file_grib_gribex.F90 51 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524
  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. !#######################################################################
  8. module file_grib_gribex
  9. use GO, only : gol, goErr, goPr
  10. implicit none
  11. ! --- in/out -------------------------------
  12. private
  13. public :: TGribFile
  14. public :: Init, Done, Opened
  15. public :: Clear
  16. public :: CopySections, CopyAllSections
  17. public :: Get
  18. public :: Check
  19. public :: Set
  20. public :: ReadRecord
  21. ! public :: pidname, pidmax
  22. ! public :: pid_T
  23. ! public :: pid_Q
  24. ! public :: pid_U, pid_V, pid_W
  25. ! public :: pid_SP, pid_LNSP
  26. ! public :: pid_VO, pid_D
  27. ! public :: pid_Z, pid_LSM
  28. ! public :: pid_SR, pid_AL, pid_LSRH
  29. ! public :: pid_SLHF
  30. ! public :: pid_CLWC, pid_CIWC, pid_CC
  31. ! --- const ------------------------------
  32. character(len=*), parameter :: mname = 'file_grib_gribex'
  33. ! ! *** Type of level (Code Table 3)
  34. !
  35. ! integer, parameter :: levtype_sfc = 1 ! ground or water surface
  36. ! integer, parameter :: levtype_hyb = 109 ! hybrid level
  37. ! integer, parameter :: levtype_land = 112 ! layer below surface
  38. !
  39. ! ! *** parameter identifier (Code Table 2)
  40. !
  41. ! ! o numbers
  42. !
  43. ! integer, parameter :: pid_Z = 129 ! geopotential (orography)
  44. ! integer, parameter :: pid_T = 130 ! temperature
  45. ! integer, parameter :: pid_U = 131 ! u-velocity
  46. ! integer, parameter :: pid_V = 132 ! v-velocity
  47. ! integer, parameter :: pid_Q = 133 ! specific humidity
  48. ! integer, parameter :: pid_SP = 134 ! surface pressure
  49. ! integer, parameter :: pid_W = 135 ! vertical velocity
  50. !
  51. ! integer, parameter :: pid_VO = 138 ! vorticity
  52. !
  53. ! integer, parameter :: pid_SLHF = 147 ! surface latent heat flux (W m**-2 s)
  54. !
  55. ! integer, parameter :: pid_LNSP = 152 ! ln surface pressure
  56. !
  57. ! integer, parameter :: pid_D = 155 ! divergence
  58. !
  59. ! integer, parameter :: pid_LSM = 172 ! land sea mask
  60. ! integer, parameter :: pid_SR = 173 ! Surface roughness m
  61. ! integer, parameter :: pid_AL = 174 ! Albedo (0-1)
  62. !
  63. ! integer, parameter :: pid_LSRH = 234 ! Logarithm of SR length for heat
  64. !
  65. ! integer, parameter :: pid_CLWC = 246 ! cloud liquid water content
  66. ! integer, parameter :: pid_CIWC = 247 ! cloud ice water content
  67. ! integer, parameter :: pid_CC = 248 ! cloud cover
  68. !
  69. ! ! o maximum number
  70. ! integer, parameter :: pidmax = 260
  71. !
  72. ! ! o names
  73. !
  74. ! character(len=4), parameter :: pidname(pidmax) = (/ &
  75. ! 'a ','b ','c ','d ','e ','f ','g ','p008','p009','p010', &
  76. ! 'p011','p012','p013','p014','p015','p016','p017','p018','p019','p020', &
  77. ! 'p021','p022','p023','p024','p025','p026','p027','p028','p029','p030', &
  78. ! 'p031','p032','p033','p034','p035','p036','p037','p038','p039','p040', &
  79. ! 'p041','p042','p043','p044','p045','p046','p047','p048','p049','p050', &
  80. ! 'p051','p052','p053','p054','p055','p056','p057','p058','p059','p060', &
  81. ! 'p061','p062','p063','p064','p065','p066','p067','p068','p069','p070', &
  82. ! 'p071','p072','p073','p074','p075','p076','p077','p078','p079','p080', &
  83. ! 'p081','p082','p083','p084','p085','p086','p087','p088','p089','p090', &
  84. ! 'p091','p092','p093','p094','p095','p096','p097','p098','p099','p100', &
  85. ! 'p101','p102','p103','p104','p105','p106','p107','p108','p109','p110', &
  86. ! 'p111','p112','p113','p114','p115','p116','p117','p118','p119','p120', &
  87. ! 'p121','p122','p123','p124','p125','p126','p127','p128','Z ','T ', &
  88. ! 'U ','V ','Q ','SP ','W ','p136','p137','VO ','p139','p140', &
  89. ! 'SD ','LSP ','CP ','SF ','p145','SSHF','SLHF','p148','p149','p150', &
  90. ! 'p151','LNSP','p153','p154','D ','zg ','pw ','pu ','pv ','sp ', &
  91. ! 'eu ','du ','dk ','ed ','dd ','p166','T2M ','D2M ','p169','p170', &
  92. ! 'p171','LSM ','SR ','AL ','p175','SSR ','p177','p178','p179','EWSS', &
  93. ! 'NSSS','p182','p183','p184','p185','p186','p187','p188','p189','clb ', &
  94. ! 'clt ','clfs','p193','p194','p195','p196','p197','SRC ','p199','p200', &
  95. ! 'p201','p202','p203','p204','p205','p206','p207','p208','p209','p210', &
  96. ! 'p211','p212','p213','p214','p215','p216','p217','p218','p219','p220', &
  97. ! 'p221','p222','p223','p224','p225','p226','p227','p228','p229','p230', &
  98. ! 'p231','p232','p233','LSRH','p235','p236','p237','p238','p239','p240', &
  99. ! 'p241','p242','p243','p244','p245','CLWC','CIWC','CC ','cco ','ccu ', &
  100. ! 'p251','p252','p253','p254','p255','p256','p257','p258','p259','p260' /)
  101. !
  102. ! ! *** data representation type (Code Table 6)
  103. !
  104. ! integer, parameter :: gridtype_ll = 0
  105. ! integer, parameter :: gridtype_gg = 4
  106. ! integer, parameter :: gridtype_sh = 50
  107. ! --- types -------------------------------
  108. type TGribFile
  109. integer :: fu
  110. character(len=256) :: fname
  111. ! *** buffer for grib message
  112. integer :: inbuff_bytes ! length of input buffer
  113. ! Section 0 - Indicator Section.
  114. integer :: isec0(2)
  115. ! Section 1 - Product Definition Section.
  116. integer :: isec1(512)
  117. ! Section 2 - Grid Description Section.
  118. integer :: isec2(512)
  119. real :: rsec2(512)
  120. ! Section 3 - ??
  121. integer :: isec3(2)
  122. real :: rsec3(2)
  123. ! Section 4 - Binary Data Section.
  124. integer :: isec4(512)
  125. real, pointer :: rsec4(:)
  126. !
  127. integer :: kword
  128. end type TGribFile
  129. ! --- interfaces ---------------------------
  130. interface Init
  131. module procedure gribfile_Init
  132. end interface
  133. interface Done
  134. module procedure gribfile_Done
  135. end interface
  136. interface Opened
  137. module procedure gribfile_Opened
  138. end interface
  139. interface ReadRecord
  140. module procedure gribfile_ReadRecord
  141. end interface
  142. interface Clear
  143. module procedure gribfile_Clear
  144. end interface
  145. interface CopySections
  146. module procedure gribfile_CopySections
  147. end interface
  148. interface CopyAllSections
  149. module procedure gribfile_CopyAllSections
  150. end interface
  151. interface Get
  152. module procedure gribfile_Get
  153. end interface
  154. interface Check
  155. module procedure gribfile_Check
  156. end interface
  157. interface Set
  158. module procedure gribfile_Set
  159. end interface
  160. CONTAINS
  161. ! =================================================================
  162. ! Open gribfile.
  163. !
  164. ! USAGE
  165. ! call Init( gribfile, 'input.gb', 'r'|'w' )
  166. !
  167. ! DESCRIPTION
  168. ! Interface around routine 'pbOpen'.
  169. ! In 'gribfile', space is allocated to store grib sections.
  170. !
  171. subroutine gribfile_Init( F, file, mode, status )
  172. ! --- in/out -----------------------
  173. type(TGribFile), intent(out) :: F
  174. character(len=*), intent(in) :: file
  175. character(len=*), intent(in) :: mode
  176. integer, intent(out) :: status
  177. ! --- const ------------------------
  178. character(len=*), parameter :: rname = mname//', gribfile_Init'
  179. ! --- local ------------------------
  180. ! dummy buffer of insufficient length:
  181. integer :: inbuff(10)
  182. ! --- begin ------------------------
  183. ! *** initialize grib sections
  184. ! Section 0 - Indicator Section.
  185. F%isec0 = 0
  186. ! Section 1 - Product Definition Section.
  187. F%isec1 = 0
  188. ! Section 2 - Grid Description Section.
  189. F%isec2 = 0
  190. F%rsec2 = 0.0
  191. ! Section 3 - ??
  192. F%isec3 = 0
  193. F%rsec3 = 0.0
  194. ! Section 4 - Binary Data Section.
  195. F%isec4 = 0
  196. nullify( F%rsec4 )
  197. F%kword = 0
  198. ! *** Open specified file with requested name.
  199. ! A free file unit seems to be assigned in pbOpen.
  200. call pbOpen( F%fu, file, mode, status )
  201. if ( status /= 0 ) then
  202. write (gol,'("from pbOpen:")'); call goErr
  203. select case ( status )
  204. case (-1)
  205. write (gol,'(" could not open file")'); call goErr
  206. case (-2)
  207. write (gol,'(" invalid file name")') ; call goErr
  208. case (-3)
  209. write (gol,'(" invalid open mode")'); call goErr
  210. case default
  211. write (gol,'(" unknown return status: ",i6)') status; call goErr
  212. end select
  213. write (gol,'(" file: ",a)') trim(file); call goErr
  214. TRACEBACK; status=1; return
  215. end if
  216. ! save filename
  217. F%fname = file
  218. select case ( mode )
  219. case ( 'r' )
  220. ! Determine length of records ('messages' in grib context);
  221. ! open with insufficient buffer, and check error messages:
  222. status = 1 ! force return even if error occures
  223. call pbGrib( F%fu, inbuff, size(inbuff)*kind(inbuff), F%inbuff_bytes, status )
  224. select case ( status )
  225. case ( 0)
  226. ! no error ?
  227. write (gol,'("tried to read record into buffer with insuficient length,")'); call goErr
  228. write (gol,'("but no error occured ...")'); call goErr
  229. TRACEBACK; status=1; return
  230. case (-1)
  231. write (gol,'("end-of-file is hit before a GRIB product is read")'); call goErr
  232. TRACEBACK; status=1; return
  233. case (-3)
  234. ! size of input buffer was not sufficient (as expected)
  235. case default
  236. write (gol,'("unknown return status from pbGrib : ",i6)') status; call goErr
  237. TRACEBACK; status=1; return
  238. end select
  239. ! adhoc increment (sometimes first record is very different form others)
  240. F%inbuff_bytes = F%inbuff_bytes*2
  241. ! Close file:
  242. call pbClose( F%fu, status )
  243. if ( status /= 0 ) then
  244. write (gol,'("error in call to pbClose; status=",i6)') status; call goErr
  245. TRACEBACK; status=1; return
  246. end if
  247. ! Reopen file:
  248. call pbOpen( F%fu, file, mode, status )
  249. if ( status /= 0 ) then
  250. write (gol,'("from second open; status=",i6)') status; call goErr
  251. TRACEBACK; status=1; return
  252. end if
  253. case ( 'w' )
  254. ! nothing special
  255. case default
  256. write (gol,'(" unknown mode `",a,"`")') mode; call goErr
  257. TRACEBACK; status=1; return
  258. end select
  259. end subroutine gribfile_Init
  260. ! ===
  261. ! Close gribfile, clear buffers
  262. !
  263. ! USAGE
  264. ! call Done( gribfile )
  265. !
  266. ! DESCRIPTION
  267. ! Interface around routine 'pbClose'.
  268. !
  269. subroutine gribfile_Done( F, status )
  270. ! --- in/out -----------------------
  271. type(TGribFile), intent(inout) :: F
  272. integer, intent(inout) :: status
  273. ! --- const ------------------------
  274. character(len=*), parameter :: rname = mname//', gribfile_Done'
  275. ! --- begin ------------------------
  276. ! close file:
  277. call pbClose( F%fu, status )
  278. if ( status /= 0 ) then
  279. write (gol,'("from closing grib file:")'); call goErr
  280. write (gol,'(" status : ",i6)') status; call goErr
  281. write (gol,'(" file : ",a)') trim(F%fname); call goErr
  282. TRACEBACK; status=1; return
  283. end if
  284. ! clear section 4 :
  285. if (associated(F%rsec4)) deallocate( F%rsec4 )
  286. end subroutine gribfile_Done
  287. ! ===
  288. ! Grib file opened ?
  289. logical function gribfile_Opened( gribfile )
  290. ! --- in/out ------------------------------
  291. type(TGribFile), intent(in) :: gribfile
  292. ! --- begin -------------------------
  293. inquire( unit=gribfile%fu, opened=gribfile_Opened )
  294. end function gribfile_Opened
  295. ! =============================================================
  296. subroutine gribfile_CopySections( gribIn, gribOut, status )
  297. ! ---in/out ------------------------------
  298. type(TGribFile), intent(in) :: gribIn
  299. type(TGribFile), intent(out) :: gribOut
  300. integer, intent(inout) :: status
  301. ! --- begin -------------------------
  302. !gribOut%isec0 = gribIn%isec0
  303. gribOut%isec1 = gribIn%isec1
  304. gribOut%isec2 = gribIn%isec2
  305. gribOut%rsec2 = gribIn%rsec2
  306. gribOut%isec3 = gribIn%isec3
  307. gribOut%isec4 = gribIn%isec4
  308. ! ok
  309. status = 0
  310. end subroutine gribfile_CopySections
  311. ! ***
  312. subroutine gribfile_CopyAllSections( gribIn, gribOut )
  313. ! ---in/out ------------------------------
  314. type(TGribFile), intent(in) :: gribIn
  315. type(TGribFile), intent(out) :: gribOut
  316. integer, intent(inout) :: status
  317. ! --- begin -------------------------
  318. !gribOut%isec0 = gribIn%isec0
  319. gribOut%isec1 = gribIn%isec1
  320. gribOut%isec2 = gribIn%isec2
  321. gribOut%rsec2 = gribIn%rsec2
  322. gribOut%isec3 = gribIn%isec3
  323. gribOut%isec4 = gribIn%isec4
  324. if ( associated(gribOut%rsec4) ) then
  325. if ( size(gribOut%rsec4) /= size(gribIn%rsec4) ) then
  326. deallocate( gribOut%rsec4 )
  327. allocate( gribOut%rsec4(size(gribIn%rsec4)) )
  328. end if
  329. else
  330. allocate( gribOut%rsec4(size(gribIn%rsec4)) )
  331. end if
  332. gribOut%rsec4 = gribIn%rsec4
  333. ! ok
  334. status = 0
  335. end subroutine gribfile_CopyAllSections
  336. ! ***
  337. subroutine gribfile_Clear( F )
  338. ! --- in/out -----------------------
  339. type(TGribFile), intent(out) :: F
  340. integer, intent(inout) :: status
  341. ! --- begin ------------------------
  342. ! Section 0 - Indicator Section.
  343. F%isec0 = 0
  344. ! Section 1 - Product Definition Section.
  345. F%isec1 = 0
  346. ! Section 2 - Grid Description Section.
  347. F%isec2 = 0
  348. F%rsec2 = 0.0
  349. ! Section 3 - ??
  350. F%isec3 = 0
  351. F%rsec3 = 0.0
  352. ! Section 4 - Binary Data Section.
  353. F%isec4 = 0
  354. if ( associated(F%rsec4) ) F%rsec4 = 0.0
  355. ! default number of bits
  356. F%isec4(2) = 24
  357. F%kword = 0
  358. ! ok
  359. status = 0
  360. end subroutine gribfile_Clear
  361. ! ==================================================================
  362. ! USAGE
  363. ! call ReadRecord( gribfile [,debug=0|1] [,status=status] )
  364. !
  365. ! DESCRIPTION
  366. ! Reads next grib record in buffers.
  367. !
  368. ! RETURN STATUS
  369. ! 0 : no error
  370. ! 1 : eof
  371. ! 2 : some error
  372. ! Execution might stop if other errors are encountered.
  373. !
  374. subroutine gribfile_ReadRecord( F, status )
  375. ! --- in/out -------------------------
  376. type(TGribFile), intent(inout) :: F
  377. integer, intent(out) :: status
  378. ! --- const --------------------------
  379. character(len=*), parameter :: rname = mname//'/grib_ReadRecord'
  380. ! --- local --------------------------
  381. integer, allocatable :: inbuff(:)
  382. integer :: length, len4
  383. ! --- begin --------------------------
  384. ! allocate array to store packed data:
  385. allocate( inbuff(ceiling(F%inbuff_bytes*1.0/kind(inbuff))) )
  386. ! read record:
  387. call pbGrib( F%fu, inbuff, size(inbuff)*kind(inbuff), length, status )
  388. select case ( status )
  389. case ( 0)
  390. ! no error !
  391. case (-1)
  392. write (gol,'("end-of-file is hit before a GRIB product is read")') ; call goErr
  393. write (gol,'(" grib file : ",a)') F%fname ; call goErr
  394. TRACEBACK; status=1; return
  395. case (-3)
  396. ! size of input buffer is not sufficient for the GRIB product !
  397. write (gol,'("size of input buffer is not sufficient for the GRIB product:")') ; call goErr
  398. write (gol,'(" current size : ",i8)') size(inbuff)*kind(inbuff) ; call goErr
  399. write (gol,'(" required : ",i8)') length ; call goErr
  400. write (gol,'(" grib file : ",a)') F%fname ; call goErr
  401. TRACEBACK; status=2; return
  402. case default
  403. write (gol,'("unknown return status from pbGrib : ",i6)') status ; call goErr
  404. write (gol,'(" grib file : ",a)') F%fname ; call goErr
  405. write (gol,'("in ",a)') rname ; call goErr
  406. TRACEBACK; status=2; return
  407. end select
  408. ! Decode.
  409. ! The array to hold the unpacked data may need to be 4 times
  410. ! as long as that for the packed data (or more!).
  411. len4 = ceiling(4*F%inbuff_bytes*1.0/kind(F%rsec4))
  412. if ( associated(F%rsec4) ) then
  413. if ( size(F%rsec4) < len4 ) then
  414. deallocate( F%rsec4 )
  415. allocate( F%rsec4(len4) )
  416. end if
  417. else
  418. allocate( F%rsec4(len4) )
  419. end if
  420. call GribEx(F%isec0,F%isec1,F%isec2,F%rsec2,F%isec3,F%rsec3,&
  421. F%isec4, F%rsec4, size(F%rsec4)*kind(F%rsec4), &
  422. inbuff, size(inbuff), F%kword, 'D' , status )
  423. if ( status /= 0 ) then
  424. select case ( status )
  425. case (-6)
  426. write (gol,'("in call to GribEx : ")'); call goErr
  427. write (gol,'(" found pseudo data in grib file: ",a)') F%fname; call goErr
  428. TRACEBACK; status=2; return
  429. case default
  430. write (gol,'("unknown return status from GribEx : ",i6)') status; call goErr
  431. TRACEBACK; status=2; return
  432. end select
  433. end if
  434. ! clear input buffer:
  435. deallocate( inbuff )
  436. ! ok
  437. status = 0
  438. end subroutine gribfile_ReadRecord
  439. ! ***
  440. ! encode and write grib sections
  441. subroutine gribfile_WriteRecord( F, status )
  442. ! --- in/out --------------------
  443. type(TGribFile), intent(in) :: F
  444. integer, intent(out) :: status
  445. ! --- const ---------------------
  446. character(len=*), parameter :: rname = mname//'/gribfile_WriteRecord'
  447. ! --- local ---------------------
  448. integer, allocatable :: outbuff(:)
  449. ! --- begin ---------------------
  450. ! *** encode
  451. status = 1
  452. allocate( outbuff(size(F%rsec4)) )
  453. call GribEx(F%isec0,F%isec1,F%isec2,F%rsec2,F%isec3,F%rsec3,&
  454. F%isec4, F%rsec4, size(F%rsec4)*kind(F%rsec4), &
  455. outbuff, size(outbuff), F%kword, 'C' , status )
  456. select case ( status )
  457. case (-2)
  458. write (gol,'("WARNING: bitmap was encountered with all bits set to 1")'); call goPr
  459. case (-3)
  460. write (gol,'("WARNING: predefined bitmap was encountered.")'); call goPr
  461. case (-4)
  462. write (gol,'("WARNING: bitmap was encountered.")'); call goPr
  463. case (-5)
  464. write (gol,'("WARNING: bitmap was encountered and the data has not been decoded.")'); call goPr
  465. case (-6)
  466. write (gol,'("WARNING: ECMWF pseudo-GRIB data (TIDE or BUDG) has been encountered.")'); call goPr
  467. case ( 0 )
  468. ! ok
  469. case default
  470. write (gol,'("unknown status from GribEx : ",i6)') status
  471. TRACEBACK; status=1; return
  472. end select
  473. ! *** write GRIB record
  474. ! PBWRITE: Writes a block of bytes to a file.
  475. ! status : -1 = Could not write to file.
  476. ! >= 0 = Number of bytes written.
  477. !
  478. call pbWrite( F%fu, outbuff, F%isec0(1), status )
  479. if ( status == -1 ) then
  480. write (gol,'("could not write to file")'); call goErr
  481. write (gol,'("in ",a)') rname; status=1; return
  482. else if ( status >= 0 ) then
  483. ! bytes written correctly
  484. else
  485. write (gol,'("unknown status from GribEx : ",i6)') status; call goErr
  486. write (gol,'("in ",a)') rname; status=1; return
  487. end if
  488. ! done
  489. deallocate( outbuff )
  490. ! ok
  491. status = 0
  492. end subroutine gribfile_WriteRecord
  493. ! ============================================================
  494. ! Extract data from grib sections.
  495. ! Optional arguments are passed to read parameter id, date, etc.
  496. ! If the same option is preceded by 'check_', an error
  497. ! message is written if the grib file does not match
  498. !
  499. ! pid : parameter identifier (integer number)
  500. !
  501. ! level : index of hybride level
  502. !
  503. ! reftime : 5 element integer array : yy, mm, dd, hh, min
  504. ! timerange : 4 element ingeger array : unit, val1, val2, indicator
  505. !
  506. subroutine gribfile_Get( F, status, &
  507. model_id, pid, pidShortName, &
  508. levtype, level, nlev, hyb_a, hyb_b, &
  509. reftime, timerange, &
  510. gridtype, &
  511. ll, &
  512. lon_first, lon_last, lon_inc, lon_n, &
  513. lat_first, lat_last, lat_inc, lat_n, &
  514. T, sh, &
  515. N, gg )
  516. use file_grib_base, only : pidName
  517. use file_grib_base, only : gridtype_ll, gridtype_gg, gridtype_sh
  518. ! --- in/out -------------------------
  519. type(TGribFile), intent(in) :: F
  520. integer, intent(out) :: status
  521. integer, intent(out), optional :: model_id
  522. integer, intent(out), optional :: pid
  523. character(72), intent(out), optional :: pidShortName
  524. integer, intent(out), optional :: levtype, level, nlev
  525. real, intent(out), optional :: hyb_a(:), hyb_b(:)
  526. integer, intent(out), optional :: reftime(5)
  527. integer, intent(out), optional :: timerange(4)
  528. integer, intent(out), optional :: gridtype
  529. real, intent(out), optional :: lon_first, lon_last, lon_inc
  530. integer, intent(out), optional :: lon_n
  531. real, intent(out), optional :: lat_first, lat_last, lat_inc
  532. integer, intent(out), optional :: lat_n
  533. real, intent(out), optional :: ll(:,:)
  534. integer, intent(out), optional :: T
  535. complex, intent(out), optional :: sh(:)
  536. integer, intent(out), optional :: N
  537. real, intent(out), optional :: gg(:)
  538. ! --- const --------------------------------------
  539. character(len=*), parameter :: name = mname//'/gribfile_Get'
  540. ! --- local --------------------------
  541. integer :: grib_reftime(5)
  542. integer :: grib_timerange(4)
  543. integer :: base
  544. integer :: grib_n
  545. real, allocatable :: rsec4_adhoc(:)
  546. ! --- begin --------------------------
  547. ! -- model id
  548. if ( present( model_id ) ) then
  549. model_id = F%isec1(3)
  550. end if
  551. ! -- parameter
  552. if ( present( pid ) ) then
  553. pid = F%isec1(6)
  554. end if
  555. ! -- parameter short name
  556. if ( present( pidShortName ) ) then
  557. pidShortName = pidName(F%isec1(6))
  558. end if
  559. ! -- level
  560. if ( present(levtype) ) levtype = F%isec1(7)
  561. if ( present(level ) ) level = F%isec1(8)
  562. ! -- Vertical Coordinate Parameters
  563. if ( present(hyb_a) .or. present(hyb_b) ) then
  564. if ( .not. (present(hyb_a) .and. present(hyb_b)) ) then
  565. write (gol,'("extract both hybride params or none")'); call goErr
  566. TRACEBACK; status=1; return
  567. end if
  568. if ( F%isec2(12) /= size(hyb_a) + size(hyb_b) ) then
  569. write (gol,'("numbers of hybride parameters do not match:")') ; call goErr
  570. write (gol,'(" expected : ",i6)') size(hyb_a)+size(hyb_b) ; call goErr
  571. write (gol,'(" found : ",i6)') F%isec2(12) ; call goErr
  572. TRACEBACK; status=1; return
  573. end if
  574. base = 10 ; hyb_a = F%rsec2(base+1:base+size(hyb_a))
  575. base = 10+size(hyb_a); hyb_b = F%rsec2(base+1:base+size(hyb_b))
  576. end if
  577. ! number of levels
  578. if ( present(nlev) ) then
  579. nlev = F%isec2(12)/2 - 1
  580. end if
  581. ! -- reference time
  582. if ( present(reftime) ) then
  583. ! extract reference time:
  584. ! extract reference time:
  585. grib_reftime(1) = (F%isec1(21)-1)*100 + F%isec1(10) ! year incl. century
  586. grib_reftime(2) = F%isec1(11) ! month
  587. grib_reftime(3) = F%isec1(12) ! day
  588. grib_reftime(4) = F%isec1(13) ! hour
  589. grib_reftime(5) = F%isec1(14) ! minutes
  590. reftime = grib_reftime
  591. end if
  592. ! -- time range
  593. if ( present(timerange) ) then
  594. grib_timerange(1:4) = F%isec1(15:18)
  595. timerange = grib_timerange
  596. end if
  597. ! --- grid
  598. if ( present(gridtype) ) gridtype = F%isec2( 1)
  599. if ( present(lon_n) ) lon_n = F%isec2( 2)
  600. if ( present(lat_n) ) lat_n = F%isec2( 3)
  601. if ( present(lat_first) ) lat_first = F%isec2( 4) / 1000.0
  602. if ( present(lon_first) ) lon_first = F%isec2( 5) / 1000.0
  603. if ( present(lat_last) ) lat_last = F%isec2( 7) / 1000.0
  604. if ( present(lon_last) ) lon_last = F%isec2( 8) / 1000.0
  605. if ( present(lon_inc) ) lon_inc = F%isec2( 9) / 1000.0
  606. if ( present(lat_inc) ) lat_inc = F%isec2(10) / 1000.0
  607. ! -- lat/lon grid
  608. if ( present(ll) ) then
  609. !call Check( F, gridtype=gridtype_ll )
  610. ! >>> no recursive call >>>>>>>>>>>>>>
  611. grib_n = F%isec2(1)
  612. if ( grib_n /= gridtype_ll ) then
  613. write (gol,'("grid types do not match:")') ; call goErr
  614. write (gol,'(" expected : ",i4," (ll)")') gridtype_ll ; call goErr
  615. write (gol,'(" found : ",i4)') grib_n ; call goErr
  616. TRACEBACK; status=1; return
  617. end if
  618. ! <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  619. if ( (size(ll,1)/=F%isec2(2)) .or. (size(ll,2)/=F%isec2(3)) ) then
  620. write (gol,'("grid sizes do not match:")') ; call goErr
  621. write (gol,'(" expected : ",i4," x ",i4)') size(ll,1), size(ll,2) ; call goErr
  622. write (gol,'(" found : ",i4," x ",i4)') F%isec2(2), F%isec2(3) ; call goErr
  623. TRACEBACK; status=1; return
  624. end if
  625. if ( .not. associated(F%rsec4) ) then
  626. write (gol,'("no grib section 4 read")'); call goErr
  627. TRACEBACK; status=1; return
  628. end if
  629. ll = reshape( F%rsec4(1:size(ll)), shape(ll) )
  630. end if
  631. ! -- gaussian lat/lon grid
  632. if ( present(N) ) then
  633. !call Check( F, gridtype=gridtype_gg )
  634. ! >>> no recursive call >>>>>>>>>>>>>>
  635. grib_n = F%isec2(1)
  636. if ( grib_n /= gridtype_gg ) then
  637. write (gol,'("grid types do not match:")') ; call goErr
  638. write (gol,'(" expected : ",i4," (gg)")') gridtype_gg ; call goErr
  639. write (gol,'(" found : ",i4)') grib_n ; call goErr
  640. TRACEBACK; status=1; return
  641. end if
  642. ! <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  643. N = F%isec2(10)
  644. end if
  645. if ( present(gg) ) then
  646. !call Check( F, gridtype=gridtype_gg )
  647. ! >>> no recursive call >>>>>>>>>>>>>>
  648. grib_n = F%isec2(1)
  649. if ( grib_n /= gridtype_gg ) then
  650. write (gol,'("grid typess do not match:")') ; call goErr
  651. write (gol,'(" expected : ",i4," (gg)")') gridtype_gg ; call goErr
  652. write (gol,'(" found : ",i4)') grib_n ; call goErr
  653. TRACEBACK
  654. status=1; return
  655. end if
  656. ! <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  657. if ( size(gg) /= F%isec4(1) ) then
  658. write (gol,'("gg grid sizes do not match:")') ; call goErr
  659. write (gol,'(" expected : ",i4)') size(gg) ; call goErr
  660. write (gol,'(" found : ",i4)') F%isec4(1) ; call goErr
  661. TRACEBACK; status=1; return
  662. end if
  663. ! data present ?
  664. if ( .not. associated(F%rsec4) ) then
  665. write (gol,'("no grib section 4 read")'); call goErr
  666. TRACEBACK; status=1; return
  667. end if
  668. gg = F%rsec4(1:size(gg))
  669. end if
  670. ! -- spectral coef
  671. if ( present(T) ) then
  672. !call Check( F, gridtype=gridtype_sh )
  673. ! >>> no recursive call >>>>>>>>>>>>>>
  674. grib_n = F%isec2(1)
  675. if ( grib_n /= gridtype_sh ) then
  676. write (gol,'("grid types do not match:")') ; call goErr
  677. write (gol,'(" expected : ",i4," (sh)")') gridtype_sh ; call goErr
  678. write (gol,'(" found : ",i4)') grib_n ; call goErr
  679. TRACEBACK; status=1; return
  680. end if
  681. ! <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  682. T = F%isec2(4)
  683. end if
  684. if ( present(sh) ) then
  685. !call Check( F, gridtype=gridtype_sh )
  686. ! >>> no recursive call >>>>>>>>>>>>>>
  687. grib_n = F%isec2(1)
  688. if ( grib_n /= gridtype_sh ) then
  689. write (gol,'("grid typess do not match:")') ; call goErr
  690. write (gol,'(" expected : ",i4," (sh)")') gridtype_sh ; call goErr
  691. write (gol,'(" found : ",i4)') grib_n ; call goErr
  692. TRACEBACK; status=1; return
  693. end if
  694. ! <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  695. ! check number of elements; complex is 2 elements !
  696. if ( size(sh) /= F%isec4(1)/2 ) then
  697. write (gol,'("numbers of spectral coefficients do not match:")') ; call goErr
  698. write (gol,'(" expected : ",i6)') size(sh) ; call goErr
  699. write (gol,'(" found : ",i6)') F%isec4(1)/2 ; call goErr
  700. TRACEBACK; status=1; return
  701. end if
  702. ! convert from real to complex:
  703. ! >>> NOTE: this call lets 'f90 -C' fail on SUN compiler !
  704. !sh = transfer( F%rsec4(1:F%isec4(1)), (/(0.0,0.0)/) )
  705. ! <<< fix >>>
  706. allocate( rsec4_adhoc(F%isec4(1)) )
  707. rsec4_adhoc = F%rsec4(1:F%isec4(1))
  708. sh = transfer( rsec4_adhoc, (/(0.0,0.0)/) )
  709. deallocate( rsec4_adhoc )
  710. ! <<<
  711. end if
  712. ! ok
  713. status = 0
  714. end subroutine gribfile_Get
  715. ! ===
  716. ! NOTE
  717. ! Do not check hybride coeff; different number of bits etc
  718. ! cause small differences ...
  719. subroutine gribfile_Check( F, status, debug, &
  720. model_id, pid, &
  721. levtype, level, &
  722. reftime, timerange, &
  723. gridtype, &
  724. lon_first, lon_last, lon_inc, lon_n, &
  725. lat_first, lat_last, lat_inc, lat_n, &
  726. T )
  727. ! --- in/out -------------------------
  728. type(TGribFile), intent(in) :: F
  729. integer, intent(out) :: status
  730. integer, intent(in), optional :: debug
  731. integer, intent(in), optional :: model_id
  732. integer, intent(in), optional :: pid
  733. integer, intent(in), optional :: levtype, level
  734. !real, intent(in), optional :: hyb_a(:), hyb_b(:)
  735. integer, intent(in), optional :: reftime(5)
  736. integer, intent(in), optional :: timerange(4)
  737. integer, intent(in), optional :: gridtype
  738. integer, intent(in), optional :: lon_first, lon_last, lon_inc, lon_n
  739. integer, intent(in), optional :: lat_first, lat_last, lat_inc, lat_n
  740. integer, intent(in), optional :: T
  741. ! --- const --------------------------------------
  742. character(len=*), parameter :: name = mname//'/gribfile_Check'
  743. ! --- local --------------------------
  744. logical :: match
  745. integer :: grib_model_id
  746. integer :: grib_pid
  747. integer :: grib_levtype, grib_level
  748. integer :: grib_reftime(5)
  749. integer :: grib_timerange(4)
  750. integer :: grib_n
  751. integer :: grib_T
  752. logical :: verbose
  753. ! --- begin --------------------------
  754. ! write error messages ?
  755. verbose = .false.
  756. if ( present(debug) ) verbose = debug > 0
  757. ! ok by default
  758. status = 0
  759. ! -- check model id
  760. if ( present( model_id ) ) then
  761. call Get( F, status, model_id=grib_model_id )
  762. if (status/=0) then
  763. TRACEBACK; status=1; return
  764. end if
  765. if ( grib_model_id /= model_id ) then
  766. if ( verbose ) then
  767. write (gol,'("model id''s do not match:")') ; call goErr
  768. write (gol,'(" expected : ",i4)') model_id ; call goErr
  769. write (gol,'(" found : ",i4)') grib_model_id ; call goErr
  770. write (gol,'(" in ",a)') trim(F%fname) ; call goErr
  771. TRACEBACK
  772. end if
  773. status=status+1
  774. end if
  775. end if
  776. ! -- check parameter
  777. if ( present( pid ) ) then
  778. call Get( F, status, pid=grib_pid )
  779. if (status/=0) then
  780. TRACEBACK ; status=1; return
  781. end if
  782. if ( grib_pid /= pid ) then
  783. if ( verbose ) then
  784. write (gol,'("parameter id''s do not match:")') ; call goErr
  785. write (gol,'(" expected : ",i6)') pid ; call goErr
  786. write (gol,'(" found : ",i6)') grib_pid ; call goErr
  787. write (gol,'(" in ",a)') trim(F%fname) ; call goErr
  788. TRACEBACK
  789. end if
  790. status=status+1
  791. end if
  792. end if
  793. ! -- check level
  794. if ( present(levtype) ) then
  795. call Get( F, status, levtype=grib_levtype )
  796. if (status/=0) then
  797. TRACEBACK ; status=1; return
  798. end if
  799. if ( grib_levtype /= levtype ) then
  800. if ( verbose ) then
  801. write (gol,'("level types do not match:")') ; call goErr
  802. write (gol,'(" expected : ",i6)') levtype ; call goErr
  803. write (gol,'(" found : ",i6)') grib_levtype ; call goErr
  804. write (gol,'(" in ",a)') trim(F%fname) ; call goErr
  805. TRACEBACK
  806. end if
  807. status=status+1
  808. end if
  809. end if
  810. if ( present(level) ) then
  811. call Get( F, status, level=grib_level )
  812. if (status/=0) then
  813. TRACEBACK ; status=1; return
  814. end if
  815. if ( grib_level /= level ) then
  816. if ( verbose ) then
  817. write (gol,'("levels do not match:")') ; call goErr
  818. write (gol,'(" expected : ",i6)') level ; call goErr
  819. write (gol,'(" found : ",i6)') grib_level ; call goErr
  820. write (gol,'(" in ",a)') trim(F%fname) ; call goErr
  821. TRACEBACK
  822. end if
  823. status=status+1
  824. end if
  825. end if
  826. ! -- check reference time
  827. ! extract reference time:
  828. grib_reftime(1) = (F%isec1(21)-1)*100 + F%isec1(10) ! year incl. century
  829. grib_reftime(2) = F%isec1(11) ! month
  830. grib_reftime(3) = F%isec1(12) ! day
  831. grib_reftime(4) = F%isec1(13) ! hour
  832. grib_reftime(5) = F%isec1(14) ! minutes
  833. if ( present(reftime) ) then
  834. if ( any( grib_reftime /= reftime ) ) then
  835. if ( verbose ) then
  836. write (gol,'("reference times do not match:")') ; call goErr
  837. write (gol,'(" expected : ",i4,4i3)') reftime ; call goErr
  838. write (gol,'(" found : ",i4,4i3)') grib_reftime ; call goErr
  839. write (gol,'(" in ",a)') trim(F%fname) ; call goErr
  840. TRACEBACK
  841. end if
  842. status=status+1
  843. end if
  844. end if
  845. ! -- check time range
  846. grib_timerange(1:4) = F%isec1(15:18)
  847. if ( present(timerange) ) then
  848. if ( any( grib_timerange /= timerange ) ) then
  849. if ( verbose ) then
  850. write (gol,'("time ranges do not match:")') ; call goErr
  851. write (gol,'(" expected : ",4i3)') timerange ; call goErr
  852. write (gol,'(" found : ",4i3)') grib_timerange ; call goErr
  853. write (gol,'(" in ",a)') trim(F%fname) ; call goErr
  854. TRACEBACK
  855. end if
  856. status=status+1
  857. end if
  858. end if
  859. ! --- check grid
  860. grib_n = F%isec2(1)
  861. if ( present(gridtype) ) then
  862. if ( grib_n /= gridtype ) then
  863. if ( verbose ) then
  864. write (gol,'("gridtypes do not match:")') ; call goErr
  865. write (gol,'(" expected : ",i6)') gridtype ; call goErr
  866. write (gol,'(" found : ",i6)') grib_n ; call goErr
  867. write (gol,'(" in ",a)') trim(F%fname) ; call goErr
  868. TRACEBACK
  869. end if
  870. status=status+1
  871. end if
  872. end if
  873. grib_n = F%isec2(2)
  874. if ( present(lon_n) ) then
  875. if ( grib_n /= lon_n ) then
  876. if ( verbose ) then
  877. write (gol,'("number of longitudes do not match:")') ; call goErr
  878. write (gol,'(" expected : ",i6)') lon_n ; call goErr
  879. write (gol,'(" found : ",i6)') grib_n ; call goErr
  880. write (gol,'(" in ",a)') trim(F%fname) ; call goErr
  881. TRACEBACK
  882. end if
  883. status=status+1
  884. end if
  885. end if
  886. grib_n = F%isec2(3)
  887. if ( present(lat_n) ) then
  888. if ( grib_n /= lat_n ) then
  889. if ( verbose ) then
  890. write (gol,'("number of latitudes do not match:")') ; call goErr
  891. write (gol,'(" expected : ",i6)') lat_n ; call goErr
  892. write (gol,'(" found : ",i6)') grib_n ; call goErr
  893. write (gol,'(" in ",a)') trim(F%fname) ; call goErr
  894. TRACEBACK
  895. end if
  896. status=status+1
  897. end if
  898. end if
  899. grib_n = F%isec2(4)
  900. if ( present(lat_first) ) then
  901. if ( grib_n /= lat_first ) then
  902. if ( verbose ) then
  903. write (gol,'("first latitudes do not match:")') ; call goErr
  904. write (gol,'(" expected : ",i6)') lat_first ; call goErr
  905. write (gol,'(" found : ",i6)') grib_n ; call goErr
  906. write (gol,'(" in ",a)') trim(F%fname) ; call goErr
  907. TRACEBACK
  908. end if
  909. status=status+1
  910. end if
  911. end if
  912. grib_n = F%isec2(5)
  913. if ( present(lon_first) ) then
  914. if ( grib_n /= lon_first ) then
  915. if ( verbose ) then
  916. write (gol,'("first longitudes do not match:")') ; call goErr
  917. write (gol,'(" expected : ",i6)') lon_first ; call goErr
  918. write (gol,'(" found : ",i6)') grib_n ; call goErr
  919. write (gol,'(" in ",a)') trim(F%fname) ; call goErr
  920. TRACEBACK
  921. end if
  922. status=status+1
  923. end if
  924. end if
  925. grib_n = F%isec2(7)
  926. if ( present(lat_last) ) then
  927. if ( grib_n /= lat_last ) then
  928. if ( verbose ) then
  929. write (gol,'("last latitudes do not match:")') ; call goErr
  930. write (gol,'(" expected : ",i6)') lat_last ; call goErr
  931. write (gol,'(" found : ",i6)') grib_n ; call goErr
  932. write (gol,'(" in ",a)') trim(F%fname) ; call goErr
  933. TRACEBACK
  934. end if
  935. status=status+1
  936. end if
  937. end if
  938. grib_n = F%isec2(8)
  939. if ( present(lon_last) ) then
  940. if ( grib_n /= lon_last ) then
  941. if ( verbose ) then
  942. write (gol,'("last longitudes do not match:")') ; call goErr
  943. write (gol,'(" expected : ",i6)') lon_last ; call goErr
  944. write (gol,'(" found : ",i6)') grib_n ; call goErr
  945. write (gol,'(" in ",a)') trim(F%fname) ; call goErr
  946. TRACEBACK
  947. end if
  948. status=status+1
  949. end if
  950. end if
  951. grib_n = F%isec2(9)
  952. if ( present(lon_inc) ) then
  953. if ( grib_n /= lon_inc ) then
  954. if ( verbose ) then
  955. write (gol,'("longitude increments do not match:")') ; call goErr
  956. write (gol,'(" expected : ",i6)') lon_inc ; call goErr
  957. write (gol,'(" found : ",i6)') grib_n ; call goErr
  958. write (gol,'(" in ",a)') trim(F%fname) ; call goErr
  959. TRACEBACK
  960. end if
  961. status=status+1
  962. end if
  963. end if
  964. grib_n = F%isec2(10)
  965. if ( present(lat_inc) ) then
  966. if ( grib_n /= lat_inc ) then
  967. if ( verbose ) then
  968. write (gol,'("latitude increments do not match:")') ; call goErr
  969. write (gol,'(" expected : ",i6)') lat_inc ; call goErr
  970. write (gol,'(" found : ",i6)') grib_n ; call goErr
  971. write (gol,'(" in ",a)') trim(F%fname) ; call goErr
  972. TRACEBACK ; status=1; return
  973. end if
  974. status=status+1
  975. end if
  976. end if
  977. ! --- check truncation
  978. if ( present(T) ) then
  979. grib_T = F%isec2(4)
  980. if ( grib_T /= T ) then
  981. if ( verbose ) then
  982. write (gol,'("spectral truncations do not match:")') ; call goErr
  983. write (gol,'(" expected : ",i6)') T ; call goErr
  984. write (gol,'(" found : ",i6)') grib_T ; call goErr
  985. write (gol,'(" in ",a)') trim(F%fname) ; call goErr
  986. TRACEBACK
  987. end if
  988. status=status+1
  989. end if
  990. end if
  991. ! return with status equal to number of failures
  992. end subroutine gribfile_Check
  993. ! ===
  994. ! fill gribsections
  995. subroutine gribfile_Set( F, status, model_id, pid, &
  996. levtype, hyb_a, hyb_b, level, &
  997. reftime, timerange, &
  998. gridtype, &
  999. ll, &
  1000. lon_first, lon_inc, lon_last, lon_n, &
  1001. lat_first, lat_inc, lat_last, lat_n, &
  1002. scanning_mode, nbits )
  1003. ! --- in/out ----------------------
  1004. type(TGribFile), intent(inout) :: F
  1005. integer, intent(out) :: status
  1006. integer, intent(in), optional :: model_id
  1007. integer, intent(in), optional :: pid
  1008. integer, intent(in), optional :: levtype
  1009. integer, intent(in), optional :: level
  1010. real, intent(in), optional :: hyb_a(:), hyb_b(:)
  1011. integer, intent(in), optional :: reftime(5) ! (/yy,mm,dd,hh,min/)
  1012. integer, intent(in), optional :: timerange(4)
  1013. integer, intent(in), optional :: gridtype
  1014. real, intent(in), optional :: ll(:,:)
  1015. integer, intent(in), optional :: lon_n, lat_n
  1016. integer, intent(in), optional :: lon_first, lon_inc, lon_last ! mili degree
  1017. integer, intent(in), optional :: lat_first, lat_inc, lat_last ! mili degree
  1018. integer, intent(in), optional :: scanning_mode
  1019. integer, intent(in), optional :: nbits
  1020. ! --- const --------------------------------------
  1021. character(len=*), parameter :: rname = mname//'/gribfile_Set'
  1022. ! --- local ------------------------
  1023. integer :: base
  1024. ! --- begin ------------------------
  1025. ! Section 1 - Product Definition Section.
  1026. ! ---------------------------------------
  1027. ! Code Table 2 Version Number.
  1028. F%isec1(1) = 128
  1029. ! Originating centre identifier.
  1030. F%isec1(2) = 98 ! ECMWF
  1031. ! Model identification.
  1032. if ( present(model_id) ) F%isec1(3) = model_id
  1033. ! Grid definition.
  1034. F%isec1(4) = 255 ! ???
  1035. ! Flag (Code Table 1) 10000000
  1036. F%isec1(5) = 128 ! ???
  1037. ! Parameter identifier (Code Table 2, NO LOCAL TABLE FOR KNMI)
  1038. if ( present(pid) ) F%isec1(6) = pid
  1039. ! Type of level (Code Table 3). 109 ; hybride
  1040. ! Value 1 of level (Code Table 3). 1
  1041. ! Value 2 of level (Code Table 3). 0
  1042. if ( present(levtype) ) F%isec1(7) = levtype
  1043. if ( present(level ) ) F%isec1(8) = level
  1044. F%isec1(9) = 0
  1045. ! 10. Year of reference time of data.
  1046. ! 11. Month of reference time of data.
  1047. ! 12. Day of reference time of data.
  1048. ! 13. Hour of reference time of data.
  1049. ! 14. Minute of reference time of data.
  1050. ! 21. Century of reference time of data.
  1051. if ( present(reftime) ) then
  1052. F%isec1(21) = int(reftime(1)/100.0) + 1
  1053. F%isec1(10) = mod(reftime(1),100)
  1054. F%isec1(11:14) = reftime(2:5)
  1055. end if
  1056. ! Time unit (Code Table 4).
  1057. ! Time range one.
  1058. ! Time range two.
  1059. ! Time range indicator (Code Table 5)
  1060. if ( present(timerange) ) F%isec1(15:18) = timerange
  1061. ! Number averaged.
  1062. F%isec1(19) = 0
  1063. ! Number missing from average.
  1064. F%isec1(20) = 0
  1065. ! Section 2 - Grid Description Section.
  1066. ! -------------------------------------
  1067. ! (Southern latitudes and Western longitudes are negative.)
  1068. ! 1. Data represent type (Table 6) 0 = lat/long
  1069. if ( present(gridtype) ) F%isec2(1) = gridtype
  1070. ! 2. Number of points along a parallel. 144
  1071. ! 3. Number of points along a meridian. 72
  1072. ! 4. Latitude of first grid point. -88750 mdeg
  1073. ! 5. Longitude of first grid point. -180000 mdeg
  1074. ! 6. Resolution and components flag. 10000000
  1075. ! 7. Latitude of last grid point. 88750
  1076. ! 8. Longitude of last grid point. 177500
  1077. ! 9. i direction (East-West) increment. 2500
  1078. ! 10. j direction (North-South) increment. 2500
  1079. if ( present(lon_n) .or. present(lon_first) .or. present(lon_last) .or. present(lon_inc) ) then
  1080. if ( present(lon_n) ) F%isec2(2) = lon_n
  1081. if ( present(lon_first) ) F%isec2(5) = lon_first
  1082. if ( present(lon_last) ) F%isec2(8) = lon_last
  1083. if ( present(lon_inc) ) F%isec2(9) = lon_inc
  1084. if ( present(lon_first) .and. present(lon_last) .and. present(lon_inc) ) then
  1085. ! lon_n
  1086. F%isec2(2) = (lon_last-lon_first)/lon_inc + 1
  1087. else if ( present(lon_n) .and. present(lon_first) .and. present(lon_inc) ) then
  1088. ! lon_last
  1089. F%isec2(8) = lon_first + lon_inc*(lon_n-1)
  1090. else if ( present(lon_n) .and. present(lon_first) .and. present(lon_last) ) then
  1091. ! lon_inc
  1092. F%isec2(9) = (lon_last-lon_first)/lon_n
  1093. else
  1094. write (gol,'("expected at least 3 of lon_n,lon_first,lon_last,lon_inc")'); call goErr
  1095. TRACEBACK; status=1; return
  1096. end if
  1097. end if
  1098. if ( present(lat_n) .or. present(lat_first) .or. present(lat_last) .or. present(lat_inc) ) then
  1099. if ( present(lat_n) ) F%isec2(3) = lat_n
  1100. if ( present(lat_first) ) F%isec2(4) = lat_first
  1101. if ( present(lat_last) ) F%isec2(7) = lat_last
  1102. if ( present(lat_inc) ) F%isec2(10) = lat_inc
  1103. if ( present(lat_first) .and. present(lat_last) .and. present(lat_inc) ) then
  1104. ! lat_n
  1105. F%isec2(3) = (lat_last-lat_first)/lat_inc + 1
  1106. else if ( present(lat_n) .and. present(lat_first) .and. present(lat_inc) ) then
  1107. ! lat_last
  1108. F%isec2(7) = lat_first + lat_inc*(lat_n-1)
  1109. else if ( present(lat_n) .and. present(lat_first) .and. present(lat_last) ) then
  1110. ! lat_inc
  1111. F%isec2(10) = (lat_last-lat_first)/lat_n
  1112. else
  1113. write (gol,'("expected at least 3 of lon_n,lon_first,lon_last,lon_inc")'); call goErr
  1114. TRACEBACK; status=1; return
  1115. end if
  1116. end if
  1117. F%isec2(6) = 128
  1118. ! 11. Scanning mode flags (Code Table 8)
  1119. ! bit 1 : 0 = west to east , 1 = east to west
  1120. ! bit 2 : 0 = north to south , 1 = south to north
  1121. ! bit 3 : 0 = store lon rows , 1 = store lat columns
  1122. ! default scanning mode 0
  1123. !F%isec2(11) = 0
  1124. !if ( F%isec2(8) < F%isec2(5) ) F%isec2(11) = F%isec2(11) + 4 ! east to west
  1125. !if ( F%isec2(7) > F%isec2(4) ) F%isec2(11) = F%isec2(11) + 2 ! south to north
  1126. ! PROBLEM >>> GribEx seems to accept scanning mode 0 only ..
  1127. F%isec2(11) = 0
  1128. ! <<<
  1129. if ( present(scanning_mode) ) F%isec2(11) = scanning_mode
  1130. ! 12. Number of vertical coordinate parameters.
  1131. ! Vertical Coordinate Parameters strored in rsec2, start in element 11
  1132. if ( present(hyb_a) .and. present(hyb_b) ) then
  1133. F%isec2(12) = size(hyb_a) + size(hyb_b)
  1134. base = 10 ; F%rsec2(base+1:base+size(hyb_a)) = hyb_a
  1135. base = 10+size(hyb_a); F%rsec2(base+1:base+size(hyb_b)) = hyb_b
  1136. end if
  1137. ! set rest to zero for safety
  1138. F%isec2(13:size(F%isec2)) = 0
  1139. ! Section 4 - Binary Data Section.
  1140. ! -------------------------------------
  1141. ! 1. Number of data values coded/decoded. 11556
  1142. ! 2. Number of bits per data value. 16
  1143. !
  1144. ! 3. Type of data (0=grid pt, 128=spectral). 128
  1145. ! 4. Type of packing (0=simple, 64=complex). 64
  1146. ! 5. Type of data (0=float, 32=integer). 0
  1147. ! 6. Additional flags (0=none, 16=present). 0
  1148. ! 7. Reserved. 0
  1149. ! 8. Number of values (0=single, 64=matrix). 0
  1150. ! 9. Secondary bit-maps (0=none, 32=present). 0
  1151. ! 10. Values width (0=constant, 16=variable). 0
  1152. ! 11. Byte offset of start of packed data (N). 2214
  1153. ! 12. Power (P * 1000). 500
  1154. ! 13. Pentagonal resolution parameter J for subset. 20
  1155. ! 14. Pentagonal resolution parameter K for subset. 20
  1156. ! 15. Pentagonal resolution parameter M for subset. 20
  1157. ! set lat/lon grid:
  1158. ! 3. Type of data (0=grid pt, 128=spectral). 0
  1159. ! 4. Type of packing (0=simple, 64=complex). 0
  1160. ! 5. Type of data (0=float, 32=integer). 0
  1161. ! 6. Additional flags (0=none, 16=present). 0
  1162. ! 7. Reserved. 0
  1163. ! 8. Number of values (0=single, 64=matrix). 0
  1164. ! 9. Secondary bit-maps (0=none, 32=present). 0
  1165. ! 10. Values width (0=constant, 16=variable). 0
  1166. if ( present(ll) ) then
  1167. ! check grid size:
  1168. if ( F%isec2(2) /= size(ll,1) .or. F%isec2(3) /= size(ll,2) ) then
  1169. write (gol,'("grid sizes do not match:")'); call goErr
  1170. write (gol,'(" expected : ",i4," x ",i4)') size(ll,1), size(ll,2); call goErr
  1171. write (gol,'(" found : ",i4," x ",i4)') F%isec2(2), F%isec2(3); call goErr
  1172. TRACEBACK; status=1; return
  1173. end if
  1174. ! 1. Number of data values coded/decoded. 11556
  1175. F%isec4(1) = size(ll)
  1176. ! 3. Type of data (0=grid pt, 128=spectral). 0
  1177. ! 4. Type of packing (0=simple, 64=complex). 0
  1178. ! 5. Type of data (0=float, 32=integer). 0
  1179. ! 6. Additional flags (0=none, 16=present). 0
  1180. ! 7. Reserved. 0
  1181. ! 8. Number of values (0=single, 64=matrix). 0
  1182. ! 9. Secondary bit-maps (0=none, 32=present). 0
  1183. ! 10. Values width (0=constant, 16=variable). 0
  1184. F%isec4(3:10) = 0
  1185. ! allocate space to store field
  1186. ! NOTE: allocate extra, sometimes errors if fit exately!
  1187. if ( associated(F%rsec4) ) then
  1188. if ( size(F%rsec4) < size(ll) ) then
  1189. deallocate( F%rsec4 )
  1190. allocate( F%rsec4(size(ll)*2) )
  1191. end if
  1192. else
  1193. allocate( F%rsec4(size(ll)*2) )
  1194. end if
  1195. ! convert to 1D array:
  1196. F%rsec4(1:size(ll)) = reshape( ll, (/ size(ll) /) )
  1197. end if
  1198. ! 2. Number of bits per data value. 16
  1199. if ( present(nbits) ) F%isec4(2) = nbits
  1200. ! ok
  1201. status = 0
  1202. end subroutine gribfile_Set
  1203. end module file_grib_gribex