subroutine count_recs_wrf_binary_file(in_unit,wrf_ges_filename,nrecs) !$$$ subprogram documentation block ! . . . . ! subprogram: count_recs_binary_file count # recs on wrf binary file ! prgmmr: parrish org: np22 date: 2004-11-29 ! ! abstract: count number of sequential records contained in wrf binary ! file. this is done by opening the file in direct access ! mode with block length of 2**20, the size of the physical ! blocks on ibm "blue" and "white" machines. for optimal ! performance, change block length to correspond to the ! physical block length of host machine disk space. ! records are counted by looking for the 4 byte starting ! and ending sequential record markers, which contain the ! record size in bytes. only blocks are read which are known ! by simple calculation to contain these record markers. ! even though this is done on one processor, it is still ! very fast, and the time will always scale by the number of ! sequential records, not their size. this step and the ! following inventory step consistently take less than 0.1 seconds ! to complete. ! ! program history log: ! 2004-11-29 parrish ! ! input argument list: ! in_unit - fortran unit number where input file is opened through. ! wrf_ges_filename - filename of input wrf binary restart file ! ! output argument list: ! nrecs - number of sequential records found on input wrf binary restart fil ! ! attributes: ! language: f90 ! machine: ibm RS/6000 SP ! !$$$ ! do an initial read through of a wrf binary file, and get total number of sequential fil use kinds, only: r_single,i_byte,i_long,i_llong implicit none integer,intent(in)::in_unit character(*),intent(in)::wrf_ges_filename integer,intent(out)::nrecs integer(i_llong) nextbyte,locbyte,thisblock integer(i_byte) lenrec4(4) integer(i_long) lenrec,lensave equivalence (lenrec4(1),lenrec) integer(i_byte) missing4(4) integer(i_long) missing equivalence (missing,missing4(1)) integer(i_llong),parameter:: lrecl=2**20 integer(i_byte) buf(lrecl) integer i,loc_count,nreads logical lastbuf open(in_unit,file=trim(wrf_ges_filename),access='direct',recl=lrecl) nrecs=0 missing=-9999 nextbyte=0_i_llong locbyte=lrecl nreads=0 lastbuf=.false. do ! get length of next record do i=1,4 nextbyte=nextbyte+1_i_llong locbyte=locbyte+1_i_llong if(locbyte > lrecl .and. lastbuf) go to 900 if(locbyte > lrecl) call next_buf(in_unit,buf,nextbyte,locbyte,thisblock,lrecl,nreads,lastbuf) lenrec4(i)=buf(locbyte) end do if(lenrec <= 0 .and. lastbuf) go to 900 if(lenrec <= 0 .and. .not.lastbuf) go to 885 nextbyte=nextbyte+1_i_llong locbyte=locbyte+1_i_llong if(locbyte > lrecl .and. lastbuf) go to 900 if(locbyte > lrecl) call next_buf(in_unit,buf,nextbyte,locbyte,thisblock,lrecl,nreads,lastbuf) nrecs=nrecs+1 loc_count=1 do i=2,4 if(loc_count.ge.lenrec) exit loc_count=loc_count+1 nextbyte=nextbyte+1_i_llong locbyte=locbyte+1_i_llong if(locbyte > lrecl .and. lastbuf) go to 900 if(locbyte > lrecl) call next_buf(in_unit,buf,nextbyte,locbyte,thisblock,lrecl,nreads,lastbuf) end do do i=1,4 if(loc_count.ge.lenrec) exit loc_count=loc_count+1 nextbyte=nextbyte+1_i_llong locbyte=locbyte+1_i_llong if(locbyte > lrecl .and. lastbuf) go to 900 if(locbyte > lrecl) call next_buf(in_unit,buf,nextbyte,locbyte,thisblock,lrecl,nreads,lastbuf) end do nextbyte=nextbyte-loc_count+lenrec locbyte=locbyte-loc_count+lenrec if(locbyte > lrecl .and. lastbuf) go to 900 if(locbyte > lrecl) call next_buf(in_unit,buf,nextbyte,locbyte,thisblock,lrecl,nreads,lastbuf) lensave=lenrec do i=1,4 nextbyte=nextbyte+1_i_llong locbyte=locbyte+1_i_llong if(locbyte > lrecl .and. lastbuf) go to 900 if(locbyte > lrecl) call next_buf(in_unit,buf,nextbyte,locbyte,thisblock,lrecl,nreads,lastbuf) lenrec4(i)=buf(locbyte) end do if(lenrec /= lensave) go to 890 end do 880 continue write(6,*)' reached impossible place in count_recs_wrf_binary_file' close(in_unit) return 885 continue write(6,*)' problem in count_recs_wrf_binary_file, lenrec has bad value before end of file' write(6,*)' lenrec =',lenrec close(in_unit) return 890 continue write(6,*)' problem in count_recs_wrf_binary_file, beginning and ending rec len words unequal' write(6,*)' begining reclen =',lensave write(6,*)' ending reclen =',lenrec close(in_unit) return 900 continue write(6,*)' normal end of file reached in count_recs_wrf_binary_file' write(6,*)' nblocks=',thisblock write(6,*)' nrecs=',nrecs write(6,*)' nreads=',nreads close(in_unit) end subroutine count_recs_wrf_binary_file