      MODULE s_getRnx
CC
CC NAME       :  getRnx
CC
CC PURPOSE    :  READ ALL THE OBSERVATIONS OF A RINEX FILE INTO MEMORY
CC
CC REMARKS    :  ---
CC
CC AUTHOR     :  T.A. SPRINGER
CC
CC CREATED    :  22-Jul-1996
CC
CC CHANGES    :  06-Feb-1997 TS: CHECK TIME ORDER OF EPOCHS
CC               23-Sep-1997 DI: USE MAXSAT.inc
CC               31-Aug-1998 DI: USE DEFREQ FOR GLONASS SATELLITES
CC               09-Sep-1999 TS: DO NOT USE C1 IF P1 AVAILABLE
CC               08-Oct-1999 TS/SS: "OBSTYP" IN CALL OF SR R2RDOR
CC               15-Jan-2002 MM: SET MAXTYP=10, DIMTST
CC               17-Feb-2003 LM: USE M_MAXDIM
CC               18-Feb-2003 SS: CONSIDER FIRST FREQUENCY CODE TYPE
CC               25-Feb-2003 SS: DEMAND MINIMAL PERCENTAGE OF P1
CC                               MEASUREMENTS
CC               28-Feb-2003 SS: TOLERANCES OF 85/15 CHANGED TO 70/30
CC               01-Apr-2003 SS: ALLOCATE "OBSAUX"
CC               30-Jun-2003 HB: ADOPT FOR CHANGES in SR R2RDOH
CC                               (SPACEBORNE)
CC               07-Jul-2003 RD: OBSAUX MUST BE "SAVE"
CC               08-Sep-2003 HU: FILENAMES CHR(*)
CC               13-Sep-2003 HU: INTERFACE FOR DEFREQ
CC               04-Dec-2003 HB: REMOVE ONLY FOR M_BERN,
CC                               COMMENT INCLUDE 'COMLFNUM.inc'
CC               12-Jan-2004 RD: SKIP SAT. W/O FREQ IN DEFREQ
CC                               USE OBSERVATION WINDOW
CC               16-Jun-2005 MM: UNUSED COMCONST.inc REMOVED
CC               23-Jun-2005 MM: IMPLICIT NONE AND DECLARATIONS ADDED
CC               08-Aug-2005 HB: Use new SR TIMST2 (module)
CC               27-Sep-2005 RD: IGNORE EPOCH FLAGS
CC               28-Sep-2005 RD: INPUT OPTION FOR EVENT FLAG HANDLING
CC               06-Jan-2006 RD: WORK-AROUND FOR TEQC-GLONASS LEAP SECOND PROBL.
CC               16-Aug-2006 HU: MAXTYP 10 -> 12
CC               20-Nov-2006 RD: REMOVE OBSERV. IF S1&S2-OBS. ARE ZERO
CC               20-Aug-2007 AG: MAXCHN 24 -> 40
CC               09-Jan-2008 RD: MOVE MAXCHN-TEST (CONFLICT WITH EPO-FLAG 4)
CC               31-Jan-2008 HB: FORMAT FOR MESSAGE:SPORADIC P1 CHANGED
CC               29-Jul-2009 SS: DIRECT ESTIMATION OF DCB VALUES
CC               29-Jul-2009 SS: USE C2 IF P2 UNAVAILABLE
CC               10-Aug-2009 SS: SR RNXDCB IMPLEMENTED
CC               03-Nov-2010 DT: MAXTYP 12->18
CC               18-Jan-2011 SL: MAXTYP FROM D_RINEX3
CC               26-Jan-2011 LP: SATELLITE-SPECIFIC OBS TYPES
CC               04-Mar-2011 MM: USE SATCRUX
CC               20-May-2011 LP: CORRECT WRONG GIOVE-A CODE OBSERVATIONS
CC               16-Sep-2011 EO/SL: DIMTST WITHOUT EXIT IF MAXTYP EXCEEDED
CC               03-Oct-2011 LP: Direct estimation of P1-P2 DCBs, too (ICBEST)
CC               01-Nov-2011 LP: Sat-specific obstypes also for C1/P2 receivers
CC               05-Nov-2011 RD: INCREASE RATION P1/C1 FROM 50 TO 60%
CC               01-Dec-2011 SS: RNXDCB CALL CHANGED, TEST FOR ICBEST
CC               01-Dec-2011 SL: USE M_BERN WITH ONLY
CC               13-Jan-2012 SS: CHANGED STATION NAME EXTRACTION
CC               09-Feb-2012 LP: MAXCOM 10->60; bugfix; correct also IOV code obs.
CC               23-Feb-2012 LP: Reinitialize array (OBSEPO...) before each R2RDOR call (new epoch)
CC               08-Mar-2012 LP: Correct huge code offsets for all GALILEO satellites
CC               23-Apr-2012 LP: Handling of slant TEC (SIP) file for RNXDCB
CC               30-Apr-2012 LP: Correct also GALILEO code offsets of 100000km
CC               04-May-2012 RD: USE DMOD FROM MODULE, REMOVE UNUSED VARIABLES
CC               24-May-2012 RD: INCREASE RATION P1/C1 FROM 60 TO 80%
CC               28-Aug-2012 SL/PW: MAXCHN SET TO MAXSAT FROM M_MAXDIM
CC               16-Nov-2012 RD: INIT ALL ELEMENTS FROM OBSFLG
CC               07-Mar-2013 SS: MAXCOM FROM 60 TO 300 (DUE TO BISK/POUS)
CC               19-Jul-2013 SC: use sr PRTFLNAM
CC               18-Jul-2013 LP: NEW CALL TO R2RDOH AND R2RDOR USING SATSYS
CC               04-Sep-2013 RD: MAXCOM IS DEFINED IN D_RINEX2
CC               02-Apr-2014 LP: ADD SATEPO(I) TO MAXSLP EXCEEDED WARNING
CC               17-Apr-2014 HB: OBSERVATION EPOCH AS TYPE T_EPOCH
CC               20-May-2014 HB: GET SNRREC FOR PG RES2ASC (GOCE HPF)
CC                               ADD GOCE PHASE UNWRAPPING AND
CC                               CORRECT EPOCH NUMBER HANDLING FOR GOCE
CC               23-Sep-2015 LP: INITIALIZE IRC,IFLAG BEFORE CALLING R2RDOR
CC               06-Dec-2016 AM: Add srName, call cpu_enter and cpu_exit
CC               07-Apr-2017 ST: Move IMPLICIT NONE to module scope
CC               07-Apr-2017 ST: Add #include "COM_CPU.inc"
CC               07-Apr-2017 ST: Add IF(srfDebug) in front of CALL cpu_
CC               05-Sep-2018 ST: Rename l_basFun::dMod to l_basFun::myDmod
CC                               for newer versions of PGF90 compiler
CC               19-Sep-2018 ST: Add rnxFileName to r2rdor
CC               18-Jun-2019 SS: Replaced COMFREQ.inc by genuine D_SATFRQ
CC               10-Jul-2019 ST: Removed variable numLin to be more
CC                               grep-comparable with other calls to r2RdOh
CC               02-Mar-2020 RD: Check dimensions for number of epochs (SR DIMTST)
CC               28-May-2020 RD: Reduce the limit for detecting the sampling (1s->0.1s)
CC               08-Jun-2020 RD: Write only 1 msg on event flag per file
CC               05-Sep-2020 ST: Add RINEX3,
CC                               therefore adapt to call wrapR2RdO?.
CC               13-Oct-2020 ST: Set rxoBaseConf%actionIfAntMrkNamNeFilNam.
CC               14-Oct-2020 ST: Add recTypHdr and adapt length of antTyp.
CC               15-Oct-2020 ST: Add setDefaultRxoBaseConfValues to o_rxoWrap.
CC               16-Oct-2020 ST: Remove RINEX header comment lines from wrapped
CC                               interface.
CC               21-Oct-2020 ST: Rename t_rxoRdConf to t_rxoRdState.
CC                               Split t_rxoBaseConf to t_rxoRdConfStatic
CC                               and t_rxoWrtConf.
CC                               Add applyPhaseShiftCorrsOnRd to getRnx.
CC               26-Oct-2020 ST: Split t_rxoRdConfStatic to t_rxoRdHdrConf
CC                               and t_rxoRdRecConf.
CC                               Split setDefaultRxoBaseConfValues
CC                               to setDefaultRxoRdHdrConfValues
CC                               and setDefaultRxoRdRecConfValues.
CC               27-Oct-2020 ST: Pass rxoRdHdrConf and rxoRdRecConf
CC                               as dummy variables to getRnx.
CC                               Replace obsWin by rxoRdHdrConf.
CC                               Replace smpInt by rxoRdRecConf.
CC               28-Oct-2020 ST: Replace wrapR2RdOh by rdRxoHdr
CC                               and extractFromHdr.
CC                               Replace RINEX version integers by t_rnxFmtVers.
CC                               Expose extractHdrInfo and calcSatSys.
CC               29-Oct-2020 ST: Split extractHdrInfo to extractPosEccsFromHdr
CC                               and  extractWlfsFromHdr.
CC                               Rename extractFromHdr to extractObsTypesFromHdr.
CC               30-Oct-2020 ST: Simplify return value of rdRxoHdr.
CC                               Simplify return state of wrapR2RdOr.
CC               09-Nov-2020 ST: Split t_rnxBaseConf to t_rnxRdHdrConf
CC                               and t_rnxRdRecConf.
CC               11-Nov-2020 ST: Don't use full t_rxoInpHdlr if not necessairy.
CC                               Fill optional rxoInpHdr from getRnx to prevent
CC                               later re-reading of RINEX file.
CC               12-Nov-2020 ST: Use t_rxoRdState to pass some dummy variables.
CC                               Get rid of labels, GOTO and CONTINUE.
CC               13-Nov-2020 ST: Properly initialize output variables.
CC               16-Nov-2020 ST: To speed up wrapR2RdOr and wrapR2WtOr,
CC                               take out constr/destr of t_rxoObsAtEpo,
CC                               pass rxoObsAtEpo as dummy variable,
CC                               only clear rxoObsAtEpo in the wrap routines.
CC               06-Dec-2020 ST: Bugfix division by zero.
CC               07-Dec-2020 ST: Bugfix: obsType has to contain the full list
CC                               of original observation types.
CC               22-Dec-2020 RD: Transform D_CONST to a protected structure CONST
CC               23-Dec-2020 RD: Transform D_SATFRQ to a protected structure SATFRQ
CC               21-Jan-2022 ST: For RINEX 4 navigation files, move
CC                               REC # / TYPE / VERS from d_rxoType to d_rnxType.
CC               12-Mar-2022 ST: Revive non-SMT RINEX version 2 (2.00).
CC               14-Mar-2022 SS: Removed DCB estimation feature
CC               27-Apr-2022 ST/AV: Replace maxTyp with maxObsTypeHash
CC               29-Jun-2023 ST: Add t_mxDim to allow better messages for user.
CC               29-Sep-2023 ST: Replace LOGICAL isSmt with enum rxo2OpMode.
CC               20-Jun-2024 RD: Sampling and time window is handled in the RINEX environment
CC
CC COPYRIGHT  :  ASTRONOMICAL INSTITUTE
CC      1996     UNIVERSITY OF BERN
CC               SWITZERLAND
      USE m_bern,     ONLY: i4b, r8b, fileNameLength, lfnErr, lfn001
      USE m_cpu,      ONLY: cpu_enter, cpu_exit
      USE m_maxdim,   ONLY: MAXSAT
      USE m_epoch,    ONLY: t_epoch,
     1                      ASSIGNMENT(=), OPERATOR(.epochToReal.),
     2                      OPERATOR(<), OPERATOR(>)
      USE d_const,    ONLY: CONST
      USE d_satfrq,   ONLY: SATFRQ
      USE d_rinex3,   ONLY: maxObsTypeHash,
     1                      t_gObsDef, t_rxo2OpMode,
     2                      obslistbasic
      USE d_satcrx,   ONLY: mxSatCrx, gtsatb
      USE l_basfun,   ONLY: myDmod
      USE d_rnxType,  ONLY: closeInpFile, openInpFile
      USE d_rxoType,  ONLY: t_rxoHdr, t_rxoInpHdlr, t_rxoObsAtEpo,
     1                      t_rxoRdHdrConf, t_rxoRdRecConf,
     2                      t_rxoRdState,
     3                      clear, constr, cpyConstr, destr
      USE o_rinexO,   ONLY: rdRxoHdr
      USE o_rxoWrap,  ONLY: extractObsTypesFromHdr, extractWlfsFromHdr,
     1                      wrapR2RdOr
      USE s_alcerr
      USE s_clrflg
      USE s_defreq
      USE s_dimtst
      USE f_djul
      USE s_exitRc
      USE s_gtflna
      USE s_jmt
      USE f_listi4
      USE f_prtflnam
      USE s_radgms
      USE s_timst2

      IMPLICIT NONE

#include "COM_CPU.inc"

      CONTAINS

      SUBROUTINE getRnx(rxoRdHdrConf, rxoRdRecConf, rxo2OpMode,
     1                  rxoRdState,
     2                  MAXREC, MAXCMB, FILNAM,
     3                  RMSTON, IC2USE, NRSAT, NUMSAT,
     4                  NEPOCH, OBSTIM, tEpNom, OBSREC, OBSFLG, CODTYP,
     5                  snrRec, IRCODE, useGeos, rxoInpHdr)

      ! Configuration for reading RINEX observation header.
      TYPE(t_rxoRdHdrConf),             INTENT(IN)    :: rxoRdHdrConf
      ! Configuration for reading RINEX observation records.
      TYPE(t_rxoRdRecConf),     TARGET, INTENT(IN)    :: rxoRdRecConf
      ! Operation mode for RINEX 2 observation files.
      TYPE(t_rxo2OpMode),               INTENT(IN)    :: rxo2OpMode
      ! RINEX observation read state.
      TYPE(t_rxoRdState),       TARGET, INTENT(INOUT) :: rxoRdState
      ! Maximum number of records.
      INTEGER(i4b),                     INTENT(IN)    :: MAXREC
      ! Maximum number of observation types and combinations
      INTEGER(i4b),                     INTENT(IN)    :: MAXCMB
      ! Name of RINEX file to be read
      CHARACTER(LEN=fileNameLength),    INTENT(IN)    :: FILNAM
      ! Remove all observations if S1 and S2 observations are zero
      ! 0 = No, 1 = Yes
      INTEGER(i4b),                     INTENT(IN)    :: RMSTON
      ! Use C2 if P2 unavailable
      ! 0 = No, 1 = Yes
      INTEGER(i4b),                     INTENT(IN)    :: IC2USE
      ! Number of observed satellites
      INTEGER(i4b),                     INTENT(OUT)   :: NRSAT
      ! Satellite numbers
      INTEGER(i4b),  DIMENSION(MAXSAT), INTENT(OUT)   :: NUMSAT
      ! Number of points in x and y array
      INTEGER(i4b),                     INTENT(OUT)   :: NEPOCH
      ! Array with time values (MJD)
      TYPE(t_epoch), DIMENSION(MAXREC), INTENT(OUT)   :: OBSTIM
      ! Nominal epoch
      REAL(r8b),     DIMENSION(MAXREC), INTENT(OUT)   :: tEpNom
      ! Array with observations
      REAL(r8b), DIMENSION(MAXREC, MAXCMB, MAXSAT),
     1                                  INTENT(OUT)   :: OBSREC
      ! Array with observation flags
      CHARACTER(LEN=1), DIMENSION(MAXREC, MAXCMB, MAXSAT),
     1                                  INTENT(OUT)   :: OBSFLG
      ! First frequency code type (P1/C1)
      CHARACTER(LEN=2),                 INTENT(OUT)   :: CODTYP
      ! Array with SNR values
      REAL(r8b), DIMENSION(MAXREC, 2, MAXSAT),
     1                                  INTENT(OUT)   :: snrRec
      ! Return code
      ! 0 = Ok, 1 = continue with next RINEX file.
      INTEGER(i4b),                     INTENT(OUT)   :: IRCODE
      INTEGER(i4b),                     INTENT(IN)    :: useGeos
      ! RINEX input header
      TYPE(t_rxoHdr),         OPTIONAL, INTENT(INOUT) :: rxoInpHdr

C Local Parameters
C ----------------
      CHARACTER(LEN=*), PARAMETER :: srName = 'getRnx'

      CHARACTER(LEN=2), DIMENSION(6), PARAMETER :: MEATYP
     1  = ['L1', 'L2', 'P1', 'P2', 'C1', 'C2']

      INTEGER(i4b), PARAMETER :: maxChn = maxSat
      INTEGER(i4b), PARAMETER :: maxSlp = 300
      INTEGER(i4b), PARAMETER :: maxBad = mxSatCrx%mx

C MAXCHN: MAXIMUM NUMBER OF CHANNELS
C MAXOBSTYPEHASH: MAXIMUM NUMBER OF OBSERVATION TYPES IN RINEX FILE
C MAXREC: MAXIMUM NUMBER OF OBS. PER SATELLITE IN FILE (24 HOURS WITH 30SEC SAMPLING)
C MAXARC: MAXIMUM NUMBER OF ARCS PER SATELLITE
C MAXSLP: MAXIMUM NUMBER OF CYCLE SLIPS PER SATELLITE
C MAXCMB: MAXIMUM NUMBER OF OBSERVATION TYPES USED
C MAXSAT: MAXIMUM NUMBER OF SATELLITES

C Local static variables
C ----------------------
      LOGICAL, SAVE :: firstCall = .TRUE.

      REAL(r8b), DIMENSION(:,:,:), ALLOCATABLE, SAVE :: obsaux
      REAL(r8b), DIMENSION(2, MAXBAD),          SAVE :: TIMBAD

      INTEGER(i4b), DIMENSION(MAXBAD), SAVE :: IACBAD, IOBBAD, SATBAD

      INTEGER(i4b), SAVE :: NBAD

C Local variables
C ---------------
      TYPE(t_rxoInpHdlr),  TARGET :: rxoInpHdlr
      TYPE(t_epoch)               :: rxepoch
      TYPE(t_rxoObsAtEpo), TARGET :: rxoObsAtEpo

      TYPE(t_rxoHdr),  POINTER :: rxoHdr
      TYPE(t_gObsDef), POINTER :: gObsDef

      REAL(r8b),        DIMENSION(maxChn, maxObsTypeHash) :: obsEpo
      REAL(r8b),        DIMENSION(2, maxSat)      :: epoGoc, obsGoc,
     1                                               obsJmp, timNof

      INTEGER(i4b),     DIMENSION(maxChn, maxObsTypeHash) :: iSign, lli
      INTEGER(i4b),     DIMENSION(maxSat, maxObsTypeHash) :: numObs
      INTEGER(i4b),     DIMENSION(3, maxSat)              :: iWlSat
      INTEGER(i4b),     DIMENSION(2, maxSat)              :: satSlp

      CHARACTER(LEN=2), DIMENSION(maxObsTypeHash) :: obsTyp

      REAL(r8b),        DIMENSION(2)      :: epoFrq

      INTEGER(i4b),     DIMENSION(maxSat) :: lstNof, prnGoc,
     1                                       satNof, stOn
      INTEGER(i4b),     DIMENSION(maxChn) :: satEpo
      INTEGER(i4b),     DIMENSION(6)      :: meaNum, namNum
      INTEGER(i4b),     DIMENSION(2)      :: iWlFac

      CHARACTER(LEN=fileNameLength) :: filCrx
      CHARACTER(LEN=40)             :: epoNof
      CHARACTER(LEN=4)              :: staNam4
      CHARACTER(LEN=2)              :: auxTyp
      CHARACTER(LEN=1)              :: ch1, obsT

      REAL(r8b) :: CORRECTION, DAY, EPOCH, EPOCOR, EPONOM, EPOSAV, DELT,
     1             RATCOD, RATMEA, RATNAM, SEC, SMPINT, WRAP

      INTEGER(i4b) :: I, IBAD, IDAY, IEPOCH,
     1                igeos, IHOUR, IHROLD, IMIN, IMNOLD, IMONTH,
     2                indgeos, INTEPO, IPOS, iprn, irc, ISAT, ISCOLD,
     3                ISEC, ISSTON, isys, ITYP, IYEAR, J, JSAT, K, L1L2,
     4                MINUTE, NAUX, NCOD, NEPSAT, NMEA, NOBSTP,
     5                NOBSTPHLP, NOBSTYPE, NOFRQ, NSAGOC,
     6                NSATEL, NWLSAT

      LOGICAL :: called, geosFlag, rdRxoSucceeded, satFound

C DEBUG: entry
C ------------
      IF (srfDebug) CALL cpu_enter(srName)

      NULLIFY(rxoHdr)

      gObsDef => rxoRdState%gObsDef

C Initialize output values
      NRSAT=0
      NUMSAT(:)=0
      NEPOCH=0
      tEpNom(:)=0d0
      OBSREC(:,:,:)=0d0
      OBSFLG(:,:,:)=''
      DO I=1,MAXREC
        OBSTIM(I)=0d0
        DO K=1,MAXSAT
          DO J=1,MAXCMB
            CALL CLRFLG(OBSFLG(I,J,K),0)
            CALL CLRFLG(OBSFLG(I,J,K),1)
            CALL CLRFLG(OBSFLG(I,J,K),2)
          ENDDO
        ENDDO
      ENDDO
      CODTYP=''
      snrRec(:,:,:)=-1.D0
      IRCODE=0

      IF (PRESENT(rxoInpHdr)) CALL clear(rxoInpHdr)

C GOCE CYCLE WRAPPING
      EPOGOC=0D0
      DELT  =5D0/1400D0
      WRAP  =2**20/3D0

      SMPINT = rxoRdRecConf%reqEpoch%samplInt_s

C ALLOCATE LOCAL VARIABLES
C ------------------------
      IF (firstCall) THEN
        ALLOCATE (obsaux(MAXREC,2,MAXSAT),STAT=irc)
        CALL alcerr(irc,'OBSAUX',[MAXREC,2,MAXSAT],srName)
        obsaux(:,:,:)=0.D0

        NBAD=0
        CALL GTFLNA(0,'SATCRUX',FILCRX,irc)
        CALL GTSATB(mxSatCrx,FILCRX,NBAD,SATBAD,IOBBAD,IACBAD,TIMBAD)

        firstCall = .FALSE.
      ENDIF

C INIT LIST OF SATELLITES W/O FREQ IN DEFREQ
C ------------------------------------------
      LSTNOF(:) = 0

C INITIALIZE VALUES
C -----------------

      MEANUM(:)=0
      NAMNUM(:)=0
      OBSTYP(:)=''
      NUMOBS(:,:)=0

      IEPOCH=0
      ISCOLD=-999
      IMNOLD=-999
      IHROLD=-999

C OPEN RINEX FILE
C ---------------
      CALL constr(rxoInpHdlr, LFN001, FILNAM)
      CALL constr(rxoObsAtEpo)
      CALL openInpFile(rxoInpHdlr%rdHdlr)

C READ RINEX HEADER
C -----------------
      rdRxoSucceeded = rdRxoHdr(
     1  rxoInpHdlr, rxoRdState, rxoRdHdrConf, rxo2OpMode, 0)

      IF (.NOT. rdRxoSucceeded) THEN
        CALL closeInpFile(rxoInpHdlr%rdHdlr)
        CALL destr(rxoObsAtEpo)
        CALL destr(rxoInpHdlr)
        IF (srfDebug) CALL cpu_exit(srName)
        RETURN
      ENDIF

      rxoHdr => rxoInpHdlr%inpHdrAndStat%hdr

      IF (PRESENT(rxoInpHdr)) THEN
        CALL destr(rxoInpHdr)
        CALL cpyConstr(rxoHdr, rxoInpHdr)
      ENDIF

      staNam4 = rxoHdr%plainData%antMrkName(1:4)

      CALL extractWlfsFromHdr(rxoHdr, iWlFac, iWlSat, nWlSat)

      CALL extractObsTypesFromHdr(
     1  rxoInpHdlr%rdHdlr%baseRdHdlr%fh%fileName_compr, rxoHdr,
     2  rxo2OpMode, nObsTp, obsTyp, nSatEl, numSat, numObs,
     3  useGeos, gObsDef)

      IF(IWLFAC(1).EQ.0) IWLFAC(1)=IWLSAT(1,1)
      IF(IWLFAC(2).EQ.0) IWLFAC(2)=IWLSAT(2,1)
      L1L2=0
      IF(IWLFAC(1).NE.0) L1L2=L1L2+1
      IF(IWLFAC(2).NE.0) L1L2=L1L2+2

C CHECK DIMENSION
C ---------------
      CALL DIMTST(0,2,2,srName,'MAXOBSTYPEHASH',
     1            'NUMBER OF OBSERVATION TYPES',' ',
     2             NOBSTP,MAXOBSTYPEHASH,irc)
      IF(irc.EQ.1) THEN
        IRCODE=1
        WRITE(LFNERR,'(/A,I3/16X,A,I3,2(/,16X,A),/)')
     1  ' ### SR getRnx: TOO MANY OBSERVATION TYPES:',NOBSTP,
     2                   'MAXIMUM NUMBER ALLOWED:',MAXOBSTYPEHASH,
     3                   'PROCESSING CONTINUED IGNORING THIS FILE!',
     4                   'RINEX FILE NAME: ' //
     5                    TRIM(PRTFLNAM(FILNAM,32))

        CALL closeInpFile(rxoInpHdlr%rdHdlr)
        CALL destr(rxoObsAtEpo)
        CALL destr(rxoInpHdlr)
        IF (srfDebug) CALL cpu_exit(srName)
        RETURN
      ENDIF
      NOBSTPHLP   = NOBSTP

C LOOP OVER ALL RECORDS
C ---------------------
      recLoop: DO

      called      = .FALSE.
      OBSEPO(:,:) = 0.D0
      ISIGN(:,:)  = 0
      LLI(:,:)    = 0
      SATEPO(:)   = 0
      NOBSTP      = NOBSTPHLP

      rdRxoSucceeded = wrapR2RdOr(
     1  rxoInpHdlr, rxoRdState, rxoObsAtEpo, rxoRdHdrConf,
     2  rxo2OpMode, rxoRdRecConf,
     3  NOBSTP, OBSTYP,rxepoch, epocor, NEPSAT, SATEPO,
     4  OBSEPO, ISIGN, LLI, useGeos, gObsDef)

      IF(.NOT. rdRxoSucceeded) EXIT recLoop

      EPOCH = .epochToReal.rxepoch

!!!!!!!!!! Needed for GOCE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
C CONVERSION
      CALL JMT(EPOCH,IYEAR,IMONTH,DAY)
      IDAY=IDINT(DAY)
      CALL RADGMS(3,rxepoch%frac,CH1,IHOUR,IMIN,SEC)
!!!      ISEC=IDNINT(SEC)
!!!!!!!!! Problem with measurement epoch >0.5 sec away from integer second
      SEC=SEC+0.5000000001D0
      ISEC=INT(SEC)

! Avoid double epoch for the same integer second:
      IF (ISEC==ISCOLD.AND.IMIN==IMNOLD.AND.IHOUR==IHROLD) CYCLE recLoop

      ISCOLD=ISEC
      IMNOLD=IMIN
      IHROLD=IHOUR
      DAY=IDAY+IHOUR/24.D0+IMIN/1440.D0+ISEC/86400.D0
      epoNom=DJUL(IYEAR,IMONTH,DAY)

      CALL JMT(EPOCH,IYEAR,IMONTH,DAY)
      CALL RADGMS(3,rxepoch%frac,CH1,IHOUR,MINUTE,SEC)

C REMOVE SATELLITES FROM SATCRX
C -----------------------------
      JSAT=0
      satLoop2: DO ISAT=1,NEPSAT
        indgeos = 0
        geosFlag = .FALSE.
        NOBSTP = NOBSTPHLP
        IF (useGeos == 1) THEN
          DO igeos = 1, gObsDef%norec
            IF (gObsDef%sat(igeos)%eposatind==ISAT) THEN
              geosFlag = .TRUE.
              indgeos = igeos
              NOBSTP = 4
              EXIT
            ENDIF
          ENDDO
        ENDIF

        badLoop: DO IBAD=1,NBAD
          IF (SATEPO(ISAT).NE.SATBAD(IBAD).OR.
     1        IACBAD(IBAD).NE.2           .OR.
     2        TIMBAD(1,IBAD).GT.EPOCH     .OR.
     3        TIMBAD(2,IBAD).LT.EPOCH          ) CYCLE badLoop

          IF (IOBBAD(IBAD).EQ.3) THEN
            OBSEPO(ISAT,:)=0.D0
          ELSE
            DO ITYP=1,NOBSTP
              IF (geosFlag) THEN
                IF (indgeos==0) EXIT
                IF ((IOBBAD(IBAD).EQ.1).AND.
     1            (gObsDef%sat(indgeos)%obstyp2(ITYP)(1:1).EQ."L")) THEN
                  OBSEPO(ISAT,ITYP)=0.D0
                ELSEIF ((IOBBAD(IBAD).EQ.2).AND.
     1            (gObsDef%sat(indgeos)%obstyp2(ITYP)(1:1).EQ."P")) THEN
                  OBSEPO(ISAT,ITYP)=0.D0
                ENDIF
              ELSE

                IF (IOBBAD(IBAD).EQ.1.AND.
     1            OBSTYP(ITYP)(1:1).EQ."L") THEN
                  OBSEPO(ISAT,ITYP)=0.D0
                ELSEIF (IOBBAD(IBAD).EQ.2.AND.
     1                (OBSTYP(ITYP)(1:1).EQ."C".OR.
     2                 OBSTYP(ITYP)(1:1).EQ."P")) THEN
                  OBSEPO(ISAT,ITYP)=0.D0
                ENDIF
              ENDIF

            ENDDO
          ENDIF
        ENDDO badLoop

        IF (.NOT.ALL(OBSEPO(ISAT,:).EQ.0.D0)) THEN
          JSAT=JSAT+1
          IF (JSAT.EQ.ISAT) CYCLE satLoop2
          SATEPO(JSAT)=SATEPO(ISAT)
          OBSEPO(JSAT,:)=OBSEPO(ISAT,:)
          ISIGN(JSAT,:)=ISIGN(ISAT,:)
          LLI(JSAT,:)=LLI(ISAT,:)
          IF (geosFlag) THEN
            gObsDef%sat(indgeos)%eposatind=JSAT
          ENDIF
        ENDIF
      ENDDO satLoop2

      NEPSAT=JSAT

C CHECK NUMBER OF SATELLITES FOR THIS EPOCH
C -----------------------------------------
      IF(NEPSAT>MAXCHN)THEN
        WRITE(lfnerr,906)MAXCHN,NEPSAT,EPOCH
906     FORMAT(/,' *** SR getRnx: MAXCHN exceeded!',/,
     1                       16X,'MAXCHN         : ',I4,/,
     2                       16X,'# of satellites: ',I4,/,F15.7)
        IF(NEPSAT>MAXCHN) CALL exitRc(2)
      ENDIF

C KEEP FIRST EPOCH
C ----------------
      IF(IEPOCH.EQ.0) THEN
        EPOSAV=EPOCH
      ELSE

C CHECK TIME ORDER OF EPOCHS
C --------------------------
        IF (EPOCH.LE.(.epochToReal.OBSTIM(IEPOCH))) CYCLE recLoop
      ENDIF

C CHECK OBSERVATION WINDOW
C ------------------------
C      IF (EPOCH < rxoRdRecConf%rnxRdRecConf%timeWin%t(1)) CYCLE recLoop
C      IF (EPOCH > rxoRdRecConf%rnxRdRecConf%timeWin%t(2)) EXIT recLoop

C SAMPLING
C --------
C      INTEPO=NINT(myDmod((EPOCH-DINT(EPOSAV))*864000D0,SMPINT*10D0))
C      IF(INTEPO.EQ.DNINT(SMPINT*10d0) .OR. INTEPO.EQ.0 .OR.
C     1   SMPINT.EQ.0.0)THEN
        IEPOCH=IEPOCH+1
        CALL DIMTST(1, 2, 2, srName,'MAXREC', 'NUMBER OF RECORDS',
     1  'VALUE IS TAKEN FROM PROGRAM INPUT PANEL', iepoch, maxrec, irc)
C      ELSE
C        CYCLE recLoop
C      ENDIF

C  CHECK IF SATELLITES ARE SET ACTIVE IN SATELLITE FILE AND SET
C  THE CORRESPONDING FREQUENCIES (CF.'I:COMFREQ')
C  ------------------------------------------------------------
      EPOFRQ(1)= EPOCH
      EPOFRQ(2)= EPOCH

      called = .FALSE.
      IF (useGeos == 1 .AND. gObsDef%norec > 0) THEN
        OBST='U'
        CALL DEFREQ(EPOFRQ,NEPSAT,SATEPO,NOFRQ,SATNOF,
     1              useGeos=useGeos,gObsDef=gObsDef,MEATYPC=OBST)
        called = .TRUE.
      ENDIF
      IF (.NOT. called) THEN
        CALL DEFREQ(EPOFRQ,NEPSAT,SATEPO,NOFRQ,SATNOF)
      ENDIF

C  CHECK OBSERVATIONS
C    - DUAL FREQ INSTR: BOTH L1 AND L2 HAVE TO BE PRESENT
C    - GET NUMBER OF OBSERVED SATELLITES PER EPOCH
C    - COUNT LOSSES OF LOCK
C    - DETERMINE NUMBER OF MISSING EPOCHS

      OBSTIM(IEPOCH)=rxepoch
      tEpNom(IEPOCH)=epoNom

      ISSTON=0
      STON(1:NEPSAT)=0

      satLoop: DO I=1,NEPSAT

C HAS THIS SATELLITE A FREQUENCY?
C -------------------------------
        frqLoop: DO ISAT=1,NOFRQ
          IF (SATEPO(I).EQ.SATNOF(ISAT)) THEN
            DO JSAT=1,MAXSAT
              IF (LSTNOF(JSAT).EQ.SATEPO(I)) THEN
                TIMNOF(2,JSAT)=EPOCH
                CYCLE satLoop
              ENDIF
              IF (LSTNOF(JSAT).EQ.0) THEN
                LSTNOF(JSAT)=SATEPO(I)
                TIMNOF(1,JSAT)=EPOCH
                TIMNOF(2,JSAT)=EPOCH
                CYCLE satLoop
              ENDIF
            ENDDO
          ENDIF
        ENDDO frqLoop

C FILL SATELLITE ARRAY AND FIND RIGHT SATELLITE INDEX
C ---------------------------------------------------
        satFound = .FALSE.

        DO ISAT=1,NRSAT
          IF (SATEPO(I).EQ.NUMSAT(ISAT)) THEN
            satFound = .TRUE.
            EXIT
          ENDIF
        ENDDO

        IF (.NOT. satFound) THEN
          NRSAT=NRSAT+1
          NUMSAT(NRSAT)=SATEPO(I)
          ISAT=NRSAT
          SATSLP(1,ISAT)=0
          SATSLP(2,ISAT)=0
        ENDIF

C ORDER THE OBSERVATIONS
C ----------------------
        isys = INT(SATEPO(I)/100)
        iprn = SATEPO(I)-isys*100
        geosFlag = .FALSE.
        indgeos  = 0
        NOBSTYPE = 0
        IF (useGeos == 1) THEN
          DO igeos = 1, gObsDef%norec
            IF ((gObsDef%sat(igeos)%sysnum==isys)
     1        .AND.(gObsDef%sat(igeos)%satnum==iprn)) THEN
              geosFlag = .TRUE.
              indgeos = igeos
              EXIT
            ENDIF
          ENDDO
        ENDIF
        IF (.NOT. geosFlag) THEN
           NOBSTYPE=NOBSTPHLP
        ELSEIF(geosFlag) THEN
           NOBSTYPE=4
        ENDIF

        obsLoop: DO K=1,NOBSTYPE

C CONVERT L1 TO METERS
C --------------------
          called = .FALSE.
          IF(.NOT. geosFlag) THEN
           IF(OBSTYP(K).EQ.'L1') THEN
              called = .TRUE.

C CORRECT CYCLE WRAPPING IN RINEX FILES FROM GOCE
              IF (OBSEPO(I,K).NE.0D0 .AND.staNam4 == 'GOCE') THEN
                IPOS=LISTI4(1,MAXSAT,PRNGOC,SATEPO(I),NSAGOC)
                IF (EPOCH < EPOGOC(1,IPOS)+DELT) THEN
                  IF(OBSEPO(I,K)-OBSGOC(1,IPOS)     >  WRAP/2D0) THEN
                    OBSJMP(1,IPOS)=OBSJMP(1,IPOS)-WRAP
                  ELSEIF(OBSEPO(I,K)-OBSGOC(1,IPOS) < -WRAP/2D0) THEN
                    OBSJMP(1,IPOS)=OBSJMP(1,IPOS)+WRAP
                  ENDIF
                ELSE
                  OBSJMP(1,IPOS)=0D0
                ENDIF
                EPOGOC(1,IPOS)=EPOCH
                OBSGOC(1,IPOS)=OBSEPO(I,K)
                OBSEPO(I,K)=OBSEPO(I,K)+OBSJMP(1,IPOS)
              ENDIF
            ENDIF
          ELSEIF(geosFlag) THEN
            IF(gObsDef%sat(indgeos)%obstyp2(K).EQ.'L1') THEN
              called = .TRUE.
            ENDIF
          ENDIF

          IF(called) THEN
            OBSREC(IEPOCH,1,ISAT)=OBSEPO(I,K)*SATFRQ%wlgt(1,SATEPO(I))
            IF (LLI(I,K).GT.0.AND.LLI(I,K).LT.4) THEN
              SATSLP(1,ISAT)=SATSLP(1,ISAT)+1
              IF (SATSLP(1,ISAT).GT.MAXSLP) THEN
                WRITE(LFNERR,902)SATSLP(1,ISAT),MAXSLP,
     1                TRIM(PRTFLNAM(FILNAM,32)), SATEPO(I)
902             FORMAT(/,' ### SR getRnx: MAXSLP EXCEEDED',/,
     1                               16X,'NUMBER OF SLIPS : ',I4,/,
     2                               16X,'MAXIMUM NUMBER  : ',I4,/,
     3                               16X,'RINEX FILE      : ',A,/,
     4                               16X,'SATELLITE       : ',I3,/)
                SATSLP(1,ISAT)=1
              ENDIF
            ENDIF
            IF (OBSEPO(I,K).NE.0.D0) THEN
              MEANUM(1)=MEANUM(1)+1
            ELSE
              NAMNUM(1)=NAMNUM(1)+1
            ENDIF
          ENDIF

C CONVERT L2 TO METERS
C --------------------
          called = .FALSE.
          IF(.NOT. geosFlag) THEN
            IF(OBSTYP(K).EQ.'L2') THEN
              called = .TRUE.
C CORRECT CYCLE WRAPPING IN RINEX FILES FROM GOCE
              IF (OBSEPO(I,K).NE.0D0 .AND.staNam4 == 'GOCE') THEN
                IPOS=LISTI4(1,MAXSAT,PRNGOC,SATEPO(I),NSAGOC)
                IF (EPOCH < EPOGOC(2,IPOS)+DELT) THEN
                  IF(OBSEPO(I,K)-OBSGOC(2,IPOS)     >  WRAP/2D0) THEN
                    OBSJMP(2,IPOS)=OBSJMP(2,IPOS)-WRAP
                  ELSEIF(OBSEPO(I,K)-OBSGOC(2,IPOS) < -WRAP/2D0) THEN
                    OBSJMP(2,IPOS)=OBSJMP(2,IPOS)+WRAP
                  ENDIF
                ELSE
                  OBSJMP(2,IPOS)=0D0
                ENDIF
                EPOGOC(2,IPOS)=EPOCH
                OBSGOC(2,IPOS)=OBSEPO(I,K)
                OBSEPO(I,K)=OBSEPO(I,K)+OBSJMP(2,IPOS)
              ENDIF
            ENDIF
          ELSEIF(geosFlag) THEN
            IF(gObsDef%sat(indgeos)%obstyp2(K).EQ.'L2') THEN
              called = .TRUE.
            ENDIF
          ENDIF

          IF(called) THEN
            OBSREC(IEPOCH,2,ISAT)=OBSEPO(I,K)*SATFRQ%wlgt(2,SATEPO(I))
            IF (LLI(I,K).GT.0.AND.LLI(I,K).LT.4) THEN
              SATSLP(2,ISAT)=SATSLP(2,ISAT)+1
              IF (SATSLP(2,ISAT).GT.MAXSLP) THEN
                WRITE(LFNERR,902)SATSLP(2,ISAT),MAXSLP,
     1                TRIM(PRTFLNAM(FILNAM,32)),SATEPO(I)
                SATSLP(2,ISAT)=1
              ENDIF
            ENDIF
            IF (OBSEPO(I,K).NE.0.D0) THEN
              MEANUM(2)=MEANUM(2)+1
            ELSE
              NAMNUM(2)=NAMNUM(2)+1
            ENDIF
          ENDIF

C P1 IN METERS
C ------------
          called = .FALSE.
          IF(.NOT. geosFlag) THEN
           IF(OBSTYP(K).EQ.'P1') THEN
              called = .TRUE.
           ENDIF
          ELSEIF(geosFlag) THEN
           IF(gObsDef%sat(indgeos)%obstyp2(K).EQ.'P1') THEN
              called = .TRUE.
           ENDIF
          ENDIF

          IF (called) THEN
            OBSREC(IEPOCH,3,ISAT)=OBSEPO(I,K)
            if(numsat(isat).gt.100.and.numsat(isat).lt.200.and.
     1         dabs(OBSREC(IEPOCH,3,ISAT)).gt.CONST%c) then
              do while (OBSREC(IEPOCH,3,ISAT).gt.CONST%c)
                OBSREC(IEPOCH,3,ISAT)=OBSREC(IEPOCH,3,ISAT)-CONST%c
              enddo
              do while (OBSREC(IEPOCH,3,ISAT).lt.-CONST%c)
                OBSREC(IEPOCH,3,ISAT)=OBSREC(IEPOCH,3,ISAT)+CONST%c
              enddo
            endif

c           Correct for half and full second code offsets for GALILEO satellites
            correction = 0.d0
            if (isys.eq.2) then
             if (dabs(obsrec(iepoch,3,isat)).gt.0.2*CONST%c) then
              correction = 0.3*CONST%c
              if (dabs(obsrec(iepoch,3,isat)).gt.0.3*CONST%c) then
                correction = 0.5*CONST%c
                if (dabs(obsrec(iepoch,3,isat)).gt.0.75*CONST%c) then
                  correction = CONST%c
                  if (dabs(obsrec(iepoch,3,isat)).gt.1.5*CONST%c) then
                    correction = 2*CONST%c
                  endif
                endif
              endif
              if (obsrec(iepoch,3,isat).lt.0d0) then
                  obsrec(iepoch,3,isat)=
     1                   obsrec(iepoch,3,isat)+correction
              else
                  obsrec(iepoch,3,isat)=
     1                   obsrec(iepoch,3,isat)-correction
              endif
             endif
            endif

            IF (OBSEPO(I,K).NE.0.D0) THEN
              MEANUM(3)=MEANUM(3)+1
            ELSE
              NAMNUM(3)=NAMNUM(3)+1
            ENDIF
          ENDIF

C P2 IN METERS
C ------------
          called = .FALSE.
          IF(.NOT. geosFlag) THEN
           IF(OBSTYP(K).EQ.'P2') THEN
              called = .TRUE.
           ENDIF
          ELSEIF(geosFlag) THEN
           IF(gObsDef%sat(indgeos)%obstyp2(K).EQ.'P2') THEN
              called = .TRUE.
           ENDIF
          ENDIF

          IF(called) THEN
            OBSREC(IEPOCH,4,ISAT)=OBSEPO(I,K)
            if(numsat(isat).gt.100.and.numsat(isat).lt.200.and.
     1         dabs(OBSREC(IEPOCH,4,ISAT)).gt.CONST%c) then
              do while (OBSREC(IEPOCH,4,ISAT).gt.CONST%c)
                OBSREC(IEPOCH,4,ISAT)=OBSREC(IEPOCH,4,ISAT)-CONST%c
              enddo
              do while (OBSREC(IEPOCH,4,ISAT).lt.-CONST%c)
                OBSREC(IEPOCH,4,ISAT)=OBSREC(IEPOCH,4,ISAT)+CONST%c
              enddo
            endif
c
c           Correct for half and full second code offsets for GALILEO satellites
            correction = 0.d0
            if (isys.eq.2) then
             if (dabs(obsrec(iepoch,4,isat)).gt.0.2*CONST%c) then
              correction = 0.3*CONST%c
              if (dabs(obsrec(iepoch,4,isat)).gt.0.3*CONST%c) then
                correction = 0.5*CONST%c
                if (dabs(obsrec(iepoch,4,isat)).gt.0.75*CONST%c) then
                  correction = CONST%c
                  if (dabs(obsrec(iepoch,4,isat)).gt.1.5*CONST%c) then
                    correction = 2*CONST%c
                  endif
                endif
              endif
              if (obsrec(iepoch,4,isat).lt.0d0) then
                  obsrec(iepoch,4,isat)=
     1                   obsrec(iepoch,4,isat)+correction
              else
                  obsrec(iepoch,4,isat)=
     1                   obsrec(iepoch,4,isat)-correction
              endif
             endif
            endif
c
            IF (OBSEPO(I,K).NE.0.D0) THEN
              MEANUM(4)=MEANUM(4)+1
            ELSE
              NAMNUM(4)=NAMNUM(4)+1
            ENDIF
          ENDIF

C C1 IN METERS
C ------------
          called = .FALSE.
          IF(.NOT. geosFlag) THEN
           IF(OBSTYP(K).EQ.'C1') THEN
              called = .TRUE.
           ENDIF
          ENDIF
          IF (called) THEN
            obsaux(IEPOCH,1,ISAT)=OBSEPO(I,K)
            if(numsat(isat).gt.100.and.numsat(isat).lt.200.and.
     1         dabs(OBSaux(IEPOCH,1,ISAT)).gt.CONST%c) then
              do while (OBSaux(IEPOCH,1,ISAT).gt.CONST%c)
                OBSaux(IEPOCH,1,ISAT)=OBSaux(IEPOCH,1,ISAT)-CONST%c
              enddo
              do while (OBSaux(IEPOCH,1,ISAT).lt.-CONST%c)
                OBSaux(IEPOCH,1,ISAT)=OBSaux(IEPOCH,1,ISAT)+CONST%c
              enddo
            endif
c
c           Correct for half and full second code offsets for GALILEO satellites
            correction = 0.d0
            if (isys.eq.2) then
             if (dabs(obsaux(IEPOCH,1,ISAT)).gt.0.2*CONST%c) then
              correction = 0.3*CONST%c
              if (dabs(obsaux(IEPOCH,1,ISAT)).gt.0.3*CONST%c) then
                correction = 0.5*CONST%c
                if (dabs(obsaux(IEPOCH,1,ISAT)).gt.0.75*CONST%c) then
                  correction = CONST%c
                  if (dabs(obsaux(IEPOCH,1,ISAT)).gt.1.5*CONST%c) then
                    correction = 2*CONST%c
                  endif
                endif
              endif
              if (obsaux(IEPOCH,1,ISAT).lt.0d0) then
                  obsaux(IEPOCH,1,ISAT)=
     1                   obsaux(IEPOCH,1,ISAT)+correction
              else
                  obsaux(IEPOCH,1,ISAT)=
     1                   obsaux(IEPOCH,1,ISAT)-correction
              endif
             endif
            endif
c
            IF (OBSEPO(I,K).NE.0.D0) THEN
              MEANUM(5)=MEANUM(5)+1
            ELSE
              NAMNUM(5)=NAMNUM(5)+1
            ENDIF
          ENDIF

C C2 IN METERS
C ------------
          called = .FALSE.
          IF(.NOT. geosFlag) THEN
           IF(OBSTYP(K).EQ.'C2') THEN
              called = .TRUE.
           ENDIF
          ENDIF
          IF (called) THEN
            obsaux(IEPOCH,2,ISAT)=OBSEPO(I,K)
            if(numsat(isat).gt.100.and.numsat(isat).lt.200.and.
     1         dabs(OBSaux(IEPOCH,2,ISAT)).gt.CONST%c) then
              do while (OBSaux(IEPOCH,2,ISAT).gt.CONST%c)
                OBSaux(IEPOCH,2,ISAT)=OBSaux(IEPOCH,2,ISAT)-CONST%c
              enddo
              do while (OBSaux(IEPOCH,2,ISAT).lt.-CONST%c)
                OBSaux(IEPOCH,2,ISAT)=OBSaux(IEPOCH,2,ISAT)+CONST%c
              enddo
            endif
c
c           Correct for half and full second code offsets for GALILEO satellites
            correction = 0.d0
            if (isys.eq.2) then
             if (dabs(obsaux(IEPOCH,2,ISAT)).gt.0.2*CONST%c) then
              correction = 0.3*CONST%c
              if (dabs(obsaux(IEPOCH,2,ISAT)).gt.0.3*CONST%c) then
                correction = 0.5*CONST%c
                if (dabs(obsaux(IEPOCH,2,ISAT)).gt.0.75*CONST%c) then
                  correction = CONST%c
                  if (dabs(obsaux(IEPOCH,2,ISAT)).gt.1.5*CONST%c) then
                    correction = 2*CONST%c
                  endif
                endif
              endif
              if (obsaux(IEPOCH,2,ISAT).lt.0d0) then
                  obsaux(IEPOCH,2,ISAT)=
     1                   obsaux(IEPOCH,2,ISAT)+correction
              else
                  obsaux(IEPOCH,2,ISAT)=
     1                   obsaux(IEPOCH,2,ISAT)-correction
              endif
             endif
            endif
c
            IF (OBSEPO(I,K).NE.0.D0) THEN
              MEANUM(6)=MEANUM(6)+1
            ELSE
              NAMNUM(6)=NAMNUM(6)+1
            ENDIF
          ENDIF

C S1
C --
          IF(OBSTYP(K).EQ.'S1') THEN
            snrRec(iEpoch,1,iSat)=obsEpo(i,k)
          ENDIF

C S2
C --
          IF(OBSTYP(K).EQ.'S2') THEN
            snrRec(iEpoch,2,iSat)=obsEpo(i,k)
          ENDIF

C CHECK FOR S/N-OBS == 0D0
C ------------------------
          called = .FALSE.
          IF(.NOT. geosFlag) THEN
           IF (OBSTYP(K).EQ.'S1'.OR.OBSTYP(K).EQ.'S2') THEN
              called = .TRUE.
           ENDIF
          ENDIF
          IF (called) THEN
            IF (OBSEPO(I,K).EQ.0D0) THEN
              ISSTON=ISSTON+1
              STON(I)=STON(I)+1
            ENDIF
          ENDIF

        ENDDO obsLoop

      ENDDO satLoop

C CHECK FOR S/N-OBS == 0D0
C ------------------------
      IF (RMSTON.EQ.1.AND.ISSTON.LT.2*NEPSAT) THEN
        DO I=1,NEPSAT
          IF (STON(I) == 2) THEN
            DO ISAT=1,NRSAT
              IF (SATEPO(I).EQ.NUMSAT(ISAT)) THEN
                OBSREC(IEPOCH,:,ISAT)=0D0
              ENDIF
            ENDDO
          ENDIF
        ENDDO
      ENDIF

C NEXT RECORD
C -----------
      ENDDO recLoop

C END OF RINEX FILE
C -----------------
      CALL closeInpFile(rxoInpHdlr%rdHdlr)
      CALL destr(rxoObsAtEpo)
      CALL destr(rxoInpHdlr)
      NEPOCH=IEPOCH

C TEST SOME OF THE MAXIMUM DIMENSIONS
C -----------------------------------
      IF (NRSAT.GT.MAXSAT) THEN
        WRITE(LFNERR,903)NRSAT,MAXSAT,TRIM(PRTFLNAM(FILNAM,32))
903     FORMAT(/,' *** SR getRnx: TOO MANY SATELLITES',/,
     1                       16X,'NUMBER OF SATELLITES     : ',I5,/,
     2                       16X,'MAX. NUMBER OF SATELLITES: ',I5,/,
     3                       16X,'RINEX FILE               : ',A,/)
        CALL exitRc(2)
      ENDIF

      IF (NEPOCH.GT.MAXREC) THEN
        WRITE(LFNERR,904)NEPOCH,MAXREC,TRIM(PRTFLNAM(FILNAM,32))
904     FORMAT(/,' *** SR getRnx: TOO MANY OBSERVATION EPOCHS',/,
     1                       16X,'NUMBER OF EPOCHS     : ',I5,/,
     2                       16X,'MAX. NUMBER OF EPOCHS: ',I5,/,
     3                       16X,'RINEX FILE           : ',A,/)
        CALL exitRc(2)
      ENDIF

C REPORT SATELLITES REMOVED BECAUSE NO FREQUENCY AVAILABLE IN DEFREQ
C ------------------------------------------------------------------
      DO ISAT=1,MAXSAT
        IF (LSTNOF(ISAT).EQ.0) EXIT
        CALL TIMST2(1,2,TIMNOF(1:2,ISAT),EPONOF)
        WRITE(LFNERR,905) LSTNOF(ISAT),EPONOF,
     1                    TRIM(PRTFLNAM(FILNAM,32))
905     FORMAT(/,' ### SR getRnx: OBSERVATIONS REMOVED BECAUSE NOT ',
     1                           'BOTH FREQUENCIES ARE DEFINED FOR',/,
     2                       16X,'SATELLITE NUMBER : ',I3,/,
     3                       16X,'EPOCHS           : ',A,/,
     4                       16X,'RINEX FILE       : ',A,/)
      ENDDO

C TAKE P1 MEASUREMENTS WHEN MINIMAL PERCENTAGE AVAILABLE
C ------------------------------------------------------
      IF (MEANUM(5).GT.0) THEN
        RATCOD=(100.D0*MEANUM(3))/MEANUM(5)
      ELSE
        RATCOD=100.D0
      ENDIF

      IF (RATCOD.GT.80.D0) THEN
        CODTYP='P1'
        NCOD=MEANUM(3)
      ELSE
        CODTYP='C1'
        NCOD=MEANUM(5)

        DO I=1,NEPOCH
          DO K=1,NRSAT

c           Turn off this selection for satellites with individual
c           obstype selection
            geosFlag = .FALSE.
            isys = INT(NUMSAT(K)/100)
            iprn = NUMSAT(K)-isys*100
            IF (useGeos == 1) THEN
              DO igeos = 1, gObsDef%norec
                IF ((gObsDef%sat(igeos)%sysnum==isys)
     1            .AND.(gObsDef%sat(igeos)%satnum==iprn)) THEN
                  geosFlag = .TRUE.
                  EXIT
                ENDIF
              ENDDO
            ENDIF

            IF (.NOT. geosFlag) THEN
              OBSREC(I,3,K)=obsaux(I,1,K)
            ENDIF
          ENDDO
        ENDDO

        IF (MEANUM(3).GT.0) THEN
          WRITE(LFNERR,911) MEANUM(3),
     1                      TRIM(PRTFLNAM(FILNAM,32))
911       FORMAT(/,' ### SR getRnx: ',
     1          'SPORADIC P1 MEASUREMENTS IGNORED',/,
     2      16X,'NUMBER OF MEASUREMENTS : ',I8,/,
     3      16X,'RINEX FILE             : ',A,/)
        ENDIF
      ENDIF

C USE C2 IF P2 UNAVAILABLE
C ------------------------
      IF (MEANUM(6).GT.0 .AND. IC2USE.EQ.1) THEN
        NAUX=0
        DO I=1,NEPOCH
          DO K=1,NRSAT
            IF (OBSREC(I,4,K).EQ.0.D0 .AND. obsaux(I,2,K).NE.0.D0) THEN
              OBSREC(I,4,K)=obsaux(I,2,K)
              NAUX=NAUX+1
CC              MEANUM(4)=MEANUM(4)+1
            ENDIF
          ENDDO
        ENDDO

        IF (NAUX.GT.0) THEN
          WRITE(LFNERR,912) NAUX,TRIM(PRTFLNAM(FILNAM,32))
912       FORMAT(/,' ### SR getRnx: ',
     1          'C2 MEASUREMENTS SUBSTITUTED FOR P2 MEASUREMENTS',/,
     2      16X,'NUMBER OF MEASUREMENTS : ',I8,/,
     3      16X,'RINEX FILE             : ',A,/)
        ENDIF
      ENDIF

      NMEA=MAXVAL(MEANUM(1:6))
      DO I=5,1,-1
        IF (MEANUM(I).EQ.NMEA) AUXTYP=MEATYP(I)
      ENDDO

      IF (NMEA.GT.0) THEN

C CHECK WHETHER INDICATED P1 OR C1 MEASUREMENTS AVAILABLE
C -------------------------------------------------------
        called = .FALSE.
        IF (useGeos == 1 .AND. gObsDef%norec >0) THEN
          called = .TRUE.
          DO I = 1,4
            DO K = 1,4
              IF (MEATYP(I).EQ.obslistbasic(K) .AND.MEANUM(I).EQ.0) THEN
                WRITE(LFNERR,921) MEATYP(I),TRIM(PRTFLNAM(FILNAM,32))
              ENDIF
            ENDDO
          ENDDO
        ENDIF

        IF (.NOT. called) THEN
          NOBSTP = NOBSTPHLP
CC        DO I=1,6
          DO I=1,5
           DO K=1,NOBSTP
            IF (MEATYP(I).EQ.OBSTYP(K) .AND. MEANUM(I).EQ.0) THEN
              WRITE(LFNERR,921) MEATYP(I),TRIM(PRTFLNAM(FILNAM,32))
921           FORMAT(/,' ### SR getRnx: ',
     1              'INDICATED ',A2,' MEASUREMENTS NOT AVAILABLE',/,
     2          16X,'RINEX FILE: ',A,/)
            ENDIF
           ENDDO
          ENDDO
        ENDIF

C COMPARE TOTAL NUMBER OF MEASUREMENTS
C ------------------------------------
        DO I=1,5
          IF (NMEA <= 0) THEN
            RATMEA=1d-3
          ELSE
            RATMEA=(100.D0*MEANUM(I))/NMEA
          ENDIF
          IF (RATMEA.GT.0.D0 .AND. RATMEA.LT.70.D0) THEN
            WRITE(LFNERR,922) MEATYP(I),AUXTYP,RATMEA,
     1                        TRIM(PRTFLNAM(FILNAM,32))
922         FORMAT(/,' ### SR getRnx: ',
     1            'LOW PERCENTAGE OF ',A2,' MEASUREMENTS',/,
     2        16X,'PERCENTAGE (WRT ',A2,') : ',F5.1,/,
     3        16X,'RINEX FILE          : ',A,/)
          ENDIF

          IF (MEANUM(1)+NAMNUM(1) <= 0) THEN
            RATNAM = 30.1d0
          ELSE
            RATNAM=(100.D0*NAMNUM(1))/(MEANUM(1)+NAMNUM(1))
          ENDIF
          IF (RATNAM.LT.100.D0 .AND. RATNAM.GT.30.D0) THEN
            WRITE(LFNERR,923) MEATYP(I),RATNAM,
     1                        TRIM(PRTFLNAM(FILNAM,32))
923         FORMAT(/,' ### SR getRnx: ',
     1            'MANY MISSING ',A2,' MEASUREMENTS',/,
     2        16X,'PERCENTAGE : ',F5.1,/,
     3        16X,'RINEX FILE : ',A,/)
          ENDIF
        ENDDO

C CHECK WHETHER L1, L2, P1/C1, P2 MEASUREMENTS AVAILABLE
C ------------------------------------------------------
        IF (MEANUM(1).EQ.0 .OR.
     1      MEANUM(2).EQ.0 .OR.
     2      NCOD     .EQ.0 .OR.
     3      MEANUM(4).EQ.0) THEN
          WRITE(LFNERR,931) TRIM(PRTFLNAM(FILNAM,32))
931       FORMAT(/,' ### SR getRnx: ',
     1          'REQUIRED MEASUREMENTS NOT AVAILABLE',/,
     2      16X,'RINEX FILE: ',A,/)
        ENDIF
      ELSE
        WRITE(LFNERR,932) TRIM(PRTFLNAM(FILNAM,32))
932     FORMAT(/,' ### SR getRnx: ',
     1        'NO VALID MEASUREMENTS',/,
     2    16X,'RINEX FILE: ',A,/)
      ENDIF

C DEBUG: exit
      IF (srfDebug) CALL cpu_exit(srName)

      RETURN
      END SUBROUTINE getRnx

      END MODULE s_getRnx
