1 subroutine getfield
(cgrib
,lcgrib
,ifldnum
,igds
,igdstmpl
,igdslen
,
2 & ideflist
,idefnum
,ipdsnum
,ipdstmpl
,ipdslen
,
3 & coordlist
,numcoord
,ndpts
,idrsnum
,idrstmpl
,
4 & idrslen
,ibmap
,bmap
,fld
,ierr
)
5 !$$$ SUBPROGRAM DOCUMENTATION BLOCK
8 ! PRGMMR
: Gilbert ORG
: W
/NP11
DATE: 2000-05-26
10 ! ABSTRACT
: This
subroutine returns the Grid Definition
, Product Definition
,
11 ! Bit
-map
( if applicable
), and the unpacked data
for a given data
12 ! field
. Since there can be multiple data fields packed into a GRIB2
13 ! message
, the calling routine indicates which field is being requested
14 ! with the ifldnum argument
.
16 ! PROGRAM HISTORY LOG
:
19 ! USAGE
: CALL getfield
(cgrib
,lcgrib
,ifldnum
,igds
,igdstmpl
,igdslen
,
20 ! & ideflist
,idefnum
,ipdsnum
,ipdstmpl
,ipdslen
,
21 ! & coordlist
,numcoord
,ndpts
,idrsnum
,idrstmpl
,
22 ! & idrslen
,ibmap
,bmap
,fld
,ierr
)
23 ! INPUT ARGUMENT LIST
:
24 ! cgrib
- Character array that contains the GRIB2 message
25 ! lcgrib
- Length
(in bytes
) of GRIB message array cgrib
.
26 ! ifldnum
- Specifies which field in the GRIB2 message
to return.
28 ! OUTPUT ARGUMENT LIST
:
29 ! igds
- Contains information
read from the appropriate GRIB Grid
30 ! Definition Section
3 for the field being returned
.
31 ! Must be dimensioned
>= 5.
32 ! igds
(1)=Source of grid definition
(see Code Table
3.0)
33 ! igds
(2)=Number of grid points in the defined grid
.
34 ! igds
(3)=Number of octets needed
for each
35 ! additional grid points definition
.
36 ! Used
to define number of
37 ! points in each row
( or column
) for
39 ! = 0, if using regular grid
.
40 ! igds
(4)=Interpretation of list
for optional points
41 ! definition
. (Code Table
3.11)
42 ! igds
(5)=Grid Definition Template Number
(Code Table
3.1)
43 ! igdstmpl
- Contains the data values
for the specified Grid Definition
44 ! Template
( NN
=igds
(5) ). Each element of this
integer
45 ! array contains an entry
(in the order specified
) of Grid
46 ! Defintion Template
3.NN
47 ! A safe
dimension for this array can be obtained in advance
48 ! from maxvals
(2), which is returned from
subroutine gribinfo
.
49 ! igdslen
- Number of elements in igdstmpl
(). i
.e
. number of entries
50 ! in Grid Defintion Template
3.NN
( NN
=igds
(5) ).
51 ! ideflist
- (Used
if igds
(3) .ne
. 0) This array contains the
52 ! number of grid points contained in each row
( or column
).
54 ! A safe
dimension for this array can be obtained in advance
55 ! from maxvals
(3), which is returned from
subroutine gribinfo
.
56 ! idefnum
- (Used
if igds
(3) .ne
. 0) The number of entries
57 ! in array ideflist
. i
.e
. number of rows
( or columns
)
58 ! for which optional grid points are defined
.
59 ! ipdsnum
- Product Definition Template Number
( see Code Table
4.0)
60 ! ipdstmpl
- Contains the data values
for the specified Product Definition
61 ! Template
( N
=ipdsnum
). Each element of this
integer
62 ! array contains an entry
(in the order specified
) of Product
63 ! Defintion Template
4.N
64 ! A safe
dimension for this array can be obtained in advance
65 ! from maxvals
(4), which is returned from
subroutine gribinfo
.
66 ! ipdslen
- Number of elements in ipdstmpl
(). i
.e
. number of entries
67 ! in Product Defintion Template
4.N
( N
=ipdsnum
).
68 ! coordlist
- Array containg floating point values intended
to document
69 ! the vertical discretisation associated
to model data
70 ! on hybrid coordinate vertical levels
. (part of Section
4)
71 ! The
dimension of this array can be obtained in advance
72 ! from maxvals
(5), which is returned from
subroutine gribinfo
.
73 ! numcoord
- number of values in array coordlist
.
74 ! ndpts
- Number of data points unpacked and returned
.
75 ! idrsnum
- Data Representation Template Number
( see Code Table
5.0)
76 ! idrstmpl
- Contains the data values
for the specified Data Representation
77 ! Template
( N
=idrsnum
). Each element of this
integer
78 ! array contains an entry
(in the order specified
) of Product
79 ! Defintion Template
5.N
80 ! A safe
dimension for this array can be obtained in advance
81 ! from maxvals
(6), which is returned from
subroutine gribinfo
.
82 ! idrslen
- Number of elements in idrstmpl
(). i
.e
. number of entries
83 ! in Data Representation Template
5.N
( N
=idrsnum
).
84 ! ibmap
- Bitmap indicator
( see Code Table
6.0 )
85 ! 0 = bitmap applies and is included in Section
6.
86 ! 1-253 = Predefined bitmap applies
87 ! 254 = Previously defined bitmap applies
to this field
88 ! 255 = Bit map does not apply
to this product
.
89 ! bmap
() - Logical*1 array containing decoded bitmap
. ( if ibmap
=0 )
90 ! The
dimension of this array can be obtained in advance
91 ! from maxvals
(7), which is returned from
subroutine gribinfo
.
92 ! fld
() - Array of ndpts unpacked data points
.
93 ! A safe
dimension for this array can be obtained in advance
94 ! from maxvals
(7), which is returned from
subroutine gribinfo
.
95 ! ierr
- Error
return code
.
97 ! 1 = Beginning characters
"GRIB" not found
.
98 ! 2 = GRIB message is not Edition
2.
99 ! 3 = The data field request number was not positive
.
100 ! 4 = End string
"7777" found
, but not where expected
.
101 ! 6 = GRIB message did not contain the requested number of
103 ! 7 = End string
"7777" not found at
end of message
.
104 ! 9 = Data Representation Template
5.NN not yet implemented
.
105 ! 10 = Error unpacking Section
3.
106 ! 11 = Error unpacking Section
4.
107 ! 12 = Error unpacking Section
5.
108 ! 13 = Error unpacking Section
6.
109 ! 14 = Error unpacking Section
7.
111 ! REMARKS
: Note that
subroutine gribinfo can be used
to first determine
112 ! how many data fields exist in a given GRIB message
.
115 ! LANGUAGE
: Fortran
90
120 character(len
=1),intent
(in
) :: cgrib
(lcgrib
)
121 integer,intent
(in
) :: lcgrib
,ifldnum
122 integer,intent
(out
) :: igds
(*),igdstmpl
(*),ideflist
(*)
123 integer,intent
(out
) :: ipdsnum
,ipdstmpl
(*)
124 integer,intent
(out
) :: idrsnum
,idrstmpl
(*)
125 integer,intent
(out
) :: ndpts
,ibmap
,idefnum
,numcoord
126 integer,intent
(out
) :: ierr
127 logical*1
,intent
(out
) :: bmap
(*)
128 real,intent
(out
) :: fld
(*),coordlist
(*)
130 character(len
=4),parameter :: grib
='GRIB',c7777
='7777'
131 character(len
=4) :: ctemp
132 integer:: listsec0
(2)
133 integer iofst
,ibeg
,istart
135 logical have3
,have4
,have5
,have6
,have7
145 ! Check
for valid request number
147 if (ifldnum
.le
.0) then
148 print
*,'getfield: Request for field number must be positive.'
153 ! Check
for beginning of GRIB message in the first
100 bytes
157 ctemp
=cgrib
(j
)//cgrib
(j
+1)//cgrib
(j
+2)//cgrib
(j
+3)
158 if (ctemp
.eq
.grib
) then
163 if (istart
.eq
.0) then
164 print
*,'getfield: Beginning characters GRIB not found.'
169 ! Unpack Section
0 - Indicator Section
172 call gbyte
(cgrib
,listsec0
(1),iofst
,8) ! Discipline
174 call gbyte
(cgrib
,listsec0
(2),iofst
,8) ! GRIB edition number
177 call gbyte
(cgrib
,lengrib
,iofst
,32) ! Length of GRIB message
182 ! Currently handles only GRIB Edition
2.
184 if (listsec0
(2).ne
.2) then
185 print
*,'getfield: can only decode GRIB edition 2.'
190 ! Loop through the remaining sections keeping track of the
191 ! length of each
. Also keep the latest Grid Definition Section info
.
192 ! Unpack the requested field number
.
195 ! Check
to see
if we are at
end of GRIB message
196 ctemp
=cgrib
(ipos
)//cgrib
(ipos
+1)//cgrib
(ipos
+2)//cgrib
(ipos
+3)
197 if (ctemp
.eq
.c7777
) then
199 ! If end of GRIB message not where expected
, issue error
200 if (ipos
.ne
.(istart
+lengrib
)) then
201 print
*,'getfield: "7777" found, but not where expected.'
207 ! Get length of Section and Section number
209 call gbyte
(cgrib
,lensec
,iofst
,32) ! Get Length of Section
211 call gbyte
(cgrib
,isecnum
,iofst
,8) ! Get Section number
213 !print
*,' lensec= ',lensec
,' secnum= ',isecnum
215 ! If found Section
3, unpack the GDS info using the
216 ! appropriate template
. Save in case this is the latest
217 ! grid before the requested field
.
219 if (isecnum
.eq
.3) then
220 iofst
=iofst
-40 ! reset offset
to beginning of section
221 call unpack3
(cgrib
,lcgrib
,iofst
,igds
,igdstmpl
,igdslen
,
222 & ideflist
,idefnum
,jerr
)
231 ! If found Section
4, check
to see
if this field is the
234 if (isecnum
.eq
.4) then
236 if (numfld
.eq
.ifldnum
) then
237 iofst
=iofst
-40 ! reset offset
to beginning of section
238 call unpack4
(cgrib
,lcgrib
,iofst
,ipdsnum
,ipdstmpl
,ipdslen
,
239 & coordlist
,numcoord
,jerr
)
249 ! If found Section
5, check
to see
if this field is the
252 if ((isecnum
.eq
.5).and
.(numfld
.eq
.ifldnum
)) then
253 iofst
=iofst
-40 ! reset offset
to beginning of section
254 call unpack5
(cgrib
,lcgrib
,iofst
,ndpts
,idrsnum
,idrstmpl
,
264 ! If found Section
6, Unpack bitmap
.
265 ! Save in case this is the latest
266 ! bitmap before the requested field
.
268 if (isecnum
.eq
.6) then
269 iofst
=iofst
-40 ! reset offset
to beginning of section
270 call unpack6
(cgrib
,lcgrib
,iofst
,igds
(2),ibmap
,bmap
,jerr
)
279 ! If found Section
7, check
to see
if this field is the
282 if ((isecnum
.eq
.7).and
.(numfld
.eq
.ifldnum
)) then
283 if (idrsnum
.eq
.0) then
284 call simunpack
(cgrib
(ipos
+5),lensec
-6,idrstmpl
,ndpts
,fld
)
286 elseif
(idrsnum
.eq
.2.or
.idrsnum
.eq
.3) then
287 call comunpack
(cgrib
(ipos
+5),lensec
-6,lensec
,idrsnum
,
288 & idrstmpl
,ndpts
,fld
,ier
)
289 if ( ier
.ne
. 0 ) then
294 elseif
(idrsnum
.eq
.50) then
295 call simunpack
(cgrib
(ipos
+5),lensec
-6,idrstmpl
,ndpts
-1,
298 call rdieee
(ieee
,fld
(1),1)
300 elseif
(idrsnum
.eq
.40 .OR
. idrsnum
.eq
.40000) then
301 call jpcunpack
(cgrib
(ipos
+5),lensec
-5,idrstmpl
,ndpts
,fld
)
303 elseif
(idrsnum
.eq
.41 .OR
. idrsnum
.eq
.40010) then
304 call pngunpack
(cgrib
(ipos
+5),lensec
-5,idrstmpl
,ndpts
,fld
)
307 print
*,'getfield: Data Representation Template ',idrsnum
,
308 & ' not yet implemented.'
314 ! Check
to see
if we
read pass the
end of the GRIB
315 ! message and missed the terminator string
'7777'.
317 ipos
=ipos
+lensec
! Update beginning of section pointer
318 if (ipos
.gt
.(istart
+lengrib
)) then
319 print
*,'getfield: "7777" not found at end of GRIB message.'
324 if (have3
.and
.have4
.and
.have5
.and
.have6
.and
.have7
) return
329 ! If exited from above loop
, the
end of the GRIB message was reached
330 ! before the requested field was found
.
332 print
*,'getfield: GRIB message contained ',numlocal
,
333 & ' different fields.'
334 print
*,'getfield: The request was for the ',ifldnum
,
342 subroutine unpack3
(cgrib
,lcgrib
,iofst
,igds
,igdstmpl
,
343 & mapgridlen
,ideflist
,idefnum
,ierr
)
344 !$$$ SUBPROGRAM DOCUMENTATION BLOCK
346 ! SUBPROGRAM
: unpack3
347 ! PRGMMR
: Gilbert ORG
: W
/NP11
DATE: 2000-05-26
349 ! ABSTRACT
: This
subroutine unpacks Section
3 (Grid Definition Section
)
350 ! starting at octet
6 of that Section
.
352 ! PROGRAM HISTORY LOG
:
355 ! USAGE
: CALL unpack3
(cgrib
,lcgrib
,lensec
,iofst
,igds
,igdstmpl
,
356 ! & mapgridlen
,ideflist
,idefnum
,ierr
)
357 ! INPUT ARGUMENT LIST
:
358 ! cgrib
- Character array that contains the GRIB2 message
359 ! lcgrib
- Length
(in bytes
) of GRIB message array cgrib
.
360 ! iofst
- Bit offset of the beginning of Section
3.
362 ! OUTPUT ARGUMENT LIST
:
363 ! iofst
- Bit offset at the
end of Section
3, returned
.
364 ! igds
- Contains information
read from the appropriate GRIB Grid
365 ! Definition Section
3 for the field being returned
.
366 ! Must be dimensioned
>= 5.
367 ! igds
(1)=Source of grid definition
(see Code Table
3.0)
368 ! igds
(2)=Number of grid points in the defined grid
.
369 ! igds
(3)=Number of octets needed
for each
370 ! additional grid points definition
.
371 ! Used
to define number of
372 ! points in each row
( or column
) for
374 ! = 0, if using regular grid
.
375 ! igds
(4)=Interpretation of list
for optional points
376 ! definition
. (Code Table
3.11)
377 ! igds
(5)=Grid Definition Template Number
(Code Table
3.1)
378 ! igdstmpl
- Contains the data values
for the specified Grid Definition
379 ! Template
( NN
=igds
(5) ). Each element of this
integer
380 ! array contains an entry
(in the order specified
) of Grid
381 ! Defintion Template
3.NN
382 ! mapgridlen
- Number of elements in igdstmpl
(). i
.e
. number of entries
383 ! in Grid Defintion Template
3.NN
( NN
=igds
(5) ).
384 ! ideflist
- (Used
if igds
(3) .ne
. 0) This array contains the
385 ! number of grid points contained in each row
( or column
).
386 ! (part of Section
3)
387 ! idefnum
- (Used
if igds
(3) .ne
. 0) The number of entries
388 ! in array ideflist
. i
.e
. number of rows
( or columns
)
389 ! for which optional grid points are defined
.
390 ! ierr
- Error
return code
.
392 ! 5 = "GRIB" message contains an undefined Grid Definition
395 ! REMARKS
: Uses Fortran
90 module gridtemplates
.
398 ! LANGUAGE
: Fortran
90
405 character(len
=1),intent
(in
) :: cgrib
(lcgrib
)
406 integer,intent
(in
) :: lcgrib
407 integer,intent
(inout
) :: iofst
408 integer,intent
(out
) :: igds
(*),igdstmpl
(*),ideflist
(*)
409 integer,intent
(out
) :: ierr
,idefnum
411 integer,allocatable
:: mapgrid
(:)
412 integer :: mapgridlen
,ibyttem
417 call gbyte
(cgrib
,lensec
,iofst
,32) ! Get Length of Section
419 iofst
=iofst
+8 ! skip section number
421 call gbyte
(cgrib
,igds
(1),iofst
,8) ! Get source of Grid def
.
423 call gbyte
(cgrib
,igds
(2),iofst
,32) ! Get number of grid pts
.
425 call gbyte
(cgrib
,igds
(3),iofst
,8) ! Get num octets
for opt
. list
427 call gbyte
(cgrib
,igds
(4),iofst
,8) ! Get interpret
. for opt
. list
429 call gbyte
(cgrib
,igds
(5),iofst
,16) ! Get Grid Def Template num
.
431 if (igds
(1).eq
.0) then
432 ! if (igds
(1).eq
.0.OR
.igds
(1).eq
.255) then ! FOR ECMWF TEST ONLY
433 allocate
(mapgrid
(lensec
))
434 ! Get Grid Definition Template
435 call getgridtemplate
(igds
(5),mapgridlen
,mapgrid
,needext
,
447 ! Unpack each value into array igdstmpl from the
448 ! the appropriate number of octets
, which are specified in
449 ! corresponding entries in array mapgrid
.
453 nbits
=iabs
(mapgrid
(i
))*8
454 if ( mapgrid
(i
).ge
.0 ) then
455 call gbyte
(cgrib
,igdstmpl
(i
),iofst
,nbits
)
457 call gbyte
(cgrib
,isign
,iofst
,1)
458 call gbyte
(cgrib
,igdstmpl
(i
),iofst
+1,nbits
-1)
459 if (isign
.eq
.1) igdstmpl
(i
)=-igdstmpl
(i
)
462 ibyttem
=ibyttem
+iabs
(mapgrid
(i
))
465 ! Check
to see
if the Grid Definition Template needs
to be
467 ! The number of values in a specific template may vary
468 ! depending on data specified in the
"static" part of the
472 call extgridtemplate
(igds
(5),igdstmpl
,newmapgridlen
,mapgrid
)
473 ! Unpack the rest of the Grid Definition Template
474 do i
=mapgridlen
+1,newmapgridlen
475 nbits
=iabs
(mapgrid
(i
))*8
476 if ( mapgrid
(i
).ge
.0 ) then
477 call gbyte
(cgrib
,igdstmpl
(i
),iofst
,nbits
)
479 call gbyte
(cgrib
,isign
,iofst
,1)
480 call gbyte
(cgrib
,igdstmpl
(i
),iofst
+1,nbits
-1)
481 if (isign
.eq
.1) igdstmpl
(i
)=-igdstmpl
(i
)
484 ibyttem
=ibyttem
+iabs
(mapgrid
(i
))
486 mapgridlen
=newmapgridlen
489 ! Unpack optional list of numbers defining number of points
490 ! in each row or column
, if included
. This is used
for non regular
493 if ( igds
(3).ne
.0 ) then
495 idefnum
=(lensec
-14-ibyttem
)/igds
(3)
496 call gbytes
(cgrib
,ideflist
,iofst
,nbits
,0,idefnum
)
497 iofst
=iofst
+(nbits*idefnum
)
501 if( allocated
(mapgrid
) ) deallocate
(mapgrid
)
502 return ! End of Section
3 processing
506 subroutine unpack4
(cgrib
,lcgrib
,iofst
,ipdsnum
,ipdstmpl
,mappdslen
,
507 & coordlist
,numcoord
,ierr
)
508 !$$$ SUBPROGRAM DOCUMENTATION BLOCK
510 ! SUBPROGRAM
: unpack4
511 ! PRGMMR
: Gilbert ORG
: W
/NP11
DATE: 2000-05-26
513 ! ABSTRACT
: This
subroutine unpacks Section
4 (Product Definition Section
)
514 ! starting at octet
6 of that Section
.
516 ! PROGRAM HISTORY LOG
:
519 ! USAGE
: CALL unpack4
(cgrib
,lcgrib
,iofst
,ipdsnum
,ipdstmpl
,mappdslen
,
520 ! & coordlist
,numcoord
,ierr
)
521 ! INPUT ARGUMENT LIST
:
522 ! cgrib
- Character array that contains the GRIB2 message
523 ! lcgrib
- Length
(in bytes
) of GRIB message array cgrib
.
524 ! iofst
- Bit offset of the beginning of Section
4.
526 ! OUTPUT ARGUMENT LIST
:
527 ! iofst
- Bit offset of the
end of Section
4, returned
.
528 ! ipdsnum
- Product Definition Template Number
( see Code Table
4.0)
529 ! ipdstmpl
- Contains the data values
for the specified Product Definition
530 ! Template
( N
=ipdsnum
). Each element of this
integer
531 ! array contains an entry
(in the order specified
) of Product
532 ! Defintion Template
4.N
533 ! mappdslen
- Number of elements in ipdstmpl
(). i
.e
. number of entries
534 ! in Product Defintion Template
4.N
( N
=ipdsnum
).
535 ! coordlist
- Array containg floating point values intended
to document
536 ! the vertical discretisation associated
to model data
537 ! on hybrid coordinate vertical levels
. (part of Section
4)
538 ! numcoord
- number of values in array coordlist
.
539 ! ierr
- Error
return code
.
541 ! 5 = "GRIB" message contains an undefined Product Definition
544 ! REMARKS
: Uses Fortran
90 module pdstemplates
.
547 ! LANGUAGE
: Fortran
90
554 character(len
=1),intent
(in
) :: cgrib
(lcgrib
)
555 integer,intent
(in
) :: lcgrib
556 integer,intent
(inout
) :: iofst
557 real,intent
(out
) :: coordlist
(*)
558 integer,intent
(out
) :: ipdsnum
,ipdstmpl
(*)
559 integer,intent
(out
) :: ierr
,numcoord
561 real(4),allocatable
:: coordieee
(:)
562 integer,allocatable
:: mappds
(:)
568 call gbyte
(cgrib
,lensec
,iofst
,32) ! Get Length of Section
570 iofst
=iofst
+8 ! skip section number
571 allocate
(mappds
(lensec
))
573 call gbyte
(cgrib
,numcoord
,iofst
,16) ! Get num of coordinate values
575 call gbyte
(cgrib
,ipdsnum
,iofst
,16) ! Get Prod
. Def Template num
.
577 ! Get Product Definition Template
578 call getpdstemplate
(ipdsnum
,mappdslen
,mappds
,needext
,iret
)
584 ! Unpack each value into array ipdstmpl from the
585 ! the appropriate number of octets
, which are specified in
586 ! corresponding entries in array mappds
.
589 nbits
=iabs
(mappds
(i
))*8
590 if ( mappds
(i
).ge
.0 ) then
591 call gbyte
(cgrib
,ipdstmpl
(i
),iofst
,nbits
)
593 call gbyte
(cgrib
,isign
,iofst
,1)
594 call gbyte
(cgrib
,ipdstmpl
(i
),iofst
+1,nbits
-1)
595 if (isign
.eq
.1) ipdstmpl
(i
)=-ipdstmpl
(i
)
600 ! Check
to see
if the Product Definition Template needs
to be
602 ! The number of values in a specific template may vary
603 ! depending on data specified in the
"static" part of the
607 call extpdstemplate
(ipdsnum
,ipdstmpl
,newmappdslen
,mappds
)
608 ! Unpack the rest of the Product Definition Template
609 do i
=mappdslen
+1,newmappdslen
610 nbits
=iabs
(mappds
(i
))*8
611 if ( mappds
(i
).ge
.0 ) then
612 call gbyte
(cgrib
,ipdstmpl
(i
),iofst
,nbits
)
614 call gbyte
(cgrib
,isign
,iofst
,1)
615 call gbyte
(cgrib
,ipdstmpl
(i
),iofst
+1,nbits
-1)
616 if (isign
.eq
.1) ipdstmpl
(i
)=-ipdstmpl
(i
)
620 mappdslen
=newmappdslen
623 ! Get Optional list of vertical coordinate values
624 ! after the Product Definition Template
, if necessary
.
626 if ( numcoord
.ne
. 0 ) then
627 allocate
(coordieee
(numcoord
))
628 call gbytes
(cgrib
,coordieee
,iofst
,32,0,numcoord
)
629 call rdieee
(coordieee
,coordlist
,numcoord
)
630 deallocate
(coordieee
)
631 iofst
=iofst
+(32*numcoord
)
633 if( allocated
(mappds
) ) deallocate
(mappds
)
634 return ! End of Section
4 processing
638 subroutine unpack5
(cgrib
,lcgrib
,iofst
,ndpts
,idrsnum
,idrstmpl
,
640 !$$$ SUBPROGRAM DOCUMENTATION BLOCK
642 ! SUBPROGRAM
: unpack5
643 ! PRGMMR
: Gilbert ORG
: W
/NP11
DATE: 2000-05-26
645 ! ABSTRACT
: This
subroutine unpacks Section
5 (Data Representation Section
)
646 ! starting at octet
6 of that Section
.
648 ! PROGRAM HISTORY LOG
:
651 ! USAGE
: CALL unpack5
(cgrib
,lcgrib
,iofst
,ndpts
,idrsnum
,idrstmpl
,
653 ! INPUT ARGUMENT LIST
:
654 ! cgrib
- Character array that contains the GRIB2 message
655 ! lcgrib
- Length
(in bytes
) of GRIB message array cgrib
.
656 ! iofst
- Bit offset of the beginning of Section
5.
658 ! OUTPUT ARGUMENT LIST
:
659 ! iofst
- Bit offset at the
end of Section
5, returned
.
660 ! ndpts
- Number of data points unpacked and returned
.
661 ! idrsnum
- Data Representation Template Number
( see Code Table
5.0)
662 ! idrstmpl
- Contains the data values
for the specified Data Representation
663 ! Template
( N
=idrsnum
). Each element of this
integer
664 ! array contains an entry
(in the order specified
) of Data
665 ! Representation Template
5.N
666 ! mapdrslen
- Number of elements in idrstmpl
(). i
.e
. number of entries
667 ! in Data Representation Template
5.N
( N
=idrsnum
).
668 ! ierr
- Error
return code
.
670 ! 7 = "GRIB" message contains an undefined Data
671 ! Representation Template
.
676 ! LANGUAGE
: Fortran
90
683 character(len
=1),intent
(in
) :: cgrib
(lcgrib
)
684 integer,intent
(in
) :: lcgrib
685 integer,intent
(inout
) :: iofst
686 integer,intent
(out
) :: ndpts
,idrsnum
,idrstmpl
(*)
687 integer,intent
(out
) :: ierr
689 C integer,allocatable :: mapdrs(:)
690 integer,allocatable
:: mapdrs
(:)
696 call gbyte
(cgrib
,lensec
,iofst
,32) ! Get Length of Section
698 iofst
=iofst
+8 ! skip section number
699 allocate
(mapdrs
(lensec
))
701 call gbyte
(cgrib
,ndpts
,iofst
,32) ! Get num of data points
703 call gbyte
(cgrib
,idrsnum
,iofst
,16) ! Get Data Rep Template Num
.
705 ! Gen Data Representation Template
706 call getdrstemplate
(idrsnum
,mapdrslen
,mapdrs
,needext
,iret
)
712 ! Unpack each value into array ipdstmpl from the
713 ! the appropriate number of octets
, which are specified in
714 ! corresponding entries in array mappds
.
717 nbits
=iabs
(mapdrs
(i
))*8
718 if ( mapdrs
(i
).ge
.0 ) then
719 call gbyte
(cgrib
,idrstmpl
(i
),iofst
,nbits
)
721 call gbyte
(cgrib
,isign
,iofst
,1)
722 call gbyte
(cgrib
,idrstmpl
(i
),iofst
+1,nbits
-1)
723 if (isign
.eq
.1) idrstmpl
(i
)=-idrstmpl
(i
)
728 ! Check
to see
if the Data Representation Template needs
to be
730 ! The number of values in a specific template may vary
731 ! depending on data specified in the
"static" part of the
735 call extdrstemplate
(idrsnum
,idrstmpl
,newmapdrslen
,mapdrs
)
736 ! Unpack the rest of the Data Representation Template
737 do i
=mapdrslen
+1,newmapdrslen
738 nbits
=iabs
(mapdrs
(i
))*8
739 if ( mapdrs
(i
).ge
.0 ) then
740 call gbyte
(cgrib
,idrstmpl
(i
),iofst
,nbits
)
742 call gbyte
(cgrib
,isign
,iofst
,1)
743 call gbyte
(cgrib
,idrstmpl
(i
),iofst
+1,nbits
-1)
744 if (isign
.eq
.1) idrstmpl
(i
)=-idrstmpl
(i
)
748 mapdrslen
=newmapdrslen
750 if( allocated
(mapdrs
) ) deallocate
(mapdrs
)
751 return ! End of Section
5 processing
755 subroutine unpack6
(cgrib
,lcgrib
,iofst
,ngpts
,ibmap
,bmap
,ierr
)
756 !$$$ SUBPROGRAM DOCUMENTATION BLOCK
758 ! SUBPROGRAM
: unpack6
759 ! PRGMMR
: Gilbert ORG
: W
/NP11
DATE: 2000-05-26
761 ! ABSTRACT
: This
subroutine unpacks Section
6 (Bit
-Map Section
)
762 ! starting at octet
6 of that Section
.
764 ! PROGRAM HISTORY LOG
:
767 ! USAGE
: CALL unpack6
(cgrib
,lcgrib
,iofst
,ngpts
,ibmap
,bmap
,ierr
)
768 ! INPUT ARGUMENT LIST
:
769 ! cgrib
- Character array that contains the GRIB2 message
770 ! lcgrib
- Length
(in bytes
) of GRIB message array cgrib
.
771 ! iofst
- Bit offset of the beginning of Section
6.
772 ! ngpts
- Number of grid points specified in the bit
-map
774 ! OUTPUT ARGUMENT LIST
:
775 ! iofst
- Bit offset at the
end of Section
6, returned
.
776 ! ibmap
- Bitmap indicator
( see Code Table
6.0 )
777 ! 0 = bitmap applies and is included in Section
6.
778 ! 1-253 = Predefined bitmap applies
779 ! 254 = Previously defined bitmap applies
to this field
780 ! 255 = Bit map does not apply
to this product
.
781 ! bmap
() - Logical*1 array containing decoded bitmap
. ( if ibmap
=0 )
782 ! ierr
- Error
return code
.
784 ! 4 = Unrecognized pre
-defined bit
-map
.
789 ! LANGUAGE
: Fortran
90
794 character(len
=1),intent
(in
) :: cgrib
(lcgrib
)
795 integer,intent
(in
) :: lcgrib
,ngpts
796 integer,intent
(inout
) :: iofst
797 integer,intent
(out
) :: ibmap
798 integer,intent
(out
) :: ierr
799 logical*1
,intent
(out
) :: bmap
(ngpts
)
801 integer :: intbmap
(ngpts
)
805 iofst
=iofst
+32 ! skip Length of Section
806 iofst
=iofst
+8 ! skip section number
808 call gbyte
(cgrib
,ibmap
,iofst
,8) ! Get bit
-map indicator
811 if (ibmap
.eq
.0) then ! Unpack bitmap
812 call gbytes
(cgrib
,intbmap
,iofst
,1,0,ngpts
)
816 if (intbmap
(j
).eq
.0) bmap
(j
)=.false
.
818 elseif
(ibmap
.eq
.254) then ! Use previous bitmap
820 elseif
(ibmap
.eq
.255) then ! No bitmap in message
823 print
*,'unpack6: Predefined bitmap ',ibmap
,' not recognized.'
827 return ! End of Section
6 processing