mdf_pyhdf.py 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  1. #
  2. # quick access to hdf files
  3. #
  4. """
  5. Quick access to data in HDF file.
  6. """
  7. # ***
  8. def const_name( i ) :
  9. """
  10. Return names for pyhdf constants.
  11. """
  12. # external
  13. import pyhdf.SD
  14. # set name corresponding to number:
  15. if i == pyhdf.SD.SDC.CHAR : name = 'char'
  16. elif i == pyhdf.SD.SDC.INT32 : name = 'int32'
  17. elif i == pyhdf.SD.SDC.FLOAT32 : name = 'float32'
  18. else : name = str(i)
  19. # ok
  20. return name
  21. #enddef
  22. # ***
  23. def show( fname ) :
  24. """
  25. List content of hdf file.
  26. """
  27. # external
  28. import os
  29. import pyhdf.SD
  30. # header:
  31. print '%s {' % os.path.basename(fname)
  32. # open:
  33. hdid = pyhdf.SD.SD( fname, pyhdf.SD.SDC.READ )
  34. # number of data sets and attributes:
  35. ndset,nattr = hdid.info()
  36. # display ...
  37. print 'variables:'
  38. # loop over data sets:
  39. for idset in range(ndset) :
  40. # select variable:
  41. varid = hdid.select(idset)
  42. # variable info:
  43. vname,irank,ishape,itype,inatt = varid.info()
  44. # extract dimensions:
  45. dimnames = ''
  46. dimlens = ''
  47. for qi in range(irank) :
  48. # current dimension id:
  49. dimid = varid.dim(qi)
  50. # extract:
  51. dimname,dimlen,dimscale,dimtype = dimid.info()
  52. # dimline from info might be unlimitted,
  53. # try what the lenght() function gives (sometimes an error ..)
  54. try :
  55. dimlength = dimid.length()
  56. dimlen = dimlength
  57. except :
  58. pass
  59. #endtry
  60. # extend line:
  61. if len(dimnames) > 0 : dimnames = dimnames+', '
  62. dimnames = dimnames+dimname
  63. # extend line:
  64. if len(dimlens) > 0 : dimlens = dimlens+','
  65. dimlens = dimlens+str(dimlen)
  66. #endfor
  67. # header : variablename( dimensions )
  68. print ' %s %s( %s ) : // (%s)' % (const_name(itype),vname,dimnames,dimlens)
  69. # attributes:
  70. attr = varid.attributes()
  71. for key in attr.keys() :
  72. print ' ', key, ' = ', attr.get(key), ' ;'
  73. #endfor
  74. #endfor
  75. # Get global attribute dictionnary
  76. attr = hdid.attributes()
  77. # display ...
  78. print ''
  79. print '// global attributes:'
  80. for key in attr.keys() :
  81. print ' ', key, ' = ', attr.get(key), ' ;'
  82. #endfor
  83. # close:
  84. hdid.end()
  85. # end:
  86. print '}'
  87. # ok
  88. return
  89. #enddef
  90. # ***
  91. def get_varnames( fname ) :
  92. """
  93. Return variable names found in hdf file.
  94. """
  95. # external
  96. import pyhdf.SD
  97. # empty result:
  98. varnames = []
  99. # open:
  100. hdid = pyhdf.SD.SD( fname, pyhdf.SD.SDC.READ )
  101. # number of data sets and attributes:
  102. ndset,nattr = hdid.info()
  103. # loop over data sets:
  104. for idset in range(ndset) :
  105. # select variable:
  106. varid = hdid.select(idset)
  107. # variable info:
  108. vname,irank,ishape,itype,inatt = varid.info()
  109. # add:
  110. varnames.append(vname)
  111. #endfor
  112. # ok
  113. return varnames
  114. #enddef
  115. # ***
  116. def get_var( fname, vname, sample=None ) :
  117. """
  118. Read data set 'vname' from the specified hdf file.
  119. If multiple data sets with this name exists the data is stacked.
  120. """
  121. # external
  122. import pyhdf.SD
  123. import numpy
  124. import warnings
  125. # trap ...
  126. with warnings.catch_warnings(DeprecationWarning) :
  127. warnings.simplefilter("ignore")
  128. # open:
  129. hdid = pyhdf.SD.SD( fname, pyhdf.SD.SDC.READ )
  130. # number of data sets and attributes:
  131. ndset,nattr = hdid.info()
  132. # current match:
  133. isample = 0
  134. # init result:
  135. data = None
  136. # loop over data sets:
  137. for idset in range(ndset) :
  138. # select variable:
  139. varid = hdid.select(idset)
  140. # variable info:
  141. dname,drank,dshape,dtype,dnatt = varid.info()
  142. # only target variable ...
  143. if dname != vname : continue
  144. # extract data:
  145. if dtype == pyhdf.SD.SDC.CHAR :
  146. field = get_char( varid, ishape )
  147. else :
  148. field = varid.get()
  149. #endif
  150. # increase counter:
  151. isample = isample + 1
  152. # specific sample required ?
  153. if sample != None :
  154. # first or the requested one ?
  155. if (isample == 1) or (isample == sample) :
  156. # copy result:
  157. data = field
  158. # leave:
  159. break
  160. #endif
  161. else :
  162. # copy or stack:
  163. if isample == 1 :
  164. # copy:
  165. data = field
  166. else :
  167. # reshape target data if necessary:
  168. if isample == 2 : data = data.reshape( (1,)+data.shape )
  169. # reshape new field:
  170. field = field.reshape( (1,)+field.shape )
  171. # stack along first dimension:
  172. data = numpy.vstack( (data,field) )
  173. #endif
  174. #endif
  175. #endfor
  176. # close:
  177. hdid.end()
  178. #endwith
  179. # check ...
  180. if data == None :
  181. print 'ERROR - variable(s) "%s" not found' % vname
  182. print 'ERROR - in file : ', fname
  183. raise Exception
  184. #endif
  185. if (sample != None) and (isample > 1) :
  186. if sample > isample :
  187. print 'ERROR - sample %i of variable "%s" not found' % (sample,vname)
  188. print 'ERROR - number of samples found : %i' % isample
  189. raise Exception
  190. #endif
  191. #endif
  192. # ok
  193. return data
  194. #enddef
  195. # ***
  196. def get_char( varid, shp ) :
  197. # external:
  198. import numpy
  199. # print for single string (1D) or table (2D):
  200. if len(shp) == 1:
  201. # can only get single value without errors ...
  202. s = ''
  203. for i in range(shp[0]):
  204. c = varid.get( start=(i), count=(1) )
  205. s = s+c[0]
  206. #endfor
  207. # store:
  208. values = s.strip()
  209. elif len(shp) == 2:
  210. # init output:
  211. values = []
  212. # loop over strings:
  213. for j in range(shp[0]):
  214. # can only get single value without errors ...
  215. s = ''
  216. for i in range(shp[1]):
  217. c = varid.get( start=(j,i), count=(1,1) )
  218. s = s+c[0][0]
  219. #endfor
  220. # store:
  221. values.append(s.strip())
  222. #endfor
  223. elif len(shp) == 3:
  224. # init output:
  225. values = numpy.zeros( (shp[0:2]), 'S%i' % shp[2] )
  226. # loop over strings:
  227. for k in range(shp[0]):
  228. for j in range(shp[1]):
  229. # can only get single value without errors ...
  230. s = ''
  231. for i in range(shp[2]):
  232. c = varid.get( start=(k,j,i), count=(1,1,1) )
  233. s = s+c[0][0][0]
  234. #endfor
  235. # store:
  236. values[k,j] = s
  237. #endfor
  238. #endfor
  239. elif len(shp) == 4:
  240. # init output:
  241. values = numpy.zeros( (shp[0:3]), 'S%i' % shp[3] )
  242. # loop over strings:
  243. for l in range(shp[0]):
  244. for k in range(shp[1]):
  245. for j in range(shp[2]):
  246. # can only get single value without errors ...
  247. s = ''
  248. for i in range(shp[3]):
  249. c = varid.get( start=(l,k,j,i), count=(1,1,1,1) )
  250. s = s+c[0][0][0][0]
  251. #endfor
  252. # store:
  253. values[l,k,j] = s
  254. #endfor
  255. #endfor
  256. #endfor
  257. else:
  258. # warning ..
  259. print " sorry, not implemented for shape : ", shp
  260. #endif
  261. # ok
  262. return values
  263. #enddef
  264. # ***
  265. def get_attr( fname, aname ) :
  266. """
  267. Read global attribute 'aname' from the specified hdf file.
  268. """
  269. # external
  270. import pyhdf.SD
  271. # open:
  272. hdid = pyhdf.SD.SD( fname, pyhdf.SD.SDC.READ )
  273. # extract:
  274. attr = hdid.attributes()
  275. data = attr.get(aname)
  276. # close:
  277. hdid.end()
  278. # ok
  279. return data
  280. #enddef
  281. # ***
  282. def get_var_attr( fname, vname, aname ) :
  283. """
  284. Read global attribute 'aname' from variable 'vname' from the specified hdf file.
  285. """
  286. # external
  287. import pyhdf.SD
  288. # open:
  289. hdid = pyhdf.SD.SD( fname, pyhdf.SD.SDC.READ )
  290. # number of data sets and attributes:
  291. ndset,nattr = hdid.info()
  292. # current match:
  293. imatch = 0
  294. # loop over data sets:
  295. for idset in range(ndset) :
  296. # select variable:
  297. varid = hdid.select(idset)
  298. # variable info:
  299. dname,drank,dshape,dtype,dnatt = varid.info()
  300. # only target variable ...
  301. if dname != vname : continue
  302. # atrributes:
  303. attr = varid.attributes()
  304. # extract:
  305. values = attr.get(aname)
  306. # same as previous ?
  307. if imatch >= 1 :
  308. if values == values_prev : continue
  309. #endif
  310. # store for comparision:
  311. values_prev = values
  312. # increase counter:
  313. imatch = imatch + 1
  314. # copy or add to data
  315. if imatch == 1 :
  316. # copy:
  317. data = values
  318. elif imatch == 2 :
  319. # combine in a list:
  320. data = [data,values]
  321. else :
  322. # add to list:
  323. data.append( values )
  324. #endif
  325. #endfor
  326. # check ...
  327. if imatch == 0 :
  328. print 'ERROR - variable not found : ', vname
  329. print 'ERROR - in file : ', fname
  330. raise IOError
  331. #endif
  332. # close:
  333. hdid.end()
  334. # ok
  335. return data
  336. #enddef