##// END OF EJS Templates
jrodataIO.py: Adicion del parametro LOCALTIME para la lectura de datos....
Miguel Valdez -
r234:039d4869c5dd
parent child
Show More
@@ -1,2560 +1,2562
1 1 '''
2 2
3 3 $Author: murco $
4 4 $Id: JRODataIO.py 169 2012-11-19 21:57:03Z murco $
5 5 '''
6 6
7 7 import os, sys
8 8 import glob
9 9 import time
10 10 import numpy
11 11 import fnmatch
12 12 import time, datetime
13 13
14 14 from jrodata import *
15 15 from jroheaderIO import *
16 16 from jroprocessing import *
17 17
18 LOCALTIME = -18000
19
18 20 def isNumber(str):
19 21 """
20 22 Chequea si el conjunto de caracteres que componen un string puede ser convertidos a un numero.
21 23
22 24 Excepciones:
23 25 Si un determinado string no puede ser convertido a numero
24 26 Input:
25 27 str, string al cual se le analiza para determinar si convertible a un numero o no
26 28
27 29 Return:
28 30 True : si el string es uno numerico
29 31 False : no es un string numerico
30 32 """
31 33 try:
32 34 float( str )
33 35 return True
34 36 except:
35 37 return False
36 38
37 39 def isThisFileinRange(filename, startUTSeconds, endUTSeconds):
38 40 """
39 41 Esta funcion determina si un archivo de datos se encuentra o no dentro del rango de fecha especificado.
40 42
41 43 Inputs:
42 44 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
43 45
44 46 startUTSeconds : fecha inicial del rango seleccionado. La fecha esta dada en
45 47 segundos contados desde 01/01/1970.
46 48 endUTSeconds : fecha final del rango seleccionado. La fecha esta dada en
47 49 segundos contados desde 01/01/1970.
48 50
49 51 Return:
50 52 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
51 53 fecha especificado, de lo contrario retorna False.
52 54
53 55 Excepciones:
54 56 Si el archivo no existe o no puede ser abierto
55 57 Si la cabecera no puede ser leida.
56 58
57 59 """
58 basicHeaderObj = BasicHeader()
60 basicHeaderObj = BasicHeader(LOCALTIME)
59 61
60 62 try:
61 63 fp = open(filename,'rb')
62 64 except:
63 65 raise IOError, "The file %s can't be opened" %(filename)
64 66
65 67 sts = basicHeaderObj.read(fp)
66 68 fp.close()
67 69
68 70 if not(sts):
69 71 print "Skipping the file %s because it has not a valid header" %(filename)
70 72 return 0
71 73
72 74 if not ((startUTSeconds <= basicHeaderObj.utc) and (endUTSeconds > basicHeaderObj.utc)):
73 75 return 0
74 76
75 77 return 1
76 78
77 79 def isFileinThisTime(filename, startTime, endTime):
78 80 """
79 81 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
80 82
81 83 Inputs:
82 84 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
83 85
84 86 startTime : tiempo inicial del rango seleccionado en formato datetime.time
85 87
86 88 endTime : tiempo final del rango seleccionado en formato datetime.time
87 89
88 90 Return:
89 91 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
90 92 fecha especificado, de lo contrario retorna False.
91 93
92 94 Excepciones:
93 95 Si el archivo no existe o no puede ser abierto
94 96 Si la cabecera no puede ser leida.
95 97
96 98 """
97 99
98 100
99 101 try:
100 102 fp = open(filename,'rb')
101 103 except:
102 104 raise IOError, "The file %s can't be opened" %(filename)
103 105
104 basicHeaderObj = BasicHeader()
106 basicHeaderObj = BasicHeader(LOCALTIME)
105 107 sts = basicHeaderObj.read(fp)
106 108 fp.close()
107 109
108 110 thisTime = basicHeaderObj.datatime.time()
109 111
110 112 if not(sts):
111 113 print "Skipping the file %s because it has not a valid header" %(filename)
112 114 return 0
113 115
114 116 if not ((startTime <= thisTime) and (endTime > thisTime)):
115 117 return 0
116 118
117 119 return 1
118 120
119 121 def getlastFileFromPath(path, ext):
120 122 """
121 123 Depura el fileList dejando solo los que cumplan el formato de "PYYYYDDDSSS.ext"
122 124 al final de la depuracion devuelve el ultimo file de la lista que quedo.
123 125
124 126 Input:
125 127 fileList : lista conteniendo todos los files (sin path) que componen una determinada carpeta
126 128 ext : extension de los files contenidos en una carpeta
127 129
128 130 Return:
129 131 El ultimo file de una determinada carpeta, no se considera el path.
130 132 """
131 133 validFilelist = []
132 134 fileList = os.listdir(path)
133 135
134 136 # 0 1234 567 89A BCDE
135 137 # H YYYY DDD SSS .ext
136 138
137 139 for file in fileList:
138 140 try:
139 141 year = int(file[1:5])
140 142 doy = int(file[5:8])
141 143
142 144
143 145 except:
144 146 continue
145 147
146 148 if (os.path.splitext(file)[-1].lower() != ext.lower()):
147 149 continue
148 150
149 151 validFilelist.append(file)
150 152
151 153 if validFilelist:
152 154 validFilelist = sorted( validFilelist, key=str.lower )
153 155 return validFilelist[-1]
154 156
155 157 return None
156 158
157 159 def checkForRealPath(path, year, doy, set, ext):
158 160 """
159 161 Por ser Linux Case Sensitive entonces checkForRealPath encuentra el nombre correcto de un path,
160 162 Prueba por varias combinaciones de nombres entre mayusculas y minusculas para determinar
161 163 el path exacto de un determinado file.
162 164
163 165 Example :
164 166 nombre correcto del file es .../.../D2009307/P2009307367.ext
165 167
166 168 Entonces la funcion prueba con las siguientes combinaciones
167 169 .../.../y2009307367.ext
168 170 .../.../Y2009307367.ext
169 171 .../.../x2009307/y2009307367.ext
170 172 .../.../x2009307/Y2009307367.ext
171 173 .../.../X2009307/y2009307367.ext
172 174 .../.../X2009307/Y2009307367.ext
173 175 siendo para este caso, la ultima combinacion de letras, identica al file buscado
174 176
175 177 Return:
176 178 Si encuentra la cobinacion adecuada devuelve el path completo y el nombre del file
177 179 caso contrario devuelve None como path y el la ultima combinacion de nombre en mayusculas
178 180 para el filename
179 181 """
180 182 fullfilename = None
181 183 find_flag = False
182 184 filename = None
183 185
184 186 prefixDirList = [None,'d','D']
185 187 if ext.lower() == ".r": #voltage
186 188 prefixFileList = ['d','D']
187 189 elif ext.lower() == ".pdata": #spectra
188 190 prefixFileList = ['p','P']
189 191 else:
190 192 return None, filename
191 193
192 194 #barrido por las combinaciones posibles
193 195 for prefixDir in prefixDirList:
194 196 thispath = path
195 197 if prefixDir != None:
196 198 #formo el nombre del directorio xYYYYDDD (x=d o x=D)
197 199 thispath = os.path.join(path, "%s%04d%03d" % ( prefixDir, year, doy ))
198 200
199 201 for prefixFile in prefixFileList: #barrido por las dos combinaciones posibles de "D"
200 202 filename = "%s%04d%03d%03d%s" % ( prefixFile, year, doy, set, ext ) #formo el nombre del file xYYYYDDDSSS.ext
201 203 fullfilename = os.path.join( thispath, filename ) #formo el path completo
202 204
203 205 if os.path.exists( fullfilename ): #verifico que exista
204 206 find_flag = True
205 207 break
206 208 if find_flag:
207 209 break
208 210
209 211 if not(find_flag):
210 212 return None, filename
211 213
212 214 return fullfilename, filename
213 215
214 216 class JRODataIO:
215 217
216 218 c = 3E8
217 219
218 220 isConfig = False
219 221
220 basicHeaderObj = BasicHeader()
222 basicHeaderObj = BasicHeader(LOCALTIME)
221 223
222 224 systemHeaderObj = SystemHeader()
223 225
224 226 radarControllerHeaderObj = RadarControllerHeader()
225 227
226 228 processingHeaderObj = ProcessingHeader()
227 229
228 230 online = 0
229 231
230 232 dtype = None
231 233
232 234 pathList = []
233 235
234 236 filenameList = []
235 237
236 238 filename = None
237 239
238 240 ext = None
239 241
240 242 flagIsNewFile = 1
241 243
242 244 flagTimeBlock = 0
243 245
244 246 flagIsNewBlock = 0
245 247
246 248 fp = None
247 249
248 250 firstHeaderSize = 0
249 251
250 252 basicHeaderSize = 24
251 253
252 254 versionFile = 1103
253 255
254 256 fileSize = None
255 257
256 258 ippSeconds = None
257 259
258 260 fileSizeByHeader = None
259 261
260 262 fileIndex = None
261 263
262 264 profileIndex = None
263 265
264 266 blockIndex = None
265 267
266 268 nTotalBlocks = None
267 269
268 270 maxTimeStep = 30
269 271
270 272 lastUTTime = None
271 273
272 274 datablock = None
273 275
274 276 dataOut = None
275 277
276 278 blocksize = None
277 279
278 280 def __init__(self):
279 281
280 282 raise ValueError, "Not implemented"
281 283
282 284 def run(self):
283 285
284 286 raise ValueError, "Not implemented"
285 287
286 288 def getOutput(self):
287 289
288 290 return self.dataOut
289 291
290 292 class JRODataReader(JRODataIO, ProcessingUnit):
291 293
292 294 nReadBlocks = 0
293 295
294 296 delay = 10 #number of seconds waiting a new file
295 297
296 298 nTries = 3 #quantity tries
297 299
298 300 nFiles = 3 #number of files for searching
299 301
300 302 flagNoMoreFiles = 0
301 303
302 304 def __init__(self):
303 305
304 306 """
305 307
306 308 """
307 309
308 310 raise ValueError, "This method has not been implemented"
309 311
310 312
311 313 def createObjByDefault(self):
312 314 """
313 315
314 316 """
315 317 raise ValueError, "This method has not been implemented"
316 318
317 319 def getBlockDimension(self):
318 320
319 321 raise ValueError, "No implemented"
320 322
321 323 def __searchFilesOffLine(self,
322 324 path,
323 325 startDate,
324 326 endDate,
325 327 startTime=datetime.time(0,0,0),
326 328 endTime=datetime.time(23,59,59),
327 329 set=None,
328 330 expLabel='',
329 331 ext='.r',
330 332 walk=True):
331 333
332 334 pathList = []
333 335
334 336 if not walk:
335 337 pathList.append(path)
336 338
337 339 else:
338 340 dirList = []
339 341 for thisPath in os.listdir(path):
340 342 if os.path.isdir(os.path.join(path,thisPath)):
341 343 dirList.append(thisPath)
342 344
343 345 if not(dirList):
344 346 return None, None
345 347
346 348 thisDate = startDate
347 349
348 350 while(thisDate <= endDate):
349 351 year = thisDate.timetuple().tm_year
350 352 doy = thisDate.timetuple().tm_yday
351 353
352 354 match = fnmatch.filter(dirList, '?' + '%4.4d%3.3d' % (year,doy))
353 355 if len(match) == 0:
354 356 thisDate += datetime.timedelta(1)
355 357 continue
356 358
357 359 pathList.append(os.path.join(path,match[0],expLabel))
358 360 thisDate += datetime.timedelta(1)
359 361
360 362 if pathList == []:
361 363 print "Any folder found into date range %s-%s" %(startDate, endDate)
362 364 return None, None
363 365
364 366 print "%d folder(s) found [%s, ...]" %(len(pathList), pathList[0])
365 367
366 368 filenameList = []
367 369 for thisPath in pathList:
368 370
369 371 fileList = glob.glob1(thisPath, "*%s" %ext)
370 372 fileList.sort()
371 373
372 374 for file in fileList:
373 375
374 376 filename = os.path.join(thisPath,file)
375 377
376 378 if isFileinThisTime(filename, startTime, endTime):
377 379 filenameList.append(filename)
378 380
379 381 if not(filenameList):
380 382 print "Any file found into time range %s-%s" %(startTime, endTime)
381 383 return None, None
382 384
383 385 self.filenameList = filenameList
384 386
385 387 return pathList, filenameList
386 388
387 389 def __searchFilesOnLine(self, path, expLabel = "", ext = None, walk=True):
388 390
389 391 """
390 392 Busca el ultimo archivo de la ultima carpeta (determinada o no por startDateTime) y
391 393 devuelve el archivo encontrado ademas de otros datos.
392 394
393 395 Input:
394 396 path : carpeta donde estan contenidos los files que contiene data
395 397
396 398 expLabel : Nombre del subexperimento (subfolder)
397 399
398 400 ext : extension de los files
399 401
400 402 walk : Si es habilitado no realiza busquedas dentro de los ubdirectorios (doypath)
401 403
402 404 Return:
403 405 directory : eL directorio donde esta el file encontrado
404 406 filename : el ultimo file de una determinada carpeta
405 407 year : el anho
406 408 doy : el numero de dia del anho
407 409 set : el set del archivo
408 410
409 411
410 412 """
411 413 dirList = []
412 414
413 415 if walk:
414 416
415 417 #Filtra solo los directorios
416 418 for thisPath in os.listdir(path):
417 419 if os.path.isdir(os.path.join(path, thisPath)):
418 420 dirList.append(thisPath)
419 421
420 422 if not(dirList):
421 423 return None, None, None, None, None
422 424
423 425 dirList = sorted( dirList, key=str.lower )
424 426
425 427 doypath = dirList[-1]
426 428 fullpath = os.path.join(path, doypath, expLabel)
427 429
428 430 else:
429 431 fullpath = path
430 432
431 433 filename = getlastFileFromPath(fullpath, ext)
432 434
433 435 if not(filename):
434 436 return None, None, None, None, None
435 437
436 438 if not(self.__verifyFile(os.path.join(fullpath, filename))):
437 439 return None, None, None, None, None
438 440
439 441 year = int( filename[1:5] )
440 442 doy = int( filename[5:8] )
441 443 set = int( filename[8:11] )
442 444
443 445 return fullpath, filename, year, doy, set
444 446
445 447
446 448
447 449 def __setNextFileOffline(self):
448 450
449 451 idFile = self.fileIndex
450 452
451 453 while (True):
452 454 idFile += 1
453 455 if not(idFile < len(self.filenameList)):
454 456 self.flagNoMoreFiles = 1
455 457 print "No more Files"
456 458 return 0
457 459
458 460 filename = self.filenameList[idFile]
459 461
460 462 if not(self.__verifyFile(filename)):
461 463 continue
462 464
463 465 fileSize = os.path.getsize(filename)
464 466 fp = open(filename,'rb')
465 467 break
466 468
467 469 self.flagIsNewFile = 1
468 470 self.fileIndex = idFile
469 471 self.filename = filename
470 472 self.fileSize = fileSize
471 473 self.fp = fp
472 474
473 475 print "Setting the file: %s"%self.filename
474 476
475 477 return 1
476 478
477 479 def __setNextFileOnline(self):
478 480 """
479 481 Busca el siguiente file que tenga suficiente data para ser leida, dentro de un folder especifico, si
480 482 no encuentra un file valido espera un tiempo determinado y luego busca en los posibles n files
481 483 siguientes.
482 484
483 485 Affected:
484 486 self.flagIsNewFile
485 487 self.filename
486 488 self.fileSize
487 489 self.fp
488 490 self.set
489 491 self.flagNoMoreFiles
490 492
491 493 Return:
492 494 0 : si luego de una busqueda del siguiente file valido este no pudo ser encontrado
493 495 1 : si el file fue abierto con exito y esta listo a ser leido
494 496
495 497 Excepciones:
496 498 Si un determinado file no puede ser abierto
497 499 """
498 500 nFiles = 0
499 501 fileOk_flag = False
500 502 firstTime_flag = True
501 503
502 504 self.set += 1
503 505
504 506 #busca el 1er file disponible
505 507 fullfilename, filename = checkForRealPath( self.path, self.year, self.doy, self.set, self.ext )
506 508 if fullfilename:
507 509 if self.__verifyFile(fullfilename, False):
508 510 fileOk_flag = True
509 511
510 512 #si no encuentra un file entonces espera y vuelve a buscar
511 513 if not(fileOk_flag):
512 514 for nFiles in range(self.nFiles+1): #busco en los siguientes self.nFiles+1 files posibles
513 515
514 516 if firstTime_flag: #si es la 1era vez entonces hace el for self.nTries veces
515 517 tries = self.nTries
516 518 else:
517 519 tries = 1 #si no es la 1era vez entonces solo lo hace una vez
518 520
519 521 for nTries in range( tries ):
520 522 if firstTime_flag:
521 523 print "\tWaiting %0.2f sec for the file \"%s\" , try %03d ..." % ( self.delay, filename, nTries+1 )
522 524 time.sleep( self.delay )
523 525 else:
524 526 print "\tSearching next \"%s%04d%03d%03d%s\" file ..." % (self.optchar, self.year, self.doy, self.set, self.ext)
525 527
526 528 fullfilename, filename = checkForRealPath( self.path, self.year, self.doy, self.set, self.ext )
527 529 if fullfilename:
528 530 if self.__verifyFile(fullfilename):
529 531 fileOk_flag = True
530 532 break
531 533
532 534 if fileOk_flag:
533 535 break
534 536
535 537 firstTime_flag = False
536 538
537 539 print "\tSkipping the file \"%s\" due to this file doesn't exist" % filename
538 540 self.set += 1
539 541
540 542 if nFiles == (self.nFiles-1): #si no encuentro el file buscado cambio de carpeta y busco en la siguiente carpeta
541 543 self.set = 0
542 544 self.doy += 1
543 545
544 546 if fileOk_flag:
545 547 self.fileSize = os.path.getsize( fullfilename )
546 548 self.filename = fullfilename
547 549 self.flagIsNewFile = 1
548 550 if self.fp != None: self.fp.close()
549 551 self.fp = open(fullfilename, 'rb')
550 552 self.flagNoMoreFiles = 0
551 553 print 'Setting the file: %s' % fullfilename
552 554 else:
553 555 self.fileSize = 0
554 556 self.filename = None
555 557 self.flagIsNewFile = 0
556 558 self.fp = None
557 559 self.flagNoMoreFiles = 1
558 560 print 'No more Files'
559 561
560 562 return fileOk_flag
561 563
562 564
563 565 def setNextFile(self):
564 566 if self.fp != None:
565 567 self.fp.close()
566 568
567 569 if self.online:
568 570 newFile = self.__setNextFileOnline()
569 571 else:
570 572 newFile = self.__setNextFileOffline()
571 573
572 574 if not(newFile):
573 575 return 0
574 576
575 577 self.__readFirstHeader()
576 578 self.nReadBlocks = 0
577 579 return 1
578 580
579 581 def __waitNewBlock(self):
580 582 """
581 583 Return 1 si se encontro un nuevo bloque de datos, 0 de otra forma.
582 584
583 585 Si el modo de lectura es OffLine siempre retorn 0
584 586 """
585 587 if not self.online:
586 588 return 0
587 589
588 590 if (self.nReadBlocks >= self.processingHeaderObj.dataBlocksPerFile):
589 591 return 0
590 592
591 593 currentPointer = self.fp.tell()
592 594
593 595 neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize
594 596
595 597 for nTries in range( self.nTries ):
596 598
597 599 self.fp.close()
598 600 self.fp = open( self.filename, 'rb' )
599 601 self.fp.seek( currentPointer )
600 602
601 603 self.fileSize = os.path.getsize( self.filename )
602 604 currentSize = self.fileSize - currentPointer
603 605
604 606 if ( currentSize >= neededSize ):
605 607 self.__rdBasicHeader()
606 608 return 1
607 609
608 610 print "\tWaiting %0.2f seconds for the next block, try %03d ..." % (self.delay, nTries+1)
609 611 time.sleep( self.delay )
610 612
611 613
612 614 return 0
613 615
614 616 def __setNewBlock(self):
615 617
616 618 if self.fp == None:
617 619 return 0
618 620
619 621 if self.flagIsNewFile:
620 622 return 1
621 623
622 624 self.lastUTTime = self.basicHeaderObj.utc
623 625 currentSize = self.fileSize - self.fp.tell()
624 626 neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize
625 627
626 628 if (currentSize >= neededSize):
627 629 self.__rdBasicHeader()
628 630 return 1
629 631
630 632 if self.__waitNewBlock():
631 633 return 1
632 634
633 635 if not(self.setNextFile()):
634 636 return 0
635 637
636 638 deltaTime = self.basicHeaderObj.utc - self.lastUTTime #
637 639
638 640 self.flagTimeBlock = 0
639 641
640 642 if deltaTime > self.maxTimeStep:
641 643 self.flagTimeBlock = 1
642 644
643 645 return 1
644 646
645 647
646 648 def readNextBlock(self):
647 649 if not(self.__setNewBlock()):
648 650 return 0
649 651
650 652 if not(self.readBlock()):
651 653 return 0
652 654
653 655 return 1
654 656
655 657 def __rdProcessingHeader(self, fp=None):
656 658 if fp == None:
657 659 fp = self.fp
658 660
659 661 self.processingHeaderObj.read(fp)
660 662
661 663 def __rdRadarControllerHeader(self, fp=None):
662 664 if fp == None:
663 665 fp = self.fp
664 666
665 667 self.radarControllerHeaderObj.read(fp)
666 668
667 669 def __rdSystemHeader(self, fp=None):
668 670 if fp == None:
669 671 fp = self.fp
670 672
671 673 self.systemHeaderObj.read(fp)
672 674
673 675 def __rdBasicHeader(self, fp=None):
674 676 if fp == None:
675 677 fp = self.fp
676 678
677 679 self.basicHeaderObj.read(fp)
678 680
679 681
680 682 def __readFirstHeader(self):
681 683 self.__rdBasicHeader()
682 684 self.__rdSystemHeader()
683 685 self.__rdRadarControllerHeader()
684 686 self.__rdProcessingHeader()
685 687
686 688 self.firstHeaderSize = self.basicHeaderObj.size
687 689
688 690 datatype = int(numpy.log2((self.processingHeaderObj.processFlags & PROCFLAG.DATATYPE_MASK))-numpy.log2(PROCFLAG.DATATYPE_CHAR))
689 691 if datatype == 0:
690 692 datatype_str = numpy.dtype([('real','<i1'),('imag','<i1')])
691 693 elif datatype == 1:
692 694 datatype_str = numpy.dtype([('real','<i2'),('imag','<i2')])
693 695 elif datatype == 2:
694 696 datatype_str = numpy.dtype([('real','<i4'),('imag','<i4')])
695 697 elif datatype == 3:
696 698 datatype_str = numpy.dtype([('real','<i8'),('imag','<i8')])
697 699 elif datatype == 4:
698 700 datatype_str = numpy.dtype([('real','<f4'),('imag','<f4')])
699 701 elif datatype == 5:
700 702 datatype_str = numpy.dtype([('real','<f8'),('imag','<f8')])
701 703 else:
702 704 raise ValueError, 'Data type was not defined'
703 705
704 706 self.dtype = datatype_str
705 707 self.ippSeconds = 2 * 1000 * self.radarControllerHeaderObj.ipp / self.c
706 708 self.fileSizeByHeader = self.processingHeaderObj.dataBlocksPerFile * self.processingHeaderObj.blockSize + self.firstHeaderSize + self.basicHeaderSize*(self.processingHeaderObj.dataBlocksPerFile - 1)
707 709 # self.dataOut.channelList = numpy.arange(self.systemHeaderObj.numChannels)
708 710 # self.dataOut.channelIndexList = numpy.arange(self.systemHeaderObj.numChannels)
709 711 self.getBlockDimension()
710 712
711 713
712 714 def __verifyFile(self, filename, msgFlag=True):
713 715 msg = None
714 716 try:
715 717 fp = open(filename, 'rb')
716 718 currentPosition = fp.tell()
717 719 except:
718 720 if msgFlag:
719 721 print "The file %s can't be opened" % (filename)
720 722 return False
721 723
722 724 neededSize = self.processingHeaderObj.blockSize + self.firstHeaderSize
723 725
724 726 if neededSize == 0:
725 basicHeaderObj = BasicHeader()
727 basicHeaderObj = BasicHeader(LOCALTIME)
726 728 systemHeaderObj = SystemHeader()
727 729 radarControllerHeaderObj = RadarControllerHeader()
728 730 processingHeaderObj = ProcessingHeader()
729 731
730 732 try:
731 733 if not( basicHeaderObj.read(fp) ): raise IOError
732 734 if not( systemHeaderObj.read(fp) ): raise IOError
733 735 if not( radarControllerHeaderObj.read(fp) ): raise IOError
734 736 if not( processingHeaderObj.read(fp) ): raise IOError
735 737 data_type = int(numpy.log2((processingHeaderObj.processFlags & PROCFLAG.DATATYPE_MASK))-numpy.log2(PROCFLAG.DATATYPE_CHAR))
736 738
737 739 neededSize = processingHeaderObj.blockSize + basicHeaderObj.size
738 740
739 741 except:
740 742 if msgFlag:
741 743 print "\tThe file %s is empty or it hasn't enough data" % filename
742 744
743 745 fp.close()
744 746 return False
745 747 else:
746 748 msg = "\tSkipping the file %s due to it hasn't enough data" %filename
747 749
748 750 fp.close()
749 751 fileSize = os.path.getsize(filename)
750 752 currentSize = fileSize - currentPosition
751 753 if currentSize < neededSize:
752 754 if msgFlag and (msg != None):
753 755 print msg #print"\tSkipping the file %s due to it hasn't enough data" %filename
754 756 return False
755 757
756 758 return True
757 759
758 760 def setup(self,
759 761 path=None,
760 762 startDate=None,
761 763 endDate=None,
762 764 startTime=datetime.time(0,0,0),
763 765 endTime=datetime.time(23,59,59),
764 766 set=0,
765 767 expLabel = "",
766 768 ext = None,
767 769 online = False,
768 770 delay = 60,
769 771 walk = True):
770 772
771 773 if path == None:
772 774 raise ValueError, "The path is not valid"
773 775
774 776 if ext == None:
775 777 ext = self.ext
776 778
777 779 if online:
778 780 print "Searching files in online mode..."
779 781
780 782 for nTries in range( self.nTries ):
781 783 fullpath, file, year, doy, set = self.__searchFilesOnLine(path=path, expLabel=expLabel, ext=ext, walk=walk)
782 784
783 785 if fullpath:
784 786 break
785 787
786 788 print '\tWaiting %0.2f sec for an valid file in %s: try %02d ...' % (self.delay, path, nTries+1)
787 789 time.sleep( self.delay )
788 790
789 791 if not(fullpath):
790 792 print "There 'isn't valied files in %s" % path
791 793 return None
792 794
793 795 self.year = year
794 796 self.doy = doy
795 797 self.set = set - 1
796 798 self.path = path
797 799
798 800 else:
799 801 print "Searching files in offline mode ..."
800 802 pathList, filenameList = self.__searchFilesOffLine(path, startDate=startDate, endDate=endDate,
801 803 startTime=startTime, endTime=endTime,
802 804 set=set, expLabel=expLabel, ext=ext,
803 805 walk=walk)
804 806
805 807 if not(pathList):
806 808 print "No *%s files into the folder %s \nfor the range: %s - %s"%(ext, path,
807 809 datetime.datetime.combine(startDate,startTime).ctime(),
808 810 datetime.datetime.combine(endDate,endTime).ctime())
809 811
810 812 sys.exit(-1)
811 813
812 814
813 815 self.fileIndex = -1
814 816 self.pathList = pathList
815 817 self.filenameList = filenameList
816 818
817 819 self.online = online
818 820 self.delay = delay
819 821 ext = ext.lower()
820 822 self.ext = ext
821 823
822 824 if not(self.setNextFile()):
823 825 if (startDate!=None) and (endDate!=None):
824 826 print "No files in range: %s - %s" %(datetime.datetime.combine(startDate,startTime).ctime(), datetime.datetime.combine(endDate,endTime).ctime())
825 827 elif startDate != None:
826 828 print "No files in range: %s" %(datetime.datetime.combine(startDate,startTime).ctime())
827 829 else:
828 830 print "No files"
829 831
830 832 sys.exit(-1)
831 833
832 834 # self.updateDataHeader()
833 835
834 836 return self.dataOut
835 837
836 838 def getData():
837 839
838 840 raise ValueError, "This method has not been implemented"
839 841
840 842 def hasNotDataInBuffer():
841 843
842 844 raise ValueError, "This method has not been implemented"
843 845
844 846 def readBlock():
845 847
846 848 raise ValueError, "This method has not been implemented"
847 849
848 850 def isEndProcess(self):
849 851
850 852 return self.flagNoMoreFiles
851 853
852 854 def printReadBlocks(self):
853 855
854 856 print "Number of read blocks per file %04d" %self.nReadBlocks
855 857
856 858 def printTotalBlocks(self):
857 859
858 860 print "Number of read blocks %04d" %self.nTotalBlocks
859 861
860 862 def printInfo(self):
861 863
862 864 print self.basicHeaderObj.printInfo()
863 865 print self.systemHeaderObj.printInfo()
864 866 print self.radarControllerHeaderObj.printInfo()
865 867 print self.processingHeaderObj.printInfo()
866 868
867 869
868 870 def run(self, **kwargs):
869 871
870 872 if not(self.isConfig):
871 873
872 874 # self.dataOut = dataOut
873 875 self.setup(**kwargs)
874 876 self.isConfig = True
875 877
876 878 self.getData()
877 879
878 880 class JRODataWriter(JRODataIO, Operation):
879 881
880 882 """
881 883 Esta clase permite escribir datos a archivos procesados (.r o ,pdata). La escritura
882 884 de los datos siempre se realiza por bloques.
883 885 """
884 886
885 887 blockIndex = 0
886 888
887 889 path = None
888 890
889 891 setFile = None
890 892
891 893 profilesPerBlock = None
892 894
893 895 blocksPerFile = None
894 896
895 897 nWriteBlocks = 0
896 898
897 899 def __init__(self, dataOut=None):
898 900 raise ValueError, "Not implemented"
899 901
900 902
901 903 def hasAllDataInBuffer(self):
902 904 raise ValueError, "Not implemented"
903 905
904 906
905 907 def setBlockDimension(self):
906 908 raise ValueError, "Not implemented"
907 909
908 910
909 911 def writeBlock(self):
910 912 raise ValueError, "No implemented"
911 913
912 914
913 915 def putData(self):
914 916 raise ValueError, "No implemented"
915 917
916 918 def getDataHeader(self):
917 919 """
918 920 Obtiene una copia del First Header
919 921
920 922 Affected:
921 923
922 924 self.basicHeaderObj
923 925 self.systemHeaderObj
924 926 self.radarControllerHeaderObj
925 927 self.processingHeaderObj self.
926 928
927 929 Return:
928 930 None
929 931 """
930 932
931 933 raise ValueError, "No implemented"
932 934
933 935 def getBasicHeader(self):
934 936
935 937 self.basicHeaderObj.size = self.basicHeaderSize #bytes
936 938 self.basicHeaderObj.version = self.versionFile
937 939 self.basicHeaderObj.dataBlock = self.nTotalBlocks
938 940
939 941 utc = numpy.floor(self.dataOut.utctime)
940 942 milisecond = (self.dataOut.utctime - utc)* 1000.0
941 943
942 944 self.basicHeaderObj.utc = utc
943 945 self.basicHeaderObj.miliSecond = milisecond
944 946 self.basicHeaderObj.timeZone = 0
945 947 self.basicHeaderObj.dstFlag = 0
946 948 self.basicHeaderObj.errorCount = 0
947 949
948 950 def __writeFirstHeader(self):
949 951 """
950 952 Escribe el primer header del file es decir el Basic header y el Long header (SystemHeader, RadarControllerHeader, ProcessingHeader)
951 953
952 954 Affected:
953 955 __dataType
954 956
955 957 Return:
956 958 None
957 959 """
958 960
959 961 # CALCULAR PARAMETROS
960 962
961 963 sizeLongHeader = self.systemHeaderObj.size + self.radarControllerHeaderObj.size + self.processingHeaderObj.size
962 964 self.basicHeaderObj.size = self.basicHeaderSize + sizeLongHeader
963 965
964 966 self.basicHeaderObj.write(self.fp)
965 967 self.systemHeaderObj.write(self.fp)
966 968 self.radarControllerHeaderObj.write(self.fp)
967 969 self.processingHeaderObj.write(self.fp)
968 970
969 971 self.dtype = self.dataOut.dtype
970 972
971 973 def __setNewBlock(self):
972 974 """
973 975 Si es un nuevo file escribe el First Header caso contrario escribe solo el Basic Header
974 976
975 977 Return:
976 978 0 : si no pudo escribir nada
977 979 1 : Si escribio el Basic el First Header
978 980 """
979 981 if self.fp == None:
980 982 self.setNextFile()
981 983
982 984 if self.flagIsNewFile:
983 985 return 1
984 986
985 987 if self.blockIndex < self.processingHeaderObj.dataBlocksPerFile:
986 988 self.basicHeaderObj.write(self.fp)
987 989 return 1
988 990
989 991 if not( self.setNextFile() ):
990 992 return 0
991 993
992 994 return 1
993 995
994 996
995 997 def writeNextBlock(self):
996 998 """
997 999 Selecciona el bloque siguiente de datos y los escribe en un file
998 1000
999 1001 Return:
1000 1002 0 : Si no hizo pudo escribir el bloque de datos
1001 1003 1 : Si no pudo escribir el bloque de datos
1002 1004 """
1003 1005 if not( self.__setNewBlock() ):
1004 1006 return 0
1005 1007
1006 1008 self.writeBlock()
1007 1009
1008 1010 return 1
1009 1011
1010 1012 def setNextFile(self):
1011 1013 """
1012 1014 Determina el siguiente file que sera escrito
1013 1015
1014 1016 Affected:
1015 1017 self.filename
1016 1018 self.subfolder
1017 1019 self.fp
1018 1020 self.setFile
1019 1021 self.flagIsNewFile
1020 1022
1021 1023 Return:
1022 1024 0 : Si el archivo no puede ser escrito
1023 1025 1 : Si el archivo esta listo para ser escrito
1024 1026 """
1025 1027 ext = self.ext
1026 1028 path = self.path
1027 1029
1028 1030 if self.fp != None:
1029 1031 self.fp.close()
1030 1032
1031 1033 timeTuple = time.localtime( self.dataOut.dataUtcTime)
1032 1034 subfolder = 'D%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday)
1033 1035
1034 1036 fullpath = os.path.join( path, subfolder )
1035 1037 if not( os.path.exists(fullpath) ):
1036 1038 os.mkdir(fullpath)
1037 1039 self.setFile = -1 #inicializo mi contador de seteo
1038 1040 else:
1039 1041 filesList = os.listdir( fullpath )
1040 1042 if len( filesList ) > 0:
1041 1043 filesList = sorted( filesList, key=str.lower )
1042 1044 filen = filesList[-1]
1043 1045 # el filename debera tener el siguiente formato
1044 1046 # 0 1234 567 89A BCDE (hex)
1045 1047 # x YYYY DDD SSS .ext
1046 1048 if isNumber( filen[8:11] ):
1047 1049 self.setFile = int( filen[8:11] ) #inicializo mi contador de seteo al seteo del ultimo file
1048 1050 else:
1049 1051 self.setFile = -1
1050 1052 else:
1051 1053 self.setFile = -1 #inicializo mi contador de seteo
1052 1054
1053 1055 setFile = self.setFile
1054 1056 setFile += 1
1055 1057
1056 1058 file = '%s%4.4d%3.3d%3.3d%s' % (self.optchar,
1057 1059 timeTuple.tm_year,
1058 1060 timeTuple.tm_yday,
1059 1061 setFile,
1060 1062 ext )
1061 1063
1062 1064 filename = os.path.join( path, subfolder, file )
1063 1065
1064 1066 fp = open( filename,'wb' )
1065 1067
1066 1068 self.blockIndex = 0
1067 1069
1068 1070 #guardando atributos
1069 1071 self.filename = filename
1070 1072 self.subfolder = subfolder
1071 1073 self.fp = fp
1072 1074 self.setFile = setFile
1073 1075 self.flagIsNewFile = 1
1074 1076
1075 1077 self.getDataHeader()
1076 1078
1077 1079 print 'Writing the file: %s'%self.filename
1078 1080
1079 1081 self.__writeFirstHeader()
1080 1082
1081 1083 return 1
1082 1084
1083 1085 def setup(self, dataOut, path, blocksPerFile, profilesPerBlock=None, set=0, ext=None):
1084 1086 """
1085 1087 Setea el tipo de formato en la cual sera guardada la data y escribe el First Header
1086 1088
1087 1089 Inputs:
1088 1090 path : el path destino en el cual se escribiran los files a crear
1089 1091 format : formato en el cual sera salvado un file
1090 1092 set : el setebo del file
1091 1093
1092 1094 Return:
1093 1095 0 : Si no realizo un buen seteo
1094 1096 1 : Si realizo un buen seteo
1095 1097 """
1096 1098
1097 1099 if ext == None:
1098 1100 ext = self.ext
1099 1101
1100 1102 ext = ext.lower()
1101 1103
1102 1104 self.ext = ext
1103 1105
1104 1106 self.path = path
1105 1107
1106 1108 self.setFile = set - 1
1107 1109
1108 1110 self.blocksPerFile = blocksPerFile
1109 1111
1110 1112 self.profilesPerBlock = profilesPerBlock
1111 1113
1112 1114 self.dataOut = dataOut
1113 1115
1114 1116 if not(self.setNextFile()):
1115 1117 print "There isn't a next file"
1116 1118 return 0
1117 1119
1118 1120 self.setBlockDimension()
1119 1121
1120 1122 return 1
1121 1123
1122 1124 def run(self, dataOut, **kwargs):
1123 1125
1124 1126 if not(self.isConfig):
1125 1127
1126 1128 self.setup(dataOut, **kwargs)
1127 1129 self.isConfig = True
1128 1130
1129 1131 self.putData()
1130 1132
1131 1133 class VoltageReader(JRODataReader):
1132 1134 """
1133 1135 Esta clase permite leer datos de voltage desde archivos en formato rawdata (.r). La lectura
1134 1136 de los datos siempre se realiza por bloques. Los datos leidos (array de 3 dimensiones:
1135 1137 perfiles*alturas*canales) son almacenados en la variable "buffer".
1136 1138
1137 1139 perfiles * alturas * canales
1138 1140
1139 1141 Esta clase contiene instancias (objetos) de las clases BasicHeader, SystemHeader,
1140 1142 RadarControllerHeader y Voltage. Los tres primeros se usan para almacenar informacion de la
1141 1143 cabecera de datos (metadata), y el cuarto (Voltage) para obtener y almacenar un perfil de
1142 1144 datos desde el "buffer" cada vez que se ejecute el metodo "getData".
1143 1145
1144 1146 Example:
1145 1147
1146 1148 dpath = "/home/myuser/data"
1147 1149
1148 1150 startTime = datetime.datetime(2010,1,20,0,0,0,0,0,0)
1149 1151
1150 1152 endTime = datetime.datetime(2010,1,21,23,59,59,0,0,0)
1151 1153
1152 1154 readerObj = VoltageReader()
1153 1155
1154 1156 readerObj.setup(dpath, startTime, endTime)
1155 1157
1156 1158 while(True):
1157 1159
1158 1160 #to get one profile
1159 1161 profile = readerObj.getData()
1160 1162
1161 1163 #print the profile
1162 1164 print profile
1163 1165
1164 1166 #If you want to see all datablock
1165 1167 print readerObj.datablock
1166 1168
1167 1169 if readerObj.flagNoMoreFiles:
1168 1170 break
1169 1171
1170 1172 """
1171 1173
1172 1174 ext = ".r"
1173 1175
1174 1176 optchar = "D"
1175 1177 dataOut = None
1176 1178
1177 1179
1178 1180 def __init__(self):
1179 1181 """
1180 1182 Inicializador de la clase VoltageReader para la lectura de datos de voltage.
1181 1183
1182 1184 Input:
1183 1185 dataOut : Objeto de la clase Voltage. Este objeto sera utilizado para
1184 1186 almacenar un perfil de datos cada vez que se haga un requerimiento
1185 1187 (getData). El perfil sera obtenido a partir del buffer de datos,
1186 1188 si el buffer esta vacio se hara un nuevo proceso de lectura de un
1187 1189 bloque de datos.
1188 1190 Si este parametro no es pasado se creara uno internamente.
1189 1191
1190 1192 Variables afectadas:
1191 1193 self.dataOut
1192 1194
1193 1195 Return:
1194 1196 None
1195 1197 """
1196 1198
1197 1199 self.isConfig = False
1198 1200
1199 1201 self.datablock = None
1200 1202
1201 1203 self.utc = 0
1202 1204
1203 1205 self.ext = ".r"
1204 1206
1205 1207 self.optchar = "D"
1206 1208
1207 self.basicHeaderObj = BasicHeader()
1209 self.basicHeaderObj = BasicHeader(LOCALTIME)
1208 1210
1209 1211 self.systemHeaderObj = SystemHeader()
1210 1212
1211 1213 self.radarControllerHeaderObj = RadarControllerHeader()
1212 1214
1213 1215 self.processingHeaderObj = ProcessingHeader()
1214 1216
1215 1217 self.online = 0
1216 1218
1217 1219 self.fp = None
1218 1220
1219 1221 self.idFile = None
1220 1222
1221 1223 self.dtype = None
1222 1224
1223 1225 self.fileSizeByHeader = None
1224 1226
1225 1227 self.filenameList = []
1226 1228
1227 1229 self.filename = None
1228 1230
1229 1231 self.fileSize = None
1230 1232
1231 1233 self.firstHeaderSize = 0
1232 1234
1233 1235 self.basicHeaderSize = 24
1234 1236
1235 1237 self.pathList = []
1236 1238
1237 1239 self.filenameList = []
1238 1240
1239 1241 self.lastUTTime = 0
1240 1242
1241 1243 self.maxTimeStep = 30
1242 1244
1243 1245 self.flagNoMoreFiles = 0
1244 1246
1245 1247 self.set = 0
1246 1248
1247 1249 self.path = None
1248 1250
1249 1251 self.profileIndex = 9999
1250 1252
1251 1253 self.delay = 3 #seconds
1252 1254
1253 1255 self.nTries = 3 #quantity tries
1254 1256
1255 1257 self.nFiles = 3 #number of files for searching
1256 1258
1257 1259 self.nReadBlocks = 0
1258 1260
1259 1261 self.flagIsNewFile = 1
1260 1262
1261 1263 self.ippSeconds = 0
1262 1264
1263 1265 self.flagTimeBlock = 0
1264 1266
1265 1267 self.flagIsNewBlock = 0
1266 1268
1267 1269 self.nTotalBlocks = 0
1268 1270
1269 1271 self.blocksize = 0
1270 1272
1271 1273 self.dataOut = self.createObjByDefault()
1272 1274
1273 1275 def createObjByDefault(self):
1274 1276
1275 1277 dataObj = Voltage()
1276 1278
1277 1279 return dataObj
1278 1280
1279 1281 def __hasNotDataInBuffer(self):
1280 1282 if self.profileIndex >= self.processingHeaderObj.profilesPerBlock:
1281 1283 return 1
1282 1284 return 0
1283 1285
1284 1286
1285 1287 def getBlockDimension(self):
1286 1288 """
1287 1289 Obtiene la cantidad de puntos a leer por cada bloque de datos
1288 1290
1289 1291 Affected:
1290 1292 self.blocksize
1291 1293
1292 1294 Return:
1293 1295 None
1294 1296 """
1295 1297 pts2read = self.processingHeaderObj.profilesPerBlock * self.processingHeaderObj.nHeights * self.systemHeaderObj.nChannels
1296 1298 self.blocksize = pts2read
1297 1299
1298 1300
1299 1301 def readBlock(self):
1300 1302 """
1301 1303 readBlock lee el bloque de datos desde la posicion actual del puntero del archivo
1302 1304 (self.fp) y actualiza todos los parametros relacionados al bloque de datos
1303 1305 (metadata + data). La data leida es almacenada en el buffer y el contador del buffer
1304 1306 es seteado a 0
1305 1307
1306 1308 Inputs:
1307 1309 None
1308 1310
1309 1311 Return:
1310 1312 None
1311 1313
1312 1314 Affected:
1313 1315 self.profileIndex
1314 1316 self.datablock
1315 1317 self.flagIsNewFile
1316 1318 self.flagIsNewBlock
1317 1319 self.nTotalBlocks
1318 1320
1319 1321 Exceptions:
1320 1322 Si un bloque leido no es un bloque valido
1321 1323 """
1322 1324
1323 1325 junk = numpy.fromfile( self.fp, self.dtype, self.blocksize )
1324 1326
1325 1327 try:
1326 1328 junk = junk.reshape( (self.processingHeaderObj.profilesPerBlock, self.processingHeaderObj.nHeights, self.systemHeaderObj.nChannels) )
1327 1329 except:
1328 1330 print "The read block (%3d) has not enough data" %self.nReadBlocks
1329 1331 return 0
1330 1332
1331 1333 junk = numpy.transpose(junk, (2,0,1))
1332 1334 self.datablock = junk['real'] + junk['imag']*1j
1333 1335
1334 1336 self.profileIndex = 0
1335 1337
1336 1338 self.flagIsNewFile = 0
1337 1339 self.flagIsNewBlock = 1
1338 1340
1339 1341 self.nTotalBlocks += 1
1340 1342 self.nReadBlocks += 1
1341 1343
1342 1344 return 1
1343 1345
1344 1346
1345 1347 def getData(self):
1346 1348 """
1347 1349 getData obtiene una unidad de datos del buffer de lectura y la copia a la clase "Voltage"
1348 1350 con todos los parametros asociados a este (metadata). cuando no hay datos en el buffer de
1349 1351 lectura es necesario hacer una nueva lectura de los bloques de datos usando "readNextBlock"
1350 1352
1351 1353 Ademas incrementa el contador del buffer en 1.
1352 1354
1353 1355 Return:
1354 1356 data : retorna un perfil de voltages (alturas * canales) copiados desde el
1355 1357 buffer. Si no hay mas archivos a leer retorna None.
1356 1358
1357 1359 Variables afectadas:
1358 1360 self.dataOut
1359 1361 self.profileIndex
1360 1362
1361 1363 Affected:
1362 1364 self.dataOut
1363 1365 self.profileIndex
1364 1366 self.flagTimeBlock
1365 1367 self.flagIsNewBlock
1366 1368 """
1367 1369
1368 1370 if self.flagNoMoreFiles:
1369 1371 self.dataOut.flagNoData = True
1370 1372 print 'Process finished'
1371 1373 return 0
1372 1374
1373 1375 self.flagTimeBlock = 0
1374 1376 self.flagIsNewBlock = 0
1375 1377
1376 1378 if self.__hasNotDataInBuffer():
1377 1379
1378 1380 if not( self.readNextBlock() ):
1379 1381 return 0
1380 1382
1381 1383 self.dataOut.dtype = self.dtype
1382 1384
1383 1385 self.dataOut.nProfiles = self.processingHeaderObj.profilesPerBlock
1384 1386
1385 1387 xf = self.processingHeaderObj.firstHeight + self.processingHeaderObj.nHeights*self.processingHeaderObj.deltaHeight
1386 1388
1387 1389 self.dataOut.heightList = numpy.arange(self.processingHeaderObj.firstHeight, xf, self.processingHeaderObj.deltaHeight)
1388 1390
1389 1391 self.dataOut.channelList = range(self.systemHeaderObj.nChannels)
1390 1392
1391 1393 self.dataOut.flagTimeBlock = self.flagTimeBlock
1392 1394
1393 1395 self.dataOut.ippSeconds = self.ippSeconds
1394 1396
1395 1397 self.dataOut.timeInterval = self.ippSeconds * self.processingHeaderObj.nCohInt
1396 1398
1397 1399 self.dataOut.nCohInt = self.processingHeaderObj.nCohInt
1398 1400
1399 1401 self.dataOut.flagShiftFFT = False
1400 1402
1401 1403 if self.processingHeaderObj.code != None:
1402 1404
1403 1405 self.dataOut.nCode = self.processingHeaderObj.nCode
1404 1406
1405 1407 self.dataOut.nBaud = self.processingHeaderObj.nBaud
1406 1408
1407 1409 self.dataOut.code = self.processingHeaderObj.code
1408 1410
1409 1411 self.dataOut.systemHeaderObj = self.systemHeaderObj.copy()
1410 1412
1411 1413 self.dataOut.radarControllerHeaderObj = self.radarControllerHeaderObj.copy()
1412 1414
1413 1415 self.dataOut.flagDecodeData = False #asumo q la data no esta decodificada
1414 1416
1415 1417 self.dataOut.flagDeflipData = False #asumo q la data no esta sin flip
1416 1418
1417 1419 self.dataOut.flagShiftFFT = False
1418 1420
1419 1421
1420 1422 # self.updateDataHeader()
1421 1423
1422 1424 #data es un numpy array de 3 dmensiones (perfiles, alturas y canales)
1423 1425
1424 1426 if self.datablock == None:
1425 1427 self.dataOut.flagNoData = True
1426 1428 return 0
1427 1429
1428 1430 self.dataOut.data = self.datablock[:,self.profileIndex,:]
1429 1431
1430 1432 self.dataOut.utctime = self.basicHeaderObj.utc + self.basicHeaderObj.miliSecond/1000. + self.profileIndex * self.ippSeconds
1431 1433
1432 1434 self.profileIndex += 1
1433 1435
1434 1436 self.dataOut.flagNoData = False
1435 1437
1436 1438 # print self.profileIndex, self.dataOut.utctime
1437 1439 # if self.profileIndex == 800:
1438 1440 # a=1
1439 1441
1440 1442
1441 1443 return self.dataOut.data
1442 1444
1443 1445
1444 1446 class VoltageWriter(JRODataWriter):
1445 1447 """
1446 1448 Esta clase permite escribir datos de voltajes a archivos procesados (.r). La escritura
1447 1449 de los datos siempre se realiza por bloques.
1448 1450 """
1449 1451
1450 1452 ext = ".r"
1451 1453
1452 1454 optchar = "D"
1453 1455
1454 1456 shapeBuffer = None
1455 1457
1456 1458
1457 1459 def __init__(self):
1458 1460 """
1459 1461 Inicializador de la clase VoltageWriter para la escritura de datos de espectros.
1460 1462
1461 1463 Affected:
1462 1464 self.dataOut
1463 1465
1464 1466 Return: None
1465 1467 """
1466 1468
1467 1469 self.nTotalBlocks = 0
1468 1470
1469 1471 self.profileIndex = 0
1470 1472
1471 1473 self.isConfig = False
1472 1474
1473 1475 self.fp = None
1474 1476
1475 1477 self.flagIsNewFile = 1
1476 1478
1477 1479 self.nTotalBlocks = 0
1478 1480
1479 1481 self.flagIsNewBlock = 0
1480 1482
1481 1483 self.setFile = None
1482 1484
1483 1485 self.dtype = None
1484 1486
1485 1487 self.path = None
1486 1488
1487 1489 self.filename = None
1488 1490
1489 self.basicHeaderObj = BasicHeader()
1491 self.basicHeaderObj = BasicHeader(LOCALTIME)
1490 1492
1491 1493 self.systemHeaderObj = SystemHeader()
1492 1494
1493 1495 self.radarControllerHeaderObj = RadarControllerHeader()
1494 1496
1495 1497 self.processingHeaderObj = ProcessingHeader()
1496 1498
1497 1499 def hasAllDataInBuffer(self):
1498 1500 if self.profileIndex >= self.processingHeaderObj.profilesPerBlock:
1499 1501 return 1
1500 1502 return 0
1501 1503
1502 1504
1503 1505 def setBlockDimension(self):
1504 1506 """
1505 1507 Obtiene las formas dimensionales del los subbloques de datos que componen un bloque
1506 1508
1507 1509 Affected:
1508 1510 self.shape_spc_Buffer
1509 1511 self.shape_cspc_Buffer
1510 1512 self.shape_dc_Buffer
1511 1513
1512 1514 Return: None
1513 1515 """
1514 1516 self.shapeBuffer = (self.processingHeaderObj.profilesPerBlock,
1515 1517 self.processingHeaderObj.nHeights,
1516 1518 self.systemHeaderObj.nChannels)
1517 1519
1518 1520 self.datablock = numpy.zeros((self.systemHeaderObj.nChannels,
1519 1521 self.processingHeaderObj.profilesPerBlock,
1520 1522 self.processingHeaderObj.nHeights),
1521 1523 dtype=numpy.dtype('complex'))
1522 1524
1523 1525
1524 1526 def writeBlock(self):
1525 1527 """
1526 1528 Escribe el buffer en el file designado
1527 1529
1528 1530 Affected:
1529 1531 self.profileIndex
1530 1532 self.flagIsNewFile
1531 1533 self.flagIsNewBlock
1532 1534 self.nTotalBlocks
1533 1535 self.blockIndex
1534 1536
1535 1537 Return: None
1536 1538 """
1537 1539 data = numpy.zeros( self.shapeBuffer, self.dtype )
1538 1540
1539 1541 junk = numpy.transpose(self.datablock, (1,2,0))
1540 1542
1541 1543 data['real'] = junk.real
1542 1544 data['imag'] = junk.imag
1543 1545
1544 1546 data = data.reshape( (-1) )
1545 1547
1546 1548 data.tofile( self.fp )
1547 1549
1548 1550 self.datablock.fill(0)
1549 1551
1550 1552 self.profileIndex = 0
1551 1553 self.flagIsNewFile = 0
1552 1554 self.flagIsNewBlock = 1
1553 1555
1554 1556 self.blockIndex += 1
1555 1557 self.nTotalBlocks += 1
1556 1558
1557 1559 def putData(self):
1558 1560 """
1559 1561 Setea un bloque de datos y luego los escribe en un file
1560 1562
1561 1563 Affected:
1562 1564 self.flagIsNewBlock
1563 1565 self.profileIndex
1564 1566
1565 1567 Return:
1566 1568 0 : Si no hay data o no hay mas files que puedan escribirse
1567 1569 1 : Si se escribio la data de un bloque en un file
1568 1570 """
1569 1571 if self.dataOut.flagNoData:
1570 1572 return 0
1571 1573
1572 1574 self.flagIsNewBlock = 0
1573 1575
1574 1576 if self.dataOut.flagTimeBlock:
1575 1577
1576 1578 self.datablock.fill(0)
1577 1579 self.profileIndex = 0
1578 1580 self.setNextFile()
1579 1581
1580 1582 if self.profileIndex == 0:
1581 1583 self.getBasicHeader()
1582 1584
1583 1585 self.datablock[:,self.profileIndex,:] = self.dataOut.data
1584 1586
1585 1587 self.profileIndex += 1
1586 1588
1587 1589 if self.hasAllDataInBuffer():
1588 1590 #if self.flagIsNewFile:
1589 1591 self.writeNextBlock()
1590 1592 # self.getDataHeader()
1591 1593
1592 1594 return 1
1593 1595
1594 1596 def __getProcessFlags(self):
1595 1597
1596 1598 processFlags = 0
1597 1599
1598 1600 dtype0 = numpy.dtype([('real','<i1'),('imag','<i1')])
1599 1601 dtype1 = numpy.dtype([('real','<i2'),('imag','<i2')])
1600 1602 dtype2 = numpy.dtype([('real','<i4'),('imag','<i4')])
1601 1603 dtype3 = numpy.dtype([('real','<i8'),('imag','<i8')])
1602 1604 dtype4 = numpy.dtype([('real','<f4'),('imag','<f4')])
1603 1605 dtype5 = numpy.dtype([('real','<f8'),('imag','<f8')])
1604 1606
1605 1607 dtypeList = [dtype0, dtype1, dtype2, dtype3, dtype4, dtype5]
1606 1608
1607 1609
1608 1610
1609 1611 datatypeValueList = [PROCFLAG.DATATYPE_CHAR,
1610 1612 PROCFLAG.DATATYPE_SHORT,
1611 1613 PROCFLAG.DATATYPE_LONG,
1612 1614 PROCFLAG.DATATYPE_INT64,
1613 1615 PROCFLAG.DATATYPE_FLOAT,
1614 1616 PROCFLAG.DATATYPE_DOUBLE]
1615 1617
1616 1618
1617 1619 for index in range(len(dtypeList)):
1618 1620 if self.dataOut.dtype == dtypeList[index]:
1619 1621 dtypeValue = datatypeValueList[index]
1620 1622 break
1621 1623
1622 1624 processFlags += dtypeValue
1623 1625
1624 1626 if self.dataOut.flagDecodeData:
1625 1627 processFlags += PROCFLAG.DECODE_DATA
1626 1628
1627 1629 if self.dataOut.flagDeflipData:
1628 1630 processFlags += PROCFLAG.DEFLIP_DATA
1629 1631
1630 1632 if self.dataOut.code != None:
1631 1633 processFlags += PROCFLAG.DEFINE_PROCESS_CODE
1632 1634
1633 1635 if self.dataOut.nCohInt > 1:
1634 1636 processFlags += PROCFLAG.COHERENT_INTEGRATION
1635 1637
1636 1638 return processFlags
1637 1639
1638 1640
1639 1641 def __getBlockSize(self):
1640 1642 '''
1641 1643 Este metodos determina el cantidad de bytes para un bloque de datos de tipo Voltage
1642 1644 '''
1643 1645
1644 1646 dtype0 = numpy.dtype([('real','<i1'),('imag','<i1')])
1645 1647 dtype1 = numpy.dtype([('real','<i2'),('imag','<i2')])
1646 1648 dtype2 = numpy.dtype([('real','<i4'),('imag','<i4')])
1647 1649 dtype3 = numpy.dtype([('real','<i8'),('imag','<i8')])
1648 1650 dtype4 = numpy.dtype([('real','<f4'),('imag','<f4')])
1649 1651 dtype5 = numpy.dtype([('real','<f8'),('imag','<f8')])
1650 1652
1651 1653 dtypeList = [dtype0, dtype1, dtype2, dtype3, dtype4, dtype5]
1652 1654 datatypeValueList = [1,2,4,8,4,8]
1653 1655 for index in range(len(dtypeList)):
1654 1656 if self.dataOut.dtype == dtypeList[index]:
1655 1657 datatypeValue = datatypeValueList[index]
1656 1658 break
1657 1659
1658 1660 blocksize = int(self.dataOut.nHeights * self.dataOut.nChannels * self.dataOut.nProfiles * datatypeValue * 2)
1659 1661
1660 1662 return blocksize
1661 1663
1662 1664 def getDataHeader(self):
1663 1665
1664 1666 """
1665 1667 Obtiene una copia del First Header
1666 1668
1667 1669 Affected:
1668 1670 self.systemHeaderObj
1669 1671 self.radarControllerHeaderObj
1670 1672 self.dtype
1671 1673
1672 1674 Return:
1673 1675 None
1674 1676 """
1675 1677
1676 1678 self.systemHeaderObj = self.dataOut.systemHeaderObj.copy()
1677 1679 self.systemHeaderObj.nChannels = self.dataOut.nChannels
1678 1680 self.radarControllerHeaderObj = self.dataOut.radarControllerHeaderObj.copy()
1679 1681
1680 1682 self.getBasicHeader()
1681 1683
1682 1684 processingHeaderSize = 40 # bytes
1683 1685 self.processingHeaderObj.dtype = 0 # Voltage
1684 1686 self.processingHeaderObj.blockSize = self.__getBlockSize()
1685 1687 self.processingHeaderObj.profilesPerBlock = self.profilesPerBlock
1686 1688 self.processingHeaderObj.dataBlocksPerFile = self.blocksPerFile
1687 1689 self.processingHeaderObj.nWindows = 1 #podria ser 1 o self.dataOut.processingHeaderObj.nWindows
1688 1690 self.processingHeaderObj.processFlags = self.__getProcessFlags()
1689 1691 self.processingHeaderObj.nCohInt = self.dataOut.nCohInt
1690 1692 self.processingHeaderObj.nIncohInt = 1 # Cuando la data de origen es de tipo Voltage
1691 1693 self.processingHeaderObj.totalSpectra = 0 # Cuando la data de origen es de tipo Voltage
1692 1694
1693 1695 if self.dataOut.code != None:
1694 1696 self.processingHeaderObj.code = self.dataOut.code
1695 1697 self.processingHeaderObj.nCode = self.dataOut.nCode
1696 1698 self.processingHeaderObj.nBaud = self.dataOut.nBaud
1697 1699 codesize = int(8 + 4 * self.dataOut.nCode * self.dataOut.nBaud)
1698 1700 processingHeaderSize += codesize
1699 1701
1700 1702 if self.processingHeaderObj.nWindows != 0:
1701 1703 self.processingHeaderObj.firstHeight = self.dataOut.heightList[0]
1702 1704 self.processingHeaderObj.deltaHeight = self.dataOut.heightList[1] - self.dataOut.heightList[0]
1703 1705 self.processingHeaderObj.nHeights = self.dataOut.nHeights
1704 1706 self.processingHeaderObj.samplesWin = self.dataOut.nHeights
1705 1707 processingHeaderSize += 12
1706 1708
1707 1709 self.processingHeaderObj.size = processingHeaderSize
1708 1710
1709 1711 class SpectraReader(JRODataReader):
1710 1712 """
1711 1713 Esta clase permite leer datos de espectros desde archivos procesados (.pdata). La lectura
1712 1714 de los datos siempre se realiza por bloques. Los datos leidos (array de 3 dimensiones)
1713 1715 son almacenados en tres buffer's para el Self Spectra, el Cross Spectra y el DC Channel.
1714 1716
1715 1717 paresCanalesIguales * alturas * perfiles (Self Spectra)
1716 1718 paresCanalesDiferentes * alturas * perfiles (Cross Spectra)
1717 1719 canales * alturas (DC Channels)
1718 1720
1719 1721 Esta clase contiene instancias (objetos) de las clases BasicHeader, SystemHeader,
1720 1722 RadarControllerHeader y Spectra. Los tres primeros se usan para almacenar informacion de la
1721 1723 cabecera de datos (metadata), y el cuarto (Spectra) para obtener y almacenar un bloque de
1722 1724 datos desde el "buffer" cada vez que se ejecute el metodo "getData".
1723 1725
1724 1726 Example:
1725 1727 dpath = "/home/myuser/data"
1726 1728
1727 1729 startTime = datetime.datetime(2010,1,20,0,0,0,0,0,0)
1728 1730
1729 1731 endTime = datetime.datetime(2010,1,21,23,59,59,0,0,0)
1730 1732
1731 1733 readerObj = SpectraReader()
1732 1734
1733 1735 readerObj.setup(dpath, startTime, endTime)
1734 1736
1735 1737 while(True):
1736 1738
1737 1739 readerObj.getData()
1738 1740
1739 1741 print readerObj.data_spc
1740 1742
1741 1743 print readerObj.data_cspc
1742 1744
1743 1745 print readerObj.data_dc
1744 1746
1745 1747 if readerObj.flagNoMoreFiles:
1746 1748 break
1747 1749
1748 1750 """
1749 1751
1750 1752 pts2read_SelfSpectra = 0
1751 1753
1752 1754 pts2read_CrossSpectra = 0
1753 1755
1754 1756 pts2read_DCchannels = 0
1755 1757
1756 1758 ext = ".pdata"
1757 1759
1758 1760 optchar = "P"
1759 1761
1760 1762 dataOut = None
1761 1763
1762 1764 nRdChannels = None
1763 1765
1764 1766 nRdPairs = None
1765 1767
1766 1768 rdPairList = []
1767 1769
1768 1770
1769 1771 def __init__(self):
1770 1772 """
1771 1773 Inicializador de la clase SpectraReader para la lectura de datos de espectros.
1772 1774
1773 1775 Inputs:
1774 1776 dataOut : Objeto de la clase Spectra. Este objeto sera utilizado para
1775 1777 almacenar un perfil de datos cada vez que se haga un requerimiento
1776 1778 (getData). El perfil sera obtenido a partir del buffer de datos,
1777 1779 si el buffer esta vacio se hara un nuevo proceso de lectura de un
1778 1780 bloque de datos.
1779 1781 Si este parametro no es pasado se creara uno internamente.
1780 1782
1781 1783 Affected:
1782 1784 self.dataOut
1783 1785
1784 1786 Return : None
1785 1787 """
1786 1788
1787 1789 self.isConfig = False
1788 1790
1789 1791 self.pts2read_SelfSpectra = 0
1790 1792
1791 1793 self.pts2read_CrossSpectra = 0
1792 1794
1793 1795 self.pts2read_DCchannels = 0
1794 1796
1795 1797 self.datablock = None
1796 1798
1797 1799 self.utc = None
1798 1800
1799 1801 self.ext = ".pdata"
1800 1802
1801 1803 self.optchar = "P"
1802 1804
1803 self.basicHeaderObj = BasicHeader()
1805 self.basicHeaderObj = BasicHeader(LOCALTIME)
1804 1806
1805 1807 self.systemHeaderObj = SystemHeader()
1806 1808
1807 1809 self.radarControllerHeaderObj = RadarControllerHeader()
1808 1810
1809 1811 self.processingHeaderObj = ProcessingHeader()
1810 1812
1811 1813 self.online = 0
1812 1814
1813 1815 self.fp = None
1814 1816
1815 1817 self.idFile = None
1816 1818
1817 1819 self.dtype = None
1818 1820
1819 1821 self.fileSizeByHeader = None
1820 1822
1821 1823 self.filenameList = []
1822 1824
1823 1825 self.filename = None
1824 1826
1825 1827 self.fileSize = None
1826 1828
1827 1829 self.firstHeaderSize = 0
1828 1830
1829 1831 self.basicHeaderSize = 24
1830 1832
1831 1833 self.pathList = []
1832 1834
1833 1835 self.lastUTTime = 0
1834 1836
1835 1837 self.maxTimeStep = 30
1836 1838
1837 1839 self.flagNoMoreFiles = 0
1838 1840
1839 1841 self.set = 0
1840 1842
1841 1843 self.path = None
1842 1844
1843 1845 self.delay = 3 #seconds
1844 1846
1845 1847 self.nTries = 3 #quantity tries
1846 1848
1847 1849 self.nFiles = 3 #number of files for searching
1848 1850
1849 1851 self.nReadBlocks = 0
1850 1852
1851 1853 self.flagIsNewFile = 1
1852 1854
1853 1855 self.ippSeconds = 0
1854 1856
1855 1857 self.flagTimeBlock = 0
1856 1858
1857 1859 self.flagIsNewBlock = 0
1858 1860
1859 1861 self.nTotalBlocks = 0
1860 1862
1861 1863 self.blocksize = 0
1862 1864
1863 1865 self.dataOut = self.createObjByDefault()
1864 1866
1865 1867
1866 1868 def createObjByDefault(self):
1867 1869
1868 1870 dataObj = Spectra()
1869 1871
1870 1872 return dataObj
1871 1873
1872 1874 def __hasNotDataInBuffer(self):
1873 1875 return 1
1874 1876
1875 1877
1876 1878 def getBlockDimension(self):
1877 1879 """
1878 1880 Obtiene la cantidad de puntos a leer por cada bloque de datos
1879 1881
1880 1882 Affected:
1881 1883 self.nRdChannels
1882 1884 self.nRdPairs
1883 1885 self.pts2read_SelfSpectra
1884 1886 self.pts2read_CrossSpectra
1885 1887 self.pts2read_DCchannels
1886 1888 self.blocksize
1887 1889 self.dataOut.nChannels
1888 1890 self.dataOut.nPairs
1889 1891
1890 1892 Return:
1891 1893 None
1892 1894 """
1893 1895 self.nRdChannels = 0
1894 1896 self.nRdPairs = 0
1895 1897 self.rdPairList = []
1896 1898
1897 1899 for i in range(0, self.processingHeaderObj.totalSpectra*2, 2):
1898 1900 if self.processingHeaderObj.spectraComb[i] == self.processingHeaderObj.spectraComb[i+1]:
1899 1901 self.nRdChannels = self.nRdChannels + 1 #par de canales iguales
1900 1902 else:
1901 1903 self.nRdPairs = self.nRdPairs + 1 #par de canales diferentes
1902 1904 self.rdPairList.append((self.processingHeaderObj.spectraComb[i], self.processingHeaderObj.spectraComb[i+1]))
1903 1905
1904 1906 pts2read = self.processingHeaderObj.nHeights * self.processingHeaderObj.profilesPerBlock
1905 1907
1906 1908 self.pts2read_SelfSpectra = int(self.nRdChannels * pts2read)
1907 1909 self.blocksize = self.pts2read_SelfSpectra
1908 1910
1909 1911 if self.processingHeaderObj.flag_cspc:
1910 1912 self.pts2read_CrossSpectra = int(self.nRdPairs * pts2read)
1911 1913 self.blocksize += self.pts2read_CrossSpectra
1912 1914
1913 1915 if self.processingHeaderObj.flag_dc:
1914 1916 self.pts2read_DCchannels = int(self.systemHeaderObj.nChannels * self.processingHeaderObj.nHeights)
1915 1917 self.blocksize += self.pts2read_DCchannels
1916 1918
1917 1919 # self.blocksize = self.pts2read_SelfSpectra + self.pts2read_CrossSpectra + self.pts2read_DCchannels
1918 1920
1919 1921
1920 1922 def readBlock(self):
1921 1923 """
1922 1924 Lee el bloque de datos desde la posicion actual del puntero del archivo
1923 1925 (self.fp) y actualiza todos los parametros relacionados al bloque de datos
1924 1926 (metadata + data). La data leida es almacenada en el buffer y el contador del buffer
1925 1927 es seteado a 0
1926 1928
1927 1929 Return: None
1928 1930
1929 1931 Variables afectadas:
1930 1932
1931 1933 self.flagIsNewFile
1932 1934 self.flagIsNewBlock
1933 1935 self.nTotalBlocks
1934 1936 self.data_spc
1935 1937 self.data_cspc
1936 1938 self.data_dc
1937 1939
1938 1940 Exceptions:
1939 1941 Si un bloque leido no es un bloque valido
1940 1942 """
1941 1943 blockOk_flag = False
1942 1944 fpointer = self.fp.tell()
1943 1945
1944 1946 spc = numpy.fromfile( self.fp, self.dtype[0], self.pts2read_SelfSpectra )
1945 1947 spc = spc.reshape( (self.nRdChannels, self.processingHeaderObj.nHeights, self.processingHeaderObj.profilesPerBlock) ) #transforma a un arreglo 3D
1946 1948
1947 1949 if self.processingHeaderObj.flag_cspc:
1948 1950 cspc = numpy.fromfile( self.fp, self.dtype, self.pts2read_CrossSpectra )
1949 1951 cspc = cspc.reshape( (self.nRdPairs, self.processingHeaderObj.nHeights, self.processingHeaderObj.profilesPerBlock) ) #transforma a un arreglo 3D
1950 1952
1951 1953 if self.processingHeaderObj.flag_dc:
1952 1954 dc = numpy.fromfile( self.fp, self.dtype, self.pts2read_DCchannels ) #int(self.processingHeaderObj.nHeights*self.systemHeaderObj.nChannels) )
1953 1955 dc = dc.reshape( (self.systemHeaderObj.nChannels, self.processingHeaderObj.nHeights) ) #transforma a un arreglo 2D
1954 1956
1955 1957
1956 1958 if not(self.processingHeaderObj.shif_fft):
1957 1959 #desplaza a la derecha en el eje 2 determinadas posiciones
1958 1960 shift = int(self.processingHeaderObj.profilesPerBlock/2)
1959 1961 spc = numpy.roll( spc, shift , axis=2 )
1960 1962
1961 1963 if self.processingHeaderObj.flag_cspc:
1962 1964 #desplaza a la derecha en el eje 2 determinadas posiciones
1963 1965 cspc = numpy.roll( cspc, shift, axis=2 )
1964 1966
1965 1967
1966 1968 spc = numpy.transpose( spc, (0,2,1) )
1967 1969 self.data_spc = spc
1968 1970
1969 1971 if self.processingHeaderObj.flag_cspc:
1970 1972 cspc = numpy.transpose( cspc, (0,2,1) )
1971 1973 self.data_cspc = cspc['real'] + cspc['imag']*1j
1972 1974 else:
1973 1975 self.data_cspc = None
1974 1976
1975 1977 if self.processingHeaderObj.flag_dc:
1976 1978 self.data_dc = dc['real'] + dc['imag']*1j
1977 1979 else:
1978 1980 self.data_dc = None
1979 1981
1980 1982 self.flagIsNewFile = 0
1981 1983 self.flagIsNewBlock = 1
1982 1984
1983 1985 self.nTotalBlocks += 1
1984 1986 self.nReadBlocks += 1
1985 1987
1986 1988 return 1
1987 1989
1988 1990
1989 1991 def getData(self):
1990 1992 """
1991 1993 Copia el buffer de lectura a la clase "Spectra",
1992 1994 con todos los parametros asociados a este (metadata). cuando no hay datos en el buffer de
1993 1995 lectura es necesario hacer una nueva lectura de los bloques de datos usando "readNextBlock"
1994 1996
1995 1997 Return:
1996 1998 0 : Si no hay mas archivos disponibles
1997 1999 1 : Si hizo una buena copia del buffer
1998 2000
1999 2001 Affected:
2000 2002 self.dataOut
2001 2003
2002 2004 self.flagTimeBlock
2003 2005 self.flagIsNewBlock
2004 2006 """
2005 2007
2006 2008 if self.flagNoMoreFiles:
2007 2009 self.dataOut.flagNoData = True
2008 2010 print 'Process finished'
2009 2011 return 0
2010 2012
2011 2013 self.flagTimeBlock = 0
2012 2014 self.flagIsNewBlock = 0
2013 2015
2014 2016 if self.__hasNotDataInBuffer():
2015 2017
2016 2018 if not( self.readNextBlock() ):
2017 2019 self.dataOut.flagNoData = True
2018 2020 return 0
2019 2021
2020 2022 # self.updateDataHeader()
2021 2023
2022 2024 #data es un numpy array de 3 dmensiones (perfiles, alturas y canales)
2023 2025
2024 2026 if self.data_dc == None:
2025 2027 self.dataOut.flagNoData = True
2026 2028 return 0
2027 2029
2028 2030 self.dataOut.data_spc = self.data_spc
2029 2031
2030 2032 self.dataOut.data_cspc = self.data_cspc
2031 2033
2032 2034 self.dataOut.data_dc = self.data_dc
2033 2035
2034 2036 self.dataOut.flagTimeBlock = self.flagTimeBlock
2035 2037
2036 2038 self.dataOut.flagNoData = False
2037 2039
2038 2040 self.dataOut.dtype = self.dtype
2039 2041
2040 2042 # self.dataOut.nChannels = self.nRdChannels
2041 2043
2042 2044 self.dataOut.nPairs = self.nRdPairs
2043 2045
2044 2046 self.dataOut.pairsList = self.rdPairList
2045 2047
2046 2048 # self.dataOut.nHeights = self.processingHeaderObj.nHeights
2047 2049
2048 2050 self.dataOut.nProfiles = self.processingHeaderObj.profilesPerBlock
2049 2051
2050 2052 self.dataOut.nFFTPoints = self.processingHeaderObj.profilesPerBlock
2051 2053
2052 2054 self.dataOut.nCohInt = self.processingHeaderObj.nCohInt
2053 2055
2054 2056 self.dataOut.nIncohInt = self.processingHeaderObj.nIncohInt
2055 2057
2056 2058 xf = self.processingHeaderObj.firstHeight + self.processingHeaderObj.nHeights*self.processingHeaderObj.deltaHeight
2057 2059
2058 2060 self.dataOut.heightList = numpy.arange(self.processingHeaderObj.firstHeight, xf, self.processingHeaderObj.deltaHeight)
2059 2061
2060 2062 self.dataOut.channelList = range(self.systemHeaderObj.nChannels)
2061 2063
2062 2064 # self.dataOut.channelIndexList = range(self.systemHeaderObj.nChannels)
2063 2065
2064 2066 self.dataOut.utctime = self.basicHeaderObj.utc + self.basicHeaderObj.miliSecond/1000.#+ self.profileIndex * self.ippSeconds
2065 2067
2066 2068 self.dataOut.ippSeconds = self.ippSeconds
2067 2069
2068 2070 self.dataOut.timeInterval = self.ippSeconds * self.processingHeaderObj.nCohInt * self.processingHeaderObj.nIncohInt * self.dataOut.nFFTPoints
2069 2071
2070 2072 # self.profileIndex += 1
2071 2073
2072 2074 self.dataOut.systemHeaderObj = self.systemHeaderObj.copy()
2073 2075
2074 2076 self.dataOut.radarControllerHeaderObj = self.radarControllerHeaderObj.copy()
2075 2077
2076 2078 self.dataOut.flagShiftFFT = self.processingHeaderObj.shif_fft
2077 2079
2078 2080 self.dataOut.flagDecodeData = True #asumo q la data no esta decodificada
2079 2081
2080 2082 self.dataOut.flagDeflipData = True #asumo q la data no esta sin flip
2081 2083
2082 2084
2083 2085 return self.dataOut.data_spc
2084 2086
2085 2087
2086 2088 class SpectraWriter(JRODataWriter):
2087 2089
2088 2090 """
2089 2091 Esta clase permite escribir datos de espectros a archivos procesados (.pdata). La escritura
2090 2092 de los datos siempre se realiza por bloques.
2091 2093 """
2092 2094
2093 2095 ext = ".pdata"
2094 2096
2095 2097 optchar = "P"
2096 2098
2097 2099 shape_spc_Buffer = None
2098 2100
2099 2101 shape_cspc_Buffer = None
2100 2102
2101 2103 shape_dc_Buffer = None
2102 2104
2103 2105 data_spc = None
2104 2106
2105 2107 data_cspc = None
2106 2108
2107 2109 data_dc = None
2108 2110
2109 2111 # dataOut = None
2110 2112
2111 2113 def __init__(self):
2112 2114 """
2113 2115 Inicializador de la clase SpectraWriter para la escritura de datos de espectros.
2114 2116
2115 2117 Affected:
2116 2118 self.dataOut
2117 2119 self.basicHeaderObj
2118 2120 self.systemHeaderObj
2119 2121 self.radarControllerHeaderObj
2120 2122 self.processingHeaderObj
2121 2123
2122 2124 Return: None
2123 2125 """
2124 2126
2125 2127 self.isConfig = False
2126 2128
2127 2129 self.nTotalBlocks = 0
2128 2130
2129 2131 self.data_spc = None
2130 2132
2131 2133 self.data_cspc = None
2132 2134
2133 2135 self.data_dc = None
2134 2136
2135 2137 self.fp = None
2136 2138
2137 2139 self.flagIsNewFile = 1
2138 2140
2139 2141 self.nTotalBlocks = 0
2140 2142
2141 2143 self.flagIsNewBlock = 0
2142 2144
2143 2145 self.setFile = None
2144 2146
2145 2147 self.dtype = None
2146 2148
2147 2149 self.path = None
2148 2150
2149 2151 self.noMoreFiles = 0
2150 2152
2151 2153 self.filename = None
2152 2154
2153 self.basicHeaderObj = BasicHeader()
2155 self.basicHeaderObj = BasicHeader(LOCALTIME)
2154 2156
2155 2157 self.systemHeaderObj = SystemHeader()
2156 2158
2157 2159 self.radarControllerHeaderObj = RadarControllerHeader()
2158 2160
2159 2161 self.processingHeaderObj = ProcessingHeader()
2160 2162
2161 2163
2162 2164 def hasAllDataInBuffer(self):
2163 2165 return 1
2164 2166
2165 2167
2166 2168 def setBlockDimension(self):
2167 2169 """
2168 2170 Obtiene las formas dimensionales del los subbloques de datos que componen un bloque
2169 2171
2170 2172 Affected:
2171 2173 self.shape_spc_Buffer
2172 2174 self.shape_cspc_Buffer
2173 2175 self.shape_dc_Buffer
2174 2176
2175 2177 Return: None
2176 2178 """
2177 2179 self.shape_spc_Buffer = (self.dataOut.nChannels,
2178 2180 self.processingHeaderObj.nHeights,
2179 2181 self.processingHeaderObj.profilesPerBlock)
2180 2182
2181 2183 self.shape_cspc_Buffer = (self.dataOut.nPairs,
2182 2184 self.processingHeaderObj.nHeights,
2183 2185 self.processingHeaderObj.profilesPerBlock)
2184 2186
2185 2187 self.shape_dc_Buffer = (self.dataOut.nChannels,
2186 2188 self.processingHeaderObj.nHeights)
2187 2189
2188 2190
2189 2191 def writeBlock(self):
2190 2192 """
2191 2193 Escribe el buffer en el file designado
2192 2194
2193 2195 Affected:
2194 2196 self.data_spc
2195 2197 self.data_cspc
2196 2198 self.data_dc
2197 2199 self.flagIsNewFile
2198 2200 self.flagIsNewBlock
2199 2201 self.nTotalBlocks
2200 2202 self.nWriteBlocks
2201 2203
2202 2204 Return: None
2203 2205 """
2204 2206
2205 2207 spc = numpy.transpose( self.data_spc, (0,2,1) )
2206 2208 if not( self.processingHeaderObj.shif_fft ):
2207 2209 spc = numpy.roll( spc, self.processingHeaderObj.profilesPerBlock/2, axis=2 ) #desplaza a la derecha en el eje 2 determinadas posiciones
2208 2210 data = spc.reshape((-1))
2209 2211 data.tofile(self.fp)
2210 2212
2211 2213 if self.data_cspc != None:
2212 2214 data = numpy.zeros( self.shape_cspc_Buffer, self.dtype )
2213 2215 cspc = numpy.transpose( self.data_cspc, (0,2,1) )
2214 2216 if not( self.processingHeaderObj.shif_fft ):
2215 2217 cspc = numpy.roll( cspc, self.processingHeaderObj.profilesPerBlock/2, axis=2 ) #desplaza a la derecha en el eje 2 determinadas posiciones
2216 2218 data['real'] = cspc.real
2217 2219 data['imag'] = cspc.imag
2218 2220 data = data.reshape((-1))
2219 2221 data.tofile(self.fp)
2220 2222
2221 2223 if self.data_dc != None:
2222 2224 data = numpy.zeros( self.shape_dc_Buffer, self.dtype )
2223 2225 dc = self.data_dc
2224 2226 data['real'] = dc.real
2225 2227 data['imag'] = dc.imag
2226 2228 data = data.reshape((-1))
2227 2229 data.tofile(self.fp)
2228 2230
2229 2231 self.data_spc.fill(0)
2230 2232 self.data_dc.fill(0)
2231 2233 if self.data_cspc != None:
2232 2234 self.data_cspc.fill(0)
2233 2235
2234 2236 self.flagIsNewFile = 0
2235 2237 self.flagIsNewBlock = 1
2236 2238 self.nTotalBlocks += 1
2237 2239 self.nWriteBlocks += 1
2238 2240 self.blockIndex += 1
2239 2241
2240 2242
2241 2243 def putData(self):
2242 2244 """
2243 2245 Setea un bloque de datos y luego los escribe en un file
2244 2246
2245 2247 Affected:
2246 2248 self.data_spc
2247 2249 self.data_cspc
2248 2250 self.data_dc
2249 2251
2250 2252 Return:
2251 2253 0 : Si no hay data o no hay mas files que puedan escribirse
2252 2254 1 : Si se escribio la data de un bloque en un file
2253 2255 """
2254 2256
2255 2257 if self.dataOut.flagNoData:
2256 2258 return 0
2257 2259
2258 2260 self.flagIsNewBlock = 0
2259 2261
2260 2262 if self.dataOut.flagTimeBlock:
2261 2263 self.data_spc.fill(0)
2262 2264 self.data_cspc.fill(0)
2263 2265 self.data_dc.fill(0)
2264 2266 self.setNextFile()
2265 2267
2266 2268 if self.flagIsNewFile == 0:
2267 2269 self.getBasicHeader()
2268 2270
2269 2271 self.data_spc = self.dataOut.data_spc
2270 2272 self.data_cspc = self.dataOut.data_cspc
2271 2273 self.data_dc = self.dataOut.data_dc
2272 2274
2273 2275 # #self.processingHeaderObj.dataBlocksPerFile)
2274 2276 if self.hasAllDataInBuffer():
2275 2277 # self.getDataHeader()
2276 2278 self.writeNextBlock()
2277 2279
2278 2280 return 1
2279 2281
2280 2282
2281 2283 def __getProcessFlags(self):
2282 2284
2283 2285 processFlags = 0
2284 2286
2285 2287 dtype0 = numpy.dtype([('real','<i1'),('imag','<i1')])
2286 2288 dtype1 = numpy.dtype([('real','<i2'),('imag','<i2')])
2287 2289 dtype2 = numpy.dtype([('real','<i4'),('imag','<i4')])
2288 2290 dtype3 = numpy.dtype([('real','<i8'),('imag','<i8')])
2289 2291 dtype4 = numpy.dtype([('real','<f4'),('imag','<f4')])
2290 2292 dtype5 = numpy.dtype([('real','<f8'),('imag','<f8')])
2291 2293
2292 2294 dtypeList = [dtype0, dtype1, dtype2, dtype3, dtype4, dtype5]
2293 2295
2294 2296
2295 2297
2296 2298 datatypeValueList = [PROCFLAG.DATATYPE_CHAR,
2297 2299 PROCFLAG.DATATYPE_SHORT,
2298 2300 PROCFLAG.DATATYPE_LONG,
2299 2301 PROCFLAG.DATATYPE_INT64,
2300 2302 PROCFLAG.DATATYPE_FLOAT,
2301 2303 PROCFLAG.DATATYPE_DOUBLE]
2302 2304
2303 2305
2304 2306 for index in range(len(dtypeList)):
2305 2307 if self.dataOut.dtype == dtypeList[index]:
2306 2308 dtypeValue = datatypeValueList[index]
2307 2309 break
2308 2310
2309 2311 processFlags += dtypeValue
2310 2312
2311 2313 if self.dataOut.flagDecodeData:
2312 2314 processFlags += PROCFLAG.DECODE_DATA
2313 2315
2314 2316 if self.dataOut.flagDeflipData:
2315 2317 processFlags += PROCFLAG.DEFLIP_DATA
2316 2318
2317 2319 if self.dataOut.code != None:
2318 2320 processFlags += PROCFLAG.DEFINE_PROCESS_CODE
2319 2321
2320 2322 if self.dataOut.nIncohInt > 1:
2321 2323 processFlags += PROCFLAG.INCOHERENT_INTEGRATION
2322 2324
2323 2325 if self.dataOut.data_dc != None:
2324 2326 processFlags += PROCFLAG.SAVE_CHANNELS_DC
2325 2327
2326 2328 return processFlags
2327 2329
2328 2330
2329 2331 def __getBlockSize(self):
2330 2332 '''
2331 2333 Este metodos determina el cantidad de bytes para un bloque de datos de tipo Spectra
2332 2334 '''
2333 2335
2334 2336 dtype0 = numpy.dtype([('real','<i1'),('imag','<i1')])
2335 2337 dtype1 = numpy.dtype([('real','<i2'),('imag','<i2')])
2336 2338 dtype2 = numpy.dtype([('real','<i4'),('imag','<i4')])
2337 2339 dtype3 = numpy.dtype([('real','<i8'),('imag','<i8')])
2338 2340 dtype4 = numpy.dtype([('real','<f4'),('imag','<f4')])
2339 2341 dtype5 = numpy.dtype([('real','<f8'),('imag','<f8')])
2340 2342
2341 2343 dtypeList = [dtype0, dtype1, dtype2, dtype3, dtype4, dtype5]
2342 2344 datatypeValueList = [1,2,4,8,4,8]
2343 2345 for index in range(len(dtypeList)):
2344 2346 if self.dataOut.dtype == dtypeList[index]:
2345 2347 datatypeValue = datatypeValueList[index]
2346 2348 break
2347 2349
2348 2350
2349 2351 pts2write = self.dataOut.nHeights * self.dataOut.nFFTPoints
2350 2352
2351 2353 pts2write_SelfSpectra = int(self.dataOut.nChannels * pts2write)
2352 2354 blocksize = (pts2write_SelfSpectra*datatypeValue)
2353 2355
2354 2356 if self.dataOut.data_cspc != None:
2355 2357 pts2write_CrossSpectra = int(self.dataOut.nPairs * pts2write)
2356 2358 blocksize += (pts2write_CrossSpectra*datatypeValue*2)
2357 2359
2358 2360 if self.dataOut.data_dc != None:
2359 2361 pts2write_DCchannels = int(self.dataOut.nChannels * self.dataOut.nHeights)
2360 2362 blocksize += (pts2write_DCchannels*datatypeValue*2)
2361 2363
2362 2364 blocksize = blocksize #* datatypeValue * 2 #CORREGIR ESTO
2363 2365
2364 2366 return blocksize
2365 2367
2366 2368 def getDataHeader(self):
2367 2369
2368 2370 """
2369 2371 Obtiene una copia del First Header
2370 2372
2371 2373 Affected:
2372 2374 self.systemHeaderObj
2373 2375 self.radarControllerHeaderObj
2374 2376 self.dtype
2375 2377
2376 2378 Return:
2377 2379 None
2378 2380 """
2379 2381
2380 2382 self.systemHeaderObj = self.dataOut.systemHeaderObj.copy()
2381 2383 self.systemHeaderObj.nChannels = self.dataOut.nChannels
2382 2384 self.radarControllerHeaderObj = self.dataOut.radarControllerHeaderObj.copy()
2383 2385
2384 2386 self.getBasicHeader()
2385 2387
2386 2388 processingHeaderSize = 40 # bytes
2387 2389 self.processingHeaderObj.dtype = 0 # Voltage
2388 2390 self.processingHeaderObj.blockSize = self.__getBlockSize()
2389 2391 self.processingHeaderObj.profilesPerBlock = self.dataOut.nFFTPoints
2390 2392 self.processingHeaderObj.dataBlocksPerFile = self.blocksPerFile
2391 2393 self.processingHeaderObj.nWindows = 1 #podria ser 1 o self.dataOut.processingHeaderObj.nWindows
2392 2394 self.processingHeaderObj.processFlags = self.__getProcessFlags()
2393 2395 self.processingHeaderObj.nCohInt = self.dataOut.nCohInt# Se requiere para determinar el valor de timeInterval
2394 2396 self.processingHeaderObj.nIncohInt = self.dataOut.nIncohInt
2395 2397 self.processingHeaderObj.totalSpectra = self.dataOut.nPairs + self.dataOut.nChannels
2396 2398
2397 2399 if self.processingHeaderObj.totalSpectra > 0:
2398 2400 channelList = []
2399 2401 for channel in range(self.dataOut.nChannels):
2400 2402 channelList.append(channel)
2401 2403 channelList.append(channel)
2402 2404
2403 2405 pairsList = []
2404 2406 for pair in self.dataOut.pairsList:
2405 2407 pairsList.append(pair[0])
2406 2408 pairsList.append(pair[1])
2407 2409 spectraComb = channelList + pairsList
2408 2410 spectraComb = numpy.array(spectraComb,dtype="u1")
2409 2411 self.processingHeaderObj.spectraComb = spectraComb
2410 2412 sizeOfSpcComb = len(spectraComb)
2411 2413 processingHeaderSize += sizeOfSpcComb
2412 2414
2413 2415 if self.dataOut.code != None:
2414 2416 self.processingHeaderObj.code = self.dataOut.code
2415 2417 self.processingHeaderObj.nCode = self.dataOut.nCode
2416 2418 self.processingHeaderObj.nBaud = self.dataOut.nBaud
2417 2419 nCodeSize = 4 # bytes
2418 2420 nBaudSize = 4 # bytes
2419 2421 codeSize = 4 # bytes
2420 2422 sizeOfCode = int(nCodeSize + nBaudSize + codeSize * self.dataOut.nCode * self.dataOut.nBaud)
2421 2423 processingHeaderSize += sizeOfCode
2422 2424
2423 2425 if self.processingHeaderObj.nWindows != 0:
2424 2426 self.processingHeaderObj.firstHeight = self.dataOut.heightList[0]
2425 2427 self.processingHeaderObj.deltaHeight = self.dataOut.heightList[1] - self.dataOut.heightList[0]
2426 2428 self.processingHeaderObj.nHeights = self.dataOut.nHeights
2427 2429 self.processingHeaderObj.samplesWin = self.dataOut.nHeights
2428 2430 sizeOfFirstHeight = 4
2429 2431 sizeOfdeltaHeight = 4
2430 2432 sizeOfnHeights = 4
2431 2433 sizeOfWindows = (sizeOfFirstHeight + sizeOfdeltaHeight + sizeOfnHeights)*self.processingHeaderObj.nWindows
2432 2434 processingHeaderSize += sizeOfWindows
2433 2435
2434 2436 self.processingHeaderObj.size = processingHeaderSize
2435 2437
2436 2438 class SpectraHeisWriter():
2437 2439
2438 2440 i=0
2439 2441
2440 2442 def __init__(self, dataOut):
2441 2443
2442 2444 self.wrObj = FITS()
2443 2445 self.dataOut = dataOut
2444 2446
2445 2447 def isNumber(str):
2446 2448 """
2447 2449 Chequea si el conjunto de caracteres que componen un string puede ser convertidos a un numero.
2448 2450
2449 2451 Excepciones:
2450 2452 Si un determinado string no puede ser convertido a numero
2451 2453 Input:
2452 2454 str, string al cual se le analiza para determinar si convertible a un numero o no
2453 2455
2454 2456 Return:
2455 2457 True : si el string es uno numerico
2456 2458 False : no es un string numerico
2457 2459 """
2458 2460 try:
2459 2461 float( str )
2460 2462 return True
2461 2463 except:
2462 2464 return False
2463 2465
2464 2466 def setup(self, wrpath,):
2465 2467
2466 2468 if not(os.path.exists(wrpath)):
2467 2469 os.mkdir(wrpath)
2468 2470
2469 2471 self.wrpath = wrpath
2470 2472 self.setFile = 0
2471 2473
2472 2474 def putData(self):
2473 2475 # self.wrObj.writeHeader(nChannels=self.dataOut.nChannels, nFFTPoints=self.dataOut.nFFTPoints)
2474 2476 #name = self.dataOut.utctime
2475 2477 name= time.localtime( self.dataOut.utctime)
2476 2478 ext=".fits"
2477 2479 #folder='D%4.4d%3.3d'%(name.tm_year,name.tm_yday)
2478 2480 subfolder = 'D%4.4d%3.3d' % (name.tm_year,name.tm_yday)
2479 2481
2480 2482 fullpath = os.path.join( self.wrpath, subfolder )
2481 2483 if not( os.path.exists(fullpath) ):
2482 2484 os.mkdir(fullpath)
2483 2485 self.setFile += 1
2484 2486 file = 'D%4.4d%3.3d%3.3d%s' % (name.tm_year,name.tm_yday,self.setFile,ext)
2485 2487
2486 2488 filename = os.path.join(self.wrpath,subfolder, file)
2487 2489
2488 2490 # print self.dataOut.ippSeconds
2489 2491 freq=numpy.arange(-1*self.dataOut.nHeights/2.,self.dataOut.nHeights/2.)/(2*self.dataOut.ippSeconds)
2490 2492
2491 2493 col1=self.wrObj.setColF(name="freq", format=str(self.dataOut.nFFTPoints)+'E', array=freq)
2492 2494 col2=self.wrObj.writeData(name="P_Ch1",format=str(self.dataOut.nFFTPoints)+'E',data=10*numpy.log10(self.dataOut.data_spc[0,:]))
2493 2495 col3=self.wrObj.writeData(name="P_Ch2",format=str(self.dataOut.nFFTPoints)+'E',data=10*numpy.log10(self.dataOut.data_spc[1,:]))
2494 2496 col4=self.wrObj.writeData(name="P_Ch3",format=str(self.dataOut.nFFTPoints)+'E',data=10*numpy.log10(self.dataOut.data_spc[2,:]))
2495 2497 col5=self.wrObj.writeData(name="P_Ch4",format=str(self.dataOut.nFFTPoints)+'E',data=10*numpy.log10(self.dataOut.data_spc[3,:]))
2496 2498 col6=self.wrObj.writeData(name="P_Ch5",format=str(self.dataOut.nFFTPoints)+'E',data=10*numpy.log10(self.dataOut.data_spc[4,:]))
2497 2499 col7=self.wrObj.writeData(name="P_Ch6",format=str(self.dataOut.nFFTPoints)+'E',data=10*numpy.log10(self.dataOut.data_spc[5,:]))
2498 2500 col8=self.wrObj.writeData(name="P_Ch7",format=str(self.dataOut.nFFTPoints)+'E',data=10*numpy.log10(self.dataOut.data_spc[6,:]))
2499 2501 col9=self.wrObj.writeData(name="P_Ch8",format=str(self.dataOut.nFFTPoints)+'E',data=10*numpy.log10(self.dataOut.data_spc[7,:]))
2500 2502 #n=numpy.arange((100))
2501 2503 n=self.dataOut.data_spc[6,:]
2502 2504 a=self.wrObj.cFImage(n)
2503 2505 b=self.wrObj.Ctable(col1,col2,col3,col4,col5,col6,col7,col8,col9)
2504 2506 self.wrObj.CFile(a,b)
2505 2507 self.wrObj.wFile(filename)
2506 2508 return 1
2507 2509
2508 2510 class FITS:
2509 2511
2510 2512 name=None
2511 2513 format=None
2512 2514 array =None
2513 2515 data =None
2514 2516 thdulist=None
2515 2517
2516 2518 def __init__(self):
2517 2519
2518 2520 pass
2519 2521
2520 2522 def setColF(self,name,format,array):
2521 2523 self.name=name
2522 2524 self.format=format
2523 2525 self.array=array
2524 2526 a1=numpy.array([self.array],dtype=numpy.float32)
2525 2527 self.col1 = pyfits.Column(name=self.name, format=self.format, array=a1)
2526 2528 return self.col1
2527 2529
2528 2530 # def setColP(self,name,format,data):
2529 2531 # self.name=name
2530 2532 # self.format=format
2531 2533 # self.data=data
2532 2534 # a2=numpy.array([self.data],dtype=numpy.float32)
2533 2535 # self.col2 = pyfits.Column(name=self.name, format=self.format, array=a2)
2534 2536 # return self.col2
2535 2537
2536 2538 def writeHeader(self,):
2537 2539 pass
2538 2540
2539 2541 def writeData(self,name,format,data):
2540 2542 self.name=name
2541 2543 self.format=format
2542 2544 self.data=data
2543 2545 a2=numpy.array([self.data],dtype=numpy.float32)
2544 2546 self.col2 = pyfits.Column(name=self.name, format=self.format, array=a2)
2545 2547 return self.col2
2546 2548
2547 2549 def cFImage(self,n):
2548 2550 self.hdu= pyfits.PrimaryHDU(n)
2549 2551 return self.hdu
2550 2552
2551 2553 def Ctable(self,col1,col2,col3,col4,col5,col6,col7,col8,col9):
2552 2554 self.cols=pyfits.ColDefs( [col1,col2,col3,col4,col5,col6,col7,col8,col9])
2553 2555 self.tbhdu = pyfits.new_table(self.cols)
2554 2556 return self.tbhdu
2555 2557
2556 2558 def CFile(self,hdu,tbhdu):
2557 2559 self.thdulist=pyfits.HDUList([hdu,tbhdu])
2558 2560
2559 2561 def wFile(self,filename):
2560 2562 self.thdulist.writeto(filename) No newline at end of file
@@ -1,519 +1,526
1 1 '''
2 2
3 3 $Author: murco $
4 4 $Id: JROHeaderIO.py 151 2012-10-31 19:00:51Z murco $
5 5 '''
6 6 import sys
7 7 import numpy
8 8 import copy
9 9 import datetime
10 10
11 11 class Header:
12 12
13 13 def __init__(self):
14 14 raise
15 15
16 16 def copy(self):
17 17 return copy.deepcopy(self)
18 18
19 19 def read():
20 20 pass
21 21
22 22 def write():
23 23 pass
24 24
25 25 def printInfo(self):
26 26
27 27 for key in self.__dict__.keys():
28 28 print "%s = %s" %(key, self.__dict__[key])
29 29
30 30 class BasicHeader(Header):
31 31
32 32 size = None
33 33 version = None
34 34 dataBlock = None
35 35 utc = None
36 36 miliSecond = None
37 37 timeZone = None
38 38 dstFlag = None
39 39 errorCount = None
40 40 struct = None
41 41 datatime = None
42
43 __LOCALTIME = None
42 44
43 def __init__(self):
45 def __init__(self, localtime=0):
44 46
45 47 self.size = 0
46 48 self.version = 0
47 49 self.dataBlock = 0
48 50 self.utc = 0
49 51 self.miliSecond = 0
50 52 self.timeZone = 0
51 53 self.dstFlag = 0
52 54 self.errorCount = 0
53 55 self.struct = numpy.dtype([
54 56 ('nSize','<u4'),
55 57 ('nVersion','<u2'),
56 58 ('nDataBlockId','<u4'),
57 59 ('nUtime','<u4'),
58 60 ('nMilsec','<u2'),
59 61 ('nTimezone','<i2'),
60 62 ('nDstflag','<i2'),
61 63 ('nErrorCount','<u4')
62 64 ])
63 65
66 self.__LOCALTIME = localtime
64 67
65 68 def read(self, fp):
66 69 try:
67 70 header = numpy.fromfile(fp, self.struct,1)
68 71 self.size = int(header['nSize'][0])
69 72 self.version = int(header['nVersion'][0])
70 73 self.dataBlock = int(header['nDataBlockId'][0])
71 74 self.utc = int(header['nUtime'][0])
72 75 self.miliSecond = int(header['nMilsec'][0])
73 76 self.timeZone = int(header['nTimezone'][0])
74 77 self.dstFlag = int(header['nDstflag'][0])
75 78 self.errorCount = int(header['nErrorCount'][0])
76 79
80 self.utc += self.__LOCALTIME
81
77 82 self.datatime = datetime.datetime.utcfromtimestamp(self.utc)
83
78 84 except Exception, e:
79 print "BasicHeader: " + e
85 print "BasicHeader: "
86 print e
80 87 return 0
81 88
82 89 return 1
83 90
84 91 def write(self, fp):
85 92 headerTuple = (self.size,self.version,self.dataBlock,self.utc,self.miliSecond,self.timeZone,self.dstFlag,self.errorCount)
86 93 header = numpy.array(headerTuple,self.struct)
87 94 header.tofile(fp)
88 95
89 96 return 1
90 97
91 98 class SystemHeader(Header):
92 99
93 100 size = None
94 101 nSamples = None
95 102 nProfiles = None
96 103 nChannels = None
97 104 adcResolution = None
98 105 pciDioBusWidth = None
99 106 struct = None
100 107
101 108 def __init__(self):
102 109 self.size = 0
103 110 self.nSamples = 0
104 111 self.nProfiles = 0
105 112 self.nChannels = 0
106 113 self.adcResolution = 0
107 114 self.pciDioBusWidth = 0
108 115 self.struct = numpy.dtype([
109 116 ('nSize','<u4'),
110 117 ('nNumSamples','<u4'),
111 118 ('nNumProfiles','<u4'),
112 119 ('nNumChannels','<u4'),
113 120 ('nADCResolution','<u4'),
114 121 ('nPCDIOBusWidth','<u4'),
115 122 ])
116 123
117 124
118 125 def read(self, fp):
119 126 try:
120 127 header = numpy.fromfile(fp,self.struct,1)
121 128 self.size = header['nSize'][0]
122 129 self.nSamples = header['nNumSamples'][0]
123 130 self.nProfiles = header['nNumProfiles'][0]
124 131 self.nChannels = header['nNumChannels'][0]
125 132 self.adcResolution = header['nADCResolution'][0]
126 133 self.pciDioBusWidth = header['nPCDIOBusWidth'][0]
127 134
128 135 except Exception, e:
129 136 print "SystemHeader: " + e
130 137 return 0
131 138
132 139 return 1
133 140
134 141 def write(self, fp):
135 142 headerTuple = (self.size,self.nSamples,self.nProfiles,self.nChannels,self.adcResolution,self.pciDioBusWidth)
136 143 header = numpy.array(headerTuple,self.struct)
137 144 header.tofile(fp)
138 145
139 146 return 1
140 147
141 148 class RadarControllerHeader(Header):
142 149
143 150 size = None
144 151 expType = None
145 152 nTx = None
146 153 ipp = None
147 154 txA = None
148 155 txB = None
149 156 nWindows = None
150 157 numTaus = None
151 158 codeType = None
152 159 line6Function = None
153 160 line5Function = None
154 161 fClock = None
155 162 prePulseBefore = None
156 163 prePulserAfter = None
157 164 rangeIpp = None
158 165 rangeTxA = None
159 166 rangeTxB = None
160 167 struct = None
161 168
162 169 def __init__(self):
163 170 self.size = 0
164 171 self.expType = 0
165 172 self.nTx = 0
166 173 self.ipp = 0
167 174 self.txA = 0
168 175 self.txB = 0
169 176 self.nWindows = 0
170 177 self.numTaus = 0
171 178 self.codeType = 0
172 179 self.line6Function = 0
173 180 self.line5Function = 0
174 181 self.fClock = 0
175 182 self.prePulseBefore = 0
176 183 self.prePulserAfter = 0
177 184 self.rangeIpp = 0
178 185 self.rangeTxA = 0
179 186 self.rangeTxB = 0
180 187 self.struct = numpy.dtype([
181 188 ('nSize','<u4'),
182 189 ('nExpType','<u4'),
183 190 ('nNTx','<u4'),
184 191 ('fIpp','<f4'),
185 192 ('fTxA','<f4'),
186 193 ('fTxB','<f4'),
187 194 ('nNumWindows','<u4'),
188 195 ('nNumTaus','<u4'),
189 196 ('nCodeType','<u4'),
190 197 ('nLine6Function','<u4'),
191 198 ('nLine5Function','<u4'),
192 199 ('fClock','<f4'),
193 200 ('nPrePulseBefore','<u4'),
194 201 ('nPrePulseAfter','<u4'),
195 202 ('sRangeIPP','<a20'),
196 203 ('sRangeTxA','<a20'),
197 204 ('sRangeTxB','<a20'),
198 205 ])
199 206
200 207 self.samplingWindowStruct = numpy.dtype([('h0','<f4'),('dh','<f4'),('nsa','<u4')])
201 208
202 209 self.samplingWindow = None
203 210 self.nHeights = None
204 211 self.firstHeight = None
205 212 self.deltaHeight = None
206 213 self.samplesWin = None
207 214
208 215 self.nCode = None
209 216 self.nBaud = None
210 217 self.code = None
211 218 self.flip1 = None
212 219 self.flip2 = None
213 220
214 221 self.dynamic = numpy.array([],numpy.dtype('byte'))
215 222
216 223
217 224 def read(self, fp):
218 225 try:
219 226 startFp = fp.tell()
220 227 header = numpy.fromfile(fp,self.struct,1)
221 228 self.size = int(header['nSize'][0])
222 229 self.expType = int(header['nExpType'][0])
223 230 self.nTx = int(header['nNTx'][0])
224 231 self.ipp = float(header['fIpp'][0])
225 232 self.txA = float(header['fTxA'][0])
226 233 self.txB = float(header['fTxB'][0])
227 234 self.nWindows = int(header['nNumWindows'][0])
228 235 self.numTaus = int(header['nNumTaus'][0])
229 236 self.codeType = int(header['nCodeType'][0])
230 237 self.line6Function = int(header['nLine6Function'][0])
231 238 self.line5Function = int(header['nLine5Function'][0])
232 239 self.fClock = float(header['fClock'][0])
233 240 self.prePulseBefore = int(header['nPrePulseBefore'][0])
234 241 self.prePulserAfter = int(header['nPrePulseAfter'][0])
235 242 self.rangeIpp = header['sRangeIPP'][0]
236 243 self.rangeTxA = header['sRangeTxA'][0]
237 244 self.rangeTxB = header['sRangeTxB'][0]
238 245 # jump Dynamic Radar Controller Header
239 246 jumpFp = self.size - 116
240 247 self.dynamic = numpy.fromfile(fp,numpy.dtype('byte'),jumpFp)
241 248 #pointer backward to dynamic header and read
242 249 backFp = fp.tell() - jumpFp
243 250 fp.seek(backFp)
244 251
245 252 self.samplingWindow = numpy.fromfile(fp,self.samplingWindowStruct,self.nWindows)
246 253 self.nHeights = int(numpy.sum(self.samplingWindow['nsa']))
247 254 self.firstHeight = self.samplingWindow['h0']
248 255 self.deltaHeight = self.samplingWindow['dh']
249 256 self.samplesWin = self.samplingWindow['nsa']
250 257
251 258 self.Taus = numpy.fromfile(fp,'<f4',self.numTaus)
252 259
253 260 if self.codeType != 0:
254 261 self.nCode = int(numpy.fromfile(fp,'<u4',1))
255 262 self.nBaud = int(numpy.fromfile(fp,'<u4',1))
256 263 self.code = numpy.empty([self.nCode,self.nBaud],dtype='u1')
257 264 tempList = []
258 265 for ic in range(self.nCode):
259 266 temp = numpy.fromfile(fp,'u1',4*int(numpy.ceil(self.nBaud/32.)))
260 267 tempList.append(temp)
261 268 self.code[ic] = numpy.unpackbits(temp[::-1])[-1*self.nBaud:]
262 269 self.code = 2.0*self.code - 1.0
263 270
264 271 if self.line5Function == RCfunction.FLIP:
265 272 self.flip1 = numpy.fromfile(fp,'<u4',1)
266 273
267 274 if self.line6Function == RCfunction.FLIP:
268 275 self.flip2 = numpy.fromfile(fp,'<u4',1)
269 276
270 277 endFp = self.size + startFp
271 278 jumpFp = endFp - fp.tell()
272 279 if jumpFp > 0:
273 280 fp.seek(jumpFp)
274 281
275 282 except Exception, e:
276 283 print "RadarControllerHeader: " + e
277 284 return 0
278 285
279 286 return 1
280 287
281 288 def write(self, fp):
282 289 headerTuple = (self.size,
283 290 self.expType,
284 291 self.nTx,
285 292 self.ipp,
286 293 self.txA,
287 294 self.txB,
288 295 self.nWindows,
289 296 self.numTaus,
290 297 self.codeType,
291 298 self.line6Function,
292 299 self.line5Function,
293 300 self.fClock,
294 301 self.prePulseBefore,
295 302 self.prePulserAfter,
296 303 self.rangeIpp,
297 304 self.rangeTxA,
298 305 self.rangeTxB)
299 306
300 307 header = numpy.array(headerTuple,self.struct)
301 308 header.tofile(fp)
302 309
303 310 dynamic = self.dynamic
304 311 dynamic.tofile(fp)
305 312
306 313 return 1
307 314
308 315
309 316
310 317 class ProcessingHeader(Header):
311 318
312 319 size = None
313 320 dtype = None
314 321 blockSize = None
315 322 profilesPerBlock = None
316 323 dataBlocksPerFile = None
317 324 nWindows = None
318 325 processFlags = None
319 326 nCohInt = None
320 327 nIncohInt = None
321 328 totalSpectra = None
322 329 struct = None
323 330 flag_dc = None
324 331 flag_cspc = None
325 332
326 333 def __init__(self):
327 334 self.size = 0
328 335 self.dtype = 0
329 336 self.blockSize = 0
330 337 self.profilesPerBlock = 0
331 338 self.dataBlocksPerFile = 0
332 339 self.nWindows = 0
333 340 self.processFlags = 0
334 341 self.nCohInt = 0
335 342 self.nIncohInt = 0
336 343 self.totalSpectra = 0
337 344 self.struct = numpy.dtype([
338 345 ('nSize','<u4'),
339 346 ('nDataType','<u4'),
340 347 ('nSizeOfDataBlock','<u4'),
341 348 ('nProfilesperBlock','<u4'),
342 349 ('nDataBlocksperFile','<u4'),
343 350 ('nNumWindows','<u4'),
344 351 ('nProcessFlags','<u4'),
345 352 ('nCoherentIntegrations','<u4'),
346 353 ('nIncoherentIntegrations','<u4'),
347 354 ('nTotalSpectra','<u4')
348 355 ])
349 356 self.samplingWindow = 0
350 357 self.structSamplingWindow = numpy.dtype([('h0','<f4'),('dh','<f4'),('nsa','<u4')])
351 358 self.nHeights = 0
352 359 self.firstHeight = 0
353 360 self.deltaHeight = 0
354 361 self.samplesWin = 0
355 362 self.spectraComb = 0
356 363 self.nCode = None
357 364 self.code = None
358 365 self.nBaud = None
359 366 self.shif_fft = False
360 367 self.flag_dc = False
361 368 self.flag_cspc = False
362 369
363 370 def read(self, fp):
364 371 try:
365 372 header = numpy.fromfile(fp,self.struct,1)
366 373 self.size = int(header['nSize'][0])
367 374 self.dtype = int(header['nDataType'][0])
368 375 self.blockSize = int(header['nSizeOfDataBlock'][0])
369 376 self.profilesPerBlock = int(header['nProfilesperBlock'][0])
370 377 self.dataBlocksPerFile = int(header['nDataBlocksperFile'][0])
371 378 self.nWindows = int(header['nNumWindows'][0])
372 379 self.processFlags = header['nProcessFlags']
373 380 self.nCohInt = int(header['nCoherentIntegrations'][0])
374 381 self.nIncohInt = int(header['nIncoherentIntegrations'][0])
375 382 self.totalSpectra = int(header['nTotalSpectra'][0])
376 383 self.samplingWindow = numpy.fromfile(fp,self.structSamplingWindow,self.nWindows)
377 384 self.nHeights = int(numpy.sum(self.samplingWindow['nsa']))
378 385 self.firstHeight = float(self.samplingWindow['h0'][0])
379 386 self.deltaHeight = float(self.samplingWindow['dh'][0])
380 387 self.samplesWin = self.samplingWindow['nsa']
381 388 self.spectraComb = numpy.fromfile(fp,'u1',2*self.totalSpectra)
382 389
383 390 if ((self.processFlags & PROCFLAG.DEFINE_PROCESS_CODE) == PROCFLAG.DEFINE_PROCESS_CODE):
384 391 self.nCode = int(numpy.fromfile(fp,'<u4',1))
385 392 self.nBaud = int(numpy.fromfile(fp,'<u4',1))
386 393 self.code = numpy.fromfile(fp,'<f4',self.nCode*self.nBaud).reshape(self.nBaud,self.nCode)
387 394
388 395 if ((self.processFlags & PROCFLAG.SHIFT_FFT_DATA) == PROCFLAG.SHIFT_FFT_DATA):
389 396 self.shif_fft = True
390 397 else:
391 398 self.shif_fft = False
392 399
393 400 if ((self.processFlags & PROCFLAG.SAVE_CHANNELS_DC) == PROCFLAG.SAVE_CHANNELS_DC):
394 401 self.flag_dc = True
395 402
396 403 nChannels = 0
397 404 nPairs = 0
398 405 pairList = []
399 406
400 407 for i in range( 0, self.totalSpectra*2, 2 ):
401 408 if self.spectraComb[i] == self.spectraComb[i+1]:
402 409 nChannels = nChannels + 1 #par de canales iguales
403 410 else:
404 411 nPairs = nPairs + 1 #par de canales diferentes
405 412 pairList.append( (self.spectraComb[i], self.spectraComb[i+1]) )
406 413
407 414 self.flag_cspc = False
408 415 if nPairs > 0:
409 416 self.flag_cspc = True
410 417
411 418 except Exception, e:
412 419 print "ProcessingHeader: " + e
413 420 return 0
414 421
415 422 return 1
416 423
417 424 def write(self, fp):
418 425 headerTuple = (self.size,
419 426 self.dtype,
420 427 self.blockSize,
421 428 self.profilesPerBlock,
422 429 self.dataBlocksPerFile,
423 430 self.nWindows,
424 431 self.processFlags,
425 432 self.nCohInt,
426 433 self.nIncohInt,
427 434 self.totalSpectra)
428 435
429 436 header = numpy.array(headerTuple,self.struct)
430 437 header.tofile(fp)
431 438
432 439 if self.nWindows != 0:
433 440 sampleWindowTuple = (self.firstHeight,self.deltaHeight,self.samplesWin)
434 441 samplingWindow = numpy.array(sampleWindowTuple,self.structSamplingWindow)
435 442 samplingWindow.tofile(fp)
436 443
437 444
438 445 if self.totalSpectra != 0:
439 446 spectraComb = numpy.array([],numpy.dtype('u1'))
440 447 spectraComb = self.spectraComb
441 448 spectraComb.tofile(fp)
442 449
443 450
444 451 if self.processFlags & PROCFLAG.DEFINE_PROCESS_CODE == PROCFLAG.DEFINE_PROCESS_CODE:
445 452 nCode = self.nCode #Probar con un dato que almacene codigo, hasta el momento no se hizo la prueba
446 453 nCode.tofile(fp)
447 454
448 455 nBaud = self.nBaud
449 456 nBaud.tofile(fp)
450 457
451 458 code = self.code.reshape(nCode*nBaud)
452 459 code.tofile(fp)
453 460
454 461 return 1
455 462
456 463 class RCfunction:
457 464 NONE=0
458 465 FLIP=1
459 466 CODE=2
460 467 SAMPLING=3
461 468 LIN6DIV256=4
462 469 SYNCHRO=5
463 470
464 471 class nCodeType:
465 472 NONE=0
466 473 USERDEFINE=1
467 474 BARKER2=2
468 475 BARKER3=3
469 476 BARKER4=4
470 477 BARKER5=5
471 478 BARKER7=6
472 479 BARKER11=7
473 480 BARKER13=8
474 481 AC128=9
475 482 COMPLEMENTARYCODE2=10
476 483 COMPLEMENTARYCODE4=11
477 484 COMPLEMENTARYCODE8=12
478 485 COMPLEMENTARYCODE16=13
479 486 COMPLEMENTARYCODE32=14
480 487 COMPLEMENTARYCODE64=15
481 488 COMPLEMENTARYCODE128=16
482 489 CODE_BINARY28=17
483 490
484 491 class PROCFLAG:
485 492 COHERENT_INTEGRATION = numpy.uint32(0x00000001)
486 493 DECODE_DATA = numpy.uint32(0x00000002)
487 494 SPECTRA_CALC = numpy.uint32(0x00000004)
488 495 INCOHERENT_INTEGRATION = numpy.uint32(0x00000008)
489 496 POST_COHERENT_INTEGRATION = numpy.uint32(0x00000010)
490 497 SHIFT_FFT_DATA = numpy.uint32(0x00000020)
491 498
492 499 DATATYPE_CHAR = numpy.uint32(0x00000040)
493 500 DATATYPE_SHORT = numpy.uint32(0x00000080)
494 501 DATATYPE_LONG = numpy.uint32(0x00000100)
495 502 DATATYPE_INT64 = numpy.uint32(0x00000200)
496 503 DATATYPE_FLOAT = numpy.uint32(0x00000400)
497 504 DATATYPE_DOUBLE = numpy.uint32(0x00000800)
498 505
499 506 DATAARRANGE_CONTIGUOUS_CH = numpy.uint32(0x00001000)
500 507 DATAARRANGE_CONTIGUOUS_H = numpy.uint32(0x00002000)
501 508 DATAARRANGE_CONTIGUOUS_P = numpy.uint32(0x00004000)
502 509
503 510 SAVE_CHANNELS_DC = numpy.uint32(0x00008000)
504 511 DEFLIP_DATA = numpy.uint32(0x00010000)
505 512 DEFINE_PROCESS_CODE = numpy.uint32(0x00020000)
506 513
507 514 ACQ_SYS_NATALIA = numpy.uint32(0x00040000)
508 515 ACQ_SYS_ECHOTEK = numpy.uint32(0x00080000)
509 516 ACQ_SYS_ADRXD = numpy.uint32(0x000C0000)
510 517 ACQ_SYS_JULIA = numpy.uint32(0x00100000)
511 518 ACQ_SYS_XXXXXX = numpy.uint32(0x00140000)
512 519
513 520 EXP_NAME_ESP = numpy.uint32(0x00200000)
514 521 CHANNEL_NAMES_ESP = numpy.uint32(0x00400000)
515 522
516 523 OPERATION_MASK = numpy.uint32(0x0000003F)
517 524 DATATYPE_MASK = numpy.uint32(0x00000FC0)
518 525 DATAARRANGE_MASK = numpy.uint32(0x00007000)
519 526 ACQ_SYS_MASK = numpy.uint32(0x001C0000) No newline at end of file
@@ -1,967 +1,976
1 1 import numpy
2 2 import time, datetime
3 3 from graphics.figure import *
4 4
5 5 class CrossSpectraPlot(Figure):
6 6
7 7 __isConfig = None
8 8 __nsubplots = None
9 9
10 WIDTH = None
11 HEIGHT = None
10 12 WIDTHPROF = None
11 13 HEIGHTPROF = None
12 14 PREFIX = 'cspc'
13 15
14 16 def __init__(self):
15 17
16 18 self.__isConfig = False
17 19 self.__nsubplots = 4
18 20
19 self.WIDTH = 300
20 self.HEIGHT = 400
21 self.WIDTH = 250
22 self.HEIGHT = 250
21 23 self.WIDTHPROF = 0
22 24 self.HEIGHTPROF = 0
23 25
24 26 def getSubplots(self):
25 27
26 28 ncol = 4
27 29 nrow = self.nplots
28 30
29 31 return nrow, ncol
30 32
31 33 def setup(self, idfigure, nplots, wintitle, showprofile=True):
32 34
33 35 self.__showprofile = showprofile
34 36 self.nplots = nplots
35 37
36 38 ncolspan = 1
37 39 colspan = 1
38 40
39 41 self.createFigure(idfigure = idfigure,
40 42 wintitle = wintitle,
41 43 widthplot = self.WIDTH + self.WIDTHPROF,
42 44 heightplot = self.HEIGHT + self.HEIGHTPROF)
43 45
44 46 nrow, ncol = self.getSubplots()
45 47
46 48 counter = 0
47 49 for y in range(nrow):
48 50 for x in range(ncol):
49 51 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
50 52
51 53 counter += 1
52 54
53 55 def run(self, dataOut, idfigure, wintitle="", pairsList=None, showprofile='True',
54 56 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
55 57 save=False, figpath='./', figfile=None):
56 58
57 59 """
58 60
59 61 Input:
60 62 dataOut :
61 63 idfigure :
62 64 wintitle :
63 65 channelList :
64 66 showProfile :
65 67 xmin : None,
66 68 xmax : None,
67 69 ymin : None,
68 70 ymax : None,
69 71 zmin : None,
70 72 zmax : None
71 73 """
72 74
73 75 if pairsList == None:
74 76 pairsIndexList = dataOut.pairsIndexList
75 77 else:
76 78 pairsIndexList = []
77 79 for pair in pairsList:
78 80 if pair not in dataOut.pairsList:
79 81 raise ValueError, "Pair %s is not in dataOut.pairsList" %(pair)
80 82 pairsIndexList.append(dataOut.pairsList.index(pair))
81 83
82 84 if pairsIndexList == []:
83 85 return
84 86
85 87 if len(pairsIndexList) > 4:
86 88 pairsIndexList = pairsIndexList[0:4]
87 89
88 90 x = dataOut.getFreqRange(1)
89 91 y = dataOut.getHeiRange()
90 92 z = 10.*numpy.log10(dataOut.data_spc[:,:,:])
91 93 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
92 94 avg = numpy.average(numpy.abs(z), axis=1)
93 95
94 96 noise = dataOut.getNoise()
95 97
96 98 if not self.__isConfig:
97 99
98 100 nplots = len(pairsIndexList)
99 101
100 102 self.setup(idfigure=idfigure,
101 103 nplots=nplots,
102 104 wintitle=wintitle,
103 105 showprofile=showprofile)
104 106
105 107 if xmin == None: xmin = numpy.nanmin(x)
106 108 if xmax == None: xmax = numpy.nanmax(x)
107 109 if ymin == None: ymin = numpy.nanmin(y)
108 110 if ymax == None: ymax = numpy.nanmax(y)
109 111 if zmin == None: zmin = numpy.nanmin(avg)*0.9
110 112 if zmax == None: zmax = numpy.nanmax(avg)*0.9
111 113
112 114 self.__isConfig = True
113 115
114 116 thisDatetime = dataOut.datatime
115 117 title = "Cross-Spectra: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
116 118 xlabel = "Velocity (m/s)"
117 119 ylabel = "Range (Km)"
118 120
119 121 self.setWinTitle(title)
120 122
121 123 for i in range(self.nplots):
122 124 pair = dataOut.pairsList[pairsIndexList[i]]
123 125
124 126 title = "Channel %d: %4.2fdB" %(pair[0], noise[pair[0]])
125 127 z = 10.*numpy.log10(dataOut.data_spc[pair[0],:,:])
126 128 axes0 = self.axesList[i*self.__nsubplots]
127 129 axes0.pcolor(x, y, z,
128 130 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
129 131 xlabel=xlabel, ylabel=ylabel, title=title,
130 132 ticksize=9, cblabel='')
131 133
132 134 title = "Channel %d: %4.2fdB" %(pair[1], noise[pair[1]])
133 135 z = 10.*numpy.log10(dataOut.data_spc[pair[1],:,:])
134 136 axes0 = self.axesList[i*self.__nsubplots+1]
135 137 axes0.pcolor(x, y, z,
136 138 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
137 139 xlabel=xlabel, ylabel=ylabel, title=title,
138 140 ticksize=9, cblabel='')
139 141
140 142 coherenceComplex = dataOut.data_cspc[pairsIndexList[i],:,:]/numpy.sqrt(dataOut.data_spc[pair[0],:,:]*dataOut.data_spc[pair[1],:,:])
141 143 coherence = numpy.abs(coherenceComplex)
142 144 phase = numpy.arctan(-1*coherenceComplex.imag/coherenceComplex.real)*180/numpy.pi
143 145
144 146
145 147 title = "Coherence %d%d" %(pair[0], pair[1])
146 148 axes0 = self.axesList[i*self.__nsubplots+2]
147 149 axes0.pcolor(x, y, coherence,
148 150 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=0, zmax=1,
149 151 xlabel=xlabel, ylabel=ylabel, title=title,
150 152 ticksize=9, cblabel='')
151 153
152 154 title = "Phase %d%d" %(pair[0], pair[1])
153 155 axes0 = self.axesList[i*self.__nsubplots+3]
154 156 axes0.pcolor(x, y, phase,
155 157 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=-180, zmax=180,
156 158 xlabel=xlabel, ylabel=ylabel, title=title,
157 159 ticksize=9, cblabel='', colormap='RdBu')
158 160
159 161
160 162
161 163 self.draw()
162 164
163 165 if save:
164 166 date = thisDatetime.strftime("%Y%m%d")
165 167 if figfile == None:
166 168 figfile = self.getFilename(name = date)
167 169
168 170 self.saveFigure(figpath, figfile)
169 171
170 172
171 173 class RTIPlot(Figure):
172 174
173 175 __isConfig = None
174 176 __nsubplots = None
175 177
176 178 WIDTHPROF = None
177 179 HEIGHTPROF = None
178 180 PREFIX = 'rti'
179 181
180 182 def __init__(self):
181 183
182 184 self.timerange = 24*60*60
183 185 self.__isConfig = False
184 186 self.__nsubplots = 1
185 187
186 188 self.WIDTH = 800
187 189 self.HEIGHT = 200
188 190 self.WIDTHPROF = 120
189 191 self.HEIGHTPROF = 0
190 192
191 193 def getSubplots(self):
192 194
193 195 ncol = 1
194 196 nrow = self.nplots
195 197
196 198 return nrow, ncol
197 199
198 200 def setup(self, idfigure, nplots, wintitle, showprofile=True):
199 201
200 202 self.__showprofile = showprofile
201 203 self.nplots = nplots
202 204
203 205 ncolspan = 1
204 206 colspan = 1
205 207 if showprofile:
206 208 ncolspan = 7
207 209 colspan = 6
208 210 self.__nsubplots = 2
209 211
210 212 self.createFigure(idfigure = idfigure,
211 213 wintitle = wintitle,
212 214 widthplot = self.WIDTH + self.WIDTHPROF,
213 215 heightplot = self.HEIGHT + self.HEIGHTPROF)
214 216
215 217 nrow, ncol = self.getSubplots()
216 218
217 219 counter = 0
218 220 for y in range(nrow):
219 221 for x in range(ncol):
220 222
221 223 if counter >= self.nplots:
222 224 break
223 225
224 226 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
225 227
226 228 if showprofile:
227 229 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
228 230
229 231 counter += 1
230 232
231 233 def run(self, dataOut, idfigure, wintitle="", channelList=None, showprofile='True',
232 234 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
233 235 timerange=None,
234 236 save=False, figpath='./', figfile=None):
235 237
236 238 """
237 239
238 240 Input:
239 241 dataOut :
240 242 idfigure :
241 243 wintitle :
242 244 channelList :
243 245 showProfile :
244 246 xmin : None,
245 247 xmax : None,
246 248 ymin : None,
247 249 ymax : None,
248 250 zmin : None,
249 251 zmax : None
250 252 """
251 253
252 254 if channelList == None:
253 255 channelIndexList = dataOut.channelIndexList
254 256 else:
255 257 channelIndexList = []
256 258 for channel in channelList:
257 259 if channel not in dataOut.channelList:
258 260 raise ValueError, "Channel %d is not in dataOut.channelList"
259 261 channelIndexList.append(dataOut.channelList.index(channel))
260 262
261 263 if timerange != None:
262 264 self.timerange = timerange
263 265
264 266 tmin = None
265 267 tmax = None
266 268 x = dataOut.getTimeRange()
267 269 y = dataOut.getHeiRange()
268 270 z = 10.*numpy.log10(dataOut.data_spc[channelIndexList,:,:])
269 271 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
270 272 avg = numpy.average(z, axis=1)
271 273
272 274 noise = dataOut.getNoise()
273 275
276 thisDatetime = dataOut.datatime
277 title = "RTI: %s" %(thisDatetime.strftime("%d-%b-%Y"))
278 xlabel = "Velocity (m/s)"
279 ylabel = "Range (Km)"
280
274 281 if not self.__isConfig:
275 282
276 283 nplots = len(channelIndexList)
277 284
278 285 self.setup(idfigure=idfigure,
279 286 nplots=nplots,
280 287 wintitle=wintitle,
281 288 showprofile=showprofile)
282 289
283 290 tmin, tmax = self.getTimeLim(x, xmin, xmax)
284 291 if ymin == None: ymin = numpy.nanmin(y)
285 292 if ymax == None: ymax = numpy.nanmax(y)
286 293 if zmin == None: zmin = numpy.nanmin(avg)*0.9
287 294 if zmax == None: zmax = numpy.nanmax(avg)*0.9
288 295
289 296 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
290 297 self.__isConfig = True
291
292 thisDatetime = dataOut.datatime
293 title = "RTI: %s" %(thisDatetime.strftime("%d-%b-%Y"))
294 xlabel = "Velocity (m/s)"
295 ylabel = "Range (Km)"
298
296 299
297 300 self.setWinTitle(title)
298 301
299 302 for i in range(self.nplots):
300 303 title = "Channel %d: %s" %(dataOut.channelList[i], thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
301 304 axes = self.axesList[i*self.__nsubplots]
302 305 z = avg[i].reshape((1,-1))
303 306 axes.pcolor(x, y, z,
304 307 xmin=tmin, xmax=tmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
305 308 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
306 309 ticksize=9, cblabel='', cbsize="1%")
307 310
308 311 if self.__showprofile:
309 312 axes = self.axesList[i*self.__nsubplots +1]
310 313 axes.pline(avg[i], y,
311 314 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
312 315 xlabel='dB', ylabel='', title='',
313 316 ytick_visible=False,
314 317 grid='x')
315 318
316 319 self.draw()
317 320
318 321 if save:
319 322
320 323 if figfile == None:
321 324 figfile = self.getFilename(name = self.name)
322 325
323 326 self.saveFigure(figpath, figfile)
324 327
325 328 if x[1] + (x[1]-x[0]) >= self.axesList[0].xmax:
326 329 self.__isConfig = False
327 330
328 331 class SpectraPlot(Figure):
329 332
330 333 __isConfig = None
331 334 __nsubplots = None
332 335
333 336 WIDTHPROF = None
334 337 HEIGHTPROF = None
335 338 PREFIX = 'spc'
336 339
337 340 def __init__(self):
338 341
339 342 self.__isConfig = False
340 343 self.__nsubplots = 1
341 344
342 self.WIDTH = 300
343 self.HEIGHT = 400
345 self.WIDTH = 230
346 self.HEIGHT = 250
344 347 self.WIDTHPROF = 120
345 348 self.HEIGHTPROF = 0
346 349
347 350 def getSubplots(self):
348 351
349 352 ncol = int(numpy.sqrt(self.nplots)+0.9)
350 353 nrow = int(self.nplots*1./ncol + 0.9)
351 354
352 355 return nrow, ncol
353 356
354 357 def setup(self, idfigure, nplots, wintitle, showprofile=True):
355 358
356 359 self.__showprofile = showprofile
357 360 self.nplots = nplots
358 361
359 362 ncolspan = 1
360 363 colspan = 1
361 364 if showprofile:
362 365 ncolspan = 3
363 366 colspan = 2
364 367 self.__nsubplots = 2
365 368
366 369 self.createFigure(idfigure = idfigure,
367 370 wintitle = wintitle,
368 371 widthplot = self.WIDTH + self.WIDTHPROF,
369 372 heightplot = self.HEIGHT + self.HEIGHTPROF)
370 373
371 374 nrow, ncol = self.getSubplots()
372 375
373 376 counter = 0
374 377 for y in range(nrow):
375 378 for x in range(ncol):
376 379
377 380 if counter >= self.nplots:
378 381 break
379 382
380 383 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
381 384
382 385 if showprofile:
383 386 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
384 387
385 388 counter += 1
386 389
387 390 def run(self, dataOut, idfigure, wintitle="", channelList=None, showprofile='True',
388 391 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
389 392 save=False, figpath='./', figfile=None):
390 393
391 394 """
392 395
393 396 Input:
394 397 dataOut :
395 398 idfigure :
396 399 wintitle :
397 400 channelList :
398 401 showProfile :
399 402 xmin : None,
400 403 xmax : None,
401 404 ymin : None,
402 405 ymax : None,
403 406 zmin : None,
404 407 zmax : None
405 408 """
406 409
407 410 if channelList == None:
408 411 channelIndexList = dataOut.channelIndexList
409 412 else:
410 413 channelIndexList = []
411 414 for channel in channelList:
412 415 if channel not in dataOut.channelList:
413 416 raise ValueError, "Channel %d is not in dataOut.channelList"
414 417 channelIndexList.append(dataOut.channelList.index(channel))
415 418
416 419 x = dataOut.getVelRange(1)
417 420 y = dataOut.getHeiRange()
418 421
419 422 z = 10.*numpy.log10(dataOut.data_spc[channelIndexList,:,:])
420 423 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
421 424 avg = numpy.average(z, axis=1)
422 425
423 426 noise = dataOut.getNoise()
424 427
425 428 if not self.__isConfig:
426 429
427 430 nplots = len(channelIndexList)
428 431
429 432 self.setup(idfigure=idfigure,
430 433 nplots=nplots,
431 434 wintitle=wintitle,
432 435 showprofile=showprofile)
433 436
434 437 if xmin == None: xmin = numpy.nanmin(x)
435 438 if xmax == None: xmax = numpy.nanmax(x)
436 439 if ymin == None: ymin = numpy.nanmin(y)
437 440 if ymax == None: ymax = numpy.nanmax(y)
438 441 if zmin == None: zmin = numpy.nanmin(avg)*0.9
439 442 if zmax == None: zmax = numpy.nanmax(avg)*0.9
440 443
441 444 self.__isConfig = True
442 445
443 446 thisDatetime = dataOut.datatime
444 447 title = "Spectra: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
445 448 xlabel = "Velocity (m/s)"
446 449 ylabel = "Range (Km)"
447 450
448 451 self.setWinTitle(title)
449 452
450 453 for i in range(self.nplots):
451 454 title = "Channel %d: %4.2fdB" %(dataOut.channelList[i], noise[i])
452 455 axes = self.axesList[i*self.__nsubplots]
453 456 axes.pcolor(x, y, z[i,:,:],
454 457 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
455 458 xlabel=xlabel, ylabel=ylabel, title=title,
456 459 ticksize=9, cblabel='')
457 460
458 461 if self.__showprofile:
459 462 axes = self.axesList[i*self.__nsubplots +1]
460 463 axes.pline(avg[i], y,
461 464 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
462 465 xlabel='dB', ylabel='', title='',
463 466 ytick_visible=False,
464 467 grid='x')
465 468
466 469 self.draw()
467 470
468 471 if save:
469 472 date = thisDatetime.strftime("%Y%m%d")
470 473 if figfile == None:
471 474 figfile = self.getFilename(name = date)
472 475
473 476 self.saveFigure(figpath, figfile)
474 477
475 478 class Scope(Figure):
476 479
477 480 __isConfig = None
478 481
479 482 def __init__(self):
480 483
481 484 self.__isConfig = False
482 485 self.WIDTH = 600
483 486 self.HEIGHT = 200
484 487
485 488 def getSubplots(self):
486 489
487 490 nrow = self.nplots
488 491 ncol = 3
489 492 return nrow, ncol
490 493
491 494 def setup(self, idfigure, nplots, wintitle):
492 495
493 496 self.nplots = nplots
494 497
495 498 self.createFigure(idfigure, wintitle)
496 499
497 500 nrow,ncol = self.getSubplots()
498 501 colspan = 3
499 502 rowspan = 1
500 503
501 504 for i in range(nplots):
502 505 self.addAxes(nrow, ncol, i, 0, colspan, rowspan)
503 506
504 507
505 508
506 509 def run(self, dataOut, idfigure, wintitle="", channelList=None,
507 510 xmin=None, xmax=None, ymin=None, ymax=None, save=False, filename=None):
508 511
509 512 """
510 513
511 514 Input:
512 515 dataOut :
513 516 idfigure :
514 517 wintitle :
515 518 channelList :
516 519 xmin : None,
517 520 xmax : None,
518 521 ymin : None,
519 522 ymax : None,
520 523 """
521 524
522 525 if channelList == None:
523 526 channelIndexList = dataOut.channelIndexList
524 527 else:
525 528 channelIndexList = []
526 529 for channel in channelList:
527 530 if channel not in dataOut.channelList:
528 531 raise ValueError, "Channel %d is not in dataOut.channelList"
529 532 channelIndexList.append(dataOut.channelList.index(channel))
530 533
531 534 x = dataOut.heightList
532 535 y = dataOut.data[channelIndexList,:] * numpy.conjugate(dataOut.data[channelIndexList,:])
533 536 y = y.real
534 537
535 538 if not self.__isConfig:
536 539 nplots = len(channelIndexList)
537 540
538 541 self.setup(idfigure=idfigure,
539 542 nplots=nplots,
540 543 wintitle=wintitle)
541 544
542 545 if xmin == None: xmin = numpy.nanmin(x)
543 546 if xmax == None: xmax = numpy.nanmax(x)
544 547 if ymin == None: ymin = numpy.nanmin(y)
545 548 if ymax == None: ymax = numpy.nanmax(y)
546 549
547 550 self.__isConfig = True
548 551
549 552
550 553 thisDatetime = dataOut.datatime
551 554 title = "Scope: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
552 555 xlabel = "Range (Km)"
553 556 ylabel = "Intensity"
554 557
555 558 self.setWinTitle(title)
556 559
557 560 for i in range(len(self.axesList)):
558 561 title = "Channel %d" %(i)
559 562 axes = self.axesList[i]
560 563 ychannel = y[i,:]
561 564 axes.pline(x, ychannel,
562 565 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
563 566 xlabel=xlabel, ylabel=ylabel, title=title)
564 567
565 568 self.draw()
566 569
567 570 if save:
568 571 self.saveFigure(filename)
569 572
570 573 class ProfilePlot(Figure):
571 574 __isConfig = None
572 575 __nsubplots = None
573 576
574 577 WIDTHPROF = None
575 578 HEIGHTPROF = None
576 579 PREFIX = 'spcprofile'
577 580
578 581 def __init__(self):
579 582 self.__isConfig = False
580 583 self.__nsubplots = 1
581 584
582 585 self.WIDTH = 300
583 586 self.HEIGHT = 500
584 587
585 588 def getSubplots(self):
586 589 ncol = 1
587 590 nrow = 1
588 591
589 592 return nrow, ncol
590 593
591 594 def setup(self, idfigure, nplots, wintitle):
592 595
593 596 self.nplots = nplots
594 597
595 598 ncolspan = 1
596 599 colspan = 1
597 600
598 601 self.createFigure(idfigure = idfigure,
599 602 wintitle = wintitle,
600 603 widthplot = self.WIDTH,
601 604 heightplot = self.HEIGHT)
602 605
603 606 nrow, ncol = self.getSubplots()
604 607
605 608 counter = 0
606 609 for y in range(nrow):
607 610 for x in range(ncol):
608 611 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
609 612
610 613 def run(self, dataOut, idfigure, wintitle="", channelList=None,
611 614 xmin=None, xmax=None, ymin=None, ymax=None,
612 615 save=False, figpath='./', figfile=None):
613 616
614 617 if channelList == None:
615 618 channelIndexList = dataOut.channelIndexList
616 619 channelList = dataOut.channelList
617 620 else:
618 621 channelIndexList = []
619 622 for channel in channelList:
620 623 if channel not in dataOut.channelList:
621 624 raise ValueError, "Channel %d is not in dataOut.channelList"
622 625 channelIndexList.append(dataOut.channelList.index(channel))
623 626
624 627
625 628 y = dataOut.getHeiRange()
626 629 x = 10.*numpy.log10(dataOut.data_spc[channelIndexList,:,:])
627 630 avg = numpy.average(x, axis=1)
628 631
629 632
630 633 if not self.__isConfig:
631 634
632 635 nplots = 1
633 636
634 637 self.setup(idfigure=idfigure,
635 638 nplots=nplots,
636 639 wintitle=wintitle)
637 640
638 641 if ymin == None: ymin = numpy.nanmin(y)
639 642 if ymax == None: ymax = numpy.nanmax(y)
640 643 if xmin == None: xmin = numpy.nanmin(avg)*0.9
641 644 if xmax == None: xmax = numpy.nanmax(avg)*0.9
642 645
643 646 self.__isConfig = True
644 647
645 648 thisDatetime = dataOut.datatime
646 649 title = "Power Profile"
647 650 xlabel = "dB"
648 651 ylabel = "Range (Km)"
649 652
650 653 self.setWinTitle(title)
651 654
652 655
653 656 title = "Power Profile: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
654 657 axes = self.axesList[0]
655 658
656 659 legendlabels = ["channel %d"%x for x in channelList]
657 660 axes.pmultiline(avg, y,
658 661 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
659 662 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels,
660 663 ytick_visible=True, nxticks=5,
661 664 grid='x')
662 665
663 666 self.draw()
664 667
665 668 if save:
666 669 date = thisDatetime.strftime("%Y%m%d")
667 670 if figfile == None:
668 671 figfile = self.getFilename(name = date)
669 672
670 673 self.saveFigure(figpath, figfile)
671 674
672 class CoherencePlot(Figure):
675 class CoherenceMap(Figure):
673 676 __isConfig = None
674 677 __nsubplots = None
675 678
676 679 WIDTHPROF = None
677 680 HEIGHTPROF = None
678 681 PREFIX = 'coherencemap'
679 682
680 683 def __init__(self):
681 684 self.timerange = 24*60*60
682 685 self.__isConfig = False
683 686 self.__nsubplots = 1
684 687
685 688 self.WIDTH = 800
686 689 self.HEIGHT = 200
687 690 self.WIDTHPROF = 120
688 691 self.HEIGHTPROF = 0
689 692
690 693 def getSubplots(self):
691 694 ncol = 1
692 695 nrow = self.nplots*2
693 696
694 697 return nrow, ncol
695 698
696 699 def setup(self, idfigure, nplots, wintitle, showprofile=True):
697 700 self.__showprofile = showprofile
698 701 self.nplots = nplots
699 702
700 703 ncolspan = 1
701 704 colspan = 1
702 705 if showprofile:
703 706 ncolspan = 7
704 707 colspan = 6
705 708 self.__nsubplots = 2
706 709
707 710 self.createFigure(idfigure = idfigure,
708 711 wintitle = wintitle,
709 712 widthplot = self.WIDTH + self.WIDTHPROF,
710 713 heightplot = self.HEIGHT + self.HEIGHTPROF)
711 714
712 715 nrow, ncol = self.getSubplots()
713 716
714 717 for y in range(nrow):
715 718 for x in range(ncol):
716 719
717 720 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
718 721
719 722 if showprofile:
720 723 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
721 724
722 725 def run(self, dataOut, idfigure, wintitle="", pairsList=None, showprofile='True',
723 726 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
724 727 timerange=None,
725 728 save=False, figpath='./', figfile=None):
726 729
727 730 if pairsList == None:
728 731 pairsIndexList = dataOut.pairsIndexList
729 732 else:
730 733 pairsIndexList = []
731 734 for pair in pairsList:
732 735 if pair not in dataOut.pairsList:
733 736 raise ValueError, "Pair %s is not in dataOut.pairsList" %(pair)
734 737 pairsIndexList.append(dataOut.pairsList.index(pair))
735 738
736 739 if timerange != None:
737 740 self.timerange = timerange
738 741
742 if pairsIndexList == []:
743 return
744
745 if len(pairsIndexList) > 4:
746 pairsIndexList = pairsIndexList[0:4]
747
739 748 tmin = None
740 749 tmax = None
741 750 x = dataOut.getTimeRange()
742 751 y = dataOut.getHeiRange()
743 752
744 753 if not self.__isConfig:
745 754 nplots = len(pairsIndexList)
746 755 self.setup(idfigure=idfigure,
747 756 nplots=nplots,
748 757 wintitle=wintitle,
749 758 showprofile=showprofile)
750 759
751 760 tmin, tmax = self.getTimeLim(x, xmin, xmax)
752 761 if ymin == None: ymin = numpy.nanmin(y)
753 762 if ymax == None: ymax = numpy.nanmax(y)
754 763
755 764 self.__isConfig = True
756 765
757 766 thisDatetime = dataOut.datatime
758 767 title = "CoherenceMap: %s" %(thisDatetime.strftime("%d-%b-%Y"))
759 768 xlabel = ""
760 769 ylabel = "Range (Km)"
761 770
762 771 self.setWinTitle(title)
763 772
764 773 for i in range(self.nplots):
765 774
766 775 pair = dataOut.pairsList[pairsIndexList[i]]
767 776 coherenceComplex = dataOut.data_cspc[pairsIndexList[i],:,:]/numpy.sqrt(dataOut.data_spc[pair[0],:,:]*dataOut.data_spc[pair[1],:,:])
768 777 coherence = numpy.abs(coherenceComplex)
769 778 avg = numpy.average(coherence, axis=0)
770 779 z = avg.reshape((1,-1))
771 780
772 781 counter = 0
773 782
774 783 title = "Coherence %d%d: %s" %(pair[0], pair[1], thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
775 784 axes = self.axesList[i*self.__nsubplots*2]
776 785 axes.pcolor(x, y, z,
777 786 xmin=tmin, xmax=tmax, ymin=ymin, ymax=ymax, zmin=0, zmax=1,
778 787 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
779 788 ticksize=9, cblabel='', cbsize="1%")
780 789
781 790 if self.__showprofile:
782 791 counter += 1
783 792 axes = self.axesList[i*self.__nsubplots*2 + counter]
784 793 axes.pline(avg, y,
785 794 xmin=0, xmax=1, ymin=ymin, ymax=ymax,
786 795 xlabel='', ylabel='', title='', ticksize=7,
787 796 ytick_visible=False, nxticks=5,
788 797 grid='x')
789 798
790 799 counter += 1
791 800 phase = numpy.arctan(-1*coherenceComplex.imag/coherenceComplex.real)*180/numpy.pi
792 801 avg = numpy.average(phase, axis=0)
793 802 z = avg.reshape((1,-1))
794 803
795 804 title = "Phase %d%d: %s" %(pair[0], pair[1], thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
796 805 axes = self.axesList[i*self.__nsubplots*2 + counter]
797 806 axes.pcolor(x, y, z,
798 807 xmin=tmin, xmax=tmax, ymin=ymin, ymax=ymax, zmin=-180, zmax=180,
799 808 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
800 809 ticksize=9, cblabel='', colormap='RdBu', cbsize="1%")
801 810
802 811 if self.__showprofile:
803 812 counter += 1
804 813 axes = self.axesList[i*self.__nsubplots*2 + counter]
805 814 axes.pline(avg, y,
806 815 xmin=-180, xmax=180, ymin=ymin, ymax=ymax,
807 816 xlabel='', ylabel='', title='', ticksize=7,
808 817 ytick_visible=False, nxticks=4,
809 818 grid='x')
810 819
811 820 self.draw()
812 821
813 822 if save:
814 823 date = thisDatetime.strftime("%Y%m%d")
815 824 if figfile == None:
816 825 figfile = self.getFilename(name = date)
817 826
818 827 self.saveFigure(figpath, figfile)
819 828
820 829 if x[1] + (x[1]-x[0]) >= self.axesList[0].xmax:
821 830 self.__isConfig = False
822 831
823 832 class RTIfromNoise(Figure):
824 833
825 834 __isConfig = None
826 835 __nsubplots = None
827 836
828 837 WIDTHPROF = None
829 838 HEIGHTPROF = None
830 839 PREFIX = 'rti'
831 840
832 841 def __init__(self):
833 842
834 843 self.__timerange = 24*60*60
835 844 self.__isConfig = False
836 845 self.__nsubplots = 1
837 846
838 847 self.WIDTH = 800
839 848 self.HEIGHT = 200
840 849
841 850 def getSubplots(self):
842 851
843 852 ncol = 1
844 853 nrow = self.nplots
845 854
846 855 return nrow, ncol
847 856
848 857 def setup(self, idfigure, nplots, wintitle, showprofile=True):
849 858
850 859 self.__showprofile = showprofile
851 860 self.nplots = nplots
852 861
853 862 ncolspan = 1
854 863 colspan = 1
855 864
856 865 self.createFigure(idfigure = idfigure,
857 866 wintitle = wintitle,
858 867 widthplot = self.WIDTH + self.WIDTHPROF,
859 868 heightplot = self.HEIGHT + self.HEIGHTPROF)
860 869
861 870 nrow, ncol = self.getSubplots()
862 871
863 872 self.addAxes(nrow, ncol, 0, 0, 1, 1)
864 873
865 874
866 875
867 876 def __getTimeLim(self, x, xmin, xmax):
868 877
869 878 thisdatetime = datetime.datetime.fromtimestamp(numpy.min(x))
870 879 thisdate = datetime.datetime.combine(thisdatetime.date(), datetime.time(0,0,0))
871 880
872 881 ####################################################
873 882 #If the x is out of xrange
874 883 if xmax < (thisdatetime - thisdate).seconds/(60*60.):
875 884 xmin = None
876 885 xmax = None
877 886
878 887 if xmin == None:
879 888 td = thisdatetime - thisdate
880 889 xmin = td.seconds/(60*60.)
881 890
882 891 if xmax == None:
883 892 xmax = xmin + self.__timerange/(60*60.)
884 893
885 894 mindt = thisdate + datetime.timedelta(0,0,0,0,0, xmin)
886 895 tmin = time.mktime(mindt.timetuple())
887 896
888 897 maxdt = thisdate + datetime.timedelta(0,0,0,0,0, xmax)
889 898 tmax = time.mktime(maxdt.timetuple())
890 899
891 900 self.__timerange = tmax - tmin
892 901
893 902 return tmin, tmax
894 903
895 904 def run(self, dataOut, idfigure, wintitle="", channelList=None, showprofile='True',
896 905 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
897 906 timerange=None,
898 907 save=False, figpath='./', figfile=None):
899 908
900 909 if channelList == None:
901 910 channelIndexList = dataOut.channelIndexList
902 911 else:
903 912 channelIndexList = []
904 913 for channel in channelList:
905 914 if channel not in dataOut.channelList:
906 915 raise ValueError, "Channel %d is not in dataOut.channelList"
907 916 channelIndexList.append(dataOut.channelList.index(channel))
908 917
909 918 if timerange != None:
910 919 self.__timerange = timerange
911 920
912 921 tmin = None
913 922 tmax = None
914 923 x = dataOut.getTimeRange()
915 924 y = dataOut.getHeiRange()
916 925 x1 = dataOut.datatime
917 926 # z = 10.*numpy.log10(dataOut.data_spc[channelIndexList,:,:])
918 927 # avg = numpy.average(z, axis=1)
919 928
920 929 noise = dataOut.getNoise()
921 930
922 931 if not self.__isConfig:
923 932
924 933 nplots = len(channelIndexList)
925 934
926 935 self.setup(idfigure=idfigure,
927 936 nplots=nplots,
928 937 wintitle=wintitle,
929 938 showprofile=showprofile)
930 939
931 940 tmin, tmax = self.__getTimeLim(x, xmin, xmax)
932 941 if ymin == None: ymin = numpy.nanmin(y)
933 942 if ymax == None: ymax = numpy.nanmax(y)
934 943 if zmin == None: zmin = numpy.nanmin(avg)*0.9
935 944 if zmax == None: zmax = numpy.nanmax(avg)*0.9
936 945
937 946 self.__isConfig = True
938 947
939 948 thisDatetime = dataOut.datatime
940 949 title = "RTI: %s" %(thisDatetime.strftime("%d-%b-%Y"))
941 950 xlabel = "Velocity (m/s)"
942 951 ylabel = "Range (Km)"
943 952
944 953 self.setWinTitle(title)
945 954
946 955 for i in range(self.nplots):
947 956 title = "Channel %d: %s" %(dataOut.channelList[i], thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
948 957 axes = self.axesList[i*self.__nsubplots]
949 958 z = avg[i].reshape((1,-1))
950 959 axes.pcolor(x, y, z,
951 960 xmin=tmin, xmax=tmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
952 961 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
953 962 ticksize=9, cblabel='', cbsize="1%")
954 963
955 964
956 965 self.draw()
957 966
958 967 if save:
959 968 date = thisDatetime.strftime("%Y%m%d")
960 969 if figfile == None:
961 970 figfile = self.getFilename(name = date)
962 971
963 972 self.saveFigure(figpath, figfile)
964 973
965 974 if x[1] + (x[1]-x[0]) >= self.axesList[0].xmax:
966 975 self.__isConfig = False
967 976 No newline at end of file
@@ -1,1150 +1,1151
1 1 '''
2 2
3 3 $Author: dsuarez $
4 4 $Id: Processor.py 1 2012-11-12 18:56:07Z dsuarez $
5 5 '''
6 6 import os
7 7 import numpy
8 8 import datetime
9 9 import time
10 10
11 11 from jrodata import *
12 12 from jrodataIO import *
13 13 from jroplot import *
14 14
15 15 class ProcessingUnit:
16 16
17 17 """
18 18 Esta es la clase base para el procesamiento de datos.
19 19
20 20 Contiene el metodo "call" para llamar operaciones. Las operaciones pueden ser:
21 21 - Metodos internos (callMethod)
22 22 - Objetos del tipo Operation (callObject). Antes de ser llamados, estos objetos
23 23 tienen que ser agreagados con el metodo "add".
24 24
25 25 """
26 26 # objeto de datos de entrada (Voltage, Spectra o Correlation)
27 27 dataIn = None
28 28
29 29 # objeto de datos de entrada (Voltage, Spectra o Correlation)
30 30 dataOut = None
31 31
32 32
33 33 objectDict = None
34 34
35 35 def __init__(self):
36 36
37 37 self.objectDict = {}
38 38
39 39 def init(self):
40 40
41 41 raise ValueError, "Not implemented"
42 42
43 43 def addOperation(self, object, objId):
44 44
45 45 """
46 46 Agrega el objeto "object" a la lista de objetos "self.objectList" y retorna el
47 47 identificador asociado a este objeto.
48 48
49 49 Input:
50 50
51 51 object : objeto de la clase "Operation"
52 52
53 53 Return:
54 54
55 55 objId : identificador del objeto, necesario para ejecutar la operacion
56 56 """
57 57
58 58 self.objectDict[objId] = object
59 59
60 60 return objId
61 61
62 62 def operation(self, **kwargs):
63 63
64 64 """
65 65 Operacion directa sobre la data (dataOut.data). Es necesario actualizar los valores de los
66 66 atributos del objeto dataOut
67 67
68 68 Input:
69 69
70 70 **kwargs : Diccionario de argumentos de la funcion a ejecutar
71 71 """
72 72
73 73 raise ValueError, "ImplementedError"
74 74
75 75 def callMethod(self, name, **kwargs):
76 76
77 77 """
78 78 Ejecuta el metodo con el nombre "name" y con argumentos **kwargs de la propia clase.
79 79
80 80 Input:
81 81 name : nombre del metodo a ejecutar
82 82
83 83 **kwargs : diccionario con los nombres y valores de la funcion a ejecutar.
84 84
85 85 """
86 86 if name != 'run':
87 87
88 88 if name == 'init' and self.dataIn.isEmpty():
89 89 self.dataOut.flagNoData = True
90 90 return False
91 91
92 92 if name != 'init' and self.dataOut.isEmpty():
93 93 return False
94 94
95 95 methodToCall = getattr(self, name)
96 96
97 97 methodToCall(**kwargs)
98 98
99 99 if name != 'run':
100 100 return True
101 101
102 102 if self.dataOut.isEmpty():
103 103 return False
104 104
105 105 return True
106 106
107 107 def callObject(self, objId, **kwargs):
108 108
109 109 """
110 110 Ejecuta la operacion asociada al identificador del objeto "objId"
111 111
112 112 Input:
113 113
114 114 objId : identificador del objeto a ejecutar
115 115
116 116 **kwargs : diccionario con los nombres y valores de la funcion a ejecutar.
117 117
118 118 Return:
119 119
120 120 None
121 121 """
122 122
123 123 if self.dataOut.isEmpty():
124 124 return False
125 125
126 126 object = self.objectDict[objId]
127 127
128 128 object.run(self.dataOut, **kwargs)
129 129
130 130 return True
131 131
132 132 def call(self, operationConf, **kwargs):
133 133
134 134 """
135 135 Return True si ejecuta la operacion "operationConf.name" con los
136 136 argumentos "**kwargs". False si la operacion no se ha ejecutado.
137 137 La operacion puede ser de dos tipos:
138 138
139 139 1. Un metodo propio de esta clase:
140 140
141 141 operation.type = "self"
142 142
143 143 2. El metodo "run" de un objeto del tipo Operation o de un derivado de ella:
144 144 operation.type = "other".
145 145
146 146 Este objeto de tipo Operation debe de haber sido agregado antes con el metodo:
147 147 "addOperation" e identificado con el operation.id
148 148
149 149
150 150 con el id de la operacion.
151 151
152 152 Input:
153 153
154 154 Operation : Objeto del tipo operacion con los atributos: name, type y id.
155 155
156 156 """
157 157
158 158 if operationConf.type == 'self':
159 159 sts = self.callMethod(operationConf.name, **kwargs)
160 160
161 161 if operationConf.type == 'other':
162 162 sts = self.callObject(operationConf.id, **kwargs)
163 163
164 164 return sts
165 165
166 166 def setInput(self, dataIn):
167 167
168 168 self.dataIn = dataIn
169 169
170 170 def getOutput(self):
171 171
172 172 return self.dataOut
173 173
174 174 class Operation():
175 175
176 176 """
177 177 Clase base para definir las operaciones adicionales que se pueden agregar a la clase ProcessingUnit
178 178 y necesiten acumular informacion previa de los datos a procesar. De preferencia usar un buffer de
179 179 acumulacion dentro de esta clase
180 180
181 181 Ejemplo: Integraciones coherentes, necesita la informacion previa de los n perfiles anteriores (bufffer)
182 182
183 183 """
184 184
185 185 __buffer = None
186 186 __isConfig = False
187 187
188 188 def __init__(self):
189 189
190 190 pass
191 191
192 192 def run(self, dataIn, **kwargs):
193 193
194 194 """
195 195 Realiza las operaciones necesarias sobre la dataIn.data y actualiza los atributos del objeto dataIn.
196 196
197 197 Input:
198 198
199 199 dataIn : objeto del tipo JROData
200 200
201 201 Return:
202 202
203 203 None
204 204
205 205 Affected:
206 206 __buffer : buffer de recepcion de datos.
207 207
208 208 """
209 209
210 210 raise ValueError, "ImplementedError"
211 211
212 212 class VoltageProc(ProcessingUnit):
213 213
214 214
215 215 def __init__(self):
216 216
217 217 self.objectDict = {}
218 218 self.dataOut = Voltage()
219 219
220 220 def init(self):
221 221
222 222 self.dataOut.copy(self.dataIn)
223 223 # No necesita copiar en cada init() los atributos de dataIn
224 224 # la copia deberia hacerse por cada nuevo bloque de datos
225 225
226 226 def selectChannels(self, channelList):
227 227
228 228 channelIndexList = []
229 229
230 230 for channel in channelList:
231 231 index = self.dataOut.channelList.index(channel)
232 232 channelIndexList.append(index)
233 233
234 234 self.selectChannelsByIndex(channelIndexList)
235 235
236 236 def selectChannelsByIndex(self, channelIndexList):
237 237 """
238 238 Selecciona un bloque de datos en base a canales segun el channelIndexList
239 239
240 240 Input:
241 241 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
242 242
243 243 Affected:
244 244 self.dataOut.data
245 245 self.dataOut.channelIndexList
246 246 self.dataOut.nChannels
247 247 self.dataOut.m_ProcessingHeader.totalSpectra
248 248 self.dataOut.systemHeaderObj.numChannels
249 249 self.dataOut.m_ProcessingHeader.blockSize
250 250
251 251 Return:
252 252 None
253 253 """
254 254
255 255 for channelIndex in channelIndexList:
256 256 if channelIndex not in self.dataOut.channelIndexList:
257 257 print channelIndexList
258 258 raise ValueError, "The value %d in channelIndexList is not valid" %channelIndex
259 259
260 260 nChannels = len(channelIndexList)
261 261
262 262 data = self.dataOut.data[channelIndexList,:]
263 263
264 264 self.dataOut.data = data
265 265 self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
266 266 # self.dataOut.nChannels = nChannels
267 267
268 268 return 1
269 269
270 270 def selectHeights(self, minHei, maxHei):
271 271 """
272 272 Selecciona un bloque de datos en base a un grupo de valores de alturas segun el rango
273 273 minHei <= height <= maxHei
274 274
275 275 Input:
276 276 minHei : valor minimo de altura a considerar
277 277 maxHei : valor maximo de altura a considerar
278 278
279 279 Affected:
280 280 Indirectamente son cambiados varios valores a travez del metodo selectHeightsByIndex
281 281
282 282 Return:
283 283 1 si el metodo se ejecuto con exito caso contrario devuelve 0
284 284 """
285 285 if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei):
286 286 raise ValueError, "some value in (%d,%d) is not valid" % (minHei, maxHei)
287 287
288 288 if (maxHei > self.dataOut.heightList[-1]):
289 289 maxHei = self.dataOut.heightList[-1]
290 290 # raise ValueError, "some value in (%d,%d) is not valid" % (minHei, maxHei)
291 291
292 292 minIndex = 0
293 293 maxIndex = 0
294 294 data = self.dataOut.heightList
295 295
296 296 for i,val in enumerate(data):
297 297 if val < minHei:
298 298 continue
299 299 else:
300 300 minIndex = i;
301 301 break
302 302
303 303 for i,val in enumerate(data):
304 304 if val <= maxHei:
305 305 maxIndex = i;
306 306 else:
307 307 break
308 308
309 309 self.selectHeightsByIndex(minIndex, maxIndex)
310 310
311 311 return 1
312 312
313 313
314 314 def selectHeightsByIndex(self, minIndex, maxIndex):
315 315 """
316 316 Selecciona un bloque de datos en base a un grupo indices de alturas segun el rango
317 317 minIndex <= index <= maxIndex
318 318
319 319 Input:
320 320 minIndex : valor de indice minimo de altura a considerar
321 321 maxIndex : valor de indice maximo de altura a considerar
322 322
323 323 Affected:
324 324 self.dataOut.data
325 325 self.dataOut.heightList
326 326
327 327 Return:
328 328 1 si el metodo se ejecuto con exito caso contrario devuelve 0
329 329 """
330 330
331 331 if (minIndex < 0) or (minIndex > maxIndex):
332 332 raise ValueError, "some value in (%d,%d) is not valid" % (minIndex, maxIndex)
333 333
334 334 if (maxIndex >= self.dataOut.nHeights):
335 335 maxIndex = self.dataOut.nHeights-1
336 336 # raise ValueError, "some value in (%d,%d) is not valid" % (minIndex, maxIndex)
337 337
338 338 nHeights = maxIndex - minIndex + 1
339 339
340 340 #voltage
341 341 data = self.dataOut.data[:,minIndex:maxIndex+1]
342 342
343 343 firstHeight = self.dataOut.heightList[minIndex]
344 344
345 345 self.dataOut.data = data
346 346 self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex+1]
347 347
348 348 return 1
349 349
350 350
351 351 def filterByHeights(self, window):
352 352 deltaHeight = self.dataOut.heightList[1] - self.dataOut.heightList[0]
353 353
354 354 if window == None:
355 355 window = self.dataOut.radarControllerHeaderObj.txA / deltaHeight
356 356
357 357 newdelta = deltaHeight * window
358 358 r = self.dataOut.data.shape[1] % window
359 359 buffer = self.dataOut.data[:,0:self.dataOut.data.shape[1]-r]
360 360 buffer = buffer.reshape(self.dataOut.data.shape[0],self.dataOut.data.shape[1]/window,window)
361 361 buffer = numpy.average(buffer,2)
362 362 self.dataOut.data = buffer
363 363 self.dataOut.heightList = numpy.arange(self.dataOut.heightList[0],newdelta*self.dataOut.nHeights/window,newdelta)
364 364
365 365
366 366
367 367 class CohInt(Operation):
368 368
369 369 __isConfig = False
370 370
371 371 __profIndex = 0
372 372 __withOverapping = False
373 373
374 374 __byTime = False
375 375 __initime = None
376 376 __lastdatatime = None
377 377 __integrationtime = None
378 378
379 379 __buffer = None
380 380
381 381 __dataReady = False
382 382
383 383 n = None
384 384
385 385
386 386 def __init__(self):
387 387
388 388 self.__isConfig = False
389 389
390 390 def setup(self, n=None, timeInterval=None, overlapping=False):
391 391 """
392 392 Set the parameters of the integration class.
393 393
394 394 Inputs:
395 395
396 396 n : Number of coherent integrations
397 397 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
398 398 overlapping :
399 399
400 400 """
401 401
402 402 self.__initime = None
403 403 self.__lastdatatime = 0
404 404 self.__buffer = None
405 405 self.__dataReady = False
406 406
407 407
408 408 if n == None and timeInterval == None:
409 409 raise ValueError, "n or timeInterval should be specified ..."
410 410
411 411 if n != None:
412 412 self.n = n
413 413 self.__byTime = False
414 414 else:
415 415 self.__integrationtime = timeInterval * 60. #if (type(timeInterval)!=integer) -> change this line
416 416 self.n = 9999
417 417 self.__byTime = True
418 418
419 419 if overlapping:
420 420 self.__withOverapping = True
421 421 self.__buffer = None
422 422 else:
423 423 self.__withOverapping = False
424 424 self.__buffer = 0
425 425
426 426 self.__profIndex = 0
427 427
428 428 def putData(self, data):
429 429
430 430 """
431 431 Add a profile to the __buffer and increase in one the __profileIndex
432 432
433 433 """
434 434
435 435 if not self.__withOverapping:
436 436 self.__buffer += data.copy()
437 437 self.__profIndex += 1
438 438 return
439 439
440 440 #Overlapping data
441 441 nChannels, nHeis = data.shape
442 442 data = numpy.reshape(data, (1, nChannels, nHeis))
443 443
444 444 #If the buffer is empty then it takes the data value
445 445 if self.__buffer == None:
446 446 self.__buffer = data
447 447 self.__profIndex += 1
448 448 return
449 449
450 450 #If the buffer length is lower than n then stakcing the data value
451 451 if self.__profIndex < self.n:
452 452 self.__buffer = numpy.vstack((self.__buffer, data))
453 453 self.__profIndex += 1
454 454 return
455 455
456 456 #If the buffer length is equal to n then replacing the last buffer value with the data value
457 457 self.__buffer = numpy.roll(self.__buffer, -1, axis=0)
458 458 self.__buffer[self.n-1] = data
459 459 self.__profIndex = self.n
460 460 return
461 461
462 462
463 463 def pushData(self):
464 464 """
465 465 Return the sum of the last profiles and the profiles used in the sum.
466 466
467 467 Affected:
468 468
469 469 self.__profileIndex
470 470
471 471 """
472 472
473 473 if not self.__withOverapping:
474 474 data = self.__buffer
475 475 n = self.__profIndex
476 476
477 477 self.__buffer = 0
478 478 self.__profIndex = 0
479 479
480 480 return data, n
481 481
482 482 #Integration with Overlapping
483 483 data = numpy.sum(self.__buffer, axis=0)
484 484 n = self.__profIndex
485 485
486 486 return data, n
487 487
488 488 def byProfiles(self, data):
489 489
490 490 self.__dataReady = False
491 491 avgdata = None
492 492 n = None
493 493
494 494 self.putData(data)
495 495
496 496 if self.__profIndex == self.n:
497 497
498 498 avgdata, n = self.pushData()
499 499 self.__dataReady = True
500 500
501 501 return avgdata
502 502
503 503 def byTime(self, data, datatime):
504 504
505 505 self.__dataReady = False
506 506 avgdata = None
507 507 n = None
508 508
509 509 self.putData(data)
510 510
511 511 if (datatime - self.__initime) >= self.__integrationtime:
512 512 avgdata, n = self.pushData()
513 513 self.n = n
514 514 self.__dataReady = True
515 515
516 516 return avgdata
517 517
518 518 def integrate(self, data, datatime=None):
519 519
520 520 if self.__initime == None:
521 521 self.__initime = datatime
522 522
523 523 if self.__byTime:
524 524 avgdata = self.byTime(data, datatime)
525 525 else:
526 526 avgdata = self.byProfiles(data)
527 527
528 528
529 529 self.__lastdatatime = datatime
530 530
531 531 if avgdata == None:
532 532 return None, None
533 533
534 534 avgdatatime = self.__initime
535 535
536 536 deltatime = datatime -self.__lastdatatime
537 537
538 538 if not self.__withOverapping:
539 539 self.__initime = datatime
540 540 else:
541 541 self.__initime += deltatime
542 542
543 543 return avgdata, avgdatatime
544 544
545 545 def run(self, dataOut, **kwargs):
546 546
547 547 if not self.__isConfig:
548 548 self.setup(**kwargs)
549 549 self.__isConfig = True
550 550
551 551 avgdata, avgdatatime = self.integrate(dataOut.data, dataOut.utctime)
552 552
553 553 # dataOut.timeInterval *= n
554 554 dataOut.flagNoData = True
555 555
556 556 if self.__dataReady:
557 557 dataOut.data = avgdata
558 558 dataOut.nCohInt *= self.n
559 559 dataOut.utctime = avgdatatime
560 560 dataOut.timeInterval = dataOut.ippSeconds * dataOut.nCohInt
561 561 dataOut.flagNoData = False
562 562
563 563
564 564 class Decoder(Operation):
565 565
566 566 __isConfig = False
567 567 __profIndex = 0
568 568
569 569 code = None
570 570
571 571 nCode = None
572 572 nBaud = None
573 573
574 574 def __init__(self):
575 575
576 576 self.__isConfig = False
577 577
578 578 def setup(self, code):
579 579
580 580 self.__profIndex = 0
581 581
582 582 self.code = code
583 583
584 584 self.nCode = len(code)
585 585 self.nBaud = len(code[0])
586 586
587 587 def convolutionInFreq(self, data):
588 588
589 589 ndata = data.shape[1]
590 590 newcode = numpy.zeros(ndata)
591 591 newcode[0:self.nBaud] = self.code[self.__profIndex]
592 592
593 593 fft_data = numpy.fft.fft(data, axis=1)
594 594 fft_code = numpy.conj(numpy.fft.fft(newcode))
595 595 fft_code = fft_code.reshape(1,len(fft_code))
596 596
597 597 # conv = fft_data.copy()
598 598 # conv.fill(0)
599 599
600 600 conv = fft_data*fft_code
601 601
602 602 data = numpy.fft.ifft(conv,axis=1)
603 603
604 604 datadec = data[:,:-self.nBaud+1]
605 605 ndatadec = ndata - self.nBaud + 1
606 606
607 607 if self.__profIndex == self.nCode:
608 608 self.__profIndex = 0
609 609
610 610 self.__profIndex += 1
611 611
612 612 return ndatadec, datadec
613 613
614 614
615 615 def convolutionInTime(self, data):
616 616
617 617 nchannel = data.shape[1]
618 618 newcode = self.code[self.__profIndex]
619 619
620 620 datadec = data.copy()
621 621
622 622 for i in range(nchannel):
623 623 datadec[i,:] = numpy.correlate(data[i,:], newcode)
624 624
625 625 ndatadec = ndata - self.nBaud + 1
626 626
627 627 if self.__profIndex == self.nCode:
628 628 self.__profIndex = 0
629 629
630 630 self.__profIndex += 1
631 631
632 632 return ndatadec, datadec
633 633
634 634 def run(self, dataOut, code=None, mode = 0):
635 635
636 636 if not self.__isConfig:
637 637
638 638 if code == None:
639 639 code = dataOut.code
640 640
641 641 self.setup(code)
642 642 self.__isConfig = True
643 643
644 644 if mode == 0:
645 645 ndatadec, datadec = self.convolutionInFreq(data)
646 646
647 647 if mode == 1:
648 648 ndatadec, datadec = self.convolutionInTime(data)
649 649
650 650 dataOut.data = datadec
651 651
652 652 dataOut.heightList = dataOut.heightList[0:ndatadec+1]
653 653
654 654 dataOut.flagDecodeData = True #asumo q la data no esta decodificada
655 655
656 656 # dataOut.flagDeflipData = True #asumo q la data no esta sin flip
657 657
658 658
659 659 class SpectraProc(ProcessingUnit):
660 660
661 661 def __init__(self):
662 662
663 663 self.objectDict = {}
664 664 self.buffer = None
665 665 self.firstdatatime = None
666 666 self.profIndex = 0
667 667 self.dataOut = Spectra()
668 668
669 669 def __updateObjFromInput(self):
670 670
671 671 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
672 672 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
673 673 self.dataOut.channelList = self.dataIn.channelList
674 674 self.dataOut.heightList = self.dataIn.heightList
675 675 self.dataOut.dtype = self.dataIn.dtype
676 676 # self.dataOut.nHeights = self.dataIn.nHeights
677 677 # self.dataOut.nChannels = self.dataIn.nChannels
678 678 self.dataOut.nBaud = self.dataIn.nBaud
679 679 self.dataOut.nCode = self.dataIn.nCode
680 680 self.dataOut.code = self.dataIn.code
681 681 self.dataOut.nProfiles = self.dataOut.nFFTPoints
682 682 # self.dataOut.channelIndexList = self.dataIn.channelIndexList
683 683 self.dataOut.flagTimeBlock = self.dataIn.flagTimeBlock
684 684 self.dataOut.utctime = self.firstdatatime
685 685 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData #asumo q la data esta decodificada
686 686 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData #asumo q la data esta sin flip
687 687 self.dataOut.flagShiftFFT = self.dataIn.flagShiftFFT
688 688 self.dataOut.nCohInt = self.dataIn.nCohInt
689 689 self.dataOut.nIncohInt = 1
690 690 self.dataOut.ippSeconds = self.dataIn.ippSeconds
691 691
692 692 self.dataOut.timeInterval = self.dataIn.timeInterval*self.dataOut.nFFTPoints*self.dataOut.nIncohInt
693 693
694 694 def __getFft(self):
695 695 """
696 696 Convierte valores de Voltaje a Spectra
697 697
698 698 Affected:
699 699 self.dataOut.data_spc
700 700 self.dataOut.data_cspc
701 701 self.dataOut.data_dc
702 702 self.dataOut.heightList
703 703 self.profIndex
704 704 self.buffer
705 705 self.dataOut.flagNoData
706 706 """
707 707 fft_volt = numpy.fft.fft(self.buffer,axis=1)
708 708 dc = fft_volt[:,0,:]
709 709
710 710 #calculo de self-spectra
711 711 fft_volt = numpy.fft.fftshift(fft_volt,axes=(1,))
712 712 spc = fft_volt * numpy.conjugate(fft_volt)
713 713 spc = spc.real
714 714
715 715 blocksize = 0
716 716 blocksize += dc.size
717 717 blocksize += spc.size
718 718
719 719 cspc = None
720 720 pairIndex = 0
721 721 if self.dataOut.pairsList != None:
722 722 #calculo de cross-spectra
723 723 cspc = numpy.zeros((self.dataOut.nPairs, self.dataOut.nFFTPoints, self.dataOut.nHeights), dtype='complex')
724 724 for pair in self.dataOut.pairsList:
725 725 cspc[pairIndex,:,:] = fft_volt[pair[0],:,:] * numpy.conjugate(fft_volt[pair[1],:,:])
726 726 pairIndex += 1
727 727 blocksize += cspc.size
728 728
729 729 self.dataOut.data_spc = spc
730 730 self.dataOut.data_cspc = cspc
731 731 self.dataOut.data_dc = dc
732 732 self.dataOut.blockSize = blocksize
733 733
734 734 def init(self, nFFTPoints=None, pairsList=None):
735 735
736 736 self.dataOut.flagNoData = True
737 737
738 738 if self.dataIn.type == "Spectra":
739 739 self.dataOut.copy(self.dataIn)
740 740 return
741 741
742 742 if self.dataIn.type == "Voltage":
743 743
744 744 if nFFTPoints == None:
745 745 raise ValueError, "This SpectraProc.init() need nFFTPoints input variable"
746 746
747 747 if pairsList == None:
748 748 nPairs = 0
749 749 else:
750 750 nPairs = len(pairsList)
751 751
752 752 self.dataOut.nFFTPoints = nFFTPoints
753 753 self.dataOut.pairsList = pairsList
754 754 self.dataOut.nPairs = nPairs
755 755
756 756 if self.buffer == None:
757 757 self.buffer = numpy.zeros((self.dataIn.nChannels,
758 758 self.dataOut.nFFTPoints,
759 759 self.dataIn.nHeights),
760 760 dtype='complex')
761 761
762 762
763 763 self.buffer[:,self.profIndex,:] = self.dataIn.data.copy()
764 764 self.profIndex += 1
765 765
766 766 if self.firstdatatime == None:
767 767 self.firstdatatime = self.dataIn.utctime
768 768
769 769 if self.profIndex == self.dataOut.nFFTPoints:
770 770 self.__updateObjFromInput()
771 771 self.__getFft()
772 772
773 773 self.dataOut.flagNoData = False
774 774
775 775 self.buffer = None
776 776 self.firstdatatime = None
777 777 self.profIndex = 0
778 778
779 779 return
780 780
781 781 raise ValuError, "The type object %s is not valid"%(self.dataIn.type)
782 782
783 783 def selectChannels(self, channelList):
784 784
785 785 channelIndexList = []
786 786
787 787 for channel in channelList:
788 788 index = self.dataOut.channelList.index(channel)
789 789 channelIndexList.append(index)
790 790
791 791 self.selectChannelsByIndex(channelIndexList)
792 792
793 793 def selectChannelsByIndex(self, channelIndexList):
794 794 """
795 795 Selecciona un bloque de datos en base a canales segun el channelIndexList
796 796
797 797 Input:
798 798 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
799 799
800 800 Affected:
801 801 self.dataOut.data_spc
802 802 self.dataOut.channelIndexList
803 803 self.dataOut.nChannels
804 804
805 805 Return:
806 806 None
807 807 """
808 808
809 809 for channelIndex in channelIndexList:
810 810 if channelIndex not in self.dataOut.channelIndexList:
811 811 print channelIndexList
812 812 raise ValueError, "The value %d in channelIndexList is not valid" %channelIndex
813 813
814 814 nChannels = len(channelIndexList)
815 815
816 816 data_spc = self.dataOut.data_spc[channelIndexList,:]
817 817
818 818 self.dataOut.data_spc = data_spc
819 819 self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
820 820 # self.dataOut.nChannels = nChannels
821 821
822 822 return 1
823 823
824 824
825 825 class IncohInt(Operation):
826 826
827 827
828 828 __profIndex = 0
829 829 __withOverapping = False
830 830
831 831 __byTime = False
832 832 __initime = None
833 833 __lastdatatime = None
834 834 __integrationtime = None
835 835
836 836 __buffer_spc = None
837 837 __buffer_cspc = None
838 838 __buffer_dc = None
839 839
840 840 __dataReady = False
841 841
842 842 n = None
843 843
844 844
845 845 def __init__(self):
846 846
847 847 self.__isConfig = False
848 848
849 849 def setup(self, n=None, timeInterval=None, overlapping=False):
850 850 """
851 851 Set the parameters of the integration class.
852 852
853 853 Inputs:
854 854
855 855 n : Number of coherent integrations
856 856 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
857 857 overlapping :
858 858
859 859 """
860 860
861 861 self.__initime = None
862 862 self.__lastdatatime = 0
863 863 self.__buffer_spc = None
864 864 self.__buffer_cspc = None
865 865 self.__buffer_dc = None
866 866 self.__dataReady = False
867 867
868 868
869 869 if n == None and timeInterval == None:
870 870 raise ValueError, "n or timeInterval should be specified ..."
871 871
872 872 if n != None:
873 873 self.n = n
874 874 self.__byTime = False
875 875 else:
876 876 self.__integrationtime = timeInterval * 60. #if (type(timeInterval)!=integer) -> change this line
877 877 self.n = 9999
878 878 self.__byTime = True
879 879
880 880 if overlapping:
881 881 self.__withOverapping = True
882 882 else:
883 883 self.__withOverapping = False
884 884 self.__buffer_spc = 0
885 885 self.__buffer_cspc = 0
886 886 self.__buffer_dc = 0
887 887
888 888 self.__profIndex = 0
889 889
890 890 def putData(self, data_spc, data_cspc, data_dc):
891 891
892 892 """
893 893 Add a profile to the __buffer_spc and increase in one the __profileIndex
894 894
895 895 """
896 896
897 897 if not self.__withOverapping:
898 898 self.__buffer_spc += data_spc
899 899
900 900 if data_cspc == None:
901 901 self.__buffer_cspc = None
902 902 else:
903 903 self.__buffer_cspc += data_cspc
904 904
905 905 if data_dc == None:
906 906 self.__buffer_dc = None
907 907 else:
908 908 self.__buffer_dc += data_dc
909 909
910 910 self.__profIndex += 1
911 911 return
912 912
913 913 #Overlapping data
914 914 nChannels, nFFTPoints, nHeis = data_spc.shape
915 915 data_spc = numpy.reshape(data_spc, (1, nChannels, nFFTPoints, nHeis))
916 916 if data_cspc != None:
917 917 data_cspc = numpy.reshape(data_cspc, (1, -1, nFFTPoints, nHeis))
918 918 if data_dc != None:
919 919 data_dc = numpy.reshape(data_dc, (1, -1, nHeis))
920 920
921 921 #If the buffer is empty then it takes the data value
922 922 if self.__buffer_spc == None:
923 923 self.__buffer_spc = data_spc
924 924
925 925 if data_cspc == None:
926 926 self.__buffer_cspc = None
927 927 else:
928 928 self.__buffer_cspc += data_cspc
929 929
930 930 if data_dc == None:
931 931 self.__buffer_dc = None
932 932 else:
933 933 self.__buffer_dc += data_dc
934 934
935 935 self.__profIndex += 1
936 936 return
937 937
938 938 #If the buffer length is lower than n then stakcing the data value
939 939 if self.__profIndex < self.n:
940 940 self.__buffer_spc = numpy.vstack((self.__buffer_spc, data_spc))
941 941
942 942 if data_cspc != None:
943 943 self.__buffer_cspc = numpy.vstack((self.__buffer_cspc, data_cspc))
944 944
945 945 if data_dc != None:
946 946 self.__buffer_dc = numpy.vstack((self.__buffer_dc, data_dc))
947 947
948 948 self.__profIndex += 1
949 949 return
950 950
951 951 #If the buffer length is equal to n then replacing the last buffer value with the data value
952 952 self.__buffer_spc = numpy.roll(self.__buffer_spc, -1, axis=0)
953 953 self.__buffer_spc[self.n-1] = data_spc
954 954
955 955 if data_cspc != None:
956 956 self.__buffer_cspc = numpy.roll(self.__buffer_cspc, -1, axis=0)
957 957 self.__buffer_cspc[self.n-1] = data_cspc
958 958
959 959 if data_dc != None:
960 960 self.__buffer_dc = numpy.roll(self.__buffer_dc, -1, axis=0)
961 961 self.__buffer_dc[self.n-1] = data_dc
962 962
963 963 self.__profIndex = self.n
964 964 return
965 965
966 966
967 967 def pushData(self):
968 968 """
969 969 Return the sum of the last profiles and the profiles used in the sum.
970 970
971 971 Affected:
972 972
973 973 self.__profileIndex
974 974
975 975 """
976 976 data_spc = None
977 977 data_cspc = None
978 978 data_dc = None
979 979
980 980 if not self.__withOverapping:
981 981 data_spc = self.__buffer_spc
982 982 data_cspc = self.__buffer_cspc
983 983 data_dc = self.__buffer_dc
984 984
985 985 n = self.__profIndex
986 986
987 987 self.__buffer_spc = 0
988 988 self.__buffer_cspc = 0
989 989 self.__buffer_dc = 0
990 990 self.__profIndex = 0
991 991
992 992 return data_spc, data_cspc, data_dc, n
993 993
994 994 #Integration with Overlapping
995 995 data_spc = numpy.sum(self.__buffer_spc, axis=0)
996 996
997 997 if self.__buffer_cspc != None:
998 998 data_cspc = numpy.sum(self.__buffer_cspc, axis=0)
999 999
1000 1000 if self.__buffer_dc != None:
1001 1001 data_dc = numpy.sum(self.__buffer_dc, axis=0)
1002 1002
1003 1003 n = self.__profIndex
1004 1004
1005 1005 return data_spc, data_cspc, data_dc, n
1006 1006
1007 1007 def byProfiles(self, *args):
1008 1008
1009 1009 self.__dataReady = False
1010 1010 avgdata_spc = None
1011 1011 avgdata_cspc = None
1012 1012 avgdata_dc = None
1013 1013 n = None
1014 1014
1015 1015 self.putData(*args)
1016 1016
1017 1017 if self.__profIndex == self.n:
1018 1018
1019 1019 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1020 1020 self.__dataReady = True
1021 1021
1022 1022 return avgdata_spc, avgdata_cspc, avgdata_dc
1023 1023
1024 1024 def byTime(self, datatime, *args):
1025 1025
1026 1026 self.__dataReady = False
1027 1027 avgdata_spc = None
1028 1028 avgdata_cspc = None
1029 1029 avgdata_dc = None
1030 1030 n = None
1031 1031
1032 1032 self.putData(*args)
1033 1033
1034 1034 if (datatime - self.__initime) >= self.__integrationtime:
1035 1035 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1036 1036 self.n = n
1037 1037 self.__dataReady = True
1038 1038
1039 1039 return avgdata_spc, avgdata_cspc, avgdata_dc
1040 1040
1041 1041 def integrate(self, datatime, *args):
1042 1042
1043 1043 if self.__initime == None:
1044 1044 self.__initime = datatime
1045 1045
1046 1046 if self.__byTime:
1047 1047 avgdata_spc, avgdata_cspc, avgdata_dc = self.byTime(datatime, *args)
1048 1048 else:
1049 1049 avgdata_spc, avgdata_cspc, avgdata_dc = self.byProfiles(*args)
1050 1050
1051 1051 self.__lastdatatime = datatime
1052 1052
1053 1053 if avgdata_spc == None:
1054 1054 return None, None, None, None
1055 1055
1056 1056 avgdatatime = self.__initime
1057 1057
1058 1058 deltatime = datatime -self.__lastdatatime
1059 1059
1060 1060 if not self.__withOverapping:
1061 1061 self.__initime = datatime
1062 1062 else:
1063 1063 self.__initime += deltatime
1064 1064
1065 1065 return avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc
1066 1066
1067 1067 def run(self, dataOut, n=None, timeInterval=None, overlapping=False):
1068 1068
1069 1069 if not self.__isConfig:
1070 1070 self.setup(n, timeInterval, overlapping)
1071 1071 self.__isConfig = True
1072 1072
1073 1073 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(dataOut.utctime,
1074 1074 dataOut.data_spc,
1075 1075 dataOut.data_cspc,
1076 1076 dataOut.data_dc)
1077 1077
1078 1078 # dataOut.timeInterval *= n
1079 1079 dataOut.flagNoData = True
1080 1080
1081 1081 if self.__dataReady:
1082 dataOut.data_spc = avgdata_spc
1083 dataOut.data_cspc = avgdata_cspc
1084 dataOut.data_dc = avgdata_dc
1082
1083 dataOut.data_spc = avgdata_spc / self.n
1084 dataOut.data_cspc = avgdata_cspc / self.n
1085 dataOut.data_dc = avgdata_dc / self.n
1085 1086
1086 1087 dataOut.nIncohInt *= self.n
1087 1088 dataOut.utctime = avgdatatime
1088 1089 dataOut.timeInterval = dataOut.ippSeconds * dataOut.nCohInt * dataOut.nIncohInt * dataOut.nFFTPoints
1089 1090 dataOut.flagNoData = False
1090 1091
1091 1092 class ProfileSelector(Operation):
1092 1093
1093 1094 profileIndex = None
1094 1095 # Tamanho total de los perfiles
1095 1096 nProfiles = None
1096 1097
1097 1098 def __init__(self):
1098 1099
1099 1100 self.profileIndex = 0
1100 1101
1101 1102 def incIndex(self):
1102 1103 self.profileIndex += 1
1103 1104
1104 1105 if self.profileIndex >= self.nProfiles:
1105 1106 self.profileIndex = 0
1106 1107
1107 1108 def isProfileInRange(self, minIndex, maxIndex):
1108 1109
1109 1110 if self.profileIndex < minIndex:
1110 1111 return False
1111 1112
1112 1113 if self.profileIndex > maxIndex:
1113 1114 return False
1114 1115
1115 1116 return True
1116 1117
1117 1118 def isProfileInList(self, profileList):
1118 1119
1119 1120 if self.profileIndex not in profileList:
1120 1121 return False
1121 1122
1122 1123 return True
1123 1124
1124 1125 def run(self, dataOut, profileList=None, profileRangeList=None):
1125 1126
1127 dataOut.flagNoData = True
1126 1128 self.nProfiles = dataOut.nProfiles
1127 1129
1128 1130 if profileList != None:
1129 if not(self.isProfileInList(profileList)):
1130 dataOut.flagNoData = True
1131 else:
1131 if self.isProfileInList(profileList):
1132 1132 dataOut.flagNoData = False
1133
1133 1134 self.incIndex()
1134 1135 return 1
1135 1136
1136 1137
1137 1138 elif profileRangeList != None:
1138 1139 minIndex = profileRangeList[0]
1139 1140 maxIndex = profileRangeList[1]
1140 if not(self.isProfileInRange(minIndex, maxIndex)):
1141 dataOut.flagNoData = True
1142 else:
1141 if self.isProfileInRange(minIndex, maxIndex):
1143 1142 dataOut.flagNoData = False
1143
1144 1144 self.incIndex()
1145 1145 return 1
1146
1146 1147 else:
1147 1148 raise ValueError, "ProfileSelector needs profileList or profileRangeList"
1148 1149
1149 1150 return 0
1150 1151
General Comments 0
You need to be logged in to leave comments. Login now