##// END OF EJS Templates
VoltageIO.py...
Victor Sarmiento -
r37:00fd38b85cf6
parent child
Show More
This diff has been collapsed as it changes many lines, (786 lines changed) Show them Hide them
@@ -20,6 +20,106 from IO.DataIO import DataWriter
20
20
21 from Model.Voltage import Voltage
21 from Model.Voltage import Voltage
22
22
23
24 def getlastFileFromPath( pathList, ext ):
25 """
26 Depura el pathList dejando solo los que cumplan el formato de "PYYYYDDDSSS.ext"
27 al final de la depuracion devuelve el ultimo file de la lista que quedo.
28
29 Input:
30 pathList : lista conteniendo todos los filename completos que componen una determinada carpeta
31 ext : extension de los files contenidos en una carpeta
32
33 Return:
34 El ultimo file de una determinada carpeta
35 """
36
37 filesList = []
38 filename = None
39
40 # 0 1234 567 89A BCDE
41 # D YYYY DDD SSS .ext
42
43 for filename in pathList:
44 year = filename[1:5]
45 doy = filename[5:8]
46 leng = len( ext )
47
48 if ( filename[-leng:].upper() != ext.upper() ) : continue
49 if not( isNumber( year ) ) : continue
50 if not( isNumber( doy ) ) : continue
51
52 filesList.append(filename)
53
54 if len( filesList ) > 0:
55 filesList = sorted( filesList, key=str.lower )
56 filename = filesList[-1]
57
58 return filename
59
60
61 def checkForRealPath( path, year, doy, set, ext ):
62 """
63 Por ser Linux Case Sensitive entonces checkForRealPath encuentra el nombre correcto de un path,
64 Prueba por varias combinaciones de nombres entre mayusculas y minusculas para determinar
65 el path exacto de un determinado file.
66
67 Example :
68 nombre correcto del file es ../RAWDATA/D2009307/P2009307367
69
70 Entonces la funcion prueba con las siguientes combinaciones
71 ../RAWDATA/d2009307/p2009307367
72 ../RAWDATA/d2009307/P2009307367
73 ../RAWDATA/D2009307/p2009307367
74 ../RAWDATA/D2009307/P2009307367
75 siendo para este caso, la ultima combinacion de letras, identica al file buscado
76
77 Return:
78 Si encuentra la cobinacion adecuada devuelve el path completo y el nombre del file
79 caso contrario devuelve None como path y el la ultima combinacion de nombre en mayusculas
80 para el filename
81 """
82 filepath = None
83 find_flag = False
84 filename = None
85
86 for dir in "dD": #barrido por las dos combinaciones posibles de "D"
87 for fil in "dD": #barrido por las dos combinaciones posibles de "D"
88 doypath = "%s%04d%03d" % ( dir, year, doy ) #formo el nombre del directorio xYYYYDDD (x=d o x=D)
89 filename = "%s%04d%03d%03d%s" % ( fil, year, doy, set, ext ) #formo el nombre del file xYYYYDDDSSS.ext (p=d o p=D)
90 filepath = os.path.join( path, doypath, filename ) #formo el path completo
91 if os.path.exists( filepath ): #verifico que exista
92 find_flag = True
93 break
94 if find_flag:
95 break
96
97 if not(find_flag):
98 return None, filename
99
100 return filepath, filename
101
102
103 def isNumber( str ):
104 """
105 Chequea si el conjunto de caracteres que componen un string puede ser convertidos a un numero.
106
107 Excepciones:
108 Si un determinado string no puede ser convertido a numero
109 Input:
110 str, string al cual se le analiza para determinar si convertible a un numero o no
111
112 Return:
113 True : si el string es uno numerico
114 False : no es un string numerico
115 """
116 try:
117 float( str )
118 return True
119 except:
120 return False
121
122
23 def isThisFileinRange(filename, startUTSeconds, endUTSeconds):
123 def isThisFileinRange(filename, startUTSeconds, endUTSeconds):
24 """
124 """
25 Esta funcion determina si un archivo de datos en formato Jicamarca(.r) se encuentra
125 Esta funcion determina si un archivo de datos en formato Jicamarca(.r) se encuentra
@@ -188,6 +288,17 class VoltageReader(DataReader):
188 self.datablock = None
288 self.datablock = None
189
289
190 self.__datablockIndex = 9999
290 self.__datablockIndex = 9999
291
292 self.__delay = 7 #seconds
293 self.__nTries = 3 #quantity tries
294 self.__nFiles = 3 #number of files for searching
295 self.__year = 0
296 self.__doy = 0
297 self.__set = 0
298 self.__ext = None
299 self.__path = None
300 self.__pts2read = 0
301 self.__blocksize = 0
191
302
192 def __rdSystemHeader(self,fp=None):
303 def __rdSystemHeader(self,fp=None):
193 if fp == None:
304 if fp == None:
@@ -252,9 +363,141 class VoltageReader(DataReader):
252 self.__dataType = tmp
363 self.__dataType = tmp
253 self.__fileSizeByHeader = self.m_ProcessingHeader.dataBlocksPerFile * self.m_ProcessingHeader.blockSize + self.firstHeaderSize + self.basicHeaderSize*(self.m_ProcessingHeader.dataBlocksPerFile - 1)
364 self.__fileSizeByHeader = self.m_ProcessingHeader.dataBlocksPerFile * self.m_ProcessingHeader.blockSize + self.firstHeaderSize + self.basicHeaderSize*(self.m_ProcessingHeader.dataBlocksPerFile - 1)
254 self.__ippSeconds = 2*1000*self.m_RadarControllerHeader.ipp/self.__c
365 self.__ippSeconds = 2*1000*self.m_RadarControllerHeader.ipp/self.__c
366
367 self.__pts2read = self.m_ProcessingHeader.profilesPerBlock * self.m_ProcessingHeader.numHeights * self.m_SystemHeader.numChannels
368 self.__blocksize = self.__pts2read
369
255
370
256 def __setNextFileOnline(self):
371 def __setNextFileOnline( self ):
257 return 0
372 """
373 Busca el siguiente file que tenga suficiente data para ser leida, dentro de un folder especifico, si
374 no encuentra un file valido espera un tiempo determinado y luego busca en los posibles n files
375 siguientes.
376
377 Affected:
378 self.__flagIsNewFile
379 self.filename
380 self.fileSize
381 self.__fp
382 self.__set
383 self.noMoreFiles
384
385 Return:
386 0 : si luego de una busqueda del siguiente file valido este no pudo ser encontrado
387 1 : si el file fue abierto con exito y esta listo a ser leido
388
389 Excepciones:
390 Si un determinado file no puede ser abierto
391 """
392 countFiles = 0
393 countTries = 0
394
395 fileStatus = 0
396 notFirstTime_flag = False
397 bChangeDir = False
398
399 fileSize = 0
400 fp = None
401
402 self.__flagIsNewFile = 0
403
404 while( True ): #este loop permite llevar la cuenta de intentos, de files y carpetas,
405 #si no encuentra alguno sale del bucle
406 countFiles += 1
407
408 if countFiles > (self.__nFiles + 1):
409 break
410
411 self.__set += 1
412
413 if countFiles > self.__nFiles: #si no encuentro el file buscado cambio de carpeta y busco en la siguiente carpeta
414 self.__set = 0
415 self.__doy += 1
416 bChangeDir = True
417
418 file = None
419 filename = None
420
421 countTries = 0
422
423 #espero hasta encontrar el 1er file disponible
424 while( True ):
425
426 countTries += 1
427 if( countTries >= self.__nTries ): #checkeo que no haya ido mas alla de la cantidad de intentos
428 break
429
430 file, filename = checkForRealPath( self.__path, self.__year, self.__doy, self.__set, self.__ext )
431 if file != None:
432 break
433
434 if notFirstTime_flag: #este flag me sirve solo para esperar por el 1er file, en lo siguientes no espera solo checkea si existe o no
435 countTries = self.__nTries
436 print "\tsearching next \"%s\" file ..." % filename
437 break
438
439 print "\twaiting new \"%s\" file ..." % filename
440 time.sleep( self.__delay )
441
442 if countTries >= self.__nTries: #se realizaron n intentos y no hubo un file nuevo
443 notFirstTime_flag = True
444 continue #vuelvo al inico del while principal
445
446 countTries = 0
447
448 #una vez que se obtuvo el 1er file valido se procede a checkear su contenido, y se espera una cierta cantidad
449 #de tiempo por una cierta cantidad de veces hasta que el contenido del file sea un contenido valido
450 while( True ):
451 countTries += 1
452 if countTries > self.__nTries:
453 break
454
455 try:
456 fp = open(file)
457 except:
458 print "The file \"%s\" can't be opened" % file
459 break
460
461 fileSize = os.path.getsize( file )
462 currentSize = fileSize - fp.tell()
463 neededSize = self.m_ProcessingHeader.blockSize + self.firstHeaderSize
464
465 if currentSize > neededSize:
466 fileStatus = 1
467 break
468
469 fp.close()
470
471 if bChangeDir: #si al buscar un file cambie de directorio ya no espero y salgo del bucle while
472 print "\tsearching next \"%s\" file ..." % filename
473 break
474
475 print "\twaiting for block of \"%s\" file ..." % filename
476 time.sleep( self.__delay )
477
478 if fileStatus == 1:
479 break
480
481 print "Skipping the file \"%s\" due to this files is empty" % filename
482 countFiles = 0
483
484
485 if fileStatus == 1:
486 self.fileSize = fileSize
487 self.filename = file
488 self.__flagIsNewFile = 1
489 self.__fp = fp
490 self.noMoreFiles = 0
491 print 'Setting the file: %s' % file
492 else:
493 self.fileSize = 0
494 self.filename = None
495 self.__fp = None
496 self.noMoreFiles = 1
497 print 'No more Files'
498
499 return fileStatus
500
258
501
259 def __setNextFileOffline(self):
502 def __setNextFileOffline(self):
260
503
@@ -294,8 +537,24 class VoltageReader(DataReader):
294
537
295 return 1
538 return 1
296
539
297 def __setNextFile(self):
540 def __setNextFile( self ):
298
541 """
542 Determina el siguiente file a leer y si hay uno disponible lee el First Header
543
544 Affected:
545 self.m_BasicHeader
546 self.m_SystemHeader
547 self.m_RadarControllerHeader
548 self.m_ProcessingHeader
549 self.firstHeaderSize
550
551 Return:
552 0 : Si no hay files disponibles
553 1 : Si hay mas files disponibles
554 """
555 if self.__fp != None:
556 self.__fp.close()
557
299 if self.online:
558 if self.online:
300 newFile = self.__setNextFileOnline()
559 newFile = self.__setNextFileOnline()
301 else:
560 else:
@@ -307,9 +566,21 class VoltageReader(DataReader):
307 self.__readFirstHeader()
566 self.__readFirstHeader()
308
567
309 return 1
568 return 1
310
311 def __setNewBlock(self):
312
569
570
571 def __setNewBlock( self ):
572 """
573 Lee el Basic Header y posiciona le file pointer en la posicion inicial del bloque a leer
574
575 Affected:
576 self.m_BasicHeader
577 self.flagResetProcessing
578 self.ns
579
580 Return:
581 0 : Si el file no tiene un Basic Header que pueda ser leido
582 1 : Si se pudo leer el Basic Header
583 """
313 if self.__fp == None:
584 if self.__fp == None:
314 return 0
585 return 0
315
586
@@ -320,12 +591,26 class VoltageReader(DataReader):
320 neededSize = self.m_ProcessingHeader.blockSize + self.basicHeaderSize
591 neededSize = self.m_ProcessingHeader.blockSize + self.basicHeaderSize
321
592
322 #If there is enough data setting new data block
593 #If there is enough data setting new data block
323 if (currentSize >= neededSize):
594 if ( currentSize >= neededSize ):
324 self.__rdBasicHeader()
595 self.__rdBasicHeader()
325 return 1
596 return 1
597 elif self.online:
598 nTries = 0
599 while( nTries < self.__nTries ):
600 nTries += 1
601 print "Waiting for the next block, try %03d ..." % nTries
602 time.sleep( self.__delay )
603
604 fileSize = os.path.getsize(self.filename)
605 currentSize = fileSize - self.__fp.tell()
606 neededSize = self.m_ProcessingHeader.blockSize + self.basicHeaderSize
607
608 if ( currentSize >= neededSize ):
609 self.__rdBasicHeader()
610 return 1
326
611
327 #Setting new file
612 #Setting new file
328 if not(self.__setNextFile()):
613 if not( self.__setNextFile() ):
329 return 0
614 return 0
330
615
331 deltaTime = self.m_BasicHeader.utc - self.__lastUTTime # check this
616 deltaTime = self.m_BasicHeader.utc - self.__lastUTTime # check this
@@ -368,11 +653,29 class VoltageReader(DataReader):
368
653
369 """
654 """
370
655
371 pts2read = self.m_ProcessingHeader.profilesPerBlock*self.m_ProcessingHeader.numHeights*self.m_SystemHeader.numChannels
656 #pts2read = self.m_ProcessingHeader.profilesPerBlock*self.m_ProcessingHeader.numHeights*self.m_SystemHeader.numChannels
372
657
373 junk = numpy.fromfile(self.__fp, self.__dataType, pts2read)
658 fpointer = self.__fp.tell()
374
659
375 junk = junk.reshape((self.m_ProcessingHeader.profilesPerBlock, self.m_ProcessingHeader.numHeights, self.m_SystemHeader.numChannels))
660 junk = numpy.fromfile( self.__fp, self.__dataType, self.__pts2read )
661
662 if self.online:
663 if junk.size != self.__blocksize:
664 nTries = 0
665 while( nTries < self.__nTries ):
666 nTries += 1
667 print "Waiting for the next block, try %03d ..." % nTries
668 time.sleep( self.__delay )
669 self.__fp.seek( fpointer )
670 fpointer = self.__fp.tell()
671 junk = numpy.fromfile( self.__fp, self.__dataType, self.__pts2read )
672 if junk.size == self.__blocksize:
673 nTries = 0
674 break
675 if nTries > 0:
676 return
677
678 junk = junk.reshape( (self.m_ProcessingHeader.profilesPerBlock, self.m_ProcessingHeader.numHeights, self.m_SystemHeader.numChannels) )
376
679
377 data = junk['real'] + junk['imag']*1j
680 data = junk['real'] + junk['imag']*1j
378
681
@@ -394,9 +697,69 class VoltageReader(DataReader):
394
697
395 return 0
698 return 0
396
699
397 def __searchFiles(self, path, startDateTime, endDateTime, set=None, expLabel = "", ext = ".r"):
700
701 def __searchFilesOnLine( self, path, startDateTime=None, ext = ".r" ):
398 """
702 """
399 __searchFiles realiza una busqueda de los archivos que coincidan con los parametros
703 Busca el ultimo archivo de la ultima carpeta (determinada o no por startDateTime) y
704 devuelve el archivo encontrado ademas de otros datos.
705
706 Input:
707 path : carpeta donde estan contenidos los files que contiene data
708 startDateTime : punto especifico en el tiempo del cual se requiere la data
709 ext : extension de los files
710
711 Return:
712 year : el anho
713 doy : el numero de dia del anho
714 set : el set del archivo
715 filename : el ultimo file de una determinada carpeta
716 directory : eL directorio donde esta el file encontrado
717 """
718
719 print "Searching files ..."
720
721 dirList = []
722 directory = None
723
724 if startDateTime == None:
725 for thisPath in os.listdir(path):
726 if os.path.isdir( os.path.join(path,thisPath) ):
727 dirList.append( thisPath )
728
729 dirList = sorted( dirList, key=str.lower ) #para que quede ordenado al margen de si el nombre esta en mayusculas o minusculas, utilizo la funcion sorted
730 if len(dirList) > 0 :
731 directory = dirList[-1]
732 else:
733 year = startDateTime.timetuple().tm_year
734 doy = startDateTime.timetuple().tm_yday
735
736 doyPath = "D%04d%03d" % (year,doy) #caso del nombre en mayusculas
737 if os.path.isdir( os.path.join(path,doyPath) ):
738 directory = doyPath
739
740 doyPath = doyPath.lower() #caso del nombre en minusculas
741 if os.path.isdir( os.path.join(path,doyPath) ):
742 directory = doyPath
743
744 if directory == None:
745 return 0, 0, 0, None, None
746
747 filename = getlastFileFromPath( os.listdir( os.path.join(path,directory) ), ext )
748
749 if filename == None:
750 return 0, 0, 0, None, None
751
752 year = int( directory[-7:-3] )
753 doy = int( directory[-3:] )
754 ln = len( ext )
755 set = int( filename[-ln-3:-ln] )
756
757 return year, doy, set, filename, directory
758
759
760 def __searchFilesOffLine(self, path, startDateTime, endDateTime, set=None, expLabel = "", ext = ".r"):
761 """
762 Realiza una busqueda de los archivos que coincidan con los parametros
400 especificados y se encuentren ubicados en el path indicado. Para realizar una busqueda
763 especificados y se encuentren ubicados en el path indicado. Para realizar una busqueda
401 correcta la estructura de directorios debe ser la siguiente:
764 correcta la estructura de directorios debe ser la siguiente:
402
765
@@ -480,6 +843,56 class VoltageReader(DataReader):
480 self.filenameList = filenameList
843 self.filenameList = filenameList
481
844
482 return pathList, filenameList
845 return pathList, filenameList
846
847
848 def __initFilesOnline( self, path, dirfilename, filename ):
849 """
850 Verifica que el primer file tenga una data valida, para ello leo el 1er bloque
851 del file, si no es un file valido espera una cierta cantidad de tiempo a que
852 lo sea, si transcurrido el tiempo no logra validar el file entonces el metodo
853 devuelve 0 caso contrario devuelve 1
854
855 Affected:
856 m_BasicHeader
857
858 Return:
859 0 : file no valido para ser leido
860 1 : file valido para ser leido
861 """
862 m_BasicHeader = BasicHeader()
863
864 file = os.path.join( path, dirfilename, filename )
865
866 nTries = 0
867 while(True):
868
869 nTries += 1
870 if nTries > self.__nTries:
871 break
872
873 try:
874 fp = open( file,'rb' ) #lectura binaria
875 except:
876 raise IOError, "The file %s can't be opened" %(file)
877
878 try:
879 m_BasicHeader.read(fp)
880 except:
881 print "The file %s is empty" % filename
882
883 fp.close()
884
885 if m_BasicHeader.size > 24:
886 break
887
888 print 'waiting for new block: try %02d' % ( nTries )
889 time.sleep( self.__delay)
890
891 if m_BasicHeader.size <= 24:
892 return 0
893
894 return 1
895
483
896
484 def setup(self, path, startDateTime, endDateTime=None, set=None, expLabel = "", ext = ".r", online = 0):
897 def setup(self, path, startDateTime, endDateTime=None, set=None, expLabel = "", ext = ".r", online = 0):
485 """
898 """
@@ -507,34 +920,77 class VoltageReader(DataReader):
507
920
508 ext : Extension de los archivos a leer. Por defecto .r
921 ext : Extension de los archivos a leer. Por defecto .r
509
922
510 online :
923 online : Si es == a 0 entonces busca files que cumplan con las condiciones dadas
511
924
512 Return:
925 Return:
926 0 : Si no encuentra files que cumplan con las condiciones dadas
927 1 : Si encuentra files que cumplan con las condiciones dadas
513
928
514 Affected:
929 Affected:
515
930 self.startUTCSeconds
516 Excepciones:
931 self.endUTCSeconds
517
932 self.startYear
518 Example:
933 self.endYear
519
934 self.startDoy
935 self.endDoy
936 self.__pathList
937 self.filenameList
938 self.online
520 """
939 """
521
940 if online:
522 if online == 0:
941 nTries = 0
523 pathList, filenameList = self.__searchFiles(path, startDateTime, endDateTime, set, expLabel, ext)
942 while( nTries < self.__nTries ):
524
943 nTries += 1
525 self.__idFile = -1
944 subfolder = "D%04d%03d" % ( startDateTime.timetuple().tm_year, startDateTime.timetuple().tm_yday )
526
945 year, doy, set, filename, dirfilename = self.__searchFilesOnLine( path, startDateTime, ext )
527 if not(self.__setNextFile()):
946 if filename == None:
528 print "No files in range: %s - %s" %(startDateTime.ctime(), endDateTime.ctime())
947 file = os.path.join( path, subfolder )
948 print "Searching first file in \"%s\", try %03d ..." % ( file, nTries )
949 time.sleep( self.__delay )
950 else:
951 break
952
953 if filename == None:
954 print "No files On Line"
955 return 0
956
957 if self.__initFilesOnline( path, dirfilename, filename ) == 0:
958 print "The file %s hasn't enough data"
959 return 0
960
961 self.__year = year
962 self.__doy = doy
963 self.__set = set - 1
964 self.__path = path
965
966 else:
967 pathList, filenameList = self.__searchFilesOffLine( path, startDateTime, endDateTime, set, expLabel, ext )
968 self.__idFile = -1
969 self.__pathList = pathList
970 self.filenameList = filenameList
971
972 self.online = online
973 self.__ext = ext
974
975 if not( self.__setNextFile() ):
976 if (startDateTime != None) and (endDateTime != None):
977 print "No files in range: %s - %s" %(startDateTime.ctime(), endDateTime.ctime())
978 elif startDateTime != None:
979 print "No files in : %s" % startDateTime.ctime()
980 else:
981 print "No files"
529 return 0
982 return 0
530
983
531 self.startUTCSeconds = time.mktime(startDateTime.timetuple())
984 if startDateTime != None:
532 self.endUTCSeconds = time.mktime(endDateTime.timetuple())
985 self.startUTCSeconds = time.mktime(startDateTime.timetuple())
986 self.startYear = startDateTime.timetuple().tm_year
987 self.startDoy = startDateTime.timetuple().tm_yday
533
988
534 self.startYear = startDateTime.timetuple().tm_year
989 if endDateTime != None:
535 self.endYear = endDateTime.timetuple().tm_year
990 self.endUTCSeconds = time.mktime(endDateTime.timetuple())
536 self.startDoy = startDateTime.timetuple().tm_yday
991 self.endYear = endDateTime.timetuple().tm_year
537 self.endDoy = endDateTime.timetuple().tm_yday
992 self.endDoy = endDateTime.timetuple().tm_yday
993 #call fillHeaderValues() - to Data Object
538
994
539 self.m_Voltage.m_BasicHeader = self.m_BasicHeader.copy()
995 self.m_Voltage.m_BasicHeader = self.m_BasicHeader.copy()
540 self.m_Voltage.m_ProcessingHeader = self.m_ProcessingHeader.copy()
996 self.m_Voltage.m_ProcessingHeader = self.m_ProcessingHeader.copy()
@@ -542,19 +998,19 class VoltageReader(DataReader):
542 self.m_Voltage.m_SystemHeader = self.m_SystemHeader.copy()
998 self.m_Voltage.m_SystemHeader = self.m_SystemHeader.copy()
543 self.m_Voltage.dataType = self.__dataType
999 self.m_Voltage.dataType = self.__dataType
544
1000
545 self.__pathList = pathList
546 self.filenameList = filenameList
547 self.online = online
548
549 return 1
1001 return 1
1002
550
1003
551 def readNextBlock(self):
1004 def readNextBlock( self ):
552 """
1005 """
553 readNextBlock establece un nuevo bloque de datos a leer y los lee, si es que no existiese
1006 Establece un nuevo bloque de datos a leer y los lee, si es que no existiese
554 mas bloques disponibles en el archivo actual salta al siguiente.
1007 mas bloques disponibles en el archivo actual salta al siguiente.
555
1008
1009 Affected:
1010 self.__lastUTTime
1011
1012 Return: None
556 """
1013 """
557
558 if not(self.__setNewBlock()):
1014 if not(self.__setNewBlock()):
559 return 0
1015 return 0
560
1016
@@ -563,8 +1019,9 class VoltageReader(DataReader):
563 self.__lastUTTime = self.m_BasicHeader.utc
1019 self.__lastUTTime = self.m_BasicHeader.utc
564
1020
565 return 1
1021 return 1
1022
566
1023
567 def getData(self):
1024 def getData( self ):
568 """
1025 """
569 getData obtiene una unidad de datos del buffer de lectura y la copia a la clase "Voltage"
1026 getData obtiene una unidad de datos del buffer de lectura y la copia a la clase "Voltage"
570 con todos los parametros asociados a este (metadata). cuando no hay datos en el buffer de
1027 con todos los parametros asociados a este (metadata). cuando no hay datos en el buffer de
@@ -572,9 +1029,6 class VoltageReader(DataReader):
572
1029
573 Ademas incrementa el contador del buffer en 1.
1030 Ademas incrementa el contador del buffer en 1.
574
1031
575 Inputs:
576 None
577
578 Return:
1032 Return:
579 data : retorna un perfil de voltages (alturas * canales) copiados desde el
1033 data : retorna un perfil de voltages (alturas * canales) copiados desde el
580 buffer. Si no hay mas archivos a leer retorna None.
1034 buffer. Si no hay mas archivos a leer retorna None.
@@ -584,20 +1038,24 class VoltageReader(DataReader):
584 self.__datablockIndex
1038 self.__datablockIndex
585 self.idProfile
1039 self.idProfile
586
1040
587 Excepciones:
1041 Affected:
588
1042 self.m_Voltage
1043 self.__datablockIndex
1044 self.flagResetProcessing
1045 self.flagIsNewBlock
1046 self.idProfile
589 """
1047 """
590 self.flagResetProcessing = 0
1048 self.flagResetProcessing = 0
591 self.flagIsNewBlock = 0
1049 self.flagIsNewBlock = 0
592
1050
593 if self.__hasNotDataInBuffer():
1051 if self.__hasNotDataInBuffer():
1052
594 self.readNextBlock()
1053 self.readNextBlock()
595
1054
596 self.m_Voltage.m_BasicHeader = self.m_BasicHeader.copy()
1055 self.m_Voltage.m_BasicHeader = self.m_BasicHeader.copy()
597 self.m_Voltage.m_ProcessingHeader = self.m_ProcessingHeader.copy()
1056 self.m_Voltage.m_ProcessingHeader = self.m_ProcessingHeader.copy()
598 self.m_Voltage.m_RadarControllerHeader = self.m_RadarControllerHeader.copy()
1057 self.m_Voltage.m_RadarControllerHeader = self.m_RadarControllerHeader.copy()
599 self.m_Voltage.m_SystemHeader = self.m_SystemHeader.copy()
1058 self.m_Voltage.m_SystemHeader = self.m_SystemHeader.copy()
600
601 self.m_Voltage.heights = self.__heights
1059 self.m_Voltage.heights = self.__heights
602 self.m_Voltage.dataType = self.__dataType
1060 self.m_Voltage.dataType = self.__dataType
603
1061
@@ -607,15 +1065,15 class VoltageReader(DataReader):
607
1065
608 #data es un numpy array de 3 dmensiones (perfiles, alturas y canales)
1066 #data es un numpy array de 3 dmensiones (perfiles, alturas y canales)
609
1067
610 time = self.m_BasicHeader.utc + self.__datablockIndex*self.__ippSeconds
1068 time = self.m_BasicHeader.utc + self.__datablockIndex * self.__ippSeconds
611 self.m_Voltage.m_BasicHeader.utc = time
1069 self.m_Voltage.m_BasicHeader.utc = time
1070
612 self.m_Voltage.flagNoData = False
1071 self.m_Voltage.flagNoData = False
613 self.m_Voltage.flagResetProcessing = self.flagResetProcessing
1072 self.m_Voltage.flagResetProcessing = self.flagResetProcessing
614
1073
615 self.m_Voltage.data = self.datablock[self.__datablockIndex,:,:]
1074 self.m_Voltage.data = self.datablock[self.__datablockIndex,:,:]
616 self.m_Voltage.idProfile = self.idProfile
1075 self.m_Voltage.idProfile = self.idProfile
617
1076
618
619 self.__datablockIndex += 1
1077 self.__datablockIndex += 1
620 self.idProfile += 1
1078 self.idProfile += 1
621
1079
@@ -623,11 +1081,27 class VoltageReader(DataReader):
623
1081
624 return self.m_Voltage.data
1082 return self.m_Voltage.data
625
1083
626 class VoltageWriter(DataWriter):
1084
1085 class VoltageWriter( DataWriter ):
1086 """
1087 Esta clase permite escribir datos de voltajes a archivos procesados (.r). La escritura
1088 de los datos siempre se realiza por bloques.
1089 """
627 __configHeaderFile = 'wrSetHeadet.txt'
1090 __configHeaderFile = 'wrSetHeadet.txt'
628
1091
629 def __init__(self, m_Voltage = None):
1092 def __init__( self, m_Voltage = None ):
630
1093 """
1094 Inicializador de la clase VoltageWriter para la escritura de datos de espectros.
1095
1096 Affected:
1097 self.m_Voltage
1098 self.m_BasicHeader
1099 self.m_SystemHeader
1100 self.m_RadarControllerHeader
1101 self.m_ProcessingHeader
1102
1103 Return: None
1104 """
631 if m_Voltage == None:
1105 if m_Voltage == None:
632 m_Voltage = Voltage()
1106 m_Voltage = Voltage()
633
1107
@@ -670,59 +1144,141 class VoltageWriter(DataWriter):
670 self.m_RadarControllerHeader = RadarControllerHeader()
1144 self.m_RadarControllerHeader = RadarControllerHeader()
671
1145
672 self.m_ProcessingHeader = ProcessingHeader()
1146 self.m_ProcessingHeader = ProcessingHeader()
1147
673
1148
674
1149 def __writeFirstHeader( self ):
675 def __writeFirstHeader(self):
1150 """
1151 Escribe el primer header del file es decir el Basic header y el Long header (SystemHeader, RadarControllerHeader, ProcessingHeader)
1152
1153 Affected:
1154 __dataType
1155
1156 Return:
1157 None
1158 """
676 self.__writeBasicHeader()
1159 self.__writeBasicHeader()
677 self.__wrSystemHeader()
1160 self.__wrSystemHeader()
678 self.__wrRadarControllerHeader()
1161 self.__wrRadarControllerHeader()
679 self.__wrProcessingHeader()
1162 self.__wrProcessingHeader()
680 self.__dataType = self.m_Voltage.dataType
1163 self.__dataType = self.m_Voltage.dataType
1164
681
1165
682 def __writeBasicHeader(self, fp=None):
1166 def __writeBasicHeader( self, fp=None ):
1167 """
1168 Escribe solo el Basic header en el file creado
1169
1170 Return:
1171 None
1172 """
683 if fp == None:
1173 if fp == None:
684 fp = self.__fp
1174 fp = self.__fp
685
1175
686 self.m_BasicHeader.write(fp)
1176 self.m_BasicHeader.write(fp)
1177
687
1178
688 def __wrSystemHeader(self,fp=None):
1179 def __wrSystemHeader( self, fp=None ):
1180 """
1181 Escribe solo el System header en el file creado
1182
1183 Return:
1184 None
1185 """
689 if fp == None:
1186 if fp == None:
690 fp = self.__fp
1187 fp = self.__fp
691
1188
692 self.m_SystemHeader.write(fp)
1189 self.m_SystemHeader.write(fp)
1190
693
1191
694 def __wrRadarControllerHeader(self,fp=None):
1192 def __wrRadarControllerHeader( self, fp=None ):
1193 """
1194 Escribe solo el RadarController header en el file creado
1195
1196 Return:
1197 None
1198 """
695 if fp == None:
1199 if fp == None:
696 fp = self.__fp
1200 fp = self.__fp
697
1201
698 self.m_RadarControllerHeader.write(fp)
1202 self.m_RadarControllerHeader.write(fp)
1203
699
1204
700 def __wrProcessingHeader(self,fp=None):
1205 def __wrProcessingHeader( self, fp=None ):
1206 """
1207 Escribe solo el Processing header en el file creado
1208
1209 Return:
1210 None
1211 """
701 if fp == None:
1212 if fp == None:
702 fp = self.__fp
1213 fp = self.__fp
703
1214
704 self.m_ProcessingHeader.write(fp)
1215 self.m_ProcessingHeader.write(fp)
705
1216
706 def __setNextFile(self):
1217 def __setNextFile( self ):
707
1218 """
708 setFile = self.__setFile
1219 Determina el siguiente file que sera escrito
1220
1221 Affected:
1222 self.filename
1223 self.__subfolder
1224 self.__fp
1225 self.__setFile
1226 self.__flagIsNewFile
1227
1228 Return:
1229 0 : Si el archivo no puede ser escrito
1230 1 : Si el archivo esta listo para ser escrito
1231 """
1232 #setFile = self.__setFile
709 ext = self.__ext
1233 ext = self.__ext
710 path = self.__path
1234 path = self.__path
711
1235
712 setFile += 1
1236 #setFile += 1
713
1237
714 if self.__fp != None:
1238 if self.__fp != None:
715 self.__fp.close()
1239 self.__fp.close()
716
1240
1241 """
717 timeTuple = time.localtime(self.m_Voltage.m_BasicHeader.utc) # utc from m_Voltage
1242 timeTuple = time.localtime(self.m_Voltage.m_BasicHeader.utc) # utc from m_Voltage
718 file = 'D%4.4d%3.3d%3.3d%s' % (timeTuple.tm_year,timeTuple.tm_yday,setFile,ext)
1243 file = 'D%4.4d%3.3d%3.3d%s' % (timeTuple.tm_year,timeTuple.tm_yday,setFile,ext)
719 subfolder = 'D%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday)
1244 subfolder = 'D%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday)
720 tmp = os.path.join(path,subfolder)
1245 tmp = os.path.join(path,subfolder)
721 if not(os.path.exists(tmp)):
1246 if not(os.path.exists(tmp)):
722 os.mkdir(tmp)
1247 os.mkdir(tmp)
723
1248 """
724 filename = os.path.join(path,subfolder,file)
1249 ##################################
725 fp = open(filename,'wb')
1250 if self.m_BasicHeader.size <= 24: return 0 #no existe la suficiente data para ser escrita
1251
1252 timeTuple = time.localtime( self.m_Voltage.m_BasicHeader.utc ) # utc from m_Voltage
1253 subfolder = 'D%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday)
1254
1255 tmp = os.path.join( path, subfolder )
1256 if not( os.path.exists(tmp) ):
1257 os.mkdir(tmp)
1258 self.__setFile = -1 #inicializo mi contador de seteo
1259 else:
1260 filesList = os.listdir( tmp )
1261 if len( filesList ) > 0:
1262 filesList = sorted( filesList, key=str.lower )
1263 filen = filesList[-1]
1264 # el filename debera tener el siguiente formato
1265 # 0 1234 567 89A BCDE (hex)
1266 # D YYYY DDD SSS .ext
1267 if isNumber( filen[8:11] ):
1268 self.__setFile = int( filen[8:11] ) #inicializo mi contador de seteo al seteo del ultimo file
1269 else:
1270 self.__setFile = -1
1271 else:
1272 self.__setFile = -1 #inicializo mi contador de seteo
1273
1274 setFile = self.__setFile
1275 setFile += 1
1276 file = 'D%4.4d%3.3d%3.3d%s' % ( timeTuple.tm_year, timeTuple.tm_yday, setFile, ext )
1277 ##################################
1278
1279 filename = os.path.join( path, subfolder, file )
1280
1281 fp = open( filename,'wb' )
726
1282
727 self.__blocksCounter = 0
1283 self.__blocksCounter = 0
728
1284
@@ -738,9 +1294,16 class VoltageWriter(DataWriter):
738 self.__writeFirstHeader()
1294 self.__writeFirstHeader()
739
1295
740 return 1
1296 return 1
1297
741
1298
742 def __setNewBlock(self):
1299 def __setNewBlock( self ):
1300 """
1301 Si es un nuevo file escribe el First Header caso contrario escribe solo el Basic Header
743
1302
1303 Return:
1304 0 : si no pudo escribir nada
1305 1 : Si escribio el Basic el First Header
1306 """
744 if self.__fp == None:
1307 if self.__fp == None:
745 self.__setNextFile()
1308 self.__setNextFile()
746
1309
@@ -751,21 +1314,32 class VoltageWriter(DataWriter):
751 self.__writeBasicHeader()
1314 self.__writeBasicHeader()
752 return 1
1315 return 1
753
1316
754 if not(self.__setNextFile()):
1317 if not( self.__setNextFile() ):
755 return 0
1318 return 0
756
1319
757 return 1
1320 return 1
758
1321
759 def __writeBlock(self):
1322 def __writeBlock( self ):
760
1323 """
761 data = numpy.zeros(self.__shapeBuffer, self.__dataType)
1324 Escribe el buffer en el file designado
1325
1326 Affected:
1327 self.__datablockIndex
1328 self.__flagIsNewFile
1329 self.flagIsNewBlock
1330 self.nWriteBlocks
1331 self.__blocksCounter
1332
1333 Return: None
1334 """
1335 data = numpy.zeros( self.__shapeBuffer, self.__dataType )
762
1336
763 data['real'] = self.datablock.real
1337 data['real'] = self.datablock.real
764 data['imag'] = self.datablock.imag
1338 data['imag'] = self.datablock.imag
765
1339
766 data = data.reshape((-1))
1340 data = data.reshape( (-1) )
767
1341
768 data.tofile(self.__fp)
1342 data.tofile( self.__fp )
769
1343
770 self.datablock.fill(0)
1344 self.datablock.fill(0)
771
1345
@@ -780,8 +1354,14 class VoltageWriter(DataWriter):
780 self.__blocksCounter += 1
1354 self.__blocksCounter += 1
781
1355
782
1356
783 def writeNextBlock(self):
1357 def writeNextBlock( self ):
784
1358 """
1359 Selecciona el bloque siguiente de datos y los escribe en un file
1360
1361 Return:
1362 0 : Si no hizo pudo escribir el bloque de datos
1363 1 : Si no pudo escribir el bloque de datos
1364 """
785 if not(self.__setNewBlock()):
1365 if not(self.__setNewBlock()):
786 return 0
1366 return 0
787
1367
@@ -789,14 +1369,26 class VoltageWriter(DataWriter):
789
1369
790 return 1
1370 return 1
791
1371
792 def __hasAllDataInBuffer(self):
1372
1373 def __hasAllDataInBuffer( self ):
793 if self.__datablockIndex >= self.m_ProcessingHeader.profilesPerBlock:
1374 if self.__datablockIndex >= self.m_ProcessingHeader.profilesPerBlock:
794 return 1
1375 return 1
795
1376
796 return 0
1377 return 0
1378
797
1379
798 def putData(self):
1380 def putData( self ):
799
1381 """
1382 Setea un bloque de datos y luego los escribe en un file
1383
1384 Affected:
1385 self.flagIsNewBlock
1386 self.__datablockIndex
1387
1388 Return:
1389 0 : Si no hay data o no hay mas files que puedan escribirse
1390 1 : Si se escribio la data de un bloque en un file
1391 """
800 self.flagIsNewBlock = 0
1392 self.flagIsNewBlock = 0
801
1393
802 if self.m_Voltage.flagNoData:
1394 if self.m_Voltage.flagNoData:
@@ -824,14 +1416,29 class VoltageWriter(DataWriter):
824
1416
825 return 1
1417 return 1
826
1418
827 def __getHeader(self):
1419
1420 def __getHeader( self ):
1421 """
1422 Obtiene una copia del First Header
1423
1424 Affected:
1425 self.m_BasicHeader
1426 self.m_SystemHeader
1427 self.m_RadarControllerHeader
1428 self.m_ProcessingHeader
1429 self.__dataType
1430
1431 Return:
1432 None
1433 """
828 self.m_BasicHeader = self.m_Voltage.m_BasicHeader.copy()
1434 self.m_BasicHeader = self.m_Voltage.m_BasicHeader.copy()
829 self.m_SystemHeader = self.m_Voltage.m_SystemHeader.copy()
1435 self.m_SystemHeader = self.m_Voltage.m_SystemHeader.copy()
830 self.m_RadarControllerHeader = self.m_Voltage.m_RadarControllerHeader.copy()
1436 self.m_RadarControllerHeader = self.m_Voltage.m_RadarControllerHeader.copy()
831 self.m_ProcessingHeader = self.m_Voltage.m_ProcessingHeader.copy()
1437 self.m_ProcessingHeader = self.m_Voltage.m_ProcessingHeader.copy()
832 self.__dataType = self.m_Voltage.dataType
1438 self.__dataType = self.m_Voltage.dataType
1439
833
1440
834 def __setHeaderByFile(self):
1441 def __setHeaderByFile( self ):
835
1442
836 format = self.__format
1443 format = self.__format
837 header = ['Basic','System','RadarController','Processing']
1444 header = ['Basic','System','RadarController','Processing']
@@ -910,9 +1517,20 class VoltageWriter(DataWriter):
910 print "file access denied:%s"%fileTable
1517 print "file access denied:%s"%fileTable
911 sys.exit(0)
1518 sys.exit(0)
912
1519
913 def setup(self, path, set=0, format='rawdata'):
1520
914
1521 def setup( self, path, set=0, format='rawdata' ):
915
1522 """
1523 Setea el tipo de formato en la cual sera guardada la data y escribe el First Header
1524
1525 Inputs:
1526 path : el path destino en el cual se escribiran los files a crear
1527 format : formato en el cual sera salvado un file
1528 set : el setebo del file
1529
1530 Return:
1531 0 : Si no realizo un buen seteo
1532 1 : Si realizo un buen seteo
1533 """
916 if format == 'hdf5':
1534 if format == 'hdf5':
917 ext = '.hdf5'
1535 ext = '.hdf5'
918 format = 'hdf5'
1536 format = 'hdf5'
General Comments 0
You need to be logged in to leave comments. Login now