##// END OF EJS Templates
jroproc_voltage.py: ProfileSelector, Decoder, Reshape was tested with nTxs != 1 and getblock = True
Miguel Valdez -
r749:2d4c40d861d3
parent child
Show More
@@ -1,1080 +1,1157
1 1 import sys
2 2 import numpy
3 3
4 4 from jroproc_base import ProcessingUnit, Operation
5 5 from schainpy.model.data.jrodata import Voltage
6 6
7 7 class VoltageProc(ProcessingUnit):
8 8
9 9
10 10 def __init__(self):
11 11
12 12 ProcessingUnit.__init__(self)
13 13
14 14 # self.objectDict = {}
15 15 self.dataOut = Voltage()
16 16 self.flip = 1
17 17
18 18 def run(self):
19 19 if self.dataIn.type == 'AMISR':
20 20 self.__updateObjFromAmisrInput()
21 21
22 22 if self.dataIn.type == 'Voltage':
23 23 self.dataOut.copy(self.dataIn)
24 24
25 25 # self.dataOut.copy(self.dataIn)
26 26
27 27 def __updateObjFromAmisrInput(self):
28 28
29 29 self.dataOut.timeZone = self.dataIn.timeZone
30 30 self.dataOut.dstFlag = self.dataIn.dstFlag
31 31 self.dataOut.errorCount = self.dataIn.errorCount
32 32 self.dataOut.useLocalTime = self.dataIn.useLocalTime
33 33
34 34 self.dataOut.flagNoData = self.dataIn.flagNoData
35 35 self.dataOut.data = self.dataIn.data
36 36 self.dataOut.utctime = self.dataIn.utctime
37 37 self.dataOut.channelList = self.dataIn.channelList
38 38 # self.dataOut.timeInterval = self.dataIn.timeInterval
39 39 self.dataOut.heightList = self.dataIn.heightList
40 40 self.dataOut.nProfiles = self.dataIn.nProfiles
41 41
42 42 self.dataOut.nCohInt = self.dataIn.nCohInt
43 43 self.dataOut.ippSeconds = self.dataIn.ippSeconds
44 44 self.dataOut.frequency = self.dataIn.frequency
45 45
46 46 self.dataOut.azimuth = self.dataIn.azimuth
47 47 self.dataOut.zenith = self.dataIn.zenith
48 48
49 49 self.dataOut.beam.codeList = self.dataIn.beam.codeList
50 50 self.dataOut.beam.azimuthList = self.dataIn.beam.azimuthList
51 51 self.dataOut.beam.zenithList = self.dataIn.beam.zenithList
52 52 #
53 53 # pass#
54 54 #
55 55 # def init(self):
56 56 #
57 57 #
58 58 # if self.dataIn.type == 'AMISR':
59 59 # self.__updateObjFromAmisrInput()
60 60 #
61 61 # if self.dataIn.type == 'Voltage':
62 62 # self.dataOut.copy(self.dataIn)
63 63 # # No necesita copiar en cada init() los atributos de dataIn
64 64 # # la copia deberia hacerse por cada nuevo bloque de datos
65 65
66 66 def selectChannels(self, channelList):
67 67
68 68 channelIndexList = []
69 69
70 70 for channel in channelList:
71 71 if channel not in self.dataOut.channelList:
72 72 raise ValueError, "Channel %d is not in %s" %(channel, str(self.dataOut.channelList))
73 73
74 74 index = self.dataOut.channelList.index(channel)
75 75 channelIndexList.append(index)
76 76
77 77 self.selectChannelsByIndex(channelIndexList)
78 78
79 79 def selectChannelsByIndex(self, channelIndexList):
80 80 """
81 81 Selecciona un bloque de datos en base a canales segun el channelIndexList
82 82
83 83 Input:
84 84 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
85 85
86 86 Affected:
87 87 self.dataOut.data
88 88 self.dataOut.channelIndexList
89 89 self.dataOut.nChannels
90 90 self.dataOut.m_ProcessingHeader.totalSpectra
91 91 self.dataOut.systemHeaderObj.numChannels
92 92 self.dataOut.m_ProcessingHeader.blockSize
93 93
94 94 Return:
95 95 None
96 96 """
97 97
98 98 for channelIndex in channelIndexList:
99 99 if channelIndex not in self.dataOut.channelIndexList:
100 100 print channelIndexList
101 101 raise ValueError, "The value %d in channelIndexList is not valid" %channelIndex
102 102
103 103 if self.dataOut.flagDataAsBlock:
104 104 """
105 105 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
106 106 """
107 107 data = self.dataOut.data[channelIndexList,:,:]
108 108 else:
109 109 data = self.dataOut.data[channelIndexList,:]
110 110
111 111 self.dataOut.data = data
112 112 self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
113 113 # self.dataOut.nChannels = nChannels
114 114
115 115 return 1
116 116
117 117 def selectHeights(self, minHei=None, maxHei=None):
118 118 """
119 119 Selecciona un bloque de datos en base a un grupo de valores de alturas segun el rango
120 120 minHei <= height <= maxHei
121 121
122 122 Input:
123 123 minHei : valor minimo de altura a considerar
124 124 maxHei : valor maximo de altura a considerar
125 125
126 126 Affected:
127 127 Indirectamente son cambiados varios valores a travez del metodo selectHeightsByIndex
128 128
129 129 Return:
130 130 1 si el metodo se ejecuto con exito caso contrario devuelve 0
131 131 """
132 132
133 133 if minHei == None:
134 134 minHei = self.dataOut.heightList[0]
135 135
136 136 if maxHei == None:
137 137 maxHei = self.dataOut.heightList[-1]
138 138
139 139 if (minHei < self.dataOut.heightList[0]):
140 140 minHei = self.dataOut.heightList[0]
141 141
142 142 if (maxHei > self.dataOut.heightList[-1]):
143 143 maxHei = self.dataOut.heightList[-1]
144 144
145 145 minIndex = 0
146 146 maxIndex = 0
147 147 heights = self.dataOut.heightList
148 148
149 149 inda = numpy.where(heights >= minHei)
150 150 indb = numpy.where(heights <= maxHei)
151 151
152 152 try:
153 153 minIndex = inda[0][0]
154 154 except:
155 155 minIndex = 0
156 156
157 157 try:
158 158 maxIndex = indb[0][-1]
159 159 except:
160 160 maxIndex = len(heights)
161 161
162 162 self.selectHeightsByIndex(minIndex, maxIndex)
163 163
164 164 return 1
165 165
166 166
167 167 def selectHeightsByIndex(self, minIndex, maxIndex):
168 168 """
169 169 Selecciona un bloque de datos en base a un grupo indices de alturas segun el rango
170 170 minIndex <= index <= maxIndex
171 171
172 172 Input:
173 173 minIndex : valor de indice minimo de altura a considerar
174 174 maxIndex : valor de indice maximo de altura a considerar
175 175
176 176 Affected:
177 177 self.dataOut.data
178 178 self.dataOut.heightList
179 179
180 180 Return:
181 181 1 si el metodo se ejecuto con exito caso contrario devuelve 0
182 182 """
183 183
184 184 if (minIndex < 0) or (minIndex > maxIndex):
185 185 raise ValueError, "Height index range (%d,%d) is not valid" % (minIndex, maxIndex)
186 186
187 187 if (maxIndex >= self.dataOut.nHeights):
188 188 maxIndex = self.dataOut.nHeights
189 189
190 190 #voltage
191 191 if self.dataOut.flagDataAsBlock:
192 192 """
193 193 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
194 194 """
195 195 data = self.dataOut.data[:,:, minIndex:maxIndex]
196 196 else:
197 197 data = self.dataOut.data[:, minIndex:maxIndex]
198 198
199 199 # firstHeight = self.dataOut.heightList[minIndex]
200 200
201 201 self.dataOut.data = data
202 202 self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex]
203 203
204 204 if self.dataOut.nHeights <= 1:
205 205 raise ValueError, "selectHeights: Too few heights. Current number of heights is %d" %(self.dataOut.nHeights)
206 206
207 207 return 1
208 208
209 209
210 210 def filterByHeights(self, window):
211 211
212 212 deltaHeight = self.dataOut.heightList[1] - self.dataOut.heightList[0]
213 213
214 214 if window == None:
215 215 window = (self.dataOut.radarControllerHeaderObj.txA/self.dataOut.radarControllerHeaderObj.nBaud) / deltaHeight
216 216
217 217 newdelta = deltaHeight * window
218 218 r = self.dataOut.nHeights % window
219 219 newheights = (self.dataOut.nHeights-r)/window
220 220
221 221 if newheights <= 1:
222 222 raise ValueError, "filterByHeights: Too few heights. Current number of heights is %d and window is %d" %(self.dataOut.nHeights, window)
223 223
224 224 if self.dataOut.flagDataAsBlock:
225 225 """
226 226 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
227 227 """
228 228 buffer = self.dataOut.data[:, :, 0:self.dataOut.nHeights-r]
229 229 buffer = buffer.reshape(self.dataOut.nChannels,self.dataOut.nProfiles,self.dataOut.nHeights/window,window)
230 230 buffer = numpy.sum(buffer,3)
231 231
232 232 else:
233 233 buffer = self.dataOut.data[:,0:self.dataOut.nHeights-r]
234 234 buffer = buffer.reshape(self.dataOut.nChannels,self.dataOut.nHeights/window,window)
235 235 buffer = numpy.sum(buffer,2)
236 236
237 237 self.dataOut.data = buffer
238 238 self.dataOut.heightList = self.dataOut.heightList[0] + numpy.arange( newheights )*newdelta
239 239 self.dataOut.windowOfFilter = window
240 240
241 241 def setH0(self, h0, deltaHeight = None):
242 242
243 243 if not deltaHeight:
244 244 deltaHeight = self.dataOut.heightList[1] - self.dataOut.heightList[0]
245 245
246 246 nHeights = self.dataOut.nHeights
247 247
248 248 newHeiRange = h0 + numpy.arange(nHeights)*deltaHeight
249 249
250 250 self.dataOut.heightList = newHeiRange
251 251
252 252 def deFlip(self, channelList = []):
253 253
254 254 data = self.dataOut.data.copy()
255 255
256 256 if self.dataOut.flagDataAsBlock:
257 257 flip = self.flip
258 258 profileList = range(self.dataOut.nProfiles)
259 259
260 260 if not channelList:
261 261 for thisProfile in profileList:
262 262 data[:,thisProfile,:] = data[:,thisProfile,:]*flip
263 263 flip *= -1.0
264 264 else:
265 265 for thisChannel in channelList:
266 266 if thisChannel not in self.dataOut.channelList:
267 267 continue
268 268
269 269 for thisProfile in profileList:
270 270 data[thisChannel,thisProfile,:] = data[thisChannel,thisProfile,:]*flip
271 271 flip *= -1.0
272 272
273 273 self.flip = flip
274 274
275 275 else:
276 276 if not channelList:
277 277 data[:,:] = data[:,:]*self.flip
278 278 else:
279 279 for thisChannel in channelList:
280 280 if thisChannel not in self.dataOut.channelList:
281 281 continue
282 282
283 283 data[thisChannel,:] = data[thisChannel,:]*self.flip
284 284
285 285 self.flip *= -1.
286 286
287 287 self.dataOut.data = data
288 288
289 289 def setRadarFrequency(self, frequency=None):
290 290
291 291 if frequency != None:
292 292 self.dataOut.frequency = frequency
293 293
294 294 return 1
295 295
296 296 class CohInt(Operation):
297 297
298 298 isConfig = False
299 299
300 300 __profIndex = 0
301 301 __withOverapping = False
302 302
303 303 __byTime = False
304 304 __initime = None
305 305 __lastdatatime = None
306 306 __integrationtime = None
307 307
308 308 __buffer = None
309 309
310 310 __dataReady = False
311 311
312 312 n = None
313 313
314 314
315 315 def __init__(self):
316 316
317 317 Operation.__init__(self)
318 318
319 319 # self.isConfig = False
320 320
321 321 def setup(self, n=None, timeInterval=None, overlapping=False, byblock=False):
322 322 """
323 323 Set the parameters of the integration class.
324 324
325 325 Inputs:
326 326
327 327 n : Number of coherent integrations
328 328 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
329 329 overlapping :
330 330
331 331 """
332 332
333 333 self.__initime = None
334 334 self.__lastdatatime = 0
335 335 self.__buffer = None
336 336 self.__dataReady = False
337 337 self.byblock = byblock
338 338
339 339 if n == None and timeInterval == None:
340 340 raise ValueError, "n or timeInterval should be specified ..."
341 341
342 342 if n != None:
343 343 self.n = n
344 344 self.__byTime = False
345 345 else:
346 346 self.__integrationtime = timeInterval #* 60. #if (type(timeInterval)!=integer) -> change this line
347 347 self.n = 9999
348 348 self.__byTime = True
349 349
350 350 if overlapping:
351 351 self.__withOverapping = True
352 352 self.__buffer = None
353 353 else:
354 354 self.__withOverapping = False
355 355 self.__buffer = 0
356 356
357 357 self.__profIndex = 0
358 358
359 359 def putData(self, data):
360 360
361 361 """
362 362 Add a profile to the __buffer and increase in one the __profileIndex
363 363
364 364 """
365 365
366 366 if not self.__withOverapping:
367 367 self.__buffer += data.copy()
368 368 self.__profIndex += 1
369 369 return
370 370
371 371 #Overlapping data
372 372 nChannels, nHeis = data.shape
373 373 data = numpy.reshape(data, (1, nChannels, nHeis))
374 374
375 375 #If the buffer is empty then it takes the data value
376 376 if self.__buffer is None:
377 377 self.__buffer = data
378 378 self.__profIndex += 1
379 379 return
380 380
381 381 #If the buffer length is lower than n then stakcing the data value
382 382 if self.__profIndex < self.n:
383 383 self.__buffer = numpy.vstack((self.__buffer, data))
384 384 self.__profIndex += 1
385 385 return
386 386
387 387 #If the buffer length is equal to n then replacing the last buffer value with the data value
388 388 self.__buffer = numpy.roll(self.__buffer, -1, axis=0)
389 389 self.__buffer[self.n-1] = data
390 390 self.__profIndex = self.n
391 391 return
392 392
393 393
394 394 def pushData(self):
395 395 """
396 396 Return the sum of the last profiles and the profiles used in the sum.
397 397
398 398 Affected:
399 399
400 400 self.__profileIndex
401 401
402 402 """
403 403
404 404 if not self.__withOverapping:
405 405 data = self.__buffer
406 406 n = self.__profIndex
407 407
408 408 self.__buffer = 0
409 409 self.__profIndex = 0
410 410
411 411 return data, n
412 412
413 413 #Integration with Overlapping
414 414 data = numpy.sum(self.__buffer, axis=0)
415 415 n = self.__profIndex
416 416
417 417 return data, n
418 418
419 419 def byProfiles(self, data):
420 420
421 421 self.__dataReady = False
422 422 avgdata = None
423 423 # n = None
424 424
425 425 self.putData(data)
426 426
427 427 if self.__profIndex == self.n:
428 428
429 429 avgdata, n = self.pushData()
430 430 self.__dataReady = True
431 431
432 432 return avgdata
433 433
434 434 def byTime(self, data, datatime):
435 435
436 436 self.__dataReady = False
437 437 avgdata = None
438 438 n = None
439 439
440 440 self.putData(data)
441 441
442 442 if (datatime - self.__initime) >= self.__integrationtime:
443 443 avgdata, n = self.pushData()
444 444 self.n = n
445 445 self.__dataReady = True
446 446
447 447 return avgdata
448 448
449 449 def integrate(self, data, datatime=None):
450 450
451 451 if self.__initime == None:
452 452 self.__initime = datatime
453 453
454 454 if self.__byTime:
455 455 avgdata = self.byTime(data, datatime)
456 456 else:
457 457 avgdata = self.byProfiles(data)
458 458
459 459
460 460 self.__lastdatatime = datatime
461 461
462 462 if avgdata is None:
463 463 return None, None
464 464
465 465 avgdatatime = self.__initime
466 466
467 467 deltatime = datatime -self.__lastdatatime
468 468
469 469 if not self.__withOverapping:
470 470 self.__initime = datatime
471 471 else:
472 472 self.__initime += deltatime
473 473
474 474 return avgdata, avgdatatime
475 475
476 476 def integrateByBlock(self, dataOut):
477 477
478 478 times = int(dataOut.data.shape[1]/self.n)
479 479 avgdata = numpy.zeros((dataOut.nChannels, times, dataOut.nHeights), dtype=numpy.complex)
480 480
481 481 id_min = 0
482 482 id_max = self.n
483 483
484 484 for i in range(times):
485 485 junk = dataOut.data[:,id_min:id_max,:]
486 486 avgdata[:,i,:] = junk.sum(axis=1)
487 487 id_min += self.n
488 488 id_max += self.n
489 489
490 490 timeInterval = dataOut.ippSeconds*self.n
491 491 avgdatatime = (times - 1) * timeInterval + dataOut.utctime
492 492 self.__dataReady = True
493 493 return avgdata, avgdatatime
494 494
495 495 def run(self, dataOut, **kwargs):
496 496
497 497 if not self.isConfig:
498 498 self.setup(**kwargs)
499 499 self.isConfig = True
500 500
501 501 if dataOut.flagDataAsBlock:
502 502 """
503 503 Si la data es leida por bloques, dimension = [nChannels, nProfiles, nHeis]
504 504 """
505 505 avgdata, avgdatatime = self.integrateByBlock(dataOut)
506 506 dataOut.nProfiles /= self.n
507 507 else:
508 508 avgdata, avgdatatime = self.integrate(dataOut.data, dataOut.utctime)
509 509
510 510 # dataOut.timeInterval *= n
511 511 dataOut.flagNoData = True
512 512
513 513 if self.__dataReady:
514 514 dataOut.data = avgdata
515 515 dataOut.nCohInt *= self.n
516 516 dataOut.utctime = avgdatatime
517 517 # dataOut.timeInterval = dataOut.ippSeconds * dataOut.nCohInt
518 518 dataOut.flagNoData = False
519 519
520 520 class Decoder(Operation):
521 521
522 522 isConfig = False
523 523 __profIndex = 0
524 524
525 525 code = None
526 526
527 527 nCode = None
528 528 nBaud = None
529 529
530 530
531 531 def __init__(self):
532 532
533 533 Operation.__init__(self)
534 534
535 535 self.times = None
536 536 self.osamp = None
537 537 # self.__setValues = False
538 538 self.isConfig = False
539 539
540 540 def setup(self, code, osamp, dataOut):
541 541
542 542 self.__profIndex = 0
543 543
544 544 self.code = code
545 545
546 546 self.nCode = len(code)
547 547 self.nBaud = len(code[0])
548 548
549 549 if (osamp != None) and (osamp >1):
550 550 self.osamp = osamp
551 551 self.code = numpy.repeat(code, repeats=self.osamp, axis=1)
552 552 self.nBaud = self.nBaud*self.osamp
553 553
554 554 self.__nChannels = dataOut.nChannels
555 555 self.__nProfiles = dataOut.nProfiles
556 556 self.__nHeis = dataOut.nHeights
557 557
558 558 if self.__nHeis < self.nBaud:
559 559 raise ValueError, 'Number of heights (%d) should be greater than number of bauds (%d)' %(self.__nHeis, self.nBaud)
560 560
561 561 #Frequency
562 562 __codeBuffer = numpy.zeros((self.nCode, self.__nHeis), dtype=numpy.complex)
563 563
564 564 __codeBuffer[:,0:self.nBaud] = self.code
565 565
566 566 self.fft_code = numpy.conj(numpy.fft.fft(__codeBuffer, axis=1))
567 567
568 568 if dataOut.flagDataAsBlock:
569 569
570 570 self.ndatadec = self.__nHeis #- self.nBaud + 1
571 571
572 572 self.datadecTime = numpy.zeros((self.__nChannels, self.__nProfiles, self.ndatadec), dtype=numpy.complex)
573 573
574 574 else:
575 575
576 576 #Time
577 577 self.ndatadec = self.__nHeis #- self.nBaud + 1
578 578
579 579 self.datadecTime = numpy.zeros((self.__nChannels, self.ndatadec), dtype=numpy.complex)
580 580
581 581 def __convolutionInFreq(self, data):
582 582
583 583 fft_code = self.fft_code[self.__profIndex].reshape(1,-1)
584 584
585 585 fft_data = numpy.fft.fft(data, axis=1)
586 586
587 587 conv = fft_data*fft_code
588 588
589 589 data = numpy.fft.ifft(conv,axis=1)
590 590
591 591 return data
592 592
593 593 def __convolutionInFreqOpt(self, data):
594 594
595 595 raise NotImplementedError
596 596
597 597 def __convolutionInTime(self, data):
598 598
599 599 code = self.code[self.__profIndex]
600 600
601 601 for i in range(self.__nChannels):
602 602 self.datadecTime[i,:] = numpy.correlate(data[i,:], code, mode='full')[self.nBaud-1:]
603 603
604 604 return self.datadecTime
605 605
606 606 def __convolutionByBlockInTime(self, data):
607 607
608 608 repetitions = self.__nProfiles / self.nCode
609 609
610 610 junk = numpy.lib.stride_tricks.as_strided(self.code, (repetitions, self.code.size), (0, self.code.itemsize))
611 611 junk = junk.flatten()
612 612 code_block = numpy.reshape(junk, (self.nCode*repetitions, self.nBaud))
613 613
614 614 for i in range(self.__nChannels):
615 615 for j in range(self.__nProfiles):
616 616 self.datadecTime[i,j,:] = numpy.correlate(data[i,j,:], code_block[j,:], mode='full')[self.nBaud-1:]
617 617
618 618 return self.datadecTime
619 619
620 620 def __convolutionByBlockInFreq(self, data):
621 621
622 raise NotImplementedError, "Decoder by frequency fro Blocks not implemented"
623
624
622 625 fft_code = self.fft_code[self.__profIndex].reshape(1,-1)
623 626
624 627 fft_data = numpy.fft.fft(data, axis=2)
625 628
626 629 conv = fft_data*fft_code
627 630
628 631 data = numpy.fft.ifft(conv,axis=2)
629 632
630 633 return data
631 634
632 635 def run(self, dataOut, code=None, nCode=None, nBaud=None, mode = 0, osamp=None, times=None):
633 636
634 637 if dataOut.flagDecodeData:
635 638 print "This data is already decoded, recoding again ..."
636 639
637 640 if not self.isConfig:
638 641
639 642 if code is None:
640 643 if dataOut.code is None:
641 644 raise ValueError, "Code could not be read from %s instance. Enter a value in Code parameter" %dataOut.type
642 645
643 646 code = dataOut.code
644 647 else:
645 648 code = numpy.array(code).reshape(nCode,nBaud)
646 649
647 650 self.setup(code, osamp, dataOut)
648 651
649 652 self.isConfig = True
650 653
651 654 if mode == 3:
652 655 sys.stderr.write("Decoder Warning: mode=%d is not valid, using mode=0\n" %mode)
653
656
657 if times != None:
658 sys.stderr.write("Decoder Warning: Argument 'times' in not used anymore\n")
654 659
655 660 if self.code is None:
656 661 print "Fail decoding: Code is not defined."
657 662 return
658 663
659 664 datadec = None
660
665 if mode == 3:
666 mode = 0
667
661 668 if dataOut.flagDataAsBlock:
662 669 """
663 670 Decoding when data have been read as block,
664 671 """
665 if mode == 3:
666 mode = 0
667 672
668 673 if mode == 0:
669 674 datadec = self.__convolutionByBlockInTime(dataOut.data)
670 675 if mode == 1:
671 676 datadec = self.__convolutionByBlockInFreq(dataOut.data)
672 677 else:
673 678 """
674 679 Decoding when data have been read profile by profile
675 680 """
676 681 if mode == 0:
677 682 datadec = self.__convolutionInTime(dataOut.data)
678 683
679 684 if mode == 1:
680 685 datadec = self.__convolutionInFreq(dataOut.data)
681 686
682 687 if mode == 2:
683 688 datadec = self.__convolutionInFreqOpt(dataOut.data)
684 689
685 690 if datadec is None:
686 691 raise ValueError, "Codification mode selected is not valid: mode=%d. Try selecting 0 or 1" %mode
687 692
688 693 dataOut.code = self.code
689 694 dataOut.nCode = self.nCode
690 695 dataOut.nBaud = self.nBaud
691 696
692 697 dataOut.data = datadec
693 698
694 699 dataOut.heightList = dataOut.heightList[0:datadec.shape[-1]]
695 700
696 701 dataOut.flagDecodeData = True #asumo q la data esta decodificada
697 702
698 703 if self.__profIndex == self.nCode-1:
699 704 self.__profIndex = 0
700 705 return 1
701 706
702 707 self.__profIndex += 1
703 708
704 709 return 1
705 710 # dataOut.flagDeflipData = True #asumo q la data no esta sin flip
706 711
707 712
708 713 class ProfileConcat(Operation):
709 714
710 715 isConfig = False
711 716 buffer = None
712 717
713 718 def __init__(self):
714 719
715 720 Operation.__init__(self)
716 721 self.profileIndex = 0
717 722
718 723 def reset(self):
719 724 self.buffer = numpy.zeros_like(self.buffer)
720 725 self.start_index = 0
721 726 self.times = 1
722 727
723 728 def setup(self, data, m, n=1):
724 729 self.buffer = numpy.zeros((data.shape[0],data.shape[1]*m),dtype=type(data[0,0]))
725 730 self.nHeights = data.nHeights
726 731 self.start_index = 0
727 732 self.times = 1
728 733
729 734 def concat(self, data):
730 735
731 736 self.buffer[:,self.start_index:self.profiles*self.times] = data.copy()
732 737 self.start_index = self.start_index + self.nHeights
733 738
734 739 def run(self, dataOut, m):
735 740
736 741 dataOut.flagNoData = True
737 742
738 743 if not self.isConfig:
739 744 self.setup(dataOut.data, m, 1)
740 745 self.isConfig = True
741 746
742 747 if dataOut.flagDataAsBlock:
743 748 raise ValueError, "ProfileConcat can only be used when voltage have been read profile by profile, getBlock = False"
744 749
745 750 else:
746 751 self.concat(dataOut.data)
747 752 self.times += 1
748 753 if self.times > m:
749 754 dataOut.data = self.buffer
750 755 self.reset()
751 756 dataOut.flagNoData = False
752 757 # se deben actualizar mas propiedades del header y del objeto dataOut, por ejemplo, las alturas
753 758 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
754 759 xf = dataOut.heightList[0] + dataOut.nHeights * deltaHeight * m
755 760 dataOut.heightList = numpy.arange(dataOut.heightList[0], xf, deltaHeight)
756 761 dataOut.ippSeconds *= m
757 762
758 763 class ProfileSelector(Operation):
759 764
760 765 profileIndex = None
761 766 # Tamanho total de los perfiles
762 767 nProfiles = None
763 768
764 769 def __init__(self):
765 770
766 771 Operation.__init__(self)
767 772 self.profileIndex = 0
768 773
769 774 def incIndex(self):
770 775
771 776 self.profileIndex += 1
772 777
773 778 if self.profileIndex >= self.nProfiles:
774 779 self.profileIndex = 0
775 780
776 781 def isThisProfileInRange(self, profileIndex, minIndex, maxIndex):
777 782
778 783 if profileIndex < minIndex:
779 784 return False
780 785
781 786 if profileIndex > maxIndex:
782 787 return False
783 788
784 789 return True
785 790
786 791 def isThisProfileInList(self, profileIndex, profileList):
787 792
788 793 if profileIndex not in profileList:
789 794 return False
790 795
791 796 return True
792 797
793 798 def run(self, dataOut, profileList=None, profileRangeList=None, beam=None, byblock=False, rangeList = None, nProfiles=None):
794 799
795 800 """
796 801 ProfileSelector:
797 802
798 803 Inputs:
799 804 profileList : Index of profiles selected. Example: profileList = (0,1,2,7,8)
800 805
801 806 profileRangeList : Minimum and maximum profile indexes. Example: profileRangeList = (4, 30)
802 807
803 808 rangeList : List of profile ranges. Example: rangeList = ((4, 30), (32, 64), (128, 256))
804 809
805 810 """
806 811
807 812 dataOut.flagNoData = True
808
813
809 814 if dataOut.flagDataAsBlock:
810 815 """
811 816 data dimension = [nChannels, nProfiles, nHeis]
812 817 """
813 818 if profileList != None:
814 819 dataOut.data = dataOut.data[:,profileList,:]
815 dataOut.nProfiles = len(profileList)
816 dataOut.profileIndex = dataOut.nProfiles - 1
817 820
818 821 if profileRangeList != None:
819 822 minIndex = profileRangeList[0]
820 823 maxIndex = profileRangeList[1]
821
824 profileList = range(minIndex, maxIndex+1)
825
822 826 dataOut.data = dataOut.data[:,minIndex:maxIndex+1,:]
823 dataOut.nProfiles = maxIndex - minIndex + 1
824 dataOut.profileIndex = dataOut.nProfiles - 1
825 827
826 828 if rangeList != None:
827 raise ValueError, "Profile Selector: Invalid argument rangeList. Not implemented for getByBlock yet"
828 829
830 profileList = []
831
832 for thisRange in rangeList:
833 minIndex = thisRange[0]
834 maxIndex = thisRange[1]
835
836 profileList.extend(range(minIndex, maxIndex+1))
837
838 dataOut.data = dataOut.data[:,profileList,:]
839
840 dataOut.nProfiles = len(profileList)
841 dataOut.profileIndex = dataOut.nProfiles - 1
829 842 dataOut.flagNoData = False
830 843
831 844 return True
832 845
833 846 """
834 847 data dimension = [nChannels, nHeis]
835 848 """
836 849
837 if nProfiles:
838 self.nProfiles = nProfiles
839 else:
840 self.nProfiles = dataOut.nProfiles
841
842 850 if profileList != None:
843 851
844 dataOut.nProfiles = len(profileList)
845
846 852 if self.isThisProfileInList(dataOut.profileIndex, profileList):
847 dataOut.flagNoData = False
853
854 self.nProfiles = len(profileList)
855 dataOut.nProfiles = self.nProfiles
848 856 dataOut.profileIndex = self.profileIndex
857 dataOut.flagNoData = False
849 858
850 859 self.incIndex()
851 860 return True
852 861
853 862 if profileRangeList != None:
854 863
855 864 minIndex = profileRangeList[0]
856 865 maxIndex = profileRangeList[1]
857 866
858 dataOut.nProfiles = maxIndex - minIndex + 1
859
860 867 if self.isThisProfileInRange(dataOut.profileIndex, minIndex, maxIndex):
861 dataOut.flagNoData = False
868
869 self.nProfiles = maxIndex - minIndex + 1
870 dataOut.nProfiles = self.nProfiles
862 871 dataOut.profileIndex = self.profileIndex
872 dataOut.flagNoData = False
863 873
864 874 self.incIndex()
865 875 return True
866 876
867 877 if rangeList != None:
868 878
869 879 nProfiles = 0
870 880
871 881 for thisRange in rangeList:
872 882 minIndex = thisRange[0]
873 883 maxIndex = thisRange[1]
874 884
875 885 nProfiles += maxIndex - minIndex + 1
876 886
877 dataOut.nProfiles = nProfiles
878
879 887 for thisRange in rangeList:
880 888
881 889 minIndex = thisRange[0]
882 890 maxIndex = thisRange[1]
883 891
884 892 if self.isThisProfileInRange(dataOut.profileIndex, minIndex, maxIndex):
885 893
886 # print "profileIndex = ", dataOut.profileIndex
887
888 dataOut.flagNoData = False
894 self.nProfiles = nProfiles
895 dataOut.nProfiles = self.nProfiles
889 896 dataOut.profileIndex = self.profileIndex
890
897 dataOut.flagNoData = False
898
891 899 self.incIndex()
900
892 901 break
902
893 903 return True
894 904
895 905
896 906 if beam != None: #beam is only for AMISR data
897 907 if self.isThisProfileInList(dataOut.profileIndex, dataOut.beamRangeDict[beam]):
898 908 dataOut.flagNoData = False
899 909 dataOut.profileIndex = self.profileIndex
900 910
901 911 self.incIndex()
902 912
903 913 return True
904 914
905 915 raise ValueError, "ProfileSelector needs profileList, profileRangeList or rangeList parameter"
906 916
907 917 return False
908 918
909 919
910 920
911 921 class Reshaper(Operation):
912 922
913 923 def __init__(self):
914 924
915 925 Operation.__init__(self)
916 self.updateNewHeights = True
926
927 self.__buffer = None
928 self.__nitems = 0
929
930 def __appendProfile(self, dataOut, nTxs):
931
932 if self.__buffer is None:
933 shape = (dataOut.nChannels, int(dataOut.nHeights/nTxs) )
934 self.__buffer = numpy.empty(shape, dtype = dataOut.data.dtype)
935
936 ini = dataOut.nHeights * self.__nitems
937 end = ini + dataOut.nHeights
938
939 self.__buffer[:, ini:end] = dataOut.data
940
941 self.__nitems += 1
942
943 return int(self.__nitems*nTxs)
917 944
918 def run(self, dataOut, shape):
945 def __getBuffer(self):
919 946
920 if not dataOut.flagDataAsBlock:
921 raise ValueError, "Reshaper can only be used when voltage have been read as Block, getBlock = True"
947 if self.__nitems == int(1./self.__nTxs):
948
949 self.__nitems = 0
950
951 return self.__buffer.copy()
922 952
923 if len(shape) != 3:
924 raise ValueError, "shape len should be equal to 3, (nChannels, nProfiles, nHeis)"
953 return None
954
955 def __checkInputs(self, dataOut, shape, nTxs):
925 956
926 shape_tuple = tuple(shape)
927 dataOut.data = numpy.reshape(dataOut.data, shape_tuple)
928 dataOut.flagNoData = False
957 if shape is None and nTxs is None:
958 raise ValueError, "Reshaper: shape of factor should be defined"
929 959
930 if self.updateNewHeights:
960 if nTxs:
961 if nTxs < 0:
962 raise ValueError, "nTxs should be greater than 0"
931 963
932 old_nheights = dataOut.nHeights
933 new_nheights = dataOut.data.shape[2]
934 factor = 1.0*new_nheights / old_nheights
964 if nTxs < 1 and dataOut.nProfiles % (1./nTxs) != 0:
965 raise ValueError, "nProfiles= %d is not divisibled by (1./nTxs) = %f" %(dataOut.nProfiles, (1./nTxs))
935 966
936 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
967 shape = [dataOut.nChannels, dataOut.nProfiles*nTxs, dataOut.nHeights/nTxs]
968
969 if len(shape) != 2 and len(shape) != 3:
970 raise ValueError, "shape dimension should be equal to 2 or 3. shape = (nProfiles, nHeis) or (nChannels, nProfiles, nHeis). Actually shape = (%d, %d, %d)" %(dataOut.nChannels, dataOut.nProfiles, dataOut.nHeights)
971
972 if len(shape) == 2:
973 shape_tuple = [dataOut.nChannels]
974 shape_tuple.extend(shape)
975 else:
976 shape_tuple = list(shape)
977
978 if not nTxs:
979 nTxs = int(shape_tuple[1]/dataOut.nProfiles)
937 980
938 xf = dataOut.heightList[0] + dataOut.nHeights * deltaHeight * factor
981 return shape_tuple, nTxs
982
983 def run(self, dataOut, shape=None, nTxs=None):
984
985 shape_tuple, self.__nTxs = self.__checkInputs(dataOut, shape, nTxs)
986
987 dataOut.flagNoData = True
988 profileIndex = None
989
990 if dataOut.flagDataAsBlock:
991
992 dataOut.data = numpy.reshape(dataOut.data, shape_tuple)
993 dataOut.flagNoData = False
939 994
940 dataOut.heightList = numpy.arange(dataOut.heightList[0], xf, deltaHeight)
995 profileIndex = int(dataOut.nProfiles*nTxs) - 1
941 996
942 dataOut.nProfiles = dataOut.data.shape[1]
997 else:
943 998
944 dataOut.ippSeconds *= factor
999 if self.__nTxs < 1:
1000
1001 self.__appendProfile(dataOut, self.__nTxs)
1002 new_data = self.__getBuffer()
1003
1004 if new_data is not None:
1005 dataOut.data = new_data
1006 dataOut.flagNoData = False
1007
1008 profileIndex = dataOut.profileIndex*nTxs
1009
1010 else:
1011 raise ValueError, "nTxs should be greater than 0 and lower than 1, or use VoltageReader(..., getblock=True)"
1012
1013 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1014
1015 dataOut.heightList = numpy.arange(dataOut.nHeights/self.__nTxs) * deltaHeight + dataOut.heightList[0]
1016
1017 dataOut.nProfiles = int(dataOut.nProfiles*self.__nTxs)
1018
1019 dataOut.profileIndex = profileIndex
1020
1021 dataOut.ippSeconds /= self.__nTxs
945 1022 #
946 1023 # import collections
947 1024 # from scipy.stats import mode
948 1025 #
949 1026 # class Synchronize(Operation):
950 1027 #
951 1028 # isConfig = False
952 1029 # __profIndex = 0
953 1030 #
954 1031 # def __init__(self):
955 1032 #
956 1033 # Operation.__init__(self)
957 1034 # # self.isConfig = False
958 1035 # self.__powBuffer = None
959 1036 # self.__startIndex = 0
960 1037 # self.__pulseFound = False
961 1038 #
962 1039 # def __findTxPulse(self, dataOut, channel=0, pulse_with = None):
963 1040 #
964 1041 # #Read data
965 1042 #
966 1043 # powerdB = dataOut.getPower(channel = channel)
967 1044 # noisedB = dataOut.getNoise(channel = channel)[0]
968 1045 #
969 1046 # self.__powBuffer.extend(powerdB.flatten())
970 1047 #
971 1048 # dataArray = numpy.array(self.__powBuffer)
972 1049 #
973 1050 # filteredPower = numpy.correlate(dataArray, dataArray[0:self.__nSamples], "same")
974 1051 #
975 1052 # maxValue = numpy.nanmax(filteredPower)
976 1053 #
977 1054 # if maxValue < noisedB + 10:
978 1055 # #No se encuentra ningun pulso de transmision
979 1056 # return None
980 1057 #
981 1058 # maxValuesIndex = numpy.where(filteredPower > maxValue - 0.1*abs(maxValue))[0]
982 1059 #
983 1060 # if len(maxValuesIndex) < 2:
984 1061 # #Solo se encontro un solo pulso de transmision de un baudio, esperando por el siguiente TX
985 1062 # return None
986 1063 #
987 1064 # phasedMaxValuesIndex = maxValuesIndex - self.__nSamples
988 1065 #
989 1066 # #Seleccionar solo valores con un espaciamiento de nSamples
990 1067 # pulseIndex = numpy.intersect1d(maxValuesIndex, phasedMaxValuesIndex)
991 1068 #
992 1069 # if len(pulseIndex) < 2:
993 1070 # #Solo se encontro un pulso de transmision con ancho mayor a 1
994 1071 # return None
995 1072 #
996 1073 # spacing = pulseIndex[1:] - pulseIndex[:-1]
997 1074 #
998 1075 # #remover senales que se distancien menos de 10 unidades o muestras
999 1076 # #(No deberian existir IPP menor a 10 unidades)
1000 1077 #
1001 1078 # realIndex = numpy.where(spacing > 10 )[0]
1002 1079 #
1003 1080 # if len(realIndex) < 2:
1004 1081 # #Solo se encontro un pulso de transmision con ancho mayor a 1
1005 1082 # return None
1006 1083 #
1007 1084 # #Eliminar pulsos anchos (deja solo la diferencia entre IPPs)
1008 1085 # realPulseIndex = pulseIndex[realIndex]
1009 1086 #
1010 1087 # period = mode(realPulseIndex[1:] - realPulseIndex[:-1])[0][0]
1011 1088 #
1012 1089 # print "IPP = %d samples" %period
1013 1090 #
1014 1091 # self.__newNSamples = dataOut.nHeights #int(period)
1015 1092 # self.__startIndex = int(realPulseIndex[0])
1016 1093 #
1017 1094 # return 1
1018 1095 #
1019 1096 #
1020 1097 # def setup(self, nSamples, nChannels, buffer_size = 4):
1021 1098 #
1022 1099 # self.__powBuffer = collections.deque(numpy.zeros( buffer_size*nSamples,dtype=numpy.float),
1023 1100 # maxlen = buffer_size*nSamples)
1024 1101 #
1025 1102 # bufferList = []
1026 1103 #
1027 1104 # for i in range(nChannels):
1028 1105 # bufferByChannel = collections.deque(numpy.zeros( buffer_size*nSamples, dtype=numpy.complex) + numpy.NAN,
1029 1106 # maxlen = buffer_size*nSamples)
1030 1107 #
1031 1108 # bufferList.append(bufferByChannel)
1032 1109 #
1033 1110 # self.__nSamples = nSamples
1034 1111 # self.__nChannels = nChannels
1035 1112 # self.__bufferList = bufferList
1036 1113 #
1037 1114 # def run(self, dataOut, channel = 0):
1038 1115 #
1039 1116 # if not self.isConfig:
1040 1117 # nSamples = dataOut.nHeights
1041 1118 # nChannels = dataOut.nChannels
1042 1119 # self.setup(nSamples, nChannels)
1043 1120 # self.isConfig = True
1044 1121 #
1045 1122 # #Append new data to internal buffer
1046 1123 # for thisChannel in range(self.__nChannels):
1047 1124 # bufferByChannel = self.__bufferList[thisChannel]
1048 1125 # bufferByChannel.extend(dataOut.data[thisChannel])
1049 1126 #
1050 1127 # if self.__pulseFound:
1051 1128 # self.__startIndex -= self.__nSamples
1052 1129 #
1053 1130 # #Finding Tx Pulse
1054 1131 # if not self.__pulseFound:
1055 1132 # indexFound = self.__findTxPulse(dataOut, channel)
1056 1133 #
1057 1134 # if indexFound == None:
1058 1135 # dataOut.flagNoData = True
1059 1136 # return
1060 1137 #
1061 1138 # self.__arrayBuffer = numpy.zeros((self.__nChannels, self.__newNSamples), dtype = numpy.complex)
1062 1139 # self.__pulseFound = True
1063 1140 # self.__startIndex = indexFound
1064 1141 #
1065 1142 # #If pulse was found ...
1066 1143 # for thisChannel in range(self.__nChannels):
1067 1144 # bufferByChannel = self.__bufferList[thisChannel]
1068 1145 # #print self.__startIndex
1069 1146 # x = numpy.array(bufferByChannel)
1070 1147 # self.__arrayBuffer[thisChannel] = x[self.__startIndex:self.__startIndex+self.__newNSamples]
1071 1148 #
1072 1149 # deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1073 1150 # dataOut.heightList = numpy.arange(self.__newNSamples)*deltaHeight
1074 1151 # # dataOut.ippSeconds = (self.__newNSamples / deltaHeight)/1e6
1075 1152 #
1076 1153 # dataOut.data = self.__arrayBuffer
1077 1154 #
1078 1155 # self.__startIndex += self.__newNSamples
1079 1156 #
1080 1157 # return No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now