      SUBROUTINE PK_MISSP(KFILDO,IA,IB,NXY,MISSP,MINPK,IFIRST,
     1                    ISECOND,IMINA,NUMOCTET,SECOND,IER)
C
C        APRIL    1997   GLAHN   MODIFIED PACKXX TO HANDLE PRIMARY MISSING
C                                VALUES
C        MARCH    2000   GLAHN   REVISED FOR GRIB2;
C                                CHANGED NAME FROM PACKYY
C        JANUARY  2001   GLAHN   COMMENTS; ELIMINATED ARRAY IBXX2( );
C                                CHANGED IER = 1100 TO 920
C        NOVEMBER 2001   GLAHN   ADDED IER=0 AT BEGINNING
C        NOVEMBER 2001   GLAHN   CHANGED NUMOCTET=(NUMBIT/8)+1 TO
C                                NUMOCTET=(NUMBIT+7)/8 NEAR THE END
C        JANUARY  2002   GLAHN   ADDED TEST FOR 1ST ORDER DIFF GE
C                                2**15.; MODIFIED COMMENT FOR IER = 920
C        JANUARY  2002   GLAHN   ADDED MALLOW = 2**30+1 AND USED INSTEAD
C                                OF 999999
C        DECEMBER 2002   TAYLOR/GLAHN   CHANGED STATEMENT 225 FROM
C                                'IF(IVALUE.LT.0)NUMBIT=NUMBIT+1' TO
C                                NUMBIT=NUMBIT+1 TO ALLOW FOR SIGN
C
C        PURPOSE
C            DETERMINES WHETHER OR NOT TO USE SECOND ORDER
C            DIFFERENCES OR ORIGINAL VALUES TO PACK.  ORIGINAL VALUES
C            ARE INDICATED WHEN THE AVERAGE RANGE OF CONSECUTIVE GROUPS
C            OF SIZE MINPK OF THE SECOND ORDER DIFFERENCES IS
C            LARGER THAN THE AVERAGE RANGE OF CONSECUTIVE GROUPS OF
C            SIZE MINPK OF THE ORIGINAL VALUES.  NOTE THAT THIS
C            PROCEDURE DOES NOT IN GENERAL USE THE SAME GROUPS AS ARE
C            USED IN THE ACTUAL PACKING BECAUSE IT DOES NOT EMPLOY THE
C            LOOKBACK PROCEDURE.  THIS ALGORITHM IS RELATIVELY CHEAP
C            AND GIVES A RESULT GOOD ENOUGH FOR THE PURPOSE.  THIS
C            ROUTINE IS USED WHEN THERE CAN BE MISSING PRIMARY
C            VALUES (I.E., A MISSING VALUE INDICATOR, MISSP, CAN BE
C            IN THE DATA).
C
C        DATA SET USE
C           KFILDO - UNIT NUMBER FOR OUTPUT (PRINT) FILE. (OUTPUT)
C
C        VARIABLES
C              KFILDO = UNIT NUMBER FOR OUTPUT (PRINT) FILE.  (INPUT) 
C               IA(K) = HOLDS THE NXY ORIGINAL VALUES ON INPUT
C                       (K=1,NXY).
C                       HOLDS THE NXY SECOND ORDER DIFFERENCES ON
C                       OUTPUT WHEN SECOND ORDER DIFFERENCES ARE TO BE
C                       USED.  IN THAT CASE, SECOND IS .TRUE.  SINCE
C                       THERE ARE ONLY NXY-2 VALUES, THE FIRST 2
C                       NON-MISSING
C                       VALUES ARE DUMMY.  (INPUT-OUTPUT)
C               IB(K) = WORK ARRAY (K=1,NXY).  (INTERNAL)
C                 NXY = NUMBER OF VALUES IN IA( ) ON INPUT.  ON RETURN,
C                       NXY WILL ALSO BE THE NUMBER OF VALUES IN IA( ).
C                       USED AS DIMENSION OF IA( ), IB( ), AND IWORK( ).
C                       (INPUT)
C               MISSP = PRIMARY MISSING VALUE INDICATOR.  (INPUT)
C               MINPK = INCREMENT IN WHICH RANGES WILL BE COMPUTED.
C                       (INPUT)
C              IFIRST = IFIRST IS THE FIRST ORIGINAL VALUE.  (OUTPUT)
C             ISECOND = ISECOND IS THE SECOND ORIGINAL VALUE. (OUTPUT)
C               IMINA = THE OVERALL MINIMUM VALUE OF THE SECOND ORDER
C                       SPATIAL DIFFERENCES. (OUTPUT)
C            NUMOCTET = THE MINIMUM NUMBER OF OCTETS REQUIRED TO
C                       PACK EACH OF THE VALUES REPRESENTED BY IFIRST,
C                       ISECOND, AND IMINA. (OUTPUT)
C              SECOND = TRUE (FALSE) WHEN SECOND ORDER DIFFERENCES
C                       ARE (ARE NOT) TO BE USED.  (OUTPUT)
C                 IER = CONTAINS ANY ERROR CODES GENERATED BY THIS
C                       ROUTINE
C                         0 = GOOD RETURN
C                       920 = A VALUE LARGER THAN WHAT CAN BE PACKED
C                             INTO 30 BITS HAS BEEN ENCOUNTERED. 
C
C             LOCAL VARIABLES
C                AVGR = CONTAINS THE AVERAGE RANGE OF NXY VALUES
C                       IN INCREMENTS OF MINPK FOR THE ORIGINAL
C                       DATA FIELD IN IA( ). 
C               AVGR2 = CONTAINS THE AVERAGE RANGE OF NXY VALUES
C                       IN INCREMENTS OF MINPK FOR THE DATA FIELD
C                       WITH SECOND ORDER DIFFERENCES IN IB( ).
C               CFEED = CONTAINS THE CHARACTER REPRESENTATION
C                       OF A PRINTER FORM FEED.
C              IAKEEP = USED IN DETERMINING SECOND ORDER
C                       DIFFERENCES AND MAINTAINING THE LOCATIONS
C                       OF MISSING VALUES.
C              ICKEEP = USED IN DETERMINING SECOND ORDER
C                       DIFFERENCES AND MAINTAINING THE LOCATIONS
C                       OF MISSING VALUES.
C               IFEED = CONTAINS THE INTEGER VALUE OF A PRINTER
C                       FORM FEED.
C              IRANGE = THE DIFFERENCE OF JMAX AND JMIN.
C             ISECPOS = THE POSITION OF THE SECOND NON-MISSING VALUE
C                       IN THE DATA FIELD.
C              IVALUE = THE VALUE OF IFIRST, ISECOND, AND IMINA
C                       THAT WILL NEED THE MOST OCTETS TO STORE.
C            IWORK(K) = WORK ARRAY. THIS ARRAY CONTAINS ALL OF THE
C                       COMPUTATIONS UNTIL WE ARE CERTAIN THAT
C                       WE WANT TO USE SECOND ORDER DIFFERENCES
C                       (K=1,NXY).  (AUTOMATIC ARRAY)
C           JMAX,JMIN = USED TO KEEP TRACK OF THE MAX AND MIN VALUES 
C                       OF A PARTICULAR GROUP OF MINPK VALUES.
C              JFIRST = CONTAINS THE ABSOLUTE VALUE OF THE FIRST
C                       NON-MISSING VALUE IN THE ORIGINAL DATA 
C                       FIELD.
C            JLARGEST = CONTAINS THE LARGEST OF JFIRST, JSECOND, AND
C                       JMINA FOR THE PURPOSE OF DETERMINING
C                       HOW MANY OCTETS TO STORE ALL THREE VALUES
C                       IN.
C               JMINA = CONTAINS THE ABSOLUTE VALUE OF THE MINIMUM
C                       OF THE FIELD OF SECOND ORDER DIFFERENCES.
C             JSECOND = CONTAINS THE ABSOLUTE VALUE OF THE SECOND
C                       NON-MISSING VALUE IN THE ORIGINAL DATA
C                       FIELD.
C                   K = LOOP INDEX VARIABLE.
C              KFIRST = FLAG INDICATING WHETHER THE FIRST NON-MISSING
C                       VALUE OF THE FIELD HAS BEEN FOUND.
C               KOUNT = A COUNTING/LOOPING VARIABLE.
C             KSECOND = FLAG INDICATING WHETHER THE SECOND NON-MISSING
C                       VALUE OF THE FIELD HAS BEEN FOUND.
C                SUMR = USED IN COMPUTING THE AVERAGE RANGE OF THE
C                       ORIGINAL NXY VALUES IN INCREMENTS OF MINPK.
C               LARGE = 2**15, THE LARGEST 1ST ORDER DIFFERENCE
C                       TOLERATED.  IF THE 1ST ORDER DIFFERENCE 
C                       EXCEEDS THIS VALUE, IT IS LIKELY THE 2ND
C                       ORDER DIFFERENCE WILL OVERFLOW THE INTEGER
C                       COMPUTATION AND CAUSE AN UNDETECTED ERROR.
C
C        NON SYSTEM SUBROUTINES CALLED
C           NONE
C
      PARAMETER (MALLOW=2**30+1)
      PARAMETER (LARGE=2**15)
C
      CHARACTER*1 CFEED
      LOGICAL SECOND,KFIRST,KSECOND
C
      DIMENSION IA(NXY),IB(NXY),IWORK(NXY)
C
      DATA IFEED/12/
C
      IER=0
C
C        INITIALIZE THE FORM FEED CHARACTER.
      CFEED=CHAR(IFEED)
C
C        INITIALIZE IFIRST, ISECOND, IB(1), AND ICKEEP.
      IFIRST=IA(1)
      ISECOND=MISSP
      IB(1)=0
      IF(IA(1).EQ.MISSP)IB(1)=MISSP
      ICKEEP=IA(1)
C
C        COMPUTE FIRST ORDER DIFFERENCES.
C
      DO 120 K=2,NXY
C
         IF(ICKEEP.EQ.MISSP)THEN
            IB(K)=MISSP
            ICKEEP=IA(K)
         ELSE
C
            IF(IA(K).EQ.MISSP)THEN
               IB(K)=MISSP
            ELSE
               IB(K)=IA(K)-ICKEEP
C         
               IF(IB(K).GT.LARGE)THEN
                  SECOND=.FALSE.
C                 WRITE(KFILDO,119)            
C119              FORMAT(/' 1ST ORDER DIFFERENCE EXCEEDS 2**15.',
C    1                    '  SECOND ORDER DIFFERENCES ARE NOT PAKCED.')
                  GO TO 900
               ENDIF
C
               ICKEEP=IA(K)
            ENDIF
C
         ENDIF
C
         IF(IFIRST.EQ.MISSP)THEN
C
            IF(IA(K).NE.MISSP)THEN
               IFIRST=IA(K)
               IB(K)=0
            ENDIF
C
         ELSE IF(ISECOND.EQ.MISSP)THEN
C
            IF(IA(K).NE.MISSP)THEN
               ISECOND=IA(K)
            ENDIF
C
         ENDIF
C
 120  CONTINUE
C
C***D     WRITE(KFILDO,121)(IA(K),K=1,10000)
C***D     WRITE(KFILDO,121)(IA(K),K=268351,268500)
C***D121  FORMAT(/' ORIGINAL SCALED VALUES'/(' '25I4))
C
C***D     WRITE(KFILDO,1210)IFIRST,IFOD
C***D1210 FORMAT(/' IFIRST ='I11,'     IFOD ='I11)
C***D     WRITE(KFILDO,122)(IB(K),K=268351,268500)
C***D122  FORMAT(/ 'FIRST ORDER DIFFERENCES'/(' '25I4))
C
C        COMPUTE SECOND ORDER DIFFERENCES.
C
      IAKEEP=MISSP
      KFIRST=.TRUE.
      KSECOND=.TRUE.
C
      DO 130 K=1,NXY
C
         IF(KFIRST)THEN
            IWORK(K)=IB(K)
            IF(IB(K).NE.MISSP)KFIRST=.FALSE.
         ELSE
C
            IF(IAKEEP.EQ.MISSP)THEN
C
               IF(IB(K).NE.MISSP)THEN
                  IAKEEP=IB(K)
                  IF(KSECOND)THEN
                     IB(K)=0
                     KSECOND=.FALSE.
                     ISECPOS=K
                  ENDIF
                  IWORK(K)=IB(K)
               ELSE
                  IWORK(K)=MISSP
               ENDIF
C
            ELSE
C
               IF(IB(K).EQ.MISSP)THEN
                  IWORK(K)=MISSP
               ELSE
                  IWORK(K)=IB(K)-IAKEEP
                  IMINA=IWORK(K)
                  IAKEEP=IB(K)
               ENDIF
C
            ENDIF
C
         ENDIF
C
 130  CONTINUE
C
C***D     WRITE(KFILDO,136)CFEED
C***D136  FORMAT(1A/' *********************'
C***D    1          /' 2ND ORDER DIFFERENCES'
C***D    2          /' *********************')
C***D     WRITE(KFILDO,137) (IWORK(K),K=268351,268500)
C***D137  FORMAT(/(' '25I4))
C
C        COMPUTE THE MINIMUM OF THE FIELD OF SECOND ORDER
C        DIFFERENCES AND SUBTRACT IT FROM OF EACH OF THE
C        VALUES IN THE FIELD.
C
      DO 132 K=ISECPOS+1,NXY
         IF(IWORK(K).EQ.MISSP)CYCLE
         IF(IWORK(K).LT.IMINA)IMINA=IWORK(K)
 132  CONTINUE
C
      DO 134 K=ISECPOS+1,NXY
         IF(IWORK(K).EQ.MISSP)CYCLE
         IWORK(K)=IWORK(K)-IMINA
 134  CONTINUE
C
C***D     WRITE(KFILDO,131)(IWORK(K),K=268351,268500)
C***D131  FORMAT(/' SECOND ORDER DIFFERENCES'/(' '25I4))
C
C        COMPUTE AVERAGE RANGE OF NXY ORIGINAL VALUES IN INCREMENTS OF 
C        MINPK.
C
      SUMR=0
      KOUNT=0
C 
      DO 140 K=1,NXY,MINPK
         JMIN=MALLOW
         JMAX=-MALLOW
         IF(K+MINPK-1.GT.NXY)GO TO 140
C           THE LAST GROUP MAY BE VERY SMALL AND NOT BE REPRESENTATIVE
C           OF THE RANGE.
C
         DO 135 J=K,K+MINPK-1
            IF(IA(J).EQ.MISSP)CYCLE
            IF(IA(J).GT.JMAX)JMAX=IA(J)
            IF(IA(J).LT.JMIN)JMIN=IA(J)
 135     CONTINUE
C
         KOUNT=KOUNT+1
C
         IF(JMIN.EQ.MALLOW)THEN
            IRANGE=0
         ELSE
            IRANGE=JMAX-JMIN
            SUMR=SUMR+IRANGE 
         ENDIF   
C
 140  CONTINUE
C
      AVGR=99999.
      IF(KOUNT.NE.0)AVGR=SUMR/KOUNT
C
C        COMPUTE AVERAGE RANGE OF NXY-4 2ND ORDER VALUES IN 
C        INCREMENTS OF MINPK.   DON'T USE THE FIRST 2 VALUES,
C        BECAUSE THEY COULD BE BASED ON MISSING VALUES.
C
      SUMR=0
      KOUNT=0
C 
      DO 150 K=3,NXY-2,MINPK
         JMIN=MALLOW
         JMAX=-MALLOW
         IF(K+MINPK-1.GT.NXY-2)GO TO 150
C        THE LAST GROUP MAY BE VERY SMALL AND NOT BE REPRESENTATIVE OF
C        THE RANGE.
C
         DO 145 J=K,K+MINPK-1
            IF(IB(J).EQ.MISSP)GO TO 145
            IF(IB(J).GT.JMAX)JMAX=IB(J)
            IF(IB(J).LT.JMIN)JMIN=IB(J)
 145     CONTINUE
C
         KOUNT=KOUNT+1
C
         IF(JMIN.EQ.MALLOW)THEN
            IRANGE=0
         ELSE
            IRANGE=JMAX-JMIN
            SUMR=SUMR+IRANGE 
         ENDIF   
C 
 150  CONTINUE
C
      AVGR2=99999.
      IF(KOUNT.NE.0)AVGR2=SUMR/KOUNT
C
      SECOND=.FALSE.
C     WRITE(KFILDO,155)AVGR,AVGR2
C155  FORMAT(/' AVERAGE RANGE OF ORIGINAL SCALED VALUES =  'F10.2/
C    1        ' AVERAGE RANGE OF SECOND ORDER DIFFERENCES ='F10.2)
      IF(AVGR2.GE.AVGR)GO TO 900
C        SECOND ORDER DIFFERENCES NOT TO BE USED.
C
C        TRANSFER IWORK( ) TO IA( ).
      KOUNT=0
C
      DO 180 K=1,NXY
         IA(K)=IWORK(K)
 180  CONTINUE
C
C***D     WRITE(KFILDO,185)(IA(K),K=1,100)
C***D185  FORMAT(/' SECOND ORDER DIFFERENCES TO BE PACKED'/(' '10I11))
C
C           SINCE WE ARE DOING SECOND ORDER DIFFERENCES
C           TAKE THE TIME HERE TO DETERMINE THE MINIMUM
C           NUMBER OF BYTES (NOT BITS) NEED TO CONTAIN 
C           THE FIRST ORIGINAL VALUE, THE SECOND ORIGINAL
C           VALUE, AND THE MINIMUM OF THE FIELD OF SECOND
C           ORDER DIFFERENCES.
C
      NUMBIT=0
      JMINA=ABS(IMINA)
      JFIRST=ABS(IFIRST)
      JSECOND=ABS(ISECOND)
C
C           FIND THE LARGEST ABSOLUTE VALUE OF THE 
C           THE THREE VARIABLES IMINA, IFIRST, AND
C           ISECOND.
C
      IF(JMINA.GT.JFIRST)THEN
         JLARGEST=JMINA
         IVALUE=IMINA
      ELSE
         JLARGEST=JFIRST
         IVALUE=IFIRST
      ENDIF
C
      IF(JLARGEST.LT.JSECOND)THEN
         JLARGEST=JSECOND
         IVALUE=ISECOND
      ENDIF
C
      IBXX2=2
C
      DO 220 K=1,30
         NUMBIT=K
         IF(JLARGEST.LT.IBXX2)GO TO 225
         IBXX2=IBXX2*2
 220  CONTINUE
C
C        DROP THROUGH HERE MEANS THE NUMBER OF BITS
C        EXCEEDS 30 AND THE VALUE TO PACK EXCEEDS 2**30.
C        2**31 IS TOO LARGE A VALUE TO PACK.  2**30 
C        IS USED AS THE LIMIT THROUGHOUT THE PACKER,
C        ALTHOUGH A VALUE OF 2**31-1 COULD PROBABLY
C        BE ACCOMMODATED.
      IER=920
C        THIS IS A FATAL ERROR.
      GO TO 900
C
 225  NUMBIT=NUMBIT+1
C        ALLOW FOR SIGN BIT.
C
C        FIND THE SMALLEST NUMBER OF OCTETS 
C        THAT WILL CONTAIN THE VALUES.  
      NUMOCTET=(NUMBIT+7)/8
      SECOND=.TRUE.
C     WRITE(KFILDO,899)JMINA,JFIRST,JSECOND,JLARGEST,
C    1                 IVALUE,NUMBIT,NUMOCTET
C899  FORMAT(/' AT 899 IN PK_MISSP--JMINA,JFIRST,JSECOND,JLARGEST,',
C    1        'IVALUE,NUMBIT,NUMOCTET'/20X,7I10)
 900  RETURN 
      END

