!######################################################################## !######################################################################## !###### ###### !###### PROGRAM QPFSTATS ###### !###### ###### !###### Developed by ###### !###### Center for Analysis and Prediction of Storms ###### !###### University of Oklahoma ###### !###### ###### !######################################################################## !######################################################################## PROGRAM QPFSTATS,19 !----------------------------------------------------------------------- ! ! PURPOSE: ! ! Reads in two HDF files created by INTQPF (a forecast and a ! verification) and a binary bit map created by QPFMASK. The precip. ! fields in the HDF files extracted, bias and equitable threat score ! are calculated, and the statistics are output. ! ! AUTHOR: Eric Kemp, March 2000 ! ! MODIFICATION HISTORY: ! Eric Kemp, 31 March 2000. ! Added lat/lon coordinates of four corners for NCL plotting. ! !----------------------------------------------------------------------- ! ! Variable declarations ! !----------------------------------------------------------------------- IMPLICIT NONE !----------------------------------------------------------------------- ! ! Forecast variables ! !----------------------------------------------------------------------- INTEGER :: fdate(6) INTEGER,ALLOCATABLE :: ftimesec(:) INTEGER :: fmapproj REAL :: fscale REAL :: ftrulat1, ftrulat2, ftrulon REAL :: fdx,fdy CHARACTER*8 :: fmodel CHARACTER*4 :: fgrid CHARACTER*4,ALLOCATABLE,DIMENSION(:) :: fid_p,fid_sfc CHARACTER*32,ALLOCATABLE,DIMENSION(:) :: fname_p,funit_p,fname_sfc, & funit_sfc REAL,ALLOCATABLE, DIMENSION(:,:,:,:,:) :: fvar_p REAL,ALLOCATABLE, DIMENSION(:,:,:,:) :: fvar_sfc REAL,ALLOCATABLE, DIMENSION(:) :: fpressure REAL,ALLOCATABLE, DIMENSION(:,:) :: flat2d,flon2d REAL :: fscswlat,fscswlon REAL :: fmapswlat,fmapswlon,fmapnwlat,fmapnwlon, & fmapselat,fmapselon,fmapnelat,fmapnelon INTEGER :: fflag_p,fflag_sfc REAL,ALLOCATABLE, DIMENSION(:,:,:) :: fprecip INTEGER :: fnx,fny,fntime INTEGER :: fnpreslevel,fnvar_p,fnvar_sfc !----------------------------------------------------------------------- ! ! Verification variables ! !----------------------------------------------------------------------- INTEGER :: vdate(6) INTEGER,ALLOCATABLE :: vtimesec(:) INTEGER :: vmapproj REAL :: vscale REAL :: vtrulat1, vtrulat2, vtrulon REAL :: vdx,vdy CHARACTER*8 :: vmodel CHARACTER*4 :: vgrid CHARACTER*4,ALLOCATABLE,DIMENSION(:) :: vid_p,vid_sfc CHARACTER*32,ALLOCATABLE,DIMENSION(:) :: vname_p,vunit_p,vname_sfc, & vunit_sfc REAL,ALLOCATABLE, DIMENSION(:,:,:,:,:) :: vvar_p REAL,ALLOCATABLE, DIMENSION(:,:,:,:) :: vvar_sfc REAL,ALLOCATABLE, DIMENSION(:) :: vpressure REAL,ALLOCATABLE, DIMENSION(:,:) :: vlat2d,vlon2d REAL :: vscswlat,vscswlon REAL :: vmapswlat,vmapswlon,vmapnwlat,vmapnwlon, & vmapselat,vmapselon,vmapnelat,vmapnelon INTEGER :: vflag_p,vflag_sfc REAL,ALLOCATABLE, DIMENSION(:,:,:) :: vprecip INTEGER :: vnx,vny,vntime INTEGER :: vnpreslevel,vnvar_p,vnvar_sfc !----------------------------------------------------------------------- ! ! Bitmap variables ! !----------------------------------------------------------------------- INTEGER :: mdate(6) INTEGER,ALLOCATABLE :: mtimesec(:) INTEGER :: mmapproj REAL :: mscale REAL :: mtrulat1, mtrulat2, mtrulon REAL :: mdx,mdy CHARACTER*8 :: mmodel CHARACTER*4 :: mgrid CHARACTER*4,ALLOCATABLE,DIMENSION(:) :: mid_p,mid_sfc CHARACTER*32,ALLOCATABLE,DIMENSION(:) :: mname_p,munit_p,mname_sfc, & munit_sfc REAL,ALLOCATABLE, DIMENSION(:,:,:,:,:) :: mvar_p REAL,ALLOCATABLE, DIMENSION(:,:,:,:) :: mvar_sfc REAL,ALLOCATABLE, DIMENSION(:) :: mpressure REAL,ALLOCATABLE, DIMENSION(:,:) :: mlat2d,mlon2d REAL :: mscswlat,mscswlon REAL :: mmapswlat,mmapswlon,mmapnwlat,mmapnwlon, & mmapselat,mmapselon,mmapnelat,mmapnelon INTEGER :: mflag_p,mflag_sfc INTEGER,ALLOCATABLE, DIMENSION(:,:) :: mask INTEGER :: mnx,mny,mntime INTEGER :: mnpreslevel,mnvar_p,mnvar_sfc INTEGER :: found_mask !----------------------------------------------------------------------- ! ! Other variables ! ! NOTE: CTA = array of "yes" forecast, "yes" observation grid points ! CTB = array of "yes" forecast, "no" observation grid points ! CTC = array of "no" forecast, "yes" observation grid points ! CTD = array of "no" forecast, "no" observation grid points ! ! Reference: Wilks, D. S., 1995: Statistical Methods in the ! Atmospheric Sciences. Academic Press, 476pp. ! !----------------------------------------------------------------------- REAL,ALLOCATABLE :: ets(:,:),bias(:,:) INTEGER,ALLOCATABLE :: CTA(:,:),CTB(:,:),CTC(:,:),CTD(:,:) INTEGER :: status,i,j,k,l REAL :: factor REAL,PARAMETER :: missing = -9999. INTEGER,PARAMETER :: nstat = 2 CHARACTER*4,ALLOCATABLE,DIMENSION(:) :: ctstatsid CHARACTER*32,ALLOCATABLE,DIMENSION(:) :: ctstatsname REAL,ALLOCATABLE,DIMENSION(:,:,:) :: ctstats CHARACTER*32 :: threshunit CHARACTER*72,PARAMETER :: line72 = & '------------------------------------------------------------------------' REAL :: vtrulat(2) REAL,ALLOCATABLE :: vxsc(:),vysc(:) REAL :: vx0,vy0 !----------------------------------------------------------------------- ! ! Namelists ! !----------------------------------------------------------------------- CHARACTER*256 :: finfilename NAMELIST /hdf_finput/ finfilename CHARACTER*256 :: vinfilename NAMELIST /hdf_vinput/ vinfilename CHARACTER*256 :: minfilename NAMELIST /bitmap/ minfilename INTEGER :: precipunit INTEGER :: numthresh INTEGER,PARAMETER :: maxnumthresh = 10 REAL :: thresh(maxnumthresh) NAMELIST /threshold/ precipunit,numthresh,thresh CHARACTER*256 :: hdfoutfilename,ascoutfilename NAMELIST /output/ hdfoutfilename,ascoutfilename !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! ! Beginning of executable code... ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ fmodel='' vmodel='' WRITE(6,'(//5x,a)') & &'###################################################################' WRITE(6,'(5x,a,/5x,a)') & &'# #',& &'# Welcome to QPFSTATS, a program that reads in two precip. HDF #' WRITE(6,'(5x,a)') & &'# files from INTQPF and a binary bitmap file from QPFMASK, and #' WRITE(6,'(5x,a)') & &'# calculates equitable threat score and bias statistics. #', & &'# #',& &'###################################################################' WRITE(6,*) !----------------------------------------------------------------------- ! ! Read in namelist ! !----------------------------------------------------------------------- PRINT *, 'Reading NAMELIST hdf_finput' READ(5,hdf_finput) PRINT *, 'Reading NAMELIST hdf_vinput' READ(5,hdf_vinput) PRINT *, 'Reading NAMELIST bitmap' READ(5,bitmap) PRINT *, 'Reading NAMELIST threshold' READ(5,threshold) PRINT *, 'Reading NAMELIST output' READ(5,output) WRITE(6,*)'EMK: thresh = ',thresh IF (numthresh > maxnumthresh) THEN WRITE(6,*)'ERROR: numthresh > maxnumthresh' WRITE(6,*)'Change maxnumthresh and recompile.' WRITE(6,*)'numthresh = ',numthresh,' maxnumthresh = ', & maxnumthresh WRITE(6,*)'Aborting...' STOP END IF IF (precipunit /= 1 .AND. precipunit /= 2) THEN WRITE(6,*)'ERROR: Invalid precipunit value' WRITE(6,*)'precipunit = ',precipunit WRITE(6,*)'Aborting...' STOP ENDIF !----------------------------------------------------------------------- ! ! Read forecast precipitation data. ! !----------------------------------------------------------------------- CALL rd_verif_dims(fnx,fny,fnpreslevel,fntime,fnvar_p,fnvar_sfc, & finfilename) ALLOCATE (ftimesec(fntime), fpressure(fnpreslevel), & fvar_p(fnx,fny,fnpreslevel,fntime,fnvar_p), & fvar_sfc(fnx,fny,fntime,fnvar_sfc), & flat2d(fnx,fny),flon2d(fnx,fny), & fprecip(fnx,fny,fntime), & fid_p(fnvar_p),fname_p(fnvar_p),funit_p(fnvar_p), & fid_sfc(fnvar_sfc),fname_sfc(fnvar_sfc), & funit_sfc(fnvar_sfc), & STAT=status) IF (status /= 0) CALL alloc_fail (status, 'f1') CALL rdverif ( fnx,fny,fnpreslevel,fntime,fnvar_p,fnvar_sfc, & finfilename,fmodel,fgrid,fdate,ftimesec,fpressure, & fmapproj,fscale,ftrulat1,ftrulat2,ftrulon,fdx,fdy, & fscswlat,fscswlon, & fmapswlat,fmapswlon,fmapnwlat,fmapnwlon, & fmapselat,fmapselon,fmapnelat,fmapnelon, & fflag_p,fvar_p, fid_p, fname_p, funit_p, & fflag_sfc,fvar_sfc, fid_sfc, fname_sfc, funit_sfc ) IF (fflag_sfc == 0) THEN WRITE(6,*)'ERROR: Could not find surface data in HDF file.' WRITE(6,*)'Aborting...' STOP ENDIF !----------------------------------------------------------------------- ! ! Read verification precipitation data. ! !----------------------------------------------------------------------- CALL rd_verif_dims(vnx,vny,vnpreslevel,vntime,vnvar_p,vnvar_sfc, & vinfilename) ALLOCATE (vtimesec(vntime), vpressure(vnpreslevel), & vvar_p(vnx,vny,vnpreslevel,vntime,vnvar_p), & vvar_sfc(vnx,vny,vntime,vnvar_sfc), & vlat2d(vnx,vny),vlon2d(vnx,vny), & vprecip(vnx,vny,vntime), & vid_p(vnvar_p),vname_p(vnvar_p),vunit_p(vnvar_p), & vid_sfc(vnvar_sfc),vname_sfc(vnvar_sfc), & vunit_sfc(vnvar_sfc), & STAT=status) IF (status /= 0) CALL alloc_fail (status, 'f1') CALL rdverif ( vnx,vny,vnpreslevel,vntime,vnvar_p,vnvar_sfc, & vinfilename,vmodel,vgrid,vdate,vtimesec,vpressure, & vmapproj,vscale,vtrulat1,vtrulat2,vtrulon,vdx,vdy, & vscswlat,vscswlon, & vmapswlat,vmapswlon,vmapnwlat,vmapnwlon, & vmapselat,vmapselon,vmapnelat,vmapnelon, & vflag_p,vvar_p, vid_p, vname_p, vunit_p, & vflag_sfc,vvar_sfc, vid_sfc, vname_sfc, vunit_sfc ) IF (vflag_sfc == 0) THEN WRITE(6,*)'ERROR: Could not find surface data in HDF file.' WRITE(6,*)'Aborting...' STOP ENDIF !----------------------------------------------------------------------- ! ! Check dimensions, map projection, etc. of forecast and verification. ! !----------------------------------------------------------------------- IF (fnx /= vnx .OR. fny /= vny .OR. fntime /= vntime .OR. & fscale /= vscale .OR. & ftrulat1 /= vtrulat1 .OR. ftrulat2 /= vtrulat2 .OR. & ftrulon /= vtrulon .OR. fdx /= vdx .OR. fdy /= vdy .OR. & fscswlat /= vscswlat .OR. fscswlon /= vscswlon) THEN WRITE(6,*)'ERROR: Grid information for forecast and verification' WRITE(6,*)'data do not match!' WRITE(6,*)'fnx = ',fnx,' vnx = ',vnx WRITE(6,*)'fny = ',fny,' vny = ',vny WRITE(6,*)'fscale = ',fscale,' vscale = ',vscale WRITE(6,*)'ftrulat1 = ',ftrulat1,' vtrulat1 = ',vtrulat1 WRITE(6,*)'ftrulat2 = ',ftrulat2,' vtrulat2 = ',vtrulat2 WRITE(6,*)'ftrulon = ',ftrulon,' vtrulon = ',vtrulon WRITE(6,*)'fdx = ',fdx,' vdx = ',vdx WRITE(6,*)'fdy = ',fdy,' vdy = ',vdy WRITE(6,*)'fscswlat = ',fscswlat,' vscswlat = ',vscswlat WRITE(6,*)'fscswlon = ',fscswlon,' vscswlon = ',vscswlon WRITE(6,*) WRITE(6,*)'Aborting...' STOP END IF DO i=1,6 IF (fdate(i) /= vdate(i)) THEN PRINT *, 'FATAL: Forecast and analysis start dates do not match' PRINT *, 'fdate= ', fdate PRINT *, 'vdate= ', vdate STOP END IF END DO !----------------------------------------------------------------------- ! ! Read bitmap file. ! !----------------------------------------------------------------------- CALL rd_verif_dims(mnx,mny,mnpreslevel,mntime,mnvar_p,mnvar_sfc, & minfilename) ALLOCATE (mtimesec(mntime), mpressure(mnpreslevel), & mvar_p(mnx,mny,mnpreslevel,mntime,mnvar_p), & mvar_sfc(mnx,mny,mntime,mnvar_sfc), & mlat2d(mnx,mny),mlon2d(mnx,mny), & mid_p(mnvar_p),mname_p(mnvar_p),munit_p(mnvar_p), & mid_sfc(mnvar_sfc),mname_sfc(mnvar_sfc), & munit_sfc(mnvar_sfc), & STAT=status) IF (status /= 0) CALL alloc_fail (status, 'f1') CALL rdverif ( mnx,mny,mnpreslevel,mntime,mnvar_p,mnvar_sfc, & minfilename,mmodel,mgrid,mdate,mtimesec,mpressure, & mmapproj,mscale,mtrulat1,mtrulat2,mtrulon,mdx,mdy, & mscswlat,mscswlon, & mmapswlat,mmapswlon,mmapnwlat,mmapnwlon, & mmapselat,mmapselon,mmapnelat,mmapnelon, & mflag_p,mvar_p, mid_p, mname_p, munit_p, & mflag_sfc,mvar_sfc, mid_sfc, mname_sfc, munit_sfc ) IF (mflag_sfc == 0) THEN WRITE(6,*)'ERROR: Could not find bitmap data in HDF file.' WRITE(6,*)'Aborting...' STOP ENDIF !----------------------------------------------------------------------- ! ! Check dimensions, map projection, etc. of bitmap and verification ! !----------------------------------------------------------------------- IF (mnx /= vnx .OR. mny /= vny .OR. mntime /= vntime .OR. & mscale /= vscale .OR. & mtrulat1 /= vtrulat1 .OR. mtrulat2 /= vtrulat2 .OR. & mtrulon /= vtrulon .OR. mdx /= vdx .OR. mdy /= vdy .OR. & mscswlat /= vscswlat .OR. mscswlon /= vscswlon) THEN WRITE(6,*)'ERROR: Grid information for bitmap and verification' WRITE(6,*)'data do not match!' WRITE(6,*)'mnx = ',mnx,' vnx = ',vnx WRITE(6,*)'mny = ',mny,' vny = ',vny WRITE(6,*)'mscale = ',mscale,' vscale = ',vscale WRITE(6,*)'mtrulat1 = ',mtrulat1,' vtrulat1 = ',vtrulat1 WRITE(6,*)'mtrulat2 = ',mtrulat2,' vtrulat2 = ',vtrulat2 WRITE(6,*)'mtrulon = ',mtrulon,' vtrulon = ',vtrulon WRITE(6,*)'mdx = ',mdx,' vdx = ',vdx WRITE(6,*)'mdy = ',mdy,' vdy = ',vdy WRITE(6,*)'mscswlat = ',mscswlat,' vscswlat = ',vscswlat WRITE(6,*)'mscswlon = ',mscswlon,' vscswlon = ',vscswlon WRITE(6,*) WRITE(6,*)'Aborting...' STOP END IF !----------------------------------------------------------------------- ! ! Dump HDF data into precip arrays, changing units as necessary. ! !----------------------------------------------------------------------- DO i = 1,fnvar_sfc IF (fid_sfc(i) == 'APCP') THEN IF (funit_sfc(i) == 'mm' .AND. precipunit == 1) THEN fprecip = fvar_sfc(:,:,:,i) ELSE IF (funit_sfc(i) == 'mm' .AND. precipunit == 2) THEN fprecip = fvar_sfc(:,:,:,i) factor = 39.37/1000. CALL cvtpcpunit(fnx,fny,fntime,fprecip,factor,missing) ELSE IF (funit_sfc(i) == 'in' .AND. precipunit == 2) THEN fprecip = fvar_sfc(:,:,:,i) ELSE IF (funit_sfc(i) == 'in' .AND. precipunit == 1) THEN fprecip = fvar_sfc(:,:,:,i) factor = 1000./39.37 CALL cvtpcpunit(fnx,fny,fntime,fprecip,factor,missing) ELSE WRITE(6,*)'ERROR: funit_sfc = ',funit_sfc STOP ENDIF ENDIF END DO DO i = 1,vnvar_sfc IF (vid_sfc(i) == 'APCP') THEN IF (vunit_sfc(i) == 'mm' .AND. precipunit == 1) THEN vprecip = vvar_sfc(:,:,:,i) ELSE IF (vunit_sfc(i) == 'mm' .AND. precipunit == 2) THEN vprecip = vvar_sfc(:,:,:,i) factor = 39.37/1000. CALL cvtpcpunit(vnx,vny,vntime,vprecip,factor,missing) ELSE IF (vunit_sfc(i) == 'in' .AND. precipunit == 2) THEN vprecip = vvar_sfc(:,:,:,i) ELSE IF (vunit_sfc(i) == 'in' .AND. precipunit == 1) THEN vprecip = vvar_sfc(:,:,:,i) factor = 1000./39.37 CALL cvtpcpunit(vnx,vny,vntime,vprecip,factor,missing) ELSE WRITE(6,*)'ERROR: vunit_sfc = ',vunit_sfc STOP ENDIF ENDIF END DO !----------------------------------------------------------------------- ! ! Dump HDF bitmap data into mask array. ! !----------------------------------------------------------------------- ALLOCATE (mask(mnx,mny),STAT=status) IF (status /= 0) CALL alloc_fail (status, 'f1') mask = missing found_mask = 0 DO i = 1,mnvar_sfc IF (mid_sfc(i) == 'MASK') THEN mask = INT(mvar_sfc(:,:,1,i)) found_mask = 1 END IF END DO IF (found_mask == 0) THEN WRITE(6,*)'ERROR: Could not find bitmap. Aborting...' STOP END IF !----------------------------------------------------------------------- ! ! Calculate equitable threat score and bias ! !----------------------------------------------------------------------- ALLOCATE (bias(vntime,numthresh),ets(vntime,numthresh), & CTA(vntime,numthresh),CTB(vntime,numthresh), & CTC(vntime,numthresh),CTD(vntime,numthresh), & STAT=status) IF (status /= 0) CALL alloc_fail (status, 'f1') CALL calcetsb(vnx,vny,vntime,vprecip,fprecip,numthresh,thresh, & mask,bias,ets,CTA,CTB,CTC,CTD) 100 FORMAT(1x,a,f4.2,a) 110 FORMAT(1x,A,i5,A,i5,A,i5) !----------------------------------------------------------------------- ! ! Dump statistical data to a new HDF file. ! !----------------------------------------------------------------------- ALLOCATE(ctstats(vntime,numthresh,nstat),ctstatsid(nstat), & ctstatsname(nstat),STAT=status) IF (status /= 0) CALL alloc_fail (status, 'f1') ctstatsid(1) = 'BIAS' ctstatsid(2) = 'ETS ' ctstatsname(1) = 'Bias' ctstatsname(2) = 'Equitable Threat Score' IF (precipunit == 1) THEN threshunit = 'mm' ELSE IF (precipunit == 2) THEN threshunit = 'in' ELSE WRITE(6,*)'ERROR: Invalid precipunit value' WRITE(6,*)'precipunit = ',precipunit WRITE(6,*)'Aborting...' STOP END IF DO i = 1,nstat IF (i == 1) THEN ctstats(:,:,i) = bias ELSE IF (i == 2) THEN ctstats(:,:,i) = ets ENDIF END DO CALL wrtqpfstats(vnx,vny,vntime,numthresh,nstat,missing, & hdfoutfilename,vmodel,vgrid, & vdate,vtimesec,vmapproj,vscale,vtrulat1,vtrulat2, & vtrulon,vdx,vdy,vscswlat,vscswlon,& vmapswlat,vmapswlon,vmapnwlat,vmapnwlon, & vmapselat,vmapselon,vmapnelat,vmapnelon, & thresh,threshunit, & ctstatsid,ctstatsname,ctstats, & CTA,CTB,CTC,CTD) !----------------------------------------------------------------------- ! ! Output ASCII data. ! !----------------------------------------------------------------------- ALLOCATE(vxsc(vnx),vysc(vny),STAT=status) IF (status /= 0) CALL alloc_fail (status, 'f1') vtrulat(1) = vtrulat1 vtrulat(2) = vtrulat2 CALL setmapr(vmapproj,vscale,vtrulat,vtrulon) CALL lltoxy(1,1,vscswlat,vscswlon,vx0,vy0) DO i=1,vnx vxsc(i)=vx0+(i-1)*vdx END DO DO j=1,vny vysc(j)=vy0+(j-1)*vdy END DO CALL xytoll(vnx,vny,vxsc,vysc,vlat2d,vlon2d) WRITE(6,*)'Writing text output to ',TRIM(ascoutfilename) OPEN(UNIT=13,FILE=ascoutfilename,STATUS="REPLACE") WRITE(13,600) 'Forecast initialized ',fdate(1),'-',fdate(2), & '-',fdate(3),'.',fdate(4),':',fdate(5),':',fdate(6) WRITE(13,610) 'Forecast precipitation data:', TRIM(fmodel) WRITE(13,610) 'Analysis precipitation data:', TRIM(vmodel) WRITE(13,*) WRITE(13,*) 'Verification Region:' WRITE(13,625) NINT((vnx)*vdx/1000.0), NINT((vny)*vdx/1000.0), & vdx/1000.0, vnx,vny WRITE(13,650) 'NW/NE', & vlat2d(1,vny),vlon2d(1,vny),vlat2d(vnx,vny),vlon2d(vnx,vny) WRITE(13,650) 'SW/SE', & vlat2d(1,1),vlon2d(1,1), vlat2d(vnx,1),vlon2d(vnx,1) WRITE(13,*)'Used bit map from file ',TRIM(minfilename) WRITE(13,*) DO l = 1, numthresh WRITE(13,*) line72 WRITE(13,810) 'Precipitation Threshold: ',thresh(l), TRIM(threshunit) WRITE(13,*) 'Time Grid False ' WRITE(13,*) '(hr) Points Hits Misses Alarms Bias', & ' ETS' DO k = 1,vntime WRITE(13,700) vtimesec(k)/3600, & CTA(k,l)+CTB(k,l)+CTC(k,l)+CTD(k,l), & CTA(k,l),CTC(k,l),CTB(k,l), & bias(k,l),ETS(k,l) END DO END DO 600 FORMAT (/1x,a21,i4.4,a1,i2.2,a1,i2.2,a1,i2.2,a1,i2.2,a1,i2.2) 610 FORMAT (1X,A,1X,A) 625 FORMAT (' Domain:',I5, ' x', I5, ' km, dx=', F5.1, & ' km (',I4,' x',I4,' )' ) 650 FORMAT (1X,A,' corner lat/lon:', 2F10.3, 2X, 2F10.3) 700 FORMAT (3x,i2,4x,i4,2x,i4,4x,i4,4x,i4,2x,f8.2,3x,f8.2) 810 FORMAT ( 1X,a,f4.2," (",A,")" ) !----------------------------------------------------------------------- ! ! The end. ! !----------------------------------------------------------------------- WRITE(6,*)'Program QPFSTATS successfully completed.' END PROGRAM QPFSTATS !######################################################################## !######################################################################## !###### ###### !###### SUBROUTINE CALCETSB ###### !###### ###### !###### Developed by ###### !###### Center for Analysis and Prediction of Storms ###### !###### University of Oklahoma ###### !###### ###### !######################################################################## !######################################################################## SUBROUTINE calcetsb(nx,ny,ntime,vprecip,fprecip,numthresh,thresh, & 1 mask,bias,ets,cta,ctb,ctc,ctd) !----------------------------------------------------------------------- ! ! PURPOSE: ! ! Calculates equitable threat score and bias scores for precipitation. ! ! AUTHOR: Eric Kemp, March 2000 ! !----------------------------------------------------------------------- ! ! Variable declarations ! !----------------------------------------------------------------------- IMPLICIT NONE INTEGER, INTENT(IN) :: nx,ny,ntime,numthresh REAL, INTENT(IN) :: vprecip(nx,ny,ntime), fprecip(nx,ny,ntime) REAL, INTENT(OUT) :: ETS(ntime,numthresh),Bias(ntime,numthresh) REAL, INTENT(IN) :: thresh(numthresh) INTEGER, INTENT(IN) :: mask(nx,ny) INTEGER, INTENT(INOUT), DIMENSION(ntime,numthresh) :: CTA,CTB,CTC,CTD !----------------------------------------------------------------------- ! ! Variables for statistical calculations ! ! LA = Number of "yes" forecast, "yes" observation grid points. ! LB = Number of "yes" forecast, "no" observation grid points. ! LC = Number of "no" forecast, "yes" observation grid points. ! LD = Number of "no" forecast, "no" observation grid points. ! R = Number of random correct forecasts expected due to chance within ! the total number of model and observation pairs. ! ETS = Equitable Threat Score. ! ! NOTE: R = (LA + LB)*(LA + LC)/(LA + LB + LC + LD) ! ETS = (LA - R)/(LA + LB + LC - R) ! Bias = (LA + LB)/(LA + LC) ! !----------------------------------------------------------------------- REAL :: R INTEGER :: LA, LB, LC, LD !----------------------------------------------------------------------- ! ! Other variables ! !----------------------------------------------------------------------- INTEGER :: i,j,k,l REAL, PARAMETER :: missing = -9999. !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! ! Beginning of executable code... ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Bias = missing ETS = missing CTA = 0 CTB = 0 CTC = 0 CTD = 0 DO l = 1,numthresh DO k = 1,ntime LA = 0 LB = 0 LC = 0 LD = 0 DO j = 1,ny DO i = 1,nx IF (mask(i,j) == 1 .AND. fprecip(i,j,k) /= missing .AND. & vprecip(i,j,k) /= missing ) THEN IF (fprecip(i,j,k) >= thresh(l) .AND. & vprecip(i,j,k) >= thresh(l)) THEN LA = LA + 1 ELSE IF (fprecip(i,j,k) >= thresh(l) .AND. & vprecip(i,j,k) < thresh(l)) THEN LB = LB + 1 ELSE IF (fprecip(i,j,k) < thresh(l) .AND. & vprecip(i,j,k) >= thresh(l)) THEN LC = LC + 1 ELSE LD = LD + 1 ENDIF ENDIF END DO END DO IF ((LA + LB + LC + LD) == 0) THEN R = missing ELSE R = REAL(LA + LB)*REAL(LA + LC)/REAL(LA + LB + LC + LD) ENDIF IF ((R == missing) .OR. (LA + LB + LC - R) == 0 ) THEN ETS(k,l) = missing ELSE ETS(k,l) = REAL(LA - R)/REAL(LA + LB + LC - R) ENDIF IF ((LA+LC) == 0) THEN Bias(k,l) = missing ELSE Bias(k,l) = REAL(LA+LB)/REAL(LA+LC) ENDIF CTA(k,l) = LA CTB(k,l) = LB CTC(k,l) = LC CTD(k,l) = LD END DO END DO END SUBROUTINE calcetsb !######################################################################## !######################################################################## !###### ###### !###### SUBROUTINE CVTPCPUNIT ###### !###### ###### !###### Developed by ###### !###### Center for Analysis and Prediction of Storms ###### !###### University of Oklahoma ###### !###### ###### !######################################################################## !######################################################################## SUBROUTINE cvtpcpunit(nx,ny,ntime,precip,factor,missing) 4 !----------------------------------------------------------------------- ! ! PURPOSE: ! ! Converts units of precipitation array. ! ! AUTHOR: Eric Kemp, March 2000 ! !----------------------------------------------------------------------- ! ! Variable declarations ! !----------------------------------------------------------------------- IMPLICIT NONE INTEGER,INTENT(IN) :: nx,ny,ntime REAL,INTENT(INOUT) :: precip(nx,ny,ntime) REAL,INTENT(IN) :: factor,missing !----------------------------------------------------------------------- ! ! Other variables ! !----------------------------------------------------------------------- INTEGER :: i,j,k !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! ! Beginning of executable code... ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ DO k = 1,ntime DO j = 1,ny DO i = 1,nx IF (precip(i,j,k).ne.missing) THEN precip(i,j,k) = precip(i,j,k)*factor END IF END DO END DO END DO END SUBROUTINE cvtpcpunit