##// END OF EJS Templates
VoltageProcessor: Crea el objeto de salida en el constructor
Miguel Valdez -
r188:c0af656b96e7
parent child
Show More
@@ -1,444 +1,439
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 addOperation(self, object, objId):
39 def addOperation(self, object, objId):
40
40
41 """
41 """
42 Agrega el objeto "object" a la lista de objetos "self.objectList" y retorna el
42 Agrega el objeto "object" a la lista de objetos "self.objectList" y retorna el
43 identificador asociado a este objeto.
43 identificador asociado a este objeto.
44
44
45 Input:
45 Input:
46
46
47 object : objeto de la clase "Operation"
47 object : objeto de la clase "Operation"
48
48
49 Return:
49 Return:
50
50
51 objId : identificador del objeto, necesario para ejecutar la operacion
51 objId : identificador del objeto, necesario para ejecutar la operacion
52 """
52 """
53
53
54 self.objectDict[objId] = object
54 self.objectDict[objId] = object
55
55
56 return objId
56 return objId
57
57
58 def operation(self, **kwargs):
58 def operation(self, **kwargs):
59
59
60 """
60 """
61 Operacion directa sobre la data (dataout.data). Es necesario actualizar los valores de los
61 Operacion directa sobre la data (dataout.data). Es necesario actualizar los valores de los
62 atributos del objeto dataOut
62 atributos del objeto dataOut
63
63
64 Input:
64 Input:
65
65
66 **kwargs : Diccionario de argumentos de la funcion a ejecutar
66 **kwargs : Diccionario de argumentos de la funcion a ejecutar
67 """
67 """
68
68
69 if self.dataIn.isEmpty():
70 return None
71
72 raise ValueError, "ImplementedError"
69 raise ValueError, "ImplementedError"
73
70
74 def callMethod(self, name, **kwargs):
71 def callMethod(self, name, **kwargs):
75
72
76 """
73 """
77 Ejecuta el metodo con el nombre "name" y con argumentos **kwargs de la propia clase.
74 Ejecuta el metodo con el nombre "name" y con argumentos **kwargs de la propia clase.
78
75
79 Input:
76 Input:
80 name : nombre del metodo a ejecutar
77 name : nombre del metodo a ejecutar
81
78
82 **kwargs : diccionario con los nombres y valores de la funcion a ejecutar.
79 **kwargs : diccionario con los nombres y valores de la funcion a ejecutar.
83
80
84 """
81 """
85
82
86 if self.dataIn.isEmpty():
87 return None
88
89 methodToCall = getattr(self, name)
83 methodToCall = getattr(self, name)
90
84
91 methodToCall(**kwargs)
85 methodToCall(**kwargs)
92
86
93 def callObject(self, objId, **kwargs):
87 def callObject(self, objId, **kwargs):
94
88
95 """
89 """
96 Ejecuta la operacion asociada al identificador del objeto "objId"
90 Ejecuta la operacion asociada al identificador del objeto "objId"
97
91
98 Input:
92 Input:
99
93
100 objId : identificador del objeto a ejecutar
94 objId : identificador del objeto a ejecutar
101
95
102 **kwargs : diccionario con los nombres y valores de la funcion a ejecutar.
96 **kwargs : diccionario con los nombres y valores de la funcion a ejecutar.
103
97
104 Return:
98 Return:
105
99
106 None
100 None
107 """
101 """
108
102
109 if self.dataIn.isEmpty():
110 return None
111
112 object = self.objectList[objId]
103 object = self.objectList[objId]
113
104
114 object.run(self.dataOut, **kwargs)
105 object.run(self.dataOut, **kwargs)
115
106
116 def call(self, operation, **kwargs):
107 def call(self, operationConf, **kwargs):
117
108
118 """
109 """
119 Ejecuta la operacion "operation" con los argumentos "**kwargs". La operacion puede
110 Ejecuta la operacion "operationConf.name" con los argumentos "**kwargs". La operacion puede
120 ser de dos tipos:
111 ser de dos tipos:
121
112
122 1. Un metodo propio de esta clase:
113 1. Un metodo propio de esta clase:
123
114
124 operation.type = "self"
115 operation.type = "self"
125
116
126 2. El metodo "run" de un objeto del tipo Operation o de un derivado de ella:
117 2. El metodo "run" de un objeto del tipo Operation o de un derivado de ella:
127 operation.type = "other".
118 operation.type = "other".
128
119
129 Este objeto de tipo Operation debe de haber sido agregado antes con el metodo:
120 Este objeto de tipo Operation debe de haber sido agregado antes con el metodo:
130 "addOperation" e identificado con el operation.id
121 "addOperation" e identificado con el operation.id
131
122
132
123
133 con el id de la operacion.
124 con el id de la operacion.
125
126 Input:
127
128 Operation : Objeto del tipo operacion con los atributos: name, type y id.
129
134 """
130 """
135 if self.dataIn.isEmpty():
131 if self.dataIn.isEmpty():
136 return None
132 return None
137
133
138 if operation.type == 'self':
134 if operationConf.type == 'self':
139 self.callMethod(operation.name, **kwargs)
135 self.callMethod(operationConf.name, **kwargs)
140 return
136 return
141
137
142 if operation.type == 'other':
138 if operationConf.type == 'other':
143 self.callObject(operation.id, **kwargs)
139 self.callObject(operationConf.id, **kwargs)
144 return
140 return
145
141
146 class Operation():
142 class Operation():
147
143
148 """
144 """
149 Clase base para definir las operaciones adicionales que se pueden agregar a la clase ProcessingUnit
145 Clase base para definir las operaciones adicionales que se pueden agregar a la clase ProcessingUnit
150 y necesiten acumular informacion previa de los datos a procesar. De preferencia usar un buffer de
146 y necesiten acumular informacion previa de los datos a procesar. De preferencia usar un buffer de
151 acumulacion dentro de esta clase
147 acumulacion dentro de esta clase
152
148
153 Ejemplo: Integraciones coherentes, necesita la informacion previa de los n perfiles anteriores (bufffer)
149 Ejemplo: Integraciones coherentes, necesita la informacion previa de los n perfiles anteriores (bufffer)
154
150
155 """
151 """
156
152
157 __buffer = None
153 __buffer = None
158 __isConfig = False
154 __isConfig = False
159
155
160 def __init__(self):
156 def __init__(self):
161
157
162 pass
158 pass
163
159
164 def run(self, dataIn, **kwargs):
160 def run(self, dataIn, **kwargs):
165
161
166 """
162 """
167 Realiza las operaciones necesarias sobre la dataIn.data y actualiza los atributos del objeto dataIn.
163 Realiza las operaciones necesarias sobre la dataIn.data y actualiza los atributos del objeto dataIn.
168
164
169 Input:
165 Input:
170
166
171 dataIn : objeto del tipo JROData
167 dataIn : objeto del tipo JROData
172
168
173 Return:
169 Return:
174
170
175 None
171 None
176
172
177 Affected:
173 Affected:
178 __buffer : buffer de recepcion de datos.
174 __buffer : buffer de recepcion de datos.
179
175
180 """
176 """
181
177
182 raise ValueError, "ImplementedError"
178 raise ValueError, "ImplementedError"
183
179
184 class VoltageProc(ProcessingUnit):
180 class VoltageProc(ProcessingUnit):
185
181
186
182
187 def __init__(self):
183 def __init__(self):
184
188 self.objectDict = {}
185 self.objectDict = {}
189 pass
186 self.dataOut = Voltage()
187
190
188
191 def setup(self, dataIn=None, dataOut=None):
189 def setup(self, dataIn=None, dataOut=None):
192
190
193 self.dataIn = dataIn
191 self.dataIn = dataIn
194
192
195 if self.dataOut == None:
193 if self.dataOut == None:
196 dataOut = Voltage()
194 dataOut = Voltage()
197
195
198 self.dataOut = dataOut
196 self.dataOut = dataOut
199
197
200 return self.dataOut
198 return self.dataOut
201
199
202 def init(self):
200 def init(self):
203
201
204 if self.dataIn.isEmpty():
205 return 0
206
207 self.dataOut.copy(self.dataIn)
202 self.dataOut.copy(self.dataIn)
208 # No necesita copiar en cada init() los atributos de dataIn
203 # No necesita copiar en cada init() los atributos de dataIn
209 # la copia deberia hacerse por cada nuevo bloque de datos
204 # la copia deberia hacerse por cada nuevo bloque de datos
210
205
211 def selectChannels(self, channelList):
206 def selectChannels(self, channelList):
212
207
213 if self.dataIn.isEmpty():
208 if self.dataIn.isEmpty():
214 return 0
209 return 0
215
210
216 self.selectChannelsByIndex(channelList)
211 self.selectChannelsByIndex(channelList)
217
212
218 def selectChannelsByIndex(self, channelIndexList):
213 def selectChannelsByIndex(self, channelIndexList):
219 """
214 """
220 Selecciona un bloque de datos en base a canales segun el channelIndexList
215 Selecciona un bloque de datos en base a canales segun el channelIndexList
221
216
222 Input:
217 Input:
223 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
218 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
224
219
225 Affected:
220 Affected:
226 self.dataOut.data
221 self.dataOut.data
227 self.dataOut.channelIndexList
222 self.dataOut.channelIndexList
228 self.dataOut.nChannels
223 self.dataOut.nChannels
229 self.dataOut.m_ProcessingHeader.totalSpectra
224 self.dataOut.m_ProcessingHeader.totalSpectra
230 self.dataOut.systemHeaderObj.numChannels
225 self.dataOut.systemHeaderObj.numChannels
231 self.dataOut.m_ProcessingHeader.blockSize
226 self.dataOut.m_ProcessingHeader.blockSize
232
227
233 Return:
228 Return:
234 None
229 None
235 """
230 """
236
231
237 for channel in channelIndexList:
232 for channel in channelIndexList:
238 if channel not in self.dataOut.channelIndexList:
233 if channel not in self.dataOut.channelIndexList:
239 raise ValueError, "The value %d in channelIndexList is not valid" %channel
234 raise ValueError, "The value %d in channelIndexList is not valid" %channel
240
235
241 nChannels = len(channelIndexList)
236 nChannels = len(channelIndexList)
242
237
243 data = self.dataOut.data[channelIndexList,:]
238 data = self.dataOut.data[channelIndexList,:]
244
239
245 self.dataOut.data = data
240 self.dataOut.data = data
246 self.dataOut.channelIndexList = channelIndexList
241 self.dataOut.channelIndexList = channelIndexList
247 self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
242 self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
248 self.dataOut.nChannels = nChannels
243 self.dataOut.nChannels = nChannels
249
244
250 return 1
245 return 1
251
246
252 class CohInt(Operation):
247 class CohInt(Operation):
253
248
254 __profIndex = 0
249 __profIndex = 0
255 __withOverapping = False
250 __withOverapping = False
256
251
257 __byTime = False
252 __byTime = False
258 __initime = None
253 __initime = None
259 __lastdatatime = None
254 __lastdatatime = None
260 __integrationtime = None
255 __integrationtime = None
261
256
262 __buffer = None
257 __buffer = None
263
258
264 __dataReady = False
259 __dataReady = False
265
260
266 nCohInt = None
261 nCohInt = None
267
262
268
263
269 def __init__(self):
264 def __init__(self):
270
265
271 self.__isConfig = False
266 self.__isConfig = False
272
267
273 def setup(self, nCohInt=None, timeInterval=None, overlapping=False):
268 def setup(self, nCohInt=None, timeInterval=None, overlapping=False):
274 """
269 """
275 Set the parameters of the integration class.
270 Set the parameters of the integration class.
276
271
277 Inputs:
272 Inputs:
278
273
279 nCohInt : Number of coherent integrations
274 nCohInt : Number of coherent integrations
280 timeInterval : Time of integration. If the parameter "nCohInt" is selected this one does not work
275 timeInterval : Time of integration. If the parameter "nCohInt" is selected this one does not work
281 overlapping :
276 overlapping :
282
277
283 """
278 """
284
279
285 self.__initime = None
280 self.__initime = None
286 self.__lastdatatime = 0
281 self.__lastdatatime = 0
287 self.__buffer = None
282 self.__buffer = None
288 self.__dataReady = False
283 self.__dataReady = False
289
284
290
285
291 if nCohInt == None and timeInterval == None:
286 if nCohInt == None and timeInterval == None:
292 raise ValueError, "nCohInt or timeInterval should be specified ..."
287 raise ValueError, "nCohInt or timeInterval should be specified ..."
293
288
294 if nCohInt != None:
289 if nCohInt != None:
295 self.nCohInt = nCohInt
290 self.nCohInt = nCohInt
296 self.__byTime = False
291 self.__byTime = False
297 else:
292 else:
298 self.__integrationtime = timeInterval * 60. #if (type(timeInterval)!=integer) -> change this line
293 self.__integrationtime = timeInterval * 60. #if (type(timeInterval)!=integer) -> change this line
299 self.nCohInt = 9999
294 self.nCohInt = 9999
300 self.__byTime = True
295 self.__byTime = True
301
296
302 if overlapping:
297 if overlapping:
303 self.__withOverapping = True
298 self.__withOverapping = True
304 self.__buffer = None
299 self.__buffer = None
305 else:
300 else:
306 self.__withOverapping = False
301 self.__withOverapping = False
307 self.__buffer = 0
302 self.__buffer = 0
308
303
309 self.__profIndex = 0
304 self.__profIndex = 0
310
305
311 def putData(self, data):
306 def putData(self, data):
312
307
313 """
308 """
314 Add a profile to the __buffer and increase in one the __profileIndex
309 Add a profile to the __buffer and increase in one the __profileIndex
315
310
316 """
311 """
317
312
318 if not self.__withOverapping:
313 if not self.__withOverapping:
319 self.__buffer += data
314 self.__buffer += data
320 self.__profIndex += 1
315 self.__profIndex += 1
321 return
316 return
322
317
323 #Overlapping data
318 #Overlapping data
324 nChannels, nHeis = data.shape
319 nChannels, nHeis = data.shape
325 data = numpy.reshape(data, (1, nChannels, nHeis))
320 data = numpy.reshape(data, (1, nChannels, nHeis))
326
321
327 #If the buffer is empty then it takes the data value
322 #If the buffer is empty then it takes the data value
328 if self.__buffer == None:
323 if self.__buffer == None:
329 self.__buffer = data
324 self.__buffer = data
330 self.__profIndex += 1
325 self.__profIndex += 1
331 return
326 return
332
327
333 #If the buffer length is lower than nCohInt then stakcing the data value
328 #If the buffer length is lower than nCohInt then stakcing the data value
334 if self.__profIndex < self.nCohInt:
329 if self.__profIndex < self.nCohInt:
335 self.__buffer = numpy.vstack((self.__buffer, data))
330 self.__buffer = numpy.vstack((self.__buffer, data))
336 self.__profIndex += 1
331 self.__profIndex += 1
337 return
332 return
338
333
339 #If the buffer length is equal to nCohInt then replacing the last buffer value with the data value
334 #If the buffer length is equal to nCohInt then replacing the last buffer value with the data value
340 self.__buffer = numpy.roll(self.__buffer, -1, axis=0)
335 self.__buffer = numpy.roll(self.__buffer, -1, axis=0)
341 self.__buffer[self.nCohInt-1] = data
336 self.__buffer[self.nCohInt-1] = data
342 self.__profIndex = self.nCohInt
337 self.__profIndex = self.nCohInt
343 return
338 return
344
339
345
340
346 def pushData(self):
341 def pushData(self):
347 """
342 """
348 Return the sum of the last profiles and the profiles used in the sum.
343 Return the sum of the last profiles and the profiles used in the sum.
349
344
350 Affected:
345 Affected:
351
346
352 self.__profileIndex
347 self.__profileIndex
353
348
354 """
349 """
355
350
356 if not self.__withOverapping:
351 if not self.__withOverapping:
357 data = self.__buffer
352 data = self.__buffer
358 nCohInt = self.__profIndex
353 nCohInt = self.__profIndex
359
354
360 self.__buffer = 0
355 self.__buffer = 0
361 self.__profIndex = 0
356 self.__profIndex = 0
362
357
363 return data, nCohInt
358 return data, nCohInt
364
359
365 #Integration with Overlapping
360 #Integration with Overlapping
366 data = numpy.sum(self.__buffer, axis=0)
361 data = numpy.sum(self.__buffer, axis=0)
367 nCohInt = self.__profIndex
362 nCohInt = self.__profIndex
368
363
369 return data, nCohInt
364 return data, nCohInt
370
365
371 def byProfiles(self, data):
366 def byProfiles(self, data):
372
367
373 self.__dataReady = False
368 self.__dataReady = False
374 avg_data = None
369 avg_data = None
375 nCohInt = None
370 nCohInt = None
376
371
377 self.putData(data)
372 self.putData(data)
378
373
379 if self.__profIndex == self.nCohInt:
374 if self.__profIndex == self.nCohInt:
380
375
381 avgdata, nCohInt = self.pushData()
376 avgdata, nCohInt = self.pushData()
382 self.__dataReady = True
377 self.__dataReady = True
383
378
384 return avgdata, nCohInt
379 return avgdata, nCohInt
385
380
386 def byTime(self, data, datatime):
381 def byTime(self, data, datatime):
387
382
388 self.__dataReady = False
383 self.__dataReady = False
389 avg_data = None
384 avg_data = None
390 nCohInt = None
385 nCohInt = None
391
386
392 self.putData(data)
387 self.putData(data)
393
388
394 if (datatime - self.__initime) >= self.__integrationtime:
389 if (datatime - self.__initime) >= self.__integrationtime:
395 avgdata, nCohInt = self.pushData()
390 avgdata, nCohInt = self.pushData()
396 self.nCohInt = nCohInt
391 self.nCohInt = nCohInt
397 self.__dataReady = True
392 self.__dataReady = True
398
393
399 return avgdata, nCohInt
394 return avgdata, nCohInt
400
395
401 def integrate(self, data, datatime=None):
396 def integrate(self, data, datatime=None):
402
397
403 if self.__initime == None:
398 if self.__initime == None:
404 self.__initime = datatime
399 self.__initime = datatime
405
400
406 if self.__byTime:
401 if self.__byTime:
407 avgdata = self.byTime(data, datatime)
402 avgdata = self.byTime(data, datatime)
408 else:
403 else:
409 avgdata = self.byProfiles(data)
404 avgdata = self.byProfiles(data)
410
405
411
406
412 self.__lastdatatime = datatime
407 self.__lastdatatime = datatime
413
408
414 if avgdata == None:
409 if avgdata == None:
415 return None
410 return None
416
411
417 avgdatatime = self.__initime
412 avgdatatime = self.__initime
418
413
419 deltatime = datatime -self.__lastdatatime
414 deltatime = datatime -self.__lastdatatime
420
415
421 if not self.__withOverapping:
416 if not self.__withOverapping:
422 self.__initime = datatime
417 self.__initime = datatime
423 else:
418 else:
424 self.__initime += deltatime
419 self.__initime += deltatime
425
420
426 return avgdata, avgdatatime
421 return avgdata, avgdatatime
427
422
428 def run(self, dataOut, nCohInt=None, timeInterval=None, overlapping=False):
423 def run(self, dataOut, nCohInt=None, timeInterval=None, overlapping=False):
429
424
430 if not self.__isConfig:
425 if not self.__isConfig:
431 self.setup(nCohInt, timeInterval, overlapping)
426 self.setup(nCohInt, timeInterval, overlapping)
432 self.__isConfig = True
427 self.__isConfig = True
433
428
434 avgdata, avgdatatime = self.integrate(dataOut.data, dataOut.utctime)
429 avgdata, avgdatatime = self.integrate(dataOut.data, dataOut.utctime)
435
430
436 # self.dataOut.timeInterval *= nCohInt
431 # self.dataOut.timeInterval *= nCohInt
437 self.dataOut.flagNoData = True
432 self.dataOut.flagNoData = True
438
433
439 if self.__dataReady:
434 if self.__dataReady:
440 dataOut.data = avgdata
435 dataOut.data = avgdata
441 dataOut.timeInterval *= self.nCohInt
436 dataOut.timeInterval *= self.nCohInt
442 dataOut.nCohInt *= self.nCohInt
437 dataOut.nCohInt *= self.nCohInt
443 dataOut.utctime = avgdatatime
438 dataOut.utctime = avgdatatime
444 dataOut.flagNoData = False No newline at end of file
439 dataOut.flagNoData = False
General Comments 0
You need to be logged in to leave comments. Login now