SUBROUTINE ch_splitting 2,3
      use mod4dv, only : l4dvar
#if defined (DOC)
*
***s/r ch_splitting - update the unobserved variables from the observed ones 
*     .               and write into RPN file
*
*Author  :  Y.Yang June 2005 based on some existing 3dvar subroutines 
*
*Revision:
*
*Arguments
*
*Purpose: implement the splitting analysis scheme to update the increments for 
*         unobserved variables using the analysed ones and their cross-correlation. 
#endif
C
      use modfgat, only : nstamplist
      IMPLICIT NONE
*implicits
#include "pardim.cdk"
#include "comdim.cdk"
#include "comgem.cdk"
#include "rpnstd.cdk"
#include "comgdpar.cdk"
#include "cominterp.cdk"
#include "comlun.cdk"
#include "comct0.cdk"
#include "comfilt.cdk"
#include "namfilt.cdk"
#include "cparbrp.cdk"
#include "comstate.cdk"
#include "comsplit.cdk"
#include "comnumbr.cdk"
#include "cvcord.cdk"
*
      integer maxkeys, nkeys
      parameter(maxkeys=100)
      integer jvar
      integer jlev, instatlev
      logical ldiagno
      integer iip1,iip2, iip3, date0
      integer nlun
      real*8 zlevstatsrc(jpnflev),zoper(1),zlevstattrg
      real*8 zvaranal, zvarunobs
      pointer (ptzvaranal, zvaranal(ni,nflev,nj)), (ptzvarunobs, zvarunobs(ni,nflev,nj))
      pointer (pxzoper,zoper),(pxzlevstattrg,zlevstattrg(nflev))
      real*8 zbuf(1)
      pointer (ptzbuf, zbuf)
      real*8 zvarout
      pointer (ptzvarout, zvarout(ni,nj,nflev,1))
c     real*8  SPLITOPER(1,1,1), SPLITOPERD(1,1)
c     pointer (ptsplitoper, splitoper), (ptsplitoperd, splitoperd)
      integer ji, jj, jk1, jk2, jlat, jlon, ilon, ikey
      integer ikeys(maxkeys)
      integer ibrpstamp
      integer nposbuf
      integer vfstluk, fstnbr
c
c---------------------------------------------------------------------
c
      WRITE(NULOUT,FMT='(/,4X,"Start SPLITTING",//)')
C
c     if(l4dvar) then
c       ibrpstamp=nstamplist(1)
c     else
c       ibrpstamp=nbrpstamp
c     endif

C
C     set incremental field parameter for allocating space
C
      nlun = nulinclr_obs
      iip1      = -1
      iip2      = -1
      iip3      = -1
      date0     = -1
      cltypvar = ' '
      cletiket = ' '
      clnomvar = cvaranal(1)

      ikey = FSTINF(nlun, INI, INJ, INK, date0, cletiket,
     &     iip1, iip2, iip3,cltypvar,clnomvar)
      if(ikey .ge. 0) then
          ierr = fstprm(ikey,idateo,ideet,inpas,ini,inj,ink, inbits,
     &           idatyp,ip1,ip2,ip3,cltypvar,clnomvar,cletiket,clgrtyp
     &           ,ig1,ig2,ig3,ig4,iswa,ilength,idltf,iubc,iextr1
     &           ,iextr2,iextr3)
      else
         write(nulout, *)' increment file problem! '
      endif
c
c     allocate space
c
      call hpalloc(ptzbuf, max(ini*inj,1),ierr,8)
      call hpalloc(ptzvarunobs, max(ini*inj*nflev, 1), ierr,8)
      call hpalloc(ptzvaranal, max(ini*inj*nflev, 1), ierr,8)
      call hpalloc(ptzvarout, max(ini*inj*nflev*npairs,1),ierr,8)
c     call hpalloc(ptsplitoper, max(nflev*nflev*inj, 1), ierr,8)
c     call hpalloc(ptsplitoperd, max(nflev*inj, 1), ierr,8)
c
C     build vertical interpolation operator
c
      kulsplitgd = 0
      ierr = fnom(kulsplitgd,'newsplitoper_gd','RND',0)
      ierr = fstouv(kulsplitgd,'RND')

      call hpalloc(pxzlevstattrg,nflev,ierr,8)
      call rdstatlev(zlevstattrg,nflev,zlevstatsrc,instatlev,jpnflev
     &     ,kulsplitgd)
c

      call hpalloc(pxzoper,nflev*instatlev,ierr,8)

      call suvintoper(zoper,zlevstattrg,nflev,zlevstatsrc,instatlev,1)
C
c     loop through the pairs of variables to be updated
C
      do jvar=1, npairs

        zvarunobs(:,:,:) = 0.0
c
c       read the increment field of the analysed variable
c
        iip1      = -1
        iip2      = -1
        iip3      = -1
        date0     = -1
        cltypvar = ' '
        cletiket = ' '
c       ibrpstamp=nbrpstamp

        DO JLEV = 1, NFLEV
           IERR = VFSTLIR(ZBUF,NLUN,INI,INJ,INK,DATE0,CLETIKET
     &           ,NIP1(JLEV),-1,-1,CLTYPVAR,CVARANAL(JVAR))

c          ikey = FSTINF(nlun, INI, INJ, INK, date0, cletiket,
c    &             nip1(jlev), iip2, iip3,cltypvar,CVARANAL(JVAR))
c
           if (ierr.lt.0) then
                write(nulout,*) 'Problems finding variable '
     &               ,CVARANAL(JVAR),' at level ',nip1(jlev)
     &               ,' in rebm file'
           else
c             ierr = VFSTLUK(zbuf,ikey, INI, INJ, INK)
              
              if(ini .ne. ni .or. inj .ne. nj) then
                 write(nulout, *)' increment dimension not consistent!'
                 write(nulout, *)' ini= ' , ini, ' ni= ' ,ni, '  inj= ' , inj, ' nj= ' ,nj
              endif
C
              DO  JJ = 1, NJ
                DO JI = 1, NI
                    nposbuf=(jj-1)*ini+ji
                    zvaranal(JI,JLEV,JJ) = zbuf(nposbuf)
                ENDDO
              ENDDO

           endif
        ENDDO !jlev
	
c
c       if required to remove the mean bias of the increments of observed variable, 
c          read the mean increment field 
c
        IF(LREMVE_MEAN_INC)THEN
	
           iip1      = -1
           iip2      = -1
           iip3      = -1
           date0     = -1
           cltypvar = ' '
           cletiket = ' '
c          ibrpstamp=nbrpstamp
c
c          ip1 in the mean increment field after averaging with rdiag may be changed and wrong. do not use that and rather read out 
C              all records in a bunch. assuming it's in the same sequence as the individual incremental field
c
           ierr = fstinl(nulinc_mean, INI,INJ,INK, DATE0,CLETIKET,iip1,iip2,iip3,cltypvar, CVARANAL(JVAR), ikeys, nkeys, maxkeys)
           
           if (ierr.lt.0) then
                   write(nulout,*) 'Problems finding variable '
     &                  ,CVARANAL(JVAR),' in mean increment file'
           else
             write(nulout, *)' number of records in mean incr field =  ' , nkeys, ' number of vlevels =  ' , nflev
             if(nkeys .ne. nflev) call abort3d(nulout,'vertical levels in mean incrment field not consistent!')
	       	      
             DO JLEV = 1, NFLEV
c              IERR = VFSTLIR(ZBUF,nulinc_mean,INI,INJ,INK,DATE0,CLETIKET
c    &             ,NIP1(JLEV),-1,-1,CLTYPVAR,CVARANAL(JVAR))
 
c               ikey = FSTINF(nulinc_mean, INI, INJ, INK, date0, cletiket,
c    &                nip1(jlev), iip2, iip3,cltypvar,CVARANAL(JVAR))
c  

                ierr = VFSTLUK(zbuf,ikeys(jlev), INI, INJ, INK)
              
                 if(ini .ne. ni .or. inj .ne. nj) then
                      write(nulout, *)' increment dimension not consistent with that of mean!'
                      write(nulout, *)' ini= ' , ini, ' ni= ' ,ni, '  inj= ' , inj, ' nj= ' ,nj
                 endif
C
                  DO  JJ = 1, NJ
                    DO JI = 1, NI
                        nposbuf=(jj-1)*ini+ji
                        zvaranal(JI,JLEV,JJ) = zvaranal(JI,JLEV,JJ) - zbuf(nposbuf)
                    ENDDO
                  ENDDO

              ENDDO !jlev	
	    endif
		       
	ENDIF !! LREMVE_MEAN_INC
		
c
C       read in split operator (splitoper)
C
        call ch_rdsplitoper(zoper, instatlev, jvar,SPLITOPER, SPLITOPERD)
C
        if (LDIAGNO) then
C
C          update unobserved variables with diagno splitoper
C

           DO JLAT = 1, NJ
           ILON = NILON(JLAT)
             DO JLON = 1, ILON
                 do jk1=1,NFLEV
                   zvarunobs(jlon,jk1,jlat)= splitoperd(jk1,jlat)*zvaranal(jlon,jk1,jlat)
                 enddo
             END DO
           END DO

        else
C
C          update unobserved variables with non-diagno splitoper (Pux(Pxx)^-1)
C
           DO JLAT = 1, NJ
           ILON = NILON(JLAT)
             DO JLON = 1, ILON
               do jk2=1,NFLEV
                 do jk1=1,NFLEV
                   zvarunobs(jlon,jk1,jlat)=zvarunobs(jlon,jk1,jlat) +
     +                 splitoper(jk1,jk2,jlat)*zvaranal(jlon,jk2,jlat)
                 enddo
               enddo
             END DO
           END DO

        endif 
c
c       store the variable in a big array
c

        do jk1=1,NFLEV
          do ji =1,ni
             do jlat = 1,nj
                zvarout(ji, jlat, jk1, jvar) = zvarunobs(ji,jk1,jlat)                
             enddo
          enddo 
        enddo

      enddo    ! done with jvar 
C
C    writeout the updated unobserved variables to RPN file
c
      call ch_writeunobs (zvarout, ni, nflev, nj, npairs)
C
c    deallocate space
c
      call hpdeallc(pxzoper,ierr,1)
      call hpdeallc(pxzlevstattrg,ierr,1)
      call hpdeallc(ptzvarout, ierr,1)
      call hpdeallc(ptzvaranal,ierr,1)
      call hpdeallc(ptzvarunobs,ierr,1)
      call hpdeallc(ptzbuf,ierr,1)

      WRITE(NULOUT,FMT='(/,4X,"END SPLITTING",//)')

      return
      end