jroIO_base.py
1813 lines
| 53.3 KiB
| text/x-python
|
PythonLexer
|
r487 | ''' | ||
|
r568 | Created on Jul 2, 2014 | ||
|
r487 | |||
|
r568 | @author: roj-idl71 | ||
|
r487 | ''' | ||
import os | ||||
import sys | ||||
import glob | ||||
import time | ||||
import numpy | ||||
import fnmatch | ||||
|
r944 | import inspect | ||
|
r487 | import time, datetime | ||
import traceback | ||||
|
r963 | import zmq | ||
|
r487 | |||
|
r568 | try: | ||
from gevent import sleep | ||||
except: | ||||
from time import sleep | ||||
r892 | ||||
|
r568 | from schainpy.model.data.jroheaderIO import PROCFLAG, BasicHeader, SystemHeader, RadarControllerHeader, ProcessingHeader | ||
|
r616 | from schainpy.model.data.jroheaderIO import get_dtype_index, get_numpy_dtype, get_procflag_dtype, get_dtype_width | ||
|
r487 | |||
|
r568 | LOCALTIME = True | ||
|
r487 | |||
|
r568 | def isNumber(cad): | ||
|
r487 | """ | ||
Chequea si el conjunto de caracteres que componen un string puede ser convertidos a un numero. | ||||
r892 | Excepciones: | |||
|
r487 | Si un determinado string no puede ser convertido a numero | ||
Input: | ||||
str, string al cual se le analiza para determinar si convertible a un numero o no | ||||
r892 | ||||
|
r487 | Return: | ||
True : si el string es uno numerico | ||||
False : no es un string numerico | ||||
""" | ||||
try: | ||||
|
r568 | float( cad ) | ||
|
r487 | return True | ||
except: | ||||
return False | ||||
|
r640 | def isFileInEpoch(filename, startUTSeconds, endUTSeconds): | ||
|
r487 | """ | ||
Esta funcion determina si un archivo de datos se encuentra o no dentro del rango de fecha especificado. | ||||
r892 | ||||
|
r487 | Inputs: | ||
filename : nombre completo del archivo de datos en formato Jicamarca (.r) | ||||
r892 | ||||
|
r487 | startUTSeconds : fecha inicial del rango seleccionado. La fecha esta dada en | ||
segundos contados desde 01/01/1970. | ||||
endUTSeconds : fecha final del rango seleccionado. La fecha esta dada en | ||||
segundos contados desde 01/01/1970. | ||||
r892 | ||||
|
r487 | Return: | ||
Boolean : Retorna True si el archivo de datos contiene datos en el rango de | ||||
fecha especificado, de lo contrario retorna False. | ||||
r892 | ||||
|
r487 | Excepciones: | ||
Si el archivo no existe o no puede ser abierto | ||||
Si la cabecera no puede ser leida. | ||||
r892 | ||||
|
r487 | """ | ||
basicHeaderObj = BasicHeader(LOCALTIME) | ||||
r892 | ||||
|
r487 | try: | ||
fp = open(filename,'rb') | ||||
except IOError: | ||||
|
r684 | print "The file %s can't be opened" %(filename) | ||
return 0 | ||||
r892 | ||||
|
r487 | sts = basicHeaderObj.read(fp) | ||
fp.close() | ||||
r892 | ||||
|
r487 | if not(sts): | ||
print "Skipping the file %s because it has not a valid header" %(filename) | ||||
return 0 | ||||
r892 | ||||
|
r487 | if not ((startUTSeconds <= basicHeaderObj.utc) and (endUTSeconds > basicHeaderObj.utc)): | ||
return 0 | ||||
r892 | ||||
|
r487 | return 1 | ||
|
r759 | def isTimeInRange(thisTime, startTime, endTime): | ||
r892 | ||||
|
r759 | if endTime >= startTime: | ||
if (thisTime < startTime) or (thisTime > endTime): | ||||
return 0 | ||||
r892 | ||||
|
r759 | return 1 | ||
else: | ||||
if (thisTime < startTime) and (thisTime > endTime): | ||||
return 0 | ||||
r892 | ||||
|
r759 | return 1 | ||
r892 | ||||
|
r652 | def isFileInTimeRange(filename, startDate, endDate, startTime, endTime): | ||
|
r487 | """ | ||
Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado. | ||||
r892 | ||||
|
r487 | Inputs: | ||
filename : nombre completo del archivo de datos en formato Jicamarca (.r) | ||||
r892 | ||||
|
r652 | startDate : fecha inicial del rango seleccionado en formato datetime.date | ||
r892 | ||||
|
r652 | endDate : fecha final del rango seleccionado en formato datetime.date | ||
r892 | ||||
|
r487 | startTime : tiempo inicial del rango seleccionado en formato datetime.time | ||
r892 | ||||
|
r487 | endTime : tiempo final del rango seleccionado en formato datetime.time | ||
r892 | ||||
|
r487 | Return: | ||
Boolean : Retorna True si el archivo de datos contiene datos en el rango de | ||||
fecha especificado, de lo contrario retorna False. | ||||
r892 | ||||
|
r487 | Excepciones: | ||
Si el archivo no existe o no puede ser abierto | ||||
Si la cabecera no puede ser leida. | ||||
r892 | ||||
|
r487 | """ | ||
r892 | ||||
|
r487 | try: | ||
fp = open(filename,'rb') | ||||
except IOError: | ||||
|
r684 | print "The file %s can't be opened" %(filename) | ||
return None | ||||
r892 | ||||
|
r759 | firstBasicHeaderObj = BasicHeader(LOCALTIME) | ||
systemHeaderObj = SystemHeader() | ||||
radarControllerHeaderObj = RadarControllerHeader() | ||||
processingHeaderObj = ProcessingHeader() | ||||
r892 | ||||
|
r759 | lastBasicHeaderObj = BasicHeader(LOCALTIME) | ||
r892 | ||||
|
r759 | sts = firstBasicHeaderObj.read(fp) | ||
r892 | ||||
|
r780 | if not(sts): | ||
print "[Reading] Skipping the file %s because it has not a valid header" %(filename) | ||||
return None | ||||
r892 | ||||
|
r803 | if not systemHeaderObj.read(fp): | ||
return None | ||||
r892 | ||||
|
r803 | if not radarControllerHeaderObj.read(fp): | ||
return None | ||||
r892 | ||||
|
r803 | if not processingHeaderObj.read(fp): | ||
return None | ||||
r892 | ||||
|
r780 | filesize = os.path.getsize(filename) | ||
r892 | ||||
|
r759 | offset = processingHeaderObj.blockSize + 24 #header size | ||
r892 | ||||
|
r780 | if filesize <= offset: | ||
print "[Reading] %s: This file has not enough data" %filename | ||||
return None | ||||
r892 | ||||
|
r759 | fp.seek(-offset, 2) | ||
r892 | ||||
|
r759 | sts = lastBasicHeaderObj.read(fp) | ||
r892 | ||||
|
r759 | fp.close() | ||
r892 | ||||
|
r780 | thisDatetime = lastBasicHeaderObj.datatime | ||
thisTime_last_block = thisDatetime.time() | ||||
r892 | ||||
|
r759 | thisDatetime = firstBasicHeaderObj.datatime | ||
thisDate = thisDatetime.date() | ||||
thisTime_first_block = thisDatetime.time() | ||||
r892 | ||||
|
r648 | #General case | ||
# o>>>>>>>>>>>>>><<<<<<<<<<<<<<o | ||||
#-----------o----------------------------o----------- | ||||
# startTime endTime | ||||
r892 | ||||
|
r648 | if endTime >= startTime: | ||
|
r759 | if (thisTime_last_block < startTime) or (thisTime_first_block > endTime): | ||
|
r648 | return None | ||
r892 | ||||
|
r648 | return thisDatetime | ||
r892 | ||||
|
r648 | #If endTime < startTime then endTime belongs to the next day | ||
r892 | ||||
|
r648 | #<<<<<<<<<<<o o>>>>>>>>>>> | ||
#-----------o----------------------------o----------- | ||||
# endTime startTime | ||||
r892 | ||||
|
r759 | if (thisDate == startDate) and (thisTime_last_block < startTime): | ||
|
r652 | return None | ||
r892 | ||||
|
r759 | if (thisDate == endDate) and (thisTime_first_block > endTime): | ||
|
r652 | return None | ||
r892 | ||||
|
r759 | if (thisTime_last_block < startTime) and (thisTime_first_block > endTime): | ||
|
r487 | return None | ||
r892 | ||||
|
r487 | return thisDatetime | ||
|
r640 | def isFolderInDateRange(folder, startDate=None, endDate=None): | ||
""" | ||||
Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado. | ||||
r892 | ||||
|
r640 | Inputs: | ||
folder : nombre completo del directorio. | ||||
Su formato deberia ser "/path_root/?YYYYDDD" | ||||
r892 | ||||
|
r640 | siendo: | ||
YYYY : Anio (ejemplo 2015) | ||||
DDD : Dia del anio (ejemplo 305) | ||||
r892 | ||||
|
r640 | startDate : fecha inicial del rango seleccionado en formato datetime.date | ||
r892 | ||||
|
r640 | endDate : fecha final del rango seleccionado en formato datetime.date | ||
r892 | ||||
|
r640 | Return: | ||
Boolean : Retorna True si el archivo de datos contiene datos en el rango de | ||||
fecha especificado, de lo contrario retorna False. | ||||
Excepciones: | ||||
Si el directorio no tiene el formato adecuado | ||||
""" | ||||
r892 | ||||
|
r640 | basename = os.path.basename(folder) | ||
r892 | ||||
|
r640 | if not isRadarFolder(basename): | ||
|
r684 | print "The folder %s has not the rigth format" %folder | ||
return 0 | ||||
r892 | ||||
|
r640 | if startDate and endDate: | ||
thisDate = getDateFromRadarFolder(basename) | ||||
r892 | ||||
|
r640 | if thisDate < startDate: | ||
return 0 | ||||
r892 | ||||
|
r640 | if thisDate > endDate: | ||
return 0 | ||||
r892 | ||||
|
r640 | return 1 | ||
def isFileInDateRange(filename, startDate=None, endDate=None): | ||||
""" | ||||
Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado. | ||||
r892 | ||||
|
r640 | Inputs: | ||
filename : nombre completo del archivo de datos en formato Jicamarca (.r) | ||||
r892 | ||||
|
r640 | Su formato deberia ser "?YYYYDDDsss" | ||
r892 | ||||
|
r640 | siendo: | ||
YYYY : Anio (ejemplo 2015) | ||||
DDD : Dia del anio (ejemplo 305) | ||||
sss : set | ||||
r892 | ||||
|
r640 | startDate : fecha inicial del rango seleccionado en formato datetime.date | ||
r892 | ||||
|
r640 | endDate : fecha final del rango seleccionado en formato datetime.date | ||
r892 | ||||
|
r640 | Return: | ||
Boolean : Retorna True si el archivo de datos contiene datos en el rango de | ||||
fecha especificado, de lo contrario retorna False. | ||||
Excepciones: | ||||
Si el archivo no tiene el formato adecuado | ||||
""" | ||||
r892 | ||||
|
r640 | basename = os.path.basename(filename) | ||
r892 | ||||
|
r640 | if not isRadarFile(basename): | ||
|
r684 | print "The filename %s has not the rigth format" %filename | ||
return 0 | ||||
r892 | ||||
|
r640 | if startDate and endDate: | ||
thisDate = getDateFromRadarFile(basename) | ||||
r892 | ||||
|
r640 | if thisDate < startDate: | ||
return 0 | ||||
r892 | ||||
|
r640 | if thisDate > endDate: | ||
return 0 | ||||
r892 | ||||
|
r640 | return 1 | ||
|
r487 | def getFileFromSet(path, ext, set): | ||
validFilelist = [] | ||||
fileList = os.listdir(path) | ||||
r892 | ||||
|
r487 | # 0 1234 567 89A BCDE | ||
# H YYYY DDD SSS .ext | ||||
r892 | ||||
|
r487 | for thisFile in fileList: | ||
try: | ||||
year = int(thisFile[1:5]) | ||||
doy = int(thisFile[5:8]) | ||||
except: | ||||
continue | ||||
r892 | ||||
|
r487 | if (os.path.splitext(thisFile)[-1].lower() != ext.lower()): | ||
continue | ||||
r892 | ||||
|
r487 | validFilelist.append(thisFile) | ||
myfile = fnmatch.filter(validFilelist,'*%4.4d%3.3d%3.3d*'%(year,doy,set)) | ||||
r892 | ||||
|
r487 | if len(myfile)!= 0: | ||
return myfile[0] | ||||
else: | ||||
filename = '*%4.4d%3.3d%3.3d%s'%(year,doy,set,ext.lower()) | ||||
print 'the filename %s does not exist'%filename | ||||
print '...going to the last file: ' | ||||
r892 | ||||
|
r487 | if validFilelist: | ||
validFilelist = sorted( validFilelist, key=str.lower ) | ||||
return validFilelist[-1] | ||||
return None | ||||
def getlastFileFromPath(path, ext): | ||||
""" | ||||
Depura el fileList dejando solo los que cumplan el formato de "PYYYYDDDSSS.ext" | ||||
r892 | al final de la depuracion devuelve el ultimo file de la lista que quedo. | |||
Input: | ||||
|
r487 | fileList : lista conteniendo todos los files (sin path) que componen una determinada carpeta | ||
r892 | ext : extension de los files contenidos en una carpeta | |||
|
r487 | Return: | ||
El ultimo file de una determinada carpeta, no se considera el path. | ||||
""" | ||||
validFilelist = [] | ||||
fileList = os.listdir(path) | ||||
r892 | ||||
|
r487 | # 0 1234 567 89A BCDE | ||
# H YYYY DDD SSS .ext | ||||
r892 | ||||
|
r487 | for thisFile in fileList: | ||
r892 | ||||
|
r487 | year = thisFile[1:5] | ||
if not isNumber(year): | ||||
continue | ||||
r892 | ||||
|
r487 | doy = thisFile[5:8] | ||
if not isNumber(doy): | ||||
continue | ||||
r892 | ||||
|
r487 | year = int(year) | ||
doy = int(doy) | ||||
r892 | ||||
|
r487 | if (os.path.splitext(thisFile)[-1].lower() != ext.lower()): | ||
continue | ||||
r892 | ||||
|
r487 | validFilelist.append(thisFile) | ||
if validFilelist: | ||||
validFilelist = sorted( validFilelist, key=str.lower ) | ||||
return validFilelist[-1] | ||||
return None | ||||
def checkForRealPath(path, foldercounter, year, doy, set, ext): | ||||
""" | ||||
Por ser Linux Case Sensitive entonces checkForRealPath encuentra el nombre correcto de un path, | ||||
Prueba por varias combinaciones de nombres entre mayusculas y minusculas para determinar | ||||
el path exacto de un determinado file. | ||||
r892 | ||||
|
r487 | Example : | ||
nombre correcto del file es .../.../D2009307/P2009307367.ext | ||||
r892 | ||||
|
r487 | Entonces la funcion prueba con las siguientes combinaciones | ||
.../.../y2009307367.ext | ||||
.../.../Y2009307367.ext | ||||
.../.../x2009307/y2009307367.ext | ||||
.../.../x2009307/Y2009307367.ext | ||||
.../.../X2009307/y2009307367.ext | ||||
.../.../X2009307/Y2009307367.ext | ||||
r892 | siendo para este caso, la ultima combinacion de letras, identica al file buscado | |||
|
r487 | Return: | ||
r892 | Si encuentra la cobinacion adecuada devuelve el path completo y el nombre del file | |||
caso contrario devuelve None como path y el la ultima combinacion de nombre en mayusculas | ||||
para el filename | ||||
|
r487 | """ | ||
fullfilename = None | ||||
find_flag = False | ||||
filename = None | ||||
r892 | ||||
|
r487 | prefixDirList = [None,'d','D'] | ||
if ext.lower() == ".r": #voltage | ||||
prefixFileList = ['d','D'] | ||||
elif ext.lower() == ".pdata": #spectra | ||||
prefixFileList = ['p','P'] | ||||
else: | ||||
return None, filename | ||||
r892 | ||||
#barrido por las combinaciones posibles | ||||
|
r487 | for prefixDir in prefixDirList: | ||
thispath = path | ||||
if prefixDir != None: | ||||
#formo el nombre del directorio xYYYYDDD (x=d o x=D) | ||||
if foldercounter == 0: | ||||
r892 | thispath = os.path.join(path, "%s%04d%03d" % ( prefixDir, year, doy )) | |||
|
r487 | else: | ||
thispath = os.path.join(path, "%s%04d%03d_%02d" % ( prefixDir, year, doy , foldercounter)) | ||||
for prefixFile in prefixFileList: #barrido por las dos combinaciones posibles de "D" | ||||
filename = "%s%04d%03d%03d%s" % ( prefixFile, year, doy, set, ext ) #formo el nombre del file xYYYYDDDSSS.ext | ||||
fullfilename = os.path.join( thispath, filename ) #formo el path completo | ||||
r892 | ||||
|
r487 | if os.path.exists( fullfilename ): #verifico que exista | ||
find_flag = True | ||||
break | ||||
if find_flag: | ||||
break | ||||
if not(find_flag): | ||||
return None, filename | ||||
return fullfilename, filename | ||||
|
r589 | def isRadarFolder(folder): | ||
|
r487 | try: | ||
year = int(folder[1:5]) | ||||
doy = int(folder[5:8]) | ||||
except: | ||||
return 0 | ||||
r892 | ||||
|
r487 | return 1 | ||
|
r589 | def isRadarFile(file): | ||
try: | ||||
year = int(file[1:5]) | ||||
doy = int(file[5:8]) | ||||
set = int(file[8:11]) | ||||
except: | ||||
return 0 | ||||
r892 | ||||
|
r589 | return 1 | ||
def getDateFromRadarFile(file): | ||||
|
r640 | try: | ||
year = int(file[1:5]) | ||||
doy = int(file[5:8]) | ||||
set = int(file[8:11]) | ||||
except: | ||||
return None | ||||
thisDate = datetime.date(year, 1, 1) + datetime.timedelta(doy-1) | ||||
return thisDate | ||||
def getDateFromRadarFolder(folder): | ||||
try: | ||||
year = int(folder[1:5]) | ||||
doy = int(folder[5:8]) | ||||
except: | ||||
return None | ||||
thisDate = datetime.date(year, 1, 1) + datetime.timedelta(doy-1) | ||||
return thisDate | ||||
r892 | ||||
|
r487 | class JRODataIO: | ||
r892 | ||||
|
r487 | c = 3E8 | ||
r892 | ||||
|
r487 | isConfig = False | ||
r892 | ||||
|
r487 | basicHeaderObj = None | ||
r892 | ||||
|
r487 | systemHeaderObj = None | ||
r892 | ||||
|
r487 | radarControllerHeaderObj = None | ||
r892 | ||||
|
r487 | processingHeaderObj = None | ||
r892 | ||||
|
r487 | dtype = None | ||
r892 | ||||
|
r487 | pathList = [] | ||
r892 | ||||
|
r487 | filenameList = [] | ||
r892 | ||||
|
r487 | filename = None | ||
r892 | ||||
|
r487 | ext = None | ||
r892 | ||||
|
r487 | flagIsNewFile = 1 | ||
r892 | ||||
|
r568 | flagDiscontinuousBlock = 0 | ||
r892 | ||||
|
r487 | flagIsNewBlock = 0 | ||
r892 | ||||
|
r487 | fp = None | ||
r892 | ||||
|
r487 | firstHeaderSize = 0 | ||
r892 | ||||
|
r487 | basicHeaderSize = 24 | ||
r892 | ||||
|
r487 | versionFile = 1103 | ||
r892 | ||||
|
r487 | fileSize = None | ||
r892 | ||||
|
r487 | # ippSeconds = None | ||
r892 | ||||
|
r487 | fileSizeByHeader = None | ||
r892 | ||||
|
r487 | fileIndex = None | ||
r892 | ||||
|
r487 | profileIndex = None | ||
r892 | ||||
|
r487 | blockIndex = None | ||
r892 | ||||
|
r487 | nTotalBlocks = None | ||
r892 | ||||
|
r487 | maxTimeStep = 30 | ||
r892 | ||||
|
r487 | lastUTTime = None | ||
r892 | ||||
|
r487 | datablock = None | ||
r892 | ||||
|
r487 | dataOut = None | ||
r892 | ||||
|
r487 | blocksize = None | ||
r892 | ||||
|
r527 | getByBlock = False | ||
r892 | ||||
|
r487 | def __init__(self): | ||
r892 | ||||
|
r684 | raise NotImplementedError | ||
r892 | ||||
|
r487 | def run(self): | ||
r892 | ||||
|
r684 | raise NotImplementedError | ||
|
r487 | |||
|
r616 | def getDtypeWidth(self): | ||
r892 | ||||
|
r616 | dtype_index = get_dtype_index(self.dtype) | ||
dtype_width = get_dtype_width(dtype_index) | ||||
r892 | ||||
|
r616 | return dtype_width | ||
r892 | ||||
|
r944 | def getAllowedArgs(self): | ||
return inspect.getargspec(self.run).args | ||||
|
r487 | class JRODataReader(JRODataIO): | ||
r892 | ||||
|
r659 | online = 0 | ||
r892 | ||||
|
r659 | realtime = 0 | ||
r892 | ||||
|
r487 | nReadBlocks = 0 | ||
r892 | ||||
|
r487 | delay = 10 #number of seconds waiting a new file | ||
r892 | ||||
|
r487 | nTries = 3 #quantity tries | ||
r892 | ||||
|
r487 | nFiles = 3 #number of files for searching | ||
r892 | ||||
|
r487 | path = None | ||
r892 | ||||
|
r487 | foldercounter = 0 | ||
r892 | ||||
|
r487 | flagNoMoreFiles = 0 | ||
r892 | ||||
|
r487 | datetimeList = [] | ||
r892 | ||||
|
r487 | __isFirstTimeOnline = 1 | ||
r892 | ||||
|
r487 | __printInfo = True | ||
r892 | ||||
|
r487 | profileIndex = None | ||
r892 | ||||
|
r534 | nTxs = 1 | ||
r892 | ||||
|
r534 | txIndex = None | ||
r892 | ||||
|
r833 | #Added-------------------- | ||
r892 | ||||
|
r833 | selBlocksize = None | ||
r892 | ||||
|
r833 | selBlocktime = None | ||
r892 | ||||
|
r487 | def __init__(self): | ||
r892 | ||||
|
r487 | """ | ||
|
r684 | This class is used to find data files | ||
r892 | ||||
|
r684 | Example: | ||
reader = JRODataReader() | ||||
fileList = reader.findDataFiles() | ||||
r892 | ||||
|
r684 | """ | ||
pass | ||||
r892 | ||||
|
r487 | |||
def createObjByDefault(self): | ||||
""" | ||||
""" | ||||
|
r684 | raise NotImplementedError | ||
|
r487 | |||
def getBlockDimension(self): | ||||
r892 | ||||
|
r684 | raise NotImplementedError | ||
|
r487 | |||
def __searchFilesOffLine(self, | ||||
path, | ||||
|
r589 | startDate=None, | ||
endDate=None, | ||||
|
r487 | startTime=datetime.time(0,0,0), | ||
endTime=datetime.time(23,59,59), | ||||
set=None, | ||||
expLabel='', | ||||
ext='.r', | ||||
r892 | queue=None, | |||
cursor=None, | ||||
skip=None, | ||||
|
r487 | walk=True): | ||
r892 | ||||
|
r589 | self.filenameList = [] | ||
self.datetimeList = [] | ||||
r892 | ||||
|
r487 | pathList = [] | ||
r892 | ||||
|
r640 | dateList, pathList = self.findDatafiles(path, startDate, endDate, expLabel, ext, walk, include_path=True) | ||
r892 | ||||
|
r640 | if dateList == []: | ||
|
r1013 | # print "[Reading] Date range selected invalid [%s - %s]: No *%s files in %s)" %(startDate, endDate, ext, path) | ||
|
r487 | return None, None | ||
r892 | ||||
|
r640 | if len(dateList) > 1: | ||
|
r759 | print "[Reading] Data found for date range [%s - %s]: total days = %d" %(startDate, endDate, len(dateList)) | ||
|
r640 | else: | ||
|
r759 | print "[Reading] Data found for date range [%s - %s]: date = %s" %(startDate, endDate, dateList[0]) | ||
r892 | ||||
|
r487 | filenameList = [] | ||
datetimeList = [] | ||||
r892 | ||||
|
r640 | for thisPath in pathList: | ||
|
r1013 | # thisPath = pathList[pathDict[file]] | ||
|
r487 | |||
fileList = glob.glob1(thisPath, "*%s" %ext) | ||||
fileList.sort() | ||||
r892 | ||||
skippedFileList = [] | ||||
if cursor is not None and skip is not None: | ||||
# if cursor*skip > len(fileList): | ||||
if skip == 0: | ||||
if queue is not None: | ||||
queue.put(len(fileList)) | ||||
skippedFileList = [] | ||||
else: | ||||
skippedFileList = fileList[cursor*skip: cursor*skip + skip] | ||||
else: | ||||
skippedFileList = fileList | ||||
for file in skippedFileList: | ||||
|
r487 | filename = os.path.join(thisPath,file) | ||
r892 | ||||
|
r640 | if not isFileInDateRange(filename, startDate, endDate): | ||
continue | ||||
r892 | ||||
|
r652 | thisDatetime = isFileInTimeRange(filename, startDate, endDate, startTime, endTime) | ||
r892 | ||||
|
r487 | if not(thisDatetime): | ||
continue | ||||
r892 | ||||
|
r487 | filenameList.append(filename) | ||
datetimeList.append(thisDatetime) | ||||
r892 | ||||
|
r487 | if not(filenameList): | ||
|
r759 | print "[Reading] Time range selected invalid [%s - %s]: No *%s files in %s)" %(startTime, endTime, ext, path) | ||
|
r487 | return None, None | ||
r892 | ||||
|
r648 | print "[Reading] %d file(s) was(were) found in time range: %s - %s" %(len(filenameList), startTime, endTime) | ||
|
r487 | |||
r892 | ||||
|
r487 | for i in range(len(filenameList)): | ||
|
r648 | print "[Reading] %s -> [%s]" %(filenameList[i], datetimeList[i].ctime()) | ||
|
r487 | |||
self.filenameList = filenameList | ||||
self.datetimeList = datetimeList | ||||
r892 | ||||
|
r487 | return pathList, filenameList | ||
def __searchFilesOnLine(self, path, expLabel = "", ext = None, walk=True, set=None): | ||||
r892 | ||||
|
r487 | """ | ||
Busca el ultimo archivo de la ultima carpeta (determinada o no por startDateTime) y | ||||
devuelve el archivo encontrado ademas de otros datos. | ||||
r892 | ||||
Input: | ||||
|
r487 | path : carpeta donde estan contenidos los files que contiene data | ||
r892 | ||||
|
r487 | expLabel : Nombre del subexperimento (subfolder) | ||
r892 | ||||
|
r487 | ext : extension de los files | ||
r892 | ||||
|
r487 | walk : Si es habilitado no realiza busquedas dentro de los ubdirectorios (doypath) | ||
Return: | ||||
directory : eL directorio donde esta el file encontrado | ||||
filename : el ultimo file de una determinada carpeta | ||||
year : el anho | ||||
doy : el numero de dia del anho | ||||
set : el set del archivo | ||||
r892 | ||||
|
r487 | """ | ||
|
r700 | if not os.path.isdir(path): | ||
return None, None, None, None, None, None | ||||
r892 | ||||
|
r700 | dirList = [] | ||
r892 | ||||
|
r487 | if not walk: | ||
fullpath = path | ||||
foldercounter = 0 | ||||
else: | ||||
#Filtra solo los directorios | ||||
for thisPath in os.listdir(path): | ||||
if not os.path.isdir(os.path.join(path,thisPath)): | ||||
continue | ||||
|
r589 | if not isRadarFolder(thisPath): | ||
|
r487 | continue | ||
r892 | ||||
|
r487 | dirList.append(thisPath) | ||
r892 | ||||
|
r487 | if not(dirList): | ||
return None, None, None, None, None, None | ||||
r892 | ||||
|
r487 | dirList = sorted( dirList, key=str.lower ) | ||
r892 | ||||
|
r487 | doypath = dirList[-1] | ||
foldercounter = int(doypath.split('_')[1]) if len(doypath.split('_'))>1 else 0 | ||||
fullpath = os.path.join(path, doypath, expLabel) | ||||
r892 | ||||
|
r648 | print "[Reading] %s folder was found: " %(fullpath ) | ||
|
r487 | |||
if set == None: | ||||
filename = getlastFileFromPath(fullpath, ext) | ||||
else: | ||||
filename = getFileFromSet(fullpath, ext, set) | ||||
if not(filename): | ||||
return None, None, None, None, None, None | ||||
r892 | ||||
|
r648 | print "[Reading] %s file was found" %(filename) | ||
r892 | ||||
|
r487 | if not(self.__verifyFile(os.path.join(fullpath, filename))): | ||
return None, None, None, None, None, None | ||||
year = int( filename[1:5] ) | ||||
doy = int( filename[5:8] ) | ||||
r892 | set = int( filename[8:11] ) | |||
|
r487 | return fullpath, foldercounter, filename, year, doy, set | ||
r892 | ||||
|
r487 | def __setNextFileOffline(self): | ||
r892 | ||||
|
r487 | idFile = self.fileIndex | ||
while (True): | ||||
idFile += 1 | ||||
if not(idFile < len(self.filenameList)): | ||||
self.flagNoMoreFiles = 1 | ||||
|
r1013 | # print "[Reading] No more Files" | ||
|
r487 | return 0 | ||
filename = self.filenameList[idFile] | ||||
if not(self.__verifyFile(filename)): | ||||
continue | ||||
fileSize = os.path.getsize(filename) | ||||
fp = open(filename,'rb') | ||||
break | ||||
self.flagIsNewFile = 1 | ||||
self.fileIndex = idFile | ||||
self.filename = filename | ||||
self.fileSize = fileSize | ||||
self.fp = fp | ||||
|
r1013 | # print "[Reading] Setting the file: %s"%self.filename | ||
|
r487 | |||
return 1 | ||||
def __setNextFileOnline(self): | ||||
""" | ||||
Busca el siguiente file que tenga suficiente data para ser leida, dentro de un folder especifico, si | ||||
no encuentra un file valido espera un tiempo determinado y luego busca en los posibles n files | ||||
r892 | siguientes. | |||
Affected: | ||||
|
r487 | self.flagIsNewFile | ||
self.filename | ||||
self.fileSize | ||||
self.fp | ||||
self.set | ||||
self.flagNoMoreFiles | ||||
r892 | Return: | |||
|
r487 | 0 : si luego de una busqueda del siguiente file valido este no pudo ser encontrado | ||
1 : si el file fue abierto con exito y esta listo a ser leido | ||||
r892 | ||||
Excepciones: | ||||
|
r487 | Si un determinado file no puede ser abierto | ||
""" | ||||
nFiles = 0 | ||||
r892 | fileOk_flag = False | |||
|
r487 | firstTime_flag = True | ||
self.set += 1 | ||||
r892 | ||||
|
r487 | if self.set > 999: | ||
self.set = 0 | ||||
r892 | self.foldercounter += 1 | |||
|
r487 | #busca el 1er file disponible | ||
fullfilename, filename = checkForRealPath( self.path, self.foldercounter, self.year, self.doy, self.set, self.ext ) | ||||
if fullfilename: | ||||
if self.__verifyFile(fullfilename, False): | ||||
fileOk_flag = True | ||||
#si no encuentra un file entonces espera y vuelve a buscar | ||||
r892 | if not(fileOk_flag): | |||
|
r487 | for nFiles in range(self.nFiles+1): #busco en los siguientes self.nFiles+1 files posibles | ||
r892 | if firstTime_flag: #si es la 1era vez entonces hace el for self.nTries veces | |||
|
r487 | tries = self.nTries | ||
else: | ||||
tries = 1 #si no es la 1era vez entonces solo lo hace una vez | ||||
r892 | ||||
for nTries in range( tries ): | ||||
|
r487 | if firstTime_flag: | ||
r892 | print "\t[Reading] Waiting %0.2f sec for the next file: \"%s\" , try %03d ..." % ( self.delay, filename, nTries+1 ) | |||
|
r568 | sleep( self.delay ) | ||
|
r487 | else: | ||
|
r584 | print "\t[Reading] Searching the next \"%s%04d%03d%03d%s\" file ..." % (self.optchar, self.year, self.doy, self.set, self.ext) | ||
r892 | ||||
|
r487 | fullfilename, filename = checkForRealPath( self.path, self.foldercounter, self.year, self.doy, self.set, self.ext ) | ||
if fullfilename: | ||||
if self.__verifyFile(fullfilename): | ||||
fileOk_flag = True | ||||
break | ||||
r892 | ||||
|
r487 | if fileOk_flag: | ||
break | ||||
firstTime_flag = False | ||||
|
r584 | print "\t[Reading] Skipping the file \"%s\" due to this file doesn't exist" % filename | ||
|
r487 | self.set += 1 | ||
r892 | ||||
|
r487 | if nFiles == (self.nFiles-1): #si no encuentro el file buscado cambio de carpeta y busco en la siguiente carpeta | ||
self.set = 0 | ||||
self.doy += 1 | ||||
self.foldercounter = 0 | ||||
if fileOk_flag: | ||||
self.fileSize = os.path.getsize( fullfilename ) | ||||
self.filename = fullfilename | ||||
self.flagIsNewFile = 1 | ||||
r892 | if self.fp != None: self.fp.close() | |||
|
r487 | self.fp = open(fullfilename, 'rb') | ||
self.flagNoMoreFiles = 0 | ||||
|
r1013 | # print '[Reading] Setting the file: %s' % fullfilename | ||
|
r487 | else: | ||
self.fileSize = 0 | ||||
self.filename = None | ||||
self.flagIsNewFile = 0 | ||||
self.fp = None | ||||
self.flagNoMoreFiles = 1 | ||||
|
r1013 | # print '[Reading] No more files to read' | ||
|
r487 | |||
return fileOk_flag | ||||
r892 | ||||
|
r487 | def setNextFile(self): | ||
if self.fp != None: | ||||
self.fp.close() | ||||
if self.online: | ||||
newFile = self.__setNextFileOnline() | ||||
else: | ||||
newFile = self.__setNextFileOffline() | ||||
if not(newFile): | ||||
|
r584 | print '[Reading] No more files to read' | ||
|
r487 | return 0 | ||
|
r931 | if self.verbose: | ||
print '[Reading] Setting the file: %s' % self.filename | ||||
r892 | ||||
|
r487 | self.__readFirstHeader() | ||
self.nReadBlocks = 0 | ||||
return 1 | ||||
def __waitNewBlock(self): | ||||
""" | ||||
r892 | Return 1 si se encontro un nuevo bloque de datos, 0 de otra forma. | |||
|
r487 | Si el modo de lectura es OffLine siempre retorn 0 | ||
""" | ||||
if not self.online: | ||||
return 0 | ||||
r892 | ||||
|
r487 | if (self.nReadBlocks >= self.processingHeaderObj.dataBlocksPerFile): | ||
return 0 | ||||
r892 | ||||
|
r487 | currentPointer = self.fp.tell() | ||
r892 | ||||
|
r487 | neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize | ||
r892 | ||||
|
r487 | for nTries in range( self.nTries ): | ||
r892 | ||||
|
r487 | self.fp.close() | ||
self.fp = open( self.filename, 'rb' ) | ||||
self.fp.seek( currentPointer ) | ||||
self.fileSize = os.path.getsize( self.filename ) | ||||
currentSize = self.fileSize - currentPointer | ||||
if ( currentSize >= neededSize ): | ||||
self.basicHeaderObj.read(self.fp) | ||||
return 1 | ||||
r892 | ||||
|
r487 | if self.fileSize == self.fileSizeByHeader: | ||
|
r1013 | # self.flagEoF = True | ||
|
r487 | return 0 | ||
r892 | ||||
|
r568 | print "[Reading] Waiting %0.2f seconds for the next block, try %03d ..." % (self.delay, nTries+1) | ||
sleep( self.delay ) | ||||
r892 | ||||
return 0 | ||||
|
r487 | |||
def waitDataBlock(self,pointer_location): | ||||
r892 | ||||
|
r487 | currentPointer = pointer_location | ||
r892 | ||||
|
r487 | neededSize = self.processingHeaderObj.blockSize #+ self.basicHeaderSize | ||
r892 | ||||
|
r487 | for nTries in range( self.nTries ): | ||
self.fp.close() | ||||
self.fp = open( self.filename, 'rb' ) | ||||
self.fp.seek( currentPointer ) | ||||
r892 | ||||
|
r487 | self.fileSize = os.path.getsize( self.filename ) | ||
currentSize = self.fileSize - currentPointer | ||||
r892 | ||||
|
r487 | if ( currentSize >= neededSize ): | ||
return 1 | ||||
r892 | ||||
|
r568 | print "[Reading] Waiting %0.2f seconds for the next block, try %03d ..." % (self.delay, nTries+1) | ||
sleep( self.delay ) | ||||
r892 | ||||
|
r487 | return 0 | ||
def __jumpToLastBlock(self): | ||||
r892 | ||||
|
r487 | if not(self.__isFirstTimeOnline): | ||
return | ||||
r892 | ||||
|
r487 | csize = self.fileSize - self.fp.tell() | ||
blocksize = self.processingHeaderObj.blockSize | ||||
r892 | ||||
|
r487 | #salta el primer bloque de datos | ||
if csize > self.processingHeaderObj.blockSize: | ||||
self.fp.seek(self.fp.tell() + blocksize) | ||||
else: | ||||
return | ||||
r892 | ||||
|
r487 | csize = self.fileSize - self.fp.tell() | ||
neededsize = self.processingHeaderObj.blockSize + self.basicHeaderSize | ||||
while True: | ||||
r892 | ||||
|
r487 | if self.fp.tell()<self.fileSize: | ||
self.fp.seek(self.fp.tell() + neededsize) | ||||
else: | ||||
self.fp.seek(self.fp.tell() - neededsize) | ||||
break | ||||
|
r1013 | # csize = self.fileSize - self.fp.tell() | ||
# neededsize = self.processingHeaderObj.blockSize + self.basicHeaderSize | ||||
# factor = int(csize/neededsize) | ||||
# if factor > 0: | ||||
# self.fp.seek(self.fp.tell() + factor*neededsize) | ||||
|
r487 | |||
self.flagIsNewFile = 0 | ||||
self.__isFirstTimeOnline = 0 | ||||
def __setNewBlock(self): | ||||
|
r975 | #if self.server is None: | ||
if self.fp == None: | ||||
return 0 | ||||
|
r659 | |||
|
r1013 | # if self.online: | ||
# self.__jumpToLastBlock() | ||||
|
r487 | |||
if self.flagIsNewFile: | ||||
|
r659 | self.lastUTTime = self.basicHeaderObj.utc | ||
|
r487 | return 1 | ||
r892 | ||||
|
r659 | if self.realtime: | ||
self.flagDiscontinuousBlock = 1 | ||||
if not(self.setNextFile()): | ||||
return 0 | ||||
else: | ||||
|
r995 | return 1 | ||
|
r975 | #if self.server is None: | ||
currentSize = self.fileSize - self.fp.tell() | ||||
neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize | ||||
if (currentSize >= neededSize): | ||||
self.basicHeaderObj.read(self.fp) | ||||
|
r659 | self.lastUTTime = self.basicHeaderObj.utc | ||
|
r487 | return 1 | ||
|
r975 | # else: | ||
# self.basicHeaderObj.read(self.zHeader) | ||||
# self.lastUTTime = self.basicHeaderObj.utc | ||||
# return 1 | ||||
|
r487 | if self.__waitNewBlock(): | ||
|
r659 | self.lastUTTime = self.basicHeaderObj.utc | ||
|
r487 | return 1 | ||
|
r975 | #if self.server is None: | ||
if not(self.setNextFile()): | ||||
return 0 | ||||
|
r487 | |||
deltaTime = self.basicHeaderObj.utc - self.lastUTTime # | ||||
|
r659 | self.lastUTTime = self.basicHeaderObj.utc | ||
r892 | ||||
|
r568 | self.flagDiscontinuousBlock = 0 | ||
|
r487 | |||
if deltaTime > self.maxTimeStep: | ||||
|
r568 | self.flagDiscontinuousBlock = 1 | ||
|
r487 | |||
return 1 | ||||
def readNextBlock(self): | ||||
r892 | ||||
|
r759 | #Skip block out of startTime and endTime | ||
|
r995 | while True: | ||
|
r759 | if not(self.__setNewBlock()): | ||
|
r963 | print 'returning' | ||
|
r759 | return 0 | ||
|
r995 | |||
|
r759 | if not(self.readBlock()): | ||
return 0 | ||||
r892 | ||||
|
r759 | self.getBasicHeader() | ||
r892 | ||||
|
r759 | if not isTimeInRange(self.dataOut.datatime.time(), self.startTime, self.endTime): | ||
r892 | ||||
|
r759 | print "[Reading] Block No. %d/%d -> %s [Skipping]" %(self.nReadBlocks, | ||
self.processingHeaderObj.dataBlocksPerFile, | ||||
self.dataOut.datatime.ctime()) | ||||
continue | ||||
r892 | ||||
|
r759 | break | ||
r892 | ||||
|
r931 | if self.verbose: | ||
print "[Reading] Block No. %d/%d -> %s" %(self.nReadBlocks, | ||||
|
r1014 | self.processingHeaderObj.dataBlocksPerFile, | ||
self.dataOut.datatime.ctime()) | ||||
|
r487 | return 1 | ||
def __readFirstHeader(self): | ||||
r892 | ||||
|
r487 | self.basicHeaderObj.read(self.fp) | ||
self.systemHeaderObj.read(self.fp) | ||||
self.radarControllerHeaderObj.read(self.fp) | ||||
self.processingHeaderObj.read(self.fp) | ||||
self.firstHeaderSize = self.basicHeaderObj.size | ||||
datatype = int(numpy.log2((self.processingHeaderObj.processFlags & PROCFLAG.DATATYPE_MASK))-numpy.log2(PROCFLAG.DATATYPE_CHAR)) | ||||
if datatype == 0: | ||||
datatype_str = numpy.dtype([('real','<i1'),('imag','<i1')]) | ||||
elif datatype == 1: | ||||
datatype_str = numpy.dtype([('real','<i2'),('imag','<i2')]) | ||||
elif datatype == 2: | ||||
datatype_str = numpy.dtype([('real','<i4'),('imag','<i4')]) | ||||
elif datatype == 3: | ||||
datatype_str = numpy.dtype([('real','<i8'),('imag','<i8')]) | ||||
elif datatype == 4: | ||||
datatype_str = numpy.dtype([('real','<f4'),('imag','<f4')]) | ||||
elif datatype == 5: | ||||
datatype_str = numpy.dtype([('real','<f8'),('imag','<f8')]) | ||||
else: | ||||
raise ValueError, 'Data type was not defined' | ||||
self.dtype = datatype_str | ||||
#self.ippSeconds = 2 * 1000 * self.radarControllerHeaderObj.ipp / self.c | ||||
self.fileSizeByHeader = self.processingHeaderObj.dataBlocksPerFile * self.processingHeaderObj.blockSize + self.firstHeaderSize + self.basicHeaderSize*(self.processingHeaderObj.dataBlocksPerFile - 1) | ||||
|
r1013 | # self.dataOut.channelList = numpy.arange(self.systemHeaderObj.numChannels) | ||
# self.dataOut.channelIndexList = numpy.arange(self.systemHeaderObj.numChannels) | ||||
|
r487 | self.getBlockDimension() | ||
r892 | ||||
|
r487 | def __verifyFile(self, filename, msgFlag=True): | ||
r892 | ||||
|
r487 | msg = None | ||
r892 | ||||
|
r487 | try: | ||
fp = open(filename, 'rb') | ||||
except IOError: | ||||
r892 | ||||
|
r487 | if msgFlag: | ||
|
r684 | print "[Reading] File %s can't be opened" % (filename) | ||
r892 | ||||
|
r487 | return False | ||
r892 | ||||
|
r684 | currentPosition = fp.tell() | ||
|
r487 | neededSize = self.processingHeaderObj.blockSize + self.firstHeaderSize | ||
if neededSize == 0: | ||||
basicHeaderObj = BasicHeader(LOCALTIME) | ||||
systemHeaderObj = SystemHeader() | ||||
radarControllerHeaderObj = RadarControllerHeader() | ||||
processingHeaderObj = ProcessingHeader() | ||||
r892 | ||||
|
r684 | if not( basicHeaderObj.read(fp) ): | ||
fp.close() | ||||
return False | ||||
r892 | ||||
|
r684 | if not( systemHeaderObj.read(fp) ): | ||
|
r487 | fp.close() | ||
return False | ||||
r892 | ||||
|
r684 | if not( radarControllerHeaderObj.read(fp) ): | ||
fp.close() | ||||
return False | ||||
r892 | ||||
|
r684 | if not( processingHeaderObj.read(fp) ): | ||
fp.close() | ||||
return False | ||||
r892 | ||||
|
r684 | neededSize = processingHeaderObj.blockSize + basicHeaderObj.size | ||
|
r487 | else: | ||
|
r568 | msg = "[Reading] Skipping the file %s due to it hasn't enough data" %filename | ||
|
r487 | |||
fp.close() | ||||
r892 | ||||
|
r487 | fileSize = os.path.getsize(filename) | ||
currentSize = fileSize - currentPosition | ||||
r892 | ||||
|
r487 | if currentSize < neededSize: | ||
if msgFlag and (msg != None): | ||||
|
r684 | print msg | ||
|
r487 | return False | ||
return True | ||||
|
r640 | def findDatafiles(self, path, startDate=None, endDate=None, expLabel='', ext='.r', walk=True, include_path=False): | ||
r892 | ||||
|
r759 | path_empty = True | ||
r892 | ||||
|
r589 | dateList = [] | ||
pathList = [] | ||||
r892 | ||||
|
r640 | multi_path = path.split(',') | ||
r892 | ||||
|
r589 | if not walk: | ||
r892 | ||||
|
r589 | for single_path in multi_path: | ||
r892 | ||||
|
r607 | if not os.path.isdir(single_path): | ||
continue | ||||
r892 | ||||
|
r589 | fileList = glob.glob1(single_path, "*"+ext) | ||
r892 | ||||
|
r726 | if not fileList: | ||
continue | ||||
r892 | ||||
|
r759 | path_empty = False | ||
r892 | ||||
|
r726 | fileList.sort() | ||
r892 | ||||
|
r589 | for thisFile in fileList: | ||
r892 | ||||
|
r589 | if not os.path.isfile(os.path.join(single_path, thisFile)): | ||
continue | ||||
r892 | ||||
|
r589 | if not isRadarFile(thisFile): | ||
continue | ||||
r892 | ||||
|
r640 | if not isFileInDateRange(thisFile, startDate, endDate): | ||
continue | ||||
r892 | ||||
|
r589 | thisDate = getDateFromRadarFile(thisFile) | ||
r892 | ||||
|
r640 | if thisDate in dateList: | ||
continue | ||||
r892 | ||||
|
r640 | dateList.append(thisDate) | ||
|
r589 | pathList.append(single_path) | ||
r892 | ||||
|
r640 | else: | ||
for single_path in multi_path: | ||||
r892 | ||||
|
r640 | if not os.path.isdir(single_path): | ||
|
r589 | continue | ||
r892 | ||||
|
r640 | dirList = [] | ||
r892 | ||||
|
r640 | for thisPath in os.listdir(single_path): | ||
r892 | ||||
|
r640 | if not os.path.isdir(os.path.join(single_path,thisPath)): | ||
|
r589 | continue | ||
r892 | ||||
|
r640 | if not isRadarFolder(thisPath): | ||
continue | ||||
r892 | ||||
|
r640 | if not isFolderInDateRange(thisPath, startDate, endDate): | ||
continue | ||||
r892 | ||||
|
r640 | dirList.append(thisPath) | ||
r892 | ||||
|
r640 | if not dirList: | ||
continue | ||||
r892 | ||||
|
r726 | dirList.sort() | ||
r892 | ||||
|
r601 | for thisDir in dirList: | ||
r892 | ||||
|
r632 | datapath = os.path.join(single_path, thisDir, expLabel) | ||
fileList = glob.glob1(datapath, "*"+ext) | ||||
r892 | ||||
|
r759 | if not fileList: | ||
|
r632 | continue | ||
r892 | ||||
|
r759 | path_empty = False | ||
r892 | ||||
|
r640 | thisDate = getDateFromRadarFolder(thisDir) | ||
r892 | ||||
|
r632 | pathList.append(datapath) | ||
|
r589 | dateList.append(thisDate) | ||
r892 | ||||
|
r640 | dateList.sort() | ||
r892 | ||||
|
r684 | if walk: | ||
pattern_path = os.path.join(multi_path[0], "[dYYYYDDD]", expLabel) | ||||
else: | ||||
pattern_path = multi_path[0] | ||||
r892 | ||||
|
r759 | if path_empty: | ||
print "[Reading] No *%s files in %s for %s to %s" %(ext, pattern_path, startDate, endDate) | ||||
else: | ||||
if not dateList: | ||||
print "[Reading] Date range selected invalid [%s - %s]: No *%s files in %s)" %(startDate, endDate, ext, path) | ||||
|
r640 | if include_path: | ||
return dateList, pathList | ||||
r892 | ||||
|
r640 | return dateList | ||
r892 | ||||
|
r487 | def setup(self, | ||
path=None, | ||||
r892 | startDate=None, | |||
endDate=None, | ||||
startTime=datetime.time(0,0,0), | ||||
endTime=datetime.time(23,59,59), | ||||
set=None, | ||||
expLabel = "", | ||||
ext = None, | ||||
|
r487 | online = False, | ||
delay = 60, | ||||
|
r495 | walk = True, | ||
|
r534 | getblock = False, | ||
|
r659 | nTxs = 1, | ||
|
r833 | realtime=False, | ||
blocksize=None, | ||||
r892 | blocktime=None, | |||
queue=None, | ||||
skip=None, | ||||
|
r931 | cursor=None, | ||
warnings=True, | ||||
|
r961 | verbose=True, | ||
server=None): | ||||
if server is not None: | ||||
if 'tcp://' in server: | ||||
address = server | ||||
else: | ||||
address = 'ipc:///tmp/%s' % server | ||||
|
r963 | self.server = address | ||
|
r961 | self.context = zmq.Context() | ||
self.receiver = self.context.socket(zmq.PULL) | ||||
|
r975 | self.receiver.connect(self.server) | ||
|
r961 | time.sleep(0.5) | ||
|
r963 | print '[Starting] ReceiverData from {}'.format(self.server) | ||
else: | ||||
self.server = None | ||||
|
r961 | if path == None: | ||
raise ValueError, "[Reading] The path is not valid" | ||||
if ext == None: | ||||
ext = self.ext | ||||
if online: | ||||
print "[Reading] Searching files in online mode..." | ||||
for nTries in range( self.nTries ): | ||||
fullpath, foldercounter, file, year, doy, set = self.__searchFilesOnLine(path=path, expLabel=expLabel, ext=ext, walk=walk, set=set) | ||||
if fullpath: | ||||
break | ||||
print '[Reading] Waiting %0.2f sec for an valid file in %s: try %02d ...' % (self.delay, path, nTries+1) | ||||
sleep( self.delay ) | ||||
if not(fullpath): | ||||
print "[Reading] There 'isn't any valid file in %s" % path | ||||
return | ||||
self.year = year | ||||
self.doy = doy | ||||
self.set = set - 1 | ||||
self.path = path | ||||
self.foldercounter = foldercounter | ||||
last_set = None | ||||
else: | ||||
print "[Reading] Searching files in offline mode ..." | ||||
pathList, filenameList = self.__searchFilesOffLine(path, startDate=startDate, endDate=endDate, | ||||
startTime=startTime, endTime=endTime, | ||||
set=set, expLabel=expLabel, ext=ext, | ||||
walk=walk, cursor=cursor, | ||||
skip=skip, queue=queue) | ||||
r892 | ||||
|
r961 | if not(pathList): | ||
|
r1014 | # print "[Reading] No *%s files in %s (%s - %s)"%(ext, path, | ||
# datetime.datetime.combine(startDate,startTime).ctime(), | ||||
# datetime.datetime.combine(endDate,endTime).ctime()) | ||||
r892 | ||||
|
r1014 | # sys.exit(-1) | ||
r892 | ||||
|
r961 | self.fileIndex = -1 | ||
self.pathList = [] | ||||
self.filenameList = [] | ||||
return | ||||
r892 | ||||
|
r676 | self.fileIndex = -1 | ||
|
r961 | self.pathList = pathList | ||
self.filenameList = filenameList | ||||
file_name = os.path.basename(filenameList[-1]) | ||||
basename, ext = os.path.splitext(file_name) | ||||
last_set = int(basename[-3:]) | ||||
self.online = online | ||||
self.realtime = realtime | ||||
self.delay = delay | ||||
ext = ext.lower() | ||||
self.ext = ext | ||||
self.getByBlock = getblock | ||||
self.nTxs = nTxs | ||||
self.startTime = startTime | ||||
self.endTime = endTime | ||||
#Added----------------- | ||||
self.selBlocksize = blocksize | ||||
self.selBlocktime = blocktime | ||||
# Verbose----------- | ||||
self.verbose = verbose | ||||
self.warnings = warnings | ||||
r892 | ||||
|
r961 | if not(self.setNextFile()): | ||
if (startDate!=None) and (endDate!=None): | ||||
print "[Reading] No files in range: %s - %s" %(datetime.datetime.combine(startDate,startTime).ctime(), datetime.datetime.combine(endDate,endTime).ctime()) | ||||
elif startDate != None: | ||||
print "[Reading] No files in range: %s" %(datetime.datetime.combine(startDate,startTime).ctime()) | ||||
else: | ||||
print "[Reading] No files" | ||||
r892 | ||||
|
r961 | self.fileIndex = -1 | ||
self.pathList = [] | ||||
self.filenameList = [] | ||||
return | ||||
|
r487 | |||
|
r1014 | # self.getBasicHeader() | ||
r892 | ||||
|
r487 | if last_set != None: | ||
self.dataOut.last_block = last_set * self.processingHeaderObj.dataBlocksPerFile + self.basicHeaderObj.dataBlock | ||||
return | ||||
def getBasicHeader(self): | ||||
r892 | ||||
|
r487 | self.dataOut.utctime = self.basicHeaderObj.utc + self.basicHeaderObj.miliSecond/1000. + self.profileIndex * self.radarControllerHeaderObj.ippSeconds | ||
r892 | ||||
|
r568 | self.dataOut.flagDiscontinuousBlock = self.flagDiscontinuousBlock | ||
r892 | ||||
|
r487 | self.dataOut.timeZone = self.basicHeaderObj.timeZone | ||
r892 | ||||
|
r487 | self.dataOut.dstFlag = self.basicHeaderObj.dstFlag | ||
r892 | ||||
|
r487 | self.dataOut.errorCount = self.basicHeaderObj.errorCount | ||
r892 | ||||
|
r487 | self.dataOut.useLocalTime = self.basicHeaderObj.useLocalTime | ||
r892 | ||||
|
r563 | self.dataOut.ippSeconds = self.radarControllerHeaderObj.ippSeconds/self.nTxs | ||
r892 | ||||
|
r833 | # self.dataOut.nProfiles = self.processingHeaderObj.profilesPerBlock*self.nTxs | ||
r892 | ||||
|
r487 | def getFirstHeader(self): | ||
r892 | ||||
|
r684 | raise NotImplementedError | ||
r892 | ||||
|
r487 | def getData(self): | ||
r892 | ||||
|
r684 | raise NotImplementedError | ||
|
r487 | |||
def hasNotDataInBuffer(self): | ||||
r892 | ||||
|
r684 | raise NotImplementedError | ||
|
r487 | |||
def readBlock(self): | ||||
r892 | ||||
|
r684 | raise NotImplementedError | ||
r892 | ||||
|
r487 | def isEndProcess(self): | ||
r892 | ||||
|
r487 | return self.flagNoMoreFiles | ||
r892 | ||||
|
r487 | def printReadBlocks(self): | ||
r892 | ||||
|
r568 | print "[Reading] Number of read blocks per file %04d" %self.nReadBlocks | ||
r892 | ||||
|
r487 | def printTotalBlocks(self): | ||
r892 | ||||
|
r568 | print "[Reading] Number of read blocks %04d" %self.nTotalBlocks | ||
|
r487 | |||
def printNumberOfBlock(self): | ||||
r892 | ||||
|
r487 | if self.flagIsNewBlock: | ||
|
r632 | print "[Reading] Block No. %d/%d -> %s" %(self.nReadBlocks, | ||
|
r616 | self.processingHeaderObj.dataBlocksPerFile, | ||
self.dataOut.datatime.ctime()) | ||||
|
r487 | |||
def printInfo(self): | ||||
r892 | ||||
|
r487 | if self.__printInfo == False: | ||
return | ||||
r892 | ||||
|
r487 | self.basicHeaderObj.printInfo() | ||
self.systemHeaderObj.printInfo() | ||||
self.radarControllerHeaderObj.printInfo() | ||||
self.processingHeaderObj.printInfo() | ||||
r892 | ||||
|
r487 | self.__printInfo = False | ||
r892 | ||||
|
r944 | def run(self, | ||
path=None, | ||||
startDate=None, | ||||
endDate=None, | ||||
startTime=datetime.time(0,0,0), | ||||
endTime=datetime.time(23,59,59), | ||||
set=None, | ||||
expLabel = "", | ||||
ext = None, | ||||
online = False, | ||||
delay = 60, | ||||
walk = True, | ||||
getblock = False, | ||||
nTxs = 1, | ||||
realtime=False, | ||||
blocksize=None, | ||||
blocktime=None, | ||||
queue=None, | ||||
skip=None, | ||||
cursor=None, | ||||
warnings=True, | ||||
|
r961 | server=None, | ||
|
r944 | verbose=True, **kwargs): | ||
r892 | ||||
|
r487 | if not(self.isConfig): | ||
# self.dataOut = dataOut | ||||
|
r944 | self.setup( path=path, | ||
startDate=startDate, | ||||
endDate=endDate, | ||||
startTime=startTime, | ||||
endTime=endTime, | ||||
set=set, | ||||
expLabel=expLabel, | ||||
ext=ext, | ||||
online=online, | ||||
delay=delay, | ||||
walk=walk, | ||||
getblock=getblock, | ||||
nTxs=nTxs, | ||||
realtime=realtime, | ||||
blocksize=blocksize, | ||||
blocktime=blocktime, | ||||
queue=queue, | ||||
skip=skip, | ||||
cursor=cursor, | ||||
warnings=warnings, | ||||
|
r963 | server=server, | ||
|
r944 | verbose=verbose) | ||
|
r487 | self.isConfig = True | ||
|
r975 | if server is None: | ||
self.getData() | ||||
else: | ||||
self.getFromServer() | ||||
|
r487 | |||
class JRODataWriter(JRODataIO): | ||||
r892 | """ | |||
|
r487 | Esta clase permite escribir datos a archivos procesados (.r o ,pdata). La escritura | ||
r892 | de los datos siempre se realiza por bloques. | |||
|
r487 | """ | ||
r892 | ||||
|
r487 | blockIndex = 0 | ||
r892 | ||||
|
r487 | path = None | ||
r892 | ||||
|
r487 | setFile = None | ||
r892 | ||||
|
r487 | profilesPerBlock = None | ||
r892 | ||||
|
r487 | blocksPerFile = None | ||
r892 | ||||
|
r487 | nWriteBlocks = 0 | ||
r892 | ||||
|
r632 | fileDate = None | ||
r892 | ||||
|
r487 | def __init__(self, dataOut=None): | ||
|
r684 | raise NotImplementedError | ||
|
r487 | |||
def hasAllDataInBuffer(self): | ||||
|
r684 | raise NotImplementedError | ||
|
r487 | |||
def setBlockDimension(self): | ||||
|
r684 | raise NotImplementedError | ||
|
r487 | |||
r892 | ||||
|
r487 | def writeBlock(self): | ||
|
r684 | raise NotImplementedError | ||
|
r487 | |||
def putData(self): | ||||
|
r684 | raise NotImplementedError | ||
|
r487 | |||
r892 | ||||
|
r616 | def getProcessFlags(self): | ||
r892 | ||||
|
r616 | processFlags = 0 | ||
r892 | ||||
|
r616 | dtype_index = get_dtype_index(self.dtype) | ||
procflag_dtype = get_procflag_dtype(dtype_index) | ||||
r892 | ||||
|
r616 | processFlags += procflag_dtype | ||
r892 | ||||
|
r616 | if self.dataOut.flagDecodeData: | ||
processFlags += PROCFLAG.DECODE_DATA | ||||
r892 | ||||
|
r616 | if self.dataOut.flagDeflipData: | ||
processFlags += PROCFLAG.DEFLIP_DATA | ||||
r892 | ||||
|
r616 | if self.dataOut.code is not None: | ||
processFlags += PROCFLAG.DEFINE_PROCESS_CODE | ||||
r892 | ||||
|
r616 | if self.dataOut.nCohInt > 1: | ||
processFlags += PROCFLAG.COHERENT_INTEGRATION | ||||
r892 | ||||
|
r616 | if self.dataOut.type == "Spectra": | ||
if self.dataOut.nIncohInt > 1: | ||||
processFlags += PROCFLAG.INCOHERENT_INTEGRATION | ||||
r892 | ||||
|
r616 | if self.dataOut.data_dc is not None: | ||
processFlags += PROCFLAG.SAVE_CHANNELS_DC | ||||
r892 | ||||
|
r624 | if self.dataOut.flagShiftFFT: | ||
processFlags += PROCFLAG.SHIFT_FFT_DATA | ||||
r892 | ||||
|
r616 | return processFlags | ||
r892 | ||||
|
r487 | def setBasicHeader(self): | ||
r892 | ||||
|
r487 | self.basicHeaderObj.size = self.basicHeaderSize #bytes | ||
self.basicHeaderObj.version = self.versionFile | ||||
|
r632 | self.basicHeaderObj.dataBlock = self.nTotalBlocks | ||
r892 | ||||
|
r487 | utc = numpy.floor(self.dataOut.utctime) | ||
milisecond = (self.dataOut.utctime - utc)* 1000.0 | ||||
r892 | ||||
|
r487 | self.basicHeaderObj.utc = utc | ||
self.basicHeaderObj.miliSecond = milisecond | ||||
self.basicHeaderObj.timeZone = self.dataOut.timeZone | ||||
self.basicHeaderObj.dstFlag = self.dataOut.dstFlag | ||||
self.basicHeaderObj.errorCount = self.dataOut.errorCount | ||||
r892 | ||||
|
r487 | def setFirstHeader(self): | ||
""" | ||||
Obtiene una copia del First Header | ||||
r892 | ||||
|
r487 | Affected: | ||
r892 | ||||
|
r487 | self.basicHeaderObj | ||
self.systemHeaderObj | ||||
self.radarControllerHeaderObj | ||||
self.processingHeaderObj self. | ||||
r892 | ||||
|
r487 | Return: | ||
None | ||||
""" | ||||
r892 | ||||
|
r684 | raise NotImplementedError | ||
r892 | ||||
|
r487 | def __writeFirstHeader(self): | ||
""" | ||||
Escribe el primer header del file es decir el Basic header y el Long header (SystemHeader, RadarControllerHeader, ProcessingHeader) | ||||
r892 | ||||
|
r487 | Affected: | ||
__dataType | ||||
r892 | ||||
|
r487 | Return: | ||
None | ||||
""" | ||||
r892 | ||||
|
r487 | # CALCULAR PARAMETROS | ||
r892 | ||||
|
r487 | sizeLongHeader = self.systemHeaderObj.size + self.radarControllerHeaderObj.size + self.processingHeaderObj.size | ||
self.basicHeaderObj.size = self.basicHeaderSize + sizeLongHeader | ||||
r892 | ||||
|
r487 | self.basicHeaderObj.write(self.fp) | ||
self.systemHeaderObj.write(self.fp) | ||||
self.radarControllerHeaderObj.write(self.fp) | ||||
self.processingHeaderObj.write(self.fp) | ||||
r892 | ||||
|
r487 | def __setNewBlock(self): | ||
""" | ||||
Si es un nuevo file escribe el First Header caso contrario escribe solo el Basic Header | ||||
r892 | ||||
|
r487 | Return: | ||
0 : si no pudo escribir nada | ||||
1 : Si escribio el Basic el First Header | ||||
r892 | """ | |||
|
r487 | if self.fp == None: | ||
self.setNextFile() | ||||
r892 | ||||
|
r487 | if self.flagIsNewFile: | ||
return 1 | ||||
r892 | ||||
|
r487 | if self.blockIndex < self.processingHeaderObj.dataBlocksPerFile: | ||
self.basicHeaderObj.write(self.fp) | ||||
return 1 | ||||
r892 | ||||
|
r487 | if not( self.setNextFile() ): | ||
return 0 | ||||
r892 | ||||
|
r487 | return 1 | ||
def writeNextBlock(self): | ||||
""" | ||||
Selecciona el bloque siguiente de datos y los escribe en un file | ||||
r892 | ||||
Return: | ||||
0 : Si no hizo pudo escribir el bloque de datos | ||||
|
r487 | 1 : Si no pudo escribir el bloque de datos | ||
""" | ||||
if not( self.__setNewBlock() ): | ||||
return 0 | ||||
r892 | ||||
|
r487 | self.writeBlock() | ||
r892 | ||||
|
r632 | print "[Writing] Block No. %d/%d" %(self.blockIndex, | ||
self.processingHeaderObj.dataBlocksPerFile) | ||||
r892 | ||||
return 1 | ||||
|
r487 | |||
def setNextFile(self): | ||||
r892 | """ | |||
|
r487 | Determina el siguiente file que sera escrito | ||
r892 | Affected: | |||
|
r487 | self.filename | ||
self.subfolder | ||||
self.fp | ||||
self.setFile | ||||
self.flagIsNewFile | ||||
Return: | ||||
0 : Si el archivo no puede ser escrito | ||||
1 : Si el archivo esta listo para ser escrito | ||||
""" | ||||
ext = self.ext | ||||
path = self.path | ||||
r892 | ||||
|
r487 | if self.fp != None: | ||
self.fp.close() | ||||
r892 | ||||
|
r487 | timeTuple = time.localtime( self.dataOut.utctime) | ||
subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday) | ||||
fullpath = os.path.join( path, subfolder ) | ||||
|
r632 | setFile = self.setFile | ||
r892 | ||||
|
r487 | if not( os.path.exists(fullpath) ): | ||
os.mkdir(fullpath) | ||||
|
r632 | setFile = -1 #inicializo mi contador de seteo | ||
|
r487 | else: | ||
filesList = os.listdir( fullpath ) | ||||
if len( filesList ) > 0: | ||||
filesList = sorted( filesList, key=str.lower ) | ||||
filen = filesList[-1] | ||||
# el filename debera tener el siguiente formato | ||||
# 0 1234 567 89A BCDE (hex) | ||||
# x YYYY DDD SSS .ext | ||||
if isNumber( filen[8:11] ): | ||||
|
r632 | setFile = int( filen[8:11] ) #inicializo mi contador de seteo al seteo del ultimo file | ||
r892 | else: | |||
|
r632 | setFile = -1 | ||
|
r487 | else: | ||
|
r632 | setFile = -1 #inicializo mi contador de seteo | ||
r892 | ||||
|
r487 | setFile += 1 | ||
r892 | ||||
|
r632 | #If this is a new day it resets some values | ||
if self.dataOut.datatime.date() > self.fileDate: | ||||
setFile = 0 | ||||
self.nTotalBlocks = 0 | ||||
r892 | ||||
|
r632 | filen = '%s%4.4d%3.3d%3.3d%s' % (self.optchar, timeTuple.tm_year, timeTuple.tm_yday, setFile, ext ) | ||
|
r487 | |||
|
r568 | filename = os.path.join( path, subfolder, filen ) | ||
|
r487 | |||
fp = open( filename,'wb' ) | ||||
r892 | ||||
|
r487 | self.blockIndex = 0 | ||
r892 | ||||
#guardando atributos | ||||
|
r487 | self.filename = filename | ||
self.subfolder = subfolder | ||||
self.fp = fp | ||||
self.setFile = setFile | ||||
self.flagIsNewFile = 1 | ||||
|
r632 | self.fileDate = self.dataOut.datatime.date() | ||
r892 | ||||
|
r487 | self.setFirstHeader() | ||
r892 | ||||
|
r616 | print '[Writing] Opening file: %s'%self.filename | ||
r892 | ||||
|
r487 | self.__writeFirstHeader() | ||
r892 | ||||
|
r487 | return 1 | ||
r892 | ||||
|
r632 | def setup(self, dataOut, path, blocksPerFile, profilesPerBlock=64, set=None, ext=None, datatype=4): | ||
|
r487 | """ | ||
r892 | Setea el tipo de formato en la cual sera guardada la data y escribe el First Header | |||
|
r487 | Inputs: | ||
|
r616 | path : directory where data will be saved | ||
r892 | profilesPerBlock : number of profiles per block | |||
|
r626 | set : initial file set | ||
|
r616 | datatype : An integer number that defines data type: | ||
0 : int8 (1 byte) | ||||
1 : int16 (2 bytes) | ||||
2 : int32 (4 bytes) | ||||
3 : int64 (8 bytes) | ||||
|
r626 | 4 : float32 (4 bytes) | ||
5 : double64 (8 bytes) | ||||
r892 | ||||
|
r487 | Return: | ||
0 : Si no realizo un buen seteo | ||||
r892 | 1 : Si realizo un buen seteo | |||
|
r487 | """ | ||
r892 | ||||
|
r487 | if ext == None: | ||
ext = self.ext | ||||
r892 | ||||
|
r632 | self.ext = ext.lower() | ||
r892 | ||||
|
r487 | self.path = path | ||
r892 | ||||
|
r632 | if set is None: | ||
self.setFile = -1 | ||||
else: | ||||
self.setFile = set - 1 | ||||
r892 | ||||
|
r487 | self.blocksPerFile = blocksPerFile | ||
r892 | ||||
|
r487 | self.profilesPerBlock = profilesPerBlock | ||
r892 | ||||
|
r487 | self.dataOut = dataOut | ||
|
r632 | self.fileDate = self.dataOut.datatime.date() | ||
|
r616 | #By default | ||
self.dtype = self.dataOut.dtype | ||||
r892 | ||||
|
r616 | if datatype is not None: | ||
self.dtype = get_numpy_dtype(datatype) | ||||
r892 | ||||
|
r487 | if not(self.setNextFile()): | ||
|
r568 | print "[Writing] There isn't a next file" | ||
|
r487 | return 0 | ||
r892 | ||||
|
r487 | self.setBlockDimension() | ||
r892 | ||||
|
r487 | return 1 | ||
r892 | ||||
|
r944 | def run(self, dataOut, path, blocksPerFile, profilesPerBlock=64, set=None, ext=None, datatype=4, **kwargs): | ||
r892 | ||||
|
r487 | if not(self.isConfig): | ||
r892 | ||||
|
r944 | self.setup(dataOut, path, blocksPerFile, profilesPerBlock=profilesPerBlock, set=set, ext=ext, datatype=datatype, **kwargs) | ||
|
r487 | self.isConfig = True | ||
r892 | self.putData() | |||