! !################################################################## !################################################################## !###### ###### !###### SUBROUTINE GRDTOSNG ###### !###### ###### !###### Developed by ###### !###### Center for Analysis and Prediction of Storms ###### !###### University of Oklahoma ###### !###### ###### !################################################################## !################################################################## ! SUBROUTINE grdtosng(nx,ny,nz,nz_tab,mxsng,nvar,nobsng, & 1,2 xs,ys,zp,icatg,anx,qback,hqback,nlvqback, & shght,su,sv,spres,stheta,sqv, & stnsng,isrcsng,icatsng,elevsng,xsng,ysng, & obsng,qobsng,qualsng,odifsng,oanxsng,thesng) ! !----------------------------------------------------------------------- ! ! PURPOSE: ! ! Gridded data are interpolated to single-level locations to ! produce observation differences. For now, bilinear interpolation ! is used to create a vertical sounding at the obs location ! and that is interpolated in the vertical to obtain the ! bacground value. ! !----------------------------------------------------------------------- ! ! AUTHOR: ! ! Keith Brewster, CAPS, July, 1995 ! ! MODIFICATION HISTORY: ! Sept, 1996 (KB) ! Added count-reporting diagnostic output. ! ! Dec., 1998 (KB) ! Added correlation categories. ! ! Feb., 1999 (KB) ! Moved calculation of oanxsng variables to outside the IF (good) ! block, so that it will always be available, for future ! calculations. Needed for determining qv thresholding from RH ! thresholding. Added sychronization of wind error flags, if one ! component is judged to be in error, the other is also. ! !----------------------------------------------------------------------- ! ! Variable Declarations: ! !----------------------------------------------------------------------- ! IMPLICIT NONE ! INTEGER :: nx,ny,nz,nz_tab INTEGER :: mxsng,nvar INTEGER :: nobsng ! !----------------------------------------------------------------------- ! ! Arrays defining model grid ! !----------------------------------------------------------------------- ! REAL :: xs(nx) REAL :: ys(ny) REAL :: zp (nx,ny,nz) ! The physical height coordinate defined at ! w-point of the staggered grid. ! INTEGER :: icatg(nx,ny) ! !----------------------------------------------------------------------- ! ! Background fields ! !----------------------------------------------------------------------- ! REAL :: anx(nx,ny,nz,nvar) REAL :: qback(nvar,nz_tab) REAL :: hqback(nz_tab) INTEGER :: nlvqback ! !----------------------------------------------------------------------- ! ! Column-interpolated values (used internally only) ! !----------------------------------------------------------------------- ! REAL :: shght(nz) REAL :: su(nz) REAL :: sv(nz) REAL :: spres(nz) REAL :: stheta(nz) REAL :: sqv(nz) ! !----------------------------------------------------------------------- ! ! Station variables ! !----------------------------------------------------------------------- ! CHARACTER (LEN=5) :: stnsng(mxsng) INTEGER :: isrcsng(mxsng) INTEGER :: icatsng(mxsng) REAL :: elevsng(mxsng) REAL :: xsng(mxsng) REAL :: ysng(mxsng) REAL :: obsng(nvar,mxsng) REAL :: qobsng(nvar,mxsng) INTEGER :: qualsng(nvar,mxsng) REAL :: odifsng(nvar,mxsng) REAL :: oanxsng(nvar,mxsng) REAL :: thesng(mxsng) ! !----------------------------------------------------------------------- ! ! Misc internal variables ! !----------------------------------------------------------------------- ! INTEGER :: ista,ivar,kgrid,ktab,kntdom INTEGER :: ipt,jpt,ireturn,nlevs REAL :: selev,hgtgnd,hgtagl REAL :: whigh,wlow,wqhigh,wqlow,qbthe ! !----------------------------------------------------------------------- ! ! Beginning of executable code ! !----------------------------------------------------------------------- ! kntdom=0 DO ista=1,nobsng ! !----------------------------------------------------------------------- ! ! Find location in ARPS grid. ! !----------------------------------------------------------------------- ! CALL findlc(nx,ny,xs,ys,xsng(ista),ysng(ista), & ipt,jpt,ireturn) ! !----------------------------------------------------------------------- ! ! Interpolated gridded data if extrapolation is not indicated. ! !----------------------------------------------------------------------- ! IF(ireturn == 0) THEN ! write(6,'(a,a)') stnsng(ista), ! : ' inside ARPS domain, processing' kntdom=kntdom+1 ! write (6,'(2x,a,f12.2,a,f12.2,/ ! : 2x,a,i6,a,i6)') ! : ' location x= ',(0.001*xsng(ista)), ! : ' y= ',(0.001*ysng(ista)), ! : ' found near pt i= ',ipt,' j= ',jpt ! write (6,'(12x,a,f12.2,a,f12.2,/)') ! : 'x= ',(0.001*xs(ipt)),' y= ',(0.001*ys(jpt)) ! !----------------------------------------------------------------------- ! ! Interpolate (in the horizontal) for the whole vertical column. ! !----------------------------------------------------------------------- ! CALL colint(nx,ny,nz,nvar, & xs,ys,zp,xsng(ista),ysng(ista),ipt,jpt,anx, & su,sv,stheta,spres,shght,sqv,selev, & nlevs) ! !----------------------------------------------------------------------- ! ! Assign category ! !----------------------------------------------------------------------- ! icatsng(ista)=icatg(ipt,jpt) ! !----------------------------------------------------------------------- ! ! Interpolate in the vertical at each obs level and compute ! obs differences. ! !----------------------------------------------------------------------- ! hgtgnd=0.5*(shght(2)+shght(1)) DO kgrid=2,nlevs-2 IF(shght(kgrid) > elevsng(ista)) EXIT END DO ! 251 CONTINUE whigh=(elevsng(ista)-shght(kgrid-1))/ & (shght(kgrid)-shght(kgrid-1)) wlow=1.-whigh ! hgtagl=AMIN1(hqback(nlvqback), & AMAX1(hqback(1),(elevsng(ista)-hgtgnd))) DO ktab=2,nlvqback-1 IF(hqback(ktab) > hgtagl) EXIT END DO ! 281 CONTINUE wqhigh=(hgtagl-hqback(ktab-1))/ & (hqback(ktab)-hqback(ktab-1)) wqlow=1.-wqhigh ! oanxsng(1,ista)=(wlow*su(kgrid-1)+whigh*su(kgrid)) IF(qualsng(1,ista) > 0) THEN odifsng(1,ista)=obsng(1,ista)-oanxsng(1,ista) qobsng(1,ista)=qobsng(1,ista)/ & (wqlow*qback(1,ktab-1)+wqhigh*qback(1,ktab)) END IF oanxsng(2,ista)=(wlow*sv(kgrid-1)+whigh*sv(kgrid)) IF(qualsng(2,ista) > 0) THEN odifsng(2,ista)=obsng(2,ista)-oanxsng(2,ista) qobsng(2,ista)=qobsng(2,ista)/ & (wqlow*qback(2,ktab-1)+wqhigh*qback(2,ktab)) END IF oanxsng(3,ista)=EXP( wlow*LOG(spres(kgrid-1))+ & whigh*LOG(spres(kgrid)) ) IF(qualsng(3,ista) > 0) THEN odifsng(3,ista)=obsng(3,ista)-oanxsng(3,ista) qobsng(3,ista)=qobsng(3,ista)/ & (wqlow*qback(3,ktab-1)+wqhigh*qback(3,ktab)) END IF oanxsng(4,ista)=(wlow*stheta(kgrid-1)+whigh*stheta(kgrid)) IF(qualsng(4,ista) > 0) THEN odifsng(4,ista)=obsng(4,ista)-oanxsng(4,ista) qbthe=wqlow*qback(4,ktab-1)+wqhigh*qback(4,ktab) thesng(ista)=( (obsng(4,ista)/qobsng(4,ista))+ & (oanxsng(4,ista)/qbthe) ) / & ((1./qobsng(4,ista)) + (1./qbthe)) ! print *, ' Theta:anx,obs,qsrc,qback: ', ! : oanxsng(4,ista),obsng(4,ista),qobsng(4,ista),qbthe qobsng(4,ista)=qobsng(4,ista)/qbthe ! print *, ' theta-sng qobs normalized: ', ! : thesng(ista),qobsng(4,ista) ELSE thesng(ista)=(wlow*stheta(kgrid-1)+whigh*stheta(kgrid)) END IF oanxsng(5,ista)=(wlow*sqv(kgrid-1)+whigh*sqv(kgrid)) IF(qualsng(5,ista) > 0) THEN odifsng(5,ista)=obsng(5,ista)-oanxsng(5,ista) qobsng(5,ista)=qobsng(5,ista)/ & (wqlow*qback(5,ktab-1)+wqhigh*qback(5,ktab)) END IF ! ELSE ! ! write(6,'(a,a)') stnsng(ista), ! : ' outside ARPS domain, skipping' ! isrcsng(ista)=0 icatsng(ista)=1 ! write(6,'(a,a,i4)') ' Extrapolation status returned from', ! : ' subroutine findlc: ',ireturn ! IF(ireturn.eq.-1) write(6,'(a)') ! : ' Extrapolation in x detected' ! IF(ireturn.eq.-2) write(6,'(a)') ! : ' Extrapolation in y detected' ! write (6,'(2x,a,f12.2,a,f12.2,/ ! : 2x,a,i6,a,i6/)') ! : ' location x= ',(0.001*xsng(ista)), ! : ' y= ',(0.001*ysng(ista)), ! : ' nearest pt i= ',ipt,' j= ',jpt ! write (6,'(12x,a,f12.2,a,f12.2/)') ! : 'x= ',(0.001*xs(ipt)),' y= ',(0.001*ys(jpt)) DO ivar=1,nvar qualsng(ivar,ista)=-9 END DO END IF END DO ! WRITE(6,'(//,1x,i5,a,i5,a)') kntdom,' of ',nobsng, & ' single-level stations are inside the ARPS domain' RETURN END SUBROUTINE grdtosng ! SUBROUTINE grdtoua(nx,ny,nz,nz_tab,nzua,mxua,nvar,nobsua, & 1,2 xs,ys,zp,anx,qback,hqback,nlvqback, & shght,su,sv,spres,stheta,sqv, & stnua,isrcua,elevua,xua,yua,hgtua, & obsua,qobsua,qualua,nlevsua, & odifua,oanxua,theua) ! ! !################################################################## !################################################################## !###### ###### !###### SUBROUTINE GRDTOUA ###### !###### ###### !###### Developed by ###### !###### Center for Analysis and Prediction of Storms ###### !###### University of Oklahoma ###### !###### ###### !################################################################## !################################################################## ! ! ! PURPOSE: ! Gridded data are interpolated to upper air locations to ! produce observation differences. For now, bilinear interpolation ! is used to create a vertical sounding at the obs location ! and that is interpolated in the vertical to obtain the ! bacground value. ! ! AUTHOR: ! ! Keith Brewster, CAPS, July, 1995 ! ! MODIFICATION HISTORY: ! Sept, 1996 (KB) ! Added count-reporting diagnostic output. ! ! !----------------------------------------------------------------------- ! ! Variable Declarations: ! !----------------------------------------------------------------------- ! IMPLICIT NONE ! INTEGER :: nx,ny,nz,nz_tab INTEGER :: nzua,mxua,nvar INTEGER :: nobsua ! !----------------------------------------------------------------------- ! ! Arrays defining model grid ! !----------------------------------------------------------------------- ! REAL :: xs(nx) REAL :: ys(ny) REAL :: zp (nx,ny,nz) ! The physical height coordinate defined at ! w-point of the staggered grid. ! !----------------------------------------------------------------------- ! ! Background fields ! !----------------------------------------------------------------------- ! REAL :: anx(nx,ny,nz,nvar) REAL :: qback(nvar,nz_tab) REAL :: hqback(nz_tab) INTEGER :: nlvqback ! REAL :: shght(nz) REAL :: su(nz) REAL :: sv(nz) REAL :: spres(nz) REAL :: stheta(nz) REAL :: sqv(nz) ! !----------------------------------------------------------------------- ! ! Station variables ! !----------------------------------------------------------------------- ! CHARACTER (LEN=5) :: stnua(mxua) INTEGER :: isrcua(mxua) REAL :: elevua(mxua) REAL :: xua(mxua),yua(mxua) REAL :: hgtua(nzua,mxua) REAL :: obsua(nvar,nzua,mxua) REAL :: qobsua(nvar,nzua,mxua) INTEGER :: qualua(nvar,nzua,mxua) INTEGER :: nlevsua(mxua) REAL :: odifua(nvar,nzua,mxua) REAL :: oanxua(nvar,nzua,mxua) REAL :: theua(nzua,mxua) ! !----------------------------------------------------------------------- ! ! Misc. internal variables ! !----------------------------------------------------------------------- ! INTEGER :: ista,ivar,k,kgrid,ktab,kntdom INTEGER :: ipt,jpt,ireturn,nlevs REAL :: selev,hgtgnd,hgtagl REAL :: whigh,wlow,wqhigh,wqlow,qbthe ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! ! Beginning of executable code... ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! kntdom=0 DO ista=1,nobsua ! !----------------------------------------------------------------------- ! ! Find location in ARPS grid. ! !----------------------------------------------------------------------- ! CALL findlc(nx,ny,xs,ys,xua(ista),yua(ista), & ipt,jpt,ireturn) ! !----------------------------------------------------------------------- ! ! Interpolate if extrapoltion is not indicated. ! !----------------------------------------------------------------------- ! IF(ireturn == 0) THEN ! write(6,'(a,a)') stnua(ista), ! : ' inside ARPS domain, processing' kntdom=kntdom+1 ! write (6,'(2x,a,f12.2,a,f12.2,/ ! : 2x,a,i6,a,i6)') ! : ' location x= ',(0.001*xua(ista)), ! : ' y= ',(0.001*yua(ista)), ! : ' found near pt i= ',ipt,' j= ',jpt ! write (6,'(12x,a,f12.2,a,f12.2,/)') ! : 'x= ',(0.001*xs(ipt)),' y= ',(0.001*ys(jpt)) ! !----------------------------------------------------------------------- ! ! Interpolate (in the horizontal) for the whole vertical column. ! !----------------------------------------------------------------------- ! CALL colint(nx,ny,nz,nvar, & xs,ys,zp,xua(ista),yua(ista),ipt,jpt,anx, & su,sv,stheta,spres,shght,sqv,selev, & nlevs) ! !----------------------------------------------------------------------- ! ! Convert pressure to ln(p) for interpolation ! !----------------------------------------------------------------------- ! DO k=1,nlevs spres(k)=LOG(spres(k)) END DO ! !----------------------------------------------------------------------- ! ! Interpolate in the vertical at each obs level and compute ! obs differences. ! !----------------------------------------------------------------------- ! hgtgnd=0.5*(shght(2)+shght(1)) DO k=1,nlevsua(ista) DO kgrid=2,nlevs-1 IF(shght(kgrid) > hgtua(k,ista)) GO TO 260 END DO DO ivar=1,nvar qualua(ivar,k,ista)=-9 END DO CYCLE 260 CONTINUE whigh=(hgtua(k,ista)-shght(kgrid-1))/ & (shght(kgrid)-shght(kgrid-1)) wlow=1.-whigh ! hgtagl=AMIN1(hqback(nlvqback), & AMAX1(hqback(1),(hgtua(k,ista)-hgtgnd))) DO ktab=2,nlvqback-1 IF(hqback(ktab) > hgtagl) EXIT END DO ! 281 CONTINUE wqhigh=(hgtagl-hqback(ktab-1))/ & (hqback(ktab)-hqback(ktab-1)) wqlow=1.-wqhigh ! IF(qualua(1,k,ista) > 0) THEN oanxua(1,k,ista)=wlow*su(kgrid-1)+whigh*su(kgrid) odifua(1,k,ista)=obsua(1,k,ista)-oanxua(1,k,ista) qobsua(1,k,ista)=qobsua(1,k,ista)/ & (wqlow*qback(1,ktab-1)+wqhigh*qback(1,ktab)) END IF IF(qualua(2,k,ista) > 0) THEN oanxua(2,k,ista)=wlow*sv(kgrid-1)+whigh*sv(kgrid) odifua(2,k,ista)=obsua(2,k,ista)-oanxua(2,k,ista) qobsua(2,k,ista)=qobsua(2,k,ista)/ & (wqlow*qback(2,ktab-1)+wqhigh*qback(2,ktab)) END IF IF(qualua(3,k,ista) > 0) THEN oanxua(3,k,ista)=EXP( wlow*spres(kgrid-1)+ & whigh*spres(kgrid) ) odifua(3,k,ista)=obsua(3,k,ista)-oanxua(3,k,ista) qobsua(3,k,ista)=qobsua(3,k,ista)/ & (wqlow*qback(3,ktab-1)+wqhigh*qback(3,ktab)) END IF IF(qualua(4,k,ista) > 0) THEN oanxua(4,k,ista)=wlow*stheta(kgrid-1)+whigh*stheta(kgrid) odifua(4,k,ista)=obsua(4,k,ista)-oanxua(4,k,ista) qbthe=wqlow*qback(4,ktab-1)+wqhigh*qback(4,ktab) theua(k,ista)=( (obsua(4,k,ista)/qobsua(4,k,ista))+ & (oanxua(4,k,ista)/qbthe) ) / & ((1./qobsua(4,k,ista)) + (1./qbthe)) qobsua(4,k,ista)=qobsua(4,k,ista)/qbthe ELSE theua(k,ista)=wlow*stheta(kgrid-1)+whigh*stheta(kgrid) END IF IF(qualua(5,k,ista) > 0) THEN oanxua(5,k,ista)=wlow*sqv(kgrid-1)+whigh*sqv(kgrid) odifua(5,k,ista)=obsua(5,k,ista)-oanxua(5,k,ista) qobsua(5,k,ista)=qobsua(5,k,ista)/ & (wqlow*qback(5,ktab-1)+wqhigh*qback(5,ktab)) END IF END DO ! ELSE ! ! write(6,'(a,a)') stnua(ista), ! : ' outside ARPS domain, skipping' isrcua(ista)=0 ! write(6,'(a,a,i4)') ' Extrapolation status returned from', ! : ' subroutine findlc: ',ireturn ! IF(ireturn.eq.-1) write(6,'(a)') ! : ' Extrapolation in x detected' ! IF(ireturn.eq.-2) write(6,'(a)') ! : ' Extrapolation in y detected' ! write (6,'(2x,a,f12.2,a,f12.2,/ ! : 2x,a,i6,a,i6/)') ! : ' location x= ',(0.001*xua(ista)), ! : ' y= ',(0.001*yua(ista)), ! : ' nearest pt i= ',ipt,' j= ',jpt ! write (6,'(12x,a,f12.2,a,f12.2/)') ! : 'x= ',(0.001*xs(ipt)),' y= ',(0.001*ys(jpt)) ! DO k=1,nzua DO ivar=1,nvar qualua(ivar,k,ista)=-9 END DO END DO END IF ! inside domain? END DO ! wdt !WRITE(6,'(//,1x,i5,a,i5,a)') kntdom,' of ',nobsua, & ! ' upper air profiles are inside the ARPS domain' PRINT *, kntdom,' of ',nobsua, & ' upper air profiles are inside the ARPS domain' RETURN END SUBROUTINE grdtoua ! !################################################################## !################################################################## !###### ###### !###### SUBROUTINE GRDTORET ###### !###### ###### !###### Developed by ###### !###### Center for Analysis and Prediction of Storms ###### !###### University of Oklahoma ###### !###### ###### !################################################################## !################################################################## ! SUBROUTINE grdtoret(nx,ny,nz,nztab, & 1,2 nzret,mxret,mxcolret,nvar,ncolret, & xs,ys,zp,anx,qback,hqback,nlvqback, & shght,su,sv,spres,stheta,sqv, & stnret,iret,xretc,yretc,hgtretc, & obsret,qobsret,qualret,nlevret, & odifret,oanxret,theretc) !----------------------------------------------------------------------- ! ! PURPOSE: ! Gridded data are interpolated to retrieval column locations to ! produce observation differences. For now, bilinear interpolation ! is used to create a vertical sounding at the obs location ! and that is interpolated in the vertical to obtain the ! bacground value. ! ! AUTHOR: ! ! Keith Brewster, CAPS, July, 1995 ! ! MODIFICATION HISTORY: ! Sept, 1996 (KB) ! Added count-reporting diagnostic output. ! !----------------------------------------------------------------------- ! ! Variable Declarations: ! !----------------------------------------------------------------------- ! IMPLICIT NONE ! INTEGER :: nx,ny,nz,nztab INTEGER :: nzret,mxret,mxcolret,nvar INTEGER :: ncolret ! !----------------------------------------------------------------------- ! ! Arrays defining model grid ! !----------------------------------------------------------------------- ! REAL :: xs(nx) REAL :: ys(ny) REAL :: zp (nx,ny,nz) ! The physical height coordinate defined at ! w-point of the staggered grid. ! !----------------------------------------------------------------------- ! ! Background fields ! !----------------------------------------------------------------------- ! REAL :: anx(nx,ny,nz,nvar) REAL :: qback(nvar,nztab) REAL :: hqback(nztab) INTEGER :: nlvqback ! REAL :: shght(nz) REAL :: su(nz) REAL :: sv(nz) REAL :: spres(nz) REAL :: stheta(nz) REAL :: sqv(nz) ! !----------------------------------------------------------------------- ! ! Station variables ! !----------------------------------------------------------------------- ! CHARACTER (LEN=5) :: stnret(mxret) INTEGER :: iret(mxcolret) REAL :: xretc(mxcolret),yretc(mxcolret) REAL :: hgtretc(nzret,mxcolret) REAL :: obsret(nvar,nzret,mxcolret) REAL :: qobsret(nvar,nzret,mxcolret) INTEGER :: qualret(nvar,nzret,mxcolret) INTEGER :: nlevret(mxcolret) REAL :: odifret(nvar,nzret,mxcolret) REAL :: oanxret(nvar,nzret,mxcolret) REAL :: theretc(nzret,mxcolret) ! !----------------------------------------------------------------------- ! ! Misc. internal variables ! !----------------------------------------------------------------------- ! INTEGER :: ista,ivar,k,kgrid,ktab,kntdom INTEGER :: ipt,jpt,ireturn,nlevs REAL :: selev,hgtgnd,hgtagl REAL :: whigh,wlow,wqhigh,wqlow,qbthe ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! ! Beginning of executable code... ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! kntdom=0 DO ista=1,ncolret ! !----------------------------------------------------------------------- ! ! Find location in ARPS grid. ! !----------------------------------------------------------------------- ! CALL findlc(nx,ny,xs,ys,xretc(ista),yretc(ista), & ipt,jpt,ireturn) ! !----------------------------------------------------------------------- ! ! Interpolate if extrapoltion is not indicated. ! !----------------------------------------------------------------------- ! IF(ireturn == 0) THEN ! write(6,'(a,i4,a)') 'Column ',ista, ! : ' inside ARPS domain, processing' kntdom=kntdom+1 ! write (6,'(2x,a,f12.2,a,f12.2,/ ! : 2x,a,i6,a,i6)') ! : ' location x= ',(0.001*xua(ista)), ! : ' y= ',(0.001*yua(ista)), ! : ' found near pt i= ',ipt,' j= ',jpt ! write (6,'(12x,a,f12.2,a,f12.2,/)') ! : 'x= ',(0.001*xs(ipt)),' y= ',(0.001*ys(jpt)) ! !----------------------------------------------------------------------- ! ! Interpolate (in the horizontal) for the whole vertical column. ! !----------------------------------------------------------------------- ! CALL colint(nx,ny,nz,nvar, & xs,ys,zp,xretc(ista),yretc(ista),ipt,jpt,anx, & su,sv,stheta,spres,shght,sqv,selev, & nlevs) ! !----------------------------------------------------------------------- ! ! Convert pressure to ln(p) for interpolation ! !----------------------------------------------------------------------- ! DO k=1,nlevs spres(k)=LOG(spres(k)) END DO ! !----------------------------------------------------------------------- ! ! Interpolate in the vertical at each obs level and compute ! obs differences. ! !----------------------------------------------------------------------- ! hgtgnd=0.5*(shght(2)+shght(1)) DO k=1,nlevret(ista) DO kgrid=2,nlevs-1 IF(shght(kgrid) > hgtretc(k,ista)) GO TO 260 END DO DO ivar=1,nvar qualret(ivar,k,ista)=-9 END DO CYCLE 260 CONTINUE whigh=(hgtretc(k,ista)-shght(kgrid-1))/ & (shght(kgrid)-shght(kgrid-1)) wlow=1.-whigh ! hgtagl=AMIN1(hqback(nlvqback), & AMAX1(hqback(1),(hgtretc(k,ista)-hgtgnd))) DO ktab=2,nlvqback-1 IF(hqback(ktab) > hgtagl) EXIT END DO ! 281 CONTINUE wqhigh=(hgtagl-hqback(ktab-1))/ & (hqback(ktab)-hqback(ktab-1)) wqlow=1.-wqhigh ! IF(qualret(1,k,ista) > 0) THEN oanxret(1,k,ista)=wlow*su(kgrid-1)+whigh*su(kgrid) odifret(1,k,ista)=obsret(1,k,ista)-oanxret(1,k,ista) qobsret(1,k,ista)=qobsret(1,k,ista)/ & (wqlow*qback(1,ktab-1)+wqhigh*qback(1,ktab)) END IF IF(qualret(2,k,ista) > 0) THEN oanxret(2,k,ista)=wlow*sv(kgrid-1)+whigh*sv(kgrid) odifret(2,k,ista)=obsret(2,k,ista)-oanxret(2,k,ista) qobsret(2,k,ista)=qobsret(2,k,ista)/ & (wqlow*qback(2,ktab-1)+wqhigh*qback(2,ktab)) END IF IF(qualret(3,k,ista) > 0) THEN oanxret(3,k,ista)=EXP( wlow*spres(kgrid-1)+ & whigh*spres(kgrid) ) odifret(3,k,ista)=obsret(3,k,ista)-oanxret(3,k,ista) qobsret(3,k,ista)=qobsret(3,k,ista)/ & (wqlow*qback(3,ktab-1)+wqhigh*qback(3,ktab)) END IF IF(qualret(4,k,ista) > 0) THEN oanxret(4,k,ista)=wlow*stheta(kgrid-1)+whigh*stheta(kgrid) odifret(4,k,ista)=obsret(4,k,ista)-oanxret(4,k,ista) qbthe=wqlow*qback(4,ktab-1)+wqhigh*qback(4,ktab) theretc(k,ista)=( (obsret(4,k,ista)/qobsret(4,k,ista))+ & (oanxret(4,k,ista)/qbthe) ) / & ((1./qobsret(4,k,ista)) + (1./qbthe)) qobsret(4,k,ista)=qobsret(4,k,ista)/qbthe ELSE theretc(k,ista)=wlow*stheta(kgrid-1)+whigh*stheta(kgrid) END IF IF(qualret(5,k,ista) > 0) THEN oanxret(5,k,ista)=wlow*sqv(kgrid-1)+whigh*sqv(kgrid) odifret(5,k,ista)=obsret(5,k,ista)-oanxret(5,k,ista) qobsret(5,k,ista)=qobsret(5,k,ista)/ & (wqlow*qback(5,ktab-1)+wqhigh*qback(5,ktab)) END IF END DO ! ELSE ! ! write(6,'(a,a)') stnret(ista), ! : ' outside ARPS domain, skipping' iret(ista)=0 ! write(6,'(a,a,i4)') ' Extrapolation status returned from', ! : ' subroutine findlc: ',ireturn ! IF(ireturn.eq.-1) write(6,'(a)') ! : ' Extrapolation in x detected' ! IF(ireturn.eq.-2) write(6,'(a)') ! : ' Extrapolation in y detected' ! write (6,'(2x,a,f12.2,a,f12.2,/ ! : 2x,a,i6,a,i6/)') ! : ' location x= ',(0.001*xretc(ista)), ! : ' y= ',(0.001*yretc(ista)), ! : ' nearest pt i= ',ipt,' j= ',jpt ! write (6,'(12x,a,f12.2,a,f12.2/)') ! : 'x= ',(0.001*xs(ipt)),' y= ',(0.001*ys(jpt)) ! DO k=1,nzret DO ivar=1,nvar qualret(ivar,k,ista)=-9 END DO END DO END IF ! inside domain? END DO WRITE(6,'(//,1x,i5,a,i5,a)') kntdom,' of ',ncolret, & ' retrieval columns are inside the ARPS domain' RETURN END SUBROUTINE grdtoret ! !################################################################## !################################################################## !###### ###### !###### SUBROUTINE COLINT ###### !###### ###### !###### Developed by ###### !###### Center for Analysis and Prediction of Storms ###### !###### University of Oklahoma ###### !###### ###### !################################################################## !################################################################## ! SUBROUTINE colint(nx,ny,nz,nvar, & 5,8 xs,ys,zp,xpt,ypt,ipt,jpt,anx, & su,sv,stheta,spres,shght,sqv,selev, & nlevs) ! !----------------------------------------------------------------------- ! ! PURPOSE: ! ! Interpolates ARPS history data in the horizontal to create ! a column of data located at point xpt, ypt. ! ! Bilinear interpolation is used. ! !----------------------------------------------------------------------- ! ! AUTHOR: Keith Brewster ! April 1992. ! ! MODIFICATION HISTORY: ! ! October, 1992 (K. Brewster) ! Conversion to ARPS 3.0. ! ! October, 1994 (K. Brewster) ! Conversion to ARPS 4.0. ! !----------------------------------------------------------------------- ! ! INPUT: ! ! nx,ny,nz Dimensions of ARPS grids. ! ! xs x coordinate of scalar points in physical/comp. space (m) ! ys y coordinate of scalar points in physical/comp. space (m) ! zp z coordinate of scalar grid points in physical space (m) ! ! xpt x coordinate of desired sounding (m) ! ypt y coordinate of desired sounding (m) ! ! ipt i index of grid point just west of xpt,ypt ! jpt j index of grid point just south of xpt,ypt ! ! anx Background field ! ! OUTPUT: ! ! su Interpolated u wind component. (m/s) ! sv Interpolated v wind component. (m/s) ! stheta Interpolated potential temperature (K). ! spres Interpolated pressure. (Pascals) ! shght Interpolated height (meters) ! sqv Interpolated specific humidity (kg/kg) ! selev Interpolated surface elevation (m) ! nlevs Number of above-ground sounding levels. ! !----------------------------------------------------------------------- ! ! Variable Declarations: ! !----------------------------------------------------------------------- ! ! Arguments -- location data ! !----------------------------------------------------------------------- ! IMPLICIT NONE INTEGER :: nx,ny,nz,nvar ! Dimensions of ARPS grids. REAL :: xs(nx) ! x coordinate of grid points in ! physical/comp. space (m) REAL :: ys(ny) ! y coordinate of grid points in ! physical/comp. space (m) REAL :: zp(nx,ny,nz) ! z coordinate of grid points in ! physical space (m) REAL :: xpt ! location to find in x coordinate (m) REAL :: ypt ! location to find in y coordinate (m) INTEGER :: ipt ! i index to the west of desired ! location INTEGER :: jpt ! j index to the south of desired ! location ! !----------------------------------------------------------------------- ! ! Arguments -- background field ! !----------------------------------------------------------------------- ! REAL :: anx(nx,ny,nz,nvar) ! !----------------------------------------------------------------------- ! ! Arguments -- Extracted sounding variables ! !----------------------------------------------------------------------- ! REAL :: su(nz),sv(nz),stheta(nz),sqv(nz) REAL :: spres(nz),shght(nz) REAL :: selev INTEGER :: nlevs ! !----------------------------------------------------------------------- ! ! Functions called ! !----------------------------------------------------------------------- ! REAL :: aint2d ! !----------------------------------------------------------------------- ! ! Include files ! !----------------------------------------------------------------------- ! INCLUDE 'phycst.inc' ! !----------------------------------------------------------------------- ! ! Misc. local variables ! !----------------------------------------------------------------------- ! INTEGER :: k,in,jn REAL :: delx,ddx,dely,ddy,w1,w2,w3,w4 REAL :: t2,t3,hmid,tmid ! !----------------------------------------------------------------------- ! ! Find corner weights ! !----------------------------------------------------------------------- ! in=ipt+1 delx=xs(in)-xs(ipt) IF(ABS(delx) > 0.) THEN ddx=(xpt-xs(ipt))/delx ELSE ddx=0. END IF jn=jpt+1 dely=ys(jn)-ys(jpt) IF(ABS(dely) > 0.) THEN ddy=(ypt-ys(jpt))/dely ELSE ddy=0. END IF w1=(1.-ddx)*(1.-ddy) w2=ddx*(1.-ddy) w3=ddx*ddy w4=(1.-ddx)*ddy ! !----------------------------------------------------------------------- ! ! Interpolate all variables at all levels. ! !----------------------------------------------------------------------- ! nlevs=nz-1 DO k=1,nz-1 shght(k)= & aint2d(nx,ny,nz, zp,ipt,jpt,k,in,jn,w1,w2,w3,w4) su(k)= & aint2d(nx,ny,nz, anx(1,1,1,1),ipt,jpt,k,in,jn,w1,w2,w3,w4) sv(k)= & aint2d(nx,ny,nz, anx(1,1,1,2),ipt,jpt,k,in,jn,w1,w2,w3,w4) spres(k)= & aint2d(nx,ny,nz, anx(1,1,1,3),ipt,jpt,k,in,jn,w1,w2,w3,w4) stheta(k)= & aint2d(nx,ny,nz, anx(1,1,1,4),ipt,jpt,k,in,jn,w1,w2,w3,w4) sqv(k)= & aint2d(nx,ny,nz, anx(1,1,1,5),ipt,jpt,k,in,jn,w1,w2,w3,w4) END DO ! !----------------------------------------------------------------------- ! ! Get height at scalar points, since zp was defined at w points. ! !----------------------------------------------------------------------- ! selev=shght(2) DO k=1,nz-1 shght(k)=0.5*(shght(k+1)+shght(k)) END DO ! !----------------------------------------------------------------------- ! ! Get a value at the surface, by linearly interpolating ! between the 1st and second levels. ! !----------------------------------------------------------------------- ! w2=(selev-shght(1))/(shght(2)-shght(1)) w1=1.-w2 su(1)=w1* su(1) + w2* su(2) sv(1)=w1* sv(1) + w2* sv(2) stheta(1)=w1*stheta(1) + w2*stheta(2) sqv(1)=w1* sqv(1) + w2* sqv(2) shght(1)=selev ! !----------------------------------------------------------------------- ! ! Integrate downward to get the pressure at level 1. ! !----------------------------------------------------------------------- ! t3=stheta(3)*(spres(3)/100000.)**rddcp t2=stheta(2)*(spres(2)/100000.)**rddcp hmid=0.5*(shght(2)+shght(1)) tmid=t3+(((shght(3)-hmid)/(shght(3)-shght(2)))*(t2-t3)) spres(1)=spres(2)*EXP(g*(shght(2)-shght(1))/(rd*tmid)) RETURN END SUBROUTINE colint ! !################################################################## !################################################################## !###### ###### !###### SUBROUTINE QCDIFF ###### !###### ###### !###### Developed by ###### !###### Center for Analysis and Prediction of Storms ###### !###### University of Oklahoma ###### !###### ###### !################################################################## !################################################################## ! SUBROUTINE qcdiff(nvar,nvarrad,nvarradin,mxsng,nsrcsng, & 1,3 nzua,mxua,nsrcua, & nzrad,mxrad,mxcolrad,nsrcrad, & nzret,mxret,mxcolret,nsrcret, & nobsng,nobsua,ncolrad,ncolret,nam_var, & stnsng,isrcsng,hgtsng,obsng,oanxsng,odifsng, & qcthrsng,qualsng, & stnua,isrcua,hgtua,obsua,oanxua,odifua, & qcthrua,qualua,nlevsua, & stnrad,irad,isrcrad,hgtradc,obsrad,odifrad, & qcthrrad,qualrad,nlevrad, & stnret,iret,isrcret,hgtretc, & obsret,oanxret,odifret, & qcthrret,qualret,nlevret, & obsknt,rejknt) ! !----------------------------------------------------------------------- ! ! PURPOSE: ! Observation differences are compared to expected errors ! and rejected if they exceed a threshold. ! ! AUTHOR: ! ! Keith Brewster, CAPS, July, 1995 ! ! MODIFICATION HISTORY: ! ! !----------------------------------------------------------------------- ! ! Variable Declarations: ! !----------------------------------------------------------------------- ! IMPLICIT NONE ! ! Sizing variables ! INTEGER :: nvar,nvarrad,nvarradin,mxsng,nsrcsng INTEGER :: nzua,mxua,nsrcua INTEGER :: nzrad,mxrad,mxcolrad,nsrcrad INTEGER :: nzret,mxret,mxcolret,nsrcret ! INTEGER :: nobsng,nobsua,ncolrad,ncolret CHARACTER (LEN=6) :: nam_var(nvar) ! !----------------------------------------------------------------------- ! ! Station variables ! !----------------------------------------------------------------------- ! CHARACTER (LEN=5) :: stnsng(mxsng) INTEGER :: isrcsng(mxsng) REAL :: obsng(nvar,mxsng) REAL :: hgtsng(mxsng) REAL :: qcthrsng(nvar,nsrcsng) INTEGER :: qualsng(nvar,mxsng) REAL :: oanxsng(nvar,mxsng) REAL :: odifsng(nvar,mxsng) ! CHARACTER (LEN=5) :: stnua(mxua) INTEGER :: isrcua(mxua) REAL :: hgtua(nzua,mxua) REAL :: obsua(nvar,nzua,mxua) REAL :: oanxua(nvar,nzua,mxua) REAL :: odifua(nvar,nzua,mxua) REAL :: qcthrua(nvar,nsrcua) INTEGER :: qualua(nvar,nzua,mxua) INTEGER :: nlevsua(mxua) ! CHARACTER (LEN=5) :: stnrad(mxrad) INTEGER :: irad(mxcolrad) INTEGER :: isrcrad(0:mxrad) REAL :: hgtradc(nzrad,mxcolrad) REAL :: obsrad(nvarradin,nzrad,mxcolrad) REAL :: odifrad(nvarrad,nzrad,mxcolrad) REAL :: qcthrrad(nvarradin,nsrcrad) INTEGER :: qualrad(nvarrad,nzrad,mxcolrad) INTEGER :: nlevrad(mxcolrad) ! CHARACTER (LEN=5) :: stnret(mxret) INTEGER :: iret(mxcolret) INTEGER :: isrcret(0:mxret) REAL :: hgtretc(nzret,mxcolret) REAL :: obsret(nvar,nzret,mxcolret) REAL :: oanxret(nvar,nzret,mxcolret) REAL :: odifret(nvar,nzret,mxcolret) REAL :: qcthrret(nvar,nsrcret) INTEGER :: qualret(nvar,nzret,mxcolret) INTEGER :: nlevret(mxcolret) REAL :: obsknt(nvar) REAL :: rejknt(nvar) ! !----------------------------------------------------------------------- ! ! Misc. internal variables ! !----------------------------------------------------------------------- ! INTEGER :: ista,ivar,klev,jsrc REAL :: pctrej,vrdiff REAL :: tk,qvsat,qcthrqv ! !----------------------------------------------------------------------- ! ! Function f_qvsat and inline directive for Cray PVP ! !----------------------------------------------------------------------- ! REAL :: f_qvsat !fpp$ expand (f_qvsat) !dir$ inline always f_qvsat !*$* inline routine (f_qvsat) ! !----------------------------------------------------------------------- ! ! Include files ! !----------------------------------------------------------------------- ! INCLUDE 'phycst.inc' ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! ! Beginning of executable code... ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! ! !----------------------------------------------------------------------- ! ! Check single-level observation differences ! !----------------------------------------------------------------------- ! DO ivar=1,nvar obsknt(ivar)=0. rejknt(ivar)=0. END DO DO ista=1,nobsng IF(isrcsng(ista) /= 0) THEN DO ivar=1,nvar-1 IF(qualsng(ivar,ista) > 0) THEN obsknt(ivar)=obsknt(ivar)+1. IF(ABS(odifsng(ivar,ista)) > qcthrsng(ivar,isrcsng(ista)) ) THEN WRITE(6,'(a,a,a,a)') & ' Discarding ',nam_var(ivar), & ' at ',stnsng(ista) WRITE(6,'(a,f8.0,a,f16.6,a,f16.6,a,f16.6)') & ' Hgt= ',hgtsng(ista),' Ob= ',obsng(ivar,ista), & ' Diff= ',odifsng(ivar,ista), & ' Thresh=',qcthrsng(ivar,isrcsng(ista)) qualsng(ivar,ista)=-199 rejknt(ivar)=rejknt(ivar)+1. END IF END IF END DO IF(qualsng(5,ista) > 0) THEN obsknt(5)=obsknt(5)+1. tk=oanxsng(4,ista)*((oanxsng(3,ista)/p0)**rddcp) qvsat=f_qvsat(oanxsng(3,ista),tk) qcthrqv=qcthrsng(5,isrcsng(ista))*qvsat IF(ABS(odifsng(5,ista)) > qcthrqv) THEN WRITE(6,'(a,a,a,a)') & ' Discarding ',nam_var(5), & ' at ',stnsng(ista) WRITE(6,'(a,f8.0,a,f16.6,a,f16.6,a,f16.6)') & ' Hgt= ',hgtsng(ista),' Ob= ',obsng(5,ista), & ' Diff= ',odifsng(5,ista), & ' Thresh=',qcthrqv qualsng(5,ista)=-199 rejknt(5)=rejknt(5)+1. END IF END IF ! !----------------------------------------------------------------------- ! ! Synchronize wind component flags ! !----------------------------------------------------------------------- ! IF(qualsng(1,ista) == -199) qualsng(2,ista)=-199 IF(qualsng(2,ista) == -199) qualsng(1,ista)=-199 END IF END DO ! !----------------------------------------------------------------------- ! ! Write statistics ! !----------------------------------------------------------------------- ! WRITE(6,'(//a/a)') ' QC Statistics for single-level data', & ' Variable Obs Rejected Percent' DO ivar=1,nvar pctrej=0. IF(obsknt(ivar) > 0.) pctrej=100.*rejknt(ivar)/obsknt(ivar) WRITE(6,'(2x,a,i10,i10,f8.1)') & nam_var(ivar),nint(obsknt(ivar)),nint(rejknt(ivar)),pctrej END DO WRITE(6,'(/a)') ' ' ! !----------------------------------------------------------------------- ! ! Check upper-air observation differences ! !----------------------------------------------------------------------- ! DO ivar=1,nvar obsknt(ivar)=0. rejknt(ivar)=0. END DO DO ista=1,nobsua IF(isrcua(ista) /= 0) THEN DO klev=1,nlevsua(ista) DO ivar=1,nvar-1 IF(qualua(ivar,klev,ista) > 0) THEN obsknt(ivar)=obsknt(ivar)+1. IF(ABS(odifua(ivar,klev,ista)) > qcthrua(ivar,isrcua(ista)) ) THEN WRITE(6,'(a,a,a,a,a,i4)') ' Discarding UA ', & nam_var(ivar),' at sta ',stnua(ista), & ' klev =',klev WRITE(6,'(a,f8.0,a,f16.6,a,f16.6,a,f16.6)') & ' Hgt= ',hgtua(klev,ista), & ' Ob= ',obsua(ivar,klev,ista), & ' Diff= ',odifua(ivar,klev,ista), & ' Thresh=',qcthrua(ivar,isrcua(ista)) qualua(ivar,klev,ista)=-199 rejknt(ivar)=rejknt(ivar)+1. END IF END IF END DO IF(qualua(5,klev,ista) > 0) THEN obsknt(5)=obsknt(5)+1. tk=oanxua(4,klev,ista)* & ((oanxua(3,klev,ista)/p0)**rddcp) qvsat=f_qvsat(oanxua(3,klev,ista),tk) qcthrqv=qcthrua(5,isrcua(ista))*qvsat IF(ABS(odifua(5,klev,ista)) > qcthrqv) THEN WRITE(6,'(a,a,a,a)') & ' Discarding ',nam_var(5), & ' at ',stnua(ista) WRITE(6,'(a,f8.0,a,f16.6,a,f16.6,a,f16.6)') & ' Hgt= ',hgtua(klev,ista), & ' Ob= ',obsua(5,klev,ista), & ' Diff= ',odifua(5,klev,ista), & ' Thresh=',qcthrqv qualua(5,klev,ista)=-199 rejknt(5)=rejknt(5)+1. END IF END IF ! !----------------------------------------------------------------------- ! ! Synchronize wind component flags ! !----------------------------------------------------------------------- ! IF(qualua(1,klev,ista) == -199) qualua(2,klev,ista)=-199 IF(qualua(2,klev,ista) == -199) qualua(1,klev,ista)=-199 END DO END IF END DO ! !----------------------------------------------------------------------- ! ! Write statistics ! !----------------------------------------------------------------------- ! WRITE(6,'(//a/a)') ' QC Statistics for UA data', & ' Variable Obs Rejected Percent' DO ivar=1,nvar pctrej=0. IF(obsknt(ivar) > 0.) pctrej=100.*rejknt(ivar)/obsknt(ivar) WRITE(6,'(2x,a,i10,i10,f8.1)') & nam_var(ivar),nint(obsknt(ivar)),nint(rejknt(ivar)),pctrej END DO WRITE(6,'(/a)') ' ' ! !----------------------------------------------------------------------- ! ! Check radar data observation differences ! Here radial wind difference is computed and compared only. ! !----------------------------------------------------------------------- ! obsknt(1)=0. rejknt(1)=0. DO ista=1,ncolrad IF(irad(ista) /= 0) THEN jsrc=isrcrad(irad(ista)) DO klev=1,nlevrad(ista) IF(qualrad(1,klev,ista) > 0 .AND. qualrad(2,klev,ista) > 0 ) THEN obsknt(1)=obsknt(1)+1. vrdiff=SQRT( & odifrad(1,klev,ista)*odifrad(1,klev,ista)+ & odifrad(2,klev,ista)*odifrad(2,klev,ista)) IF(vrdiff > qcthrrad(2,jsrc) ) THEN WRITE(6,'(a,a,i5,a,i4)') ' Discarding radar Vr', & ' at col ',ista,' klev =',klev WRITE(6,'(a,f8.0,a,f16.6,a,f16.6,a,f16.6)') & ' Hgt= ',hgtradc(klev,ista), & ' Ob= ',obsrad(2,klev,ista), & ' Diff= ',vrdiff, & ' Thresh=',qcthrrad(2,jsrc) qualrad(1,klev,ista)=-199 qualrad(2,klev,ista)=-199 rejknt(1)=rejknt(1)+1. END IF END IF END DO END IF END DO WRITE(6,'(//a/a)') ' QC Statistics for radar data', & ' Variable Obs Rejected Percent' pctrej=0. IF(obsknt(1) > 0.) pctrej=100.*rejknt(1)/obsknt(1) WRITE(6,'(2x,a,i10,i10,f8.1)') & 'Vr',nint(obsknt(1)),nint(rejknt(1)),pctrej WRITE(6,'(/a)') ' ' ! !----------------------------------------------------------------------- ! ! Check retrieval observation differences ! !----------------------------------------------------------------------- ! DO ivar=1,nvar obsknt(ivar)=0. rejknt(ivar)=0. END DO DO ista=1,ncolret IF(iret(ista) /= 0) THEN jsrc=isrcret(iret(ista)) DO klev=1,nlevret(ista) DO ivar=1,nvar-1 IF(qualret(ivar,klev,ista) > 0) THEN obsknt(ivar)=obsknt(ivar)+1. IF(ABS(odifret(ivar,klev,ista)) > qcthrret(ivar,jsrc) ) THEN WRITE(6,'(a,a,a,i5,a,i4)') ' Discarding retrieval ', & nam_var(ivar),' at col ',ista,' klev =',klev WRITE(6,'(a,f8.0,a,f16.6,a,f16.6,a,f16.6)') & ' Hgt= ',hgtretc(klev,ista), & ' Ob= ',obsret(ivar,klev,ista), & ' Diff= ',odifret(ivar,klev,ista), & ' Thresh=',qcthrret(ivar,jsrc) qualret(ivar,klev,ista)=-199 rejknt(ivar)=rejknt(ivar)+1. END IF END IF END DO IF(qualret(5,klev,ista) > 0) THEN obsknt(5)=obsknt(5)+1. tk=oanxret(4,klev,ista)* & ((oanxret(3,klev,ista)/p0)**rddcp) qvsat=f_qvsat(oanxret(3,klev,ista),tk) qcthrqv=qcthrret(5,jsrc)*qvsat IF(ABS(odifret(5,klev,ista)) > qcthrqv) THEN WRITE(6,'(a,a,a,i5,a,i4)') ' Discarding retrieval ', & nam_var(5),' at col ',ista,' klev =',klev WRITE(6,'(a,f8.0,a,f16.6,a,f16.6,a,f16.6)') & ' Hgt= ',hgtretc(klev,ista), & ' Ob= ',obsret(5,klev,ista), & ' Diff= ',odifret(5,klev,ista), & ' Thresh=',qcthrqv qualret(5,klev,ista)=-199 rejknt(5)=rejknt(5)+1. END IF END IF ! !----------------------------------------------------------------------- ! ! Synchronize wind component flags ! !----------------------------------------------------------------------- ! IF(qualret(1,klev,ista) == -199) qualret(2,klev,ista)=-199 IF(qualret(2,klev,ista) == -199) qualret(1,klev,ista)=-199 END DO END IF END DO ! !----------------------------------------------------------------------- ! ! Write statistics ! !----------------------------------------------------------------------- ! WRITE(6,'(//a/a)') ' QC Statistics for retrieval data', & ' Variable Obs Rejected Percent' DO ivar=1,nvar pctrej=0. IF(obsknt(ivar) > 0.) pctrej=100.*rejknt(ivar)/obsknt(ivar) WRITE(6,'(2x,a,i10,i10,f8.1)') & nam_var(ivar),nint(obsknt(ivar)),nint(rejknt(ivar)),pctrej END DO WRITE(6,'(/a)') ' ' RETURN END SUBROUTINE qcdiff