#! /usr/bin/env python """ MDF - Multipe Data Formats Description Quick access to hdf or netcdf files. Since a number of different python modules is available to read this type of files, the mdf routines first try to find out which one is installed: o for hdf files : pyhdf o for netcdf files : pycdf or netCDF4 Usage: mdf.show( 'myfile.nc' ) vnames = mdf.get_varnames( 'myfile.nc' ) data = mdf.get_var ( 'myfile.nc', 'mydata' ) data = mdf.get_var_attr( 'myfile.nc', 'mydata', 'variable_attribute' ) data = mdf.get_attr ( 'myfile.nc', 'global_attribute' ) HDF files with non-unique data set names HDF files could contain multiple data sets with the same name; not very useful, but there is nothing that prevents a user from doing it so mdf has to deal with it. The following convention is used: o If data is requested with 'get_var' and multiple data sets match the name, than all matching data sets are concatenated as if they are time records. o If a specific sample is needed, add the optional 'sample' argument: data = mdf.get_var( 'myfile.nc', 'mydata', sample=1 ) The sample number is 1-based. If only one matching data set is found, this one is returned. History 2010-08, Arjo Segers """ # *** def MyLogger( name ) : """ Setup logger; if not logging configured yet, write to standard output. """ # external: import logging import sys # setup logger: logger = logging.getLogger( name ) # no handlers yet ? then print to standard output: if len(logger.handlers) == 0 : logger.addHandler(logging.StreamHandler(sys.stdout)) # no level set yet ? then set for info and higher: if logger.level == 0 : logger.setLevel(logging.INFO) # ok: return logger #enddef # *** def GetModuleName( fname ) : """ Return a character key that specifies the python module to be used. First select between hdf and netcdf given the filename extension. Then try if a known module is present to read the file. Supported: pyhdf pycdf netCDF4 """ # get logger: logger = MyLogger('mdf') # set module names for filetype: if fname.endswith('.hdf') : modnames = ['pyhdf'] elif fname.endswith('.nc') : filetype = 'netcdf' modnames = ['netCDF4','pycdf'] else : logger.error( 'could not guess filetype from extension for file : %s' % fname ) raise ValueError #endif # none found yet: modname = None # loop over modules to be tested: for amodname in modnames : try : # import : testmod = __import__(amodname) # no exceptions ? then this one is ok: modname = amodname break except : # try next: continue #endtry #endfor # check .. if modname == None : logger.error( 'could not import any of the modules : %s' % modnames ) raise ImportError #endif # ok return modname #enddef # *** def show( fname ) : """ List contents of file. """ # modules: import os # get logger: logger = MyLogger('mdf') # check ... if not os.path.exists(fname) : logger.error( 'file not found : %s' % fname ) raise IOError #endif # different modules: modname = GetModuleName( fname ) # import : submod = __import__( 'mdf_'+modname ) # apply: submod.show( fname ) # ok return #enddef # *** def get_varnames( fname ) : """ Return list with variable names. """ # modules: import os # get logger: logger = MyLogger('mdf') # check ... if not os.path.exists(fname) : logger.error( 'file not found : %s' % fname ) raise IOError #endif # different modules: modname = GetModuleName( fname ) # import : submod = __import__( 'mdf_'+modname ) # apply: values = submod.get_varnames( fname ) # ok return values #enddef # *** def get_var( fname, vname, sample=None ) : """ Read variable from file. Sample number (1-based) could be used to select a data set from a hdf file which has more than one matching data set. """ # modules: import os # get logger: logger = MyLogger('mdf') # check ... if not os.path.exists(fname) : logger.error( 'file not found : %s' % fname ) raise IOError #endif # different modules: modname = GetModuleName( fname ) # import : submod = __import__( 'mdf_'+modname ) # apply: values = submod.get_var( fname, vname, sample=sample ) # ok return values #enddef # *** def get_attr( fname, aname ) : """ Read global attribute from file. """ # modules: import os # get logger: logger = MyLogger('mdf') # check ... if not os.path.exists(fname) : logger.error( 'file not found : %s' % fname ) raise IOError #endif # different modules: modname = GetModuleName( fname ) # import : submod = __import__( 'mdf_'+modname ) # apply: values = submod.get_attr( fname, aname ) # ok return values #enddef # *** def get_var_attr( fname, vname, aname ) : """ Read variable attribute from file. """ # modules: import os # get logger: logger = MyLogger('mdf') # check ... if not os.path.exists(fname) : logger.error( 'file not found : %s' % fname ) raise IOError #endif # different modules: modname = GetModuleName( fname ) # import : submod = __import__( 'mdf_'+modname ) # apply: values = submod.get_var_attr( fname, vname, aname ) # ok return values #enddef