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