wgrib2api: grb2_inq(..) and Scanning
Introduction
In the page grb2_inq.html, grb2_inq(..) was used to
read individual fields. In some applications, sometimes you have to scan
to see which fields are available. To read the file in "scan" mode, you need
to read the file sequentially. The first call to grb2_inq(..) has
the option "sequential=0". By adding the optional parameter "sequential", only
one matching field is read. By setting sequential to zero, the first matching
field in the file is read.
iret = grb2_inq(GRB2, INV, (list of search terms), (list of options),sequential=0)
reads the first field that matches the search terms
if iret = 0, matching field is not found
To read the remaining matching fields, you read the file sequentially by calls to grb2_inq(..)
using sequantial=N where N is non-zero.
iret = grb2_inq(GRB2, INV, (list of search terms), (list of options),sequential=N)
N is non-zero
reads the next field that matches the search terms
if iret = 0, matching field is not found
The sequential reads should not be mixed with non-sequential reads. It is probably
a mistake if the search terms varies in the sequential reads.
Example
This example comes from Da Li (CMC).
use wgrib2api
character (len=100) :: in, out, inv
character (len=500) :: metadata
real, allocatable :: spfh(:,:), tmp(:,:), w(:,:)
integer :: nlevs, iret, i, j, k
real:: cp, grav, rgas
real, allocatable :: levs(:)
character (len=30), allocatable :: slevs(:)
!---- Constant for poisson's equation
grav = 9.80665 ! m/s**2; gravity
rgas = 287.058 ! J/kg/K; gas constant
in='one.grb2'
inv='tt.inv'
out='omega.grb2'
! make inventory
iret = grb2_mk_inv(in,inv)
if (iret.ne.0) stop 1
! get number of SPFH levels
nlevs = grb2_inq(in,inv,':SPFH:',' mb:')
write(*,*) 'nlevs=',nlevs
allocate (levs(nlevs))
allocate (slevs(nlevs))
! get the pressure levels, and pressure search string by sequential reads
do i = 1,nlevs
iret=grb2_inq(in,inv,':SPFH:',' mb:',sequential=i-1,desc=metadata)
if (iret.ne.1) stop 2
j = index(metadata,':SPFH:') + len(':SPFH:')
k = index(metadata," mb:") + len(" mb:")-1
read(metadata(j:),*) levs(i)
slevs(i) = metadata(j-1:k)
write(*,*) 'levs=',levs(i), slevs(i)
enddo
! need to read the data with random access
! because grib messages can be in any order
do i = 1,nlevs
iret=grb2_inq(in,inv,':SPFH:',slevs(i),data2=spfh)
if (iret.ne.1) stop 3
iret=grb2_inq(in,inv,':TMP:',slevs(i),data2=tmp)
if (iret.ne.1) stop 4
iret=grb2_inq(in,inv,':DZDT:',slevs(i),data2=w)
if (iret.ne.1) stop 5
w = -1.0 * w * levs(i) * 100.0 * grav / (rgas * tmp)
iret=grb2_wrt(out,in,1,data2=w,meta=metadata,mb=levs(i),var='VVEL')
if (iret.ne.0) stop 8
write(*,*) 'omega:',w(1,1), ' level=',levs(i),' hPa'
enddo
stop
end
This above example shows the basic method of scanning a file to find the
vertical levels, and processing the data in order to create new fields.
The above code is independent on the resolution of the grid and the number
of pressure levels.
|