SUBROUTINE MWAVE_GET_TL(KMWAVE_BUF,PMWAVE_ZEN_BUF,PMWAVE_AZI_BUF, &
  &  PMWAVE_P19_BUF, PMWAVE_P37_BUF, PMWAVE_OERR_BUF,PMWAVE_PERS1_BUF)

!**** *MWAVE_GET_TL* - 4D-VAR RAIN ASSIMILATION 

!     P. Bauer, P. Lopez, D. Salmond   ECMWF    Aug 2006

!     PURPOSE.
!     -------
!     GET MDB_DATUM_TBFLAG FROM ODB TO GRID-POINT SPACE

!**   INTERFACE.
!**   ---------
!**   *CALL* * MWAVE_GET_TL()*  (FROM GP_MODEL_TL)

!        Explicit arguments :


!     AUTHOR: Deborah Salmond
!     DATE  : 01-08-2006

!     Modifications :
!     25-Apr-2008   Alan Geer    Multiple sensor extensions
!     09-Mar-2009   W. Bell      Add azimuth angle for windsat
!     10-Jun-2009   Alan Geer    Passive monitoring enabled; per-channel status
!     01-Nov-2009   Anne Fouilloux  Obs to grid point mapping now in ODB
!     16-Dec-2009   F. Karbou	 Allow surface emissivity handling
!     ------------------------------------------------------------------

USE PARKIND1  ,ONLY : JPIM     ,JPRB
USE YOMHOOK   ,ONLY : LHOOK,   DR_HOOK
USE YOMDB
USE YOMGEM    ,ONLY : NGPTOT
USE YOMECTAB  ,ONLY : NTSLOTNOS, NTSLOTNOE
USE YOMANCS  , ONLY : RMDI
USE PARMWAVE  ,ONLY : NMAX_CHAN, RMISSING_ANGLE, IMWAVE_P_OBS, &
  &  NMWAVE_P
USE YOMMWAVE  ,ONLY : N_SATSENS, MWAVE_ID, MWAVE_NO_OBS, MWAVE_PASSIVE, &
  &  MWAVE_CONTAMINATED, MWAVE_OK

IMPLICIT NONE

INTEGER(KIND=JPIM) ,INTENT(INOUT) :: KMWAVE_BUF     (NGPTOT,NMAX_CHAN,N_SATSENS)
REAL(KIND=JPRB)    ,INTENT(OUT)   :: PMWAVE_ZEN_BUF (NGPTOT,N_SATSENS)
REAL(KIND=JPRB)    ,INTENT(OUT)   :: PMWAVE_AZI_BUF (NGPTOT,N_SATSENS)
REAL(KIND=JPRB)    ,INTENT(OUT)   :: PMWAVE_P19_BUF (NGPTOT,NMWAVE_P,N_SATSENS)
REAL(KIND=JPRB)    ,INTENT(OUT)   :: PMWAVE_P37_BUF (NGPTOT,NMWAVE_P,N_SATSENS)
REAL(KIND=JPRB)    ,INTENT(OUT)   :: PMWAVE_OERR_BUF (NGPTOT,NMAX_CHAN,N_SATSENS)
REAL(KIND=JPRB)    ,INTENT(OUT)   :: PMWAVE_PERS1_BUF (NGPTOT,NMAX_CHAN,N_SATSENS)

INTEGER(KIND=JPIM) :: ILEN,ICH,JOBS,ICHAN 
INTEGER(KIND=JPIM) :: JBODY, INFO(2), IRET, IBODY, JROF, ISAT
INTEGER(KIND=JPIM) :: INSTA, IDSTA(4)
INTEGER(KIND=JPIM) :: ICMBDY
REAL(KIND=JPRB) :: ZHOOK_HANDLE, ZINFO(0)

INTERFACE
#include "getdb.h"
#include "putdb.h"
END INTERFACE

#include "ngedsta.intfb.h"
#include "openmp_obs.h"

IF (LHOOK) CALL DR_HOOK('MWAVE_GET_TL',0,ZHOOK_HANDLE)

INFO(1)=NTSLOTNOS
INFO(2)=NTSLOTNOE

CALL GETDB('MWAVE_GET_SSMI',0, ILEN, INFO, 2, ZINFO, 0, &
 & -1, -1, -1, -1, -1, -1)

PMWAVE_OERR_BUF(:,:,:) = RMDI
PMWAVE_PERS1_BUF(:,:,:) = RMDI
PMWAVE_P19_BUF(:,:,:) = RMDI
PMWAVE_P37_BUF(:,:,:) = RMDI
PMWAVE_ZEN_BUF(:,:) = RMDI
PMWAVE_AZI_BUF(:,:) = RMDI
KMWAVE_BUF(:,:,:) = IBSET(0, MWAVE_NO_OBS)

DO JOBS=1,ILEN

  ! Find satellite index in our local table
  DO ISAT=1,N_SATSENS
    IF(ROBHDR(JOBS,MDB_SATID_AT_SAT) == MWAVE_ID(ISAT) % BUFR_ID ) EXIT
  ENDDO

  ! Grid point index
  JROF = ROBHDR(JOBS,MDB_GP_NUMBER)

  ! Sateliite zenith and azimuth angles. Take maximum in the case of more than one
  ! obs per grid point
  PMWAVE_ZEN_BUF(JROF,ISAT) = MAX( PMWAVE_ZEN_BUF(JROF,ISAT), ROBHDR(JOBS,MDB_ZENITH_AT_SAT))
  IF (PMWAVE_ZEN_BUF(JROF,ISAT) < 0.0_JPRB) PMWAVE_ZEN_BUF(JROF,ISAT) = RMISSING_ANGLE
  PMWAVE_AZI_BUF(JROF,ISAT) = MAX( PMWAVE_AZI_BUF(JROF,ISAT), ROBHDR(JOBS,MDB_AZIMUTH_AT_SAT))
  IF (PMWAVE_AZI_BUF(JROF,ISAT) < 0.0_JPRB) PMWAVE_AZI_BUF(JROF,ISAT) = RMISSING_ANGLE

  ! Observed polarisation differences (computed in screening trajectory)
  PMWAVE_P19_BUF(JROF,IMWAVE_P_OBS,ISAT) = ROBHDR (JOBS,MDB_OB_P19)  
  PMWAVE_P37_BUF(JROF,IMWAVE_P_OBS,ISAT) = ROBHDR (JOBS,MDB_OB_P37)   

  ICMBDY=MLNKH2B(JOBS+1)-MLNKH2B(JOBS)
  DO JBODY=1,ICMBDY

    IBODY=MLNKH2B(JOBS)+(JBODY-1)
    ICHAN=ROBODY(IBODY,MDBPPP)

    DO ICH=1,NMAX_CHAN
      IF(ICHAN == ICH)THEN

        ! Observation error - take maximum in the case of more than one obs per grid point
        PMWAVE_OERR_BUF(JROF,ICH,ISAT) = &
          & MAX( PMWAVE_OERR_BUF(JROF,ICH,ISAT), ROBODY(IBODY,MDBFOE))

        ! Surface emissivity
        PMWAVE_PERS1_BUF(JROF,ICH,ISAT) = &
          & MAX( PMWAVE_PERS1_BUF(JROF,ICH,ISAT), ROBODY(IBODY,MDB_MWEMIS_SAT2))

        ! Status flag
        IF ( BTEST(KMWAVE_BUF(JROF,ICH,ISAT) , MWAVE_NO_OBS) ) THEN

          ! This is the first observation associated with this grid point
          KMWAVE_BUF(JROF,ICH,ISAT) = ROBODY(IBODY,MDB_DATUM_TBFLAG)

        ELSE

          ! There is more than one obs for this grid point
          
          ! Rejected observations will be "contaminating" unrejected ones, so
          ! flag this if it happens.
          IF (   (.NOT. MWAVE_OK( KMWAVE_BUF(JROF,ICH,ISAT))) &
           & .OR.(.NOT. MWAVE_OK( INT(ROBODY(IBODY,MDB_DATUM_TBFLAG))))  )  THEN   
            KMWAVE_BUF(JROF,ICH,ISAT) = IBSET( KMWAVE_BUF(JROF,ICH,ISAT), MWAVE_CONTAMINATED )
          ENDIF

          ! Merge together the status flags.
          KMWAVE_BUF(JROF,ICH,ISAT) = IOR( KMWAVE_BUF(JROF,ICH,ISAT), INT(ROBODY(IBODY,MDB_DATUM_TBFLAG)) )

        ENDIF
  
        ! Check for passive monitoring data and flag (we will do this multiple
        ! times but that will not matter)
        CALL NGEDSTA(INT(ROBODY(IBODY,MDBDSTA)),INSTA,IDSTA)     
        IF (IDSTA(2) == 1) KMWAVE_BUF(JROF,ICH,ISAT) = &
          &     IBSET( KMWAVE_BUF(JROF,ICH,ISAT), MWAVE_PASSIVE )  

        EXIT
      ENDIF
    ENDDO
  ENDDO
ENDDO

CALL PUTDB('MWAVE_GET_SSMI', 0, IRET, INFO, 0, ZINFO, 0)

IF (LHOOK) CALL DR_HOOK('MWAVE_GET_TL',1,ZHOOK_HANDLE)

END SUBROUTINE MWAVE_GET_TL
