file_ncg.F90 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808
  1. !
  2. ! NCEP Grib files.
  3. !
  4. ! Grib tables: http://www.nco.ncep.noaa.gov/pmb/docs/on388/
  5. !
  6. module file_ncg
  7. implicit none
  8. ! --- in/out ----------------------------------
  9. private
  10. public :: TNcepGrib
  11. public :: Init, Done
  12. public :: ReadRecord
  13. public :: CheckRecord
  14. public :: ListRecord
  15. public :: Get
  16. ! --- const -----------------------------------------------
  17. character(len=*), parameter :: mname = 'file_ncg'
  18. ! --- types ----------------------------------
  19. type TNcepGrib
  20. ! file name:
  21. character(len=256) :: fname
  22. ! unit for grib data file:
  23. integer :: lugb
  24. ! unit for index file (?):
  25. integer :: lugi
  26. ! message number
  27. integer :: mnr
  28. ! product definition section:
  29. integer :: pds(200)
  30. ! grid description section:
  31. integer :: gds(200)
  32. ! bit map and binary data sections:
  33. integer :: n
  34. logical, pointer :: bms(:)
  35. real, pointer :: bds(:)
  36. end type TNcepGrib
  37. ! --- interfaces ----------------------------------------
  38. interface Init
  39. module procedure ncg_Init
  40. end interface
  41. interface Done
  42. module procedure ncg_Done
  43. end interface
  44. interface ReadRecord
  45. module procedure ncg_ReadRecord
  46. end interface
  47. interface CheckRecord
  48. module procedure ncg_CheckRecord
  49. end interface
  50. interface ListRecord
  51. module procedure ncg_ListRecord
  52. end interface
  53. interface Get
  54. module procedure ncg_Get
  55. end interface
  56. ! --- local ------------------------------------------
  57. ! grib tables:
  58. character(len=4) :: type_of_level(0:255)
  59. character(len=5) :: parameter_abbrev(0:255)
  60. character(len=6) :: forecast_time_unit(0:4)
  61. character(len=20) :: time_range_indicator(0:10)
  62. character(len=2) :: data_representation_type(0:50)
  63. contains
  64. ! =======================================================================
  65. subroutine ncg_Init( ncg, unit, fname, status )
  66. ! --- in/out ----------------------------------------
  67. type(TNcepGrib), intent(out) :: ncg
  68. integer, intent(in) :: unit
  69. character(len=*), intent(in) :: fname
  70. integer, intent(out) :: status
  71. ! --- const ------------------------------------------
  72. character(len=*), parameter :: rname = mname//'/ncg_Init'
  73. ! --- local ------------------------------------------
  74. logical :: exist, opened
  75. ! --- begin ------------------------------------------
  76. ! store file name:
  77. ncg%fname = fname
  78. ! file exist ?
  79. inquire( file=trim(ncg%fname), exist=exist )
  80. if ( .not. exist ) then
  81. write (*,'("ERROR - file not found :")')
  82. write (*,'("ERROR - ",a)') trim(ncg%fname)
  83. write (*,'("ERROR in ",a)') rname; status=1; return
  84. end if
  85. ncg%lugb = unit
  86. ! ! select free file unit:
  87. ! ! note: baopenr expects number within {1,..,99}
  88. ! ncg%lugb = 10
  89. ! do
  90. ! inquire( unit=ncg%lugb, opened=opened )
  91. ! if ( .not. opened ) exit
  92. ! ncg%lugb = ncg%lugb + 1
  93. ! end do
  94. ! open file:
  95. #ifdef with_w3
  96. call baOpenR( ncg%lugb, trim(ncg%fname), status )
  97. if ( status /= 0 ) then
  98. write (*,'("ERROR - from baOpenR :")')
  99. write (*,'("ERROR - file : ",a )') trim(ncg%fname)
  100. write (*,'("ERROR - iret : ",i6)') status
  101. select case ( status )
  102. case ( 6 ) ; write (*,'("ERROR - (file unit not in 1..999 : ",i6,")")') ncg%lugb
  103. end select
  104. write (*,'("ERROR in ",a)') rname; status=1; return
  105. end if
  106. #else
  107. write (*,'("ERROR - not compiled with w3 library")')
  108. write (*,'("ERROR in ",a)') rname; status=1; return
  109. #endif
  110. ! no index file yet ...
  111. ncg%lugi = 0
  112. ! no data sections read yet, but allocate some space already:
  113. ncg%n = 0
  114. allocate( ncg%bms(1000) )
  115. allocate( ncg%bds(1000) )
  116. ! fill param abbrevs (GRIB table 2)
  117. parameter_abbrev(1 ) = 'PRES '
  118. parameter_abbrev(11 ) = 'TMP '
  119. parameter_abbrev(15 ) = 'TMAX '
  120. parameter_abbrev(16 ) = 'TMIN '
  121. parameter_abbrev(33 ) = 'UGRD '
  122. parameter_abbrev(34 ) = 'VGRD '
  123. parameter_abbrev(51 ) = 'SPFH '
  124. parameter_abbrev(54 ) = 'PWAT '
  125. parameter_abbrev(59 ) = 'PRATE'
  126. parameter_abbrev(65 ) = 'WEASD'
  127. parameter_abbrev(71 ) = 'TCDC '
  128. parameter_abbrev(81 ) = 'LAND '
  129. parameter_abbrev(84 ) = 'ALBDO'
  130. parameter_abbrev(90 ) = 'WATR '
  131. parameter_abbrev(91 ) = 'ICEC '
  132. parameter_abbrev(121) = 'LHTFL'
  133. parameter_abbrev(122) = 'SHTFL'
  134. parameter_abbrev(124) = 'UFLX '
  135. parameter_abbrev(125) = 'VFLX '
  136. parameter_abbrev(144) = 'SOILW'
  137. parameter_abbrev(145) = 'PEVPR'
  138. parameter_abbrev(146) = 'CWORK'
  139. parameter_abbrev(147) = 'U-GWD'
  140. parameter_abbrev(148) = 'V-GWD'
  141. parameter_abbrev(155) = 'GFLUX'
  142. parameter_abbrev(204) = 'DSWRF'
  143. parameter_abbrev(205) = 'DLWRF'
  144. parameter_abbrev(212) = 'ULWRF'
  145. parameter_abbrev(211) = 'USWRF'
  146. parameter_abbrev(214) = 'CPRAT'
  147. parameter_abbrev(221) = 'HPBL '
  148. ! type of level (GRIB table 3) level
  149. type_of_level( 1) = 'SFC'
  150. type_of_level( 8) = 'NTAT'
  151. type_of_level(105) = 'HTGL' ! height above ground level (meters)
  152. type_of_level(112) = 'DBLY' ! layer between two depths 10=0-10cm, 2760=10-200cm
  153. type_of_level(200) = 'EATM' ! entire atmosphere
  154. type_of_level(211) = 'BCY' ! boundary layer cloud layer
  155. type_of_level(212) = 'LCBL' ! low cloud bottom level
  156. type_of_level(213) = 'LCTL' ! low cloud top level
  157. type_of_level(214) = 'LCY' ! low cloud layer
  158. type_of_level(222) = 'MCBL' ! mid cloud bottom level
  159. type_of_level(223) = 'MCTL' ! mid cloud top level
  160. type_of_level(224) = 'MCY' ! mid cloud layer
  161. type_of_level(232) = 'HCBL' ! high cloud bottom level
  162. type_of_level(233) = 'HCTL' ! high cloud top level
  163. type_of_level(234) = 'HCY' ! high cloud layer
  164. type_of_level(242) = 'CCBL' ! conv cloud bottom level
  165. type_of_level(243) = 'CCTL' ! conv cloud top level
  166. type_of_level(244) = 'CCY' ! conv cloud layer
  167. ! forecast time unit (GRIB table 4)
  168. forecast_time_unit( 0) = 'minute'
  169. forecast_time_unit( 1) = 'hour'
  170. forecast_time_unit( 2) = 'day'
  171. forecast_time_unit( 3) = 'month'
  172. forecast_time_unit( 4) = 'year'
  173. ! time range indicator
  174. time_range_indicator( 0) = 'tref+P1'
  175. time_range_indicator( 3) = 'tref+[P1,P2] aver'
  176. time_range_indicator( 4) = 'tref+[P1,P2] accum'
  177. time_range_indicator( 10) = 'tref+P1'
  178. ! data representation type (GRIB table 6)
  179. data_representation_type( 0) = 'll'
  180. data_representation_type( 4) = 'gg'
  181. data_representation_type(50) = 'sh'
  182. ! ok
  183. status = 0
  184. end subroutine ncg_Init
  185. ! ***
  186. subroutine ncg_Done( ncg, status )
  187. ! --- in/out ----------------------------------------
  188. type(TNcepGrib), intent(inout) :: ncg
  189. integer, intent(out) :: status
  190. ! --- const ------------------------------------------
  191. character(len=*), parameter :: rname = mname//'/ncg_Done'
  192. ! --- begin ------------------------------------------
  193. ! clear
  194. deallocate( ncg%bms )
  195. deallocate( ncg%bds )
  196. ! close file:
  197. #ifdef with_w3
  198. call baClose( ncg%lugb, status )
  199. if ( status /= 0 ) then
  200. write (*,'("ERROR - from baClose :")')
  201. write (*,'("ERROR - file : ",a )') trim(ncg%fname)
  202. write (*,'("ERROR - iret : ",i6)') status
  203. write (*,'("ERROR in ",a)') rname; status=1; return
  204. end if
  205. #else
  206. write (*,'("ERROR - not compiled with w3 library")')
  207. write (*,'("ERROR in ",a)') rname; status=1; return
  208. #endif
  209. ! ok
  210. status = 0
  211. end subroutine ncg_Done
  212. ! ***
  213. subroutine ncg_ReadRecord( ncg, status, irec, param, reftime, timerange, levtype, level )
  214. ! --- in/out ----------------------------------------
  215. type(TNcepGrib), intent(inout) :: ncg
  216. integer, intent(out) :: status
  217. integer, intent(in), optional :: irec
  218. character(len=*), intent(in), optional :: param
  219. integer, intent(in), optional :: reftime(5)
  220. integer, intent(in), optional :: timerange(4)
  221. character(len=*), intent(in), optional :: levtype
  222. integer, intent(in), optional :: level
  223. ! --- const ------------------------------------------
  224. character(len=*), parameter :: rname = mname//'/ncg_ReadRecord'
  225. ! --- local -----------------------------------------
  226. integer :: pds(200)
  227. integer :: gds(200)
  228. integer :: nskip
  229. integer :: i
  230. integer :: n
  231. ! --- begin ------------------------------------------
  232. ! wild cards by default
  233. pds = -1
  234. gds = -1
  235. ! number of grib messages to skip:
  236. nskip = 0
  237. if ( present(irec) ) nskip = irec - 1
  238. ! search param ?
  239. if ( present(param) ) then
  240. do i = 0, 255
  241. if ( param == parameter_abbrev(i) ) then
  242. pds(5) = i
  243. exit
  244. end if
  245. end do
  246. end if
  247. ! search reftime ?
  248. if ( present(reftime) ) then
  249. if ( all(reftime >= 0) ) then
  250. pds(21) = int(ceiling(reftime(1)/100.0))
  251. pds( 8) = modulo(reftime(1),100)
  252. pds( 9) = reftime(2)
  253. pds(10) = reftime(3)
  254. pds(11) = reftime(4)
  255. pds(12) = reftime(5)
  256. end if
  257. end if
  258. ! search time range ?
  259. if ( present(timerange) ) pds(13:16) = timerange
  260. ! search level type ?
  261. if ( present(levtype) ) then
  262. do i = 0, 255
  263. if ( levtype == type_of_level(i) ) then
  264. pds(6) = i
  265. exit
  266. end if
  267. end do
  268. end if
  269. ! search level ?
  270. if ( present(level) ) pds(7) = level
  271. ! loop until data section is large enough to hold the data:
  272. do
  273. n = size(ncg%bds)
  274. #ifdef with_w3
  275. ! find and unpack grib message;
  276. ! no search ...
  277. call GetGB( ncg%lugb, ncg%lugi, n, nskip, pds, gds, &
  278. ncg%n, ncg%mnr, ncg%pds, ncg%gds, ncg%bms, ncg%bds, status )
  279. select case ( status )
  280. case ( 0 )
  281. ! all ok, thus leave loop:
  282. exit
  283. case ( 96 )
  284. write (*,'("ERROR - from GetGB : reading index file")')
  285. case ( 97 )
  286. write (*,'("ERROR - from GetGB : reading grib file")')
  287. case ( 98 )
  288. ! number of data points greater than size ncg%bds;
  289. ! check for excesive size first ...
  290. if ( n >= 1000000 ) then
  291. write (*,'("ERROR - excesive size of bds still not large enough:")')
  292. write (*,'("ERROR - size bds : ",i8)') n
  293. else
  294. ! reallocate:
  295. deallocate( ncg%bms ) ; allocate( ncg%bms(n*10) )
  296. deallocate( ncg%bds ) ; allocate( ncg%bds(n*10) )
  297. ! try again ...
  298. cycle
  299. end if
  300. case ( 99 )
  301. write (*,'("ERROR - from GetGB : request not found")')
  302. case default
  303. write (*,'("ERROR - from GetGB : W3FI63 grib unpacker return code : ",i6)') status
  304. select case ( status )
  305. case ( 1 ) ; write (*,'("ERROR - = `GRIB` NOT FOUND IN FIRST 100 CHARS ")')
  306. case ( 2 ) ; write (*,'("ERROR - = `7777` NOT IN CORRECT LOCATION ")')
  307. case ( 3 ) ; write (*,'("ERROR - = UNPACKED FIELD IS LARGER THAN 260000 ")')
  308. case ( 4 ) ; write (*,'("ERROR - = GDS/ GRID NOT ONE OF CURRENTLY ACCEPTED VALUES ")')
  309. case ( 5 ) ; write (*,'("ERROR - = GRID NOT CURRENTLY AVAIL FOR CENTER INDICATED ")')
  310. case ( 8 ) ; write (*,'("ERROR - = TEMP GDS INDICATED, BUT GDS FLAG IS OFF ")')
  311. case ( 9 ) ; write (*,'("ERROR - = GDS INDICATES SIZE MISMATCH WITH STD GRID ")')
  312. case ( 10 ) ; write (*,'("ERROR - = INCORRECT CENTER INDICATOR ")')
  313. case ( 11 ) ; write (*,'("ERROR - = BINARY DATA SECTION (BDS) NOT COMPLETELY PROCESSED.")') &
  314. ; write (*,'("ERROR - PROGRAM IS NOT SET TO PROCESS FLAG COMBINATIONS ")') &
  315. ; write (*,'("ERROR - SHOWN IN OCTETS 4 AND 14. ")')
  316. case ( 12 ) ; write (*,'("ERROR - = BINARY DATA SECTION (BDS) NOT COMPLETELY PROCESSED.")') &
  317. ; write (*,'("ERROR - PROGRAM IS NOT SET TO PROCESS FLAG COMBINATIONS ")')
  318. end select
  319. end select
  320. #else
  321. write (*,'("ERROR - not compiled with w3 library")')
  322. write (*,'("ERROR in ",a)') rname; status=1; return
  323. #endif
  324. write (*,'("ERROR - file : ",a )') trim(ncg%fname)
  325. write (*,'("ERROR - irec : ",i6 )') nskip+1
  326. if ( present(param ) ) write (*,'("ERROR - param : ",a,i4 )') param, pds(5)
  327. if ( present(reftime ) ) write (*,'("ERROR - reftime : ",i4,4i3 )') reftime
  328. if ( present(reftime ) ) write (*,'("ERROR - (pds : ",6i3,")")') pds(21), pds(8:12)
  329. if ( present(timerange) ) write (*,'("ERROR - timerange : ",4i4 )') timerange
  330. if ( present(levtype ) ) write (*,'("ERROR - levtype : ",a,i4 )') levtype, pds(6)
  331. if ( present(level ) ) write (*,'("ERROR - level : ",i6 )') level
  332. write (*,'("ERROR in ",a)') rname; status=1; return
  333. end do
  334. ! ok
  335. status = 0
  336. end subroutine ncg_ReadRecord
  337. ! ***
  338. subroutine ncg_CheckRecord( ncg, status, param, reftime, timerange, levtype, level )
  339. ! --- in/out ----------------------------------------
  340. type(TNcepGrib), intent(inout) :: ncg
  341. integer, intent(out) :: status
  342. character(len=*), intent(in), optional :: param
  343. integer, intent(in), optional :: reftime(5)
  344. integer, intent(in), optional :: timerange(4)
  345. character(len=*), intent(in), optional :: levtype
  346. integer, intent(in), optional :: level
  347. ! --- const ------------------------------------------
  348. character(len=*), parameter :: rname = mname//'/ncg_CheckRecord'
  349. ! --- local -----------------------------------------
  350. integer :: pds(200)
  351. ! --- begin ------------------------------------------
  352. ! initially ok
  353. status = 0
  354. ! check param ?
  355. if ( present(param) ) then
  356. if ( param /= parameter_abbrev(ncg%pds(5)) ) then
  357. write (*,'("ERROR - parameters do not match : ")')
  358. write (*,'("ERROR - requested : ",a)') param
  359. write (*,'("ERROR - grib record : ",a)') parameter_abbrev(ncg%pds(5))
  360. status = 1
  361. end if
  362. end if
  363. ! check reftime ?
  364. if ( present(reftime) ) then
  365. if ( all(reftime >= 0) ) then
  366. pds(21) = int(ceiling(reftime(1)/100.0))
  367. pds( 8) = modulo(reftime(1),100)
  368. pds( 9) = reftime(2)
  369. pds(10) = reftime(3)
  370. pds(11) = reftime(4)
  371. pds(12) = reftime(5)
  372. if ( any( (/pds(21),pds(8:12)/) /= (/ncg%pds(21),ncg%pds(8:12)/) ) ) then
  373. write (*,'("ERROR - reference times do not match : ")')
  374. write (*,'("ERROR - requested : ",6i3)') pds(21), pds(8:12)
  375. write (*,'("ERROR - grib record : ",6i3)') ncg%pds(21), ncg%pds(8:12)
  376. status = 1
  377. end if
  378. end if
  379. end if
  380. ! check time range ?
  381. if ( present(timerange) ) then
  382. if ( all(timerange >= 0) .and. any( timerange /= ncg%pds(13:16) ) ) then
  383. write (*,'("ERROR - time ranges do not match : ")')
  384. write (*,'("ERROR - requested : ",6i3)') timerange
  385. write (*,'("ERROR - grib record : ",6i3)') ncg%pds(13:16)
  386. status = 1
  387. end if
  388. end if
  389. ! check level type ?
  390. if ( present(levtype) ) then
  391. if ( levtype /= type_of_level(ncg%pds(6)) ) then
  392. write (*,'("ERROR - level types do not match : ")')
  393. write (*,'("ERROR - requested : ",a)') levtype
  394. write (*,'("ERROR - grib record : ",a)') type_of_level(ncg%pds(6))
  395. status = 1
  396. end if
  397. end if
  398. ! check level ?
  399. if ( present(level) ) then
  400. if ( level /= ncg%pds(7) ) then
  401. write (*,'("ERROR - levels do not match : ")')
  402. write (*,'("ERROR - requested : ",6i3)') level
  403. write (*,'("ERROR - grib record : ",6i3)') ncg%pds(7)
  404. status = 1
  405. end if
  406. end if
  407. ! any errors ?
  408. if ( status /= 0 ) then
  409. write (*,'("ERROR - some checks failed ...")')
  410. write (*,'("ERROR - checks requrested for:")')
  411. if ( present(param ) ) write (*,'("ERROR - param : ",a,i4 )') param, pds(5)
  412. if ( present(reftime ) ) write (*,'("ERROR - reftime : ",i4,4i3 )') reftime
  413. if ( present(reftime ) ) write (*,'("ERROR - (pds : ",6i3,")")') pds(21), pds(8:12)
  414. if ( present(timerange) ) write (*,'("ERROR - timerange : ",4i4 )') timerange
  415. if ( present(levtype ) ) write (*,'("ERROR - levtype : ",a,i4 )') levtype, pds(6)
  416. if ( present(level ) ) write (*,'("ERROR - level : ",i6 )') level
  417. write (*,'("ERROR - file : ",a )') trim(ncg%fname)
  418. write (*,'("ERROR - record nr : ",i6)') ncg%mnr
  419. write (*,'("ERROR in ",a)') rname; status=1; return
  420. end if
  421. ! ok
  422. status = 0
  423. end subroutine ncg_CheckRecord
  424. ! ***
  425. subroutine ncg_ListRecord( ncg, status )
  426. ! --- in/out ----------------------------------------
  427. type(TNcepGrib), intent(inout) :: ncg
  428. integer, intent(out) :: status
  429. ! --- const ------------------------------------------
  430. character(len=*), parameter :: rname = mname//'/ncg_ListRecord'
  431. ! --- local ---------------------------------------
  432. integer :: i
  433. ! --- begin ------------------------------------------
  434. write (*,'(" ")')
  435. write (*,'("Section 1 - Product Definition Section ")')
  436. write (*,'(" ")')
  437. write (*,'(" ( 1) - ID OF CENTER : ",i6)') ncg%pds(1)
  438. write (*,'(" (23) - SUBCENTER NUMBER : ",i6)') ncg%pds(23)
  439. write (*,'(" ( 2) - GENERATING PROCESS ID NUMBER : ",i6)') ncg%pds(2)
  440. write (*,'(" (18) - VERSION NR OF GRIB SPECIFICATION : ",i6)') ncg%pds(18)
  441. write (*,'(" ( 3) - GRID DEFINITION : ",i6)') ncg%pds(3)
  442. write (*,'(" ( 4) - GDS/BMS FLAG (RIGHT ADJ COPY OF OCTET 8) : ",i6)') ncg%pds(4)
  443. write (*,'(" (19) - VERSION NR OF PARAMETER TABLE : ",i6)') ncg%pds(19)
  444. write (*,'(" (17) - NUMBER INCLUDED IN AVERAGE : ",i6)') ncg%pds(17)
  445. write (*,'(" (20) - NR MISSING FROM AVERAGE/ACCUMULATION : ",i6)') ncg%pds(20)
  446. write (*,'(" (22) - UNITS DECIMAL SCALE FACTOR : ",i6)') ncg%pds(22)
  447. write (*,'(" ( 5) - INDICATOR OF PARAMETER : ",i6," = ",a)') &
  448. ncg%pds(5), parameter_abbrev(ncg%pds(5))
  449. write (*,'(" ( 6) - TYPE OF LEVEL : ",i6," = ",a)') &
  450. ncg%pds(6), type_of_level(ncg%pds(6))
  451. write (*,'(" ( 7) - HEIGHT/PRESSURE , ETC OF LEVEL : ",i6)') ncg%pds(7)
  452. write (*,'(" (21) - CENTURY OF REFERENCE TIME OF DATA : ",i6)') ncg%pds(21)
  453. write (*,'(" ( 8) - YEAR INCLUDING (CENTURY-1) : ",i6)') ncg%pds(8)
  454. write (*,'(" ( 9) - MONTH OF YEAR : ",i6)') ncg%pds(9)
  455. write (*,'(" (10) - DAY OF MONTH : ",i6)') ncg%pds(10)
  456. write (*,'(" (11) - HOUR OF DAY : ",i6)') ncg%pds(11)
  457. write (*,'(" (12) - MINUTE OF HOUR : ",i6)') ncg%pds(12)
  458. write (*,'(" (13) - INDICATOR OF FORECAST TIME UNIT : ",i6," = ",a)') &
  459. ncg%pds(13), forecast_time_unit(ncg%pds(13))
  460. write (*,'(" (14) - TIME RANGE 1 : ",i6)') ncg%pds(14)
  461. write (*,'(" (15) - TIME RANGE 2 : ",i6)') ncg%pds(15)
  462. write (*,'(" (16) - TIME RANGE FLAG : ",i6," = ",a)') &
  463. ncg%pds(16), time_range_indicator(ncg%pds(16))
  464. write (*,'(" ")')
  465. write (*,'("Section 2 - Grid Description Section ")')
  466. write (*,'(" ")')
  467. write (*,'(" ( 1) - DATA REPRESENTATION TYPE : ",i6," = ",a)') &
  468. ncg%gds( 1), data_representation_type(ncg%gds( 1))
  469. select case ( data_representation_type(ncg%gds( 1)) )
  470. case ( 'll' )
  471. write (*,'(" ")')
  472. write (*,'("LATITUDE/LONGITUDE GRID ")')
  473. write (*,'(" ( 2) - N(I) NR POINTS ON LATITUDE CIRCLE : ",i6)') ncg%gds( 2)
  474. write (*,'(" ( 3) - N(J) NR POINTS ON LONGITUDE MERIDIAN : ",i6)') ncg%gds( 3)
  475. write (*,'(" ( 4) - LA(1) LATITUDE OF ORIGIN : ",i6)') ncg%gds( 4)
  476. write (*,'(" ( 5) - LO(1) LONGITUDE OF ORIGIN : ",i6)') ncg%gds( 5)
  477. write (*,'(" ( 6) - RESOLUTION FLAG (RIGHT ADJ COPY OF OCTET 17) : ",i6)') ncg%gds( 6)
  478. write (*,'(" ( 7) - LA(2) LATITUDE OF EXTREME POINT : ",i6)') ncg%gds( 7)
  479. write (*,'(" ( 8) - LO(2) LONGITUDE OF EXTREME POINT : ",i6)') ncg%gds( 8)
  480. write (*,'(" ( 9) - DI LONGITUDINAL DIRECTION OF INCREMENT : ",i6)') ncg%gds( 9)
  481. write (*,'(" (10) - DJ LATITUDINAL DIRECTION INCREMENT : ",i6)') ncg%gds(10)
  482. write (*,'(" (11) - SCANNING MODE FLAG (RIGHT ADJ COPY OF OCTET 28) : ",i6)') ncg%gds(11)
  483. case ( 'gg' )
  484. write (*,'(" ")')
  485. write (*,'("GAUSSIAN GRID ")')
  486. write (*,'(" ( 2) - N(I) NR POINTS ON LATITUDE CIRCLE : ",i6)') ncg%gds( 2)
  487. write (*,'(" ( 3) - N(J) NR POINTS ON LONGITUDE MERIDIAN : ",i6)') ncg%gds( 3)
  488. write (*,'(" ( 4) - LA(1) LATITUDE OF ORIGIN : ",i6)') ncg%gds( 4)
  489. write (*,'(" ( 5) - LO(1) LONGITUDE OF ORIGIN : ",i6)') ncg%gds( 5)
  490. write (*,'(" ( 6) - RESOLUTION FLAG (RIGHT ADJ COPY OF OCTET 17) : ",i6)') ncg%gds( 6)
  491. write (*,'(" ( 7) - LA(2) LATITUDE OF EXTREME POINT : ",i6)') ncg%gds( 7)
  492. write (*,'(" ( 8) - LO(2) LONGITUDE OF EXTREME POINT : ",i6)') ncg%gds( 8)
  493. write (*,'(" ( 9) - DI LONGITUDINAL DIRECTION OF INCREMENT : ",i6)') ncg%gds( 9)
  494. write (*,'(" (10) - N - NR OF CIRCLES POLE TO EQUATOR : ",i6)') ncg%gds(10)
  495. write (*,'(" (11) - SCANNING MODE FLAG (RIGHT ADJ COPY OF OCTET 28) : ",i6)') ncg%gds(11)
  496. case ( 'sh' )
  497. write (*,'(" ")')
  498. write (*,'("SPHERICAL HARMONIC COEFFICIENTS ")')
  499. write (*,'(" ( 2) - J PENTAGONAL RESOLUTION PARAMETER : ",i6)') ncg%gds( 2)
  500. write (*,'(" ( 3) - K x x x : ",i6)') ncg%gds( 3)
  501. write (*,'(" ( 4) - M x x x : ",i6)') ncg%gds( 4)
  502. write (*,'(" ( 5) - REPRESENTATION TYPE : ",i6)') ncg%gds( 5)
  503. write (*,'(" ( 6) - COEFFICIENT STORAGE MODE : ",i6)') ncg%gds( 6)
  504. end select
  505. if ( (ncg%gds(12) > 0) .or.(ncg%gds(19) > 0) ) then
  506. write (*,'(" ")')
  507. write (*,'("VERTICAL COORDINATE PARAMETERS ")')
  508. write (*,'(" (12) - NV - NR OF VERT COORD PARAMETERS : ",i6)') ncg%gds(12)
  509. write (*,'(" (13) - PV - OCTET NR OF LIST OF VERT COORD PARAMETERS : ",i6)') ncg%gds(13)
  510. write (*,'(" PL - LOCATION OF THE LIST OF NUMBERS OF POINTS IN EACH ROW ")')
  511. write (*,'(" (IF NO VERT COORD PARAMETERS ARE PRESENT) ")')
  512. write (*,'(" 255 IF NEITHER ARE PRESENT ")')
  513. write (*,'(" (19) - NUMBER OF VERTICAL COORDINATE PARAMETERS : ",i6)') ncg%gds(19)
  514. write (*,'(" (20) - OCTET NUMBER OF THE LIST OF VERTICAL COORDINATE PARAMETERS : ",i6)') ncg%gds(20)
  515. write (*,'(" OCTET NUMBER OF THE LIST OF NUMBERS OF POINTS IN EACH ROW : ")')
  516. write (*,'(" 255 IF NEITHER ARE PRESENT : ")')
  517. write (*,'(" (21) - FOR GRIDS WITH PL, NUMBER OF POINTS IN GRID : ",i6)') ncg%gds(21)
  518. write (*,'(" (22) - NUMBER OF WORDS IN EACH ROW : ",i6)') ncg%gds(22)
  519. end if
  520. write (*,'(" ")')
  521. write (*,'("Section 4 - Binary Data Section ")')
  522. write (*,'(" ")')
  523. write (*,'(" first 20 values: ")')
  524. do i = 1, 20
  525. write (*,'(" ",es16.6)') ncg%bds(i)
  526. end do
  527. write (*,'(" ")')
  528. ! ok
  529. status = 0
  530. end subroutine ncg_ListRecord
  531. ! ***
  532. subroutine ncg_Get( ncg, status, ggN, gg )
  533. ! --- in/out ----------------------------------------
  534. type(TNcepGrib), intent(inout) :: ncg
  535. integer, intent(out) :: status
  536. integer, intent(out), optional :: ggN
  537. real, intent(out), optional :: gg(:)
  538. ! --- const ------------------------------------------
  539. character(len=*), parameter :: rname = mname//'/ncg_Get'
  540. ! --- begin ------------------------------------------
  541. ! return gg number:
  542. if ( present(ggN) ) then
  543. if ( data_representation_type(ncg%gds(1)) /= 'gg' ) then
  544. write (*,'("ERROR - ggN not for grid type : ",a)') data_representation_type(ncg%gds(1))
  545. write (*,'("ERROR in ",a)') rname; status=1; return
  546. end if
  547. ggN = ncg%gds(10)
  548. end if
  549. ! return gg field:
  550. if ( present(gg) ) then
  551. if ( data_representation_type(ncg%gds(1)) /= 'gg' ) then
  552. write (*,'("ERROR - ggN not for grid type : ",a)') data_representation_type(ncg%gds(1))
  553. write (*,'("ERROR in ",a)') rname; status=1; return
  554. end if
  555. if ( size(gg) /= ncg%n ) then
  556. write (*,'("ERROR - size of output grid does not match with storred data:")')
  557. write (*,'("ERROR - storred : ",i6)') ncg%n
  558. write (*,'("ERROR - output gg : ",i6)') size(gg)
  559. write (*,'("ERROR in ",a)') rname; status=1; return
  560. end if
  561. gg = ncg%bds(1:ncg%n)
  562. end if
  563. ! ok
  564. status = 0
  565. end subroutine ncg_Get
  566. end module file_ncg
  567. ! #####################################################################################
  568. ! ###
  569. ! ### test
  570. ! ###
  571. ! #####################################################################################
  572. !
  573. ! ifort -o test.x -r8 file_ncg.f90 /ahome/segers/opt/ifort-default-R64/lib/libw3.a && ./test.x
  574. !
  575. ! Problem: reading from a new grib file gives an error from GetGB .
  576. !
  577. ! Tested:
  578. ! o set all input/output variables to zero before second file
  579. ! o multiple open/read/close from same file is not a problem
  580. ! o copy files to same temporary file name does not help
  581. !
  582. !
  583. !program test
  584. !
  585. ! !use file_ncg
  586. !
  587. ! !type(TNcepGrib) :: ncg
  588. ! integer :: status
  589. ! integer :: irec
  590. ! logical :: opened
  591. !
  592. ! integer :: pds(200)
  593. ! integer :: gds(200)
  594. !
  595. ! integer :: lugb
  596. ! integer :: lugi
  597. ! integer :: ncg_n
  598. ! integer :: ncg_pds(200)
  599. ! integer :: ncg_gds(200)
  600. ! integer :: mnr
  601. !
  602. ! integer, parameter :: n = 400000
  603. ! logical :: bms(n)
  604. ! real :: bds(n)
  605. !
  606. ! ! --- begin ------------------------------------
  607. !
  608. ! print *, 'test: begin'
  609. !
  610. ! do irec = 31, 31
  611. !
  612. ! print *, 'test: 1', irec
  613. !
  614. ! !call system( '/bin/cp -f /p71/co2/ncep.gfs/20040614/20040614.06.00.SFLUXGrbF /p71/co2/segers/tmp/tmp.gb' )
  615. !
  616. ! lugb = 10
  617. ! call baOpenR( lugb, '/p71/co2/ncep.gfs/20040614/20040614.06.00.SFLUXGrbF', status )
  618. ! if (status/=0) stop 'ERROR in test'
  619. !
  620. ! lugi = 0
  621. ! pds = -1
  622. ! gds = -1
  623. ! call GetGB( lugb, lugi, n, irec-1, pds, gds, &
  624. ! ncg_n, mnr, ncg_pds, ncg_gds, bms, bds, status )
  625. ! print *, ' getgb : ', status
  626. ! if (status/=0) stop 'ERROR in test'
  627. !
  628. ! !call baClose( lugb, status )
  629. ! !if (status/=0) stop 'ERROR in test'
  630. !
  631. ! inquire( lugb, opened=opened )
  632. ! print *, ' opened : ', opened
  633. !
  634. ! close(lugb,iostat=status)
  635. ! if (status/=0) stop 'ERROR in test from close'
  636. !
  637. ! end do
  638. !
  639. ! print *, 'test: 2'
  640. !
  641. ! !call system( '/bin/cp -f /p71/co2/ncep.gfs/20040614/20040614.12.00.SFLUXGrbF /p71/co2/segers/tmp/tmp.gb' )
  642. !
  643. ! lugb = 10
  644. ! call baOpenR( lugb, '/p71/co2/ncep.gfs/20040614/20040614.12.00.SFLUXGrbF', status )
  645. ! if (status/=0) stop 'ERROR in test'
  646. !
  647. ! lugi = 0
  648. ! irec = 31
  649. ! pds = -1
  650. ! gds = -1
  651. ! ncg_n = 0
  652. ! mnr = 0
  653. ! ncg_pds = 0
  654. ! ncg_gds = 0
  655. ! bms = .false.
  656. ! bds = 0.0
  657. ! status = 0
  658. ! call GetGB( lugb, lugi, n, irec-1, pds, gds, &
  659. ! ncg_n, mnr, ncg_pds, ncg_gds, bms, bds, status )
  660. ! print *, ' getgb : ', status
  661. ! if (status/=0) stop 'ERROR in test'
  662. !
  663. ! call baClose( lugb, status )
  664. ! if (status/=0) stop 'ERROR in test'
  665. !
  666. ! print *, 'test: end'
  667. !
  668. !end program test