C$$$  SUBPROGRAM DOCUMENTATION BLOCK
C                .      .    .                                       .
C SUBPROGRAM:    MSATSNDMOI    GET POES-SOUNDINGS MOISTURE VARIABLE
C   PRGMMR: L. BENJAMIN      ORG: FSL        DATE: 04-09-28
C
C ABSTRACT: GET POES-SOUNDINGS MIXING RATIO OBS FOR ALL STATIONS IN
C   ONE NETCDF FILE FOR ONE TIME AND RETURN AS DPD, TD, RH, Q, OR AH.
C
C PROGRAM HISTORY LOG:
C   04-09-28  L. BENJAMIN ORIGINAL VERSION
C   04-10-16  L. BENJAMIN ADDED NO SUCH VARIABLE CHECK FOR QCA CHECKS
C   06-07-20  L. BENJAMIN ADDED NO SUCH VARIABLE CHECK FOR SOLE DD 
C                         CHECKS
C   07-11-21  L. BENJAMIN REMOVED COMMENTED OUT CODE
C
C USAGE:    CALL MSATSNDMOI (VCN,DSN,FNUM,NV,OB,QCDESC,QCAPP,QCRES,
C                            STATUS)
C
C   INPUT ARGUMENT LIST:
C     VCN      - I       VARIABLE CODE NUMBER FOR DPD, TD, RH, Q, OR AH
C     DSN      - I       DATASET CODE NUMBER
C     FNUM     - I       FILE NUMBER (INDEX IN COMMON) OF NETCDF FILE
C     NV       - I       NUMBER OF ELEMENTS DIMENSIONED FOR THE 
C                        VARIABLE
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_RH, M_SSH, M_TD2AH, M_TMR2
C
C REMARKS:
C   - THE MOISTURE VARIABLE IS MIXING RATIO.  THE CALLER CAN 
C     REQUEST THAT DPD, TD, RH, Q, OR AH BE RETURNED.
C   - THE QC INFO THAT'S USED IS FROM THE STORED VARIABLE, EVEN IF
C     WE CONVERT.
C   - IF CONVERSIONS ARE REQUIRED, AND ANY OF THE VARIABLES
C     NEEDED IN THE CONVERSIONS FAILED QC, A MISSING VALUE WILL BE
C     RETURNED.
C   - A VALIDITY CHECK IS PERFORMED BEFORE DOING CERTAIN CONVERSIONS.
C     THIS IS NEEDED TO COVER THE CASE OF *REALLY* BAD DATA FROM THE
C     AWIPS DATABASE, WHICH DOESN'T HAVE ANY QC DONE ON IT, FROM 
C     BLOWING UP A CALCULATION.  THE VALIDITY CHECK LIMITS ARE VERY
C     GROSS, AND ARE DESIGNED SIMPLY TO KEEP CALCULATIONS FROM 
C     BLOWING UP.
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   - 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 MSATSNDMOI (VCN,DSN,FNUM,NV,OB,QCDESC,QCAPP,QCRES,
     1     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,NV,STATUS
      REAL OB(*),QCAPP(*),QCRES(*)
      CHARACTER*1 QCDESC(*)

C     -----------------------------------------------------------------
C     LOCAL
C     -----------------------------------------------------------------
      INTEGER MXTMP
      PARAMETER (MXTMP = MXSATS_P * MXSATSLEV_P)
      REAL OBTMP(MXTMP),TTMP(MXTMP),PTMP(MXTMP),M_TMR2
      REAL M_RH,M_SSH,M_TD2AH,TD
      INTEGER I,LVCN,LEN1REC,CD,DUMMY
      CHARACTER*1 TTMP_QCD(MXTMP),PTMP_QCD(MXTMP)

C     -----------------------------------------------------------------
C     TEMPORARY STORAGE DEFINITIONS
C     -----------------------------------------------------------------
      EQUIVALENCE(OBTMP,TMP_L3_N1)
      EQUIVALENCE(TTMP,TMP_L3_N2)
      EQUIVALENCE(PTMP,TMP_L3_N3)
      EQUIVALENCE(TTMP_QCD,TMP_L3_C1)
      EQUIVALENCE(PTMP_QCD,TMP_L3_C2)

C     -----------------------------------------------------------------
C     IF THE REQUESTED VARIABLE IS THE ONE STORED IN THE DATASET, READ
C     IT AND WE'RE DONE.
C     -----------------------------------------------------------------
      CD = DSN - MAX_SFCDSET_P - MAX_UAPTDSET_P - MAX_HYDRODSET_P
     1     - MAX_SATWDSET_P

      IF(VCN.EQ.SATSMR_VN_P.AND.CD.EQ.POES_DS_P)THEN

         CALL MGTNUM(VNAME(VCN,DSN)(1:VLEN(VCN,DSN)),SATS_NCID(FNUM),
     1        SATS_RECDIM(FNUM),1,SATS_NRECS(FNUM),MISS_P,
     2        OB,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           SATS_NCID(FNUM),SATS_RECDIM(FNUM),1,
     2           SATS_NRECS(FNUM),MISS_P,QCAPP,STATUS)
            IF(STATUS.EQ.VAR_NOTINDB_P)THEN
               QCSTATUS = EQCFAILED_P
               STATUS = SUCCESS_P
               DO 11 I = 1, SATS_NRECS(FNUM) * NV
                  QCAPP(I) = 0
                  QCRES(I) = 0
                  QCDESC(I) = 'Z'
 11             CONTINUE
            ELSE IF(STATUS.NE.SUCCESS_P)THEN
               RETURN
            ELSE
               CALL MGTNUM(VNAME(VCN,DSN)(1:VLEN(VCN,DSN))//'QCR',
     1           SATS_NCID(FNUM),SATS_RECDIM(FNUM),1,
     2           SATS_NRECS(FNUM),MISS_P,QCRES,STATUS)
               IF(STATUS.NE.SUCCESS_P)RETURN

               CALL MGTCHR(VNAME(VCN,DSN)(1:VLEN(VCN,DSN))//'DD',
     1           SATS_NCID(FNUM),SATS_RECDIM(FNUM),1,
     2           SATS_NRECS(FNUM),QCDESC,LEN1REC,STATUS)
               IF(STATUS.NE.SUCCESS_P)RETURN
            ENDIF
         ELSE
            QCSTATUS = EQCFAILED_P
            DO 1 I = 1, SATS_NRECS(FNUM) * NV
               QCAPP(I) = 0
               QCRES(I) = 0
               QCDESC(I) = 'Z'
 1          CONTINUE

         ENDIF

      ELSE

C     -----------------------------------------------------------------
C     THE REQUESTED VARIABLE IS NOT WHAT'S STORED.  READ IN THE ONE
C     THAT'S STORED, ALSO GET THE TEMPERATURE AND/OR PRESSURE, MAKE
C     THEN CONVERT.  NOTE THAT IF ANY OF THE VARIABLES ARE BAD,
C     WE'LL RETURN MISSING VALUES.
C     -----------------------------------------------------------------

C     -----------------------------------------------------------------
C     GET THE STORED VARIABLE AND ITS QC. (MR (OBTMP)) kg/kg
C     -----------------------------------------------------------------
         LVCN = SATSMR_VN_P
         CALL MGTNUM(VNAME(LVCN,DSN)(1:VLEN(LVCN,DSN)),
     1               SATS_NCID(FNUM),SATS_RECDIM(FNUM),1,
     2               SATS_NRECS(FNUM),MISS_P,OBTMP,STATUS)
         IF(STATUS.NE.SUCCESS_P)RETURN

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

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

            CALL MGTNUM(VNAME(LVCN,DSN)(1:VLEN(LVCN,DSN))//'QCA',
     1                  SATS_NCID(FNUM),SATS_RECDIM(FNUM),1,
     2                  SATS_NRECS(FNUM),MISS_P,QCAPP,STATUS)
            IF(STATUS.EQ.VAR_NOTINDB_P)THEN
               QCSTATUS = EQCFAILED_P
               STATUS = SUCCESS_P
               DO I = 1, SATS_NRECS(FNUM) * NV
                  QCAPP(I) = 0
                  QCRES(I) = 0
                  QCDESC(I) = 'Z'
               ENDDO
            ELSE IF(STATUS.NE.SUCCESS_P)THEN
               RETURN
            ELSE
               CALL MGTNUM(VNAME(LVCN,DSN)(1:VLEN(LVCN,DSN))//'QCR',
     1                  SATS_NCID(FNUM),SATS_RECDIM(FNUM),1,
     2                  SATS_NRECS(FNUM),MISS_P,QCRES,STATUS)
               IF(STATUS.NE.SUCCESS_P)RETURN

               CALL MGTCHR(VNAME(LVCN,DSN)(1:VLEN(LVCN,DSN))//'DD',
     1                  SATS_NCID(FNUM),SATS_RECDIM(FNUM),1,
     2                  SATS_NRECS(FNUM),QCDESC,LEN1REC,STATUS)
               IF(STATUS.NE.SUCCESS_P)RETURN
            ENDIF
         ELSE
            QCSTATUS = EQCFAILED_P
            DO 6 I = 1, SATS_NRECS(FNUM) * NV
               QCAPP(I) = 0
               QCRES(I) = 0
               QCDESC(I) = 'Z'
 6          CONTINUE

         ENDIF

C     -----------------------------------------------------------------
C     GET THE TEMPERATURE AND ITS QC. (T (TTMP)) kelvin
C     -----------------------------------------------------------------
         CALL MGTNUM(VNAME(SATST_VN_P,DSN)(1:VLEN(SATST_VN_P,DSN)),
     1               SATS_NCID(FNUM),SATS_RECDIM(FNUM),1,
     2               SATS_NRECS(FNUM),MISS_P,TTMP,STATUS)
         IF(STATUS.NE.SUCCESS_P)RETURN

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

            CALL MGTCHR(VNAME(SATST_VN_P,DSN)(1:VLEN(SATST_VN_P,DSN))//
     1                  'DD',SATS_NCID(FNUM),SATS_RECDIM(FNUM),1,
     2                  SATS_NRECS(FNUM),TTMP_QCD,LEN1REC,STATUS)

            IF(STATUS.EQ.VAR_NOTINDB_P)THEN
               QCSTATUS = EQCFAILED_P
               STATUS = SUCCESS_P
               DO 21 I = 1, SATS_NRECS(FNUM) * NV
                  TTMP_QCD(I) = 'Z'
 21            CONTINUE
            ELSE IF(STATUS.NE.SUCCESS_P)THEN
               RETURN
            ENDIF
         ELSE

            DO 125 I = 1, SATS_NRECS(FNUM) * NV
               TTMP_QCD(I) = 'Z'
 125        CONTINUE

         ENDIF

C     -----------------------------------------------------------------
C     GET THE PRESSURE AND ITS QC. (P (PTMP)) pascals
C     -----------------------------------------------------------------
         CALL MGTNUM(VNAME(SATSP_VN_P,DSN)(1:VLEN(SATSP_VN_P,DSN)),
     1        SATS_NCID(FNUM),SATS_RECDIM(FNUM),1,
     2        SATS_NRECS(FNUM),MISS_P,PTMP,STATUS)
         IF(STATUS.NE.SUCCESS_P)RETURN
         
         IF(VQC(SATSP_VN_P,DSN).EQ.'Q')THEN

            CALL MGTCHR(VNAME(SATSP_VN_P,DSN)
     1           (1:VLEN(SATSP_VN_P,DSN))//'DD',
     2           SATS_NCID(FNUM),SATS_RECDIM(FNUM),1,
     2           SATS_NRECS(FNUM),PTMP_QCD,LEN1REC,STATUS)

            IF(STATUS.EQ.VAR_NOTINDB_P)THEN
               QCSTATUS = EQCFAILED_P
               STATUS = SUCCESS_P
               DO 22 I = 1, SATS_NRECS(FNUM) * NV
                  TTMP_QCD(I) = 'Z'
 22            CONTINUE
            ELSE IF(STATUS.NE.SUCCESS_P)THEN
               RETURN
            ENDIF

         ELSE

            DO 1125 I = 1, SATS_NRECS(FNUM) * NV
               PTMP_QCD(I) = 'Z'
 1125       CONTINUE

         ENDIF


C     -----------------------------------------------------------------
C     CREATE DEW POINT  MR, P --> TD (OBTMP)
C     FOR THE CONVERSION, CONVERT INPUT MR FROM KG/KG TO GRAMS/KG AND 
C     CONVERT P FROM PASCALS TO MB.  CONVERT OUTPUT T FROM CELSIUS TO
C     KELVIN.
C     -----------------------------------------------------------------

         DO I = 1, SATS_NRECS(FNUM) * NV

            IF(PTMP(I).EQ.MISS_P.OR.OBTMP(I).EQ.MISS_P.OR.
     1           OBTMP(I).LE.0.OR.QCDESC(I).EQ.'B'.OR.
     2           QCDESC(I).EQ.'X'.OR.QCDESC(I).EQ.'Q')THEN
               OBTMP(I) = MISS_P
               QCAPP(I) = 0
               QCRES(I) = 0
               QCDESC(I) = 'Z'
            ELSE
               OBTMP(I) = M_TMR2(OBTMP(I)*1000,PTMP(I)/100)
               IF(OBTMP(I).NE.MISS_P)OBTMP(I) = OBTMP(I) + 273.15
            ENDIF
         ENDDO



         IF(VCN.EQ.SATSTD_VN_P)THEN
C     -----------------------------------------------------------------
C     HANDLE TD.
C     WE ALREADY CONVERTED RH->TD ABOVE, JUST MOVE OBTMP TO OB.
C     -----------------------------------------------------------------
            DO I = 1, SATS_NRECS(FNUM) * NV
               OB(I) = OBTMP(I)
            ENDDO

         ELSE IF(VCN.EQ.SATSRH_VN_P)THEN
C     -----------------------------------------------------------------
C     HANDLE CONVERSIONS TO RH. T, TD --> RH
C     -----------------------------------------------------------------

            DO 2 I = 1, SATS_NRECS(FNUM) * NV

               IF(TTMP_QCD(I).EQ.'B'.OR.TTMP_QCD(I).EQ.'X'.OR.
     1            TTMP_QCD(I).EQ.'Q'.OR.TTMP(I).EQ.MISS_P.OR.
     2            QCDESC(I).EQ.'B'.OR.QCDESC(I).EQ.'X'.OR.
     3            QCDESC(I).EQ.'Q'.OR.OBTMP(I).EQ.MISS_P.OR.
     4            TTMP(I).LT.89.0.OR.TTMP(I).GT.422.0.OR.
     5            OBTMP(I).LT.89.0.OR.OBTMP(I).GT.422.0)THEN
                  OB(I) = MISS_P
                  QCAPP(I) = 0
                  QCRES(I) = 0
                  QCDESC(I) = 'Z'
               ELSE
                  OB(I) = M_RH(TTMP(I),OBTMP(I),MISS_P) * 100.0
               ENDIF

 2          CONTINUE

         ELSE IF(VCN.EQ.SATSDPD_VN_P)THEN

C     -----------------------------------------------------------------
C     HANDLE CONVERSIONS TO DPD.  T, TD --> DPD
C     -----------------------------------------------------------------
            DO 5 I = 1, SATS_NRECS(FNUM) * NV

               IF(TTMP(I).NE.MISS_P.AND.OBTMP(I).NE.MISS_P.AND.
     1            TTMP_QCD(I).NE.'B'.AND.TTMP_QCD(I).NE.'X'.AND.
     2            TTMP_QCD(I).NE.'Q'.AND.QCDESC(I).NE.'B'.AND.
     3            QCDESC(I).NE.'X'.AND.QCDESC(I).NE.'Q'.AND.
     4            TTMP(I).GE.89.0.AND.TTMP(I).LE.422.0.AND.
     5            OBTMP(I).GE.89.0.AND.OBTMP(I).LE.422.0)THEN
                  OB(I) = TTMP(I) - OBTMP(I)
               ELSE
                  OB(I) = MISS_P
                  QCAPP(I) = 0
                  QCRES(I) = 0
                  QCDESC(I) = 'Z'
               ENDIF

 5          CONTINUE

C     -----------------------------------------------------------------
C     HANDLE CONVERSIONS TO Q.
C     -----------------------------------------------------------------

         ELSE IF(VCN.EQ.SATSQ_VN_P)THEN

            DO 61 I = 1, SATS_NRECS(FNUM) * NV

C     -----------------------------------------------------------------
C     TRY TO CONVERT.  MAKE SURE WE HAVE TD.
C       1) P, TD --> Q
C     -----------------------------------------------------------------
               IF(TTMP(I).EQ.MISS_P.OR.OBTMP(I).EQ.MISS_P.OR.
     1              PTMP(I).EQ.MISS_P.OR.
     1              QCDESC(I).EQ.'B'.OR.QCDESC(I).EQ.'X'.OR.
     1              QCDESC(I).EQ.'Q'.OR.OBTMP(I).EQ.MISS_P.OR.
     2              TTMP_QCD(I).EQ.'B'.OR.TTMP_QCD(I).EQ.'X'.OR.
     3              TTMP_QCD(I).EQ.'Q'.OR.
     4              PTMP(I).LE.0.0.OR.PTMP(I).GT.110000.0.OR.
     5              OBTMP(I).LT.89.0.OR.OBTMP(I).GT.422.0)THEN
                  OB(I) = MISS_P
                  QCAPP(I) = 0
                  QCRES(I) = 0
                  QCDESC(I) = 'Z'
               ELSE

C     -----------------------------------------------------------------
C     THE M_SSH FUNCTION EXPECTS P IN MB, TD IN C, AND RETURNS Q IN 
C     G/KG.  WE, ON THE OTHER HAND, ARE "SI-CORRECT", SO WE USE 
C     PASCALS, K, AND KG/KG RESPECTIVELY.  (THIS EXPLAINS THE 
C     RIGARAMOLE BELOW.)
C     -----------------------------------------------------------------
                  OB(I) = M_SSH(PTMP(I)/100.,OBTMP(I)-273.15)/1000.
               ENDIF

 61         CONTINUE

         ELSE IF(VCN.EQ.SATSAH_VN_P)THEN

C     -----------------------------------------------------------------
C     HANDLE CONVERSIONS TO AH.  T, TD --> AH
C     -----------------------------------------------------------------
            DO I = 1, SATS_NRECS(FNUM) * NV

               IF(TTMP_QCD(I).EQ.'B'.OR.TTMP_QCD(I).EQ.'X'.OR.
     1            TTMP_QCD(I).EQ.'Q'.OR.TTMP(I).EQ.MISS_P.OR.
     2            QCDESC(I).EQ.'B'.OR.QCDESC(I).EQ.'X'.OR.
     3            QCDESC(I).EQ.'Q'.OR.OBTMP(I).EQ.MISS_P.OR.
     4            TTMP(I).LT.89.0.OR.TTMP(I).GT.422.0.OR.
     5            OBTMP(I).LT.89.0.OR.OBTMP(I).GT.422.0)THEN
                  OB(I) = MISS_P
                  QCAPP(I) = 0
                  QCRES(I) = 0
                  QCDESC(I) = 'Z'
               ELSE
                  OB(I) = M_TD2AH(OBTMP(I),TTMP(I),MISS_P)
               ENDIF

            ENDDO

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