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