SUBROUTINE SEKF_WRITE(CDWRT)

!**** *SEKF_WRITE*  - write output from the SEKF to grib

!     Purpose.
!     --------
!     (1) generate grib fields for debugging
!     (2) generate B-matrix in grib for cycling
!     (3) generate grib fields for analysed soil moisture

!**   Interface.
!     ----------
!     *CALL* *SEKF_WRITE(CDWRT)

!**   Input parameters:
!     -----------------
!     CDWRT   :  If set to 'SEKF1' create grib files for debugging fields and B matrix,
!                if set to 'SEKF2' create grib files for soil moisture analysis.

!     Explicit arguments :     None
!     --------------------

!     Implicit arguments :     None
!     --------------------

!     Method.
!     -------
!     See documentation

!     Externals.
!     ----------

!     Reference.
!     ----------
!     ECMWF Research Department documentation of the IFS

!     Author.
!     -------
!     M. Drusch  *ECMWF*

!     Modifications.
!     --------------
!       2008-08-03 - K. Scipal - added debug output for ASCAT data
!                    (only first observation in assimilation window is written)
!       2009-12-15 - P. de Rosnay lighter output in log file

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

USE PARKIND1  ,ONLY : JPIM     ,JPRB
USE YOMHOOK   ,ONLY : LHOOK,   DR_HOOK
USE YOMGEM    ,ONLY : NGPTOT
USE YOMLUN    ,ONLY : NULOUT
USE IOSTREAM_MIX  ,ONLY : SETUP_IOSTREAM, SETUP_IOREQUEST, IO_PUT, CLOSE_IOSTREAM, &
    &                 TYPE_IOSTREAM, TYPE_IOREQUEST, CLOSE_IOREQUEST
USE YOMSEKF   ,ONLY : SEKF_INC, SEKF_Q, SEKF_DEBUG_3D, &
    &                 SEKF_A, SEKF_B, SEKF_G, SEKF_J, N_SEKF_CV, &
    &                 NOBS_SEKF_MAX, NANAL, SEKF_F

IMPLICIT NONE

CHARACTER(LEN = 5), INTENT(IN) :: CDWRT

REAL(KIND=JPRB)    ::  ZHOOK_HANDLE

INTEGER(KIND=JPIM) :: J1, J2, J3, IFIELDS, ILEVELS
INTEGER(KIND=JPIM) :: J_ABFILE, J_GJFILE, JOBS, JNOFILE, JANAFILE
INTEGER(KIND=JPIM), ALLOCATABLE :: IGRIB2D(:)
INTEGER(KIND=JPIM), ALLOCATABLE :: ILEVS2D(:)

REAL(KIND=JPRB), ALLOCATABLE :: ZGGP(:,:,:)

TYPE(TYPE_IOSTREAM) :: YL_IOSTREAM
TYPE(TYPE_IOREQUEST):: YL_IOREQUEST

CHARACTER(LEN = 2) :: CLJ1,CLJ2
CHARACTER(LEN = 3) :: CLLEVT
CHARACTER(LEN =20), ALLOCATABLE :: CLOFILE(:)
CHARACTER(LEN =20), ALLOCATABLE :: CL_CAFILE(:)
CHARACTER(LEN =20), ALLOCATABLE :: CL_CBFILE(:)
CHARACTER(LEN =20), ALLOCATABLE :: CL_CGFILE(:)
CHARACTER(LEN =20), ALLOCATABLE :: CL_CJFILE(:)
CHARACTER(LEN =20), ALLOCATABLE :: CL_CANAFILE(:)

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

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

!     1.0 Initialize output files  -------------------------------------

CLLEVT = 'SFC'

JOBS = NOBS_SEKF_MAX

IF (CDWRT == 'SEKF1') THEN
  JNOFILE = 24
  J_ABFILE = N_SEKF_CV*N_SEKF_CV
  J_GJFILE = N_SEKF_CV*JOBS
  ALLOCATE(CLOFILE(JNOFILE))
  ALLOCATE(CL_CAFILE(J_ABFILE))
  ALLOCATE(CL_CBFILE(J_ABFILE))
  ALLOCATE(CL_CGFILE(J_GJFILE))
  ALLOCATE(CL_CJFILE(J_GJFILE))
  CLOFILE(1) = 'sekf_inc_l1.grib'
  CLOFILE(2) = 'sekf_inc_l2.grib'
  CLOFILE(3) = 'sekf_inc_l3.grib'
  CLOFILE(4) = 'sekf_qual.grib'
  CLOFILE(5) = 'sekf_debug_1.grib'
  CLOFILE(6) = 'sekf_debug_2.grib'
  CLOFILE(7) = 'sekf_debug_3.grib'
  CLOFILE(8) = 'sekf_debug_4.grib'
  CLOFILE(9) = 'sekf_debug_5.grib'
  CLOFILE(10)= 'sekf_debug_6.grib'
  CLOFILE(11)= 'sekf_debug_7.grib'
  CLOFILE(12)= 'sekf_debug_8.grib'
  CLOFILE(13)= 'sekf_debug_9.grib'
  CLOFILE(14)= 'sekf_debug_10.grib'
  CLOFILE(15)= 'sekf_debug_11.grib'
  CLOFILE(16)= 'sekf_debug_12.grib'
  CLOFILE(17)= 'sekf_debug_13.grib'
  CLOFILE(18)= 'sekf_debug_14.grib'
  CLOFILE(19)= 'sekf_debug_15.grib'
  CLOFILE(20)= 'sekf_debug_16.grib'
  CLOFILE(21)= 'sekf_debug_17.grib'
  CLOFILE(22)= 'sekf_debug_18.grib'
  CLOFILE(23)= 'sekf_debug_19.grib'
  CLOFILE(24)= 'sekf_debug_20.grib'
  DO J1 = 1, N_SEKF_CV
    DO J2 = 1, N_SEKF_CV
      J3 = N_SEKF_CV * (J1-1) + J2
      WRITE(CLJ1,'(i2.2)') J1
      WRITE(CLJ2,'(i2.2)') J2
      CL_CAFILE(J3) = 'A_'//CLJ1//CLJ2//'.grib'
      CL_CBFILE(J3) = 'B_'//CLJ1//CLJ2//'.grib'
    ENDDO
  ENDDO
  DO J1 = 1, N_SEKF_CV
    DO J2 = 1, JOBS
      J3 = JOBS * (J1-1) + J2
      WRITE(CLJ1,'(i2.2)') J1
      WRITE(CLJ2,'(i2.2)') J2
      CL_CGFILE(J3) = 'G_'//CLJ1//CLJ2//'.grib'
    ENDDO
  ENDDO
  DO J1 = 1, JOBS
    DO J2 = 1, N_SEKF_CV
      J3 = N_SEKF_CV * (J1-1) + J2
      WRITE(CLJ1,'(i2.2)') J1
      WRITE(CLJ2,'(i2.2)') J2
      CL_CJFILE(J3) = 'J_'//CLJ1//CLJ2//'.grib'
    ENDDO
  ENDDO
  IFIELDS = 1
  ILEVELS = 1
ELSEIF (CDWRT == 'SEKF2') THEN
  JANAFILE = N_SEKF_CV*NANAL
  ALLOCATE(CL_CANAFILE(JANAFILE))
  DO J1 = 1, NANAL
    DO J2 = 1, N_SEKF_CV
      J3 = N_SEKF_CV * (J1-1) + J2
      WRITE(CLJ1,'(i2.2)') J1
      WRITE(CLJ2,'(i2.2)') J2
      CL_CANAFILE(J3) = 'ANA_T'//CLJ1//'_L'//CLJ2//'.grib'
    ENDDO
  ENDDO
  IFIELDS = 1
  ILEVELS = 1
ENDIF

ALLOCATE(IGRIB2D(IFIELDS))
ALLOCATE(ILEVS2D(ILEVELS))
ALLOCATE(ZGGP(NGPTOT,ILEVELS,1))

!     2.0 Create grib files  -------------------------------------------

IF (CDWRT == 'SEKF1') THEN

!     2.1 Write 1 D fields for debugging

  DO J1 = 1, JNOFILE
    ZGGP(:,:,:)= 0.
    IF (J1 == 1) THEN
      ILEVS2D(1) = 1
      IGRIB2D(1) = 39
      ZGGP(:,1,1) = SEKF_INC(:,1,1)
    ENDIF
    IF (J1 == 2) THEN
      ILEVS2D(1) = 1
      IGRIB2D(1) = 40
      ZGGP(:,1,1) = SEKF_INC(:,2,1)
    ENDIF
    IF (J1 == 3) THEN
      ILEVS2D(1) = 1
      IGRIB2D(1) = 41
      ZGGP(:,1,1) = SEKF_INC(:,3,1)
    ENDIF
    IF (J1 ==  4) THEN
      ILEVS2D(1) = 1
      IGRIB2D(1) = 39
      ZGGP(:,1,1) = SEKF_Q(:,1,1)
    ENDIF
    IF ((J1 >= 5) .AND. (J1 <= 24)) THEN
      ILEVS2D(1) = 1
      IGRIB2D(1) = 39
      ZGGP(:,1,1) = SEKF_DEBUG_3D(:,J1-4,1)
      !WRITE(NULOUT,*) ZGGP(:,1,1)
    ENDIF

    CALL SETUP_IOSTREAM(YL_IOSTREAM,'CIO',TRIM(CLOFILE(J1)),CDMODE='w',KIOMASTER=1)
    CALL SETUP_IOREQUEST(YL_IOREQUEST,'GRIDPOINT_FIELDS',LDGRIB=.TRUE., &
       & KGRIB2D=IGRIB2D,KLEVS2D=ILEVS2D,CDLEVTYPE=CLLEVT)
    CALL IO_PUT(YL_IOSTREAM,YL_IOREQUEST,PR3=ZGGP)
    CALL CLOSE_IOREQUEST(YL_IOREQUEST)
    CALL CLOSE_IOSTREAM(YL_IOSTREAM)
  ENDDO

!     2.1 Write 1D fields for debugging

  DO J1 = 1, 2
    DO J2 = 1, J_ABFILE

      ZGGP(:,:,:)= 0.
      ILEVS2D(1) = 1
      IGRIB2D(1) = 39
      IF (J1 == 1) THEN
        ZGGP(:,1,1) = SEKF_A(:,J2,1)
        CALL SETUP_IOSTREAM(YL_IOSTREAM,'CIO',TRIM(CL_CAFILE(J2)),CDMODE='w',KIOMASTER=1)
      ENDIF
      IF (J1 == 2) THEN
        ZGGP(:,1,1) = SEKF_B(:,J2,1)
        CALL SETUP_IOSTREAM(YL_IOSTREAM,'CIO',TRIM(CL_CBFILE(J2)),CDMODE='w',KIOMASTER=1)
      ENDIF

      CALL SETUP_IOREQUEST(YL_IOREQUEST,'GRIDPOINT_FIELDS',LDGRIB=.TRUE., &
         & KGRIB2D=IGRIB2D,KLEVS2D=ILEVS2D,CDLEVTYPE=CLLEVT)
      CALL IO_PUT(YL_IOSTREAM,YL_IOREQUEST,PR3=ZGGP)
      CALL CLOSE_IOREQUEST(YL_IOREQUEST)
      CALL CLOSE_IOSTREAM(YL_IOSTREAM)

    ENDDO
  ENDDO

  DO J1 = 1, 2
    DO J2 = 1, J_GJFILE

      ZGGP(:,:,:)= 0.
      ILEVS2D(1) = 1
      IGRIB2D(1) = 39
      IF (J1 == 1) THEN
        ZGGP(:,1,1) = SEKF_G(:,J2,1)
        CALL SETUP_IOSTREAM(YL_IOSTREAM,'CIO',TRIM(CL_CGFILE(J2)),CDMODE='w',KIOMASTER=1)
      ENDIF
      IF (J1 == 2) THEN
        ZGGP(:,1,1) = SEKF_J(:,J2,1)
        CALL SETUP_IOSTREAM(YL_IOSTREAM,'CIO',TRIM(CL_CJFILE(J2)),CDMODE='w',KIOMASTER=1)
      ENDIF

      CALL SETUP_IOREQUEST(YL_IOREQUEST,'GRIDPOINT_FIELDS',LDGRIB=.TRUE., &
         & KGRIB2D=IGRIB2D,KLEVS2D=ILEVS2D,CDLEVTYPE=CLLEVT)
      CALL IO_PUT(YL_IOSTREAM,YL_IOREQUEST,PR3=ZGGP)
      CALL CLOSE_IOREQUEST(YL_IOREQUEST)
      CALL CLOSE_IOSTREAM(YL_IOSTREAM)

    ENDDO
  ENDDO

ELSEIF (CDWRT == 'SEKF2') THEN

  DO J1 = 1, NANAL
    DO J2 = 1, N_SEKF_CV

      J3 = N_SEKF_CV * (J1-1) + J2
      ZGGP(:,:,:)= 0.
      ILEVS2D(1) = 1

      IF (J2 == 1) IGRIB2D(1) = 39
      IF (J2 == 2) IGRIB2D(1) = 40
      IF (J2 == 3) IGRIB2D(1) = 41

      ZGGP(:,1,1) = SEKF_F(:,J3,1)
      CALL SETUP_IOSTREAM(YL_IOSTREAM,'CIO',TRIM(CL_CANAFILE(J3)),CDMODE='w',KIOMASTER=1)
      CALL SETUP_IOREQUEST(YL_IOREQUEST,'GRIDPOINT_FIELDS',LDGRIB=.TRUE., &
         & KGRIB2D=IGRIB2D,KLEVS2D=ILEVS2D,CDLEVTYPE=CLLEVT)
      CALL IO_PUT(YL_IOSTREAM,YL_IOREQUEST,PR3=ZGGP)
      CALL CLOSE_IOREQUEST(YL_IOREQUEST)
      CALL CLOSE_IOSTREAM(YL_IOSTREAM)

    ENDDO
  ENDDO

ENDIF

!     N.0 Clean up -----------------------------------------------------

IF (ALLOCATED(CLOFILE)) DEALLOCATE(CLOFILE)
IF (ALLOCATED(CL_CANAFILE)) DEALLOCATE(CL_CANAFILE)
IF (ALLOCATED(CL_CAFILE)) DEALLOCATE(CL_CAFILE)
IF (ALLOCATED(CL_CBFILE)) DEALLOCATE(CL_CBFILE)
IF (ALLOCATED(CL_CGFILE)) DEALLOCATE(CL_CGFILE)
IF (ALLOCATED(CL_CJFILE)) DEALLOCATE(CL_CJFILE)
IF (ALLOCATED(IGRIB2D)) DEALLOCATE(IGRIB2D)
IF (ALLOCATED(ILEVS2D)) DEALLOCATE(ILEVS2D)
IF (ALLOCATED(ZGGP)) DEALLOCATE(ZGGP)

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

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