SUBROUTINE ERS1IF &
 & (K_ISATID,PUWIPC,PAZI,PINC,PSIGM,PMIS,PKP,KNWIND,&
 & KFLAG,PURET,PVRET,PRES,PSKILL,PKPM,PWE,KCELL,&
 & LDNOSOL)  
!*****************************************************************************

!     PURPOSE:
!     COMPUTE THE 2 AMBIGOUS WINDS FROM THE ESA BUFR,
!     KEEP THE RESIDUAL AND DIRECTIONNAL SKILL ASSOCIATED,
!     CHECK THE ESA FLAG                  
!     AND CONCENTRATE INFORMATION TOGETHER WITH WIND ERROR.
!     ALSO PRE-CHECK DISTANCE TO THE CONE.

!     INPUT:  ISATID         SATELLITE IDENTIFIER ([ERS-] 1 OR 2) 
!             PUWIPC         ESA FLAG(12BIT)
!             PAZI(JPANT)    AZIMUTH ANGLE  (DEGRES) AS READ IN THE ESA BUFR
!             PINC(JPANT)    INCIDENCE ANGLE          "         "
!             PSIGM(JPANT)   SIGMA0 VALUES             "         "
!             PMIS(JPANT)    MISSING PACKET COUNTER
!             PKP(JPANT)     NOISE FOR THE 3 ANTENNAS

!    OUTPUT:  KFLAG         FLAG (10BIT)                             
!             PURET(KNWIND) 2 U SOLUTIONS
!             PVRET(KNWIND) 2 V SOLUTIONS                 
!             PRES(KNWIND)  2 INVERSION RESIDUAL (SQUARED NORMALISED DISTANCE)        
!             PSKILL        1 DIRECTIONAL SKILL  (NATURAL NORMALISED VALUE)        
!             PKPM(JPANT)   MODELLED NOISE FOR THE 3 ANTENNAE    
!             PWE           WIND ERROR IN U AND V (2 M/S)
!             KCELL         NODE NUMBER INSIDE THE SWATH ( 1 TO 19 )
!             LDNOSOL       NO SOLUTION SWITCH

!****************************************************************************** 

USE PARKIND1  ,ONLY : JPIM     ,JPRB
USE YOMHOOK   ,ONLY : LHOOK,   DR_HOOK

USE PARERSCA , ONLY : JPCELL   ,JPANT    ,JPSPL    ,JPSOLMAX ,JPSPEEDMAX
USE YOMERSCA , ONLY : A180     ,A270     ,A360     ,ARAD     ,&
 & SIGMAX   ,XKPMAX   ,XMISMAX  ,MBIT     ,VALTT    ,&
 & BIASBM   ,VALSPL   ,XSPL     ,RSCAMDI  ,MSCAMDI ,&
 & NKNOTSP7 ,RKNOTS   ,RSPLCOEFF,RSPLEND  ,ERS_SPEED_BIASCOR
USE YOMMKODB , ONLY : NBIASCOR
USE YOMLUN   , ONLY : NULOUT

IMPLICIT NONE

INTEGER(KIND=JPIM),INTENT(IN)    :: KNWIND 
INTEGER(KIND=JPIM),INTENT(IN)    :: K_ISATID 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PUWIPC 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PAZI(JPANT) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PINC(JPANT) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PSIGM(JPANT) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PMIS(JPANT) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PKP(JPANT) 
INTEGER(KIND=JPIM),INTENT(OUT)   :: KFLAG 
REAL(KIND=JPRB)   ,INTENT(OUT)   :: PURET(KNWIND) 
REAL(KIND=JPRB)   ,INTENT(OUT)   :: PVRET(KNWIND) 
REAL(KIND=JPRB)   ,INTENT(OUT)   :: PRES(KNWIND) 
REAL(KIND=JPRB)   ,INTENT(OUT)   :: PSKILL 
REAL(KIND=JPRB)   ,INTENT(OUT)   :: PKPM(JPANT) 
REAL(KIND=JPRB)   ,INTENT(OUT)   :: PWE 
INTEGER(KIND=JPIM),INTENT(INOUT) :: KCELL 
LOGICAL           ,INTENT(OUT)   :: LDNOSOL 
!     LOCAL VARIABLES
REAL(KIND=JPRB) ::        ZVS(JPSOLMAX), ZPHI(JPSOLMAX),ZDRES(JPSOLMAX)
REAL(KIND=JPRB) ::        ZBA(JPANT),ZSIGM(JPANT)
INTEGER(KIND=JPIM) ::     ICELL(JPANT)

INTEGER(KIND=JPIM) :: IAB, IABA, IFB, IFBA, IFC, IKPT, ILS, IMB,&
 & IMBA, IMIS, IPC, ISOL, ISOLMAX, J, JJ, JSPL,&
 & ISPEEDBIN  

REAL(KIND=JPRB) :: Z_DZV, ZPH, ZV0, ZVSNEW, ZVSOLD
REAL(KIND=JPRB) :: ZHOOK_HANDLE

#include "abor1.intfb.h"
#include "s0towind.intfb.h"
#include "speedcor_nag.intfb.h"

!***  1.INITIALIZE

IF (LHOOK) CALL DR_HOOK('ERS1IF',0,ZHOOK_HANDLE)
LDNOSOL = .FALSE.

DO J=1,KNWIND
  PURET(J)=RSCAMDI
  PVRET(J)=RSCAMDI
  PRES(J) =RSCAMDI
ENDDO
PSKILL=RSCAMDI
DO J=1,JPANT
  PKPM(J)=RSCAMDI
  ICELL(J)=MSCAMDI
ENDDO
!     PWE=RSCAMDI
PWE=2.0_JPRB
KFLAG=0 !A PRIORI OK

!**2.DEFINE THE CONDENSED FLAG

! MISSING AT THIS STAGE IS SST CONTROL FOR SEA ICE 

! THE 3 FIRST BITS INDICATE IF SIGMA0 1, 2, 3 ARE USABLE
! (NO MAJOR TECHNICAL PROBLEM)

! BIT 4 INDICATES IF THE DISTANCE TO THE CONE IS CORRECT 
! IT WILL POSSIBLY BE OVERWRITTEN 
! AFTER THE SST AND LAND/SEA MASK CHECKS 
! SINCE THAT DISTANCE IS SUPPOSED TO BE CORRECT ONLY OVER SEA

! BIT 5 WILL BE SET FROM THE FG CHECK

! THE AMBIGOUS WIND WILL BE USED ONLY IF THE WHOLE FLAG IS EQUAL TO 0 

!    2.1 DECODE THE ESA FLAG
IPC=INT(PUWIPC)
IFB =MOD(IPC     ,2)    !NO FOREBEAM CALCULATION
IMB =MOD(IPC/2   ,2)    !NO MIDBEEAM "        "
IAB =MOD(IPC/4   ,2)    !NO AFTBEAM  "        "
IFBA=MOD(IPC/8   ,2)    !FOREBEAM ARCING DETECTED
IMBA=MOD(IPC/16  ,2)    !MIDBEAM     "        "
IABA=MOD(IPC/32  ,2)    !AFT         "        "
IKPT=MOD(IPC/64  ,2)    !KP ABOVE A THRESOLD
ILS =MOD(IPC/128 ,2)    !LAND
IFC =MOD(IPC/1024,2)    !FRAME CHECKSUM ERROR DETECTED
IMIS=MOD(IPC/2048,2)    !MISSING VALUE

IF( IMIS > 0) THEN                    !NO FLAG PRESENCE
  DO  J=1,MBIT
    KFLAG=IBSET(KFLAG,J-1)                 !1BIT=1 NOFLAG
  ENDDO
ELSE
  IF(IFC+ILS+IKPT >= 1)THEN
    DO J=1,JPANT
      KFLAG=IBSET(KFLAG,J-1)
    ENDDO
  ELSE    ! check the data
    IF(IFB+IFBA >= 1.OR.&
     & PSIGM(1) == RSCAMDI.OR.PKP(1) == RSCAMDI.OR.&
     & PSIGM(1) > SIGMAX.OR.PKP(1) > XKPMAX.OR.&
     & ABS( PMIS(1) ) > XMISMAX .OR.&
     & PINC(1) == RSCAMDI .OR.&
     & PAZI(1) == RSCAMDI)             KFLAG=IBSET(KFLAG,0)  
    IF(IMB+IMBA >= 1.OR.&
     & PSIGM(2) == RSCAMDI.OR.PKP(2) == RSCAMDI.OR.&
     & PSIGM(2) > SIGMAX.OR.PKP(2) > XKPMAX.OR.&
     & ABS( PMIS(2) ) > XMISMAX .OR.&
     & PINC(2) == RSCAMDI .OR.&
     & PAZI(2) == RSCAMDI)             KFLAG=IBSET(KFLAG,1)  
    IF(IAB+IABA >= 1.OR.&
     & PSIGM(3) == RSCAMDI.OR.PKP(3) == RSCAMDI.OR.&
     & PSIGM(3) > SIGMAX.OR.PKP(3) > XKPMAX.OR.&
     & ABS( PMIS(3) ) > XMISMAX.OR.&
     & PINC(3) == RSCAMDI .OR.&
     & PAZI(3) == RSCAMDI)             KFLAG=IBSET(KFLAG,2)  
  ENDIF
ENDIF

!***FIND CELL NUMBER AND CHECK CONSISTENCY

DO J=1,JPANT
  DO JJ=1,JPCELL
    IF(PINC(J) /= RSCAMDI.AND.PINC(J) >= VALTT(J,JJ)&
     & .AND.PINC(J) < VALTT(J,JJ+1))ICELL(J)=JJ  
  ENDDO
ENDDO
IF(ICELL(1) /= ICELL(2).OR.ICELL(1) /= ICELL(3)&
   & .OR. ICELL(1) == MSCAMDI.OR.ICELL(2) == MSCAMDI &
   & .OR.ICELL(3) == MSCAMDI)THEN  
  KFLAG=IBSET(KFLAG,0)
  KFLAG=IBSET(KFLAG,1)
  KFLAG=IBSET(KFLAG,2)
  KCELL=MSCAMDI
  LDNOSOL=.TRUE.
  IF (LHOOK) CALL DR_HOOK('ERS1IF',1,ZHOOK_HANDLE)
  RETURN
ELSE
  KCELL=ICELL(2)
ENDIF

!***3. FIND AMBIGUOUS WINDS (ONLY IF KFLAG=0)

IF (KFLAG == 0) THEN
  DO J=1,JPANT
    ZBA(J)=MOD(PAZI(J)-PAZI(2),A360)
    ZSIGM(J)= 10._JPRB**(PSIGM(J)/10._JPRB)
  ENDDO

!   3.0 BEAM-DEPENDENT SIGMA0 BIAS CORRECTION

  DO J=1,JPANT
    ZSIGM(J)=ZSIGM(J)/BIASBM(J,KCELL,K_ISATID)
  ENDDO

!   3.1 INVERSION

  ISOLMAX=JPSOLMAX
  CALL S0TOWIND(ZSIGM,PINC,ZBA,ISOLMAX,ISOL,ZVS,ZPHI,ZDRES,PSKILL,PKPM)

  IF(ISOL == 0) THEN
! NO SOLUTION -> RESULTS ALREADY PUT TO MISSING (WIND EITHER TOO LOW OR TOO HIGH)
    LDNOSOL = .TRUE.
    IF (LHOOK) CALL DR_HOOK('ERS1IF',1,ZHOOK_HANDLE)
    RETURN
  ENDIF
  DO J=1,MIN(KNWIND,ISOL)

!   3.2 PUT DIRECTION IN METEOROLOGICAL CONVENTION

! BY HABIT WIND DIRECTION IS RELATIVE TO THE MID BEAM (ZBA=PAZI-PAZI(2))
! THE ANGLE USED TO COMPUTE THE TABLE IS THE ANGLE BETWEEN THE BACKSCATERRED VECTOR
! AND THE VECTOR WIND (NO METEOROLOGICAL CONVENTION)
! THE AZIMUTH ANGLE GIVEN BY ESA IS THE ANGLE OF THE BACKSCATERRED VECTOR RELATIVE
! TO THE NORTH, THE DIRECTION FROM WHERE THE ANTENNA BLOWS!!

    ZPHI(J)=MOD(PAZI(2)-ZPHI(J) +A180,A360)

!   3.3 APPLY SPEED BIAS CORRECTION
!       Version 0 no bias correction
!       Version 1 used up to CY21R3,  version 2 used from CY21R4
!       version 3 used in ERA40

    ZVSOLD=ZVS(J)
    IF     (NBIASCOR == 0) THEN
      CONTINUE
    ELSEIF (NBIASCOR == 1) THEN
      ZV0=XSPL(1,KCELL,K_ISATID)
      IF (ZVSOLD > ZV0) THEN
        ZVSNEW=XSPL(2,KCELL,K_ISATID)&
         & +ZVSOLD*(XSPL(3,KCELL,K_ISATID)&
         & +ZVSOLD*(XSPL(4,KCELL,K_ISATID)&
         & +ZVSOLD*XSPL(5,KCELL,K_ISATID)))  
        JSPL=1
        999    CONTINUE
        IF (ZVSOLD > VALSPL(JSPL)) THEN
          Z_DZV=ZVSOLD-VALSPL(JSPL)
          ZVSNEW=ZVSNEW+Z_DZV*Z_DZV*XSPL(5+JSPL,KCELL,K_ISATID)
          IF (JSPL < JPSPL) THEN
            JSPL=JSPL+1
            GOTO 999
          ENDIF
        ENDIF
      ELSE
        ZVSNEW=0.0_JPRB
      ENDIF
      ZVS(J)=ZVSNEW
    ELSEIF (NBIASCOR == 2) THEN
      CALL SPEEDCOR_NAG(NKNOTSP7,RKNOTS(1:NKNOTSP7,KCELL,K_ISATID), &
       & RSPLCOEFF(1:NKNOTSP7,KCELL,K_ISATID),&
       & RSPLEND(KCELL,K_ISATID),ZVSOLD,ZVS(J))  
    ELSEIF (NBIASCOR == 3) THEN
      ISPEEDBIN=NINT(ZVS(J)-0.25)
      IF (ISPEEDBIN >= 0 .AND. ISPEEDBIN <= JPSPEEDMAX) THEN
        ZVS(J)=ZVS(J)+ERS_SPEED_BIASCOR(ISPEEDBIN,KCELL,K_ISATID)
      ENDIF
    ELSE
      WRITE(NULOUT,'(''0NBIASCOR INCORRECT VALUE IN ERS1IF'')')
      WRITE(NULOUT,'('' NBIASCOR IS '',I5)') NBIASCOR
      CALL ABOR1('SUBROUTINE ERS1IF')
    ENDIF

!   3.4 COMPUTE U AND V

    ZPH = (A270 - ZPHI(J))*ARAD
    PURET(J) = ZVS(J)*COS(ZPH)
    PVRET(J) = ZVS(J)*SIN(ZPH)
    PRES(J)  = ZDRES(J)
  ENDDO
ENDIF

! CONTROL THE DISTANCE TO THE CONE

IF(PRES(1) > 9._JPRB) KFLAG=IBSET(KFLAG,3)
IF(PRES(1) >= 409.5_JPRB) PRES(1)=409.5_JPRB
IF(PRES(2) >= 409.5_JPRB) PRES(2)=409.5_JPRB
IF(PSKILL >= 409.5_JPRB) PSKILL=409.5_JPRB

IF (LHOOK) CALL DR_HOOK('ERS1IF',1,ZHOOK_HANDLE)
END SUBROUTINE ERS1IF
