1 | subroutine addgrid(cgrib,lcgrib,igds,igdstmpl,igdstmplen, |
---|
2 | & ideflist,idefnum,ierr) |
---|
3 | !$$$ SUBPROGRAM DOCUMENTATION BLOCK |
---|
4 | ! . . . . |
---|
5 | ! SUBPROGRAM: addgrid |
---|
6 | ! PRGMMR: Gilbert ORG: W/NP11 DATE: 2000-05-01 |
---|
7 | ! |
---|
8 | ! ABSTRACT: This subroutine packs up a Grid Definition Section (Section 3) |
---|
9 | ! and adds it to a GRIB2 message. |
---|
10 | ! This routine is used with routines "gribcreate", "addlocal", "addfield", |
---|
11 | ! and "gribend" to create a complete GRIB2 message. Subroutine |
---|
12 | ! gribcreate must be called first to initialize a new GRIB2 message. |
---|
13 | ! |
---|
14 | ! PROGRAM HISTORY LOG: |
---|
15 | ! 2000-05-01 Gilbert |
---|
16 | ! |
---|
17 | ! USAGE: CALL addgrid(cgrib,lcgrib,igds,igdstmpl,igdstmplen, |
---|
18 | ! ideflist,idefnum,ierr) |
---|
19 | ! INPUT ARGUMENT LIST: |
---|
20 | ! cgrib - Character array to contain the GRIB2 message |
---|
21 | ! lcgrib - Maximum length (bytes) of array cgrib. |
---|
22 | ! igds - Contains information needed for GRIB Grid Definition Section 3. |
---|
23 | ! Must be dimensioned >= 5. |
---|
24 | ! igds(1)=Source of grid definition (see Code Table 3.0) |
---|
25 | ! igds(2)=Number of grid points in the defined grid. |
---|
26 | ! igds(3)=Number of octets needed for each |
---|
27 | ! additional grid points definition. |
---|
28 | ! Used to define number of |
---|
29 | ! points in each row ( or column ) for |
---|
30 | ! non-regular grids. |
---|
31 | ! = 0, if using regular grid. |
---|
32 | ! igds(4)=Interpretation of list for optional points |
---|
33 | ! definition. (Code Table 3.11) |
---|
34 | ! igds(5)=Grid Definition Template Number (Code Table 3.1) |
---|
35 | ! igdstmpl - Contains the data values for the specified Grid Definition |
---|
36 | ! Template ( NN=igds(5) ). Each element of this integer |
---|
37 | ! array contains an entry (in the order specified) of Grid |
---|
38 | ! Defintion Template 3.NN |
---|
39 | ! igdstmplen - Max dimension of igdstmpl() |
---|
40 | ! ideflist - (Used if igds(3) .ne. 0) This array contains the |
---|
41 | ! number of grid points contained in each row ( or column ) |
---|
42 | ! idefnum - (Used if igds(3) .ne. 0) The number of entries |
---|
43 | ! in array ideflist. i.e. number of rows ( or columns ) |
---|
44 | ! for which optional grid points are defined. |
---|
45 | ! |
---|
46 | ! OUTPUT ARGUMENT LIST: |
---|
47 | ! cgrib - Character array to contain the GRIB2 message |
---|
48 | ! ierr - Error return code. |
---|
49 | ! 0 = no error |
---|
50 | ! 1 = GRIB message was not initialized. Need to call |
---|
51 | ! routine gribcreate first. |
---|
52 | ! 2 = GRIB message already complete. Cannot add new section. |
---|
53 | ! 3 = Sum of Section byte counts doesn't add to total byte count. |
---|
54 | ! 4 = Previous Section was not 1, 2 or 7. |
---|
55 | ! 5 = Could not find requested Grid Definition Template. |
---|
56 | ! |
---|
57 | ! REMARKS: Note that the Local Use Section ( Section 2 ) can only follow |
---|
58 | ! Section 1 or Section 7 in a GRIB2 message. |
---|
59 | ! |
---|
60 | ! ATTRIBUTES: |
---|
61 | ! LANGUAGE: Fortran 90 |
---|
62 | ! MACHINE: IBM SP |
---|
63 | ! |
---|
64 | !$$$ |
---|
65 | |
---|
66 | use gridtemplates |
---|
67 | |
---|
68 | character(len=1),intent(inout) :: cgrib(lcgrib) |
---|
69 | integer,intent(in) :: igds(*),igdstmpl(*),ideflist(idefnum) |
---|
70 | integer,intent(in) :: lcgrib,idefnum,igdstmplen |
---|
71 | integer,intent(out) :: ierr |
---|
72 | |
---|
73 | character(len=4),parameter :: grib='GRIB',c7777='7777' |
---|
74 | character(len=4):: ctemp |
---|
75 | integer:: mapgrid(igdstmplen) |
---|
76 | integer,parameter :: one=1,three=3 |
---|
77 | integer lensec3,iofst,ibeg,lencurr,len,mapgridlen |
---|
78 | logical needext |
---|
79 | |
---|
80 | ierr=0 |
---|
81 | ! |
---|
82 | ! Check to see if beginning of GRIB message exists |
---|
83 | ! |
---|
84 | ctemp=cgrib(1)//cgrib(2)//cgrib(3)//cgrib(4) |
---|
85 | if ( ctemp.ne.grib ) then |
---|
86 | print *,'addgrid: GRIB not found in given message.' |
---|
87 | print *,'addgrid: Call to routine gribcreate required', |
---|
88 | & ' to initialize GRIB messge.' |
---|
89 | ierr=1 |
---|
90 | return |
---|
91 | endif |
---|
92 | ! |
---|
93 | ! Get current length of GRIB message |
---|
94 | ! |
---|
95 | call g2lib_gbyte(cgrib,lencurr,96,32) |
---|
96 | ! |
---|
97 | ! Check to see if GRIB message is already complete |
---|
98 | ! |
---|
99 | ctemp=cgrib(lencurr-3)//cgrib(lencurr-2)//cgrib(lencurr-1) |
---|
100 | & //cgrib(lencurr) |
---|
101 | if ( ctemp.eq.c7777 ) then |
---|
102 | print *,'addgrid: GRIB message already complete. Cannot', |
---|
103 | & ' add new section.' |
---|
104 | ierr=2 |
---|
105 | return |
---|
106 | endif |
---|
107 | ! |
---|
108 | ! Loop through all current sections of the GRIB message to |
---|
109 | ! find the last section number. |
---|
110 | ! |
---|
111 | len=16 ! length of Section 0 |
---|
112 | do |
---|
113 | ! Get section number and length of next section |
---|
114 | iofst=len*8 |
---|
115 | call g2lib_gbyte(cgrib,ilen,iofst,32) |
---|
116 | iofst=iofst+32 |
---|
117 | call g2lib_gbyte(cgrib,isecnum,iofst,8) |
---|
118 | len=len+ilen |
---|
119 | ! Exit loop if last section reached |
---|
120 | if ( len.eq.lencurr ) exit |
---|
121 | ! If byte count for each section doesn't match current |
---|
122 | ! total length, then there is a problem. |
---|
123 | if ( len.gt.lencurr ) then |
---|
124 | print *,'addgrid: Section byte counts don''t add to total.' |
---|
125 | print *,'addgrid: Sum of section byte counts = ',len |
---|
126 | print *,'addgrid: Total byte count in Section 0 = ',lencurr |
---|
127 | ierr=3 |
---|
128 | return |
---|
129 | endif |
---|
130 | enddo |
---|
131 | ! |
---|
132 | ! Section 3 can only be added after sections 1, 2 and 7. |
---|
133 | ! |
---|
134 | if ( (isecnum.ne.1) .and. (isecnum.ne.2) .and. |
---|
135 | & (isecnum.ne.7) ) then |
---|
136 | print *,'addgrid: Section 3 can only be added after Section', |
---|
137 | & ' 1, 2 or 7.' |
---|
138 | print *,'addgrid: Section ',isecnum,' was the last found in', |
---|
139 | & ' given GRIB message.' |
---|
140 | ierr=4 |
---|
141 | return |
---|
142 | endif |
---|
143 | ! |
---|
144 | ! Add Section 3 - Grid Definition Section |
---|
145 | ! |
---|
146 | ibeg=lencurr*8 ! Calculate offset for beginning of section 3 |
---|
147 | iofst=ibeg+32 ! leave space for length of section |
---|
148 | call g2lib_sbyte(cgrib,three,iofst,8) ! Store section number ( 3 ) |
---|
149 | iofst=iofst+8 |
---|
150 | call g2lib_sbyte(cgrib,igds(1),iofst,8) ! Store source of Grid def. |
---|
151 | iofst=iofst+8 |
---|
152 | call g2lib_sbyte(cgrib,igds(2),iofst,32) ! Store number of data pts. |
---|
153 | iofst=iofst+32 |
---|
154 | call g2lib_sbyte(cgrib,igds(3),iofst,8) ! Store number of extra octets. |
---|
155 | iofst=iofst+8 |
---|
156 | call g2lib_sbyte(cgrib,igds(4),iofst,8) ! Store interp. of extra octets. |
---|
157 | iofst=iofst+8 |
---|
158 | ! if Octet 6 is not equal to zero, Grid Definition Template may |
---|
159 | ! not be supplied. |
---|
160 | if ( igds(1).eq.0 ) then |
---|
161 | call g2lib_sbyte(cgrib,igds(5),iofst,16) ! Store Grid Def Template num. |
---|
162 | else |
---|
163 | call g2lib_sbyte(cgrib,65535,iofst,16) ! Store missing value as Grid Def Template num. |
---|
164 | endif |
---|
165 | iofst=iofst+16 |
---|
166 | ! |
---|
167 | ! Get Grid Definition Template |
---|
168 | ! |
---|
169 | if (igds(1).eq.0) then |
---|
170 | call getgridtemplate(igds(5),mapgridlen,mapgrid,needext, |
---|
171 | & iret) |
---|
172 | if (iret.ne.0) then |
---|
173 | ierr=5 |
---|
174 | return |
---|
175 | endif |
---|
176 | ! |
---|
177 | ! Extend the Grid Definition Template, if necessary. |
---|
178 | ! The number of values in a specific template may vary |
---|
179 | ! depending on data specified in the "static" part of the |
---|
180 | ! template. |
---|
181 | ! |
---|
182 | if ( needext ) then |
---|
183 | call extgridtemplate(igds(5),igdstmpl,mapgridlen,mapgrid) |
---|
184 | endif |
---|
185 | else |
---|
186 | mapgridlen=0 |
---|
187 | endif |
---|
188 | ! |
---|
189 | ! Pack up each input value in array igdstmpl into the |
---|
190 | ! the appropriate number of octets, which are specified in |
---|
191 | ! corresponding entries in array mapgrid. |
---|
192 | ! |
---|
193 | do i=1,mapgridlen |
---|
194 | nbits=iabs(mapgrid(i))*8 |
---|
195 | if ( (mapgrid(i).ge.0).or.(igdstmpl(i).ge.0) ) then |
---|
196 | call g2lib_sbyte(cgrib,igdstmpl(i),iofst,nbits) |
---|
197 | else |
---|
198 | call g2lib_sbyte(cgrib,one,iofst,1) |
---|
199 | call g2lib_sbyte(cgrib,iabs(igdstmpl(i)),iofst+1,nbits-1) |
---|
200 | endif |
---|
201 | iofst=iofst+nbits |
---|
202 | enddo |
---|
203 | ! |
---|
204 | ! If requested, |
---|
205 | ! Insert optional list of numbers defining number of points |
---|
206 | ! in each row or column. This is used for non regular |
---|
207 | ! grids. |
---|
208 | ! |
---|
209 | if ( igds(3).ne.0 ) then |
---|
210 | nbits=igds(3)*8 |
---|
211 | call g2lib_sbytes(cgrib,ideflist,iofst,nbits,0,idefnum) |
---|
212 | iofst=iofst+(nbits*idefnum) |
---|
213 | endif |
---|
214 | ! |
---|
215 | ! Calculate length of section 3 and store it in octets |
---|
216 | ! 1-4 of section 3. |
---|
217 | ! |
---|
218 | lensec3=(iofst-ibeg)/8 |
---|
219 | call g2lib_sbyte(cgrib,lensec3,ibeg,32) |
---|
220 | |
---|
221 | ! |
---|
222 | ! Update current byte total of message in Section 0 |
---|
223 | ! |
---|
224 | call g2lib_sbyte(cgrib,lencurr+lensec3,96,32) |
---|
225 | |
---|
226 | return |
---|
227 | end |
---|
228 | |
---|