SUBROUTINE FIXERR(POERR,KAREA,KSQOBTYP,KSQCDTYP,PRES1,PERROR)

!**** SUBROUTINE FIXERR - OBSERVATION ERROR EVALUATION

!        D. VASILJEVIC    ECMWF    17/10/1994

!     PURPOSE
!     -------

!        EVALUATE OBSERVATION ERROR

!**   INTERFACE
!     ---------

!        CALL FIXERR(POERR,KAREA,KSQOBTYP,KSQCDTYP,
!                    PRES1,PERROR)

!     WHERE:
!           POERR    = INPUT ARRAY OF OBSERVATION ERRORS
!           KAREA    = AREA
!           KSQOBTYP = OBS. TYPE SQ. NO.
!           KSQCDTYP = CODE TYPE SQ. NO.
!           PRES1    = PRESSURE (VERTICAL REF. 1) TO BE INTERPOL. TO
!           PERROR   = OUTPUT INTERPOLATED OBSERVATION ERROR

!        FIXERR IS CALLED BY SUBROUTINE OBSERR

!     METHOD
!     ------

!        FOR GIVEN PRESSURE OBS. ERROR IS EVALUATED AT THAT PRESS. BY
!     THE LINEAR INTERPOLATION IN LNP.

!     HISTORY
!     -------

!-----------------------------------------------------------------------

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

USE YOMCMA   , ONLY : NMXOTP   ,NMXOCT
USE YOMANCS  , ONLY : RMDI     ,EPSMAC
USE YOMOERR  , ONLY : NMXESTLV ,NMXEAREA
USE YOMLVLY  , ONLY : STPRELV  ,STPRELVL
IMPLICIT NONE

!     EXTERNAL INTEGER FUNCTIONS
REAL(KIND=JPRB)   ,INTENT(IN)    :: POERR(NMXESTLV,NMXEAREA,NMXOCT,NMXOTP) 
INTEGER(KIND=JPIM),INTENT(IN)    :: KAREA 
INTEGER(KIND=JPIM),INTENT(IN)    :: KSQOBTYP 
INTEGER(KIND=JPIM),INTENT(IN)    :: KSQCDTYP 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PRES1 
REAL(KIND=JPRB)   ,INTENT(OUT)   :: PERROR 
INTEGER(KIND=JPIM), EXTERNAL :: ISRCHFLE

INTEGER(KIND=JPIM) :: IA, IC, ILEVU, IO

REAL(KIND=JPRB) :: ZLNLEV
REAL(KIND=JPRB) :: ZHOOK_HANDLE

!*
!-----------------------------------------------------------------------

!        1.       CALCULATE OBSERVATION ERROR
!                 ---------------------------

!*          1.0   ARRAY ADDRESSES

IF (LHOOK) CALL DR_HOOK('FIXERR',0,ZHOOK_HANDLE)
IA    = KAREA
IC    = KSQCDTYP
IO    = KSQOBTYP

!*          1.1   KEEP OBSERVATION ERROR CONSTANT BELOW LOWEST LEVEL

IF(PRES1 >= STPRELV(1)) THEN
  PERROR=POERR(1,IA,IC,IO)

!*          1.2   KEEP OBSERVATION ERROR CONSTANT ABOVE HIGHEST ANALYSIS
!                 LEVEL
ELSEIF (PRES1 <= STPRELV(NMXESTLV)) THEN
  PERROR=POERR(NMXESTLV,IA,IC,IO)

!*          1.3   FIND NEAREST LEVEL ABOVE OBSERVATION

ELSE
  ZLNLEV=LOG(PRES1)
  ILEVU=ISRCHFLE(NMXESTLV,STPRELVL,1,ZLNLEV)
  IF(ABS(ZLNLEV-STPRELVL(ILEVU)) < EPSMAC) THEN
    PERROR=POERR(ILEVU,IA,IC,IO)

!*          1.4   INTERPOLATE ERROR LINEARLY IN VERTICAL WITH RESPECT TO
!                 LN(P)
  ELSE
    IF(POERR(ILEVU-1,IA,IC,IO) == RMDI.OR.&
       & POERR(ILEVU  ,IA,IC,IO) == RMDI    )       THEN  
      PERROR = RMDI
    ELSE
      PERROR=POERR(ILEVU-1,IA,IC,IO)+&
       & (POERR(ILEVU,IA,IC,IO)-POERR(ILEVU-1,IA,IC,IO))/&
       & (STPRELVL(ILEVU)-STPRELVL(ILEVU-1))*&
       & (ZLNLEV-STPRELVL(ILEVU-1))  
    ENDIF
  ENDIF
ENDIF
!*
!-----------------------------------------------------------------------

!        2.       RETURN
!                 ------

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