file_grib_api.F90 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992
  1. !#######################################################################
  2. !
  3. #define TRACEBACK write (gol,'("in ",a," (",a,", line",i5,")")') rname, __FILE__, __LINE__; call goErr
  4. #define IF_NOTOK_RETURN(action) if (status/=0) then; TRACEBACK; action; return; end if
  5. #define IF_ERROR_RETURN(action) if (status >0) then; TRACEBACK; action; return; end if
  6. !
  7. ! trap errors from GRIB_API:
  8. #define IF_GRIB_NOTOK_RETURN(action) if (status/=GRIB_SUCCESS) then; call GRIB_Get_Error_String(status,gol); call goErr; TRACEBACK; action; return; end if
  9. !
  10. !#######################################################################
  11. MODULE FILE_GRIB_API
  12. USE GO, only : gol, goPr, goErr
  13. USE GRIB_API, only : HGRIB => kindOfInt ! handle kind
  14. USE GRIB_API, only : GRIB_SUCCESS, GRIB_Get_Error_String
  15. IMPLICIT NONE
  16. PRIVATE
  17. PUBLIC :: TGribFile
  18. PUBLIC :: Init, Done, Opened
  19. PUBLIC :: Get
  20. PUBLIC :: Check
  21. PUBLIC :: ReadRecord
  22. ! --- const ------------------------------
  23. character(len=*), parameter :: mname = 'file_grib_api'
  24. ! --- types -------------------------------
  25. TYPE TGribFile
  26. integer(kind=HGRIB) :: fu
  27. character(len=256) :: fname
  28. ! grib id and return value (end_of_file check)
  29. integer(kind=HGRIB) :: igrib
  30. integer :: iret
  31. logical :: opened
  32. END TYPE TGribFile
  33. ! --- interfaces ---------------------------
  34. interface Init
  35. module procedure gribfile_Init
  36. end interface
  37. interface Done
  38. module procedure gribfile_Done
  39. end interface
  40. interface Opened
  41. module procedure gribfile_Opened
  42. end interface
  43. interface ReadRecord
  44. module procedure gribfile_ReadRecord
  45. end interface
  46. interface Get
  47. module procedure gribfile_Get
  48. end interface
  49. interface Check
  50. module procedure gribfile_Check
  51. end interface
  52. CONTAINS
  53. ! =================================================================
  54. ! Open gribfile.
  55. !
  56. ! USAGE
  57. ! call Init( gribfile, 'input.gb', 'r'|'w' )
  58. !
  59. ! DESCRIPTION
  60. ! Interface around routine 'pbOpen'.
  61. ! In 'gribfile', space is allocated to store grib sections.
  62. !
  63. subroutine gribfile_Init( F, file, mode, status )
  64. use Grib_API, only : Grib_Open_File
  65. ! --- in/out -----------------------
  66. type(TGribFile), intent(out) :: F
  67. character(len=*), intent(in) :: file
  68. character(len=*), intent(in) :: mode
  69. integer, intent(out) :: status
  70. ! --- const ------------------------
  71. character(len=*), parameter :: rname = mname//'/gribfile_Init'
  72. ! --- begin ------------------------
  73. F%fname = file ! filename
  74. select case ( mode )
  75. case ( 'r' )
  76. call grib_open_file ( F%fu, file, 'r' )
  77. F%opened=.true.
  78. case ( 'w' )
  79. write (gol,'("writing not yet supported for grib-api")') ; call goErr
  80. TRACEBACK; status=1; return
  81. case default
  82. write (gol,'("unknown mode `",a,"`")') mode; call goErr
  83. TRACEBACK; status=1; return
  84. end select
  85. ! no message loaded yet:
  86. F%igrib = -1
  87. end subroutine gribfile_Init
  88. ! ===
  89. ! Close gribfile, clear buffers
  90. !
  91. ! USAGE
  92. ! call Done( gribfile )
  93. !
  94. ! DESCRIPTION
  95. ! Interface around routine 'pbClose'.
  96. !
  97. subroutine gribfile_Done( F, status )
  98. use Grib_API, only : GRIB_Release
  99. use Grib_API, only : Grib_Close_File
  100. ! --- in/out -----------------------
  101. type(TGribFile), intent(inout) :: F
  102. integer, intent(inout) :: status
  103. ! --- const ------------------------
  104. character(len=*), parameter :: rname = mname//'/gribfile_Done'
  105. ! --- begin ------------------------
  106. ! old message loaded ?
  107. if ( F%igrib > 0 ) then
  108. ! remove from memory:
  109. call GRIB_Release( F%igrib, status=status )
  110. IF_GRIB_NOTOK_RETURN(status=1)
  111. ! no message loaded yet:
  112. F%igrib = -1
  113. end if
  114. ! write(*,'(1x,a,a)') 'Close grib file ',trim(F%fname)
  115. call grib_close_file ( F%fu, status )
  116. if ( status /= 0 ) then
  117. write (gol,'("from closing grib file:")'); call goErr
  118. write (gol,'(" status : ",i6)') status; call goErr
  119. write (gol,'(" file : ",a)') trim(F%fname); call goErr
  120. TRACEBACK; status=1; return
  121. else
  122. F%opened=.false.
  123. end if
  124. end subroutine gribfile_Done
  125. ! ===
  126. ! Grib file opened ?
  127. logical function gribfile_Opened( gribfile )
  128. ! --- in/out ------------------------------
  129. type(TGribFile), intent(in) :: gribfile
  130. ! --- begin -------------------------
  131. !inquire( unit=gribfile%fu, opened=gribfile_Opened )
  132. gribfile_Opened=gribfile%opened
  133. end function gribfile_Opened
  134. ! ==================================================================
  135. ! USAGE
  136. ! call ReadRecord( gribfile [,debug=0|1] [,status=status] )
  137. !
  138. ! DESCRIPTION
  139. ! Reads next grib record (a/k/a grib message) in buffers.
  140. !
  141. ! RETURN STATUS
  142. ! 0 : no error
  143. ! 1 : eof
  144. ! 2 : some error
  145. ! Execution might stop if other errors are encountered.
  146. !
  147. subroutine gribfile_ReadRecord( F, status )
  148. use Grib_API, only : GRIB_END_OF_FILE
  149. use Grib_API, only : GRIB_SUCCESS
  150. use Grib_API, only : Grib_New_From_File
  151. use Grib_API, only : Grib_Get
  152. use GRIB_API, only : GRIB_Release
  153. ! --- in/out -------------------------
  154. type(TGribFile), intent(inout) :: F
  155. integer, intent(out) :: status
  156. ! --- const --------------------------
  157. character(len=*), parameter :: rname = mname//'/gribfile_ReadRecord'
  158. integer :: iret
  159. logical :: verbose
  160. ! --- begin --------------------------
  161. ! old message loaded ?
  162. if ( F%igrib > 0 ) then
  163. ! remove from memory:
  164. call GRIB_Release( F%igrib, status=status )
  165. IF_GRIB_NOTOK_RETURN(status=1)
  166. ! no message loaded yet:
  167. F%igrib = -1
  168. end if
  169. ! a new grib message is loaded from file
  170. ! igrib is the grib id to be used in subsequent calls
  171. ! ret is the return value to check on end_of_file
  172. call grib_new_from_file ( F%fu, F%igrib, iret )
  173. if ( iret == GRIB_END_OF_FILE ) then
  174. write (gol,'("end-of-file is hit before a GRIB product is read")') ; call goErr
  175. write (gol,'(" grib file : ",a)') F%fname ; call goErr
  176. TRACEBACK; status = 1; return
  177. end if
  178. if ( iret /= GRIB_SUCCESS ) then
  179. write (gol,'("problem reading GRIB data block")') ; call goErr
  180. write (gol,'(" grib file : ",a)') F%fname ; call goErr
  181. call grib_get_error_string(iret,gol)
  182. call goErr
  183. TRACEBACK; status = 2; return
  184. end if
  185. ! no error ...
  186. status = 0
  187. end subroutine gribfile_ReadRecord
  188. ! ============================================================
  189. ! Extract data from grib sections.
  190. ! Optional arguments are passed to read parameter id, date, etc.
  191. ! If the same option is preceded by 'check_', an error
  192. ! message is written if the grib file does not match
  193. !
  194. ! pid : parameter identifier (integer number)
  195. !
  196. ! level : index of hybride level
  197. !
  198. ! reftime : 5 element integer array : yy, mm, dd, hh, min
  199. ! timerange : 4 element ingeger array : unit, val1, val2, indicator
  200. !
  201. subroutine gribfile_Get( F, status, &
  202. model_id, pid, pidShortName, &
  203. levtype, level, nlev, hyb_a, hyb_b, &
  204. reftime, timerange, &
  205. gridtype, &
  206. ll, &
  207. lon_first, lon_last, lon_inc, lon_n, &
  208. lat_first, lat_last, lat_inc, lat_n, &
  209. T, sh, &
  210. N, gg )
  211. use Grib_API, only : grib_get, grib_get_size
  212. use file_grib_base, only : gridtype_ll, gridtype_gg, gridtype_sh, gridtype_red_gg
  213. use file_grib_base, only : levtype_sfc, levtype_hyb, levtype_land, levtype_hyb2
  214. ! --- in/out -------------------------
  215. type(TGribFile), intent(in) :: F
  216. integer, intent(out) :: status
  217. integer, intent(out), optional :: model_id
  218. integer, intent(out), optional :: pid
  219. character(72), intent(out), optional :: pidShortName
  220. integer, intent(out), optional :: levtype, level, nlev
  221. real, intent(out), optional :: hyb_a(:), hyb_b(:)
  222. integer, intent(out), optional :: reftime(5)
  223. integer, intent(out), optional :: timerange(4)
  224. integer, intent(out), optional :: gridtype
  225. real, intent(out), optional :: lon_first, lon_last, lon_inc
  226. integer, intent(out), optional :: lon_n
  227. real, intent(out), optional :: lat_first, lat_last, lat_inc
  228. integer, intent(out), optional :: lat_n
  229. real, intent(out), optional :: ll(:,:)
  230. integer, intent(out), optional :: T
  231. complex, intent(out), optional :: sh(:)
  232. integer, intent(out), optional :: N
  233. real, intent(out), optional :: gg(:)
  234. ! --- const --------------------------------------
  235. character(len=*), parameter :: rname = mname//'/gribfile_Get'
  236. ! --- local --------------------------
  237. integer :: grib_reftime(5)
  238. integer :: grib_timerange(4)
  239. integer :: PVPresent, nb_pv, step, iret, ni, nj
  240. integer :: dataDate, dataTime
  241. integer :: numberOfValues
  242. real, allocatable :: pv(:)
  243. real, allocatable :: values(:)
  244. character(72) :: gridtypestring
  245. integer :: TypeOfLevel, edition
  246. ! --- begin --------------------------
  247. ! this grib1/grib2 business is getting messy!
  248. call grib_get(F%igrib, 'editionNumber', edition)
  249. ! -- model id
  250. if ( present( model_id ) ) then
  251. call grib_get(F%igrib, 'generatingProcessIdentifier', model_id )
  252. end if
  253. ! -- parameter
  254. if ( present( pid ) ) then
  255. call grib_get(F%igrib, 'paramId', pid )
  256. end if
  257. ! -- parameter short name
  258. if ( present( pidShortName ) ) then
  259. call grib_get(F%igrib, 'shortName', pidShortName )
  260. end if
  261. ! -- level
  262. if ( present(levtype) ) then
  263. call grib_get(F%igrib, 'levtype', levtype )
  264. ! make TM5 code works with edition2:
  265. if ((edition==2).and.(levtype==levtype_hyb2)) then
  266. levtype=levtype_hyb
  267. endif
  268. endif
  269. if ( present(level ) ) &
  270. call grib_get(F%igrib, 'level', level )
  271. ! -- Vertical Coordinate Parameters
  272. if ( present(hyb_a) .or. present(hyb_b) ) then
  273. if ( .not. (present(hyb_a) .and. present(hyb_b)) ) then
  274. write (gol,'("extract both hybrid params or none")'); call goErr
  275. TRACEBACK ; status = 1 ; return
  276. end if
  277. if (edition==1) then
  278. call grib_get(F%igrib,'indicatorOfTypeOfLevel', TypeOfLevel)
  279. select case (TypeOfLevel)
  280. case(levtype_hyb)
  281. ! get size, check, read, and split into 'a' and 'b'
  282. call grib_get_size(F%igrib,'pv',nb_pv)
  283. if ( nb_pv /= size(hyb_a) + size(hyb_b) ) then
  284. write (gol,'("numbers of hybride parameters do not match:")'); call goErr
  285. write (gol,'(" expected : ",i6)') size(hyb_a)+size(hyb_b); call goErr
  286. write (gol,'(" found : ",i6)') nb_pv; call goErr
  287. write (gol,'(" file : ",a)') trim(F%fname); call goErr
  288. TRACEBACK ; status = 1 ; return
  289. end if
  290. allocate(pv(nb_pv))
  291. call grib_get(F%igrib,'pv',pv)
  292. hyb_a = pv(1:size(hyb_a))
  293. hyb_b = pv(size(hyb_a)+1:nb_pv)
  294. deallocate(pv)
  295. ! case(levtype_sfc)
  296. ! !surface
  297. ! nlev=1
  298. case default
  299. write (gol,'("there are no hybride parameters in the grib message")'); call goErr
  300. write (gol,'(" file : ",a)') trim(F%fname); call goErr
  301. TRACEBACK ; status = 1 ; return
  302. end select
  303. elseif (edition==2) then
  304. call grib_get(F%igrib,'PVPresent',PVPresent)
  305. if (PVPresent == 1) then
  306. ! get size, check, read, and split into 'a' and 'b'
  307. call grib_get_size(F%igrib,'pv',nb_pv)
  308. if ( nb_pv /= size(hyb_a) + size(hyb_b) ) then
  309. write (gol,'("numbers of hybride parameters do not match:")'); call goErr
  310. write (gol,'(" expected : ",i6)') size(hyb_a)+size(hyb_b); call goErr
  311. write (gol,'(" found : ",i6)') nb_pv; call goErr
  312. write (gol,'(" file : ",a)') trim(F%fname); call goErr
  313. TRACEBACK ; status = 1 ; return
  314. end if
  315. allocate(pv(nb_pv))
  316. call grib_get(F%igrib,'pv',pv)
  317. hyb_a = pv(1:size(hyb_a))
  318. hyb_b = pv(size(hyb_a)+1:nb_pv)
  319. deallocate(pv)
  320. else
  321. write (gol,'("there are no hybride parameters in the grib message")'); call goErr
  322. write (gol,'(" file : ",a)') trim(F%fname); call goErr
  323. TRACEBACK ; status = 1 ; return
  324. end if
  325. end if
  326. !PLS: PVPresent flag is not available anymore. (for ei in grib1 I think)
  327. !PLS
  328. !PLS ! set PVPresent as an integer
  329. !PLS call grib_get(F%igrib,'PVPresent',PVPresent)
  330. !PLS if (PVPresent == 1) then
  331. !PLS ! number of parameters:
  332. !PLS call grib_get_size(F%igrib,'pv',nb_pv)
  333. !PLS ! parameters are stored a(0),..,a(L),b(0),..,b(L),
  334. !PLS ! thus length should be combined size of 'a' and 'b' arrays:
  335. !PLS if ( nb_pv /= size(hyb_a) + size(hyb_b) ) then
  336. !PLS write (gol,'("numbers of hybride parameters do not match:")'); call goErr
  337. !PLS write (gol,'(" expected : ",i6)') size(hyb_a)+size(hyb_b); call goErr
  338. !PLS write (gol,'(" found : ",i6)') nb_pv; call goErr
  339. !PLS write (gol,'(" file : ",a)') trim(F%fname); call goErr
  340. !PLS TRACEBACK ; status = 1 ; return
  341. !PLS end if
  342. !PLS ! storage for all parameters:
  343. !PLS allocate(pv(nb_pv))
  344. !PLS ! read:
  345. !PLS call grib_get(F%igrib,'pv',pv)
  346. !PLS ! split into 'a' and 'b' coeff:
  347. !PLS hyb_a = pv(1:size(hyb_a))
  348. !PLS hyb_b = pv(size(hyb_a)+1:nb_pv)
  349. !PLS ! clear:
  350. !PLS deallocate(pv)
  351. !PLS else
  352. !PLS write (gol,'("there are no hybride parameters in the grib message")'); call goErr
  353. !PLS write (gol,'(" file : ",a)') trim(F%fname); call goErr
  354. !PLS TRACEBACK ; status = 1 ; return
  355. !PLS end if
  356. end if
  357. ! number of levels
  358. if ( present(nlev) ) then
  359. if (edition==1) then
  360. call grib_get(F%igrib,'indicatorOfTypeOfLevel', TypeOfLevel)
  361. select case (TypeOfLevel)
  362. case(levtype_hyb)
  363. call grib_get_size(F%igrib,'pv',nb_pv)
  364. ! half level coeffs are hyba(0:nlev) and hybb(0:nlev), compute number of (full) levels:
  365. nlev = nb_pv/2 - 1
  366. case(levtype_sfc)
  367. !surface
  368. nlev=1
  369. case(levtype_land)
  370. nlev=1
  371. case default
  372. write (gol,'("do not know about that TypeOfLevel")'); call goErr
  373. TRACEBACK ; status = 1 ; return
  374. end select
  375. elseif (edition==2) then
  376. call grib_get(F%igrib,'PVPresent',PVPresent)
  377. if (PVPresent == 1) then
  378. ! get total number of half level hyb. coeffs:
  379. call grib_get_size(F%igrib,'pv',nb_pv)
  380. ! half level coeffs are hyba(0:nlev) and hybb(0:nlev), compute number of (full) levels:
  381. nlev = nb_pv/2 - 1
  382. else
  383. write (gol,'("there are no hybrid parameters in the grib message")'); call goErr
  384. TRACEBACK ; status = 1 ; return
  385. end if
  386. end if
  387. endif
  388. ! -- reference time
  389. if ( present(reftime) ) then
  390. ! extract reference time:
  391. call grib_get(F%igrib,'dataDate',dataDate)
  392. call grib_get(F%igrib,'dataTime',dataTime)
  393. grib_reftime(1) = dataDate/10000 ! year
  394. grib_reftime(2) = Mod(dataDate/100,100) ! month
  395. grib_reftime(3) = Mod(datadate,100) ! day
  396. grib_reftime(4) = dataTime/100 ! hour
  397. grib_reftime(5) = Mod(dataTime,100) ! minutes
  398. reftime = grib_reftime
  399. end if
  400. ! -- time range
  401. if ( present(timerange) ) then
  402. ! write (*,'(" ",a," WARNING timerange argument not fully supported ")') trim(name)
  403. ! Available from Grib-api: stepType, stepUnits, startStep, endStep, stepRange, step
  404. call grib_get(F%igrib,'step',step)
  405. grib_timerange(1:4) = (/ 1, step, 0, 0 /)
  406. timerange = grib_timerange
  407. end if
  408. ! --- grid
  409. if ( present(gridtype) ) then
  410. call grib_get(F%igrib,'gridType',gridtypestring)
  411. select case ( trim(gridtypestring) )
  412. case ( 'regular_ll' ) ; gridtype = gridtype_ll
  413. case ( 'regular_gg' ) ; gridtype = gridtype_gg ! gribex gives that for reduced.
  414. case ( 'regular_sh' ) ; gridtype = gridtype_sh
  415. case ( 'sh' ) ; gridtype = gridtype_sh ! used by grid_api
  416. case ( 'reduced_gg' ) ; gridtype = gridtype_red_gg ! used by grid_api
  417. case default
  418. write (gol,'("unsupported grid type string : ",a)') trim(gridtypestring); call goErr
  419. TRACEBACK ; status = 1 ; return
  420. end select
  421. end if
  422. if ( present(lon_n) ) call grib_get(F%igrib,'Ni',lon_n)
  423. if ( present(lat_n) ) call grib_get(F%igrib,'Nj',lat_n)
  424. if ( present(lat_first) ) call grib_get(F%igrib,'latitudeOfFirstGridPointInDegrees',lat_first)
  425. if ( present(lon_first) ) call grib_get(F%igrib,'longitudeOfFirstGridPointInDegrees',lon_first)
  426. if ( present(lat_last) ) call grib_get(F%igrib,'latitudeOfLastGridPointInDegrees',lat_last)
  427. if ( present(lon_last) ) call grib_get(F%igrib,'longitudeOfLastGridPointInDegrees',lon_last)
  428. if ( present(lon_inc) ) call grib_get(F%igrib,'iDirectionIncrementInDegrees',lon_inc)
  429. if ( present(lat_inc) ) call grib_get(F%igrib,'jDirectionIncrementInDegrees',lat_inc)
  430. ! -- lat/lon grid
  431. if ( present(ll) ) then
  432. !call Check( F, gridtype=gridtype_ll )
  433. call grib_get(F%igrib,'gridType',gridtypestring)
  434. if ( trim(gridtypestring) /= 'regular_ll' ) then
  435. write (gol,'("grid types do not match:")'); call goErr
  436. write (gol,'(" expected : regular_ll")') ; call goErr
  437. write (gol,'(" found : ",i4)') gridtype; call goErr
  438. TRACEBACK ; status = 1 ; return
  439. end if
  440. call grib_get(F%igrib,'Ni',ni)
  441. call grib_get(F%igrib,'Nj',nj)
  442. if ( (size(ll,1)/=ni) .or. (size(ll,2)/=nj) ) then
  443. write (gol,'("grid sizes do not match:")'); call goErr
  444. write (gol,'(" expected : ",i4," x ",i4)') size(ll,1), size(ll,2); call goErr
  445. write (gol,'(" found : ",i4," x ",i4)') ni, nj; call goErr
  446. TRACEBACK ; status = 1 ; return
  447. end if
  448. ! get the size of the values array, and allocate storage
  449. call grib_get_size(F%igrib,'values',numberOfValues)
  450. allocate(values(numberOfValues), stat=iret)
  451. ! get the field
  452. call grib_get(F%igrib,'values',values)
  453. ll = reshape( values(1:size(ll)), shape(ll) )
  454. ! release storage
  455. deallocate(values)
  456. end if
  457. ! -- gaussian lat/lon grid
  458. if ( present(N) ) then
  459. call grib_get(F%igrib,'N',N)
  460. end if
  461. if ( present(gg) ) then
  462. ! Get and check size of field
  463. call grib_get_size(F%igrib,'values',numberOfValues)
  464. if ( size(gg) /= numberOfValues ) then
  465. write (gol,'("gg grid sizes do not match:")') ; call goErr
  466. write (gol,'(" expected : ",i6)') size(gg) ; call goErr
  467. write (gol,'(" found : ",i6)') numberOfValues ; call goErr
  468. TRACEBACK; status=1; return
  469. end if
  470. ! Get the field
  471. call grib_get(F%igrib,'values',gg)
  472. end if
  473. ! -- spectral coef
  474. if ( present(T) ) then ! truncation nb
  475. call grib_get(F%igrib,'M',T)
  476. end if
  477. if ( present(sh) ) then
  478. ! Get and check size of field
  479. call grib_get_size(F%igrib,'values',numberOfValues)
  480. if ( size(sh) /= numberOfValues/2 ) then
  481. write (gol,'("numbers of spectral coefficients do not match:")') ; call goErr
  482. write (gol,'(" expected : ",i6)') size(sh) ; call goErr
  483. write (gol,'(" found : ",i6)') numberOfValues/2 ; call goErr
  484. TRACEBACK; status=1; return
  485. end if
  486. ! Get the field, convert from real to complex
  487. allocate(values(numberOfValues), stat=iret)
  488. call grib_get(F%igrib,'values',values)
  489. sh = transfer( values, (/(0.0,0.0)/) )
  490. deallocate( values )
  491. end if
  492. ! ok
  493. status = 0
  494. end subroutine gribfile_Get
  495. ! ===
  496. ! NOTE
  497. ! Do not check hybride coeff; different number of bits etc
  498. ! cause small differences ...
  499. subroutine gribfile_Check( F, status, debug, &
  500. model_id, pid, &
  501. levtype, level, &
  502. reftime, timerange, &
  503. gridtype, &
  504. lon_first, lon_last, lon_inc, lon_n, &
  505. lat_first, lat_last, lat_inc, lat_n, &
  506. T )
  507. use Grib_API, only : grib_get
  508. use file_grib_base, only : gridtype_ll, gridtype_gg, gridtype_sh, gridtype_red_gg
  509. ! --- in/out -------------------------
  510. type(TGribFile), intent(in) :: F
  511. integer, intent(out) :: status
  512. integer, intent(in), optional :: debug
  513. integer, intent(in), optional :: model_id
  514. integer, intent(in), optional :: pid
  515. integer, intent(in), optional :: levtype, level
  516. !real, intent(in), optional :: hyb_a(:), hyb_b(:)
  517. integer, intent(in), optional :: reftime(5)
  518. integer, intent(in), optional :: timerange(4)
  519. integer, intent(in), optional :: gridtype
  520. integer, intent(in), optional :: lon_first, lon_last, lon_inc, lon_n
  521. integer, intent(in), optional :: lat_first, lat_last, lat_inc, lat_n
  522. integer, intent(in), optional :: T
  523. ! --- const --------------------------------------
  524. character(len=*), parameter :: rname = mname//'/gribfile_Check'
  525. ! --- local --------------------------
  526. integer :: dataDate, dataTime
  527. integer :: grib_model_id
  528. integer :: grib_pid
  529. integer :: grib_levtype, grib_level
  530. integer :: grib_reftime(5)
  531. integer :: grib_timerange(4)
  532. integer :: grib_n
  533. ! integer :: grib_T
  534. !
  535. ! !real, allocatable :: grib_hyb_a(:), grib_hyb_b(:)
  536. logical :: verbose
  537. integer :: step, recGridType
  538. character(255) :: gridtypestring
  539. real :: xdum
  540. ! --- begin --------------------------
  541. ! write error messages ?
  542. verbose = .false.
  543. if ( present(debug) ) verbose = debug > 0
  544. ! ok by default
  545. status = 0
  546. ! -- check model id
  547. if ( present( model_id ) ) then
  548. call grib_get(F%igrib, 'generatingProcessIdentifier', grib_model_id )
  549. if ( grib_model_id /= model_id ) then
  550. if ( verbose ) then
  551. write (gol,'("model id''s do not match:")') ; call goErr
  552. write (gol,'(" expected : ",i4)') model_id ; call goErr
  553. write (gol,'(" found : ",i4)') grib_model_id ; call goErr
  554. write (gol,'(" in ",a)') trim(F%fname) ; call goErr
  555. TRACEBACK
  556. end if
  557. status=status+1
  558. end if
  559. end if
  560. ! -- check parameter
  561. if ( present( pid ) ) then
  562. call grib_get(F%igrib, 'paramId', grib_pid )
  563. if ( grib_pid /= pid ) then
  564. if ( verbose ) then
  565. write (gol,'("parameter id''s do not match:")') ; call goErr
  566. write (gol,'(" expected : ",i6)') pid ; call goErr
  567. write (gol,'(" found : ",i6)') grib_pid ; call goErr
  568. write (gol,'(" in ",a)') trim(F%fname) ; call goErr
  569. TRACEBACK
  570. end if
  571. status = status+1
  572. end if
  573. end if
  574. ! -- check level
  575. if ( present(levtype) ) then
  576. call grib_get(F%igrib, 'levtype', grib_levtype )
  577. if ( grib_levtype /= levtype ) then
  578. if ( verbose ) then
  579. write (gol,'("level types do not match:")') ; call goErr
  580. write (gol,'(" expected : ",i6)') levtype ; call goErr
  581. write (gol,'(" found : ",i6)') grib_levtype ; call goErr
  582. write (gol,'(" in ",a)') trim(F%fname) ; call goErr
  583. TRACEBACK
  584. end if
  585. status=status+1
  586. end if
  587. end if
  588. if ( present(level) ) then
  589. call grib_get(F%igrib, 'level', grib_level )
  590. if ( grib_level /= level ) then
  591. if ( verbose ) then
  592. write (gol,'("levels do not match:")') ; call goErr
  593. write (gol,'(" expected : ",i6)') level ; call goErr
  594. write (gol,'(" found : ",i6)') grib_level ; call goErr
  595. write (gol,'(" in ",a)') trim(F%fname) ; call goErr
  596. TRACEBACK
  597. end if
  598. status=status+1
  599. end if
  600. end if
  601. !if ( present(hyb_a) .or. present(hyb_b) ) then
  602. ! if ( .not. (present(hyb_a) .and. present(hyb_b)) ) then
  603. ! print *, 'gribsections_Extract : error : extract both hybride params or none'
  604. ! !stop
  605. ! end if
  606. ! allocate( grib_hyb_a(size(hyb_a)) )
  607. ! allocate( grib_hyb_b(size(hyb_b)) )
  608. ! call Get( F, hyb_a=grib_hyb_a, hyb_b=grib_hyb_b )
  609. ! if ( any(grib_hyb_a/=hyb_a) .or. any(grib_hyb_b/=hyb_b) ) then
  610. ! if ( present(status) ) then
  611. ! status = 1
  612. ! else
  613. ! print *, 'gribsections_Check : hybride coeff in grib file do not match'
  614. ! stop
  615. ! end if
  616. ! end if
  617. ! deallocate( grib_hyb_a )
  618. ! deallocate( grib_hyb_b )
  619. !end if
  620. ! -- check reference time
  621. ! extract reference time:
  622. call grib_get(F%igrib,'dataDate',dataDate)
  623. call grib_get(F%igrib,'dataTime',dataTime)
  624. grib_reftime(1) = dataDate/10000 ! year
  625. grib_reftime(2) = Mod(dataDate/100,100) ! month
  626. grib_reftime(3) = Mod(datadate,100) ! day
  627. grib_reftime(4) = dataTime/100 ! hour
  628. grib_reftime(5) = Mod(dataTime,100) ! minutes
  629. if ( present(reftime) ) then
  630. if ( any( grib_reftime /= reftime ) ) then
  631. if ( verbose ) then
  632. write (gol,'("reference times do not match:")') ; call goErr
  633. write (gol,'(" expected : ",i4,4i3)') reftime ; call goErr
  634. write (gol,'(" found : ",i4,4i3)') grib_reftime ; call goErr
  635. write (gol,'(" in ",a)') trim(F%fname) ; call goErr
  636. TRACEBACK
  637. end if
  638. status=status+1
  639. end if
  640. end if
  641. ! -- check time range
  642. if ( present(timerange) ) then
  643. write (*,'(a," WARNING timerange argument not fully supported ")') rname
  644. write(*,*)
  645. ! Available from Grib-api: stepType, stepUnits, startStep, endStep, stepRange, step
  646. call grib_get(F%igrib,'step',step)
  647. grib_timerange(1:4) = (/ 1, step, 0, 0 /)
  648. if ( any( grib_timerange /= timerange ) ) then
  649. if ( verbose ) then
  650. write (gol,'("time ranges do not match:")') ; call goErr
  651. write (gol,'(" expected : ",4i3)') timerange ; call goErr
  652. write (gol,'(" found : ",4i3)') grib_timerange ; call goErr
  653. write (gol,'(" in ",a)') trim(F%fname) ; call goErr
  654. TRACEBACK
  655. end if
  656. status=status+1
  657. end if
  658. end if
  659. ! --- check grid
  660. if ( present(gridtype) ) then
  661. call grib_get(F%igrib,'gridType',gridtypestring)
  662. ! See https://software.ecmwf.int/wiki/display/GRIB/Grib+API+keys for availability
  663. select case ( trim(gridtypestring) )
  664. case ( 'regular_ll' ) ; recGridType = gridtype_ll
  665. case ( 'regular_gg' ) ; recGridType = gridtype_gg
  666. case ( 'regular_sh' ) ; recGridType = gridtype_sh
  667. case ( 'sh' ) ; recGridType = gridtype_sh ! used by grid_api
  668. case ( 'reduced_gg' ) ; recgridtype = gridtype_red_gg ! used by grid_api
  669. case default
  670. if ( verbose ) then
  671. write (gol,'("unsupported grid type string : ",a)') trim(gridtypestring); call goErr
  672. endif
  673. recGridType = -999
  674. end select
  675. if ( recGridType /= gridtype ) then
  676. if ( verbose ) then
  677. write (gol,'("gridtypes do not match:")') ; call goErr
  678. write (gol,'(" expected : ",i6)') gridtype ; call goErr
  679. write (gol,'(" found : ",i6)') recGridType ; call goErr
  680. write (gol,'(" in ",a)') trim(F%fname) ; call goErr
  681. TRACEBACK
  682. end if
  683. status=status+1
  684. end if
  685. end if
  686. if ( present(lon_n) ) then
  687. call grib_get(F%igrib,'Ni',grib_n)
  688. if ( grib_n /= lon_n ) then
  689. if ( verbose ) then
  690. write (gol,'("number of longitudes do not match:")') ; call goErr
  691. write (gol,'(" expected : ",i6)') lon_n ; call goErr
  692. write (gol,'(" found : ",i6)') grib_n ; call goErr
  693. write (gol,'(" in ",a)') trim(F%fname) ; call goErr
  694. TRACEBACK
  695. end if
  696. status=status+1
  697. end if
  698. end if
  699. if ( present(lat_n) ) then
  700. call grib_get(F%igrib,'Nj',grib_n)
  701. if ( grib_n /= lat_n ) then
  702. if ( verbose ) then
  703. write (gol,'("number of latitudes do not match:")') ; call goErr
  704. write (gol,'(" expected : ",i6)') lat_n ; call goErr
  705. write (gol,'(" found : ",i6)') grib_n ; call goErr
  706. write (gol,'(" in ",a)') trim(F%fname) ; call goErr
  707. TRACEBACK
  708. end if
  709. status=status+1
  710. end if
  711. end if
  712. if ( present(lat_first) ) then
  713. call grib_get(F%igrib,'latitudeOfFirstGridPointInDegrees',xdum)
  714. grib_n = nint(xdum*1000)
  715. if ( grib_n /= lat_first ) then
  716. if ( verbose ) then
  717. write (gol,'("first latitudes do not match:")') ; call goErr
  718. write (gol,'(" expected : ",i6)') lat_first ; call goErr
  719. write (gol,'(" found : ",i6)') grib_n ; call goErr
  720. write (gol,'(" in ",a)') trim(F%fname) ; call goErr
  721. TRACEBACK
  722. end if
  723. status=status+1
  724. end if
  725. end if
  726. if ( present(lon_first) ) then
  727. call grib_get(F%igrib,'longitudeOfFirstGridPointInDegrees',xdum)
  728. grib_n = nint(xdum*1000)
  729. if ( grib_n /= lon_first ) then
  730. if ( verbose ) then
  731. write (gol,'("first longitudes do not match:")') ; call goErr
  732. write (gol,'(" expected : ",i6)') lon_first ; call goErr
  733. write (gol,'(" found : ",i6)') grib_n ; call goErr
  734. write (gol,'(" in ",a)') trim(F%fname) ; call goErr
  735. TRACEBACK
  736. end if
  737. status=status+1
  738. end if
  739. end if
  740. if ( present(lat_last) ) then
  741. call grib_get(F%igrib,'latitudeOfLastGridPointInDegrees',xdum)
  742. grib_n = nint(xdum*1000)
  743. if ( grib_n /= lat_last ) then
  744. if ( verbose ) then
  745. write (gol,'("last latitudes do not match:")') ; call goErr
  746. write (gol,'(" expected : ",i6)') lat_last ; call goErr
  747. write (gol,'(" found : ",i6)') grib_n ; call goErr
  748. write (gol,'(" in ",a)') trim(F%fname) ; call goErr
  749. TRACEBACK
  750. end if
  751. status=status+1
  752. end if
  753. end if
  754. if ( present(lon_last) ) then
  755. call grib_get(F%igrib,'longitudeOfLastGridPointInDegrees',xdum)
  756. grib_n = nint(xdum*1000)
  757. if ( grib_n /= lon_last ) then
  758. if ( verbose ) then
  759. write (gol,'("last longitudes do not match:")') ; call goErr
  760. write (gol,'(" expected : ",i6)') lon_last ; call goErr
  761. write (gol,'(" found : ",i6)') grib_n ; call goErr
  762. write (gol,'(" in ",a)') trim(F%fname) ; call goErr
  763. TRACEBACK
  764. end if
  765. status=status+1
  766. end if
  767. end if
  768. if ( present(lon_inc) ) then
  769. call grib_get(F%igrib,'iDirectionIncrementInDegrees',xdum)
  770. grib_n = nint(xdum*1000)
  771. if ( grib_n /= lon_inc ) then
  772. if ( verbose ) then
  773. write (gol,'("longitude increments do not match:")') ; call goErr
  774. write (gol,'(" expected : ",i6)') lon_inc ; call goErr
  775. write (gol,'(" found : ",i6)') grib_n ; call goErr
  776. write (gol,'(" in ",a)') trim(F%fname) ; call goErr
  777. TRACEBACK
  778. end if
  779. status=status+1
  780. end if
  781. end if
  782. if ( present(lat_inc) ) then
  783. call grib_get(F%igrib,'jDirectionIncrementInDegrees',xdum)
  784. grib_n = nint(xdum*1000)
  785. if ( grib_n /= lat_inc ) then
  786. if ( verbose ) then
  787. write (gol,'("latitude increments do not match:")') ; call goErr
  788. write (gol,'(" expected : ",i6)') lat_inc ; call goErr
  789. write (gol,'(" found : ",i6)') grib_n ; call goErr
  790. write (gol,'(" in ",a)') trim(F%fname) ; call goErr
  791. TRACEBACK
  792. end if
  793. status=status+1
  794. end if
  795. end if
  796. ! --- check truncation
  797. if ( present(T) ) then
  798. write (*,'("ERROR, Spectral grid not yet supported for Grib-api")')
  799. stop
  800. end if
  801. end subroutine gribfile_Check
  802. end module file_grib_api