C$$$  SUBPROGRAM DOCUMENTATION BLOCK
C                .      .    .                                       .
C SUBPROGRAM:    MSFCSTA     GET SFC STATIONS FOR ONE TIME
C   PRGMMR: M. BARTH         ORG: FSL        DATE: 99-09-14
C
C ABSTRACT: READ STATION INFO FOR SFC DATASETS FOR ONE TIME.
C
C PROGRAM HISTORY LOG:
C   99-09-14  M. BARTH    ORIGINAL VERSION
C   00-03-22  M. BARTH    CHANGES TO ALLOW FOR UPPER-AIR-POINT DATA
C   01-04-27  M. BARTH    CHANGED TO AWIPS-STYLE FILENAMES
C   01-07-02  M. BARTH    - ADDED CDBTYPE
C                         - CHANGED MSFILES CALL & INCR USAGE
C                         - CHANGED ACTION WHEN, AFTER FILTERING,
C                           THERE WOULD BE TOO MANY RECORDS TO RETURN
C                           TO THE USER.  BEFORE:  SUBTRACTED THE
C                           DATASET THAT PUT HIM OVER THE TOP; NOW:
C                           RETURN WITH "TOO MANY RECORDS" ERROR.
C   01-07-24  M. BARTH    - SPLIT PROVIDER INFO INTO SFC & HYDRO
C                         - STANAM CHANGED FROM 8 TO 10 CHARACTERS
C   02-06-01  M. BARTH    RETURN "TOO MANY RECORDS" ERROR IF NUMBER
C                         OF FILES NEEDED FOR THE TIME WINDOW IS MORE
C                         THAN THE NUMBER THAT CAN BE USED -- THIS
C                         CHANGE ALLOWS US TO CHANGE THE AMOUNT OF
C                         TIME (AND THEREFORE VOLUME OF RECORDS)
C                         KEPT IN A SINGLE FILE BY ONLY CHANGING
C                         THE TEMPLATE -- ALLOWS ROOM FOR GROWTH.
C   03-10-03  M. BARTH    REPLACED NCOPN CALL WITH MMADISOPEN ROUTINE
C   04-08-19  M. BARTH    REPLACED NCCLOS CALL WITH MMADISCLS1 ROUTINE
C                         AND PUT THE YYYYMMDD_HHMM PART OF THE 
C                         FILENAMES INTO STRCCOM (WAS LOCAL)
C   06-02-13  L. BENJAMIN CHANGED MEMORY LOCATION FOR LOCAL VARIABLES
C   07-13-11  L. BENJAMIN ADDED RSAS DOMAIN INDENTITY FOR DETERMININT 
C                         MAX QC FOR SFC DATA
C   08-07-25  L. BENJAMIN REMOVED COMMENT
C   13-04-21  L. BENJAMIN RETURN MADIS SOURCE CODE (SOURCE_N)
C
C USAGE:    CALL MSFCSTA (ATIME,NSTA,STANAM,WMOID,LAT,LON,ELEV,TIMEOB,
C                         PROVDR,STATUS)
C
C   INPUT ARGUMENT LIST:
C     ATIME    - C       YYJJJHHMM OF THE DATA TO BE READ
C
C   OUTPUT ARGUMENT LIST:
C     NSTA     - I       NUMBER OF STATIONS RETURNED
C     STANAM   - CA      STATION NAMES
C     WMOID    - IA      WMO ID NUMBERS
C     LAT      - RA      LATITUDES (N)
C     LON      - RA      LONGITUDES (E)
C     ELEV     - RA      STATION ELEVATIONS (M)
C     TIMEOB   - CA      YYJJJHHMM OBSERVATION TIMES
C     PROVDR   - CA      DATA PROVIDER NAMES
C     STATUS   - I       0 - SUCCESS, OR ERROR CODE
C     SOURCE_N - I       DATASET INDEX NUMBER
C
C   INPUT FILES:
C     MADIS SFC NETCDF FILES FOR ATIME
C
C SUBPROGRAMS CALLED:
C     UNIQUE:    MERROR, M_MKI4TM, MSFCCLS, MSFILES, M_MKFNAM, M_MKWFNM,
C                MSFCRDSTA, MSFCFLTR, MMADISOPEN, MMADISCLS1
C     NETCDF:    NCINQ, NCDINQ
C
C REMARKS:
C   - THE CALLER MUST CALL MINIT BEFORE CALLING THIS ROUTINE.
C   - THE CALLER SHOULD DIMENSION ARRAYS TO MATCH MXSFC_P IN
C     madiscon.f.  IF AFTER TIME & DOMAIN FILTERING THERE ARE MORE
C     THAN MXSFC_P RECORDS THIS ROUTINE WILL RETURN WITH THE
C     "TOO MANY RECORDS" ERROR (TOO_MANY_REC_P).  THIS SHOULD ALERT
C     THE USER TO RESTRUCTURE HIS/HER CODE TO CHANGE HOW DATA
C     ARE BEING RETRIEVED:  E.G., USE A SMALLER TIME WINDOW AND
C     CALL THIS ROUTINE TWICE -- GET THE DESIRED RESULT BUT WITHOUT
C     EXCEEDING THE MAXIMUM NUMBER OF RECORDS LEGALLY HANDLED BY
C     THE MADIS CODE.
C   - THIS ROUTINE SHOULD BE CALLED WHENEVER ACCESS TO A NEW TIME
C     IS DESIRED.
C   - FOLLOWING THIS CALL, MGETSFC OR MGETSFCC SHOULD BE CALLED TO READ
C     IN WHATEVER OBSERVATIONS ARE DESIRED FOR THIS TIME.  THE INFO
C     STORED IN THE STRCCOM COMMON BY THIS ROUTINE IS USED BY THE OTHER
C     ROUTINES TO FIGURE OUT WHICH RECORDS IT NEEDS ON NETCDF FILES
C     OPENED IN THIS ROUTINE.
C   - THE MADISCOM PROVIDER ARRAYS (NPVD, PVDNAME, ETC.) HAVE SFC
C     PROVIDERS IN ROW 1, HYDRO PROVIDERS IN ROW 2.
C
C ATTRIBUTES:
C   LANGUAGE: FORTRAN-77 + EXTENSIONS
C   MACHINE:  UNIX
C$$$

      SUBROUTINE MSFCSTA (ATIME,NSTA,STANAM,WMOID,LAT,LON,ELEV,TIMEOB,
     1                    PROVDR,STATUS,SOURCE_N)


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

C     ------------------------------------------------------------------
C     ARGUMENTS
C     ------------------------------------------------------------------
      CHARACTER*9 ATIME,TIMEOB(*)
      CHARACTER*(*) STANAM(*),PROVDR(*)
      INTEGER NSTA,WMOID(*),STATUS
      REAL LAT(*),LON(*),ELEV(*)
      INTEGER SOURCE_N(*)

C     ------------------------------------------------------------------
C     LOCAL
C     ------------------------------------------------------------------
      INTEGER I,J,K,L,I4TIME,NFILES,START_TIME,RCODE
      INTEGER NDIMS,NVARS,NGATTS
      LOGICAL KEEP_GOING
      CHARACTER*9 FTIME
      CHARACTER*31 DUMMY

      INTEGER OBTIME(MXSFC_P*4),FNUML(MXSFC_P*4),RNUML(MXSFC_P*4)

      CHARACTER*10 STANAML(MXSFC_P*4)
      CHARACTER*(LDPNAM_P) PROVDRL(MXSFC_P*4)
      INTEGER NSTANEW,WMOIDL(MXSFC_P*4),SUBSRC(MXSFC_P*4)
      REAL LATL(MXSFC_P*4),LONL(MXSFC_P*4),ELEVL(MXSFC_P*4)
      CHARACTER*5 ATYPE(MXSFC_P*4),RTYPE(MXSFC_P*4)

      EQUIVALENCE(STANAML,TMP_L1_C1)
      EQUIVALENCE(PROVDRL,TMP_L1_C1(MXSFC_P*40+1))

      EQUIVALENCE(LATL,TMP_L1_N1)
      EQUIVALENCE(LONL,TMP_L1_N2)
      EQUIVALENCE(ELEVL,TMP_L1_N3)

      REAL XCART,YCART
      REAL X_MIN_S 
      PARAMETER  (X_MIN_S = 0.0)
      REAL Y_MIN_S
      PARAMETER  (Y_MIN_S = 0.0)
      REAL X_MAX_S
      PARAMETER  (X_MAX_S = (580-1)*15000)
      REAL Y_MAX_S
      PARAMETER  (Y_MAX_S = (548-1)*15000)

      REAL        LAT_PS_S
      PARAMETER  (LAT_PS_S = 90.00000)
      REAL        LON_PS_S 
      PARAMETER  (LON_PS_S = -105.0000)
      REAL        X_POLE_S
      PARAMETER  (X_POLE_S = 3897800.)
      REAL        Y_POLE_S
      PARAMETER  (Y_POLE_S = 9182641.)
      REAL        LAT_TRUE_S 
      PARAMETER  (LAT_TRUE_S = 60.00000)

      
      REAL XLIMN,XLIMX,YLIMN,YLIMX
      PARAMETER  (XLIMN = X_MIN_S - 7500.0)
      PARAMETER  (XLIMX = X_MAX_S - 7500.0)
      PARAMETER  (YLIMN = Y_MIN_S - 7500.0)
      PARAMETER  (YLIMX = Y_MAX_S - 7500.0)

      REAL M_XGRID,M_YGRID

C     ------------------------------------------------------------------
C     IF THE SFC SUBSYSTEM HASN'T BEEN INITIALIZED, RETURN WITH ERROR.
C     OTHERWISE, CLOSE ANY OPEN NETCDF FILES AND INITIALIZE OTHER DATA
C     STRUCTURES.
C     ------------------------------------------------------------------
      IF(SFC_INIT.NE.INIT_P)THEN
         STATUS = SELSUB_NOTINIT_P
         CALL MERROR('MSFCSTA: SELECTED SUBSYSTEM NOT INITIALIZED - '//
     1               'SFC')
         RETURN
      ENDIF

      CALL M_MKI4TM(ATIME,I4TIME,STATUS)
      IF(STATUS.NE.SUCCESS_P)THEN
         CALL MERROR('MSFCSTA: INVALID TIME')
         RETURN
      ENDIF
      CALL MSFCCLS
      LAST_SFC_ATIME = '         '
      SFC_NFILES = 0
      SFC_LNUM = 0
      KEEP_GOING = .TRUE.
      CDTYPE = SFC_DS_P
      CDBTYPE = SFC_DBTYPE

C     ------------------------------------------------------------------
C     LOOP THROUGH THE DATASETS.
C     ------------------------------------------------------------------
      DO 1 I = 1, MAX_SFCDSET_P

C     ------------------------------------------------------------------
C     DETERMINE HOW MANY FILES NEED TO BE READ IN TO SATISFY THE TIME
C     WINDOW.
C     ------------------------------------------------------------------
         IF(SFCDSET_ENBL(I))THEN

            CALL MSFILES(I,I4TIME,START_TIME,NFILES)
            IF(NFILES.GT.SFC_MXSTRF/MAX_SFCDSET_P)THEN
               NSTA = 0
               LAST_SFC_ATIME = '         '
               STATUS = TOO_MANY_REC_P
               CALL MERROR('MSFCSTA: TOO MANY RECORDS REQUESTED')
               RETURN
            ENDIF

            K = 1

C     ------------------------------------------------------------------
C     LOOP FOR ALL FILES IN THE DATASET:
C     - CREATE THE FILENAME.
C     - OPEN THE FILE AND GET THE NO. OF RECORDS, STORE NCID & NREC.
C       IN COMMON FOR SUBSEQUENT READS.
C     - READ IN THE STATION INFO INTO LOCAL ARRAYS.
C     ------------------------------------------------------------------
            DO 5 J = 1, NFILES

               SFC_NFILES = SFC_NFILES + 1
               CALL M_MKFNAM(START_TIME,FTIME,STATUS)
               START_TIME = START_TIME + SFCDSET_INCR(I)

               CALL M_MKWFNM(FTIME,SFC_FNAME(SFC_NFILES),STATUS)

               CALL MMADISOPEN(SFCDIR(I),SFCDIRLEN(I),
     1                         SFC_FNAME(SFC_NFILES),
     2                         SFC_NCID(SFC_NFILES),RCODE)
               IF(RCODE.NE.0)THEN
                  SFC_NCID(SFC_NFILES) = -1
                  GO TO 10
               ENDIF

               CALL NCINQ(SFC_NCID(SFC_NFILES),NDIMS,NVARS,NGATTS,
     1                    SFC_RECDIM(SFC_NFILES),RCODE)
               IF(RCODE.NE.0)GO TO 10
               CALL NCDINQ(SFC_NCID(SFC_NFILES),SFC_RECDIM(SFC_NFILES),
     1                     DUMMY,SFC_NRECS(SFC_NFILES),RCODE)
               IF(RCODE.NE.0.OR.SFC_NRECS(SFC_NFILES).EQ.0)GO TO 10

C     ------------------------------------------------------------------
C     IF WE'VE SOMEHOW EXCEEDED THE DIMENSION OF OUR ARRAYS, DON'T
C     TRY TO READ ANYMORE, BUT DO RETURN WITH WHAT WE'VE ALREADY GOT.
C     NOTE THAT WE DON'T DECLARE A FATAL ERROR, AS WE DO WHEN THE
C     POST-FILTERED AMOUNT IS GREATHER THAN MXSFC_P.  THIS IS BECAUSE
C     THIS ERROR WOULD BE A RESULT OF INTERNAL LOGIC PROBLEMS AND
C     THE USER WHO STUMBLES ACROSS IT SHOULDN'T BE EXPECTED TO REWRITE
C     HIS CODE TO COMPENSATE...
C     ------------------------------------------------------------------
               IF(K-1+SFC_NRECS(SFC_NFILES).GT.MXSFC_P*4)THEN
                  KEEP_GOING = .FALSE.
                  CALL MMADISCLS1(SFC_NCID(SFC_NFILES),SFCDIR(I),
     1                            SFCDIRLEN(I),SFC_FNAME(SFC_NFILES))
                  SFC_NCID(SFC_NFILES) = -1
                  SFC_NFILES = SFC_NFILES - 1
                  GO TO 100
               ENDIF

               CALL MSFCRDSTA(I,SFC_NCID(SFC_NFILES),
     1                        SFC_RECDIM(SFC_NFILES),1,
     2                        SFC_NRECS(SFC_NFILES),MXSFC_P*4,OBTIME(K),
     3                        STANAML(K),WMOIDL(K),PROVDRL(K),LATL(K),
     4                        LONL(K),ELEVL(K),SUBSRC(K),ATYPE(K),
     5                        RTYPE(K),STATUS)
               IF(STATUS.EQ.SUCCESS_P)THEN

C     ------------------------------------------------------------------
C     PUT THE FILE AND RECORD NUMBERS, AND THE SOURCE, INTO COMMON AND
C     UPDATE K FOR NEXT FILE IN THIS DATASET.
C     ------------------------------------------------------------------
                  DO 4 L = K, K + SFC_NRECS(SFC_NFILES) - 1
                     FNUML(L) = SFC_NFILES
                     RNUML(L) = L - K + 1
C     ------------------------------------------------------------------
C     UPDATE RSAS DOMAIN DESINATION
C     ------------------------------------------------------------------
                     IF(LATL(L).EQ.-90.0.OR.LATL(L).EQ.90.0)THEN

C     ------------------------------------------------------------------
C     CAN'T DO SOME OF THE CALCULATIONS AT THE POLES, BUT WE KNOW THAT
C     THIS IS OUTSIDE RSAS, SO ACT ACCORDINGLY.
C     ------------------------------------------------------------------
                        INRSASDMN(L) = .FALSE.
                        
                     ELSE 

                        XCART = M_XGRID(LATL(L),LONL(L),X_POLE_S,
     1                       LAT_TRUE_S,LON_PS_S)

                        YCART = M_YGRID(LATL(L),LONL(L),Y_POLE_S,
     1                       LAT_TRUE_S,LON_PS_S)
                        IF(XCART.LT.XLIMN.OR.XCART.GT.XLIMX.OR.
     1                       YCART.LT.YLIMN.OR.YCART.GT.YLIMX)THEN

C     ------------------------------------------------------------------
C     IT'S OUTSIDE OF RSAS.
C     ------------------------------------------------------------------
                           INRSASDMN(L) = .FALSE.
                        ELSE
                           INRSASDMN(L) = .TRUE.
                        ENDIF
                     ENDIF
 4                CONTINUE
                  K = K + SFC_NRECS(SFC_NFILES)
                  SFC_SOURCE(SFC_NFILES) = I
                  GO TO 5
               ENDIF

C     ------------------------------------------------------------------
C     ERROR WITH THE NETCDF FILE.  CLOSE IT (IF OPEN) AND RELEASE ITS
C     SLOT IN THE COMMON.
C     ------------------------------------------------------------------
 10            IF(SFC_NCID(SFC_NFILES).GE.0)
     1            CALL MMADISCLS1(SFC_NCID(SFC_NFILES),SFCDIR(I),
     2                            SFCDIRLEN(I),SFC_FNAME(SFC_NFILES))
               SFC_NCID(SFC_NFILES) = -1
               SFC_NFILES = SFC_NFILES - 1

 5          CONTINUE

C     ------------------------------------------------------------------
C     IF WE HAVE ANYTHING FOR THIS DATASET, FILTER RECS WE DON'T WANT:
C     - JUNK METARS AND SAOS
C     - MISSING LAT, LON OR ELEV
C     - OUTSIDE THE TIME WINDOW
C     - MULTIPLES WITHIN THE TIME WINDOW (IF RECWIN SO INDICATES)
C     - PROVIDERS THAT HAVE BEEN DISABLED BY MSETPVDR
C     ------------------------------------------------------------------
 100        K = K - 1
            IF(K.EQ.0)THEN
               IF(KEEP_GOING)THEN
                  GO TO 1
               ELSE
                  GO TO 900
               ENDIF
            ENDIF

            CALL MSFCFLTR(ATIME,MINBCK,MINFWD,RECWIN,I,MISS_P,
     1                    PROVDR_ENBL(1,1),K,OBTIME,STANAML,WMOIDL,
     2                    PROVDRL,SUBSRC,LATL,LONL,ELEVL,ATYPE,RTYPE,
     3                    FNUML,RNUML,NSTANEW)

C     ------------------------------------------------------------------
C     THE CALLER IS EXPECTED TO HAVE MXSFC_P RECORDS AVAILABLE.  IF
C     THIS WOULD PUT HIM OVER THE TOP, RETURN WITH AN ERROR (SEE
C     REMARKS SECTION ABOVE).
C     ------------------------------------------------------------------
            IF(NSTANEW+SFC_LNUM.GT.MXSFC_P)THEN
               NSTA = 0
               LAST_SFC_ATIME = '         '
               STATUS = TOO_MANY_REC_P
               CALL MERROR('MSFCSTA: TOO MANY RECORDS REQUESTED')
               RETURN
            ENDIF

C     ------------------------------------------------------------------
C     TRANSFER REMAINING RECORDS TO CALLER'S ARRAYS, AND UPDATE INFO
C     IN COMMON.
C     ------------------------------------------------------------------
            DO 200 J = 1, NSTANEW
               K = SFC_LNUM + J
               STANAM(K) = STANAML(J)
               WMOID(K) = WMOIDL(J)
               LAT(K) = LATL(J)
               LON(K) = LONL(J)
               ELEV(K) = ELEVL(J)
               CALL M_MKFNAM(OBTIME(J),TIMEOB(K),STATUS)
               PROVDR(K) = PROVDRL(J)

               SFC_FNUM(K) = FNUML(J)
               SFC_RNUM(K) = RNUML(J)
               SOURCE_N(K) = I
 200        CONTINUE

            SFC_LNUM = SFC_LNUM + NSTANEW
         ENDIF

         IF(.NOT.KEEP_GOING)GO TO 900

 1    CONTINUE

C     ------------------------------------------------------------------
C     IF WE GOT ANYTHING AT ALL, TELL CALLER HOW MANY STATIONS AND
C     UPDATE THE ATIME KEPT IN COMMON SO SUBSEQUENT READS FOR THE
C     SAME TIME WILL USE THE FILE/RECORD INFO WE JUST WORKED SO HARD
C     TO CREATE...
C     ------------------------------------------------------------------
 900  IF(SFC_LNUM.GT.0)THEN
         NSTA = SFC_LNUM
         LAST_SFC_ATIME = ATIME
         STATUS = SUCCESS_P
      ELSE
         NSTA = 0
         LAST_SFC_ATIME = '         '
         STATUS = NO_DATA_P
         CALL MERROR('MSFCSTA: NO DATA FOR '//ATIME)
      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**---------------------------------------------------------------------
