PROGRAM attenuation,38
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Sample program to read history data files produced by ARPS.
!
!-----------------------------------------------------------------------
!
!  AUTHOR: Ming Xue
!    12/12/2003: Rewrote based on arpscvt. Input file names will be 
!    specified in arpsread.input.
!
!  MODIFICATION HISTORY: edited arpsread for attenuation program
!
!-----------------------------------------------------------------------
!
  IMPLICIT NONE

  INTEGER :: nx,ny,nz,nzsoil   ! Grid dimensions.
  INTEGER :: nstyps            ! Maximum number of soil types.

  INTEGER :: hinfmt,nhisfile_max,nhisfile,lengbf,nf,lenfil
  PARAMETER (nhisfile_max=200)
  CHARACTER (LEN=256) :: grdbasfn,hisfile(nhisfile_max)
!
!-----------------------------------------------------------------------
!  Include files:
!-----------------------------------------------------------------------
!
  INCLUDE 'globcst.inc'
  INCLUDE 'grid.inc'
!
!-----------------------------------------------------------------------
!  Arrays to be read in:
!-----------------------------------------------------------------------
!
  REAL, ALLOCATABLE :: x(:)   ! The x-coord. of the physical and
                              ! computational grid. Defined at u-point.
  REAL, ALLOCATABLE :: y(:)   ! The y-coord. of the physical and
                              ! computational grid. Defined at v-point.
  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 of the terrain.

  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 :: tke    (:,:,:) ! Turbulent Kinetic Energy ((m/s)**2)
  REAL, ALLOCATABLE :: kmh    (:,:,:) ! Horizontal turb. mixing coef. for
                                      ! momentum. ( m**2/s )
  REAL, ALLOCATABLE :: kmv    (:,:,:) ! Vertical turb. mixing coef. for
                                      ! momentum. ( m**2/s )
  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)

  REAL, ALLOCATABLE :: u      (:,:,:) ! Total u-velocity (m/s)
  REAL, ALLOCATABLE :: v      (:,:,:) ! Total v-velocity (m/s)
  REAL, ALLOCATABLE :: w      (:,:,:) ! Total w-velocity (m/s)
  REAL, ALLOCATABLE :: qv     (:,:,:) ! Water vapor specific humidity (kg/kg)

  INTEGER, ALLOCATABLE :: soiltyp (:,:,:) ! Soil type
  REAL, ALLOCATABLE :: stypfrct(:,:,:)    ! Soil type
  INTEGER, ALLOCATABLE :: vegtyp(:,:)     ! Vegetation type
  REAL, ALLOCATABLE :: lai    (:,:)   ! Leaf Area Index
  REAL, ALLOCATABLE :: roufns (:,:)   ! Surface roughness
  REAL, ALLOCATABLE :: veg    (:,:)   ! Vegetation fraction

  REAL, ALLOCATABLE :: tsoil (:,:,:,:) ! Soil temperature (K)
  REAL, ALLOCATABLE :: qsoil (:,:,:,:) ! Soil moisture (m**3/m**3) 
  REAL, ALLOCATABLE :: wetcanp(:,:,:) ! Canopy water amount
  REAL, ALLOCATABLE :: snowdpth(:,:)  ! Snow depth (m)

  REAL, ALLOCATABLE :: raing(:,:)     ! Grid supersaturation rain
  REAL, ALLOCATABLE :: rainc(:,:)     ! Cumulus convective rain
  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 :: radfrc(:,:,:)  ! Radiation forcing (K/s)
  REAL, ALLOCATABLE :: radsw (:,:)    ! Solar radiation reaching the surface
  REAL, ALLOCATABLE :: rnflx (:,:)    ! Net radiation flux absorbed by surface
  REAL, ALLOCATABLE :: radswnet (:,:) ! Net solar radiation, SWin - SWout
  REAL, ALLOCATABLE :: radlwin  (:,:) ! Incoming longwave radiation

  REAL, ALLOCATABLE :: usflx (:,:)    ! Surface flux of u-momentum (kg/(m*s**2))
  REAL, ALLOCATABLE :: vsflx (:,:)    ! Surface flux of v-momentum (kg/(m*s**2))
  REAL, ALLOCATABLE :: ptsflx(:,:)    ! Surface heat flux (K*kg/(m*s**2))
  REAL, ALLOCATABLE :: qvsflx(:,:)    ! Surface moisture flux (kg/(m**2*s))

  REAL, ALLOCATABLE :: xsc(:)
  REAL, ALLOCATABLE :: ysc(:)
  REAL, ALLOCATABLE :: zps(:,:,:)
  REAL, ALLOCATABLE :: latsc(:,:)
  REAL, ALLOCATABLE :: lonsc(:,:)
  REAL, ALLOCATABLE :: azmsc(:,:)
  REAL, ALLOCATABLE :: sfcr(:,:)
  REAL, ALLOCATABLE :: cmpref(:,:)
  REAL, ALLOCATABLE :: elvsc(:,:,:)
  REAL, ALLOCATABLE :: rngsc(:,:,:)

  REAL, ALLOCATABLE :: reflect(:,:,:)  ! reflectivity (dBZ)
  REAL, ALLOCATABLE :: refz(:,:,:)  ! reflectivity (mm6/m3) 
!
!-----------------------------------------------------------------------
! Temporary working arrays:
!-----------------------------------------------------------------------
!
  REAL, ALLOCATABLE :: tem1(:,:,:)
  REAL, ALLOCATABLE :: tem2(:,:,:)
  REAL, ALLOCATABLE :: tem3(:,:,:)
  REAL, ALLOCATABLE :: tem4(:,:,:)
!
!-----------------------------------------------------------------------
! Az-ran weighting arrays:
!-----------------------------------------------------------------------
!
  REAL, ALLOCATABLE :: delrng(:)
  REAL, ALLOCATABLE :: delazm(:)
  REAL, ALLOCATABLE :: delelv(:)
  REAL, ALLOCATABLE :: wgtpt(:,:,:)
!
!-----------------------------------------------------------------------
! Radar radial arrays
!-----------------------------------------------------------------------
!
  REAL, ALLOCATABLE :: refl(:)
  REAL, ALLOCATABLE :: refatt(:)
  REAL, ALLOCATABLE :: sens(:)
!
!-----------------------------------------------------------------------
! Hit-Miss bookkeeping arrays
!-----------------------------------------------------------------------
!
  INTEGER, ALLOCATABLE :: score(:,:,:)
  INTEGER, ALLOCATABLE :: netscore(:,:)
  REAL, ALLOCATABLE :: tornlat(:,:)
  REAL, ALLOCATABLE :: tornlon(:,:)
!
!-----------------------------------------------------------------------
! Original Observing Radar data variables
!-----------------------------------------------------------------------
!
  CHARACTER (len=4) :: radname
  REAL :: radlat,radlon,radelv,lowest_elv,bmwidth
  INTEGER :: fillopt

  NAMELIST /radar_src/ radname,radlat,radlon,radelv, &
                       lowest_elv,bmwidth,fillopt
!
!-----------------------------------------------------------------------
! Tornado location information
!-----------------------------------------------------------------------
!
  REAL :: torn_azim,torn_rngkm,torn_refl
  NAMELIST /tornado_loc/ torn_azim,torn_rngkm,torn_refl
!
!-----------------------------------------------------------------------
! Spatial offset variables
!-----------------------------------------------------------------------
!
  INTEGER :: adjctr,adjhgt
  REAL :: ctrlatnew,ctrlonnew,hgtoffset
  REAL :: deltax,deltay
  INTEGER :: ioffbgn,ioffend,joffbgn,joffend
  NAMELIST /offsetxy/ adjctr,ctrlatnew,ctrlonnew,                       &
                      adjhgt,hgtoffset,                                 &
                      deltax,deltay,ioffbgn,ioffend,joffbgn,joffend
!
!-----------------------------------------------------------------------
! Radar Network variables
!-----------------------------------------------------------------------
!
  INTEGER, PARAMETER :: mxradnet = 40
  INTEGER :: nradnet,ngate,pulseopt,dualprf
  INTEGER :: npulse1,npulse2
  REAL :: elvmin,gatesp
  REAL :: pulselen1,pulselen2,pulsewid1,pulsewid2,prt1,prt2
  REAL :: rotrate,beamwid
  REAL :: radnet_lat(mxradnet),radnet_lon(mxradnet)
  REAL :: radnet_elev(mxradnet)
  CHARACTER (len=4) :: radnet(mxradnet)

  NAMELIST /radar_net/ nradnet,ngate,pulseopt,dualprf,                 &
                       elvmin,gatesp,pulselen1,pulselen2,              &
                       pulsewid1,pulsewid2,prt1,prt2,                  &
                       npulse1,npulse2,beamwid,rotrate,                &
                       radnet_lat,radnet_lon,radnet_elev,radnet

  INTEGER :: nptsrng,nptsazm,nptselv
  REAL :: evalwid
  NAMELIST /emul_specs/ nptsrng,nptsazm,nptselv,evalwid
!
!-----------------------------------------------------------------------
! Misc. internal variables
!-----------------------------------------------------------------------
!
  INTEGER, PARAMETER :: kntrmin=5
  REAL, PARAMETER :: rngmin=1000.
  REAL, PARAMETER :: rmisval=-99.
  REAL, PARAMETER :: c = 2.9979e08    ! speed of light m/s
  REAL, PARAMETER :: sumweps=1.0E-04

  INTEGER :: nchin,idxdir
  INTEGER :: grdbas
  INTEGER :: i,j,k,ireturn
  INTEGER :: idx,igate,iradius,jradius,irad
  INTEGER :: ibgn,iend,jbgn,jend,ipt,jpt,ioff,joff
  INTEGER :: iloc1,jloc1,iloc,jloc,ilc,jlc,klc,itgate
  INTEGER :: kpt,npulsmn
  INTEGER :: kntclr,knthob,kntvob,kntfewr,kntr,kntpt,kntintr
  INTEGER :: length, ierr, istatus
  INTEGER :: nt,nhits,nattn,nrng,kntrad

  REAL :: alatnot(2)
  REAL :: rad2deg,deg2rad
  REAL :: twdx2inv,twdxinv,twdy2inv,twdyinv
  REAL :: prtmn,pulselmn,pulsewmn
  REAL :: r11l,r21l,r12l,r22l,r11h,r21h,r12h,r22h
  REAL :: time,hgtmsl,bmwrad,bmwm,elv,azimuth,azrad
  REAL :: depth,dsdr,srange,hgt,sradius,elradius
  REAL :: hlfgtsp,efbmwid,fourln4,wasqinv,wesqinv,da,de,dr
  REAL :: xsw,ysw,ctrx,ctry,xrad,yrad,xrada,yrada,radlata,radlona
  REAL :: srgpt,azmpt,elvpt,hgtpt,sfcrpt
  REAL :: rmax,dhdr,gatspkm,delx,dely
  REAL :: gtlat,gtlon,gtx,gty,xrat,yrat,xpt,ypt
  REAL :: ipos,jpos,irloc,jrloc
  REAL :: w1i,w2i,w1j,w2j,w11,w12,w21,w22
  REAL :: wgt0,wgt1,whigh,wlow,a,b,fjp1,fj0,fjm1
  REAL :: flow,fhigh,reflz,refdbz
  REAL :: reflzkm1,reflzk,reflz0,reflz1,reflz2
  REAL :: pi,cinv,hlftau,aconst,b6,hlfctau,sigr2,sr2inv
  REAL :: wgtg,wgtr,sumwr,sumr
  REAL :: torn_rng,torn0x,torn0y,tornx,torny
  REAL :: tornsfcr,tornhgt,tornelv,tornrngi,torngate
  REAL :: tornref,tornaref,tornsen
  REAL :: hpct,apct,rpct,hsum,asum

  CHARACTER(len=24) :: varunits
  CHARACTER(len=6) :: varid
  CHARACTER(len=24) :: varname
  CHARACTER(len=180), PARAMETER :: tornfile='tornscore.txt'
  CHARACTER(len=180), PARAMETER :: tornstat='tornstat.txt'

  LOGICAL :: echo
  LOGICAL :: hit,rng
  LOGICAL :: printit
!
!-----------------------------------------------------------------------
! Functions
!-----------------------------------------------------------------------
!
  REAL :: effbmw
!
!-----------------------------------------------------------------------
! Variables used in finding height of lowest elv + half beamwidth
!-----------------------------------------------------------------------
!
  REAL, PARAMETER :: refmiss = -90.

  INTEGER :: klow

  REAL :: radarx
  REAL :: radary
  REAL :: bmtop
  REAL :: sfcrng
  REAL :: bmhgt,bmhgtmsl
  REAL :: reflow,hgtlow

!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
  pi=acos(-1.)
  deg2rad=pi/180.
  rad2deg=1./deg2rad
!
!-----------------------------------------------------------------------
!  Get the names of the input data files.
!-----------------------------------------------------------------------
!
  CALL get_input_file_names(hinfmt,grdbasfn,hisfile,nhisfile)

  lengbf = len_trim(grdbasfn)

  CALL get_dims_from_data(hinfmt,grdbasfn(1:lengbf),                    &
       nx,ny,nz,nzsoil,nstyps, ireturn)

  IF (nstyps <= 0) nstyps = 1
  nstyp = nstyps

  IF( ireturn /= 0 ) THEN
    PRINT*,'Problem occured when trying to get dimensions from data.'
    PRINT*,'Program stopped.'
    STOP
  END IF

  WRITE(6,'(4(a,i5))') 'nx =',nx,', ny=',ny,', nz=',nz ,'nzsoil=',nzsoil  
 
  ALLOCATE(x      (nx))       
  ALLOCATE(y      (ny))       
  ALLOCATE(z      (nz))       
  ALLOCATE(zp     (nx,ny,nz)) 
  ALLOCATE(zpsoil (nx,ny,nzsoil)) 

  ALLOCATE(uprt (nx,ny,nz),STAT=istatus)
  CALL check_alloc_status(istatus, "uprt")

  ALLOCATE(vprt (nx,ny,nz),STAT=istatus)
  CALL check_alloc_status(istatus, "vprt")

  ALLOCATE(wprt (nx,ny,nz),STAT=istatus)
  CALL check_alloc_status(istatus, "wprt")

  ALLOCATE(ptprt  (nx,ny,nz)) 
  ALLOCATE(pprt   (nx,ny,nz)) 
  ALLOCATE(qvprt  (nx,ny,nz)) 
  ALLOCATE(qc     (nx,ny,nz)) 
  ALLOCATE(qr     (nx,ny,nz)) 
  ALLOCATE(qi     (nx,ny,nz)) 
  ALLOCATE(qs     (nx,ny,nz)) 
  ALLOCATE(qh     (nx,ny,nz)) 


  ALLOCATE(tke    (nx,ny,nz)) 
  ALLOCATE(kmh    (nx,ny,nz)) 
  ALLOCATE(kmv    (nx,ny,nz)) 
  ALLOCATE(ubar   (nx,ny,nz)) 
  ALLOCATE(vbar   (nx,ny,nz)) 
  ALLOCATE(wbar   (nx,ny,nz)) 
  ALLOCATE(ptbar  (nx,ny,nz)) 
  ALLOCATE(pbar   (nx,ny,nz)) 
  ALLOCATE(rhobar (nx,ny,nz)) 

  ALLOCATE(qvbar  (nx,ny,nz)) 
  ALLOCATE(u      (nx,ny,nz)) 
  ALLOCATE(v      (nx,ny,nz)) 
  ALLOCATE(w      (nx,ny,nz)) 
  ALLOCATE(qv     (nx,ny,nz)) 

  ALLOCATE(soiltyp (nx,ny,nstyps))    
  ALLOCATE(stypfrct(nx,ny,nstyps))    
  ALLOCATE(vegtyp (nx,ny))     
  ALLOCATE(lai    (nx,ny))    
  ALLOCATE(roufns (nx,ny))    
  ALLOCATE(veg    (nx,ny))    

  ALLOCATE(tsoil (nx,ny,nzsoil,0:nstyps))    
  ALLOCATE(qsoil (nx,ny,nzsoil,0:nstyps))    
  ALLOCATE(wetcanp(nx,ny,0:nstyps))    
  ALLOCATE(snowdpth(nx,ny))            

  ALLOCATE(raing(nx,ny))         
  ALLOCATE(rainc(nx,ny))         
  ALLOCATE(prcrate(nx,ny,4))     

  ALLOCATE(radsw (nx,ny))        
  ALLOCATE(rnflx (nx,ny))        
  ALLOCATE(radswnet (nx,ny))        
  ALLOCATE(radlwin (nx,ny))        
  
  ALLOCATE(radfrc(nx,ny,nz))     

  ALLOCATE(usflx (nx,ny))        
  ALLOCATE(vsflx (nx,ny))        
  ALLOCATE(ptsflx(nx,ny))        
  ALLOCATE(qvsflx(nx,ny))        
  ALLOCATE(tem1(nx,ny,nz))
  ALLOCATE(tem2(nx,ny,nz))
  ALLOCATE(tem3(nx,ny,nz))
  ALLOCATE(tem4(nx,ny,nz))

  ALLOCATE(xsc   (nx))       
  ALLOCATE(ysc   (ny))       
  ALLOCATE(latsc(nx,ny))
  ALLOCATE(lonsc(nx,ny))
  ALLOCATE(azmsc(nx,ny))
  ALLOCATE(sfcr(nx,ny))
  ALLOCATE(cmpref(nx,ny))

  ALLOCATE(zps    (nx,ny,nz)) 
  ALLOCATE(reflect(nx,ny,nz))
  ALLOCATE(refz(nx,ny,nz))
  ALLOCATE(elvsc(nx,ny,nz))
  ALLOCATE(rngsc(nx,ny,nz))

  x      =0.0
  y      =0.0
  z      =0.0
  zp     =0.0
  zpsoil =0.0

  uprt   =0.0
  vprt   =0.0
  wprt   =0.0
  ptprt  =0.0
  pprt   =0.0
  qvprt  =0.0
  qc     =0.0
  qr     =0.0
  qi     =0.0
  qs     =0.0
  qh     =0.0
  tke    =0.0
  kmh    =0.0
  kmv    =0.0
  ubar   =0.0
  vbar   =0.0
  wbar   =0.0
  ptbar  =0.0
  pbar   =0.0
  rhobar =0.0
  qvbar  =0.0
  u      =0.0
  v      =0.0
  w      =0.0
  qv     =0.0

  soiltyp =0.0
  stypfrct=0.0
  vegtyp =0.0
  lai    =0.0
  roufns =0.0
  veg    =0.0

  tsoil  =0.0
  qsoil  =0.0
  wetcanp=0.0
  snowdpth=0.0

  raing=0.0
  rainc=0.0
  prcrate=0.0

  radfrc=0.0
  radsw =0.0
  rnflx =0.0
  radswnet = 0.0
  radlwin = 0.0

  usflx =0.0
  vsflx =0.0
  ptsflx=0.0
  qvsflx=0.0
  tem1=0.0
  tem2=0.0
  tem4=0.0

  xsc=0.
  ysc=0.
  latsc=0.
  lonsc=0.
  azmsc=0.
  sfcr=0.
  cmpref=0.
  zps=0.
  reflect=0.
  refz=0.
  elvsc=0.
  rngsc=0.

  lengbf=len_trim(grdbasfn)
  WRITE(6,'(/a,a)')' The grid/base name is ', grdbasfn(1:lengbf)

  lenfil=len_trim(hisfile(1))
  WRITE(6,'(/a,a,a)')                                                 &
        ' Data set ', trim(hisfile(1)),' to be converted.'
!
!-----------------------------------------------------------------------
!  Read all input data arrays
!-----------------------------------------------------------------------

  CALL dtaread(nx,ny,nz,nzsoil,nstyps,                                &
                 hinfmt, nchin,grdbasfn(1:lengbf),lengbf,               &
                 hisfile(1)(1:lenfil),lenfil,time,                  &
                 x,y,z,zp,zpsoil, uprt ,vprt ,wprt ,ptprt, pprt ,       &
                 qvprt, qc, qr, qi, qs, qh, tke,kmh,kmv,                &
                 ubar, vbar, wbar, ptbar, pbar, rhobar, qvbar,          &
                 soiltyp,stypfrct,vegtyp,lai,roufns,veg,                &
                 tsoil, qsoil, wetcanp,snowdpth,                        &
                 raing,rainc,prcrate,                                   &
                 radfrc,radsw,rnflx,radswnet,radlwin,                   &
                 usflx,vsflx,ptsflx,qvsflx,                             &
                 ireturn, tem1, tem2, tem3)

  CALL gtlfnkey( runname, lfnkey )
  idxdir=index(hisfile(1)(1:lenfil),runname(1:lfnkey),.true.)
  IF(idxdir<=1) THEN
    dirname='.'
  ELSE 
    IF(hisfile(1)(idxdir-1:idxdir-1) == '/') THEN
      dirname=hisfile(1)(1:idxdir-2)
    ELSE
      dirname=hisfile(1)(1:idxdir-1)
    END IF
  END IF
  print *, ' ATTEN dirname= ',dirname
  ldirnam=LEN(dirname)
  CALL strlnth( dirname , ldirnam)

  curtim = time
  dx=(x(2)-x(1))
  dy=(y(2)-y(1))
  dxinv=1./dx
  dyinv=1./dy

  twdx2inv=1./(2.*dx*dx)
  twdxinv=1./(2.*dx)
  twdy2inv=1./(2.*dy*dy)
  twdyinv=1./(2.*dy)

  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)

  if( ireturn /= 0 ) then 
     WRITE(6,'(1x,a,i2,/1x,a)')                                       &
    'Data read was unsuccessful. ireturn =', ireturn,' Job stopped.'
     STOP
  endif
!
  radname='KTLX'
  radlat=35.33
  radlon=-97.28
  radelv=350.0
  lowest_elv=0.5

  WRITE(6,'(a)') ' Reading radar_src namelist...'
  READ(5,radar_src)
  WRITE(6,'(a/)') ' Namelist radar_src successfully read.'
!
!-----------------------------------------------------------------------
! Get tornado location relative to original observing radar
!-----------------------------------------------------------------------
!
  torn_azim=300.
  torn_rngkm=65.
  torn_refl=40.

  WRITE(6,'(a)') ' Reading tornado_loc namelist...'
  READ(5,tornado_loc)
  WRITE(6,'(a/)') ' Namelist tornado_loc successfully read.'
  torn_rng=1000.0*torn_rngkm
!
!-----------------------------------------------------------------------
! Get offset control variables
!-----------------------------------------------------------------------
!
  adjctr=0
  adjhgt=0
  ctrlatnew=35.
  ctrlonnew=-98.
  hgtoffset=0.
  deltax=3000.
  deltay=3000.
  ioffbgn=-10
  ioffend=10
  joffbgn=-10
  joffend=10

  WRITE(6,'(a)') ' Reading offsetxy namelist...'
  READ(5,offsetxy)
  WRITE(6,'(a/)') ' Namelist offsetxy successfully read.'
!
!-----------------------------------------------------------------------
! Get radar network observing locations
! and operating specs for network radar
!-----------------------------------------------------------------------
!
  nradnet=1
  ngate=150
  elvmin=1.0
  gatesp=200.
  dualprf=1
  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
  beamwid = 2.0
  rotrate=18.
  evalwid=2.0

  WRITE(6,'(a)') ' Reading radar_net namelist...'
  READ(5,radar_net)
  WRITE(6,'(a/)') ' Namelist radar_net successfully read.'
!
  gatspkm=0.001*gatesp
  hlfgtsp=0.5*gatesp
  ALLOCATE(refl(ngate))
  refl=0.
  ALLOCATE(refatt(ngate))
  refatt=0.
  ALLOCATE(sens(ngate))
  sens=0.
  ALLOCATE(score(ioffbgn:ioffend,joffbgn:joffend,nradnet))
  score=-99
  ALLOCATE(netscore(ioffbgn:ioffend,joffbgn:joffend))
  score=-99
  ALLOCATE(tornlat(ioffbgn:ioffend,joffbgn:joffend))
  tornlat=-999.
  ALLOCATE(tornlon(ioffbgn:ioffend,joffbgn:joffend))
  tornlon=-999.
!
  CALL radcoord(nx,ny,nz,                                              &
                     x,y,z,zp,xsc,ysc,zps,                             &
                     radlat,radlon,radarx,radary)
  varid='reflct'
  CALL readvar1(nx,ny,nz, reflect, varid, varname,                     &
                varunits, time, runname, dirname, istatus)

  elv=elvmin

  IF(fillopt > 0 ) THEN
!
! Fill in radar reflectivity below the lowest beam height using
! zero gradient assumption.
!
    bmtop=lowest_elv+0.5*bmwidth
    DO j=1,ny
      DO i=1,nx
!
!   find height of lowest elev + half beamwidth
!
        delx=xsc(i)-radarx
        dely=ysc(j)-radary
        sfcrng=sqrt(delx*delx+dely*dely)
        CALL bmhgtsfr(bmtop,sfcrng,bmhgt)
        bmhgtmsl=bmhgt+radelv
        klow=nz
        reflow=0.
        hgtlow=1.0E06
        DO k=nz-1,2,-1
          IF(reflect(i,j,k) > refmiss) THEN
            klow=k
            reflow=reflect(i,j,k)
            hgtlow=zps(i,j,k)
          END IF
        END DO
        IF(hgtlow < bmhgtmsl) THEN
          DO k=2,klow-1
            reflect(i,j,k)=reflow
          END DO
        END IF
      END DO
    END DO
  END IF

  DO k=1,nz-1
    DO j=1,ny-1
      DO i=1,nx-1
        IF(reflect(i,j,k) < -30.) reflect(i,j,k)=-30.
      END DO
    END DO
  END DO

  IF(fillopt > 0 ) THEN
    varid='rflctx'
    CALL wrtvar1(nx,ny,nz,reflect, varid,varname,varunits,              &
           time,runname,dirname, istatus)
  END IF

  DO j=1,ny-1
    DO i=1,nx-1
      DO k=2,nz-1
        IF(reflect(i,j,k) > -30.) THEN
          refz(i,j,k)=10.**(0.1*reflect(i,j,k))
        ELSE
          refz(i,j,k)=0.
        END IF
        cmpref(i,j)=max(cmpref(i,j),reflect(i,j,k))
      END DO
    END DO
  END DO
!
!
!-----------------------------------------------------------------------
!
!  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
      pulsewmn=c*pulselmn
    ELSE
      pulsewmn=pulsewid1
      pulselmn=cinv*pulsewmn
    END IF
    prtmn=prt1
    npulsmn=npulse1
  ELSE
    IF(pulseopt == 1) THEN
      pulselmn=0.5*(pulselen1*pulselen2)
      pulsewmn=c*pulselmn
    ELSE
      pulsewmn=0.5*(pulsewid1*pulsewid2)
      pulselmn=cinv*pulsewmn
    END IF
    prtmn=0.5*(prt1+prt2)
    npulsmn=NINT(0.5*(npulse1+npulse2))
  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)

  WRITE(6,'(a,f10.2,a)') ' Mean pulse width: ',pulsewmn,' m'
  WRITE(6,'(a,f10.2,a)') &
    ' Mean pulse length: ',(pulselmn*1.0E06),' microsec'
  WRITE(6,'(a,f10.2,a)') &
    ' Gaussian filtered pulse half-width: ',sqrt(sigr2),' m'

!
!-----------------------------------------------------------------------
! Calculate constants for antenna gain weighting.
!-----------------------------------------------------------------------
!
  IF( abs(rotrate) > 0.) THEN
    efbmwid=EFFBMW(beamwid,rotrate,prtmn,npulsmn)
  ELSE
    efbmwid=beamwid
  END IF

  fourln4=4.0*alog(4.0)
  wasqinv=fourln4/(efbmwid*efbmwid)
  wesqinv=fourln4/(beamwid*beamwid)
  bmwrad=deg2rad*efbmwid
  elradius=evalwid*beamwid
  hlfgtsp=0.5*gatesp

  nptsrng=max(nptsrng,3)
  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

  nptsazm=max(nptsazm,3)
  ALLOCATE (delazm(nptsazm))

  nptselv=max(nptselv,3)
  ALLOCATE (delelv(nptselv))
  de=(evalwid*beamwid)/float(nptselv-1)
  WRITE(6,'(a,f10.2,a,f10.2)') &
   ' Beam width ',beamwid,' Eval region width:',(evalwid*beamwid)
  WRITE(6,'(a)') &
   ' Cross-beam evaluation pts (elev deg from 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

  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)') &
       ' 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

  wasqinv=fourln4/(efbmwid*efbmwid)
  bmwrad=deg2rad*efbmwid
  ALLOCATE (wgtpt(nptsrng,nptsazm,nptselv))

  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 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 ( mapproj == 0 ) THEN
    IF ( adjctr > 0 ) THEN
      ctrlat = ctrlatnew
      ctrlon = ctrlonnew
    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 = ctrlatnew
    ctrlon = ctrlonnew
    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

  torn0x=radarx+torn_rng*sin(deg2rad*torn_azim)
  torn0y=radary+torn_rng*cos(deg2rad*torn_azim)
!
!-----------------------------------------------------------------------
! Adjust grid heights to be compatible with the netrad domain
!-----------------------------------------------------------------------
!
  IF(adjhgt > 0) THEN
    DO k=1,nz
      DO j=1,ny
        DO i=1,nx
          zps(i,j,k)=zps(i,j,k)+hgtoffset
        END DO
      END DO
    END DO
  END IF
!
!-----------------------------------------------------------------------
! Calculate sensitivity values for all distances from radar.
!-----------------------------------------------------------------------
!
  CALL xbsens(ngate,gatesp,sens)
!
!-----------------------------------------------------------------------
! Loop through all possible offsets
!-----------------------------------------------------------------------
!
  DO joff=joffbgn,joffend
  DO ioff=ioffbgn,ioffend
!
!-----------------------------------------------------------------------
!
! Calculate new tornado location for this storm offset.
!
!-----------------------------------------------------------------------
!
    printit=((mod(ioff,10) == 0) .AND. (mod(joff,10) == 0))
    tornx=torn0x+(ioff*deltax)
    torny=torn0y+(joff*deltay)
    CALL xytoll(1,1,tornx,torny,tornlat(ioff,joff),tornlon(ioff,joff))
    IF (printit) &
      WRITE(6,'(a,f12.4,a,f12.4)') ' Tornado lat: ',tornlat(ioff,joff),   &
                                   ' Tornado lon: ',tornlon(ioff,joff)
!
    DO irad=1,nradnet

      IF (printit) &
      WRITE(6,'(a,a)') ' Processing network radar: ',radnet(irad)
!
! Set up radar location info.
! For now, consider just one radar.
! ioff, joff refer to an offset of the grid and hence storm location
! This is accounted for by moving the radar locations by an equal 
! distance in the opposite direction.
!
      CALL lltoxy(1,1,radnet_lat(irad),radnet_lon(irad),xrad,yrad)
      xrada=xrad-umove*curtim
      yrada=yrad-vmove*curtim
      xrada=xrada-(ioff*deltax)
      yrada=yrada-(joff*deltay)
      CALL xytoll(1,1,xrada,yrada,radlata,radlona)
      irloc=((xrada-xsc(1))*dxinv)+1.0
      jrloc=((yrada-ysc(1))*dyinv)+1.0
      IF (printit) &
        WRITE(6,'(a,i3,a,i3,/,a,f10.3,a,f10.3,/a,f10.3,a,f10.3)') &
          ' Ioffset ',ioff,'  Joffset ',joff, &
          ' x-coord (km) ',(0.001*xrada),'  y-coord (km) ',(0.001*yrada),&
          ' i-location: ',irloc,'  j-location:',jrloc
!
!-----------------------------------------------------------------------
!
! Calculate radar parameters at each scalar grid point.
!
!-----------------------------------------------------------------------
!
      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 beam heading to the position of the tornado
!
      delx=torn0x-xrada
      dely=torn0y-yrada
      IF(abs(dely) .gt. 1.0E-06) THEN
        IF(dely .gt. 0.) THEN
          azrad=atan(delx/dely)
        ELSE
          azrad=pi+atan(delx/dely)
        END IF
      ELSE IF(delx .gt. 0.) THEN
        azrad=0.5*pi
      ELSE
        azrad=1.5*pi
      END IF

      azimuth=rad2deg*azrad
      IF(azimuth < 0.) azimuth=azimuth+360.
      IF(azimuth > 360.) azimuth=azimuth-360.
      tornsfcr=sqrt((delx*delx)+(dely*dely))
      CALL bmhgtsfr(elv,tornsfcr,tornhgt)
      CALL beamelv(tornhgt,tornsfcr,tornelv,tornrngi)
      IF (printit) THEN
        WRITE(6,'(a,3(f10.2))') ' torn delx,dely,azimuth: ', &
              (0.001*delx),(0.001*dely),azimuth
        WRITE(6,'(a,3(f10.2))') ' torn elv in, elv out: ', &
              elv,tornelv
        WRITE(6,'(a,3(f10.2))') ' torn sfcrange, range: ',  &
              (0.001*tornsfcr),(0.001*tornrngi)
      END IF
      torngate=(tornrngi/gatesp)
      IF(torngate < float(ngate)) THEN
!
! For this radial, fill a 1d-array with the reflectivity data
!
        kntpt=0
        kntclr=0
        knthob=0
        kntvob=0 
        kntintr=0
        kntfewr=0
        DO igate=1, ngate
          kntpt=kntpt+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
!
!  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)
!             print *, 'bmwm,pulsewid = ',bmwm,pulsewmn
!             print *, 'iradius,jradius = ',iradius,jradius
              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) THEN
!
!  Calculate beam-weighted sums for an uniform array of points around this 
!  range-gate using tri-linear interpolation
!
                kntr=0
                sumr=0.
                sumwr=0.
                DO kpt=1,nptselv
                DO jpt=1,nptsazm
                DO ipt=1,nptsrng
                  srgpt=(igate*gatesp)+delrng(ipt)
                  azmpt=azimuth+delazm(jpt)
                  elvpt=elv+delelv(kpt)
                  CALL beamhgt(elvpt,srgpt,hgtpt,sfcrpt)
                  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/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

                    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

                    hgtmsl=hgtpt+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
                      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

                      reflz2=whigh*fhigh+wlow*flow
!
!   TEST CODE
!
                      reflzk=refz(iloc1,jloc1,k)
                      reflzkm1=refz(iloc1,jloc1,k-1)
                      reflz0=whigh*reflzk+wlow*reflzkm1
!
!   TEST CODE 2
!
                      reflz1=whigh*(w11*refz(iloc,jloc,k) +         &
                                   w21*refz(iloc+1,jloc,k) +        &
                                   w12*refz(iloc,jloc+1,k) +        &
                                   w22*refz(iloc+1,jloc+1,k)) +     &
                             wlow*(w11*refz(iloc,jloc,k-1) +        &
                                   w21*refz(iloc+1,jloc,k-1) +      &
                                   w12*refz(iloc,jloc+1,k-1) +      &
                                   w22*refz(iloc+1,jloc+1,k-1))

            WRITE(36,'(5f12.1)') reflzkm1,reflzk,reflz0,reflz1,reflz2
                      kntr=kntr+1
                      sumr=sumr+reflz0*wgtpt(ipt,jpt,kpt)
                      sumwr=sumwr+wgtpt(ipt,jpt,kpt)

                    END IF ! hgt in grid
                  END IF ! iloc in grid
                END DO
                END DO
                END DO
!
!  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)=max(refdbz,0.)
                ELSE
                  kntfewr=kntfewr+1 
                  refl(igate)=0.
                END IF
              ELSE ! no echo found in area
                kntclr=kntclr+1
                refl(igate)=0.
              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
    
!-----------------------------------------------------------------------
! Calculate attenuation values for all distances from radar.
!-----------------------------------------------------------------------
!
        CALL xbatten(ngate,1,refl,gatesp,rmisval,refatt)

!-----------------------------------------------------------------------
! Output R(km), K'(dB), K(dB), Z(dB), Z'(dB), and Ze_min.
!-----------------------------------------------------------------------

        IF(ioff == 0 .AND. joff == 0) THEN
        WRITE(6,'(5(1x,a10))') &
                'R(km)','Z(dB)','Za(dB)','Za-Sens','Sens'
        WRITE(6,'(a)')                                         &
        '-----------------------------------------------------------------'
   
        DO idx = 5, ngate, 5
          WRITE(6,'(5(1x,f10.3))') &
            (idx*gatspkm),refl(idx),refatt(idx), &
            (refatt(idx)-sens(idx)),sens(idx)
        END DO
        END IF

!-----------------------------------------------------------------------
! Decide if the tornado is detectable from this radar.
!-----------------------------------------------------------------------
        itgate=INT(torngate)
        wgt1=torngate-float(itgate)
        wgt0=1.-wgt1
        tornref=wgt0*refl(itgate)+wgt1*refl(itgate+1)
        tornaref=wgt0*refatt(itgate)+wgt1*refatt(itgate+1)
        tornsen=wgt0*sens(itgate)+wgt1*sens(itgate+1)
        IF(printit) &
          WRITE(6,'(a,f10.2,/a,f10.2,a,f10.2,a,f10.2)') &
            ' At tornado location:  Refl=',tornref, &
            ' Att Ref=',tornaref,' Sens=',tornsen,' Att Ref-Sens=',&
            (tornaref-tornsen)
        IF(tornaref > tornsen) THEN
          score(ioff,joff,irad)=1      ! hit, detectable
        ELSE
          score(ioff,joff,irad)=0      ! attenuated, undetectable
        END IF

      ELSE
        score(ioff,joff,irad)=-1     ! out of range.undetectable
      END IF

    END DO  ! i-radar

  END DO  ! i-offset
  END DO  ! j-offset


!
! Compute summary scores of hits-n-misses 
! First summarize by individual radar
!
  print *, ' writing tornstat file'
  open(42,file=tornstat,status='unknown',form='formatted')
  WRITE(42,'(a)') TRIM(runname)
  WRITE(42,'(i4.4,a,i2.2,a,i2.2,1x,i2.2,a,i2.2,a,i2.2,a)') &
    year,'-',month,'-',day,hour,':',minute,':',second,' UTC'
  WRITE(42,'(a,f8.1,a,f8.1,a,f8.1)')  &
    ' Tornado Azim:',torn_azim,' Range:',torn_rngkm,' Refl:',torn_refl
  WRITE(42,'(/a)') '  Individual Radar Statistics'
  WRITE(42,'(a)') '  Radar    Trials     Hits      Miss   Out-of-Range'
  kntrad=0
  hsum=0.
  asum=0.
  DO irad=1,nradnet
    nt=0
    nhits=0
    nattn=0
    nrng=0
    DO ioff=ioffbgn,ioffend
      DO joff=joffbgn,joffend
        IF(score(ioff,joff,irad) > -90) THEN
          nt=nt+1
          IF(score(ioff,joff,irad) == 1) THEN
            nhits=nhits+1
          ELSE IF (score(ioff,joff,irad) == 0) THEN
            nattn=nattn+1
          ELSE IF (score(ioff,joff,irad) == -1) THEN
            nrng=nrng+1
          END IF 
        END IF
      END DO
    END DO
  
    IF((nt-nrng) > 0 ) THEN 
      hpct=100.*float(nhits)/float(nt-nrng) 
      apct=100.*float(nattn)/float(nt-nrng) 
      hsum=hsum+hpct
      asum=asum+apct
      kntrad=kntrad+1
    ELSE
      hpct=0.
      apct=0.
    END IF
    rpct=100.*float(nrng)/float(nt) 
    WRITE(42,'(a4,i6,3f12.1)') &
      radnet(irad),nt,hpct,apct,rpct
    IF(kntrad > 0) THEN
      hsum=hsum/float(kntrad)
      asum=hsum/float(kntrad)
    END IF
    WRITE(42,'(a4,i6,2f12.1)') &
      'AVG:',kntrad,hsum,asum
  END DO
!
! Compute hits and misses for the network as a whole
!
  WRITE(6,'(a)') ' Computing hits and misses'
  nt=0
  nhits=0
  nattn=0
  nrng=0
  DO joff=joffbgn,joffend
    DO ioff=ioffbgn,ioffend
      nt=nt+1
      hit=.false.
      rng=.false.
      DO irad=1,nradnet
        IF(score(ioff,joff,irad) == 1) hit=.true.
        IF(score(ioff,joff,irad) /= -1) rng=.true.
      END DO
      IF(hit) THEN
        nhits=nhits+1
        netscore(ioff,joff)=1      ! hit, detectable
      ELSE IF (.not.rng) THEN
        nrng=nrng+1
        netscore(ioff,joff)=-1      ! out-of-range
      ELSE
        nattn=nattn+1
        netscore(ioff,joff)=0      ! network miss
      END IF
    END DO
  END DO
  
  IF((nt-nrng) > 0) THEN 
    hpct=100.*float(nhits)/float(nt-nrng) 
    apct=100.*float(nattn)/float(nt-nrng)
  ELSE
    hpct=0.
    apct=0.
  END IF
  rpct=100.*float(nrng)/float(nt) 

  print *, ' writing tornfile file'
  open(41,file=tornfile,status='unknown',form='formatted')
  WRITE(41,'(a)') TRIM(runname)
  WRITE(41,'(i4.4,a,i2.2,a,i2.2,1x,i2.2,a,i2.2,a,i2.2,a)') &
    year,'-',month,'-',day,hour,':',minute,':',second,' UTC'
  WRITE(41,'(a,f8.1,a,f8.1,a,f8.1)')  &
    ' Tornado Azim:',torn_azim,' Range:',torn_rngkm,' Refl:',torn_refl
  DO joff=joffbgn,joffend
    DO ioff=ioffbgn,ioffend
      WRITE(41,'(2i6,2f12.4,13i5)') &
      ioff,joff,tornlat(ioff,joff),tornlon(ioff,joff), &
      netscore(ioff,joff), &
      (score(ioff,joff,irad),irad=1,nradnet)
    END DO
  END DO
  CLOSE(41)

  WRITE(42,'(//a)') 'Network Statistics'
  WRITE(42,'(a)') 'Trials    Hits       Miss      Out-of-Range'
  WRITE(42,'(i6,3f12.1)') nt,hpct,apct,rpct
  CLOSE(42)

  CLOSE(9)

  STOP
END PROGRAM attenuation
!-----------------------------------------------------------------------
! Subroutine atten
!-----------------------------------------------------------------------
!

SUBROUTINE atten(all_rngs,all_refs,seg,att_values,att)
  IMPLICIT NONE
  
  INTEGER :: idx         ! Index.
  INTEGER :: seg         ! Number of distance segments.
  REAL :: att_tally      ! Running tally of attenuation values.
  REAL :: att_const1     ! Attenuation constant 1.
  REAL :: att_const2     ! Attenuation constant 2.
  REAL :: att_const3     ! Attenuation constant 3.

  REAL, DIMENSION(seg),INTENT (IN):: all_rngs      ! Range values for all dist from radar.
  REAL, DIMENSION(seg),INTENT (IN):: all_refs      ! Reflectivity values for all dist from radar.
  REAL, DIMENSION(seg),INTENT (OUT) :: att_values  ! Attenuation values for all dist from radar.
  REAL :: att(seg)                                 ! Attenuation value for a specific distance.
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!

  att_const1 = 2.0*0.01
  att_const2 = 1.0/400.0
  att_const3 = 1.21/1.4
 
  att_tally = 0 

  DO idx = 1, seg
    att(idx) = &
      att_const1*((att_const2*(10.0**(0.1*all_refs(idx))))**att_const3)
    IF(idx == 1) THEN
      att_tally = att_tally + att(idx)
      att_values(idx) = att_tally
    ELSE IF(all_refs(idx) == all_refs(idx-1)) THEN
      att_tally = att_tally + att(idx)
      att_values(idx) = att_tally
    ELSE
      att_tally = att_tally + .75*att(idx-1) + &
        .25*att_const1*((att_const2*(10.0**(0.1*all_refs(idx))))**att_const3)
      att_values(idx) = att_tally
    END IF
  END DO
END SUBROUTINE atten
  
!-----------------------------------------------------------------------
! Subroutine sens
!-----------------------------------------------------------------------
!
!

SUBROUTINE xbsens(ngate,gatesp,sens) 2
! 
!-----------------------------------------------------------------------
! Subroutine xbsens
! Calculate X-band radar sensitivity (dBZ) as a function of range.
!
! Based on information provided by Francesc Joyvount
!
! Keith Brewster and Erin Fay, CAPS
!-----------------------------------------------------------------------
!
  IMPLICIT NONE
     
  INTEGER, INTENT(IN) :: ngate
  REAL, INTENT(IN) :: gatesp
  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 :: tau = 0.67E-06  ! Radar pulse length (s)
  REAL, PARAMETER :: theta = 2.0     ! Antenna half-power beamwidth (deg)
  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 squarred
  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
  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=theta*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*tau)) * ((lmbda*lmbda*four3*rlm)/(Pt*rG*rG))
  DO igate = 1, ngate
     range=igate*gatesp
     sens(igate) = 10.*LOG10(range*range*sconst)
  END DO
END SUBROUTINE xbsens

SUBROUTINE xbatten(ngate,nazim,refl,gatesp,rmisval,refatt) 2
!
!-----------------------------------------------------------------------
!
!  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
!
!
!  OUTPUT:
!  refatt:    Attenuated reflectivity.
!
!-----------------------------------------------------------------------
!
  IMPLICIT NONE

  INTEGER, INTENT (IN)  :: ngate      ! Number of gates
  INTEGER, INTENT (IN)  :: nazim       ! Number of radials
  REAL, INTENT (IN):: refl(ngate,nazim)     ! Reflectivity (dBZ)
  REAL, INTENT (IN)  :: gatesp         ! Gate spacing (m)
  REAL, INTENT (IN)  :: rmisval
  REAL, INTENT (OUT) :: refatt(ngate,nazim) ! Attenuated reflectivities

  INTEGER :: igate,jazim ! Index.
  REAL :: att_tally      ! Running tally of attenuation values.
  REAL :: att_const      ! Attenuation constant
  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...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!
! Use Z-R relationship to develop attenuation constant for rain.
!   refl(dBZ)=10 log10(zrconst*R**zrexp)
!   So R=(10**(refl*.1))**(1/zrexp)
!   Kr(dbZ/km)=krconst*(R**krexp)
!   So
!   Kr=(krconst/zrconst)*(10**(refl*0.1)**(krexp/zrexp))
!
!   Calculating two-way attenuation requires this figure be doubled.
!

  att_exp=krexp/zrexp
  att_const=2.*krconst/(zrconst**att_exp)
  hlfgatsp=0.5*gatesp*mperkm
  
  DO jazim=1, nazim
    IF(refl(1,jazim) .gt. rmisval) THEN
      atten = att_const*((10.0**(0.1*refl(1,jazim)))**att_exp)
      att_tally = atten*hlfgatsp
      refatt(1,jazim) = refl(1,jazim)-att_tally
    ELSE
      atten=0.
      att_tally=0.
      refatt(1,jazim)=refl(1,jazim)
    END IF
    atten_last=atten
    DO igate = 2, ngate
      IF(refl(igate,jazim) .gt. rmisval) THEN
        atten = att_const*((10.0**(0.1*refl(igate,jazim)))**att_exp)
        att_tally = att_tally + hlfgatsp*atten_last + hlfgatsp*atten
        refatt(igate,jazim) = refl(igate,jazim)-att_tally
        atten_last=atten
      ELSE
        refatt(igate,jazim) = refl(igate,jazim)
        atten_last=0.
      END IF
    END DO
  END DO
  RETURN
END SUBROUTINE xbatten
!

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