!-------------------------------------- LICENCE BEGIN ------------------------------------
!Environment Canada - Atmospheric Science and Technology License/Disclaimer,
!                     version 3; Last Modified: May 7, 2008.
!This is free but copyrighted software; you can use/redistribute/modify it under the terms
!of the Environment Canada - Atmospheric Science and Technology License/Disclaimer
!version 3 or (at your option) any later version that should be found at:
!http://collaboration.cmc.ec.gc.ca/science/rpn.comm/license.html
!
!This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
!without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
!See the above mentioned License/Disclaimer for more details.
!You should have received a copy of the License/Disclaimer along with this software;
!if not, you can write to: EC-RPN COMM Group, 2121 TransCanada, suite 500, Dorval (Quebec),
!CANADA, H9P 1J3; or send e-mail to service.rpn@ec.gc.ca
!-------------------------------------- LICENCE END --------------------------------------
!

      SUBROUTINE FILTERGPSRO(lcolumnhr,lobsSpaceData) 1,27
#if defined (DOC)
*
***s/r FILTERGPSRO - Filter GPSRO observations
*                    Guarantee that altitude and observation values are
*                    within bounds for further processing
*
*                    For noncompliant GPSRO observations:
*                    -Set assimilable flag to 0
*                    -Set bit of cma flag 11 ON
*
*Author  : J. M. Aparicio Jan 2008
*          Adapted Nov 2012 for both refractivity and bending angle data
*    -------------------
*
*Arguments
*
#endif
      use EarthConstants_mod
      use MathPhysConstants_mod
      use obsSpaceData_mod
      use columnData_mod
      use modgpsro_mod
      IMPLICIT NONE
C
      type(struct_columnData) :: lcolumnhr
      type(struct_obs)        :: lobsSpaceData
C
      INTEGER INDEX_HEADER, IDATYP, INDEX_BODY
      INTEGER JL, IAZM, ISAT, ICLF, iProfile, NH, I
      REAL*8 ZMT, Rad, Geo, zLat, zLon, Lat, Lon
      REAL*8 HNH1, HSF, HTP, HGP, HMIN, HMAX, ZOBS, ZREF
      LOGICAL LLEV, LOBS, LNOM, LSAT
C
      WRITE(*,*)'ENTER FILTERGPSRO'
C
C     Loop over all header indices of the 'RO' family:
C
      call obs_set_current_header_list(lobsSpaceData,'RO')
      numGPSROProfiles=0
      HEADER: do
         index_header = obs_getHeaderIndex(lobsSpaceData)
         if (index_header < 0) exit HEADER
C
C     *  Process only refractivity data (codtyp 169)
C
         IDATYP = obs_headElem_i(lobsSpaceData,OBS_ITY,INDEX_HEADER)
         IF ( IDATYP .EQ. 169 ) THEN
            numGPSROProfiles=numGPSROProfiles+1
C
C     *     Basic geometric variables of the profile:
C
            IAZM = obs_headElem_i(lobsSpaceData,OBS_AZA,INDEX_HEADER)
            ISAT = obs_headElem_i(lobsSpaceData,OBS_SAT,INDEX_HEADER)
            ICLF = obs_headElem_i(lobsSpaceData,OBS_ROQF,INDEX_HEADER)
            Rad  = obs_headElem_r(lobsSpaceData,OBS_TRAD,INDEX_HEADER)
            Geo  = obs_headElem_r(lobsSpaceData,OBS_GEOI,INDEX_HEADER)
            LNOM = .NOT.BTEST(ICLF,16-1)
C
C     *     Check if the satellite is within the accepted set:
C
            IF ( NUMGPSSATS .GE. 1 ) THEN
              LSAT = .FALSE.
              DO I=1,NUMGPSSATS
                 LSAT=( LSAT .OR. (ISAT.EQ.IGPSSAT(I)) )
              ENDDO
            ELSE
              LSAT = .TRUE.
            ENDIF
C
            JL  = col_getNumLev(LCOLUMNHR,'TH')
            ZMT = col_getHeight(lcolumnhr,JL,INDEX_HEADER,'TH')/RG
C
C     *     Acceptable height limits:
C
            JL = 1
            HTP = col_getHeight(lcolumnhr,JL,INDEX_HEADER,'TH')/RG
            HSF = ZMT+SURFMIN
C
C     *     Discard low data for METOP/GRAS:
C
            IF ( NUMGPSSATS .GE. 1 ) THEN
               IF ( ISAT.EQ.3 .OR. ISAT.EQ.4 .OR. ISAT.EQ.5 ) THEN
                 IF (HSF .LT. 10000.d0) HSF=10000.d0
               ENDIF
            ENDIF
C
C     *     Min/max altitudes:
C
            IF (HSF .LT. HSFMIN) HSF=HSFMIN
            IF (HTP .GT. HTPMAX) HTP=HTPMAX
            HMIN=Geo+HSF
            HMAX=Geo+HTP
C
C     *     Loop over all body indices for this index_header:
C     *     (start at the beginning of the list)
C
            call obs_set_current_body_list(lobsSpaceData, INDEX_HEADER)
            BODY: do 
               index_body = obs_getBodyIndex(lobsSpaceData)
               if (index_body < 0) exit BODY
C
C     *        Altitude:
C
               HNH1= obs_bodyElem_r(lobsSpaceData,OBS_PPP,INDEX_BODY)
               IF (LEVELGPSRO.EQ.1) HNH1=HNH1-Rad
C
C     *        Observation:
C
               ZOBS= obs_bodyElem_r(lobsSpaceData,OBS_VAR,INDEX_BODY)
C
C     *        Reference order of magnitude value:
C
               IF (LEVELGPSRO.EQ.1) THEN
                  ZREF = 0.025d0*exp(-HNH1/6500.d0)
               ELSE
                  ZREF = 300.d0*exp(-HNH1/6500.d0)
               ENDIF
C
C     *        Positively verify that the altitude is within bounds:
C
               LLEV= (HNH1.GT.HMIN) .AND. (HNH1.LT.HMAX)
C
C     *        Positively verify that the observable is within bounds:
C
               LOBS= (ZOBS.GT.(0.3d0*ZREF)) .AND. (ZOBS.LT.(3.d0*ZREF))
C
C     *        Mark as not assimilable unless all conditions are satisfied:
C
               IF ( .NOT.LLEV .OR. .NOT.LOBS .OR. IAZM.LT.0 .OR. .NOT.LNOM .OR. .NOT.LSAT) THEN
                  call obs_bodySet_i(lobsSpaceData,OBS_ASS,INDEX_BODY, 0)
                  call obs_bodySet_i(lobsSpaceData,OBS_FLG,INDEX_BODY, IBSET(obs_bodyElem_i(lobsSpaceData,OBS_FLG,INDEX_BODY),11))
               ENDIF
            ENDDO BODY

         ENDIF

      ENDDO HEADER

      IF (numGPSROProfiles.GT.0) THEN
         if(.not.allocated(vGPSRO_IndexPrf)) allocate(vGPSRO_IndexPrf(numGPSROProfiles))

         iProfile=0
C
C     *  Loop over all header indices of the 'RO' family:
C
         call obs_set_current_header_list(lobsSpaceData,'RO')
         HEADER2: do
            index_header = obs_getHeaderIndex(lobsSpaceData)
            if (index_header < 0) exit HEADER2
C     
C     *  Process only refractivity data (codtyp 169)
C
            IDATYP = obs_headElem_i(lobsSpaceData,OBS_ITY,INDEX_HEADER)
            IF ( IDATYP .EQ. 169 ) THEN
               iProfile=iProfile+1
               vGPSRO_IndexPrf(iProfile)=INDEX_HEADER
               zLat = obs_headElem_r(lobsSpaceData,OBS_LAT,INDEX_HEADER)
               zLon = obs_headElem_r(lobsSpaceData,OBS_LON,INDEX_HEADER)
               Lat  = zLat * MPC_DEGREES_PER_RADIAN_R8
               Lon  = zLon * MPC_DEGREES_PER_RADIAN_R8
            ENDIF
         ENDDO HEADER2

      ENDIF

      WRITE(*,*)'EXIT FILTERGPSRO'
      RETURN
      END SUBROUTINE FILTERGPSRO