PROGRAM rademul,146
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Reads an ARPS history file and creates data emulating that observed
! by a radar. Output is in polar (az-ran) coordinates.
!
! The initial version uses the "nearest neighbor" in the horizontal and
! linear vertical interpolation without Gaussian beam smoothing, a
! feature to be added later.
!
! Output are NetCDF files which are readable by the NSSL WDSS-II system.
!
! Radar parameters (tilt angles, beamwidth, etc) are set in the input file.
!
! AUTHOR:
! Keith Brewster, Center for Analysis and Prediction of Storms
! 02/10/2004
!
! MODIFICATIONS
! 10/30/2004 Version with beam-weight filtering. KB, CAPS
!
! 11/15/2004 Added processing for effective horizontal beam width as a
! function of rotation rate, PRT and number of samples.
! Also added an option for X-band attenuation.
! Keith Brewster, CAPS
!
! 12/05/2004 Added Gaussian random noise for velocity and reflectivity
! Sometime this could be updated to parameterize the noise
! Gaussian width as a function of SNR.
! Keith Brewster, CAPS
!
! 02/06/2005 Added processing for reading individual variables from
! ARPS hdf history files in order to save memory when reading
! very large datasets.
!
! 03/18/2005 Added loop to process mulitple files (model output times)
! in a single run.
!
! 05/10/2005 Keith Brewster, CAPS
! Added vertical vorticity variable for
! verification of vortex detection algorithms.
!
! 05/24/2005 Keith Brewster, CAPS
! Added unattenuated variables and variable write flags.
! Added smoothing option for vorticity variable.
!
! 06/14/2005 Keith Brewster, CAPS
! Modified logic to compute weighted average of data re-
! interpolated to points in a regular 7x7x7 az-ran-elv array.
!
! 12/14/2005 Keith Brewster, CAPS
! Various updates to make computing on array more flexible, add
! dual-pulse mode, add forced consistency between PRT, number
! of samples, rotation rate and output radial spacing.
!
! 04/20/2006 Keith Brewster, CAPS
! Added beam blockage.
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
INCLUDE 'grid.inc'
INCLUDE 'globcst.inc'
INCLUDE 'phycst.inc'
INTEGER :: nx, ny, nz
INTEGER :: nzsoil
INTEGER :: nstyps
!
!-----------------------------------------------------------------------
!
! Arrays to be read in:
!
!-----------------------------------------------------------------------
!
REAL, ALLOCATABLE :: x(:) ! The x-coord. of the physical and
! computational grid.
REAL, ALLOCATABLE :: y(:) ! The y-coord. of the physical and
! computational grid.
REAL, ALLOCATABLE :: z(:) ! The z-coord. of the computational
! grid. Defined at w-point.
REAL, ALLOCATABLE :: zp(:,:,:) ! The height of the terrain.
REAL, ALLOCATABLE :: zpsoil(:,:,:) ! The height for soil model
REAL, ALLOCATABLE :: uprt (:,:,:) ! Perturbation u-velocity (m/s)
REAL, ALLOCATABLE :: vprt (:,:,:) ! Perturbation v-velocity (m/s)
REAL, ALLOCATABLE :: wprt (:,:,:) ! Perturbation w-velocity (m/s)
REAL, ALLOCATABLE :: ptprt (:,:,:) ! Perturbation potential temperature (K)
REAL, ALLOCATABLE :: pprt (:,:,:) ! Perturbation pressure (Pascal)
REAL, ALLOCATABLE :: qvprt (:,:,:) ! Perturbation water vapor specific
! humidity (kg/kg)
REAL, ALLOCATABLE :: qc (:,:,:) ! Cloud water mixing ratio (kg/kg)
REAL, ALLOCATABLE :: qr (:,:,:) ! Rain water mixing ratio (kg/kg)
REAL, ALLOCATABLE :: qi (:,:,:) ! Cloud ice mixing ratio (kg/kg)
REAL, ALLOCATABLE :: qs (:,:,:) ! Snow mixing ratio (kg/kg)
REAL, ALLOCATABLE :: qh (:,:,:) ! Hail mixing ratio (kg/kg)
REAL, ALLOCATABLE :: ubar (:,:,:) ! Base state u-velocity (m/s)
REAL, ALLOCATABLE :: vbar (:,:,:) ! Base state v-velocity (m/s)
REAL, ALLOCATABLE :: wbar (:,:,:) ! Base state w-velocity (m/s)
REAL, ALLOCATABLE :: ptbar (:,:,:) ! Base state potential temperature (K)
REAL, ALLOCATABLE :: pbar (:,:,:) ! Base state pressure (Pascal)
REAL, ALLOCATABLE :: rhobar (:,:,:) ! Base state air density (kg/m**3)
REAL, ALLOCATABLE :: qvbar (:,:,:) ! Base state water vapor specific
! humidity (kg/kg)
INTEGER, ALLOCATABLE :: soiltyp (:,:,:) ! Soil type
REAL, ALLOCATABLE :: stypfrct(:,:,:) ! Fraction of soil types
INTEGER, ALLOCATABLE :: vegtyp(:,:) ! Vegetation type
REAL, ALLOCATABLE :: tsoil (:,:,:,:) ! Deep soil temperature (K)
REAL, ALLOCATABLE :: qsoil (:,:,:,:) ! Deep soil temperature (K)
REAL, ALLOCATABLE :: wetcanp(:,:,:) ! Canopy water amount
REAL, ALLOCATABLE ::prcrate(:,:,:) ! precipitation rate (kg/(m**2*s))
! prcrate(1,1,1) = total precip. rate
! prcrate(1,1,2) = grid scale precip. rate
! prcrate(1,1,3) = cumulus precip. rate
! prcrate(1,1,4) = microphysics precip. rate
REAL, ALLOCATABLE ::tem2d(:,:) ! 2D work array
REAL, ALLOCATABLE ::tem1(:,:,:) ! Work arrays
REAL, ALLOCATABLE ::tem2(:,:,:) ! Work arrays
REAL, ALLOCATABLE ::tem3(:,:,:) ! Work arrays
REAL, ALLOCATABLE ::tem4(:,:,:) ! Work arrays
INTEGER (KIND=selected_int_kind(4)), ALLOCATABLE :: itmp(:,:,:) ! Temporary array
REAL, ALLOCATABLE :: hmax(:)
REAL, ALLOCATABLE :: hmin(:)
REAL, ALLOCATABLE :: xsc(:)
REAL, ALLOCATABLE :: ysc(:)
REAL, ALLOCATABLE :: latsc(:,:)
REAL, ALLOCATABLE :: lonsc(:,:)
REAL, ALLOCATABLE :: azmsc(:,:)
REAL, ALLOCATABLE :: sfcr(:,:)
REAL, ALLOCATABLE :: cmpref(:,:)
REAL, ALLOCATABLE :: usc(:,:,:)
REAL, ALLOCATABLE :: vsc(:,:,:)
REAL, ALLOCATABLE :: usm(:,:,:)
REAL, ALLOCATABLE :: vsm(:,:,:)
REAL, ALLOCATABLE :: wsc(:,:,:)
REAL, ALLOCATABLE :: zps(:,:,:)
REAL, ALLOCATABLE :: ref(:,:,:)
REAL, ALLOCATABLE :: refz(:,:,:)
REAL, ALLOCATABLE :: elvsc(:,:,:)
REAL, ALLOCATABLE :: rngsc(:,:,:)
REAL, ALLOCATABLE :: vort(:,:,:)
REAL, ALLOCATABLE :: vrsc(:,:,:)
!
!-----------------------------------------------------------------------
!
! NEXRAD Radar variables
!
!-----------------------------------------------------------------------
!
INTEGER, PARAMETER :: maxtilt=14
REAL :: ang11(maxtilt),ang12(maxtilt)
REAL :: ang31(maxtilt),ang32(maxtilt)
DATA ang11 / 0.5,1.5,2.4,3.4,4.3,5.3,6.2,7.5,8.7, &
10.0,12.0,14.0,16.7,19.5/
DATA ang12 / 0.5,1.5,2.4,3.4,4.3,6.0,9.9,14.6,19.5, &
19.5,19.5,19.5,19.5,19.5/
DATA ang31 / 0.5,1.5,2.5,3.5,4.5,4.5,4.5,4.5,4.5, &
4.5, 4.5, 4.5, 4.5, 4.5/
DATA ang32 / 0.5,1.5,2.5,3.5,4.5,4.5,4.5,4.5,4.5, &
4.5, 4.5, 4.5, 4.5, 4.5/
!
!-----------------------------------------------------------------------
!
! Grid adjustment variables -- adjustments to model grid specifications
!
!-----------------------------------------------------------------------
!
INTEGER :: adjhgt,adjctr,adjmove
REAL :: ctrlatem,ctrlonem
REAL :: umovein,vmovein
REAL :: hgtoffset
NAMELIST /grid_adj/ adjhgt,adjctr,adjmove,ctrlatem,ctrlonem, &
umovein,vmovein,hgtoffset
!
!-----------------------------------------------------------------------
!
! I/O Options
!
!-----------------------------------------------------------------------
!
INTEGER :: ifmt,creidx,ipktyp,nbits,nsmvort
INTEGER :: wrtuaref,wrtuavel,wrtvort
CHARACTER (LEN=80) :: outdir
NAMELIST /output_opts/ ifmt,creidx,ipktyp,nbits,outdir, &
nsmvort,wrtuaref,wrtuavel,wrtvort
!-----------------------------------------------------------------------
!
! Radar variables
!
!-----------------------------------------------------------------------
!
CHARACTER (LEN=4) :: radname
INTEGER :: locopt
REAL :: xrad,yrad,radlat,radlon,radelv
REAL :: wavelen,beamwid
REAL :: pwrxmt,gaindb,lossdb,noisedbm
NAMELIST /radar_specs/ radname,locopt, &
xrad,yrad,radlat,radlon,radelv,wavelen,beamwid, &
pwrxmt,gaindb,lossdb,noisedbm
!
!-----------------------------------------------------------------------
!
! Radar Operation Mode Variables
!
!-----------------------------------------------------------------------
!
INTEGER, PARAMETER :: maxelv=30
INTEGER :: nelev,vcp,ngate
INTEGER :: unifpuls,dualprf,pulseopt,rotropt,rotdir
REAL :: gatesp,rotrate,delaz,azim1,azim2
REAL :: elev(maxelv)
REAL :: pulselen1(maxelv),pulselen2(maxelv)
REAL :: pulsewid1(maxelv),pulsewid2(maxelv)
REAL :: prt1(maxelv),prt2(maxelv)
INTEGER :: npulse1(maxelv),npulse2(maxelv)
NAMELIST /radar_opmode/ nelev,vcp,elev,ngate,gatesp, &
rotdir,rotropt,rotrate,delaz,azim1,azim2, &
unifpuls,dualprf,pulseopt, &
pulselen1,pulselen2,pulsewid1,pulsewid2, &
prt1,prt2,npulse1,npulse2
!
!-----------------------------------------------------------------------
!
! Radar emulator options
!
!-----------------------------------------------------------------------
!
REAL, PARAMETER :: refchk = -99.
REAL, PARAMETER :: refmax = 80.
INTEGER :: nptsazm,nptselv,nptsrng
REAL :: evalwid,refmin,rngmin
REAL :: rmisval,rngfval
REAL :: hblkmin,hblkmax,gndrefl
INTEGER :: int_method,blockopt,kntrmin,kntvmin
INTEGER :: attenopt,senstvopt
INTEGER :: rferropt,vrerropt,nyqstopt
INTEGER :: tmadvopt
REAL :: sigmarf,sigmavr
REAL :: samploi,stdvrmul
REAL :: vnyquist(maxelv)
REAL :: timeincr
NAMELIST /emul_specs/ int_method,nptsazm,nptselv,nptsrng, &
evalwid,refmin,rngmin,kntrmin,kntvmin, &
blockopt,hblkmin,hblkmax,gndrefl, &
tmadvopt,attenopt,senstvopt, &
rferropt,sigmarf,vrerropt,sigmavr,samploi,stdvrmul, &
timeincr,rmisval,rngfval,nyqstopt,vnyquist
!-----------------------------------------------------------------------
!
! Radar tilt variables
!
!-----------------------------------------------------------------------
!
INTEGER :: maxazim
INTEGER :: itilt,jazim,igate,iigate
INTEGER :: iloc,jloc,iloc1,jloc1,ilc,jlc
REAL :: deg2rad,rad2deg
REAL :: irloc,jrloc
REAL :: elvang(maxelv)
REAL, ALLOCATABLE :: azim(:)
REAL, ALLOCATABLE :: beamw(:)
REAL, ALLOCATABLE :: gtspc(:)
REAL, ALLOCATABLE :: vnyq(:)
REAL, ALLOCATABLE :: radv(:,:)
REAL, ALLOCATABLE :: attradv(:,:)
REAL, ALLOCATABLE :: refl(:,:)
REAL, ALLOCATABLE :: attrefl(:,:)
REAL, ALLOCATABLE :: stdvr(:,:)
REAL, ALLOCATABLE :: vvort(:,:)
REAL, ALLOCATABLE :: sens(:)
!
!-----------------------------------------------------------------------
!
! Radar volume variables
!
!-----------------------------------------------------------------------
!
INTEGER, ALLOCATABLE :: itimvol(:)
REAL, ALLOCATABLE :: vnyqvol(:)
REAL, ALLOCATABLE :: rngvol(:,:)
REAL, ALLOCATABLE :: azmvol(:,:)
REAL, ALLOCATABLE :: elvvol(:,:)
REAL, ALLOCATABLE :: refvol(:,:,:)
REAL, ALLOCATABLE :: uarefvol(:,:,:)
REAL, ALLOCATABLE :: velvol(:,:,:)
REAL, ALLOCATABLE :: uavelvol(:,:,:)
REAL, ALLOCATABLE :: vorvol(:,:,:)
!
!-----------------------------------------------------------------------
!
! Misc. internal variables
!
!-----------------------------------------------------------------------
!
REAL :: alatnot(2)
REAL, PARAMETER :: c = 2.9979e08 ! speed of light m/s
REAL, ALLOCATABLE :: delrng(:)
REAL, ALLOCATABLE :: delazm(:)
REAL, ALLOCATABLE :: delelv(:)
REAL, ALLOCATABLE :: wgtpt(:,:,:)
REAL, ALLOCATABLE :: blockfct(:,:)
INTEGER, PARAMETER :: nhisfile_max=1000
CHARACTER (LEN=256) :: fname
CHARACTER (LEN=256) :: fnamevol
CHARACTER (LEN=256) :: idxfname
CHARACTER (LEN=256) :: grdbasfn
CHARACTER (LEN=256) :: hisfile(nhisfile_max)
CHARACTER (LEN=80) :: vcptxt
CHARACTER (LEN=40) :: varname
CHARACTER (LEN=5) :: cmprext
INTEGER, PARAMETER :: itim1970=315619200
INTEGER :: hinfmt,nchin,nhisfile,idxunit,istatus
INTEGER :: lengbf,lenfil,itime,itimcdf,npulsmn
INTEGER :: itimtilt,iyear,imon,iday,ihour,imin,isec
INTEGER :: ifile,initime,ifsecs,ireturn
INTEGER :: i,j,k,ibgn,iend,jbgn,jend,ipt,jpt,kpt,iptmid
INTEGER :: ipmid,jpmid,kpmid,nzm2
INTEGER :: ntilt,nazim,ielv,felv,ifold,irot,ismth
INTEGER :: iradius,jradius,kntr,kntv
INTEGER :: kntgate,kntintr,kntintv,kntfewr,kntfewv
INTEGER :: kntavgr,kntavgv
INTEGER :: kntclr,knthob,kntvob,kntbob
REAL :: twdx2inv,twdxinv,twdy2inv,twdyinv
REAL :: dr,de,da,p0inv,azmsect,azmbgn,denom,ttime
REAL :: time,time0,rfrgate,frtime,radlata,radlona,hlfgtsp
REAL :: elv,azimuth,azrad,srange,hgt,hgtmsl,sfcrng
REAL :: ctrx,ctry,xsw,ysw,gtlat,gtlon,gtx,gty,xpt,ypt
REAL :: delx,dely,xrat,yrat,dhdr,dsdr,twovnyq,twovninv
REAL :: ucmp,vcmp,urad,vrad,wrad,vt,vr,vvmin,vvmax
REAL :: xrada,yrada,ipos,jpos
REAL :: w1i,w2i,w1j,w2j,w11,w12,w21,w22
REAL :: r11h,r12h,r21h,r22h,rmax
REAL :: r11l,r12l,r21l,r22l
REAL :: delv,dazm,drng,depth,elradius
REAL :: whigh,wlow,a,b,fjp1,fj0,fjm1
REAL :: flow,fhigh,reflz,refdbz,reflzgnd
REAL :: pi,cinv,b6,hlftau,hlfctau,aconst,rngg
REAL :: efbmwid,bmwrad,bmwm,sradius,vnyqstl
REAL :: fourln4,sigr2,sr2inv,wesqinv,wasqinv
REAL :: wgtg,wgtr,wgtv,sumwr,sumwv,sumv,sumr
REAL :: sumv1,sumv2,flkntv,varvr
REAL :: wgti,wgtj,wgtk
REAL :: prtmn,pulsewmn,pulselmn
REAL :: rngwid,srgpt,azmpt,azmrpt,elvpt,sfcrpt,sfcrngt,sfcrngb
REAL :: elvtop,elvbot,trnpt,trngt,topgt,tophgt,topmsl,bothgt,botmsl
REAL :: hgtpt,hgtagl,xmit,dhblkinv,blkcst,gndatten
REAL :: reflmin,reflmax
LOGICAL :: echo
!
!-----------------------------------------------------------------------
!
! External Functions
!
!-----------------------------------------------------------------------
!
REAL :: randnor
REAL :: effbmw
REAL :: erf
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!
!-----------------------------------------------------------------------
!
! Initializations of constants and namelist variables
!
!-----------------------------------------------------------------------
!
itime=0
frtime=0.
time0=0.
pi=acos(-1.)
deg2rad=pi/180.
rad2deg=180./pi
cinv=1./c
p0inv=1./p0
radname='NULL'
locopt=2
xrad=0.
yrad=0.
radlat=0.
radlon=0.
radelv=0.
wavelen=10.5
beamwid=0.89
pwrxmt=475000.
gaindb=44.5
lossdb=5.
noisedbm=-113.
int_method=2
nptsazm=7
nptselv=7
nptsrng=7
evalwid=2.0
refmin=-20.
rngmin=100.
kntrmin=9
kntvmin=9
blockopt=2
hblkmin=1.0
hblkmax=10.0
gndrefl=50.0
tmadvopt=1
attenopt=0
senstvopt=0
rferropt=1
sigmarf=5.0
vrerropt=1
sigmavr=1.0
samploi=0.5
stdvrmul=1.5
timeincr=1.
rmisval=-99900.
rngfval=-99901.
nyqstopt=1
vnyquist=100.
nelev=1
vcp=0
elev=0.5
ngate=100
gatesp=1000.
rotdir=1
rotropt=1
rotrate=18.0
delaz=1.0
azim1=0.
azim2=360.
unifpuls=1
dualprf=0
pulseopt=1
pulselen1=1.57E-06
pulselen2=1.57E-06
pulsewid1=441.
pulsewid2=441.
prt1=1.06e-03
prt2=1.06e-03
npulse1=54
npulse2=54
ifmt=1
creidx=0
ipktyp=2
nbits=16
nsmvort=2
wrtuaref=0
wrtuavel=0
wrtvort =0
outdir='./'
adjhgt=0
adjctr=0
adjmove=0
ctrlatem=45.
ctrlonem=-90.
umovein=0.
vmovein=0.
hgtoffset=0.
irloc=45.
jrloc=45.
cmprext='.gz'
!
!-----------------------------------------------------------------------
!
! Get the names of the input data files.
!
!-----------------------------------------------------------------------
!
CALL get_input_file_names
(hinfmt,grdbasfn,hisfile,nhisfile)
WRITE(6,'(a,i4,a/)') ' Processing ',nhisfile,' model files.'
lengbf = len_trim(grdbasfn)
!
!-----------------------------------------------------------------------
!
! Read other input namelists
!
!-----------------------------------------------------------------------
!
WRITE(6,'(a)') ' Reading grid_adj namelist'
READ(5,grid_adj)
WRITE(6,'(a)') ' Reading output_opts namelist'
READ(5,output_opts)
WRITE(6,'(a)') ' Reading radar_specs namelist'
READ(5,radar_specs)
WRITE(6,'(a)') ' Reading radar_opmode namelist'
READ(5,radar_opmode)
WRITE(6,'(a)') ' Reading emul_specs namelist'
READ(5,emul_specs)
IF(vcp == 0) THEN
ntilt=nelev
write(vcptxt,'(a,i2,a,f4.1,a,f4.1,a)') &
'Custom vcp',ntilt,' tilts',elev(1),'-',elev(ntilt),' deg'
vcptxt='Custom vcp 14 tilts 0.5-19.5 deg'
DO itilt=1,ntilt
elvang(itilt)=elev(itilt)
END DO
ELSE IF(vcp == 11) THEN
ntilt=14
vcptxt='Storm mode 14 tilts 0.5-19.5 deg'
DO itilt=1,ntilt
elvang(itilt)=ang11(itilt)
END DO
ELSE IF (vcp == 12) THEN
ntilt=9
vcptxt='Storm mode 9 tilts 0.5-19.5 deg'
DO itilt=1,ntilt
elvang(itilt)=ang11(itilt)
END DO
ELSE IF (vcp == 31) THEN
ntilt=5
vcptxt='Clear-air 5 tilts 0.5- 4.5 deg'
DO itilt=1,ntilt
elvang(itilt)=ang11(itilt)
END DO
ELSE IF (vcp == 32) THEN
ntilt=5
vcptxt='Clear-air 5 tilts 0.5- 4.5 deg'
DO itilt=1,ntilt
elvang(itilt)=ang11(itilt)
END DO
ELSE
WRITE(6,*) vcp,' is not a recognized VCP number'
STOP
END IF
!
!-----------------------------------------------------------------------
!
! Print a warning about blocking/clutter using integration method 1.
!
!-----------------------------------------------------------------------
!
IF(int_method == 1 .AND. blockopt > 0) THEN
WRITE(6,'(//a,/a,i4,/a,i4,/a//)') &
' ***********WARNING*********************', &
' Terrain blocking calculation not possible using integration method ', &
int_method, ' Select integration method 2 with blockopt=',blockopt,&
'Continuing using integration method 2...'
int_method=2
END IF
!
!-----------------------------------------------------------------------
!
! Calculate constants for antenna gain weighting.
!
!-----------------------------------------------------------------------
!
kntvmin=max(kntvmin,2)
fourln4=4.0*alog(4.0)
wesqinv=fourln4/(beamwid*beamwid)
reflzgnd=10.**(gndrefl*0.10)
IF(azim2 > azim1) THEN
azmsect=azim2-azim1
ELSE
azmsect=(360.+azim2)-azim1
END IF
IF(unifpuls == 1) THEN
DO itilt=2,ntilt
prt1(itilt)=prt1(1)
prt2(itilt)=prt2(1)
npulse1(itilt)=npulse1(1)
npulse2(itilt)=npulse2(1)
pulselen1(itilt)=pulselen1(1)
pulselen2(itilt)=pulselen2(1)
pulsewid1(itilt)=pulsewid1(1)
pulsewid2(itilt)=pulsewid2(1)
END DO
END IF
IF(rotropt > 1) THEN
nazim=NINT(azmsect/delaz)+1
maxazim=max(nazim,1)
ELSE
maxazim=1
DO itilt=1,ntilt
IF(dualprf > 0) THEN
delaz=rotrate*((prt1(itilt)*npulse1(itilt))+ &
(prt2(itilt)*npulse2(itilt)))
ELSE
delaz=rotrate*prt1(itilt)*npulse1(itilt)
END IF
nazim=NINT(azmsect/delaz)+1
maxazim=max(nazim,maxazim)
END DO
END IF
WRITE(6,'(a,i6)') ' Maximum azimuths: ',maxazim
rfrgate=gatesp
hlfgtsp=0.5*gatesp
IF(blockopt == 0) THEN
hblkmin=0.
hblkmax=1.0
dhblkinv=1.0
ELSE
hblkmin=max(hblkmin,0.0)
hblkmax=max(hblkmax,(hblkmin+1.0))
dhblkinv=1./(hblkmax-hblkmin)
END IF
nptsrng=max(nptsrng,5)
ALLOCATE (delrng(nptsrng))
dr=gatesp/float(nptsrng-1)
WRITE(6,'(a,f10.2,a)') ' Range evaluation points (gatesp=',gatesp,'):'
DO ipt=1,nptsrng
delrng(ipt)=(-0.5*gatesp)+((ipt-1)*dr)
WRITE(6,'(a,i4,a,f12.4)') ' delrng(',ipt,') = ',delrng(ipt)
END DO
iptmid=(nptsrng/2)+1
blkcst=(0.001*gatesp)/float(nptsrng)
nptsazm=max(nptsazm,5)
ALLOCATE (delazm(nptsazm))
nptselv=max(nptselv,5)
ALLOCATE (delelv(nptselv))
elradius=evalwid*beamwid
de=elradius/float(nptselv-1)
WRITE(6,'(a,f10.2,a,f10.2)') &
' Beam width ',beamwid,' Eval region width:',(evalwid*beamwid)
WRITE(6,'(a)') &
' Vertical cross-beam evaluation pts (elev deg above center):'
DO kpt=1,nptselv
delelv(kpt)=(-0.5*evalwid*beamwid)+((kpt-1)*de)
WRITE(6,'(a,i4,a,f12.4)') ' delelv(',kpt,') = ',delelv(kpt)
END DO
ipmid=(nptsrng/2)+1
jpmid=(nptsazm/2)+1
kpmid=(nptselv/2)+1
ALLOCATE (wgtpt(nptsrng,nptsazm,nptselv))
ALLOCATE (blockfct(nptsazm,nptselv))
!
!-----------------------------------------------------------------------
!
! Obtain the grid dimensions from input data.
!
!-----------------------------------------------------------------------
!
CALL get_dims_from_data
(hinfmt,grdbasfn(1:lengbf), &
nx,ny,nz,nzsoil,nstyps,ireturn)
nstyp = nstyps ! Copy to global variable
IF( ireturn /= 0 ) THEN
PRINT*,'Problem occured when trying to get dimensions from data.'
PRINT*,'Program stopped.'
STOP
END IF
WRITE(6,'(3(a,i5))') 'nx =',nx,', ny=',ny,', nz=',nz,', nzsoil',nzsoil
nzm2=nz-2
!-----------------------------------------------------------------------
!
! Allocate grid position arrays.
!
!-----------------------------------------------------------------------
!
allocate(x(nx),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:x")
x=0.
allocate(y(ny),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:y")
y=0.
allocate(z(nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:z")
z=0.
allocate(zp(nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:zp")
zp=0.
DO ifile=1,nhisfile
WRITE(6,'(a,a)') ' Processing file: ',TRIM(hisfile(ifile))
IF( hinfmt .NE. 3) THEN
!-----------------------------------------------------------------------
!
! Allocate arrays needed for dtaread
! These are deallocated after being read and used so they need
! to be reallocated with each new file.
!
!-----------------------------------------------------------------------
!
allocate(zpsoil (nx,ny,nzsoil),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:zpsoil")
zpsoil=0.
allocate(uprt (nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:uprt")
uprt=0.
allocate(vprt (nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:vprt")
vprt=0.
allocate(wprt (nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:wprt")
wprt=0.
allocate(ptprt (nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:ptprt")
ptprt=0.
allocate(pprt (nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:pprt")
pprt=0.
allocate(qvprt (nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:qvprt")
qvprt=0.
allocate(ubar (nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:ubar")
ubar=0.
allocate(vbar (nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:vbar")
vbar=0.
allocate(wbar (nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:wbar")
wbar=0.
allocate(ptbar (nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:ptbar")
ptbar=0.
allocate(pbar (nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:pbar")
pbar=0.
allocate(rhobar (nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:rhobar")
rhobar=0.
allocate(qvbar (nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:qvbar")
qvbar=0.
allocate(qc (nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:qc")
qc=0.
allocate(qr (nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:qr")
qr=0.
allocate(qi (nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:qi")
qi=0.
allocate(qs (nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:qs")
qs=0.
allocate(qh (nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:qh")
qh=0.
allocate(soiltyp (nx,ny,nstyps),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:soiltyp")
soiltyp=0
allocate(stypfrct(nx,ny,nstyps),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:stypfrct")
stypfrct=0.
allocate(vegtyp(nx,ny),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:vegtyp")
vegtyp=0
allocate(tsoil (nx,ny,nzsoil,0:nstyps),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:tsoil")
tsoil=0.
allocate(qsoil (nx,ny,nzsoil,0:nstyps),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:qsoil")
qsoil=0.
allocate(wetcanp(nx,ny,0:nstyps),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:wetcanp")
wetcanp=0.
allocate(prcrate(nx,ny,4),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:prcrate")
prcrate=0.
allocate(tem2d(nx,ny),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:tem2d")
tem2d=0.
allocate(tem1(nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:tem1")
tem1=0.
allocate(tem2(nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:tem2")
tem2=0.
allocate(tem3(nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:tem3")
tem3=0.
allocate(tem4(nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:tem4")
tem4=0.
lenfil = len_trim(hisfile(ifile))
CALL dtaread
(nx,ny,nz,nzsoil,nstyps, &
hinfmt, nchin,grdbasfn(1:lengbf),lengbf, &
hisfile(ifile),lenfil,time, &
x,y,z,zp,zpsoil,uprt,vprt,wprt,ptprt,pprt, &
qvprt, qc, qr, qi, qs, qh, tem4,tem4,tem4, &
ubar, vbar, wbar, ptbar, pbar, rhobar, qvbar, &
soiltyp,stypfrct,vegtyp,tem2d,tem2d,tem2d, &
tsoil,qsoil,wetcanp,tem2d, &
tem2d,tem2d,prcrate, &
tem4,tem2d,tem2d,tem2d,tem2d, &
tem2d,tem2d,tem2d,tem2d, &
ireturn, tem1,tem2,tem3)
!
!-----------------------------------------------------------------------
!
! Deallocate the no-longer-needed dtaread arrays.
!
!-----------------------------------------------------------------------
!
deallocate(qvprt)
deallocate(qvbar)
deallocate(wbar)
deallocate(qc)
deallocate(qi)
deallocate(zpsoil)
deallocate(soiltyp)
deallocate(stypfrct)
deallocate(vegtyp)
deallocate(tsoil)
deallocate(qsoil)
deallocate(wetcanp)
deallocate(prcrate)
deallocate(tem2d)
deallocate(tem2)
deallocate(tem3)
deallocate(tem4)
allocate(usc(nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:usc")
usc=0.
allocate(vsc(nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:vsc")
vsc=0.
allocate(wsc(nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:wsc")
wsc=0.
dxinv=1./dx
dyinv=1./dx
twdx2inv=1./(2.*dx*dx)
twdxinv=1./(2.*dx)
twdy2inv=1./(2.*dy*dy)
twdyinv=1./(2.*dy)
DO k=1,nz-1
DO j=1,ny-1
DO i=1,nx-1
usc(i,j,k)=0.5*((uprt( i,j,k)+ubar( i,j,k))+ &
(uprt(i+1,j,k)+ubar(i+1,j,k)))+umove
vsc(i,j,k)=0.5*((vprt(i, j,k)+vbar(i, j,k))+ &
(vprt(i,j+1,k)+vbar(i,j+1,k)))+vmove
wsc(i,j,k)=0.5*(wprt(i,j,k)+wprt(i,j,k+1))
END DO
END DO
END DO
deallocate(ubar)
deallocate(uprt)
deallocate(vbar)
deallocate(vprt)
deallocate(wprt)
!
!-----------------------------------------------------------------------
!
! Calculate reflectivity at all scalar grid points.
! First need Temperature in K, which is stored in tem1
!
!-----------------------------------------------------------------------
!
tem1=0.
tem2=0.
DO k=1,nz-1
DO j=1,ny-1
DO i=1,nx-1
tem1(i,j,k)=(ptprt(i,j,k)+ptbar(i,j,k))* &
(((pprt(i,j,k) + pbar(i,j,k))*p0inv) ** rddcp)
END DO
END DO
END DO
deallocate(pbar)
deallocate(pprt)
deallocate(ptbar)
deallocate(ptprt)
allocate(ref(nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:ref")
ref=0.
! CALL reflec_ferrier(nx,ny,nz, tem2, qr, qs, qh, tem1, ref)
CALL reflec
(nx,ny,nz, rhobar, qr, qs, qh, ref)
!
deallocate(qr)
deallocate(qs)
deallocate(qh)
deallocate(tem1)
deallocate(rhobar)
ELSE ! hdf format
allocate(itmp(nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:hdf:itmp")
itmp=0
allocate(hmax(nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:hdf:hmax")
hmax=0.
allocate(hmin(nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:hdf:hmin")
hmin=0.
IF(ifile == 1) THEN
CALL get_gridxyzp_hdf
(nx,ny,nz,grdbasfn(1:lengbf), &
x,y,zp, &
itmp,hmax,hmin,ireturn)
IF( ireturn /= 0 ) THEN
WRITE(6,'(a,a)') ' Problem getting x,y,zp from hdf file ', &
grdbasfn(1:lengbf)
WRITE(6,'(a)') ' Program stopped.'
STOP
END IF
print *,' HDF info: x,y,z of input data read in.'
print *,' x(1 )=',x(1)
print *,' x(nx)=',x(nx)
print *,' y(1 )=',y(1)
print *,' y(ny)=',y(ny)
END IF
!
!-----------------------------------------------------------------------
!
! Read in the wind data and average to the scalar points
! Here the tem arrays are used to store the total wind components
! Note also: umove and vmove are returned via common
!
!-----------------------------------------------------------------------
!
allocate(tem1(nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:hdf:tem1")
tem1=0.
allocate(tem2(nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:hdf:tem2")
tem2=0.
allocate(tem3(nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:hdf:tem3")
tem3=0.
allocate(tem4(nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:hdf:tem4")
tem4=0.
allocate(usc(nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:hdf:usc")
usc=0.
allocate(vsc(nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:hdf:vsc")
vsc=0.
allocate(wsc(nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:hdf:wsc")
wsc=0.
allocate(rhobar(nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:hdf:rhobar")
rhobar=0.
CALL hdfreaduvw
(nx,ny,nz,TRIM(hisfile(ifile)), &
time,tem1,tem2,tem3, &
itmp,hmax,hmin,ireturn)
IF(ireturn < 0) EXIT
DO k=1,nz-1
DO j=1,ny-1
DO i=1,nx-1
usc(i,j,k)=(0.5*(tem1(i,j,k)+tem1(i+1,j,k)))+umove
vsc(i,j,k)=(0.5*(tem2(i,j,k)+tem2(i+1,j,k)))+vmove
wsc(i,j,k)=0.5*(tem3(i,j,k)+tem3(i,j,k+1))
END DO
END DO
END DO
!
!-----------------------------------------------------------------------
!
! Get pressure and potential temperature to find temperature in K
! Here the tem1 = total pressure and tem2 is total potential temp
! Use the rhobar array to store rho.
!
!-----------------------------------------------------------------------
!
tem1=0.
tem2=0.
CALL hdfreadppt
(nx,ny,nz,TRIM(hisfile(ifile)), &
time,tem1,tem2, &
itmp,hmax,hmin,ireturn)
IF(ireturn < 0) EXIT
DO k=1,nz-1
DO j=1,ny-1
DO i=1,nx-1
tem4(i,j,k)=(tem2(i,j,k))*((tem1(i,j,k)*p0inv) ** rddcp)
rhobar(i,j,k)=tem1(i,j,k)/(rd*tem4(i,j,k))
END DO
END DO
END DO
!
!-----------------------------------------------------------------------
!
! Get the hydrometeors qr,qs, and qh in tem1,tem2, and tem3
!
!-----------------------------------------------------------------------
!
tem1=0.
tem2=0.
tem3=0.
CALL hdfreadqrsh
(nx,ny,nz,TRIM(hisfile(ifile)), &
time,tem1,tem2,tem3, &
itmp,hmax,hmin,ireturn)
IF(ireturn < 0) EXIT
!
!-----------------------------------------------------------------------
!
! Free the hdf io arrays
!
!-----------------------------------------------------------------------
!
deallocate(itmp)
deallocate(hmax)
deallocate(hmin)
!
!-----------------------------------------------------------------------
!
! Compute the reflectivity
!
!-----------------------------------------------------------------------
!
allocate(ref(nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:hdf:ref")
ref=0.
! CALL reflec_ferrier(nx,ny,nz, rhobar, tem1, tem2, tem3, tem4, ref)
CALL reflec
(nx,ny,nz, rhobar, tem1, tem2, tem3, ref)
!
!-----------------------------------------------------------------------
!
! Free the temporary i/o arrays
!
!-----------------------------------------------------------------------
!
deallocate(tem1)
deallocate(tem2)
deallocate(tem3)
deallocate(tem4)
deallocate(rhobar)
END IF ! hdf format
!
!-----------------------------------------------------------------------
!
! Set up fake reflectivity for testing terrain blocking.
!
!-----------------------------------------------------------------------
! CALL fake_reflec(nx,ny,nz,ref)
! CALL fake_vel(nx,ny,nz,usc,vsc)
!
!-----------------------------------------------------------------------
!
! Make a few calculations now that we have read the datafile.
!
!-----------------------------------------------------------------------
!
dx=x(2)-x(1)
dy=y(2)-y(1)
dxinv=1./dx
dyinv=1./dy
curtim = time
IF(ifile == 1 .AND. adjctr == 2) time0=curtim
CALL ctim2abss
(year,month,day,hour,minute,second,itime)
ifsecs=NINT(curtim)
itime=itime+ifsecs
itimtilt=itime
initime=itimcdf-ifsecs
CALL gtlfnkey
(runname,lfnkey)
print *, ' yr,mo,day,hr,min,sec:',year,month,day
print *, ' hr,min,sec:',hour,minute,second
print *, ' ifsecs: ',ifsecs
print *, ' curtim: ',curtim
print *, ' mapproj,ctrlat,ctrlon: ',mapproj,ctrlat,ctrlon
CALL abss2ctim
(itime,year,month,day,hour,minute,second)
!
!-----------------------------------------------------------------------
!
! Average spatial locations to scalar points
! Need only do this once, for the first file.
!
!-----------------------------------------------------------------------
!
IF(ifile == 1) THEN
allocate(xsc(nx),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:xsc")
xsc=0.
allocate(ysc(ny),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:ysc")
ysc=0.
allocate(zps(nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:zps")
zps=0.
DO i=1,nx-1
xsc(i)=0.5*(x(i)+x(i+1))
END DO
xsc(nx)=xsc(nx-1)+dx
DO j=1,ny-1
ysc(j)=0.5*(y(j)+y(j+1))
END DO
ysc(ny)=ysc(ny-1)+dy
write(6,'(a,f10.2,a,f10.2,a)') ' Coordinate of x(2): ',(x(2)*0.001), &
' km y(2): ',(y(2)*0.001),' km'
IF( adjhgt > 0) THEN
write(6,'(a,f10.2,a)') &
' Adding height offset to grid:',hgtoffset,' m.'
ELSE
hgtoffset=0.
END IF
DO k=1,nz-1
DO j=1,ny-1
DO i=1,nx-1
zps(i,j,k)=(0.5*(zp(i,j,k)+zp(i,j,k+1)))+hgtoffset
END DO
END DO
END DO
DO j=1,ny-1
DO i=1,nx-1
zps(i,j,nz)=(2.0*zps(i,j,nz-1))-zps(i,j,nz-2)
END DO
END DO
END IF ! first file
!
!-----------------------------------------------------------------------
!
! Allocate additional grid location and geometry arrays
! These speed calculations down the road.
!
!-----------------------------------------------------------------------
!
allocate(latsc(nx,ny),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:latsc")
latsc=0.
allocate(lonsc(nx,ny),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:lonsc")
lonsc=0.
allocate(azmsc(nx,ny),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:azmsc")
azmsc=0.
allocate(sfcr(nx,ny),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:sfcr")
sfcr=0.
allocate(elvsc(nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:elvsc")
elvsc=0.
allocate(rngsc(nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:rngsc")
rngsc=0.
allocate(vrsc(nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:vrsc")
vrsc=0.
allocate(usm(nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:usm")
usm=0.
allocate(vsm(nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:vsm")
vsm=0.
allocate(vort(nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:vort")
vort=0.
allocate(refz(nx,ny,nz),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:refz")
refz=0.
allocate(cmpref(nx,ny),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:cmpref")
cmpref=0.
!
!-----------------------------------------------------------------------
!
! Define output data size and find location of radar in the grid.
! Account for umove and vmove by moving the radar relative to the grid.
!
! If no map projection has been defined, for the purposes of emulation,
! set the projection to Lambert conformal and center the grid on
! ctrlat, ctrlon.
!
!-----------------------------------------------------------------------
!
IF ( adjmove > 0 ) THEN
umove=umovein
vmove=vmovein
END IF
IF ( ifile == 1 ) THEN
IF ( mapproj == 0 ) THEN
IF ( adjctr > 0 ) THEN
ctrlat = ctrlatem
ctrlon = ctrlonem
END IF
print *, ' ctrlat, ctrlon: ',ctrlat,ctrlon
trulat1 = ctrlat
trulat2 = ctrlat
trulon = ctrlon
alatnot(1)=trulat1
alatnot(2)=trulat2
CALL setmapr
(2,1.0,alatnot,trulon)
CALL lltoxy
(1,1,ctrlat,ctrlon,ctrx,ctry)
xsw=ctrx-0.5*((nx-3)*dx)
ysw=ctry-0.5*((ny-3)*dy)
CALL setorig
(1,xsw,ysw)
ELSE IF ( adjctr > 0 ) THEN
ctrlat = ctrlatem
ctrlon = ctrlonem
alatnot(1)=trulat1
alatnot(2)=trulat2
CALL setmapr
(mapproj,1.0,alatnot,trulon)
CALL lltoxy
(1,1,ctrlat,ctrlon,ctrx,ctry)
xsw=ctrx-0.5*((nx-3)*dx)
ysw=ctry-0.5*((ny-3)*dy)
CALL setorig
(1,xsw,ysw)
ELSE
alatnot(1)=trulat1
alatnot(2)=trulat2
CALL setmapr
(mapproj,1.0,alatnot,trulon)
CALL lltoxy
(1,1,ctrlat,ctrlon,ctrx,ctry)
xsw=ctrx-0.5*((nx-3)*dx)
ysw=ctry-0.5*((ny-3)*dy)
CALL setorig
(1,xsw,ysw)
END IF
END IF
IF(locopt == 1) THEN
print *, ' radlat,radlon=',radlat,radlon
CALL lltoxy
(1,1,radlat,radlon,xrad,yrad)
xrada=xrad-umove*(curtim-time0)
yrada=yrad-vmove*(curtim-time0)
CALL xytoll
(1,1,xrada,yrada,radlata,radlona)
irloc=((xrada-xsc(1))*dxinv)+1.0
jrloc=((yrada-ysc(1))*dyinv)+1.0
WRITE(6,'(a,/a,f10.4,a,f10.4,/a,f10.4,a,f10.4,/a,f10.4,a,f10.4)') &
' Radar position (adjusted for umove, vmove)', &
' Radar latitude:',radlata,' longitude: ',radlona, &
' x-coord (km):',(0.001*xrada),' y-coord (km):',(0.001*yrada), &
' i-location: ',irloc,' j-location:',jrloc
ELSE
xrada=xrad*1000.
yrada=yrad*1000.
CALL xytoll
(1,1,xrada,yrada,radlat,radlon)
radlata=radlat
radlona=radlon
irloc=((xrada-xsc(1))*dxinv)+1.0
jrloc=((yrada-ysc(1))*dyinv)+1.0
WRITE(6,'(a,f10.4,a,f10.4,/a,f10.4,a,f10.4,/a,f10.4,a,f10.4)') &
' Radar latitude:',radlata,' longitude: ',radlona, &
' x-coord (km):',(0.001*xrada),' y-coord (km):',(0.001*yrada),&
' i-location: ',irloc,' j-location:',jrloc
END IF
iloc=INT(irloc)
jloc=INT(jrloc)
trngt=0.
IF(iloc > 0 .AND. iloc < nx-2 .AND. &
jloc > 0 .AND. jloc < ny-2 ) THEN
w2i=irloc-iloc
w1i=1.0-w2i
w2j=jrloc-jloc
w1j=1.0-w2j
w11=w1i*w1j
w21=w2i*w1j
w12=w1i*w2j
w22=w2i*w2j
trngt=w11*zp(iloc,jloc,2) + &
w21*zp(iloc+1,jloc,2) + &
w12*zp(iloc,jloc+1,2) + &
w22*zp(iloc+1,jloc+1,2)
END IF
WRITE(6,'(a,f8.1,a,f8.1//)') &
' Radar Elevation: ',radelv,' Terrain Height= ',trngt
!
!-----------------------------------------------------------------------
!
! Calculate radar parameters at each scalar grid point.
!
!-----------------------------------------------------------------------
print *, ' calculating radar parameters'
!
IF( mapproj > 0 ) THEN
CALL xytoll
(nx,ny,xsc,ysc,latsc,lonsc)
DO j=1,ny-1
DO i=1,nx-1
CALL disthead
(radlata,radlona,latsc(i,j),lonsc(i,j), &
azmsc(i,j),sfcr(i,j))
IF(sfcr(i,j) > rngmin) THEN
DO k=1,nz-1
CALL beamelv
((zps(i,j,k)-radelv),sfcr(i,j), &
elvsc(i,j,k),rngsc(i,j,k))
END DO
ELSE
rngsc(i,j,k)=sfcr(i,j)
elvsc(i,j,k)=-99.
END IF
END DO
END DO
ELSE
DO j=1,ny-1
DO i=1,nx-1
delx=xsc(i)-xrada
dely=ysc(j)-yrada
sfcr(i,j)=sqrt(delx*delx + dely*dely)
IF(dely > 0.) THEN
azmsc(i,j)=rad2deg*atan(delx/dely)
ELSE IF (dely < 0.) THEN
azmsc(i,j)=180.+rad2deg*atan(delx/dely)
ELSE IF (delx > 0.) THEN
azmsc(i,j)=90.
ELSE
azmsc(i,j)=270.
END IF
IF(azmsc(i,j) < 0.) azmsc(i,j)=azmsc(i,j)+360.
IF(sfcr(i,j) > rngmin) THEN
DO k=1,nz-1
CALL beamelv
((zps(i,j,k)-radelv),sfcr(i,j), &
elvsc(i,j,k),rngsc(i,j,k))
END DO
ELSE
rngsc(i,j,k)=sfcr(i,j)
elvsc(i,j,k)=-99.
END IF
END DO
END DO
END IF
!
!-----------------------------------------------------------------------
!
! Calculate radial velocity, including terminal velocity, and reflectivity
! factor (in mm6/m3) at all scalar grid points.
!
! The termvel subroutine can be updated sometime to use actual freezing
! level and/or the model species variables to calculate vt.
!
!-----------------------------------------------------------------------
!
print *, ' Calculating radial velocity'
DO j=1,ny-1
DO i=1,nx-1
ucmp=sin(deg2rad*azmsc(i,j))
vcmp=cos(deg2rad*azmsc(i,j))
cmpref(i,j)=-99.
DO k=2,nz-1
CALL termvel
(ref(i,j,k),zps(i,j,k),vt)
IF(ref(i,j,k) > 0.) THEN
refz(i,j,k)=10.**(0.1*ref(i,j,k))
ELSE
refz(i,j,k)=0.
END IF
CALL dhdrange
(elvsc(i,j,k),rngsc(i,j,k),dhdr)
dsdr=sqrt(1.-dhdr*dhdr)
vrsc(i,j,k)=dsdr*(ucmp*usc(i,j,k) + vcmp*vsc(i,j,k)) + &
dhdr*(wsc(i,j,k)-vt)
cmpref(i,j)=max(cmpref(i,j),ref(i,j,k))
END DO
END DO
END DO
usm=usc
vsm=usc
print *, ' Smoothing velocities, nsmvort=',nsmvort
IF(nsmvort > 0) THEN
DO ismth=1,nsmvort
CALL smooth9p
( usm, nx,ny, 1, nx-1, 1, ny-1, 0, vort )
CALL smooth9p
( vsm, nx,ny, 1, nx-1, 1, ny-1, 0, vort )
END DO
vort=0.
END IF
!
! Calculate vertical vorticity at scalar points
!
WRITE(6,'(a,f10.8,a,f10.8)') ' Calculating vorticity: dxinv=', &
dxinv,' dyinv: ',dyinv
DO k=1,nz
DO j=2,ny-2
DO i=2,nx-2
vort(i,j,k)=0.5*((vsm(i+1,j,k)-vsm(i-1,j,k))*dxinv - &
(usm(i,j+1,k)-usm(i,j-1,k))*dyinv)
END DO
END DO
END DO
DO k=1,nz
DO j=2,ny-2
vort(1,j,k)=vort(2,j,k)
vort(nx-1,j,k)=vort(nx-2,j,k)
END DO
END DO
DO k=1,nz
DO i=1,nx-1
vort(i,1,k)=vort(1,2,k)
vort(i,ny-1,k)=vort(i,ny-2,k)
END DO
END DO
vvmax=maxval(vort)
vvmin=minval(vort)
WRITE(6,'(a,g16.9,a,g16.9)') ' Grid min vert vort=',vvmin, &
' Max vert vort = ',vvmax
!
deallocate(usm)
deallocate(vsm)
!
! Allocate output radar arrays
!
allocate(azim(maxazim),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:azim")
azim=0.
allocate(beamw(maxazim),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:beamw")
beamw=0.
allocate(gtspc(maxazim),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:gtspc")
gtspc=0.
allocate(vnyq(maxazim),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:vnyq")
vnyq=0.
allocate(refl(ngate,maxazim),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:refl")
refl=0.
allocate(attrefl(ngate,maxazim),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:attrefl")
attrefl=0.
allocate(radv(ngate,maxazim),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:radv")
radv=0.
allocate(attradv(ngate,maxazim),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:attradv")
attradv=0.
allocate(stdvr(ngate,maxazim),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:stdvr")
stdvr=0.
allocate(vvort(ngate,maxazim),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:vvort")
vvort=0.
allocate(sens(ngate),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:sens")
sens=0.
IF( ifmt == 1 ) THEN
allocate(itimvol(nelev),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:itimvol")
itimvol=0
allocate(vnyqvol(nelev),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:vnyqvol")
vnyqvol=0.
allocate(rngvol(ngate,nelev),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:rngvol")
rngvol=0.
allocate(azmvol(maxazim,nelev),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:azmvol")
azmvol=0.
allocate(elvvol(maxazim,nelev),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:elvvol")
elvvol=0.
allocate(refvol(ngate,maxazim,nelev),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:refvol")
refvol=0.
allocate(uarefvol(ngate,maxazim,nelev),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:uarefvol")
uarefvol=0.
allocate(velvol(ngate,maxazim,nelev),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:velvol")
velvol=0.
allocate(uavelvol(ngate,maxazim,nelev),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:uavelvol")
uavelvol=0.
allocate(vorvol(ngate,maxazim,nelev),stat=istatus)
CALL check_alloc_status
(istatus, "radaremul:vorvol")
vorvol=0.
END IF
!
!-----------------------------------------------------------------------
!
! Open log file for index records
!
!-----------------------------------------------------------------------
!
IF( creidx > 0 .AND. ifmt == 2) THEN
write(idxfname,'(a,a,a,a,a,a,i6.6,a)') &
TRIM(outdir),'/',radname,'.',runname(1:lfnkey),'.',ifsecs,'.xml'
CALL getunit
(idxunit)
write(6,'(a,a)') ' Writing index to:',TRIM(idxfname)
OPEN(idxunit,file=idxfname,form='formatted',status='unknown')
write(idxunit,'(a)') &
'<?xml version="1.0" encoding="iso-8859-1" ?>'
write(idxunit,'(a,a,a)') '<codeindex type="netcdf" dataset="', &
TRIM(outdir),'">'
END IF
!
!-----------------------------------------------------------------------
!
! Create data from Cartesian grid.
!
!-----------------------------------------------------------------------
!
irot=1
IF(rotdir == 2) irot=-1
print *, ' entering tilt loop'
DO itilt=1,ntilt
kntgate=0
kntintr=0
kntintv=0
kntfewr=0
kntfewv=0
kntclr=0
knthob=0
kntvob=0
kntbob=0
write(6,'(/a,i3,a,f6.2,a)') &
' Processing tilt ',itilt,' elev=',elvang(itilt),' deg'
azim=rmisval
beamw=rmisval
gtspc=rmisval
vnyq=rmisval
refl=rmisval
attrefl=rmisval
radv=rmisval
attradv=rmisval
vvort=0.
vvmax=-999.
vvmin=999.
elv=elvang(itilt)
ielv=INT(elv)
felv=NINT(100.*(elv-ielv))
elvtop=elv+delelv(nptselv)
elvbot=elv+delelv(1)
write(6,'(a,f6.2,a,f6.2)') &
' Elv ang beam bot=',elvbot,' Elv ang beam top=',elvtop
IF(tmadvopt == 1) THEN
itimtilt=itime+NINT((itilt-1)*timeincr)
END IF
print *, ' itilt, itimtilt, tmadvopt, timeincr: ', &
itilt,itimtilt,tmadvopt,timeincr
IF(rotropt > 1) THEN
nazim=NINT(azmsect/delaz)+1
IF(dualprf > 0) THEN
ttime=nazim*((prt1(itilt)*npulse1(itilt))+ &
(prt2(itilt)*npulse2(itilt)))
ELSE
ttime=nazim*prt1(itilt)*npulse1(itilt)
END IF
rotrate=azmsect/ttime
ELSE
IF(dualprf > 0) THEN
delaz=rotrate*((prt1(itilt)*npulse1(itilt))+ &
(prt2(itilt)*npulse2(itilt)))
ELSE
delaz=rotrate*prt1(itilt)*npulse1(itilt)
END IF
nazim=NINT(azmsect/delaz)+1
END IF
WRITE(6,'(a,f10.2,a,/a,f10.2,a,/a,i6)') &
' Rotation rate:',rotrate,' deg/s', &
' Azimuth sampling increment:',delaz,' deg', &
' Number of azimuth samples:',nazim
!
!-----------------------------------------------------------------------
!
! Calculate constants for range weighting.
! Assumed here is a square wave transmitted with a matched filter
! in the receiver resulting in a received wave envelope that is
! approximately Gaussian.
! See Eqs 11.118 and 5.76 in Doviak and Zrnic', 2nd Ed, 1993.
!
! Note that pulselen has units of time, pulsewid units of meters
!
!-----------------------------------------------------------------------
!
IF(dualprf == 0) THEN
IF(pulseopt == 1) THEN
pulselmn=pulselen1(itilt)
pulsewmn=c*pulselmn
ELSE
pulsewmn=pulsewid1(itilt)
pulselmn=cinv*pulsewmn
END IF
prtmn=prt1(itilt)
npulsmn=npulse1(itilt)
IF(nyqstopt == 1) THEN
vnyqstl=vnyquist(itilt)
ELSE
vnyqstl=0.25*(0.01*wavelen)/prt1(itilt)
vnyquist(itilt)=vnyqstl
END IF
ELSE
IF(pulseopt == 1) THEN
pulselmn=0.5*(pulselen1(itilt)*pulselen2(itilt))
pulsewmn=c*pulselmn
ELSE
pulsewmn=0.5*(pulsewid1(itilt)*pulsewid2(itilt))
pulselmn=cinv*pulsewmn
END IF
prtmn=0.5*(prt1(itilt)+prt2(itilt))
npulsmn=NINT(0.5*(npulse1(itilt)+npulse2(itilt)))
IF(nyqstopt == 1) THEN
vnyqstl=vnyquist(itilt)
ELSE
vnyqstl=abs(0.25*(0.01*wavelen)/(prt1(itilt)-prt2(itilt)))
vnyquist(itilt)=vnyqstl
END IF
END IF
hlftau=0.5*pulselmn
aconst=pi/(2.*sqrt(log(2.0)))
b6=1.04/pulselmn
hlfctau=0.5*pulsewmn
sigr2=(0.35*hlfctau)*(0.35*hlfctau)
sr2inv=2.0/(4.0*sigr2)
rngwid=sqrt(sigr2)
twovnyq=2.*vnyqstl
twovninv=1./twovnyq
WRITE(6,'(a,f10.2,a)') ' Mean PRT: ',(prtmn*1000.),' millisec'
WRITE(6,'(a,f10.2,a)') ' Mean pulse length: ',(pulselmn*1.0E06), &
' microsec'
WRITE(6,'(a,f10.2,a)') ' Mean pulse width: ',pulsewmn,' m'
WRITE(6,'(a,f10.2,a)') &
' Gaussian filtered pulse half-width: ',rngwid,' m'
WRITE(6,'(a,f10.2,a)') ' Unambiguous velocity: ',vnyqstl,' m/s'
print *, 'rotrate,prtmn,npulsmn: ',rotrate,prtmn,npulsmn
IF( abs(rotrate) > 0.) THEN
efbmwid=EFFBMW(beamwid,rotrate,prtmn,npulsmn)
ELSE
efbmwid=beamwid
END IF
WRITE(6,'(a,f8.2,a)') ' Static beamwidth:',beamwid,' degrees.'
WRITE(6,'(a,f8.2,a)') ' Effective beamwidth:',efbmwid,' degrees.'
da=(evalwid*efbmwid)/float(nptsazm-1)
WRITE(6,'(a)') &
' Horiz cross-beam evaluation pts (azimuth degrees from center):'
DO jpt=1,nptsazm
delazm(jpt)=(-0.5*evalwid*efbmwid)+((jpt-1)*da)
WRITE(6,'(a,i4,a,f12.4)') ' delazm(',jpt,') = ',delazm(jpt)
END DO
!
!-----------------------------------------------------------------------
!
! Calculate sensitivity as a function of range.
!
!-----------------------------------------------------------------------
!
IF(senstvopt == 1) CALL xbsens
(ngate,gatesp,pulselmn,beamwid,sens)
wasqinv=fourln4/(efbmwid*efbmwid)
bmwrad=deg2rad*efbmwid
DO kpt=1,nptselv
DO jpt=1,nptsazm
DO ipt=1,nptsrng
wgtpt(ipt,jpt,kpt)=exp(-((delrng(ipt)*delrng(ipt))*sr2inv + &
(delazm(jpt)*delazm(jpt))*wasqinv + &
(delelv(kpt)*delelv(kpt))*wesqinv))
END DO
END DO
END DO
IF(rotdir == 1) THEN
irot=1
ELSE IF(rotdir == -1) THEN
irot=-1
ELSE IF (rotdir == 2 .OR. rotdir == -2) THEN
irot=-1*irot
END IF
IF(irot > 0) THEN
azmbgn=azim1
ELSE
azmbgn=azim2
END IF
WRITE(6,'(a,f10.2,a,i4,a,f10.2)') &
' Elev:',elv,' irot:',irot,' azmbgn:',azmbgn
IF(int_method == 1) THEN
WRITE(6,'(a,i3)') 'Using integration method ',int_method
DO jazim=1,nazim
azimuth=azmbgn+irot*((jazim-1)*delaz)
IF(azimuth > 360.) azimuth = azimuth-360.
IF(azimuth < 0.) azimuth = azimuth+360.
! IF(MOD((jazim-1),10) == 0) &
! WRITE(6,'(a,f10.2)') ' Processing azimuth: ', azimuth
azrad=deg2rad*azimuth
azim(jazim)=azimuth
beamw(jazim)=beamwid
gtspc(jazim)=gatesp
vnyq(jazim)=vnyquist(itilt)
DO igate=1, ngate
kntgate=kntgate+1
srange=igate*gatesp
CALL beamhgt
(elv,srange,hgt,sfcrng)
IF(mapproj > 0 ) THEN
CALL gcircle
(radlata,radlona,azimuth,sfcrng,gtlat,gtlon)
CALL lltoxy
(1,1,gtlat,gtlon,gtx,gty)
delx=gtx-xrada
dely=gty-yrada
xrat=delx/srange
yrat=dely/srange
ipos=(gtx*dxinv)+1.5
jpos=(gty*dyinv)+1.5
ELSE
delx=sin(azrad)*sfcrng
dely=cos(azrad)*sfcrng
xrat=delx/srange
yrat=dely/srange
ipos=irloc+(delx*dxinv)
jpos=jrloc+(dely*dyinv)
END IF
iloc1=NINT(ipos)
jloc1=NINT(jpos)
iloc=INT(ipos)
jloc=INT(jpos)
IF(iloc1 > 0 .AND. iloc1 < nx-1 .AND. &
jloc1 > 0 .AND. jloc1 < ny-1 ) THEN
hgtmsl=hgt+radelv
IF( hgtmsl > zps(iloc1,jloc1,2) .AND. &
hgtmsl < zps(iloc1,jloc1,nz-1) ) THEN
DO k=3,nz-2
IF(zps(iloc1,jloc1,k) > hgtmsl) EXIT
END DO
bmwm=bmwrad*evalwid*srange
sradius=max(bmwm,pulsewmn)
iradius=1+INT(sradius/dx)
jradius=1+INT(sradius/dy)
! print *, 'bmwm,pulsewid = ',bmwm,pulsewmn
! print *, 'iradius,jradius = ',iradius,jradius
!
! First calculate provisional values using tri-linear interpolation
! These will be used if there is insufficient density of data for a
! weighted-average calculation
!
rmax=0.
r11l=max(refz( iloc, jloc,k-1),0.)
rmax=max(rmax,r11l)
r21l=max(refz(iloc+1, jloc,k-1),0.)
rmax=max(rmax,r21l)
r12l=max(refz( iloc,jloc+1,k-1),0.)
rmax=max(rmax,r12l)
r22l=max(refz(iloc+1,jloc+1,k-1),0.)
rmax=max(rmax,r22l)
r11h=max(refz( iloc, jloc, k),0.)
rmax=max(rmax,r11h)
r21h=max(refz(iloc+1, jloc, k),0.)
rmax=max(rmax,r21h)
r12h=max(refz( iloc,jloc+1, k),0.)
rmax=max(rmax,r12h)
r22h=max(refz(iloc+1,jloc+1, k),0.)
rmax=max(rmax,r22h)
whigh=(hgtmsl-zps(iloc1,jloc1,k-1))/ &
(zps(iloc1,jloc1,k)-zps(iloc1,jloc1,k-1))
wlow=1.-whigh
w2i=ipos-iloc
w1i=1.0-w2i
w2j=jpos-jloc
w1j=1.0-w2j
w11=w1i*w1j
w21=w2i*w1j
w12=w1i*w2j
w22=w2i*w2j
vvort(igate,jazim)=whigh*(w11*vort(iloc,jloc,k) + &
w21*vort(iloc+1,jloc,k) + &
w12*vort(iloc,jloc+1,k) + &
w22*vort(iloc+1,jloc+1,k)) + &
wlow*(w11*vort(iloc,jloc,k-1) + &
w21*vort(iloc+1,jloc,k-1) + &
w12*vort(iloc,jloc+1,k-1) + &
w22*vort(iloc+1,jloc+1,k-1))
vvmin=min(vvmin,vvort(igate,jazim))
vvmax=max(vvmax,vvort(igate,jazim))
IF( rmax > 0. ) THEN
CALL dhdrange
(elv,srange,dhdr)
dsdr=sqrt(1.-dhdr*dhdr)
kntintv=kntintv+1
kntintr=kntintr+1
reflz=whigh*(w11*r11h+w21*r21h + &
w12*r12h+w22*r22h) + &
wlow*(w11*r11l+w21*r21l + &
w12*r12l+w22*r22l)
refdbz=10.*alog10(reflz)
refl(igate,jazim)=refdbz+sigmarf*randnor()
refl(igate,jazim)=max(refl(igate,jazim),refmin)
IF(refdbz > refmin ) THEN
urad=whigh*(w11*usc( iloc, jloc,k) + &
w21*usc(iloc+1, jloc,k) + &
w12*usc( iloc,jloc+1,k) + &
w22*usc(iloc+1,jloc+1,k))+ &
wlow*(w11*usc( iloc, jloc,k-1) + &
w21*usc(iloc+1, jloc,k-1) + &
w12*usc( iloc,jloc+1,k-1) + &
w22*usc(iloc+1,jloc+1,k-1))
vrad=whigh*(w11*vsc( iloc, jloc,k) + &
w21*vsc(iloc+1, jloc,k) + &
w12*vsc( iloc,jloc+1,k) + &
w22*vsc(iloc+1,jloc+1,k))+ &
wlow*(w11*vsc( iloc, jloc,k-1) + &
w21*vsc(iloc+1, jloc,k-1) + &
w12*vsc( iloc,jloc+1,k-1) + &
w22*vsc(iloc+1,jloc+1,k-1))
wrad=whigh*(w11*wsc( iloc, jloc,k) + &
w21*wsc(iloc+1, jloc,k) + &
w12*wsc( iloc,jloc+1,k) + &
w22*wsc(iloc+1,jloc+1,k))+ &
wlow*(w11*wsc( iloc, jloc,k-1) + &
w21*wsc(iloc+1, jloc,k-1) + &
w12*wsc( iloc,jloc+1,k-1) + &
w22*wsc(iloc+1,jloc+1,k-1))
!
! Estimate terminal velocity (vt is positive down)
!
CALL termvel
(refl(igate,jazim),hgtmsl,vt)
!
! Calculate radial component
!
vr=dsdr*(xrat*urad+yrat*vrad)+dhdr*(wrad-vt)
!
! Add Gaussian random noise
!
vr=vr+sigmavr*randnor()
!
! Apply Doppler aliasing, if any
!
ifold=NINT(vr*twovninv)
radv(igate,jazim)=vr-ifold*twovnyq
END IF
END IF
!
! Calculate weighted average values using antenna pattern gain.
!
ibgn=max(1,(iloc1-iradius))
iend=min((nx-1),(iloc1+iradius))
jbgn=max(1,(jloc1-jradius))
jend=min((ny-1),(jloc1+jradius))
!
! First check to see of the entire observation volume area is clear.
!
echo=.false.
DO jpt=jbgn,jend
DO ipt=ibgn,iend
IF(cmpref(ipt,jpt) > 0.) echo=.true.
END DO
END DO
!
! If echo was found in 2d composite, proceed with processing 3d data.
!
IF(echo) THEN
sumwr=0.
sumwv=0.
sumv=0.
sumr=0.
kntr=0
kntv=0
DO jpt=jbgn,jend
DO ipt=ibgn,iend
DO kpt=2,nz-2
delv=elvsc(ipt,jpt,kpt)-elv
IF( abs(delv) < elradius .AND. &
refz(ipt,jpt,kpt) > 0. ) THEN
depth=0.5*(zps(ipt,jpt,kpt+1)-zps(ipt,jpt,kpt-1))
drng=rngsc(ipt,jpt,kpt)-srange
dazm=azmsc(ipt,jpt)-azimuth
IF(dazm > 180.) THEN
dazm=dazm-360.
ELSE IF( dazm < -180.) THEN
dazm=dazm+360.
END IF
wgtg=(drng*drng)*sr2inv + &
(dazm*dazm)*wasqinv + &
(delv*delv)*wesqinv
wgtr=depth*exp(-wgtg)
kntr=kntr+1
sumwr=sumwr+wgtr
sumr=sumr+wgtr*refz(ipt,jpt,kpt)
IF( ref(ipt,jpt,kpt) > refmin ) THEN
wgtv=refz(ipt,jpt,kpt)*wgtr
kntv=kntv+1
sumwv=sumwv+wgtv
sumv=sumv+wgtv*vrsc(ipt,jpt,kpt)
END IF
END IF
END DO
END DO
END DO
!
! Solve for mean reflectivity
!
! print *, ' igate,jazim,sumwr, kntr = ', &
! igate,jazim,sumwr,kntr
IF(sumwr > 0. .AND. kntr >= kntrmin ) THEN
kntavgr=kntavgr+1
reflz=sumr/sumwr
refdbz=10.*alog10(reflz)
refl(igate,jazim)=refdbz+sigmarf*randnor()
refl(igate,jazim)=max(refl(igate,jazim),refmin)
END IF
!
! Solve for mean radial velocity
!
! print *, ' igate,jazim,sumwv, kntv = ', &
! igate,jazim,sumwv,kntv
IF(sumwv > 0. .AND. kntv >= kntvmin ) THEN
kntavgv=kntavgv+1
vr=sumv/sumwv
!
! Add Gaussian random noise
!
vr=vr+sigmavr*randnor()
!
! Apply Doppler aliasing, if any
!
ifold=NINT(vr*twovninv)
radv(igate,jazim)=vr-ifold*twovnyq
END IF
ELSE ! no echo found in area
kntclr=kntclr+1
refl(igate,jazim)=0.
radv(igate,jazim)=rmisval
END IF
ELSE ! outside vertical limits of grid
kntvob=kntvob+1
END IF
ELSE ! outside grid domain
knthob=knthob+1
END IF
END DO ! igate
END DO ! jazim
!
ELSE ! Integration method 2
WRITE(6,'(a,i3)') 'Using integration method ',int_method
DO jazim=1,nazim
azimuth=azmbgn+irot*((jazim-1)*delaz)
IF(azimuth > 360.) azimuth = azimuth-360.
IF(azimuth < 0.) azimuth = azimuth+360.
! IF(MOD((jazim-1),20) == 0) &
! WRITE(6,'(a,f10.2)') ' Processing azimuth: ', azimuth
azrad=deg2rad*azimuth
azim(jazim)=azimuth
beamw(jazim)=beamwid
gtspc(jazim)=gatesp
vnyq(jazim)=vnyqstl
DO kpt=1,nptselv
DO jpt=1,nptsazm
blockfct(jpt,kpt)=1.0
END DO
END DO
DO igate=1, ngate
kntgate=kntgate+1
srange=igate*gatesp
CALL beamhgt
(elv,srange,hgt,sfcrng)
IF(mapproj > 0 ) THEN
CALL gcircle
(radlata,radlona,azimuth,sfcrng,gtlat,gtlon)
CALL lltoxy
(1,1,gtlat,gtlon,gtx,gty)
delx=gtx-xrada
dely=gty-yrada
xrat=delx/srange
yrat=dely/srange
ipos=(gtx*dxinv)+1.5
jpos=(gty*dyinv)+1.5
ELSE
delx=sin(azrad)*sfcrng
dely=cos(azrad)*sfcrng
xrat=delx/srange
yrat=dely/srange
ipos=irloc+(delx*dxinv)
jpos=jrloc+(dely*dyinv)
END IF
iloc1=NINT(ipos)
jloc1=NINT(jpos)
iloc=INT(ipos)
jloc=INT(jpos)
IF(iloc1 > 0 .AND. iloc1 < nx-1 .AND. &
jloc1 > 0 .AND. jloc1 < ny-1 ) THEN
hgtmsl=hgt+radelv
w2i=ipos-iloc
w1i=1.0-w2i
w2j=jpos-jloc
w1j=1.0-w2j
w11=w1i*w1j
w21=w2i*w1j
w12=w1i*w2j
w22=w2i*w2j
trngt=w11*zp(iloc,jloc,2) + &
w21*zp(iloc+1,jloc,2) + &
w12*zp(iloc,jloc+1,2) + &
w22*zp(iloc+1,jloc+1,2)
topgt=w11*zps(iloc,jloc,nzm2) + &
w21*zps(iloc+1,jloc,nzm2) + &
w12*zps(iloc,jloc+1,nzm2) + &
w22*zps(iloc+1,jloc+1,nzm2)
CALL beamhgt
(elvtop,srange,tophgt,sfcrngt)
CALL beamhgt
(elvbot,srange,bothgt,sfcrngb)
topmsl=tophgt+radelv
botmsl=bothgt+radelv
IF(botmsl < topgt .AND. topmsl > (trngt+hblkmin)) THEN
DO k=3,nz-2
IF(zps(iloc1,jloc1,k) > hgtmsl) EXIT
END DO
!
! Calculate vorticity by doing a linear interpolation directly to
! the gate center location.
!
whigh=(hgtmsl-zps(iloc1,jloc1,k-1))/ &
(zps(iloc1,jloc1,k)-zps(iloc1,jloc1,k-1))
wlow=1.-whigh
vvort(igate,jazim)=whigh*(w11*vort(iloc,jloc,k) + &
w21*vort(iloc+1,jloc,k) + &
w12*vort(iloc,jloc+1,k) + &
w22*vort(iloc+1,jloc+1,k)) + &
wlow*(w11*vort(iloc,jloc,k-1) + &
w21*vort(iloc+1,jloc,k-1) + &
w12*vort(iloc,jloc+1,k-1) + &
w22*vort(iloc+1,jloc+1,k-1))
vvmin=min(vvmin,vvort(igate,jazim))
vvmax=max(vvmax,vvort(igate,jazim))
!
! Check to see of the entire observation volume area is clear.
!
bmwm=bmwrad*evalwid*srange
sradius=max(bmwm,pulsewmn)
iradius=1+INT(sradius/dx)
jradius=1+INT(sradius/dy)
ibgn=max(1,(iloc1-iradius))
iend=min((nx-1),(iloc1+iradius))
jbgn=max(1,(jloc1-jradius))
jend=min((ny-1),(jloc1+jradius))
echo=.false.
DO jpt=jbgn,jend
DO ipt=ibgn,iend
IF(cmpref(ipt,jpt) > 0.) THEN
echo=.true.
EXIT
END IF
END DO
END DO
IF(echo .OR. (botmsl < trngt)) THEN
!
! Calculate beam-weighted sums for an uniform array of points around this
! range-gate using bi-quadratic horizontal and linear vertical interpolation
!
kntr=0
sumr=0.
sumwr=0.
kntv=0.
sumv=0.
sumv1=0.
sumv2=0.
sumwv=0.
DO kpt=1,nptselv
elvpt=elv+delelv(kpt)
! IF(igate == 100) print *, 'kpt, hgtmsl: ',kpt,hgtmsl
DO jpt=1,nptsazm
azmpt=azimuth+delazm(jpt)
azmrpt=deg2rad*azmpt
DO ipt=1,nptsrng
srgpt=(igate*gatesp)+delrng(ipt)
IF(srgpt <= 0.0) CYCLE
CALL beamhgt
(elvpt,srgpt,hgtpt,sfcrpt)
hgtmsl=hgtpt+radelv
IF(mapproj > 0 ) THEN
CALL gcircle
(radlata,radlona,azmpt,sfcrpt,gtlat,gtlon)
CALL lltoxy
(1,1,gtlat,gtlon,gtx,gty)
delx=gtx-xrada
dely=gty-yrada
xrat=delx/sfcrpt
yrat=dely/sfcrpt
ipos=(gtx*dxinv)+1.5
jpos=(gty*dyinv)+1.5
ELSE
delx=sin(azmrpt)*sfcrpt
dely=cos(azmrpt)*sfcrpt
xrat=delx/sfcrpt
yrat=dely/sfcrpt
ipos=irloc+(delx*dxinv)
jpos=jrloc+(dely*dyinv)
END IF
iloc1=NINT(ipos)
jloc1=NINT(jpos)
iloc=INT(ipos)
jloc=INT(jpos)
IF(iloc1 > 0 .AND. iloc1 < nx-1 .AND. &
jloc1 > 0 .AND. jloc1 < ny-1 ) THEN
ilc=max(min(iloc1,nx-2),2)
jlc=max(min(jloc1,ny-2),2)
xpt=gtx-xsc(ilc)
ypt=gty-ysc(jlc)
w2i=ipos-iloc
w1i=1.0-w2i
w2j=jpos-jloc
w1j=1.0-w2j
w11=w1i*w1j
w21=w2i*w1j
w12=w1i*w2j
w22=w2i*w2j
trnpt=w11*zp(iloc,jloc,2) + &
w21*zp(iloc+1,jloc,2) + &
w12*zp(iloc,jloc+1,2) + &
w22*zp(iloc+1,jloc+1,2)
hgtagl=hgtmsl-trnpt
IF(blockopt > 0 .AND. hgtagl < hblkmax) THEN
xmit=max(0.0,min(1.0,((hgtagl-hblkmin)*dhblkinv)))
gndatten=max(0.0,min(1.0,(blkcst*(1.-xmit))))
blockfct(jpt,kpt)= &
max(0.0,min(1.0,(blockfct(jpt,kpt)-gndatten)))
END IF
IF( hgtagl > hblkmin .AND. &
hgtmsl < zps(iloc1,jloc1,nz-1) ) THEN
DO k=3,nz-2
IF(zps(iloc1,jloc1,k) > hgtmsl) EXIT
END DO
whigh=(hgtmsl-zps(iloc1,jloc1,k-1))/ &
(zps(iloc1,jloc1,k)-zps(iloc1,jloc1,k-1))
wlow=1.-whigh
a=(refz(ilc-1,jlc-1,k-1)-2.*refz(ilc,jlc-1,k-1)+ &
refz(ilc+1,jlc-1,k-1))*twdx2inv
b=(refz(ilc+1,jlc-1,k-1)-refz(ilc-1,jlc-1,k-1)) &
*twdxinv
fjm1=a*xpt*xpt+b*xpt+refz(ilc,jlc-1,k-1)
a=(refz(ilc-1,jlc,k-1)-2.*refz(ilc,jlc,k-1)+ &
refz(ilc+1,jlc,k-1))*twdx2inv
b=(refz(ilc+1,jlc,k-1)-refz(ilc-1,jlc,k-1)) &
*twdxinv
fj0=a*xpt*xpt+b*xpt+refz(ilc,jlc,k-1)
a=(refz(ilc-1,jlc+1,k-1)-2.*refz(ilc,jlc+1,k-1)+ &
refz(ilc+1,jlc+1,k-1))*twdx2inv
b=(refz(ilc+1,jlc+1,k-1)-refz(ilc-1,jlc+1,k-1)) &
*twdxinv
fjp1=a*xpt*xpt+b*xpt+refz(ilc,jlc+1,k-1)
a=(fjm1-2.*fj0+fjp1)*twdy2inv
b=(fjp1-fjm1)*twdyinv
flow=a*ypt*ypt + b*ypt + fj0
a=(refz(ilc-1,jlc-1,k)-2.*refz(ilc,jlc-1,k)+ &
refz(ilc+1,jlc-1,k))*twdx2inv
b=(refz(ilc+1,jlc-1,k)-refz(ilc-1,jlc-1,k)) &
*twdxinv
fjm1=a*xpt*xpt+b*xpt+refz(ilc,jlc-1,k)
a=(refz(ilc-1,jlc,k)-2.*refz(ilc,jlc,k)+ &
refz(ilc+1,jlc,k))*twdx2inv
b=(refz(ilc+1,jlc,k)-refz(ilc-1,jlc,k))*twdxinv
fj0=a*xpt*xpt+b*xpt+refz(ilc,jlc,k)
a=(refz(ilc-1,jlc+1,k)-2.*refz(ilc,jlc+1,k)+ &
refz(ilc+1,jlc+1,k))*twdx2inv
b=(refz(ilc+1,jlc+1,k)-refz(ilc-1,jlc+1,k)) &
*twdxinv
fjp1=a*xpt*xpt+b*xpt+refz(ilc,jlc+1,k)
a=(fjm1-2.*fj0+fjp1)*twdy2inv
b=(fjp1-fjm1)*twdyinv
fhigh=a*ypt*ypt + b*ypt + fj0
reflz=whigh*fhigh+wlow*flow
kntr=kntr+1
sumr=sumr+reflz*wgtpt(ipt,jpt,kpt)*blockfct(jpt,kpt)
sumwr=sumwr+wgtpt(ipt,jpt,kpt)
IF( reflz > 0. ) THEN
CALL dhdrange
(elvpt,srgpt,dhdr)
dsdr=sqrt(1.-dhdr*dhdr)
refdbz=10.*alog10(reflz)
IF(refdbz > refmin ) THEN
a=(usc(ilc-1,jlc-1,k-1)-2.*usc(ilc,jlc-1,k-1)&
+usc(ilc+1,jlc-1,k-1))*twdx2inv
b=(usc(ilc+1,jlc-1,k-1)-usc(ilc-1,jlc-1,k-1))&
*twdxinv
fjm1=a*xpt*xpt+b*xpt+usc(ilc,jlc-1,k-1)
a=(usc(ilc-1,jlc,k-1)-2.*usc(ilc,jlc,k-1)+ &
usc(ilc+1,jlc,k-1))*twdx2inv
b=(usc(ilc+1,jlc,k-1)-usc(ilc-1,jlc,k-1)) &
*twdxinv
fj0=a*xpt*xpt+b*xpt+usc(ilc,jlc,k-1)
a=(usc(ilc-1,jlc+1,k-1)-2.*usc(ilc,jlc+1,k-1)&
+usc(ilc+1,jlc+1,k-1))*twdx2inv
b=(usc(ilc+1,jlc+1,k-1)-usc(ilc-1,jlc+1,k-1))&
*twdxinv
fjp1=a*xpt*xpt+b*xpt+usc(ilc,jlc+1,k-1)
a=(fjm1-2.*fj0+fjp1)*twdy2inv
b=(fjp1-fjm1)*twdyinv
flow=a*ypt*ypt + b*ypt + fj0
a=(usc(ilc-1,jlc-1,k)-2.*usc(ilc,jlc-1,k)+ &
usc(ilc+1,jlc-1,k))*twdx2inv
b=(usc(ilc+1,jlc-1,k)-usc(ilc-1,jlc-1,k)) &
*twdxinv
fjm1=a*xpt*xpt+b*xpt+usc(ilc,jlc-1,k)
a=(usc(ilc-1,jlc,k)-2.*usc(ilc,jlc,k)+ &
usc(ilc+1,jlc,k))*twdx2inv
b=(usc(ilc+1,jlc,k)-usc(ilc-1,jlc,k))*twdxinv
fj0=a*xpt*xpt+b*xpt+usc(ilc,jlc,k)
a=(usc(ilc-1,jlc+1,k)-2.*usc(ilc,jlc+1,k)+ &
usc(ilc+1,jlc+1,k))*twdx2inv
b=(usc(ilc+1,jlc+1,k)-usc(ilc-1,jlc+1,k)) &
*twdxinv
fjp1=a*xpt*xpt+b*xpt+usc(ilc,jlc+1,k)
a=(fjm1-2.*fj0+fjp1)*twdy2inv
b=(fjp1-fjm1)*twdyinv
fhigh=a*ypt*ypt + b*ypt + fj0
urad=whigh*fhigh+wlow*flow
a=(vsc(ilc-1,jlc-1,k-1)-2.*vsc(ilc,jlc-1,k-1)&
+vsc(ilc+1,jlc-1,k-1))*twdx2inv
b=(vsc(ilc+1,jlc-1,k-1)-vsc(ilc-1,jlc-1,k-1))&
*twdxinv
fjm1=a*xpt*xpt+b*xpt+vsc(ilc,jlc-1,k-1)
a=(vsc(ilc-1,jlc,k-1)-2.*vsc(ilc,jlc,k-1)+ &
vsc(ilc+1,jlc,k-1))*twdx2inv
b=(vsc(ilc+1,jlc,k-1)-vsc(ilc-1,jlc,k-1)) &
*twdxinv
fj0=a*xpt*xpt+b*xpt+vsc(ilc,jlc,k-1)
a=(vsc(ilc-1,jlc+1,k-1)-2.*vsc(ilc,jlc+1,k-1)&
+vsc(ilc+1,jlc+1,k-1))*twdx2inv
b=(vsc(ilc+1,jlc+1,k-1)-vsc(ilc-1,jlc+1,k-1))&
*twdxinv
fjp1=a*xpt*xpt+b*xpt+vsc(ilc,jlc+1,k-1)
a=(fjm1-2.*fj0+fjp1)*twdy2inv
b=(fjp1-fjm1)*twdyinv
flow=a*ypt*ypt + b*ypt + fj0
a=(vsc(ilc-1,jlc-1,k)-2.*vsc(ilc,jlc-1,k)+ &
vsc(ilc+1,jlc-1,k))*twdx2inv
b=(vsc(ilc+1,jlc-1,k)-vsc(ilc-1,jlc-1,k)) &
*twdxinv
fjm1=a*xpt*xpt+b*xpt+vsc(ilc,jlc-1,k)
a=(vsc(ilc-1,jlc,k)-2.*vsc(ilc,jlc,k)+ &
vsc(ilc+1,jlc,k))*twdx2inv
b=(vsc(ilc+1,jlc,k)-vsc(ilc-1,jlc,k))*twdxinv
fj0=a*xpt*xpt+b*xpt+vsc(ilc,jlc,k)
a=(vsc(ilc-1,jlc+1,k)-2.*vsc(ilc,jlc+1,k)+ &
vsc(ilc+1,jlc+1,k))*twdx2inv
b=(vsc(ilc+1,jlc+1,k)-vsc(ilc-1,jlc+1,k)) &
*twdxinv
fjp1=a*xpt*xpt+b*xpt+vsc(ilc,jlc+1,k)
a=(fjm1-2.*fj0+fjp1)*twdy2inv
b=(fjp1-fjm1)*twdyinv
fhigh=a*ypt*ypt + b*ypt + fj0
vrad=whigh*fhigh+wlow*flow
a=(wsc(ilc-1,jlc-1,k-1)-2.*wsc(ilc,jlc-1,k-1)&
+wsc(ilc+1,jlc-1,k-1))*twdx2inv
b=(wsc(ilc+1,jlc-1,k-1)-wsc(ilc-1,jlc-1,k-1))&
*twdxinv
fjm1=a*xpt*xpt+b*xpt+wsc(ilc,jlc-1,k-1)
a=(wsc(ilc-1,jlc,k-1)-2.*wsc(ilc,jlc,k-1)+ &
wsc(ilc+1,jlc,k-1))*twdx2inv
b=(wsc(ilc+1,jlc,k-1)-wsc(ilc-1,jlc,k-1)) &
*twdxinv
fj0=a*xpt*xpt+b*xpt+wsc(ilc,jlc,k-1)
a=(wsc(ilc-1,jlc+1,k-1)-2.*wsc(ilc,jlc+1,k-1)&
+wsc(ilc+1,jlc+1,k-1))*twdx2inv
b=(wsc(ilc+1,jlc+1,k-1)-wsc(ilc-1,jlc+1,k-1))&
*twdxinv
fjp1=a*xpt*xpt+b*xpt+wsc(ilc,jlc+1,k-1)
a=(fjm1-2.*fj0+fjp1)*twdy2inv
b=(fjp1-fjm1)*twdyinv
flow=a*ypt*ypt + b*ypt + fj0
a=(wsc(ilc-1,jlc-1,k)-2.*wsc(ilc,jlc-1,k)+ &
wsc(ilc+1,jlc-1,k))*twdx2inv
b=(wsc(ilc+1,jlc-1,k)-wsc(ilc-1,jlc-1,k)) &
*twdxinv
fjm1=a*xpt*xpt+b*xpt+wsc(ilc,jlc-1,k)
a=(wsc(ilc-1,jlc,k)-2.*wsc(ilc,jlc,k)+ &
wsc(ilc+1,jlc,k))*twdx2inv
b=(wsc(ilc+1,jlc,k)-wsc(ilc-1,jlc,k))*twdxinv
fj0=a*xpt*xpt+b*xpt+wsc(ilc,jlc,k)
a=(wsc(ilc-1,jlc+1,k)-2.*wsc(ilc,jlc+1,k)+ &
wsc(ilc+1,jlc+1,k))*twdx2inv
b=(wsc(ilc+1,jlc+1,k)-wsc(ilc-1,jlc+1,k)) &
*twdxinv
fjp1=a*xpt*xpt+b*xpt+wsc(ilc,jlc+1,k)
a=(fjm1-2.*fj0+fjp1)*twdy2inv
b=(fjp1-fjm1)*twdyinv
fhigh=a*ypt*ypt + b*ypt + fj0
wrad=whigh*fhigh+wlow*flow
!
! Estimate terminal velocity (vt is positive down)
!
CALL termvel
(refdbz,hgtmsl,vt)
!
! Calculate radial component
!
vr=dsdr*(xrat*urad+yrat*vrad)+dhdr*(wrad-vt)
kntv=kntv+1
sumv=sumv+vr*wgtpt(ipt,jpt,kpt)* &
blockfct(jpt,kpt)*reflz
sumwv=sumwv+wgtpt(ipt,jpt,kpt)*reflz
sumv1=sumv1+vr
sumv2=sumv2+vr*vr
END IF ! refdbz > refmin
END IF ! reflz > 0
ELSE IF(hgtagl <= hblkmin .AND. blockopt > 1) THEN
vr=0.
reflz=reflzgnd
kntr=kntr+1
sumr=sumr+reflz*wgtpt(ipt,jpt,kpt)*blockfct(jpt,kpt)
sumwr=sumwr+wgtpt(ipt,jpt,kpt)
kntv=kntv+1
sumv=sumv+vr*wgtpt(ipt,jpt,kpt)* &
blockfct(jpt,kpt)*reflz
sumwv=sumwv+wgtpt(ipt,jpt,kpt)*reflz
sumv1=sumv1+vr
sumv2=sumv2+vr*vr
END IF ! hgt in grid
END IF ! iloc in grid
END DO ! ipt
END DO ! jpt
END DO ! kpt
!
! Calculate reflectivity and velocity from the uniform
! array center on this range gate.
!
IF(sumwr > 0. .AND. kntr > kntrmin) THEN
kntintr=kntintr+1
reflz=sumr/sumwr
refdbz=10.*alog10(reflz)
refl(igate,jazim)=min(max(refdbz,refmin),refmax)
ELSE
kntfewr=kntfewr+1
refl(igate,jazim)=0.
END IF
IF(sumwv > 0. .AND. kntv > kntvmin) THEN
kntintv=kntintv+1
vr=sumv/sumwv
ifold=NINT(vr*twovninv)
radv(igate,jazim)=vr-ifold*twovnyq
flkntv=float(kntv)
varvr=max(0.01, &
((sumv2-(sumv1*sumv1/flkntv))/(flkntv-1.)))
stdvr(igate,jazim)=stdvrmul*SQRT(varvr)
ELSE
kntfewv=kntfewv+1
radv(igate,jazim)=rmisval
END IF
ELSE ! no echo
kntclr=kntclr+1
refl(igate,jazim)=0.
radv(igate,jazim)=rmisval
END IF
ELSE IF ( botmsl > topgt) THEN ! beam completely above grid
kntvob=kntvob+(ngate-igate)+1
kntgate=kntgate+(ngate-igate)
EXIT
ELSE IF ( topmsl < (trnpt+hblkmin) ) THEN ! beam completely below ground
print *, ' Entire beam below ground: ',azimuth,igate
IF(blockopt > 1) THEN
sumr=0.
sumwr=0.
DO kpt=1,nptselv
DO jpt=1,nptsazm
reflz=reflzgnd
sumr=sumr+reflz*wgtpt(ipt,jpt,kpt)*blockfct(jpt,kpt)
sumwr=sumwr+wgtpt(ipt,jpt,kpt)
END DO
END DO
refl(igate,jazim)=sumr/sumwr
ELSE
refl(igate,jazim)=0.
END IF
radv(igate,jazim)=0.
kntbob=kntbob+(ngate-igate)+1
kntgate=kntgate+(ngate-igate)
DO iigate=igate+1,ngate
radv(iigate,jazim)=0.
refl(iigate,jazim)=0.
END DO
EXIT
END IF
ELSE ! outside grid domain
knthob=knthob+1
END IF
END DO ! igate
reflmin=999.
reflmax=-999.
DO igate=1,ngate
IF(refl(igate,jazim) > refchk) THEN
reflmin=min(reflmin,refl(igate,jazim))
reflmax=max(reflmax,refl(igate,jazim))
END IF
END DO
IF(mod(jazim,30) == 0) &
print *, ' Azimuth,reflmin,reflmax=',azimuth,reflmin,reflmax
END DO ! jazim
END IF ! integration method
!
!-----------------------------------------------------------------------
!
! Calculate attenuation for this tilt
!
!-----------------------------------------------------------------------
!
WRITE(6,'(a,i6)') ' Attenopt block, attenopt= ',attenopt
IF (attenopt > 0) THEN
CALL xbatten
(ngate,maxazim,nazim, &
refl,gatesp,rmisval,refmin,attrefl)
ELSE
DO jazim=1,nazim
DO igate=1,ngate
attrefl(igate,jazim)=refl(igate,jazim)
END DO
END DO
END IF
!
!-----------------------------------------------------------------------
!
! Apply noise to the reflectivity and velocity according the
! indicated option.
!
!-----------------------------------------------------------------------
!
WRITE(6,'(a,i4)') ' radial vel error, vrerropt= ',vrerropt
IF(vrerropt > 0 ) &
CALL radverr
(ngate,maxazim,nazim,radv,attrefl,stdvr,gatesp, &
vrerropt,sigmavr,samploi,vnyqstl, &
wavelen,pwrxmt,gaindb,lossdb,noisedbm,beamwid, &
pulselmn,npulsmn,rmisval)
WRITE(6,'(a,i4)') ' reflectivity error, rferropt= ',rferropt
IF(rferropt > 0 ) &
CALL reflerr
(ngate,maxazim,nazim,refl,attrefl,gatesp, &
rferropt,sigmarf,refmin,samploi, &
wavelen,pwrxmt,gaindb,lossdb,noisedbm,beamwid, &
pulselmn,npulsmn,rmisval)
!
!-----------------------------------------------------------------------
!
! Apply X-band radar sensitivity thresholding to the
! attenuated velocity using the attenuated reflectivity.
!
!-----------------------------------------------------------------------
!
IF(senstvopt > 0) THEN
DO jazim=1,nazim
DO igate=1,ngate
IF(attrefl(igate,jazim) > sens(igate)) THEN
attradv(igate,jazim)=radv(igate,jazim)
ELSE
attrefl(igate,jazim)=rmisval
attradv(igate,jazim)=rmisval
END IF
END DO
END DO
ELSE
DO jazim=1,nazim
DO igate=1,ngate
attradv(igate,jazim)=radv(igate,jazim)
END DO
END DO
END IF
!
!-----------------------------------------------------------------------
!
! Report statistics
!
!-----------------------------------------------------------------------
!
denom=1./float(kntgate)
write(6,'(a,i9)') ' Total gates: ',kntgate
write(6,'(a,i9,f7.1,a)') ' Out-of-bounds Horiz: ',knthob, &
(100.*float(knthob)*denom),' percent'
write(6,'(a,i9,f7.1,a)') ' Above grid points: ',kntvob, &
(100.*float(kntvob)*denom),' percent'
write(6,'(a,i9,f7.1,a)') ' Ground-blocked points: ',kntbob, &
(100.*float(kntbob)*denom),' percent'
write(6,'(a,i9,f7.1,a)') ' Gates no echo: ',kntclr, &
(100.*float(kntclr)*denom),' percent'
write(6,'(a,i9,f7.1,a)') ' Gates interp refl: ',kntintr, &
(100.*float(kntintr)*denom),' percent'
write(6,'(a,i9,f7.1,a)') ' Gates interp rvel: ',kntintv, &
(100.*float(kntintv)*denom),' percent'
write(6,'(a,i9,f7.1,a)') ' Gates too few pts refl: ',kntfewr, &
(100.*float(kntfewr)*denom),' percent'
write(6,'(a,i9,f7.1,a)') ' Gates too few pts rvel: ',kntfewv, &
(100.*float(kntfewv)*denom),' percent'
write(6,'(a,f16.8,a,f16.8)') &
' Tilt min vert vort (*10**3)=',vvmin,' Max vert vort = ',vvmax
print *, ' Stats by azimuth, refl:'
DO jazim=1,nazim,30
reflmin=999.
reflmax=-999.
DO igate=1,ngate
IF(refl(igate,jazim) > refchk) THEN
reflmin=min(reflmin,refl(igate,jazim))
reflmax=max(reflmax,refl(igate,jazim))
END IF
END DO
print *, ' Azimuth,reflmin,reflmax=',azim(jazim),reflmin,reflmax
END DO
print *, ' Stats by azimuth, Attenuted refl:'
DO jazim=1,nazim,30
reflmin=999.
reflmax=-999.
DO igate=1,ngate
reflmin=min(reflmin,attrefl(igate,jazim))
reflmax=max(reflmax,attrefl(igate,jazim))
END DO
print *, ' Azimuth,reflmin,reflmax=',azim(jazim),reflmin,reflmax
END DO
CALL abss2ctim
(itimtilt,iyear,imon,iday,ihour,imin,isec)
itimcdf=itimtilt-itim1970
!
!-----------------------------------------------------------------------
!
! Write tilt netCDF file - Reflectivity
!
!-----------------------------------------------------------------------
!
IF( ifmt == 1) THEN
itimvol(itilt)=itimtilt
vnyqvol(itilt)=vnyqstl
DO igate=1,ngate
rngvol(igate,itilt)=igate*gatesp
END DO
DO jazim=1,nazim
elvvol(jazim,itilt)=elvang(itilt)
azmvol(jazim,itilt)=azim(jazim)
END DO
DO jazim=1,nazim
DO igate=1,ngate
refvol(igate,jazim,itilt)=attrefl(igate,jazim)
velvol(igate,jazim,itilt)=attradv(igate,jazim)
uarefvol(igate,jazim,itilt)=refl(igate,jazim)
uavelvol(igate,jazim,itilt)=radv(igate,jazim)
vorvol(igate,jazim,itilt)=vvort(igate,jazim)
END DO
END DO
ELSE IF( ifmt == 2 ) THEN
write(fname,'(a,i2.2,a,i2.2,a,i4.4,2(i2.2),a,3(i2.2),a)') &
'Reflectivity_',ielv,'.',felv,'_',iyear,imon,iday,'-', &
ihour,imin,isec,'.netcdf'
varname='Reflectivity'
CALL wtrftiltcdf
(ngate,maxazim,nazim,fname,outdir,varname, &
radname,radlata,radlona,radelv,vcp,elv, &
rmisval,rngfval,itimtilt,frtime,initime, &
vnyqstl,rfrgate, &
azim,beamw,gtspc,attrefl)
!
!-----------------------------------------------------------------------
!
! Write index record
!
!-----------------------------------------------------------------------
!
IF( creidx > 0 ) THEN
write(idxunit,'(a)') '<item>'
write(idxunit,'(a,f8.6,a,i10,a)') &
'<time fractional="',frtime,'">',itimcdf,'</time>'
write(idxunit,'(a,a,a,a)') '<params>netcdf {indexlocation} ', &
TRIM(fname),TRIM(cmprext),'</params>'
write(idxunit,'(a,i4.4,2i2.2,a,3i2.2,1x,a,1x,i2.2,a1,i2.2,a)')&
'<selections>',iyear,imon,iday,'-', &
ihour,imin,isec,'Reflectivity',ielv,'.',felv, &
'</selections>'
write(idxunit,'(a)') '</item>'
END IF ! creidx
!
!-----------------------------------------------------------------------
!
! Write tilt netCDF file - Velocity
!
!-----------------------------------------------------------------------
!
write(fname,'(a,i2.2,a,i2.2,a,i4.4,2(i2.2),a,3(i2.2),a)') &
'Velocity_',ielv,'.',felv,'_',iyear,imon,iday,'-', &
ihour,imin,isec,'.netcdf'
varname='RadialVelocity'
CALL wtvrtiltcdf
(ngate,maxazim,nazim,fname,outdir,varname, &
radname,radlat,radlon,radelv,vcp,elv, &
rmisval,rngfval,itimcdf,frtime,initime, &
vnyqstl,rfrgate, &
azim,beamw,gtspc,vnyq,attradv)
!
!-----------------------------------------------------------------------
!
! Write index record
!
!-----------------------------------------------------------------------
!
IF( creidx > 0 ) THEN
write(idxunit,'(a)') '<item>'
write(idxunit,'(a,f8.6,a,i10,a)') &
'<time fractional="',frtime,'">',itimcdf,'</time>'
write(idxunit,'(a,i4.4,2i2.2,a,3i2.2,1x,a,1x,i2.2,a1,i2.2,a)')&
'<selections>',iyear,imon,iday,'-', &
ihour,imin,isec,'Velocity',ielv,'.',felv, &
'</selections>'
write(idxunit,'(a)') '</item>'
END IF ! creidx
!
write(fname,'(a,i2.2,a,i2.2,a,i4.4,2(i2.2),a,3(i2.2),a)') &
'ReflectUnatten_',ielv,'.',felv,'_',iyear,imon,iday,'-', &
ihour,imin,isec,'.netcdf'
varname='UnattenuatedReflectivity'
CALL wtrftiltcdf
(ngate,maxazim,nazim,fname,outdir,varname, &
radname,radlata,radlona,radelv,vcp,elv, &
rmisval,rngfval,itimcdf,frtime,initime, &
vnyqstl,rfrgate, &
azim,beamw,gtspc,refl)
!
!-----------------------------------------------------------------------
!
! Write index record
!
!-----------------------------------------------------------------------
!
IF( creidx > 0 ) THEN
write(idxunit,'(a)') '<item>'
write(idxunit,'(a,f8.6,a,i10,a)') &
'<time fractional="',frtime,'">',itimcdf,'</time>'
write(idxunit,'(a,a,a,a)') '<params>netcdf {indexlocation} ', &
TRIM(fname),TRIM(cmprext),'</params>'
write(idxunit,'(a,i4.4,2i2.2,a,3i2.2,1x,a,1x,i2.2,a1,i2.2,a)')&
'<selections>',iyear,imon,iday,'-', &
ihour,imin,isec,'Reflectivity',ielv,'.',felv, &
'</selections>'
write(idxunit,'(a)') '</item>'
END IF ! creidx
!
!-----------------------------------------------------------------------
!
! Write tilt netCDF file - Velocity
!
!-----------------------------------------------------------------------
!
write(fname,'(a,i2.2,a,i2.2,a,i4.4,2(i2.2),a,3(i2.2),a)') &
'VelocityUnatten_',ielv,'.',felv,'_',iyear,imon,iday,'-', &
ihour,imin,isec,'.netcdf'
varname='UnattenuatedVelocity'
CALL wtvrtiltcdf
(ngate,maxazim,nazim,fname,outdir,varname, &
radname,radlat,radlon,radelv,vcp,elv, &
rmisval,rngfval,itimcdf,frtime,initime, &
vnyqstl,rfrgate, &
azim,beamw,gtspc,vnyq,radv)
!
!-----------------------------------------------------------------------
!
! Write index record
!
!-----------------------------------------------------------------------
!
IF( creidx > 0 ) THEN
write(idxunit,'(a)') '<item>'
write(idxunit,'(a,f8.6,a,i10,a)') &
'<time fractional="',frtime,'">',itimcdf,'</time>'
write(idxunit,'(a,i4.4,2i2.2,a,3i2.2,1x,a,1x,i2.2,a1,i2.2,a)')&
'<selections>',iyear,imon,iday,'-', &
ihour,imin,isec,'Velocity',ielv,'.',felv, &
'</selections>'
write(idxunit,'(a)') '</item>'
END IF ! creidx
!-----------------------------------------------------------------------
!
! Write tilt netCDF file - Vorticity
!
!-----------------------------------------------------------------------
!
write(fname,'(a,i2.2,a,i2.2,a,i4.4,2(i2.2),a,3(i2.2),a)') &
'Vorticity_',ielv,'.',felv,'_',iyear,imon,iday,'-', &
ihour,imin,isec,'.netcdf'
varname='VerticalVorticity'
CALL wtvvtiltcdf
(ngate,maxazim,nazim,fname,outdir,varname, &
radname,radlat,radlon,radelv,vcp,elv, &
rmisval,rngfval,itimcdf,frtime,initime, &
vnyqstl,rfrgate, &
azim,beamw,gtspc,vvort)
!
!-----------------------------------------------------------------------
!
! Write index record
!
!-----------------------------------------------------------------------
!
IF( creidx > 0 ) THEN
write(idxunit,'(a)') '<item>'
write(idxunit,'(a,f8.6,a,i10,a)') &
'<time fractional="',frtime,'">',itimcdf,'</time>'
write(idxunit,'(a,i4.4,2i2.2,a,3i2.2,1x,a,1x,i2.2,a1,i2.2,a)')&
'<selections>',iyear,imon,iday,'-', &
ihour,imin,isec,'Vorticity',ielv,'.',felv, &
'</selections>'
write(idxunit,'(a)') '</item>'
END IF ! creidx
END IF ! ifmt=2
IF(tmadvopt == 2) itimtilt=itimtilt+NINT(azmsect/rotrate)
!
END DO ! itilt
IF( ifmt == 1 ) THEN
write(fnamevol,'(4a,i4.4,i2.2,i2.2,a,i2.2,i2.2,i2.2,a)') &
TRIM(outdir),'/',TRIM(radname),'_',year,month,day,'_', &
hour,minute,second,'.vol'
CALL wtradvol
(fnamevol,ngate,ngate,maxazim,nelev, &
rngvol,azmvol,elvvol,velvol,uavelvol, &
vorvol,vnyqvol,itimvol, &
rngvol,azmvol,elvvol,refvol,uarefvol, &
wrtuaref,wrtuavel,wrtvort, &
runname,radname,vcp,curtim,beamwid, &
rmisval,rngfval,radelv,radlat,radlon)
END IF
!
!-----------------------------------------------------------------------
!
! Release memory for gridded data
!
!-----------------------------------------------------------------------
WRITE(6,'(a)') ' Deallocating grid memory'
!
deallocate(usc)
deallocate(vsc)
deallocate(wsc)
deallocate(latsc)
deallocate(lonsc)
deallocate(azmsc)
deallocate(sfcr)
deallocate(elvsc)
deallocate(rngsc)
deallocate(vort)
deallocate(vrsc)
deallocate(ref)
deallocate(refz)
deallocate(cmpref)
!
! Release memory for polar coordinate radar data
!
WRITE(6,'(a)') ' Deallocating radar tilt memory'
deallocate(azim)
deallocate(beamw)
deallocate(gtspc)
deallocate(vnyq)
deallocate(radv)
deallocate(attradv)
deallocate(refl)
deallocate(attrefl)
deallocate(stdvr)
deallocate(vvort)
deallocate(sens)
WRITE(6,'(a)') ' Deallocating radar volume memory'
IF( ifmt == 1 ) THEN
deallocate(itimvol)
deallocate(vnyqvol)
deallocate(rngvol)
deallocate(azmvol)
deallocate(elvvol)
deallocate(refvol)
deallocate(uarefvol)
deallocate(velvol)
deallocate(uavelvol)
deallocate(vorvol)
END IF
WRITE(6,'(a)') ' End of file loop'
!
END DO ! ifile loop
!
! Finish index file and close it out
!
IF( creidx > 0 .AND. ifmt == 2 ) THEN
write(idxunit,'(a)') '</codeindex>'
CLOSE(idxunit)
CALL retunit(idxunit)
END IF
STOP
END PROGRAM rademul
SUBROUTINE termvel(refl,hgtmsl,vt) 3
!
!-----------------------------------------------------------------------
!
! Calculates the precipitation terminal velocity from
! the observed radial velocity. From Zeigler, 1978.
!
! An empirical formula based on the reflectivity is
! used to estimate the terminal velocity.
!
! For simplicity, atmospheric density is approxmated
! by a standard atmosphere, rho(z)=rhonot exp(-z/h0)
!
!-----------------------------------------------------------------------
!
!
IMPLICIT NONE
REAL :: refl
REAL :: hgtmsl
REAL :: vt
!
REAL, PARAMETER :: zfrez=3000.
REAL, PARAMETER :: zice=8000.
REAL, PARAMETER :: rho0=1.2250
REAL, PARAMETER :: h0=7000.
REAL, PARAMETER :: denom=(1./(zice-zfrez))
REAL, PARAMETER :: dbzmin=10.
REAL, PARAMETER :: dbzmax=100.
!
REAL :: refz,rhofact,s1,s2
!
refz=10.**(0.1*refl)
rhofact=EXP(0.4*hgtmsl/h0)
IF(hgtmsl < zfrez) THEN
vt=2.6*(refz**0.107)*rhofact
ELSE IF(hgtmsl < zice) THEN
s1=(zice-hgtmsl)*denom
s2=2.*(hgtmsl-zfrez)*denom
vt=s1*2.6*(refz**0.107)*rhofact + s2
ELSE
vt=2.0
END IF
RETURN
END SUBROUTINE termvel
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE WTRADVOL ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE wtradvol(fnamevol,maxgatevel,maxgateref,maxazim,maxelev, & 1,1
rngvvol,azmvvol,elvvvol,velvol,uavelvol, &
vorvol,vnyqvol,itimvol, &
rngrvol,azmrvol,elvrvol,refvol,uarefvol, &
wrtuaref,wrtuavel,wrtvort, &
runname,radname,vcp,curtim,beamwid, &
rmisval,rngfval,radar_alt,radar_lat,radar_lon)
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Write out radar observations in radar coordinate
!
!-----------------------------------------------------------------------
!
! AUTHOR: Ming Hu, CAPS
!
! MODIFICATION HISTORY:
! Converted to subroutine WTRADVOL, Keith Brewster
!
! 11/13/2004 Keith Brewster, CAPS
! Updated to write more variables for use by radbin2cdf
!
! 05/24/2005 Keith Brewster, CAPS
! Added unattenuated variables and variable write switches
!
!-----------------------------------------------------------------------
!
! INPUT :
!
! maxgate Maximum gates in a radial
! maxazim Maximum radials per tilt
! maxelev Maximum number of tilts
!
IMPLICIT NONE
!
CHARACTER (LEN=256), INTENT(IN) :: fnamevol
INTEGER, INTENT(IN) :: maxgatevel
INTEGER, INTENT(IN) :: maxgateref
INTEGER, INTENT(IN) :: maxazim
INTEGER, INTENT(IN) :: maxelev
INTEGER, INTENT(IN) :: itimvol(maxelev)
REAL, INTENT(IN) :: rngvvol(maxgatevel,maxelev)
REAL, INTENT(IN) :: azmvvol(maxazim,maxelev)
REAL, INTENT(IN) :: elvvvol(maxazim,maxelev)
REAL, INTENT(IN) :: velvol(maxgatevel,maxazim,maxelev)
REAL, INTENT(IN) :: uavelvol(maxgatevel,maxazim,maxelev)
REAL, INTENT(IN) :: vorvol(maxgatevel,maxazim,maxelev)
REAL, INTENT(IN) :: vnyqvol(maxelev)
REAL, INTENT(IN) :: rngrvol(maxgateref,maxelev)
REAL, INTENT(IN) :: azmrvol(maxazim,maxelev)
REAL, INTENT(IN) :: elvrvol(maxazim,maxelev)
REAL, INTENT(IN) :: refvol(maxgateref,maxazim,maxelev)
REAL, INTENT(IN) :: uarefvol(maxgateref,maxazim,maxelev)
INTEGER, INTENT(IN) :: wrtuaref,wrtuavel,wrtvort
CHARACTER (LEN=80 ), INTENT(IN) :: runname
CHARACTER (LEN=4 ), INTENT(IN) :: radname
REAL, INTENT(IN) :: beamwid,rmisval,rngfval
INTEGER, INTENT(IN) :: vcp
REAL, INTENT(IN) :: curtim
REAL, INTENT(IN) :: radar_alt
REAL, INTENT(IN) :: radar_lat
REAL, INTENT(IN) :: radar_lon
!
!-----------------------------------------------------------------------
!
! Misc local variables
!
!-----------------------------------------------------------------------
!
INTEGER :: iyear,imon,iday,ihour,imin,isec,idummy
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
idummy=0
CALL abss2ctim
(itimvol(1),iyear,imon,iday,ihour,imin,isec)
!
!-----------------------------------------------------------------------
!
! Open file for output
!
!-----------------------------------------------------------------------
!
WRITE(6,'(a,a)') 'Opening: ',TRIM(fnamevol)
OPEN(13,FILE=trim(fnamevol),STATUS='unknown', &
FORM='unformatted')
WRITE(13) runname
WRITE(13) radname
WRITE(13) maxgatevel,maxgateref,maxazim,maxelev
WRITE(13) iyear,imon,iday,ihour,imin,isec
WRITE(13) radar_alt,radar_lat,radar_lon
WRITE(13) vcp,beamwid,rmisval,rngfval,curtim
WRITE(13) wrtuaref,wrtuavel,wrtvort, &
idummy,idummy,idummy,idummy,idummy
WRITE(13) itimvol
WRITE(13) rngrvol
WRITE(13) azmrvol
WRITE(13) elvrvol
WRITE(13) refvol
IF(wrtuaref /= 0) WRITE(13) uarefvol
WRITE(13) vnyqvol
WRITE(13) rngvvol
WRITE(13) azmvvol
WRITE(13) elvvvol
WRITE(13) velvol
IF(wrtuavel /= 0) WRITE(13) uavelvol
IF(wrtvort /= 0) WRITE(13) vorvol
close(13)
WRITE(6,'(a,a)') ' Writing complete for file ',TRIM(fnamevol)
RETURN
END SUBROUTINE wtradvol
!
SUBROUTINE xbatten(ngate,maxazim,nazim, & 2
refl,gatesp,rmisval,refmin,attrefl)
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Calculate X-band (3.2 cm) attenuated reflectivity given unattenuated
! reflectivty (from S-band data or from simulation model hydrometeors)
! for a single tilt of data.
!
! Uses attenuation coefficients from Burrows and Atwood (1949) data as
! reported in Doviak and Zrnic', Doppler Radar and Weather Observations,
! 2nd Ed., Eq. 3.16c.
!
!-----------------------------------------------------------------------
!
! AUTHOR: Keith Brewster, CAPS and Erin Fay, OU/SoM
! November, 2004
!
! MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
! INPUT:
!
! ngate: Number of gates in each radial
! nazim: Number of radials of data
! refl: Unattenuated reflectivity factor dBZ
! gatesp: Gate spacing (m)
! rmisval: Missing data value, assumed below threshold
! refmin: Threshold minimum reflectivity (dBZ)
!
!
! OUTPUT:
! attrefl: Attenuated reflectivity.
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
INTEGER, INTENT (IN) :: ngate ! Number of gates
INTEGER, INTENT (IN) :: maxazim ! Maximum number of radials
INTEGER, INTENT (IN) :: nazim ! Number of radials
REAL, INTENT (IN):: refl(ngate,maxazim) ! Reflectivity (dBZ)
REAL, INTENT (IN) :: gatesp ! Gate spacing (m)
REAL, INTENT (IN) :: rmisval
REAL, INTENT (IN) :: refmin
REAL, INTENT (OUT) :: attrefl(ngate,maxazim) ! Attenuated reflectivities
INTEGER :: igate,jazim ! Index.
REAL :: att_tally ! Running tally of attenuation values.
REAL :: att_const1 ! Attenuation constant 1.
REAL :: att_const2 ! Attenuation constant 2.
REAL :: att_exp ! Attenuation exponent
REAL :: atten,atten_last,hlfgatsp
REAL, PARAMETER :: zrconst=400.
REAL, PARAMETER :: zrexp=1.4
REAL, PARAMETER :: krconst=0.01
REAL, PARAMETER :: krexp=1.21
REAL, PARAMETER :: mperkm=0.001
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
att_const1 = 2.0*krconst*mperkm ! leading constant (two-way)
att_const2 = 1.0/zrconst
att_exp = krexp/zrexp
hlfgatsp = 0.5*gatesp
DO jazim=1, nazim
IF(refl(1,jazim) .gt. rmisval) THEN
atten = &
att_const1*((att_const2*(10.0**(0.1*refl(1,jazim))))**att_exp)
att_tally = atten*hlfgatsp
attrefl(1,jazim) = refl(1,jazim)-att_tally
attrefl(1,jazim) = max(attrefl(1,jazim),refmin)
ELSE
atten=0.
att_tally=0.
attrefl(1,jazim)=refl(1,jazim)
END IF
atten_last=atten
DO igate = 2, ngate
IF(refl(igate,jazim) .gt. rmisval) THEN
atten = &
att_const1*((att_const2*(10.0**(0.1*refl(igate,jazim))))**att_exp)
att_tally = att_tally + hlfgatsp*atten_last + hlfgatsp*atten
attrefl(igate,jazim) = refl(igate,jazim)-att_tally
attrefl(igate,jazim) = max(attrefl(igate,jazim),refmin)
atten_last=atten
ELSE
attrefl(igate,jazim) = refl(igate,jazim)
attrefl(igate,jazim) = max(attrefl(igate,jazim),refmin)
atten_last=0.
END IF
END DO
END DO
RETURN
END SUBROUTINE xbatten
SUBROUTINE xbsens(ngate,gatesp,pulselen,beamwid,sens) 2
!
!-----------------------------------------------------------------------
! Subroutine xbsens
! Calculate X-band radar sensitivity (dBZ) as a function of range.
!
! Based on information provided by Francesc Junyent
!
! Keith Brewster and Erin Fay, CAPS
!-----------------------------------------------------------------------
!
IMPLICIT NONE
INTEGER, INTENT(IN) :: ngate
REAL, INTENT(IN) :: gatesp
REAL, INTENT(IN) :: pulselen
REAL, INTENT(IN) :: beamwid
REAL, INTENT (OUT):: sens(ngate) ! Sensitivity values for all dist from radar.
!
! Parameters for CASA radar
!
REAL, PARAMETER :: lmbda = 3.0E-02 ! Wavelength (m)
REAL, PARAMETER :: pt = 12500 ! Peak power (Watts)
REAL, PARAMETER :: G = 38.0 ! Antenna gain (dB)
REAL, PARAMETER :: F = 5.5 ! Noise figure (dB)
REAL, PARAMETER :: B = 2.5 ! Bandwidth (MHz)
REAL, PARAMETER :: lm = 1.0 ! Receiver mis-match loss(dB)
REAL, PARAMETER :: Kw2 = 0.91 ! Refractive Index of water
REAL, PARAMETER :: T0 = 300. ! Rx temperature (K)
REAL, PARAMETER :: Ta = 200. ! Antenna temperature (K)
!
! Physical constants
!
REAL, PARAMETER :: K = 1.38E-23 ! Boltsmann's Constant (J/K)
REAL, PARAMETER :: c = 2.99792E08 ! Speed of light (m/s)
REAL, PARAMETER :: rconst =1.0E18 ! m6/m3 to mm6/m3
!
! Misc internal variables
!
INTEGER :: igate,ntilt
REAL :: pulsel,pulsew
REAL :: ln2,pi,pi3,four3,bwrad,rnoise,BHz,Ni,sconst,rlm,rG
REAL :: range
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
ln2=log(2.0)
pi=acos(-1.)
pi3=pi*pi*pi
four3=4.*4.*4.
bwrad=beamwid*pi/180.
rnoise=10.**(0.1*F)
rlm=10.**(0.1*lm)
rG=10.**(0.1*G)
BHz=1.0E06*b
Ni=K*(Ta+(rnoise-1.0)*T0)*BHz
sconst=rconst *(Ni/(pi3*Kw2)) * ((8.*ln2)/(bwrad*bwrad)) * &
(2./(c*pulselen)) * ((lmbda*lmbda*four3*rlm)/(Pt*rG*rG))
print *, ' pulselen=',pulselen
print *, ' beamwid=',beamwid
print *, ' Sensitivity................'
DO igate = 1, ngate
range=igate*gatesp
sens(igate) = 10.*LOG10(range*range*sconst)
IF(mod(igate,10) == 0) print *, (0.001*range),sens(igate)
END DO
END SUBROUTINE xbsens
FUNCTION EFFBMW(beamwid,rotrate,prt,npulse)
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Estimate effective half-power beamwidth given the antenna half-power
! beamwidth, the rotation rate, pulse repetition time and the number of
! pulses used in estimating the moment data.
!
! Based on solutions to Eq. 7.34 in Doviak and Zrnic',
! Doppler Radar and Weather Observations, 2nd Ed. (1993)
!
! AUTHOR: Keith Brewster, CAPS
! November, 2004
!
! INPUT:
! beamwid Half-power antenna beamwidth (degrees)
! rotrate Rotation rate (degrees per second)
! prt Pulse repetition time (seconds)
! npulse Number of pulses averaged to get moment data
!
! OUTPUT:
! effbmw Effective half-power beamwidth (degrees)
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
!
REAL :: effbmw
!
REAL :: beamwid
REAL :: rotrate
REAL :: prt
INTEGER :: npulse
!
!-----------------------------------------------------------------------
!
! Misc local variables
!
!-----------------------------------------------------------------------
!
INTEGER, PARAMETER :: ntry=30
REAL,PARAMETER :: eps = 1.0E-06
!
REAL :: sqrtln4,twortln4,bmwinv,amts,erfcst
REAL :: gtheta,theta,test,test0,test2,delth
REAL :: theta1,theta2
INTEGER :: itry
!
!-----------------------------------------------------------------------
!
! External functions
!
!-----------------------------------------------------------------------
!
REAL :: erf
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
sqrtln4=sqrt(alog(4.))
twortln4=2.0*sqrtln4
bmwinv=1.0/beamwid
amts=abs(rotrate)*npulse*prt
erfcst=0.5*erf(sqrtln4*amts*bmwinv)
!
!-----------------------------------------------------------------------
!
! Iteratively solve for zeros. First for positive solution angle.
!
!-----------------------------------------------------------------------
!
gtheta=beamwid+amts
theta=0.
test0=erf(twortln4*theta*bmwinv)-erf(twortln4*(theta-amts)*bmwinv)- &
erfcst
delth=gtheta
theta=gtheta
test2=erf(twortln4*theta*bmwinv)-erf(twortln4*(theta-amts)*bmwinv)- &
erfcst
DO itry=1,ntry
delth=0.5*sign(delth,(test0*test2))
theta=theta+delth
test2=erf(twortln4*theta*bmwinv)-erf(twortln4*(theta-amts)*bmwinv)- &
erfcst
IF(abs(test2) < eps) EXIT
END DO
theta2=theta
WRITE(6,'(a,f10.4,a,g12.4,a,i3)') &
' EFFBMW Positive sol, theta=',theta2,' diffr=',test2, &
' iter=',itry
!
!-----------------------------------------------------------------------
!
! Solve for negative solution angle.
!
!-----------------------------------------------------------------------
!
theta=-gtheta
test0=erf(twortln4*theta*bmwinv)-erf(twortln4*(theta-amts)*bmwinv)- &
erfcst
delth=gtheta
theta=0.
test2=erf(twortln4*theta*bmwinv)-erf(twortln4*(theta-amts)*bmwinv)- &
erfcst
DO itry=1,ntry
delth=0.5*sign(delth,(test0*test2))
theta=theta+delth
test2=erf(twortln4*theta*bmwinv)-erf(twortln4*(theta-amts)*bmwinv)- &
erfcst
IF(abs(test2) < eps) EXIT
END DO
theta1=theta
WRITE(6,'(a,f10.4,a,g12.4,a,i3)') &
' EFFBMW Negative sol, theta=',theta1,' diffr=',test2, &
' iter=',itry
!
!-----------------------------------------------------------------------
!
! Effective beamwidth is difference between positive and negative
! solution angles.
!
!-----------------------------------------------------------------------
!
effbmw=(theta2-theta1)
WRITE(6,'(a,f12.4,a)') &
' EFFBMW Effective half-power beamwidth =',effbmw,' degrees'
RETURN
END FUNCTION EFFBMW
!
FUNCTION RANDNOR()
!
! Returns a random number with a normal (Gaussian) distribution
! with a mean of zero and standard deviation of one.
! A distribution with a mean of m and standard deviation of s would
! use the result of this function in the following way:
! x = m + s*randnor()
!
! The algorithm used here to convert a uniform random distribution (0,1)
! to a Gaussian is the polar form of the Box-Muller transformation. This
! code based on sample C code and a description of the technique given
! by Dr. Everett Carter of Taygeta Scientific on the following website:
! http://www.taygeta.com/random/gaussian.html
!
! I've added a test to avoid dividing by zero, rsq > epsilon, which doesn't
! seem to affect the statistics of the distribution.
!
! random_number is a fortran-90 intrinsic function. Implementation on
! different machines and compilers may vary.
!
! Keith Brewster, CAPS
! August, 2004
!
! MODIFICATIONS
!
! 02/28/2005 Keith Brewster
! Replaced intrinsic function rand with random_number, that seems to be
! available on more machines than "rand".
!
!
IMPLICIT NONE
REAL, PARAMETER :: epsilon = 1.0E-12
REAL :: randnor
REAL :: xr,yr,rsq,r
REAL :: myranf
DO
xr = 2.*myranf() - 1.
yr = 2.*myranf() - 1.
rsq = xr*xr + yr*yr
IF(rsq < 1.0 .AND. rsq > epsilon) EXIT
END DO
r = sqrt( (-2.0 * log( rsq ) ) / rsq )
randnor = xr * r
RETURN
END FUNCTION RANDNOR
REAL FUNCTION myranf ()
!
! A simple random number generator provided by Vijay Lakamraju UMASS, ECE
! as ranf is not implemented on all compilers.
!
! Generates a random number between 0 and 1.
!
INTEGER L, C, M
PARAMETER ( L = 1029, C = 221591, M = 1048576 )
INTEGER SEED
SAVE SEED
DATA SEED / 0 /
SEED = MOD ( SEED * L + C, M )
myranf = REAL ( SEED ) / M
RETURN
END FUNCTION myranf
!
!##################################################################
!##################################################################
!###### ######
!###### FUNCTION ERF ######
!###### ######
!##################################################################
!##################################################################
!
FUNCTION erf(x)
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! ERF computes the error function.
!
!
! Definition:
!
! ERF(X) = ( 2 / SQRT ( PI ) ) * Integral ( 0 <= T <= X ) EXP ( -T**2 ) dT
!
!
! Reference:
!
! David Kahaner, Clever Moler, Steven Nash,
! Numerical Methods and Software,
! Prentice Hall, 1988.
!
! INPUT:
!
! real x, the argument of the error function.
!
! OUTPUT:
! real erf, the value of the error function at X.
!
!
! AUTHOR: John Burkardt, Pittsburgh Supercomputing Center
! NMS Fortran Software Package
!
! MODIFICATION HISTORY:
! 23-Oct-2004 Modified for ARPS Standard Fortran-90
! Keith Brewster, CAPS Univ of Oklahoma
!
!-----------------------------------------------------------------------
!
! Variable Declarations.
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
!
REAL :: x
REAL :: erf
!
REAL :: csevl
REAL :: erfc
!
REAL :: erfcs(13)
INTEGER inits
REAL :: r1mach
REAL :: sqeps
REAL :: sqrtpi
REAL :: y
!
REAL, SAVE :: xbig = 0.
INTEGER, SAVE :: nterf = 0
!
data erfcs( 1) / -0.049046121234691808 /
data erfcs( 2) / -0.14226120510371364 /
data erfcs( 3) / 0.010035582187599796 /
data erfcs( 4) / -0.000576876469976748 /
data erfcs( 5) / 0.000027419931252196 /
data erfcs( 6) / -0.000001104317550734 /
data erfcs( 7) / 0.000000038488755420 /
data erfcs( 8) / -0.000000001180858253 /
data erfcs( 9) / 0.000000000032334215 /
data erfcs(10) / -0.000000000000799101 /
data erfcs(11) / 0.000000000000017990 /
data erfcs(12) / -0.000000000000000371 /
data erfcs(13) / 0.000000000000000007 /
data sqeps / 0. /
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
sqrtpi=sqrt(acos(-1.))
!
IF ( nterf == 0 ) THEN
nterf = inits ( erfcs, 13, 0.1*r1mach(3) )
xbig = sqrt ( - log ( sqrtpi * r1mach(3) ) )
sqeps = sqrt ( 2. * epsilon ( sqeps ) )
END IF
y = abs ( x )
IF ( y <= sqeps ) THEN
erf = 2.0 * x / sqrtpi
ELSE IF ( y <= 1.0 ) THEN
erf = x * ( 1. + csevl ( (2.*x*x - 1.), erfcs, nterf ) )
ELSE IF ( y <= xbig ) THEN
erf = sign ( 1. - erfc ( y ), x )
ELSE
erf = sign ( 1., x )
END IF
RETURN
END FUNCTION erf
!
!
!##################################################################
!##################################################################
!###### ######
!###### FUNCTION ERFC ######
!###### ######
!##################################################################
!##################################################################
!
FUNCTION erfc ( x )
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! erfc(x) calculates the single precision complementary error
! function for single precision argument x.
!
!
! Reference:
!
! David Kahaner, Clever Moler, Steven Nash,
! Numerical Methods and Software,
! Prentice Hall, 1988.
!
!
! series for erf on the interval 0. to 1.00000d+00
! with weighted error 7.10e-18
! log weighted error 17.15
! significant figures required 16.31
! decimal places required 17.71
!
! series for erfc on the interval 0. to 2.50000d-01
! with weighted error 4.81e-17
! log weighted error 16.32
! approx significant figures required 15.0E+00
!
!
! series for erc2 on the interval 2.50000d-01 to 1.00000d+00
! with weighted error 5.22e-17
! log weighted error 16.28
! approx significant figures required 15.0E+00
! decimal places required 16.96
!
!
! AUTHOR: John Burkardt, Pittsburgh Supercomputing Center
! NMS Fortran Software Package
!
! MODIFICATION HISTORY:
! 23-Oct-2004 Modified for ARPS Standard Fortran-90
! Keith Brewster, CAPS Univ of Oklahoma
!
!-----------------------------------------------------------------------
!
! Variable Declarations.
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
!
REAL :: erfc
REAL :: x
!
REAL :: csevl
REAL :: r1mach
!
REAL :: erfcs(13)
REAL :: erfccs(24)
REAL :: erc2cs(23)
REAL :: eta
INTEGER :: inits
INTEGER :: nterc2
INTEGER :: nterf
INTEGER :: nterfc
REAL :: sqeps
REAL :: sqrtpi
REAL :: xmax
REAL :: xsml
REAL :: y
!
data erfcs( 1) / -.049046121234691808e0 /
data erfcs( 2) / -.14226120510371364e0 /
data erfcs( 3) / .010035582187599796e0 /
data erfcs( 4) / -.000576876469976748e0 /
data erfcs( 5) / .000027419931252196e0 /
data erfcs( 6) / -.000001104317550734e0 /
data erfcs( 7) / .000000038488755420e0 /
data erfcs( 8) / -.000000001180858253e0 /
data erfcs( 9) / .000000000032334215e0 /
data erfcs(10) / -.000000000000799101e0 /
data erfcs(11) / .000000000000017990e0 /
data erfcs(12) / -.000000000000000371e0 /
data erfcs(13) / .000000000000000007e0 /
data erc2cs( 1) / -.069601346602309501e0 /
data erc2cs( 2) / -.041101339362620893e0 /
data erc2cs( 3) / .003914495866689626e0 /
data erc2cs( 4) / -.000490639565054897e0 /
data erc2cs( 5) / .000071574790013770e0 /
data erc2cs( 6) / -.000011530716341312e0 /
data erc2cs( 7) / .000001994670590201e0 /
data erc2cs( 8) / -.000000364266647159e0 /
data erc2cs( 9) / .000000069443726100e0 /
data erc2cs(10) / -.000000013712209021e0 /
data erc2cs(11) / .000000002788389661e0 /
data erc2cs(12) / -.000000000581416472e0 /
data erc2cs(13) / .000000000123892049e0 /
data erc2cs(14) / -.000000000026906391e0 /
data erc2cs(15) / .000000000005942614e0 /
data erc2cs(16) / -.000000000001332386e0 /
data erc2cs(17) / .000000000000302804e0 /
data erc2cs(18) / -.000000000000069666e0 /
data erc2cs(19) / .000000000000016208e0 /
data erc2cs(20) / -.000000000000003809e0 /
data erc2cs(21) / .000000000000000904e0 /
data erc2cs(22) / -.000000000000000216e0 /
data erc2cs(23) / .000000000000000052e0 /
data erfccs( 1) / 0.0715179310202925e0 /
data erfccs( 2) / -.026532434337606719e0 /
data erfccs( 3) / .001711153977920853e0 /
data erfccs( 4) / -.000163751663458512e0 /
data erfccs( 5) / .000019871293500549e0 /
data erfccs( 6) / -.000002843712412769e0 /
data erfccs( 7) / .000000460616130901e0 /
data erfccs( 8) / -.000000082277530261e0 /
data erfccs( 9) / .000000015921418724e0 /
data erfccs(10) / -.000000003295071356e0 /
data erfccs(11) / .000000000722343973e0 /
data erfccs(12) / -.000000000166485584e0 /
data erfccs(13) / .000000000040103931e0 /
data erfccs(14) / -.000000000010048164e0 /
data erfccs(15) / .000000000002608272e0 /
data erfccs(16) / -.000000000000699105e0 /
data erfccs(17) / .000000000000192946e0 /
data erfccs(18) / -.000000000000054704e0 /
data erfccs(19) / .000000000000015901e0 /
data erfccs(20) / -.000000000000004729e0 /
data erfccs(21) / .000000000000001432e0 /
data erfccs(22) / -.000000000000000439e0 /
data erfccs(23) / .000000000000000138e0 /
data erfccs(24) / -.000000000000000048e0 /
data nterf, nterfc, nterc2, xsml, xmax, sqeps /3*0, 3*0./
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
sqrtpi=sqrt(acos(-1.))
IF ( nterf == 0 ) THEN
eta = 0.1 * r1mach(3)
nterf = inits ( erfcs, 13, eta )
nterfc = inits ( erfccs, 24, eta )
nterc2 = inits ( erc2cs, 23, eta )
xsml = -sqrt ( - log ( sqrtpi * r1mach(3) ) )
xmax = sqrt ( - log ( sqrtpi * r1mach(1) ) )
xmax = xmax - 0.5 * log ( xmax ) / xmax - 0.01
sqeps = sqrt ( 2. * r1mach(3) )
END IF
IF ( x <= xsml ) THEN
erfc = 2.
RETURN
END IF
IF ( x > xmax ) THEN
WRITE(6,'(a)') 'erfc x so big erfc underflows'
erfc = 0.
RETURN
END IF
y = abs(x)
IF (y>1.0) THEN
!
! erfc(x) = 1.0E+00 - erf(x) for 1. < abs(x) <= xmax
!
y = y*y
IF (y<=4.) THEN
erfc = exp(-y)/abs(x) * (0.5 + csevl ((8./y-5.)/3.,erc2cs, nterc2) )
ELSE
erfc = exp(-y)/abs(x) * (0.5 + csevl (8./y-1.,erfccs, nterfc) )
END IF
IF ( x < 0.0 ) erfc = 2.0 - erfc
RETURN
ELSE
!
! erfc(x) = 1. - erf(x) for -1. <= x <= 1.
!
IF ( y < sqeps ) THEN
erfc = 1.0 - 2.0*x/sqrtpi
ELSE IF (y>=sqeps) THEN
erfc = 1.0 - x*(1.0 + csevl((2.0*x*x-1.0), erfcs, nterf) )
END IF
RETURN
END IF
END FUNCTION erfc
!
!##################################################################
!##################################################################
!###### ######
!###### FUNCTION CSEVL ######
!###### ######
!##################################################################
!##################################################################
!
FUNCTION csevl ( x, cs, n )
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! CSEVL evaluates an N term Chebyshev series.
!
!
! Reference:
!
! R Broucke,
! algorithm 446, c.a.c.m.,
! volume 16, page 254, 1973.
!
! Fox and Parker,
! chebyshev polynomials in numerical analysis,
! oxford press, page 56.
!
! David Kahaner, Clever Moler, Steven Nash,
! Numerical Methods and Software,
! Prentice Hall, 1988.
!
! INPUT:
!
! x value at which the series is to be evaluated.
! cs array of n terms of a chebyshev series. in eval-
! uating cs, only half the first coefficient is summed.
! n number of terms in array cs.
!
!
! AUTHOR: John Burkardt, Pittsburgh Supercomputing Center
! NMS Fortran Software Package
!
! MODIFICATION HISTORY:
! 23-Oct-2004 Modified for ARPS Standard Fortran-90
! Keith Brewster, CAPS Univ of Oklahoma
!
!-----------------------------------------------------------------------
!
! Variable Declarations.
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
!
REAL :: csevl
INTEGER :: n
REAL :: x
REAL :: cs(n)
!
REAL :: b0
REAL :: b1
REAL :: b2
INTEGER :: i
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
IF ( n < 1 ) THEN
WRITE ( *, * ) ' '
WRITE ( *, * ) 'CSEVL - Fatal error!'
WRITE ( *, * ) ' Number of terms N is less than 1.'
STOP
END IF
IF ( n > 1000 ) THEN
WRITE ( *, * ) ' '
WRITE ( *, * ) 'CSEVL - Fatal error!'
WRITE ( *, * ) ' The number of terms is more than 1000.'
STOP
END IF
IF ( x < -1.0 .or. x > 1.0 ) THEN
WRITE ( *, * ) ' '
WRITE ( *, * ) 'CSEVL - Fatal error!'
WRITE ( *, * ) ' The input argument X is outside the interval [-1,1].'
STOP
END IF
b1 = 0.
b0 = 0.
DO i = n, 1, -1
b2 = b1
b1 = b0
b0 = 2.*x*b1 - b2 + cs(i)
END DO
csevl = 0.5*(b0-b2)
RETURN
END FUNCTION csevl
!
!##################################################################
!##################################################################
!###### ######
!###### FUNCTION INITS ######
!###### ######
!##################################################################
!##################################################################
!
FUNCTION inits ( os, nos, eta )
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
!
! INITS estimates the order of an orthogonal series guaranteeing a given accuracy.
!
!
! Reference:
!
! David Kahaner, Clever Moler, Steven Nash,
! Numerical Methods and Software,
! Prentice Hall, 1988.
!
!
! INPUT:
!
! os array of nos coefficients in an orthogonal series.
! nos number of coefficients in os.
! eta requested accuracy of series.
! Ordinarily, eta will be chosen to be one-tenth machine precision.
!
!
! AUTHOR: John Burkardt, Pittsburgh Supercomputing Center
! NMS Fortran Software Package
!
! MODIFICATION HISTORY:
! 23-Oct-2004 Modified for ARPS Standard Fortran-90
! Keith Brewster, CAPS Univ of Oklahoma
!
!-----------------------------------------------------------------------
!
! Variable Declarations.
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
INTEGER :: inits
INTEGER :: nos
REAL :: eta
!
INTEGER :: ii,i
REAL :: err
REAL :: os(nos)
!
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
IF ( nos < 1) THEN
WRITE(6,'(a)') 'inits number of coefficients lt 1'
STOP
END IF
err = 0.
DO ii=1,nos
i = nos + 1 - ii
err = err + abs(os(i))
if (err>eta) EXIT
END DO
if (i==nos) WRITE(6,'(a)') 'inits eta may be too small'
inits = i
RETURN
END FUNCTION inits
!
!##################################################################
!##################################################################
!###### ######
!###### FUNCTION ERF ######
!###### ######
!##################################################################
!##################################################################
!
!
FUNCTION r1mach ( i )
!
!*******************************************************************************
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! R1MACH returns single precision machine constants.
!
!
! Assume that single precision numbers are stored with a mantissa of T digits
! in base B, with an exponent whose value must lie between EMIN and EMAX. Then
! for values of I between 1 and 5, R1MACH will return the following values:
!
! R1MACH(1) = B**(EMIN-1), the smallest positive magnitude.
! R1MACH(2) = B**EMAX*(1-B**(-T)), the largest magnitude.
! R1MACH(3) = B**(-T), the smallest relative spacing.
! R1MACH(4) = B**(1-T), the largest relative spacing.
! R1MACH(5) = log10(B)
!
! To alter this function for a particular environment, the desired set of data
! statements should be activated by removing the C from column 1.
!
! On rare machines a STATIC statement may need to be added. But probably more
! systems prohibit it that require it.
!
! For IEEE-arithmetic machines (binary standard), the first set of constants
! below should be appropriate.
!
! Where possible, octal or hexadecimal constants have been used to specify the
! constants exactly which has in some cases required the use of EQUIVALENCED
! integer arrays. If your compiler uses half-word integers by default
! (sometimes called INTEGER*2), you may need to change INTEGER to INTEGER*4 or
! otherwise instruct your compiler to use full-word integers in the next 5
! declarations.
!
!
! AUTHOR: John Burkardt, Pittsburgh Supercomputing Center
! NMS Fortran Software Package
!
! MODIFICATION HISTORY:
! 23-Oct-2004 Modified for ARPS Standard Fortran-90
! Keith Brewster, CAPS Univ of Oklahoma
!
!-----------------------------------------------------------------------
!
! Variable Declarations.
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
REAL :: r1mach
INTEGER :: i
!
INTEGER :: diver(2)
INTEGER :: large(2)
INTEGER :: ilog10(2)
INTEGER :: right(2)
REAL :: rmach(5)
INTEGER ::small(2)
!
equivalence (rmach(1),small(1))
equivalence (rmach(2),large(1))
equivalence (rmach(3),right(1))
equivalence (rmach(4),diver(1))
equivalence (rmach(5),ilog10(1))
!
! IEEE arithmetic machines, such as the ATT 3B series, Motorola 68000 based
! machines such as the SUN 3 and ATT PC 7300, and 8087 based micros such as
! the IBM PC and ATT 6300.
!
! data small(1) / 8388608 /
! data large(1) / 2139095039 /
! data right(1) / 864026624 /
! data diver(1) / 872415232 /
! data ilog10(1) / 1050288283 /
!
! ALLIANT FX/8 UNIX Fortran compiler with the -r8 command line option. This
! option causes all variables declared with 'REAL' to be of type 'REAL*8' or
! DOUBLE PRECISION. This option does not override the 'REAL*4' declarations.
! These R1MACH numbers below and the coresponding I1MACH are simply the DOUBLE
! PRECISION or 'REAL*8' numbers. If you use the -r8 your whole code (and the
! user libraries you link with, the system libraries are taken care of
! automagicly) must be compiled with this option.
!
! data rmach(1) / 2.22507385850721D-308 /
! data rmach(2) / 1.79769313486231D+308 /
! data rmach(3) / 1.1101827117665D-16 /
! data rmach(4) / 2.2203654423533D-16 /
! data rmach(5) / 3.01029995663981E-1 /
!
! AMDAHL machines.
!
! data small(1) / 1048576 /
! data large(1) / 2147483647 /
! data right(1) / 990904320 /
! data diver(1) / 1007681536 /
! data ilog10(1) / 1091781651 /
!
! BURROUGHS 1700 system.
!
! data rmach(1) / Z400800000 /
! data rmach(2) / Z5FFFFFFFF /
! data rmach(3) / Z4E9800000 /
! data rmach(4) / Z4EA800000 /
! data rmach(5) / Z500E730E8 /
!
! BURROUGHS 5700/6700/7700 systems.
!
! data rmach(1) / O1771000000000000 /
! data rmach(2) / O0777777777777777 /
! data rmach(3) / O1311000000000000 /
! data rmach(4) / O1301000000000000 /
! data rmach(5) / O1157163034761675 /
!
! CDC CYBER 170/180 series using NOS
!
! data rmach(1) / O"00014000000000000000" /
! data rmach(2) / O"37767777777777777777" /
! data rmach(3) / O"16404000000000000000" /
! data rmach(4) / O"16414000000000000000" /
! data rmach(5) / O"17164642023241175720" /
!
! CDC CYBER 170/180 series using NOS/VE
!
! data rmach(1) / Z"3001800000000000" /
! data rmach(2) / Z"4FFEFFFFFFFFFFFE" /
! data rmach(3) / Z"3FD2800000000000" /
! data rmach(4) / Z"3FD3800000000000" /
! data rmach(5) / Z"3FFF9A209A84FBCF" /
!
! CDC CYBER 200 series
!
! data rmach(1) / X'9000400000000000' /
! data rmach(2) / X'6FFF7FFFFFFFFFFF' /
! data rmach(3) / X'FFA3400000000000' /
! data rmach(4) / X'FFA4400000000000' /
! data rmach(5) / X'FFD04D104D427DE8' /
!
! CDC 6000/7000 series using FTN4.
!
! data rmach(1) / 00564000000000000000B /
! data rmach(2) / 37767777777777777776B /
! data rmach(3) / 16414000000000000000B /
! data rmach(4) / 16424000000000000000B /
! data rmach(5) / 17164642023241175720B /
!
! CDC 6000/7000 series using FTN5.
!
! data rmach(1) / O"00564000000000000000" /
! data rmach(2) / O"37767777777777777776" /
! data rmach(3) / O"16414000000000000000" /
! data rmach(4) / O"16424000000000000000" /
! data rmach(5) / O"17164642023241175720" /
!
! CONVEX C-1.
!
! data rmach(1) / '00800000'X /
! data rmach(2) / '7FFFFFFF'X /
! data rmach(3) / '34800000'X /
! data rmach(4) / '35000000'X /
! data rmach(5) / '3F9A209B'X /
!
! CONVEX C-120 (native mode) without -R8 option
!
! data rmach(1) / 2.9387360E-39 /
! data rmach(2) / 1.7014117E+38 /
! data rmach(3) / 5.9604645E-08 /
! data rmach(4) / 1.1920929E-07 /
! data rmach(5) / 3.0102999E-01 /
!
! CONVEX C-120 (native mode) with -R8 option
!
! data rmach(1) / 5.562684646268007D-309 /
! data rmach(2) / 8.988465674311577D+307 /
! data rmach(3) / 1.110223024625157D-016 /
! data rmach(4) / 2.220446049250313D-016 /
! data rmach(5) / 3.010299956639812D-001 /
!
! CONVEX C-120 (IEEE mode) without -R8 option
!
! data rmach(1) / 1.1754945E-38 /
! data rmach(2) / 3.4028234E+38 /
! data rmach(3) / 5.9604645E-08 /
! data rmach(4) / 1.1920929E-07 /
! data rmach(5) / 3.0102999E-01 /
!
! CONVEX C-120 (IEEE mode) with -R8 option
!
! data rmach(1) / 2.225073858507202D-308 /
! data rmach(2) / 1.797693134862315D+308 /
! data rmach(3) / 1.110223024625157D-016 /
! data rmach(4) / 2.220446049250313D-016 /
! data rmach(5) / 3.010299956639812D-001 /
!
! CRAY 1, 2, XMP and YMP.
!
! data rmach(1) / 200034000000000000000B /
! data rmach(2) / 577767777777777777776B /
! data rmach(3) / 377224000000000000000B /
! data rmach(4) / 377234000000000000000B /
! data rmach(5) / 377774642023241175720B /
!
! DATA GENERAL ECLIPSE S/200.
! Note - It may be appropriate to include the line: STATIC RMACH(5)
!
! data small /20K,0/
! data large /77777K,177777K/
! data right /35420K,0/
! data diver /36020K,0/
! data ilog10 /40423K,42023K/
!
! ELXSI 6400, assuming REAL*4 is the default real type.
!
! data small(1) / '00800000'X /
! data large(1) / '7F7FFFFF'X /
! data right(1) / '33800000'X /
! data diver(1) / '34000000'X /
! data ilog10(1) / '3E9A209B'X /
!
! HARRIS 220
!
! data small(1),small(2) / '20000000, '00000201 /
! data large(1),large(2) / '37777777, '00000177 /
! data right(1),right(2) / '20000000, '00000352 /
! data diver(1),diver(2) / '20000000, '00000353 /
! data ilog10(1),ilog10(2) / '23210115, '00000377 /
!
! HARRIS SLASH 6 and SLASH 7.
!
! data small(1),small(2) / '20000000, '00000201 /
! data large(1),large(2) / '37777777, '00000177 /
! data right(1),right(2) / '20000000, '00000352 /
! data diver(1),diver(2) / '20000000, '00000353 /
! data ilog10(1),ilog10(2) / '23210115, '00000377 /
!
! HONEYWELL DPS 8/70 and 600/6000 series.
!
! data rmach(1) / O402400000000 /
! data rmach(2) / O376777777777 /
! data rmach(3) / O714400000000 /
! data rmach(4) / O716400000000 /
! data rmach(5) / O776464202324 /
!
! HP 2100, 3 word double precision with FTN4
!
! data small(1), small(2) / 40000B, 1 /
! data large(1), large(2) / 77777B, 177776B /
! data right(1), right(2) / 40000B, 325B /
! data diver(1), diver(2) / 40000B, 327B /
! data ilog10(1), ilog10(2) / 46420B, 46777B /
!
! HP 2100, 4 word double precision with FTN4
!
! data small(1), small(2) / 40000B, 1 /
! data large91), large(2) / 77777B, 177776B /
! data right(1), right(2) / 40000B, 325B /
! data diver(1), diver(2) / 40000B, 327B /
! data ilog10(1), ilog10(2) / 46420B, 46777B /
!
! HP 9000
!
! r1mach(1) = 1.17549435E-38
! r1mach(2) = 1.70141163E+38
! r1mach(3) = 5.960464478E-8
! r1mach(4) = 1.119209290E-7
! r1mach(5) = 3.01030010E-1
!
! data small(1) / 00040000000B /
! data large(1) / 17677777777B /
! data right(1) / 06340000000B /
! data diver(1) / 06400000000B /
! data ilog10(1) / 07646420233B /
!
! IBM 360/370 series, XEROX SIGMA 5/7/9, SEL systems 85/86, PERKIN ELMER 3230,
! and PERKIN ELMER (INTERDATA) 3230.
!
! data rmach(1) / Z00100000 /
! data rmach(2) / Z7FFFFFFF /
! data rmach(3) / Z3B100000 /
! data rmach(4) / Z3C100000 /
! data rmach(5) / Z41134413 /
!
! IBM PC - Microsoft FORTRAN
!
! data small(1) / #00800000 /
! data large(1) / #7F7FFFFF /
! data right(1) / #33800000 /
! data diver(1) / #34000000 /
! data ilog10(1) / #3E9A209A /
!
! IBM PC - Professional FORTRAN and Lahey FORTRAN
!
! data small(1)/ Z'00800000' /
! data large(1)/ Z'7F7FFFFF' /
! data right(1)/ Z'33800000' /
! data diver(1)/ Z'34000000' /
! data ilog10(1)/ Z'3E9A209A' /
!
! INTERDATA 8/32 with the UNIX system FORTRAN 77 compiler.
! For the INTERDATA FORTRAN VII compiler replace the Z'S specifying HEX
! constants with Y'S.
!
! data rmach(1) / Z'00100000' /
! data rmach(2) / Z'7EFFFFFF' /
! data rmach(3) / Z'3B100000' /
! data rmach(4) / Z'3C100000' /
! data rmach(5) / Z'41134413' /
!
! PDP-10 (KA or KI processor).
!
! data rmach(1) / "000400000000 /
! data rmach(2) / "377777777777 /
! data rmach(3) / "146400000000 /
! data rmach(4) / "147400000000 /
! data rmach(5) / "177464202324 /
!
! PDP-11 FORTRANS supporting 32-bit integers (integer version).
!
! data small(1) / 8388608 /
! data large(1) / 2147483647 /
! data right(1) / 880803840 /
! data diver(1) / 889192448 /
! data ilog10(1) / 1067065499 /
!
! PDP-11 FORTRANS supporting 32-bit integers (octal version).
!
! data rmach(1) / O00040000000 /
! data rmach(2) / O17777777777 /
! data rmach(3) / O06440000000 /
! data rmach(4) / O06500000000 /
! data rmach(5) / O07746420233 /
!
! PDP-11 FORTRANS supporting 16-bit integers (integer version).
!
! data small(1),small(2) / 128, 0 /
! data large(1),large(2) / 32767, -1 /
! data right(1),right(2) / 13440, 0 /
! data diver(1),diver(2) / 13568, 0 /
! data ilog10(1),ilog10(2) / 16282, 8347 /
!
! PDP-11 FORTRANS supporting 16-bit integers (octal version).
!
! data small(1),small(2) / O000200, O000000 /
! data large(1),large(2) / O077777, O177777 /
! data right(1),right(2) / O032200, O000000 /
! data diver(1),diver(2) / O032400, O000000 /
! data ilog10(1),ilog10(2) / O037632, O020233 /
!
! SEQUENT BALANCE 8000.
!
! data small(1) / $00800000 /
! data large(1) / $7F7FFFFF /
! data right(1) / $33800000 /
! data diver(1) / $34000000 /
! data ilog10(1) / $3E9A209B /
!
! SUN Microsystems UNIX F77 compiler.
!
data rmach(1) / 1.17549435E-38 /
data rmach(2) / 3.40282347E+38 /
data rmach(3) / 5.96016605E-08 /
data rmach(4) / 1.19203321E-07 /
data rmach(5) / 3.01030010E-01 /
!
! SUN 3 (68881 or FPA)
!
! data small(1) / X'00800000' /
! data large(1) / X'7F7FFFFF' /
! data right(1) / X'33800000' /
! data diver(1) / X'34000000' /
! data ilog10(1) / X'3E9A209B' /
!
! UNIVAC 1100 series.
!
! data rmach(1) / O000400000000 /
! data rmach(2) / O377777777777 /
! data rmach(3) / O146400000000 /
! data rmach(4) / O147400000000 /
! data rmach(5) / O177464202324 /
!
! VAX/ULTRIX F77 compiler.
!
! data small(1) / 128 /
! data large(1) / -32769 /
! data right(1) / 13440 /
! data diver(1) / 13568 /
! data ilog10(1) / 547045274 /
!
! VAX-11 with FORTRAN IV-PLUS compiler.
!
! data rmach(1) / Z00000080 /
! data rmach(2) / ZFFFF7FFF /
! data rmach(3) / Z00003480 /
! data rmach(4) / Z00003500 /
! data rmach(5) / Z209B3F9A /
!
! VAX/VMS version 2.2.
!
! data rmach(1) / '80'X /
! data rmach(2) / 'FFFF7FFF'X /
! data rmach(3) / '3480'X /
! data rmach(4) / '3500'X /
! data rmach(5) / '209B3F9A'X /
!
! VAX/VMS 11/780
!
! data small(1) / Z00000080 /
! data large(1) / ZFFFF7FFF /
! data right(1) / Z00003480 /
! data diver(1) / Z00003500 /
! data ilog10(1) / Z209B3F9A /
!
! Z80 microprocessor.
!
! data small(1), small(2) / 0, 256 /
! data large(1), large(2) / -1, -129 /
! data right(1), right(2) / 0, 26880 /
! data diver(1), diver(2) / 0, 27136 /
! data ilog10(1), ilog10(2) / 8347, 32538 /
!
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
IF ( i > 0 .AND. i < 6 ) THEN
r1mach = rmach(i)
ELSE
WRITE(6,'(/a)') 'R1MACH - Fatal error!'
WRITE(6,'(a,i9)')'I is out of bounds=',i
r1mach=0.
STOP
END IF
RETURN
END FUNCTION r1mach
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE GET_GRIDXYZP_HDF ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
SUBROUTINE get_gridxyzp_hdf(nx,ny,nz,filename, & 1,12
x,y,zp, &
itmp,hmax,hmin,ireturn)
!
!-----------------------------------------------------------------------
!
! PURPOSE:
! Read in grid variables from base state/grid history data.
!
!-----------------------------------------------------------------------
!
! AUTHOR: Keith Brewster, after a similar program developed by Ming Xue
! 02/06/2005.
!
! MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
! INPUT :
!
! filename HDF file name of grid/base file.
!
! OUTPUT:
!
! 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
! x x-coordinate data
! y y-coordinate data
! zp zp-coordinate data
!
! SCRATCH:
! itmp Temporary array for hdf compression
! hmin hmin temporary array
! hmax hmax temporary array
!
!-----------------------------------------------------------------------
IMPLICIT NONE
INTEGER :: stat, sd_id
CHARACTER (LEN=*) :: filename
INTEGER :: nx,ny,nz ! Number of grid points in 3 directions
REAL :: x(nx)
REAL :: y(ny)
REAL :: zp(nx,ny,nz)
INTEGER (KIND=selected_int_kind(4)) :: itmp(nx,ny,nz) ! Temporary array
REAL :: hmin(nz)
REAL :: hmax(nz)
INTEGER :: ireturn ! Return status indicator
!-----------------------------------------------------------------------
!
! Misc. local variables
!
!-----------------------------------------------------------------------
INTEGER :: istat
REAL :: alatpro(2)
REAL :: sclf,dxscl,dyscl,ctrx,ctry,swx,swy
LOGICAL :: success
!
!-----------------------------------------------------------------------
!
! Include files
!
!-----------------------------------------------------------------------
!
INCLUDE 'grid.inc'
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
CALL hdfopen
(filename,1,sd_id)
IF (sd_id < 0) THEN
WRITE (6,*) "get_gridxyzprho_hdf: ERROR opening ", &
trim(filename)," for reading."
ireturn=-1
RETURN
ELSE
WRITE(6,*) 'File ',filename,' opened.'
END IF
success=.true.
CALL hdfrdi
(sd_id,"mapproj",mapproj,istat)
CALL hdfrdr
(sd_id,"trulat1",trulat1,istat)
CALL hdfrdr
(sd_id,"trulat2",trulat2,istat)
CALL hdfrdr
(sd_id,"trulon",trulon,istat)
CALL hdfrdr
(sd_id,"sclfct",sclfct,istat)
CALL hdfrdr
(sd_id,"ctrlat",ctrlat,istat)
CALL hdfrdr
(sd_id,"ctrlon",ctrlon,istat)
CALL hdfrd1d
(sd_id,"x",nx,x,istat)
IF (istat /= 0) success=.false.
CALL hdfrd1d
(sd_id,"y",ny,y,istat)
IF (istat /= 0) success=.false.
CALL hdfrd3d
(sd_id,"zp",nx,ny,nz,zp,istat,itmp,hmax,hmin)
IF (istat /= 0) success=.false.
IF (success) THEN
ireturn = 0
ELSE
!-----------------------------------------------------------------------
!
! Error during read
!
!-----------------------------------------------------------------------
WRITE(6,'(/a/)') ' Error reading data in GET_GRIDXYZPRHO_HDF.'
ireturn=-2
END IF
CALL hdfclose
(sd_id,stat)
RETURN
END SUBROUTINE get_gridxyzp_hdf
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE HDFREADUVW ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
SUBROUTINE hdfreaduvw(nx,ny,nz,filename, & 1,28
time,u,v,w, &
itmp,hmax,hmin,ireturn)
!-----------------------------------------------------------------------
! PURPOSE:
! Read in ARPS wind data in the NCSA HDF4 format.
!-----------------------------------------------------------------------
!
! AUTHOR: Ming Xue
! 2000/04/15
!
! MODIFICATION HISTORY:
! Keith Brewster, CAPS
! 2005/02/06 Created hdfreaduvw, streamlined from hdfreadwind
!
!-----------------------------------------------------------------------
!
! 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
!
! filename Character variable naming the input HDF file
!-----------------------------------------------------------------------
! Variable Declarations.
!-----------------------------------------------------------------------
IMPLICIT NONE
INTEGER :: nx,ny,nz
CHARACTER (LEN=*) :: filename
REAL :: time
REAL :: u(nx,ny,nz)
REAL :: v(nx,ny,nz)
REAL :: w(nx,ny,nz)
INTEGER (KIND=selected_int_kind(4)) :: itmp(nx,ny,nz) ! Temporary array
REAL :: hmin(nz) ! Temporary array
REAL :: hmax(nz) ! Temporary array
INTEGER :: ireturn
!-----------------------------------------------------------------------
! Parameters describing routine that wrote the gridded data
!-----------------------------------------------------------------------
!
! 06/28/2002 Zuwen He
!
! fmtver??: to label each data a version.
! intver??: an integer to allow faster comparison than fmtver??,
! which are strings.
!
! Verion 5.00: significant change in soil variables since version 4.10.
!
!-----------------------------------------------------------------------
CHARACTER (LEN=40) :: fmtver410,fmtver500
INTEGER :: intver,intver410,intver500
PARAMETER (fmtver410='004.10 HDF4 Coded Data',intver410=410)
PARAMETER (fmtver500='005.00 HDF4 Coded Data',intver500=500)
CHARACTER (LEN=40) :: fmtverin
CHARACTER (LEN=10) :: tmunit
!-----------------------------------------------------------------------
! Misc. local variables
!-----------------------------------------------------------------------
INTEGER :: lchanl
PARAMETER (lchanl=6) ! Channel number for formatted printing.
INTEGER :: i,j,k,is
INTEGER :: nxin,nyin,nzin
INTEGER :: istat, sd_id
INTEGER :: varflg, istatus
LOGICAL :: success
!-----------------------------------------------------------------------
!
! Include files:
!
!-----------------------------------------------------------------------
INCLUDE 'globcst.inc'
INCLUDE 'grid.inc' ! Grid parameters
INCLUDE 'indtflg.inc'
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
! Beginning of executable code...
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
WRITE(*,*) 'HDFREADUVW: Reading HDF file: ', trim(filename)
!-----------------------------------------------------------------------
! Open file for reading
!-----------------------------------------------------------------------
CALL hdfopen
(filename,1,sd_id)
IF (sd_id < 0) THEN
WRITE (6,*) "HDFREADUVW: ERROR opening ", trim(filename)," for reading."
ireturn=-1
RETURN
END IF
fmtverin = fmtver500
WRITE(6,'(/1x,a,a/)') 'Incoming data format, fmtverin=',fmtverin
CALL hdfrdc
(sd_id,80,"runname",runname,istat)
CALL hdfrdi
(sd_id,"nocmnt",nocmnt,istat)
IF( nocmnt > 0 ) THEN
CALL hdfrdc
(sd_id,80*nocmnt,"cmnt",cmnt,istat)
END IF
WRITE(6,'(//'' THE NAME OF THIS RUN IS: '',A//)') trim(runname)
WRITE (6,*) "Comments:"
IF( nocmnt > 0 ) THEN
DO i=1,nocmnt
WRITE(6,'(1x,a)') cmnt(i)
END DO
END IF
WRITE (6,*) " "
CALL hdfrdc
(sd_id,10,"tmunit",tmunit,istat)
CALL hdfrdr
(sd_id,"time",time,istat)
!-----------------------------------------------------------------------
! Get dimensions of data in binary file and check against
! the dimensions passed to HDFREAD
!-----------------------------------------------------------------------
CALL hdfrdi
(sd_id,"nx",nxin,istat)
CALL hdfrdi
(sd_id,"ny",nyin,istat)
CALL hdfrdi
(sd_id,"nz",nzin,istat)
IF ( nxin /= nx .OR. nyin /= ny .OR. nzin /= nz ) THEN
WRITE(6,'(1x,a)') ' Dimensions in HDFREADUVW inconsistent with data.'
WRITE(6,'(1x,a,3I15)') ' Read were: ', nxin, nyin, nzin
WRITE(6,'(1x,a,3I15)') ' Expected: ', nx, ny, nz
WRITE(6,'(1x,a)') ' Program aborted in HDFREAD.'
CALL arpsstop
('arpsstop called from HDFREADUVW due to nxin...',1)
END IF
WRITE(lchanl,'(1x,a,f8.1,a,f8.3,a/)')'To read data for time:', &
time,' secs = ',(time/60.),' mins.'
CALL hdfrdi
(sd_id,"grdflg",grdin,istat)
CALL hdfrdi
(sd_id,"basflg",basin,istat)
CALL hdfrdi
(sd_id,"varflg",varin,istat)
WRITE(6,'(a)') ' Done reading parameters'
CALL hdfrdi
(sd_id,"month",month,istat)
CALL hdfrdi
(sd_id,"day",day,istat)
CALL hdfrdi
(sd_id,"year",year,istat)
CALL hdfrdi
(sd_id,"hour",hour,istat)
CALL hdfrdi
(sd_id,"minute",minute,istat)
CALL hdfrdi
(sd_id,"second",second,istat)
CALL hdfrdr
(sd_id,"umove",umove,istat)
CALL hdfrdr
(sd_id,"vmove",vmove,istat)
CALL hdfrdr
(sd_id,"xgrdorg",xgrdorg,istat)
CALL hdfrdr
(sd_id,"ygrdorg",ygrdorg,istat)
success=.true.
IF( varin == 1 ) then
!-----------------------------------------------------------------------
! Read in total values of variables from history dump
!-----------------------------------------------------------------------
CALL hdfrd3d
(sd_id,"u",nx,ny,nz,u,istat,itmp,hmax,hmin)
IF (istat /= 0) success=.false.
CALL hdfrd3d
(sd_id,"v",nx,ny,nz,v,istat,itmp,hmax,hmin)
IF (istat /= 0) success=.false.
CALL hdfrd3d
(sd_id,"w",nx,ny,nz,w,istat,itmp,hmax,hmin)
IF (istat /= 0) success=.false.
!-----------------------------------------------------------------------
!
! Friendly exit message
!
!-----------------------------------------------------------------------
IF(success) THEN
WRITE(6,'(/a,F8.1,a/)') &
' Data at time=', time/60,' (min) were successfully read.'
ireturn = 0
ELSE
WRITE(6,'(/a,F8.1,a/)') &
' Error reading u,v,w data at time=', time/60,' (min)'
ireturn = -3
END IF
CALL hdfclose
(sd_id,istat)
ELSE
WRITE(6,'(/a/a,a/)') ' Error reading data in HDFREADUVW:', &
' No time-dependent data in file',trim(filename)
ireturn = -2
CALL hdfclose
(sd_id,istat)
END IF
RETURN
END SUBROUTINE hdfreaduvw
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE HDFREADPPTRHO ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
SUBROUTINE hdfreadppt(nx,ny,nz,filename, & 1,23
time,p,pt, &
itmp,hmax,hmin,ireturn)
!-----------------------------------------------------------------------
! PURPOSE:
! Read in ARPS pressure and temperature data in the NCSA HDF4 format.
!-----------------------------------------------------------------------
!
! AUTHOR: Keith Brewster after hdfreaduvw
! 02/06/2005
!
! MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
! 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
!
! filename Character variable naming the input HDF file
!-----------------------------------------------------------------------
! Variable Declarations.
!-----------------------------------------------------------------------
IMPLICIT NONE
INTEGER :: nx,ny,nz
CHARACTER (LEN=*) :: filename
REAL :: time
REAL :: p(nx,ny,nz)
REAL :: pt(nx,ny,nz)
INTEGER (KIND=selected_int_kind(4)) :: itmp(nx,ny,nz) ! Temporary array
REAL :: hmin(nz) ! Temporary array
REAL :: hmax(nz) ! Temporary array
INTEGER :: ireturn
!-----------------------------------------------------------------------
! Parameters describing routine that wrote the gridded data
!-----------------------------------------------------------------------
!
! 06/28/2002 Zuwen He
!
! fmtver??: to label each data a version.
! intver??: an integer to allow faster comparison than fmtver??,
! which are strings.
!
! Verion 5.00: significant change in soil variables since version 4.10.
!
!-----------------------------------------------------------------------
CHARACTER (LEN=40) :: fmtver410,fmtver500
INTEGER :: intver,intver410,intver500
PARAMETER (fmtver410='004.10 HDF4 Coded Data',intver410=410)
PARAMETER (fmtver500='005.00 HDF4 Coded Data',intver500=500)
CHARACTER (LEN=40) :: fmtverin
CHARACTER (LEN=10) :: tmunit
!-----------------------------------------------------------------------
! Misc. local variables
!-----------------------------------------------------------------------
INTEGER :: lchanl
PARAMETER (lchanl=6) ! Channel number for formatted printing.
INTEGER :: i,j,k,is
INTEGER :: nxin,nyin,nzin
INTEGER :: istat, sd_id
INTEGER :: varflg, istatus
LOGICAL :: success
!-----------------------------------------------------------------------
!
! Include files:
!
!-----------------------------------------------------------------------
INCLUDE 'globcst.inc'
INCLUDE 'grid.inc' ! Grid parameters
INCLUDE 'indtflg.inc'
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
! Beginning of executable code...
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
WRITE(*,*) 'HDFREADPPTRHO: Reading HDF file: ', trim(filename)
!-----------------------------------------------------------------------
! Open file for reading
!-----------------------------------------------------------------------
CALL hdfopen
(filename,1,sd_id)
IF (sd_id < 0) THEN
WRITE (6,'(3a)') 'HDFREADPPTRHO: ERROR opening ', trim(filename), &
' for reading.'
ireturn=-1
RETURN
END IF
fmtverin = fmtver500
WRITE(6,'(/1x,a,a/)') 'Incoming data format, fmtverin=',fmtverin
CALL hdfrdc
(sd_id,80,"runname",runname,istat)
CALL hdfrdi
(sd_id,"nocmnt",nocmnt,istat)
IF( nocmnt > 0 ) THEN
CALL hdfrdc
(sd_id,80*nocmnt,"cmnt",cmnt,istat)
END IF
WRITE(6,'(//'' THE NAME OF THIS RUN IS: '',A//)') trim(runname)
WRITE (6,*) "Comments:"
IF( nocmnt > 0 ) THEN
DO i=1,nocmnt
WRITE(6,'(1x,a)') cmnt(i)
END DO
END IF
WRITE (6,*) " "
CALL hdfrdc
(sd_id,10,"tmunit",tmunit,istat)
CALL hdfrdr
(sd_id,"time",time,istat)
!-----------------------------------------------------------------------
! Get dimensions of data in binary file and check against
! the dimensions passed to HDFREAD
!-----------------------------------------------------------------------
CALL hdfrdi
(sd_id,"nx",nxin,istat)
CALL hdfrdi
(sd_id,"ny",nyin,istat)
CALL hdfrdi
(sd_id,"nz",nzin,istat)
IF ( nxin /= nx .OR. nyin /= ny .OR. nzin /= nz ) THEN
WRITE(6,'(1x,a)') ' Dimensions in HDFREADUVW inconsistent with data.'
WRITE(6,'(1x,a,3I15)') ' Read were: ', nxin, nyin, nzin
WRITE(6,'(1x,a,3I15)') ' Expected: ', nx, ny, nz
WRITE(6,'(1x,a)') ' Program aborted in HDFREAD.'
CALL arpsstop
('arpsstop called from HDFREADUVW due to nxin...',1)
END IF
WRITE(lchanl,'(1x,a,f8.1,a,f8.3,a/)')'To read data for time:', &
time,' secs = ',(time/60.),' mins.'
CALL hdfrdi
(sd_id,"grdflg",grdin,istat)
CALL hdfrdi
(sd_id,"basflg",basin,istat)
CALL hdfrdi
(sd_id,"varflg",varin,istat)
WRITE(6,'(a)') ' Done reading parameters'
CALL hdfrdi
(sd_id,"month",month,istat)
CALL hdfrdi
(sd_id,"day",day,istat)
CALL hdfrdi
(sd_id,"year",year,istat)
CALL hdfrdi
(sd_id,"hour",hour,istat)
CALL hdfrdi
(sd_id,"minute",minute,istat)
CALL hdfrdi
(sd_id,"second",second,istat)
success=.true.
IF( varin == 1 ) THEN
!-----------------------------------------------------------------------
! Read in total values of variables from history dump
!-----------------------------------------------------------------------
CALL hdfrd3d
(sd_id,"p",nx,ny,nz,p,istat,itmp,hmax,hmin)
IF (istat /= 0) success=.false.
CALL hdfrd3d
(sd_id,"pt",nx,ny,nz,pt,istat,itmp,hmax,hmin)
IF (istat /= 0) success=.false.
!-----------------------------------------------------------------------
!
! Friendly exit message
!
!-----------------------------------------------------------------------
IF(success) THEN
WRITE(6,'(/a,F8.1,a/)') &
' Data at time=', time/60,' (min) were successfully read.'
ireturn = 0
ELSE
WRITE(6,'(/a,F8.1,a/)') &
' Error reading u,v,w data at time=', time/60,' (min)'
ireturn = -3
END IF
CALL hdfclose
(sd_id,istat)
ELSE
WRITE(6,'(/a/a,a/)') ' Error reading data in HDFREADPPT:', &
' No time-dependent data in file',trim(filename)
ireturn = -2
CALL hdfclose
(sd_id,istat)
END IF
RETURN
END SUBROUTINE hdfreadppt
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE HDFREADQRSH ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
SUBROUTINE hdfreadqrsh(nx,ny,nz,filename,time,qr,qs,qh, & 1,25
itmp,hmax,hmin,ireturn)
!-----------------------------------------------------------------------
! PURPOSE:
! Read in ARPS pressure and temperature data in the NCSA HDF4 format.
!-----------------------------------------------------------------------
!
! AUTHOR: Keith Brewster after hdfreaduvw
! 02/06/2005
!
! MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
! 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
!
! filename Character variable naming the input HDF file
!-----------------------------------------------------------------------
! Variable Declarations.
!-----------------------------------------------------------------------
IMPLICIT NONE
INTEGER :: nx,ny,nz
CHARACTER (LEN=*) :: filename
REAL :: time
REAL :: qr(nx,ny,nz)
REAL :: qs(nx,ny,nz)
REAL :: qh(nx,ny,nz)
INTEGER (KIND=selected_int_kind(4)) :: itmp(nx,ny,nz) ! Temporary array
REAL :: hmin(nz) ! Temporary array
REAL :: hmax(nz) ! Temporary array
INTEGER :: ireturn
!-----------------------------------------------------------------------
! Parameters describing routine that wrote the gridded data
!-----------------------------------------------------------------------
!
! 06/28/2002 Zuwen He
!
! fmtver??: to label each data a version.
! intver??: an integer to allow faster comparison than fmtver??,
! which are strings.
!
! Verion 5.00: significant change in soil variables since version 4.10.
!
!-----------------------------------------------------------------------
CHARACTER (LEN=40) :: fmtver410,fmtver500
INTEGER :: intver,intver410,intver500
PARAMETER (fmtver410='004.10 HDF4 Coded Data',intver410=410)
PARAMETER (fmtver500='005.00 HDF4 Coded Data',intver500=500)
CHARACTER (LEN=40) :: fmtverin
CHARACTER (LEN=10) :: tmunit
!-----------------------------------------------------------------------
! Misc. local variables
!-----------------------------------------------------------------------
INTEGER :: lchanl
PARAMETER (lchanl=6) ! Channel number for formatted printing.
INTEGER :: i,j,k,is
INTEGER :: nxin,nyin,nzin
INTEGER :: istat, sd_id
INTEGER :: varflg, istatus
LOGICAL :: success
!-----------------------------------------------------------------------
!
! Include files:
!
!-----------------------------------------------------------------------
INCLUDE 'globcst.inc'
INCLUDE 'grid.inc' ! Grid parameters
INCLUDE 'indtflg.inc'
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
! Beginning of executable code...
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
WRITE(*,*) 'HDFREADQRSH: Reading HDF file: ', trim(filename)
!-----------------------------------------------------------------------
! Open file for reading
!-----------------------------------------------------------------------
CALL hdfopen
(filename,1,sd_id)
IF (sd_id < 0) THEN
WRITE (6,*) "HDFREADQRSH: ERROR opening ", trim(filename)," for reading."
ireturn=-1
RETURN
END IF
fmtverin = fmtver500
WRITE(6,'(/1x,a,a/)') 'Incoming data format, fmtverin=',fmtverin
CALL hdfrdc
(sd_id,80,"runname",runname,istat)
CALL hdfrdi
(sd_id,"nocmnt",nocmnt,istat)
IF( nocmnt > 0 ) THEN
CALL hdfrdc
(sd_id,80*nocmnt,"cmnt",cmnt,istat)
END IF
WRITE(6,'(//'' THE NAME OF THIS RUN IS: '',A//)') trim(runname)
WRITE (6,*) "Comments:"
IF( nocmnt > 0 ) THEN
DO i=1,nocmnt
WRITE(6,'(1x,a)') cmnt(i)
END DO
END IF
WRITE (6,*) " "
CALL hdfrdc
(sd_id,10,"tmunit",tmunit,istat)
CALL hdfrdr
(sd_id,"time",time,istat)
!-----------------------------------------------------------------------
! Get dimensions of data in binary file and check against
! the dimensions passed to HDFREAD
!-----------------------------------------------------------------------
CALL hdfrdi
(sd_id,"nx",nxin,istat)
CALL hdfrdi
(sd_id,"ny",nyin,istat)
CALL hdfrdi
(sd_id,"nz",nzin,istat)
IF ( nxin /= nx .OR. nyin /= ny .OR. nzin /= nz ) THEN
WRITE(6,'(1x,a)') ' Dimensions in HDFREADUVW inconsistent with data.'
WRITE(6,'(1x,a,3I15)') ' Read were: ', nxin, nyin, nzin
WRITE(6,'(1x,a,3I15)') ' Expected: ', nx, ny, nz
WRITE(6,'(1x,a)') ' Program aborted in HDFREAD.'
CALL arpsstop
('arpsstop called from HDFREADUVW due to nxin...',1)
END IF
WRITE(lchanl,'(1x,a,f8.1,a,f8.3,a/)')'To read data for time:', &
time,' secs = ',(time/60.),' mins.'
CALL hdfrdi
(sd_id,"grdflg",grdin,istat)
CALL hdfrdi
(sd_id,"basflg",basin,istat)
CALL hdfrdi
(sd_id,"varflg",varin,istat)
CALL hdfrdi
(sd_id,"iceflg",icein,istat)
WRITE(6,'(a)') ' Done reading parameters'
CALL hdfrdi
(sd_id,"month",month,istat)
CALL hdfrdi
(sd_id,"day",day,istat)
CALL hdfrdi
(sd_id,"year",year,istat)
CALL hdfrdi
(sd_id,"hour",hour,istat)
CALL hdfrdi
(sd_id,"minute",minute,istat)
CALL hdfrdi
(sd_id,"second",second,istat)
success=.true.
IF( varin == 1 ) THEN
!-----------------------------------------------------------------------
! Read in total values of variables from history dump
!-----------------------------------------------------------------------
CALL hdfrd3d
(sd_id,"qr",nx,ny,nz,qr,istat,itmp,hmax,hmin)
IF (istat /= 0) success=.false.
IF(icein == 1) THEN
CALL hdfrd3d
(sd_id,"qs",nx,ny,nz,qs,istat,itmp,hmax,hmin)
IF (istat /= 0) success=.false.
CALL hdfrd3d
(sd_id,"qh",nx,ny,nz,qh,istat,itmp,hmax,hmin)
IF (istat /= 0) success=.false.
ELSE
qs=0.
qh=0.
END IF
!-----------------------------------------------------------------------
!
! Friendly exit message
!
!-----------------------------------------------------------------------
IF(success) THEN
WRITE(6,'(/a,F8.1,a/)') &
' Data at time=', time/60,' (min) were successfully read.'
ireturn = 0
ELSE
WRITE(6,'(/a,F8.1,a/)') &
' Error reading qr,qs,qh data at time=', time/60,' (min)'
ireturn = -3
END IF
CALL hdfclose
(sd_id,istat)
ELSE
WRITE(6,'(/a/a,a/)') ' Error reading data in HDFREADQRSH:', &
' No time-dependent data in file',trim(filename)
ireturn = -2
CALL hdfclose
(sd_id,istat)
END IF
RETURN
END SUBROUTINE hdfreadqrsh
SUBROUTINE radverr(ngate,maxazim,nazim,radv,attrefl,stdvr,gatesp, & 1
vrerropt,sigmavr,samploi,vnyqstl, &
wavelen,pwrxmt,gaindb,lossdb,noisedbm,beamwid, &
pulselen,npulse,rmisval)
!
! Calculate an expected error for reflectivity based in the SNR
! of the attenuated signal and apply to the relectivity arrays.
!
! Calculation of expected radial velocity error based on SNR,
! estimated spectrum width and number of samples is derived
! from a fit to the modelled errors presented in Fig 6.5 of
! Doviak and Zrnic', 1993.
!
! Keith Brewster, CAPS
! 29 Sept 2005
!
IMPLICIT NONE
INTEGER :: ngate
INTEGER :: maxazim
INTEGER :: nazim
REAL :: radv(ngate,maxazim)
REAL :: attrefl(ngate,maxazim)
REAL :: stdvr(ngate,maxazim)
REAL :: gatesp
INTEGER :: vrerropt
REAL :: sigmavr
REAL :: samploi
REAL :: vnyqstl
REAL :: wavelen
REAL :: pwrxmt
REAL :: gaindb
REAL :: lossdb
REAL :: noisedbm
REAL :: beamwid
REAL :: pulselen
INTEGER :: npulse
REAL :: rmisval
!
! Misc. local variables
!
REAL, PARAMETER :: kw2=0.91
REAL :: taums,gatspkm,nplsind,nplsinv,twovnyq,twovninv
REAL :: pi,rkm,dBZ,ze,pwrmw,noisemw,snr,snrinv,pwrcst
REAL :: gain,gain2,loss,wavln2,beamwid2,pi5,ln2,two14,loss2,err
REAL :: stdvrnor,sdnor,sigmav,vr,sigmvcst,sigmvlim
INTEGER :: i,j,mid,ifold
REAL :: randnor
!
! Calculate constants, including power constant needed to
! compute SRM from reflectivity. Change units of radar parameters
! to those used in Eq. 4.35 of Doviak and Zrnic', 1993.
!
mid=(nazim/2)+1
pi=acos(-1.)
twovnyq=2.*vnyqstl
twovninv=1./twovnyq
sigmvcst=twovnyq/sqrt(npulse*samploi)
sigmvlim=0.8*vnyqstl
taums=1.0E06*pulselen
gatspkm=0.001*gatesp
nplsind=samploi*npulse
nplsinv=1./nplsind
noisemw=10.**(0.1*noisedbm)
gain=10.**(0.1*gaindb)
loss=10.**(0.1*lossdb)
gain2=gain*gain
wavln2=wavelen*wavelen
beamwid2=beamwid*beamwid
pi5=pi**5
two14=2.0**14
ln2=log(2.)
pwrcst=(pi5*1.0E-17*pwrxmt*gain2*taums*beamwid2*kw2)/ &
(6.75*two14*ln2*wavln2*loss)
IF(vrerropt == 1) THEN
DO j=1,nazim
DO i=1,ngate
IF(radv(i,j) > rmisval) THEN
vr=radv(i,j)+sigmavr*randnor()
ifold=NINT(vr*twovninv)
radv(i,j)=vr-ifold*twovnyq
END IF
END DO
END DO
ELSE IF(vrerropt > 1) THEN
WRITE(6,'(a,f12.2)') ' vnyqstl=',vnyqstl
WRITE(6,'(a,f12.0,a,f12.3)') ' gatesp=',gatesp,'gatspkm',gatspkm
! OPEN(51,file='snrp20.txt',status='unknown',form='formatted')
! WRITE(51,'(6x,a)') &
! 'rkm attrefl snr stdvr sigmav vr'
! OPEN(52,file='snrp15.txt',status='unknown',form='formatted')
! WRITE(52,'(6x,a)') &
! 'rkm attrefl snr stdvr sigmav vr'
! OPEN(53,file='snrp08.txt',status='unknown',form='formatted')
! WRITE(53,'(6x,a)') &
! 'rkm attrefl snr stdvr sigmav vr'
! OPEN(54,file='snrp00.txt',status='unknown',form='formatted')
! WRITE(54,'(6x,a)') &
! 'rkm attrefl snr stdvr sigmav vr'
! OPEN(55,file='snrm05.txt',status='unknown',form='formatted')
! WRITE(55,'(6x,a)') &
! 'rkm attrefl snr stdvr sigmav vr'
! OPEN(56,file='snrm06.txt',status='unknown',form='formatted')
! WRITE(56,'(6x,a)') &
! 'rkm attrefl snr stdvr sigmav vr'
DO j=1,nazim
DO i=1,ngate
IF(radv(i,j) > rmisval) THEN
IF(attrefl(i,j) > rmisval ) THEN
rkm=i*gatspkm
ze=10.**(attrefl(i,j)*0.1)
pwrmw=pwrcst*ze/(rkm*rkm)
snr=pwrmw/noisemw
ELSE
rkm=i*gatspkm
snr=0.01
END IF
snr=max(snr,0.01)
snrinv=1.0/snr
stdvrnor=stdvr(i,j)*twovninv
stdvrnor=min(max(stdvrnor,0.01),0.4)
sdnor=(0.0177*exp(12.0*stdvrnor)) + &
((0.159-0.755*stdvrnor+6.5*stdvrnor*stdvrnor)*snrinv)
sigmav=sigmvcst*sdnor
sigmav=min(max(sigmav,0.1),sigmvlim)
! IF(snr > 100.) THEN ! 20 dB
! WRITE(51,'(f10.1,2x,g10.5,2x,g10.5,2x,g10.5,2x,g10.4,f10.2)') &
! rkm,attrefl(i,j),snr,stdvrnor,sdnor,sigmav
! ELSE IF(snr > 15.85) THEN ! 12 dB
! WRITE(52,'(f10.1,2x,g10.5,2x,g10.5,2x,g10.5,2x,g10.4,f10.2)') &
! rkm,attrefl(i,j),snr,stdvrnor,sdnor,sigmav
! ELSE IF(snr > 3.16) THEN ! 5 dB
! WRITE(53,'(f10.1,2x,g10.5,2x,g10.5,2x,g10.5,2x,g10.4,f10.2)') &
! rkm,attrefl(i,j),snr,stdvrnor,sdnor,sigmav
! ELSE IF(snr > 0.631) THEN ! -2 dB
! WRITE(54,'(f10.1,2x,g10.5,2x,g10.5,2x,g10.5,2x,g10.4,f10.2)') &
! rkm,attrefl(i,j),snr,stdvrnor,sdnor,sigmav
! ELSE IF(snr > 0.20) THEN ! -7 dB
! WRITE(55,'(f10.1,2x,g10.5,2x,g10.5,2x,g10.5,2x,g10.4,f10.2)') &
! rkm,attrefl(i,j),snr,stdvrnor,sdnor,sigmav
! ELSE
! WRITE(56,'(f10.1,2x,g10.5,2x,g10.5,2x,g10.5,2x,g10.4,f10.2)') &
! rkm,attrefl(i,j),snr,stdvr(i,j),sigmav,radv(i,j)
! END IF
vr=radv(i,j)+sigmav*randnor()
ifold=NINT(vr*twovninv)
radv(i,j)=vr-ifold*twovnyq
END IF
END DO
END DO
END IF
RETURN
END SUBROUTINE radverr
SUBROUTINE reflerr(ngate,maxazim,nazim,refl,attrefl,gatesp, & 1
rferropt,sigmarf,refmin,samploi, &
wavelen,pwrxmt,gaindb,lossdb,noisedbm,beamwid, &
pulselen,npulse,rmisval)
!
! Calculate an expected error for reflectivity based in the SNR
! of the attenuated signal and apply to the relectivity arrays.
!
! Keith Brewster, CAPS
! 29 Sept 2005
!
IMPLICIT NONE
INTEGER :: ngate
INTEGER :: maxazim
INTEGER :: nazim
REAL :: refl(ngate,maxazim)
REAL :: attrefl(ngate,maxazim)
REAL :: gatesp
INTEGER :: rferropt
REAL :: sigmarf
REAL :: refmin
REAL :: samploi
REAL :: wavelen
REAL :: pwrxmt
REAL :: gaindb
REAL :: lossdb
REAL :: noisedbm
REAL :: beamwid
REAL :: pulselen
INTEGER :: npulse
REAL :: rmisval
!
! Misc. local variables
!
REAL, PARAMETER :: kw2=0.91
REAL :: taums,gatspkm,nplsind,nplsinv,rminze
REAL :: pi,rkm,rkm2,dBZ,ze,pwrmw,noisemw,randerr
REAL :: snr,sigmaz,snrinv,pwrcst,pcstinv
REAL :: gain,gain2,loss,wavln2,beamwid2,pi5,ln2,two14,loss2,err
INTEGER :: i,j,mid
REAL :: randnor
WRITE(6,'(a,i4)') ' Calculating Reflectivity Error, Opt=',rferropt
mid=(nazim/2)+1
pi=acos(-1.)
taums=1.0E06*pulselen
gatspkm=0.001*gatesp
nplsind=samploi*npulse
nplsinv=1./nplsind
noisemw=10.**(0.1*noisedbm)
gain=10.**(0.1*gaindb)
loss=10.**(0.1*lossdb)
gain2=gain*gain
wavln2=wavelen*wavelen
beamwid2=beamwid*beamwid
pi5=pi**5
two14=2.0**14
ln2=log(2.)
pwrcst=(pi5*1.0E-17*pwrxmt*gain2*taums*beamwid2*kw2)/ &
(6.75*two14*ln2*wavln2*loss)
pcstinv=1.0/pwrcst
IF(rferropt == 1) THEN
DO j=1,nazim
DO i=1,ngate
IF(attrefl(i,j) > rmisval) THEN
err=sigmarf*randnor()
refl(i,j)=max(refmin,(refl(i,j)+err))
attrefl(i,j)=max(refmin,(attrefl(i,j)+err))
END IF
END DO
END DO
ELSE IF(rferropt > 1) THEN
! WRITE(6,'(6x,a)') 'rkm attrefl snr sigmaz'
DO j=1,nazim
DO i=1,ngate
IF(attrefl(i,j) > rmisval) THEN
rkm=i*gatspkm
rkm2=rkm*rkm
ze=10.**(attrefl(i,j)*0.1)
pwrmw=pwrcst*ze/rkm2
snr=pwrmw/noisemw
snrinv=1.0/snr
sigmaz= &
1.0+sqrt(nplsinv*((1.+snrinv)*(1.+snrinv)+(snrinv*snrinv)))
! IF(mod(i,100) == 0) &
! WRITE(6,'(/f10.1,2x,g10.4,2x,g10.4,2x,g10.4)') &
! rkm,attrefl(i,j),snr,sigmaz
randerr=randnor()
err=sigmaz*noisemw*randerr
pwrmw=pwrmw+err
IF (pwrmw > 0. ) THEN
ze=rkm2*pcstinv*pwrmw
attrefl(i,j)=10.*log10(ze)
attrefl(i,j)=max(refmin,attrefl(i,j))
ELSE
attrefl(i,j)=refmin
END IF
! IF(mod(i,100) == 0) THEN
! WRITE(6,'(12x,g10.4,2x,g10.4)') &
! attrefl(i,j),pwrmw
! print *, 'randerr, err=',randerr,err
! END IF
ze=10.**(refl(i,j)*0.1)
pwrmw=pwrcst*ze/(rkm*rkm)
pwrmw=pwrmw+err
IF (pwrmw > 0.) THEN
ze=rkm2*pcstinv*pwrmw
refl(i,j)=10.*log10(ze)
refl(i,j)=max(refmin,refl(i,j))
ELSE
refl(i,j)=refmin
END IF
END IF
END DO
END DO
END IF
RETURN
END SUBROUTINE reflerr
SUBROUTINE fake_reflec(nx,ny,nz,ref)
IMPLICIT NONE
INTEGER :: nx,ny,nz
REAL :: ref(nx,ny,nz)
INTEGER :: i,j,k
REAL, PARAMETER :: refcst=30.0
WRITE(6,'(//a,/,/a,f10.2//)') '*******WARNING***************', &
' Test code: Setting all reflectivity in domain to:',refcst
DO k=1,nz
DO j=1,ny
DO i=1,nx
ref(i,j,k)=refcst
END DO
END DO
END DO
RETURN
END SUBROUTINE fake_reflec
SUBROUTINE fake_vel(nx,ny,nz,usc,vsc)
IMPLICIT NONE
INTEGER :: nx,ny,nz
REAL :: usc(nx,ny,nz)
REAL :: vsc(nx,ny,nz)
INTEGER :: i,j,k
REAL, PARAMETER :: ucst=50.0
REAL, PARAMETER :: vcst=0.0
WRITE(6,'(//a,/,/a,f10.2,/a,f10.2//)') &
'*******WARNING***************', &
' Test code: Setting all u velocity in domain to:',ucst, &
' Test code: Setting all v velocity in domain to:',vcst
DO k=1,nz
DO j=1,ny
DO i=1,nx
usc(i,j,k)=ucst
vsc(i,j,k)=vcst
END DO
END DO
END DO
RETURN
END SUBROUTINE fake_vel