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