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