SUBROUTINE SYMTRANSIN(PST5,PGFLT5,PSPS5,PST7,PGFLT7,PSPS7)

!     SYMTRANSIN - Nonlinear inverse transform from the control
!                  variable to the analysis increments using
!                  a "symmetrizing transform". 
!                  Only for humidity and ozone so far.

!     Purpose:     Inclusion of nonlinear effects (asymmetry) in
!     --------     the background error statistics.

!     Arguments :
!     -----------
!     Input: 
!       PST5       Trajectory first guess temperature
!       PGFLT5     Trajectory first guess gridpoint fields
!       PSPS5      Trajectory first guess surface pressure
!       PST7       Background temperature
!       PGFLT7     Background gridpoint fields
!       PSPS7      Background surface pressure

!     Method:      The symmetrizing control variable transform
!     -------      normalizes the control variable dx with 
!                  a state-dependent standard deviation which 
!                  depends on the average of analysis and background

!                    dx_n = dx/sigma_bg{[f(x_an)+f(x_bg)]/2}

!                  For relative humidity this reduces to

!                    dRH_n = dRH/sigma_bg(RH_bg/2+RH_fg/2+dRH/2)

!                  This formulation maps asymmetric background errors
!                  to symmetric ones. The inverse transform solved here
!                  updates the initial estimate of dRH from the linear
!                  inner loops in the outer loop by solving

!                    dRH_n - dRH/sigma_bg(RH_bg/2+RH_fg/2+dRH/2) = 0

!                  One iteration of the secant method is performed,
!                  which gives enough accuracy.

!     Externals:   PREGPRH -  modified relative humidity, q > 0, 
!     ----------              full level pressure and tropopause height
!                  SPEREE   - spectral to grid-point transform

!     Reference.
!     ----------
!        E. Holm et al., 2002: "Assimilation and Modelling of the
!        Hydrological Cycle: ECMWF's Status and Plans." Chapter 6.
!        ECMWF Technical Memorandum 383.

!     Author.
!     -------
!        Elias Holm, using parts of SUGPLIMDM.

!     Modifications.
!     --------------
!        Original  : 03-04-15.
!        M.Hamrud  : 03-08-01  GFL introduction
!        M.Hamrud      01-Oct-2003 CY28 Cleaning
!        Elias Holm: 04-01-23 Added ozone
!        Elias Holm: 04-12-21 Change between RH (trop) and q(strat)
!                             vertical geometry independent 
!        Elias Holm: 05-04-04 Spindown reduction via capping of positive
!                             RH increments for RH_b>0.8 and CAPE>125,
!                             CAPE calucaleted in CUANCAPE.
!        Elias Holm: 06-07-11 Tropopause level calculation moved to
!                             TROPLEV and tropopause transition simplified
!                             with function FQT.
!        Elias Holm: 08-11-12 Move pressure and tropopause calculation into
!                             PREGPRH. Added background and modified inversion.
!                             Remove CUANCAPE. Simplify inversion.
!     ------------------------------------------------------------------

USE PARKIND1  ,ONLY : JPIM     ,JPRB
USE YOMHOOK   ,ONLY : LHOOK,   DR_HOOK
USE YOMDIM   , ONLY :     NFLEVL   ,NFLEVG   ,&
 & NPROMA   ,NSPEC2  ,NGPBLKS  
USE YOMSP    , ONLY : SPT      ,SPSP
USE YOMCST   , ONLY : RV       ,RCPV     ,RETV     ,RCW      ,&
 & RCS      ,RLVTT    ,RLSTT    ,RTT      ,RALPW    ,&
 & RBETW    ,RGAMW    ,RALPS    ,RBETS    ,RGAMS    ,&
 & RALPD    ,RBETD    ,RGAMD
USE YOETHF   , ONLY : R2ES     ,R3LES    ,R3IES    ,R4LES    ,&
 & R4IES    ,R5LES    ,R5IES    ,R5ALVCP  ,R5ALSCP  ,&
 & RTWAT_RTICE_R      ,RTWAT_RTICECU_R,&
 & RALVDCP  ,RALSDCP  ,RTWAT    ,RTICE    ,RTICECU  
USE YOMGEM   , ONLY : NGPTOT
USE YOMMP    , ONLY : NBSETLEV
USE YOMGFL   , ONLY : GFL
USE YOM_YGFL , ONLY : YGFL     ,YQ       ,YO3
USE YOMJBCHVAR , ONLY : RQS, RQT, RQTBAL, RQLMIN, RQLMAX,&
 & RQLSTD, RQHMIN, RQHMAX, RQHSTD, RO3MIN, RO3STD
USE YOMJG    , ONLY : LJB_NONLINEAR_CVHUM, LJB_NONLINEAR_CVO3

IMPLICIT NONE

REAL(KIND=JPRB)   ,INTENT(IN)    :: PST5(NFLEVL,NSPEC2), PSPS5(NSPEC2) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PST7(NFLEVL,NSPEC2), PSPS7(NSPEC2) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PGFLT5(NPROMA,NFLEVG,YGFL%NDIM0,NGPBLKS) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PGFLT7(NPROMA,NFLEVG,YGFL%NDIM0,NGPBLKS) 
REAL(KIND=JPRB) :: ZTT0(NPROMA,NFLEVG,NGPBLKS), ZPS0(NPROMA,NGPBLKS)
! REAL(KIND=JPRB) :: ZTT5(NPROMA,NFLEVG,NGPBLKS), ZPS5(NPROMA,NGPBLKS)
! REAL(KIND=JPRB) :: ZTTM(NPROMA,NFLEVG,NGPBLKS), ZPSM(NPROMA,NGPBLKS)
REAL(KIND=JPRB) :: ZPRSH0(NPROMA,0:NFLEVG), ZPRSF0(NPROMA,NFLEVG)
! REAL(KIND=JPRB) :: ZPRSH5(NPROMA,0:NFLEVG), ZPRSF5(NPROMA,NFLEVG)
REAL(KIND=JPRB) :: ZPRSHM(NPROMA,0:NFLEVG), ZPRSFM(NPROMA,NFLEVG)
REAL(KIND=JPRB) :: ZES0(NPROMA,NFLEVG),ZRH0(NPROMA,NFLEVG),ZQP0(NPROMA,NFLEVG)
! REAL(KIND=JPRB) :: ZES5(NPROMA,NFLEVG),ZRH5(NPROMA,NFLEVG),ZQP5(NPROMA,NFLEVG)
! REAL(KIND=JPRB) :: ZQPM(NPROMA,NFLEVG)
! REAL(KIND=JPRB) :: ZESM(NPROMA,NFLEVG),ZRHM(NPROMA,NFLEVG),ZQM(NPROMA,NFLEVG)
REAL(KIND=JPRB) :: ZRHMAX,ZRHMIN,ZDQMIN,ZDQMAX,ZDQ,ZQS

INTEGER(KIND=JPIM) :: IBL, ICEND, JKGLO, JROF, JLEV
INTEGER(KIND=JPIM) :: ILTROP0(NPROMA)
! INTEGER(KIND=JPIM) :: ILTROPM(NPROMA), ILTROP5(NPROMA)
REAL(KIND=JPRB) :: ZHOOK_HANDLE

#include "fcttrm.h"
#include "fcttre.h"
#include "fjbchvar.h"

INTERFACE
#include "inv_trans.h"
END INTERFACE

#include "pregprh.intfb.h"
#include "speree.intfb.h"


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

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

!*       1.  CONVERT T AND PS TO GRIDPOINT SPACE.
!            ------------------------------------
!     SPECRTSM/DM is normally not called because LSPRT is set false
!     locally inside RDFPINC. Note, SPECRT is not exactly invertible.

!*       1.1   ANALYSIS

CALL INV_TRANS(PSPSCALAR=SPT,KVSETSC=NBSETLEV,KPROMA=NPROMA,PGP=ZTT0)
CALL SPEREE(1,1,SPSP,ZPS0)

! EH: below not needed in present cycle, but leave for next cycle updates
!*       1.2   TRAJECTORY

!CALL INV_TRANS(PSPSCALAR=PST5,KVSETSC=NBSETLEV,KPROMA=NPROMA,PGP=ZTT5)
!CALL SPEREE(1,1,PSPS5,ZPS5)

!*       1.3   BACKGROUND

!CALL INV_TRANS(PSPSCALAR=PST7,KVSETSC=NBSETLEV,KPROMA=NPROMA,PGP=ZTTM)
!CALL SPEREE(1,1,PSPS7,ZPSM)
! EH: end not needed in present cycle

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

!*       2.  CALCULATE PRESSURE AND RH
!*           Modified relative humidity, q > 0, full level
!*           pressure and tropopause height
!            -------------------------

DO JKGLO=1,NGPTOT,NPROMA
  IBL=(JKGLO-1)/NPROMA+1
  ICEND = MIN(NPROMA,NGPTOT-JKGLO+1)

!*       2.1   ANALYSIS 
  CALL PREGPRH (ICEND,ZTT0(1,1,IBL),GFL(1,1,YQ%MP,IBL),&
              & ZPS0(1,IBL),ZQP0,ZPRSH0,ZPRSF0,ZES0,ZRH0,ILTROP0)

! EH: below not needed in present cycle, but leave for next cycle updates
!*       2.2   TRAJECTORY 
! CALL PREGPRH (ICEND,ZTT5(1,1,IBL),PGFLT5(1,1,YQ%MP,IBL),&
!             & ZPS5(1,IBL),ZQP5,ZPRSH5,ZPRSF5,ZES5,ZRH5,ILTROP5)

!*       2.3   (BACKGROUND+TRAJECTORY)/2
! ZTTM(1:ICEND,1:NFLEVG,IBL) = 0.5_JPRB*(    ZTTM(1:ICEND,1:NFLEVG,      IBL) &
!                            &           +   ZTT0(1:ICEND,1:NFLEVG,      IBL) )
! ZPSM(1:ICEND,         IBL) = 0.5_JPRB*(    ZPSM(1:ICEND,               IBL) &
!                            &           +   ZPS0(1:ICEND,               IBL) )
! ZQM (1:ICEND,1:NFLEVG    ) = 0.5_JPRB*(  PGFLT5(1:ICEND,1:NFLEVG,YQ%MP,IBL) &
!                            &           +    GFL(1:ICEND,1:NFLEVG,YQ%MP,IBL) )
! CALL PREGPRH (ICEND,ZTTM(1,1,IBL),ZQM,&
!             & ZPSM(1,IBL),ZQPM,ZPRSHM,ZPRSFM,ZESM,ZRHM,ILTROPM)
! EH: end not needed in present cycle

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

!*       3.  NONLINEAR ADJUSTMENT
!            --------------------
!*           Here we solve the nonlinear change of control
!*           variable at full resolution. This takes into account
!*           the assymmetric behaviour of the background error
!*           pdf.
!*           Note: Simplification necessary for allowing supersaturated states.

  IF (LJB_NONLINEAR_CVHUM) THEN

!*       3.1   NONLINEAR ADJUSTMENT OF RH 

    DO JLEV=1,NFLEVG
      DO JROF=1,ICEND
        IF (JLEV > ILTROP0(JROF) ) THEN
          ZRHMIN=FQMIN(JLEV,ZRH0(JROF,JLEV))
          ZRHMAX=FQMAX(JLEV,ZRH0(JROF,JLEV))

!*       3.1.1   INVERT ANALYSIS MODIFICATION OF RH TO Q MODIFICATION

          ZQS    =ZES0(JROF,JLEV) &
                 &/(ZPRSF0(JROF,JLEV)*(1.0_JPRB+RETV)-ZES0(JROF,JLEV)*RETV)
          ZDQMIN =ZRHMIN*ZQS              -PGFLT5(JROF,JLEV,YQ%MP,IBL)
          ZDQMAX =ZRHMAX*ZQS              -PGFLT5(JROF,JLEV,YQ%MP,IBL)
          ZDQ    =GFL(JROF,JLEV,YQ%MP,IBL)-PGFLT5(JROF,JLEV,YQ%MP,IBL)
          GFL(JROF,JLEV,YQ%MP,IBL)=PGFLT5(JROF,JLEV,YQ%MP,IBL)              &
                                & + MAX( MIN( ZDQ, MAX( 0._JPRB, ZDQMAX ) ),&
                                &                  MIN( 0._JPRB, ZDQMIN ) )
        ENDIF
      ENDDO
    ENDDO

  ENDIF

  IF (YO3%LACTIVE .AND. LJB_NONLINEAR_CVO3) THEN

!*  Generalize for tracers

  ENDIF

ENDDO

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

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