! !################################################################## !################################################################## !###### ###### !###### SUBROUTINE STATS ###### !###### ###### !###### Developed by ###### !###### Center for Analysis and Prediction of Storms ###### !###### University of Oklahoma ###### !###### ###### !################################################################## !################################################################## ! SUBROUTINE difstats(nx,ny,nz, & 1,2 nvar_anx,nvarradin,nvarrad,nzua,nzrdr,nzret, & mxsng,mxua,mxrad,mxcolrad,mxret,mxcolret, & nsrc_sng,nsrc_ua,nsrc_rad,nsrc_ret, & xs,ys,zp,w, & xsng,ysng,hgtsng,thesng, & obsng,odifsng,qobsng,qualsng,isrcsng,musesng,nobsng, & xua,yua,hgtua,theua, & obsua,odifua,qobsua,qualua,isrcua,museua,nlevsua,nobsua, & elvrad,xradc,yradc, & distrad,uazmrad,vazmrad,hgtradc,theradc,wradc, & obsrad,odifrad,qobsrad,qualrad, & irad,isrcrad,muserad,nlevrad,ncolrad, & xretc,yretc,hgtretc,theretc, & obsret,odifret,qobsret,qualret, & iret,isrcret,museret,nlevret,ncolret, & srcsng,srcua,srcrad,srcret, & refmos,refgrid, & knt,bias,rms, & kntsngt,biassngt,rmssngt,kntuat,biasuat,rmsuat, & kntrett,biasrett,rmsrett,kntradt,biasradt,rmsradt, & kntsng,biassng,rmssng,kntua,biasua,rmsua,kntret, & biasret,rmsret,kntrad,biasrad,rmsrad, & oanxsng,oanxua,oanxrad,oanxret, & tem1d,istatus) ! !----------------------------------------------------------------------- ! ! PURPOSE: Calculate summary tatistics from observation differences. ! ! AUTHOR: Keith Brewster and Nazir Said, CAPS ! ! INPUT: ! ! nx Number of grid points in the x-direction (east/west) ! ny Number of grid points in the y-direction (north/south) ! nz Number of grid points in the vertical ! nvar_anx Number of analysis variables ! nvarradin Number of variables in the obsrad array ! nvarrad Number of variables in the odifrad array ! nzua Maximumnumber of levels in UA observations ! nzrdr Maximum number of levels in a radar column ! nzret Maximum number of levels in a retrieval column ! mxsng Maximum number of single level data ! mxua Maximum number of upper air observations ! mxrad Maximum number of radars ! mxcolrad Maximum number of radar columns ! mxcolret Maximum number of retrieval columns ! npass Number of iterations ! iwstat Status indicator for writing statistics ! ! xsng x location of single-level data ! ysng y location of single-level data ! hgtsng elevation of single-level data ! thesng theta (potential temperature) of single-level data ! ! obsng single-level observations ! odifsng difference between single-level obs and analysis ! qobsng normalized observation error ! qualsng single-level data quality indicator ! isrcsng index of single-level data source ! nobsng number of single-level observations ! ! xua x location of upper air data ! yua y location of upper air data ! hgtua elevation of upper air data ! theua theta (potential temperature) of upper air data ! ! obsua upper air observations ! odifua difference between upper air obs and analysis ! qobsua normalized observation error ! qualua upper air data quality indicator ! isrcua index of upper air data source ! nlevsua number of levels of data for each upper air location ! nobsua number of upper air observations ! ! anx Analyzed variables (or first guess) ! qback Background (first guess) error ! ! nradfil number of radar files ! fradname file name for radar dataset ! srcrad name of radar sources ! ! latrad latitude of radar (degrees N) ! lonrad longitude of radar (degrees E) ! elvrad elevation of feed horn of radar (m MSL) ! xradc x location of radar column ! yradc y location of radar column ! irad radar number ! nlevrad number of levels of radar data in each column ! distrad distance of radar column from source radar ! uazmrad u-component of radar beam for each column ! vazmrad v-component of radar beam for each column ! hgtradc height (m MSL) of radar observations ! obsrad radar observations ! oanxrad analysis (first guess) value at radar data location ! odifrad difference between radar observation and analysis ! qobsrad normalized observation error ! qualrad radar data quality indicator ! ncolrad number of radar columns read-in ! istatus status indicator ! ! latret latitude of retrieval radar (degrees N) ! lonret longitude of retrieval radar (degrees E) ! xretc x location of retrieval column ! yretc y location of retrieval column ! iret retrieval number ! nlevret number of levels of retrieval data in each column ! hgtretc height (m MSL) of retrieval observations ! obsret retrieval observations ! odifret difference between retrieval observation and analysis ! qobsret normalized observation error ! qualret retrieval data quality indicator ! ncolret number of retr columns read-in ! istatus status indicator ! !----------------------------------------------------------------------- ! ! Variable Declarations: ! !----------------------------------------------------------------------- ! IMPLICIT NONE ! !----------------------------------------------------------------------- ! ! Input Sizing Arguments ! !----------------------------------------------------------------------- ! INTEGER :: nx,ny,nz,lfnkey INTEGER :: nvar_anx,nvarradin,nvarrad,nvar INTEGER :: nzua,nzrdr,nzret INTEGER :: mxsng,mxua,mxrad,mxcolrad,mxret,mxcolret INTEGER :: nsrc_sng,nsrc_ua,nsrc_rad,nsrc_ret,ncat ! !----------------------------------------------------------------------- ! ! Input gridded data ! !----------------------------------------------------------------------- ! REAL :: xs(nx) REAL :: ys(ny) REAL :: zp(nx,ny,nz) REAL :: w(nx,ny,nz) ! !----------------------------------------------------------------------- ! ! Input Observation Arguments ! !----------------------------------------------------------------------- ! REAL :: xsng(mxsng) REAL :: ysng(mxsng) REAL :: hgtsng(mxsng) REAL :: thesng(mxsng) REAL :: obsng(nvar_anx,mxsng) REAL :: odifsng(nvar_anx,mxsng) REAL :: qobsng(nvar_anx,mxsng) INTEGER :: qualsng(nvar_anx,mxsng) INTEGER :: isrcsng(mxsng) INTEGER :: musesng(0:nsrc_sng) INTEGER :: icatsng(mxsng) INTEGER :: nobsng ! REAL :: xua(mxua) REAL :: yua(mxua) REAL :: hgtua(nzua,mxua) REAL :: theua(nzua,mxua) REAL :: obsua(nvar_anx,nzua,mxua) REAL :: odifua(nvar_anx,nzua,mxua) REAL :: qobsua(nvar_anx,nzua,mxua) INTEGER :: qualua(nvar_anx,nzua,mxua) INTEGER :: nlevsua(mxua) INTEGER :: isrcua(mxua) INTEGER :: museua(0:nsrc_ua) INTEGER :: nobsua ! REAL :: elvrad(mxrad) REAL :: xradc(mxcolrad) REAL :: yradc(mxcolrad) REAL :: distrad(mxcolrad) REAL :: uazmrad(mxcolrad) REAL :: vazmrad(mxcolrad) REAL :: hgtradc(nzrdr,mxcolrad) REAL :: theradc(nzrdr,mxcolrad) REAL :: wradc(nzrdr) REAL :: obsrad(nvarradin,nzrdr,mxcolrad) REAL :: odifrad(nvarrad,nzrdr,mxcolrad) REAL :: qobsrad(nvarrad,nzrdr,mxcolrad) INTEGER :: qualrad(nvarrad,nzrdr,mxcolrad) INTEGER :: nlevrad(mxcolrad) INTEGER :: irad(mxcolrad) INTEGER :: isrcrad(0:mxrad) INTEGER :: muserad(0:nsrc_rad) INTEGER :: ncolrad ! REAL :: xretc(mxcolret) REAL :: yretc(mxcolret) REAL :: hgtretc(nzret,mxcolret) REAL :: theretc(nzret,mxcolret) REAL :: obsret(nvar_anx,nzret,mxcolret) REAL :: odifret(nvar_anx,nzret,mxcolret) REAL :: qobsret(nvar_anx,nzret,mxcolret) INTEGER :: qualret(nvar_anx,nzret,mxcolret) INTEGER :: nlevret(mxcolret) INTEGER :: iret(mxcolret) INTEGER :: isrcret(0:mxret) INTEGER :: museret(0:nsrc_ret) INTEGER :: ncolret ! !----------------------------------------------------------------------- ! ! Input Analysis Control Variables ! !----------------------------------------------------------------------- ! CHARACTER (LEN=8) :: srcsng(nsrc_sng) CHARACTER (LEN=8) :: srcua (nsrc_ua ) CHARACTER (LEN=8) :: srcrad(nsrc_rad) CHARACTER (LEN=8) :: srcret(nsrc_ret) ! !----------------------------------------------------------------------- ! ! Input reflectivity data ! !----------------------------------------------------------------------- ! REAL :: refmos(nx,ny,nz) REAL :: refgrid(nx,ny,nz) ! !----------------------------------------------------------------------- ! ! Scratch Space ! !----------------------------------------------------------------------- ! INTEGER :: knt(nvar_anx) INTEGER :: kntsngt(nvar_anx) INTEGER :: kntuat(nvar_anx) INTEGER :: kntrett(nvar_anx) INTEGER :: kntradt(nvar_anx) INTEGER :: kntsng(nvar_anx,nsrc_sng) INTEGER :: kntua(nvar_anx,nsrc_ua) INTEGER :: kntret(nvar_anx,nsrc_ret) INTEGER :: kntrad(nvar_anx,nsrc_rad) REAL :: bias(nvar_anx) REAL :: rms(nvar_anx) REAL :: biassngt(nvar_anx) REAL :: rmssngt(nvar_anx) REAL :: biasuat(nvar_anx) REAL :: rmsuat(nvar_anx) REAL :: biasrett(nvar_anx) REAL :: rmsrett(nvar_anx) REAL :: biasradt(nvar_anx) REAL :: rmsradt(nvar_anx) REAL :: biassng(nvar_anx,nsrc_sng) REAL :: rmssng(nvar_anx,nsrc_sng) REAL :: biasua(nvar_anx,nsrc_ua) REAL :: rmsua(nvar_anx,nsrc_ua) REAL :: biasret(nvar_anx,nsrc_ret) REAL :: rmsret(nvar_anx,nsrc_ret) REAL :: biasrad(nvar_anx,nsrc_rad) REAL :: rmsrad(nvar_anx,nsrc_rad) ! !----------------------------------------------------------------------- ! ! Output Variables at Observation Locations ! !----------------------------------------------------------------------- ! REAL :: oanxsng(nvar_anx,mxsng) REAL :: oanxua(nvar_anx,nzua,mxua) REAL :: oanxrad(nvarrad,nzrdr,mxcolrad) REAL :: oanxret(nvar_anx,nzret,mxcolret) ! REAL :: tem1d(nz) ! INTEGER :: istatus ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! ! Beginning of executable code ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! WRITE(6,'(a,i4)') 'Computing orig difference stats' CALL verifst3d(nvar_anx, & nzua,nzret,mxsng,mxua,mxret,mxcolret, & obsng,odifsng,oanxsng,isrcsng,musesng,qualsng,nobsng, & obsua,odifua,oanxua,isrcua,museua,qualua,nlevsua,nobsua, & obsret,odifret,oanxret,iret,isrcret,museret, & qualret,nlevret,ncolret,nsrc_sng,nsrc_ua,nsrc_ret, & knt,bias,rms,kntsngt,biassngt,rmssngt,kntuat,biasuat, & rmsuat,kntrett,biasrett,rmsrett,kntsng,biassng,rmssng, & kntua,biasua,rmsua,kntret,biasret,rmsret) ! CALL verifstra(nx,ny,nz,nvar_anx,nvarrad,nvarradin, & nzrdr,mxrad,mxcolrad, & xs,ys,zp,w, & elvrad,distrad,xradc,yradc,hgtradc, & uazmrad,vazmrad,wradc,qualrad,irad,isrcrad, & obsrad,odifrad,oanxrad, & nlevrad,ncolrad,nsrc_rad, & refmos,refgrid, & kntradt,biasradt,rmsradt,kntrad,biasrad,rmsrad,tem1d) RETURN END SUBROUTINE difstats ! !################################################################## !################################################################## !###### ###### !###### SUBROUTINE VERIFST3d ###### !###### ###### !###### Developed by ###### !###### Center for Analysis and Prediction of Storms ###### !###### University of Oklahoma ###### !###### ###### !################################################################## !################################################################## ! SUBROUTINE verifst3d(nvar_anx, & 1 nzua,nzret,mxsng,mxua,mxret,mxcolret, & obsng,odifsng,oanxsng,isrcsng,musesng,qualsng,nobsng, & obsua,odifua,oanxua,isrcua,museua,qualua,nlevsua,nobsua, & obsret,odifret,oanxret,iret,isrcret,museret, & qualret,nlevret,ncolret,nsrc_sng,nsrc_ua,nsrc_ret, & knt,bias,rms,kntsngt,biassngt,rmssngt,kntuat,biasuat, & rmsuat,kntrett,biasrett,rmsrett,kntsng,biassng,rmssng, & kntua,biasua,rmsua,kntret,biasret,rmsret) ! !----------------------------------------------------------------------- ! ! PURPOSE: ! ! Calculate new observation differences ! and report statistics on the differences. ! !----------------------------------------------------------------------- ! ! AUTHOR: Keith Brewster, CAPS ! March, 1994 ! ! MODIFICATION HISTORY: ! July, 1995 (Keith Brewster) ! 3D ARPS version ! ! May, 1996 (KB) ! Added retrieval data. ! ! Dec, 2001 (KB & Nazir Said) ! Updated ! !----------------------------------------------------------------------- ! ! Variable Declarations: ! !----------------------------------------------------------------------- ! IMPLICIT NONE INTEGER :: nvar_anx,nz,nvar INTEGER :: nzua,nzret,mxsng,mxua,mxret,mxcolret INTEGER :: nsrc_sng,nsrc_ua,nsrc_ret ! REAL :: obsng(nvar_anx,mxsng) REAL :: odifsng(nvar_anx,mxsng) REAL :: oanxsng(nvar_anx,mxsng) INTEGER :: isrcsng(mxsng) INTEGER :: musesng(0:nsrc_sng) INTEGER :: qualsng(nvar_anx,mxsng) INTEGER :: nobsng ! REAL :: obsua(nvar_anx,nzua,mxua) REAL :: odifua(nvar_anx,nzua,mxua) REAL :: oanxua(nvar_anx,nzua,mxua) INTEGER :: isrcua(mxua) INTEGER :: museua(0:nsrc_ua) INTEGER :: qualua(nvar_anx,nzua,mxua) INTEGER :: nlevsua(mxua) INTEGER :: nobsua ! REAL :: obsret(nvar_anx,nzret,mxcolret) REAL :: odifret(nvar_anx,nzret,mxcolret) REAL :: oanxret(nvar_anx,nzret,mxcolret) INTEGER :: iret(mxcolret) INTEGER :: isrcret(mxret) INTEGER :: museret(0:nsrc_ret) INTEGER :: qualret(nvar_anx,nzret,mxcolret) INTEGER :: nlevret(mxcolret) INTEGER :: ncolret ! INTEGER :: knt(nvar_anx) INTEGER :: kntsngt(nvar_anx) INTEGER :: kntuat(nvar_anx) INTEGER :: kntrett(nvar_anx) INTEGER :: kntsng(nvar_anx,nsrc_sng) INTEGER :: kntua(nvar_anx,nsrc_ua) INTEGER :: kntret(nvar_anx,nsrc_ret) REAL :: bias(nvar_anx) REAL :: rms(nvar_anx) REAL :: biassngt(nvar_anx) REAL :: biasuat(nvar_anx) REAL :: biasrett(nvar_anx) REAL :: rmssngt(nvar_anx) REAL :: rmsuat(nvar_anx) REAL :: rmsrett(nvar_anx) REAL :: biassng(nvar_anx,nsrc_sng) REAL :: rmssng(nvar_anx,nsrc_sng) REAL :: biasua(nvar_anx,nsrc_ua) REAL :: biasret(nvar_anx,nsrc_ret) REAL :: rmsua(nvar_anx,nsrc_ua) REAL :: rmsret(nvar_anx,nsrc_ret) ! !----------------------------------------------------------------------- ! ! Misc.local variables ! !----------------------------------------------------------------------- ! INTEGER :: ivar,jsta,klev,isrc REAL :: flknt ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! ! Beginning of executable code... ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! DO ivar=1,nvar_anx knt(ivar) =0 bias(ivar)=0. rms(ivar)=0. biassngt(ivar)=0. biasuat(ivar)=0. biasrett(ivar)=0. rmssngt(ivar)=0. rmsuat(ivar)=0. rmsrett(ivar)=0. kntsngt(ivar)=0 kntuat(ivar)=0 kntrett(ivar)=0 DO isrc=1,nsrc_sng kntsng(ivar,isrc)=0 END DO DO isrc=1,nsrc_sng biassng(ivar,isrc)=0. rmssng(ivar,isrc)=0. END DO DO isrc=1,nsrc_ua kntua(ivar,isrc)=0 biasua(ivar,isrc)=0. rmsua(ivar,isrc)=0. END DO DO isrc=1,nsrc_ret kntret(ivar,isrc)=0 biasret(ivar,isrc)=0. rmsret(ivar,isrc)=0. END DO END DO ! !----------------------------------------------------------------------- ! ! Find differences and form sums at single-level sites ! !----------------------------------------------------------------------- ! DO jsta=1,nobsng IF(isrcsng(jsta) /= 0) THEN IF(musesng(isrcsng(jsta)) > 0 ) THEN DO ivar=1,nvar_anx IF(qualsng(ivar,jsta) > 0) THEN odifsng(ivar,jsta)=(obsng(ivar,jsta)-oanxsng(ivar,jsta)) knt(ivar)=(knt(ivar)+1) bias(ivar)=bias(ivar)-odifsng(ivar,jsta) rms(ivar)=rms(ivar)+ & odifsng(ivar,jsta)*odifsng(ivar,jsta) kntsngt(ivar)=kntsngt(ivar)+1 biassngt(ivar)=biassngt(ivar)-odifsng(ivar,jsta) rmssngt(ivar)=rmssngt(ivar)+ & odifsng(ivar,jsta)*odifsng(ivar,jsta) kntsng(ivar,isrcsng(jsta))=kntsng(ivar,isrcsng(jsta))+1 biassng(ivar,isrcsng(jsta))= & biassng(ivar,isrcsng(jsta))-odifsng(ivar,jsta) rmssng(ivar,isrcsng(jsta))= rmssng(ivar,isrcsng(jsta)) & +odifsng(ivar,jsta)*odifsng(ivar,jsta) END IF END DO END IF END IF END DO ! !----------------------------------------------------------------------- ! ! Find differences at multiple-level sites ! Add to sums ! !----------------------------------------------------------------------- ! DO jsta=1,nobsua IF(isrcua(jsta) /= 0) THEN IF(museua(isrcua(jsta)) > 0) THEN DO klev=1,nlevsua(jsta) DO ivar=1,nvar_anx IF(qualua(ivar,klev,jsta) > 0) THEN odifua(ivar,klev,jsta)= & obsua(ivar,klev,jsta)-oanxua(ivar,klev,jsta) knt(ivar)=knt(ivar)+1 bias(ivar)=bias(ivar)-odifua(ivar,klev,jsta) rms(ivar)=rms(ivar)+ & odifua(ivar,klev,jsta)*odifua(ivar,klev,jsta) kntuat(ivar)=kntuat(ivar)+1 biasuat(ivar)=biasuat(ivar)-odifua(ivar,klev,jsta) rmsuat(ivar)=rmsuat(ivar)+ & odifua(ivar,klev,jsta)*odifua(ivar,klev,jsta) kntua(ivar,isrcua(jsta))=kntua(ivar,isrcua(jsta))+1 biasua(ivar,isrcua(jsta))= & biasua(ivar,isrcua(jsta))-odifua(ivar,klev,jsta) rmsua(ivar,isrcua(jsta))= rmsua(ivar,isrcua(jsta)) & +odifua(ivar,klev,jsta)*odifua(ivar,klev,jsta) END IF END DO END DO END IF END IF END DO ! !----------------------------------------------------------------------- ! ! Find differences at retrieval columns ! Add to sums ! !----------------------------------------------------------------------- ! DO jsta=1,ncolret IF(isrcret(iret(jsta)) > 0) THEN IF(museret(isrcret(iret(jsta))) > 0) THEN DO klev=1,nlevret(jsta) DO ivar=1,nvar_anx IF(qualret(ivar,klev,jsta) > 0) THEN odifret(ivar,klev,jsta)= & obsret(ivar,klev,jsta)-oanxret(ivar,klev,jsta) knt(ivar)=knt(ivar)+1 bias(ivar)=bias(ivar)-odifret(ivar,klev,jsta) rms(ivar)=rms(ivar)+ & odifret(ivar,klev,jsta)*odifret(ivar,klev,jsta) kntrett(ivar)=kntrett(ivar)+1 biasrett(ivar)=biasrett(ivar)-odifret(ivar,klev,jsta) rmsrett(ivar)=rmsrett(ivar)+ & odifret(ivar,klev,jsta)*odifret(ivar,klev,jsta) kntret(ivar,iret(jsta))=kntret(ivar,iret(jsta))+1 biasret(ivar,iret(jsta))= & biasret(ivar,iret(jsta))-odifret(ivar,klev,jsta) rmsret(ivar,iret(jsta))= rmsret(ivar,iret(jsta)) & +odifret(ivar,klev,jsta)*odifret(ivar,klev,jsta) END IF END DO END DO END IF END IF END DO ! !----------------------------------------------------------------------- ! ! Calculate stats from the sums formed above ! !----------------------------------------------------------------------- ! DO ivar=1,nvar_anx IF(knt(ivar) > 0) THEN flknt=FLOAT(knt(ivar)) bias(ivar)=bias(ivar)/flknt rms(ivar)=SQRT(rms(ivar)/flknt) ELSE bias(ivar)=0. rms(ivar)=0. END IF IF(kntsngt(ivar) > 0) THEN flknt=FLOAT(kntsngt(ivar)) biassngt(ivar)=biassngt(ivar)/flknt rmssngt(ivar)=SQRT(rmssngt(ivar)/flknt) ELSE biassngt(ivar)=0. rmssngt(ivar)=0. END IF IF(kntuat(ivar) > 0) THEN flknt=FLOAT(kntuat(ivar)) biasuat(ivar)=biasuat(ivar)/flknt rmsuat(ivar)=SQRT(rmsuat(ivar)/flknt) ELSE biasuat(ivar)=0. rmsuat(ivar)=0. END IF IF(kntrett(ivar) > 0) THEN flknt=FLOAT(kntrett(ivar)) biasrett(ivar)=biasrett(ivar)/flknt rmsrett(ivar)=SQRT(rmsrett(ivar)/flknt) ELSE biasrett(ivar)=0. rmsrett(ivar)=0. END IF DO isrc =1,nsrc_sng IF(kntsngt(ivar) > 0 ) THEN flknt=FLOAT(kntsngt(ivar)) biassng(ivar,isrc)=biassng(ivar,isrc)/flknt rmssng(ivar,isrc)=SQRT(rmssng(ivar,isrc)/flknt) ELSE biassng(ivar,isrc)=0. rmssng(ivar,isrc)=0. END IF END DO DO isrc =1,nsrc_ua IF(kntua(ivar,isrc) > 0 ) THEN flknt=FLOAT(kntua(ivar,isrc)) biasua(ivar,isrc)=biasua(ivar,isrc)/flknt rmsua(ivar,isrc)=SQRT(rmsua(ivar,isrc)/flknt) ELSE biasua(ivar,isrc)=0. rmsua(ivar,isrc)=0. END IF END DO DO isrc =1,nsrc_ret IF(kntret(ivar,isrc) > 0 ) THEN flknt=FLOAT(kntret(ivar,isrc)) biasret(ivar,isrc)=biasret(ivar,isrc)/flknt rmsret(ivar,isrc)=SQRT(rmsret(ivar,isrc)/flknt) ELSE biasret(ivar,isrc)=0. rmsret(ivar,isrc)=0. END IF END DO END DO RETURN END SUBROUTINE verifst3d ! !################################################################## !################################################################## !###### ###### !###### SUBROUTINE VERIFSTRA ###### !###### ###### !###### Developed by ###### !###### Center for Analysis and Prediction of Storms ###### !###### University of Oklahoma ###### !###### ###### !################################################################## !################################################################## SUBROUTINE verifstra(nx,ny,nz,nvar_anx,nvarrad,nvarradin, & 1,3 nzrdr,mxrad,mxcolrad, & xs,ys,zp,w, & elvrad,distrad,xradc,yradc,hgtradc, & uazmrad,vazmrad,wradc,qualrad,irad,isrcrad, & obsrad,odifrad,oanxrad, & nlevrad,ncolrad,nsrc_rad, & refmos,refgrid, & kntradt,biasradt,rmsradt,kntrad,biasrad,rmsrad,tem1d) ! !----------------------------------------------------------------------- ! ! PURPOSE: ! ! Calculate radar observation differences ! and report statistics on the differences. ! !----------------------------------------------------------------------- ! ! AUTHOR: Keith Brewster, CAPS ! September, 1995 ! ! MODIFICATION HISTORY: ! ! Jan, 1996 (KB) ! Added radar data and other improvements. ! ! August, 2001 (KB) ! Corrected call to dhdr which now returns dhdr not local ! elevation angle. Modified calculation of odifrad to speed ! convergence to vr. ! ! August, 2003 (KB) ! Updated for statistical calculations !----------------------------------------------------------------------- ! ! Variable Declarations: ! !----------------------------------------------------------------------- ! IMPLICIT NONE INTEGER :: nx,ny,nz INTEGER :: nvar_anx,nvarrad,nvarradin,nzrdr,mxrad,mxcolrad,nsrc_rad ! REAL :: xs(nx) REAL :: ys(ny) REAL :: zp(nx,ny,nz) REAL :: w(nx,ny,nz) REAL :: elvrad(mxrad) REAL :: distrad(mxcolrad) REAL :: xradc(mxcolrad) REAL :: yradc(mxcolrad) REAL :: hgtradc(nzrdr,mxcolrad) REAL :: uazmrad(mxcolrad) REAL :: vazmrad(mxcolrad) INTEGER :: qualrad(nvarrad,nzrdr,mxcolrad) INTEGER :: irad(mxcolrad) INTEGER :: isrcrad(0:mxrad) REAL :: obsrad(nvarradin,nzrdr,mxcolrad) REAL :: odifrad(nvarrad,nzrdr,mxcolrad) REAL :: oanxrad(nvarrad,nzrdr,mxcolrad) REAL :: wradc(nzrdr) INTEGER :: nlevrad(mxcolrad) INTEGER :: ncolrad ! REAL :: refmos(nx,ny,nz) REAL :: refgrid(nx,ny,nz) ! INTEGER :: kntradt(nvar_anx) REAL :: biasradt(nvar_anx) REAL :: rmsradt(nvar_anx) INTEGER :: kntrad(nvar_anx,nsrc_rad) REAL :: biasrad(nvar_anx,nsrc_rad) REAL :: rmsrad(nvar_anx,nsrc_rad) REAL :: tem1d(nz) ! !----------------------------------------------------------------------- ! ! Misc.local variables ! !----------------------------------------------------------------------- ! INTEGER :: i,j,k INTEGER :: icol,ivar,kr,jrad,isrc REAL :: pi,dtr,dz,eleva,range,flknt REAL :: vr,vrdiff,avrdif,dhdr,dsdr,dsdrinv,refdiff REAL :: vr_miss ! !----------------------------------------------------------------------- ! ! QC and conversion parameters ! ! vrqcthr maximum radial velocity diff from background to use ! vrcnvthr lower limit of the dot product between the radial ! direction and the analysis wind component to use data ! !----------------------------------------------------------------------- ! REAL :: vrqcthr,vrcnvthr PARAMETER (vrqcthr=20., & ! maximum vrdiff from background to use vrcnvthr=-0.2) ! lower limit of the dot product to use data ! !----------------------------------------------------------------------- ! ! Some initializations ! !----------------------------------------------------------------------- ! vr_miss=-999. pi=4.*ATAN(1.0) dtr=pi/180. ! DO ivar=1,nvar_anx kntradt(ivar)=0. biasradt(ivar)=0. rmsradt(ivar)=0. DO isrc=1,nsrc_rad kntrad(ivar,isrc)=0 biasrad(ivar,isrc)=0. rmsrad(ivar,isrc)=0. END DO END DO ! !----------------------------------------------------------------------- ! ! Find radial velocity differences at radar data points ! Add to sums ! !----------------------------------------------------------------------- ! DO icol=1,ncolrad IF(irad(icol) > 0) THEN jrad=irad(icol) isrc=isrcrad(jrad) ! IF(isrc > 0) THEN CALL wintrp(nx,ny,nz,nzrdr,nlevrad, xs,ys,zp,w, & xradc(icol),yradc(icol),hgtradc(1,icol),wradc,tem1d) ! DO kr=1,nlevrad(icol) IF(qualrad(1,kr,icol) > 0 .AND. qualrad(2,kr,icol) > 0 ) THEN ! dz=hgtradc(kr,icol)-elvrad(jrad) CALL beamelv(dz,distrad(icol),eleva,range) CALL dhdrange(eleva,range,dhdr) dsdr=SQRT(MAX(0.,(1.-dhdr*dhdr))) IF(dsdr /= 0.) THEN dsdrinv=1./dsdr ELSE dsdrinv=0. END IF ! ! Obtain w from grid, which was not previously saved. ! vr=((uazmrad(icol)*oanxrad(1,kr,icol) + & vazmrad(icol)*oanxrad(2,kr,icol)) * dsdr) + & (wradc(kr) * dhdr ) vrdiff=(obsrad(2,kr,icol)*dsdrinv) - vr avrdif=ABS(vrdiff) odifrad(1,kr,icol)=vrdiff kntradt(1)=kntradt(1)+1 biasradt(1)=biasradt(1)+vrdiff rmsradt(1)=rmsradt(1)+(vrdiff*vrdiff) kntrad(1,isrc)=kntrad(1,isrc)+1 biasrad(1,isrc)=biasrad(1,isrc)+vrdiff rmsrad(1,isrc)=rmsrad(1,isrc)+(vrdiff*vrdiff) END IF END DO END IF END IF END DO ! !----------------------------------------------------------------------- ! ! Calculate errors in reflectivity. ! !----------------------------------------------------------------------- ! DO k=2,nz-1 DO j=2,ny-2 DO i=2,nx-2 IF(refmos(i,j,k) >= 0.) THEN refdiff=refgrid(i,j,k)-refmos(i,j,k) kntradt(2)=kntradt(2)+1 biasradt(2)=biasradt(2)+refdiff rmsradt(2)=rmsradt(2)+(refdiff*refdiff) END IF END DO END DO END DO ! !----------------------------------------------------------------------- ! ! Calculate stats from the sums formed above ! !----------------------------------------------------------------------- ! DO ivar=1,nvar_anx IF(kntradt(ivar) > 0) THEN flknt=FLOAT(kntradt(ivar)) biasradt(ivar)=biasradt(ivar)/flknt rmsradt(ivar)=SQRT(rmsradt(ivar)/flknt) ELSE biasradt(ivar)=0. rmsradt(ivar)=0. END IF DO isrc=1,nsrc_rad IF(kntrad(ivar,isrc) > 0) THEN flknt=FLOAT(kntrad(ivar,isrc)) biasrad(ivar,isrc)=biasrad(ivar,isrc)/flknt rmsrad(ivar,isrc)=SQRT(rmsrad(ivar,isrc)/flknt) ELSE biasrad(ivar,isrc)=0. rmsrad(ivar,isrc)=0. END IF END DO END DO ! RETURN END SUBROUTINE verifstra ! SUBROUTINE wintrp(nx,ny,nz,nzrdr,nlevrad, xs,ys,zp,w, & 1 xradc,yradc,hgtradc,wradc,tem1d) IMPLICIT NONE INTEGER :: nx,ny,nz INTEGER :: nzrdr INTEGER :: nlevrad REAL :: xs(nx) REAL :: ys(nx) REAL :: zp(nx,ny,nz) REAL :: w(nx,ny,nz) INTEGER :: nlevrad REAL :: xradc REAL :: yradc REAL :: hgtradc(nzrdr) REAL :: wradc(nzrdr) REAL :: tem1d(nz) ! ! Misc local variables ! INTEGER :: i,j,k,kr,imid,jmid,kmid,iloc,jloc,kloc REAL :: wx,wy,wlo,whi REAL :: w11,w12,w21,w22 ! imid=nx/2 jmid=ny/2 kmid=nz/2 wradc=-999.0 ! !----------------------------------------------------------------------- ! ! Find column in grid ! !----------------------------------------------------------------------- ! IF(xradc < xs(imid)) THEN DO i=imid,2,-1 IF(xs(i) < xradc) EXIT END DO iloc=i ELSE DO i=imid,nx-1 IF(xs(i) > xradc) EXIT END DO iloc=i-1 END IF wx = (xradc-xs(iloc))/(xs(iloc+1)-xs(iloc)) ! IF(yradc < ys(jmid)) THEN DO j=jmid,2,-1 IF(ys(j) < yradc) EXIT END DO jloc=j ELSE DO j=jmid,ny-1 IF(ys(j) > yradc) EXIT END DO jloc=j-1 END IF wy = (yradc-ys(jloc))/(ys(jloc+1)-ys(jloc)) ! !----------------------------------------------------------------------- ! ! Determine bilinear interpolation weights ! !----------------------------------------------------------------------- ! w22 = wx*wy w12 = (1.0 - wx) * wy w21 = wx * (1.0 - wy) w11 = (1.0 - wx) * (1.0 - wy) ! !----------------------------------------------------------------------- ! ! Interpolate grid heights in horizontal ! !----------------------------------------------------------------------- ! DO k=1,nz-1 tem1d(k)=w11*zp( iloc, jloc,k) + & w21*zp(iloc+1, jloc,k) + & w12*zp( iloc,jloc+1,k) + & w22*zp(iloc+1,jloc+1,k) END DO ! !----------------------------------------------------------------------- ! ! Loop in height ! !----------------------------------------------------------------------- ! DO kr=1,nlevrad IF(hgtradc(kr) >= tem1d(2) .AND. hgtradc(kr) <= tem1d(nz-1)) THEN ! !----------------------------------------------------------------------- ! ! Find z location in grid ! !----------------------------------------------------------------------- ! IF(hgtradc(kr) < tem1d(kmid)) THEN DO k=kmid,2,-1 IF(tem1d(k) < hgtradc(kr)) EXIT END DO kloc=k ELSE DO k=kmid,nz-1 IF(tem1d(k) > hgtradc(kr)) EXIT END DO kloc=k-1 END IF ! !----------------------------------------------------------------------- ! ! Set z weights ! !----------------------------------------------------------------------- ! whi = (hgtradc(kr)-tem1d(kloc))/ & (tem1d(kloc+1)-tem1d(kloc)) wlo = 1.0 - whi wradc(kr)= & wlo* (w11*w( iloc, jloc, kloc) + & w21*w(iloc+1, jloc, kloc) + & w12*w( iloc,jloc+1, kloc) + & w22*w(iloc+1,jloc+1, kloc)) & + whi* (w11*w( iloc, jloc,kloc+1) + & w21*w(iloc+1, jloc,kloc+1) + & w12*w( iloc,jloc+1,kloc+1) + & w22*w(iloc+1,jloc+1,kloc+1)) END IF END DO RETURN END SUBROUTINE wintrp