      SUBROUTINE FRMRET (RETANC,HIRANC,SYNCTI,ODFREC,FRHREC,N16HIR,
     +                   ERSTAT)
      IMPLICIT NONE
C
C**********************************************************************
C
C   NAME- FRMRET
C
C   LANGUAGE- FORTRAN 77     TYPE- SUBROUTINE      COMPUTER- CRAY
C
C   VERSION- 1.0    DATE- 04/01/92   PROGRAMMER- DAVE MOREL (SMSRC)
C   VERSION- 2.0    DATE- 06/06/95   PROGRAMMER- LI LU (SMSRC)
C      ATOVS-123: INCLUDE TO /INSPARM/ IS ADDED BEFORE INCLUDE TO
C                 /FRMINF/. HNSPOT, HTOTLN ARE REMOVED FROM CALLING
C                 ARGUMENTS. HNPARM IS CHANGED TO HNANC.
C   VERSION- 2.1    DATE- 07/27/95   PROGRAMMER- LI LU (SMSRC)
C      ATOVS-148: FRAME SYNC TIME IS ADDED AS AN OUTPUT ARGUMENT.
C   VERSION- 2.2    DATE- 03/01/96   PROGRAMMER- DAVE MOREL (SMSRC)
C      ATOVS-346: CHANGING CYCLEN FROM 818 TO 826.
C   VERSION- 3.0    DATE- 06/06/96   PROGRAMMER- ALEX POZDNYAK (FDC)
C      ADDED AN EXPLICIT DATA STATEMENT FOR VARIABLES OPCFLG AND CONE.
C      THE CRAY DOES NOT SUPPORT DECLARATIONS WITH EMBEDDED IMPLICIT
C      DATA STATEMENTS.
C   VERSION- 3.1    DATE- 06/19/97   PROGRAMMER- LEAH WILSON (HSTX)
C      ADDED /OZONE/ AND FILLED FSTIME WITH THE FRAME STARTING TIME FOR
C      LATER USE BY SUBROUTINE OZOUT.  ALSO ADDED /STBGEO/.  CHANGED
C      CYCLEN FROM 826 TO 934.
C   VERSION- 4.0    DATE- 09/02/97   PROGRAMMER- LEAH WILSON (HSTX)
C      REPLACE ODB WITH ODF.  REMOVE FRMRE$.
C   VERSION- 4.1    DATE- 02/26/99   PROGRAMMER- LEAH WILSON (RAYTHEON)
C      ADD 4-DIGIT YEAR.
C   VERSION- 4.2    DATE- 04/21/00   PROGRAMMER- LEAH WILSON (RAYTHEON)
C      ADJUST HIRS FRAME BOUNDARIES.
C   VERSION- 4.3    DATE- 11/09/00   PROGRAMMER- A. ALLEGRINO (RITSS)
C      ADDED ARRAY FRHREC TO STORE THE FRAME HEADER RECORDS FOR LATER
C      USE IN DETERMINING MISLOCATED DATA.
C   VERSION- 4.4    DATE- 01/08/01   PROGRAMMER- FRANK TILLEY (RAYTHEON)
C      ADD COMMON /NOHIRSCF/. IF FLAG NOH1BS IS TRUE (NO HIRS 1B*)
C      USE HIRS SPOTS 2 AND 55 VICE 1 AND 56 FOR FRAME VERTICES. WITH
C      NO HIRS 1B*, HIRS SPOT LOCATIONS FOR SPOTS 2 THROUGH 55 ARE
C      INTERPOLATED FROM AMSU-A LOCATIONS AND SPOTS 1 AND 56 ARE
C      MISSING. (WR #100)
C   VERSION- 4.5    DATE- 02/12/01   PROGRAMMER- FRANK TILLEY (RAYTHEON)
C      ADDED CALLING ARGUMENT N16HIR TO USE LATITUDE AND LONGITUDE
C      VALUES FROM SPOT 2 AND NOT SPOT 1 WHEN THE HIRS DATA HAVE
C      BEEN SHIFTED TO COMPENSATE FOR HIRS MISALIGNMENT (NOAA-16).
C      (WR #131A)
C   VERSION- 4.6    DATE- 02/27/03   PROGRAMMER- Rickey Rollins (CSC)
C        Replace R4SPV equivalence test with ISR4SPV function
C
C   FUNCTION- THIS SUBROUTINE CREATES AN ODF FRAME HEADER FOR THE
C        RETRIEVAL GRID, AND WRITES THE HEADER TO THE ORBITAL DATA
C        FILE (ODF).
C
C   FILES-
C     DSN OR DESCRIPTIVE TITLE I/O  UNIT   FUNCTIONAL DESCRIPTION
C     ------------------------ ---  ----   ----------------------
C        .../ODF                O  ODBUNT  ORBITAL DATA FILE (FLAT)
C     .......KIDS               O   KUNIT  KIDS MESSAGE FILE
C
C   CALLING SEQUENCE PARAMETERS-
C     VARIABLE          TYPE I/O  FUNCTION
C     --------          ---- ---  --------
C     RETANC            REAL I/O  ARRAY OF DIMENSION (RNGRDP,RTOTLN,
C                                 RNANC) WHICH HOLDS THE ANCILLARY
C                                 INFORMATION FROM THE RETRIEVAL GRID.
C     HIRANC            REAL  I   ARRAY OF DIMENSION (INSPARM:HNSPOT,
C                                 HTOTLN,HNANC) WHICH HOLDS THE
C                                 ANCILLARY INFORMATION FROM THE
C                                 HIRS DATA.
C     SYNCTI            INT   O   VECTOR OF 3 CONTAINING THE SYNC TIME OF
C                                 THE FRAME.
C     ODFREC            INT   I   ODF RECORD NUMBER.
C     FRHREC            INT   O   ARRAY OF THE LOCATIONS OF FRAME HEADER
C                                 RECORDS.
C     N16HIR            INT   I   FLAG TO INDICATE WHETHER OR NOT HIRS
C                                 DATA WERE SHIFTED 1 SPOT TO THE RIGHT.
C     ERSTAT            INT   O   ERROR STATUS CODE(SEE EXIT STATES).
C
C   COMMON AREA PARAMETERS-
      INCLUDE 'MONSTA'
      INCLUDE 'INSPARM'
      INCLUDE 'INPARM'
      INCLUDE 'RTVPARM'
      INCLUDE 'FRMINF'
      INCLUDE 'COLLOC'
      INCLUDE 'STBGEO'
      INCLUDE 'OZONE'
      INCLUDE 'SPGUNT'
      INCLUDE 'ERPARM'
      INCLUDE 'ERINFO'
      INCLUDE 'NOHIRSCF'
C
C   LOCAL PARAMETERS-
C     VARIABLE          TYPE  FUNCTION
C     --------          ----  --------
C     STATUS            INT   ERROR STATUS CODE RETURNED FROM A FMU.
C     DUMMY             INT   A VECTOR OF TWO USED AS A PLACE HOLDER.
C     CNT               INT   COUNT OF THE CYCLES IN THE FRAME.
C     LAT               REAL  A VECTOR OF 4 INDICATING THE LATITUDE OF
C                             FIRST AND LAST SPOTS OF THE FIRST AND
C                             LAST ACTIVE SCAN RTOTLN.
C     LON               REAL  A VECTOR OF 4 INDICATING THE LONGITUDE
C                             CORRESPONDING TO THE SAME 4 SPOTS AT LAT.
C     CYCLEN            INT   CYCLE LENGTH OF THE DATA CYCLES.
C     ENDTIM            INT   VECTOR OF 3 CONTAINING THE ENDING TIME
C                             OF THE FRAME.
C     ORB               INT   VECTOR OF 2 CONTAINING THE STARTING
C                             AND ENDING ORBIT NUMBERS OF THE HIRS.
C     I                 INT   LOOP CONTROL INDEX.
C     J                 INT   NUMBER OF THE LAST HIRS ACTIVE SCANLINE.
C     K                 INT   LOOP CONTROL INDEX.
C     N                 INT   NUMBER OF FIRST HIRS ACTIVE SCANLINE.
C     MILTIM            INT   TIME IN MILLISECONDS.
C     REALSP            REAL  TOTAL SPOT NUMBERS AS A REAL VALUE.
C     ONCE              LOG   SET TRUE THE FIRST TIME ONLY.
C     C4TEMP           CH*4   TEMPORARY BUFFER FOR WRITING TO KIDS.
C     C6TEMP           CH*6   TEMPORARY BUFFER FOR WRITING TO KIDS.
C     KMSG            CH*100  KIDS MESSAGE BUFFER.
C     ODFBUF           INT    ODF RECORD BUFFER.
C
C   SUBPROGRAMS CALLED- ODBTIM, KIDS
C
C   FUNCTIONS USED- MOD, REAL
C
C   EXIT STATES-
C      ERSTAT = -2 : INDICATOR MEANING, NO RETRIEVALS IN THIS FRAME.
C      ERSTAT = -3 : UNRECOVERABLE ERROR IN HIRS SCAN PROCESSING.
C      ERSTAT = 99 : ERROR ENCOUNTERED IN ACCESSING ODF FILES.
C
C   COMMENTS-  IT IS ASSUMED THAT THE REQUIRED TIME AND ANCILLARY
C              HIRS BUFFERS CONTAIN THE CORRECT DATA EVEN IF THE
C              HIRS INSTRUMENT IS NOT PRESENT.
C*********************************************************************
C
      INTEGER   ERSTAT,IDX,ODFREC,IOERR,N16HIR,ODFLENGTH
      PARAMETER (ODFLENGTH=1000)
      REAL      RETANC(RNGRDP,RTOTLN,RNANC)
      REAL      HIRANC(HNSPOT,HTOTLN,HNANC)
      INTEGER   FRHREC(30)
      INTEGER*2 ODFBUF(ODFLENGTH/2)
C
      CHARACTER*2 C2TEMP
      CHARACTER*4 C4TEMP
      CHARACTER*6 C6TEMP
      CHARACTER*100 KMSG
      INTEGER     CYCLEN, I, J, K, SYNCTI(3), ENDTIM(3), CNT
      INTEGER     STATUS, DUMMY(2), N, MILTIM, ORB(2)
      INTEGER     CRAY2IBM, IERR
      REAL        LAT(4), LON(4), REALSP
      LOGICAL     ONCE
      LOGICAL ISR4SPV
C
      INCLUDE 'DEBUG'
      INCLUDE 'SPVAL'
C
C INITIALIZE LOCAL VARIABLES FOR THE RETRIEVAL GRID, ODB PARMS.
C
      CNT = 0
      IOERR = 0
      ONCE = .TRUE.
      I = 0
      J = 0
      N = 0
      REALSP = REAL(HNSPOT)
      DO IDX=1,(ODFLENGTH/2)
         ODFBUF(IDX) = I2SPV
      END DO
C
C COMPUTE THE CYCLECNT BY COUNTING THE AMOUNT OF RETRIEVALS
C WHICH HAVE A CLASS INDEX. IF THE COUNT IS ZERO RETURN WITH A
C ERROR STATUS OF -2 SO THE ROUTINE RETODB WILL NOT BE CALLED.
C
      DO 20 K = 1, RTOTLN
         DO 10 I = 1, RNGRDP
            IF(.NOT. ISR4SPV(RETANC(I,K,5))) THEN
               CNT = CNT + 1
            ENDIF
   10    CONTINUE
   20 CONTINUE
C
      NFRCYC(FRAMNO) = CNT
C
      IF(CNT .EQ. 0) THEN
         ERSTAT = -2
         RETURN
      ENDIF
C
C GET THE FIRST AND LAST ACTIVE HIRS LINE NUMBERS. BASED
C ON NEW FRAME BOUNDARIES (SEE INHIRS), THIS SHOULD GO
C FROM LINES 10-49.
C
      DO 30 I = HTOTBF, HTOTLN-1
         IF(HGOODL(I)) THEN
            IF(ONCE) THEN
               N = I
               ONCE = .FALSE.
            ENDIF
            J = I
         ENDIF
   30 CONTINUE
C
C IF NO GOOD HIRS SCANS ARE FOUND, ISSUE A WARNING MESSAGE
C AND RETURN A FATAL ERROR CODE TO THE CALLING ROUTINE.
C
      IF (J.LT.1) THEN
         SUBNAM = 'SPGDVR  '
         KMSG = 'FRMRET: NO GOOD HIRS SCAN TIMES FOUND.'
         PRINT *,KMSG
         CALL KIDS(KUNIT,SUBNAM,0,KMSG,0)
         ERSTAT = -3
         RETURN
      END IF
C
      ORB(1) = SORB(1)
      ORB(2) = EORB(1)
C
C  NOW WRITE THE INFORMATION TO THE ODF BUFFER.
C
      ODFBUF(1) = 1
C
C SET UP THE STARTING AND ENDING ORBIT NUMBERS.
C
      ODFBUF(2) = ORB(1)
      ODFBUF(3) = ORB(2)
C
C SET UP THE FRAME NUMBER FROM THE BEGINNING OF THE 1B DATA.
C
      ODFBUF(4) = FRAMNO
      ODFBUF(5) = CNT
      IF(DBUGPRT.EQ.1) THEN
         SUBNAM='SPGDVR  '
         KMSG='RODF-        RECS WRITTEN FOR FRAME   '
         WRITE(C6TEMP,'(I6)') CNT
         KMSG(7:12) = C6TEMP
         WRITE(C2TEMP,'(I2)') FRAMNO
         KMSG(37:38) = C2TEMP
         CALL KIDS(KUNIT,SUBNAM,2,KMSG,0)
      ENDIF

C
C THE HIRS INSTRUMENT IS USED TO REPRESENT THE RETRIEVAL GRID
C TIMES WHETHER THE HIRS IS PRESENT OR NOT THE HIRS SCAN LINE BUFFER
C WILL BE FILLED WITH THE CORRECT VALUES.
C THE 256 SECOND ACTIVE HIRS FRAME (SPOT 1 OF LINE 6 TO SPOT 56 OF
C LINE 45) WILL USED.
C
C CONVERT THE DATE/TIME FROM CENDAY/MILLISECOND TIME TO ODB TIME
C
      CALL ODBTIM(HSCTIM(1,N),HSCTIM(2,N),SYNCTI)
C
C STORE FRAME TIME FOR LATER USE IN STABILITY DEPARTURE CALCULATION
C AND FOR WRITING TO THE OZONE FILE.
C
      FRMTIM(1)=SYNCTI(1)
      FRMTIM(2)=SYNCTI(2)
      FRMTIM(3)=SYNCTI(3)
C
      FSTIME(1)=SYNCTI(1)
      FSTIME(2)=SYNCTI(2)
      FSTIME(3)=SYNCTI(3)
C
C SET UP THE SYNC TIME OF THE FRAME YEAR/MONTH,DAY/HOUR,MIN/SEC.
C
      ODFBUF(6) = SYNCTI(1)
      ODFBUF(7) = SYNCTI(2)
      ODFBUF(8) = SYNCTI(3)
      IF(ODFBUF(6)/100.EQ.99) THEN
         ODFBUF(21) = 1999
      ELSE
         ODFBUF(21) = ODFBUF(6)/100 + 2000
      ENDIF
C
C COMPUTE AND CONVERT THE OBSERVATION TIME OF THE LAST GRID CYCLE
C THIS IS DONE BY TAKING THE SCAN LINE TIME FROM THE COMMON
C FRMINF:HSCTIM PLUS THE DIFFERENCE IN TIME TO THE LAST SPOT
C OF THE LAST ACTIVE SCAN LINE.
C
      MILTIM = HSCTIM(2,J) + ((HNSPOT-1)*HIRTIM(2)) + HIRTIM(2)
      CALL ODBTIM(HSCTIM(1,J),MILTIM,ENDTIM)
C
C SET UP THE END_TIME OF THE LAST OBSERVED DATA CYCLE YYMM, DDHH, MMSS.
C
      ODFBUF(9) = ENDTIM(1)
      ODFBUF(10) = ENDTIM(2)
      ODFBUF(11) = ENDTIM(3)
      IF(ODFBUF(9)/100.EQ.99) THEN
         ODFBUF(22) = 1999
      ELSE
         ODFBUF(22) = ODFBUF(9)/100 + 2000
      ENDIF
C
C SET UP THE DATA FRAME LAT/LONG VERTICES (FIRST AND LAST ACTIVE SPOT OF
C THE FIRST ACTIVE SCAN LINE AND THE LAST AND FIRST ACTIVE SPOT OF THE
C LAST ACTIVE SCAN LINE), BASED ON THE ASSUMPTION THAT THE HIRS
C ANCILLARY DATA IS FILLED IN. THE ORDER OF THE FRAME VERTICES ARE
C IN A COUNTER CLOCKWISE DIRECTION. IF NO HIRS 1B* IS AVAILABLE,
C LOCATIONS FOR HIRS SPOTS 2 THROUGH 55 ARE INTERPOLATED FROM AMSU-A
C DATA AND NO LOCATIONS ARE AVAILABLE FOR SPOTS 1 AND 56. WHEN THE
C NOH1BS FLAG IS SET, USE SPOTS 2 AND 55 FOR FRAME VERTICES.
C
      IF (NOH1BS) THEN
         LAT(1) = HIRANC(2,N,1)
         LAT(2) = HIRANC(HNSPOT-1,N,1)
         LAT(3) = HIRANC(HNSPOT-1,J,1)
         LAT(4) = HIRANC(2,J,1)
      ELSE
         LAT(1) = HIRANC(1,N,1)
         LAT(2) = HIRANC(HNSPOT,N,1)
         LAT(3) = HIRANC(HNSPOT,J,1)
         LAT(4) = HIRANC(1,J,1)
      END IF
C
C IF THE "NOAA-16 HIRS" FLAG IS SET THERE WILL BE NO LATITUDES OR
C LONGITUDES FOR HIRS SPOT 1. USE THOSE FROM SPOT 2.
C
      IF (N16HIR.NE.0) THEN
         LAT(1) = HIRANC(2,N,1)
         LAT(4) = HIRANC(2,J,1)
      END IF
C
      ODFBUF(12) = NINT(LAT(1) * 128.0)
      ODFBUF(13) = NINT(LAT(2) * 128.0)
      ODFBUF(14) = NINT(LAT(3) * 128.0)
      ODFBUF(15) = NINT(LAT(4) * 128.0)
C
C SET UP THE DATA FRAME LONGITUDE VERTICES.
C
      IF (NOH1BS) THEN
          LON(1) = HIRANC(2,N,2)
          LON(2) = HIRANC(HNSPOT-1,N,2)
          LON(3) = HIRANC(HNSPOT-1,J,2)
          LON(4) = HIRANC(2,J,2)
      ELSE
          LON(1) = HIRANC(1,N,2)
          LON(2) = HIRANC(HNSPOT,N,2)
          LON(3) = HIRANC(HNSPOT,J,2)
          LON(4) = HIRANC(1,J,2)
      END IF
C
      IF (N16HIR.NE.0) THEN
         LON(1) = HIRANC(2,N,2)
         LON(4) = HIRANC(2,J,2)
      END IF
C
      ODFBUF(16) = NINT(LON(1) * 128.0)
      ODFBUF(17) = NINT(LON(2) * 128.0)
      ODFBUF(18) = NINT(LON(3) * 128.0)
      ODFBUF(19) = NINT(LON(4) * 128.0)
C
C  SAVE LATITUDE AND LONGITUDE OF THE FIRST AND LAST SCANS TO
C  THE COMMON BLOCK MONSTA FOR LATER USE BY MONITORING STATISTICS.
C
      DO 40 I= 1, 4
          LATVER(I, FRAMNO) = LAT(I)
          LONVER(I, FRAMNO) = LON(I)
   40 CONTINUE
C
C SET UP THE OPERATIONAL FLAGS. THE FIRST ONE MEANS THE FRAME WAS
C SUCCESSFULLY PROCESSED, THE OTHERS ARE UNSPECIFIED AS YET.
C
      ODFBUF(20) = 1
C
C INCREMENT RECORD NUMBER AND WRITE THE FRAME HEADER TO THE ODF.
C THE ODF IS A 2-BYTE FILE, SO USE CRAY2IBM TO CONVERT THE 8-BYTE
C ODFBUF TO A 2-BYTE BUFFER WHICH IS WRITTEN. SAVE FRAME HEADER
C RECORD IN ARRAY FRHREC.
C
      ODFREC = ODFREC + 1
      FRHREC(FRAMNO) = ODFREC
      WRITE(UNIT=ODBUNT,REC=ODFREC,IOSTAT=IOERR) ODFBUF
      IF(IOERR.NE.0) GO TO 900
      GO TO 1000
C
  900 KMSG(1:50)='* FATAL ERROR * WRITING RECORD        OF ODF FILE'
      KMSG(51:100)=' FOR FRAME     '
      WRITE(C6TEMP,'(I6)') ODFREC
      KMSG(32:37) =  C6TEMP
      WRITE(C4TEMP,'(I4)') FRMNBR
      KMSG(62:65) = C4TEMP
      IF(IOERR.NE.0) THEN
         KMSG(67:100) = 'WITH IOSTAT =     '
         WRITE(C4TEMP,'(I4)') IOERR
         KMSG(81:84) = C4TEMP
      ENDIF
      SUBNAM='SPGDVR'
      CALL KIDS(KUNIT,SUBNAM,0,KMSG,0)
C
C  SINCE SOMETHING WAS WRONG WITH THIS RECORD, DECREMENT THE RECORD
C  NUMBER COUNTER FOR THIS FILE
C
      ODFREC = ODFREC - 1
      ERSTAT = 99
C
 1000 RETURN
      END
