!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE UNFNQC ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE UNFNQC(maxgate,maxazim, ngate,nazim, &,3
lvlprof,zsnd,usnd,vsnd, &
gsp_vel,rfrst_vel, &
rlat_ptr,rlon_ptr,ralt_ptr, &
rvel,spw,elev,azim,vnyq, &
unfvel,tmp1,tmp2)
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Unfold and Quality Control Doppler radial velocities.
!
! AUTHOR:
! Keith Brewster, Center for Analysis and Prediction of Storms
!
! MODIFICATION HISTORY:
! Nov. 2000, First Version
! Oct. 2001, Updated and added spectrum width and std dev thresholding
!
!
!-----------------------------------------------------------------------
!
! INPUT :
!
! maxgate Maximum number of gates in a radial
! maxazim Maximum number of radials in a tilt
! ngate Number of gates in radial
! nazim Number of radials
! rvel Doppler radial velocity
! spw Doppler spectrum width
! elev Elevation angle
! azim Azimuth
! vnyq Nyquist velocity
! unfvel Unfolded Doppler radial velocity
!
! WORK ARRAYS:
!
! tmp1
! tmp2
!
!-----------------------------------------------------------------------
!
! Variable Declarations.
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
!
INTEGER, INTENT(IN) :: maxgate
INTEGER, INTENT(IN) :: maxazim
INTEGER, INTENT(IN) :: ngate
INTEGER, INTENT(IN) :: nazim
INTEGER, INTENT(IN) :: lvlprof
INTEGER, INTENT(IN) :: gsp_vel
INTEGER, INTENT(IN) :: rfrst_vel
REAL, INTENT(IN) :: rvel(maxgate,maxazim)
REAL, INTENT(IN) :: spw(maxgate,maxazim)
REAL, INTENT(IN) :: elev(maxazim)
REAL, INTENT(IN) :: azim(maxazim)
REAL, INTENT(IN) :: vnyq
REAL, INTENT(IN) :: rlat_ptr
REAL, INTENT(IN) :: rlon_ptr
REAL, INTENT(IN) :: ralt_ptr
REAL, INTENT(IN) :: zsnd(lvlprof)
REAL, INTENT(IN) :: usnd(lvlprof)
REAL, INTENT(IN) :: vsnd(lvlprof)
REAL, INTENT(OUT) :: unfvel(maxgate,maxazim)
REAL, INTENT(OUT) :: tmp1(maxgate,maxazim)
REAL, INTENT(OUT) :: tmp2(maxgate,maxazim)
INTEGER :: iray,kray
INTEGER :: bgate,igate,kgate,kkgate,bkgate,ekgate,lgate,kgate1,kgate2
INTEGER :: egate,k,kclose
INTEGER :: kntall,kntgood,kntfold,kntrej
INTEGER :: istatwrt,rem_points,found
REAL :: bknt,fknt,tknt,tpoint
REAL :: velok,twonyq,inv2nyq,thrpri
REAL :: sum,sum2,vavg,sdev,thresh,tstdev,tstvel,sum1,vavg1
REAL :: rlen,valid_vel,height,diff,refvel
!
!-----------------------------------------------------------------------
!
! Constants
!
!-----------------------------------------------------------------------
!
REAL :: rvchek = -90.
REAL :: spwflag = -931.
CHARACTER (LEN=6) :: varid
CHARACTER (LEN=20):: varname
CHARACTER (LEN=20):: varunits = 'm/s'
!
!-----------------------------------------------------------------------
!
! Include files:
!
!-----------------------------------------------------------------------
INCLUDE 'globcst.inc'
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
kntall=0
kntgood=0
kntfold=0
kntrej=0
velok = -(vnyq+1.0E-05)
twonyq = 2.0*vnyq
inv2nyq = 1./twonyq
thrpri = min(max((0.5*vnyq),10.),vnyq)
!
!-----------------------------------------------------------------------
!
! Apply Spectrum width thresholding
!
!-----------------------------------------------------------------------
!
CALL SPWTHR
(maxgate,maxazim, &
ngate,nazim,rvchek,spwflag,vnyq,rvel,spw)
!
!-----------------------------------------------------------------------
!
! Set up tmp1 and tmp2 to be quality arrays. 1=good 0=bad/missing
!
!-----------------------------------------------------------------------
!
tmp1=0.
tmp2=0.
DO iray=1,nazim
DO igate=1,ngate
unfvel(igate,iray)=rvel(igate,iray)
IF( rvel(igate,iray) > velok) THEN
tmp1(igate,iray)=1.
tmp2(igate,iray)=1.
END IF
END DO
END DO
!
!-----------------------------------------------------------------------
!
! Apply gate-to-gate shear checking for velocity folding.
! Follows Eilts and Smith, 1989, JTech, 118.
!
!-----------------------------------------------------------------------
!
DO iray=1,nazim
bgate=ngate
DO igate=1,ngate-1
IF( tmp1(igate,iray) > 0.) THEN
bgate=igate
EXIT
END IF
END DO
IF( bgate < ngate ) THEN
! DO igate=bgate+1,ngate
DO igate=bgate,ngate
IF( tmp1(igate,iray) > 0. ) THEN
kntall=kntall+1
lgate = 0
ekgate = max(1,igate-5)
bkgate = max(1,igate-1)
DO kgate = igate-1,ekgate,-1
IF(tmp2(kgate,iray) >0. ) THEN
lgate = kgate
EXIT
ENDIF
ENDDO
IF(lgate >0) THEN
refvel = unfvel(lgate,iray)
ELSE
refvel = 999.
ENDIF
IF( abs(rvel(igate,iray) - refvel) > thrpri) THEN
sum=0.
sum2=0.
fknt=0.
bknt=0.
bkgate=max((igate-10),bgate)
DO kgate=igate-1,bkgate,-1
bknt=bknt+tmp2(kgate,iray)
sum=sum+tmp2(kgate,iray)*unfvel(kgate,iray)
sum2=sum2+tmp2(kgate,iray)*(unfvel(kgate,iray)*unfvel(kgate,iray))
IF (bknt > 3. ) EXIT
END DO
IF( iray > 1 ) THEN
kray=iray-1
ekgate=min((igate+10),ngate)
DO kgate=igate,ekgate
fknt=fknt+tmp2(kgate,kray)
sum=sum+tmp2(kgate,kray)*unfvel(kgate,kray)
sum2=sum2+tmp2(kgate,kray)*(unfvel(kgate,kray)*unfvel(kgate,kray))
IF ( fknt > 4. ) EXIT
END DO
IF( fknt < 5. .AND. kray > 1 ) THEN
kray=kray-1
DO kgate=igate,ekgate
fknt=fknt+tmp2(kgate,kray)
sum=sum+tmp2(kgate,kray)*unfvel(kgate,kray)
sum2=sum2+tmp2(kgate,kray)*(unfvel(kgate,kray)*unfvel(kgate,kray))
IF ( fknt > 4. ) EXIT
END DO
END IF
END IF
tknt=bknt+fknt
IF(tknt > 0. ) THEN
vavg=sum/tknt
thresh=max((0.4*abs(vavg)),thrpri)
IF ( tknt > 2. ) THEN
sdev=sqrt((sum2-(sum*sum/tknt))/(tknt-1.))
thresh=max((2.0*sdev),thresh)
END IF
IF( abs(rvel(igate,iray)-vavg) < thresh ) THEN
kntgood=kntgood+1
ELSE
tstdev=twonyq*NINT((vavg-rvel(igate,iray))*inv2nyq)
tstvel=rvel(igate,iray)+tstdev
IF( abs(tstvel-vavg) < thresh ) THEN
IF(abs(tstdev) > 0.) THEN
kntfold=kntfold+1
! write(6,'(a,f10.1,a,f10.1,a,f10.1)') &
! ' Unfold: Meas=',rvel(igate,iray),' Avgvel=', &
! vavg,' New=',tstvel
unfvel(igate,iray)=tstvel
ELSE
kntgood=kntgood+1
END IF
ELSE
kntrej=kntrej+1
! write(8,'(a,i5,a,i5,a,f10.1,a,f10.1,a,f10.1,a,f10.1)') &
! 'igate=',igate,'iray=',iray, &
! ' Reject: Meas=',rvel(igate,iray),' Avgvel=', &
! vavg,' Try=',tstvel,'vnyq=',vnyq
unfvel(igate,iray)=-777.
tmp2(igate,iray)=0.
ENDIF ! tstvel-vavg >thresh
END IF ! rvel-vavg >thresh
ELSE ! tknt =0.
!
!-----------------------------------------------------------------------
!
! If no points are found to comparison,use environmental wind as a reference
!
!-----------------------------------------------------------------------
!
IF(initopt == 2 .or. initopt ==3)THEN !no valid vel,use snd
rlen = rfrst_vel + (igate-1)*gsp_vel
height = rlen*sin(elev(iray)*3.1415926/180.)
diff = 500.0
DO k=1,lvlprof
IF( abs(zsnd(k)-height)<diff ) THEN
diff = abs(zsnd(k)-height)
kclose = k
ENDIF
ENDDO
CALL uv2vr
(rlen,elev(iray),azim(iray), &
rlat_ptr,rlon_ptr,ralt_ptr, &
usnd(kclose),vsnd(kclose),valid_vel)
! IF(abs(rvel(igate,iray)-valid_vel) < 1.5*thrpri) THEN
IF(abs(rvel(igate,iray)-valid_vel) < thrpri) THEN
kntgood = kntgood+1
ELSE
IF(valid_vel*rvel(igate,iray)<0)THEN
tstdev=twonyq*NINT(valid_vel/abs(valid_vel))
ELSE
tstdev=twonyq*NINT((valid_vel-rvel(igate,iray))*inv2nyq)
ENDIF
tstvel=rvel(igate,iray)+tstdev
! IF( abs(tstvel-valid_vel) < 1.5*thrpri ) THEN
IF( abs(tstvel-valid_vel) < 3.0*thrpri ) THEN
IF(abs(tstdev) > 0.) THEN
kntfold=kntfold+1
ELSE
kntgood = kntgood+1
END IF
unfvel(igate,iray)=tstvel
tmp2(igate,iray) = 1.
ELSE
kntrej=kntrej+1
unfvel(igate,iray)=-777.
tmp2(igate,iray)=0.
ENDIF !tstvel-valid_vel
ENDIF !rval-valid_vel<1.5
ELSE
kntrej=kntrej+1
unfvel(igate,iray)=-777.
tmp2(igate,iray)=0.
ENDIF !initopt=1 analytical
ENDIF ! tknt >0.
ELSE
kntgood=kntgood+1
END IF !(rvel(igate,iray) - refvel) > thrpri
END IF ! tmp1(igate,iray) > 0.
END DO
END IF ! bgate < ngate
END DO
!
!-----------------------------------------------------------------------
!
! Second pass to deal with those failed points which have been removed
! during 1st pass. Use average of 15 points in 3 radials
!
!-----------------------------------------------------------------------
!
DO igate = 2,ngate
DO iray = 2,nazim-1
IF(unfvel(igate,iray) == -777. .AND. tmp2(igate,iray) == 0.) THEN
sum=0.
tpoint=0.
sum2=0.
bkgate=max((igate-10),1)
ekgate=min((igate+10),ngate)
DO kray = iray-1,iray+1
fknt = 0.
tknt=0.
DO kgate=igate,ekgate
tknt=tknt+tmp2(kgate,kray)
sum=sum+tmp2(kgate,kray)*unfvel(kgate,kray)
sum2=sum2+tmp2(kgate,kray)*unfvel(kgate,kray)*unfvel(kgate,kray)
IF(tknt > 3.) EXIT
ENDDO
DO kgate=igate-1,bkgate,-1
fknt=fknt+tmp2(kgate,kray)
sum=sum+tmp2(kgate,kray)*unfvel(kgate,kray)
sum2=sum2+tmp2(kgate,kray)*unfvel(kgate,kray)*unfvel(kgate,kray)
IF(fknt > 2.) EXIT
ENDDO
tpoint = tpoint + tknt + fknt
ENDDO
IF(tpoint > 0.) THEN
vavg = sum/tpoint
thresh=max((0.4*abs(vavg)),thrpri)
IF ( tpoint > 2. ) THEN
sdev=sqrt((sum2-(sum*sum/tpoint))/(tpoint-1.))
thresh=max((2.0*sdev),thresh)
END IF
IF( abs(rvel(igate,iray)-vavg) < thresh ) THEN
kntgood=kntgood+1
unfvel(igate,iray)=rvel(igate,iray)
tmp2(igate,iray)=1.
ELSE
tstdev=twonyq*NINT((vavg-rvel(igate,iray))*inv2nyq)
tstvel=rvel(igate,iray)+tstdev
IF( abs(tstvel-vavg) < thresh ) THEN
IF(abs(tstdev) > 0.) THEN
kntfold=kntfold+1
unfvel(igate,iray)=tstvel
tmp2(igate,iray)=1.
ELSE
kntgood=kntgood+1
unfvel(igate,iray)=rvel(igate,iray)
tmp2(igate,iray)=1.
ENDIF
ENDIF
ENDIF
ELSE !no valid vel,use snd
!-----------------------------------------------------------------------
!
! If no points are found to comparison,use environmental wind as a reference
!
!-----------------------------------------------------------------------
!
IF(initopt ==2 .or. initopt ==3)THEN
rlen = rfrst_vel + (igate-1)*gsp_vel
height = rlen*sin(elev(iray)*3.1415926/180.)
diff = 500.0
DO k=1,lvlprof
IF( abs(zsnd(k)-height)<diff ) THEN
diff = abs(zsnd(k)-height)
kclose = k
ENDIF
ENDDO
CALL uv2vr
(rlen,elev(iray),azim(iray), &
rlat_ptr,rlon_ptr,ralt_ptr, &
usnd(kclose),vsnd(kclose),valid_vel)
! IF(abs(rvel(igate,iray)-valid_vel) < 1.5*thrpri) THEN
IF(abs(rvel(igate,iray)-valid_vel) < thrpri) THEN
kntgood = kntgood+1
ELSE
IF(valid_vel*rvel(igate,iray)<0)THEN
tstdev=twonyq*NINT(valid_vel/abs(valid_vel))
ELSE
tstdev=twonyq*NINT((valid_vel-rvel(igate,iray))*inv2nyq)
ENDIF
tstvel=rvel(igate,iray)+tstdev
! IF( abs(tstvel-valid_vel) < 1.5*thrpri ) THEN
IF( abs(tstvel-valid_vel) < 3*thrpri ) THEN
IF(abs(tstdev) > 0.) THEN
kntfold=kntfold+1
ELSE
kntgood = kntgood+1
END IF
unfvel(igate,iray)=tstvel
tmp2(igate,iray) = 1.
ELSE
kntrej=kntrej+1
unfvel(igate,iray)=-777.
tmp2(igate,iray)=0.
ENDIF !tstvel-valid_vel
ENDIF !rval-valid_vel<1.5
ELSE
kntrej=kntrej+1
unfvel(igate,iray)=-777.
tmp2(igate,iray)=0.
ENDIF ! initopt = 1
ENDIF ! tknt >0.
ENDIF ! -777.0
ENDDO
ENDDO
write(6,'(a/,4i12)') &
' Gates Good-Gates Folded Rejected', &
kntall,kntgood,kntfold,kntrej
RETURN
END SUBROUTINE unfnqc
!
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE DESPEKL ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE DESPEKL(maxgate,maxazim, & 3
ngate,nazim,varchek,rdata,tmp)
!
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Despeckle radar data.
! Can be used for reflectivity or velocity.
!
!
! AUTHOR: Keith Brewster
!
! MODIFICATION HISTORY:
!
!
!-----------------------------------------------------------------------
!
! INPUT:
! maxgate Maximum number of gates in a radial
! maxazim Maximum number of radials in a tilt
! ngate Number of gates in radial
! nazim Number of radials
! varchek Threshold to determine good data vs. flagged
! rdata Doppler radial velocity
!
! OUTPUT:
! rdata
!
! WORK ARRAYS:
!
! tmp
!
!-----------------------------------------------------------------------
!
! Variable Declarations.
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
INTEGER, INTENT(IN) :: maxgate
INTEGER, INTENT(IN) :: maxazim
INTEGER, INTENT(IN) :: ngate
INTEGER, INTENT(IN) :: nazim
REAL, INTENT(IN) :: varchek
REAL, INTENT(INOUT) :: rdata(maxgate,maxazim)
REAL, INTENT(OUT) :: tmp(maxgate,maxazim)
!
!-----------------------------------------------------------------------
!
! Misc. local variables
!
!-----------------------------------------------------------------------
!
INTEGER :: i,j
INTEGER :: kntgd,kntdsp
!
REAL :: sum,pctdsp
REAL, PARAMETER :: dspmiss = -991.
!
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!
!-----------------------------------------------------------------------
!
! Create temporary array where tmp=1 if non-missing tmp=0 if missing
!
!-----------------------------------------------------------------------
!
!
tmp=0.
DO j=1,nazim
DO i=1,ngate
IF ( rdata(i,j) > varchek ) tmp(i,j)=1.
END DO
END DO
!
!-----------------------------------------------------------------------
!
! If datum has fewer than 3 non-missing neighbors in a 3x3
! square template set it to missing
!
!-----------------------------------------------------------------------
!
kntgd=0
kntdsp=0
DO j=2,nazim-1
DO i=2,ngate-1
IF(rdata(i,j) > varchek ) THEN
kntgd=kntgd+1
sum=tmp(i-1,j+1)+tmp(i,j+1)+tmp(i+1,j+1) &
+tmp(i-1,j )+ tmp(i+1,j) &
+tmp(i-1,j-1)+tmp(i,j-1)+tmp(i+1,j-1)
IF( sum < 3. ) THEN
kntdsp=kntdsp+1
rdata(i,j) = dspmiss
END IF
END IF
END DO
END DO
IF(kntgd > 0 ) THEN
pctdsp=100.*(float(kntdsp)/float(kntgd))
ELSE
pctdsp=0.
END IF
write(6,'(a,i8,a,i8,a,f6.1,a)') &
' Despeckled ',kntdsp,' of ',kntgd,' data =',pctdsp,' percent.'
!
RETURN
!
END SUBROUTINE despekl
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE SPWTHR ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE SPWTHR(maxgate,maxazim, & 1
ngate,nazim,rvchek,spwflag,vnyq,rvel,spw)
!
!-----------------------------------------------------------------------
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Threshold radial velocity data based on spectrum width.
!
!-----------------------------------------------------------------------
!
! AUTHOR: Keith Brewster
!
! MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
! INPUT :
!
! maxgate Maximum number of gates in a radial
! maxazim Maximum number of radials in a tilt
! ngate Number of gates in radial
! nazim Number of radials
! rvchek Threshold for good data vs. flagged
! spwflag Flag for spectrum width threshold fail
! vnyq Nyquist velocity
! rvel Doppler radial velocity
! spw Doppler spectrum width
!
! OUTPUT:
! rvel Doppler radial velocity
!
!
! WORK ARRAYS:
!
!
!-----------------------------------------------------------------------
!
! Variable Declarations.
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
!
INTEGER, INTENT(IN) :: maxgate
INTEGER, INTENT(IN) :: maxazim
INTEGER, INTENT(IN) :: ngate
INTEGER, INTENT(IN) :: nazim
REAL, INTENT(IN) :: rvchek
REAL, INTENT(IN) :: spwflag
REAL, INTENT(IN) :: vnyq
REAL, INTENT(INOUT) :: rvel(maxgate,maxazim)
REAL, INTENT(IN) :: spw(maxgate,maxazim)
!
!-----------------------------------------------------------------------
!
! Misc. local variables:
!
!-----------------------------------------------------------------------
!
REAL :: spthrat = 0.67
REAL :: spthr
INTEGER :: i,j
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!
!-----------------------------------------------------------------------
!
! If spectrum width is greater than threshold, set to missing
!
!-----------------------------------------------------------------------
!
spthr=spthrat*vnyq
DO j=1,nazim
DO i=1,ngate
IF(rvel(i,j) > rvchek .AND. spw(i,j) > spthr ) rvel(i,j) = spwflag
END DO
END DO
!
RETURN
!
END SUBROUTINE spwthr