##// END OF EJS Templates
Bux fixed: El calculo del intervalo del tiempo ahora incluye el numero de puntos de FFT
Miguel Valdez -
r202:a95dc414d095
parent child
Show More
@@ -1,836 +1,836
1 '''
1 '''
2
2
3 $Author: dsuarez $
3 $Author: dsuarez $
4 $Id: Processor.py 1 2012-11-12 18:56:07Z dsuarez $
4 $Id: Processor.py 1 2012-11-12 18:56:07Z dsuarez $
5 '''
5 '''
6 import os
6 import os
7 import numpy
7 import numpy
8 import datetime
8 import datetime
9 import time
9 import time
10
10
11 from jrodata import *
11 from jrodata import *
12 from jrodataIO import *
12 from jrodataIO import *
13 from jroplot import *
13 from jroplot import *
14
14
15 class ProcessingUnit:
15 class ProcessingUnit:
16
16
17 """
17 """
18 Esta es la clase base para el procesamiento de datos.
18 Esta es la clase base para el procesamiento de datos.
19
19
20 Contiene el metodo "call" para llamar operaciones. Las operaciones pueden ser:
20 Contiene el metodo "call" para llamar operaciones. Las operaciones pueden ser:
21 - Metodos internos (callMethod)
21 - Metodos internos (callMethod)
22 - Objetos del tipo Operation (callObject). Antes de ser llamados, estos objetos
22 - Objetos del tipo Operation (callObject). Antes de ser llamados, estos objetos
23 tienen que ser agreagados con el metodo "add".
23 tienen que ser agreagados con el metodo "add".
24
24
25 """
25 """
26 # objeto de datos de entrada (Voltage, Spectra o Correlation)
26 # objeto de datos de entrada (Voltage, Spectra o Correlation)
27 dataIn = None
27 dataIn = None
28
28
29 # objeto de datos de entrada (Voltage, Spectra o Correlation)
29 # objeto de datos de entrada (Voltage, Spectra o Correlation)
30 dataOut = None
30 dataOut = None
31
31
32
32
33 objectDict = None
33 objectDict = None
34
34
35 def __init__(self):
35 def __init__(self):
36
36
37 self.objectDict = {}
37 self.objectDict = {}
38
38
39 def init(self):
39 def init(self):
40
40
41 raise ValueError, "Not implemented"
41 raise ValueError, "Not implemented"
42
42
43 def addOperation(self, object, objId):
43 def addOperation(self, object, objId):
44
44
45 """
45 """
46 Agrega el objeto "object" a la lista de objetos "self.objectList" y retorna el
46 Agrega el objeto "object" a la lista de objetos "self.objectList" y retorna el
47 identificador asociado a este objeto.
47 identificador asociado a este objeto.
48
48
49 Input:
49 Input:
50
50
51 object : objeto de la clase "Operation"
51 object : objeto de la clase "Operation"
52
52
53 Return:
53 Return:
54
54
55 objId : identificador del objeto, necesario para ejecutar la operacion
55 objId : identificador del objeto, necesario para ejecutar la operacion
56 """
56 """
57
57
58 self.objectDict[objId] = object
58 self.objectDict[objId] = object
59
59
60 return objId
60 return objId
61
61
62 def operation(self, **kwargs):
62 def operation(self, **kwargs):
63
63
64 """
64 """
65 Operacion directa sobre la data (dataout.data). Es necesario actualizar los valores de los
65 Operacion directa sobre la data (dataout.data). Es necesario actualizar los valores de los
66 atributos del objeto dataOut
66 atributos del objeto dataOut
67
67
68 Input:
68 Input:
69
69
70 **kwargs : Diccionario de argumentos de la funcion a ejecutar
70 **kwargs : Diccionario de argumentos de la funcion a ejecutar
71 """
71 """
72
72
73 raise ValueError, "ImplementedError"
73 raise ValueError, "ImplementedError"
74
74
75 def callMethod(self, name, **kwargs):
75 def callMethod(self, name, **kwargs):
76
76
77 """
77 """
78 Ejecuta el metodo con el nombre "name" y con argumentos **kwargs de la propia clase.
78 Ejecuta el metodo con el nombre "name" y con argumentos **kwargs de la propia clase.
79
79
80 Input:
80 Input:
81 name : nombre del metodo a ejecutar
81 name : nombre del metodo a ejecutar
82
82
83 **kwargs : diccionario con los nombres y valores de la funcion a ejecutar.
83 **kwargs : diccionario con los nombres y valores de la funcion a ejecutar.
84
84
85 """
85 """
86 if name != 'run':
86 if name != 'run':
87
87
88 if name == 'init' and self.dataIn.isEmpty():
88 if name == 'init' and self.dataIn.isEmpty():
89 self.dataOut.flagNoData = True
89 self.dataOut.flagNoData = True
90 return False
90 return False
91
91
92 if name != 'init' and self.dataOut.isEmpty():
92 if name != 'init' and self.dataOut.isEmpty():
93 return False
93 return False
94
94
95 methodToCall = getattr(self, name)
95 methodToCall = getattr(self, name)
96
96
97 methodToCall(**kwargs)
97 methodToCall(**kwargs)
98
98
99 if name != 'run':
99 if name != 'run':
100 return True
100 return True
101
101
102 if self.dataOut.isEmpty():
102 if self.dataOut.isEmpty():
103 return False
103 return False
104
104
105 return True
105 return True
106
106
107 def callObject(self, objId, **kwargs):
107 def callObject(self, objId, **kwargs):
108
108
109 """
109 """
110 Ejecuta la operacion asociada al identificador del objeto "objId"
110 Ejecuta la operacion asociada al identificador del objeto "objId"
111
111
112 Input:
112 Input:
113
113
114 objId : identificador del objeto a ejecutar
114 objId : identificador del objeto a ejecutar
115
115
116 **kwargs : diccionario con los nombres y valores de la funcion a ejecutar.
116 **kwargs : diccionario con los nombres y valores de la funcion a ejecutar.
117
117
118 Return:
118 Return:
119
119
120 None
120 None
121 """
121 """
122
122
123 if self.dataOut.isEmpty():
123 if self.dataOut.isEmpty():
124 return False
124 return False
125
125
126 object = self.objectDict[objId]
126 object = self.objectDict[objId]
127
127
128 object.run(self.dataOut, **kwargs)
128 object.run(self.dataOut, **kwargs)
129
129
130 return True
130 return True
131
131
132 def call(self, operationConf, **kwargs):
132 def call(self, operationConf, **kwargs):
133
133
134 """
134 """
135 Return True si ejecuta la operacion "operationConf.name" con los
135 Return True si ejecuta la operacion "operationConf.name" con los
136 argumentos "**kwargs". False si la operacion no se ha ejecutado.
136 argumentos "**kwargs". False si la operacion no se ha ejecutado.
137 La operacion puede ser de dos tipos:
137 La operacion puede ser de dos tipos:
138
138
139 1. Un metodo propio de esta clase:
139 1. Un metodo propio de esta clase:
140
140
141 operation.type = "self"
141 operation.type = "self"
142
142
143 2. El metodo "run" de un objeto del tipo Operation o de un derivado de ella:
143 2. El metodo "run" de un objeto del tipo Operation o de un derivado de ella:
144 operation.type = "other".
144 operation.type = "other".
145
145
146 Este objeto de tipo Operation debe de haber sido agregado antes con el metodo:
146 Este objeto de tipo Operation debe de haber sido agregado antes con el metodo:
147 "addOperation" e identificado con el operation.id
147 "addOperation" e identificado con el operation.id
148
148
149
149
150 con el id de la operacion.
150 con el id de la operacion.
151
151
152 Input:
152 Input:
153
153
154 Operation : Objeto del tipo operacion con los atributos: name, type y id.
154 Operation : Objeto del tipo operacion con los atributos: name, type y id.
155
155
156 """
156 """
157
157
158 if operationConf.type == 'self':
158 if operationConf.type == 'self':
159 sts = self.callMethod(operationConf.name, **kwargs)
159 sts = self.callMethod(operationConf.name, **kwargs)
160
160
161 if operationConf.type == 'other':
161 if operationConf.type == 'other':
162 sts = self.callObject(operationConf.id, **kwargs)
162 sts = self.callObject(operationConf.id, **kwargs)
163
163
164 return sts
164 return sts
165
165
166 def setInput(self, dataIn):
166 def setInput(self, dataIn):
167
167
168 self.dataIn = dataIn
168 self.dataIn = dataIn
169
169
170 def getOutput(self):
170 def getOutput(self):
171
171
172 return self.dataOut
172 return self.dataOut
173
173
174 class Operation():
174 class Operation():
175
175
176 """
176 """
177 Clase base para definir las operaciones adicionales que se pueden agregar a la clase ProcessingUnit
177 Clase base para definir las operaciones adicionales que se pueden agregar a la clase ProcessingUnit
178 y necesiten acumular informacion previa de los datos a procesar. De preferencia usar un buffer de
178 y necesiten acumular informacion previa de los datos a procesar. De preferencia usar un buffer de
179 acumulacion dentro de esta clase
179 acumulacion dentro de esta clase
180
180
181 Ejemplo: Integraciones coherentes, necesita la informacion previa de los n perfiles anteriores (bufffer)
181 Ejemplo: Integraciones coherentes, necesita la informacion previa de los n perfiles anteriores (bufffer)
182
182
183 """
183 """
184
184
185 __buffer = None
185 __buffer = None
186 __isConfig = False
186 __isConfig = False
187
187
188 def __init__(self):
188 def __init__(self):
189
189
190 pass
190 pass
191
191
192 def run(self, dataIn, **kwargs):
192 def run(self, dataIn, **kwargs):
193
193
194 """
194 """
195 Realiza las operaciones necesarias sobre la dataIn.data y actualiza los atributos del objeto dataIn.
195 Realiza las operaciones necesarias sobre la dataIn.data y actualiza los atributos del objeto dataIn.
196
196
197 Input:
197 Input:
198
198
199 dataIn : objeto del tipo JROData
199 dataIn : objeto del tipo JROData
200
200
201 Return:
201 Return:
202
202
203 None
203 None
204
204
205 Affected:
205 Affected:
206 __buffer : buffer de recepcion de datos.
206 __buffer : buffer de recepcion de datos.
207
207
208 """
208 """
209
209
210 raise ValueError, "ImplementedError"
210 raise ValueError, "ImplementedError"
211
211
212 class VoltageProc(ProcessingUnit):
212 class VoltageProc(ProcessingUnit):
213
213
214
214
215 def __init__(self):
215 def __init__(self):
216
216
217 self.objectDict = {}
217 self.objectDict = {}
218 self.dataOut = Voltage()
218 self.dataOut = Voltage()
219
219
220 def init(self):
220 def init(self):
221
221
222 self.dataOut.copy(self.dataIn)
222 self.dataOut.copy(self.dataIn)
223 # No necesita copiar en cada init() los atributos de dataIn
223 # No necesita copiar en cada init() los atributos de dataIn
224 # la copia deberia hacerse por cada nuevo bloque de datos
224 # la copia deberia hacerse por cada nuevo bloque de datos
225
225
226 def selectChannels(self, channelList):
226 def selectChannels(self, channelList):
227
227
228 channelIndexList = []
228 channelIndexList = []
229
229
230 for channel in channelList:
230 for channel in channelList:
231 index = self.dataOut.channelList.index(channel)
231 index = self.dataOut.channelList.index(channel)
232 channelIndexList.append(index)
232 channelIndexList.append(index)
233
233
234 self.selectChannelsByIndex(channelIndexList)
234 self.selectChannelsByIndex(channelIndexList)
235
235
236 def selectChannelsByIndex(self, channelIndexList):
236 def selectChannelsByIndex(self, channelIndexList):
237 """
237 """
238 Selecciona un bloque de datos en base a canales segun el channelIndexList
238 Selecciona un bloque de datos en base a canales segun el channelIndexList
239
239
240 Input:
240 Input:
241 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
241 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
242
242
243 Affected:
243 Affected:
244 self.dataOut.data
244 self.dataOut.data
245 self.dataOut.channelIndexList
245 self.dataOut.channelIndexList
246 self.dataOut.nChannels
246 self.dataOut.nChannels
247 self.dataOut.m_ProcessingHeader.totalSpectra
247 self.dataOut.m_ProcessingHeader.totalSpectra
248 self.dataOut.systemHeaderObj.numChannels
248 self.dataOut.systemHeaderObj.numChannels
249 self.dataOut.m_ProcessingHeader.blockSize
249 self.dataOut.m_ProcessingHeader.blockSize
250
250
251 Return:
251 Return:
252 None
252 None
253 """
253 """
254
254
255 for channelIndex in channelIndexList:
255 for channelIndex in channelIndexList:
256 if channelIndex not in self.dataOut.channelIndexList:
256 if channelIndex not in self.dataOut.channelIndexList:
257 print channelIndexList
257 print channelIndexList
258 raise ValueError, "The value %d in channelIndexList is not valid" %channelIndex
258 raise ValueError, "The value %d in channelIndexList is not valid" %channelIndex
259
259
260 nChannels = len(channelIndexList)
260 nChannels = len(channelIndexList)
261
261
262 data = self.dataOut.data[channelIndexList,:]
262 data = self.dataOut.data[channelIndexList,:]
263
263
264 self.dataOut.data = data
264 self.dataOut.data = data
265 self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
265 self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
266 # self.dataOut.nChannels = nChannels
266 # self.dataOut.nChannels = nChannels
267
267
268 return 1
268 return 1
269
269
270 class CohInt(Operation):
270 class CohInt(Operation):
271
271
272 __profIndex = 0
272 __profIndex = 0
273 __withOverapping = False
273 __withOverapping = False
274
274
275 __byTime = False
275 __byTime = False
276 __initime = None
276 __initime = None
277 __lastdatatime = None
277 __lastdatatime = None
278 __integrationtime = None
278 __integrationtime = None
279
279
280 __buffer = None
280 __buffer = None
281
281
282 __dataReady = False
282 __dataReady = False
283
283
284 n = None
284 n = None
285
285
286
286
287 def __init__(self):
287 def __init__(self):
288
288
289 self.__isConfig = False
289 self.__isConfig = False
290
290
291 def setup(self, n=None, timeInterval=None, overlapping=False):
291 def setup(self, n=None, timeInterval=None, overlapping=False):
292 """
292 """
293 Set the parameters of the integration class.
293 Set the parameters of the integration class.
294
294
295 Inputs:
295 Inputs:
296
296
297 n : Number of coherent integrations
297 n : Number of coherent integrations
298 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
298 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
299 overlapping :
299 overlapping :
300
300
301 """
301 """
302
302
303 self.__initime = None
303 self.__initime = None
304 self.__lastdatatime = 0
304 self.__lastdatatime = 0
305 self.__buffer = None
305 self.__buffer = None
306 self.__dataReady = False
306 self.__dataReady = False
307
307
308
308
309 if n == None and timeInterval == None:
309 if n == None and timeInterval == None:
310 raise ValueError, "n or timeInterval should be specified ..."
310 raise ValueError, "n or timeInterval should be specified ..."
311
311
312 if n != None:
312 if n != None:
313 self.n = n
313 self.n = n
314 self.__byTime = False
314 self.__byTime = False
315 else:
315 else:
316 self.__integrationtime = timeInterval * 60. #if (type(timeInterval)!=integer) -> change this line
316 self.__integrationtime = timeInterval * 60. #if (type(timeInterval)!=integer) -> change this line
317 self.n = 9999
317 self.n = 9999
318 self.__byTime = True
318 self.__byTime = True
319
319
320 if overlapping:
320 if overlapping:
321 self.__withOverapping = True
321 self.__withOverapping = True
322 self.__buffer = None
322 self.__buffer = None
323 else:
323 else:
324 self.__withOverapping = False
324 self.__withOverapping = False
325 self.__buffer = 0
325 self.__buffer = 0
326
326
327 self.__profIndex = 0
327 self.__profIndex = 0
328
328
329 def putData(self, data):
329 def putData(self, data):
330
330
331 """
331 """
332 Add a profile to the __buffer and increase in one the __profileIndex
332 Add a profile to the __buffer and increase in one the __profileIndex
333
333
334 """
334 """
335
335
336 if not self.__withOverapping:
336 if not self.__withOverapping:
337 self.__buffer += data.copy()
337 self.__buffer += data.copy()
338 self.__profIndex += 1
338 self.__profIndex += 1
339 return
339 return
340
340
341 #Overlapping data
341 #Overlapping data
342 nChannels, nHeis = data.shape
342 nChannels, nHeis = data.shape
343 data = numpy.reshape(data, (1, nChannels, nHeis))
343 data = numpy.reshape(data, (1, nChannels, nHeis))
344
344
345 #If the buffer is empty then it takes the data value
345 #If the buffer is empty then it takes the data value
346 if self.__buffer == None:
346 if self.__buffer == None:
347 self.__buffer = data
347 self.__buffer = data
348 self.__profIndex += 1
348 self.__profIndex += 1
349 return
349 return
350
350
351 #If the buffer length is lower than n then stakcing the data value
351 #If the buffer length is lower than n then stakcing the data value
352 if self.__profIndex < self.n:
352 if self.__profIndex < self.n:
353 self.__buffer = numpy.vstack((self.__buffer, data))
353 self.__buffer = numpy.vstack((self.__buffer, data))
354 self.__profIndex += 1
354 self.__profIndex += 1
355 return
355 return
356
356
357 #If the buffer length is equal to n then replacing the last buffer value with the data value
357 #If the buffer length is equal to n then replacing the last buffer value with the data value
358 self.__buffer = numpy.roll(self.__buffer, -1, axis=0)
358 self.__buffer = numpy.roll(self.__buffer, -1, axis=0)
359 self.__buffer[self.n-1] = data
359 self.__buffer[self.n-1] = data
360 self.__profIndex = self.n
360 self.__profIndex = self.n
361 return
361 return
362
362
363
363
364 def pushData(self):
364 def pushData(self):
365 """
365 """
366 Return the sum of the last profiles and the profiles used in the sum.
366 Return the sum of the last profiles and the profiles used in the sum.
367
367
368 Affected:
368 Affected:
369
369
370 self.__profileIndex
370 self.__profileIndex
371
371
372 """
372 """
373
373
374 if not self.__withOverapping:
374 if not self.__withOverapping:
375 data = self.__buffer
375 data = self.__buffer
376 n = self.__profIndex
376 n = self.__profIndex
377
377
378 self.__buffer = 0
378 self.__buffer = 0
379 self.__profIndex = 0
379 self.__profIndex = 0
380
380
381 return data, n
381 return data, n
382
382
383 #Integration with Overlapping
383 #Integration with Overlapping
384 data = numpy.sum(self.__buffer, axis=0)
384 data = numpy.sum(self.__buffer, axis=0)
385 n = self.__profIndex
385 n = self.__profIndex
386
386
387 return data, n
387 return data, n
388
388
389 def byProfiles(self, data):
389 def byProfiles(self, data):
390
390
391 self.__dataReady = False
391 self.__dataReady = False
392 avgdata = None
392 avgdata = None
393 n = None
393 n = None
394
394
395 self.putData(data)
395 self.putData(data)
396
396
397 if self.__profIndex == self.n:
397 if self.__profIndex == self.n:
398
398
399 avgdata, n = self.pushData()
399 avgdata, n = self.pushData()
400 self.__dataReady = True
400 self.__dataReady = True
401
401
402 return avgdata
402 return avgdata
403
403
404 def byTime(self, data, datatime):
404 def byTime(self, data, datatime):
405
405
406 self.__dataReady = False
406 self.__dataReady = False
407 avgdata = None
407 avgdata = None
408 n = None
408 n = None
409
409
410 self.putData(data)
410 self.putData(data)
411
411
412 if (datatime - self.__initime) >= self.__integrationtime:
412 if (datatime - self.__initime) >= self.__integrationtime:
413 avgdata, n = self.pushData()
413 avgdata, n = self.pushData()
414 self.n = n
414 self.n = n
415 self.__dataReady = True
415 self.__dataReady = True
416
416
417 return avgdata
417 return avgdata
418
418
419 def integrate(self, data, datatime=None):
419 def integrate(self, data, datatime=None):
420
420
421 if self.__initime == None:
421 if self.__initime == None:
422 self.__initime = datatime
422 self.__initime = datatime
423
423
424 if self.__byTime:
424 if self.__byTime:
425 avgdata = self.byTime(data, datatime)
425 avgdata = self.byTime(data, datatime)
426 else:
426 else:
427 avgdata = self.byProfiles(data)
427 avgdata = self.byProfiles(data)
428
428
429
429
430 self.__lastdatatime = datatime
430 self.__lastdatatime = datatime
431
431
432 if avgdata == None:
432 if avgdata == None:
433 return None, None
433 return None, None
434
434
435 avgdatatime = self.__initime
435 avgdatatime = self.__initime
436
436
437 deltatime = datatime -self.__lastdatatime
437 deltatime = datatime -self.__lastdatatime
438
438
439 if not self.__withOverapping:
439 if not self.__withOverapping:
440 self.__initime = datatime
440 self.__initime = datatime
441 else:
441 else:
442 self.__initime += deltatime
442 self.__initime += deltatime
443
443
444 return avgdata, avgdatatime
444 return avgdata, avgdatatime
445
445
446 def run(self, dataOut, n=None, timeInterval=None, overlapping=False):
446 def run(self, dataOut, n=None, timeInterval=None, overlapping=False):
447
447
448 if not self.__isConfig:
448 if not self.__isConfig:
449 self.setup(n, timeInterval, overlapping)
449 self.setup(n, timeInterval, overlapping)
450 self.__isConfig = True
450 self.__isConfig = True
451
451
452 avgdata, avgdatatime = self.integrate(dataOut.data, dataOut.utctime)
452 avgdata, avgdatatime = self.integrate(dataOut.data, dataOut.utctime)
453
453
454 # dataOut.timeInterval *= n
454 # dataOut.timeInterval *= n
455 dataOut.flagNoData = True
455 dataOut.flagNoData = True
456
456
457 if self.__dataReady:
457 if self.__dataReady:
458 dataOut.data = avgdata
458 dataOut.data = avgdata
459 dataOut.nCohInt *= self.n
459 dataOut.nCohInt *= self.n
460 dataOut.utctime = avgdatatime
460 dataOut.utctime = avgdatatime
461 dataOut.timeInterval = dataOut.ippSeconds * dataOut.nCohInt
461 dataOut.timeInterval = dataOut.ippSeconds * dataOut.nCohInt
462 dataOut.flagNoData = False
462 dataOut.flagNoData = False
463
463
464
464
465 class SpectraProc(ProcessingUnit):
465 class SpectraProc(ProcessingUnit):
466
466
467 def __init__(self):
467 def __init__(self):
468
468
469 self.objectDict = {}
469 self.objectDict = {}
470 self.buffer = None
470 self.buffer = None
471 self.firstdatatime = None
471 self.firstdatatime = None
472 self.profIndex = 0
472 self.profIndex = 0
473 self.dataOut = Spectra()
473 self.dataOut = Spectra()
474
474
475 def __updateObjFromInput(self):
475 def __updateObjFromInput(self):
476
476
477 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
477 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
478 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
478 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
479 self.dataOut.channelList = self.dataIn.channelList
479 self.dataOut.channelList = self.dataIn.channelList
480 self.dataOut.heightList = self.dataIn.heightList
480 self.dataOut.heightList = self.dataIn.heightList
481 self.dataOut.dtype = self.dataIn.dtype
481 self.dataOut.dtype = self.dataIn.dtype
482 self.dataOut.nHeights = self.dataIn.nHeights
482 self.dataOut.nHeights = self.dataIn.nHeights
483 # self.dataOut.nChannels = self.dataIn.nChannels
483 # self.dataOut.nChannels = self.dataIn.nChannels
484 self.dataOut.nBaud = self.dataIn.nBaud
484 self.dataOut.nBaud = self.dataIn.nBaud
485 self.dataOut.nCode = self.dataIn.nCode
485 self.dataOut.nCode = self.dataIn.nCode
486 self.dataOut.code = self.dataIn.code
486 self.dataOut.code = self.dataIn.code
487 self.dataOut.nProfiles = self.dataOut.nFFTPoints
487 self.dataOut.nProfiles = self.dataOut.nFFTPoints
488 # self.dataOut.channelIndexList = self.dataIn.channelIndexList
488 # self.dataOut.channelIndexList = self.dataIn.channelIndexList
489 self.dataOut.flagTimeBlock = self.dataIn.flagTimeBlock
489 self.dataOut.flagTimeBlock = self.dataIn.flagTimeBlock
490 self.dataOut.utctime = self.firstdatatime
490 self.dataOut.utctime = self.firstdatatime
491 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData #asumo q la data esta decodificada
491 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData #asumo q la data esta decodificada
492 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData #asumo q la data esta sin flip
492 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData #asumo q la data esta sin flip
493 self.dataOut.flagShiftFFT = self.dataIn.flagShiftFFT
493 self.dataOut.flagShiftFFT = self.dataIn.flagShiftFFT
494 self.dataOut.nCohInt = self.dataIn.nCohInt
494 self.dataOut.nCohInt = self.dataIn.nCohInt
495 self.dataOut.nIncohInt = 1
495 self.dataOut.nIncohInt = 1
496 self.dataOut.ippSeconds = self.dataIn.ippSeconds
496 self.dataOut.ippSeconds = self.dataIn.ippSeconds
497 self.dataOut.timeInterval = self.dataIn.timeInterval*self.dataOut.nFFTPoints
497 self.dataOut.timeInterval = self.dataIn.timeInterval*self.dataOut.nFFTPoints
498
498
499 def __getFft(self):
499 def __getFft(self):
500 """
500 """
501 Convierte valores de Voltaje a Spectra
501 Convierte valores de Voltaje a Spectra
502
502
503 Affected:
503 Affected:
504 self.dataOut.data_spc
504 self.dataOut.data_spc
505 self.dataOut.data_cspc
505 self.dataOut.data_cspc
506 self.dataOut.data_dc
506 self.dataOut.data_dc
507 self.dataOut.heightList
507 self.dataOut.heightList
508 self.dataOut.m_BasicHeader
508 self.dataOut.m_BasicHeader
509 self.dataOut.m_ProcessingHeader
509 self.dataOut.m_ProcessingHeader
510 self.dataOut.radarControllerHeaderObj
510 self.dataOut.radarControllerHeaderObj
511 self.dataOut.systemHeaderObj
511 self.dataOut.systemHeaderObj
512 self.profIndex
512 self.profIndex
513 self.buffer
513 self.buffer
514 self.dataOut.flagNoData
514 self.dataOut.flagNoData
515 self.dataOut.dtype
515 self.dataOut.dtype
516 self.dataOut.nPairs
516 self.dataOut.nPairs
517 self.dataOut.nChannels
517 self.dataOut.nChannels
518 self.dataOut.nProfiles
518 self.dataOut.nProfiles
519 self.dataOut.systemHeaderObj.numChannels
519 self.dataOut.systemHeaderObj.numChannels
520 self.dataOut.m_ProcessingHeader.totalSpectra
520 self.dataOut.m_ProcessingHeader.totalSpectra
521 self.dataOut.m_ProcessingHeader.profilesPerBlock
521 self.dataOut.m_ProcessingHeader.profilesPerBlock
522 self.dataOut.m_ProcessingHeader.numHeights
522 self.dataOut.m_ProcessingHeader.numHeights
523 self.dataOut.m_ProcessingHeader.spectraComb
523 self.dataOut.m_ProcessingHeader.spectraComb
524 self.dataOut.m_ProcessingHeader.shif_fft
524 self.dataOut.m_ProcessingHeader.shif_fft
525 """
525 """
526 fft_volt = numpy.fft.fft(self.buffer,axis=1)
526 fft_volt = numpy.fft.fft(self.buffer,axis=1)
527 dc = fft_volt[:,0,:]
527 dc = fft_volt[:,0,:]
528
528
529 #calculo de self-spectra
529 #calculo de self-spectra
530 fft_volt = numpy.fft.fftshift(fft_volt,axes=(1,))
530 fft_volt = numpy.fft.fftshift(fft_volt,axes=(1,))
531 spc = fft_volt * numpy.conjugate(fft_volt)
531 spc = fft_volt * numpy.conjugate(fft_volt)
532 spc = spc.real
532 spc = spc.real
533
533
534 blocksize = 0
534 blocksize = 0
535 blocksize += dc.size
535 blocksize += dc.size
536 blocksize += spc.size
536 blocksize += spc.size
537
537
538 cspc = None
538 cspc = None
539 pairIndex = 0
539 pairIndex = 0
540 if self.dataOut.pairsList != None:
540 if self.dataOut.pairsList != None:
541 #calculo de cross-spectra
541 #calculo de cross-spectra
542 cspc = numpy.zeros((self.dataOut.nPairs, self.dataOut.nFFTPoints, self.dataOut.nHeights), dtype='complex')
542 cspc = numpy.zeros((self.dataOut.nPairs, self.dataOut.nFFTPoints, self.dataOut.nHeights), dtype='complex')
543 for pair in self.dataOut.pairsList:
543 for pair in self.dataOut.pairsList:
544 cspc[pairIndex,:,:] = numpy.abs(fft_volt[pair[0],:,:] * numpy.conjugate(fft_volt[pair[1],:,:]))
544 cspc[pairIndex,:,:] = numpy.abs(fft_volt[pair[0],:,:] * numpy.conjugate(fft_volt[pair[1],:,:]))
545 pairIndex += 1
545 pairIndex += 1
546 blocksize += cspc.size
546 blocksize += cspc.size
547
547
548 self.dataOut.data_spc = spc
548 self.dataOut.data_spc = spc
549 self.dataOut.data_cspc = cspc
549 self.dataOut.data_cspc = cspc
550 self.dataOut.data_dc = dc
550 self.dataOut.data_dc = dc
551 self.dataOut.blockSize = blocksize
551 self.dataOut.blockSize = blocksize
552
552
553 def init(self, nFFTPoints=None, pairsList=None):
553 def init(self, nFFTPoints=None, pairsList=None):
554
554
555 if self.dataIn.type == "Spectra":
555 if self.dataIn.type == "Spectra":
556 self.dataOut.copy(self.dataIn)
556 self.dataOut.copy(self.dataIn)
557 return
557 return
558
558
559 if self.dataIn.type == "Voltage":
559 if self.dataIn.type == "Voltage":
560
560
561 if nFFTPoints == None:
561 if nFFTPoints == None:
562 raise ValueError, "This SpectraProc.setup() need nFFTPoints input variable"
562 raise ValueError, "This SpectraProc.setup() need nFFTPoints input variable"
563
563
564 if pairsList == None:
564 if pairsList == None:
565 nPairs = 0
565 nPairs = 0
566 else:
566 else:
567 nPairs = len(pairsList)
567 nPairs = len(pairsList)
568
568
569 self.dataOut.nFFTPoints = nFFTPoints
569 self.dataOut.nFFTPoints = nFFTPoints
570 self.dataOut.pairsList = pairsList
570 self.dataOut.pairsList = pairsList
571 self.dataOut.nPairs = nPairs
571 self.dataOut.nPairs = nPairs
572
572
573 if self.buffer == None:
573 if self.buffer == None:
574 self.buffer = numpy.zeros((self.dataIn.nChannels,
574 self.buffer = numpy.zeros((self.dataIn.nChannels,
575 self.dataOut.nFFTPoints,
575 self.dataOut.nFFTPoints,
576 self.dataIn.nHeights),
576 self.dataIn.nHeights),
577 dtype='complex')
577 dtype='complex')
578
578
579
579
580 self.buffer[:,self.profIndex,:] = self.dataIn.data
580 self.buffer[:,self.profIndex,:] = self.dataIn.data
581 self.profIndex += 1
581 self.profIndex += 1
582
582
583 if self.firstdatatime == None:
583 if self.firstdatatime == None:
584 self.firstdatatime = self.dataIn.utctime
584 self.firstdatatime = self.dataIn.utctime
585
585
586 if self.profIndex == self.dataOut.nFFTPoints:
586 if self.profIndex == self.dataOut.nFFTPoints:
587 self.__updateObjFromInput()
587 self.__updateObjFromInput()
588 self.__getFft()
588 self.__getFft()
589
589
590 self.dataOut.flagNoData = False
590 self.dataOut.flagNoData = False
591
591
592 self.buffer = None
592 self.buffer = None
593 self.firstdatatime = None
593 self.firstdatatime = None
594 self.profIndex = 0
594 self.profIndex = 0
595
595
596 return
596 return
597
597
598 raise ValuError, "The type object %s is not valid"%(self.dataIn.type)
598 raise ValuError, "The type object %s is not valid"%(self.dataIn.type)
599
599
600 def selectChannels(self, channelList):
600 def selectChannels(self, channelList):
601
601
602 channelIndexList = []
602 channelIndexList = []
603
603
604 for channel in channelList:
604 for channel in channelList:
605 index = self.dataOut.channelList.index(channel)
605 index = self.dataOut.channelList.index(channel)
606 channelIndexList.append(index)
606 channelIndexList.append(index)
607
607
608 self.selectChannelsByIndex(channelIndexList)
608 self.selectChannelsByIndex(channelIndexList)
609
609
610 def selectChannelsByIndex(self, channelIndexList):
610 def selectChannelsByIndex(self, channelIndexList):
611 """
611 """
612 Selecciona un bloque de datos en base a canales segun el channelIndexList
612 Selecciona un bloque de datos en base a canales segun el channelIndexList
613
613
614 Input:
614 Input:
615 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
615 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
616
616
617 Affected:
617 Affected:
618 self.dataOut.data_spc
618 self.dataOut.data_spc
619 self.dataOut.channelIndexList
619 self.dataOut.channelIndexList
620 self.dataOut.nChannels
620 self.dataOut.nChannels
621
621
622 Return:
622 Return:
623 None
623 None
624 """
624 """
625
625
626 for channelIndex in channelIndexList:
626 for channelIndex in channelIndexList:
627 if channelIndex not in self.dataOut.channelIndexList:
627 if channelIndex not in self.dataOut.channelIndexList:
628 print channelIndexList
628 print channelIndexList
629 raise ValueError, "The value %d in channelIndexList is not valid" %channelIndex
629 raise ValueError, "The value %d in channelIndexList is not valid" %channelIndex
630
630
631 nChannels = len(channelIndexList)
631 nChannels = len(channelIndexList)
632
632
633 data_spc = self.dataOut.data_spc[channelIndexList,:]
633 data_spc = self.dataOut.data_spc[channelIndexList,:]
634
634
635 self.dataOut.data_spc = data_spc
635 self.dataOut.data_spc = data_spc
636 self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
636 self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
637 # self.dataOut.nChannels = nChannels
637 # self.dataOut.nChannels = nChannels
638
638
639 return 1
639 return 1
640
640
641
641
642 class IncohInt(Operation):
642 class IncohInt(Operation):
643
643
644
644
645 __profIndex = 0
645 __profIndex = 0
646 __withOverapping = False
646 __withOverapping = False
647
647
648 __byTime = False
648 __byTime = False
649 __initime = None
649 __initime = None
650 __lastdatatime = None
650 __lastdatatime = None
651 __integrationtime = None
651 __integrationtime = None
652
652
653 __buffer = None
653 __buffer = None
654
654
655 __dataReady = False
655 __dataReady = False
656
656
657 n = None
657 n = None
658
658
659
659
660 def __init__(self):
660 def __init__(self):
661
661
662 self.__isConfig = False
662 self.__isConfig = False
663
663
664 def setup(self, n=None, timeInterval=None, overlapping=False):
664 def setup(self, n=None, timeInterval=None, overlapping=False):
665 """
665 """
666 Set the parameters of the integration class.
666 Set the parameters of the integration class.
667
667
668 Inputs:
668 Inputs:
669
669
670 n : Number of coherent integrations
670 n : Number of coherent integrations
671 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
671 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
672 overlapping :
672 overlapping :
673
673
674 """
674 """
675
675
676 self.__initime = None
676 self.__initime = None
677 self.__lastdatatime = 0
677 self.__lastdatatime = 0
678 self.__buffer = None
678 self.__buffer = None
679 self.__dataReady = False
679 self.__dataReady = False
680
680
681
681
682 if n == None and timeInterval == None:
682 if n == None and timeInterval == None:
683 raise ValueError, "n or timeInterval should be specified ..."
683 raise ValueError, "n or timeInterval should be specified ..."
684
684
685 if n != None:
685 if n != None:
686 self.n = n
686 self.n = n
687 self.__byTime = False
687 self.__byTime = False
688 else:
688 else:
689 self.__integrationtime = timeInterval * 60. #if (type(timeInterval)!=integer) -> change this line
689 self.__integrationtime = timeInterval * 60. #if (type(timeInterval)!=integer) -> change this line
690 self.n = 9999
690 self.n = 9999
691 self.__byTime = True
691 self.__byTime = True
692
692
693 if overlapping:
693 if overlapping:
694 self.__withOverapping = True
694 self.__withOverapping = True
695 self.__buffer = None
695 self.__buffer = None
696 else:
696 else:
697 self.__withOverapping = False
697 self.__withOverapping = False
698 self.__buffer = 0
698 self.__buffer = 0
699
699
700 self.__profIndex = 0
700 self.__profIndex = 0
701
701
702 def putData(self, data):
702 def putData(self, data):
703
703
704 """
704 """
705 Add a profile to the __buffer and increase in one the __profileIndex
705 Add a profile to the __buffer and increase in one the __profileIndex
706
706
707 """
707 """
708
708
709 if not self.__withOverapping:
709 if not self.__withOverapping:
710 self.__buffer += data.copy()
710 self.__buffer += data.copy()
711 self.__profIndex += 1
711 self.__profIndex += 1
712 return
712 return
713
713
714 #Overlapping data
714 #Overlapping data
715 nChannels, nFFTPoints, nHeis = data.shape
715 nChannels, nFFTPoints, nHeis = data.shape
716 data = numpy.reshape(data, (1, nChannels, nFFTPoints, nHeis))
716 data = numpy.reshape(data, (1, nChannels, nFFTPoints, nHeis))
717
717
718 #If the buffer is empty then it takes the data value
718 #If the buffer is empty then it takes the data value
719 if self.__buffer == None:
719 if self.__buffer == None:
720 self.__buffer = data
720 self.__buffer = data
721 self.__profIndex += 1
721 self.__profIndex += 1
722 return
722 return
723
723
724 #If the buffer length is lower than n then stakcing the data value
724 #If the buffer length is lower than n then stakcing the data value
725 if self.__profIndex < self.n:
725 if self.__profIndex < self.n:
726 self.__buffer = numpy.vstack((self.__buffer, data))
726 self.__buffer = numpy.vstack((self.__buffer, data))
727 self.__profIndex += 1
727 self.__profIndex += 1
728 return
728 return
729
729
730 #If the buffer length is equal to n then replacing the last buffer value with the data value
730 #If the buffer length is equal to n then replacing the last buffer value with the data value
731 self.__buffer = numpy.roll(self.__buffer, -1, axis=0)
731 self.__buffer = numpy.roll(self.__buffer, -1, axis=0)
732 self.__buffer[self.n-1] = data
732 self.__buffer[self.n-1] = data
733 self.__profIndex = self.n
733 self.__profIndex = self.n
734 return
734 return
735
735
736
736
737 def pushData(self):
737 def pushData(self):
738 """
738 """
739 Return the sum of the last profiles and the profiles used in the sum.
739 Return the sum of the last profiles and the profiles used in the sum.
740
740
741 Affected:
741 Affected:
742
742
743 self.__profileIndex
743 self.__profileIndex
744
744
745 """
745 """
746
746
747 if not self.__withOverapping:
747 if not self.__withOverapping:
748 data = self.__buffer
748 data = self.__buffer
749 n = self.__profIndex
749 n = self.__profIndex
750
750
751 self.__buffer = 0
751 self.__buffer = 0
752 self.__profIndex = 0
752 self.__profIndex = 0
753
753
754 return data, n
754 return data, n
755
755
756 #Integration with Overlapping
756 #Integration with Overlapping
757 data = numpy.sum(self.__buffer, axis=0)
757 data = numpy.sum(self.__buffer, axis=0)
758 n = self.__profIndex
758 n = self.__profIndex
759
759
760 return data, n
760 return data, n
761
761
762 def byProfiles(self, data):
762 def byProfiles(self, data):
763
763
764 self.__dataReady = False
764 self.__dataReady = False
765 avgdata = None
765 avgdata = None
766 n = None
766 n = None
767
767
768 self.putData(data)
768 self.putData(data)
769
769
770 if self.__profIndex == self.n:
770 if self.__profIndex == self.n:
771
771
772 avgdata, n = self.pushData()
772 avgdata, n = self.pushData()
773 self.__dataReady = True
773 self.__dataReady = True
774
774
775 return avgdata
775 return avgdata
776
776
777 def byTime(self, data, datatime):
777 def byTime(self, data, datatime):
778
778
779 self.__dataReady = False
779 self.__dataReady = False
780 avgdata = None
780 avgdata = None
781 n = None
781 n = None
782
782
783 self.putData(data)
783 self.putData(data)
784
784
785 if (datatime - self.__initime) >= self.__integrationtime:
785 if (datatime - self.__initime) >= self.__integrationtime:
786 avgdata, n = self.pushData()
786 avgdata, n = self.pushData()
787 self.n = n
787 self.n = n
788 self.__dataReady = True
788 self.__dataReady = True
789
789
790 return avgdata
790 return avgdata
791
791
792 def integrate(self, data, datatime=None):
792 def integrate(self, data, datatime=None):
793
793
794 if self.__initime == None:
794 if self.__initime == None:
795 self.__initime = datatime
795 self.__initime = datatime
796
796
797 if self.__byTime:
797 if self.__byTime:
798 avgdata = self.byTime(data, datatime)
798 avgdata = self.byTime(data, datatime)
799 else:
799 else:
800 avgdata = self.byProfiles(data)
800 avgdata = self.byProfiles(data)
801
801
802
802
803 self.__lastdatatime = datatime
803 self.__lastdatatime = datatime
804
804
805 if avgdata == None:
805 if avgdata == None:
806 return None, None
806 return None, None
807
807
808 avgdatatime = self.__initime
808 avgdatatime = self.__initime
809
809
810 deltatime = datatime -self.__lastdatatime
810 deltatime = datatime -self.__lastdatatime
811
811
812 if not self.__withOverapping:
812 if not self.__withOverapping:
813 self.__initime = datatime
813 self.__initime = datatime
814 else:
814 else:
815 self.__initime += deltatime
815 self.__initime += deltatime
816
816
817 return avgdata, avgdatatime
817 return avgdata, avgdatatime
818
818
819 def run(self, dataOut, n=None, timeInterval=None, overlapping=False):
819 def run(self, dataOut, n=None, timeInterval=None, overlapping=False):
820
820
821 if not self.__isConfig:
821 if not self.__isConfig:
822 self.setup(n, timeInterval, overlapping)
822 self.setup(n, timeInterval, overlapping)
823 self.__isConfig = True
823 self.__isConfig = True
824
824
825 avgdata, avgdatatime = self.integrate(dataOut.data_spc, dataOut.utctime)
825 avgdata, avgdatatime = self.integrate(dataOut.data_spc, dataOut.utctime)
826
826
827 # dataOut.timeInterval *= n
827 # dataOut.timeInterval *= n
828 dataOut.flagNoData = True
828 dataOut.flagNoData = True
829
829
830 if self.__dataReady:
830 if self.__dataReady:
831 dataOut.data_spc = avgdata
831 dataOut.data_spc = avgdata
832 dataOut.nIncohInt *= self.n
832 dataOut.nIncohInt *= self.n
833 dataOut.utctime = avgdatatime
833 dataOut.utctime = avgdatatime
834 dataOut.timeInterval = dataOut.ippSeconds * dataOut.nCohInt * dataOut.nIncohInt
834 dataOut.timeInterval = dataOut.ippSeconds * dataOut.nCohInt * dataOut.nIncohInt * dataOut.nFFTPoints
835 dataOut.flagNoData = False
835 dataOut.flagNoData = False
836 No newline at end of file
836
General Comments 0
You need to be logged in to leave comments. Login now