!######################################################################## !######################################################################## !###### ###### !###### 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