NCEPLIBS-w3emc  2.11.0
w3nogds.f
Go to the documentation of this file.
1 C> @file
2 C> @brief Make a complete grib message
3 C> @author Farley @date 1997-02-24
4 
5 C> Makes a complete grib message from a user supplied
6 C> array of floating point or integer data. The user has the
7 C> option of supplying the pds or an integer array that will be
8 C> used to create a pds (with w3fi68()). The user must also
9 C> supply other necessary info; see usage section below.
10 C>
11 C> ### Program History Log:
12 C> Date | Programmer | Comment
13 C> -----|------------|--------
14 C> 1997-02-24 | M. Farley | Modified w3fi72() - this routine allows for no gds (errors in w3fi71 for grib grids 21-26, 61-64 forced the need for this routine).
15 C> 1998-06-24 | Stephen Gilbert | Added number of gridpoint values for grids 61-64, needed when igflag=2 ( no gds ).
16 C> 1998-12-21 | Stephen Gilbert | Replaced function ichar with mova2i.
17 C>
18 C> @param[in] ITYPE 0 = Floating point data supplied in array 'fld'
19 C> 1 = Data supplied in array 'ifld'
20 C> @param[in] FLD Array of data (at proper gridpoints) to be
21 C> converted to grib format if itype=0.
22 C> see remarks #1 & 2.
23 C> @param[in] IFLD Array of data (at proper gridpoints) to be
24 C> converted to grib format if itype=1.
25 C> see remarks #1 & 2.
26 C> @param[in] IBITL 0 = Computer computes length for packing data from
27 C> power of 2 (number of bits) best fit of data
28 C> using 'variable' bit packer w3fi58.
29 C> 8, 12, etc. computer rescales data to fit into that
30 C> 'fixed' number of bits using w3fi59.
31 C> see remarks #3.
32 C> @param[in] IPFLAG 0 = Make pds from user supplied array (id)
33 C> 1 = user supplying pds
34 C> note: if pds is greater than 30, use iplfag=1.
35 C> the user could call w3fi68 before he calls
36 C> w3nogds. this would make the first 30 bytes of
37 C> the pds, user then would make bytes after 30.
38 C> @param[in] ID Array of values that w3fi68 will use
39 C> to make an edition 1 pds if ipflag=0. (see the
40 C> docblock for w3fi68 for layout of array)
41 C> @param[in] PDS Array of values (valid pds supplied
42 C> by user) if ipflag=1. length may exceed 28 bytes
43 C> (contents of bytes beyond 28 are passed
44 C> through unchanged).
45 C> @param[in] IGFLAG 0 = Make gds based on 'igrid' value.
46 C> 1 = make gds from user supplied info in 'igds' and 'igrid' value. see remarks #4.
47 C> 2 = no gds will be included...for international grids
48 C> *** this is an exception to remarks #4!!!!
49 C> @param[in] IGRID # = Grid identification (table b)
50 C> 255 = if user defined grid; igds must be supplied and igflag must =1.
51 C> @param[in] IGDS Array containing user gds info (same
52 C> format as supplied by w3fi71 - see dockblock for
53 C> layout) if igflag=1.
54 C> @param[in] ICOMP Resolution and component flag for bit 5 of gds(17)
55 C> 0 = earth oriented winds
56 C> 1 = grid oriented winds
57 C> @param[in] IBFLAG 0 = Make bit map from user supplied data
58 C> - # = bit map predefined by center see remarks #5.
59 C> @param[in] IBMAP Array containing bit map
60 C> @param[in] IBLEN Length of bit map will be used to verify length
61 C> of field (error if it doesn't match).
62 C> @param[in] IBDSFL Array containing table 11 flag info
63 C> bds octet 4:
64 C> (1) 0 = grid point data
65 C> 1 = spherical harmonic coefficients
66 C> (2) 0 = simple packing
67 C> 1 = second order packing
68 C> (3) ... same value as 'itype'
69 C> 0 = original data were floating point values
70 C> 1 = original data were integer values
71 C> (4) 0 = no additional flags at octet 14
72 C> 1 = octet 14 contains flag bits 5-12
73 C> (5) 0 = reserved - always set to 0
74 C> byte 6 option 1 not available (as of 5-16-93)
75 C> (6) 0 = single datum at each grid point
76 C> 1 = matrix of values at each grid point
77 C> byte 7 option 0 with second order packing n/a (as of 5-16-93)
78 C> (7) 0 = no secondary bit maps
79 C> 1 = secondary bit maps present
80 C> (8) 0 = second order values have constant width
81 C> 1 = second order values have different widths
82 C> @param[out] NPTS Number of gridpoints in array fld or ifld
83 C> @param[out] KBUF Entire grib message ('grib' to '7777')
84 C> equivalence to integer array to make sure it
85 C> is on word bounary.
86 C> @param[out] ITOT Total length of grib message in bytes
87 C> @param[out] JERR =:
88 C> - 0, Completed making grib field without error
89 C> - 1, Ipflag not 0 or 1
90 C> - 2, Igflag not 0 or 1 or 2
91 C> - 3, Error converting ieee f.p. number to ibm370 f.p.
92 C> - 4, W3fi71 error/igrid not defined
93 C> - 5, W3fk74 error/grid representation type not valid
94 C> - 6, Grid too large for packer dimension arrays
95 C> see automation division for revision!
96 C> - 7, Length of bit map not equal to size of fld/ifld
97 C> - 8, W3fi73 error, all values in ibmap are zero
98 C>
99 C> @remark
100 C> - 1 If bit map to be included in message, null data should
101 C> be included in fld or ifld. this routine will take care
102 C> of 'discarding' any null data based on the bit map.
103 C> - 2 Units must be those in grib documentation: nmc o.n. 388
104 C> or wmo publication 306.
105 C> - 3 In either case, input numbers will be multiplied by
106 C> '10 to the nth' power found in id(25) or pds(27-28),
107 C> the d-scaling factor, prior to binary packing.
108 C> - 4 All nmc produced grib fields will have a grid definition
109 C> section included in the grib message. id(6) will be
110 C> set to '1'.
111 C> - gds will be built based on grid number (igrid), unless
112 C> igflag=1 (user supplying igds). user must still supply
113 C> igrid even if igds provided.
114 C> - 5 If bit map used then id(7) or pds(8) must indicate the
115 C> presence of a bit map.
116 C> - 6 Array kbuf should be equivalenced to an integer value or
117 C> array to make sure it is on a word boundary.
118 C> - 7 Subprogram can be called from a multiprocessing environment.
119 C>
120  SUBROUTINE w3nogds(ITYPE,FLD,IFLD,IBITL,
121  & IPFLAG,ID,PDS,
122  & IGFLAG,IGRID,IGDS,ICOMP,
123  & IBFLAG,IBMAP,IBLEN,IBDSFL,
124  & NPTS,KBUF,ITOT,JERR)
125 C
126  parameter(mxsize=260000)
127 C ALLOW UP TO 24 BITS PER POINT
128  parameter(mxsiz3=mxsize*3)
129  parameter(mxsizb=mxsize/8+6)
130 C FOR 64 BIT CRAY
131  parameter(mxsizi=mxsiz3/8)
132 C FOR 32 BIT WORKSTATIONS AND HDS
133 C PARAMETER (MXSIZI=MXSIZ3/4)
134 C
135  REAL FLD(*)
136 C
137  INTEGER IBDSFL(*)
138  INTEGER IBMAP(*)
139  INTEGER ID(*)
140  INTEGER IFLD(*)
141  INTEGER IGDS(*)
142  INTEGER IPFLD(MXSIZI)
143  INTEGER IB(4)
144 C
145  CHARACTER * 1 BDS11(11)
146  CHARACTER * 1 KBUF(*)
147  CHARACTER * 1 PDS(*)
148  CHARACTER * 1 GDS(200)
149  CHARACTER * 1 BMS(MXSIZB)
150  CHARACTER * 1 PFLD(MXSIZ3)
151  CHARACTER * 1 SEVEN
152  CHARACTER * 1 ZERO
153 C
154  equivalence(ipfld(1),pfld(1))
155  equivalence(bds11(1),idummy)
156 C
157 C ASCII REP OF /'G', 'R', 'I', 'B'/
158 C
159  DATA ib / 71, 82, 73, 66/
160 C
161  ier = 0
162  iberr = 0
163  jerr = 0
164  igribl = 8
165  ipdsl = 0
166  lengds = 0
167  lenbms = 0
168  lenbds = 0
169  itoss = 0
170 C
171 C$ 1.0 PRODUCT DEFINITION SECTION(PDS).
172 C
173 C SET ID(6) TO 1 ...OR... MODIFY PDS(8) ...
174 C REGARDLESS OF USER SPECIFICATION...
175 C NMC GRIB FIELDS WILL ALWAYS HAVE A GDS
176 C ***** exception for international GRIB GRIDS 21-26, 61-64
177 C ***** which will NOT contain a GDS until subroutine W3FI71 is fixed!
178 C
179  IF (ipflag .EQ.0) THEN
180  id(6) = 1
181  if (igflag .eq. 2) then
182  id(6) = 0
183  endif
184  CALL w3fi68(id,pds)
185  ELSE IF (ipflag .EQ. 1) THEN
186  IF (iand(mova2i(pds(8)),64) .EQ. 64) THEN
187 C BOTH GDS AND BMS
188  pds(8) = char(192)
189  ELSE IF (mova2i(pds(8)) .EQ. 0) THEN
190 C GDS ONLY
191  pds(8) = char(128)
192  END IF
193  CONTINUE
194  ELSE
195 C PRINT *,' W3NOGDS ERROR, IPFLAG IS NOT 0 OR 1 IPFLAG = ',IPFLAG
196  jerr = 1
197  GO TO 900
198  END IF
199 C
200 C GET LENGTH OF PDS
201 C
202  ipdsl = mova2i(pds(1)) * 65536 + mova2i(pds(2)) * 256 +
203  & mova2i(pds(3))
204 C
205 C$ 2.0 GRID DEFINITION SECTION (GDS).
206 C
207 C IF IGFLAG=1 THEN USER IS SUPPLYING THE IGDS INFORMATION
208 C IF IGFLAG=2 THEN USER doesn't want a GDS and this section
209 C will be skipped...LENGDS=0
210 C
211  IF (igflag .EQ. 0) THEN
212  CALL w3fi71(igrid,igds,igerr)
213  IF (igerr .EQ. 1) THEN
214 C PRINT *,' W3FI71 ERROR, GRID TYPE NOT DEFINED...',IGRID
215  jerr = 4
216  GO TO 900
217  END IF
218  END IF
219  IF (igflag .EQ. 0 .OR. igflag .EQ.1) THEN
220  CALL w3fi74(igds,icomp,gds,lengds,npts,igerr)
221  IF (igerr .EQ. 1) THEN
222 C PRINT *,' W3FI74 ERROR, GRID REP TYPE NOT VALID...',IGDS(3)
223  jerr = 5
224  GO TO 900
225  ELSE
226  END IF
227  IF (npts .GT. mxsize) THEN
228 C PRINT *,' W3NOGDS ERROR, GRID TOO LARGE FOR PACKER ARRAY',
229 C & ' DIMENSIONS'
230  jerr = 6
231  GO TO 900
232  END IF
233  else if (igflag .eq. 2) then
234  lengds = 0
235  if (igrid.eq.21) then
236  npts=1333
237  else if (igrid.eq.22) then
238  npts=1333
239  else if (igrid.eq.23) then
240  npts=1333
241  else if (igrid.eq.24) then
242  npts=1333
243  else if (igrid.eq.25) then
244  npts=1297
245  else if (igrid.eq.26) then
246  npts=1297
247  else if ((igrid.ge.61).and.(igrid.le.64)) then
248  npts=4096
249  end if
250  ELSE
251 C PRINT *,' W3NOGDS ERROR, IGFLAG IS NOT 0-2 IGFLAG = ',IGFLAG
252  GO TO 900
253  END IF
254 C
255 C$ 3.0 BIT MAP SECTION (BMS).
256 C
257 C SET ITOSS=1 IF BITMAP BEING USED. W3FI75 WILL TOSS DATA
258 C PRIOR TO PACKING. LATER CODING WILL BE NEEDED WHEN THE
259 C 'PREDEFINED' GRIDS ARE FINALLY 'DEFINED'.
260 C
261  IF (mova2i(pds(8)) .EQ. 64 .OR.
262  & mova2i(pds(8)) .EQ. 192) THEN
263  itoss = 1
264  IF (ibflag .EQ. 0) THEN
265  IF (iblen .NE. npts) THEN
266 C PRINT *,' W3NOGDS ERROR, IBLEN .NE. NPTS = ',IBLEN,NPTS
267  jerr = 7
268  GO TO 900
269  END IF
270  CALL w3fi73(ibflag,ibmap,iblen,bms,lenbms,ier)
271  IF (ier .NE. 0) THEN
272 C PRINT *,' W3FI73 ERROR, IBMAP VALUES ARE ALL ZERO'
273  jerr = 8
274  GO TO 900
275  END IF
276  ELSE
277 C PRINT *,' BIT MAP PREDEFINED BY CENTER, IBFLAG = ',IBFLAG
278  END IF
279  END IF
280 C
281 C$ 4.0 BINARY DATA SECTION (BDS).
282 C
283 C$ 4.1 SCALE THE DATA WITH D-SCALE FROM PDS(27-28)
284 C
285  jscale = mova2i(pds(27)) * 256 + mova2i(pds(28))
286  IF (iand(jscale,32768).NE.0) THEN
287  jscale = - iand(jscale,32767)
288  END IF
289  scale = 10.0 ** jscale
290  IF (itype .EQ. 0) THEN
291  DO 410 i = 1,npts
292  fld(i) = fld(i) * scale
293  410 CONTINUE
294  ELSE
295  DO 411 i = 1,npts
296  ifld(i) = nint(float(ifld(i)) * scale)
297  411 CONTINUE
298  END IF
299 C
300 C$ 4.2 CALL W3FI75 TO PACK DATA AND MAKE BDS.
301 C
302  CALL w3fi75(ibitl,itype,itoss,fld,ifld,ibmap,ibdsfl,
303  & npts,bds11,ipfld,pfld,len,lenbds,iberr,pds,igds)
304  IF (iberr .EQ. 1) THEN
305  jerr = 3
306  GO TO 900
307  END IF
308 C 4.3 IF D-SCALE NOT 0, RESCALE INPUT FIELD TO
309 C ORIGINAL VALUE
310 C
311  IF (jscale.NE.0) THEN
312  dscale = 1.0 / scale
313  IF (itype.EQ.0) THEN
314  DO 412 i = 1, npts
315  fld(i) = fld(i) * dscale
316  412 CONTINUE
317  ELSE
318  DO 413 i = 1, npts
319  fld(i) = nint(float(ifld(i)) * dscale)
320  413 CONTINUE
321  END IF
322  END IF
323 C
324 C$ 5.0 OUTPUT SECTION.
325 C
326 C$ 5.1 ZERO OUT THE OUTPUT ARRAY KBUF.
327 C
328  zero = char(00)
329  itot = igribl + ipdsl + lengds + lenbms + lenbds + 4
330 C PRINT *,'IGRIBL =',IGRIBL
331 C PRINT *,'IPDSL =',IPDSL
332 C PRINT *,'LENGDS =',LENGDS
333 C PRINT *,'LENBMS =',LENBMS
334 C PRINT *,'LENBDS =',LENBDS
335 C PRINT *,'ITOT =',ITOT
336 C
337 C KBUF MUST BE ON A WORD BOUNDRY, EQUIVALENCE TO AN
338 C INTEGER ARRAY IN THE MAIN PROGRAM TO MAKE SURE IT IS.
339 C THIS IS BOTH COMPUTER AND COMPILER DEPENDENT, W3FI01
340 C IS USED TO FILL OUT IF THE COMPUTER IS A 64 BIT OR
341 C 32 BIT WORD SIZE COMPUTER. LW IS SET TO 4 FOR 32 BIT
342 C COMPUTER, 8 FOR 64 BIT COMPUTER.
343 C
344  CALL w3fi01(lw)
345  iwords = itot / lw
346  CALL xstore(kbuf,0,iwords)
347  IF (mod(itot,lw).NE.0) THEN
348  ibytes = itot - iwords * lw
349  DO 510 i = 1,ibytes
350  kbuf(iwords * lw + i) = zero
351  510 CONTINUE
352  END IF
353 C
354 C$ 5.2 MOVE SECTION 0 - 'IS' INTO KBUF (8 BYTES).
355 C
356  istart = 0
357  DO 520 i = 1,4
358  kbuf(i) = char(ib(i))
359  520 CONTINUE
360 C
361  kbuf(5) = char(mod(itot / 65536,256))
362  kbuf(6) = char(mod(itot / 256,256))
363  kbuf(7) = char(mod(itot ,256))
364  kbuf(8) = char(1)
365 C
366 C$ 5.3 MOVE SECTION 1 - 'PDS' INTO KBUF (28 BYTES).
367 C
368  istart = istart + igribl
369  IF (ipdsl.GT.0) THEN
370  CALL xmovex(kbuf(istart+1),pds,ipdsl)
371  ELSE
372 C PRINT *,'LENGTH OF PDS LESS OR EQUAL 0, IPDSL = ',IPDSL
373  END IF
374 C
375 C$ 5.4 MOVE SECTION 2 - 'GDS' INTO KBUF.
376 C
377  istart = istart + ipdsl
378  IF (lengds .GT. 0) THEN
379  CALL xmovex(kbuf(istart+1),gds,lengds)
380  END IF
381 C
382 C$ 5.5 MOVE SECTION 3 - 'BMS' INTO KBUF.
383 C
384  istart = istart + lengds
385  IF (lenbms .GT. 0) THEN
386  CALL xmovex(kbuf(istart+1),bms,lenbms)
387  END IF
388 C
389 C$ 5.6 MOVE SECTION 4 - 'BDS' INTO KBUF.
390 C
391 C$ MOVE THE FIRST 11 OCTETS OF THE BDS INTO KBUF.
392 C
393  istart = istart + lenbms
394  CALL xmovex(kbuf(istart+1),bds11,11)
395 C
396 C$ MOVE THE PACKED DATA INTO THE KBUF
397 C
398  istart = istart + 11
399  IF (len.GT.0) THEN
400  CALL xmovex(kbuf(istart+1),pfld,len)
401  END IF
402 C
403 C$ ADD '7777' TO END OFF KBUF
404 C NOTE THAT THESE 4 OCTETS NOT INCLUDED IN ACTUAL SIZE OF BDS.
405 C
406  seven = char(55)
407  istart = itot - 4
408  DO 562 i = 1,4
409  kbuf(istart+i) = seven
410  562 CONTINUE
411 C
412  900 CONTINUE
413  RETURN
414  END
function lengds(KGDS)
Program history log:
Definition: lengds.f:15
integer function mova2i(a)
This Function copies a bit string from a Character*1 variable to an integer variable.
Definition: mova2i.f:25
subroutine w3fi01(LW)
Determines the number of bytes in a full word for the particular machine (IBM or cray).
Definition: w3fi01.f:19
subroutine w3fi68(ID, PDS)
Converts an array of 25, or 27 integer words into a grib product definition section (pds) of 28 bytes...
Definition: w3fi68.f:85
subroutine w3fi71(IGRID, IGDS, IERR)
Makes a 18, 37, 55, 64, or 91 word integer array used by w3fi72() GRIB packer to make the grid descri...
Definition: w3fi71.f:187
subroutine w3fi73(IBFLAG, IBMAP, IBLEN, BMS, LENBMS, IER)
This subroutine constructs a grib bit map section.
Definition: w3fi73.f:23
subroutine w3fi74(IGDS, ICOMP, GDS, LENGDS, NPTS, IGERR)
This subroutine constructs a GRIB grid definition section.
Definition: w3fi74.f:19
subroutine w3fi75(IBITL, ITYPE, ITOSS, FLD, IFLD, IBMAP, IBDSFL, NPTS, BDS11, IPFLD, PFLD, LEN, LENBDS, IBERR, PDS, IGDS)
This routine packs a grib field and forms octets(1-11) of the binary data section (bds).
Definition: w3fi75.f:90
subroutine w3nogds(ITYPE, FLD, IFLD, IBITL, IPFLAG, ID, PDS, IGFLAG, IGRID, IGDS, ICOMP, IBFLAG, IBMAP, IBLEN, IBDSFL, NPTS, KBUF, ITOT, JERR)
Makes a complete grib message from a user supplied array of floating point or integer data.
Definition: w3nogds.f:125
subroutine xmovex(OUT, IN, IBYTES)
Definition: xmovex.f:21
subroutine xstore(COUT, CON, MWORDS)
Stores an 8-byte (fullword) value through consecutive storage locations.
Definition: xstore.f:29