##// END OF EJS Templates
Merge branch 'schain_mp' of http://jro-dev.igp.gob.pe/rhodecode/schain into schain_mp
Merge branch 'schain_mp' of http://jro-dev.igp.gob.pe/rhodecode/schain into schain_mp

File last commit:

r897:bf36fab25ada
r905:610840afa451 merge
Show More
jroproc_base.py
299 lines | 7.6 KiB | text/x-python | PythonLexer
'''
$Author: murco $
$Id: jroproc_base.py 1 2012-11-12 18:56:07Z murco $
'''
class ProcessingUnit(object):
"""
Esta es la clase base para el procesamiento de datos.
Contiene el metodo "call" para llamar operaciones. Las operaciones pueden ser:
- Metodos internos (callMethod)
- Objetos del tipo Operation (callObject). Antes de ser llamados, estos objetos
tienen que ser agreagados con el metodo "add".
"""
# objeto de datos de entrada (Voltage, Spectra o Correlation)
dataIn = None
dataInList = []
# objeto de datos de entrada (Voltage, Spectra o Correlation)
dataOut = None
operations2RunDict = None
isConfig = False
def __init__(self, *args, **kwargs):
self.dataIn = None
self.dataInList = []
self.dataOut = None
self.operations2RunDict = {}
self.isConfig = False
self.args = args
self.kwargs = kwargs
def addOperation(self, opObj, objId):
"""
Agrega un objeto del tipo "Operation" (opObj) a la lista de objetos "self.objectList" y retorna el
identificador asociado a este objeto.
Input:
object : objeto de la clase "Operation"
Return:
objId : identificador del objeto, necesario para ejecutar la operacion
"""
self.operations2RunDict[objId] = opObj
return objId
def getOperationObj(self, objId):
if objId not in self.operations2RunDict.keys():
return None
return self.operations2RunDict[objId]
def operation(self, **kwargs):
"""
Operacion directa sobre la data (dataOut.data). Es necesario actualizar los valores de los
atributos del objeto dataOut
Input:
**kwargs : Diccionario de argumentos de la funcion a ejecutar
"""
raise NotImplementedError
def callMethod(self, name, **kwargs):
"""
Ejecuta el metodo con el nombre "name" y con argumentos **kwargs de la propia clase.
Input:
name : nombre del metodo a ejecutar
**kwargs : diccionario con los nombres y valores de la funcion a ejecutar.
"""
#Checking the inputs
if name == 'run':
if not self.checkInputs():
self.dataOut.flagNoData = True
return False
else:
#Si no es un metodo RUN la entrada es la misma dataOut (interna)
if self.dataOut.isEmpty():
return False
#Getting the pointer to method
methodToCall = getattr(self, name)
#Executing the self method
if hasattr(self, 'mp'):
if self.mp is False:
self.mp = True
self.start()
else:
methodToCall(**kwargs)
if self.dataOut is None:
return False
if self.dataOut.isEmpty():
return False
return True
def callObject(self, objId):
"""
Ejecuta la operacion asociada al identificador del objeto "objId"
Input:
objId : identificador del objeto a ejecutar
**kwargs : diccionario con los nombres y valores de la funcion a ejecutar.
Return:
None
"""
if self.dataOut is not None and self.dataOut.isEmpty():
return False
externalProcObj = self.operations2RunDict[objId]
if hasattr(externalProcObj, 'mp'):
if externalProcObj.mp is False:
externalProcObj.mp = True
externalProcObj.start()
else:
externalProcObj.run(self.dataOut, **externalProcObj.kwargs)
return True
def call(self, opType, opName=None, opId=None):
"""
Return True si ejecuta la operacion interna nombrada "opName" o la operacion externa
identificada con el id "opId"; con los argumentos "**kwargs".
False si la operacion no se ha ejecutado.
Input:
opType : Puede ser "self" o "external"
Depende del tipo de operacion para llamar a:callMethod or callObject:
1. If opType = "self": Llama a un metodo propio de esta clase:
name_method = getattr(self, name)
name_method(**kwargs)
2. If opType = "other" o"external": Llama al metodo "run()" de una instancia de la
clase "Operation" o de un derivado de ella:
instanceName = self.operationList[opId]
instanceName.run(**kwargs)
opName : Si la operacion es interna (opType = 'self'), entonces el "opName" sera
usada para llamar a un metodo interno de la clase Processing
opId : Si la operacion es externa (opType = 'other' o 'external), entonces el
"opId" sera usada para llamar al metodo "run" de la clase Operation
registrada anteriormente con ese Id
Exception:
Este objeto de tipo Operation debe de haber sido agregado antes con el metodo:
"addOperation" e identificado con el valor "opId" = el id de la operacion.
De lo contrario retornara un error del tipo ValueError
"""
if opType == 'self':
if not opName:
raise ValueError, "opName parameter should be defined"
sts = self.callMethod(opName, **self.kwargs)
elif opType == 'other' or opType == 'external' or opType == 'plotter':
if not opId:
raise ValueError, "opId parameter should be defined"
if opId not in self.operations2RunDict.keys():
raise ValueError, "Any operation with id=%s has been added" %str(opId)
sts = self.callObject(opId)
else:
raise ValueError, "opType should be 'self', 'external' or 'plotter'; and not '%s'" %opType
return sts
def setInput(self, dataIn):
self.dataIn = dataIn
self.dataInList.append(dataIn)
def getOutputObj(self):
return self.dataOut
def checkInputs(self):
for thisDataIn in self.dataInList:
if thisDataIn.isEmpty():
return False
return True
def setup(self):
raise NotImplementedError
def run(self):
raise NotImplementedError
def close(self):
#Close every thread, queue or any other object here is it is neccesary.
return
class Operation(object):
"""
Clase base para definir las operaciones adicionales que se pueden agregar a la clase ProcessingUnit
y necesiten acumular informacion previa de los datos a procesar. De preferencia usar un buffer de
acumulacion dentro de esta clase
Ejemplo: Integraciones coherentes, necesita la informacion previa de los n perfiles anteriores (bufffer)
"""
__buffer = None
isConfig = False
def __init__(self, **kwargs):
self.__buffer = None
self.isConfig = False
self.kwargs = kwargs
def setup(self):
self.isConfig = True
raise NotImplementedError
def run(self, dataIn, **kwargs):
"""
Realiza las operaciones necesarias sobre la dataIn.data y actualiza los
atributos del objeto dataIn.
Input:
dataIn : objeto del tipo JROData
Return:
None
Affected:
__buffer : buffer de recepcion de datos.
"""
if not self.isConfig:
self.setup(**kwargs)
raise NotImplementedError
def close(self):
pass