!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE ANXITER ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE anxiter(nx,ny,nz, & 1,12
nvar,nvarradin,nvarrad,nzua,nzrdr,nzret, &
mxsng,mxua,mxrad,mxcolrad,mxret,mxcolret, &
nsrcsng,nsrcua,nsrcrad,nsrcret,ncat, &
mxpass,npass,iwstat,xs,ys,zs,icatg,xcor,nam_var, &
xsng,ysng,hgtsng,thesng, &
obsng,odifsng,qobsng,qualsng,isrcsng,icatsng,nobsng, &
xua,yua,hgtua,theua, &
obsua,odifua,qobsua,qualua,isrcua,nlevsua,nobsua, &
elvrad,xradc,yradc, &
distrad,uazmrad,vazmrad,hgtradc,theradc, &
obsrad,odifrad,qobsrad,qualrad, &
irad,isrcrad,nlevrad,ncolrad, &
xretc,yretc,hgtretc,theretc, &
obsret,odifret,qobsret,qualret, &
iret,isrcret,nlevret,ncolret, &
srcsng,srcua,srcrad,srcret, &
ianxtyp,iusesng,iuseua,iuserad,iuseret, &
xyrange,kpvrsq,wlim,zrange,zwlim, &
thrng,rngsqi,knt,wgtsum,zsum, &
corsng,corua,corrad,corret, &
oanxsng,oanxua,oanxrad,oanxret, &
anx,tem1,tem2,tem3,ibegin,iend,istatus)
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Control ARPS analysis successive corrections iteration.
! For each pass it calls routines to analyze at grid points,
! analyze at obs points, computes new obs differences and
! reports rms statistics.
!
! On input the analyses at grid points and obs points
! (anx, oanxsng and oanxua) should be initialized.
! Either as as zero or with a first guess field and
! that guess field interpolated to obs sites.
!
!-----------------------------------------------------------------------
!
! AUTHOR:
! Version for OLAPS surface Keith Brewster, CAPS
! March, 1994
!
! 3-D ARPS version Keith Brewster, CAPS
! July, 1995
!
! MODIFICATION HISTORY:
! Update for radar data, misc. improvements
! Jan, 1996 KB
!
! Added sngsw and uasw to switch on/off use of single-level
! and sounding data, respectively.
! July, 1996 KB
!
! Changes made to anxiter argument list and calls to Bratseth routines
! to accomodate changes made to speed up Bratseth routines.
! Jan 5, 1997 KB
!
!-----------------------------------------------------------------------
!
! 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 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
! mxpass Maximum number of iterations
! npass Number of iterations
! iwstat Status indicator for writing statistics
!
! xs x location of scalar pts (m)
! ys y location of scalar pts (m)
! zs z location of scalar pts (m)
!
! 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
INTEGER :: nvar,nvarradin,nvarrad
INTEGER :: nzua,nzrdr,nzret
INTEGER :: mxsng,mxua,mxrad,mxcolrad,mxret,mxcolret
INTEGER :: nsrcsng,nsrcua,nsrcrad,nsrcret,ncat
INTEGER :: mxpass,npass
!
!-----------------------------------------------------------------------
!
! Input Grid Arguments
!
!-----------------------------------------------------------------------
!
REAL :: xs(nx)
REAL :: ys(ny)
REAL :: zs(nx,ny,nz)
INTEGER :: icatg(nx,ny)
REAL :: xcor(ncat,ncat)
!
!-----------------------------------------------------------------------
!
! Input Observation Arguments
!
!-----------------------------------------------------------------------
!
CHARACTER (LEN=6) :: nam_var(nvar)
REAL :: xsng(mxsng)
REAL :: ysng(mxsng)
REAL :: hgtsng(mxsng)
REAL :: thesng(mxsng)
REAL :: obsng(nvar,mxsng)
REAL :: odifsng(nvar,mxsng)
REAL :: qobsng(nvar,mxsng)
INTEGER :: qualsng(nvar,mxsng)
INTEGER :: isrcsng(mxsng)
INTEGER :: icatsng(mxsng)
INTEGER :: nobsng
!
REAL :: xua(mxua)
REAL :: yua(mxua)
REAL :: hgtua(nzua,mxua)
REAL :: theua(nzua,mxua)
REAL :: obsua(nvar,nzua,mxua)
REAL :: odifua(nvar,nzua,mxua)
REAL :: qobsua(nvar,nzua,mxua)
INTEGER :: qualua(nvar,nzua,mxua)
INTEGER :: nlevsua(mxua)
INTEGER :: isrcua(mxua)
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 :: 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 :: ncolrad
!
REAL :: xretc(mxcolret)
REAL :: yretc(mxcolret)
REAL :: hgtretc(nzret,mxcolret)
REAL :: theretc(nzret,mxcolret)
REAL :: obsret(nvar,nzret,mxcolret)
REAL :: odifret(nvar,nzret,mxcolret)
REAL :: qobsret(nvar,nzret,mxcolret)
INTEGER :: qualret(nvar,nzret,mxcolret)
INTEGER :: nlevret(mxcolret)
INTEGER :: iret(mxcolret)
INTEGER :: isrcret(0:mxret)
INTEGER :: ncolret
!
!-----------------------------------------------------------------------
!
! Input Analysis Control Variables
!
!-----------------------------------------------------------------------
!
CHARACTER (LEN=8) :: srcsng(nsrcsng)
CHARACTER (LEN=8) :: srcua (nsrcua )
CHARACTER (LEN=8) :: srcrad(nsrcrad)
CHARACTER (LEN=8) :: srcret(nsrcret)
INTEGER :: ianxtyp(mxpass)
INTEGER :: iusesng(0:nsrcsng,mxpass)
INTEGER :: iuseua(0:nsrcua,mxpass)
INTEGER :: iuserad(0:nsrcrad,mxpass)
INTEGER :: iuseret(0:nsrcret,mxpass)
REAL :: xyrange(mxpass)
REAL :: kpvrsq(nvar)
REAL :: wlim
REAL :: zrange(mxpass)
REAL :: zwlim
REAL :: thrng(mxpass)
INTEGER :: iwstat
!
!-----------------------------------------------------------------------
!
! Scratch Space
!
!-----------------------------------------------------------------------
!
REAL :: rngsqi(nvar)
INTEGER :: knt(nvar,nz)
REAL :: wgtsum(nvar,nz)
REAL :: zsum(nvar,nz)
!
!-----------------------------------------------------------------------
!
! Output Variables at Observation Locations
!
!-----------------------------------------------------------------------
!
REAL :: corsng(nvar,mxsng)
REAL :: corua(nvar,nzua,mxua)
REAL :: corrad(nvarrad,nzrdr,mxcolrad)
REAL :: corret(nvar,nzret,mxcolret)
REAL :: oanxsng(nvar,mxsng)
REAL :: oanxua(nvar,nzua,mxua)
REAL :: oanxrad(nvarrad,nzrdr,mxcolrad)
REAL :: oanxret(nvar,nzret,mxcolret)
!
!-----------------------------------------------------------------------
!
! Output Grid
!
!-----------------------------------------------------------------------
!
REAL :: anx(nx,ny,nz,nvar)
!
!-----------------------------------------------------------------------
!
! Work arrays
!
!-----------------------------------------------------------------------
!
REAL :: tem1(nx,ny,nz)
REAL :: tem2(nx,ny,nz)
REAL :: tem3(nx,ny,nz)
INTEGER :: ibegin(ny)
INTEGER :: iend(ny)
!
!-----------------------------------------------------------------------
!
! Return status
!
!-----------------------------------------------------------------------
!
INTEGER :: istatus
!
!-----------------------------------------------------------------------
!
! Misc.local variables
!
!-----------------------------------------------------------------------
!
REAL :: ftabinv,setexp
INTEGER :: i,j,k,ipass,isrc,sngsw,uasw,radsw,retsw
REAL :: rpass,zrngsq,thrngsq
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!-----------------------------------------------------------------------
!
! Note in the following the analysis scratch arrays
! are used to hold the output statistics
!
!-----------------------------------------------------------------------
!
ipass=0
WRITE(6,'(a,i4)') 'Computing orig difference stats'
CALL diffnst3d
(nvar, &
nzua,nzret,mxsng,mxua,mxcolret, &
obsng,odifsng,oanxsng,isrcsng,qualsng,nobsng, &
obsua,odifua,oanxua,isrcua,qualua,nlevsua,nobsua, &
obsret,odifret,oanxret,iret, &
qualret,nlevret,ncolret, &
knt,wgtsum,zsum)
!
WRITE(6,805) ipass
805 FORMAT(' Statistics for analysis pass ',i4,/ &
' ivar name knt bias rms')
DO k=1,nvar
WRITE(6,812) k,nam_var(k),knt(k,1),wgtsum(k,1),zsum(k,1)
812 FORMAT(i6,2X,a6,i6,g12.3,g11.3)
END DO
CALL diffnstra
(nvar,nvarrad,nvarradin,nzrdr,mxrad,mxcolrad, &
elvrad,distrad,hgtradc, &
uazmrad,vazmrad,qualrad,irad, &
obsrad,odifrad,oanxrad, &
nlevrad,ncolrad, &
knt,wgtsum,zsum)
WRITE(6,815)
815 FORMAT(' Radar data variables ',i4,/ &
' ivar name knt bias rms')
DO k=1,nvar
WRITE(6,812) k,nam_var(k),knt(k,1),wgtsum(k,1),zsum(k,1)
END DO
WRITE(6,806)
806 FORMAT(/,' ')
IF(iwstat > 0) THEN
WRITE(iwstat,820) ipass
DO k=1,nvarrad
WRITE(iwstat,812) k,nam_var(k), &
knt(k,1),wgtsum(k,1),zsum(k,1)
END DO
END IF
!
!-----------------------------------------------------------------------
!
! Initialize correlation lookup table.
!
!-----------------------------------------------------------------------
!
ftabinv=setexp(16.)
!
!-----------------------------------------------------------------------
!
! Loop through npass analysis iterations
!
!-----------------------------------------------------------------------
!
DO ipass=1,npass
!
!-----------------------------------------------------------------------
!
! Set single-level usage switch based in iusesng
!
!-----------------------------------------------------------------------
!
WRITE(6,'(/a,i4)') ' Source usage switches for pass ',ipass
WRITE(6,'(/a,i4)') ' Single level data'
sngsw=0
DO isrc=1,nsrcsng
IF(iusesng(isrc,ipass) > 0) THEN
sngsw=1
WRITE(6,'(a,a)') ' Using ',srcsng(isrc)
END IF
END DO
IF(sngsw == 0) WRITE(6,'(a)') ' none'
!
!-----------------------------------------------------------------------
!
! Set multiple-level usage switch based in iuseua
!
!-----------------------------------------------------------------------
!
WRITE(6,'(/a,i4)') ' Multiple level data'
uasw=0
DO isrc=1,nsrcua
IF(iuseua(isrc,ipass) > 0) THEN
uasw=1
WRITE(6,'(a,a)') ' Using ',srcua(isrc)
END IF
END DO
IF(uasw == 0) WRITE(6,'(a)') ' none'
!
!-----------------------------------------------------------------------
!
! Set radar-data usage switch based in iuserad
!
!-----------------------------------------------------------------------
!
WRITE(6,'(/a,i4)') ' Raw radar data'
radsw=0
DO isrc=1,nsrcrad
IF(iuserad(isrc,ipass) > 0) THEN
radsw=1
WRITE(6,'(a,a)') ' Using ',srcrad(isrc)
END IF
END DO
IF(radsw == 0) WRITE(6,'(a)') ' none'
!
!-----------------------------------------------------------------------
!
! Set ret usage switch based in iuseret
!
!-----------------------------------------------------------------------
!
WRITE(6,'(/a,i4)') ' Retrieval radar data'
retsw=0
DO isrc=1,nsrcret
IF(iuseret(isrc,ipass) > 0) THEN
retsw=1
WRITE(6,'(a,a)') ' Using ',srcret(isrc)
END IF
END DO
IF(retsw == 0) WRITE(6,'(a)') ' none'
rpass=xyrange(ipass)*xyrange(ipass)
zrngsq=zrange(ipass)*zrange(ipass)
thrngsq=thrng(ipass)*thrng(ipass)
!
IF(ianxtyp(ipass) == 11) THEN
WRITE(6,'(/a,a,i4)') 'Barnes on grid using height', &
' ipass=',ipass
CALL bargrd3d
(nx,ny,nz, &
nvar,nvarrad,nzua,nzrdr,nzret, &
mxsng,mxua,mxrad,mxcolrad,mxret,mxcolret, &
nsrcsng,nsrcua,nsrcrad,nsrcret,xs,ys,zs, &
odifsng,xsng,ysng,hgtsng,qualsng,isrcsng,nobsng, &
odifua,xua,yua,hgtua,qualua,isrcua,nlevsua,nobsua, &
odifrad,xradc,yradc,hgtradc, &
uazmrad,vazmrad,qualrad, &
irad,isrcrad,nlevrad,ncolrad, &
odifret,xretc,yretc,hgtretc, &
qualret,iret,isrcret,nlevret,ncolret, &
iusesng(0,ipass),iuseua(0,ipass), &
iuserad(0,ipass),iuseret(0,ipass), &
sngsw,uasw,radsw,retsw,kpvrsq,rpass, &
wlim,zrngsq,zwlim, &
rngsqi,knt,wgtsum,zsum, &
anx,istatus)
!
WRITE(6,'(/a,a,i4)') 'Barnes at obs sites using height', &
' ipass=',ipass
CALL barobs3d
(nvar,nvarrad,nzua,nzrdr,nzret, &
mxsng,mxua,mxrad,mxcolrad,mxret,mxcolret, &
nsrcsng,nsrcua,nsrcrad,nsrcret, &
odifsng,xsng,ysng,hgtsng,qualsng,isrcsng,nobsng, &
odifua,xua,yua,hgtua,qualua,isrcua,nlevsua,nobsua, &
odifrad,xradc,yradc,hgtradc,uazmrad,vazmrad, &
qualrad,irad,isrcrad,nlevrad,ncolrad, &
odifret,xretc,yretc,hgtretc, &
qualret,iret,isrcret,nlevret,ncolret, &
iusesng(0,ipass),iuseua(0,ipass), &
iuserad(0,ipass),iuseret(0,ipass), &
sngsw,uasw,radsw,retsw,kpvrsq,rpass, &
wlim,zrngsq,zwlim, &
rngsqi,knt,wgtsum,zsum, &
oanxsng,oanxua,oanxrad,oanxret,istatus)
!
ELSE IF(ianxtyp(ipass) == 21) THEN
!
CALL obscor
(nvar,nvarrad,nzua,nzrdr,nzret, &
mxsng,mxua,mxrad,mxcolrad,mxret,mxcolret, &
nsrcsng,nsrcua,nsrcrad,nsrcret,ncat,xcor, &
qobsng,xsng,ysng,hgtsng, &
qualsng,isrcsng,icatsng,nobsng, &
qobsua,xua,yua,hgtua, &
qualua,isrcua,nlevsua,nobsua, &
qobsrad,xradc,yradc,hgtradc, &
uazmrad,vazmrad, &
qualrad,irad,isrcrad,nlevrad,ncolrad, &
qobsret,xretc,yretc,hgtretc, &
qualret,iret,isrcret,nlevret,ncolret, &
iusesng(0,ipass),iuseua(0,ipass), &
iuserad(0,ipass),iuseret(0,ipass), &
sngsw,uasw,radsw,retsw,kpvrsq,rpass,rngsqi, &
wlim,zrngsq, &
corsng,corua,corrad,corret,istatus)
!
!-----------------------------------------------------------------------
!
! Calculate covariance sums at observation points for
!
!-----------------------------------------------------------------------
!
WRITE(6,'(/a,a,i4)') 'Bratseth on grid using height', &
' ipass=',ipass
CALL brtgrd3d
(nx,ny,nz,nvar,nvarrad, &
nzua,nzrdr,nzret, &
mxsng,mxua,mxrad,mxcolrad,mxret,mxcolret, &
nsrcsng,nsrcua,nsrcrad,nsrcret,ncat,xs,ys,zs,icatg,xcor, &
odifsng,corsng,xsng,ysng,hgtsng,isrcsng,icatsng,nobsng, &
odifua,corua,xua,yua,hgtua,isrcua,nlevsua,nobsua, &
odifrad,corrad,xradc,yradc,hgtradc, &
uazmrad,vazmrad,irad,isrcrad,nlevrad,ncolrad, &
odifret,corret,xretc,yretc,hgtretc, &
iret,isrcret,nlevret,ncolret, &
iusesng(0,ipass),iuseua(0,ipass), &
iuserad(0,ipass),iuseret(0,ipass), &
sngsw,uasw,radsw,retsw,kpvrsq,rpass, &
wlim,zrngsq,rngsqi, &
anx,tem1,tem2,ibegin,iend,istatus)
!
WRITE(6,'(a,a,i4)') 'Bratseth at obs sites using height', &
' ipass=',ipass
CALL brtobs3d
(nvar,nvarrad,nzua,nzrdr,nzret, &
mxsng,mxua,mxrad,mxcolrad,mxret,mxcolret, &
nsrcsng,nsrcua,nsrcrad,nsrcret,ncat,xcor, &
odifsng,qobsng,corsng,xsng,ysng,hgtsng, &
isrcsng,icatsng,nobsng, &
odifua,qobsua,corua,xua,yua,hgtua,isrcua,nlevsua,nobsua, &
odifrad,qobsrad,corrad,xradc,yradc,hgtradc, &
uazmrad,vazmrad,irad,isrcrad,nlevrad,ncolrad, &
odifret,qobsret,corret,xretc,yretc,hgtretc, &
iret,isrcret,nlevret,ncolret, &
iusesng(0,ipass),iuseua(0,ipass), &
iuserad(0,ipass),iuseret(0,ipass), &
sngsw,uasw,radsw,retsw,kpvrsq,rpass, &
wlim,zrngsq,rngsqi, &
oanxsng,oanxua,oanxrad,oanxret,istatus)
ELSE
!
CALL obscor
(nvar,nvarrad,nzua,nzrdr,nzret, &
mxsng,mxua,mxrad,mxcolrad,mxret,mxcolret, &
nsrcsng,nsrcua,nsrcrad,nsrcret,ncat,xcor, &
qobsng,xsng,ysng,thesng, &
qualsng,isrcsng,icatsng,nobsng, &
qobsua,xua,yua,theua, &
qualua,isrcua,nlevsua,nobsua, &
qobsrad,xradc,yradc,theradc, &
uazmrad,vazmrad, &
qualrad,irad,isrcrad,nlevrad,ncolrad, &
qobsret,xretc,yretc,theretc, &
qualret,iret,isrcret,nlevret,ncolret, &
iusesng(0,ipass),iuseua(0,ipass), &
iuserad(0,ipass),iuseret(0,ipass), &
sngsw,uasw,radsw,retsw,kpvrsq,rpass,rngsqi, &
wlim,thrngsq, &
corsng,corua,corrad,corret,istatus)
!
WRITE(6,'(/a,a,i4)') 'Bratseth on grid using theta', &
' ipass=',ipass
!
DO k=1,nz
DO j=1,ny
DO i=1,nx
tem3(i,j,k)=anx(i,j,k,4)
END DO
END DO
END DO
!
CALL brtgrd3d
(nx,ny,nz,nvar,nvarrad, &
nzua,nzrdr,nzret, &
mxsng,mxua,mxrad,mxcolrad,mxret,mxcolret, &
nsrcsng,nsrcua,nsrcrad,nsrcret,ncat, &
xs,ys,tem3,icatg,xcor, &
odifsng,corsng,xsng,ysng,thesng, &
isrcsng,icatsng,nobsng, &
odifua,corua,xua,yua,theua,isrcua,nlevsua,nobsua, &
odifrad,corrad,xradc,yradc,theradc, &
uazmrad,vazmrad,irad,isrcrad,nlevrad,ncolrad, &
odifret,corret,xretc,yretc,theretc, &
iret,isrcret,nlevret,ncolret, &
iusesng(0,ipass),iuseua(0,ipass), &
iuserad(0,ipass),iuseret(0,ipass), &
sngsw,uasw,radsw,retsw,kpvrsq,rpass, &
wlim,thrngsq,rngsqi, &
anx,tem1,tem2,ibegin,iend,istatus)
!
WRITE(6,'(a,a,i4)') 'Bratseth at obs sites using theta', &
' ipass=',ipass
!
!-----------------------------------------------------------------------
!
CALL brtobs3d
(nvar,nvarrad,nzua,nzrdr,nzret, &
mxsng,mxua,mxrad,mxcolrad,mxret,mxcolret, &
nsrcsng,nsrcua,nsrcrad,nsrcret,ncat,xcor, &
odifsng,qobsng,corsng,xsng,ysng,thesng, &
isrcsng,icatsng,nobsng, &
odifua,qobsua,corua,xua,yua,theua, &
isrcua,nlevsua,nobsua, &
odifrad,qobsrad,corrad,xradc,yradc,theradc, &
uazmrad,vazmrad,irad,isrcrad,nlevrad,ncolrad, &
odifret,qobsret,corret,xretc,yretc,theretc, &
iret,isrcret,nlevret,ncolret, &
iusesng(0,ipass),iuseua(0,ipass), &
iuserad(0,ipass),iuseret(0,ipass), &
sngsw,uasw,radsw,retsw,kpvrsq,rpass, &
wlim,thrngsq,rngsqi, &
oanxsng,oanxua,oanxrad,oanxret,istatus)
END IF
!
!-----------------------------------------------------------------------
!
! Note in the following the analysis scratch arrays
! are used to hold the output statistics
!
!-----------------------------------------------------------------------
!
WRITE(6,'(a,i4)') 'Computing new differences, ipass=',ipass
CALL diffnst3d
(nvar, &
nzua,nzret,mxsng,mxua,mxcolret, &
obsng,odifsng,oanxsng,isrcsng,qualsng,nobsng, &
obsua,odifua,oanxua,isrcua,qualua,nlevsua,nobsua, &
obsret,odifret,oanxret,iret, &
qualret,nlevret,ncolret, &
knt,wgtsum,zsum)
!
WRITE(6,820) ipass
820 FORMAT(' Statistics for analysis pass ',i4,/ &
' ivar name knt bias rms')
DO k=1,nvar
WRITE(6,812) k,nam_var(k),knt(k,1),wgtsum(k,1),zsum(k,1)
END DO
IF(iwstat > 0) THEN
WRITE(iwstat,820) ipass
DO k=1,nvar
WRITE(iwstat,812) k,nam_var(k), &
knt(k,1),wgtsum(k,1),zsum(k,1)
END DO
WRITE(iwstat,806)
END IF
CALL diffnstra
(nvar,nvarrad,nvarradin,nzrdr,mxrad,mxcolrad, &
elvrad,distrad,hgtradc, &
uazmrad,vazmrad,qualrad,irad, &
obsrad,odifrad,oanxrad, &
nlevrad,ncolrad, &
knt,wgtsum,zsum)
WRITE(6,815)
DO k=1,nvar
WRITE(6,812) k,nam_var(k),knt(k,1),wgtsum(k,1),zsum(k,1)
END DO
WRITE(6,806)
!
END DO
!
istatus=0
RETURN
END SUBROUTINE anxiter
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE DIFFNST3d ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE diffnst3d(nvar, & 2
nzua,nzret,mxsng,mxua,mxcolret, &
obsng,odifsng,oanxsng,isrcsng,qualsng,nobsng, &
obsua,odifua,oanxua,isrcua,qualua,nlevsua,nobsua, &
obsret,odifret,oanxret,iret, &
qualret,nlevret,ncolret, &
knt,dmean,drms)
!
!-----------------------------------------------------------------------
!
! 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.
!
!-----------------------------------------------------------------------
!
! Variable Declarations:
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
INTEGER :: nvar
INTEGER :: nzua,nzret,mxsng,mxua,mxcolret
!
REAL :: obsng(nvar,mxsng)
REAL :: odifsng(nvar,mxsng)
REAL :: oanxsng(nvar,mxsng)
INTEGER :: isrcsng(mxsng)
INTEGER :: qualsng(nvar,mxsng)
INTEGER :: nobsng
!
REAL :: obsua(nvar,nzua,mxua)
REAL :: odifua(nvar,nzua,mxua)
REAL :: oanxua(nvar,nzua,mxua)
INTEGER :: isrcua(mxua)
INTEGER :: qualua(nvar,nzua,mxua)
INTEGER :: nlevsua(mxua)
INTEGER :: nobsua
!
REAL :: obsret(nvar,nzret,mxcolret)
REAL :: odifret(nvar,nzret,mxcolret)
REAL :: oanxret(nvar,nzret,mxcolret)
INTEGER :: iret(mxcolret)
INTEGER :: qualret(nvar,nzret,mxcolret)
INTEGER :: nlevret(mxcolret)
INTEGER :: ncolret
!
INTEGER :: knt(nvar)
REAL :: dmean(nvar)
REAL :: drms(nvar)
!
!-----------------------------------------------------------------------
!
! Misc.local variables
!
!-----------------------------------------------------------------------
!
INTEGER :: ivar,jsta,klev
REAL :: flknt
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
DO ivar=1,nvar
knt(ivar)=0
dmean(ivar)=0.
drms(ivar)=0.
END DO
!
!-----------------------------------------------------------------------
!
! Find differences and form sums at single-level sites
!
!-----------------------------------------------------------------------
!
DO jsta=1,nobsng
IF(isrcsng(jsta) /= 0) THEN
DO ivar=1,nvar
IF(qualsng(ivar,jsta) > 0) THEN
odifsng(ivar,jsta)=obsng(ivar,jsta)-oanxsng(ivar,jsta)
knt(ivar)=knt(ivar)+1
dmean(ivar)=dmean(ivar)-odifsng(ivar,jsta)
drms(ivar)=drms(ivar)+ &
odifsng(ivar,jsta)*odifsng(ivar,jsta)
END IF
END DO
END IF
END DO
!
!-----------------------------------------------------------------------
!
! Find differences at multiple-level sites
! Add to sums
!
!-----------------------------------------------------------------------
!
DO jsta=1,nobsua
IF(isrcua(jsta) /= 0) THEN
DO klev=1,nlevsua(jsta)
DO ivar=1,nvar
IF(qualua(ivar,klev,jsta) > 0) THEN
odifua(ivar,klev,jsta)= &
obsua(ivar,klev,jsta)-oanxua(ivar,klev,jsta)
knt(ivar)=knt(ivar)+1
dmean(ivar)=dmean(ivar)-odifua(ivar,klev,jsta)
drms(ivar)=drms(ivar)+ &
odifua(ivar,klev,jsta)*odifua(ivar,klev,jsta)
END IF
END DO
END DO
END IF
END DO
!
!-----------------------------------------------------------------------
!
! Find differences at retrieval columns
! Add to sums
!
!-----------------------------------------------------------------------
!
DO jsta=1,ncolret
IF(iret(jsta) > 0) THEN
DO klev=1,nlevret(jsta)
DO ivar=1,nvar
IF(qualret(ivar,klev,jsta) > 0) THEN
odifret(ivar,klev,jsta)= &
obsret(ivar,klev,jsta)-oanxret(ivar,klev,jsta)
knt(ivar)=knt(ivar)+1
dmean(ivar)=dmean(ivar)-odifret(ivar,klev,jsta)
drms(ivar)=drms(ivar)+ &
odifret(ivar,klev,jsta)*odifret(ivar,klev,jsta)
END IF
END DO
END DO
END IF
END DO
!
!-----------------------------------------------------------------------
!
! Calculate stats from the sums formed above
!
!-----------------------------------------------------------------------
!
DO ivar=1,nvar
IF(knt(ivar) > 0) THEN
flknt=FLOAT(knt(ivar))
dmean(ivar)=dmean(ivar)/flknt
drms(ivar)=SQRT(drms(ivar)/flknt)
ELSE
dmean(ivar)=0.
drms(ivar)=0.
END IF
END DO
!
RETURN
END SUBROUTINE diffnst3d
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE DIFFNSTRA ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
SUBROUTINE diffnstra(nvar,nvarrad,nvarradin,nzrdr,mxrad,mxcolrad, & 2,2
elvrad,distrad,hgtradc, &
uazmrad,vazmrad,qualrad,irad, &
obsrad,odifrad,oanxrad, &
nlevrad,ncolrad, &
knt,dmean,drms)
!
!-----------------------------------------------------------------------
!
! 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.
!
!
!-----------------------------------------------------------------------
!
! Variable Declarations:
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
INTEGER :: nvar,nvarrad,nvarradin,nzrdr,mxrad,mxcolrad
!
REAL :: elvrad(mxrad)
REAL :: distrad(mxcolrad)
REAL :: hgtradc(nzrdr,mxcolrad)
REAL :: uazmrad(mxcolrad)
REAL :: vazmrad(mxcolrad)
INTEGER :: qualrad(nvarrad,nzrdr,mxcolrad)
INTEGER :: irad(mxcolrad)
REAL :: obsrad(nvarradin,nzrdr,mxcolrad)
REAL :: odifrad(nvarrad,nzrdr,mxcolrad)
REAL :: oanxrad(nvarrad,nzrdr,mxcolrad)
INTEGER :: nlevrad(mxcolrad)
INTEGER :: ncolrad
!
INTEGER :: knt(nvar)
REAL :: dmean(nvar)
REAL :: drms(nvar)
!
!-----------------------------------------------------------------------
!
! Misc.local variables
!
!-----------------------------------------------------------------------
!
INTEGER :: icol,ivar,kr,jrad
REAL :: pi,dtr,delz,eleva,range,flknt
REAL :: vr,vrdiff,avrdif,dhdr,dsdr,dsdrinv
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
knt(ivar)=0
dmean(ivar)=0.
drms(ivar)=0.
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)
!
DO kr=1,nlevrad(icol)
IF(qualrad(1,kr,icol) > 0 .AND. qualrad(2,kr,icol) > 0 ) THEN
!
delz=hgtradc(kr,icol)-elvrad(jrad)
CALL beamelv
(delz,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
!
vr=(uazmrad(icol)*oanxrad(1,kr,icol) + &
vazmrad(icol)*oanxrad(2,kr,icol)) * dsdr
vrdiff=obsrad(2,kr,icol)-vr
avrdif=ABS(vrdiff)
IF(avrdif < vrqcthr) THEN
!
!-----------------------------------------------------------------------
!
! Find increment in analysis u and v needed to make vrdiff zero
!
!-----------------------------------------------------------------------
!
odifrad(1,kr,icol)=dsdrinv*uazmrad(icol)*vrdiff
odifrad(2,kr,icol)=dsdrinv*vazmrad(icol)*vrdiff
!
knt(1)=knt(1)+1
dmean(1)=dmean(1)-odifrad(1,kr,icol)
drms(1)=drms(1)+ &
odifrad(1,kr,icol)*odifrad(1,kr,icol)
knt(2)=knt(2)+1
dmean(2)=dmean(2)-odifrad(2,kr,icol)
drms(2)=drms(2)+ &
odifrad(2,kr,icol)*odifrad(2,kr,icol)
ELSE
odifrad(1,kr,icol)=vr_miss
qualrad(1,kr,icol)=-199
odifrad(2,kr,icol)=vr_miss
qualrad(2,kr,icol)=-199
END IF
END IF
IF(qualrad(3,kr,icol) > 0) THEN
odifrad(3,kr,icol)=obsrad(1,kr,icol)-oanxrad(3,kr,icol)
! print *, ' kr,icol,obsrad,oanx= ',kr,icol,
! + obsrad(1,kr,icol),oanxrad(3,kr,icol)
knt(5)=knt(5)+1
dmean(5)=dmean(5)-odifrad(3,kr,icol)
drms(5)=drms(5)+ &
odifrad(3,kr,icol)*odifrad(3,kr,icol)
END IF
END DO
END IF
END DO
!
!-----------------------------------------------------------------------
!
! Calculate stats from the sums formed above
!
!-----------------------------------------------------------------------
!
DO ivar=1,nvar
IF(knt(ivar) > 0) THEN
flknt=FLOAT(knt(ivar))
dmean(ivar)=dmean(ivar)/flknt
drms(ivar)=SQRT(drms(ivar)/flknt)
ELSE
dmean(ivar)=0.
drms(ivar)=0.
END IF
END DO
!
RETURN
END SUBROUTINE diffnstra
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE BAROBS3d ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE barobs3d(nvar,nvarrad,nzua,nzrdr,nzret, & 1
mxsng,mxua,mxrad,mxcolrad,mxret,mxcolret, &
nsrcsng,nsrcua,nsrcrad,nsrcret, &
odifsng,xsng,ysng,hgtsng,qualsng,isrcsng,nobsng, &
odifua,xua,yua,hgtua,qualua,isrcua,nlevsua,nobsua, &
odifrad,xradc,yradc,hgtradc,uazmrad,vazmrad, &
qualrad,irad,isrcrad,nlevrad,ncolrad, &
odifret,xretc,yretc,hgtretc, &
qualret,iret,isrcret,nlevret,ncolret, &
iusesng,iuseua,iuserad,iuseret, &
sngsw,uasw,radsw,retsw,kpvrsq,rpass, &
wlim,zrngsq,zwlim, &
rngsqi,knt,wgtsum,zsum, &
oanxsng,oanxua,oanxrad,oanxret,istatus)
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Objectively analyze data at observation pts
! Barnes weight function is employed.
!
!-----------------------------------------------------------------------
!
! AUTHOR: Keith Brewster, CAPS
! July, 1995
!
! MODIFICATION HISTORY:
!
! Jan, 1996 (KB)
! Added radar data and other improvements.
!
! July, 1996 (KB)
! Added sngsw and uasw to switch on/off use of single-level
! and sounding data, respectively.
!
!-----------------------------------------------------------------------
!
! Variable Declarations:
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
!
!-----------------------------------------------------------------------
!
! Sizing arguments
!
!-----------------------------------------------------------------------
!
INTEGER :: nvar,nvarrad,nzua,nzrdr,nzret
INTEGER :: mxsng,mxua,mxrad,mxcolrad,mxret,mxcolret
INTEGER :: nsrcsng,nsrcua,nsrcrad,nsrcret
!
!-----------------------------------------------------------------------
!
! Observation Arguments
!
!-----------------------------------------------------------------------
!
REAL :: odifsng(nvar,mxsng), &
xsng(mxsng), &
ysng(mxsng), &
hgtsng(mxsng)
INTEGER :: qualsng(nvar,mxsng)
INTEGER :: isrcsng(mxsng)
INTEGER :: nobsng
REAL :: odifua(nvar,nzua,mxua) ! variable to analyse
REAL :: xua(mxua)
REAL :: yua(mxua)
REAL :: hgtua(nzua,mxua)
INTEGER :: qualua(nvar,nzua,mxua)
INTEGER :: nlevsua(mxua)
INTEGER :: isrcua(mxua)
INTEGER :: nobsua
!
REAL :: odifrad(nvarrad,nzrdr,mxcolrad)
REAL :: xradc(mxcolrad)
REAL :: yradc(mxcolrad)
REAL :: uazmrad(mxcolrad)
REAL :: vazmrad(mxcolrad)
REAL :: hgtradc(nzrdr,mxcolrad)
INTEGER :: qualrad(nvarrad,nzrdr,mxcolrad)
INTEGER :: nlevrad(mxcolrad)
INTEGER :: irad(mxcolrad)
INTEGER :: isrcrad(0:mxrad)
INTEGER :: ncolrad
!
REAL :: odifret(nvar,nzret,mxcolret)
REAL :: xretc(mxcolret)
REAL :: yretc(mxcolret)
REAL :: hgtretc(nzret,mxcolret)
INTEGER :: qualret(nvar,nzret,mxcolret)
INTEGER :: nlevret(mxcolret)
INTEGER :: iret(mxcolret)
INTEGER :: isrcret(0:mxret)
INTEGER :: ncolret
!
!-----------------------------------------------------------------------
!
! Scratch space
!
!-----------------------------------------------------------------------
!
INTEGER :: knt(nvar)
REAL :: rngsqi(nvar)
REAL :: wgtsum(nvar)
REAL :: zsum(nvar)
!
!-----------------------------------------------------------------------
!
! Analysis specification arguments
!
!-----------------------------------------------------------------------
!
INTEGER :: iusesng(0:nsrcsng)
INTEGER :: iuseua(0:nsrcua)
INTEGER :: iuserad(0:nsrcrad)
INTEGER :: iuseret(0:nsrcret)
INTEGER :: sngsw,uasw,radsw,retsw
REAL :: kpvrsq(nvar)
REAL :: rpass
REAL :: wlim
REAL :: zrngsq
REAL :: zwlim
!
!-----------------------------------------------------------------------
!
! Output arguments
!
!-----------------------------------------------------------------------
!
REAL :: oanxsng(nvar,mxsng)
REAL :: oanxua(nvar,nzua,mxua)
REAL :: oanxrad(nvarrad,nzrdr,mxcolrad)
REAL :: oanxret(nvar,nzret,mxcolret)
INTEGER :: istatus
!
!-----------------------------------------------------------------------
!
! Misc.local variables
!
!-----------------------------------------------------------------------
!
REAL :: texp
REAL :: rlimsq,zlimsq,zsqinv
REAL :: dist,dzsq,wgt
INTEGER :: ista,jsta,k,klev,ivar
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
rlimsq=-rpass*ALOG(wlim)
DO ivar=1,nvar
rngsqi(ivar)=1./(kpvrsq(ivar)*rpass)
END DO
!
zlimsq=-zrngsq*ALOG(zwlim)
zsqinv=1./zrngsq
!
!-----------------------------------------------------------------------
!
! Loop over single stations.
!
!-----------------------------------------------------------------------
!
DO ista=1,nobsng
IF(iusesng(isrcsng(ista)) > 0) THEN
DO ivar=1,nvar
knt(ivar)=0
wgtsum(ivar)=0.
zsum(ivar)=0.
END DO
!
!-----------------------------------------------------------------------
!
! First sum contributions from single-level obs
!
!-----------------------------------------------------------------------
!
IF(sngsw > 0) THEN
DO jsta=1,nobsng
IF(iusesng(isrcsng(jsta)) > 0) THEN
dist=(xsng(ista)-xsng(jsta))*(xsng(ista)-xsng(jsta)) &
+(ysng(ista)-ysng(jsta))*(ysng(ista)-ysng(jsta))
IF(dist < rlimsq) THEN
dzsq=(hgtsng(ista)-hgtsng(jsta)) * &
(hgtsng(ista)-hgtsng(jsta))
IF(dzsq < zlimsq) THEN
DO ivar=1,nvar
IF(qualsng(ivar,jsta) > 0) THEN
knt(ivar)=knt(ivar)+1
wgt=texp(-dist*rngsqi(ivar) -dzsq*zsqinv)
wgtsum(ivar)=wgtsum(ivar) + wgt
zsum(ivar)=zsum(ivar)+ &
wgt*odifsng(ivar,jsta)
END IF
END DO
END IF
END IF ! horizontal dist check
END IF ! source check
END DO
END IF
!
!-----------------------------------------------------------------------
!
! Add contributions from multiple-level obs
!
!-----------------------------------------------------------------------
!
IF(uasw > 0) THEN
DO jsta=1,nobsua
IF(iuseua(isrcua(jsta)) > 0) THEN
dist=(xsng(ista)-xua(jsta))*(xsng(ista)-xua(jsta)) &
+(ysng(ista)-yua(jsta))*(ysng(ista)-yua(jsta))
IF(dist < rlimsq) THEN
DO klev=1,nlevsua(jsta)
dzsq=(hgtsng(ista)-hgtua(klev,jsta)) * &
(hgtsng(ista)-hgtua(klev,jsta))
IF(dzsq < zlimsq) THEN
DO ivar=1,nvar
IF(qualua(ivar,klev,jsta) > 0) THEN
knt(ivar)=knt(ivar)+1
wgt=texp(-dist*rngsqi(ivar) -dzsq*zsqinv)
wgtsum(ivar)=wgtsum(ivar) + wgt
zsum(ivar)=zsum(ivar)+ &
wgt*odifua(ivar,klev,jsta)
END IF
END DO
END IF
END DO
END IF ! horizontal dist check
END IF ! source check
END DO
END IF
!
!-----------------------------------------------------------------------
!
! Add contributions from radar obs
!
!-----------------------------------------------------------------------
!
IF(radsw > 0) THEN
DO jsta=1,ncolrad
IF(iuserad(isrcrad(irad(jsta))) > 0) THEN
dist=(xsng(ista)-xradc(jsta))*(xsng(ista)-xradc(jsta)) &
+(ysng(ista)-yradc(jsta))*(ysng(ista)-yradc(jsta))
IF(dist < rlimsq) THEN
DO klev=1,nlevrad(jsta)
dzsq=(hgtsng(ista)-hgtradc(klev,jsta)) * &
(hgtsng(ista)-hgtradc(klev,jsta))
IF(dzsq < zlimsq) THEN
IF(qualrad(1,klev,jsta) > 0) THEN
knt(1)=knt(1)+1
wgt=texp(-dist*rngsqi(1) -dzsq*zsqinv)
wgtsum(1)=wgtsum(1)+wgt* &
ABS(uazmrad(jsta))
zsum(1)=zsum(1)+ &
wgt*odifrad(1,klev,jsta) * &
ABS(uazmrad(jsta))
END IF
IF(qualrad(2,klev,jsta) > 0) THEN
knt(2)=knt(2)+1
wgt=texp(-dist*rngsqi(2) -dzsq*zsqinv)
wgtsum(2)=wgtsum(2)+wgt* &
ABS(vazmrad(jsta))
zsum(2)=zsum(2)+ &
wgt*odifrad(2,klev,jsta) * &
ABS(vazmrad(jsta))
END IF
IF(qualrad(3,klev,jsta) > 0) THEN
knt(5)=knt(5)+1
wgt=texp(-dist*rngsqi(5) -dzsq*zsqinv)
wgtsum(5)=wgtsum(5)+wgt
zsum(5)=zsum(5)+ &
wgt*odifrad(3,klev,jsta)
END IF
END IF
END DO
END IF ! horizontal dist check
END IF ! source check
END DO
END IF
!
!-----------------------------------------------------------------------
!
! Add contributions from retrieval obs
!
!-----------------------------------------------------------------------
!
IF(retsw > 0) THEN
DO jsta=1,ncolret
IF(iuseret(isrcret(iret(jsta))) > 0) THEN
dist=(xsng(ista)-xretc(jsta))*(xsng(ista)-xretc(jsta)) &
+(ysng(ista)-yretc(jsta))*(ysng(ista)-yretc(jsta))
IF(dist < rlimsq) THEN
DO klev=1,nlevret(jsta)
dzsq=(hgtsng(ista)-hgtretc(klev,jsta)) * &
(hgtsng(ista)-hgtretc(klev,jsta))
IF(dzsq < zlimsq) THEN
DO ivar=1,nvar
IF(qualret(ivar,klev,jsta) > 0) THEN
knt(ivar)=knt(ivar)+1
wgt=texp(-dist*rngsqi(ivar) -dzsq*zsqinv)
wgtsum(ivar)=wgtsum(ivar) + wgt
zsum(ivar)=zsum(ivar)+ &
wgt*odifret(ivar,klev,jsta)
END IF
END DO
END IF
END DO
END IF ! horizontal dist check
END IF ! source check
END DO
END IF
!
!-----------------------------------------------------------------------
!
! Divide by sum of weights
!
!-----------------------------------------------------------------------
!
DO ivar=1,nvar
IF(wgtsum(ivar) > wlim) oanxsng(ivar,ista)=oanxsng(ivar,ista) + &
zsum(ivar)/wgtsum(ivar)
END DO
END IF
END DO
!
!-----------------------------------------------------------------------
!
! Loop over all multi-level obs
!
!-----------------------------------------------------------------------
!
DO ista=1,nobsua
IF(iuseua(isrcua(ista)) > 0) THEN
DO k=1,nlevsua(ista)
DO ivar=1,nvar
zsum(ivar)=0.
wgtsum(ivar)=0.
knt(ivar)=0
END DO
!
!-----------------------------------------------------------------------
!
! First sum contributions from single-level obs
!
!-----------------------------------------------------------------------
!
IF(sngsw > 0) THEN
DO jsta=1,nobsng
IF(iusesng(isrcsng(jsta)) > 0) THEN
dist=(xua(ista)-xsng(jsta))*(xua(ista)-xsng(jsta)) &
+(yua(ista)-ysng(jsta))*(yua(ista)-ysng(jsta))
IF(dist < rlimsq) THEN
dzsq=(hgtua(k,ista)-hgtsng(jsta)) * &
(hgtua(k,ista)-hgtsng(jsta))
IF(dzsq < zlimsq) THEN
DO ivar=1,nvar
IF(qualsng(ivar,jsta) > 0) THEN
knt(ivar)=knt(ivar)+1
wgt=texp(-dist*rngsqi(ivar) -dzsq*zsqinv)
wgtsum(ivar)=wgtsum(ivar) + wgt
zsum(ivar)=zsum(ivar)+ &
wgt*odifsng(ivar,jsta)
END IF
END DO
END IF
END IF ! horizontal dist check
END IF ! source check
END DO
END IF
!
!-----------------------------------------------------------------------
!
! Add contributions from multiple-level obs
!
!-----------------------------------------------------------------------
!
IF(uasw > 0) THEN
DO jsta=1,nobsua
IF(iuseua(isrcua(jsta)) > 0) THEN
dist=(xua(ista)-xua(jsta))*(xua(ista)-xua(jsta)) &
+(yua(ista)-yua(jsta))*(yua(ista)-yua(jsta))
IF(dist < rlimsq) THEN
DO klev=1,nlevsua(jsta)
dzsq=(hgtua(k,ista)-hgtua(klev,jsta)) * &
(hgtua(k,ista)-hgtua(klev,jsta))
IF(dzsq < zlimsq) THEN
DO ivar=1,nvar
IF(qualua(ivar,klev,jsta) > 0) THEN
knt(ivar)=knt(ivar)+1
wgt=texp(-dist*rngsqi(ivar) -dzsq*zsqinv)
wgtsum(ivar)=wgtsum(ivar) + wgt
zsum(ivar)=zsum(ivar)+ &
wgt*odifua(ivar,klev,jsta)
END IF
END DO
END IF
END DO
END IF ! horizontal dist check
END IF ! source check
END DO
END IF
!
!-----------------------------------------------------------------------
!
! Add contributions from radar obs
!
!-----------------------------------------------------------------------
!
IF(radsw > 0) THEN
DO jsta=1,ncolrad
IF(iuserad(isrcrad(irad(jsta))) > 0) THEN
dist=(xua(ista)-xradc(jsta))*(xua(ista)-xradc(jsta)) &
+(yua(ista)-yradc(jsta))*(yua(ista)-yradc(jsta))
IF(dist < rlimsq) THEN
DO klev=1,nlevrad(jsta)
dzsq=(hgtua(k,ista)-hgtradc(klev,jsta)) * &
(hgtua(k,ista)-hgtradc(klev,jsta))
IF(dzsq < zlimsq) THEN
IF(qualrad(1,klev,jsta) > 0) THEN
knt(1)=knt(1)+1
wgt=texp(-dist*rngsqi(1) -dzsq*zsqinv)
wgtsum(1)=wgtsum(1)+wgt* &
ABS(uazmrad(jsta))
zsum(1)=zsum(1)+ &
wgt*odifrad(1,klev,jsta) * &
ABS(uazmrad(jsta))
END IF
IF(qualrad(2,klev,jsta) > 0) THEN
knt(2)=knt(2)+1
wgt=texp(-dist*rngsqi(2) -dzsq*zsqinv)
wgtsum(2)=wgtsum(2)+wgt* &
ABS(vazmrad(jsta))
zsum(2)=zsum(2)+ &
wgt*odifrad(2,klev,jsta) * &
ABS(vazmrad(jsta))
END IF
IF(qualrad(3,klev,jsta) > 0) THEN
knt(5)=knt(5)+1
wgt=texp(-dist*rngsqi(5) -dzsq*zsqinv)
wgtsum(5)=wgtsum(5)+wgt
zsum(5)=zsum(5)+ &
wgt*odifrad(3,klev,jsta)
END IF
END IF
END DO
END IF ! horizontal dist check
END IF ! source check
END DO
END IF
!
!-----------------------------------------------------------------------
!
! Add contributions from retrieval obs
!
!-----------------------------------------------------------------------
!
IF(retsw > 0) THEN
DO jsta=1,ncolret
IF(iuseret(isrcret(iret(jsta))) > 0) THEN
dist=(xua(ista)-xretc(jsta))*(xua(ista)-xretc(jsta)) &
+(yua(ista)-yretc(jsta))*(yua(ista)-yretc(jsta))
IF(dist < rlimsq) THEN
DO klev=1,nlevret(jsta)
dzsq=(hgtua(k,ista)-hgtretc(klev,jsta)) * &
(hgtua(k,ista)-hgtretc(klev,jsta))
IF(dzsq < zlimsq) THEN
DO ivar=1,nvar
IF(qualret(ivar,klev,jsta) > 0) THEN
knt(ivar)=knt(ivar)+1
wgt=texp(-dist*rngsqi(ivar) -dzsq*zsqinv)
wgtsum(ivar)=wgtsum(ivar) + wgt
zsum(ivar)=zsum(ivar)+ &
wgt*odifret(ivar,klev,jsta)
END IF
END DO
END IF
END DO
END IF ! horizontal dist check
END IF ! source check
END DO
END IF
!
!-----------------------------------------------------------------------
!
! Divide by sum of weights
!
!-----------------------------------------------------------------------
!
DO ivar=1,nvar
IF(wgtsum(ivar) > wlim) oanxua(ivar,k,ista)=oanxua(ivar,k,ista) + &
zsum(ivar)/wgtsum(ivar)
END DO
END DO
END IF
END DO
!
!-----------------------------------------------------------------------
!
! Loop over all radar columns
!
!-----------------------------------------------------------------------
!
DO ista=1,ncolrad
IF(iuserad(isrcrad(irad(ista))) > 0) THEN
DO k=1,nlevrad(ista)
IF(qualrad(1,k,ista) > 0 .AND. qualrad(2,k,ista) > 0 ) THEN
DO ivar=1,nvar
zsum(ivar)=0.
wgtsum(ivar)=0.
knt(ivar)=0
END DO
!
!-----------------------------------------------------------------------
!
! First sum contributions from single-level obs
!
!-----------------------------------------------------------------------
!
IF(sngsw > 0) THEN
DO jsta=1,nobsng
IF(iusesng(isrcsng(jsta)) > 0) THEN
dist=(xradc(ista)-xsng(jsta))*(xradc(ista)-xsng(jsta)) &
+(yradc(ista)-ysng(jsta))*(yradc(ista)-ysng(jsta))
IF(dist < rlimsq) THEN
dzsq=(hgtradc(k,ista)-hgtsng(jsta)) * &
(hgtradc(k,ista)-hgtsng(jsta))
IF(dzsq < zlimsq) THEN
DO ivar=1,nvar
IF(qualsng(ivar,jsta) > 0) THEN
knt(ivar)=knt(ivar)+1
wgt=texp(-dist*rngsqi(ivar) -dzsq*zsqinv)
wgtsum(ivar)=wgtsum(ivar) + wgt
zsum(ivar)=zsum(ivar)+ &
wgt*odifsng(ivar,jsta)
END IF
END DO
END IF
END IF ! horizontal dist check
END IF ! source check
END DO
END IF
!
!-----------------------------------------------------------------------
!
! Add contributions from multiple-level obs
!
!-----------------------------------------------------------------------
!
IF(uasw > 0) THEN
DO jsta=1,nobsua
IF(iuseua(isrcua(jsta)) > 0) THEN
dist=(xradc(ista)-xua(jsta))*(xradc(ista)-xua(jsta)) &
+(yradc(ista)-yua(jsta))*(yradc(ista)-yua(jsta))
IF(dist < rlimsq) THEN
DO klev=1,nlevsua(jsta)
dzsq=(hgtradc(k,ista)-hgtua(klev,jsta)) * &
(hgtradc(k,ista)-hgtua(klev,jsta))
IF(dzsq < zlimsq) THEN
DO ivar=1,nvar
IF(qualua(ivar,klev,jsta) > 0) THEN
knt(ivar)=knt(ivar)+1
wgt=texp(-dist*rngsqi(ivar) -dzsq*zsqinv)
wgtsum(ivar)=wgtsum(ivar) + wgt
zsum(ivar)=zsum(ivar)+ &
wgt*odifua(ivar,klev,jsta)
END IF
END DO
END IF
END DO
END IF ! horizontal dist check
END IF ! source check
END DO
END IF
!
!-----------------------------------------------------------------------
!
! Add contributions from radar obs
!
!-----------------------------------------------------------------------
!
IF(radsw > 0) THEN
DO jsta=1,ncolrad
IF(iuserad(isrcrad(irad(jsta))) > 0) THEN
dist=(xradc(ista)-xradc(jsta))*(xradc(ista)-xradc(jsta)) &
+(yradc(ista)-yradc(jsta))*(yradc(ista)-yradc(jsta))
IF(dist < rlimsq) THEN
DO klev=1,nlevrad(jsta)
dzsq=(hgtradc(k,ista)-hgtradc(klev,jsta)) * &
(hgtradc(k,ista)-hgtradc(klev,jsta))
IF(dzsq < zlimsq) THEN
IF(qualrad(1,klev,jsta) > 0) THEN
knt(1)=knt(1)+1
wgt=texp(-dist*rngsqi(1) -dzsq*zsqinv)
wgtsum(1)=wgtsum(1)+wgt* &
ABS(uazmrad(jsta))
zsum(1)=zsum(1)+ &
wgt*odifrad(1,klev,jsta) * &
ABS(uazmrad(jsta))
END IF
IF(qualrad(2,klev,jsta) > 0) THEN
knt(2)=knt(2)+1
wgt=texp(-dist*rngsqi(2) -dzsq*zsqinv)
wgtsum(2)=wgtsum(2)+wgt* &
ABS(vazmrad(jsta))
zsum(2)=zsum(2)+ &
wgt*odifrad(2,klev,jsta) * &
ABS(vazmrad(jsta))
END IF
IF(qualrad(3,klev,jsta) > 0) THEN
knt(5)=knt(5)+1
wgt=texp(-dist*rngsqi(5) -dzsq*zsqinv)
wgtsum(5)=wgtsum(5)+wgt
zsum(5)=zsum(5)+ &
wgt*odifrad(3,klev,jsta)
END IF
END IF
END DO
END IF ! horizontal dist check
END IF ! source check
END DO
END IF
!
!-----------------------------------------------------------------------
!
! Add contributions from radar retrieval obs
!
!-----------------------------------------------------------------------
!
IF(retsw > 0) THEN
DO jsta=1,ncolret
IF(iuseret(isrcret(iret(jsta))) > 0) THEN
dist=(xradc(ista)-xretc(jsta))*(xradc(ista)-xretc(jsta)) &
+(yradc(ista)-yretc(jsta))*(yradc(ista)-yretc(jsta))
IF(dist < rlimsq) THEN
DO klev=1,nlevret(jsta)
dzsq=(hgtradc(k,ista)-hgtretc(klev,jsta)) * &
(hgtradc(k,ista)-hgtretc(klev,jsta))
IF(dzsq < zlimsq) THEN
DO ivar=1,nvar
IF(qualret(ivar,klev,jsta) > 0) THEN
knt(ivar)=knt(ivar)+1
wgt=texp(-dist*rngsqi(ivar) -dzsq*zsqinv)
wgtsum(ivar)=wgtsum(ivar) + wgt
zsum(ivar)=zsum(ivar)+ &
wgt*odifret(ivar,klev,jsta)
END IF
END DO
END IF
END DO
END IF ! horizontal dist check
END IF ! source check
END DO
END IF
!
!-----------------------------------------------------------------------
!
! Divide by sum of weights
!
!-----------------------------------------------------------------------
!
IF(wgtsum(1) > wlim) oanxrad(1,k,ista)=oanxrad(1,k,ista) + &
zsum(1)/wgtsum(1)
IF(wgtsum(2) > wlim) oanxrad(2,k,ista)=oanxrad(2,k,ista) + &
zsum(2)/wgtsum(2)
IF(wgtsum(5) > wlim) oanxrad(3,k,ista)=oanxrad(3,k,ista) + &
zsum(5)/wgtsum(5)
END IF
END DO
END IF
END DO
!
!-----------------------------------------------------------------------
!
! Loop over all radar retrievals
!
!-----------------------------------------------------------------------
!
DO ista=1,ncolret
IF(iuseret(isrcret(iret(ista))) > 0) THEN
DO k=1,nlevret(ista)
DO ivar=1,nvar
zsum(ivar)=0.
wgtsum(ivar)=0.
knt(ivar)=0
END DO
!
!-----------------------------------------------------------------------
!
! First sum contributions from single-level obs
!
!-----------------------------------------------------------------------
!
IF(sngsw > 0) THEN
DO jsta=1,nobsng
IF(iusesng(isrcsng(jsta)) > 0) THEN
dist=(xretc(ista)-xsng(jsta))*(xretc(ista)-xsng(jsta)) &
+(yretc(ista)-ysng(jsta))*(yretc(ista)-ysng(jsta))
IF(dist < rlimsq) THEN
dzsq=(hgtretc(k,ista)-hgtsng(jsta)) * &
(hgtretc(k,ista)-hgtsng(jsta))
IF(dzsq < zlimsq) THEN
DO ivar=1,nvar
IF(qualsng(ivar,jsta) > 0) THEN
knt(ivar)=knt(ivar)+1
wgt=texp(-dist*rngsqi(ivar) -dzsq*zsqinv)
wgtsum(ivar)=wgtsum(ivar) + wgt
zsum(ivar)=zsum(ivar)+ &
wgt*odifsng(ivar,jsta)
END IF
END DO
END IF
END IF ! horizontal dist check
END IF ! source check
END DO
END IF
!
!-----------------------------------------------------------------------
!
! Add contributions from multiple-level obs
!
!-----------------------------------------------------------------------
!
IF(uasw > 0) THEN
DO jsta=1,nobsua
IF(iuseua(isrcua(jsta)) > 0) THEN
dist=(xretc(ista)-xua(jsta))*(xretc(ista)-xua(jsta)) &
+(yretc(ista)-yua(jsta))*(yretc(ista)-yua(jsta))
IF(dist < rlimsq) THEN
DO klev=1,nlevsua(jsta)
dzsq=(hgtretc(k,ista)-hgtua(klev,jsta)) * &
(hgtretc(k,ista)-hgtua(klev,jsta))
IF(dzsq < zlimsq) THEN
DO ivar=1,nvar
IF(qualua(ivar,klev,jsta) > 0) THEN
knt(ivar)=knt(ivar)+1
wgt=texp(-dist*rngsqi(ivar) -dzsq*zsqinv)
wgtsum(ivar)=wgtsum(ivar) + wgt
zsum(ivar)=zsum(ivar)+ &
wgt*odifua(ivar,klev,jsta)
END IF
END DO
END IF
END DO
END IF ! horizontal dist check
END IF ! source check
END DO
END IF
!
!-----------------------------------------------------------------------
!
! Add contributions from radar obs
!
!-----------------------------------------------------------------------
!
IF(radsw > 0) THEN
DO jsta=1,ncolrad
IF(iuserad(isrcrad(irad(jsta))) > 0) THEN
dist=(xretc(ista)-xradc(jsta))*(xretc(ista)-xradc(jsta)) &
+(yretc(ista)-yradc(jsta))*(yretc(ista)-yradc(jsta))
IF(dist < rlimsq) THEN
DO klev=1,nlevrad(jsta)
dzsq=(hgtretc(k,ista)-hgtradc(klev,jsta)) * &
(hgtretc(k,ista)-hgtradc(klev,jsta))
IF(dzsq < zlimsq) THEN
IF(qualrad(1,klev,jsta) > 0) THEN
knt(1)=knt(1)+1
wgt=texp(-dist*rngsqi(1) -dzsq*zsqinv)
wgtsum(1)=wgtsum(1)+wgt* &
ABS(uazmrad(jsta))
zsum(1)=zsum(1)+ &
wgt*odifrad(1,klev,jsta) * &
ABS(uazmrad(jsta))
END IF
IF(qualrad(2,klev,jsta) > 0) THEN
knt(2)=knt(2)+1
wgt=texp(-dist*rngsqi(2) -dzsq*zsqinv)
wgtsum(2)=wgtsum(2)+wgt* &
ABS(vazmrad(jsta))
zsum(2)=zsum(2)+ &
wgt*odifrad(2,klev,jsta) * &
ABS(vazmrad(jsta))
END IF
IF(qualrad(3,klev,jsta) > 0) THEN
knt(5)=knt(5)+1
wgt=texp(-dist*rngsqi(5) -dzsq*zsqinv)
wgtsum(5)=wgtsum(5)+wgt
zsum(5)=zsum(5)+ &
wgt*odifrad(3,klev,jsta)
END IF
END IF
END DO
END IF ! horizontal dist check
END IF ! source check
END DO
END IF
!
!-----------------------------------------------------------------------
!
! Add contributions from retrieval obs
!
!-----------------------------------------------------------------------
!
IF(retsw > 0) THEN
DO jsta=1,ncolret
IF(iuseret(isrcret(jsta)) > 0) THEN
dist=(xretc(ista)-xretc(jsta))*(xretc(ista)-xretc(jsta)) &
+(yretc(ista)-yretc(jsta))*(yretc(ista)-yretc(jsta))
IF(dist < rlimsq) THEN
DO klev=1,nlevret(jsta)
dzsq=(hgtretc(k,ista)-hgtretc(klev,jsta)) * &
(hgtretc(k,ista)-hgtretc(klev,jsta))
IF(dzsq < zlimsq) THEN
DO ivar=1,nvar
IF(qualret(ivar,klev,jsta) > 0) THEN
knt(ivar)=knt(ivar)+1
wgt=texp(-dist*rngsqi(ivar) -dzsq*zsqinv)
wgtsum(ivar)=wgtsum(ivar) + wgt
zsum(ivar)=zsum(ivar)+ &
wgt*odifret(ivar,klev,jsta)
END IF
END DO
END IF
END DO
END IF ! horizontal dist check
END IF ! source check
END DO
END IF
!
!-----------------------------------------------------------------------
!
! Divide by sum of weights
!
!-----------------------------------------------------------------------
!
DO ivar=1,nvar
IF(wgtsum(ivar) > wlim) oanxret(ivar,k,ista)=oanxret(ivar,k,ista) + &
zsum(ivar)/wgtsum(ivar)
END DO
END DO
END IF
END DO
!
istatus=0
RETURN
END SUBROUTINE barobs3d
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE BARGRD3d ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE bargrd3d(nx,ny,nz, & 1
nvar,nvarrad,nzua,nzrdr,nzret, &
mxsng,mxua,mxrad,mxcolrad,mxret,mxcolret, &
nsrcsng,nsrcua,nsrcrad,nsrcret,xs,ys,zs, &
odifsng,xsng,ysng,hgtsng,qualsng,isrcsng,nobsng, &
odifua,xua,yua,hgtua,qualua,isrcua,nlevsua,nobsua, &
odifrad,xradc,yradc,hgtradc, &
uazmrad,vazmrad,qualrad,irad,isrcrad,nlevrad,ncolrad, &
odifret,xretc,yretc,hgtretc, &
qualret,iret,isrcret,nlevret,ncolret, &
iusesng,iuseua,iuserad,iuseret, &
sngsw,uasw,radsw,retsw,kpvrsq,rpass, &
wlim,zrngsq,zwlim, &
rngsqi,knt,wgtsum,zsum, &
anx,istatus)
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Objectively analyze data on a regular grid specified
! by x and y. Barnes weight function is employed.
!
!
!-----------------------------------------------------------------------
!
! AUTHOR: Keith Brewster, CAPS
! September, 1995
!
! MODIFICATION HISTORY:
!
! July, 1996 (KB)
! Added sngsw and uasw to switch on/off use of single-level
! and sounding data, respectively.
!
!-----------------------------------------------------------------------
!
! Variable Declarations:
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
!
!
!-----------------------------------------------------------------------
!
! Sizing Arguments
!
INTEGER :: nx,ny,nz
INTEGER :: nvar,nvarrad,nzua,nzrdr,nzret
INTEGER :: mxsng,mxua,mxrad,mxcolrad,mxret,mxcolret
INTEGER :: nsrcsng,nsrcua,nsrcrad,nsrcret
!
!-----------------------------------------------------------------------
!
! Grid arguments
!
!-----------------------------------------------------------------------
!
REAL :: xs(nx)
REAL :: ys(ny)
REAL :: zs(nx,ny,nz)
!
!-----------------------------------------------------------------------
!
! Observation Arguments
!
!-----------------------------------------------------------------------
!
REAL :: odifsng(nvar,mxsng), &
xsng(mxsng), &
ysng(mxsng), &
hgtsng(mxsng)
INTEGER :: qualsng(nvar,mxsng)
INTEGER :: isrcsng(mxsng)
INTEGER :: nobsng
REAL :: odifua(nvar,nzua,mxua) ! variable to analyse
REAL :: xua(mxua)
REAL :: yua(mxua)
REAL :: hgtua(nzua,mxua)
INTEGER :: qualua(nvar,nzua,mxua)
INTEGER :: nlevsua(mxua)
INTEGER :: isrcua(mxua)
INTEGER :: nobsua
!
REAL :: odifrad(nvarrad,nzrdr,mxcolrad)
REAL :: xradc(mxcolrad)
REAL :: yradc(mxcolrad)
REAL :: hgtradc(nzrdr,mxcolrad)
REAL :: uazmrad(mxcolrad)
REAL :: vazmrad(mxcolrad)
INTEGER :: qualrad(nvarrad,nzrdr,mxcolrad)
INTEGER :: nlevrad(mxcolrad)
INTEGER :: irad(mxcolrad)
INTEGER :: isrcrad(0:mxrad)
INTEGER :: ncolrad
!
REAL :: odifret(nvar,nzret,mxcolret)
REAL :: xretc(mxcolret)
REAL :: yretc(mxcolret)
REAL :: hgtretc(nzret,mxcolret)
INTEGER :: qualret(nvar,nzret,mxcolret)
INTEGER :: nlevret(mxcolret)
INTEGER :: iret(mxcolret)
INTEGER :: isrcret(0:mxret)
INTEGER :: ncolret
!
!-----------------------------------------------------------------------
!
! Scratch space
!
!-----------------------------------------------------------------------
!
REAL :: rngsqi(nvar)
INTEGER :: knt(nvar,nz)
REAL :: wgtsum(nvar,nz)
REAL :: zsum(nvar,nz)
!
!-----------------------------------------------------------------------
!
! Analysis specification arguments
!
!-----------------------------------------------------------------------
!
INTEGER :: iusesng(0:nsrcsng)
INTEGER :: iuseua(0:nsrcua)
INTEGER :: iuserad(0:nsrcrad)
INTEGER :: iuseret(0:nsrcret)
INTEGER :: sngsw,uasw,radsw,retsw
REAL :: kpvrsq(nvar)
REAL :: rpass, &
wlim
REAL :: zrngsq, &
zwlim
!
!-----------------------------------------------------------------------
!
! Output grid arguments
!
!-----------------------------------------------------------------------
!
REAL :: anx(nx,ny,nz,nvar)
INTEGER :: istatus
!
!-----------------------------------------------------------------------
!
! Misc.local variables
!
!-----------------------------------------------------------------------
!
REAL :: texp
REAL :: rlimsq,zlimsq,zsqinv
REAL :: dist,dzsq,wgt
INTEGER :: i,j,k,jsta,klev,ivar
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
rlimsq=-rpass*ALOG(wlim)
DO ivar=1,nvar
rngsqi(ivar)=1./(kpvrsq(ivar)*rpass)
END DO
!
zlimsq=-zrngsq*ALOG(zwlim)
zsqinv=1./zrngsq
!
!-----------------------------------------------------------------------
!
! Loop over all grid points
!
!-----------------------------------------------------------------------
!
DO j=1,ny-1
DO i=1,nx-1
DO k=1,nz-1
DO ivar=1,nvar
knt(ivar,k)=0
wgtsum(ivar,k)=0.
zsum(ivar,k)=0.
END DO
END DO
!
!-----------------------------------------------------------------------
!
! First sum contributions from single-level obs
!
!-----------------------------------------------------------------------
!
IF(sngsw > 0) THEN
DO jsta=1,nobsng
IF(iusesng(isrcsng(jsta)) > 0) THEN
dist=(xs(i)-xsng(jsta))*(xs(i)-xsng(jsta)) &
+(ys(j)-ysng(jsta))*(ys(j)-ysng(jsta))
IF(dist < rlimsq) THEN
DO k=1,nz-1
dzsq=(zs(i,j,k)-hgtsng(jsta)) * &
(zs(i,j,k)-hgtsng(jsta))
IF(dzsq < zlimsq) THEN
DO ivar=1,nvar
IF(qualsng(ivar,jsta) > 0) THEN
knt(ivar,k)=knt(ivar,k)+1
wgt=texp(-dist*rngsqi(ivar) -dzsq*zsqinv)
wgtsum(ivar,k)=wgtsum(ivar,k) + wgt
zsum(ivar,k)=zsum(ivar,k)+ &
wgt*odifsng(ivar,jsta)
END IF
END DO
END IF
END DO
END IF ! horizontal dist check
END IF ! source check
END DO
END IF
!
!-----------------------------------------------------------------------
!
! Add contributions from multiple-level obs
!
!-----------------------------------------------------------------------
!
IF(uasw > 0) THEN
DO jsta=1,nobsua
IF(iuseua(isrcua(jsta)) > 0) THEN
dist=(xs(i)-xua(jsta))*(xs(i)-xua(jsta)) &
+(ys(j)-yua(jsta))*(ys(j)-yua(jsta))
IF(dist < rlimsq) THEN
DO k=1,nz-1
DO klev=1,nlevsua(jsta)
dzsq=(zs(i,j,k)-hgtua(klev,jsta)) * &
(zs(i,j,k)-hgtua(klev,jsta))
IF(dzsq < zlimsq) THEN
DO ivar=1,nvar
IF(qualua(ivar,klev,jsta) > 0) THEN
knt(ivar,k)=knt(ivar,k)+1
wgt=texp(-dist*rngsqi(ivar) -dzsq*zsqinv)
wgtsum(ivar,k)=wgtsum(ivar,k) + wgt
zsum(ivar,k)=zsum(ivar,k)+ &
wgt*odifua(ivar,klev,jsta)
END IF
END DO
END IF
END DO
END DO
END IF ! horizontal dist check
END IF ! source check
END DO
END IF
!
!-----------------------------------------------------------------------
!
! Add contributions from radar obs
!
!-----------------------------------------------------------------------
!
IF(radsw > 0) THEN
DO jsta=1,ncolrad
IF(iuserad(isrcrad(irad(jsta))) > 0) THEN
dist=(xs(i)-xradc(jsta))*(xs(i)-xradc(jsta)) &
+(ys(j)-yradc(jsta))*(ys(j)-yradc(jsta))
IF(dist < rlimsq) THEN
DO k=1,nz-1
DO klev=1,nlevrad(jsta)
dzsq=(zs(i,j,k)-hgtradc(klev,jsta)) * &
(zs(i,j,k)-hgtradc(klev,jsta))
IF(dzsq < zlimsq) THEN
IF(qualrad(1,klev,jsta) > 0) THEN
knt(1,k)=knt(1,k)+1
wgt=texp(-dist*rngsqi(1) -dzsq*zsqinv)
wgtsum(1,k)=wgtsum(1,k)+ &
wgt*uazmrad(jsta)
zsum(1,k)=zsum(1,k)+ &
wgt*odifrad(1,klev,jsta) * &
uazmrad(jsta)
END IF
IF(qualrad(2,klev,jsta) > 0) THEN
knt(2,k)=knt(2,k)+1
wgt=texp(-dist*rngsqi(2) -dzsq*zsqinv)
wgtsum(2,k)=wgtsum(2,k)+ &
wgt*vazmrad(jsta)
zsum(2,k)=zsum(2,k)+ &
wgt*odifrad(2,klev,jsta) * &
vazmrad(jsta)
END IF
IF(qualrad(3,klev,jsta) > 0) THEN
knt(5,k)=knt(5,k)+1
wgt=texp(-dist*rngsqi(5) -dzsq*zsqinv)
wgtsum(5,k)=wgtsum(5,k)+wgt
zsum(5,k)=zsum(5,k)+ &
wgt*odifrad(3,klev,jsta)
END IF
END IF
END DO
END DO
END IF ! horizontal dist check
END IF ! source check
END DO
END IF
!
!-----------------------------------------------------------------------
!
! Add contributions from retrieval obs
!
!-----------------------------------------------------------------------
!
IF(retsw > 0) THEN
DO jsta=1,ncolret
IF(iuseret(isrcret(iret(jsta))) > 0) THEN
dist=(xs(i)-xretc(jsta))*(xs(i)-xretc(jsta)) &
+(ys(j)-yretc(jsta))*(ys(j)-yretc(jsta))
IF(dist < rlimsq) THEN
DO k=1,nz-1
DO klev=1,nlevret(jsta)
dzsq=(zs(i,j,k)-hgtretc(klev,jsta)) * &
(zs(i,j,k)-hgtretc(klev,jsta))
IF(dzsq < zlimsq) THEN
DO ivar=1,nvar
IF(qualret(ivar,klev,jsta) > 0) THEN
knt(ivar,k)=knt(ivar,k)+1
wgt=texp(-dist*rngsqi(ivar) -dzsq*zsqinv)
wgtsum(ivar,k)=wgtsum(ivar,k) + wgt
zsum(ivar,k)=zsum(ivar,k)+ &
wgt*odifret(ivar,klev,jsta)
END IF
END DO
END IF
END DO
END DO
END IF ! horizontal dist check
END IF ! source check
END DO
END IF
!
!-----------------------------------------------------------------------
!
! Divide by sum of weights
!
!-----------------------------------------------------------------------
!
DO k=1,nz-1
DO ivar=1,nvar
IF(wgtsum(ivar,k) > wlim) anx(i,j,k,ivar)=anx(i,j,k,ivar) + &
zsum(ivar,k)/wgtsum(ivar,k)
END DO
END DO
END DO
END DO
!
istatus=0
RETURN
END SUBROUTINE bargrd3d
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE OBSCOR ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE obscor(nvar,nvarrad,nzua,nzrdr,nzret, & 2
mxsng,mxua,mxrad,mxcolrad,mxret,mxcolret, &
nsrcsng,nsrcua,nsrcrad,nsrcret,ncat,xcor, &
qobsng,xsng,ysng,hgtsng, &
qualsng,isrcsng,icatsng,nobsng, &
qobsua,xua,yua,hgtua, &
qualua,isrcua,nlevsua,nobsua, &
qobsrad,xradc,yradc,hgtradc, &
uazmrad,vazmrad, &
qualrad,irad,isrcrad,nlevrad,ncolrad, &
qobsret,xretc,yretc,hgtretc, &
qualret,iret,isrcret,nlevret,ncolret, &
iusesng,iuseua,iuserad,iuseret, &
sngsw,uasw,radsw,retsw,kpvrsq,rpass,rngsqi, &
wlim,zrngsq, &
corsng,corua,corrad,corret,istatus)
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Calculate covariance sums at observation points for
! Bratseth analysis method.
!
!
!-----------------------------------------------------------------------
!
! AUTHOR: Keith Brewster, CAPS
! July, 1995
!
! MODIFICATION HISTORY:
!
! Jan, 1996 (KB)
! Added radar data and other improvements.
!
! July, 1996 (KB)
! Added sngsw and uasw to switch on/off use of single-level
! and sounding data, respectively.
!
! Jan 5, 1997 (KB)
! New version to reorder summing to speed-up code.
!
!-----------------------------------------------------------------------
!
! Variable Declarations:
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
!
!-----------------------------------------------------------------------
!
! Sizing arguments
!
!-----------------------------------------------------------------------
!
INTEGER :: nvar,nvarrad,nzua,nzrdr,nzret
INTEGER :: mxsng,mxua,mxrad,mxcolrad,mxret,mxcolret
INTEGER :: nsrcsng,nsrcua,nsrcrad,nsrcret,ncat
REAL :: xcor(ncat,ncat)
!
!-----------------------------------------------------------------------
!
! Observation Arguments
!
!-----------------------------------------------------------------------
!
REAL :: qobsng(nvar,mxsng), &
xsng(mxsng), &
ysng(mxsng), &
hgtsng(mxsng)
INTEGER :: qualsng(nvar,mxsng)
INTEGER :: isrcsng(mxsng)
INTEGER :: icatsng(mxsng)
INTEGER :: nobsng
!
REAL :: qobsua(nvar,nzua,mxua)
REAL :: xua(mxua)
REAL :: yua(mxua)
REAL :: hgtua(nzua,mxua)
INTEGER :: qualua(nvar,nzua,mxua)
INTEGER :: nlevsua(mxua)
INTEGER :: isrcua(mxua)
INTEGER :: nobsua
!
REAL :: qobsrad(nvarrad,nzrdr,mxcolrad)
REAL :: xradc(mxcolrad)
REAL :: yradc(mxcolrad)
REAL :: hgtradc(nzrdr,mxcolrad)
REAL :: uazmrad(mxcolrad)
REAL :: vazmrad(mxcolrad)
INTEGER :: qualrad(nvarrad,nzrdr,mxcolrad)
INTEGER :: nlevrad(mxcolrad)
INTEGER :: irad(mxcolrad)
INTEGER :: isrcrad(0:mxrad)
INTEGER :: ncolrad
!
REAL :: qobsret(nvar,nzret,mxcolret)
REAL :: xretc(mxcolret)
REAL :: yretc(mxcolret)
REAL :: hgtretc(nzret,mxcolret)
INTEGER :: qualret(nvar,nzret,mxcolret)
INTEGER :: nlevret(mxcolret)
INTEGER :: iret(mxcolret)
INTEGER :: isrcret(0:mxret)
INTEGER :: ncolret
!
!-----------------------------------------------------------------------
!
! Analysis specification arguments
!
!-----------------------------------------------------------------------
!
INTEGER :: iusesng(0:nsrcsng)
INTEGER :: iuseua(0:nsrcua)
INTEGER :: iuserad(0:nsrcrad)
INTEGER :: iuseret(0:nsrcret)
INTEGER :: sngsw,uasw,radsw,retsw
REAL :: kpvrsq(nvar)
REAL :: rpass, &
wlim
REAL :: zrngsq
REAL :: rngsqi(nvar)
!
!-----------------------------------------------------------------------
!
! Output arguments
!
!-----------------------------------------------------------------------
!
REAL :: corsng(nvar,mxsng)
REAL :: corua(nvar,nzua,mxua)
REAL :: corrad(nvarrad,nzrdr,mxcolrad)
REAL :: corret(nvar,nzret,mxcolret)
INTEGER :: istatus
!
REAL :: ftabinv
INTEGER :: ntabexp
PARAMETER (ntabexp=1000)
REAL :: tabexp(ntabexp)
COMMON /ftabexp/ ftabinv
COMMON /tablexp/ tabexp
!
!-----------------------------------------------------------------------
!
! Misc.local variables
!
!-----------------------------------------------------------------------
!
REAL :: rsq,rlim,rlimsq,zsqinv
REAL :: dist,dzsq,rnorm
INTEGER :: ista,jsta,k,klev,ivar,INDEX
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
rlimsq=0.
DO ivar=1,nvar
rsq=(kpvrsq(ivar)*rpass)
rngsqi(ivar)=1./rsq
rlimsq=AMAX1(rlimsq,rsq)
END DO
rlimsq=-rlimsq*ALOG(wlim)
rlim=0.001*SQRT(rlimsq)
WRITE(6,'(/a,f10.2,a)') &
' OBSCOR: Influence cutoff radius: ',rlim,' km.'
zsqinv=1./zrngsq
!
!-----------------------------------------------------------------------
!
! Initialize covariance sums with observation error variance
!
!-----------------------------------------------------------------------
!
! OpenMP:
!$OMP PARALLEL DO PRIVATE(ista,ivar)
DO ista=1,nobsng
DO ivar=1,nvar
corsng(ivar,ista)=qobsng(ivar,ista)
END DO
END DO
!$OMP PARALLEL DO PRIVATE(ista,k,ivar)
DO ista=1,nobsua
DO k=1,nlevsua(ista)
DO ivar=1,nvar
corua(ivar,k,ista)=qobsua(ivar,k,ista)
END DO
END DO
END DO
!$OMP PARALLEL DO PRIVATE(ista,k,ivar)
DO ista=1,ncolret
DO k=1,nlevret(ista)
DO ivar=1,nvar
corret(ivar,k,ista)=qobsret(ivar,k,ista)
END DO
END DO
END DO
!$OMP PARALLEL DO PRIVATE(ista,k,ivar)
DO ista=1,ncolrad
DO k=1,nlevrad(ista)
DO ivar=1,nvarrad
corrad(ivar,k,ista)=qobsrad(ivar,k,ista)
END DO
END DO
END DO
!
!-----------------------------------------------------------------------
!
! Sum contributions from single-level obs
!
!-----------------------------------------------------------------------
!
IF(sngsw > 0) THEN
DO jsta=1,nobsng
IF(iusesng(isrcsng(jsta)) > 0) THEN
DO ivar=1,nvar
IF(qualsng(ivar,jsta) > 0) THEN
!
!-----------------------------------------------------------------------
!
! Add to single-level covariance sum
!
!-----------------------------------------------------------------------
!
DO ista=1,nobsng
dist=(xsng(ista)-xsng(jsta))*(xsng(ista)-xsng(jsta)) &
+(ysng(ista)-ysng(jsta))*(ysng(ista)-ysng(jsta))
IF(dist < rlimsq) THEN
dzsq=(hgtsng(ista)-hgtsng(jsta)) * &
(hgtsng(ista)-hgtsng(jsta))
rnorm=(dist*rngsqi(ivar) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) corsng(ivar,ista)=corsng(ivar,ista)+ &
tabexp(INDEX)*xcor(icatsng(ista),icatsng(jsta))
END IF
END DO
!
!-----------------------------------------------------------------------
!
! Add to multiple-level covariance sum
!
!-----------------------------------------------------------------------
!
DO ista=1,nobsua
dist=(xua(ista)-xsng(jsta))*(xua(ista)-xsng(jsta)) &
+(yua(ista)-ysng(jsta))*(yua(ista)-ysng(jsta))
IF(dist < rlimsq) THEN
DO k=1,nlevsua(ista)
dzsq=(hgtua(k,ista)-hgtsng(jsta)) * &
(hgtua(k,ista)-hgtsng(jsta))
rnorm=(dist*rngsqi(ivar) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) corua(ivar,k,ista)= &
corua(ivar,k,ista)+tabexp(INDEX)
END DO
END IF
END DO
!
!-----------------------------------------------------------------------
!
! Add to retrieval covariance sum
!
!-----------------------------------------------------------------------
!
DO ista=1,ncolret
dist=(xretc(ista)-xsng(jsta))*(xretc(ista)-xsng(jsta)) &
+(yretc(ista)-ysng(jsta))*(yretc(ista)-ysng(jsta))
IF(dist < rlimsq) THEN
DO k=1,nlevret(ista)
dzsq=(hgtretc(k,ista)-hgtsng(jsta)) * &
(hgtretc(k,ista)-hgtsng(jsta))
rnorm=(dist*rngsqi(ivar) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) corret(ivar,k,ista)= &
corret(ivar,k,ista)+tabexp(INDEX)
END DO
END IF
END DO
END IF
END DO
!
!-----------------------------------------------------------------------
!
! Add to radar data covariance sum
!
!-----------------------------------------------------------------------
!
DO ista=1,ncolrad
dist=(xradc(ista)-xsng(jsta))*(xradc(ista)-xsng(jsta)) &
+(yradc(ista)-ysng(jsta))*(yradc(ista)-ysng(jsta))
IF(dist < rlimsq) THEN
DO k=1,nlevrad(ista)
dzsq=(hgtradc(k,ista)-hgtsng(jsta)) * &
(hgtradc(k,ista)-hgtsng(jsta))
!
IF(qualsng(1,jsta) > 0) THEN
rnorm=(dist*rngsqi(1) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) corrad(1,k,ista)= &
corrad(1,k,ista)+tabexp(INDEX)
END IF
!
IF(qualsng(2,jsta) > 0) THEN
rnorm=(dist*rngsqi(2) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) corrad(2,k,ista)= &
corrad(2,k,ista)+tabexp(INDEX)
END IF
!
IF(qualsng(5,jsta) > 0) THEN
rnorm=(dist*rngsqi(5) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) corrad(3,k,ista)= &
corrad(3,k,ista)+tabexp(INDEX)
END IF
END DO
END IF
END DO
END IF ! source check
END DO
END IF ! sngsw check
!
!-----------------------------------------------------------------------
!
! Add contributions from multiple-level obs
!
!-----------------------------------------------------------------------
!
IF(uasw > 0) THEN
DO jsta=1,nobsua
IF(iuseua(isrcua(jsta)) > 0) THEN
DO klev=1,nlevsua(jsta)
DO ivar=1,nvar
IF(qualua(ivar,klev,jsta) > 0) THEN
!
!-----------------------------------------------------------------------
!
! Add to single-level covariance sum
!
!-----------------------------------------------------------------------
!
DO ista=1,nobsng
dist=(xsng(ista)-xua(jsta))*(xsng(ista)-xua(jsta)) &
+(ysng(ista)-yua(jsta))*(ysng(ista)-yua(jsta))
IF(dist < rlimsq) THEN
dzsq=(hgtsng(ista)-hgtua(klev,jsta)) * &
(hgtsng(ista)-hgtua(klev,jsta))
rnorm=(dist*rngsqi(ivar) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) corsng(ivar,ista)= &
corsng(ivar,ista)+tabexp(INDEX)
END IF
END DO
!
!-----------------------------------------------------------------------
!
! Add to multiple-level covariance sum
!
!-----------------------------------------------------------------------
!
DO ista=1,nobsua
dist=(xua(ista)-xua(jsta))*(xua(ista)-xua(jsta)) &
+(yua(ista)-yua(jsta))*(yua(ista)-yua(jsta))
IF(dist < rlimsq) THEN
DO k=1,nlevsua(ista)
dzsq=(hgtua(k,ista)-hgtua(klev,jsta)) * &
(hgtua(k,ista)-hgtua(klev,jsta))
rnorm=(dist*rngsqi(ivar) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) corua(ivar,k,ista)= &
corua(ivar,k,ista)+tabexp(INDEX)
END DO
END IF
END DO
!
!-----------------------------------------------------------------------
!
! Add to retrieval covariance sum
!
!-----------------------------------------------------------------------
!
DO ista=1,ncolret
dist=(xretc(ista)-xua(jsta))*(xretc(ista)-xua(jsta)) &
+(yretc(ista)-yua(jsta))*(yretc(ista)-yua(jsta))
IF(dist < rlimsq) THEN
DO k=1,nlevret(ista)
dzsq=(hgtretc(k,ista)-hgtua(klev,jsta)) * &
(hgtretc(k,ista)-hgtua(klev,jsta))
rnorm=(dist*rngsqi(ivar) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) corret(ivar,k,ista)= &
corret(ivar,k,ista)+tabexp(INDEX)
END DO
END IF
END DO
END IF
END DO
!
!-----------------------------------------------------------------------
!
! Add to radar covariance sum
!
!-----------------------------------------------------------------------
!
DO ista=1,ncolrad
dist=(xradc(ista)-xua(jsta))*(xradc(ista)-xua(jsta)) &
+(yradc(ista)-yua(jsta))*(yradc(ista)-yua(jsta))
IF(dist < rlimsq) THEN
DO k=1,nlevrad(ista)
dzsq=(hgtradc(k,ista)-hgtua(klev,jsta)) * &
(hgtradc(k,ista)-hgtua(klev,jsta))
!
IF(qualua(1,klev,jsta) > 0) THEN
rnorm=(dist*rngsqi(1) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) corrad(1,k,ista)= &
corrad(1,k,ista)+tabexp(INDEX)
END IF
!
IF(qualua(2,klev,jsta) > 0) THEN
rnorm=(dist*rngsqi(2) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) corrad(2,k,ista)= &
corrad(2,k,ista)+tabexp(INDEX)
END IF
!
IF(qualua(5,klev,jsta) > 0) THEN
rnorm=(dist*rngsqi(5) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) corrad(3,k,ista)= &
corrad(3,k,ista)+tabexp(INDEX)
END IF
END DO
END IF
END DO
END DO
END IF ! source check
END DO
END IF ! uasw check
!
!-----------------------------------------------------------------------
!
! Add contributions from retrieval data
!
!-----------------------------------------------------------------------
!
IF(retsw > 0) THEN
DO jsta=1,ncolret
IF(iuseret(isrcret(iret(jsta))) > 0) THEN
DO klev=1,nlevret(jsta)
DO ivar=1,nvar
IF(qualret(ivar,klev,jsta) > 0) THEN
!
!-----------------------------------------------------------------------
!
! Add to single-level covariance sum
!
!-----------------------------------------------------------------------
!
DO ista=1,nobsng
dist=(xsng(ista)-xretc(jsta))*(xsng(ista)-xretc(jsta)) &
+(ysng(ista)-yretc(jsta))*(ysng(ista)-yretc(jsta))
IF(dist < rlimsq) THEN
dzsq=(hgtsng(ista)-hgtretc(klev,jsta)) * &
(hgtsng(ista)-hgtretc(klev,jsta))
rnorm=(dist*rngsqi(ivar) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) corsng(ivar,ista)= &
corsng(ivar,ista)+tabexp(INDEX)
END IF
END DO
!
!-----------------------------------------------------------------------
!
! Add to multiple-level covariance sum
!
!-----------------------------------------------------------------------
!
DO ista=1,nobsua
dist=(xua(ista)-xretc(jsta))*(xua(ista)-xretc(jsta)) &
+(yua(ista)-yretc(jsta))*(yua(ista)-yretc(jsta))
IF(dist < rlimsq) THEN
DO k=1,nlevsua(ista)
dzsq=(hgtua(k,ista)-hgtretc(klev,jsta)) * &
(hgtua(k,ista)-hgtretc(klev,jsta))
rnorm=(dist*rngsqi(ivar) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) corua(ivar,k,ista)= &
corua(ivar,k,ista)+tabexp(INDEX)
END DO
END IF
END DO
!
!-----------------------------------------------------------------------
!
! Add to retrieval covariance sum
!
!-----------------------------------------------------------------------
!
DO ista=1,ncolret
dist=(xretc(ista)-xretc(jsta))* &
(xretc(ista)-xretc(jsta)) &
+(yretc(ista)-yretc(jsta))* &
(yretc(ista)-yretc(jsta))
IF(dist < rlimsq) THEN
DO k=1,nlevret(ista)
dzsq=(hgtretc(k,ista)-hgtretc(klev,jsta)) * &
(hgtretc(k,ista)-hgtretc(klev,jsta))
rnorm=(dist*rngsqi(ivar) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) corret(ivar,k,ista)= &
corret(ivar,k,ista)+tabexp(INDEX)
END DO
END IF
END DO
END IF
END DO
!
!-----------------------------------------------------------------------
!
! Add to radar covariance sum
!
!-----------------------------------------------------------------------
!
DO ista=1,ncolrad
dist=(xradc(ista)-xretc(jsta))*(xradc(ista)-xretc(jsta)) &
+(yradc(ista)-yretc(jsta))*(yradc(ista)-yretc(jsta))
IF(dist < rlimsq) THEN
DO k=1,nlevrad(ista)
dzsq=(hgtradc(k,ista)-hgtretc(klev,jsta)) * &
(hgtradc(k,ista)-hgtretc(klev,jsta))
!
IF(qualret(1,klev,jsta) > 0) THEN
rnorm=(dist*rngsqi(1) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) corrad(1,k,ista)= &
corrad(1,k,ista)+tabexp(INDEX)
END IF
!
IF(qualret(2,klev,jsta) > 0) THEN
rnorm=(dist*rngsqi(2) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) corrad(2,k,ista)= &
corrad(2,k,ista)+tabexp(INDEX)
END IF
!
IF(qualret(5,klev,jsta) > 0) THEN
rnorm=(dist*rngsqi(5) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) corrad(3,k,ista)= &
corrad(3,k,ista)+tabexp(INDEX)
END IF
END DO
END IF
END DO
END DO
END IF ! source check
END DO
END IF ! retsw check
!
!-----------------------------------------------------------------------
!
! Add contributions from radar obs
!
!-----------------------------------------------------------------------
!
IF(radsw > 0) THEN
DO jsta=1,ncolrad
IF(iuserad(isrcrad(irad(jsta))) > 0) THEN
DO klev=1,nlevrad(jsta)
!
!-----------------------------------------------------------------------
!
! Add to single-level covariance sum
!
!-----------------------------------------------------------------------
!
DO ista=1,nobsng
dist=(xsng(ista)-xradc(jsta))*(xsng(ista)-xradc(jsta)) &
+(ysng(ista)-yradc(jsta))*(ysng(ista)-yradc(jsta))
IF(dist < rlimsq) THEN
dzsq=(hgtsng(ista)-hgtradc(klev,jsta)) * &
(hgtsng(ista)-hgtradc(klev,jsta))
!
IF(qualrad(1,klev,jsta) > 0) THEN
rnorm=(dist*rngsqi(1) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) corsng(1,ista)=corsng(1,ista)+ &
(tabexp(INDEX)*ABS(uazmrad(jsta)))
END IF
!
IF(qualrad(2,klev,jsta) > 0) THEN
rnorm=(dist*rngsqi(2) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) corsng(2,ista)=corsng(2,ista)+ &
(tabexp(INDEX)*ABS(vazmrad(jsta)))
END IF
!
IF(qualrad(3,klev,jsta) > 0) THEN
rnorm=(dist*rngsqi(5) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) corsng(5,ista)=corsng(5,ista)+tabexp(INDEX)
END IF
END IF
END DO
!
!-----------------------------------------------------------------------
!
! Add to multiple-level covariance sum
!
!-----------------------------------------------------------------------
!
DO ista=1,nobsua
dist=(xua(ista)-xradc(jsta))*(xua(ista)-xradc(jsta)) &
+(yua(ista)-yradc(jsta))*(yua(ista)-yradc(jsta))
IF(dist < rlimsq) THEN
DO k=1,nlevsua(ista)
dzsq=(hgtua(k,ista)-hgtradc(klev,jsta)) * &
(hgtua(k,ista)-hgtradc(klev,jsta))
!
IF(qualrad(1,klev,jsta) > 0) THEN
rnorm=(dist*rngsqi(1) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) corua(1,k,ista)=corua(1,k,ista)+ &
(tabexp(INDEX)*ABS(uazmrad(jsta)))
END IF
!
IF(qualrad(2,klev,jsta) > 0) THEN
rnorm=(dist*rngsqi(2) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) corua(2,k,ista)=corua(2,k,ista)+ &
(tabexp(INDEX)*ABS(vazmrad(jsta)))
END IF
!
IF(qualrad(3,klev,jsta) > 0) THEN
rnorm=(dist*rngsqi(5) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) &
corua(5,k,ista)=corua(5,k,ista)+tabexp(INDEX)
END IF
END DO
END IF
END DO
!
!-----------------------------------------------------------------------
!
! Add to retrieval covariance sum
!
!-----------------------------------------------------------------------
!
DO ista=1,ncolret
dist=(xretc(ista)-xradc(jsta))*(xretc(ista)-xradc(jsta)) &
+(yretc(ista)-yradc(jsta))*(yretc(ista)-yradc(jsta))
IF(dist < rlimsq) THEN
DO k=1,nlevret(ista)
dzsq=(hgtretc(k,ista)-hgtradc(klev,jsta)) * &
(hgtretc(k,ista)-hgtradc(klev,jsta))
!
IF(qualrad(1,klev,jsta) > 0) THEN
rnorm=(dist*rngsqi(1) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) corret(1,k,ista)=corret(1,k,ista)+ &
(tabexp(INDEX)*ABS(uazmrad(jsta)))
END IF
!
IF(qualrad(2,klev,jsta) > 0) THEN
rnorm=(dist*rngsqi(2) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) corret(2,k,ista)=corret(2,k,ista)+ &
(tabexp(INDEX)*ABS(vazmrad(jsta)))
END IF
!
IF(qualrad(3,klev,jsta) > 0) THEN
rnorm=(dist*rngsqi(5) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) corret(5,k,ista)= &
corret(5,k,ista)+tabexp(INDEX)
END IF
END DO
END IF
END DO
!
!-----------------------------------------------------------------------
!
! Add to radar covariance sum
!
!-----------------------------------------------------------------------
!
DO ista=1,ncolrad
dist=(xradc(ista)-xradc(jsta))*(xradc(ista)-xradc(jsta)) &
+(yradc(ista)-yradc(jsta))*(yradc(ista)-yradc(jsta))
IF(dist < rlimsq) THEN
DO k=1,nlevrad(ista)
dzsq=(hgtradc(k,ista)-hgtradc(klev,jsta)) * &
(hgtradc(k,ista)-hgtradc(klev,jsta))
!
IF(qualrad(1,klev,jsta) > 0) THEN
rnorm=(dist*rngsqi(1) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) corrad(1,k,ista)=corrad(1,k,ista)+ &
(tabexp(INDEX)*ABS(uazmrad(jsta)))
END IF
!
IF(qualrad(2,klev,jsta) > 0) THEN
rnorm=(dist*rngsqi(2) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) corrad(2,k,ista)=corrad(2,k,ista)+ &
(tabexp(INDEX)*ABS(vazmrad(jsta)))
END IF
!
IF(qualrad(3,klev,jsta) > 0) THEN
rnorm=(dist*rngsqi(5) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) corrad(3,k,ista)= &
corrad(3,k,ista)+tabexp(INDEX)
END IF
END DO
END IF
END DO
END DO
END IF ! source check
END DO
END IF ! radsw check
!
!-----------------------------------------------------------------------
!
! Take inverse to speed up later calculations or
! set covariance inverse to zero as a mask for "bad" obs
!
!-----------------------------------------------------------------------
!
DO ista=1,nobsng
DO ivar=1,nvar
IF(qualsng(ivar,ista) > 0 ) THEN
corsng(ivar,ista)=1./corsng(ivar,ista)
ELSE
corsng(ivar,ista)=0.
END IF
END DO
END DO
!
DO ista=1,nobsua
DO k=1,nlevsua(ista)
DO ivar=1,nvar
IF(qualua(ivar,k,ista) > 0 ) THEN
corua(ivar,k,ista)=1./corua(ivar,k,ista)
ELSE
corua(ivar,k,ista)=0.
END IF
END DO
END DO
END DO
!
DO ista=1,ncolret
DO k=1,nlevret(ista)
DO ivar=1,nvar
IF(qualret(ivar,k,ista) > 0 ) THEN
corret(ivar,k,ista)=1./corret(ivar,k,ista)
ELSE
corret(ivar,k,ista)=0.
END IF
END DO
END DO
END DO
!
DO ista=1,ncolrad
DO k=1,nlevrad(ista)
DO ivar=1,nvarrad
IF(qualrad(ivar,k,ista) > 0 ) THEN
IF(corrad(ivar,k,ista) == 0.) THEN
PRINT *, ' zero corrad: ',ivar,k,ista
PRINT *, ' qobsrad: ',qobsrad(ivar,k,ista)
STOP
END IF
corrad(ivar,k,ista)=1./corrad(ivar,k,ista)
ELSE
corrad(ivar,k,ista)=0.
END IF
END DO
END DO
END DO
!
istatus=0
RETURN
END SUBROUTINE obscor
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE BRTOBS3d ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE brtobs3d(nvar,nvarrad,nzua,nzrdr,nzret, & 2
mxsng,mxua,mxrad,mxcolrad,mxret,mxcolret, &
nsrcsng,nsrcua,nsrcrad,nsrcret,ncat,xcor, &
odifsng,qobsng,corsng,xsng,ysng,hgtsng, &
isrcsng,icatsng,nobsng, &
odifua,qobsua,corua,xua,yua,hgtua,isrcua,nlevsua,nobsua, &
odifrad,qobsrad,corrad,xradc,yradc,hgtradc, &
uazmrad,vazmrad,irad,isrcrad,nlevrad,ncolrad, &
odifret,qobsret,corret,xretc,yretc,hgtretc, &
iret,isrcret,nlevret,ncolret, &
iusesng,iuseua,iuserad,iuseret, &
sngsw,uasw,radsw,retsw,kpvrsq,rpass, &
wlim,zrngsq,rngsqi, &
oanxsng,oanxua,oanxrad,oanxret,istatus)
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Objectively analyze data at observation pts
! Bratseth scheme is employed.
!
!-----------------------------------------------------------------------
!
! AUTHOR: Keith Brewster, CAPS
! July, 1995
!
! MODIFICATION HISTORY:
!
! Jan, 1996 (KB)
! Added radar data and other improvements.
! Keith Brewster, CAPS
!
! July, 1996 (KB)
! Added sngsw and uasw to switch on/off use of single-level
! and sounding data, respectively.
!
! Jan 5, 1997 (KB)
! New version to reorder summing to speed-up code.
! Renamed to BRTGRD3D from BRTGRDZ3d and BRTGRDTH3d.
! When called to analyze using delta-theta, potential
! temperature data is passed into the height arrays.
!
!-----------------------------------------------------------------------
!
! Variable Declarations:
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
!
!-----------------------------------------------------------------------
!
! Sizing arguments
!
!-----------------------------------------------------------------------
!
INTEGER :: nvar,nvarrad,nzua,nzrdr,nzret
INTEGER :: mxsng,mxua,mxrad,mxcolrad,mxret,mxcolret
INTEGER :: nsrcsng,nsrcua,nsrcrad,nsrcret,ncat
REAL :: xcor(ncat,ncat)
!
!-----------------------------------------------------------------------
!
! Observation Arguments
!
!-----------------------------------------------------------------------
!
REAL :: odifsng(nvar,mxsng)
REAL :: qobsng(nvar,mxsng)
REAL :: corsng(nvar,mxsng)
REAL :: xsng(mxsng)
REAL :: ysng(mxsng)
REAL :: hgtsng(mxsng)
INTEGER :: isrcsng(mxsng)
INTEGER :: icatsng(mxsng)
INTEGER :: nobsng
!
REAL :: odifua(nvar,nzua,mxua)
REAL :: qobsua(nvar,nzua,mxua)
REAL :: corua(nvar,nzua,mxua)
REAL :: xua(mxua)
REAL :: yua(mxua)
REAL :: hgtua(nzua,mxua)
INTEGER :: nlevsua(mxua)
INTEGER :: isrcua(mxua)
INTEGER :: nobsua
!
REAL :: odifrad(nvarrad,nzrdr,mxcolrad)
REAL :: qobsrad(nvarrad,nzrdr,mxcolrad)
REAL :: corrad(nvarrad,nzrdr,mxcolrad)
REAL :: xradc(mxcolrad)
REAL :: yradc(mxcolrad)
REAL :: hgtradc(nzrdr,mxcolrad)
REAL :: uazmrad(mxcolrad)
REAL :: vazmrad(mxcolrad)
INTEGER :: nlevrad(mxcolrad)
INTEGER :: irad(mxcolrad)
INTEGER :: isrcrad(0:mxrad)
INTEGER :: ncolrad
!
REAL :: odifret(nvar,nzret,mxcolret)
REAL :: qobsret(nvar,nzret,mxcolret)
REAL :: corret(nvar,nzret,mxcolret)
REAL :: xretc(mxcolret)
REAL :: yretc(mxcolret)
REAL :: hgtretc(nzret,mxcolret)
INTEGER :: nlevret(mxcolret)
INTEGER :: iret(mxcolret)
INTEGER :: isrcret(0:mxret)
INTEGER :: ncolret
!
!-----------------------------------------------------------------------
!
! Scratch space
!
!-----------------------------------------------------------------------
!
REAL :: rngsqi(nvar)
!
!-----------------------------------------------------------------------
!
! Analysis specification arguments
!
!-----------------------------------------------------------------------
!
INTEGER :: iusesng(0:nsrcsng)
INTEGER :: iuseua(0:nsrcua)
INTEGER :: iuserad(0:nsrcrad)
INTEGER :: iuseret(0:nsrcret)
INTEGER :: sngsw,uasw,radsw,retsw
REAL :: kpvrsq(nvar)
REAL :: rpass, &
wlim
REAL :: zrngsq
!
!-----------------------------------------------------------------------
!
! Output arguments
!
!-----------------------------------------------------------------------
!
REAL :: oanxsng(nvar,mxsng)
REAL :: oanxua(nvar,nzua,mxua)
REAL :: oanxrad(nvarrad,nzrdr,mxcolrad)
REAL :: oanxret(nvar,nzret,mxcolret)
INTEGER :: istatus
!
REAL :: ftabinv
INTEGER :: ntabexp
PARAMETER (ntabexp=1000)
REAL :: tabexp(ntabexp)
COMMON /ftabexp/ ftabinv
COMMON /tablexp/ tabexp
!
!-----------------------------------------------------------------------
!
! Misc. local variables
!
!-----------------------------------------------------------------------
!
REAL :: rsq,rlim,rlimsq,zsqinv
REAL :: dist,dzsq,rnorm
INTEGER :: ista,jsta,k,klev,ivar,INDEX
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
rlimsq=0.
DO ivar=1,nvar
rsq=(kpvrsq(ivar)*rpass)
rngsqi(ivar)=1./rsq
rlimsq=AMAX1(rlimsq,rsq)
END DO
rlimsq=-rlimsq*ALOG(wlim)
rlim=0.001*SQRT(rlimsq)
WRITE(6,'(a,f10.2,a)') ' Influence cutoff radius: ',rlim,' km.'
!
zsqinv=1./zrngsq
!
!-----------------------------------------------------------------------
!
! Sum contributions from single-level obs
!
!-----------------------------------------------------------------------
!
IF(sngsw > 0) THEN
DO jsta=1,nobsng
IF(iusesng(isrcsng(jsta)) > 0) THEN
DO ivar=1,nvar
!
!-----------------------------------------------------------------------
!
! Add to single-level data analyses
!
!-----------------------------------------------------------------------
!
DO ista=1,nobsng
dist=(xsng(ista)-xsng(jsta))*(xsng(ista)-xsng(jsta)) &
+(ysng(ista)-ysng(jsta))*(ysng(ista)-ysng(jsta))
IF(dist < rlimsq) THEN
dzsq=(hgtsng(ista)-hgtsng(jsta)) * &
(hgtsng(ista)-hgtsng(jsta))
rnorm=(dist*rngsqi(ivar) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) oanxsng(ivar,ista)=oanxsng(ivar,ista)+ &
(tabexp(INDEX)*xcor(icatsng(ista),icatsng(jsta)) &
*odifsng(ivar,jsta)*corsng(ivar,jsta))
END IF
END DO
!
!-----------------------------------------------------------------------
!
! Add to multiple-level data analyses
!
!-----------------------------------------------------------------------
!
DO ista=1,nobsua
dist=(xua(ista)-xsng(jsta))*(xua(ista)-xsng(jsta)) &
+(yua(ista)-ysng(jsta))*(yua(ista)-ysng(jsta))
IF(dist < rlimsq) THEN
DO k=1,nlevsua(ista)
dzsq=(hgtua(k,ista)-hgtsng(jsta)) * &
(hgtua(k,ista)-hgtsng(jsta))
rnorm=(dist*rngsqi(ivar) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) oanxua(ivar,k,ista)=oanxua(ivar,k,ista)+ &
(tabexp(INDEX) * &
odifsng(ivar,jsta)*corsng(ivar,jsta))
END DO
END IF
END DO
!
!-----------------------------------------------------------------------
!
! Add to retrieval data analyses
!
!-----------------------------------------------------------------------
!
DO ista=1,ncolret
dist=(xretc(ista)-xsng(jsta))*(xretc(ista)-xsng(jsta)) &
+(yretc(ista)-ysng(jsta))*(yretc(ista)-ysng(jsta))
IF(dist < rlimsq) THEN
DO k=1,nlevret(ista)
dzsq=(hgtretc(k,ista)-hgtsng(jsta)) * &
(hgtretc(k,ista)-hgtsng(jsta))
rnorm=(dist*rngsqi(ivar) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) oanxret(ivar,k,ista)=oanxret(ivar,k,ista)+ &
(tabexp(INDEX) * &
odifsng(ivar,jsta)*corsng(ivar,jsta))
END DO
END IF
END DO
!
!-----------------------------------------------------------------------
!
! Add contribution due to observation error variance
!
!-----------------------------------------------------------------------
!
oanxsng(ivar,jsta)= &
oanxsng(ivar,jsta)+qobsng(ivar,jsta)* &
odifsng(ivar,jsta)*corsng(ivar,jsta)
END DO
!
!-----------------------------------------------------------------------
!
! Add to radar data analyses
!
!-----------------------------------------------------------------------
!
DO ista=1,ncolrad
dist=(xradc(ista)-xsng(jsta))*(xradc(ista)-xsng(jsta)) &
+(yradc(ista)-ysng(jsta))*(yradc(ista)-ysng(jsta))
IF(dist < rlimsq) THEN
DO k=1,nlevrad(ista)
dzsq=(hgtradc(k,ista)-hgtsng(jsta)) * &
(hgtradc(k,ista)-hgtsng(jsta))
!
rnorm=(dist*rngsqi(1) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) oanxrad(1,k,ista)=oanxrad(1,k,ista)+ &
(tabexp(INDEX) * &
odifsng(1,jsta)*corsng(1,jsta))
!
rnorm=(dist*rngsqi(2) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) oanxrad(2,k,ista)=oanxrad(2,k,ista)+ &
(tabexp(INDEX) * &
odifsng(2,jsta)*corsng(2,jsta))
!
rnorm=(dist*rngsqi(5) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) oanxrad(3,k,ista)=oanxrad(3,k,ista)+ &
(tabexp(INDEX) * &
odifsng(5,jsta)*corsng(5,jsta))
END DO
END IF
END DO
END IF ! source check
END DO
END IF ! sngsw check
!
!-----------------------------------------------------------------------
!
! Add contributions from multiple-level obs
!
!-----------------------------------------------------------------------
!
IF(uasw > 0) THEN
DO jsta=1,nobsua
IF(iuseua(isrcua(jsta)) > 0) THEN
DO klev=1,nlevsua(jsta)
DO ivar=1,nvar
!
!-----------------------------------------------------------------------
!
! Add to single-level data analyses
!
!-----------------------------------------------------------------------
!
DO ista=1,nobsng
dist=(xsng(ista)-xua(jsta))*(xsng(ista)-xua(jsta)) &
+(ysng(ista)-yua(jsta))*(ysng(ista)-yua(jsta))
IF(dist < rlimsq) THEN
dzsq=(hgtsng(ista)-hgtua(klev,jsta)) * &
(hgtsng(ista)-hgtua(klev,jsta))
rnorm=(dist*rngsqi(ivar) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) oanxsng(ivar,ista)=oanxsng(ivar,ista)+ &
(tabexp(INDEX) * &
odifua(ivar,klev,jsta) * &
corua(ivar,klev,jsta))
END IF
END DO
!
!-----------------------------------------------------------------------
!
! Add to multiple-level data analyses
!
!-----------------------------------------------------------------------
!
DO ista=1,nobsua
dist=(xua(ista)-xua(jsta))*(xua(ista)-xua(jsta)) &
+(yua(ista)-yua(jsta))*(yua(ista)-yua(jsta))
IF(dist < rlimsq) THEN
DO k=1,nlevsua(ista)
dzsq=(hgtua(k,ista)-hgtua(klev,jsta)) * &
(hgtua(k,ista)-hgtua(klev,jsta))
rnorm=(dist*rngsqi(ivar) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) oanxua(ivar,k,ista)=oanxua(ivar,k,ista)+ &
(tabexp(INDEX) * &
odifua(ivar,klev,jsta) * &
corua(ivar,klev,jsta))
END DO
END IF
END DO
!
!-----------------------------------------------------------------------
!
! Add term due to observation error
!
!-----------------------------------------------------------------------
!
oanxua(ivar,klev,jsta)= &
oanxua(ivar,klev,jsta)+qobsua(ivar,klev,jsta)* &
odifua(ivar,klev,jsta)*corua(ivar,klev,jsta)
!
!-----------------------------------------------------------------------
!
! Add to retrieval data analyses
!
!-----------------------------------------------------------------------
!
DO ista=1,ncolret
dist=(xretc(ista)-xua(jsta))*(xretc(ista)-xua(jsta)) &
+(yretc(ista)-yua(jsta))*(yretc(ista)-yua(jsta))
IF(dist < rlimsq) THEN
DO k=1,nlevret(ista)
dzsq=(hgtretc(k,ista)-hgtua(klev,jsta)) * &
(hgtretc(k,ista)-hgtua(klev,jsta))
rnorm=(dist*rngsqi(ivar) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) &
oanxret(ivar,k,ista)=oanxret(ivar,k,ista)+ &
(tabexp(INDEX) * &
odifua(ivar,klev,jsta) * &
corua(ivar,klev,jsta))
END DO
END IF
END DO
END DO
!
!-----------------------------------------------------------------------
!
! Add to radar data analyses
!
!-----------------------------------------------------------------------
!
DO ista=1,ncolrad
dist=(xradc(ista)-xua(jsta))*(xradc(ista)-xua(jsta)) &
+(yradc(ista)-yua(jsta))*(yradc(ista)-yua(jsta))
IF(dist < rlimsq) THEN
DO k=1,nlevrad(ista)
dzsq=(hgtradc(k,ista)-hgtua(klev,jsta)) * &
(hgtradc(k,ista)-hgtua(klev,jsta))
!
rnorm=(dist*rngsqi(1) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) oanxrad(1,k,ista)=oanxrad(1,k,ista)+ &
(tabexp(INDEX) * &
odifua(1,klev,jsta) * &
corua(1,klev,jsta))
!
rnorm=(dist*rngsqi(2) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) oanxrad(2,k,ista)=oanxrad(2,k,ista)+ &
(tabexp(INDEX) * &
odifua(2,klev,jsta) * &
corua(2,klev,jsta))
!
rnorm=(dist*rngsqi(5) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) oanxrad(3,k,ista)=oanxrad(3,k,ista)+ &
(tabexp(INDEX) * &
odifua(5,klev,jsta) * &
corua(5,klev,jsta))
END DO
END IF
END DO
END DO
END IF ! source check
END DO
END IF ! uasw check
!
!-----------------------------------------------------------------------
!
! Add contributions from retrieval data
!
!-----------------------------------------------------------------------
!
IF(retsw > 0) THEN
DO jsta=1,ncolret
IF(iuseret(isrcret(iret(jsta))) > 0) THEN
DO klev=1,nlevret(jsta)
DO ivar=1,nvar
!
!-----------------------------------------------------------------------
!
! Add to single-level data analyses
!
!-----------------------------------------------------------------------
!
DO ista=1,nobsng
dist=(xsng(ista)-xretc(jsta))*(xsng(ista)-xretc(jsta)) &
+(ysng(ista)-yretc(jsta))*(ysng(ista)-yretc(jsta))
IF(dist < rlimsq) THEN
dzsq=(hgtsng(ista)-hgtretc(klev,jsta)) * &
(hgtsng(ista)-hgtretc(klev,jsta))
rnorm=(dist*rngsqi(ivar) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) oanxsng(ivar,ista)=oanxsng(ivar,ista)+ &
(tabexp(INDEX) * &
odifret(ivar,klev,jsta) * &
corret(ivar,klev,jsta))
END IF
END DO
!
!-----------------------------------------------------------------------
!
! Add to multiple-level data analyses
!
!-----------------------------------------------------------------------
!
DO ista=1,nobsua
dist=(xua(ista)-xretc(jsta))*(xua(ista)-xretc(jsta)) &
+(yua(ista)-yretc(jsta))*(yua(ista)-yretc(jsta))
IF(dist < rlimsq) THEN
DO k=1,nlevsua(ista)
dzsq=(hgtua(k,ista)-hgtretc(klev,jsta)) * &
(hgtua(k,ista)-hgtretc(klev,jsta))
rnorm=(dist*rngsqi(ivar) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) oanxua(ivar,k,ista)=oanxua(ivar,k,ista)+ &
(tabexp(INDEX) * &
odifret(ivar,klev,jsta) * &
corret(ivar,klev,jsta))
END DO
END IF
END DO
!
!-----------------------------------------------------------------------
!
! Add to retrieval data analyses
!
!-----------------------------------------------------------------------
!
DO ista=1,ncolret
dist=(xretc(ista)-xretc(jsta))*(xretc(ista)-xretc(jsta)) &
+(yretc(ista)-yretc(jsta))*(yretc(ista)-yretc(jsta))
IF(dist < rlimsq) THEN
DO k=1,nlevret(ista)
dzsq=(hgtretc(k,ista)-hgtretc(klev,jsta)) * &
(hgtretc(k,ista)-hgtretc(klev,jsta))
rnorm=(dist*rngsqi(ivar) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) &
oanxret(ivar,k,ista)=oanxret(ivar,k,ista)+ &
(tabexp(INDEX) * &
odifret(ivar,klev,jsta) * &
corret(ivar,klev,jsta))
END DO
END IF
END DO
!
!-----------------------------------------------------------------------
!
! Add term due to observation error
!
!-----------------------------------------------------------------------
!
oanxret(ivar,klev,jsta)= &
oanxret(ivar,klev,jsta)+qobsret(ivar,klev,jsta)* &
odifret(ivar,klev,jsta)*corret(ivar,klev,jsta)
END DO
!
!-----------------------------------------------------------------------
!
! Add to radar data analyses
!
!-----------------------------------------------------------------------
!
DO ista=1,ncolrad
dist=(xradc(ista)-xretc(jsta))*(xradc(ista)-xretc(jsta)) &
+(yradc(ista)-yretc(jsta))*(yradc(ista)-yretc(jsta))
IF(dist < rlimsq) THEN
DO k=1,nlevrad(ista)
dzsq=(hgtradc(k,ista)-hgtretc(klev,jsta)) * &
(hgtradc(k,ista)-hgtretc(klev,jsta))
!
rnorm=(dist*rngsqi(1) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) oanxrad(1,k,ista)=oanxrad(1,k,ista)+ &
(tabexp(INDEX) * &
odifret(1,klev,jsta) * &
corret(1,klev,jsta))
!
rnorm=(dist*rngsqi(2) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) oanxrad(2,k,ista)=oanxrad(2,k,ista)+ &
(tabexp(INDEX) * &
odifret(2,klev,jsta) * &
corret(2,klev,jsta))
!
rnorm=(dist*rngsqi(5) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) oanxrad(3,k,ista)=oanxrad(3,k,ista)+ &
(tabexp(INDEX) * &
odifret(5,klev,jsta) * &
corret(5,klev,jsta))
END DO
END IF
END DO
END DO
END IF ! source check
END DO
END IF ! retsw check
!
!-----------------------------------------------------------------------
!
! Add contributions from radar obs
!
!-----------------------------------------------------------------------
!
IF(radsw > 0) THEN
DO jsta=1,ncolrad
IF(iuserad(isrcrad(irad(jsta))) > 0) THEN
DO klev=1,nlevrad(jsta)
!
!-----------------------------------------------------------------------
!
! Add to single-level data analyses
!
!-----------------------------------------------------------------------
!
DO ista=1,nobsng
dist=(xsng(ista)-xradc(jsta))*(xsng(ista)-xradc(jsta)) &
+(ysng(ista)-yradc(jsta))*(ysng(ista)-yradc(jsta))
IF(dist < rlimsq) THEN
dzsq=(hgtsng(ista)-hgtradc(klev,jsta)) * &
(hgtsng(ista)-hgtradc(klev,jsta))
!
rnorm=(dist*rngsqi(1) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) oanxsng(1,ista)=oanxsng(1,ista)+ &
(tabexp(INDEX) * ABS(uazmrad(jsta)) * &
odifrad(1,klev,jsta) * &
corrad(1,klev,jsta))
!
rnorm=(dist*rngsqi(2) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) oanxsng(2,ista)=oanxsng(2,ista)+ &
(tabexp(INDEX) * ABS(vazmrad(jsta)) * &
odifrad(2,klev,jsta) * &
corrad(2,klev,jsta))
!
rnorm=(dist*rngsqi(5) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) oanxsng(5,ista)=oanxsng(5,ista)+ &
(tabexp(INDEX) * &
odifrad(3,klev,jsta) * &
corrad(3,klev,jsta))
END IF
END DO
!
!-----------------------------------------------------------------------
!
! Add to multiple-level data analyses
!
!-----------------------------------------------------------------------
!
DO ista=1,nobsua
dist=(xua(ista)-xradc(jsta))*(xua(ista)-xradc(jsta)) &
+(yua(ista)-yradc(jsta))*(yua(ista)-yradc(jsta))
IF(dist < rlimsq) THEN
DO k=1,nlevsua(ista)
dzsq=(hgtua(k,ista)-hgtradc(klev,jsta)) * &
(hgtua(k,ista)-hgtradc(klev,jsta))
!
rnorm=(dist*rngsqi(1) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) oanxua(1,k,ista)=oanxua(1,k,ista)+ &
(tabexp(INDEX) * ABS(uazmrad(jsta)) * &
odifrad(1,klev,jsta) * &
corrad(1,klev,jsta))
!
rnorm=(dist*rngsqi(2) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) oanxua(2,k,ista)=oanxua(2,k,ista)+ &
(tabexp(INDEX) * ABS(vazmrad(jsta)) * &
odifrad(2,klev,jsta) * &
corrad(2,klev,jsta))
!
rnorm=(dist*rngsqi(5) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) oanxua(5,k,ista)=oanxua(5,k,ista)+ &
(tabexp(INDEX) * &
odifrad(3,klev,jsta) * &
corrad(3,klev,jsta))
END DO
END IF
END DO
!
!-----------------------------------------------------------------------
!
! Add to retrieval data analyses
!
!-----------------------------------------------------------------------
!
DO ista=1,ncolret
dist=(xretc(ista)-xradc(jsta))*(xretc(ista)-xradc(jsta)) &
+(yretc(ista)-yradc(jsta))*(yretc(ista)-yradc(jsta))
IF(dist < rlimsq) THEN
DO k=1,nlevret(ista)
dzsq=(hgtretc(k,ista)-hgtradc(klev,jsta)) * &
(hgtretc(k,ista)-hgtradc(klev,jsta))
!
rnorm=(dist*rngsqi(1) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) oanxret(1,k,ista)=oanxret(2,k,ista)+ &
(tabexp(INDEX) * ABS(uazmrad(jsta)) * &
odifrad(1,klev,jsta) * &
corrad(1,klev,jsta))
!
rnorm=(dist*rngsqi(2) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) oanxret(2,k,ista)=oanxret(2,k,ista)+ &
(tabexp(INDEX) * ABS(vazmrad(jsta)) * &
odifrad(2,klev,jsta) * &
corrad(2,klev,jsta))
!
rnorm=(dist*rngsqi(5) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) oanxret(5,k,ista)=oanxret(5,k,ista)+ &
(tabexp(INDEX) * &
odifrad(3,klev,jsta) * &
corrad(3,klev,jsta))
END DO
END IF
END DO
!
!-----------------------------------------------------------------------
!
! Add to radar data analyses
!
!-----------------------------------------------------------------------
!
DO ista=1,ncolrad
dist=(xradc(ista)-xradc(jsta))*(xradc(ista)-xradc(jsta)) &
+(yradc(ista)-yradc(jsta))*(yradc(ista)-yradc(jsta))
IF(dist < rlimsq) THEN
DO k=1,nlevrad(ista)
dzsq=(hgtradc(k,ista)-hgtradc(klev,jsta)) * &
(hgtradc(k,ista)-hgtradc(klev,jsta))
!
rnorm=(dist*rngsqi(1) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) oanxrad(1,k,ista)=oanxrad(1,k,ista)+ &
(tabexp(INDEX) * ABS(uazmrad(jsta)) * &
odifrad(1,klev,jsta) * &
corrad(1,klev,jsta))
!
rnorm=(dist*rngsqi(2) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) oanxrad(2,k,ista)=oanxrad(2,k,ista)+ &
(tabexp(INDEX) * ABS(vazmrad(jsta)) * &
odifrad(2,klev,jsta) * &
corrad(2,klev,jsta))
!
rnorm=(dist*rngsqi(5) +dzsq*zsqinv)*ftabinv
INDEX=nint(rnorm+1)
IF(INDEX < ntabexp) oanxrad(3,k,ista)=oanxrad(3,k,ista)+ &
(tabexp(INDEX) * &
odifrad(3,klev,jsta) * &
corrad(3,klev,jsta))
END DO
END IF
END DO
oanxrad(1,klev,jsta)= &
oanxrad(1,klev,jsta)+qobsrad(1,klev,jsta)* &
odifrad(1,klev,jsta)*corrad(1,klev,jsta)
oanxrad(2,klev,jsta)= &
oanxrad(2,klev,jsta)+qobsrad(2,klev,jsta)* &
odifrad(2,klev,jsta)*corrad(2,klev,jsta)
oanxrad(3,klev,jsta)= &
oanxrad(3,klev,jsta)+qobsrad(3,klev,jsta)* &
odifrad(3,klev,jsta)*corrad(3,klev,jsta)
END DO
END IF ! source check
END DO
END IF ! radsw check
istatus=0
RETURN
END SUBROUTINE brtobs3d
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE BRTGRD3d ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
!
SUBROUTINE brtgrd3d(nx,ny,nz,nvar,nvarrad, & 2
nzua,nzrdr,nzret, &
mxsng,mxua,mxrad,mxcolrad,mxret,mxcolret, &
nsrcsng,nsrcua,nsrcrad,nsrcret,ncat,xs,ys,zs,icatg,xcor, &
odifsng,corsng,xsng,ysng,hgtsng,isrcsng,icatsng,nobsng, &
odifua,corua,xua,yua,hgtua,isrcua,nlevsua,nobsua, &
odifrad,corrad,xradc,yradc,hgtradc, &
uazmrad,vazmrad,irad,isrcrad,nlevrad,ncolrad, &
odifret,corret,xretc,yretc,hgtretc, &
iret,isrcret,nlevret,ncolret, &
iusesng,iuseua,iuserad,iuseret, &
sngsw,uasw,radsw,retsw,kpvrsq,rpass, &
wlim,zrngsq,rngsqi, &
anx,tem1,tem2,ibegin,iend,istatus)
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Objectively analyze data on a regular grid specified
! by x and y.
! Bratseth scheme is employed.
!
!-----------------------------------------------------------------------
!
! AUTHOR: Keith Brewster, CAPS
! July, 1995
!
! MODIFICATION HISTORY:
!
! Jan, 1996 (KB)
! Added radar data and other improvements.
!
! July, 1996 (KB)
! Added sngsw and uasw to switch on/off use of single-level
! and sounding data, respectively.
!
! Jan 5, 1997 (KB)
! New version to reorder summing to speed-up code.
! Renamed to BRTGRD3D from BRTGRDZ3d and BRTGRDTH3d.
! When called to analyze using delta-theta, potential
! temperature data is passed into the height arrays.
!
!-----------------------------------------------------------------------
!
! Variable Declarations:
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
!
!-----------------------------------------------------------------------
!
! Sizing arguments
!
!-----------------------------------------------------------------------
!
INTEGER :: nx,ny,nz
INTEGER :: nvar,nvarrad,nzua,nzrdr,nzret
INTEGER :: mxsng,mxua,mxrad,mxcolrad,mxret,mxcolret
INTEGER :: nsrcsng,nsrcua,nsrcrad,nsrcret,ncat
!
!-----------------------------------------------------------------------
!
! Grid arguments
!
!-----------------------------------------------------------------------
!
REAL :: xs(nx)
REAL :: ys(ny)
REAL :: zs(nx,ny,nz)
INTEGER :: icatg(nx,ny)
REAL :: xcor(ncat,ncat)
!
!-----------------------------------------------------------------------
!
! Observation Arguments
!
!-----------------------------------------------------------------------
!
REAL :: odifsng(nvar,mxsng) ! variable to analyse
REAL :: corsng(nvar,mxsng)
REAL :: xsng(mxsng)
REAL :: ysng(mxsng)
REAL :: hgtsng(mxsng)
INTEGER :: isrcsng(mxsng)
INTEGER :: icatsng(mxsng)
INTEGER :: nobsng
!
REAL :: odifua(nvar,nzua,mxua)
REAL :: corua(nvar,nzua,mxua)
REAL :: xua(mxua)
REAL :: yua(mxua)
REAL :: hgtua(nzua,mxua)
INTEGER :: nlevsua(mxua)
INTEGER :: isrcua(mxua)
INTEGER :: nobsua
!
REAL :: odifrad(nvarrad,nzrdr,mxcolrad)
REAL :: corrad(nvarrad,nzrdr,mxcolrad)
REAL :: xradc(mxcolrad)
REAL :: yradc(mxcolrad)
REAL :: hgtradc(nzrdr,mxcolrad)
REAL :: uazmrad(mxcolrad)
REAL :: vazmrad(mxcolrad)
INTEGER :: nlevrad(mxcolrad)
INTEGER :: irad(mxcolrad)
INTEGER :: isrcrad(0:mxrad)
INTEGER :: ncolrad
!
REAL :: odifret(nvar,nzret,mxcolret)
REAL :: corret(nvar,nzret,mxcolret)
REAL :: xretc(mxcolret)
REAL :: yretc(mxcolret)
REAL :: hgtretc(nzret,mxcolret)
INTEGER :: nlevret(mxcolret)
INTEGER :: iret(mxcolret)
INTEGER :: isrcret(0:mxret)
INTEGER :: ncolret
!
!-----------------------------------------------------------------------
!
! Scratch space
!
!-----------------------------------------------------------------------
!
REAL :: rngsqi(nvar)
!
!-----------------------------------------------------------------------
!
! Analysis specification arguments
!
!-----------------------------------------------------------------------
!
INTEGER :: iusesng(0:nsrcsng)
INTEGER :: iuseua(0:nsrcua)
INTEGER :: iuserad(0:nsrcrad)
INTEGER :: iuseret(0:nsrcret)
INTEGER :: sngsw,uasw,radsw,retsw
REAL :: kpvrsq(nvar)
REAL :: rpass, &
wlim
REAL :: zrngsq
!
!-----------------------------------------------------------------------
!
! Output grid arguments
!
!-----------------------------------------------------------------------
!
REAL :: anx(nx,ny,nz,nvar)
REAL :: tem1(nx,ny,nz)
REAL :: tem2(nx,ny,nz)
INTEGER :: ibegin(ny)
INTEGER :: iend(ny)
INTEGER :: istatus
!
REAL :: ftabinv
INTEGER :: ntabexp
PARAMETER (ntabexp=1000)
REAL :: tabexp(ntabexp)
COMMON /ftabexp/ ftabinv
COMMON /tablexp/ tabexp
!
!-----------------------------------------------------------------------
!
! Misc. local variables
!
!-----------------------------------------------------------------------
!
REAL :: rsq,rlim,rlimsq,zsqinv,rnorm
INTEGER :: i,j,k,jsta,klev,ivar,INDEX,jbegin,jend
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
rlimsq=0.
DO ivar=1,nvar
rsq=(kpvrsq(ivar)*rpass)
rngsqi(ivar)=1./rsq
rlimsq=AMAX1(rlimsq,rsq)
END DO
rlimsq=-rlimsq*ALOG(wlim)
rlim=0.001*SQRT(rlimsq)
WRITE(6,'(/a,f10.2,a/)') ' Influence cutoff radius: ',rlim,' km.'
!
zsqinv=1./zrngsq
!
!-----------------------------------------------------------------------
!
! First sum contributions from single-level obs
!
!-----------------------------------------------------------------------
!
IF(sngsw > 0) THEN
DO jsta=1,nobsng
IF(iusesng(isrcsng(jsta)) > 0) THEN
DO j=1,ny
DO i=1,nx
tem1(i,j,1)=(xs(i)-xsng(jsta))*(xs(i)-xsng(jsta)) &
+(ys(j)-ysng(jsta))*(ys(j)-ysng(jsta))
END DO
END DO
!
!-----------------------------------------------------------------------
!
! Find range in i,j of valid influence
!
!-----------------------------------------------------------------------
!
jbegin=ny+1
jend=1
DO j=1,ny
DO i=1,nx
IF(tem1(i,j,1) < rlimsq) EXIT
END DO
ibegin(j)=i
IF(i <= nx) THEN
jbegin=MIN(jbegin,j)
jend=MAX(jend,j)
END IF
DO i=nx,ibegin(j),-1
IF(tem1(i,j,1) < rlimsq) EXIT
END DO
iend(j)=i
END DO
!
! OpenMP changed loop order to j,k,i:
!$OMP PARALLEL DO PRIVATE (j,k,i)
DO j=jbegin,jend
DO k=1,nz-1
DO i=ibegin(j),iend(j)
tem2(i,j,k)=(zs(i,j,k)-hgtsng(jsta)) * &
(zs(i,j,k)-hgtsng(jsta)) * zsqinv
END DO
END DO
END DO
DO ivar=1,nvar
! OpenMP changed loop order to j,k,i:
!$OMP PARALLEL DO PRIVATE (j,k,i,rnorm,index)
DO j=jbegin,jend
DO k=1,nz-1
DO i=ibegin(j),iend(j)
rnorm=(tem1(i,j,1)*rngsqi(ivar) + &
tem2(i,j,k))*ftabinv
INDEX= &
MIN(nint(rnorm+1),ntabexp)
anx(i,j,k,ivar)=anx(i,j,k,ivar) + &
(tabexp(INDEX)*xcor(icatsng(jsta),icatg(i,j)) &
*odifsng(ivar,jsta)*corsng(ivar,jsta))
END DO
END DO
END DO
END DO
END IF ! source check
END DO
END IF
!
!-----------------------------------------------------------------------
!
! Add contributions from multiple-level obs
!
!-----------------------------------------------------------------------
!
IF(uasw > 0) THEN
DO jsta=1,nobsua
IF(iuseua(isrcua(jsta)) > 0) THEN
DO j=1,ny
DO i=1,nx
tem1(i,j,1)=(xs(i)-xua(jsta))*(xs(i)-xua(jsta)) &
+(ys(j)-yua(jsta))*(ys(j)-yua(jsta))
END DO
END DO
!
!-----------------------------------------------------------------------
!
! Find range in i,j of valid influence
!
!-----------------------------------------------------------------------
!
jbegin=ny+1
jend=1
DO j=1,ny
DO i=1,nx
IF(tem1(i,j,1) < rlimsq) EXIT
END DO
ibegin(j)=i
IF(i <= nx) THEN
jbegin=MIN(jbegin,j)
jend=MAX(jend,j)
END IF
DO i=nx,ibegin(j),-1
IF(tem1(i,j,1) < rlimsq) EXIT
END DO
iend(j)=i
END DO
!
DO klev=1,nlevsua(jsta)
DO k=1,nz-1
DO j=jbegin,jend
DO i=ibegin(j),iend(j)
tem2(i,j,k)=(zs(i,j,k)-hgtua(klev,jsta)) * &
(zs(i,j,k)-hgtua(klev,jsta)) * zsqinv
END DO
END DO
END DO
DO ivar=1,nvar
DO k=1,nz-1
DO j=jbegin,jend
DO i=ibegin(j),iend(j)
rnorm=(tem1(i,j,1)*rngsqi(ivar) + &
tem2(i,j,k) ) * ftabinv
INDEX= &
MIN(nint(rnorm+1),ntabexp)
anx(i,j,k,ivar)=anx(i,j,k,ivar) + &
(tabexp(INDEX) * &
odifua(ivar,klev,jsta) * &
corua(ivar,klev,jsta))
END DO
END DO
END DO
END DO
END DO
END IF ! source check
END DO
END IF
!
!-----------------------------------------------------------------------
!
! Add contributions from radar obs
!
!-----------------------------------------------------------------------
!
IF(radsw > 0) THEN
DO jsta=1,ncolrad
IF(iuserad(isrcrad(irad(jsta))) > 0) THEN
DO j=1,ny
DO i=1,nx
tem1(i,j,1)=(xs(i)-xradc(jsta))*(xs(i)-xradc(jsta)) &
+(ys(j)-yradc(jsta))*(ys(j)-yradc(jsta))
END DO
END DO
!
!-----------------------------------------------------------------------
!
! Find range in i,j of valid influence
!
!-----------------------------------------------------------------------
!
jbegin=ny+1
jend=1
DO j=1,ny
DO i=1,nx
IF(tem1(i,j,1) < rlimsq) EXIT
END DO
ibegin(j)=i
IF(i <= nx) THEN
jbegin=MIN(jbegin,j)
jend=MAX(jend,j)
END IF
DO i=nx,ibegin(j),-1
IF(tem1(i,j,1) < rlimsq) EXIT
END DO
iend(j)=i
END DO
!
DO klev=1,nlevrad(jsta)
DO k=1,nz-1
DO j=jbegin,jend
DO i=ibegin(j),iend(j)
tem2(i,j,k)=(zs(i,j,k)-hgtradc(klev,jsta)) * &
(zs(i,j,k)-hgtradc(klev,jsta)) * zsqinv
END DO
END DO
END DO
DO k=1,nz-1
DO j=jbegin,jend
DO i=ibegin(j),iend(j)
rnorm=(tem1(i,j,1)*rngsqi(1) + &
tem2(i,j,k) ) * ftabinv
INDEX= &
MIN(nint(rnorm+1),ntabexp)
anx(i,j,k,1)=anx(i,j,k,1) + &
(tabexp(INDEX) * &
ABS(uazmrad(jsta)) * &
odifrad(1,klev,jsta) * &
corrad(1,klev,jsta))
END DO
END DO
END DO
DO k=1,nz-1
DO j=jbegin,jend
DO i=ibegin(j),iend(j)
rnorm=(tem1(i,j,1)*rngsqi(2) + &
tem2(i,j,k) ) * ftabinv
INDEX= &
MIN(nint(rnorm+1),ntabexp)
anx(i,j,k,2)=anx(i,j,k,2) + &
(tabexp(INDEX) * &
ABS(vazmrad(jsta)) * &
odifrad(2,klev,jsta) * &
corrad(2,klev,jsta))
END DO
END DO
END DO
DO k=1,nz-1
DO j=jbegin,jend
DO i=ibegin(j),iend(j)
rnorm=(tem1(i,j,1)*rngsqi(5) + &
tem2(i,j,k) ) * ftabinv
INDEX= &
MIN(nint(rnorm+1),ntabexp)
anx(i,j,k,5)=anx(i,j,k,5) + &
(tabexp(INDEX) * &
odifrad(3,klev,jsta) * &
corrad(3,klev,jsta))
END DO
END DO
END DO
END DO
END IF ! source check
END DO
END IF
!
!-----------------------------------------------------------------------
!
! Add contributions from retrieval data
!
!-----------------------------------------------------------------------
!
IF(retsw > 0) THEN
DO jsta=1,ncolret
IF(iuseret(isrcret(iret(jsta))) > 0) THEN
DO j=1,ny
DO i=1,nx
tem1(i,j,1)=(xs(i)-xretc(jsta))*(xs(i)-xretc(jsta)) &
+(ys(j)-yretc(jsta))*(ys(j)-yretc(jsta))
END DO
END DO
!
!-----------------------------------------------------------------------
!
! Find range in i,j of valid influence
!
!-----------------------------------------------------------------------
!
jbegin=ny+1
jend=1
DO j=1,ny
DO i=1,nx
IF(tem1(i,j,1) < rlimsq) EXIT
END DO
ibegin(j)=i
IF(i <= nx) THEN
jbegin=MIN(jbegin,j)
jend=MAX(jend,j)
END IF
DO i=nx,ibegin(j),-1
IF(tem1(i,j,1) < rlimsq) EXIT
END DO
iend(j)=i
END DO
!
!-----------------------------------------------------------------------
!
! Apply retrievel corrections
!
!-----------------------------------------------------------------------
!
DO klev=1,nlevret(jsta)
DO k=1,nz-1
DO j=jbegin,jend
DO i=ibegin(j),iend(j)
tem2(i,j,k)=(zs(i,j,k)-hgtretc(klev,jsta)) * &
(zs(i,j,k)-hgtretc(klev,jsta)) * zsqinv
END DO
END DO
END DO
DO ivar=1,nvar
DO j=jbegin,jend
DO k=1,nz-1
DO i=ibegin(j),iend(j)
rnorm=(tem1(i,j,1)*rngsqi(ivar) + &
tem2(i,j,k) ) * ftabinv
INDEX= &
MIN(nint(rnorm+1),ntabexp)
anx(i,j,k,ivar)=anx(i,j,k,ivar) + &
(tabexp(INDEX) * &
odifret(ivar,klev,jsta) * &
corret(ivar,klev,jsta))
END DO
END DO
END DO
END DO
END DO
END IF ! source check
END DO
END IF
!
istatus=0
RETURN
END SUBROUTINE brtgrd3d
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE BARQC ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE barqc(maxsta,nvar,nsrc,nprev,nsta, & 1
obs,obstime,xsta,ysta,isrc,qual, &
knt,wgtsum,zsum,sqsum, &
range,wlim,klim,qclim,varnam,snam, &
iqclist,iqcsave,iqcflag)
!
!-----------------------------------------------------------------------
!
! PURPOSE:
! Routine to objectively quality control surface data using a
! Barnes analysis of nearby stations.
!
! If an observations is found to be bad its quality variable
! is set to the input flag value, iqcflag
!
!-----------------------------------------------------------------------
!
! AUTHOR: Keith Brewster, CAPS
! September, 1989
!
! MODIFICATION HISTORY:
!
! Jul, 1996 (KB)
! Version for ARPS analysis
! Keith Brewster, CAPS
!
! Aug, 1997 (KB)
! Modifications and clarification of code for QC of analysis
! variables instead of raw observed variables, before. Related
! to changes in data error specification in other routines.
!
!-----------------------------------------------------------------------
!
! Variable Declarations:
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
!
!-----------------------------------------------------------------------
!
! Observation Arguments
!
!-----------------------------------------------------------------------
!
INTEGER :: maxsta,nvar,nsrc
REAL :: obs(nvar,maxsta)
INTEGER :: obstime(maxsta)
REAL :: xsta(maxsta)
REAL :: ysta(maxsta)
INTEGER :: isrc(maxsta)
INTEGER :: nprev
INTEGER :: nsta
!
!-----------------------------------------------------------------------
!
! Scratch space
!
!-----------------------------------------------------------------------
!
INTEGER :: knt(nvar)
REAL :: wgtsum(nvar)
REAL :: zsum(nvar)
REAL :: sqsum(nvar)
!
!-----------------------------------------------------------------------
!
! File unit numbers
!
!-----------------------------------------------------------------------
!
INTEGER :: iqclist,iqcsave
!
!-----------------------------------------------------------------------
!
! Analysis specification arguments
!
!-----------------------------------------------------------------------
!
REAL :: range, & ! e-folding range km**2 of barnes weight
wlim ! limit of weight to set max range
INTEGER :: klim ! minimum # of stations to influence grid pt
REAL :: qclim(nvar,nsrc) ! QC cutoffs
!
!-----------------------------------------------------------------------
!
! Input/Output quality indicator
!
!-----------------------------------------------------------------------
!
INTEGER :: qual(nvar,maxsta)
!
!-----------------------------------------------------------------------
!
! Diagnostics and other argument variables
!
!-----------------------------------------------------------------------
!
CHARACTER (LEN=6) :: varnam(nvar)
CHARACTER (LEN=5) :: snam(maxsta)
INTEGER :: iqcflag
!
!-----------------------------------------------------------------------
!
! Misc. local variables
!
!-----------------------------------------------------------------------
!
REAL :: rlimsq,dist, &
wgt,zanx,dob,sqanx,chklim
INTEGER :: jsta,ksta,ivar
LOGICAL :: listit,saveit
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!
!-----------------------------------------------------------------------
!
! Set printing logicals
!
!-----------------------------------------------------------------------
!
listit=(iqclist > 0)
saveit=(iqcsave > 0)
!
!-----------------------------------------------------------------------
!
! Based on the minimum weight to consider, set
! a maximum range
!
!-----------------------------------------------------------------------
!
rlimsq=-range*ALOG(wlim)
!
!-----------------------------------------------------------------------
!
! print *, ' Analyzing...'
! print *, ' rlim= ', rlim
! print *, ' range = ',range
!
! Uses Barnes weighting function. see variable wgt.
!
! Ksta is location that is being examined
!
!-----------------------------------------------------------------------
!
PRINT *, ' BARQC: nsta= ',nsta
DO ksta=(nprev+1),(nprev+nsta)
! print *, ' ksta,isrc= ',ksta,isrc(ksta)
! print *, ' obs: '
! print *, (obs(ivar,ksta),ivar=1,nvar)
! print *, ' qual: '
! print *, (qual(ivar,ksta),ivar=1,nvar)
IF(isrc(ksta) > 0) THEN
DO ivar=1,nvar
zsum(ivar)=0.
sqsum(ivar)=0.
wgtsum(ivar)=0.
knt(ivar)=0
END DO
DO jsta=1,(nprev+nsta)
IF(jsta /= ksta) THEN
dist=(xsta(ksta)-xsta(jsta))*(xsta(ksta)-xsta(jsta)) &
+(ysta(ksta)-ysta(jsta))*(ysta(ksta)-ysta(jsta))
IF(dist < rlimsq) THEN
wgt=EXP(-dist/range)
DO ivar=1,nvar
IF(qual(ivar,jsta) > 0) THEN
knt(ivar)=knt(ivar)+1
wgtsum(ivar)=wgtsum(ivar)+wgt
zsum(ivar)=zsum(ivar)+wgt*obs(ivar,jsta)
sqsum(ivar)=sqsum(ivar)+ &
wgt*obs(ivar,jsta)*obs(ivar,jsta)
END IF
END DO
END IF
END IF ! dont use current station
END DO
DO ivar=1,nvar
IF(qual(ivar,ksta) > 0) THEN
IF(knt(ivar) >= klim) THEN
sqanx=sqsum(ivar)- &
(zsum(ivar)*zsum(ivar)/wgtsum(ivar))
sqanx=AMAX1(sqanx,0.)
sqanx=3.0*SQRT(sqanx/wgtsum(ivar))
zanx=zsum(ivar)/wgtsum(ivar)
dob=obs(ivar,ksta)-zanx
chklim=AMAX1(sqanx,qclim(ivar,isrc(ksta)))
IF(ABS(dob) > chklim) THEN
PRINT *, ' QC flagging data...sta=',snam(ksta)
PRINT *, ' var, ob =', &
varnam(ivar),obs(ivar,ksta)
PRINT *, ' delta ob =',dob
PRINT *, ' 3.0*stdv,qclimit=',sqanx, &
qclim(ivar,isrc(ksta))
IF(listit) WRITE(iqclist,810) &
snam(ksta),obstime(ksta),ivar,varnam(ivar), &
obs(ivar,ksta),dob, &
sqanx,qclim(ivar,isrc(ksta))
810 FORMAT(2X,a5,i5,2X,i3,1X,a6,f11.2,f11.2,f11.2,f11.2)
qual(ivar,ksta)=iqcflag
END IF
zsum(ivar)=dob
ELSE
! print *, ' Not enuf data to check ivar= ',
! : ivar,' for ',snam(ksta)
zsum(ivar)=-999.
END IF
ELSE
zsum(ivar)=-999.
END IF ! data missing, dont bother checking
END DO
IF(saveit) WRITE(iqcsave,820) snam(ksta),obstime(ksta), &
(obs(ivar,ksta),ivar=1,nvar)
820 FORMAT(2X,a5,i5,2X,15(f7.2))
END IF ! isrc check
END DO
RETURN
END SUBROUTINE barqc
!
!##################################################################
!##################################################################
!###### ######
!###### FUNCTION TEXP ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
FUNCTION texp(rnorm)
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! A faster exponential function, via a lookup table.
!
!-----------------------------------------------------------------------
!
! AUTHOR: Keith Brewster, CAPS
! December, 1995
!
! MODIFICATION HISTORY:
!
!
!-----------------------------------------------------------------------
!
! Variable Declarations:
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
REAL :: texp,setexp
REAL :: rnorm
!
REAL :: mxrnrm,ftabinv
INTEGER :: ntabexp
PARAMETER (ntabexp=1000)
REAL :: tabexp(ntabexp)
COMMON /ftabexp/ ftabinv
COMMON /tablexp/ tabexp
!
!-----------------------------------------------------------------------
!
! Misc. local variables
!
!-----------------------------------------------------------------------
!
INTEGER :: i,INDEX
REAL :: ftab
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
INDEX=nint(-(rnorm*ftabinv)) + 1
INDEX=MAX(INDEX,1)
INDEX=MIN(INDEX,ntabexp)
texp=tabexp(INDEX)
RETURN
!
ENTRY setexp(mxrnrm)
ftab=mxrnrm/FLOAT(ntabexp)
ftabinv=1./ftab
DO i=1,ntabexp
tabexp(i)=EXP((-(i-1)*ftab))
END DO
setexp=ftabinv
RETURN
END FUNCTION texp