subroutine onedvar_obsop_gr (ksat, kproma, k1d_x, k1d_y, k1d_z, &
                           &   p1d_x5, p1d_x_xt5, p1d_y, pdj_o, pdj_ox)

!**** Gradient of observation operator for 
!     1D-Var in clouds/precipitation for SSM/I radiances 

!     P. Bauer, P. Lopez, E. Moreau, D. Salmond   ECMWF    May 2004

!     1. Call simplified moist physics
!     2. Call RTTOV-interface of gradient of observation operator
!     3. Call adjoint of simplified moist physics

!     ONEDVAR_OBSOP is called from ONEDVAR_RAINTB, ONEDVAR_SIMUL

!     Modifications:

!     A. Geer     22-Mar-2006  Add 10m wind to control vector
!     C. O'Dell   Dec-2006  Slight changes necessary for multiple sensors
!     A. Geer     11-Nov-2007  RTTOV9 compatible

!**** MODULES      

!* KIND     
use parkind1, only: jpim, jprb
use yomhook , only: lhook,   dr_hook

!* IFS
use yomdim  , only: nflevg                      
use yomgem  , only: vah, vbh

implicit none
         
!**** VARIABLES
!* IN/OUTPUT
integer (kind=jpim), intent    (in)                           :: ksat, kproma
integer (kind=jpim), intent    (in)                           :: k1d_x, k1d_y, k1d_z
real    (kind=jprb), intent    (in), dimension (kproma,k1d_x) :: p1d_x5
real    (kind=jprb), intent (inout), dimension (kproma,k1d_z) :: p1d_x_xt5
real    (kind=jprb), intent    (in), dimension (kproma,k1d_y) :: pdj_o   
real    (kind=jprb), intent (inout), dimension (kproma,k1d_y) :: p1d_y  
real    (kind=jprb), intent   (out), dimension (kproma,k1d_x) :: pdj_ox  

!* OTHER                      
integer (kind=jpim) :: i_lev, i_print, i_flevg, i_proma
integer (kind=jpim) :: ichannels
    
real    (kind=jprb), dimension (kproma,k1d_x) :: z1d_x
real    (kind=jprb), dimension (kproma,k1d_z) :: z1d_x_xt
    
real    (kind=jprb), dimension (kproma,nflevg+1) :: zphys_ph5, zphys_ph
    
real    (kind=jprb), dimension (kproma,nflevg) :: zphys_rfl5, zphys_sfl5, zphys_tet5, zphys_teq5  
real    (kind=jprb), dimension (kproma,nflevg) :: zphys_rfl , zphys_sfl , zphys_tet , zphys_teq  
real    (kind=jprb), dimension (kproma,nflevg) :: zphys_cwc5, zphys_cic5, zphys_cc5, zphys_t5, zphys_q5, zphys_p5  
real    (kind=jprb), dimension (kproma,nflevg) :: zphys_cwc , zphys_cic , zphys_cc , zphys_t , zphys_q , zphys_p
real    (kind=jprb), dimension (kproma)        :: zphys_ps5 , zphys_sh5 , zphys_lh5, zphys_us5, zphys_vs5   
real    (kind=jprb), dimension (kproma)        :: zphys_ps  , zphys_sh  , zphys_lh , zphys_us , zphys_vs
real    (kind=jprb), dimension (kproma)        :: zphys_srf5, zphys_crf5,  z_sfc
real    (kind=jprb), dimension (kproma)        :: zphys_srf , zphys_crf  

real (kind=jprb) :: zhook_handle

!* INTERFACES
#include "phys_nl.intfb.h"
#include "phys_ad.intfb.h"
!#include "onedvar_obsop_rttov.intfb.h"
!#include "onedvar_obsop_grad_rttov.intfb.h"

if (lhook) call dr_hook ('ONEDVAR_OBSOP_GR',0,zhook_handle)

!* START 

pdj_ox (:,:) = 0.0_JPRB
i_print      = 0     
i_flevg      = nflevg
        
!* Control variable 
zphys_t5   (1:kproma,1:nflevg) = p1d_x5   (1:kproma,       1:  nflevg)
zphys_q5   (1:kproma,1:nflevg) = p1d_x5   (1:kproma,nflevg+1:2*nflevg)
    
!* Others
zphys_tet5 (1:kproma,1:nflevg) = p1d_x_xt5 (1:kproma,       1:  nflevg)
zphys_teq5 (1:kproma,1:nflevg) = p1d_x_xt5 (1:kproma,nflevg+1:2*nflevg)
    
zphys_ps5  (1:kproma) = p1d_x_xt5 (1:kproma,7*nflevg+9)
zphys_sh5  (1:kproma) = p1d_x_xt5 (1:kproma,7*nflevg+6)
zphys_lh5  (1:kproma) = p1d_x_xt5 (1:kproma,7*nflevg+7)
zphys_us5  (1:kproma) = p1d_x_xt5 (1:kproma,7*nflevg+4)
zphys_vs5  (1:kproma) = p1d_x_xt5 (1:kproma,7*nflevg+5)

!* Set up pressure at ML
do i_proma = 1, kproma
   z_sfc (i_proma) = p1d_x_xt5 (i_proma,7*nflevg+9)
   zphys_ph5 (i_proma,1:nflevg+1) = vbh (0:nflevg) * z_sfc (i_proma) + vah (0:nflevg)
enddo
    
do i_lev =  nflevg, 1, -1
  zphys_p5 (1:kproma,i_lev) = 0.5_JPRB * (zphys_ph5 (1:kproma,i_lev) + zphys_ph5 (1:kproma,i_lev+1))
enddo
                
!* Initialize for safety
zphys_rfl5 (:,:) = 0.0_JPRB
zphys_sfl5 (:,:) = 0.0_JPRB
zphys_cwc5 (:,:) = 0.0_JPRB
zphys_cic5 (:,:) = 0.0_JPRB
zphys_cc5  (:,:) = 0.0_JPRB
zphys_crf5 (:)   = 0.0_JPRB
zphys_srf5 (:)   = 0.0_JPRB

!* Moist physics
call phys_nl (i_flevg, kproma, &
 &   zphys_t5                  , &            ! in:  T
 &   zphys_q5                  , &            ! in:  q, rh'
 &   zphys_p5                  , &            ! in:  p
 &   zphys_ph5                 , &            ! in:  ph
 &   zphys_tet5                , &            ! in:  ten_t
 &   zphys_teq5                , &            ! in:  ten_q
 &   zphys_sh5                 , &            ! in:  sh_sfc
 &   zphys_lh5                 , &            ! in:  lh_sfc
 &   zphys_us5                 , &            ! in:  u_star
 &   zphys_vs5                 , &            ! in:  v_star
 &   zphys_rfl5                , &            ! out: rain flux
 &   zphys_sfl5                , &            ! out: snow flux
 &   zphys_cwc5                , &            ! out: cloud water
 &   zphys_cic5                , &            ! out: cloud ice
 &   zphys_cc5                 , &            ! out: cloud cover
 &   zphys_srf5                , &            ! out: strt. rain flux at sfc
 &   zphys_crf5)                              ! out: conv. rain flux at sfc

                        
p1d_x_xt5 (1:kproma,2*nflevg+1:3*nflevg) = zphys_rfl5 (1:kproma,1:nflevg)
p1d_x_xt5 (1:kproma,3*nflevg+1:4*nflevg) = zphys_sfl5 (1:kproma,1:nflevg)
p1d_x_xt5 (1:kproma,4*nflevg+1:5*nflevg) = zphys_cwc5 (1:kproma,1:nflevg)
p1d_x_xt5 (1:kproma,5*nflevg+1:6*nflevg) = zphys_cic5 (1:kproma,1:nflevg)
p1d_x_xt5 (1:kproma,6*nflevg+1:7*nflevg) = zphys_cc5  (1:kproma,1:nflevg)

p1d_x_xt5 (1:kproma,7*nflevg+11) = zphys_srf5 (1:kproma)                  
p1d_x_xt5 (1:kproma,7*nflevg+12) = zphys_crf5 (1:kproma)

z1d_x    (:,:) = 0.0_JPRB
z1d_x_xt (:,:) = 0.0_JPRB                       

ichannels = k1d_y * kproma

call onedvar_obsop_grad_rttov (ksat, &
 &  k1d_x, k1d_y, k1d_z, &        
 &  ichannels           , &
 &  i_flevg, kproma     , &            ! in: levels, profiles
 &  p1d_x5              , &
 &  p1d_x_xt5           , &
 &  z1d_x               , &
 &  z1d_x_xt            , &
 &  zphys_p5            , &            ! in: pressure
 &  zphys_ph5           , &            ! in: pressure at i/f
 &  p1d_y               , &
 &  pdj_o)

zphys_t   (1:kproma,1:nflevg) = z1d_x      (1:kproma,       1:  nflevg)
zphys_q   (1:kproma,1:nflevg) = z1d_x      (1:kproma,nflevg+1:2*nflevg)
    
zphys_rfl (1:kproma,1:nflevg) = z1d_x_xt (1:kproma,2*nflevg+1:3*nflevg)
zphys_sfl (1:kproma,1:nflevg) = z1d_x_xt (1:kproma,3*nflevg+1:4*nflevg)
zphys_cwc (1:kproma,1:nflevg) = z1d_x_xt (1:kproma,4*nflevg+1:5*nflevg)
zphys_cic (1:kproma,1:nflevg) = z1d_x_xt (1:kproma,5*nflevg+1:6*nflevg)
zphys_cc  (1:kproma,1:nflevg) = z1d_x_xt (1:kproma,6*nflevg+1:7*nflevg)

!* Reset Reset local trajectory fields to input
zphys_tet5 (1:kproma,1:nflevg) = p1d_x_xt5 (1:kproma,       1:  nflevg)
zphys_teq5 (1:kproma,1:nflevg) = p1d_x_xt5 (1:kproma,nflevg+1:2*nflevg)
    
zphys_ps5  (1:kproma) = p1d_x_xt5 (1:kproma,7*nflevg+9)
zphys_sh5  (1:kproma) = p1d_x_xt5 (1:kproma,7*nflevg+6)
zphys_lh5  (1:kproma) = p1d_x_xt5 (1:kproma,7*nflevg+7)
zphys_us5  (1:kproma) = p1d_x_xt5 (1:kproma,7*nflevg+4)
zphys_vs5  (1:kproma) = p1d_x_xt5 (1:kproma,7*nflevg+5)

!* Set up pressure at ML
do i_proma = 1, kproma
   z_sfc (i_proma) = p1d_x_xt5 (i_proma,7*nflevg+9)
   zphys_ph5 (i_proma,1:nflevg+1) = vbh (0:nflevg) * z_sfc (i_proma) + vah (0:nflevg)
enddo
    
do i_lev =  nflevg, 1, -1
  zphys_p5 (1:kproma,i_lev) = 0.5_JPRB * (zphys_ph5 (1:kproma,i_lev) + zphys_ph5 (1:kproma,i_lev+1))
enddo
                
!* Reset increments that are not output from RTTOV_SCATT_AD
zphys_p   (:,:) = 0.0_JPRB           
zphys_ph  (:,:) = 0.0_JPRB   
zphys_tet (:,:) = 0.0_JPRB    
zphys_teq (:,:) = 0.0_JPRB   
zphys_ps  (:)   = 0.0_JPRB 
zphys_sh  (:)   = 0.0_JPRB 
zphys_lh  (:)   = 0.0_JPRB    
zphys_us  (:)   = 0.0_JPRB   
zphys_vs  (:)   = 0.0_JPRB    
zphys_srf (:)   = 0.0_JPRB  
zphys_crf (:)   = 0.0_JPRB            

zphys_rfl5 (:,:) = 0.0_JPRB
zphys_sfl5 (:,:) = 0.0_JPRB
zphys_cwc5 (:,:) = 0.0_JPRB
zphys_cic5 (:,:) = 0.0_JPRB
zphys_cc5  (:,:) = 0.0_JPRB
zphys_crf5 (:)   = 0.0_JPRB
zphys_srf5 (:)   = 0.0_JPRB

!* Moist physics, AD
call phys_ad (i_flevg, kproma, &
 &   zphys_t5                  , &            ! in:  T
 &   zphys_q5                  , &            ! in:  q, rh'
 &   zphys_p5                  , &            ! in:  p
 &   zphys_ph5                 , &            ! in:  ph
 &   zphys_tet5                , &            ! in:  ten_t
 &   zphys_teq5                , &            ! in:  ten_q
 &   zphys_sh5                 , &            ! in:  sh_sfc
 &   zphys_lh5                 , &            ! in:  lh_sfc
 &   zphys_us5                 , &            ! in:  u_star
 &   zphys_vs5                 , &            ! in:  v_star
 &   zphys_rfl5                , &            ! inout: rain flux
 &   zphys_sfl5                , &            ! inout: snow flux
 &   zphys_cwc5                , &            ! inout: cloud water
 &   zphys_cic5                , &            ! inout: cloud ice
 &   zphys_cc5                 , &            ! inout: cloud cover
 &   zphys_srf5                , &            ! inout: strt. rain flux at sfc
 &   zphys_crf5                , &            ! inout: conv. rain flux at sfc            
 &   zphys_t                   , &            ! out: T, inc.
 &   zphys_q                   , &            ! out: q, rh', inc.
 &   zphys_p                   , &            ! out: p, inc.
 &   zphys_ph                  , &            ! out: ph, rh', inc.
 &   zphys_tet                 , &            ! out: ten_t, inc.
 &   zphys_teq                 , &            ! out: ten_q, inc.
 &   zphys_sh                  , &            ! out: sh_sfc, inc.
 &   zphys_lh                  , &            ! out: lh_sfc, inc.
 &   zphys_us                  , &            ! out: u_star, inc.
 &   zphys_vs                  , &            ! out: v_star, inc.
 &   zphys_rfl                 , &            ! out: rain flux, inc.
 &   zphys_sfl                 , &            ! out: snow flux, inc.
 &   zphys_cwc                 , &            ! out: cloud water, inc.
 &   zphys_cic                 , &            ! out: cloud ice, inc.
 &   zphys_cc                  , &            ! out: cloud cover, inc.
 &   zphys_srf                 , &            ! out: strt. rain flux at sfc, inc.
 &   zphys_crf)                                ! out: conv. rain flux at sfc, inc.            

pdj_ox (1:kproma,       1:  nflevg) = zphys_t (1:kproma,1:nflevg)       
pdj_ox (1:kproma,nflevg+1:2*nflevg) = zphys_q (1:kproma,1:nflevg)
pdj_ox (1:kproma,       2*nflevg+1) = z1d_x   (1:kproma,2*nflevg+1) ! u10
pdj_ox (1:kproma,       2*nflevg+2) = z1d_x   (1:kproma,2*nflevg+2) ! v10
              
if (lhook) call dr_hook ('ONEDVAR_OBSOP_GR',1,zhook_handle)
end subroutine onedvar_obsop_gr
