##// END OF EJS Templates
bugs and formatting
Juan C. Espinoza -
r1096:fa511d6b9ad9
parent child
Show More

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

@@ -1,348 +1,354
1 1 '''
2 2
3 3 $Author: murco $
4 4 $Id: jroproc_base.py 1 2012-11-12 18:56:07Z murco $
5 5 '''
6 6 import inspect
7 7 from fuzzywuzzy import process
8 8
9 9 def checkKwargs(method, kwargs):
10 10 currentKwargs = kwargs
11 11 choices = inspect.getargspec(method).args
12 12 try:
13 13 choices.remove('self')
14 14 except Exception as e:
15 15 pass
16 16
17 17 try:
18 18 choices.remove('dataOut')
19 19 except Exception as e:
20 20 pass
21 21
22 22 for kwarg in kwargs:
23 23 fuzz = process.extractOne(kwarg, choices)
24 24 if fuzz is None:
25 25 continue
26 26 if fuzz[1] < 100:
27 27 raise Exception('\x1b[0;32;40mDid you mean {} instead of {} in {}? \x1b[0m'.
28 28 format(fuzz[0], kwarg, method.__self__.__class__.__name__))
29 29
30 30 class ProcessingUnit(object):
31 31
32 32 """
33 33 Esta es la clase base para el procesamiento de datos.
34 34
35 35 Contiene el metodo "call" para llamar operaciones. Las operaciones pueden ser:
36 36 - Metodos internos (callMethod)
37 37 - Objetos del tipo Operation (callObject). Antes de ser llamados, estos objetos
38 38 tienen que ser agreagados con el metodo "add".
39 39
40 40 """
41 41 # objeto de datos de entrada (Voltage, Spectra o Correlation)
42 42 dataIn = None
43 43 dataInList = []
44 44
45 45 # objeto de datos de entrada (Voltage, Spectra o Correlation)
46 46 dataOut = None
47 47
48 48 operations2RunDict = None
49 49
50 50 isConfig = False
51 51
52 52
53 53 def __init__(self, *args, **kwargs):
54 54
55 55 self.dataIn = None
56 56 self.dataInList = []
57 57
58 58 self.dataOut = None
59 59
60 60 self.operations2RunDict = {}
61 61 self.operationKwargs = {}
62 62
63 63 self.isConfig = False
64 64
65 65 self.args = args
66 66 self.kwargs = kwargs
67
68 if not hasattr(self, 'name'):
69 self.name = self.__class__.__name__
70
67 71 checkKwargs(self.run, kwargs)
68 72
69 73 def getAllowedArgs(self):
70 74 return inspect.getargspec(self.run).args
71 75
72 76 def addOperationKwargs(self, objId, **kwargs):
73 77 '''
74 78 '''
75 79
76 80 self.operationKwargs[objId] = kwargs
77 81
78 82
79 83 def addOperation(self, opObj, objId):
80 84
81 85 """
82 86 Agrega un objeto del tipo "Operation" (opObj) a la lista de objetos "self.objectList" y retorna el
83 87 identificador asociado a este objeto.
84 88
85 89 Input:
86 90
87 91 object : objeto de la clase "Operation"
88 92
89 93 Return:
90 94
91 95 objId : identificador del objeto, necesario para ejecutar la operacion
92 96 """
93 97
94 98 self.operations2RunDict[objId] = opObj
95 99
96 100 return objId
97 101
98 102 def getOperationObj(self, objId):
99 103
100 104 if objId not in self.operations2RunDict.keys():
101 105 return None
102 106
103 107 return self.operations2RunDict[objId]
104 108
105 109 def operation(self, **kwargs):
106 110
107 111 """
108 112 Operacion directa sobre la data (dataOut.data). Es necesario actualizar los valores de los
109 113 atributos del objeto dataOut
110 114
111 115 Input:
112 116
113 117 **kwargs : Diccionario de argumentos de la funcion a ejecutar
114 118 """
115 119
116 120 raise NotImplementedError
117 121
118 122 def callMethod(self, name, opId):
119 123
120 124 """
121 125 Ejecuta el metodo con el nombre "name" y con argumentos **kwargs de la propia clase.
122 126
123 127 Input:
124 128 name : nombre del metodo a ejecutar
125 129
126 130 **kwargs : diccionario con los nombres y valores de la funcion a ejecutar.
127 131
128 132 """
129 133
130 134 #Checking the inputs
131 135 if name == 'run':
132 136
133 137 if not self.checkInputs():
134 138 self.dataOut.flagNoData = True
135 139 return False
136 140 else:
137 141 #Si no es un metodo RUN la entrada es la misma dataOut (interna)
138 142 if self.dataOut is not None and self.dataOut.isEmpty():
139 143 return False
140 144
141 145 #Getting the pointer to method
142 146 methodToCall = getattr(self, name)
143 147
144 148 #Executing the self method
145 149
146 150 if hasattr(self, 'mp'):
147 151 if name=='run':
148 152 if self.mp is False:
149 153 self.mp = True
150 154 self.start()
151 155 else:
152 156 self.operationKwargs[opId]['parent'] = self.kwargs
153 157 methodToCall(**self.operationKwargs[opId])
154 158 else:
155 159 if name=='run':
156 160 methodToCall(**self.kwargs)
157 161 else:
158 162 methodToCall(**self.operationKwargs[opId])
159 163
160 164 if self.dataOut is None:
161 165 return False
162 166
163 167 if self.dataOut.isEmpty():
164 168 return False
165 169
166 170 return True
167 171
168 172 def callObject(self, objId):
169 173
170 174 """
171 175 Ejecuta la operacion asociada al identificador del objeto "objId"
172 176
173 177 Input:
174 178
175 179 objId : identificador del objeto a ejecutar
176 180
177 181 **kwargs : diccionario con los nombres y valores de la funcion a ejecutar.
178 182
179 183 Return:
180 184
181 185 None
182 186 """
183 187
184 188 if self.dataOut is not None and self.dataOut.isEmpty():
185 189 return False
186 190
187 191 externalProcObj = self.operations2RunDict[objId]
188 192
189 193 if hasattr(externalProcObj, 'mp'):
190 194 if externalProcObj.mp is False:
191 195 externalProcObj.kwargs['parent'] = self.kwargs
192 196 self.operationKwargs[objId] = externalProcObj.kwargs
193 197 externalProcObj.mp = True
194 198 externalProcObj.start()
195 199 else:
196 200 externalProcObj.run(self.dataOut, **externalProcObj.kwargs)
197 201 self.operationKwargs[objId] = externalProcObj.kwargs
198 202
199 203
200 204 return True
201 205
202 206 def call(self, opType, opName=None, opId=None):
203 207 """
204 208 Return True si ejecuta la operacion interna nombrada "opName" o la operacion externa
205 209 identificada con el id "opId"; con los argumentos "**kwargs".
206 210
207 211 False si la operacion no se ha ejecutado.
208 212
209 213 Input:
210 214
211 215 opType : Puede ser "self" o "external"
212 216
213 217 Depende del tipo de operacion para llamar a:callMethod or callObject:
214 218
215 219 1. If opType = "self": Llama a un metodo propio de esta clase:
216 220
217 221 name_method = getattr(self, name)
218 222 name_method(**kwargs)
219 223
220 224
221 225 2. If opType = "other" o"external": Llama al metodo "run()" de una instancia de la
222 226 clase "Operation" o de un derivado de ella:
223 227
224 228 instanceName = self.operationList[opId]
225 229 instanceName.run(**kwargs)
226 230
227 231 opName : Si la operacion es interna (opType = 'self'), entonces el "opName" sera
228 232 usada para llamar a un metodo interno de la clase Processing
229 233
230 234 opId : Si la operacion es externa (opType = 'other' o 'external), entonces el
231 235 "opId" sera usada para llamar al metodo "run" de la clase Operation
232 236 registrada anteriormente con ese Id
233 237
234 238 Exception:
235 239 Este objeto de tipo Operation debe de haber sido agregado antes con el metodo:
236 240 "addOperation" e identificado con el valor "opId" = el id de la operacion.
237 241 De lo contrario retornara un error del tipo ValueError
238 242
239 243 """
240 244
241 245 if opType == 'self':
242 246
243 247 if not opName:
244 248 raise ValueError, "opName parameter should be defined"
245 249
246 250 sts = self.callMethod(opName, opId)
247 251
248 252 elif opType == 'other' or opType == 'external' or opType == 'plotter':
249 253
250 254 if not opId:
251 255 raise ValueError, "opId parameter should be defined"
252 256
253 257 if opId not in self.operations2RunDict.keys():
254 258 raise ValueError, "Any operation with id=%s has been added" %str(opId)
255 259
256 260 sts = self.callObject(opId)
257 261
258 262 else:
259 263 raise ValueError, "opType should be 'self', 'external' or 'plotter'; and not '%s'" %opType
260 264
261 265 return sts
262 266
263 267 def setInput(self, dataIn):
264 268
265 269 self.dataIn = dataIn
266 270 self.dataInList.append(dataIn)
267 271
268 272 def getOutputObj(self):
269 273
270 274 return self.dataOut
271 275
272 276 def checkInputs(self):
273 277
274 278 for thisDataIn in self.dataInList:
275 279
276 280 if thisDataIn.isEmpty():
277 281 return False
278 282
279 283 return True
280 284
281 285 def setup(self):
282 286
283 287 raise NotImplementedError
284 288
285 289 def run(self):
286 290
287 291 raise NotImplementedError
288 292
289 293 def close(self):
290 294 #Close every thread, queue or any other object here is it is neccesary.
291 295 return
292 296
293 297 class Operation(object):
294 298
295 299 """
296 300 Clase base para definir las operaciones adicionales que se pueden agregar a la clase ProcessingUnit
297 301 y necesiten acumular informacion previa de los datos a procesar. De preferencia usar un buffer de
298 302 acumulacion dentro de esta clase
299 303
300 304 Ejemplo: Integraciones coherentes, necesita la informacion previa de los n perfiles anteriores (bufffer)
301 305
302 306 """
303 307
304 308 __buffer = None
305 309 isConfig = False
306 310
307 311 def __init__(self, **kwargs):
308 312
309 313 self.__buffer = None
310 314 self.isConfig = False
311 315 self.kwargs = kwargs
316 if not hasattr(self, 'name'):
317 self.name = self.__class__.__name__
312 318 checkKwargs(self.run, kwargs)
313 319
314 320 def getAllowedArgs(self):
315 321 return inspect.getargspec(self.run).args
316 322
317 323 def setup(self):
318 324
319 325 self.isConfig = True
320 326
321 327 raise NotImplementedError
322 328
323 329 def run(self, dataIn, **kwargs):
324 330
325 331 """
326 332 Realiza las operaciones necesarias sobre la dataIn.data y actualiza los
327 333 atributos del objeto dataIn.
328 334
329 335 Input:
330 336
331 337 dataIn : objeto del tipo JROData
332 338
333 339 Return:
334 340
335 341 None
336 342
337 343 Affected:
338 344 __buffer : buffer de recepcion de datos.
339 345
340 346 """
341 347 if not self.isConfig:
342 348 self.setup(**kwargs)
343 349
344 350 raise NotImplementedError
345 351
346 352 def close(self):
347 353
348 354 pass
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now