SUBROUTINE GP_SSMI_IOBS2GP(KFIELD,KFIELD_GP,KLEN,KSTREAM1D)

!**** *GP_SSMI_IOBS2GP* - RAIN ASSIMILATION - GET SSMI OBS IN GRID-POINT SPACE for
!     1D-Var in clouds/precipitation for SSM/I radiances

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

!     PURPOSE.
!     -------
!     GET SSMI OBS FROM OBS TO GRID-POINT SPACE

!**   INTERFACE.
!**   ---------
!**   *CALL* * GP_SSMI_IOBS2GP()*  (FROM GP_SSMI)

!        Explicit arguments :


!     AUTHOR: Deborah Salmond
!     DATE  : 02-04-2004

!     Modifications :
!     D.Salmond      1-Jul-2005  Bit reproducible OBS/GP matching
!     A.Geer        26-Feb-2007  Multiple sensors
!     ------------------------------------------------------------------

USE PARKIND1  ,ONLY : JPIM     ,JPRB
USE YOMMP    , ONLY : MYPROC
USE YOMCT0   , ONLY : NPROC
USE YOMGEM   , ONLY : NGPTOT
USE YOM_SSMI , ONLY : OB_JOBS, OB_FROM, OB_JROF_GP, &
                    & GP_COUNT,OB_COUNT
USE MPL_MODULE, ONLY : MPL_SEND, MPL_RECV, MPL_BARRIER

USE YOMHOOK   ,ONLY : LHOOK,   DR_HOOK

IMPLICIT NONE

INTEGER(KIND=JPIM),INTENT(IN) :: KFIELD(KLEN)
INTEGER(KIND=JPIM),INTENT(OUT) :: KFIELD_GP(NGPTOT)
INTEGER(KIND=JPIM),INTENT(IN) :: KLEN, KSTREAM1D

INTEGER(KIND=JPIM) :: ITAG,IDIM_GP,IDIM_OB,IPROC,II
INTEGER(KIND=JPIM),ALLOCATABLE :: IBUF_GP(:,:)
INTEGER(KIND=JPIM),ALLOCATABLE :: IBUF_OBS(:,:)
INTEGER(KIND=JPIM),ALLOCATABLE :: IBUF(:)
REAL(KIND=JPRB) :: ZHOOK_HANDLE

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

CALL GSTATS(699,0)
ITAG=1

IF(MYPROC == 1)THEN
  IDIM_GP=MAXVAL(GP_COUNT(KSTREAM1D,:))
  IDIM_OB=MAXVAL(OB_COUNT(:))
  ALLOCATE(IBUF_GP(IDIM_GP,NPROC))
  ALLOCATE(IBUF_OBS(IDIM_OB,NPROC))
ENDIF

ALLOCATE(IBUF(GP_COUNT(KSTREAM1D,MYPROC)))



IF(MYPROC == 1)THEN
  IBUF_GP=0
  IBUF_OBS=0
ENDIF

IBUF=0.0_JPRB

! Gather the observation-space data to processor 1
IF(MYPROC /= 1)THEN
  
  IF(OB_COUNT(MYPROC) /= 0)THEN
    CALL MPL_SEND(KFIELD(1:OB_COUNT(MYPROC)),&
     & KDEST=1,KTAG=ITAG,CDSTRING='GP_SSMI_IOBS2GP' )
  ENDIF

ELSE
  
  DO IPROC=2,NPROC
    IF(OB_COUNT(IPROC) /= 0)THEN
      CALL MPL_RECV(IBUF_OBS(1:OB_COUNT(IPROC),IPROC),&
       & KSOURCE=IPROC,KTAG=ITAG,CDSTRING='GP_SSMI_IOBS2GP' )
    ENDIF
  ENDDO
  
  IBUF_OBS(1:OB_COUNT(1),1) = &
             &   KFIELD(1:OB_COUNT(1))
  
ENDIF
  
  
! Distribute to the processor that owns the grid point 
IF(MYPROC ==1)THEN

  DO IPROC=1,NPROC
    DO II=1,GP_COUNT(KSTREAM1D,IPROC)
      IBUF_GP(II,IPROC)= &
        &  IBUF_OBS(OB_JOBS(II,KSTREAM1D,IPROC),OB_FROM(II,KSTREAM1D,IPROC))
    ENDDO
  ENDDO

  DO IPROC=2,NPROC
    IF(GP_COUNT(KSTREAM1D,IPROC) /= 0)THEN
      CALL MPL_SEND(IBUF_GP(1:GP_COUNT(KSTREAM1D,IPROC),IPROC),&
       & KDEST=IPROC,KTAG=ITAG,CDSTRING='GP_SSMI_IOBS2GP' )
    ENDIF
  ENDDO

  IBUF(1:GP_COUNT(KSTREAM1D,1)) = &
       &    IBUF_GP(1:GP_COUNT(KSTREAM1D,1),1)

ELSE 

  IF(GP_COUNT(KSTREAM1D,MYPROC) /= 0)THEN
    CALL MPL_RECV(IBUF(1:GP_COUNT(KSTREAM1D,MYPROC)),&
     & KSOURCE=1,KTAG=ITAG,CDSTRING='GP_SSMI_IOBS2GP' )
  ENDIF

ENDIF


DO II=1,GP_COUNT(KSTREAM1D,MYPROC)
  KFIELD_GP(OB_JROF_GP(II,KSTREAM1D,MYPROC))=IBUF(II)
ENDDO


IF(MYPROC == 1)THEN
  DEALLOCATE(IBUF_GP)
  DEALLOCATE(IBUF_OBS)
ENDIF

DEALLOCATE(IBUF)

CALL MPL_BARRIER(CDSTRING='GP_SSMI_IOBS2GP')
CALL GSTATS(699,1)

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

END SUBROUTINE GP_SSMI_IOBS2GP
