file_hdf_base.F90 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641
  1. module file_hdf_base
  2. use GO, only : gol, goPr, goErr
  3. implicit none
  4. ! --- in/out --------------------------
  5. private
  6. public :: wpi
  7. public :: wp_int8, wp_int16, wp_int32, wp_int64
  8. public :: wp_float32, wp_float64
  9. public :: MAX_DATA_RANK
  10. public :: SD_UNLIMITED
  11. public :: THdfFile
  12. public :: TSds
  13. public :: TSdsDim
  14. public :: Init, Done
  15. public :: Defined
  16. public :: Select
  17. public :: GetInfo, CheckInfo
  18. public :: Compress
  19. public :: SetName
  20. public :: FindAttribute
  21. public :: GetAttributeInfo, CheckAttributeInfo
  22. public :: FindDataSet
  23. ! --- const ----------------------------
  24. character(len=*), parameter :: mname = 'file_hdf_base'
  25. ! ** hdf constants
  26. include "hdf.f90"
  27. ! ** working precision of hdf library
  28. integer, parameter :: wpi = 4
  29. ! ** working precisions of data
  30. integer, parameter :: wp_int8 = 1
  31. integer, parameter :: wp_int16 = 2
  32. integer, parameter :: wp_int32 = 4
  33. integer, parameter :: wp_int64 = 8
  34. integer, parameter :: wp_float32 = 4
  35. integer, parameter :: wp_float64 = 8
  36. ! ** maximum array ranks
  37. integer, parameter :: MAX_DATA_RANK = 32
  38. ! --- types ---------------------------
  39. ! ~~ scientific data set:
  40. type TSds
  41. ! internal id:
  42. integer(wpi) :: id
  43. ! hdf file name:
  44. character(len=256) :: hdfname
  45. ! name:
  46. character(len=64) :: name
  47. ! data specification:
  48. integer :: dfnt
  49. character(len=3) :: typ
  50. integer :: knd
  51. integer :: rnk
  52. integer :: shp(7)
  53. end type TSds
  54. ! ~~ dimension
  55. type TSdsDim
  56. ! internal id:
  57. integer(wpi) :: id
  58. end type TSdsDim
  59. ! ~~ hdf file
  60. type THdfFile
  61. ! internal id:
  62. integer(wpi) :: id
  63. ! file name
  64. character(len=256) :: fname
  65. end type THdfFile
  66. ! --- interfaces ------------------------
  67. interface Init
  68. module procedure sds_Init
  69. module procedure sds_Init_select
  70. module procedure sds_Init_create
  71. module procedure dim_Init
  72. module procedure hdf_Init
  73. end interface
  74. interface Done
  75. module procedure sds_Done
  76. module procedure dim_Done
  77. module procedure hdf_Done
  78. end interface
  79. interface Defined
  80. module procedure sds_Defined
  81. end interface
  82. interface Select
  83. module procedure sds_Select_index
  84. module procedure dim_Select
  85. end interface
  86. interface GetInfo
  87. module procedure sds_GetInfo
  88. module procedure hdf_GetInfo
  89. end interface
  90. interface CheckInfo
  91. module procedure sds_CheckInfo
  92. end interface
  93. interface Compress
  94. module procedure sds_Compress
  95. end interface
  96. interface SetName
  97. module procedure dim_SetName
  98. end interface
  99. interface FindAttribute
  100. module procedure obj_FindAttribute
  101. module procedure sds_FindAttribute
  102. module procedure hdf_FindAttribute
  103. end interface
  104. interface GetAttributeInfo
  105. module procedure obj_GetAttributeInfo
  106. module procedure sds_GetAttributeInfo
  107. module procedure hdf_GetAttributeInfo
  108. end interface
  109. interface CheckAttributeInfo
  110. module procedure obj_CheckAttributeInfo
  111. module procedure sds_CheckAttributeInfo
  112. module procedure hdf_CheckAttributeInfo
  113. end interface
  114. interface FindDataSet
  115. module procedure hdf_FindDataSet
  116. end interface
  117. contains
  118. ! ############################################################
  119. ! ###
  120. ! ### tools
  121. ! ###
  122. ! ############################################################
  123. !
  124. ! compare character strings case independent
  125. !
  126. logical function leq( s1, s2 )
  127. ! --- in/out ------------------------
  128. character(len=*), intent(in) :: s1, s2
  129. ! --- local -------------------------
  130. character(len=2) :: cc
  131. integer :: k
  132. ! --- begin -------------------------
  133. if ( len_trim(s1) /= len_trim(s2) ) then
  134. leq = .false.
  135. return
  136. end if
  137. do k = 1, len_trim(s1)
  138. select case ( s1(k:k) )
  139. case ( 'A', 'a' ); cc = 'Aa'
  140. case ( 'B', 'b' ); cc = 'Bb'
  141. case ( 'C', 'c' ); cc = 'Cc'
  142. case ( 'D', 'd' ); cc = 'Dd'
  143. case ( 'E', 'e' ); cc = 'Ee'
  144. case ( 'F', 'f' ); cc = 'Ff'
  145. case ( 'G', 'g' ); cc = 'Gg'
  146. case ( 'H', 'h' ); cc = 'Hh'
  147. case ( 'I', 'i' ); cc = 'Ii'
  148. case ( 'J', 'j' ); cc = 'Jj'
  149. case ( 'K', 'k' ); cc = 'Kk'
  150. case ( 'L', 'l' ); cc = 'Ll'
  151. case ( 'M', 'm' ); cc = 'Mm'
  152. case ( 'N', 'n' ); cc = 'Nn'
  153. case ( 'O', 'o' ); cc = 'Oo'
  154. case ( 'P', 'p' ); cc = 'Pp'
  155. case ( 'Q', 'q' ); cc = 'Qq'
  156. case ( 'R', 'r' ); cc = 'Rr'
  157. case ( 'S', 's' ); cc = 'Ss'
  158. case ( 'T', 't' ); cc = 'Tt'
  159. case ( 'U', 'u' ); cc = 'Uu'
  160. case ( 'V', 'v' ); cc = 'Vv'
  161. case ( 'W', 'w' ); cc = 'Ww'
  162. case ( 'X', 'x' ); cc = 'Xx'
  163. case ( 'Y', 'y' ); cc = 'Yy'
  164. case ( 'Z', 'z' ); cc = 'Zz'
  165. case default; cc = '**'
  166. end select
  167. if ( cc == '**' ) then
  168. if ( s2(k:k) /= s1(k:k) ) then
  169. leq = .false.
  170. return
  171. end if
  172. else
  173. if ( s2(k:k) /= cc(1:1) .and. s2(k:k) /= cc(2:2) ) then
  174. leq = .false.
  175. return
  176. end if
  177. end if
  178. end do
  179. leq = .true.
  180. end function leq
  181. ! ############################################################
  182. ! ###
  183. ! ### objects
  184. ! ###
  185. ! ############################################################
  186. subroutine obj_FindAttribute( obj_id, name, attr_index, status )
  187. ! --- in/out -------------------------
  188. integer(wpi), intent(in) :: obj_id
  189. character(len=*), intent(in) :: name
  190. integer, intent(out) :: attr_index
  191. integer, intent(inout) :: status
  192. ! --- const -------------------------------
  193. character(len=*), parameter :: rname = mname//'/obj_FindAttribute'
  194. ! --- local -------------------------------
  195. integer :: istat
  196. logical :: verbose
  197. ! --- external ----------------------------
  198. integer(wpi), external :: sfFAttr
  199. ! --- begin -------------------------------
  200. ! write error messages ?
  201. verbose = status == 0
  202. ! extract id of attribute:
  203. attr_index = sfFAttr( obj_id, name )
  204. if ( attr_index == FAIL ) then
  205. if ( verbose ) then
  206. write (gol,'("finding attribute `",a,"`")') trim(name); call goErr
  207. write (gol,'("in ",a)') rname; call goErr
  208. end if
  209. status=-1; return
  210. end if
  211. ! ok
  212. status = 0
  213. end subroutine obj_FindAttribute
  214. ! ***
  215. !
  216. ! argument attr_index : 0,..,n-1
  217. !
  218. subroutine obj_GetAttributeInfo( obj_id, attr_index, status, &
  219. name, data_type, data_type_descr, n_values )
  220. ! --- in/out -------------------------
  221. integer(wpi), intent(in) :: obj_id
  222. integer, intent(in) :: attr_index
  223. integer, intent(out) :: status
  224. character(len=*), intent(out), optional :: name
  225. integer, intent(out), optional :: data_type
  226. character(len=1), intent(out), optional :: data_type_descr
  227. integer, intent(out), optional :: n_values
  228. ! --- const -------------------------------
  229. character(len=*), parameter :: rname = mname//'/obj_GetAttributeInfo'
  230. ! --- local -------------------------------
  231. character(len=64) :: attr_name
  232. integer :: attr_data_type
  233. integer :: attr_n_values
  234. ! --- external ----------------------------
  235. integer(wpi), external :: sfGAInfo
  236. ! --- begin -------------------------------
  237. ! extract info:
  238. status = sfGAInfo( obj_id, attr_index, attr_name, attr_data_type, attr_n_values )
  239. if ( status /= SUCCEED ) then
  240. write (gol,'("getting attribute info")') ; call goErr
  241. write (gol,'("in ",a)') rname; call goErr; status=1; return
  242. end if
  243. ! return values:
  244. if ( present(name) ) name = attr_name
  245. if ( present(data_type) ) data_type = attr_data_type
  246. if ( present(data_type_descr) ) then
  247. select case ( attr_data_type )
  248. case ( DFNT_INT8, DFNT_INT16, DFNT_INT32, DFNT_INT64 )
  249. data_type_descr = 'i'
  250. case ( DFNT_FLOAT32, DFNT_FLOAT64 )
  251. data_type_descr = 'r'
  252. case ( DFNT_CHAR )
  253. data_type_descr = 's'
  254. case default
  255. write (gol,'("do not know the data type description")'); call goErr
  256. write (gol,'(" attribute name : ",a)') trim(attr_name); call goErr
  257. write (gol,'(" attribute data type : ",i6)') attr_data_type; call goErr
  258. write (gol,'("in ",a)') rname; call goErr; status=1; return
  259. end select
  260. end if
  261. if ( present(n_values) ) n_values = attr_n_values
  262. ! ok
  263. status = 0
  264. end subroutine obj_GetAttributeInfo
  265. ! ***
  266. !
  267. ! argument attr_index : 0,..,n-1
  268. !
  269. subroutine obj_CheckAttributeInfo( obj_id, attr_index, status, &
  270. name, data_type, n_values )
  271. ! --- in/out -------------------------
  272. integer(wpi), intent(in) :: obj_id
  273. integer, intent(in) :: attr_index
  274. integer, intent(inout) :: status
  275. character(len=*), intent(in), optional :: name
  276. integer, intent(in), optional :: data_type
  277. integer, intent(in), optional :: n_values
  278. ! --- const -------------------------------
  279. character(len=*), parameter :: rname = mname//'/obj_CheckAttributeInfo'
  280. ! --- local -------------------------------
  281. logical :: verbose
  282. character(len=64) :: attr_name
  283. integer :: attr_data_type
  284. integer :: attr_n_values
  285. ! --- begin -------------------------------
  286. ! write error messages ?
  287. verbose = status == 0
  288. ! check name
  289. if ( present(name) ) then
  290. call GetAttributeInfo( obj_id, attr_index, status, name=attr_name )
  291. if (status/=0) then; write (gol,'("in ",a)') rname; call goErr; status=1; return; end if
  292. if ( .not. leq(attr_name,name) ) then
  293. if ( verbose ) then
  294. write (gol,'("found different attribute name :")'); call goErr
  295. write (gol,'(" requested : ",a)') trim(name); call goErr
  296. write (gol,'(" found : ",a)') trim(attr_name); call goErr
  297. end if
  298. status=-1; return
  299. end if
  300. end if
  301. ! check data type
  302. if ( present(data_type) ) then
  303. call GetAttributeInfo( obj_id, attr_index, status, &
  304. data_type=attr_data_type, name=attr_name )
  305. if (status/=0) then; write (gol,'("in ",a)') rname; call goErr; status=1; return; end if
  306. if ( attr_data_type /= data_type ) then
  307. if ( verbose ) then
  308. write (gol,'("found different data type :")'); call goErr
  309. write (gol,'(" requested : ",i6)') data_type; call goErr
  310. write (gol,'(" found : ",i6)') attr_data_type; call goErr
  311. write (gol,'(" attribute :")') trim(attr_name); call goErr
  312. end if
  313. status=-1; return
  314. end if
  315. end if
  316. ! check number of values:
  317. if ( present(n_values) ) then
  318. call GetAttributeInfo( obj_id, attr_index, status, &
  319. n_values=attr_n_values, name=attr_name )
  320. if (status/=0) then; write (gol,'("in ",a)') rname; call goErr; status=1; return; end if
  321. if ( attr_n_values /= n_values ) then
  322. if ( verbose ) then
  323. write (gol,'("found different number of values :")'); call goErr
  324. write (gol,'(" requested : ")') n_values; call goErr
  325. write (gol,'(" found : ")') attr_n_values; call goErr
  326. write (gol,'(" attribute : ")') trim(attr_name); call goErr
  327. end if
  328. status=-1; return
  329. end if
  330. end if
  331. ! ok
  332. status = 0
  333. end subroutine obj_CheckAttributeInfo
  334. ! ############################################################
  335. ! ###
  336. ! ### scientific data sets
  337. ! ###
  338. ! ############################################################
  339. ! ================================================================
  340. ! init, done
  341. ! ================================================================
  342. subroutine sds_Init( sds, status )
  343. ! --- in/out -----------------------------
  344. type(Tsds), intent(out) :: sds
  345. integer, intent(out) :: status
  346. ! --- const -------------------------------
  347. character(len=*), parameter :: rname = mname//'/sds_Init'
  348. ! --- begin ------------------------------
  349. ! dummy ...
  350. sds%hdfname = 'unknown-hdf-file'
  351. sds%typ = 'xxx'
  352. ! no id yet
  353. sds%id = -1
  354. ! ok
  355. status = 0
  356. end subroutine sds_Init
  357. ! ***
  358. subroutine sds_Done( sds, status )
  359. ! --- in/out -----------------------------
  360. type(Tsds), intent(inout) :: sds
  361. integer, intent(out) :: status
  362. ! --- const -------------------------------
  363. character(len=*), parameter :: rname = mname//'/sds_Done'
  364. ! --- external ----------------------------
  365. integer(wpi), external :: sfEndAcc
  366. ! --- begin ------------------------------
  367. if ( sds%id /= -1 ) then
  368. status = sfEndAcc( sds%id )
  369. if ( status == FAIL ) then
  370. write (gol,'("ending scientific data set ",i6)') sds%id; call goErr
  371. write (gol,'(" hdf file name : ",a)') trim(sds%hdfname); call goErr
  372. write (gol,'("in ",a)') rname; call goErr; status=1; return
  373. end if
  374. end if
  375. ! ok
  376. status = 0
  377. end subroutine sds_Done
  378. ! ***
  379. logical function sds_Defined( sds )
  380. ! --- in/out ------------------------------
  381. type(TSds), intent(in) :: sds
  382. ! --- begin ------------------------------
  383. sds_Defined = sds%id /= -1
  384. end function sds_Defined
  385. ! ================================================================
  386. ! === select sds
  387. ! ================================================================
  388. subroutine sds_Select_index( sds, hdf, ind, status )
  389. ! --- in/out -------------------------
  390. type(TSds), intent(out) :: sds
  391. type(THdfFile), intent(in) :: hdf
  392. integer, intent(in) :: ind
  393. integer, intent(out) :: status
  394. ! --- const -------------------------------
  395. character(len=*), parameter :: rname = mname//'/sds_Select_index'
  396. ! --- external ------------------------
  397. integer(wpi), external :: sfSelect
  398. ! --- begin ---------------------------
  399. sds%id = sfSelect( hdf%id, ind ) ! <-- 0,..,n-1
  400. if ( sds%id == FAIL ) then
  401. write (gol,'("unable to locate data set with index ",i6)') ind; call goErr
  402. write (gol,'(" hdf file name : ",a)') trim(hdf%fname); call goErr
  403. write (gol,'("in ",a)') rname; call goErr; status=1; return
  404. end if
  405. ! ok
  406. status = 0
  407. end subroutine sds_Select_index
  408. ! ***
  409. subroutine sds_Init_select( sds, hdf, name, status )
  410. ! --- in/out -------------------------
  411. type(Tsds), intent(out) :: sds
  412. type(THdfFile), intent(inout) :: hdf
  413. character(len=*), intent(in) :: name
  414. integer, intent(inout) :: status
  415. ! --- const -------------------------------
  416. character(len=*), parameter :: rname = mname//'/sds_Init_select'
  417. ! --- local -------------------------------
  418. integer :: sds_index
  419. ! --- external ------------------------
  420. integer(wpi), external :: sfN2Index
  421. ! --- begin -------------------------------
  422. ! default init
  423. call Init( sds, status )
  424. if (status/=0) then; write (gol,'("in ",a)') rname; call goErr; status=1; return; end if
  425. ! fill hdf and sds names:
  426. sds%hdfname = hdf%fname
  427. sds%name = name
  428. ! search for the record
  429. sds_index = sfN2Index( hdf%id, name )
  430. if ( sds_index == FAIL ) then
  431. write (gol,'("converting sds name to index :")'); call goErr
  432. write (gol,'(" sds name : ",a)') trim(sds%name); call goErr
  433. write (gol,'(" hdf name : ",a)') trim(sds%hdfname); call goErr
  434. write (gol,'("in ",a)') rname; call goErr
  435. status=1; return
  436. end if
  437. ! select sds id:
  438. call Select( sds, hdf, sds_index, status )
  439. if (status/=0) then; write (gol,'("in ",a)') rname; call goErr; status=1; return; end if
  440. ! ok
  441. status = 0
  442. end subroutine sds_Init_select
  443. ! =============================================================
  444. ! === sds info
  445. ! =============================================================
  446. subroutine sds_GetInfo( sds, status, &
  447. name, data_rank, data_dims, data_type, num_attrs )
  448. ! --- in/out -------------------------
  449. type(TSds), intent(in) :: sds
  450. integer, intent(out) :: status
  451. character(len=*), intent(out), optional :: name
  452. integer, intent(out), optional :: data_rank
  453. integer, intent(out), optional :: data_type
  454. integer, intent(out), optional :: data_dims(:)
  455. integer, intent(out), optional :: num_attrs
  456. ! --- local -------------------------------
  457. integer :: istat
  458. character(len=64) :: sds_name
  459. integer :: sds_data_rank, sds_data_type
  460. integer :: sds_data_dims(MAX_DATA_RANK)
  461. integer :: sds_num_attrs
  462. ! --- const -------------------------------
  463. character(len=*), parameter :: rname = mname//'/sds_GetInfo'
  464. ! --- external ----------------------------
  465. integer(wpi), external :: sfGInfo
  466. ! --- begin -------------------------------
  467. ! extract info about record:
  468. istat = sfGInfo( sds%id, sds_name, sds_data_rank, sds_data_dims, sds_data_type, sds_num_attrs )
  469. if ( istat /= SUCCEED ) then
  470. write (gol,'("error getting info")'); call goErr
  471. write (gol,'("in ",a)') rname; call goErr; status=1; return
  472. end if
  473. ! return values:
  474. if ( present(name) ) name = sds_name
  475. if ( present(data_rank) ) data_rank = sds_data_rank
  476. if ( present(data_type) ) data_type = sds_data_type
  477. if ( present(data_dims) ) data_dims = sds_data_dims(1:size(data_dims))
  478. if ( present(num_attrs) ) num_attrs = sds_num_attrs
  479. ! ok
  480. status = 0
  481. end subroutine sds_GetInfo
  482. ! ***
  483. subroutine sds_CheckInfo( sds, status, &
  484. name, data_rank, data_dims, data_type, num_attrs )
  485. ! --- in/out -------------------------
  486. type(TSds), intent(in) :: sds
  487. integer, intent(inout) :: status
  488. character(len=*), intent(in), optional :: name
  489. integer, intent(in), optional :: data_rank
  490. integer, intent(in), optional :: data_type
  491. integer, intent(in), optional :: data_dims(:)
  492. integer, intent(in), optional :: num_attrs
  493. ! --- const -------------------------------
  494. character(len=*), parameter :: rname = mname//'/sds_CheckInfo'
  495. ! --- local -------------------------------
  496. logical :: verbose
  497. character(len=64) :: sds_name
  498. integer :: sds_data_rank, sds_data_type
  499. integer, allocatable :: sds_data_dims(:)
  500. integer :: sds_num_attrs
  501. ! --- begin -------------------------------
  502. ! write error messages ?
  503. verbose = status == 0
  504. ! check name
  505. if ( present(name) ) then
  506. call GetInfo( sds, status, name=sds_name )
  507. if (status/=0) then; write (gol,'("in ",a)') rname; call goErr; status=1; return; end if
  508. if ( .not. leq(sds_name,name) ) then
  509. if ( verbose ) then
  510. write (gol,'("found different name :")'); call goErr
  511. write (gol,'(" requested : ",a)') trim(name); call goErr
  512. write (gol,'(" found : ",a)') trim(sds_name); call goErr
  513. write (gol,'("in ",a)') rname; call goErr
  514. end if
  515. status=-1; return
  516. end if
  517. end if
  518. ! check data rank
  519. if ( present(data_rank) ) then
  520. call GetInfo( sds, status, data_rank=sds_data_rank )
  521. if (status/=0) then; write (gol,'("in ",a)') rname; call goErr; status=1; return; end if
  522. if ( sds_data_rank /= data_rank ) then
  523. if ( verbose ) then
  524. write (gol,'("found different data rank :")'); call goErr
  525. write (gol,'(" requested : ",i6)') data_rank; call goErr
  526. write (gol,'(" found : ",i6)') sds_data_rank; call goErr
  527. write (gol,'("in ",a)') rname; call goErr
  528. end if
  529. status=-1; return
  530. end if
  531. end if
  532. ! check data type
  533. if ( present(data_type) ) then
  534. call GetInfo( sds, status, data_type=sds_data_type )
  535. if (status/=0) then; write (gol,'("in ",a)') rname; call goErr; status=1; return; end if
  536. if ( sds_data_type /= data_type ) then
  537. if ( verbose ) then
  538. write (gol,'("found different data type :")'); call goErr
  539. write (gol,'(" requested : ",i6)') data_type; call goErr
  540. write (gol,'(" found : ",i6)') sds_data_type; call goErr
  541. write (gol,'("in ",a)') rname; call goErr
  542. end if
  543. status=-1; return
  544. end if
  545. end if
  546. ! check data dimensions
  547. if ( present(data_dims) ) then
  548. allocate( sds_data_dims(size(data_dims)) )
  549. call GetInfo( sds, status, data_dims=sds_data_dims )
  550. if (status/=0) then; write (gol,'("in ",a)') rname; call goErr; status=1; return; end if
  551. if ( any( sds_data_dims /= data_dims ) ) then
  552. if ( verbose ) then
  553. write (gol,'("different data dims :")'); call goErr
  554. write (gol,'(" requested : ",7i4)') data_dims; call goErr
  555. write (gol,'(" found : ",7i4)') sds_data_dims; call goErr
  556. write (gol,'("in ",a)') rname; call goErr
  557. end if
  558. status=-1; return
  559. end if
  560. deallocate( sds_data_dims )
  561. end if
  562. ! check number of attributes:
  563. if ( present(num_attrs) ) then
  564. call GetInfo( sds, status, num_attrs=sds_num_attrs )
  565. if (status/=0) then; write (gol,'("in ",a)') rname; call goErr; status=1; return; end if
  566. if ( sds_num_attrs /= num_attrs ) then
  567. if ( verbose ) then
  568. write (gol,'("different data num_attrs :")'); call goErr
  569. write (gol,'(" requested : ")') num_attrs; call goErr
  570. write (gol,'(" found : ")') sds_num_attrs; call goErr
  571. write (gol,'("in ",a)') rname; call goErr
  572. end if
  573. status=-1; return
  574. end if
  575. end if
  576. ! ok
  577. status = 0
  578. end subroutine sds_CheckInfo
  579. ! =============================================================
  580. ! === create sds data
  581. ! =============================================================
  582. !
  583. ! 'int8' 'integer(1)' 'int'|'integer', bits=8 |knd=1
  584. ! 'int16' 'integer(2)' 'int'|'integer', bits=16|knd=2
  585. ! 'int32' 'integer(4)' 'int'|'integer', bits=32|knd=4
  586. ! 'int64' 'integer(8)' 'int'|'integer', bits=64|knd=8
  587. !
  588. ! 'float32' 'real(4)' 'float'|'real', bits=32|knd=4
  589. ! 'float64' 'real(8)' 'float'|'real', bits=64|knd=8
  590. !
  591. ! 'char'
  592. !
  593. subroutine sds_Init_create( sds, hdf, name, shp, typekey, status, &
  594. knd, bits )
  595. ! --- in/out -------------------------
  596. type(TSds), intent(out) :: sds
  597. type(THdfFile), intent(inout) :: hdf
  598. character(len=*), intent(in) :: name
  599. integer, intent(in) :: shp(:)
  600. character(len=*), intent(in) :: typekey
  601. integer, intent(out) :: status
  602. integer, intent(in), optional :: knd
  603. integer, intent(in), optional :: bits
  604. ! --- const -------------------------------
  605. character(len=*), parameter :: rname = mname//'/sds_Init_create'
  606. ! --- local -------------------------------
  607. integer :: dfnt
  608. character(len=3) :: dtyp
  609. integer :: dbits, dknd
  610. ! --- external ----------------------------
  611. integer(wpi), external :: sfCreate
  612. ! --- begin -------------------------------
  613. ! default initialisation:
  614. call Init( sds, status )
  615. if (status/=0) then; write (gol,'("in ",a)') rname; call goErr; status=1; return; end if
  616. ! fill hdf file name
  617. sds%hdfname = hdf%fname
  618. ! fill hdf variable name
  619. sds%name = name
  620. ! determine data type:
  621. select case ( typekey )
  622. case ( 'int8', 'integer(1)' )
  623. dfnt = DFNT_INT8
  624. dtyp = 'int'
  625. dknd = 1
  626. case ( 'int16', 'integer(2)' )
  627. dfnt = DFNT_INT16
  628. dtyp = 'int'
  629. dknd = 2
  630. case ( 'int32', 'integer(4)' )
  631. dfnt = DFNT_INT32
  632. dtyp = 'int'
  633. dknd = 4
  634. case ( 'int64', 'integer(8)' )
  635. dfnt = DFNT_INT64
  636. dtyp = 'int'
  637. dknd = 8
  638. case ( 'int', 'integer' )
  639. if ( present(bits) ) then
  640. dbits = bits
  641. else if ( present(knd) ) then
  642. dbits = knd * 8
  643. else
  644. dbits = kind(1) * 8
  645. end if
  646. select case ( dbits )
  647. case ( 8 )
  648. dfnt = DFNT_INT8
  649. dknd = 1
  650. case ( 16 )
  651. dfnt = DFNT_INT16
  652. dknd = 2
  653. case ( 32 )
  654. dfnt = DFNT_INT32
  655. dknd = 4
  656. case ( 64 )
  657. dfnt = DFNT_INT64
  658. dknd = 8
  659. case default
  660. write (gol,'("integer data not implemented for dbits=",i6)') dbits; call goErr
  661. write (gol,'("in ",a)') rname; call goErr; status=1; return
  662. end select
  663. dtyp = 'int'
  664. case ( 'float32', 'real(4)' )
  665. dfnt = DFNT_FLOAT32
  666. dtyp = 'flt'
  667. dknd = 4
  668. case ( 'float64', 'real(8)' )
  669. dfnt = DFNT_FLOAT64
  670. dtyp = 'flt'
  671. dknd = 8
  672. case ( 'float', 'real' )
  673. if ( present(bits) ) then
  674. dbits = bits
  675. else if ( present(knd) ) then
  676. dbits = knd * 8
  677. else
  678. dbits = kind(1) * 8
  679. end if
  680. select case ( dbits )
  681. case ( 32 )
  682. dfnt = DFNT_FLOAT32
  683. dknd = 4
  684. case ( 64 )
  685. dfnt = DFNT_FLOAT64
  686. dknd = 8
  687. case default
  688. write (gol,'("real data not implemented for dbits=",i6)') dbits; call goErr
  689. write (gol,'("in ",a)') rname; call goErr; status=1; return
  690. end select
  691. dtyp = 'flt'
  692. case ( 'char' )
  693. dfnt = DFNT_CHAR
  694. dtyp = 'chr'
  695. dknd = 1
  696. case default
  697. write (gol,'("typekey not implemented: ",a)') trim(typekey); call goErr
  698. write (gol,'("in ",a)') rname; call goErr; status=1; return
  699. end select
  700. ! store type and kind
  701. sds%dfnt = dfnt
  702. sds%typ = dtyp
  703. sds%knd = dknd
  704. ! store rank
  705. sds%rnk = size(shp)
  706. if ( sds%rnk < 1 .or. sds%rnk > 7 ) then
  707. write (gol,'("invalid rank : ",i4)') sds%rnk; call goErr
  708. write (gol,'("in ",a)') rname; call goErr; status=1; return
  709. end if
  710. ! store shape
  711. sds%shp(1:sds%rnk) = shp
  712. ! start new record:
  713. sds%id = sfCreate( hdf%id, name, sds%dfnt, sds%rnk, sds%shp(1:sds%rnk) )
  714. if ( sds%id == FAIL ) then
  715. write (gol,'("from sfCreate :")'); call goErr
  716. write (gol,'(" name : ",a)') trim(name); call goErr
  717. write (gol,'(" hdf file : ",a)') trim(sds%hdfname); call goErr
  718. write (gol,'("in ",a)') rname; call goErr; status=1; return
  719. end if
  720. ! ok
  721. status = 0
  722. end subroutine sds_Init_create
  723. ! ================================================================
  724. ! compression
  725. ! ================================================================
  726. subroutine sds_Compress( sds, compression, status, &
  727. skip_size, deflate_level )
  728. ! --- in/out -------------------------
  729. type(Tsds), intent(inout) :: sds
  730. character(len=*), intent(in) :: compression
  731. integer, intent(out) :: status
  732. integer, intent(in), optional :: skip_size
  733. integer, intent(in), optional :: deflate_level
  734. ! --- const -------------------------------
  735. character(len=*), parameter :: rname = mname//'/sds_Compress'
  736. ! --- local -------------------------------
  737. integer :: comp_type
  738. integer :: comp_prm(1)
  739. ! --- external ---------------------------
  740. integer(wpi), external :: sfsCompress
  741. ! --- begin -------------------------------
  742. ! default compression parameters:
  743. comp_prm = (/ 0 /)
  744. ! set compression type and parameters given key:
  745. select case ( compression )
  746. case ( 'none' )
  747. comp_type = COMP_CODE_NONE
  748. case ( 'rle' ) ! run-length encoding
  749. comp_type = COMP_CODE_RLE
  750. case ( 'skphuff' ) ! skipping Huffman
  751. comp_type = COMP_CODE_SKPHUFF
  752. comp_prm = (/ 1 /)
  753. if ( present(skip_size) ) comp_prm(1) = skip_size
  754. case ( 'deflate' ) ! gzip
  755. comp_type = COMP_CODE_DEFLATE
  756. comp_prm = (/ 6 /)
  757. if ( present(deflate_level) ) comp_prm(1) = deflate_level
  758. case default
  759. write (gol,'("unknown compression type : ",a)') trim(compression); call goErr
  760. write (gol,'("in ",a)') rname; call goErr; status=1; return
  761. end select
  762. ! call HDF routine:
  763. status = sfsCompress( sds%id, comp_type, comp_prm )
  764. if ( status == FAIL ) then
  765. write (gol,'("from sfsCompress : ")'); call goErr
  766. write (gol,'(" compression : ",a )') trim(compression); call goErr
  767. write (gol,'(" compress type : ",i6)') comp_type; call goErr
  768. write (gol,'(" compress param : ",i6)') comp_prm; call goErr
  769. write (gol,'("in ",a)') rname; call goErr; status=1; return
  770. end if
  771. ! ok
  772. status = 0
  773. end subroutine sds_Compress
  774. ! =============================================================
  775. ! === sds attributes
  776. ! =============================================================
  777. subroutine sds_FindAttribute( sds, name, attr_index, status )
  778. ! --- in/out -------------------------
  779. type(TSds), intent(in) :: sds
  780. character(len=*), intent(in) :: name
  781. integer, intent(out) :: attr_index
  782. integer, intent(inout) :: status
  783. ! --- const -------------------------------
  784. character(len=*), parameter :: rname = mname//'/sds_FindAttribute'
  785. ! --- local -------------------------------
  786. logical :: verbose
  787. ! --- begin -------------------------------
  788. ! write error messages ?
  789. verbose = status == 0
  790. call FindAttribute( sds%id, name, attr_index, status )
  791. if (status<0) then
  792. ! not found ..
  793. if (verbose) then; write (gol,'("in ",a)') rname; call goErr; end if
  794. status=-1; return
  795. else if ( status == 0 ) then
  796. ! ok
  797. status=0; return
  798. else
  799. ! error
  800. write (gol,'("in ",a)') rname; call goErr; status=1; return
  801. end if
  802. end subroutine sds_FindAttribute
  803. ! ***
  804. subroutine sds_GetAttributeInfo( sds, attr_index, status, &
  805. name, data_type, data_type_descr, &
  806. n_values )
  807. ! --- in/out -------------------------
  808. type(TSds), intent(in) :: sds
  809. integer, intent(in) :: attr_index
  810. integer, intent(out) :: status
  811. character(len=*), intent(out), optional :: name
  812. integer, intent(out), optional :: data_type
  813. character(len=1), intent(out), optional :: data_type_descr
  814. integer, intent(out), optional :: n_values
  815. ! --- const -------------------------------
  816. character(len=*), parameter :: rname = mname//'/sds_GetAttributeInfo'
  817. ! --- begin -------------------------------
  818. call GetAttributeInfo( sds%id, attr_index, status, &
  819. name=name, &
  820. data_type=data_type, data_type_descr=data_type_descr, &
  821. n_values=n_values )
  822. if (status/=0) then; write (gol,'("in ",a)') rname; call goErr; status=1; return; end if
  823. ! ok
  824. status = 0
  825. end subroutine sds_GetAttributeInfo
  826. ! ***
  827. subroutine sds_CheckAttributeInfo( sds, attr_index, status, &
  828. name, data_type, n_values )
  829. ! --- in/out -------------------------
  830. type(TSds), intent(in) :: sds
  831. integer, intent(in) :: attr_index
  832. integer, intent(inout) :: status
  833. character(len=*), intent(in), optional :: name
  834. integer, intent(in), optional :: data_type
  835. integer, intent(in), optional :: n_values
  836. ! --- const -------------------------------
  837. character(len=*), parameter :: rname = mname//'/sds_CheckAttributeInfo'
  838. ! --- local -------------------------------
  839. logical :: verbose
  840. ! --- begin -------------------------------
  841. ! write error messages ?
  842. verbose = status == 0
  843. call CheckAttributeInfo( sds%id, attr_index, &
  844. name=name, data_type=data_type, n_values=n_values, &
  845. status=status )
  846. if ( status < 0 ) then
  847. ! error
  848. if (verbose) then; write (gol,'("in ",a)') rname; call goErr; end if
  849. status=-1; return
  850. else if ( status == 0 ) then
  851. ! ok
  852. status=0; return
  853. else
  854. ! error
  855. write (gol,'("in ",a)') rname; call goErr; status=1; return
  856. end if
  857. end subroutine sds_CheckAttributeInfo
  858. ! ############################################################
  859. ! ###
  860. ! ### dimensions
  861. ! ###
  862. ! ############################################################
  863. ! ================================================================
  864. ! init, done
  865. ! ================================================================
  866. subroutine dim_Init( sdim, status )
  867. ! --- in/out ------------------------------
  868. type(TSdsDim), intent(out) :: sdim
  869. integer, intent(out) :: status
  870. ! --- begin -------------------------------
  871. sdim%id = FAIL
  872. ! ok
  873. status = 0
  874. end subroutine dim_Init
  875. ! *
  876. subroutine dim_Done( sdim, status )
  877. ! --- in/out ------------------------------
  878. type(TSdsDim), intent(inout) :: sdim
  879. integer, intent(out) :: status
  880. ! --- begin -------------------------------
  881. ! nothing to be done
  882. ! ok
  883. status = 0
  884. end subroutine dim_Done
  885. ! ================================================================
  886. ! select
  887. ! ================================================================
  888. !
  889. ! argument ind : 0,..,n-1
  890. !
  891. subroutine dim_Select( sdim, sds, ind, status )
  892. ! --- in/out -------------------------
  893. type(TSdsDim), intent(out) :: sdim
  894. type(TSds), intent(in) :: sds
  895. integer, intent(in) :: ind
  896. integer, intent(out) :: status
  897. ! --- const -------------------------------
  898. character(len=*), parameter :: rname = mname//'/dim_Select'
  899. ! --- external ------------------------
  900. integer(wpi), external :: sfDimID
  901. ! --- begin ---------------------------
  902. sdim%id = sfDimID( sds%id, ind ) ! <-- 0,..,n-1
  903. if ( sdim%id == FAIL ) then
  904. write (gol,'("error selecting dimension :")'); call goErr
  905. write (gol,'(" index : ",i6)') ind; call goErr
  906. write (gol,'(" sds name : ",a)') trim(sds%name); call goErr
  907. write (gol,'(" hdf name : ",a)') trim(sds%hdfname); call goErr
  908. write (gol,'("in ",a)') rname; call goErr; status=1; return
  909. end if
  910. ! ok
  911. status = 0
  912. end subroutine dim_Select
  913. ! ================================================================
  914. ! set dimension name
  915. ! ================================================================
  916. subroutine dim_SetName( sdim, name, status )
  917. ! --- in/out -------------------------
  918. type(TSdsDim), intent(inout) :: sdim
  919. character(len=*), intent(in) :: name
  920. integer, intent(out) :: status
  921. ! --- const -------------------------------
  922. character(len=*), parameter :: rname = mname//'/dim_SetName'
  923. ! --- external ---------------------------
  924. integer(wpi), external :: sfSDmName
  925. ! --- begin ---------------------------
  926. ! set dimension name
  927. status = sfSDmName( sdim%id, name )
  928. if ( status == FAIL ) then
  929. write (gol,'("setting dimension name :")'); call goErr
  930. write (gol,'(" dim name : ",a)') name; call goErr
  931. write (gol,'("in ",a)') rname; call goErr; status=1; return
  932. end if
  933. ! ok
  934. status = 0
  935. end subroutine dim_SetName
  936. ! ############################################################
  937. ! ###
  938. ! ### hdf files
  939. ! ###
  940. ! ############################################################
  941. ! ================================================================
  942. ! init, done
  943. ! ================================================================
  944. subroutine hdf_Init( hdf, fname, key, status )
  945. ! --- in/out ------------------------------
  946. ! !ARGUMENTS:
  947. type(THdfFile), intent(out) :: hdf
  948. character(len=*), intent(in) :: fname
  949. character(len=*), intent(in) :: key
  950. integer, intent(out) :: status
  951. ! --- const -------------------------------
  952. character(len=*), parameter :: rname = mname//'/hdf_Init'
  953. ! --- local -------------------------------
  954. integer :: dfacc
  955. ! --- external ----------------------------
  956. integer(wpi), external :: sfStart
  957. ! --- begin -------------------------------
  958. ! code to open file:
  959. select case ( key )
  960. case ( 'read' )
  961. dfacc = DFACC_READ
  962. case ( 'write' )
  963. dfacc = DFACC_WRITE
  964. case ( 'create' )
  965. dfacc = DFACC_CREATE
  966. case default
  967. write (gol,'("do not know what how to access hdf for `",a,"`:")') key; call goErr
  968. write (gol,'(" file name : ",a)') trim(fname); call goErr
  969. write (gol,'("in ",a)') rname; call goErr; status=1; return
  970. end select
  971. ! open file:
  972. hdf%id = sfStart( fname, dfacc )
  973. if ( hdf%id == FAIL ) then
  974. write (gol,'("from starting access to hdf file:")'); call goErr
  975. write (gol,'(" file name : ",a)') trim(fname); call goErr
  976. write (gol,'(" access key : ",a)') trim(key); call goErr
  977. write (gol,'("in ",a)') rname; call goErr; status=1; return
  978. end if
  979. ! save file name:
  980. hdf%fname = fname
  981. ! ok
  982. status = 0
  983. end subroutine hdf_Init
  984. ! ***
  985. subroutine hdf_Done( hdf, status )
  986. ! --- in/out ------------------------------
  987. ! !ARGUMENTS:
  988. type(THdfFile), intent(out) :: hdf
  989. integer, intent(out) :: status
  990. ! --- const -------------------------------
  991. character(len=*), parameter :: rname = mname//'/hdf_Done'
  992. ! --- external ----------------------------
  993. integer(wpi), external :: sfEnd
  994. ! --- begin -------------------------------
  995. ! close file:
  996. status = sfEnd( hdf%id )
  997. if ( status == FAIL ) then
  998. write (gol,'("while closing HDF file:")'); call goErr
  999. write (gol,'(" file name : ",a)') trim(hdf%fname); call goErr
  1000. write (gol,'("in ",a)') rname; call goErr; status=1; return
  1001. end if
  1002. ! ok
  1003. status = 0
  1004. end subroutine hdf_Done
  1005. ! ================================================================
  1006. ! info
  1007. ! ================================================================
  1008. subroutine hdf_GetInfo( hdf, status, num_datasets, num_global_attrs )
  1009. ! --- in/out -------------------------
  1010. type(THdfFile), intent(inout) :: hdf
  1011. integer, intent(out) :: status
  1012. integer, intent(out), optional :: num_datasets
  1013. integer, intent(out), optional :: num_global_attrs
  1014. ! --- const -------------------------------
  1015. character(len=*), parameter :: rname = mname//'/hdf_GetInfo'
  1016. ! --- local -------------------------------
  1017. integer :: istat
  1018. integer :: f_num_datasets, f_num_global_attrs
  1019. ! --- external ----------------------------
  1020. integer(wpi), external :: sfFInfo
  1021. ! --- begin -------------------------------
  1022. ! extract info
  1023. istat = sfFInfo( hdf%id, f_num_datasets, f_num_global_attrs )
  1024. if ( istat == FAIL ) then
  1025. write (gol,'("from sfFInfo :")'); call goErr
  1026. write (gol,'(" hdf file : ",a)') hdf%fname; call goErr
  1027. write (gol,'("in ",a)') rname; call goErr; status=1; return
  1028. end if
  1029. ! return result
  1030. if ( present(num_datasets) ) num_datasets = f_num_datasets
  1031. if ( present(num_global_attrs) ) num_global_attrs = f_num_global_attrs
  1032. ! ok
  1033. status = 0
  1034. end subroutine hdf_GetInfo
  1035. ! =============================================================
  1036. ! === hdf data sets
  1037. ! =============================================================
  1038. subroutine hdf_FindDataSet( hdf, name, sds_index, status )
  1039. ! --- in/out -------------------------
  1040. type(THdfFile), intent(in) :: hdf
  1041. character(len=*), intent(in) :: name
  1042. integer, intent(out) :: sds_index
  1043. integer, intent(inout) :: status
  1044. ! --- const -------------------------------
  1045. character(len=*), parameter :: rname = mname//'/hdf_FindDataSet'
  1046. ! --- external -------------------------------
  1047. integer(wpi), external :: sfN2Index
  1048. ! --- local -------------------------------
  1049. logical :: verbose
  1050. ! --- begin -------------------------------
  1051. ! write error messages ?
  1052. verbose = status == 0
  1053. ! find index from name:
  1054. sds_index = sfN2Index( hdf%id, name )
  1055. if ( status < 0 ) then
  1056. ! not found ...
  1057. if (verbose) then
  1058. write (gol,'("data set not found ")'); call goErr
  1059. write (gol,'(" name : ",a)') trim(name)
  1060. write (gol,'(" file name : ",a)') trim(hdf%fname); call goErr
  1061. write (gol,'("in ",a)') rname; call goErr; status=-1; return
  1062. end if
  1063. else if ( status == 0 ) then
  1064. ! ok
  1065. status=0; return
  1066. else
  1067. ! error ...
  1068. write (gol,'("in ",a)') rname; call goErr; status=1; return
  1069. end if
  1070. end subroutine hdf_FindDataSet
  1071. ! =============================================================
  1072. ! === hdf global attributes
  1073. ! =============================================================
  1074. subroutine hdf_FindAttribute( hdf, name, attr_index, status )
  1075. ! --- in/out -------------------------
  1076. type(THdfFile), intent(in) :: hdf
  1077. character(len=*), intent(in) :: name
  1078. integer, intent(out) :: attr_index
  1079. integer, intent(inout) :: status
  1080. ! --- const -------------------------------
  1081. character(len=*), parameter :: rname = mname//'/hdf_FindAttribute'
  1082. ! --- local -------------------------------
  1083. logical :: verbose
  1084. ! --- begin -------------------------------
  1085. ! write error messages ?
  1086. verbose = status == 0
  1087. ! find attribute index from name:
  1088. call FindAttribute( hdf%id, name, attr_index, status )
  1089. if ( status < 0 ) then
  1090. ! not found ...
  1091. if (verbose) then; write (gol,'("in ",a)') rname; call goErr; end if
  1092. status=-1; return
  1093. else if ( status == 0 ) then
  1094. ! ok
  1095. status=0; return
  1096. else
  1097. ! error ...
  1098. write (gol,'("in ",a)') rname; call goErr; status=1; return
  1099. end if
  1100. end subroutine hdf_FindAttribute
  1101. ! ***
  1102. subroutine hdf_GetAttributeInfo( hdf, attr_index, status, &
  1103. name, &
  1104. data_type, data_type_descr, &
  1105. n_values )
  1106. ! --- in/out ----------------------------
  1107. type(THdfFile), intent(in) :: hdf
  1108. integer, intent(in) :: attr_index
  1109. integer, intent(inout) :: status
  1110. character(len=*), intent(out), optional :: name
  1111. integer, intent(out), optional :: data_type
  1112. character(len=1), intent(out), optional :: data_type_descr
  1113. integer, intent(out), optional :: n_values
  1114. ! --- const -------------------------------
  1115. character(len=*), parameter :: rname = mname//'/hdf_GetAttributeInfo'
  1116. ! --- begin -------------------------------
  1117. call GetAttributeInfo( hdf%id, attr_index, status, &
  1118. name=name, &
  1119. data_type=data_type, data_type_descr=data_type_descr, &
  1120. n_values=n_values )
  1121. if (status/=0) then; write (gol,'("in ",a)') rname; call goErr; status=1; return; end if
  1122. ! ok
  1123. status = 0
  1124. end subroutine hdf_GetAttributeInfo
  1125. ! ***
  1126. subroutine hdf_CheckAttributeInfo( hdf, attr_index, status, &
  1127. name, data_type, n_values )
  1128. ! --- in/out -------------------------
  1129. type(THdfFile), intent(in) :: hdf
  1130. integer, intent(in) :: attr_index
  1131. integer, intent(inout) :: status
  1132. character(len=*), intent(in), optional :: name
  1133. integer, intent(in), optional :: data_type
  1134. integer, intent(in), optional :: n_values
  1135. ! --- const -------------------------------
  1136. character(len=*), parameter :: rname = mname//'/hdf_CheckAttributeInfo'
  1137. ! --- local -------------------------------
  1138. logical :: verbose
  1139. ! --- begin -------------------------------
  1140. ! write error messages ?
  1141. verbose = status == 0
  1142. call CheckAttributeInfo( hdf%id, attr_index, status, &
  1143. name=name, data_type=data_type, n_values=n_values )
  1144. if ( status < 0 ) then
  1145. ! check failed ...
  1146. if (verbose) then; write (gol,'("in ",a)') rname; call goErr; end if
  1147. status=-1; return
  1148. else if ( status == 0 ) then
  1149. ! ok
  1150. status = 0; return
  1151. else
  1152. ! error ...
  1153. write (gol,'("in ",a)') rname; call goErr; status=1; return
  1154. end if
  1155. ! ok
  1156. status = 0
  1157. end subroutine hdf_CheckAttributeInfo
  1158. end module file_hdf_base