1 subroutine gribinfo(cgrib,lcgrib,listsec0,listsec1,
2 & numlocal,numfields,maxvals,ierr)
3 !$$$ SUBPROGRAM DOCUMENTATION BLOCK
6 ! PRGMMR: Gilbert ORG: W/NP11 DATE: 2000-05-25
8 ! ABSTRACT: This subroutine searches through a GRIB2 message and
9 ! returns the number of Local Use Sections and number of gridded
10 ! fields found in the message. It also performs various checks
11 ! to see if the message is a valid GRIB2 message.
12 ! Last, a list of safe array dimensions is returned for use in
13 ! allocating return arrays from routines getlocal, gettemplates, and
14 ! getfields. (See maxvals and REMARKS)
16 ! PROGRAM HISTORY LOG:
19 ! USAGE: CALL gribinfo(cgrib,lcgrib,listsec0,listsec1,
20 ! & numlocal,numfields,ierr)
21 ! INPUT ARGUMENT LIST:
22 ! cgrib - Character array that contains the GRIB2 message
23 ! lcgrib - Length (in bytes) of GRIB message in array cgrib.
25 ! OUTPUT ARGUMENT LIST:
26 ! listsec0 - Contains information decoded from GRIB Indicator Section 0.
27 ! Must be dimensioned >= 2.
28 ! listsec0(1)=Discipline-GRIB Master Table Number
29 ! (see Code Table 0.0)
30 ! listsec0(2)=GRIB Edition Number (currently 2)
31 ! listsec0(3)=Length of GRIB message
32 ! listsec1 - Contains information read from GRIB Identification Section 1.
33 ! Must be dimensioned >= 13.
34 ! listsec1(1)=Id of orginating centre (Common Code Table C-1)
35 ! listsec1(2)=Id of orginating sub-centre (local table)
36 ! listsec1(3)=GRIB Master Tables Version Number (Code Table 1.0)
37 ! listsec1(4)=GRIB Local Tables Version Number
38 ! listsec1(5)=Significance of Reference Time (Code Table 1.1)
39 ! listsec1(6)=Reference Time - Year (4 digits)
40 ! listsec1(7)=Reference Time - Month
41 ! listsec1(8)=Reference Time - Day
42 ! listsec1(9)=Reference Time - Hour
43 ! listsec1(10)=Reference Time - Minute
44 ! listsec1(11)=Reference Time - Second
45 ! listsec1(12)=Production status of data (Code Table 1.2)
46 ! listsec1(13)=Type of processed data (Code Table 1.3)
47 ! numlocal - The number of Local Use Sections ( Section 2 ) found in
49 ! numfields- The number of gridded fieldse found in the GRIB message.
50 ! maxvals()- The maximum number of elements that could be returned
51 ! in various arrays from this GRIB2 message. (see REMARKS)
52 ! maxvals(1)=max length of local section 2 (for getlocal)
53 ! maxvals(2)=max length of GDS Template (for gettemplates
55 ! maxvals(3)=max length of GDS Optional list (for getfield)
56 ! maxvals(4)=max length of PDS Template (for gettemplates
58 ! maxvals(5)=max length of PDS Optional list (for getfield)
59 ! maxvals(6)=max length of DRS Template (for gettemplates
61 ! maxvals(7)=max number of gridpoints (for getfield)
62 ! ierr - Error return code.
64 ! 1 = Beginning characters "GRIB" not found.
65 ! 2 = GRIB message is not Edition 2.
66 ! 3 = Could not find Section 1, where expected.
67 ! 4 = End string "7777" found, but not where expected.
68 ! 5 = End string "7777" not found at end of message.
70 ! REMARKS: Array maxvals contains the maximum possible
71 ! number of values that will be returned in argument arrays
72 ! for routines getlocal, gettemplates, and getfields.
73 ! Users can use this info to determine if their arrays are
74 ! dimensioned large enough for the data that may be returned
75 ! from the above routines, or to dynamically allocate arrays
76 ! with a reasonable size.
77 ! NOTE that the actual number of values in these arrays is returned
78 ! from the routines and will likely be less than the values
79 ! calculated by this routine.
82 ! LANGUAGE: Fortran 90
87 character(len=1),intent(in) :: cgrib(lcgrib)
88 integer,intent(in) :: lcgrib
89 integer,intent(out) :: listsec0(3),listsec1(13),maxvals(7)
90 integer,intent(out) :: numlocal,numfields,ierr
92 character(len=4),parameter :: grib='GRIB',c7777='7777'
93 character(len=4) :: ctemp
94 integer,parameter :: zero=0,one=1
95 integer,parameter :: mapsec1len=13
97 & mapsec1(mapsec1len)=(/ 2,2,1,1,1,2,1,1,1,1,1,1,1 /)
98 integer iofst,ibeg,istart
111 ! Check for beginning of GRIB message in the first 100 bytes
115 ctemp=cgrib(j)//cgrib(j+1)//cgrib(j+2)//cgrib(j+3)
116 if (ctemp.eq.grib ) then
121 if (istart.eq.0) then
122 print *,'gribinfo: Beginning characters GRIB not found.'
127 ! Unpack Section 0 - Indicator Section
130 call g2lib_gbyte(cgrib,listsec0(1),iofst,8) ! Discipline
132 call g2lib_gbyte(cgrib,listsec0(2),iofst,8) ! GRIB edition number
135 call g2lib_gbyte(cgrib,lengrib,iofst,32) ! Length of GRIB message
141 ! Currently handles only GRIB Edition 2.
143 if (listsec0(2).ne.2) then
144 print *,'gribinfo: can only decode GRIB edition 2.'
149 ! Unpack Section 1 - Identification Section
151 call g2lib_gbyte(cgrib,lensec1,iofst,32) ! Length of Section 1
153 call g2lib_gbyte(cgrib,isecnum,iofst,8) ! Section number ( 1 )
155 if (isecnum.ne.1) then
156 print *,'gribinfo: Could not find section 1.'
161 ! Unpack each input value in array listsec1 into the
162 ! the appropriate number of octets, which are specified in
163 ! corresponding entries in array mapsec1.
167 call g2lib_gbyte(cgrib,listsec1(i),iofst,nbits)
172 ! Loop through the remaining sections keeping track of the
173 ! length of each. Also count the number of times Section 2
174 ! and Section 4 appear.
177 ctemp=cgrib(ipos)//cgrib(ipos+1)//cgrib(ipos+2)//cgrib(ipos+3)
178 if (ctemp.eq.c7777 ) then
180 if (ipos.ne.(istart+lengrib)) then
181 print *,'gribinfo: "7777" found, but not where expected.'
188 call g2lib_gbyte(cgrib,lensec,iofst,32) ! Get Length of Section
190 call g2lib_gbyte(cgrib,isecnum,iofst,8) ! Get Section number
192 ipos=ipos+lensec ! Update beginning of section pointer
193 if (ipos.gt.(istart+lengrib)) then
194 print *,'gribinfo: "7777" not found at end of GRIB message.'
198 if (isecnum.eq.2) then ! Local Section 2
199 ! increment counter for total number of local sections found
200 ! and determine largest Section 2 in message
203 if ( lenposs.gt.maxsec2len ) maxsec2len=lenposs
204 elseif (isecnum.eq.3) then
205 iofst=iofst+8 ! skip source of grid def.
206 call g2lib_gbyte(cgrib,ngdpts,iofst,32) ! Get Num of Grid Points
208 call g2lib_gbyte(cgrib,nbyte,iofst,8) ! Get Num octets for opt. list
210 if (ngdpts.gt.maxgridpts) maxgridpts=ngdpts
212 if ( lenposs.gt.maxgdstmpl ) maxgdstmpl=lenposs
214 lenposs=lenposs/nbyte
215 if ( lenposs.gt.maxdeflist ) maxdeflist=lenposs
217 elseif (isecnum.eq.4) then
218 numfields=numfields+1
219 call g2lib_gbyte(cgrib,numcoord,iofst,16) ! Get Num of Coord Values
221 if (numcoord.ne.0) then
222 if (numcoord.gt.maxcoordlist) maxcoordlist=numcoord
225 if ( lenposs.gt.maxpdstmpl ) maxpdstmpl=lenposs
226 elseif (isecnum.eq.5) then
228 if ( lenposs.gt.maxdrstmpl ) maxdrstmpl=lenposs
233 maxvals(1)=maxsec2len
234 maxvals(2)=maxgdstmpl
235 maxvals(3)=maxdeflist
236 maxvals(4)=maxpdstmpl
237 maxvals(5)=maxcoordlist
238 maxvals(6)=maxdrstmpl
239 maxvals(7)=maxgridpts