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