PageRenderTime 56ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 1ms

/WPS/ungrib/src/gribcode.F

http://github.com/jbeezley/wrf-fire
FORTRAN Legacy | 2135 lines | 1246 code | 207 blank | 682 comment | 138 complexity | 878b75ab815647767790fbda17c533d2 MD5 | raw file
Possible License(s): AGPL-1.0
  1. ! !
  2. !*****************************************************************************!
  3. ! !
  4. ! This is a package of subroutines to read GRIB-formatted data. It is still !
  5. ! under continuous development. It will not be able to read every GRIB dataset!
  6. ! you give it, but it will read a good many. !
  7. ! !
  8. ! Kevin W. Manning !
  9. ! NCAR/MMM !
  10. ! Summer 1998, and continuing !
  11. ! SDG !
  12. ! !
  13. !*****************************************************************************!
  14. ! !
  15. ! The main user interfaces are: !
  16. ! !
  17. ! SUBROUTINE GRIBGET(NUNIT, IERR) !
  18. ! Read a single GRIB record from UNIX file-descriptor NUNIT into array !
  19. ! GREC. No unpacking of any header or data values is performed. !
  20. ! !
  21. ! SUBROUTINE GRIBREAD(NUNIT, DATA, NDATA, IERR) !
  22. ! Read a single GRIB record from UNIX file-descriptor NUNIT, and unpack !
  23. ! all header and data values into the appropriate arrays. !
  24. ! !
  25. ! SUBROUTINE GRIBHEADER !
  26. ! Unpack the header of a GRIB record !
  27. ! !
  28. ! SUBROUTINE GRIBDATA(DATARRAY, NDAT) !
  29. ! Unpack the data in a GRIB record into array DATARRAY !
  30. ! !
  31. ! SUBROUTINE GRIBPRINT(ISEC) !
  32. ! Print the header information from GRIB section ISEC. !
  33. ! !
  34. ! SUBROUTINE GET_SEC1(KSEC1) !
  35. ! Return the header information from Section 1. !
  36. ! !
  37. ! SUBROUTINE GET_SEC2(KSEC2) !
  38. ! Return the header information from Section 2. !
  39. ! !
  40. ! SUBROUTINE GET_GRIDINFO(IGINFO, GINFO) !
  41. ! Return the grid information of the previously-unpacked GRIB header. !
  42. ! !
  43. ! !
  44. !*****************************************************************************!
  45. ! !
  46. ! !
  47. ! The following arrays have meanings as follows: !
  48. ! !
  49. ! !
  50. ! SEC0: GRIB Header Section 0 information !
  51. ! !
  52. ! 1 : Length of a complete GRIB record !
  53. ! 2 : GRIB Edition number !
  54. ! !
  55. ! !
  56. ! SEC1: GRIB Header Section 1 information !
  57. ! !
  58. ! 1 : Length of GRIB section 1 (bytes) !
  59. ! 2 : Parameter Table Version number ???? !
  60. ! 3 : Center Identifier ???? !
  61. ! 4 : Process Identifier ???? !
  62. ! 5 : Grid ID number for pre-specified grids. !
  63. ! 6 : Binary bitmap flag: !
  64. ! 7 : Parameter ID Number (ON388 Table 2) !
  65. ! 8 : Level type (ON388 Table 3) !
  66. ! 9 : Level value, or top value of a layer !
  67. ! 10 : Bottom value of a layer ( 0 if NA ??) !
  68. ! 11 : Year (00-99) !
  69. ! 12 : Month (01-12) !
  70. ! 13 : Day of the month (01-31) !
  71. ! 14 : Hour (00-23) !
  72. ! 15 : Minute (00-59) !
  73. ! 16 : Forecast time unit: (ON388 Table 4) !
  74. ! 17 : Time period 1: !
  75. ! 18 : Time period 2: !
  76. ! 19 : Time range indicator (ON833 Table 5) !
  77. ! 20 : Number of ?? in an average ?? !
  78. ! 21 : Number of ?? missing from average ?? !
  79. ! 22 : Century (Years 1999 and 2000 are century 20, 2001 is century 21)!
  80. ! 23 : Sub-center identifier ?? !
  81. ! 24 : Decimal scale factor for ??? !
  82. ! !
  83. ! !
  84. ! !
  85. ! !
  86. ! !
  87. ! SEC2: GRIB Header Section 2 information !
  88. ! !
  89. ! 1 : Length of GRIB Section 2 !
  90. ! 2 : Number of vertical-coordinate parameters ??? !
  91. ! 3 : Starting-point of the list of vertical-coordinate parameters ?? !
  92. ! 4 : Data-representation type (i.e., grid type) Table ??? !
  93. ! : 0 = ?? !
  94. ! : 3 = Lambert-conformal grid. !
  95. ! : 5 = Polar-stereographic grid. !
  96. ! !
  97. ! if (SEC2(4) == 0) then LATITUDE/LONGITUDE GRID !
  98. ! !
  99. ! INFOGRID/GRIDINFO: !
  100. ! !
  101. ! 1 : I Dimension of the grid !
  102. ! 2 : J Dimension of the grid !
  103. ! 3 : Starting Latitude of the grid. !
  104. ! 4 : Starting Longitude of the grid. !
  105. ! 5 : Resolution and component flags. !
  106. ! 6 : Ending latitude of the grid. !
  107. ! 7 : Ending longitude of the grid. !
  108. ! 8 : Longitudinal increment. !
  109. ! 9 : Latitudinal incriment. !
  110. ! 10 : Scanning mode (bit 3 from Table 8) !
  111. ! 21 : Iscan sign (+1/-1) (bit 1 from Table 8) !
  112. ! 22 : Jscan sign (+1/-1) (bit 2 from Table 8) !
  113. ! !
  114. ! !
  115. ! elseif (SEC2(4) == 3) then LAMBERT CONFORMAL GRID !
  116. ! !
  117. ! INFOGRID/GRIDINFO: !
  118. ! !
  119. ! 1 : I Dimension of the grid !
  120. ! 2 : J Dimension of the grid !
  121. ! 3 : Starting Latitude of the grid. !
  122. ! 4 : Starting Longitude of the grid. !
  123. ! 5 : Resolution and component flags. !
  124. ! 6 : Center longitude of the projection. !
  125. ! 7 : Grid-spacing in the I direction !
  126. ! 8 : Grid-spacing in the J direction !
  127. ! 9 : Projection center !
  128. ! 10 : Scanning mode (bit 3 from Table 8) !
  129. ! 11 : First TRUELAT value. !
  130. ! 12 : Second TRUELAT value. !
  131. ! 13 : Latitude of the southern pole ?? !
  132. ! 14 : Longitude of the southern pole ?? !
  133. ! 21 : Iscan sign (+1/-1) (bit 1 from Table 8) !
  134. ! 22 : Jscan sign (+1/-1) (bit 2 from Table 8) !
  135. ! !
  136. ! if (SEC2(4) == 4) then GAUSSIAN GRID !
  137. ! !
  138. ! INFOGRID/GRIDINFO: !
  139. ! !
  140. ! 1 : I Dimension of the grid !
  141. ! 2 : J Dimension of the grid !
  142. ! 3 : Starting Latitude of the grid. !
  143. ! 4 : Starting Longitude of the grid. !
  144. ! 5 : Resolution and component flags. !
  145. ! 6 : Ending latitude of the grid. !
  146. ! 7 : Ending longitude of the grid. !
  147. ! 8 : Longitudinal increment. !
  148. ! 9 : Number of latitude circles between pole and equator !
  149. ! 10 : Scanning mode (bit 3 from Table 8) !
  150. ! 17 : Original (stored) ending latitude !
  151. ! 18 : Original (stored) starting latitude !
  152. ! 19 : Approximate delta-latitude !
  153. ! 21 : Iscan sign (+1/-1) (bit 1 from Table 8) !
  154. ! 22 : Jscan sign (+1/-1) (bit 2 from Table 8) !
  155. ! !
  156. ! !
  157. ! elseif (SEC2(4) == 5) then POLAR STEREOGRAPHIC GRID !
  158. ! !
  159. ! INFOGRID/GRIDINFO: !
  160. ! !
  161. ! 1 : I Dimension of the grid !
  162. ! 2 : J Dimension of the grid !
  163. ! 3 : Starting Latitude of the grid. !
  164. ! 4 : Starting Longitude of the grid. !
  165. ! 5 : Resolution and component flags. !
  166. ! 6 : Center longitude of the projection. !
  167. ! 7 : Grid-spacing in the I direction !
  168. ! 8 : Grid-spacing in the J direction !
  169. ! 9 : Projection center !
  170. ! 10 : Scanning mode (bit 3 from Table 8) !
  171. ! 21 : Iscan sign (+1/-1) (bit 1 from Table 8) !
  172. ! 22 : Jscan sign (+1/-1) (bit 2 from Table 8) !
  173. ! !
  174. ! elseif (SEC2(4) == 50) then SPHERICAL HARMONIC COEFFICIENTS !
  175. ! !
  176. ! INFOGRID/GRIDINFO: !
  177. ! !
  178. ! 1 : J-pentagonal resolution parameter !
  179. ! 2 : K-pentagonal resolution parameter !
  180. ! 3 : M-pentagonal resolution parameter !
  181. ! 4 : Spectral representation type (ON388 Table 9) !
  182. ! 5 : Coefficient storage mode (ON388 Table 10) !
  183. ! !
  184. ! elseif (SEC2(4) == ?) then ?? !
  185. ! !
  186. ! !
  187. ! SEC3: GRIB Header Section 3 information: !
  188. ! SEC4: GRIB Header Section 4 information: !
  189. !
  190. !
  191. !
  192. module module_grib
  193. !
  194. ! Machine wordsize must be known for the various unpacking routines to work.
  195. ! Machine wordsize is set through CPP Directives.
  196. ! Use options -DBIT32 (for 32-bit word-size) or -DBIT64 (for 64-bit wordsize)
  197. ! for the CPP pass of the compiler.
  198. !
  199. #if defined (BIT32)
  200. integer, parameter :: MWSIZE = 32 ! Machine word size in bits
  201. #elif defined (BIT64)
  202. integer, parameter :: MWSIZE = 64 ! Machine word size in bits
  203. #endif
  204. ! Array GREC holds a single packed GRIB record (header and all).
  205. ! Array BITMAP holds the bitmap (if a bitmap was used).
  206. !
  207. ! For some reason, the cray does not like grec to be allocatable.
  208. !
  209. #if defined (CRAY)
  210. integer, dimension(100000) :: grec
  211. integer, dimension(100000) :: bitmap
  212. #else
  213. integer, allocatable, save, dimension(:) :: grec
  214. integer, allocatable, save, dimension(:) :: bitmap
  215. #endif
  216. ! SEC0 holds the Section 0 header information
  217. ! SEC1 holds the Section 1 header information
  218. ! SEC2 holds the Section 2 header information
  219. ! SEC3 holds the Section 3 header information
  220. ! SEC4 holds the Section 4 header information
  221. ! XEC4 holds floating-point Section 4 header information
  222. integer, dimension(2) :: sec0
  223. integer, dimension(100) :: sec1
  224. integer, dimension(10) :: sec2
  225. integer, dimension(10) :: sec3
  226. integer, dimension(10) :: sec4
  227. real, dimension(1) :: xec4
  228. integer :: sevencount = 0
  229. ! INFOGRID holds integer values defining the grid.
  230. ! GRIDINFO holds floating-point values definint the grid
  231. integer, dimension(40) :: infogrid
  232. real, dimension(40) :: gridinfo
  233. integer :: ied
  234. real, parameter :: pi = 3.1415926534
  235. real, parameter :: degran = pi/180.
  236. real, parameter :: raddeg = 1./degran
  237. real :: glat1, glon1, gclon, gtrue1, gtrue2, grrth, gx1, gy1, gkappa
  238. contains
  239. !
  240. !=============================================================================!
  241. !=============================================================================!
  242. !=============================================================================!
  243. !
  244. integer function gribsize(trec, ilen, ierr)
  245. !-----------------------------------------------------------------------------!
  246. ! Return the size of a single GRIB record. !
  247. ! !
  248. ! Input: !
  249. ! TREC: At least a portion of the complete GRIB record. !
  250. ! ILEN: The size of array TREC. !
  251. ! !
  252. ! Output !
  253. ! GRIBSIZE: The size of the full GRIB record !
  254. ! IERR : 0= no errors, 1 = read error
  255. ! !
  256. ! Side Effects: !
  257. ! * Module variable IED is set to the GRIB Edition number. !
  258. ! * STOP, if not GRIB Edition 0 or 1 !
  259. ! !
  260. ! Externals !
  261. ! GBYTE !
  262. ! !
  263. !-----------------------------------------------------------------------------!
  264. implicit none
  265. integer :: ilen
  266. integer, dimension(ilen) :: trec
  267. integer :: isz0 = 32
  268. integer :: isz1 = 0
  269. integer :: isz2 = 0
  270. integer :: isz3 = 0
  271. integer :: isz4 = 0
  272. integer :: isz5 = 32
  273. integer :: iflag
  274. integer :: ierr
  275. character :: pname*132
  276. ierr = 0
  277. ! Unpack the GRIB Edition number, located in the eighth byte (bits 57-64) !
  278. ! of array TREC. !
  279. call gbyte_g1(trec, ied, 56, 8)
  280. ! GRIB Edition 1 has the size of the whole GRIB record right up front. !
  281. if (ied.eq.1) then
  282. ! Grib1
  283. ! Find the size of the whole GRIB record
  284. call gbyte_g1(trec, gribsize, 32, 24)
  285. ! GRIB Edition 0 does not include the total size, so we have to sum up !
  286. ! the sizes of the individual sections !
  287. elseif (ied.eq.0) then
  288. ! Grib old edition
  289. ! Find the size of section 1.
  290. call gbyte_g1(trec, isz1, isz0, 24)
  291. isz1 = isz1 * 8
  292. call gbyte_g1(trec, iflag, isz0+56, 8)
  293. if ((iflag.eq.128).or.(iflag.eq.192)) then ! section 2 is there
  294. ! Find the size of section 2.
  295. call gbyte_g1(trec, isz2, isz0+isz1, 24)
  296. isz2 = isz2 * 8
  297. endif
  298. if ((iflag.eq.64).or.(iflag.eq.192)) then ! Section 3 is there
  299. ! Find the size of section 3.
  300. call gbyte_g1(trec, isz3, isz0+isz1+isz2, 24)
  301. isz3 = isz3 * 8
  302. endif
  303. ! Find the size of section 4.
  304. call gbyte_g1(trec, isz4, isz0+isz1+isz2+isz3, 24)
  305. isz4 = isz4 * 8
  306. ! Total the sizes of sections 0 through 5.
  307. gribsize = (isz0+isz1+isz2+isz3+isz4+isz5) / 8
  308. elseif (ied.eq.2) then
  309. ! Grib2
  310. CALL getarg ( 0 , pname )
  311. write(*,'("*** stopping in gribcode ***\n")')
  312. write(*,'("\tI was expecting a Grib1 file, but this is a Grib2 file.")')
  313. if ( index(pname,'ungrib.exe') .ne. 0 ) then
  314. write(*,'("\tIt is possible this is because your GRIBFILE.XXX files")')
  315. write(*,'("\tare not all of the same type.")')
  316. write(*,'("\tWPS can handle both file types, but a separate ungrib")')
  317. write(*,'("\tjob must be run for each Grib type.\n")')
  318. else
  319. write(*,'("\tUse g2print on Grib2 files\n")')
  320. endif
  321. stop 'gribsize in gribcode'
  322. else
  323. write(*,'("Error trying to read grib edition number in gribsize.")')
  324. write(*,'("Possible corrupt grib file.")')
  325. write(6,*) 'Incorrect edition number = ',ied
  326. write(6,*) 'Skipping the rest of the file and continuing.'
  327. ierr = 1
  328. endif
  329. end function gribsize
  330. !
  331. !=============================================================================!
  332. !=============================================================================!
  333. !=============================================================================!
  334. !
  335. subroutine findgrib(nunit, isize, ierr)
  336. !-----------------------------------------------------------------------------!
  337. ! !
  338. ! Find the string "GRIB", which starts off a GRIB record. !
  339. ! !
  340. ! Input: !
  341. ! NUNIT: The C unit to read from. This should already be opened. !
  342. ! !
  343. ! Output: !
  344. ! ISIZE: The size in bytes of one complete GRIB Record !
  345. ! IERR: Error flag, !
  346. ! 0 : No error or end-of-file on reading !
  347. ! 1 : Hit the end of file !
  348. ! 2 : Error on reading !
  349. ! !
  350. ! Side effects: !
  351. ! * The pointer to C unit NUNIT is set to the beginning of the next !
  352. ! GRIB record. !
  353. ! * The first time FINDGRIB is called, the integer GTEST is set to !
  354. ! a value equivalent to the string 'GRIB' !
  355. ! !
  356. ! Modules: !
  357. ! MODULE_GRIB !
  358. ! !
  359. ! Externals: !
  360. ! BN_READ !
  361. ! BN_SEEK !
  362. ! GRIBSIZE !
  363. ! !
  364. !-----------------------------------------------------------------------------!
  365. implicit none
  366. integer, intent(in) :: nunit
  367. integer, intent(out) :: isize
  368. integer, intent(out) :: ierr
  369. integer, parameter :: LENTMP=100
  370. integer, dimension(lentmp) :: trec
  371. integer :: isz, itest, icnt
  372. integer, save :: gtest = 0
  373. ! Set the integer variable GTEST to hold the integer representation of the
  374. ! character string 'GRIB'. This integer variable is later compared to
  375. ! integers we read from the GRIB file, to find the beginning of a GRIB record.
  376. if (gtest.eq.0) then
  377. if (mwsize.eq.32) then
  378. gtest = transfer('GRIB', gtest)
  379. elseif(mwsize.eq.64) then
  380. call gbyte_g1(char(0)//char(0)//char(0)//char(0)//'GRIB', gtest, 0, mwsize)
  381. endif
  382. endif
  383. ierr = 0
  384. icnt = 0
  385. LOOP : DO
  386. ! Read LENTMP bytes into holding array TREC.
  387. call bn_read(nunit, trec, lentmp, isz, ierr, 0)
  388. if (ierr.eq.1) then
  389. return
  390. elseif (ierr.eq.2) then
  391. write(*,'("Error reading GRIB: IERR = ", I2)') ierr
  392. return
  393. endif
  394. ! Reposition the file pointer back to where we started.
  395. call bn_seek(nunit, -isz, 0, 0)
  396. ! Compare the first four bytes of TREC with the string 'GRIB' stored in
  397. ! integer variable GTEST.
  398. if (mwsize.eq.32) then
  399. if (trec(1) == gtest) exit LOOP
  400. elseif (mwsize.eq.64) then
  401. call gbyte_g1(trec, itest, 0, 32)
  402. if (itest == gtest) exit LOOP
  403. endif
  404. ! Advance the file pointer one byte.
  405. call bn_seek(nunit, 1, 0, 0)
  406. icnt = icnt + 1
  407. if ( icnt .gt. 100000) then ! stop if we cannot find the GRIB string
  408. write(*,'("*** stopping in findgrib in gribcode ***\n")')
  409. write(*,'("\tI could not find the GRIB string in the input file")')
  410. write(*,'("\tafter testing the first 100,000 bytes.")')
  411. write(*,'("\tEither the file is corrupt or it is not a GRIB file.\n")')
  412. stop 'findgrib'
  413. endif
  414. ENDDO LOOP
  415. !#if defined (DEC) || defined (ALPHA) || defined (alpha) || defined (LINUX)
  416. #ifdef BYTESWAP
  417. call swap4(trec, isz)
  418. #endif
  419. isize = gribsize(trec, isz, ierr)
  420. end subroutine findgrib
  421. !
  422. !=============================================================================!
  423. !=============================================================================!
  424. !=============================================================================!
  425. !
  426. subroutine SGUP_NOBITMAP(datarray, ndat)
  427. ! Simple grid-point unpacking
  428. implicit none
  429. integer :: ndat
  430. real , dimension(ndat) :: datarray
  431. integer, dimension(ndat) :: IX
  432. real :: dfac, bfac
  433. integer :: iskip
  434. DFAC = 10.**(-sec1(24))
  435. BFAC = 2.**sec4(7)
  436. if (ied.eq.0) then
  437. iskip = 32 + sec1(1)*8 + sec2(1)*8 + sec3(1)*8 + 11*8
  438. elseif (ied.eq.1) then
  439. iskip = 64 + sec1(1)*8 + sec2(1)*8 + sec3(1)*8 + 11*8
  440. endif
  441. ! sec4(8) is the number of bits used per datum value.
  442. ! If sec4(8) = 255, assume they mean sec4(8) = 0
  443. if (sec4(8) == 255) then
  444. sec4(8) = 0
  445. endif
  446. ! If sec4(8) is 0, assume datarray is constant value of xec4(1)
  447. if (sec4(8).eq.0) then
  448. !!! HERE IS THE ORIGINAL NCAR CODE:
  449. ! datarray = xec4(1)
  450. !!! HERE IS WHAT FSL CHANGED IT TO:
  451. datarray = DFAC*xec4(1)
  452. !!! because even though it is a constant value
  453. !!! your still need to scale by the decimal scale factor.
  454. else
  455. !!! FSL developers MOVED THE CALL TO gbytes FROM line 441 ABOVE
  456. !!! BECAUSE IF sec4(8)==0 BEFORE gbytes IS CALLED, THE MASKS ARRAY
  457. !!! IN gbytes WILL BE INDEXED OUT OF BOUNDS. C HARROP 9/16/04
  458. call gbytes_g1(grec, IX, iskip, sec4(8), 0, ndat)
  459. datarray = DFAC * (xec4(1) + (IX*BFAC))
  460. endif
  461. end subroutine SGUP_NOBITMAP
  462. !
  463. !=============================================================================!
  464. !=============================================================================!
  465. !=============================================================================!
  466. !
  467. subroutine SGUP_BITMAP(datarray, ndat)
  468. ! Simple grid-point unpacking, with a bitmap.
  469. implicit none
  470. integer :: ndat ! Number of data points in the final grid.
  471. real , dimension(ndat) :: datarray ! Array holding the final unpacked data.
  472. real :: dfac, bfac
  473. integer :: iskip, nbm, i, nn
  474. integer, allocatable, dimension(:) :: bmdat
  475. ! SEC4(1) : The number of bytes in the whole of GRIB Section 4.
  476. ! SEC4(6) : The number of unused bits at the end of GRIB Section 4.
  477. ! SEC4(8) : The number of bits per data value.
  478. datarray = -1.E30
  479. ! 1) There are fewer than NDAT data values, because a bitmap was used.
  480. ! Compute the number of data values (NBM). There are 11 extra bytes
  481. ! in the header section 4. NBM equals the total number of data bits (not
  482. ! counting the header bits), minus the number of unused buts, and then
  483. ! divided by the number of bits per data value.
  484. ! If sec4(8) is 0, assume datarray is constant value of xec4(1)
  485. if (sec4(8).eq.0) then
  486. where(bitmap(1:ndat).eq.1) datarray = xec4(1)
  487. return
  488. endif
  489. nbm = ((sec4(1)-11)*8-sec4(6))/sec4(8)
  490. allocate(bmdat(nbm))
  491. ! Compute the parameters involved with packing
  492. DFAC = 10.**(-sec1(24))
  493. BFAC = 2.**sec4(7)
  494. ! Set ISKIP to the beginning of the data.
  495. if (ied.eq.0) then
  496. iskip = 32 + sec1(1)*8 + sec2(1)*8 + sec3(1)*8 + 11*8
  497. elseif (ied.eq.1) then
  498. iskip = 64 + sec1(1)*8 + sec2(1)*8 + sec3(1)*8 + 11*8
  499. endif
  500. ! Read the data from the GREC array
  501. call gbytes_g1(grec, bmdat, iskip, sec4(8), 0, nbm)
  502. ! sec4(8) is the number of bits used per datum value.
  503. ! If sec4(8) = 255, assume they mean sec4(8) = 0
  504. if (sec4(8) == 255) sec4(8) = 0
  505. ! Unpack the data according to packing parameters DFAC, BFAC, and XEC4(1),
  506. ! and masked by the bitmap BITMAP.
  507. nn = 0
  508. do i = 1, ndat
  509. if (bitmap(i).eq.1) then
  510. nn = nn + 1
  511. datarray(i) = DFAC * (xec4(1) + (bmdat(nn)*BFAC))
  512. endif
  513. enddo
  514. ! Deallocate the scratch BMDAT array
  515. deallocate(bmdat)
  516. end subroutine SGUP_BITMAP
  517. !
  518. !=============================================================================!
  519. !=============================================================================!
  520. !=============================================================================!
  521. !
  522. subroutine CSHUP(pdata, ndat)
  523. ! ECMWFs unpacking of ECMWFs Complex Spherical Harmonic packing
  524. ! Adapted from ECMWFs GRIBEX package.
  525. implicit none
  526. integer :: ndat
  527. real , dimension(ndat) :: pdata
  528. integer, dimension(ndat+500) :: IX
  529. integer :: iskip, isign
  530. integer :: N1, IPOWER, J, K, M, nval
  531. real :: zscale, zref
  532. integer :: ic, jm, iuc, il2, inum, jn
  533. integer :: inext, ilast, ioff, jrow, index, i, jcol
  534. real :: bval
  535. integer, allocatable, dimension(:) :: iexp, imant
  536. real , dimension(0:400) :: factor
  537. real :: power
  538. integer :: N
  539. index = -1
  540. if (ied.eq.0) then
  541. iskip = 32 + sec1(1)*8 + sec2(1)*8 + sec3(1)*8 + 11*8
  542. elseif(ied.eq.1) then
  543. iskip = 64 + sec1(1)*8 + sec2(1)*8 + sec3(1)*8 + 11*8
  544. endif
  545. call gbyte_g1(grec,N1,iskip,16)
  546. iskip = iskip + 16
  547. call gbyte_g1(grec,ipower,iskip,16)
  548. iskip = iskip + 16
  549. if (ipower.ge.32768) ipower = 32768-ipower
  550. ! Unpack the resolution parameters for the initial (small) truncation:
  551. call gbyte_g1(grec,J,iskip,8)
  552. iskip = iskip + 8
  553. call gbyte_g1(grec,K,iskip,8)
  554. iskip = iskip + 8
  555. call gbyte_g1(grec,M,iskip,8)
  556. iskip = iskip + 8
  557. zscale = 2.**sec4(7)
  558. iskip = N1*8
  559. nval = NDAT - (J+1)*(J+2)
  560. call gbytes_g1(grec, ix, iskip, sec4(8), 0, nval)
  561. ! sec4(8) is the number of bits used per datum value.
  562. ! If sec4(8) = 255, assume they mean sec4(8) = 0
  563. if (sec4(8) == 255) sec4(8) = 0
  564. pdata(1:nval) = (float(ix(1:nval))*zscale)+xec4(1)
  565. IUC = NDAT+1
  566. IC = NVAL+1
  567. DO JM=INFOGRID(1),0,-1
  568. IL2=MAX(JM,J+1)
  569. INUM=2*(INFOGRID(1)-IL2+1)
  570. pdata(iuc-inum:iuc-1) = pdata(ic-inum:ic-1)
  571. iuc = iuc - inum
  572. ic = ic - inum
  573. IUC = IUC-MAX((IL2-JM)*2,0)
  574. ENDDO
  575. if (ied.eq.0) then
  576. iskip = 32 + sec1(1)*8 + sec2(1)*8 + sec3(1)*8 + 11*8
  577. elseif (ied.eq.1) then
  578. iskip = 64 + sec1(1)*8 + sec2(1)*8 + sec3(1)*8 + 18*8
  579. endif
  580. allocate(iexp(802))
  581. allocate(imant(802))
  582. ilast=j+1
  583. do jrow=1,ilast
  584. inext = 2*(ilast-jrow+1)
  585. ! extract all the exponents
  586. call gbytes_g1(grec, iexp, iskip, 8, 24, inext)
  587. ! extract all the mantissas
  588. ioff = 8
  589. call gbytes_g1(grec, imant, iskip+8, 24, 8, inext)
  590. iskip = iskip + inext*32
  591. ! Build the real values from mantissas and exponents
  592. bval = 2.**(-24)
  593. i = 0
  594. do jcol = jrow, infogrid(1)+1
  595. index = index + 2
  596. if (ilast.ge.jcol) then
  597. i = i + 1
  598. if ((iexp(i).eq.128.or.iexp(i).eq.0).and.(imant(i).eq.0)) then
  599. pdata(i) = 0
  600. else
  601. if (iexp(i).ge.128) then
  602. iexp(i) = iexp(i) - 128
  603. isign = -1
  604. else
  605. isign = 1
  606. endif
  607. pdata(index) = isign*bval*IMANT(i)*16.**(IEXP(i)-64)
  608. i = i + 1
  609. if (iexp(i).ge.128) then
  610. iexp(i) = iexp(i) - 128
  611. isign = -1
  612. else
  613. isign = 1
  614. endif
  615. pdata(index+1) = isign*bval*IMANT(i)*16.**(IEXP(i)-64)
  616. endif
  617. endif
  618. enddo
  619. enddo
  620. !Apply power scaling:
  621. if (ipower.ne.0) then
  622. power = float(ipower) / 1000.0
  623. factor(0) = 1.0
  624. do n = 1 , infogrid(1)
  625. if( ipower .ne. 1000 ) then
  626. factor(n) = 1.0 / (n * (n+1) )**power
  627. else
  628. factor(n) = 1.0 / (n * (n + 1))
  629. endif
  630. enddo
  631. INDEX = -1
  632. DO M = 0 , J-1
  633. DO N = M , INFOGRID(1)
  634. INDEX = INDEX + 2
  635. IF ( N .GE. J ) THEN
  636. PDATA(INDEX:INDEX+1) = PDATA(INDEX:INDEX+1) * FACTOR(N)
  637. ENDIF
  638. ENDDO
  639. ENDDO
  640. DO M = J , INFOGRID(1)
  641. DO N = M , INFOGRID(1)
  642. INDEX = INDEX + 2
  643. PDATA(INDEX:INDEX+1) = PDATA(INDEX:INDEX+1) * FACTOR(N)
  644. ENDDO
  645. ENDDO
  646. endif
  647. end subroutine CSHUP
  648. !
  649. !=============================================================================!
  650. !=============================================================================!
  651. !=============================================================================!
  652. !
  653. !
  654. !
  655. ! Trigonometric functions which deal with degrees, rather than radians:
  656. !
  657. real function sind(theta)
  658. real :: theta
  659. sind = sin(theta*degran)
  660. end function sind
  661. real function cosd(theta)
  662. real :: theta
  663. cosd = cos(theta*degran)
  664. end function cosd
  665. real function tand(theta)
  666. real :: theta
  667. tand = tan(theta*degran)
  668. end function tand
  669. real function atand(x)
  670. real :: x
  671. atand = atan(x)*raddeg
  672. end function atand
  673. real function atan2d(x,y)
  674. real :: x,y
  675. atan2d = atan2(x,y)*raddeg
  676. end function atan2d
  677. real function asind(x)
  678. real :: x
  679. asind = asin(x)*raddeg
  680. end function asind
  681. real function acosd(x)
  682. real :: x
  683. acosd = acos(x)*raddeg
  684. end function acosd
  685. !
  686. !=============================================================================!
  687. !=============================================================================!
  688. !=============================================================================!
  689. !
  690. end module module_grib
  691. !
  692. !=============================================================================!
  693. !=============================================================================!
  694. !=============================================================================!
  695. !
  696. subroutine gribget(nunit, ierr)
  697. use module_grib
  698. !-----------------------------------------------------------------------------!
  699. ! !
  700. ! Read a single GRIB record, with no unpacking of any header or data fields. !
  701. ! !
  702. ! Input: !
  703. ! NUNIT: C unit number to read from. This should already be open. !
  704. ! !
  705. ! Output: !
  706. ! IERR: Error flag, Non-zero means there was a problem with the read. !
  707. ! !
  708. ! Side Effects: !
  709. ! The array GREC is allocated, and filled with one GRIB record. !
  710. ! The C unit pointer is moved to the end of the GRIB record just read. !
  711. ! !
  712. ! Modules: !
  713. ! MODULE_GRIB !
  714. ! !
  715. ! Externals: !
  716. ! FINDGRIB !
  717. ! BN_READ !
  718. ! !
  719. !-----------------------------------------------------------------------------!
  720. implicit none
  721. integer :: nunit
  722. integer :: ierr
  723. integer :: isz, isize
  724. ! Position the file pointer at the beginning of the GRIB record.
  725. call findgrib(nunit, isize, ierr)
  726. if (ierr.ne.0) return
  727. ! Allocate the GREC array to be able to hold the data
  728. #if defined (CRAY)
  729. #else
  730. allocate(grec((isize+(mwsize/8-1))/(mwsize/8)))
  731. #endif
  732. ! Read the full GRIB record.
  733. call bn_read(nunit, grec, isize, isz, ierr, 1)
  734. !#if defined (DEC) || defined (ALPHA) || defined (alpha) || defined (LINUX)
  735. #ifdef BYTESWAP
  736. call swap4(grec, isz)
  737. #endif
  738. end subroutine gribget
  739. !
  740. !=============================================================================!
  741. !=============================================================================!
  742. !=============================================================================!
  743. !
  744. subroutine gribread(nunit, data, ndata, debug_level, ierr)
  745. !-----------------------------------------------------------------------------!
  746. ! Read one grib record, unpack the header and data information. !
  747. ! !
  748. ! Input: !
  749. ! NUNIT: C Unit to read from. !
  750. ! NDATA: Size of array DATA (Should be >= NDAT as computed herein.) !
  751. ! !
  752. ! Output: !
  753. ! DATA: The unpacked data array !
  754. ! IERR: Error flag, non-zero means there was a problem. !
  755. ! !
  756. ! Side Effects: !
  757. ! * Header arrays SEC0, SEC1, SEC2, SEC3, SEC4, XEC4, INFOGRID and !
  758. ! INFOGRID are filled. !
  759. ! * The BITMAP array is filled. !
  760. ! * The C unit pointer is advanced to the end of the GRIB record. !
  761. ! !
  762. ! Modules: !
  763. ! MODULE_GRIB !
  764. ! !
  765. ! Externals: !
  766. ! GRIBGET !
  767. ! GRIBHEADER !
  768. ! GRIBDATA !
  769. ! !
  770. !-----------------------------------------------------------------------------!
  771. use module_grib
  772. implicit none
  773. integer :: nunit
  774. integer :: debug_level
  775. integer :: ierr
  776. real, allocatable, dimension(:) :: datarray
  777. integer :: ndata
  778. real, dimension(ndata) :: data
  779. integer :: ni, nj
  780. ierr = 0
  781. call gribget(nunit, ierr)
  782. if (ierr.ne.0) return
  783. ! Unpack the header information
  784. call gribheader(debug_level,ierr)
  785. ! Determine the size of the data array from the information in the header,
  786. ! and allocate the array DATARRAY to hold that data.
  787. if (sec2(4).ne.50) then
  788. ni = infogrid(1)
  789. nj = infogrid(2)
  790. allocate(datarray(ni*nj))
  791. else
  792. ni = (infogrid(1)+1) * (infogrid(1)+2)
  793. nj = 1
  794. allocate(datarray(ni*nj))
  795. endif
  796. ! Unpack the data from the GRIB record, and fill the array DATARRAY.
  797. call gribdata(datarray, ni*nj)
  798. data(1:ni*nj) = datarray(1:ni*nj)
  799. #if defined (CRAY)
  800. #else
  801. deallocate(grec, datarray)
  802. #endif
  803. end subroutine gribread
  804. !
  805. !=============================================================================!
  806. !=============================================================================!
  807. !=============================================================================!
  808. !
  809. subroutine get_sec1(ksec1)
  810. ! Return the GRIB Section 1 header information, which has already been
  811. ! unpacked by subroutine GRIBHEADER.
  812. use module_grib
  813. integer, dimension(100) :: ksec1
  814. ksec1 = sec1
  815. end subroutine get_sec1
  816. !
  817. !=============================================================================!
  818. !=============================================================================!
  819. !=============================================================================!
  820. !
  821. subroutine get_sec2(ksec2)
  822. ! Return the GRIB Section 2 header information, which has already been
  823. ! unpacked by subroutine GRIBHEADER.
  824. use module_grib
  825. integer, dimension(10) :: ksec2
  826. ksec2 = sec2
  827. end subroutine get_sec2
  828. !
  829. !=============================================================================!
  830. !=============================================================================!
  831. !=============================================================================!
  832. !
  833. subroutine get_gridinfo(iginfo, ginfo)
  834. use module_grib
  835. integer, dimension(40) :: iginfo
  836. real, dimension(40) :: ginfo
  837. iginfo = infogrid
  838. ginfo = gridinfo
  839. end subroutine get_gridinfo
  840. !
  841. !=============================================================================!
  842. !=============================================================================!
  843. !=============================================================================!
  844. !
  845. subroutine gribprint(isec)
  846. use module_grib
  847. implicit none
  848. integer :: isec
  849. integer :: ou = 6
  850. character(len=12) :: string = ',t45,":",i8)'
  851. character(len=15) :: rstring = ',t45,":",f12.5)'
  852. if (isec.eq.0) then
  853. write(*,'(/,"GRIB SECTION 0:")')
  854. write(ou,'(5x,"Grib Length"'//string) sec0(1)
  855. write(ou,'(5x,"Grib Edition"'//string) sec0(2)
  856. else if (isec.eq.1) then
  857. write(*,'(/,"GRIB SECTION 1:")')
  858. write(ou,'(5x,"Length of PDS"'//string) sec1(1)
  859. write(ou,'(5x,"Parameter Table Version"'//string) sec1(2)
  860. write(ou,'(5x,"Center ID"'//string) sec1(3)
  861. write(ou,'(5x,"Process ID"'//string) sec1(4)
  862. write(ou,'(5x,"Grid ID"'//string) sec1(5)
  863. if (sec1(25) == 1) then
  864. write(ou,'(5x,"Is there a Grid Desc. Section (GDS)?",t45,": Yes")')
  865. else if (sec1(25) == 0) then
  866. write(ou,'(5x,"Is there a Grid Desc. Section (GDS)?",t45,": No")')
  867. else
  868. print*, 'Unrecognized sec1(25): ', sec1(25)
  869. endif
  870. if (sec1(26) == 1) then
  871. write(ou,'(5x,"Is there a Bit Map Section (BMS)?",t45,": Yes")')
  872. else if (sec1(26) == 0) then
  873. write(ou,'(5x,"Is there a Bit Map Section (BMS)?",t45,": No")')
  874. else
  875. print*, 'Unrecognized sec1(26): ', sec1(26)
  876. endif
  877. write(ou,'(5x,"Parameter"'//string) sec1(7)
  878. write(ou,'(5x,"Level type"'//string) sec1(8)
  879. if ( (sec1(8) == 101) .or. (sec1(8) == 104) .or. (sec1(8) == 106) .or. &
  880. (sec1(8) == 108) .or. (sec1(8) == 110) .or. (sec1(8) == 112) .or. &
  881. (sec1(8) == 114) .or. (sec1(8) == 116) .or. (sec1(8) == 120) .or. &
  882. (sec1(8) == 121) .or. (sec1(8) == 128) .or. (sec1(8) == 141) ) then
  883. write(ou,'(5x,"Hgt, pres, etc. of layer top "'//string) sec1(9)
  884. write(ou,'(5x,"Hgt, pres, etc. of layer bottom "'//string) sec1(10)
  885. else
  886. write(ou,'(5x,"Height, pressure, etc "'//string) sec1(9)
  887. endif
  888. write(ou,'(5x,"Year"'//string) sec1(11)
  889. write(ou,'(5x,"Month"'//string) sec1(12)
  890. write(ou,'(5x,"Day"'//string) sec1(13)
  891. write(ou,'(5x,"Hour"'//string) sec1(14)
  892. write(ou,'(5x,"Minute"'//string) sec1(15)
  893. write(ou,'(5x,"Forecast time unit"'//string) sec1(16)
  894. write(ou,'(5x,"P1"'//string) sec1(17)
  895. write(ou,'(5x,"P2"'//string) sec1(18)
  896. write(ou,'(5x,"Time Range Indicator"'//string) sec1(19)
  897. write(ou,'(5x,"Number in Ave?"'//string) sec1(20)
  898. write(ou,'(5x,"Number missing from ave?"'//string) sec1(21)
  899. write(ou,'(5x,"Century"'//string) sec1(22)
  900. write(ou,'(5x,"Sub-center"'//string) sec1(23)
  901. write(ou,'(5x,"Decimal scale factor"'//string) sec1(24)
  902. elseif ((isec.eq.2) .and. ((sec1(6).eq.128).or.(sec1(6).eq.192))) then
  903. write(*,'(/,"GRIB SECTION 2:")')
  904. write(ou,'(5x,"Length of GRID Desc. Section"'//string) sec2(1)
  905. if ((sec2(2) /= 0).or.(sec2(3) /= 0) .or. (sec2(4) /= 0)) then
  906. write(ou,'(5x,"Number of V. Coordinate Parms"'//string) sec2(2)
  907. write(ou,'(5x,"List Starting point"'//string) sec2(3)
  908. write(ou,'(5x,"Data Representation type"'//string) sec2(4)
  909. endif
  910. if (sec2(4).eq.0) then
  911. write(ou,'(5x,"Cylindrical Equidistant Grid")')
  912. write(ou,'(10x,"NI"'//string) infogrid(1)
  913. write(ou,'(10x,"NJ"'//string) infogrid(2)
  914. write(ou,'(10x,"Lat 1"'//rstring) gridinfo(3)
  915. write(ou,'(10x,"Lon 1"'//rstring) gridinfo(4)
  916. write(ou,'(10x,"Resolution and Component:", t45,":",B8.8)') infogrid(5)
  917. write(ou,'(10x,"Lat NI"'//string) infogrid(6)
  918. write(ou,'(10x,"Lon NJ"'//string) infogrid(7)
  919. write(ou,'(10x,"Delta-Lon"'//string) infogrid(8)
  920. write(ou,'(10x,"Delta-Lat"'//string) infogrid(9)
  921. write(ou,'(10x,"Scanning mode"'//string) infogrid(10)
  922. write(ou,'(10x,"I-Scanning increment"'//string) infogrid(21)
  923. write(ou,'(10x,"J-Scanning increment"'//string) infogrid(22)
  924. else if (sec2(4).eq.1) then
  925. write(ou,'(5x,"Mercator Grid")')
  926. write(ou,'(10x,"NI"'//string) infogrid(1)
  927. write(ou,'(10x,"NJ"'//string) infogrid(2)
  928. write(ou,'(10x,"Lat 1"'//rstring) gridinfo(3)
  929. write(ou,'(10x,"Lon 1"'//rstring) gridinfo(4)
  930. write(ou,'(10x,"Resolution and Component",t45,":", B8.8)') infogrid(5)
  931. write(ou,'(10x,"Lat NI"'//rstring) gridinfo(6)
  932. write(ou,'(10x,"Lon NJ"'//rstring) gridinfo(7)
  933. write(ou,'(10x,"Dx"'//rstring) gridinfo(8)
  934. write(ou,'(10x,"Dy"'//rstring) gridinfo(9)
  935. write(ou,'(10x,"Scanning mode"'//string) infogrid(10)
  936. write(ou,'(10x,"Latin"'//rstring) gridinfo(11)
  937. write(ou,'(10x,"I-Scanning increment"'//string) infogrid(21)
  938. write(ou,'(10x,"J-Scanning increment"'//string) infogrid(22)
  939. else if (sec2(4).eq.4) then
  940. write(ou,'(5x,"Gaussian Grid")')
  941. write(ou,'(10x,"NI"'//string) infogrid(1)
  942. write(ou,'(10x,"NJ"'//string) infogrid(2)
  943. write(ou,'(10x,"Original (stored) Lat 1"'//rstring) gridinfo(18)
  944. write(ou,'(10x,"Lat 1"'//rstring) gridinfo(3)
  945. write(ou,'(10x,"Lon 1"'//rstring) gridinfo(4)
  946. write(ou,'(10x,"Resolution and Component",t45,":", B8.8)') infogrid(5)
  947. write(ou,'(10x,"Original (stored) Lat NI"'//rstring) gridinfo(17)
  948. write(ou,'(10x,"Lat NI"'//rstring) gridinfo(6)
  949. write(ou,'(10x,"Lon NJ"'//rstring) gridinfo(7)
  950. write(ou,'(10x,"Delta-Lon"'//rstring) gridinfo(8)
  951. write(ou,'(10x,"Delta-Lat"'//rstring) gridinfo(19)
  952. write(ou,'(10x,"Number of lats (pole - eq)"'//string) infogrid(9)
  953. write(ou,'(10x,"Scanning mode"'//string) infogrid(10)
  954. write(ou,'(10x,"I-Scanning increment"'//string) infogrid(21)
  955. write(ou,'(10x,"J-Scanning increment"'//string) infogrid(22)
  956. elseif (sec2(4).eq.3) then
  957. write(ou,'(5x,"Lambert Conformal Grid")')
  958. write(ou,'(10x,"NI"'//string) infogrid(1)
  959. write(ou,'(10x,"NJ"'//string) infogrid(2)
  960. write(ou,'(10x,"Lat 1"'//string) infogrid(3)
  961. write(ou,'(10x,"Lon 1"'//string) infogrid(4)
  962. write(ou,'(10x,"Resolution and Component",t45,":", B8.8)') infogrid(5)
  963. write(ou,'(10x,"Lov"'//string) infogrid(6)
  964. write(ou,'(10x,"Dx"'//string) infogrid(7)
  965. write(ou,'(10x,"Dy"'//string) infogrid(8)
  966. write(ou,'(10x,"Projection center"'//string) infogrid(9)
  967. write(ou,'(10x,"Scanning mode"'//string) infogrid(10)
  968. write(ou,'(10x,"I-Scanning increment"'//string) infogrid(21)
  969. write(ou,'(10x,"J-Scanning increment"'//string) infogrid(22)
  970. write(ou,'(10x,"Latin 1"'//string) infogrid(11)
  971. write(ou,'(10x,"Latin 2"'//string) infogrid(12)
  972. write(ou,'(10x,"Lat of southern pole"'//string) infogrid(13)
  973. write(ou,'(10x,"Lon of southern pole"'//string) infogrid(14)
  974. elseif (sec2(4).eq.5) then
  975. write(ou,'(5x,"Polar Stereographic Grid")')
  976. write(ou,'(10x,"NI"'//string) infogrid(1)
  977. write(ou,'(10x,"NJ"'//string) infogrid(2)
  978. write(ou,'(10x,"Lat 1"'//string) infogrid(3)
  979. write(ou,'(10x,"Lon 1"'//string) infogrid(4)
  980. write(ou,'(10x,"Resolution and Component", t45,":",B8.8)') infogrid(5)
  981. write(ou,'(10x,"Lov"'//string) infogrid(6)
  982. write(ou,'(10x,"Dx"'//string) infogrid(7)
  983. write(ou,'(10x,"Dy"'//string) infogrid(8)
  984. write(ou,'(10x,"Projection center"'//string) infogrid(9)
  985. write(ou,'(10x,"Scanning mode"'//string) infogrid(10)
  986. write(ou,'(10x,"I-Scanning increment"'//string) infogrid(21)
  987. write(ou,'(10x,"J-Scanning increment"'//string) infogrid(22)
  988. elseif (sec2(4).eq.50) then
  989. write(ou,'(5x,"Spherical harmonic components")')
  990. write(ou,'(10x,"J-Pentagonal resolution parm:"'//string) infogrid(1)
  991. write(ou,'(10x,"K-Pentagonal resolution parm:"'//string) infogrid(2)
  992. write(ou,'(10x,"M-Pentagonal resolution parm:"'//string) infogrid(3)
  993. write(ou,'(10x,"Representation type"'//string) infogrid(4)
  994. write(ou,'(10x,"Coefficient storage mode"'//string) infogrid(5)
  995. endif
  996. elseif ((isec.eq.3) .and. (sec1(26).eq.1)) then
  997. write(*,'(/,"GRIB SECTION 3:")')
  998. write(ou,'(5x,"Length of bit map section"'//string) sec3(1)
  999. write(ou,'(5x,"Number of unused bits"'//string) sec3(2)
  1000. write(ou,'(5x,"Numeric"'//string) sec3(3)
  1001. elseif (isec.eq.4) then
  1002. write(*,'(/,"GRIB SECTION 4:")')
  1003. write(ou,'(5x,"Length of BDS"'//string) sec4(1)
  1004. write(ou,'(5x,"0/1: grid-point or sph. harm. data"'//string) sec4(2)
  1005. write(ou,'(5x,"0/1: simple or complex packing"'//string) sec4(3)
  1006. write(ou,'(5x,"0/1: floating or integer"'//string) sec4(4)
  1007. write(ou,'(5x,"0/1: No addl flags or addl flags"'//string) sec4(5)
  1008. write(ou,'(5x,"Unused bits"'//string) sec4(6)
  1009. write(ou,'(5x,"Binary Scale Factor"'//string) sec4(7)
  1010. write(ou,'(5x,"Reference Value", t45, ":", F18.8)') xec4(1)
  1011. write(ou,'(5x,"Number of bits for packing"'//string) sec4(8)
  1012. endif
  1013. end subroutine gribprint
  1014. !
  1015. !=============================================================================!
  1016. !=============================================================================!
  1017. !=============================================================================!
  1018. !
  1019. subroutine get_bitmap(bm8, ndat)
  1020. use module_grib
  1021. integer, dimension(ndat) :: bm8
  1022. if ((sec1(6).eq.64).or.(sec1(6).eq.192)) then
  1023. bm8 = bitmap
  1024. else
  1025. bm8 = 1
  1026. endif
  1027. end subroutine get_bitmap
  1028. !
  1029. !=============================================================================!
  1030. !=============================================================================!
  1031. !=============================================================================!
  1032. !
  1033. subroutine gribxyll(x, y, xlat, xlon)
  1034. use module_grib
  1035. implicit none
  1036. real , intent(in) :: x, y
  1037. real , intent(out) :: xlat, xlon
  1038. real :: r, xkm, ykm, y1
  1039. integer :: iscan, jscan
  1040. if (sec2(4).eq.0) then ! Cylindrical equidistant grid
  1041. xlat = gridinfo(3) + gridinfo(9)*(y-1.)
  1042. xlon = gridinfo(4) + gridinfo(8)*(x-1.)
  1043. elseif (sec2(4) == 1) then ! Mercator grid
  1044. r = grrth*cosd(gtrue1)
  1045. xkm = (x-1.)*gridinfo(8)
  1046. ykm = (y-1.)*gridinfo(9)
  1047. xlon = gridinfo(4) + (xkm/r)*(180./pi)
  1048. y1 = r*alog((1.+sind(gridinfo(3)))/cosd(gridinfo(3)))/gridinfo(9)
  1049. xlat = 90. - 2. * atan(exp(-gridinfo(9)*(y+y1-1.)/r))*180./pi
  1050. elseif (sec2(4) == 3) then ! Lambert Conformal grid
  1051. gclon = gridinfo(6)
  1052. r = sqrt((x-1.+gx1)**2 + (y-1+gy1)**2)
  1053. xlat = 90. - 2.*atand(tand(45.-gtrue1/2.)* &
  1054. ((r*gkappa*gridinfo(7))/(grrth*sind(90.-gtrue1)))**(1./gkappa))
  1055. xlon = atan2d((x-1.+gx1),-(y-1.+gy1))/gkappa + gclon
  1056. elseif (sec2(4) == 5) then ! Polar Stereographic grid
  1057. gclon = gridinfo(6)
  1058. r = sqrt((x-1.+gx1)**2 + (y-1+gy1)**2)
  1059. xlat = 90. - 2.*atan2d((r*gridinfo(7)),(grrth*(1.+sind(gtrue1))))
  1060. xlon = atan2d((x-1.+gx1),-(y-1.+gy1)) + gclon
  1061. elseif (sec2(4) == 4) then ! Gaussian grid
  1062. xlon = gridinfo(4) + gridinfo(8)*(x-1.)
  1063. xlat = gridinfo(3) + gridinfo(19)*(y-1.)
  1064. else
  1065. write(*,'("Unrecognized projection:", I10)') sec2(4)
  1066. write(*,'("STOP in GRIBXYLL")')
  1067. stop
  1068. endif
  1069. end subroutine gribxyll
  1070. !
  1071. !=============================================================================!
  1072. !=============================================================================!
  1073. !=============================================================================!
  1074. !
  1075. subroutine gribllxy(xlat, xlon, x, y)
  1076. use module_grib
  1077. implicit none
  1078. real , intent(in) :: xlat, xlon
  1079. real , intent(out) :: x, y
  1080. real :: r, y1
  1081. if (sec2(4) == 0) then ! Cylindrical Equidistant grid
  1082. x = 1. + (xlon-gridinfo(4)) / gridinfo(9)
  1083. y = 1. + (xlat-gridinfo(3)) / gridinfo(8)
  1084. else if (sec2(4) == 1) then ! Mercator grid
  1085. r = grrth*cosd(gtrue1)
  1086. x = 1.+( (r/gridinfo(8)) * (xlon-gridinfo(4)) * (pi/180.) )
  1087. y1 = (r/gridinfo(9))*alog((1.+sind(gridinfo(3)))/cosd(gridinfo(3)))
  1088. y = 1. + ((r/gridinfo(9))*alog((1.+sind(xlat))/cosd(xlat)))-y1
  1089. else if (sec2(4) == 3) then ! Lambert Conformal grid
  1090. gclon = gridinfo(6)
  1091. r = grrth/(gridinfo(7)*gkappa)*sind(90.-gtrue1) * &
  1092. (tand(45.-xlat/2.)/tand(45.-gtrue1/2.)) ** gkappa
  1093. x = r*sind(gkappa*(xlon-gclon)) - gx1 + 1.
  1094. y = -r*cosd(gkappa*(xlon-gclon)) - gy1 + 1.
  1095. elseif (sec2(4) == 5) then ! Polar Stereographic grid
  1096. gclon = gridinfo(6)
  1097. r = grrth/gridinfo(7) * tand((90.-xlat)/2.) * (1.+sind(gtrue1))
  1098. x = ( r * sind(xlon-gclon)) - gx1 + 1.
  1099. y = (-r * cosd(xlon-gclon)) - gy1 + 1.
  1100. else
  1101. write(*,'("Unrecognized projection:", I10)') sec2(4)
  1102. write(*,'("STOP in GRIBLLXY")')
  1103. stop
  1104. endif
  1105. end subroutine gribllxy
  1106. !
  1107. !=============================================================================!
  1108. !=============================================================================!
  1109. !=============================================================================!
  1110. !
  1111. subroutine glccone (fsplat,ssplat,sign,confac)
  1112. use module_grib
  1113. implicit none
  1114. real, intent(in) :: fsplat,ssplat
  1115. integer, intent(in) :: sign
  1116. real, intent(out) :: confac
  1117. if (abs(fsplat-ssplat).lt.1.E-3) then
  1118. confac = sind(fsplat)
  1119. else
  1120. confac = log10(cosd(fsplat))-log10(cosd(ssplat))
  1121. confac = confac/(log10(tand(45.-float(sign)*fsplat/2.))- &
  1122. log10(tand(45.-float(sign)*ssplat/2.)))
  1123. endif
  1124. end subroutine glccone
  1125. !
  1126. !=============================================================================!
  1127. !=============================================================================!
  1128. !=============================================================================!
  1129. !
  1130. !=============================================================================!
  1131. !=============================================================================!
  1132. !=============================================================================!
  1133. !
  1134. subroutine gribheader(debug_level,ierr)
  1135. !
  1136. ! IERR non-zero means there was a problem unpacking the grib header.
  1137. !
  1138. use module_grib
  1139. implicit none
  1140. integer :: debug_level
  1141. integer :: ierr
  1142. integer, parameter :: nsec1 = 24
  1143. integer, dimension(nsec1) :: &
  1144. iw1=(/3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,2/)
  1145. integer :: icount, iskip, ibts, nbm, nbz, i9skip, i17skip
  1146. integer :: iman, ichar, isign, iscan
  1147. integer, allocatable, dimension(:) :: bm8
  1148. real :: r
  1149. integer :: isvns
  1150. integer :: gsvns = 0
  1151. if (gsvns.eq.0) then
  1152. if (mwsize.eq.32) then
  1153. gsvns = transfer('7777', gsvns)
  1154. elseif(mwsize.eq.64) then
  1155. call gbyte_g1(char(0)//char(0)//char(0)//char(0)//'7777', gsvns, 0, mwsize)
  1156. endif
  1157. endif
  1158. ! Section 0:
  1159. sec0(2) = ied
  1160. if (ied.eq.1) then
  1161. call gbyte_g1(grec, sec0(1), 32, 24)
  1162. iskip = 64
  1163. elseif (ied.eq.0) then
  1164. sec0(1) = gribsize(grec,200, ierr)
  1165. iskip = 32
  1166. endif
  1167. ! Section 1:
  1168. i9skip = iskip + 80
  1169. i17skip = iskip + 144
  1170. do icount = 1, nsec1 - ((1-ied)*6)
  1171. ibts = iw1(icount)*8
  1172. call gbyte_g1(grec, sec1(icount), iskip, ibts)
  1173. iskip = iskip + ibts
  1174. enddo
  1175. if (ied.eq.0) sec1(22) = 20
  1176. ! Sec1 indices 9 and 10 might actually be one value, not two.
  1177. ! If this is the case, reread sec1(9), and set sec1(10) to zero:
  1178. if ( (sec1(8) == 101) .or. (sec1(8) == 104) .or. (sec1(8) == 106) .or. &
  1179. (sec1(8) == 108) .or. (sec1(8) == 110) .or. (sec1(8) == 112) .or. &
  1180. (sec1(8) == 114) .or. (sec1(8) == 116) .or. (sec1(8) == 120) .or. &
  1181. (sec1(8) == 121) .or. (sec1(8) == 128) .or. (sec1(8) == 141) .or. &
  1182. (sec1(8) == 236) ) then
  1183. ! No action here.
  1184. else
  1185. call gbyte_g1(grec, sec1(9), i9skip, 16)
  1186. sec1(10) = 0.
  1187. endif
  1188. if (sec1(24).ge.32768) sec1(24) = 32768-sec1(24)
  1189. ! If the TIME/RANGE INDICATOR (sec1(19)) indicates that the time P1
  1190. ! is spread over two bytes, then recompute sec1(17) and set sec1(18)
  1191. ! to zero.
  1192. if (sec1(19) == 10) then
  1193. call gbyte_g1(grec, sec1(17), i17skip, 16)
  1194. sec1(18) = 0
  1195. endif
  1196. ! Pull out single bits from sec1(6) for the GDS and BMS flags:
  1197. sec1(25) = sec1(6)/128
  1198. sec1(26) = mod(sec1(6)/64,2)
  1199. ! Section 2:
  1200. ! if ((sec1(6) == 128) .or. (sec1(6) == 192)) then
  1201. if (sec1(25) == 1) then
  1202. if (ied.eq.0) then
  1203. iskip = 32 + sec1(1)*8
  1204. elseif (ied.eq.1) then
  1205. iskip = 64 + sec1(1)*8
  1206. endif
  1207. call gbyte_g1(grec, sec2(1), iskip, 24)
  1208. iskip = iskip + 24
  1209. call gbytes_g1(grec, sec2(2), iskip, 8, 0, 3)
  1210. iskip = iskip + 8*3
  1211. if (sec2(4) == 0) then
  1212. ! Lat/Lon Grid:
  1213. call gbytes_g1(grec, infogrid(1), iskip, 16, 0, 2)
  1214. iskip = iskip + 32
  1215. call gbytes_g1(grec, infogrid(3), iskip, 24, 0, 2)
  1216. iskip = iskip + 48
  1217. call gbyte_g1(grec, infogrid(5), iskip, 8)
  1218. iskip = iskip + 8
  1219. call gbytes_g1(grec, infogrid(6), iskip, 24, 0, 2)
  1220. iskip = iskip + 48
  1221. call gbytes_g1(grec, infogrid(8), iskip, 16, 0, 2)
  1222. iskip = iskip + 32
  1223. call gbyte_g1(grec, infogrid(21), iskip, 1)
  1224. infogrid(21) = 1-(infogrid(21)*2)
  1225. iskip = iskip + 1
  1226. call gbyte_g1(grec, infogrid(22), iskip, 1)
  1227. infogrid(22) = (infogrid(22)*2)-1
  1228. iskip = iskip + 1
  1229. call gbyte_g1(grec, infogrid(10), iskip, 1)
  1230. iskip = iskip + 1
  1231. iskip = iskip + 5
  1232. call gbyte_g1(grec, infogrid(11), iskip, 32)
  1233. iskip = iskip + 32
  1234. !MGD if ( debug_level .gt. 100 ) then
  1235. !MGD print *, "lat/lon grib grid info", infogrid(1), infogrid(3), &
  1236. !MGD infogrid(5), infogrid(6), infogrid(8), infogrid(21), &
  1237. !MGD infogrid(22), infogrid(10), infogrid(11), infogrid(8)
  1238. !MGD end if
  1239. infogrid(8) = infogrid(8) * infogrid(21)
  1240. infogrid(9) = infogrid(9) * infogrid(22)
  1241. gridinfo(1) = float(infogrid(1))
  1242. gridinfo(2) = float(infogrid(2))
  1243. if (infogrid(3).ge.8388608) infogrid(3) = 8388608 - infogrid(3)
  1244. if (infogrid(4).ge.8388608) infogrid(4) = 8388608 - infogrid(4)
  1245. gridinfo(3) = float(infogrid(3))*0.001
  1246. gridinfo(4) = infogrid(4) * 0.001
  1247. if (infogrid(6).ge.8388608) infogrid(6) = 8388608 - infogrid(6)
  1248. if (infogrid(7).ge.8388608) infogrid(7) = 8388608 - infogrid(7)
  1249. gridinfo(6) = infogrid(6) * 0.001
  1250. gridinfo(7) = infogrid(7) * 0.001
  1251. gridinfo(8) = infogrid(8) * 0.001
  1252. gridinfo(9) = infogrid(9) * 0.001
  1253. gridinfo(21) = float(infogrid(21))
  1254. gridinfo(22) = float(infogrid(22))
  1255. elseif (sec2(4) == 1) then ! Mercator grid
  1256. ! Number of points in X and Y
  1257. call gbytes_g1(grec, infogrid(1), iskip, 16, 0, 2)
  1258. iskip = iskip + 32
  1259. ! Starting lat and lon
  1260. call gbytes_g1(grec, infogrid(3), iskip, 24, 0, 2)
  1261. iskip = iskip + 48
  1262. ! "Resolution and component flags"
  1263. call gbyte_g1(grec, infogrid(5), iskip, 8)
  1264. iskip = iskip + 8
  1265. ! Ending lat and lon
  1266. call gbytes_g1(grec, infogrid(6), iskip, 24, 0, 2)
  1267. iskip = iskip + 48
  1268. ! Truelat, 3 bytes
  1269. call gbyte_g1(grec, infogrid(11), iskip, 24)
  1270. iskip = iskip + 24
  1271. ! "Reserved", i.e., skip a byte
  1272. iskip = iskip + 8
  1273. ! Scanning mode flags, first three bits of the next byte
  1274. ! and skip the last five bits.
  1275. call gbyte_g1(grec, infogrid(21), iskip, 1)
  1276. infogrid(21) = 1-(infogrid(21)*2)
  1277. iskip = iskip + 1
  1278. call gbyte_g1(grec, infogrid(22), iskip, 1)
  1279. infogrid(22) = (infogrid(22)*2)-1
  1280. iskip = iskip + 1
  1281. call gbyte_g1(grec, infogrid(10), iskip, 1)
  1282. iskip = iskip + 1
  1283. iskip = iskip + 5
  1284. ! Grid increment in X and Y
  1285. call gbytes_g1(grec, infogrid(8), iskip, 24, 0, 2)
  1286. iskip = iskip + 48
  1287. ! Done reading map specifications.
  1288. ! Now do various conversions:
  1289. gridinfo(1) = float(infogrid(1)) ! ok
  1290. gridinfo(2) = float(infogrid(2)) ! ok
  1291. if (infogrid(3) .ge.8388608) infogrid(3) = 8388608 - infogrid(3)
  1292. if (infogrid(4) .ge.8388608) infogrid(4) = 8388608 - infogrid(4)
  1293. if (infogrid(6) .ge.8388608) infogrid(6) = 8388608 - infogrid(6)
  1294. if (infogrid(7) .ge.8388608) infogrid(7) = 8388608 - infogrid(7)
  1295. if (infogrid(11).ge.8388608) infogrid(11) = 8388608 - infogrid(11)
  1296. gridinfo(3) = infogrid(3) * 0.001
  1297. gridinfo(4) = infogrid(4) * 0.001
  1298. gridinfo(6) = infogrid(6) * 0.001
  1299. gridinfo(7) = infogrid(7) * 0.001
  1300. gridinfo(8) = infogrid(8) * 0.001
  1301. gridinfo(9) = infogrid(9) * 0.001
  1302. gridinfo(11) = infogrid(11) * 0.001
  1303. gridinfo(21) = infogrid(21)
  1304. gridinfo(22) = infogrid(22)
  1305. gridinfo(20) = 6370.949
  1306. grrth = gridinfo(20)
  1307. gtrue1 = gridinfo(11)
  1308. elseif (sec2(4) == 3) then
  1309. if (ied.eq.0) then
  1310. print '(//,"*** Despair ***"//)'
  1311. stop
  1312. endif
  1313. ! Lambert Conformal:
  1314. call gbytes_g1(grec, infogrid(1), iskip, 16, 0, 2)
  1315. iskip = iskip + 32
  1316. call gbytes_g1(grec, infogrid(3), iskip, 24, 0, 2)
  1317. iskip = iskip + 48
  1318. if (infogrid(3).ge.8388608) infogrid(3) = 8388608 - infogrid(3)
  1319. if (infogrid(4).ge.8388608) infogrid(4) = 8388608 - infogrid(4)
  1320. call gbyte_g1(grec, infogrid(5), iskip, 8)
  1321. iskip = iskip + 8
  1322. call gbytes_g1(grec, infogrid(6), iskip, 24, 0, 3)
  1323. if (infogrid(6).ge.8388608) infogrid(6) = 8388608 - infogrid(6)
  1324. iskip = iskip + 72
  1325. call gbyte_g1(grec, infogrid(9), iskip, 8)
  1326. iskip = iskip + 8
  1327. call gbyte_g1(grec, infogrid(21), iskip, 1)
  1328. infogrid(21) = 1-(infogrid(21)*2)
  1329. iskip = iskip + 1
  1330. call gbyte_g1(grec, infogrid(22), iskip, 1)
  1331. infogrid(22) = (infogrid(22)*2)-1
  1332. iskip = iskip + 1
  1333. call gbyte_g1(grec, infogrid(10), iskip, 1)
  1334. iskip = iskip + 1
  1335. iskip = iskip + 5
  1336. call gbytes_g1(grec, infogrid(11), iskip, 24, 0, 4)
  1337. if (infogrid(11).ge.8388608) infogrid(11) = 8388608 - infogrid(11)
  1338. if (infogrid(12).ge.8388608) infogrid(12) = 8388608 - infogrid(12)
  1339. if (infogrid(13).ge.8388608) infogrid(13) = 8388608 - infogrid(13)
  1340. if (infogrid(14).ge.8388608) infogrid(14) = 8388608 - infogrid(14)
  1341. iskip = iskip + 96
  1342. call gbyte_g1(grec, infogrid(15), iskip, 16)
  1343. iskip = iskip + 16
  1344. infogrid(7) = infogrid(7) * infogrid(21)
  1345. infogrid(8) = infogrid(8) * infogrid(22)
  1346. gridinfo(1) = float(infogrid(1))
  1347. gridinfo(2) = float(infogrid(2))
  1348. gridinfo(3) = infogrid(3) * 0.001
  1349. gridinfo(4) = infogrid(4) * 0.001
  1350. gridinfo(6) = infogrid(6) * 0.001
  1351. gridinfo(7) = infogrid(7) * 0.001
  1352. gridinfo(8) = infogrid(8) * 0.001
  1353. gridinfo(9) = infogrid(9) * 0.001
  1354. gridinfo(11) = infogrid(11) * 0.001
  1355. gridinfo(12) = infogrid(12) * 0.001
  1356. gridinfo(13) = infogrid(13) * 0.001
  1357. gridinfo(14) = infogrid(14) * 0.001
  1358. gridinfo(20) = 6370
  1359. ! a priori knowledge:
  1360. if (sec1(5).eq.212) then
  1361. gridinfo(3) = 12.190
  1362. gridinfo(4) = -133.459
  1363. gridinfo(7) = 40.63525
  1364. gridinfo(8) = 40.63525
  1365. gridinfo(20) = 6370
  1366. endif
  1367. !=============================================================================!
  1368. ! More a priori knowledge: !
  1369. ! Correct some bad lat/lon numbers coded into some RUC headers. !
  1370. ! !
  1371. if (sec1(3) == 59) then ! If FSL
  1372. if (sec1(4) == 86) then ! and RUC
  1373. if (sec1(5) == 255) then
  1374. ! Check to correct bad lat/lon numbers.
  1375. if (infogrid(3) == 16909) then
  1376. infogrid(3) = 16281
  1377. gridinfo(3) = 16.281
  1378. endif
  1379. if (infogrid(4) == 236809) then
  1380. infogrid(4) = 2338622
  1381. gridinfo(4) = 233.8622
  1382. endif
  1383. endif
  1384. endif
  1385. endif
  1386. !=============================================================================!
  1387. gridinfo(21) = float(infogrid(21))
  1388. gridinfo(22) = float(infogrid(22))
  1389. ! Map parameters
  1390. glat1 = gridinfo(3)
  1391. glon1 = gridinfo(4)
  1392. gclon = gridinfo(6)
  1393. if (gclon.gt.180.) gclon = -(360.-gclon)
  1394. if ((gclon<0).and.(glon1>180)) glon1 = glon1-360.
  1395. gtrue1 = gridinfo(11)
  1396. gtrue2 = gridinfo(12)
  1397. grrth = gridinfo(20)
  1398. call glccone(gtrue1, gtrue2, 1, gkappa)
  1399. r = grrth/(gridinfo(7)*gkappa)*sind(90.-gtrue1) * &
  1400. (tand(45.-glat1/2.)/tand(45.-gtrue1/2.)) ** gkappa
  1401. gx1 = r*sind(gkappa*(glon1-gclon))
  1402. gy1 = -r*cosd(gkappa*(glon1-gclon))
  1403. elseif (sec2(4) == 4) then
  1404. ! Gaussian Grid:
  1405. call gbytes_g1(grec, infogrid(1), iskip, 16, 0, 2)
  1406. iskip = iskip + 32
  1407. call gbytes_g1(grec, infogrid(3), iskip, 24, 0, 2)
  1408. iskip = iskip + 48
  1409. call gbyte_g1(grec, infogrid(5), iskip, 8)
  1410. iskip = iskip + 8
  1411. call gbytes_g1(grec, infogrid(6), iskip, 24, 0, 2)
  1412. iskip = iskip + 48
  1413. call gbytes_g1(grec, infogrid(8), iskip, 16, 0, 2)
  1414. iskip = iskip + 32
  1415. call gbyte_g1(grec, infogrid(21), iskip, 1)
  1416. infogrid(21) = 1-(infogrid(21)*2)
  1417. iskip = iskip + 1
  1418. call gbyte_g1(grec, infogrid(22), iskip, 1)
  1419. infogrid(22) = (infogrid(22)*2)-1
  1420. iskip = iskip + 1
  1421. call gbyte_g1(grec, infogrid(10), iskip, 1)
  1422. iskip = iskip + 1
  1423. iskip = iskip + 5
  1424. call gbyte_g1(grec, infogrid(11), iskip, 32)
  1425. iskip = iskip + 32
  1426. infogrid(8) = infogrid(8) * infogrid(21)
  1427. gridinfo(1) = float(infogrid(1))
  1428. gridinfo(2) = float(infogrid(2))
  1429. if (infogrid(3).ge.8388608) infogrid(3) = 8388608 - infogrid(3)
  1430. if (infogrid(4).ge.8388608) infogrid(4) = 8388608 - infogrid(4)
  1431. gridinfo(3) = float(infogrid(3))*0.001
  1432. gridinfo(4) = infogrid(4) * 0.001
  1433. if (infogrid(6).ge.8388608) infogrid(6) = 8388608 - infogrid(6)
  1434. if (infogrid(7).ge.8388608) infogrid(7) = 8388608 - infogrid(7)
  1435. gridinfo(6) = infogrid(6) * 0.001
  1436. gridinfo(7) = infogrid(7) * 0.001
  1437. gridinfo(8) = infogrid(8) * 0.001
  1438. gridinfo(21) = float(infogrid(21))
  1439. gridinfo(22) = float(infogrid(22))
  1440. ! Compute an approximate delta-latitude and starting latitude.
  1441. ! Replace the stored value of starting latitude with approximate one.
  1442. gridinfo(18) = gridinfo(3)
  1443. infogrid(18) = infogrid(3)
  1444. gridinfo(17) = gridinfo(6)
  1445. infogrid(17) = infogrid(6)
  1446. ! call griblgg(infogrid(2), gridinfo(3), gridinfo(19))
  1447. ! infogrid(19) = nint(gridinfo(19)*1000.)
  1448. ! infogrid(3) = nint(gridinfo(3)*1000.)
  1449. gridinfo(6) = -gridinfo(3)
  1450. infogrid(6) = -infogrid(3)
  1451. elseif (sec2(4) == 5) then
  1452. ! Polar Stereographic Grid
  1453. if (ied.eq.0) then
  1454. print '(//,"*** Despair ***"//)'
  1455. stop
  1456. endif
  1457. call gbytes_g1(grec, infogrid(1), iskip, 16, 0, 2) ! NX and NY
  1458. iskip = iskip + 32
  1459. call gbytes_g1(grec, infogrid(3), iskip, 24, 0, 2) ! LAT1 and LON1
  1460. iskip = iskip + 48
  1461. call gbyte_g1(grec, infogrid(5), iskip, 8) ! Resolution and Component
  1462. iskip = iskip + 8
  1463. call gbytes_g1(grec, infogrid(6), iskip, 24, 0, 3) ! LOV, DX, and DY
  1464. iskip = iskip + 72
  1465. call gbyte_g1(grec, infogrid(9), iskip, 8) ! Projection center flag
  1466. iskip = iskip + 8
  1467. call gbyte_g1(grec, infogrid(21), iskip, 1)
  1468. infogrid(21) = 1-(infogrid(21)*2)
  1469. iskip = iskip + 1
  1470. call gbyte_g1(grec, infogrid(22), iskip, 1)
  1471. infogrid(22) = (infogrid(22)*2)-1
  1472. iskip = iskip + 1
  1473. call gbyte_g1(grec, infogrid(10), iskip, 1)
  1474. iskip = iskip + 1
  1475. iskip = iskip + 5
  1476. ! call gbyte_g1(grec, infogrid(11), iskip, 32) ! Set to 0 (reserved)
  1477. iskip = iskip + 32
  1478. if (infogrid(3).ge.8388608) infogrid(3) = 8388608 - infogrid(3)
  1479. if (infogrid(4).ge.8388608) infogrid(4) = 8388608 - infogrid(4)
  1480. if (infogrid(6).ge.8388608) infogrid(6) = 8388608 - infogrid(6)
  1481. infogrid(7) = infogrid(7) * infogrid(21)
  1482. infogrid(8) = infogrid(8) * infogrid(22)
  1483. gridinfo(1) = float(infogrid(1))
  1484. gridinfo(2) = float(infogrid(2))
  1485. gridinfo(3) = infogrid(3) * 0.001
  1486. gridinfo(4) = infogrid(4) * 0.001
  1487. gridinfo(6) = infogrid(6) * 0.001
  1488. gridinfo(7) = infogrid(7) * 0.001
  1489. gridinfo(8) = infogrid(8) * 0.001
  1490. gridinfo(20) = 6370
  1491. ! a priori knowledge:
  1492. if (sec1(5).eq.240) then
  1493. gridinfo(3) = 22.7736
  1494. gridinfo(4) = -120.376
  1495. gridinfo(7) = 4.7625
  1496. gridinfo(8) = 4.7625
  1497. gridinfo(20) = 6370
  1498. endif
  1499. ! Map parameters
  1500. glat1 = gridinfo(3)
  1501. glon1 = gridinfo(4)
  1502. gclon = gridinfo(6)
  1503. if (gclon.gt.180.) gclon = -(360.-gclon)
  1504. ! GRIB edition 1 Polar Stereographic grids are true at 60 degrees
  1505. ! Which hemisphere depends on infogrid(9), the "Projection Center Flag"
  1506. grrth = gridinfo(20)
  1507. if (infogrid(9) > 127) then
  1508. gtrue1 = -60.
  1509. r = grrth/gridinfo(7) * tand((-90.-glat1)/2.) * (1.+sind(-gtrue1))
  1510. gx1 = -r * sind(glon1-gridinfo(6))
  1511. gy1 = -r * cosd(glon1-gridinfo(6))
  1512. else
  1513. gtrue1 = 60.
  1514. r = grrth/gridinfo(7) * tand((90.-glat1)/2.) * (1.+sind(gtrue1))
  1515. gx1 = r * sind(glon1-gridinfo(6))
  1516. gy1 = -r * cosd(glon1-gridinfo(6))
  1517. endif
  1518. gridinfo(21) = float(infogrid(21))
  1519. gridinfo(22) = float(infogrid(22))
  1520. elseif (sec2(4) == 50) then
  1521. ! Spherical harmonic coefficients
  1522. if (ied.eq.0) then
  1523. print '(//,"*** Despair ***"//)'
  1524. stop
  1525. endif
  1526. call gbytes_g1(grec, infogrid(1), iskip, 16, 0, 3)
  1527. iskip = iskip + 48
  1528. call gbytes_g1(grec, infogrid(4), iskip, 8, 0, 2)
  1529. iskip = iskip + 16
  1530. iskip = iskip + 18*8
  1531. else
  1532. call gribprint(0)
  1533. call gribprint(1)
  1534. call gribprint(2)
  1535. call gribprint(3)
  1536. call gribprint(4)
  1537. write(*,'("Unrecognized grid: ", i8)') sec2(4)
  1538. write(*,'("This grid is not currently supported.")')
  1539. write(*,'("Write your own program to put the data to the intermediate format")')
  1540. stop
  1541. endif
  1542. endif
  1543. ! Section 3
  1544. if ((sec1(6).eq.64).or.(sec1(6).eq.192)) then
  1545. if (ied.eq.0) then
  1546. print '(//,"*** Despair ***"//)'
  1547. stop
  1548. endif
  1549. if (ied.eq.0) then
  1550. iskip = 32 + sec1(1)*8 + sec2(1)*8
  1551. elseif (ied.eq.1) then
  1552. iskip = 64 + sec1(1)*8 + sec2(1)*8
  1553. endif
  1554. call gbyte_g1(grec, sec3(1), iskip, 24)
  1555. iskip = iskip + 24
  1556. call gbyte_g1(grec, sec3(2), iskip, 8)
  1557. iskip = iskip + 8
  1558. call gbyte_g1(grec, sec3(3), iskip, 16)
  1559. iskip = iskip + 16
  1560. #if defined (CRAY)
  1561. #else
  1562. allocate(bitmap((sec3(1)-6)*8))
  1563. #endif
  1564. allocate(bm8((sec3(1)-6)*8))
  1565. call gbytes_g1(grec, bm8, iskip, 1, 0, (sec3(1)-6)*8)
  1566. bitmap(1:size(bm8)) = bm8(1:size(bm8))
  1567. deallocate(bm8)
  1568. iskip = iskip + sec3(1)-6
  1569. else
  1570. sec3 = 0
  1571. endif
  1572. ! Section 4
  1573. if ((sec1(6).eq.128).or.(sec1(6).eq.192)) then
  1574. if (ied.eq.0) then
  1575. iskip = 32 + sec1(1)*8 + sec2(1)*8 + sec3(1)*8
  1576. elseif (ied.eq.1) then
  1577. iskip = 64 + sec1(1)*8 + sec2(1)*8 + sec3(1)*8
  1578. endif
  1579. call gbyte_g1(grec, sec4(1), iskip, 24)
  1580. if (sec4(1) > (sec0(1) - sec1(1) - sec2(1) - sec3(1) - 4)) then
  1581. write(*,'(/,"*** I have good reason to believe that this GRIB record is")')
  1582. write(*,'("*** corrupted or miscoded.",/)')
  1583. ierr = 1
  1584. return
  1585. endif
  1586. iskip = iskip + 24
  1587. call gbytes_g1(grec, sec4(2), iskip, 1,0,4)
  1588. iskip = iskip + 4
  1589. call gbyte_g1(grec, sec4(6), iskip, 4)
  1590. iskip = iskip + 4
  1591. ! Get the binary scale factor
  1592. call gbyte_g1(grec, isign, iskip, 1)
  1593. iskip = iskip + 1
  1594. call gbyte_g1(grec, sec4(7), iskip, 15)
  1595. iskip = iskip + 15
  1596. sec4(7) = sec4(7) * (-2*isign+1)
  1597. ! Get the reference value:
  1598. call gbyte_g1(grec, isign, iskip, 1)
  1599. iskip = iskip + 1
  1600. isign = -2*isign+1
  1601. call gbyte_g1(grec, ichar, iskip, 7)
  1602. iskip = iskip + 7
  1603. call gbyte_g1(grec, iman, iskip, 24)
  1604. iskip = iskip + 24
  1605. if ( iman .ne. 0 ) then
  1606. xec4(1) = float(isign) * (2.**(-24)) * float(iman) * &
  1607. (16.**(ichar-64))
  1608. else
  1609. xec4(1) = 0.
  1610. endif
  1611. call gbyte_g1(grec,sec4(8), iskip, 8)
  1612. ! sec4(8) is the number of bits used per datum value.
  1613. ! If sec4(8) = 255, assume they mean sec4(8) = 0
  1614. if (sec4(8) == 255) sec4(8) = 0
  1615. iskip = iskip + 8
  1616. endif
  1617. ! Section 5
  1618. call gbyte_g1(grec, isvns, ((sec0(1)-4)*8), 32)
  1619. if (isvns.ne.gsvns) then
  1620. write(*, '("End-of-record mark (7777) not found", 2I10)') isvns
  1621. write(*, '("Sec0(1) = ", I8, i2)') sec0(1), sevencount
  1622. sevencount = sevencount + 1
  1623. if (sevencount > 10) then
  1624. write(*,'(//," *** Found more than 10 consecutive bad GRIB records")')
  1625. write(*,'(" *** Let''s just stop now.",//)')
  1626. write(*,'(" Perhaps the analysis file should have been converted",/,&
  1627. &" from COS-Blocked format?",//)')
  1628. stop
  1629. endif
  1630. else
  1631. sevencount = 0
  1632. endif
  1633. ierr = 0
  1634. end subroutine gribheader
  1635. !
  1636. !=============================================================================!
  1637. !=============================================================================!
  1638. !=============================================================================!
  1639. !
  1640. subroutine gribdata(datarray, ndat)
  1641. !-----------------------------------------------------------------------------!
  1642. ! !
  1643. ! Read and unpack the data from a GRIB record. !
  1644. ! !
  1645. ! Input: !
  1646. ! NDAT: The size of the data array we expect to unpack. !
  1647. ! !
  1648. ! Output: !
  1649. ! DATARRAY: The unpacked data from the GRIB record !
  1650. ! !
  1651. ! Side Effects: !
  1652. ! STOP if it cannot unpack the data. !
  1653. ! !
  1654. ! Externals: !
  1655. ! SGUP_BITMAP !
  1656. ! SGUP_NOBITMAP !
  1657. ! CSHUP !
  1658. ! !
  1659. ! Modules: !
  1660. ! MODULE_GRIB !
  1661. ! !
  1662. !-----------------------------------------------------------------------------!
  1663. use module_grib
  1664. implicit none
  1665. integer :: ndat
  1666. real , dimension(ndat) :: datarray
  1667. integer, dimension(ndat) :: IX
  1668. integer :: iskip, nbm
  1669. if (sec4(2) == 0) then ! Grid-point data
  1670. if (sec4(3).eq.0) then ! Simple unpacking
  1671. if ((sec1(6).eq.64).or.(sec1(6).eq.192)) then ! There is a bitmap
  1672. call SGUP_BITMAP(datarray, ndat)
  1673. else
  1674. call SGUP_NOBITMAP(datarray, ndat)
  1675. endif
  1676. else
  1677. write(*,'(//,"***** No complex unpacking of gridpoint data.")')
  1678. write(*,'("***** Option not yet available.",//)')
  1679. ! write(*,'("***** Complain to mesouser@ucar.edu",//)')
  1680. stop
  1681. endif
  1682. else
  1683. if (sec4(3).eq.0) then ! Simple unpacking
  1684. write(*,'(//,"***** No simple unpacking of spherical-harmonic coefficients.")')
  1685. write(*,'("***** Option not yet available.",//)')
  1686. ! write(*,'("***** Complain to mesouser@ucar.edu",//)')
  1687. stop
  1688. elseif (sec4(3).eq.1) then
  1689. call CSHUP(datarray, ndat)
  1690. endif
  1691. endif
  1692. end subroutine gribdata
  1693. subroutine deallogrib
  1694. ! Deallocates a couple of arrays that may be allocated.
  1695. use module_grib
  1696. #if defined (CRAY)
  1697. #else
  1698. if (allocated(grec)) deallocate(grec)
  1699. if (allocated(bitmap)) deallocate(bitmap)
  1700. #endif
  1701. end subroutine deallogrib
  1702. SUBROUTINE gribLGG( NLAT, startlat, deltalat )
  1703. implicit none
  1704. !
  1705. ! LGGAUS finds the Gaussian latitudes by finding the roots of the
  1706. ! ordinary Legendre polynomial of degree NLAT using Newtons
  1707. ! iteration method.
  1708. !
  1709. ! On entry:
  1710. integer NLAT ! the number of latitudes (degree of the polynomial)
  1711. !
  1712. ! On exit: for each Gaussian latitude
  1713. double precision, dimension(NLAT) :: LATG ! Latitude
  1714. ! Approximations to a regular latitude grid:
  1715. real :: deltalat
  1716. real :: startlat
  1717. !-----------------------------------------------------------------------
  1718. integer :: iskip = 15
  1719. double precision :: sum1 = 0.
  1720. double precision :: sum2 = 0.
  1721. double precision :: sum3 = 0.
  1722. double precision :: sum4 = 0.
  1723. double precision :: xn
  1724. integer, save :: SAVE_NLAT = -99
  1725. real, save :: save_deltalat = -99.
  1726. real, save :: save_startlat = -99.
  1727. double precision, dimension(nlat) :: COSC, SINC
  1728. double precision, parameter :: PI = 3.141592653589793
  1729. !
  1730. ! -convergence criterion for iteration of cos latitude
  1731. double precision, parameter :: XLIM = 1.0E-14
  1732. integer :: nzero, i, j
  1733. double precision :: fi, fi1, a, b, g, gm, gp, gt, delta, c, d
  1734. if (nlat == save_nlat) then
  1735. deltalat = save_deltalat
  1736. startlat = save_startlat
  1737. return
  1738. endif
  1739. !
  1740. ! -the number of zeros between pole and equator
  1741. NZERO = NLAT/2
  1742. !
  1743. ! -set first guess for cos(colat)
  1744. DO I=1,NZERO
  1745. COSC(I) = SIN( (I-0.5)*PI/NLAT + PI*0.5 )
  1746. ENDDO
  1747. !
  1748. ! -constants for determining the derivative of the polynomial
  1749. FI = NLAT
  1750. FI1 = FI+1.0
  1751. A = FI*FI1 / SQRT(4.0*FI1*FI1-1.0)
  1752. B = FI1*FI / SQRT(4.0*FI*FI-1.0)
  1753. !
  1754. ! -loop over latitudes, iterating the search for each root
  1755. DO I=1,NZERO
  1756. J=0
  1757. !
  1758. ! -determine the value of the ordinary Legendre polynomial for
  1759. ! -the current guess root
  1760. LOOP30 : DO
  1761. CALL LGORD( G, COSC(I), NLAT )
  1762. !
  1763. ! -determine the derivative of the polynomial at this point
  1764. CALL LGORD( GM, COSC(I), NLAT-1 )
  1765. CALL LGORD( GP, COSC(I), NLAT+1 )
  1766. GT = (COSC(I)*COSC(I)-1.0) / (A*GP-B*GM)
  1767. !
  1768. ! -update the estimate of the root
  1769. DELTA = G*GT
  1770. COSC(I) = COSC(I) - DELTA
  1771. !
  1772. ! -if convergence criterion has not been met, keep trying
  1773. J = J+1
  1774. IF( ABS(DELTA).LE.XLIM ) EXIT LOOP30
  1775. ENDDO LOOP30
  1776. ENDDO
  1777. !
  1778. ! Determine the sin(colat)
  1779. SINC(1:NZERO) = SIN(ACOS(COSC(1:NZERO)))
  1780. !
  1781. ! -if NLAT is odd, set values at the equator
  1782. IF( MOD(NLAT,2) .NE. 0 ) THEN
  1783. I = NZERO+1
  1784. SINC(I) = 1.0
  1785. latg(i) = 0.
  1786. END IF
  1787. ! Set the latitudes.
  1788. latg(1:NZERO) = dacos(sinc(1:NZERO)) * 180. / pi
  1789. ! Determine the southern hemisphere values by symmetry
  1790. do i = 1, nzero
  1791. latg(nlat-nzero+i) = -latg(nzero+1-i)
  1792. enddo
  1793. ! Now that we have the true values, find some approximate values.
  1794. xn = float(nlat-iskip*2)
  1795. do i = iskip+1, nlat-iskip
  1796. sum1 = sum1 + latg(i)*float(i)
  1797. sum2 = sum2 + float(i)
  1798. sum3 = sum3 + latg(i)
  1799. sum4 = sum4 + float(i)**2
  1800. enddo
  1801. b = (xn*sum1 - sum2*sum3) / (xn*sum4 - sum2**2)
  1802. a = (sum3 - b * sum2) / xn
  1803. deltalat = sngl(b)
  1804. startlat = sngl(a + b)
  1805. save_nlat = nlat
  1806. save_deltalat = deltalat
  1807. save_startlat = startlat
  1808. contains
  1809. SUBROUTINE LGORD( F, COSC, N )
  1810. implicit none
  1811. !
  1812. ! LGORD calculates the value of an ordinary Legendre polynomial at a
  1813. ! latitude.
  1814. !
  1815. ! On entry:
  1816. ! COSC - cos(colatitude)
  1817. ! N - the degree of the polynomial
  1818. !
  1819. ! On exit:
  1820. ! F - the value of the Legendre polynomial of degree N at
  1821. ! latitude asin(COSC)
  1822. double precision :: s1, c4, a, b, fk, f, cosc, colat, c1, fn, ang
  1823. integer :: n, k
  1824. !------------------------------------------------------------------------
  1825. colat = acos(cosc)
  1826. c1 = sqrt(2.0)
  1827. do k=1,n
  1828. c1 = c1 * sqrt( 1.0 - 1.0/(4*k*k) )
  1829. enddo
  1830. fn = n
  1831. ang= fn * colat
  1832. s1 = 0.0
  1833. c4 = 1.0
  1834. a =-1.0
  1835. b = 0.0
  1836. do k=0,n,2
  1837. if (k.eq.n) c4 = 0.5 * c4
  1838. s1 = s1 + c4 * cos(ang)
  1839. a = a + 2.0
  1840. b = b + 1.0
  1841. fk = k
  1842. ang= colat * (fn-fk-2.0)
  1843. c4 = ( a * (fn-b+1.0) / ( b * (fn+fn-a) ) ) * c4
  1844. enddo
  1845. f = s1 * c1
  1846. end subroutine lgord
  1847. END SUBROUTINE GRIBLGG
  1848. SUBROUTINE REORDER_IT (a, nx, ny, dx, dy, iorder)
  1849. use module_debug
  1850. implicit none
  1851. integer :: nx, ny, iorder
  1852. integer :: i, j, k, m
  1853. real :: dx, dy
  1854. real, dimension(nx*ny) :: a, z
  1855. if (iorder .eq. 0 .and. dx .gt. 0. .and. dy .lt. 0) return
  1856. k = 0
  1857. call mprintf(.true.,DEBUG, &
  1858. "Reordering GRIB array : dx = %f , dy = %f , iorder = %i", &
  1859. f1=dx,f2=dy,i1=iorder)
  1860. if (iorder .eq. 0 ) then
  1861. if ( dx .lt. 0 .and. dy .lt. 0. ) then
  1862. do j = 1, ny
  1863. do i = nx, 1, -1
  1864. k = k + 1
  1865. m = i * j
  1866. z(k) = a(m)
  1867. enddo
  1868. enddo
  1869. else if ( dx .lt. 0 .and. dy .gt. 0. ) then
  1870. do j = ny, 1, -1
  1871. do i = nx, 1, -1
  1872. k = k + 1
  1873. m = i * j
  1874. z(k) = a(m)
  1875. enddo
  1876. enddo
  1877. else if ( dx .gt. 0 .and. dy .gt. 0. ) then
  1878. do j = ny, 1, -1
  1879. do i = 1, nx
  1880. k = k + 1
  1881. m = i * j
  1882. z(k) = a(m)
  1883. enddo
  1884. enddo
  1885. endif
  1886. else
  1887. if ( dx .gt. 0 .and. dy .lt. 0. ) then
  1888. do i = 1, nx
  1889. do j = 1, ny
  1890. k = k + 1
  1891. m = i * j
  1892. z(k) = a(m)
  1893. enddo
  1894. enddo
  1895. else if ( dx .lt. 0 .and. dy .lt. 0. ) then
  1896. do i = nx, 1, -1
  1897. do j = 1, ny
  1898. k = k + 1
  1899. m = i * j
  1900. z(k) = a(m)
  1901. enddo
  1902. enddo
  1903. else if ( dx .lt. 0 .and. dy .lt. 0. ) then
  1904. do i = nx, 1, -1
  1905. do j = ny, 1, -1
  1906. k = k + 1
  1907. m = i * j
  1908. z(k) = a(m)
  1909. enddo
  1910. enddo
  1911. else if ( dx .gt. 0 .and. dy .gt. 0. ) then
  1912. do i = 1, nx
  1913. do j = ny, 1, -1
  1914. k = k + 1
  1915. m = i * j
  1916. z(k) = a(m)
  1917. enddo
  1918. enddo
  1919. endif
  1920. endif
  1921. ! now put it back in the 1-d array and reset the dx and dy
  1922. do k = 1, nx*ny
  1923. a(k) = z(k)
  1924. enddo
  1925. dx = abs ( dx)
  1926. dy = -1 * abs(dy)
  1927. return
  1928. END SUBROUTINE REORDER_IT