##// END OF EJS Templates
Modificaciones para operacion en tiempo real: lectura de archivos, titulo de graficos, timeinterval
Daniel Valdez -
r389:bb39554baf19
parent child
Show More
@@ -1,3317 +1,3372
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 from xml.etree.ElementTree import Element, SubElement, ElementTree
14 14 try:
15 15 import pyfits
16 16 except:
17 17 print "pyfits module has not been imported, it should be installed to save files in fits format"
18 18
19 19 from jrodata import *
20 20 from jroheaderIO import *
21 21 from jroprocessing import *
22 22
23 23 LOCALTIME = True #-18000
24 24
25 25 def isNumber(str):
26 26 """
27 27 Chequea si el conjunto de caracteres que componen un string puede ser convertidos a un numero.
28 28
29 29 Excepciones:
30 30 Si un determinado string no puede ser convertido a numero
31 31 Input:
32 32 str, string al cual se le analiza para determinar si convertible a un numero o no
33 33
34 34 Return:
35 35 True : si el string es uno numerico
36 36 False : no es un string numerico
37 37 """
38 38 try:
39 39 float( str )
40 40 return True
41 41 except:
42 42 return False
43 43
44 44 def isThisFileinRange(filename, startUTSeconds, endUTSeconds):
45 45 """
46 46 Esta funcion determina si un archivo de datos se encuentra o no dentro del rango de fecha especificado.
47 47
48 48 Inputs:
49 49 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
50 50
51 51 startUTSeconds : fecha inicial del rango seleccionado. La fecha esta dada en
52 52 segundos contados desde 01/01/1970.
53 53 endUTSeconds : fecha final del rango seleccionado. La fecha esta dada en
54 54 segundos contados desde 01/01/1970.
55 55
56 56 Return:
57 57 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
58 58 fecha especificado, de lo contrario retorna False.
59 59
60 60 Excepciones:
61 61 Si el archivo no existe o no puede ser abierto
62 62 Si la cabecera no puede ser leida.
63 63
64 64 """
65 65 basicHeaderObj = BasicHeader(LOCALTIME)
66 66
67 67 try:
68 68 fp = open(filename,'rb')
69 69 except:
70 70 raise IOError, "The file %s can't be opened" %(filename)
71 71
72 72 sts = basicHeaderObj.read(fp)
73 73 fp.close()
74 74
75 75 if not(sts):
76 76 print "Skipping the file %s because it has not a valid header" %(filename)
77 77 return 0
78 78
79 79 if not ((startUTSeconds <= basicHeaderObj.utc) and (endUTSeconds > basicHeaderObj.utc)):
80 80 return 0
81 81
82 82 return 1
83 83
84 84 def isFileinThisTime(filename, startTime, endTime):
85 85 """
86 86 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
87 87
88 88 Inputs:
89 89 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
90 90
91 91 startTime : tiempo inicial del rango seleccionado en formato datetime.time
92 92
93 93 endTime : tiempo final del rango seleccionado en formato datetime.time
94 94
95 95 Return:
96 96 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
97 97 fecha especificado, de lo contrario retorna False.
98 98
99 99 Excepciones:
100 100 Si el archivo no existe o no puede ser abierto
101 101 Si la cabecera no puede ser leida.
102 102
103 103 """
104 104
105 105
106 106 try:
107 107 fp = open(filename,'rb')
108 108 except:
109 109 raise IOError, "The file %s can't be opened" %(filename)
110 110
111 111 basicHeaderObj = BasicHeader(LOCALTIME)
112 112 sts = basicHeaderObj.read(fp)
113 113 fp.close()
114 114
115 115 thisDatetime = basicHeaderObj.datatime
116 116 thisTime = basicHeaderObj.datatime.time()
117 117
118 118 if not(sts):
119 119 print "Skipping the file %s because it has not a valid header" %(filename)
120 120 return None
121 121
122 122 if not ((startTime <= thisTime) and (endTime > thisTime)):
123 123 return None
124 124
125 125 return thisDatetime
126 126
127 def getFileFromSet(path,ext,set):
128 validFilelist = []
129 fileList = os.listdir(path)
130
131 # 0 1234 567 89A BCDE
132 # H YYYY DDD SSS .ext
133
134 for file in fileList:
135 try:
136 year = int(file[1:5])
137 doy = int(file[5:8])
138
139
140 except:
141 continue
142
143 if (os.path.splitext(file)[-1].lower() != ext.lower()):
144 continue
145
146 validFilelist.append(file)
147
148 myfile = fnmatch.filter(validFilelist,'*%4.4d%3.3d%3.3d*'%(year,doy,set))
149
150 if len(myfile)!= 0:
151 return myfile[0]
152 else:
153 filename = '*%4.4d%3.3d%3.3d%s'%(year,doy,set,ext.lower())
154 print 'the filename %s does not exist'%filename
155 print '...going to the last file: '
156
157 if validFilelist:
158 validFilelist = sorted( validFilelist, key=str.lower )
159 return validFilelist[-1]
160
161 return None
162
163
127 164 def getlastFileFromPath(path, ext):
128 165 """
129 166 Depura el fileList dejando solo los que cumplan el formato de "PYYYYDDDSSS.ext"
130 167 al final de la depuracion devuelve el ultimo file de la lista que quedo.
131 168
132 169 Input:
133 170 fileList : lista conteniendo todos los files (sin path) que componen una determinada carpeta
134 171 ext : extension de los files contenidos en una carpeta
135 172
136 173 Return:
137 174 El ultimo file de una determinada carpeta, no se considera el path.
138 175 """
139 176 validFilelist = []
140 177 fileList = os.listdir(path)
141 178
142 179 # 0 1234 567 89A BCDE
143 180 # H YYYY DDD SSS .ext
144 181
145 182 for file in fileList:
146 183 try:
147 184 year = int(file[1:5])
148 185 doy = int(file[5:8])
149 186
150 187
151 188 except:
152 189 continue
153 190
154 191 if (os.path.splitext(file)[-1].lower() != ext.lower()):
155 192 continue
156 193
157 194 validFilelist.append(file)
158 195
159 196 if validFilelist:
160 197 validFilelist = sorted( validFilelist, key=str.lower )
161 198 return validFilelist[-1]
162 199
163 200 return None
164 201
165 202 def checkForRealPath(path, foldercounter, year, doy, set, ext):
166 203 """
167 204 Por ser Linux Case Sensitive entonces checkForRealPath encuentra el nombre correcto de un path,
168 205 Prueba por varias combinaciones de nombres entre mayusculas y minusculas para determinar
169 206 el path exacto de un determinado file.
170 207
171 208 Example :
172 209 nombre correcto del file es .../.../D2009307/P2009307367.ext
173 210
174 211 Entonces la funcion prueba con las siguientes combinaciones
175 212 .../.../y2009307367.ext
176 213 .../.../Y2009307367.ext
177 214 .../.../x2009307/y2009307367.ext
178 215 .../.../x2009307/Y2009307367.ext
179 216 .../.../X2009307/y2009307367.ext
180 217 .../.../X2009307/Y2009307367.ext
181 218 siendo para este caso, la ultima combinacion de letras, identica al file buscado
182 219
183 220 Return:
184 221 Si encuentra la cobinacion adecuada devuelve el path completo y el nombre del file
185 222 caso contrario devuelve None como path y el la ultima combinacion de nombre en mayusculas
186 223 para el filename
187 224 """
188 225 fullfilename = None
189 226 find_flag = False
190 227 filename = None
191 228
192 229 prefixDirList = [None,'d','D']
193 230 if ext.lower() == ".r": #voltage
194 231 prefixFileList = ['d','D']
195 232 elif ext.lower() == ".pdata": #spectra
196 233 prefixFileList = ['p','P']
197 234 else:
198 235 return None, filename
199 236
200 237 #barrido por las combinaciones posibles
201 238 for prefixDir in prefixDirList:
202 239 thispath = path
203 240 if prefixDir != None:
204 241 #formo el nombre del directorio xYYYYDDD (x=d o x=D)
205 242 if foldercounter == 0:
206 243 thispath = os.path.join(path, "%s%04d%03d" % ( prefixDir, year, doy ))
207 244 else:
208 245 thispath = os.path.join(path, "%s%04d%03d_%02d" % ( prefixDir, year, doy , foldercounter))
209 246 for prefixFile in prefixFileList: #barrido por las dos combinaciones posibles de "D"
210 247 filename = "%s%04d%03d%03d%s" % ( prefixFile, year, doy, set, ext ) #formo el nombre del file xYYYYDDDSSS.ext
211 248 fullfilename = os.path.join( thispath, filename ) #formo el path completo
212 249
213 250 if os.path.exists( fullfilename ): #verifico que exista
214 251 find_flag = True
215 252 break
216 253 if find_flag:
217 254 break
218 255
219 256 if not(find_flag):
220 257 return None, filename
221 258
222 259 return fullfilename, filename
223 260
224 261 def isDoyFolder(folder):
225 262 try:
226 263 year = int(folder[1:5])
227 264 except:
228 265 return 0
229 266
230 267 try:
231 268 doy = int(folder[5:8])
232 269 except:
233 270 return 0
234 271
235 272 return 1
236 273
237 274 class JRODataIO:
238 275
239 276 c = 3E8
240 277
241 278 isConfig = False
242 279
243 280 basicHeaderObj = BasicHeader(LOCALTIME)
244 281
245 282 systemHeaderObj = SystemHeader()
246 283
247 284 radarControllerHeaderObj = RadarControllerHeader()
248 285
249 286 processingHeaderObj = ProcessingHeader()
250 287
251 288 online = 0
252 289
253 290 dtype = None
254 291
255 292 pathList = []
256 293
257 294 filenameList = []
258 295
259 296 filename = None
260 297
261 298 ext = None
262 299
263 300 flagIsNewFile = 1
264 301
265 302 flagTimeBlock = 0
266 303
267 304 flagIsNewBlock = 0
268 305
269 306 fp = None
270 307
271 308 firstHeaderSize = 0
272 309
273 310 basicHeaderSize = 24
274 311
275 312 versionFile = 1103
276 313
277 314 fileSize = None
278 315
279 316 ippSeconds = None
280 317
281 318 fileSizeByHeader = None
282 319
283 320 fileIndex = None
284 321
285 322 profileIndex = None
286 323
287 324 blockIndex = None
288 325
289 326 nTotalBlocks = None
290 327
291 328 maxTimeStep = 30
292 329
293 330 lastUTTime = None
294 331
295 332 datablock = None
296 333
297 334 dataOut = None
298 335
299 336 blocksize = None
300 337
301 338 def __init__(self):
302 339
303 340 raise ValueError, "Not implemented"
304 341
305 342 def run(self):
306 343
307 344 raise ValueError, "Not implemented"
308 345
309 346 def getOutput(self):
310 347
311 348 return self.dataOut
312 349
313 350 class JRODataReader(JRODataIO, ProcessingUnit):
314 351
315 352 nReadBlocks = 0
316 353
317 354 delay = 10 #number of seconds waiting a new file
318 355
319 356 nTries = 3 #quantity tries
320 357
321 358 nFiles = 3 #number of files for searching
322 359
323 360 path = None
324 361
325 362 foldercounter = 0
326 363
327 364 flagNoMoreFiles = 0
328 365
329 366 datetimeList = []
330 367
331 368 __isFirstTimeOnline = 1
332 369
333 370 __printInfo = True
334 371
335 372 profileIndex = None
336 373
337 374 def __init__(self):
338 375
339 376 """
340 377
341 378 """
342 379
343 380 raise ValueError, "This method has not been implemented"
344 381
345 382
346 383 def createObjByDefault(self):
347 384 """
348 385
349 386 """
350 387 raise ValueError, "This method has not been implemented"
351 388
352 389 def getBlockDimension(self):
353 390
354 391 raise ValueError, "No implemented"
355 392
356 393 def __searchFilesOffLine(self,
357 394 path,
358 395 startDate,
359 396 endDate,
360 397 startTime=datetime.time(0,0,0),
361 398 endTime=datetime.time(23,59,59),
362 399 set=None,
363 400 expLabel='',
364 401 ext='.r',
365 402 walk=True):
366 403
367 404 pathList = []
368 405
369 406 if not walk:
370 407 pathList.append(path)
371 408
372 409 else:
373 410 dirList = []
374 411 for thisPath in os.listdir(path):
375 412 if not os.path.isdir(os.path.join(path,thisPath)):
376 413 continue
377 414 if not isDoyFolder(thisPath):
378 415 continue
379 416
380 417 dirList.append(thisPath)
381 418
382 419 if not(dirList):
383 420 return None, None
384 421
385 422 thisDate = startDate
386 423
387 424 while(thisDate <= endDate):
388 425 year = thisDate.timetuple().tm_year
389 426 doy = thisDate.timetuple().tm_yday
390 427
391 428 matchlist = fnmatch.filter(dirList, '?' + '%4.4d%3.3d' % (year,doy) + '*')
392 429 if len(matchlist) == 0:
393 430 thisDate += datetime.timedelta(1)
394 431 continue
395 432 for match in matchlist:
396 433 pathList.append(os.path.join(path,match,expLabel))
397 434
398 435 thisDate += datetime.timedelta(1)
399 436
400 437 if pathList == []:
401 438 print "Any folder was found for the date range: %s-%s" %(startDate, endDate)
402 439 return None, None
403 440
404 441 print "%d folder(s) was(were) found for the date range: %s - %s" %(len(pathList), startDate, endDate)
405 442
406 443 filenameList = []
407 444 datetimeList = []
408 445
409 446 for i in range(len(pathList)):
410 447
411 448 thisPath = pathList[i]
412 449
413 450 fileList = glob.glob1(thisPath, "*%s" %ext)
414 451 fileList.sort()
415 452
416 453 for file in fileList:
417 454
418 455 filename = os.path.join(thisPath,file)
419 456 thisDatetime = isFileinThisTime(filename, startTime, endTime)
420 457
421 458 if not(thisDatetime):
422 459 continue
423 460
424 461 filenameList.append(filename)
425 462 datetimeList.append(thisDatetime)
426 463
427 464 if not(filenameList):
428 465 print "Any file was found for the time range %s - %s" %(startTime, endTime)
429 466 return None, None
430 467
431 468 print "%d file(s) was(were) found for the time range: %s - %s" %(len(filenameList), startTime, endTime)
432 469 print
433 470
434 471 for i in range(len(filenameList)):
435 472 print "%s -> [%s]" %(filenameList[i], datetimeList[i].ctime())
436 473
437 474 self.filenameList = filenameList
438 475 self.datetimeList = datetimeList
439 476
440 477 return pathList, filenameList
441 478
442 def __searchFilesOnLine(self, path, expLabel = "", ext = None, walk=True):
479 def __searchFilesOnLine(self, path, expLabel = "", ext = None, walk=True, set=None):
443 480
444 481 """
445 482 Busca el ultimo archivo de la ultima carpeta (determinada o no por startDateTime) y
446 483 devuelve el archivo encontrado ademas de otros datos.
447 484
448 485 Input:
449 486 path : carpeta donde estan contenidos los files que contiene data
450 487
451 488 expLabel : Nombre del subexperimento (subfolder)
452 489
453 490 ext : extension de los files
454 491
455 492 walk : Si es habilitado no realiza busquedas dentro de los ubdirectorios (doypath)
456 493
457 494 Return:
458 495 directory : eL directorio donde esta el file encontrado
459 496 filename : el ultimo file de una determinada carpeta
460 497 year : el anho
461 498 doy : el numero de dia del anho
462 499 set : el set del archivo
463 500
464 501
465 502 """
466 503 dirList = []
467 504
468 505 if not walk:
469 506 fullpath = path
470 foldercounter = ''
507 foldercounter = 0
471 508 else:
472 509 #Filtra solo los directorios
473 510 for thisPath in os.listdir(path):
474 511 if not os.path.isdir(os.path.join(path,thisPath)):
475 512 continue
476 513 if not isDoyFolder(thisPath):
477 514 continue
478 515
479 516 dirList.append(thisPath)
480 517
481 518 if not(dirList):
482 519 return None, None, None, None, None, None
483 520
484 521 dirList = sorted( dirList, key=str.lower )
485 522
486 523 doypath = dirList[-1]
487 524 foldercounter = int(doypath.split('_')[1]) if len(doypath.split('_'))>1 else 0
488 525 fullpath = os.path.join(path, doypath, expLabel)
489 526
490 527
491 528 print "%s folder was found: " %(fullpath )
492 529
493 filename = getlastFileFromPath(fullpath, ext)
530 if set == None:
531 filename = getlastFileFromPath(fullpath, ext)
532 else:
533 filename = getFileFromSet(fullpath, ext, set)
494 534
495 535 if not(filename):
496 return None, None, None, None, None
536 return None, None, None, None, None, None
497 537
498 538 print "%s file was found" %(filename)
499 539
500 540 if not(self.__verifyFile(os.path.join(fullpath, filename))):
501 return None, None, None, None, None
541 return None, None, None, None, None, None
502 542
503 543 year = int( filename[1:5] )
504 544 doy = int( filename[5:8] )
505 545 set = int( filename[8:11] )
506 546
507 547 return fullpath, foldercounter, filename, year, doy, set
508 548
509 549 def __setNextFileOffline(self):
510 550
511 551 idFile = self.fileIndex
512 552
513 553 while (True):
514 554 idFile += 1
515 555 if not(idFile < len(self.filenameList)):
516 556 self.flagNoMoreFiles = 1
517 557 print "No more Files"
518 558 return 0
519 559
520 560 filename = self.filenameList[idFile]
521 561
522 562 if not(self.__verifyFile(filename)):
523 563 continue
524 564
525 565 fileSize = os.path.getsize(filename)
526 566 fp = open(filename,'rb')
527 567 break
528 568
529 569 self.flagIsNewFile = 1
530 570 self.fileIndex = idFile
531 571 self.filename = filename
532 572 self.fileSize = fileSize
533 573 self.fp = fp
534 574
535 575 print "Setting the file: %s"%self.filename
536 576
537 577 return 1
538 578
539 579 def __setNextFileOnline(self):
540 580 """
541 581 Busca el siguiente file que tenga suficiente data para ser leida, dentro de un folder especifico, si
542 582 no encuentra un file valido espera un tiempo determinado y luego busca en los posibles n files
543 583 siguientes.
544 584
545 585 Affected:
546 586 self.flagIsNewFile
547 587 self.filename
548 588 self.fileSize
549 589 self.fp
550 590 self.set
551 591 self.flagNoMoreFiles
552 592
553 593 Return:
554 594 0 : si luego de una busqueda del siguiente file valido este no pudo ser encontrado
555 595 1 : si el file fue abierto con exito y esta listo a ser leido
556 596
557 597 Excepciones:
558 598 Si un determinado file no puede ser abierto
559 599 """
560 600 nFiles = 0
561 601 fileOk_flag = False
562 602 firstTime_flag = True
563 603
564 604 self.set += 1
565 605
566 606 if self.set > 999:
567 607 self.set = 0
568 608 self.foldercounter += 1
569 609
570 610 #busca el 1er file disponible
571 611 fullfilename, filename = checkForRealPath( self.path, self.foldercounter, self.year, self.doy, self.set, self.ext )
572 612 if fullfilename:
573 613 if self.__verifyFile(fullfilename, False):
574 614 fileOk_flag = True
575 615
576 616 #si no encuentra un file entonces espera y vuelve a buscar
577 617 if not(fileOk_flag):
578 618 for nFiles in range(self.nFiles+1): #busco en los siguientes self.nFiles+1 files posibles
579 619
580 620 if firstTime_flag: #si es la 1era vez entonces hace el for self.nTries veces
581 621 tries = self.nTries
582 622 else:
583 623 tries = 1 #si no es la 1era vez entonces solo lo hace una vez
584 624
585 625 for nTries in range( tries ):
586 626 if firstTime_flag:
587 627 print "\tWaiting %0.2f sec for the file \"%s\" , try %03d ..." % ( self.delay, filename, nTries+1 )
588 628 time.sleep( self.delay )
589 629 else:
590 630 print "\tSearching next \"%s%04d%03d%03d%s\" file ..." % (self.optchar, self.year, self.doy, self.set, self.ext)
591 631
592 632 fullfilename, filename = checkForRealPath( self.path, self.foldercounter, self.year, self.doy, self.set, self.ext )
593 633 if fullfilename:
594 634 if self.__verifyFile(fullfilename):
595 635 fileOk_flag = True
596 636 break
597 637
598 638 if fileOk_flag:
599 639 break
600 640
601 641 firstTime_flag = False
602 642
603 643 print "\tSkipping the file \"%s\" due to this file doesn't exist" % filename
604 644 self.set += 1
605 645
606 646 if nFiles == (self.nFiles-1): #si no encuentro el file buscado cambio de carpeta y busco en la siguiente carpeta
607 647 self.set = 0
608 648 self.doy += 1
609 649 self.foldercounter = 0
610 650
611 651 if fileOk_flag:
612 652 self.fileSize = os.path.getsize( fullfilename )
613 653 self.filename = fullfilename
614 654 self.flagIsNewFile = 1
615 655 if self.fp != None: self.fp.close()
616 656 self.fp = open(fullfilename, 'rb')
617 657 self.flagNoMoreFiles = 0
618 658 print 'Setting the file: %s' % fullfilename
619 659 else:
620 660 self.fileSize = 0
621 661 self.filename = None
622 662 self.flagIsNewFile = 0
623 663 self.fp = None
624 664 self.flagNoMoreFiles = 1
625 665 print 'No more Files'
626 666
627 667 return fileOk_flag
628 668
629 669
630 670 def setNextFile(self):
631 671 if self.fp != None:
632 672 self.fp.close()
633 673
634 674 if self.online:
635 675 newFile = self.__setNextFileOnline()
636 676 else:
637 677 newFile = self.__setNextFileOffline()
638 678
639 679 if not(newFile):
640 680 return 0
641 681
642 682 self.__readFirstHeader()
643 683 self.nReadBlocks = 0
644 684 return 1
645 685
646 686 def __waitNewBlock(self):
647 687 """
648 688 Return 1 si se encontro un nuevo bloque de datos, 0 de otra forma.
649 689
650 690 Si el modo de lectura es OffLine siempre retorn 0
651 691 """
652 692 if not self.online:
653 693 return 0
654 694
655 695 if (self.nReadBlocks >= self.processingHeaderObj.dataBlocksPerFile):
656 696 return 0
657 697
658 698 currentPointer = self.fp.tell()
659 699
660 700 neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize
661 701
662 702 for nTries in range( self.nTries ):
663 703
664 704 self.fp.close()
665 705 self.fp = open( self.filename, 'rb' )
666 706 self.fp.seek( currentPointer )
667 707
668 708 self.fileSize = os.path.getsize( self.filename )
669 709 currentSize = self.fileSize - currentPointer
670 710
671 711 if ( currentSize >= neededSize ):
672 712 self.__rdBasicHeader()
673 713 return 1
674 714
715 if self.fileSize == self.fileSizeByHeader:
716 # self.flagEoF = True
717 return 0
718
675 719 print "\tWaiting %0.2f seconds for the next block, try %03d ..." % (self.delay, nTries+1)
676 720 time.sleep( self.delay )
677 721
678 722
679 723 return 0
680 724
681 725 def __jumpToLastBlock(self):
682 726
683 727 if not(self.__isFirstTimeOnline):
684 728 return
685 729
686 730 csize = self.fileSize - self.fp.tell()
731 blocksize = self.processingHeaderObj.blockSize
687 732
688 #sata el primer bloque de datos
733 #salta el primer bloque de datos
689 734 if csize > self.processingHeaderObj.blockSize:
690 self.fp.seek(self.fp.tell() + self.processingHeaderObj.blockSize)
735 self.fp.seek(self.fp.tell() + blocksize)
691 736 else:
692 737 return
693 738
694 739 csize = self.fileSize - self.fp.tell()
695 740 neededsize = self.processingHeaderObj.blockSize + self.basicHeaderSize
696 factor = int(csize/neededsize)
697 if factor > 0:
698 self.fp.seek(self.fp.tell() + factor*neededsize)
741 while True:
742
743 if self.fp.tell()<self.fileSize:
744 self.fp.seek(self.fp.tell() + neededsize)
745 else:
746 self.fp.seek(self.fp.tell() - neededsize)
747 break
748
749 # csize = self.fileSize - self.fp.tell()
750 # neededsize = self.processingHeaderObj.blockSize + self.basicHeaderSize
751 # factor = int(csize/neededsize)
752 # if factor > 0:
753 # self.fp.seek(self.fp.tell() + factor*neededsize)
699 754
700 755 self.flagIsNewFile = 0
701 756 self.__isFirstTimeOnline = 0
702 757
703 758
704 759 def __setNewBlock(self):
705 760
706 761 if self.fp == None:
707 762 return 0
708 763
709 764 if self.online:
710 765 self.__jumpToLastBlock()
711 766
712 767 if self.flagIsNewFile:
713 768 return 1
714 769
715 770 self.lastUTTime = self.basicHeaderObj.utc
716 771 currentSize = self.fileSize - self.fp.tell()
717 772 neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize
718 773
719 774 if (currentSize >= neededSize):
720 775 self.__rdBasicHeader()
721 776 return 1
722 777
723 778 if self.__waitNewBlock():
724 779 return 1
725 780
726 781 if not(self.setNextFile()):
727 782 return 0
728 783
729 784 deltaTime = self.basicHeaderObj.utc - self.lastUTTime #
730 785
731 786 self.flagTimeBlock = 0
732 787
733 788 if deltaTime > self.maxTimeStep:
734 789 self.flagTimeBlock = 1
735 790
736 791 return 1
737 792
738 793
739 794 def readNextBlock(self):
740 795 if not(self.__setNewBlock()):
741 796 return 0
742 797
743 798 if not(self.readBlock()):
744 799 return 0
745 800
746 801 return 1
747 802
748 803 def __rdProcessingHeader(self, fp=None):
749 804 if fp == None:
750 805 fp = self.fp
751 806
752 807 self.processingHeaderObj.read(fp)
753 808
754 809 def __rdRadarControllerHeader(self, fp=None):
755 810 if fp == None:
756 811 fp = self.fp
757 812
758 813 self.radarControllerHeaderObj.read(fp)
759 814
760 815 def __rdSystemHeader(self, fp=None):
761 816 if fp == None:
762 817 fp = self.fp
763 818
764 819 self.systemHeaderObj.read(fp)
765 820
766 821 def __rdBasicHeader(self, fp=None):
767 822 if fp == None:
768 823 fp = self.fp
769 824
770 825 self.basicHeaderObj.read(fp)
771 826
772 827
773 828 def __readFirstHeader(self):
774 829 self.__rdBasicHeader()
775 830 self.__rdSystemHeader()
776 831 self.__rdRadarControllerHeader()
777 832 self.__rdProcessingHeader()
778 833
779 834 self.firstHeaderSize = self.basicHeaderObj.size
780 835
781 836 datatype = int(numpy.log2((self.processingHeaderObj.processFlags & PROCFLAG.DATATYPE_MASK))-numpy.log2(PROCFLAG.DATATYPE_CHAR))
782 837 if datatype == 0:
783 838 datatype_str = numpy.dtype([('real','<i1'),('imag','<i1')])
784 839 elif datatype == 1:
785 840 datatype_str = numpy.dtype([('real','<i2'),('imag','<i2')])
786 841 elif datatype == 2:
787 842 datatype_str = numpy.dtype([('real','<i4'),('imag','<i4')])
788 843 elif datatype == 3:
789 844 datatype_str = numpy.dtype([('real','<i8'),('imag','<i8')])
790 845 elif datatype == 4:
791 846 datatype_str = numpy.dtype([('real','<f4'),('imag','<f4')])
792 847 elif datatype == 5:
793 848 datatype_str = numpy.dtype([('real','<f8'),('imag','<f8')])
794 849 else:
795 850 raise ValueError, 'Data type was not defined'
796 851
797 852 self.dtype = datatype_str
798 853 self.ippSeconds = 2 * 1000 * self.radarControllerHeaderObj.ipp / self.c
799 854 self.fileSizeByHeader = self.processingHeaderObj.dataBlocksPerFile * self.processingHeaderObj.blockSize + self.firstHeaderSize + self.basicHeaderSize*(self.processingHeaderObj.dataBlocksPerFile - 1)
800 855 # self.dataOut.channelList = numpy.arange(self.systemHeaderObj.numChannels)
801 856 # self.dataOut.channelIndexList = numpy.arange(self.systemHeaderObj.numChannels)
802 857 self.getBlockDimension()
803 858
804 859
805 860 def __verifyFile(self, filename, msgFlag=True):
806 861 msg = None
807 862 try:
808 863 fp = open(filename, 'rb')
809 864 currentPosition = fp.tell()
810 865 except:
811 866 if msgFlag:
812 867 print "The file %s can't be opened" % (filename)
813 868 return False
814 869
815 870 neededSize = self.processingHeaderObj.blockSize + self.firstHeaderSize
816 871
817 872 if neededSize == 0:
818 873 basicHeaderObj = BasicHeader(LOCALTIME)
819 874 systemHeaderObj = SystemHeader()
820 875 radarControllerHeaderObj = RadarControllerHeader()
821 876 processingHeaderObj = ProcessingHeader()
822 877
823 878 try:
824 879 if not( basicHeaderObj.read(fp) ): raise IOError
825 880 if not( systemHeaderObj.read(fp) ): raise IOError
826 881 if not( radarControllerHeaderObj.read(fp) ): raise IOError
827 882 if not( processingHeaderObj.read(fp) ): raise IOError
828 883 data_type = int(numpy.log2((processingHeaderObj.processFlags & PROCFLAG.DATATYPE_MASK))-numpy.log2(PROCFLAG.DATATYPE_CHAR))
829 884
830 885 neededSize = processingHeaderObj.blockSize + basicHeaderObj.size
831 886
832 887 except:
833 888 if msgFlag:
834 889 print "\tThe file %s is empty or it hasn't enough data" % filename
835 890
836 891 fp.close()
837 892 return False
838 893 else:
839 894 msg = "\tSkipping the file %s due to it hasn't enough data" %filename
840 895
841 896 fp.close()
842 897 fileSize = os.path.getsize(filename)
843 898 currentSize = fileSize - currentPosition
844 899 if currentSize < neededSize:
845 900 if msgFlag and (msg != None):
846 901 print msg #print"\tSkipping the file %s due to it hasn't enough data" %filename
847 902 return False
848 903
849 904 return True
850 905
851 906 def setup(self,
852 907 path=None,
853 908 startDate=None,
854 909 endDate=None,
855 910 startTime=datetime.time(0,0,0),
856 911 endTime=datetime.time(23,59,59),
857 set=0,
912 set=None,
858 913 expLabel = "",
859 914 ext = None,
860 915 online = False,
861 916 delay = 60,
862 917 walk = True):
863 918
864 919 if path == None:
865 920 raise ValueError, "The path is not valid"
866 921
867 922 if ext == None:
868 923 ext = self.ext
869 924
870 925 if online:
871 926 print "Searching files in online mode..."
872 927
873 928 for nTries in range( self.nTries ):
874 fullpath, foldercounter, file, year, doy, set = self.__searchFilesOnLine(path=path, expLabel=expLabel, ext=ext, walk=walk)
929 fullpath, foldercounter, file, year, doy, set = self.__searchFilesOnLine(path=path, expLabel=expLabel, ext=ext, walk=walk, set=set)
875 930
876 931 if fullpath:
877 932 break
878 933
879 934 print '\tWaiting %0.2f sec for an valid file in %s: try %02d ...' % (self.delay, path, nTries+1)
880 935 time.sleep( self.delay )
881 936
882 937 if not(fullpath):
883 938 print "There 'isn't valied files in %s" % path
884 939 return None
885 940
886 941 self.year = year
887 942 self.doy = doy
888 943 self.set = set - 1
889 944 self.path = path
890 945 self.foldercounter = foldercounter
891 946
892 947 else:
893 948 print "Searching files in offline mode ..."
894 949 pathList, filenameList = self.__searchFilesOffLine(path, startDate=startDate, endDate=endDate,
895 950 startTime=startTime, endTime=endTime,
896 951 set=set, expLabel=expLabel, ext=ext,
897 952 walk=walk)
898 953
899 954 if not(pathList):
900 955 print "No *%s files into the folder %s \nfor the range: %s - %s"%(ext, path,
901 956 datetime.datetime.combine(startDate,startTime).ctime(),
902 957 datetime.datetime.combine(endDate,endTime).ctime())
903 958
904 959 sys.exit(-1)
905 960
906 961
907 962 self.fileIndex = -1
908 963 self.pathList = pathList
909 964 self.filenameList = filenameList
910 965
911 966 self.online = online
912 967 self.delay = delay
913 968 ext = ext.lower()
914 969 self.ext = ext
915 970
916 971 if not(self.setNextFile()):
917 972 if (startDate!=None) and (endDate!=None):
918 973 print "No files in range: %s - %s" %(datetime.datetime.combine(startDate,startTime).ctime(), datetime.datetime.combine(endDate,endTime).ctime())
919 974 elif startDate != None:
920 975 print "No files in range: %s" %(datetime.datetime.combine(startDate,startTime).ctime())
921 976 else:
922 977 print "No files"
923 978
924 979 sys.exit(-1)
925 980
926 981 # self.updateDataHeader()
927 982
928 983 return self.dataOut
929 984
930 985 def getBasicHeader(self):
931 986
932 987 self.dataOut.utctime = self.basicHeaderObj.utc + self.basicHeaderObj.miliSecond/1000. + self.profileIndex * self.ippSeconds
933 988
934 989 self.dataOut.flagTimeBlock = self.flagTimeBlock
935 990
936 991 self.dataOut.timeZone = self.basicHeaderObj.timeZone
937 992
938 993 self.dataOut.dstFlag = self.basicHeaderObj.dstFlag
939 994
940 995 self.dataOut.errorCount = self.basicHeaderObj.errorCount
941 996
942 997 self.dataOut.useLocalTime = self.basicHeaderObj.useLocalTime
943 998
944 999 def getFirstHeader(self):
945 1000
946 1001 raise ValueError, "This method has not been implemented"
947 1002
948 1003 def getData():
949 1004
950 1005 raise ValueError, "This method has not been implemented"
951 1006
952 1007 def hasNotDataInBuffer():
953 1008
954 1009 raise ValueError, "This method has not been implemented"
955 1010
956 1011 def readBlock():
957 1012
958 1013 raise ValueError, "This method has not been implemented"
959 1014
960 1015 def isEndProcess(self):
961 1016
962 1017 return self.flagNoMoreFiles
963 1018
964 1019 def printReadBlocks(self):
965 1020
966 1021 print "Number of read blocks per file %04d" %self.nReadBlocks
967 1022
968 1023 def printTotalBlocks(self):
969 1024
970 1025 print "Number of read blocks %04d" %self.nTotalBlocks
971 1026
972 1027 def printNumberOfBlock(self):
973 1028
974 1029 if self.flagIsNewBlock:
975 1030 print "Block No. %04d, Total blocks %04d -> %s" %(self.basicHeaderObj.dataBlock, self.nTotalBlocks, self.dataOut.datatime.ctime())
976 1031
977 1032 def printInfo(self):
978 1033
979 1034 if self.__printInfo == False:
980 1035 return
981 1036
982 1037 self.basicHeaderObj.printInfo()
983 1038 self.systemHeaderObj.printInfo()
984 1039 self.radarControllerHeaderObj.printInfo()
985 1040 self.processingHeaderObj.printInfo()
986 1041
987 1042 self.__printInfo = False
988 1043
989 1044
990 1045 def run(self, **kwargs):
991 1046
992 1047 if not(self.isConfig):
993 1048
994 1049 # self.dataOut = dataOut
995 1050 self.setup(**kwargs)
996 1051 self.isConfig = True
997 1052
998 1053 self.getData()
999 1054
1000 1055 class JRODataWriter(JRODataIO, Operation):
1001 1056
1002 1057 """
1003 1058 Esta clase permite escribir datos a archivos procesados (.r o ,pdata). La escritura
1004 1059 de los datos siempre se realiza por bloques.
1005 1060 """
1006 1061
1007 1062 blockIndex = 0
1008 1063
1009 1064 path = None
1010 1065
1011 1066 setFile = None
1012 1067
1013 1068 profilesPerBlock = None
1014 1069
1015 1070 blocksPerFile = None
1016 1071
1017 1072 nWriteBlocks = 0
1018 1073
1019 1074 def __init__(self, dataOut=None):
1020 1075 raise ValueError, "Not implemented"
1021 1076
1022 1077
1023 1078 def hasAllDataInBuffer(self):
1024 1079 raise ValueError, "Not implemented"
1025 1080
1026 1081
1027 1082 def setBlockDimension(self):
1028 1083 raise ValueError, "Not implemented"
1029 1084
1030 1085
1031 1086 def writeBlock(self):
1032 1087 raise ValueError, "No implemented"
1033 1088
1034 1089
1035 1090 def putData(self):
1036 1091 raise ValueError, "No implemented"
1037 1092
1038 1093
1039 1094 def setBasicHeader(self):
1040 1095
1041 1096 self.basicHeaderObj.size = self.basicHeaderSize #bytes
1042 1097 self.basicHeaderObj.version = self.versionFile
1043 1098 self.basicHeaderObj.dataBlock = self.nTotalBlocks
1044 1099
1045 1100 utc = numpy.floor(self.dataOut.utctime)
1046 1101 milisecond = (self.dataOut.utctime - utc)* 1000.0
1047 1102
1048 1103 self.basicHeaderObj.utc = utc
1049 1104 self.basicHeaderObj.miliSecond = milisecond
1050 1105 self.basicHeaderObj.timeZone = self.dataOut.timeZone
1051 1106 self.basicHeaderObj.dstFlag = self.dataOut.dstFlag
1052 1107 self.basicHeaderObj.errorCount = self.dataOut.errorCount
1053 1108
1054 1109 def setFirstHeader(self):
1055 1110 """
1056 1111 Obtiene una copia del First Header
1057 1112
1058 1113 Affected:
1059 1114
1060 1115 self.basicHeaderObj
1061 1116 self.systemHeaderObj
1062 1117 self.radarControllerHeaderObj
1063 1118 self.processingHeaderObj self.
1064 1119
1065 1120 Return:
1066 1121 None
1067 1122 """
1068 1123
1069 1124 raise ValueError, "No implemented"
1070 1125
1071 1126 def __writeFirstHeader(self):
1072 1127 """
1073 1128 Escribe el primer header del file es decir el Basic header y el Long header (SystemHeader, RadarControllerHeader, ProcessingHeader)
1074 1129
1075 1130 Affected:
1076 1131 __dataType
1077 1132
1078 1133 Return:
1079 1134 None
1080 1135 """
1081 1136
1082 1137 # CALCULAR PARAMETROS
1083 1138
1084 1139 sizeLongHeader = self.systemHeaderObj.size + self.radarControllerHeaderObj.size + self.processingHeaderObj.size
1085 1140 self.basicHeaderObj.size = self.basicHeaderSize + sizeLongHeader
1086 1141
1087 1142 self.basicHeaderObj.write(self.fp)
1088 1143 self.systemHeaderObj.write(self.fp)
1089 1144 self.radarControllerHeaderObj.write(self.fp)
1090 1145 self.processingHeaderObj.write(self.fp)
1091 1146
1092 1147 self.dtype = self.dataOut.dtype
1093 1148
1094 1149 def __setNewBlock(self):
1095 1150 """
1096 1151 Si es un nuevo file escribe el First Header caso contrario escribe solo el Basic Header
1097 1152
1098 1153 Return:
1099 1154 0 : si no pudo escribir nada
1100 1155 1 : Si escribio el Basic el First Header
1101 1156 """
1102 1157 if self.fp == None:
1103 1158 self.setNextFile()
1104 1159
1105 1160 if self.flagIsNewFile:
1106 1161 return 1
1107 1162
1108 1163 if self.blockIndex < self.processingHeaderObj.dataBlocksPerFile:
1109 1164 self.basicHeaderObj.write(self.fp)
1110 1165 return 1
1111 1166
1112 1167 if not( self.setNextFile() ):
1113 1168 return 0
1114 1169
1115 1170 return 1
1116 1171
1117 1172
1118 1173 def writeNextBlock(self):
1119 1174 """
1120 1175 Selecciona el bloque siguiente de datos y los escribe en un file
1121 1176
1122 1177 Return:
1123 1178 0 : Si no hizo pudo escribir el bloque de datos
1124 1179 1 : Si no pudo escribir el bloque de datos
1125 1180 """
1126 1181 if not( self.__setNewBlock() ):
1127 1182 return 0
1128 1183
1129 1184 self.writeBlock()
1130 1185
1131 1186 return 1
1132 1187
1133 1188 def setNextFile(self):
1134 1189 """
1135 1190 Determina el siguiente file que sera escrito
1136 1191
1137 1192 Affected:
1138 1193 self.filename
1139 1194 self.subfolder
1140 1195 self.fp
1141 1196 self.setFile
1142 1197 self.flagIsNewFile
1143 1198
1144 1199 Return:
1145 1200 0 : Si el archivo no puede ser escrito
1146 1201 1 : Si el archivo esta listo para ser escrito
1147 1202 """
1148 1203 ext = self.ext
1149 1204 path = self.path
1150 1205
1151 1206 if self.fp != None:
1152 1207 self.fp.close()
1153 1208
1154 1209 timeTuple = time.localtime( self.dataOut.utctime)
1155 1210 subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday)
1156 1211
1157 1212 fullpath = os.path.join( path, subfolder )
1158 1213 if not( os.path.exists(fullpath) ):
1159 1214 os.mkdir(fullpath)
1160 1215 self.setFile = -1 #inicializo mi contador de seteo
1161 1216 else:
1162 1217 filesList = os.listdir( fullpath )
1163 1218 if len( filesList ) > 0:
1164 1219 filesList = sorted( filesList, key=str.lower )
1165 1220 filen = filesList[-1]
1166 1221 # el filename debera tener el siguiente formato
1167 1222 # 0 1234 567 89A BCDE (hex)
1168 1223 # x YYYY DDD SSS .ext
1169 1224 if isNumber( filen[8:11] ):
1170 1225 self.setFile = int( filen[8:11] ) #inicializo mi contador de seteo al seteo del ultimo file
1171 1226 else:
1172 1227 self.setFile = -1
1173 1228 else:
1174 1229 self.setFile = -1 #inicializo mi contador de seteo
1175 1230
1176 1231 setFile = self.setFile
1177 1232 setFile += 1
1178 1233
1179 1234 file = '%s%4.4d%3.3d%3.3d%s' % (self.optchar,
1180 1235 timeTuple.tm_year,
1181 1236 timeTuple.tm_yday,
1182 1237 setFile,
1183 1238 ext )
1184 1239
1185 1240 filename = os.path.join( path, subfolder, file )
1186 1241
1187 1242 fp = open( filename,'wb' )
1188 1243
1189 1244 self.blockIndex = 0
1190 1245
1191 1246 #guardando atributos
1192 1247 self.filename = filename
1193 1248 self.subfolder = subfolder
1194 1249 self.fp = fp
1195 1250 self.setFile = setFile
1196 1251 self.flagIsNewFile = 1
1197 1252
1198 1253 self.setFirstHeader()
1199 1254
1200 1255 print 'Writing the file: %s'%self.filename
1201 1256
1202 1257 self.__writeFirstHeader()
1203 1258
1204 1259 return 1
1205 1260
1206 1261 def setup(self, dataOut, path, blocksPerFile, profilesPerBlock=None, set=0, ext=None):
1207 1262 """
1208 1263 Setea el tipo de formato en la cual sera guardada la data y escribe el First Header
1209 1264
1210 1265 Inputs:
1211 1266 path : el path destino en el cual se escribiran los files a crear
1212 1267 format : formato en el cual sera salvado un file
1213 1268 set : el setebo del file
1214 1269
1215 1270 Return:
1216 1271 0 : Si no realizo un buen seteo
1217 1272 1 : Si realizo un buen seteo
1218 1273 """
1219 1274
1220 1275 if ext == None:
1221 1276 ext = self.ext
1222 1277
1223 1278 ext = ext.lower()
1224 1279
1225 1280 self.ext = ext
1226 1281
1227 1282 self.path = path
1228 1283
1229 1284 self.setFile = set - 1
1230 1285
1231 1286 self.blocksPerFile = blocksPerFile
1232 1287
1233 1288 self.profilesPerBlock = profilesPerBlock
1234 1289
1235 1290 self.dataOut = dataOut
1236 1291
1237 1292 if not(self.setNextFile()):
1238 1293 print "There isn't a next file"
1239 1294 return 0
1240 1295
1241 1296 self.setBlockDimension()
1242 1297
1243 1298 return 1
1244 1299
1245 1300 def run(self, dataOut, **kwargs):
1246 1301
1247 1302 if not(self.isConfig):
1248 1303
1249 1304 self.setup(dataOut, **kwargs)
1250 1305 self.isConfig = True
1251 1306
1252 1307 self.putData()
1253 1308
1254 1309 class VoltageReader(JRODataReader):
1255 1310 """
1256 1311 Esta clase permite leer datos de voltage desde archivos en formato rawdata (.r). La lectura
1257 1312 de los datos siempre se realiza por bloques. Los datos leidos (array de 3 dimensiones:
1258 1313 perfiles*alturas*canales) son almacenados en la variable "buffer".
1259 1314
1260 1315 perfiles * alturas * canales
1261 1316
1262 1317 Esta clase contiene instancias (objetos) de las clases BasicHeader, SystemHeader,
1263 1318 RadarControllerHeader y Voltage. Los tres primeros se usan para almacenar informacion de la
1264 1319 cabecera de datos (metadata), y el cuarto (Voltage) para obtener y almacenar un perfil de
1265 1320 datos desde el "buffer" cada vez que se ejecute el metodo "getData".
1266 1321
1267 1322 Example:
1268 1323
1269 1324 dpath = "/home/myuser/data"
1270 1325
1271 1326 startTime = datetime.datetime(2010,1,20,0,0,0,0,0,0)
1272 1327
1273 1328 endTime = datetime.datetime(2010,1,21,23,59,59,0,0,0)
1274 1329
1275 1330 readerObj = VoltageReader()
1276 1331
1277 1332 readerObj.setup(dpath, startTime, endTime)
1278 1333
1279 1334 while(True):
1280 1335
1281 1336 #to get one profile
1282 1337 profile = readerObj.getData()
1283 1338
1284 1339 #print the profile
1285 1340 print profile
1286 1341
1287 1342 #If you want to see all datablock
1288 1343 print readerObj.datablock
1289 1344
1290 1345 if readerObj.flagNoMoreFiles:
1291 1346 break
1292 1347
1293 1348 """
1294 1349
1295 1350 ext = ".r"
1296 1351
1297 1352 optchar = "D"
1298 1353 dataOut = None
1299 1354
1300 1355
1301 1356 def __init__(self):
1302 1357 """
1303 1358 Inicializador de la clase VoltageReader para la lectura de datos de voltage.
1304 1359
1305 1360 Input:
1306 1361 dataOut : Objeto de la clase Voltage. Este objeto sera utilizado para
1307 1362 almacenar un perfil de datos cada vez que se haga un requerimiento
1308 1363 (getData). El perfil sera obtenido a partir del buffer de datos,
1309 1364 si el buffer esta vacio se hara un nuevo proceso de lectura de un
1310 1365 bloque de datos.
1311 1366 Si este parametro no es pasado se creara uno internamente.
1312 1367
1313 1368 Variables afectadas:
1314 1369 self.dataOut
1315 1370
1316 1371 Return:
1317 1372 None
1318 1373 """
1319 1374
1320 1375 self.isConfig = False
1321 1376
1322 1377 self.datablock = None
1323 1378
1324 1379 self.utc = 0
1325 1380
1326 1381 self.ext = ".r"
1327 1382
1328 1383 self.optchar = "D"
1329 1384
1330 1385 self.basicHeaderObj = BasicHeader(LOCALTIME)
1331 1386
1332 1387 self.systemHeaderObj = SystemHeader()
1333 1388
1334 1389 self.radarControllerHeaderObj = RadarControllerHeader()
1335 1390
1336 1391 self.processingHeaderObj = ProcessingHeader()
1337 1392
1338 1393 self.online = 0
1339 1394
1340 1395 self.fp = None
1341 1396
1342 1397 self.idFile = None
1343 1398
1344 1399 self.dtype = None
1345 1400
1346 1401 self.fileSizeByHeader = None
1347 1402
1348 1403 self.filenameList = []
1349 1404
1350 1405 self.filename = None
1351 1406
1352 1407 self.fileSize = None
1353 1408
1354 1409 self.firstHeaderSize = 0
1355 1410
1356 1411 self.basicHeaderSize = 24
1357 1412
1358 1413 self.pathList = []
1359 1414
1360 1415 self.filenameList = []
1361 1416
1362 1417 self.lastUTTime = 0
1363 1418
1364 1419 self.maxTimeStep = 30
1365 1420
1366 1421 self.flagNoMoreFiles = 0
1367 1422
1368 1423 self.set = 0
1369 1424
1370 1425 self.path = None
1371 1426
1372 1427 self.profileIndex = 2**32-1
1373 1428
1374 1429 self.delay = 3 #seconds
1375 1430
1376 1431 self.nTries = 3 #quantity tries
1377 1432
1378 1433 self.nFiles = 3 #number of files for searching
1379 1434
1380 1435 self.nReadBlocks = 0
1381 1436
1382 1437 self.flagIsNewFile = 1
1383 1438
1384 1439 self.__isFirstTimeOnline = 1
1385 1440
1386 1441 self.ippSeconds = 0
1387 1442
1388 1443 self.flagTimeBlock = 0
1389 1444
1390 1445 self.flagIsNewBlock = 0
1391 1446
1392 1447 self.nTotalBlocks = 0
1393 1448
1394 1449 self.blocksize = 0
1395 1450
1396 1451 self.dataOut = self.createObjByDefault()
1397 1452
1398 1453 def createObjByDefault(self):
1399 1454
1400 1455 dataObj = Voltage()
1401 1456
1402 1457 return dataObj
1403 1458
1404 1459 def __hasNotDataInBuffer(self):
1405 1460 if self.profileIndex >= self.processingHeaderObj.profilesPerBlock:
1406 1461 return 1
1407 1462 return 0
1408 1463
1409 1464
1410 1465 def getBlockDimension(self):
1411 1466 """
1412 1467 Obtiene la cantidad de puntos a leer por cada bloque de datos
1413 1468
1414 1469 Affected:
1415 1470 self.blocksize
1416 1471
1417 1472 Return:
1418 1473 None
1419 1474 """
1420 1475 pts2read = self.processingHeaderObj.profilesPerBlock * self.processingHeaderObj.nHeights * self.systemHeaderObj.nChannels
1421 1476 self.blocksize = pts2read
1422 1477
1423 1478
1424 1479 def readBlock(self):
1425 1480 """
1426 1481 readBlock lee el bloque de datos desde la posicion actual del puntero del archivo
1427 1482 (self.fp) y actualiza todos los parametros relacionados al bloque de datos
1428 1483 (metadata + data). La data leida es almacenada en el buffer y el contador del buffer
1429 1484 es seteado a 0
1430 1485
1431 1486 Inputs:
1432 1487 None
1433 1488
1434 1489 Return:
1435 1490 None
1436 1491
1437 1492 Affected:
1438 1493 self.profileIndex
1439 1494 self.datablock
1440 1495 self.flagIsNewFile
1441 1496 self.flagIsNewBlock
1442 1497 self.nTotalBlocks
1443 1498
1444 1499 Exceptions:
1445 1500 Si un bloque leido no es un bloque valido
1446 1501 """
1447 1502
1448 1503 junk = numpy.fromfile( self.fp, self.dtype, self.blocksize )
1449 1504
1450 1505 try:
1451 1506 junk = junk.reshape( (self.processingHeaderObj.profilesPerBlock, self.processingHeaderObj.nHeights, self.systemHeaderObj.nChannels) )
1452 1507 except:
1453 1508 print "The read block (%3d) has not enough data" %self.nReadBlocks
1454 1509 return 0
1455 1510
1456 1511 junk = numpy.transpose(junk, (2,0,1))
1457 1512 self.datablock = junk['real'] + junk['imag']*1j
1458 1513
1459 1514 self.profileIndex = 0
1460 1515
1461 1516 self.flagIsNewFile = 0
1462 1517 self.flagIsNewBlock = 1
1463 1518
1464 1519 self.nTotalBlocks += 1
1465 1520 self.nReadBlocks += 1
1466 1521
1467 1522 return 1
1468 1523
1469 1524 def getFirstHeader(self):
1470 1525
1471 1526 self.dataOut.dtype = self.dtype
1472 1527
1473 1528 self.dataOut.nProfiles = self.processingHeaderObj.profilesPerBlock
1474 1529
1475 1530 xf = self.processingHeaderObj.firstHeight + self.processingHeaderObj.nHeights*self.processingHeaderObj.deltaHeight
1476 1531
1477 1532 self.dataOut.heightList = numpy.arange(self.processingHeaderObj.firstHeight, xf, self.processingHeaderObj.deltaHeight)
1478 1533
1479 1534 self.dataOut.channelList = range(self.systemHeaderObj.nChannels)
1480 1535
1481 1536 self.dataOut.ippSeconds = self.ippSeconds
1482 1537
1483 1538 self.dataOut.timeInterval = self.ippSeconds * self.processingHeaderObj.nCohInt
1484 1539
1485 1540 self.dataOut.nCohInt = self.processingHeaderObj.nCohInt
1486 1541
1487 1542 self.dataOut.flagShiftFFT = False
1488 1543
1489 1544 if self.radarControllerHeaderObj.code != None:
1490 1545
1491 1546 self.dataOut.nCode = self.radarControllerHeaderObj.nCode
1492 1547
1493 1548 self.dataOut.nBaud = self.radarControllerHeaderObj.nBaud
1494 1549
1495 1550 self.dataOut.code = self.radarControllerHeaderObj.code
1496 1551
1497 1552 self.dataOut.systemHeaderObj = self.systemHeaderObj.copy()
1498 1553
1499 1554 self.dataOut.radarControllerHeaderObj = self.radarControllerHeaderObj.copy()
1500 1555
1501 1556 self.dataOut.flagDecodeData = False #asumo q la data no esta decodificada
1502 1557
1503 1558 self.dataOut.flagDeflipData = False #asumo q la data no esta sin flip
1504 1559
1505 1560 self.dataOut.flagShiftFFT = False
1506 1561
1507 1562 def getData(self):
1508 1563 """
1509 1564 getData obtiene una unidad de datos del buffer de lectura y la copia a la clase "Voltage"
1510 1565 con todos los parametros asociados a este (metadata). cuando no hay datos en el buffer de
1511 1566 lectura es necesario hacer una nueva lectura de los bloques de datos usando "readNextBlock"
1512 1567
1513 1568 Ademas incrementa el contador del buffer en 1.
1514 1569
1515 1570 Return:
1516 1571 data : retorna un perfil de voltages (alturas * canales) copiados desde el
1517 1572 buffer. Si no hay mas archivos a leer retorna None.
1518 1573
1519 1574 Variables afectadas:
1520 1575 self.dataOut
1521 1576 self.profileIndex
1522 1577
1523 1578 Affected:
1524 1579 self.dataOut
1525 1580 self.profileIndex
1526 1581 self.flagTimeBlock
1527 1582 self.flagIsNewBlock
1528 1583 """
1529 1584
1530 1585 if self.flagNoMoreFiles:
1531 1586 self.dataOut.flagNoData = True
1532 1587 print 'Process finished'
1533 1588 return 0
1534 1589
1535 1590 self.flagTimeBlock = 0
1536 1591 self.flagIsNewBlock = 0
1537 1592
1538 1593 if self.__hasNotDataInBuffer():
1539 1594
1540 1595 if not( self.readNextBlock() ):
1541 1596 return 0
1542 1597
1543 1598 self.getFirstHeader()
1544 1599
1545 1600 if self.datablock == None:
1546 1601 self.dataOut.flagNoData = True
1547 1602 return 0
1548 1603
1549 1604 self.dataOut.data = self.datablock[:,self.profileIndex,:]
1550 1605
1551 1606 self.dataOut.flagNoData = False
1552 1607
1553 1608 self.getBasicHeader()
1554 1609
1555 1610 self.profileIndex += 1
1556 1611
1557 1612 self.dataOut.realtime = self.online
1558 1613
1559 1614 return self.dataOut.data
1560 1615
1561 1616
1562 1617 class VoltageWriter(JRODataWriter):
1563 1618 """
1564 1619 Esta clase permite escribir datos de voltajes a archivos procesados (.r). La escritura
1565 1620 de los datos siempre se realiza por bloques.
1566 1621 """
1567 1622
1568 1623 ext = ".r"
1569 1624
1570 1625 optchar = "D"
1571 1626
1572 1627 shapeBuffer = None
1573 1628
1574 1629
1575 1630 def __init__(self):
1576 1631 """
1577 1632 Inicializador de la clase VoltageWriter para la escritura de datos de espectros.
1578 1633
1579 1634 Affected:
1580 1635 self.dataOut
1581 1636
1582 1637 Return: None
1583 1638 """
1584 1639
1585 1640 self.nTotalBlocks = 0
1586 1641
1587 1642 self.profileIndex = 0
1588 1643
1589 1644 self.isConfig = False
1590 1645
1591 1646 self.fp = None
1592 1647
1593 1648 self.flagIsNewFile = 1
1594 1649
1595 1650 self.nTotalBlocks = 0
1596 1651
1597 1652 self.flagIsNewBlock = 0
1598 1653
1599 1654 self.setFile = None
1600 1655
1601 1656 self.dtype = None
1602 1657
1603 1658 self.path = None
1604 1659
1605 1660 self.filename = None
1606 1661
1607 1662 self.basicHeaderObj = BasicHeader(LOCALTIME)
1608 1663
1609 1664 self.systemHeaderObj = SystemHeader()
1610 1665
1611 1666 self.radarControllerHeaderObj = RadarControllerHeader()
1612 1667
1613 1668 self.processingHeaderObj = ProcessingHeader()
1614 1669
1615 1670 def hasAllDataInBuffer(self):
1616 1671 if self.profileIndex >= self.processingHeaderObj.profilesPerBlock:
1617 1672 return 1
1618 1673 return 0
1619 1674
1620 1675
1621 1676 def setBlockDimension(self):
1622 1677 """
1623 1678 Obtiene las formas dimensionales del los subbloques de datos que componen un bloque
1624 1679
1625 1680 Affected:
1626 1681 self.shape_spc_Buffer
1627 1682 self.shape_cspc_Buffer
1628 1683 self.shape_dc_Buffer
1629 1684
1630 1685 Return: None
1631 1686 """
1632 1687 self.shapeBuffer = (self.processingHeaderObj.profilesPerBlock,
1633 1688 self.processingHeaderObj.nHeights,
1634 1689 self.systemHeaderObj.nChannels)
1635 1690
1636 1691 self.datablock = numpy.zeros((self.systemHeaderObj.nChannels,
1637 1692 self.processingHeaderObj.profilesPerBlock,
1638 1693 self.processingHeaderObj.nHeights),
1639 1694 dtype=numpy.dtype('complex64'))
1640 1695
1641 1696
1642 1697 def writeBlock(self):
1643 1698 """
1644 1699 Escribe el buffer en el file designado
1645 1700
1646 1701 Affected:
1647 1702 self.profileIndex
1648 1703 self.flagIsNewFile
1649 1704 self.flagIsNewBlock
1650 1705 self.nTotalBlocks
1651 1706 self.blockIndex
1652 1707
1653 1708 Return: None
1654 1709 """
1655 1710 data = numpy.zeros( self.shapeBuffer, self.dtype )
1656 1711
1657 1712 junk = numpy.transpose(self.datablock, (1,2,0))
1658 1713
1659 1714 data['real'] = junk.real
1660 1715 data['imag'] = junk.imag
1661 1716
1662 1717 data = data.reshape( (-1) )
1663 1718
1664 1719 data.tofile( self.fp )
1665 1720
1666 1721 self.datablock.fill(0)
1667 1722
1668 1723 self.profileIndex = 0
1669 1724 self.flagIsNewFile = 0
1670 1725 self.flagIsNewBlock = 1
1671 1726
1672 1727 self.blockIndex += 1
1673 1728 self.nTotalBlocks += 1
1674 1729
1675 1730 def putData(self):
1676 1731 """
1677 1732 Setea un bloque de datos y luego los escribe en un file
1678 1733
1679 1734 Affected:
1680 1735 self.flagIsNewBlock
1681 1736 self.profileIndex
1682 1737
1683 1738 Return:
1684 1739 0 : Si no hay data o no hay mas files que puedan escribirse
1685 1740 1 : Si se escribio la data de un bloque en un file
1686 1741 """
1687 1742 if self.dataOut.flagNoData:
1688 1743 return 0
1689 1744
1690 1745 self.flagIsNewBlock = 0
1691 1746
1692 1747 if self.dataOut.flagTimeBlock:
1693 1748
1694 1749 self.datablock.fill(0)
1695 1750 self.profileIndex = 0
1696 1751 self.setNextFile()
1697 1752
1698 1753 if self.profileIndex == 0:
1699 1754 self.setBasicHeader()
1700 1755
1701 1756 self.datablock[:,self.profileIndex,:] = self.dataOut.data
1702 1757
1703 1758 self.profileIndex += 1
1704 1759
1705 1760 if self.hasAllDataInBuffer():
1706 1761 #if self.flagIsNewFile:
1707 1762 self.writeNextBlock()
1708 1763 # self.setFirstHeader()
1709 1764
1710 1765 return 1
1711 1766
1712 1767 def __getProcessFlags(self):
1713 1768
1714 1769 processFlags = 0
1715 1770
1716 1771 dtype0 = numpy.dtype([('real','<i1'),('imag','<i1')])
1717 1772 dtype1 = numpy.dtype([('real','<i2'),('imag','<i2')])
1718 1773 dtype2 = numpy.dtype([('real','<i4'),('imag','<i4')])
1719 1774 dtype3 = numpy.dtype([('real','<i8'),('imag','<i8')])
1720 1775 dtype4 = numpy.dtype([('real','<f4'),('imag','<f4')])
1721 1776 dtype5 = numpy.dtype([('real','<f8'),('imag','<f8')])
1722 1777
1723 1778 dtypeList = [dtype0, dtype1, dtype2, dtype3, dtype4, dtype5]
1724 1779
1725 1780
1726 1781
1727 1782 datatypeValueList = [PROCFLAG.DATATYPE_CHAR,
1728 1783 PROCFLAG.DATATYPE_SHORT,
1729 1784 PROCFLAG.DATATYPE_LONG,
1730 1785 PROCFLAG.DATATYPE_INT64,
1731 1786 PROCFLAG.DATATYPE_FLOAT,
1732 1787 PROCFLAG.DATATYPE_DOUBLE]
1733 1788
1734 1789
1735 1790 for index in range(len(dtypeList)):
1736 1791 if self.dataOut.dtype == dtypeList[index]:
1737 1792 dtypeValue = datatypeValueList[index]
1738 1793 break
1739 1794
1740 1795 processFlags += dtypeValue
1741 1796
1742 1797 if self.dataOut.flagDecodeData:
1743 1798 processFlags += PROCFLAG.DECODE_DATA
1744 1799
1745 1800 if self.dataOut.flagDeflipData:
1746 1801 processFlags += PROCFLAG.DEFLIP_DATA
1747 1802
1748 1803 if self.dataOut.code != None:
1749 1804 processFlags += PROCFLAG.DEFINE_PROCESS_CODE
1750 1805
1751 1806 if self.dataOut.nCohInt > 1:
1752 1807 processFlags += PROCFLAG.COHERENT_INTEGRATION
1753 1808
1754 1809 return processFlags
1755 1810
1756 1811
1757 1812 def __getBlockSize(self):
1758 1813 '''
1759 1814 Este metodos determina el cantidad de bytes para un bloque de datos de tipo Voltage
1760 1815 '''
1761 1816
1762 1817 dtype0 = numpy.dtype([('real','<i1'),('imag','<i1')])
1763 1818 dtype1 = numpy.dtype([('real','<i2'),('imag','<i2')])
1764 1819 dtype2 = numpy.dtype([('real','<i4'),('imag','<i4')])
1765 1820 dtype3 = numpy.dtype([('real','<i8'),('imag','<i8')])
1766 1821 dtype4 = numpy.dtype([('real','<f4'),('imag','<f4')])
1767 1822 dtype5 = numpy.dtype([('real','<f8'),('imag','<f8')])
1768 1823
1769 1824 dtypeList = [dtype0, dtype1, dtype2, dtype3, dtype4, dtype5]
1770 1825 datatypeValueList = [1,2,4,8,4,8]
1771 1826 for index in range(len(dtypeList)):
1772 1827 if self.dataOut.dtype == dtypeList[index]:
1773 1828 datatypeValue = datatypeValueList[index]
1774 1829 break
1775 1830
1776 1831 blocksize = int(self.dataOut.nHeights * self.dataOut.nChannels * self.dataOut.nProfiles * datatypeValue * 2)
1777 1832
1778 1833 return blocksize
1779 1834
1780 1835 def setFirstHeader(self):
1781 1836
1782 1837 """
1783 1838 Obtiene una copia del First Header
1784 1839
1785 1840 Affected:
1786 1841 self.systemHeaderObj
1787 1842 self.radarControllerHeaderObj
1788 1843 self.dtype
1789 1844
1790 1845 Return:
1791 1846 None
1792 1847 """
1793 1848
1794 1849 self.systemHeaderObj = self.dataOut.systemHeaderObj.copy()
1795 1850 self.systemHeaderObj.nChannels = self.dataOut.nChannels
1796 1851 self.radarControllerHeaderObj = self.dataOut.radarControllerHeaderObj.copy()
1797 1852
1798 1853 self.setBasicHeader()
1799 1854
1800 1855 processingHeaderSize = 40 # bytes
1801 1856 self.processingHeaderObj.dtype = 0 # Voltage
1802 1857 self.processingHeaderObj.blockSize = self.__getBlockSize()
1803 1858 self.processingHeaderObj.profilesPerBlock = self.profilesPerBlock
1804 1859 self.processingHeaderObj.dataBlocksPerFile = self.blocksPerFile
1805 1860 self.processingHeaderObj.nWindows = 1 #podria ser 1 o self.dataOut.processingHeaderObj.nWindows
1806 1861 self.processingHeaderObj.processFlags = self.__getProcessFlags()
1807 1862 self.processingHeaderObj.nCohInt = self.dataOut.nCohInt
1808 1863 self.processingHeaderObj.nIncohInt = 1 # Cuando la data de origen es de tipo Voltage
1809 1864 self.processingHeaderObj.totalSpectra = 0 # Cuando la data de origen es de tipo Voltage
1810 1865
1811 1866 if self.dataOut.code != None:
1812 1867 self.processingHeaderObj.code = self.dataOut.code
1813 1868 self.processingHeaderObj.nCode = self.dataOut.nCode
1814 1869 self.processingHeaderObj.nBaud = self.dataOut.nBaud
1815 1870 codesize = int(8 + 4 * self.dataOut.nCode * self.dataOut.nBaud)
1816 1871 processingHeaderSize += codesize
1817 1872
1818 1873 if self.processingHeaderObj.nWindows != 0:
1819 1874 self.processingHeaderObj.firstHeight = self.dataOut.heightList[0]
1820 1875 self.processingHeaderObj.deltaHeight = self.dataOut.heightList[1] - self.dataOut.heightList[0]
1821 1876 self.processingHeaderObj.nHeights = self.dataOut.nHeights
1822 1877 self.processingHeaderObj.samplesWin = self.dataOut.nHeights
1823 1878 processingHeaderSize += 12
1824 1879
1825 1880 self.processingHeaderObj.size = processingHeaderSize
1826 1881
1827 1882 class SpectraReader(JRODataReader):
1828 1883 """
1829 1884 Esta clase permite leer datos de espectros desde archivos procesados (.pdata). La lectura
1830 1885 de los datos siempre se realiza por bloques. Los datos leidos (array de 3 dimensiones)
1831 1886 son almacenados en tres buffer's para el Self Spectra, el Cross Spectra y el DC Channel.
1832 1887
1833 1888 paresCanalesIguales * alturas * perfiles (Self Spectra)
1834 1889 paresCanalesDiferentes * alturas * perfiles (Cross Spectra)
1835 1890 canales * alturas (DC Channels)
1836 1891
1837 1892 Esta clase contiene instancias (objetos) de las clases BasicHeader, SystemHeader,
1838 1893 RadarControllerHeader y Spectra. Los tres primeros se usan para almacenar informacion de la
1839 1894 cabecera de datos (metadata), y el cuarto (Spectra) para obtener y almacenar un bloque de
1840 1895 datos desde el "buffer" cada vez que se ejecute el metodo "getData".
1841 1896
1842 1897 Example:
1843 1898 dpath = "/home/myuser/data"
1844 1899
1845 1900 startTime = datetime.datetime(2010,1,20,0,0,0,0,0,0)
1846 1901
1847 1902 endTime = datetime.datetime(2010,1,21,23,59,59,0,0,0)
1848 1903
1849 1904 readerObj = SpectraReader()
1850 1905
1851 1906 readerObj.setup(dpath, startTime, endTime)
1852 1907
1853 1908 while(True):
1854 1909
1855 1910 readerObj.getData()
1856 1911
1857 1912 print readerObj.data_spc
1858 1913
1859 1914 print readerObj.data_cspc
1860 1915
1861 1916 print readerObj.data_dc
1862 1917
1863 1918 if readerObj.flagNoMoreFiles:
1864 1919 break
1865 1920
1866 1921 """
1867 1922
1868 1923 pts2read_SelfSpectra = 0
1869 1924
1870 1925 pts2read_CrossSpectra = 0
1871 1926
1872 1927 pts2read_DCchannels = 0
1873 1928
1874 1929 ext = ".pdata"
1875 1930
1876 1931 optchar = "P"
1877 1932
1878 1933 dataOut = None
1879 1934
1880 1935 nRdChannels = None
1881 1936
1882 1937 nRdPairs = None
1883 1938
1884 1939 rdPairList = []
1885 1940
1886 1941 def __init__(self):
1887 1942 """
1888 1943 Inicializador de la clase SpectraReader para la lectura de datos de espectros.
1889 1944
1890 1945 Inputs:
1891 1946 dataOut : Objeto de la clase Spectra. Este objeto sera utilizado para
1892 1947 almacenar un perfil de datos cada vez que se haga un requerimiento
1893 1948 (getData). El perfil sera obtenido a partir del buffer de datos,
1894 1949 si el buffer esta vacio se hara un nuevo proceso de lectura de un
1895 1950 bloque de datos.
1896 1951 Si este parametro no es pasado se creara uno internamente.
1897 1952
1898 1953 Affected:
1899 1954 self.dataOut
1900 1955
1901 1956 Return : None
1902 1957 """
1903 1958
1904 1959 self.isConfig = False
1905 1960
1906 1961 self.pts2read_SelfSpectra = 0
1907 1962
1908 1963 self.pts2read_CrossSpectra = 0
1909 1964
1910 1965 self.pts2read_DCchannels = 0
1911 1966
1912 1967 self.datablock = None
1913 1968
1914 1969 self.utc = None
1915 1970
1916 1971 self.ext = ".pdata"
1917 1972
1918 1973 self.optchar = "P"
1919 1974
1920 1975 self.basicHeaderObj = BasicHeader(LOCALTIME)
1921 1976
1922 1977 self.systemHeaderObj = SystemHeader()
1923 1978
1924 1979 self.radarControllerHeaderObj = RadarControllerHeader()
1925 1980
1926 1981 self.processingHeaderObj = ProcessingHeader()
1927 1982
1928 1983 self.online = 0
1929 1984
1930 1985 self.fp = None
1931 1986
1932 1987 self.idFile = None
1933 1988
1934 1989 self.dtype = None
1935 1990
1936 1991 self.fileSizeByHeader = None
1937 1992
1938 1993 self.filenameList = []
1939 1994
1940 1995 self.filename = None
1941 1996
1942 1997 self.fileSize = None
1943 1998
1944 1999 self.firstHeaderSize = 0
1945 2000
1946 2001 self.basicHeaderSize = 24
1947 2002
1948 2003 self.pathList = []
1949 2004
1950 2005 self.lastUTTime = 0
1951 2006
1952 2007 self.maxTimeStep = 30
1953 2008
1954 2009 self.flagNoMoreFiles = 0
1955 2010
1956 2011 self.set = 0
1957 2012
1958 2013 self.path = None
1959 2014
1960 2015 self.delay = 60 #seconds
1961 2016
1962 2017 self.nTries = 3 #quantity tries
1963 2018
1964 2019 self.nFiles = 3 #number of files for searching
1965 2020
1966 2021 self.nReadBlocks = 0
1967 2022
1968 2023 self.flagIsNewFile = 1
1969 2024
1970 2025 self.__isFirstTimeOnline = 1
1971 2026
1972 2027 self.ippSeconds = 0
1973 2028
1974 2029 self.flagTimeBlock = 0
1975 2030
1976 2031 self.flagIsNewBlock = 0
1977 2032
1978 2033 self.nTotalBlocks = 0
1979 2034
1980 2035 self.blocksize = 0
1981 2036
1982 2037 self.dataOut = self.createObjByDefault()
1983 2038
1984 2039 self.profileIndex = 1 #Always
1985 2040
1986 2041
1987 2042 def createObjByDefault(self):
1988 2043
1989 2044 dataObj = Spectra()
1990 2045
1991 2046 return dataObj
1992 2047
1993 2048 def __hasNotDataInBuffer(self):
1994 2049 return 1
1995 2050
1996 2051
1997 2052 def getBlockDimension(self):
1998 2053 """
1999 2054 Obtiene la cantidad de puntos a leer por cada bloque de datos
2000 2055
2001 2056 Affected:
2002 2057 self.nRdChannels
2003 2058 self.nRdPairs
2004 2059 self.pts2read_SelfSpectra
2005 2060 self.pts2read_CrossSpectra
2006 2061 self.pts2read_DCchannels
2007 2062 self.blocksize
2008 2063 self.dataOut.nChannels
2009 2064 self.dataOut.nPairs
2010 2065
2011 2066 Return:
2012 2067 None
2013 2068 """
2014 2069 self.nRdChannels = 0
2015 2070 self.nRdPairs = 0
2016 2071 self.rdPairList = []
2017 2072
2018 2073 for i in range(0, self.processingHeaderObj.totalSpectra*2, 2):
2019 2074 if self.processingHeaderObj.spectraComb[i] == self.processingHeaderObj.spectraComb[i+1]:
2020 2075 self.nRdChannels = self.nRdChannels + 1 #par de canales iguales
2021 2076 else:
2022 2077 self.nRdPairs = self.nRdPairs + 1 #par de canales diferentes
2023 2078 self.rdPairList.append((self.processingHeaderObj.spectraComb[i], self.processingHeaderObj.spectraComb[i+1]))
2024 2079
2025 2080 pts2read = self.processingHeaderObj.nHeights * self.processingHeaderObj.profilesPerBlock
2026 2081
2027 2082 self.pts2read_SelfSpectra = int(self.nRdChannels * pts2read)
2028 2083 self.blocksize = self.pts2read_SelfSpectra
2029 2084
2030 2085 if self.processingHeaderObj.flag_cspc:
2031 2086 self.pts2read_CrossSpectra = int(self.nRdPairs * pts2read)
2032 2087 self.blocksize += self.pts2read_CrossSpectra
2033 2088
2034 2089 if self.processingHeaderObj.flag_dc:
2035 2090 self.pts2read_DCchannels = int(self.systemHeaderObj.nChannels * self.processingHeaderObj.nHeights)
2036 2091 self.blocksize += self.pts2read_DCchannels
2037 2092
2038 2093 # self.blocksize = self.pts2read_SelfSpectra + self.pts2read_CrossSpectra + self.pts2read_DCchannels
2039 2094
2040 2095
2041 2096 def readBlock(self):
2042 2097 """
2043 2098 Lee el bloque de datos desde la posicion actual del puntero del archivo
2044 2099 (self.fp) y actualiza todos los parametros relacionados al bloque de datos
2045 2100 (metadata + data). La data leida es almacenada en el buffer y el contador del buffer
2046 2101 es seteado a 0
2047 2102
2048 2103 Return: None
2049 2104
2050 2105 Variables afectadas:
2051 2106
2052 2107 self.flagIsNewFile
2053 2108 self.flagIsNewBlock
2054 2109 self.nTotalBlocks
2055 2110 self.data_spc
2056 2111 self.data_cspc
2057 2112 self.data_dc
2058 2113
2059 2114 Exceptions:
2060 2115 Si un bloque leido no es un bloque valido
2061 2116 """
2062 2117 blockOk_flag = False
2063 2118 fpointer = self.fp.tell()
2064 2119
2065 2120 spc = numpy.fromfile( self.fp, self.dtype[0], self.pts2read_SelfSpectra )
2066 2121 spc = spc.reshape( (self.nRdChannels, self.processingHeaderObj.nHeights, self.processingHeaderObj.profilesPerBlock) ) #transforma a un arreglo 3D
2067 2122
2068 2123 if self.processingHeaderObj.flag_cspc:
2069 2124 cspc = numpy.fromfile( self.fp, self.dtype, self.pts2read_CrossSpectra )
2070 2125 cspc = cspc.reshape( (self.nRdPairs, self.processingHeaderObj.nHeights, self.processingHeaderObj.profilesPerBlock) ) #transforma a un arreglo 3D
2071 2126
2072 2127 if self.processingHeaderObj.flag_dc:
2073 2128 dc = numpy.fromfile( self.fp, self.dtype, self.pts2read_DCchannels ) #int(self.processingHeaderObj.nHeights*self.systemHeaderObj.nChannels) )
2074 2129 dc = dc.reshape( (self.systemHeaderObj.nChannels, self.processingHeaderObj.nHeights) ) #transforma a un arreglo 2D
2075 2130
2076 2131
2077 2132 if not(self.processingHeaderObj.shif_fft):
2078 2133 #desplaza a la derecha en el eje 2 determinadas posiciones
2079 2134 shift = int(self.processingHeaderObj.profilesPerBlock/2)
2080 2135 spc = numpy.roll( spc, shift , axis=2 )
2081 2136
2082 2137 if self.processingHeaderObj.flag_cspc:
2083 2138 #desplaza a la derecha en el eje 2 determinadas posiciones
2084 2139 cspc = numpy.roll( cspc, shift, axis=2 )
2085 2140
2086 2141 # self.processingHeaderObj.shif_fft = True
2087 2142
2088 2143 spc = numpy.transpose( spc, (0,2,1) )
2089 2144 self.data_spc = spc
2090 2145
2091 2146 if self.processingHeaderObj.flag_cspc:
2092 2147 cspc = numpy.transpose( cspc, (0,2,1) )
2093 2148 self.data_cspc = cspc['real'] + cspc['imag']*1j
2094 2149 else:
2095 2150 self.data_cspc = None
2096 2151
2097 2152 if self.processingHeaderObj.flag_dc:
2098 2153 self.data_dc = dc['real'] + dc['imag']*1j
2099 2154 else:
2100 2155 self.data_dc = None
2101 2156
2102 2157 self.flagIsNewFile = 0
2103 2158 self.flagIsNewBlock = 1
2104 2159
2105 2160 self.nTotalBlocks += 1
2106 2161 self.nReadBlocks += 1
2107 2162
2108 2163 return 1
2109 2164
2110 2165 def getFirstHeader(self):
2111 2166
2112 2167 self.dataOut.dtype = self.dtype
2113 2168
2114 2169 self.dataOut.nPairs = self.nRdPairs
2115 2170
2116 2171 self.dataOut.pairsList = self.rdPairList
2117 2172
2118 2173 self.dataOut.nProfiles = self.processingHeaderObj.profilesPerBlock
2119 2174
2120 2175 self.dataOut.nFFTPoints = self.processingHeaderObj.profilesPerBlock
2121 2176
2122 2177 self.dataOut.nCohInt = self.processingHeaderObj.nCohInt
2123 2178
2124 2179 self.dataOut.nIncohInt = self.processingHeaderObj.nIncohInt
2125 2180
2126 2181 xf = self.processingHeaderObj.firstHeight + self.processingHeaderObj.nHeights*self.processingHeaderObj.deltaHeight
2127 2182
2128 2183 self.dataOut.heightList = numpy.arange(self.processingHeaderObj.firstHeight, xf, self.processingHeaderObj.deltaHeight)
2129 2184
2130 2185 self.dataOut.channelList = range(self.systemHeaderObj.nChannels)
2131 2186
2132 2187 self.dataOut.ippSeconds = self.ippSeconds
2133 2188
2134 2189 self.dataOut.timeInterval = self.ippSeconds * self.processingHeaderObj.nCohInt * self.processingHeaderObj.nIncohInt * self.dataOut.nFFTPoints
2135 2190
2136 2191 self.dataOut.systemHeaderObj = self.systemHeaderObj.copy()
2137 2192
2138 2193 self.dataOut.radarControllerHeaderObj = self.radarControllerHeaderObj.copy()
2139 2194
2140 2195 self.dataOut.flagShiftFFT = self.processingHeaderObj.shif_fft
2141 2196
2142 2197 self.dataOut.flagDecodeData = False #asumo q la data no esta decodificada
2143 2198
2144 2199 self.dataOut.flagDeflipData = True #asumo q la data no esta sin flip
2145 2200
2146 2201 if self.processingHeaderObj.code != None:
2147 2202
2148 2203 self.dataOut.nCode = self.processingHeaderObj.nCode
2149 2204
2150 2205 self.dataOut.nBaud = self.processingHeaderObj.nBaud
2151 2206
2152 2207 self.dataOut.code = self.processingHeaderObj.code
2153 2208
2154 2209 self.dataOut.flagDecodeData = True
2155 2210
2156 2211 def getData(self):
2157 2212 """
2158 2213 Copia el buffer de lectura a la clase "Spectra",
2159 2214 con todos los parametros asociados a este (metadata). cuando no hay datos en el buffer de
2160 2215 lectura es necesario hacer una nueva lectura de los bloques de datos usando "readNextBlock"
2161 2216
2162 2217 Return:
2163 2218 0 : Si no hay mas archivos disponibles
2164 2219 1 : Si hizo una buena copia del buffer
2165 2220
2166 2221 Affected:
2167 2222 self.dataOut
2168 2223
2169 2224 self.flagTimeBlock
2170 2225 self.flagIsNewBlock
2171 2226 """
2172 2227
2173 2228 if self.flagNoMoreFiles:
2174 2229 self.dataOut.flagNoData = True
2175 2230 print 'Process finished'
2176 2231 return 0
2177 2232
2178 2233 self.flagTimeBlock = 0
2179 2234 self.flagIsNewBlock = 0
2180 2235
2181 2236 if self.__hasNotDataInBuffer():
2182 2237
2183 2238 if not( self.readNextBlock() ):
2184 2239 self.dataOut.flagNoData = True
2185 2240 return 0
2186 2241
2187 2242 #data es un numpy array de 3 dmensiones (perfiles, alturas y canales)
2188 2243
2189 2244 if self.data_dc == None:
2190 2245 self.dataOut.flagNoData = True
2191 2246 return 0
2192 2247
2193 2248 self.getBasicHeader()
2194 2249
2195 2250 self.getFirstHeader()
2196 2251
2197 2252 self.dataOut.data_spc = self.data_spc
2198 2253
2199 2254 self.dataOut.data_cspc = self.data_cspc
2200 2255
2201 2256 self.dataOut.data_dc = self.data_dc
2202 2257
2203 2258 self.dataOut.flagNoData = False
2204 2259
2205 2260 self.dataOut.realtime = self.online
2206 2261
2207 2262 return self.dataOut.data_spc
2208 2263
2209 2264
2210 2265 class SpectraWriter(JRODataWriter):
2211 2266
2212 2267 """
2213 2268 Esta clase permite escribir datos de espectros a archivos procesados (.pdata). La escritura
2214 2269 de los datos siempre se realiza por bloques.
2215 2270 """
2216 2271
2217 2272 ext = ".pdata"
2218 2273
2219 2274 optchar = "P"
2220 2275
2221 2276 shape_spc_Buffer = None
2222 2277
2223 2278 shape_cspc_Buffer = None
2224 2279
2225 2280 shape_dc_Buffer = None
2226 2281
2227 2282 data_spc = None
2228 2283
2229 2284 data_cspc = None
2230 2285
2231 2286 data_dc = None
2232 2287
2233 2288 # dataOut = None
2234 2289
2235 2290 def __init__(self):
2236 2291 """
2237 2292 Inicializador de la clase SpectraWriter para la escritura de datos de espectros.
2238 2293
2239 2294 Affected:
2240 2295 self.dataOut
2241 2296 self.basicHeaderObj
2242 2297 self.systemHeaderObj
2243 2298 self.radarControllerHeaderObj
2244 2299 self.processingHeaderObj
2245 2300
2246 2301 Return: None
2247 2302 """
2248 2303
2249 2304 self.isConfig = False
2250 2305
2251 2306 self.nTotalBlocks = 0
2252 2307
2253 2308 self.data_spc = None
2254 2309
2255 2310 self.data_cspc = None
2256 2311
2257 2312 self.data_dc = None
2258 2313
2259 2314 self.fp = None
2260 2315
2261 2316 self.flagIsNewFile = 1
2262 2317
2263 2318 self.nTotalBlocks = 0
2264 2319
2265 2320 self.flagIsNewBlock = 0
2266 2321
2267 2322 self.setFile = None
2268 2323
2269 2324 self.dtype = None
2270 2325
2271 2326 self.path = None
2272 2327
2273 2328 self.noMoreFiles = 0
2274 2329
2275 2330 self.filename = None
2276 2331
2277 2332 self.basicHeaderObj = BasicHeader(LOCALTIME)
2278 2333
2279 2334 self.systemHeaderObj = SystemHeader()
2280 2335
2281 2336 self.radarControllerHeaderObj = RadarControllerHeader()
2282 2337
2283 2338 self.processingHeaderObj = ProcessingHeader()
2284 2339
2285 2340
2286 2341 def hasAllDataInBuffer(self):
2287 2342 return 1
2288 2343
2289 2344
2290 2345 def setBlockDimension(self):
2291 2346 """
2292 2347 Obtiene las formas dimensionales del los subbloques de datos que componen un bloque
2293 2348
2294 2349 Affected:
2295 2350 self.shape_spc_Buffer
2296 2351 self.shape_cspc_Buffer
2297 2352 self.shape_dc_Buffer
2298 2353
2299 2354 Return: None
2300 2355 """
2301 2356 self.shape_spc_Buffer = (self.dataOut.nChannels,
2302 2357 self.processingHeaderObj.nHeights,
2303 2358 self.processingHeaderObj.profilesPerBlock)
2304 2359
2305 2360 self.shape_cspc_Buffer = (self.dataOut.nPairs,
2306 2361 self.processingHeaderObj.nHeights,
2307 2362 self.processingHeaderObj.profilesPerBlock)
2308 2363
2309 2364 self.shape_dc_Buffer = (self.dataOut.nChannels,
2310 2365 self.processingHeaderObj.nHeights)
2311 2366
2312 2367
2313 2368 def writeBlock(self):
2314 2369 """
2315 2370 Escribe el buffer en el file designado
2316 2371
2317 2372 Affected:
2318 2373 self.data_spc
2319 2374 self.data_cspc
2320 2375 self.data_dc
2321 2376 self.flagIsNewFile
2322 2377 self.flagIsNewBlock
2323 2378 self.nTotalBlocks
2324 2379 self.nWriteBlocks
2325 2380
2326 2381 Return: None
2327 2382 """
2328 2383
2329 2384 spc = numpy.transpose( self.data_spc, (0,2,1) )
2330 2385 if not( self.processingHeaderObj.shif_fft ):
2331 2386 spc = numpy.roll( spc, self.processingHeaderObj.profilesPerBlock/2, axis=2 ) #desplaza a la derecha en el eje 2 determinadas posiciones
2332 2387 data = spc.reshape((-1))
2333 2388 data = data.astype(self.dtype[0])
2334 2389 data.tofile(self.fp)
2335 2390
2336 2391 if self.data_cspc != None:
2337 2392 data = numpy.zeros( self.shape_cspc_Buffer, self.dtype )
2338 2393 cspc = numpy.transpose( self.data_cspc, (0,2,1) )
2339 2394 if not( self.processingHeaderObj.shif_fft ):
2340 2395 cspc = numpy.roll( cspc, self.processingHeaderObj.profilesPerBlock/2, axis=2 ) #desplaza a la derecha en el eje 2 determinadas posiciones
2341 2396 data['real'] = cspc.real
2342 2397 data['imag'] = cspc.imag
2343 2398 data = data.reshape((-1))
2344 2399 data.tofile(self.fp)
2345 2400
2346 2401 if self.data_dc != None:
2347 2402 data = numpy.zeros( self.shape_dc_Buffer, self.dtype )
2348 2403 dc = self.data_dc
2349 2404 data['real'] = dc.real
2350 2405 data['imag'] = dc.imag
2351 2406 data = data.reshape((-1))
2352 2407 data.tofile(self.fp)
2353 2408
2354 2409 self.data_spc.fill(0)
2355 2410 self.data_dc.fill(0)
2356 2411 if self.data_cspc != None:
2357 2412 self.data_cspc.fill(0)
2358 2413
2359 2414 self.flagIsNewFile = 0
2360 2415 self.flagIsNewBlock = 1
2361 2416 self.nTotalBlocks += 1
2362 2417 self.nWriteBlocks += 1
2363 2418 self.blockIndex += 1
2364 2419
2365 2420
2366 2421 def putData(self):
2367 2422 """
2368 2423 Setea un bloque de datos y luego los escribe en un file
2369 2424
2370 2425 Affected:
2371 2426 self.data_spc
2372 2427 self.data_cspc
2373 2428 self.data_dc
2374 2429
2375 2430 Return:
2376 2431 0 : Si no hay data o no hay mas files que puedan escribirse
2377 2432 1 : Si se escribio la data de un bloque en un file
2378 2433 """
2379 2434
2380 2435 if self.dataOut.flagNoData:
2381 2436 return 0
2382 2437
2383 2438 self.flagIsNewBlock = 0
2384 2439
2385 2440 if self.dataOut.flagTimeBlock:
2386 2441 self.data_spc.fill(0)
2387 2442 self.data_cspc.fill(0)
2388 2443 self.data_dc.fill(0)
2389 2444 self.setNextFile()
2390 2445
2391 2446 if self.flagIsNewFile == 0:
2392 2447 self.setBasicHeader()
2393 2448
2394 2449 self.data_spc = self.dataOut.data_spc.copy()
2395 2450 self.data_cspc = self.dataOut.data_cspc.copy()
2396 2451 self.data_dc = self.dataOut.data_dc.copy()
2397 2452
2398 2453 # #self.processingHeaderObj.dataBlocksPerFile)
2399 2454 if self.hasAllDataInBuffer():
2400 2455 # self.setFirstHeader()
2401 2456 self.writeNextBlock()
2402 2457
2403 2458 return 1
2404 2459
2405 2460
2406 2461 def __getProcessFlags(self):
2407 2462
2408 2463 processFlags = 0
2409 2464
2410 2465 dtype0 = numpy.dtype([('real','<i1'),('imag','<i1')])
2411 2466 dtype1 = numpy.dtype([('real','<i2'),('imag','<i2')])
2412 2467 dtype2 = numpy.dtype([('real','<i4'),('imag','<i4')])
2413 2468 dtype3 = numpy.dtype([('real','<i8'),('imag','<i8')])
2414 2469 dtype4 = numpy.dtype([('real','<f4'),('imag','<f4')])
2415 2470 dtype5 = numpy.dtype([('real','<f8'),('imag','<f8')])
2416 2471
2417 2472 dtypeList = [dtype0, dtype1, dtype2, dtype3, dtype4, dtype5]
2418 2473
2419 2474
2420 2475
2421 2476 datatypeValueList = [PROCFLAG.DATATYPE_CHAR,
2422 2477 PROCFLAG.DATATYPE_SHORT,
2423 2478 PROCFLAG.DATATYPE_LONG,
2424 2479 PROCFLAG.DATATYPE_INT64,
2425 2480 PROCFLAG.DATATYPE_FLOAT,
2426 2481 PROCFLAG.DATATYPE_DOUBLE]
2427 2482
2428 2483
2429 2484 for index in range(len(dtypeList)):
2430 2485 if self.dataOut.dtype == dtypeList[index]:
2431 2486 dtypeValue = datatypeValueList[index]
2432 2487 break
2433 2488
2434 2489 processFlags += dtypeValue
2435 2490
2436 2491 if self.dataOut.flagDecodeData:
2437 2492 processFlags += PROCFLAG.DECODE_DATA
2438 2493
2439 2494 if self.dataOut.flagDeflipData:
2440 2495 processFlags += PROCFLAG.DEFLIP_DATA
2441 2496
2442 2497 if self.dataOut.code != None:
2443 2498 processFlags += PROCFLAG.DEFINE_PROCESS_CODE
2444 2499
2445 2500 if self.dataOut.nIncohInt > 1:
2446 2501 processFlags += PROCFLAG.INCOHERENT_INTEGRATION
2447 2502
2448 2503 if self.dataOut.data_dc != None:
2449 2504 processFlags += PROCFLAG.SAVE_CHANNELS_DC
2450 2505
2451 2506 return processFlags
2452 2507
2453 2508
2454 2509 def __getBlockSize(self):
2455 2510 '''
2456 2511 Este metodos determina el cantidad de bytes para un bloque de datos de tipo Spectra
2457 2512 '''
2458 2513
2459 2514 dtype0 = numpy.dtype([('real','<i1'),('imag','<i1')])
2460 2515 dtype1 = numpy.dtype([('real','<i2'),('imag','<i2')])
2461 2516 dtype2 = numpy.dtype([('real','<i4'),('imag','<i4')])
2462 2517 dtype3 = numpy.dtype([('real','<i8'),('imag','<i8')])
2463 2518 dtype4 = numpy.dtype([('real','<f4'),('imag','<f4')])
2464 2519 dtype5 = numpy.dtype([('real','<f8'),('imag','<f8')])
2465 2520
2466 2521 dtypeList = [dtype0, dtype1, dtype2, dtype3, dtype4, dtype5]
2467 2522 datatypeValueList = [1,2,4,8,4,8]
2468 2523 for index in range(len(dtypeList)):
2469 2524 if self.dataOut.dtype == dtypeList[index]:
2470 2525 datatypeValue = datatypeValueList[index]
2471 2526 break
2472 2527
2473 2528
2474 2529 pts2write = self.dataOut.nHeights * self.dataOut.nFFTPoints
2475 2530
2476 2531 pts2write_SelfSpectra = int(self.dataOut.nChannels * pts2write)
2477 2532 blocksize = (pts2write_SelfSpectra*datatypeValue)
2478 2533
2479 2534 if self.dataOut.data_cspc != None:
2480 2535 pts2write_CrossSpectra = int(self.dataOut.nPairs * pts2write)
2481 2536 blocksize += (pts2write_CrossSpectra*datatypeValue*2)
2482 2537
2483 2538 if self.dataOut.data_dc != None:
2484 2539 pts2write_DCchannels = int(self.dataOut.nChannels * self.dataOut.nHeights)
2485 2540 blocksize += (pts2write_DCchannels*datatypeValue*2)
2486 2541
2487 2542 blocksize = blocksize #* datatypeValue * 2 #CORREGIR ESTO
2488 2543
2489 2544 return blocksize
2490 2545
2491 2546 def setFirstHeader(self):
2492 2547
2493 2548 """
2494 2549 Obtiene una copia del First Header
2495 2550
2496 2551 Affected:
2497 2552 self.systemHeaderObj
2498 2553 self.radarControllerHeaderObj
2499 2554 self.dtype
2500 2555
2501 2556 Return:
2502 2557 None
2503 2558 """
2504 2559
2505 2560 self.systemHeaderObj = self.dataOut.systemHeaderObj.copy()
2506 2561 self.systemHeaderObj.nChannels = self.dataOut.nChannels
2507 2562 self.radarControllerHeaderObj = self.dataOut.radarControllerHeaderObj.copy()
2508 2563
2509 2564 self.setBasicHeader()
2510 2565
2511 2566 processingHeaderSize = 40 # bytes
2512 2567 self.processingHeaderObj.dtype = 1 # Spectra
2513 2568 self.processingHeaderObj.blockSize = self.__getBlockSize()
2514 2569 self.processingHeaderObj.profilesPerBlock = self.dataOut.nFFTPoints
2515 2570 self.processingHeaderObj.dataBlocksPerFile = self.blocksPerFile
2516 2571 self.processingHeaderObj.nWindows = 1 #podria ser 1 o self.dataOut.processingHeaderObj.nWindows
2517 2572 self.processingHeaderObj.processFlags = self.__getProcessFlags()
2518 2573 self.processingHeaderObj.nCohInt = self.dataOut.nCohInt# Se requiere para determinar el valor de timeInterval
2519 2574 self.processingHeaderObj.nIncohInt = self.dataOut.nIncohInt
2520 2575 self.processingHeaderObj.totalSpectra = self.dataOut.nPairs + self.dataOut.nChannels
2521 2576 self.processingHeaderObj.shif_fft = self.dataOut.flagShiftFFT
2522 2577
2523 2578 if self.processingHeaderObj.totalSpectra > 0:
2524 2579 channelList = []
2525 2580 for channel in range(self.dataOut.nChannels):
2526 2581 channelList.append(channel)
2527 2582 channelList.append(channel)
2528 2583
2529 2584 pairsList = []
2530 2585 for pair in self.dataOut.pairsList:
2531 2586 pairsList.append(pair[0])
2532 2587 pairsList.append(pair[1])
2533 2588 spectraComb = channelList + pairsList
2534 2589 spectraComb = numpy.array(spectraComb,dtype="u1")
2535 2590 self.processingHeaderObj.spectraComb = spectraComb
2536 2591 sizeOfSpcComb = len(spectraComb)
2537 2592 processingHeaderSize += sizeOfSpcComb
2538 2593
2539 2594 # The processing header should not have information about code
2540 2595 # if self.dataOut.code != None:
2541 2596 # self.processingHeaderObj.code = self.dataOut.code
2542 2597 # self.processingHeaderObj.nCode = self.dataOut.nCode
2543 2598 # self.processingHeaderObj.nBaud = self.dataOut.nBaud
2544 2599 # nCodeSize = 4 # bytes
2545 2600 # nBaudSize = 4 # bytes
2546 2601 # codeSize = 4 # bytes
2547 2602 # sizeOfCode = int(nCodeSize + nBaudSize + codeSize * self.dataOut.nCode * self.dataOut.nBaud)
2548 2603 # processingHeaderSize += sizeOfCode
2549 2604
2550 2605 if self.processingHeaderObj.nWindows != 0:
2551 2606 self.processingHeaderObj.firstHeight = self.dataOut.heightList[0]
2552 2607 self.processingHeaderObj.deltaHeight = self.dataOut.heightList[1] - self.dataOut.heightList[0]
2553 2608 self.processingHeaderObj.nHeights = self.dataOut.nHeights
2554 2609 self.processingHeaderObj.samplesWin = self.dataOut.nHeights
2555 2610 sizeOfFirstHeight = 4
2556 2611 sizeOfdeltaHeight = 4
2557 2612 sizeOfnHeights = 4
2558 2613 sizeOfWindows = (sizeOfFirstHeight + sizeOfdeltaHeight + sizeOfnHeights)*self.processingHeaderObj.nWindows
2559 2614 processingHeaderSize += sizeOfWindows
2560 2615
2561 2616 self.processingHeaderObj.size = processingHeaderSize
2562 2617
2563 2618 class SpectraHeisWriter(Operation):
2564 2619 # set = None
2565 2620 setFile = None
2566 2621 idblock = None
2567 2622 doypath = None
2568 2623 subfolder = None
2569 2624
2570 2625 def __init__(self):
2571 2626 self.wrObj = FITS()
2572 2627 # self.dataOut = dataOut
2573 2628 self.nTotalBlocks=0
2574 2629 # self.set = None
2575 2630 self.setFile = None
2576 2631 self.idblock = 0
2577 2632 self.wrpath = None
2578 2633 self.doypath = None
2579 2634 self.subfolder = None
2580 2635 self.isConfig = False
2581 2636
2582 2637 def isNumber(str):
2583 2638 """
2584 2639 Chequea si el conjunto de caracteres que componen un string puede ser convertidos a un numero.
2585 2640
2586 2641 Excepciones:
2587 2642 Si un determinado string no puede ser convertido a numero
2588 2643 Input:
2589 2644 str, string al cual se le analiza para determinar si convertible a un numero o no
2590 2645
2591 2646 Return:
2592 2647 True : si el string es uno numerico
2593 2648 False : no es un string numerico
2594 2649 """
2595 2650 try:
2596 2651 float( str )
2597 2652 return True
2598 2653 except:
2599 2654 return False
2600 2655
2601 2656 def setup(self, dataOut, wrpath):
2602 2657
2603 2658 if not(os.path.exists(wrpath)):
2604 2659 os.mkdir(wrpath)
2605 2660
2606 2661 self.wrpath = wrpath
2607 2662 # self.setFile = 0
2608 2663 self.dataOut = dataOut
2609 2664
2610 2665 def putData(self):
2611 2666 name= time.localtime( self.dataOut.utctime)
2612 2667 ext=".fits"
2613 2668
2614 2669 if self.doypath == None:
2615 2670 self.subfolder = 'F%4.4d%3.3d_%d' % (name.tm_year,name.tm_yday,time.mktime(datetime.datetime.now().timetuple()))
2616 2671 self.doypath = os.path.join( self.wrpath, self.subfolder )
2617 2672 os.mkdir(self.doypath)
2618 2673
2619 2674 if self.setFile == None:
2620 2675 # self.set = self.dataOut.set
2621 2676 self.setFile = 0
2622 2677 # if self.set != self.dataOut.set:
2623 2678 ## self.set = self.dataOut.set
2624 2679 # self.setFile = 0
2625 2680
2626 2681 #make the filename
2627 2682 file = 'D%4.4d%3.3d_%3.3d%s' % (name.tm_year,name.tm_yday,self.setFile,ext)
2628 2683
2629 2684 filename = os.path.join(self.wrpath,self.subfolder, file)
2630 2685
2631 2686 idblock = numpy.array([self.idblock],dtype="int64")
2632 2687 header=self.wrObj.cFImage(idblock=idblock,
2633 2688 year=time.gmtime(self.dataOut.utctime).tm_year,
2634 2689 month=time.gmtime(self.dataOut.utctime).tm_mon,
2635 2690 day=time.gmtime(self.dataOut.utctime).tm_mday,
2636 2691 hour=time.gmtime(self.dataOut.utctime).tm_hour,
2637 2692 minute=time.gmtime(self.dataOut.utctime).tm_min,
2638 2693 second=time.gmtime(self.dataOut.utctime).tm_sec)
2639 2694
2640 2695 c=3E8
2641 2696 deltaHeight = self.dataOut.heightList[1] - self.dataOut.heightList[0]
2642 2697 freq=numpy.arange(-1*self.dataOut.nHeights/2.,self.dataOut.nHeights/2.)*(c/(2*deltaHeight*1000))
2643 2698
2644 2699 colList = []
2645 2700
2646 2701 colFreq=self.wrObj.setColF(name="freq", format=str(self.dataOut.nFFTPoints)+'E', array=freq)
2647 2702
2648 2703 colList.append(colFreq)
2649 2704
2650 2705 nchannel=self.dataOut.nChannels
2651 2706
2652 2707 for i in range(nchannel):
2653 2708 col = self.wrObj.writeData(name="PCh"+str(i+1),
2654 2709 format=str(self.dataOut.nFFTPoints)+'E',
2655 2710 data=10*numpy.log10(self.dataOut.data_spc[i,:]))
2656 2711
2657 2712 colList.append(col)
2658 2713
2659 2714 data=self.wrObj.Ctable(colList=colList)
2660 2715
2661 2716 self.wrObj.CFile(header,data)
2662 2717
2663 2718 self.wrObj.wFile(filename)
2664 2719
2665 2720 #update the setFile
2666 2721 self.setFile += 1
2667 2722 self.idblock += 1
2668 2723
2669 2724 return 1
2670 2725
2671 2726 def run(self, dataOut, **kwargs):
2672 2727
2673 2728 if not(self.isConfig):
2674 2729
2675 2730 self.setup(dataOut, **kwargs)
2676 2731 self.isConfig = True
2677 2732
2678 2733 self.putData()
2679 2734
2680 2735
2681 2736 class FITS:
2682 2737 name=None
2683 2738 format=None
2684 2739 array =None
2685 2740 data =None
2686 2741 thdulist=None
2687 2742 prihdr=None
2688 2743 hdu=None
2689 2744
2690 2745 def __init__(self):
2691 2746
2692 2747 pass
2693 2748
2694 2749 def setColF(self,name,format,array):
2695 2750 self.name=name
2696 2751 self.format=format
2697 2752 self.array=array
2698 2753 a1=numpy.array([self.array],dtype=numpy.float32)
2699 2754 self.col1 = pyfits.Column(name=self.name, format=self.format, array=a1)
2700 2755 return self.col1
2701 2756
2702 2757 # def setColP(self,name,format,data):
2703 2758 # self.name=name
2704 2759 # self.format=format
2705 2760 # self.data=data
2706 2761 # a2=numpy.array([self.data],dtype=numpy.float32)
2707 2762 # self.col2 = pyfits.Column(name=self.name, format=self.format, array=a2)
2708 2763 # return self.col2
2709 2764
2710 2765
2711 2766 def writeData(self,name,format,data):
2712 2767 self.name=name
2713 2768 self.format=format
2714 2769 self.data=data
2715 2770 a2=numpy.array([self.data],dtype=numpy.float32)
2716 2771 self.col2 = pyfits.Column(name=self.name, format=self.format, array=a2)
2717 2772 return self.col2
2718 2773
2719 2774 def cFImage(self,idblock,year,month,day,hour,minute,second):
2720 2775 self.hdu= pyfits.PrimaryHDU(idblock)
2721 2776 self.hdu.header.set("Year",year)
2722 2777 self.hdu.header.set("Month",month)
2723 2778 self.hdu.header.set("Day",day)
2724 2779 self.hdu.header.set("Hour",hour)
2725 2780 self.hdu.header.set("Minute",minute)
2726 2781 self.hdu.header.set("Second",second)
2727 2782 return self.hdu
2728 2783
2729 2784
2730 2785 def Ctable(self,colList):
2731 2786 self.cols=pyfits.ColDefs(colList)
2732 2787 self.tbhdu = pyfits.new_table(self.cols)
2733 2788 return self.tbhdu
2734 2789
2735 2790
2736 2791 def CFile(self,hdu,tbhdu):
2737 2792 self.thdulist=pyfits.HDUList([hdu,tbhdu])
2738 2793
2739 2794 def wFile(self,filename):
2740 2795 if os.path.isfile(filename):
2741 2796 os.remove(filename)
2742 2797 self.thdulist.writeto(filename)
2743 2798
2744 2799
2745 2800 class ParameterConf:
2746 2801 ELEMENTNAME = 'Parameter'
2747 2802 def __init__(self):
2748 2803 self.name = ''
2749 2804 self.value = ''
2750 2805
2751 2806 def readXml(self, parmElement):
2752 2807 self.name = parmElement.get('name')
2753 2808 self.value = parmElement.get('value')
2754 2809
2755 2810 def getElementName(self):
2756 2811 return self.ELEMENTNAME
2757 2812
2758 2813 class Metadata:
2759 2814
2760 2815 def __init__(self, filename):
2761 2816 self.parmConfObjList = []
2762 2817 self.readXml(filename)
2763 2818
2764 2819 def readXml(self, filename):
2765 2820 self.projectElement = None
2766 2821 self.procUnitConfObjDict = {}
2767 2822 self.projectElement = ElementTree().parse(filename)
2768 2823 self.project = self.projectElement.tag
2769 2824
2770 2825 parmElementList = self.projectElement.getiterator(ParameterConf().getElementName())
2771 2826
2772 2827 for parmElement in parmElementList:
2773 2828 parmConfObj = ParameterConf()
2774 2829 parmConfObj.readXml(parmElement)
2775 2830 self.parmConfObjList.append(parmConfObj)
2776 2831
2777 2832 class FitsWriter(Operation):
2778 2833
2779 2834 def __init__(self):
2780 2835 self.isConfig = False
2781 2836 self.dataBlocksPerFile = None
2782 2837 self.blockIndex = 0
2783 2838 self.flagIsNewFile = 1
2784 2839 self.fitsObj = None
2785 2840 self.optchar = 'P'
2786 2841 self.ext = '.fits'
2787 2842 self.setFile = 0
2788 2843
2789 2844 def setFitsHeader(self, dataOut, metadatafile):
2790 2845
2791 2846 header_data = pyfits.PrimaryHDU()
2792 2847
2793 2848 metadata4fits = Metadata(metadatafile)
2794 2849 for parameter in metadata4fits.parmConfObjList:
2795 2850 parm_name = parameter.name
2796 2851 parm_value = parameter.value
2797 2852
2798 2853 if parm_value == 'fromdatadatetime':
2799 2854 value = time.strftime("%b %d %Y %H:%M:%S", dataOut.datatime.timetuple())
2800 2855 elif parm_value == 'fromdataheights':
2801 2856 value = dataOut.nHeights
2802 2857 elif parm_value == 'fromdatachannel':
2803 2858 value = dataOut.nChannels
2804 2859 elif parm_value == 'fromdatasamples':
2805 2860 value = dataOut.nFFTPoints
2806 2861 else:
2807 2862 value = parm_value
2808 2863
2809 2864 header_data.header[parm_name] = value
2810 2865
2811 2866 header_data.header['NBLOCK'] = self.blockIndex
2812 2867
2813 2868 header_data.writeto(self.filename)
2814 2869
2815 2870
2816 2871 def setup(self, dataOut, path, dataBlocksPerFile, metadatafile):
2817 2872
2818 2873 self.path = path
2819 2874 self.dataOut = dataOut
2820 2875 self.metadatafile = metadatafile
2821 2876 self.dataBlocksPerFile = dataBlocksPerFile
2822 2877
2823 2878 def open(self):
2824 2879 self.fitsObj = pyfits.open(self.filename, mode='update')
2825 2880
2826 2881
2827 2882 def addData(self, data):
2828 2883 self.open()
2829 2884 extension = pyfits.ImageHDU(data=data, name=self.fitsObj[0].header['DATA'])
2830 2885 extension.header['UTCTIME'] = self.dataOut.utctime
2831 2886 self.fitsObj.append(extension)
2832 2887 self.blockIndex += 1
2833 2888 self.fitsObj[0].header['NBLOCK'] = self.blockIndex
2834 2889
2835 2890 self.write()
2836 2891
2837 2892 def write(self):
2838 2893
2839 2894 self.fitsObj.flush(verbose=True)
2840 2895 self.fitsObj.close()
2841 2896
2842 2897
2843 2898 def setNextFile(self):
2844 2899
2845 2900 ext = self.ext
2846 2901 path = self.path
2847 2902
2848 2903 timeTuple = time.localtime( self.dataOut.utctime)
2849 2904 subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday)
2850 2905
2851 2906 fullpath = os.path.join( path, subfolder )
2852 2907 if not( os.path.exists(fullpath) ):
2853 2908 os.mkdir(fullpath)
2854 2909 self.setFile = -1 #inicializo mi contador de seteo
2855 2910 else:
2856 2911 filesList = os.listdir( fullpath )
2857 2912 if len( filesList ) > 0:
2858 2913 filesList = sorted( filesList, key=str.lower )
2859 2914 filen = filesList[-1]
2860 2915
2861 2916 if isNumber( filen[8:11] ):
2862 2917 self.setFile = int( filen[8:11] ) #inicializo mi contador de seteo al seteo del ultimo file
2863 2918 else:
2864 2919 self.setFile = -1
2865 2920 else:
2866 2921 self.setFile = -1 #inicializo mi contador de seteo
2867 2922
2868 2923 setFile = self.setFile
2869 2924 setFile += 1
2870 2925
2871 2926 file = '%s%4.4d%3.3d%3.3d%s' % (self.optchar,
2872 2927 timeTuple.tm_year,
2873 2928 timeTuple.tm_yday,
2874 2929 setFile,
2875 2930 ext )
2876 2931
2877 2932 filename = os.path.join( path, subfolder, file )
2878 2933
2879 2934 self.blockIndex = 0
2880 2935 self.filename = filename
2881 2936 self.setFile = setFile
2882 2937 self.flagIsNewFile = 1
2883 2938
2884 2939 print 'Writing the file: %s'%self.filename
2885 2940
2886 2941 self.setFitsHeader(self.dataOut, self.metadatafile)
2887 2942
2888 2943 return 1
2889 2944
2890 2945 def writeBlock(self):
2891 2946 self.addData(self.dataOut.data_spc)
2892 2947 self.flagIsNewFile = 0
2893 2948
2894 2949
2895 2950 def __setNewBlock(self):
2896 2951
2897 2952 if self.flagIsNewFile:
2898 2953 return 1
2899 2954
2900 2955 if self.blockIndex < self.dataBlocksPerFile:
2901 2956 return 1
2902 2957
2903 2958 if not( self.setNextFile() ):
2904 2959 return 0
2905 2960
2906 2961 return 1
2907 2962
2908 2963 def writeNextBlock(self):
2909 2964 if not( self.__setNewBlock() ):
2910 2965 return 0
2911 2966 self.writeBlock()
2912 2967 return 1
2913 2968
2914 2969 def putData(self):
2915 2970 if self.flagIsNewFile:
2916 2971 self.setNextFile()
2917 2972 self.writeNextBlock()
2918 2973
2919 2974 def run(self, dataOut, **kwargs):
2920 2975 if not(self.isConfig):
2921 2976 self.setup(dataOut, **kwargs)
2922 2977 self.isConfig = True
2923 2978 self.putData()
2924 2979
2925 2980
2926 2981 class FitsReader(ProcessingUnit):
2927 2982
2928 2983 __TIMEZONE = time.timezone
2929 2984
2930 2985 expName = None
2931 2986 datetimestr = None
2932 2987 utc = None
2933 2988 nChannels = None
2934 2989 nSamples = None
2935 2990 dataBlocksPerFile = None
2936 2991 comments = None
2937 2992 lastUTTime = None
2938 2993 header_dict = None
2939 2994 data = None
2940 2995 data_header_dict = None
2941 2996
2942 2997 def __init__(self):
2943 2998 self.isConfig = False
2944 2999 self.ext = '.fits'
2945 3000 self.setFile = 0
2946 3001 self.flagNoMoreFiles = 0
2947 3002 self.flagIsNewFile = 1
2948 3003 self.flagTimeBlock = None
2949 3004 self.fileIndex = None
2950 3005 self.filename = None
2951 3006 self.fileSize = None
2952 3007 self.fitsObj = None
2953 3008 self.nReadBlocks = 0
2954 3009 self.nTotalBlocks = 0
2955 3010 self.dataOut = self.createObjByDefault()
2956 3011 self.maxTimeStep = 10# deberia ser definido por el usuario usando el metodo setup()
2957 3012 self.blockIndex = 1
2958 3013
2959 3014 def createObjByDefault(self):
2960 3015
2961 3016 dataObj = Fits()
2962 3017
2963 3018 return dataObj
2964 3019
2965 3020 def isFileinThisTime(self, filename, startTime, endTime, useLocalTime=False):
2966 3021 try:
2967 3022 fitsObj = pyfits.open(filename,'readonly')
2968 3023 except:
2969 3024 raise IOError, "The file %s can't be opened" %(filename)
2970 3025
2971 3026 header = fitsObj[0].header
2972 3027 struct_time = time.strptime(header['DATETIME'], "%b %d %Y %H:%M:%S")
2973 3028 utc = time.mktime(struct_time) - time.timezone #TIMEZONE debe ser un parametro del header FITS
2974 3029
2975 3030 ltc = utc
2976 3031 if useLocalTime:
2977 3032 ltc -= time.timezone
2978 3033 thisDatetime = datetime.datetime.utcfromtimestamp(ltc)
2979 3034 thisTime = thisDatetime.time()
2980 3035
2981 3036 if not ((startTime <= thisTime) and (endTime > thisTime)):
2982 3037 return None
2983 3038
2984 3039 return thisDatetime
2985 3040
2986 3041 def __setNextFileOnline(self):
2987 3042 raise ValueError, "No implemented"
2988 3043
2989 3044 def __setNextFileOffline(self):
2990 3045 idFile = self.fileIndex
2991 3046
2992 3047 while (True):
2993 3048 idFile += 1
2994 3049 if not(idFile < len(self.filenameList)):
2995 3050 self.flagNoMoreFiles = 1
2996 3051 print "No more Files"
2997 3052 return 0
2998 3053
2999 3054 filename = self.filenameList[idFile]
3000 3055
3001 3056 # if not(self.__verifyFile(filename)):
3002 3057 # continue
3003 3058
3004 3059 fileSize = os.path.getsize(filename)
3005 3060 fitsObj = pyfits.open(filename,'readonly')
3006 3061 break
3007 3062
3008 3063 self.flagIsNewFile = 1
3009 3064 self.fileIndex = idFile
3010 3065 self.filename = filename
3011 3066 self.fileSize = fileSize
3012 3067 self.fitsObj = fitsObj
3013 3068
3014 3069 print "Setting the file: %s"%self.filename
3015 3070
3016 3071 return 1
3017 3072
3018 3073 def readHeader(self):
3019 3074 headerObj = self.fitsObj[0]
3020 3075
3021 3076 self.header_dict = headerObj.header
3022 3077 self.expName = headerObj.header['EXPNAME']
3023 3078 self.datetimestr = headerObj.header['DATETIME']
3024 3079 struct_time = time.strptime(headerObj.header['DATETIME'], "%b %d %Y %H:%M:%S")
3025 3080 # self.utc = time.mktime(struct_time) - self.__TIMEZONE
3026 3081 self.nChannels = headerObj.header['NCHANNEL']
3027 3082 self.nSamples = headerObj.header['NSAMPLE']
3028 3083 self.dataBlocksPerFile = headerObj.header['NBLOCK']
3029 3084 self.comments = headerObj.header['COMMENT']
3030 3085
3031 3086
3032 3087 def setNextFile(self):
3033 3088
3034 3089 if self.online:
3035 3090 newFile = self.__setNextFileOnline()
3036 3091 else:
3037 3092 newFile = self.__setNextFileOffline()
3038 3093
3039 3094 if not(newFile):
3040 3095 return 0
3041 3096
3042 3097 self.readHeader()
3043 3098
3044 3099 self.nReadBlocks = 0
3045 3100 self.blockIndex = 1
3046 3101 return 1
3047 3102
3048 3103 def __searchFilesOffLine(self,
3049 3104 path,
3050 3105 startDate,
3051 3106 endDate,
3052 3107 startTime=datetime.time(0,0,0),
3053 3108 endTime=datetime.time(23,59,59),
3054 3109 set=None,
3055 3110 expLabel='',
3056 3111 ext='.fits',
3057 3112 walk=True):
3058 3113
3059 3114 pathList = []
3060 3115
3061 3116 if not walk:
3062 3117 pathList.append(path)
3063 3118
3064 3119 else:
3065 3120 dirList = []
3066 3121 for thisPath in os.listdir(path):
3067 3122 if not os.path.isdir(os.path.join(path,thisPath)):
3068 3123 continue
3069 3124 if not isDoyFolder(thisPath):
3070 3125 continue
3071 3126
3072 3127 dirList.append(thisPath)
3073 3128
3074 3129 if not(dirList):
3075 3130 return None, None
3076 3131
3077 3132 thisDate = startDate
3078 3133
3079 3134 while(thisDate <= endDate):
3080 3135 year = thisDate.timetuple().tm_year
3081 3136 doy = thisDate.timetuple().tm_yday
3082 3137
3083 3138 matchlist = fnmatch.filter(dirList, '?' + '%4.4d%3.3d' % (year,doy) + '*')
3084 3139 if len(matchlist) == 0:
3085 3140 thisDate += datetime.timedelta(1)
3086 3141 continue
3087 3142 for match in matchlist:
3088 3143 pathList.append(os.path.join(path,match,expLabel))
3089 3144
3090 3145 thisDate += datetime.timedelta(1)
3091 3146
3092 3147 if pathList == []:
3093 3148 print "Any folder was found for the date range: %s-%s" %(startDate, endDate)
3094 3149 return None, None
3095 3150
3096 3151 print "%d folder(s) was(were) found for the date range: %s - %s" %(len(pathList), startDate, endDate)
3097 3152
3098 3153 filenameList = []
3099 3154 datetimeList = []
3100 3155
3101 3156 for i in range(len(pathList)):
3102 3157
3103 3158 thisPath = pathList[i]
3104 3159
3105 3160 fileList = glob.glob1(thisPath, "*%s" %ext)
3106 3161 fileList.sort()
3107 3162
3108 3163 for file in fileList:
3109 3164
3110 3165 filename = os.path.join(thisPath,file)
3111 3166 thisDatetime = self.isFileinThisTime(filename, startTime, endTime, useLocalTime=True)
3112 3167
3113 3168 if not(thisDatetime):
3114 3169 continue
3115 3170
3116 3171 filenameList.append(filename)
3117 3172 datetimeList.append(thisDatetime)
3118 3173
3119 3174 if not(filenameList):
3120 3175 print "Any file was found for the time range %s - %s" %(startTime, endTime)
3121 3176 return None, None
3122 3177
3123 3178 print "%d file(s) was(were) found for the time range: %s - %s" %(len(filenameList), startTime, endTime)
3124 3179 print
3125 3180
3126 3181 for i in range(len(filenameList)):
3127 3182 print "%s -> [%s]" %(filenameList[i], datetimeList[i].ctime())
3128 3183
3129 3184 self.filenameList = filenameList
3130 3185 self.datetimeList = datetimeList
3131 3186
3132 3187 return pathList, filenameList
3133 3188
3134 3189 def setup(self, path=None,
3135 3190 startDate=None,
3136 3191 endDate=None,
3137 3192 startTime=datetime.time(0,0,0),
3138 3193 endTime=datetime.time(23,59,59),
3139 3194 set=0,
3140 3195 expLabel = "",
3141 3196 ext = None,
3142 3197 online = False,
3143 3198 delay = 60,
3144 3199 walk = True):
3145 3200
3146 3201 if path == None:
3147 3202 raise ValueError, "The path is not valid"
3148 3203
3149 3204 if ext == None:
3150 3205 ext = self.ext
3151 3206
3152 3207 if not(online):
3153 3208 print "Searching files in offline mode ..."
3154 3209 pathList, filenameList = self.__searchFilesOffLine(path, startDate=startDate, endDate=endDate,
3155 3210 startTime=startTime, endTime=endTime,
3156 3211 set=set, expLabel=expLabel, ext=ext,
3157 3212 walk=walk)
3158 3213
3159 3214 if not(pathList):
3160 3215 print "No *%s files into the folder %s \nfor the range: %s - %s"%(ext, path,
3161 3216 datetime.datetime.combine(startDate,startTime).ctime(),
3162 3217 datetime.datetime.combine(endDate,endTime).ctime())
3163 3218
3164 3219 sys.exit(-1)
3165 3220
3166 3221 self.fileIndex = -1
3167 3222 self.pathList = pathList
3168 3223 self.filenameList = filenameList
3169 3224
3170 3225 self.online = online
3171 3226 self.delay = delay
3172 3227 ext = ext.lower()
3173 3228 self.ext = ext
3174 3229
3175 3230 if not(self.setNextFile()):
3176 3231 if (startDate!=None) and (endDate!=None):
3177 3232 print "No files in range: %s - %s" %(datetime.datetime.combine(startDate,startTime).ctime(), datetime.datetime.combine(endDate,endTime).ctime())
3178 3233 elif startDate != None:
3179 3234 print "No files in range: %s" %(datetime.datetime.combine(startDate,startTime).ctime())
3180 3235 else:
3181 3236 print "No files"
3182 3237
3183 3238 sys.exit(-1)
3184 3239
3185 3240
3186 3241
3187 3242 def readBlock(self):
3188 3243 dataObj = self.fitsObj[self.blockIndex]
3189 3244
3190 3245 self.data = dataObj.data
3191 3246 self.data_header_dict = dataObj.header
3192 3247 self.utc = self.data_header_dict['UTCTIME']
3193 3248
3194 3249 self.flagIsNewFile = 0
3195 3250 self.blockIndex += 1
3196 3251 self.nTotalBlocks += 1
3197 3252 self.nReadBlocks += 1
3198 3253
3199 3254 return 1
3200 3255
3201 3256 def __jumpToLastBlock(self):
3202 3257 raise ValueError, "No implemented"
3203 3258
3204 3259 def __waitNewBlock(self):
3205 3260 """
3206 3261 Return 1 si se encontro un nuevo bloque de datos, 0 de otra forma.
3207 3262
3208 3263 Si el modo de lectura es OffLine siempre retorn 0
3209 3264 """
3210 3265 if not self.online:
3211 3266 return 0
3212 3267
3213 3268 if (self.nReadBlocks >= self.processingHeaderObj.dataBlocksPerFile):
3214 3269 return 0
3215 3270
3216 3271 currentPointer = self.fp.tell()
3217 3272
3218 3273 neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize
3219 3274
3220 3275 for nTries in range( self.nTries ):
3221 3276
3222 3277 self.fp.close()
3223 3278 self.fp = open( self.filename, 'rb' )
3224 3279 self.fp.seek( currentPointer )
3225 3280
3226 3281 self.fileSize = os.path.getsize( self.filename )
3227 3282 currentSize = self.fileSize - currentPointer
3228 3283
3229 3284 if ( currentSize >= neededSize ):
3230 3285 self.__rdBasicHeader()
3231 3286 return 1
3232 3287
3233 3288 print "\tWaiting %0.2f seconds for the next block, try %03d ..." % (self.delay, nTries+1)
3234 3289 time.sleep( self.delay )
3235 3290
3236 3291
3237 3292 return 0
3238 3293
3239 3294 def __setNewBlock(self):
3240 3295
3241 3296 if self.online:
3242 3297 self.__jumpToLastBlock()
3243 3298
3244 3299 if self.flagIsNewFile:
3245 3300 return 1
3246 3301
3247 3302 self.lastUTTime = self.utc
3248 3303
3249 3304 if self.online:
3250 3305 if self.__waitNewBlock():
3251 3306 return 1
3252 3307
3253 3308 if self.nReadBlocks < self.dataBlocksPerFile:
3254 3309 return 1
3255 3310
3256 3311 if not(self.setNextFile()):
3257 3312 return 0
3258 3313
3259 3314 deltaTime = self.utc - self.lastUTTime
3260 3315
3261 3316 self.flagTimeBlock = 0
3262 3317
3263 3318 if deltaTime > self.maxTimeStep:
3264 3319 self.flagTimeBlock = 1
3265 3320
3266 3321 return 1
3267 3322
3268 3323
3269 3324 def readNextBlock(self):
3270 3325 if not(self.__setNewBlock()):
3271 3326 return 0
3272 3327
3273 3328 if not(self.readBlock()):
3274 3329 return 0
3275 3330
3276 3331 return 1
3277 3332
3278 3333
3279 3334 def getData(self):
3280 3335
3281 3336 if self.flagNoMoreFiles:
3282 3337 self.dataOut.flagNoData = True
3283 3338 print 'Process finished'
3284 3339 return 0
3285 3340
3286 3341 self.flagTimeBlock = 0
3287 3342 self.flagIsNewBlock = 0
3288 3343
3289 3344 if not(self.readNextBlock()):
3290 3345 return 0
3291 3346
3292 3347 if self.data == None:
3293 3348 self.dataOut.flagNoData = True
3294 3349 return 0
3295 3350
3296 3351 self.dataOut.data = self.data
3297 3352 self.dataOut.data_header = self.data_header_dict
3298 3353 self.dataOut.utctime = self.utc
3299 3354
3300 3355 self.dataOut.header = self.header_dict
3301 3356 self.dataOut.expName = self.expName
3302 3357 self.dataOut.nChannels = self.nChannels
3303 3358 self.dataOut.nSamples = self.nSamples
3304 3359 self.dataOut.dataBlocksPerFile = self.dataBlocksPerFile
3305 3360 self.dataOut.comments = self.comments
3306 3361
3307 3362 self.dataOut.flagNoData = False
3308 3363
3309 3364 return self.dataOut.data
3310 3365
3311 3366 def run(self, **kwargs):
3312 3367
3313 3368 if not(self.isConfig):
3314 3369 self.setup(**kwargs)
3315 3370 self.isConfig = True
3316 3371
3317 3372 self.getData() No newline at end of file
@@ -1,1354 +1,1355
1 1 import numpy
2 2 import time, datetime, os
3 3 from graphics.figure import *
4 4 def isRealtime(utcdatatime):
5 5 utcnow = time.mktime(datetime.datetime.utcnow().timetuple())
6 6 delta = utcnow - utcdatatime # abs
7 7 if delta >= 5*60.:
8 8 return False
9 9 return True
10 10
11 11 class CrossSpectraPlot(Figure):
12 12
13 13 __isConfig = None
14 14 __nsubplots = None
15 15
16 16 WIDTH = None
17 17 HEIGHT = None
18 18 WIDTHPROF = None
19 19 HEIGHTPROF = None
20 20 PREFIX = 'cspc'
21 21
22 22 def __init__(self):
23 23
24 24 self.__isConfig = False
25 25 self.__nsubplots = 4
26 26
27 27 self.WIDTH = 250
28 28 self.HEIGHT = 250
29 29 self.WIDTHPROF = 0
30 30 self.HEIGHTPROF = 0
31 31
32 32 def getSubplots(self):
33 33
34 34 ncol = 4
35 35 nrow = self.nplots
36 36
37 37 return nrow, ncol
38 38
39 39 def setup(self, idfigure, nplots, wintitle, showprofile=True, show=True):
40 40
41 41 self.__showprofile = showprofile
42 42 self.nplots = nplots
43 43
44 44 ncolspan = 1
45 45 colspan = 1
46 46
47 47 self.createFigure(idfigure = idfigure,
48 48 wintitle = wintitle,
49 49 widthplot = self.WIDTH + self.WIDTHPROF,
50 50 heightplot = self.HEIGHT + self.HEIGHTPROF,
51 51 show=True)
52 52
53 53 nrow, ncol = self.getSubplots()
54 54
55 55 counter = 0
56 56 for y in range(nrow):
57 57 for x in range(ncol):
58 58 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
59 59
60 60 counter += 1
61 61
62 62 def run(self, dataOut, idfigure, wintitle="", pairsList=None, showprofile='True',
63 63 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
64 64 save=False, figpath='./', figfile=None,
65 65 power_cmap='jet', coherence_cmap='jet', phase_cmap='RdBu_r', show=True):
66 66
67 67 """
68 68
69 69 Input:
70 70 dataOut :
71 71 idfigure :
72 72 wintitle :
73 73 channelList :
74 74 showProfile :
75 75 xmin : None,
76 76 xmax : None,
77 77 ymin : None,
78 78 ymax : None,
79 79 zmin : None,
80 80 zmax : None
81 81 """
82 82
83 83 if pairsList == None:
84 84 pairsIndexList = dataOut.pairsIndexList
85 85 else:
86 86 pairsIndexList = []
87 87 for pair in pairsList:
88 88 if pair not in dataOut.pairsList:
89 89 raise ValueError, "Pair %s is not in dataOut.pairsList" %(pair)
90 90 pairsIndexList.append(dataOut.pairsList.index(pair))
91 91
92 92 if pairsIndexList == []:
93 93 return
94 94
95 95 if len(pairsIndexList) > 4:
96 96 pairsIndexList = pairsIndexList[0:4]
97 97 factor = dataOut.normFactor
98 98 x = dataOut.getVelRange(1)
99 99 y = dataOut.getHeiRange()
100 100 z = dataOut.data_spc[:,:,:]/factor
101 101 # z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
102 102 avg = numpy.abs(numpy.average(z, axis=1))
103 103 noise = dataOut.getNoise()/factor
104 104
105 105 zdB = 10*numpy.log10(z)
106 106 avgdB = 10*numpy.log10(avg)
107 107 noisedB = 10*numpy.log10(noise)
108 108
109 109
110 110 thisDatetime = dataOut.datatime
111 111 title = "Cross-Spectra: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
112 112 xlabel = "Velocity (m/s)"
113 113 ylabel = "Range (Km)"
114 114
115 115 if not self.__isConfig:
116 116
117 117 nplots = len(pairsIndexList)
118 118
119 119 self.setup(idfigure=idfigure,
120 120 nplots=nplots,
121 121 wintitle=wintitle,
122 122 showprofile=showprofile,
123 123 show=show)
124 124
125 125 if xmin == None: xmin = numpy.nanmin(x)
126 126 if xmax == None: xmax = numpy.nanmax(x)
127 127 if ymin == None: ymin = numpy.nanmin(y)
128 128 if ymax == None: ymax = numpy.nanmax(y)
129 129 if zmin == None: zmin = numpy.nanmin(avgdB)*0.9
130 130 if zmax == None: zmax = numpy.nanmax(avgdB)*0.9
131 131
132 132 self.__isConfig = True
133 133
134 134 self.setWinTitle(title)
135 135
136 136 for i in range(self.nplots):
137 137 pair = dataOut.pairsList[pairsIndexList[i]]
138 138
139 139 title = "Channel %d: %4.2fdB" %(pair[0], noisedB[pair[0]])
140 140 zdB = 10.*numpy.log10(dataOut.data_spc[pair[0],:,:]/factor)
141 141 axes0 = self.axesList[i*self.__nsubplots]
142 142 axes0.pcolor(x, y, zdB,
143 143 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
144 144 xlabel=xlabel, ylabel=ylabel, title=title,
145 145 ticksize=9, colormap=power_cmap, cblabel='')
146 146
147 147 title = "Channel %d: %4.2fdB" %(pair[1], noisedB[pair[1]])
148 148 zdB = 10.*numpy.log10(dataOut.data_spc[pair[1],:,:]/factor)
149 149 axes0 = self.axesList[i*self.__nsubplots+1]
150 150 axes0.pcolor(x, y, zdB,
151 151 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
152 152 xlabel=xlabel, ylabel=ylabel, title=title,
153 153 ticksize=9, colormap=power_cmap, cblabel='')
154 154
155 155 coherenceComplex = dataOut.data_cspc[pairsIndexList[i],:,:]/numpy.sqrt(dataOut.data_spc[pair[0],:,:]*dataOut.data_spc[pair[1],:,:])
156 156 coherence = numpy.abs(coherenceComplex)
157 157 # phase = numpy.arctan(-1*coherenceComplex.imag/coherenceComplex.real)*180/numpy.pi
158 158 phase = numpy.arctan2(coherenceComplex.imag, coherenceComplex.real)*180/numpy.pi
159 159
160 160 title = "Coherence %d%d" %(pair[0], pair[1])
161 161 axes0 = self.axesList[i*self.__nsubplots+2]
162 162 axes0.pcolor(x, y, coherence,
163 163 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=0, zmax=1,
164 164 xlabel=xlabel, ylabel=ylabel, title=title,
165 165 ticksize=9, colormap=coherence_cmap, cblabel='')
166 166
167 167 title = "Phase %d%d" %(pair[0], pair[1])
168 168 axes0 = self.axesList[i*self.__nsubplots+3]
169 169 axes0.pcolor(x, y, phase,
170 170 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=-180, zmax=180,
171 171 xlabel=xlabel, ylabel=ylabel, title=title,
172 172 ticksize=9, colormap=phase_cmap, cblabel='')
173 173
174 174
175 175
176 176 self.draw()
177 177
178 178 if save:
179 179 date = thisDatetime.strftime("%Y%m%d_%H%M%S")
180 180 if figfile == None:
181 181 figfile = self.getFilename(name = date)
182 182
183 183 self.saveFigure(figpath, figfile)
184 184
185 185
186 186 class RTIPlot(Figure):
187 187
188 188 __isConfig = None
189 189 __nsubplots = None
190 190
191 191 WIDTHPROF = None
192 192 HEIGHTPROF = None
193 193 PREFIX = 'rti'
194 194
195 195 def __init__(self):
196 196
197 197 self.timerange = 2*60*60
198 198 self.__isConfig = False
199 199 self.__nsubplots = 1
200 200
201 201 self.WIDTH = 800
202 202 self.HEIGHT = 150
203 203 self.WIDTHPROF = 120
204 204 self.HEIGHTPROF = 0
205 205 self.counterftp = 0
206 206
207 207 def getSubplots(self):
208 208
209 209 ncol = 1
210 210 nrow = self.nplots
211 211
212 212 return nrow, ncol
213 213
214 214 def setup(self, idfigure, nplots, wintitle, showprofile=True, show=True):
215 215
216 216 self.__showprofile = showprofile
217 217 self.nplots = nplots
218 218
219 219 ncolspan = 1
220 220 colspan = 1
221 221 if showprofile:
222 222 ncolspan = 7
223 223 colspan = 6
224 224 self.__nsubplots = 2
225 225
226 226 self.createFigure(idfigure = idfigure,
227 227 wintitle = wintitle,
228 228 widthplot = self.WIDTH + self.WIDTHPROF,
229 229 heightplot = self.HEIGHT + self.HEIGHTPROF,
230 230 show=show)
231 231
232 232 nrow, ncol = self.getSubplots()
233 233
234 234 counter = 0
235 235 for y in range(nrow):
236 236 for x in range(ncol):
237 237
238 238 if counter >= self.nplots:
239 239 break
240 240
241 241 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
242 242
243 243 if showprofile:
244 244 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
245 245
246 246 counter += 1
247 247
248 248 def run(self, dataOut, idfigure, wintitle="", channelList=None, showprofile='True',
249 249 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
250 250 timerange=None,
251 251 save=False, figpath='./', figfile=None, ftp=False, ftpratio=1, show=True):
252 252
253 253 """
254 254
255 255 Input:
256 256 dataOut :
257 257 idfigure :
258 258 wintitle :
259 259 channelList :
260 260 showProfile :
261 261 xmin : None,
262 262 xmax : None,
263 263 ymin : None,
264 264 ymax : None,
265 265 zmin : None,
266 266 zmax : None
267 267 """
268 268
269 269 if channelList == None:
270 270 channelIndexList = dataOut.channelIndexList
271 271 else:
272 272 channelIndexList = []
273 273 for channel in channelList:
274 274 if channel not in dataOut.channelList:
275 275 raise ValueError, "Channel %d is not in dataOut.channelList"
276 276 channelIndexList.append(dataOut.channelList.index(channel))
277 277
278 278 if timerange != None:
279 279 self.timerange = timerange
280 280
281 281 tmin = None
282 282 tmax = None
283 283 factor = dataOut.normFactor
284 284 x = dataOut.getTimeRange()
285 285 y = dataOut.getHeiRange()
286 286
287 287 z = dataOut.data_spc[channelIndexList,:,:]/factor
288 288 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
289 289 avg = numpy.average(z, axis=1)
290 290
291 291 avgdB = 10.*numpy.log10(avg)
292 292
293 293
294 thisDatetime = dataOut.datatime
295 title = "RTI: %s" %(thisDatetime.strftime("%d-%b-%Y"))
294 # thisDatetime = dataOut.datatime
295 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[1])
296 title = wintitle+' ' + "RTI: %s" %(thisDatetime.strftime("%d-%b-%Y"))
296 297 xlabel = ""
297 298 ylabel = "Range (Km)"
298 299
299 300 if not self.__isConfig:
300 301
301 302 nplots = len(channelIndexList)
302 303
303 304 self.setup(idfigure=idfigure,
304 305 nplots=nplots,
305 306 wintitle=wintitle,
306 307 showprofile=showprofile,
307 308 show=show)
308 309
309 310 tmin, tmax = self.getTimeLim(x, xmin, xmax)
310 311 if ymin == None: ymin = numpy.nanmin(y)
311 312 if ymax == None: ymax = numpy.nanmax(y)
312 313 if zmin == None: zmin = numpy.nanmin(avgdB)*0.9
313 314 if zmax == None: zmax = numpy.nanmax(avgdB)*0.9
314 315
315 316 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
316 317 self.__isConfig = True
317 318
318 319
319 320 self.setWinTitle(title)
320 321
321 322 for i in range(self.nplots):
322 323 title = "Channel %d: %s" %(dataOut.channelList[i], thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
323 324 axes = self.axesList[i*self.__nsubplots]
324 325 zdB = avgdB[i].reshape((1,-1))
325 326 axes.pcolorbuffer(x, y, zdB,
326 327 xmin=tmin, xmax=tmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
327 328 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
328 329 ticksize=9, cblabel='', cbsize="1%")
329 330
330 331 if self.__showprofile:
331 332 axes = self.axesList[i*self.__nsubplots +1]
332 333 axes.pline(avgdB[i], y,
333 334 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
334 335 xlabel='dB', ylabel='', title='',
335 336 ytick_visible=False,
336 337 grid='x')
337 338
338 339 self.draw()
339 340
340 341 if save:
341 342
342 343 if figfile == None:
343 344 figfile = self.getFilename(name = self.name)
344 345
345 346 self.saveFigure(figpath, figfile)
346 347
347 348 self.counterftp += 1
348 349 if (ftp and (self.counterftp==ftpratio)):
349 350 figfilename = os.path.join(figpath,figfile)
350 351 self.sendByFTP(figfilename)
351 352 self.counterftp = 0
352 353
353 354 if x[1] + (x[1]-x[0]) >= self.axesList[0].xmax:
354 355 self.__isConfig = False
355 356
356 357 class SpectraPlot(Figure):
357 358
358 359 __isConfig = None
359 360 __nsubplots = None
360 361
361 362 WIDTHPROF = None
362 363 HEIGHTPROF = None
363 364 PREFIX = 'spc'
364 365
365 366 def __init__(self):
366 367
367 368 self.__isConfig = False
368 369 self.__nsubplots = 1
369 370
370 371 self.WIDTH = 230
371 372 self.HEIGHT = 250
372 373 self.WIDTHPROF = 120
373 374 self.HEIGHTPROF = 0
374 375
375 376 def getSubplots(self):
376 377
377 378 ncol = int(numpy.sqrt(self.nplots)+0.9)
378 379 nrow = int(self.nplots*1./ncol + 0.9)
379 380
380 381 return nrow, ncol
381 382
382 383 def setup(self, idfigure, nplots, wintitle, showprofile=True, show=True):
383 384
384 385 self.__showprofile = showprofile
385 386 self.nplots = nplots
386 387
387 388 ncolspan = 1
388 389 colspan = 1
389 390 if showprofile:
390 391 ncolspan = 3
391 392 colspan = 2
392 393 self.__nsubplots = 2
393 394
394 395 self.createFigure(idfigure = idfigure,
395 396 wintitle = wintitle,
396 397 widthplot = self.WIDTH + self.WIDTHPROF,
397 398 heightplot = self.HEIGHT + self.HEIGHTPROF,
398 399 show=show)
399 400
400 401 nrow, ncol = self.getSubplots()
401 402
402 403 counter = 0
403 404 for y in range(nrow):
404 405 for x in range(ncol):
405 406
406 407 if counter >= self.nplots:
407 408 break
408 409
409 410 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
410 411
411 412 if showprofile:
412 413 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
413 414
414 415 counter += 1
415 416
416 417 def run(self, dataOut, idfigure, wintitle="", channelList=None, showprofile='True',
417 418 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
418 419 save=False, figpath='./', figfile=None, show=True):
419 420
420 421 """
421 422
422 423 Input:
423 424 dataOut :
424 425 idfigure :
425 426 wintitle :
426 427 channelList :
427 428 showProfile :
428 429 xmin : None,
429 430 xmax : None,
430 431 ymin : None,
431 432 ymax : None,
432 433 zmin : None,
433 434 zmax : None
434 435 """
435 436
436 437 if channelList == None:
437 438 channelIndexList = dataOut.channelIndexList
438 439 else:
439 440 channelIndexList = []
440 441 for channel in channelList:
441 442 if channel not in dataOut.channelList:
442 443 raise ValueError, "Channel %d is not in dataOut.channelList"
443 444 channelIndexList.append(dataOut.channelList.index(channel))
444 445 factor = dataOut.normFactor
445 446 x = dataOut.getVelRange(1)
446 447 y = dataOut.getHeiRange()
447 448
448 449 z = dataOut.data_spc[channelIndexList,:,:]/factor
449 450 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
450 451 avg = numpy.average(z, axis=1)
451 452 noise = dataOut.getNoise()/factor
452 453
453 454 zdB = 10*numpy.log10(z)
454 455 avgdB = 10*numpy.log10(avg)
455 456 noisedB = 10*numpy.log10(noise)
456 457
457 458 thisDatetime = dataOut.datatime
458 459 title = "Spectra: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
459 460 xlabel = "Velocity (m/s)"
460 461 ylabel = "Range (Km)"
461 462
462 463 if not self.__isConfig:
463 464
464 465 nplots = len(channelIndexList)
465 466
466 467 self.setup(idfigure=idfigure,
467 468 nplots=nplots,
468 469 wintitle=wintitle,
469 470 showprofile=showprofile,
470 471 show=show)
471 472
472 473 if xmin == None: xmin = numpy.nanmin(x)
473 474 if xmax == None: xmax = numpy.nanmax(x)
474 475 if ymin == None: ymin = numpy.nanmin(y)
475 476 if ymax == None: ymax = numpy.nanmax(y)
476 477 if zmin == None: zmin = numpy.nanmin(avgdB)*0.9
477 478 if zmax == None: zmax = numpy.nanmax(avgdB)*0.9
478 479
479 480 self.__isConfig = True
480 481
481 482 self.setWinTitle(title)
482 483
483 484 for i in range(self.nplots):
484 485 title = "Channel %d: %4.2fdB" %(dataOut.channelList[i], noisedB[i])
485 486 axes = self.axesList[i*self.__nsubplots]
486 487 axes.pcolor(x, y, zdB[i,:,:],
487 488 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
488 489 xlabel=xlabel, ylabel=ylabel, title=title,
489 490 ticksize=9, cblabel='')
490 491
491 492 if self.__showprofile:
492 493 axes = self.axesList[i*self.__nsubplots +1]
493 494 axes.pline(avgdB[i], y,
494 495 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
495 496 xlabel='dB', ylabel='', title='',
496 497 ytick_visible=False,
497 498 grid='x')
498 499
499 500 noiseline = numpy.repeat(noisedB[i], len(y))
500 501 axes.addpline(noiseline, y, idline=1, color="black", linestyle="dashed", lw=2)
501 502
502 503 self.draw()
503 504
504 505 if save:
505 506 date = thisDatetime.strftime("%Y%m%d_%H%M%S")
506 507 if figfile == None:
507 508 figfile = self.getFilename(name = date)
508
509
509 510 self.saveFigure(figpath, figfile)
510 511
511 512 class Scope(Figure):
512 513
513 514 __isConfig = None
514 515
515 516 def __init__(self):
516 517
517 518 self.__isConfig = False
518 519 self.WIDTH = 600
519 520 self.HEIGHT = 200
520 521
521 522 def getSubplots(self):
522 523
523 524 nrow = self.nplots
524 525 ncol = 3
525 526 return nrow, ncol
526 527
527 528 def setup(self, idfigure, nplots, wintitle, show):
528 529
529 530 self.nplots = nplots
530 531
531 532 self.createFigure(idfigure=idfigure,
532 533 wintitle=wintitle,
533 534 show=show)
534 535
535 536 nrow,ncol = self.getSubplots()
536 537 colspan = 3
537 538 rowspan = 1
538 539
539 540 for i in range(nplots):
540 541 self.addAxes(nrow, ncol, i, 0, colspan, rowspan)
541 542
542 543
543 544
544 545 def run(self, dataOut, idfigure, wintitle="", channelList=None,
545 546 xmin=None, xmax=None, ymin=None, ymax=None, save=False,
546 547 figpath='./', figfile=None, show=True):
547 548
548 549 """
549 550
550 551 Input:
551 552 dataOut :
552 553 idfigure :
553 554 wintitle :
554 555 channelList :
555 556 xmin : None,
556 557 xmax : None,
557 558 ymin : None,
558 559 ymax : None,
559 560 """
560 561
561 562 if channelList == None:
562 563 channelIndexList = dataOut.channelIndexList
563 564 else:
564 565 channelIndexList = []
565 566 for channel in channelList:
566 567 if channel not in dataOut.channelList:
567 568 raise ValueError, "Channel %d is not in dataOut.channelList"
568 569 channelIndexList.append(dataOut.channelList.index(channel))
569 570
570 571 x = dataOut.heightList
571 572 y = dataOut.data[channelIndexList,:] * numpy.conjugate(dataOut.data[channelIndexList,:])
572 573 y = y.real
573 574
574 575 thisDatetime = dataOut.datatime
575 576 title = "Scope: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
576 577 xlabel = "Range (Km)"
577 578 ylabel = "Intensity"
578 579
579 580 if not self.__isConfig:
580 581 nplots = len(channelIndexList)
581 582
582 583 self.setup(idfigure=idfigure,
583 584 nplots=nplots,
584 585 wintitle=wintitle,
585 586 show=show)
586 587
587 588 if xmin == None: xmin = numpy.nanmin(x)
588 589 if xmax == None: xmax = numpy.nanmax(x)
589 590 if ymin == None: ymin = numpy.nanmin(y)
590 591 if ymax == None: ymax = numpy.nanmax(y)
591 592
592 593 self.__isConfig = True
593 594
594 595 self.setWinTitle(title)
595 596
596 597 for i in range(len(self.axesList)):
597 598 title = "Channel %d" %(i)
598 599 axes = self.axesList[i]
599 600 ychannel = y[i,:]
600 601 axes.pline(x, ychannel,
601 602 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
602 603 xlabel=xlabel, ylabel=ylabel, title=title)
603 604
604 605 self.draw()
605 606
606 607 if save:
607 608 date = thisDatetime.strftime("%Y%m%d_%H%M%S")
608 609 if figfile == None:
609 610 figfile = self.getFilename(name = date)
610 611
611 612 self.saveFigure(figpath, figfile)
612 613
613 614 class PowerProfilePlot(Figure):
614 615 __isConfig = None
615 616 __nsubplots = None
616 617
617 618 WIDTHPROF = None
618 619 HEIGHTPROF = None
619 620 PREFIX = 'spcprofile'
620 621
621 622 def __init__(self):
622 623 self.__isConfig = False
623 624 self.__nsubplots = 1
624 625
625 626 self.WIDTH = 300
626 627 self.HEIGHT = 500
627 628
628 629 def getSubplots(self):
629 630 ncol = 1
630 631 nrow = 1
631 632
632 633 return nrow, ncol
633 634
634 635 def setup(self, idfigure, nplots, wintitle, show):
635 636
636 637 self.nplots = nplots
637 638
638 639 ncolspan = 1
639 640 colspan = 1
640 641
641 642 self.createFigure(idfigure = idfigure,
642 643 wintitle = wintitle,
643 644 widthplot = self.WIDTH,
644 645 heightplot = self.HEIGHT,
645 646 show=show)
646 647
647 648 nrow, ncol = self.getSubplots()
648 649
649 650 counter = 0
650 651 for y in range(nrow):
651 652 for x in range(ncol):
652 653 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
653 654
654 655 def run(self, dataOut, idfigure, wintitle="", channelList=None,
655 656 xmin=None, xmax=None, ymin=None, ymax=None,
656 657 save=False, figpath='./', figfile=None, show=True):
657 658
658 659 if channelList == None:
659 660 channelIndexList = dataOut.channelIndexList
660 661 channelList = dataOut.channelList
661 662 else:
662 663 channelIndexList = []
663 664 for channel in channelList:
664 665 if channel not in dataOut.channelList:
665 666 raise ValueError, "Channel %d is not in dataOut.channelList"
666 667 channelIndexList.append(dataOut.channelList.index(channel))
667 668
668 669 factor = dataOut.normFactor
669 670 y = dataOut.getHeiRange()
670 671 x = dataOut.data_spc[channelIndexList,:,:]/factor
671 672 x = numpy.where(numpy.isfinite(x), x, numpy.NAN)
672 673 avg = numpy.average(x, axis=1)
673 674
674 675 avgdB = 10*numpy.log10(avg)
675 676
676 677 thisDatetime = dataOut.datatime
677 678 title = "Power Profile"
678 679 xlabel = "dB"
679 680 ylabel = "Range (Km)"
680 681
681 682 if not self.__isConfig:
682 683
683 684 nplots = 1
684 685
685 686 self.setup(idfigure=idfigure,
686 687 nplots=nplots,
687 688 wintitle=wintitle,
688 689 show=show)
689 690
690 691 if ymin == None: ymin = numpy.nanmin(y)
691 692 if ymax == None: ymax = numpy.nanmax(y)
692 693 if xmin == None: xmin = numpy.nanmin(avgdB)*0.9
693 694 if xmax == None: xmax = numpy.nanmax(avgdB)*0.9
694 695
695 696 self.__isConfig = True
696 697
697 698 self.setWinTitle(title)
698 699
699 700
700 701 title = "Power Profile: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
701 702 axes = self.axesList[0]
702 703
703 704 legendlabels = ["channel %d"%x for x in channelList]
704 705 axes.pmultiline(avgdB, y,
705 706 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
706 707 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels,
707 708 ytick_visible=True, nxticks=5,
708 709 grid='x')
709 710
710 711 self.draw()
711 712
712 713 if save:
713 714 date = thisDatetime.strftime("%Y%m%d")
714 715 if figfile == None:
715 716 figfile = self.getFilename(name = date)
716 717
717 718 self.saveFigure(figpath, figfile)
718 719
719 720 class CoherenceMap(Figure):
720 721 __isConfig = None
721 722 __nsubplots = None
722 723
723 724 WIDTHPROF = None
724 725 HEIGHTPROF = None
725 726 PREFIX = 'cmap'
726 727
727 728 def __init__(self):
728 729 self.timerange = 2*60*60
729 730 self.__isConfig = False
730 731 self.__nsubplots = 1
731 732
732 733 self.WIDTH = 800
733 734 self.HEIGHT = 150
734 735 self.WIDTHPROF = 120
735 736 self.HEIGHTPROF = 0
736 737 self.counterftp = 0
737 738
738 739 def getSubplots(self):
739 740 ncol = 1
740 741 nrow = self.nplots*2
741 742
742 743 return nrow, ncol
743 744
744 745 def setup(self, idfigure, nplots, wintitle, showprofile=True, show=True):
745 746 self.__showprofile = showprofile
746 747 self.nplots = nplots
747 748
748 749 ncolspan = 1
749 750 colspan = 1
750 751 if showprofile:
751 752 ncolspan = 7
752 753 colspan = 6
753 754 self.__nsubplots = 2
754 755
755 756 self.createFigure(idfigure = idfigure,
756 757 wintitle = wintitle,
757 758 widthplot = self.WIDTH + self.WIDTHPROF,
758 759 heightplot = self.HEIGHT + self.HEIGHTPROF,
759 760 show=True)
760 761
761 762 nrow, ncol = self.getSubplots()
762 763
763 764 for y in range(nrow):
764 765 for x in range(ncol):
765 766
766 767 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
767 768
768 769 if showprofile:
769 770 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
770 771
771 772 def run(self, dataOut, idfigure, wintitle="", pairsList=None, showprofile='True',
772 773 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
773 774 timerange=None,
774 775 save=False, figpath='./', figfile=None, ftp=False, ftpratio=1,
775 776 coherence_cmap='jet', phase_cmap='RdBu_r', show=True):
776 777
777 778 if pairsList == None:
778 779 pairsIndexList = dataOut.pairsIndexList
779 780 else:
780 781 pairsIndexList = []
781 782 for pair in pairsList:
782 783 if pair not in dataOut.pairsList:
783 784 raise ValueError, "Pair %s is not in dataOut.pairsList" %(pair)
784 785 pairsIndexList.append(dataOut.pairsList.index(pair))
785 786
786 787 if timerange != None:
787 788 self.timerange = timerange
788 789
789 790 if pairsIndexList == []:
790 791 return
791 792
792 793 if len(pairsIndexList) > 4:
793 794 pairsIndexList = pairsIndexList[0:4]
794 795
795 796 tmin = None
796 797 tmax = None
797 798 x = dataOut.getTimeRange()
798 799 y = dataOut.getHeiRange()
799 800
800 801 thisDatetime = dataOut.datatime
801 802 title = "CoherenceMap: %s" %(thisDatetime.strftime("%d-%b-%Y"))
802 803 xlabel = ""
803 804 ylabel = "Range (Km)"
804 805
805 806 if not self.__isConfig:
806 807 nplots = len(pairsIndexList)
807 808 self.setup(idfigure=idfigure,
808 809 nplots=nplots,
809 810 wintitle=wintitle,
810 811 showprofile=showprofile,
811 812 show=show)
812 813
813 814 tmin, tmax = self.getTimeLim(x, xmin, xmax)
814 815 if ymin == None: ymin = numpy.nanmin(y)
815 816 if ymax == None: ymax = numpy.nanmax(y)
816 817
817 818 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
818 819
819 820 self.__isConfig = True
820 821
821 822 self.setWinTitle(title)
822 823
823 824 for i in range(self.nplots):
824 825
825 826 pair = dataOut.pairsList[pairsIndexList[i]]
826 827 coherenceComplex = dataOut.data_cspc[pairsIndexList[i],:,:]/numpy.sqrt(dataOut.data_spc[pair[0],:,:]*dataOut.data_spc[pair[1],:,:])
827 828 avgcoherenceComplex = numpy.average(coherenceComplex, axis=0)
828 829 coherence = numpy.abs(avgcoherenceComplex)
829 830 # coherence = numpy.abs(coherenceComplex)
830 831 # avg = numpy.average(coherence, axis=0)
831 832
832 833 z = coherence.reshape((1,-1))
833 834
834 835 counter = 0
835 836
836 837 title = "Coherence %d%d: %s" %(pair[0], pair[1], thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
837 838 axes = self.axesList[i*self.__nsubplots*2]
838 839 axes.pcolorbuffer(x, y, z,
839 840 xmin=tmin, xmax=tmax, ymin=ymin, ymax=ymax, zmin=0, zmax=1,
840 841 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
841 842 ticksize=9, cblabel='', colormap=coherence_cmap, cbsize="1%")
842 843
843 844 if self.__showprofile:
844 845 counter += 1
845 846 axes = self.axesList[i*self.__nsubplots*2 + counter]
846 847 axes.pline(coherence, y,
847 848 xmin=0, xmax=1, ymin=ymin, ymax=ymax,
848 849 xlabel='', ylabel='', title='', ticksize=7,
849 850 ytick_visible=False, nxticks=5,
850 851 grid='x')
851 852
852 853 counter += 1
853 854 # phase = numpy.arctan(-1*coherenceComplex.imag/coherenceComplex.real)*180/numpy.pi
854 855 phase = numpy.arctan2(avgcoherenceComplex.imag, avgcoherenceComplex.real)*180/numpy.pi
855 856 # avg = numpy.average(phase, axis=0)
856 857 z = phase.reshape((1,-1))
857 858
858 859 title = "Phase %d%d: %s" %(pair[0], pair[1], thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
859 860 axes = self.axesList[i*self.__nsubplots*2 + counter]
860 861 axes.pcolorbuffer(x, y, z,
861 862 xmin=tmin, xmax=tmax, ymin=ymin, ymax=ymax, zmin=-180, zmax=180,
862 863 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
863 864 ticksize=9, cblabel='', colormap=phase_cmap, cbsize="1%")
864 865
865 866 if self.__showprofile:
866 867 counter += 1
867 868 axes = self.axesList[i*self.__nsubplots*2 + counter]
868 869 axes.pline(phase, y,
869 870 xmin=-180, xmax=180, ymin=ymin, ymax=ymax,
870 871 xlabel='', ylabel='', title='', ticksize=7,
871 872 ytick_visible=False, nxticks=4,
872 873 grid='x')
873 874
874 875 self.draw()
875 876
876 877 if save:
877 878
878 879 if figfile == None:
879 880 figfile = self.getFilename(name = self.name)
880 881
881 882 self.saveFigure(figpath, figfile)
882 883
883 884 self.counterftp += 1
884 885 if (ftp and (self.counterftp==ftpratio)):
885 886 figfilename = os.path.join(figpath,figfile)
886 887 self.sendByFTP(figfilename)
887 888 self.counterftp = 0
888 889
889 890 if x[1] + (x[1]-x[0]) >= self.axesList[0].xmax:
890 891 self.__isConfig = False
891 892
892 893 class RTIfromNoise(Figure):
893 894
894 895 __isConfig = None
895 896 __nsubplots = None
896 897
897 898 PREFIX = 'rtinoise'
898 899
899 900 def __init__(self):
900 901
901 902 self.timerange = 24*60*60
902 903 self.__isConfig = False
903 904 self.__nsubplots = 1
904 905
905 906 self.WIDTH = 820
906 907 self.HEIGHT = 200
907 908 self.WIDTHPROF = 120
908 909 self.HEIGHTPROF = 0
909 910 self.xdata = None
910 911 self.ydata = None
911 912
912 913 def getSubplots(self):
913 914
914 915 ncol = 1
915 916 nrow = 1
916 917
917 918 return nrow, ncol
918 919
919 920 def setup(self, idfigure, nplots, wintitle, showprofile=True, show=True):
920 921
921 922 self.__showprofile = showprofile
922 923 self.nplots = nplots
923 924
924 925 ncolspan = 7
925 926 colspan = 6
926 927 self.__nsubplots = 2
927 928
928 929 self.createFigure(idfigure = idfigure,
929 930 wintitle = wintitle,
930 931 widthplot = self.WIDTH+self.WIDTHPROF,
931 932 heightplot = self.HEIGHT+self.HEIGHTPROF,
932 933 show=show)
933 934
934 935 nrow, ncol = self.getSubplots()
935 936
936 937 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
937 938
938 939
939 940 def run(self, dataOut, idfigure, wintitle="", channelList=None, showprofile='True',
940 941 xmin=None, xmax=None, ymin=None, ymax=None,
941 942 timerange=None,
942 943 save=False, figpath='./', figfile=None, show=True):
943 944
944 945 if channelList == None:
945 946 channelIndexList = dataOut.channelIndexList
946 947 channelList = dataOut.channelList
947 948 else:
948 949 channelIndexList = []
949 950 for channel in channelList:
950 951 if channel not in dataOut.channelList:
951 952 raise ValueError, "Channel %d is not in dataOut.channelList"
952 953 channelIndexList.append(dataOut.channelList.index(channel))
953 954
954 955 if timerange != None:
955 956 self.timerange = timerange
956 957
957 958 tmin = None
958 959 tmax = None
959 960 x = dataOut.getTimeRange()
960 961 y = dataOut.getHeiRange()
961 962 factor = dataOut.normFactor
962 963 noise = dataOut.getNoise()/factor
963 964 noisedB = 10*numpy.log10(noise)
964 965
965 966 thisDatetime = dataOut.datatime
966 967 title = "RTI Noise: %s" %(thisDatetime.strftime("%d-%b-%Y"))
967 968 xlabel = ""
968 969 ylabel = "Range (Km)"
969 970
970 971 if not self.__isConfig:
971 972
972 973 nplots = 1
973 974
974 975 self.setup(idfigure=idfigure,
975 976 nplots=nplots,
976 977 wintitle=wintitle,
977 978 showprofile=showprofile,
978 979 show=show)
979 980
980 981 tmin, tmax = self.getTimeLim(x, xmin, xmax)
981 982 if ymin == None: ymin = numpy.nanmin(noisedB)
982 983 if ymax == None: ymax = numpy.nanmax(noisedB)
983 984
984 985 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
985 986 self.__isConfig = True
986 987
987 988 self.xdata = numpy.array([])
988 989 self.ydata = numpy.array([])
989 990
990 991 self.setWinTitle(title)
991 992
992 993
993 994 title = "RTI Noise %s" %(thisDatetime.strftime("%d-%b-%Y"))
994 995
995 996 legendlabels = ["channel %d"%idchannel for idchannel in channelList]
996 997 axes = self.axesList[0]
997 998
998 999 self.xdata = numpy.hstack((self.xdata, x[0:1]))
999 1000
1000 1001 if len(self.ydata)==0:
1001 1002 self.ydata = noisedB[channelIndexList].reshape(-1,1)
1002 1003 else:
1003 1004 self.ydata = numpy.hstack((self.ydata, noisedB[channelIndexList].reshape(-1,1)))
1004 1005
1005 1006
1006 1007 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
1007 1008 xmin=tmin, xmax=tmax, ymin=ymin, ymax=ymax,
1008 1009 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
1009 1010 XAxisAsTime=True
1010 1011 )
1011 1012
1012 1013 self.draw()
1013 1014
1014 1015 if save:
1015 1016
1016 1017 if figfile == None:
1017 1018 figfile = self.getFilename(name = self.name)
1018 1019
1019 1020 self.saveFigure(figpath, figfile)
1020 1021
1021 1022 if x[1] + (x[1]-x[0]) >= self.axesList[0].xmax:
1022 1023 self.__isConfig = False
1023 1024 del self.xdata
1024 1025 del self.ydata
1025 1026
1026 1027
1027 1028 class SpectraHeisScope(Figure):
1028 1029
1029 1030
1030 1031 __isConfig = None
1031 1032 __nsubplots = None
1032 1033
1033 1034 WIDTHPROF = None
1034 1035 HEIGHTPROF = None
1035 1036 PREFIX = 'spc'
1036 1037
1037 1038 def __init__(self):
1038 1039
1039 1040 self.__isConfig = False
1040 1041 self.__nsubplots = 1
1041 1042
1042 1043 self.WIDTH = 230
1043 1044 self.HEIGHT = 250
1044 1045 self.WIDTHPROF = 120
1045 1046 self.HEIGHTPROF = 0
1046 1047 self.counterftp = 0
1047 1048
1048 1049 def getSubplots(self):
1049 1050
1050 1051 ncol = int(numpy.sqrt(self.nplots)+0.9)
1051 1052 nrow = int(self.nplots*1./ncol + 0.9)
1052 1053
1053 1054 return nrow, ncol
1054 1055
1055 1056 def setup(self, idfigure, nplots, wintitle, show):
1056 1057
1057 1058 showprofile = False
1058 1059 self.__showprofile = showprofile
1059 1060 self.nplots = nplots
1060 1061
1061 1062 ncolspan = 1
1062 1063 colspan = 1
1063 1064 if showprofile:
1064 1065 ncolspan = 3
1065 1066 colspan = 2
1066 1067 self.__nsubplots = 2
1067 1068
1068 1069 self.createFigure(idfigure = idfigure,
1069 1070 wintitle = wintitle,
1070 1071 widthplot = self.WIDTH + self.WIDTHPROF,
1071 1072 heightplot = self.HEIGHT + self.HEIGHTPROF,
1072 1073 show = show)
1073 1074
1074 1075 nrow, ncol = self.getSubplots()
1075 1076
1076 1077 counter = 0
1077 1078 for y in range(nrow):
1078 1079 for x in range(ncol):
1079 1080
1080 1081 if counter >= self.nplots:
1081 1082 break
1082 1083
1083 1084 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
1084 1085
1085 1086 if showprofile:
1086 1087 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
1087 1088
1088 1089 counter += 1
1089 1090
1090 1091 # __isConfig = None
1091 1092 # def __init__(self):
1092 1093 #
1093 1094 # self.__isConfig = False
1094 1095 # self.WIDTH = 600
1095 1096 # self.HEIGHT = 200
1096 1097 #
1097 1098 # def getSubplots(self):
1098 1099 #
1099 1100 # nrow = self.nplots
1100 1101 # ncol = 3
1101 1102 # return nrow, ncol
1102 1103 #
1103 1104 # def setup(self, idfigure, nplots, wintitle):
1104 1105 #
1105 1106 # self.nplots = nplots
1106 1107 #
1107 1108 # self.createFigure(idfigure, wintitle)
1108 1109 #
1109 1110 # nrow,ncol = self.getSubplots()
1110 1111 # colspan = 3
1111 1112 # rowspan = 1
1112 1113 #
1113 1114 # for i in range(nplots):
1114 1115 # self.addAxes(nrow, ncol, i, 0, colspan, rowspan)
1115 1116
1116 1117 def run(self, dataOut, idfigure, wintitle="", channelList=None,
1117 1118 xmin=None, xmax=None, ymin=None, ymax=None, save=False,
1118 1119 figpath='./', figfile=None, ftp=False, ftpratio=1, show=True):
1119 1120
1120 1121 """
1121 1122
1122 1123 Input:
1123 1124 dataOut :
1124 1125 idfigure :
1125 1126 wintitle :
1126 1127 channelList :
1127 1128 xmin : None,
1128 1129 xmax : None,
1129 1130 ymin : None,
1130 1131 ymax : None,
1131 1132 """
1132 1133
1133 1134 if dataOut.realtime:
1134 1135 if not(isRealtime(utcdatatime = dataOut.utctime)):
1135 1136 print 'Skipping this plot function'
1136 1137 return
1137 1138
1138 1139 if channelList == None:
1139 1140 channelIndexList = dataOut.channelIndexList
1140 1141 else:
1141 1142 channelIndexList = []
1142 1143 for channel in channelList:
1143 1144 if channel not in dataOut.channelList:
1144 1145 raise ValueError, "Channel %d is not in dataOut.channelList"
1145 1146 channelIndexList.append(dataOut.channelList.index(channel))
1146 1147
1147 1148 # x = dataOut.heightList
1148 1149 c = 3E8
1149 1150 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1150 1151 #deberia cambiar para el caso de 1Mhz y 100KHz
1151 1152 x = numpy.arange(-1*dataOut.nHeights/2.,dataOut.nHeights/2.)*(c/(2*deltaHeight*dataOut.nHeights*1000))
1152 1153 x= x/(10000.0)
1153 1154 # y = dataOut.data[channelIndexList,:] * numpy.conjugate(dataOut.data[channelIndexList,:])
1154 1155 # y = y.real
1155 1156 datadB = 10.*numpy.log10(dataOut.data_spc)
1156 1157 y = datadB
1157 1158
1158 1159 thisDatetime = dataOut.datatime
1159 1160 title = "Scope: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
1160 1161 xlabel = "Frequency x 10000"
1161 1162 ylabel = "Intensity (dB)"
1162 1163
1163 1164 if not self.__isConfig:
1164 1165 nplots = len(channelIndexList)
1165 1166
1166 1167 self.setup(idfigure=idfigure,
1167 1168 nplots=nplots,
1168 1169 wintitle=wintitle,
1169 1170 show=show)
1170 1171
1171 1172 if xmin == None: xmin = numpy.nanmin(x)
1172 1173 if xmax == None: xmax = numpy.nanmax(x)
1173 1174 if ymin == None: ymin = numpy.nanmin(y)
1174 1175 if ymax == None: ymax = numpy.nanmax(y)
1175 1176
1176 1177 self.__isConfig = True
1177 1178
1178 1179 self.setWinTitle(title)
1179 1180
1180 1181 for i in range(len(self.axesList)):
1181 1182 ychannel = y[i,:]
1182 1183 title = "Channel %d - peak:%.2f" %(i,numpy.max(ychannel))
1183 1184 axes = self.axesList[i]
1184 1185 axes.pline(x, ychannel,
1185 1186 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
1186 1187 xlabel=xlabel, ylabel=ylabel, title=title, grid='both')
1187 1188
1188 1189
1189 1190 self.draw()
1190 1191
1191 1192 if save:
1192 1193 date = thisDatetime.strftime("%Y%m%d_%H%M%S")
1193 1194 if figfile == None:
1194 1195 figfile = self.getFilename(name = date)
1195 1196
1196 1197 self.saveFigure(figpath, figfile)
1197 1198
1198 1199 self.counterftp += 1
1199 1200 if (ftp and (self.counterftp==ftpratio)):
1200 1201 figfilename = os.path.join(figpath,figfile)
1201 1202 self.sendByFTP(figfilename)
1202 1203 self.counterftp = 0
1203 1204
1204 1205
1205 1206 class RTIfromSpectraHeis(Figure):
1206 1207
1207 1208 __isConfig = None
1208 1209 __nsubplots = None
1209 1210
1210 1211 PREFIX = 'rtinoise'
1211 1212
1212 1213 def __init__(self):
1213 1214
1214 1215 self.timerange = 24*60*60
1215 1216 self.__isConfig = False
1216 1217 self.__nsubplots = 1
1217 1218
1218 1219 self.WIDTH = 820
1219 1220 self.HEIGHT = 200
1220 1221 self.WIDTHPROF = 120
1221 1222 self.HEIGHTPROF = 0
1222 1223 self.counterftp = 0
1223 1224 self.xdata = None
1224 1225 self.ydata = None
1225 1226
1226 1227 def getSubplots(self):
1227 1228
1228 1229 ncol = 1
1229 1230 nrow = 1
1230 1231
1231 1232 return nrow, ncol
1232 1233
1233 1234 def setup(self, idfigure, nplots, wintitle, showprofile=True, show=True):
1234 1235
1235 1236 self.__showprofile = showprofile
1236 1237 self.nplots = nplots
1237 1238
1238 1239 ncolspan = 7
1239 1240 colspan = 6
1240 1241 self.__nsubplots = 2
1241 1242
1242 1243 self.createFigure(idfigure = idfigure,
1243 1244 wintitle = wintitle,
1244 1245 widthplot = self.WIDTH+self.WIDTHPROF,
1245 1246 heightplot = self.HEIGHT+self.HEIGHTPROF,
1246 1247 show = show)
1247 1248
1248 1249 nrow, ncol = self.getSubplots()
1249 1250
1250 1251 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
1251 1252
1252 1253
1253 1254 def run(self, dataOut, idfigure, wintitle="", channelList=None, showprofile='True',
1254 1255 xmin=None, xmax=None, ymin=None, ymax=None,
1255 1256 timerange=None,
1256 1257 save=False, figpath='./', figfile=None, ftp=False, ftpratio=1, show=True):
1257 1258
1258 1259 if channelList == None:
1259 1260 channelIndexList = dataOut.channelIndexList
1260 1261 channelList = dataOut.channelList
1261 1262 else:
1262 1263 channelIndexList = []
1263 1264 for channel in channelList:
1264 1265 if channel not in dataOut.channelList:
1265 1266 raise ValueError, "Channel %d is not in dataOut.channelList"
1266 1267 channelIndexList.append(dataOut.channelList.index(channel))
1267 1268
1268 1269 if timerange != None:
1269 1270 self.timerange = timerange
1270 1271
1271 1272 tmin = None
1272 1273 tmax = None
1273 1274 x = dataOut.getTimeRange()
1274 1275 y = dataOut.getHeiRange()
1275 1276
1276 1277 factor = 1
1277 1278 data = dataOut.data_spc/factor
1278 1279 data = numpy.average(data,axis=1)
1279 1280 datadB = 10*numpy.log10(data)
1280 1281
1281 1282 # factor = dataOut.normFactor
1282 1283 # noise = dataOut.getNoise()/factor
1283 1284 # noisedB = 10*numpy.log10(noise)
1284 1285
1285 1286 thisDatetime = dataOut.datatime
1286 1287 title = "RTI: %s" %(thisDatetime.strftime("%d-%b-%Y"))
1287 1288 xlabel = "Local Time"
1288 1289 ylabel = "Intensity (dB)"
1289 1290
1290 1291 if not self.__isConfig:
1291 1292
1292 1293 nplots = 1
1293 1294
1294 1295 self.setup(idfigure=idfigure,
1295 1296 nplots=nplots,
1296 1297 wintitle=wintitle,
1297 1298 showprofile=showprofile,
1298 1299 show=show)
1299 1300
1300 1301 tmin, tmax = self.getTimeLim(x, xmin, xmax)
1301 1302 if ymin == None: ymin = numpy.nanmin(datadB)
1302 1303 if ymax == None: ymax = numpy.nanmax(datadB)
1303 1304
1304 1305 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1305 1306 self.__isConfig = True
1306 1307
1307 1308 self.xdata = numpy.array([])
1308 1309 self.ydata = numpy.array([])
1309 1310
1310 1311 self.setWinTitle(title)
1311 1312
1312 1313
1313 1314 # title = "RTI %s" %(thisDatetime.strftime("%d-%b-%Y"))
1314 1315 title = "RTI-Noise - %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
1315 1316
1316 1317 legendlabels = ["channel %d"%idchannel for idchannel in channelList]
1317 1318 axes = self.axesList[0]
1318 1319
1319 1320 self.xdata = numpy.hstack((self.xdata, x[0:1]))
1320 1321
1321 1322 if len(self.ydata)==0:
1322 1323 self.ydata = datadB[channelIndexList].reshape(-1,1)
1323 1324 else:
1324 1325 self.ydata = numpy.hstack((self.ydata, datadB[channelIndexList].reshape(-1,1)))
1325 1326
1326 1327
1327 1328 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
1328 1329 xmin=tmin, xmax=tmax, ymin=ymin, ymax=ymax,
1329 1330 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='.', markersize=8, linestyle="solid", grid='both',
1330 1331 XAxisAsTime=True
1331 1332 )
1332 1333
1333 1334 self.draw()
1334 1335
1335 1336 if save:
1336 1337
1337 1338 if figfile == None:
1338 1339 figfile = self.getFilename(name = self.name)
1339 1340
1340 1341 self.saveFigure(figpath, figfile)
1341 1342
1342 1343 self.counterftp += 1
1343 1344 if (ftp and (self.counterftp==ftpratio)):
1344 1345 figfilename = os.path.join(figpath,figfile)
1345 1346 self.sendByFTP(figfilename)
1346 1347 self.counterftp = 0
1347 1348
1348 1349 if x[1] + (x[1]-x[0]) >= self.axesList[0].xmax:
1349 1350 self.__isConfig = False
1350 1351 del self.xdata
1351 1352 del self.ydata
1352 1353
1353 1354
1354 1355 No newline at end of file
@@ -1,1632 +1,1635
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 try:
16 16 import cfunctions
17 17 except:
18 18 pass
19 19
20 20 class ProcessingUnit:
21 21
22 22 """
23 23 Esta es la clase base para el procesamiento de datos.
24 24
25 25 Contiene el metodo "call" para llamar operaciones. Las operaciones pueden ser:
26 26 - Metodos internos (callMethod)
27 27 - Objetos del tipo Operation (callObject). Antes de ser llamados, estos objetos
28 28 tienen que ser agreagados con el metodo "add".
29 29
30 30 """
31 31 # objeto de datos de entrada (Voltage, Spectra o Correlation)
32 32 dataIn = None
33 33
34 34 # objeto de datos de entrada (Voltage, Spectra o Correlation)
35 35 dataOut = None
36 36
37 37
38 38 objectDict = None
39 39
40 40 def __init__(self):
41 41
42 42 self.objectDict = {}
43 43
44 44 def init(self):
45 45
46 46 raise ValueError, "Not implemented"
47 47
48 48 def addOperation(self, object, objId):
49 49
50 50 """
51 51 Agrega el objeto "object" a la lista de objetos "self.objectList" y retorna el
52 52 identificador asociado a este objeto.
53 53
54 54 Input:
55 55
56 56 object : objeto de la clase "Operation"
57 57
58 58 Return:
59 59
60 60 objId : identificador del objeto, necesario para ejecutar la operacion
61 61 """
62 62
63 63 self.objectDict[objId] = object
64 64
65 65 return objId
66 66
67 67 def operation(self, **kwargs):
68 68
69 69 """
70 70 Operacion directa sobre la data (dataOut.data). Es necesario actualizar los valores de los
71 71 atributos del objeto dataOut
72 72
73 73 Input:
74 74
75 75 **kwargs : Diccionario de argumentos de la funcion a ejecutar
76 76 """
77 77
78 78 raise ValueError, "ImplementedError"
79 79
80 80 def callMethod(self, name, **kwargs):
81 81
82 82 """
83 83 Ejecuta el metodo con el nombre "name" y con argumentos **kwargs de la propia clase.
84 84
85 85 Input:
86 86 name : nombre del metodo a ejecutar
87 87
88 88 **kwargs : diccionario con los nombres y valores de la funcion a ejecutar.
89 89
90 90 """
91 91 if name != 'run':
92 92
93 93 if name == 'init' and self.dataIn.isEmpty():
94 94 self.dataOut.flagNoData = True
95 95 return False
96 96
97 97 if name != 'init' and self.dataOut.isEmpty():
98 98 return False
99 99
100 100 methodToCall = getattr(self, name)
101 101
102 102 methodToCall(**kwargs)
103 103
104 104 if name != 'run':
105 105 return True
106 106
107 107 if self.dataOut.isEmpty():
108 108 return False
109 109
110 110 return True
111 111
112 112 def callObject(self, objId, **kwargs):
113 113
114 114 """
115 115 Ejecuta la operacion asociada al identificador del objeto "objId"
116 116
117 117 Input:
118 118
119 119 objId : identificador del objeto a ejecutar
120 120
121 121 **kwargs : diccionario con los nombres y valores de la funcion a ejecutar.
122 122
123 123 Return:
124 124
125 125 None
126 126 """
127 127
128 128 if self.dataOut.isEmpty():
129 129 return False
130 130
131 131 object = self.objectDict[objId]
132 132
133 133 object.run(self.dataOut, **kwargs)
134 134
135 135 return True
136 136
137 137 def call(self, operationConf, **kwargs):
138 138
139 139 """
140 140 Return True si ejecuta la operacion "operationConf.name" con los
141 141 argumentos "**kwargs". False si la operacion no se ha ejecutado.
142 142 La operacion puede ser de dos tipos:
143 143
144 144 1. Un metodo propio de esta clase:
145 145
146 146 operation.type = "self"
147 147
148 148 2. El metodo "run" de un objeto del tipo Operation o de un derivado de ella:
149 149 operation.type = "other".
150 150
151 151 Este objeto de tipo Operation debe de haber sido agregado antes con el metodo:
152 152 "addOperation" e identificado con el operation.id
153 153
154 154
155 155 con el id de la operacion.
156 156
157 157 Input:
158 158
159 159 Operation : Objeto del tipo operacion con los atributos: name, type y id.
160 160
161 161 """
162 162
163 163 if operationConf.type == 'self':
164 164 sts = self.callMethod(operationConf.name, **kwargs)
165 165
166 166 if operationConf.type == 'other':
167 167 sts = self.callObject(operationConf.id, **kwargs)
168 168
169 169 return sts
170 170
171 171 def setInput(self, dataIn):
172 172
173 173 self.dataIn = dataIn
174 174
175 175 def getOutput(self):
176 176
177 177 return self.dataOut
178 178
179 179 class Operation():
180 180
181 181 """
182 182 Clase base para definir las operaciones adicionales que se pueden agregar a la clase ProcessingUnit
183 183 y necesiten acumular informacion previa de los datos a procesar. De preferencia usar un buffer de
184 184 acumulacion dentro de esta clase
185 185
186 186 Ejemplo: Integraciones coherentes, necesita la informacion previa de los n perfiles anteriores (bufffer)
187 187
188 188 """
189 189
190 190 __buffer = None
191 191 __isConfig = False
192 192
193 193 def __init__(self):
194 194
195 195 pass
196 196
197 197 def run(self, dataIn, **kwargs):
198 198
199 199 """
200 200 Realiza las operaciones necesarias sobre la dataIn.data y actualiza los atributos del objeto dataIn.
201 201
202 202 Input:
203 203
204 204 dataIn : objeto del tipo JROData
205 205
206 206 Return:
207 207
208 208 None
209 209
210 210 Affected:
211 211 __buffer : buffer de recepcion de datos.
212 212
213 213 """
214 214
215 215 raise ValueError, "ImplementedError"
216 216
217 217 class VoltageProc(ProcessingUnit):
218 218
219 219
220 220 def __init__(self):
221 221
222 222 self.objectDict = {}
223 223 self.dataOut = Voltage()
224 224 self.flip = 1
225 225
226 226 def init(self):
227 227
228 228 self.dataOut.copy(self.dataIn)
229 229 # No necesita copiar en cada init() los atributos de dataIn
230 230 # la copia deberia hacerse por cada nuevo bloque de datos
231 231
232 232 def selectChannels(self, channelList):
233 233
234 234 channelIndexList = []
235 235
236 236 for channel in channelList:
237 237 index = self.dataOut.channelList.index(channel)
238 238 channelIndexList.append(index)
239 239
240 240 self.selectChannelsByIndex(channelIndexList)
241 241
242 242 def selectChannelsByIndex(self, channelIndexList):
243 243 """
244 244 Selecciona un bloque de datos en base a canales segun el channelIndexList
245 245
246 246 Input:
247 247 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
248 248
249 249 Affected:
250 250 self.dataOut.data
251 251 self.dataOut.channelIndexList
252 252 self.dataOut.nChannels
253 253 self.dataOut.m_ProcessingHeader.totalSpectra
254 254 self.dataOut.systemHeaderObj.numChannels
255 255 self.dataOut.m_ProcessingHeader.blockSize
256 256
257 257 Return:
258 258 None
259 259 """
260 260
261 261 for channelIndex in channelIndexList:
262 262 if channelIndex not in self.dataOut.channelIndexList:
263 263 print channelIndexList
264 264 raise ValueError, "The value %d in channelIndexList is not valid" %channelIndex
265 265
266 266 nChannels = len(channelIndexList)
267 267
268 268 data = self.dataOut.data[channelIndexList,:]
269 269
270 270 self.dataOut.data = data
271 271 self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
272 272 # self.dataOut.nChannels = nChannels
273 273
274 274 return 1
275 275
276 276 def selectHeights(self, minHei, maxHei):
277 277 """
278 278 Selecciona un bloque de datos en base a un grupo de valores de alturas segun el rango
279 279 minHei <= height <= maxHei
280 280
281 281 Input:
282 282 minHei : valor minimo de altura a considerar
283 283 maxHei : valor maximo de altura a considerar
284 284
285 285 Affected:
286 286 Indirectamente son cambiados varios valores a travez del metodo selectHeightsByIndex
287 287
288 288 Return:
289 289 1 si el metodo se ejecuto con exito caso contrario devuelve 0
290 290 """
291 291 if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei):
292 292 raise ValueError, "some value in (%d,%d) is not valid" % (minHei, maxHei)
293 293
294 294 if (maxHei > self.dataOut.heightList[-1]):
295 295 maxHei = self.dataOut.heightList[-1]
296 296 # raise ValueError, "some value in (%d,%d) is not valid" % (minHei, maxHei)
297 297
298 298 minIndex = 0
299 299 maxIndex = 0
300 300 heights = self.dataOut.heightList
301 301
302 302 inda = numpy.where(heights >= minHei)
303 303 indb = numpy.where(heights <= maxHei)
304 304
305 305 try:
306 306 minIndex = inda[0][0]
307 307 except:
308 308 minIndex = 0
309 309
310 310 try:
311 311 maxIndex = indb[0][-1]
312 312 except:
313 313 maxIndex = len(heights)
314 314
315 315 self.selectHeightsByIndex(minIndex, maxIndex)
316 316
317 317 return 1
318 318
319 319
320 320 def selectHeightsByIndex(self, minIndex, maxIndex):
321 321 """
322 322 Selecciona un bloque de datos en base a un grupo indices de alturas segun el rango
323 323 minIndex <= index <= maxIndex
324 324
325 325 Input:
326 326 minIndex : valor de indice minimo de altura a considerar
327 327 maxIndex : valor de indice maximo de altura a considerar
328 328
329 329 Affected:
330 330 self.dataOut.data
331 331 self.dataOut.heightList
332 332
333 333 Return:
334 334 1 si el metodo se ejecuto con exito caso contrario devuelve 0
335 335 """
336 336
337 337 if (minIndex < 0) or (minIndex > maxIndex):
338 338 raise ValueError, "some value in (%d,%d) is not valid" % (minIndex, maxIndex)
339 339
340 340 if (maxIndex >= self.dataOut.nHeights):
341 341 maxIndex = self.dataOut.nHeights-1
342 342 # raise ValueError, "some value in (%d,%d) is not valid" % (minIndex, maxIndex)
343 343
344 344 nHeights = maxIndex - minIndex + 1
345 345
346 346 #voltage
347 347 data = self.dataOut.data[:,minIndex:maxIndex+1]
348 348
349 349 firstHeight = self.dataOut.heightList[minIndex]
350 350
351 351 self.dataOut.data = data
352 352 self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex+1]
353 353
354 354 return 1
355 355
356 356
357 357 def filterByHeights(self, window):
358 358 deltaHeight = self.dataOut.heightList[1] - self.dataOut.heightList[0]
359 359
360 360 if window == None:
361 361 window = self.dataOut.radarControllerHeaderObj.txA / deltaHeight
362 362
363 363 newdelta = deltaHeight * window
364 364 r = self.dataOut.data.shape[1] % window
365 365 buffer = self.dataOut.data[:,0:self.dataOut.data.shape[1]-r]
366 366 buffer = buffer.reshape(self.dataOut.data.shape[0],self.dataOut.data.shape[1]/window,window)
367 367 buffer = numpy.sum(buffer,2)
368 368 self.dataOut.data = buffer
369 369 self.dataOut.heightList = numpy.arange(self.dataOut.heightList[0],newdelta*self.dataOut.nHeights/window,newdelta)
370 370 self.dataOut.windowOfFilter = window
371 371
372 372 def deFlip(self):
373 373 self.dataOut.data *= self.flip
374 374 self.flip *= -1.
375 375
376 376
377 377 class CohInt(Operation):
378 378
379 379 __isConfig = False
380 380
381 381 __profIndex = 0
382 382 __withOverapping = False
383 383
384 384 __byTime = False
385 385 __initime = None
386 386 __lastdatatime = None
387 387 __integrationtime = None
388 388
389 389 __buffer = None
390 390
391 391 __dataReady = False
392 392
393 393 n = None
394 394
395 395
396 396 def __init__(self):
397 397
398 398 self.__isConfig = False
399 399
400 400 def setup(self, n=None, timeInterval=None, overlapping=False):
401 401 """
402 402 Set the parameters of the integration class.
403 403
404 404 Inputs:
405 405
406 406 n : Number of coherent integrations
407 407 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
408 408 overlapping :
409 409
410 410 """
411 411
412 412 self.__initime = None
413 413 self.__lastdatatime = 0
414 414 self.__buffer = None
415 415 self.__dataReady = False
416 416
417 417
418 418 if n == None and timeInterval == None:
419 419 raise ValueError, "n or timeInterval should be specified ..."
420 420
421 421 if n != None:
422 422 self.n = n
423 423 self.__byTime = False
424 424 else:
425 425 self.__integrationtime = timeInterval * 60. #if (type(timeInterval)!=integer) -> change this line
426 426 self.n = 9999
427 427 self.__byTime = True
428 428
429 429 if overlapping:
430 430 self.__withOverapping = True
431 431 self.__buffer = None
432 432 else:
433 433 self.__withOverapping = False
434 434 self.__buffer = 0
435 435
436 436 self.__profIndex = 0
437 437
438 438 def putData(self, data):
439 439
440 440 """
441 441 Add a profile to the __buffer and increase in one the __profileIndex
442 442
443 443 """
444 444
445 445 if not self.__withOverapping:
446 446 self.__buffer += data.copy()
447 447 self.__profIndex += 1
448 448 return
449 449
450 450 #Overlapping data
451 451 nChannels, nHeis = data.shape
452 452 data = numpy.reshape(data, (1, nChannels, nHeis))
453 453
454 454 #If the buffer is empty then it takes the data value
455 455 if self.__buffer == None:
456 456 self.__buffer = data
457 457 self.__profIndex += 1
458 458 return
459 459
460 460 #If the buffer length is lower than n then stakcing the data value
461 461 if self.__profIndex < self.n:
462 462 self.__buffer = numpy.vstack((self.__buffer, data))
463 463 self.__profIndex += 1
464 464 return
465 465
466 466 #If the buffer length is equal to n then replacing the last buffer value with the data value
467 467 self.__buffer = numpy.roll(self.__buffer, -1, axis=0)
468 468 self.__buffer[self.n-1] = data
469 469 self.__profIndex = self.n
470 470 return
471 471
472 472
473 473 def pushData(self):
474 474 """
475 475 Return the sum of the last profiles and the profiles used in the sum.
476 476
477 477 Affected:
478 478
479 479 self.__profileIndex
480 480
481 481 """
482 482
483 483 if not self.__withOverapping:
484 484 data = self.__buffer
485 485 n = self.__profIndex
486 486
487 487 self.__buffer = 0
488 488 self.__profIndex = 0
489 489
490 490 return data, n
491 491
492 492 #Integration with Overlapping
493 493 data = numpy.sum(self.__buffer, axis=0)
494 494 n = self.__profIndex
495 495
496 496 return data, n
497 497
498 498 def byProfiles(self, data):
499 499
500 500 self.__dataReady = False
501 501 avgdata = None
502 502 n = None
503 503
504 504 self.putData(data)
505 505
506 506 if self.__profIndex == self.n:
507 507
508 508 avgdata, n = self.pushData()
509 509 self.__dataReady = True
510 510
511 511 return avgdata
512 512
513 513 def byTime(self, data, datatime):
514 514
515 515 self.__dataReady = False
516 516 avgdata = None
517 517 n = None
518 518
519 519 self.putData(data)
520 520
521 521 if (datatime - self.__initime) >= self.__integrationtime:
522 522 avgdata, n = self.pushData()
523 523 self.n = n
524 524 self.__dataReady = True
525 525
526 526 return avgdata
527 527
528 528 def integrate(self, data, datatime=None):
529 529
530 530 if self.__initime == None:
531 531 self.__initime = datatime
532 532
533 533 if self.__byTime:
534 534 avgdata = self.byTime(data, datatime)
535 535 else:
536 536 avgdata = self.byProfiles(data)
537 537
538 538
539 539 self.__lastdatatime = datatime
540 540
541 541 if avgdata == None:
542 542 return None, None
543 543
544 544 avgdatatime = self.__initime
545 545
546 546 deltatime = datatime -self.__lastdatatime
547 547
548 548 if not self.__withOverapping:
549 549 self.__initime = datatime
550 550 else:
551 551 self.__initime += deltatime
552 552
553 553 return avgdata, avgdatatime
554 554
555 555 def run(self, dataOut, **kwargs):
556 556
557 557 if not self.__isConfig:
558 558 self.setup(**kwargs)
559 559 self.__isConfig = True
560 560
561 561 avgdata, avgdatatime = self.integrate(dataOut.data, dataOut.utctime)
562 562
563 563 # dataOut.timeInterval *= n
564 564 dataOut.flagNoData = True
565 565
566 566 if self.__dataReady:
567 567 dataOut.data = avgdata
568 568 dataOut.nCohInt *= self.n
569 569 dataOut.utctime = avgdatatime
570 570 dataOut.timeInterval = dataOut.ippSeconds * dataOut.nCohInt
571 571 dataOut.flagNoData = False
572 572
573 573
574 574 class Decoder(Operation):
575 575
576 576 __isConfig = False
577 577 __profIndex = 0
578 578
579 579 code = None
580 580
581 581 nCode = None
582 582 nBaud = None
583 583
584 584 def __init__(self):
585 585
586 586 self.__isConfig = False
587 587
588 588 def setup(self, code, shape):
589 589
590 590 self.__profIndex = 0
591 591
592 592 self.code = code
593 593
594 594 self.nCode = len(code)
595 595 self.nBaud = len(code[0])
596 596
597 597 self.__nChannels, self.__nHeis = shape
598 598
599 599 __codeBuffer = numpy.zeros((self.nCode, self.__nHeis), dtype=numpy.complex)
600 600
601 601 __codeBuffer[:,0:self.nBaud] = self.code
602 602
603 603 self.fft_code = numpy.conj(numpy.fft.fft(__codeBuffer, axis=1))
604 604
605 605 self.ndatadec = self.__nHeis - self.nBaud + 1
606 606
607 607 self.datadecTime = numpy.zeros((self.__nChannels, self.ndatadec), dtype=numpy.complex)
608 608
609 609 def convolutionInFreq(self, data):
610 610
611 611 fft_code = self.fft_code[self.__profIndex].reshape(1,-1)
612 612
613 613 fft_data = numpy.fft.fft(data, axis=1)
614 614
615 615 conv = fft_data*fft_code
616 616
617 617 data = numpy.fft.ifft(conv,axis=1)
618 618
619 619 datadec = data[:,:-self.nBaud+1]
620 620
621 621 return datadec
622 622
623 623 def convolutionInFreqOpt(self, data):
624 624
625 625 fft_code = self.fft_code[self.__profIndex].reshape(1,-1)
626 626
627 627 data = cfunctions.decoder(fft_code, data)
628 628
629 629 datadec = data[:,:-self.nBaud+1]
630 630
631 631 return datadec
632 632
633 633 def convolutionInTime(self, data):
634 634
635 635 code = self.code[self.__profIndex]
636 636
637 637 for i in range(self.__nChannels):
638 638 self.datadecTime[i,:] = numpy.correlate(data[i,:], code, mode='valid')
639 639
640 640 return self.datadecTime
641 641
642 642 def run(self, dataOut, code=None, nCode=None, nBaud=None, mode = 0):
643 643
644 644 if not self.__isConfig:
645 645
646 646 if code == None:
647 647 code = dataOut.code
648 648 else:
649 649 code = numpy.array(code).reshape(nCode,nBaud)
650 650 dataOut.code = code
651 651 dataOut.nCode = nCode
652 652 dataOut.nBaud = nBaud
653 653
654 654 if code == None:
655 655 return 1
656 656
657 657 self.setup(code, dataOut.data.shape)
658 658 self.__isConfig = True
659 659
660 660 if mode == 0:
661 661 datadec = self.convolutionInTime(dataOut.data)
662 662
663 663 if mode == 1:
664 664 datadec = self.convolutionInFreq(dataOut.data)
665 665
666 666 if mode == 2:
667 667 datadec = self.convolutionInFreqOpt(dataOut.data)
668 668
669 669 dataOut.data = datadec
670 670
671 671 dataOut.heightList = dataOut.heightList[0:self.ndatadec]
672 672
673 673 dataOut.flagDecodeData = True #asumo q la data no esta decodificada
674 674
675 675 if self.__profIndex == self.nCode-1:
676 676 self.__profIndex = 0
677 677 return 1
678 678
679 679 self.__profIndex += 1
680 680
681 681 return 1
682 682 # dataOut.flagDeflipData = True #asumo q la data no esta sin flip
683 683
684 684
685 685
686 686 class SpectraProc(ProcessingUnit):
687 687
688 688 def __init__(self):
689 689
690 690 self.objectDict = {}
691 691 self.buffer = None
692 692 self.firstdatatime = None
693 693 self.profIndex = 0
694 694 self.dataOut = Spectra()
695 695
696 696 def __updateObjFromInput(self):
697 697
698 698 self.dataOut.timeZone = self.dataIn.timeZone
699 699 self.dataOut.dstFlag = self.dataIn.dstFlag
700 700 self.dataOut.errorCount = self.dataIn.errorCount
701 701 self.dataOut.useLocalTime = self.dataIn.useLocalTime
702 702
703 703 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
704 704 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
705 705 self.dataOut.channelList = self.dataIn.channelList
706 706 self.dataOut.heightList = self.dataIn.heightList
707 707 self.dataOut.dtype = numpy.dtype([('real','<f4'),('imag','<f4')])
708 708 # self.dataOut.nHeights = self.dataIn.nHeights
709 709 # self.dataOut.nChannels = self.dataIn.nChannels
710 710 self.dataOut.nBaud = self.dataIn.nBaud
711 711 self.dataOut.nCode = self.dataIn.nCode
712 712 self.dataOut.code = self.dataIn.code
713 713 self.dataOut.nProfiles = self.dataOut.nFFTPoints
714 714 # self.dataOut.channelIndexList = self.dataIn.channelIndexList
715 715 self.dataOut.flagTimeBlock = self.dataIn.flagTimeBlock
716 716 self.dataOut.utctime = self.firstdatatime
717 717 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData #asumo q la data esta decodificada
718 718 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData #asumo q la data esta sin flip
719 719 # self.dataOut.flagShiftFFT = self.dataIn.flagShiftFFT
720 720 self.dataOut.nCohInt = self.dataIn.nCohInt
721 721 self.dataOut.nIncohInt = 1
722 722 self.dataOut.ippSeconds = self.dataIn.ippSeconds
723 723 self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
724 724
725 725 self.dataOut.timeInterval = self.dataIn.timeInterval*self.dataOut.nFFTPoints*self.dataOut.nIncohInt
726 726
727 727 def __getFft(self):
728 728 """
729 729 Convierte valores de Voltaje a Spectra
730 730
731 731 Affected:
732 732 self.dataOut.data_spc
733 733 self.dataOut.data_cspc
734 734 self.dataOut.data_dc
735 735 self.dataOut.heightList
736 736 self.profIndex
737 737 self.buffer
738 738 self.dataOut.flagNoData
739 739 """
740 740 fft_volt = numpy.fft.fft(self.buffer,axis=1)
741 741 fft_volt = fft_volt.astype(numpy.dtype('complex'))
742 742 dc = fft_volt[:,0,:]
743 743
744 744 #calculo de self-spectra
745 745 fft_volt = numpy.fft.fftshift(fft_volt,axes=(1,))
746 746 spc = fft_volt * numpy.conjugate(fft_volt)
747 747 spc = spc.real
748 748
749 749 blocksize = 0
750 750 blocksize += dc.size
751 751 blocksize += spc.size
752 752
753 753 cspc = None
754 754 pairIndex = 0
755 755 if self.dataOut.pairsList != None:
756 756 #calculo de cross-spectra
757 757 cspc = numpy.zeros((self.dataOut.nPairs, self.dataOut.nFFTPoints, self.dataOut.nHeights), dtype='complex')
758 758 for pair in self.dataOut.pairsList:
759 759 cspc[pairIndex,:,:] = fft_volt[pair[0],:,:] * numpy.conjugate(fft_volt[pair[1],:,:])
760 760 pairIndex += 1
761 761 blocksize += cspc.size
762 762
763 763 self.dataOut.data_spc = spc
764 764 self.dataOut.data_cspc = cspc
765 765 self.dataOut.data_dc = dc
766 766 self.dataOut.blockSize = blocksize
767 767 self.dataOut.flagShiftFFT = False
768 768
769 769 def init(self, nFFTPoints=None, pairsList=None):
770 770
771 771 self.dataOut.flagNoData = True
772 772
773 773 if self.dataIn.type == "Spectra":
774 774 self.dataOut.copy(self.dataIn)
775 775 return
776 776
777 777 if self.dataIn.type == "Voltage":
778 778
779 779 if nFFTPoints == None:
780 780 raise ValueError, "This SpectraProc.init() need nFFTPoints input variable"
781 781
782 782 if pairsList == None:
783 783 nPairs = 0
784 784 else:
785 785 nPairs = len(pairsList)
786 786
787 787 self.dataOut.nFFTPoints = nFFTPoints
788 788 self.dataOut.pairsList = pairsList
789 789 self.dataOut.nPairs = nPairs
790 790
791 791 if self.buffer == None:
792 792 self.buffer = numpy.zeros((self.dataIn.nChannels,
793 793 self.dataOut.nFFTPoints,
794 794 self.dataIn.nHeights),
795 795 dtype='complex')
796 796
797 797
798 798 self.buffer[:,self.profIndex,:] = self.dataIn.data.copy()
799 799 self.profIndex += 1
800 800
801 801 if self.firstdatatime == None:
802 802 self.firstdatatime = self.dataIn.utctime
803 803
804 804 if self.profIndex == self.dataOut.nFFTPoints:
805 805 self.__updateObjFromInput()
806 806 self.__getFft()
807 807
808 808 self.dataOut.flagNoData = False
809 809
810 810 self.buffer = None
811 811 self.firstdatatime = None
812 812 self.profIndex = 0
813 813
814 814 return
815 815
816 816 raise ValuError, "The type object %s is not valid"%(self.dataIn.type)
817 817
818 818 def selectChannels(self, channelList):
819 819
820 820 channelIndexList = []
821 821
822 822 for channel in channelList:
823 823 index = self.dataOut.channelList.index(channel)
824 824 channelIndexList.append(index)
825 825
826 826 self.selectChannelsByIndex(channelIndexList)
827 827
828 828 def selectChannelsByIndex(self, channelIndexList):
829 829 """
830 830 Selecciona un bloque de datos en base a canales segun el channelIndexList
831 831
832 832 Input:
833 833 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
834 834
835 835 Affected:
836 836 self.dataOut.data_spc
837 837 self.dataOut.channelIndexList
838 838 self.dataOut.nChannels
839 839
840 840 Return:
841 841 None
842 842 """
843 843
844 844 for channelIndex in channelIndexList:
845 845 if channelIndex not in self.dataOut.channelIndexList:
846 846 print channelIndexList
847 847 raise ValueError, "The value %d in channelIndexList is not valid" %channelIndex
848 848
849 849 nChannels = len(channelIndexList)
850 850
851 851 data_spc = self.dataOut.data_spc[channelIndexList,:]
852 852
853 853 self.dataOut.data_spc = data_spc
854 854 self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
855 855 # self.dataOut.nChannels = nChannels
856 856
857 857 return 1
858 858
859 859 def selectHeights(self, minHei, maxHei):
860 860 """
861 861 Selecciona un bloque de datos en base a un grupo de valores de alturas segun el rango
862 862 minHei <= height <= maxHei
863 863
864 864 Input:
865 865 minHei : valor minimo de altura a considerar
866 866 maxHei : valor maximo de altura a considerar
867 867
868 868 Affected:
869 869 Indirectamente son cambiados varios valores a travez del metodo selectHeightsByIndex
870 870
871 871 Return:
872 872 1 si el metodo se ejecuto con exito caso contrario devuelve 0
873 873 """
874 874 if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei):
875 875 raise ValueError, "some value in (%d,%d) is not valid" % (minHei, maxHei)
876 876
877 877 if (maxHei > self.dataOut.heightList[-1]):
878 878 maxHei = self.dataOut.heightList[-1]
879 879 # raise ValueError, "some value in (%d,%d) is not valid" % (minHei, maxHei)
880 880
881 881 minIndex = 0
882 882 maxIndex = 0
883 883 heights = self.dataOut.heightList
884 884
885 885 inda = numpy.where(heights >= minHei)
886 886 indb = numpy.where(heights <= maxHei)
887 887
888 888 try:
889 889 minIndex = inda[0][0]
890 890 except:
891 891 minIndex = 0
892 892
893 893 try:
894 894 maxIndex = indb[0][-1]
895 895 except:
896 896 maxIndex = len(heights)
897 897
898 898 self.selectHeightsByIndex(minIndex, maxIndex)
899 899
900 900 return 1
901 901
902 902
903 903 def selectHeightsByIndex(self, minIndex, maxIndex):
904 904 """
905 905 Selecciona un bloque de datos en base a un grupo indices de alturas segun el rango
906 906 minIndex <= index <= maxIndex
907 907
908 908 Input:
909 909 minIndex : valor de indice minimo de altura a considerar
910 910 maxIndex : valor de indice maximo de altura a considerar
911 911
912 912 Affected:
913 913 self.dataOut.data_spc
914 914 self.dataOut.data_cspc
915 915 self.dataOut.data_dc
916 916 self.dataOut.heightList
917 917
918 918 Return:
919 919 1 si el metodo se ejecuto con exito caso contrario devuelve 0
920 920 """
921 921
922 922 if (minIndex < 0) or (minIndex > maxIndex):
923 923 raise ValueError, "some value in (%d,%d) is not valid" % (minIndex, maxIndex)
924 924
925 925 if (maxIndex >= self.dataOut.nHeights):
926 926 maxIndex = self.dataOut.nHeights-1
927 927 # raise ValueError, "some value in (%d,%d) is not valid" % (minIndex, maxIndex)
928 928
929 929 nHeights = maxIndex - minIndex + 1
930 930
931 931 #Spectra
932 932 data_spc = self.dataOut.data_spc[:,:,minIndex:maxIndex+1]
933 933
934 934 data_cspc = None
935 935 if self.dataOut.data_cspc != None:
936 936 data_cspc = self.dataOut.data_cspc[:,:,minIndex:maxIndex+1]
937 937
938 938 data_dc = None
939 939 if self.dataOut.data_dc != None:
940 940 data_dc = self.dataOut.data_dc[:,minIndex:maxIndex+1]
941 941
942 942 self.dataOut.data_spc = data_spc
943 943 self.dataOut.data_cspc = data_cspc
944 944 self.dataOut.data_dc = data_dc
945 945
946 946 self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex+1]
947 947
948 948 return 1
949 949
950 950 def removeDC(self, mode = 1):
951 951
952 952 dc_index = 0
953 953 freq_index = numpy.array([-2,-1,1,2])
954 954 data_spc = self.dataOut.data_spc
955 955 data_cspc = self.dataOut.data_cspc
956 956 data_dc = self.dataOut.data_dc
957 957
958 958 if self.dataOut.flagShiftFFT:
959 959 dc_index += self.dataOut.nFFTPoints/2
960 960 freq_index += self.dataOut.nFFTPoints/2
961 961
962 962 if mode == 1:
963 963 data_spc[dc_index] = (data_spc[:,freq_index[1],:] + data_spc[:,freq_index[2],:])/2
964 964 if data_cspc != None:
965 965 data_cspc[dc_index] = (data_cspc[:,freq_index[1],:] + data_cspc[:,freq_index[2],:])/2
966 966 return 1
967 967
968 968 if mode == 2:
969 969 pass
970 970
971 971 if mode == 3:
972 972 pass
973 973
974 974 raise ValueError, "mode parameter has to be 1, 2 or 3"
975 975
976 976 def removeInterference(self):
977 977
978 978 pass
979 979
980 980
981 981 class IncohInt(Operation):
982 982
983 983
984 984 __profIndex = 0
985 985 __withOverapping = False
986 986
987 987 __byTime = False
988 988 __initime = None
989 989 __lastdatatime = None
990 990 __integrationtime = None
991 991
992 992 __buffer_spc = None
993 993 __buffer_cspc = None
994 994 __buffer_dc = None
995 995
996 996 __dataReady = False
997 997
998 998 __timeInterval = None
999 999
1000 1000 n = None
1001 1001
1002 1002
1003 1003
1004 1004 def __init__(self):
1005 1005
1006 1006 self.__isConfig = False
1007 1007
1008 1008 def setup(self, n=None, timeInterval=None, overlapping=False):
1009 1009 """
1010 1010 Set the parameters of the integration class.
1011 1011
1012 1012 Inputs:
1013 1013
1014 1014 n : Number of coherent integrations
1015 1015 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
1016 1016 overlapping :
1017 1017
1018 1018 """
1019 1019
1020 1020 self.__initime = None
1021 1021 self.__lastdatatime = 0
1022 1022 self.__buffer_spc = None
1023 1023 self.__buffer_cspc = None
1024 1024 self.__buffer_dc = None
1025 1025 self.__dataReady = False
1026 1026
1027 1027
1028 1028 if n == None and timeInterval == None:
1029 1029 raise ValueError, "n or timeInterval should be specified ..."
1030 1030
1031 1031 if n != None:
1032 1032 self.n = n
1033 1033 self.__byTime = False
1034 1034 else:
1035 1035 self.__integrationtime = timeInterval * 60. #if (type(timeInterval)!=integer) -> change this line
1036 1036 self.n = 9999
1037 1037 self.__byTime = True
1038 1038
1039 1039 if overlapping:
1040 1040 self.__withOverapping = True
1041 1041 else:
1042 1042 self.__withOverapping = False
1043 1043 self.__buffer_spc = 0
1044 1044 self.__buffer_cspc = 0
1045 1045 self.__buffer_dc = 0
1046 1046
1047 1047 self.__profIndex = 0
1048 1048
1049 1049 def putData(self, data_spc, data_cspc, data_dc):
1050 1050
1051 1051 """
1052 1052 Add a profile to the __buffer_spc and increase in one the __profileIndex
1053 1053
1054 1054 """
1055 1055
1056 1056 if not self.__withOverapping:
1057 1057 self.__buffer_spc += data_spc
1058 1058
1059 1059 if data_cspc == None:
1060 1060 self.__buffer_cspc = None
1061 1061 else:
1062 1062 self.__buffer_cspc += data_cspc
1063 1063
1064 1064 if data_dc == None:
1065 1065 self.__buffer_dc = None
1066 1066 else:
1067 1067 self.__buffer_dc += data_dc
1068 1068
1069 1069 self.__profIndex += 1
1070 1070 return
1071 1071
1072 1072 #Overlapping data
1073 1073 nChannels, nFFTPoints, nHeis = data_spc.shape
1074 1074 data_spc = numpy.reshape(data_spc, (1, nChannels, nFFTPoints, nHeis))
1075 1075 if data_cspc != None:
1076 1076 data_cspc = numpy.reshape(data_cspc, (1, -1, nFFTPoints, nHeis))
1077 1077 if data_dc != None:
1078 1078 data_dc = numpy.reshape(data_dc, (1, -1, nHeis))
1079 1079
1080 1080 #If the buffer is empty then it takes the data value
1081 1081 if self.__buffer_spc == None:
1082 1082 self.__buffer_spc = data_spc
1083 1083
1084 1084 if data_cspc == None:
1085 1085 self.__buffer_cspc = None
1086 1086 else:
1087 1087 self.__buffer_cspc += data_cspc
1088 1088
1089 1089 if data_dc == None:
1090 1090 self.__buffer_dc = None
1091 1091 else:
1092 1092 self.__buffer_dc += data_dc
1093 1093
1094 1094 self.__profIndex += 1
1095 1095 return
1096 1096
1097 1097 #If the buffer length is lower than n then stakcing the data value
1098 1098 if self.__profIndex < self.n:
1099 1099 self.__buffer_spc = numpy.vstack((self.__buffer_spc, data_spc))
1100 1100
1101 1101 if data_cspc != None:
1102 1102 self.__buffer_cspc = numpy.vstack((self.__buffer_cspc, data_cspc))
1103 1103
1104 1104 if data_dc != None:
1105 1105 self.__buffer_dc = numpy.vstack((self.__buffer_dc, data_dc))
1106 1106
1107 1107 self.__profIndex += 1
1108 1108 return
1109 1109
1110 1110 #If the buffer length is equal to n then replacing the last buffer value with the data value
1111 1111 self.__buffer_spc = numpy.roll(self.__buffer_spc, -1, axis=0)
1112 1112 self.__buffer_spc[self.n-1] = data_spc
1113 1113
1114 1114 if data_cspc != None:
1115 1115 self.__buffer_cspc = numpy.roll(self.__buffer_cspc, -1, axis=0)
1116 1116 self.__buffer_cspc[self.n-1] = data_cspc
1117 1117
1118 1118 if data_dc != None:
1119 1119 self.__buffer_dc = numpy.roll(self.__buffer_dc, -1, axis=0)
1120 1120 self.__buffer_dc[self.n-1] = data_dc
1121 1121
1122 1122 self.__profIndex = self.n
1123 1123 return
1124 1124
1125 1125
1126 1126 def pushData(self):
1127 1127 """
1128 1128 Return the sum of the last profiles and the profiles used in the sum.
1129 1129
1130 1130 Affected:
1131 1131
1132 1132 self.__profileIndex
1133 1133
1134 1134 """
1135 1135 data_spc = None
1136 1136 data_cspc = None
1137 1137 data_dc = None
1138 1138
1139 1139 if not self.__withOverapping:
1140 1140 data_spc = self.__buffer_spc
1141 1141 data_cspc = self.__buffer_cspc
1142 1142 data_dc = self.__buffer_dc
1143 1143
1144 1144 n = self.__profIndex
1145 1145
1146 1146 self.__buffer_spc = 0
1147 1147 self.__buffer_cspc = 0
1148 1148 self.__buffer_dc = 0
1149 1149 self.__profIndex = 0
1150 1150
1151 1151 return data_spc, data_cspc, data_dc, n
1152 1152
1153 1153 #Integration with Overlapping
1154 1154 data_spc = numpy.sum(self.__buffer_spc, axis=0)
1155 1155
1156 1156 if self.__buffer_cspc != None:
1157 1157 data_cspc = numpy.sum(self.__buffer_cspc, axis=0)
1158 1158
1159 1159 if self.__buffer_dc != None:
1160 1160 data_dc = numpy.sum(self.__buffer_dc, axis=0)
1161 1161
1162 1162 n = self.__profIndex
1163 1163
1164 1164 return data_spc, data_cspc, data_dc, n
1165 1165
1166 1166 def byProfiles(self, *args):
1167 1167
1168 1168 self.__dataReady = False
1169 1169 avgdata_spc = None
1170 1170 avgdata_cspc = None
1171 1171 avgdata_dc = None
1172 1172 n = None
1173 1173
1174 1174 self.putData(*args)
1175 1175
1176 1176 if self.__profIndex == self.n:
1177 1177
1178 1178 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1179 1179 self.__dataReady = True
1180 1180
1181 1181 return avgdata_spc, avgdata_cspc, avgdata_dc
1182 1182
1183 1183 def byTime(self, datatime, *args):
1184 1184
1185 1185 self.__dataReady = False
1186 1186 avgdata_spc = None
1187 1187 avgdata_cspc = None
1188 1188 avgdata_dc = None
1189 1189 n = None
1190 1190
1191 1191 self.putData(*args)
1192 1192
1193 1193 if (datatime - self.__initime) >= self.__integrationtime:
1194 1194 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1195 1195 self.n = n
1196 1196 self.__dataReady = True
1197 1197
1198 1198 return avgdata_spc, avgdata_cspc, avgdata_dc
1199 1199
1200 1200 def integrate(self, datatime, *args):
1201 1201
1202 1202 if self.__initime == None:
1203 1203 self.__initime = datatime
1204 1204
1205 1205 if self.__byTime:
1206 1206 avgdata_spc, avgdata_cspc, avgdata_dc = self.byTime(datatime, *args)
1207 1207 else:
1208 1208 avgdata_spc, avgdata_cspc, avgdata_dc = self.byProfiles(*args)
1209 1209
1210 1210 self.__lastdatatime = datatime
1211 1211
1212 1212 if avgdata_spc == None:
1213 1213 return None, None, None, None
1214 1214
1215 1215 avgdatatime = self.__initime
1216 self.__timeInterval = (self.__lastdatatime - self.__initime)/(self.n - 1)
1217
1216 try:
1217 self.__timeInterval = (self.__lastdatatime - self.__initime)/(self.n - 1)
1218 except:
1219 self.__timeInterval = self.__lastdatatime - self.__initime
1220
1218 1221 deltatime = datatime -self.__lastdatatime
1219 1222
1220 1223 if not self.__withOverapping:
1221 1224 self.__initime = datatime
1222 1225 else:
1223 1226 self.__initime += deltatime
1224 1227
1225 1228 return avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc
1226 1229
1227 1230 def run(self, dataOut, n=None, timeInterval=None, overlapping=False):
1228 1231
1229 1232 if n==1:
1230 1233 dataOut.flagNoData = False
1231 1234 return
1232 1235
1233 1236 if not self.__isConfig:
1234 1237 self.setup(n, timeInterval, overlapping)
1235 1238 self.__isConfig = True
1236 1239
1237 1240 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(dataOut.utctime,
1238 1241 dataOut.data_spc,
1239 1242 dataOut.data_cspc,
1240 1243 dataOut.data_dc)
1241 1244
1242 1245 # dataOut.timeInterval *= n
1243 1246 dataOut.flagNoData = True
1244 1247
1245 1248 if self.__dataReady:
1246 1249
1247 1250 dataOut.data_spc = avgdata_spc
1248 1251 dataOut.data_cspc = avgdata_cspc
1249 1252 dataOut.data_dc = avgdata_dc
1250 1253
1251 1254 dataOut.nIncohInt *= self.n
1252 1255 dataOut.utctime = avgdatatime
1253 1256 #dataOut.timeInterval = dataOut.ippSeconds * dataOut.nCohInt * dataOut.nIncohInt * dataOut.nFFTPoints
1254 1257 dataOut.timeInterval = self.__timeInterval*self.n
1255 1258 dataOut.flagNoData = False
1256 1259
1257 1260 class ProfileSelector(Operation):
1258 1261
1259 1262 profileIndex = None
1260 1263 # Tamanho total de los perfiles
1261 1264 nProfiles = None
1262 1265
1263 1266 def __init__(self):
1264 1267
1265 1268 self.profileIndex = 0
1266 1269
1267 1270 def incIndex(self):
1268 1271 self.profileIndex += 1
1269 1272
1270 1273 if self.profileIndex >= self.nProfiles:
1271 1274 self.profileIndex = 0
1272 1275
1273 1276 def isProfileInRange(self, minIndex, maxIndex):
1274 1277
1275 1278 if self.profileIndex < minIndex:
1276 1279 return False
1277 1280
1278 1281 if self.profileIndex > maxIndex:
1279 1282 return False
1280 1283
1281 1284 return True
1282 1285
1283 1286 def isProfileInList(self, profileList):
1284 1287
1285 1288 if self.profileIndex not in profileList:
1286 1289 return False
1287 1290
1288 1291 return True
1289 1292
1290 1293 def run(self, dataOut, profileList=None, profileRangeList=None):
1291 1294
1292 1295 dataOut.flagNoData = True
1293 1296 self.nProfiles = dataOut.nProfiles
1294 1297
1295 1298 if profileList != None:
1296 1299 if self.isProfileInList(profileList):
1297 1300 dataOut.flagNoData = False
1298 1301
1299 1302 self.incIndex()
1300 1303 return 1
1301 1304
1302 1305
1303 1306 elif profileRangeList != None:
1304 1307 minIndex = profileRangeList[0]
1305 1308 maxIndex = profileRangeList[1]
1306 1309 if self.isProfileInRange(minIndex, maxIndex):
1307 1310 dataOut.flagNoData = False
1308 1311
1309 1312 self.incIndex()
1310 1313 return 1
1311 1314
1312 1315 else:
1313 1316 raise ValueError, "ProfileSelector needs profileList or profileRangeList"
1314 1317
1315 1318 return 0
1316 1319
1317 1320 class SpectraHeisProc(ProcessingUnit):
1318 1321 def __init__(self):
1319 1322 self.objectDict = {}
1320 1323 # self.buffer = None
1321 1324 # self.firstdatatime = None
1322 1325 # self.profIndex = 0
1323 1326 self.dataOut = SpectraHeis()
1324 1327
1325 1328 def __updateObjFromInput(self):
1326 1329 self.dataOut.timeZone = self.dataIn.timeZone
1327 1330 self.dataOut.dstFlag = self.dataIn.dstFlag
1328 1331 self.dataOut.errorCount = self.dataIn.errorCount
1329 1332 self.dataOut.useLocalTime = self.dataIn.useLocalTime
1330 1333
1331 1334 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()#
1332 1335 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()#
1333 1336 self.dataOut.channelList = self.dataIn.channelList
1334 1337 self.dataOut.heightList = self.dataIn.heightList
1335 1338 # self.dataOut.dtype = self.dataIn.dtype
1336 1339 self.dataOut.dtype = numpy.dtype([('real','<f4'),('imag','<f4')])
1337 1340 # self.dataOut.nHeights = self.dataIn.nHeights
1338 1341 # self.dataOut.nChannels = self.dataIn.nChannels
1339 1342 self.dataOut.nBaud = self.dataIn.nBaud
1340 1343 self.dataOut.nCode = self.dataIn.nCode
1341 1344 self.dataOut.code = self.dataIn.code
1342 1345 # self.dataOut.nProfiles = 1
1343 1346 # self.dataOut.nProfiles = self.dataOut.nFFTPoints
1344 1347 self.dataOut.nFFTPoints = self.dataIn.nHeights
1345 1348 # self.dataOut.channelIndexList = self.dataIn.channelIndexList
1346 1349 # self.dataOut.flagNoData = self.dataIn.flagNoData
1347 1350 self.dataOut.flagTimeBlock = self.dataIn.flagTimeBlock
1348 1351 self.dataOut.utctime = self.dataIn.utctime
1349 1352 # self.dataOut.utctime = self.firstdatatime
1350 1353 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData #asumo q la data esta decodificada
1351 1354 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData #asumo q la data esta sin flip
1352 1355 # self.dataOut.flagShiftFFT = self.dataIn.flagShiftFFT
1353 1356 self.dataOut.nCohInt = self.dataIn.nCohInt
1354 1357 self.dataOut.nIncohInt = 1
1355 1358 self.dataOut.ippSeconds= self.dataIn.ippSeconds
1356 1359 self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
1357 1360
1358 1361 self.dataOut.timeInterval = self.dataIn.timeInterval*self.dataOut.nIncohInt
1359 1362 # self.dataOut.set=self.dataIn.set
1360 1363 # self.dataOut.deltaHeight=self.dataIn.deltaHeight
1361 1364
1362 1365
1363 1366 def __getFft(self):
1364 1367
1365 1368 fft_volt = numpy.fft.fft(self.dataIn.data, axis=1)
1366 1369 fft_volt = numpy.fft.fftshift(fft_volt,axes=(1,))
1367 1370 spc = numpy.abs(fft_volt * numpy.conjugate(fft_volt))/(self.dataOut.nFFTPoints)
1368 1371 self.dataOut.data_spc = spc
1369 1372
1370 1373 def init(self):
1371 1374
1372 1375 self.dataOut.flagNoData = True
1373 1376
1374 1377 if self.dataIn.type == "SpectraHeis":
1375 1378 self.dataOut.copy(self.dataIn)
1376 1379 return
1377 1380
1378 1381 if self.dataIn.type == "Voltage":
1379 1382 self.__updateObjFromInput()
1380 1383 self.__getFft()
1381 1384 self.dataOut.flagNoData = False
1382 1385
1383 1386 return
1384 1387
1385 1388 raise ValuError, "The type object %s is not valid"%(self.dataIn.type)
1386 1389
1387 1390
1388 1391 def selectChannels(self, channelList):
1389 1392
1390 1393 channelIndexList = []
1391 1394
1392 1395 for channel in channelList:
1393 1396 index = self.dataOut.channelList.index(channel)
1394 1397 channelIndexList.append(index)
1395 1398
1396 1399 self.selectChannelsByIndex(channelIndexList)
1397 1400
1398 1401 def selectChannelsByIndex(self, channelIndexList):
1399 1402 """
1400 1403 Selecciona un bloque de datos en base a canales segun el channelIndexList
1401 1404
1402 1405 Input:
1403 1406 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
1404 1407
1405 1408 Affected:
1406 1409 self.dataOut.data
1407 1410 self.dataOut.channelIndexList
1408 1411 self.dataOut.nChannels
1409 1412 self.dataOut.m_ProcessingHeader.totalSpectra
1410 1413 self.dataOut.systemHeaderObj.numChannels
1411 1414 self.dataOut.m_ProcessingHeader.blockSize
1412 1415
1413 1416 Return:
1414 1417 None
1415 1418 """
1416 1419
1417 1420 for channelIndex in channelIndexList:
1418 1421 if channelIndex not in self.dataOut.channelIndexList:
1419 1422 print channelIndexList
1420 1423 raise ValueError, "The value %d in channelIndexList is not valid" %channelIndex
1421 1424
1422 1425 nChannels = len(channelIndexList)
1423 1426
1424 1427 data_spc = self.dataOut.data_spc[channelIndexList,:]
1425 1428
1426 1429 self.dataOut.data_spc = data_spc
1427 1430 self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
1428 1431
1429 1432 return 1
1430 1433
1431 1434 class IncohInt4SpectraHeis(Operation):
1432 1435
1433 1436 __isConfig = False
1434 1437
1435 1438 __profIndex = 0
1436 1439 __withOverapping = False
1437 1440
1438 1441 __byTime = False
1439 1442 __initime = None
1440 1443 __lastdatatime = None
1441 1444 __integrationtime = None
1442 1445
1443 1446 __buffer = None
1444 1447
1445 1448 __dataReady = False
1446 1449
1447 1450 n = None
1448 1451
1449 1452
1450 1453 def __init__(self):
1451 1454
1452 1455 self.__isConfig = False
1453 1456
1454 1457 def setup(self, n=None, timeInterval=None, overlapping=False):
1455 1458 """
1456 1459 Set the parameters of the integration class.
1457 1460
1458 1461 Inputs:
1459 1462
1460 1463 n : Number of coherent integrations
1461 1464 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
1462 1465 overlapping :
1463 1466
1464 1467 """
1465 1468
1466 1469 self.__initime = None
1467 1470 self.__lastdatatime = 0
1468 1471 self.__buffer = None
1469 1472 self.__dataReady = False
1470 1473
1471 1474
1472 1475 if n == None and timeInterval == None:
1473 1476 raise ValueError, "n or timeInterval should be specified ..."
1474 1477
1475 1478 if n != None:
1476 1479 self.n = n
1477 1480 self.__byTime = False
1478 1481 else:
1479 1482 self.__integrationtime = timeInterval #* 60. #if (type(timeInterval)!=integer) -> change this line
1480 1483 self.n = 9999
1481 1484 self.__byTime = True
1482 1485
1483 1486 if overlapping:
1484 1487 self.__withOverapping = True
1485 1488 self.__buffer = None
1486 1489 else:
1487 1490 self.__withOverapping = False
1488 1491 self.__buffer = 0
1489 1492
1490 1493 self.__profIndex = 0
1491 1494
1492 1495 def putData(self, data):
1493 1496
1494 1497 """
1495 1498 Add a profile to the __buffer and increase in one the __profileIndex
1496 1499
1497 1500 """
1498 1501
1499 1502 if not self.__withOverapping:
1500 1503 self.__buffer += data.copy()
1501 1504 self.__profIndex += 1
1502 1505 return
1503 1506
1504 1507 #Overlapping data
1505 1508 nChannels, nHeis = data.shape
1506 1509 data = numpy.reshape(data, (1, nChannels, nHeis))
1507 1510
1508 1511 #If the buffer is empty then it takes the data value
1509 1512 if self.__buffer == None:
1510 1513 self.__buffer = data
1511 1514 self.__profIndex += 1
1512 1515 return
1513 1516
1514 1517 #If the buffer length is lower than n then stakcing the data value
1515 1518 if self.__profIndex < self.n:
1516 1519 self.__buffer = numpy.vstack((self.__buffer, data))
1517 1520 self.__profIndex += 1
1518 1521 return
1519 1522
1520 1523 #If the buffer length is equal to n then replacing the last buffer value with the data value
1521 1524 self.__buffer = numpy.roll(self.__buffer, -1, axis=0)
1522 1525 self.__buffer[self.n-1] = data
1523 1526 self.__profIndex = self.n
1524 1527 return
1525 1528
1526 1529
1527 1530 def pushData(self):
1528 1531 """
1529 1532 Return the sum of the last profiles and the profiles used in the sum.
1530 1533
1531 1534 Affected:
1532 1535
1533 1536 self.__profileIndex
1534 1537
1535 1538 """
1536 1539
1537 1540 if not self.__withOverapping:
1538 1541 data = self.__buffer
1539 1542 n = self.__profIndex
1540 1543
1541 1544 self.__buffer = 0
1542 1545 self.__profIndex = 0
1543 1546
1544 1547 return data, n
1545 1548
1546 1549 #Integration with Overlapping
1547 1550 data = numpy.sum(self.__buffer, axis=0)
1548 1551 n = self.__profIndex
1549 1552
1550 1553 return data, n
1551 1554
1552 1555 def byProfiles(self, data):
1553 1556
1554 1557 self.__dataReady = False
1555 1558 avgdata = None
1556 1559 n = None
1557 1560
1558 1561 self.putData(data)
1559 1562
1560 1563 if self.__profIndex == self.n:
1561 1564
1562 1565 avgdata, n = self.pushData()
1563 1566 self.__dataReady = True
1564 1567
1565 1568 return avgdata
1566 1569
1567 1570 def byTime(self, data, datatime):
1568 1571
1569 1572 self.__dataReady = False
1570 1573 avgdata = None
1571 1574 n = None
1572 1575
1573 1576 self.putData(data)
1574 1577
1575 1578 if (datatime - self.__initime) >= self.__integrationtime:
1576 1579 avgdata, n = self.pushData()
1577 1580 self.n = n
1578 1581 self.__dataReady = True
1579 1582
1580 1583 return avgdata
1581 1584
1582 1585 def integrate(self, data, datatime=None):
1583 1586
1584 1587 if self.__initime == None:
1585 1588 self.__initime = datatime
1586 1589
1587 1590 if self.__byTime:
1588 1591 avgdata = self.byTime(data, datatime)
1589 1592 else:
1590 1593 avgdata = self.byProfiles(data)
1591 1594
1592 1595
1593 1596 self.__lastdatatime = datatime
1594 1597
1595 1598 if avgdata == None:
1596 1599 return None, None
1597 1600
1598 1601 avgdatatime = self.__initime
1599 1602
1600 1603 deltatime = datatime -self.__lastdatatime
1601 1604
1602 1605 if not self.__withOverapping:
1603 1606 self.__initime = datatime
1604 1607 else:
1605 1608 self.__initime += deltatime
1606 1609
1607 1610 return avgdata, avgdatatime
1608 1611
1609 1612 def run(self, dataOut, **kwargs):
1610 1613
1611 1614 if not self.__isConfig:
1612 1615 self.setup(**kwargs)
1613 1616 self.__isConfig = True
1614 1617
1615 1618 avgdata, avgdatatime = self.integrate(dataOut.data_spc, dataOut.utctime)
1616 1619
1617 1620 # dataOut.timeInterval *= n
1618 1621 dataOut.flagNoData = True
1619 1622
1620 1623 if self.__dataReady:
1621 1624 dataOut.data_spc = avgdata
1622 1625 dataOut.nIncohInt *= self.n
1623 1626 # dataOut.nCohInt *= self.n
1624 1627 dataOut.utctime = avgdatatime
1625 1628 dataOut.timeInterval = dataOut.ippSeconds * dataOut.nIncohInt
1626 1629 # dataOut.timeInterval = self.__timeInterval*self.n
1627 1630 dataOut.flagNoData = False
1628 1631
1629 1632
1630 1633
1631 1634
1632 1635 No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now