##// END OF EJS Templates
Lectura y procesamiento de spectra desde HDF5
joabAM -
r1404:b1b398996ebb
parent child
Show More

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

@@ -1,1073 +1,1077
1 # Copyright (c) 2012-2020 Jicamarca Radio Observatory
1 # Copyright (c) 2012-2020 Jicamarca Radio Observatory
2 # All rights reserved.
2 # All rights reserved.
3 #
3 #
4 # Distributed under the terms of the BSD 3-clause license.
4 # Distributed under the terms of the BSD 3-clause license.
5 """Definition of diferent Data objects for different types of data
5 """Definition of diferent Data objects for different types of data
6
6
7 Here you will find the diferent data objects for the different types
7 Here you will find the diferent data objects for the different types
8 of data, this data objects must be used as dataIn or dataOut objects in
8 of data, this data objects must be used as dataIn or dataOut objects in
9 processing units and operations. Currently the supported data objects are:
9 processing units and operations. Currently the supported data objects are:
10 Voltage, Spectra, SpectraHeis, Fits, Correlation and Parameters
10 Voltage, Spectra, SpectraHeis, Fits, Correlation and Parameters
11 """
11 """
12
12
13 import copy
13 import copy
14 import numpy
14 import numpy
15 import datetime
15 import datetime
16 import json
16 import json
17
17
18 import schainpy.admin
18 import schainpy.admin
19 from schainpy.utils import log
19 from schainpy.utils import log
20 from .jroheaderIO import SystemHeader, RadarControllerHeader
20 from .jroheaderIO import SystemHeader, RadarControllerHeader
21 from schainpy.model.data import _noise
21 from schainpy.model.data import _noise
22
22
23
23
24 def getNumpyDtype(dataTypeCode):
24 def getNumpyDtype(dataTypeCode):
25
25
26 if dataTypeCode == 0:
26 if dataTypeCode == 0:
27 numpyDtype = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
27 numpyDtype = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
28 elif dataTypeCode == 1:
28 elif dataTypeCode == 1:
29 numpyDtype = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
29 numpyDtype = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
30 elif dataTypeCode == 2:
30 elif dataTypeCode == 2:
31 numpyDtype = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
31 numpyDtype = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
32 elif dataTypeCode == 3:
32 elif dataTypeCode == 3:
33 numpyDtype = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
33 numpyDtype = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
34 elif dataTypeCode == 4:
34 elif dataTypeCode == 4:
35 numpyDtype = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
35 numpyDtype = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
36 elif dataTypeCode == 5:
36 elif dataTypeCode == 5:
37 numpyDtype = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
37 numpyDtype = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
38 else:
38 else:
39 raise ValueError('dataTypeCode was not defined')
39 raise ValueError('dataTypeCode was not defined')
40
40
41 return numpyDtype
41 return numpyDtype
42
42
43
43
44 def getDataTypeCode(numpyDtype):
44 def getDataTypeCode(numpyDtype):
45
45
46 if numpyDtype == numpy.dtype([('real', '<i1'), ('imag', '<i1')]):
46 if numpyDtype == numpy.dtype([('real', '<i1'), ('imag', '<i1')]):
47 datatype = 0
47 datatype = 0
48 elif numpyDtype == numpy.dtype([('real', '<i2'), ('imag', '<i2')]):
48 elif numpyDtype == numpy.dtype([('real', '<i2'), ('imag', '<i2')]):
49 datatype = 1
49 datatype = 1
50 elif numpyDtype == numpy.dtype([('real', '<i4'), ('imag', '<i4')]):
50 elif numpyDtype == numpy.dtype([('real', '<i4'), ('imag', '<i4')]):
51 datatype = 2
51 datatype = 2
52 elif numpyDtype == numpy.dtype([('real', '<i8'), ('imag', '<i8')]):
52 elif numpyDtype == numpy.dtype([('real', '<i8'), ('imag', '<i8')]):
53 datatype = 3
53 datatype = 3
54 elif numpyDtype == numpy.dtype([('real', '<f4'), ('imag', '<f4')]):
54 elif numpyDtype == numpy.dtype([('real', '<f4'), ('imag', '<f4')]):
55 datatype = 4
55 datatype = 4
56 elif numpyDtype == numpy.dtype([('real', '<f8'), ('imag', '<f8')]):
56 elif numpyDtype == numpy.dtype([('real', '<f8'), ('imag', '<f8')]):
57 datatype = 5
57 datatype = 5
58 else:
58 else:
59 datatype = None
59 datatype = None
60
60
61 return datatype
61 return datatype
62
62
63
63
64 def hildebrand_sekhon(data, navg):
64 def hildebrand_sekhon(data, navg):
65 """
65 """
66 This method is for the objective determination of the noise level in Doppler spectra. This
66 This method is for the objective determination of the noise level in Doppler spectra. This
67 implementation technique is based on the fact that the standard deviation of the spectral
67 implementation technique is based on the fact that the standard deviation of the spectral
68 densities is equal to the mean spectral density for white Gaussian noise
68 densities is equal to the mean spectral density for white Gaussian noise
69
69
70 Inputs:
70 Inputs:
71 Data : heights
71 Data : heights
72 navg : numbers of averages
72 navg : numbers of averages
73
73
74 Return:
74 Return:
75 mean : noise's level
75 mean : noise's level
76 """
76 """
77
77
78 sortdata = numpy.sort(data, axis=None)
78 sortdata = numpy.sort(data, axis=None)
79 '''
79 '''
80 lenOfData = len(sortdata)
80 lenOfData = len(sortdata)
81 nums_min = lenOfData*0.2
81 nums_min = lenOfData*0.2
82
82
83 if nums_min <= 5:
83 if nums_min <= 5:
84
84
85 nums_min = 5
85 nums_min = 5
86
86
87 sump = 0.
87 sump = 0.
88 sumq = 0.
88 sumq = 0.
89
89
90 j = 0
90 j = 0
91 cont = 1
91 cont = 1
92
92
93 while((cont == 1)and(j < lenOfData)):
93 while((cont == 1)and(j < lenOfData)):
94
94
95 sump += sortdata[j]
95 sump += sortdata[j]
96 sumq += sortdata[j]**2
96 sumq += sortdata[j]**2
97
97
98 if j > nums_min:
98 if j > nums_min:
99 rtest = float(j)/(j-1) + 1.0/navg
99 rtest = float(j)/(j-1) + 1.0/navg
100 if ((sumq*j) > (rtest*sump**2)):
100 if ((sumq*j) > (rtest*sump**2)):
101 j = j - 1
101 j = j - 1
102 sump = sump - sortdata[j]
102 sump = sump - sortdata[j]
103 sumq = sumq - sortdata[j]**2
103 sumq = sumq - sortdata[j]**2
104 cont = 0
104 cont = 0
105
105
106 j += 1
106 j += 1
107
107
108 lnoise = sump / j
108 lnoise = sump / j
109 '''
109 '''
110 return _noise.hildebrand_sekhon(sortdata, navg)
110 return _noise.hildebrand_sekhon(sortdata, navg)
111
111
112
112
113 class Beam:
113 class Beam:
114
114
115 def __init__(self):
115 def __init__(self):
116 self.codeList = []
116 self.codeList = []
117 self.azimuthList = []
117 self.azimuthList = []
118 self.zenithList = []
118 self.zenithList = []
119
119
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 codeList = None
195 codeList = None
196 azimuthList = None
196 azimuthList = None
197 elevationList = None
197 elevationList = None
198
198
199 def __str__(self):
199 def __str__(self):
200
200
201 return '{} - {}'.format(self.type, self.datatime())
201 return '{} - {}'.format(self.type, self.datatime())
202
202
203 def getNoise(self):
203 def getNoise(self):
204
204
205 raise NotImplementedError
205 raise NotImplementedError
206
206
207 @property
207 @property
208 def nChannels(self):
208 def nChannels(self):
209
209
210 return len(self.channelList)
210 return len(self.channelList)
211
211
212 @property
212 @property
213 def channelIndexList(self):
213 def channelIndexList(self):
214
214
215 return list(range(self.nChannels))
215 return list(range(self.nChannels))
216
216
217 @property
217 @property
218 def nHeights(self):
218 def nHeights(self):
219
219
220 return len(self.heightList)
220 return len(self.heightList)
221
221
222 def getDeltaH(self):
222 def getDeltaH(self):
223
223
224 return self.heightList[1] - self.heightList[0]
224 return self.heightList[1] - self.heightList[0]
225
225
226 @property
226 @property
227 def ltctime(self):
227 def ltctime(self):
228
228
229 if self.useLocalTime:
229 if self.useLocalTime:
230 return self.utctime - self.timeZone * 60
230 return self.utctime - self.timeZone * 60
231
231
232 return self.utctime
232 return self.utctime
233
233
234 @property
234 @property
235 def datatime(self):
235 def datatime(self):
236
236
237 datatimeValue = datetime.datetime.utcfromtimestamp(self.ltctime)
237 datatimeValue = datetime.datetime.utcfromtimestamp(self.ltctime)
238 return datatimeValue
238 return datatimeValue
239
239
240 def getTimeRange(self):
240 def getTimeRange(self):
241
241
242 datatime = []
242 datatime = []
243
243
244 datatime.append(self.ltctime)
244 datatime.append(self.ltctime)
245 datatime.append(self.ltctime + self.timeInterval + 1)
245 datatime.append(self.ltctime + self.timeInterval + 1)
246
246
247 datatime = numpy.array(datatime)
247 datatime = numpy.array(datatime)
248
248
249 return datatime
249 return datatime
250
250
251 def getFmaxTimeResponse(self):
251 def getFmaxTimeResponse(self):
252
252
253 period = (10**-6) * self.getDeltaH() / (0.15)
253 period = (10**-6) * self.getDeltaH() / (0.15)
254
254
255 PRF = 1. / (period * self.nCohInt)
255 PRF = 1. / (period * self.nCohInt)
256
256
257 fmax = PRF
257 fmax = PRF
258
258
259 return fmax
259 return fmax
260
260
261 def getFmax(self):
261 def getFmax(self):
262 PRF = 1. / (self.ippSeconds * self.nCohInt)
262 PRF = 1. / (self.ippSeconds * self.nCohInt)
263
263
264 fmax = PRF
264 fmax = PRF
265 return fmax
265 return fmax
266
266
267 def getVmax(self):
267 def getVmax(self):
268
268
269 _lambda = self.C / self.frequency
269 _lambda = self.C / self.frequency
270
270
271 vmax = self.getFmax() * _lambda / 2
271 vmax = self.getFmax() * _lambda / 2
272
272
273 return vmax
273 return vmax
274
274
275 @property
275 @property
276 def ippSeconds(self):
276 def ippSeconds(self):
277 '''
277 '''
278 '''
278 '''
279 return self.radarControllerHeaderObj.ippSeconds
279 return self.radarControllerHeaderObj.ippSeconds
280
280
281 @ippSeconds.setter
281 @ippSeconds.setter
282 def ippSeconds(self, ippSeconds):
282 def ippSeconds(self, ippSeconds):
283 '''
283 '''
284 '''
284 '''
285 self.radarControllerHeaderObj.ippSeconds = ippSeconds
285 self.radarControllerHeaderObj.ippSeconds = ippSeconds
286
286
287 @property
287 @property
288 def code(self):
288 def code(self):
289 '''
289 '''
290 '''
290 '''
291 return self.radarControllerHeaderObj.code
291 return self.radarControllerHeaderObj.code
292
292
293 @code.setter
293 @code.setter
294 def code(self, code):
294 def code(self, code):
295 '''
295 '''
296 '''
296 '''
297 self.radarControllerHeaderObj.code = code
297 self.radarControllerHeaderObj.code = code
298
298
299 @property
299 @property
300 def nCode(self):
300 def nCode(self):
301 '''
301 '''
302 '''
302 '''
303 return self.radarControllerHeaderObj.nCode
303 return self.radarControllerHeaderObj.nCode
304
304
305 @nCode.setter
305 @nCode.setter
306 def nCode(self, ncode):
306 def nCode(self, ncode):
307 '''
307 '''
308 '''
308 '''
309 self.radarControllerHeaderObj.nCode = ncode
309 self.radarControllerHeaderObj.nCode = ncode
310
310
311 @property
311 @property
312 def nBaud(self):
312 def nBaud(self):
313 '''
313 '''
314 '''
314 '''
315 return self.radarControllerHeaderObj.nBaud
315 return self.radarControllerHeaderObj.nBaud
316
316
317 @nBaud.setter
317 @nBaud.setter
318 def nBaud(self, nbaud):
318 def nBaud(self, nbaud):
319 '''
319 '''
320 '''
320 '''
321 self.radarControllerHeaderObj.nBaud = nbaud
321 self.radarControllerHeaderObj.nBaud = nbaud
322
322
323 @property
323 @property
324 def ipp(self):
324 def ipp(self):
325 '''
325 '''
326 '''
326 '''
327 return self.radarControllerHeaderObj.ipp
327 return self.radarControllerHeaderObj.ipp
328
328
329 @ipp.setter
329 @ipp.setter
330 def ipp(self, ipp):
330 def ipp(self, ipp):
331 '''
331 '''
332 '''
332 '''
333 self.radarControllerHeaderObj.ipp = ipp
333 self.radarControllerHeaderObj.ipp = ipp
334
334
335 @property
335 @property
336 def metadata(self):
336 def metadata(self):
337 '''
337 '''
338 '''
338 '''
339
339
340 return {attr: getattr(self, attr) for attr in self.metadata_list}
340 return {attr: getattr(self, attr) for attr in self.metadata_list}
341
341
342
342
343 class Voltage(JROData):
343 class Voltage(JROData):
344
344
345 dataPP_POW = None
345 dataPP_POW = None
346 dataPP_DOP = None
346 dataPP_DOP = None
347 dataPP_WIDTH = None
347 dataPP_WIDTH = None
348 dataPP_SNR = None
348 dataPP_SNR = None
349
349
350 def __init__(self):
350 def __init__(self):
351 '''
351 '''
352 Constructor
352 Constructor
353 '''
353 '''
354
354
355 self.useLocalTime = True
355 self.useLocalTime = True
356 self.radarControllerHeaderObj = RadarControllerHeader()
356 self.radarControllerHeaderObj = RadarControllerHeader()
357 self.systemHeaderObj = SystemHeader()
357 self.systemHeaderObj = SystemHeader()
358 self.type = "Voltage"
358 self.type = "Voltage"
359 self.data = None
359 self.data = None
360 self.nProfiles = None
360 self.nProfiles = None
361 self.heightList = None
361 self.heightList = None
362 self.channelList = None
362 self.channelList = None
363 self.flagNoData = True
363 self.flagNoData = True
364 self.flagDiscontinuousBlock = False
364 self.flagDiscontinuousBlock = False
365 self.utctime = None
365 self.utctime = None
366 self.timeZone = 0
366 self.timeZone = 0
367 self.dstFlag = None
367 self.dstFlag = None
368 self.errorCount = None
368 self.errorCount = None
369 self.nCohInt = None
369 self.nCohInt = None
370 self.blocksize = None
370 self.blocksize = None
371 self.flagCohInt = False
371 self.flagCohInt = False
372 self.flagDecodeData = False # asumo q la data no esta decodificada
372 self.flagDecodeData = False # asumo q la data no esta decodificada
373 self.flagDeflipData = False # asumo q la data no esta sin flip
373 self.flagDeflipData = False # asumo q la data no esta sin flip
374 self.flagShiftFFT = False
374 self.flagShiftFFT = False
375 self.flagDataAsBlock = False # Asumo que la data es leida perfil a perfil
375 self.flagDataAsBlock = False # Asumo que la data es leida perfil a perfil
376 self.profileIndex = 0
376 self.profileIndex = 0
377 self.metadata_list = ['type', 'heightList', 'timeZone', 'nProfiles', 'channelList', 'nCohInt',
377 self.metadata_list = ['type', 'heightList', 'timeZone', 'nProfiles', 'channelList', 'nCohInt',
378 'code', 'nCode', 'nBaud', 'ippSeconds', 'ipp']
378 'code', 'nCode', 'nBaud', 'ippSeconds', 'ipp']
379
379
380 def getNoisebyHildebrand(self, channel=None):
380 def getNoisebyHildebrand(self, channel=None):
381 """
381 """
382 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
382 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
383
383
384 Return:
384 Return:
385 noiselevel
385 noiselevel
386 """
386 """
387
387
388 if channel != None:
388 if channel != None:
389 data = self.data[channel]
389 data = self.data[channel]
390 nChannels = 1
390 nChannels = 1
391 else:
391 else:
392 data = self.data
392 data = self.data
393 nChannels = self.nChannels
393 nChannels = self.nChannels
394
394
395 noise = numpy.zeros(nChannels)
395 noise = numpy.zeros(nChannels)
396 power = data * numpy.conjugate(data)
396 power = data * numpy.conjugate(data)
397
397
398 for thisChannel in range(nChannels):
398 for thisChannel in range(nChannels):
399 if nChannels == 1:
399 if nChannels == 1:
400 daux = power[:].real
400 daux = power[:].real
401 else:
401 else:
402 daux = power[thisChannel, :].real
402 daux = power[thisChannel, :].real
403 noise[thisChannel] = hildebrand_sekhon(daux, self.nCohInt)
403 noise[thisChannel] = hildebrand_sekhon(daux, self.nCohInt)
404
404
405 return noise
405 return noise
406
406
407 def getNoise(self, type=1, channel=None):
407 def getNoise(self, type=1, channel=None):
408
408
409 if type == 1:
409 if type == 1:
410 noise = self.getNoisebyHildebrand(channel)
410 noise = self.getNoisebyHildebrand(channel)
411
411
412 return noise
412 return noise
413
413
414 def getPower(self, channel=None):
414 def getPower(self, channel=None):
415
415
416 if channel != None:
416 if channel != None:
417 data = self.data[channel]
417 data = self.data[channel]
418 else:
418 else:
419 data = self.data
419 data = self.data
420
420
421 power = data * numpy.conjugate(data)
421 power = data * numpy.conjugate(data)
422 powerdB = 10 * numpy.log10(power.real)
422 powerdB = 10 * numpy.log10(power.real)
423 powerdB = numpy.squeeze(powerdB)
423 powerdB = numpy.squeeze(powerdB)
424
424
425 return powerdB
425 return powerdB
426
426
427 @property
427 @property
428 def timeInterval(self):
428 def timeInterval(self):
429
429
430 return self.ippSeconds * self.nCohInt
430 return self.ippSeconds * self.nCohInt
431
431
432 noise = property(getNoise, "I'm the 'nHeights' property.")
432 noise = property(getNoise, "I'm the 'nHeights' property.")
433
433
434
434
435 class Spectra(JROData):
435 class Spectra(JROData):
436
436
437 def __init__(self):
437 def __init__(self):
438 '''
438 '''
439 Constructor
439 Constructor
440 '''
440 '''
441
441
442 self.data_dc = None
442 self.data_dc = None
443 self.data_spc = None
443 self.data_spc = None
444 self.data_cspc = None
444 self.data_cspc = None
445 self.useLocalTime = True
445 self.useLocalTime = True
446 self.radarControllerHeaderObj = RadarControllerHeader()
446 self.radarControllerHeaderObj = RadarControllerHeader()
447 self.systemHeaderObj = SystemHeader()
447 self.systemHeaderObj = SystemHeader()
448 self.type = "Spectra"
448 self.type = "Spectra"
449 self.timeZone = 0
449 self.timeZone = 0
450 self.nProfiles = None
450 self.nProfiles = None
451 self.heightList = None
451 self.heightList = None
452 self.channelList = None
452 self.channelList = None
453 self.pairsList = None
453 self.pairsList = None
454 self.flagNoData = True
454 self.flagNoData = True
455 self.flagDiscontinuousBlock = False
455 self.flagDiscontinuousBlock = False
456 self.utctime = None
456 self.utctime = None
457 self.nCohInt = None
457 self.nCohInt = None
458 self.nIncohInt = None
458 self.nIncohInt = None
459 self.blocksize = None
459 self.blocksize = None
460 self.nFFTPoints = None
460 self.nFFTPoints = None
461 self.wavelength = None
461 self.wavelength = None
462 self.flagDecodeData = False # asumo q la data no esta decodificada
462 self.flagDecodeData = False # asumo q la data no esta decodificada
463 self.flagDeflipData = False # asumo q la data no esta sin flip
463 self.flagDeflipData = False # asumo q la data no esta sin flip
464 self.flagShiftFFT = False
464 self.flagShiftFFT = False
465 self.ippFactor = 1
465 self.ippFactor = 1
466 self.beacon_heiIndexList = []
466 self.beacon_heiIndexList = []
467 self.noise_estimation = None
467 self.noise_estimation = None
468 self.codeList = []
469 self.azimuthList = []
470 self.elevationList = []
468 self.metadata_list = ['type', 'heightList', 'timeZone', 'pairsList', 'channelList', 'nCohInt',
471 self.metadata_list = ['type', 'heightList', 'timeZone', 'pairsList', 'channelList', 'nCohInt',
469 'code', 'nCode', 'nBaud', 'ippSeconds', 'ipp','nIncohInt', 'nFFTPoints', 'nProfiles']
472 'code', 'nCode', 'nBaud', 'ippSeconds', 'ipp','nIncohInt', 'nFFTPoints', 'nProfiles']
470
473
471
474
472 def getNoisebyHildebrand(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
475 def getNoisebyHildebrand(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
473 """
476 """
474 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
477 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
475
478
476 Return:
479 Return:
477 noiselevel
480 noiselevel
478 """
481 """
479
482
480 noise = numpy.zeros(self.nChannels)
483 noise = numpy.zeros(self.nChannels)
481 for channel in range(self.nChannels):
484 for channel in range(self.nChannels):
482 daux = self.data_spc[channel,
485 daux = self.data_spc[channel,
483 xmin_index:xmax_index, ymin_index:ymax_index]
486 xmin_index:xmax_index, ymin_index:ymax_index]
484 noise[channel] = hildebrand_sekhon(daux, self.nIncohInt)
487 noise[channel] = hildebrand_sekhon(daux, self.nIncohInt)
485
488
486 return noise
489 return noise
487
490
488 def getNoise(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
491 def getNoise(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
489
492
490 if self.noise_estimation is not None:
493 if self.noise_estimation is not None:
491 # this was estimated by getNoise Operation defined in jroproc_spectra.py
494 # this was estimated by getNoise Operation defined in jroproc_spectra.py
492 return self.noise_estimation
495 return self.noise_estimation
493 else:
496 else:
494 noise = self.getNoisebyHildebrand(
497 noise = self.getNoisebyHildebrand(
495 xmin_index, xmax_index, ymin_index, ymax_index)
498 xmin_index, xmax_index, ymin_index, ymax_index)
496 return noise
499 return noise
497
500
498 def getFreqRangeTimeResponse(self, extrapoints=0):
501 def getFreqRangeTimeResponse(self, extrapoints=0):
499
502
500 deltafreq = self.getFmaxTimeResponse() / (self.nFFTPoints * self.ippFactor)
503 deltafreq = self.getFmaxTimeResponse() / (self.nFFTPoints * self.ippFactor)
501 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.) - deltafreq / 2
504 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.) - deltafreq / 2
502
505
503 return freqrange
506 return freqrange
504
507
505 def getAcfRange(self, extrapoints=0):
508 def getAcfRange(self, extrapoints=0):
506
509
507 deltafreq = 10. / (self.getFmax() / (self.nFFTPoints * self.ippFactor))
510 deltafreq = 10. / (self.getFmax() / (self.nFFTPoints * self.ippFactor))
508 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
511 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
509
512
510 return freqrange
513 return freqrange
511
514
512 def getFreqRange(self, extrapoints=0):
515 def getFreqRange(self, extrapoints=0):
513
516
514 deltafreq = self.getFmax() / (self.nFFTPoints * self.ippFactor)
517 deltafreq = self.getFmax() / (self.nFFTPoints * self.ippFactor)
515 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
518 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
516
519
517 return freqrange
520 return freqrange
518
521
519 def getVelRange(self, extrapoints=0):
522 def getVelRange(self, extrapoints=0):
520
523
521 deltav = self.getVmax() / (self.nFFTPoints * self.ippFactor)
524 deltav = self.getVmax() / (self.nFFTPoints * self.ippFactor)
522 velrange = deltav * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.)
525 velrange = deltav * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.)
523
526
524 if self.nmodes:
527 if self.nmodes:
525 return velrange/self.nmodes
528 return velrange/self.nmodes
526 else:
529 else:
527 return velrange
530 return velrange
528
531
529 @property
532 @property
530 def nPairs(self):
533 def nPairs(self):
531
534
532 return len(self.pairsList)
535 return len(self.pairsList)
533
536
534 @property
537 @property
535 def pairsIndexList(self):
538 def pairsIndexList(self):
536
539
537 return list(range(self.nPairs))
540 return list(range(self.nPairs))
538
541
539 @property
542 @property
540 def normFactor(self):
543 def normFactor(self):
541
544
542 pwcode = 1
545 pwcode = 1
543
546
544 if self.flagDecodeData:
547 if self.flagDecodeData:
545 pwcode = numpy.sum(self.code[0]**2)
548 pwcode = numpy.sum(self.code[0]**2)
546 #normFactor = min(self.nFFTPoints,self.nProfiles)*self.nIncohInt*self.nCohInt*pwcode*self.windowOfFilter
549 #normFactor = min(self.nFFTPoints,self.nProfiles)*self.nIncohInt*self.nCohInt*pwcode*self.windowOfFilter
547 normFactor = self.nProfiles * self.nIncohInt * self.nCohInt * pwcode * self.windowOfFilter
550 normFactor = self.nProfiles * self.nIncohInt * self.nCohInt * pwcode * self.windowOfFilter
548
551
549 return normFactor
552 return normFactor
550
553
551 @property
554 @property
552 def flag_cspc(self):
555 def flag_cspc(self):
553
556
554 if self.data_cspc is None:
557 if self.data_cspc is None:
555 return True
558 return True
556
559
557 return False
560 return False
558
561
559 @property
562 @property
560 def flag_dc(self):
563 def flag_dc(self):
561
564
562 if self.data_dc is None:
565 if self.data_dc is None:
563 return True
566 return True
564
567
565 return False
568 return False
566
569
567 @property
570 @property
568 def timeInterval(self):
571 def timeInterval(self):
569
572
570 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt * self.nProfiles * self.ippFactor
573 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt * self.nProfiles * self.ippFactor
571 if self.nmodes:
574 if self.nmodes:
572 return self.nmodes*timeInterval
575 return self.nmodes*timeInterval
573 else:
576 else:
574 return timeInterval
577 return timeInterval
575
578
576 def getPower(self):
579 def getPower(self):
577
580
578 factor = self.normFactor
581 factor = self.normFactor
579 z = self.data_spc / factor
582 z = self.data_spc / factor
580 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
583 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
581 avg = numpy.average(z, axis=1)
584 avg = numpy.average(z, axis=1)
582
585
583 return 10 * numpy.log10(avg)
586 return 10 * numpy.log10(avg)
584
587
585 def getCoherence(self, pairsList=None, phase=False):
588 def getCoherence(self, pairsList=None, phase=False):
586
589
587 z = []
590 z = []
588 if pairsList is None:
591 if pairsList is None:
589 pairsIndexList = self.pairsIndexList
592 pairsIndexList = self.pairsIndexList
590 else:
593 else:
591 pairsIndexList = []
594 pairsIndexList = []
592 for pair in pairsList:
595 for pair in pairsList:
593 if pair not in self.pairsList:
596 if pair not in self.pairsList:
594 raise ValueError("Pair %s is not in dataOut.pairsList" % (
597 raise ValueError("Pair %s is not in dataOut.pairsList" % (
595 pair))
598 pair))
596 pairsIndexList.append(self.pairsList.index(pair))
599 pairsIndexList.append(self.pairsList.index(pair))
597 for i in range(len(pairsIndexList)):
600 for i in range(len(pairsIndexList)):
598 pair = self.pairsList[pairsIndexList[i]]
601 pair = self.pairsList[pairsIndexList[i]]
599 ccf = numpy.average(self.data_cspc[pairsIndexList[i], :, :], axis=0)
602 ccf = numpy.average(self.data_cspc[pairsIndexList[i], :, :], axis=0)
600 powa = numpy.average(self.data_spc[pair[0], :, :], axis=0)
603 powa = numpy.average(self.data_spc[pair[0], :, :], axis=0)
601 powb = numpy.average(self.data_spc[pair[1], :, :], axis=0)
604 powb = numpy.average(self.data_spc[pair[1], :, :], axis=0)
602 avgcoherenceComplex = ccf / numpy.sqrt(powa * powb)
605 avgcoherenceComplex = ccf / numpy.sqrt(powa * powb)
603 if phase:
606 if phase:
604 data = numpy.arctan2(avgcoherenceComplex.imag,
607 data = numpy.arctan2(avgcoherenceComplex.imag,
605 avgcoherenceComplex.real) * 180 / numpy.pi
608 avgcoherenceComplex.real) * 180 / numpy.pi
606 else:
609 else:
607 data = numpy.abs(avgcoherenceComplex)
610 data = numpy.abs(avgcoherenceComplex)
608
611
609 z.append(data)
612 z.append(data)
610
613
611 return numpy.array(z)
614 return numpy.array(z)
612
615
613 def setValue(self, value):
616 def setValue(self, value):
614
617
615 print("This property should not be initialized")
618 print("This property should not be initialized")
616
619
617 return
620 return
618
621
619 noise = property(getNoise, setValue, "I'm the 'nHeights' property.")
622 noise = property(getNoise, setValue, "I'm the 'nHeights' property.")
620
623
621
624
622 class SpectraHeis(Spectra):
625 class SpectraHeis(Spectra):
623
626
624 def __init__(self):
627 def __init__(self):
625
628
626 self.radarControllerHeaderObj = RadarControllerHeader()
629 self.radarControllerHeaderObj = RadarControllerHeader()
627 self.systemHeaderObj = SystemHeader()
630 self.systemHeaderObj = SystemHeader()
628 self.type = "SpectraHeis"
631 self.type = "SpectraHeis"
629 self.nProfiles = None
632 self.nProfiles = None
630 self.heightList = None
633 self.heightList = None
631 self.channelList = None
634 self.channelList = None
632 self.flagNoData = True
635 self.flagNoData = True
633 self.flagDiscontinuousBlock = False
636 self.flagDiscontinuousBlock = False
634 self.utctime = None
637 self.utctime = None
635 self.blocksize = None
638 self.blocksize = None
636 self.profileIndex = 0
639 self.profileIndex = 0
637 self.nCohInt = 1
640 self.nCohInt = 1
638 self.nIncohInt = 1
641 self.nIncohInt = 1
639
642
640 @property
643 @property
641 def normFactor(self):
644 def normFactor(self):
642 pwcode = 1
645 pwcode = 1
643 if self.flagDecodeData:
646 if self.flagDecodeData:
644 pwcode = numpy.sum(self.code[0]**2)
647 pwcode = numpy.sum(self.code[0]**2)
645
648
646 normFactor = self.nIncohInt * self.nCohInt * pwcode
649 normFactor = self.nIncohInt * self.nCohInt * pwcode
647
650
648 return normFactor
651 return normFactor
649
652
650 @property
653 @property
651 def timeInterval(self):
654 def timeInterval(self):
652
655
653 return self.ippSeconds * self.nCohInt * self.nIncohInt
656 return self.ippSeconds * self.nCohInt * self.nIncohInt
654
657
655
658
656 class Fits(JROData):
659 class Fits(JROData):
657
660
658 def __init__(self):
661 def __init__(self):
659
662
660 self.type = "Fits"
663 self.type = "Fits"
661 self.nProfiles = None
664 self.nProfiles = None
662 self.heightList = None
665 self.heightList = None
663 self.channelList = None
666 self.channelList = None
664 self.flagNoData = True
667 self.flagNoData = True
665 self.utctime = None
668 self.utctime = None
666 self.nCohInt = 1
669 self.nCohInt = 1
667 self.nIncohInt = 1
670 self.nIncohInt = 1
668 self.useLocalTime = True
671 self.useLocalTime = True
669 self.profileIndex = 0
672 self.profileIndex = 0
670 self.timeZone = 0
673 self.timeZone = 0
671
674
672 def getTimeRange(self):
675 def getTimeRange(self):
673
676
674 datatime = []
677 datatime = []
675
678
676 datatime.append(self.ltctime)
679 datatime.append(self.ltctime)
677 datatime.append(self.ltctime + self.timeInterval)
680 datatime.append(self.ltctime + self.timeInterval)
678
681
679 datatime = numpy.array(datatime)
682 datatime = numpy.array(datatime)
680
683
681 return datatime
684 return datatime
682
685
683 def getChannelIndexList(self):
686 def getChannelIndexList(self):
684
687
685 return list(range(self.nChannels))
688 return list(range(self.nChannels))
686
689
687 def getNoise(self, type=1):
690 def getNoise(self, type=1):
688
691
689
692
690 if type == 1:
693 if type == 1:
691 noise = self.getNoisebyHildebrand()
694 noise = self.getNoisebyHildebrand()
692
695
693 if type == 2:
696 if type == 2:
694 noise = self.getNoisebySort()
697 noise = self.getNoisebySort()
695
698
696 if type == 3:
699 if type == 3:
697 noise = self.getNoisebyWindow()
700 noise = self.getNoisebyWindow()
698
701
699 return noise
702 return noise
700
703
701 @property
704 @property
702 def timeInterval(self):
705 def timeInterval(self):
703
706
704 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
707 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
705
708
706 return timeInterval
709 return timeInterval
707
710
708 @property
711 @property
709 def ippSeconds(self):
712 def ippSeconds(self):
710 '''
713 '''
711 '''
714 '''
712 return self.ipp_sec
715 return self.ipp_sec
713
716
714 noise = property(getNoise, "I'm the 'nHeights' property.")
717 noise = property(getNoise, "I'm the 'nHeights' property.")
715
718
716
719
717 class Correlation(JROData):
720 class Correlation(JROData):
718
721
719 def __init__(self):
722 def __init__(self):
720 '''
723 '''
721 Constructor
724 Constructor
722 '''
725 '''
723 self.radarControllerHeaderObj = RadarControllerHeader()
726 self.radarControllerHeaderObj = RadarControllerHeader()
724 self.systemHeaderObj = SystemHeader()
727 self.systemHeaderObj = SystemHeader()
725 self.type = "Correlation"
728 self.type = "Correlation"
726 self.data = None
729 self.data = None
727 self.dtype = None
730 self.dtype = None
728 self.nProfiles = None
731 self.nProfiles = None
729 self.heightList = None
732 self.heightList = None
730 self.channelList = None
733 self.channelList = None
731 self.flagNoData = True
734 self.flagNoData = True
732 self.flagDiscontinuousBlock = False
735 self.flagDiscontinuousBlock = False
733 self.utctime = None
736 self.utctime = None
734 self.timeZone = 0
737 self.timeZone = 0
735 self.dstFlag = None
738 self.dstFlag = None
736 self.errorCount = None
739 self.errorCount = None
737 self.blocksize = None
740 self.blocksize = None
738 self.flagDecodeData = False # asumo q la data no esta decodificada
741 self.flagDecodeData = False # asumo q la data no esta decodificada
739 self.flagDeflipData = False # asumo q la data no esta sin flip
742 self.flagDeflipData = False # asumo q la data no esta sin flip
740 self.pairsList = None
743 self.pairsList = None
741 self.nPoints = None
744 self.nPoints = None
742
745
743 def getPairsList(self):
746 def getPairsList(self):
744
747
745 return self.pairsList
748 return self.pairsList
746
749
747 def getNoise(self, mode=2):
750 def getNoise(self, mode=2):
748
751
749 indR = numpy.where(self.lagR == 0)[0][0]
752 indR = numpy.where(self.lagR == 0)[0][0]
750 indT = numpy.where(self.lagT == 0)[0][0]
753 indT = numpy.where(self.lagT == 0)[0][0]
751
754
752 jspectra0 = self.data_corr[:, :, indR, :]
755 jspectra0 = self.data_corr[:, :, indR, :]
753 jspectra = copy.copy(jspectra0)
756 jspectra = copy.copy(jspectra0)
754
757
755 num_chan = jspectra.shape[0]
758 num_chan = jspectra.shape[0]
756 num_hei = jspectra.shape[2]
759 num_hei = jspectra.shape[2]
757
760
758 freq_dc = jspectra.shape[1] / 2
761 freq_dc = jspectra.shape[1] / 2
759 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
762 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
760
763
761 if ind_vel[0] < 0:
764 if ind_vel[0] < 0:
762 ind_vel[list(range(0, 1))] = ind_vel[list(
765 ind_vel[list(range(0, 1))] = ind_vel[list(
763 range(0, 1))] + self.num_prof
766 range(0, 1))] + self.num_prof
764
767
765 if mode == 1:
768 if mode == 1:
766 jspectra[:, freq_dc, :] = (
769 jspectra[:, freq_dc, :] = (
767 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
770 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
768
771
769 if mode == 2:
772 if mode == 2:
770
773
771 vel = numpy.array([-2, -1, 1, 2])
774 vel = numpy.array([-2, -1, 1, 2])
772 xx = numpy.zeros([4, 4])
775 xx = numpy.zeros([4, 4])
773
776
774 for fil in range(4):
777 for fil in range(4):
775 xx[fil, :] = vel[fil]**numpy.asarray(list(range(4)))
778 xx[fil, :] = vel[fil]**numpy.asarray(list(range(4)))
776
779
777 xx_inv = numpy.linalg.inv(xx)
780 xx_inv = numpy.linalg.inv(xx)
778 xx_aux = xx_inv[0, :]
781 xx_aux = xx_inv[0, :]
779
782
780 for ich in range(num_chan):
783 for ich in range(num_chan):
781 yy = jspectra[ich, ind_vel, :]
784 yy = jspectra[ich, ind_vel, :]
782 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
785 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
783
786
784 junkid = jspectra[ich, freq_dc, :] <= 0
787 junkid = jspectra[ich, freq_dc, :] <= 0
785 cjunkid = sum(junkid)
788 cjunkid = sum(junkid)
786
789
787 if cjunkid.any():
790 if cjunkid.any():
788 jspectra[ich, freq_dc, junkid.nonzero()] = (
791 jspectra[ich, freq_dc, junkid.nonzero()] = (
789 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
792 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
790
793
791 noise = jspectra0[:, freq_dc, :] - jspectra[:, freq_dc, :]
794 noise = jspectra0[:, freq_dc, :] - jspectra[:, freq_dc, :]
792
795
793 return noise
796 return noise
794
797
795 @property
798 @property
796 def timeInterval(self):
799 def timeInterval(self):
797
800
798 return self.ippSeconds * self.nCohInt * self.nProfiles
801 return self.ippSeconds * self.nCohInt * self.nProfiles
799
802
800 def splitFunctions(self):
803 def splitFunctions(self):
801
804
802 pairsList = self.pairsList
805 pairsList = self.pairsList
803 ccf_pairs = []
806 ccf_pairs = []
804 acf_pairs = []
807 acf_pairs = []
805 ccf_ind = []
808 ccf_ind = []
806 acf_ind = []
809 acf_ind = []
807 for l in range(len(pairsList)):
810 for l in range(len(pairsList)):
808 chan0 = pairsList[l][0]
811 chan0 = pairsList[l][0]
809 chan1 = pairsList[l][1]
812 chan1 = pairsList[l][1]
810
813
811 # Obteniendo pares de Autocorrelacion
814 # Obteniendo pares de Autocorrelacion
812 if chan0 == chan1:
815 if chan0 == chan1:
813 acf_pairs.append(chan0)
816 acf_pairs.append(chan0)
814 acf_ind.append(l)
817 acf_ind.append(l)
815 else:
818 else:
816 ccf_pairs.append(pairsList[l])
819 ccf_pairs.append(pairsList[l])
817 ccf_ind.append(l)
820 ccf_ind.append(l)
818
821
819 data_acf = self.data_cf[acf_ind]
822 data_acf = self.data_cf[acf_ind]
820 data_ccf = self.data_cf[ccf_ind]
823 data_ccf = self.data_cf[ccf_ind]
821
824
822 return acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf
825 return acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf
823
826
824 @property
827 @property
825 def normFactor(self):
828 def normFactor(self):
826 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.splitFunctions()
829 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.splitFunctions()
827 acf_pairs = numpy.array(acf_pairs)
830 acf_pairs = numpy.array(acf_pairs)
828 normFactor = numpy.zeros((self.nPairs, self.nHeights))
831 normFactor = numpy.zeros((self.nPairs, self.nHeights))
829
832
830 for p in range(self.nPairs):
833 for p in range(self.nPairs):
831 pair = self.pairsList[p]
834 pair = self.pairsList[p]
832
835
833 ch0 = pair[0]
836 ch0 = pair[0]
834 ch1 = pair[1]
837 ch1 = pair[1]
835
838
836 ch0_max = numpy.max(data_acf[acf_pairs == ch0, :, :], axis=1)
839 ch0_max = numpy.max(data_acf[acf_pairs == ch0, :, :], axis=1)
837 ch1_max = numpy.max(data_acf[acf_pairs == ch1, :, :], axis=1)
840 ch1_max = numpy.max(data_acf[acf_pairs == ch1, :, :], axis=1)
838 normFactor[p, :] = numpy.sqrt(ch0_max * ch1_max)
841 normFactor[p, :] = numpy.sqrt(ch0_max * ch1_max)
839
842
840 return normFactor
843 return normFactor
841
844
842
845
843 class Parameters(Spectra):
846 class Parameters(Spectra):
844
847
845 groupList = None # List of Pairs, Groups, etc
848 groupList = None # List of Pairs, Groups, etc
846 data_param = None # Parameters obtained
849 data_param = None # Parameters obtained
847 data_pre = None # Data Pre Parametrization
850 data_pre = None # Data Pre Parametrization
848 data_SNR = None # Signal to Noise Ratio
851 data_SNR = None # Signal to Noise Ratio
849 abscissaList = None # Abscissa, can be velocities, lags or time
852 abscissaList = None # Abscissa, can be velocities, lags or time
850 utctimeInit = None # Initial UTC time
853 utctimeInit = None # Initial UTC time
851 paramInterval = None # Time interval to calculate Parameters in seconds
854 paramInterval = None # Time interval to calculate Parameters in seconds
852 useLocalTime = True
855 useLocalTime = True
853 # Fitting
856 # Fitting
854 data_error = None # Error of the estimation
857 data_error = None # Error of the estimation
855 constants = None
858 constants = None
856 library = None
859 library = None
857 # Output signal
860 # Output signal
858 outputInterval = None # Time interval to calculate output signal in seconds
861 outputInterval = None # Time interval to calculate output signal in seconds
859 data_output = None # Out signal
862 data_output = None # Out signal
860 nAvg = None
863 nAvg = None
861 noise_estimation = None
864 noise_estimation = None
862 GauSPC = None # Fit gaussian SPC
865 GauSPC = None # Fit gaussian SPC
863
866
864 def __init__(self):
867 def __init__(self):
865 '''
868 '''
866 Constructor
869 Constructor
867 '''
870 '''
868 self.radarControllerHeaderObj = RadarControllerHeader()
871 self.radarControllerHeaderObj = RadarControllerHeader()
872 self.radarControllerHeaderObj.set_ippSeconds(0)
869 self.systemHeaderObj = SystemHeader()
873 self.systemHeaderObj = SystemHeader()
870 self.type = "Parameters"
874 self.type = "Parameters"
871 self.timeZone = 0
875 self.timeZone = 0
872
876
873 def getTimeRange1(self, interval):
877 def getTimeRange1(self, interval):
874
878
875 datatime = []
879 datatime = []
876
880
877 if self.useLocalTime:
881 if self.useLocalTime:
878 time1 = self.utctimeInit - self.timeZone * 60
882 time1 = self.utctimeInit - self.timeZone * 60
879 else:
883 else:
880 time1 = self.utctimeInit
884 time1 = self.utctimeInit
881
885
882 datatime.append(time1)
886 datatime.append(time1)
883 datatime.append(time1 + interval)
887 datatime.append(time1 + interval)
884 datatime = numpy.array(datatime)
888 datatime = numpy.array(datatime)
885
889
886 return datatime
890 return datatime
887
891
888 @property
892 @property
889 def timeInterval(self):
893 def timeInterval(self):
890
894
891 if hasattr(self, 'timeInterval1'):
895 if hasattr(self, 'timeInterval1'):
892 return self.timeInterval1
896 return self.timeInterval1
893 else:
897 else:
894 return self.paramInterval
898 return self.paramInterval
895
899
896 def setValue(self, value):
900 def setValue(self, value):
897
901
898 print("This property should not be initialized")
902 print("This property should not be initialized")
899
903
900 return
904 return
901
905
902 def getNoise(self):
906 def getNoise(self):
903
907
904 return self.spc_noise
908 return self.spc_noise
905
909
906 noise = property(getNoise, setValue, "I'm the 'Noise' property.")
910 noise = property(getNoise, setValue, "I'm the 'Noise' property.")
907
911
908
912
909 class PlotterData(object):
913 class PlotterData(object):
910 '''
914 '''
911 Object to hold data to be plotted
915 Object to hold data to be plotted
912 '''
916 '''
913
917
914 MAXNUMX = 200
918 MAXNUMX = 200
915 MAXNUMY = 200
919 MAXNUMY = 200
916
920
917 def __init__(self, code, exp_code, localtime=True):
921 def __init__(self, code, exp_code, localtime=True):
918
922
919 self.key = code
923 self.key = code
920 self.exp_code = exp_code
924 self.exp_code = exp_code
921 self.ready = False
925 self.ready = False
922 self.flagNoData = False
926 self.flagNoData = False
923 self.localtime = localtime
927 self.localtime = localtime
924 self.data = {}
928 self.data = {}
925 self.meta = {}
929 self.meta = {}
926 self.__heights = []
930 self.__heights = []
927
931
928 def __str__(self):
932 def __str__(self):
929 dum = ['{}{}'.format(key, self.shape(key)) for key in self.data]
933 dum = ['{}{}'.format(key, self.shape(key)) for key in self.data]
930 return 'Data[{}][{}]'.format(';'.join(dum), len(self.times))
934 return 'Data[{}][{}]'.format(';'.join(dum), len(self.times))
931
935
932 def __len__(self):
936 def __len__(self):
933 return len(self.data)
937 return len(self.data)
934
938
935 def __getitem__(self, key):
939 def __getitem__(self, key):
936 if isinstance(key, int):
940 if isinstance(key, int):
937 return self.data[self.times[key]]
941 return self.data[self.times[key]]
938 elif isinstance(key, str):
942 elif isinstance(key, str):
939 ret = numpy.array([self.data[x][key] for x in self.times])
943 ret = numpy.array([self.data[x][key] for x in self.times])
940 if ret.ndim > 1:
944 if ret.ndim > 1:
941 ret = numpy.swapaxes(ret, 0, 1)
945 ret = numpy.swapaxes(ret, 0, 1)
942 return ret
946 return ret
943
947
944 def __contains__(self, key):
948 def __contains__(self, key):
945 return key in self.data[self.min_time]
949 return key in self.data[self.min_time]
946
950
947 def setup(self):
951 def setup(self):
948 '''
952 '''
949 Configure object
953 Configure object
950 '''
954 '''
951 self.type = ''
955 self.type = ''
952 self.ready = False
956 self.ready = False
953 del self.data
957 del self.data
954 self.data = {}
958 self.data = {}
955 self.__heights = []
959 self.__heights = []
956 self.__all_heights = set()
960 self.__all_heights = set()
957
961
958 def shape(self, key):
962 def shape(self, key):
959 '''
963 '''
960 Get the shape of the one-element data for the given key
964 Get the shape of the one-element data for the given key
961 '''
965 '''
962
966
963 if len(self.data[self.min_time][key]):
967 if len(self.data[self.min_time][key]):
964 return self.data[self.min_time][key].shape
968 return self.data[self.min_time][key].shape
965 return (0,)
969 return (0,)
966
970
967 def update(self, data, tm, meta={}):
971 def update(self, data, tm, meta={}):
968 '''
972 '''
969 Update data object with new dataOut
973 Update data object with new dataOut
970 '''
974 '''
971
975
972 self.data[tm] = data
976 self.data[tm] = data
973
977
974 for key, value in meta.items():
978 for key, value in meta.items():
975 setattr(self, key, value)
979 setattr(self, key, value)
976
980
977 def normalize_heights(self):
981 def normalize_heights(self):
978 '''
982 '''
979 Ensure same-dimension of the data for different heighList
983 Ensure same-dimension of the data for different heighList
980 '''
984 '''
981
985
982 H = numpy.array(list(self.__all_heights))
986 H = numpy.array(list(self.__all_heights))
983 H.sort()
987 H.sort()
984 for key in self.data:
988 for key in self.data:
985 shape = self.shape(key)[:-1] + H.shape
989 shape = self.shape(key)[:-1] + H.shape
986 for tm, obj in list(self.data[key].items()):
990 for tm, obj in list(self.data[key].items()):
987 h = self.__heights[self.times.tolist().index(tm)]
991 h = self.__heights[self.times.tolist().index(tm)]
988 if H.size == h.size:
992 if H.size == h.size:
989 continue
993 continue
990 index = numpy.where(numpy.in1d(H, h))[0]
994 index = numpy.where(numpy.in1d(H, h))[0]
991 dummy = numpy.zeros(shape) + numpy.nan
995 dummy = numpy.zeros(shape) + numpy.nan
992 if len(shape) == 2:
996 if len(shape) == 2:
993 dummy[:, index] = obj
997 dummy[:, index] = obj
994 else:
998 else:
995 dummy[index] = obj
999 dummy[index] = obj
996 self.data[key][tm] = dummy
1000 self.data[key][tm] = dummy
997
1001
998 self.__heights = [H for tm in self.times]
1002 self.__heights = [H for tm in self.times]
999
1003
1000 def jsonify(self, tm, plot_name, plot_type, decimate=False):
1004 def jsonify(self, tm, plot_name, plot_type, decimate=False):
1001 '''
1005 '''
1002 Convert data to json
1006 Convert data to json
1003 '''
1007 '''
1004
1008
1005 meta = {}
1009 meta = {}
1006 meta['xrange'] = []
1010 meta['xrange'] = []
1007 dy = int(len(self.yrange)/self.MAXNUMY) + 1
1011 dy = int(len(self.yrange)/self.MAXNUMY) + 1
1008 tmp = self.data[tm][self.key]
1012 tmp = self.data[tm][self.key]
1009 shape = tmp.shape
1013 shape = tmp.shape
1010 if len(shape) == 2:
1014 if len(shape) == 2:
1011 data = self.roundFloats(self.data[tm][self.key][::, ::dy].tolist())
1015 data = self.roundFloats(self.data[tm][self.key][::, ::dy].tolist())
1012 elif len(shape) == 3:
1016 elif len(shape) == 3:
1013 dx = int(self.data[tm][self.key].shape[1]/self.MAXNUMX) + 1
1017 dx = int(self.data[tm][self.key].shape[1]/self.MAXNUMX) + 1
1014 data = self.roundFloats(
1018 data = self.roundFloats(
1015 self.data[tm][self.key][::, ::dx, ::dy].tolist())
1019 self.data[tm][self.key][::, ::dx, ::dy].tolist())
1016 meta['xrange'] = self.roundFloats(self.xrange[2][::dx].tolist())
1020 meta['xrange'] = self.roundFloats(self.xrange[2][::dx].tolist())
1017 else:
1021 else:
1018 data = self.roundFloats(self.data[tm][self.key].tolist())
1022 data = self.roundFloats(self.data[tm][self.key].tolist())
1019
1023
1020 ret = {
1024 ret = {
1021 'plot': plot_name,
1025 'plot': plot_name,
1022 'code': self.exp_code,
1026 'code': self.exp_code,
1023 'time': float(tm),
1027 'time': float(tm),
1024 'data': data,
1028 'data': data,
1025 }
1029 }
1026 meta['type'] = plot_type
1030 meta['type'] = plot_type
1027 meta['interval'] = float(self.interval)
1031 meta['interval'] = float(self.interval)
1028 meta['localtime'] = self.localtime
1032 meta['localtime'] = self.localtime
1029 meta['yrange'] = self.roundFloats(self.yrange[::dy].tolist())
1033 meta['yrange'] = self.roundFloats(self.yrange[::dy].tolist())
1030 meta.update(self.meta)
1034 meta.update(self.meta)
1031 ret['metadata'] = meta
1035 ret['metadata'] = meta
1032 return json.dumps(ret)
1036 return json.dumps(ret)
1033
1037
1034 @property
1038 @property
1035 def times(self):
1039 def times(self):
1036 '''
1040 '''
1037 Return the list of times of the current data
1041 Return the list of times of the current data
1038 '''
1042 '''
1039
1043
1040 ret = [t for t in self.data]
1044 ret = [t for t in self.data]
1041 ret.sort()
1045 ret.sort()
1042 return numpy.array(ret)
1046 return numpy.array(ret)
1043
1047
1044 @property
1048 @property
1045 def min_time(self):
1049 def min_time(self):
1046 '''
1050 '''
1047 Return the minimun time value
1051 Return the minimun time value
1048 '''
1052 '''
1049
1053
1050 return self.times[0]
1054 return self.times[0]
1051
1055
1052 @property
1056 @property
1053 def max_time(self):
1057 def max_time(self):
1054 '''
1058 '''
1055 Return the maximun time value
1059 Return the maximun time value
1056 '''
1060 '''
1057
1061
1058 return self.times[-1]
1062 return self.times[-1]
1059
1063
1060 # @property
1064 # @property
1061 # def heights(self):
1065 # def heights(self):
1062 # '''
1066 # '''
1063 # Return the list of heights of the current data
1067 # Return the list of heights of the current data
1064 # '''
1068 # '''
1065
1069
1066 # return numpy.array(self.__heights[-1])
1070 # return numpy.array(self.__heights[-1])
1067
1071
1068 @staticmethod
1072 @staticmethod
1069 def roundFloats(obj):
1073 def roundFloats(obj):
1070 if isinstance(obj, list):
1074 if isinstance(obj, list):
1071 return list(map(PlotterData.roundFloats, obj))
1075 return list(map(PlotterData.roundFloats, obj))
1072 elif isinstance(obj, float):
1076 elif isinstance(obj, float):
1073 return round(obj, 2)
1077 return round(obj, 2)
@@ -1,701 +1,700
1 # Copyright (c) 2012-2020 Jicamarca Radio Observatory
1 # Copyright (c) 2012-2020 Jicamarca Radio Observatory
2 # All rights reserved.
2 # All rights reserved.
3 #
3 #
4 # Distributed under the terms of the BSD 3-clause license.
4 # Distributed under the terms of the BSD 3-clause license.
5 """Base class to create plot operations
5 """Base class to create plot operations
6
6
7 """
7 """
8
8
9 import os
9 import os
10 import sys
10 import sys
11 import zmq
11 import zmq
12 import time
12 import time
13 import numpy
13 import numpy
14 import datetime
14 import datetime
15 from collections import deque
15 from collections import deque
16 from functools import wraps
16 from functools import wraps
17 from threading import Thread
17 from threading import Thread
18 import matplotlib
18 import matplotlib
19
19
20 if 'BACKEND' in os.environ:
20 if 'BACKEND' in os.environ:
21 matplotlib.use(os.environ['BACKEND'])
21 matplotlib.use(os.environ['BACKEND'])
22 elif 'linux' in sys.platform:
22 elif 'linux' in sys.platform:
23 matplotlib.use("TkAgg")
23 matplotlib.use("TkAgg")
24 elif 'darwin' in sys.platform:
24 elif 'darwin' in sys.platform:
25 matplotlib.use('MacOSX')
25 matplotlib.use('MacOSX')
26 else:
26 else:
27 from schainpy.utils import log
27 from schainpy.utils import log
28 log.warning('Using default Backend="Agg"', 'INFO')
28 log.warning('Using default Backend="Agg"', 'INFO')
29 matplotlib.use('Agg')
29 matplotlib.use('Agg')
30
30
31 import matplotlib.pyplot as plt
31 import matplotlib.pyplot as plt
32 from matplotlib.patches import Polygon
32 from matplotlib.patches import Polygon
33 from mpl_toolkits.axes_grid1 import make_axes_locatable
33 from mpl_toolkits.axes_grid1 import make_axes_locatable
34 from matplotlib.ticker import FuncFormatter, LinearLocator, MultipleLocator
34 from matplotlib.ticker import FuncFormatter, LinearLocator, MultipleLocator
35
35
36 from schainpy.model.data.jrodata import PlotterData
36 from schainpy.model.data.jrodata import PlotterData
37 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
37 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
38 from schainpy.utils import log
38 from schainpy.utils import log
39
39
40 jet_values = matplotlib.pyplot.get_cmap('jet', 100)(numpy.arange(100))[10:90]
40 jet_values = matplotlib.pyplot.get_cmap('jet', 100)(numpy.arange(100))[10:90]
41 blu_values = matplotlib.pyplot.get_cmap(
41 blu_values = matplotlib.pyplot.get_cmap(
42 'seismic_r', 20)(numpy.arange(20))[10:15]
42 'seismic_r', 20)(numpy.arange(20))[10:15]
43 ncmap = matplotlib.colors.LinearSegmentedColormap.from_list(
43 ncmap = matplotlib.colors.LinearSegmentedColormap.from_list(
44 'jro', numpy.vstack((blu_values, jet_values)))
44 'jro', numpy.vstack((blu_values, jet_values)))
45 matplotlib.pyplot.register_cmap(cmap=ncmap)
45 matplotlib.pyplot.register_cmap(cmap=ncmap)
46
46
47 CMAPS = [plt.get_cmap(s) for s in ('jro', 'jet', 'viridis',
47 CMAPS = [plt.get_cmap(s) for s in ('jro', 'jet', 'viridis',
48 'plasma', 'inferno', 'Greys', 'seismic', 'bwr', 'coolwarm')]
48 'plasma', 'inferno', 'Greys', 'seismic', 'bwr', 'coolwarm')]
49
49
50 EARTH_RADIUS = 6.3710e3
50 EARTH_RADIUS = 6.3710e3
51
51
52 def ll2xy(lat1, lon1, lat2, lon2):
52 def ll2xy(lat1, lon1, lat2, lon2):
53
53
54 p = 0.017453292519943295
54 p = 0.017453292519943295
55 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
55 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
56 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
56 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
57 r = 12742 * numpy.arcsin(numpy.sqrt(a))
57 r = 12742 * numpy.arcsin(numpy.sqrt(a))
58 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)
58 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)
59 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
59 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
60 theta = -theta + numpy.pi/2
60 theta = -theta + numpy.pi/2
61 return r*numpy.cos(theta), r*numpy.sin(theta)
61 return r*numpy.cos(theta), r*numpy.sin(theta)
62
62
63
63
64 def km2deg(km):
64 def km2deg(km):
65 '''
65 '''
66 Convert distance in km to degrees
66 Convert distance in km to degrees
67 '''
67 '''
68
68
69 return numpy.rad2deg(km/EARTH_RADIUS)
69 return numpy.rad2deg(km/EARTH_RADIUS)
70
70
71
71
72 def figpause(interval):
72 def figpause(interval):
73 backend = plt.rcParams['backend']
73 backend = plt.rcParams['backend']
74 if backend in matplotlib.rcsetup.interactive_bk:
74 if backend in matplotlib.rcsetup.interactive_bk:
75 figManager = matplotlib._pylab_helpers.Gcf.get_active()
75 figManager = matplotlib._pylab_helpers.Gcf.get_active()
76 if figManager is not None:
76 if figManager is not None:
77 canvas = figManager.canvas
77 canvas = figManager.canvas
78 if canvas.figure.stale:
78 if canvas.figure.stale:
79 canvas.draw()
79 canvas.draw()
80 try:
80 try:
81 canvas.start_event_loop(interval)
81 canvas.start_event_loop(interval)
82 except:
82 except:
83 pass
83 pass
84 return
84 return
85
85
86 def popup(message):
86 def popup(message):
87 '''
87 '''
88 '''
88 '''
89
89
90 fig = plt.figure(figsize=(12, 8), facecolor='r')
90 fig = plt.figure(figsize=(12, 8), facecolor='r')
91 text = '\n'.join([s.strip() for s in message.split(':')])
91 text = '\n'.join([s.strip() for s in message.split(':')])
92 fig.text(0.01, 0.5, text, ha='left', va='center',
92 fig.text(0.01, 0.5, text, ha='left', va='center',
93 size='20', weight='heavy', color='w')
93 size='20', weight='heavy', color='w')
94 fig.show()
94 fig.show()
95 figpause(1000)
95 figpause(1000)
96
96
97
97
98 class Throttle(object):
98 class Throttle(object):
99 '''
99 '''
100 Decorator that prevents a function from being called more than once every
100 Decorator that prevents a function from being called more than once every
101 time period.
101 time period.
102 To create a function that cannot be called more than once a minute, but
102 To create a function that cannot be called more than once a minute, but
103 will sleep until it can be called:
103 will sleep until it can be called:
104 @Throttle(minutes=1)
104 @Throttle(minutes=1)
105 def foo():
105 def foo():
106 pass
106 pass
107
107
108 for i in range(10):
108 for i in range(10):
109 foo()
109 foo()
110 print "This function has run %s times." % i
110 print "This function has run %s times." % i
111 '''
111 '''
112
112
113 def __init__(self, seconds=0, minutes=0, hours=0):
113 def __init__(self, seconds=0, minutes=0, hours=0):
114 self.throttle_period = datetime.timedelta(
114 self.throttle_period = datetime.timedelta(
115 seconds=seconds, minutes=minutes, hours=hours
115 seconds=seconds, minutes=minutes, hours=hours
116 )
116 )
117
117
118 self.time_of_last_call = datetime.datetime.min
118 self.time_of_last_call = datetime.datetime.min
119
119
120 def __call__(self, fn):
120 def __call__(self, fn):
121 @wraps(fn)
121 @wraps(fn)
122 def wrapper(*args, **kwargs):
122 def wrapper(*args, **kwargs):
123 coerce = kwargs.pop('coerce', None)
123 coerce = kwargs.pop('coerce', None)
124 if coerce:
124 if coerce:
125 self.time_of_last_call = datetime.datetime.now()
125 self.time_of_last_call = datetime.datetime.now()
126 return fn(*args, **kwargs)
126 return fn(*args, **kwargs)
127 else:
127 else:
128 now = datetime.datetime.now()
128 now = datetime.datetime.now()
129 time_since_last_call = now - self.time_of_last_call
129 time_since_last_call = now - self.time_of_last_call
130 time_left = self.throttle_period - time_since_last_call
130 time_left = self.throttle_period - time_since_last_call
131
131
132 if time_left > datetime.timedelta(seconds=0):
132 if time_left > datetime.timedelta(seconds=0):
133 return
133 return
134
134
135 self.time_of_last_call = datetime.datetime.now()
135 self.time_of_last_call = datetime.datetime.now()
136 return fn(*args, **kwargs)
136 return fn(*args, **kwargs)
137
137
138 return wrapper
138 return wrapper
139
139
140 def apply_throttle(value):
140 def apply_throttle(value):
141
141
142 @Throttle(seconds=value)
142 @Throttle(seconds=value)
143 def fnThrottled(fn):
143 def fnThrottled(fn):
144 fn()
144 fn()
145
145
146 return fnThrottled
146 return fnThrottled
147
147
148
148
149 @MPDecorator
149 @MPDecorator
150 class Plot(Operation):
150 class Plot(Operation):
151 """Base class for Schain plotting operations
151 """Base class for Schain plotting operations
152
152
153 This class should never be use directtly you must subclass a new operation,
153 This class should never be use directtly you must subclass a new operation,
154 children classes must be defined as follow:
154 children classes must be defined as follow:
155
155
156 ExamplePlot(Plot):
156 ExamplePlot(Plot):
157
157
158 CODE = 'code'
158 CODE = 'code'
159 colormap = 'jet'
159 colormap = 'jet'
160 plot_type = 'pcolor' # options are ('pcolor', 'pcolorbuffer', 'scatter', 'scatterbuffer')
160 plot_type = 'pcolor' # options are ('pcolor', 'pcolorbuffer', 'scatter', 'scatterbuffer')
161
161
162 def setup(self):
162 def setup(self):
163 pass
163 pass
164
164
165 def plot(self):
165 def plot(self):
166 pass
166 pass
167
167
168 """
168 """
169
169
170 CODE = 'Figure'
170 CODE = 'Figure'
171 colormap = 'jet'
171 colormap = 'jet'
172 bgcolor = 'white'
172 bgcolor = 'white'
173 buffering = True
173 buffering = True
174 __missing = 1E30
174 __missing = 1E30
175
175
176 __attrs__ = ['show', 'save', 'ymin', 'ymax', 'zmin', 'zmax', 'title',
176 __attrs__ = ['show', 'save', 'ymin', 'ymax', 'zmin', 'zmax', 'title',
177 'showprofile']
177 'showprofile']
178
178
179 def __init__(self):
179 def __init__(self):
180
180
181 Operation.__init__(self)
181 Operation.__init__(self)
182 self.isConfig = False
182 self.isConfig = False
183 self.isPlotConfig = False
183 self.isPlotConfig = False
184 self.save_time = 0
184 self.save_time = 0
185 self.sender_time = 0
185 self.sender_time = 0
186 self.data = None
186 self.data = None
187 self.firsttime = True
187 self.firsttime = True
188 self.sender_queue = deque(maxlen=10)
188 self.sender_queue = deque(maxlen=10)
189 self.plots_adjust = {'left': 0.125, 'right': 0.9, 'bottom': 0.15, 'top': 0.9, 'wspace': 0.2, 'hspace': 0.2}
189 self.plots_adjust = {'left': 0.125, 'right': 0.9, 'bottom': 0.15, 'top': 0.9, 'wspace': 0.2, 'hspace': 0.2}
190
190
191 def __fmtTime(self, x, pos):
191 def __fmtTime(self, x, pos):
192 '''
192 '''
193 '''
193 '''
194 if self.t_units == "h_m":
194 if self.t_units == "h_m":
195 return '{}'.format(self.getDateTime(x).strftime('%H:%M'))
195 return '{}'.format(self.getDateTime(x).strftime('%H:%M'))
196 if self.t_units == "h":
196 if self.t_units == "h":
197 return '{}'.format(self.getDateTime(x).strftime('%H'))
197 return '{}'.format(self.getDateTime(x).strftime('%H'))
198
198
199 def __setup(self, **kwargs):
199 def __setup(self, **kwargs):
200 '''
200 '''
201 Initialize variables
201 Initialize variables
202 '''
202 '''
203
203
204 self.figures = []
204 self.figures = []
205 self.axes = []
205 self.axes = []
206 self.cb_axes = []
206 self.cb_axes = []
207 self.pf_axes = []
207 self.pf_axes = []
208 self.localtime = kwargs.pop('localtime', True)
208 self.localtime = kwargs.pop('localtime', True)
209 self.show = kwargs.get('show', True)
209 self.show = kwargs.get('show', True)
210 self.save = kwargs.get('save', False)
210 self.save = kwargs.get('save', False)
211 self.save_period = kwargs.get('save_period', 0)
211 self.save_period = kwargs.get('save_period', 0)
212 self.colormap = kwargs.get('colormap', self.colormap)
212 self.colormap = kwargs.get('colormap', self.colormap)
213 self.colormap_coh = kwargs.get('colormap_coh', 'jet')
213 self.colormap_coh = kwargs.get('colormap_coh', 'jet')
214 self.colormap_phase = kwargs.get('colormap_phase', 'RdBu_r')
214 self.colormap_phase = kwargs.get('colormap_phase', 'RdBu_r')
215 self.colormaps = kwargs.get('colormaps', None)
215 self.colormaps = kwargs.get('colormaps', None)
216 self.bgcolor = kwargs.get('bgcolor', self.bgcolor)
216 self.bgcolor = kwargs.get('bgcolor', self.bgcolor)
217 self.showprofile = kwargs.get('showprofile', False)
217 self.showprofile = kwargs.get('showprofile', False)
218 self.title = kwargs.get('wintitle', self.CODE.upper())
218 self.title = kwargs.get('wintitle', self.CODE.upper())
219 self.cb_label = kwargs.get('cb_label', None)
219 self.cb_label = kwargs.get('cb_label', None)
220 self.cb_labels = kwargs.get('cb_labels', None)
220 self.cb_labels = kwargs.get('cb_labels', None)
221 self.labels = kwargs.get('labels', None)
221 self.labels = kwargs.get('labels', None)
222 self.xaxis = kwargs.get('xaxis', 'frequency')
222 self.xaxis = kwargs.get('xaxis', 'frequency')
223 self.zmin = kwargs.get('zmin', None)
223 self.zmin = kwargs.get('zmin', None)
224 self.zmax = kwargs.get('zmax', None)
224 self.zmax = kwargs.get('zmax', None)
225 self.zlimits = kwargs.get('zlimits', None)
225 self.zlimits = kwargs.get('zlimits', None)
226 self.xmin = kwargs.get('xmin', None)
226 self.xmin = kwargs.get('xmin', None)
227 self.xmax = kwargs.get('xmax', None)
227 self.xmax = kwargs.get('xmax', None)
228 self.xrange = kwargs.get('xrange', 12)
228 self.xrange = kwargs.get('xrange', 12)
229 self.xscale = kwargs.get('xscale', None)
229 self.xscale = kwargs.get('xscale', None)
230 self.ymin = kwargs.get('ymin', None)
230 self.ymin = kwargs.get('ymin', None)
231 self.ymax = kwargs.get('ymax', None)
231 self.ymax = kwargs.get('ymax', None)
232 self.yscale = kwargs.get('yscale', None)
232 self.yscale = kwargs.get('yscale', None)
233 self.xlabel = kwargs.get('xlabel', None)
233 self.xlabel = kwargs.get('xlabel', None)
234 self.attr_time = kwargs.get('attr_time', 'utctime')
234 self.attr_time = kwargs.get('attr_time', 'utctime')
235 self.attr_data = kwargs.get('attr_data', 'data_param')
235 self.attr_data = kwargs.get('attr_data', 'data_param')
236 self.decimation = kwargs.get('decimation', None)
236 self.decimation = kwargs.get('decimation', None)
237 self.oneFigure = kwargs.get('oneFigure', True)
237 self.oneFigure = kwargs.get('oneFigure', True)
238 self.width = kwargs.get('width', None)
238 self.width = kwargs.get('width', None)
239 self.height = kwargs.get('height', None)
239 self.height = kwargs.get('height', None)
240 self.colorbar = kwargs.get('colorbar', True)
240 self.colorbar = kwargs.get('colorbar', True)
241 self.factors = kwargs.get('factors', range(18))
241 self.factors = kwargs.get('factors', range(18))
242 self.channels = kwargs.get('channels', None)
242 self.channels = kwargs.get('channels', None)
243 self.titles = kwargs.get('titles', [])
243 self.titles = kwargs.get('titles', [])
244 self.polar = False
244 self.polar = False
245 self.type = kwargs.get('type', 'iq')
245 self.type = kwargs.get('type', 'iq')
246 self.grid = kwargs.get('grid', False)
246 self.grid = kwargs.get('grid', False)
247 self.pause = kwargs.get('pause', False)
247 self.pause = kwargs.get('pause', False)
248 self.save_code = kwargs.get('save_code', self.CODE)
248 self.save_code = kwargs.get('save_code', self.CODE)
249 self.throttle = kwargs.get('throttle', 0)
249 self.throttle = kwargs.get('throttle', 0)
250 self.exp_code = kwargs.get('exp_code', None)
250 self.exp_code = kwargs.get('exp_code', None)
251 self.server = kwargs.get('server', False)
251 self.server = kwargs.get('server', False)
252 self.sender_period = kwargs.get('sender_period', 60)
252 self.sender_period = kwargs.get('sender_period', 60)
253 self.tag = kwargs.get('tag', '')
253 self.tag = kwargs.get('tag', '')
254 self.height_index = kwargs.get('height_index', None)
254 self.height_index = kwargs.get('height_index', None)
255 self.__throttle_plot = apply_throttle(self.throttle)
255 self.__throttle_plot = apply_throttle(self.throttle)
256 code = self.attr_data if self.attr_data else self.CODE
256 code = self.attr_data if self.attr_data else self.CODE
257 self.data = PlotterData(self.CODE, self.exp_code, self.localtime)
257 self.data = PlotterData(self.CODE, self.exp_code, self.localtime)
258 self.tmin = kwargs.get('tmin', None)
258 self.tmin = kwargs.get('tmin', None)
259 self.t_units = kwargs.get('t_units', "h_m")
259 self.t_units = kwargs.get('t_units', "h_m")
260
260
261 if self.server:
261 if self.server:
262 if not self.server.startswith('tcp://'):
262 if not self.server.startswith('tcp://'):
263 self.server = 'tcp://{}'.format(self.server)
263 self.server = 'tcp://{}'.format(self.server)
264 log.success(
264 log.success(
265 'Sending to server: {}'.format(self.server),
265 'Sending to server: {}'.format(self.server),
266 self.name
266 self.name
267 )
267 )
268
268
269 if isinstance(self.attr_data, str):
269 if isinstance(self.attr_data, str):
270 self.attr_data = [self.attr_data]
270 self.attr_data = [self.attr_data]
271
271
272 def __setup_plot(self):
272 def __setup_plot(self):
273 '''
273 '''
274 Common setup for all figures, here figures and axes are created
274 Common setup for all figures, here figures and axes are created
275 '''
275 '''
276
276
277 self.setup()
277 self.setup()
278
278
279 self.time_label = 'LT' if self.localtime else 'UTC'
279 self.time_label = 'LT' if self.localtime else 'UTC'
280
280
281 if self.width is None:
281 if self.width is None:
282 self.width = 8
282 self.width = 8
283
283
284 self.figures = []
284 self.figures = []
285 self.axes = []
285 self.axes = []
286 self.cb_axes = []
286 self.cb_axes = []
287 self.pf_axes = []
287 self.pf_axes = []
288 self.cmaps = []
288 self.cmaps = []
289
289
290 size = '15%' if self.ncols == 1 else '30%'
290 size = '15%' if self.ncols == 1 else '30%'
291 pad = '4%' if self.ncols == 1 else '8%'
291 pad = '4%' if self.ncols == 1 else '8%'
292
292
293 if self.oneFigure:
293 if self.oneFigure:
294 if self.height is None:
294 if self.height is None:
295 self.height = 1.4 * self.nrows + 1
295 self.height = 1.4 * self.nrows + 1
296 fig = plt.figure(figsize=(self.width, self.height),
296 fig = plt.figure(figsize=(self.width, self.height),
297 edgecolor='k',
297 edgecolor='k',
298 facecolor='w')
298 facecolor='w')
299 self.figures.append(fig)
299 self.figures.append(fig)
300 for n in range(self.nplots):
300 for n in range(self.nplots):
301 ax = fig.add_subplot(self.nrows, self.ncols,
301 ax = fig.add_subplot(self.nrows, self.ncols,
302 n + 1, polar=self.polar)
302 n + 1, polar=self.polar)
303 ax.tick_params(labelsize=8)
303 ax.tick_params(labelsize=8)
304 ax.firsttime = True
304 ax.firsttime = True
305 ax.index = 0
305 ax.index = 0
306 ax.press = None
306 ax.press = None
307 self.axes.append(ax)
307 self.axes.append(ax)
308 if self.showprofile:
308 if self.showprofile:
309 cax = self.__add_axes(ax, size=size, pad=pad)
309 cax = self.__add_axes(ax, size=size, pad=pad)
310 cax.tick_params(labelsize=8)
310 cax.tick_params(labelsize=8)
311 self.pf_axes.append(cax)
311 self.pf_axes.append(cax)
312 else:
312 else:
313 if self.height is None:
313 if self.height is None:
314 self.height = 3
314 self.height = 3
315 for n in range(self.nplots):
315 for n in range(self.nplots):
316 fig = plt.figure(figsize=(self.width, self.height),
316 fig = plt.figure(figsize=(self.width, self.height),
317 edgecolor='k',
317 edgecolor='k',
318 facecolor='w')
318 facecolor='w')
319 ax = fig.add_subplot(1, 1, 1, polar=self.polar)
319 ax = fig.add_subplot(1, 1, 1, polar=self.polar)
320 ax.tick_params(labelsize=8)
320 ax.tick_params(labelsize=8)
321 ax.firsttime = True
321 ax.firsttime = True
322 ax.index = 0
322 ax.index = 0
323 ax.press = None
323 ax.press = None
324 self.figures.append(fig)
324 self.figures.append(fig)
325 self.axes.append(ax)
325 self.axes.append(ax)
326 if self.showprofile:
326 if self.showprofile:
327 cax = self.__add_axes(ax, size=size, pad=pad)
327 cax = self.__add_axes(ax, size=size, pad=pad)
328 cax.tick_params(labelsize=8)
328 cax.tick_params(labelsize=8)
329 self.pf_axes.append(cax)
329 self.pf_axes.append(cax)
330
330
331 for n in range(self.nrows):
331 for n in range(self.nrows):
332 if self.colormaps is not None:
332 if self.colormaps is not None:
333 cmap = plt.get_cmap(self.colormaps[n])
333 cmap = plt.get_cmap(self.colormaps[n])
334 else:
334 else:
335 cmap = plt.get_cmap(self.colormap)
335 cmap = plt.get_cmap(self.colormap)
336 cmap.set_bad(self.bgcolor, 1.)
336 cmap.set_bad(self.bgcolor, 1.)
337 self.cmaps.append(cmap)
337 self.cmaps.append(cmap)
338
338
339 def __add_axes(self, ax, size='30%', pad='8%'):
339 def __add_axes(self, ax, size='30%', pad='8%'):
340 '''
340 '''
341 Add new axes to the given figure
341 Add new axes to the given figure
342 '''
342 '''
343 divider = make_axes_locatable(ax)
343 divider = make_axes_locatable(ax)
344 nax = divider.new_horizontal(size=size, pad=pad)
344 nax = divider.new_horizontal(size=size, pad=pad)
345 ax.figure.add_axes(nax)
345 ax.figure.add_axes(nax)
346 return nax
346 return nax
347
347
348 def fill_gaps(self, x_buffer, y_buffer, z_buffer):
348 def fill_gaps(self, x_buffer, y_buffer, z_buffer):
349 '''
349 '''
350 Create a masked array for missing data
350 Create a masked array for missing data
351 '''
351 '''
352 if x_buffer.shape[0] < 2:
352 if x_buffer.shape[0] < 2:
353 return x_buffer, y_buffer, z_buffer
353 return x_buffer, y_buffer, z_buffer
354
354
355 deltas = x_buffer[1:] - x_buffer[0:-1]
355 deltas = x_buffer[1:] - x_buffer[0:-1]
356 x_median = numpy.median(deltas)
356 x_median = numpy.median(deltas)
357
357
358 index = numpy.where(deltas > 5 * x_median)
358 index = numpy.where(deltas > 5 * x_median)
359
359
360 if len(index[0]) != 0:
360 if len(index[0]) != 0:
361 z_buffer[::, index[0], ::] = self.__missing
361 z_buffer[::, index[0], ::] = self.__missing
362 z_buffer = numpy.ma.masked_inside(z_buffer,
362 z_buffer = numpy.ma.masked_inside(z_buffer,
363 0.99 * self.__missing,
363 0.99 * self.__missing,
364 1.01 * self.__missing)
364 1.01 * self.__missing)
365
365
366 return x_buffer, y_buffer, z_buffer
366 return x_buffer, y_buffer, z_buffer
367
367
368 def decimate(self):
368 def decimate(self):
369
369
370 # dx = int(len(self.x)/self.__MAXNUMX) + 1
370 # dx = int(len(self.x)/self.__MAXNUMX) + 1
371 dy = int(len(self.y) / self.decimation) + 1
371 dy = int(len(self.y) / self.decimation) + 1
372
372
373 # x = self.x[::dx]
373 # x = self.x[::dx]
374 x = self.x
374 x = self.x
375 y = self.y[::dy]
375 y = self.y[::dy]
376 z = self.z[::, ::, ::dy]
376 z = self.z[::, ::, ::dy]
377
377
378 return x, y, z
378 return x, y, z
379
379
380 def format(self):
380 def format(self):
381 '''
381 '''
382 Set min and max values, labels, ticks and titles
382 Set min and max values, labels, ticks and titles
383 '''
383 '''
384
384
385 for n, ax in enumerate(self.axes):
385 for n, ax in enumerate(self.axes):
386 if ax.firsttime:
386 if ax.firsttime:
387 if self.xaxis != 'time':
387 if self.xaxis != 'time':
388 xmin = self.xmin
388 xmin = self.xmin
389 xmax = self.xmax
389 xmax = self.xmax
390 else:
390 else:
391 xmin = self.tmin
391 xmin = self.tmin
392 xmax = self.tmin + self.xrange*60*60
392 xmax = self.tmin + self.xrange*60*60
393 ax.xaxis.set_major_formatter(FuncFormatter(self.__fmtTime))
393 ax.xaxis.set_major_formatter(FuncFormatter(self.__fmtTime))
394 if self.t_units == "h_m":
394 if self.t_units == "h_m":
395 ax.xaxis.set_major_locator(LinearLocator(9))
395 ax.xaxis.set_major_locator(LinearLocator(9))
396 if self.t_units == "h":
396 if self.t_units == "h":
397 ax.xaxis.set_major_locator(LinearLocator(int((xmax-xmin)/3600)+1))
397 ax.xaxis.set_major_locator(LinearLocator(int((xmax-xmin)/3600)+1))
398 ymin = self.ymin if self.ymin is not None else numpy.nanmin(self.y[numpy.isfinite(self.y)])
398 ymin = self.ymin if self.ymin is not None else numpy.nanmin(self.y[numpy.isfinite(self.y)])
399 ymax = self.ymax if self.ymax is not None else numpy.nanmax(self.y[numpy.isfinite(self.y)])
399 ymax = self.ymax if self.ymax is not None else numpy.nanmax(self.y[numpy.isfinite(self.y)])
400 ax.set_facecolor(self.bgcolor)
400 ax.set_facecolor(self.bgcolor)
401 if self.xscale:
401 if self.xscale:
402 ax.xaxis.set_major_formatter(FuncFormatter(
402 ax.xaxis.set_major_formatter(FuncFormatter(
403 lambda x, pos: '{0:g}'.format(x*self.xscale)))
403 lambda x, pos: '{0:g}'.format(x*self.xscale)))
404 if self.yscale:
404 if self.yscale:
405 ax.yaxis.set_major_formatter(FuncFormatter(
405 ax.yaxis.set_major_formatter(FuncFormatter(
406 lambda x, pos: '{0:g}'.format(x*self.yscale)))
406 lambda x, pos: '{0:g}'.format(x*self.yscale)))
407 if self.xlabel is not None:
407 if self.xlabel is not None:
408 ax.set_xlabel(self.xlabel)
408 ax.set_xlabel(self.xlabel)
409 if self.ylabel is not None:
409 if self.ylabel is not None:
410 ax.set_ylabel(self.ylabel)
410 ax.set_ylabel(self.ylabel)
411 if self.showprofile:
411 if self.showprofile:
412 self.pf_axes[n].set_ylim(ymin, ymax)
412 self.pf_axes[n].set_ylim(ymin, ymax)
413 self.pf_axes[n].set_xlim(self.zmin, self.zmax)
413 self.pf_axes[n].set_xlim(self.zmin, self.zmax)
414 self.pf_axes[n].set_xlabel('dB')
414 self.pf_axes[n].set_xlabel('dB')
415 self.pf_axes[n].grid(b=True, axis='x')
415 self.pf_axes[n].grid(b=True, axis='x')
416 [tick.set_visible(False)
416 [tick.set_visible(False)
417 for tick in self.pf_axes[n].get_yticklabels()]
417 for tick in self.pf_axes[n].get_yticklabels()]
418 if self.colorbar:
418 if self.colorbar:
419 ax.cbar = plt.colorbar(
419 ax.cbar = plt.colorbar(
420 ax.plt, ax=ax, fraction=0.05, pad=0.02, aspect=10)
420 ax.plt, ax=ax, fraction=0.05, pad=0.02, aspect=10)
421 ax.cbar.ax.tick_params(labelsize=8)
421 ax.cbar.ax.tick_params(labelsize=8)
422 ax.cbar.ax.press = None
422 ax.cbar.ax.press = None
423 if self.cb_label:
423 if self.cb_label:
424 ax.cbar.set_label(self.cb_label, size=8)
424 ax.cbar.set_label(self.cb_label, size=8)
425 elif self.cb_labels:
425 elif self.cb_labels:
426 ax.cbar.set_label(self.cb_labels[n], size=8)
426 ax.cbar.set_label(self.cb_labels[n], size=8)
427 else:
427 else:
428 ax.cbar = None
428 ax.cbar = None
429 ax.set_xlim(xmin, xmax)
429 ax.set_xlim(xmin, xmax)
430 ax.set_ylim(ymin, ymax)
430 ax.set_ylim(ymin, ymax)
431 ax.firsttime = False
431 ax.firsttime = False
432 if self.grid:
432 if self.grid:
433 ax.grid(True)
433 ax.grid(True)
434 if not self.polar:
434 if not self.polar:
435 ax.set_title('{} {} {}'.format(
435 ax.set_title('{} {} {}'.format(
436 self.titles[n],
436 self.titles[n],
437 self.getDateTime(self.data.max_time).strftime(
437 self.getDateTime(self.data.max_time).strftime(
438 '%Y-%m-%d %H:%M:%S'),
438 '%Y-%m-%d %H:%M:%S'),
439 self.time_label),
439 self.time_label),
440 size=8)
440 size=8)
441 else:
441 else:
442 ax.set_title('{}'.format(self.titles[n]), size=8)
442 ax.set_title('{}'.format(self.titles[n]), size=8)
443 ax.set_ylim(0, 90)
443 ax.set_ylim(0, 90)
444 ax.set_yticks(numpy.arange(0, 90, 20))
444 ax.set_yticks(numpy.arange(0, 90, 20))
445 ax.yaxis.labelpad = 40
445 ax.yaxis.labelpad = 40
446
446
447 if self.firsttime:
447 if self.firsttime:
448 for n, fig in enumerate(self.figures):
448 for n, fig in enumerate(self.figures):
449 fig.subplots_adjust(**self.plots_adjust)
449 fig.subplots_adjust(**self.plots_adjust)
450 self.firsttime = False
450 self.firsttime = False
451
451
452 def clear_figures(self):
452 def clear_figures(self):
453 '''
453 '''
454 Reset axes for redraw plots
454 Reset axes for redraw plots
455 '''
455 '''
456
456
457 for ax in self.axes+self.pf_axes+self.cb_axes:
457 for ax in self.axes+self.pf_axes+self.cb_axes:
458 ax.clear()
458 ax.clear()
459 ax.firsttime = True
459 ax.firsttime = True
460 if hasattr(ax, 'cbar') and ax.cbar:
460 if hasattr(ax, 'cbar') and ax.cbar:
461 ax.cbar.remove()
461 ax.cbar.remove()
462
462
463 def __plot(self):
463 def __plot(self):
464 '''
464 '''
465 Main function to plot, format and save figures
465 Main function to plot, format and save figures
466 '''
466 '''
467
467
468 self.plot()
468 self.plot()
469 self.format()
469 self.format()
470
470
471 for n, fig in enumerate(self.figures):
471 for n, fig in enumerate(self.figures):
472 if self.nrows == 0 or self.nplots == 0:
472 if self.nrows == 0 or self.nplots == 0:
473 log.warning('No data', self.name)
473 log.warning('No data', self.name)
474 fig.text(0.5, 0.5, 'No Data', fontsize='large', ha='center')
474 fig.text(0.5, 0.5, 'No Data', fontsize='large', ha='center')
475 fig.canvas.manager.set_window_title(self.CODE)
475 fig.canvas.manager.set_window_title(self.CODE)
476 continue
476 continue
477
477
478 fig.canvas.manager.set_window_title('{} - {}'.format(self.title,
478 fig.canvas.manager.set_window_title('{} - {}'.format(self.title,
479 self.getDateTime(self.data.max_time).strftime('%Y/%m/%d')))
479 self.getDateTime(self.data.max_time).strftime('%Y/%m/%d')))
480 fig.canvas.draw()
480 fig.canvas.draw()
481 if self.show:
481 if self.show:
482 fig.show()
482 fig.show()
483 figpause(0.01)
483 figpause(0.01)
484
484
485 if self.save:
485 if self.save:
486 self.save_figure(n)
486 self.save_figure(n)
487
487
488 if self.server:
488 if self.server:
489 self.send_to_server()
489 self.send_to_server()
490
490
491 def __update(self, dataOut, timestamp):
491 def __update(self, dataOut, timestamp):
492 '''
492 '''
493 '''
493 '''
494
494
495 metadata = {
495 metadata = {
496 'yrange': dataOut.heightList,
496 'yrange': dataOut.heightList,
497 'interval': dataOut.timeInterval,
497 'interval': dataOut.timeInterval,
498 'channels': dataOut.channelList
498 'channels': dataOut.channelList
499 }
499 }
500
501 data, meta = self.update(dataOut)
500 data, meta = self.update(dataOut)
502 metadata.update(meta)
501 metadata.update(meta)
503 self.data.update(data, timestamp, metadata)
502 self.data.update(data, timestamp, metadata)
504
503
505 def save_figure(self, n):
504 def save_figure(self, n):
506 '''
505 '''
507 '''
506 '''
508
507
509 if (self.data.max_time - self.save_time) <= self.save_period:
508 if (self.data.max_time - self.save_time) <= self.save_period:
510 return
509 return
511
510
512 self.save_time = self.data.max_time
511 self.save_time = self.data.max_time
513
512
514 fig = self.figures[n]
513 fig = self.figures[n]
515
514
516 if self.throttle == 0:
515 if self.throttle == 0:
517 figname = os.path.join(
516 figname = os.path.join(
518 self.save,
517 self.save,
519 self.save_code,
518 self.save_code,
520 '{}_{}.png'.format(
519 '{}_{}.png'.format(
521 self.save_code,
520 self.save_code,
522 self.getDateTime(self.data.max_time).strftime(
521 self.getDateTime(self.data.max_time).strftime(
523 '%Y%m%d_%H%M%S'
522 '%Y%m%d_%H%M%S'
524 ),
523 ),
525 )
524 )
526 )
525 )
527 log.log('Saving figure: {}'.format(figname), self.name)
526 log.log('Saving figure: {}'.format(figname), self.name)
528 if not os.path.isdir(os.path.dirname(figname)):
527 if not os.path.isdir(os.path.dirname(figname)):
529 os.makedirs(os.path.dirname(figname))
528 os.makedirs(os.path.dirname(figname))
530 fig.savefig(figname)
529 fig.savefig(figname)
531
530
532 figname = os.path.join(
531 figname = os.path.join(
533 self.save,
532 self.save,
534 '{}_{}.png'.format(
533 '{}_{}.png'.format(
535 self.save_code,
534 self.save_code,
536 self.getDateTime(self.data.min_time).strftime(
535 self.getDateTime(self.data.min_time).strftime(
537 '%Y%m%d'
536 '%Y%m%d'
538 ),
537 ),
539 )
538 )
540 )
539 )
541
540
542 log.log('Saving figure: {}'.format(figname), self.name)
541 log.log('Saving figure: {}'.format(figname), self.name)
543 if not os.path.isdir(os.path.dirname(figname)):
542 if not os.path.isdir(os.path.dirname(figname)):
544 os.makedirs(os.path.dirname(figname))
543 os.makedirs(os.path.dirname(figname))
545 fig.savefig(figname)
544 fig.savefig(figname)
546
545
547 def send_to_server(self):
546 def send_to_server(self):
548 '''
547 '''
549 '''
548 '''
550
549
551 if self.exp_code == None:
550 if self.exp_code == None:
552 log.warning('Missing `exp_code` skipping sending to server...')
551 log.warning('Missing `exp_code` skipping sending to server...')
553
552
554 last_time = self.data.max_time
553 last_time = self.data.max_time
555 interval = last_time - self.sender_time
554 interval = last_time - self.sender_time
556 if interval < self.sender_period:
555 if interval < self.sender_period:
557 return
556 return
558
557
559 self.sender_time = last_time
558 self.sender_time = last_time
560
559
561 attrs = ['titles', 'zmin', 'zmax', 'tag', 'ymin', 'ymax']
560 attrs = ['titles', 'zmin', 'zmax', 'tag', 'ymin', 'ymax']
562 for attr in attrs:
561 for attr in attrs:
563 value = getattr(self, attr)
562 value = getattr(self, attr)
564 if value:
563 if value:
565 if isinstance(value, (numpy.float32, numpy.float64)):
564 if isinstance(value, (numpy.float32, numpy.float64)):
566 value = round(float(value), 2)
565 value = round(float(value), 2)
567 self.data.meta[attr] = value
566 self.data.meta[attr] = value
568 if self.colormap == 'jet':
567 if self.colormap == 'jet':
569 self.data.meta['colormap'] = 'Jet'
568 self.data.meta['colormap'] = 'Jet'
570 elif 'RdBu' in self.colormap:
569 elif 'RdBu' in self.colormap:
571 self.data.meta['colormap'] = 'RdBu'
570 self.data.meta['colormap'] = 'RdBu'
572 else:
571 else:
573 self.data.meta['colormap'] = 'Viridis'
572 self.data.meta['colormap'] = 'Viridis'
574 self.data.meta['interval'] = int(interval)
573 self.data.meta['interval'] = int(interval)
575
574
576 self.sender_queue.append(last_time)
575 self.sender_queue.append(last_time)
577
576
578 while True:
577 while True:
579 try:
578 try:
580 tm = self.sender_queue.popleft()
579 tm = self.sender_queue.popleft()
581 except IndexError:
580 except IndexError:
582 break
581 break
583 msg = self.data.jsonify(tm, self.save_code, self.plot_type)
582 msg = self.data.jsonify(tm, self.save_code, self.plot_type)
584 self.socket.send_string(msg)
583 self.socket.send_string(msg)
585 socks = dict(self.poll.poll(2000))
584 socks = dict(self.poll.poll(2000))
586 if socks.get(self.socket) == zmq.POLLIN:
585 if socks.get(self.socket) == zmq.POLLIN:
587 reply = self.socket.recv_string()
586 reply = self.socket.recv_string()
588 if reply == 'ok':
587 if reply == 'ok':
589 log.log("Response from server ok", self.name)
588 log.log("Response from server ok", self.name)
590 time.sleep(0.1)
589 time.sleep(0.1)
591 continue
590 continue
592 else:
591 else:
593 log.warning(
592 log.warning(
594 "Malformed reply from server: {}".format(reply), self.name)
593 "Malformed reply from server: {}".format(reply), self.name)
595 else:
594 else:
596 log.warning(
595 log.warning(
597 "No response from server, retrying...", self.name)
596 "No response from server, retrying...", self.name)
598 self.sender_queue.appendleft(tm)
597 self.sender_queue.appendleft(tm)
599 self.socket.setsockopt(zmq.LINGER, 0)
598 self.socket.setsockopt(zmq.LINGER, 0)
600 self.socket.close()
599 self.socket.close()
601 self.poll.unregister(self.socket)
600 self.poll.unregister(self.socket)
602 self.socket = self.context.socket(zmq.REQ)
601 self.socket = self.context.socket(zmq.REQ)
603 self.socket.connect(self.server)
602 self.socket.connect(self.server)
604 self.poll.register(self.socket, zmq.POLLIN)
603 self.poll.register(self.socket, zmq.POLLIN)
605 break
604 break
606
605
607 def setup(self):
606 def setup(self):
608 '''
607 '''
609 This method should be implemented in the child class, the following
608 This method should be implemented in the child class, the following
610 attributes should be set:
609 attributes should be set:
611
610
612 self.nrows: number of rows
611 self.nrows: number of rows
613 self.ncols: number of cols
612 self.ncols: number of cols
614 self.nplots: number of plots (channels or pairs)
613 self.nplots: number of plots (channels or pairs)
615 self.ylabel: label for Y axes
614 self.ylabel: label for Y axes
616 self.titles: list of axes title
615 self.titles: list of axes title
617
616
618 '''
617 '''
619 raise NotImplementedError
618 raise NotImplementedError
620
619
621 def plot(self):
620 def plot(self):
622 '''
621 '''
623 Must be defined in the child class, the actual plotting method
622 Must be defined in the child class, the actual plotting method
624 '''
623 '''
625 raise NotImplementedError
624 raise NotImplementedError
626
625
627 def update(self, dataOut):
626 def update(self, dataOut):
628 '''
627 '''
629 Must be defined in the child class, update self.data with new data
628 Must be defined in the child class, update self.data with new data
630 '''
629 '''
631
630
632 data = {
631 data = {
633 self.CODE: getattr(dataOut, 'data_{}'.format(self.CODE))
632 self.CODE: getattr(dataOut, 'data_{}'.format(self.CODE))
634 }
633 }
635 meta = {}
634 meta = {}
636
635
637 return data, meta
636 return data, meta
638
637
639 def run(self, dataOut, **kwargs):
638 def run(self, dataOut, **kwargs):
640 '''
639 '''
641 Main plotting routine
640 Main plotting routine
642 '''
641 '''
643
642
644 if self.isConfig is False:
643 if self.isConfig is False:
645 self.__setup(**kwargs)
644 self.__setup(**kwargs)
646
645
647 if self.localtime:
646 if self.localtime:
648 self.getDateTime = datetime.datetime.fromtimestamp
647 self.getDateTime = datetime.datetime.fromtimestamp
649 else:
648 else:
650 self.getDateTime = datetime.datetime.utcfromtimestamp
649 self.getDateTime = datetime.datetime.utcfromtimestamp
651
650
652 self.data.setup()
651 self.data.setup()
653 self.isConfig = True
652 self.isConfig = True
654 if self.server:
653 if self.server:
655 self.context = zmq.Context()
654 self.context = zmq.Context()
656 self.socket = self.context.socket(zmq.REQ)
655 self.socket = self.context.socket(zmq.REQ)
657 self.socket.connect(self.server)
656 self.socket.connect(self.server)
658 self.poll = zmq.Poller()
657 self.poll = zmq.Poller()
659 self.poll.register(self.socket, zmq.POLLIN)
658 self.poll.register(self.socket, zmq.POLLIN)
660
659
661 tm = getattr(dataOut, self.attr_time)
660 tm = getattr(dataOut, self.attr_time)
662
661
663 if self.data and 'time' in self.xaxis and (tm - self.tmin) >= self.xrange*60*60:
662 if self.data and 'time' in self.xaxis and (tm - self.tmin) >= self.xrange*60*60:
664 self.save_time = tm
663 self.save_time = tm
665 self.__plot()
664 self.__plot()
666 self.tmin += self.xrange*60*60
665 self.tmin += self.xrange*60*60
667 self.data.setup()
666 self.data.setup()
668 self.clear_figures()
667 self.clear_figures()
669
668
670 self.__update(dataOut, tm)
669 self.__update(dataOut, tm)
671
670
672 if self.isPlotConfig is False:
671 if self.isPlotConfig is False:
673 self.__setup_plot()
672 self.__setup_plot()
674 self.isPlotConfig = True
673 self.isPlotConfig = True
675 if self.xaxis == 'time':
674 if self.xaxis == 'time':
676 dt = self.getDateTime(tm)
675 dt = self.getDateTime(tm)
677 if self.xmin is None:
676 if self.xmin is None:
678 self.tmin = tm
677 self.tmin = tm
679 self.xmin = dt.hour
678 self.xmin = dt.hour
680 minutes = (self.xmin-int(self.xmin)) * 60
679 minutes = (self.xmin-int(self.xmin)) * 60
681 seconds = (minutes - int(minutes)) * 60
680 seconds = (minutes - int(minutes)) * 60
682 self.tmin = (dt.replace(hour=int(self.xmin), minute=int(minutes), second=int(seconds)) -
681 self.tmin = (dt.replace(hour=int(self.xmin), minute=int(minutes), second=int(seconds)) -
683 datetime.datetime(1970, 1, 1)).total_seconds()
682 datetime.datetime(1970, 1, 1)).total_seconds()
684 if self.localtime:
683 if self.localtime:
685 self.tmin += time.timezone
684 self.tmin += time.timezone
686
685
687 if self.xmin is not None and self.xmax is not None:
686 if self.xmin is not None and self.xmax is not None:
688 self.xrange = self.xmax - self.xmin
687 self.xrange = self.xmax - self.xmin
689
688
690 if self.throttle == 0:
689 if self.throttle == 0:
691 self.__plot()
690 self.__plot()
692 else:
691 else:
693 self.__throttle_plot(self.__plot)#, coerce=coerce)
692 self.__throttle_plot(self.__plot)#, coerce=coerce)
694
693
695 def close(self):
694 def close(self):
696
695
697 if self.data and not self.data.flagNoData:
696 if self.data and not self.data.flagNoData:
698 self.save_time = 0
697 self.save_time = 0
699 self.__plot()
698 self.__plot()
700 if self.data and not self.data.flagNoData and self.pause:
699 if self.data and not self.data.flagNoData and self.pause:
701 figpause(10)
700 figpause(10)
@@ -1,356 +1,355
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
6 from schainpy.model.graphics.jroplot_spectra import SpectraPlot, RTIPlot, CoherencePlot
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
41
42 class SnrPlot(RTIPlot):
42 class SnrPlot(RTIPlot):
43 '''
43 '''
44 Plot for SNR Data
44 Plot for SNR Data
45 '''
45 '''
46
46
47 CODE = 'snr'
47 CODE = 'snr'
48 colormap = 'jet'
48 colormap = 'jet'
49
49
50 def update(self, dataOut):
50 def update(self, dataOut):
51 self.update_list(dataOut)
51 self.update_list(dataOut)
52 data = {
52 data = {
53 'snr': 10*numpy.log10(dataOut.data_snr)
53 'snr': 10*numpy.log10(dataOut.data_snr)
54 }
54 }
55
55
56 return data, {}
56 return data, {}
57
57
58 class DopplerPlot(RTIPlot):
58 class DopplerPlot(RTIPlot):
59 '''
59 '''
60 Plot for DOPPLER Data (1st moment)
60 Plot for DOPPLER Data (1st moment)
61 '''
61 '''
62
62
63 CODE = 'dop'
63 CODE = 'dop'
64 colormap = 'jet'
64 colormap = 'jet'
65
65
66 def update(self, dataOut):
66 def update(self, dataOut):
67 self.update_list(dataOut)
67 self.update_list(dataOut)
68 data = {
68 data = {
69 'dop': 10*numpy.log10(dataOut.data_dop)
69 'dop': 10*numpy.log10(dataOut.data_dop)
70 }
70 }
71
71
72 return data, {}
72 return data, {}
73
73
74 class PowerPlot(RTIPlot):
74 class PowerPlot(RTIPlot):
75 '''
75 '''
76 Plot for Power Data (0 moment)
76 Plot for Power Data (0 moment)
77 '''
77 '''
78
78
79 CODE = 'pow'
79 CODE = 'pow'
80 colormap = 'jet'
80 colormap = 'jet'
81
81
82 def update(self, dataOut):
82 def update(self, dataOut):
83 self.update_list(dataOut)
83 self.update_list(dataOut)
84 data = {
84 data = {
85 'pow': 10*numpy.log10(dataOut.data_pow)
85 'pow': 10*numpy.log10(dataOut.data_pow)
86 }
86 }
87 #print("data",data)
88 return data, {}
87 return data, {}
89
88
90 class SpectralWidthPlot(RTIPlot):
89 class SpectralWidthPlot(RTIPlot):
91 '''
90 '''
92 Plot for Spectral Width Data (2nd moment)
91 Plot for Spectral Width Data (2nd moment)
93 '''
92 '''
94
93
95 CODE = 'width'
94 CODE = 'width'
96 colormap = 'jet'
95 colormap = 'jet'
97
96
98 def update(self, dataOut):
97 def update(self, dataOut):
99 self.update_list(dataOut)
98 self.update_list(dataOut)
100 data = {
99 data = {
101 'width': dataOut.data_width
100 'width': dataOut.data_width
102 }
101 }
103
102
104 return data, {}
103 return data, {}
105
104
106 class SkyMapPlot(Plot):
105 class SkyMapPlot(Plot):
107 '''
106 '''
108 Plot for meteors detection data
107 Plot for meteors detection data
109 '''
108 '''
110
109
111 CODE = 'param'
110 CODE = 'param'
112
111
113 def setup(self):
112 def setup(self):
114
113
115 self.ncols = 1
114 self.ncols = 1
116 self.nrows = 1
115 self.nrows = 1
117 self.width = 7.2
116 self.width = 7.2
118 self.height = 7.2
117 self.height = 7.2
119 self.nplots = 1
118 self.nplots = 1
120 self.xlabel = 'Zonal Zenith Angle (deg)'
119 self.xlabel = 'Zonal Zenith Angle (deg)'
121 self.ylabel = 'Meridional Zenith Angle (deg)'
120 self.ylabel = 'Meridional Zenith Angle (deg)'
122 self.polar = True
121 self.polar = True
123 self.ymin = -180
122 self.ymin = -180
124 self.ymax = 180
123 self.ymax = 180
125 self.colorbar = False
124 self.colorbar = False
126
125
127 def plot(self):
126 def plot(self):
128
127
129 arrayParameters = numpy.concatenate(self.data['param'])
128 arrayParameters = numpy.concatenate(self.data['param'])
130 error = arrayParameters[:, -1]
129 error = arrayParameters[:, -1]
131 indValid = numpy.where(error == 0)[0]
130 indValid = numpy.where(error == 0)[0]
132 finalMeteor = arrayParameters[indValid, :]
131 finalMeteor = arrayParameters[indValid, :]
133 finalAzimuth = finalMeteor[:, 3]
132 finalAzimuth = finalMeteor[:, 3]
134 finalZenith = finalMeteor[:, 4]
133 finalZenith = finalMeteor[:, 4]
135
134
136 x = finalAzimuth * numpy.pi / 180
135 x = finalAzimuth * numpy.pi / 180
137 y = finalZenith
136 y = finalZenith
138
137
139 ax = self.axes[0]
138 ax = self.axes[0]
140
139
141 if ax.firsttime:
140 if ax.firsttime:
142 ax.plot = ax.plot(x, y, 'bo', markersize=5)[0]
141 ax.plot = ax.plot(x, y, 'bo', markersize=5)[0]
143 else:
142 else:
144 ax.plot.set_data(x, y)
143 ax.plot.set_data(x, y)
145
144
146 dt1 = self.getDateTime(self.data.min_time).strftime('%y/%m/%d %H:%M:%S')
145 dt1 = self.getDateTime(self.data.min_time).strftime('%y/%m/%d %H:%M:%S')
147 dt2 = self.getDateTime(self.data.max_time).strftime('%y/%m/%d %H:%M:%S')
146 dt2 = self.getDateTime(self.data.max_time).strftime('%y/%m/%d %H:%M:%S')
148 title = 'Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n' % (dt1,
147 title = 'Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n' % (dt1,
149 dt2,
148 dt2,
150 len(x))
149 len(x))
151 self.titles[0] = title
150 self.titles[0] = title
152
151
153
152
154 class GenericRTIPlot(Plot):
153 class GenericRTIPlot(Plot):
155 '''
154 '''
156 Plot for data_xxxx object
155 Plot for data_xxxx object
157 '''
156 '''
158
157
159 CODE = 'param'
158 CODE = 'param'
160 colormap = 'viridis'
159 colormap = 'viridis'
161 plot_type = 'pcolorbuffer'
160 plot_type = 'pcolorbuffer'
162
161
163 def setup(self):
162 def setup(self):
164 self.xaxis = 'time'
163 self.xaxis = 'time'
165 self.ncols = 1
164 self.ncols = 1
166 self.nrows = self.data.shape('param')[0]
165 self.nrows = self.data.shape('param')[0]
167 self.nplots = self.nrows
166 self.nplots = self.nrows
168 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.08, 'right':0.95, 'top': 0.95})
167 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.08, 'right':0.95, 'top': 0.95})
169
168
170 if not self.xlabel:
169 if not self.xlabel:
171 self.xlabel = 'Time'
170 self.xlabel = 'Time'
172
171
173 self.ylabel = 'Height [km]'
172 self.ylabel = 'Height [km]'
174 if not self.titles:
173 if not self.titles:
175 self.titles = ['Param {}'.format(x) for x in range(self.nrows)]
174 self.titles = ['Param {}'.format(x) for x in range(self.nrows)]
176
175
177 def update(self, dataOut):
176 def update(self, dataOut):
178
177
179 data = {
178 data = {
180 'param' : numpy.concatenate([getattr(dataOut, attr) for attr in self.attr_data], axis=0)
179 'param' : numpy.concatenate([getattr(dataOut, attr) for attr in self.attr_data], axis=0)
181 }
180 }
182
181
183 meta = {}
182 meta = {}
184
183
185 return data, meta
184 return data, meta
186
185
187 def plot(self):
186 def plot(self):
188 # self.data.normalize_heights()
187 # self.data.normalize_heights()
189 self.x = self.data.times
188 self.x = self.data.times
190 self.y = self.data.yrange
189 self.y = self.data.yrange
191 self.z = self.data['param']
190 self.z = self.data['param']
192
191
193 self.z = numpy.ma.masked_invalid(self.z)
192 self.z = numpy.ma.masked_invalid(self.z)
194
193
195 if self.decimation is None:
194 if self.decimation is None:
196 x, y, z = self.fill_gaps(self.x, self.y, self.z)
195 x, y, z = self.fill_gaps(self.x, self.y, self.z)
197 else:
196 else:
198 x, y, z = self.fill_gaps(*self.decimate())
197 x, y, z = self.fill_gaps(*self.decimate())
199
198
200 for n, ax in enumerate(self.axes):
199 for n, ax in enumerate(self.axes):
201
200
202 self.zmax = self.zmax if self.zmax is not None else numpy.max(
201 self.zmax = self.zmax if self.zmax is not None else numpy.max(
203 self.z[n])
202 self.z[n])
204 self.zmin = self.zmin if self.zmin is not None else numpy.min(
203 self.zmin = self.zmin if self.zmin is not None else numpy.min(
205 self.z[n])
204 self.z[n])
206
205
207 if ax.firsttime:
206 if ax.firsttime:
208 if self.zlimits is not None:
207 if self.zlimits is not None:
209 self.zmin, self.zmax = self.zlimits[n]
208 self.zmin, self.zmax = self.zlimits[n]
210
209
211 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
210 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
212 vmin=self.zmin,
211 vmin=self.zmin,
213 vmax=self.zmax,
212 vmax=self.zmax,
214 cmap=self.cmaps[n]
213 cmap=self.cmaps[n]
215 )
214 )
216 else:
215 else:
217 if self.zlimits is not None:
216 if self.zlimits is not None:
218 self.zmin, self.zmax = self.zlimits[n]
217 self.zmin, self.zmax = self.zlimits[n]
219 ax.collections.remove(ax.collections[0])
218 ax.collections.remove(ax.collections[0])
220 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
219 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
221 vmin=self.zmin,
220 vmin=self.zmin,
222 vmax=self.zmax,
221 vmax=self.zmax,
223 cmap=self.cmaps[n]
222 cmap=self.cmaps[n]
224 )
223 )
225
224
226
225
227 class PolarMapPlot(Plot):
226 class PolarMapPlot(Plot):
228 '''
227 '''
229 Plot for weather radar
228 Plot for weather radar
230 '''
229 '''
231
230
232 CODE = 'param'
231 CODE = 'param'
233 colormap = 'seismic'
232 colormap = 'seismic'
234
233
235 def setup(self):
234 def setup(self):
236 self.ncols = 1
235 self.ncols = 1
237 self.nrows = 1
236 self.nrows = 1
238 self.width = 9
237 self.width = 9
239 self.height = 8
238 self.height = 8
240 self.mode = self.data.meta['mode']
239 self.mode = self.data.meta['mode']
241 if self.channels is not None:
240 if self.channels is not None:
242 self.nplots = len(self.channels)
241 self.nplots = len(self.channels)
243 self.nrows = len(self.channels)
242 self.nrows = len(self.channels)
244 else:
243 else:
245 self.nplots = self.data.shape(self.CODE)[0]
244 self.nplots = self.data.shape(self.CODE)[0]
246 self.nrows = self.nplots
245 self.nrows = self.nplots
247 self.channels = list(range(self.nplots))
246 self.channels = list(range(self.nplots))
248 if self.mode == 'E':
247 if self.mode == 'E':
249 self.xlabel = 'Longitude'
248 self.xlabel = 'Longitude'
250 self.ylabel = 'Latitude'
249 self.ylabel = 'Latitude'
251 else:
250 else:
252 self.xlabel = 'Range (km)'
251 self.xlabel = 'Range (km)'
253 self.ylabel = 'Height (km)'
252 self.ylabel = 'Height (km)'
254 self.bgcolor = 'white'
253 self.bgcolor = 'white'
255 self.cb_labels = self.data.meta['units']
254 self.cb_labels = self.data.meta['units']
256 self.lat = self.data.meta['latitude']
255 self.lat = self.data.meta['latitude']
257 self.lon = self.data.meta['longitude']
256 self.lon = self.data.meta['longitude']
258 self.xmin, self.xmax = float(
257 self.xmin, self.xmax = float(
259 km2deg(self.xmin) + self.lon), float(km2deg(self.xmax) + self.lon)
258 km2deg(self.xmin) + self.lon), float(km2deg(self.xmax) + self.lon)
260 self.ymin, self.ymax = float(
259 self.ymin, self.ymax = float(
261 km2deg(self.ymin) + self.lat), float(km2deg(self.ymax) + self.lat)
260 km2deg(self.ymin) + self.lat), float(km2deg(self.ymax) + self.lat)
262 # self.polar = True
261 # self.polar = True
263
262
264 def plot(self):
263 def plot(self):
265
264
266 for n, ax in enumerate(self.axes):
265 for n, ax in enumerate(self.axes):
267 data = self.data['param'][self.channels[n]]
266 data = self.data['param'][self.channels[n]]
268
267
269 zeniths = numpy.linspace(
268 zeniths = numpy.linspace(
270 0, self.data.meta['max_range'], data.shape[1])
269 0, self.data.meta['max_range'], data.shape[1])
271 if self.mode == 'E':
270 if self.mode == 'E':
272 azimuths = -numpy.radians(self.data.yrange)+numpy.pi/2
271 azimuths = -numpy.radians(self.data.yrange)+numpy.pi/2
273 r, theta = numpy.meshgrid(zeniths, azimuths)
272 r, theta = numpy.meshgrid(zeniths, azimuths)
274 x, y = r*numpy.cos(theta)*numpy.cos(numpy.radians(self.data.meta['elevation'])), r*numpy.sin(
273 x, y = r*numpy.cos(theta)*numpy.cos(numpy.radians(self.data.meta['elevation'])), r*numpy.sin(
275 theta)*numpy.cos(numpy.radians(self.data.meta['elevation']))
274 theta)*numpy.cos(numpy.radians(self.data.meta['elevation']))
276 x = km2deg(x) + self.lon
275 x = km2deg(x) + self.lon
277 y = km2deg(y) + self.lat
276 y = km2deg(y) + self.lat
278 else:
277 else:
279 azimuths = numpy.radians(self.data.yrange)
278 azimuths = numpy.radians(self.data.yrange)
280 r, theta = numpy.meshgrid(zeniths, azimuths)
279 r, theta = numpy.meshgrid(zeniths, azimuths)
281 x, y = r*numpy.cos(theta), r*numpy.sin(theta)
280 x, y = r*numpy.cos(theta), r*numpy.sin(theta)
282 self.y = zeniths
281 self.y = zeniths
283
282
284 if ax.firsttime:
283 if ax.firsttime:
285 if self.zlimits is not None:
284 if self.zlimits is not None:
286 self.zmin, self.zmax = self.zlimits[n]
285 self.zmin, self.zmax = self.zlimits[n]
287 ax.plt = ax.pcolormesh( # r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
286 ax.plt = ax.pcolormesh( # r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
288 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
287 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
289 vmin=self.zmin,
288 vmin=self.zmin,
290 vmax=self.zmax,
289 vmax=self.zmax,
291 cmap=self.cmaps[n])
290 cmap=self.cmaps[n])
292 else:
291 else:
293 if self.zlimits is not None:
292 if self.zlimits is not None:
294 self.zmin, self.zmax = self.zlimits[n]
293 self.zmin, self.zmax = self.zlimits[n]
295 ax.collections.remove(ax.collections[0])
294 ax.collections.remove(ax.collections[0])
296 ax.plt = ax.pcolormesh( # r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
295 ax.plt = ax.pcolormesh( # r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
297 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
296 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
298 vmin=self.zmin,
297 vmin=self.zmin,
299 vmax=self.zmax,
298 vmax=self.zmax,
300 cmap=self.cmaps[n])
299 cmap=self.cmaps[n])
301
300
302 if self.mode == 'A':
301 if self.mode == 'A':
303 continue
302 continue
304
303
305 # plot district names
304 # plot district names
306 f = open('/data/workspace/schain_scripts/distrito.csv')
305 f = open('/data/workspace/schain_scripts/distrito.csv')
307 for line in f:
306 for line in f:
308 label, lon, lat = [s.strip() for s in line.split(',') if s]
307 label, lon, lat = [s.strip() for s in line.split(',') if s]
309 lat = float(lat)
308 lat = float(lat)
310 lon = float(lon)
309 lon = float(lon)
311 # ax.plot(lon, lat, '.b', ms=2)
310 # ax.plot(lon, lat, '.b', ms=2)
312 ax.text(lon, lat, label.decode('utf8'), ha='center',
311 ax.text(lon, lat, label.decode('utf8'), ha='center',
313 va='bottom', size='8', color='black')
312 va='bottom', size='8', color='black')
314
313
315 # plot limites
314 # plot limites
316 limites = []
315 limites = []
317 tmp = []
316 tmp = []
318 for line in open('/data/workspace/schain_scripts/lima.csv'):
317 for line in open('/data/workspace/schain_scripts/lima.csv'):
319 if '#' in line:
318 if '#' in line:
320 if tmp:
319 if tmp:
321 limites.append(tmp)
320 limites.append(tmp)
322 tmp = []
321 tmp = []
323 continue
322 continue
324 values = line.strip().split(',')
323 values = line.strip().split(',')
325 tmp.append((float(values[0]), float(values[1])))
324 tmp.append((float(values[0]), float(values[1])))
326 for points in limites:
325 for points in limites:
327 ax.add_patch(
326 ax.add_patch(
328 Polygon(points, ec='k', fc='none', ls='--', lw=0.5))
327 Polygon(points, ec='k', fc='none', ls='--', lw=0.5))
329
328
330 # plot Cuencas
329 # plot Cuencas
331 for cuenca in ('rimac', 'lurin', 'mala', 'chillon', 'chilca', 'chancay-huaral'):
330 for cuenca in ('rimac', 'lurin', 'mala', 'chillon', 'chilca', 'chancay-huaral'):
332 f = open('/data/workspace/schain_scripts/{}.csv'.format(cuenca))
331 f = open('/data/workspace/schain_scripts/{}.csv'.format(cuenca))
333 values = [line.strip().split(',') for line in f]
332 values = [line.strip().split(',') for line in f]
334 points = [(float(s[0]), float(s[1])) for s in values]
333 points = [(float(s[0]), float(s[1])) for s in values]
335 ax.add_patch(Polygon(points, ec='b', fc='none'))
334 ax.add_patch(Polygon(points, ec='b', fc='none'))
336
335
337 # plot grid
336 # plot grid
338 for r in (15, 30, 45, 60):
337 for r in (15, 30, 45, 60):
339 ax.add_artist(plt.Circle((self.lon, self.lat),
338 ax.add_artist(plt.Circle((self.lon, self.lat),
340 km2deg(r), color='0.6', fill=False, lw=0.2))
339 km2deg(r), color='0.6', fill=False, lw=0.2))
341 ax.text(
340 ax.text(
342 self.lon + (km2deg(r))*numpy.cos(60*numpy.pi/180),
341 self.lon + (km2deg(r))*numpy.cos(60*numpy.pi/180),
343 self.lat + (km2deg(r))*numpy.sin(60*numpy.pi/180),
342 self.lat + (km2deg(r))*numpy.sin(60*numpy.pi/180),
344 '{}km'.format(r),
343 '{}km'.format(r),
345 ha='center', va='bottom', size='8', color='0.6', weight='heavy')
344 ha='center', va='bottom', size='8', color='0.6', weight='heavy')
346
345
347 if self.mode == 'E':
346 if self.mode == 'E':
348 title = 'El={}$^\circ$'.format(self.data.meta['elevation'])
347 title = 'El={}$^\circ$'.format(self.data.meta['elevation'])
349 label = 'E{:02d}'.format(int(self.data.meta['elevation']))
348 label = 'E{:02d}'.format(int(self.data.meta['elevation']))
350 else:
349 else:
351 title = 'Az={}$^\circ$'.format(self.data.meta['azimuth'])
350 title = 'Az={}$^\circ$'.format(self.data.meta['azimuth'])
352 label = 'A{:02d}'.format(int(self.data.meta['azimuth']))
351 label = 'A{:02d}'.format(int(self.data.meta['azimuth']))
353
352
354 self.save_labels = ['{}-{}'.format(lbl, label) for lbl in self.labels]
353 self.save_labels = ['{}-{}'.format(lbl, label) for lbl in self.labels]
355 self.titles = ['{} {}'.format(
354 self.titles = ['{} {}'.format(
356 self.data.parameters[x], title) for x in self.channels]
355 self.data.parameters[x], title) for x in self.channels]
@@ -1,731 +1,735
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 """Classes to plot Spectra data
5 """Classes to plot Spectra data
6
6
7 """
7 """
8
8
9 import os
9 import os
10 import numpy
10 import numpy
11
11
12 from schainpy.model.graphics.jroplot_base import Plot, plt, log
12 from schainpy.model.graphics.jroplot_base import Plot, plt, log
13 from itertools import combinations
13 from itertools import combinations
14
14
15
15 class SpectraPlot(Plot):
16 class SpectraPlot(Plot):
16 '''
17 '''
17 Plot for Spectra data
18 Plot for Spectra data
18 '''
19 '''
19
20
20 CODE = 'spc'
21 CODE = 'spc'
21 colormap = 'jet'
22 colormap = 'jet'
22 plot_type = 'pcolor'
23 plot_type = 'pcolor'
23 buffering = False
24 buffering = False
24 channelList = []
25 channelList = []
25
26
26 def setup(self):
27 def setup(self):
27 self.nplots = len(self.data.channels)
28 self.nplots = len(self.data.channels)
28 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
29 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
29 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
30 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
30 self.height = 2.6 * self.nrows
31 self.height = 2.6 * self.nrows
31
32
32 self.cb_label = 'dB'
33 self.cb_label = 'dB'
33 if self.showprofile:
34 if self.showprofile:
34 self.width = 4 * self.ncols
35 self.width = 4 * self.ncols
35 else:
36 else:
36 self.width = 3.5 * self.ncols
37 self.width = 3.5 * self.ncols
37 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.08})
38 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.08})
38 self.ylabel = 'Range [km]'
39 self.ylabel = 'Range [km]'
40 def update_list(self,dataOut):
41 if len(self.channelList) == 0:
42 self.channelList = dataOut.channelList
39
43
40 def update(self, dataOut):
44 def update(self, dataOut):
41 if self.channelList == None:
45 self.update_list(dataOut)
42 self.channelList = dataOut.channelList
43 data = {}
46 data = {}
44 meta = {}
47 meta = {}
45 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
48 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
46
49
47 data['spc'] = spc
50 data['spc'] = spc
48 data['rti'] = dataOut.getPower()
51 data['rti'] = dataOut.getPower()
49 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
52 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
50 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
53 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
51 if self.CODE == 'spc_moments':
54 if self.CODE == 'spc_moments':
52 data['moments'] = dataOut.moments
55 data['moments'] = dataOut.moments
53
56
54 return data, meta
57 return data, meta
55
58
56 def plot(self):
59 def plot(self):
57 if self.xaxis == "frequency":
60 if self.xaxis == "frequency":
58 x = self.data.xrange[0]
61 x = self.data.xrange[0]
59 self.xlabel = "Frequency (kHz)"
62 self.xlabel = "Frequency (kHz)"
60 elif self.xaxis == "time":
63 elif self.xaxis == "time":
61 x = self.data.xrange[1]
64 x = self.data.xrange[1]
62 self.xlabel = "Time (ms)"
65 self.xlabel = "Time (ms)"
63 else:
66 else:
64 x = self.data.xrange[2]
67 x = self.data.xrange[2]
65 self.xlabel = "Velocity (m/s)"
68 self.xlabel = "Velocity (m/s)"
66
69
67 if self.CODE == 'spc_moments':
70 if self.CODE == 'spc_moments':
68 x = self.data.xrange[2]
71 x = self.data.xrange[2]
69 self.xlabel = "Velocity (m/s)"
72 self.xlabel = "Velocity (m/s)"
70
73
71 self.titles = []
74 self.titles = []
72
75
73 y = self.data.yrange
76 y = self.data.yrange
74 self.y = y
77 self.y = y
75
78
76 data = self.data[-1]
79 data = self.data[-1]
77 z = data['spc']
80 z = data['spc']
78
81
79 for n, ax in enumerate(self.axes):
82 for n, ax in enumerate(self.axes):
80 noise = data['noise'][n]
83 noise = data['noise'][n]
81 if self.CODE == 'spc_moments':
84 if self.CODE == 'spc_moments':
82 mean = data['moments'][n, 1]
85 mean = data['moments'][n, 1]
83 if ax.firsttime:
86 if ax.firsttime:
84 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
87 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
85 self.xmin = self.xmin if self.xmin else -self.xmax
88 self.xmin = self.xmin if self.xmin else -self.xmax
86 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
89 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
87 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
90 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
88 ax.plt = ax.pcolormesh(x, y, z[n].T,
91 ax.plt = ax.pcolormesh(x, y, z[n].T,
89 vmin=self.zmin,
92 vmin=self.zmin,
90 vmax=self.zmax,
93 vmax=self.zmax,
91 cmap=plt.get_cmap(self.colormap)
94 cmap=plt.get_cmap(self.colormap)
92 )
95 )
93
96
94 if self.showprofile:
97 if self.showprofile:
95 ax.plt_profile = self.pf_axes[n].plot(
98 ax.plt_profile = self.pf_axes[n].plot(
96 data['rti'][n], y)[0]
99 data['rti'][n], y)[0]
97 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
100 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
98 color="k", linestyle="dashed", lw=1)[0]
101 color="k", linestyle="dashed", lw=1)[0]
99 if self.CODE == 'spc_moments':
102 if self.CODE == 'spc_moments':
100 ax.plt_mean = ax.plot(mean, y, color='k')[0]
103 ax.plt_mean = ax.plot(mean, y, color='k')[0]
101 else:
104 else:
102 ax.plt.set_array(z[n].T.ravel())
105 ax.plt.set_array(z[n].T.ravel())
103 if self.showprofile:
106 if self.showprofile:
104 ax.plt_profile.set_data(data['rti'][n], y)
107 ax.plt_profile.set_data(data['rti'][n], y)
105 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
108 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
106 if self.CODE == 'spc_moments':
109 if self.CODE == 'spc_moments':
107 ax.plt_mean.set_data(mean, y)
110 ax.plt_mean.set_data(mean, y)
108 self.titles.append('CH {}: {:3.2f}dB'.format(self.channelList[n], noise))
111 self.titles.append('CH {}: {:3.2f}dB'.format(self.channelList[n], noise))
109
112
110
113
111 class CrossSpectraPlot(Plot):
114 class CrossSpectraPlot(Plot):
112
115
113 CODE = 'cspc'
116 CODE = 'cspc'
114 colormap = 'jet'
117 colormap = 'jet'
115 plot_type = 'pcolor'
118 plot_type = 'pcolor'
116 zmin_coh = None
119 zmin_coh = None
117 zmax_coh = None
120 zmax_coh = None
118 zmin_phase = None
121 zmin_phase = None
119 zmax_phase = None
122 zmax_phase = None
120 realChannels = None
123 realChannels = None
121 crossPairs = None
124 crossPairs = None
122
125
123 def setup(self):
126 def setup(self):
124
127
125 self.ncols = 4
128 self.ncols = 4
126 self.nplots = len(self.data.pairs) * 2
129 self.nplots = len(self.data.pairs) * 2
127 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
130 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
128 self.width = 3.1 * self.ncols
131 self.width = 3.1 * self.ncols
129 self.height = 2.6 * self.nrows
132 self.height = 2.6 * self.nrows
130 self.ylabel = 'Range [km]'
133 self.ylabel = 'Range [km]'
131 self.showprofile = False
134 self.showprofile = False
132 self.plots_adjust.update({'left': 0.08, 'right': 0.92, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
135 self.plots_adjust.update({'left': 0.08, 'right': 0.92, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
133
136
134 def update(self, dataOut):
137 def update(self, dataOut):
135
138
136 data = {}
139 data = {}
137 meta = {}
140 meta = {}
138
141
139 spc = dataOut.data_spc
142 spc = dataOut.data_spc
140 cspc = dataOut.data_cspc
143 cspc = dataOut.data_cspc
141 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
144 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
142 rawPairs = list(combinations(list(range(dataOut.nChannels)), 2))
145 rawPairs = list(combinations(list(range(dataOut.nChannels)), 2))
143 meta['pairs'] = rawPairs
146 meta['pairs'] = rawPairs
144
147
145 if self.crossPairs == None:
148 if self.crossPairs == None:
146 self.crossPairs = dataOut.pairsList
149 self.crossPairs = dataOut.pairsList
147
150
148 tmp = []
151 tmp = []
149
152
150 for n, pair in enumerate(meta['pairs']):
153 for n, pair in enumerate(meta['pairs']):
151
154
152 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
155 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
153 coh = numpy.abs(out)
156 coh = numpy.abs(out)
154 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
157 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
155 tmp.append(coh)
158 tmp.append(coh)
156 tmp.append(phase)
159 tmp.append(phase)
157
160
158 data['cspc'] = numpy.array(tmp)
161 data['cspc'] = numpy.array(tmp)
159
162
160 return data, meta
163 return data, meta
161
164
162 def plot(self):
165 def plot(self):
163
166
164 if self.xaxis == "frequency":
167 if self.xaxis == "frequency":
165 x = self.data.xrange[0]
168 x = self.data.xrange[0]
166 self.xlabel = "Frequency (kHz)"
169 self.xlabel = "Frequency (kHz)"
167 elif self.xaxis == "time":
170 elif self.xaxis == "time":
168 x = self.data.xrange[1]
171 x = self.data.xrange[1]
169 self.xlabel = "Time (ms)"
172 self.xlabel = "Time (ms)"
170 else:
173 else:
171 x = self.data.xrange[2]
174 x = self.data.xrange[2]
172 self.xlabel = "Velocity (m/s)"
175 self.xlabel = "Velocity (m/s)"
173
176
174 self.titles = []
177 self.titles = []
175
178
176 y = self.data.yrange
179 y = self.data.yrange
177 self.y = y
180 self.y = y
178
181
179 data = self.data[-1]
182 data = self.data[-1]
180 cspc = data['cspc']
183 cspc = data['cspc']
181 #print(self.crossPairs)
184
182 for n in range(len(self.data.pairs)):
185 for n in range(len(self.data.pairs)):
183 #pair = self.data.pairs[n]
186
184 pair = self.crossPairs[n]
187 pair = self.crossPairs[n]
185
188
186 coh = cspc[n*2]
189 coh = cspc[n*2]
187 phase = cspc[n*2+1]
190 phase = cspc[n*2+1]
188 ax = self.axes[2 * n]
191 ax = self.axes[2 * n]
189
192
190 if ax.firsttime:
193 if ax.firsttime:
191 ax.plt = ax.pcolormesh(x, y, coh.T,
194 ax.plt = ax.pcolormesh(x, y, coh.T,
192 vmin=0,
195 vmin=0,
193 vmax=1,
196 vmax=1,
194 cmap=plt.get_cmap(self.colormap_coh)
197 cmap=plt.get_cmap(self.colormap_coh)
195 )
198 )
196 else:
199 else:
197 ax.plt.set_array(coh.T.ravel())
200 ax.plt.set_array(coh.T.ravel())
198 self.titles.append(
201 self.titles.append(
199 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
202 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
200
203
201 ax = self.axes[2 * n + 1]
204 ax = self.axes[2 * n + 1]
202 if ax.firsttime:
205 if ax.firsttime:
203 ax.plt = ax.pcolormesh(x, y, phase.T,
206 ax.plt = ax.pcolormesh(x, y, phase.T,
204 vmin=-180,
207 vmin=-180,
205 vmax=180,
208 vmax=180,
206 cmap=plt.get_cmap(self.colormap_phase)
209 cmap=plt.get_cmap(self.colormap_phase)
207 )
210 )
208 else:
211 else:
209 ax.plt.set_array(phase.T.ravel())
212 ax.plt.set_array(phase.T.ravel())
210 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
213 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
211
214
212
215
213 class RTIPlot(Plot):
216 class RTIPlot(Plot):
214 '''
217 '''
215 Plot for RTI data
218 Plot for RTI data
216 '''
219 '''
217
220
218 CODE = 'rti'
221 CODE = 'rti'
219 colormap = 'jet'
222 colormap = 'jet'
220 plot_type = 'pcolorbuffer'
223 plot_type = 'pcolorbuffer'
221 titles = None
224 titles = None
222 channelList = []
225 channelList = []
223
226
224 def setup(self):
227 def setup(self):
225 self.xaxis = 'time'
228 self.xaxis = 'time'
226 self.ncols = 1
229 self.ncols = 1
227 #print("dataChannels ",self.data.channels)
230 #print("dataChannels ",self.data.channels)
228 self.nrows = len(self.data.channels)
231 self.nrows = len(self.data.channels)
229 self.nplots = len(self.data.channels)
232 self.nplots = len(self.data.channels)
230 self.ylabel = 'Range [km]'
233 self.ylabel = 'Range [km]'
231 self.xlabel = 'Time'
234 self.xlabel = 'Time'
232 self.cb_label = 'dB'
235 self.cb_label = 'dB'
233 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.08, 'right':0.95})
236 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.08, 'right':0.95})
234 self.titles = ['{} Channel {}'.format(
237 self.titles = ['{} Channel {}'.format(
235 self.CODE.upper(), x) for x in range(self.nplots)]
238 self.CODE.upper(), x) for x in range(self.nplots)]
236
239
237 def update_list(self,dataOut):
240 def update_list(self,dataOut):
238 if len(self.channelList) == 0:
241 if len(self.channelList) == 0:
239 self.channelList = dataOut.channelList
242 self.channelList = dataOut.channelList
240
243
244
241 def update(self, dataOut):
245 def update(self, dataOut):
242 self.update_list(dataOut)
246 self.update_list(dataOut)
243 data = {}
247 data = {}
244 meta = {}
248 meta = {}
245 data['rti'] = dataOut.getPower()
249 data['rti'] = dataOut.getPower()
246 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
250 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
247 return data, meta
251 return data, meta
248
252
249 def plot(self):
253 def plot(self):
250
254
251 self.x = self.data.times
255 self.x = self.data.times
252 self.y = self.data.yrange
256 self.y = self.data.yrange
253 self.z = self.data[self.CODE]
257 self.z = self.data[self.CODE]
254 self.z = numpy.ma.masked_invalid(self.z)
258 self.z = numpy.ma.masked_invalid(self.z)
255 try:
259 try:
256 if self.channelList != None:
260 if self.channelList != None:
257 self.titles = ['{} Channel {}'.format(
261 self.titles = ['{} Channel {}'.format(
258 self.CODE.upper(), x) for x in self.channelList]
262 self.CODE.upper(), x) for x in self.channelList]
259 except:
263 except:
260 if self.channelList.any() != None:
264 if self.channelList.any() != None:
261 self.titles = ['{} Channel {}'.format(
265 self.titles = ['{} Channel {}'.format(
262 self.CODE.upper(), x) for x in self.channelList]
266 self.CODE.upper(), x) for x in self.channelList]
263 if self.decimation is None:
267 if self.decimation is None:
264 x, y, z = self.fill_gaps(self.x, self.y, self.z)
268 x, y, z = self.fill_gaps(self.x, self.y, self.z)
265 else:
269 else:
266 x, y, z = self.fill_gaps(*self.decimate())
270 x, y, z = self.fill_gaps(*self.decimate())
267
271
268 for n, ax in enumerate(self.axes):
272 for n, ax in enumerate(self.axes):
269 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
273 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
270 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
274 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
271 data = self.data[-1]
275 data = self.data[-1]
272 if ax.firsttime:
276 if ax.firsttime:
273 ax.plt = ax.pcolormesh(x, y, z[n].T,
277 ax.plt = ax.pcolormesh(x, y, z[n].T,
274 vmin=self.zmin,
278 vmin=self.zmin,
275 vmax=self.zmax,
279 vmax=self.zmax,
276 cmap=plt.get_cmap(self.colormap)
280 cmap=plt.get_cmap(self.colormap)
277 )
281 )
278 if self.showprofile:
282 if self.showprofile:
279 ax.plot_profile = self.pf_axes[n].plot(
283 ax.plot_profile = self.pf_axes[n].plot(
280 data['rti'][n], self.y)[0]
284 data['rti'][n], self.y)[0]
281 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(data['noise'][n], len(self.y)), self.y,
285 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(data['noise'][n], len(self.y)), self.y,
282 color="k", linestyle="dashed", lw=1)[0]
286 color="k", linestyle="dashed", lw=1)[0]
283 else:
287 else:
284 ax.collections.remove(ax.collections[0])
288 ax.collections.remove(ax.collections[0])
285 ax.plt = ax.pcolormesh(x, y, z[n].T,
289 ax.plt = ax.pcolormesh(x, y, z[n].T,
286 vmin=self.zmin,
290 vmin=self.zmin,
287 vmax=self.zmax,
291 vmax=self.zmax,
288 cmap=plt.get_cmap(self.colormap)
292 cmap=plt.get_cmap(self.colormap)
289 )
293 )
290 if self.showprofile:
294 if self.showprofile:
291 ax.plot_profile.set_data(data['rti'][n], self.y)
295 ax.plot_profile.set_data(data['rti'][n], self.y)
292 ax.plot_noise.set_data(numpy.repeat(
296 ax.plot_noise.set_data(numpy.repeat(
293 data['noise'][n], len(self.y)), self.y)
297 data['noise'][n], len(self.y)), self.y)
294
298
295
299
296 class CoherencePlot(RTIPlot):
300 class CoherencePlot(RTIPlot):
297 '''
301 '''
298 Plot for Coherence data
302 Plot for Coherence data
299 '''
303 '''
300
304
301 CODE = 'coh'
305 CODE = 'coh'
302
306
303 def setup(self):
307 def setup(self):
304 self.xaxis = 'time'
308 self.xaxis = 'time'
305 self.ncols = 1
309 self.ncols = 1
306 self.nrows = len(self.data.pairs)
310 self.nrows = len(self.data.pairs)
307 self.nplots = len(self.data.pairs)
311 self.nplots = len(self.data.pairs)
308 self.ylabel = 'Range [km]'
312 self.ylabel = 'Range [km]'
309 self.xlabel = 'Time'
313 self.xlabel = 'Time'
310 self.plots_adjust.update({'hspace':0.6, 'left': 0.1, 'bottom': 0.1,'right':0.95})
314 self.plots_adjust.update({'hspace':0.6, 'left': 0.1, 'bottom': 0.1,'right':0.95})
311 if self.CODE == 'coh':
315 if self.CODE == 'coh':
312 self.cb_label = ''
316 self.cb_label = ''
313 self.titles = [
317 self.titles = [
314 'Coherence Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
318 'Coherence Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
315 else:
319 else:
316 self.cb_label = 'Degrees'
320 self.cb_label = 'Degrees'
317 self.titles = [
321 self.titles = [
318 'Phase Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
322 'Phase Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
319
323
320 def update(self, dataOut):
324 def update(self, dataOut):
321 self.update_list(dataOut)
325 self.update_list(dataOut)
322 data = {}
326 data = {}
323 meta = {}
327 meta = {}
324 data['coh'] = dataOut.getCoherence()
328 data['coh'] = dataOut.getCoherence()
325 meta['pairs'] = dataOut.pairsList
329 meta['pairs'] = dataOut.pairsList
326
330
327
331
328 return data, meta
332 return data, meta
329
333
330 class PhasePlot(CoherencePlot):
334 class PhasePlot(CoherencePlot):
331 '''
335 '''
332 Plot for Phase map data
336 Plot for Phase map data
333 '''
337 '''
334
338
335 CODE = 'phase'
339 CODE = 'phase'
336 colormap = 'seismic'
340 colormap = 'seismic'
337
341
338 def update(self, dataOut):
342 def update(self, dataOut):
339
343
340 data = {}
344 data = {}
341 meta = {}
345 meta = {}
342 data['phase'] = dataOut.getCoherence(phase=True)
346 data['phase'] = dataOut.getCoherence(phase=True)
343 meta['pairs'] = dataOut.pairsList
347 meta['pairs'] = dataOut.pairsList
344
348
345 return data, meta
349 return data, meta
346
350
347 class NoisePlot(Plot):
351 class NoisePlot(Plot):
348 '''
352 '''
349 Plot for noise
353 Plot for noise
350 '''
354 '''
351
355
352 CODE = 'noise'
356 CODE = 'noise'
353 plot_type = 'scatterbuffer'
357 plot_type = 'scatterbuffer'
354
358
355 def setup(self):
359 def setup(self):
356 self.xaxis = 'time'
360 self.xaxis = 'time'
357 self.ncols = 1
361 self.ncols = 1
358 self.nrows = 1
362 self.nrows = 1
359 self.nplots = 1
363 self.nplots = 1
360 self.ylabel = 'Intensity [dB]'
364 self.ylabel = 'Intensity [dB]'
361 self.xlabel = 'Time'
365 self.xlabel = 'Time'
362 self.titles = ['Noise']
366 self.titles = ['Noise']
363 self.colorbar = False
367 self.colorbar = False
364 self.plots_adjust.update({'right': 0.85 })
368 self.plots_adjust.update({'right': 0.85 })
365
369
366 def update(self, dataOut):
370 def update(self, dataOut):
367
371
368 data = {}
372 data = {}
369 meta = {}
373 meta = {}
370 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor).reshape(dataOut.nChannels, 1)
374 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor).reshape(dataOut.nChannels, 1)
371 meta['yrange'] = numpy.array([])
375 meta['yrange'] = numpy.array([])
372
376
373 return data, meta
377 return data, meta
374
378
375 def plot(self):
379 def plot(self):
376
380
377 x = self.data.times
381 x = self.data.times
378 xmin = self.data.min_time
382 xmin = self.data.min_time
379 xmax = xmin + self.xrange * 60 * 60
383 xmax = xmin + self.xrange * 60 * 60
380 Y = self.data['noise']
384 Y = self.data['noise']
381
385
382 if self.axes[0].firsttime:
386 if self.axes[0].firsttime:
383 self.ymin = numpy.nanmin(Y) - 5
387 self.ymin = numpy.nanmin(Y) - 5
384 self.ymax = numpy.nanmax(Y) + 5
388 self.ymax = numpy.nanmax(Y) + 5
385 for ch in self.data.channels:
389 for ch in self.data.channels:
386 y = Y[ch]
390 y = Y[ch]
387 self.axes[0].plot(x, y, lw=1, label='Ch{}'.format(ch))
391 self.axes[0].plot(x, y, lw=1, label='Ch{}'.format(ch))
388 plt.legend(bbox_to_anchor=(1.18, 1.0))
392 plt.legend(bbox_to_anchor=(1.18, 1.0))
389 else:
393 else:
390 for ch in self.data.channels:
394 for ch in self.data.channels:
391 y = Y[ch]
395 y = Y[ch]
392 self.axes[0].lines[ch].set_data(x, y)
396 self.axes[0].lines[ch].set_data(x, y)
393
397
394
398
395 class PowerProfilePlot(Plot):
399 class PowerProfilePlot(Plot):
396
400
397 CODE = 'pow_profile'
401 CODE = 'pow_profile'
398 plot_type = 'scatter'
402 plot_type = 'scatter'
399
403
400 def setup(self):
404 def setup(self):
401
405
402 self.ncols = 1
406 self.ncols = 1
403 self.nrows = 1
407 self.nrows = 1
404 self.nplots = 1
408 self.nplots = 1
405 self.height = 4
409 self.height = 4
406 self.width = 3
410 self.width = 3
407 self.ylabel = 'Range [km]'
411 self.ylabel = 'Range [km]'
408 self.xlabel = 'Intensity [dB]'
412 self.xlabel = 'Intensity [dB]'
409 self.titles = ['Power Profile']
413 self.titles = ['Power Profile']
410 self.colorbar = False
414 self.colorbar = False
411
415
412 def update(self, dataOut):
416 def update(self, dataOut):
413
417
414 data = {}
418 data = {}
415 meta = {}
419 meta = {}
416 data[self.CODE] = dataOut.getPower()
420 data[self.CODE] = dataOut.getPower()
417
421
418 return data, meta
422 return data, meta
419
423
420 def plot(self):
424 def plot(self):
421
425
422 y = self.data.yrange
426 y = self.data.yrange
423 self.y = y
427 self.y = y
424
428
425 x = self.data[-1][self.CODE]
429 x = self.data[-1][self.CODE]
426
430
427 if self.xmin is None: self.xmin = numpy.nanmin(x)*0.9
431 if self.xmin is None: self.xmin = numpy.nanmin(x)*0.9
428 if self.xmax is None: self.xmax = numpy.nanmax(x)*1.1
432 if self.xmax is None: self.xmax = numpy.nanmax(x)*1.1
429
433
430 if self.axes[0].firsttime:
434 if self.axes[0].firsttime:
431 for ch in self.data.channels:
435 for ch in self.data.channels:
432 self.axes[0].plot(x[ch], y, lw=1, label='Ch{}'.format(ch))
436 self.axes[0].plot(x[ch], y, lw=1, label='Ch{}'.format(ch))
433 plt.legend()
437 plt.legend()
434 else:
438 else:
435 for ch in self.data.channels:
439 for ch in self.data.channels:
436 self.axes[0].lines[ch].set_data(x[ch], y)
440 self.axes[0].lines[ch].set_data(x[ch], y)
437
441
438
442
439 class SpectraCutPlot(Plot):
443 class SpectraCutPlot(Plot):
440
444
441 CODE = 'spc_cut'
445 CODE = 'spc_cut'
442 plot_type = 'scatter'
446 plot_type = 'scatter'
443 buffering = False
447 buffering = False
444
448
445 def setup(self):
449 def setup(self):
446
450
447 self.nplots = len(self.data.channels)
451 self.nplots = len(self.data.channels)
448 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
452 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
449 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
453 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
450 self.width = 3.4 * self.ncols + 1.5
454 self.width = 3.4 * self.ncols + 1.5
451 self.height = 3 * self.nrows
455 self.height = 3 * self.nrows
452 self.ylabel = 'Power [dB]'
456 self.ylabel = 'Power [dB]'
453 self.colorbar = False
457 self.colorbar = False
454 self.plots_adjust.update({'left':0.1, 'hspace':0.3, 'right': 0.75, 'bottom':0.08})
458 self.plots_adjust.update({'left':0.1, 'hspace':0.3, 'right': 0.75, 'bottom':0.08})
455
459
456 def update(self, dataOut):
460 def update(self, dataOut):
457
461
458 data = {}
462 data = {}
459 meta = {}
463 meta = {}
460 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
464 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
461 data['spc'] = spc
465 data['spc'] = spc
462 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
466 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
463
467
464 return data, meta
468 return data, meta
465
469
466 def plot(self):
470 def plot(self):
467 if self.xaxis == "frequency":
471 if self.xaxis == "frequency":
468 x = self.data.xrange[0][1:]
472 x = self.data.xrange[0][1:]
469 self.xlabel = "Frequency (kHz)"
473 self.xlabel = "Frequency (kHz)"
470 elif self.xaxis == "time":
474 elif self.xaxis == "time":
471 x = self.data.xrange[1]
475 x = self.data.xrange[1]
472 self.xlabel = "Time (ms)"
476 self.xlabel = "Time (ms)"
473 else:
477 else:
474 x = self.data.xrange[2]
478 x = self.data.xrange[2]
475 self.xlabel = "Velocity (m/s)"
479 self.xlabel = "Velocity (m/s)"
476
480
477 self.titles = []
481 self.titles = []
478
482
479 y = self.data.yrange
483 y = self.data.yrange
480 z = self.data[-1]['spc']
484 z = self.data[-1]['spc']
481
485
482 if self.height_index:
486 if self.height_index:
483 index = numpy.array(self.height_index)
487 index = numpy.array(self.height_index)
484 else:
488 else:
485 index = numpy.arange(0, len(y), int((len(y))/9))
489 index = numpy.arange(0, len(y), int((len(y))/9))
486
490
487 for n, ax in enumerate(self.axes):
491 for n, ax in enumerate(self.axes):
488 if ax.firsttime:
492 if ax.firsttime:
489 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
493 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
490 self.xmin = self.xmin if self.xmin else -self.xmax
494 self.xmin = self.xmin if self.xmin else -self.xmax
491 self.ymin = self.ymin if self.ymin else numpy.nanmin(z)
495 self.ymin = self.ymin if self.ymin else numpy.nanmin(z)
492 self.ymax = self.ymax if self.ymax else numpy.nanmax(z)
496 self.ymax = self.ymax if self.ymax else numpy.nanmax(z)
493 ax.plt = ax.plot(x, z[n, :, index].T)
497 ax.plt = ax.plot(x, z[n, :, index].T)
494 labels = ['Range = {:2.1f}km'.format(y[i]) for i in index]
498 labels = ['Range = {:2.1f}km'.format(y[i]) for i in index]
495 self.figures[0].legend(ax.plt, labels, loc='center right')
499 self.figures[0].legend(ax.plt, labels, loc='center right')
496 else:
500 else:
497 for i, line in enumerate(ax.plt):
501 for i, line in enumerate(ax.plt):
498 line.set_data(x, z[n, :, index[i]])
502 line.set_data(x, z[n, :, index[i]])
499 self.titles.append('CH {}'.format(n))
503 self.titles.append('CH {}'.format(n))
500
504
501
505
502 class BeaconPhase(Plot):
506 class BeaconPhase(Plot):
503
507
504 __isConfig = None
508 __isConfig = None
505 __nsubplots = None
509 __nsubplots = None
506
510
507 PREFIX = 'beacon_phase'
511 PREFIX = 'beacon_phase'
508
512
509 def __init__(self):
513 def __init__(self):
510 Plot.__init__(self)
514 Plot.__init__(self)
511 self.timerange = 24*60*60
515 self.timerange = 24*60*60
512 self.isConfig = False
516 self.isConfig = False
513 self.__nsubplots = 1
517 self.__nsubplots = 1
514 self.counter_imagwr = 0
518 self.counter_imagwr = 0
515 self.WIDTH = 800
519 self.WIDTH = 800
516 self.HEIGHT = 400
520 self.HEIGHT = 400
517 self.WIDTHPROF = 120
521 self.WIDTHPROF = 120
518 self.HEIGHTPROF = 0
522 self.HEIGHTPROF = 0
519 self.xdata = None
523 self.xdata = None
520 self.ydata = None
524 self.ydata = None
521
525
522 self.PLOT_CODE = BEACON_CODE
526 self.PLOT_CODE = BEACON_CODE
523
527
524 self.FTP_WEI = None
528 self.FTP_WEI = None
525 self.EXP_CODE = None
529 self.EXP_CODE = None
526 self.SUB_EXP_CODE = None
530 self.SUB_EXP_CODE = None
527 self.PLOT_POS = None
531 self.PLOT_POS = None
528
532
529 self.filename_phase = None
533 self.filename_phase = None
530
534
531 self.figfile = None
535 self.figfile = None
532
536
533 self.xmin = None
537 self.xmin = None
534 self.xmax = None
538 self.xmax = None
535
539
536 def getSubplots(self):
540 def getSubplots(self):
537
541
538 ncol = 1
542 ncol = 1
539 nrow = 1
543 nrow = 1
540
544
541 return nrow, ncol
545 return nrow, ncol
542
546
543 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
547 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
544
548
545 self.__showprofile = showprofile
549 self.__showprofile = showprofile
546 self.nplots = nplots
550 self.nplots = nplots
547
551
548 ncolspan = 7
552 ncolspan = 7
549 colspan = 6
553 colspan = 6
550 self.__nsubplots = 2
554 self.__nsubplots = 2
551
555
552 self.createFigure(id = id,
556 self.createFigure(id = id,
553 wintitle = wintitle,
557 wintitle = wintitle,
554 widthplot = self.WIDTH+self.WIDTHPROF,
558 widthplot = self.WIDTH+self.WIDTHPROF,
555 heightplot = self.HEIGHT+self.HEIGHTPROF,
559 heightplot = self.HEIGHT+self.HEIGHTPROF,
556 show=show)
560 show=show)
557
561
558 nrow, ncol = self.getSubplots()
562 nrow, ncol = self.getSubplots()
559
563
560 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
564 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
561
565
562 def save_phase(self, filename_phase):
566 def save_phase(self, filename_phase):
563 f = open(filename_phase,'w+')
567 f = open(filename_phase,'w+')
564 f.write('\n\n')
568 f.write('\n\n')
565 f.write('JICAMARCA RADIO OBSERVATORY - Beacon Phase \n')
569 f.write('JICAMARCA RADIO OBSERVATORY - Beacon Phase \n')
566 f.write('DD MM YYYY HH MM SS pair(2,0) pair(2,1) pair(2,3) pair(2,4)\n\n' )
570 f.write('DD MM YYYY HH MM SS pair(2,0) pair(2,1) pair(2,3) pair(2,4)\n\n' )
567 f.close()
571 f.close()
568
572
569 def save_data(self, filename_phase, data, data_datetime):
573 def save_data(self, filename_phase, data, data_datetime):
570 f=open(filename_phase,'a')
574 f=open(filename_phase,'a')
571 timetuple_data = data_datetime.timetuple()
575 timetuple_data = data_datetime.timetuple()
572 day = str(timetuple_data.tm_mday)
576 day = str(timetuple_data.tm_mday)
573 month = str(timetuple_data.tm_mon)
577 month = str(timetuple_data.tm_mon)
574 year = str(timetuple_data.tm_year)
578 year = str(timetuple_data.tm_year)
575 hour = str(timetuple_data.tm_hour)
579 hour = str(timetuple_data.tm_hour)
576 minute = str(timetuple_data.tm_min)
580 minute = str(timetuple_data.tm_min)
577 second = str(timetuple_data.tm_sec)
581 second = str(timetuple_data.tm_sec)
578 f.write(day+' '+month+' '+year+' '+hour+' '+minute+' '+second+' '+str(data[0])+' '+str(data[1])+' '+str(data[2])+' '+str(data[3])+'\n')
582 f.write(day+' '+month+' '+year+' '+hour+' '+minute+' '+second+' '+str(data[0])+' '+str(data[1])+' '+str(data[2])+' '+str(data[3])+'\n')
579 f.close()
583 f.close()
580
584
581 def plot(self):
585 def plot(self):
582 log.warning('TODO: Not yet implemented...')
586 log.warning('TODO: Not yet implemented...')
583
587
584 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
588 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
585 xmin=None, xmax=None, ymin=None, ymax=None, hmin=None, hmax=None,
589 xmin=None, xmax=None, ymin=None, ymax=None, hmin=None, hmax=None,
586 timerange=None,
590 timerange=None,
587 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
591 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
588 server=None, folder=None, username=None, password=None,
592 server=None, folder=None, username=None, password=None,
589 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
593 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
590
594
591 if dataOut.flagNoData:
595 if dataOut.flagNoData:
592 return dataOut
596 return dataOut
593
597
594 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
598 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
595 return
599 return
596
600
597 if pairsList == None:
601 if pairsList == None:
598 pairsIndexList = dataOut.pairsIndexList[:10]
602 pairsIndexList = dataOut.pairsIndexList[:10]
599 else:
603 else:
600 pairsIndexList = []
604 pairsIndexList = []
601 for pair in pairsList:
605 for pair in pairsList:
602 if pair not in dataOut.pairsList:
606 if pair not in dataOut.pairsList:
603 raise ValueError("Pair %s is not in dataOut.pairsList" %(pair))
607 raise ValueError("Pair %s is not in dataOut.pairsList" %(pair))
604 pairsIndexList.append(dataOut.pairsList.index(pair))
608 pairsIndexList.append(dataOut.pairsList.index(pair))
605
609
606 if pairsIndexList == []:
610 if pairsIndexList == []:
607 return
611 return
608
612
609 # if len(pairsIndexList) > 4:
613 # if len(pairsIndexList) > 4:
610 # pairsIndexList = pairsIndexList[0:4]
614 # pairsIndexList = pairsIndexList[0:4]
611
615
612 hmin_index = None
616 hmin_index = None
613 hmax_index = None
617 hmax_index = None
614
618
615 if hmin != None and hmax != None:
619 if hmin != None and hmax != None:
616 indexes = numpy.arange(dataOut.nHeights)
620 indexes = numpy.arange(dataOut.nHeights)
617 hmin_list = indexes[dataOut.heightList >= hmin]
621 hmin_list = indexes[dataOut.heightList >= hmin]
618 hmax_list = indexes[dataOut.heightList <= hmax]
622 hmax_list = indexes[dataOut.heightList <= hmax]
619
623
620 if hmin_list.any():
624 if hmin_list.any():
621 hmin_index = hmin_list[0]
625 hmin_index = hmin_list[0]
622
626
623 if hmax_list.any():
627 if hmax_list.any():
624 hmax_index = hmax_list[-1]+1
628 hmax_index = hmax_list[-1]+1
625
629
626 x = dataOut.getTimeRange()
630 x = dataOut.getTimeRange()
627
631
628 thisDatetime = dataOut.datatime
632 thisDatetime = dataOut.datatime
629
633
630 title = wintitle + " Signal Phase" # : %s" %(thisDatetime.strftime("%d-%b-%Y"))
634 title = wintitle + " Signal Phase" # : %s" %(thisDatetime.strftime("%d-%b-%Y"))
631 xlabel = "Local Time"
635 xlabel = "Local Time"
632 ylabel = "Phase (degrees)"
636 ylabel = "Phase (degrees)"
633
637
634 update_figfile = False
638 update_figfile = False
635
639
636 nplots = len(pairsIndexList)
640 nplots = len(pairsIndexList)
637 #phase = numpy.zeros((len(pairsIndexList),len(dataOut.beacon_heiIndexList)))
641 #phase = numpy.zeros((len(pairsIndexList),len(dataOut.beacon_heiIndexList)))
638 phase_beacon = numpy.zeros(len(pairsIndexList))
642 phase_beacon = numpy.zeros(len(pairsIndexList))
639 for i in range(nplots):
643 for i in range(nplots):
640 pair = dataOut.pairsList[pairsIndexList[i]]
644 pair = dataOut.pairsList[pairsIndexList[i]]
641 ccf = numpy.average(dataOut.data_cspc[pairsIndexList[i], :, hmin_index:hmax_index], axis=0)
645 ccf = numpy.average(dataOut.data_cspc[pairsIndexList[i], :, hmin_index:hmax_index], axis=0)
642 powa = numpy.average(dataOut.data_spc[pair[0], :, hmin_index:hmax_index], axis=0)
646 powa = numpy.average(dataOut.data_spc[pair[0], :, hmin_index:hmax_index], axis=0)
643 powb = numpy.average(dataOut.data_spc[pair[1], :, hmin_index:hmax_index], axis=0)
647 powb = numpy.average(dataOut.data_spc[pair[1], :, hmin_index:hmax_index], axis=0)
644 avgcoherenceComplex = ccf/numpy.sqrt(powa*powb)
648 avgcoherenceComplex = ccf/numpy.sqrt(powa*powb)
645 phase = numpy.arctan2(avgcoherenceComplex.imag, avgcoherenceComplex.real)*180/numpy.pi
649 phase = numpy.arctan2(avgcoherenceComplex.imag, avgcoherenceComplex.real)*180/numpy.pi
646
650
647 if dataOut.beacon_heiIndexList:
651 if dataOut.beacon_heiIndexList:
648 phase_beacon[i] = numpy.average(phase[dataOut.beacon_heiIndexList])
652 phase_beacon[i] = numpy.average(phase[dataOut.beacon_heiIndexList])
649 else:
653 else:
650 phase_beacon[i] = numpy.average(phase)
654 phase_beacon[i] = numpy.average(phase)
651
655
652 if not self.isConfig:
656 if not self.isConfig:
653
657
654 nplots = len(pairsIndexList)
658 nplots = len(pairsIndexList)
655
659
656 self.setup(id=id,
660 self.setup(id=id,
657 nplots=nplots,
661 nplots=nplots,
658 wintitle=wintitle,
662 wintitle=wintitle,
659 showprofile=showprofile,
663 showprofile=showprofile,
660 show=show)
664 show=show)
661
665
662 if timerange != None:
666 if timerange != None:
663 self.timerange = timerange
667 self.timerange = timerange
664
668
665 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
669 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
666
670
667 if ymin == None: ymin = 0
671 if ymin == None: ymin = 0
668 if ymax == None: ymax = 360
672 if ymax == None: ymax = 360
669
673
670 self.FTP_WEI = ftp_wei
674 self.FTP_WEI = ftp_wei
671 self.EXP_CODE = exp_code
675 self.EXP_CODE = exp_code
672 self.SUB_EXP_CODE = sub_exp_code
676 self.SUB_EXP_CODE = sub_exp_code
673 self.PLOT_POS = plot_pos
677 self.PLOT_POS = plot_pos
674
678
675 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
679 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
676 self.isConfig = True
680 self.isConfig = True
677 self.figfile = figfile
681 self.figfile = figfile
678 self.xdata = numpy.array([])
682 self.xdata = numpy.array([])
679 self.ydata = numpy.array([])
683 self.ydata = numpy.array([])
680
684
681 update_figfile = True
685 update_figfile = True
682
686
683 #open file beacon phase
687 #open file beacon phase
684 path = '%s%03d' %(self.PREFIX, self.id)
688 path = '%s%03d' %(self.PREFIX, self.id)
685 beacon_file = os.path.join(path,'%s.txt'%self.name)
689 beacon_file = os.path.join(path,'%s.txt'%self.name)
686 self.filename_phase = os.path.join(figpath,beacon_file)
690 self.filename_phase = os.path.join(figpath,beacon_file)
687 #self.save_phase(self.filename_phase)
691 #self.save_phase(self.filename_phase)
688
692
689
693
690 #store data beacon phase
694 #store data beacon phase
691 #self.save_data(self.filename_phase, phase_beacon, thisDatetime)
695 #self.save_data(self.filename_phase, phase_beacon, thisDatetime)
692
696
693 self.setWinTitle(title)
697 self.setWinTitle(title)
694
698
695
699
696 title = "Phase Plot %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
700 title = "Phase Plot %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
697
701
698 legendlabels = ["Pair (%d,%d)"%(pair[0], pair[1]) for pair in dataOut.pairsList]
702 legendlabels = ["Pair (%d,%d)"%(pair[0], pair[1]) for pair in dataOut.pairsList]
699
703
700 axes = self.axesList[0]
704 axes = self.axesList[0]
701
705
702 self.xdata = numpy.hstack((self.xdata, x[0:1]))
706 self.xdata = numpy.hstack((self.xdata, x[0:1]))
703
707
704 if len(self.ydata)==0:
708 if len(self.ydata)==0:
705 self.ydata = phase_beacon.reshape(-1,1)
709 self.ydata = phase_beacon.reshape(-1,1)
706 else:
710 else:
707 self.ydata = numpy.hstack((self.ydata, phase_beacon.reshape(-1,1)))
711 self.ydata = numpy.hstack((self.ydata, phase_beacon.reshape(-1,1)))
708
712
709
713
710 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
714 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
711 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax,
715 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax,
712 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
716 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
713 XAxisAsTime=True, grid='both'
717 XAxisAsTime=True, grid='both'
714 )
718 )
715
719
716 self.draw()
720 self.draw()
717
721
718 if dataOut.ltctime >= self.xmax:
722 if dataOut.ltctime >= self.xmax:
719 self.counter_imagwr = wr_period
723 self.counter_imagwr = wr_period
720 self.isConfig = False
724 self.isConfig = False
721 update_figfile = True
725 update_figfile = True
722
726
723 self.save(figpath=figpath,
727 self.save(figpath=figpath,
724 figfile=figfile,
728 figfile=figfile,
725 save=save,
729 save=save,
726 ftp=ftp,
730 ftp=ftp,
727 wr_period=wr_period,
731 wr_period=wr_period,
728 thisDatetime=thisDatetime,
732 thisDatetime=thisDatetime,
729 update_figfile=update_figfile)
733 update_figfile=update_figfile)
730
734
731 return dataOut
735 return dataOut
@@ -1,1577 +1,1577
1 """
1 """
2 Created on Jul 2, 2014
2 Created on Jul 2, 2014
3
3
4 @author: roj-idl71
4 @author: roj-idl71
5 """
5 """
6 import os
6 import os
7 import sys
7 import sys
8 import glob
8 import glob
9 import time
9 import time
10 import numpy
10 import numpy
11 import fnmatch
11 import fnmatch
12 import inspect
12 import inspect
13 import time
13 import time
14 import datetime
14 import datetime
15 import zmq
15 import zmq
16
16
17 from schainpy.model.proc.jroproc_base import Operation, MPDecorator
17 from schainpy.model.proc.jroproc_base import Operation, MPDecorator
18 from schainpy.model.data.jroheaderIO import PROCFLAG, BasicHeader, SystemHeader, RadarControllerHeader, ProcessingHeader
18 from schainpy.model.data.jroheaderIO import PROCFLAG, BasicHeader, SystemHeader, RadarControllerHeader, ProcessingHeader
19 from schainpy.model.data.jroheaderIO import get_dtype_index, get_numpy_dtype, get_procflag_dtype, get_dtype_width
19 from schainpy.model.data.jroheaderIO import get_dtype_index, get_numpy_dtype, get_procflag_dtype, get_dtype_width
20 from schainpy.utils import log
20 from schainpy.utils import log
21 import schainpy.admin
21 import schainpy.admin
22
22
23 LOCALTIME = True
23 LOCALTIME = True
24 DT_DIRECTIVES = {
24 DT_DIRECTIVES = {
25 '%Y': 4,
25 '%Y': 4,
26 '%y': 2,
26 '%y': 2,
27 '%m': 2,
27 '%m': 2,
28 '%d': 2,
28 '%d': 2,
29 '%j': 3,
29 '%j': 3,
30 '%H': 2,
30 '%H': 2,
31 '%M': 2,
31 '%M': 2,
32 '%S': 2,
32 '%S': 2,
33 '%f': 6
33 '%f': 6
34 }
34 }
35
35
36
36
37 def isNumber(cad):
37 def isNumber(cad):
38 """
38 """
39 Chequea si el conjunto de caracteres que componen un string puede ser convertidos a un numero.
39 Chequea si el conjunto de caracteres que componen un string puede ser convertidos a un numero.
40
40
41 Excepciones:
41 Excepciones:
42 Si un determinado string no puede ser convertido a numero
42 Si un determinado string no puede ser convertido a numero
43 Input:
43 Input:
44 str, string al cual se le analiza para determinar si convertible a un numero o no
44 str, string al cual se le analiza para determinar si convertible a un numero o no
45
45
46 Return:
46 Return:
47 True : si el string es uno numerico
47 True : si el string es uno numerico
48 False : no es un string numerico
48 False : no es un string numerico
49 """
49 """
50 try:
50 try:
51 float(cad)
51 float(cad)
52 return True
52 return True
53 except:
53 except:
54 return False
54 return False
55
55
56
56
57 def isFileInEpoch(filename, startUTSeconds, endUTSeconds):
57 def isFileInEpoch(filename, startUTSeconds, endUTSeconds):
58 """
58 """
59 Esta funcion determina si un archivo de datos se encuentra o no dentro del rango de fecha especificado.
59 Esta funcion determina si un archivo de datos se encuentra o no dentro del rango de fecha especificado.
60
60
61 Inputs:
61 Inputs:
62 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
62 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
63
63
64 startUTSeconds : fecha inicial del rango seleccionado. La fecha esta dada en
64 startUTSeconds : fecha inicial del rango seleccionado. La fecha esta dada en
65 segundos contados desde 01/01/1970.
65 segundos contados desde 01/01/1970.
66 endUTSeconds : fecha final del rango seleccionado. La fecha esta dada en
66 endUTSeconds : fecha final del rango seleccionado. La fecha esta dada en
67 segundos contados desde 01/01/1970.
67 segundos contados desde 01/01/1970.
68
68
69 Return:
69 Return:
70 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
70 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
71 fecha especificado, de lo contrario retorna False.
71 fecha especificado, de lo contrario retorna False.
72
72
73 Excepciones:
73 Excepciones:
74 Si el archivo no existe o no puede ser abierto
74 Si el archivo no existe o no puede ser abierto
75 Si la cabecera no puede ser leida.
75 Si la cabecera no puede ser leida.
76
76
77 """
77 """
78 basicHeaderObj = BasicHeader(LOCALTIME)
78 basicHeaderObj = BasicHeader(LOCALTIME)
79
79
80 try:
80 try:
81 fp = open(filename, 'rb')
81 fp = open(filename, 'rb')
82 except IOError:
82 except IOError:
83 print("The file %s can't be opened" % (filename))
83 print("The file %s can't be opened" % (filename))
84 return 0
84 return 0
85
85
86 sts = basicHeaderObj.read(fp)
86 sts = basicHeaderObj.read(fp)
87 fp.close()
87 fp.close()
88
88
89 if not(sts):
89 if not(sts):
90 print("Skipping the file %s because it has not a valid header" % (filename))
90 print("Skipping the file %s because it has not a valid header" % (filename))
91 return 0
91 return 0
92
92
93 if not ((startUTSeconds <= basicHeaderObj.utc) and (endUTSeconds > basicHeaderObj.utc)):
93 if not ((startUTSeconds <= basicHeaderObj.utc) and (endUTSeconds > basicHeaderObj.utc)):
94 return 0
94 return 0
95
95
96 return 1
96 return 1
97
97
98
98
99 def isTimeInRange(thisTime, startTime, endTime):
99 def isTimeInRange(thisTime, startTime, endTime):
100 if endTime >= startTime:
100 if endTime >= startTime:
101 if (thisTime < startTime) or (thisTime > endTime):
101 if (thisTime < startTime) or (thisTime > endTime):
102 return 0
102 return 0
103 return 1
103 return 1
104 else:
104 else:
105 if (thisTime < startTime) and (thisTime > endTime):
105 if (thisTime < startTime) and (thisTime > endTime):
106 return 0
106 return 0
107 return 1
107 return 1
108
108
109
109
110 def isFileInTimeRange(filename, startDate, endDate, startTime, endTime):
110 def isFileInTimeRange(filename, startDate, endDate, startTime, endTime):
111 """
111 """
112 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
112 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
113
113
114 Inputs:
114 Inputs:
115 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
115 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
116
116
117 startDate : fecha inicial del rango seleccionado en formato datetime.date
117 startDate : fecha inicial del rango seleccionado en formato datetime.date
118
118
119 endDate : fecha final del rango seleccionado en formato datetime.date
119 endDate : fecha final del rango seleccionado en formato datetime.date
120
120
121 startTime : tiempo inicial del rango seleccionado en formato datetime.time
121 startTime : tiempo inicial del rango seleccionado en formato datetime.time
122
122
123 endTime : tiempo final del rango seleccionado en formato datetime.time
123 endTime : tiempo final del rango seleccionado en formato datetime.time
124
124
125 Return:
125 Return:
126 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
126 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
127 fecha especificado, de lo contrario retorna False.
127 fecha especificado, de lo contrario retorna False.
128
128
129 Excepciones:
129 Excepciones:
130 Si el archivo no existe o no puede ser abierto
130 Si el archivo no existe o no puede ser abierto
131 Si la cabecera no puede ser leida.
131 Si la cabecera no puede ser leida.
132
132
133 """
133 """
134
134
135 try:
135 try:
136 fp = open(filename, 'rb')
136 fp = open(filename, 'rb')
137 except IOError:
137 except IOError:
138 print("The file %s can't be opened" % (filename))
138 print("The file %s can't be opened" % (filename))
139 return None
139 return None
140
140
141 firstBasicHeaderObj = BasicHeader(LOCALTIME)
141 firstBasicHeaderObj = BasicHeader(LOCALTIME)
142 systemHeaderObj = SystemHeader()
142 systemHeaderObj = SystemHeader()
143 radarControllerHeaderObj = RadarControllerHeader()
143 radarControllerHeaderObj = RadarControllerHeader()
144 processingHeaderObj = ProcessingHeader()
144 processingHeaderObj = ProcessingHeader()
145
145
146 lastBasicHeaderObj = BasicHeader(LOCALTIME)
146 lastBasicHeaderObj = BasicHeader(LOCALTIME)
147
147
148 sts = firstBasicHeaderObj.read(fp)
148 sts = firstBasicHeaderObj.read(fp)
149
149
150 if not(sts):
150 if not(sts):
151 print("[Reading] Skipping the file %s because it has not a valid header" % (filename))
151 print("[Reading] Skipping the file %s because it has not a valid header" % (filename))
152 return None
152 return None
153
153
154 if not systemHeaderObj.read(fp):
154 if not systemHeaderObj.read(fp):
155 return None
155 return None
156
156
157 if not radarControllerHeaderObj.read(fp):
157 if not radarControllerHeaderObj.read(fp):
158 return None
158 return None
159
159
160 if not processingHeaderObj.read(fp):
160 if not processingHeaderObj.read(fp):
161 return None
161 return None
162
162
163 filesize = os.path.getsize(filename)
163 filesize = os.path.getsize(filename)
164
164
165 offset = processingHeaderObj.blockSize + 24 # header size
165 offset = processingHeaderObj.blockSize + 24 # header size
166
166
167 if filesize <= offset:
167 if filesize <= offset:
168 print("[Reading] %s: This file has not enough data" % filename)
168 print("[Reading] %s: This file has not enough data" % filename)
169 return None
169 return None
170
170
171 fp.seek(-offset, 2)
171 fp.seek(-offset, 2)
172
172
173 sts = lastBasicHeaderObj.read(fp)
173 sts = lastBasicHeaderObj.read(fp)
174
174
175 fp.close()
175 fp.close()
176
176
177 thisDatetime = lastBasicHeaderObj.datatime
177 thisDatetime = lastBasicHeaderObj.datatime
178 thisTime_last_block = thisDatetime.time()
178 thisTime_last_block = thisDatetime.time()
179
179
180 thisDatetime = firstBasicHeaderObj.datatime
180 thisDatetime = firstBasicHeaderObj.datatime
181 thisDate = thisDatetime.date()
181 thisDate = thisDatetime.date()
182 thisTime_first_block = thisDatetime.time()
182 thisTime_first_block = thisDatetime.time()
183
183
184 # General case
184 # General case
185 # o>>>>>>>>>>>>>><<<<<<<<<<<<<<o
185 # o>>>>>>>>>>>>>><<<<<<<<<<<<<<o
186 #-----------o----------------------------o-----------
186 #-----------o----------------------------o-----------
187 # startTime endTime
187 # startTime endTime
188
188
189 if endTime >= startTime:
189 if endTime >= startTime:
190 if (thisTime_last_block < startTime) or (thisTime_first_block > endTime):
190 if (thisTime_last_block < startTime) or (thisTime_first_block > endTime):
191 return None
191 return None
192
192
193 return thisDatetime
193 return thisDatetime
194
194
195 # If endTime < startTime then endTime belongs to the next day
195 # If endTime < startTime then endTime belongs to the next day
196
196
197 #<<<<<<<<<<<o o>>>>>>>>>>>
197 #<<<<<<<<<<<o o>>>>>>>>>>>
198 #-----------o----------------------------o-----------
198 #-----------o----------------------------o-----------
199 # endTime startTime
199 # endTime startTime
200
200
201 if (thisDate == startDate) and (thisTime_last_block < startTime):
201 if (thisDate == startDate) and (thisTime_last_block < startTime):
202 return None
202 return None
203
203
204 if (thisDate == endDate) and (thisTime_first_block > endTime):
204 if (thisDate == endDate) and (thisTime_first_block > endTime):
205 return None
205 return None
206
206
207 if (thisTime_last_block < startTime) and (thisTime_first_block > endTime):
207 if (thisTime_last_block < startTime) and (thisTime_first_block > endTime):
208 return None
208 return None
209
209
210 return thisDatetime
210 return thisDatetime
211
211
212
212
213 def isFolderInDateRange(folder, startDate=None, endDate=None):
213 def isFolderInDateRange(folder, startDate=None, endDate=None):
214 """
214 """
215 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
215 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
216
216
217 Inputs:
217 Inputs:
218 folder : nombre completo del directorio.
218 folder : nombre completo del directorio.
219 Su formato deberia ser "/path_root/?YYYYDDD"
219 Su formato deberia ser "/path_root/?YYYYDDD"
220
220
221 siendo:
221 siendo:
222 YYYY : Anio (ejemplo 2015)
222 YYYY : Anio (ejemplo 2015)
223 DDD : Dia del anio (ejemplo 305)
223 DDD : Dia del anio (ejemplo 305)
224
224
225 startDate : fecha inicial del rango seleccionado en formato datetime.date
225 startDate : fecha inicial del rango seleccionado en formato datetime.date
226
226
227 endDate : fecha final del rango seleccionado en formato datetime.date
227 endDate : fecha final del rango seleccionado en formato datetime.date
228
228
229 Return:
229 Return:
230 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
230 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
231 fecha especificado, de lo contrario retorna False.
231 fecha especificado, de lo contrario retorna False.
232 Excepciones:
232 Excepciones:
233 Si el directorio no tiene el formato adecuado
233 Si el directorio no tiene el formato adecuado
234 """
234 """
235
235
236 basename = os.path.basename(folder)
236 basename = os.path.basename(folder)
237
237
238 if not isRadarFolder(basename):
238 if not isRadarFolder(basename):
239 print("The folder %s has not the rigth format" % folder)
239 print("The folder %s has not the rigth format" % folder)
240 return 0
240 return 0
241
241
242 if startDate and endDate:
242 if startDate and endDate:
243 thisDate = getDateFromRadarFolder(basename)
243 thisDate = getDateFromRadarFolder(basename)
244
244
245 if thisDate < startDate:
245 if thisDate < startDate:
246 return 0
246 return 0
247
247
248 if thisDate > endDate:
248 if thisDate > endDate:
249 return 0
249 return 0
250
250
251 return 1
251 return 1
252
252
253
253
254 def isFileInDateRange(filename, startDate=None, endDate=None):
254 def isFileInDateRange(filename, startDate=None, endDate=None):
255 """
255 """
256 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
256 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
257
257
258 Inputs:
258 Inputs:
259 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
259 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
260
260
261 Su formato deberia ser "?YYYYDDDsss"
261 Su formato deberia ser "?YYYYDDDsss"
262
262
263 siendo:
263 siendo:
264 YYYY : Anio (ejemplo 2015)
264 YYYY : Anio (ejemplo 2015)
265 DDD : Dia del anio (ejemplo 305)
265 DDD : Dia del anio (ejemplo 305)
266 sss : set
266 sss : set
267
267
268 startDate : fecha inicial del rango seleccionado en formato datetime.date
268 startDate : fecha inicial del rango seleccionado en formato datetime.date
269
269
270 endDate : fecha final del rango seleccionado en formato datetime.date
270 endDate : fecha final del rango seleccionado en formato datetime.date
271
271
272 Return:
272 Return:
273 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
273 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
274 fecha especificado, de lo contrario retorna False.
274 fecha especificado, de lo contrario retorna False.
275 Excepciones:
275 Excepciones:
276 Si el archivo no tiene el formato adecuado
276 Si el archivo no tiene el formato adecuado
277 """
277 """
278
278
279 basename = os.path.basename(filename)
279 basename = os.path.basename(filename)
280
280
281 if not isRadarFile(basename):
281 if not isRadarFile(basename):
282 print("The filename %s has not the rigth format" % filename)
282 print("The filename %s has not the rigth format" % filename)
283 return 0
283 return 0
284
284
285 if startDate and endDate:
285 if startDate and endDate:
286 thisDate = getDateFromRadarFile(basename)
286 thisDate = getDateFromRadarFile(basename)
287
287
288 if thisDate < startDate:
288 if thisDate < startDate:
289 return 0
289 return 0
290
290
291 if thisDate > endDate:
291 if thisDate > endDate:
292 return 0
292 return 0
293
293
294 return 1
294 return 1
295
295
296
296
297 def getFileFromSet(path, ext, set):
297 def getFileFromSet(path, ext, set):
298 validFilelist = []
298 validFilelist = []
299 fileList = os.listdir(path)
299 fileList = os.listdir(path)
300
300
301 # 0 1234 567 89A BCDE
301 # 0 1234 567 89A BCDE
302 # H YYYY DDD SSS .ext
302 # H YYYY DDD SSS .ext
303
303
304 for thisFile in fileList:
304 for thisFile in fileList:
305 try:
305 try:
306 year = int(thisFile[1:5])
306 year = int(thisFile[1:5])
307 doy = int(thisFile[5:8])
307 doy = int(thisFile[5:8])
308 except:
308 except:
309 continue
309 continue
310
310
311 if (os.path.splitext(thisFile)[-1].lower() != ext.lower()):
311 if (os.path.splitext(thisFile)[-1].lower() != ext.lower()):
312 continue
312 continue
313
313
314 validFilelist.append(thisFile)
314 validFilelist.append(thisFile)
315
315
316 myfile = fnmatch.filter(
316 myfile = fnmatch.filter(
317 validFilelist, '*%4.4d%3.3d%3.3d*' % (year, doy, set))
317 validFilelist, '*%4.4d%3.3d%3.3d*' % (year, doy, set))
318
318
319 if len(myfile) != 0:
319 if len(myfile) != 0:
320 return myfile[0]
320 return myfile[0]
321 else:
321 else:
322 filename = '*%4.4d%3.3d%3.3d%s' % (year, doy, set, ext.lower())
322 filename = '*%4.4d%3.3d%3.3d%s' % (year, doy, set, ext.lower())
323 print('the filename %s does not exist' % filename)
323 print('the filename %s does not exist' % filename)
324 print('...going to the last file: ')
324 print('...going to the last file: ')
325
325
326 if validFilelist:
326 if validFilelist:
327 validFilelist = sorted(validFilelist, key=str.lower)
327 validFilelist = sorted(validFilelist, key=str.lower)
328 return validFilelist[-1]
328 return validFilelist[-1]
329
329
330 return None
330 return None
331
331
332
332
333 def getlastFileFromPath(path, ext):
333 def getlastFileFromPath(path, ext):
334 """
334 """
335 Depura el fileList dejando solo los que cumplan el formato de "PYYYYDDDSSS.ext"
335 Depura el fileList dejando solo los que cumplan el formato de "PYYYYDDDSSS.ext"
336 al final de la depuracion devuelve el ultimo file de la lista que quedo.
336 al final de la depuracion devuelve el ultimo file de la lista que quedo.
337
337
338 Input:
338 Input:
339 fileList : lista conteniendo todos los files (sin path) que componen una determinada carpeta
339 fileList : lista conteniendo todos los files (sin path) que componen una determinada carpeta
340 ext : extension de los files contenidos en una carpeta
340 ext : extension de los files contenidos en una carpeta
341
341
342 Return:
342 Return:
343 El ultimo file de una determinada carpeta, no se considera el path.
343 El ultimo file de una determinada carpeta, no se considera el path.
344 """
344 """
345 validFilelist = []
345 validFilelist = []
346 fileList = os.listdir(path)
346 fileList = os.listdir(path)
347
347
348 # 0 1234 567 89A BCDE
348 # 0 1234 567 89A BCDE
349 # H YYYY DDD SSS .ext
349 # H YYYY DDD SSS .ext
350
350
351 for thisFile in fileList:
351 for thisFile in fileList:
352
352
353 year = thisFile[1:5]
353 year = thisFile[1:5]
354 if not isNumber(year):
354 if not isNumber(year):
355 continue
355 continue
356
356
357 doy = thisFile[5:8]
357 doy = thisFile[5:8]
358 if not isNumber(doy):
358 if not isNumber(doy):
359 continue
359 continue
360
360
361 year = int(year)
361 year = int(year)
362 doy = int(doy)
362 doy = int(doy)
363
363
364 if (os.path.splitext(thisFile)[-1].lower() != ext.lower()):
364 if (os.path.splitext(thisFile)[-1].lower() != ext.lower()):
365 continue
365 continue
366
366
367 validFilelist.append(thisFile)
367 validFilelist.append(thisFile)
368
368
369 if validFilelist:
369 if validFilelist:
370 validFilelist = sorted(validFilelist, key=str.lower)
370 validFilelist = sorted(validFilelist, key=str.lower)
371 return validFilelist[-1]
371 return validFilelist[-1]
372
372
373 return None
373 return None
374
374
375
375
376 def isRadarFolder(folder):
376 def isRadarFolder(folder):
377 try:
377 try:
378 year = int(folder[1:5])
378 year = int(folder[1:5])
379 doy = int(folder[5:8])
379 doy = int(folder[5:8])
380 except:
380 except:
381 return 0
381 return 0
382
382
383 return 1
383 return 1
384
384
385
385
386 def isRadarFile(file):
386 def isRadarFile(file):
387 try:
387 try:
388 year = int(file[1:5])
388 year = int(file[1:5])
389 doy = int(file[5:8])
389 doy = int(file[5:8])
390 set = int(file[8:11])
390 set = int(file[8:11])
391 except:
391 except:
392 return 0
392 return 0
393
393
394 return 1
394 return 1
395
395
396
396
397 def getDateFromRadarFile(file):
397 def getDateFromRadarFile(file):
398 try:
398 try:
399 year = int(file[1:5])
399 year = int(file[1:5])
400 doy = int(file[5:8])
400 doy = int(file[5:8])
401 set = int(file[8:11])
401 set = int(file[8:11])
402 except:
402 except:
403 return None
403 return None
404
404
405 thisDate = datetime.date(year, 1, 1) + datetime.timedelta(doy - 1)
405 thisDate = datetime.date(year, 1, 1) + datetime.timedelta(doy - 1)
406 return thisDate
406 return thisDate
407
407
408
408
409 def getDateFromRadarFolder(folder):
409 def getDateFromRadarFolder(folder):
410 try:
410 try:
411 year = int(folder[1:5])
411 year = int(folder[1:5])
412 doy = int(folder[5:8])
412 doy = int(folder[5:8])
413 except:
413 except:
414 return None
414 return None
415
415
416 thisDate = datetime.date(year, 1, 1) + datetime.timedelta(doy - 1)
416 thisDate = datetime.date(year, 1, 1) + datetime.timedelta(doy - 1)
417 return thisDate
417 return thisDate
418
418
419 def parse_format(s, fmt):
419 def parse_format(s, fmt):
420
420
421 for i in range(fmt.count('%')):
421 for i in range(fmt.count('%')):
422 x = fmt.index('%')
422 x = fmt.index('%')
423 d = DT_DIRECTIVES[fmt[x:x+2]]
423 d = DT_DIRECTIVES[fmt[x:x+2]]
424 fmt = fmt.replace(fmt[x:x+2], s[x:x+d])
424 fmt = fmt.replace(fmt[x:x+2], s[x:x+d])
425 return fmt
425 return fmt
426
426
427 class Reader(object):
427 class Reader(object):
428
428
429 c = 3E8
429 c = 3E8
430 isConfig = False
430 isConfig = False
431 dtype = None
431 dtype = None
432 pathList = []
432 pathList = []
433 filenameList = []
433 filenameList = []
434 datetimeList = []
434 datetimeList = []
435 filename = None
435 filename = None
436 ext = None
436 ext = None
437 flagIsNewFile = 1
437 flagIsNewFile = 1
438 flagDiscontinuousBlock = 0
438 flagDiscontinuousBlock = 0
439 flagIsNewBlock = 0
439 flagIsNewBlock = 0
440 flagNoMoreFiles = 0
440 flagNoMoreFiles = 0
441 fp = None
441 fp = None
442 firstHeaderSize = 0
442 firstHeaderSize = 0
443 basicHeaderSize = 24
443 basicHeaderSize = 24
444 versionFile = 1103
444 versionFile = 1103
445 fileSize = None
445 fileSize = None
446 fileSizeByHeader = None
446 fileSizeByHeader = None
447 fileIndex = -1
447 fileIndex = -1
448 profileIndex = None
448 profileIndex = None
449 blockIndex = 0
449 blockIndex = 0
450 nTotalBlocks = 0
450 nTotalBlocks = 0
451 maxTimeStep = 30
451 maxTimeStep = 30
452 lastUTTime = None
452 lastUTTime = None
453 datablock = None
453 datablock = None
454 dataOut = None
454 dataOut = None
455 getByBlock = False
455 getByBlock = False
456 path = None
456 path = None
457 startDate = None
457 startDate = None
458 endDate = None
458 endDate = None
459 startTime = datetime.time(0, 0, 0)
459 startTime = datetime.time(0, 0, 0)
460 endTime = datetime.time(23, 59, 59)
460 endTime = datetime.time(23, 59, 59)
461 set = None
461 set = None
462 expLabel = ""
462 expLabel = ""
463 online = False
463 online = False
464 delay = 60
464 delay = 60
465 nTries = 3 # quantity tries
465 nTries = 3 # quantity tries
466 nFiles = 3 # number of files for searching
466 nFiles = 3 # number of files for searching
467 walk = True
467 walk = True
468 getblock = False
468 getblock = False
469 nTxs = 1
469 nTxs = 1
470 realtime = False
470 realtime = False
471 blocksize = 0
471 blocksize = 0
472 blocktime = None
472 blocktime = None
473 warnings = True
473 warnings = True
474 verbose = True
474 verbose = True
475 server = None
475 server = None
476 format = None
476 format = None
477 oneDDict = None
477 oneDDict = None
478 twoDDict = None
478 twoDDict = None
479 independentParam = None
479 independentParam = None
480 filefmt = None
480 filefmt = None
481 folderfmt = None
481 folderfmt = None
482 open_file = open
482 open_file = open
483 open_mode = 'rb'
483 open_mode = 'rb'
484
484
485 def run(self):
485 def run(self):
486
486
487 raise NotImplementedError
487 raise NotImplementedError
488
488
489 def getAllowedArgs(self):
489 def getAllowedArgs(self):
490 if hasattr(self, '__attrs__'):
490 if hasattr(self, '__attrs__'):
491 return self.__attrs__
491 return self.__attrs__
492 else:
492 else:
493 return inspect.getargspec(self.run).args
493 return inspect.getargspec(self.run).args
494
494
495 def set_kwargs(self, **kwargs):
495 def set_kwargs(self, **kwargs):
496
496
497 for key, value in kwargs.items():
497 for key, value in kwargs.items():
498 setattr(self, key, value)
498 setattr(self, key, value)
499
499
500 def find_folders(self, path, startDate, endDate, folderfmt, last=False):
500 def find_folders(self, path, startDate, endDate, folderfmt, last=False):
501
501
502 folders = [x for f in path.split(',')
502 folders = [x for f in path.split(',')
503 for x in os.listdir(f) if os.path.isdir(os.path.join(f, x))]
503 for x in os.listdir(f) if os.path.isdir(os.path.join(f, x))]
504 folders.sort()
504 folders.sort()
505
505
506 if last:
506 if last:
507 folders = [folders[-1]]
507 folders = [folders[-1]]
508
508
509 for folder in folders:
509 for folder in folders:
510 try:
510 try:
511 dt = datetime.datetime.strptime(parse_format(folder, folderfmt), folderfmt).date()
511 dt = datetime.datetime.strptime(parse_format(folder, folderfmt), folderfmt).date()
512 if dt >= startDate and dt <= endDate:
512 if dt >= startDate and dt <= endDate:
513 yield os.path.join(path, folder)
513 yield os.path.join(path, folder)
514 else:
514 else:
515 log.log('Skiping folder {}'.format(folder), self.name)
515 log.log('Skiping folder {}'.format(folder), self.name)
516 except Exception as e:
516 except Exception as e:
517 log.log('Skiping folder {}'.format(folder), self.name)
517 log.log('Skiping folder {}'.format(folder), self.name)
518 continue
518 continue
519 return
519 return
520
520
521 def find_files(self, folders, ext, filefmt, startDate=None, endDate=None,
521 def find_files(self, folders, ext, filefmt, startDate=None, endDate=None,
522 expLabel='', last=False):
522 expLabel='', last=False):
523
523
524 for path in folders:
524 for path in folders:
525 files = glob.glob1(path, '*{}'.format(ext))
525 files = glob.glob1(path, '*{}'.format(ext))
526 files.sort()
526 files.sort()
527 if last:
527 if last:
528 if files:
528 if files:
529 fo = files[-1]
529 fo = files[-1]
530 try:
530 try:
531 dt = datetime.datetime.strptime(parse_format(fo, filefmt), filefmt).date()
531 dt = datetime.datetime.strptime(parse_format(fo, filefmt), filefmt).date()
532 yield os.path.join(path, expLabel, fo)
532 yield os.path.join(path, expLabel, fo)
533 except Exception as e:
533 except Exception as e:
534 pass
534 pass
535 return
535 return
536 else:
536 else:
537 return
537 return
538
538
539 for fo in files:
539 for fo in files:
540 try:
540 try:
541 dt = datetime.datetime.strptime(parse_format(fo, filefmt), filefmt).date()
541 dt = datetime.datetime.strptime(parse_format(fo, filefmt), filefmt).date()
542 if dt >= startDate and dt <= endDate:
542 if dt >= startDate and dt <= endDate:
543 yield os.path.join(path, expLabel, fo)
543 yield os.path.join(path, expLabel, fo)
544 else:
544 else:
545 log.log('Skiping file {}'.format(fo), self.name)
545 log.log('Skiping file {}'.format(fo), self.name)
546 except Exception as e:
546 except Exception as e:
547 log.log('Skiping file {}'.format(fo), self.name)
547 log.log('Skiping file {}'.format(fo), self.name)
548 continue
548 continue
549
549
550 def searchFilesOffLine(self, path, startDate, endDate,
550 def searchFilesOffLine(self, path, startDate, endDate,
551 expLabel, ext, walk,
551 expLabel, ext, walk,
552 filefmt, folderfmt):
552 filefmt, folderfmt):
553 """Search files in offline mode for the given arguments
553 """Search files in offline mode for the given arguments
554
554
555 Return:
555 Return:
556 Generator of files
556 Generator of files
557 """
557 """
558
558
559 if walk:
559 if walk:
560 folders = self.find_folders(
560 folders = self.find_folders(
561 path, startDate, endDate, folderfmt)
561 path, startDate, endDate, folderfmt)
562 else:
562 else:
563 folders = path.split(',')
563 folders = path.split(',')
564
564
565 return self.find_files(
565 return self.find_files(
566 folders, ext, filefmt, startDate, endDate, expLabel)
566 folders, ext, filefmt, startDate, endDate, expLabel)
567
567
568 def searchFilesOnLine(self, path, startDate, endDate,
568 def searchFilesOnLine(self, path, startDate, endDate,
569 expLabel, ext, walk,
569 expLabel, ext, walk,
570 filefmt, folderfmt):
570 filefmt, folderfmt):
571 """Search for the last file of the last folder
571 """Search for the last file of the last folder
572
572
573 Arguments:
573 Arguments:
574 path : carpeta donde estan contenidos los files que contiene data
574 path : carpeta donde estan contenidos los files que contiene data
575 expLabel : Nombre del subexperimento (subfolder)
575 expLabel : Nombre del subexperimento (subfolder)
576 ext : extension de los files
576 ext : extension de los files
577 walk : Si es habilitado no realiza busquedas dentro de los ubdirectorios (doypath)
577 walk : Si es habilitado no realiza busquedas dentro de los ubdirectorios (doypath)
578
578
579 Return:
579 Return:
580 generator with the full path of last filename
580 generator with the full path of last filename
581 """
581 """
582
582
583 if walk:
583 if walk:
584 folders = self.find_folders(
584 folders = self.find_folders(
585 path, startDate, endDate, folderfmt, last=True)
585 path, startDate, endDate, folderfmt, last=True)
586 else:
586 else:
587 folders = path.split(',')
587 folders = path.split(',')
588
588
589 return self.find_files(
589 return self.find_files(
590 folders, ext, filefmt, startDate, endDate, expLabel, last=True)
590 folders, ext, filefmt, startDate, endDate, expLabel, last=True)
591
591
592 def setNextFile(self):
592 def setNextFile(self):
593 """Set the next file to be readed open it and parse de file header"""
593 """Set the next file to be readed open it and parse de file header"""
594
594
595 while True:
595 while True:
596 if self.fp != None:
596 if self.fp != None:
597 self.fp.close()
597 self.fp.close()
598
598
599 if self.online:
599 if self.online:
600 newFile = self.setNextFileOnline()
600 newFile = self.setNextFileOnline()
601 else:
601 else:
602 newFile = self.setNextFileOffline()
602 newFile = self.setNextFileOffline()
603
603
604 if not(newFile):
604 if not(newFile):
605 if self.online:
605 if self.online:
606 raise schainpy.admin.SchainError('Time to wait for new files reach')
606 raise schainpy.admin.SchainError('Time to wait for new files reach')
607 else:
607 else:
608 if self.fileIndex == -1:
608 if self.fileIndex == -1:
609 raise schainpy.admin.SchainWarning('No files found in the given path')
609 raise schainpy.admin.SchainWarning('No files found in the given path')
610 else:
610 else:
611 raise schainpy.admin.SchainWarning('No more files to read')
611 raise schainpy.admin.SchainWarning('No more files to read')
612
612
613 if self.verifyFile(self.filename):
613 if self.verifyFile(self.filename):
614 break
614 break
615
615
616 log.log('Opening file: %s' % self.filename, self.name)
616 log.log('Opening file: %s' % self.filename, self.name)
617
617
618 self.readFirstHeader()
618 self.readFirstHeader()
619 self.nReadBlocks = 0
619 self.nReadBlocks = 0
620
620
621 def setNextFileOnline(self):
621 def setNextFileOnline(self):
622 """Check for the next file to be readed in online mode.
622 """Check for the next file to be readed in online mode.
623
623
624 Set:
624 Set:
625 self.filename
625 self.filename
626 self.fp
626 self.fp
627 self.filesize
627 self.filesize
628
628
629 Return:
629 Return:
630 boolean
630 boolean
631
631
632 """
632 """
633 nextFile = True
633 nextFile = True
634 nextDay = False
634 nextDay = False
635
635
636 for nFiles in range(self.nFiles+1):
636 for nFiles in range(self.nFiles+1):
637 for nTries in range(self.nTries):
637 for nTries in range(self.nTries):
638 fullfilename, filename = self.checkForRealPath(nextFile, nextDay)
638 fullfilename, filename = self.checkForRealPath(nextFile, nextDay)
639 if fullfilename is not None:
639 if fullfilename is not None:
640 break
640 break
641 log.warning(
641 log.warning(
642 "Waiting %0.2f sec for the next file: \"%s\" , try %02d ..." % (self.delay, filename, nTries + 1),
642 "Waiting %0.2f sec for the next file: \"%s\" , try %02d ..." % (self.delay, filename, nTries + 1),
643 self.name)
643 self.name)
644 time.sleep(self.delay)
644 time.sleep(self.delay)
645 nextFile = False
645 nextFile = False
646 continue
646 continue
647
647
648 if fullfilename is not None:
648 if fullfilename is not None:
649 break
649 break
650
650
651 self.nTries = 1
651 self.nTries = 1
652 nextFile = True
652 nextFile = True
653
653
654 if nFiles == (self.nFiles - 1):
654 if nFiles == (self.nFiles - 1):
655 log.log('Trying with next day...', self.name)
655 log.log('Trying with next day...', self.name)
656 nextDay = True
656 nextDay = True
657 self.nTries = 3
657 self.nTries = 3
658
658
659 if fullfilename:
659 if fullfilename:
660 self.fileSize = os.path.getsize(fullfilename)
660 self.fileSize = os.path.getsize(fullfilename)
661 self.filename = fullfilename
661 self.filename = fullfilename
662 self.flagIsNewFile = 1
662 self.flagIsNewFile = 1
663 if self.fp != None:
663 if self.fp != None:
664 self.fp.close()
664 self.fp.close()
665 self.fp = self.open_file(fullfilename, self.open_mode)
665 self.fp = self.open_file(fullfilename, self.open_mode)
666 self.flagNoMoreFiles = 0
666 self.flagNoMoreFiles = 0
667 self.fileIndex += 1
667 self.fileIndex += 1
668 return 1
668 return 1
669 else:
669 else:
670 return 0
670 return 0
671
671
672 def setNextFileOffline(self):
672 def setNextFileOffline(self):
673 """Open the next file to be readed in offline mode"""
673 """Open the next file to be readed in offline mode"""
674
674
675 try:
675 try:
676 filename = next(self.filenameList)
676 filename = next(self.filenameList)
677 self.fileIndex +=1
677 self.fileIndex +=1
678 except StopIteration:
678 except StopIteration:
679 self.flagNoMoreFiles = 1
679 self.flagNoMoreFiles = 1
680 return 0
680 return 0
681
681
682 self.filename = filename
682 self.filename = filename
683 self.fileSize = os.path.getsize(filename)
683 self.fileSize = os.path.getsize(filename)
684 self.fp = self.open_file(filename, self.open_mode)
684 self.fp = self.open_file(filename, self.open_mode)
685 self.flagIsNewFile = 1
685 self.flagIsNewFile = 1
686
686
687 return 1
687 return 1
688
688
689 @staticmethod
689 @staticmethod
690 def isDateTimeInRange(dt, startDate, endDate, startTime, endTime):
690 def isDateTimeInRange(dt, startDate, endDate, startTime, endTime):
691 """Check if the given datetime is in range"""
691 """Check if the given datetime is in range"""
692 startDateTime= datetime.datetime.combine(startDate,startTime)
692 startDateTime= datetime.datetime.combine(startDate,startTime)
693 endDateTime = datetime.datetime.combine(endDate,endTime)
693 endDateTime = datetime.datetime.combine(endDate,endTime)
694 #print("dt eval: ", dt, startDateTime,endDateTime)
694
695 if startDateTime <= dt <= endDateTime:
695 if startDateTime <= dt <= endDateTime:
696 return True
696 return True
697 return False
697 return False
698
698
699 def verifyFile(self, filename):
699 def verifyFile(self, filename):
700 """Check for a valid file
700 """Check for a valid file
701
701
702 Arguments:
702 Arguments:
703 filename -- full path filename
703 filename -- full path filename
704
704
705 Return:
705 Return:
706 boolean
706 boolean
707 """
707 """
708
708
709 return True
709 return True
710
710
711 def checkForRealPath(self, nextFile, nextDay):
711 def checkForRealPath(self, nextFile, nextDay):
712 """Check if the next file to be readed exists"""
712 """Check if the next file to be readed exists"""
713
713
714 raise NotImplementedError
714 raise NotImplementedError
715
715
716 def readFirstHeader(self):
716 def readFirstHeader(self):
717 """Parse the file header"""
717 """Parse the file header"""
718
718
719 pass
719 pass
720
720
721 def waitDataBlock(self, pointer_location, blocksize=None):
721 def waitDataBlock(self, pointer_location, blocksize=None):
722 """
722 """
723 """
723 """
724
724
725 currentPointer = pointer_location
725 currentPointer = pointer_location
726 if blocksize is None:
726 if blocksize is None:
727 neededSize = self.processingHeaderObj.blockSize # + self.basicHeaderSize
727 neededSize = self.processingHeaderObj.blockSize # + self.basicHeaderSize
728 else:
728 else:
729 neededSize = blocksize
729 neededSize = blocksize
730
730
731 for nTries in range(self.nTries):
731 for nTries in range(self.nTries):
732 self.fp.close()
732 self.fp.close()
733 self.fp = open(self.filename, 'rb')
733 self.fp = open(self.filename, 'rb')
734 self.fp.seek(currentPointer)
734 self.fp.seek(currentPointer)
735
735
736 self.fileSize = os.path.getsize(self.filename)
736 self.fileSize = os.path.getsize(self.filename)
737 currentSize = self.fileSize - currentPointer
737 currentSize = self.fileSize - currentPointer
738
738
739 if (currentSize >= neededSize):
739 if (currentSize >= neededSize):
740 return 1
740 return 1
741
741
742 log.warning(
742 log.warning(
743 "Waiting %0.2f seconds for the next block, try %03d ..." % (self.delay, nTries + 1),
743 "Waiting %0.2f seconds for the next block, try %03d ..." % (self.delay, nTries + 1),
744 self.name
744 self.name
745 )
745 )
746 time.sleep(self.delay)
746 time.sleep(self.delay)
747
747
748 return 0
748 return 0
749
749
750 class JRODataReader(Reader):
750 class JRODataReader(Reader):
751
751
752 utc = 0
752 utc = 0
753 nReadBlocks = 0
753 nReadBlocks = 0
754 foldercounter = 0
754 foldercounter = 0
755 firstHeaderSize = 0
755 firstHeaderSize = 0
756 basicHeaderSize = 24
756 basicHeaderSize = 24
757 __isFirstTimeOnline = 1
757 __isFirstTimeOnline = 1
758 filefmt = "*%Y%j***"
758 filefmt = "*%Y%j***"
759 folderfmt = "*%Y%j"
759 folderfmt = "*%Y%j"
760 __attrs__ = ['path', 'startDate', 'endDate', 'startTime', 'endTime', 'online', 'delay', 'walk']
760 __attrs__ = ['path', 'startDate', 'endDate', 'startTime', 'endTime', 'online', 'delay', 'walk']
761
761
762 def getDtypeWidth(self):
762 def getDtypeWidth(self):
763
763
764 dtype_index = get_dtype_index(self.dtype)
764 dtype_index = get_dtype_index(self.dtype)
765 dtype_width = get_dtype_width(dtype_index)
765 dtype_width = get_dtype_width(dtype_index)
766
766
767 return dtype_width
767 return dtype_width
768
768
769 def checkForRealPath(self, nextFile, nextDay):
769 def checkForRealPath(self, nextFile, nextDay):
770 """Check if the next file to be readed exists.
770 """Check if the next file to be readed exists.
771
771
772 Example :
772 Example :
773 nombre correcto del file es .../.../D2009307/P2009307367.ext
773 nombre correcto del file es .../.../D2009307/P2009307367.ext
774
774
775 Entonces la funcion prueba con las siguientes combinaciones
775 Entonces la funcion prueba con las siguientes combinaciones
776 .../.../y2009307367.ext
776 .../.../y2009307367.ext
777 .../.../Y2009307367.ext
777 .../.../Y2009307367.ext
778 .../.../x2009307/y2009307367.ext
778 .../.../x2009307/y2009307367.ext
779 .../.../x2009307/Y2009307367.ext
779 .../.../x2009307/Y2009307367.ext
780 .../.../X2009307/y2009307367.ext
780 .../.../X2009307/y2009307367.ext
781 .../.../X2009307/Y2009307367.ext
781 .../.../X2009307/Y2009307367.ext
782 siendo para este caso, la ultima combinacion de letras, identica al file buscado
782 siendo para este caso, la ultima combinacion de letras, identica al file buscado
783
783
784 Return:
784 Return:
785 str -- fullpath of the file
785 str -- fullpath of the file
786 """
786 """
787
787
788
788
789 if nextFile:
789 if nextFile:
790 self.set += 1
790 self.set += 1
791 if nextDay:
791 if nextDay:
792 self.set = 0
792 self.set = 0
793 self.doy += 1
793 self.doy += 1
794 foldercounter = 0
794 foldercounter = 0
795 prefixDirList = [None, 'd', 'D']
795 prefixDirList = [None, 'd', 'D']
796 if self.ext.lower() == ".r": # voltage
796 if self.ext.lower() == ".r": # voltage
797 prefixFileList = ['d', 'D']
797 prefixFileList = ['d', 'D']
798 elif self.ext.lower() == ".pdata": # spectra
798 elif self.ext.lower() == ".pdata": # spectra
799 prefixFileList = ['p', 'P']
799 prefixFileList = ['p', 'P']
800
800
801 # barrido por las combinaciones posibles
801 # barrido por las combinaciones posibles
802 for prefixDir in prefixDirList:
802 for prefixDir in prefixDirList:
803 thispath = self.path
803 thispath = self.path
804 if prefixDir != None:
804 if prefixDir != None:
805 # formo el nombre del directorio xYYYYDDD (x=d o x=D)
805 # formo el nombre del directorio xYYYYDDD (x=d o x=D)
806 if foldercounter == 0:
806 if foldercounter == 0:
807 thispath = os.path.join(self.path, "%s%04d%03d" %
807 thispath = os.path.join(self.path, "%s%04d%03d" %
808 (prefixDir, self.year, self.doy))
808 (prefixDir, self.year, self.doy))
809 else:
809 else:
810 thispath = os.path.join(self.path, "%s%04d%03d_%02d" % (
810 thispath = os.path.join(self.path, "%s%04d%03d_%02d" % (
811 prefixDir, self.year, self.doy, foldercounter))
811 prefixDir, self.year, self.doy, foldercounter))
812 for prefixFile in prefixFileList: # barrido por las dos combinaciones posibles de "D"
812 for prefixFile in prefixFileList: # barrido por las dos combinaciones posibles de "D"
813 # formo el nombre del file xYYYYDDDSSS.ext
813 # formo el nombre del file xYYYYDDDSSS.ext
814 filename = "%s%04d%03d%03d%s" % (prefixFile, self.year, self.doy, self.set, self.ext)
814 filename = "%s%04d%03d%03d%s" % (prefixFile, self.year, self.doy, self.set, self.ext)
815 fullfilename = os.path.join(
815 fullfilename = os.path.join(
816 thispath, filename)
816 thispath, filename)
817
817
818 if os.path.exists(fullfilename):
818 if os.path.exists(fullfilename):
819 return fullfilename, filename
819 return fullfilename, filename
820
820
821 return None, filename
821 return None, filename
822
822
823 def __waitNewBlock(self):
823 def __waitNewBlock(self):
824 """
824 """
825 Return 1 si se encontro un nuevo bloque de datos, 0 de otra forma.
825 Return 1 si se encontro un nuevo bloque de datos, 0 de otra forma.
826
826
827 Si el modo de lectura es OffLine siempre retorn 0
827 Si el modo de lectura es OffLine siempre retorn 0
828 """
828 """
829 if not self.online:
829 if not self.online:
830 return 0
830 return 0
831
831
832 if (self.nReadBlocks >= self.processingHeaderObj.dataBlocksPerFile):
832 if (self.nReadBlocks >= self.processingHeaderObj.dataBlocksPerFile):
833 return 0
833 return 0
834
834
835 currentPointer = self.fp.tell()
835 currentPointer = self.fp.tell()
836
836
837 neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize
837 neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize
838
838
839 for nTries in range(self.nTries):
839 for nTries in range(self.nTries):
840
840
841 self.fp.close()
841 self.fp.close()
842 self.fp = open(self.filename, 'rb')
842 self.fp = open(self.filename, 'rb')
843 self.fp.seek(currentPointer)
843 self.fp.seek(currentPointer)
844
844
845 self.fileSize = os.path.getsize(self.filename)
845 self.fileSize = os.path.getsize(self.filename)
846 currentSize = self.fileSize - currentPointer
846 currentSize = self.fileSize - currentPointer
847
847
848 if (currentSize >= neededSize):
848 if (currentSize >= neededSize):
849 self.basicHeaderObj.read(self.fp)
849 self.basicHeaderObj.read(self.fp)
850 return 1
850 return 1
851
851
852 if self.fileSize == self.fileSizeByHeader:
852 if self.fileSize == self.fileSizeByHeader:
853 # self.flagEoF = True
853 # self.flagEoF = True
854 return 0
854 return 0
855
855
856 print("[Reading] Waiting %0.2f seconds for the next block, try %03d ..." % (self.delay, nTries + 1))
856 print("[Reading] Waiting %0.2f seconds for the next block, try %03d ..." % (self.delay, nTries + 1))
857 time.sleep(self.delay)
857 time.sleep(self.delay)
858
858
859 return 0
859 return 0
860
860
861 def __setNewBlock(self):
861 def __setNewBlock(self):
862
862
863 if self.fp == None:
863 if self.fp == None:
864 return 0
864 return 0
865
865
866 if self.flagIsNewFile:
866 if self.flagIsNewFile:
867 self.lastUTTime = self.basicHeaderObj.utc
867 self.lastUTTime = self.basicHeaderObj.utc
868 return 1
868 return 1
869
869
870 if self.realtime:
870 if self.realtime:
871 self.flagDiscontinuousBlock = 1
871 self.flagDiscontinuousBlock = 1
872 if not(self.setNextFile()):
872 if not(self.setNextFile()):
873 return 0
873 return 0
874 else:
874 else:
875 return 1
875 return 1
876
876
877 currentSize = self.fileSize - self.fp.tell()
877 currentSize = self.fileSize - self.fp.tell()
878 neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize
878 neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize
879
879
880 if (currentSize >= neededSize):
880 if (currentSize >= neededSize):
881 self.basicHeaderObj.read(self.fp)
881 self.basicHeaderObj.read(self.fp)
882 self.lastUTTime = self.basicHeaderObj.utc
882 self.lastUTTime = self.basicHeaderObj.utc
883 return 1
883 return 1
884
884
885 if self.__waitNewBlock():
885 if self.__waitNewBlock():
886 self.lastUTTime = self.basicHeaderObj.utc
886 self.lastUTTime = self.basicHeaderObj.utc
887 return 1
887 return 1
888
888
889 if not(self.setNextFile()):
889 if not(self.setNextFile()):
890 return 0
890 return 0
891
891
892 deltaTime = self.basicHeaderObj.utc - self.lastUTTime
892 deltaTime = self.basicHeaderObj.utc - self.lastUTTime
893 self.lastUTTime = self.basicHeaderObj.utc
893 self.lastUTTime = self.basicHeaderObj.utc
894
894
895 self.flagDiscontinuousBlock = 0
895 self.flagDiscontinuousBlock = 0
896
896
897 if deltaTime > self.maxTimeStep:
897 if deltaTime > self.maxTimeStep:
898 self.flagDiscontinuousBlock = 1
898 self.flagDiscontinuousBlock = 1
899
899
900 return 1
900 return 1
901
901
902 def readNextBlock(self):
902 def readNextBlock(self):
903
903
904 while True:
904 while True:
905 if not(self.__setNewBlock()):
905 if not(self.__setNewBlock()):
906 continue
906 continue
907
907
908 if not(self.readBlock()):
908 if not(self.readBlock()):
909 return 0
909 return 0
910
910
911 self.getBasicHeader()
911 self.getBasicHeader()
912
912
913 if not self.isDateTimeInRange(self.dataOut.datatime, self.startDate, self.endDate, self.startTime, self.endTime):
913 if not self.isDateTimeInRange(self.dataOut.datatime, self.startDate, self.endDate, self.startTime, self.endTime):
914 print("[Reading] Block No. %d/%d -> %s [Skipping]" % (self.nReadBlocks,
914 print("[Reading] Block No. %d/%d -> %s [Skipping]" % (self.nReadBlocks,
915 self.processingHeaderObj.dataBlocksPerFile,
915 self.processingHeaderObj.dataBlocksPerFile,
916 self.dataOut.datatime.ctime()))
916 self.dataOut.datatime.ctime()))
917 continue
917 continue
918
918
919 break
919 break
920
920
921 if self.verbose:
921 if self.verbose:
922 print("[Reading] Block No. %d/%d -> %s" % (self.nReadBlocks,
922 print("[Reading] Block No. %d/%d -> %s" % (self.nReadBlocks,
923 self.processingHeaderObj.dataBlocksPerFile,
923 self.processingHeaderObj.dataBlocksPerFile,
924 self.dataOut.datatime.ctime()))
924 self.dataOut.datatime.ctime()))
925 return 1
925 return 1
926
926
927 def readFirstHeader(self):
927 def readFirstHeader(self):
928
928
929 self.basicHeaderObj.read(self.fp)
929 self.basicHeaderObj.read(self.fp)
930 self.systemHeaderObj.read(self.fp)
930 self.systemHeaderObj.read(self.fp)
931 self.radarControllerHeaderObj.read(self.fp)
931 self.radarControllerHeaderObj.read(self.fp)
932 self.processingHeaderObj.read(self.fp)
932 self.processingHeaderObj.read(self.fp)
933 self.firstHeaderSize = self.basicHeaderObj.size
933 self.firstHeaderSize = self.basicHeaderObj.size
934
934
935 datatype = int(numpy.log2((self.processingHeaderObj.processFlags &
935 datatype = int(numpy.log2((self.processingHeaderObj.processFlags &
936 PROCFLAG.DATATYPE_MASK)) - numpy.log2(PROCFLAG.DATATYPE_CHAR))
936 PROCFLAG.DATATYPE_MASK)) - numpy.log2(PROCFLAG.DATATYPE_CHAR))
937 if datatype == 0:
937 if datatype == 0:
938 datatype_str = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
938 datatype_str = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
939 elif datatype == 1:
939 elif datatype == 1:
940 datatype_str = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
940 datatype_str = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
941 elif datatype == 2:
941 elif datatype == 2:
942 datatype_str = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
942 datatype_str = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
943 elif datatype == 3:
943 elif datatype == 3:
944 datatype_str = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
944 datatype_str = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
945 elif datatype == 4:
945 elif datatype == 4:
946 datatype_str = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
946 datatype_str = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
947 elif datatype == 5:
947 elif datatype == 5:
948 datatype_str = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
948 datatype_str = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
949 else:
949 else:
950 raise ValueError('Data type was not defined')
950 raise ValueError('Data type was not defined')
951
951
952 self.dtype = datatype_str
952 self.dtype = datatype_str
953 #self.ippSeconds = 2 * 1000 * self.radarControllerHeaderObj.ipp / self.c
953 #self.ippSeconds = 2 * 1000 * self.radarControllerHeaderObj.ipp / self.c
954 self.fileSizeByHeader = self.processingHeaderObj.dataBlocksPerFile * self.processingHeaderObj.blockSize + \
954 self.fileSizeByHeader = self.processingHeaderObj.dataBlocksPerFile * self.processingHeaderObj.blockSize + \
955 self.firstHeaderSize + self.basicHeaderSize * \
955 self.firstHeaderSize + self.basicHeaderSize * \
956 (self.processingHeaderObj.dataBlocksPerFile - 1)
956 (self.processingHeaderObj.dataBlocksPerFile - 1)
957 # self.dataOut.channelList = numpy.arange(self.systemHeaderObj.numChannels)
957 # self.dataOut.channelList = numpy.arange(self.systemHeaderObj.numChannels)
958 # self.dataOut.channelIndexList = numpy.arange(self.systemHeaderObj.numChannels)
958 # self.dataOut.channelIndexList = numpy.arange(self.systemHeaderObj.numChannels)
959 self.getBlockDimension()
959 self.getBlockDimension()
960
960
961 def verifyFile(self, filename):
961 def verifyFile(self, filename):
962
962
963 flag = True
963 flag = True
964
964
965 try:
965 try:
966 fp = open(filename, 'rb')
966 fp = open(filename, 'rb')
967 except IOError:
967 except IOError:
968 log.error("File {} can't be opened".format(filename), self.name)
968 log.error("File {} can't be opened".format(filename), self.name)
969 return False
969 return False
970
970
971 if self.online and self.waitDataBlock(0):
971 if self.online and self.waitDataBlock(0):
972 pass
972 pass
973
973
974 basicHeaderObj = BasicHeader(LOCALTIME)
974 basicHeaderObj = BasicHeader(LOCALTIME)
975 systemHeaderObj = SystemHeader()
975 systemHeaderObj = SystemHeader()
976 radarControllerHeaderObj = RadarControllerHeader()
976 radarControllerHeaderObj = RadarControllerHeader()
977 processingHeaderObj = ProcessingHeader()
977 processingHeaderObj = ProcessingHeader()
978
978
979 if not(basicHeaderObj.read(fp)):
979 if not(basicHeaderObj.read(fp)):
980 flag = False
980 flag = False
981 if not(systemHeaderObj.read(fp)):
981 if not(systemHeaderObj.read(fp)):
982 flag = False
982 flag = False
983 if not(radarControllerHeaderObj.read(fp)):
983 if not(radarControllerHeaderObj.read(fp)):
984 flag = False
984 flag = False
985 if not(processingHeaderObj.read(fp)):
985 if not(processingHeaderObj.read(fp)):
986 flag = False
986 flag = False
987 if not self.online:
987 if not self.online:
988 dt1 = basicHeaderObj.datatime
988 dt1 = basicHeaderObj.datatime
989 pos = self.fileSize-processingHeaderObj.blockSize-24
989 pos = self.fileSize-processingHeaderObj.blockSize-24
990 if pos<0:
990 if pos<0:
991 flag = False
991 flag = False
992 log.error('Invalid size for file: {}'.format(self.filename), self.name)
992 log.error('Invalid size for file: {}'.format(self.filename), self.name)
993 else:
993 else:
994 fp.seek(pos)
994 fp.seek(pos)
995 if not(basicHeaderObj.read(fp)):
995 if not(basicHeaderObj.read(fp)):
996 flag = False
996 flag = False
997 dt2 = basicHeaderObj.datatime
997 dt2 = basicHeaderObj.datatime
998 if not self.isDateTimeInRange(dt1, self.startDate, self.endDate, self.startTime, self.endTime) and not \
998 if not self.isDateTimeInRange(dt1, self.startDate, self.endDate, self.startTime, self.endTime) and not \
999 self.isDateTimeInRange(dt2, self.startDate, self.endDate, self.startTime, self.endTime):
999 self.isDateTimeInRange(dt2, self.startDate, self.endDate, self.startTime, self.endTime):
1000 flag = False
1000 flag = False
1001
1001
1002 fp.close()
1002 fp.close()
1003 return flag
1003 return flag
1004
1004
1005 def findDatafiles(self, path, startDate=None, endDate=None, expLabel='', ext='.r', walk=True, include_path=False):
1005 def findDatafiles(self, path, startDate=None, endDate=None, expLabel='', ext='.r', walk=True, include_path=False):
1006
1006
1007 path_empty = True
1007 path_empty = True
1008
1008
1009 dateList = []
1009 dateList = []
1010 pathList = []
1010 pathList = []
1011
1011
1012 multi_path = path.split(',')
1012 multi_path = path.split(',')
1013
1013
1014 if not walk:
1014 if not walk:
1015
1015
1016 for single_path in multi_path:
1016 for single_path in multi_path:
1017
1017
1018 if not os.path.isdir(single_path):
1018 if not os.path.isdir(single_path):
1019 continue
1019 continue
1020
1020
1021 fileList = glob.glob1(single_path, "*" + ext)
1021 fileList = glob.glob1(single_path, "*" + ext)
1022
1022
1023 if not fileList:
1023 if not fileList:
1024 continue
1024 continue
1025
1025
1026 path_empty = False
1026 path_empty = False
1027
1027
1028 fileList.sort()
1028 fileList.sort()
1029
1029
1030 for thisFile in fileList:
1030 for thisFile in fileList:
1031
1031
1032 if not os.path.isfile(os.path.join(single_path, thisFile)):
1032 if not os.path.isfile(os.path.join(single_path, thisFile)):
1033 continue
1033 continue
1034
1034
1035 if not isRadarFile(thisFile):
1035 if not isRadarFile(thisFile):
1036 continue
1036 continue
1037
1037
1038 if not isFileInDateRange(thisFile, startDate, endDate):
1038 if not isFileInDateRange(thisFile, startDate, endDate):
1039 continue
1039 continue
1040
1040
1041 thisDate = getDateFromRadarFile(thisFile)
1041 thisDate = getDateFromRadarFile(thisFile)
1042
1042
1043 if thisDate in dateList or single_path in pathList:
1043 if thisDate in dateList or single_path in pathList:
1044 continue
1044 continue
1045
1045
1046 dateList.append(thisDate)
1046 dateList.append(thisDate)
1047 pathList.append(single_path)
1047 pathList.append(single_path)
1048
1048
1049 else:
1049 else:
1050 for single_path in multi_path:
1050 for single_path in multi_path:
1051
1051
1052 if not os.path.isdir(single_path):
1052 if not os.path.isdir(single_path):
1053 continue
1053 continue
1054
1054
1055 dirList = []
1055 dirList = []
1056
1056
1057 for thisPath in os.listdir(single_path):
1057 for thisPath in os.listdir(single_path):
1058
1058
1059 if not os.path.isdir(os.path.join(single_path, thisPath)):
1059 if not os.path.isdir(os.path.join(single_path, thisPath)):
1060 continue
1060 continue
1061
1061
1062 if not isRadarFolder(thisPath):
1062 if not isRadarFolder(thisPath):
1063 continue
1063 continue
1064
1064
1065 if not isFolderInDateRange(thisPath, startDate, endDate):
1065 if not isFolderInDateRange(thisPath, startDate, endDate):
1066 continue
1066 continue
1067
1067
1068 dirList.append(thisPath)
1068 dirList.append(thisPath)
1069
1069
1070 if not dirList:
1070 if not dirList:
1071 continue
1071 continue
1072
1072
1073 dirList.sort()
1073 dirList.sort()
1074
1074
1075 for thisDir in dirList:
1075 for thisDir in dirList:
1076
1076
1077 datapath = os.path.join(single_path, thisDir, expLabel)
1077 datapath = os.path.join(single_path, thisDir, expLabel)
1078 fileList = glob.glob1(datapath, "*" + ext)
1078 fileList = glob.glob1(datapath, "*" + ext)
1079
1079
1080 if not fileList:
1080 if not fileList:
1081 continue
1081 continue
1082
1082
1083 path_empty = False
1083 path_empty = False
1084
1084
1085 thisDate = getDateFromRadarFolder(thisDir)
1085 thisDate = getDateFromRadarFolder(thisDir)
1086
1086
1087 pathList.append(datapath)
1087 pathList.append(datapath)
1088 dateList.append(thisDate)
1088 dateList.append(thisDate)
1089
1089
1090 dateList.sort()
1090 dateList.sort()
1091
1091
1092 if walk:
1092 if walk:
1093 pattern_path = os.path.join(multi_path[0], "[dYYYYDDD]", expLabel)
1093 pattern_path = os.path.join(multi_path[0], "[dYYYYDDD]", expLabel)
1094 else:
1094 else:
1095 pattern_path = multi_path[0]
1095 pattern_path = multi_path[0]
1096
1096
1097 if path_empty:
1097 if path_empty:
1098 raise schainpy.admin.SchainError("[Reading] No *%s files in %s for %s to %s" % (ext, pattern_path, startDate, endDate))
1098 raise schainpy.admin.SchainError("[Reading] No *%s files in %s for %s to %s" % (ext, pattern_path, startDate, endDate))
1099 else:
1099 else:
1100 if not dateList:
1100 if not dateList:
1101 raise schainpy.admin.SchainError("[Reading] Date range selected invalid [%s - %s]: No *%s files in %s)" % (startDate, endDate, ext, path))
1101 raise schainpy.admin.SchainError("[Reading] Date range selected invalid [%s - %s]: No *%s files in %s)" % (startDate, endDate, ext, path))
1102
1102
1103 if include_path:
1103 if include_path:
1104 return dateList, pathList
1104 return dateList, pathList
1105
1105
1106 return dateList
1106 return dateList
1107
1107
1108 def setup(self, **kwargs):
1108 def setup(self, **kwargs):
1109
1109
1110 self.set_kwargs(**kwargs)
1110 self.set_kwargs(**kwargs)
1111 if not self.ext.startswith('.'):
1111 if not self.ext.startswith('.'):
1112 self.ext = '.{}'.format(self.ext)
1112 self.ext = '.{}'.format(self.ext)
1113
1113
1114 if self.server is not None:
1114 if self.server is not None:
1115 if 'tcp://' in self.server:
1115 if 'tcp://' in self.server:
1116 address = server
1116 address = server
1117 else:
1117 else:
1118 address = 'ipc:///tmp/%s' % self.server
1118 address = 'ipc:///tmp/%s' % self.server
1119 self.server = address
1119 self.server = address
1120 self.context = zmq.Context()
1120 self.context = zmq.Context()
1121 self.receiver = self.context.socket(zmq.PULL)
1121 self.receiver = self.context.socket(zmq.PULL)
1122 self.receiver.connect(self.server)
1122 self.receiver.connect(self.server)
1123 time.sleep(0.5)
1123 time.sleep(0.5)
1124 print('[Starting] ReceiverData from {}'.format(self.server))
1124 print('[Starting] ReceiverData from {}'.format(self.server))
1125 else:
1125 else:
1126 self.server = None
1126 self.server = None
1127 if self.path == None:
1127 if self.path == None:
1128 raise ValueError("[Reading] The path is not valid")
1128 raise ValueError("[Reading] The path is not valid")
1129
1129
1130 if self.online:
1130 if self.online:
1131 log.log("[Reading] Searching files in online mode...", self.name)
1131 log.log("[Reading] Searching files in online mode...", self.name)
1132
1132
1133 for nTries in range(self.nTries):
1133 for nTries in range(self.nTries):
1134 fullpath = self.searchFilesOnLine(self.path, self.startDate,
1134 fullpath = self.searchFilesOnLine(self.path, self.startDate,
1135 self.endDate, self.expLabel, self.ext, self.walk,
1135 self.endDate, self.expLabel, self.ext, self.walk,
1136 self.filefmt, self.folderfmt)
1136 self.filefmt, self.folderfmt)
1137
1137
1138 try:
1138 try:
1139 fullpath = next(fullpath)
1139 fullpath = next(fullpath)
1140 except:
1140 except:
1141 fullpath = None
1141 fullpath = None
1142
1142
1143 if fullpath:
1143 if fullpath:
1144 break
1144 break
1145
1145
1146 log.warning(
1146 log.warning(
1147 'Waiting {} sec for a valid file in {}: try {} ...'.format(
1147 'Waiting {} sec for a valid file in {}: try {} ...'.format(
1148 self.delay, self.path, nTries + 1),
1148 self.delay, self.path, nTries + 1),
1149 self.name)
1149 self.name)
1150 time.sleep(self.delay)
1150 time.sleep(self.delay)
1151
1151
1152 if not(fullpath):
1152 if not(fullpath):
1153 raise schainpy.admin.SchainError(
1153 raise schainpy.admin.SchainError(
1154 'There isn\'t any valid file in {}'.format(self.path))
1154 'There isn\'t any valid file in {}'.format(self.path))
1155
1155
1156 pathname, filename = os.path.split(fullpath)
1156 pathname, filename = os.path.split(fullpath)
1157 self.year = int(filename[1:5])
1157 self.year = int(filename[1:5])
1158 self.doy = int(filename[5:8])
1158 self.doy = int(filename[5:8])
1159 self.set = int(filename[8:11]) - 1
1159 self.set = int(filename[8:11]) - 1
1160 else:
1160 else:
1161 log.log("Searching files in {}".format(self.path), self.name)
1161 log.log("Searching files in {}".format(self.path), self.name)
1162 self.filenameList = self.searchFilesOffLine(self.path, self.startDate,
1162 self.filenameList = self.searchFilesOffLine(self.path, self.startDate,
1163 self.endDate, self.expLabel, self.ext, self.walk, self.filefmt, self.folderfmt)
1163 self.endDate, self.expLabel, self.ext, self.walk, self.filefmt, self.folderfmt)
1164
1164
1165 self.setNextFile()
1165 self.setNextFile()
1166
1166
1167 return
1167 return
1168
1168
1169 def getBasicHeader(self):
1169 def getBasicHeader(self):
1170
1170
1171 self.dataOut.utctime = self.basicHeaderObj.utc + self.basicHeaderObj.miliSecond / \
1171 self.dataOut.utctime = self.basicHeaderObj.utc + self.basicHeaderObj.miliSecond / \
1172 1000. + self.profileIndex * self.radarControllerHeaderObj.ippSeconds
1172 1000. + self.profileIndex * self.radarControllerHeaderObj.ippSeconds
1173
1173
1174 self.dataOut.flagDiscontinuousBlock = self.flagDiscontinuousBlock
1174 self.dataOut.flagDiscontinuousBlock = self.flagDiscontinuousBlock
1175
1175
1176 self.dataOut.timeZone = self.basicHeaderObj.timeZone
1176 self.dataOut.timeZone = self.basicHeaderObj.timeZone
1177
1177
1178 self.dataOut.dstFlag = self.basicHeaderObj.dstFlag
1178 self.dataOut.dstFlag = self.basicHeaderObj.dstFlag
1179
1179
1180 self.dataOut.errorCount = self.basicHeaderObj.errorCount
1180 self.dataOut.errorCount = self.basicHeaderObj.errorCount
1181
1181
1182 self.dataOut.useLocalTime = self.basicHeaderObj.useLocalTime
1182 self.dataOut.useLocalTime = self.basicHeaderObj.useLocalTime
1183
1183
1184 self.dataOut.ippSeconds = self.radarControllerHeaderObj.ippSeconds / self.nTxs
1184 self.dataOut.ippSeconds = self.radarControllerHeaderObj.ippSeconds / self.nTxs
1185
1185
1186 def getFirstHeader(self):
1186 def getFirstHeader(self):
1187
1187
1188 raise NotImplementedError
1188 raise NotImplementedError
1189
1189
1190 def getData(self):
1190 def getData(self):
1191
1191
1192 raise NotImplementedError
1192 raise NotImplementedError
1193
1193
1194 def hasNotDataInBuffer(self):
1194 def hasNotDataInBuffer(self):
1195
1195
1196 raise NotImplementedError
1196 raise NotImplementedError
1197
1197
1198 def readBlock(self):
1198 def readBlock(self):
1199
1199
1200 raise NotImplementedError
1200 raise NotImplementedError
1201
1201
1202 def isEndProcess(self):
1202 def isEndProcess(self):
1203
1203
1204 return self.flagNoMoreFiles
1204 return self.flagNoMoreFiles
1205
1205
1206 def printReadBlocks(self):
1206 def printReadBlocks(self):
1207
1207
1208 print("[Reading] Number of read blocks per file %04d" % self.nReadBlocks)
1208 print("[Reading] Number of read blocks per file %04d" % self.nReadBlocks)
1209
1209
1210 def printTotalBlocks(self):
1210 def printTotalBlocks(self):
1211
1211
1212 print("[Reading] Number of read blocks %04d" % self.nTotalBlocks)
1212 print("[Reading] Number of read blocks %04d" % self.nTotalBlocks)
1213
1213
1214 def run(self, **kwargs):
1214 def run(self, **kwargs):
1215 """
1215 """
1216
1216
1217 Arguments:
1217 Arguments:
1218 path :
1218 path :
1219 startDate :
1219 startDate :
1220 endDate :
1220 endDate :
1221 startTime :
1221 startTime :
1222 endTime :
1222 endTime :
1223 set :
1223 set :
1224 expLabel :
1224 expLabel :
1225 ext :
1225 ext :
1226 online :
1226 online :
1227 delay :
1227 delay :
1228 walk :
1228 walk :
1229 getblock :
1229 getblock :
1230 nTxs :
1230 nTxs :
1231 realtime :
1231 realtime :
1232 blocksize :
1232 blocksize :
1233 blocktime :
1233 blocktime :
1234 skip :
1234 skip :
1235 cursor :
1235 cursor :
1236 warnings :
1236 warnings :
1237 server :
1237 server :
1238 verbose :
1238 verbose :
1239 format :
1239 format :
1240 oneDDict :
1240 oneDDict :
1241 twoDDict :
1241 twoDDict :
1242 independentParam :
1242 independentParam :
1243 """
1243 """
1244
1244
1245 if not(self.isConfig):
1245 if not(self.isConfig):
1246 self.setup(**kwargs)
1246 self.setup(**kwargs)
1247 self.isConfig = True
1247 self.isConfig = True
1248 if self.server is None:
1248 if self.server is None:
1249 self.getData()
1249 self.getData()
1250 else:
1250 else:
1251 self.getFromServer()
1251 self.getFromServer()
1252
1252
1253
1253
1254 class JRODataWriter(Reader):
1254 class JRODataWriter(Reader):
1255
1255
1256 """
1256 """
1257 Esta clase permite escribir datos a archivos procesados (.r o ,pdata). La escritura
1257 Esta clase permite escribir datos a archivos procesados (.r o ,pdata). La escritura
1258 de los datos siempre se realiza por bloques.
1258 de los datos siempre se realiza por bloques.
1259 """
1259 """
1260
1260
1261 setFile = None
1261 setFile = None
1262 profilesPerBlock = None
1262 profilesPerBlock = None
1263 blocksPerFile = None
1263 blocksPerFile = None
1264 nWriteBlocks = 0
1264 nWriteBlocks = 0
1265 fileDate = None
1265 fileDate = None
1266
1266
1267 def __init__(self, dataOut=None):
1267 def __init__(self, dataOut=None):
1268 raise NotImplementedError
1268 raise NotImplementedError
1269
1269
1270 def hasAllDataInBuffer(self):
1270 def hasAllDataInBuffer(self):
1271 raise NotImplementedError
1271 raise NotImplementedError
1272
1272
1273 def setBlockDimension(self):
1273 def setBlockDimension(self):
1274 raise NotImplementedError
1274 raise NotImplementedError
1275
1275
1276 def writeBlock(self):
1276 def writeBlock(self):
1277 raise NotImplementedError
1277 raise NotImplementedError
1278
1278
1279 def putData(self):
1279 def putData(self):
1280 raise NotImplementedError
1280 raise NotImplementedError
1281
1281
1282 def getDtypeWidth(self):
1282 def getDtypeWidth(self):
1283
1283
1284 dtype_index = get_dtype_index(self.dtype)
1284 dtype_index = get_dtype_index(self.dtype)
1285 dtype_width = get_dtype_width(dtype_index)
1285 dtype_width = get_dtype_width(dtype_index)
1286
1286
1287 return dtype_width
1287 return dtype_width
1288
1288
1289 def getProcessFlags(self):
1289 def getProcessFlags(self):
1290
1290
1291 processFlags = 0
1291 processFlags = 0
1292
1292
1293 dtype_index = get_dtype_index(self.dtype)
1293 dtype_index = get_dtype_index(self.dtype)
1294 procflag_dtype = get_procflag_dtype(dtype_index)
1294 procflag_dtype = get_procflag_dtype(dtype_index)
1295
1295
1296 processFlags += procflag_dtype
1296 processFlags += procflag_dtype
1297
1297
1298 if self.dataOut.flagDecodeData:
1298 if self.dataOut.flagDecodeData:
1299 processFlags += PROCFLAG.DECODE_DATA
1299 processFlags += PROCFLAG.DECODE_DATA
1300
1300
1301 if self.dataOut.flagDeflipData:
1301 if self.dataOut.flagDeflipData:
1302 processFlags += PROCFLAG.DEFLIP_DATA
1302 processFlags += PROCFLAG.DEFLIP_DATA
1303
1303
1304 if self.dataOut.code is not None:
1304 if self.dataOut.code is not None:
1305 processFlags += PROCFLAG.DEFINE_PROCESS_CODE
1305 processFlags += PROCFLAG.DEFINE_PROCESS_CODE
1306
1306
1307 if self.dataOut.nCohInt > 1:
1307 if self.dataOut.nCohInt > 1:
1308 processFlags += PROCFLAG.COHERENT_INTEGRATION
1308 processFlags += PROCFLAG.COHERENT_INTEGRATION
1309
1309
1310 if self.dataOut.type == "Spectra":
1310 if self.dataOut.type == "Spectra":
1311 if self.dataOut.nIncohInt > 1:
1311 if self.dataOut.nIncohInt > 1:
1312 processFlags += PROCFLAG.INCOHERENT_INTEGRATION
1312 processFlags += PROCFLAG.INCOHERENT_INTEGRATION
1313
1313
1314 if self.dataOut.data_dc is not None:
1314 if self.dataOut.data_dc is not None:
1315 processFlags += PROCFLAG.SAVE_CHANNELS_DC
1315 processFlags += PROCFLAG.SAVE_CHANNELS_DC
1316
1316
1317 if self.dataOut.flagShiftFFT:
1317 if self.dataOut.flagShiftFFT:
1318 processFlags += PROCFLAG.SHIFT_FFT_DATA
1318 processFlags += PROCFLAG.SHIFT_FFT_DATA
1319
1319
1320 return processFlags
1320 return processFlags
1321
1321
1322 def setBasicHeader(self):
1322 def setBasicHeader(self):
1323
1323
1324 self.basicHeaderObj.size = self.basicHeaderSize # bytes
1324 self.basicHeaderObj.size = self.basicHeaderSize # bytes
1325 self.basicHeaderObj.version = self.versionFile
1325 self.basicHeaderObj.version = self.versionFile
1326 self.basicHeaderObj.dataBlock = self.nTotalBlocks
1326 self.basicHeaderObj.dataBlock = self.nTotalBlocks
1327 utc = numpy.floor(self.dataOut.utctime)
1327 utc = numpy.floor(self.dataOut.utctime)
1328 milisecond = (self.dataOut.utctime - utc) * 1000.0
1328 milisecond = (self.dataOut.utctime - utc) * 1000.0
1329 self.basicHeaderObj.utc = utc
1329 self.basicHeaderObj.utc = utc
1330 self.basicHeaderObj.miliSecond = milisecond
1330 self.basicHeaderObj.miliSecond = milisecond
1331 self.basicHeaderObj.timeZone = self.dataOut.timeZone
1331 self.basicHeaderObj.timeZone = self.dataOut.timeZone
1332 self.basicHeaderObj.dstFlag = self.dataOut.dstFlag
1332 self.basicHeaderObj.dstFlag = self.dataOut.dstFlag
1333 self.basicHeaderObj.errorCount = self.dataOut.errorCount
1333 self.basicHeaderObj.errorCount = self.dataOut.errorCount
1334
1334
1335 def setFirstHeader(self):
1335 def setFirstHeader(self):
1336 """
1336 """
1337 Obtiene una copia del First Header
1337 Obtiene una copia del First Header
1338
1338
1339 Affected:
1339 Affected:
1340
1340
1341 self.basicHeaderObj
1341 self.basicHeaderObj
1342 self.systemHeaderObj
1342 self.systemHeaderObj
1343 self.radarControllerHeaderObj
1343 self.radarControllerHeaderObj
1344 self.processingHeaderObj self.
1344 self.processingHeaderObj self.
1345
1345
1346 Return:
1346 Return:
1347 None
1347 None
1348 """
1348 """
1349
1349
1350 raise NotImplementedError
1350 raise NotImplementedError
1351
1351
1352 def __writeFirstHeader(self):
1352 def __writeFirstHeader(self):
1353 """
1353 """
1354 Escribe el primer header del file es decir el Basic header y el Long header (SystemHeader, RadarControllerHeader, ProcessingHeader)
1354 Escribe el primer header del file es decir el Basic header y el Long header (SystemHeader, RadarControllerHeader, ProcessingHeader)
1355
1355
1356 Affected:
1356 Affected:
1357 __dataType
1357 __dataType
1358
1358
1359 Return:
1359 Return:
1360 None
1360 None
1361 """
1361 """
1362
1362
1363 # CALCULAR PARAMETROS
1363 # CALCULAR PARAMETROS
1364
1364
1365 sizeLongHeader = self.systemHeaderObj.size + \
1365 sizeLongHeader = self.systemHeaderObj.size + \
1366 self.radarControllerHeaderObj.size + self.processingHeaderObj.size
1366 self.radarControllerHeaderObj.size + self.processingHeaderObj.size
1367 self.basicHeaderObj.size = self.basicHeaderSize + sizeLongHeader
1367 self.basicHeaderObj.size = self.basicHeaderSize + sizeLongHeader
1368
1368
1369 self.basicHeaderObj.write(self.fp)
1369 self.basicHeaderObj.write(self.fp)
1370 self.systemHeaderObj.write(self.fp)
1370 self.systemHeaderObj.write(self.fp)
1371 self.radarControllerHeaderObj.write(self.fp)
1371 self.radarControllerHeaderObj.write(self.fp)
1372 self.processingHeaderObj.write(self.fp)
1372 self.processingHeaderObj.write(self.fp)
1373
1373
1374 def __setNewBlock(self):
1374 def __setNewBlock(self):
1375 """
1375 """
1376 Si es un nuevo file escribe el First Header caso contrario escribe solo el Basic Header
1376 Si es un nuevo file escribe el First Header caso contrario escribe solo el Basic Header
1377
1377
1378 Return:
1378 Return:
1379 0 : si no pudo escribir nada
1379 0 : si no pudo escribir nada
1380 1 : Si escribio el Basic el First Header
1380 1 : Si escribio el Basic el First Header
1381 """
1381 """
1382 if self.fp == None:
1382 if self.fp == None:
1383 self.setNextFile()
1383 self.setNextFile()
1384
1384
1385 if self.flagIsNewFile:
1385 if self.flagIsNewFile:
1386 return 1
1386 return 1
1387
1387
1388 if self.blockIndex < self.processingHeaderObj.dataBlocksPerFile:
1388 if self.blockIndex < self.processingHeaderObj.dataBlocksPerFile:
1389 self.basicHeaderObj.write(self.fp)
1389 self.basicHeaderObj.write(self.fp)
1390 return 1
1390 return 1
1391
1391
1392 if not(self.setNextFile()):
1392 if not(self.setNextFile()):
1393 return 0
1393 return 0
1394
1394
1395 return 1
1395 return 1
1396
1396
1397 def writeNextBlock(self):
1397 def writeNextBlock(self):
1398 """
1398 """
1399 Selecciona el bloque siguiente de datos y los escribe en un file
1399 Selecciona el bloque siguiente de datos y los escribe en un file
1400
1400
1401 Return:
1401 Return:
1402 0 : Si no hizo pudo escribir el bloque de datos
1402 0 : Si no hizo pudo escribir el bloque de datos
1403 1 : Si no pudo escribir el bloque de datos
1403 1 : Si no pudo escribir el bloque de datos
1404 """
1404 """
1405 if not(self.__setNewBlock()):
1405 if not(self.__setNewBlock()):
1406 return 0
1406 return 0
1407
1407
1408 self.writeBlock()
1408 self.writeBlock()
1409
1409
1410 print("[Writing] Block No. %d/%d" % (self.blockIndex,
1410 print("[Writing] Block No. %d/%d" % (self.blockIndex,
1411 self.processingHeaderObj.dataBlocksPerFile))
1411 self.processingHeaderObj.dataBlocksPerFile))
1412
1412
1413 return 1
1413 return 1
1414
1414
1415 def setNextFile(self):
1415 def setNextFile(self):
1416 """Determina el siguiente file que sera escrito
1416 """Determina el siguiente file que sera escrito
1417
1417
1418 Affected:
1418 Affected:
1419 self.filename
1419 self.filename
1420 self.subfolder
1420 self.subfolder
1421 self.fp
1421 self.fp
1422 self.setFile
1422 self.setFile
1423 self.flagIsNewFile
1423 self.flagIsNewFile
1424
1424
1425 Return:
1425 Return:
1426 0 : Si el archivo no puede ser escrito
1426 0 : Si el archivo no puede ser escrito
1427 1 : Si el archivo esta listo para ser escrito
1427 1 : Si el archivo esta listo para ser escrito
1428 """
1428 """
1429 ext = self.ext
1429 ext = self.ext
1430 path = self.path
1430 path = self.path
1431
1431
1432 if self.fp != None:
1432 if self.fp != None:
1433 self.fp.close()
1433 self.fp.close()
1434
1434
1435
1435
1436 if not os.path.exists(path):
1436 if not os.path.exists(path):
1437 os.mkdir(path)
1437 os.mkdir(path)
1438
1438
1439 timeTuple = time.localtime(self.dataOut.utctime)
1439 timeTuple = time.localtime(self.dataOut.utctime)
1440 subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year, timeTuple.tm_yday)
1440 subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year, timeTuple.tm_yday)
1441
1441
1442 fullpath = os.path.join(path, subfolder)
1442 fullpath = os.path.join(path, subfolder)
1443 setFile = self.setFile
1443 setFile = self.setFile
1444
1444
1445 if not(os.path.exists(fullpath)):
1445 if not(os.path.exists(fullpath)):
1446 os.mkdir(fullpath)
1446 os.mkdir(fullpath)
1447 setFile = -1 # inicializo mi contador de seteo
1447 setFile = -1 # inicializo mi contador de seteo
1448 else:
1448 else:
1449 filesList = os.listdir(fullpath)
1449 filesList = os.listdir(fullpath)
1450 if len(filesList) > 0:
1450 if len(filesList) > 0:
1451 filesList = sorted(filesList, key=str.lower)
1451 filesList = sorted(filesList, key=str.lower)
1452 filen = filesList[-1]
1452 filen = filesList[-1]
1453 # el filename debera tener el siguiente formato
1453 # el filename debera tener el siguiente formato
1454 # 0 1234 567 89A BCDE (hex)
1454 # 0 1234 567 89A BCDE (hex)
1455 # x YYYY DDD SSS .ext
1455 # x YYYY DDD SSS .ext
1456 if isNumber(filen[8:11]):
1456 if isNumber(filen[8:11]):
1457 # inicializo mi contador de seteo al seteo del ultimo file
1457 # inicializo mi contador de seteo al seteo del ultimo file
1458 setFile = int(filen[8:11])
1458 setFile = int(filen[8:11])
1459 else:
1459 else:
1460 setFile = -1
1460 setFile = -1
1461 else:
1461 else:
1462 setFile = -1 # inicializo mi contador de seteo
1462 setFile = -1 # inicializo mi contador de seteo
1463
1463
1464 setFile += 1
1464 setFile += 1
1465
1465
1466 # If this is a new day it resets some values
1466 # If this is a new day it resets some values
1467 if self.dataOut.datatime.date() > self.fileDate:
1467 if self.dataOut.datatime.date() > self.fileDate:
1468 setFile = 0
1468 setFile = 0
1469 self.nTotalBlocks = 0
1469 self.nTotalBlocks = 0
1470
1470
1471 filen = '{}{:04d}{:03d}{:03d}{}'.format(
1471 filen = '{}{:04d}{:03d}{:03d}{}'.format(
1472 self.optchar, timeTuple.tm_year, timeTuple.tm_yday, setFile, ext)
1472 self.optchar, timeTuple.tm_year, timeTuple.tm_yday, setFile, ext)
1473
1473
1474 filename = os.path.join(path, subfolder, filen)
1474 filename = os.path.join(path, subfolder, filen)
1475
1475
1476 fp = open(filename, 'wb')
1476 fp = open(filename, 'wb')
1477
1477
1478 self.blockIndex = 0
1478 self.blockIndex = 0
1479 self.filename = filename
1479 self.filename = filename
1480 self.subfolder = subfolder
1480 self.subfolder = subfolder
1481 self.fp = fp
1481 self.fp = fp
1482 self.setFile = setFile
1482 self.setFile = setFile
1483 self.flagIsNewFile = 1
1483 self.flagIsNewFile = 1
1484 self.fileDate = self.dataOut.datatime.date()
1484 self.fileDate = self.dataOut.datatime.date()
1485 self.setFirstHeader()
1485 self.setFirstHeader()
1486
1486
1487 print('[Writing] Opening file: %s' % self.filename)
1487 print('[Writing] Opening file: %s' % self.filename)
1488
1488
1489 self.__writeFirstHeader()
1489 self.__writeFirstHeader()
1490
1490
1491 return 1
1491 return 1
1492
1492
1493 def setup(self, dataOut, path, blocksPerFile, profilesPerBlock=64, set=None, ext=None, datatype=4):
1493 def setup(self, dataOut, path, blocksPerFile, profilesPerBlock=64, set=None, ext=None, datatype=4):
1494 """
1494 """
1495 Setea el tipo de formato en la cual sera guardada la data y escribe el First Header
1495 Setea el tipo de formato en la cual sera guardada la data y escribe el First Header
1496
1496
1497 Inputs:
1497 Inputs:
1498 path : directory where data will be saved
1498 path : directory where data will be saved
1499 profilesPerBlock : number of profiles per block
1499 profilesPerBlock : number of profiles per block
1500 set : initial file set
1500 set : initial file set
1501 datatype : An integer number that defines data type:
1501 datatype : An integer number that defines data type:
1502 0 : int8 (1 byte)
1502 0 : int8 (1 byte)
1503 1 : int16 (2 bytes)
1503 1 : int16 (2 bytes)
1504 2 : int32 (4 bytes)
1504 2 : int32 (4 bytes)
1505 3 : int64 (8 bytes)
1505 3 : int64 (8 bytes)
1506 4 : float32 (4 bytes)
1506 4 : float32 (4 bytes)
1507 5 : double64 (8 bytes)
1507 5 : double64 (8 bytes)
1508
1508
1509 Return:
1509 Return:
1510 0 : Si no realizo un buen seteo
1510 0 : Si no realizo un buen seteo
1511 1 : Si realizo un buen seteo
1511 1 : Si realizo un buen seteo
1512 """
1512 """
1513
1513
1514 if ext == None:
1514 if ext == None:
1515 ext = self.ext
1515 ext = self.ext
1516
1516
1517 self.ext = ext.lower()
1517 self.ext = ext.lower()
1518
1518
1519 self.path = path
1519 self.path = path
1520
1520
1521 if set is None:
1521 if set is None:
1522 self.setFile = -1
1522 self.setFile = -1
1523 else:
1523 else:
1524 self.setFile = set - 1
1524 self.setFile = set - 1
1525
1525
1526 self.blocksPerFile = blocksPerFile
1526 self.blocksPerFile = blocksPerFile
1527 self.profilesPerBlock = profilesPerBlock
1527 self.profilesPerBlock = profilesPerBlock
1528 self.dataOut = dataOut
1528 self.dataOut = dataOut
1529 self.fileDate = self.dataOut.datatime.date()
1529 self.fileDate = self.dataOut.datatime.date()
1530 self.dtype = self.dataOut.dtype
1530 self.dtype = self.dataOut.dtype
1531
1531
1532 if datatype is not None:
1532 if datatype is not None:
1533 self.dtype = get_numpy_dtype(datatype)
1533 self.dtype = get_numpy_dtype(datatype)
1534
1534
1535 if not(self.setNextFile()):
1535 if not(self.setNextFile()):
1536 print("[Writing] There isn't a next file")
1536 print("[Writing] There isn't a next file")
1537 return 0
1537 return 0
1538
1538
1539 self.setBlockDimension()
1539 self.setBlockDimension()
1540
1540
1541 return 1
1541 return 1
1542
1542
1543 def run(self, dataOut, path, blocksPerFile=100, profilesPerBlock=64, set=None, ext=None, datatype=4, **kwargs):
1543 def run(self, dataOut, path, blocksPerFile=100, profilesPerBlock=64, set=None, ext=None, datatype=4, **kwargs):
1544
1544
1545 if not(self.isConfig):
1545 if not(self.isConfig):
1546
1546
1547 self.setup(dataOut, path, blocksPerFile, profilesPerBlock=profilesPerBlock,
1547 self.setup(dataOut, path, blocksPerFile, profilesPerBlock=profilesPerBlock,
1548 set=set, ext=ext, datatype=datatype, **kwargs)
1548 set=set, ext=ext, datatype=datatype, **kwargs)
1549 self.isConfig = True
1549 self.isConfig = True
1550
1550
1551 self.dataOut = dataOut
1551 self.dataOut = dataOut
1552 self.putData()
1552 self.putData()
1553 return self.dataOut
1553 return self.dataOut
1554
1554
1555 @MPDecorator
1555 @MPDecorator
1556 class printInfo(Operation):
1556 class printInfo(Operation):
1557
1557
1558 def __init__(self):
1558 def __init__(self):
1559
1559
1560 Operation.__init__(self)
1560 Operation.__init__(self)
1561 self.__printInfo = True
1561 self.__printInfo = True
1562
1562
1563 def run(self, dataOut, headers = ['systemHeaderObj', 'radarControllerHeaderObj', 'processingHeaderObj']):
1563 def run(self, dataOut, headers = ['systemHeaderObj', 'radarControllerHeaderObj', 'processingHeaderObj']):
1564 if self.__printInfo == False:
1564 if self.__printInfo == False:
1565 return
1565 return
1566
1566
1567 for header in headers:
1567 for header in headers:
1568 if hasattr(dataOut, header):
1568 if hasattr(dataOut, header):
1569 obj = getattr(dataOut, header)
1569 obj = getattr(dataOut, header)
1570 if hasattr(obj, 'printInfo'):
1570 if hasattr(obj, 'printInfo'):
1571 obj.printInfo()
1571 obj.printInfo()
1572 else:
1572 else:
1573 print(obj)
1573 print(obj)
1574 else:
1574 else:
1575 log.warning('Header {} Not found in object'.format(header))
1575 log.warning('Header {} Not found in object'.format(header))
1576
1576
1577 self.__printInfo = False
1577 self.__printInfo = False
@@ -1,659 +1,659
1 ''''
1 ''''
2 Created on Set 9, 2015
2 Created on Set 9, 2015
3
3
4 @author: roj-idl71 Karim Kuyeng
4 @author: roj-idl71 Karim Kuyeng
5
5
6 @update: 2021, Joab Apaza
6 @update: 2021, Joab Apaza
7 '''
7 '''
8
8
9 import os
9 import os
10 import sys
10 import sys
11 import glob
11 import glob
12 import fnmatch
12 import fnmatch
13 import datetime
13 import datetime
14 import time
14 import time
15 import re
15 import re
16 import h5py
16 import h5py
17 import numpy
17 import numpy
18
18
19 try:
19 try:
20 from gevent import sleep
20 from gevent import sleep
21 except:
21 except:
22 from time import sleep
22 from time import sleep
23
23
24 from schainpy.model.data.jroheaderIO import RadarControllerHeader, SystemHeader
24 from schainpy.model.data.jroheaderIO import RadarControllerHeader, SystemHeader
25 from schainpy.model.data.jrodata import Voltage
25 from schainpy.model.data.jrodata import Voltage
26 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
26 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
27 from numpy import imag
27 from numpy import imag
28
28
29
29
30 class AMISRReader(ProcessingUnit):
30 class AMISRReader(ProcessingUnit):
31 '''
31 '''
32 classdocs
32 classdocs
33 '''
33 '''
34
34
35 def __init__(self):
35 def __init__(self):
36 '''
36 '''
37 Constructor
37 Constructor
38 '''
38 '''
39
39
40 ProcessingUnit.__init__(self)
40 ProcessingUnit.__init__(self)
41
41
42 self.set = None
42 self.set = None
43 self.subset = None
43 self.subset = None
44 self.extension_file = '.h5'
44 self.extension_file = '.h5'
45 self.dtc_str = 'dtc'
45 self.dtc_str = 'dtc'
46 self.dtc_id = 0
46 self.dtc_id = 0
47 self.status = True
47 self.status = True
48 self.isConfig = False
48 self.isConfig = False
49 self.dirnameList = []
49 self.dirnameList = []
50 self.filenameList = []
50 self.filenameList = []
51 self.fileIndex = None
51 self.fileIndex = None
52 self.flagNoMoreFiles = False
52 self.flagNoMoreFiles = False
53 self.flagIsNewFile = 0
53 self.flagIsNewFile = 0
54 self.filename = ''
54 self.filename = ''
55 self.amisrFilePointer = None
55 self.amisrFilePointer = None
56 self.realBeamCode = []
56 self.realBeamCode = []
57 self.beamCodeMap = None
57 self.beamCodeMap = None
58 self.azimuthList = []
58 self.azimuthList = []
59 self.elevationList = []
59 self.elevationList = []
60 self.dataShape = None
60 self.dataShape = None
61
61
62
62
63
63
64 self.profileIndex = 0
64 self.profileIndex = 0
65
65
66
66
67 self.beamCodeByFrame = None
67 self.beamCodeByFrame = None
68 self.radacTimeByFrame = None
68 self.radacTimeByFrame = None
69
69
70 self.dataset = None
70 self.dataset = None
71
71
72 self.__firstFile = True
72 self.__firstFile = True
73
73
74 self.buffer = None
74 self.buffer = None
75
75
76 self.timezone = 'ut'
76 self.timezone = 'ut'
77
77
78 self.__waitForNewFile = 20
78 self.__waitForNewFile = 20
79 self.__filename_online = None
79 self.__filename_online = None
80 #Is really necessary create the output object in the initializer
80 #Is really necessary create the output object in the initializer
81 self.dataOut = Voltage()
81 self.dataOut = Voltage()
82 self.dataOut.error=False
82 self.dataOut.error=False
83
83
84
84
85 def setup(self,path=None,
85 def setup(self,path=None,
86 startDate=None,
86 startDate=None,
87 endDate=None,
87 endDate=None,
88 startTime=None,
88 startTime=None,
89 endTime=None,
89 endTime=None,
90 walk=True,
90 walk=True,
91 timezone='ut',
91 timezone='ut',
92 all=0,
92 all=0,
93 code = None,
93 code = None,
94 nCode = 0,
94 nCode = 0,
95 nBaud = 0,
95 nBaud = 0,
96 online=False):
96 online=False):
97
97
98
98
99
99
100 self.timezone = timezone
100 self.timezone = timezone
101 self.all = all
101 self.all = all
102 self.online = online
102 self.online = online
103
103
104 self.code = code
104 self.code = code
105 self.nCode = int(nCode)
105 self.nCode = int(nCode)
106 self.nBaud = int(nBaud)
106 self.nBaud = int(nBaud)
107
107
108
108
109
109
110 #self.findFiles()
110 #self.findFiles()
111 if not(online):
111 if not(online):
112 #Busqueda de archivos offline
112 #Busqueda de archivos offline
113 self.searchFilesOffLine(path, startDate, endDate, startTime, endTime, walk)
113 self.searchFilesOffLine(path, startDate, endDate, startTime, endTime, walk)
114 else:
114 else:
115 self.searchFilesOnLine(path, startDate, endDate, startTime,endTime,walk)
115 self.searchFilesOnLine(path, startDate, endDate, startTime,endTime,walk)
116
116
117 if not(self.filenameList):
117 if not(self.filenameList):
118 raise schainpy.admin.SchainWarning("There is no files into the folder: %s"%(path))
118 raise schainpy.admin.SchainWarning("There is no files into the folder: %s"%(path))
119 sys.exit()
119 sys.exit()
120
120
121 self.fileIndex = 0
121 self.fileIndex = 0
122
122
123 self.readNextFile(online)
123 self.readNextFile(online)
124
124
125 '''
125 '''
126 Add code
126 Add code
127 '''
127 '''
128 self.isConfig = True
128 self.isConfig = True
129 # print("Setup Done")
129 # print("Setup Done")
130 pass
130 pass
131
131
132
132
133 def readAMISRHeader(self,fp):
133 def readAMISRHeader(self,fp):
134
134
135 if self.isConfig and (not self.flagNoMoreFiles):
135 if self.isConfig and (not self.flagNoMoreFiles):
136 newShape = fp.get('Raw11/Data/Samples/Data').shape[1:]
136 newShape = fp.get('Raw11/Data/Samples/Data').shape[1:]
137 if self.dataShape != newShape and newShape != None:
137 if self.dataShape != newShape and newShape != None:
138 raise schainpy.admin.SchainError("NEW FILE HAS A DIFFERENT SHAPE: ")
138 raise schainpy.admin.SchainError("NEW FILE HAS A DIFFERENT SHAPE: ")
139 print(self.dataShape,newShape,"\n")
139 print(self.dataShape,newShape,"\n")
140 return 0
140 return 0
141 else:
141 else:
142 self.dataShape = fp.get('Raw11/Data/Samples/Data').shape[1:]
142 self.dataShape = fp.get('Raw11/Data/Samples/Data').shape[1:]
143
143
144
144
145 header = 'Raw11/Data/RadacHeader'
145 header = 'Raw11/Data/RadacHeader'
146 self.beamCodeByPulse = fp.get(header+'/BeamCode') # LIST OF BEAMS PER PROFILE, TO BE USED ON REARRANGE
146 self.beamCodeByPulse = fp.get(header+'/BeamCode') # LIST OF BEAMS PER PROFILE, TO BE USED ON REARRANGE
147 if (self.startDate> datetime.date(2021, 7, 15)): #Se cambiΓ³ la forma de extracciΓ³n de Apuntes el 17
147 if (self.startDate> datetime.date(2021, 7, 15)): #Se cambiΓ³ la forma de extracciΓ³n de Apuntes el 17
148 self.beamcodeFile = fp['Setup/Beamcodefile'][()].decode()
148 self.beamcodeFile = fp['Setup/Beamcodefile'][()].decode()
149 self.trueBeams = self.beamcodeFile.split("\n")
149 self.trueBeams = self.beamcodeFile.split("\n")
150 self.trueBeams.pop()#remove last
150 self.trueBeams.pop()#remove last
151 [self.realBeamCode.append(x) for x in self.trueBeams if x not in self.realBeamCode]
151 [self.realBeamCode.append(x) for x in self.trueBeams if x not in self.realBeamCode]
152 self.beamCode = [int(x, 16) for x in self.realBeamCode]
152 self.beamCode = [int(x, 16) for x in self.realBeamCode]
153 else:
153 else:
154 _beamCode= fp.get('Raw11/Data/Beamcodes') #se usa la manera previa al cambio de apuntes
154 _beamCode= fp.get('Raw11/Data/Beamcodes') #se usa la manera previa al cambio de apuntes
155 self.beamCode = _beamCode[0,:]
155 self.beamCode = _beamCode[0,:]
156
156
157 if self.beamCodeMap == None:
157 if self.beamCodeMap == None:
158 self.beamCodeMap = fp['Setup/BeamcodeMap']
158 self.beamCodeMap = fp['Setup/BeamcodeMap']
159 for beam in self.beamCode:
159 for beam in self.beamCode:
160 beamAziElev = numpy.where(self.beamCodeMap[:,0]==beam)
160 beamAziElev = numpy.where(self.beamCodeMap[:,0]==beam)
161 beamAziElev = beamAziElev[0].squeeze()
161 beamAziElev = beamAziElev[0].squeeze()
162 self.azimuthList.append(self.beamCodeMap[beamAziElev,1])
162 self.azimuthList.append(self.beamCodeMap[beamAziElev,1])
163 self.elevationList.append(self.beamCodeMap[beamAziElev,2])
163 self.elevationList.append(self.beamCodeMap[beamAziElev,2])
164 #print("Beamssss: ",self.beamCodeMap[beamAziElev,1],self.beamCodeMap[beamAziElev,2])
164 #print("Beamssss: ",self.beamCodeMap[beamAziElev,1],self.beamCodeMap[beamAziElev,2])
165 #print(self.beamCode)
165 #print(self.beamCode)
166 #self.code = fp.get(header+'/Code') # NOT USE FOR THIS
166 #self.code = fp.get(header+'/Code') # NOT USE FOR THIS
167 self.frameCount = fp.get(header+'/FrameCount')# NOT USE FOR THIS
167 self.frameCount = fp.get(header+'/FrameCount')# NOT USE FOR THIS
168 self.modeGroup = fp.get(header+'/ModeGroup')# NOT USE FOR THIS
168 self.modeGroup = fp.get(header+'/ModeGroup')# NOT USE FOR THIS
169 self.nsamplesPulse = fp.get(header+'/NSamplesPulse')# TO GET NSA OR USING DATA FOR THAT
169 self.nsamplesPulse = fp.get(header+'/NSamplesPulse')# TO GET NSA OR USING DATA FOR THAT
170 self.pulseCount = fp.get(header+'/PulseCount')# NOT USE FOR THIS
170 self.pulseCount = fp.get(header+'/PulseCount')# NOT USE FOR THIS
171 self.radacTime = fp.get(header+'/RadacTime')# 1st TIME ON FILE ANDE CALCULATE THE REST WITH IPP*nindexprofile
171 self.radacTime = fp.get(header+'/RadacTime')# 1st TIME ON FILE ANDE CALCULATE THE REST WITH IPP*nindexprofile
172 self.timeCount = fp.get(header+'/TimeCount')# NOT USE FOR THIS
172 self.timeCount = fp.get(header+'/TimeCount')# NOT USE FOR THIS
173 self.timeStatus = fp.get(header+'/TimeStatus')# NOT USE FOR THIS
173 self.timeStatus = fp.get(header+'/TimeStatus')# NOT USE FOR THIS
174 self.rangeFromFile = fp.get('Raw11/Data/Samples/Range')
174 self.rangeFromFile = fp.get('Raw11/Data/Samples/Range')
175 self.frequency = fp.get('Rx/Frequency')
175 self.frequency = fp.get('Rx/Frequency')
176 txAus = fp.get('Raw11/Data/Pulsewidth')
176 txAus = fp.get('Raw11/Data/Pulsewidth')
177
177
178
178
179 self.nblocks = self.pulseCount.shape[0] #nblocks
179 self.nblocks = self.pulseCount.shape[0] #nblocks
180
180
181 self.nprofiles = self.pulseCount.shape[1] #nprofile
181 self.nprofiles = self.pulseCount.shape[1] #nprofile
182 self.nsa = self.nsamplesPulse[0,0] #ngates
182 self.nsa = self.nsamplesPulse[0,0] #ngates
183 self.nchannels = len(self.beamCode)
183 self.nchannels = len(self.beamCode)
184 self.ippSeconds = (self.radacTime[0][1] -self.radacTime[0][0]) #Ipp in seconds
184 self.ippSeconds = (self.radacTime[0][1] -self.radacTime[0][0]) #Ipp in seconds
185 #self.__waitForNewFile = self.nblocks # wait depending on the number of blocks since each block is 1 sec
185 #self.__waitForNewFile = self.nblocks # wait depending on the number of blocks since each block is 1 sec
186 self.__waitForNewFile = self.nblocks * self.nprofiles * self.ippSeconds # wait until new file is created
186 self.__waitForNewFile = self.nblocks * self.nprofiles * self.ippSeconds # wait until new file is created
187
187
188 #filling radar controller header parameters
188 #filling radar controller header parameters
189 self.__ippKm = self.ippSeconds *.15*1e6 # in km
189 self.__ippKm = self.ippSeconds *.15*1e6 # in km
190 self.__txA = (txAus.value)*.15 #(ipp[us]*.15km/1us) in km
190 self.__txA = (txAus.value)*.15 #(ipp[us]*.15km/1us) in km
191 self.__txB = 0
191 self.__txB = 0
192 nWindows=1
192 nWindows=1
193 self.__nSamples = self.nsa
193 self.__nSamples = self.nsa
194 self.__firstHeight = self.rangeFromFile[0][0]/1000 #in km
194 self.__firstHeight = self.rangeFromFile[0][0]/1000 #in km
195 self.__deltaHeight = (self.rangeFromFile[0][1] - self.rangeFromFile[0][0])/1000
195 self.__deltaHeight = (self.rangeFromFile[0][1] - self.rangeFromFile[0][0])/1000
196
196
197 #for now until understand why the code saved is different (code included even though code not in tuf file)
197 #for now until understand why the code saved is different (code included even though code not in tuf file)
198 #self.__codeType = 0
198 #self.__codeType = 0
199 # self.__nCode = None
199 # self.__nCode = None
200 # self.__nBaud = None
200 # self.__nBaud = None
201 self.__code = self.code
201 self.__code = self.code
202 self.__codeType = 0
202 self.__codeType = 0
203 if self.code != None:
203 if self.code != None:
204 self.__codeType = 1
204 self.__codeType = 1
205 self.__nCode = self.nCode
205 self.__nCode = self.nCode
206 self.__nBaud = self.nBaud
206 self.__nBaud = self.nBaud
207 #self.__code = 0
207 #self.__code = 0
208
208
209 #filling system header parameters
209 #filling system header parameters
210 self.__nSamples = self.nsa
210 self.__nSamples = self.nsa
211 self.newProfiles = self.nprofiles/self.nchannels
211 self.newProfiles = self.nprofiles/self.nchannels
212 self.__channelList = list(range(self.nchannels))
212 self.__channelList = list(range(self.nchannels))
213
213
214 self.__frequency = self.frequency[0][0]
214 self.__frequency = self.frequency[0][0]
215
215
216
216
217 return 1
217 return 1
218
218
219
219
220 def createBuffers(self):
220 def createBuffers(self):
221
221
222 pass
222 pass
223
223
224 def __setParameters(self,path='', startDate='',endDate='',startTime='', endTime='', walk=''):
224 def __setParameters(self,path='', startDate='',endDate='',startTime='', endTime='', walk=''):
225 self.path = path
225 self.path = path
226 self.startDate = startDate
226 self.startDate = startDate
227 self.endDate = endDate
227 self.endDate = endDate
228 self.startTime = startTime
228 self.startTime = startTime
229 self.endTime = endTime
229 self.endTime = endTime
230 self.walk = walk
230 self.walk = walk
231
231
232 def __checkPath(self):
232 def __checkPath(self):
233 if os.path.exists(self.path):
233 if os.path.exists(self.path):
234 self.status = 1
234 self.status = 1
235 else:
235 else:
236 self.status = 0
236 self.status = 0
237 print('Path:%s does not exists'%self.path)
237 print('Path:%s does not exists'%self.path)
238
238
239 return
239 return
240
240
241
241
242 def __selDates(self, amisr_dirname_format):
242 def __selDates(self, amisr_dirname_format):
243 try:
243 try:
244 year = int(amisr_dirname_format[0:4])
244 year = int(amisr_dirname_format[0:4])
245 month = int(amisr_dirname_format[4:6])
245 month = int(amisr_dirname_format[4:6])
246 dom = int(amisr_dirname_format[6:8])
246 dom = int(amisr_dirname_format[6:8])
247 thisDate = datetime.date(year,month,dom)
247 thisDate = datetime.date(year,month,dom)
248 #margen de un dΓ­a extra, igual luego se filtra for fecha y hora
248 #margen de un dΓ­a extra, igual luego se filtra for fecha y hora
249 if (thisDate>=(self.startDate - datetime.timedelta(days=1)) and thisDate <= (self.endDate)+ datetime.timedelta(days=1)):
249 if (thisDate>=(self.startDate - datetime.timedelta(days=1)) and thisDate <= (self.endDate)+ datetime.timedelta(days=1)):
250 return amisr_dirname_format
250 return amisr_dirname_format
251 except:
251 except:
252 return None
252 return None
253
253
254
254
255 def __findDataForDates(self,online=False):
255 def __findDataForDates(self,online=False):
256
256
257 if not(self.status):
257 if not(self.status):
258 return None
258 return None
259
259
260 pat = '\d+.\d+'
260 pat = '\d+.\d+'
261 dirnameList = [re.search(pat,x) for x in os.listdir(self.path)]
261 dirnameList = [re.search(pat,x) for x in os.listdir(self.path)]
262 dirnameList = [x for x in dirnameList if x!=None]
262 dirnameList = [x for x in dirnameList if x!=None]
263 dirnameList = [x.string for x in dirnameList]
263 dirnameList = [x.string for x in dirnameList]
264 if not(online):
264 if not(online):
265 dirnameList = [self.__selDates(x) for x in dirnameList]
265 dirnameList = [self.__selDates(x) for x in dirnameList]
266 dirnameList = [x for x in dirnameList if x!=None]
266 dirnameList = [x for x in dirnameList if x!=None]
267 if len(dirnameList)>0:
267 if len(dirnameList)>0:
268 self.status = 1
268 self.status = 1
269 self.dirnameList = dirnameList
269 self.dirnameList = dirnameList
270 self.dirnameList.sort()
270 self.dirnameList.sort()
271 else:
271 else:
272 self.status = 0
272 self.status = 0
273 return None
273 return None
274
274
275 def __getTimeFromData(self):
275 def __getTimeFromData(self):
276 startDateTime_Reader = datetime.datetime.combine(self.startDate,self.startTime)
276 startDateTime_Reader = datetime.datetime.combine(self.startDate,self.startTime)
277 endDateTime_Reader = datetime.datetime.combine(self.endDate,self.endTime)
277 endDateTime_Reader = datetime.datetime.combine(self.endDate,self.endTime)
278
278
279 print('Filtering Files from %s to %s'%(startDateTime_Reader, endDateTime_Reader))
279 print('Filtering Files from %s to %s'%(startDateTime_Reader, endDateTime_Reader))
280 print('........................................')
280 print('........................................')
281 filter_filenameList = []
281 filter_filenameList = []
282 self.filenameList.sort()
282 self.filenameList.sort()
283 #for i in range(len(self.filenameList)-1):
283 #for i in range(len(self.filenameList)-1):
284 for i in range(len(self.filenameList)):
284 for i in range(len(self.filenameList)):
285 filename = self.filenameList[i]
285 filename = self.filenameList[i]
286 fp = h5py.File(filename,'r')
286 fp = h5py.File(filename,'r')
287 time_str = fp.get('Time/RadacTimeString')
287 time_str = fp.get('Time/RadacTimeString')
288
288
289 startDateTimeStr_File = time_str[0][0].decode('UTF-8').split('.')[0]
289 startDateTimeStr_File = time_str[0][0].decode('UTF-8').split('.')[0]
290 #startDateTimeStr_File = "2019-12-16 09:21:11"
290 #startDateTimeStr_File = "2019-12-16 09:21:11"
291 junk = time.strptime(startDateTimeStr_File, '%Y-%m-%d %H:%M:%S')
291 junk = time.strptime(startDateTimeStr_File, '%Y-%m-%d %H:%M:%S')
292 startDateTime_File = datetime.datetime(junk.tm_year,junk.tm_mon,junk.tm_mday,junk.tm_hour, junk.tm_min, junk.tm_sec)
292 startDateTime_File = datetime.datetime(junk.tm_year,junk.tm_mon,junk.tm_mday,junk.tm_hour, junk.tm_min, junk.tm_sec)
293
293
294 #endDateTimeStr_File = "2019-12-16 11:10:11"
294 #endDateTimeStr_File = "2019-12-16 11:10:11"
295 endDateTimeStr_File = time_str[-1][-1].decode('UTF-8').split('.')[0]
295 endDateTimeStr_File = time_str[-1][-1].decode('UTF-8').split('.')[0]
296 junk = time.strptime(endDateTimeStr_File, '%Y-%m-%d %H:%M:%S')
296 junk = time.strptime(endDateTimeStr_File, '%Y-%m-%d %H:%M:%S')
297 endDateTime_File = datetime.datetime(junk.tm_year,junk.tm_mon,junk.tm_mday,junk.tm_hour, junk.tm_min, junk.tm_sec)
297 endDateTime_File = datetime.datetime(junk.tm_year,junk.tm_mon,junk.tm_mday,junk.tm_hour, junk.tm_min, junk.tm_sec)
298
298
299 fp.close()
299 fp.close()
300
300
301 #print("check time", startDateTime_File)
301 #print("check time", startDateTime_File)
302 if self.timezone == 'lt':
302 if self.timezone == 'lt':
303 startDateTime_File = startDateTime_File - datetime.timedelta(minutes = 300)
303 startDateTime_File = startDateTime_File - datetime.timedelta(minutes = 300)
304 endDateTime_File = endDateTime_File - datetime.timedelta(minutes = 300)
304 endDateTime_File = endDateTime_File - datetime.timedelta(minutes = 300)
305 if (startDateTime_File >=startDateTime_Reader and endDateTime_File<=endDateTime_Reader):
305 if (startDateTime_File >=startDateTime_Reader and endDateTime_File<=endDateTime_Reader):
306 filter_filenameList.append(filename)
306 filter_filenameList.append(filename)
307
307
308 if (startDateTime_File>endDateTime_Reader):
308 if (startDateTime_File>endDateTime_Reader):
309 break
309 break
310
310
311
311
312 filter_filenameList.sort()
312 filter_filenameList.sort()
313 self.filenameList = filter_filenameList
313 self.filenameList = filter_filenameList
314
314
315 return 1
315 return 1
316
316
317 def __filterByGlob1(self, dirName):
317 def __filterByGlob1(self, dirName):
318 filter_files = glob.glob1(dirName, '*.*%s'%self.extension_file)
318 filter_files = glob.glob1(dirName, '*.*%s'%self.extension_file)
319 filter_files.sort()
319 filter_files.sort()
320 filterDict = {}
320 filterDict = {}
321 filterDict.setdefault(dirName)
321 filterDict.setdefault(dirName)
322 filterDict[dirName] = filter_files
322 filterDict[dirName] = filter_files
323 return filterDict
323 return filterDict
324
324
325 def __getFilenameList(self, fileListInKeys, dirList):
325 def __getFilenameList(self, fileListInKeys, dirList):
326 for value in fileListInKeys:
326 for value in fileListInKeys:
327 dirName = list(value.keys())[0]
327 dirName = list(value.keys())[0]
328 for file in value[dirName]:
328 for file in value[dirName]:
329 filename = os.path.join(dirName, file)
329 filename = os.path.join(dirName, file)
330 self.filenameList.append(filename)
330 self.filenameList.append(filename)
331
331
332
332
333 def __selectDataForTimes(self, online=False):
333 def __selectDataForTimes(self, online=False):
334 #aun no esta implementado el filtro for tiempo
334 #aun no esta implementado el filtro for tiempo
335 if not(self.status):
335 if not(self.status):
336 return None
336 return None
337
337
338 dirList = [os.path.join(self.path,x) for x in self.dirnameList]
338 dirList = [os.path.join(self.path,x) for x in self.dirnameList]
339 fileListInKeys = [self.__filterByGlob1(x) for x in dirList]
339 fileListInKeys = [self.__filterByGlob1(x) for x in dirList]
340 self.__getFilenameList(fileListInKeys, dirList)
340 self.__getFilenameList(fileListInKeys, dirList)
341 if not(online):
341 if not(online):
342 #filtro por tiempo
342 #filtro por tiempo
343 if not(self.all):
343 if not(self.all):
344 self.__getTimeFromData()
344 self.__getTimeFromData()
345
345
346 if len(self.filenameList)>0:
346 if len(self.filenameList)>0:
347 self.status = 1
347 self.status = 1
348 self.filenameList.sort()
348 self.filenameList.sort()
349 else:
349 else:
350 self.status = 0
350 self.status = 0
351 return None
351 return None
352
352
353 else:
353 else:
354 #get the last file - 1
354 #get the last file - 1
355 self.filenameList = [self.filenameList[-2]]
355 self.filenameList = [self.filenameList[-2]]
356 new_dirnameList = []
356 new_dirnameList = []
357 for dirname in self.dirnameList:
357 for dirname in self.dirnameList:
358 junk = numpy.array([dirname in x for x in self.filenameList])
358 junk = numpy.array([dirname in x for x in self.filenameList])
359 junk_sum = junk.sum()
359 junk_sum = junk.sum()
360 if junk_sum > 0:
360 if junk_sum > 0:
361 new_dirnameList.append(dirname)
361 new_dirnameList.append(dirname)
362 self.dirnameList = new_dirnameList
362 self.dirnameList = new_dirnameList
363 return 1
363 return 1
364
364
365 def searchFilesOnLine(self, path, startDate, endDate, startTime=datetime.time(0,0,0),
365 def searchFilesOnLine(self, path, startDate, endDate, startTime=datetime.time(0,0,0),
366 endTime=datetime.time(23,59,59),walk=True):
366 endTime=datetime.time(23,59,59),walk=True):
367
367
368 if endDate ==None:
368 if endDate ==None:
369 startDate = datetime.datetime.utcnow().date()
369 startDate = datetime.datetime.utcnow().date()
370 endDate = datetime.datetime.utcnow().date()
370 endDate = datetime.datetime.utcnow().date()
371
371
372 self.__setParameters(path=path, startDate=startDate, endDate=endDate,startTime = startTime,endTime=endTime, walk=walk)
372 self.__setParameters(path=path, startDate=startDate, endDate=endDate,startTime = startTime,endTime=endTime, walk=walk)
373
373
374 self.__checkPath()
374 self.__checkPath()
375
375
376 self.__findDataForDates(online=True)
376 self.__findDataForDates(online=True)
377
377
378 self.dirnameList = [self.dirnameList[-1]]
378 self.dirnameList = [self.dirnameList[-1]]
379
379
380 self.__selectDataForTimes(online=True)
380 self.__selectDataForTimes(online=True)
381
381
382 return
382 return
383
383
384
384
385 def searchFilesOffLine(self,
385 def searchFilesOffLine(self,
386 path,
386 path,
387 startDate,
387 startDate,
388 endDate,
388 endDate,
389 startTime=datetime.time(0,0,0),
389 startTime=datetime.time(0,0,0),
390 endTime=datetime.time(23,59,59),
390 endTime=datetime.time(23,59,59),
391 walk=True):
391 walk=True):
392
392
393 self.__setParameters(path, startDate, endDate, startTime, endTime, walk)
393 self.__setParameters(path, startDate, endDate, startTime, endTime, walk)
394
394
395 self.__checkPath()
395 self.__checkPath()
396
396
397 self.__findDataForDates()
397 self.__findDataForDates()
398
398
399 self.__selectDataForTimes()
399 self.__selectDataForTimes()
400
400
401 for i in range(len(self.filenameList)):
401 for i in range(len(self.filenameList)):
402 print("%s" %(self.filenameList[i]))
402 print("%s" %(self.filenameList[i]))
403
403
404 return
404 return
405
405
406 def __setNextFileOffline(self):
406 def __setNextFileOffline(self):
407
407
408 try:
408 try:
409 self.filename = self.filenameList[self.fileIndex]
409 self.filename = self.filenameList[self.fileIndex]
410 self.amisrFilePointer = h5py.File(self.filename,'r')
410 self.amisrFilePointer = h5py.File(self.filename,'r')
411 self.fileIndex += 1
411 self.fileIndex += 1
412 except:
412 except:
413 self.flagNoMoreFiles = 1
413 self.flagNoMoreFiles = 1
414 raise schainpy.admin.SchainError('No more files to read')
414 raise schainpy.admin.SchainError('No more files to read')
415 return 0
415 return 0
416
416
417 self.flagIsNewFile = 1
417 self.flagIsNewFile = 1
418 print("Setting the file: %s"%self.filename)
418 print("Setting the file: %s"%self.filename)
419
419
420 return 1
420 return 1
421
421
422
422
423 def __setNextFileOnline(self):
423 def __setNextFileOnline(self):
424 filename = self.filenameList[0]
424 filename = self.filenameList[0]
425 if self.__filename_online != None:
425 if self.__filename_online != None:
426 self.__selectDataForTimes(online=True)
426 self.__selectDataForTimes(online=True)
427 filename = self.filenameList[0]
427 filename = self.filenameList[0]
428 wait = 0
428 wait = 0
429 self.__waitForNewFile=300 ## DEBUG:
429 self.__waitForNewFile=300 ## DEBUG:
430 while self.__filename_online == filename:
430 while self.__filename_online == filename:
431 print('waiting %d seconds to get a new file...'%(self.__waitForNewFile))
431 print('waiting %d seconds to get a new file...'%(self.__waitForNewFile))
432 if wait == 5:
432 if wait == 5:
433 self.flagNoMoreFiles = 1
433 self.flagNoMoreFiles = 1
434 return 0
434 return 0
435 sleep(self.__waitForNewFile)
435 sleep(self.__waitForNewFile)
436 self.__selectDataForTimes(online=True)
436 self.__selectDataForTimes(online=True)
437 filename = self.filenameList[0]
437 filename = self.filenameList[0]
438 wait += 1
438 wait += 1
439
439
440 self.__filename_online = filename
440 self.__filename_online = filename
441
441
442 self.amisrFilePointer = h5py.File(filename,'r')
442 self.amisrFilePointer = h5py.File(filename,'r')
443 self.flagIsNewFile = 1
443 self.flagIsNewFile = 1
444 self.filename = filename
444 self.filename = filename
445 print("Setting the file: %s"%self.filename)
445 print("Setting the file: %s"%self.filename)
446 return 1
446 return 1
447
447
448
448
449 def readData(self):
449 def readData(self):
450 buffer = self.amisrFilePointer.get('Raw11/Data/Samples/Data')
450 buffer = self.amisrFilePointer.get('Raw11/Data/Samples/Data')
451 re = buffer[:,:,:,0]
451 re = buffer[:,:,:,0]
452 im = buffer[:,:,:,1]
452 im = buffer[:,:,:,1]
453 dataset = re + im*1j
453 dataset = re + im*1j
454
454
455 self.radacTime = self.amisrFilePointer.get('Raw11/Data/RadacHeader/RadacTime')
455 self.radacTime = self.amisrFilePointer.get('Raw11/Data/RadacHeader/RadacTime')
456 timeset = self.radacTime[:,0]
456 timeset = self.radacTime[:,0]
457
457
458 return dataset,timeset
458 return dataset,timeset
459
459
460 def reshapeData(self):
460 def reshapeData(self):
461 #self.beamCodeByPulse, self.beamCode, self.nblocks, self.nprofiles, self.nsa,
461 #self.beamCodeByPulse, self.beamCode, self.nblocks, self.nprofiles, self.nsa,
462 channels = self.beamCodeByPulse[0,:]
462 channels = self.beamCodeByPulse[0,:]
463 nchan = self.nchannels
463 nchan = self.nchannels
464 #self.newProfiles = self.nprofiles/nchan #must be defined on filljroheader
464 #self.newProfiles = self.nprofiles/nchan #must be defined on filljroheader
465 nblocks = self.nblocks
465 nblocks = self.nblocks
466 nsamples = self.nsa
466 nsamples = self.nsa
467
467
468 #Dimensions : nChannels, nProfiles, nSamples
468 #Dimensions : nChannels, nProfiles, nSamples
469 new_block = numpy.empty((nblocks, nchan, numpy.int_(self.newProfiles), nsamples), dtype="complex64")
469 new_block = numpy.empty((nblocks, nchan, numpy.int_(self.newProfiles), nsamples), dtype="complex64")
470 ############################################
470 ############################################
471
471
472 for thisChannel in range(nchan):
472 for thisChannel in range(nchan):
473 new_block[:,thisChannel,:,:] = self.dataset[:,numpy.where(channels==self.beamCode[thisChannel])[0],:]
473 new_block[:,thisChannel,:,:] = self.dataset[:,numpy.where(channels==self.beamCode[thisChannel])[0],:]
474
474
475
475
476 new_block = numpy.transpose(new_block, (1,0,2,3))
476 new_block = numpy.transpose(new_block, (1,0,2,3))
477 new_block = numpy.reshape(new_block, (nchan,-1, nsamples))
477 new_block = numpy.reshape(new_block, (nchan,-1, nsamples))
478
478
479 return new_block
479 return new_block
480
480
481 def updateIndexes(self):
481 def updateIndexes(self):
482
482
483 pass
483 pass
484
484
485 def fillJROHeader(self):
485 def fillJROHeader(self):
486
486
487 #fill radar controller header
487 #fill radar controller header
488 self.dataOut.radarControllerHeaderObj = RadarControllerHeader(ipp=self.__ippKm,
488 self.dataOut.radarControllerHeaderObj = RadarControllerHeader(ipp=self.__ippKm,
489 txA=self.__txA,
489 txA=self.__txA,
490 txB=0,
490 txB=0,
491 nWindows=1,
491 nWindows=1,
492 nHeights=self.__nSamples,
492 nHeights=self.__nSamples,
493 firstHeight=self.__firstHeight,
493 firstHeight=self.__firstHeight,
494 deltaHeight=self.__deltaHeight,
494 deltaHeight=self.__deltaHeight,
495 codeType=self.__codeType,
495 codeType=self.__codeType,
496 nCode=self.__nCode, nBaud=self.__nBaud,
496 nCode=self.__nCode, nBaud=self.__nBaud,
497 code = self.__code,
497 code = self.__code,
498 fClock=1)
498 fClock=1)
499
499
500 #fill system header
500 #fill system header
501 self.dataOut.systemHeaderObj = SystemHeader(nSamples=self.__nSamples,
501 self.dataOut.systemHeaderObj = SystemHeader(nSamples=self.__nSamples,
502 nProfiles=self.newProfiles,
502 nProfiles=self.newProfiles,
503 nChannels=len(self.__channelList),
503 nChannels=len(self.__channelList),
504 adcResolution=14,
504 adcResolution=14,
505 pciDioBusWidth=32)
505 pciDioBusWidth=32)
506
506
507 self.dataOut.type = "Voltage"
507 self.dataOut.type = "Voltage"
508 self.dataOut.data = None
508 self.dataOut.data = None
509 self.dataOut.dtype = numpy.dtype([('real','<i8'),('imag','<i8')])
509 self.dataOut.dtype = numpy.dtype([('real','<i8'),('imag','<i8')])
510 # self.dataOut.nChannels = 0
510 # self.dataOut.nChannels = 0
511
511
512 # self.dataOut.nHeights = 0
512 # self.dataOut.nHeights = 0
513
513
514 self.dataOut.nProfiles = self.newProfiles*self.nblocks
514 self.dataOut.nProfiles = self.newProfiles*self.nblocks
515 #self.dataOut.heightList = self.__firstHeigth + numpy.arange(self.__nSamples, dtype = numpy.float)*self.__deltaHeigth
515 #self.dataOut.heightList = self.__firstHeigth + numpy.arange(self.__nSamples, dtype = numpy.float)*self.__deltaHeigth
516 ranges = numpy.reshape(self.rangeFromFile.value,(-1))
516 ranges = numpy.reshape(self.rangeFromFile.value,(-1))
517 self.dataOut.heightList = ranges/1000.0 #km
517 self.dataOut.heightList = ranges/1000.0 #km
518 self.dataOut.channelList = self.__channelList
518 self.dataOut.channelList = self.__channelList
519 self.dataOut.blocksize = self.dataOut.nChannels * self.dataOut.nHeights
519 self.dataOut.blocksize = self.dataOut.nChannels * self.dataOut.nHeights
520
520
521 # self.dataOut.channelIndexList = None
521 # self.dataOut.channelIndexList = None
522
522
523
523
524 self.dataOut.azimuthList = numpy.array(self.azimuthList)
524 self.dataOut.azimuthList = numpy.array(self.azimuthList)
525 self.dataOut.elevationList = numpy.array(self.elevationList)
525 self.dataOut.elevationList = numpy.array(self.elevationList)
526 self.dataOut.codeList = numpy.array(self.beamCode)
526 self.dataOut.codeList = numpy.array(self.beamCode)
527 #print(self.dataOut.elevationList)
527 #print(self.dataOut.elevationList)
528 self.dataOut.flagNoData = True
528 self.dataOut.flagNoData = True
529
529
530 #Set to TRUE if the data is discontinuous
530 #Set to TRUE if the data is discontinuous
531 self.dataOut.flagDiscontinuousBlock = False
531 self.dataOut.flagDiscontinuousBlock = False
532
532
533 self.dataOut.utctime = None
533 self.dataOut.utctime = None
534
534
535 #self.dataOut.timeZone = -5 #self.__timezone/60 #timezone like jroheader, difference in minutes between UTC and localtime
535 #self.dataOut.timeZone = -5 #self.__timezone/60 #timezone like jroheader, difference in minutes between UTC and localtime
536 if self.timezone == 'lt':
536 if self.timezone == 'lt':
537 self.dataOut.timeZone = time.timezone / 60. #get the timezone in minutes
537 self.dataOut.timeZone = time.timezone / 60. #get the timezone in minutes
538 else:
538 else:
539 self.dataOut.timeZone = 0 #by default time is UTC
539 self.dataOut.timeZone = 0 #by default time is UTC
540
540
541 self.dataOut.dstFlag = 0
541 self.dataOut.dstFlag = 0
542 self.dataOut.errorCount = 0
542 self.dataOut.errorCount = 0
543 self.dataOut.nCohInt = 1
543 self.dataOut.nCohInt = 1
544 self.dataOut.flagDecodeData = False #asumo que la data esta decodificada
544 self.dataOut.flagDecodeData = False #asumo que la data esta decodificada
545 self.dataOut.flagDeflipData = False #asumo que la data esta sin flip
545 self.dataOut.flagDeflipData = False #asumo que la data esta sin flip
546 self.dataOut.flagShiftFFT = False
546 self.dataOut.flagShiftFFT = False
547 self.dataOut.ippSeconds = self.ippSeconds
547 self.dataOut.ippSeconds = self.ippSeconds
548
548
549 #Time interval between profiles
549 #Time interval between profiles
550 #self.dataOut.timeInterval = self.dataOut.ippSeconds * self.dataOut.nCohInt
550 #self.dataOut.timeInterval = self.dataOut.ippSeconds * self.dataOut.nCohInt
551
551
552 self.dataOut.frequency = self.__frequency
552 self.dataOut.frequency = self.__frequency
553 self.dataOut.realtime = self.online
553 self.dataOut.realtime = self.online
554 pass
554 pass
555
555
556 def readNextFile(self,online=False):
556 def readNextFile(self,online=False):
557
557
558 if not(online):
558 if not(online):
559 newFile = self.__setNextFileOffline()
559 newFile = self.__setNextFileOffline()
560 else:
560 else:
561 newFile = self.__setNextFileOnline()
561 newFile = self.__setNextFileOnline()
562
562
563 if not(newFile):
563 if not(newFile):
564 self.dataOut.error = True
564 self.dataOut.error = True
565 return 0
565 return 0
566
566
567 if not self.readAMISRHeader(self.amisrFilePointer):
567 if not self.readAMISRHeader(self.amisrFilePointer):
568 self.dataOut.error = True
568 self.dataOut.error = True
569 return 0
569 return 0
570
570
571 self.createBuffers()
571 self.createBuffers()
572 self.fillJROHeader()
572 self.fillJROHeader()
573
573
574 #self.__firstFile = False
574 #self.__firstFile = False
575
575
576
576
577
577
578 self.dataset,self.timeset = self.readData()
578 self.dataset,self.timeset = self.readData()
579
579
580 if self.endDate!=None:
580 if self.endDate!=None:
581 endDateTime_Reader = datetime.datetime.combine(self.endDate,self.endTime)
581 endDateTime_Reader = datetime.datetime.combine(self.endDate,self.endTime)
582 time_str = self.amisrFilePointer.get('Time/RadacTimeString')
582 time_str = self.amisrFilePointer.get('Time/RadacTimeString')
583 startDateTimeStr_File = time_str[0][0].decode('UTF-8').split('.')[0]
583 startDateTimeStr_File = time_str[0][0].decode('UTF-8').split('.')[0]
584 junk = time.strptime(startDateTimeStr_File, '%Y-%m-%d %H:%M:%S')
584 junk = time.strptime(startDateTimeStr_File, '%Y-%m-%d %H:%M:%S')
585 startDateTime_File = datetime.datetime(junk.tm_year,junk.tm_mon,junk.tm_mday,junk.tm_hour, junk.tm_min, junk.tm_sec)
585 startDateTime_File = datetime.datetime(junk.tm_year,junk.tm_mon,junk.tm_mday,junk.tm_hour, junk.tm_min, junk.tm_sec)
586 if self.timezone == 'lt':
586 if self.timezone == 'lt':
587 startDateTime_File = startDateTime_File - datetime.timedelta(minutes = 300)
587 startDateTime_File = startDateTime_File - datetime.timedelta(minutes = 300)
588 if (startDateTime_File>endDateTime_Reader):
588 if (startDateTime_File>endDateTime_Reader):
589 return 0
589 return 0
590
590
591 self.jrodataset = self.reshapeData()
591 self.jrodataset = self.reshapeData()
592 #----self.updateIndexes()
592 #----self.updateIndexes()
593 self.profileIndex = 0
593 self.profileIndex = 0
594
594
595 return 1
595 return 1
596
596
597
597
598 def __hasNotDataInBuffer(self):
598 def __hasNotDataInBuffer(self):
599 if self.profileIndex >= (self.newProfiles*self.nblocks):
599 if self.profileIndex >= (self.newProfiles*self.nblocks):
600 return 1
600 return 1
601 return 0
601 return 0
602
602
603
603
604 def getData(self):
604 def getData(self):
605
605
606 if self.flagNoMoreFiles:
606 if self.flagNoMoreFiles:
607 self.dataOut.flagNoData = True
607 self.dataOut.flagNoData = True
608 return 0
608 return 0
609
609
610 if self.__hasNotDataInBuffer():
610 if self.__hasNotDataInBuffer():
611 if not (self.readNextFile(self.online)):
611 if not (self.readNextFile(self.online)):
612 return 0
612 return 0
613
613
614
614
615 if self.dataset is None: # setear esta condicion cuando no hayan datos por leer
615 if self.dataset is None: # setear esta condicion cuando no hayan datos por leer
616 self.dataOut.flagNoData = True
616 self.dataOut.flagNoData = True
617 return 0
617 return 0
618
618
619 #self.dataOut.data = numpy.reshape(self.jrodataset[self.profileIndex,:],(1,-1))
619 #self.dataOut.data = numpy.reshape(self.jrodataset[self.profileIndex,:],(1,-1))
620
620
621 self.dataOut.data = self.jrodataset[:,self.profileIndex,:]
621 self.dataOut.data = self.jrodataset[:,self.profileIndex,:]
622
622
623 #print("R_t",self.timeset)
623 #print("R_t",self.timeset)
624
624
625 #self.dataOut.utctime = self.jrotimeset[self.profileIndex]
625 #self.dataOut.utctime = self.jrotimeset[self.profileIndex]
626 #verificar basic header de jro data y ver si es compatible con este valor
626 #verificar basic header de jro data y ver si es compatible con este valor
627 #self.dataOut.utctime = self.timeset + (self.profileIndex * self.ippSeconds * self.nchannels)
627 #self.dataOut.utctime = self.timeset + (self.profileIndex * self.ippSeconds * self.nchannels)
628 indexprof = numpy.mod(self.profileIndex, self.newProfiles)
628 indexprof = numpy.mod(self.profileIndex, self.newProfiles)
629 indexblock = self.profileIndex/self.newProfiles
629 indexblock = self.profileIndex/self.newProfiles
630 #print (indexblock, indexprof)
630 #print (indexblock, indexprof)
631 diffUTC = 0
631 diffUTC = 0
632 t_comp = (indexprof * self.ippSeconds * self.nchannels) + diffUTC #
632 t_comp = (indexprof * self.ippSeconds * self.nchannels) + diffUTC #
633
633
634 #print("utc :",indexblock," __ ",t_comp)
634 #print("utc :",indexblock," __ ",t_comp)
635 #print(numpy.shape(self.timeset))
635 #print(numpy.shape(self.timeset))
636 self.dataOut.utctime = self.timeset[numpy.int_(indexblock)] + t_comp
636 self.dataOut.utctime = self.timeset[numpy.int_(indexblock)] + t_comp
637 #self.dataOut.utctime = self.timeset[self.profileIndex] + t_comp
637 #self.dataOut.utctime = self.timeset[self.profileIndex] + t_comp
638
638
639 self.dataOut.profileIndex = self.profileIndex
639 self.dataOut.profileIndex = self.profileIndex
640 #print("N profile:",self.profileIndex,self.newProfiles,self.nblocks,self.dataOut.utctime)
640 #print("N profile:",self.profileIndex,self.newProfiles,self.nblocks,self.dataOut.utctime)
641 self.dataOut.flagNoData = False
641 self.dataOut.flagNoData = False
642 # if indexprof == 0:
642 # if indexprof == 0:
643 # print("kamisr: ",self.dataOut.utctime)
643 # print("kamisr: ",self.dataOut.utctime)
644
644
645 self.profileIndex += 1
645 self.profileIndex += 1
646
646
647 return self.dataOut.data
647 return self.dataOut.data #retorno necesario??
648
648
649
649
650 def run(self, **kwargs):
650 def run(self, **kwargs):
651 '''
651 '''
652 This method will be called many times so here you should put all your code
652 This method will be called many times so here you should put all your code
653 '''
653 '''
654 #print("running kamisr")
654 #print("running kamisr")
655 if not self.isConfig:
655 if not self.isConfig:
656 self.setup(**kwargs)
656 self.setup(**kwargs)
657 self.isConfig = True
657 self.isConfig = True
658
658
659 self.getData()
659 self.getData()
@@ -1,677 +1,673
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 Examples
41 Examples
42 --------
42 --------
43
43
44 desc = {
44 desc = {
45 'Data': {
45 'Data': {
46 'data_output': ['u', 'v', 'w'],
46 'data_output': ['u', 'v', 'w'],
47 'utctime': 'timestamps',
47 'utctime': 'timestamps',
48 } ,
48 } ,
49 'Metadata': {
49 'Metadata': {
50 'heightList': 'heights'
50 'heightList': 'heights'
51 }
51 }
52 }
52 }
53
53
54 desc = {
54 desc = {
55 'Data': {
55 'Data': {
56 'data_output': 'winds',
56 'data_output': 'winds',
57 'utctime': 'timestamps'
57 'utctime': 'timestamps'
58 },
58 },
59 'Metadata': {
59 'Metadata': {
60 'heightList': 'heights'
60 'heightList': 'heights'
61 }
61 }
62 }
62 }
63
63
64 extras = {
64 extras = {
65 'timeZone': 300
65 'timeZone': 300
66 }
66 }
67
67
68 reader = project.addReadUnit(
68 reader = project.addReadUnit(
69 name='HDFReader',
69 name='HDFReader',
70 path='/path/to/files',
70 path='/path/to/files',
71 startDate='2019/01/01',
71 startDate='2019/01/01',
72 endDate='2019/01/31',
72 endDate='2019/01/31',
73 startTime='00:00:00',
73 startTime='00:00:00',
74 endTime='23:59:59',
74 endTime='23:59:59',
75 # description=json.dumps(desc),
75 # description=json.dumps(desc),
76 # extras=json.dumps(extras),
76 # extras=json.dumps(extras),
77 )
77 )
78
78
79 """
79 """
80
80
81 __attrs__ = ['path', 'startDate', 'endDate', 'startTime', 'endTime', 'description', 'extras']
81 __attrs__ = ['path', 'startDate', 'endDate', 'startTime', 'endTime', 'description', 'extras']
82
82
83 def __init__(self):
83 def __init__(self):
84 ProcessingUnit.__init__(self)
84 ProcessingUnit.__init__(self)
85 self.dataOut = Parameters()
85
86 self.ext = ".hdf5"
86 self.ext = ".hdf5"
87 self.optchar = "D"
87 self.optchar = "D"
88 self.meta = {}
88 self.meta = {}
89 self.data = {}
89 self.data = {}
90 self.open_file = h5py.File
90 self.open_file = h5py.File
91 self.open_mode = 'r'
91 self.open_mode = 'r'
92 self.description = {}
92 self.description = {}
93 self.extras = {}
93 self.extras = {}
94 self.filefmt = "*%Y%j***"
94 self.filefmt = "*%Y%j***"
95 self.folderfmt = "*%Y%j"
95 self.folderfmt = "*%Y%j"
96 self.utcoffset = 0
96 self.utcoffset = 0
97
97
98 self.dataOut = Parameters()
99 self.dataOut.error=False ## NOTE: Importante definir esto antes inicio
100 self.dataOut.flagNoData = True
101
98 def setup(self, **kwargs):
102 def setup(self, **kwargs):
99
103
100 self.set_kwargs(**kwargs)
104 self.set_kwargs(**kwargs)
101 if not self.ext.startswith('.'):
105 if not self.ext.startswith('.'):
102 self.ext = '.{}'.format(self.ext)
106 self.ext = '.{}'.format(self.ext)
103
107
104 if self.online:
108 if self.online:
105 log.log("Searching files in online mode...", self.name)
109 log.log("Searching files in online mode...", self.name)
106
110
107 for nTries in range(self.nTries):
111 for nTries in range(self.nTries):
108 fullpath = self.searchFilesOnLine(self.path, self.startDate,
112 fullpath = self.searchFilesOnLine(self.path, self.startDate,
109 self.endDate, self.expLabel, self.ext, self.walk,
113 self.endDate, self.expLabel, self.ext, self.walk,
110 self.filefmt, self.folderfmt)
114 self.filefmt, self.folderfmt)
111 pathname, filename = os.path.split(fullpath)
115 pathname, filename = os.path.split(fullpath)
112 #print(pathname,filename)
116
113 try:
117 try:
114 fullpath = next(fullpath)
118 fullpath = next(fullpath)
115
119
116 except:
120 except:
117 fullpath = None
121 fullpath = None
118
122
119 if fullpath:
123 if fullpath:
120 break
124 break
121
125
122 log.warning(
126 log.warning(
123 'Waiting {} sec for a valid file in {}: try {} ...'.format(
127 'Waiting {} sec for a valid file in {}: try {} ...'.format(
124 self.delay, self.path, nTries + 1),
128 self.delay, self.path, nTries + 1),
125 self.name)
129 self.name)
126 time.sleep(self.delay)
130 time.sleep(self.delay)
127
131
128 if not(fullpath):
132 if not(fullpath):
129 raise schainpy.admin.SchainError(
133 raise schainpy.admin.SchainError(
130 'There isn\'t any valid file in {}'.format(self.path))
134 'There isn\'t any valid file in {}'.format(self.path))
131
135
132 pathname, filename = os.path.split(fullpath)
136 pathname, filename = os.path.split(fullpath)
133 self.year = int(filename[1:5])
137 self.year = int(filename[1:5])
134 self.doy = int(filename[5:8])
138 self.doy = int(filename[5:8])
135 self.set = int(filename[8:11]) - 1
139 self.set = int(filename[8:11]) - 1
136 else:
140 else:
137 log.log("Searching files in {}".format(self.path), self.name)
141 log.log("Searching files in {}".format(self.path), self.name)
138 self.filenameList = self.searchFilesOffLine(self.path, self.startDate,
142 self.filenameList = self.searchFilesOffLine(self.path, self.startDate,
139 self.endDate, self.expLabel, self.ext, self.walk, self.filefmt, self.folderfmt)
143 self.endDate, self.expLabel, self.ext, self.walk, self.filefmt, self.folderfmt)
140
144
141 self.setNextFile()
145 self.setNextFile()
142
146
143 return
147
144
148
145
149
146 def readFirstHeader(self):
150 def readFirstHeader(self):
147 '''Read metadata and data'''
151 '''Read metadata and data'''
148
152
149 self.__readMetadata()
153 self.__readMetadata()
150 self.__readData()
154 self.__readData()
151 self.__setBlockList()
155 self.__setBlockList()
152
156
153 if 'type' in self.meta:
154 ##print("Creting dataOut...")
155 self.dataOut = eval(self.meta['type'])()
156 ##print(vars(self.dataOut))
157
157
158 for attr in self.meta:
158 for attr in self.meta:
159 ##print("attr: ", attr)
160 ##print(type(self.dataOut).__name__)
161 setattr(self.dataOut, attr, self.meta[attr])
162
159
160 setattr(self.dataOut, attr, self.meta[attr])
161 self.dataOut.error=False
162 self.dataOut.flagNoData = False
163 self.blockIndex = 0
163 self.blockIndex = 0
164
164
165 return
165 return
166
166
167 def __setBlockList(self):
167 def __setBlockList(self):
168 '''
168 '''
169 Selects the data within the times defined
169 Selects the data within the times defined
170
170
171 self.fp
171 self.fp
172 self.startTime
172 self.startTime
173 self.endTime
173 self.endTime
174 self.blockList
174 self.blockList
175 self.blocksPerFile
175 self.blocksPerFile
176
176
177 '''
177 '''
178
178
179 startTime = self.startTime
179 startTime = self.startTime
180 endTime = self.endTime
180 endTime = self.endTime
181 thisUtcTime = self.data['utctime'] + self.utcoffset
181 thisUtcTime = self.data['utctime'] + self.utcoffset
182 self.interval = numpy.min(thisUtcTime[1:] - thisUtcTime[:-1])
182 self.interval = numpy.min(thisUtcTime[1:] - thisUtcTime[:-1])
183 thisDatetime = datetime.datetime.utcfromtimestamp(thisUtcTime[0])
183 thisDatetime = datetime.datetime.utcfromtimestamp(thisUtcTime[0])
184 self.startFileDatetime = thisDatetime
184 self.startFileDatetime = thisDatetime
185 thisDate = thisDatetime.date()
185 thisDate = thisDatetime.date()
186 thisTime = thisDatetime.time()
186 thisTime = thisDatetime.time()
187
187
188 startUtcTime = (datetime.datetime.combine(thisDate, startTime) - datetime.datetime(1970, 1, 1)).total_seconds()
188 startUtcTime = (datetime.datetime.combine(thisDate, startTime) - datetime.datetime(1970, 1, 1)).total_seconds()
189 endUtcTime = (datetime.datetime.combine(thisDate, endTime) - datetime.datetime(1970, 1, 1)).total_seconds()
189 endUtcTime = (datetime.datetime.combine(thisDate, endTime) - datetime.datetime(1970, 1, 1)).total_seconds()
190
190
191 ind = numpy.where(numpy.logical_and(thisUtcTime >= startUtcTime, thisUtcTime < endUtcTime))[0]
191 ind = numpy.where(numpy.logical_and(thisUtcTime >= startUtcTime, thisUtcTime < endUtcTime))[0]
192
192
193 self.blockList = ind
193 self.blockList = ind
194 self.blocksPerFile = len(ind)
194 self.blocksPerFile = len(ind)
195 self.blocksPerFile = len(thisUtcTime)
195 self.blocksPerFile = len(thisUtcTime)
196 return
196 return
197
197
198 def __readMetadata(self):
198 def __readMetadata(self):
199 '''
199 '''
200 Reads Metadata
200 Reads Metadata
201 '''
201 '''
202
202
203 meta = {}
203 meta = {}
204
204
205 if self.description:
205 if self.description:
206 for key, value in self.description['Metadata'].items():
206 for key, value in self.description['Metadata'].items():
207 meta[key] = self.fp[value][()]
207 meta[key] = self.fp[value][()]
208 else:
208 else:
209 grp = self.fp['Metadata']
209 grp = self.fp['Metadata']
210 for name in grp:
210 for name in grp:
211 meta[name] = grp[name][()]
211 meta[name] = grp[name][()]
212
212
213 if self.extras:
213 if self.extras:
214 for key, value in self.extras.items():
214 for key, value in self.extras.items():
215 meta[key] = value
215 meta[key] = value
216 self.meta = meta
216 self.meta = meta
217
217
218 return
218 return
219
219
220
220
221
221
222 def checkForRealPath(self, nextFile, nextDay):
222 def checkForRealPath(self, nextFile, nextDay):
223
223
224 # print("check FRP")
224 # print("check FRP")
225 # dt = self.startFileDatetime + datetime.timedelta(1)
225 # dt = self.startFileDatetime + datetime.timedelta(1)
226 # filename = '{}.{}{}'.format(self.path, dt.strftime('%Y%m%d'), self.ext)
226 # filename = '{}.{}{}'.format(self.path, dt.strftime('%Y%m%d'), self.ext)
227 # fullfilename = os.path.join(self.path, filename)
227 # fullfilename = os.path.join(self.path, filename)
228 # print("check Path ",fullfilename,filename)
228 # print("check Path ",fullfilename,filename)
229 # if os.path.exists(fullfilename):
229 # if os.path.exists(fullfilename):
230 # return fullfilename, filename
230 # return fullfilename, filename
231 # return None, filename
231 # return None, filename
232 return None,None
232 return None,None
233
233
234 def __readData(self):
234 def __readData(self):
235
235
236 data = {}
236 data = {}
237
237
238 if self.description:
238 if self.description:
239 for key, value in self.description['Data'].items():
239 for key, value in self.description['Data'].items():
240 if isinstance(value, str):
240 if isinstance(value, str):
241 if isinstance(self.fp[value], h5py.Dataset):
241 if isinstance(self.fp[value], h5py.Dataset):
242 data[key] = self.fp[value][()]
242 data[key] = self.fp[value][()]
243 elif isinstance(self.fp[value], h5py.Group):
243 elif isinstance(self.fp[value], h5py.Group):
244 array = []
244 array = []
245 for ch in self.fp[value]:
245 for ch in self.fp[value]:
246 array.append(self.fp[value][ch][()])
246 array.append(self.fp[value][ch][()])
247 data[key] = numpy.array(array)
247 data[key] = numpy.array(array)
248 elif isinstance(value, list):
248 elif isinstance(value, list):
249 array = []
249 array = []
250 for ch in value:
250 for ch in value:
251 array.append(self.fp[ch][()])
251 array.append(self.fp[ch][()])
252 data[key] = numpy.array(array)
252 data[key] = numpy.array(array)
253 else:
253 else:
254 grp = self.fp['Data']
254 grp = self.fp['Data']
255 for name in grp:
255 for name in grp:
256 if isinstance(grp[name], h5py.Dataset):
256 if isinstance(grp[name], h5py.Dataset):
257 array = grp[name][()]
257 array = grp[name][()]
258 elif isinstance(grp[name], h5py.Group):
258 elif isinstance(grp[name], h5py.Group):
259 array = []
259 array = []
260 for ch in grp[name]:
260 for ch in grp[name]:
261 array.append(grp[name][ch][()])
261 array.append(grp[name][ch][()])
262 array = numpy.array(array)
262 array = numpy.array(array)
263 else:
263 else:
264 log.warning('Unknown type: {}'.format(name))
264 log.warning('Unknown type: {}'.format(name))
265
265
266 if name in self.description:
266 if name in self.description:
267 key = self.description[name]
267 key = self.description[name]
268 else:
268 else:
269 key = name
269 key = name
270 data[key] = array
270 data[key] = array
271
271
272 self.data = data
272 self.data = data
273 return
273 return
274
274
275 def getData(self):
275 def getData(self):
276 if not self.isDateTimeInRange(self.startFileDatetime, self.startDate, self.endDate, self.startTime, self.endTime):
276 if not self.isDateTimeInRange(self.startFileDatetime, self.startDate, self.endDate, self.startTime, self.endTime):
277 self.dataOut.flagNoData = True
277 self.dataOut.flagNoData = True
278 self.blockIndex = self.blocksPerFile
278 self.blockIndex = self.blocksPerFile
279 #self.dataOut.error = True TERMINA EL PROGRAMA, removido
279 self.dataOut.error = True # TERMINA EL PROGRAMA
280 return
280 return
281 for attr in self.data:
281 for attr in self.data:
282 #print("attr ",attr)
282
283 if self.data[attr].ndim == 1:
283 if self.data[attr].ndim == 1:
284 setattr(self.dataOut, attr, self.data[attr][self.blockIndex])
284 setattr(self.dataOut, attr, self.data[attr][self.blockIndex])
285 else:
285 else:
286 setattr(self.dataOut, attr, self.data[attr][:, self.blockIndex])
286 setattr(self.dataOut, attr, self.data[attr][:, self.blockIndex])
287
287
288
288
289 self.blockIndex += 1
289 self.blockIndex += 1
290
290
291 if self.blockIndex == 1:
291 if self.blockIndex == 1:
292 log.log("Block No. {}/{} -> {}".format(
292 log.log("Block No. {}/{} -> {}".format(
293 self.blockIndex,
293 self.blockIndex,
294 self.blocksPerFile,
294 self.blocksPerFile,
295 self.dataOut.datatime.ctime()), self.name)
295 self.dataOut.datatime.ctime()), self.name)
296 else:
296 else:
297 log.log("Block No. {}/{} ".format(
297 log.log("Block No. {}/{} ".format(
298 self.blockIndex,
298 self.blockIndex,
299 self.blocksPerFile),self.name)
299 self.blocksPerFile),self.name)
300
300
301 if self.blockIndex == self.blocksPerFile:
302 self.setNextFile()
303
301 self.dataOut.flagNoData = False
304 self.dataOut.flagNoData = False
302 self.dataOut.error = False
305
303 return
304
306
305 def run(self, **kwargs):
307 def run(self, **kwargs):
306
308
307 if not(self.isConfig):
309 if not(self.isConfig):
308 self.setup(**kwargs)
310 self.setup(**kwargs)
309 self.isConfig = True
311 self.isConfig = True
310
312
311 if self.blockIndex == self.blocksPerFile:
312 self.setNextFile()
313
314 self.getData()
313 self.getData()
315
314
316 return
317
318 @MPDecorator
315 @MPDecorator
319 class HDFWriter(Operation):
316 class HDFWriter(Operation):
320 """Operation to write HDF5 files.
317 """Operation to write HDF5 files.
321
318
322 The HDF5 file contains by default two groups Data and Metadata where
319 The HDF5 file contains by default two groups Data and Metadata where
323 you can save any `dataOut` attribute specified by `dataList` and `metadataList`
320 you can save any `dataOut` attribute specified by `dataList` and `metadataList`
324 parameters, data attributes are normaly time dependent where the metadata
321 parameters, data attributes are normaly time dependent where the metadata
325 are not.
322 are not.
326 It is possible to customize the structure of the HDF5 file with the
323 It is possible to customize the structure of the HDF5 file with the
327 optional description parameter see the examples.
324 optional description parameter see the examples.
328
325
329 Parameters:
326 Parameters:
330 -----------
327 -----------
331 path : str
328 path : str
332 Path where files will be saved.
329 Path where files will be saved.
333 blocksPerFile : int
330 blocksPerFile : int
334 Number of blocks per file
331 Number of blocks per file
335 metadataList : list
332 metadataList : list
336 List of the dataOut attributes that will be saved as metadata
333 List of the dataOut attributes that will be saved as metadata
337 dataList : int
334 dataList : int
338 List of the dataOut attributes that will be saved as data
335 List of the dataOut attributes that will be saved as data
339 setType : bool
336 setType : bool
340 If True the name of the files corresponds to the timestamp of the data
337 If True the name of the files corresponds to the timestamp of the data
341 description : dict, optional
338 description : dict, optional
342 Dictionary with the desired description of the HDF5 file
339 Dictionary with the desired description of the HDF5 file
343
340
344 Examples
341 Examples
345 --------
342 --------
346
343
347 desc = {
344 desc = {
348 'data_output': {'winds': ['z', 'w', 'v']},
345 'data_output': {'winds': ['z', 'w', 'v']},
349 'utctime': 'timestamps',
346 'utctime': 'timestamps',
350 'heightList': 'heights'
347 'heightList': 'heights'
351 }
348 }
352 desc = {
349 desc = {
353 'data_output': ['z', 'w', 'v'],
350 'data_output': ['z', 'w', 'v'],
354 'utctime': 'timestamps',
351 'utctime': 'timestamps',
355 'heightList': 'heights'
352 'heightList': 'heights'
356 }
353 }
357 desc = {
354 desc = {
358 'Data': {
355 'Data': {
359 'data_output': 'winds',
356 'data_output': 'winds',
360 'utctime': 'timestamps'
357 'utctime': 'timestamps'
361 },
358 },
362 'Metadata': {
359 'Metadata': {
363 'heightList': 'heights'
360 'heightList': 'heights'
364 }
361 }
365 }
362 }
366
363
367 writer = proc_unit.addOperation(name='HDFWriter')
364 writer = proc_unit.addOperation(name='HDFWriter')
368 writer.addParameter(name='path', value='/path/to/file')
365 writer.addParameter(name='path', value='/path/to/file')
369 writer.addParameter(name='blocksPerFile', value='32')
366 writer.addParameter(name='blocksPerFile', value='32')
370 writer.addParameter(name='metadataList', value='heightList,timeZone')
367 writer.addParameter(name='metadataList', value='heightList,timeZone')
371 writer.addParameter(name='dataList',value='data_output,utctime')
368 writer.addParameter(name='dataList',value='data_output,utctime')
372 # writer.addParameter(name='description',value=json.dumps(desc))
369 # writer.addParameter(name='description',value=json.dumps(desc))
373
370
374 """
371 """
375
372
376 ext = ".hdf5"
373 ext = ".hdf5"
377 optchar = "D"
374 optchar = "D"
378 filename = None
375 filename = None
379 path = None
376 path = None
380 setFile = None
377 setFile = None
381 fp = None
378 fp = None
382 firsttime = True
379 firsttime = True
383 #Configurations
380 #Configurations
384 blocksPerFile = None
381 blocksPerFile = None
385 blockIndex = None
382 blockIndex = None
386 dataOut = None
383 dataOut = None
387 #Data Arrays
384 #Data Arrays
388 dataList = None
385 dataList = None
389 metadataList = None
386 metadataList = None
390 currentDay = None
387 currentDay = None
391 lastTime = None
388 lastTime = None
392 timeZone = "ut"
389 timeZone = "ut"
393 hourLimit = 3
390 hourLimit = 3
394 breakDays = True
391 breakDays = True
395
392
396 def __init__(self):
393 def __init__(self):
397
394
398 Operation.__init__(self)
395 Operation.__init__(self)
399 return
396 return
400
397
401 def setup(self, path=None, blocksPerFile=10, metadataList=None, dataList=None, setType=None,
398 def setup(self, path=None, blocksPerFile=10, metadataList=None, dataList=None, setType=None,
402 description={},timeZone = "ut",hourLimit = 3, breakDays=True):
399 description={},timeZone = "ut",hourLimit = 3, breakDays=True):
403 self.path = path
400 self.path = path
404 self.blocksPerFile = blocksPerFile
401 self.blocksPerFile = blocksPerFile
405 self.metadataList = metadataList
402 self.metadataList = metadataList
406 self.dataList = [s.strip() for s in dataList]
403 self.dataList = [s.strip() for s in dataList]
407 self.setType = setType
404 self.setType = setType
408 self.description = description
405 self.description = description
409 self.timeZone = timeZone
406 self.timeZone = timeZone
410 self.hourLimit = hourLimit
407 self.hourLimit = hourLimit
411 self.breakDays = breakDays
408 self.breakDays = breakDays
412
409
413 if self.metadataList is None:
410 if self.metadataList is None:
414 self.metadataList = self.dataOut.metadata_list
411 self.metadataList = self.dataOut.metadata_list
415
412
416 tableList = []
413 tableList = []
417 dsList = []
414 dsList = []
418
415
419 for i in range(len(self.dataList)):
416 for i in range(len(self.dataList)):
420 dsDict = {}
417 dsDict = {}
421 if hasattr(self.dataOut, self.dataList[i]):
418 if hasattr(self.dataOut, self.dataList[i]):
422 dataAux = getattr(self.dataOut, self.dataList[i])
419 dataAux = getattr(self.dataOut, self.dataList[i])
423 dsDict['variable'] = self.dataList[i]
420 dsDict['variable'] = self.dataList[i]
424 else:
421 else:
425 log.warning('Attribute {} not found in dataOut', self.name)
422 log.warning('Attribute {} not found in dataOut', self.name)
426 continue
423 continue
427
424
428 if dataAux is None:
425 if dataAux is None:
429 continue
426 continue
430 elif isinstance(dataAux, (int, float, numpy.integer, numpy.float)):
427 elif isinstance(dataAux, (int, float, numpy.integer, numpy.float)):
431 dsDict['nDim'] = 0
428 dsDict['nDim'] = 0
432 else:
429 else:
433 dsDict['nDim'] = len(dataAux.shape)
430 dsDict['nDim'] = len(dataAux.shape)
434 dsDict['shape'] = dataAux.shape
431 dsDict['shape'] = dataAux.shape
435 dsDict['dsNumber'] = dataAux.shape[0]
432 dsDict['dsNumber'] = dataAux.shape[0]
436 dsDict['dtype'] = dataAux.dtype
433 dsDict['dtype'] = dataAux.dtype
437
434
438 dsList.append(dsDict)
435 dsList.append(dsDict)
439
436
440 self.dsList = dsList
437 self.dsList = dsList
441 self.currentDay = self.dataOut.datatime.date()
438 self.currentDay = self.dataOut.datatime.date()
442
439
443 def timeFlag(self):
440 def timeFlag(self):
444 currentTime = self.dataOut.utctime
441 currentTime = self.dataOut.utctime
445 timeTuple = None
442 timeTuple = None
446 if self.timeZone == "lt":
443 if self.timeZone == "lt":
447 timeTuple = time.localtime(currentTime)
444 timeTuple = time.localtime(currentTime)
448 else :
445 else :
449 timeTuple = time.gmtime(currentTime)
446 timeTuple = time.gmtime(currentTime)
450
447
451 dataDay = timeTuple.tm_yday
448 dataDay = timeTuple.tm_yday
452 #print("time UTC: ",currentTime, self.dataOut.datatime)
449 #print("time UTC: ",currentTime, self.dataOut.datatime)
453 if self.lastTime is None:
450 if self.lastTime is None:
454 self.lastTime = currentTime
451 self.lastTime = currentTime
455 self.currentDay = dataDay
452 self.currentDay = dataDay
456 return False
453 return False
457
454
458 timeDiff = currentTime - self.lastTime
455 timeDiff = currentTime - self.lastTime
459
456
460 #Si el dia es diferente o si la diferencia entre un dato y otro supera self.hourLimit
457 #Si el dia es diferente o si la diferencia entre un dato y otro supera self.hourLimit
461 if (dataDay != self.currentDay) and self.breakDays:
458 if (dataDay != self.currentDay) and self.breakDays:
462 self.currentDay = dataDay
459 self.currentDay = dataDay
463 return True
460 return True
464 elif timeDiff > self.hourLimit*60*60:
461 elif timeDiff > self.hourLimit*60*60:
465 self.lastTime = currentTime
462 self.lastTime = currentTime
466 return True
463 return True
467 else:
464 else:
468 self.lastTime = currentTime
465 self.lastTime = currentTime
469 return False
466 return False
470
467
471 def run(self, dataOut,**kwargs):
468 def run(self, dataOut,**kwargs):
472
469
473 self.dataOut = dataOut
470 self.dataOut = dataOut
474 if not(self.isConfig):
471 if not(self.isConfig):
475 self.setup(**kwargs)
472 self.setup(**kwargs)
476
473
477 self.isConfig = True
474 self.isConfig = True
478 self.setNextFile()
475 self.setNextFile()
479
476
480 self.putData()
477 self.putData()
481 return
478 return
482
479
483 def setNextFile(self):
480 def setNextFile(self):
484
481
485 ext = self.ext
482 ext = self.ext
486 path = self.path
483 path = self.path
487 setFile = self.setFile
484 setFile = self.setFile
488 timeTuple = None
485 timeTuple = None
489 if self.timeZone == "lt":
486 if self.timeZone == "lt":
490 timeTuple = time.localtime(self.dataOut.utctime)
487 timeTuple = time.localtime(self.dataOut.utctime)
491 elif self.timeZone == "ut":
488 elif self.timeZone == "ut":
492 timeTuple = time.gmtime(self.dataOut.utctime)
489 timeTuple = time.gmtime(self.dataOut.utctime)
493 #print("path: ",timeTuple)
490 #print("path: ",timeTuple)
494 subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday)
491 subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday)
495 fullpath = os.path.join(path, subfolder)
492 fullpath = os.path.join(path, subfolder)
496
493
497 if os.path.exists(fullpath):
494 if os.path.exists(fullpath):
498 filesList = os.listdir(fullpath)
495 filesList = os.listdir(fullpath)
499 filesList = [k for k in filesList if k.startswith(self.optchar)]
496 filesList = [k for k in filesList if k.startswith(self.optchar)]
500 if len( filesList ) > 0:
497 if len( filesList ) > 0:
501 filesList = sorted(filesList, key=str.lower)
498 filesList = sorted(filesList, key=str.lower)
502 filen = filesList[-1]
499 filen = filesList[-1]
503 # el filename debera tener el siguiente formato
500 # el filename debera tener el siguiente formato
504 # 0 1234 567 89A BCDE (hex)
501 # 0 1234 567 89A BCDE (hex)
505 # x YYYY DDD SSS .ext
502 # x YYYY DDD SSS .ext
506 if isNumber(filen[8:11]):
503 if isNumber(filen[8:11]):
507 setFile = int(filen[8:11]) #inicializo mi contador de seteo al seteo del ultimo file
504 setFile = int(filen[8:11]) #inicializo mi contador de seteo al seteo del ultimo file
508 else:
505 else:
509 setFile = -1
506 setFile = -1
510 else:
507 else:
511 setFile = -1 #inicializo mi contador de seteo
508 setFile = -1 #inicializo mi contador de seteo
512 else:
509 else:
513 os.makedirs(fullpath)
510 os.makedirs(fullpath)
514 setFile = -1 #inicializo mi contador de seteo
511 setFile = -1 #inicializo mi contador de seteo
515
512
516 if self.setType is None:
513 if self.setType is None:
517 setFile += 1
514 setFile += 1
518 file = '%s%4.4d%3.3d%03d%s' % (self.optchar,
515 file = '%s%4.4d%3.3d%03d%s' % (self.optchar,
519 timeTuple.tm_year,
516 timeTuple.tm_year,
520 timeTuple.tm_yday,
517 timeTuple.tm_yday,
521 setFile,
518 setFile,
522 ext )
519 ext )
523 else:
520 else:
524 setFile = timeTuple.tm_hour*60+timeTuple.tm_min
521 setFile = timeTuple.tm_hour*60+timeTuple.tm_min
525 file = '%s%4.4d%3.3d%04d%s' % (self.optchar,
522 file = '%s%4.4d%3.3d%04d%s' % (self.optchar,
526 timeTuple.tm_year,
523 timeTuple.tm_year,
527 timeTuple.tm_yday,
524 timeTuple.tm_yday,
528 setFile,
525 setFile,
529 ext )
526 ext )
530
527
531 self.filename = os.path.join( path, subfolder, file )
528 self.filename = os.path.join( path, subfolder, file )
532
529
533 #Setting HDF5 File
530 #Setting HDF5 File
534 self.fp = h5py.File(self.filename, 'w')
531 self.fp = h5py.File(self.filename, 'w')
535 #write metadata
532 #write metadata
536 self.writeMetadata(self.fp)
533 self.writeMetadata(self.fp)
537 #Write data
534 #Write data
538 self.writeData(self.fp)
535 self.writeData(self.fp)
539
536
540 def getLabel(self, name, x=None):
537 def getLabel(self, name, x=None):
541
538
542 if x is None:
539 if x is None:
543 if 'Data' in self.description:
540 if 'Data' in self.description:
544 data = self.description['Data']
541 data = self.description['Data']
545 if 'Metadata' in self.description:
542 if 'Metadata' in self.description:
546 data.update(self.description['Metadata'])
543 data.update(self.description['Metadata'])
547 else:
544 else:
548 data = self.description
545 data = self.description
549 if name in data:
546 if name in data:
550 if isinstance(data[name], str):
547 if isinstance(data[name], str):
551 return data[name]
548 return data[name]
552 elif isinstance(data[name], list):
549 elif isinstance(data[name], list):
553 return None
550 return None
554 elif isinstance(data[name], dict):
551 elif isinstance(data[name], dict):
555 for key, value in data[name].items():
552 for key, value in data[name].items():
556 return key
553 return key
557 return name
554 return name
558 else:
555 else:
559 if 'Metadata' in self.description:
556 if 'Metadata' in self.description:
560 meta = self.description['Metadata']
557 meta = self.description['Metadata']
561 else:
558 else:
562 meta = self.description
559 meta = self.description
563 if name in meta:
560 if name in meta:
564 if isinstance(meta[name], list):
561 if isinstance(meta[name], list):
565 return meta[name][x]
562 return meta[name][x]
566 elif isinstance(meta[name], dict):
563 elif isinstance(meta[name], dict):
567 for key, value in meta[name].items():
564 for key, value in meta[name].items():
568 return value[x]
565 return value[x]
569 if 'cspc' in name:
566 if 'cspc' in name:
570 return 'pair{:02d}'.format(x)
567 return 'pair{:02d}'.format(x)
571 else:
568 else:
572 return 'channel{:02d}'.format(x)
569 return 'channel{:02d}'.format(x)
573
570
574 def writeMetadata(self, fp):
571 def writeMetadata(self, fp):
575
572
576 if self.description:
573 if self.description:
577 if 'Metadata' in self.description:
574 if 'Metadata' in self.description:
578 grp = fp.create_group('Metadata')
575 grp = fp.create_group('Metadata')
579 else:
576 else:
580 grp = fp
577 grp = fp
581 else:
578 else:
582 grp = fp.create_group('Metadata')
579 grp = fp.create_group('Metadata')
583
580
584 for i in range(len(self.metadataList)):
581 for i in range(len(self.metadataList)):
585 if not hasattr(self.dataOut, self.metadataList[i]):
582 if not hasattr(self.dataOut, self.metadataList[i]):
586 log.warning('Metadata: `{}` not found'.format(self.metadataList[i]), self.name)
583 log.warning('Metadata: `{}` not found'.format(self.metadataList[i]), self.name)
587 continue
584 continue
588 value = getattr(self.dataOut, self.metadataList[i])
585 value = getattr(self.dataOut, self.metadataList[i])
589 if isinstance(value, bool):
586 if isinstance(value, bool):
590 if value is True:
587 if value is True:
591 value = 1
588 value = 1
592 else:
589 else:
593 value = 0
590 value = 0
594 grp.create_dataset(self.getLabel(self.metadataList[i]), data=value)
591 grp.create_dataset(self.getLabel(self.metadataList[i]), data=value)
595 return
592 return
596
593
597 def writeData(self, fp):
594 def writeData(self, fp):
598
595
599 if self.description:
596 if self.description:
600 if 'Data' in self.description:
597 if 'Data' in self.description:
601 grp = fp.create_group('Data')
598 grp = fp.create_group('Data')
602 else:
599 else:
603 grp = fp
600 grp = fp
604 else:
601 else:
605 grp = fp.create_group('Data')
602 grp = fp.create_group('Data')
606
603
607 dtsets = []
604 dtsets = []
608 data = []
605 data = []
609
606
610 for dsInfo in self.dsList:
607 for dsInfo in self.dsList:
611 if dsInfo['nDim'] == 0:
608 if dsInfo['nDim'] == 0:
612 ds = grp.create_dataset(
609 ds = grp.create_dataset(
613 self.getLabel(dsInfo['variable']),
610 self.getLabel(dsInfo['variable']),
614 (self.blocksPerFile, ),
611 (self.blocksPerFile, ),
615 chunks=True,
612 chunks=True,
616 dtype=numpy.float64)
613 dtype=numpy.float64)
617 dtsets.append(ds)
614 dtsets.append(ds)
618 data.append((dsInfo['variable'], -1))
615 data.append((dsInfo['variable'], -1))
619 else:
616 else:
620 label = self.getLabel(dsInfo['variable'])
617 label = self.getLabel(dsInfo['variable'])
621 if label is not None:
618 if label is not None:
622 sgrp = grp.create_group(label)
619 sgrp = grp.create_group(label)
623 else:
620 else:
624 sgrp = grp
621 sgrp = grp
625 for i in range(dsInfo['dsNumber']):
622 for i in range(dsInfo['dsNumber']):
626 ds = sgrp.create_dataset(
623 ds = sgrp.create_dataset(
627 self.getLabel(dsInfo['variable'], i),
624 self.getLabel(dsInfo['variable'], i),
628 (self.blocksPerFile, ) + dsInfo['shape'][1:],
625 (self.blocksPerFile, ) + dsInfo['shape'][1:],
629 chunks=True,
626 chunks=True,
630 dtype=dsInfo['dtype'])
627 dtype=dsInfo['dtype'])
631 dtsets.append(ds)
628 dtsets.append(ds)
632 data.append((dsInfo['variable'], i))
629 data.append((dsInfo['variable'], i))
633 fp.flush()
630 fp.flush()
634
631
635 log.log('Creating file: {}'.format(fp.filename), self.name)
632 log.log('Creating file: {}'.format(fp.filename), self.name)
636
633
637 self.ds = dtsets
634 self.ds = dtsets
638 self.data = data
635 self.data = data
639 self.firsttime = True
636 self.firsttime = True
640 self.blockIndex = 0
637 self.blockIndex = 0
641 return
638 return
642
639
643 def putData(self):
640 def putData(self):
644
641
645 if (self.blockIndex == self.blocksPerFile) or self.timeFlag():
642 if (self.blockIndex == self.blocksPerFile) or self.timeFlag():
646 self.closeFile()
643 self.closeFile()
647 self.setNextFile()
644 self.setNextFile()
648 print("breaking file")
649
645
650 for i, ds in enumerate(self.ds):
646 for i, ds in enumerate(self.ds):
651 attr, ch = self.data[i]
647 attr, ch = self.data[i]
652 if ch == -1:
648 if ch == -1:
653 ds[self.blockIndex] = getattr(self.dataOut, attr)
649 ds[self.blockIndex] = getattr(self.dataOut, attr)
654 else:
650 else:
655 ds[self.blockIndex] = getattr(self.dataOut, attr)[ch]
651 ds[self.blockIndex] = getattr(self.dataOut, attr)[ch]
656
652
657 self.fp.flush()
653 self.fp.flush()
658 self.blockIndex += 1
654 self.blockIndex += 1
659 if self.blockIndex == 1:
655 if self.blockIndex == 1:
660 log.log('Block No. {}/{} --> {}'.format(self.blockIndex, self.blocksPerFile,self.dataOut.datatime.ctime()), self.name)
656 log.log('Block No. {}/{} --> {}'.format(self.blockIndex, self.blocksPerFile,self.dataOut.datatime.ctime()), self.name)
661 else:
657 else:
662 log.log('Block No. {}/{}'.format(self.blockIndex, self.blocksPerFile), self.name)
658 log.log('Block No. {}/{}'.format(self.blockIndex, self.blocksPerFile), self.name)
663 return
659 return
664
660
665 def closeFile(self):
661 def closeFile(self):
666
662
667 if self.blockIndex != self.blocksPerFile:
663 if self.blockIndex != self.blocksPerFile:
668 for ds in self.ds:
664 for ds in self.ds:
669 ds.resize(self.blockIndex, axis=0)
665 ds.resize(self.blockIndex, axis=0)
670
666
671 if self.fp:
667 if self.fp:
672 self.fp.flush()
668 self.fp.flush()
673 self.fp.close()
669 self.fp.close()
674
670
675 def close(self):
671 def close(self):
676
672
677 self.closeFile()
673 self.closeFile()
@@ -1,203 +1,205
1 '''
1 '''
2 Base clases to create Processing units and operations, the MPDecorator
2 Base clases to create Processing units and operations, the MPDecorator
3 must be used in plotting and writing operations to allow to run as an
3 must be used in plotting and writing operations to allow to run as an
4 external process.
4 external process.
5 '''
5 '''
6
6
7 import inspect
7 import inspect
8 import zmq
8 import zmq
9 import time
9 import time
10 import pickle
10 import pickle
11 import traceback
11 import traceback
12 from threading import Thread
12 from threading import Thread
13 from multiprocessing import Process, Queue
13 from multiprocessing import Process, Queue
14 from schainpy.utils import log
14 from schainpy.utils import log
15
15
16
16
17 class ProcessingUnit(object):
17 class ProcessingUnit(object):
18 '''
18 '''
19 Base class to create Signal Chain Units
19 Base class to create Signal Chain Units
20 '''
20 '''
21
21
22 proc_type = 'processing'
22 proc_type = 'processing'
23
23
24 def __init__(self):
24 def __init__(self):
25
25
26 self.dataIn = None
26 self.dataIn = None
27 self.dataOut = None
27 self.dataOut = None
28 self.isConfig = False
28 self.isConfig = False
29 self.operations = []
29 self.operations = []
30
30
31 def setInput(self, unit):
31 def setInput(self, unit):
32
32
33 self.dataIn = unit.dataOut
33 self.dataIn = unit.dataOut
34
34
35
35 def getAllowedArgs(self):
36 def getAllowedArgs(self):
36 if hasattr(self, '__attrs__'):
37 if hasattr(self, '__attrs__'):
37 return self.__attrs__
38 return self.__attrs__
38 else:
39 else:
39 return inspect.getargspec(self.run).args
40 return inspect.getargspec(self.run).args
40
41
41 def addOperation(self, conf, operation):
42 def addOperation(self, conf, operation):
42 '''
43 '''
43 '''
44 '''
44
45
45 self.operations.append((operation, conf.type, conf.getKwargs()))
46 self.operations.append((operation, conf.type, conf.getKwargs()))
46
47
47 def getOperationObj(self, objId):
48 def getOperationObj(self, objId):
48
49
49 if objId not in list(self.operations.keys()):
50 if objId not in list(self.operations.keys()):
50 return None
51 return None
51
52
52 return self.operations[objId]
53 return self.operations[objId]
53
54
54 def call(self, **kwargs):
55 def call(self, **kwargs):
55 '''
56 '''
56 '''
57 '''
57
58
58 try:
59 try:
59 if self.dataIn is not None and self.dataIn.flagNoData and not self.dataIn.error:
60 if self.dataIn is not None and self.dataIn.flagNoData and not self.dataIn.error:
60 return self.dataIn.isReady()
61 return self.dataIn.isReady()
61 elif self.dataIn is None or not self.dataIn.error:
62 elif self.dataIn is None or not self.dataIn.error:
62 self.run(**kwargs)
63 self.run(**kwargs)
63 elif self.dataIn.error:
64 elif self.dataIn.error:
64 self.dataOut.error = self.dataIn.error
65 self.dataOut.error = self.dataIn.error
65 self.dataOut.flagNoData = True
66 self.dataOut.flagNoData = True
66 except:
67 except:
68
67 err = traceback.format_exc()
69 err = traceback.format_exc()
68 if 'SchainWarning' in err:
70 if 'SchainWarning' in err:
69 log.warning(err.split('SchainWarning:')[-1].split('\n')[0].strip(), self.name)
71 log.warning(err.split('SchainWarning:')[-1].split('\n')[0].strip(), self.name)
70 elif 'SchainError' in err:
72 elif 'SchainError' in err:
71 log.error(err.split('SchainError:')[-1].split('\n')[0].strip(), self.name)
73 log.error(err.split('SchainError:')[-1].split('\n')[0].strip(), self.name)
72 else:
74 else:
73 log.error(err, self.name)
75 log.error(err, self.name)
74 self.dataOut.error = True
76 self.dataOut.error = True
75
77
76 for op, optype, opkwargs in self.operations:
78 for op, optype, opkwargs in self.operations:
77 if optype == 'other' and not self.dataOut.flagNoData:
79 if optype == 'other' and not self.dataOut.flagNoData:
78 self.dataOut = op.run(self.dataOut, **opkwargs)
80 self.dataOut = op.run(self.dataOut, **opkwargs)
79 elif optype == 'external' and not self.dataOut.flagNoData:
81 elif optype == 'external' and not self.dataOut.flagNoData:
80 op.queue.put(self.dataOut)
82 op.queue.put(self.dataOut)
81 elif optype == 'external' and self.dataOut.error:
83 elif optype == 'external' and self.dataOut.error:
82 op.queue.put(self.dataOut)
84 op.queue.put(self.dataOut)
83
85
84 return 'Error' if self.dataOut.error else self.dataOut.isReady()
86 return 'Error' if self.dataOut.error else self.dataOut.isReady()
85
87
86 def setup(self):
88 def setup(self):
87
89
88 raise NotImplementedError
90 raise NotImplementedError
89
91
90 def run(self):
92 def run(self):
91
93
92 raise NotImplementedError
94 raise NotImplementedError
93
95
94 def close(self):
96 def close(self):
95
97
96 return
98 return
97
99
98
100
99 class Operation(object):
101 class Operation(object):
100
102
101 '''
103 '''
102 '''
104 '''
103
105
104 proc_type = 'operation'
106 proc_type = 'operation'
105
107
106 def __init__(self):
108 def __init__(self):
107
109
108 self.id = None
110 self.id = None
109 self.isConfig = False
111 self.isConfig = False
110
112
111 if not hasattr(self, 'name'):
113 if not hasattr(self, 'name'):
112 self.name = self.__class__.__name__
114 self.name = self.__class__.__name__
113
115
114 def getAllowedArgs(self):
116 def getAllowedArgs(self):
115 if hasattr(self, '__attrs__'):
117 if hasattr(self, '__attrs__'):
116 return self.__attrs__
118 return self.__attrs__
117 else:
119 else:
118 return inspect.getargspec(self.run).args
120 return inspect.getargspec(self.run).args
119
121
120 def setup(self):
122 def setup(self):
121
123
122 self.isConfig = True
124 self.isConfig = True
123
125
124 raise NotImplementedError
126 raise NotImplementedError
125
127
126 def run(self, dataIn, **kwargs):
128 def run(self, dataIn, **kwargs):
127 """
129 """
128 Realiza las operaciones necesarias sobre la dataIn.data y actualiza los
130 Realiza las operaciones necesarias sobre la dataIn.data y actualiza los
129 atributos del objeto dataIn.
131 atributos del objeto dataIn.
130
132
131 Input:
133 Input:
132
134
133 dataIn : objeto del tipo JROData
135 dataIn : objeto del tipo JROData
134
136
135 Return:
137 Return:
136
138
137 None
139 None
138
140
139 Affected:
141 Affected:
140 __buffer : buffer de recepcion de datos.
142 __buffer : buffer de recepcion de datos.
141
143
142 """
144 """
143 if not self.isConfig:
145 if not self.isConfig:
144 self.setup(**kwargs)
146 self.setup(**kwargs)
145
147
146 raise NotImplementedError
148 raise NotImplementedError
147
149
148 def close(self):
150 def close(self):
149
151
150 return
152 return
151
153
152
154
153 def MPDecorator(BaseClass):
155 def MPDecorator(BaseClass):
154 """
156 """
155 Multiprocessing class decorator
157 Multiprocessing class decorator
156
158
157 This function add multiprocessing features to a BaseClass.
159 This function add multiprocessing features to a BaseClass.
158 """
160 """
159
161
160 class MPClass(BaseClass, Process):
162 class MPClass(BaseClass, Process):
161
163
162 def __init__(self, *args, **kwargs):
164 def __init__(self, *args, **kwargs):
163 super(MPClass, self).__init__()
165 super(MPClass, self).__init__()
164 Process.__init__(self)
166 Process.__init__(self)
165
167
166 self.args = args
168 self.args = args
167 self.kwargs = kwargs
169 self.kwargs = kwargs
168 self.t = time.time()
170 self.t = time.time()
169 self.op_type = 'external'
171 self.op_type = 'external'
170 self.name = BaseClass.__name__
172 self.name = BaseClass.__name__
171 self.__doc__ = BaseClass.__doc__
173 self.__doc__ = BaseClass.__doc__
172
174
173 if 'plot' in self.name.lower() and not self.name.endswith('_'):
175 if 'plot' in self.name.lower() and not self.name.endswith('_'):
174 self.name = '{}{}'.format(self.CODE.upper(), 'Plot')
176 self.name = '{}{}'.format(self.CODE.upper(), 'Plot')
175
177
176 self.start_time = time.time()
178 self.start_time = time.time()
177 #self.err_queue = args[2]
179 #self.err_queue = args[2]
178 self.queue = Queue(maxsize=1)
180 self.queue = Queue(maxsize=1)
179 self.myrun = BaseClass.run
181 self.myrun = BaseClass.run
180
182
181 def run(self):
183 def run(self):
182
184
183 while True:
185 while True:
184
186
185 dataOut = self.queue.get()
187 dataOut = self.queue.get()
186
188
187 if not dataOut.error:
189 if not dataOut.error:
188 try:
190 try:
189 BaseClass.run(self, dataOut, **self.kwargs)
191 BaseClass.run(self, dataOut, **self.kwargs)
190 except:
192 except:
191 err = traceback.format_exc()
193 err = traceback.format_exc()
192 log.error(err, self.name)
194 log.error(err, self.name)
193 else:
195 else:
194 break
196 break
195
197
196 self.close()
198 self.close()
197
199
198 def close(self):
200 def close(self):
199
201
200 BaseClass.close(self)
202 BaseClass.close(self)
201 log.success('Done...(Time:{:4.2f} secs)'.format(time.time()-self.start_time), self.name)
203 log.success('Done...(Time:{:4.2f} secs)'.format(time.time()-self.start_time), self.name)
202
204
203 return MPClass
205 return MPClass
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
@@ -1,1683 +1,1684
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 import math
15 import math
16
16
17 from schainpy.model.proc.jroproc_base import ProcessingUnit, MPDecorator, Operation
17 from schainpy.model.proc.jroproc_base import ProcessingUnit, MPDecorator, Operation
18 from schainpy.model.data.jrodata import Spectra
18 from schainpy.model.data.jrodata import Spectra
19 from schainpy.model.data.jrodata import hildebrand_sekhon
19 from schainpy.model.data.jrodata import hildebrand_sekhon
20 from schainpy.utils import log
20 from schainpy.utils import log
21
21
22 from scipy.optimize import curve_fit
22 from scipy.optimize import curve_fit
23
23 SPEED_OF_LIGHT = 299792458
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.id_min = None
35 self.id_min = None
36 self.id_max = None
36 self.id_max = None
37 self.setupReq = False #Agregar a todas las unidades de proc
37 self.setupReq = False #Agregar a todas las unidades de proc
38
38
39 def __updateSpecFromVoltage(self):
39 def __updateSpecFromVoltage(self):
40
40
41 self.dataOut.timeZone = self.dataIn.timeZone
41 self.dataOut.timeZone = self.dataIn.timeZone
42 self.dataOut.dstFlag = self.dataIn.dstFlag
42 self.dataOut.dstFlag = self.dataIn.dstFlag
43 self.dataOut.errorCount = self.dataIn.errorCount
43 self.dataOut.errorCount = self.dataIn.errorCount
44 self.dataOut.useLocalTime = self.dataIn.useLocalTime
44 self.dataOut.useLocalTime = self.dataIn.useLocalTime
45 try:
45 try:
46 self.dataOut.processingHeaderObj = self.dataIn.processingHeaderObj.copy()
46 self.dataOut.processingHeaderObj = self.dataIn.processingHeaderObj.copy()
47 except:
47 except:
48 pass
48 pass
49 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
49 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
50 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
50 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
51 self.dataOut.channelList = self.dataIn.channelList
51 self.dataOut.channelList = self.dataIn.channelList
52 self.dataOut.heightList = self.dataIn.heightList
52 self.dataOut.heightList = self.dataIn.heightList
53 self.dataOut.dtype = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
53 self.dataOut.dtype = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
54 self.dataOut.nProfiles = self.dataOut.nFFTPoints
54 self.dataOut.nProfiles = self.dataOut.nFFTPoints
55 self.dataOut.flagDiscontinuousBlock = self.dataIn.flagDiscontinuousBlock
55 self.dataOut.flagDiscontinuousBlock = self.dataIn.flagDiscontinuousBlock
56 self.dataOut.utctime = self.firstdatatime
56 self.dataOut.utctime = self.firstdatatime
57 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData
57 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData
58 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData
58 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData
59 self.dataOut.flagShiftFFT = False
59 self.dataOut.flagShiftFFT = False
60 self.dataOut.nCohInt = self.dataIn.nCohInt
60 self.dataOut.nCohInt = self.dataIn.nCohInt
61 self.dataOut.nIncohInt = 1
61 self.dataOut.nIncohInt = 1
62 self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
62 self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
63 self.dataOut.frequency = self.dataIn.frequency
63 self.dataOut.frequency = self.dataIn.frequency
64 self.dataOut.realtime = self.dataIn.realtime
64 self.dataOut.realtime = self.dataIn.realtime
65 self.dataOut.azimuth = self.dataIn.azimuth
65 self.dataOut.azimuth = self.dataIn.azimuth
66 self.dataOut.zenith = self.dataIn.zenith
66 self.dataOut.zenith = self.dataIn.zenith
67 self.dataOut.codeList = self.dataIn.codeList
67 self.dataOut.codeList = self.dataIn.codeList
68 self.dataOut.azimuthList = self.dataIn.azimuthList
68 self.dataOut.azimuthList = self.dataIn.azimuthList
69 self.dataOut.elevationList = self.dataIn.elevationList
69 self.dataOut.elevationList = self.dataIn.elevationList
70
70
71
72
71 def __getFft(self):
73 def __getFft(self):
72 """
74 """
73 Convierte valores de Voltaje a Spectra
75 Convierte valores de Voltaje a Spectra
74
76
75 Affected:
77 Affected:
76 self.dataOut.data_spc
78 self.dataOut.data_spc
77 self.dataOut.data_cspc
79 self.dataOut.data_cspc
78 self.dataOut.data_dc
80 self.dataOut.data_dc
79 self.dataOut.heightList
81 self.dataOut.heightList
80 self.profIndex
82 self.profIndex
81 self.buffer
83 self.buffer
82 self.dataOut.flagNoData
84 self.dataOut.flagNoData
83 """
85 """
84 fft_volt = numpy.fft.fft(
86 fft_volt = numpy.fft.fft(
85 self.buffer, n=self.dataOut.nFFTPoints, axis=1)
87 self.buffer, n=self.dataOut.nFFTPoints, axis=1)
86 fft_volt = fft_volt.astype(numpy.dtype('complex'))
88 fft_volt = fft_volt.astype(numpy.dtype('complex'))
87 dc = fft_volt[:, 0, :]
89 dc = fft_volt[:, 0, :]
88
90
89 # calculo de self-spectra
91 # calculo de self-spectra
90 fft_volt = numpy.fft.fftshift(fft_volt, axes=(1,))
92 fft_volt = numpy.fft.fftshift(fft_volt, axes=(1,))
91 spc = fft_volt * numpy.conjugate(fft_volt)
93 spc = fft_volt * numpy.conjugate(fft_volt)
92 spc = spc.real
94 spc = spc.real
93
95
94 blocksize = 0
96 blocksize = 0
95 blocksize += dc.size
97 blocksize += dc.size
96 blocksize += spc.size
98 blocksize += spc.size
97
99
98 cspc = None
100 cspc = None
99 pairIndex = 0
101 pairIndex = 0
100 if self.dataOut.pairsList != None:
102 if self.dataOut.pairsList != None:
101 # calculo de cross-spectra
103 # calculo de cross-spectra
102 cspc = numpy.zeros(
104 cspc = numpy.zeros(
103 (self.dataOut.nPairs, self.dataOut.nFFTPoints, self.dataOut.nHeights), dtype='complex')
105 (self.dataOut.nPairs, self.dataOut.nFFTPoints, self.dataOut.nHeights), dtype='complex')
104 for pair in self.dataOut.pairsList:
106 for pair in self.dataOut.pairsList:
105 if pair[0] not in self.dataOut.channelList:
107 if pair[0] not in self.dataOut.channelList:
106 raise ValueError("Error getting CrossSpectra: pair 0 of %s is not in channelList = %s" % (
108 raise ValueError("Error getting CrossSpectra: pair 0 of %s is not in channelList = %s" % (
107 str(pair), str(self.dataOut.channelList)))
109 str(pair), str(self.dataOut.channelList)))
108 if pair[1] not in self.dataOut.channelList:
110 if pair[1] not in self.dataOut.channelList:
109 raise ValueError("Error getting CrossSpectra: pair 1 of %s is not in channelList = %s" % (
111 raise ValueError("Error getting CrossSpectra: pair 1 of %s is not in channelList = %s" % (
110 str(pair), str(self.dataOut.channelList)))
112 str(pair), str(self.dataOut.channelList)))
111
113
112 cspc[pairIndex, :, :] = fft_volt[pair[0], :, :] * \
114 cspc[pairIndex, :, :] = fft_volt[pair[0], :, :] * \
113 numpy.conjugate(fft_volt[pair[1], :, :])
115 numpy.conjugate(fft_volt[pair[1], :, :])
114 pairIndex += 1
116 pairIndex += 1
115 blocksize += cspc.size
117 blocksize += cspc.size
116
118
117 self.dataOut.data_spc = spc
119 self.dataOut.data_spc = spc
118 self.dataOut.data_cspc = cspc
120 self.dataOut.data_cspc = cspc
119 self.dataOut.data_dc = dc
121 self.dataOut.data_dc = dc
120 self.dataOut.blockSize = blocksize
122 self.dataOut.blockSize = blocksize
121 self.dataOut.flagShiftFFT = False
123 self.dataOut.flagShiftFFT = False
122
124
123 def run(self, nProfiles=None, nFFTPoints=None, pairsList=None, ippFactor=None, shift_fft=False):
125 def run(self, nProfiles=None, nFFTPoints=None, pairsList=None, ippFactor=None, shift_fft=False):
124 #print("spectra run")
126
125 if self.dataIn.type == "Spectra":
127 if self.dataIn.type == "Spectra":
126 self.dataOut.copy(self.dataIn)
128 self.dataOut.copy(self.dataIn)
127 if shift_fft:
129 if shift_fft:
128 #desplaza a la derecha en el eje 2 determinadas posiciones
130 #desplaza a la derecha en el eje 2 determinadas posiciones
129 shift = int(self.dataOut.nFFTPoints/2)
131 shift = int(self.dataOut.nFFTPoints/2)
130 self.dataOut.data_spc = numpy.roll(self.dataOut.data_spc, shift , axis=1)
132 self.dataOut.data_spc = numpy.roll(self.dataOut.data_spc, shift , axis=1)
131
133
132 if self.dataOut.data_cspc is not None:
134 if self.dataOut.data_cspc is not None:
133 #desplaza a la derecha en el eje 2 determinadas posiciones
135 #desplaza a la derecha en el eje 2 determinadas posiciones
134 self.dataOut.data_cspc = numpy.roll(self.dataOut.data_cspc, shift, axis=1)
136 self.dataOut.data_cspc = numpy.roll(self.dataOut.data_cspc, shift, axis=1)
135 if pairsList:
137 if pairsList:
136 self.__selectPairs(pairsList)
138 self.__selectPairs(pairsList)
137
139
140
138 elif self.dataIn.type == "Voltage":
141 elif self.dataIn.type == "Voltage":
139
142
140 self.dataOut.flagNoData = True
143 self.dataOut.flagNoData = True
141
144
142 if nFFTPoints == None:
145 if nFFTPoints == None:
143 raise ValueError("This SpectraProc.run() need nFFTPoints input variable")
146 raise ValueError("This SpectraProc.run() need nFFTPoints input variable")
144
147
145 if nProfiles == None:
148 if nProfiles == None:
146 nProfiles = nFFTPoints
149 nProfiles = nFFTPoints
147
150
148 if ippFactor == None:
151 if ippFactor == None:
149 self.dataOut.ippFactor = 1
152 self.dataOut.ippFactor = 1
150
153
151 self.dataOut.nFFTPoints = nFFTPoints
154 self.dataOut.nFFTPoints = nFFTPoints
152
155
153 if self.buffer is None:
156 if self.buffer is None:
154 self.buffer = numpy.zeros((self.dataIn.nChannels,
157 self.buffer = numpy.zeros((self.dataIn.nChannels,
155 nProfiles,
158 nProfiles,
156 self.dataIn.nHeights),
159 self.dataIn.nHeights),
157 dtype='complex')
160 dtype='complex')
158
161
159 if self.dataIn.flagDataAsBlock:
162 if self.dataIn.flagDataAsBlock:
160 nVoltProfiles = self.dataIn.data.shape[1]
163 nVoltProfiles = self.dataIn.data.shape[1]
161
164
162 if nVoltProfiles == nProfiles:
165 if nVoltProfiles == nProfiles:
163 self.buffer = self.dataIn.data.copy()
166 self.buffer = self.dataIn.data.copy()
164 self.profIndex = nVoltProfiles
167 self.profIndex = nVoltProfiles
165
168
166 elif nVoltProfiles < nProfiles:
169 elif nVoltProfiles < nProfiles:
167
170
168 if self.profIndex == 0:
171 if self.profIndex == 0:
169 self.id_min = 0
172 self.id_min = 0
170 self.id_max = nVoltProfiles
173 self.id_max = nVoltProfiles
171
174
172 self.buffer[:, self.id_min:self.id_max,
175 self.buffer[:, self.id_min:self.id_max,
173 :] = self.dataIn.data
176 :] = self.dataIn.data
174 self.profIndex += nVoltProfiles
177 self.profIndex += nVoltProfiles
175 self.id_min += nVoltProfiles
178 self.id_min += nVoltProfiles
176 self.id_max += nVoltProfiles
179 self.id_max += nVoltProfiles
177 else:
180 else:
178 raise ValueError("The type object %s has %d profiles, it should just has %d profiles" % (
181 raise ValueError("The type object %s has %d profiles, it should just has %d profiles" % (
179 self.dataIn.type, self.dataIn.data.shape[1], nProfiles))
182 self.dataIn.type, self.dataIn.data.shape[1], nProfiles))
180 self.dataOut.flagNoData = True
183 self.dataOut.flagNoData = True
181 else:
184 else:
182 self.buffer[:, self.profIndex, :] = self.dataIn.data.copy()
185 self.buffer[:, self.profIndex, :] = self.dataIn.data.copy()
183 self.profIndex += 1
186 self.profIndex += 1
184
187
185 if self.firstdatatime == None:
188 if self.firstdatatime == None:
186 self.firstdatatime = self.dataIn.utctime
189 self.firstdatatime = self.dataIn.utctime
187
190
188 if self.profIndex == nProfiles:
191 if self.profIndex == nProfiles:
189 self.__updateSpecFromVoltage()
192 self.__updateSpecFromVoltage()
190 if pairsList == None:
193 if pairsList == None:
191 self.dataOut.pairsList = [pair for pair in itertools.combinations(self.dataOut.channelList, 2)]
194 self.dataOut.pairsList = [pair for pair in itertools.combinations(self.dataOut.channelList, 2)]
192 else:
195 else:
193 self.dataOut.pairsList = pairsList
196 self.dataOut.pairsList = pairsList
194 self.__getFft()
197 self.__getFft()
195 self.dataOut.flagNoData = False
198 self.dataOut.flagNoData = False
196 self.firstdatatime = None
199 self.firstdatatime = None
197 self.profIndex = 0
200 self.profIndex = 0
198 else:
201 else:
199 raise ValueError("The type of input object '%s' is not valid".format(
202 raise ValueError("The type of input object '%s' is not valid".format(
200 self.dataIn.type))
203 self.dataIn.type))
201
204
202 def __selectPairs(self, pairsList):
205 def __selectPairs(self, pairsList):
203
206
204 if not pairsList:
207 if not pairsList:
205 return
208 return
206
209
207 pairs = []
210 pairs = []
208 pairsIndex = []
211 pairsIndex = []
209
212
210 for pair in pairsList:
213 for pair in pairsList:
211 if pair[0] not in self.dataOut.channelList or pair[1] not in self.dataOut.channelList:
214 if pair[0] not in self.dataOut.channelList or pair[1] not in self.dataOut.channelList:
212 continue
215 continue
213 pairs.append(pair)
216 pairs.append(pair)
214 pairsIndex.append(pairs.index(pair))
217 pairsIndex.append(pairs.index(pair))
215
218
216 self.dataOut.data_cspc = self.dataOut.data_cspc[pairsIndex]
219 self.dataOut.data_cspc = self.dataOut.data_cspc[pairsIndex]
217 self.dataOut.pairsList = pairs
220 self.dataOut.pairsList = pairs
218
221
219 return
222 return
220
223
221 def selectFFTs(self, minFFT, maxFFT ):
224 def selectFFTs(self, minFFT, maxFFT ):
222 """
225 """
223 Selecciona un bloque de datos en base a un grupo de valores de puntos FFTs segun el rango
226 Selecciona un bloque de datos en base a un grupo de valores de puntos FFTs segun el rango
224 minFFT<= FFT <= maxFFT
227 minFFT<= FFT <= maxFFT
225 """
228 """
226
229
227 if (minFFT > maxFFT):
230 if (minFFT > maxFFT):
228 raise ValueError("Error selecting heights: Height range (%d,%d) is not valid" % (minFFT, maxFFT))
231 raise ValueError("Error selecting heights: Height range (%d,%d) is not valid" % (minFFT, maxFFT))
229
232
230 if (minFFT < self.dataOut.getFreqRange()[0]):
233 if (minFFT < self.dataOut.getFreqRange()[0]):
231 minFFT = self.dataOut.getFreqRange()[0]
234 minFFT = self.dataOut.getFreqRange()[0]
232
235
233 if (maxFFT > self.dataOut.getFreqRange()[-1]):
236 if (maxFFT > self.dataOut.getFreqRange()[-1]):
234 maxFFT = self.dataOut.getFreqRange()[-1]
237 maxFFT = self.dataOut.getFreqRange()[-1]
235
238
236 minIndex = 0
239 minIndex = 0
237 maxIndex = 0
240 maxIndex = 0
238 FFTs = self.dataOut.getFreqRange()
241 FFTs = self.dataOut.getFreqRange()
239
242
240 inda = numpy.where(FFTs >= minFFT)
243 inda = numpy.where(FFTs >= minFFT)
241 indb = numpy.where(FFTs <= maxFFT)
244 indb = numpy.where(FFTs <= maxFFT)
242
245
243 try:
246 try:
244 minIndex = inda[0][0]
247 minIndex = inda[0][0]
245 except:
248 except:
246 minIndex = 0
249 minIndex = 0
247
250
248 try:
251 try:
249 maxIndex = indb[0][-1]
252 maxIndex = indb[0][-1]
250 except:
253 except:
251 maxIndex = len(FFTs)
254 maxIndex = len(FFTs)
252
255
253 self.selectFFTsByIndex(minIndex, maxIndex)
256 self.selectFFTsByIndex(minIndex, maxIndex)
254
257
255 return 1
258 return 1
256
259
257 def getBeaconSignal(self, tauindex=0, channelindex=0, hei_ref=None):
260 def getBeaconSignal(self, tauindex=0, channelindex=0, hei_ref=None):
258 newheis = numpy.where(
261 newheis = numpy.where(
259 self.dataOut.heightList > self.dataOut.radarControllerHeaderObj.Taus[tauindex])
262 self.dataOut.heightList > self.dataOut.radarControllerHeaderObj.Taus[tauindex])
260
263
261 if hei_ref != None:
264 if hei_ref != None:
262 newheis = numpy.where(self.dataOut.heightList > hei_ref)
265 newheis = numpy.where(self.dataOut.heightList > hei_ref)
263
266
264 minIndex = min(newheis[0])
267 minIndex = min(newheis[0])
265 maxIndex = max(newheis[0])
268 maxIndex = max(newheis[0])
266 data_spc = self.dataOut.data_spc[:, :, minIndex:maxIndex + 1]
269 data_spc = self.dataOut.data_spc[:, :, minIndex:maxIndex + 1]
267 heightList = self.dataOut.heightList[minIndex:maxIndex + 1]
270 heightList = self.dataOut.heightList[minIndex:maxIndex + 1]
268
271
269 # determina indices
272 # determina indices
270 nheis = int(self.dataOut.radarControllerHeaderObj.txB /
273 nheis = int(self.dataOut.radarControllerHeaderObj.txB /
271 (self.dataOut.heightList[1] - self.dataOut.heightList[0]))
274 (self.dataOut.heightList[1] - self.dataOut.heightList[0]))
272 avg_dB = 10 * \
275 avg_dB = 10 * \
273 numpy.log10(numpy.sum(data_spc[channelindex, :, :], axis=0))
276 numpy.log10(numpy.sum(data_spc[channelindex, :, :], axis=0))
274 beacon_dB = numpy.sort(avg_dB)[-nheis:]
277 beacon_dB = numpy.sort(avg_dB)[-nheis:]
275 beacon_heiIndexList = []
278 beacon_heiIndexList = []
276 for val in avg_dB.tolist():
279 for val in avg_dB.tolist():
277 if val >= beacon_dB[0]:
280 if val >= beacon_dB[0]:
278 beacon_heiIndexList.append(avg_dB.tolist().index(val))
281 beacon_heiIndexList.append(avg_dB.tolist().index(val))
279
282
280 #data_spc = data_spc[:,:,beacon_heiIndexList]
283 #data_spc = data_spc[:,:,beacon_heiIndexList]
281 data_cspc = None
284 data_cspc = None
282 if self.dataOut.data_cspc is not None:
285 if self.dataOut.data_cspc is not None:
283 data_cspc = self.dataOut.data_cspc[:, :, minIndex:maxIndex + 1]
286 data_cspc = self.dataOut.data_cspc[:, :, minIndex:maxIndex + 1]
284 #data_cspc = data_cspc[:,:,beacon_heiIndexList]
287 #data_cspc = data_cspc[:,:,beacon_heiIndexList]
285
288
286 data_dc = None
289 data_dc = None
287 if self.dataOut.data_dc is not None:
290 if self.dataOut.data_dc is not None:
288 data_dc = self.dataOut.data_dc[:, minIndex:maxIndex + 1]
291 data_dc = self.dataOut.data_dc[:, minIndex:maxIndex + 1]
289 #data_dc = data_dc[:,beacon_heiIndexList]
292 #data_dc = data_dc[:,beacon_heiIndexList]
290
293
291 self.dataOut.data_spc = data_spc
294 self.dataOut.data_spc = data_spc
292 self.dataOut.data_cspc = data_cspc
295 self.dataOut.data_cspc = data_cspc
293 self.dataOut.data_dc = data_dc
296 self.dataOut.data_dc = data_dc
294 self.dataOut.heightList = heightList
297 self.dataOut.heightList = heightList
295 self.dataOut.beacon_heiIndexList = beacon_heiIndexList
298 self.dataOut.beacon_heiIndexList = beacon_heiIndexList
296
299
297 return 1
300 return 1
298
301
299 def selectFFTsByIndex(self, minIndex, maxIndex):
302 def selectFFTsByIndex(self, minIndex, maxIndex):
300 """
303 """
301
304
302 """
305 """
303
306
304 if (minIndex < 0) or (minIndex > maxIndex):
307 if (minIndex < 0) or (minIndex > maxIndex):
305 raise ValueError("Error selecting heights: Index range (%d,%d) is not valid" % (minIndex, maxIndex))
308 raise ValueError("Error selecting heights: Index range (%d,%d) is not valid" % (minIndex, maxIndex))
306
309
307 if (maxIndex >= self.dataOut.nProfiles):
310 if (maxIndex >= self.dataOut.nProfiles):
308 maxIndex = self.dataOut.nProfiles-1
311 maxIndex = self.dataOut.nProfiles-1
309
312
310 #Spectra
313 #Spectra
311 data_spc = self.dataOut.data_spc[:,minIndex:maxIndex+1,:]
314 data_spc = self.dataOut.data_spc[:,minIndex:maxIndex+1,:]
312
315
313 data_cspc = None
316 data_cspc = None
314 if self.dataOut.data_cspc is not None:
317 if self.dataOut.data_cspc is not None:
315 data_cspc = self.dataOut.data_cspc[:,minIndex:maxIndex+1,:]
318 data_cspc = self.dataOut.data_cspc[:,minIndex:maxIndex+1,:]
316
319
317 data_dc = None
320 data_dc = None
318 if self.dataOut.data_dc is not None:
321 if self.dataOut.data_dc is not None:
319 data_dc = self.dataOut.data_dc[minIndex:maxIndex+1,:]
322 data_dc = self.dataOut.data_dc[minIndex:maxIndex+1,:]
320
323
321 self.dataOut.data_spc = data_spc
324 self.dataOut.data_spc = data_spc
322 self.dataOut.data_cspc = data_cspc
325 self.dataOut.data_cspc = data_cspc
323 self.dataOut.data_dc = data_dc
326 self.dataOut.data_dc = data_dc
324
327
325 self.dataOut.ippSeconds = self.dataOut.ippSeconds*(self.dataOut.nFFTPoints / numpy.shape(data_cspc)[1])
328 self.dataOut.ippSeconds = self.dataOut.ippSeconds*(self.dataOut.nFFTPoints / numpy.shape(data_cspc)[1])
326 self.dataOut.nFFTPoints = numpy.shape(data_cspc)[1]
329 self.dataOut.nFFTPoints = numpy.shape(data_cspc)[1]
327 self.dataOut.profilesPerBlock = numpy.shape(data_cspc)[1]
330 self.dataOut.profilesPerBlock = numpy.shape(data_cspc)[1]
328
331
329 return 1
332 return 1
330
333
331 def getNoise(self, minHei=None, maxHei=None, minVel=None, maxVel=None):
334 def getNoise(self, minHei=None, maxHei=None, minVel=None, maxVel=None):
332 # validacion de rango
335 # validacion de rango
333 if minHei == None:
336 if minHei == None:
334 minHei = self.dataOut.heightList[0]
337 minHei = self.dataOut.heightList[0]
335
338
336 if maxHei == None:
339 if maxHei == None:
337 maxHei = self.dataOut.heightList[-1]
340 maxHei = self.dataOut.heightList[-1]
338
341
339 if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei):
342 if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei):
340 print('minHei: %.2f is out of the heights range' % (minHei))
343 print('minHei: %.2f is out of the heights range' % (minHei))
341 print('minHei is setting to %.2f' % (self.dataOut.heightList[0]))
344 print('minHei is setting to %.2f' % (self.dataOut.heightList[0]))
342 minHei = self.dataOut.heightList[0]
345 minHei = self.dataOut.heightList[0]
343
346
344 if (maxHei > self.dataOut.heightList[-1]) or (maxHei < minHei):
347 if (maxHei > self.dataOut.heightList[-1]) or (maxHei < minHei):
345 print('maxHei: %.2f is out of the heights range' % (maxHei))
348 print('maxHei: %.2f is out of the heights range' % (maxHei))
346 print('maxHei is setting to %.2f' % (self.dataOut.heightList[-1]))
349 print('maxHei is setting to %.2f' % (self.dataOut.heightList[-1]))
347 maxHei = self.dataOut.heightList[-1]
350 maxHei = self.dataOut.heightList[-1]
348
351
349 # validacion de velocidades
352 # validacion de velocidades
350 velrange = self.dataOut.getVelRange(1)
353 velrange = self.dataOut.getVelRange(1)
351
354
352 if minVel == None:
355 if minVel == None:
353 minVel = velrange[0]
356 minVel = velrange[0]
354
357
355 if maxVel == None:
358 if maxVel == None:
356 maxVel = velrange[-1]
359 maxVel = velrange[-1]
357
360
358 if (minVel < velrange[0]) or (minVel > maxVel):
361 if (minVel < velrange[0]) or (minVel > maxVel):
359 print('minVel: %.2f is out of the velocity range' % (minVel))
362 print('minVel: %.2f is out of the velocity range' % (minVel))
360 print('minVel is setting to %.2f' % (velrange[0]))
363 print('minVel is setting to %.2f' % (velrange[0]))
361 minVel = velrange[0]
364 minVel = velrange[0]
362
365
363 if (maxVel > velrange[-1]) or (maxVel < minVel):
366 if (maxVel > velrange[-1]) or (maxVel < minVel):
364 print('maxVel: %.2f is out of the velocity range' % (maxVel))
367 print('maxVel: %.2f is out of the velocity range' % (maxVel))
365 print('maxVel is setting to %.2f' % (velrange[-1]))
368 print('maxVel is setting to %.2f' % (velrange[-1]))
366 maxVel = velrange[-1]
369 maxVel = velrange[-1]
367
370
368 # seleccion de indices para rango
371 # seleccion de indices para rango
369 minIndex = 0
372 minIndex = 0
370 maxIndex = 0
373 maxIndex = 0
371 heights = self.dataOut.heightList
374 heights = self.dataOut.heightList
372
375
373 inda = numpy.where(heights >= minHei)
376 inda = numpy.where(heights >= minHei)
374 indb = numpy.where(heights <= maxHei)
377 indb = numpy.where(heights <= maxHei)
375
378
376 try:
379 try:
377 minIndex = inda[0][0]
380 minIndex = inda[0][0]
378 except:
381 except:
379 minIndex = 0
382 minIndex = 0
380
383
381 try:
384 try:
382 maxIndex = indb[0][-1]
385 maxIndex = indb[0][-1]
383 except:
386 except:
384 maxIndex = len(heights)
387 maxIndex = len(heights)
385
388
386 if (minIndex < 0) or (minIndex > maxIndex):
389 if (minIndex < 0) or (minIndex > maxIndex):
387 raise ValueError("some value in (%d,%d) is not valid" % (
390 raise ValueError("some value in (%d,%d) is not valid" % (
388 minIndex, maxIndex))
391 minIndex, maxIndex))
389
392
390 if (maxIndex >= self.dataOut.nHeights):
393 if (maxIndex >= self.dataOut.nHeights):
391 maxIndex = self.dataOut.nHeights - 1
394 maxIndex = self.dataOut.nHeights - 1
392
395
393 # seleccion de indices para velocidades
396 # seleccion de indices para velocidades
394 indminvel = numpy.where(velrange >= minVel)
397 indminvel = numpy.where(velrange >= minVel)
395 indmaxvel = numpy.where(velrange <= maxVel)
398 indmaxvel = numpy.where(velrange <= maxVel)
396 try:
399 try:
397 minIndexVel = indminvel[0][0]
400 minIndexVel = indminvel[0][0]
398 except:
401 except:
399 minIndexVel = 0
402 minIndexVel = 0
400
403
401 try:
404 try:
402 maxIndexVel = indmaxvel[0][-1]
405 maxIndexVel = indmaxvel[0][-1]
403 except:
406 except:
404 maxIndexVel = len(velrange)
407 maxIndexVel = len(velrange)
405
408
406 # seleccion del espectro
409 # seleccion del espectro
407 data_spc = self.dataOut.data_spc[:,
410 data_spc = self.dataOut.data_spc[:,
408 minIndexVel:maxIndexVel + 1, minIndex:maxIndex + 1]
411 minIndexVel:maxIndexVel + 1, minIndex:maxIndex + 1]
409 # estimacion de ruido
412 # estimacion de ruido
410 noise = numpy.zeros(self.dataOut.nChannels)
413 noise = numpy.zeros(self.dataOut.nChannels)
411
414
412 for channel in range(self.dataOut.nChannels):
415 for channel in range(self.dataOut.nChannels):
413 daux = data_spc[channel, :, :]
416 daux = data_spc[channel, :, :]
414 sortdata = numpy.sort(daux, axis=None)
417 sortdata = numpy.sort(daux, axis=None)
415 noise[channel] = hildebrand_sekhon(sortdata, self.dataOut.nIncohInt)
418 noise[channel] = hildebrand_sekhon(sortdata, self.dataOut.nIncohInt)
416
419
417 self.dataOut.noise_estimation = noise.copy()
420 self.dataOut.noise_estimation = noise.copy()
418
421
419 return 1
422 return 1
420
423
421 class removeDC(Operation):
424 class removeDC(Operation):
422
425
423 def run(self, dataOut, mode=2):
426 def run(self, dataOut, mode=2):
424 self.dataOut = dataOut
427 self.dataOut = dataOut
425 jspectra = self.dataOut.data_spc
428 jspectra = self.dataOut.data_spc
426 jcspectra = self.dataOut.data_cspc
429 jcspectra = self.dataOut.data_cspc
427
430
428 num_chan = jspectra.shape[0]
431 num_chan = jspectra.shape[0]
429 num_hei = jspectra.shape[2]
432 num_hei = jspectra.shape[2]
430
433
431 if jcspectra is not None:
434 if jcspectra is not None:
432 jcspectraExist = True
435 jcspectraExist = True
433 num_pairs = jcspectra.shape[0]
436 num_pairs = jcspectra.shape[0]
434 else:
437 else:
435 jcspectraExist = False
438 jcspectraExist = False
436
439
437 freq_dc = int(jspectra.shape[1] / 2)
440 freq_dc = int(jspectra.shape[1] / 2)
438 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
441 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
439 ind_vel = ind_vel.astype(int)
442 ind_vel = ind_vel.astype(int)
440
443
441 if ind_vel[0] < 0:
444 if ind_vel[0] < 0:
442 ind_vel[list(range(0, 1))] = ind_vel[list(range(0, 1))] + self.num_prof
445 ind_vel[list(range(0, 1))] = ind_vel[list(range(0, 1))] + self.num_prof
443
446
444 if mode == 1:
447 if mode == 1:
445 jspectra[:, freq_dc, :] = (
448 jspectra[:, freq_dc, :] = (
446 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
449 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
447
450
448 if jcspectraExist:
451 if jcspectraExist:
449 jcspectra[:, freq_dc, :] = (
452 jcspectra[:, freq_dc, :] = (
450 jcspectra[:, ind_vel[1], :] + jcspectra[:, ind_vel[2], :]) / 2
453 jcspectra[:, ind_vel[1], :] + jcspectra[:, ind_vel[2], :]) / 2
451
454
452 if mode == 2:
455 if mode == 2:
453
456
454 vel = numpy.array([-2, -1, 1, 2])
457 vel = numpy.array([-2, -1, 1, 2])
455 xx = numpy.zeros([4, 4])
458 xx = numpy.zeros([4, 4])
456
459
457 for fil in range(4):
460 for fil in range(4):
458 xx[fil, :] = vel[fil]**numpy.asarray(list(range(4)))
461 xx[fil, :] = vel[fil]**numpy.asarray(list(range(4)))
459
462
460 xx_inv = numpy.linalg.inv(xx)
463 xx_inv = numpy.linalg.inv(xx)
461 xx_aux = xx_inv[0, :]
464 xx_aux = xx_inv[0, :]
462
465
463 for ich in range(num_chan):
466 for ich in range(num_chan):
464 yy = jspectra[ich, ind_vel, :]
467 yy = jspectra[ich, ind_vel, :]
465 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
468 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
466
469
467 junkid = jspectra[ich, freq_dc, :] <= 0
470 junkid = jspectra[ich, freq_dc, :] <= 0
468 cjunkid = sum(junkid)
471 cjunkid = sum(junkid)
469
472
470 if cjunkid.any():
473 if cjunkid.any():
471 jspectra[ich, freq_dc, junkid.nonzero()] = (
474 jspectra[ich, freq_dc, junkid.nonzero()] = (
472 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
475 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
473
476
474 if jcspectraExist:
477 if jcspectraExist:
475 for ip in range(num_pairs):
478 for ip in range(num_pairs):
476 yy = jcspectra[ip, ind_vel, :]
479 yy = jcspectra[ip, ind_vel, :]
477 jcspectra[ip, freq_dc, :] = numpy.dot(xx_aux, yy)
480 jcspectra[ip, freq_dc, :] = numpy.dot(xx_aux, yy)
478
481
479 self.dataOut.data_spc = jspectra
482 self.dataOut.data_spc = jspectra
480 self.dataOut.data_cspc = jcspectra
483 self.dataOut.data_cspc = jcspectra
481
484
482 return self.dataOut
485 return self.dataOut
483
486
484 # import matplotlib.pyplot as plt
487 # import matplotlib.pyplot as plt
485
488
486 def fit_func( x, a0, a1, a2): #, a3, a4, a5):
489 def fit_func( x, a0, a1, a2): #, a3, a4, a5):
487 z = (x - a1) / a2
490 z = (x - a1) / a2
488 y = a0 * numpy.exp(-z**2 / a2) #+ a3 + a4 * x + a5 * x**2
491 y = a0 * numpy.exp(-z**2 / a2) #+ a3 + a4 * x + a5 * x**2
489 return y
492 return y
490
493
491
494
492 class CleanRayleigh(Operation):
495 class CleanRayleigh(Operation):
493
496
494 def __init__(self):
497 def __init__(self):
495
498
496 Operation.__init__(self)
499 Operation.__init__(self)
497 self.i=0
500 self.i=0
498 self.isConfig = False
501 self.isConfig = False
499 self.__dataReady = False
502 self.__dataReady = False
500 self.__profIndex = 0
503 self.__profIndex = 0
501 self.byTime = False
504 self.byTime = False
502 self.byProfiles = False
505 self.byProfiles = False
503
506
504 self.bloques = None
507 self.bloques = None
505 self.bloque0 = None
508 self.bloque0 = None
506
509
507 self.index = 0
510 self.index = 0
508
511
509 self.buffer = 0
512 self.buffer = 0
510 self.buffer2 = 0
513 self.buffer2 = 0
511 self.buffer3 = 0
514 self.buffer3 = 0
512
515
513
516
514 def setup(self,dataOut,min_hei,max_hei,n, timeInterval,factor_stdv):
517 def setup(self,dataOut,min_hei,max_hei,n, timeInterval,factor_stdv):
515
518
516 self.nChannels = dataOut.nChannels
519 self.nChannels = dataOut.nChannels
517 self.nProf = dataOut.nProfiles
520 self.nProf = dataOut.nProfiles
518 self.nPairs = dataOut.data_cspc.shape[0]
521 self.nPairs = dataOut.data_cspc.shape[0]
519 self.pairsArray = numpy.array(dataOut.pairsList)
522 self.pairsArray = numpy.array(dataOut.pairsList)
520 self.spectra = dataOut.data_spc
523 self.spectra = dataOut.data_spc
521 self.cspectra = dataOut.data_cspc
524 self.cspectra = dataOut.data_cspc
522 self.heights = dataOut.heightList #alturas totales
525 self.heights = dataOut.heightList #alturas totales
523 self.nHeights = len(self.heights)
526 self.nHeights = len(self.heights)
524 self.min_hei = min_hei
527 self.min_hei = min_hei
525 self.max_hei = max_hei
528 self.max_hei = max_hei
526 if (self.min_hei == None):
529 if (self.min_hei == None):
527 self.min_hei = 0
530 self.min_hei = 0
528 if (self.max_hei == None):
531 if (self.max_hei == None):
529 self.max_hei = dataOut.heightList[-1]
532 self.max_hei = dataOut.heightList[-1]
530 self.hval = ((self.max_hei>=self.heights) & (self.heights >= self.min_hei)).nonzero()
533 self.hval = ((self.max_hei>=self.heights) & (self.heights >= self.min_hei)).nonzero()
531 self.heightsClean = self.heights[self.hval] #alturas filtradas
534 self.heightsClean = self.heights[self.hval] #alturas filtradas
532 self.hval = self.hval[0] # forma (N,), an solo N elementos -> Indices de alturas
535 self.hval = self.hval[0] # forma (N,), an solo N elementos -> Indices de alturas
533 self.nHeightsClean = len(self.heightsClean)
536 self.nHeightsClean = len(self.heightsClean)
534 self.channels = dataOut.channelList
537 self.channels = dataOut.channelList
535 self.nChan = len(self.channels)
538 self.nChan = len(self.channels)
536 self.nIncohInt = dataOut.nIncohInt
539 self.nIncohInt = dataOut.nIncohInt
537 self.__initime = dataOut.utctime
540 self.__initime = dataOut.utctime
538 self.maxAltInd = self.hval[-1]+1
541 self.maxAltInd = self.hval[-1]+1
539 self.minAltInd = self.hval[0]
542 self.minAltInd = self.hval[0]
540
543
541 self.crosspairs = dataOut.pairsList
544 self.crosspairs = dataOut.pairsList
542 self.nPairs = len(self.crosspairs)
545 self.nPairs = len(self.crosspairs)
543 self.normFactor = dataOut.normFactor
546 self.normFactor = dataOut.normFactor
544 self.nFFTPoints = dataOut.nFFTPoints
547 self.nFFTPoints = dataOut.nFFTPoints
545 self.ippSeconds = dataOut.ippSeconds
548 self.ippSeconds = dataOut.ippSeconds
546 self.currentTime = self.__initime
549 self.currentTime = self.__initime
547 self.pairsArray = numpy.array(dataOut.pairsList)
550 self.pairsArray = numpy.array(dataOut.pairsList)
548 self.factor_stdv = factor_stdv
551 self.factor_stdv = factor_stdv
549 #print("CHANNELS: ",[x for x in self.channels])
550
552
551 if n != None :
553 if n != None :
552 self.byProfiles = True
554 self.byProfiles = True
553 self.nIntProfiles = n
555 self.nIntProfiles = n
554 else:
556 else:
555 self.__integrationtime = timeInterval
557 self.__integrationtime = timeInterval
556
558
557 self.__dataReady = False
559 self.__dataReady = False
558 self.isConfig = True
560 self.isConfig = True
559
561
560
562
561
563
562 def run(self, dataOut,min_hei=None,max_hei=None, n=None, timeInterval=10,factor_stdv=2.5):
564 def run(self, dataOut,min_hei=None,max_hei=None, n=None, timeInterval=10,factor_stdv=2.5):
563 #print (dataOut.utctime)
565
564 if not self.isConfig :
566 if not self.isConfig :
565 #print("Setting config")
567
566 self.setup(dataOut, min_hei,max_hei,n,timeInterval,factor_stdv)
568 self.setup(dataOut, min_hei,max_hei,n,timeInterval,factor_stdv)
567 #print("Config Done")
569
568 tini=dataOut.utctime
570 tini=dataOut.utctime
569
571
570 if self.byProfiles:
572 if self.byProfiles:
571 if self.__profIndex == self.nIntProfiles:
573 if self.__profIndex == self.nIntProfiles:
572 self.__dataReady = True
574 self.__dataReady = True
573 else:
575 else:
574 if (tini - self.__initime) >= self.__integrationtime:
576 if (tini - self.__initime) >= self.__integrationtime:
575 #print(tini - self.__initime,self.__profIndex)
577
576 self.__dataReady = True
578 self.__dataReady = True
577 self.__initime = tini
579 self.__initime = tini
578
580
579 #if (tini.tm_min % 2) == 0 and (tini.tm_sec < 5 and self.fint==0):
581 #if (tini.tm_min % 2) == 0 and (tini.tm_sec < 5 and self.fint==0):
580
582
581 if self.__dataReady:
583 if self.__dataReady:
582 #print("Data ready",self.__profIndex)
584
583 self.__profIndex = 0
585 self.__profIndex = 0
584 jspc = self.buffer
586 jspc = self.buffer
585 jcspc = self.buffer2
587 jcspc = self.buffer2
586 #jnoise = self.buffer3
588 #jnoise = self.buffer3
587 self.buffer = dataOut.data_spc
589 self.buffer = dataOut.data_spc
588 self.buffer2 = dataOut.data_cspc
590 self.buffer2 = dataOut.data_cspc
589 #self.buffer3 = dataOut.noise
591 #self.buffer3 = dataOut.noise
590 self.currentTime = dataOut.utctime
592 self.currentTime = dataOut.utctime
591 if numpy.any(jspc) :
593 if numpy.any(jspc) :
592 #print( jspc.shape, jcspc.shape)
594 #print( jspc.shape, jcspc.shape)
593 jspc = numpy.reshape(jspc,(int(len(jspc)/self.nChannels),self.nChannels,self.nFFTPoints,self.nHeights))
595 jspc = numpy.reshape(jspc,(int(len(jspc)/self.nChannels),self.nChannels,self.nFFTPoints,self.nHeights))
594 jcspc= numpy.reshape(jcspc,(int(len(jcspc)/self.nPairs),self.nPairs,self.nFFTPoints,self.nHeights))
596 jcspc= numpy.reshape(jcspc,(int(len(jcspc)/self.nPairs),self.nPairs,self.nFFTPoints,self.nHeights))
595 self.__dataReady = False
597 self.__dataReady = False
596 #print( jspc.shape, jcspc.shape)
598 #print( jspc.shape, jcspc.shape)
597 dataOut.flagNoData = False
599 dataOut.flagNoData = False
598 else:
600 else:
599 dataOut.flagNoData = True
601 dataOut.flagNoData = True
600 self.__dataReady = False
602 self.__dataReady = False
601 return dataOut
603 return dataOut
602 else:
604 else:
603 #print( len(self.buffer))
605 #print( len(self.buffer))
604 if numpy.any(self.buffer):
606 if numpy.any(self.buffer):
605 self.buffer = numpy.concatenate((self.buffer,dataOut.data_spc), axis=0)
607 self.buffer = numpy.concatenate((self.buffer,dataOut.data_spc), axis=0)
606 self.buffer2 = numpy.concatenate((self.buffer2,dataOut.data_cspc), axis=0)
608 self.buffer2 = numpy.concatenate((self.buffer2,dataOut.data_cspc), axis=0)
607 self.buffer3 += dataOut.data_dc
609 self.buffer3 += dataOut.data_dc
608 else:
610 else:
609 self.buffer = dataOut.data_spc
611 self.buffer = dataOut.data_spc
610 self.buffer2 = dataOut.data_cspc
612 self.buffer2 = dataOut.data_cspc
611 self.buffer3 = dataOut.data_dc
613 self.buffer3 = dataOut.data_dc
612 #print self.index, self.fint
614 #print self.index, self.fint
613 #print self.buffer2.shape
615 #print self.buffer2.shape
614 dataOut.flagNoData = True ## NOTE: ?? revisar LUEGO
616 dataOut.flagNoData = True ## NOTE: ?? revisar LUEGO
615 self.__profIndex += 1
617 self.__profIndex += 1
616 return dataOut ## NOTE: REV
618 return dataOut ## NOTE: REV
617
619
618
620
619 #index = tini.tm_hour*12+tini.tm_min/5
621 #index = tini.tm_hour*12+tini.tm_min/5
620 '''REVISAR'''
622 '''REVISAR'''
621 # jspc = jspc/self.nFFTPoints/self.normFactor
623 # jspc = jspc/self.nFFTPoints/self.normFactor
622 # jcspc = jcspc/self.nFFTPoints/self.normFactor
624 # jcspc = jcspc/self.nFFTPoints/self.normFactor
623
625
624
626
625
627
626 tmp_spectra,tmp_cspectra = self.cleanRayleigh(dataOut,jspc,jcspc,self.factor_stdv)
628 tmp_spectra,tmp_cspectra = self.cleanRayleigh(dataOut,jspc,jcspc,self.factor_stdv)
627 dataOut.data_spc = tmp_spectra
629 dataOut.data_spc = tmp_spectra
628 dataOut.data_cspc = tmp_cspectra
630 dataOut.data_cspc = tmp_cspectra
629
631
630 #dataOut.data_spc,dataOut.data_cspc = self.cleanRayleigh(dataOut,jspc,jcspc,self.factor_stdv)
632 #dataOut.data_spc,dataOut.data_cspc = self.cleanRayleigh(dataOut,jspc,jcspc,self.factor_stdv)
631
633
632 dataOut.data_dc = self.buffer3
634 dataOut.data_dc = self.buffer3
633 dataOut.nIncohInt *= self.nIntProfiles
635 dataOut.nIncohInt *= self.nIntProfiles
634 dataOut.utctime = self.currentTime #tiempo promediado
636 dataOut.utctime = self.currentTime #tiempo promediado
635 #print("Time: ",time.localtime(dataOut.utctime))
637 #print("Time: ",time.localtime(dataOut.utctime))
636 # dataOut.data_spc = sat_spectra
638 # dataOut.data_spc = sat_spectra
637 # dataOut.data_cspc = sat_cspectra
639 # dataOut.data_cspc = sat_cspectra
638 self.buffer = 0
640 self.buffer = 0
639 self.buffer2 = 0
641 self.buffer2 = 0
640 self.buffer3 = 0
642 self.buffer3 = 0
641
643
642 return dataOut
644 return dataOut
643
645
644 def cleanRayleigh(self,dataOut,spectra,cspectra,factor_stdv):
646 def cleanRayleigh(self,dataOut,spectra,cspectra,factor_stdv):
645 #print("OP cleanRayleigh")
647 #print("OP cleanRayleigh")
646 #import matplotlib.pyplot as plt
648 #import matplotlib.pyplot as plt
647 #for k in range(149):
649 #for k in range(149):
648 #channelsProcssd = []
650 #channelsProcssd = []
649 #channelA_ok = False
651 #channelA_ok = False
650 #rfunc = cspectra.copy() #self.bloques
652 #rfunc = cspectra.copy() #self.bloques
651 rfunc = spectra.copy()
653 rfunc = spectra.copy()
652 #rfunc = cspectra
654 #rfunc = cspectra
653 #val_spc = spectra*0.0 #self.bloque0*0.0
655 #val_spc = spectra*0.0 #self.bloque0*0.0
654 #val_cspc = cspectra*0.0 #self.bloques*0.0
656 #val_cspc = cspectra*0.0 #self.bloques*0.0
655 #in_sat_spectra = spectra.copy() #self.bloque0
657 #in_sat_spectra = spectra.copy() #self.bloque0
656 #in_sat_cspectra = cspectra.copy() #self.bloques
658 #in_sat_cspectra = cspectra.copy() #self.bloques
657
659
658
660
659 ###ONLY FOR TEST:
661 ###ONLY FOR TEST:
660 raxs = math.ceil(math.sqrt(self.nPairs))
662 raxs = math.ceil(math.sqrt(self.nPairs))
661 caxs = math.ceil(self.nPairs/raxs)
663 caxs = math.ceil(self.nPairs/raxs)
662 if self.nPairs <4:
664 if self.nPairs <4:
663 raxs = 2
665 raxs = 2
664 caxs = 2
666 caxs = 2
665 #print(raxs, caxs)
667 #print(raxs, caxs)
666 fft_rev = 14 #nFFT to plot
668 fft_rev = 14 #nFFT to plot
667 hei_rev = ((self.heights >= 550) & (self.heights <= 551)).nonzero() #hei to plot
669 hei_rev = ((self.heights >= 550) & (self.heights <= 551)).nonzero() #hei to plot
668 hei_rev = hei_rev[0]
670 hei_rev = hei_rev[0]
669 #print(hei_rev)
671 #print(hei_rev)
670
672
671 #print numpy.absolute(rfunc[:,0,0,14])
673 #print numpy.absolute(rfunc[:,0,0,14])
672
674
673 gauss_fit, covariance = None, None
675 gauss_fit, covariance = None, None
674 for ih in range(self.minAltInd,self.maxAltInd):
676 for ih in range(self.minAltInd,self.maxAltInd):
675 for ifreq in range(self.nFFTPoints):
677 for ifreq in range(self.nFFTPoints):
676 '''
678 '''
677 ###ONLY FOR TEST:
679 ###ONLY FOR TEST:
678 if ifreq ==fft_rev and ih==hei_rev: #TO VIEW A SIGNLE FREQUENCY
680 if ifreq ==fft_rev and ih==hei_rev: #TO VIEW A SIGNLE FREQUENCY
679 fig, axs = plt.subplots(raxs, caxs)
681 fig, axs = plt.subplots(raxs, caxs)
680 fig2, axs2 = plt.subplots(raxs, caxs)
682 fig2, axs2 = plt.subplots(raxs, caxs)
681 col_ax = 0
683 col_ax = 0
682 row_ax = 0
684 row_ax = 0
683 '''
685 '''
684 #print(self.nPairs)
686 #print(self.nPairs)
685 for ii in range(self.nChan): #PARES DE CANALES SELF y CROSS
687 for ii in range(self.nChan): #PARES DE CANALES SELF y CROSS
686 # if self.crosspairs[ii][1]-self.crosspairs[ii][0] > 1: # APLICAR SOLO EN PARES CONTIGUOS
688 # if self.crosspairs[ii][1]-self.crosspairs[ii][0] > 1: # APLICAR SOLO EN PARES CONTIGUOS
687 # continue
689 # continue
688 # if not self.crosspairs[ii][0] in channelsProcssd:
690 # if not self.crosspairs[ii][0] in channelsProcssd:
689 # channelA_ok = True
691 # channelA_ok = True
690 #print("pair: ",self.crosspairs[ii])
692 #print("pair: ",self.crosspairs[ii])
691 '''
693 '''
692 ###ONLY FOR TEST:
694 ###ONLY FOR TEST:
693 if (col_ax%caxs==0 and col_ax!=0 and self.nPairs !=1):
695 if (col_ax%caxs==0 and col_ax!=0 and self.nPairs !=1):
694 col_ax = 0
696 col_ax = 0
695 row_ax += 1
697 row_ax += 1
696 '''
698 '''
697 func2clean = 10*numpy.log10(numpy.absolute(rfunc[:,ii,ifreq,ih])) #Potencia?
699 func2clean = 10*numpy.log10(numpy.absolute(rfunc[:,ii,ifreq,ih])) #Potencia?
698 #print(func2clean.shape)
700 #print(func2clean.shape)
699 val = (numpy.isfinite(func2clean)==True).nonzero()
701 val = (numpy.isfinite(func2clean)==True).nonzero()
700
702
701 if len(val)>0: #limitador
703 if len(val)>0: #limitador
702 min_val = numpy.around(numpy.amin(func2clean)-2) #> (-40)
704 min_val = numpy.around(numpy.amin(func2clean)-2) #> (-40)
703 if min_val <= -40 :
705 if min_val <= -40 :
704 min_val = -40
706 min_val = -40
705 max_val = numpy.around(numpy.amax(func2clean)+2) #< 200
707 max_val = numpy.around(numpy.amax(func2clean)+2) #< 200
706 if max_val >= 200 :
708 if max_val >= 200 :
707 max_val = 200
709 max_val = 200
708 #print min_val, max_val
710 #print min_val, max_val
709 step = 1
711 step = 1
710 #print("Getting bins and the histogram")
712 #print("Getting bins and the histogram")
711 x_dist = min_val + numpy.arange(1 + ((max_val-(min_val))/step))*step
713 x_dist = min_val + numpy.arange(1 + ((max_val-(min_val))/step))*step
712 y_dist,binstep = numpy.histogram(func2clean,bins=range(int(min_val),int(max_val+2),step))
714 y_dist,binstep = numpy.histogram(func2clean,bins=range(int(min_val),int(max_val+2),step))
713 #print(len(y_dist),len(binstep[:-1]))
715 #print(len(y_dist),len(binstep[:-1]))
714 #print(row_ax,col_ax, " ..")
716 #print(row_ax,col_ax, " ..")
715 #print(self.pairsArray[ii][0],self.pairsArray[ii][1])
717 #print(self.pairsArray[ii][0],self.pairsArray[ii][1])
716 mean = numpy.sum(x_dist * y_dist) / numpy.sum(y_dist)
718 mean = numpy.sum(x_dist * y_dist) / numpy.sum(y_dist)
717 sigma = numpy.sqrt(numpy.sum(y_dist * (x_dist - mean)**2) / numpy.sum(y_dist))
719 sigma = numpy.sqrt(numpy.sum(y_dist * (x_dist - mean)**2) / numpy.sum(y_dist))
718 parg = [numpy.amax(y_dist),mean,sigma]
720 parg = [numpy.amax(y_dist),mean,sigma]
719
721
720 newY = None
722 newY = None
721
723
722 try :
724 try :
723 gauss_fit, covariance = curve_fit(fit_func, x_dist, y_dist,p0=parg)
725 gauss_fit, covariance = curve_fit(fit_func, x_dist, y_dist,p0=parg)
724 mode = gauss_fit[1]
726 mode = gauss_fit[1]
725 stdv = gauss_fit[2]
727 stdv = gauss_fit[2]
726 #print(" FIT OK",gauss_fit)
728 #print(" FIT OK",gauss_fit)
727 '''
729 '''
728 ###ONLY FOR TEST:
730 ###ONLY FOR TEST:
729 if ifreq ==fft_rev and ih==hei_rev: #TO VIEW A SIGNLE FREQUENCY
731 if ifreq ==fft_rev and ih==hei_rev: #TO VIEW A SIGNLE FREQUENCY
730 newY = fit_func(x_dist,gauss_fit[0],gauss_fit[1],gauss_fit[2])
732 newY = fit_func(x_dist,gauss_fit[0],gauss_fit[1],gauss_fit[2])
731 axs[row_ax,col_ax].plot(binstep[:-1],y_dist,color='green')
733 axs[row_ax,col_ax].plot(binstep[:-1],y_dist,color='green')
732 axs[row_ax,col_ax].plot(binstep[:-1],newY,color='red')
734 axs[row_ax,col_ax].plot(binstep[:-1],newY,color='red')
733 axs[row_ax,col_ax].set_title("CH "+str(self.channels[ii]))
735 axs[row_ax,col_ax].set_title("CH "+str(self.channels[ii]))
734 '''
736 '''
735 except:
737 except:
736 mode = mean
738 mode = mean
737 stdv = sigma
739 stdv = sigma
738 #print("FIT FAIL")
740 #print("FIT FAIL")
739 #continue
741 #continue
740
742
741
743
742 #print(mode,stdv)
744 #print(mode,stdv)
743 #Removing echoes greater than mode + std_factor*stdv
745 #Removing echoes greater than mode + std_factor*stdv
744 noval = (abs(func2clean - mode)>=(factor_stdv*stdv)).nonzero()
746 noval = (abs(func2clean - mode)>=(factor_stdv*stdv)).nonzero()
745 #noval tiene los indices que se van a remover
747 #noval tiene los indices que se van a remover
746 #print("Chan ",ii," novals: ",len(noval[0]))
748 #print("Chan ",ii," novals: ",len(noval[0]))
747 if len(noval[0]) > 0: #forma de array (N,) es igual a longitud (N)
749 if len(noval[0]) > 0: #forma de array (N,) es igual a longitud (N)
748 novall = ((func2clean - mode) >= (factor_stdv*stdv)).nonzero()
750 novall = ((func2clean - mode) >= (factor_stdv*stdv)).nonzero()
749 #print(novall)
751 #print(novall)
750 #print(" ",self.pairsArray[ii])
752 #print(" ",self.pairsArray[ii])
751 #cross_pairs = self.pairsArray[ii]
753 #cross_pairs = self.pairsArray[ii]
752 #Getting coherent echoes which are removed.
754 #Getting coherent echoes which are removed.
753 # if len(novall[0]) > 0:
755 # if len(novall[0]) > 0:
754 #
756 #
755 # val_spc[novall[0],cross_pairs[0],ifreq,ih] = 1
757 # val_spc[novall[0],cross_pairs[0],ifreq,ih] = 1
756 # val_spc[novall[0],cross_pairs[1],ifreq,ih] = 1
758 # val_spc[novall[0],cross_pairs[1],ifreq,ih] = 1
757 # val_cspc[novall[0],ii,ifreq,ih] = 1
759 # val_cspc[novall[0],ii,ifreq,ih] = 1
758 #print("OUT NOVALL 1")
760 #print("OUT NOVALL 1")
759 try:
761 try:
760 pair = (self.channels[ii],self.channels[ii + 1])
762 pair = (self.channels[ii],self.channels[ii + 1])
761 except:
763 except:
762 pair = (99,99)
764 pair = (99,99)
763 #print("par ", pair)
765 #print("par ", pair)
764 if ( pair in self.crosspairs):
766 if ( pair in self.crosspairs):
765 q = self.crosspairs.index(pair)
767 q = self.crosspairs.index(pair)
766 #print("estΓ‘ aqui: ", q, (ii,ii + 1))
768 #print("estΓ‘ aqui: ", q, (ii,ii + 1))
767 new_a = numpy.delete(cspectra[:,q,ifreq,ih], noval[0])
769 new_a = numpy.delete(cspectra[:,q,ifreq,ih], noval[0])
768 cspectra[noval,q,ifreq,ih] = numpy.mean(new_a) #mean CrossSpectra
770 cspectra[noval,q,ifreq,ih] = numpy.mean(new_a) #mean CrossSpectra
769
771
770 #if channelA_ok:
772 #if channelA_ok:
771 #chA = self.channels.index(cross_pairs[0])
773 #chA = self.channels.index(cross_pairs[0])
772 new_b = numpy.delete(spectra[:,ii,ifreq,ih], noval[0])
774 new_b = numpy.delete(spectra[:,ii,ifreq,ih], noval[0])
773 spectra[noval,ii,ifreq,ih] = numpy.mean(new_b) #mean Spectra Pair A
775 spectra[noval,ii,ifreq,ih] = numpy.mean(new_b) #mean Spectra Pair A
774 #channelA_ok = False
776 #channelA_ok = False
775
777
776 # chB = self.channels.index(cross_pairs[1])
778 # chB = self.channels.index(cross_pairs[1])
777 # new_c = numpy.delete(spectra[:,chB,ifreq,ih], noval[0])
779 # new_c = numpy.delete(spectra[:,chB,ifreq,ih], noval[0])
778 # spectra[noval,chB,ifreq,ih] = numpy.mean(new_c) #mean Spectra Pair B
780 # spectra[noval,chB,ifreq,ih] = numpy.mean(new_c) #mean Spectra Pair B
779 #
781 #
780 # channelsProcssd.append(self.crosspairs[ii][0]) # save channel A
782 # channelsProcssd.append(self.crosspairs[ii][0]) # save channel A
781 # channelsProcssd.append(self.crosspairs[ii][1]) # save channel B
783 # channelsProcssd.append(self.crosspairs[ii][1]) # save channel B
782 '''
784 '''
783 ###ONLY FOR TEST:
785 ###ONLY FOR TEST:
784 if ifreq ==fft_rev and ih==hei_rev: #TO VIEW A SIGNLE FREQUENCY
786 if ifreq ==fft_rev and ih==hei_rev: #TO VIEW A SIGNLE FREQUENCY
785 func2clean = 10*numpy.log10(numpy.absolute(spectra[:,ii,ifreq,ih]))
787 func2clean = 10*numpy.log10(numpy.absolute(spectra[:,ii,ifreq,ih]))
786 y_dist,binstep = numpy.histogram(func2clean,bins=range(int(min_val),int(max_val+2),step))
788 y_dist,binstep = numpy.histogram(func2clean,bins=range(int(min_val),int(max_val+2),step))
787 axs2[row_ax,col_ax].plot(binstep[:-1],newY,color='red')
789 axs2[row_ax,col_ax].plot(binstep[:-1],newY,color='red')
788 axs2[row_ax,col_ax].plot(binstep[:-1],y_dist,color='green')
790 axs2[row_ax,col_ax].plot(binstep[:-1],y_dist,color='green')
789 axs2[row_ax,col_ax].set_title("CH "+str(self.channels[ii]))
791 axs2[row_ax,col_ax].set_title("CH "+str(self.channels[ii]))
790 '''
792 '''
791 '''
793 '''
792 ###ONLY FOR TEST:
794 ###ONLY FOR TEST:
793 col_ax += 1 #contador de ploteo columnas
795 col_ax += 1 #contador de ploteo columnas
794 ##print(col_ax)
796 ##print(col_ax)
795 ###ONLY FOR TEST:
797 ###ONLY FOR TEST:
796 if ifreq ==fft_rev and ih==hei_rev: #TO VIEW A SIGNLE FREQUENCY
798 if ifreq ==fft_rev and ih==hei_rev: #TO VIEW A SIGNLE FREQUENCY
797 title = str(dataOut.datatime)+" nFFT: "+str(ifreq)+" Alt: "+str(self.heights[ih])+ " km"
799 title = str(dataOut.datatime)+" nFFT: "+str(ifreq)+" Alt: "+str(self.heights[ih])+ " km"
798 title2 = str(dataOut.datatime)+" nFFT: "+str(ifreq)+" Alt: "+str(self.heights[ih])+ " km CLEANED"
800 title2 = str(dataOut.datatime)+" nFFT: "+str(ifreq)+" Alt: "+str(self.heights[ih])+ " km CLEANED"
799 fig.suptitle(title)
801 fig.suptitle(title)
800 fig2.suptitle(title2)
802 fig2.suptitle(title2)
801 plt.show()
803 plt.show()
802 '''
804 '''
803 ##################################################################################################
805 ##################################################################################################
804
806
805 #print("Getting average of the spectra and cross-spectra from incoherent echoes.")
807 #print("Getting average of the spectra and cross-spectra from incoherent echoes.")
806 out_spectra = numpy.zeros([self.nChan,self.nFFTPoints,self.nHeights], dtype=float) #+numpy.nan
808 out_spectra = numpy.zeros([self.nChan,self.nFFTPoints,self.nHeights], dtype=float) #+numpy.nan
807 out_cspectra = numpy.zeros([self.nPairs,self.nFFTPoints,self.nHeights], dtype=complex) #+numpy.nan
809 out_cspectra = numpy.zeros([self.nPairs,self.nFFTPoints,self.nHeights], dtype=complex) #+numpy.nan
808 for ih in range(self.nHeights):
810 for ih in range(self.nHeights):
809 for ifreq in range(self.nFFTPoints):
811 for ifreq in range(self.nFFTPoints):
810 for ich in range(self.nChan):
812 for ich in range(self.nChan):
811 tmp = spectra[:,ich,ifreq,ih]
813 tmp = spectra[:,ich,ifreq,ih]
812 valid = (numpy.isfinite(tmp[:])==True).nonzero()
814 valid = (numpy.isfinite(tmp[:])==True).nonzero()
813
815
814 if len(valid[0]) >0 :
816 if len(valid[0]) >0 :
815 out_spectra[ich,ifreq,ih] = numpy.nansum(tmp)#/len(valid[0])
817 out_spectra[ich,ifreq,ih] = numpy.nansum(tmp)#/len(valid[0])
816
818
817 for icr in range(self.nPairs):
819 for icr in range(self.nPairs):
818 tmp = numpy.squeeze(cspectra[:,icr,ifreq,ih])
820 tmp = numpy.squeeze(cspectra[:,icr,ifreq,ih])
819 valid = (numpy.isfinite(tmp)==True).nonzero()
821 valid = (numpy.isfinite(tmp)==True).nonzero()
820 if len(valid[0]) > 0:
822 if len(valid[0]) > 0:
821 out_cspectra[icr,ifreq,ih] = numpy.nansum(tmp)#/len(valid[0])
823 out_cspectra[icr,ifreq,ih] = numpy.nansum(tmp)#/len(valid[0])
822
824
823 return out_spectra, out_cspectra
825 return out_spectra, out_cspectra
824
826
825 def REM_ISOLATED_POINTS(self,array,rth):
827 def REM_ISOLATED_POINTS(self,array,rth):
826 # import matplotlib.pyplot as plt
828 # import matplotlib.pyplot as plt
827 if rth == None :
829 if rth == None :
828 rth = 4
830 rth = 4
829 #print("REM ISO")
831 #print("REM ISO")
830 num_prof = len(array[0,:,0])
832 num_prof = len(array[0,:,0])
831 num_hei = len(array[0,0,:])
833 num_hei = len(array[0,0,:])
832 n2d = len(array[:,0,0])
834 n2d = len(array[:,0,0])
833
835
834 for ii in range(n2d) :
836 for ii in range(n2d) :
835 #print ii,n2d
837 #print ii,n2d
836 tmp = array[ii,:,:]
838 tmp = array[ii,:,:]
837 #print tmp.shape, array[ii,101,:],array[ii,102,:]
839 #print tmp.shape, array[ii,101,:],array[ii,102,:]
838
840
839 # fig = plt.figure(figsize=(6,5))
841 # fig = plt.figure(figsize=(6,5))
840 # left, bottom, width, height = 0.1, 0.1, 0.8, 0.8
842 # left, bottom, width, height = 0.1, 0.1, 0.8, 0.8
841 # ax = fig.add_axes([left, bottom, width, height])
843 # ax = fig.add_axes([left, bottom, width, height])
842 # x = range(num_prof)
844 # x = range(num_prof)
843 # y = range(num_hei)
845 # y = range(num_hei)
844 # cp = ax.contour(y,x,tmp)
846 # cp = ax.contour(y,x,tmp)
845 # ax.clabel(cp, inline=True,fontsize=10)
847 # ax.clabel(cp, inline=True,fontsize=10)
846 # plt.show()
848 # plt.show()
847
849
848 #indxs = WHERE(FINITE(tmp) AND tmp GT 0,cindxs)
850 #indxs = WHERE(FINITE(tmp) AND tmp GT 0,cindxs)
849 tmp = numpy.reshape(tmp,num_prof*num_hei)
851 tmp = numpy.reshape(tmp,num_prof*num_hei)
850 indxs1 = (numpy.isfinite(tmp)==True).nonzero()
852 indxs1 = (numpy.isfinite(tmp)==True).nonzero()
851 indxs2 = (tmp > 0).nonzero()
853 indxs2 = (tmp > 0).nonzero()
852
854
853 indxs1 = (indxs1[0])
855 indxs1 = (indxs1[0])
854 indxs2 = indxs2[0]
856 indxs2 = indxs2[0]
855 #indxs1 = numpy.array(indxs1[0])
857 #indxs1 = numpy.array(indxs1[0])
856 #indxs2 = numpy.array(indxs2[0])
858 #indxs2 = numpy.array(indxs2[0])
857 indxs = None
859 indxs = None
858 #print indxs1 , indxs2
860 #print indxs1 , indxs2
859 for iv in range(len(indxs2)):
861 for iv in range(len(indxs2)):
860 indv = numpy.array((indxs1 == indxs2[iv]).nonzero())
862 indv = numpy.array((indxs1 == indxs2[iv]).nonzero())
861 #print len(indxs2), indv
863 #print len(indxs2), indv
862 if len(indv[0]) > 0 :
864 if len(indv[0]) > 0 :
863 indxs = numpy.concatenate((indxs,indxs2[iv]), axis=None)
865 indxs = numpy.concatenate((indxs,indxs2[iv]), axis=None)
864 # print indxs
866 # print indxs
865 indxs = indxs[1:]
867 indxs = indxs[1:]
866 #print(indxs, len(indxs))
868 #print(indxs, len(indxs))
867 if len(indxs) < 4 :
869 if len(indxs) < 4 :
868 array[ii,:,:] = 0.
870 array[ii,:,:] = 0.
869 return
871 return
870
872
871 xpos = numpy.mod(indxs ,num_hei)
873 xpos = numpy.mod(indxs ,num_hei)
872 ypos = (indxs / num_hei)
874 ypos = (indxs / num_hei)
873 sx = numpy.argsort(xpos) # Ordering respect to "x" (time)
875 sx = numpy.argsort(xpos) # Ordering respect to "x" (time)
874 #print sx
876 #print sx
875 xpos = xpos[sx]
877 xpos = xpos[sx]
876 ypos = ypos[sx]
878 ypos = ypos[sx]
877
879
878 # *********************************** Cleaning isolated points **********************************
880 # *********************************** Cleaning isolated points **********************************
879 ic = 0
881 ic = 0
880 while True :
882 while True :
881 r = numpy.sqrt(list(numpy.power((xpos[ic]-xpos),2)+ numpy.power((ypos[ic]-ypos),2)))
883 r = numpy.sqrt(list(numpy.power((xpos[ic]-xpos),2)+ numpy.power((ypos[ic]-ypos),2)))
882 #no_coh = WHERE(FINITE(r) AND (r LE rth),cno_coh)
884 #no_coh = WHERE(FINITE(r) AND (r LE rth),cno_coh)
883 #plt.plot(r)
885 #plt.plot(r)
884 #plt.show()
886 #plt.show()
885 no_coh1 = (numpy.isfinite(r)==True).nonzero()
887 no_coh1 = (numpy.isfinite(r)==True).nonzero()
886 no_coh2 = (r <= rth).nonzero()
888 no_coh2 = (r <= rth).nonzero()
887 #print r, no_coh1, no_coh2
889 #print r, no_coh1, no_coh2
888 no_coh1 = numpy.array(no_coh1[0])
890 no_coh1 = numpy.array(no_coh1[0])
889 no_coh2 = numpy.array(no_coh2[0])
891 no_coh2 = numpy.array(no_coh2[0])
890 no_coh = None
892 no_coh = None
891 #print valid1 , valid2
893 #print valid1 , valid2
892 for iv in range(len(no_coh2)):
894 for iv in range(len(no_coh2)):
893 indv = numpy.array((no_coh1 == no_coh2[iv]).nonzero())
895 indv = numpy.array((no_coh1 == no_coh2[iv]).nonzero())
894 if len(indv[0]) > 0 :
896 if len(indv[0]) > 0 :
895 no_coh = numpy.concatenate((no_coh,no_coh2[iv]), axis=None)
897 no_coh = numpy.concatenate((no_coh,no_coh2[iv]), axis=None)
896 no_coh = no_coh[1:]
898 no_coh = no_coh[1:]
897 #print len(no_coh), no_coh
899 #print len(no_coh), no_coh
898 if len(no_coh) < 4 :
900 if len(no_coh) < 4 :
899 #print xpos[ic], ypos[ic], ic
901 #print xpos[ic], ypos[ic], ic
900 # plt.plot(r)
902 # plt.plot(r)
901 # plt.show()
903 # plt.show()
902 xpos[ic] = numpy.nan
904 xpos[ic] = numpy.nan
903 ypos[ic] = numpy.nan
905 ypos[ic] = numpy.nan
904
906
905 ic = ic + 1
907 ic = ic + 1
906 if (ic == len(indxs)) :
908 if (ic == len(indxs)) :
907 break
909 break
908 #print( xpos, ypos)
910 #print( xpos, ypos)
909
911
910 indxs = (numpy.isfinite(list(xpos))==True).nonzero()
912 indxs = (numpy.isfinite(list(xpos))==True).nonzero()
911 #print indxs[0]
913 #print indxs[0]
912 if len(indxs[0]) < 4 :
914 if len(indxs[0]) < 4 :
913 array[ii,:,:] = 0.
915 array[ii,:,:] = 0.
914 return
916 return
915
917
916 xpos = xpos[indxs[0]]
918 xpos = xpos[indxs[0]]
917 ypos = ypos[indxs[0]]
919 ypos = ypos[indxs[0]]
918 for i in range(0,len(ypos)):
920 for i in range(0,len(ypos)):
919 ypos[i]=int(ypos[i])
921 ypos[i]=int(ypos[i])
920 junk = tmp
922 junk = tmp
921 tmp = junk*0.0
923 tmp = junk*0.0
922
924
923 tmp[list(xpos + (ypos*num_hei))] = junk[list(xpos + (ypos*num_hei))]
925 tmp[list(xpos + (ypos*num_hei))] = junk[list(xpos + (ypos*num_hei))]
924 array[ii,:,:] = numpy.reshape(tmp,(num_prof,num_hei))
926 array[ii,:,:] = numpy.reshape(tmp,(num_prof,num_hei))
925
927
926 #print array.shape
928 #print array.shape
927 #tmp = numpy.reshape(tmp,(num_prof,num_hei))
929 #tmp = numpy.reshape(tmp,(num_prof,num_hei))
928 #print tmp.shape
930 #print tmp.shape
929
931
930 # fig = plt.figure(figsize=(6,5))
932 # fig = plt.figure(figsize=(6,5))
931 # left, bottom, width, height = 0.1, 0.1, 0.8, 0.8
933 # left, bottom, width, height = 0.1, 0.1, 0.8, 0.8
932 # ax = fig.add_axes([left, bottom, width, height])
934 # ax = fig.add_axes([left, bottom, width, height])
933 # x = range(num_prof)
935 # x = range(num_prof)
934 # y = range(num_hei)
936 # y = range(num_hei)
935 # cp = ax.contour(y,x,array[ii,:,:])
937 # cp = ax.contour(y,x,array[ii,:,:])
936 # ax.clabel(cp, inline=True,fontsize=10)
938 # ax.clabel(cp, inline=True,fontsize=10)
937 # plt.show()
939 # plt.show()
938 return array
940 return array
939
941
940
942
941 class IntegrationFaradaySpectra(Operation):
943 class IntegrationFaradaySpectra(Operation):
942
944
943 __profIndex = 0
945 __profIndex = 0
944 __withOverapping = False
946 __withOverapping = False
945
947
946 __byTime = False
948 __byTime = False
947 __initime = None
949 __initime = None
948 __lastdatatime = None
950 __lastdatatime = None
949 __integrationtime = None
951 __integrationtime = None
950
952
951 __buffer_spc = None
953 __buffer_spc = None
952 __buffer_cspc = None
954 __buffer_cspc = None
953 __buffer_dc = None
955 __buffer_dc = None
954
956
955 __dataReady = False
957 __dataReady = False
956
958
957 __timeInterval = None
959 __timeInterval = None
958
960
959 n = None
961 n = None
960
962
961 def __init__(self):
963 def __init__(self):
962
964
963 Operation.__init__(self)
965 Operation.__init__(self)
964
966
965 def setup(self, dataOut,n=None, timeInterval=None, overlapping=False, DPL=None):
967 def setup(self, dataOut,n=None, timeInterval=None, overlapping=False, DPL=None):
966 """
968 """
967 Set the parameters of the integration class.
969 Set the parameters of the integration class.
968
970
969 Inputs:
971 Inputs:
970
972
971 n : Number of coherent integrations
973 n : Number of coherent integrations
972 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
974 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
973 overlapping :
975 overlapping :
974
976
975 """
977 """
976
978
977 self.__initime = None
979 self.__initime = None
978 self.__lastdatatime = 0
980 self.__lastdatatime = 0
979
981
980 self.__buffer_spc = []
982 self.__buffer_spc = []
981 self.__buffer_cspc = []
983 self.__buffer_cspc = []
982 self.__buffer_dc = 0
984 self.__buffer_dc = 0
983
985
984 self.__profIndex = 0
986 self.__profIndex = 0
985 self.__dataReady = False
987 self.__dataReady = False
986 self.__byTime = False
988 self.__byTime = False
987
989
988 #self.ByLags = dataOut.ByLags ###REDEFINIR
990 #self.ByLags = dataOut.ByLags ###REDEFINIR
989 self.ByLags = False
991 self.ByLags = False
990
992
991 if DPL != None:
993 if DPL != None:
992 self.DPL=DPL
994 self.DPL=DPL
993 else:
995 else:
994 #self.DPL=dataOut.DPL ###REDEFINIR
996 #self.DPL=dataOut.DPL ###REDEFINIR
995 self.DPL=0
997 self.DPL=0
996
998
997 if n is None and timeInterval is None:
999 if n is None and timeInterval is None:
998 raise ValueError("n or timeInterval should be specified ...")
1000 raise ValueError("n or timeInterval should be specified ...")
999
1001
1000 if n is not None:
1002 if n is not None:
1001 self.n = int(n)
1003 self.n = int(n)
1002 else:
1004 else:
1003
1005
1004 self.__integrationtime = int(timeInterval)
1006 self.__integrationtime = int(timeInterval)
1005 self.n = None
1007 self.n = None
1006 self.__byTime = True
1008 self.__byTime = True
1007
1009
1008 def putData(self, data_spc, data_cspc, data_dc):
1010 def putData(self, data_spc, data_cspc, data_dc):
1009 """
1011 """
1010 Add a profile to the __buffer_spc and increase in one the __profileIndex
1012 Add a profile to the __buffer_spc and increase in one the __profileIndex
1011
1013
1012 """
1014 """
1013
1015
1014 self.__buffer_spc.append(data_spc)
1016 self.__buffer_spc.append(data_spc)
1015
1017
1016 if data_cspc is None:
1018 if data_cspc is None:
1017 self.__buffer_cspc = None
1019 self.__buffer_cspc = None
1018 else:
1020 else:
1019 self.__buffer_cspc.append(data_cspc)
1021 self.__buffer_cspc.append(data_cspc)
1020
1022
1021 if data_dc is None:
1023 if data_dc is None:
1022 self.__buffer_dc = None
1024 self.__buffer_dc = None
1023 else:
1025 else:
1024 self.__buffer_dc += data_dc
1026 self.__buffer_dc += data_dc
1025
1027
1026 self.__profIndex += 1
1028 self.__profIndex += 1
1027
1029
1028 return
1030 return
1029
1031
1030 def hildebrand_sekhon_Integration(self,data,navg):
1032 def hildebrand_sekhon_Integration(self,data,navg):
1031
1033
1032 sortdata = numpy.sort(data, axis=None)
1034 sortdata = numpy.sort(data, axis=None)
1033 sortID=data.argsort()
1035 sortID=data.argsort()
1034 lenOfData = len(sortdata)
1036 lenOfData = len(sortdata)
1035 nums_min = lenOfData*0.75
1037 nums_min = lenOfData*0.75
1036 if nums_min <= 5:
1038 if nums_min <= 5:
1037 nums_min = 5
1039 nums_min = 5
1038 sump = 0.
1040 sump = 0.
1039 sumq = 0.
1041 sumq = 0.
1040 j = 0
1042 j = 0
1041 cont = 1
1043 cont = 1
1042 while((cont == 1)and(j < lenOfData)):
1044 while((cont == 1)and(j < lenOfData)):
1043 sump += sortdata[j]
1045 sump += sortdata[j]
1044 sumq += sortdata[j]**2
1046 sumq += sortdata[j]**2
1045 if j > nums_min:
1047 if j > nums_min:
1046 rtest = float(j)/(j-1) + 1.0/navg
1048 rtest = float(j)/(j-1) + 1.0/navg
1047 if ((sumq*j) > (rtest*sump**2)):
1049 if ((sumq*j) > (rtest*sump**2)):
1048 j = j - 1
1050 j = j - 1
1049 sump = sump - sortdata[j]
1051 sump = sump - sortdata[j]
1050 sumq = sumq - sortdata[j]**2
1052 sumq = sumq - sortdata[j]**2
1051 cont = 0
1053 cont = 0
1052 j += 1
1054 j += 1
1053 #lnoise = sump / j
1055 #lnoise = sump / j
1054
1056
1055 return j,sortID
1057 return j,sortID
1056
1058
1057 def pushData(self):
1059 def pushData(self):
1058 """
1060 """
1059 Return the sum of the last profiles and the profiles used in the sum.
1061 Return the sum of the last profiles and the profiles used in the sum.
1060
1062
1061 Affected:
1063 Affected:
1062
1064
1063 self.__profileIndex
1065 self.__profileIndex
1064
1066
1065 """
1067 """
1066 bufferH=None
1068 bufferH=None
1067 buffer=None
1069 buffer=None
1068 buffer1=None
1070 buffer1=None
1069 buffer_cspc=None
1071 buffer_cspc=None
1070 self.__buffer_spc=numpy.array(self.__buffer_spc)
1072 self.__buffer_spc=numpy.array(self.__buffer_spc)
1071 self.__buffer_cspc=numpy.array(self.__buffer_cspc)
1073 self.__buffer_cspc=numpy.array(self.__buffer_cspc)
1072 freq_dc = int(self.__buffer_spc.shape[2] / 2)
1074 freq_dc = int(self.__buffer_spc.shape[2] / 2)
1073 #print("FREQ_DC",freq_dc,self.__buffer_spc.shape,self.nHeights)
1075 #print("FREQ_DC",freq_dc,self.__buffer_spc.shape,self.nHeights)
1074 for k in range(7,self.nHeights):
1076 for k in range(7,self.nHeights):
1075 buffer_cspc=numpy.copy(self.__buffer_cspc[:,:,:,k])
1077 buffer_cspc=numpy.copy(self.__buffer_cspc[:,:,:,k])
1076 outliers_IDs_cspc=[]
1078 outliers_IDs_cspc=[]
1077 cspc_outliers_exist=False
1079 cspc_outliers_exist=False
1078 #print("AQUIII")
1079 for i in range(self.nChannels):#dataOut.nChannels):
1080 for i in range(self.nChannels):#dataOut.nChannels):
1080
1081
1081 buffer1=numpy.copy(self.__buffer_spc[:,i,:,k])
1082 buffer1=numpy.copy(self.__buffer_spc[:,i,:,k])
1082 indexes=[]
1083 indexes=[]
1083 #sortIDs=[]
1084 #sortIDs=[]
1084 outliers_IDs=[]
1085 outliers_IDs=[]
1085
1086
1086 for j in range(self.nProfiles):
1087 for j in range(self.nProfiles):
1087 # if i==0 and j==freq_dc: #NOT CONSIDERING DC PROFILE AT CHANNEL 0
1088 # if i==0 and j==freq_dc: #NOT CONSIDERING DC PROFILE AT CHANNEL 0
1088 # continue
1089 # continue
1089 # if i==1 and j==0: #NOT CONSIDERING DC PROFILE AT CHANNEL 1
1090 # if i==1 and j==0: #NOT CONSIDERING DC PROFILE AT CHANNEL 1
1090 # continue
1091 # continue
1091 buffer=buffer1[:,j]
1092 buffer=buffer1[:,j]
1092 index,sortID=self.hildebrand_sekhon_Integration(buffer,1)
1093 index,sortID=self.hildebrand_sekhon_Integration(buffer,1)
1093
1094
1094 indexes.append(index)
1095 indexes.append(index)
1095 #sortIDs.append(sortID)
1096 #sortIDs.append(sortID)
1096 outliers_IDs=numpy.append(outliers_IDs,sortID[index:])
1097 outliers_IDs=numpy.append(outliers_IDs,sortID[index:])
1097
1098
1098 outliers_IDs=numpy.array(outliers_IDs)
1099 outliers_IDs=numpy.array(outliers_IDs)
1099 outliers_IDs=outliers_IDs.ravel()
1100 outliers_IDs=outliers_IDs.ravel()
1100 outliers_IDs=numpy.unique(outliers_IDs)
1101 outliers_IDs=numpy.unique(outliers_IDs)
1101 outliers_IDs=outliers_IDs.astype(numpy.dtype('int64'))
1102 outliers_IDs=outliers_IDs.astype(numpy.dtype('int64'))
1102 indexes=numpy.array(indexes)
1103 indexes=numpy.array(indexes)
1103 indexmin=numpy.min(indexes)
1104 indexmin=numpy.min(indexes)
1104
1105
1105 if indexmin != buffer1.shape[0]:
1106 if indexmin != buffer1.shape[0]:
1106 cspc_outliers_exist=True
1107 cspc_outliers_exist=True
1107 ###sortdata=numpy.sort(buffer1,axis=0)
1108 ###sortdata=numpy.sort(buffer1,axis=0)
1108 ###avg2=numpy.mean(sortdata[:indexmin,:],axis=0)
1109 ###avg2=numpy.mean(sortdata[:indexmin,:],axis=0)
1109 lt=outliers_IDs
1110 lt=outliers_IDs
1110 avg=numpy.mean(buffer1[[t for t in range(buffer1.shape[0]) if t not in lt],:],axis=0)
1111 avg=numpy.mean(buffer1[[t for t in range(buffer1.shape[0]) if t not in lt],:],axis=0)
1111
1112
1112 for p in list(outliers_IDs):
1113 for p in list(outliers_IDs):
1113 buffer1[p,:]=avg
1114 buffer1[p,:]=avg
1114
1115
1115 self.__buffer_spc[:,i,:,k]=numpy.copy(buffer1)
1116 self.__buffer_spc[:,i,:,k]=numpy.copy(buffer1)
1116 ###cspc IDs
1117 ###cspc IDs
1117 #indexmin_cspc+=indexmin_cspc
1118 #indexmin_cspc+=indexmin_cspc
1118 outliers_IDs_cspc=numpy.append(outliers_IDs_cspc,outliers_IDs)
1119 outliers_IDs_cspc=numpy.append(outliers_IDs_cspc,outliers_IDs)
1119
1120
1120 #if not breakFlag:
1121 #if not breakFlag:
1121 outliers_IDs_cspc=outliers_IDs_cspc.astype(numpy.dtype('int64'))
1122 outliers_IDs_cspc=outliers_IDs_cspc.astype(numpy.dtype('int64'))
1122 if cspc_outliers_exist:
1123 if cspc_outliers_exist:
1123 #sortdata=numpy.sort(buffer_cspc,axis=0)
1124 #sortdata=numpy.sort(buffer_cspc,axis=0)
1124 #avg=numpy.mean(sortdata[:indexmin_cpsc,:],axis=0)
1125 #avg=numpy.mean(sortdata[:indexmin_cpsc,:],axis=0)
1125 lt=outliers_IDs_cspc
1126 lt=outliers_IDs_cspc
1126
1127
1127 avg=numpy.mean(buffer_cspc[[t for t in range(buffer_cspc.shape[0]) if t not in lt],:],axis=0)
1128 avg=numpy.mean(buffer_cspc[[t for t in range(buffer_cspc.shape[0]) if t not in lt],:],axis=0)
1128 for p in list(outliers_IDs_cspc):
1129 for p in list(outliers_IDs_cspc):
1129 buffer_cspc[p,:]=avg
1130 buffer_cspc[p,:]=avg
1130
1131
1131 self.__buffer_cspc[:,:,:,k]=numpy.copy(buffer_cspc)
1132 self.__buffer_cspc[:,:,:,k]=numpy.copy(buffer_cspc)
1132 #else:
1133 #else:
1133 #break
1134 #break
1134
1135
1135
1136
1136
1137
1137
1138
1138 buffer=None
1139 buffer=None
1139 bufferH=None
1140 bufferH=None
1140 buffer1=None
1141 buffer1=None
1141 buffer_cspc=None
1142 buffer_cspc=None
1142
1143
1143 #print("cpsc",self.__buffer_cspc[:,0,0,0,0])
1144 #print("cpsc",self.__buffer_cspc[:,0,0,0,0])
1144 #print(self.__profIndex)
1145 #print(self.__profIndex)
1145 #exit()
1146 #exit()
1146
1147
1147 buffer=None
1148 buffer=None
1148 #print(self.__buffer_spc[:,1,3,20,0])
1149 #print(self.__buffer_spc[:,1,3,20,0])
1149 #print(self.__buffer_spc[:,1,5,37,0])
1150 #print(self.__buffer_spc[:,1,5,37,0])
1150 data_spc = numpy.sum(self.__buffer_spc,axis=0)
1151 data_spc = numpy.sum(self.__buffer_spc,axis=0)
1151 data_cspc = numpy.sum(self.__buffer_cspc,axis=0)
1152 data_cspc = numpy.sum(self.__buffer_cspc,axis=0)
1152
1153
1153 #print(numpy.shape(data_spc))
1154 #print(numpy.shape(data_spc))
1154 #data_spc[1,4,20,0]=numpy.nan
1155 #data_spc[1,4,20,0]=numpy.nan
1155
1156
1156 #data_cspc = self.__buffer_cspc
1157 #data_cspc = self.__buffer_cspc
1157 data_dc = self.__buffer_dc
1158 data_dc = self.__buffer_dc
1158 n = self.__profIndex
1159 n = self.__profIndex
1159
1160
1160 self.__buffer_spc = []
1161 self.__buffer_spc = []
1161 self.__buffer_cspc = []
1162 self.__buffer_cspc = []
1162 self.__buffer_dc = 0
1163 self.__buffer_dc = 0
1163 self.__profIndex = 0
1164 self.__profIndex = 0
1164
1165
1165 return data_spc, data_cspc, data_dc, n
1166 return data_spc, data_cspc, data_dc, n
1166
1167
1167 def byProfiles(self, *args):
1168 def byProfiles(self, *args):
1168
1169
1169 self.__dataReady = False
1170 self.__dataReady = False
1170 avgdata_spc = None
1171 avgdata_spc = None
1171 avgdata_cspc = None
1172 avgdata_cspc = None
1172 avgdata_dc = None
1173 avgdata_dc = None
1173
1174
1174 self.putData(*args)
1175 self.putData(*args)
1175
1176
1176 if self.__profIndex == self.n:
1177 if self.__profIndex == self.n:
1177
1178
1178 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1179 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1179 self.n = n
1180 self.n = n
1180 self.__dataReady = True
1181 self.__dataReady = True
1181
1182
1182 return avgdata_spc, avgdata_cspc, avgdata_dc
1183 return avgdata_spc, avgdata_cspc, avgdata_dc
1183
1184
1184 def byTime(self, datatime, *args):
1185 def byTime(self, datatime, *args):
1185
1186
1186 self.__dataReady = False
1187 self.__dataReady = False
1187 avgdata_spc = None
1188 avgdata_spc = None
1188 avgdata_cspc = None
1189 avgdata_cspc = None
1189 avgdata_dc = None
1190 avgdata_dc = None
1190
1191
1191 self.putData(*args)
1192 self.putData(*args)
1192
1193
1193 if (datatime - self.__initime) >= self.__integrationtime:
1194 if (datatime - self.__initime) >= self.__integrationtime:
1194 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1195 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1195 self.n = n
1196 self.n = n
1196 self.__dataReady = True
1197 self.__dataReady = True
1197
1198
1198 return avgdata_spc, avgdata_cspc, avgdata_dc
1199 return avgdata_spc, avgdata_cspc, avgdata_dc
1199
1200
1200 def integrate(self, datatime, *args):
1201 def integrate(self, datatime, *args):
1201
1202
1202 if self.__profIndex == 0:
1203 if self.__profIndex == 0:
1203 self.__initime = datatime
1204 self.__initime = datatime
1204
1205
1205 if self.__byTime:
1206 if self.__byTime:
1206 avgdata_spc, avgdata_cspc, avgdata_dc = self.byTime(
1207 avgdata_spc, avgdata_cspc, avgdata_dc = self.byTime(
1207 datatime, *args)
1208 datatime, *args)
1208 else:
1209 else:
1209 avgdata_spc, avgdata_cspc, avgdata_dc = self.byProfiles(*args)
1210 avgdata_spc, avgdata_cspc, avgdata_dc = self.byProfiles(*args)
1210
1211
1211 if not self.__dataReady:
1212 if not self.__dataReady:
1212 return None, None, None, None
1213 return None, None, None, None
1213
1214
1214 return self.__initime, avgdata_spc, avgdata_cspc, avgdata_dc
1215 return self.__initime, avgdata_spc, avgdata_cspc, avgdata_dc
1215
1216
1216 def run(self, dataOut, n=None, DPL = None,timeInterval=None, overlapping=False):
1217 def run(self, dataOut, n=None, DPL = None,timeInterval=None, overlapping=False):
1217 if n == 1:
1218 if n == 1:
1218 return dataOut
1219 return dataOut
1219
1220
1220 dataOut.flagNoData = True
1221 dataOut.flagNoData = True
1221
1222
1222 if not self.isConfig:
1223 if not self.isConfig:
1223 self.setup(dataOut, n, timeInterval, overlapping,DPL )
1224 self.setup(dataOut, n, timeInterval, overlapping,DPL )
1224 self.isConfig = True
1225 self.isConfig = True
1225
1226
1226 if not self.ByLags:
1227 if not self.ByLags:
1227 self.nProfiles=dataOut.nProfiles
1228 self.nProfiles=dataOut.nProfiles
1228 self.nChannels=dataOut.nChannels
1229 self.nChannels=dataOut.nChannels
1229 self.nHeights=dataOut.nHeights
1230 self.nHeights=dataOut.nHeights
1230 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(dataOut.utctime,
1231 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(dataOut.utctime,
1231 dataOut.data_spc,
1232 dataOut.data_spc,
1232 dataOut.data_cspc,
1233 dataOut.data_cspc,
1233 dataOut.data_dc)
1234 dataOut.data_dc)
1234 else:
1235 else:
1235 self.nProfiles=dataOut.nProfiles
1236 self.nProfiles=dataOut.nProfiles
1236 self.nChannels=dataOut.nChannels
1237 self.nChannels=dataOut.nChannels
1237 self.nHeights=dataOut.nHeights
1238 self.nHeights=dataOut.nHeights
1238 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(dataOut.utctime,
1239 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(dataOut.utctime,
1239 dataOut.dataLag_spc,
1240 dataOut.dataLag_spc,
1240 dataOut.dataLag_cspc,
1241 dataOut.dataLag_cspc,
1241 dataOut.dataLag_dc)
1242 dataOut.dataLag_dc)
1242
1243
1243 if self.__dataReady:
1244 if self.__dataReady:
1244
1245
1245 if not self.ByLags:
1246 if not self.ByLags:
1246
1247
1247 dataOut.data_spc = numpy.squeeze(avgdata_spc)
1248 dataOut.data_spc = numpy.squeeze(avgdata_spc)
1248 dataOut.data_cspc = numpy.squeeze(avgdata_cspc)
1249 dataOut.data_cspc = numpy.squeeze(avgdata_cspc)
1249 dataOut.data_dc = avgdata_dc
1250 dataOut.data_dc = avgdata_dc
1250 else:
1251 else:
1251 dataOut.dataLag_spc = avgdata_spc
1252 dataOut.dataLag_spc = avgdata_spc
1252 dataOut.dataLag_cspc = avgdata_cspc
1253 dataOut.dataLag_cspc = avgdata_cspc
1253 dataOut.dataLag_dc = avgdata_dc
1254 dataOut.dataLag_dc = avgdata_dc
1254
1255
1255 dataOut.data_spc=dataOut.dataLag_spc[:,:,:,dataOut.LagPlot]
1256 dataOut.data_spc=dataOut.dataLag_spc[:,:,:,dataOut.LagPlot]
1256 dataOut.data_cspc=dataOut.dataLag_cspc[:,:,:,dataOut.LagPlot]
1257 dataOut.data_cspc=dataOut.dataLag_cspc[:,:,:,dataOut.LagPlot]
1257 dataOut.data_dc=dataOut.dataLag_dc[:,:,dataOut.LagPlot]
1258 dataOut.data_dc=dataOut.dataLag_dc[:,:,dataOut.LagPlot]
1258
1259
1259
1260
1260 dataOut.nIncohInt *= self.n
1261 dataOut.nIncohInt *= self.n
1261 dataOut.utctime = avgdatatime
1262 dataOut.utctime = avgdatatime
1262 dataOut.flagNoData = False
1263 dataOut.flagNoData = False
1263
1264
1264 return dataOut
1265 return dataOut
1265
1266
1266 class removeInterference(Operation):
1267 class removeInterference(Operation):
1267
1268
1268 def removeInterference2(self):
1269 def removeInterference2(self):
1269
1270
1270 cspc = self.dataOut.data_cspc
1271 cspc = self.dataOut.data_cspc
1271 spc = self.dataOut.data_spc
1272 spc = self.dataOut.data_spc
1272 Heights = numpy.arange(cspc.shape[2])
1273 Heights = numpy.arange(cspc.shape[2])
1273 realCspc = numpy.abs(cspc)
1274 realCspc = numpy.abs(cspc)
1274
1275
1275 for i in range(cspc.shape[0]):
1276 for i in range(cspc.shape[0]):
1276 LinePower= numpy.sum(realCspc[i], axis=0)
1277 LinePower= numpy.sum(realCspc[i], axis=0)
1277 Threshold = numpy.amax(LinePower)-numpy.sort(LinePower)[len(Heights)-int(len(Heights)*0.1)]
1278 Threshold = numpy.amax(LinePower)-numpy.sort(LinePower)[len(Heights)-int(len(Heights)*0.1)]
1278 SelectedHeights = Heights[ numpy.where( LinePower < Threshold ) ]
1279 SelectedHeights = Heights[ numpy.where( LinePower < Threshold ) ]
1279 InterferenceSum = numpy.sum( realCspc[i,:,SelectedHeights], axis=0 )
1280 InterferenceSum = numpy.sum( realCspc[i,:,SelectedHeights], axis=0 )
1280 InterferenceThresholdMin = numpy.sort(InterferenceSum)[int(len(InterferenceSum)*0.98)]
1281 InterferenceThresholdMin = numpy.sort(InterferenceSum)[int(len(InterferenceSum)*0.98)]
1281 InterferenceThresholdMax = numpy.sort(InterferenceSum)[int(len(InterferenceSum)*0.99)]
1282 InterferenceThresholdMax = numpy.sort(InterferenceSum)[int(len(InterferenceSum)*0.99)]
1282
1283
1283
1284
1284 InterferenceRange = numpy.where( ([InterferenceSum > InterferenceThresholdMin]))# , InterferenceSum < InterferenceThresholdMax]) )
1285 InterferenceRange = numpy.where( ([InterferenceSum > InterferenceThresholdMin]))# , InterferenceSum < InterferenceThresholdMax]) )
1285 #InterferenceRange = numpy.where( ([InterferenceRange < InterferenceThresholdMax]))
1286 #InterferenceRange = numpy.where( ([InterferenceRange < InterferenceThresholdMax]))
1286 if len(InterferenceRange)<int(cspc.shape[1]*0.3):
1287 if len(InterferenceRange)<int(cspc.shape[1]*0.3):
1287 cspc[i,InterferenceRange,:] = numpy.NaN
1288 cspc[i,InterferenceRange,:] = numpy.NaN
1288
1289
1289 self.dataOut.data_cspc = cspc
1290 self.dataOut.data_cspc = cspc
1290
1291
1291 def removeInterference(self, interf = 2, hei_interf = None, nhei_interf = None, offhei_interf = None):
1292 def removeInterference(self, interf = 2, hei_interf = None, nhei_interf = None, offhei_interf = None):
1292
1293
1293 jspectra = self.dataOut.data_spc
1294 jspectra = self.dataOut.data_spc
1294 jcspectra = self.dataOut.data_cspc
1295 jcspectra = self.dataOut.data_cspc
1295 jnoise = self.dataOut.getNoise()
1296 jnoise = self.dataOut.getNoise()
1296 num_incoh = self.dataOut.nIncohInt
1297 num_incoh = self.dataOut.nIncohInt
1297
1298
1298 num_channel = jspectra.shape[0]
1299 num_channel = jspectra.shape[0]
1299 num_prof = jspectra.shape[1]
1300 num_prof = jspectra.shape[1]
1300 num_hei = jspectra.shape[2]
1301 num_hei = jspectra.shape[2]
1301
1302
1302 # hei_interf
1303 # hei_interf
1303 if hei_interf is None:
1304 if hei_interf is None:
1304 count_hei = int(num_hei / 2)
1305 count_hei = int(num_hei / 2)
1305 hei_interf = numpy.asmatrix(list(range(count_hei))) + num_hei - count_hei
1306 hei_interf = numpy.asmatrix(list(range(count_hei))) + num_hei - count_hei
1306 hei_interf = numpy.asarray(hei_interf)[0]
1307 hei_interf = numpy.asarray(hei_interf)[0]
1307 # nhei_interf
1308 # nhei_interf
1308 if (nhei_interf == None):
1309 if (nhei_interf == None):
1309 nhei_interf = 5
1310 nhei_interf = 5
1310 if (nhei_interf < 1):
1311 if (nhei_interf < 1):
1311 nhei_interf = 1
1312 nhei_interf = 1
1312 if (nhei_interf > count_hei):
1313 if (nhei_interf > count_hei):
1313 nhei_interf = count_hei
1314 nhei_interf = count_hei
1314 if (offhei_interf == None):
1315 if (offhei_interf == None):
1315 offhei_interf = 0
1316 offhei_interf = 0
1316
1317
1317 ind_hei = list(range(num_hei))
1318 ind_hei = list(range(num_hei))
1318 # mask_prof = numpy.asarray(range(num_prof - 2)) + 1
1319 # mask_prof = numpy.asarray(range(num_prof - 2)) + 1
1319 # mask_prof[range(num_prof/2 - 1,len(mask_prof))] += 1
1320 # mask_prof[range(num_prof/2 - 1,len(mask_prof))] += 1
1320 mask_prof = numpy.asarray(list(range(num_prof)))
1321 mask_prof = numpy.asarray(list(range(num_prof)))
1321 num_mask_prof = mask_prof.size
1322 num_mask_prof = mask_prof.size
1322 comp_mask_prof = [0, num_prof / 2]
1323 comp_mask_prof = [0, num_prof / 2]
1323
1324
1324 # noise_exist: Determina si la variable jnoise ha sido definida y contiene la informacion del ruido de cada canal
1325 # noise_exist: Determina si la variable jnoise ha sido definida y contiene la informacion del ruido de cada canal
1325 if (jnoise.size < num_channel or numpy.isnan(jnoise).any()):
1326 if (jnoise.size < num_channel or numpy.isnan(jnoise).any()):
1326 jnoise = numpy.nan
1327 jnoise = numpy.nan
1327 noise_exist = jnoise[0] < numpy.Inf
1328 noise_exist = jnoise[0] < numpy.Inf
1328
1329
1329 # Subrutina de Remocion de la Interferencia
1330 # Subrutina de Remocion de la Interferencia
1330 for ich in range(num_channel):
1331 for ich in range(num_channel):
1331 # Se ordena los espectros segun su potencia (menor a mayor)
1332 # Se ordena los espectros segun su potencia (menor a mayor)
1332 power = jspectra[ich, mask_prof, :]
1333 power = jspectra[ich, mask_prof, :]
1333 power = power[:, hei_interf]
1334 power = power[:, hei_interf]
1334 power = power.sum(axis=0)
1335 power = power.sum(axis=0)
1335 psort = power.ravel().argsort()
1336 psort = power.ravel().argsort()
1336
1337
1337 # Se estima la interferencia promedio en los Espectros de Potencia empleando
1338 # Se estima la interferencia promedio en los Espectros de Potencia empleando
1338 junkspc_interf = jspectra[ich, :, hei_interf[psort[list(range(
1339 junkspc_interf = jspectra[ich, :, hei_interf[psort[list(range(
1339 offhei_interf, nhei_interf + offhei_interf))]]]
1340 offhei_interf, nhei_interf + offhei_interf))]]]
1340
1341
1341 if noise_exist:
1342 if noise_exist:
1342 # tmp_noise = jnoise[ich] / num_prof
1343 # tmp_noise = jnoise[ich] / num_prof
1343 tmp_noise = jnoise[ich]
1344 tmp_noise = jnoise[ich]
1344 junkspc_interf = junkspc_interf - tmp_noise
1345 junkspc_interf = junkspc_interf - tmp_noise
1345 #junkspc_interf[:,comp_mask_prof] = 0
1346 #junkspc_interf[:,comp_mask_prof] = 0
1346
1347
1347 jspc_interf = junkspc_interf.sum(axis=0) / nhei_interf
1348 jspc_interf = junkspc_interf.sum(axis=0) / nhei_interf
1348 jspc_interf = jspc_interf.transpose()
1349 jspc_interf = jspc_interf.transpose()
1349 # Calculando el espectro de interferencia promedio
1350 # Calculando el espectro de interferencia promedio
1350 noiseid = numpy.where(
1351 noiseid = numpy.where(
1351 jspc_interf <= tmp_noise / numpy.sqrt(num_incoh))
1352 jspc_interf <= tmp_noise / numpy.sqrt(num_incoh))
1352 noiseid = noiseid[0]
1353 noiseid = noiseid[0]
1353 cnoiseid = noiseid.size
1354 cnoiseid = noiseid.size
1354 interfid = numpy.where(
1355 interfid = numpy.where(
1355 jspc_interf > tmp_noise / numpy.sqrt(num_incoh))
1356 jspc_interf > tmp_noise / numpy.sqrt(num_incoh))
1356 interfid = interfid[0]
1357 interfid = interfid[0]
1357 cinterfid = interfid.size
1358 cinterfid = interfid.size
1358
1359
1359 if (cnoiseid > 0):
1360 if (cnoiseid > 0):
1360 jspc_interf[noiseid] = 0
1361 jspc_interf[noiseid] = 0
1361
1362
1362 # Expandiendo los perfiles a limpiar
1363 # Expandiendo los perfiles a limpiar
1363 if (cinterfid > 0):
1364 if (cinterfid > 0):
1364 new_interfid = (
1365 new_interfid = (
1365 numpy.r_[interfid - 1, interfid, interfid + 1] + num_prof) % num_prof
1366 numpy.r_[interfid - 1, interfid, interfid + 1] + num_prof) % num_prof
1366 new_interfid = numpy.asarray(new_interfid)
1367 new_interfid = numpy.asarray(new_interfid)
1367 new_interfid = {x for x in new_interfid}
1368 new_interfid = {x for x in new_interfid}
1368 new_interfid = numpy.array(list(new_interfid))
1369 new_interfid = numpy.array(list(new_interfid))
1369 new_cinterfid = new_interfid.size
1370 new_cinterfid = new_interfid.size
1370 else:
1371 else:
1371 new_cinterfid = 0
1372 new_cinterfid = 0
1372
1373
1373 for ip in range(new_cinterfid):
1374 for ip in range(new_cinterfid):
1374 ind = junkspc_interf[:, new_interfid[ip]].ravel().argsort()
1375 ind = junkspc_interf[:, new_interfid[ip]].ravel().argsort()
1375 jspc_interf[new_interfid[ip]
1376 jspc_interf[new_interfid[ip]
1376 ] = junkspc_interf[ind[nhei_interf // 2], new_interfid[ip]]
1377 ] = junkspc_interf[ind[nhei_interf // 2], new_interfid[ip]]
1377
1378
1378 jspectra[ich, :, ind_hei] = jspectra[ich, :,
1379 jspectra[ich, :, ind_hei] = jspectra[ich, :,
1379 ind_hei] - jspc_interf # Corregir indices
1380 ind_hei] - jspc_interf # Corregir indices
1380
1381
1381 # Removiendo la interferencia del punto de mayor interferencia
1382 # Removiendo la interferencia del punto de mayor interferencia
1382 ListAux = jspc_interf[mask_prof].tolist()
1383 ListAux = jspc_interf[mask_prof].tolist()
1383 maxid = ListAux.index(max(ListAux))
1384 maxid = ListAux.index(max(ListAux))
1384
1385
1385 if cinterfid > 0:
1386 if cinterfid > 0:
1386 for ip in range(cinterfid * (interf == 2) - 1):
1387 for ip in range(cinterfid * (interf == 2) - 1):
1387 ind = (jspectra[ich, interfid[ip], :] < tmp_noise *
1388 ind = (jspectra[ich, interfid[ip], :] < tmp_noise *
1388 (1 + 1 / numpy.sqrt(num_incoh))).nonzero()
1389 (1 + 1 / numpy.sqrt(num_incoh))).nonzero()
1389 cind = len(ind)
1390 cind = len(ind)
1390
1391
1391 if (cind > 0):
1392 if (cind > 0):
1392 jspectra[ich, interfid[ip], ind] = tmp_noise * \
1393 jspectra[ich, interfid[ip], ind] = tmp_noise * \
1393 (1 + (numpy.random.uniform(cind) - 0.5) /
1394 (1 + (numpy.random.uniform(cind) - 0.5) /
1394 numpy.sqrt(num_incoh))
1395 numpy.sqrt(num_incoh))
1395
1396
1396 ind = numpy.array([-2, -1, 1, 2])
1397 ind = numpy.array([-2, -1, 1, 2])
1397 xx = numpy.zeros([4, 4])
1398 xx = numpy.zeros([4, 4])
1398
1399
1399 for id1 in range(4):
1400 for id1 in range(4):
1400 xx[:, id1] = ind[id1]**numpy.asarray(list(range(4)))
1401 xx[:, id1] = ind[id1]**numpy.asarray(list(range(4)))
1401
1402
1402 xx_inv = numpy.linalg.inv(xx)
1403 xx_inv = numpy.linalg.inv(xx)
1403 xx = xx_inv[:, 0]
1404 xx = xx_inv[:, 0]
1404 ind = (ind + maxid + num_mask_prof) % num_mask_prof
1405 ind = (ind + maxid + num_mask_prof) % num_mask_prof
1405 yy = jspectra[ich, mask_prof[ind], :]
1406 yy = jspectra[ich, mask_prof[ind], :]
1406 jspectra[ich, mask_prof[maxid], :] = numpy.dot(
1407 jspectra[ich, mask_prof[maxid], :] = numpy.dot(
1407 yy.transpose(), xx)
1408 yy.transpose(), xx)
1408
1409
1409 indAux = (jspectra[ich, :, :] < tmp_noise *
1410 indAux = (jspectra[ich, :, :] < tmp_noise *
1410 (1 - 1 / numpy.sqrt(num_incoh))).nonzero()
1411 (1 - 1 / numpy.sqrt(num_incoh))).nonzero()
1411 jspectra[ich, indAux[0], indAux[1]] = tmp_noise * \
1412 jspectra[ich, indAux[0], indAux[1]] = tmp_noise * \
1412 (1 - 1 / numpy.sqrt(num_incoh))
1413 (1 - 1 / numpy.sqrt(num_incoh))
1413
1414
1414 # Remocion de Interferencia en el Cross Spectra
1415 # Remocion de Interferencia en el Cross Spectra
1415 if jcspectra is None:
1416 if jcspectra is None:
1416 return jspectra, jcspectra
1417 return jspectra, jcspectra
1417 num_pairs = int(jcspectra.size / (num_prof * num_hei))
1418 num_pairs = int(jcspectra.size / (num_prof * num_hei))
1418 jcspectra = jcspectra.reshape(num_pairs, num_prof, num_hei)
1419 jcspectra = jcspectra.reshape(num_pairs, num_prof, num_hei)
1419
1420
1420 for ip in range(num_pairs):
1421 for ip in range(num_pairs):
1421
1422
1422 #-------------------------------------------
1423 #-------------------------------------------
1423
1424
1424 cspower = numpy.abs(jcspectra[ip, mask_prof, :])
1425 cspower = numpy.abs(jcspectra[ip, mask_prof, :])
1425 cspower = cspower[:, hei_interf]
1426 cspower = cspower[:, hei_interf]
1426 cspower = cspower.sum(axis=0)
1427 cspower = cspower.sum(axis=0)
1427
1428
1428 cspsort = cspower.ravel().argsort()
1429 cspsort = cspower.ravel().argsort()
1429 junkcspc_interf = jcspectra[ip, :, hei_interf[cspsort[list(range(
1430 junkcspc_interf = jcspectra[ip, :, hei_interf[cspsort[list(range(
1430 offhei_interf, nhei_interf + offhei_interf))]]]
1431 offhei_interf, nhei_interf + offhei_interf))]]]
1431 junkcspc_interf = junkcspc_interf.transpose()
1432 junkcspc_interf = junkcspc_interf.transpose()
1432 jcspc_interf = junkcspc_interf.sum(axis=1) / nhei_interf
1433 jcspc_interf = junkcspc_interf.sum(axis=1) / nhei_interf
1433
1434
1434 ind = numpy.abs(jcspc_interf[mask_prof]).ravel().argsort()
1435 ind = numpy.abs(jcspc_interf[mask_prof]).ravel().argsort()
1435
1436
1436 median_real = int(numpy.median(numpy.real(
1437 median_real = int(numpy.median(numpy.real(
1437 junkcspc_interf[mask_prof[ind[list(range(3 * num_prof // 4))]], :])))
1438 junkcspc_interf[mask_prof[ind[list(range(3 * num_prof // 4))]], :])))
1438 median_imag = int(numpy.median(numpy.imag(
1439 median_imag = int(numpy.median(numpy.imag(
1439 junkcspc_interf[mask_prof[ind[list(range(3 * num_prof // 4))]], :])))
1440 junkcspc_interf[mask_prof[ind[list(range(3 * num_prof // 4))]], :])))
1440 comp_mask_prof = [int(e) for e in comp_mask_prof]
1441 comp_mask_prof = [int(e) for e in comp_mask_prof]
1441 junkcspc_interf[comp_mask_prof, :] = numpy.complex(
1442 junkcspc_interf[comp_mask_prof, :] = numpy.complex(
1442 median_real, median_imag)
1443 median_real, median_imag)
1443
1444
1444 for iprof in range(num_prof):
1445 for iprof in range(num_prof):
1445 ind = numpy.abs(junkcspc_interf[iprof, :]).ravel().argsort()
1446 ind = numpy.abs(junkcspc_interf[iprof, :]).ravel().argsort()
1446 jcspc_interf[iprof] = junkcspc_interf[iprof, ind[nhei_interf // 2]]
1447 jcspc_interf[iprof] = junkcspc_interf[iprof, ind[nhei_interf // 2]]
1447
1448
1448 # Removiendo la Interferencia
1449 # Removiendo la Interferencia
1449 jcspectra[ip, :, ind_hei] = jcspectra[ip,
1450 jcspectra[ip, :, ind_hei] = jcspectra[ip,
1450 :, ind_hei] - jcspc_interf
1451 :, ind_hei] - jcspc_interf
1451
1452
1452 ListAux = numpy.abs(jcspc_interf[mask_prof]).tolist()
1453 ListAux = numpy.abs(jcspc_interf[mask_prof]).tolist()
1453 maxid = ListAux.index(max(ListAux))
1454 maxid = ListAux.index(max(ListAux))
1454
1455
1455 ind = numpy.array([-2, -1, 1, 2])
1456 ind = numpy.array([-2, -1, 1, 2])
1456 xx = numpy.zeros([4, 4])
1457 xx = numpy.zeros([4, 4])
1457
1458
1458 for id1 in range(4):
1459 for id1 in range(4):
1459 xx[:, id1] = ind[id1]**numpy.asarray(list(range(4)))
1460 xx[:, id1] = ind[id1]**numpy.asarray(list(range(4)))
1460
1461
1461 xx_inv = numpy.linalg.inv(xx)
1462 xx_inv = numpy.linalg.inv(xx)
1462 xx = xx_inv[:, 0]
1463 xx = xx_inv[:, 0]
1463
1464
1464 ind = (ind + maxid + num_mask_prof) % num_mask_prof
1465 ind = (ind + maxid + num_mask_prof) % num_mask_prof
1465 yy = jcspectra[ip, mask_prof[ind], :]
1466 yy = jcspectra[ip, mask_prof[ind], :]
1466 jcspectra[ip, mask_prof[maxid], :] = numpy.dot(yy.transpose(), xx)
1467 jcspectra[ip, mask_prof[maxid], :] = numpy.dot(yy.transpose(), xx)
1467
1468
1468 # Guardar Resultados
1469 # Guardar Resultados
1469 self.dataOut.data_spc = jspectra
1470 self.dataOut.data_spc = jspectra
1470 self.dataOut.data_cspc = jcspectra
1471 self.dataOut.data_cspc = jcspectra
1471
1472
1472 return 1
1473 return 1
1473
1474
1474 def run(self, dataOut, interf = 2,hei_interf = None, nhei_interf = None, offhei_interf = None, mode=1):
1475 def run(self, dataOut, interf = 2,hei_interf = None, nhei_interf = None, offhei_interf = None, mode=1):
1475
1476
1476 self.dataOut = dataOut
1477 self.dataOut = dataOut
1477
1478
1478 if mode == 1:
1479 if mode == 1:
1479 self.removeInterference(interf = 2,hei_interf = None, nhei_interf = None, offhei_interf = None)
1480 self.removeInterference(interf = 2,hei_interf = None, nhei_interf = None, offhei_interf = None)
1480 elif mode == 2:
1481 elif mode == 2:
1481 self.removeInterference2()
1482 self.removeInterference2()
1482
1483
1483 return self.dataOut
1484 return self.dataOut
1484
1485
1485
1486
1486 class IncohInt(Operation):
1487 class IncohInt(Operation):
1487
1488
1488 __profIndex = 0
1489 __profIndex = 0
1489 __withOverapping = False
1490 __withOverapping = False
1490
1491
1491 __byTime = False
1492 __byTime = False
1492 __initime = None
1493 __initime = None
1493 __lastdatatime = None
1494 __lastdatatime = None
1494 __integrationtime = None
1495 __integrationtime = None
1495
1496
1496 __buffer_spc = None
1497 __buffer_spc = None
1497 __buffer_cspc = None
1498 __buffer_cspc = None
1498 __buffer_dc = None
1499 __buffer_dc = None
1499
1500
1500 __dataReady = False
1501 __dataReady = False
1501
1502
1502 __timeInterval = None
1503 __timeInterval = None
1503
1504
1504 n = None
1505 n = None
1505
1506
1506 def __init__(self):
1507 def __init__(self):
1507
1508
1508 Operation.__init__(self)
1509 Operation.__init__(self)
1509
1510
1510 def setup(self, n=None, timeInterval=None, overlapping=False):
1511 def setup(self, n=None, timeInterval=None, overlapping=False):
1511 """
1512 """
1512 Set the parameters of the integration class.
1513 Set the parameters of the integration class.
1513
1514
1514 Inputs:
1515 Inputs:
1515
1516
1516 n : Number of coherent integrations
1517 n : Number of coherent integrations
1517 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
1518 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
1518 overlapping :
1519 overlapping :
1519
1520
1520 """
1521 """
1521
1522
1522 self.__initime = None
1523 self.__initime = None
1523 self.__lastdatatime = 0
1524 self.__lastdatatime = 0
1524
1525
1525 self.__buffer_spc = 0
1526 self.__buffer_spc = 0
1526 self.__buffer_cspc = 0
1527 self.__buffer_cspc = 0
1527 self.__buffer_dc = 0
1528 self.__buffer_dc = 0
1528
1529
1529 self.__profIndex = 0
1530 self.__profIndex = 0
1530 self.__dataReady = False
1531 self.__dataReady = False
1531 self.__byTime = False
1532 self.__byTime = False
1532
1533
1533 if n is None and timeInterval is None:
1534 if n is None and timeInterval is None:
1534 raise ValueError("n or timeInterval should be specified ...")
1535 raise ValueError("n or timeInterval should be specified ...")
1535
1536
1536 if n is not None:
1537 if n is not None:
1537 self.n = int(n)
1538 self.n = int(n)
1538 else:
1539 else:
1539
1540
1540 self.__integrationtime = int(timeInterval)
1541 self.__integrationtime = int(timeInterval)
1541 self.n = None
1542 self.n = None
1542 self.__byTime = True
1543 self.__byTime = True
1543
1544
1544 def putData(self, data_spc, data_cspc, data_dc):
1545 def putData(self, data_spc, data_cspc, data_dc):
1545 """
1546 """
1546 Add a profile to the __buffer_spc and increase in one the __profileIndex
1547 Add a profile to the __buffer_spc and increase in one the __profileIndex
1547
1548
1548 """
1549 """
1549
1550
1550 self.__buffer_spc += data_spc
1551 self.__buffer_spc += data_spc
1551
1552
1552 if data_cspc is None:
1553 if data_cspc is None:
1553 self.__buffer_cspc = None
1554 self.__buffer_cspc = None
1554 else:
1555 else:
1555 self.__buffer_cspc += data_cspc
1556 self.__buffer_cspc += data_cspc
1556
1557
1557 if data_dc is None:
1558 if data_dc is None:
1558 self.__buffer_dc = None
1559 self.__buffer_dc = None
1559 else:
1560 else:
1560 self.__buffer_dc += data_dc
1561 self.__buffer_dc += data_dc
1561
1562
1562 self.__profIndex += 1
1563 self.__profIndex += 1
1563
1564
1564 return
1565 return
1565
1566
1566 def pushData(self):
1567 def pushData(self):
1567 """
1568 """
1568 Return the sum of the last profiles and the profiles used in the sum.
1569 Return the sum of the last profiles and the profiles used in the sum.
1569
1570
1570 Affected:
1571 Affected:
1571
1572
1572 self.__profileIndex
1573 self.__profileIndex
1573
1574
1574 """
1575 """
1575
1576
1576 data_spc = self.__buffer_spc
1577 data_spc = self.__buffer_spc
1577 data_cspc = self.__buffer_cspc
1578 data_cspc = self.__buffer_cspc
1578 data_dc = self.__buffer_dc
1579 data_dc = self.__buffer_dc
1579 n = self.__profIndex
1580 n = self.__profIndex
1580
1581
1581 self.__buffer_spc = 0
1582 self.__buffer_spc = 0
1582 self.__buffer_cspc = 0
1583 self.__buffer_cspc = 0
1583 self.__buffer_dc = 0
1584 self.__buffer_dc = 0
1584 self.__profIndex = 0
1585 self.__profIndex = 0
1585
1586
1586 return data_spc, data_cspc, data_dc, n
1587 return data_spc, data_cspc, data_dc, n
1587
1588
1588 def byProfiles(self, *args):
1589 def byProfiles(self, *args):
1589
1590
1590 self.__dataReady = False
1591 self.__dataReady = False
1591 avgdata_spc = None
1592 avgdata_spc = None
1592 avgdata_cspc = None
1593 avgdata_cspc = None
1593 avgdata_dc = None
1594 avgdata_dc = None
1594
1595
1595 self.putData(*args)
1596 self.putData(*args)
1596
1597
1597 if self.__profIndex == self.n:
1598 if self.__profIndex == self.n:
1598
1599
1599 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1600 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1600 self.n = n
1601 self.n = n
1601 self.__dataReady = True
1602 self.__dataReady = True
1602
1603
1603 return avgdata_spc, avgdata_cspc, avgdata_dc
1604 return avgdata_spc, avgdata_cspc, avgdata_dc
1604
1605
1605 def byTime(self, datatime, *args):
1606 def byTime(self, datatime, *args):
1606
1607
1607 self.__dataReady = False
1608 self.__dataReady = False
1608 avgdata_spc = None
1609 avgdata_spc = None
1609 avgdata_cspc = None
1610 avgdata_cspc = None
1610 avgdata_dc = None
1611 avgdata_dc = None
1611
1612
1612 self.putData(*args)
1613 self.putData(*args)
1613
1614
1614 if (datatime - self.__initime) >= self.__integrationtime:
1615 if (datatime - self.__initime) >= self.__integrationtime:
1615 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1616 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1616 self.n = n
1617 self.n = n
1617 self.__dataReady = True
1618 self.__dataReady = True
1618
1619
1619 return avgdata_spc, avgdata_cspc, avgdata_dc
1620 return avgdata_spc, avgdata_cspc, avgdata_dc
1620
1621
1621 def integrate(self, datatime, *args):
1622 def integrate(self, datatime, *args):
1622
1623
1623 if self.__profIndex == 0:
1624 if self.__profIndex == 0:
1624 self.__initime = datatime
1625 self.__initime = datatime
1625
1626
1626 if self.__byTime:
1627 if self.__byTime:
1627 avgdata_spc, avgdata_cspc, avgdata_dc = self.byTime(
1628 avgdata_spc, avgdata_cspc, avgdata_dc = self.byTime(
1628 datatime, *args)
1629 datatime, *args)
1629 else:
1630 else:
1630 avgdata_spc, avgdata_cspc, avgdata_dc = self.byProfiles(*args)
1631 avgdata_spc, avgdata_cspc, avgdata_dc = self.byProfiles(*args)
1631
1632
1632 if not self.__dataReady:
1633 if not self.__dataReady:
1633 return None, None, None, None
1634 return None, None, None, None
1634
1635
1635 return self.__initime, avgdata_spc, avgdata_cspc, avgdata_dc
1636 return self.__initime, avgdata_spc, avgdata_cspc, avgdata_dc
1636
1637
1637 def run(self, dataOut, n=None, timeInterval=None, overlapping=False):
1638 def run(self, dataOut, n=None, timeInterval=None, overlapping=False):
1638 if n == 1:
1639 if n == 1:
1639 return dataOut
1640 return dataOut
1640
1641
1641 dataOut.flagNoData = True
1642 dataOut.flagNoData = True
1642
1643
1643 if not self.isConfig:
1644 if not self.isConfig:
1644 self.setup(n, timeInterval, overlapping)
1645 self.setup(n, timeInterval, overlapping)
1645 self.isConfig = True
1646 self.isConfig = True
1646
1647
1647 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(dataOut.utctime,
1648 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(dataOut.utctime,
1648 dataOut.data_spc,
1649 dataOut.data_spc,
1649 dataOut.data_cspc,
1650 dataOut.data_cspc,
1650 dataOut.data_dc)
1651 dataOut.data_dc)
1651
1652
1652 if self.__dataReady:
1653 if self.__dataReady:
1653
1654
1654 dataOut.data_spc = avgdata_spc
1655 dataOut.data_spc = avgdata_spc
1655 dataOut.data_cspc = avgdata_cspc
1656 dataOut.data_cspc = avgdata_cspc
1656 dataOut.data_dc = avgdata_dc
1657 dataOut.data_dc = avgdata_dc
1657 dataOut.nIncohInt *= self.n
1658 dataOut.nIncohInt *= self.n
1658 dataOut.utctime = avgdatatime
1659 dataOut.utctime = avgdatatime
1659 dataOut.flagNoData = False
1660 dataOut.flagNoData = False
1660
1661
1661 return dataOut
1662 return dataOut
1662
1663
1663 class dopplerFlip(Operation):
1664 class dopplerFlip(Operation):
1664
1665
1665 def run(self, dataOut):
1666 def run(self, dataOut):
1666 # arreglo 1: (num_chan, num_profiles, num_heights)
1667 # arreglo 1: (num_chan, num_profiles, num_heights)
1667 self.dataOut = dataOut
1668 self.dataOut = dataOut
1668 # JULIA-oblicua, indice 2
1669 # JULIA-oblicua, indice 2
1669 # arreglo 2: (num_profiles, num_heights)
1670 # arreglo 2: (num_profiles, num_heights)
1670 jspectra = self.dataOut.data_spc[2]
1671 jspectra = self.dataOut.data_spc[2]
1671 jspectra_tmp = numpy.zeros(jspectra.shape)
1672 jspectra_tmp = numpy.zeros(jspectra.shape)
1672 num_profiles = jspectra.shape[0]
1673 num_profiles = jspectra.shape[0]
1673 freq_dc = int(num_profiles / 2)
1674 freq_dc = int(num_profiles / 2)
1674 # Flip con for
1675 # Flip con for
1675 for j in range(num_profiles):
1676 for j in range(num_profiles):
1676 jspectra_tmp[num_profiles-j-1]= jspectra[j]
1677 jspectra_tmp[num_profiles-j-1]= jspectra[j]
1677 # Intercambio perfil de DC con perfil inmediato anterior
1678 # Intercambio perfil de DC con perfil inmediato anterior
1678 jspectra_tmp[freq_dc-1]= jspectra[freq_dc-1]
1679 jspectra_tmp[freq_dc-1]= jspectra[freq_dc-1]
1679 jspectra_tmp[freq_dc]= jspectra[freq_dc]
1680 jspectra_tmp[freq_dc]= jspectra[freq_dc]
1680 # canal modificado es re-escrito en el arreglo de canales
1681 # canal modificado es re-escrito en el arreglo de canales
1681 self.dataOut.data_spc[2] = jspectra_tmp
1682 self.dataOut.data_spc[2] = jspectra_tmp
1682
1683
1683 return self.dataOut
1684 return self.dataOut
General Comments 0
You need to be logged in to leave comments. Login now