!########################################################################
!########################################################################
!###### ######
!###### PROGRAM INTQPF ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!########################################################################
!########################################################################
PROGRAM INTQPF,8
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Reads in precipitation data from ARPS history dumps and GRIB
! files, calculates total precipitation, and interpolates the
! data to a new grid.
!
! Based on program INTGRB (NCEP) and program ARPSENSCV (CAPS).
!
! AUTHOR: Eric Kemp, February 2000.
!
! MODIFICATION HISTORY:
! Eric Kemp, March 2000.
! Conversion to FORTRAN 90.
!
! Eric Kemp, 31 March 2000.
! Added lat/lon coordinates of four corners for NCL plotting.
!
!-----------------------------------------------------------------------
!
! Variable Declarations:
!
!-----------------------------------------------------------------------
IMPLICIT NONE
INCLUDE 'globcst.inc' ! FORTRAN 77 include file.
!-----------------------------------------------------------------------
!
! Other variables
!
!-----------------------------------------------------------------------
INTEGER :: intnx,intny
REAL,ALLOCATABLE :: tpcp2d(:,:)
INTEGER,PARAMETER :: maxtimes = 12
REAL :: qswcorn,qswcorw,qnecorn,qnecorw
INTEGER,PARAMETER :: IMAXIN=1200,JJMAXIN=900,JMAXIN=IMAXIN*JJMAXIN
INTEGER,PARAMETER :: IMAXOT=200,JJMAXOT=150,JMAXOT=IMAXOT*JJMAXOT
INTEGER,PARAMETER :: IBUFSIZE = 50000000
INTEGER :: KPDS(25),KGDS(25)
INTEGER :: KPDSO(25),KGDSO(25)
INTEGER :: KPTR(20)
INTEGER :: JSTAT(25),IPOPT(20)
LOGICAL*1 :: KBMS(JMAXIN),KBMSO(JMAXOT)
REAL :: DATA(JMAXIN),DATAO(JMAXOT),RLAT(JMAXOT),RLON(JMAXOT)
REAL :: tpcp(JMAXIN),tpcpint(JMAXOT)
REAL :: tpcpold(JMAXIN)
REAL, ALLOCATABLE, DIMENSION(:,:) :: lat2d,lon2d
REAL :: scswlat,scswlon
REAL :: mapswlat,mapswlon,mapnwlat,mapnwlon
REAL :: mapselat,mapselon,mapnelat,mapnelon
CHARACTER*1 :: IBUF(IBUFSIZE),MSGA(200+17*JMAXIN/8),GDS(400)
CHARACTER :: NFILE*132
INTEGER :: ILEVL,IPDS16,ILVLT,IPARM
INTEGER :: IYEAR,IMON,IDAY,IHR,IFHR1,IFHR2
INTEGER :: date(6)
INTEGER :: IFHRDIFF
INTEGER :: kk,i,kj,iret,IGRID,IERR,KBYTES,MERR,j,ll
INTEGER :: ii,jj
INTEGER :: LUGBIN,LUGBOT,IBI,IJK,NDATA
REAL :: RMAX,RMIN
INTEGER :: LENGDS,JERR2,JSTART,I1,IRCBYTE,KRET
INTEGER :: ko,ibo
INTEGER :: foundpcp,addpcp
INTEGER :: iabssec,isec
INTEGER :: houroday, minohour, dayoweek, dateomon, month, year
INTEGER :: countoutfile,ifile
INTEGER :: lenrun,grbflen,len1
CHARACTER*13 :: gribtime
INTEGER :: kftime,initsec,jabssec
INTEGER :: imin,imo,iyr,jldy
CHARACTER*9 :: julfname
INTEGER :: ifhr,ifmin,ifsec,mfhr
INTEGER :: myr
CHARACTER*9 :: extdfcst
CHARACTER*19 :: extdinit
INTEGER :: ilength
INTEGER :: ijq
REAL,ALLOCATABLE,DIMENSION(:,:) :: x2n,y2n
REAL,PARAMETER :: missing = -9999.
INTEGER :: tt
INTEGER :: timesec(maxtimes),tmptimesec
LOGICAL :: firstfile
INTEGER :: status
INTEGER :: grbflen
INTEGER :: oldifhr1
!-----------------------------------------------------------------------
!
! HDF arrays and variables for output
!
!-----------------------------------------------------------------------
INTEGER,PARAMETER :: flag_p = 0,flag_sfc = 1
INTEGER,PARAMETER :: npreslevel=1,nvar_p=1,nvar_sfc=1
REAL,ALLOCATABLE :: tprecip4d(:,:,:,:)
REAL,ALLOCATABLE :: var_p(:,:,:,:,:)
CHARACTER*4 :: varid_p(nvar_p)
CHARACTER*16 :: varname_p(nvar_p)
CHARACTER*3 :: varunit_p(nvar_p)
REAL,PARAMETER :: pressure(nvar_p) = -9999.
CHARACTER*4,PARAMETER :: varid_tpcp(nvar_sfc) = 'APCP'
CHARACTER*32,PARAMETER :: varname_tpcp(nvar_sfc) = 'Acc. Precip.'
CHARACTER*32,PARAMETER :: varunit_tpcp(nvar_sfc) = 'mm'
REAL :: intscale,inttrulat1,inttrulat2,inttrulon,intdx,intdy, &
intswlat,intswlon
INTEGER :: intmapproj
!-----------------------------------------------------------------------
!
! Namelists
!
!-----------------------------------------------------------------------
INTEGER :: infiletype,arpsfmt,nx,ny,nz,numinfiles
INTEGER :: iimin,iimax,jjmin,jjmax
INTEGER :: sumpcp,timepcpopt,numtimes
INTEGER,PARAMETER :: maxfiles = 36
CHARACTER*29 :: extdtime(maxfiles)
CHARACTER*60 :: dir_extd
CHARACTER*132 :: extdname
CHARACTER*132 :: infilename(maxfiles)
INTEGER :: starthr(maxfiles)
CHARACTER*132 :: outfile
INTEGER :: igrid,interp,nintopt
INTEGER,PARAMETER :: maxintopt = 20
INTEGER :: intopt(maxintopt)
CHARACTER*8 :: model
CHARACTER*4 :: cgrid
NAMELIST /fileinfo/ infiletype,arpsfmt,nx,ny,nz, &
iimin,iimax,jjmin,jjmax, &
sumpcp,timepcpopt,numtimes, &
numinfiles,extdtime, starthr,&
dir_extd,extdname,infilename,outfile,igrid, &
interp,nintopt,intopt,model,cgrid
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
oldifhr1 = 0
kbms = .true.
tmptimesec = 0
DO j = 1,maxtimes
timesec(j) = 0
END DO
firstfile = .true.
foundpcp = 0
addpcp = 0
DO j = 1,jmaxin
tpcp(j) = REAL(0)
tpcpold(j) = REAL(0)
ENDDO
LUGBIN=11
LUGBOT=51
ipopt(1)=-1
ipopt(2)=-1
DO i=3,20
ipopt(i)=0
END DO
WRITE(6,*)'Welcome to program INTQPF. This program reads in'
WRITE(6,*)'gridded precipitation data and interpolates it to'
WRITE(6,*)'another grid.'
WRITE(6,*)
!-----------------------------------------------------------------------
!
! Read input file
!
!-----------------------------------------------------------------------
READ(5,fileinfo,END=100)
100 CONTINUE
!-----------------------------------------------------------------------
!
! Perform some error checking...
!
!-----------------------------------------------------------------------
IF (numinfiles > maxfiles) THEN
WRITE(6,*)'ERROR -- numinfiles > maxfiles'
WRITE(6,*)'Reset maxfiles to ',numinfiles,' and recompile.'
STOP
ENDIF
IF (nintopt > maxintopt) THEN
WRITE(6,*)'ERROR -- nintopt > maxintopt'
WRITE(6,*)'Change nintopt to 0 <= nintopt <= 20'
WRITE(6,*)'nintopt = ',nintopt,' maxintopt = ',maxintopt
STOP
ELSE
DO ll = 1,nintopt
ipopt(ll) = intopt(ll)
ENDDO
ENDIF
IF (sumpcp < 1 .OR. sumpcp > 2) THEN
WRITE(6,*)'INTQPF: ERROR -- Invalid value for sumpcp.'
WRITE(6,*)'sumpcp = ',sumpcp
WRITE(6,*)'Aborting...'
STOP
ENDIF
IF (timepcpopt < 1 .OR. timepcpopt > 3) THEN
WRITE(6,*)'INTQPF: ERROR -- Invalid value for timepcpopt.'
WRITE(6,*)'timepcpopt = ',timepcpopt
WRITE(6,*)'Aborting...'
STOP
ENDIF
IF (numtimes > numinfiles .AND. infiletype == 1 .AND. &
timepcpopt == 3) THEN
WRITE(6,*)'INTQPF: ERROR -- numtimes > numinfiles'
WRITE(6,*)'numtimes = ',numtimes,' numinfiles = ', &
numinfiles
WRITE(6,*)'Aborting...'
STOP
ENDIF
!-----------------------------------------------------------------------
!
! Create GDS information for new grid
!
!-----------------------------------------------------------------------
CALL MAKGDS(IGRID,KGDSO,GDS,LENGDS,IERR)
IF (KGDSO(1) == 1) THEN ! Mercator
intmapproj = 3
intscale = 1.
inttrulat1 = REAL(KGDSO(9))*0.001
inttrulat2 = REAL(KGDSO(9))*0.001
inttrulon = missing ! True lon is not included in GRIB!!!
intdx = REAL(KGDSO(12))
intdy = REAL(KGDSO(13))
intnx = KGDSO(2)
intny = KGDSO(3)
ELSE IF (KGDSO(1) == 3) THEN ! Lambert Conformal
intmapproj = 2
intscale = 1.
inttrulat1 = REAL(KGDSO(12))*0.001
inttrulat2 = REAL(KGDSO(13))*0.001
inttrulon = REAL(KGDSO(7))*0.001
intdx = REAL(KGDSO(8))
intdy = REAL(KGDSO(9))
intnx = KGDSO(2)
intny = KGDSO(3)
ELSE IF (KGDSO(1) == 5) THEN ! Polar Stereographic
intmapproj = 1
intscale = 1.
IF (KGDSO(10).eq.0) THEN ! Northern Hemisphere
inttrulat1 = 60. ! 60. degree latitude in hemisphere
inttrulat2 = 60.
ELSE ! Southern Hemisphere
inttrulat1 = -60.
inttrulat2 = -60.
ENDIF
inttrulon = REAL(KGDSO(7))*0.001
intdx = REAL(KGDSO(8))
intdy = REAL(KGDSO(9))
intnx = KGDSO(2)
intny = KGDSO(3)
ELSE ! New projection doesn't have a dx!
WRITE(6,*)'ERROR: Invalid Map Projection.'
intmapproj = missing
intscale = missing
inttrulat1 = missing
inttrulat2 = missing
inttrulon = missing
intdx = missing
intdy = missing
STOP
ENDIF
!-----------------------------------------------------------------------
!
! Allocate arrays.
!
!-----------------------------------------------------------------------
ALLOCATE(tpcp2d(intnx,intny),lat2d(intnx,intny), &
lon2d(intnx,intny),x2n(intnx,intny),y2n(intnx,intny), &
tprecip4d(intnx,intny,maxtimes,nvar_sfc), &
var_p(intnx,intny,npreslevel,maxtimes,nvar_p), &
STAT=status)
IF (status /= 0) CALL alloc_fail
(status, 'f1')
!-----------------------------------------------------------------------
!
! Loop through the files.
!
!-----------------------------------------------------------------------
countoutfile = 1
tt = 1
DO ifile = 1,numinfiles
IF (tt > maxtimes) THEN
WRITE(6,*)'ERROR: tt > maxtimes'
WRITE(6,*)'Increase maxtimes and recompile'
WRITE(6,*)'tt = ',tt,' maxtimes = ',maxtimes
STOP
ENDIF
!-----------------------------------------------------------------------
!
! Determine the Julian date for the data.
!
!-----------------------------------------------------------------------
READ(extdtime(ifile),'(a19,1x,a9)') extdinit,extdfcst
IF (extdfcst.eq.' ') extdfcst='000:00:00'
READ(extdinit, &
'(i4,1x,i2,1x,i2,1x,i2,1x,i2,1x,i2)',err=920,end=920) &
iyear,imon,iday,ihr,imin,isec
CALL julday
(iyear,imon,iday,jldy)
myr=mod(iyear,100)
ifhr1=0
ifmin=0
ifsec=0
READ(extdfcst, &
'(i3,1x,i2,1x,i2)',err=4,end=4) ifhr1,ifmin,ifsec
4 CONTINUE
mfhr=mod(ifhr1,24)
jldy = jldy + ifhr1/24
WRITE(julfname, &
'(i2.2,i3.3,i2.2,i2.2)') myr,jldy,ihr,mfhr
CALL ctim2abss
(iyear,imon,iday,ihr,imin,isec,iabssec)
jabssec=(ifhr1*3600) + (ifmin*60) + ifsec + iabssec
IF (ifile == 1) THEN
initsec = jabssec
ENDIF
kftime=jabssec-initsec
curtim=float(kftime)
WRITE(6,*)
WRITE(6,'(a,a9,a,/19x,a,a19,a/a,i16,a,/,i26,a)') &
' Calling rdextfil, looking for ', &
extdfcst,' hour forecast ', &
'initialized at ',extdinit,' UTC', &
' Which is ',jabssec,' abs seconds or ',kftime, &
' seconds from the ARPS initial time.'
!-----------------------------------------------------------------------
!
! Get precipitation data.
!
!-----------------------------------------------------------------------
IF (infiletype == 1) THEN ! GRIB
len1=LEN(dir_extd)
grbflen=len1
CALL strlnth
( dir_extd, grbflen )
IF( grbflen .EQ. 0 .OR. dir_extd(1:grbflen) .EQ. ' ' ) THEN
dir_extd = '.'
grbflen=1
END IF
IF( dir_extd(grbflen:grbflen) .NE. '/'.AND. &
grbflen .LT. len1) THEN
grbflen=grbflen+1
dir_extd(grbflen:grbflen)='/'
END IF
CALL strlnth
( dir_extd, grbflen )
NFILE = dir_extd(1:grbflen)//'/'//infilename(ifile)
ifhr2 = ifhr1
ifhr1 = starthr(ifile)
IF (ifhr1 /= oldifhr1 .AND. timepcpopt == 1) THEN
tpcpold = 0 ! Reset previous accumulation to zero.
END IF
CALL rdgrbqpf(sumpcp,timepcpopt,numtimes, &
tpcp,tpcpold,foundpcp,addpcp,gribtime, &
dir_extd,nfile,kgds, &
ibi,kbms,iyear,imon,iday,ihr,ifhr1,ifhr2, &
jmaxin,ibufsize)
oldifhr1 = ifhr1
IF (IFHR2 > IFHR1) THEN
tmptimesec = (IFHR2*3600) - (IFHR1*3600) + tmptimesec
ELSE
tmptimesec = (IFHR1*3600)
END IF
timesec(tt) = tmptimesec
ELSEIF (infiletype == 2) THEN ! ARPS history dump
IF ((nx*ny).gt.JMAXIN) THEN
WRITE(6,*)'ERROR: Dimensions of ARPS history dump '
WRITE(6,*)'are larger than JMAXIN. Reset JMAXIN to'
WRITE(6,*)'be larger than nx*ny and recompile.'
WRITE(6,*)'JMAXIN = ',JMAXIN,' nx*ny = ',nx*ny
WRITE(6,*)'Aborting...'
STOP
ENDIF
CALL rdarpsqpf
(nx,ny,nz,tpcp,tpcpold,foundpcp,addpcp,nfile, &
kgds,ibi,kbms,iyear,imon,iday,ihr,ifhr1, &
ifhr2,jmaxin,ibufsize,dir_extd,extdname, &
extdfcst,arpsfmt,iimin,iimax,jjmin,jjmax)
tmptimesec = (IFHR2*3600) - (IFHR1*3600)
timesec(tt) = tmptimesec
ELSE
WRITE(6,*)'ERROR -- Invalid selection for infiletype.'
WRITE(6,*)'infiletype = ',infiletype
WRITE(6,*)'Aborting...'
STOP
ENDIF
IF (firstfile) THEN
date(1) = IYEAR
date(2) = IMON
date(3) = IDAY
date(4) = IHR
date(5) = 0
date(6) = 0
WRITE(6,*)'Date = ',date
firstfile = .FALSE.
ENDIF
!-----------------------------------------------------------------------
!
! Interpolate field if precipitation data is ready.
!
!-----------------------------------------------------------------------
IF (foundpcp == 1) THEN
WRITE(6,*)'Interpolating precipitation field...'!EMK
WRITE(6,*)
CALL ipolates(interp,ipopt,kgds,kgdso,jmaxin,jmaxot,1,ibi, &
kbms,tpcp,ko,rlat,rlon,ibo,kbmso,datao,iret)
kbms = .true. ! Reset bit map
foundpcp = 0
addpcp = 0
countoutfile = countoutfile + 1
!-----------------------------------------------------------------------
!
! Dump 1-D interpolated precip array into 2-D array.
!
!-----------------------------------------------------------------------
IF (intnx /= kgdso(2).OR. intny /= kgdso(3)) THEN
WRITE(6,*)'INTGRB: ERROR -- Output dimensions from '
WRITE(6,*)'subroutine IPOLATES does not match those '
WRITE(6,*)'set in the main program. Reset intnx and '
WRITE(6,*)'intny and then recompile.'
WRITE(6,*)'intnx = ',intnx,' kgdso(2) = ',kgdso(2)
WRITE(6,*)'intny = ',intny,' kgdso(3) = ',kgdso(3)
STOP
ELSE
kk = 1
DO jj = 1,intny
DO ii = 1,intnx
IF (kbmso(kk)) THEN
tprecip4d(ii,jj,tt,1) = datao(kk)
lat2d(ii,jj) = rlat(kk)
lon2d(ii,jj) = rlon(kk)
ELSE
tprecip4d(ii,jj,tt,1) = missing
lat2d(ii,jj) = rlat(kk)
lon2d(ii,jj) = rlon(kk)
ENDIF
kk = kk + 1
END DO
END DO
tt = tt + 1
qswcorn = rlat(1)
qswcorw = rlon(1) - 360.
qnecorn = rlat(ko)
qnecorw = rlon(ko) -360.
ENDIF
DO kk=1,25
kpdso(kk)=kpds(kk)
ENDDO
kpdso(3)=igrid
kpdso(4)=128+64*ibo
IF (timepcpopt == 3 .AND. infiletype == 1) THEN
tpcpold = 0.
ENDIF
ENDIF
ENDDO
!-----------------------------------------------------------------------
!
! Dump interpolated precip. field to HDF file.
!
!-----------------------------------------------------------------------
IF (intmapproj /= missing .AND. intscale /= missing .AND. &
inttrulat1 /= missing .AND. inttrulat2 /= missing .AND. &
inttrulon /= missing .AND. intdx /= missing .AND. &
intdy /= missing) THEN
tt = tt - 1
scswlat = lat2d(1,1)
scswlon = lon2d(1,1) - 360.
CALL qpfmcorn
(intmapproj,intscale,inttrulat1,inttrulat2, &
inttrulon,intdx,intdy,intnx,intny,&
lat2d,lon2d, &
1,intnx,1,intny, &
mapswlat,mapswlon,mapnwlat,mapnwlon, &
mapselat,mapselon,mapnelat,mapnelon)
CALL wrtverif
(intnx,intny,npreslevel,tt,nvar_p,nvar_sfc,missing, &
outfile,model,cgrid,date,timesec,pressure, &
intmapproj,intscale,inttrulat1,inttrulat2, &
inttrulon,intdx,intdy,scswlat,scswlon, &
mapswlat,mapswlon,mapnwlat,mapnwlon, &
mapselat,mapselon,mapnelat,mapnelon, &
flag_p,varid_p, varname_p, varunit_p, var_p, &
flag_sfc,varid_tpcp, varname_tpcp, varunit_tpcp, &
tprecip4d)
ELSE
WRITE(6,*)'ERROR: Missing some grid information'
STOP
ENDIF
!-----------------------------------------------------------------------
!
! The end.
!
!-----------------------------------------------------------------------
WRITE(6,*)'Program INTQPF completed.'
STOP
!-----------------------------------------------------------------------
!
! Problem doing time conversions.
!
!-----------------------------------------------------------------------
920 CONTINUE
WRITE(6,*) &
' Aborting, error in time format for external file', &
' External file time provided:',extdtime
STOP
END PROGRAM INTQPF