NCEPLIBS-g2  3.4.8
addgrid.F90
Go to the documentation of this file.
1 
5 
49 subroutine addgrid(cgrib, lcgrib, igds, igdstmpl, igdstmplen, &
50  ideflist, idefnum, ierr)
51  use gridtemplates
52  implicit none
53 
54  character(len = 1), intent(inout) :: cgrib(lcgrib)
55  integer, intent(in) :: igds(*), igdstmpl(*), ideflist(idefnum)
56  integer, intent(in) :: lcgrib, idefnum, igdstmplen
57  integer, intent(out) :: ierr
58 
59  character(len = 4), parameter :: grib = 'GRIB', c7777 = '7777'
60  character(len = 4):: ctemp
61  integer:: mapgrid(igdstmplen)
62  integer, parameter :: ONE = 1, three = 3
63  integer lensec3, iofst, ibeg, lencurr, len, mapgridlen
64  logical needext
65  integer :: i, ilen, iret, isecnum, nbits
66 
67  ierr = 0
68 
69 #ifdef LOGGING
70  print *, 'addgrid lcgrib ', lcgrib, ' igdstmplen ', igdstmplen, ' idefnum ', idefnum
71 #endif
72 
73  ! Check to see if beginning of GRIB message exists.
74  do i = 1, 4
75  if (cgrib(i) /= grib(i:i)) then
76  print *, 'addgrid: GRIB not found in given message.'
77  print *, 'addgrid: Call to routine gribcreate required', &
78  ' to initialize GRIB messge.'
79 10 format('"', 4a1, '" /= "GRIB"')
80  print 10, cgrib(1:4)
81  ierr = 1
82  return
83  endif
84  enddo
85 
86  ! Get current length of GRIB message.
87  call g2_gbytec(cgrib, lencurr, 96, 32)
88 
89  ! Check to see if GRIB message is already complete.
90  ctemp = cgrib(lencurr - 3) // cgrib(lencurr - 2) // cgrib(lencurr &
91  - 1) // cgrib(lencurr)
92  if (ctemp .eq. c7777) then
93  print *, 'addgrid: GRIB message already complete. Cannot', &
94  ' add new section.'
95  ierr = 2
96  return
97  endif
98 
99  ! Loop through all current sections of the GRIB message to find the
100  ! last section number.
101  len = 16 ! length of Section 0
102  do
103  ! Get length and section number of next section.
104  iofst = len * 8
105  call g2_gbytec(cgrib, ilen, iofst, 32)
106  iofst = iofst + 32
107  call g2_gbytec(cgrib, isecnum, iofst, 8)
108  len = len + ilen
109 
110  ! Exit loop if last section reached.
111  if (len .eq. lencurr) exit
112 
113  ! If byte count for each section doesn't match current
114  ! total length, then there is a problem.
115  if (len .gt. lencurr) then
116  print *, 'addgrid: Section byte counts don''t add to total.'
117  print *, 'addgrid: Sum of section byte counts = ', len
118  print *, 'addgrid: Total byte count in Section 0 = ', lencurr
119  ierr = 3
120  return
121  endif
122  enddo
123 
124  ! Section 3 can only be added after sections 1, 2 and 7.
125  if ((isecnum .ne. 1) .and. (isecnum .ne. 2) .and. &
126  (isecnum .ne. 7)) then
127  print *, 'addgrid: Section 3 can only be added after Section', &
128  ' 1, 2 or 7.'
129  print *, 'addgrid: Section ', isecnum, &
130  ' was the last found in given GRIB message.'
131  ierr = 4
132  return
133  endif
134 
135  ! Add Section 3 - Grid Definition Section.
136  ibeg = lencurr * 8 ! Calculate offset for beginning of section 3
137  iofst = ibeg + 32 ! leave space for length of section
138  call g2_sbytec(cgrib, three, iofst, 8) ! Store section number (3)
139  iofst = iofst + 8
140  call g2_sbytec(cgrib, igds(1), iofst, 8) ! Store source of Grid def.
141  iofst = iofst + 8
142  call g2_sbytec(cgrib, igds(2), iofst, 32) ! Store number of data pts.
143  iofst = iofst + 32
144  call g2_sbytec(cgrib, igds(3), iofst, 8) ! Store number of extra octets.
145  iofst = iofst + 8
146  call g2_sbytec(cgrib, igds(4), iofst, 8) ! Store interp. of extra octets.
147  iofst = iofst + 8
148 
149  ! If Octet 6 is not equal to zero, Grid Definition Template may not
150  ! be supplied.
151  if (igds(1) .eq. 0) then
152  call g2_sbytec(cgrib, igds(5), iofst, 16) ! Store Grid Def Template num.
153  else
154  call g2_sbytec(cgrib, 65535, iofst, 16) ! Store missing value as Grid Def Template num.
155  endif
156  iofst = iofst + 16
157 
158  ! Get Grid Definition Template.
159  if (igds(1) .eq. 0) then
160  call getgridtemplate(igds(5), mapgridlen, mapgrid, needext, &
161  iret)
162  if (iret .ne. 0) then
163  ierr = 5
164  return
165  endif
166 
167  ! Extend the Grid Definition Template, if necessary. The number
168  ! of values in a specific template may vary depending on data
169  ! specified in the "static" part of the template.
170  if (needext) then
171  call extgridtemplate(igds(5), igdstmpl, mapgridlen, &
172  mapgrid)
173  endif
174  else
175  mapgridlen = 0
176  endif
177 
178  ! Pack up each input value in array igdstmpl into the the
179  ! appropriate number of octets, which are specified in corresponding
180  ! entries in array mapgrid.
181  do i = 1, mapgridlen
182  nbits = iabs(mapgrid(i)) * 8
183  if ((mapgrid(i) .ge. 0) .or. (igdstmpl(i) .ge. 0)) then
184  call g2_sbytec(cgrib, igdstmpl(i), iofst, nbits)
185  else
186  call g2_sbytec(cgrib, one, iofst, 1)
187  call g2_sbytec(cgrib, iabs(igdstmpl(i)), iofst + 1, nbits &
188  - 1)
189  endif
190  iofst = iofst + nbits
191  enddo
192 
193  ! If requested, insert optional list of numbers defining number of
194  ! points in each row or column. This is used for non regular grids.
195  if (igds(3) .ne. 0) then
196  nbits = igds(3) * 8
197  call g2_sbytesc(cgrib, ideflist, iofst, nbits, 0, idefnum)
198  iofst = iofst + (nbits * idefnum)
199  endif
200 
201  ! Calculate length of section 3 and store it in octets 1-4 of
202  ! section 3.
203  lensec3 = (iofst - ibeg) / 8
204  call g2_sbytec(cgrib, lensec3, ibeg, 32)
205 
206 
207  ! Update current byte total of message in Section 0.
208  call g2_sbytec(cgrib, lencurr + lensec3, 96, 32)
209 end subroutine addgrid
subroutine addgrid(cgrib, lcgrib, igds, igdstmpl, igdstmplen, ideflist, idefnum, ierr)
Add a Grid Definition Section (Section 3) to a GRIB2 message.
Definition: addgrid.F90:51
subroutine g2_gbytec(in, iout, iskip, nbits)
Extract arbitrary size values from a packed bit string, right justifying each value in the unpacked a...
Definition: g2_gbytesc.F90:20
subroutine g2_sbytec(out, in, iskip, nbits)
Put arbitrary size values into a packed bit string, taking the low order bits from each value in the ...
Definition: g2_gbytesc.F90:42
subroutine g2_sbytesc(out, in, iskip, nbits, nskip, n)
Put arbitrary size values into a packed bit string, taking the low order bits from each value in the ...
Definition: g2_gbytesc.F90:120
This Fortran module contains info on all the available GRIB2 Grid Definition Templates used in [Secti...
subroutine getgridtemplate(number, nummap, map, needext, iret)
Get the grid template information for a specified Grid Definition Template.
subroutine extgridtemplate(number, list, nummap, map)
Generate the remaining octet map for a given Grid Definition Template, if required.