##// END OF EJS Templates
Optimizacion de la decodificacion
Miguel Valdez -
r298:492f9399ce75
parent child
Show More
@@ -1,1292 +1,1298
1 1 '''
2 2
3 3 $Author: dsuarez $
4 4 $Id: Processor.py 1 2012-11-12 18:56:07Z dsuarez $
5 5 '''
6 6 import os
7 7 import numpy
8 8 import datetime
9 9 import time
10 10
11 11 from jrodata import *
12 12 from jrodataIO import *
13 13 from jroplot import *
14 14
15 15 class ProcessingUnit:
16 16
17 17 """
18 18 Esta es la clase base para el procesamiento de datos.
19 19
20 20 Contiene el metodo "call" para llamar operaciones. Las operaciones pueden ser:
21 21 - Metodos internos (callMethod)
22 22 - Objetos del tipo Operation (callObject). Antes de ser llamados, estos objetos
23 23 tienen que ser agreagados con el metodo "add".
24 24
25 25 """
26 26 # objeto de datos de entrada (Voltage, Spectra o Correlation)
27 27 dataIn = None
28 28
29 29 # objeto de datos de entrada (Voltage, Spectra o Correlation)
30 30 dataOut = None
31 31
32 32
33 33 objectDict = None
34 34
35 35 def __init__(self):
36 36
37 37 self.objectDict = {}
38 38
39 39 def init(self):
40 40
41 41 raise ValueError, "Not implemented"
42 42
43 43 def addOperation(self, object, objId):
44 44
45 45 """
46 46 Agrega el objeto "object" a la lista de objetos "self.objectList" y retorna el
47 47 identificador asociado a este objeto.
48 48
49 49 Input:
50 50
51 51 object : objeto de la clase "Operation"
52 52
53 53 Return:
54 54
55 55 objId : identificador del objeto, necesario para ejecutar la operacion
56 56 """
57 57
58 58 self.objectDict[objId] = object
59 59
60 60 return objId
61 61
62 62 def operation(self, **kwargs):
63 63
64 64 """
65 65 Operacion directa sobre la data (dataOut.data). Es necesario actualizar los valores de los
66 66 atributos del objeto dataOut
67 67
68 68 Input:
69 69
70 70 **kwargs : Diccionario de argumentos de la funcion a ejecutar
71 71 """
72 72
73 73 raise ValueError, "ImplementedError"
74 74
75 75 def callMethod(self, name, **kwargs):
76 76
77 77 """
78 78 Ejecuta el metodo con el nombre "name" y con argumentos **kwargs de la propia clase.
79 79
80 80 Input:
81 81 name : nombre del metodo a ejecutar
82 82
83 83 **kwargs : diccionario con los nombres y valores de la funcion a ejecutar.
84 84
85 85 """
86 86 if name != 'run':
87 87
88 88 if name == 'init' and self.dataIn.isEmpty():
89 89 self.dataOut.flagNoData = True
90 90 return False
91 91
92 92 if name != 'init' and self.dataOut.isEmpty():
93 93 return False
94 94
95 95 methodToCall = getattr(self, name)
96 96
97 97 methodToCall(**kwargs)
98 98
99 99 if name != 'run':
100 100 return True
101 101
102 102 if self.dataOut.isEmpty():
103 103 return False
104 104
105 105 return True
106 106
107 107 def callObject(self, objId, **kwargs):
108 108
109 109 """
110 110 Ejecuta la operacion asociada al identificador del objeto "objId"
111 111
112 112 Input:
113 113
114 114 objId : identificador del objeto a ejecutar
115 115
116 116 **kwargs : diccionario con los nombres y valores de la funcion a ejecutar.
117 117
118 118 Return:
119 119
120 120 None
121 121 """
122 122
123 123 if self.dataOut.isEmpty():
124 124 return False
125 125
126 126 object = self.objectDict[objId]
127 127
128 128 object.run(self.dataOut, **kwargs)
129 129
130 130 return True
131 131
132 132 def call(self, operationConf, **kwargs):
133 133
134 134 """
135 135 Return True si ejecuta la operacion "operationConf.name" con los
136 136 argumentos "**kwargs". False si la operacion no se ha ejecutado.
137 137 La operacion puede ser de dos tipos:
138 138
139 139 1. Un metodo propio de esta clase:
140 140
141 141 operation.type = "self"
142 142
143 143 2. El metodo "run" de un objeto del tipo Operation o de un derivado de ella:
144 144 operation.type = "other".
145 145
146 146 Este objeto de tipo Operation debe de haber sido agregado antes con el metodo:
147 147 "addOperation" e identificado con el operation.id
148 148
149 149
150 150 con el id de la operacion.
151 151
152 152 Input:
153 153
154 154 Operation : Objeto del tipo operacion con los atributos: name, type y id.
155 155
156 156 """
157 157
158 158 if operationConf.type == 'self':
159 159 sts = self.callMethod(operationConf.name, **kwargs)
160 160
161 161 if operationConf.type == 'other':
162 162 sts = self.callObject(operationConf.id, **kwargs)
163 163
164 164 return sts
165 165
166 166 def setInput(self, dataIn):
167 167
168 168 self.dataIn = dataIn
169 169
170 170 def getOutput(self):
171 171
172 172 return self.dataOut
173 173
174 174 class Operation():
175 175
176 176 """
177 177 Clase base para definir las operaciones adicionales que se pueden agregar a la clase ProcessingUnit
178 178 y necesiten acumular informacion previa de los datos a procesar. De preferencia usar un buffer de
179 179 acumulacion dentro de esta clase
180 180
181 181 Ejemplo: Integraciones coherentes, necesita la informacion previa de los n perfiles anteriores (bufffer)
182 182
183 183 """
184 184
185 185 __buffer = None
186 186 __isConfig = False
187 187
188 188 def __init__(self):
189 189
190 190 pass
191 191
192 192 def run(self, dataIn, **kwargs):
193 193
194 194 """
195 195 Realiza las operaciones necesarias sobre la dataIn.data y actualiza los atributos del objeto dataIn.
196 196
197 197 Input:
198 198
199 199 dataIn : objeto del tipo JROData
200 200
201 201 Return:
202 202
203 203 None
204 204
205 205 Affected:
206 206 __buffer : buffer de recepcion de datos.
207 207
208 208 """
209 209
210 210 raise ValueError, "ImplementedError"
211 211
212 212 class VoltageProc(ProcessingUnit):
213 213
214 214
215 215 def __init__(self):
216 216
217 217 self.objectDict = {}
218 218 self.dataOut = Voltage()
219 219 self.flip = 1
220 220
221 221 def init(self):
222 222
223 223 self.dataOut.copy(self.dataIn)
224 224 # No necesita copiar en cada init() los atributos de dataIn
225 225 # la copia deberia hacerse por cada nuevo bloque de datos
226 226
227 227 def selectChannels(self, channelList):
228 228
229 229 channelIndexList = []
230 230
231 231 for channel in channelList:
232 232 index = self.dataOut.channelList.index(channel)
233 233 channelIndexList.append(index)
234 234
235 235 self.selectChannelsByIndex(channelIndexList)
236 236
237 237 def selectChannelsByIndex(self, channelIndexList):
238 238 """
239 239 Selecciona un bloque de datos en base a canales segun el channelIndexList
240 240
241 241 Input:
242 242 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
243 243
244 244 Affected:
245 245 self.dataOut.data
246 246 self.dataOut.channelIndexList
247 247 self.dataOut.nChannels
248 248 self.dataOut.m_ProcessingHeader.totalSpectra
249 249 self.dataOut.systemHeaderObj.numChannels
250 250 self.dataOut.m_ProcessingHeader.blockSize
251 251
252 252 Return:
253 253 None
254 254 """
255 255
256 256 for channelIndex in channelIndexList:
257 257 if channelIndex not in self.dataOut.channelIndexList:
258 258 print channelIndexList
259 259 raise ValueError, "The value %d in channelIndexList is not valid" %channelIndex
260 260
261 261 nChannels = len(channelIndexList)
262 262
263 263 data = self.dataOut.data[channelIndexList,:]
264 264
265 265 self.dataOut.data = data
266 266 self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
267 267 # self.dataOut.nChannels = nChannels
268 268
269 269 return 1
270 270
271 271 def selectHeights(self, minHei, maxHei):
272 272 """
273 273 Selecciona un bloque de datos en base a un grupo de valores de alturas segun el rango
274 274 minHei <= height <= maxHei
275 275
276 276 Input:
277 277 minHei : valor minimo de altura a considerar
278 278 maxHei : valor maximo de altura a considerar
279 279
280 280 Affected:
281 281 Indirectamente son cambiados varios valores a travez del metodo selectHeightsByIndex
282 282
283 283 Return:
284 284 1 si el metodo se ejecuto con exito caso contrario devuelve 0
285 285 """
286 286 if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei):
287 287 raise ValueError, "some value in (%d,%d) is not valid" % (minHei, maxHei)
288 288
289 289 if (maxHei > self.dataOut.heightList[-1]):
290 290 maxHei = self.dataOut.heightList[-1]
291 291 # raise ValueError, "some value in (%d,%d) is not valid" % (minHei, maxHei)
292 292
293 293 minIndex = 0
294 294 maxIndex = 0
295 295 heights = self.dataOut.heightList
296 296
297 297 inda = numpy.where(heights >= minHei)
298 298 indb = numpy.where(heights <= maxHei)
299 299
300 300 try:
301 301 minIndex = inda[0][0]
302 302 except:
303 303 minIndex = 0
304 304
305 305 try:
306 306 maxIndex = indb[0][-1]
307 307 except:
308 308 maxIndex = len(heights)
309 309
310 310 self.selectHeightsByIndex(minIndex, maxIndex)
311 311
312 312 return 1
313 313
314 314
315 315 def selectHeightsByIndex(self, minIndex, maxIndex):
316 316 """
317 317 Selecciona un bloque de datos en base a un grupo indices de alturas segun el rango
318 318 minIndex <= index <= maxIndex
319 319
320 320 Input:
321 321 minIndex : valor de indice minimo de altura a considerar
322 322 maxIndex : valor de indice maximo de altura a considerar
323 323
324 324 Affected:
325 325 self.dataOut.data
326 326 self.dataOut.heightList
327 327
328 328 Return:
329 329 1 si el metodo se ejecuto con exito caso contrario devuelve 0
330 330 """
331 331
332 332 if (minIndex < 0) or (minIndex > maxIndex):
333 333 raise ValueError, "some value in (%d,%d) is not valid" % (minIndex, maxIndex)
334 334
335 335 if (maxIndex >= self.dataOut.nHeights):
336 336 maxIndex = self.dataOut.nHeights-1
337 337 # raise ValueError, "some value in (%d,%d) is not valid" % (minIndex, maxIndex)
338 338
339 339 nHeights = maxIndex - minIndex + 1
340 340
341 341 #voltage
342 342 data = self.dataOut.data[:,minIndex:maxIndex+1]
343 343
344 344 firstHeight = self.dataOut.heightList[minIndex]
345 345
346 346 self.dataOut.data = data
347 347 self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex+1]
348 348
349 349 return 1
350 350
351 351
352 352 def filterByHeights(self, window):
353 353 deltaHeight = self.dataOut.heightList[1] - self.dataOut.heightList[0]
354 354
355 355 if window == None:
356 356 window = self.dataOut.radarControllerHeaderObj.txA / deltaHeight
357 357
358 358 newdelta = deltaHeight * window
359 359 r = self.dataOut.data.shape[1] % window
360 360 buffer = self.dataOut.data[:,0:self.dataOut.data.shape[1]-r]
361 361 buffer = buffer.reshape(self.dataOut.data.shape[0],self.dataOut.data.shape[1]/window,window)
362 362 buffer = numpy.sum(buffer,2)
363 363 self.dataOut.data = buffer
364 364 self.dataOut.heightList = numpy.arange(self.dataOut.heightList[0],newdelta*self.dataOut.nHeights/window-newdelta,newdelta)
365 365 self.dataOut.windowOfFilter = window
366 366
367 367 def deFlip(self):
368 368 self.dataOut.data *= self.flip
369 369 self.flip *= -1.
370 370
371 371
372 372 class CohInt(Operation):
373 373
374 374 __isConfig = False
375 375
376 376 __profIndex = 0
377 377 __withOverapping = False
378 378
379 379 __byTime = False
380 380 __initime = None
381 381 __lastdatatime = None
382 382 __integrationtime = None
383 383
384 384 __buffer = None
385 385
386 386 __dataReady = False
387 387
388 388 n = None
389 389
390 390
391 391 def __init__(self):
392 392
393 393 self.__isConfig = False
394 394
395 395 def setup(self, n=None, timeInterval=None, overlapping=False):
396 396 """
397 397 Set the parameters of the integration class.
398 398
399 399 Inputs:
400 400
401 401 n : Number of coherent integrations
402 402 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
403 403 overlapping :
404 404
405 405 """
406 406
407 407 self.__initime = None
408 408 self.__lastdatatime = 0
409 409 self.__buffer = None
410 410 self.__dataReady = False
411 411
412 412
413 413 if n == None and timeInterval == None:
414 414 raise ValueError, "n or timeInterval should be specified ..."
415 415
416 416 if n != None:
417 417 self.n = n
418 418 self.__byTime = False
419 419 else:
420 420 self.__integrationtime = timeInterval * 60. #if (type(timeInterval)!=integer) -> change this line
421 421 self.n = 9999
422 422 self.__byTime = True
423 423
424 424 if overlapping:
425 425 self.__withOverapping = True
426 426 self.__buffer = None
427 427 else:
428 428 self.__withOverapping = False
429 429 self.__buffer = 0
430 430
431 431 self.__profIndex = 0
432 432
433 433 def putData(self, data):
434 434
435 435 """
436 436 Add a profile to the __buffer and increase in one the __profileIndex
437 437
438 438 """
439 439
440 440 if not self.__withOverapping:
441 441 self.__buffer += data.copy()
442 442 self.__profIndex += 1
443 443 return
444 444
445 445 #Overlapping data
446 446 nChannels, nHeis = data.shape
447 447 data = numpy.reshape(data, (1, nChannels, nHeis))
448 448
449 449 #If the buffer is empty then it takes the data value
450 450 if self.__buffer == None:
451 451 self.__buffer = data
452 452 self.__profIndex += 1
453 453 return
454 454
455 455 #If the buffer length is lower than n then stakcing the data value
456 456 if self.__profIndex < self.n:
457 457 self.__buffer = numpy.vstack((self.__buffer, data))
458 458 self.__profIndex += 1
459 459 return
460 460
461 461 #If the buffer length is equal to n then replacing the last buffer value with the data value
462 462 self.__buffer = numpy.roll(self.__buffer, -1, axis=0)
463 463 self.__buffer[self.n-1] = data
464 464 self.__profIndex = self.n
465 465 return
466 466
467 467
468 468 def pushData(self):
469 469 """
470 470 Return the sum of the last profiles and the profiles used in the sum.
471 471
472 472 Affected:
473 473
474 474 self.__profileIndex
475 475
476 476 """
477 477
478 478 if not self.__withOverapping:
479 479 data = self.__buffer
480 480 n = self.__profIndex
481 481
482 482 self.__buffer = 0
483 483 self.__profIndex = 0
484 484
485 485 return data, n
486 486
487 487 #Integration with Overlapping
488 488 data = numpy.sum(self.__buffer, axis=0)
489 489 n = self.__profIndex
490 490
491 491 return data, n
492 492
493 493 def byProfiles(self, data):
494 494
495 495 self.__dataReady = False
496 496 avgdata = None
497 497 n = None
498 498
499 499 self.putData(data)
500 500
501 501 if self.__profIndex == self.n:
502 502
503 503 avgdata, n = self.pushData()
504 504 self.__dataReady = True
505 505
506 506 return avgdata
507 507
508 508 def byTime(self, data, datatime):
509 509
510 510 self.__dataReady = False
511 511 avgdata = None
512 512 n = None
513 513
514 514 self.putData(data)
515 515
516 516 if (datatime - self.__initime) >= self.__integrationtime:
517 517 avgdata, n = self.pushData()
518 518 self.n = n
519 519 self.__dataReady = True
520 520
521 521 return avgdata
522 522
523 523 def integrate(self, data, datatime=None):
524 524
525 525 if self.__initime == None:
526 526 self.__initime = datatime
527 527
528 528 if self.__byTime:
529 529 avgdata = self.byTime(data, datatime)
530 530 else:
531 531 avgdata = self.byProfiles(data)
532 532
533 533
534 534 self.__lastdatatime = datatime
535 535
536 536 if avgdata == None:
537 537 return None, None
538 538
539 539 avgdatatime = self.__initime
540 540
541 541 deltatime = datatime -self.__lastdatatime
542 542
543 543 if not self.__withOverapping:
544 544 self.__initime = datatime
545 545 else:
546 546 self.__initime += deltatime
547 547
548 548 return avgdata, avgdatatime
549 549
550 550 def run(self, dataOut, **kwargs):
551 551
552 552 if not self.__isConfig:
553 553 self.setup(**kwargs)
554 554 self.__isConfig = True
555 555
556 556 avgdata, avgdatatime = self.integrate(dataOut.data, dataOut.utctime)
557 557
558 558 # dataOut.timeInterval *= n
559 559 dataOut.flagNoData = True
560 560
561 561 if self.__dataReady:
562 562 dataOut.data = avgdata
563 563 dataOut.nCohInt *= self.n
564 564 dataOut.utctime = avgdatatime
565 565 dataOut.timeInterval = dataOut.ippSeconds * dataOut.nCohInt
566 566 dataOut.flagNoData = False
567 567
568 568
569 569 class Decoder(Operation):
570 570
571 571 __isConfig = False
572 572 __profIndex = 0
573 573
574 574 code = None
575 575
576 576 nCode = None
577 577 nBaud = None
578 578
579 579 def __init__(self):
580 580
581 581 self.__isConfig = False
582 582
583 def setup(self, code):
583 def setup(self, code, shape):
584 584
585 585 self.__profIndex = 0
586 586
587 587 self.code = code
588 588
589 589 self.nCode = len(code)
590 590 self.nBaud = len(code[0])
591 591
592 self.__nChannels, self.__nHeis = shape
593
594 self.__codeBuffer = numpy.zeros(self.nCode, self.__nHeis)
595
596 self.__codeBuffer[:,0:self.nBaud] = self.code[:,:]
597
598 self.fft_code = numpy.conj(numpy.fft.fft(self.__codeBuffer, axis=1))
599
600
592 601 def convolutionInFreq(self, data):
593 602
594 nchannel, ndata = data.shape
595 newcode = numpy.zeros(ndata)
596 newcode[0:self.nBaud] = self.code[self.__profIndex]
603 fft_code = self.fft_code[self.__profIndex].reshape(1,-1)
597 604
598 605 fft_data = numpy.fft.fft(data, axis=1)
599 fft_code = numpy.conj(numpy.fft.fft(newcode))
600 fft_code = fft_code.reshape(1,len(fft_code))
606
601 607
602 608 # conv = fft_data.copy()
603 609 # conv.fill(0)
604 610
605 611 conv = fft_data*fft_code
606 612
607 613 data = numpy.fft.ifft(conv,axis=1)
608 614
609 615 datadec = data[:,:-self.nBaud+1]
610 ndatadec = ndata - self.nBaud + 1
616 ndatadec = self.__nHeis - self.nBaud + 1
611 617
612 618 if self.__profIndex == self.nCode-1:
613 619 self.__profIndex = 0
614 620 return ndatadec, datadec
615 621
616 622 self.__profIndex += 1
617 623
618 624 return ndatadec, datadec
619 625
620 626
621 627 def convolutionInTime(self, data):
622 628
623 nchannel, ndata = data.shape
624 newcode = self.code[self.__profIndex]
625 ndatadec = ndata - self.nBaud + 1
629 self.__nChannels, self.__nHeis = data.shape
630 self.__codeBuffer = self.code[self.__profIndex]
631 ndatadec = self.__nHeis - self.nBaud + 1
626 632
627 datadec = numpy.zeros((nchannel, ndatadec))
633 datadec = numpy.zeros((self.__nChannels, ndatadec))
628 634
629 for i in range(nchannel):
630 datadec[i,:] = numpy.correlate(data[i,:], newcode)
635 for i in range(self.__nChannels):
636 datadec[i,:] = numpy.correlate(data[i,:], self.__codeBuffer)
631 637
632 638 if self.__profIndex == self.nCode-1:
633 639 self.__profIndex = 0
634 640 return ndatadec, datadec
635 641
636 642 self.__profIndex += 1
637 643
638 644 return ndatadec, datadec
639 645
640 646 def run(self, dataOut, code=None, nCode=None, nBaud=None, mode = 0):
641 647 if code == None:
642 648 code = dataOut.code
643 649 else:
644 650 code = numpy.array(code).reshape(nCode,nBaud)
645 651 dataOut.code = code
646 652 dataOut.nCode = nCode
647 653 dataOut.nBaud = nBaud
648 654
649 655 if code == None:
650 656 return 1
651 657
652 658 if not self.__isConfig:
653 self.setup(code)
659 self.setup(code, data.shape)
654 660 self.__isConfig = True
655 661
656 662 if mode == 0:
657 663 ndatadec, datadec = self.convolutionInFreq(dataOut.data)
658 664
659 665 if mode == 1:
660 666 print "This function is not implemented"
661 667 # ndatadec, datadec = self.convolutionInTime(dataOut.data)
662 668
663 669 dataOut.data = datadec
664 670
665 671 dataOut.heightList = dataOut.heightList[0:ndatadec]
666 672
667 673 dataOut.flagDecodeData = True #asumo q la data no esta decodificada
668 674
669 675 # dataOut.flagDeflipData = True #asumo q la data no esta sin flip
670 676
671 677
672 678 class SpectraProc(ProcessingUnit):
673 679
674 680 def __init__(self):
675 681
676 682 self.objectDict = {}
677 683 self.buffer = None
678 684 self.firstdatatime = None
679 685 self.profIndex = 0
680 686 self.dataOut = Spectra()
681 687
682 688 def __updateObjFromInput(self):
683 689
684 690 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
685 691 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
686 692 self.dataOut.channelList = self.dataIn.channelList
687 693 self.dataOut.heightList = self.dataIn.heightList
688 694 self.dataOut.dtype = numpy.dtype([('real','<f4'),('imag','<f4')])
689 695 # self.dataOut.nHeights = self.dataIn.nHeights
690 696 # self.dataOut.nChannels = self.dataIn.nChannels
691 697 self.dataOut.nBaud = self.dataIn.nBaud
692 698 self.dataOut.nCode = self.dataIn.nCode
693 699 self.dataOut.code = self.dataIn.code
694 700 self.dataOut.nProfiles = self.dataOut.nFFTPoints
695 701 # self.dataOut.channelIndexList = self.dataIn.channelIndexList
696 702 self.dataOut.flagTimeBlock = self.dataIn.flagTimeBlock
697 703 self.dataOut.utctime = self.firstdatatime
698 704 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData #asumo q la data esta decodificada
699 705 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData #asumo q la data esta sin flip
700 706 self.dataOut.flagShiftFFT = self.dataIn.flagShiftFFT
701 707 self.dataOut.nCohInt = self.dataIn.nCohInt
702 708 self.dataOut.nIncohInt = 1
703 709 self.dataOut.ippSeconds = self.dataIn.ippSeconds
704 710 self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
705 711
706 712 self.dataOut.timeInterval = self.dataIn.timeInterval*self.dataOut.nFFTPoints*self.dataOut.nIncohInt
707 713
708 714 def __getFft(self):
709 715 """
710 716 Convierte valores de Voltaje a Spectra
711 717
712 718 Affected:
713 719 self.dataOut.data_spc
714 720 self.dataOut.data_cspc
715 721 self.dataOut.data_dc
716 722 self.dataOut.heightList
717 723 self.profIndex
718 724 self.buffer
719 725 self.dataOut.flagNoData
720 726 """
721 727 fft_volt = numpy.fft.fft(self.buffer,axis=1)
722 728 fft_volt = fft_volt.astype(numpy.dtype('complex'))
723 729 dc = fft_volt[:,0,:]
724 730
725 731 #calculo de self-spectra
726 732 fft_volt = numpy.fft.fftshift(fft_volt,axes=(1,))
727 733 spc = fft_volt * numpy.conjugate(fft_volt)
728 734 spc = spc.real
729 735
730 736 blocksize = 0
731 737 blocksize += dc.size
732 738 blocksize += spc.size
733 739
734 740 cspc = None
735 741 pairIndex = 0
736 742 if self.dataOut.pairsList != None:
737 743 #calculo de cross-spectra
738 744 cspc = numpy.zeros((self.dataOut.nPairs, self.dataOut.nFFTPoints, self.dataOut.nHeights), dtype='complex')
739 745 for pair in self.dataOut.pairsList:
740 746 cspc[pairIndex,:,:] = fft_volt[pair[0],:,:] * numpy.conjugate(fft_volt[pair[1],:,:])
741 747 pairIndex += 1
742 748 blocksize += cspc.size
743 749
744 750 self.dataOut.data_spc = spc
745 751 self.dataOut.data_cspc = cspc
746 752 self.dataOut.data_dc = dc
747 753 self.dataOut.blockSize = blocksize
748 754
749 755 def init(self, nFFTPoints=None, pairsList=None):
750 756
751 757 self.dataOut.flagNoData = True
752 758
753 759 if self.dataIn.type == "Spectra":
754 760 self.dataOut.copy(self.dataIn)
755 761 return
756 762
757 763 if self.dataIn.type == "Voltage":
758 764
759 765 if nFFTPoints == None:
760 766 raise ValueError, "This SpectraProc.init() need nFFTPoints input variable"
761 767
762 768 if pairsList == None:
763 769 nPairs = 0
764 770 else:
765 771 nPairs = len(pairsList)
766 772
767 773 self.dataOut.nFFTPoints = nFFTPoints
768 774 self.dataOut.pairsList = pairsList
769 775 self.dataOut.nPairs = nPairs
770 776
771 777 if self.buffer == None:
772 778 self.buffer = numpy.zeros((self.dataIn.nChannels,
773 779 self.dataOut.nFFTPoints,
774 780 self.dataIn.nHeights),
775 781 dtype='complex')
776 782
777 783
778 784 self.buffer[:,self.profIndex,:] = self.dataIn.data.copy()
779 785 self.profIndex += 1
780 786
781 787 if self.firstdatatime == None:
782 788 self.firstdatatime = self.dataIn.utctime
783 789
784 790 if self.profIndex == self.dataOut.nFFTPoints:
785 791 self.__updateObjFromInput()
786 792 self.__getFft()
787 793
788 794 self.dataOut.flagNoData = False
789 795
790 796 self.buffer = None
791 797 self.firstdatatime = None
792 798 self.profIndex = 0
793 799
794 800 return
795 801
796 802 raise ValuError, "The type object %s is not valid"%(self.dataIn.type)
797 803
798 804 def selectChannels(self, channelList):
799 805
800 806 channelIndexList = []
801 807
802 808 for channel in channelList:
803 809 index = self.dataOut.channelList.index(channel)
804 810 channelIndexList.append(index)
805 811
806 812 self.selectChannelsByIndex(channelIndexList)
807 813
808 814 def selectChannelsByIndex(self, channelIndexList):
809 815 """
810 816 Selecciona un bloque de datos en base a canales segun el channelIndexList
811 817
812 818 Input:
813 819 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
814 820
815 821 Affected:
816 822 self.dataOut.data_spc
817 823 self.dataOut.channelIndexList
818 824 self.dataOut.nChannels
819 825
820 826 Return:
821 827 None
822 828 """
823 829
824 830 for channelIndex in channelIndexList:
825 831 if channelIndex not in self.dataOut.channelIndexList:
826 832 print channelIndexList
827 833 raise ValueError, "The value %d in channelIndexList is not valid" %channelIndex
828 834
829 835 nChannels = len(channelIndexList)
830 836
831 837 data_spc = self.dataOut.data_spc[channelIndexList,:]
832 838
833 839 self.dataOut.data_spc = data_spc
834 840 self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
835 841 # self.dataOut.nChannels = nChannels
836 842
837 843 return 1
838 844
839 845 def selectHeights(self, minHei, maxHei):
840 846 """
841 847 Selecciona un bloque de datos en base a un grupo de valores de alturas segun el rango
842 848 minHei <= height <= maxHei
843 849
844 850 Input:
845 851 minHei : valor minimo de altura a considerar
846 852 maxHei : valor maximo de altura a considerar
847 853
848 854 Affected:
849 855 Indirectamente son cambiados varios valores a travez del metodo selectHeightsByIndex
850 856
851 857 Return:
852 858 1 si el metodo se ejecuto con exito caso contrario devuelve 0
853 859 """
854 860 if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei):
855 861 raise ValueError, "some value in (%d,%d) is not valid" % (minHei, maxHei)
856 862
857 863 if (maxHei > self.dataOut.heightList[-1]):
858 864 maxHei = self.dataOut.heightList[-1]
859 865 # raise ValueError, "some value in (%d,%d) is not valid" % (minHei, maxHei)
860 866
861 867 minIndex = 0
862 868 maxIndex = 0
863 869 heights = self.dataOut.heightList
864 870
865 871 inda = numpy.where(heights >= minHei)
866 872 indb = numpy.where(heights <= maxHei)
867 873
868 874 try:
869 875 minIndex = inda[0][0]
870 876 except:
871 877 minIndex = 0
872 878
873 879 try:
874 880 maxIndex = indb[0][-1]
875 881 except:
876 882 maxIndex = len(heights)
877 883
878 884 self.selectHeightsByIndex(minIndex, maxIndex)
879 885
880 886 return 1
881 887
882 888
883 889 def selectHeightsByIndex(self, minIndex, maxIndex):
884 890 """
885 891 Selecciona un bloque de datos en base a un grupo indices de alturas segun el rango
886 892 minIndex <= index <= maxIndex
887 893
888 894 Input:
889 895 minIndex : valor de indice minimo de altura a considerar
890 896 maxIndex : valor de indice maximo de altura a considerar
891 897
892 898 Affected:
893 899 self.dataOut.data_spc
894 900 self.dataOut.data_cspc
895 901 self.dataOut.data_dc
896 902 self.dataOut.heightList
897 903
898 904 Return:
899 905 1 si el metodo se ejecuto con exito caso contrario devuelve 0
900 906 """
901 907
902 908 if (minIndex < 0) or (minIndex > maxIndex):
903 909 raise ValueError, "some value in (%d,%d) is not valid" % (minIndex, maxIndex)
904 910
905 911 if (maxIndex >= self.dataOut.nHeights):
906 912 maxIndex = self.dataOut.nHeights-1
907 913 # raise ValueError, "some value in (%d,%d) is not valid" % (minIndex, maxIndex)
908 914
909 915 nHeights = maxIndex - minIndex + 1
910 916
911 917 #Spectra
912 918 data_spc = self.dataOut.data_spc[:,:,minIndex:maxIndex+1]
913 919
914 920 data_cspc = None
915 921 if self.dataOut.data_cspc != None:
916 922 data_cspc = self.dataOut.data_cspc[:,:,minIndex:maxIndex+1]
917 923
918 924 data_dc = None
919 925 if self.dataOut.data_dc != None:
920 926 data_dc = self.dataOut.data_dc[:,minIndex:maxIndex+1]
921 927
922 928 self.dataOut.data_spc = data_spc
923 929 self.dataOut.data_cspc = data_cspc
924 930 self.dataOut.data_dc = data_dc
925 931
926 932 self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex+1]
927 933
928 934 return 1
929 935
930 936 def removeDC(self, mode = 1):
931 937
932 938 dc_index = 0
933 939 freq_index = numpy.array([-2,-1,1,2])
934 940 data_spc = self.dataOut.data_spc
935 941 data_cspc = self.dataOut.data_cspc
936 942 data_dc = self.dataOut.data_dc
937 943
938 944 if self.dataOut.flagShiftFFT:
939 945 dc_index += self.dataOut.nFFTPoints/2
940 946 freq_index += self.dataOut.nFFTPoints/2
941 947
942 948 if mode == 1:
943 949 data_spc[dc_index] = (data_spc[:,freq_index[1],:] + data_spc[:,freq_index[2],:])/2
944 950 if data_cspc != None:
945 951 data_cspc[dc_index] = (data_cspc[:,freq_index[1],:] + data_cspc[:,freq_index[2],:])/2
946 952 return 1
947 953
948 954 if mode == 2:
949 955 pass
950 956
951 957 if mode == 3:
952 958 pass
953 959
954 960 raise ValueError, "mode parameter has to be 1, 2 or 3"
955 961
956 962 def removeInterference(self):
957 963
958 964 pass
959 965
960 966
961 967 class IncohInt(Operation):
962 968
963 969
964 970 __profIndex = 0
965 971 __withOverapping = False
966 972
967 973 __byTime = False
968 974 __initime = None
969 975 __lastdatatime = None
970 976 __integrationtime = None
971 977
972 978 __buffer_spc = None
973 979 __buffer_cspc = None
974 980 __buffer_dc = None
975 981
976 982 __dataReady = False
977 983
978 984 __timeInterval = None
979 985
980 986 n = None
981 987
982 988
983 989
984 990 def __init__(self):
985 991
986 992 self.__isConfig = False
987 993
988 994 def setup(self, n=None, timeInterval=None, overlapping=False):
989 995 """
990 996 Set the parameters of the integration class.
991 997
992 998 Inputs:
993 999
994 1000 n : Number of coherent integrations
995 1001 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
996 1002 overlapping :
997 1003
998 1004 """
999 1005
1000 1006 self.__initime = None
1001 1007 self.__lastdatatime = 0
1002 1008 self.__buffer_spc = None
1003 1009 self.__buffer_cspc = None
1004 1010 self.__buffer_dc = None
1005 1011 self.__dataReady = False
1006 1012
1007 1013
1008 1014 if n == None and timeInterval == None:
1009 1015 raise ValueError, "n or timeInterval should be specified ..."
1010 1016
1011 1017 if n != None:
1012 1018 self.n = n
1013 1019 self.__byTime = False
1014 1020 else:
1015 1021 self.__integrationtime = timeInterval * 60. #if (type(timeInterval)!=integer) -> change this line
1016 1022 self.n = 9999
1017 1023 self.__byTime = True
1018 1024
1019 1025 if overlapping:
1020 1026 self.__withOverapping = True
1021 1027 else:
1022 1028 self.__withOverapping = False
1023 1029 self.__buffer_spc = 0
1024 1030 self.__buffer_cspc = 0
1025 1031 self.__buffer_dc = 0
1026 1032
1027 1033 self.__profIndex = 0
1028 1034
1029 1035 def putData(self, data_spc, data_cspc, data_dc):
1030 1036
1031 1037 """
1032 1038 Add a profile to the __buffer_spc and increase in one the __profileIndex
1033 1039
1034 1040 """
1035 1041
1036 1042 if not self.__withOverapping:
1037 1043 self.__buffer_spc += data_spc
1038 1044
1039 1045 if data_cspc == None:
1040 1046 self.__buffer_cspc = None
1041 1047 else:
1042 1048 self.__buffer_cspc += data_cspc
1043 1049
1044 1050 if data_dc == None:
1045 1051 self.__buffer_dc = None
1046 1052 else:
1047 1053 self.__buffer_dc += data_dc
1048 1054
1049 1055 self.__profIndex += 1
1050 1056 return
1051 1057
1052 1058 #Overlapping data
1053 1059 nChannels, nFFTPoints, nHeis = data_spc.shape
1054 1060 data_spc = numpy.reshape(data_spc, (1, nChannels, nFFTPoints, nHeis))
1055 1061 if data_cspc != None:
1056 1062 data_cspc = numpy.reshape(data_cspc, (1, -1, nFFTPoints, nHeis))
1057 1063 if data_dc != None:
1058 1064 data_dc = numpy.reshape(data_dc, (1, -1, nHeis))
1059 1065
1060 1066 #If the buffer is empty then it takes the data value
1061 1067 if self.__buffer_spc == None:
1062 1068 self.__buffer_spc = data_spc
1063 1069
1064 1070 if data_cspc == None:
1065 1071 self.__buffer_cspc = None
1066 1072 else:
1067 1073 self.__buffer_cspc += data_cspc
1068 1074
1069 1075 if data_dc == None:
1070 1076 self.__buffer_dc = None
1071 1077 else:
1072 1078 self.__buffer_dc += data_dc
1073 1079
1074 1080 self.__profIndex += 1
1075 1081 return
1076 1082
1077 1083 #If the buffer length is lower than n then stakcing the data value
1078 1084 if self.__profIndex < self.n:
1079 1085 self.__buffer_spc = numpy.vstack((self.__buffer_spc, data_spc))
1080 1086
1081 1087 if data_cspc != None:
1082 1088 self.__buffer_cspc = numpy.vstack((self.__buffer_cspc, data_cspc))
1083 1089
1084 1090 if data_dc != None:
1085 1091 self.__buffer_dc = numpy.vstack((self.__buffer_dc, data_dc))
1086 1092
1087 1093 self.__profIndex += 1
1088 1094 return
1089 1095
1090 1096 #If the buffer length is equal to n then replacing the last buffer value with the data value
1091 1097 self.__buffer_spc = numpy.roll(self.__buffer_spc, -1, axis=0)
1092 1098 self.__buffer_spc[self.n-1] = data_spc
1093 1099
1094 1100 if data_cspc != None:
1095 1101 self.__buffer_cspc = numpy.roll(self.__buffer_cspc, -1, axis=0)
1096 1102 self.__buffer_cspc[self.n-1] = data_cspc
1097 1103
1098 1104 if data_dc != None:
1099 1105 self.__buffer_dc = numpy.roll(self.__buffer_dc, -1, axis=0)
1100 1106 self.__buffer_dc[self.n-1] = data_dc
1101 1107
1102 1108 self.__profIndex = self.n
1103 1109 return
1104 1110
1105 1111
1106 1112 def pushData(self):
1107 1113 """
1108 1114 Return the sum of the last profiles and the profiles used in the sum.
1109 1115
1110 1116 Affected:
1111 1117
1112 1118 self.__profileIndex
1113 1119
1114 1120 """
1115 1121 data_spc = None
1116 1122 data_cspc = None
1117 1123 data_dc = None
1118 1124
1119 1125 if not self.__withOverapping:
1120 1126 data_spc = self.__buffer_spc
1121 1127 data_cspc = self.__buffer_cspc
1122 1128 data_dc = self.__buffer_dc
1123 1129
1124 1130 n = self.__profIndex
1125 1131
1126 1132 self.__buffer_spc = 0
1127 1133 self.__buffer_cspc = 0
1128 1134 self.__buffer_dc = 0
1129 1135 self.__profIndex = 0
1130 1136
1131 1137 return data_spc, data_cspc, data_dc, n
1132 1138
1133 1139 #Integration with Overlapping
1134 1140 data_spc = numpy.sum(self.__buffer_spc, axis=0)
1135 1141
1136 1142 if self.__buffer_cspc != None:
1137 1143 data_cspc = numpy.sum(self.__buffer_cspc, axis=0)
1138 1144
1139 1145 if self.__buffer_dc != None:
1140 1146 data_dc = numpy.sum(self.__buffer_dc, axis=0)
1141 1147
1142 1148 n = self.__profIndex
1143 1149
1144 1150 return data_spc, data_cspc, data_dc, n
1145 1151
1146 1152 def byProfiles(self, *args):
1147 1153
1148 1154 self.__dataReady = False
1149 1155 avgdata_spc = None
1150 1156 avgdata_cspc = None
1151 1157 avgdata_dc = None
1152 1158 n = None
1153 1159
1154 1160 self.putData(*args)
1155 1161
1156 1162 if self.__profIndex == self.n:
1157 1163
1158 1164 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1159 1165 self.__dataReady = True
1160 1166
1161 1167 return avgdata_spc, avgdata_cspc, avgdata_dc
1162 1168
1163 1169 def byTime(self, datatime, *args):
1164 1170
1165 1171 self.__dataReady = False
1166 1172 avgdata_spc = None
1167 1173 avgdata_cspc = None
1168 1174 avgdata_dc = None
1169 1175 n = None
1170 1176
1171 1177 self.putData(*args)
1172 1178
1173 1179 if (datatime - self.__initime) >= self.__integrationtime:
1174 1180 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1175 1181 self.n = n
1176 1182 self.__dataReady = True
1177 1183
1178 1184 return avgdata_spc, avgdata_cspc, avgdata_dc
1179 1185
1180 1186 def integrate(self, datatime, *args):
1181 1187
1182 1188 if self.__initime == None:
1183 1189 self.__initime = datatime
1184 1190
1185 1191 if self.__byTime:
1186 1192 avgdata_spc, avgdata_cspc, avgdata_dc = self.byTime(datatime, *args)
1187 1193 else:
1188 1194 avgdata_spc, avgdata_cspc, avgdata_dc = self.byProfiles(*args)
1189 1195
1190 1196 self.__lastdatatime = datatime
1191 1197
1192 1198 if avgdata_spc == None:
1193 1199 return None, None, None, None
1194 1200
1195 1201 avgdatatime = self.__initime
1196 1202 self.__timeInterval = (self.__lastdatatime - self.__initime)/(self.n - 1)
1197 1203
1198 1204 deltatime = datatime -self.__lastdatatime
1199 1205
1200 1206 if not self.__withOverapping:
1201 1207 self.__initime = datatime
1202 1208 else:
1203 1209 self.__initime += deltatime
1204 1210
1205 1211 return avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc
1206 1212
1207 1213 def run(self, dataOut, n=None, timeInterval=None, overlapping=False):
1208 1214
1209 1215 if not self.__isConfig:
1210 1216 self.setup(n, timeInterval, overlapping)
1211 1217 self.__isConfig = True
1212 1218
1213 1219 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(dataOut.utctime,
1214 1220 dataOut.data_spc,
1215 1221 dataOut.data_cspc,
1216 1222 dataOut.data_dc)
1217 1223
1218 1224 # dataOut.timeInterval *= n
1219 1225 dataOut.flagNoData = True
1220 1226
1221 1227 if self.__dataReady:
1222 1228
1223 1229 dataOut.data_spc = avgdata_spc
1224 1230 dataOut.data_cspc = avgdata_cspc
1225 1231 dataOut.data_dc = avgdata_dc
1226 1232
1227 1233 dataOut.nIncohInt *= self.n
1228 1234 dataOut.utctime = avgdatatime
1229 1235 #dataOut.timeInterval = dataOut.ippSeconds * dataOut.nCohInt * dataOut.nIncohInt * dataOut.nFFTPoints
1230 1236 dataOut.timeInterval = self.__timeInterval*self.n
1231 1237 dataOut.flagNoData = False
1232 1238
1233 1239 class ProfileSelector(Operation):
1234 1240
1235 1241 profileIndex = None
1236 1242 # Tamanho total de los perfiles
1237 1243 nProfiles = None
1238 1244
1239 1245 def __init__(self):
1240 1246
1241 1247 self.profileIndex = 0
1242 1248
1243 1249 def incIndex(self):
1244 1250 self.profileIndex += 1
1245 1251
1246 1252 if self.profileIndex >= self.nProfiles:
1247 1253 self.profileIndex = 0
1248 1254
1249 1255 def isProfileInRange(self, minIndex, maxIndex):
1250 1256
1251 1257 if self.profileIndex < minIndex:
1252 1258 return False
1253 1259
1254 1260 if self.profileIndex > maxIndex:
1255 1261 return False
1256 1262
1257 1263 return True
1258 1264
1259 1265 def isProfileInList(self, profileList):
1260 1266
1261 1267 if self.profileIndex not in profileList:
1262 1268 return False
1263 1269
1264 1270 return True
1265 1271
1266 1272 def run(self, dataOut, profileList=None, profileRangeList=None):
1267 1273
1268 1274 dataOut.flagNoData = True
1269 1275 self.nProfiles = dataOut.nProfiles
1270 1276
1271 1277 if profileList != None:
1272 1278 if self.isProfileInList(profileList):
1273 1279 dataOut.flagNoData = False
1274 1280
1275 1281 self.incIndex()
1276 1282 return 1
1277 1283
1278 1284
1279 1285 elif profileRangeList != None:
1280 1286 minIndex = profileRangeList[0]
1281 1287 maxIndex = profileRangeList[1]
1282 1288 if self.isProfileInRange(minIndex, maxIndex):
1283 1289 dataOut.flagNoData = False
1284 1290
1285 1291 self.incIndex()
1286 1292 return 1
1287 1293
1288 1294 else:
1289 1295 raise ValueError, "ProfileSelector needs profileList or profileRangeList"
1290 1296
1291 1297 return 0
1292 1298
General Comments 0
You need to be logged in to leave comments. Login now