##// END OF EJS Templates
Bux fixed: El calculo del intervalo del tiempo ahora incluye el numero de puntos de FFT
Miguel Valdez -
r202:a95dc414d095
parent child
Show More
@@ -1,836 +1,836
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
220 220 def init(self):
221 221
222 222 self.dataOut.copy(self.dataIn)
223 223 # No necesita copiar en cada init() los atributos de dataIn
224 224 # la copia deberia hacerse por cada nuevo bloque de datos
225 225
226 226 def selectChannels(self, channelList):
227 227
228 228 channelIndexList = []
229 229
230 230 for channel in channelList:
231 231 index = self.dataOut.channelList.index(channel)
232 232 channelIndexList.append(index)
233 233
234 234 self.selectChannelsByIndex(channelIndexList)
235 235
236 236 def selectChannelsByIndex(self, channelIndexList):
237 237 """
238 238 Selecciona un bloque de datos en base a canales segun el channelIndexList
239 239
240 240 Input:
241 241 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
242 242
243 243 Affected:
244 244 self.dataOut.data
245 245 self.dataOut.channelIndexList
246 246 self.dataOut.nChannels
247 247 self.dataOut.m_ProcessingHeader.totalSpectra
248 248 self.dataOut.systemHeaderObj.numChannels
249 249 self.dataOut.m_ProcessingHeader.blockSize
250 250
251 251 Return:
252 252 None
253 253 """
254 254
255 255 for channelIndex in channelIndexList:
256 256 if channelIndex not in self.dataOut.channelIndexList:
257 257 print channelIndexList
258 258 raise ValueError, "The value %d in channelIndexList is not valid" %channelIndex
259 259
260 260 nChannels = len(channelIndexList)
261 261
262 262 data = self.dataOut.data[channelIndexList,:]
263 263
264 264 self.dataOut.data = data
265 265 self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
266 266 # self.dataOut.nChannels = nChannels
267 267
268 268 return 1
269 269
270 270 class CohInt(Operation):
271 271
272 272 __profIndex = 0
273 273 __withOverapping = False
274 274
275 275 __byTime = False
276 276 __initime = None
277 277 __lastdatatime = None
278 278 __integrationtime = None
279 279
280 280 __buffer = None
281 281
282 282 __dataReady = False
283 283
284 284 n = None
285 285
286 286
287 287 def __init__(self):
288 288
289 289 self.__isConfig = False
290 290
291 291 def setup(self, n=None, timeInterval=None, overlapping=False):
292 292 """
293 293 Set the parameters of the integration class.
294 294
295 295 Inputs:
296 296
297 297 n : Number of coherent integrations
298 298 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
299 299 overlapping :
300 300
301 301 """
302 302
303 303 self.__initime = None
304 304 self.__lastdatatime = 0
305 305 self.__buffer = None
306 306 self.__dataReady = False
307 307
308 308
309 309 if n == None and timeInterval == None:
310 310 raise ValueError, "n or timeInterval should be specified ..."
311 311
312 312 if n != None:
313 313 self.n = n
314 314 self.__byTime = False
315 315 else:
316 316 self.__integrationtime = timeInterval * 60. #if (type(timeInterval)!=integer) -> change this line
317 317 self.n = 9999
318 318 self.__byTime = True
319 319
320 320 if overlapping:
321 321 self.__withOverapping = True
322 322 self.__buffer = None
323 323 else:
324 324 self.__withOverapping = False
325 325 self.__buffer = 0
326 326
327 327 self.__profIndex = 0
328 328
329 329 def putData(self, data):
330 330
331 331 """
332 332 Add a profile to the __buffer and increase in one the __profileIndex
333 333
334 334 """
335 335
336 336 if not self.__withOverapping:
337 337 self.__buffer += data.copy()
338 338 self.__profIndex += 1
339 339 return
340 340
341 341 #Overlapping data
342 342 nChannels, nHeis = data.shape
343 343 data = numpy.reshape(data, (1, nChannels, nHeis))
344 344
345 345 #If the buffer is empty then it takes the data value
346 346 if self.__buffer == None:
347 347 self.__buffer = data
348 348 self.__profIndex += 1
349 349 return
350 350
351 351 #If the buffer length is lower than n then stakcing the data value
352 352 if self.__profIndex < self.n:
353 353 self.__buffer = numpy.vstack((self.__buffer, data))
354 354 self.__profIndex += 1
355 355 return
356 356
357 357 #If the buffer length is equal to n then replacing the last buffer value with the data value
358 358 self.__buffer = numpy.roll(self.__buffer, -1, axis=0)
359 359 self.__buffer[self.n-1] = data
360 360 self.__profIndex = self.n
361 361 return
362 362
363 363
364 364 def pushData(self):
365 365 """
366 366 Return the sum of the last profiles and the profiles used in the sum.
367 367
368 368 Affected:
369 369
370 370 self.__profileIndex
371 371
372 372 """
373 373
374 374 if not self.__withOverapping:
375 375 data = self.__buffer
376 376 n = self.__profIndex
377 377
378 378 self.__buffer = 0
379 379 self.__profIndex = 0
380 380
381 381 return data, n
382 382
383 383 #Integration with Overlapping
384 384 data = numpy.sum(self.__buffer, axis=0)
385 385 n = self.__profIndex
386 386
387 387 return data, n
388 388
389 389 def byProfiles(self, data):
390 390
391 391 self.__dataReady = False
392 392 avgdata = None
393 393 n = None
394 394
395 395 self.putData(data)
396 396
397 397 if self.__profIndex == self.n:
398 398
399 399 avgdata, n = self.pushData()
400 400 self.__dataReady = True
401 401
402 402 return avgdata
403 403
404 404 def byTime(self, data, datatime):
405 405
406 406 self.__dataReady = False
407 407 avgdata = None
408 408 n = None
409 409
410 410 self.putData(data)
411 411
412 412 if (datatime - self.__initime) >= self.__integrationtime:
413 413 avgdata, n = self.pushData()
414 414 self.n = n
415 415 self.__dataReady = True
416 416
417 417 return avgdata
418 418
419 419 def integrate(self, data, datatime=None):
420 420
421 421 if self.__initime == None:
422 422 self.__initime = datatime
423 423
424 424 if self.__byTime:
425 425 avgdata = self.byTime(data, datatime)
426 426 else:
427 427 avgdata = self.byProfiles(data)
428 428
429 429
430 430 self.__lastdatatime = datatime
431 431
432 432 if avgdata == None:
433 433 return None, None
434 434
435 435 avgdatatime = self.__initime
436 436
437 437 deltatime = datatime -self.__lastdatatime
438 438
439 439 if not self.__withOverapping:
440 440 self.__initime = datatime
441 441 else:
442 442 self.__initime += deltatime
443 443
444 444 return avgdata, avgdatatime
445 445
446 446 def run(self, dataOut, n=None, timeInterval=None, overlapping=False):
447 447
448 448 if not self.__isConfig:
449 449 self.setup(n, timeInterval, overlapping)
450 450 self.__isConfig = True
451 451
452 452 avgdata, avgdatatime = self.integrate(dataOut.data, dataOut.utctime)
453 453
454 454 # dataOut.timeInterval *= n
455 455 dataOut.flagNoData = True
456 456
457 457 if self.__dataReady:
458 458 dataOut.data = avgdata
459 459 dataOut.nCohInt *= self.n
460 460 dataOut.utctime = avgdatatime
461 461 dataOut.timeInterval = dataOut.ippSeconds * dataOut.nCohInt
462 462 dataOut.flagNoData = False
463 463
464 464
465 465 class SpectraProc(ProcessingUnit):
466 466
467 467 def __init__(self):
468 468
469 469 self.objectDict = {}
470 470 self.buffer = None
471 471 self.firstdatatime = None
472 472 self.profIndex = 0
473 473 self.dataOut = Spectra()
474 474
475 475 def __updateObjFromInput(self):
476 476
477 477 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
478 478 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
479 479 self.dataOut.channelList = self.dataIn.channelList
480 480 self.dataOut.heightList = self.dataIn.heightList
481 481 self.dataOut.dtype = self.dataIn.dtype
482 482 self.dataOut.nHeights = self.dataIn.nHeights
483 483 # self.dataOut.nChannels = self.dataIn.nChannels
484 484 self.dataOut.nBaud = self.dataIn.nBaud
485 485 self.dataOut.nCode = self.dataIn.nCode
486 486 self.dataOut.code = self.dataIn.code
487 487 self.dataOut.nProfiles = self.dataOut.nFFTPoints
488 488 # self.dataOut.channelIndexList = self.dataIn.channelIndexList
489 489 self.dataOut.flagTimeBlock = self.dataIn.flagTimeBlock
490 490 self.dataOut.utctime = self.firstdatatime
491 491 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData #asumo q la data esta decodificada
492 492 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData #asumo q la data esta sin flip
493 493 self.dataOut.flagShiftFFT = self.dataIn.flagShiftFFT
494 494 self.dataOut.nCohInt = self.dataIn.nCohInt
495 495 self.dataOut.nIncohInt = 1
496 496 self.dataOut.ippSeconds = self.dataIn.ippSeconds
497 497 self.dataOut.timeInterval = self.dataIn.timeInterval*self.dataOut.nFFTPoints
498 498
499 499 def __getFft(self):
500 500 """
501 501 Convierte valores de Voltaje a Spectra
502 502
503 503 Affected:
504 504 self.dataOut.data_spc
505 505 self.dataOut.data_cspc
506 506 self.dataOut.data_dc
507 507 self.dataOut.heightList
508 508 self.dataOut.m_BasicHeader
509 509 self.dataOut.m_ProcessingHeader
510 510 self.dataOut.radarControllerHeaderObj
511 511 self.dataOut.systemHeaderObj
512 512 self.profIndex
513 513 self.buffer
514 514 self.dataOut.flagNoData
515 515 self.dataOut.dtype
516 516 self.dataOut.nPairs
517 517 self.dataOut.nChannels
518 518 self.dataOut.nProfiles
519 519 self.dataOut.systemHeaderObj.numChannels
520 520 self.dataOut.m_ProcessingHeader.totalSpectra
521 521 self.dataOut.m_ProcessingHeader.profilesPerBlock
522 522 self.dataOut.m_ProcessingHeader.numHeights
523 523 self.dataOut.m_ProcessingHeader.spectraComb
524 524 self.dataOut.m_ProcessingHeader.shif_fft
525 525 """
526 526 fft_volt = numpy.fft.fft(self.buffer,axis=1)
527 527 dc = fft_volt[:,0,:]
528 528
529 529 #calculo de self-spectra
530 530 fft_volt = numpy.fft.fftshift(fft_volt,axes=(1,))
531 531 spc = fft_volt * numpy.conjugate(fft_volt)
532 532 spc = spc.real
533 533
534 534 blocksize = 0
535 535 blocksize += dc.size
536 536 blocksize += spc.size
537 537
538 538 cspc = None
539 539 pairIndex = 0
540 540 if self.dataOut.pairsList != None:
541 541 #calculo de cross-spectra
542 542 cspc = numpy.zeros((self.dataOut.nPairs, self.dataOut.nFFTPoints, self.dataOut.nHeights), dtype='complex')
543 543 for pair in self.dataOut.pairsList:
544 544 cspc[pairIndex,:,:] = numpy.abs(fft_volt[pair[0],:,:] * numpy.conjugate(fft_volt[pair[1],:,:]))
545 545 pairIndex += 1
546 546 blocksize += cspc.size
547 547
548 548 self.dataOut.data_spc = spc
549 549 self.dataOut.data_cspc = cspc
550 550 self.dataOut.data_dc = dc
551 551 self.dataOut.blockSize = blocksize
552 552
553 553 def init(self, nFFTPoints=None, pairsList=None):
554 554
555 555 if self.dataIn.type == "Spectra":
556 556 self.dataOut.copy(self.dataIn)
557 557 return
558 558
559 559 if self.dataIn.type == "Voltage":
560 560
561 561 if nFFTPoints == None:
562 562 raise ValueError, "This SpectraProc.setup() need nFFTPoints input variable"
563 563
564 564 if pairsList == None:
565 565 nPairs = 0
566 566 else:
567 567 nPairs = len(pairsList)
568 568
569 569 self.dataOut.nFFTPoints = nFFTPoints
570 570 self.dataOut.pairsList = pairsList
571 571 self.dataOut.nPairs = nPairs
572 572
573 573 if self.buffer == None:
574 574 self.buffer = numpy.zeros((self.dataIn.nChannels,
575 575 self.dataOut.nFFTPoints,
576 576 self.dataIn.nHeights),
577 577 dtype='complex')
578 578
579 579
580 580 self.buffer[:,self.profIndex,:] = self.dataIn.data
581 581 self.profIndex += 1
582 582
583 583 if self.firstdatatime == None:
584 584 self.firstdatatime = self.dataIn.utctime
585 585
586 586 if self.profIndex == self.dataOut.nFFTPoints:
587 587 self.__updateObjFromInput()
588 588 self.__getFft()
589 589
590 590 self.dataOut.flagNoData = False
591 591
592 592 self.buffer = None
593 593 self.firstdatatime = None
594 594 self.profIndex = 0
595 595
596 596 return
597 597
598 598 raise ValuError, "The type object %s is not valid"%(self.dataIn.type)
599 599
600 600 def selectChannels(self, channelList):
601 601
602 602 channelIndexList = []
603 603
604 604 for channel in channelList:
605 605 index = self.dataOut.channelList.index(channel)
606 606 channelIndexList.append(index)
607 607
608 608 self.selectChannelsByIndex(channelIndexList)
609 609
610 610 def selectChannelsByIndex(self, channelIndexList):
611 611 """
612 612 Selecciona un bloque de datos en base a canales segun el channelIndexList
613 613
614 614 Input:
615 615 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
616 616
617 617 Affected:
618 618 self.dataOut.data_spc
619 619 self.dataOut.channelIndexList
620 620 self.dataOut.nChannels
621 621
622 622 Return:
623 623 None
624 624 """
625 625
626 626 for channelIndex in channelIndexList:
627 627 if channelIndex not in self.dataOut.channelIndexList:
628 628 print channelIndexList
629 629 raise ValueError, "The value %d in channelIndexList is not valid" %channelIndex
630 630
631 631 nChannels = len(channelIndexList)
632 632
633 633 data_spc = self.dataOut.data_spc[channelIndexList,:]
634 634
635 635 self.dataOut.data_spc = data_spc
636 636 self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
637 637 # self.dataOut.nChannels = nChannels
638 638
639 639 return 1
640 640
641 641
642 642 class IncohInt(Operation):
643 643
644 644
645 645 __profIndex = 0
646 646 __withOverapping = False
647 647
648 648 __byTime = False
649 649 __initime = None
650 650 __lastdatatime = None
651 651 __integrationtime = None
652 652
653 653 __buffer = None
654 654
655 655 __dataReady = False
656 656
657 657 n = None
658 658
659 659
660 660 def __init__(self):
661 661
662 662 self.__isConfig = False
663 663
664 664 def setup(self, n=None, timeInterval=None, overlapping=False):
665 665 """
666 666 Set the parameters of the integration class.
667 667
668 668 Inputs:
669 669
670 670 n : Number of coherent integrations
671 671 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
672 672 overlapping :
673 673
674 674 """
675 675
676 676 self.__initime = None
677 677 self.__lastdatatime = 0
678 678 self.__buffer = None
679 679 self.__dataReady = False
680 680
681 681
682 682 if n == None and timeInterval == None:
683 683 raise ValueError, "n or timeInterval should be specified ..."
684 684
685 685 if n != None:
686 686 self.n = n
687 687 self.__byTime = False
688 688 else:
689 689 self.__integrationtime = timeInterval * 60. #if (type(timeInterval)!=integer) -> change this line
690 690 self.n = 9999
691 691 self.__byTime = True
692 692
693 693 if overlapping:
694 694 self.__withOverapping = True
695 695 self.__buffer = None
696 696 else:
697 697 self.__withOverapping = False
698 698 self.__buffer = 0
699 699
700 700 self.__profIndex = 0
701 701
702 702 def putData(self, data):
703 703
704 704 """
705 705 Add a profile to the __buffer and increase in one the __profileIndex
706 706
707 707 """
708 708
709 709 if not self.__withOverapping:
710 710 self.__buffer += data.copy()
711 711 self.__profIndex += 1
712 712 return
713 713
714 714 #Overlapping data
715 715 nChannels, nFFTPoints, nHeis = data.shape
716 716 data = numpy.reshape(data, (1, nChannels, nFFTPoints, nHeis))
717 717
718 718 #If the buffer is empty then it takes the data value
719 719 if self.__buffer == None:
720 720 self.__buffer = data
721 721 self.__profIndex += 1
722 722 return
723 723
724 724 #If the buffer length is lower than n then stakcing the data value
725 725 if self.__profIndex < self.n:
726 726 self.__buffer = numpy.vstack((self.__buffer, data))
727 727 self.__profIndex += 1
728 728 return
729 729
730 730 #If the buffer length is equal to n then replacing the last buffer value with the data value
731 731 self.__buffer = numpy.roll(self.__buffer, -1, axis=0)
732 732 self.__buffer[self.n-1] = data
733 733 self.__profIndex = self.n
734 734 return
735 735
736 736
737 737 def pushData(self):
738 738 """
739 739 Return the sum of the last profiles and the profiles used in the sum.
740 740
741 741 Affected:
742 742
743 743 self.__profileIndex
744 744
745 745 """
746 746
747 747 if not self.__withOverapping:
748 748 data = self.__buffer
749 749 n = self.__profIndex
750 750
751 751 self.__buffer = 0
752 752 self.__profIndex = 0
753 753
754 754 return data, n
755 755
756 756 #Integration with Overlapping
757 757 data = numpy.sum(self.__buffer, axis=0)
758 758 n = self.__profIndex
759 759
760 760 return data, n
761 761
762 762 def byProfiles(self, data):
763 763
764 764 self.__dataReady = False
765 765 avgdata = None
766 766 n = None
767 767
768 768 self.putData(data)
769 769
770 770 if self.__profIndex == self.n:
771 771
772 772 avgdata, n = self.pushData()
773 773 self.__dataReady = True
774 774
775 775 return avgdata
776 776
777 777 def byTime(self, data, datatime):
778 778
779 779 self.__dataReady = False
780 780 avgdata = None
781 781 n = None
782 782
783 783 self.putData(data)
784 784
785 785 if (datatime - self.__initime) >= self.__integrationtime:
786 786 avgdata, n = self.pushData()
787 787 self.n = n
788 788 self.__dataReady = True
789 789
790 790 return avgdata
791 791
792 792 def integrate(self, data, datatime=None):
793 793
794 794 if self.__initime == None:
795 795 self.__initime = datatime
796 796
797 797 if self.__byTime:
798 798 avgdata = self.byTime(data, datatime)
799 799 else:
800 800 avgdata = self.byProfiles(data)
801 801
802 802
803 803 self.__lastdatatime = datatime
804 804
805 805 if avgdata == None:
806 806 return None, None
807 807
808 808 avgdatatime = self.__initime
809 809
810 810 deltatime = datatime -self.__lastdatatime
811 811
812 812 if not self.__withOverapping:
813 813 self.__initime = datatime
814 814 else:
815 815 self.__initime += deltatime
816 816
817 817 return avgdata, avgdatatime
818 818
819 819 def run(self, dataOut, n=None, timeInterval=None, overlapping=False):
820 820
821 821 if not self.__isConfig:
822 822 self.setup(n, timeInterval, overlapping)
823 823 self.__isConfig = True
824 824
825 825 avgdata, avgdatatime = self.integrate(dataOut.data_spc, dataOut.utctime)
826 826
827 827 # dataOut.timeInterval *= n
828 828 dataOut.flagNoData = True
829 829
830 830 if self.__dataReady:
831 831 dataOut.data_spc = avgdata
832 832 dataOut.nIncohInt *= self.n
833 833 dataOut.utctime = avgdatatime
834 dataOut.timeInterval = dataOut.ippSeconds * dataOut.nCohInt * dataOut.nIncohInt
834 dataOut.timeInterval = dataOut.ippSeconds * dataOut.nCohInt * dataOut.nIncohInt * dataOut.nFFTPoints
835 835 dataOut.flagNoData = False
836 836 No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now