NCEPLIBS-w3emc 2.12.0
Loading...
Searching...
No Matches
w3fi75.f
Go to the documentation of this file.
1C> @file
2C> @brief GRIB pack data and form bds octets(1-11)
3C> @author M. Farley @date 1992-07-10
4
5C> This routine packs a grib field and forms octets(1-11)
6C> of the binary data section (bds).
7C>
8C> Program history log:
9C> - M. Farley 1992-07-10 Original author
10C> - Ralph Jones 1992-10-01 Correction for field of constant data
11C> - Ralph Jones 1992-10-16 Get rid of arrays fp and int
12C> - Bill Cavanaugh 1993-08-06 Added routines fi7501, fi7502, fi7503
13C> To allow second order packing in pds.
14C> - John Stackpole 1993-07-21 Assorted repairs to get 2nd diff pack in
15C> - Bill Cavanaugh 1993-10-28 Commented out nonoperational prints and
16C> Write statements
17C> - Bill Cavanaugh 1993-12-15 Corrected location of start of first order
18C> Values and start of second order values to
19C> Reflect a byte location in the bds instead
20C> Of an offset in subroutine fi7501().
21C> - Bill Cavanaugh 1994-01-27 Added igds as input argument to this routine
22C> And added pds and igds arrays to the call to
23C> W3fi82 to provide information needed for
24C> Boustrophedonic processing.
25C> - Bill Cavanaugh 1994-05-25 Subroutine fi7503 has been added to provide
26C> For row by row or column by column second
27C> Order packing. this feature can be activated
28C> By setting ibdsfl(7) to zero.
29C> - Bill Cavanaugh 1994-07-08 Commented out print statements used for debug
30C> - M. Farley 1994-11-22 Enlarged work arrays to handle .5degree grids
31C> - Ralph Jones 1995-06-01 Correction for number of unused bits at end
32C> Of section 4, in bds byte 4, bits 5-8.
33C> - Mark Iredell 1995-10-31 Removed saves and prints
34C> - Stephen Gilbert 2001-06-06 Changed gbyte/sbyte calls to refer to
35C> Wesley ebisuzaki's endian independent
36C> versions gbytec/sbytec.
37C> Use f90 standard routine bit_size to get
38C> number of bits in an integer instead of w3fi01.
39C>
40C> @param[in] IBITL
41C> - 0, computer computes packing length from power of 2 that best fits the data.
42C> - 8, 12, etc. computer rescales data to fit into set number of bits.
43C> @param[in] ITYPE
44C> - 0 = if input data is floating point (fld)
45C> - 1 = If input data is integer (ifld)
46C> @param[in] ITOSS
47C> - 0 = no bit map is included (don't toss data)
48C> - 1 = Toss null data according to ibmap
49C> @param[in] FLD Real array of data to be packed if itype=0
50C> @param[in] IFLD Integer array to be packed if itype=1
51C> @param[in] IBMAP Bit map supplied from user
52C> @param[in] IBDSFL Integer array containing table 11 flag info
53C> BDS octet 4:
54C> - (1)
55C> - 0 = grid point data
56C> - 1 = spherical harmonic coefficients
57C> - (2)
58C> - 0 = simple packing
59C> - 1 = second order packing
60C> - (3)
61C> - 0 = original data were floating point values
62C> - 1 = original data were integer values
63C> - (4)
64C> - 0 = no additional flags at octet 14
65C> - 1 = octet 14 contains flag bits 5-12
66C> - (5) 0 = reserved - always set to 0
67C> - (6)
68C> - 0 = single datum at each grid point
69C> - 1 = matrix of values at each grid point
70C> - (7)
71C> - 0 = no secondary bit maps
72C> - 1 = secondary bit maps present
73C> - (8)
74C> - 0 = second order values have constant width
75C> - 1 = second order values have different widths
76C> @param[in] NPTS Number of gridpoints in array to be packed
77C> @param[in] IGDS Array of gds information
78C> @param[out] BDS11 First 11 octets of bds
79C> @param[out] PFLD Packed grib field
80C> @param[out] LEN Length of pfld
81C> @param[out] LENBDS Length of bds
82C> @param[out] IBERR 1, error converting ieee f.p. number to ibm370 f.p.
83C> @param IPFLD
84C> @param PDS
85C>
86C> @note Subprogram can be called from a multiprocessing environment.
87C>
88 SUBROUTINE w3fi75 (IBITL,ITYPE,ITOSS,FLD,IFLD,IBMAP,IBDSFL,
89 & NPTS,BDS11,IPFLD,PFLD,LEN,LENBDS,IBERR,PDS,IGDS)
90C
91 REAL FLD(*)
92C REAL FWORK(260000)
93C
94C FWORK CAN USE DYNAMIC ALLOCATION OF MEMORY ON CRAY
95C
96 REAL FWORK(NPTS)
97 REAL RMIN,REFNCE
98C
99 character(len=1) IPFLD(*)
100 INTEGER IBDSFL(*)
101 INTEGER IBMAP(*)
102 INTEGER IFLD(*),IGDS(*)
103C INTEGER IWORK(260000)
104C
105C IWORK CAN USE DYNAMIC ALLOCATION OF MEMORY ON CRAY
106C
107 INTEGER IWORK(NPTS)
108C
109 LOGICAL CONST
110C
111 CHARACTER * 1 BDS11(11),PDS(*)
112 CHARACTER * 1 PFLD(*)
113C
114C 1.0 PACK THE FIELD.
115C
116C 1.1 TOSS DATA IF BITMAP BEING USED,
117C MOVING 'DATA' TO WORK AREA...
118C
119 const = .false.
120 iberr = 0
121 iw = 0
122C
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
141C
142C ELSE, JUST MOVE DATA TO WORK ARRAY
143C
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
155C
156C 1.2 CONVERT DATA IF NEEDED PRIOR TO PACKING.
157C (INTEGER TO F.P. OR F.P. TO INTEGER)
158C ITYPE = 0...FLOATING POINT DATA
159C IBITL = 0...PACK IN LEAST # BITS...CONVERT TO INTEGER
160C ITYPE = 1...INTEGER DATA
161C IBITL > 0...PACK IN FIXED # BITS...CONVERT TO FLOATING POINT
162C
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
172C
173C 1.3 PACK THE DATA.
174C
175 IF (ibdsfl(2).NE.0) THEN
176C SECOND ORDER PACKING
177C
178C PRINT*,' DOING SECOND ORDER PACKING...'
179 IF (ibitl.EQ.0) THEN
180C
181C PRINT*,' AND VARIABLE BIT PACKING'
182C
183C WORKING WITH INTEGER VALUES
184C SINCE DOING VARIABLE BIT PACKING
185C
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
195C EXTRACT MINIMA
196 DO 400 i = 1, npts
197C IF (IWORK(I).LT.0) THEN
198C PRINT *,'MINIMA 400',I,IWORK(I),NPTS
199C END IF
200 iwork(i) = iwork(i) - min
201 400 CONTINUE
202 refnce = min
203 idiff = max - min
204C PRINT *,'REFERENCE VALUE',REFNCE
205C
206C WRITE (6,FMT='('' MINIMA REMOVED = '',/,
207C & 10(3X,10I10,/))') (IWORK(I),I=1,6)
208C WRITE (6,FMT='('' END OF ARRAY = '',/,
209C & 10(3X,10I10,/))') (IWORK(I),I=NPTS-5,NPTS)
210C
211C FIND BIT WIDTH OF IDIFF
212C
213 CALL fi7505 (idiff,kwide)
214C PRINT*,' BIT WIDTH FOR ORIGINAL DATA', KWIDE
215 iscal2 = 0
216C
217C MULTIPLICATIVE SCALE FACTOR SET TO 1
218C IN ANTICIPATION OF POSSIBLE USE IN GLAHN 2DN DIFF
219C
220 scal2 = 1.
221C
222 ELSE
223C
224C PRINT*,' AND FIXED BIT PACKING, IBITL = ', IBITL
225C FIXED BIT PACKING
226C - LENGTH OF FIELD IN IBITL
227C - MUST BE REAL DATA
228C FLOATING POINT INPUT
229C
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
240C PRINT *,'100 REFERENCE',REFNCE
241C EXTRACT MINIMA
242 DO 200 i = 1, npts
243 fwork(i) = fwork(i) - rmin
244 200 CONTINUE
245C PRINT *,'REFERENCE VALUE',REFNCE
246C WRITE (6,FMT='('' MINIMA REMOVED = '',/,
247C & 10(3X,10F8.2,/))') (FWORK(I),I=1,6)
248C WRITE (6,FMT='('' END OF ARRAY = '',/,
249C & 10(3X,10F8.2,/))') (FWORK(I),I=NPTS-5,NPTS)
250C FIND LARGEST DELTA
251 idelt = nint(rmax - rmin)
252C DO BINARY SCALING
253C FIND OUT WHAT BINARY SCALE FACTOR
254C PERMITS CONTAINMENT OF
255C LARGEST DELTA
256 CALL fi7505 (idelt,iwide)
257C
258C BINARY SCALING
259C
260 iscal2 = iwide - ibitl
261C PRINT *,'SCALING NEEDED TO FIT =',ISCAL2
262C PRINT*,' RANGE OF = ',IDELT
263C
264C EXPAND DATA WITH BINARY SCALING
265C 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
273C
274C *****************************************************************
275C
276C FOLLOWING IS FOR GLAHN SECOND DIFFERENCING
277C NOT STANDARD GRIB
278C
279C TEST FOR SECOND DIFFERENCE PACKING
280C BASED OF SIZE OF PDS - SIZE IN FIRST 3 BYTES
281C
282 CALL gbytec(pds,ipdsiz,0,24)
283 IF (ipdsiz.EQ.50) THEN
284C PRINT*,' DO SECOND DIFFERENCE PACKING '
285C
286C GLAHN PACKING TO 2ND DIFFS
287C
288C WRITE (6,FMT='('' CALL TO W3FI82 WITH = '',/,
289C & 10(3X,10I6,/))') (IWORK(I),I=1,NPTS)
290C
291 CALL w3fi82 (iwork,fval1,fdiff1,npts,pds,igds)
292C
293C PRINT *,'GLAHN',FVAL1,FDIFF1
294C WRITE (6,FMT='('' OUT FROM W3FI82 WITH = '',/,
295C & 10(3X,10I6,/))') (IWORK(I),I=1,NPTS)
296C
297C MUST NOW RE-REMOVE THE MINIMUM VALUE
298C OF THE SECOND DIFFERENCES TO ASSURE
299C ALL POSITIVE NUMBERS FOR SECOND ORDER GRIB PACKING
300C
301C ORIGINAL REFERENCE VALUE ADDED TO FIRST POINT
302C VALUE FROM THE 2ND DIFF PACKER TO BE ADDED
303C BACK IN WHEN THE 2ND DIFF VALUES ARE
304C RECONSTRUCTED BACK TO THE BASIC VALUES
305C
306C ALSO, THE REFERENCE VALUE IS
307C POWER-OF-TWO SCALED TO MATCH
308C FVAL1. ALL OF THIS SCALING
309C WILL BE REMOVED AFTER THE
310C GLAHN SECOND DIFFERENCING IS UNDONE.
311C THE SCALING FACTOR NEEDED TO DO THAT
312C IS SAVED IN THE PDS AS A SIGNED POSITIVE
313C TWO BYTE INTEGER
314C
315C THE SCALING FOR THE 2ND DIF PACKED
316C VALUES IS PROPERLY SET TO ZERO
317C
318 fval1 = fval1 + refnce*scal2
319C FIRST TEST TO SEE IF
320C ON 32 OR 64 BIT COMPUTER
321C 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)
329C
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)
337C
338C TURN ISCAL2 INTO SIGNED POSITIVE INTEGER
339C AND STORE IN TWO BYTES
340C
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
348C
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
358C EXTRACT MINIMA
359 DO 710 i = 1, npts
360 iwork(i) = iwork(i) - min
361 710 CONTINUE
362 refnce = min
363C PRINT *,'710 REFERENCE',REFNCE
364 iscal2 = 0
365C
366C AND RESET VALUE OF KWIDE - THE BIT WIDTH
367C FOR THE RANGE OF THE VALUES
368C
369 idiff = max - min
370 CALL fi7505 (idiff,kwide)
371C
372C PRINT*,'BIT WIDTH (KWIDE) OF 2ND DIFFS', KWIDE
373C
374C **************************** END OF GLAHN PACKING ************
375 ELSE IF (ibdsfl(2).EQ.1.AND.ibdsfl(7).EQ.0) THEN
376C HAVE SECOND ORDER PACKING WITH NO SECOND ORDER
377C 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
382C WRITE (6,FMT='('' CALL TO FI7501 WITH = '',/,
383C & 10(3X,10I6,/))') (IWORK(I),I=1,NPTS)
384C WRITE (6,FMT='('' END OF ARRAY = '',/,
385C & 10(3X,10I6,/))') (IWORK(I),I=NPTS-5,NPTS)
386C PRINT*,' REFNCE,ISCAL2, KWIDE AT CALL TO FI7501',
387C & REFNCE, ISCAL2,KWIDE
388C
389C SECOND ORDER PACKING
390C
391 CALL fi7501 (iwork,ipfld,npts,ibdsfl,bds11,
392 * len,lenbds,pds,refnce,iscal2,kwide)
393C
394C BDS COMPLETELY ASSEMBLED IN FI7501 FOR SECOND ORDER
395C PACKING.
396C
397 ELSE
398C SIMPLE PACKING
399C
400C PRINT*,' SIMPLE FIRST ORDER PACKING...'
401 IF (ibitl.EQ.0) THEN
402C PRINT*,' WITH VARIABLE BIT LENGTH'
403C
404C WITH VARIABLE BIT LENGTH, ADJUSTED
405C TO ACCOMMODATE LARGEST VALUE
406C BINARY SCALING ALWAYS = 0
407C
408 CALL w3fi58(iwork,npts,iwork,pfld,nbits,len,kmin)
409 rmin = kmin
410 refnce = rmin
411 iscale = 0
412C PRINT*,' BIT LENGTH CAME OUT AT ...',NBITS
413C
414C SET CONST .TRUE. IF ALL VALUES ARE THE SAME
415C
416 IF (len.EQ.0.AND.nbits.EQ.0) const = .true.
417C
418 ELSE
419C PRINT*,' FIXED BIT LENGTH, IBITL = ', IBITL
420C
421C FIXED BIT LENGTH PACKING (VARIABLE PRECISION)
422C VALUES SCALED BY POWER OF 2 (ISCALE) TO
423C FIT LARGEST VALUE INTO GIVEN BIT LENGTH (IBITL)
424C
425 CALL w3fi59(fwork,npts,ibitl,iwork,pfld,iscale,len,rmin)
426 refnce = rmin
427C PRINT *,' SCALING NEEDED TO FIT IS ...', ISCALE
428 nbits = ibitl
429C
430C SET CONST .TRUE. IF ALL VALUES ARE THE SAME
431C
432 IF (len.EQ.0) THEN
433 const = .true.
434 nbits = 0
435 END IF
436 END IF
437C
438C$ COMPUTE LENGTH OF BDS IN OCTETS
439C
440 inum = npts * nbits + 88
441C PRINT *,'NUMBER OF BITS BEFORE FILL ADDED',INUM
442C
443C 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
450C PRINT *,'NUMBER OF BITS AFTER FILL ADDED',INUM
451C LENGTH OF BDS IN BYTES
452 lenbds = inum / 8
453C
454C 2.0 FORM THE BINARY DATA SECTION (BDS).
455C
456C CONCANTENATE ALL FIELDS FOR BDS
457C
458C BYTES 1-3
459 CALL sbytec (bds11,lenbds,0,24)
460C
461C BYTE 4
462C 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)
467C NR OF FILL BITS
468 CALL sbytec (bds11,nfill,28,4)
469C
470C$ FILL OCTETS 5-6 WITH THE SCALE FACTOR.
471C
472C 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
480C
481C$ FILL OCTET 7-10 WITH THE REFERENCE VALUE
482C CONVERT THE FLOATING POINT OF YOUR MACHINE TO IBM370 32 BIT
483C FLOATING POINT NUMBER
484C
485C BYTE 7-10
486C REFERENCE VALUE
487C FIRST TEST TO SEE IF
488C ON 32 OR 64 BIT COMPUTER
489C 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)
497C
498C
499C$ FILL OCTET 11 WITH THE NUMBER OF BITS.
500C
501C BYTE 11
502 CALL sbytec (bds11,nbits,80,8)
503 END IF
504C
505 RETURN
506 END
507C
508C> @brief BDS second order packing.
509C> @author Bill Cavanaugh @date 1993-08-06
510
511C> Perform secondary packing on grid point data, generating all BDS information.
512C>
513C> Program history log:
514C> - Bill Cavanaugh 1993-08-06
515C> - Bill Cavanaugh 1993-12-15 Corrected location of start of first order
516C> values and start of second order values to reflect a byte location in the
517C> BDS instead of an offset.
518C> - Mark Iredell 1995-10-31 Removed saves and prints
519C>
520C> @param[in] IWORK Integer source array
521C> @param[in] NPTS Number of points in iwork
522C> @param[in] IBDSFL Flags
523C> @param[out] IPFLD Contains bds from byte 12 on
524C> @param[out] BDS11 Contains first 11 bytes for bds
525C> @param[out] LEN Number of bytes from 12 on
526C> @param[out] LENBDS Total length of bds
527C> @param PDS
528C> @param REFNCE
529C> @param ISCAL2
530C> @param KWIDE
531C>
532C> @note Subprogram can be called from a multiprocessing environment.
533C>
534C> @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(*)
539C
540 REAL REFNCE
541C
542 INTEGER ISCAL2,KWIDE
543 INTEGER LENBDS
544 CHARACTER(len=1) IPFLD(*)
545 INTEGER LEN,KBDS(22)
546 INTEGER IWORK(*)
547C OCTET NUMBER IN SECTION, FIRST ORDER PACKING
548C INTEGER KBDS(12)
549C FLAGS
550 INTEGER IBDSFL(*)
551C EXTENDED FLAGS
552C INTEGER KBDS(14)
553C OCTET NUMBER FOR SECOND ORDER PACKING
554C INTEGER KBDS(15)
555C NUMBER OF FIRST ORDER VALUES
556C INTEGER KBDS(17)
557C NUMBER OF SECOND ORDER PACKED VALUES
558C INTEGER KBDS(19)
559C WIDTH OF SECOND ORDER PACKING
560 character(len=1) ISOWID(400000)
561C SECONDARY BIT MAP
562 character(len=1) ISOBMP(65600)
563C FIRST ORDER PACKED VALUES
564 character(len=1) IFOVAL(400000)
565C SECOND ORDER PACKED VALUES
566 character(len=1) ISOVAL(800000)
567C
568C INTEGER KBDS(11)
569C BIT WIDTH TABLE
570 INTEGER IBITS(31)
571C
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/
578C ----------------------------------
579C INITIALIZE ARRAYS
580
581 DO i = 1, 400000
582 ifoval(i) = char(0)
583 isowid(i) = char(0)
584 ENDDO
585C
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
592C INITIALIZE POINTERS
593C SECONDARY BIT WIDTH POINTER
594 iwdptr = 0
595C SECONDARY BIT MAP POINTER
596 ibmp2p = 0
597C FIRST ORDER VALUE POINTER
598 ifoptr = 0
599C BYTE POINTER TO START OF 1ST ORDER VALUES
600 kbds(12) = 0
601C BYTE POINTER TO START OF 2ND ORDER VALUES
602 kbds(15) = 0
603C TO CONTAIN NUMBER OF FIRST ORDER VALUES
604 kbds(17) = 0
605C TO CONTAIN NUMBER OF SECOND ORDER VALUES
606 kbds(19) = 0
607C SECOND ORDER PACKED VALUE POINTER
608 isoptr = 0
609C =======================================================
610C
611C DATA IS IN IWORK
612C
613 kbds(11) = kwide
614C
615C DATA PACKING
616C
617 iter = 0
618 inext = 1
619 istart = 1
620C -----------------------------------------------------------
621 kount = 0
622C DO 1 I = 1, NPTS, 10
623C PRINT *,I,(IWORK(K),K=I, I+9)
624C 1 CONTINUE
625 2000 CONTINUE
626 iter = iter + 1
627C 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
635C
636C LOOK FOR REPITITIONS OF A SINGLE VALUE
637 CALL fi7502 (iwork,istart,npts,isame)
638 IF (isame.GE.15) THEN
639 kount = kount + 1
640C PRINT *,'FI7501 - FOUND IDENTICAL SET OF ',ISAME
641 mxdiff = 0
642 kpts = isame
643 ELSE
644C
645C LOOK FOR SETS OF VALUES IN TREND SELECTED RANGE
646 CALL fi7513 (iwork,istart,npts,nmax,nmin,inrnge)
647C PRINT *,'ISTART ',ISTART,' INRNGE',INRNGE,NMAX,NMIN
648 iend = istart + inrnge - 1
649C DO 2199 NM = ISTART, IEND, 10
650C PRINT *,' ',(IWORK(NM+JK),JK=0,9)
651C2199 CONTINUE
652 mxdiff = nmax - nmin
653 kpts = inrnge
654 END IF
655 2200 CONTINUE
656C PRINT *,' RANGE ',MXDIFF,' MAX',NMAX,' MIN',NMIN
657C INCREMENT NUMBER OF FIRST ORDER VALUES
658 kbds(17) = kbds(17) + 1
659C 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)
669C 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
682C PRINT *,KWIDE,' IFOVAL=',NMIN,IWORK(ISTART),KPTS
683C 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
688C PRINT *,' SECOND ORDER VALUES'
689C PRINT *,(IWORK(ISTART+I),I=0,KPTS-1)
690 END IF
691C ADD TO SECOND ORDER BITMAP
692 CALL sbytec (isobmp,1,ibmp2p,1)
693 ibmp2p = ibmp2p + kpts
694 istart = istart + kpts
695 GO TO 2000
696C --------------------------------------------------------------
697 4000 CONTINUE
698C PRINT *,'THERE WERE ',ITER,' SECOND ORDER GROUPS'
699C PRINT *,'THERE WERE ',KOUNT,' STRINGS OF CONSTANTS'
700C CONCANTENATE ALL FIELDS FOR BDS
701C
702C REMAINDER GOES INTO IPFLD
703 iptr = 0
704C BYTES 12-13
705C VALUE FOR N1
706C LEAVE SPACE FOR THIS
707 iptr = iptr + 16
708C BYTE 14
709C 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
726C BYTES 15-16
727C SKIP OVER VALUE FOR N2
728 iptr = iptr + 16
729C BYTES 17-18
730C P1
731 CALL sbytec (ipfld,kbds(17),iptr,16)
732 iptr = iptr + 16
733C BYTES 19-20
734C P2
735 CALL sbytec (ipfld,kbds(19),iptr,16)
736 iptr = iptr + 16
737C BYTE 21 - RESERVED LOCATION
738 CALL sbytec (ipfld,0,iptr,8)
739 iptr = iptr + 8
740C BYTES 22 - ?
741C WIDTHS OF SECOND ORDER PACKING
742 ix = (iwdptr + 32) / 32
743C 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
748C SECONDARY BIT MAP
749 ij = (ibmp2p + 32) / 32
750C 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
758C DETERMINE LOCATION FOR START
759C OF FIRST ORDER PACKED VALUES
760 kbds(12) = iptr / 8 + 12
761C STORE LOCATION
762 CALL sbytec (ipfld,kbds(12),0,16)
763C MOVE IN FIRST ORDER PACKED VALUES
764 ipass = (ifoptr + 32) / 32
765C 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
773C PRINT *,'IFOPTR =',IFOPTR,' ISOPTR =',ISOPTR
774C DETERMINE LOCATION FOR START
775C OF SECOND ORDER VALUES
776 kbds(15) = iptr / 8 + 12
777C SAVE LOCATION OF SECOND ORDER VALUES
778 CALL sbytec (ipfld,kbds(15),24,16)
779C MOVE IN SECOND ORDER PACKED VALUES
780 ix = (isoptr + 32) / 32
781c 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
791C COMPUTE LENGTH OF DATA PORTION
792 len = iptr / 8
793C COMPUTE LENGTH OF BDS
794 lenbds = len + 11
795C -----------------------------------
796C BYTES 1-3
797C THIS FUNCTION COMPLETED BELOW
798C WHEN LENGTH OF BDS IS KNOWN
799 CALL sbytec (bds11,lenbds,0,24)
800C 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)
805C ENTER NUMBER OF FILL BITS
806 CALL sbytec (bds11,nleft,28,4)
807C 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)
815C
816C$ FILL OCTET 7-10 WITH THE REFERENCE VALUE
817C CONVERT THE FLOATING POINT OF YOUR MACHINE TO IBM370 32 BIT
818C FLOATING POINT NUMBER
819C REFERENCE VALUE
820C FIRST TEST TO SEE IF
821C ON 32 OR 64 BIT COMPUTER
822C 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)
830C
831C BYTE 11
832C
833 CALL sbytec (bds11,kbds(11),80,8)
834C
835 RETURN
836 END
837C
838C> @brief Second order same value collection.
839C> @author Bill Cavanaugh @date 1993-06-23
840
841C> Collect sequential same values for processing
842C> as second order value for grib messages.
843C>
844C> Program history log:
845C> - Bill Cavanaugh 1993-06-23
846C> - Mark Iredell 1995-10-31 Removed saves and prints
847C>
848C> @param[in] IWORK Array containing source data
849C> @param[in] ISTART Starting location for this test
850C> @param[in] NPTS Number of points in iwork
851C> @param[out] ISAME Number of sequential points having the same value
852C>
853C> @note Subprogram can be called from a multiprocessing environment.
854C>
855C> @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
863C -------------------------------------------------------------
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
873C
874C> @brief Row by row, col by col packing.
875C> @author Bill Cavanaugh @date 1993-08-06
876
877C> Perform row by row or column by column packing
878C> generating all bds information.
879C>
880C> Program history log:
881C> - Bill Cavanaugh 1993-08-06
882C> - Mark Iredell 1995-10-31 Removed saves and prints
883C>
884C> @param[in] IWORK Integer source array
885C> @param[in] NPTS Number of points in iwork
886C> @param[in] IBDSFL Flags
887C> @param[out] IPFLD Contains bds from byte 12 on
888C> @param[out] BDS11 Contains first 11 bytes for bds
889C> @param[out] LEN Number of bytes from 12 on
890C> @param[out] LENBDS Total length of bds
891C> @param PDS
892C> @param REFNCE
893C> @param ISCAL2
894C> @param KWIDE
895C> @param IGDS
896C>
897C> @note Subprogram can be called from a multiprocessing environment.
898C>
899C> @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(*)
904C
905 REAL REFNCE
906C
907 INTEGER ISCAL2,KWIDE
908 INTEGER LENBDS
909 INTEGER IGDS(*)
910 INTEGER LEN,KBDS(22)
911 INTEGER IWORK(*)
912C OCTET NUMBER IN SECTION, FIRST ORDER PACKING
913C INTEGER KBDS(12)
914C FLAGS
915 INTEGER IBDSFL(*)
916C EXTENDED FLAGS
917C INTEGER KBDS(14)
918C OCTET NUMBER FOR SECOND ORDER PACKING
919C INTEGER KBDS(15)
920C NUMBER OF FIRST ORDER VALUES
921C INTEGER KBDS(17)
922C NUMBER OF SECOND ORDER PACKED VALUES
923C INTEGER KBDS(19)
924C WIDTH OF SECOND ORDER PACKING
925 character(len=1) ISOWID(400000)
926C SECONDARY BIT MAP
927 character(len=1) ISOBMP(65600)
928C FIRST ORDER PACKED VALUES
929 character(len=1) IFOVAL(400000)
930C SECOND ORDER PACKED VALUES
931 character(len=1) ISOVAL(800000)
932C
933C INTEGER KBDS(11)
934C ----------------------------------
935C INITIALIZE ARRAYS
936C
937 DO i = 1, 400000
938 ifoval(i) = char(0)
939 isowid(i) = char(0)
940 ENDDO
941C
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
948C INITIALIZE POINTERS
949C SECONDARY BIT WIDTH POINTER
950 iwdptr = 0
951C SECONDARY BIT MAP POINTER
952 ibmp2p = 0
953C FIRST ORDER VALUE POINTER
954 ifoptr = 0
955C BYTE POINTER TO START OF 1ST ORDER VALUES
956 kbds(12) = 0
957C BYTE POINTER TO START OF 2ND ORDER VALUES
958 kbds(15) = 0
959C TO CONTAIN NUMBER OF FIRST ORDER VALUES
960 kbds(17) = 0
961C TO CONTAIN NUMBER OF SECOND ORDER VALUES
962 kbds(19) = 0
963C SECOND ORDER PACKED VALUE POINTER
964 isoptr = 0
965C =======================================================
966C BUILD SECOND ORDER BIT MAP IN EITHER
967C ROW BY ROW OR COL BY COL FORMAT
968 IF (iand(igds(13),32).NE.0) THEN
969C COLUMN BY COLUMN
970 kout = igds(4)
971 kin = igds(5)
972C PRINT *,'COLUMN BY COLUMN',KOUT,KIN
973 ELSE
974C ROW BY ROW
975 kout = igds(5)
976 kin = igds(4)
977C PRINT *,'ROW BY ROW',KOUT,KIN
978 END IF
979 kbds(17) = kout
980 kbds(19) = npts
981C
982C DO 4100 J = 1, NPTS, 53
983C WRITE (6,4101) (IWORK(K),K=J,J+52)
984 4101 FORMAT (1x,25i4)
985C PRINT *,' '
986C4100 CONTINUE
987C
988C INITIALIZE BIT MAP POINTER
989 ibmp2p = 0
990C 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
1002C CALL BINARY(ISOBMP,LEN)
1003C
1004C PROCESS OUTER LOOP OF ROW BY ROW OR COL BY COL
1005C
1006 kptr = 1
1007 kbds(11) = kwide
1008 DO 6000 i = 1, kout
1009C IN CURRENT ROW OR COL
1010C 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
1019C SAVE FIRST ORDER VALUE
1020 CALL sbytec (ifoval,lowest,ifoptr,kwide)
1021 ifoptr = ifoptr + kwide
1022C PRINT *,'FOVAL',I,LOWEST,KWIDE
1023C SUBTRACT FIRST ORDER VALUE FROM OTHER VALS
1024C 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
1034C HOW MANY BITS TO CONTAIN LARGEST SECOND
1035C ORDER VALUE IN SEGMENT
1036 CALL fi7505 (ibig,nwide)
1037C SAVE BIT WIDTH
1038 CALL sbytec (isowid,nwide,iwdptr,8)
1039 iwdptr = iwdptr + 8
1040C PRINT *,I,'SOVAL',IBIG,' IN',NWIDE,' BITS'
1041C WRITE (6,4101) (IWORK(K),K=KPTR,KPTR+52)
1042C 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
1049C =======================================================
1050C CONCANTENATE ALL FIELDS FOR BDS
1051C
1052C REMAINDER GOES INTO IPFLD
1053 iptr = 0
1054C BYTES 12-13
1055C VALUE FOR N1
1056C LEAVE SPACE FOR THIS
1057 iptr = iptr + 16
1058C BYTE 14
1059C 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
1076C BYTES 15-16
1077C SKIP OVER VALUE FOR N2
1078 iptr = iptr + 16
1079C BYTES 17-18
1080C P1
1081 CALL sbytec (ipfld,kbds(17),iptr,16)
1082 iptr = iptr + 16
1083C BYTES 19-20
1084C P2
1085 CALL sbytec (ipfld,kbds(19),iptr,16)
1086 iptr = iptr + 16
1087C BYTE 21 - RESERVED LOCATION
1088 CALL sbytec (ipfld,0,iptr,8)
1089 iptr = iptr + 8
1090C BYTES 22 - ?
1091C WIDTHS OF SECOND ORDER PACKING
1092 ix = (iwdptr + 32) / 32
1093C 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
1098C PRINT *,'ISOWID',IWDPTR,IX
1099C CALL BINARY (ISOWID,IX)
1100C
1101C NO SECONDARY BIT MAP
1102
1103C DETERMINE LOCATION FOR START
1104C OF FIRST ORDER PACKED VALUES
1105 kbds(12) = iptr / 8 + 12
1106C STORE LOCATION
1107 CALL sbytec (ipfld,kbds(12),0,16)
1108C MOVE IN FIRST ORDER PACKED VALUES
1109 ipass = (ifoptr + 32) / 32
1110c 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
1115C PRINT *,'IFOVAL',IFOPTR,IPASS,KWIDE
1116C CALL BINARY (IFOVAL,IPASS)
1117 IF (mod(iptr,8).NE.0) THEN
1118 iptr = iptr + 8 - mod(iptr,8)
1119 END IF
1120C PRINT *,'IFOPTR =',IFOPTR,' ISOPTR =',ISOPTR
1121C DETERMINE LOCATION FOR START
1122C OF SECOND ORDER VALUES
1123 kbds(15) = iptr / 8 + 12
1124C SAVE LOCATION OF SECOND ORDER VALUES
1125 CALL sbytec (ipfld,kbds(15),24,16)
1126C MOVE IN SECOND ORDER PACKED VALUES
1127 ix = (isoptr + 32) / 32
1128C 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
1133C PRINT *,'ISOVAL',ISOPTR,IX
1134C 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
1140C COMPUTE LENGTH OF DATA PORTION
1141 len = iptr / 8
1142C COMPUTE LENGTH OF BDS
1143 lenbds = len + 11
1144C -----------------------------------
1145C BYTES 1-3
1146C THIS FUNCTION COMPLETED BELOW
1147C WHEN LENGTH OF BDS IS KNOWN
1148 CALL sbytec (bds11,lenbds,0,24)
1149C 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)
1154C ENTER NUMBER OF FILL BITS
1155 CALL sbytec (bds11,nleft,28,4)
1156C 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)
1164C
1165C$ FILL OCTET 7-10 WITH THE REFERENCE VALUE
1166C CONVERT THE FLOATING POINT OF YOUR MACHINE TO IBM370 32 BIT
1167C FLOATING POINT NUMBER
1168C REFERENCE VALUE
1169C FIRST TEST TO SEE IF
1170C ON 32 OR 64 BIT COMPUTER
1171C 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)
1179C
1180C BYTE 11
1181C
1182 CALL sbytec (bds11,kbds(11),80,8)
1183C
1184 klen = lenbds / 4 + 1
1185C PRINT *,'BDS11 LISTING',4,LENBDS
1186C CALL BINARY (BDS11,4)
1187C PRINT *,'IPFLD LISTING'
1188C CALL BINARY (IPFLD,KLEN)
1189 RETURN
1190 END
1191C
1192C> @brief Determine number of bits to contain value.
1193C> @author Bill Cavanaugh @date 1993-06-23
1194
1195C> Calculate number of bits to contain value n, with a maximum of 32 bits.
1196C>
1197C> Program history log:
1198C> - Bill Cavanaugh 1993-06-23
1199C> - Mark Iredell 1995-10-31 Removed saves and prints
1200C>
1201C> @param[in] N Integer value
1202C> @param[out] NBITS Number of bits to contain n
1203C>
1204C> @note Subprogram can be called from a multiprocessing environment.
1205C>
1206C> @author Bill Cavanaugh @date 1993-06-23
1207 SUBROUTINE fi7505 (N,NBITS)
1208
1209 INTEGER N,NBITS
1210 INTEGER IBITS(31)
1211C
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/
1217C ----------------------------------------------------------------
1218C
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
1226C
1227C> @brief Select block of data for packing.
1228C> @author Bill Cavanaugh @date 1994-01-21
1229
1230C> Select a block of data for packing
1231C>
1232C> Program history log:
1233C> - Bill Cavanaugh 1994-01-21
1234C> - Mark Iredell 1995-10-31 Removed saves and prints
1235C>
1236C> - Return address if encounter set of same values
1237C> @param[in] IWORK
1238C> @param[in] ISTART
1239C> @param[in] NPTS
1240C> @param[out] MAX
1241C> @param[out] MIN
1242C> @param[out] INRNGE
1243C>
1244C> @note Subprogram can be called from a multiprocessing environment.
1245C>
1246C> @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)
1252C
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/
1258C ----------------------------------------------------------------
1259C IDENTIFY NEXT BLOCK OF DATA FOR PACKING AND
1260C RETURN TO CALLER
1261C ********************************************************************
1262 istrta = istart
1263C
1264C GET BLOCK A
1265 CALL fi7516 (iwork,npts,inrnga,istrta,
1266 * max,min,mxval,lwide)
1267C ********************************************************************
1268C
1269 istrtb = istrta + inrnga
1270 2000 CONTINUE
1271C IF HAVE PROCESSED ALL DATA, RETURN
1272 IF (istrtb.GT.npts) THEN
1273C NO MORE DATA TO LOOK AT
1274 inrnge = inrnga
1275 RETURN
1276 END IF
1277C GET BLOCK B
1278 CALL fi7502 (iwork,istrtb,npts,isame)
1279 IF (isame.GE.15) THEN
1280C PRINT *,'BLOCK B HAS ALL IDENTICAL VALUES'
1281C PRINT *,'BLOCK A HAS INRNGE =',INRNGA
1282C BLOCK B CONTAINS ALL IDENTICAL VALUES
1283 inrnge = inrnga
1284C EXIT WITH BLOCK A
1285 RETURN
1286 END IF
1287C GET BLOCK B
1288C
1289 istrtb = istrta + inrnga
1290 CALL fi7516 (iwork,npts,inrngb,istrtb,
1291 * maxb,minb,mxvalb,lwideb)
1292C PRINT *,'BLOCK A',INRNGA,' BLOCK B',INRNGB
1293C ********************************************************************
1294C PERFORM TREND ANALYSIS TO DETERMINE
1295C IF DATA COLLECTION CAN BE IMPROVED
1296C
1297 ktrnd = lwide - lwideb
1298C PRINT *,'TREND',LWIDE,LWIDEB
1299 IF (ktrnd.LE.0) THEN
1300C PRINT *,'BLOCK A - SMALLER, SHOULD EXTEND INTO BLOCK B'
1301 mxval = ibits(lwide)
1302C
1303C IF BLOCK A REQUIRES THE SAME OR FEWER BITS
1304C LOOK AHEAD
1305C AND GATHER THOSE DATA POINTS THAT CAN
1306C BE RETAINED IN BLOCK A
1307C BECAUSE THIS BLOCK OF DATA
1308C USES FEWER BITS
1309C
1310 CALL fi7518 (iret,iwork,npts,istrta,inrnga,inrngb,
1311 * max,min,lwide,mxval)
1312 IF(iret.EQ.1) GO TO 8000
1313C 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
1320C PRINT *,'BLOCK A - LARGER, B SHOULD EXTEND BACK INTO A'
1321 mxvalb = ibits(lwideb)
1322C
1323C IF BLOCK B REQUIRES FEWER BITS
1324C LOOK BACK
1325C SHORTEN BLOCK A BECAUSE NEXT BLOCK OF DATA
1326C USES FEWER BITS
1327C
1328 CALL fi7517 (iret,iwork,npts,istrtb,inrnga,
1329 * maxb,minb,lwideb,mxvalb)
1330 IF(iret.EQ.1) GO TO 8000
1331C PRINT *,'17 INRNGA IS NOW ',INRNGA
1332 END IF
1333C
1334C PACK UP BLOCK A
1335C UPDATA POINTERS
1336 8000 CONTINUE
1337 inrnge = inrnga
1338C GET NEXT BLOCK A
1339 9000 CONTINUE
1340 RETURN
1341 END
1342C
1343C> @brief Scan number of points.
1344C> @author Bill Cavanaugh @date 1994-01-21
1345
1346C> Scan forward from current position. collect points and
1347C> determine maximum and minimum values and the number
1348C> of points that are included. Forward search is terminated
1349C> by encountering a set of identical values, by reaching
1350C> the number of points selected or by reaching the end
1351C> of data.
1352C>
1353C> Program history log:
1354C> - Bill Cavavnaugh 1994-01-21
1355C> - Mark Iredell 1995-10-31 Removed saves and prints
1356C>
1357C> - Return address if encounter set of same values
1358C> @param[in] IWORK Data array
1359C> @param[in] NPTS Number of points in data array
1360C> @param[in] ISTART Starting location in data
1361C> @param[out] INRNG Number of points selected
1362C> @param[out] MAX Maximum value of points
1363C> @param[out] MIN Minimum value of points
1364C> @param[out] MXVAL Maximum value that can be contained in lwidth bits
1365C> @param[out] LWIDTH Number of bits to contain max diff
1366C>
1367C> @note Subprogram can be called from a multiprocessing environment.
1368C>
1369C> @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)
1374C
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/
1380C ----------------------------------------------------------------
1381C
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
1400C
1401 DO 9000 lwidth = 1, 31
1402 IF (krng.LE.ibits(lwidth)) THEN
1403C PRINT *,'RETURNED',INRNG,' VALUES'
1404 RETURN
1405 END IF
1406 9000 CONTINUE
1407 RETURN
1408 END
1409C
1410C> @brief Scan backward.
1411C> @author Bill Cavanaugh @date 1994-01-21
1412
1413C> Scan backwards until a value exceeds range of group b this may shorten group a
1414C>
1415C> Program history log:
1416C> - Bill Cavanaugh 1994-01-21
1417C> - Mark Iredell 1995-10-31 Removed saves and prints
1418C> - Mark Iredell 1998-06-17 Removed alternate return
1419C>
1420C> @param[in] IWORK
1421C> @param[in] ISTRTB
1422C> @param[in] NPTS
1423C> @param[in] INRNGA
1424C> @param[out] IRET
1425C> @param[out] MAXB
1426C> @param[out] MINB
1427C> @param MXVALB
1428C> @param LWIDEB
1429C>
1430C> @note Subprogram can be called from a multiprocessing environment.
1431C>
1432C> @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)
1439C
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/
1445C ----------------------------------------------------------------
1446 iret=0
1447C PRINT *,' FI7517'
1448 npos = istrtb - 1
1449 itst = 0
1450 kset = inrnga
1451C
1452 1000 CONTINUE
1453C 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
1458C 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
1466C 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
1477C ----------------------------------------------------------------
1478C
1479 9000 CONTINUE
1480 RETURN
1481 END
1482C
1483C> @brief Scan forward.
1484C> @author Bill Cavanaugh @date 1994-01-21
1485
1486C> Scan forward from start of block b towards end of block b
1487C> if next point under test forces a larger maxvala then
1488C> terminate indicating last point tested for inclusion
1489C> into block a.
1490C>
1491C> Program history log:
1492C> - Bill Cavanaugh 1994-01-21
1493C> - Mark Iredell 1995-10-31 Removed saves and prints
1494C> - Mark Iredell 1998-06-17 Removed alternate return
1495C>
1496C> @param IWORK
1497C> @param ISTRTA
1498C> @param INRNGA
1499C> @param INRNGB
1500C> @param MAXA
1501C> @param MINA
1502C> @param LWIDEA
1503C> @param MXVALA
1504C> @param[in] NPTS
1505C> @param[out] IRET
1506C>
1507C> @note Subprogram can be called from a multiprocessing environment.
1508C>
1509C> @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)
1516C
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/
1522C ----------------------------------------------------------------
1523 iret=0
1524C PRINT *,' FI7518'
1525 npos = istrta + inrnga
1526 itst = 0
1527C
1528 1000 CONTINUE
1529 itst = itst + 1
1530 IF (itst.LE.inrngb) THEN
1531C PRINT *,'TRY NPOS',NPOS,IWORK(NPOS),MAXA,MINA
1532 IF (iwork(npos).GT.maxa) THEN
1533 IF ((iwork(npos)-mina).GT.mxvala) THEN
1534C 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
1542C 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
1550C PRINT *,' ',ITST,INRNGA
1551 npos = npos +1
1552 GO TO 1000
1553 END IF
1554C ----------------------------------------------------------------
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 fi7513(iwork, istart, npts, max, min, inrnge)
Select block of data for packing.
Definition w3fi75.f:1248
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 fi7517(iret, iwork, npts, istrtb, inrnga, maxb, minb, mxvalb, lwideb)
Scan backward.
Definition w3fi75.f:1435
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 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 fi7516(iwork, npts, inrng, istart, max, min, mxval, lwidth)
Scan number of points.
Definition w3fi75.f:1371
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