##// END OF EJS Templates
Se actualiza jroprocessing.py para que el atributo 'flagShiftFFT=False' tenga valor igual a True despues del calculo
Daniel Valdez -
r357:821c6640ce9b
parent child
Show More
@@ -1,1627 +1,1627
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 599 __codeBuffer = numpy.zeros((self.nCode, self.__nHeis), dtype=numpy.complex)
600 600
601 601 __codeBuffer[:,0:self.nBaud] = self.code
602 602
603 603 self.fft_code = numpy.conj(numpy.fft.fft(__codeBuffer, axis=1))
604 604
605 605 self.ndatadec = self.__nHeis - self.nBaud + 1
606 606
607 607 self.datadecTime = numpy.zeros((self.__nChannels, self.ndatadec), dtype=numpy.complex)
608 608
609 609 def convolutionInFreq(self, data):
610 610
611 611 fft_code = self.fft_code[self.__profIndex].reshape(1,-1)
612 612
613 613 fft_data = numpy.fft.fft(data, axis=1)
614 614
615 615 conv = fft_data*fft_code
616 616
617 617 data = numpy.fft.ifft(conv,axis=1)
618 618
619 619 datadec = data[:,:-self.nBaud+1]
620 620
621 621 return datadec
622 622
623 623 def convolutionInFreqOpt(self, data):
624 624
625 625 fft_code = self.fft_code[self.__profIndex].reshape(1,-1)
626 626
627 627 data = cfunctions.decoder(fft_code, data)
628 628
629 629 datadec = data[:,:-self.nBaud+1]
630 630
631 631 return datadec
632 632
633 633 def convolutionInTime(self, data):
634 634
635 635 code = self.code[self.__profIndex]
636 636
637 637 for i in range(self.__nChannels):
638 638 self.datadecTime[i,:] = numpy.correlate(data[i,:], code, mode='valid')
639 639
640 640 return self.datadecTime
641 641
642 642 def run(self, dataOut, code=None, nCode=None, nBaud=None, mode = 0):
643 643
644 644 if not self.__isConfig:
645 645
646 646 if code == None:
647 647 code = dataOut.code
648 648 else:
649 649 code = numpy.array(code).reshape(nCode,nBaud)
650 650 dataOut.code = code
651 651 dataOut.nCode = nCode
652 652 dataOut.nBaud = nBaud
653 653
654 654 if code == None:
655 655 return 1
656 656
657 657 self.setup(code, dataOut.data.shape)
658 658 self.__isConfig = True
659 659
660 660 if mode == 0:
661 661 datadec = self.convolutionInTime(dataOut.data)
662 662
663 663 if mode == 1:
664 664 datadec = self.convolutionInFreq(dataOut.data)
665 665
666 666 if mode == 2:
667 667 datadec = self.convolutionInFreqOpt(dataOut.data)
668 668
669 669 dataOut.data = datadec
670 670
671 671 dataOut.heightList = dataOut.heightList[0:self.ndatadec]
672 672
673 673 dataOut.flagDecodeData = True #asumo q la data no esta decodificada
674 674
675 675 if self.__profIndex == self.nCode-1:
676 676 self.__profIndex = 0
677 677 return 1
678 678
679 679 self.__profIndex += 1
680 680
681 681 return 1
682 682 # dataOut.flagDeflipData = True #asumo q la data no esta sin flip
683 683
684 684
685 685
686 686 class SpectraProc(ProcessingUnit):
687 687
688 688 def __init__(self):
689 689
690 690 self.objectDict = {}
691 691 self.buffer = None
692 692 self.firstdatatime = None
693 693 self.profIndex = 0
694 694 self.dataOut = Spectra()
695 695
696 696 def __updateObjFromInput(self):
697 697
698 698 self.dataOut.timeZone = self.dataIn.timeZone
699 699 self.dataOut.dstFlag = self.dataIn.dstFlag
700 700 self.dataOut.errorCount = self.dataIn.errorCount
701 701 self.dataOut.useLocalTime = self.dataIn.useLocalTime
702 702
703 703 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
704 704 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
705 705 self.dataOut.channelList = self.dataIn.channelList
706 706 self.dataOut.heightList = self.dataIn.heightList
707 707 self.dataOut.dtype = numpy.dtype([('real','<f4'),('imag','<f4')])
708 708 # self.dataOut.nHeights = self.dataIn.nHeights
709 709 # self.dataOut.nChannels = self.dataIn.nChannels
710 710 self.dataOut.nBaud = self.dataIn.nBaud
711 711 self.dataOut.nCode = self.dataIn.nCode
712 712 self.dataOut.code = self.dataIn.code
713 713 self.dataOut.nProfiles = self.dataOut.nFFTPoints
714 714 # self.dataOut.channelIndexList = self.dataIn.channelIndexList
715 715 self.dataOut.flagTimeBlock = self.dataIn.flagTimeBlock
716 716 self.dataOut.utctime = self.firstdatatime
717 717 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData #asumo q la data esta decodificada
718 718 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData #asumo q la data esta sin flip
719 self.dataOut.flagShiftFFT = self.dataIn.flagShiftFFT
719 # self.dataOut.flagShiftFFT = self.dataIn.flagShiftFFT
720 720 self.dataOut.nCohInt = self.dataIn.nCohInt
721 721 self.dataOut.nIncohInt = 1
722 722 self.dataOut.ippSeconds = self.dataIn.ippSeconds
723 723 self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
724 724
725 725 self.dataOut.timeInterval = self.dataIn.timeInterval*self.dataOut.nFFTPoints*self.dataOut.nIncohInt
726 726
727 727 def __getFft(self):
728 728 """
729 729 Convierte valores de Voltaje a Spectra
730 730
731 731 Affected:
732 732 self.dataOut.data_spc
733 733 self.dataOut.data_cspc
734 734 self.dataOut.data_dc
735 735 self.dataOut.heightList
736 736 self.profIndex
737 737 self.buffer
738 738 self.dataOut.flagNoData
739 739 """
740 740 fft_volt = numpy.fft.fft(self.buffer,axis=1)
741 741 fft_volt = fft_volt.astype(numpy.dtype('complex'))
742 742 dc = fft_volt[:,0,:]
743 743
744 744 #calculo de self-spectra
745 745 fft_volt = numpy.fft.fftshift(fft_volt,axes=(1,))
746 746 spc = fft_volt * numpy.conjugate(fft_volt)
747 747 spc = spc.real
748 748
749 749 blocksize = 0
750 750 blocksize += dc.size
751 751 blocksize += spc.size
752 752
753 753 cspc = None
754 754 pairIndex = 0
755 755 if self.dataOut.pairsList != None:
756 756 #calculo de cross-spectra
757 757 cspc = numpy.zeros((self.dataOut.nPairs, self.dataOut.nFFTPoints, self.dataOut.nHeights), dtype='complex')
758 758 for pair in self.dataOut.pairsList:
759 759 cspc[pairIndex,:,:] = fft_volt[pair[0],:,:] * numpy.conjugate(fft_volt[pair[1],:,:])
760 760 pairIndex += 1
761 761 blocksize += cspc.size
762 762
763 763 self.dataOut.data_spc = spc
764 764 self.dataOut.data_cspc = cspc
765 765 self.dataOut.data_dc = dc
766 766 self.dataOut.blockSize = blocksize
767 self.dataOut.flagShiftFFT = True
767 self.dataOut.flagShiftFFT = False
768 768
769 769 def init(self, nFFTPoints=None, pairsList=None):
770 770
771 771 self.dataOut.flagNoData = True
772 772
773 773 if self.dataIn.type == "Spectra":
774 774 self.dataOut.copy(self.dataIn)
775 775 return
776 776
777 777 if self.dataIn.type == "Voltage":
778 778
779 779 if nFFTPoints == None:
780 780 raise ValueError, "This SpectraProc.init() need nFFTPoints input variable"
781 781
782 782 if pairsList == None:
783 783 nPairs = 0
784 784 else:
785 785 nPairs = len(pairsList)
786 786
787 787 self.dataOut.nFFTPoints = nFFTPoints
788 788 self.dataOut.pairsList = pairsList
789 789 self.dataOut.nPairs = nPairs
790 790
791 791 if self.buffer == None:
792 792 self.buffer = numpy.zeros((self.dataIn.nChannels,
793 793 self.dataOut.nFFTPoints,
794 794 self.dataIn.nHeights),
795 795 dtype='complex')
796 796
797 797
798 798 self.buffer[:,self.profIndex,:] = self.dataIn.data.copy()
799 799 self.profIndex += 1
800 800
801 801 if self.firstdatatime == None:
802 802 self.firstdatatime = self.dataIn.utctime
803 803
804 804 if self.profIndex == self.dataOut.nFFTPoints:
805 805 self.__updateObjFromInput()
806 806 self.__getFft()
807 807
808 808 self.dataOut.flagNoData = False
809 809
810 810 self.buffer = None
811 811 self.firstdatatime = None
812 812 self.profIndex = 0
813 813
814 814 return
815 815
816 816 raise ValuError, "The type object %s is not valid"%(self.dataIn.type)
817 817
818 818 def selectChannels(self, channelList):
819 819
820 820 channelIndexList = []
821 821
822 822 for channel in channelList:
823 823 index = self.dataOut.channelList.index(channel)
824 824 channelIndexList.append(index)
825 825
826 826 self.selectChannelsByIndex(channelIndexList)
827 827
828 828 def selectChannelsByIndex(self, channelIndexList):
829 829 """
830 830 Selecciona un bloque de datos en base a canales segun el channelIndexList
831 831
832 832 Input:
833 833 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
834 834
835 835 Affected:
836 836 self.dataOut.data_spc
837 837 self.dataOut.channelIndexList
838 838 self.dataOut.nChannels
839 839
840 840 Return:
841 841 None
842 842 """
843 843
844 844 for channelIndex in channelIndexList:
845 845 if channelIndex not in self.dataOut.channelIndexList:
846 846 print channelIndexList
847 847 raise ValueError, "The value %d in channelIndexList is not valid" %channelIndex
848 848
849 849 nChannels = len(channelIndexList)
850 850
851 851 data_spc = self.dataOut.data_spc[channelIndexList,:]
852 852
853 853 self.dataOut.data_spc = data_spc
854 854 self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
855 855 # self.dataOut.nChannels = nChannels
856 856
857 857 return 1
858 858
859 859 def selectHeights(self, minHei, maxHei):
860 860 """
861 861 Selecciona un bloque de datos en base a un grupo de valores de alturas segun el rango
862 862 minHei <= height <= maxHei
863 863
864 864 Input:
865 865 minHei : valor minimo de altura a considerar
866 866 maxHei : valor maximo de altura a considerar
867 867
868 868 Affected:
869 869 Indirectamente son cambiados varios valores a travez del metodo selectHeightsByIndex
870 870
871 871 Return:
872 872 1 si el metodo se ejecuto con exito caso contrario devuelve 0
873 873 """
874 874 if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei):
875 875 raise ValueError, "some value in (%d,%d) is not valid" % (minHei, maxHei)
876 876
877 877 if (maxHei > self.dataOut.heightList[-1]):
878 878 maxHei = self.dataOut.heightList[-1]
879 879 # raise ValueError, "some value in (%d,%d) is not valid" % (minHei, maxHei)
880 880
881 881 minIndex = 0
882 882 maxIndex = 0
883 883 heights = self.dataOut.heightList
884 884
885 885 inda = numpy.where(heights >= minHei)
886 886 indb = numpy.where(heights <= maxHei)
887 887
888 888 try:
889 889 minIndex = inda[0][0]
890 890 except:
891 891 minIndex = 0
892 892
893 893 try:
894 894 maxIndex = indb[0][-1]
895 895 except:
896 896 maxIndex = len(heights)
897 897
898 898 self.selectHeightsByIndex(minIndex, maxIndex)
899 899
900 900 return 1
901 901
902 902
903 903 def selectHeightsByIndex(self, minIndex, maxIndex):
904 904 """
905 905 Selecciona un bloque de datos en base a un grupo indices de alturas segun el rango
906 906 minIndex <= index <= maxIndex
907 907
908 908 Input:
909 909 minIndex : valor de indice minimo de altura a considerar
910 910 maxIndex : valor de indice maximo de altura a considerar
911 911
912 912 Affected:
913 913 self.dataOut.data_spc
914 914 self.dataOut.data_cspc
915 915 self.dataOut.data_dc
916 916 self.dataOut.heightList
917 917
918 918 Return:
919 919 1 si el metodo se ejecuto con exito caso contrario devuelve 0
920 920 """
921 921
922 922 if (minIndex < 0) or (minIndex > maxIndex):
923 923 raise ValueError, "some value in (%d,%d) is not valid" % (minIndex, maxIndex)
924 924
925 925 if (maxIndex >= self.dataOut.nHeights):
926 926 maxIndex = self.dataOut.nHeights-1
927 927 # raise ValueError, "some value in (%d,%d) is not valid" % (minIndex, maxIndex)
928 928
929 929 nHeights = maxIndex - minIndex + 1
930 930
931 931 #Spectra
932 932 data_spc = self.dataOut.data_spc[:,:,minIndex:maxIndex+1]
933 933
934 934 data_cspc = None
935 935 if self.dataOut.data_cspc != None:
936 936 data_cspc = self.dataOut.data_cspc[:,:,minIndex:maxIndex+1]
937 937
938 938 data_dc = None
939 939 if self.dataOut.data_dc != None:
940 940 data_dc = self.dataOut.data_dc[:,minIndex:maxIndex+1]
941 941
942 942 self.dataOut.data_spc = data_spc
943 943 self.dataOut.data_cspc = data_cspc
944 944 self.dataOut.data_dc = data_dc
945 945
946 946 self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex+1]
947 947
948 948 return 1
949 949
950 950 def removeDC(self, mode = 1):
951 951
952 952 dc_index = 0
953 953 freq_index = numpy.array([-2,-1,1,2])
954 954 data_spc = self.dataOut.data_spc
955 955 data_cspc = self.dataOut.data_cspc
956 956 data_dc = self.dataOut.data_dc
957 957
958 958 if self.dataOut.flagShiftFFT:
959 959 dc_index += self.dataOut.nFFTPoints/2
960 960 freq_index += self.dataOut.nFFTPoints/2
961 961
962 962 if mode == 1:
963 963 data_spc[dc_index] = (data_spc[:,freq_index[1],:] + data_spc[:,freq_index[2],:])/2
964 964 if data_cspc != None:
965 965 data_cspc[dc_index] = (data_cspc[:,freq_index[1],:] + data_cspc[:,freq_index[2],:])/2
966 966 return 1
967 967
968 968 if mode == 2:
969 969 pass
970 970
971 971 if mode == 3:
972 972 pass
973 973
974 974 raise ValueError, "mode parameter has to be 1, 2 or 3"
975 975
976 976 def removeInterference(self):
977 977
978 978 pass
979 979
980 980
981 981 class IncohInt(Operation):
982 982
983 983
984 984 __profIndex = 0
985 985 __withOverapping = False
986 986
987 987 __byTime = False
988 988 __initime = None
989 989 __lastdatatime = None
990 990 __integrationtime = None
991 991
992 992 __buffer_spc = None
993 993 __buffer_cspc = None
994 994 __buffer_dc = None
995 995
996 996 __dataReady = False
997 997
998 998 __timeInterval = None
999 999
1000 1000 n = None
1001 1001
1002 1002
1003 1003
1004 1004 def __init__(self):
1005 1005
1006 1006 self.__isConfig = False
1007 1007
1008 1008 def setup(self, n=None, timeInterval=None, overlapping=False):
1009 1009 """
1010 1010 Set the parameters of the integration class.
1011 1011
1012 1012 Inputs:
1013 1013
1014 1014 n : Number of coherent integrations
1015 1015 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
1016 1016 overlapping :
1017 1017
1018 1018 """
1019 1019
1020 1020 self.__initime = None
1021 1021 self.__lastdatatime = 0
1022 1022 self.__buffer_spc = None
1023 1023 self.__buffer_cspc = None
1024 1024 self.__buffer_dc = None
1025 1025 self.__dataReady = False
1026 1026
1027 1027
1028 1028 if n == None and timeInterval == None:
1029 1029 raise ValueError, "n or timeInterval should be specified ..."
1030 1030
1031 1031 if n != None:
1032 1032 self.n = n
1033 1033 self.__byTime = False
1034 1034 else:
1035 1035 self.__integrationtime = timeInterval * 60. #if (type(timeInterval)!=integer) -> change this line
1036 1036 self.n = 9999
1037 1037 self.__byTime = True
1038 1038
1039 1039 if overlapping:
1040 1040 self.__withOverapping = True
1041 1041 else:
1042 1042 self.__withOverapping = False
1043 1043 self.__buffer_spc = 0
1044 1044 self.__buffer_cspc = 0
1045 1045 self.__buffer_dc = 0
1046 1046
1047 1047 self.__profIndex = 0
1048 1048
1049 1049 def putData(self, data_spc, data_cspc, data_dc):
1050 1050
1051 1051 """
1052 1052 Add a profile to the __buffer_spc and increase in one the __profileIndex
1053 1053
1054 1054 """
1055 1055
1056 1056 if not self.__withOverapping:
1057 1057 self.__buffer_spc += data_spc
1058 1058
1059 1059 if data_cspc == None:
1060 1060 self.__buffer_cspc = None
1061 1061 else:
1062 1062 self.__buffer_cspc += data_cspc
1063 1063
1064 1064 if data_dc == None:
1065 1065 self.__buffer_dc = None
1066 1066 else:
1067 1067 self.__buffer_dc += data_dc
1068 1068
1069 1069 self.__profIndex += 1
1070 1070 return
1071 1071
1072 1072 #Overlapping data
1073 1073 nChannels, nFFTPoints, nHeis = data_spc.shape
1074 1074 data_spc = numpy.reshape(data_spc, (1, nChannels, nFFTPoints, nHeis))
1075 1075 if data_cspc != None:
1076 1076 data_cspc = numpy.reshape(data_cspc, (1, -1, nFFTPoints, nHeis))
1077 1077 if data_dc != None:
1078 1078 data_dc = numpy.reshape(data_dc, (1, -1, nHeis))
1079 1079
1080 1080 #If the buffer is empty then it takes the data value
1081 1081 if self.__buffer_spc == None:
1082 1082 self.__buffer_spc = data_spc
1083 1083
1084 1084 if data_cspc == None:
1085 1085 self.__buffer_cspc = None
1086 1086 else:
1087 1087 self.__buffer_cspc += data_cspc
1088 1088
1089 1089 if data_dc == None:
1090 1090 self.__buffer_dc = None
1091 1091 else:
1092 1092 self.__buffer_dc += data_dc
1093 1093
1094 1094 self.__profIndex += 1
1095 1095 return
1096 1096
1097 1097 #If the buffer length is lower than n then stakcing the data value
1098 1098 if self.__profIndex < self.n:
1099 1099 self.__buffer_spc = numpy.vstack((self.__buffer_spc, data_spc))
1100 1100
1101 1101 if data_cspc != None:
1102 1102 self.__buffer_cspc = numpy.vstack((self.__buffer_cspc, data_cspc))
1103 1103
1104 1104 if data_dc != None:
1105 1105 self.__buffer_dc = numpy.vstack((self.__buffer_dc, data_dc))
1106 1106
1107 1107 self.__profIndex += 1
1108 1108 return
1109 1109
1110 1110 #If the buffer length is equal to n then replacing the last buffer value with the data value
1111 1111 self.__buffer_spc = numpy.roll(self.__buffer_spc, -1, axis=0)
1112 1112 self.__buffer_spc[self.n-1] = data_spc
1113 1113
1114 1114 if data_cspc != None:
1115 1115 self.__buffer_cspc = numpy.roll(self.__buffer_cspc, -1, axis=0)
1116 1116 self.__buffer_cspc[self.n-1] = data_cspc
1117 1117
1118 1118 if data_dc != None:
1119 1119 self.__buffer_dc = numpy.roll(self.__buffer_dc, -1, axis=0)
1120 1120 self.__buffer_dc[self.n-1] = data_dc
1121 1121
1122 1122 self.__profIndex = self.n
1123 1123 return
1124 1124
1125 1125
1126 1126 def pushData(self):
1127 1127 """
1128 1128 Return the sum of the last profiles and the profiles used in the sum.
1129 1129
1130 1130 Affected:
1131 1131
1132 1132 self.__profileIndex
1133 1133
1134 1134 """
1135 1135 data_spc = None
1136 1136 data_cspc = None
1137 1137 data_dc = None
1138 1138
1139 1139 if not self.__withOverapping:
1140 1140 data_spc = self.__buffer_spc
1141 1141 data_cspc = self.__buffer_cspc
1142 1142 data_dc = self.__buffer_dc
1143 1143
1144 1144 n = self.__profIndex
1145 1145
1146 1146 self.__buffer_spc = 0
1147 1147 self.__buffer_cspc = 0
1148 1148 self.__buffer_dc = 0
1149 1149 self.__profIndex = 0
1150 1150
1151 1151 return data_spc, data_cspc, data_dc, n
1152 1152
1153 1153 #Integration with Overlapping
1154 1154 data_spc = numpy.sum(self.__buffer_spc, axis=0)
1155 1155
1156 1156 if self.__buffer_cspc != None:
1157 1157 data_cspc = numpy.sum(self.__buffer_cspc, axis=0)
1158 1158
1159 1159 if self.__buffer_dc != None:
1160 1160 data_dc = numpy.sum(self.__buffer_dc, axis=0)
1161 1161
1162 1162 n = self.__profIndex
1163 1163
1164 1164 return data_spc, data_cspc, data_dc, n
1165 1165
1166 1166 def byProfiles(self, *args):
1167 1167
1168 1168 self.__dataReady = False
1169 1169 avgdata_spc = None
1170 1170 avgdata_cspc = None
1171 1171 avgdata_dc = None
1172 1172 n = None
1173 1173
1174 1174 self.putData(*args)
1175 1175
1176 1176 if self.__profIndex == self.n:
1177 1177
1178 1178 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1179 1179 self.__dataReady = True
1180 1180
1181 1181 return avgdata_spc, avgdata_cspc, avgdata_dc
1182 1182
1183 1183 def byTime(self, datatime, *args):
1184 1184
1185 1185 self.__dataReady = False
1186 1186 avgdata_spc = None
1187 1187 avgdata_cspc = None
1188 1188 avgdata_dc = None
1189 1189 n = None
1190 1190
1191 1191 self.putData(*args)
1192 1192
1193 1193 if (datatime - self.__initime) >= self.__integrationtime:
1194 1194 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1195 1195 self.n = n
1196 1196 self.__dataReady = True
1197 1197
1198 1198 return avgdata_spc, avgdata_cspc, avgdata_dc
1199 1199
1200 1200 def integrate(self, datatime, *args):
1201 1201
1202 1202 if self.__initime == None:
1203 1203 self.__initime = datatime
1204 1204
1205 1205 if self.__byTime:
1206 1206 avgdata_spc, avgdata_cspc, avgdata_dc = self.byTime(datatime, *args)
1207 1207 else:
1208 1208 avgdata_spc, avgdata_cspc, avgdata_dc = self.byProfiles(*args)
1209 1209
1210 1210 self.__lastdatatime = datatime
1211 1211
1212 1212 if avgdata_spc == None:
1213 1213 return None, None, None, None
1214 1214
1215 1215 avgdatatime = self.__initime
1216 1216 self.__timeInterval = (self.__lastdatatime - self.__initime)/(self.n - 1)
1217 1217
1218 1218 deltatime = datatime -self.__lastdatatime
1219 1219
1220 1220 if not self.__withOverapping:
1221 1221 self.__initime = datatime
1222 1222 else:
1223 1223 self.__initime += deltatime
1224 1224
1225 1225 return avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc
1226 1226
1227 1227 def run(self, dataOut, n=None, timeInterval=None, overlapping=False):
1228 1228
1229 1229 if n==1:
1230 1230 dataOut.flagNoData = False
1231 1231 return
1232 1232
1233 1233 if not self.__isConfig:
1234 1234 self.setup(n, timeInterval, overlapping)
1235 1235 self.__isConfig = True
1236 1236
1237 1237 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(dataOut.utctime,
1238 1238 dataOut.data_spc,
1239 1239 dataOut.data_cspc,
1240 1240 dataOut.data_dc)
1241 1241
1242 1242 # dataOut.timeInterval *= n
1243 1243 dataOut.flagNoData = True
1244 1244
1245 1245 if self.__dataReady:
1246 1246
1247 1247 dataOut.data_spc = avgdata_spc
1248 1248 dataOut.data_cspc = avgdata_cspc
1249 1249 dataOut.data_dc = avgdata_dc
1250 1250
1251 1251 dataOut.nIncohInt *= self.n
1252 1252 dataOut.utctime = avgdatatime
1253 1253 #dataOut.timeInterval = dataOut.ippSeconds * dataOut.nCohInt * dataOut.nIncohInt * dataOut.nFFTPoints
1254 1254 dataOut.timeInterval = self.__timeInterval*self.n
1255 1255 dataOut.flagNoData = False
1256 1256
1257 1257 class ProfileSelector(Operation):
1258 1258
1259 1259 profileIndex = None
1260 1260 # Tamanho total de los perfiles
1261 1261 nProfiles = None
1262 1262
1263 1263 def __init__(self):
1264 1264
1265 1265 self.profileIndex = 0
1266 1266
1267 1267 def incIndex(self):
1268 1268 self.profileIndex += 1
1269 1269
1270 1270 if self.profileIndex >= self.nProfiles:
1271 1271 self.profileIndex = 0
1272 1272
1273 1273 def isProfileInRange(self, minIndex, maxIndex):
1274 1274
1275 1275 if self.profileIndex < minIndex:
1276 1276 return False
1277 1277
1278 1278 if self.profileIndex > maxIndex:
1279 1279 return False
1280 1280
1281 1281 return True
1282 1282
1283 1283 def isProfileInList(self, profileList):
1284 1284
1285 1285 if self.profileIndex not in profileList:
1286 1286 return False
1287 1287
1288 1288 return True
1289 1289
1290 1290 def run(self, dataOut, profileList=None, profileRangeList=None):
1291 1291
1292 1292 dataOut.flagNoData = True
1293 1293 self.nProfiles = dataOut.nProfiles
1294 1294
1295 1295 if profileList != None:
1296 1296 if self.isProfileInList(profileList):
1297 1297 dataOut.flagNoData = False
1298 1298
1299 1299 self.incIndex()
1300 1300 return 1
1301 1301
1302 1302
1303 1303 elif profileRangeList != None:
1304 1304 minIndex = profileRangeList[0]
1305 1305 maxIndex = profileRangeList[1]
1306 1306 if self.isProfileInRange(minIndex, maxIndex):
1307 1307 dataOut.flagNoData = False
1308 1308
1309 1309 self.incIndex()
1310 1310 return 1
1311 1311
1312 1312 else:
1313 1313 raise ValueError, "ProfileSelector needs profileList or profileRangeList"
1314 1314
1315 1315 return 0
1316 1316
1317 1317 class SpectraHeisProc(ProcessingUnit):
1318 1318 def __init__(self):
1319 1319 self.objectDict = {}
1320 1320 # self.buffer = None
1321 1321 # self.firstdatatime = None
1322 1322 # self.profIndex = 0
1323 1323 self.dataOut = SpectraHeis()
1324 1324
1325 1325 def __updateObjFromInput(self):
1326 1326 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()#
1327 1327 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()#
1328 1328 self.dataOut.channelList = self.dataIn.channelList
1329 1329 self.dataOut.heightList = self.dataIn.heightList
1330 1330 # self.dataOut.dtype = self.dataIn.dtype
1331 1331 self.dataOut.dtype = numpy.dtype([('real','<f4'),('imag','<f4')])
1332 1332 # self.dataOut.nHeights = self.dataIn.nHeights
1333 1333 # self.dataOut.nChannels = self.dataIn.nChannels
1334 1334 self.dataOut.nBaud = self.dataIn.nBaud
1335 1335 self.dataOut.nCode = self.dataIn.nCode
1336 1336 self.dataOut.code = self.dataIn.code
1337 1337 # self.dataOut.nProfiles = 1
1338 1338 # self.dataOut.nProfiles = self.dataOut.nFFTPoints
1339 1339 self.dataOut.nFFTPoints = self.dataIn.nHeights
1340 1340 # self.dataOut.channelIndexList = self.dataIn.channelIndexList
1341 1341 # self.dataOut.flagNoData = self.dataIn.flagNoData
1342 1342 self.dataOut.flagTimeBlock = self.dataIn.flagTimeBlock
1343 1343 self.dataOut.utctime = self.dataIn.utctime
1344 1344 # self.dataOut.utctime = self.firstdatatime
1345 1345 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData #asumo q la data esta decodificada
1346 1346 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData #asumo q la data esta sin flip
1347 self.dataOut.flagShiftFFT = self.dataIn.flagShiftFFT
1347 # self.dataOut.flagShiftFFT = self.dataIn.flagShiftFFT
1348 1348 self.dataOut.nCohInt = self.dataIn.nCohInt
1349 1349 self.dataOut.nIncohInt = 1
1350 1350 self.dataOut.ippSeconds= self.dataIn.ippSeconds
1351 1351 self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
1352 1352
1353 1353 self.dataOut.timeInterval = self.dataIn.timeInterval*self.dataOut.nIncohInt
1354 1354 # self.dataOut.set=self.dataIn.set
1355 1355 # self.dataOut.deltaHeight=self.dataIn.deltaHeight
1356 1356
1357 1357
1358 1358 def __getFft(self):
1359 1359
1360 1360 fft_volt = numpy.fft.fft(self.dataIn.data, axis=1)
1361 1361 fft_volt = numpy.fft.fftshift(fft_volt,axes=(1,))
1362 1362 spc = numpy.abs(fft_volt * numpy.conjugate(fft_volt))/(self.dataOut.nFFTPoints)
1363 1363 self.dataOut.data_spc = spc
1364 1364
1365 1365 def init(self):
1366 1366
1367 1367 self.dataOut.flagNoData = True
1368 1368
1369 1369 if self.dataIn.type == "SpectraHeis":
1370 1370 self.dataOut.copy(self.dataIn)
1371 1371 return
1372 1372
1373 1373 if self.dataIn.type == "Voltage":
1374 1374 self.__updateObjFromInput()
1375 1375 self.__getFft()
1376 1376 self.dataOut.flagNoData = False
1377 1377
1378 1378 return
1379 1379
1380 1380 raise ValuError, "The type object %s is not valid"%(self.dataIn.type)
1381 1381
1382 1382
1383 1383 def selectChannels(self, channelList):
1384 1384
1385 1385 channelIndexList = []
1386 1386
1387 1387 for channel in channelList:
1388 1388 index = self.dataOut.channelList.index(channel)
1389 1389 channelIndexList.append(index)
1390 1390
1391 1391 self.selectChannelsByIndex(channelIndexList)
1392 1392
1393 1393 def selectChannelsByIndex(self, channelIndexList):
1394 1394 """
1395 1395 Selecciona un bloque de datos en base a canales segun el channelIndexList
1396 1396
1397 1397 Input:
1398 1398 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
1399 1399
1400 1400 Affected:
1401 1401 self.dataOut.data
1402 1402 self.dataOut.channelIndexList
1403 1403 self.dataOut.nChannels
1404 1404 self.dataOut.m_ProcessingHeader.totalSpectra
1405 1405 self.dataOut.systemHeaderObj.numChannels
1406 1406 self.dataOut.m_ProcessingHeader.blockSize
1407 1407
1408 1408 Return:
1409 1409 None
1410 1410 """
1411 1411
1412 1412 for channelIndex in channelIndexList:
1413 1413 if channelIndex not in self.dataOut.channelIndexList:
1414 1414 print channelIndexList
1415 1415 raise ValueError, "The value %d in channelIndexList is not valid" %channelIndex
1416 1416
1417 1417 nChannels = len(channelIndexList)
1418 1418
1419 1419 data_spc = self.dataOut.data_spc[channelIndexList,:]
1420 1420
1421 1421 self.dataOut.data_spc = data_spc
1422 1422 self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
1423 1423
1424 1424 return 1
1425 1425
1426 1426 class IncohInt4SpectraHeis(Operation):
1427 1427
1428 1428 __isConfig = False
1429 1429
1430 1430 __profIndex = 0
1431 1431 __withOverapping = False
1432 1432
1433 1433 __byTime = False
1434 1434 __initime = None
1435 1435 __lastdatatime = None
1436 1436 __integrationtime = None
1437 1437
1438 1438 __buffer = None
1439 1439
1440 1440 __dataReady = False
1441 1441
1442 1442 n = None
1443 1443
1444 1444
1445 1445 def __init__(self):
1446 1446
1447 1447 self.__isConfig = False
1448 1448
1449 1449 def setup(self, n=None, timeInterval=None, overlapping=False):
1450 1450 """
1451 1451 Set the parameters of the integration class.
1452 1452
1453 1453 Inputs:
1454 1454
1455 1455 n : Number of coherent integrations
1456 1456 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
1457 1457 overlapping :
1458 1458
1459 1459 """
1460 1460
1461 1461 self.__initime = None
1462 1462 self.__lastdatatime = 0
1463 1463 self.__buffer = None
1464 1464 self.__dataReady = False
1465 1465
1466 1466
1467 1467 if n == None and timeInterval == None:
1468 1468 raise ValueError, "n or timeInterval should be specified ..."
1469 1469
1470 1470 if n != None:
1471 1471 self.n = n
1472 1472 self.__byTime = False
1473 1473 else:
1474 1474 self.__integrationtime = timeInterval #* 60. #if (type(timeInterval)!=integer) -> change this line
1475 1475 self.n = 9999
1476 1476 self.__byTime = True
1477 1477
1478 1478 if overlapping:
1479 1479 self.__withOverapping = True
1480 1480 self.__buffer = None
1481 1481 else:
1482 1482 self.__withOverapping = False
1483 1483 self.__buffer = 0
1484 1484
1485 1485 self.__profIndex = 0
1486 1486
1487 1487 def putData(self, data):
1488 1488
1489 1489 """
1490 1490 Add a profile to the __buffer and increase in one the __profileIndex
1491 1491
1492 1492 """
1493 1493
1494 1494 if not self.__withOverapping:
1495 1495 self.__buffer += data.copy()
1496 1496 self.__profIndex += 1
1497 1497 return
1498 1498
1499 1499 #Overlapping data
1500 1500 nChannels, nHeis = data.shape
1501 1501 data = numpy.reshape(data, (1, nChannels, nHeis))
1502 1502
1503 1503 #If the buffer is empty then it takes the data value
1504 1504 if self.__buffer == None:
1505 1505 self.__buffer = data
1506 1506 self.__profIndex += 1
1507 1507 return
1508 1508
1509 1509 #If the buffer length is lower than n then stakcing the data value
1510 1510 if self.__profIndex < self.n:
1511 1511 self.__buffer = numpy.vstack((self.__buffer, data))
1512 1512 self.__profIndex += 1
1513 1513 return
1514 1514
1515 1515 #If the buffer length is equal to n then replacing the last buffer value with the data value
1516 1516 self.__buffer = numpy.roll(self.__buffer, -1, axis=0)
1517 1517 self.__buffer[self.n-1] = data
1518 1518 self.__profIndex = self.n
1519 1519 return
1520 1520
1521 1521
1522 1522 def pushData(self):
1523 1523 """
1524 1524 Return the sum of the last profiles and the profiles used in the sum.
1525 1525
1526 1526 Affected:
1527 1527
1528 1528 self.__profileIndex
1529 1529
1530 1530 """
1531 1531
1532 1532 if not self.__withOverapping:
1533 1533 data = self.__buffer
1534 1534 n = self.__profIndex
1535 1535
1536 1536 self.__buffer = 0
1537 1537 self.__profIndex = 0
1538 1538
1539 1539 return data, n
1540 1540
1541 1541 #Integration with Overlapping
1542 1542 data = numpy.sum(self.__buffer, axis=0)
1543 1543 n = self.__profIndex
1544 1544
1545 1545 return data, n
1546 1546
1547 1547 def byProfiles(self, data):
1548 1548
1549 1549 self.__dataReady = False
1550 1550 avgdata = None
1551 1551 n = None
1552 1552
1553 1553 self.putData(data)
1554 1554
1555 1555 if self.__profIndex == self.n:
1556 1556
1557 1557 avgdata, n = self.pushData()
1558 1558 self.__dataReady = True
1559 1559
1560 1560 return avgdata
1561 1561
1562 1562 def byTime(self, data, datatime):
1563 1563
1564 1564 self.__dataReady = False
1565 1565 avgdata = None
1566 1566 n = None
1567 1567
1568 1568 self.putData(data)
1569 1569
1570 1570 if (datatime - self.__initime) >= self.__integrationtime:
1571 1571 avgdata, n = self.pushData()
1572 1572 self.n = n
1573 1573 self.__dataReady = True
1574 1574
1575 1575 return avgdata
1576 1576
1577 1577 def integrate(self, data, datatime=None):
1578 1578
1579 1579 if self.__initime == None:
1580 1580 self.__initime = datatime
1581 1581
1582 1582 if self.__byTime:
1583 1583 avgdata = self.byTime(data, datatime)
1584 1584 else:
1585 1585 avgdata = self.byProfiles(data)
1586 1586
1587 1587
1588 1588 self.__lastdatatime = datatime
1589 1589
1590 1590 if avgdata == None:
1591 1591 return None, None
1592 1592
1593 1593 avgdatatime = self.__initime
1594 1594
1595 1595 deltatime = datatime -self.__lastdatatime
1596 1596
1597 1597 if not self.__withOverapping:
1598 1598 self.__initime = datatime
1599 1599 else:
1600 1600 self.__initime += deltatime
1601 1601
1602 1602 return avgdata, avgdatatime
1603 1603
1604 1604 def run(self, dataOut, **kwargs):
1605 1605
1606 1606 if not self.__isConfig:
1607 1607 self.setup(**kwargs)
1608 1608 self.__isConfig = True
1609 1609
1610 1610 avgdata, avgdatatime = self.integrate(dataOut.data_spc, dataOut.utctime)
1611 1611
1612 1612 # dataOut.timeInterval *= n
1613 1613 dataOut.flagNoData = True
1614 1614
1615 1615 if self.__dataReady:
1616 1616 dataOut.data_spc = avgdata
1617 1617 dataOut.nIncohInt *= self.n
1618 1618 # dataOut.nCohInt *= self.n
1619 1619 dataOut.utctime = avgdatatime
1620 1620 dataOut.timeInterval = dataOut.ippSeconds * dataOut.nIncohInt
1621 1621 # dataOut.timeInterval = self.__timeInterval*self.n
1622 1622 dataOut.flagNoData = False
1623 1623
1624 1624
1625 1625
1626 1626
1627 1627 No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now