📄 gettemplates.f
字号:
subroutine gettemplates(cgrib,lcgrib,ifldnum,igds,igdstmpl, & igdslen,ideflist,idefnum,ipdsnum,ipdstmpl, & ipdslen,coordlist,numcoord,ierr)!$$$ SUBPROGRAM DOCUMENTATION BLOCK! . . . .! SUBPROGRAM: gettemplates ! PRGMMR: Gilbert ORG: W/NP11 DATE: 2000-05-26!! ABSTRACT: This subroutine returns the Grid Definition, and! Product Definition for a given data! field. Since there can be multiple data fields packed into a GRIB2! message, the calling routine indicates which field is being requested! with the ifldnum argument.!! PROGRAM HISTORY LOG:! 2000-05-26 Gilbert!! USAGE: CALL gettemplates(cgrib,lcgrib,ifldnum,igds,igdstmpl,igdslen,! & ideflist,idefnum,ipdsnum,ipdstmpl,ipdslen,! & coordlist,numcoord,ierr)! INPUT ARGUMENT LIST:! cgrib - Character array that contains the GRIB2 message! lcgrib - Length (in bytes) of GRIB message array cgrib.! ifldnum - Specifies which field in the GRIB2 message to return.!! OUTPUT ARGUMENT LIST: ! igds - Contains information read from the appropriate GRIB Grid ! Definition Section 3 for the field being returned.! Must be dimensioned >= 5.! igds(1)=Source of grid definition (see Code Table 3.0)! igds(2)=Number of grid points in the defined grid.! igds(3)=Number of octets needed for each ! additional grid points definition. ! Used to define number of! points in each row ( or column ) for! non-regular grids. ! = 0, if using regular grid.! igds(4)=Interpretation of list for optional points ! definition. (Code Table 3.11)! igds(5)=Grid Definition Template Number (Code Table 3.1)! igdstmpl - Contains the data values for the specified Grid Definition! Template ( NN=igds(5) ). Each element of this integer ! array contains an entry (in the order specified) of Grid! Defintion Template 3.NN! A safe dimension for this array can be obtained in advance! from maxvals(2), which is returned from subroutine gribinfo.! igdslen - Number of elements in igdstmpl(). i.e. number of entries! in Grid Defintion Template 3.NN ( NN=igds(5) ).! ideflist - (Used if igds(3) .ne. 0) This array contains the! number of grid points contained in each row ( or column ).! (part of Section 3)! A safe dimension for this array can be obtained in advance! from maxvals(3), which is returned from subroutine gribinfo.! idefnum - (Used if igds(3) .ne. 0) The number of entries! in array ideflist. i.e. number of rows ( or columns )! for which optional grid points are defined.! ipdsnum - Product Definition Template Number ( see Code Table 4.0)! ipdstmpl - Contains the data values for the specified Product Definition! Template ( N=ipdsnum ). Each element of this integer! array contains an entry (in the order specified) of Product! Defintion Template 4.N! A safe dimension for this array can be obtained in advance! from maxvals(4), which is returned from subroutine gribinfo.! ipdslen - Number of elements in ipdstmpl(). i.e. number of entries! in Product Defintion Template 4.N ( N=ipdsnum ).! coordlist- Array containg floating point values intended to document! the vertical discretisation associated to model data! on hybrid coordinate vertical levels. (part of Section 4)! The dimension of this array can be obtained in advance! from maxvals(5), which is returned from subroutine gribinfo.! numcoord - number of values in array coordlist.! ierr - Error return code.! 0 = no error! 1 = Beginning characters "GRIB" not found.! 2 = GRIB message is not Edition 2.! 3 = The data field request number was not positive.! 4 = End string "7777" found, but not where expected.! 6 = GRIB message did not contain the requested number of! data fields.! 7 = End string "7777" not found at end of message.! 10 = Error unpacking Section 3.! 11 = Error unpacking Section 4.!! REMARKS: Note that subroutine gribinfo can be used to first determine! how many data fields exist in the given GRIB message.!! ATTRIBUTES:! LANGUAGE: Fortran 90! MACHINE: IBM SP!!$$$ character(len=1),intent(in) :: cgrib(lcgrib) integer,intent(in) :: lcgrib,ifldnum integer,intent(out) :: igds(*),igdstmpl(*),ideflist(*) integer,intent(out) :: ipdsnum,ipdstmpl(*) integer,intent(out) :: idefnum,numcoord integer,intent(out) :: ierr real,intent(out) :: coordlist(*) character(len=4),parameter :: grib='GRIB',c7777='7777' character(len=4) :: ctemp integer:: listsec0(2) integer iofst,ibeg,istart logical have3,have4 have3=.false. have4=.false. ierr=0 numfld=0!! Check for valid request number! if (ifldnum.le.0) then print *,'gettemplates: Request for field number must be ', & 'positive.' ierr=3 return endif!! Check for beginning of GRIB message in the first 100 bytes! istart=0 do j=1,100 ctemp=cgrib(j)//cgrib(j+1)//cgrib(j+2)//cgrib(j+3) if (ctemp.eq.grib ) then istart=j exit endif enddo if (istart.eq.0) then print *,'gettemplates: Beginning characters GRIB not found.' ierr=1 return endif!! Unpack Section 0 - Indicator Section ! iofst=8*(istart+5) call gbyte(cgrib,listsec0(1),iofst,8) ! Discipline iofst=iofst+8 call gbyte(cgrib,listsec0(2),iofst,8) ! GRIB edition number iofst=iofst+8 iofst=iofst+32 call gbyte(cgrib,lengrib,iofst,32) ! Length of GRIB message iofst=iofst+32 lensec0=16 ipos=istart+lensec0!! Currently handles only GRIB Edition 2.! if (listsec0(2).ne.2) then print *,'gettemplates: can only decode GRIB edition 2.' ierr=2 return endif!! Loop through the remaining sections keeping track of the ! length of each. Also keep the latest Grid Definition Section info.! Unpack the requested field number.! do ! Check to see if we are at end of GRIB message ctemp=cgrib(ipos)//cgrib(ipos+1)//cgrib(ipos+2)//cgrib(ipos+3) if (ctemp.eq.c7777 ) then ipos=ipos+4 ! If end of GRIB message not where expected, issue error if (ipos.ne.(istart+lengrib)) then print *,'gettemplates: "7777" found, but not where ', & 'expected.' ierr=4 return endif exit endif ! Get length of Section and Section number iofst=(ipos-1)*8 call gbyte(cgrib,lensec,iofst,32) ! Get Length of Section iofst=iofst+32 call gbyte(cgrib,isecnum,iofst,8) ! Get Section number iofst=iofst+8 !print *,' lensec= ',lensec,' secnum= ',isecnum ! ! If found Section 3, unpack the GDS info using the ! appropriate template. Save in case this is the latest ! grid before the requested field. ! if (isecnum.eq.3) then iofst=iofst-40 ! reset offset to beginning of section call unpack3(cgrib,lcgrib,iofst,igds,igdstmpl,igdslen, & ideflist,idefnum,jerr) if (jerr.eq.0) then have3=.true. else ierr=10 return endif endif ! ! If found Section 4, check to see if this field is the ! one requested. ! if (isecnum.eq.4) then numfld=numfld+1 if (numfld.eq.ifldnum) then iofst=iofst-40 ! reset offset to beginning of section call unpack4(cgrib,lcgrib,iofst,ipdsnum,ipdstmpl,ipdslen, & coordlist,numcoord,jerr) if (jerr.eq.0) then have4=.true. else ierr=11 return endif endif endif ! ! Check to see if we read pass the end of the GRIB ! message and missed the terminator string '7777'. ! ipos=ipos+lensec ! Update beginning of section pointer if (ipos.gt.(istart+lengrib)) then print *,'gettemplates: "7777" not found at end of GRIB ', & 'message.' ierr=7 return endif if (have3.and.have4) return enddo!! If exited from above loop, the end of the GRIB message was reached! before the requested field was found.! print *,'gettemplates: GRIB message contained ',numlocal, & ' different fields.' print *,'gettemplates: The request was for the ',ifldnum, & ' field.' ierr=6 return end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -