##// END OF EJS Templates
Actualiza la variable "realtime" del objeto dataOut, de Voltage a Spectra
Daniel Valdez -
r408:547afa1143b4
parent child
Show More
@@ -1,1655 +1,1656
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=None, maxHei=None):
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
292 292 if minHei == None:
293 293 minHei = self.dataOut.heightList[0]
294 294
295 295 if maxHei == None:
296 296 maxHei = self.dataOut.heightList[-1]
297 297
298 298 if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei):
299 299 raise ValueError, "some value in (%d,%d) is not valid" % (minHei, maxHei)
300 300
301 301
302 302 if (maxHei > self.dataOut.heightList[-1]):
303 303 maxHei = self.dataOut.heightList[-1]
304 304 # raise ValueError, "some value in (%d,%d) is not valid" % (minHei, maxHei)
305 305
306 306 minIndex = 0
307 307 maxIndex = 0
308 308 heights = self.dataOut.heightList
309 309
310 310 inda = numpy.where(heights >= minHei)
311 311 indb = numpy.where(heights <= maxHei)
312 312
313 313 try:
314 314 minIndex = inda[0][0]
315 315 except:
316 316 minIndex = 0
317 317
318 318 try:
319 319 maxIndex = indb[0][-1]
320 320 except:
321 321 maxIndex = len(heights)
322 322
323 323 self.selectHeightsByIndex(minIndex, maxIndex)
324 324
325 325 return 1
326 326
327 327
328 328 def selectHeightsByIndex(self, minIndex, maxIndex):
329 329 """
330 330 Selecciona un bloque de datos en base a un grupo indices de alturas segun el rango
331 331 minIndex <= index <= maxIndex
332 332
333 333 Input:
334 334 minIndex : valor de indice minimo de altura a considerar
335 335 maxIndex : valor de indice maximo de altura a considerar
336 336
337 337 Affected:
338 338 self.dataOut.data
339 339 self.dataOut.heightList
340 340
341 341 Return:
342 342 1 si el metodo se ejecuto con exito caso contrario devuelve 0
343 343 """
344 344
345 345 if (minIndex < 0) or (minIndex > maxIndex):
346 346 raise ValueError, "some value in (%d,%d) is not valid" % (minIndex, maxIndex)
347 347
348 348 if (maxIndex >= self.dataOut.nHeights):
349 349 maxIndex = self.dataOut.nHeights-1
350 350 # raise ValueError, "some value in (%d,%d) is not valid" % (minIndex, maxIndex)
351 351
352 352 nHeights = maxIndex - minIndex + 1
353 353
354 354 #voltage
355 355 data = self.dataOut.data[:,minIndex:maxIndex+1]
356 356
357 357 firstHeight = self.dataOut.heightList[minIndex]
358 358
359 359 self.dataOut.data = data
360 360 self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex+1]
361 361
362 362 return 1
363 363
364 364
365 365 def filterByHeights(self, window):
366 366 deltaHeight = self.dataOut.heightList[1] - self.dataOut.heightList[0]
367 367
368 368 if window == None:
369 369 window = (self.dataOut.radarControllerHeaderObj.txA/self.dataOut.radarControllerHeaderObj.nBaud) / deltaHeight
370 370
371 371 newdelta = deltaHeight * window
372 372 r = self.dataOut.data.shape[1] % window
373 373 buffer = self.dataOut.data[:,0:self.dataOut.data.shape[1]-r]
374 374 buffer = buffer.reshape(self.dataOut.data.shape[0],self.dataOut.data.shape[1]/window,window)
375 375 buffer = numpy.sum(buffer,2)
376 376 self.dataOut.data = buffer
377 377 self.dataOut.heightList = numpy.arange(self.dataOut.heightList[0],newdelta*(self.dataOut.nHeights-r)/window,newdelta)
378 378 self.dataOut.windowOfFilter = window
379 379
380 380 def deFlip(self):
381 381 self.dataOut.data *= self.flip
382 382 self.flip *= -1.
383 383
384 384 def setRadarFrequency(self, frequency=None):
385 385 if frequency != None:
386 386 self.dataOut.frequency = frequency
387 387
388 388 return 1
389 389
390 390 class CohInt(Operation):
391 391
392 392 __isConfig = False
393 393
394 394 __profIndex = 0
395 395 __withOverapping = False
396 396
397 397 __byTime = False
398 398 __initime = None
399 399 __lastdatatime = None
400 400 __integrationtime = None
401 401
402 402 __buffer = None
403 403
404 404 __dataReady = False
405 405
406 406 n = None
407 407
408 408
409 409 def __init__(self):
410 410
411 411 self.__isConfig = False
412 412
413 413 def setup(self, n=None, timeInterval=None, overlapping=False):
414 414 """
415 415 Set the parameters of the integration class.
416 416
417 417 Inputs:
418 418
419 419 n : Number of coherent integrations
420 420 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
421 421 overlapping :
422 422
423 423 """
424 424
425 425 self.__initime = None
426 426 self.__lastdatatime = 0
427 427 self.__buffer = None
428 428 self.__dataReady = False
429 429
430 430
431 431 if n == None and timeInterval == None:
432 432 raise ValueError, "n or timeInterval should be specified ..."
433 433
434 434 if n != None:
435 435 self.n = n
436 436 self.__byTime = False
437 437 else:
438 438 self.__integrationtime = timeInterval * 60. #if (type(timeInterval)!=integer) -> change this line
439 439 self.n = 9999
440 440 self.__byTime = True
441 441
442 442 if overlapping:
443 443 self.__withOverapping = True
444 444 self.__buffer = None
445 445 else:
446 446 self.__withOverapping = False
447 447 self.__buffer = 0
448 448
449 449 self.__profIndex = 0
450 450
451 451 def putData(self, data):
452 452
453 453 """
454 454 Add a profile to the __buffer and increase in one the __profileIndex
455 455
456 456 """
457 457
458 458 if not self.__withOverapping:
459 459 self.__buffer += data.copy()
460 460 self.__profIndex += 1
461 461 return
462 462
463 463 #Overlapping data
464 464 nChannels, nHeis = data.shape
465 465 data = numpy.reshape(data, (1, nChannels, nHeis))
466 466
467 467 #If the buffer is empty then it takes the data value
468 468 if self.__buffer == None:
469 469 self.__buffer = data
470 470 self.__profIndex += 1
471 471 return
472 472
473 473 #If the buffer length is lower than n then stakcing the data value
474 474 if self.__profIndex < self.n:
475 475 self.__buffer = numpy.vstack((self.__buffer, data))
476 476 self.__profIndex += 1
477 477 return
478 478
479 479 #If the buffer length is equal to n then replacing the last buffer value with the data value
480 480 self.__buffer = numpy.roll(self.__buffer, -1, axis=0)
481 481 self.__buffer[self.n-1] = data
482 482 self.__profIndex = self.n
483 483 return
484 484
485 485
486 486 def pushData(self):
487 487 """
488 488 Return the sum of the last profiles and the profiles used in the sum.
489 489
490 490 Affected:
491 491
492 492 self.__profileIndex
493 493
494 494 """
495 495
496 496 if not self.__withOverapping:
497 497 data = self.__buffer
498 498 n = self.__profIndex
499 499
500 500 self.__buffer = 0
501 501 self.__profIndex = 0
502 502
503 503 return data, n
504 504
505 505 #Integration with Overlapping
506 506 data = numpy.sum(self.__buffer, axis=0)
507 507 n = self.__profIndex
508 508
509 509 return data, n
510 510
511 511 def byProfiles(self, data):
512 512
513 513 self.__dataReady = False
514 514 avgdata = None
515 515 n = None
516 516
517 517 self.putData(data)
518 518
519 519 if self.__profIndex == self.n:
520 520
521 521 avgdata, n = self.pushData()
522 522 self.__dataReady = True
523 523
524 524 return avgdata
525 525
526 526 def byTime(self, data, datatime):
527 527
528 528 self.__dataReady = False
529 529 avgdata = None
530 530 n = None
531 531
532 532 self.putData(data)
533 533
534 534 if (datatime - self.__initime) >= self.__integrationtime:
535 535 avgdata, n = self.pushData()
536 536 self.n = n
537 537 self.__dataReady = True
538 538
539 539 return avgdata
540 540
541 541 def integrate(self, data, datatime=None):
542 542
543 543 if self.__initime == None:
544 544 self.__initime = datatime
545 545
546 546 if self.__byTime:
547 547 avgdata = self.byTime(data, datatime)
548 548 else:
549 549 avgdata = self.byProfiles(data)
550 550
551 551
552 552 self.__lastdatatime = datatime
553 553
554 554 if avgdata == None:
555 555 return None, None
556 556
557 557 avgdatatime = self.__initime
558 558
559 559 deltatime = datatime -self.__lastdatatime
560 560
561 561 if not self.__withOverapping:
562 562 self.__initime = datatime
563 563 else:
564 564 self.__initime += deltatime
565 565
566 566 return avgdata, avgdatatime
567 567
568 568 def run(self, dataOut, **kwargs):
569 569
570 570 if not self.__isConfig:
571 571 self.setup(**kwargs)
572 572 self.__isConfig = True
573 573
574 574 avgdata, avgdatatime = self.integrate(dataOut.data, dataOut.utctime)
575 575
576 576 # dataOut.timeInterval *= n
577 577 dataOut.flagNoData = True
578 578
579 579 if self.__dataReady:
580 580 dataOut.data = avgdata
581 581 dataOut.nCohInt *= self.n
582 582 dataOut.utctime = avgdatatime
583 583 dataOut.timeInterval = dataOut.ippSeconds * dataOut.nCohInt
584 584 dataOut.flagNoData = False
585 585
586 586
587 587 class Decoder(Operation):
588 588
589 589 __isConfig = False
590 590 __profIndex = 0
591 591
592 592 code = None
593 593
594 594 nCode = None
595 595 nBaud = None
596 596
597 597 def __init__(self):
598 598
599 599 self.__isConfig = False
600 600
601 601 def setup(self, code, shape):
602 602
603 603 self.__profIndex = 0
604 604
605 605 self.code = code
606 606
607 607 self.nCode = len(code)
608 608 self.nBaud = len(code[0])
609 609
610 610 self.__nChannels, self.__nHeis = shape
611 611
612 612 __codeBuffer = numpy.zeros((self.nCode, self.__nHeis), dtype=numpy.complex)
613 613
614 614 __codeBuffer[:,0:self.nBaud] = self.code
615 615
616 616 self.fft_code = numpy.conj(numpy.fft.fft(__codeBuffer, axis=1))
617 617
618 618 self.ndatadec = self.__nHeis - self.nBaud + 1
619 619
620 620 self.datadecTime = numpy.zeros((self.__nChannels, self.ndatadec), dtype=numpy.complex)
621 621
622 622 def convolutionInFreq(self, data):
623 623
624 624 fft_code = self.fft_code[self.__profIndex].reshape(1,-1)
625 625
626 626 fft_data = numpy.fft.fft(data, axis=1)
627 627
628 628 conv = fft_data*fft_code
629 629
630 630 data = numpy.fft.ifft(conv,axis=1)
631 631
632 632 datadec = data[:,:-self.nBaud+1]
633 633
634 634 return datadec
635 635
636 636 def convolutionInFreqOpt(self, data):
637 637
638 638 fft_code = self.fft_code[self.__profIndex].reshape(1,-1)
639 639
640 640 data = cfunctions.decoder(fft_code, data)
641 641
642 642 datadec = data[:,:-self.nBaud+1]
643 643
644 644 return datadec
645 645
646 646 def convolutionInTime(self, data):
647 647
648 648 code = self.code[self.__profIndex]
649 649
650 650 for i in range(self.__nChannels):
651 651 self.datadecTime[i,:] = numpy.correlate(data[i,:], code, mode='valid')
652 652
653 653 return self.datadecTime
654 654
655 655 def run(self, dataOut, code=None, nCode=None, nBaud=None, mode = 0):
656 656
657 657 if not self.__isConfig:
658 658
659 659 if code == None:
660 660 code = dataOut.code
661 661 else:
662 662 code = numpy.array(code).reshape(nCode,nBaud)
663 663 dataOut.code = code
664 664 dataOut.nCode = nCode
665 665 dataOut.nBaud = nBaud
666 666
667 667 if code == None:
668 668 return 1
669 669
670 670 self.setup(code, dataOut.data.shape)
671 671 self.__isConfig = True
672 672
673 673 if mode == 0:
674 674 datadec = self.convolutionInTime(dataOut.data)
675 675
676 676 if mode == 1:
677 677 datadec = self.convolutionInFreq(dataOut.data)
678 678
679 679 if mode == 2:
680 680 datadec = self.convolutionInFreqOpt(dataOut.data)
681 681
682 682 dataOut.data = datadec
683 683
684 684 dataOut.heightList = dataOut.heightList[0:self.ndatadec]
685 685
686 686 dataOut.flagDecodeData = True #asumo q la data no esta decodificada
687 687
688 688 if self.__profIndex == self.nCode-1:
689 689 self.__profIndex = 0
690 690 return 1
691 691
692 692 self.__profIndex += 1
693 693
694 694 return 1
695 695 # dataOut.flagDeflipData = True #asumo q la data no esta sin flip
696 696
697 697
698 698
699 699 class SpectraProc(ProcessingUnit):
700 700
701 701 def __init__(self):
702 702
703 703 self.objectDict = {}
704 704 self.buffer = None
705 705 self.firstdatatime = None
706 706 self.profIndex = 0
707 707 self.dataOut = Spectra()
708 708
709 709 def __updateObjFromInput(self):
710 710
711 711 self.dataOut.timeZone = self.dataIn.timeZone
712 712 self.dataOut.dstFlag = self.dataIn.dstFlag
713 713 self.dataOut.errorCount = self.dataIn.errorCount
714 714 self.dataOut.useLocalTime = self.dataIn.useLocalTime
715 715
716 716 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
717 717 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
718 718 self.dataOut.channelList = self.dataIn.channelList
719 719 self.dataOut.heightList = self.dataIn.heightList
720 720 self.dataOut.dtype = numpy.dtype([('real','<f4'),('imag','<f4')])
721 721 # self.dataOut.nHeights = self.dataIn.nHeights
722 722 # self.dataOut.nChannels = self.dataIn.nChannels
723 723 self.dataOut.nBaud = self.dataIn.nBaud
724 724 self.dataOut.nCode = self.dataIn.nCode
725 725 self.dataOut.code = self.dataIn.code
726 726 self.dataOut.nProfiles = self.dataOut.nFFTPoints
727 727 # self.dataOut.channelIndexList = self.dataIn.channelIndexList
728 728 self.dataOut.flagTimeBlock = self.dataIn.flagTimeBlock
729 729 self.dataOut.utctime = self.firstdatatime
730 730 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData #asumo q la data esta decodificada
731 731 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData #asumo q la data esta sin flip
732 732 # self.dataOut.flagShiftFFT = self.dataIn.flagShiftFFT
733 733 self.dataOut.nCohInt = self.dataIn.nCohInt
734 734 self.dataOut.nIncohInt = 1
735 735 self.dataOut.ippSeconds = self.dataIn.ippSeconds
736 736 self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
737 737
738 738 self.dataOut.timeInterval = self.dataIn.timeInterval*self.dataOut.nFFTPoints*self.dataOut.nIncohInt
739 739 self.dataOut.frequency = self.dataIn.frequency
740 self.dataOut.realtime = self.dataIn.realtime
740 741
741 742 def __getFft(self):
742 743 """
743 744 Convierte valores de Voltaje a Spectra
744 745
745 746 Affected:
746 747 self.dataOut.data_spc
747 748 self.dataOut.data_cspc
748 749 self.dataOut.data_dc
749 750 self.dataOut.heightList
750 751 self.profIndex
751 752 self.buffer
752 753 self.dataOut.flagNoData
753 754 """
754 755 fft_volt = numpy.fft.fft(self.buffer,n=self.dataOut.nFFTPoints,axis=1)
755 756 fft_volt = fft_volt.astype(numpy.dtype('complex'))
756 757 dc = fft_volt[:,0,:]
757 758
758 759 #calculo de self-spectra
759 760 fft_volt = numpy.fft.fftshift(fft_volt,axes=(1,))
760 761 spc = fft_volt * numpy.conjugate(fft_volt)
761 762 spc = spc.real
762 763
763 764 blocksize = 0
764 765 blocksize += dc.size
765 766 blocksize += spc.size
766 767
767 768 cspc = None
768 769 pairIndex = 0
769 770 if self.dataOut.pairsList != None:
770 771 #calculo de cross-spectra
771 772 cspc = numpy.zeros((self.dataOut.nPairs, self.dataOut.nFFTPoints, self.dataOut.nHeights), dtype='complex')
772 773 for pair in self.dataOut.pairsList:
773 774 cspc[pairIndex,:,:] = fft_volt[pair[0],:,:] * numpy.conjugate(fft_volt[pair[1],:,:])
774 775 pairIndex += 1
775 776 blocksize += cspc.size
776 777
777 778 self.dataOut.data_spc = spc
778 779 self.dataOut.data_cspc = cspc
779 780 self.dataOut.data_dc = dc
780 781 self.dataOut.blockSize = blocksize
781 782 self.dataOut.flagShiftFFT = False
782 783
783 784 def init(self, nProfiles, nFFTPoints=None, pairsList=None):
784 785
785 786 self.dataOut.flagNoData = True
786 787
787 788 if self.dataIn.type == "Spectra":
788 789 self.dataOut.copy(self.dataIn)
789 790 return
790 791
791 792 if self.dataIn.type == "Voltage":
792 793
793 794 if nFFTPoints == None:
794 795 raise ValueError, "This SpectraProc.init() need nFFTPoints input variable"
795 796
796 797 if pairsList == None:
797 798 nPairs = 0
798 799 else:
799 800 nPairs = len(pairsList)
800 801
801 802 self.dataOut.nFFTPoints = nFFTPoints
802 803 self.dataOut.pairsList = pairsList
803 804 self.dataOut.nPairs = nPairs
804 805
805 806 if self.buffer == None:
806 807 self.buffer = numpy.zeros((self.dataIn.nChannels,
807 808 nProfiles,
808 809 self.dataIn.nHeights),
809 810 dtype='complex')
810 811
811 812
812 813 self.buffer[:,self.profIndex,:] = self.dataIn.data.copy()
813 814 self.profIndex += 1
814 815
815 816 if self.firstdatatime == None:
816 817 self.firstdatatime = self.dataIn.utctime
817 818
818 819 if self.profIndex == self.dataOut.nFFTPoints:
819 820 self.__updateObjFromInput()
820 821 self.__getFft()
821 822
822 823 self.dataOut.flagNoData = False
823 824
824 825 self.buffer = None
825 826 self.firstdatatime = None
826 827 self.profIndex = 0
827 828
828 829 return
829 830
830 831 raise ValuError, "The type object %s is not valid"%(self.dataIn.type)
831 832
832 833 def selectChannels(self, channelList):
833 834
834 835 channelIndexList = []
835 836
836 837 for channel in channelList:
837 838 index = self.dataOut.channelList.index(channel)
838 839 channelIndexList.append(index)
839 840
840 841 self.selectChannelsByIndex(channelIndexList)
841 842
842 843 def selectChannelsByIndex(self, channelIndexList):
843 844 """
844 845 Selecciona un bloque de datos en base a canales segun el channelIndexList
845 846
846 847 Input:
847 848 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
848 849
849 850 Affected:
850 851 self.dataOut.data_spc
851 852 self.dataOut.channelIndexList
852 853 self.dataOut.nChannels
853 854
854 855 Return:
855 856 None
856 857 """
857 858
858 859 for channelIndex in channelIndexList:
859 860 if channelIndex not in self.dataOut.channelIndexList:
860 861 print channelIndexList
861 862 raise ValueError, "The value %d in channelIndexList is not valid" %channelIndex
862 863
863 864 nChannels = len(channelIndexList)
864 865
865 866 data_spc = self.dataOut.data_spc[channelIndexList,:]
866 867
867 868 self.dataOut.data_spc = data_spc
868 869 self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
869 870 # self.dataOut.nChannels = nChannels
870 871
871 872 return 1
872 873
873 874 def selectHeights(self, minHei, maxHei):
874 875 """
875 876 Selecciona un bloque de datos en base a un grupo de valores de alturas segun el rango
876 877 minHei <= height <= maxHei
877 878
878 879 Input:
879 880 minHei : valor minimo de altura a considerar
880 881 maxHei : valor maximo de altura a considerar
881 882
882 883 Affected:
883 884 Indirectamente son cambiados varios valores a travez del metodo selectHeightsByIndex
884 885
885 886 Return:
886 887 1 si el metodo se ejecuto con exito caso contrario devuelve 0
887 888 """
888 889 if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei):
889 890 raise ValueError, "some value in (%d,%d) is not valid" % (minHei, maxHei)
890 891
891 892 if (maxHei > self.dataOut.heightList[-1]):
892 893 maxHei = self.dataOut.heightList[-1]
893 894 # raise ValueError, "some value in (%d,%d) is not valid" % (minHei, maxHei)
894 895
895 896 minIndex = 0
896 897 maxIndex = 0
897 898 heights = self.dataOut.heightList
898 899
899 900 inda = numpy.where(heights >= minHei)
900 901 indb = numpy.where(heights <= maxHei)
901 902
902 903 try:
903 904 minIndex = inda[0][0]
904 905 except:
905 906 minIndex = 0
906 907
907 908 try:
908 909 maxIndex = indb[0][-1]
909 910 except:
910 911 maxIndex = len(heights)
911 912
912 913 self.selectHeightsByIndex(minIndex, maxIndex)
913 914
914 915 return 1
915 916
916 917
917 918 def selectHeightsByIndex(self, minIndex, maxIndex):
918 919 """
919 920 Selecciona un bloque de datos en base a un grupo indices de alturas segun el rango
920 921 minIndex <= index <= maxIndex
921 922
922 923 Input:
923 924 minIndex : valor de indice minimo de altura a considerar
924 925 maxIndex : valor de indice maximo de altura a considerar
925 926
926 927 Affected:
927 928 self.dataOut.data_spc
928 929 self.dataOut.data_cspc
929 930 self.dataOut.data_dc
930 931 self.dataOut.heightList
931 932
932 933 Return:
933 934 1 si el metodo se ejecuto con exito caso contrario devuelve 0
934 935 """
935 936
936 937 if (minIndex < 0) or (minIndex > maxIndex):
937 938 raise ValueError, "some value in (%d,%d) is not valid" % (minIndex, maxIndex)
938 939
939 940 if (maxIndex >= self.dataOut.nHeights):
940 941 maxIndex = self.dataOut.nHeights-1
941 942 # raise ValueError, "some value in (%d,%d) is not valid" % (minIndex, maxIndex)
942 943
943 944 nHeights = maxIndex - minIndex + 1
944 945
945 946 #Spectra
946 947 data_spc = self.dataOut.data_spc[:,:,minIndex:maxIndex+1]
947 948
948 949 data_cspc = None
949 950 if self.dataOut.data_cspc != None:
950 951 data_cspc = self.dataOut.data_cspc[:,:,minIndex:maxIndex+1]
951 952
952 953 data_dc = None
953 954 if self.dataOut.data_dc != None:
954 955 data_dc = self.dataOut.data_dc[:,minIndex:maxIndex+1]
955 956
956 957 self.dataOut.data_spc = data_spc
957 958 self.dataOut.data_cspc = data_cspc
958 959 self.dataOut.data_dc = data_dc
959 960
960 961 self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex+1]
961 962
962 963 return 1
963 964
964 965 def removeDC(self, mode = 1):
965 966
966 967 dc_index = 0
967 968 freq_index = numpy.array([-2,-1,1,2])
968 969 data_spc = self.dataOut.data_spc
969 970 data_cspc = self.dataOut.data_cspc
970 971 data_dc = self.dataOut.data_dc
971 972
972 973 if self.dataOut.flagShiftFFT:
973 974 dc_index += self.dataOut.nFFTPoints/2
974 975 freq_index += self.dataOut.nFFTPoints/2
975 976
976 977 if mode == 1:
977 978 data_spc[dc_index] = (data_spc[:,freq_index[1],:] + data_spc[:,freq_index[2],:])/2
978 979 if data_cspc != None:
979 980 data_cspc[dc_index] = (data_cspc[:,freq_index[1],:] + data_cspc[:,freq_index[2],:])/2
980 981 return 1
981 982
982 983 if mode == 2:
983 984 pass
984 985
985 986 if mode == 3:
986 987 pass
987 988
988 989 raise ValueError, "mode parameter has to be 1, 2 or 3"
989 990
990 991 def removeInterference(self):
991 992
992 993 pass
993 994
994 995 def setRadarFrequency(self, frequency=None):
995 996 if frequency != None:
996 997 self.dataOut.frequency = frequency
997 998
998 999 return 1
999 1000
1000 1001
1001 1002 class IncohInt(Operation):
1002 1003
1003 1004
1004 1005 __profIndex = 0
1005 1006 __withOverapping = False
1006 1007
1007 1008 __byTime = False
1008 1009 __initime = None
1009 1010 __lastdatatime = None
1010 1011 __integrationtime = None
1011 1012
1012 1013 __buffer_spc = None
1013 1014 __buffer_cspc = None
1014 1015 __buffer_dc = None
1015 1016
1016 1017 __dataReady = False
1017 1018
1018 1019 __timeInterval = None
1019 1020
1020 1021 n = None
1021 1022
1022 1023
1023 1024
1024 1025 def __init__(self):
1025 1026
1026 1027 self.__isConfig = False
1027 1028
1028 1029 def setup(self, n=None, timeInterval=None, overlapping=False):
1029 1030 """
1030 1031 Set the parameters of the integration class.
1031 1032
1032 1033 Inputs:
1033 1034
1034 1035 n : Number of coherent integrations
1035 1036 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
1036 1037 overlapping :
1037 1038
1038 1039 """
1039 1040
1040 1041 self.__initime = None
1041 1042 self.__lastdatatime = 0
1042 1043 self.__buffer_spc = None
1043 1044 self.__buffer_cspc = None
1044 1045 self.__buffer_dc = None
1045 1046 self.__dataReady = False
1046 1047
1047 1048
1048 1049 if n == None and timeInterval == None:
1049 1050 raise ValueError, "n or timeInterval should be specified ..."
1050 1051
1051 1052 if n != None:
1052 1053 self.n = n
1053 1054 self.__byTime = False
1054 1055 else:
1055 1056 self.__integrationtime = timeInterval * 60. #if (type(timeInterval)!=integer) -> change this line
1056 1057 self.n = 9999
1057 1058 self.__byTime = True
1058 1059
1059 1060 if overlapping:
1060 1061 self.__withOverapping = True
1061 1062 else:
1062 1063 self.__withOverapping = False
1063 1064 self.__buffer_spc = 0
1064 1065 self.__buffer_cspc = 0
1065 1066 self.__buffer_dc = 0
1066 1067
1067 1068 self.__profIndex = 0
1068 1069
1069 1070 def putData(self, data_spc, data_cspc, data_dc):
1070 1071
1071 1072 """
1072 1073 Add a profile to the __buffer_spc and increase in one the __profileIndex
1073 1074
1074 1075 """
1075 1076
1076 1077 if not self.__withOverapping:
1077 1078 self.__buffer_spc += data_spc
1078 1079
1079 1080 if data_cspc == None:
1080 1081 self.__buffer_cspc = None
1081 1082 else:
1082 1083 self.__buffer_cspc += data_cspc
1083 1084
1084 1085 if data_dc == None:
1085 1086 self.__buffer_dc = None
1086 1087 else:
1087 1088 self.__buffer_dc += data_dc
1088 1089
1089 1090 self.__profIndex += 1
1090 1091 return
1091 1092
1092 1093 #Overlapping data
1093 1094 nChannels, nFFTPoints, nHeis = data_spc.shape
1094 1095 data_spc = numpy.reshape(data_spc, (1, nChannels, nFFTPoints, nHeis))
1095 1096 if data_cspc != None:
1096 1097 data_cspc = numpy.reshape(data_cspc, (1, -1, nFFTPoints, nHeis))
1097 1098 if data_dc != None:
1098 1099 data_dc = numpy.reshape(data_dc, (1, -1, nHeis))
1099 1100
1100 1101 #If the buffer is empty then it takes the data value
1101 1102 if self.__buffer_spc == None:
1102 1103 self.__buffer_spc = data_spc
1103 1104
1104 1105 if data_cspc == None:
1105 1106 self.__buffer_cspc = None
1106 1107 else:
1107 1108 self.__buffer_cspc += data_cspc
1108 1109
1109 1110 if data_dc == None:
1110 1111 self.__buffer_dc = None
1111 1112 else:
1112 1113 self.__buffer_dc += data_dc
1113 1114
1114 1115 self.__profIndex += 1
1115 1116 return
1116 1117
1117 1118 #If the buffer length is lower than n then stakcing the data value
1118 1119 if self.__profIndex < self.n:
1119 1120 self.__buffer_spc = numpy.vstack((self.__buffer_spc, data_spc))
1120 1121
1121 1122 if data_cspc != None:
1122 1123 self.__buffer_cspc = numpy.vstack((self.__buffer_cspc, data_cspc))
1123 1124
1124 1125 if data_dc != None:
1125 1126 self.__buffer_dc = numpy.vstack((self.__buffer_dc, data_dc))
1126 1127
1127 1128 self.__profIndex += 1
1128 1129 return
1129 1130
1130 1131 #If the buffer length is equal to n then replacing the last buffer value with the data value
1131 1132 self.__buffer_spc = numpy.roll(self.__buffer_spc, -1, axis=0)
1132 1133 self.__buffer_spc[self.n-1] = data_spc
1133 1134
1134 1135 if data_cspc != None:
1135 1136 self.__buffer_cspc = numpy.roll(self.__buffer_cspc, -1, axis=0)
1136 1137 self.__buffer_cspc[self.n-1] = data_cspc
1137 1138
1138 1139 if data_dc != None:
1139 1140 self.__buffer_dc = numpy.roll(self.__buffer_dc, -1, axis=0)
1140 1141 self.__buffer_dc[self.n-1] = data_dc
1141 1142
1142 1143 self.__profIndex = self.n
1143 1144 return
1144 1145
1145 1146
1146 1147 def pushData(self):
1147 1148 """
1148 1149 Return the sum of the last profiles and the profiles used in the sum.
1149 1150
1150 1151 Affected:
1151 1152
1152 1153 self.__profileIndex
1153 1154
1154 1155 """
1155 1156 data_spc = None
1156 1157 data_cspc = None
1157 1158 data_dc = None
1158 1159
1159 1160 if not self.__withOverapping:
1160 1161 data_spc = self.__buffer_spc
1161 1162 data_cspc = self.__buffer_cspc
1162 1163 data_dc = self.__buffer_dc
1163 1164
1164 1165 n = self.__profIndex
1165 1166
1166 1167 self.__buffer_spc = 0
1167 1168 self.__buffer_cspc = 0
1168 1169 self.__buffer_dc = 0
1169 1170 self.__profIndex = 0
1170 1171
1171 1172 return data_spc, data_cspc, data_dc, n
1172 1173
1173 1174 #Integration with Overlapping
1174 1175 data_spc = numpy.sum(self.__buffer_spc, axis=0)
1175 1176
1176 1177 if self.__buffer_cspc != None:
1177 1178 data_cspc = numpy.sum(self.__buffer_cspc, axis=0)
1178 1179
1179 1180 if self.__buffer_dc != None:
1180 1181 data_dc = numpy.sum(self.__buffer_dc, axis=0)
1181 1182
1182 1183 n = self.__profIndex
1183 1184
1184 1185 return data_spc, data_cspc, data_dc, n
1185 1186
1186 1187 def byProfiles(self, *args):
1187 1188
1188 1189 self.__dataReady = False
1189 1190 avgdata_spc = None
1190 1191 avgdata_cspc = None
1191 1192 avgdata_dc = None
1192 1193 n = None
1193 1194
1194 1195 self.putData(*args)
1195 1196
1196 1197 if self.__profIndex == self.n:
1197 1198
1198 1199 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1199 1200 self.__dataReady = True
1200 1201
1201 1202 return avgdata_spc, avgdata_cspc, avgdata_dc
1202 1203
1203 1204 def byTime(self, datatime, *args):
1204 1205
1205 1206 self.__dataReady = False
1206 1207 avgdata_spc = None
1207 1208 avgdata_cspc = None
1208 1209 avgdata_dc = None
1209 1210 n = None
1210 1211
1211 1212 self.putData(*args)
1212 1213
1213 1214 if (datatime - self.__initime) >= self.__integrationtime:
1214 1215 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1215 1216 self.n = n
1216 1217 self.__dataReady = True
1217 1218
1218 1219 return avgdata_spc, avgdata_cspc, avgdata_dc
1219 1220
1220 1221 def integrate(self, datatime, *args):
1221 1222
1222 1223 if self.__initime == None:
1223 1224 self.__initime = datatime
1224 1225
1225 1226 if self.__byTime:
1226 1227 avgdata_spc, avgdata_cspc, avgdata_dc = self.byTime(datatime, *args)
1227 1228 else:
1228 1229 avgdata_spc, avgdata_cspc, avgdata_dc = self.byProfiles(*args)
1229 1230
1230 1231 self.__lastdatatime = datatime
1231 1232
1232 1233 if avgdata_spc == None:
1233 1234 return None, None, None, None
1234 1235
1235 1236 avgdatatime = self.__initime
1236 1237 try:
1237 1238 self.__timeInterval = (self.__lastdatatime - self.__initime)/(self.n - 1)
1238 1239 except:
1239 1240 self.__timeInterval = self.__lastdatatime - self.__initime
1240 1241
1241 1242 deltatime = datatime -self.__lastdatatime
1242 1243
1243 1244 if not self.__withOverapping:
1244 1245 self.__initime = datatime
1245 1246 else:
1246 1247 self.__initime += deltatime
1247 1248
1248 1249 return avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc
1249 1250
1250 1251 def run(self, dataOut, n=None, timeInterval=None, overlapping=False):
1251 1252
1252 1253 if n==1:
1253 1254 dataOut.flagNoData = False
1254 1255 return
1255 1256
1256 1257 if not self.__isConfig:
1257 1258 self.setup(n, timeInterval, overlapping)
1258 1259 self.__isConfig = True
1259 1260
1260 1261 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(dataOut.utctime,
1261 1262 dataOut.data_spc,
1262 1263 dataOut.data_cspc,
1263 1264 dataOut.data_dc)
1264 1265
1265 1266 # dataOut.timeInterval *= n
1266 1267 dataOut.flagNoData = True
1267 1268
1268 1269 if self.__dataReady:
1269 1270
1270 1271 dataOut.data_spc = avgdata_spc
1271 1272 dataOut.data_cspc = avgdata_cspc
1272 1273 dataOut.data_dc = avgdata_dc
1273 1274
1274 1275 dataOut.nIncohInt *= self.n
1275 1276 dataOut.utctime = avgdatatime
1276 1277 #dataOut.timeInterval = dataOut.ippSeconds * dataOut.nCohInt * dataOut.nIncohInt * dataOut.nFFTPoints
1277 1278 dataOut.timeInterval = self.__timeInterval*self.n
1278 1279 dataOut.flagNoData = False
1279 1280
1280 1281 class ProfileSelector(Operation):
1281 1282
1282 1283 profileIndex = None
1283 1284 # Tamanho total de los perfiles
1284 1285 nProfiles = None
1285 1286
1286 1287 def __init__(self):
1287 1288
1288 1289 self.profileIndex = 0
1289 1290
1290 1291 def incIndex(self):
1291 1292 self.profileIndex += 1
1292 1293
1293 1294 if self.profileIndex >= self.nProfiles:
1294 1295 self.profileIndex = 0
1295 1296
1296 1297 def isProfileInRange(self, minIndex, maxIndex):
1297 1298
1298 1299 if self.profileIndex < minIndex:
1299 1300 return False
1300 1301
1301 1302 if self.profileIndex > maxIndex:
1302 1303 return False
1303 1304
1304 1305 return True
1305 1306
1306 1307 def isProfileInList(self, profileList):
1307 1308
1308 1309 if self.profileIndex not in profileList:
1309 1310 return False
1310 1311
1311 1312 return True
1312 1313
1313 1314 def run(self, dataOut, profileList=None, profileRangeList=None):
1314 1315
1315 1316 dataOut.flagNoData = True
1316 1317 self.nProfiles = dataOut.nProfiles
1317 1318
1318 1319 if profileList != None:
1319 1320 if self.isProfileInList(profileList):
1320 1321 dataOut.flagNoData = False
1321 1322
1322 1323 self.incIndex()
1323 1324 return 1
1324 1325
1325 1326
1326 1327 elif profileRangeList != None:
1327 1328 minIndex = profileRangeList[0]
1328 1329 maxIndex = profileRangeList[1]
1329 1330 if self.isProfileInRange(minIndex, maxIndex):
1330 1331 dataOut.flagNoData = False
1331 1332
1332 1333 self.incIndex()
1333 1334 return 1
1334 1335
1335 1336 else:
1336 1337 raise ValueError, "ProfileSelector needs profileList or profileRangeList"
1337 1338
1338 1339 return 0
1339 1340
1340 1341 class SpectraHeisProc(ProcessingUnit):
1341 1342 def __init__(self):
1342 1343 self.objectDict = {}
1343 1344 # self.buffer = None
1344 1345 # self.firstdatatime = None
1345 1346 # self.profIndex = 0
1346 1347 self.dataOut = SpectraHeis()
1347 1348
1348 1349 def __updateObjFromInput(self):
1349 1350 self.dataOut.timeZone = self.dataIn.timeZone
1350 1351 self.dataOut.dstFlag = self.dataIn.dstFlag
1351 1352 self.dataOut.errorCount = self.dataIn.errorCount
1352 1353 self.dataOut.useLocalTime = self.dataIn.useLocalTime
1353 1354
1354 1355 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()#
1355 1356 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()#
1356 1357 self.dataOut.channelList = self.dataIn.channelList
1357 1358 self.dataOut.heightList = self.dataIn.heightList
1358 1359 # self.dataOut.dtype = self.dataIn.dtype
1359 1360 self.dataOut.dtype = numpy.dtype([('real','<f4'),('imag','<f4')])
1360 1361 # self.dataOut.nHeights = self.dataIn.nHeights
1361 1362 # self.dataOut.nChannels = self.dataIn.nChannels
1362 1363 self.dataOut.nBaud = self.dataIn.nBaud
1363 1364 self.dataOut.nCode = self.dataIn.nCode
1364 1365 self.dataOut.code = self.dataIn.code
1365 1366 # self.dataOut.nProfiles = 1
1366 1367 # self.dataOut.nProfiles = self.dataOut.nFFTPoints
1367 1368 self.dataOut.nFFTPoints = self.dataIn.nHeights
1368 1369 # self.dataOut.channelIndexList = self.dataIn.channelIndexList
1369 1370 # self.dataOut.flagNoData = self.dataIn.flagNoData
1370 1371 self.dataOut.flagTimeBlock = self.dataIn.flagTimeBlock
1371 1372 self.dataOut.utctime = self.dataIn.utctime
1372 1373 # self.dataOut.utctime = self.firstdatatime
1373 1374 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData #asumo q la data esta decodificada
1374 1375 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData #asumo q la data esta sin flip
1375 1376 # self.dataOut.flagShiftFFT = self.dataIn.flagShiftFFT
1376 1377 self.dataOut.nCohInt = self.dataIn.nCohInt
1377 1378 self.dataOut.nIncohInt = 1
1378 1379 self.dataOut.ippSeconds= self.dataIn.ippSeconds
1379 1380 self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
1380 1381
1381 1382 self.dataOut.timeInterval = self.dataIn.timeInterval*self.dataOut.nIncohInt
1382 1383 # self.dataOut.set=self.dataIn.set
1383 1384 # self.dataOut.deltaHeight=self.dataIn.deltaHeight
1384 1385
1385 1386
1386 1387 def __getFft(self):
1387 1388
1388 1389 fft_volt = numpy.fft.fft(self.dataIn.data, axis=1)
1389 1390 fft_volt = numpy.fft.fftshift(fft_volt,axes=(1,))
1390 1391 spc = numpy.abs(fft_volt * numpy.conjugate(fft_volt))/(self.dataOut.nFFTPoints)
1391 1392 self.dataOut.data_spc = spc
1392 1393
1393 1394 def init(self):
1394 1395
1395 1396 self.dataOut.flagNoData = True
1396 1397
1397 1398 if self.dataIn.type == "SpectraHeis":
1398 1399 self.dataOut.copy(self.dataIn)
1399 1400 return
1400 1401
1401 1402 if self.dataIn.type == "Voltage":
1402 1403 self.__updateObjFromInput()
1403 1404 self.__getFft()
1404 1405 self.dataOut.flagNoData = False
1405 1406
1406 1407 return
1407 1408
1408 1409 raise ValuError, "The type object %s is not valid"%(self.dataIn.type)
1409 1410
1410 1411
1411 1412 def selectChannels(self, channelList):
1412 1413
1413 1414 channelIndexList = []
1414 1415
1415 1416 for channel in channelList:
1416 1417 index = self.dataOut.channelList.index(channel)
1417 1418 channelIndexList.append(index)
1418 1419
1419 1420 self.selectChannelsByIndex(channelIndexList)
1420 1421
1421 1422 def selectChannelsByIndex(self, channelIndexList):
1422 1423 """
1423 1424 Selecciona un bloque de datos en base a canales segun el channelIndexList
1424 1425
1425 1426 Input:
1426 1427 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
1427 1428
1428 1429 Affected:
1429 1430 self.dataOut.data
1430 1431 self.dataOut.channelIndexList
1431 1432 self.dataOut.nChannels
1432 1433 self.dataOut.m_ProcessingHeader.totalSpectra
1433 1434 self.dataOut.systemHeaderObj.numChannels
1434 1435 self.dataOut.m_ProcessingHeader.blockSize
1435 1436
1436 1437 Return:
1437 1438 None
1438 1439 """
1439 1440
1440 1441 for channelIndex in channelIndexList:
1441 1442 if channelIndex not in self.dataOut.channelIndexList:
1442 1443 print channelIndexList
1443 1444 raise ValueError, "The value %d in channelIndexList is not valid" %channelIndex
1444 1445
1445 1446 nChannels = len(channelIndexList)
1446 1447
1447 1448 data_spc = self.dataOut.data_spc[channelIndexList,:]
1448 1449
1449 1450 self.dataOut.data_spc = data_spc
1450 1451 self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
1451 1452
1452 1453 return 1
1453 1454
1454 1455 class IncohInt4SpectraHeis(Operation):
1455 1456
1456 1457 __isConfig = False
1457 1458
1458 1459 __profIndex = 0
1459 1460 __withOverapping = False
1460 1461
1461 1462 __byTime = False
1462 1463 __initime = None
1463 1464 __lastdatatime = None
1464 1465 __integrationtime = None
1465 1466
1466 1467 __buffer = None
1467 1468
1468 1469 __dataReady = False
1469 1470
1470 1471 n = None
1471 1472
1472 1473
1473 1474 def __init__(self):
1474 1475
1475 1476 self.__isConfig = False
1476 1477
1477 1478 def setup(self, n=None, timeInterval=None, overlapping=False):
1478 1479 """
1479 1480 Set the parameters of the integration class.
1480 1481
1481 1482 Inputs:
1482 1483
1483 1484 n : Number of coherent integrations
1484 1485 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
1485 1486 overlapping :
1486 1487
1487 1488 """
1488 1489
1489 1490 self.__initime = None
1490 1491 self.__lastdatatime = 0
1491 1492 self.__buffer = None
1492 1493 self.__dataReady = False
1493 1494
1494 1495
1495 1496 if n == None and timeInterval == None:
1496 1497 raise ValueError, "n or timeInterval should be specified ..."
1497 1498
1498 1499 if n != None:
1499 1500 self.n = n
1500 1501 self.__byTime = False
1501 1502 else:
1502 1503 self.__integrationtime = timeInterval #* 60. #if (type(timeInterval)!=integer) -> change this line
1503 1504 self.n = 9999
1504 1505 self.__byTime = True
1505 1506
1506 1507 if overlapping:
1507 1508 self.__withOverapping = True
1508 1509 self.__buffer = None
1509 1510 else:
1510 1511 self.__withOverapping = False
1511 1512 self.__buffer = 0
1512 1513
1513 1514 self.__profIndex = 0
1514 1515
1515 1516 def putData(self, data):
1516 1517
1517 1518 """
1518 1519 Add a profile to the __buffer and increase in one the __profileIndex
1519 1520
1520 1521 """
1521 1522
1522 1523 if not self.__withOverapping:
1523 1524 self.__buffer += data.copy()
1524 1525 self.__profIndex += 1
1525 1526 return
1526 1527
1527 1528 #Overlapping data
1528 1529 nChannels, nHeis = data.shape
1529 1530 data = numpy.reshape(data, (1, nChannels, nHeis))
1530 1531
1531 1532 #If the buffer is empty then it takes the data value
1532 1533 if self.__buffer == None:
1533 1534 self.__buffer = data
1534 1535 self.__profIndex += 1
1535 1536 return
1536 1537
1537 1538 #If the buffer length is lower than n then stakcing the data value
1538 1539 if self.__profIndex < self.n:
1539 1540 self.__buffer = numpy.vstack((self.__buffer, data))
1540 1541 self.__profIndex += 1
1541 1542 return
1542 1543
1543 1544 #If the buffer length is equal to n then replacing the last buffer value with the data value
1544 1545 self.__buffer = numpy.roll(self.__buffer, -1, axis=0)
1545 1546 self.__buffer[self.n-1] = data
1546 1547 self.__profIndex = self.n
1547 1548 return
1548 1549
1549 1550
1550 1551 def pushData(self):
1551 1552 """
1552 1553 Return the sum of the last profiles and the profiles used in the sum.
1553 1554
1554 1555 Affected:
1555 1556
1556 1557 self.__profileIndex
1557 1558
1558 1559 """
1559 1560
1560 1561 if not self.__withOverapping:
1561 1562 data = self.__buffer
1562 1563 n = self.__profIndex
1563 1564
1564 1565 self.__buffer = 0
1565 1566 self.__profIndex = 0
1566 1567
1567 1568 return data, n
1568 1569
1569 1570 #Integration with Overlapping
1570 1571 data = numpy.sum(self.__buffer, axis=0)
1571 1572 n = self.__profIndex
1572 1573
1573 1574 return data, n
1574 1575
1575 1576 def byProfiles(self, data):
1576 1577
1577 1578 self.__dataReady = False
1578 1579 avgdata = None
1579 1580 n = None
1580 1581
1581 1582 self.putData(data)
1582 1583
1583 1584 if self.__profIndex == self.n:
1584 1585
1585 1586 avgdata, n = self.pushData()
1586 1587 self.__dataReady = True
1587 1588
1588 1589 return avgdata
1589 1590
1590 1591 def byTime(self, data, datatime):
1591 1592
1592 1593 self.__dataReady = False
1593 1594 avgdata = None
1594 1595 n = None
1595 1596
1596 1597 self.putData(data)
1597 1598
1598 1599 if (datatime - self.__initime) >= self.__integrationtime:
1599 1600 avgdata, n = self.pushData()
1600 1601 self.n = n
1601 1602 self.__dataReady = True
1602 1603
1603 1604 return avgdata
1604 1605
1605 1606 def integrate(self, data, datatime=None):
1606 1607
1607 1608 if self.__initime == None:
1608 1609 self.__initime = datatime
1609 1610
1610 1611 if self.__byTime:
1611 1612 avgdata = self.byTime(data, datatime)
1612 1613 else:
1613 1614 avgdata = self.byProfiles(data)
1614 1615
1615 1616
1616 1617 self.__lastdatatime = datatime
1617 1618
1618 1619 if avgdata == None:
1619 1620 return None, None
1620 1621
1621 1622 avgdatatime = self.__initime
1622 1623
1623 1624 deltatime = datatime -self.__lastdatatime
1624 1625
1625 1626 if not self.__withOverapping:
1626 1627 self.__initime = datatime
1627 1628 else:
1628 1629 self.__initime += deltatime
1629 1630
1630 1631 return avgdata, avgdatatime
1631 1632
1632 1633 def run(self, dataOut, **kwargs):
1633 1634
1634 1635 if not self.__isConfig:
1635 1636 self.setup(**kwargs)
1636 1637 self.__isConfig = True
1637 1638
1638 1639 avgdata, avgdatatime = self.integrate(dataOut.data_spc, dataOut.utctime)
1639 1640
1640 1641 # dataOut.timeInterval *= n
1641 1642 dataOut.flagNoData = True
1642 1643
1643 1644 if self.__dataReady:
1644 1645 dataOut.data_spc = avgdata
1645 1646 dataOut.nIncohInt *= self.n
1646 1647 # dataOut.nCohInt *= self.n
1647 1648 dataOut.utctime = avgdatatime
1648 1649 dataOut.timeInterval = dataOut.ippSeconds * dataOut.nIncohInt
1649 1650 # dataOut.timeInterval = self.__timeInterval*self.n
1650 1651 dataOut.flagNoData = False
1651 1652
1652 1653
1653 1654
1654 1655
1655 1656 No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now