NCEPLIBS-w3emc  2.11.0
w3fi75.f
Go to the documentation of this file.
1 C> @file
2 C> @brief GRIB pack data and form bds octets(1-11)
3 C> @author M. Farley @date 1992-07-10
4 
5 C> This routine packs a grib field and forms octets(1-11)
6 C> of the binary data section (bds).
7 C>
8 C> Program history log:
9 C> - M. Farley 1992-07-10 Original author
10 C> - Ralph Jones 1992-10-01 Correction for field of constant data
11 C> - Ralph Jones 1992-10-16 Get rid of arrays fp and int
12 C> - Bill Cavanaugh 1993-08-06 Added routines fi7501, fi7502, fi7503
13 C> To allow second order packing in pds.
14 C> - John Stackpole 1993-07-21 Assorted repairs to get 2nd diff pack in
15 C> - Bill Cavanaugh 1993-10-28 Commented out nonoperational prints and
16 C> Write statements
17 C> - Bill Cavanaugh 1993-12-15 Corrected location of start of first order
18 C> Values and start of second order values to
19 C> Reflect a byte location in the bds instead
20 C> Of an offset in subroutine fi7501().
21 C> - Bill Cavanaugh 1994-01-27 Added igds as input argument to this routine
22 C> And added pds and igds arrays to the call to
23 C> W3fi82 to provide information needed for
24 C> Boustrophedonic processing.
25 C> - Bill Cavanaugh 1994-05-25 Subroutine fi7503 has been added to provide
26 C> For row by row or column by column second
27 C> Order packing. this feature can be activated
28 C> By setting ibdsfl(7) to zero.
29 C> - Bill Cavanaugh 1994-07-08 Commented out print statements used for debug
30 C> - M. Farley 1994-11-22 Enlarged work arrays to handle .5degree grids
31 C> - Ralph Jones 1995-06-01 Correction for number of unused bits at end
32 C> Of section 4, in bds byte 4, bits 5-8.
33 C> - Mark Iredell 1995-10-31 Removed saves and prints
34 C> - Stephen Gilbert 2001-06-06 Changed gbyte/sbyte calls to refer to
35 C> Wesley ebisuzaki's endian independent
36 C> versions gbytec/sbytec.
37 C> Use f90 standard routine bit_size to get
38 C> number of bits in an integer instead of w3fi01.
39 C>
40 C> @param[in] IBITL
41 C> - 0, computer computes packing length from power of 2 that best fits the data.
42 C> - 8, 12, etc. computer rescales data to fit into set number of bits.
43 C> @param[in] ITYPE
44 C> - 0 = if input data is floating point (fld)
45 C> - 1 = If input data is integer (ifld)
46 C> @param[in] ITOSS
47 C> - 0 = no bit map is included (don't toss data)
48 C> - 1 = Toss null data according to ibmap
49 C> @param[in] FLD Real array of data to be packed if itype=0
50 C> @param[in] IFLD Integer array to be packed if itype=1
51 C> @param[in] IBMAP Bit map supplied from user
52 C> @param[in] IBDSFL Integer array containing table 11 flag info
53 C> BDS octet 4:
54 C> - (1)
55 C> - 0 = grid point data
56 C> - 1 = spherical harmonic coefficients
57 C> - (2)
58 C> - 0 = simple packing
59 C> - 1 = second order packing
60 C> - (3)
61 C> - 0 = original data were floating point values
62 C> - 1 = original data were integer values
63 C> - (4)
64 C> - 0 = no additional flags at octet 14
65 C> - 1 = octet 14 contains flag bits 5-12
66 C> - (5) 0 = reserved - always set to 0
67 C> - (6)
68 C> - 0 = single datum at each grid point
69 C> - 1 = matrix of values at each grid point
70 C> - (7)
71 C> - 0 = no secondary bit maps
72 C> - 1 = secondary bit maps present
73 C> - (8)
74 C> - 0 = second order values have constant width
75 C> - 1 = second order values have different widths
76 C> @param[in] NPTS Number of gridpoints in array to be packed
77 C> @param[in] IGDS Array of gds information
78 C> @param[out] BDS11 First 11 octets of bds
79 C> @param[out] PFLD Packed grib field
80 C> @param[out] LEN Length of pfld
81 C> @param[out] LENBDS Length of bds
82 C> @param[out] IBERR 1, error converting ieee f.p. number to ibm370 f.p.
83 C> @param IPFLD
84 C> @param PDS
85 C>
86 C> @note Subprogram can be called from a multiprocessing environment.
87 C>
88  SUBROUTINE w3fi75 (IBITL,ITYPE,ITOSS,FLD,IFLD,IBMAP,IBDSFL,
89  & NPTS,BDS11,IPFLD,PFLD,LEN,LENBDS,IBERR,PDS,IGDS)
90 C
91  REAL FLD(*)
92 C REAL FWORK(260000)
93 C
94 C FWORK CAN USE DYNAMIC ALLOCATION OF MEMORY ON CRAY
95 C
96  REAL FWORK(NPTS)
97  REAL RMIN,REFNCE
98 C
99  character(len=1) IPFLD(*)
100  INTEGER IBDSFL(*)
101  INTEGER IBMAP(*)
102  INTEGER IFLD(*),IGDS(*)
103 C INTEGER IWORK(260000)
104 C
105 C IWORK CAN USE DYNAMIC ALLOCATION OF MEMORY ON CRAY
106 C
107  INTEGER IWORK(NPTS)
108 C
109  LOGICAL CONST
110 C
111  CHARACTER * 1 BDS11(11),PDS(*)
112  CHARACTER * 1 PFLD(*)
113 C
114 C 1.0 PACK THE FIELD.
115 C
116 C 1.1 TOSS DATA IF BITMAP BEING USED,
117 C MOVING 'DATA' TO WORK AREA...
118 C
119  const = .false.
120  iberr = 0
121  iw = 0
122 C
123  IF (itoss .EQ. 1) THEN
124  IF (itype .EQ. 0) THEN
125  DO 110 it=1,npts
126  IF (ibmap(it) .EQ. 1) THEN
127  iw = iw + 1
128  fwork(iw) = fld(it)
129  ENDIF
130  110 CONTINUE
131  npts = iw
132  ELSE IF (itype .EQ. 1) THEN
133  DO 111 it=1,npts
134  IF (ibmap(it) .EQ. 1) THEN
135  iw = iw + 1
136  iwork(iw) = ifld(it)
137  ENDIF
138  111 CONTINUE
139  npts = iw
140  ENDIF
141 C
142 C ELSE, JUST MOVE DATA TO WORK ARRAY
143 C
144  ELSE IF (itoss .EQ. 0) THEN
145  IF (itype .EQ. 0) THEN
146  DO 112 it=1,npts
147  fwork(it) = fld(it)
148  112 CONTINUE
149  ELSE IF (itype .EQ. 1) THEN
150  DO 113 it=1,npts
151  iwork(it) = ifld(it)
152  113 CONTINUE
153  ENDIF
154  ENDIF
155 C
156 C 1.2 CONVERT DATA IF NEEDED PRIOR TO PACKING.
157 C (INTEGER TO F.P. OR F.P. TO INTEGER)
158 C ITYPE = 0...FLOATING POINT DATA
159 C IBITL = 0...PACK IN LEAST # BITS...CONVERT TO INTEGER
160 C ITYPE = 1...INTEGER DATA
161 C IBITL > 0...PACK IN FIXED # BITS...CONVERT TO FLOATING POINT
162 C
163  IF (itype .EQ. 0 .AND. ibitl .EQ. 0) THEN
164  DO 120 if=1,npts
165  iwork(if) = nint(fwork(if))
166  120 CONTINUE
167  ELSE IF (itype .EQ. 1 .AND. ibitl .NE. 0) THEN
168  DO 123 if=1,npts
169  fwork(if) = float(iwork(if))
170  123 CONTINUE
171  ENDIF
172 C
173 C 1.3 PACK THE DATA.
174 C
175  IF (ibdsfl(2).NE.0) THEN
176 C SECOND ORDER PACKING
177 C
178 C PRINT*,' DOING SECOND ORDER PACKING...'
179  IF (ibitl.EQ.0) THEN
180 C
181 C PRINT*,' AND VARIABLE BIT PACKING'
182 C
183 C WORKING WITH INTEGER VALUES
184 C SINCE DOING VARIABLE BIT PACKING
185 C
186  max = iwork(1)
187  min = iwork(1)
188  DO 300 i = 2, npts
189  IF (iwork(i).LT.min) THEN
190  min = iwork(i)
191  ELSE IF (iwork(i).GT.max) THEN
192  max = iwork(i)
193  END IF
194  300 CONTINUE
195 C EXTRACT MINIMA
196  DO 400 i = 1, npts
197 C IF (IWORK(I).LT.0) THEN
198 C PRINT *,'MINIMA 400',I,IWORK(I),NPTS
199 C END IF
200  iwork(i) = iwork(i) - min
201  400 CONTINUE
202  refnce = min
203  idiff = max - min
204 C PRINT *,'REFERENCE VALUE',REFNCE
205 C
206 C WRITE (6,FMT='('' MINIMA REMOVED = '',/,
207 C & 10(3X,10I10,/))') (IWORK(I),I=1,6)
208 C WRITE (6,FMT='('' END OF ARRAY = '',/,
209 C & 10(3X,10I10,/))') (IWORK(I),I=NPTS-5,NPTS)
210 C
211 C FIND BIT WIDTH OF IDIFF
212 C
213  CALL fi7505 (idiff,kwide)
214 C PRINT*,' BIT WIDTH FOR ORIGINAL DATA', KWIDE
215  iscal2 = 0
216 C
217 C MULTIPLICATIVE SCALE FACTOR SET TO 1
218 C IN ANTICIPATION OF POSSIBLE USE IN GLAHN 2DN DIFF
219 C
220  scal2 = 1.
221 C
222  ELSE
223 C
224 C PRINT*,' AND FIXED BIT PACKING, IBITL = ', IBITL
225 C FIXED BIT PACKING
226 C - LENGTH OF FIELD IN IBITL
227 C - MUST BE REAL DATA
228 C FLOATING POINT INPUT
229 C
230  rmax = fwork(1)
231  rmin = fwork(1)
232  DO 100 i = 2, npts
233  IF (fwork(i).LT.rmin) THEN
234  rmin = fwork(i)
235  ELSE IF (fwork(i).GT.rmax) THEN
236  rmax = fwork(i)
237  END IF
238  100 CONTINUE
239  refnce = rmin
240 C PRINT *,'100 REFERENCE',REFNCE
241 C EXTRACT MINIMA
242  DO 200 i = 1, npts
243  fwork(i) = fwork(i) - rmin
244  200 CONTINUE
245 C PRINT *,'REFERENCE VALUE',REFNCE
246 C WRITE (6,FMT='('' MINIMA REMOVED = '',/,
247 C & 10(3X,10F8.2,/))') (FWORK(I),I=1,6)
248 C WRITE (6,FMT='('' END OF ARRAY = '',/,
249 C & 10(3X,10F8.2,/))') (FWORK(I),I=NPTS-5,NPTS)
250 C FIND LARGEST DELTA
251  idelt = nint(rmax - rmin)
252 C DO BINARY SCALING
253 C FIND OUT WHAT BINARY SCALE FACTOR
254 C PERMITS CONTAINMENT OF
255 C LARGEST DELTA
256  CALL fi7505 (idelt,iwide)
257 C
258 C BINARY SCALING
259 C
260  iscal2 = iwide - ibitl
261 C PRINT *,'SCALING NEEDED TO FIT =',ISCAL2
262 C PRINT*,' RANGE OF = ',IDELT
263 C
264 C EXPAND DATA WITH BINARY SCALING
265 C CONVERT TO INTEGER
266  scal2 = 2.0**iscal2
267  scal2 = 1./ scal2
268  DO 600 i = 1, npts
269  iwork(i) = nint(fwork(i) * scal2)
270  600 CONTINUE
271  kwide = ibitl
272  END IF
273 C
274 C *****************************************************************
275 C
276 C FOLLOWING IS FOR GLAHN SECOND DIFFERENCING
277 C NOT STANDARD GRIB
278 C
279 C TEST FOR SECOND DIFFERENCE PACKING
280 C BASED OF SIZE OF PDS - SIZE IN FIRST 3 BYTES
281 C
282  CALL gbytec(pds,ipdsiz,0,24)
283  IF (ipdsiz.EQ.50) THEN
284 C PRINT*,' DO SECOND DIFFERENCE PACKING '
285 C
286 C GLAHN PACKING TO 2ND DIFFS
287 C
288 C WRITE (6,FMT='('' CALL TO W3FI82 WITH = '',/,
289 C & 10(3X,10I6,/))') (IWORK(I),I=1,NPTS)
290 C
291  CALL w3fi82 (iwork,fval1,fdiff1,npts,pds,igds)
292 C
293 C PRINT *,'GLAHN',FVAL1,FDIFF1
294 C WRITE (6,FMT='('' OUT FROM W3FI82 WITH = '',/,
295 C & 10(3X,10I6,/))') (IWORK(I),I=1,NPTS)
296 C
297 C MUST NOW RE-REMOVE THE MINIMUM VALUE
298 C OF THE SECOND DIFFERENCES TO ASSURE
299 C ALL POSITIVE NUMBERS FOR SECOND ORDER GRIB PACKING
300 C
301 C ORIGINAL REFERENCE VALUE ADDED TO FIRST POINT
302 C VALUE FROM THE 2ND DIFF PACKER TO BE ADDED
303 C BACK IN WHEN THE 2ND DIFF VALUES ARE
304 C RECONSTRUCTED BACK TO THE BASIC VALUES
305 C
306 C ALSO, THE REFERENCE VALUE IS
307 C POWER-OF-TWO SCALED TO MATCH
308 C FVAL1. ALL OF THIS SCALING
309 C WILL BE REMOVED AFTER THE
310 C GLAHN SECOND DIFFERENCING IS UNDONE.
311 C THE SCALING FACTOR NEEDED TO DO THAT
312 C IS SAVED IN THE PDS AS A SIGNED POSITIVE
313 C TWO BYTE INTEGER
314 C
315 C THE SCALING FOR THE 2ND DIF PACKED
316 C VALUES IS PROPERLY SET TO ZERO
317 C
318  fval1 = fval1 + refnce*scal2
319 C FIRST TEST TO SEE IF
320 C ON 32 OR 64 BIT COMPUTER
321 C CALL W3FI01(LW)
322  IF (bit_size(lw).EQ.32) THEN
323  CALL w3fi76 (fval1,iexp,imant,32)
324  ELSE
325  CALL w3fi76 (fval1,iexp,imant,64)
326  END IF
327  CALL sbytec(pds,iexp,320,8)
328  CALL sbytec(pds,imant,328,24)
329 C
330  IF (bit_size(lw).EQ.32) THEN
331  CALL w3fi76 (fdiff1,iexp,imant,32)
332  ELSE
333  CALL w3fi76 (fdiff1,iexp,imant,64)
334  END IF
335  CALL sbytec(pds,iexp,352,8)
336  CALL sbytec(pds,imant,360,24)
337 C
338 C TURN ISCAL2 INTO SIGNED POSITIVE INTEGER
339 C AND STORE IN TWO BYTES
340 C
341  IF(iscal2.GE.0) THEN
342  CALL sbytec(pds,iscal2,384,16)
343  ELSE
344  CALL sbytec(pds,1,384,1)
345  iscal2 = - iscal2
346  CALL sbytec( pds,iscal2,385,15)
347  ENDIF
348 C
349  max = iwork(1)
350  min = iwork(1)
351  DO 700 i = 2, npts
352  IF (iwork(i).LT.min) THEN
353  min = iwork(i)
354  ELSE IF (iwork(i).GT.max) THEN
355  max = iwork(i)
356  END IF
357  700 CONTINUE
358 C EXTRACT MINIMA
359  DO 710 i = 1, npts
360  iwork(i) = iwork(i) - min
361  710 CONTINUE
362  refnce = min
363 C PRINT *,'710 REFERENCE',REFNCE
364  iscal2 = 0
365 C
366 C AND RESET VALUE OF KWIDE - THE BIT WIDTH
367 C FOR THE RANGE OF THE VALUES
368 C
369  idiff = max - min
370  CALL fi7505 (idiff,kwide)
371 C
372 C PRINT*,'BIT WIDTH (KWIDE) OF 2ND DIFFS', KWIDE
373 C
374 C **************************** END OF GLAHN PACKING ************
375  ELSE IF (ibdsfl(2).EQ.1.AND.ibdsfl(7).EQ.0) THEN
376 C HAVE SECOND ORDER PACKING WITH NO SECOND ORDER
377 C BIT MAP. ERGO ROW BY ROW - COL BY COL
378  CALL fi7503 (iwork,ipfld,npts,ibdsfl,bds11,
379  * len,lenbds,pds,refnce,iscal2,kwide,igds)
380  RETURN
381  END IF
382 C WRITE (6,FMT='('' CALL TO FI7501 WITH = '',/,
383 C & 10(3X,10I6,/))') (IWORK(I),I=1,NPTS)
384 C WRITE (6,FMT='('' END OF ARRAY = '',/,
385 C & 10(3X,10I6,/))') (IWORK(I),I=NPTS-5,NPTS)
386 C PRINT*,' REFNCE,ISCAL2, KWIDE AT CALL TO FI7501',
387 C & REFNCE, ISCAL2,KWIDE
388 C
389 C SECOND ORDER PACKING
390 C
391  CALL fi7501 (iwork,ipfld,npts,ibdsfl,bds11,
392  * len,lenbds,pds,refnce,iscal2,kwide)
393 C
394 C BDS COMPLETELY ASSEMBLED IN FI7501 FOR SECOND ORDER
395 C PACKING.
396 C
397  ELSE
398 C SIMPLE PACKING
399 C
400 C PRINT*,' SIMPLE FIRST ORDER PACKING...'
401  IF (ibitl.EQ.0) THEN
402 C PRINT*,' WITH VARIABLE BIT LENGTH'
403 C
404 C WITH VARIABLE BIT LENGTH, ADJUSTED
405 C TO ACCOMMODATE LARGEST VALUE
406 C BINARY SCALING ALWAYS = 0
407 C
408  CALL w3fi58(iwork,npts,iwork,pfld,nbits,len,kmin)
409  rmin = kmin
410  refnce = rmin
411  iscale = 0
412 C PRINT*,' BIT LENGTH CAME OUT AT ...',NBITS
413 C
414 C SET CONST .TRUE. IF ALL VALUES ARE THE SAME
415 C
416  IF (len.EQ.0.AND.nbits.EQ.0) const = .true.
417 C
418  ELSE
419 C PRINT*,' FIXED BIT LENGTH, IBITL = ', IBITL
420 C
421 C FIXED BIT LENGTH PACKING (VARIABLE PRECISION)
422 C VALUES SCALED BY POWER OF 2 (ISCALE) TO
423 C FIT LARGEST VALUE INTO GIVEN BIT LENGTH (IBITL)
424 C
425  CALL w3fi59(fwork,npts,ibitl,iwork,pfld,iscale,len,rmin)
426  refnce = rmin
427 C PRINT *,' SCALING NEEDED TO FIT IS ...', ISCALE
428  nbits = ibitl
429 C
430 C SET CONST .TRUE. IF ALL VALUES ARE THE SAME
431 C
432  IF (len.EQ.0) THEN
433  const = .true.
434  nbits = 0
435  END IF
436  END IF
437 C
438 C$ COMPUTE LENGTH OF BDS IN OCTETS
439 C
440  inum = npts * nbits + 88
441 C PRINT *,'NUMBER OF BITS BEFORE FILL ADDED',INUM
442 C
443 C NUMBER OF FILL BITS
444  nfill = 0
445  nleft = mod(inum,16)
446  IF (nleft.NE.0) THEN
447  inum = inum + 16 - nleft
448  nfill = 16 - nleft
449  END IF
450 C PRINT *,'NUMBER OF BITS AFTER FILL ADDED',INUM
451 C LENGTH OF BDS IN BYTES
452  lenbds = inum / 8
453 C
454 C 2.0 FORM THE BINARY DATA SECTION (BDS).
455 C
456 C CONCANTENATE ALL FIELDS FOR BDS
457 C
458 C BYTES 1-3
459  CALL sbytec (bds11,lenbds,0,24)
460 C
461 C BYTE 4
462 C FLAGS
463  CALL sbytec (bds11,ibdsfl(1),24,1)
464  CALL sbytec (bds11,ibdsfl(2),25,1)
465  CALL sbytec (bds11,ibdsfl(3),26,1)
466  CALL sbytec (bds11,ibdsfl(4),27,1)
467 C NR OF FILL BITS
468  CALL sbytec (bds11,nfill,28,4)
469 C
470 C$ FILL OCTETS 5-6 WITH THE SCALE FACTOR.
471 C
472 C BYTE 5-6
473  IF (iscale.LT.0) THEN
474  CALL sbytec (bds11,1,32,1)
475  iscale = - iscale
476  CALL sbytec (bds11,iscale,33,15)
477  ELSE
478  CALL sbytec (bds11,iscale,32,16)
479  END IF
480 C
481 C$ FILL OCTET 7-10 WITH THE REFERENCE VALUE
482 C CONVERT THE FLOATING POINT OF YOUR MACHINE TO IBM370 32 BIT
483 C FLOATING POINT NUMBER
484 C
485 C BYTE 7-10
486 C REFERENCE VALUE
487 C FIRST TEST TO SEE IF
488 C ON 32 OR 64 BIT COMPUTER
489 C CALL W3FI01(LW)
490  IF (bit_size(lw).EQ.32) THEN
491  CALL w3fi76 (refnce,iexp,imant,32)
492  ELSE
493  CALL w3fi76 (refnce,iexp,imant,64)
494  END IF
495  CALL sbytec (bds11,iexp,48,8)
496  CALL sbytec (bds11,imant,56,24)
497 C
498 C
499 C$ FILL OCTET 11 WITH THE NUMBER OF BITS.
500 C
501 C BYTE 11
502  CALL sbytec (bds11,nbits,80,8)
503  END IF
504 C
505  RETURN
506  END
507 C
508 C> @brief BDS second order packing.
509 C> @author Bill Cavanaugh @date 1993-08-06
510 
511 C> Perform secondary packing on grid point data, generating all BDS information.
512 C>
513 C> Program history log:
514 C> - Bill Cavanaugh 1993-08-06
515 C> - Bill Cavanaugh 1993-12-15 Corrected location of start of first order
516 C> values and start of second order values to reflect a byte location in the
517 C> BDS instead of an offset.
518 C> - Mark Iredell 1995-10-31 Removed saves and prints
519 C>
520 C> @param[in] IWORK Integer source array
521 C> @param[in] NPTS Number of points in iwork
522 C> @param[in] IBDSFL Flags
523 C> @param[out] IPFLD Contains bds from byte 12 on
524 C> @param[out] BDS11 Contains first 11 bytes for bds
525 C> @param[out] LEN Number of bytes from 12 on
526 C> @param[out] LENBDS Total length of bds
527 C> @param PDS
528 C> @param REFNCE
529 C> @param ISCAL2
530 C> @param KWIDE
531 C>
532 C> @note Subprogram can be called from a multiprocessing environment.
533 C>
534 C> @author Bill Cavanaugh @date 1993-08-06
535  SUBROUTINE fi7501 (IWORK,IPFLD,NPTS,IBDSFL,BDS11,
536  * LEN,LENBDS,PDS,REFNCE,ISCAL2,KWIDE)
537 
538  CHARACTER*1 BDS11(*),PDS(*)
539 C
540  REAL REFNCE
541 C
542  INTEGER ISCAL2,KWIDE
543  INTEGER LENBDS
544  CHARACTER(len=1) IPFLD(*)
545  INTEGER LEN,KBDS(22)
546  INTEGER IWORK(*)
547 C OCTET NUMBER IN SECTION, FIRST ORDER PACKING
548 C INTEGER KBDS(12)
549 C FLAGS
550  INTEGER IBDSFL(*)
551 C EXTENDED FLAGS
552 C INTEGER KBDS(14)
553 C OCTET NUMBER FOR SECOND ORDER PACKING
554 C INTEGER KBDS(15)
555 C NUMBER OF FIRST ORDER VALUES
556 C INTEGER KBDS(17)
557 C NUMBER OF SECOND ORDER PACKED VALUES
558 C INTEGER KBDS(19)
559 C WIDTH OF SECOND ORDER PACKING
560  character(len=1) ISOWID(400000)
561 C SECONDARY BIT MAP
562  character(len=1) ISOBMP(65600)
563 C FIRST ORDER PACKED VALUES
564  character(len=1) IFOVAL(400000)
565 C SECOND ORDER PACKED VALUES
566  character(len=1) ISOVAL(800000)
567 C
568 C INTEGER KBDS(11)
569 C BIT WIDTH TABLE
570  INTEGER IBITS(31)
571 C
572  DATA ibits/1,3,7,15,31,63,127,255,511,1023,
573  * 2047,4095,8191,16383,32767,65535,131072,
574  * 262143,524287,1048575,2097151,4194303,
575  * 8388607,16777215,33554431,67108863,
576  * 134217727,268435455,536870911,
577  * 1073741823,2147483647/
578 C ----------------------------------
579 C INITIALIZE ARRAYS
580 
581  DO i = 1, 400000
582  ifoval(i) = char(0)
583  isowid(i) = char(0)
584  ENDDO
585 C
586  DO 101 i = 1, 65600
587  isobmp(i) = char(0)
588  101 CONTINUE
589  DO 102 i = 1, 800000
590  isoval(i) = char(0)
591  102 CONTINUE
592 C INITIALIZE POINTERS
593 C SECONDARY BIT WIDTH POINTER
594  iwdptr = 0
595 C SECONDARY BIT MAP POINTER
596  ibmp2p = 0
597 C FIRST ORDER VALUE POINTER
598  ifoptr = 0
599 C BYTE POINTER TO START OF 1ST ORDER VALUES
600  kbds(12) = 0
601 C BYTE POINTER TO START OF 2ND ORDER VALUES
602  kbds(15) = 0
603 C TO CONTAIN NUMBER OF FIRST ORDER VALUES
604  kbds(17) = 0
605 C TO CONTAIN NUMBER OF SECOND ORDER VALUES
606  kbds(19) = 0
607 C SECOND ORDER PACKED VALUE POINTER
608  isoptr = 0
609 C =======================================================
610 C
611 C DATA IS IN IWORK
612 C
613  kbds(11) = kwide
614 C
615 C DATA PACKING
616 C
617  iter = 0
618  inext = 1
619  istart = 1
620 C -----------------------------------------------------------
621  kount = 0
622 C DO 1 I = 1, NPTS, 10
623 C PRINT *,I,(IWORK(K),K=I, I+9)
624 C 1 CONTINUE
625  2000 CONTINUE
626  iter = iter + 1
627 C PRINT *,'NEXT ITERATION STARTS AT',ISTART
628  IF (istart.GT.npts) THEN
629  GO TO 4000
630  ELSE IF (istart.EQ.npts) THEN
631  kpts = 1
632  mxdiff = 0
633  GO TO 2200
634  END IF
635 C
636 C LOOK FOR REPITITIONS OF A SINGLE VALUE
637  CALL fi7502 (iwork,istart,npts,isame)
638  IF (isame.GE.15) THEN
639  kount = kount + 1
640 C PRINT *,'FI7501 - FOUND IDENTICAL SET OF ',ISAME
641  mxdiff = 0
642  kpts = isame
643  ELSE
644 C
645 C LOOK FOR SETS OF VALUES IN TREND SELECTED RANGE
646  CALL fi7513 (iwork,istart,npts,nmax,nmin,inrnge)
647 C PRINT *,'ISTART ',ISTART,' INRNGE',INRNGE,NMAX,NMIN
648  iend = istart + inrnge - 1
649 C DO 2199 NM = ISTART, IEND, 10
650 C PRINT *,' ',(IWORK(NM+JK),JK=0,9)
651 C2199 CONTINUE
652  mxdiff = nmax - nmin
653  kpts = inrnge
654  END IF
655  2200 CONTINUE
656 C PRINT *,' RANGE ',MXDIFF,' MAX',NMAX,' MIN',NMIN
657 C INCREMENT NUMBER OF FIRST ORDER VALUES
658  kbds(17) = kbds(17) + 1
659 C ENTER FIRST ORDER VALUE
660  IF (mxdiff.GT.0) THEN
661  DO 2220 lk = 0, kpts-1
662  iwork(istart+lk) = iwork(istart+lk) - nmin
663  2220 CONTINUE
664  CALL sbytec (ifoval,nmin,ifoptr,kbds(11))
665  ELSE
666  CALL sbytec (ifoval,iwork(istart),ifoptr,kbds(11))
667  END IF
668  ifoptr = ifoptr + kbds(11)
669 C PROCESS SECOND ORDER BIT WIDTH
670  IF (mxdiff.GT.0) THEN
671  DO 2330 kwide = 1, 31
672  IF (mxdiff.LE.ibits(kwide)) THEN
673  GO TO 2331
674  END IF
675  2330 CONTINUE
676  2331 CONTINUE
677  ELSE
678  kwide = 0
679  END IF
680  CALL sbytec (isowid,kwide,iwdptr,8)
681  iwdptr = iwdptr + 8
682 C PRINT *,KWIDE,' IFOVAL=',NMIN,IWORK(ISTART),KPTS
683 C IF KWIDE NE 0, SAVE SECOND ORDER VALUE
684  IF (kwide.GT.0) THEN
685  CALL sbytesc (isoval,iwork(istart),isoptr,kwide,0,kpts)
686  isoptr = isoptr + kpts * kwide
687  kbds(19) = kbds(19) + kpts
688 C PRINT *,' SECOND ORDER VALUES'
689 C PRINT *,(IWORK(ISTART+I),I=0,KPTS-1)
690  END IF
691 C ADD TO SECOND ORDER BITMAP
692  CALL sbytec (isobmp,1,ibmp2p,1)
693  ibmp2p = ibmp2p + kpts
694  istart = istart + kpts
695  GO TO 2000
696 C --------------------------------------------------------------
697  4000 CONTINUE
698 C PRINT *,'THERE WERE ',ITER,' SECOND ORDER GROUPS'
699 C PRINT *,'THERE WERE ',KOUNT,' STRINGS OF CONSTANTS'
700 C CONCANTENATE ALL FIELDS FOR BDS
701 C
702 C REMAINDER GOES INTO IPFLD
703  iptr = 0
704 C BYTES 12-13
705 C VALUE FOR N1
706 C LEAVE SPACE FOR THIS
707  iptr = iptr + 16
708 C BYTE 14
709 C EXTENDED FLAGS
710  CALL sbytec (ipfld,ibdsfl(5),iptr,1)
711  iptr = iptr + 1
712  CALL sbytec (ipfld,ibdsfl(6),iptr,1)
713  iptr = iptr + 1
714  CALL sbytec (ipfld,ibdsfl(7),iptr,1)
715  iptr = iptr + 1
716  CALL sbytec (ipfld,ibdsfl(8),iptr,1)
717  iptr = iptr + 1
718  CALL sbytec (ipfld,ibdsfl(9),iptr,1)
719  iptr = iptr + 1
720  CALL sbytec (ipfld,ibdsfl(10),iptr,1)
721  iptr = iptr + 1
722  CALL sbytec (ipfld,ibdsfl(11),iptr,1)
723  iptr = iptr + 1
724  CALL sbytec (ipfld,ibdsfl(12),iptr,1)
725  iptr = iptr + 1
726 C BYTES 15-16
727 C SKIP OVER VALUE FOR N2
728  iptr = iptr + 16
729 C BYTES 17-18
730 C P1
731  CALL sbytec (ipfld,kbds(17),iptr,16)
732  iptr = iptr + 16
733 C BYTES 19-20
734 C P2
735  CALL sbytec (ipfld,kbds(19),iptr,16)
736  iptr = iptr + 16
737 C BYTE 21 - RESERVED LOCATION
738  CALL sbytec (ipfld,0,iptr,8)
739  iptr = iptr + 8
740 C BYTES 22 - ?
741 C WIDTHS OF SECOND ORDER PACKING
742  ix = (iwdptr + 32) / 32
743 C CALL SBYTESC (IPFLD,ISOWID,IPTR,32,0,IX)
744  ijk=iwdptr/8
745  jst=(iptr/8)+1
746  ipfld(jst:jst+ijk)=isowid(1:ijk)
747  iptr = iptr + iwdptr
748 C SECONDARY BIT MAP
749  ij = (ibmp2p + 32) / 32
750 C CALL SBYTESC (IPFLD,ISOBMP,IPTR,32,0,IJ)
751  ijk=(ibmp2p/8)+1
752  jst=(iptr/8)+1
753  ipfld(jst:jst+ijk)=isobmp(1:ijk)
754  iptr = iptr + ibmp2p
755  IF (mod(iptr,8).NE.0) THEN
756  iptr = iptr + 8 - mod(iptr,8)
757  END IF
758 C DETERMINE LOCATION FOR START
759 C OF FIRST ORDER PACKED VALUES
760  kbds(12) = iptr / 8 + 12
761 C STORE LOCATION
762  CALL sbytec (ipfld,kbds(12),0,16)
763 C MOVE IN FIRST ORDER PACKED VALUES
764  ipass = (ifoptr + 32) / 32
765 C CALL SBYTESC (IPFLD,IFOVAL,IPTR,32,0,IPASS)
766  ijk=(ifoptr/8)+1
767  jst=(iptr/8)+1
768  ipfld(jst:jst+ijk)=ifoval(1:ijk)
769  iptr = iptr + ifoptr
770  IF (mod(iptr,8).NE.0) THEN
771  iptr = iptr + 8 - mod(iptr,8)
772  END IF
773 C PRINT *,'IFOPTR =',IFOPTR,' ISOPTR =',ISOPTR
774 C DETERMINE LOCATION FOR START
775 C OF SECOND ORDER VALUES
776  kbds(15) = iptr / 8 + 12
777 C SAVE LOCATION OF SECOND ORDER VALUES
778  CALL sbytec (ipfld,kbds(15),24,16)
779 C MOVE IN SECOND ORDER PACKED VALUES
780  ix = (isoptr + 32) / 32
781 c CALL SBYTESC (IPFLD,ISOVAL,IPTR,32,0,IX)
782  ijk=(isoptr/8)+1
783  jst=(iptr/8)+1
784  ipfld(jst:jst+ijk)=isoval(1:ijk)
785  iptr = iptr + isoptr
786  nleft = mod(iptr+88,16)
787  IF (nleft.NE.0) THEN
788  nleft = 16 - nleft
789  iptr = iptr + nleft
790  END IF
791 C COMPUTE LENGTH OF DATA PORTION
792  len = iptr / 8
793 C COMPUTE LENGTH OF BDS
794  lenbds = len + 11
795 C -----------------------------------
796 C BYTES 1-3
797 C THIS FUNCTION COMPLETED BELOW
798 C WHEN LENGTH OF BDS IS KNOWN
799  CALL sbytec (bds11,lenbds,0,24)
800 C BYTE 4
801  CALL sbytec (bds11,ibdsfl(1),24,1)
802  CALL sbytec (bds11,ibdsfl(2),25,1)
803  CALL sbytec (bds11,ibdsfl(3),26,1)
804  CALL sbytec (bds11,ibdsfl(4),27,1)
805 C ENTER NUMBER OF FILL BITS
806  CALL sbytec (bds11,nleft,28,4)
807 C BYTE 5-6
808  IF (iscal2.LT.0) THEN
809  CALL sbytec (bds11,1,32,1)
810  iscal2 = - iscal2
811  ELSE
812  CALL sbytec (bds11,0,32,1)
813  END IF
814  CALL sbytec (bds11,iscal2,33,15)
815 C
816 C$ FILL OCTET 7-10 WITH THE REFERENCE VALUE
817 C CONVERT THE FLOATING POINT OF YOUR MACHINE TO IBM370 32 BIT
818 C FLOATING POINT NUMBER
819 C REFERENCE VALUE
820 C FIRST TEST TO SEE IF
821 C ON 32 OR 64 BIT COMPUTER
822 C CALL W3FI01(LW)
823  IF (bit_size(lw).EQ.32) THEN
824  CALL w3fi76 (refnce,iexp,imant,32)
825  ELSE
826  CALL w3fi76 (refnce,iexp,imant,64)
827  END IF
828  CALL sbytec (bds11,iexp,48,8)
829  CALL sbytec (bds11,imant,56,24)
830 C
831 C BYTE 11
832 C
833  CALL sbytec (bds11,kbds(11),80,8)
834 C
835  RETURN
836  END
837 C
838 C> @brief Second order same value collection.
839 C> @author Bill Cavanaugh @date 1993-06-23
840 
841 C> Collect sequential same values for processing
842 C> as second order value for grib messages.
843 C>
844 C> Program history log:
845 C> - Bill Cavanaugh 1993-06-23
846 C> - Mark Iredell 1995-10-31 Removed saves and prints
847 C>
848 C> @param[in] IWORK Array containing source data
849 C> @param[in] ISTART Starting location for this test
850 C> @param[in] NPTS Number of points in iwork
851 C> @param[out] ISAME Number of sequential points having the same value
852 C>
853 C> @note Subprogram can be called from a multiprocessing environment.
854 C>
855 C> @author Bill Cavanaugh @date 1993-06-23
856  SUBROUTINE fi7502 (IWORK,ISTART,NPTS,ISAME)
857 
858  INTEGER IWORK(*)
859  INTEGER ISTART
860  INTEGER ISAME
861  INTEGER K
862  INTEGER NPTS
863 C -------------------------------------------------------------
864  isame = 0
865  DO 100 k = istart, npts
866  IF (iwork(k).NE.iwork(istart)) THEN
867  RETURN
868  END IF
869  isame = isame + 1
870  100 CONTINUE
871  RETURN
872  END
873 C
874 C> @brief Row by row, col by col packing.
875 C> @author Bill Cavanaugh @date 1993-08-06
876 
877 C> Perform row by row or column by column packing
878 C> generating all bds information.
879 C>
880 C> Program history log:
881 C> - Bill Cavanaugh 1993-08-06
882 C> - Mark Iredell 1995-10-31 Removed saves and prints
883 C>
884 C> @param[in] IWORK Integer source array
885 C> @param[in] NPTS Number of points in iwork
886 C> @param[in] IBDSFL Flags
887 C> @param[out] IPFLD Contains bds from byte 12 on
888 C> @param[out] BDS11 Contains first 11 bytes for bds
889 C> @param[out] LEN Number of bytes from 12 on
890 C> @param[out] LENBDS Total length of bds
891 C> @param PDS
892 C> @param REFNCE
893 C> @param ISCAL2
894 C> @param KWIDE
895 C> @param IGDS
896 C>
897 C> @note Subprogram can be called from a multiprocessing environment.
898 C>
899 C> @author Bill Cavanaugh @date 1993-08-06
900  SUBROUTINE fi7503 (IWORK,IPFLD,NPTS,IBDSFL,BDS11,
901  * LEN,LENBDS,PDS,REFNCE,ISCAL2,KWIDE,IGDS)
902 
903  CHARACTER*1 BDS11(*),PDS(*),IPFLD(*)
904 C
905  REAL REFNCE
906 C
907  INTEGER ISCAL2,KWIDE
908  INTEGER LENBDS
909  INTEGER IGDS(*)
910  INTEGER LEN,KBDS(22)
911  INTEGER IWORK(*)
912 C OCTET NUMBER IN SECTION, FIRST ORDER PACKING
913 C INTEGER KBDS(12)
914 C FLAGS
915  INTEGER IBDSFL(*)
916 C EXTENDED FLAGS
917 C INTEGER KBDS(14)
918 C OCTET NUMBER FOR SECOND ORDER PACKING
919 C INTEGER KBDS(15)
920 C NUMBER OF FIRST ORDER VALUES
921 C INTEGER KBDS(17)
922 C NUMBER OF SECOND ORDER PACKED VALUES
923 C INTEGER KBDS(19)
924 C WIDTH OF SECOND ORDER PACKING
925  character(len=1) ISOWID(400000)
926 C SECONDARY BIT MAP
927  character(len=1) ISOBMP(65600)
928 C FIRST ORDER PACKED VALUES
929  character(len=1) IFOVAL(400000)
930 C SECOND ORDER PACKED VALUES
931  character(len=1) ISOVAL(800000)
932 C
933 C INTEGER KBDS(11)
934 C ----------------------------------
935 C INITIALIZE ARRAYS
936 C
937  DO i = 1, 400000
938  ifoval(i) = char(0)
939  isowid(i) = char(0)
940  ENDDO
941 C
942  DO 101 i = 1, 65600
943  isobmp(i) = char(0)
944  101 CONTINUE
945  DO 102 i = 1, 800000
946  isoval(i) = char(0)
947  102 CONTINUE
948 C INITIALIZE POINTERS
949 C SECONDARY BIT WIDTH POINTER
950  iwdptr = 0
951 C SECONDARY BIT MAP POINTER
952  ibmp2p = 0
953 C FIRST ORDER VALUE POINTER
954  ifoptr = 0
955 C BYTE POINTER TO START OF 1ST ORDER VALUES
956  kbds(12) = 0
957 C BYTE POINTER TO START OF 2ND ORDER VALUES
958  kbds(15) = 0
959 C TO CONTAIN NUMBER OF FIRST ORDER VALUES
960  kbds(17) = 0
961 C TO CONTAIN NUMBER OF SECOND ORDER VALUES
962  kbds(19) = 0
963 C SECOND ORDER PACKED VALUE POINTER
964  isoptr = 0
965 C =======================================================
966 C BUILD SECOND ORDER BIT MAP IN EITHER
967 C ROW BY ROW OR COL BY COL FORMAT
968  IF (iand(igds(13),32).NE.0) THEN
969 C COLUMN BY COLUMN
970  kout = igds(4)
971  kin = igds(5)
972 C PRINT *,'COLUMN BY COLUMN',KOUT,KIN
973  ELSE
974 C ROW BY ROW
975  kout = igds(5)
976  kin = igds(4)
977 C PRINT *,'ROW BY ROW',KOUT,KIN
978  END IF
979  kbds(17) = kout
980  kbds(19) = npts
981 C
982 C DO 4100 J = 1, NPTS, 53
983 C WRITE (6,4101) (IWORK(K),K=J,J+52)
984  4101 FORMAT (1x,25i4)
985 C PRINT *,' '
986 C4100 CONTINUE
987 C
988 C INITIALIZE BIT MAP POINTER
989  ibmp2p = 0
990 C CONSTRUCT WORKING BIT MAP
991  DO 2000 i = 1, kout
992  DO 1000 j = 1, kin
993  IF (j.EQ.1) THEN
994  CALL sbytec (isobmp,1,ibmp2p,1)
995  ELSE
996  CALL sbytec (isobmp,0,ibmp2p,1)
997  END IF
998  ibmp2p = ibmp2p + 1
999  1000 CONTINUE
1000  2000 CONTINUE
1001  len = ibmp2p / 32 + 1
1002 C CALL BINARY(ISOBMP,LEN)
1003 C
1004 C PROCESS OUTER LOOP OF ROW BY ROW OR COL BY COL
1005 C
1006  kptr = 1
1007  kbds(11) = kwide
1008  DO 6000 i = 1, kout
1009 C IN CURRENT ROW OR COL
1010 C FIND FIRST ORDER VALUE
1011  jptr = kptr
1012  lowest = iwork(jptr)
1013  DO 4000 j = 1, kin
1014  IF (iwork(jptr).LT.lowest) THEN
1015  lowest = iwork(jptr)
1016  END IF
1017  jptr = jptr + 1
1018  4000 CONTINUE
1019 C SAVE FIRST ORDER VALUE
1020  CALL sbytec (ifoval,lowest,ifoptr,kwide)
1021  ifoptr = ifoptr + kwide
1022 C PRINT *,'FOVAL',I,LOWEST,KWIDE
1023 C SUBTRACT FIRST ORDER VALUE FROM OTHER VALS
1024 C GETTING SECOND ORDER VALUES
1025  jptr = kptr
1026  ibig = iwork(jptr) - lowest
1027  DO 4200 j = 1, kin
1028  iwork(jptr) = iwork(jptr) - lowest
1029  IF (iwork(jptr).GT.ibig) THEN
1030  ibig = iwork(jptr)
1031  END IF
1032  jptr = jptr + 1
1033  4200 CONTINUE
1034 C HOW MANY BITS TO CONTAIN LARGEST SECOND
1035 C ORDER VALUE IN SEGMENT
1036  CALL fi7505 (ibig,nwide)
1037 C SAVE BIT WIDTH
1038  CALL sbytec (isowid,nwide,iwdptr,8)
1039  iwdptr = iwdptr + 8
1040 C PRINT *,I,'SOVAL',IBIG,' IN',NWIDE,' BITS'
1041 C WRITE (6,4101) (IWORK(K),K=KPTR,KPTR+52)
1042 C SAVE SECOND ORDER VALUES OF THIS SEGMENT
1043  DO 5000 j = 0, kin-1
1044  CALL sbytec (isoval,iwork(kptr+j),isoptr,nwide)
1045  isoptr = isoptr + nwide
1046  5000 CONTINUE
1047  kptr = kptr + kin
1048  6000 CONTINUE
1049 C =======================================================
1050 C CONCANTENATE ALL FIELDS FOR BDS
1051 C
1052 C REMAINDER GOES INTO IPFLD
1053  iptr = 0
1054 C BYTES 12-13
1055 C VALUE FOR N1
1056 C LEAVE SPACE FOR THIS
1057  iptr = iptr + 16
1058 C BYTE 14
1059 C EXTENDED FLAGS
1060  CALL sbytec (ipfld,ibdsfl(5),iptr,1)
1061  iptr = iptr + 1
1062  CALL sbytec (ipfld,ibdsfl(6),iptr,1)
1063  iptr = iptr + 1
1064  CALL sbytec (ipfld,ibdsfl(7),iptr,1)
1065  iptr = iptr + 1
1066  CALL sbytec (ipfld,ibdsfl(8),iptr,1)
1067  iptr = iptr + 1
1068  CALL sbytec (ipfld,ibdsfl(9),iptr,1)
1069  iptr = iptr + 1
1070  CALL sbytec (ipfld,ibdsfl(10),iptr,1)
1071  iptr = iptr + 1
1072  CALL sbytec (ipfld,ibdsfl(11),iptr,1)
1073  iptr = iptr + 1
1074  CALL sbytec (ipfld,ibdsfl(12),iptr,1)
1075  iptr = iptr + 1
1076 C BYTES 15-16
1077 C SKIP OVER VALUE FOR N2
1078  iptr = iptr + 16
1079 C BYTES 17-18
1080 C P1
1081  CALL sbytec (ipfld,kbds(17),iptr,16)
1082  iptr = iptr + 16
1083 C BYTES 19-20
1084 C P2
1085  CALL sbytec (ipfld,kbds(19),iptr,16)
1086  iptr = iptr + 16
1087 C BYTE 21 - RESERVED LOCATION
1088  CALL sbytec (ipfld,0,iptr,8)
1089  iptr = iptr + 8
1090 C BYTES 22 - ?
1091 C WIDTHS OF SECOND ORDER PACKING
1092  ix = (iwdptr + 32) / 32
1093 C CALL SBYTESC (IPFLD,ISOWID,IPTR,32,0,IX)
1094  ijk=iwdptr/8
1095  jst=(iptr/8)+1
1096  ipfld(jst:jst+ijk)=isowid(1:ijk)
1097  iptr = iptr + iwdptr
1098 C PRINT *,'ISOWID',IWDPTR,IX
1099 C CALL BINARY (ISOWID,IX)
1100 C
1101 C NO SECONDARY BIT MAP
1102 
1103 C DETERMINE LOCATION FOR START
1104 C OF FIRST ORDER PACKED VALUES
1105  kbds(12) = iptr / 8 + 12
1106 C STORE LOCATION
1107  CALL sbytec (ipfld,kbds(12),0,16)
1108 C MOVE IN FIRST ORDER PACKED VALUES
1109  ipass = (ifoptr + 32) / 32
1110 c CALL SBYTESC (IPFLD,IFOVAL,IPTR,32,0,IPASS)
1111  ijk=(ifoptr/8)+1
1112  jst=(iptr/8)+1
1113  ipfld(jst:jst+ijk)=ifoval(1:ijk)
1114  iptr = iptr + ifoptr
1115 C PRINT *,'IFOVAL',IFOPTR,IPASS,KWIDE
1116 C CALL BINARY (IFOVAL,IPASS)
1117  IF (mod(iptr,8).NE.0) THEN
1118  iptr = iptr + 8 - mod(iptr,8)
1119  END IF
1120 C PRINT *,'IFOPTR =',IFOPTR,' ISOPTR =',ISOPTR
1121 C DETERMINE LOCATION FOR START
1122 C OF SECOND ORDER VALUES
1123  kbds(15) = iptr / 8 + 12
1124 C SAVE LOCATION OF SECOND ORDER VALUES
1125  CALL sbytec (ipfld,kbds(15),24,16)
1126 C MOVE IN SECOND ORDER PACKED VALUES
1127  ix = (isoptr + 32) / 32
1128 C CALL SBYTESC (IPFLD,ISOVAL,IPTR,32,0,IX)
1129  ijk=(isoptr/8)+1
1130  jst=(iptr/8)+1
1131  ipfld(jst:jst+ijk)=isoval(1:ijk)
1132  iptr = iptr + isoptr
1133 C PRINT *,'ISOVAL',ISOPTR,IX
1134 C CALL BINARY (ISOVAL,IX)
1135  nleft = mod(iptr+88,16)
1136  IF (nleft.NE.0) THEN
1137  nleft = 16 - nleft
1138  iptr = iptr + nleft
1139  END IF
1140 C COMPUTE LENGTH OF DATA PORTION
1141  len = iptr / 8
1142 C COMPUTE LENGTH OF BDS
1143  lenbds = len + 11
1144 C -----------------------------------
1145 C BYTES 1-3
1146 C THIS FUNCTION COMPLETED BELOW
1147 C WHEN LENGTH OF BDS IS KNOWN
1148  CALL sbytec (bds11,lenbds,0,24)
1149 C BYTE 4
1150  CALL sbytec (bds11,ibdsfl(1),24,1)
1151  CALL sbytec (bds11,ibdsfl(2),25,1)
1152  CALL sbytec (bds11,ibdsfl(3),26,1)
1153  CALL sbytec (bds11,ibdsfl(4),27,1)
1154 C ENTER NUMBER OF FILL BITS
1155  CALL sbytec (bds11,nleft,28,4)
1156 C BYTE 5-6
1157  IF (iscal2.LT.0) THEN
1158  CALL sbytec (bds11,1,32,1)
1159  iscal2 = - iscal2
1160  ELSE
1161  CALL sbytec (bds11,0,32,1)
1162  END IF
1163  CALL sbytec (bds11,iscal2,33,15)
1164 C
1165 C$ FILL OCTET 7-10 WITH THE REFERENCE VALUE
1166 C CONVERT THE FLOATING POINT OF YOUR MACHINE TO IBM370 32 BIT
1167 C FLOATING POINT NUMBER
1168 C REFERENCE VALUE
1169 C FIRST TEST TO SEE IF
1170 C ON 32 OR 64 BIT COMPUTER
1171 C CALL W3FI01(LW)
1172  IF (bit_size(lw).EQ.32) THEN
1173  CALL w3fi76 (refnce,iexp,imant,32)
1174  ELSE
1175  CALL w3fi76 (refnce,iexp,imant,64)
1176  END IF
1177  CALL sbytec (bds11,iexp,48,8)
1178  CALL sbytec (bds11,imant,56,24)
1179 C
1180 C BYTE 11
1181 C
1182  CALL sbytec (bds11,kbds(11),80,8)
1183 C
1184  klen = lenbds / 4 + 1
1185 C PRINT *,'BDS11 LISTING',4,LENBDS
1186 C CALL BINARY (BDS11,4)
1187 C PRINT *,'IPFLD LISTING'
1188 C CALL BINARY (IPFLD,KLEN)
1189  RETURN
1190  END
1191 C
1192 C> @brief Determine number of bits to contain value.
1193 C> @author Bill Cavanaugh @date 1993-06-23
1194 
1195 C> Calculate number of bits to contain value n, with a maximum of 32 bits.
1196 C>
1197 C> Program history log:
1198 C> - Bill Cavanaugh 1993-06-23
1199 C> - Mark Iredell 1995-10-31 Removed saves and prints
1200 C>
1201 C> @param[in] N Integer value
1202 C> @param[out] NBITS Number of bits to contain n
1203 C>
1204 C> @note Subprogram can be called from a multiprocessing environment.
1205 C>
1206 C> @author Bill Cavanaugh @date 1993-06-23
1207  SUBROUTINE fi7505 (N,NBITS)
1208 
1209  INTEGER N,NBITS
1210  INTEGER IBITS(31)
1211 C
1212  DATA ibits/1,3,7,15,31,63,127,255,511,1023,2047,
1213  * 4095,8191,16383,32767,65535,131071,262143,
1214  * 524287,1048575,2097151,4194303,8388607,
1215  * 16777215,33554431,67108863,134217727,268435455,
1216  * 536870911,1073741823,2147483647/
1217 C ----------------------------------------------------------------
1218 C
1219  DO 1000 nbits = 1, 31
1220  IF (n.LE.ibits(nbits)) THEN
1221  RETURN
1222  END IF
1223  1000 CONTINUE
1224  RETURN
1225  END
1226 C
1227 C> @brief Select block of data for packing.
1228 C> @author Bill Cavanaugh @date 1994-01-21
1229 
1230 C> Select a block of data for packing
1231 C>
1232 C> Program history log:
1233 C> - Bill Cavanaugh 1994-01-21
1234 C> - Mark Iredell 1995-10-31 Removed saves and prints
1235 C>
1236 C> - Return address if encounter set of same values
1237 C> @param[in] IWORK
1238 C> @param[in] ISTART
1239 C> @param[in] NPTS
1240 C> @param[out] MAX
1241 C> @param[out] MIN
1242 C> @param[out] INRNGE
1243 C>
1244 C> @note Subprogram can be called from a multiprocessing environment.
1245 C>
1246 C> @author Bill Cavanaugh @date 1994-01-21
1247  SUBROUTINE fi7513 (IWORK,ISTART,NPTS,MAX,MIN,INRNGE)
1248 
1249  INTEGER IWORK(*),NPTS,ISTART,INRNGE,INRNGA,INRNGB
1250  INTEGER MAX,MIN,MXVAL,MAXB,MINB,MXVALB
1251  INTEGER IBITS(31)
1252 C
1253  DATA ibits/1,3,7,15,31,63,127,255,511,1023,2047,
1254  * 4095,8191,16383,32767,65535,131071,262143,
1255  * 524287,1048575,2097151,4194303,8388607,
1256  * 16777215,33554431,67108863,134217727,268435455,
1257  * 536870911,1073741823,2147483647/
1258 C ----------------------------------------------------------------
1259 C IDENTIFY NEXT BLOCK OF DATA FOR PACKING AND
1260 C RETURN TO CALLER
1261 C ********************************************************************
1262  istrta = istart
1263 C
1264 C GET BLOCK A
1265  CALL fi7516 (iwork,npts,inrnga,istrta,
1266  * max,min,mxval,lwide)
1267 C ********************************************************************
1268 C
1269  istrtb = istrta + inrnga
1270  2000 CONTINUE
1271 C IF HAVE PROCESSED ALL DATA, RETURN
1272  IF (istrtb.GT.npts) THEN
1273 C NO MORE DATA TO LOOK AT
1274  inrnge = inrnga
1275  RETURN
1276  END IF
1277 C GET BLOCK B
1278  CALL fi7502 (iwork,istrtb,npts,isame)
1279  IF (isame.GE.15) THEN
1280 C PRINT *,'BLOCK B HAS ALL IDENTICAL VALUES'
1281 C PRINT *,'BLOCK A HAS INRNGE =',INRNGA
1282 C BLOCK B CONTAINS ALL IDENTICAL VALUES
1283  inrnge = inrnga
1284 C EXIT WITH BLOCK A
1285  RETURN
1286  END IF
1287 C GET BLOCK B
1288 C
1289  istrtb = istrta + inrnga
1290  CALL fi7516 (iwork,npts,inrngb,istrtb,
1291  * maxb,minb,mxvalb,lwideb)
1292 C PRINT *,'BLOCK A',INRNGA,' BLOCK B',INRNGB
1293 C ********************************************************************
1294 C PERFORM TREND ANALYSIS TO DETERMINE
1295 C IF DATA COLLECTION CAN BE IMPROVED
1296 C
1297  ktrnd = lwide - lwideb
1298 C PRINT *,'TREND',LWIDE,LWIDEB
1299  IF (ktrnd.LE.0) THEN
1300 C PRINT *,'BLOCK A - SMALLER, SHOULD EXTEND INTO BLOCK B'
1301  mxval = ibits(lwide)
1302 C
1303 C IF BLOCK A REQUIRES THE SAME OR FEWER BITS
1304 C LOOK AHEAD
1305 C AND GATHER THOSE DATA POINTS THAT CAN
1306 C BE RETAINED IN BLOCK A
1307 C BECAUSE THIS BLOCK OF DATA
1308 C USES FEWER BITS
1309 C
1310  CALL fi7518 (iret,iwork,npts,istrta,inrnga,inrngb,
1311  * max,min,lwide,mxval)
1312  IF(iret.EQ.1) GO TO 8000
1313 C PRINT *,'18 INRNGA IS NOW ',INRNGA
1314  IF (inrngb.LT.20) THEN
1315  RETURN
1316  ELSE
1317  GO TO 2000
1318  END IF
1319  ELSE
1320 C PRINT *,'BLOCK A - LARGER, B SHOULD EXTEND BACK INTO A'
1321  mxvalb = ibits(lwideb)
1322 C
1323 C IF BLOCK B REQUIRES FEWER BITS
1324 C LOOK BACK
1325 C SHORTEN BLOCK A BECAUSE NEXT BLOCK OF DATA
1326 C USES FEWER BITS
1327 C
1328  CALL fi7517 (iret,iwork,npts,istrtb,inrnga,
1329  * maxb,minb,lwideb,mxvalb)
1330  IF(iret.EQ.1) GO TO 8000
1331 C PRINT *,'17 INRNGA IS NOW ',INRNGA
1332  END IF
1333 C
1334 C PACK UP BLOCK A
1335 C UPDATA POINTERS
1336  8000 CONTINUE
1337  inrnge = inrnga
1338 C GET NEXT BLOCK A
1339  9000 CONTINUE
1340  RETURN
1341  END
1342 C
1343 C> @brief Scan number of points.
1344 C> @author Bill Cavanaugh @date 1994-01-21
1345 
1346 C> Scan forward from current position. collect points and
1347 C> determine maximum and minimum values and the number
1348 C> of points that are included. Forward search is terminated
1349 C> by encountering a set of identical values, by reaching
1350 C> the number of points selected or by reaching the end
1351 C> of data.
1352 C>
1353 C> Program history log:
1354 C> - Bill Cavavnaugh 1994-01-21
1355 C> - Mark Iredell 1995-10-31 Removed saves and prints
1356 C>
1357 C> - Return address if encounter set of same values
1358 C> @param[in] IWORK Data array
1359 C> @param[in] NPTS Number of points in data array
1360 C> @param[in] ISTART Starting location in data
1361 C> @param[out] INRNG Number of points selected
1362 C> @param[out] MAX Maximum value of points
1363 C> @param[out] MIN Minimum value of points
1364 C> @param[out] MXVAL Maximum value that can be contained in lwidth bits
1365 C> @param[out] LWIDTH Number of bits to contain max diff
1366 C>
1367 C> @note Subprogram can be called from a multiprocessing environment.
1368 C>
1369 C> @author Bill Cavanaugh @date 1994-01-21
1370  SUBROUTINE fi7516 (IWORK,NPTS,INRNG,ISTART,MAX,MIN,MXVAL,LWIDTH)
1371 
1372  INTEGER IWORK(*),NPTS,ISTART,INRNG,MAX,MIN,LWIDTH,MXVAL
1373  INTEGER IBITS(31)
1374 C
1375  DATA ibits/1,3,7,15,31,63,127,255,511,1023,2047,
1376  * 4095,8191,16383,32767,65535,131071,262143,
1377  * 524287,1048575,2097151,4194303,8388607,
1378  * 16777215,33554431,67108863,134217727,268435455,
1379  * 536870911,1073741823,2147483647/
1380 C ----------------------------------------------------------------
1381 C
1382  inrng = 1
1383  jq = istart + 19
1384  max = iwork(istart)
1385  min = iwork(istart)
1386  DO 1000 i = istart+1, jq
1387  CALL fi7502 (iwork,i,npts,isame)
1388  IF (isame.GE.15) THEN
1389  GO TO 5000
1390  END IF
1391  inrng = inrng + 1
1392  IF (iwork(i).GT.max) THEN
1393  max = iwork(i)
1394  ELSE IF (iwork(i).LT.min) THEN
1395  min = iwork(i)
1396  END IF
1397  1000 CONTINUE
1398  5000 CONTINUE
1399  krng = max - min
1400 C
1401  DO 9000 lwidth = 1, 31
1402  IF (krng.LE.ibits(lwidth)) THEN
1403 C PRINT *,'RETURNED',INRNG,' VALUES'
1404  RETURN
1405  END IF
1406  9000 CONTINUE
1407  RETURN
1408  END
1409 C
1410 C> @brief Scan backward.
1411 C> @author Bill Cavanaugh @date 1994-01-21
1412 
1413 C> Scan backwards until a value exceeds range of group b this may shorten group a
1414 C>
1415 C> Program history log:
1416 C> - Bill Cavanaugh 1994-01-21
1417 C> - Mark Iredell 1995-10-31 Removed saves and prints
1418 C> - Mark Iredell 1998-06-17 Removed alternate return
1419 C>
1420 C> @param[in] IWORK
1421 C> @param[in] ISTRTB
1422 C> @param[in] NPTS
1423 C> @param[in] INRNGA
1424 C> @param[out] IRET
1425 C> @param[out] MAXB
1426 C> @param[out] MINB
1427 C> @param MXVALB
1428 C> @param LWIDEB
1429 C>
1430 C> @note Subprogram can be called from a multiprocessing environment.
1431 C>
1432 C> @author Bill Cavanaugh @date 1994-01-21
1433  SUBROUTINE fi7517 (IRET,IWORK,NPTS,ISTRTB,INRNGA,
1434  * MAXB,MINB,MXVALB,LWIDEB)
1435 
1436  INTEGER IWORK(*),NPTS,ISTRTB,INRNGA
1437  INTEGER MAXB,MINB,LWIDEB,MXVALB
1438  INTEGER IBITS(31)
1439 C
1440  DATA ibits/1,3,7,15,31,63,127,255,511,1023,2047,
1441  * 4095,8191,16383,32767,65535,131071,262143,
1442  * 524287,1048575,2097151,4194303,8388607,
1443  * 16777215,33554431,67108863,134217727,268435455,
1444  * 536870911,1073741823,2147483647/
1445 C ----------------------------------------------------------------
1446  iret=0
1447 C PRINT *,' FI7517'
1448  npos = istrtb - 1
1449  itst = 0
1450  kset = inrnga
1451 C
1452  1000 CONTINUE
1453 C PRINT *,'TRY NPOS',NPOS,IWORK(NPOS),MAXB,MINB
1454  itst = itst + 1
1455  IF (itst.LE.kset) THEN
1456  IF (iwork(npos).GT.maxb) THEN
1457  IF ((iwork(npos)-minb).GT.mxvalb) THEN
1458 C PRINT *,'WENT OUT OF RANGE AT',NPOS
1459  iret=1
1460  RETURN
1461  ELSE
1462  maxb = iwork(npos)
1463  END IF
1464  ELSE IF (iwork(npos).LT.minb) THEN
1465  IF ((maxb-iwork(npos)).GT.mxvalb) THEN
1466 C PRINT *,'WENT OUT OF RANGE AT',NPOS
1467  iret=1
1468  RETURN
1469  ELSE
1470  minb = iwork(npos)
1471  END IF
1472  END IF
1473  inrnga = inrnga - 1
1474  npos = npos - 1
1475  GO TO 1000
1476  END IF
1477 C ----------------------------------------------------------------
1478 C
1479  9000 CONTINUE
1480  RETURN
1481  END
1482 C
1483 C> @brief Scan forward.
1484 C> @author Bill Cavanaugh @date 1994-01-21
1485 
1486 C> Scan forward from start of block b towards end of block b
1487 C> if next point under test forces a larger maxvala then
1488 C> terminate indicating last point tested for inclusion
1489 C> into block a.
1490 C>
1491 C> Program history log:
1492 C> - Bill Cavanaugh 1994-01-21
1493 C> - Mark Iredell 1995-10-31 Removed saves and prints
1494 C> - Mark Iredell 1998-06-17 Removed alternate return
1495 C>
1496 C> @param IWORK
1497 C> @param ISTRTA
1498 C> @param INRNGA
1499 C> @param INRNGB
1500 C> @param MAXA
1501 C> @param MINA
1502 C> @param LWIDEA
1503 C> @param MXVALA
1504 C> @param[in] NPTS
1505 C> @param[out] IRET
1506 C>
1507 C> @note Subprogram can be called from a multiprocessing environment.
1508 C>
1509 C> @author Bill Cavanaugh @date 1994-01-21
1510  SUBROUTINE fi7518 (IRET,IWORK,NPTS,ISTRTA,INRNGA,INRNGB,
1511  * MAXA,MINA,LWIDEA,MXVALA)
1512 
1513  INTEGER IWORK(*),NPTS,ISTRTA,INRNGA
1514  INTEGER MAXA,MINA,LWIDEA,MXVALA
1515  INTEGER IBITS(31)
1516 C
1517  DATA IBITS/1,3,7,15,31,63,127,255,511,1023,2047,
1518  * 4095,8191,16383,32767,65535,131071,262143,
1519  * 524287,1048575,2097151,4194303,8388607,
1520  * 16777215,33554431,67108863,134217727,268435455,
1521  * 536870911,1073741823,2147483647/
1522 C ----------------------------------------------------------------
1523  iret=0
1524 C PRINT *,' FI7518'
1525  npos = istrta + inrnga
1526  itst = 0
1527 C
1528  1000 CONTINUE
1529  itst = itst + 1
1530  IF (itst.LE.inrngb) THEN
1531 C PRINT *,'TRY NPOS',NPOS,IWORK(NPOS),MAXA,MINA
1532  IF (iwork(npos).GT.maxa) THEN
1533  IF ((iwork(npos)-mina).GT.mxvala) THEN
1534 C PRINT *,'FI7518A -',ITST,' RANGE EXCEEDS MAX'
1535  iret=1
1536  RETURN
1537  ELSE
1538  maxa = iwork(npos)
1539  END IF
1540  ELSE IF (iwork(npos).LT.mina) THEN
1541  IF ((maxa-iwork(npos)).GT.mxvala) THEN
1542 C PRINT *,'FI7518B -',ITST,' RANGE EXCEEDS MAX'
1543  iret=1
1544  RETURN
1545  ELSE
1546  mina = iwork(npos)
1547  END IF
1548  END IF
1549  inrnga = inrnga + 1
1550 C PRINT *,' ',ITST,INRNGA
1551  npos = npos +1
1552  GO TO 1000
1553  END IF
1554 C ----------------------------------------------------------------
1555  9000 CONTINUE
1556  RETURN
1557  END
subroutine gbytec(IN, IOUT, ISKIP, NBYTE)
Wrapper for gbytesc() limiting NSKIP and N to 0 and 1.
Definition: gbytec.f:14
subroutine sbytec(OUT, IN, ISKIP, NBYTE)
This is a wrapper for sbytesc()
Definition: sbytec.f:14
subroutine sbytesc(OUT, IN, ISKIP, NBYTE, NSKIP, N)
Store bytes - pack bits: Put arbitrary size values into a packed bit string, taking the low order bit...
Definition: sbytesc.f:17
subroutine w3fi58(IFIELD, NPTS, NWORK, NPFLD, NBITS, LEN, KMIN)
Converts an array of integer numbers into an array of positive differences (number(s) - minimum value...
Definition: w3fi58.f:39
subroutine w3fi59(FIELD, NPTS, NBITS, NWORK, NPFLD, ISCALE, LEN, RMIN)
Converts an array of single precision real numbers into an array of positive scaled differences (numb...
Definition: w3fi59.f:48
subroutine fi7516(IWORK, NPTS, INRNG, ISTART, MAX, MIN, MXVAL, LWIDTH)
Scan number of points.
Definition: w3fi75.f:1371
subroutine fi7513(IWORK, ISTART, NPTS, MAX, MIN, INRNGE)
Select block of data for packing.
Definition: w3fi75.f:1248
subroutine fi7501(IWORK, IPFLD, NPTS, IBDSFL, BDS11, LEN, LENBDS, PDS, REFNCE, ISCAL2, KWIDE)
BDS second order packing.
Definition: w3fi75.f:537
subroutine fi7503(IWORK, IPFLD, NPTS, IBDSFL, BDS11, LEN, LENBDS, PDS, REFNCE, ISCAL2, KWIDE, IGDS)
Row by row, col by col packing.
Definition: w3fi75.f:902
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 fi7518(IRET, IWORK, NPTS, ISTRTA, INRNGA, INRNGB, MAXA, MINA, LWIDEA, MXVALA)
Scan forward.
Definition: w3fi75.f:1512
subroutine fi7502(IWORK, ISTART, NPTS, ISAME)
Second order same value collection.
Definition: w3fi75.f:857
subroutine fi7505(N, NBITS)
Determine number of bits to contain value.
Definition: w3fi75.f:1208
subroutine fi7517(IRET, IWORK, NPTS, ISTRTB, INRNGA, MAXB, MINB, MXVALB, LWIDEB)
Scan backward.
Definition: w3fi75.f:1435
subroutine w3fi76(PVAL, KEXP, KMANT, KBITS)
Converts floating point number from machine representation to grib representation (ibm370 32 bit f....
Definition: w3fi76.f:24
subroutine w3fi82(IFLD, FVAL1, FDIFF1, NPTS, PDS, IGDS)
Accept an input array, convert to array of second differences.
Definition: w3fi82.f:31