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