19 integer :: msk2, icount, ifl1, itot, j, lengrib, lgrib
20 integer*8 :: iseek8, msk18, lskip8, lgrib8, lengrib8
21 integer :: maxlocal, n, ncgb, numfields, numlocal
22 real :: fldmax, fldmin, sum
23 parameter(msk18 = 32000, msk2 = 4000)
24 character(len = 1),
allocatable,
dimension(:) :: cgrib
25 integer :: listsec0(3)
26 integer :: listsec1(13)
27 character(len = 250) :: gfile1
28 character(len = 8) :: pabbrev
29 character(len = 40) :: labbrev
30 character(len = 110) :: tabbrev
31 integer(4) narg, iargc, temparg
32 integer :: currlen = 0, numpts = 0
33 logical :: unpack, expand
35 integer :: ierr, ios, is
44 call errmsg(
'degrib2: incorrect usage')
45 call errmsg(
'usage: degrib2 grib2file')
52 call getarg(temparg, gfile1)
53 ncgb = len_trim(gfile1)
54 call baopenr(ifl1, gfile1(1:ncgb), ios)
61 call skgb8(ifl1, iseek8, msk18, lskip8, lgrib8)
63 if (lgrib8 .eq. 0)
exit
66 if (lgrib8 .gt. currlen)
then
67 if (
allocated(cgrib))
deallocate(cgrib)
68 allocate(cgrib(lgrib8), stat = is)
71 call bareadl(ifl1, lskip8, lgrib8, lengrib8, cgrib)
73 if (lgrib8 .ne. lengrib)
then
74 write(6, *)
' degrib2: IO Error.'
77 iseek8 = lskip8 + lgrib8
80 write(6,
'(A,I0,A,I0)')
' GRIB MESSAGE ', icount,
' starts at ', lskip8 + 1
84 call gb_info(cgrib, lengrib, listsec0, listsec1, &
85 numfields, numlocal, maxlocal, ierr)
87 write(6,
'(A,I0)')
' ERROR extracting field = ', ierr
90 itot = itot + numfields
91 write(6,
'(A,3(1x,I0))')
' SECTION 0: ', (listsec0(j), j = 1, 3)
92 write(6,
'(A,13(1x,I0))')
' SECTION 1: ', (listsec1(j), j = 1, 13)
93 write(6,
'(A,1x,I0,1x,A,I0,1x,A)')
' Contains ', numlocal, &
94 ' Local Sections and ', numfields,
' data fields.'
99 call gf_getfld(cgrib, lengrib, n, unpack, expand, gfld, ierr)
100 if (ierr .ne. 0)
then
101 write(6,
'(A,I0)')
' ERROR extracting field = ', ierr
106 write(6,
'(A,1x,I0)')
' FIELD ', n
108 write(6,
'(A,2(1x,I0))')
' SECTION 0: ', gfld%discipline, gfld%version
109 write(6,
'(A,20(1x,I0))')
' SECTION 1: ', (gfld%idsect(j), j = 1, gfld%idsectlen)
111 if (
associated(gfld%local).AND.gfld%locallen.gt.0 )
then
112 write(6,
'(A,I0,A)')
' SECTION 2: ', gfld%locallen,
' bytes'
114 write(6,
'(A,5(1x,I0))')
' SECTION 3: ', gfld%griddef, gfld%ngrdpts, gfld%numoct_opt, &
115 gfld%interp_opt, gfld%igdtnum
116 write(6,
'(A,1x,I0,A,100(1x,I0))')
' GRID TEMPLATE 3.', &
117 gfld%igdtnum,
' : ', (gfld%igdtmpl(j), j = 1, gfld%igdtlen)
118 if (gfld%num_opt .eq. 0)
then
119 write(6, *)
' NO Optional List Defining Number of Data Points.'
121 write(6,
'(A,1x,150(1x,I0))')
' Section 3 Optional List:', &
122 (gfld%list_opt(j), j = 1, gfld%num_opt)
125 pabbrev =
param_get_abbrev(gfld%discipline, gfld%ipdtmpl(1), gfld%ipdtmpl(2))
126 call prlevel(gfld%ipdtnum, gfld%ipdtmpl, labbrev)
127 call prvtime(gfld%ipdtnum, gfld%ipdtmpl, listsec1, tabbrev)
129 write(6,
'(A,1x,I0,A,A,3(1X,I0),A,80(1x,I0))')
' PRODUCT TEMPLATE 4.', gfld%ipdtnum, &
130 ': ( PARAMETER = ', pabbrev, gfld%discipline, gfld%ipdtmpl(1), gfld%ipdtmpl(2),
' ) ', &
131 (gfld%ipdtmpl(j), j = 1, gfld%ipdtlen)
133 write(6,
'(A,A,A,A,A)')
' FIELD: ', pabbrev, trim(labbrev),
" ", trim(tabbrev)
134 if (gfld%num_coord .eq. 0)
then
135 write(6, *)
' NO Optional Vertical Coordinate List.'
137 write(6,
'(A,1X,150(1x,I0))')
' Section 4 Optional & Coordinates: ', &
138 (gfld%coord_list(j), j = 1, gfld%num_coord)
140 if (gfld%ibmap .ne. 255)
then
141 write(6,
'(A,I0,A,I0)')
' Num. of Data Points = ', &
142 gfld%ndpts,
' with BIT-MAP ', gfld%ibmap
144 write(6,
'(A,I0,A)')
' Num. of Data Points = ', gfld%ndpts,
' NO BIT-MAP '
146 write(6,
'(A,I0,A,20(1x,I0))')
' DRS TEMPLATE 5. ', gfld%idrtnum,
' : ', &
147 (gfld%idrtmpl(j), j = 1, gfld%idrtlen)
148 if (gfld%ndpts .eq. 0)
then
154 if (gfld%fld(1) .eq. 9.9990003e+20)
then
166 if (gfld%fld(j) .eq. 9.9990003e+20)
then
169 if (gfld%fld(j) .gt. fldmax) fldmax = gfld%fld(j)
170 if (gfld%fld(j) .lt. fldmin) fldmin = gfld%fld(j)
171 sum = sum + gfld%fld(j)
176 write(6, *)
' Data Values:'
177 write(6,
'(A,I0,A,I0)')
' Num. of Data Points = ', &
178 gfld%ndpts,
' Num. of Data Undefined = ', gfld%ndpts-numpts
180 write(6, fmt =
'( "( PARM= ",A," ) : ", " MIN=",f25.8," AVE=",f25.8, " MAX=",f25.8)') &
181 trim(pabbrev), fldmin, sum / numpts, fldmax
188 write(6,
'(A,I0)')
' Total Number of Fields Found = ', itot
189 if (
allocated(cgrib))
deallocate(cgrib)
program degrib2
This program reads a GRIB2 file and makes an inventory.
subroutine gb_info(cgrib, lcgrib, listsec0, listsec1, numfields, numlocal, maxlocal, ierr)
Find the number of gridded fields and Local Use Sections in a GRIB2 message.
subroutine gf_free(gfld)
Free memory that was used to store array values in derived type grib_mod::gribfield.
subroutine gf_getfld(cgrib, lcgrib, ifldnum, unpack, expand, gfld, ierr)
Return the Grid Definition, and Product Definition for a given data field.
This Fortran module contains the declaration of derived type gribfield.
This Fortran Module contains info on all the available GRIB Parameters, and their GRIB1 and GRIB2 cod...
character(len=8) function param_get_abbrev(g2disc, g2cat, g2num)
This function returns the parameter abbreviation for a given GRIB2 Discipline, Category and Parameter...
subroutine prlevel(ipdtn, ipdtmpl, labbrev)
Print level information to a character array, given the GRIB2 Product Definition Template information...
subroutine prvtime(ipdtn, ipdtmpl, listsec1, tabbrev)
Convert date and time from GRIB2 info to string output.
subroutine skgb8(lugb, iseek8, mseek8, lskip8, lgrib8)
Search a file for the next GRIB1 or GRIB2 message.