SUBROUTINE SMOS_OBS2GP(  PFIELD,PFIELD_GP,KPOL,&
                       & LDSUM,LDMEAN)

!**** *SMOS_OBS2GP* -  
!
!     
!
!     PURPOSE.
!     -------
!     GET SMOS OBS FROM OBS TO GRID-POINT SPACE
!
!**   INTERFACE.
!**   ---------
!**   *CALL* * SMOS_OBS2GP()*  (FROM SMOS_GET)
!
!        Explicit arguments :
!
!
!     AUTHOR: J. Muñoz Sabater 
!     DATE  : 05-10-2009
!
!     Modifications :
!     J. Muñoz Sabater  25-11-2009 : Accounts for different polarisations in data
!   
!     ------------------------------------------------------------------

 USE PARKIND1  ,ONLY : JPIM,JPRB
 USE YOMMP    , ONLY : MYPROC
 USE YOMCT0   , ONLY : NPROC
 USE YOMGEM   , ONLY : NGPTOT
 USE YOMANCS  , ONLY : RMDI
 USE YOMSMOS  , ONLY : OB_JOBS, OB_FROM, OB_JROF_GP, OB_INDEX, GP_COUNT,OB_COUNT
 USE MPL_MODULE, ONLY : MPL_SEND, MPL_RECV, MPL_BARRIER
 USE YOMHOOK   ,ONLY : LHOOK,   DR_HOOK

 IMPLICIT NONE

 REAL(KIND=JPRB),INTENT(IN)    :: PFIELD(OB_COUNT(MYPROC,KPOL))
 REAL(KIND=JPRB),INTENT(OUT)   :: PFIELD_GP(NGPTOT)
 INTEGER(KIND=JPIM),INTENT(IN) :: KPOL
 LOGICAL, INTENT(IN)           :: LDSUM
 LOGICAL, INTENT(IN)           :: LDMEAN

 INTEGER(KIND=JPIM)          :: ITAG,IDIM_GP,IDIM_OB,IPROC,II,JROF
 INTEGER(KIND=JPIM)          :: IFIELD_GP_COUNT(NGPTOT)

 REAL(KIND=JPRB),ALLOCATABLE :: ZBUF_GP(:,:)
 REAL(KIND=JPRB),ALLOCATABLE :: ZBUF_OBS(:,:)
 REAL(KIND=JPRB),ALLOCATABLE :: ZBUF(:)

 REAL(KIND=JPRB)             :: ZHOOK_HANDLE

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

 ITAG=1

 IF(MYPROC == 1)THEN
   IDIM_GP=MAXVAL(GP_COUNT(:,KPOL))
   IDIM_OB=MAXVAL(OB_COUNT(:,KPOL))
   ALLOCATE(ZBUF_GP(IDIM_GP,NPROC))
   ALLOCATE(ZBUF_OBS(IDIM_OB,NPROC))
 ENDIF

 ALLOCATE(ZBUF(GP_COUNT(MYPROC,KPOL)))
 

 IF(MYPROC == 1)THEN
   ZBUF_GP =0.0_JPRB
   ZBUF_OBS=0.0_JPRB
 ENDIF

 ZBUF=0.0_JPRB

! Send to PE 1

  IF(MYPROC /= 1)THEN
  
    IF(OB_COUNT(MYPROC,KPOL) /= 0)THEN
       CALL GSTATS(904,0)
       CALL MPL_SEND(PFIELD(1:OB_COUNT(MYPROC,KPOL)),&
            & KDEST=1,KTAG=ITAG,CDSTRING='SMOS_OBS2GP')
       CALL GSTATS(904,1)
    ENDIF
  
  ELSE
  
     CALL GSTATS(904,0)
     DO IPROC=2,NPROC
       IF(OB_COUNT(IPROC,KPOL) /= 0)THEN
         CALL MPL_RECV(ZBUF_OBS(1:OB_COUNT(IPROC,KPOL),IPROC),&
              & KSOURCE=IPROC,KTAG=ITAG,CDSTRING='SMOS_OBS2GP' )
        ENDIF
     ENDDO
     CALL GSTATS(904,1)
  
     ZBUF_OBS(1:OB_COUNT(1,KPOL),1) = PFIELD(1:OB_COUNT(1,KPOL))
  
  ENDIF
  
!  
! Send to PE that owns GP
  
  IF(MYPROC ==1)THEN
  !
    DO IPROC=1,NPROC
      DO II=1,GP_COUNT(IPROC,KPOL)
        ZBUF_GP(II,IPROC)= ZBUF_OBS(OB_JOBS(II,IPROC,KPOL),OB_FROM(II,IPROC,KPOL))
      ENDDO
    ENDDO
    
    CALL GSTATS(904,0)
     
    DO IPROC=2,NPROC
      IF(GP_COUNT(IPROC,KPOL) /= 0)THEN
        CALL MPL_SEND(ZBUF_GP(1:GP_COUNT(IPROC,KPOL),IPROC),&
         & KDEST=IPROC,KTAG=ITAG,CDSTRING='SMOS_OBS2GP' )
      ENDIF
    ENDDO
    CALL GSTATS(904,1)
    
    ZBUF(1:GP_COUNT(1,KPOL)) = ZBUF_GP(1:GP_COUNT(1,KPOL),1)
  
  ELSE 
  
    IF(GP_COUNT(MYPROC,KPOL) /= 0)THEN
      CALL GSTATS(904,0)
      CALL MPL_RECV(ZBUF(1:GP_COUNT(MYPROC,KPOL)),&
       & KSOURCE=1,KTAG=ITAG,CDSTRING='SMOS_OBS2GP' )
      CALL GSTATS(904,1)
    ENDIF
  
  ENDIF
  
  CALL GSTATS(2016,0)
  IF (LDSUM .OR. LDMEAN) THEN
    
    ! LDSUM = Intended to be used when there is more than one observation
    ! per grid point and a summation is required for the adjoint 
    ! contributions in brightness temperature.
    !
    ! LDMEAN = Intended to be used when instead an average value is needed.
    
     DO II=1,NGPTOT
       PFIELD_GP(II)=0.0_JPRB
       IFIELD_GP_COUNT(II)=0
     ENDDO
     
     DO II=1,GP_COUNT(MYPROC,KPOL)
       JROF = OB_JROF_GP(OB_INDEX(II,KPOL),MYPROC,KPOL)
       PFIELD_GP(JROF) = PFIELD_GP(JROF) + ZBUF(OB_INDEX(II,KPOL)) 
       IFIELD_GP_COUNT(JROF) = IFIELD_GP_COUNT(JROF) + 1
     ENDDO
     
     IF (LDMEAN) THEN
       WHERE( IFIELD_GP_COUNT /= 0 ) &
         & PFIELD_GP(:) = PFIELD_GP(:) / IFIELD_GP_COUNT
     ENDIF

   ELSE
     
     ! Intended to be used when no more than one obs per grid point
     DO II=1,NGPTOT
       PFIELD_GP(II)=RMDI
     ENDDO
     
     DO II=1,GP_COUNT(MYPROC,KPOL)
       PFIELD_GP(OB_JROF_GP(OB_INDEX(II,KPOL),MYPROC,KPOL))=ZBUF(OB_INDEX(II,KPOL))
     ENDDO
   
   ENDIF
   CALL GSTATS(2016,1)


 IF(MYPROC == 1)THEN
   DEALLOCATE(ZBUF_GP)
   DEALLOCATE(ZBUF_OBS)
 ENDIF

 DEALLOCATE(ZBUF)

 CALL GSTATS(910,0)
 CALL MPL_BARRIER(CDSTRING='SMOS_OBS2GP')
 CALL GSTATS(910,1)

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

END SUBROUTINE SMOS_OBS2GP
