This diff has been collapsed as it changes many lines, (678 lines changed) Show them Hide them | |||
@@ -20,6 +20,106 from IO.DataIO import DataWriter | |||
|
20 | 20 | |
|
21 | 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 | 123 | def isThisFileinRange(filename, startUTSeconds, endUTSeconds): |
|
24 | 124 | """ |
|
25 | 125 | Esta funcion determina si un archivo de datos en formato Jicamarca(.r) se encuentra |
@@ -189,6 +289,17 class VoltageReader(DataReader): | |||
|
189 | 289 | |
|
190 | 290 | self.__datablockIndex = 9999 |
|
191 | 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 | |
|
302 | ||
|
192 | 303 | def __rdSystemHeader(self,fp=None): |
|
193 | 304 | if fp == None: |
|
194 | 305 | fp = self.__fp |
@@ -253,8 +364,140 class VoltageReader(DataReader): | |||
|
253 | 364 | self.__fileSizeByHeader = self.m_ProcessingHeader.dataBlocksPerFile * self.m_ProcessingHeader.blockSize + self.firstHeaderSize + self.basicHeaderSize*(self.m_ProcessingHeader.dataBlocksPerFile - 1) |
|
254 | 365 | self.__ippSeconds = 2*1000*self.m_RadarControllerHeader.ipp/self.__c |
|
255 | 366 | |
|
367 | self.__pts2read = self.m_ProcessingHeader.profilesPerBlock * self.m_ProcessingHeader.numHeights * self.m_SystemHeader.numChannels | |
|
368 | self.__blocksize = self.__pts2read | |
|
369 | ||
|
370 | ||
|
256 | 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 | 502 | def __setNextFileOffline(self): |
|
260 | 503 | |
@@ -295,6 +538,22 class VoltageReader(DataReader): | |||
|
295 | 538 | return 1 |
|
296 | 539 | |
|
297 | 540 | def __setNextFile(self): |
|
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() | |
|
298 | 557 | |
|
299 | 558 | if self.online: |
|
300 | 559 | newFile = self.__setNextFileOnline() |
@@ -308,8 +567,20 class VoltageReader(DataReader): | |||
|
308 | 567 | |
|
309 | 568 | return 1 |
|
310 | 569 | |
|
570 | ||
|
311 | 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 | |
|
312 | 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 | 584 | if self.__fp == None: |
|
314 | 585 | return 0 |
|
315 | 586 | |
@@ -323,6 +594,20 class VoltageReader(DataReader): | |||
|
323 | 594 | if (currentSize >= neededSize): |
|
324 | 595 | self.__rdBasicHeader() |
|
325 | 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 | 612 | #Setting new file |
|
328 | 613 | if not(self.__setNextFile()): |
@@ -368,9 +653,27 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 | |
|
657 | ||
|
658 | fpointer = self.__fp.tell() | |
|
372 | 659 | |
|
373 | junk = numpy.fromfile(self.__fp, self.__dataType, pts2read) | |
|
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 | |
|
374 | 677 | |
|
375 | 678 | junk = junk.reshape((self.m_ProcessingHeader.profilesPerBlock, self.m_ProcessingHeader.numHeights, self.m_SystemHeader.numChannels)) |
|
376 | 679 | |
@@ -394,9 +697,69 class VoltageReader(DataReader): | |||
|
394 | 697 | |
|
395 | 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" ): | |
|
702 | """ | |
|
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 | |
|
398 | 717 |
|
|
399 | __searchFiles realiza una busqueda de los archivos que coincidan con los parametros | |
|
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 | 763 | especificados y se encuentren ubicados en el path indicado. Para realizar una busqueda |
|
401 | 764 | correcta la estructura de directorios debe ser la siguiente: |
|
402 | 765 | |
@@ -481,6 +844,56 class VoltageReader(DataReader): | |||
|
481 | 844 | |
|
482 | 845 | return pathList, filenameList |
|
483 | 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 | ||
|
896 | ||
|
484 | 897 | def setup(self, path, startDateTime, endDateTime=None, set=None, expLabel = "", ext = ".r", online = 0): |
|
485 | 898 | """ |
|
486 | 899 | setup configura los parametros de lectura de la clase VoltageReader. |
@@ -507,34 +920,77 class VoltageReader(DataReader): | |||
|
507 | 920 | |
|
508 | 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 | 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 | 929 | Affected: |
|
930 | self.startUTCSeconds | |
|
931 | self.endUTCSeconds | |
|
932 | self.startYear | |
|
933 | self.endYear | |
|
934 | self.startDoy | |
|
935 | self.endDoy | |
|
936 | self.__pathList | |
|
937 | self.filenameList | |
|
938 | self.online | |
|
939 | """ | |
|
940 | if online: | |
|
941 | nTries = 0 | |
|
942 | while( nTries < self.__nTries ): | |
|
943 | nTries += 1 | |
|
944 | subfolder = "D%04d%03d" % ( startDateTime.timetuple().tm_year, startDateTime.timetuple().tm_yday ) | |
|
945 | year, doy, set, filename, dirfilename = self.__searchFilesOnLine( path, startDateTime, ext ) | |
|
946 | if filename == None: | |
|
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 | |
|
515 | 952 | |
|
516 | Excepciones: | |
|
517 | ||
|
518 |
|
|
|
953 | if filename == None: | |
|
954 | print "No files On Line" | |
|
955 | return 0 | |
|
519 | 956 | |
|
520 | """ | |
|
957 | if self.__initFilesOnline( path, dirfilename, filename ) == 0: | |
|
958 | print "The file %s hasn't enough data" | |
|
959 | return 0 | |
|
521 | 960 | |
|
522 | if online == 0: | |
|
523 | pathList, filenameList = self.__searchFiles(path, startDateTime, endDateTime, set, expLabel, ext) | |
|
961 | self.__year = year | |
|
962 | self.__doy = doy | |
|
963 | self.__set = set - 1 | |
|
964 | self.__path = path | |
|
524 | 965 | |
|
966 | else: | |
|
967 | pathList, filenameList = self.__searchFilesOffLine( path, startDateTime, endDateTime, set, expLabel, ext ) | |
|
525 | 968 | self.__idFile = -1 |
|
969 | self.__pathList = pathList | |
|
970 | self.filenameList = filenameList | |
|
971 | ||
|
972 | self.online = online | |
|
973 | self.__ext = ext | |
|
526 | 974 | |
|
527 | 975 | if not(self.__setNextFile()): |
|
976 | if (startDateTime != None) and (endDateTime != None): | |
|
528 | 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 | 982 | return 0 |
|
530 | 983 | |
|
984 | if startDateTime != None: | |
|
531 | 985 | self.startUTCSeconds = time.mktime(startDateTime.timetuple()) |
|
532 | self.endUTCSeconds = time.mktime(endDateTime.timetuple()) | |
|
533 | ||
|
534 | 986 | self.startYear = startDateTime.timetuple().tm_year |
|
535 | self.endYear = endDateTime.timetuple().tm_year | |
|
536 | 987 | self.startDoy = startDateTime.timetuple().tm_yday |
|
988 | ||
|
989 | if endDateTime != None: | |
|
990 | self.endUTCSeconds = time.mktime(endDateTime.timetuple()) | |
|
991 | self.endYear = endDateTime.timetuple().tm_year | |
|
537 | 992 | self.endDoy = endDateTime.timetuple().tm_yday |
|
993 | #call fillHeaderValues() - to Data Object | |
|
538 | 994 | |
|
539 | 995 | self.m_Voltage.m_BasicHeader = self.m_BasicHeader.copy() |
|
540 | 996 | self.m_Voltage.m_ProcessingHeader = self.m_ProcessingHeader.copy() |
@@ -542,19 +998,19 class VoltageReader(DataReader): | |||
|
542 | 998 | self.m_Voltage.m_SystemHeader = self.m_SystemHeader.copy() |
|
543 | 999 | self.m_Voltage.dataType = self.__dataType |
|
544 | 1000 | |
|
545 | self.__pathList = pathList | |
|
546 | self.filenameList = filenameList | |
|
547 | self.online = online | |
|
548 | ||
|
549 | 1001 | return 1 |
|
550 | 1002 | |
|
1003 | ||
|
551 | 1004 | def readNextBlock(self): |
|
552 | 1005 | """ |
|
553 |
|
|
|
1006 | Establece un nuevo bloque de datos a leer y los lee, si es que no existiese | |
|
554 | 1007 | mas bloques disponibles en el archivo actual salta al siguiente. |
|
555 | 1008 | |
|
556 | """ | |
|
1009 | Affected: | |
|
1010 | self.__lastUTTime | |
|
557 | 1011 | |
|
1012 | Return: None | |
|
1013 | """ | |
|
558 | 1014 | if not(self.__setNewBlock()): |
|
559 | 1015 | return 0 |
|
560 | 1016 | |
@@ -564,6 +1020,7 class VoltageReader(DataReader): | |||
|
564 | 1020 | |
|
565 | 1021 | return 1 |
|
566 | 1022 | |
|
1023 | ||
|
567 | 1024 | def getData(self): |
|
568 | 1025 | """ |
|
569 | 1026 | getData obtiene una unidad de datos del buffer de lectura y la copia a la clase "Voltage" |
@@ -572,9 +1029,6 class VoltageReader(DataReader): | |||
|
572 | 1029 | |
|
573 | 1030 | Ademas incrementa el contador del buffer en 1. |
|
574 | 1031 | |
|
575 | Inputs: | |
|
576 | None | |
|
577 | ||
|
578 | 1032 | Return: |
|
579 | 1033 | data : retorna un perfil de voltages (alturas * canales) copiados desde el |
|
580 | 1034 | buffer. Si no hay mas archivos a leer retorna None. |
@@ -584,20 +1038,24 class VoltageReader(DataReader): | |||
|
584 | 1038 | self.__datablockIndex |
|
585 | 1039 | self.idProfile |
|
586 | 1040 | |
|
587 | Excepciones: | |
|
588 | ||
|
1041 | Affected: | |
|
1042 | self.m_Voltage | |
|
1043 | self.__datablockIndex | |
|
1044 | self.flagResetProcessing | |
|
1045 | self.flagIsNewBlock | |
|
1046 | self.idProfile | |
|
589 | 1047 | """ |
|
590 | 1048 | self.flagResetProcessing = 0 |
|
591 | 1049 | self.flagIsNewBlock = 0 |
|
592 | 1050 | |
|
593 | 1051 | if self.__hasNotDataInBuffer(): |
|
1052 | ||
|
594 | 1053 | self.readNextBlock() |
|
595 | 1054 | |
|
596 | 1055 | self.m_Voltage.m_BasicHeader = self.m_BasicHeader.copy() |
|
597 | 1056 | self.m_Voltage.m_ProcessingHeader = self.m_ProcessingHeader.copy() |
|
598 | 1057 | self.m_Voltage.m_RadarControllerHeader = self.m_RadarControllerHeader.copy() |
|
599 | 1058 | self.m_Voltage.m_SystemHeader = self.m_SystemHeader.copy() |
|
600 | ||
|
601 | 1059 | self.m_Voltage.heights = self.__heights |
|
602 | 1060 | self.m_Voltage.dataType = self.__dataType |
|
603 | 1061 | |
@@ -609,13 +1067,13 class VoltageReader(DataReader): | |||
|
609 | 1067 | |
|
610 | 1068 | time = self.m_BasicHeader.utc + self.__datablockIndex*self.__ippSeconds |
|
611 | 1069 | self.m_Voltage.m_BasicHeader.utc = time |
|
1070 | ||
|
612 | 1071 | self.m_Voltage.flagNoData = False |
|
613 | 1072 | self.m_Voltage.flagResetProcessing = self.flagResetProcessing |
|
614 | 1073 | |
|
615 | 1074 | self.m_Voltage.data = self.datablock[self.__datablockIndex,:,:] |
|
616 | 1075 | self.m_Voltage.idProfile = self.idProfile |
|
617 | 1076 | |
|
618 | ||
|
619 | 1077 | self.__datablockIndex += 1 |
|
620 | 1078 | self.idProfile += 1 |
|
621 | 1079 | |
@@ -623,11 +1081,27 class VoltageReader(DataReader): | |||
|
623 | 1081 | |
|
624 | 1082 | return self.m_Voltage.data |
|
625 | 1083 | |
|
1084 | ||
|
626 | 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 | 1090 | __configHeaderFile = 'wrSetHeadet.txt' |
|
628 | 1091 | |
|
629 | 1092 | def __init__(self, m_Voltage = None): |
|
1093 | """ | |
|
1094 | Inicializador de la clase VoltageWriter para la escritura de datos de espectros. | |
|
630 | 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 | 1105 | if m_Voltage == None: |
|
632 | 1106 | m_Voltage = Voltage() |
|
633 | 1107 | |
@@ -673,55 +1147,137 class VoltageWriter(DataWriter): | |||
|
673 | 1147 | |
|
674 | 1148 | |
|
675 | 1149 | 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 | 1159 | self.__writeBasicHeader() |
|
677 | 1160 | self.__wrSystemHeader() |
|
678 | 1161 | self.__wrRadarControllerHeader() |
|
679 | 1162 | self.__wrProcessingHeader() |
|
680 | 1163 | self.__dataType = self.m_Voltage.dataType |
|
681 | 1164 | |
|
1165 | ||
|
682 | 1166 | def __writeBasicHeader(self, fp=None): |
|
1167 | """ | |
|
1168 | Escribe solo el Basic header en el file creado | |
|
1169 | ||
|
1170 | Return: | |
|
1171 | None | |
|
1172 | """ | |
|
683 | 1173 | if fp == None: |
|
684 | 1174 | fp = self.__fp |
|
685 | 1175 | |
|
686 | 1176 | self.m_BasicHeader.write(fp) |
|
687 | 1177 | |
|
1178 | ||
|
688 | 1179 | def __wrSystemHeader(self,fp=None): |
|
1180 | """ | |
|
1181 | Escribe solo el System header en el file creado | |
|
1182 | ||
|
1183 | Return: | |
|
1184 | None | |
|
1185 | """ | |
|
689 | 1186 | if fp == None: |
|
690 | 1187 | fp = self.__fp |
|
691 | 1188 | |
|
692 | 1189 | self.m_SystemHeader.write(fp) |
|
693 | 1190 | |
|
1191 | ||
|
694 | 1192 | def __wrRadarControllerHeader(self,fp=None): |
|
1193 | """ | |
|
1194 | Escribe solo el RadarController header en el file creado | |
|
1195 | ||
|
1196 | Return: | |
|
1197 | None | |
|
1198 | """ | |
|
695 | 1199 | if fp == None: |
|
696 | 1200 | fp = self.__fp |
|
697 | 1201 | |
|
698 | 1202 | self.m_RadarControllerHeader.write(fp) |
|
699 | 1203 | |
|
1204 | ||
|
700 | 1205 | def __wrProcessingHeader(self,fp=None): |
|
1206 | """ | |
|
1207 | Escribe solo el Processing header en el file creado | |
|
1208 | ||
|
1209 | Return: | |
|
1210 | None | |
|
1211 | """ | |
|
701 | 1212 | if fp == None: |
|
702 | 1213 | fp = self.__fp |
|
703 | 1214 | |
|
704 | 1215 | self.m_ProcessingHeader.write(fp) |
|
705 | 1216 | |
|
706 | 1217 | def __setNextFile(self): |
|
1218 | """ | |
|
1219 | Determina el siguiente file que sera escrito | |
|
707 | 1220 | |
|
708 | setFile = self.__setFile | |
|
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 | 1233 | ext = self.__ext |
|
710 | 1234 | path = self.__path |
|
711 | 1235 | |
|
712 | setFile += 1 | |
|
1236 | #setFile += 1 | |
|
713 | 1237 | |
|
714 | 1238 | if self.__fp != None: |
|
715 | 1239 | self.__fp.close() |
|
716 | 1240 |
|
|
1241 | """ | |
|
717 | 1242 | timeTuple = time.localtime(self.m_Voltage.m_BasicHeader.utc) # utc from m_Voltage |
|
718 | 1243 | file = 'D%4.4d%3.3d%3.3d%s' % (timeTuple.tm_year,timeTuple.tm_yday,setFile,ext) |
|
719 | 1244 | subfolder = 'D%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday) |
|
720 | 1245 | tmp = os.path.join(path,subfolder) |
|
721 | 1246 | if not(os.path.exists(tmp)): |
|
722 | 1247 | os.mkdir(tmp) |
|
1248 | """ | |
|
1249 | ################################## | |
|
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 | ################################## | |
|
723 | 1278 | |
|
724 | 1279 | filename = os.path.join(path,subfolder,file) |
|
1280 | ||
|
725 | 1281 | fp = open(filename,'wb') |
|
726 | 1282 | |
|
727 | 1283 | self.__blocksCounter = 0 |
@@ -739,8 +1295,15 class VoltageWriter(DataWriter): | |||
|
739 | 1295 | |
|
740 | 1296 | return 1 |
|
741 | 1297 | |
|
1298 | ||
|
742 | 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 | 1307 | if self.__fp == None: |
|
745 | 1308 | self.__setNextFile() |
|
746 | 1309 | |
@@ -757,7 +1320,18 class VoltageWriter(DataWriter): | |||
|
757 | 1320 | return 1 |
|
758 | 1321 | |
|
759 | 1322 | def __writeBlock(self): |
|
1323 | """ | |
|
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 | |
|
760 | 1332 | |
|
1333 | Return: None | |
|
1334 | """ | |
|
761 | 1335 | data = numpy.zeros(self.__shapeBuffer, self.__dataType) |
|
762 | 1336 | |
|
763 | 1337 | data['real'] = self.datablock.real |
@@ -781,7 +1355,13 class VoltageWriter(DataWriter): | |||
|
781 | 1355 | |
|
782 | 1356 | |
|
783 | 1357 | def writeNextBlock(self): |
|
1358 | """ | |
|
1359 | Selecciona el bloque siguiente de datos y los escribe en un file | |
|
784 | 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 | 1365 | if not(self.__setNewBlock()): |
|
786 | 1366 | return 0 |
|
787 | 1367 | |
@@ -789,14 +1369,26 class VoltageWriter(DataWriter): | |||
|
789 | 1369 | |
|
790 | 1370 | return 1 |
|
791 | 1371 | |
|
1372 | ||
|
792 | 1373 | def __hasAllDataInBuffer(self): |
|
793 | 1374 | if self.__datablockIndex >= self.m_ProcessingHeader.profilesPerBlock: |
|
794 | 1375 | return 1 |
|
795 | 1376 | |
|
796 | 1377 | return 0 |
|
797 | 1378 | |
|
1379 | ||
|
798 | 1380 | def putData(self): |
|
1381 | """ | |
|
1382 | Setea un bloque de datos y luego los escribe en un file | |
|
799 | 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 | 1392 | self.flagIsNewBlock = 0 |
|
801 | 1393 | |
|
802 | 1394 | if self.m_Voltage.flagNoData: |
@@ -824,13 +1416,28 class VoltageWriter(DataWriter): | |||
|
824 | 1416 | |
|
825 | 1417 | return 1 |
|
826 | 1418 | |
|
1419 | ||
|
827 | 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 | 1434 | self.m_BasicHeader = self.m_Voltage.m_BasicHeader.copy() |
|
829 | 1435 | self.m_SystemHeader = self.m_Voltage.m_SystemHeader.copy() |
|
830 | 1436 | self.m_RadarControllerHeader = self.m_Voltage.m_RadarControllerHeader.copy() |
|
831 | 1437 | self.m_ProcessingHeader = self.m_Voltage.m_ProcessingHeader.copy() |
|
832 | 1438 | self.__dataType = self.m_Voltage.dataType |
|
833 | 1439 | |
|
1440 | ||
|
834 | 1441 | def __setHeaderByFile(self): |
|
835 | 1442 | |
|
836 | 1443 | format = self.__format |
@@ -910,9 +1517,20 class VoltageWriter(DataWriter): | |||
|
910 | 1517 | print "file access denied:%s"%fileTable |
|
911 | 1518 | sys.exit(0) |
|
912 | 1519 | |
|
1520 | ||
|
913 | 1521 | def setup(self, path, set=0, format='rawdata'): |
|
1522 | """ | |
|
1523 | Setea el tipo de formato en la cual sera guardada la data y escribe el First Header | |
|
914 | 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 | |
|
915 | 1529 | |
|
1530 | Return: | |
|
1531 | 0 : Si no realizo un buen seteo | |
|
1532 | 1 : Si realizo un buen seteo | |
|
1533 | """ | |
|
916 | 1534 | if format == 'hdf5': |
|
917 | 1535 | ext = '.hdf5' |
|
918 | 1536 | format = 'hdf5' |
General Comments 0
You need to be logged in to leave comments.
Login now