PageRenderTime 56ms CodeModel.GetById 14ms 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

Large files files are truncated, but you can click here to view the full file

  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) inf…

Large files files are truncated, but you can click here to view the full file