C$$$  SUBPROGRAM DOCUMENTATION BLOCK
C                .      .    .                                       .
C SUBPROGRAM:    MGETUAPT    GET UPPER-AIR-POINT OBS & QC FOR A VARIABLE
C   PRGMMR: M. BARTH         ORG: FSL        DATE: 00-03-24
C
C ABSTRACT: READ UPPER-AIR-POINT OBS & QC INFO FOR ALL STATIONS FOR ONE
C   VARIABLE AND TIME.
C
C PROGRAM HISTORY LOG:
C   00-03-24  M. BARTH    ORIGINAL VERSION
C   01-05-03  M. BARTH    CHANGES FOR AWIPS-FORMATTED RAOB FILES
C   01-07-02  M. BARTH    - ADDED CDBTYPE
C                         - ADDED DSN ARGUMENT TO MQCFLTR
C                         - FIXED LOGIC ERROR THAT CAUSED FILES TO
C                           BE PROCESSED MULTIPLE TIMES GIVEN SOME
C                           TIME WINDOW CHOICES
C                         - CHANGES FOR NPN AWIPS DATABASE
C                         - CHANGED DEFINITION OF MXSTA TO CONFORM WITH
C                           G77 COMPILER, AND FIXED BUG REVEALED BY IT
C                           (WE WERE CHANGING CALLER'S VCN, SHOULDN'T
C                            HAVE)
C                         - ADDED Q (SPECIFIC HUMIDITY), TV (VIRTUAL
C                           TEMPERATURE), AND PRESSURE FOR ACARS & NPN.
C                         - FIXED BUG WHERE NLEVELS WASN'T BEING FILLED
C                           IN PROPERLY WHEN MNPNHT IS CALLED.
C                         - CHANGE FROM CALLER-SPECIFIED VARIABLE CODE
C                           NUMBER TO VARIABLE CODE NAME
C   02-04-30  M. BARTH    ADDED MAP DATASET                      
C   02-05-29  M. BARTH    RESTRUCTURED TEMPORARY MEMORY ARRAY USAGE
C   03-07-02  M. BARTH    - ADDED RDMTR DATASET
C                         - ADDED ABSOLUTE HUMIDITY VARIABLE
C                         - RENAMED MMAPHT TO MUAPTHTP
C   03-10-10  M. BARTH    CHANGES FOR AWIPS-FORMATTED ACARS FILES
C   04-06-17  M. BARTH    ADDED ACARSP DATASET
C   04-10-16  L. BENJAMIN ADDED NO SUCH VARIABLE CHECK FOR QCA CHECKS
C   05-06-01  L. BENJAMIN ADDED WVMR
C   06-09-06  L. BENJAMIN CHANGE MAP RASS LEVELS TO 30 GATES FROM 15
C   08-07-27  L. BENJAMIN REMOVED COMMENTED CODE
C   08-08-15  L. BENJAMIN ADDED MISS_P AS MISSING DATA ARGUMENT FOR
C                         M_ZTOPSA.
C
C USAGE:    CALL MGETUAPT (ATIME,VCODE,NSTA,NOBS,NLEVELS,OB,QCDESC,
C                          QCAPP,QCRES,STATUS)
C
C   INPUT ARGUMENT LIST:
C     ATIME    - C       YYJJJHHMM OF THE DATA TO BE READ
C     VCODE    - C       VARIABLE CODE NAME
C
C   OUTPUT ARGUMENT LIST:
C     NSTA     - I       NUMBER OF STATIONS RETURNED
C     NOBS     - I       NUMBER OF NON-MISSING OBS
C     NLEVELS  - IA      NUMBER OF LEVELS
C     OB       - RA      OBSERVATIONS IN M/K/S UNITS
C     QCDESC   - CA      QC DATA DESCRIPTORS
C     QCAPP    - IA      QC APPLIED WORD (SHOWS CHECKS APPLIED)
C     QCRES    - IA      QC RESULTS WORD (GOOD/BAD FOR EACH CHECK)
C     STATUS   - I       0 - SUCCESS, OR ERROR CODE
C
C   INPUT FILES:
C     MADIS UPPER-AIR-POINT NETCDF FILES FOR ATIME
C
C SUBPROGRAMS CALLED:
C     UNIQUE:    MERROR, MUAPTMOI, MUAPTWIND, MNPNBEAM, MGTNUM,
C                MGTCHR, MRDDIM, MQCFLTR, MGENVCN, M_ZTOPSA,
C                MNPNHT, MNPNLT, MNPNEXT, MRAOBEXT, MUAPTTV, MGETVCN,
C                MMAPLT, MMAPWMODE, MMAPBEAM, MMAPVC, MMAPEXT,
C                MMAPWIND, MUAPTHTP
C
C REMARKS:
C   - THE CALLER MUST CALL MINIT AND MUAPTSTA BEFORE CALLING THIS
C     ROUTINE.  MUAPTSTA SHOULD BE CALLED FIRST WHENEVER ACCESS TO
C     A NEW TIME IS DESIRED.  IT STORES INFO IN THE STRCCOM COMMON
C     THAT IS USED BY THIS ROUTINE TO FIGURE OUT WHICH RECORDS ARE
C     NEEDED ON NETCDF FILES OPENED BY MUAPTSTA.
C   - DOUBLE & CHARACTER DATA TYPES ARE NOT HANDLED BY THIS ROUTINE.
C   - THE CALLER SHOULD DIMENSION ARRAYS TO MATCH THE MAXIMUM NUMBER
C     OF LEVELS AND STATIONS POSSIBLE FOR THIS DATATYPE (madiscon.f).
C   - LOCAL ARRAYS ARE DIMENSIONED TO THE MAXIMUM NUMBER OF MAP
C     STATIONS * THE MAXIMUM NUMBER OF MAP LEVELS.  AS THIS NUMBER
C     IS CURRENTLY LARGER THAN THE CORRESPONDING VALUE FOR THE
C     OTHER UPPER-AIR-POINT DATASETS, THIS ONE'S USED (IN THE
C     MXTMP PARAMETER).  THIS NUMBER SHOULD BE REVISITED AS NEW
C     UPPER-AIR-POINT DATASETS ARE ADDED.
C   - THE FEATURE WHERE THE CALLER CAN SPECIFY THE LEVELS ON WHICH
C     HE/SHE WANTS DATA RETURNED HAS NOT BEEN IMPLEMENTED.  HOWEVER,
C     AS SOMEDAY THE DECISION MAY BE MADE TO DO THIS, CODE AND
C     COMMENTS IN THIS ROUTINE REFERRING TO "VCTYPE" AND "CALLER-
C     SPECIFIED LEVELS" REMAIN, ALTHOUGH THE VCTYPE CANNOT BE SET
C     TO ANYTHING OTHER THAN 0.  ALSO NOTE THAT THE FUAPTITP
C     ROUTINE DESIGNED TO DO MOST OF THIS LOGIC HAS NEVER BEEN
C     WRITTEN SO IF THIS FEATURE DOES GET ADDED IN THE FUTURE THE
C     RELATED LOGIC STILL IN THIS ROUTINE NEEDS TO BE TESTED.
C   - NOTE THAT MXSTA MUST BE EQUAL TO THE LARGEST "MAXSTA" 
C     PARAMETER FOR ANY OF THE UPPER-AIR DATASETS.  WE CAN'T
C     USE THE MAX FUNCTION IN THE PARAMETER DEFINITION BECAUSE
C     G77 WON'T LET US...
C   - THERE ARE A FEW PLACES WHERE THE MAXIMUM NUMBER OF MAP WIND
C     MODES IS HARD-WIRED -- THIS USES THE MXWMODE LOCAL PARAMETER
C     AND SHOULD BE MODIFIED IF THE MAP FOLKS EVER ADD A MODE.
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 MGETUAPT(ATIME,VCODE,NSTA,NOBS,NLEVELS,OB,QCDESC,
     1                    QCAPP,QCRES,STATUS)

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

C     ------------------------------------------------------------------
C     ARGUMENTS
C     ------------------------------------------------------------------
      CHARACTER*9 ATIME
      CHARACTER*(*) VCODE
      INTEGER NSTA,NOBS,NLEVELS(*),QCAPP(*),QCRES(*),STATUS
      REAL OB(*)
      CHARACTER*1 QCDESC(*)

C     ------------------------------------------------------------------
C     LOCAL
C     ------------------------------------------------------------------
      INTEGER I,J,K,L,FNUM,DSN,LEN1REC,CD,VCN,SPT,NLT,ORIG_VCN
      INTEGER MXTMP,NC,NV,BEAMDIM,LEVDIM,NVDIMS,DIMSIZ(MAXVDIMS),MXWMODE
      PARAMETER (MXTMP = MXMAP_P * MXMAPLEV_P)
      PARAMETER (MXWMODE = 3)
      REAL OBTMP(MXTMP),QCATMP(MXTMP),QCRTMP(MXTMP)
      CHARACTER*1 QCDTMP(MXTMP),VCT
      INTEGER MXSTA
      PARAMETER (MXSTA=MXACARS_P)
      INTEGER NLREC(MXSTA)
      CHARACTER*(MAXNCNAM) DIMNAM(MAXVDIMS)
      INTEGER NRAOBLEVS(6)
      LOGICAL PROC_FILE(UAPT_MXSTRF)
      REAL M_ZTOPSA

C     ------------------------------------------------------------------
C     TEMPORARY STORAGE DEFINITIONS
C     ------------------------------------------------------------------
      EQUIVALENCE(OBTMP,TMP_L1_N1)
      EQUIVALENCE(QCATMP,TMP_L1_N2)
      EQUIVALENCE(QCRTMP,TMP_L1_N3)
      EQUIVALENCE(QCDTMP,TMP_L1_C1)

C     ------------------------------------------------------------------
C     DATA STATEMENTS (KEEP AT BOTTOM OF DECLARATIONS)
C     ------------------------------------------------------------------
      DATA NRAOBLEVS/MXRAOBMAN_P,MXRAOBMAN_P,MXRAOBSIGT_P,MXRAOBSIGW_P,
     1               MXRAOBMXWND_P,MXRAOBTROP_P/


C     ------------------------------------------------------------------
C     IF THE DESIRED SUBSYSTEM HASN'T BEEN INITIALIZED, OR IF THE
C     REQUESTED TIME DOESN'T MATCH THE TIME LAST PROCESSED BY MUAPTSTA,
C     OR IF THE VCODE IS ILLEGAL, OR IF THE VARIABLE'S DOUBLE OR
C     CHARACTER DATA TYPE, RETURN WITH ERROR.
C     ------------------------------------------------------------------
      CD = CDTYPE
      CDBTYPE = UAPT_DBTYPE(CD)
      DSN = MAX_SFCDSET_P + CD
      BEAMDIM = 0
      SPT = 0

      IF(CD.LT.1.OR.CD.GT.MAX_UAPTDSET_P)THEN
         STATUS = SELSUB_NOTINIT_P
         CALL MERROR('MGETUAPT: SELECTED SUBSYSTEM NOT INITIALIZED')
         GO TO 900
      ELSE IF(UAPT_INIT(CD).NE.INIT_P)THEN
         STATUS = SELSUB_NOTINIT_P
         CALL MERROR('MGETUAPT: SELECTED SUBSYSTEM NOT INITIALIZED'//
     1               ' - '//UAPTDSET_NAME(CD))
         GO TO 900
      ELSE IF(ATIME.NE.LAST_UAPT_ATIME(CD).OR.ATIME.EQ.'         ')THEN
         STATUS = TIME_NOTINIT_P
         CALL MERROR('MGETUAPT: TIME NOT INITIALIZED BY MUAPTSTA'//
     1               ' - '//UAPTDSET_NAME(CD))
         GO TO 900
      ENDIF

      CALL MGETVCN(VCODE,ORIG_VCN,VCT,STATUS)
      IF(STATUS.NE.SUCCESS_P)GO TO 900

C     ------------------------------------------------------------------
C     TRANSLATE THE CALLER'S VCN INTO THE GENERIC VERSION.  THIS IS
C     NEEDED, FOR EXAMPLE, TO ALLOW THE CALLER TO SELECT ONLY MANDATORY
C     LEVELS FOR RAOBS.  FOR MOST OF THIS ROUTINE (AND ITS SUBORDINATES)
C     WE'LL DEAL WITH THE GENERIC VERSION TO MAKE THINGS SIMPLER, THEN
C     DEAL WITH THE CALLER'S DESIRED SUBSET WHEN IT COMES TIME TO
C     RETURN THE ACUAL DATA.
C     ------------------------------------------------------------------
      IF(CD.EQ.NPN_DS_P.OR.CD.EQ.RAOB_DS_P.OR.CD.EQ.MAP_DS_P.OR.
     1   CD.EQ.RDMTR_DS_P.OR.CD.EQ.ACARSP_DS_P)THEN
         CALL MGENVCN(ORIG_VCN,CD,CDBTYPE,VCN,SPT)
      ELSE
         VCN = ORIG_VCN
      ENDIF

      IF(VDTYPE(VCN,DSN).EQ.'d'.OR.VDTYPE(VCN,DSN).EQ.'c')THEN
         STATUS = INV_DTYPE_P
         CALL MERROR('MGETUAPT: INVALID VARIABLE DATA TYPE'//
     1               ' - '//UAPTDSET_NAME(CD))
         GO TO 900
      ENDIF

C     ------------------------------------------------------------------
C     THEN LOOP THROUGH THE FILES THAT ARE NEEDED AND PUT IN REAL DATA
C     WHERE AVAILABLE.
C     ------------------------------------------------------------------
      NSTA = UAPT_LNUM(CD)

      IF(NSTA.EQ.0)THEN
         STATUS = NO_DATA_P
         GO TO 900
      ENDIF

      FNUM = 0
      RAOB_HT_QC = .FALSE.
      RAOB_WIND_QC = .FALSE.

      DO 22 I = 1, UAPT_MXSTRF
         PROC_FILE(I) = .FALSE.
 22   CONTINUE

C     ------------------------------------------------------------------
C     NOTE THAT WE LOOP THROUGH UAPT_FNUM TO SEE WHICH FILES ARE NEEDED
C     AND NOT THROUGH UAPT_NFILES.  THIS IS DONE AS JUST BECAUSE A FILE
C     GOT READ DOESN'T MEAN ANY OF ITS RECORDS ACTUALLY WERE EXTRACTED
C     WHEN ALL THE FILTERING WAS DONE IN MUAPTSTA.  THEREFORE, WE'LL
C     ONLY PROCESS EACH FILE WITH RECORDS IN USE.
C     ------------------------------------------------------------------
      DO 100 I = 1, NSTA

C     ------------------------------------------------------------------
C     ALREADY HANDLED THIS FILE.
C     ------------------------------------------------------------------
         IF(PROC_FILE(UAPT_FNUM(I,CD)))GO TO 100

C     ------------------------------------------------------------------
C     INDICATE THAT WE DON'T YET HAVE THE PROFILER LEVEL TYPE INFO FOR
C     THIS FILE.
C     ------------------------------------------------------------------
         HAVE_NPN_LT = .FALSE.
         HAVE_MAP_LT = .FALSE.

C     ------------------------------------------------------------------
C     IF THIS IS THE FIRST TIME WE'VE BEEN HERE FOR ANY FILE, DETERMINE
C     HOW MANY LEVELS THE CALLER'S EXPECTING FOR THIS VARIABLE (NC), AND
C     HOW MANY LEVELS EXIST IN THE NETCDF VARIABLE (NV).  THEN 
C     INITIALIZE THE CALLER'S ARRAYS TO ALL MISSING FLAGS, AND OUR 
C     LOCAL DATA ARRAY TO ALL MISSING.
C     ------------------------------------------------------------------
         IF(FNUM.EQ.0)THEN

            FNUM = UAPT_FNUM(I,CD)

C     ------------------------------------------------------------------
C     NC AND NV DETERMINATION - RAOB
C     ------------------------------------------------------------------
            IF(CD.EQ.RAOB_DS_P)THEN

               IF(VCN.EQ.RAOBST_VN_P)THEN
                  NV = 1
               ELSE
                  NV = MXRAOBLEV_P
               ENDIF

C     ------------------------------------------------------------------
C     THE NUMBER OF LEVELS TO BE RETURNED FOR EACH STATION IS A FUNCTION
C     OF WHAT'S STORED IN THE VARIABLE, AND WHAT THE CALLER HAS ASKED
C     FOR.
C
C     - IF THIS ISN'T A LEVEL-DIMENSIONED VARIABLE, THE ACTUAL VARIABLE
C       SIZE IS ALWAYS USED.
C     - IF THE CALLER HAS ASKED FOR DATA TO BE RETURNED ON SPECIFIED
C       LEVELS, THAT'S THE SIZE OF WHAT HE'S EXPECTING FOR LEVEL DATA
C       (VCNLEV IS THE DIMENSION IN MADISCOM).
C     - IF THE CALLER HAS ASKED FOR A SUBSET OF STORED LEVELS (E.G.,
C       MANDATORY RAOB LEVELS, LOW MODE NPN LEVELS), THAT'S THE SIZE.
C     ------------------------------------------------------------------
               IF(VCTYPE.EQ.0.OR.NV.EQ.1)THEN
                  IF(SPT.EQ.0.OR.NV.EQ.1)THEN
                     NC = NV
                  ELSE IF(SPT.GT.0)THEN
                     NC = NRAOBLEVS(SPT)
                  ENDIF
               ELSE IF(VCTYPE.GT.0)THEN
                  NC = VCNLEV
               ENDIF

C     ------------------------------------------------------------------
C     NC AND NV DETERMINATION - NPN & MAP
C     ------------------------------------------------------------------
            ELSE IF(CD.EQ.NPN_DS_P.OR.CD.EQ.MAP_DS_P)THEN

               CALL MRDDIM(VNAME(VCN,DSN)(1:VLEN(VCN,DSN)),
     1                     UAPT_NCID(FNUM,CD),NVDIMS,DIMNAM,DIMSIZ,
     2                     STATUS)
               IF(STATUS.NE.SUCCESS_P)GO TO 900

C     ------------------------------------------------------------------
C     IN ADDITION TO THE RECORD DIMENSION, NPN/MAP VARIABLES THAT WE 
C     MIGHT READ MAY INCLUDE A BEAM DIMENSION, A LEVEL DIMENSION, OR 
C     BOTH.  THIS ROUTINE WILL ONLY RETURN INFO FOR ONE BEAM AT A TIME, 
C     SO NC WILL BE SET ACCORDINGLY (NOT SO FAST:  MAP WIND MODE
C     PARAMETERS ARE RETURNED WITH ALL BEAMS...).  ALSO NOTE THAT 
C     VARIABLES WITH THE BEAM DIMENSION DON'T GET PLACED ON 
C     CALLER-SPECIFIED LEVELS.
C     ------------------------------------------------------------------
               K = 1
               BEAMDIM = 0
               LEVDIM = 0
               DO 1 J = 1, NVDIMS
                  IF(DIMNAM(J)(1:4).EQ.'beam')THEN
                     BEAMDIM = J
                  ELSE IF(DIMNAM(J)(1:5).EQ.'level')THEN
                     LEVDIM = J
                  ENDIF
                  IF(J.NE.NVDIMS)K = K * DIMSIZ(J)
 1             CONTINUE

               IF(BEAMDIM.EQ.0)THEN
                  IF(LEVDIM.NE.0)THEN
                     NV = DIMSIZ(LEVDIM)
                  ELSE
                     NV = 1
                  ENDIF
                  IF(VCTYPE.EQ.0.OR.NV.EQ.1)THEN
                     IF(SPT.EQ.0.OR.SPT.EQ.-10.OR.NV.EQ.1)THEN
                        NC = NV
                     ELSE IF(SPT.EQ.-1)THEN
                        IF(CDBTYPE.EQ.FSL_DB_P)THEN
                           NC = 64
                        ELSE IF(CDBTYPE.EQ.AWIPS_DB_P)THEN
                           NC = 43
                        ENDIF
                     ELSE IF(SPT.LE.-11)THEN
                        NC = 50
                     ELSE
                        IF(CDBTYPE.EQ.FSL_DB_P)THEN
                           NC = 36
                        ELSE IF(CDBTYPE.EQ.AWIPS_DB_P)THEN
                           IF(SPT.EQ.-2)THEN
                              NC = 36
                           ELSE
                              NC = 15
                           ENDIF
                        ENDIF
                     ENDIF
                  ELSE IF(VCTYPE.GT.0)THEN
                     NC = VCNLEV
                  ENDIF
               ELSE

C     ------------------------------------------------------------------
C     THIS ELSE IS FOR BEAMDIM IS IN PLAY.
C     ------------------------------------------------------------------
                  NV = K
                  IF(SPT.EQ.0.OR.SPT.EQ.-10)THEN
                     NC = K/DIMSIZ(BEAMDIM)
                  ELSE IF(SPT.EQ.-1)THEN
                     IF(CDBTYPE.EQ.FSL_DB_P)THEN
                        NC = 64
                     ELSE IF(CDBTYPE.EQ.AWIPS_DB_P)THEN
                        NC = 43
                     ENDIF
                  ELSE IF(SPT.LE.-11.AND.SPT.GE.-11-MXWMODE+1)THEN
                     NC = 50
                  ELSE IF(SPT.EQ.-11-MXWMODE)THEN
                     IF(CD.EQ.MAP_DS_P)THEN
                        NC = 30
                     ELSE
                        NC = 15
                     ENDIF
                  ELSE IF(SPT.EQ.-11-MXWMODE-1)THEN
                     NC = 5
                  ELSE
                     IF(CDBTYPE.EQ.FSL_DB_P)THEN
                        NC = 36
                     ELSE IF(CDBTYPE.EQ.AWIPS_DB_P)THEN
                        IF(SPT.EQ.-2)THEN
                           NC = 36
                        ELSE
                           NC = 15
                        ENDIF
                     ENDIF
                  ENDIF
               ENDIF

C     ------------------------------------------------------------------
C     NC AND NV DETERMINATION - ACARS
C     ------------------------------------------------------------------
            ELSE IF(CD.EQ.ACARS_DS_P)THEN

               NV = 1
               IF(VCTYPE.EQ.0)THEN
                  NC = NV
               ELSE
                  NC = VCNLEV
               ENDIF

C     ------------------------------------------------------------------
C     NC AND NV DETERMINATION - RDMTR
C     ------------------------------------------------------------------
            ELSE IF(CD.EQ.RDMTR_DS_P)THEN 

               IF(SPT.NE.-20)THEN
                  NV = 1
               ELSE
                  NV = MXRDMTRLEV_P
               ENDIF
               IF(VCTYPE.EQ.0.OR.NV.EQ.1)THEN
                  NC = NV
               ELSE IF(VCTYPE.GT.0)THEN
                  NC = VCNLEV
               ENDIF

C     ------------------------------------------------------------------
C     NC AND NV DETERMINATION - ACARSP
C     ------------------------------------------------------------------
            ELSE IF(CD.EQ.ACARSP_DS_P)THEN 

               IF(SPT.NE.-20)THEN
                  NV = 1
               ELSE
                  NV = MXACARSPLEV_P
               ENDIF
               IF(VCTYPE.EQ.0.OR.NV.EQ.1)THEN
                  NC = NV
               ELSE IF(VCTYPE.GT.0)THEN
                  NC = VCNLEV
               ENDIF
            ENDIF

C     ------------------------------------------------------------------
C     DONE WITH NC, NV DETERMINATION.  NOW FILL IN MISSING FLAGS.
C     ------------------------------------------------------------------
            DO 2 J = 1, NSTA * NC
               OB(J) = MISS_P
               QCDESC(J) = 'Z'
               QCAPP(J) = 0
               QCRES(J) = 0
 2          CONTINUE

            DO 3 J = 1, NSTA * NV
               OBTMP(J) = MISS_P
 3          CONTINUE

         ELSE

            FNUM = UAPT_FNUM(I,CD)

         ENDIF

         PROC_FILE(FNUM) = .TRUE.

C     ------------------------------------------------------------------
C     IF THIS IS RAOB DATA THE MRAOBNUM/CHR ROUTINES NEED TO KNOW THE
C     FNUM.
C     ------------------------------------------------------------------
         IF(CD.EQ.RAOB_DS_P)RAOB_FNUM = FNUM

C     ------------------------------------------------------------------
C     IF THE VARIABLE NEEDS TO BE CREATED FROM OTHER VARIABLES, OR
C     OTHER SPECIAL HANDLING IS NEEDED, CALL A SUBROUTINE TO FILL IN
C     THE LOCAL ARRAYS.  OTHERWISE, READ THE VARIABLE, AND IF AVAILABLE,
C     QC INFO.  IF THERE'S AN ERROR, THE SUBROUTINES WILL HAVE SET
C     STATUS & CALLED MERROR.
C     ------------------------------------------------------------------
         IF(CD.EQ.NPN_DS_P.AND.
     1      (VCN.EQ.NPNHT_VN_P.OR.VCN.EQ.NPNP_VN_P))THEN

C     ------------------------------------------------------------------
C     NOTE THAT THE HT/P OBS ARE PLACED DIRECTLY INTO THE CALLER'S
C     ARRAY.  THIS IS BECAUSE THE STATION ELEVATIONS USED TO COMPUTE
C     THEM ARE SAVED AFTER ANY TIME WINDOWING HAS BEEN DONE,
C     AND ARE THEREFORE ONLY KEPT FOR THOSE STATIONS THAT WILL BE
C     RETURNED.  THIS ALSO MEANS WE NEED TO SKIP THE LOGIC THAT
C     LOOPS THROUGH THE MULTIPLE FILES INVOLVED AND MOVES FROM THE
C     TEMPORARY ARRAYS TO THE CALLER'S ARRAYS BELOW.
C     ------------------------------------------------------------------
            CALL MNPNHT(VCN,SPT,UAPT_NRECS(FNUM,CD),NLEVELS,OB,QCDESC,
     1                  QCAPP,QCRES)
            STATUS = SUCCESS_P
            GO TO 900

         ELSE IF(CD.EQ.NPN_DS_P.AND.VCN.EQ.NPNLT_VN_P)THEN

            CALL MNPNLT(VCN,DSN,FNUM,NV,OBTMP,QCDTMP,QCATMP,QCRTMP,
     1                  STATUS)
            IF(STATUS.NE.SUCCESS_P)GO TO 900

         ELSE IF((CD.EQ.MAP_DS_P.AND.
     1            (VCN.EQ.MAPHT_VN_P.OR.VCN.EQ.MAPP_VN_P)).OR.
     2           (CD.EQ.RDMTR_DS_P.AND.
     3            (VCN.EQ.RDMTRHT_VN_P.OR.VCN.EQ.RDMTRP_VN_P)))THEN

C     ------------------------------------------------------------------
C     NOTE THAT OTHER DATASETS WHERE WE NEED TO CALCULATE HT/P OBS 
C     DON'T HAVE THE SAME POST-WINDOW PROBLEM AS WITH THE NPN HT/P OBS 
C     ABOVE.
C     ------------------------------------------------------------------
            CALL MUAPTHTP(VCN,DSN,FNUM,.TRUE.,NV,OBTMP,QCDTMP,QCATMP,
     1                    QCRTMP,STATUS)
            IF(STATUS.NE.SUCCESS_P)GO TO 900

         ELSE IF(CD.EQ.MAP_DS_P.AND.VCN.EQ.MAPLT_VN_P)THEN

            CALL MMAPLT(VCN,DSN,FNUM,NV,OBTMP,QCDTMP,QCATMP,QCRTMP,
     1                  STATUS)
            IF(STATUS.NE.SUCCESS_P)GO TO 900

         ELSE IF(CD.EQ.MAP_DS_P.AND.SPT.EQ.-11-MXWMODE-1)THEN

            CALL MMAPWMODE(VCN,DSN,FNUM,OBTMP,QCDTMP,QCATMP,QCRTMP,
     1                     STATUS)
            IF(STATUS.NE.SUCCESS_P)GO TO 900

         ELSE IF(((VCN.EQ.UAPTTD_VN_P.OR.VCN.EQ.UAPTRH_VN_P.OR.
     1             VCN.EQ.UAPTDPD_VN_P.OR.VCN.EQ.UAPTQ_VN_P.OR.
     2             VCN.EQ.UAPTAH_VN_P).AND
     3                .CD.NE.NPN_DS_P.AND.CD.NE.MAP_DS_P).OR.
     4            (VCN.EQ.UAPTMR_VN_P.AND.CD.EQ.RAOB_DS_P).OR.
     5            (VCN.EQ.UAPTMR_VN_P.AND.CD.EQ.RDMTR_DS_P).OR.
     6           ((CD.EQ.ACARS_DS_P.OR.CD.EQ.ACARSP_DS_P).AND.
     7             VCN.EQ.UAPTMR_VN_P.AND.CDBTYPE.EQ.FSL_DB_P).OR.
     8            (VCN.EQ.ACARSRH_VN_P.AND.CD.EQ.ACARS_DS_P.AND.
     9              CDBTYPE.EQ.FSL_DB_P))THEN

C     ------------------------------------------------------------------
C     NOTE THE CD.NE.NPN_DS_P/MAP_DS_P IN THE ABOVE IF:  THE HEIGHT 
C     VARIABLE FOR THOSE DATASETS MATCHES UAPTRH_VN_P.  UGLY, BUT 
C     THAT'S SHOWBIZ...
C     ------------------------------------------------------------------
            CALL MUAPTMOI(VCN,DSN,FNUM,NV,OBTMP,QCDTMP,QCATMP,QCRTMP,
     1                    STATUS)
            IF(STATUS.NE.SUCCESS_P)GO TO 900

         ELSE IF(VCN.EQ.UAPTTV_VN_P.AND.CD.NE.NPN_DS_P.AND.
     1           CD.NE.MAP_DS_P)THEN

C     ------------------------------------------------------------------
C     ...AND NPN'S W STD DEV VARIABLE MATCHES UAPTTV_VN_P..., AND WHILE
C     THE MAP VARIABLE OF THE SAME NUMBER DOES HAPPEN TO BE FOR TV
C     (STRICTLY A COINCIDENCE!), THE TV LOGIC FOR THAT DATASET IS
C     COMPLETELY SEPARATE FROM THAT OF THE OTHER UPPER-AIR DATASETS.
C     ------------------------------------------------------------------
            CALL MUAPTTV(DSN,FNUM,NV,OBTMP,QCDTMP,QCATMP,QCRTMP,STATUS)
            IF(STATUS.NE.SUCCESS_P)GO TO 900

         ELSE IF(VCN.EQ.UAPTU_VN_P.OR.VCN.EQ.UAPTV_VN_P.OR.
     1           VCN.EQ.UAPTFF_VN_P.OR.VCN.EQ.UAPTDD_VN_P)THEN

            IF(CD.NE.MAP_DS_P)THEN

               CALL MUAPTWIND(VCN,DSN,FNUM,NV,OBTMP,QCDTMP,QCATMP,
     1                        QCRTMP,STATUS)
               IF(STATUS.NE.SUCCESS_P)GO TO 900

            ELSE IF(CD.EQ.MAP_DS_P)THEN

               CALL MMAPWIND(VCN,DSN,FNUM,NV,OBTMP,QCDTMP,QCATMP,
     1                       QCRTMP,STATUS)
               IF(STATUS.NE.SUCCESS_P)GO TO 900

               IF(VCN.NE.UAPTDD_VN_P)THEN

C     ------------------------------------------------------------------
C     MAP SPEEDS HAVE TO BE CONVERTED FROM KTS TO M/S.
C     ------------------------------------------------------------------
                  DO J = 1, UAPT_NRECS(FNUM,CD) * NV
                     IF(OBTMP(J).NE.MISS_P)OBTMP(J) = 
     1                                       OBTMP(J)/1.943861286
                  ENDDO

               ENDIF

            ENDIF

            RAOB_WIND_QC = .TRUE.

         ELSE IF(BEAMDIM.NE.0)THEN

            IF(CD.EQ.NPN_DS_P)THEN

               CALL MNPNBEAM(VCN,DSN,FNUM,NVDIMS,OBTMP,QCDTMP,QCATMP,
     1                       QCRTMP,STATUS)
               IF(STATUS.NE.SUCCESS_P)GO TO 900

            ELSE IF(CD.EQ.MAP_DS_P)THEN

               CALL MMAPBEAM(VCN,DSN,FNUM,NVDIMS,OBTMP,QCDTMP,QCATMP,
     1                       QCRTMP,STATUS)
               IF(STATUS.NE.SUCCESS_P)GO TO 900

            ENDIF

C     ------------------------------------------------------------------
C     MAP VERTICAL CORRECTION FLAGS:  USER ASKS FOR ONE MODE, ALL
C     MODES GET READ IN FOR THE VARIABLE...
C     ------------------------------------------------------------------
         ELSE IF(CD.EQ.MAP_DS_P.AND.(VCN.EQ.MAPVC_1_VN_P.OR.
     1           VCN.EQ.MAPVC_2_VN_P.OR.VCN.EQ.MAPVC_3_VN_P))THEN

            CALL MMAPVC(VCN,DSN,FNUM,OBTMP,QCDTMP,QCATMP,QCRTMP,STATUS)
            IF(STATUS.NE.SUCCESS_P)GO TO 900

C     ------------------------------------------------------------------
C     MAP MODE ONLY DIMENSION VARAIBLES:  USER ASKS FOR ONE MODE, ALL
C     MODES GET READ IN FOR THE VARIABLE...
C     ------------------------------------------------------------------
         ELSE IF(CD.EQ.MAP_DS_P.AND.(
     1           (VCN.EQ.MAPAP_1_VN_P.OR.VCN.EQ.MAPAP_2_VN_P.OR.
     2           VCN.EQ.MAPAP_3_VN_P) .OR.
     5           (VCN.EQ.MAPNL_1_VN_P.OR.VCN.EQ.MAPNL_2_VN_P.OR.
     6           VCN.EQ.MAPNL_3_VN_P) 
     7           ))THEN

            CALL MMAPMDVAR(VCN,DSN,FNUM,OBTMP,QCDTMP,QCATMP,QCRTMP,
     1           STATUS)
            IF(STATUS.NE.SUCCESS_P)GO TO 900

         ELSE

            CALL MGTNUM(VNAME(VCN,DSN)(1:VLEN(VCN,DSN)),
     1                  UAPT_NCID(FNUM,CD),UAPT_RECDIM(FNUM,CD),1,
     2                  UAPT_NRECS(FNUM,CD),MISS_P,OBTMP,STATUS)
            IF(STATUS.NE.SUCCESS_P)GO TO 900

C     ------------------------------------------------------------------
C     NOW FOR ONE OF THE SIMPLER "SPECIAL-CASES" IN THIS SPECIAL-CASE
C     FIESTA:  CONVERT FSL DATABASE ACARS ALTITUDE TO PRESSURE USING 
C     U.S. STD ATMOS., AND CONVERT FROM MB TO PASCALS.  (AWIPS DATABASE
C     HAS THIS IN THE FILES.)  NOTE THAT THE AWIPS ACARSP FILES DON'T
C     HAVE PRESSURE IN THE FILES, SO WE'LL CONVERT THOSE HERE AS WELL.
C     ------------------------------------------------------------------
            IF((CD.EQ.ACARS_DS_P.AND.VCN.EQ.ACARSP_VN_P.AND.
     1          CDBTYPE.EQ.FSL_DB_P).OR.(CD.EQ.ACARSP_DS_P.AND.
     2                                   VCN.EQ.ACARSPP_VN_P))THEN

               DO 101 J = 1, UAPT_NRECS(FNUM,CD) * NV
                  IF(OBTMP(J).NE.MISS_P)OBTMP(J) = 
     1                 M_ZTOPSA(OBTMP(J),MISS_P) * 100.0
 101           CONTINUE

C     ------------------------------------------------------------------
C     SEVERAL MAP WIND-RELATED VARIABLES HAVE TO BE CONVERTED FROM KTS 
C     TO M/S.
C     ------------------------------------------------------------------
            ELSE IF(CD.EQ.MAP_DS_P.AND.(VCN.EQ.MAPUGUST_VN_P.OR.
     1              VCN.EQ.MAPVGUST_VN_P.OR.VCN.EQ.MAPUSDEV_VN_P.OR.
     2              VCN.EQ.MAPVSDEV_VN_P.OR.VCN.EQ.MAPWSDEV_VN_P.OR.
     3              VCN.EQ.MAPW_VN_P.OR.VCN.EQ.MAPRW_VN_P))THEN

               DO J = 1, UAPT_NRECS(FNUM,CD) * NV
                  IF(OBTMP(J).NE.MISS_P)OBTMP(J) = OBTMP(J)/1.943861286
               ENDDO

C     ------------------------------------------------------------------
C     CONVERT AWIPS DATABASE MIXING RATIO FROM KG/KG TO G/KG.
C     ------------------------------------------------------------------
            ELSE IF((CD.EQ.ACARS_DS_P.OR.CD.EQ.ACARSP_DS_P).AND.
     1              CDBTYPE.EQ.AWIPS_DB_P.AND.VCN.EQ.UAPTMR_VN_P)THEN

               DO J = 1, UAPT_NRECS(FNUM,CD) * NV
                  IF(OBTMP(J).NE.MISS_P)OBTMP(J) = OBTMP(J) * 1000
               ENDDO

            ENDIF
                  
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                     UAPT_NCID(FNUM,CD),UAPT_RECDIM(FNUM,CD),1,
     2                     UAPT_NRECS(FNUM,CD),MISS_P,QCATMP,STATUS)
               IF(STATUS.EQ.VAR_NOTINDB_P)THEN
                  QCSTATUS = EQCFAILED_P
                  STATUS = SUCCESS_P
                  DO J = 1, UAPT_NRECS(FNUM,CD) * NV
                     
                     QCDTMP(J) = 'Z'
                     QCATMP(J) = 0
                     QCRTMP(J) = 0
                  ENDDO
               ELSE IF(STATUS.NE.SUCCESS_P)THEN
                  GO TO 900
               ELSE
                  CALL MGTNUM(VNAME(VCN,DSN)(1:VLEN(VCN,DSN))//'QCR',
     1                     UAPT_NCID(FNUM,CD),UAPT_RECDIM(FNUM,CD),1,
     2                     UAPT_NRECS(FNUM,CD),MISS_P,QCRTMP,STATUS)
                  IF(STATUS.NE.SUCCESS_P)GO TO 900

                  CALL MGTCHR(VNAME(VCN,DSN)(1:VLEN(VCN,DSN))//'DD',
     1                     UAPT_NCID(FNUM,CD),UAPT_RECDIM(FNUM,CD),1,
     2                     UAPT_NRECS(FNUM,CD),QCDTMP,LEN1REC,STATUS)
                  IF(STATUS.NE.SUCCESS_P)GO TO 900
               ENDIF
            ELSE
               QCSTATUS = EQCFAILED_P

               DO 10 J = 1, UAPT_NRECS(FNUM,CD) * NV

                  QCDTMP(J) = 'Z'
                  QCATMP(J) = 0
                  QCRTMP(J) = 0

 10            CONTINUE

            ENDIF

         ENDIF

C     ------------------------------------------------------------------
C     DEAL WITH THIS SPECIAL CASE:  FOR THE AWIPS DATABASE WE DON'T HAVE
C     QC, SO IT WON'T BE READ IN BY MGTNUM.  HOWEVER, THE PRESSURE AND
C     HEIGHT VARIABLES MAY BE INTERPOLATED, AND THAT'S INDICATED TO THE
C     USER VIA THE QC DESCRIPTORS, WHICH FOR THE INTERPOLATION QUESTION,
C     ARE FILLED IN BY MRAOBINT.  THEREFORE, PUT THAT INFO INTO
C     QCDTMP SO IT WILL WIND UP GETTING TO THE END USER.
C     ------------------------------------------------------------------
         IF(CD.EQ.RAOB_DS_P.AND.CDBTYPE.EQ.AWIPS_DB_P.AND.
     1      (VCN.EQ.RAOBHT_VN_P.OR.VCN.EQ.RAOBP_VN_P))THEN

            IF(VCN.EQ.RAOBP_VN_P)THEN
               L = P_RAOB_P
            ELSE
               L = HT_RAOB_P
            ENDIF

            DO 11 J = 1, UAPT_NRECS(FNUM,CD)

               DO 12 K = 1, NV

                  QCDTMP((J-1)*NV+K) = RAOB_QCDD(K,J,L,FNUM)

 12            CONTINUE

 11         CONTINUE

         ENDIF

C     ------------------------------------------------------------------
C     DO ANY REQUESTED QC FILTERING.  INDICATE IF RAOB HT'S ARE BEING
C     FILTERED.  IF SO, THEY GET SPECIAL PROCESSING IN THE FILTER
C     ROUTINE.
C     ------------------------------------------------------------------
         IF(CD.EQ.RAOB_DS_P.AND.VCN.EQ.RAOBHT_VN_P)RAOB_HT_QC = .TRUE.

         IF(BEAMDIM.NE.0)THEN
            J = NC
         ELSE
            J = NV
         ENDIF
         CALL MQCFLTR(VCN,DSN,J,UAPT_NRECS(FNUM,CD),QCDTMP,
     1                RAOB_NLEVELS(1,FNUM),RAOB_LT(1,1,FNUM),OBTMP)

C     ------------------------------------------------------------------
C     EXTRACT DESIRED RECORDS INTO CALLER'S ARRAY.  POSSIBILITIES:
C
C     - RAOB SOUNDING NEEDS TO BE EXTRACTED (MRAOBEXT)
C     - NPN/MAP PROFILE NEEDS TO BE EXTRACTED (MNPNEXT/MMAPEXT) -- NOTE 
C       THAT THIS ALSO REQUIRES US TO MAKE SURE THE NPN/MAP LEVEL TYPES 
C       ARE IN COMMON
C
C     IF WE DON'T CALL ONE OF THE EXTRACT ROUTINES, WE HAVE TO FILL
C     IN THE NUMBER OF LEVELS FOR EACH STATION.
C
C     THEN ONCE THAT'S DEALT WITH:
C
C     - PUT DATA ON CALLER-SPECIFIED LEVELS (MUAPTITP)
C     - NO SPECIAL LOGIC NEEDED -- DO IT HERE
C     ------------------------------------------------------------------
         IF(SPT.GT.0)THEN

            CALL MRAOBEXT(SPT,UAPT_NRECS(FNUM,CD),FNUM,NC,OBTMP,QCDTMP,
     1                    QCATMP,QCRTMP,NLREC)
            NLT = 0

         ELSE IF(SPT.LT.0.AND.SPT.GT.-10)THEN

            CALL MNPNLT(VCN,DSN,FNUM,NV,OBTMP,QCDTMP,QCATMP,QCRTMP,
     1                  STATUS)
            IF(STATUS.NE.SUCCESS_P)GO TO 900

            CALL MNPNEXT(VCN,SPT,UAPT_NRECS(FNUM,CD),NC,OBTMP,QCDTMP,
     1                   QCATMP,QCRTMP,NLREC)
            NLT = 0

         ELSE IF(SPT.LE.-11.AND.SPT.GE.-11-MXWMODE)THEN

            CALL MMAPLT(VCN,DSN,FNUM,NV,OBTMP,QCDTMP,QCATMP,QCRTMP,
     1                  STATUS)
            IF(STATUS.NE.SUCCESS_P)GO TO 900

            CALL MMAPEXT(VCN,SPT,UAPT_NRECS(FNUM,CD),NC,OBTMP,QCDTMP,
     1                   QCATMP,QCRTMP,NLREC)
            NLT = 0

         ELSE IF(.NOT.(CD.EQ.RAOB_DS_P.AND.NC.NE.1))THEN

            NLT = 1

         ELSE

            NLT = 2

         ENDIF

         IF(NC.EQ.NV.OR.BEAMDIM.NE.0.OR.VCTYPE.EQ.0)THEN

            DO 120 J = I, NSTA

               IF(UAPT_FNUM(J,CD).NE.FNUM)GO TO 120

               IF(NLT.EQ.0)THEN

                  NLEVELS(J) = NLREC(UAPT_RNUM(J,CD))

               ELSE IF(NLT.EQ.1)THEN

                  NLEVELS(J) = NC

               ELSE

                  NLEVELS(J) = RAOB_NLEVELS(UAPT_RNUM(J,CD),FNUM)

               ENDIF

               DO 130 K = 1, NC

                  OB((J-1)*NC+K) = OBTMP((UAPT_RNUM(J,CD)-1)*NC+K)
                  QCDESC((J-1)*NC+K) = QCDTMP((UAPT_RNUM(J,CD)-1)*NC+K)
                  QCAPP((J-1)*NC+K) = QCATMP((UAPT_RNUM(J,CD)-1)*NC+K)
                  QCRES((J-1)*NC+K) = QCRTMP((UAPT_RNUM(J,CD)-1)*NC+K)

 130           CONTINUE

 120        CONTINUE

C         ELSE
C
C     IF THIS CODE IS ACTIVATED, NOTES TO REMEMBER:
C     - FILL IN NLEVELS.
C     - MUAPTITP NEEDS TO HANDLE FNUM STUFF AS DONE IN DO 120 LOOP
C
C            CALL MUAPTITP(VCN,I,NSTA,FNUM,OBTMP,QCDTMP,QCATMP,QCRTMP,
C     1                    OB,QCDESC,QCAPP,QCRES)

         ENDIF

 100  CONTINUE

 900  IF(STATUS.NE.SUCCESS_P)THEN

         NSTA = 0
         NOBS = 0

      ELSE

C     ------------------------------------------------------------------
C     COUNT UP THE NUMBER OF NON-MISSING OBS ACTUALLY RETURNED.
C     ------------------------------------------------------------------
         NOBS = 0

         DO 121 J = 1, NSTA * NC
            IF(OB(J).NE.MISS_P)NOBS = NOBS + 1
 121     CONTINUE

         IF(NOBS.EQ.0)THEN
            NSTA = 0
            STATUS = NO_DATA_P
         ENDIF

      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**---------------------------------------------------------------------
