SUBROUTINE split_hdf(fileheader,nxsm,nysm,nz,nzsoil,nstyps, & 8,25
                     buf_r,buf_rsoil4d,buf_i,buf_i16,sstat)
  IMPLICIT NONE
  INCLUDE 'mp.inc'
  INCLUDE 'hdf.f90'    ! HDF4 library include file
  CHARACTER (LEN=*) :: fileheader
  INTEGER ::  nxsm,nysm,nz,nzsoil,nstyps
  INTEGER :: sstat     ! split status: sstat=1 if error encountered
  INTEGER :: nxlg, nylg
!-----------------------------------------------------------------------
!
!  Misc. local variables
!
!-----------------------------------------------------------------------
  CHARACTER (LEN=256) :: filename
  INTEGER :: fi, fj
  INTEGER :: nxin, nyin, nzin,nzsoilin
  REAL :: buf_r(nxsm,nysm,nz)
  REAL :: buf_rsoil4d(nxsm,nysm,nzsoil,0:nstyps)
  INTEGER :: buf_i(nxsm,nysm,nz)
  INTEGER (KIND=selected_int_kind(4)):: buf_i16(nxsm,nysm,nz,0:nstyps)
           ! already assume nz > nzsoil, otherwise there will be trouble
  INTEGER :: sd_id,sd_id2,ndata,nattr,istat,aindex,dindex
  INTEGER :: sds_id,sds_id2,rank,dims(6),dtype,ndattr
  CHARACTER (LEN=256 ) :: name, aname
  CHARACTER (LEN=1024) :: char_attr
  CHARACTER (LEN=1), ALLOCATABLE :: lchar_attr(:)
  INTEGER :: nvalues
  INTEGER :: istart, iend, jstart, jend
  INTEGER :: size(4),start(4),stride(4),startout(4)
  INTEGER :: x_off, y_off
  INTEGER :: comp_code, comp_prm(1)
! fmtver??: to label each data a version.
! intver??: an integer to allow faster comparison than fmtver??,
!           which are strings.
!  
! Version 5.00: significant change in soil variables since version 4.10. 
!
  CHARACTER (LEN=40) :: fmtver,fmtver410a,fmtver500a
  CHARACTER (LEN=40) :: fmtver410b,fmtver500b
  INTEGER  :: intver,intver410,intver500
 
  PARAMETER (fmtver410a='* 004.10 GrADS Soilvar Data',intver410=410)
  PARAMETER (fmtver500a='* 005.00 GrADS Soilvar Data',intver500=500)
  PARAMETER (fmtver410b='004.10 HDF4 Coded Data')
  PARAMETER (fmtver500b='005.00 HDF4 Coded Data')
  CHARACTER (LEN=40) :: fmtverin
!-----------------------------------------------------------------------
!
!  Functions
!
!-----------------------------------------------------------------------
  INTEGER :: sfcreate, sfrdata, sfrnatt, sfscompress, sfselect,  &
     sfsnatt, sfwdata, sfendacc
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  nxlg = (nxsm-3)*nproc_x+3
  nylg = (nysm-3)*nproc_y+3
  stride = 1
  startout = 0
  sstat = 0
!-----------------------------------------------------------------------
!
!  Open the original file, read in its attributes and check the 
!  dimensions in the file against the dimensions passed in.
!
!-----------------------------------------------------------------------
  CALL hdfopen
(trim(fileheader),1,sd_id)
  IF (sd_id < 0) THEN
    WRITE (6,*) "SPLIT_HDF: ERROR opening ",                              &
                 trim(fileheader)," for reading."
    sstat = 1
    RETURN
  END IF
  CALL hdfinfo
(sd_id,ndata,nattr,istat)
  fmtverin = " "
  CALL hdfrdc
(sd_id,40,"fmtver",fmtverin,istat)
! The following code is a dangerous practice
! but it may be the only way to distinguish
! versions prior to 500.
!
  IF (fmtverin == fmtver500a .OR. fmtverin == fmtver500b) THEN
    intver=intver500
  ELSE
    intver=intver410  ! prior to 500, there is no fmtver variable
    istat=0
    WRITE(6,'(/1x,a/,a/,1x,a/,a/)')   &
          'WARNING: Incoming data format are older than version 5.00!!! ', &
          '          It is to be read as if version 4.10!!! ',             &
          'NOTE: Ignore this WARNING for terain data and surface data,',   &
          '       because both have the same format for version 5.00 and 4.10.' 
  END IF
  CALL hdfrdi
(sd_id,"nx",nxin,istat)
  CALL hdfrdi
(sd_id,"ny",nyin,istat)
  IF (nz > 1) THEN
    CALL hdfrdi
(sd_id,"nz",nzin,istat)
  ELSE
    nzin = nz          ! the file is 2-D so it won't have nz
  ENDIF
  IF (nzsoil > 1) THEN ! Soil levels expected.
    IF (intver >= intver500) THEN 
                       ! New version with OUSoil model.
      CALL hdfrdi
(sd_id,"nzsoil",nzsoilin,istat)
    ELSE
      nzsoilin = 2     ! prior to version 500, it is 2 layer soil
    END IF
  ELSE
    nzsoilin = nzsoil
  END IF
  IF ((nxin /= nxlg).OR.(nyin /= nylg).OR.(nzin /= nz).OR. &
      (nzsoilin /= nzsoil)) THEN
    WRITE (*,*) "ERROR:  mismatch in sizes."
    WRITE (*,*) "nxin,nyin,nzin,nzsoilin: ",nxin,nyin,nzin,nzsoilin
    WRITE (*,*) "nxlg,nylg,nz,nzsoil:   ",nxlg,nylg,nz,nzsoil
    sstat = 1
    RETURN
  END IF
  if ( mp_opt > 0 ) then
      istart = loc_x
      iend   = loc_x
      jstart = loc_y
      jend   = loc_y
  else
      istart = 1
      iend   = nproc_x
      jstart = 1
      jend   = nproc_y
  endif
      
! DO fj=1,nproc_y
!   DO fi=1,nproc_x
  DO fj=jstart,jend
    DO fi=istart,iend
      x_off = (fi-1) * (nxsm-3)
      y_off = (fj-1) * (nysm-3)
!-----------------------------------------------------------------------
!
!  Create each split file.
!
!-----------------------------------------------------------------------
      WRITE (filename, '(a,a,2i2.2)')                                   &
            trim(fileheader),'_',fi,fj
      CALL hdfopen
(filename,2,sd_id2)
      IF (sd_id2 < 0) THEN
        WRITE (6,*) "SPLIT_HDF: ERROR creating HDF4 file: ",                  &
                    trim(filename)
        sstat = 1
        GO TO 600
      END IF
!-----------------------------------------------------------------------
!
!  Read/write header info.
!
!-----------------------------------------------------------------------
      DO aindex = 0,nattr-1
        CALL hdfainfo
(sd_id,aindex,name,dtype,nvalues,istat)
        IF (dtype == dfnt_char8) THEN
          IF (nvalues > 1024) THEN
            ALLOCATE (lchar_attr(nvalues))
            CALL hdfrdc
(sd_id,nvalues,name,lchar_attr,istat)
            CALL hdfwrtc
(sd_id2,nvalues,name,lchar_attr,istat)
            DEALLOCATE(lchar_attr)
          ELSE
            CALL hdfrdc
(sd_id,nvalues,name,char_attr,istat)
            CALL hdfwrtc
(sd_id2,nvalues,name,char_attr,istat)
          ENDIF
        ELSE IF (dtype == dfnt_float32) THEN
          !EMK:  Add soil stuff here???
          istat = sfrnatt(sd_id, aindex, buf_r)
          IF (istat /= 0) THEN
            WRITE (6,*) "SPLIT_HDF: ERROR, reading attribute ",trim(name)
            sstat = 1
            GOTO 600
          ENDIF
          istat = sfsnatt(sd_id2, trim(name), dfnt_float32, nvalues, buf_r)
          IF (istat /= 0) THEN
            WRITE (6,*) "SPLIT_HDF: ERROR, writing attribute ",trim(name)
            sstat = 1
            GOTO 600
          ENDIF
        ELSE IF (dtype == dfnt_int32) THEN
          IF (trim(name) == 'nx') THEN 
            CALL hdfwrti
(sd_id2, 'nx', nxsm, istat)
          ELSE IF (trim(name) == 'ny') THEN
            CALL hdfwrti
(sd_id2, 'ny', nysm, istat)
          ELSE
            istat = sfrnatt(sd_id, aindex, buf_i)
            IF (istat /= 0) THEN
              WRITE (6,*) "SPLIT_HDF: ERROR, reading attribute ",trim(name)
              sstat = 1
              GOTO 600
            ENDIF
            istat = sfsnatt(sd_id2, trim(name), dfnt_int32, nvalues, buf_i)
            IF (istat /= 0) THEN
              WRITE (6,*) "SPLIT_HDF: ERROR, writing attribute ",trim(name)
              sstat = 1
              GOTO 600
            ENDIF
          ENDIF
        ELSE
          WRITE (6,*) "SPLIT_HDF: ERROR, unknown data type for ", &
             "attribute ", trim(name)
          sstat = 1
          GOTO 600
        ENDIF
      END DO
!-----------------------------------------------------------------------
!
!  Read/write each data set.
!
!-----------------------------------------------------------------------
      DO dindex = 0,ndata-1
        sds_id = sfselect(sd_id,dindex)
        ! data set
        CALL hdfdinfo
(sds_id,name,rank,dims,dtype,ndattr,istat) 
        start(1) = x_off
        start(2) = y_off
        start(3) = 0
        start(4) = 0 ! EMK Test
        size(1) = nxsm
        size(2) = nysm
        size(3) = dims(3)
!       size(4) = dims(4)  ! EMK Test
        size(4) = nstyps+1 ! KWT Fix
        IF (rank /= 1) THEN         ! x,y,z etc. 1d array do not write comp_prm. 
                                    ! - WYH - why?
          CALL hdfrdi
(sds_id,"hdf_comp_prm",comp_prm,istat)
          IF(comp_prm(1) /= 0) CALL hdfrdi
(sds_id,"hdf_comp_code",comp_code,istat)
        END IF
        IF (rank == 1) THEN
          IF (dtype /= dfnt_float32) THEN
            WRITE (6,*) "SPLIT_HDF: ERROR, unsupported data type for 1-d ",  &
               " variable ",trim(name)
            sstat = 1
            GOTO 600
          ENDIF
          IF (trim(name) == 'x') THEN       ! x
            size(1) = nxsm
            istat = sfrdata(sds_id, start, stride, size, buf_r)
            IF (istat /= 0) THEN
              WRITE (6,*) "SPLIT_HDF: ERROR reading ",trim(name),", exiting"
              sstat = 1
              GOTO 600
            ENDIF
            sds_id2 = sfcreate(sd_id2, trim(name), dfnt_float32, 1, size)
            istat = sfwdata(sds_id2, startout, stride, size, buf_r)
            IF (istat /= 0) THEN
              WRITE (6,*) "SPLIT_HDF: ERROR writing ",trim(name),  &
                 " to file ",trim(filename)," , exiting"
              sstat = 1
              GOTO 600
            ENDIF
          ELSE IF (trim(name) == 'y') THEN  ! y
            start(1) = y_off
            size(1) = nysm
            istat = sfrdata(sds_id, start, stride, size, buf_r)
            IF (istat /= 0) THEN
              WRITE (6,*) "SPLIT_HDF: ERROR reading ",trim(name),", exiting"
              sstat = 1
              GOTO 600
            ENDIF
            sds_id2 = sfcreate(sd_id2, trim(name), dfnt_float32, 1, size)
            istat = sfwdata(sds_id2, startout, stride, size, buf_r)
            IF (istat /= 0) THEN
              WRITE (6,*) "SPLIT_HDF: ERROR writing ",trim(name),  &
                 " to file ",trim(filename)," , exiting"
              sstat = 1
              GOTO 600
            ENDIF
          ELSE IF (trim(name) == 'z') THEN  ! z
            start = 0
            size(1) = nz
            istat = sfrdata(sds_id, start, stride, dims, buf_r)
            IF (istat /= 0) THEN
              WRITE (6,*) "SPLIT_HDF: ERROR reading ",trim(name),", exiting"
              sstat = 1
              GOTO 600
            ENDIF
            sds_id2 = sfcreate(sd_id2, trim(name), dfnt_float32, 1, size)
            istat = sfwdata(sds_id2, startout, stride, size, buf_r)
            IF (istat /= 0) THEN
              WRITE (6,*) "SPLIT_HDF: ERROR writing ",trim(name),  &
                 " to file ",trim(filename)," , exiting"
              sstat = 1
              GOTO 600
            ENDIF
          ELSE                                                      
            start = 0
            startout = 0
            istat = sfrdata(sds_id, start, stride, dims, buf_r)
            IF (istat /= 0) THEN
              WRITE (6,*) "SPLIT_HDF: ERROR reading ",trim(name),", exiting"
              sstat = 1
              GOTO 600
            ENDIF
            sds_id2 = sfcreate(sd_id2, trim(name), dfnt_float32, 1, dims)
            istat = sfwdata(sds_id2, startout, stride, dims, buf_r)
            IF (istat /= 0) THEN
              WRITE (6,*) "SPLIT_HDF: ERROR writing ",trim(name),  &
                 " to file ",trim(filename)," , exiting"
              sstat = 1
              GOTO 600
            ENDIF
          ENDIF
        ELSE 
          IF (dtype == dfnt_float32) THEN
            IF (intver <= intver410 .AND. &
                 (TRIM(name) == "tsfc" .OR. &
                  TRIM(name) == "tsoil" .OR. &
                  TRIM(name) == "wetsfc" .OR. &
                  TRIM(name) == "wetdp")) THEN
              istat = sfrdata(sds_id, start, stride, size, buf_r)
              IF (istat /= 0) THEN
                WRITE (6,*) "SPLIT_HDF: ERROR reading ",trim(name),", exiting"
                sstat = 1
                GOTO 600
              ENDIF
              sds_id2 = sfcreate(sd_id2, trim(name), dfnt_float32, rank, size)
              IF (comp_prm(1) > 0) THEN
                istat = sfscompress(sds_id2, comp_code, comp_prm)
              ENDIF
              istat = sfwdata(sds_id2, startout, stride, size, buf_r)
              IF (istat /= 0) THEN
                WRITE (6,*) "SPLIT_HDF: ERROR writing ",trim(name),  &
                   " to file ",trim(filename)," , exiting"
                sstat = 1
                GOTO 600
              ENDIF
            ELSE IF (intver >= intver500 .AND. &
                      (TRIM(name) == "tsoil" .OR. &
                       TRIM(name) == "qsoil")) THEN
              istat = sfrdata(sds_id, start, stride, size, buf_rsoil4d)
              IF (istat /= 0) THEN
                WRITE (6,*) "SPLIT_HDF: ERROR reading ",trim(name),", exiting"
                sstat = 1
                GOTO 600
              ENDIF
              sds_id2 = sfcreate(sd_id2, trim(name), dfnt_float32, rank, size)
              IF (comp_prm(1) > 0) THEN
                istat = sfscompress(sds_id2, comp_code, comp_prm)
              ENDIF
              istat = sfwdata(sds_id2, startout, stride, size, buf_rsoil4d)
              IF (istat /= 0) THEN
                WRITE (6,*) "SPLIT_HDF: ERROR writing ",trim(name),  &
                   " to file ",trim(filename)," , exiting"
                sstat = 1
                GOTO 600
              ENDIF
            ELSE IF (intver >= intver500 .AND. &
                      (TRIM(name) == "zpsoil")) THEN
              istat = sfrdata(sds_id, start, stride, size, buf_rsoil4d(1,1,1,0))
              IF (istat /= 0) THEN
                WRITE (6,*) "SPLIT_HDF: ERROR reading ",trim(name),", exiting"
                sstat = 1
                GOTO 600
              ENDIF
              sds_id2 = sfcreate(sd_id2, trim(name), dfnt_float32, rank, size)
              IF (comp_prm(1) > 0) THEN
                istat = sfscompress(sds_id2, comp_code, comp_prm)
              ENDIF
              istat = sfwdata(sds_id2, startout, stride, size, buf_rsoil4d(1,1,1,0))
              IF (istat /= 0) THEN
                WRITE (6,*) "SPLIT_HDF: ERROR writing ",trim(name),  &
                   " to file ",trim(filename)," , exiting"
                sstat = 1
                GOTO 600
              ENDIF
            ELSE ! Not a soil variable
              istat = sfrdata(sds_id, start, stride, size, buf_r)
              IF (istat /= 0) THEN
                WRITE (6,*) "SPLIT_HDF: ERROR reading ",trim(name),", exiting"
                sstat = 1
                GOTO 600
              ENDIF
              sds_id2 = sfcreate(sd_id2, trim(name), dfnt_float32, rank, size)
              IF (comp_prm(1) > 0) THEN
                istat = sfscompress(sds_id2, comp_code, comp_prm)
              ENDIF
              istat = sfwdata(sds_id2, startout, stride, size, buf_r)
              IF (istat /= 0) THEN
                WRITE (6,*) "SPLIT_HDF: ERROR writing ",trim(name),  &
                   " to file ",trim(filename)," , exiting"
                sstat = 1
                GOTO 600
              ENDIF
            ENDIF
          ELSE IF (dtype == dfnt_int32) THEN
            istat = sfrdata(sds_id, start, stride, size, buf_i)
            IF (istat /= 0) THEN
              WRITE (6,*) "SPLIT_HDF: ERROR reading ",trim(name),", exiting"
              sstat = 1
              GOTO 600
            ENDIF
            sds_id2 = sfcreate(sd_id2, trim(name), dfnt_int32, rank, size)
            IF (comp_prm(1) > 0) THEN
              istat = sfscompress(sds_id2, comp_code, comp_prm)
            ENDIF
            istat = sfwdata(sds_id2, startout, stride, size, buf_i)
            IF (istat /= 0) THEN
              WRITE (6,*) "SPLIT_HDF: ERROR writing ",trim(name),  &
                 " to file ",trim(filename)," , exiting"
              sstat = 1
              GOTO 600
            ENDIF
          ELSE IF (dtype == dfnt_int16) THEN
            istat = sfrdata(sds_id, start, stride, size, buf_i16)
            IF (istat /= 0) THEN
              WRITE (6,*) "SPLIT_HDF: ERROR reading ",trim(name),", exiting"
              sstat = 1
              GOTO 600
            ENDIF
            sds_id2 = sfcreate(sd_id2, trim(name), dfnt_int16, rank, size)
            IF (comp_prm(1) > 0) THEN
              istat = sfscompress(sds_id2, comp_code, comp_prm)
            ENDIF
            istat = sfwdata(sds_id2, startout, stride, size, buf_i16)
            IF (istat /= 0) THEN
              WRITE (6,*) "SPLIT_HDF: ERROR writing ",trim(name),  &
                 " to file ",trim(filename)," , exiting"
              sstat = 1
              GOTO 600
            ENDIF
          ELSE
            WRITE (6,*) "SPLIT_HDF: ERROR, unknown data type for ", &
               "attribute ", trim(name)
            sstat = 1
            GOTO 600
          ENDIF
        ENDIF
        ! data set attributes
        DO aindex = 0,ndattr-1
          CALL hdfainfo
(sds_id,aindex,aname,dtype,nvalues,istat)
          IF (dtype == dfnt_char8) THEN
            IF (nvalues > 1024) THEN
              ALLOCATE (lchar_attr(nvalues))
              CALL hdfrdc
(sds_id,nvalues,aname,lchar_attr,istat)
              CALL hdfwrtc
(sds_id2,nvalues,aname,lchar_attr,istat)
              DEALLOCATE(lchar_attr)
            ELSE
              CALL hdfrdc
(sds_id,nvalues,aname,char_attr,istat)
              CALL hdfwrtc
(sds_id2,nvalues,aname,char_attr,istat)
            ENDIF
          ELSE IF (dtype == dfnt_float32) THEN
            IF (size(3) == nzsoil) THEN
              istat = sfrnatt(sds_id, aindex, buf_rsoil4d)
              IF (istat /= 0) THEN
                WRITE (6,*) "SPLIT_HDF: ERROR, reading attribute ",trim(aname)
                sstat = 1
                GOTO 600
              ENDIF
              istat = sfsnatt(sds_id2, trim(aname), dfnt_float32, nvalues,&
                              buf_rsoil4d)
              IF (istat /= 0) THEN
                WRITE (6,*) "SPLIT_HDF: ERROR, writing attribute ",trim(aname)
                sstat = 1
                GOTO 600
              ENDIF
            ELSE
              istat = sfrnatt(sds_id, aindex, buf_r)
              IF (istat /= 0) THEN
                WRITE (6,*) "SPLIT_HDF: ERROR, reading attribute ",trim(aname)
                sstat = 1
                GOTO 600
              ENDIF
              istat = sfsnatt(sds_id2, trim(aname), dfnt_float32, nvalues, buf_r)
              IF (istat /= 0) THEN
                WRITE (6,*) "SPLIT_HDF: ERROR, writing attribute ",trim(aname)
                sstat = 1
                GOTO 600
              ENDIF
            END IF
          ELSE IF (dtype == dfnt_int32) THEN
            istat = sfrnatt(sds_id, aindex, buf_i)
            IF (istat /= 0) THEN
              WRITE (6,*) "SPLIT_HDF: ERROR, reading attribute ",trim(aname)
              sstat = 1
              GOTO 600
            ENDIF
            istat = sfsnatt(sds_id2, trim(aname), dfnt_int32, nvalues, buf_i)
            IF (istat /= 0) THEN
              WRITE (6,*) "SPLIT_HDF: ERROR, writing attribute ",trim(aname)
              sstat = 1
              GOTO 600
            ENDIF
          ELSE
            WRITE (6,*) "SPLIT_HDF: ERROR, unknown data type for ", &
               "attribute ", trim(aname)
            sstat = 1
            GOTO 600
          ENDIF
        END DO
        istat = sfendacc(sds_id2)
        IF (istat /= 0) THEN
          WRITE (6,*) "SPLIT_HDF: ERROR writing variable ",trim(name)
        END IF
      END DO ! dindex 
      CALL hdfclose
(sd_id2,istat)
      IF (istat /= 0) THEN
        WRITE (6,*) "SPLIT_HDF: ERROR on close of file ",trim(filename)
        sstat = 1
        GOTO 600
      ENDIF
    END DO ! fi
  END DO ! fj
!-----------------------------------------------------------------------
!
!  Close I/O and return.
!
!----------------------------------------------------------------------
  600   CONTINUE
  CALL hdfclose
(sd_id,istat)
  IF (istat /= 0) THEN
    WRITE (6,*) "SPLIT_HDF: ERROR on close of file ",trim(fileheader)
    sstat = 1
  ENDIF
  RETURN
END SUBROUTINE split_hdf