NCEPLIBS-w3emc  2.9.3
w3fi72.f
Go to the documentation of this file.
1 C> @file
2 C> @brief Make a complete grib message
3 C> @author Ralph Jones @date 1991-05-08
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> - Ralph Jones 1991-05-08
13 C> - M. Farley 1992-07-01 Added gds and bms logic. Placed existing
14 C> logic for bds in a routine.
15 C> - Ralph Jones 1992-10-02 Add error exit for w3fi73()
16 C> - Ralph Jones 1993-04-30 Replace do loops to move character data
17 C> with xmovex, use xstore to zero character
18 C> array. make change so flat field will pack.
19 C> - Bill Cavanaugh 1993-08-06 Modified call to w3fi75
20 C> - Bill Cavanaugh 1993-10-26 Added code to restore input field to original
21 C> values if d-scale not 0
22 C> - Bill Cavanaugh 1994-01-27 Added igds array in call to w3fi75 to provide
23 C> information for boustrophedonic processing
24 C> - Bill Cavanaugh 1994-03-03 Increased size of gds array for thin grids
25 C> - M. Farley 1994-05-16 Cleaned up documentation
26 C> - M. Farley 1994-11-10 Increased size of pfld/ifld arrarys from
27 C> 100k to 260k for .5 degree sst anal fields
28 C> - Ralph Jones 1994-12-04 Change document for ipflag.
29 C> - Mark Iredell 1995-10-31 Removed saves and prints
30 C> - Stephen Gilbert 1998-05-19 Increased array dimensions to handle grids
31 C> of up to 500,000 grid points.
32 C> - Mark Iredell 1995-10-31 Generalized word size
33 C> - Stephen Gilbert 1998-12-21 Replaced Function ICHAR with mova2i.
34 C> - Stephen Gilbert 1999-02-01 Changed the method of zeroing out array KBUF.
35 C> the old method, using W3FI01() and XSTORE() was
36 C> incorrect with 4-byte integers and 8-byte reals.
37 C> - Stephen Gilbert 2001-06-07 Removed calls to xmovex.
38 C> changed IPFLD from integer to character.
39 C> - George Gayno 2010-02-19 Fix allocation of array bms
40 C>
41 C> @param[in] ITYPE
42 C> - 0 = Floating point data supplied in array 'fld'
43 C> - 1 = Integer data supplied in array 'ifld'
44 C> @param[in] FLD Real array of data (at proper gridpoints) to be
45 C> converted to grib format if itype=0.
46 C> see remarks #1 & 2.
47 C> @param[in] IFLD Integer array of data (at proper gridpoints) to be
48 C> converted to grib format if itype=1. See remarks #1 & 2.
49 C> @param[in] IBITL
50 C> - 0 = Computer computes length for packing data from
51 C> power of 2 (number of bits) best fit of data
52 C> using 'variable' bit packer w3fi58().
53 C> - 8, 12, Etc. computer rescales data to fit into that
54 C> 'fixed' number of bits using w3fi59(). See remarks #3.
55 C> @param[in] IPFLAG
56 C> - 0 = Make pds from user supplied array (id)
57 C> - 1 = User supplying pds
58 C> @note If pds is greater than 30, use iplfag=1. The user could call w3fi68()
59 C> before he calls w3fi72(). This would make the first 30 bytes of the pds,
60 C> user then would make bytes after 30.
61 C> @param[in] ID Integer array of values that w3fi68() will use
62 C> to make an edition 1 pds if ipflag=0. (see the
63 C> docblock for w3fi68() for layout of array)
64 C> @param[in] PDS Character array of values (valid pds supplied
65 C> by user) if ipflag=1. length may exceed 28 bytes
66 C> (contents of bytes beyond 28 are passed
67 C> through unchanged).
68 C> @param[in] IGFLAG
69 C> - 0 = Make gds based on 'igrid' value.
70 C> - 1 = Make gds from user supplied info in 'igds' and 'igrid' value.
71 C> See remarks #4.
72 C> @param[in] IGRID
73 C> - # = Grid identification (table b)
74 C> - 255 = If user defined grid; igds must be supplied and igflag must =1.
75 C> @param[in] IGDS Integer array containing user gds info (same
76 C> format as supplied by w3fi71() - see dockblock for
77 C> layout) if igflag=1.
78 C> @param[in] ICOMP Resolution and component flag for bit 5 of gds(17)
79 C> - 0 = Earth oriented winds
80 C> - 1 = Grid oriented winds
81 C> @param[in] IBFLAG
82 C> - 0 = Make bit map from user supplied data
83 C> - # = Bit map predefined by center. See remarks #5.
84 C> @param[in] IBMAP Integer array containing bit map
85 C> @param[in] IBLEN Length of bit map will be used to verify length
86 C> of field (error if it doesn't match).
87 C> @param[in] IBDSFL Integer array containing table 11 flag info
88 C> - BDS octet 4:
89 C> - (1)
90 C> - 0 = Grid point data
91 C> - 1 = Spherical harmonic coefficients
92 C> - (2) 0 = Simple packing
93 C> - 1 = Second order packing
94 C> - (3) ... Same value as 'itype'
95 C> - 0 = Original data were floating point values
96 C> - 1 = Original data were integer values
97 C> - (4) 0 = No additional flags at octet 14
98 C> - 1 = Octet 14 contains flag bits 5-12
99 C> - (5) 0 = Reserved - always set to 0
100 C> Byte 6 option 1 not available (as of 5-16-93)
101 C> - (6) 0 = Single datum at each grid point
102 C> - 1 = Matrix of values at each grid point
103 C> Byte 7 option 0 with second order packing n/a (as of 5-16-93)
104 C> - (7) 0 = No secondary bit maps
105 C> - 1 = Secondary bit maps present
106 C> - (8) 0 = Second order values have constant width
107 C> - 1 = Second order values have different widths
108 C> @param[out] NPTS Number of gridpoints in array fld or ifld
109 C> @param[out] KBUF Entire grib message ('grib' to '7777')
110 C> equivalence to integer array to make sure it is on word boundary.
111 C> @param[out] ITOT Total length of grib message in bytes
112 C> @param[out] JERR
113 C> - = 0, Completed making grib field without error
114 C> - = 1, Ipflag not 0 or 1
115 C> - = 2, Igflag not 0 or 1
116 C> - = 3, Error converting ieee f.p. number to ibm370 f.p.
117 C> - = 4, W3fi71() error/igrid not defined
118 C> - = 5, W3fk74() error/grid representation type not valid
119 C> - = 6, Grid too large for packer dimension arrays
120 C> - = See automation division for revision!
121 C> - = 7, Length of bit map not equal to size of fld/ifld
122 C> - = 8, W3fi73() error, all values in ibmap are zero
123 C>
124 C> @note
125 C> - 1: If bit map to be included in message, null data should
126 C> be included in fld or ifld. this routine will take care
127 C> of 'discarding' any null data based on the bit map.
128 C> - 2: Units must be those in grib documentation: nmc o.n. 388
129 C> or wmo publication 306.
130 C> - 3: In either case, input numbers will be multiplied by
131 C> '10 to the nth' power found in id(25) or pds(27-28),
132 C> the d-scaling factor, prior to binary packing.
133 C> - 4: All nmc produced grib fields will have a grid definition
134 C> section included in the grib message. id(6) will be
135 C> set to '1'.
136 C> - GDS will be built based on grid number (igrid), unless
137 C> igflag=1 (user supplying igds). user must still supply
138 C> igrid even if igds provided.
139 C> - 5: if bit map used then id(7) or pds(8) must indicate the
140 C> presence of a bit map.
141 C> - 6: Array kbuf should be equivalenced to an integer value or
142 C> array to make sure it is on a word boundary.
143 C> - 7: Subprogram can be called from a multiprocessing environment.
144 C>
145 C> @author Ralph Jones @date 1991-05-08
146  SUBROUTINE w3fi72(ITYPE,FLD,IFLD,IBITL,
147  & IPFLAG,ID,PDS,
148  & IGFLAG,IGRID,IGDS,ICOMP,
149  & IBFLAG,IBMAP,IBLEN,IBDSFL,
150  & NPTS,KBUF,ITOT,JERR)
151 C
152  REAL FLD(*)
153 C
154  INTEGER IBDSFL(*)
155  INTEGER IBMAP(*)
156  INTEGER ID(*)
157  INTEGER IFLD(*)
158  INTEGER IGDS(*)
159  INTEGER IB(4)
160  INTEGER NLEFT, NUMBMS
161 C
162  CHARACTER * 1 BDS11(11)
163  CHARACTER * 1 KBUF(*)
164  CHARACTER * 1 PDS(*)
165  CHARACTER * 1 GDS(200)
166  CHARACTER(1),ALLOCATABLE:: BMS(:)
167  CHARACTER(1),ALLOCATABLE:: PFLD(:)
168  CHARACTER(1),ALLOCATABLE:: IPFLD(:)
169  CHARACTER * 1 SEVEN
170  CHARACTER * 1 ZERO
171 C
172 C
173 C ASCII REP OF /'G', 'R', 'I', 'B'/
174 C
175  DATA ib / 71, 82, 73, 66/
176 C
177  ier = 0
178  iberr = 0
179  jerr = 0
180  igribl = 8
181  ipdsl = 0
182  lengds = 0
183  lenbms = 0
184  lenbds = 0
185  itoss = 0
186 C
187 C$ 1.0 PRODUCT DEFINITION SECTION(PDS).
188 C
189 C SET ID(6) TO 1 ...OR... MODIFY PDS(8) ...
190 C REGARDLESS OF USER SPECIFICATION...
191 C NMC GRIB FIELDS WILL ALWAYS HAVE A GDS
192 C
193  IF (ipflag .EQ.0) THEN
194  id(6) = 1
195  CALL w3fi68(id,pds)
196  ELSE IF (ipflag .EQ. 1) THEN
197  IF (iand(mova2i(pds(8)),64) .EQ. 64) THEN
198 C BOTH GDS AND BMS
199  pds(8) = char(192)
200  ELSE IF (mova2i(pds(8)) .EQ. 0) THEN
201 C GDS ONLY
202  pds(8) = char(128)
203  END IF
204  CONTINUE
205  ELSE
206 C PRINT *,' W3FI72 ERROR, IPFLAG IS NOT 0 OR 1 IPFLAG = ',IPFLAG
207  jerr = 1
208  GO TO 900
209  END IF
210 C
211 C GET LENGTH OF PDS
212 C
213  ipdsl = mova2i(pds(1)) * 65536 + mova2i(pds(2)) * 256 +
214  & mova2i(pds(3))
215 C
216 C$ 2.0 GRID DEFINITION SECTION (GDS).
217 C
218 C IF IGFLAG=1 THEN USER IS SUPPLYING THE IGDS INFORMATION
219 C
220  IF (igflag .EQ. 0) THEN
221  CALL w3fi71(igrid,igds,igerr)
222  IF (igerr .EQ. 1) THEN
223 C PRINT *,' W3FI71 ERROR, GRID TYPE NOT DEFINED...',IGRID
224  jerr = 4
225  GO TO 900
226  END IF
227  END IF
228  IF (igflag .EQ. 0 .OR. igflag .EQ.1) THEN
229  CALL w3fi74(igds,icomp,gds,lengds,npts,igerr)
230  IF (igerr .EQ. 1) THEN
231 C PRINT *,' W3FI74 ERROR, GRID REP TYPE NOT VALID...',IGDS(3)
232  jerr = 5
233  GO TO 900
234  ELSE
235  END IF
236  ELSE
237 C PRINT *,' W3FI72 ERROR, IGFLAG IS NOT 0 OR 1 IGFLAG = ',IGFLAG
238  jerr = 2
239  GO TO 900
240  END IF
241 C
242 C$ 3.0 BIT MAP SECTION (BMS).
243 C
244 C SET ITOSS=1 IF BITMAP BEING USED. W3FI75 WILL TOSS DATA
245 C PRIOR TO PACKING. LATER CODING WILL BE NEEDED WHEN THE
246 C 'PREDEFINED' GRIDS ARE FINALLY 'DEFINED'.
247 C
248  IF (mova2i(pds(8)) .EQ. 64 .OR.
249  & mova2i(pds(8)) .EQ. 192) THEN
250  itoss = 1
251  IF (ibflag .EQ. 0) THEN
252  IF (iblen .NE. npts) THEN
253 C PRINT *,' W3FI72 ERROR, IBLEN .NE. NPTS = ',IBLEN,NPTS
254  jerr = 7
255  GO TO 900
256  END IF
257  IF (mod(iblen,16).NE.0) THEN
258  nleft = 16 - mod(iblen,16)
259  ELSE
260  nleft = 0
261  END IF
262  numbms = 6 + (iblen+nleft) / 8
263  ALLOCATE(bms(numbms))
264  zero = char(00)
265  bms = zero
266  CALL w3fi73(ibflag,ibmap,iblen,bms,lenbms,ier)
267  IF (ier .NE. 0) THEN
268 C PRINT *,' W3FI73 ERROR, IBMAP VALUES ARE ALL ZERO'
269  jerr = 8
270  GO TO 900
271  END IF
272  ELSE
273 C PRINT *,' BIT MAP PREDEFINED BY CENTER, IBFLAG = ',IBFLAG
274  END IF
275  END IF
276 C
277 C$ 4.0 BINARY DATA SECTION (BDS).
278 C
279 C$ 4.1 SCALE THE DATA WITH D-SCALE FROM PDS(27-28)
280 C
281  jscale = mova2i(pds(27)) * 256 + mova2i(pds(28))
282  IF (iand(jscale,32768).NE.0) THEN
283  jscale = - iand(jscale,32767)
284  END IF
285  scale = 10.0 ** jscale
286  IF (itype .EQ. 0) THEN
287  DO 410 i = 1,npts
288  fld(i) = fld(i) * scale
289  410 CONTINUE
290  ELSE
291  DO 411 i = 1,npts
292  ifld(i) = nint(float(ifld(i)) * scale)
293  411 CONTINUE
294  END IF
295 C
296 C$ 4.2 CALL W3FI75 TO PACK DATA AND MAKE BDS.
297 C
298  ALLOCATE(pfld(npts*4))
299 C
300  IF(ibdsfl(2).NE.0) THEN
301  ALLOCATE(ipfld(npts*4))
302  ipfld=char(0)
303  ELSE
304  ALLOCATE(ipfld(1))
305  ENDIF
306 C
307  CALL w3fi75(ibitl,itype,itoss,fld,ifld,ibmap,ibdsfl,
308  & npts,bds11,ipfld,pfld,len,lenbds,iberr,pds,igds)
309 C
310  IF(ibdsfl(2).NE.0) THEN
311 C CALL XMOVEX(PFLD,IPFLD,NPTS*4)
312  do ii = 1, npts*4
313  pfld(ii) = ipfld(ii)
314  enddo
315  ENDIF
316  DEALLOCATE(ipfld)
317 C
318  IF (iberr .EQ. 1) THEN
319  jerr = 3
320  GO TO 900
321  END IF
322 C 4.3 IF D-SCALE NOT 0, RESCALE INPUT FIELD TO
323 C ORIGINAL VALUE
324 C
325  IF (jscale.NE.0) THEN
326  dscale = 1.0 / scale
327  IF (itype.EQ.0) THEN
328  DO 412 i = 1, npts
329  fld(i) = fld(i) * dscale
330  412 CONTINUE
331  ELSE
332  DO 413 i = 1, npts
333  fld(i) = nint(float(ifld(i)) * dscale)
334  413 CONTINUE
335  END IF
336  END IF
337 C
338 C$ 5.0 OUTPUT SECTION.
339 C
340 C$ 5.1 ZERO OUT THE OUTPUT ARRAY KBUF.
341 C
342  zero = char(00)
343  itot = igribl + ipdsl + lengds + lenbms + lenbds + 4
344 C PRINT *,'IGRIBL =',IGRIBL
345 C PRINT *,'IPDSL =',IPDSL
346 C PRINT *,'LENGDS =',LENGDS
347 C PRINT *,'LENBMS =',LENBMS
348 C PRINT *,'LENBDS =',LENBDS
349 C PRINT *,'ITOT =',ITOT
350  kbuf(1:itot)=zero
351 C
352 C$ 5.2 MOVE SECTION 0 - 'IS' INTO KBUF (8 BYTES).
353 C
354  istart = 0
355  DO 520 i = 1,4
356  kbuf(i) = char(ib(i))
357  520 CONTINUE
358 C
359  kbuf(5) = char(mod(itot / 65536,256))
360  kbuf(6) = char(mod(itot / 256,256))
361  kbuf(7) = char(mod(itot ,256))
362  kbuf(8) = char(1)
363 C
364 C$ 5.3 MOVE SECTION 1 - 'PDS' INTO KBUF (28 BYTES).
365 C
366  istart = istart + igribl
367  IF (ipdsl.GT.0) THEN
368 C CALL XMOVEX(KBUF(ISTART+1),PDS,IPDSL)
369  do ii = 1, ipdsl
370  kbuf(istart+ii) = pds(ii)
371  enddo
372  ELSE
373 C PRINT *,'LENGTH OF PDS LESS OR EQUAL 0, IPDSL = ',IPDSL
374  END IF
375 C
376 C$ 5.4 MOVE SECTION 2 - 'GDS' INTO KBUF.
377 C
378  istart = istart + ipdsl
379  IF (lengds .GT. 0) THEN
380 C CALL XMOVEX(KBUF(ISTART+1),GDS,LENGDS)
381  do ii = 1, lengds
382  kbuf(istart+ii) = gds(ii)
383  enddo
384  END IF
385 C
386 C$ 5.5 MOVE SECTION 3 - 'BMS' INTO KBUF.
387 C
388  istart = istart + lengds
389  IF (lenbms .GT. 0) THEN
390 C CALL XMOVEX(KBUF(ISTART+1),BMS,LENBMS)
391  do ii = 1, lenbms
392  kbuf(istart+ii) = bms(ii)
393  enddo
394  END IF
395 C
396 C$ 5.6 MOVE SECTION 4 - 'BDS' INTO KBUF.
397 C
398 C$ MOVE THE FIRST 11 OCTETS OF THE BDS INTO KBUF.
399 C
400  istart = istart + lenbms
401 C CALL XMOVEX(KBUF(ISTART+1),BDS11,11)
402  do ii = 1, 11
403  kbuf(istart+ii) = bds11(ii)
404  enddo
405 C
406 C$ MOVE THE PACKED DATA INTO THE KBUF
407 C
408  istart = istart + 11
409  IF (len.GT.0) THEN
410 C CALL XMOVEX(KBUF(ISTART+1),PFLD,LEN)
411  do ii = 1, len
412  kbuf(istart+ii) = pfld(ii)
413  enddo
414  END IF
415 C
416 C$ ADD '7777' TO END OFF KBUF
417 C NOTE THAT THESE 4 OCTETS NOT INCLUDED IN ACTUAL SIZE OF BDS.
418 C
419  seven = char(55)
420  istart = itot - 4
421  DO 562 i = 1,4
422  kbuf(istart+i) = seven
423  562 CONTINUE
424 C
425  900 CONTINUE
426  IF(ALLOCATED(bms)) DEALLOCATE(bms)
427  IF(ALLOCATED(pfld)) DEALLOCATE(pfld)
428  RETURN
429  END
mova2i
integer function mova2i(a)
This Function copies a bit string from a Character*1 variable to an integer variable.
Definition: mova2i.f:25
lengds
function lengds(KGDS)
Program history log:
Definition: lengds.f:15
w3fi73
subroutine w3fi73(IBFLAG, IBMAP, IBLEN, BMS, LENBMS, IER)
This subroutine constructs a grib bit map section.
Definition: w3fi73.f:23
w3fi75
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
w3fi74
subroutine w3fi74(IGDS, ICOMP, GDS, LENGDS, NPTS, IGERR)
This subroutine constructs a grib grid definition section.
Definition: w3fi74.f:34
w3fi72
subroutine w3fi72(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: w3fi72.f:151
w3fi68
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
w3fi71
subroutine w3fi71(IGRID, IGDS, IERR)
W3FI71 Makes a 18, 37, 55, 64, or 91 word integer array used by w3fi72() grib packer to make the grid...
Definition: w3fi71.f:293