C$$$  SUBPROGRAM DOCUMENTATION BLOCK
C                .      .    .                                       .
C SUBPROGRAM:    MSFCPCP     GET PRECIP OBS THAT NEED SPECIAL HANDLING
C   PRGMMR: M. BARTH         ORG: FSL        DATE: 01-02-09
C
C ABSTRACT: GET THE PRECIP OBS THAT NEED SPECIAL-HANDLING
C
C PROGRAM HISTORY LOG:
C   01-02-09  M. BARTH    ORIGINAL VERSION
C   01-04-24  M. BARTH    - ADDED "MesoWest" AS DPTMP = "UTMESNET"
C                         - ADDED PCP24_VN_P VARIABLE FOR MESONET
C   01-05-03  M. BARTH    CHANGED MRDNUM/MRDCHR TO MGTNUM/MGTCHR
C   01-06-27  M. BARTH    ADDED SUBPROVIDER CAPABILITY (AND CHANGED
C                         PACCUM_CODE TO PACCUM_*_CODE ACCORDINGLY)
C   01-06-29  M. BARTH    REMOVED PSOS DATASET
C   01-07-24  M. BARTH    SPLIT PROVIDER INFO INTO SFC & HYDRO
C   02-05-28  M. BARTH    FIXED A BUG WHERE 3/6/12/18 H MESONET
C                         PRECIP ACCUM WEREN'T BEING PROCESSED
C   02-05-29  M. BARTH    RESTRUCTURED TEMPORARY MEMORY ARRAY USAGE
C   04-03-24  M. BARTH    ADDED COOP DATASET AND PCPCDAY/PCPUDAY
C   04-06-30  M. BARTH    - ADDED PCPTOTL
C                         - ADDED TMP_L2_C2 (USAGE OF TMP_L2_C1
C                           HAD BEEN OVERFLOWING THE DIMENSION OF
C                           THAT ARRAY, THIS HADN'T CAUSED ANY
C                           PROBLEM BECAUSE THE LEVEL 3 ARRAY
C                           STORED AFTER IT WASN'T USED BY ANY
C                           ROUTINES CALLED HERE.  THIS WAS 
C                           DISCOVERED WHEN ADDING ANOTHER TMP
C                           ARRAY FOR THE PCPTOTL PROCESSING, AND
C                           HAS NOW BEEN FIXED.)
C   04-10-16  L. BENJAMIN ADDED NO SUCH VARIABLE CHECK FOR QCA CHECKS
C   05-09-16  L. BENJAMIN ADDED "APRSWXNET" PRECIP CHECK TO OUTPUT 
C                         THE ACCUM DATA AS "LAST 24 HOURS".
C   05-09-21  L. BENJAMIN ADDED PCPTOTL FOR CODE4PST SITES OTHER THAN 
C                         COOP.
C   06-09-20  L. BENJAMIN ADDED URBANET DATASET.
C   07-10-17  M. BARTH    ADDED 5- AND 15-MIN ACCUM PERIOD FOR MESONETS,
C                         AND 5-MIN ACCUM FOR COOP.
C   08-06-25  M. BARTH    ADDED HIGH FREQUENCY METAR DATASET.
C   09-07-23  L. BENJAMIN ADDED NEPP, HCN, AND CRN AS A SFC DATASETS.
C   09-08-08  L. BENJAMIN ADDED CRN ARCHIVE ONE HOUR PRECIP AND CRN
C                         /HCN/NEPP PRECIP VARIABLES.
C
C USAGE:    CALL MSFCPCP (VCN,DSN,FNUM,OB,QCDESC,QCAPP,QCRES,STATUS)
C
C   INPUT ARGUMENT LIST:
C     VCN      - I       VARIABLE CODE NUMBER FOR 1H PRECIP ACCUM,
C                        PRECIP RATE, PRECIP ACCUM SINCE MIDNIGHT
C                        (LOCAL OR UTC), LAST 24H PRECIP ACCUM
C     DSN      - I       DATASET CODE NUMBER
C     FNUM     - I       FILE NUMBER (INDEX IN COMMON) OF NETCDF FILE
C
C   OUTPUT ARGUMENT LIST:
C     OB       - RA      OBSERVATIONS IN M/K/S UNITS
C     QCDESC   - CA      QC DATA DESCRIPTORS
C     QCAPP    - RA      QC APPLIED WORD (SHOWS CHECKS APPLIED)
C     QCRES    - RA      QC RESULTS WORD (GOOD/BAD FOR EACH CHECK)
C     STATUS   - I       SUCCESS_P OR ERROR CODE
C
C   INPUT FILES:
C     NETCDF FILE OPENED USING DATA STRUCTURES FOR FNUM IN STRCCOM
C
C SUBPROGRAMS CALLED:
C     UNIQUE:    MGTNUM, MGTCHR, M_LSTCHR, M_MKI4TM
C
C REMARKS:
C   - THIS ROUTINE IS ASSUMED TO BE CALLED BY A HIGHER-LEVEL MADIS
C     ROUTINE, SO NO ERROR CHECKING IS DONE ON THE INPUT VARIABLES.
C   - 1H PRECIP ACCUM & PRECIP RATE ARE INTERCHANGEABLE (AT LEAST
C     AS FAR AS ANY CURRENT PRECIP RATE REPORTS ARE CONCERNED), SO
C     WE CAN GIVE THE USER WHICHEVER HE WANTS.
C   - THE ACCUM SINCE MIDNIGHT OBS ARE A FUNCTION OF THE MESONET
C     DATA PROVIDER.  THE PRECIPACCUM VARIABLE IN THE NETCDF FILE
C     IS FOR AN UNSPECIFIED DURATION, SO WE TAKE CARE OF THIS
C     RIDICULOUS DESIGN DECISION (OBVIOUSLY, A DESIGN BY SOMEONE
C     OTHER THAN MYSELF...) BY FIXING IT IN THIS ROUTINE.
C   - THE MADISCOM PACCUM_*_CODE ARRAYS ARE USED TO KEEP TRACK OF WHAT
C     DIFFERENT MESONETS ARE PUTTING INTO PRECIPACCUM.  THIS IS
C     SPECIFIED IN SUBSRCIN.TXT, SO THAT FILE SHOULD BE EDITED WHEN
C     DATA FROM A NEW MESONET ARE ADDED.  LEGAL VALUES INCLUDE:
C
C      0        NOT USED, OR INFO NOT AVAILABLE
C      1-24     1-24H RUNNING ACCUMULATION (FOR 1/3/6/12/18/24 H)
C     -1        24H ACCUMULATION SINCE LOCAL MIDNIGHT (MESONET)
C     -2        24H ACCUMULATION SINCE UTC MIDNIGHT (MESONET)
C     -3        24H ACCUMULATION OVER LAST 24 HOURS (MESONET)
C
C     THIS CAN BE SPECIFIED ON A PROVIDER OR SUBPROVIDER LEVEL.  IF
C     THE SUB_CODE FOR THE PROVIDER INDICATES THAT THE SUBPROVIDER
C     CODES SHOULD BE USED, THESE WILL BE USED INSTEAD OF WHATEVER'S
C     IN THE PROVIDER ACCUM CODE.
C   - NOTE THAT AS OF 2/01 THE UTMESNET PRECIP RATE VARIABLES
C     ARE KNOWN TO BE GARBAGE, AND ARE KNOCKED OUT VIA THIS ROUTINE.
C     AS OF 6/05 THE PRECIP RATE'S BEEN FIXED, SO THESE ARE NO
C     LONGER KNOCKED OUT AS OF THIS TIME:  052591500.
C   - PCPTOTL FOR THE COOP DATASET HAS THREE CASES IF THE STATION
C     ISN'T STYN6:
C     - USE fiveMinPrecipAccum VARIABLE PRIOR TO 2000 6/2/04.
C     - WIPE ALL DATA >= 2000 & < 2100 6/2/04.
C     - USE NORMAL VARIABLE (rawPrecip) 2100 6/2/04 AND LATER.
C   - THE MADISCOM PROVIDER ARRAYS (NPVD, PVDNAME, ETC.) HAVE SFC
C     PROVIDERS IN ROW 1, HYDRO PROVIDERS IN ROW 2.
C   - SEE madistmp.f FOR AN EXPLANATION OF HOW TEMPORARY STORAGE
C     IS HANDLED (ALL ARRAYS NAMED *TMP*).
C
C ATTRIBUTES:
C   LANGUAGE: FORTRAN-77 + EXTENSIONS
C   MACHINE:  UNIX
C$$$

      SUBROUTINE MSFCPCP (VCN,DSN,FNUM,OB,QCDESC,QCAPP,QCRES,STATUS)

C     ------------------------------------------------------------------
C     INCLUDES AND COMMONS
C     ------------------------------------------------------------------
      INCLUDE 'IMPLICIT'
      INCLUDE 'MADISCON'
      INCLUDE 'MADISCOM'
      INCLUDE 'STRCCOM'
      INCLUDE 'MADISTMP'

C     ------------------------------------------------------------------
C     ARGUMENTS
C     ------------------------------------------------------------------
      INTEGER VCN,DSN,FNUM,STATUS
      REAL OB(*),QCAPP(*),QCRES(*)
      CHARACTER*1 QCDESC(*)

C     ------------------------------------------------------------------
C     LOCAL
C     ------------------------------------------------------------------
      REAL OBTMP(MXSFC_P,2),METARTYPE(MXSFC_P)
      INTEGER I,J,K,L,M,LEN1REC,M_LSTCHR,ACCUM_CODE,DESIRED_CODE
      REAL QCATMP(MXSFC_P,2),QCRTMP(MXSFC_P,2)
      CHARACTER*1 QCDTMP(MXSFC_P,2)
      CHARACTER*11 DPTMP(MXSFC_P)
      CHARACTER*6 IDTMP(MXSFC_P)
      CHARACTER*51 LNTMP(MXSFC_P)
      LOGICAL UTMESNET
      LOGICAL ISCODE4
      INTEGER I4TIME,COOPTIME1,COOPTIME2,COOPSPC,UTMESNETTIME
      PARAMETER(COOPTIME1=-239169600)
      PARAMETER(COOPTIME2=-239166000)
      PARAMETER(UTMESNETTIME=-198493200)
      LOGICAL QCMISS(2)
C     ------------------------------------------------------------------
C     TEMPORARY STORAGE DEFINITIONS
C     ------------------------------------------------------------------
      EQUIVALENCE(OBTMP,METARTYPE,TMP_L2_N1)
      EQUIVALENCE(QCATMP,TMP_L2_N2)
      EQUIVALENCE(QCRTMP,TMP_L2_N3)
      EQUIVALENCE(QCDTMP,TMP_L2_C1)
      EQUIVALENCE(DPTMP,TMP_L2_C1(MXSFC_P*2+1))
      EQUIVALENCE(IDTMP,TMP_L2_C1(MXSFC_P*13+1))
      EQUIVALENCE(LNTMP,TMP_L2_C2)


C     ------------------------------------------------------------------
C     COOP SPECIAL CASE FOR TOTAL PRECIPITATION:
C
C     IF THE STATION ISN'T STYN6:
C
C     - USE fiveMinPrecipAccum VARIABLE PRIOR TO 2000 6/2/04.
C     - WIPE ALL DATA >= 2000 & < 2100 6/2/04.
C     - USE NORMAL VARIABLE (rawPrecip) 2100 6/2/04 AND LATER.
C     ------------------------------------------------------------------
      IF(DSN.EQ.COOP_DS_P.AND.VCN.EQ.PCPTOTL_VN_P)THEN

         CALL M_MKI4TM(LAST_SFC_ATIME,I4TIME,STATUS)
         IF(I4TIME.LT.COOPTIME1)THEN
            
            COOPSPC = 0

         ELSE IF(I4TIME.GE.COOPTIME2)THEN

            COOPSPC = 1

         ELSE

            COOPSPC = 2

         ENDIF

      ELSE

         COOPSPC = 1

      ENDIF

C     ------------------------------------------------------------------
C     IF THE DATASET ISN'T MESONET, READ THE VARIABLE AND ITS QC INFO.
C     THEN, IF THE STORED VARIABLE ISN'T THE ONE DESIRED BY THE CALLER,
C     CONVERT IT.  WE'LL ALSO USE THIS CLAUSE FOR MESONET PCPTOTL.
C     ------------------------------------------------------------------


      IF(.NOT.(DSN.EQ.MESONET_DS_P.AND.VCN.NE.PCPTOTL_VN_P))THEN
         IF(COOPSPC.EQ.0)THEN

            CALL MGTNUM('fiveMinPrecipAccum',SFC_NCID(FNUM),
     1                  SFC_RECDIM(FNUM),1,SFC_NRECS(FNUM),MISS_P,OBTMP,
     2                  STATUS)
            IF(STATUS.NE.SUCCESS_P)RETURN

         ENDIF

         CALL MGTNUM(VNAME(VCN,DSN)(1:VLEN(VCN,DSN)),SFC_NCID(FNUM),
     1               SFC_RECDIM(FNUM),1,SFC_NRECS(FNUM),MISS_P,OB,
     2               STATUS)
         IF(STATUS.NE.SUCCESS_P)RETURN

C     ASSUME QC OK, SET FOR DIFFERNET CONDITIONS
         QCSTATUS = EQCOK_P

         IF(VQC(VCN,DSN).EQ.'Q')THEN

            CALL MGTNUM(VNAME(VCN,DSN)(1:VLEN(VCN,DSN))//'QCA',
     1                  SFC_NCID(FNUM),SFC_RECDIM(FNUM),1,
     2                  SFC_NRECS(FNUM),MISS_P,QCAPP,STATUS)
            IF(STATUS.EQ.VAR_NOTINDB_P)THEN
               QCSTATUS = EQCFAILED_P
               STATUS = SUCCESS_P
               DO I = 1, SFC_NRECS(FNUM)
                  QCAPP(I) = 0
                  QCRES(I) = 0
                  QCDESC(I) = 'Z'
               ENDDO
            ELSE IF(STATUS.NE.SUCCESS_P)THEN
               RETURN
            ELSE
               CALL MGTNUM(VNAME(VCN,DSN)(1:VLEN(VCN,DSN))//'QCR',
     1                  SFC_NCID(FNUM),SFC_RECDIM(FNUM),1,
     2                  SFC_NRECS(FNUM),MISS_P,QCRES,STATUS)
               IF(STATUS.NE.SUCCESS_P)RETURN

               CALL MGTCHR(VNAME(VCN,DSN)(1:VLEN(VCN,DSN))//'DD',
     1                  SFC_NCID(FNUM),SFC_RECDIM(FNUM),1,
     2                  SFC_NRECS(FNUM),QCDESC,LEN1REC,STATUS)
               IF(STATUS.NE.SUCCESS_P)RETURN
            ENDIF
         ELSE
            QCSTATUS = EQCFAILED_P

            DO 1 I = 1, SFC_NRECS(FNUM)
               QCAPP(I) = 0
               QCRES(I) = 0
               QCDESC(I) = 'Z'
 1          CONTINUE

         ENDIF

C     ------------------------------------------------------------------
C     PROCESS COOPSPC CASES 0 & 2, REMEMBERING TO CONVERT FROM MM TO M.
C     ------------------------------------------------------------------
         IF(COOPSPC.NE.1)THEN

            CALL MGTCHR('stationId',SFC_NCID(FNUM),SFC_RECDIM(FNUM),1,
     3                  SFC_NRECS(FNUM),IDTMP,LEN1REC,STATUS)
            IF(STATUS.NE.SUCCESS_P)RETURN

            IF(COOPSPC.EQ.0)THEN

               DO I = 1, SFC_NRECS(FNUM)

                  IF(IDTMP(I)(1:5).NE.'STYN6'.AND.
     1               OBTMP(I,1).NE.MISS_P)THEN

                     OB(I) = OBTMP(I,1) * 0.001

                  ELSE IF(IDTMP(I)(1:5).EQ.'STYN6'.AND.
     1                    OB(I).NE.MISS_P)THEN

                     OB(I) = OB(I) * 0.001

                  ELSE

                     OB(I) = MISS_P

                  ENDIF

               ENDDO

            ELSE

               DO I = 1, SFC_NRECS(FNUM)

                  IF(IDTMP(I)(1:5).EQ.'STYN6'.AND.OB(I).NE.MISS_P)THEN

                     OB(I) = OB(I) * 0.001

                  ELSE

                     OB(I) = MISS_P

                  ENDIF

               ENDDO

            ENDIF

            RETURN

         ENDIF

C     ------------------------------------------------------------------
C     FOR THE SAO/COOP/URBANET/HFMETAR/NEPP/HCN/CNR DATASETS, CONVERT 
C     THE ACCUM OBS FROM MM TO M.
C     ------------------------------------------------------------------
         IF(DSN.EQ.SAO_DS_P.OR.DSN.EQ.URBANET_DS_P.OR.
     1      DSN.EQ.HFMETAR_DS_P.OR.
     1      DSN.EQ.NEPP_DS_P.OR.DSN.EQ.HCN_DS_P.OR.DSN.EQ.CRN_DS_P.OR.
     1      (DSN.EQ.COOP_DS_P.AND.(VCN.EQ.PCP24_VN_P.OR.
     2       VCN.EQ.PCPCDAY_VN_P.OR.VCN.EQ.PCPUDAY_VN_P.OR.
     3       VCN.EQ.PCPTOTL_VN_P.OR.VCN.EQ.PCP5M_VN_P)))THEN

            DO 22 I = 1, SFC_NRECS(FNUM)
               IF(OB(I).NE.MISS_P)OB(I) = OB(I) * 0.001
 22         CONTINUE

         ENDIF

C     ------------------------------------------------------------------
C     GET TOTAL PRECIP FOR HFMETAR DATASET.  HERE WE NEED TO GET THE
C     METARTYPE VARIABLE IN ORDER TO TELL WHICH ONES ARE AWOS'S AND
C     WHICH ONES AREN'T -- ONLY AWOS'S HAVE TOTAL PRECIP.
C     ------------------------------------------------------------------
         IF(DSN.EQ.HFMETAR_DS_P.AND.VCN.EQ.PCPTOTL_VN_P)THEN
            
            CALL MGTNUM('metarType',SFC_NCID(FNUM),
     1                  SFC_RECDIM(FNUM),1,SFC_NRECS(FNUM),MISS_P,
     2                  METARTYPE,STATUS)
            IF(STATUS.NE.SUCCESS_P)RETURN

            DO I = 1, SFC_NRECS(FNUM)
               IF(METARTYPE(I).NE.2.AND.METARTYPE(I).NE.5)OB(I) = MISS_P
            ENDDO

            RETURN

         ENDIF

C     ------------------------------------------------------------------
C     FOR THE MESONET DATASETS, CHECK CODE4PST STATUS, CONVERT THE ACCUM 
C     OBS FROM MM TO M.
C     ------------------------------------------------------------------
         IF(DSN.EQ.MESONET_DS_P.AND.VCN.EQ.PCPTOTL_VN_P)THEN

            CALL MGTCHR('dataProvider',SFC_NCID(FNUM),SFC_RECDIM(FNUM),
     1           1,SFC_NRECS(FNUM),DPTMP,LEN1REC,STATUS)
            IF(STATUS.NE.SUCCESS_P)RETURN

            DO 222 I = 1, SFC_NRECS(FNUM)
               K = M_LSTCHR(DPTMP(I),10)
               ISCODE4 = .FALSE.
               DO 228 J = 1, NPVD(1)

                  IF(K.EQ.PVDLEN(J,1).AND.DPTMP(I)(1:K).EQ.
     1                 PVDNAME(J,1)(1:K))THEN

                     IF(RAWP_CODE(J,1).EQ.1)THEN
                        IF(OB(I).NE.MISS_P)OB(I) = OB(I) * 0.001
                        ISCODE4 = .TRUE.
                        GO TO 229
                     ENDIF
                  ENDIF
 228           CONTINUE
               IF(.NOT.ISCODE4)OB(I) = MISS_P
 229           CONTINUE
 222         CONTINUE

         ENDIF

         IF((VCN.EQ.PCP1_VN_P.OR.VCN.EQ.PCPRATE_VN_P).AND.
     1        (DSN.EQ.CRN_DS_P.OR.DSN.EQ.HCN_DS_P))THEN
C     ------------------------------------------------------------------
C     USE ARCHIVE IF AVAILABLE, ELSE USE REAL TIME, WHICH IS WHAT WE 
C     HAVE.
C     ------------------------------------------------------------------
            CALL MGTNUM('archivePrecipAccum1h',SFC_NCID(FNUM),
     1           SFC_RECDIM(FNUM),1,SFC_NRECS(FNUM),MISS_P,OBTMP(1,1),
     2           STATUS)
            IF(STATUS.NE.SUCCESS_P)RETURN
            
C     ASSUME QC OK, SET FOR DIFFERNET CONDITIONS
            QCSTATUS = EQCOK_P
            
            IF(VQC(VCN,DSN).EQ.'Q')THEN
               
               CALL MGTNUM('archivePrecipAccum1hQCA',
     1              SFC_NCID(FNUM),SFC_RECDIM(FNUM),1,
     2              SFC_NRECS(FNUM),MISS_P,QCATMP(1,1),STATUS)
               IF(STATUS.EQ.VAR_NOTINDB_P)THEN
                  QCSTATUS = EQCFAILED_P
                  STATUS = SUCCESS_P
                  DO I = 1, SFC_NRECS(FNUM)
                     QCATMP(I,1) = 0
                     QCRTMP(I,1) = 0
                     QCDTMP(I,1) = 'Z'
                  ENDDO
               ELSE IF(STATUS.NE.SUCCESS_P)THEN
                  RETURN
               ELSE
                  CALL MGTNUM('archivePrecipAccum1hQCR',
     1                 SFC_NCID(FNUM),SFC_RECDIM(FNUM),1,
     2                 SFC_NRECS(FNUM),MISS_P,QCRTMP(1,1),STATUS)
                  IF(STATUS.NE.SUCCESS_P)RETURN
                  
                  CALL MGTCHR('archivePrecipAccum1hDD',
     1                 SFC_NCID(FNUM),SFC_RECDIM(FNUM),1,
     2                 SFC_NRECS(FNUM),QCDTMP(1,1),LEN1REC,STATUS)
                  IF(STATUS.NE.SUCCESS_P)RETURN
               ENDIF
            ELSE
               QCSTATUS = EQCFAILED_P
               
               DO 201 I = 1, SFC_NRECS(FNUM)
                  QCATMP(I,1) = 0
                  QCRTMP(I,1) = 0
                  QCDTMP(I,1) = 'Z'
 201             CONTINUE
               
            ENDIF


C     ------------------------------------------------------------------
C     SELECT WHICH MEASUREMENT TO USE.
C     CONVERT THE ACCUM OBS FROM MM TO M.
C     ------------------------------------------------------------------
            DO 322 I = 1, SFC_NRECS(FNUM)
               IF(OBTMP(I,1).NE.MISS_P)THEN
                  OB(I) = OBTMP(I,1)
                  QCAPP(I) = QCATMP(I,1)
                  QCRES(I) = QCRTMP(I,1)
                  QCDESC(I) = QCDTMP(I,1)
               ENDIF
               IF(OB(I).NE.MISS_P)OB(I) = OB(I) * 0.001
 322        CONTINUE


CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
         ELSE IF(VCN.EQ.PCPRATE_VN_P.AND.DSN.NE.COOP_DS_P)THEN

C     ------------------------------------------------------------------
C     CONVERT ALL NON-MISSING OBS FROM ACCUMULATED METERS (FOR ONE HOUR) 
C     TO THE RATE IN KG/(M**2)/S (WHICH IS EQUAL TO MM/S).
C     ------------------------------------------------------------------
            DO 10 I = 1, SFC_NRECS(FNUM)
               IF(OB(I).NE.MISS_P)OB(I) = OB(I) * 1000. / 3600.
 10         CONTINUE

         ELSE IF(VCN.EQ.PCP1_VN_P.AND.DSN.EQ.COOP_DS_P)THEN

C     ------------------------------------------------------------------
C     CONVERT FROM THE RATE (STORED AS M/S) TO A 1H ACCUM (M).
C     ------------------------------------------------------------------
            DO I = 1, SFC_NRECS(FNUM)
               IF(OB(I).NE.MISS_P)OB(I) = OB(I) * 3600.
            ENDDO

         ELSE IF(VCN.EQ.PCPRATE_VN_P.AND.DSN.EQ.COOP_DS_P)THEN

C     ------------------------------------------------------------------
C     CONVERT FROM THE STORED M/S TO KG/(M**2)/S.
C     ------------------------------------------------------------------
            DO I = 1, SFC_NRECS(FNUM)
               IF(OB(I).NE.MISS_P)OB(I) = OB(I) * 1000.0
            ENDDO

         ENDIF

      ELSE IF(VCN.EQ.PCP1_VN_P.OR.VCN.EQ.PCPRATE_VN_P)THEN

C     ------------------------------------------------------------------
C     FOR MESONET, WE'LL READ BOTH VARIABLES, AND THEIR QC STRUCTURES.
C     WE ALSO NEED THE PROVIDER AND SUBPROVIDER NAMES SO WE CAN TELL IF
C     ANY OF THEM HAVE 1H ACCUMULATIONS IN THE GENERIC PRECIPACCUM
C     VARIABLE.  THEN, WE'LL RETURN EITHER THE READ-IN VALUE OR THE
C     CALCULATED VALUE FOR THE FORM OF THE VARIABLE DESIRED BY THE
C     CALLER.  (NOTE THAT THE SUBPROVIDER NAMES ARE IN CHARACTERS 40:50
C     OF THE LONG STATION NAMES.)
C     ------------------------------------------------------------------
         CALL MGTNUM(VNAME(PCPRATE_VN_P,DSN)(1:VLEN(PCPRATE_VN_P,DSN)),
     1               SFC_NCID(FNUM),SFC_RECDIM(FNUM),1,SFC_NRECS(FNUM),
     2               MISS_P,OBTMP(1,2),STATUS)
         IF(STATUS.NE.SUCCESS_P)RETURN

         QCMISS(2) = .TRUE.
         IF(VQC(PCPRATE_VN_P,DSN).EQ.'Q')THEN

            CALL MGTNUM(VNAME(PCPRATE_VN_P,DSN)
     1                  (1:VLEN(PCPRATE_VN_P,DSN))//
     2                  'QCA',SFC_NCID(FNUM),SFC_RECDIM(FNUM),1,
     3                  SFC_NRECS(FNUM),MISS_P,QCATMP(1,2),STATUS)
            IF(STATUS.EQ.VAR_NOTINDB_P)THEN
               QCSTATUS = EQCFAILED_P
               STATUS = SUCCESS_P
               DO I = 1, SFC_NRECS(FNUM)
                  QCATMP(I,2) = 0
                  QCRTMP(I,2) = 0
                  QCDTMP(I,2) = 'Z'
               ENDDO
            ELSE IF(STATUS.NE.SUCCESS_P)THEN
               RETURN
            ELSE
               CALL MGTNUM(VNAME(PCPRATE_VN_P,DSN)
     1                  (1:VLEN(PCPRATE_VN_P,DSN))//
     2                  'QCR',SFC_NCID(FNUM),SFC_RECDIM(FNUM),1,
     3                  SFC_NRECS(FNUM),MISS_P,QCRTMP(1,2),STATUS)
               IF(STATUS.NE.SUCCESS_P)RETURN

               CALL MGTCHR(VNAME(PCPRATE_VN_P,DSN)
     1                  (1:VLEN(PCPRATE_VN_P,DSN))//
     2                  'DD',SFC_NCID(FNUM),SFC_RECDIM(FNUM),1,
     3                  SFC_NRECS(FNUM),QCDTMP(1,2),LEN1REC,STATUS)
               IF(STATUS.NE.SUCCESS_P)RETURN

               QCMISS(2) = .FALSE.
            ENDIF
         ELSE
            QCSTATUS = EQCFAILED_P

            DO 21 I = 1, SFC_NRECS(FNUM)
               QCATMP(I,2) = 0
               QCRTMP(I,2) = 0
               QCDTMP(I,2) = 'Z'
 21         CONTINUE

         ENDIF
         CALL MGTNUM(VNAME(PCP1_VN_P,DSN)(1:VLEN(PCP1_VN_P,DSN)),
     1               SFC_NCID(FNUM),SFC_RECDIM(FNUM),1,
     2               SFC_NRECS(FNUM),MISS_P,OBTMP(1,1),STATUS)
         IF(STATUS.NE.SUCCESS_P)RETURN

         CALL MGTCHR('dataProvider',SFC_NCID(FNUM),SFC_RECDIM(FNUM),
     1               1,SFC_NRECS(FNUM),DPTMP,LEN1REC,STATUS)
         IF(STATUS.NE.SUCCESS_P)RETURN

         CALL MGTCHR('stationName',SFC_NCID(FNUM),SFC_RECDIM(FNUM),
     1               1,SFC_NRECS(FNUM),LNTMP,LEN1REC,STATUS)
         IF(STATUS.NE.SUCCESS_P)RETURN

C     ------------------------------------------------------------------
C     BEFORE CONTINUING, PUT THE OBS INTO THE PROPER UNITS.
C     (ACCUM:  MM -> M, RATE:  M/S -> KG/(M**2)/S)
C     ALSO WIPE OUT ACCUM OBS FOR ANY PROVIDERS THAT AREN'T PUTTING
C     1H ACCUMULATION INTO THE GENERIC VARIABLE.  AND WIPE OUT THE
C     BOGUS UTMESNET PRECIP RATES IF THE TIME'S BEFORE THEY WERE FIXED.
C     ------------------------------------------------------------------
         DO 23 I = 1, SFC_NRECS(FNUM)

            K = M_LSTCHR(DPTMP(I),10)
            UTMESNET = .FALSE.
            ACCUM_CODE = 0

            DO 24 J = 1, NPVD(1)

               IF(K.EQ.PVDLEN(J,1).AND.DPTMP(I)(1:K).EQ.
     1              PVDNAME(J,1)(1:K))THEN

                  IF(SUB_CODE(J,1).EQ.0)THEN

                     ACCUM_CODE = PACCUM_P_CODE(J,1)
                     IF(DPTMP(I)(1:8).EQ.'UTMESNET'.OR.
     1                    DPTMP(I)(1:8).EQ.'MesoWest')THEN
                        CALL M_MKI4TM(LAST_SFC_ATIME,I4TIME,STATUS)
                        IF(I4TIME.LT.UTMESNETTIME)UTMESNET = .TRUE.
                     ENDIF
                     GO TO 25

                  ELSE

                     L = M_LSTCHR(LNTMP(I)(40:50),11)
                     IF(L.EQ.0)GO TO 25

                     DO 26 M = 1, NSUB(1)

                        IF(L.EQ.SUBLEN(M,1).AND.LNTMP(I)(40:40+L-1).EQ.
     1                     SUBNAME(M,1)(1:L))THEN

                           ACCUM_CODE = PACCUM_S_CODE(M,1)
                           GO TO 25

                        ENDIF

 26                  CONTINUE

                  ENDIF

               ENDIF

 24         CONTINUE

 25         IF(ACCUM_CODE.NE.1)OBTMP(I,1) = MISS_P
            IF(UTMESNET)OBTMP(I,2) = MISS_P
            IF(OBTMP(I,1).NE.MISS_P)OBTMP(I,1) = OBTMP(I,1) * 0.001
            IF(OBTMP(I,2).NE.MISS_P)OBTMP(I,2) = OBTMP(I,2) * 1000.0
 23      CONTINUE

         QCMISS(1) = .TRUE.
         IF(VQC(PCP1_VN_P,DSN).EQ.'Q')THEN

            CALL MGTNUM(VNAME(PCP1_VN_P,DSN)(1:VLEN(PCP1_VN_P,DSN))//
     1                  'QCA',SFC_NCID(FNUM),SFC_RECDIM(FNUM),1,
     2                  SFC_NRECS(FNUM),MISS_P,QCATMP(1,1),STATUS)
            IF(STATUS.EQ.VAR_NOTINDB_P)THEN
               QCSTATUS = EQCFAILED_P
               STATUS = SUCCESS_P
               DO I = 1, SFC_NRECS(FNUM)
                  QCATMP(I,1) = 0
                  QCRTMP(I,1) = 0
                  QCDTMP(I,1) = 'Z'
               ENDDO
            ELSE IF(STATUS.NE.SUCCESS_P)THEN
               RETURN
            ELSE
               CALL MGTNUM(VNAME(PCP1_VN_P,DSN)(1:VLEN(PCP1_VN_P,DSN))//
     1                  'QCR',SFC_NCID(FNUM),SFC_RECDIM(FNUM),1,
     2                  SFC_NRECS(FNUM),MISS_P,QCRTMP(1,1),STATUS)
               IF(STATUS.NE.SUCCESS_P)RETURN
               CALL MGTCHR(VNAME(PCP1_VN_P,DSN)(1:VLEN(PCP1_VN_P,DSN))//
     1                  'DD',SFC_NCID(FNUM),SFC_RECDIM(FNUM),1,
     2                  SFC_NRECS(FNUM),QCDTMP(1,1),LEN1REC,STATUS)
               IF(STATUS.NE.SUCCESS_P)RETURN
            ENDIF
            QCMISS(1) = .FALSE.

         ELSE
            QCSTATUS = EQCFAILED_P

            DO 11 I = 1, SFC_NRECS(FNUM)
               QCATMP(I,1) = 0
               QCRTMP(I,1) = 0
               QCDTMP(I,1) = 'Z'
 11         CONTINUE

         ENDIF

C     ------------------------------------------------------------------
C     FILL IN WHAT THE CALLER ASKED FOR.
C     ------------------------------------------------------------------
         IF(VCN.EQ.PCP1_VN_P)THEN

            IF(QCMISS(1) .AND. QCMISS(2))THEN
               QCSTATUS = EQCFAILED_P
            ELSE
               QCSTATUS = EQCOK_P
            ENDIF
               
               
            DO 31 I = 1, SFC_NRECS(FNUM)

               IF(.NOT.QCMISS(1) .AND. OBTMP(I,1).NE.MISS_P)THEN

                  OB(I) = OBTMP(I,1)
                  QCAPP(I) = QCATMP(I,1)
                  QCRES(I) = QCRTMP(I,1)
                  QCDESC(I) = QCDTMP(I,1)

               ELSE IF(.NOT.QCMISS(2) .AND. OBTMP(I,2).NE.MISS_P)THEN

                  OB(I) = OBTMP(I,2) * 3600.0 / 1000.0
                  QCAPP(I) = QCATMP(I,2)
                  QCRES(I) = QCRTMP(I,2)
                  QCDESC(I) = QCDTMP(I,2)

               ELSE IF(OBTMP(I,1).NE.MISS_P)THEN

                  OB(I) = OBTMP(I,1)
                  QCAPP(I) = QCATMP(I,1)
                  QCRES(I) = QCRTMP(I,1)
                  QCDESC(I) = QCDTMP(I,1)

               ELSE IF(OBTMP(I,2).NE.MISS_P)THEN

                  OB(I) = OBTMP(I,2) * 3600.0 / 1000.0
                  QCAPP(I) = QCATMP(I,2)
                  QCRES(I) = QCRTMP(I,2)
                  QCDESC(I) = QCDTMP(I,2)

               ELSE

                  OB(I) = MISS_P
                  QCAPP(I) = 0
                  QCRES(I) = 0
                  QCDESC(I) = 'Z'

               ENDIF

 31         CONTINUE

         ELSE

            IF(QCMISS(1) .AND. QCMISS(2))THEN
               QCSTATUS = EQCFAILED_P
            ELSE
               QCSTATUS = EQCOK_P
            ENDIF
            DO 41 I = 1, SFC_NRECS(FNUM)

               IF(.NOT. QCMISS(2) .AND. OBTMP(I,2).NE.MISS_P)THEN

                  OB(I) = OBTMP(I,2)
                  QCAPP(I) = QCATMP(I,2)
                  QCRES(I) = QCRTMP(I,2)
                  QCDESC(I) = QCDTMP(I,2)

               ELSE IF(.NOT. QCMISS(1) .AND. OBTMP(I,1).NE.MISS_P)THEN

                  OB(I) = OBTMP(I,1) * 1000. / 3600.
                  QCAPP(I) = QCATMP(I,1)
                  QCRES(I) = QCRTMP(I,1)
                  QCDESC(I) = QCDTMP(I,1)

               ELSE IF(OBTMP(I,2).NE.MISS_P)THEN

                  OB(I) = OBTMP(I,2)
                  QCAPP(I) = QCATMP(I,2)
                  QCRES(I) = QCRTMP(I,2)
                  QCDESC(I) = QCDTMP(I,2)

               ELSE IF(OBTMP(I,1).NE.MISS_P)THEN

                  OB(I) = OBTMP(I,1) * 1000. / 3600.
                  QCAPP(I) = QCATMP(I,1)
                  QCRES(I) = QCRTMP(I,1)
                  QCDESC(I) = QCDTMP(I,1)

               ELSE

                  OB(I) = MISS_P
                  QCAPP(I) = 0
                  QCRES(I) = 0
                  QCDESC(I) = 'Z'

               ENDIF

 41         CONTINUE

         ENDIF

      ELSE

C     ------------------------------------------------------------------
C     THIS IS EITHER 24H ACCUM SINCE LOCAL OR UTC MIDNIGHT, OR XH 
C     ACCUM OVER THE LAST X HOURS (X=3/6/12/18/24), OR XM ACCUM OVER
C     THE LAST X MINUTES.  READ IN THE DATA, AND GET THE PROVIDER NAMES 
C     SO WE CAN TELL WHICH HAVE THE DESIRED VARIABLE IN THE GENERIC 
C     PRECIPACCUM VARIABLE.
C     ------------------------------------------------------------------
         CALL MGTNUM(VNAME(VCN,DSN)(1:VLEN(VCN,DSN)),
     1               SFC_NCID(FNUM),SFC_RECDIM(FNUM),1,SFC_NRECS(FNUM),
     2               MISS_P,OBTMP(1,1),STATUS)
         IF(STATUS.NE.SUCCESS_P)RETURN

         CALL MGTCHR('dataProvider',SFC_NCID(FNUM),SFC_RECDIM(FNUM),1,
     1               SFC_NRECS(FNUM),DPTMP,LEN1REC,STATUS)
         IF(STATUS.NE.SUCCESS_P)RETURN

         CALL MGTCHR('stationName',SFC_NCID(FNUM),SFC_RECDIM(FNUM),1,
     1               SFC_NRECS(FNUM),LNTMP,LEN1REC,STATUS)
         IF(STATUS.NE.SUCCESS_P)RETURN

C     ------------------------------------------------------------------
C     BEFORE CONTINUING, PUT THE OBS INTO THE PROPER UNITS.
C     (ACCUM:  MM -> M)
C     ALSO WIPE OUT ACCUM OBS FOR ANY PROVIDERS THAT AREN'T PUTTING
C     THE DESIRED ACCUMULATION INTO THE GENERIC VARIABLE.
C     ------------------------------------------------------------------
         IF(VCN.EQ.PCPLCL_VN_P)THEN
            DESIRED_CODE = -1
         ELSE IF(VCN.EQ.PCPUTC_VN_P)THEN
            DESIRED_CODE = -2
         ELSE IF(VCN.EQ.PCP24_VN_P)THEN
            DESIRED_CODE = -3
         ELSE IF(VCN.EQ.PCP3_VN_P)THEN
            DESIRED_CODE = 3
         ELSE IF(VCN.EQ.PCP6_VN_P)THEN
            DESIRED_CODE = 6
         ELSE IF(VCN.EQ.PCP12_VN_P)THEN
            DESIRED_CODE = 12
         ELSE IF(VCN.EQ.PCP18_VN_P)THEN
            DESIRED_CODE = 18
         ELSE IF(VCN.EQ.PCP5M_VN_P)THEN
            DESIRED_CODE = -4
         ELSE IF(VCN.EQ.PCP15M_VN_P)THEN
            DESIRED_CODE = -5
         ENDIF

         DO 223 I = 1, SFC_NRECS(FNUM)

            K = M_LSTCHR(DPTMP(I),10)
            ACCUM_CODE = 0

            DO 224 J = 1, NPVD(1)

               IF(K.EQ.PVDLEN(J,1).AND.DPTMP(I)(1:K).EQ.
     1            PVDNAME(J,1)(1:K))THEN

                  IF(SUB_CODE(J,1).EQ.0)THEN

C     ------------------------------------------------------------------
C     IF THE PROVIDER IS APRSWXNET THEN THEN HARD CODE THE DATA 
C     TO THE LAST 24 HOURS.
C     ------------------------------------------------------------------
                     IF(DPTMP(I)(1:K).EQ."APRSWXNET")THEN
                        ACCUM_CODE = -3
                     ELSE
                        ACCUM_CODE = PACCUM_P_CODE(J,1)
                     ENDIF

                     GO TO 225

                  ELSE

                     L = M_LSTCHR(LNTMP(I)(40:50),11)
                     IF(L.EQ.0)GO TO 225

                     DO 226 M = 1, NSUB(1)

                        IF(L.EQ.SUBLEN(M,1).AND.LNTMP(I)(40:40+L-1).EQ.
     1                     SUBNAME(M,1)(1:L))THEN
                           
C     ------------------------------------------------------------------
C     IF THE PROVIDER IS APRSWXNET THEN THEN HARD CODE THE DATA 
C     TO THE LAST 24 HOURS.
C     ------------------------------------------------------------------
                           IF(DPTMP(I)(1:K).EQ."APRSWXNET")THEN
                              ACCUM_CODE = -3
                           ELSE
                              ACCUM_CODE = PACCUM_S_CODE(M,1)
                           ENDIF
                           GO TO 225

                        ENDIF

 226                 CONTINUE

                  ENDIF

               ENDIF

 224        CONTINUE

 225        IF(ACCUM_CODE.NE.DESIRED_CODE)OBTMP(I,1) = MISS_P
            IF(OBTMP(I,1).NE.MISS_P)OBTMP(I,1) = OBTMP(I,1) * 0.001
 223     CONTINUE

C     ASSUME QC OK, SET FOR DIFFERNET CONDITIONS
         QCSTATUS = EQCOK_P

         IF(VQC(VCN,DSN).EQ.'Q')THEN

            CALL MGTNUM(VNAME(VCN,DSN)(1:VLEN(VCN,DSN))//
     1                  'QCA',SFC_NCID(FNUM),SFC_RECDIM(FNUM),1,
     2                  SFC_NRECS(FNUM),MISS_P,QCATMP(1,1),STATUS)
            IF(STATUS.EQ.VAR_NOTINDB_P)THEN
               QCSTATUS = EQCFAILED_P
               STATUS = SUCCESS_P
               DO I = 1, SFC_NRECS(FNUM)
                  QCATMP(I,1) = 0
                  QCRTMP(I,1) = 0
                  QCDTMP(I,1) = 'Z'
               ENDDO
            ELSE IF(STATUS.NE.SUCCESS_P)THEN
               RETURN
            ELSE
               CALL MGTNUM(VNAME(VCN,DSN)(1:VLEN(VCN,DSN))//
     1                  'QCR',SFC_NCID(FNUM),SFC_RECDIM(FNUM),1,
     2                  SFC_NRECS(FNUM),MISS_P,QCRTMP(1,1),STATUS)
               IF(STATUS.NE.SUCCESS_P)RETURN

               CALL MGTCHR(VNAME(VCN,DSN)(1:VLEN(VCN,DSN))//
     1                  'DD',SFC_NCID(FNUM),SFC_RECDIM(FNUM),1,
     2                  SFC_NRECS(FNUM),QCDTMP(1,1),LEN1REC,STATUS)
               IF(STATUS.NE.SUCCESS_P)RETURN
            ENDIF
         ELSE

            QCSTATUS = EQCFAILED_P
            DO 211 I = 1, SFC_NRECS(FNUM)
               QCATMP(I,1) = 0
               QCRTMP(I,1) = 0
               QCDTMP(I,1) = 'Z'
 211        CONTINUE

         ENDIF

C     ------------------------------------------------------------------
C     FILL IN WHAT THE CALLER ASKED FOR.
C     ------------------------------------------------------------------
         DO 231 I = 1, SFC_NRECS(FNUM)

            IF(OBTMP(I,1).NE.MISS_P)THEN

               OB(I) = OBTMP(I,1)
               QCAPP(I) = QCATMP(I,1)
               QCRES(I) = QCRTMP(I,1)
               QCDESC(I) = QCDTMP(I,1)

            ELSE

               OB(I) = MISS_P
               QCAPP(I) = 0
               QCRES(I) = 0
               QCDESC(I) = 'Z'

            ENDIF

 231     CONTINUE

      ENDIF

      RETURN
      END
C**---------------------------------------------------------------------
C**REQUIRED STANDARD FSL DISCLAIMER (NOVEMBER 2000)
C**---------------------------------------------------------------------
C**  OPEN SOURCE LICENSE/DISCLAIMER,  FORECAST SYSTEMS LABORATORY
C**  NOAA/OAR/FSL, 325 BROADWAY BOULDER, CO 80305
C**
C**  THIS SOFTWARE IS DISTRIBUTED UNDER THE OPEN SOURCE DEFINITION, 
C**  WHICH MAY BE FOUND AT http://www.opensource.org/osd.html.
C**
C**  IN PARTICULAR, REDISTRIBUTION AND USE IN SOURCE AND BINARY FORMS,
C**  WITH OR WITHOUT MODIFICATION, ARE PERMITTED PROVIDED THAT THE 
C**  FOLLOWING CONDITIONS ARE MET:
C**
C**  - REDISTRIBUTIONS OF SOURCE CODE MUST RETAIN THIS NOTICE, THIS LIST
C**    OF CONDITIONS AND THE FOLLOWING DISCLAIMER.
C**
C**  - REDISTRIBUTIONS IN BINARY FORM MUST PROVIDE ACCESS TO THIS 
C**    NOTICE, THIS LIST OF CONDITIONS AND THE FOLLOWING DISCLAIMER, AND
C**    THE UNDERLYING SOURCE CODE.
C**
C**  - ALL MODIFICATIONS TO THIS SOFTWARE MUST BE CLEARLY DOCUMENTED, 
C**    AND ARE SOLELY THE RESPONSIBILITY OF THE AGENT MAKING THE 
C**    MODIFICATIONS.
C**
C**  - IF SIGNIFICANT MODIFICATIONS OR ENHANCEMENTS ARE MADE TO THIS
C**    SOFTWARE, THE FSL SOFTWARE POLICY MANAGER 
C**    (softwaremgr.fsl@noaa.gov) BE NOTIFIED.
C**
C**  THIS SOFTWARE AND ITS DOCUMENTATION ARE IN THE PUBLIC DOMAIN AND 
C**  ARE FURNISHED "AS IS."  THE AUTHORS, THE UNITED STATES GOVERNMENT,
C**  ITS INSTRUMENTALITIES, OFFICERS, EMPLOYEES, AND AGENTS MAKE NO 
C**  WARRANTY, EXPRESS OR IMPLIED, AS TO THE USEFULNESS OF THE SOFTWARE
C**  AND DOCUMENTATION FOR ANY PURPOSE.  THEY ASSUME NO RESPONSIBILITY 
C**  (1) FOR THE USE OF THE SOFTWARE AND DOCUMENTATION; OR (2) TO 
C**  PROVIDE TECHNICAL SUPPORT TO USERS.
C**---------------------------------------------------------------------
