!########################################################################
!########################################################################
!######### #########
!######### SUBROUTINE setrastergrid #########
!######### #########
!######### Developed by #########
!######### Center for Analysis and Prediction of Storms #########
!######### University of Oklahoma #########
!######### #########
!########################################################################
!########################################################################
SUBROUTINE setrastergrid(rasterdim,radar_lat,radar_lon,rasterdx, & 1,2
rasterlat,rasterlon,rasterx,rastery, &
rasterdata,missing)
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Calculate latitudes/longitudes and Cartesian coordinates (relative to
! radar) of NIDS raster grid points surrounding a radar. Also, resets
! raster data to missing if raster point is beyond radar range.
!
!-----------------------------------------------------------------------
!
! AUTHOR: Eric Kemp, 5 April 2001
!
! MODIFICATION HISTORY:
!
! Eric Kemp, 1 August 2001
! Changed rasterx and rastery to automatic arrays, and added USE
! statement to module n2aconst.
!
! Eric Kemp, 9 August 2001
! Reversed earlier changes -- rasterx and rastery are now arguments
! with INTENT(OUT). Also, added rasterdata array and missing flag
! as arguments.
!
!-----------------------------------------------------------------------
!
! Use modules
!
!-----------------------------------------------------------------------
USE n2aconst
!-----------------------------------------------------------------------
!
! Force explicit declarations
!
!-----------------------------------------------------------------------
IMPLICIT NONE
!-----------------------------------------------------------------------
!
! Declare arguments
!
!-----------------------------------------------------------------------
INTEGER, INTENT(IN) :: rasterdim ! Dimension of raster grid
REAL,INTENT(IN) :: radar_lat ! Radar latitude (positive deg north)
REAL,INTENT(IN) :: radar_lon ! Radar longitude (positive deg east)
REAL,INTENT(IN) :: rasterdx ! Raster grid spacing (m)
REAL,INTENT(OUT) :: rasterlat(rasterdim,rasterdim) ! Latitude of raster
! grid points
! (positive deg
! north)
REAL,INTENT(OUT) :: rasterlon(rasterdim,rasterdim) ! Longitude of raster
! grid points
! (positive deg east)
REAL,INTENT(OUT) :: rasterx(rasterdim,rasterdim) ! x-coordinate of
! grid points
REAL,INTENT(OUT) :: rastery(rasterdim,rasterdim) ! y-coordinate of
! grid points
REAL,INTENT(INOUT) :: rasterdata(rasterdim,rasterdim) ! Raster data
! array.
REAL,INTENT(IN) :: missing ! Missing value
! flag.
!-----------------------------------------------------------------------
!
! Internal variables
!
!-----------------------------------------------------------------------
REAL :: dist,head
INTEGER :: istatus
INTEGER :: i,j
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!-----------------------------------------------------------------------
!
! Construct raster Cartesian grid centered on and relative to the radar.
!
!-----------------------------------------------------------------------
DO j = 1,rasterdim ! Column
DO i = 1,rasterdim ! Row
rasterx(i,j) = rasterdx*(REAL(i) - REAL(rasterdim*0.5) - 0.5) ! m
rastery(i,j) = rasterdx*(REAL(j) - REAL(rasterdim*0.5) - 0.5) ! m
END DO ! Row
END DO ! Column
!-----------------------------------------------------------------------
!
! Calculate latitudes and longitudes of each raster point by following
! the great circle path from the radar (lat and lon) to the raster
! point. Also, set rasterdata to missing if it is beyond 230 km from
! the radar.
!
!-----------------------------------------------------------------------
DO j = 1,rasterdim ! Column
DO i = 1,rasterdim ! Row
dist = SQRT( (rasterx(i,j)*rasterx(i,j)) + &
(rastery(i,j)*rastery(i,j)) )
IF (dist > 230000.) THEN
rasterdata(i,j) = missing
END IF
IF (rasterx(i,j) == 0 .AND. rastery(i,j) == 0) THEN
head = 0.
ELSE
head = ATAN2(rasterx(i,j),rastery(i,j))*rad2deg
END IF
CALL gcircle
(radar_lat,radar_lon,head,dist, &
rasterlat(i,j),rasterlon(i,j))
END DO ! Row
END DO ! Column
RETURN
END SUBROUTINE setrastergrid
!########################################################################
!########################################################################
!######### #########
!######### SUBROUTINE remapraster #########
!######### #########
!######### Developed by #########
!######### Center for Analysis and Prediction of Storms #########
!######### University of Oklahoma #########
!######### #########
!########################################################################
!########################################################################
SUBROUTINE remapraster(nx,ny,xs2d,ys2d,dx,rasterchek,datamiss,xrad,yrad,& 2,4
remapopt,radius,rnx,rny,rasterdata, &
radx,rady,remdata,istatus)
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Remap 2d raster data to ARPS grid. Several remapping methods are
! available:
!
! 1. Bi-quadratic interpolation. IMPORTANT: Raster and ARPS
! Cartesian coordinates must be in radar projection space.
!
! 2. Bi-quadratic regression (requires radius of influence).
!
! a. If at least eight radar data points are matched to an ARPS
! scalar point, a bi-quadratic regression equation of the
! form V = A + B*x + C*y + D*x*x + E*y*y is solved for
! to determine the data value at the scalar point. A check
! is made to make sure that the solution is within the
! maximum and minimum radar point values; if this criteria
! is not met, the minimum radar point value is substituted
! for the regression solution.
!
! b. If between one and eight radar data points are matched to
! an ARPS scalar point, the radar point values are simply
! averaged.
!
! 3. Using maximum raster value (requires radius of influence).
!
!-----------------------------------------------------------------------
!
! AUTHOR: Eric Kemp, 27 April 2001
! Based on subroutine 'remap' by Keith Brewster and
! interpolation procedure used in program arpsextsnd.
!
! MODIFICATION HISTORY:
!
! Eric Kemp, 1 August 2001
! Reorganized code and updated documentation.
!
! Eric Kemp, 9 August 2001
! Changed ARPS scalar grid point arguments to 2-dimensions.
!
!-----------------------------------------------------------------------
!
! Force explicit declarations
!
!-----------------------------------------------------------------------
IMPLICIT NONE
!-----------------------------------------------------------------------
!
! Declare arguments
!
!-----------------------------------------------------------------------
INTEGER, INTENT(IN) :: nx,ny ! Dimensions of ARPS grid
INTEGER, INTENT(IN) :: rnx, rny ! Dimensions of raster data
INTEGER, INTENT(IN) :: remapopt ! Remapping option.
! 1 = Bi-quadratic interpolation
! 2 = Bi-quadratic regreesion/mean
! 3 = Maximum raster value
REAL, INTENT(IN) :: radius ! Radius of influence used with
! remapopt = 2 or 3.
REAL, INTENT(IN) :: dx ! ARPS horizontal grid resolution (m)
REAL, INTENT(IN) :: rasterchek ! Flag for missing raster data.
REAL, INTENT(IN) :: datamiss ! Flag for missing remapped data.
REAL, INTENT(IN) :: xs2d(nx,ny),ys2d(nx,ny) ! Scalar coordinates of
! ARPS grid points (m).
REAL, INTENT(IN) :: xrad,yrad ! Scalar coordinates of radar (m).
REAL, INTENT(IN) :: rasterdata(rnx,rny) ! Raster data (VIL, echo top,
! etc.)
REAL, INTENT(IN) :: radx(rnx,rny) ! x coordinate of raster point.
REAL, INTENT(IN) :: rady(rnx,rny) ! y coordinate of raster point.
REAL, INTENT(OUT) :: remdata(nx,ny) ! Remapped radar data.
INTEGER, INTENT(OUT) :: istatus ! Status variable
!-----------------------------------------------------------------------
!
! Declare functions
!
!-----------------------------------------------------------------------
REAL :: pntint2d2d
!-----------------------------------------------------------------------
!
! Interpolation arrays
!
!-----------------------------------------------------------------------
INTEGER, ALLOCATABLE :: ipt(:,:)
INTEGER, ALLOCATABLE :: jpt(:,:)
REAL, ALLOCATABLE :: dxfld(:,:)
REAL, ALLOCATABLE :: dyfld(:,:)
REAL, ALLOCATABLE :: rdxfld(:,:)
REAL, ALLOCATABLE :: rdyfld(:,:)
REAL, ALLOCATABLE :: slopey(:,:)
REAL, ALLOCATABLE :: alphay(:,:)
REAL, ALLOCATABLE :: betay(:,:)
!-----------------------------------------------------------------------
!
! Declare internal variables for least-squares curve fitting.
!
!-----------------------------------------------------------------------
INTEGER, PARAMETER :: n = 5 ! Quadratic
REAL, ALLOCATABLE :: araster(:,:)
REAL, ALLOCATABLE :: rhsraster(:)
REAL, ALLOCATABLE :: sol(:)
REAL, ALLOCATABLE :: work(:,:)
REAL, ALLOCATABLE :: work1d(:)
!-----------------------------------------------------------------------
!
! Other internal variables
!
!-----------------------------------------------------------------------
REAL :: ddx,ddy
REAL :: dxthr
LOGICAL :: rastergood
REAL :: rastermax, rastermin, rastermean
INTEGER :: i,j,ii,jj
REAL :: delx, dely
REAL :: slrange
INTEGER :: knt
REAL, PARAMETER :: eps = 1.0E-25
INTEGER, PARAMETER :: iorder = 2 ! Bi-quadratic interpolation
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IF (remapopt < 1 .OR. remapopt > 3) THEN
WRITE(6,*)'remapraster: ERROR -- Invalid remap option.'
WRITE(6,*)'remapraster: remapopt = ',remapopt
WRITE(6,*)'remapraster: Aborting...'
istatus = 1
RETURN
END IF
remdata(:,:) = datamiss
!-----------------------------------------------------------------------
!
! Allocate necessary arrays and coefficients.
!
!-----------------------------------------------------------------------
IF (remapopt == 1) THEN ! Bi-quadratic interpolation
ALLOCATE(ipt(nx,ny),STAT=istatus)
ALLOCATE(jpt(nx,ny),STAT=istatus)
ALLOCATE(dxfld(rnx,rny),STAT=istatus)
ALLOCATE(dyfld(rny,rny),STAT=istatus)
ALLOCATE(rdxfld(rnx,rny),STAT=istatus)
ALLOCATE(rdyfld(rnx,rny),STAT=istatus)
ALLOCATE(slopey(rnx,rny),STAT=istatus)
ALLOCATE(alphay(rnx,rny),STAT=istatus)
ALLOCATE(betay(rnx,rny),STAT=istatus)
CALL setijloc2
(rnx,rny,nx,ny,ipt,jpt,radx,rady,xs2d,ys2d)
CALL setdxdy2d
(rnx,rny, &
1,rnx,1,rny, &
radx,rady,dxfld,dyfld,rdxfld,rdyfld)
CALL setdrvy2d
(rnx,rny,1, &
1,rnx,1,rny,1,1, &
dyfld,rdyfld,rasterdata, &
datamiss,slopey,alphay,betay)
ELSE
ALLOCATE(araster(n,n),STAT=istatus)
ALLOCATE(rhsraster(n),STAT=istatus)
ALLOCATE(sol(n),STAT=istatus)
ALLOCATE(work(n,n+1),STAT=istatus)
ALLOCATE(work1d(n+1),STAT=istatus)
END IF ! IF (remapopt == 1)
DO j=1,ny
DO i=1,nx
!-----------------------------------------------------------------------
!
! Proceed with the bi-quadratic interpolation.
!
!-----------------------------------------------------------------------
IF (remapopt == 1) THEN
IF (ipt(i,j) <= rnx-1 .AND. ipt(i,j) >= 1 .AND. &
jpt(i,j) <= rny-1 .AND. jpt(i,j) >= 1) THEN
remdata(i,j)=pntint2d2d(rnx,rny, &
1,rnx-1,1,rny-1, &
iorder,radx,rady,xs2d(i,j),ys2d(i,j), &
ipt(i,j),jpt(i,j),rasterdata, &
dxfld,dyfld,rdxfld,rdyfld, &
datamiss,slopey,alphay,betay)
IF (remdata(i,j) /= datamiss) THEN
remdata(i,j) = MAX(0.,remdata(i,j))
END IF
END IF
ELSE ! remapopt /= 1
!-----------------------------------------------------------------------
!
! Using an option that requires the radius of influence. First,
! determine the distance between the current ARPS grid point and
! the radar.
!
!-----------------------------------------------------------------------
delx=xs2d(i,j)-xrad
dely=ys2d(i,j)-yrad
slrange=SQRT(delx*delx + dely*dely)
IF (slrange > 0.) THEN
rastermax = -9999.
rastermin = 9999.
araster(:,:) = 0.
rhsraster(:) = 0.
!-----------------------------------------------------------------------
!
! Loop through each raster data point, searching for valid
! data.
!
!-----------------------------------------------------------------------
DO jj = 1,rny
DO ii = 1,rnx
rastergood = (rasterdata(ii,jj) > rasterchek)
IF (rastergood) THEN
!-----------------------------------------------------------------------
!
! For a "valid" raster data point, find the distance
! between the data point and the current ARPS scalar
! grid point.
!
!-----------------------------------------------------------------------
ddx=radx(ii,jj)-xs2d(i,j)
ddy=rady(ii,jj)-ys2d(i,j)
!-----------------------------------------------------------------------
!
! Compare radius of influence with actual horizontal
! ddx and ddy) distances between the raster point and the
! ARPS scalar point. If actual distance is within the
! threshold, we'll process the raster point.
!
!-----------------------------------------------------------------------
dxthr = radius
IF ( SQRT((ddx*ddx) + (ddy*ddy)) < dxthr ) THEN
rastermax=MAX(rastermax,rasterdata(ii,jj))
rastermin=MIN(rastermin,rasterdata(ii,jj))
IF (remapopt == 2) THEN ! Regression/average option
!-----------------------------------------------------------------------
!
! Save raster data and 2-D raster point to grid point
! data. These data will be used to determine the
! grid point value using least squares curve fitting
! (Data = A + B*ddx + C*ddy + D*ddx*ddx + E*ddy*ddy).
!
!-----------------------------------------------------------------------
rhsraster(1)=rhsraster(1)+rasterdata(ii,jj)
rhsraster(2)=rhsraster(2)+rasterdata(ii,jj)*ddx
rhsraster(3)=rhsraster(3)+rasterdata(ii,jj)*ddy
rhsraster(4)=rhsraster(4)+rasterdata(ii,jj)*ddx*ddx
rhsraster(5)=rhsraster(5)+rasterdata(ii,jj)*ddy*ddy
araster(1,1)=araster(1,1)+1.
araster(1,2)=araster(1,2)+ddx
araster(1,3)=araster(1,3)+ddy
araster(1,4)=araster(1,4)+(ddx*ddx)
araster(1,5)=araster(1,5)+(ddy*ddy)
araster(2,1)=araster(2,1)+ddx
araster(2,2)=araster(2,2)+ddx*ddx
araster(2,3)=araster(2,3)+ddx*ddy
araster(2,4)=araster(2,4)+ddx*ddx*ddx
araster(2,5)=araster(2,5)+ddx*ddy*ddy
araster(3,1)=araster(3,1)+ddy
araster(3,2)=araster(3,2)+ddy*ddx
araster(3,3)=araster(3,3)+ddy*ddy
araster(3,4)=araster(3,4)+ddy*ddx*ddx
araster(3,5)=araster(3,5)+ddy*ddy*ddy
araster(4,1)=araster(4,1)+ddx*ddx
araster(4,2)=araster(4,2)+ddx*ddx*ddx
araster(4,3)=araster(4,3)+ddx*ddx*ddy
araster(4,4)=araster(4,4)+ddx*ddx*ddx*ddx
araster(4,5)=araster(4,5)+ddx*ddx*ddy*ddy
araster(5,1)=araster(5,1)+ddy*ddy
araster(5,2)=araster(5,2)+ddy*ddy*ddx
araster(5,3)=araster(5,3)+ddy*ddy*ddy
araster(5,4)=araster(5,4)+ddy*ddy*ddx*ddx
araster(5,5)=araster(5,5)+ddy*ddy*ddy*ddy
END IF ! remapopt
END IF ! (ABS(ddx) < dxthr .AND. ABS(ddy) < dxthr)
END IF ! Is rastergood true?
END DO ! ii loop
END DO ! jj loop
!-----------------------------------------------------------------------
!
! At this point we've gone through all the radar pixels to see
! which one(s) can be matched to an ARPS grid point. Now we'll
! process the data we've saved.
!
!-----------------------------------------------------------------------
IF (remapopt == 3) THEN ! Use maximum value
remdata(i,j) = rastermax
ELSE ! remapopt == 2
knt = NINT(araster(1,1)) ! Number of raster points matched
! to grid point.
IF (knt >= 8) THEN
! IF (knt >= 5) THEN
!-----------------------------------------------------------------------
!
! If at least eight raster points have been matched to the
! grid point, use Gauss-Jordan elimination to calculate the
! constants in the least square curve equation. The
! resulting grid point value is then checked with the
! maximum and minimum raster point values.
!
!-----------------------------------------------------------------------
CALL gjelim
(n,araster,rhsraster,sol,work,work1d,eps, &
istatus)
remdata(i,j) = MIN(rastermax,MAX(rastermin,sol(1)))
! ELSE IF (knt >= 4) THEN
ELSE IF (knt >= 1) THEN
!-----------------------------------------------------------------------
!
! If at least one (but less than eight) raster points have
! been matched to the grid point, simply calculate the
! average raster value and assign it to the grid point.
!
!-----------------------------------------------------------------------
rastermean=rhsraster(1)/araster(1,1)
remdata(i,j)=rastermean
END IF ! knt
END IF ! remapopt = 2 vs. 3
END IF ! slrange > 0.
END IF ! if remapopt = 1
END DO ! i loop
END DO ! j loop
!-----------------------------------------------------------------------
!
! Deallocate arrays and return.
!
!-----------------------------------------------------------------------
IF (remapopt == 1) THEN
DEALLOCATE(ipt,jpt,dxfld,dyfld,rdxfld,rdyfld,slopey,alphay,betay, &
STAT=istatus)
ELSE
DEALLOCATE(araster,rhsraster,sol,work,work1d,STAT=istatus)
END IF
istatus = 0
RETURN
END SUBROUTINE remapraster
!########################################################################
!########################################################################
!######### #########
!######### SUBROUTINE setdxdy2d #########
!######### #########
!######### Developed by #########
!######### Center for Analysis and Prediction of Storms #########
!######### University of Oklahoma #########
!######### #########
!########################################################################
!########################################################################
SUBROUTINE setdxdy2d(nx,ny, & 1
ibeg,iend,jbeg,jend, &
x2d,y2d,dxfld,dyfld,rdxfld,rdyfld)
!-----------------------------------------------------------------------
!
! PURPOSE:
! Calculate the local delta-x, delta-y and their inverses.
! Precalculating these variables speeds up later calculations.
!
!-----------------------------------------------------------------------
!
! AUTHOR: Keith Brewster, CAPS, November, 1996
!
! MODIFICATION HISTORY:
!
! Eric Kemp, 27 April 2001
! Modified to allow for two-dimensioned arrays.
!
! Eric Kemp, 9 August 2001
! Added INTENT statements.
!
!-----------------------------------------------------------------------
!
! Force explicit declarations
!
!-----------------------------------------------------------------------
IMPLICIT NONE
!-----------------------------------------------------------------------
!
! INPUT:
! nx Number of model grid points in the x-direction (east/west)
! ny Number of model grid points in the y-direction (north/south)
!
! ibeg,iend Range of x index to do interpolation
! jbeg,jend Range of y index to do interpolation
!
! x2d Array of x-coordinate grid locations (m)
! y2d Array of y-coordinate grid locations (m)
!
! OUTPUT:
! dxfld Vector of delta-x (m) of field to be interpolated
! dyfld Vector of delta-y (m) of field to be interpolated
! rdxfld Vector of 1./delta-x (1/m) of field to be interpolated
! rdyfld Vector of 1./delta-y (1/m) of field to be interpolated
!
!-----------------------------------------------------------------------
INTEGER, INTENT(IN) :: nx,ny
INTEGER, INTENT(IN) :: ibeg,iend
INTEGER, INTENT(IN) :: jbeg,jend
REAL, INTENT(IN) :: x2d(nx,ny)
REAL, INTENT(IN) :: y2d(nx,ny)
REAL, INTENT(OUT) :: dxfld(nx,ny)
REAL, INTENT(OUT) :: dyfld(nx,ny)
REAL, INTENT(OUT) :: rdxfld(nx,ny)
REAL, INTENT(OUT) :: rdyfld(nx,ny)
!-----------------------------------------------------------------------
!
! Misc. local variables
!
!-----------------------------------------------------------------------
INTEGER :: i,j,istop,jstop
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
istop=MIN((iend-1),(nx-1))
jstop=MIN((jend-1),(ny-1))
DO j=jbeg,jstop
DO i=ibeg,istop
dxfld(i,j)=(x2d(i+1,j)-x2d(i,j))
rdxfld(i,j)=1./(x2d(i+1,j)-x2d(i,j))
dyfld(i,j)=(y2d(i,j+1)-y2d(i,j))
rdyfld(i,j)=1./(y2d(i,j+1)-y2d(i,j))
END DO ! i loop
END DO ! j loop
RETURN
END SUBROUTINE setdxdy2d
!########################################################################
!########################################################################
!######### #########
!######### SUBROUTINE setdrvy2d #########
!######### #########
!######### Developed by #########
!######### Center for Analysis and Prediction of Storms #########
!######### University of Oklahoma #########
!######### #########
!########################################################################
!########################################################################
SUBROUTINE setdrvy2d(nx,ny,nz, & 1
ibeg,iend,jbeg,jend,kbeg,kend, &
dyfld,rdyfld,var, &
missing,slopey,alphay,betay)
!-----------------------------------------------------------------------
!
! PURPOSE:
! Calculate the coefficients of interpolating polynomials
! in the y-direction.
!
!-----------------------------------------------------------------------
!
! AUTHOR: Keith Brewster, CAPS, November, 1996
!
! MODIFICATION HISTORY:
!
! Eric Kemp, 27 April 2001
! Modified to allow for 2D arrays
!
! Eric Kemp, 7 August 2001
! Modified to check for missing data, and added INTENT statements.
!
!-----------------------------------------------------------------------
!
! Force explicit declarations.
!
!-----------------------------------------------------------------------
IMPLICIT NONE
!-----------------------------------------------------------------------
!
! INPUT:
! nx Number of model grid points in the x-direction (east/west)
! ny Number of model grid points in the y-direction (north/south)
! nz Number of model grid points in the vertical
!
! ibeg,iend Range of x index to do interpolation
! jbeg,jend Range of y index to do interpolation
! kbeg,kend Range of z index to do interpolation
!
! dyfld Vector of delta-y (m) of field to be interpolated
! rdyfld Vector of 1./delta-y (1/m) of field to be interpolated
!
! var variable to be interpolated
! missing Value of missing data
!
! slopey Piecewise linear df/dy
! alphay Coefficient of y-squared term in y quadratic interpolator
! betay Coefficient of y term in y quadratic interpolator
!
!-----------------------------------------------------------------------
INTEGER, INTENT(IN) :: nx,ny,nz
INTEGER, INTENT(IN) :: ibeg,iend,jbeg,jend,kbeg,kend
REAL, INTENT(IN) :: dyfld(nx,ny)
REAL, INTENT(IN) :: rdyfld(nx,ny)
REAL, INTENT(IN) :: var(nx,ny,nz)
REAL, INTENT(IN) :: missing
REAL, INTENT(OUT) :: slopey(nx,ny,nz)
REAL, INTENT(OUT) :: alphay(nx,ny,nz)
REAL, INTENT(OUT) :: betay(nx,ny,nz)
!-----------------------------------------------------------------------
!
! Misc. local variables
!
!-----------------------------------------------------------------------
INTEGER :: i,j,k
INTEGER :: jstart,jstop
REAL :: rtwody
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
jstart=MAX(jbeg,2)
jstop=MIN((jend-1),(ny-2))
DO k=kbeg,kend
DO j=jstart,jstop
DO i=ibeg,iend
IF (var(i,j+1,k) == missing .OR. &
var(i,j,k) == missing) THEN
slopey(i,j,k) = missing
ELSE
slopey(i,j,k)=(var(i,j+1,k)-var(i,j,k))*rdyfld(i,j)
END IF
rtwody=1./(dyfld(i,j-1)+dyfld(i,j))
IF (var(i,j+1,k) == missing .OR. &
var(i,j,k) == missing .OR. &
var(i,j-1,k) == missing) THEN
alphay(i,j,k) = missing
ELSE
alphay(i,j,k)=((var(i,j+1,k)-var(i,j,k))*rdyfld(i,j) + &
(var(i,j-1,k)-var(i,j,k))*rdyfld(i,j-1))*rtwody
END IF
IF (var(i,j+1,k) == missing .OR. &
var(i,j,k) == missing .OR. &
alphay(i,j,k) == missing ) THEN
betay(i,j,k)=missing
ELSE
betay(i,j,k)=(var(i,j+1,k)-var(i,j,k))*rdyfld(i,j) - &
dyfld(i,j)*alphay(i,j,k)
END IF
END DO
END DO
END DO
RETURN
END SUBROUTINE setdrvy2d
!########################################################################
!########################################################################
!######### #########
!######### FUNCTION pntint2d2d #########
!######### #########
!######### Developed by #########
!######### Center for Analysis and Prediction of Storms #########
!######### University of Oklahoma #########
!######### #########
!########################################################################
!########################################################################
REAL FUNCTION pntint2d2d(vnx,vny,ivbeg,ivend,jvbeg,jvend,iorder,vx,vy, &
xpnt,ypnt,iloc,jloc,var,dxfld,dyfld,rdxfld, &
rdyfld,missing,slopey,alphay,betay)
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Interpolate a 2-d field for a single point on that plane.
!
!-----------------------------------------------------------------------
!
! AUTHOR: Keith Brewster, CAPS, November, 1996
!
! MODIFICATION HISTORY:
!
! Eric Kemp, 27 April 2001
! Modified to allow for 2D arrays
!
! Eric Kemp, 9 August 2001
! Modified to check for missing data, and added INTENT statements.
!
!-----------------------------------------------------------------------
!
! Force explicit declarations
!
!-----------------------------------------------------------------------
IMPLICIT NONE
!-----------------------------------------------------------------------
!
! INPUT:
! vnx Number of model grid points in the x-direction (east/west)
! vny Number of model grid points in the y-direction
! (north/south)
!
! ivbeg,ivend Range of x index to use in verification array
! jvbeg,jvend Range of y index to use in verification array
!
! iorder Interpolation parameter.
! iorder specifies the order of interpolation
! 1 = bi-linear
! 2 = bi-quadratic
!
! vx x coordinate of verif scalar grid points in physical space
! (m)
! vy y coordinate of verif scalar grid points in physical space
! (m)
!
! xpnt x coordinate (m) of interpolation point
! ypnt y coordinate (m) of interpolation point
!
! iloc I-index of interpolation point in field to be interpolated
! jloc J-index of interpolation point in field to be interpolated
! dxfld Vector of delta-x (m) of field to be interpolated
! dyfld Vector of delta-y (m) of field to be interpolated
! rdxfld Vector of 1./delta-x (1/m) of field to be interpolated
! rdyfld Vector of 1./delta-y (1/m) of field to be interpolated
! missing Value of missing data
!
! slopey Piecewise linear df/dy
! alphay Coefficient of y-squared term in y quadratic interpolator
! betay Coefficient of y term in y quadratic interpolator
!
!-----------------------------------------------------------------------
INTEGER, INTENT(IN) :: vnx,vny
INTEGER, INTENT(IN) :: ivbeg,ivend,jvbeg,jvend
INTEGER, INTENT(IN) :: iorder
REAL, INTENT(IN) :: vx(vnx,vny)
REAL, INTENT(IN) :: vy(vnx,vny)
REAL, INTENT(IN) :: xpnt
REAL, INTENT(IN) :: ypnt
INTEGER, INTENT(IN) :: iloc
INTEGER, INTENT(IN) :: jloc
REAL, INTENT(IN) :: var(vnx,vny)
REAL, INTENT(IN) :: dxfld(vnx,vny)
REAL, INTENT(IN) :: dyfld(vnx,vny)
REAL, INTENT(IN) :: rdxfld(vnx,vny)
REAL, INTENT(IN) :: rdyfld(vnx,vny)
REAL, INTENT(IN) :: slopey(vnx,vny)
REAL, INTENT(IN) :: alphay(vnx,vny)
REAL, INTENT(IN) :: betay(vnx,vny)
REAL, INTENT(IN) :: missing
!-----------------------------------------------------------------------
!
! Misc. local variables
!
!-----------------------------------------------------------------------
INTEGER :: ii,jj
REAL :: delx,dely
REAL :: alpha,beta,rtwodx
REAL :: varm1,var00,varp1
REAL :: varint
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!-----------------------------------------------------------------------
!
! Compute bilinear interpolated value
!
!-----------------------------------------------------------------------
IF(iorder == 1) THEN
ii=MIN(MAX(iloc,ivbeg),(ivend-1))
jj=MIN(MAX(jloc,jvbeg),(jvend-1))
delx=(xpnt-vx(ii,jj))
dely=(ypnt-vy(ii,jj))
IF (var(ii,jj) == missing .OR. &
slopey(ii,jj) == missing .OR. &
var(ii+1,jj) == missing .OR. &
slopey(ii+1,jj) == missing) THEN
varint = missing
ELSE
varint=(1.-delx*rdxfld(ii,jj))* &
(var(ii ,jj)+slopey(ii ,jj)*dely)+ &
(delx*rdxfld(ii,jj))* &
(var(ii+1,jj)+slopey(ii+1,jj)*dely)
END IF
!-----------------------------------------------------------------------
!
! Compute biquadratic
!
!-----------------------------------------------------------------------
ELSE
ii=MIN(MAX(iloc,(ivbeg+1)),(ivend-1))
jj=MIN(MAX(jloc,(jvbeg+1)),(jvend-1))
delx=(xpnt-vx(ii,jj))
dely=(ypnt-vy(ii,jj))
!-----------------------------------------------------------------------
!
! Stencil is ii-1 to ii+1 and jj-1 to jj + 1
!
! Interpolate in y.
!
!-----------------------------------------------------------------------
IF (alphay(ii-1,jj) == missing .OR. betay(ii-1,jj) == missing .OR. &
var(ii-1,jj) == missing) THEN
varm1 = missing
ELSE
varm1=(alphay(ii-1,jj)*dely+betay(ii-1,jj))*dely+var(ii-1,jj)
END IF
IF (alphay(ii,jj) == missing .OR. betay(ii,jj) == missing .OR. &
var(ii,jj) == missing) THEN
varm1 = missing
ELSE
var00=(alphay(ii ,jj)*dely+betay(ii ,jj))*dely+var(ii ,jj)
END IF
IF (alphay(ii+1,jj) == missing .OR. betay(ii+1,jj) == missing .OR. &
var(ii+1,jj) == missing) THEN
varm1 = missing
ELSE
varp1=(alphay(ii+1,jj)*dely+betay(ii+1,jj))*dely+var(ii+1,jj)
END IF
!-----------------------------------------------------------------------
!
! Interpolate intermediate results in x.
!
!-----------------------------------------------------------------------
rtwodx=1./(dxfld(ii-1,jj)+dxfld(ii,jj))
IF (varp1 == missing .OR. var00 == missing .OR. &
varm1 == missing) THEN
varint = missing
ELSE
alpha=((varp1-var00)*rdxfld(ii ,jj) + &
(varm1-var00)*rdxfld(ii-1,jj))*rtwodx
beta=(varp1-var00)*rdxfld(ii,jj) - &
dxfld(ii,jj)*alpha
varint=(alpha*delx+beta)*delx+var00
END IF
END IF
pntint2d2d=varint
RETURN
END FUNCTION pntint2d2d
!########################################################################
!########################################################################
!######### #########
!######### SUBROUTINE setijloc2 #########
!######### #########
!######### Developed by #########
!######### Center for Analysis and Prediction of Storms #########
!######### University of Oklahoma #########
!######### #########
!########################################################################
!########################################################################
SUBROUTINE setijloc2(fnx,fny,anx,any,iloc,jloc,fx2d,fy2d,ax2d,ay2d) 4
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Find i,j indicies in forecast grid of each analysis grid point.
! No indicies are returned if the analysis grid point is outside
! of the forecast grid.
!
! NOTE: The forecast and analysis grid points are assumed to have
! the same origin and map projection.
!
!-----------------------------------------------------------------------
!
! AUTHOR: Eric Kemp, November 1999.
!
! Based on subroutine setijloc
!
! MODIFICATION HISTORY:
!
! Eric Kemp, 9 August 2001
! Added INTENT statements.
!
!-----------------------------------------------------------------------
!
! Force explicit declarations.
!
!-----------------------------------------------------------------------
IMPLICIT NONE
!-----------------------------------------------------------------------
!
! Arguments
!
!-----------------------------------------------------------------------
INTEGER,INTENT(IN) :: fnx,fny,anx,any
REAL,INTENT(IN) :: fx2d(fnx,fny),fy2d(fnx,fny)
REAL,INTENT(IN) :: ax2d(anx,any),ay2d(anx,any)
INTEGER,INTENT(INOUT) :: iloc(anx,any),jloc(anx,any)
!-----------------------------------------------------------------------
!
! Miscellaneous variables
!
!-----------------------------------------------------------------------
INTEGER :: i,j,m,n
INTEGER :: fimid,fjmid
REAL :: fxmid,fymid
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!-----------------------------------------------------------------------
!
! Initialize iloc and jloc to -9999 (i.e., outside the forecast grid)
!
!-----------------------------------------------------------------------
DO n = 1,any
DO m = 1,anx
iloc(m,n) = -9999
jloc(m,n) = -9999
END DO
END DO
!-----------------------------------------------------------------------
!
! Determine the scalar coordinates of the middle of the forecast field.
!
!-----------------------------------------------------------------------
fimid = fnx/2
fjmid = fny/2
fxmid = fx2d(fimid,fjmid)
fymid = fy2d(fimid,fjmid)
!-----------------------------------------------------------------------
!
! Find the forecast i,j of each analysis grid point.
!
!-----------------------------------------------------------------------
DO n = 1,any-1
analysism: DO m = 1,anx-1
IF (ax2d(m,n) < fxmid) THEN
IF (ay2d(m,n) < fymid) THEN
DO j = fjmid,2,-1
DO i = fimid,2,-1
IF (fx2d(i,j) <= ax2d(m,n) .AND. &
fx2d(i+1,j) > ax2d(m,n) .AND. &
fy2d(i,j) <= ay2d(m,n) .AND. &
fy2d(i,j+1) > ay2d(m,n)) THEN
iloc(m,n) = i
jloc(m,n) = j
CYCLE analysism
END IF
END DO
END DO
ELSE
DO j = fjmid,fny-1
DO i = fimid,2,-1
IF (fx2d(i,j) <= ax2d(m,n) .AND. &
fx2d(i+1,j) > ax2d(m,n) .AND. &
fy2d(i,j-1) < ay2d(m,n) .AND. &
fy2d(i,j) >= ay2d(m,n)) THEN
iloc(m,n) = i
jloc(m,n) = j-1
CYCLE analysism
END IF
END DO
END DO
END IF
ELSE
IF (ay2d(m,n) < fymid) THEN
DO j = fjmid,2,-1
DO i = fimid,fnx-1
IF (fx2d(i-1,j) < ax2d(m,n) .AND. &
fx2d(i,j) >= ax2d(m,n) .AND. &
fy2d(i,j) <= ay2d(m,n) .AND. &
fy2d(i,j+1) > ay2d(m,n)) THEN
iloc(m,n) = i-1
jloc(m,n) = j
CYCLE analysism
END IF
END DO
END DO
ELSE
DO j = fjmid,fny-1
DO i = fimid,fnx-1
IF (fx2d(i-1,j) < ax2d(m,n) .AND. &
fx2d(i,j) >= ax2d(m,n) .AND. &
fy2d(i,j-1) < ay2d(m,n) .AND. &
fy2d(i,j) >= ay2d(m,n)) THEN
iloc(m,n) = i-1
jloc(m,n) = j-1
CYCLE analysism
END IF
END DO
END DO
END IF
END IF
END DO analysism
END DO
END SUBROUTINE setijloc2
!########################################################################
!########################################################################
!######### #########
!######### SUBROUTINE dpalatlon #########
!######### #########
!######### Developed by #########
!######### Center for Analysis and Prediction of Storms #########
!######### University of Oklahoma #########
!######### #########
!########################################################################
!########################################################################
SUBROUTINE dpalatlon(nrow,ncol,radarlat,radarlon,dpalat,dpalon),1
!------------------------------------------------------------------------
!
! PURPOSE:
!
! Determines latitude and longitude of each NIDS Digital Precipitation
! Array (DPA) point for a given radar latitude and longitude. The DPA
! is on a "1/40 LFM grid", i.e., a polar stereographic grid nested within
! the old Limited Fine Mesh model grid. Equations for calculating
! latitudes and longitudes on the DPA grid are taken from Appendix C
! of Fulton (1998).
!
! IMPORTANT: The NEXRAD equations assume that the DPA grid is such that
! i increases to the right and j increases *downward*. An easy
! correction is made so that the output arrays follow the ARPS grid,
! i.e., i increases to the right and j increases *upward*.
!
!------------------------------------------------------------------------
!
! REFERENCE:
!
! Fulton, R. A., 1998: WSR-88D Polar-to-HRAP Mapping. Technical
! Memorandum, Hydrologic Research Laboratory, 33 pp. Available at:
! http://hsp.nws.noaa.gov/oh/hrl/papers/wsr88d/hrapmap.pdf
!
!------------------------------------------------------------------------
!
! AUTHOR:
!
! Eric Kemp, 3 August 2001.
!
! MODIFICATION HISTORY:
!
! Eric Kemp, 9 August 2001.
! Now uses module N2ACONST.
!
!------------------------------------------------------------------------
!
! Use modules
!
!------------------------------------------------------------------------
USE n2aconst
!------------------------------------------------------------------------
!
! Force explicit declarations.
!
!------------------------------------------------------------------------
IMPLICIT NONE
!------------------------------------------------------------------------
!
! Arguments
!
!------------------------------------------------------------------------
INTEGER, INTENT(IN) :: nrow,ncol ! Dimensions of DPA product
REAL, INTENT(IN) :: radarlat,radarlon ! Lat/Lon of radar.
REAL, INTENT(OUT) :: dpalat(nrow,ncol) ! Lat of DPA points.
REAL, INTENT(OUT) :: dpalon(nrow,ncol) ! Lon of DPA points.
!------------------------------------------------------------------------
!
! Grid scale factor.
!
!------------------------------------------------------------------------
REAL, PARAMETER :: Kc = 249.6348607
!------------------------------------------------------------------------
!
! Global grid coordinates of the North Pole in units of 1/4 LFM
! boxes.
!
!------------------------------------------------------------------------
INTEGER, PARAMETER :: Ip = 433
INTEGER, PARAMETER :: Jp = 433
!------------------------------------------------------------------------
!
! Global grid coordinates of radar site in units of 1/4 LFM boxes.
!
!------------------------------------------------------------------------
REAL :: GIs, GJs
!------------------------------------------------------------------------
!
! Global grid box number for 0,0 of 1/40 LFM grid
!
!------------------------------------------------------------------------
INTEGER :: Is3, Js3
!------------------------------------------------------------------------
!
! Coefficients used to calculate coordinates of box centers in units
! of 1/4 LFM boxes.
!
!------------------------------------------------------------------------
REAL :: AI3, AJ3
REAL, PARAMETER :: B3 = 0.1
!------------------------------------------------------------------------
!
! Coordinates of box centers in units of 1/4 LFM boxes.
!
!------------------------------------------------------------------------
REAL :: CIi, CJj
!------------------------------------------------------------------------
!
! Misc. variables.
!
!------------------------------------------------------------------------
REAL :: sinls, cosls, coslambdaplus, sinlambdaplus
INTEGER :: i,j
REAL :: tmplat, tmplon
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!------------------------------------------------------------------------
!
! Calculate GIs, GJs. See Appendix C, Sections 30.6.2 and 30.6.3 of
! Fulton (1998).
!
!------------------------------------------------------------------------
sinls = SIN(radarlat*deg2rad)
cosls = COS(radarlat*deg2rad)
coslambdaplus = COS((radarlon + 105.)*deg2rad)
sinlambdaplus = SIN((radarlon + 105.)*deg2rad)
GIs = 1. + sinls
GIs = Kc*cosls*sinlambdaplus/GIs
GIs = GIs + REAL(Ip)
GJs = 1 + sinls
GJs = Kc*cosls*coslambdaplus/GJs
GJs = GJs + REAL(Jp)
!------------------------------------------------------------------------
!
! Calculate Is3 and Js3. See Appendix C, Section 30.6.3 of Fulton
! (1998). Note that GIs and GJs are multiplied by 10 to make Is3 and
! Js3 valid on the 1/40 LFM grid. This corrects an error in the
! NEXRAD documentation.
!
!------------------------------------------------------------------------
Is3 = INT(10.*GIs) - 66
Js3 = INT(10.*GJs) - 66
!------------------------------------------------------------------------
!
! Calculate AI3 and AJ3 (B3 is already set as a parameter). See
! Appendix C, Section 30.6.4 of Fulton (1998).
!
!------------------------------------------------------------------------
AI3 = -10.*REAL(Ip)
AI3 = (REAL(Is3) + AI3 + 0.5)/10.
AJ3 = -10.*REAL(Jp)
AJ3 = (REAL(Js3) + AJ3 + 0.5)/10.
!------------------------------------------------------------------------
!
! Begin looping through the DPA points.
!
!------------------------------------------------------------------------
DO j = 1, ncol
DO i = 1, nrow
!------------------------------------------------------------------------
!
! Calculate CIi and CJj for a given DPA point. See Appendix C,
! Section 30.6.4 of Fulton (1998).
!
!------------------------------------------------------------------------
CIi = AI3 + (B3*REAL(i))
CJj = AJ3 + (B3*REAL(j))
!------------------------------------------------------------------------
!
! Now calculate latitude and longitude of a given DPA point. See
! Section 30.6.4 of Fulton (1998). Note that the output array will
! follow the ARPS grid, i.e., i increases to the right and j
! increases *upward*.
!
!------------------------------------------------------------------------
tmplat = (CIi*CIi) + (CJj*CJj)
tmplat = SQRT(tmplat)/Kc
tmplat = 2.*ATAN(tmplat)*rad2deg
tmplat = 90. - tmplat
dpalat(i,ncol-j+1) = tmplat
tmplon = -105. + (ATAN2(CIi,CJj)*rad2deg)
dpalon(i,ncol-j+1) = tmplon
END DO ! i loop
END DO ! j loop
!------------------------------------------------------------------------
!
! The end.
!
!------------------------------------------------------------------------
RETURN
END SUBROUTINE dpalatlon
!########################################################################
!########################################################################
!######### #########
!######### SUBROUTINE getarpsrasterxy #########
!######### #########
!######### Developed by #########
!######### Center for Analysis and Prediction of Storms #########
!######### University of Oklahoma #########
!######### #########
!########################################################################
!########################################################################
SUBROUTINE getarpsrasterxy(nx,ny,arpslat,arpslon,radarlat,radarlon, & 1,2
arpsrasterx,arpsrastery)
!------------------------------------------------------------------------
!
! PURPOSE:
!
! Calculates Cartesian coordinates of ARPS scalar points relative to
! a radar using spherical geometry.
!
!------------------------------------------------------------------------
!
! AUTHOR:
!
! Eric Kemp, 8 August 2001.
!
!------------------------------------------------------------------------
!
! Use modules.
!
!------------------------------------------------------------------------
USE n2aconst
!------------------------------------------------------------------------
!
! Force explicit declarations
!
!------------------------------------------------------------------------
IMPLICIT NONE
!------------------------------------------------------------------------
!
! Declare arguments
!
!------------------------------------------------------------------------
INTEGER, INTENT(IN) :: nx,ny ! Dimensions of ARPS grid
REAL, INTENT(IN) :: arpslat(nx,ny) ! Latitude of ARPS point
REAL, INTENT(IN) :: arpslon(nx,ny) ! Longitude of ARPS point
REAL, INTENT(IN) :: radarlat,radarlon ! Lat/Lon of radar.
REAL, INTENT(OUT) :: arpsrasterx(nx,ny) ! x-coordinate of ARPS point.
REAL, INTENT(OUT) :: arpsrastery(nx,ny) ! y-coordinate of ARPS point.
!------------------------------------------------------------------------
!
! Internal variables.
!
!------------------------------------------------------------------------
INTEGER :: i,j
REAL :: headng,dist
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
DO j = 1,ny-1
DO i = 1,nx-1
CALL disthead
(radarlat,radarlon,arpslat(i,j),arpslon(i,j), &
headng,dist)
arpsrasterx(i,j) = dist*SIN(deg2rad*headng)
arpsrastery(i,j) = dist*COS(deg2rad*headng)
END DO ! i loop
END DO ! j loop
RETURN
END SUBROUTINE getarpsrasterxy
!########################################################################
!########################################################################
!######### #########
!######### SUBROUTINE getarpsdpaxy #########
!######### #########
!######### Developed by #########
!######### Center for Analysis and Prediction of Storms #########
!######### University of Oklahoma #########
!######### #########
!########################################################################
!########################################################################
SUBROUTINE getarpsdpaxy(nx,ny,arpslat,arpslon,radarlat,radarlon, &,1
arpsdpax,arpsdpay)
!------------------------------------------------------------------------
!
! PURPOSE:
!
! Calculates Cartesian coordinates of ARPS scalar points relative to
! a radar in HRAP (1/40 LFM) polar stereographic grid projection (used
! by NIDS DPA product).
!
!------------------------------------------------------------------------
!
! AUTHOR:
!
! Eric Kemp, 8 August 2001.
!
!------------------------------------------------------------------------
!
! REFERENCE:
!
! Fulton, R. A., 1998: WSR-88D Polar-to-HRAP Mapping. Technical
! Memorandum, Hydrologic Research Laboratory, 33 pp. Available at:
! http://hsp.nws.noaa.gov/oh/hrl/papers/wsr88d/hrapmap.pdf
!
!------------------------------------------------------------------------
!
! Use modules.
!
!------------------------------------------------------------------------
USE n2aconst
!------------------------------------------------------------------------
!
! Force explicit declarations
!
!------------------------------------------------------------------------
IMPLICIT NONE
!------------------------------------------------------------------------
!
! Declare arguments.
!
!------------------------------------------------------------------------
INTEGER, INTENT(IN) :: nx,ny ! Dimensions of ARPS grid
REAL, INTENT(IN) :: arpslat(nx,ny) ! Latitude of ARPS point
REAL, INTENT(IN) :: arpslon(nx,ny) ! Longitude of ARPS point
REAL, INTENT(IN) :: radarlat,radarlon ! Lat/Lon of radar.
REAL, INTENT(OUT) :: arpsdpax(nx,ny) ! x-coordinate of ARPS point.
REAL, INTENT(OUT) :: arpsdpay(nx,ny) ! y-coordinate of ARPS point.
!------------------------------------------------------------------------
!
! Internal variables
!
!------------------------------------------------------------------------
INTEGER :: i,j
! INTEGER :: Is3, Js3
REAL :: GIs, GJs
INTEGER, PARAMETER :: Ip = 433
INTEGER, PARAMETER :: Jp = 433
REAL, PARAMETER :: Kc = 249.6348607
REAL :: GI, GJ
REAL :: sinls, cosls, coslambdaplus, sinlambdaplus
REAL :: sindeltalambda,cosdeltalambda,deltalambda, sinl,cosl
REAL :: Rl
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!------------------------------------------------------------------------
!
! Calculate GIs, GJs. See Appendix C, Sections 30.6.2 and 30.6.3 of
! Fulton (1998).
!
!------------------------------------------------------------------------
sinls = SIN(radarlat*deg2rad)
cosls = COS(radarlat*deg2rad)
coslambdaplus = COS((radarlon + 105.)*deg2rad)
sinlambdaplus = SIN((radarlon + 105.)*deg2rad)
GIs = 1. + sinls
GIs = Kc*cosls*sinlambdaplus/GIs
GIs = GIs + REAL(Ip)
GJs = 1 + sinls
GJs = Kc*cosls*coslambdaplus/GJs
GJs = GJs + REAL(Jp)
!------------------------------------------------------------------------
!
! Calculate Is3 and Js3. See Appendix C, Section 30.6.3 of Fulton
! (1998). Note that GIs and GJs are multiplied by 10 to make Is3 and
! Js3 valid on the 1/40 LFM grid. This corrects an error in the
! NEXRAD documentation.
!
!------------------------------------------------------------------------
DO j = 1,ny-1
DO i = 1,nx-1
deltalambda = arpslon(i,j) - radarlon
sinl = SIN(arpslat(i,j)*deg2rad)
cosl = COS(arpslat(i,j)*deg2rad)
Rl = Kc*cosl/(1. + sinl)
sindeltalambda = SIN(deltalambda*deg2rad)
cosdeltalambda = COS(deltalambda*deg2rad)
GI = Rl*sindeltalambda*coslambdaplus
GI = GI + (Rl*cosdeltalambda*sinlambdaplus) + REAL(Ip)
GJ = Rl*cosdeltalambda*coslambdaplus
GJ = GJ + (Rl*sindeltalambda*sinlambdaplus) + REAL(Jp)
arpsdpax(i,j) = DPAdx*(GI - GIs)*10.
arpsdpay(i,j) = DPAdx*(GJ - GJs)*10.
END DO ! i loop
END DO ! j loop
RETURN
END SUBROUTINE getarpsdpaxy