mdf.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. #! /usr/bin/env python
  2. """
  3. MDF - Multipe Data Formats
  4. Description
  5. Quick access to hdf or netcdf files.
  6. Since a number of different python modules is available
  7. to read this type of files, the mdf routines first try to
  8. find out which one is installed:
  9. o for hdf files : pyhdf
  10. o for netcdf files : pycdf or netCDF4
  11. Usage:
  12. mdf.show( 'myfile.nc' )
  13. vnames = mdf.get_varnames( 'myfile.nc' )
  14. data = mdf.get_var ( 'myfile.nc', 'mydata' )
  15. data = mdf.get_var_attr( 'myfile.nc', 'mydata', 'variable_attribute' )
  16. data = mdf.get_attr ( 'myfile.nc', 'global_attribute' )
  17. HDF files with non-unique data set names
  18. HDF files could contain multiple data sets with the same name;
  19. not very useful, but there is nothing that prevents a user from
  20. doing it so mdf has to deal with it. The following convention is used:
  21. o If data is requested with 'get_var' and multiple data sets match
  22. the name, than all matching data sets are concatenated as if they
  23. are time records.
  24. o If a specific sample is needed, add the optional 'sample' argument:
  25. data = mdf.get_var( 'myfile.nc', 'mydata', sample=1 )
  26. The sample number is 1-based.
  27. If only one matching data set is found, this one is returned.
  28. History
  29. 2010-08, Arjo Segers
  30. """
  31. # ***
  32. def MyLogger( name ) :
  33. """
  34. Setup logger; if not logging configured yet, write to standard output.
  35. """
  36. # external:
  37. import logging
  38. import sys
  39. # setup logger:
  40. logger = logging.getLogger( name )
  41. # no handlers yet ? then print to standard output:
  42. if len(logger.handlers) == 0 : logger.addHandler(logging.StreamHandler(sys.stdout))
  43. # no level set yet ? then set for info and higher:
  44. if logger.level == 0 : logger.setLevel(logging.INFO)
  45. # ok:
  46. return logger
  47. #enddef
  48. # ***
  49. def GetModuleName( fname ) :
  50. """
  51. Return a character key that specifies the python module to be used.
  52. First select between hdf and netcdf given the filename extension.
  53. Then try if a known module is present to read the file.
  54. Supported:
  55. pyhdf
  56. pycdf
  57. netCDF4
  58. """
  59. # get logger:
  60. logger = MyLogger('mdf')
  61. # set module names for filetype:
  62. if fname.endswith('.hdf') :
  63. modnames = ['pyhdf']
  64. elif fname.endswith('.nc') :
  65. filetype = 'netcdf'
  66. modnames = ['netCDF4','pycdf']
  67. else :
  68. logger.error( 'could not guess filetype from extension for file : %s' % fname )
  69. raise ValueError
  70. #endif
  71. # none found yet:
  72. modname = None
  73. # loop over modules to be tested:
  74. for amodname in modnames :
  75. try :
  76. # import :
  77. testmod = __import__(amodname)
  78. # no exceptions ? then this one is ok:
  79. modname = amodname
  80. break
  81. except :
  82. # try next:
  83. continue
  84. #endtry
  85. #endfor
  86. # check ..
  87. if modname == None :
  88. logger.error( 'could not import any of the modules : %s' % modnames )
  89. raise ImportError
  90. #endif
  91. # ok
  92. return modname
  93. #enddef
  94. # ***
  95. def show( fname ) :
  96. """
  97. List contents of file.
  98. """
  99. # modules:
  100. import os
  101. # get logger:
  102. logger = MyLogger('mdf')
  103. # check ...
  104. if not os.path.exists(fname) :
  105. logger.error( 'file not found : %s' % fname )
  106. raise IOError
  107. #endif
  108. # different modules:
  109. modname = GetModuleName( fname )
  110. # import :
  111. submod = __import__( 'mdf_'+modname )
  112. # apply:
  113. submod.show( fname )
  114. # ok
  115. return
  116. #enddef
  117. # ***
  118. def get_varnames( fname ) :
  119. """
  120. Return list with variable names.
  121. """
  122. # modules:
  123. import os
  124. # get logger:
  125. logger = MyLogger('mdf')
  126. # check ...
  127. if not os.path.exists(fname) :
  128. logger.error( 'file not found : %s' % fname )
  129. raise IOError
  130. #endif
  131. # different modules:
  132. modname = GetModuleName( fname )
  133. # import :
  134. submod = __import__( 'mdf_'+modname )
  135. # apply:
  136. values = submod.get_varnames( fname )
  137. # ok
  138. return values
  139. #enddef
  140. # ***
  141. def get_var( fname, vname, sample=None ) :
  142. """
  143. Read variable from file.
  144. Sample number (1-based) could be used to select a
  145. data set from a hdf file which has more than one
  146. matching data set.
  147. """
  148. # modules:
  149. import os
  150. # get logger:
  151. logger = MyLogger('mdf')
  152. # check ...
  153. if not os.path.exists(fname) :
  154. logger.error( 'file not found : %s' % fname )
  155. raise IOError
  156. #endif
  157. # different modules:
  158. modname = GetModuleName( fname )
  159. # import :
  160. submod = __import__( 'mdf_'+modname )
  161. # apply:
  162. values = submod.get_var( fname, vname, sample=sample )
  163. # ok
  164. return values
  165. #enddef
  166. # ***
  167. def get_attr( fname, aname ) :
  168. """
  169. Read global attribute from file.
  170. """
  171. # modules:
  172. import os
  173. # get logger:
  174. logger = MyLogger('mdf')
  175. # check ...
  176. if not os.path.exists(fname) :
  177. logger.error( 'file not found : %s' % fname )
  178. raise IOError
  179. #endif
  180. # different modules:
  181. modname = GetModuleName( fname )
  182. # import :
  183. submod = __import__( 'mdf_'+modname )
  184. # apply:
  185. values = submod.get_attr( fname, aname )
  186. # ok
  187. return values
  188. #enddef
  189. # ***
  190. def get_var_attr( fname, vname, aname ) :
  191. """
  192. Read variable attribute from file.
  193. """
  194. # modules:
  195. import os
  196. # get logger:
  197. logger = MyLogger('mdf')
  198. # check ...
  199. if not os.path.exists(fname) :
  200. logger.error( 'file not found : %s' % fname )
  201. raise IOError
  202. #endif
  203. # different modules:
  204. modname = GetModuleName( fname )
  205. # import :
  206. submod = __import__( 'mdf_'+modname )
  207. # apply:
  208. values = submod.get_var_attr( fname, vname, aname )
  209. # ok
  210. return values
  211. #enddef