##// END OF EJS Templates
BLTR reader now starts in last block
jespinoza -
r1414:f3c20d0284ef
parent child
Show More
@@ -1,1169 +1,1170
1 # Copyright (c) 2012-2020 Jicamarca Radio Observatory
1 # Copyright (c) 2012-2020 Jicamarca Radio Observatory
2 # All rights reserved.
2 # All rights reserved.
3 #
3 #
4 # Distributed under the terms of the BSD 3-clause license.
4 # Distributed under the terms of the BSD 3-clause license.
5 """Definition of diferent Data objects for different types of data
5 """Definition of diferent Data objects for different types of data
6
6
7 Here you will find the diferent data objects for the different types
7 Here you will find the diferent data objects for the different types
8 of data, this data objects must be used as dataIn or dataOut objects in
8 of data, this data objects must be used as dataIn or dataOut objects in
9 processing units and operations. Currently the supported data objects are:
9 processing units and operations. Currently the supported data objects are:
10 Voltage, Spectra, SpectraHeis, Fits, Correlation and Parameters
10 Voltage, Spectra, SpectraHeis, Fits, Correlation and Parameters
11 """
11 """
12
12
13 import copy
13 import copy
14 import numpy
14 import numpy
15 import datetime
15 import datetime
16 import json
16 import json
17
17
18 import schainpy.admin
18 import schainpy.admin
19 from schainpy.utils import log
19 from schainpy.utils import log
20 from .jroheaderIO import SystemHeader, RadarControllerHeader
20 from .jroheaderIO import SystemHeader, RadarControllerHeader
21 from schainpy.model.data import _noise
21 from schainpy.model.data import _noise
22
22
23
23
24 def getNumpyDtype(dataTypeCode):
24 def getNumpyDtype(dataTypeCode):
25
25
26 if dataTypeCode == 0:
26 if dataTypeCode == 0:
27 numpyDtype = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
27 numpyDtype = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
28 elif dataTypeCode == 1:
28 elif dataTypeCode == 1:
29 numpyDtype = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
29 numpyDtype = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
30 elif dataTypeCode == 2:
30 elif dataTypeCode == 2:
31 numpyDtype = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
31 numpyDtype = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
32 elif dataTypeCode == 3:
32 elif dataTypeCode == 3:
33 numpyDtype = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
33 numpyDtype = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
34 elif dataTypeCode == 4:
34 elif dataTypeCode == 4:
35 numpyDtype = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
35 numpyDtype = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
36 elif dataTypeCode == 5:
36 elif dataTypeCode == 5:
37 numpyDtype = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
37 numpyDtype = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
38 else:
38 else:
39 raise ValueError('dataTypeCode was not defined')
39 raise ValueError('dataTypeCode was not defined')
40
40
41 return numpyDtype
41 return numpyDtype
42
42
43
43
44 def getDataTypeCode(numpyDtype):
44 def getDataTypeCode(numpyDtype):
45
45
46 if numpyDtype == numpy.dtype([('real', '<i1'), ('imag', '<i1')]):
46 if numpyDtype == numpy.dtype([('real', '<i1'), ('imag', '<i1')]):
47 datatype = 0
47 datatype = 0
48 elif numpyDtype == numpy.dtype([('real', '<i2'), ('imag', '<i2')]):
48 elif numpyDtype == numpy.dtype([('real', '<i2'), ('imag', '<i2')]):
49 datatype = 1
49 datatype = 1
50 elif numpyDtype == numpy.dtype([('real', '<i4'), ('imag', '<i4')]):
50 elif numpyDtype == numpy.dtype([('real', '<i4'), ('imag', '<i4')]):
51 datatype = 2
51 datatype = 2
52 elif numpyDtype == numpy.dtype([('real', '<i8'), ('imag', '<i8')]):
52 elif numpyDtype == numpy.dtype([('real', '<i8'), ('imag', '<i8')]):
53 datatype = 3
53 datatype = 3
54 elif numpyDtype == numpy.dtype([('real', '<f4'), ('imag', '<f4')]):
54 elif numpyDtype == numpy.dtype([('real', '<f4'), ('imag', '<f4')]):
55 datatype = 4
55 datatype = 4
56 elif numpyDtype == numpy.dtype([('real', '<f8'), ('imag', '<f8')]):
56 elif numpyDtype == numpy.dtype([('real', '<f8'), ('imag', '<f8')]):
57 datatype = 5
57 datatype = 5
58 else:
58 else:
59 datatype = None
59 datatype = None
60
60
61 return datatype
61 return datatype
62
62
63
63
64 def hildebrand_sekhon(data, navg):
64 def hildebrand_sekhon(data, navg):
65 """
65 """
66 This method is for the objective determination of the noise level in Doppler spectra. This
66 This method is for the objective determination of the noise level in Doppler spectra. This
67 implementation technique is based on the fact that the standard deviation of the spectral
67 implementation technique is based on the fact that the standard deviation of the spectral
68 densities is equal to the mean spectral density for white Gaussian noise
68 densities is equal to the mean spectral density for white Gaussian noise
69
69
70 Inputs:
70 Inputs:
71 Data : heights
71 Data : heights
72 navg : numbers of averages
72 navg : numbers of averages
73
73
74 Return:
74 Return:
75 mean : noise's level
75 mean : noise's level
76 """
76 """
77
77
78 sortdata = numpy.sort(data, axis=None)
78 sortdata = numpy.sort(data, axis=None)
79 #print(numpy.shape(data))
79 #print(numpy.shape(data))
80 #exit()
80 #exit()
81 '''
81 '''
82 lenOfData = len(sortdata)
82 lenOfData = len(sortdata)
83 nums_min = lenOfData*0.2
83 nums_min = lenOfData*0.2
84
84
85 if nums_min <= 5:
85 if nums_min <= 5:
86
86
87 nums_min = 5
87 nums_min = 5
88
88
89 sump = 0.
89 sump = 0.
90 sumq = 0.
90 sumq = 0.
91
91
92 j = 0
92 j = 0
93 cont = 1
93 cont = 1
94
94
95 while((cont == 1)and(j < lenOfData)):
95 while((cont == 1)and(j < lenOfData)):
96
96
97 sump += sortdata[j]
97 sump += sortdata[j]
98 sumq += sortdata[j]**2
98 sumq += sortdata[j]**2
99
99
100 if j > nums_min:
100 if j > nums_min:
101 rtest = float(j)/(j-1) + 1.0/navg
101 rtest = float(j)/(j-1) + 1.0/navg
102 if ((sumq*j) > (rtest*sump**2)):
102 if ((sumq*j) > (rtest*sump**2)):
103 j = j - 1
103 j = j - 1
104 sump = sump - sortdata[j]
104 sump = sump - sortdata[j]
105 sumq = sumq - sortdata[j]**2
105 sumq = sumq - sortdata[j]**2
106 cont = 0
106 cont = 0
107
107
108 j += 1
108 j += 1
109
109
110 lnoise = sump / j
110 lnoise = sump / j
111 '''
111 '''
112 return _noise.hildebrand_sekhon(sortdata, navg)
112 return _noise.hildebrand_sekhon(sortdata, navg)
113
113
114
114
115 class Beam:
115 class Beam:
116
116
117 def __init__(self):
117 def __init__(self):
118 self.codeList = []
118 self.codeList = []
119 self.azimuthList = []
119 self.azimuthList = []
120 self.zenithList = []
120 self.zenithList = []
121
121
122
122
123 class GenericData(object):
123 class GenericData(object):
124
124
125 flagNoData = True
125 flagNoData = True
126
126
127 def copy(self, inputObj=None):
127 def copy(self, inputObj=None):
128
128
129 if inputObj == None:
129 if inputObj == None:
130 return copy.deepcopy(self)
130 return copy.deepcopy(self)
131
131
132 for key in list(inputObj.__dict__.keys()):
132 for key in list(inputObj.__dict__.keys()):
133
133
134 attribute = inputObj.__dict__[key]
134 attribute = inputObj.__dict__[key]
135
135
136 # If this attribute is a tuple or list
136 # If this attribute is a tuple or list
137 if type(inputObj.__dict__[key]) in (tuple, list):
137 if type(inputObj.__dict__[key]) in (tuple, list):
138 self.__dict__[key] = attribute[:]
138 self.__dict__[key] = attribute[:]
139 continue
139 continue
140
140
141 # If this attribute is another object or instance
141 # If this attribute is another object or instance
142 if hasattr(attribute, '__dict__'):
142 if hasattr(attribute, '__dict__'):
143 self.__dict__[key] = attribute.copy()
143 self.__dict__[key] = attribute.copy()
144 continue
144 continue
145
145
146 self.__dict__[key] = inputObj.__dict__[key]
146 self.__dict__[key] = inputObj.__dict__[key]
147
147
148 def deepcopy(self):
148 def deepcopy(self):
149
149
150 return copy.deepcopy(self)
150 return copy.deepcopy(self)
151
151
152 def isEmpty(self):
152 def isEmpty(self):
153
153
154 return self.flagNoData
154 return self.flagNoData
155
155
156 def isReady(self):
156 def isReady(self):
157
157
158 return not self.flagNoData
158 return not self.flagNoData
159
159
160
160
161 class JROData(GenericData):
161 class JROData(GenericData):
162
162
163 systemHeaderObj = SystemHeader()
163 systemHeaderObj = SystemHeader()
164 radarControllerHeaderObj = RadarControllerHeader()
164 radarControllerHeaderObj = RadarControllerHeader()
165 type = None
165 type = None
166 datatype = None # dtype but in string
166 datatype = None # dtype but in string
167 nProfiles = None
167 nProfiles = None
168 heightList = None
168 heightList = None
169 channelList = None
169 channelList = None
170 flagDiscontinuousBlock = False
170 flagDiscontinuousBlock = False
171 useLocalTime = False
171 useLocalTime = False
172 utctime = None
172 utctime = None
173 timeZone = None
173 timeZone = None
174 dstFlag = None
174 dstFlag = None
175 errorCount = None
175 errorCount = None
176 blocksize = None
176 blocksize = None
177 flagDecodeData = False # asumo q la data no esta decodificada
177 flagDecodeData = False # asumo q la data no esta decodificada
178 flagDeflipData = False # asumo q la data no esta sin flip
178 flagDeflipData = False # asumo q la data no esta sin flip
179 flagShiftFFT = False
179 flagShiftFFT = False
180 nCohInt = None
180 nCohInt = None
181 windowOfFilter = 1
181 windowOfFilter = 1
182 C = 3e8
182 C = 3e8
183 frequency = 49.92e6
183 frequency = 49.92e6
184 realtime = False
184 realtime = False
185 beacon_heiIndexList = None
185 beacon_heiIndexList = None
186 last_block = None
186 last_block = None
187 blocknow = None
187 blocknow = None
188 azimuth = None
188 azimuth = None
189 zenith = None
189 zenith = None
190 beam = Beam()
190 beam = Beam()
191 profileIndex = None
191 profileIndex = None
192 error = None
192 error = None
193 data = None
193 data = None
194 nmodes = None
194 nmodes = None
195 metadata_list = ['heightList', 'timeZone', 'type']
195 metadata_list = ['heightList', 'timeZone', 'type']
196
196
197 def __str__(self):
197 def __str__(self):
198
198
199 return '{} - {}'.format(self.type, self.datatime())
199 return '{} - {}'.format(self.type, self.datatime())
200
200
201 def getNoise(self):
201 def getNoise(self):
202
202
203 raise NotImplementedError
203 raise NotImplementedError
204
204
205 @property
205 @property
206 def nChannels(self):
206 def nChannels(self):
207
207
208 return len(self.channelList)
208 return len(self.channelList)
209
209
210 @property
210 @property
211 def channelIndexList(self):
211 def channelIndexList(self):
212
212
213 return list(range(self.nChannels))
213 return list(range(self.nChannels))
214
214
215 @property
215 @property
216 def nHeights(self):
216 def nHeights(self):
217
217
218 return len(self.heightList)
218 return len(self.heightList)
219
219
220 def getDeltaH(self):
220 def getDeltaH(self):
221
221
222 return self.heightList[1] - self.heightList[0]
222 return self.heightList[1] - self.heightList[0]
223
223
224 @property
224 @property
225 def ltctime(self):
225 def ltctime(self):
226
226
227 if self.useLocalTime:
227 if self.useLocalTime:
228 return self.utctime - self.timeZone * 60
228 return self.utctime - self.timeZone * 60
229
229
230 return self.utctime
230 return self.utctime
231
231
232 @property
232 @property
233 def datatime(self):
233 def datatime(self):
234
234
235 datatimeValue = datetime.datetime.utcfromtimestamp(self.ltctime)
235 datatimeValue = datetime.datetime.utcfromtimestamp(self.ltctime)
236 return datatimeValue
236 return datatimeValue
237
237
238 def getTimeRange(self):
238 def getTimeRange(self):
239
239
240 datatime = []
240 datatime = []
241
241
242 datatime.append(self.ltctime)
242 datatime.append(self.ltctime)
243 datatime.append(self.ltctime + self.timeInterval + 1)
243 datatime.append(self.ltctime + self.timeInterval + 1)
244
244
245 datatime = numpy.array(datatime)
245 datatime = numpy.array(datatime)
246
246
247 return datatime
247 return datatime
248
248
249 def getFmaxTimeResponse(self):
249 def getFmaxTimeResponse(self):
250
250
251 period = (10 ** -6) * self.getDeltaH() / (0.15)
251 period = (10 ** -6) * self.getDeltaH() / (0.15)
252
252
253 PRF = 1. / (period * self.nCohInt)
253 PRF = 1. / (period * self.nCohInt)
254
254
255 fmax = PRF
255 fmax = PRF
256
256
257 return fmax
257 return fmax
258
258
259 def getFmax(self):
259 def getFmax(self):
260 PRF = 1. / (self.ippSeconds * self.nCohInt)
260 PRF = 1. / (self.ippSeconds * self.nCohInt)
261
261
262 fmax = PRF
262 fmax = PRF
263 return fmax
263 return fmax
264
264
265 def getVmax(self):
265 def getVmax(self):
266
266
267 _lambda = self.C / self.frequency
267 _lambda = self.C / self.frequency
268
268
269 vmax = self.getFmax() * _lambda / 2
269 vmax = self.getFmax() * _lambda / 2
270
270
271 return vmax
271 return vmax
272
272
273 @property
273 @property
274 def ippSeconds(self):
274 def ippSeconds(self):
275 '''
275 '''
276 '''
276 '''
277 return self.radarControllerHeaderObj.ippSeconds
277 return self.radarControllerHeaderObj.ippSeconds
278
278
279 @ippSeconds.setter
279 @ippSeconds.setter
280 def ippSeconds(self, ippSeconds):
280 def ippSeconds(self, ippSeconds):
281 '''
281 '''
282 '''
282 '''
283 self.radarControllerHeaderObj.ippSeconds = ippSeconds
283 self.radarControllerHeaderObj.ippSeconds = ippSeconds
284
284
285 @property
285 @property
286 def code(self):
286 def code(self):
287 '''
287 '''
288 '''
288 '''
289 return self.radarControllerHeaderObj.code
289 return self.radarControllerHeaderObj.code
290
290
291 @code.setter
291 @code.setter
292 def code(self, code):
292 def code(self, code):
293 '''
293 '''
294 '''
294 '''
295 self.radarControllerHeaderObj.code = code
295 self.radarControllerHeaderObj.code = code
296
296
297 @property
297 @property
298 def nCode(self):
298 def nCode(self):
299 '''
299 '''
300 '''
300 '''
301 return self.radarControllerHeaderObj.nCode
301 return self.radarControllerHeaderObj.nCode
302
302
303 @nCode.setter
303 @nCode.setter
304 def nCode(self, ncode):
304 def nCode(self, ncode):
305 '''
305 '''
306 '''
306 '''
307 self.radarControllerHeaderObj.nCode = ncode
307 self.radarControllerHeaderObj.nCode = ncode
308
308
309 @property
309 @property
310 def nBaud(self):
310 def nBaud(self):
311 '''
311 '''
312 '''
312 '''
313 return self.radarControllerHeaderObj.nBaud
313 return self.radarControllerHeaderObj.nBaud
314
314
315 @nBaud.setter
315 @nBaud.setter
316 def nBaud(self, nbaud):
316 def nBaud(self, nbaud):
317 '''
317 '''
318 '''
318 '''
319 self.radarControllerHeaderObj.nBaud = nbaud
319 self.radarControllerHeaderObj.nBaud = nbaud
320
320
321 @property
321 @property
322 def ipp(self):
322 def ipp(self):
323 '''
323 '''
324 '''
324 '''
325 return self.radarControllerHeaderObj.ipp
325 return self.radarControllerHeaderObj.ipp
326
326
327 @ipp.setter
327 @ipp.setter
328 def ipp(self, ipp):
328 def ipp(self, ipp):
329 '''
329 '''
330 '''
330 '''
331 self.radarControllerHeaderObj.ipp = ipp
331 self.radarControllerHeaderObj.ipp = ipp
332
332
333 @property
333 @property
334 def metadata(self):
334 def metadata(self):
335 '''
335 '''
336 '''
336 '''
337
337
338 return {attr: getattr(self, attr) for attr in self.metadata_list}
338 return {attr: getattr(self, attr) for attr in self.metadata_list}
339
339
340
340
341 class Voltage(JROData):
341 class Voltage(JROData):
342
342
343 dataPP_POW = None
343 dataPP_POW = None
344 dataPP_DOP = None
344 dataPP_DOP = None
345 dataPP_WIDTH = None
345 dataPP_WIDTH = None
346 dataPP_SNR = None
346 dataPP_SNR = None
347
347
348 def __init__(self):
348 def __init__(self):
349 '''
349 '''
350 Constructor
350 Constructor
351 '''
351 '''
352
352
353 self.useLocalTime = True
353 self.useLocalTime = True
354 self.radarControllerHeaderObj = RadarControllerHeader()
354 self.radarControllerHeaderObj = RadarControllerHeader()
355 self.systemHeaderObj = SystemHeader()
355 self.systemHeaderObj = SystemHeader()
356 self.type = "Voltage"
356 self.type = "Voltage"
357 self.data = None
357 self.data = None
358 self.nProfiles = None
358 self.nProfiles = None
359 self.heightList = None
359 self.heightList = None
360 self.channelList = None
360 self.channelList = None
361 self.flagNoData = True
361 self.flagNoData = True
362 self.flagDiscontinuousBlock = False
362 self.flagDiscontinuousBlock = False
363 self.utctime = None
363 self.utctime = None
364 self.timeZone = 0
364 self.timeZone = 0
365 self.dstFlag = None
365 self.dstFlag = None
366 self.errorCount = None
366 self.errorCount = None
367 self.nCohInt = None
367 self.nCohInt = None
368 self.blocksize = None
368 self.blocksize = None
369 self.flagCohInt = False
369 self.flagCohInt = False
370 self.flagDecodeData = False # asumo q la data no esta decodificada
370 self.flagDecodeData = False # asumo q la data no esta decodificada
371 self.flagDeflipData = False # asumo q la data no esta sin flip
371 self.flagDeflipData = False # asumo q la data no esta sin flip
372 self.flagShiftFFT = False
372 self.flagShiftFFT = False
373 self.flagDataAsBlock = False # Asumo que la data es leida perfil a perfil
373 self.flagDataAsBlock = False # Asumo que la data es leida perfil a perfil
374 self.profileIndex = 0
374 self.profileIndex = 0
375 self.metadata_list = ['type', 'heightList', 'timeZone', 'nProfiles', 'channelList', 'nCohInt',
375 self.metadata_list = ['type', 'heightList', 'timeZone', 'nProfiles', 'channelList', 'nCohInt',
376 'code', 'nCode', 'nBaud', 'ippSeconds', 'ipp']
376 'code', 'nCode', 'nBaud', 'ippSeconds', 'ipp']
377
377
378 def getNoisebyHildebrand(self, channel=None):
378 def getNoisebyHildebrand(self, channel=None):
379 """
379 """
380 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
380 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
381
381
382 Return:
382 Return:
383 noiselevel
383 noiselevel
384 """
384 """
385
385
386 if channel != None:
386 if channel != None:
387 data = self.data[channel]
387 data = self.data[channel]
388 nChannels = 1
388 nChannels = 1
389 else:
389 else:
390 data = self.data
390 data = self.data
391 nChannels = self.nChannels
391 nChannels = self.nChannels
392
392
393 noise = numpy.zeros(nChannels)
393 noise = numpy.zeros(nChannels)
394 power = data * numpy.conjugate(data)
394 power = data * numpy.conjugate(data)
395
395
396 for thisChannel in range(nChannels):
396 for thisChannel in range(nChannels):
397 if nChannels == 1:
397 if nChannels == 1:
398 daux = power[:].real
398 daux = power[:].real
399 else:
399 else:
400 daux = power[thisChannel, :].real
400 daux = power[thisChannel, :].real
401 noise[thisChannel] = hildebrand_sekhon(daux, self.nCohInt)
401 noise[thisChannel] = hildebrand_sekhon(daux, self.nCohInt)
402
402
403 return noise
403 return noise
404
404
405 def getNoise(self, type=1, channel=None):
405 def getNoise(self, type=1, channel=None):
406
406
407 if type == 1:
407 if type == 1:
408 noise = self.getNoisebyHildebrand(channel)
408 noise = self.getNoisebyHildebrand(channel)
409
409
410 return noise
410 return noise
411
411
412 def getPower(self, channel=None):
412 def getPower(self, channel=None):
413
413
414 if channel != None:
414 if channel != None:
415 data = self.data[channel]
415 data = self.data[channel]
416 else:
416 else:
417 data = self.data
417 data = self.data
418
418
419 power = data * numpy.conjugate(data)
419 power = data * numpy.conjugate(data)
420 powerdB = 10 * numpy.log10(power.real)
420 powerdB = 10 * numpy.log10(power.real)
421 powerdB = numpy.squeeze(powerdB)
421 powerdB = numpy.squeeze(powerdB)
422
422
423 return powerdB
423 return powerdB
424
424
425 @property
425 @property
426 def timeInterval(self):
426 def timeInterval(self):
427
427
428 return self.ippSeconds * self.nCohInt
428 return self.ippSeconds * self.nCohInt
429
429
430 noise = property(getNoise, "I'm the 'nHeights' property.")
430 noise = property(getNoise, "I'm the 'nHeights' property.")
431
431
432
432
433 class CrossProds(JROData):
433 class CrossProds(JROData):
434
434
435 # data es un numpy array de 2 dmensiones (canales, alturas)
435 # data es un numpy array de 2 dmensiones (canales, alturas)
436 data = None
436 data = None
437
437
438 def __init__(self):
438 def __init__(self):
439 '''
439 '''
440 Constructor
440 Constructor
441 '''
441 '''
442
442
443 self.useLocalTime = True
443 self.useLocalTime = True
444 '''
444 '''
445 self.radarControllerHeaderObj = RadarControllerHeader()
445 self.radarControllerHeaderObj = RadarControllerHeader()
446 self.systemHeaderObj = SystemHeader()
446 self.systemHeaderObj = SystemHeader()
447 self.type = "Voltage"
447 self.type = "Voltage"
448 self.data = None
448 self.data = None
449 # self.dtype = None
449 # self.dtype = None
450 # self.nChannels = 0
450 # self.nChannels = 0
451 # self.nHeights = 0
451 # self.nHeights = 0
452 self.nProfiles = None
452 self.nProfiles = None
453 self.heightList = None
453 self.heightList = None
454 self.channelList = None
454 self.channelList = None
455 # self.channelIndexList = None
455 # self.channelIndexList = None
456 self.flagNoData = True
456 self.flagNoData = True
457 self.flagDiscontinuousBlock = False
457 self.flagDiscontinuousBlock = False
458 self.utctime = None
458 self.utctime = None
459 self.timeZone = None
459 self.timeZone = None
460 self.dstFlag = None
460 self.dstFlag = None
461 self.errorCount = None
461 self.errorCount = None
462 self.nCohInt = None
462 self.nCohInt = None
463 self.blocksize = None
463 self.blocksize = None
464 self.flagDecodeData = False # asumo q la data no esta decodificada
464 self.flagDecodeData = False # asumo q la data no esta decodificada
465 self.flagDeflipData = False # asumo q la data no esta sin flip
465 self.flagDeflipData = False # asumo q la data no esta sin flip
466 self.flagShiftFFT = False
466 self.flagShiftFFT = False
467 self.flagDataAsBlock = False # Asumo que la data es leida perfil a perfil
467 self.flagDataAsBlock = False # Asumo que la data es leida perfil a perfil
468 self.profileIndex = 0
468 self.profileIndex = 0
469
469
470
470
471 def getNoisebyHildebrand(self, channel=None):
471 def getNoisebyHildebrand(self, channel=None):
472
472
473
473
474 if channel != None:
474 if channel != None:
475 data = self.data[channel]
475 data = self.data[channel]
476 nChannels = 1
476 nChannels = 1
477 else:
477 else:
478 data = self.data
478 data = self.data
479 nChannels = self.nChannels
479 nChannels = self.nChannels
480
480
481 noise = numpy.zeros(nChannels)
481 noise = numpy.zeros(nChannels)
482 power = data * numpy.conjugate(data)
482 power = data * numpy.conjugate(data)
483
483
484 for thisChannel in range(nChannels):
484 for thisChannel in range(nChannels):
485 if nChannels == 1:
485 if nChannels == 1:
486 daux = power[:].real
486 daux = power[:].real
487 else:
487 else:
488 daux = power[thisChannel, :].real
488 daux = power[thisChannel, :].real
489 noise[thisChannel] = hildebrand_sekhon(daux, self.nCohInt)
489 noise[thisChannel] = hildebrand_sekhon(daux, self.nCohInt)
490
490
491 return noise
491 return noise
492
492
493 def getNoise(self, type=1, channel=None):
493 def getNoise(self, type=1, channel=None):
494
494
495 if type == 1:
495 if type == 1:
496 noise = self.getNoisebyHildebrand(channel)
496 noise = self.getNoisebyHildebrand(channel)
497
497
498 return noise
498 return noise
499
499
500 def getPower(self, channel=None):
500 def getPower(self, channel=None):
501
501
502 if channel != None:
502 if channel != None:
503 data = self.data[channel]
503 data = self.data[channel]
504 else:
504 else:
505 data = self.data
505 data = self.data
506
506
507 power = data * numpy.conjugate(data)
507 power = data * numpy.conjugate(data)
508 powerdB = 10 * numpy.log10(power.real)
508 powerdB = 10 * numpy.log10(power.real)
509 powerdB = numpy.squeeze(powerdB)
509 powerdB = numpy.squeeze(powerdB)
510
510
511 return powerdB
511 return powerdB
512
512
513 def getTimeInterval(self):
513 def getTimeInterval(self):
514
514
515 timeInterval = self.ippSeconds * self.nCohInt
515 timeInterval = self.ippSeconds * self.nCohInt
516
516
517 return timeInterval
517 return timeInterval
518
518
519 noise = property(getNoise, "I'm the 'nHeights' property.")
519 noise = property(getNoise, "I'm the 'nHeights' property.")
520 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
520 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
521 '''
521 '''
522 def getTimeInterval(self):
522 def getTimeInterval(self):
523
523
524 timeInterval = self.ippSeconds * self.nCohInt
524 timeInterval = self.ippSeconds * self.nCohInt
525
525
526 return timeInterval
526 return timeInterval
527
527
528
528
529
529
530 class Spectra(JROData):
530 class Spectra(JROData):
531
531
532 def __init__(self):
532 def __init__(self):
533 '''
533 '''
534 Constructor
534 Constructor
535 '''
535 '''
536
536
537 self.data_dc = None
537 self.data_dc = None
538 self.data_spc = None
538 self.data_spc = None
539 self.data_cspc = None
539 self.data_cspc = None
540 self.useLocalTime = True
540 self.useLocalTime = True
541 self.radarControllerHeaderObj = RadarControllerHeader()
541 self.radarControllerHeaderObj = RadarControllerHeader()
542 self.systemHeaderObj = SystemHeader()
542 self.systemHeaderObj = SystemHeader()
543 self.type = "Spectra"
543 self.type = "Spectra"
544 self.timeZone = 0
544 self.timeZone = 0
545 self.nProfiles = None
545 self.nProfiles = None
546 self.heightList = None
546 self.heightList = None
547 self.channelList = None
547 self.channelList = None
548 self.pairsList = None
548 self.pairsList = None
549 self.flagNoData = True
549 self.flagNoData = True
550 self.flagDiscontinuousBlock = False
550 self.flagDiscontinuousBlock = False
551 self.utctime = None
551 self.utctime = None
552 self.nCohInt = None
552 self.nCohInt = None
553 self.nIncohInt = None
553 self.nIncohInt = None
554 self.blocksize = None
554 self.blocksize = None
555 self.nFFTPoints = None
555 self.nFFTPoints = None
556 self.wavelength = None
556 self.wavelength = None
557 self.flagDecodeData = False # asumo q la data no esta decodificada
557 self.flagDecodeData = False # asumo q la data no esta decodificada
558 self.flagDeflipData = False # asumo q la data no esta sin flip
558 self.flagDeflipData = False # asumo q la data no esta sin flip
559 self.flagShiftFFT = False
559 self.flagShiftFFT = False
560 self.ippFactor = 1
560 self.ippFactor = 1
561 self.beacon_heiIndexList = []
561 self.beacon_heiIndexList = []
562 self.noise_estimation = None
562 self.noise_estimation = None
563 self.metadata_list = ['type', 'heightList', 'timeZone', 'pairsList', 'channelList', 'nCohInt',
563 self.metadata_list = ['type', 'heightList', 'timeZone', 'pairsList', 'channelList', 'nCohInt',
564 'code', 'nCode', 'nBaud', 'ippSeconds', 'ipp', 'nIncohInt', 'nFFTPoints', 'nProfiles']
564 'code', 'nCode', 'nBaud', 'ippSeconds', 'ipp', 'nIncohInt', 'nFFTPoints', 'nProfiles']
565
565
566 def getNoisebyHildebrand(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
566 def getNoisebyHildebrand(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
567 """
567 """
568 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
568 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
569
569
570 Return:
570 Return:
571 noiselevel
571 noiselevel
572 """
572 """
573
573
574 noise = numpy.zeros(self.nChannels)
574 noise = numpy.zeros(self.nChannels)
575
575
576 for channel in range(self.nChannels):
576 for channel in range(self.nChannels):
577 daux = self.data_spc[channel,
577 daux = self.data_spc[channel,
578 xmin_index:xmax_index, ymin_index:ymax_index]
578 xmin_index:xmax_index, ymin_index:ymax_index]
579 noise[channel] = hildebrand_sekhon(daux, self.nIncohInt)
579 noise[channel] = hildebrand_sekhon(daux, self.nIncohInt)
580
580
581 return noise
581 return noise
582
582
583 def getNoise(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
583 def getNoise(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
584
584
585 if self.noise_estimation is not None:
585 if self.noise_estimation is not None:
586 # this was estimated by getNoise Operation defined in jroproc_spectra.py
586 # this was estimated by getNoise Operation defined in jroproc_spectra.py
587 return self.noise_estimation
587 return self.noise_estimation
588 else:
588 else:
589 noise = self.getNoisebyHildebrand(
589 noise = self.getNoisebyHildebrand(
590 xmin_index, xmax_index, ymin_index, ymax_index)
590 xmin_index, xmax_index, ymin_index, ymax_index)
591 return noise
591 return noise
592
592
593 def getFreqRangeTimeResponse(self, extrapoints=0):
593 def getFreqRangeTimeResponse(self, extrapoints=0):
594
594
595 deltafreq = self.getFmaxTimeResponse() / (self.nFFTPoints * self.ippFactor)
595 deltafreq = self.getFmaxTimeResponse() / (self.nFFTPoints * self.ippFactor)
596 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.) - deltafreq / 2
596 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.) - deltafreq / 2
597
597
598 return freqrange
598 return freqrange
599
599
600 def getAcfRange(self, extrapoints=0):
600 def getAcfRange(self, extrapoints=0):
601
601
602 deltafreq = 10. / (self.getFmax() / (self.nFFTPoints * self.ippFactor))
602 deltafreq = 10. / (self.getFmax() / (self.nFFTPoints * self.ippFactor))
603 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.) - deltafreq / 2
603 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.) - deltafreq / 2
604
604
605 return freqrange
605 return freqrange
606
606
607 def getFreqRange(self, extrapoints=0):
607 def getFreqRange(self, extrapoints=0):
608
608
609 deltafreq = self.getFmax() / (self.nFFTPoints * self.ippFactor)
609 deltafreq = self.getFmax() / (self.nFFTPoints * self.ippFactor)
610 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.) - deltafreq / 2
610 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.) - deltafreq / 2
611
611
612 return freqrange
612 return freqrange
613
613
614 def getVelRange(self, extrapoints=0):
614 def getVelRange(self, extrapoints=0):
615
615
616 deltav = self.getVmax() / (self.nFFTPoints * self.ippFactor)
616 deltav = self.getVmax() / (self.nFFTPoints * self.ippFactor)
617 velrange = deltav * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.)
617 velrange = deltav * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.)
618
618
619 if self.nmodes:
619 if self.nmodes:
620 return velrange / self.nmodes
620 return velrange / self.nmodes
621 else:
621 else:
622 return velrange
622 return velrange
623
623
624 @property
624 @property
625 def nPairs(self):
625 def nPairs(self):
626
626
627 return len(self.pairsList)
627 return len(self.pairsList)
628
628
629 @property
629 @property
630 def pairsIndexList(self):
630 def pairsIndexList(self):
631
631
632 return list(range(self.nPairs))
632 return list(range(self.nPairs))
633
633
634 @property
634 @property
635 def normFactor(self):
635 def normFactor(self):
636
636
637 pwcode = 1
637 pwcode = 1
638
638
639 if self.flagDecodeData:
639 if self.flagDecodeData:
640 pwcode = numpy.sum(self.code[0] ** 2)
640 pwcode = numpy.sum(self.code[0] ** 2)
641 # normFactor = min(self.nFFTPoints,self.nProfiles)*self.nIncohInt*self.nCohInt*pwcode*self.windowOfFilter
641 # normFactor = min(self.nFFTPoints,self.nProfiles)*self.nIncohInt*self.nCohInt*pwcode*self.windowOfFilter
642 normFactor = self.nProfiles * self.nIncohInt * self.nCohInt * pwcode * self.windowOfFilter
642 normFactor = self.nProfiles * self.nIncohInt * self.nCohInt * pwcode * self.windowOfFilter
643
643
644 return normFactor
644 return normFactor
645
645
646 @property
646 @property
647 def flag_cspc(self):
647 def flag_cspc(self):
648
648
649 if self.data_cspc is None:
649 if self.data_cspc is None:
650 return True
650 return True
651
651
652 return False
652 return False
653
653
654 @property
654 @property
655 def flag_dc(self):
655 def flag_dc(self):
656
656
657 if self.data_dc is None:
657 if self.data_dc is None:
658 return True
658 return True
659
659
660 return False
660 return False
661
661
662 @property
662 @property
663 def timeInterval(self):
663 def timeInterval(self):
664
664
665 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt * self.nProfiles * self.ippFactor
665 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt * self.nProfiles * self.ippFactor
666 if self.nmodes:
666 if self.nmodes:
667 return self.nmodes * timeInterval
667 return self.nmodes * timeInterval
668 else:
668 else:
669 return timeInterval
669 return timeInterval
670
670
671 def getPower(self):
671 def getPower(self):
672
672
673 factor = self.normFactor
673 factor = self.normFactor
674 z = self.data_spc / factor
674 z = self.data_spc / factor
675 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
675 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
676 avg = numpy.average(z, axis=1)
676 avg = numpy.average(z, axis=1)
677
677
678 return 10 * numpy.log10(avg)
678 return 10 * numpy.log10(avg)
679
679
680 def getCoherence(self, pairsList=None, phase=False):
680 def getCoherence(self, pairsList=None, phase=False):
681
681
682 z = []
682 z = []
683 if pairsList is None:
683 if pairsList is None:
684 pairsIndexList = self.pairsIndexList
684 pairsIndexList = self.pairsIndexList
685 else:
685 else:
686 pairsIndexList = []
686 pairsIndexList = []
687 for pair in pairsList:
687 for pair in pairsList:
688 if pair not in self.pairsList:
688 if pair not in self.pairsList:
689 raise ValueError("Pair %s is not in dataOut.pairsList" % (
689 raise ValueError("Pair %s is not in dataOut.pairsList" % (
690 pair))
690 pair))
691 pairsIndexList.append(self.pairsList.index(pair))
691 pairsIndexList.append(self.pairsList.index(pair))
692 for i in range(len(pairsIndexList)):
692 for i in range(len(pairsIndexList)):
693 pair = self.pairsList[pairsIndexList[i]]
693 pair = self.pairsList[pairsIndexList[i]]
694 ccf = numpy.average(self.data_cspc[pairsIndexList[i], :, :], axis=0)
694 ccf = numpy.average(self.data_cspc[pairsIndexList[i], :, :], axis=0)
695 powa = numpy.average(self.data_spc[pair[0], :, :], axis=0)
695 powa = numpy.average(self.data_spc[pair[0], :, :], axis=0)
696 powb = numpy.average(self.data_spc[pair[1], :, :], axis=0)
696 powb = numpy.average(self.data_spc[pair[1], :, :], axis=0)
697 avgcoherenceComplex = ccf / numpy.sqrt(powa * powb)
697 avgcoherenceComplex = ccf / numpy.sqrt(powa * powb)
698 if phase:
698 if phase:
699 data = numpy.arctan2(avgcoherenceComplex.imag,
699 data = numpy.arctan2(avgcoherenceComplex.imag,
700 avgcoherenceComplex.real) * 180 / numpy.pi
700 avgcoherenceComplex.real) * 180 / numpy.pi
701 else:
701 else:
702 data = numpy.abs(avgcoherenceComplex)
702 data = numpy.abs(avgcoherenceComplex)
703
703
704 z.append(data)
704 z.append(data)
705
705
706 return numpy.array(z)
706 return numpy.array(z)
707
707
708 def setValue(self, value):
708 def setValue(self, value):
709
709
710 print("This property should not be initialized")
710 print("This property should not be initialized")
711
711
712 return
712 return
713
713
714 noise = property(getNoise, setValue, "I'm the 'nHeights' property.")
714 noise = property(getNoise, setValue, "I'm the 'nHeights' property.")
715
715
716
716
717 class SpectraHeis(Spectra):
717 class SpectraHeis(Spectra):
718
718
719 def __init__(self):
719 def __init__(self):
720
720
721 self.radarControllerHeaderObj = RadarControllerHeader()
721 self.radarControllerHeaderObj = RadarControllerHeader()
722 self.systemHeaderObj = SystemHeader()
722 self.systemHeaderObj = SystemHeader()
723 self.type = "SpectraHeis"
723 self.type = "SpectraHeis"
724 self.nProfiles = None
724 self.nProfiles = None
725 self.heightList = None
725 self.heightList = None
726 self.channelList = None
726 self.channelList = None
727 self.flagNoData = True
727 self.flagNoData = True
728 self.flagDiscontinuousBlock = False
728 self.flagDiscontinuousBlock = False
729 self.utctime = None
729 self.utctime = None
730 self.blocksize = None
730 self.blocksize = None
731 self.profileIndex = 0
731 self.profileIndex = 0
732 self.nCohInt = 1
732 self.nCohInt = 1
733 self.nIncohInt = 1
733 self.nIncohInt = 1
734
734
735 @property
735 @property
736 def normFactor(self):
736 def normFactor(self):
737 pwcode = 1
737 pwcode = 1
738 if self.flagDecodeData:
738 if self.flagDecodeData:
739 pwcode = numpy.sum(self.code[0] ** 2)
739 pwcode = numpy.sum(self.code[0] ** 2)
740
740
741 normFactor = self.nIncohInt * self.nCohInt * pwcode
741 normFactor = self.nIncohInt * self.nCohInt * pwcode
742
742
743 return normFactor
743 return normFactor
744
744
745 @property
745 @property
746 def timeInterval(self):
746 def timeInterval(self):
747
747
748 return self.ippSeconds * self.nCohInt * self.nIncohInt
748 return self.ippSeconds * self.nCohInt * self.nIncohInt
749
749
750
750
751 class Fits(JROData):
751 class Fits(JROData):
752
752
753 def __init__(self):
753 def __init__(self):
754
754
755 self.type = "Fits"
755 self.type = "Fits"
756 self.nProfiles = None
756 self.nProfiles = None
757 self.heightList = None
757 self.heightList = None
758 self.channelList = None
758 self.channelList = None
759 self.flagNoData = True
759 self.flagNoData = True
760 self.utctime = None
760 self.utctime = None
761 self.nCohInt = 1
761 self.nCohInt = 1
762 self.nIncohInt = 1
762 self.nIncohInt = 1
763 self.useLocalTime = True
763 self.useLocalTime = True
764 self.profileIndex = 0
764 self.profileIndex = 0
765 self.timeZone = 0
765 self.timeZone = 0
766
766
767 def getTimeRange(self):
767 def getTimeRange(self):
768
768
769 datatime = []
769 datatime = []
770
770
771 datatime.append(self.ltctime)
771 datatime.append(self.ltctime)
772 datatime.append(self.ltctime + self.timeInterval)
772 datatime.append(self.ltctime + self.timeInterval)
773
773
774 datatime = numpy.array(datatime)
774 datatime = numpy.array(datatime)
775
775
776 return datatime
776 return datatime
777
777
778 def getChannelIndexList(self):
778 def getChannelIndexList(self):
779
779
780 return list(range(self.nChannels))
780 return list(range(self.nChannels))
781
781
782 def getNoise(self, type=1):
782 def getNoise(self, type=1):
783
783
784
784
785 if type == 1:
785 if type == 1:
786 noise = self.getNoisebyHildebrand()
786 noise = self.getNoisebyHildebrand()
787
787
788 if type == 2:
788 if type == 2:
789 noise = self.getNoisebySort()
789 noise = self.getNoisebySort()
790
790
791 if type == 3:
791 if type == 3:
792 noise = self.getNoisebyWindow()
792 noise = self.getNoisebyWindow()
793
793
794 return noise
794 return noise
795
795
796 @property
796 @property
797 def timeInterval(self):
797 def timeInterval(self):
798
798
799 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
799 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
800
800
801 return timeInterval
801 return timeInterval
802
802
803 @property
803 @property
804 def ippSeconds(self):
804 def ippSeconds(self):
805 '''
805 '''
806 '''
806 '''
807 return self.ipp_sec
807 return self.ipp_sec
808
808
809 noise = property(getNoise, "I'm the 'nHeights' property.")
809 noise = property(getNoise, "I'm the 'nHeights' property.")
810
810
811
811
812 class Correlation(JROData):
812 class Correlation(JROData):
813
813
814 def __init__(self):
814 def __init__(self):
815 '''
815 '''
816 Constructor
816 Constructor
817 '''
817 '''
818 self.radarControllerHeaderObj = RadarControllerHeader()
818 self.radarControllerHeaderObj = RadarControllerHeader()
819 self.systemHeaderObj = SystemHeader()
819 self.systemHeaderObj = SystemHeader()
820 self.type = "Correlation"
820 self.type = "Correlation"
821 self.data = None
821 self.data = None
822 self.dtype = None
822 self.dtype = None
823 self.nProfiles = None
823 self.nProfiles = None
824 self.heightList = None
824 self.heightList = None
825 self.channelList = None
825 self.channelList = None
826 self.flagNoData = True
826 self.flagNoData = True
827 self.flagDiscontinuousBlock = False
827 self.flagDiscontinuousBlock = False
828 self.utctime = None
828 self.utctime = None
829 self.timeZone = 0
829 self.timeZone = 0
830 self.dstFlag = None
830 self.dstFlag = None
831 self.errorCount = None
831 self.errorCount = None
832 self.blocksize = None
832 self.blocksize = None
833 self.flagDecodeData = False # asumo q la data no esta decodificada
833 self.flagDecodeData = False # asumo q la data no esta decodificada
834 self.flagDeflipData = False # asumo q la data no esta sin flip
834 self.flagDeflipData = False # asumo q la data no esta sin flip
835 self.pairsList = None
835 self.pairsList = None
836 self.nPoints = None
836 self.nPoints = None
837
837
838 def getPairsList(self):
838 def getPairsList(self):
839
839
840 return self.pairsList
840 return self.pairsList
841
841
842 def getNoise(self, mode=2):
842 def getNoise(self, mode=2):
843
843
844 indR = numpy.where(self.lagR == 0)[0][0]
844 indR = numpy.where(self.lagR == 0)[0][0]
845 indT = numpy.where(self.lagT == 0)[0][0]
845 indT = numpy.where(self.lagT == 0)[0][0]
846
846
847 jspectra0 = self.data_corr[:, :, indR, :]
847 jspectra0 = self.data_corr[:, :, indR, :]
848 jspectra = copy.copy(jspectra0)
848 jspectra = copy.copy(jspectra0)
849
849
850 num_chan = jspectra.shape[0]
850 num_chan = jspectra.shape[0]
851 num_hei = jspectra.shape[2]
851 num_hei = jspectra.shape[2]
852
852
853 freq_dc = jspectra.shape[1] / 2
853 freq_dc = jspectra.shape[1] / 2
854 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
854 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
855
855
856 if ind_vel[0] < 0:
856 if ind_vel[0] < 0:
857 ind_vel[list(range(0, 1))] = ind_vel[list(
857 ind_vel[list(range(0, 1))] = ind_vel[list(
858 range(0, 1))] + self.num_prof
858 range(0, 1))] + self.num_prof
859
859
860 if mode == 1:
860 if mode == 1:
861 jspectra[:, freq_dc, :] = (
861 jspectra[:, freq_dc, :] = (
862 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
862 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
863
863
864 if mode == 2:
864 if mode == 2:
865
865
866 vel = numpy.array([-2, -1, 1, 2])
866 vel = numpy.array([-2, -1, 1, 2])
867 xx = numpy.zeros([4, 4])
867 xx = numpy.zeros([4, 4])
868
868
869 for fil in range(4):
869 for fil in range(4):
870 xx[fil, :] = vel[fil] ** numpy.asarray(list(range(4)))
870 xx[fil, :] = vel[fil] ** numpy.asarray(list(range(4)))
871
871
872 xx_inv = numpy.linalg.inv(xx)
872 xx_inv = numpy.linalg.inv(xx)
873 xx_aux = xx_inv[0, :]
873 xx_aux = xx_inv[0, :]
874
874
875 for ich in range(num_chan):
875 for ich in range(num_chan):
876 yy = jspectra[ich, ind_vel, :]
876 yy = jspectra[ich, ind_vel, :]
877 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
877 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
878
878
879 junkid = jspectra[ich, freq_dc, :] <= 0
879 junkid = jspectra[ich, freq_dc, :] <= 0
880 cjunkid = sum(junkid)
880 cjunkid = sum(junkid)
881
881
882 if cjunkid.any():
882 if cjunkid.any():
883 jspectra[ich, freq_dc, junkid.nonzero()] = (
883 jspectra[ich, freq_dc, junkid.nonzero()] = (
884 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
884 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
885
885
886 noise = jspectra0[:, freq_dc, :] - jspectra[:, freq_dc, :]
886 noise = jspectra0[:, freq_dc, :] - jspectra[:, freq_dc, :]
887
887
888 return noise
888 return noise
889
889
890 @property
890 @property
891 def timeInterval(self):
891 def timeInterval(self):
892
892
893 return self.ippSeconds * self.nCohInt * self.nProfiles
893 return self.ippSeconds * self.nCohInt * self.nProfiles
894
894
895 def splitFunctions(self):
895 def splitFunctions(self):
896
896
897 pairsList = self.pairsList
897 pairsList = self.pairsList
898 ccf_pairs = []
898 ccf_pairs = []
899 acf_pairs = []
899 acf_pairs = []
900 ccf_ind = []
900 ccf_ind = []
901 acf_ind = []
901 acf_ind = []
902 for l in range(len(pairsList)):
902 for l in range(len(pairsList)):
903 chan0 = pairsList[l][0]
903 chan0 = pairsList[l][0]
904 chan1 = pairsList[l][1]
904 chan1 = pairsList[l][1]
905
905
906 # Obteniendo pares de Autocorrelacion
906 # Obteniendo pares de Autocorrelacion
907 if chan0 == chan1:
907 if chan0 == chan1:
908 acf_pairs.append(chan0)
908 acf_pairs.append(chan0)
909 acf_ind.append(l)
909 acf_ind.append(l)
910 else:
910 else:
911 ccf_pairs.append(pairsList[l])
911 ccf_pairs.append(pairsList[l])
912 ccf_ind.append(l)
912 ccf_ind.append(l)
913
913
914 data_acf = self.data_cf[acf_ind]
914 data_acf = self.data_cf[acf_ind]
915 data_ccf = self.data_cf[ccf_ind]
915 data_ccf = self.data_cf[ccf_ind]
916
916
917 return acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf
917 return acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf
918
918
919 @property
919 @property
920 def normFactor(self):
920 def normFactor(self):
921 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.splitFunctions()
921 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.splitFunctions()
922 acf_pairs = numpy.array(acf_pairs)
922 acf_pairs = numpy.array(acf_pairs)
923 normFactor = numpy.zeros((self.nPairs, self.nHeights))
923 normFactor = numpy.zeros((self.nPairs, self.nHeights))
924
924
925 for p in range(self.nPairs):
925 for p in range(self.nPairs):
926 pair = self.pairsList[p]
926 pair = self.pairsList[p]
927
927
928 ch0 = pair[0]
928 ch0 = pair[0]
929 ch1 = pair[1]
929 ch1 = pair[1]
930
930
931 ch0_max = numpy.max(data_acf[acf_pairs == ch0, :, :], axis=1)
931 ch0_max = numpy.max(data_acf[acf_pairs == ch0, :, :], axis=1)
932 ch1_max = numpy.max(data_acf[acf_pairs == ch1, :, :], axis=1)
932 ch1_max = numpy.max(data_acf[acf_pairs == ch1, :, :], axis=1)
933 normFactor[p, :] = numpy.sqrt(ch0_max * ch1_max)
933 normFactor[p, :] = numpy.sqrt(ch0_max * ch1_max)
934
934
935 return normFactor
935 return normFactor
936
936
937
937
938 class Parameters(Spectra):
938 class Parameters(Spectra):
939
939
940 groupList = None # List of Pairs, Groups, etc
940 groupList = None # List of Pairs, Groups, etc
941 data_param = None # Parameters obtained
941 data_param = None # Parameters obtained
942 data_pre = None # Data Pre Parametrization
942 data_pre = None # Data Pre Parametrization
943 data_SNR = None # Signal to Noise Ratio
943 data_SNR = None # Signal to Noise Ratio
944 abscissaList = None # Abscissa, can be velocities, lags or time
944 abscissaList = None # Abscissa, can be velocities, lags or time
945 utctimeInit = None # Initial UTC time
945 utctimeInit = None # Initial UTC time
946 paramInterval = None # Time interval to calculate Parameters in seconds
946 paramInterval = None # Time interval to calculate Parameters in seconds
947 useLocalTime = True
947 useLocalTime = True
948 # Fitting
948 # Fitting
949 data_error = None # Error of the estimation
949 data_error = None # Error of the estimation
950 constants = None
950 constants = None
951 library = None
951 library = None
952 # Output signal
952 # Output signal
953 outputInterval = None # Time interval to calculate output signal in seconds
953 outputInterval = None # Time interval to calculate output signal in seconds
954 data_output = None # Out signal
954 data_output = None # Out signal
955 nAvg = None
955 nAvg = None
956 noise_estimation = None
956 noise_estimation = None
957 GauSPC = None # Fit gaussian SPC
957 GauSPC = None # Fit gaussian SPC
958
958
959 def __init__(self):
959 def __init__(self):
960 '''
960 '''
961 Constructor
961 Constructor
962 '''
962 '''
963 self.radarControllerHeaderObj = RadarControllerHeader()
963 self.radarControllerHeaderObj = RadarControllerHeader()
964 self.systemHeaderObj = SystemHeader()
964 self.systemHeaderObj = SystemHeader()
965 self.type = "Parameters"
965 self.type = "Parameters"
966 self.timeZone = 0
966 self.timeZone = 0
967 self.ippFactor = 1
967
968
968 def getTimeRange1(self, interval):
969 def getTimeRange1(self, interval):
969
970
970 datatime = []
971 datatime = []
971
972
972 if self.useLocalTime:
973 if self.useLocalTime:
973 time1 = self.utctimeInit - self.timeZone * 60
974 time1 = self.utctimeInit - self.timeZone * 60
974 else:
975 else:
975 time1 = self.utctimeInit
976 time1 = self.utctimeInit
976
977
977 datatime.append(time1)
978 datatime.append(time1)
978 datatime.append(time1 + interval)
979 datatime.append(time1 + interval)
979 datatime = numpy.array(datatime)
980 datatime = numpy.array(datatime)
980
981
981 return datatime
982 return datatime
982
983
983 @property
984 @property
984 def timeInterval(self):
985 def timeInterval(self):
985
986
986 if hasattr(self, 'timeInterval1'):
987 if hasattr(self, 'timeInterval1'):
987 return self.timeInterval1
988 return self.timeInterval1
988 else:
989 else:
989 return self.paramInterval
990 return self.paramInterval
990
991
991
992
992 def setValue(self, value):
993 def setValue(self, value):
993
994
994 print("This property should not be initialized")
995 print("This property should not be initialized")
995
996
996 return
997 return
997
998
998 def getNoise(self):
999 def getNoise(self):
999
1000
1000 return self.spc_noise
1001 return self.spc_noise
1001
1002
1002 noise = property(getNoise, setValue, "I'm the 'Noise' property.")
1003 noise = property(getNoise, setValue, "I'm the 'Noise' property.")
1003
1004
1004
1005
1005 class PlotterData(object):
1006 class PlotterData(object):
1006 '''
1007 '''
1007 Object to hold data to be plotted
1008 Object to hold data to be plotted
1008 '''
1009 '''
1009
1010
1010 MAXNUMX = 200
1011 MAXNUMX = 200
1011 MAXNUMY = 200
1012 MAXNUMY = 200
1012
1013
1013 def __init__(self, code, exp_code, localtime=True):
1014 def __init__(self, code, exp_code, localtime=True):
1014
1015
1015 self.key = code
1016 self.key = code
1016 self.exp_code = exp_code
1017 self.exp_code = exp_code
1017 self.ready = False
1018 self.ready = False
1018 self.flagNoData = False
1019 self.flagNoData = False
1019 self.localtime = localtime
1020 self.localtime = localtime
1020 self.data = {}
1021 self.data = {}
1021 self.meta = {}
1022 self.meta = {}
1022 self.__heights = []
1023 self.__heights = []
1023
1024
1024 def __str__(self):
1025 def __str__(self):
1025 dum = ['{}{}'.format(key, self.shape(key)) for key in self.data]
1026 dum = ['{}{}'.format(key, self.shape(key)) for key in self.data]
1026 return 'Data[{}][{}]'.format(';'.join(dum), len(self.times))
1027 return 'Data[{}][{}]'.format(';'.join(dum), len(self.times))
1027
1028
1028 def __len__(self):
1029 def __len__(self):
1029 return len(self.data)
1030 return len(self.data)
1030
1031
1031 def __getitem__(self, key):
1032 def __getitem__(self, key):
1032 if isinstance(key, int):
1033 if isinstance(key, int):
1033 return self.data[self.times[key]]
1034 return self.data[self.times[key]]
1034 elif isinstance(key, str):
1035 elif isinstance(key, str):
1035 ret = numpy.array([self.data[x][key] for x in self.times])
1036 ret = numpy.array([self.data[x][key] for x in self.times])
1036 if ret.ndim > 1:
1037 if ret.ndim > 1:
1037 ret = numpy.swapaxes(ret, 0, 1)
1038 ret = numpy.swapaxes(ret, 0, 1)
1038 return ret
1039 return ret
1039
1040
1040 def __contains__(self, key):
1041 def __contains__(self, key):
1041 return key in self.data[self.min_time]
1042 return key in self.data[self.min_time]
1042
1043
1043 def setup(self):
1044 def setup(self):
1044 '''
1045 '''
1045 Configure object
1046 Configure object
1046 '''
1047 '''
1047 self.type = ''
1048 self.type = ''
1048 self.ready = False
1049 self.ready = False
1049 del self.data
1050 del self.data
1050 self.data = {}
1051 self.data = {}
1051 self.__heights = []
1052 self.__heights = []
1052 self.__all_heights = set()
1053 self.__all_heights = set()
1053
1054
1054 def shape(self, key):
1055 def shape(self, key):
1055 '''
1056 '''
1056 Get the shape of the one-element data for the given key
1057 Get the shape of the one-element data for the given key
1057 '''
1058 '''
1058
1059
1059 if len(self.data[self.min_time][key]):
1060 if len(self.data[self.min_time][key]):
1060 return self.data[self.min_time][key].shape
1061 return self.data[self.min_time][key].shape
1061 return (0,)
1062 return (0,)
1062
1063
1063 def update(self, data, tm, meta={}):
1064 def update(self, data, tm, meta={}):
1064 '''
1065 '''
1065 Update data object with new dataOut
1066 Update data object with new dataOut
1066 '''
1067 '''
1067
1068
1068 self.data[tm] = data
1069 self.data[tm] = data
1069
1070
1070 for key, value in meta.items():
1071 for key, value in meta.items():
1071 setattr(self, key, value)
1072 setattr(self, key, value)
1072
1073
1073 def normalize_heights(self):
1074 def normalize_heights(self):
1074 '''
1075 '''
1075 Ensure same-dimension of the data for different heighList
1076 Ensure same-dimension of the data for different heighList
1076 '''
1077 '''
1077
1078
1078 H = numpy.array(list(self.__all_heights))
1079 H = numpy.array(list(self.__all_heights))
1079 H.sort()
1080 H.sort()
1080 for key in self.data:
1081 for key in self.data:
1081 shape = self.shape(key)[:-1] + H.shape
1082 shape = self.shape(key)[:-1] + H.shape
1082 for tm, obj in list(self.data[key].items()):
1083 for tm, obj in list(self.data[key].items()):
1083 h = self.__heights[self.times.tolist().index(tm)]
1084 h = self.__heights[self.times.tolist().index(tm)]
1084 if H.size == h.size:
1085 if H.size == h.size:
1085 continue
1086 continue
1086 index = numpy.where(numpy.in1d(H, h))[0]
1087 index = numpy.where(numpy.in1d(H, h))[0]
1087 dummy = numpy.zeros(shape) + numpy.nan
1088 dummy = numpy.zeros(shape) + numpy.nan
1088 if len(shape) == 2:
1089 if len(shape) == 2:
1089 dummy[:, index] = obj
1090 dummy[:, index] = obj
1090 else:
1091 else:
1091 dummy[index] = obj
1092 dummy[index] = obj
1092 self.data[key][tm] = dummy
1093 self.data[key][tm] = dummy
1093
1094
1094 self.__heights = [H for tm in self.times]
1095 self.__heights = [H for tm in self.times]
1095
1096
1096 def jsonify(self, tm, plot_name, plot_type, decimate=False):
1097 def jsonify(self, tm, plot_name, plot_type, decimate=False):
1097 '''
1098 '''
1098 Convert data to json
1099 Convert data to json
1099 '''
1100 '''
1100
1101
1101 meta = {}
1102 meta = {}
1102 meta['xrange'] = []
1103 meta['xrange'] = []
1103 dy = int(len(self.yrange) / self.MAXNUMY) + 1
1104 dy = int(len(self.yrange) / self.MAXNUMY) + 1
1104 tmp = self.data[tm][self.key]
1105 tmp = self.data[tm][self.key]
1105 shape = tmp.shape
1106 shape = tmp.shape
1106 if len(shape) == 2:
1107 if len(shape) == 2:
1107 data = self.roundFloats(self.data[tm][self.key][::, ::dy].tolist())
1108 data = self.roundFloats(self.data[tm][self.key][::, ::dy].tolist())
1108 elif len(shape) == 3:
1109 elif len(shape) == 3:
1109 dx = int(self.data[tm][self.key].shape[1] / self.MAXNUMX) + 1
1110 dx = int(self.data[tm][self.key].shape[1] / self.MAXNUMX) + 1
1110 data = self.roundFloats(
1111 data = self.roundFloats(
1111 self.data[tm][self.key][::, ::dx, ::dy].tolist())
1112 self.data[tm][self.key][::, ::dx, ::dy].tolist())
1112 meta['xrange'] = self.roundFloats(self.xrange[2][::dx].tolist())
1113 meta['xrange'] = self.roundFloats(self.xrange[2][::dx].tolist())
1113 else:
1114 else:
1114 data = self.roundFloats(self.data[tm][self.key].tolist())
1115 data = self.roundFloats(self.data[tm][self.key].tolist())
1115
1116
1116 ret = {
1117 ret = {
1117 'plot': plot_name,
1118 'plot': plot_name,
1118 'code': self.exp_code,
1119 'code': self.exp_code,
1119 'time': float(tm),
1120 'time': float(tm),
1120 'data': data,
1121 'data': data,
1121 }
1122 }
1122 meta['type'] = plot_type
1123 meta['type'] = plot_type
1123 meta['interval'] = float(self.interval)
1124 meta['interval'] = float(self.interval)
1124 meta['localtime'] = self.localtime
1125 meta['localtime'] = self.localtime
1125 meta['yrange'] = self.roundFloats(self.yrange[::dy].tolist())
1126 meta['yrange'] = self.roundFloats(self.yrange[::dy].tolist())
1126 meta.update(self.meta)
1127 meta.update(self.meta)
1127 ret['metadata'] = meta
1128 ret['metadata'] = meta
1128 return json.dumps(ret)
1129 return json.dumps(ret)
1129
1130
1130 @property
1131 @property
1131 def times(self):
1132 def times(self):
1132 '''
1133 '''
1133 Return the list of times of the current data
1134 Return the list of times of the current data
1134 '''
1135 '''
1135
1136
1136 ret = [t for t in self.data]
1137 ret = [t for t in self.data]
1137 ret.sort()
1138 ret.sort()
1138 return numpy.array(ret)
1139 return numpy.array(ret)
1139
1140
1140 @property
1141 @property
1141 def min_time(self):
1142 def min_time(self):
1142 '''
1143 '''
1143 Return the minimun time value
1144 Return the minimun time value
1144 '''
1145 '''
1145
1146
1146 return self.times[0]
1147 return self.times[0]
1147
1148
1148 @property
1149 @property
1149 def max_time(self):
1150 def max_time(self):
1150 '''
1151 '''
1151 Return the maximun time value
1152 Return the maximun time value
1152 '''
1153 '''
1153
1154
1154 return self.times[-1]
1155 return self.times[-1]
1155
1156
1156 # @property
1157 # @property
1157 # def heights(self):
1158 # def heights(self):
1158 # '''
1159 # '''
1159 # Return the list of heights of the current data
1160 # Return the list of heights of the current data
1160 # '''
1161 # '''
1161
1162
1162 # return numpy.array(self.__heights[-1])
1163 # return numpy.array(self.__heights[-1])
1163
1164
1164 @staticmethod
1165 @staticmethod
1165 def roundFloats(obj):
1166 def roundFloats(obj):
1166 if isinstance(obj, list):
1167 if isinstance(obj, list):
1167 return list(map(PlotterData.roundFloats, obj))
1168 return list(map(PlotterData.roundFloats, obj))
1168 elif isinstance(obj, float):
1169 elif isinstance(obj, float):
1169 return round(obj, 2)
1170 return round(obj, 2)
@@ -1,909 +1,908
1 '''
1 '''
2
2
3 $Author: murco $
3 $Author: murco $
4 $Id: JROHeaderIO.py 151 2012-10-31 19:00:51Z murco $
4 $Id: JROHeaderIO.py 151 2012-10-31 19:00:51Z murco $
5 '''
5 '''
6 import sys
6 import sys
7 import numpy
7 import numpy
8 import copy
8 import copy
9 import datetime
9 import datetime
10 import inspect
10 import inspect
11 from schainpy.utils import log
11 from schainpy.utils import log
12
12
13 SPEED_OF_LIGHT = 299792458
13 SPEED_OF_LIGHT = 299792458
14 SPEED_OF_LIGHT = 3e8
14 SPEED_OF_LIGHT = 3e8
15
15
16 BASIC_STRUCTURE = numpy.dtype([
16 BASIC_STRUCTURE = numpy.dtype([
17 ('nSize', '<u4'),
17 ('nSize', '<u4'),
18 ('nVersion', '<u2'),
18 ('nVersion', '<u2'),
19 ('nDataBlockId', '<u4'),
19 ('nDataBlockId', '<u4'),
20 ('nUtime', '<u4'),
20 ('nUtime', '<u4'),
21 ('nMilsec', '<u2'),
21 ('nMilsec', '<u2'),
22 ('nTimezone', '<i2'),
22 ('nTimezone', '<i2'),
23 ('nDstflag', '<i2'),
23 ('nDstflag', '<i2'),
24 ('nErrorCount', '<u4')
24 ('nErrorCount', '<u4')
25 ])
25 ])
26
26
27 SYSTEM_STRUCTURE = numpy.dtype([
27 SYSTEM_STRUCTURE = numpy.dtype([
28 ('nSize', '<u4'),
28 ('nSize', '<u4'),
29 ('nNumSamples', '<u4'),
29 ('nNumSamples', '<u4'),
30 ('nNumProfiles', '<u4'),
30 ('nNumProfiles', '<u4'),
31 ('nNumChannels', '<u4'),
31 ('nNumChannels', '<u4'),
32 ('nADCResolution', '<u4'),
32 ('nADCResolution', '<u4'),
33 ('nPCDIOBusWidth', '<u4'),
33 ('nPCDIOBusWidth', '<u4'),
34 ])
34 ])
35
35
36 RADAR_STRUCTURE = numpy.dtype([
36 RADAR_STRUCTURE = numpy.dtype([
37 ('nSize', '<u4'),
37 ('nSize', '<u4'),
38 ('nExpType', '<u4'),
38 ('nExpType', '<u4'),
39 ('nNTx', '<u4'),
39 ('nNTx', '<u4'),
40 ('fIpp', '<f4'),
40 ('fIpp', '<f4'),
41 ('fTxA', '<f4'),
41 ('fTxA', '<f4'),
42 ('fTxB', '<f4'),
42 ('fTxB', '<f4'),
43 ('nNumWindows', '<u4'),
43 ('nNumWindows', '<u4'),
44 ('nNumTaus', '<u4'),
44 ('nNumTaus', '<u4'),
45 ('nCodeType', '<u4'),
45 ('nCodeType', '<u4'),
46 ('nLine6Function', '<u4'),
46 ('nLine6Function', '<u4'),
47 ('nLine5Function', '<u4'),
47 ('nLine5Function', '<u4'),
48 ('fClock', '<f4'),
48 ('fClock', '<f4'),
49 ('nPrePulseBefore', '<u4'),
49 ('nPrePulseBefore', '<u4'),
50 ('nPrePulseAfter', '<u4'),
50 ('nPrePulseAfter', '<u4'),
51 ('sRangeIPP', '<a20'),
51 ('sRangeIPP', '<a20'),
52 ('sRangeTxA', '<a20'),
52 ('sRangeTxA', '<a20'),
53 ('sRangeTxB', '<a20'),
53 ('sRangeTxB', '<a20'),
54 ])
54 ])
55
55
56 SAMPLING_STRUCTURE = numpy.dtype(
56 SAMPLING_STRUCTURE = numpy.dtype(
57 [('h0', '<f4'), ('dh', '<f4'), ('nsa', '<u4')])
57 [('h0', '<f4'), ('dh', '<f4'), ('nsa', '<u4')])
58
58
59
59
60 PROCESSING_STRUCTURE = numpy.dtype([
60 PROCESSING_STRUCTURE = numpy.dtype([
61 ('nSize', '<u4'),
61 ('nSize', '<u4'),
62 ('nDataType', '<u4'),
62 ('nDataType', '<u4'),
63 ('nSizeOfDataBlock', '<u4'),
63 ('nSizeOfDataBlock', '<u4'),
64 ('nProfilesperBlock', '<u4'),
64 ('nProfilesperBlock', '<u4'),
65 ('nDataBlocksperFile', '<u4'),
65 ('nDataBlocksperFile', '<u4'),
66 ('nNumWindows', '<u4'),
66 ('nNumWindows', '<u4'),
67 ('nProcessFlags', '<u4'),
67 ('nProcessFlags', '<u4'),
68 ('nCoherentIntegrations', '<u4'),
68 ('nCoherentIntegrations', '<u4'),
69 ('nIncoherentIntegrations', '<u4'),
69 ('nIncoherentIntegrations', '<u4'),
70 ('nTotalSpectra', '<u4')
70 ('nTotalSpectra', '<u4')
71 ])
71 ])
72
72
73
73
74 class Header(object):
74 class Header(object):
75
75
76 def __init__(self):
76 def __init__(self):
77 raise NotImplementedError
77 raise NotImplementedError
78
78
79 def copy(self):
79 def copy(self):
80 return copy.deepcopy(self)
80 return copy.deepcopy(self)
81
81
82 def read(self):
82 def read(self):
83
83
84 raise NotImplementedError
84 raise NotImplementedError
85
85
86 def write(self):
86 def write(self):
87
87
88 raise NotImplementedError
88 raise NotImplementedError
89
89
90 def getAllowedArgs(self):
90 def getAllowedArgs(self):
91 args = inspect.getargspec(self.__init__).args
91 args = inspect.getargspec(self.__init__).args
92 try:
92 try:
93 args.remove('self')
93 args.remove('self')
94 except:
94 except:
95 pass
95 pass
96 return args
96 return args
97
97
98 def getAsDict(self):
98 def getAsDict(self):
99 args = self.getAllowedArgs()
99 args = self.getAllowedArgs()
100 asDict = {}
100 asDict = {}
101 for x in args:
101 for x in args:
102 asDict[x] = self[x]
102 asDict[x] = self[x]
103 return asDict
103 return asDict
104
104
105 def __getitem__(self, name):
105 def __getitem__(self, name):
106 return getattr(self, name)
106 return getattr(self, name)
107
107
108 def printInfo(self):
108 def printInfo(self):
109
109
110 message = "#" * 50 + "\n"
110 message = "#" * 50 + "\n"
111 message += self.__class__.__name__.upper() + "\n"
111 message += self.__class__.__name__.upper() + "\n"
112 message += "#" * 50 + "\n"
112 message += "#" * 50 + "\n"
113
113
114 keyList = list(self.__dict__.keys())
114 keyList = list(self.__dict__.keys())
115 keyList.sort()
115 keyList.sort()
116
116
117 for key in keyList:
117 for key in keyList:
118 message += "%s = %s" % (key, self.__dict__[key]) + "\n"
118 message += "%s = %s" % (key, self.__dict__[key]) + "\n"
119
119
120 if "size" not in keyList:
120 if "size" not in keyList:
121 attr = getattr(self, "size")
121 attr = getattr(self, "size")
122
122
123 if attr:
123 if attr:
124 message += "%s = %s" % ("size", attr) + "\n"
124 message += "%s = %s" % ("size", attr) + "\n"
125
125
126 print(message)
126 print(message)
127
127
128
128
129 class BasicHeader(Header):
129 class BasicHeader(Header):
130
130
131 size = None
131 size = None
132 version = None
132 version = None
133 dataBlock = None
133 dataBlock = None
134 utc = None
134 utc = None
135 ltc = None
135 ltc = None
136 miliSecond = None
136 miliSecond = None
137 timeZone = None
137 timeZone = None
138 dstFlag = None
138 dstFlag = None
139 errorCount = None
139 errorCount = None
140 F = None
140 F = None
141 structure = BASIC_STRUCTURE
141 structure = BASIC_STRUCTURE
142 __LOCALTIME = None
142 __LOCALTIME = None
143
143
144 def __init__(self, useLocalTime=True):
144 def __init__(self, useLocalTime=True):
145
145
146 self.size = 24
146 self.size = 24
147 self.version = 0
147 self.version = 0
148 self.dataBlock = 0
148 self.dataBlock = 0
149 self.utc = 0
149 self.utc = 0
150 self.miliSecond = 0
150 self.miliSecond = 0
151 self.timeZone = 0
151 self.timeZone = 0
152 self.dstFlag = 0
152 self.dstFlag = 0
153 self.errorCount = 0
153 self.errorCount = 0
154
155 self.useLocalTime = useLocalTime
154 self.useLocalTime = useLocalTime
156
155
157 def read(self, fp):
156 def read(self, fp):
158
157
159 self.length = 0
158 self.length = 0
160 try:
159 try:
161 if hasattr(fp, 'read'):
160 if hasattr(fp, 'read'):
162 header = numpy.fromfile(fp, BASIC_STRUCTURE, 1)
161 header = numpy.fromfile(fp, BASIC_STRUCTURE, 1)
163 else:
162 else:
164 header = numpy.fromstring(fp, BASIC_STRUCTURE, 1)
163 header = numpy.fromstring(fp, BASIC_STRUCTURE, 1)
165 except Exception as e:
164 except Exception as e:
166 print("BasicHeader: ")
165 print("BasicHeader: ")
167 print(e)
166 print(e)
168 return 0
167 return 0
169
168
170 self.size = int(header['nSize'][0])
169 self.size = int(header['nSize'][0])
171 self.version = int(header['nVersion'][0])
170 self.version = int(header['nVersion'][0])
172 self.dataBlock = int(header['nDataBlockId'][0])
171 self.dataBlock = int(header['nDataBlockId'][0])
173 self.utc = int(header['nUtime'][0])
172 self.utc = int(header['nUtime'][0])
174 self.miliSecond = int(header['nMilsec'][0])
173 self.miliSecond = int(header['nMilsec'][0])
175 self.timeZone = int(header['nTimezone'][0])
174 self.timeZone = int(header['nTimezone'][0])
176 self.dstFlag = int(header['nDstflag'][0])
175 self.dstFlag = int(header['nDstflag'][0])
177 self.errorCount = int(header['nErrorCount'][0])
176 self.errorCount = int(header['nErrorCount'][0])
178
177
179 if self.size < 24:
178 if self.size < 24:
180 return 0
179 return 0
181
180
182 self.length = header.nbytes
181 self.length = header.nbytes
183 return 1
182 return 1
184
183
185 def write(self, fp):
184 def write(self, fp):
186
185
187 headerTuple = (self.size, self.version, self.dataBlock, self.utc,
186 headerTuple = (self.size, self.version, self.dataBlock, self.utc,
188 self.miliSecond, self.timeZone, self.dstFlag, self.errorCount)
187 self.miliSecond, self.timeZone, self.dstFlag, self.errorCount)
189 header = numpy.array(headerTuple, BASIC_STRUCTURE)
188 header = numpy.array(headerTuple, BASIC_STRUCTURE)
190 header.tofile(fp)
189 header.tofile(fp)
191
190
192 return 1
191 return 1
193
192
194 def get_ltc(self):
193 def get_ltc(self):
195
194
196 return self.utc - self.timeZone * 60
195 return self.utc - self.timeZone * 60
197
196
198 def set_ltc(self, value):
197 def set_ltc(self, value):
199
198
200 self.utc = value + self.timeZone * 60
199 self.utc = value + self.timeZone * 60
201
200
202 def get_datatime(self):
201 def get_datatime(self):
203
202
204 return datetime.datetime.utcfromtimestamp(self.ltc)
203 return datetime.datetime.utcfromtimestamp(self.ltc)
205
204
206 ltc = property(get_ltc, set_ltc)
205 ltc = property(get_ltc, set_ltc)
207 datatime = property(get_datatime)
206 datatime = property(get_datatime)
208
207
209
208
210 class SystemHeader(Header):
209 class SystemHeader(Header):
211
210
212 size = None
211 size = None
213 nSamples = None
212 nSamples = None
214 nProfiles = None
213 nProfiles = None
215 nChannels = None
214 nChannels = None
216 adcResolution = None
215 adcResolution = None
217 pciDioBusWidth = None
216 pciDioBusWidth = None
218 structure = SYSTEM_STRUCTURE
217 structure = SYSTEM_STRUCTURE
219
218
220 def __init__(self, nSamples=0, nProfiles=0, nChannels=0, adcResolution=14, pciDioBusWidth=0):
219 def __init__(self, nSamples=0, nProfiles=0, nChannels=0, adcResolution=14, pciDioBusWidth=0):
221
220
222 self.size = 24
221 self.size = 24
223 self.nSamples = nSamples
222 self.nSamples = nSamples
224 self.nProfiles = nProfiles
223 self.nProfiles = nProfiles
225 self.nChannels = nChannels
224 self.nChannels = nChannels
226 self.adcResolution = adcResolution
225 self.adcResolution = adcResolution
227 self.pciDioBusWidth = pciDioBusWidth
226 self.pciDioBusWidth = pciDioBusWidth
228
227
229 def read(self, fp):
228 def read(self, fp):
230 self.length = 0
229 self.length = 0
231 try:
230 try:
232 startFp = fp.tell()
231 startFp = fp.tell()
233 except Exception as e:
232 except Exception as e:
234 startFp = None
233 startFp = None
235 pass
234 pass
236
235
237 try:
236 try:
238 if hasattr(fp, 'read'):
237 if hasattr(fp, 'read'):
239 header = numpy.fromfile(fp, SYSTEM_STRUCTURE, 1)
238 header = numpy.fromfile(fp, SYSTEM_STRUCTURE, 1)
240 else:
239 else:
241 header = numpy.fromstring(fp, SYSTEM_STRUCTURE, 1)
240 header = numpy.fromstring(fp, SYSTEM_STRUCTURE, 1)
242 except Exception as e:
241 except Exception as e:
243 print("System Header: " + str(e))
242 print("System Header: " + str(e))
244 return 0
243 return 0
245
244
246 self.size = header['nSize'][0]
245 self.size = header['nSize'][0]
247 self.nSamples = header['nNumSamples'][0]
246 self.nSamples = header['nNumSamples'][0]
248 self.nProfiles = header['nNumProfiles'][0]
247 self.nProfiles = header['nNumProfiles'][0]
249 self.nChannels = header['nNumChannels'][0]
248 self.nChannels = header['nNumChannels'][0]
250 self.adcResolution = header['nADCResolution'][0]
249 self.adcResolution = header['nADCResolution'][0]
251 self.pciDioBusWidth = header['nPCDIOBusWidth'][0]
250 self.pciDioBusWidth = header['nPCDIOBusWidth'][0]
252
251
253 if startFp is not None:
252 if startFp is not None:
254 endFp = self.size + startFp
253 endFp = self.size + startFp
255
254
256 if fp.tell() > endFp:
255 if fp.tell() > endFp:
257 sys.stderr.write(
256 sys.stderr.write(
258 "Warning %s: Size value read from System Header is lower than it has to be\n" % fp.name)
257 "Warning %s: Size value read from System Header is lower than it has to be\n" % fp.name)
259 return 0
258 return 0
260
259
261 if fp.tell() < endFp:
260 if fp.tell() < endFp:
262 sys.stderr.write(
261 sys.stderr.write(
263 "Warning %s: Size value read from System Header size is greater than it has to be\n" % fp.name)
262 "Warning %s: Size value read from System Header size is greater than it has to be\n" % fp.name)
264 return 0
263 return 0
265
264
266 self.length = header.nbytes
265 self.length = header.nbytes
267 return 1
266 return 1
268
267
269 def write(self, fp):
268 def write(self, fp):
270
269
271 headerTuple = (self.size, self.nSamples, self.nProfiles,
270 headerTuple = (self.size, self.nSamples, self.nProfiles,
272 self.nChannels, self.adcResolution, self.pciDioBusWidth)
271 self.nChannels, self.adcResolution, self.pciDioBusWidth)
273 header = numpy.array(headerTuple, SYSTEM_STRUCTURE)
272 header = numpy.array(headerTuple, SYSTEM_STRUCTURE)
274 header.tofile(fp)
273 header.tofile(fp)
275
274
276 return 1
275 return 1
277
276
278
277
279 class RadarControllerHeader(Header):
278 class RadarControllerHeader(Header):
280
279
281 expType = None
280 expType = None
282 nTx = None
281 nTx = None
283 ipp = None
282 ipp = None
284 txA = None
283 txA = None
285 txB = None
284 txB = None
286 nWindows = None
285 nWindows = None
287 numTaus = None
286 numTaus = None
288 codeType = None
287 codeType = None
289 line6Function = None
288 line6Function = None
290 line5Function = None
289 line5Function = None
291 fClock = None
290 fClock = None
292 prePulseBefore = None
291 prePulseBefore = None
293 prePulseAfter = None
292 prePulseAfter = None
294 rangeIpp = None
293 rangeIpp = None
295 rangeTxA = None
294 rangeTxA = None
296 rangeTxB = None
295 rangeTxB = None
297 structure = RADAR_STRUCTURE
296 structure = RADAR_STRUCTURE
298 __size = None
297 __size = None
299
298
300 def __init__(self, expType=2, nTx=1,
299 def __init__(self, expType=2, nTx=1,
301 ipp=None, txA=0, txB=0,
300 ipp=None, txA=0, txB=0,
302 nWindows=None, nHeights=None, firstHeight=None, deltaHeight=None,
301 nWindows=None, nHeights=None, firstHeight=None, deltaHeight=None,
303 numTaus=0, line6Function=0, line5Function=0, fClock=None,
302 numTaus=0, line6Function=0, line5Function=0, fClock=None,
304 prePulseBefore=0, prePulseAfter=0,
303 prePulseBefore=0, prePulseAfter=0,
305 codeType=0, nCode=0, nBaud=0, code=[],
304 codeType=0, nCode=0, nBaud=0, code=[],
306 flip1=0, flip2=0):
305 flip1=0, flip2=0):
307
306
308 # self.size = 116
307 # self.size = 116
309 self.expType = expType
308 self.expType = expType
310 self.nTx = nTx
309 self.nTx = nTx
311 self.ipp = ipp
310 self.ipp = ipp
312 self.txA = txA
311 self.txA = txA
313 self.txB = txB
312 self.txB = txB
314 self.rangeIpp = ipp
313 self.rangeIpp = ipp
315 self.rangeTxA = txA
314 self.rangeTxA = txA
316 self.rangeTxB = txB
315 self.rangeTxB = txB
317
316
318 self.nWindows = nWindows
317 self.nWindows = nWindows
319 self.numTaus = numTaus
318 self.numTaus = numTaus
320 self.codeType = codeType
319 self.codeType = codeType
321 self.line6Function = line6Function
320 self.line6Function = line6Function
322 self.line5Function = line5Function
321 self.line5Function = line5Function
323 self.fClock = fClock
322 self.fClock = fClock
324 self.prePulseBefore = prePulseBefore
323 self.prePulseBefore = prePulseBefore
325 self.prePulseAfter = prePulseAfter
324 self.prePulseAfter = prePulseAfter
326
325
327 self.nHeights = nHeights
326 self.nHeights = nHeights
328 self.firstHeight = firstHeight
327 self.firstHeight = firstHeight
329 self.deltaHeight = deltaHeight
328 self.deltaHeight = deltaHeight
330 self.samplesWin = nHeights
329 self.samplesWin = nHeights
331
330
332 self.nCode = nCode
331 self.nCode = nCode
333 self.nBaud = nBaud
332 self.nBaud = nBaud
334 self.code = code
333 self.code = code
335 self.flip1 = flip1
334 self.flip1 = flip1
336 self.flip2 = flip2
335 self.flip2 = flip2
337
336
338 self.code_size = int(numpy.ceil(self.nBaud / 32.)) * self.nCode * 4
337 self.code_size = int(numpy.ceil(self.nBaud / 32.)) * self.nCode * 4
339 # self.dynamic = numpy.array([],numpy.dtype('byte'))
338 # self.dynamic = numpy.array([],numpy.dtype('byte'))
340
339
341 if self.fClock is None and self.deltaHeight is not None:
340 if self.fClock is None and self.deltaHeight is not None:
342 self.fClock = 0.15 / (deltaHeight * 1e-6) # 0.15Km / (height * 1u)
341 self.fClock = 0.15 / (deltaHeight * 1e-6) # 0.15Km / (height * 1u)
343
342
344 def read(self, fp):
343 def read(self, fp):
345 self.length = 0
344 self.length = 0
346 try:
345 try:
347 startFp = fp.tell()
346 startFp = fp.tell()
348 except Exception as e:
347 except Exception as e:
349 startFp = None
348 startFp = None
350 pass
349 pass
351
350
352 try:
351 try:
353 if hasattr(fp, 'read'):
352 if hasattr(fp, 'read'):
354 header = numpy.fromfile(fp, RADAR_STRUCTURE, 1)
353 header = numpy.fromfile(fp, RADAR_STRUCTURE, 1)
355 else:
354 else:
356 header = numpy.fromstring(fp, RADAR_STRUCTURE, 1)
355 header = numpy.fromstring(fp, RADAR_STRUCTURE, 1)
357 self.length += header.nbytes
356 self.length += header.nbytes
358 except Exception as e:
357 except Exception as e:
359 print("RadarControllerHeader: " + str(e))
358 print("RadarControllerHeader: " + str(e))
360 return 0
359 return 0
361
360
362 size = int(header['nSize'][0])
361 size = int(header['nSize'][0])
363 self.expType = int(header['nExpType'][0])
362 self.expType = int(header['nExpType'][0])
364 self.nTx = int(header['nNTx'][0])
363 self.nTx = int(header['nNTx'][0])
365 self.ipp = float(header['fIpp'][0])
364 self.ipp = float(header['fIpp'][0])
366 #print(self.ipp)
365 #print(self.ipp)
367 self.txA = float(header['fTxA'][0])
366 self.txA = float(header['fTxA'][0])
368 self.txB = float(header['fTxB'][0])
367 self.txB = float(header['fTxB'][0])
369 self.nWindows = int(header['nNumWindows'][0])
368 self.nWindows = int(header['nNumWindows'][0])
370 self.numTaus = int(header['nNumTaus'][0])
369 self.numTaus = int(header['nNumTaus'][0])
371 self.codeType = int(header['nCodeType'][0])
370 self.codeType = int(header['nCodeType'][0])
372 self.line6Function = int(header['nLine6Function'][0])
371 self.line6Function = int(header['nLine6Function'][0])
373 self.line5Function = int(header['nLine5Function'][0])
372 self.line5Function = int(header['nLine5Function'][0])
374 self.fClock = float(header['fClock'][0])
373 self.fClock = float(header['fClock'][0])
375 self.prePulseBefore = int(header['nPrePulseBefore'][0])
374 self.prePulseBefore = int(header['nPrePulseBefore'][0])
376 self.prePulseAfter = int(header['nPrePulseAfter'][0])
375 self.prePulseAfter = int(header['nPrePulseAfter'][0])
377 self.rangeIpp = header['sRangeIPP'][0]
376 self.rangeIpp = header['sRangeIPP'][0]
378 self.rangeTxA = header['sRangeTxA'][0]
377 self.rangeTxA = header['sRangeTxA'][0]
379 self.rangeTxB = header['sRangeTxB'][0]
378 self.rangeTxB = header['sRangeTxB'][0]
380
379
381 try:
380 try:
382 if hasattr(fp, 'read'):
381 if hasattr(fp, 'read'):
383 samplingWindow = numpy.fromfile(
382 samplingWindow = numpy.fromfile(
384 fp, SAMPLING_STRUCTURE, self.nWindows)
383 fp, SAMPLING_STRUCTURE, self.nWindows)
385 else:
384 else:
386 samplingWindow = numpy.fromstring(
385 samplingWindow = numpy.fromstring(
387 fp[self.length:], SAMPLING_STRUCTURE, self.nWindows)
386 fp[self.length:], SAMPLING_STRUCTURE, self.nWindows)
388 self.length += samplingWindow.nbytes
387 self.length += samplingWindow.nbytes
389 except Exception as e:
388 except Exception as e:
390 print("RadarControllerHeader: " + str(e))
389 print("RadarControllerHeader: " + str(e))
391 return 0
390 return 0
392 self.nHeights = int(numpy.sum(samplingWindow['nsa']))
391 self.nHeights = int(numpy.sum(samplingWindow['nsa']))
393 self.firstHeight = samplingWindow['h0']
392 self.firstHeight = samplingWindow['h0']
394 self.deltaHeight = samplingWindow['dh']
393 self.deltaHeight = samplingWindow['dh']
395 self.samplesWin = samplingWindow['nsa']
394 self.samplesWin = samplingWindow['nsa']
396
395
397 try:
396 try:
398 if hasattr(fp, 'read'):
397 if hasattr(fp, 'read'):
399 self.Taus = numpy.fromfile(fp, '<f4', self.numTaus)
398 self.Taus = numpy.fromfile(fp, '<f4', self.numTaus)
400 else:
399 else:
401 self.Taus = numpy.fromstring(
400 self.Taus = numpy.fromstring(
402 fp[self.length:], '<f4', self.numTaus)
401 fp[self.length:], '<f4', self.numTaus)
403 self.length += self.Taus.nbytes
402 self.length += self.Taus.nbytes
404 except Exception as e:
403 except Exception as e:
405 print("RadarControllerHeader: " + str(e))
404 print("RadarControllerHeader: " + str(e))
406 return 0
405 return 0
407
406
408 self.code_size = 0
407 self.code_size = 0
409 if self.codeType != 0:
408 if self.codeType != 0:
410
409
411 try:
410 try:
412 if hasattr(fp, 'read'):
411 if hasattr(fp, 'read'):
413 self.nCode = numpy.fromfile(fp, '<u4', 1)[0]
412 self.nCode = numpy.fromfile(fp, '<u4', 1)[0]
414 self.length += self.nCode.nbytes
413 self.length += self.nCode.nbytes
415 self.nBaud = numpy.fromfile(fp, '<u4', 1)[0]
414 self.nBaud = numpy.fromfile(fp, '<u4', 1)[0]
416 self.length += self.nBaud.nbytes
415 self.length += self.nBaud.nbytes
417 else:
416 else:
418 self.nCode = numpy.fromstring(
417 self.nCode = numpy.fromstring(
419 fp[self.length:], '<u4', 1)[0]
418 fp[self.length:], '<u4', 1)[0]
420 self.length += self.nCode.nbytes
419 self.length += self.nCode.nbytes
421 self.nBaud = numpy.fromstring(
420 self.nBaud = numpy.fromstring(
422 fp[self.length:], '<u4', 1)[0]
421 fp[self.length:], '<u4', 1)[0]
423 self.length += self.nBaud.nbytes
422 self.length += self.nBaud.nbytes
424 except Exception as e:
423 except Exception as e:
425 print("RadarControllerHeader: " + str(e))
424 print("RadarControllerHeader: " + str(e))
426 return 0
425 return 0
427 code = numpy.empty([self.nCode, self.nBaud], dtype='i1')
426 code = numpy.empty([self.nCode, self.nBaud], dtype='i1')
428
427
429 for ic in range(self.nCode):
428 for ic in range(self.nCode):
430 try:
429 try:
431 if hasattr(fp, 'read'):
430 if hasattr(fp, 'read'):
432 temp = numpy.fromfile(fp, 'u4', int(
431 temp = numpy.fromfile(fp, 'u4', int(
433 numpy.ceil(self.nBaud / 32.)))
432 numpy.ceil(self.nBaud / 32.)))
434 else:
433 else:
435 temp = numpy.fromstring(
434 temp = numpy.fromstring(
436 fp, 'u4', int(numpy.ceil(self.nBaud / 32.)))
435 fp, 'u4', int(numpy.ceil(self.nBaud / 32.)))
437 self.length += temp.nbytes
436 self.length += temp.nbytes
438 except Exception as e:
437 except Exception as e:
439 print("RadarControllerHeader: " + str(e))
438 print("RadarControllerHeader: " + str(e))
440 return 0
439 return 0
441
440
442 for ib in range(self.nBaud - 1, -1, -1):
441 for ib in range(self.nBaud - 1, -1, -1):
443 code[ic, ib] = temp[int(ib / 32)] % 2
442 code[ic, ib] = temp[int(ib / 32)] % 2
444 temp[int(ib / 32)] = temp[int(ib / 32)] / 2
443 temp[int(ib / 32)] = temp[int(ib / 32)] / 2
445
444
446 self.code = 2.0 * code - 1.0
445 self.code = 2.0 * code - 1.0
447 self.code_size = int(numpy.ceil(self.nBaud / 32.)) * self.nCode * 4
446 self.code_size = int(numpy.ceil(self.nBaud / 32.)) * self.nCode * 4
448
447
449 # if self.line5Function == RCfunction.FLIP:
448 # if self.line5Function == RCfunction.FLIP:
450 # self.flip1 = numpy.fromfile(fp,'<u4',1)
449 # self.flip1 = numpy.fromfile(fp,'<u4',1)
451 #
450 #
452 # if self.line6Function == RCfunction.FLIP:
451 # if self.line6Function == RCfunction.FLIP:
453 # self.flip2 = numpy.fromfile(fp,'<u4',1)
452 # self.flip2 = numpy.fromfile(fp,'<u4',1)
454 if startFp is not None:
453 if startFp is not None:
455 endFp = size + startFp
454 endFp = size + startFp
456
455
457 if fp.tell() != endFp:
456 if fp.tell() != endFp:
458 # fp.seek(endFp)
457 # fp.seek(endFp)
459 print("%s: Radar Controller Header size is not consistent: from data [%d] != from header field [%d]" % (fp.name, fp.tell() - startFp, size))
458 print("%s: Radar Controller Header size is not consistent: from data [%d] != from header field [%d]" % (fp.name, fp.tell() - startFp, size))
460 # return 0
459 # return 0
461
460
462 if fp.tell() > endFp:
461 if fp.tell() > endFp:
463 sys.stderr.write(
462 sys.stderr.write(
464 "Warning %s: Size value read from Radar Controller header is lower than it has to be\n" % fp.name)
463 "Warning %s: Size value read from Radar Controller header is lower than it has to be\n" % fp.name)
465 # return 0
464 # return 0
466
465
467 if fp.tell() < endFp:
466 if fp.tell() < endFp:
468 sys.stderr.write(
467 sys.stderr.write(
469 "Warning %s: Size value read from Radar Controller header is greater than it has to be\n" % fp.name)
468 "Warning %s: Size value read from Radar Controller header is greater than it has to be\n" % fp.name)
470
469
471 return 1
470 return 1
472
471
473 def write(self, fp):
472 def write(self, fp):
474
473
475 headerTuple = (self.size,
474 headerTuple = (self.size,
476 self.expType,
475 self.expType,
477 self.nTx,
476 self.nTx,
478 self.ipp,
477 self.ipp,
479 self.txA,
478 self.txA,
480 self.txB,
479 self.txB,
481 self.nWindows,
480 self.nWindows,
482 self.numTaus,
481 self.numTaus,
483 self.codeType,
482 self.codeType,
484 self.line6Function,
483 self.line6Function,
485 self.line5Function,
484 self.line5Function,
486 self.fClock,
485 self.fClock,
487 self.prePulseBefore,
486 self.prePulseBefore,
488 self.prePulseAfter,
487 self.prePulseAfter,
489 self.rangeIpp,
488 self.rangeIpp,
490 self.rangeTxA,
489 self.rangeTxA,
491 self.rangeTxB)
490 self.rangeTxB)
492
491
493 header = numpy.array(headerTuple, RADAR_STRUCTURE)
492 header = numpy.array(headerTuple, RADAR_STRUCTURE)
494 header.tofile(fp)
493 header.tofile(fp)
495
494
496 sampleWindowTuple = (
495 sampleWindowTuple = (
497 self.firstHeight, self.deltaHeight, self.samplesWin)
496 self.firstHeight, self.deltaHeight, self.samplesWin)
498 samplingWindow = numpy.array(sampleWindowTuple, SAMPLING_STRUCTURE)
497 samplingWindow = numpy.array(sampleWindowTuple, SAMPLING_STRUCTURE)
499 samplingWindow.tofile(fp)
498 samplingWindow.tofile(fp)
500
499
501 if self.numTaus > 0:
500 if self.numTaus > 0:
502 self.Taus.tofile(fp)
501 self.Taus.tofile(fp)
503
502
504 if self.codeType != 0:
503 if self.codeType != 0:
505 nCode = numpy.array(self.nCode, '<u4')
504 nCode = numpy.array(self.nCode, '<u4')
506 nCode.tofile(fp)
505 nCode.tofile(fp)
507 nBaud = numpy.array(self.nBaud, '<u4')
506 nBaud = numpy.array(self.nBaud, '<u4')
508 nBaud.tofile(fp)
507 nBaud.tofile(fp)
509 code1 = (self.code + 1.0) / 2.
508 code1 = (self.code + 1.0) / 2.
510
509
511 for ic in range(self.nCode):
510 for ic in range(self.nCode):
512 tempx = numpy.zeros(int(numpy.ceil(self.nBaud / 32.)))
511 tempx = numpy.zeros(int(numpy.ceil(self.nBaud / 32.)))
513 start = 0
512 start = 0
514 end = 32
513 end = 32
515 for i in range(len(tempx)):
514 for i in range(len(tempx)):
516 code_selected = code1[ic, start:end]
515 code_selected = code1[ic, start:end]
517 for j in range(len(code_selected) - 1, -1, -1):
516 for j in range(len(code_selected) - 1, -1, -1):
518 if code_selected[j] == 1:
517 if code_selected[j] == 1:
519 tempx[i] = tempx[i] + \
518 tempx[i] = tempx[i] + \
520 2 ** (len(code_selected) - 1 - j)
519 2 ** (len(code_selected) - 1 - j)
521 start = start + 32
520 start = start + 32
522 end = end + 32
521 end = end + 32
523
522
524 tempx = tempx.astype('u4')
523 tempx = tempx.astype('u4')
525 tempx.tofile(fp)
524 tempx.tofile(fp)
526
525
527 # if self.line5Function == RCfunction.FLIP:
526 # if self.line5Function == RCfunction.FLIP:
528 # self.flip1.tofile(fp)
527 # self.flip1.tofile(fp)
529 #
528 #
530 # if self.line6Function == RCfunction.FLIP:
529 # if self.line6Function == RCfunction.FLIP:
531 # self.flip2.tofile(fp)
530 # self.flip2.tofile(fp)
532
531
533 return 1
532 return 1
534
533
535 def get_ippSeconds(self):
534 def get_ippSeconds(self):
536 '''
535 '''
537 '''
536 '''
538
537
539 ippSeconds = 2.0 * 1000 * self.ipp / SPEED_OF_LIGHT
538 ippSeconds = 2.0 * 1000 * self.ipp / SPEED_OF_LIGHT
540
539
541 return ippSeconds
540 return ippSeconds
542
541
543 def set_ippSeconds(self, ippSeconds):
542 def set_ippSeconds(self, ippSeconds):
544 '''
543 '''
545 '''
544 '''
546
545
547 self.ipp = ippSeconds * SPEED_OF_LIGHT / (2.0 * 1000)
546 self.ipp = ippSeconds * SPEED_OF_LIGHT / (2.0 * 1000)
548
547
549 return
548 return
550
549
551 def get_size(self):
550 def get_size(self):
552
551
553 self.__size = 116 + 12 * self.nWindows + 4 * self.numTaus
552 self.__size = 116 + 12 * self.nWindows + 4 * self.numTaus
554
553
555 if self.codeType != 0:
554 if self.codeType != 0:
556 self.__size += 4 + 4 + 4 * self.nCode * \
555 self.__size += 4 + 4 + 4 * self.nCode * \
557 numpy.ceil(self.nBaud / 32.)
556 numpy.ceil(self.nBaud / 32.)
558
557
559 return self.__size
558 return self.__size
560
559
561 def set_size(self, value):
560 def set_size(self, value):
562
561
563 raise IOError("size is a property and it cannot be set, just read")
562 raise IOError("size is a property and it cannot be set, just read")
564
563
565 return
564 return
566
565
567 ippSeconds = property(get_ippSeconds, set_ippSeconds)
566 ippSeconds = property(get_ippSeconds, set_ippSeconds)
568 size = property(get_size, set_size)
567 size = property(get_size, set_size)
569
568
570
569
571 class ProcessingHeader(Header):
570 class ProcessingHeader(Header):
572
571
573 # size = None
572 # size = None
574 dtype = None
573 dtype = None
575 blockSize = None
574 blockSize = None
576 profilesPerBlock = None
575 profilesPerBlock = None
577 dataBlocksPerFile = None
576 dataBlocksPerFile = None
578 nWindows = None
577 nWindows = None
579 processFlags = None
578 processFlags = None
580 nCohInt = None
579 nCohInt = None
581 nIncohInt = None
580 nIncohInt = None
582 totalSpectra = None
581 totalSpectra = None
583 structure = PROCESSING_STRUCTURE
582 structure = PROCESSING_STRUCTURE
584 flag_dc = None
583 flag_dc = None
585 flag_cspc = None
584 flag_cspc = None
586
585
587 def __init__(self, dtype=0, blockSize=0, profilesPerBlock=0, dataBlocksPerFile=0, nWindows=0, processFlags=0, nCohInt=0,
586 def __init__(self, dtype=0, blockSize=0, profilesPerBlock=0, dataBlocksPerFile=0, nWindows=0, processFlags=0, nCohInt=0,
588 nIncohInt=0, totalSpectra=0, nHeights=0, firstHeight=0, deltaHeight=0, samplesWin=0, spectraComb=0, nCode=0,
587 nIncohInt=0, totalSpectra=0, nHeights=0, firstHeight=0, deltaHeight=0, samplesWin=0, spectraComb=0, nCode=0,
589 code=0, nBaud=None, shif_fft=False, flag_dc=False, flag_cspc=False, flag_decode=False, flag_deflip=False
588 code=0, nBaud=None, shif_fft=False, flag_dc=False, flag_cspc=False, flag_decode=False, flag_deflip=False
590 ):
589 ):
591
590
592 # self.size = 0
591 # self.size = 0
593 self.dtype = dtype
592 self.dtype = dtype
594 self.blockSize = blockSize
593 self.blockSize = blockSize
595 self.profilesPerBlock = 0
594 self.profilesPerBlock = 0
596 self.dataBlocksPerFile = 0
595 self.dataBlocksPerFile = 0
597 self.nWindows = 0
596 self.nWindows = 0
598 self.processFlags = 0
597 self.processFlags = 0
599 self.nCohInt = 0
598 self.nCohInt = 0
600 self.nIncohInt = 0
599 self.nIncohInt = 0
601 self.totalSpectra = 0
600 self.totalSpectra = 0
602
601
603 self.nHeights = 0
602 self.nHeights = 0
604 self.firstHeight = 0
603 self.firstHeight = 0
605 self.deltaHeight = 0
604 self.deltaHeight = 0
606 self.samplesWin = 0
605 self.samplesWin = 0
607 self.spectraComb = 0
606 self.spectraComb = 0
608 self.nCode = None
607 self.nCode = None
609 self.code = None
608 self.code = None
610 self.nBaud = None
609 self.nBaud = None
611
610
612 self.shif_fft = False
611 self.shif_fft = False
613 self.flag_dc = False
612 self.flag_dc = False
614 self.flag_cspc = False
613 self.flag_cspc = False
615 self.flag_decode = False
614 self.flag_decode = False
616 self.flag_deflip = False
615 self.flag_deflip = False
617 self.length = 0
616 self.length = 0
618
617
619 def read(self, fp):
618 def read(self, fp):
620 self.length = 0
619 self.length = 0
621 try:
620 try:
622 startFp = fp.tell()
621 startFp = fp.tell()
623 except Exception as e:
622 except Exception as e:
624 startFp = None
623 startFp = None
625 pass
624 pass
626
625
627 try:
626 try:
628 if hasattr(fp, 'read'):
627 if hasattr(fp, 'read'):
629 header = numpy.fromfile(fp, PROCESSING_STRUCTURE, 1)
628 header = numpy.fromfile(fp, PROCESSING_STRUCTURE, 1)
630 else:
629 else:
631 header = numpy.fromstring(fp, PROCESSING_STRUCTURE, 1)
630 header = numpy.fromstring(fp, PROCESSING_STRUCTURE, 1)
632 self.length += header.nbytes
631 self.length += header.nbytes
633 except Exception as e:
632 except Exception as e:
634 print("ProcessingHeader: " + str(e))
633 print("ProcessingHeader: " + str(e))
635 return 0
634 return 0
636
635
637 size = int(header['nSize'][0])
636 size = int(header['nSize'][0])
638 self.dtype = int(header['nDataType'][0])
637 self.dtype = int(header['nDataType'][0])
639 self.blockSize = int(header['nSizeOfDataBlock'][0])
638 self.blockSize = int(header['nSizeOfDataBlock'][0])
640 self.profilesPerBlock = int(header['nProfilesperBlock'][0])
639 self.profilesPerBlock = int(header['nProfilesperBlock'][0])
641 self.dataBlocksPerFile = int(header['nDataBlocksperFile'][0])
640 self.dataBlocksPerFile = int(header['nDataBlocksperFile'][0])
642 self.nWindows = int(header['nNumWindows'][0])
641 self.nWindows = int(header['nNumWindows'][0])
643 self.processFlags = header['nProcessFlags']
642 self.processFlags = header['nProcessFlags']
644 self.nCohInt = int(header['nCoherentIntegrations'][0])
643 self.nCohInt = int(header['nCoherentIntegrations'][0])
645
644
646 self.nIncohInt = int(header['nIncoherentIntegrations'][0])
645 self.nIncohInt = int(header['nIncoherentIntegrations'][0])
647 self.totalSpectra = int(header['nTotalSpectra'][0])
646 self.totalSpectra = int(header['nTotalSpectra'][0])
648
647
649 try:
648 try:
650 if hasattr(fp, 'read'):
649 if hasattr(fp, 'read'):
651 samplingWindow = numpy.fromfile(
650 samplingWindow = numpy.fromfile(
652 fp, SAMPLING_STRUCTURE, self.nWindows)
651 fp, SAMPLING_STRUCTURE, self.nWindows)
653 else:
652 else:
654 samplingWindow = numpy.fromstring(
653 samplingWindow = numpy.fromstring(
655 fp[self.length:], SAMPLING_STRUCTURE, self.nWindows)
654 fp[self.length:], SAMPLING_STRUCTURE, self.nWindows)
656 self.length += samplingWindow.nbytes
655 self.length += samplingWindow.nbytes
657 except Exception as e:
656 except Exception as e:
658 print("ProcessingHeader: " + str(e))
657 print("ProcessingHeader: " + str(e))
659 return 0
658 return 0
660
659
661 self.nHeights = int(numpy.sum(samplingWindow['nsa']))
660 self.nHeights = int(numpy.sum(samplingWindow['nsa']))
662 self.firstHeight = float(samplingWindow['h0'][0])
661 self.firstHeight = float(samplingWindow['h0'][0])
663 self.deltaHeight = float(samplingWindow['dh'][0])
662 self.deltaHeight = float(samplingWindow['dh'][0])
664 self.samplesWin = samplingWindow['nsa'][0]
663 self.samplesWin = samplingWindow['nsa'][0]
665
664
666 try:
665 try:
667 if hasattr(fp, 'read'):
666 if hasattr(fp, 'read'):
668 self.spectraComb = numpy.fromfile(
667 self.spectraComb = numpy.fromfile(
669 fp, 'u1', 2 * self.totalSpectra)
668 fp, 'u1', 2 * self.totalSpectra)
670 else:
669 else:
671 self.spectraComb = numpy.fromstring(
670 self.spectraComb = numpy.fromstring(
672 fp[self.length:], 'u1', 2 * self.totalSpectra)
671 fp[self.length:], 'u1', 2 * self.totalSpectra)
673 self.length += self.spectraComb.nbytes
672 self.length += self.spectraComb.nbytes
674 except Exception as e:
673 except Exception as e:
675 print("ProcessingHeader: " + str(e))
674 print("ProcessingHeader: " + str(e))
676 return 0
675 return 0
677
676
678 if ((self.processFlags & PROCFLAG.DEFINE_PROCESS_CODE) == PROCFLAG.DEFINE_PROCESS_CODE):
677 if ((self.processFlags & PROCFLAG.DEFINE_PROCESS_CODE) == PROCFLAG.DEFINE_PROCESS_CODE):
679 self.nCode = int(numpy.fromfile(fp, '<u4', 1))
678 self.nCode = int(numpy.fromfile(fp, '<u4', 1))
680 self.nBaud = int(numpy.fromfile(fp, '<u4', 1))
679 self.nBaud = int(numpy.fromfile(fp, '<u4', 1))
681 self.code = numpy.fromfile(
680 self.code = numpy.fromfile(
682 fp, '<f4', self.nCode * self.nBaud).reshape(self.nCode, self.nBaud)
681 fp, '<f4', self.nCode * self.nBaud).reshape(self.nCode, self.nBaud)
683
682
684 if ((self.processFlags & PROCFLAG.EXP_NAME_ESP) == PROCFLAG.EXP_NAME_ESP):
683 if ((self.processFlags & PROCFLAG.EXP_NAME_ESP) == PROCFLAG.EXP_NAME_ESP):
685 exp_name_len = int(numpy.fromfile(fp, '<u4', 1))
684 exp_name_len = int(numpy.fromfile(fp, '<u4', 1))
686 exp_name = numpy.fromfile(fp, 'u1', exp_name_len + 1)
685 exp_name = numpy.fromfile(fp, 'u1', exp_name_len + 1)
687
686
688 if ((self.processFlags & PROCFLAG.SHIFT_FFT_DATA) == PROCFLAG.SHIFT_FFT_DATA):
687 if ((self.processFlags & PROCFLAG.SHIFT_FFT_DATA) == PROCFLAG.SHIFT_FFT_DATA):
689 self.shif_fft = True
688 self.shif_fft = True
690 else:
689 else:
691 self.shif_fft = False
690 self.shif_fft = False
692
691
693 if ((self.processFlags & PROCFLAG.SAVE_CHANNELS_DC) == PROCFLAG.SAVE_CHANNELS_DC):
692 if ((self.processFlags & PROCFLAG.SAVE_CHANNELS_DC) == PROCFLAG.SAVE_CHANNELS_DC):
694 self.flag_dc = True
693 self.flag_dc = True
695 else:
694 else:
696 self.flag_dc = False
695 self.flag_dc = False
697
696
698 if ((self.processFlags & PROCFLAG.DECODE_DATA) == PROCFLAG.DECODE_DATA):
697 if ((self.processFlags & PROCFLAG.DECODE_DATA) == PROCFLAG.DECODE_DATA):
699 self.flag_decode = True
698 self.flag_decode = True
700 else:
699 else:
701 self.flag_decode = False
700 self.flag_decode = False
702
701
703 if ((self.processFlags & PROCFLAG.DEFLIP_DATA) == PROCFLAG.DEFLIP_DATA):
702 if ((self.processFlags & PROCFLAG.DEFLIP_DATA) == PROCFLAG.DEFLIP_DATA):
704 self.flag_deflip = True
703 self.flag_deflip = True
705 else:
704 else:
706 self.flag_deflip = False
705 self.flag_deflip = False
707
706
708 nChannels = 0
707 nChannels = 0
709 nPairs = 0
708 nPairs = 0
710 pairList = []
709 pairList = []
711
710
712 for i in range(0, self.totalSpectra * 2, 2):
711 for i in range(0, self.totalSpectra * 2, 2):
713 if self.spectraComb[i] == self.spectraComb[i + 1]:
712 if self.spectraComb[i] == self.spectraComb[i + 1]:
714 nChannels = nChannels + 1 # par de canales iguales
713 nChannels = nChannels + 1 # par de canales iguales
715 else:
714 else:
716 nPairs = nPairs + 1 # par de canales diferentes
715 nPairs = nPairs + 1 # par de canales diferentes
717 pairList.append((self.spectraComb[i], self.spectraComb[i + 1]))
716 pairList.append((self.spectraComb[i], self.spectraComb[i + 1]))
718
717
719 self.flag_cspc = False
718 self.flag_cspc = False
720 if nPairs > 0:
719 if nPairs > 0:
721 self.flag_cspc = True
720 self.flag_cspc = True
722
721
723 if startFp is not None:
722 if startFp is not None:
724 endFp = size + startFp
723 endFp = size + startFp
725 if fp.tell() > endFp:
724 if fp.tell() > endFp:
726 sys.stderr.write(
725 sys.stderr.write(
727 "Warning: Processing header size is lower than it has to be")
726 "Warning: Processing header size is lower than it has to be")
728 return 0
727 return 0
729
728
730 if fp.tell() < endFp:
729 if fp.tell() < endFp:
731 sys.stderr.write(
730 sys.stderr.write(
732 "Warning: Processing header size is greater than it is considered")
731 "Warning: Processing header size is greater than it is considered")
733
732
734 return 1
733 return 1
735
734
736 def write(self, fp):
735 def write(self, fp):
737 # Clear DEFINE_PROCESS_CODE
736 # Clear DEFINE_PROCESS_CODE
738 self.processFlags = self.processFlags & (~PROCFLAG.DEFINE_PROCESS_CODE)
737 self.processFlags = self.processFlags & (~PROCFLAG.DEFINE_PROCESS_CODE)
739
738
740 headerTuple = (self.size,
739 headerTuple = (self.size,
741 self.dtype,
740 self.dtype,
742 self.blockSize,
741 self.blockSize,
743 self.profilesPerBlock,
742 self.profilesPerBlock,
744 self.dataBlocksPerFile,
743 self.dataBlocksPerFile,
745 self.nWindows,
744 self.nWindows,
746 self.processFlags,
745 self.processFlags,
747 self.nCohInt,
746 self.nCohInt,
748 self.nIncohInt,
747 self.nIncohInt,
749 self.totalSpectra)
748 self.totalSpectra)
750
749
751 header = numpy.array(headerTuple, PROCESSING_STRUCTURE)
750 header = numpy.array(headerTuple, PROCESSING_STRUCTURE)
752 header.tofile(fp)
751 header.tofile(fp)
753
752
754 if self.nWindows != 0:
753 if self.nWindows != 0:
755 sampleWindowTuple = (
754 sampleWindowTuple = (
756 self.firstHeight, self.deltaHeight, self.samplesWin)
755 self.firstHeight, self.deltaHeight, self.samplesWin)
757 samplingWindow = numpy.array(sampleWindowTuple, SAMPLING_STRUCTURE)
756 samplingWindow = numpy.array(sampleWindowTuple, SAMPLING_STRUCTURE)
758 samplingWindow.tofile(fp)
757 samplingWindow.tofile(fp)
759
758
760 if self.totalSpectra != 0:
759 if self.totalSpectra != 0:
761 # spectraComb = numpy.array([],numpy.dtype('u1'))
760 # spectraComb = numpy.array([],numpy.dtype('u1'))
762 spectraComb = self.spectraComb
761 spectraComb = self.spectraComb
763 spectraComb.tofile(fp)
762 spectraComb.tofile(fp)
764
763
765 # if self.processFlags & PROCFLAG.DEFINE_PROCESS_CODE == PROCFLAG.DEFINE_PROCESS_CODE:
764 # if self.processFlags & PROCFLAG.DEFINE_PROCESS_CODE == PROCFLAG.DEFINE_PROCESS_CODE:
766 # nCode = numpy.array([self.nCode], numpy.dtype('u4')) #Probar con un dato que almacene codigo, hasta el momento no se hizo la prueba
765 # nCode = numpy.array([self.nCode], numpy.dtype('u4')) #Probar con un dato que almacene codigo, hasta el momento no se hizo la prueba
767 # nCode.tofile(fp)
766 # nCode.tofile(fp)
768 #
767 #
769 # nBaud = numpy.array([self.nBaud], numpy.dtype('u4'))
768 # nBaud = numpy.array([self.nBaud], numpy.dtype('u4'))
770 # nBaud.tofile(fp)
769 # nBaud.tofile(fp)
771 #
770 #
772 # code = self.code.reshape(self.nCode*self.nBaud)
771 # code = self.code.reshape(self.nCode*self.nBaud)
773 # code = code.astype(numpy.dtype('<f4'))
772 # code = code.astype(numpy.dtype('<f4'))
774 # code.tofile(fp)
773 # code.tofile(fp)
775
774
776 return 1
775 return 1
777
776
778 def get_size(self):
777 def get_size(self):
779
778
780 self.__size = 40 + 12 * self.nWindows + 2 * self.totalSpectra
779 self.__size = 40 + 12 * self.nWindows + 2 * self.totalSpectra
781
780
782 # if self.processFlags & PROCFLAG.DEFINE_PROCESS_CODE == PROCFLAG.DEFINE_PROCESS_CODE:
781 # if self.processFlags & PROCFLAG.DEFINE_PROCESS_CODE == PROCFLAG.DEFINE_PROCESS_CODE:
783 # self.__size += 4 + 4 + 4*self.nCode*numpy.ceil(self.nBaud/32.)
782 # self.__size += 4 + 4 + 4*self.nCode*numpy.ceil(self.nBaud/32.)
784 # self.__size += 4 + 4 + 4 * self.nCode * self.nBaud
783 # self.__size += 4 + 4 + 4 * self.nCode * self.nBaud
785
784
786 return self.__size
785 return self.__size
787
786
788 def set_size(self, value):
787 def set_size(self, value):
789
788
790 raise IOError("size is a property and it cannot be set, just read")
789 raise IOError("size is a property and it cannot be set, just read")
791
790
792 return
791 return
793
792
794 size = property(get_size, set_size)
793 size = property(get_size, set_size)
795
794
796
795
797 class RCfunction:
796 class RCfunction:
798 NONE = 0
797 NONE = 0
799 FLIP = 1
798 FLIP = 1
800 CODE = 2
799 CODE = 2
801 SAMPLING = 3
800 SAMPLING = 3
802 LIN6DIV256 = 4
801 LIN6DIV256 = 4
803 SYNCHRO = 5
802 SYNCHRO = 5
804
803
805
804
806 class nCodeType:
805 class nCodeType:
807 NONE = 0
806 NONE = 0
808 USERDEFINE = 1
807 USERDEFINE = 1
809 BARKER2 = 2
808 BARKER2 = 2
810 BARKER3 = 3
809 BARKER3 = 3
811 BARKER4 = 4
810 BARKER4 = 4
812 BARKER5 = 5
811 BARKER5 = 5
813 BARKER7 = 6
812 BARKER7 = 6
814 BARKER11 = 7
813 BARKER11 = 7
815 BARKER13 = 8
814 BARKER13 = 8
816 AC128 = 9
815 AC128 = 9
817 COMPLEMENTARYCODE2 = 10
816 COMPLEMENTARYCODE2 = 10
818 COMPLEMENTARYCODE4 = 11
817 COMPLEMENTARYCODE4 = 11
819 COMPLEMENTARYCODE8 = 12
818 COMPLEMENTARYCODE8 = 12
820 COMPLEMENTARYCODE16 = 13
819 COMPLEMENTARYCODE16 = 13
821 COMPLEMENTARYCODE32 = 14
820 COMPLEMENTARYCODE32 = 14
822 COMPLEMENTARYCODE64 = 15
821 COMPLEMENTARYCODE64 = 15
823 COMPLEMENTARYCODE128 = 16
822 COMPLEMENTARYCODE128 = 16
824 CODE_BINARY28 = 17
823 CODE_BINARY28 = 17
825
824
826
825
827 class PROCFLAG:
826 class PROCFLAG:
828
827
829 COHERENT_INTEGRATION = numpy.uint32(0x00000001)
828 COHERENT_INTEGRATION = numpy.uint32(0x00000001)
830 DECODE_DATA = numpy.uint32(0x00000002)
829 DECODE_DATA = numpy.uint32(0x00000002)
831 SPECTRA_CALC = numpy.uint32(0x00000004)
830 SPECTRA_CALC = numpy.uint32(0x00000004)
832 INCOHERENT_INTEGRATION = numpy.uint32(0x00000008)
831 INCOHERENT_INTEGRATION = numpy.uint32(0x00000008)
833 POST_COHERENT_INTEGRATION = numpy.uint32(0x00000010)
832 POST_COHERENT_INTEGRATION = numpy.uint32(0x00000010)
834 SHIFT_FFT_DATA = numpy.uint32(0x00000020)
833 SHIFT_FFT_DATA = numpy.uint32(0x00000020)
835
834
836 DATATYPE_CHAR = numpy.uint32(0x00000040)
835 DATATYPE_CHAR = numpy.uint32(0x00000040)
837 DATATYPE_SHORT = numpy.uint32(0x00000080)
836 DATATYPE_SHORT = numpy.uint32(0x00000080)
838 DATATYPE_LONG = numpy.uint32(0x00000100)
837 DATATYPE_LONG = numpy.uint32(0x00000100)
839 DATATYPE_INT64 = numpy.uint32(0x00000200)
838 DATATYPE_INT64 = numpy.uint32(0x00000200)
840 DATATYPE_FLOAT = numpy.uint32(0x00000400)
839 DATATYPE_FLOAT = numpy.uint32(0x00000400)
841 DATATYPE_DOUBLE = numpy.uint32(0x00000800)
840 DATATYPE_DOUBLE = numpy.uint32(0x00000800)
842
841
843 DATAARRANGE_CONTIGUOUS_CH = numpy.uint32(0x00001000)
842 DATAARRANGE_CONTIGUOUS_CH = numpy.uint32(0x00001000)
844 DATAARRANGE_CONTIGUOUS_H = numpy.uint32(0x00002000)
843 DATAARRANGE_CONTIGUOUS_H = numpy.uint32(0x00002000)
845 DATAARRANGE_CONTIGUOUS_P = numpy.uint32(0x00004000)
844 DATAARRANGE_CONTIGUOUS_P = numpy.uint32(0x00004000)
846
845
847 SAVE_CHANNELS_DC = numpy.uint32(0x00008000)
846 SAVE_CHANNELS_DC = numpy.uint32(0x00008000)
848 DEFLIP_DATA = numpy.uint32(0x00010000)
847 DEFLIP_DATA = numpy.uint32(0x00010000)
849 DEFINE_PROCESS_CODE = numpy.uint32(0x00020000)
848 DEFINE_PROCESS_CODE = numpy.uint32(0x00020000)
850
849
851 ACQ_SYS_NATALIA = numpy.uint32(0x00040000)
850 ACQ_SYS_NATALIA = numpy.uint32(0x00040000)
852 ACQ_SYS_ECHOTEK = numpy.uint32(0x00080000)
851 ACQ_SYS_ECHOTEK = numpy.uint32(0x00080000)
853 ACQ_SYS_ADRXD = numpy.uint32(0x000C0000)
852 ACQ_SYS_ADRXD = numpy.uint32(0x000C0000)
854 ACQ_SYS_JULIA = numpy.uint32(0x00100000)
853 ACQ_SYS_JULIA = numpy.uint32(0x00100000)
855 ACQ_SYS_XXXXXX = numpy.uint32(0x00140000)
854 ACQ_SYS_XXXXXX = numpy.uint32(0x00140000)
856
855
857 EXP_NAME_ESP = numpy.uint32(0x00200000)
856 EXP_NAME_ESP = numpy.uint32(0x00200000)
858 CHANNEL_NAMES_ESP = numpy.uint32(0x00400000)
857 CHANNEL_NAMES_ESP = numpy.uint32(0x00400000)
859
858
860 OPERATION_MASK = numpy.uint32(0x0000003F)
859 OPERATION_MASK = numpy.uint32(0x0000003F)
861 DATATYPE_MASK = numpy.uint32(0x00000FC0)
860 DATATYPE_MASK = numpy.uint32(0x00000FC0)
862 DATAARRANGE_MASK = numpy.uint32(0x00007000)
861 DATAARRANGE_MASK = numpy.uint32(0x00007000)
863 ACQ_SYS_MASK = numpy.uint32(0x001C0000)
862 ACQ_SYS_MASK = numpy.uint32(0x001C0000)
864
863
865
864
866 dtype0 = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
865 dtype0 = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
867 dtype1 = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
866 dtype1 = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
868 dtype2 = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
867 dtype2 = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
869 dtype3 = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
868 dtype3 = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
870 dtype4 = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
869 dtype4 = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
871 dtype5 = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
870 dtype5 = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
872
871
873 NUMPY_DTYPE_LIST = [dtype0, dtype1, dtype2, dtype3, dtype4, dtype5]
872 NUMPY_DTYPE_LIST = [dtype0, dtype1, dtype2, dtype3, dtype4, dtype5]
874
873
875 PROCFLAG_DTYPE_LIST = [PROCFLAG.DATATYPE_CHAR,
874 PROCFLAG_DTYPE_LIST = [PROCFLAG.DATATYPE_CHAR,
876 PROCFLAG.DATATYPE_SHORT,
875 PROCFLAG.DATATYPE_SHORT,
877 PROCFLAG.DATATYPE_LONG,
876 PROCFLAG.DATATYPE_LONG,
878 PROCFLAG.DATATYPE_INT64,
877 PROCFLAG.DATATYPE_INT64,
879 PROCFLAG.DATATYPE_FLOAT,
878 PROCFLAG.DATATYPE_FLOAT,
880 PROCFLAG.DATATYPE_DOUBLE]
879 PROCFLAG.DATATYPE_DOUBLE]
881
880
882 DTYPE_WIDTH = [1, 2, 4, 8, 4, 8]
881 DTYPE_WIDTH = [1, 2, 4, 8, 4, 8]
883
882
884
883
885 def get_dtype_index(numpy_dtype):
884 def get_dtype_index(numpy_dtype):
886
885
887 index = None
886 index = None
888
887
889 for i in range(len(NUMPY_DTYPE_LIST)):
888 for i in range(len(NUMPY_DTYPE_LIST)):
890 if numpy_dtype == NUMPY_DTYPE_LIST[i]:
889 if numpy_dtype == NUMPY_DTYPE_LIST[i]:
891 index = i
890 index = i
892 break
891 break
893
892
894 return index
893 return index
895
894
896
895
897 def get_numpy_dtype(index):
896 def get_numpy_dtype(index):
898
897
899 return NUMPY_DTYPE_LIST[index]
898 return NUMPY_DTYPE_LIST[index]
900
899
901
900
902 def get_procflag_dtype(index):
901 def get_procflag_dtype(index):
903
902
904 return PROCFLAG_DTYPE_LIST[index]
903 return PROCFLAG_DTYPE_LIST[index]
905
904
906
905
907 def get_dtype_width(index):
906 def get_dtype_width(index):
908
907
909 return DTYPE_WIDTH[index]
908 return DTYPE_WIDTH[index]
@@ -1,355 +1,361
1 '''
1 '''
2 Created on Nov 9, 2016
2 Created on Nov 9, 2016
3
3
4 @author: roj- LouVD
4 @author: roj- LouVD
5 '''
5 '''
6
6
7
7
8 import os
8 import os
9 import sys
9 import sys
10 import time
10 import time
11 import glob
11 import glob
12 import datetime
12 import datetime
13
13
14 import numpy
14 import numpy
15
15
16 import schainpy.admin
16 import schainpy.admin
17 from schainpy.model.proc.jroproc_base import ProcessingUnit, MPDecorator
17 from schainpy.model.proc.jroproc_base import ProcessingUnit, MPDecorator
18 from schainpy.model.data.jrodata import Parameters
18 from schainpy.model.data.jrodata import Parameters
19 from schainpy.model.io.jroIO_base import Reader
19 from schainpy.model.io.jroIO_base import Reader
20 from schainpy.utils import log
20 from schainpy.utils import log
21
21
22 FILE_HEADER_STRUCTURE = numpy.dtype([
22 FILE_HEADER_STRUCTURE = numpy.dtype([
23 ('FMN', '<u4'),
23 ('FMN', '<u4'),
24 ('nrec', '<u4'),
24 ('nrec', '<u4'),
25 ('fr_offset', '<u4'),
25 ('fr_offset', '<u4'),
26 ('id', '<u4'),
26 ('id', '<u4'),
27 ('site', 'u1', (32,))
27 ('site', 'u1', (32,))
28 ])
28 ])
29
29
30 REC_HEADER_STRUCTURE = numpy.dtype([
30 REC_HEADER_STRUCTURE = numpy.dtype([
31 ('rmn', '<u4'),
31 ('rmn', '<u4'),
32 ('rcounter', '<u4'),
32 ('rcounter', '<u4'),
33 ('nr_offset', '<u4'),
33 ('nr_offset', '<u4'),
34 ('tr_offset', '<u4'),
34 ('tr_offset', '<u4'),
35 ('time', '<u4'),
35 ('time', '<u4'),
36 ('time_msec', '<u4'),
36 ('time_msec', '<u4'),
37 ('tag', 'u1', (32,)),
37 ('tag', 'u1', (32,)),
38 ('comments', 'u1', (32,)),
38 ('comments', 'u1', (32,)),
39 ('lat', '<f4'),
39 ('lat', '<f4'),
40 ('lon', '<f4'),
40 ('lon', '<f4'),
41 ('gps_status', '<u4'),
41 ('gps_status', '<u4'),
42 ('freq', '<u4'),
42 ('freq', '<u4'),
43 ('freq0', '<u4'),
43 ('freq0', '<u4'),
44 ('nchan', '<u4'),
44 ('nchan', '<u4'),
45 ('delta_r', '<u4'),
45 ('delta_r', '<u4'),
46 ('nranges', '<u4'),
46 ('nranges', '<u4'),
47 ('r0', '<u4'),
47 ('r0', '<u4'),
48 ('prf', '<u4'),
48 ('prf', '<u4'),
49 ('ncoh', '<u4'),
49 ('ncoh', '<u4'),
50 ('npoints', '<u4'),
50 ('npoints', '<u4'),
51 ('polarization', '<i4'),
51 ('polarization', '<i4'),
52 ('rx_filter', '<u4'),
52 ('rx_filter', '<u4'),
53 ('nmodes', '<u4'),
53 ('nmodes', '<u4'),
54 ('dmode_index', '<u4'),
54 ('dmode_index', '<u4'),
55 ('dmode_rngcorr', '<u4'),
55 ('dmode_rngcorr', '<u4'),
56 ('nrxs', '<u4'),
56 ('nrxs', '<u4'),
57 ('acf_length', '<u4'),
57 ('acf_length', '<u4'),
58 ('acf_lags', '<u4'),
58 ('acf_lags', '<u4'),
59 ('sea_to_atmos', '<f4'),
59 ('sea_to_atmos', '<f4'),
60 ('sea_notch', '<u4'),
60 ('sea_notch', '<u4'),
61 ('lh_sea', '<u4'),
61 ('lh_sea', '<u4'),
62 ('hh_sea', '<u4'),
62 ('hh_sea', '<u4'),
63 ('nbins_sea', '<u4'),
63 ('nbins_sea', '<u4'),
64 ('min_snr', '<f4'),
64 ('min_snr', '<f4'),
65 ('min_cc', '<f4'),
65 ('min_cc', '<f4'),
66 ('max_time_diff', '<f4')
66 ('max_time_diff', '<f4')
67 ])
67 ])
68
68
69 DATA_STRUCTURE = numpy.dtype([
69 DATA_STRUCTURE = numpy.dtype([
70 ('range', '<u4'),
70 ('range', '<u4'),
71 ('status', '<u4'),
71 ('status', '<u4'),
72 ('zonal', '<f4'),
72 ('zonal', '<f4'),
73 ('meridional', '<f4'),
73 ('meridional', '<f4'),
74 ('vertical', '<f4'),
74 ('vertical', '<f4'),
75 ('zonal_a', '<f4'),
75 ('zonal_a', '<f4'),
76 ('meridional_a', '<f4'),
76 ('meridional_a', '<f4'),
77 ('corrected_fading', '<f4'), # seconds
77 ('corrected_fading', '<f4'), # seconds
78 ('uncorrected_fading', '<f4'), # seconds
78 ('uncorrected_fading', '<f4'), # seconds
79 ('time_diff', '<f4'),
79 ('time_diff', '<f4'),
80 ('major_axis', '<f4'),
80 ('major_axis', '<f4'),
81 ('axial_ratio', '<f4'),
81 ('axial_ratio', '<f4'),
82 ('orientation', '<f4'),
82 ('orientation', '<f4'),
83 ('sea_power', '<u4'),
83 ('sea_power', '<u4'),
84 ('sea_algorithm', '<u4')
84 ('sea_algorithm', '<u4')
85 ])
85 ])
86
86
87
87
88 class BLTRParamReader(Reader, ProcessingUnit):
88 class BLTRParamReader(Reader, ProcessingUnit):
89 '''
89 '''
90 Boundary Layer and Tropospheric Radar (BLTR) reader, Wind velocities and SNR
90 Boundary Layer and Tropospheric Radar (BLTR) reader, Wind velocities and SNR
91 from *.sswma files
91 from *.sswma files
92 '''
92 '''
93
93
94 ext = '.sswma'
94 ext = '.sswma'
95
95
96 def __init__(self):
96 def __init__(self):
97
97
98 ProcessingUnit.__init__(self)
98 ProcessingUnit.__init__(self)
99
99
100 self.dataOut = Parameters()
100 self.dataOut = Parameters()
101 self.dataOut.timezone = 300
101 self.dataOut.timezone = 300
102 self.counter_records = 0
102 self.counter_records = 0
103 self.flagNoMoreFiles = 0
103 self.flagNoMoreFiles = 0
104 self.isConfig = False
104 self.isConfig = False
105 self.filename = None
105 self.filename = None
106 self.status_value = 0
106 self.status_value = 0
107 self.datatime = datetime.datetime(1900, 1, 1)
107 self.datatime = datetime.datetime(1900, 1, 1)
108 self.filefmt = "*********%Y%m%d******"
108 self.filefmt = "*********%Y%m%d******"
109
109
110 def setup(self, **kwargs):
110 def setup(self, **kwargs):
111
111
112 self.set_kwargs(**kwargs)
112 self.set_kwargs(**kwargs)
113
113
114 if self.path is None:
114 if self.path is None:
115 raise ValueError("The path is not valid")
115 raise ValueError("The path is not valid")
116
116
117 if self.online:
117 if self.online:
118 log.log("Searching files in online mode...", self.name)
118 log.log("Searching files in online mode...", self.name)
119
119
120 for nTries in range(self.nTries):
120 for nTries in range(self.nTries):
121 fullpath = self.searchFilesOnLine(self.path, self.startDate,
121 fullpath = self.searchFilesOnLine(self.path, self.startDate,
122 self.endDate, self.expLabel, self.ext, self.walk,
122 self.endDate, self.expLabel, self.ext, self.walk,
123 self.filefmt, self.folderfmt)
123 self.filefmt, self.folderfmt)
124 try:
124 try:
125 fullpath = next(fullpath)
125 fullpath = next(fullpath)
126 except:
126 except:
127 fullpath = None
127 fullpath = None
128
128
129 if fullpath:
129 if fullpath:
130 self.fileSize = os.path.getsize(fullpath)
130 self.fileSize = os.path.getsize(fullpath)
131 self.filename = fullpath
131 self.filename = fullpath
132 self.flagIsNewFile = 1
132 self.flagIsNewFile = 1
133 if self.fp != None:
133 if self.fp != None:
134 self.fp.close()
134 self.fp.close()
135 self.fp = self.open_file(fullpath, self.open_mode)
135 self.fp = self.open_file(fullpath, self.open_mode)
136 self.flagNoMoreFiles = 0
136 self.flagNoMoreFiles = 0
137 break
137 break
138
138
139 log.warning(
139 log.warning(
140 'Waiting {} sec for a valid file in {}: try {} ...'.format(
140 'Waiting {} sec for a valid file in {}: try {} ...'.format(
141 self.delay, self.path, nTries + 1),
141 self.delay, self.path, nTries + 1),
142 self.name)
142 self.name)
143 time.sleep(self.delay)
143 time.sleep(self.delay)
144
144
145 if not(fullpath):
145 if not(fullpath):
146 raise schainpy.admin.SchainError(
146 raise schainpy.admin.SchainError(
147 'There isn\'t any valid file in {}'.format(self.path))
147 'There isn\'t any valid file in {}'.format(self.path))
148 self.readFirstHeader()
148 self.readFirstHeader()
149 else:
149 else:
150 log.log("Searching files in {}".format(self.path), self.name)
150 log.log("Searching files in {}".format(self.path), self.name)
151 self.filenameList = self.searchFilesOffLine(self.path, self.startDate,
151 self.filenameList = self.searchFilesOffLine(self.path, self.startDate,
152 self.endDate, self.expLabel, self.ext, self.walk, self.filefmt, self.folderfmt)
152 self.endDate, self.expLabel, self.ext, self.walk, self.filefmt, self.folderfmt)
153 self.setNextFile()
153 self.setNextFile()
154
154
155 def checkForRealPath(self, nextFile, nextDay):
155 def checkForRealPath(self, nextFile, nextDay):
156 '''
156 '''
157 '''
157 '''
158
158
159 dt = self.datatime + datetime.timedelta(1)
159 dt = self.datatime + datetime.timedelta(1)
160 filename = '{}.{}{}'.format(self.siteFile, dt.strftime('%Y%m%d'), self.ext)
160 filename = '{}.{}{}'.format(self.siteFile, dt.strftime('%Y%m%d'), self.ext)
161 fullfilename = os.path.join(self.path, filename)
161 fullfilename = os.path.join(self.path, filename)
162 if os.path.exists(fullfilename):
162 if os.path.exists(fullfilename):
163 return fullfilename, filename
163 return fullfilename, filename
164 return None, filename
164 return None, filename
165
165
166
166
167 def readFirstHeader(self):
167 def readFirstHeader(self):
168 '''
168 '''
169 '''
169 '''
170
170
171 # 'peru2' ---> Piura - 'peru1' ---> Huancayo or Porcuya
171 # 'peru2' ---> Piura - 'peru1' ---> Huancayo or Porcuya
172 self.siteFile = self.filename.split('/')[-1].split('.')[0]
172 self.siteFile = self.filename.split('/')[-1].split('.')[0]
173 self.header_file = numpy.fromfile(self.fp, FILE_HEADER_STRUCTURE, 1)
173 self.header_file = numpy.fromfile(self.fp, FILE_HEADER_STRUCTURE, 1)
174 self.nrecords = self.header_file['nrec'][0]
174 self.nrecords = self.header_file['nrec'][0]
175 self.counter_records = 0
175 self.counter_records = 0
176 self.flagIsNewFile = 0
176 self.flagIsNewFile = 0
177 self.fileIndex += 1
177 self.fileIndex += 1
178
178
179 def readNextBlock(self):
179 def readNextBlock(self):
180
180
181 while True:
181 while True:
182 if not self.online and self.counter_records == self.nrecords:
182 if not self.online and self.counter_records == self.nrecords:
183 self.flagIsNewFile = 1
183 self.flagIsNewFile = 1
184 if not self.setNextFile():
184 if not self.setNextFile():
185 return 0
185 return 0
186 try:
186 try:
187 pointer = self.fp.tell()
187 if self.online and self.counter_records == 0:
188 pos = int(self.fileSize / (38512))
189 self.counter_records = pos*2 - 2
190 pointer = 38512 * (pos-1) + 48
191 self.fp.seek(pointer)
192 else:
193 pointer = self.fp.tell()
188 self.readBlock()
194 self.readBlock()
189 except:
195 except:
190 if self.online and self.waitDataBlock(pointer, 38512) == 1:
196 if self.online and self.waitDataBlock(pointer, 38512) == 1:
191 continue
197 continue
192 else:
198 else:
193 if not self.setNextFile():
199 if not self.setNextFile():
194 return 0
200 return 0
195
201
196 if (self.datatime < datetime.datetime.combine(self.startDate, self.startTime)) or \
202 if (self.datatime < datetime.datetime.combine(self.startDate, self.startTime)) or \
197 (self.datatime > datetime.datetime.combine(self.endDate, self.endTime)):
203 (self.datatime > datetime.datetime.combine(self.endDate, self.endTime)):
198 log.warning(
204 log.warning(
199 'Reading Record No. {}/{} -> {} [Skipping]'.format(
205 'Reading Record No. {}/{} -> {} [Skipping]'.format(
200 self.counter_records,
206 self.counter_records,
201 self.nrecords,
207 self.nrecords,
202 self.datatime.ctime()),
208 self.datatime.ctime()),
203 'BLTRParamReader')
209 'BLTRParamReader')
204 continue
210 continue
205 break
211 break
206
212
207 log.log('Reading Record No. {} -> {}'.format(
213 log.log('Reading Record No. {} -> {}'.format(
208 self.counter_records,
214 self.counter_records,
209 self.datatime.ctime()), 'BLTRParamReader')
215 self.datatime.ctime()), 'BLTRParamReader')
210
216
211 return 1
217 return 1
212
218
213 def readBlock(self):
219 def readBlock(self):
214
220
215 pointer = self.fp.tell()
221 pointer = self.fp.tell()
216 header_rec = numpy.fromfile(self.fp, REC_HEADER_STRUCTURE, 1)
222 header_rec = numpy.fromfile(self.fp, REC_HEADER_STRUCTURE, 1)
217 self.nchannels = int(header_rec['nchan'][0] / 2)
223 self.nchannels = int(header_rec['nchan'][0] / 2)
218 self.kchan = header_rec['nrxs'][0]
224 self.kchan = header_rec['nrxs'][0]
219 self.nmodes = header_rec['nmodes'][0]
225 self.nmodes = header_rec['nmodes'][0]
220 self.nranges = header_rec['nranges'][0]
226 self.nranges = header_rec['nranges'][0]
221 self.fp.seek(pointer)
227 self.fp.seek(pointer)
222 self.height = numpy.empty((self.nmodes, self.nranges))
228 self.height = numpy.empty((self.nmodes, self.nranges))
223 self.snr = numpy.empty((self.nmodes, int(self.nchannels), self.nranges))
229 self.snr = numpy.empty((self.nmodes, int(self.nchannels), self.nranges))
224 self.buffer = numpy.empty((self.nmodes, 3, self.nranges))
230 self.buffer = numpy.empty((self.nmodes, 3, self.nranges))
225 self.flagDiscontinuousBlock = 0
231 self.flagDiscontinuousBlock = 0
226
232
227 for mode in range(self.nmodes):
233 for mode in range(self.nmodes):
228 self.readHeader()
234 self.readHeader()
229 data = self.readData()
235 data = self.readData()
230 self.height[mode] = (data[0] - self.correction) / 1000.
236 self.height[mode] = (data[0] - self.correction) / 1000.
231 self.buffer[mode] = data[1]
237 self.buffer[mode] = data[1]
232 self.snr[mode] = data[2]
238 self.snr[mode] = data[2]
233
239
234 self.counter_records = self.counter_records + self.nmodes
240 self.counter_records = self.counter_records + self.nmodes
235
241
236 return
242 return
237
243
238 def readHeader(self):
244 def readHeader(self):
239 '''
245 '''
240 RecordHeader of BLTR rawdata file
246 RecordHeader of BLTR rawdata file
241 '''
247 '''
242
248
243 header_structure = numpy.dtype(
249 header_structure = numpy.dtype(
244 REC_HEADER_STRUCTURE.descr + [
250 REC_HEADER_STRUCTURE.descr + [
245 ('antenna_coord', 'f4', (2, int(self.nchannels))),
251 ('antenna_coord', 'f4', (2, int(self.nchannels))),
246 ('rx_gains', 'u4', (int(self.nchannels),)),
252 ('rx_gains', 'u4', (int(self.nchannels),)),
247 ('rx_analysis', 'u4', (int(self.nchannels),))
253 ('rx_analysis', 'u4', (int(self.nchannels),))
248 ]
254 ]
249 )
255 )
250
256
251 self.header_rec = numpy.fromfile(self.fp, header_structure, 1)
257 self.header_rec = numpy.fromfile(self.fp, header_structure, 1)
252 self.lat = self.header_rec['lat'][0]
258 self.lat = self.header_rec['lat'][0]
253 self.lon = self.header_rec['lon'][0]
259 self.lon = self.header_rec['lon'][0]
254 self.delta = self.header_rec['delta_r'][0]
260 self.delta = self.header_rec['delta_r'][0]
255 self.correction = self.header_rec['dmode_rngcorr'][0]
261 self.correction = self.header_rec['dmode_rngcorr'][0]
256 self.imode = self.header_rec['dmode_index'][0]
262 self.imode = self.header_rec['dmode_index'][0]
257 self.antenna = self.header_rec['antenna_coord']
263 self.antenna = self.header_rec['antenna_coord']
258 self.rx_gains = self.header_rec['rx_gains']
264 self.rx_gains = self.header_rec['rx_gains']
259 self.time = self.header_rec['time'][0]
265 self.time = self.header_rec['time'][0]
260 dt = datetime.datetime.utcfromtimestamp(self.time)
266 dt = datetime.datetime.utcfromtimestamp(self.time)
261 if dt.date() > self.datatime.date():
267 if dt.date() > self.datatime.date():
262 self.flagDiscontinuousBlock = 1
268 self.flagDiscontinuousBlock = 1
263 self.datatime = dt
269 self.datatime = dt
264
270
265 def readData(self):
271 def readData(self):
266 '''
272 '''
267 Reading and filtering data block record of BLTR rawdata file,
273 Reading and filtering data block record of BLTR rawdata file,
268 filtering is according to status_value.
274 filtering is according to status_value.
269
275
270 Input:
276 Input:
271 status_value - Array data is set to NAN for values that are not
277 status_value - Array data is set to NAN for values that are not
272 equal to status_value
278 equal to status_value
273
279
274 '''
280 '''
275 self.nchannels = int(self.nchannels)
281 self.nchannels = int(self.nchannels)
276
282
277 data_structure = numpy.dtype(
283 data_structure = numpy.dtype(
278 DATA_STRUCTURE.descr + [
284 DATA_STRUCTURE.descr + [
279 ('rx_saturation', 'u4', (self.nchannels,)),
285 ('rx_saturation', 'u4', (self.nchannels,)),
280 ('chan_offset', 'u4', (2 * self.nchannels,)),
286 ('chan_offset', 'u4', (2 * self.nchannels,)),
281 ('rx_amp', 'u4', (self.nchannels,)),
287 ('rx_amp', 'u4', (self.nchannels,)),
282 ('rx_snr', 'f4', (self.nchannels,)),
288 ('rx_snr', 'f4', (self.nchannels,)),
283 ('cross_snr', 'f4', (self.kchan,)),
289 ('cross_snr', 'f4', (self.kchan,)),
284 ('sea_power_relative', 'f4', (self.kchan,))]
290 ('sea_power_relative', 'f4', (self.kchan,))]
285 )
291 )
286
292
287 data = numpy.fromfile(self.fp, data_structure, self.nranges)
293 data = numpy.fromfile(self.fp, data_structure, self.nranges)
288
294
289 height = data['range']
295 height = data['range']
290 winds = numpy.array(
296 winds = numpy.array(
291 (data['zonal'], data['meridional'], data['vertical']))
297 (data['zonal'], data['meridional'], data['vertical']))
292 snr = data['rx_snr'].T
298 snr = data['rx_snr'].T
293
299
294 winds[numpy.where(winds == -9999.)] = numpy.nan
300 winds[numpy.where(winds == -9999.)] = numpy.nan
295 winds[:, numpy.where(data['status'] != self.status_value)] = numpy.nan
301 winds[:, numpy.where(data['status'] != self.status_value)] = numpy.nan
296 snr[numpy.where(snr == -9999.)] = numpy.nan
302 snr[numpy.where(snr == -9999.)] = numpy.nan
297 snr[:, numpy.where(data['status'] != self.status_value)] = numpy.nan
303 snr[:, numpy.where(data['status'] != self.status_value)] = numpy.nan
298 snr = numpy.power(10, snr / 10)
304 snr = numpy.power(10, snr / 10)
299
305
300 return height, winds, snr
306 return height, winds, snr
301
307
302 def set_output(self):
308 def set_output(self):
303 '''
309 '''
304 Storing data from databuffer to dataOut object
310 Storing data from databuffer to dataOut object
305 '''
311 '''
306
312
307 self.dataOut.data_snr = self.snr
313 self.dataOut.data_snr = self.snr
308 self.dataOut.height = self.height
314 self.dataOut.height = self.height
309 self.dataOut.data = self.buffer
315 self.dataOut.data = self.buffer
310 self.dataOut.utctimeInit = self.time
316 self.dataOut.utctimeInit = self.time
311 self.dataOut.utctime = self.dataOut.utctimeInit
317 self.dataOut.utctime = self.dataOut.utctimeInit
312 self.dataOut.useLocalTime = False
318 self.dataOut.useLocalTime = False
313 self.dataOut.paramInterval = 157
319 self.dataOut.paramInterval = 157
314 self.dataOut.site = self.siteFile
320 self.dataOut.site = self.siteFile
315 self.dataOut.nrecords = self.nrecords / self.nmodes
321 self.dataOut.nrecords = self.nrecords / self.nmodes
316 self.dataOut.lat = self.lat
322 self.dataOut.lat = self.lat
317 self.dataOut.lon = self.lon
323 self.dataOut.lon = self.lon
318 self.dataOut.channelList = list(range(self.nchannels))
324 self.dataOut.channelList = list(range(self.nchannels))
319 self.dataOut.kchan = self.kchan
325 self.dataOut.kchan = self.kchan
320 self.dataOut.delta = self.delta
326 self.dataOut.delta = self.delta
321 self.dataOut.correction = self.correction
327 self.dataOut.correction = self.correction
322 self.dataOut.nmodes = self.nmodes
328 self.dataOut.nmodes = self.nmodes
323 self.dataOut.imode = self.imode
329 self.dataOut.imode = self.imode
324 self.dataOut.antenna = self.antenna
330 self.dataOut.antenna = self.antenna
325 self.dataOut.rx_gains = self.rx_gains
331 self.dataOut.rx_gains = self.rx_gains
326 self.dataOut.flagNoData = False
332 self.dataOut.flagNoData = False
327 self.dataOut.flagDiscontinuousBlock = self.flagDiscontinuousBlock
333 self.dataOut.flagDiscontinuousBlock = self.flagDiscontinuousBlock
328
334
329 def getData(self):
335 def getData(self):
330 '''
336 '''
331 Storing data from databuffer to dataOut object
337 Storing data from databuffer to dataOut object
332 '''
338 '''
333 if self.flagNoMoreFiles:
339 if self.flagNoMoreFiles:
334 self.dataOut.flagNoData = True
340 self.dataOut.flagNoData = True
335 return 0
341 return 0
336
342
337 if not self.readNextBlock():
343 if not self.readNextBlock():
338 self.dataOut.flagNoData = True
344 self.dataOut.flagNoData = True
339 return 0
345 return 0
340
346
341 self.set_output()
347 self.set_output()
342
348
343 return 1
349 return 1
344
350
345 def run(self, **kwargs):
351 def run(self, **kwargs):
346 '''
352 '''
347 '''
353 '''
348
354
349 if not(self.isConfig):
355 if not(self.isConfig):
350 self.setup(**kwargs)
356 self.setup(**kwargs)
351 self.isConfig = True
357 self.isConfig = True
352
358
353 self.getData()
359 self.getData()
354
360
355 return
361 return
General Comments 0
You need to be logged in to leave comments. Login now