!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE BARNES_R5 ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
!
SUBROUTINE barnes_r5 (nx,ny,nz,TO,t,wt_p,cf_modelfg, &
l_stn_clouds,default_clear_cover,cld_snd,wt_snd, &
spcng,i_snd,j_snd,n_cld_snd, &
istatus)
!
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Horizontally interpolate the SAO cloud soundings to ADAS grid.
! The interpolation scheme is Barnes-type, the weight given to a
! data point is:
!
! wt(m) = [(100.0*bias)/(1.533*dgrd(m)**2 + 1.0)]**(5.0/2.0)
! wt(m) ~ 34367.237 /(dgrd(m)**5)
!
! where
!
! m is the index of a data point
! bias=1.0 ! it can be a function of data location
! dgrd(m) is the distance from the mth data point to
! the grid point, in terms of the number of grid spacings.
!
!-----------------------------------------------------------------------
!
! AUTHOR: (Jian Zhang)
! 07/95 Based on the LAPS cloud analysis code
!
! MODIFICATION HISTORY:
! 02/06/96 J. Zhang
! Modified for ADAS. Added documents.
! 05/10/96 J. Zhang
! Added the interpolation for the station grid column
! (skipped during the first step).
! 03/14/97 J. Zhang
! Clean up the code and implemented for the offcial
! arps4.2.4 version
! 07/30/97 J. Zhang
! Added minimum weight threshold for Barnes interpolation.
! This can avoid the interpolations at the grid points
! where there is no station nearby.
! 08/06/97 J. Zhang
! Change adascld24.inc to adascld25.inc.
! Set weight_modelfg=1.0 for the cases when there is
! no SAO cloud soundings.
! 09/09/97 J. Zhang
! Using the different influence cutoff radius for
! cloud soundingd with different cloud coverage
! 09/10/97 J. Zhang
! Awoke the procedure which uses background RH field to
! derive cloud cover field when there is no SAO cloud
! sounding.
! Change adascld25.inc to adascld26.inc.
! 11/18/97 J. Zhang
! Moved "max_obs" to adascld26.inc.
! 11/19/97 J. Zhang
! Added test for the case when ncnt > max_obs.
!
!-----------------------------------------------------------------------
!
! INPUT:
!
!
! OUTPUT:
!
!
!-----------------------------------------------------------------------
!
!-----------------------------------------------------------------------
!
! Variable Declarations.
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
INCLUDE 'adas.inc'
!
! INPUT from adas.inc:
! real r_missing ! missing value flag
! real range_cld ! cutoff radius for interpolation
! integer max_cld_snd ! max. possible # of cloudy soundings
! integer max_obs ! max. possible # of cldy data points in 3D
! domain (should be about max_cld_snd*nz)
! integer i_perimeter ! an extension of the ADAS domain for
! searching SAOs.
!
! INPUT:
!
INTEGER :: nx,ny,nz ! grid size
INTEGER :: n_cld_snd ! actual # of cld snd
REAL :: TO(nx,ny,nz) ! 1st guess of gridded cloud cover
REAL :: cf_modelfg(nx,ny,nz) ! 1st guess for cloud cover field
REAL :: wt_p(nx,ny,nz) ! weights for first guess field
LOGICAL :: l_stn_clouds ! using SAO stns'cld sndings?
REAL :: default_clear_cover ! defaule cld value for clear sky
REAL :: cld_snd(max_cld_snd,nz) ! obs. cloud cover sounding
REAL :: wt_snd(max_cld_snd,nz) ! weights for obs. cld sounding
INTEGER :: i_snd(max_cld_snd) ! i-loc of cloud sounding stn
INTEGER :: j_snd(max_cld_snd) ! j-loc of cloud sounding stn
!
! OUTPUT:
!
REAL :: t(nx,ny,nz) ! the gridded analysis of cld cvr
INTEGER :: istatus
!
! LOCAL:
!
INTEGER :: nx_lut,ny_lut ! dims for look up tbl of intp wgt.
INTEGER :: ix_low,ix_high,iy_low,iy_high
INTEGER :: n_fnorm
!
INTEGER :: iskip ! # of grid pts skipped when performing
! Barnes intp. (for time-saving)
INTEGER :: lowi_lut(nx) ! index for skipped grid points.
INTEGER :: lowj_lut(ny) ! index for skipped grid points.
!
REAL, allocatable :: fnorm(:) ! normalized weights
!
INTEGER :: iob(max_obs) ! i-loc of each cld data pt. in ADAS grid
INTEGER :: job(max_obs) ! j-loc of each cld data pt. in ADAS grid
INTEGER :: kob(max_obs) ! k-lvl of each cld data pt. in ADAS grid
INTEGER :: nob(max_obs) ! sequential index of each cldy data pt.
REAL, allocatable :: iiilut(:,:)
!
!-----------------------------------------------------------------------
!
! Misc local variables
!
!-----------------------------------------------------------------------
!
INTEGER :: nlast (nz) ! the index for the cloud sounding data
! point at each level.
LOGICAL :: l_analyze (nz)
!
REAL :: weight_modelfg ! the weight given to the 1st guess
! cloud cover field
REAL :: rden_ratio,radm2,rfac
PARAMETER ( rfac=10.0, radm2=1.533/rfac**2)
! parameter ( radm2=1.533)
!
REAL :: exp_dist_wt ! power of distance in weight
PARAMETER( exp_dist_wt = 5.0)
REAL :: spcng ! grid spacing in m
REAL :: rr,rr_max
INTEGER :: iii,iii_max
INTEGER :: iiizero,ncnt
REAL :: bias_iii ! a bias may be a func of locatns
LOGICAL :: cldprt
INTEGER :: i,j,k,n,nobs,nstart,nstop,ii,jj,nn,n1,jmid,ibeg
REAL :: weight,sum,sumwt
INTEGER :: il,ih,jl,jh,km1
REAL :: z1,z2,z3,z4,fraci,fracj
INTEGER :: astat
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
nx_lut = nx + i_perimeter - 1
ny_lut = ny + i_perimeter - 1
ix_low = 1 - i_perimeter
ix_high= nx + i_perimeter
iy_low = 1 - i_perimeter
iy_high= ny + i_perimeter
n_fnorm = 1.6 * ((nx_lut*nx_lut)+(ny_lut*ny_lut))
allocate (fnorm(n_fnorm),stat=astat)
IF (astat /= 0) THEN
WRITE (6,'(a)') "BARNES_R5: ERROR allocating fnorm, exiting"
STOP
END IF
allocate (iiilut(-nx_lut:nx_lut,-ny_lut:ny_lut),stat=astat)
IF (astat /= 0) THEN
WRITE (6,'(a)') "BARNES_R5: ERROR allocating fnorm, exiting"
STOP
END IF
cldprt=(clddiag == 1)
jmid=ny/2
ibeg=MAX(1,nx-10)
WRITE(6,'(1x,a)') ' Barnes_r5 called'
istatus = 0
IF(cldprt) THEN
WRITE(6,'(a,i8)') ' # of cloud soundings = ',n_cld_snd
WRITE(6,'(/a)') ' ==== BARNES cloud cover first guess===='
WRITE(6,'(/1X,3X,11(1X,i4,1X))') (i,i=nx-10,nx)
WRITE(6,'(1X,i3,11F6.1)') &
(k,(cf_modelfg(i,jmid,k),i=ibeg,nx),k=nz,1,-1)
END IF
!
!-----------------------------------------------------------------------
!
! Obtain and/or iterate for value of iskip
!
!-----------------------------------------------------------------------
!
iskip = nint(20000. / spcng) ! # of grid pts skipped
! during calcul'n
iskip = MAX(iskip,1)
100 rden_ratio = ((FLOAT(nx)-1.)/FLOAT(iskip))
IF( ABS(rden_ratio - nint(rden_ratio)) > 0.001) THEN
WRITE(6,*)' Bad value of iskip'
IF(iskip > 1)THEN
iskip = iskip - 1
GO TO 100
ELSE IF( iskip == 1) THEN
WRITE(6,*)' Code error - stop'
STOP
END IF
ELSE
WRITE(6,*)' Good value of iskip = ',iskip
END IF
!
!-----------------------------------------------------------------------
!
! Create an array (lookup table) of weights as function of the
! distance iii (in the unit of grid spacings)
!
!-----------------------------------------------------------------------
!
IF( l_stn_clouds) PRINT*, ' # of cloud soundings = ',n_cld_snd
iiizero = 0
DO iii = 1,n_fnorm
bias_iii = 1E0 ! It can be func of location iii later
fnorm(iii) = (100.*bias_iii/FLOAT(iii)) ** (exp_dist_wt/2.0)
IF( fnorm(iii) == 0. .AND. iiizero == 0) THEN
iiizero = iii
WRITE(6,*)' WARNING: fnorm array reached zero, iii=',iiizero
END IF
END DO ! III
WRITE(6,*)' Min possible weight = ',fnorm(n_fnorm)
WRITE(6,*)' Max possible weight = ',fnorm(1)
IF (n_cld_snd <= 0) THEN
weight_modelfg = 1.0
ELSE
weight_modelfg = 0.0
END IF
!
!-----------------------------------------------------------------------
!
! Count the number of cloudy data points on each cloud height
! level, and mark each cloudy data point with iob- and job-index.
!
!-----------------------------------------------------------------------
!
ncnt=0 ! # of cloudy data points on each cloud grid level
DO k = 1, nz
IF (.NOT. l_stn_clouds) THEN ! using gridded non-model 1st
! guess field
nlast(k) = ncnt
DO j=1,ny
DO i=1,nx
IF( TO(i,j,k) == r_missing) GO TO 223
ncnt=ncnt+1
iob(ncnt)=i
job(ncnt)=j
kob(ncnt)=k
nlast(k) = ncnt
223 CONTINUE
END DO ! i
END DO ! j
ELSE ! l_stn_clouds = .TRUE., use cloud soundings
nlast(k) = ncnt
IF (n_cld_snd >= 1) THEN
DO n = 1,n_cld_snd
IF(cld_snd(n,k) < default_clear_cover) GO TO 233
!
!-----------------------------------------------------------------------
!
! Test if out of the bounds of the ADAS_plus domain
!
!-----------------------------------------------------------------------
!
IF(i_snd(n) < ix_low .OR. i_snd(n) > ix_high) GO TO 233
IF(j_snd(n) < iy_low .OR. i_snd(n) > iy_high) GO TO 233
ncnt=ncnt+1
IF (ncnt > max_obs) THEN
PRINT*,'# of cldy grid pts exceeds the max. # allowed'
PRINT*,'# of cldy grid pts:',ncnt,' # allowed:',max_obs
PRINT*,'Plz increase MAX_OBS in adas.inc.'
PRINT*,' Aborting...'
STOP
END IF
iob(ncnt)=i_snd(n)
job(ncnt)=j_snd(n)
kob(ncnt)=k
nob(ncnt)=n
nlast(k) = ncnt
233 CONTINUE
END DO ! n
END IF
END IF ! l_stn_clouds
IF( k > 1) THEN
km1 = k - 1
l_analyze(k) = .false.
IF(.NOT. l_stn_clouds) THEN
DO j=1,ny
DO i=1,nx
IF( TO(i,j,k) /= TO(i,j,km1)) THEN
l_analyze(k) = .true.
GO TO 250
END IF
END DO ! i
END DO ! j
ELSE
DO n=1,n_cld_snd
IF( cld_snd(n,k) /= cld_snd(n,km1)) THEN
l_analyze(k) = .true.
goto 250
END IF
END DO ! n
END IF ! l_stn_clouds
250 CONTINUE
ELSE ! k .eq. 1
l_analyze(k) = .true.
END IF
END DO ! K
IF(ncnt == 0) THEN
PRINT*, 'No SAO cloud sounding data for Barnes'
PRINT*, 'Using the background cloud cover field'
DO k=2,nz-2
DO j=1,ny
DO i=1,nx
t(i,j,k) = cf_modelfg(i,j,k)
END DO
END DO
END DO
istatus = 1
RETURN
ELSE
WRITE(6,*)' Ncnt = ',ncnt
END IF
!
!-----------------------------------------------------------------------
!
! Create a lookup table for fnorm(iii): the weights as a function
! of i- and j- distances.
!
!-----------------------------------------------------------------------
!
rr_max = (nx_lut-1)**2 + (ny_lut-1)**2
iii_max = radm2*100.*rr_max + 1.
PRINT*,' radm2*100,iii_max,n_fnorm: ',radm2*100.,iii_max,n_fnorm
IF( iii_max > n_fnorm) THEN
PRINT*,' iii_max is too large, increase n_fnorm',iii_max &
,n_fnorm
istatus = 0
RETURN
END IF
!
DO i = -nx_lut,nx_lut
DO j = -ny_lut,ny_lut
rr=i*i+j*j
iii=radm2*100.*rr+1.
IF( iii > n_fnorm) iii=n_fnorm
iiilut(i,j) = fnorm(iii) ! lookup table for weights
! fnorm as a function of
! distance iii.
END DO
END DO
!
!-----------------------------------------------------------------------
!
! Loop through each cloud height level.
!
!-----------------------------------------------------------------------
!
DO k = 1, nz
IF(k == 1)THEN
nstart = 1
ELSE
nstart = nlast(k-1) + 1
END IF
nstop = nlast(k)
nobs = nstop-nstart+1 ! # of obs. in one level
IF (nobs <= 0) THEN ! No Obs; Set level to model 1st guess
!
IF(cldprt) WRITE(6,'(a,4i5,a)') ' lvl,nstart,nstop,nobs=', &
k,nstart,nstop,nobs,' No Obs; Set level to model fg'
DO j=1,ny
DO i=1,nx
t(i,j,k) = cf_modelfg(i,j,k)
END DO ! i
END DO ! j
ELSE IF( weight_modelfg > 1.0E-15 .OR. l_analyze(k) ) THEN
IF(cldprt) WRITE(6,'(a,4i5)') ' lvl,nstart,nstop,nobs=', &
k,nstart,nstop,nobs
!
!-----------------------------------------------------------------------
!
! Analyze every iskip-th grid point
!
!-----------------------------------------------------------------------
!
DO j=1,ny,iskip
DO i=1,nx,iskip
sum=0.
sumwt=0.
IF(.NOT. l_stn_clouds)THEN
DO n=nstart,nstop
ii=iob(n)
jj=job(n)
iii = (i-ii)*(i-ii) + (j-jj)*(j-jj)
rr = FLOAT (iii)
rr = spcng*SQRT (rr)
IF (rr <= range_cld) THEN
!
!-----------------------------------------------------------------------
!
!c gridded obs are being weighted
!
!-----------------------------------------------------------------------
!
weight = iiilut(i-ii,j-jj) * wt_p(ii,jj,k)
sum=weight*TO(ii,jj,k)+sum
sumwt=sumwt+weight
END IF
END DO ! n
ELSE
DO n=nstart,nstop
ii=iob(n)
jj=job(n)
nn=nob(n)
iii = (i-ii)*(i-ii) + (j-jj)*(j-jj)
rr = FLOAT (iii)
rr = spcng*SQRT (rr)
IF (rr <= range_cld) THEN
!
!-----------------------------------------------------------------------
!
!c Station obs are being weighted
!
!-----------------------------------------------------------------------
!
weight = iiilut(i-ii,j-jj) * wt_snd(nn,k)
sum=weight*cld_snd(nn,k)+sum
sumwt=sumwt+weight
END IF
END DO ! n
END IF
sum = sum + weight_modelfg * cf_modelfg(i,j,k)
sumwt = sumwt + weight_modelfg
IF (ABS(sumwt) <= 1.0E-15) THEN
!9/3/97 t(i,j,k) = r_missing
! istatus = 0
! print*,'(00): ',i,j,k,' tot sum:',sum,' tot sumwt:'
! : ,sumwt,' t:',t(i,j,k)
t(i,j,k) = 0.01
ELSE
t(i,j,k)=sum/sumwt
END IF
END DO ! i
END DO ! j
!
!-----------------------------------------------------------------------
!
! Bilinearly interpolate to fill in rest of domain
!
!-----------------------------------------------------------------------
!
DO i = 1,nx
lowi_lut(i) = (i-1)/iskip*iskip + 1
IF( i == nx) lowi_lut(i) = lowi_lut(i) - iskip
END DO ! i
DO j = 1,ny
lowj_lut(j) = (j-1)/iskip*iskip + 1
IF( j == ny) lowj_lut(j) = lowj_lut(j) - iskip
END DO ! i
DO j=1,ny
jl = lowj_lut(j)
jh = jl + iskip
fracj = FLOAT(j-jl)/FLOAT(iskip)
DO i=1,nx
il = lowi_lut(i)
ih = il + iskip
fraci = FLOAT(i-il)/FLOAT(iskip)
z1=t(il,jl,k)
z2=t(ih,jl,k)
z3=t(ih,jh,k)
z4=t(il,jh,k)
t(i,j,k) = z1+(z2-z1)*fraci+(z4-z1)*fracj &
- (z2+z4-z3-z1)*fraci*fracj
END DO ! i
END DO ! j
IF (l_stn_clouds .AND. n_cld_snd >= 1) THEN
!
!-----------------------------------------------------------------------
!
! Reinterpolate at the station grid points which were skipped
! previously.
!
!-----------------------------------------------------------------------
!
DO n1=1,n_cld_snd
i = i_snd(n1)
j = j_snd(n1)
IF(i < 1.OR.i > nx.OR.j < 1.OR.j > ny) GO TO 252
IF( (i-1) /= (i-1)/iskip*iskip .OR. (j-1) /= (j-1)/iskip*iskip) THEN
sum=0.
sumwt=0.
DO n=nstart,nstop
ii=iob(n)
jj=job(n)
nn=nob(n)
iii = (i-ii)*(i-ii) + (j-jj)*(j-jj)
rr = FLOAT (iii)
rr = spcng*SQRT (rr)
IF (rr <= range_cld) THEN
!
!-----------------------------------------------------------------------
!
!c Station obs are being weighted
!
!-----------------------------------------------------------------------
!
weight = iiilut(i-ii,j-jj) * wt_snd(nn,k)
sum=weight*cld_snd(nn,k)+sum
sumwt=sumwt+weight
END IF
END DO ! n
sum = sum + weight_modelfg * cf_modelfg(i,j,k)
sumwt = sumwt + weight_modelfg
IF (ABS(sumwt) <= 1.0E-15) THEN
! t(i,j,k) = r_missing
! istatus = 0
! print*,'(00*): ',i,j,k,' tot sum:',sum,
! : ' tot sumwt:',sumwt,' t:',t(i,j,k)
t(i,j,k) = 0.01
ELSE
t(i,j,k)=sum/sumwt
END IF
END IF ! Stn (i,j) was skipped during the 1st-pass intp.
252 CONTINUE
END DO ! n1
END IF ! l_stn_clouds = .true. and n_cld_snd >0
ELSE ! no 1st guess and obs. is identical to lower lvl
!
!-----------------------------------------------------------------------
!
!c Obs are identical; Copy analysis from 1 level below
!
!-----------------------------------------------------------------------
!
IF(cldprt) WRITE(6,'(a,4i5,a)') ' lvl,nstart,nstop,nobs=', &
k,nstart,nstop,nobs,' Identical Obs; Copy from 1 lvl down'
km1 = k - 1
DO j=1,ny
DO i=1,nx
t(i,j,k) = t(i,j,km1)
END DO ! i
END DO ! j
END IF
END DO ! K
istatus = 1
!
deallocate (fnorm,stat=astat)
deallocate (iiilut,stat=astat)
RETURN
END SUBROUTINE barnes_r5
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE HGT_TO_ZK ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE hgt_to_zk (z,zk,nk,zs_1d,istatus) 2
!
!
!-----------------------------------------------------------------------
!
! PURPOSE:
! To find the k-position of a given height in the model grid
! If the height is above the model highest level, the largest
! level index (nk) will be returned. If the height is below
! the lowest model level, the lowestlevel index (1) will be
! returned.
!
!-----------------------------------------------------------------------
!
! AUTHOR: (Jian Zhang)
! 05/01/96
!
! MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
! Variable Declarations.
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
!
!-----------------------------------------------------------------------
!
! INPUT:
REAL :: z ! the height (m) to be coverted to k-index
INTEGER :: nk ! number of vertical levels in model grid
REAL :: zs_1d(nk) ! the physical height of each model level
!
! OUTPUT:
INTEGER :: istatus
REAL :: zk ! the k-position of the ht. in the model grid
!
!-----------------------------------------------------------------------
!
! Misc local variables
!
!-----------------------------------------------------------------------
!
INTEGER :: k,nkm1
REAL :: height_above,thickness,frac
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
zk = FLOAT(nk-1)
height_above = zs_1d(nk-1)
IF( z > height_above) THEN
nkm1=nk-1
! write(6,*)
! write(6,601) z,zk,nkm1,zs_1d(nkm1)
!601 format(' Warning: above model domain in HGT_TO_ZK'/
! : 1x,' z=',f9.0,' zk=',f6.2,' nk=',i2,' zs(nk)=',f9.0)
! write(6,*) 'Top level index will be assigned to ZK.'
istatus=0
!
GO TO 999
END IF
DO k = nk-2,1,-1
IF( height_above >= z .AND. zs_1d(k) <= z) THEN
thickness = height_above - zs_1d(k)
frac = (z - zs_1d(k))/thickness
zk = FLOAT(k) + frac
istatus=1
GO TO 999
END IF
height_above = zs_1d(k)
END DO ! K
zk = 1.0
! write(6,*)
! write(6,602) z,zk,zs_1d(1)
!602 format(' Warning: below model level_1 in HGT_TO_ZK'/
! : 1x,' z=',f9.0,' zk=',f6.2,' k=1 zs(1)=',f9.0)
! write(6,*) 'Bottom level index will be assigned to ZK.'
istatus=0
999 CONTINUE
RETURN
END SUBROUTINE hgt_to_zk
SUBROUTINE wmix (p,t,dd,w,nl) 1
!
! 07-jun-84 source code from wang
! (not on u. of w. source tape)
!
! dd - dewpoint depression
DIMENSION p(*), t(*), dd(*), w(*)
DO i = 1, nl
td = t(i) - dd(i)
IF (td > 253.0) GO TO 110
es = vpice(td)
GO TO 120
110 es = satvap(td)
120 w(i) = 622.0 * es / p(i)
END DO
RETURN
END SUBROUTINE wmix
!
!##################################################################
!##################################################################
!###### ######
!###### FUNCTION WSAT ######
!###### ######
!##################################################################
!##################################################################
!
FUNCTION wsat(p, t),1
!
! 1 4-may-84 added from csu vas code
! (not on u. of w. source tape)
!
! jz 4/29/98 to avoid warning message when compile on origin
DIMENSION p(1),t(1),dd(1),w(1)
dd(1) = 0.0
! jz 4/29/98 end
CALL wmix
(p,t,dd,w,1)
wsat=w(1)
! wsat=w
!
! 1 4-may-84 return added
!
RETURN
END FUNCTION wsat
!
!##################################################################
!##################################################################
!###### ######
!###### FUNCTION VPICE ######
!###### ######
!##################################################################
!##################################################################
!
FUNCTION vpice(temp)
!
! 07-jun-84 source code from wong
! (not on u. of w. source tape)
REAL(KIND=8) :: c(6)
REAL(KIND=8) :: t
!
DATA c/ 0.7859063157D+00, 0.3579242320D-01, &
-0.1292820828D-03, 0.5937519208D-06, &
0.4482949133D-09, 0.2176664827D-10/
!
t = temp - 273.16
vplog = c(1) + t * (c(2) + t * (c(3) + t * (c(4) + t * (c(5) + &
t * c(6)))))
vpice = 10.0 ** vplog
RETURN
END FUNCTION vpice
!
!##################################################################
!##################################################################
!###### ######
!###### FUNCTION SATVAP ######
!###### ######
!##################################################################
!##################################################################
!
FUNCTION satvap(temp)
!
! 07-jun-84 source code from wang
! (not on u. of w. source tape)
!
REAL(KIND=8) :: c(10)
REAL(KIND=8) :: s, t
!
DATA c/ 0.9999968760D-00, -0.9082695004D-02, &
0.7873616869D-04, -0.6111795727D-06, &
0.4388418740D-08, -0.2988388486D-10, &
0.2187442495D-12, -0.1789232111D-14, &
0.1111201803D-16, -0.3099457145D-19/
t = temp - 273.16
s = 6.1078000000D+00 / (c(1) + t * (c(2) + t * (c(3) + &
t * (c(4) + t * (c(5) + &
t * (c(6) + t * (c(7) + &
t * (c(8) + t * (c(9) + &
t * c(10)))))))))) ** 8
satvap = s
RETURN
END FUNCTION satvap
SUBROUTINE precw(p,w,u,np)
!
! 02-may-84 sequence numbers removed
!
DIMENSION p(*),w(*),u(*)
DATA f/1961.33/
w1=w(1)
p1=p(1)
s=0.
u(1)=s
!
! 07-jun-84 correction of tape read error
! do 100 i=2,n
DO i = 2, np
w2=w(i)
p2=p(i)
dp=ABS(p2-p1)
s=s+(w1+w2)*dp/f
u(i)=s
w1=w2
p1=p2
END DO
RETURN
END SUBROUTINE precw
!
!##################################################################
!##################################################################
!###### ######
!###### FUNCTION VSKINT ######
!###### ######
!##################################################################
!##################################################################
!
FUNCTION vskint(tbb,jcof,juse,jact)
!
! * obtain sfc-skin-temp from vas brightness temperatures
! jcof=0 for empirical coefficients
! jcof=1 for climatological(theoretical) coeffs.
!
! juse=0 to use 'day'(2-chan) or 'night'(3-chan) eqn.
! according to solar zenith angle
! ******* currently forced out; will use day only if chan 12 missing.
! juse=1 to use 'day' eqn.
! juse=2 to use 'night' eqn.
!
! jact=0 if nothing done
! jact=1 if 'day' eqn. actually used
! jact=2 if 'night' eqn. actually used
COMMON/nav/vlat,vlon,vzen,szen,il,ie,iras,ipic,itime,jtime,jday
COMMON/tsurfc/tscc(4,2)
COMMON/tsurfe/tsce(4,2)
DIMENSION tsc(4,2),tx(3),ic(3),tbb(*)
DATA ic/7,8,12/,nx/3/,vmisg/999999./
DO i=1,nx
j=ic(i)
tx(i)=tbb(j)
END DO
jact=0
ts=tx(2)
IF(tx(1) == vmisg) GO TO 180
IF(tx(2) == vmisg) GO TO 180
IF(jcof /= 0) GO TO 110
DO j=1,2
DO i=1,4
tsc(i,j)=tsce(i,j)
END DO
END DO
GO TO 130
110 DO j=1,2
DO i=1,4
tsc(i,j)=tscc(i,j)
END DO
END DO
130 j=juse
IF(j /= 0) GO TO 150
j=2 !changed 1 --> 2
! if(szen.ge.90.) j=2 !deleted line
150 IF(j == 1) GO TO 160
IF(tx(3) == vmisg) j=1
IF(tx(3) < tx(2)-4.) j=1 !changed tx(2) --> tx(2)-4.
160 jact=j
ts=tsc(4,j)
DO i=1,nx
ts=ts+tx(i)*tsc(i,j)
END DO
IF(ts == 0.) ts=vmisg
180 vskint=ts
RETURN
END FUNCTION vskint
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE PCP_MXR ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
!
SUBROUTINE pcp_mxr (nx,ny,nz,t_3d,p_3d ,ref_3d & 1
,cldpcp_type_3d &
,qr_3d,qs_3d,qh_3d,istatus )
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Perform 3D precipitation mixing ratio (in g/kg) analysis using
! radar reflectivity data. For rain water, using Kessler (1969)
! formula:
! qr(g/kg) = a*(rho*arg)**b (1)
!
! Here arg = Z (mm**6/m**3), and dBZ = 10log10 (arg).
! Coeffcients a=17300.0, and b=7/4.
! rho represents the air density.
!
! For snow and hail, using Rogers and Yau (1989) formula:
!
! qs(g/kg) = c*(rho*arg)**d (2)
!
! where, c=38000.0, d=2.2
!
!
!-----------------------------------------------------------------------
!
! AUTHOR: (Jian Zhang)
! 06/13/96
!
! MODIFICATION HISTORY:
! 07/30/97 (J. Zhang)
! Added precipitation type in the argument list so that
! mixing ratios of different precip. types can be computed.
! 09/04/97 (J. Zhang)
! Changed the radar echo thresholds for inserting precip.
! from radar reflectivities.
!
!-----------------------------------------------------------------------
!
!-----------------------------------------------------------------------
!
! Variable Declarations.
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
!
!-----------------------------------------------------------------------
!
! INPUT:
INTEGER :: nx,ny,nz ! Model grid size
!
REAL :: ref_3d(nx,ny,nz) ! radar reflectivity (dBZ)
REAL :: t_3d(nx,ny,nz) ! Temperature (deg. Kelvin)
REAL :: p_3d(nx,ny,nz) ! Pressure (Pascal)
INTEGER :: cldpcp_type_3d(nx,ny,nz) ! cloud/precip type field
!
! OUTPUT:
INTEGER :: istatus
!
REAL :: qr_3d(nx,ny,nz) ! rain mixing ratio in (g/kg)
REAL :: qs_3d(nx,ny,nz) ! snow/sleet/frz-rain mixing ratio
! in (g/kg)
REAL :: qh_3d(nx,ny,nz) ! hail mixing ratio in (g/kg)
!
! LOCAL:
REAL :: a,b,c,d ! Coef. for Z-qr relation.
PARAMETER (a=17300.0, b=7.0/4.0)
PARAMETER (c=38000.0, d=2.2)
REAL :: rair ! Gas constant (J/deg/kg)
PARAMETER (rair = 287.04)
REAL :: thresh_ref
PARAMETER (thresh_ref = 0.0)
INTEGER :: pcptype
!
!-----------------------------------------------------------------------
!
! Misc local variables
!
!-----------------------------------------------------------------------
!
INTEGER :: i,j,k, iarg
REAL :: arg,rhobar,br,dr
PARAMETER (br=1.0/b, dr=1.0/d)
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!
!-----------------------------------------------------------------------
!
istatus=0
!
!-----------------------------------------------------------------------
!
! Compute the precip mixing ratio in g/kg from radar reflectivity
! factor following Kessler (1969) or Rogers and Yau (1989).
!
!-----------------------------------------------------------------------
!
DO k = 1,nz-1
DO j = 1,ny-1
DO i = 1,nx-1
IF (ref_3d(i,j,k) >= thresh_ref) THEN ! valid radar refl.
rhobar = p_3d(i,j,k)/rair/t_3d(i,j,k)
arg = 10.0**(0.1*ref_3d(i,j,k))
iarg = cldpcp_type_3d(i,j,k)
pcptype = iarg/16 ! precip. type
IF (pcptype == 0) THEN ! no precip
PRINT*,'+++ NOTE: radar echo though no precip. +++'
ELSE IF (pcptype == 1.OR.pcptype == 3) THEN ! rain or Z R
qr_3d(i,j,k) = (arg/a)**br/rhobar
ELSE IF (pcptype == 2) THEN ! snow
qs_3d(i,j,k) = (arg/c)**dr/rhobar
ELSE IF (pcptype == 4.OR.pcptype == 5) THEN ! hail or sleet
qh_3d(i,j,k) = (arg/c)**dr/rhobar
ELSE ! unknown
PRINT*,'+++ NOTE: unknown precip type. +++'
END IF
ELSE
qr_3d(i,j,k) = 0.
qs_3d(i,j,k) = 0.
qh_3d(i,j,k) = 0.
END IF
END DO ! k
END DO ! i
END DO ! j
!
!-----------------------------------------------------------------------
!
istatus = 1
!
RETURN
END SUBROUTINE pcp_mxr
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE PCP_MXR_FERRIER ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
!
SUBROUTINE pcp_mxr_ferrier (nx,ny,nz,t_3d,p_3d ,ref_3d & 1
,cldpcp_type_3d &
,qr_3d,qs_3d,qh_3d,istatus )
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Perform 3D precipitation mixing ratio (in g/kg) analysis using
! radar reflectivity data. For rain water, using Ferrier et al (1995)
! formulation:
!
!
! For rain water:
!
! 18
! 10 * 720 1.75
! Zer = --------------------------- * (rho * qr)
! 1.75 0.75 1.75
! pi * N0r * rhor
!
!
! For dry snow (t <= 0 C):
!
!
! 18 2 0.25
! 10 * 720 * |K| * rhos
! ice 1.75
! Zes = ----------------------------------------- * (rho * qs) t <= 0 C
! 1.75 2 0.75 2
! pi * |K| * N0s * rhoi
! water
!
!
! For wet snow (t >= 0 C):
!
!
! 18
! 10 * 720 1.75
! Zes = ---------------------------- * (rho * qs) t > 0 C
! 1.75 0.75 1.75
! pi * N0s * rhos
!
!
! For hail water:
!
!
! / 18 \ 0.95
! / 10 * 720 \ 1.6625
! Zeh = | ---------------------------- | * (rho * qh)
! \ 1.75 0.75 1.75 /
! \ pi * N0h * rhoh /
!
! Here Zx (mm**6/m**3, x=r,s,h), and dBZ = 10log10 (Zx).
! rho represents the air density, rhor,rhos,rhoh are the density of
! rain, snow and hail respectively. Other variables are all constants
! for this scheme, see below.
!
!
!-----------------------------------------------------------------------
!
! AUTHOR: (Donghai Wang and Eric Kemp)
! 07/20/2000
!
! MODIFICATION HISTORY:
!
! 11/09/2000 Keith Brewster
! Moved some parameters with real-valued exponentiation to be
! computed at runtime due to compiler complaint.
!
! 04/07/2003 Keith Brewster
! Restructured code to make more tractable.and consistent with
! the reflec_ferrier subroutine.
!
!-----------------------------------------------------------------------
!
! Variable Declarations.
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
!
!-----------------------------------------------------------------------
!
! INPUT:
INTEGER :: nx,ny,nz ! Model grid size
!
REAL :: ref_3d(nx,ny,nz) ! radar reflectivity (dBZ)
REAL :: t_3d(nx,ny,nz) ! Temperature (deg. Kelvin)
REAL :: p_3d(nx,ny,nz) ! Pressure (Pascal)
INTEGER:: cldpcp_type_3d(nx,ny,nz) ! cloud/precip type field
!
! OUTPUT:
INTEGER :: istatus
!
REAL :: qr_3d(nx,ny,nz) ! rain mixing ratio in (g/kg)
REAL :: qs_3d(nx,ny,nz) ! snow/sleet/frz-rain mixing ratio
! in (g/kg)
REAL :: qh_3d(nx,ny,nz) ! hail mixing ratio in (g/kg)
!
REAL,PARAMETER :: ki2 = 0.176 ! Dielectric factor for ice if other
! than melted drop diameters are used.
REAL,PARAMETER :: kw2=0.93 ! Dielectric factor for water.
REAL,PARAMETER :: m3todBZ=1.0E+18 ! Conversion factor from m**3 to
! mm**6 m**-3.
REAL,PARAMETER :: Zefact=720.0 ! Multiplier for Ze components.
REAL,PARAMETER :: lg10div=0.10 ! Log10 multiplier (1/10)
REAL,PARAMETER :: pi=3.1415926 ! Pi.
REAL,PARAMETER :: N0r=8.0E+06 ! Intercept parameter in 1/(m^4) for rain.
REAL,PARAMETER :: N0s=3.0E+06 ! Intercept parameter in 1/(m^4) for snow.
REAL,PARAMETER :: N0h=4.0E+04 ! Intercept parameter in 1/(m^4) for hail.
REAL,PARAMETER :: N0xpowf=3.0/7.0 ! Power to which N0r,N0s & N0h are
! raised.
REAL,PARAMETER :: K2powf=4.0/7.0 ! Power to which K-squared
! of ice, water are raised
REAL,PARAMETER :: zkpowf=4.0/7.0 ! Power to which Zk is raised
REAL,PARAMETER :: zepowf=4.0/7.0 ! Power to which Ze is raised
REAL,PARAMETER :: zehpowf=(4.0/7.0)*1.0526 ! Power to which Zeh is raised
REAL,PARAMETER :: rhoi=917. ! Density of ice (kg m**-3)
REAL,PARAMETER :: rhor=1000. ! Density of rain (kg m**-3)
REAL,PARAMETER :: rhos=100. ! Density of snow (kg m**-3)
REAL,PARAMETER :: rhoh=913. ! Density of hail (kg m**-3)
REAL,PARAMETER :: rhoipowf=8.0/7.0 ! Power to which rhoi is raised.
REAL,PARAMETER :: rhospowf=1.0/7.0 ! Power to which rhos is raised.
!
!-----------------------------------------------------------------------
!
! Misc local variables
!
!-----------------------------------------------------------------------
!
REAL :: thresh_ref
PARAMETER (thresh_ref = 0.0)
INTEGER :: i,j,k, iarg
INTEGER :: pcptype
REAL :: zkconst,zerf,zesnegf,zesposf,zehf,rfract
REAL :: ze,zer,zeh,zes,rho,tc
!
!-----------------------------------------------------------------------
!
! Include Files
!
!-----------------------------------------------------------------------
!
INCLUDE 'phycst.inc'
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!
!-----------------------------------------------------------------------
!
! Intiailize constant factors in the Ze terms for rain, snow and hail,
! respectively, in Ferrier.
!
! These are the inverse of those presented in the reflec_ferrier function.
!
!-----------------------------------------------------------------------
!
istatus=0
zkconst = (Zefact*m3todBZ) ** zkpowf
zerf=1000.*(pi * (N0r**N0xpowf) * rhor )/zkconst
zesnegf=1000.*(pi*(kw2**k2powf)*(N0s**N0xpowf)*(rhoi**rhoipowf)) / &
( zkconst * (ki2**k2powf) * (rhos**rhospowf) )
zesposf=1000.*( pi * (N0s**N0xpowf) * rhos) / zkconst
zehf=1000.*( pi * (N0h**N0xpowf) * rhoh) / zkconst
!-----------------------------------------------------------------------
!
! Compute the precip mixing ratio in g/kg from radar reflectivity
! factor following Ferrier et al (1995).
!
!-----------------------------------------------------------------------
!
DO k = 2,nz-1
DO j = 1,ny-1
DO i = 1,nx-1
IF (ref_3d(i,j,k) >= thresh_ref) THEN ! valid radar refl.
rho = p_3d(i,j,k)/(rd*t_3d(i,j,k))
ze = 10.0**(0.1*ref_3d(i,j,k))
iarg = cldpcp_type_3d(i,j,k)
pcptype = iarg/16 ! precip. type
tc = t_3d(i,j,k) - 273.15
IF (pcptype == 1) THEN ! rain
qr_3d(i,j,k) = zerf * (ze**zepowf) / rho
ELSE IF (pcptype == 2) THEN ! snow
IF (tc <= 0.0) THEN !dry snow
qs_3d(i,j,k) = zesnegf * (ze**zepowf) / rho
ELSE IF (tc < 5.0) THEN !wet snow
rfract=0.20*tc
zer=rfract*ze
zes=(1.-rfract)*ze
qs_3d(i,j,k) = zesposf * (zes**zepowf) / rho
qr_3d(i,j,k) = zerf * (zer**zepowf) / rho
ELSE
qr_3d(i,j,k) = zerf * (ze**zepowf) / rho
END IF
ELSE IF (pcptype == 3) THEN ! ZR
qr_3d(i,j,k) = zerf * (ze**zepowf) / rho
ELSE IF (pcptype == 4) THEN ! sleet
IF (tc <= 0.0) THEN ! hail category
qh_3d(i,j,k) = zehf * (ze**zehpowf) / rho
ELSE IF( tc < 10. ) THEN
rfract=0.10*tc
zer=rfract*ze
zeh=(1.-rfract)*ze
qr_3d(i,j,k) = zerf * (zer**zepowf) / rho
qh_3d(i,j,k) = zehf * (zeh**zehpowf) / rho
ELSE
qr_3d(i,j,k) = zerf * (ze**zepowf) / rho
END IF
ELSE IF (pcptype == 5) THEN ! hail
qh_3d(i,j,k) = zehf * (ze**zehpowf) / rho
ELSE ! unknown
IF (tc <= 0.0) THEN !dry snow
qs_3d(i,j,k) = zesnegf * (ze**zepowf) / rho
ELSE IF ( tc < 5.0 ) THEN !wet snow
rfract=0.20*tc
zer=rfract*ze
zes=(1.-rfract)*ze
qs_3d(i,j,k) = zesposf * (zes**zepowf) / rho
qr_3d(i,j,k) = zerf * (zer**zepowf) / rho
ELSE ! rain
qr_3d(i,j,k) = zerf * (ze**zepowf) / rho
END IF
END IF
ELSE
qr_3d(i,j,k) = 0.
qs_3d(i,j,k) = 0.
qh_3d(i,j,k) = 0.
END IF
END DO ! k
END DO ! i
END DO ! j
PRINT*,'Finish Ferrier ...'
!
!-----------------------------------------------------------------------
!
istatus = 1
!
RETURN
END SUBROUTINE pcp_mxr_ferrier
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE REFMOSAIC ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
!
SUBROUTINE refmosaic(nradfil,nx,ny,nz,mx_rad, & 3,1
xs,ys,zs,radfname,ref_mos_3d,rhinf,rvinf, &
refl,tem1,tem2,istatus)
!-----------------------------------------------------------------------
!
! PURPOSE:
! This routine patches together reflectivity fields observed from
! multiple radars to create one 3D radar reflectivity field.
! It also fills the data gaps between the radar beams and elevations).
! These gaps are possible because that the real-time radar data
! processing only put data to the grid point nearest to the radar gate.
!
!-----------------------------------------------------------------------
!
! AUTHOR: (Jian Zhang)
! 06/04/96.
!
! MODIFICATION HISTORY:
! 11/01/01 (Keith Brewster)
! Created refmosaic from rad_patch_fill saving lots of memory when
! there are more than a couple of radars.
!
!-----------------------------------------------------------------------
!
!-----------------------------------------------------------------------
!
! Variable Declarations.
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
!
!-----------------------------------------------------------------------
!
INTEGER :: nradfil ! # of radars currently available
INTEGER :: nx,ny,nz ! model grid size
INTEGER :: mx_rad
REAL :: xs(nx) ! x-coor at scalar points
REAL :: ys(ny) ! y-coor at scalar points
REAL :: zs(nx,ny,nz) ! z-coor at scalar points
CHARACTER (LEN=132) radfname(mx_rad)
REAL :: rhinf
REAL :: rvinf
!
! OUTPUT:
!
REAL :: ref_mos_3d (nx,ny,nz) ! combined radar refl. field
INTEGER :: istatus
!
! Temporary working array
!
REAL :: refl(nx,ny,nz)
REAL :: tem1(nx,ny,nz)
REAL :: tem2(nx,ny,nz)
!
!-----------------------------------------------------------------------
!
! Misc. local variables
!
!-----------------------------------------------------------------------
!
INTEGER :: i,j,k,irad
INTEGER :: im1,ip1,jm1,jp1,km1,kp1
INTEGER :: isrcrad,istat_rad
REAL :: latrad,lonrad,elvrad
REAL :: x_m1,x_p1,y_m1,y_p1,hgt_km1,hgt_kp1,frac
REAL :: refl_ip1,refl_im1,refl_jm1,refl_jp1,refl_km1,refl_kp1
LOGICAL :: got_im1,got_ip1,got_jm1,got_jp1,got_km1,got_kp1
INTEGER :: strhopt_rad,mapproj_rad
REAL :: dx_rad,dy_rad,dz_rad,dzmin_rad
REAL :: ctrlat_rad,ctrlon_rad,tlat1_rad,tlat2_rad,tlon_rad
REAL :: sclfct_rad
CHARACTER (LEN=5) stnrad
CHARACTER (LEN=128) warn_string
!
!-----------------------------------------------------------------------
!
! Include files
!
!-----------------------------------------------------------------------
!
INCLUDE 'grid.inc'
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
istatus=0
warn_string = 'WARNING: Radar data are not used ' // &
'due to grid or map projection inconsistencies'
WRITE(6,'(a)') &
' Mosaiking reflectivity from multiple radar observations'
!
!-----------------------------------------------------------------------
!
! Combining the multiple radar obs. to produce one set of
! 3D reflectivity field.
!
!-----------------------------------------------------------------------
!
DO irad = 1,nradfil
CALL read1rad
(nx,ny,nz,radfname(irad), &
strhopt_rad,mapproj_rad,dx_rad,dy_rad,dz_rad, &
dzmin_rad,ctrlat_rad,ctrlon_rad, &
tlat1_rad,tlat2_rad,tlon_rad,sclfct_rad, &
isrcrad,stnrad,latrad,lonrad,elvrad, &
tem1,refl,tem2,tem2, &
istat_rad)
!
!-----------------------------------------------------------------------
!
! For successful read of radar data.
!
! Check IF the radar data are remapped on the same grid as
! the one we are using for ADAS.
!
!-----------------------------------------------------------------------
!
IF (istat_rad == 1 ) THEN
WRITE(6,'(a,a)') ' Successfully read radar datafile ',radfname(irad)
IF (ABS(strhopt_rad-strhopt) > 1.0E-4 .OR. &
mapproj_rad /= mapproj) THEN
WRITE(6,*) warn_string
WRITE(6,*) &
'RADAR: strhopt=',strhopt_rad, ' mapproj=',mapproj_rad
WRITE(6,*) 'ADAS: strhopt=',strhopt, ' mapproj=',mapproj
CYCLE
END IF
!
IF (ABS(dx_rad-dx) > 1.0E-4 .OR. ABS(dy_rad-dy) > 1.0E-4 .OR. &
ABS(dz_rad-dz) > 1.0E-4 .OR. &
ABS(dzmin_rad-dzmin) > 1.0E-4) THEN
WRITE(6,*) warn_string
WRITE(6,*) 'RADAR: dx=',dx_rad, ' dy=',dy_rad,' dz=',dz_rad
WRITE(6,*) 'ADAS: dx=',dx, ' dy=',dy,' dz=',dz
CYCLE
END IF
!
IF (mapproj /= 0) THEN
IF (ABS(ctrlat_rad-ctrlat) > 1.0E-4 .OR. &
ABS(ctrlon_rad-ctrlon) > 1.0E-4) THEN
WRITE(6,*) warn_string
WRITE(6,*) 'RADAR: ctrlat=',ctrlat_rad,' ctrlon=',ctrlon_rad
WRITE(6,*) 'ADAS: ctrlat=',ctrlat, ' ctrlon=',ctrlon
CYCLE
END IF
!
IF(ABS(sclfct_rad-sclfct) > 1.0E-4) THEN
WRITE(6,*) warn_string
WRITE(6,*) 'RADAR: sclfct=',sclfct_rad
WRITE(6,*) 'ADAS: sclfct=',sclfct
CYCLE
END IF
END IF
!
IF (mapproj == 1 .OR. mapproj == 3) THEN
IF (ABS(tlat1_rad-trulat1) > 1.0E-4 .OR. &
ABS(tlon_rad-trulon) > 1.0E-4) THEN
WRITE(6,*) warn_string
WRITE(6,*) 'RADAR: trulat1=',tlat1_rad, ' trulon=',tlon_rad
WRITE(6,*) 'ADAS: trulat1=',trulat1, ' trulon=',trulon
CYCLE
END IF
ELSE IF (mapproj == 2) THEN
IF (ABS(tlat1_rad-trulat1) > 1.0E-4 .OR. &
ABS(tlat2_rad-trulat2) > 1.0E-4 &
.OR. ABS(tlon_rad-trulon) > 1.0E-4) THEN
WRITE(6,*) warn_string
WRITE(6,*) 'RADAR: trulat1=',tlat1_rad, &
' trulat2=',tlat2_rad,' trulon=',tlon_rad
WRITE(6,*) 'ADAS: trulat1=',trulat1, &
' trulat2=',trulat2,' trulon=',trulon
CYCLE
END IF
END IF
!
!-----------------------------------------------------------------------
!
! For now, mosaic by taking the maximum value
!
!-----------------------------------------------------------------------
!
WRITE(6,'(a,a,a)') ' Bringing radar ',stnrad,' into mosaic '
! OpenMP changed loop order to j,k,i:
!$OMP PARALLEL DO PRIVATE (j,k,i,irad)
DO j=1,ny
DO k=1,nz-1
DO i=1,nx
ref_mos_3d(i,j,k) = MAX(ref_mos_3d(i,j,k),refl(i,j,k))
END DO
END DO
END DO
END IF ! read ok
END DO !irad
!
!-----------------------------------------------------------------------
!
! Vertical interpolation to fill the gaps between different
! elevations.
!
!-----------------------------------------------------------------------
!
! WRITE(6,'(a)') ' Vertically interpolating radar refl.'
!! OpenMP changed loop order to j,i,k:
!!$OMP PARALLEL DO PRIVATE(j,i,k,kp1,got_kp1,refl_kp1,hgt_kp1,km1,got_km1,refl_km1,hgt_km1,frac)
! DO j=1,ny
! DO i=1,nx
! DO k=2,nz-2
! tem1(i,j,k) = ref_mos_3d(i,j,k)
! IF(ref_mos_3d(i,j,k) < -10.) THEN
! got_kp1=.FALSE.
! DO kp1=k+1,nz-1
! IF (zs(i,j,kp1) > (zs(i,j,k)+rvinf)) EXIT
! IF (ref_mos_3d(i,j,kp1) >= -10.) THEN
! refl_kp1 = ref_mos_3d(i,j,kp1)
! hgt_kp1 = zs(i,j,kp1)
! got_kp1=.TRUE.
! EXIT
! END IF
! END DO
! got_km1=.FALSE.
! DO km1=k-1,2,-1
! IF(zs(i,j,km1) < (zs(i,j,k)-rvinf)) EXIT
! IF(ref_mos_3d(i,j,km1) >= -10) THEN
! refl_km1 = ref_mos_3d(i,j,km1)
! hgt_km1 = zs(i,j,km1)
! got_km1=.TRUE.
! EXIT
! END IF
! END DO
! IF(got_km1 .AND. got_kp1 .AND. &
! (hgt_kp1-hgt_km1) < rvinf ) THEN
! frac = (zs(i,j,k)-hgt_km1)/(hgt_kp1-hgt_km1)
! tem1(i,j,k) = refl_kp1*frac + refl_km1*(1.-frac)
! END IF
! END IF
! END DO
! END DO
! END DO
!
!-----------------------------------------------------------------------
!
! Horizontal interpolation to further fill gaps between
! the beams.
!
!-----------------------------------------------------------------------
!
! WRITE(6,'(a)') ' Horizontally interpolating radar refl.'
! DO k=1,nz-1
! DO i=2,nx-2
! DO j=2,ny-2
! ref_mos_3d(i,j,k)=tem1(i,j,k)
! IF(tem1(i,j,k) < -10.) THEN
! got_ip1=.FALSE.
! DO ip1=i+1,nx-1
! IF (xs(ip1) > (xs(i)+rhinf)) EXIT
! IF(tem1(ip1,j,k) >= -10.) THEN
! refl_ip1=tem1(ip1,j,k)
! x_p1=xs(ip1)
! got_ip1=.TRUE.
! EXIT
! END IF
! END DO
! got_im1=.FALSE.
! DO im1=i-1,1,-1
! IF (xs(im1) < (xs(i)-rhinf)) EXIT
! IF(tem1(im1,j,k) >= -10.) THEN
! refl_im1=tem1(im1,j,k)
! x_m1=xs(im1)
! got_im1=.TRUE.
! EXIT
! END IF
! END DO
! got_jp1=.FALSE.
! DO jp1=j+1,ny-1
! IF (ys(jp1) > (ys(j)+rhinf)) EXIT
! IF(tem1(i,jp1,k) >= -10.) THEN
! refl_jp1=tem1(i,jp1,k)
! y_p1=ys(jp1)
! got_jp1=.TRUE.
! EXIT
! END IF
! END DO
! got_jm1=.FALSE.
! DO jm1=j-1,1,-1
! IF (ys(jm1) < (ys(j)-rhinf)) EXIT
! IF(tem1(i,jm1,k) >= -10.) THEN
! refl_jm1=tem1(i,jm1,k)
! y_m1=ys(jm1)
! got_jm1=.TRUE.
! EXIT
! END IF
! END DO
! IF(got_im1 .AND. got_ip1 .AND. (x_p1-x_m1) < rhinf .AND. &
! got_jm1 .AND. got_jp1 .AND. (y_p1-y_m1) < rhinf ) THEN
! frac = (xs(i)-x_m1)/(x_p1-x_m1)
! ref_mos_3d(i,j,k) = refl_ip1*frac + refl_im1*(1-frac)
! frac = (ys(j)-y_m1)/(y_p1-y_m1)
! ref_mos_3d(i,j,k) = (refl_jp1*frac + refl_jm1*(1-frac) &
! + ref_mos_3d(i,j,k))*0.5
! ELSE IF (got_im1 .AND. got_ip1 .AND. &
! (x_p1-x_m1) < rhinf) THEN
! frac = (xs(i)-x_m1)/(x_p1-x_m1)
! ref_mos_3d(i,j,k) = refl_ip1*frac + refl_im1*(1-frac)
! ELSE IF (got_jm1 .AND. got_jp1 .AND. &
! (y_p1-y_m1) < rhinf) THEN
! frac = (ys(j)-y_m1)/(y_p1-y_m1)
! ref_mos_3d(i,j,k) = refl_jp1*frac + refl_jm1*(1-frac)
! END IF
! END IF
! END DO
! END DO
! END DO
!
!-----------------------------------------------------------------------
!
! Done.
!
!-----------------------------------------------------------------------
!
istatus=1
RETURN
END SUBROUTINE refmosaic
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE READRAD ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE readrad(nx,ny,nz,isrcrad,stnrad &,4
,latrad,lonrad,elvrad &
,gridvel,gridref,gridnyq,gridtim &
,istatus)
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Reads radar data remapped on the ARPS grid.
! This routine requires the remapping to occur on the same grid
! as the analysis.
!
!-----------------------------------------------------------------------
!
! AUTHOR: Jian Zhang
! 05/1996 Read the remapped radar data which was written by the
! corresponding output routine "wrtrad" in remaplib.f.
!
! MODIFICATION HISTORY:
! 03/19/97 J. Zhang
! Added a line of error message when there is trouble
! reading a radar file.
! 04/03/97 J. Zhang
! Added the option of reading the data file created
! from "WTRADCOL". Added output for the remapping
! parameters in the radar file (e.g., strhopt,mapproj,
! dx,dy,dz,dzmin,ctrlat,ctrlon,tlat1,tlat2,tlon,scale)
! 04/07/97 J. Zhang
! Added the QC for the case when i,j,k outside the model
! domain
! 04/09/97 J. Zhang
! Added the Initializations for gridref, girdvel...
! 04/11/97 J. Zhang
! Include dims.inc for nx,ny,nz
! 04/14/97 J. Zhang
! Added message output for the case when actual # of
! radar files exceeds the maximum allowed number in the
! ADAS include file. When that happens, the program will
! stop.
! 03/31/98 J. Zhang
! Deleted the option for reading the radar data file
! created from "WRTRAD".
!
!-----------------------------------------------------------------------
!
! INCLUDE: (from dims.inc and adas.inc)
!
! nx Number of grid points in the x-direction (east/west)
! ny Number of grid points in the y-direction (north/south)
! nz Number of grid points in the vertical
! mx_rad maximum number of radars
!
! nradfil number of radar files
! radfname file name for radar datasets
!
! OUTPUT:
!
! isrcrad index of radar source
! stnrad radar site name character*4
! latrad latitude of radar (degrees N)
! lonrad longitude of radar (degrees E)
! elvrad elevation of feed horn of radar (m MSL)
!
! gridvel radial velocity on ARPS grid
! gridref reflectivity on ARPS grid
! gridnyq nyquist velocity on ARPS grid
! gridtim observation time at ARPS grid
!
! istatus status indicator
!
!
!-----------------------------------------------------------------------
!
! Variable Declarations:
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
!
!-----------------------------------------------------------------------
!
! Include files:
!
INCLUDE 'adas.inc' ! ADAS parameters
!
!-----------------------------------------------------------------------
!
! INPUT:
INTEGER :: nx,ny,nz ! the ARPS grid size
!
! LOCAL:
!
REAL :: readk(nz)
REAL :: readhgt(nz)
REAL :: readref(nz)
REAL :: readvel(nz)
REAL :: readnyq(nz)
REAL :: readtim(nz)
!
INTEGER :: kntref(nz)
INTEGER :: kntvel(nz)
INTEGER :: iradvr
INTEGER :: nradvr
!
! OUTPUT:
INTEGER :: istatus
!
! OUTPUT: ARPS radar arrays
REAL :: gridvel(nx,ny,nz,mx_rad)
REAL :: gridref(nx,ny,nz,mx_rad)
REAL :: gridnyq(nx,ny,nz,mx_rad)
REAL :: gridtim(nx,ny,nz,mx_rad)
!
! OUTPUT: Radar site variables
INTEGER :: isrcrad(0:mx_rad)
CHARACTER (LEN=5) :: stnrad(mx_rad)
REAL :: latrad(mx_rad)
REAL :: lonrad(mx_rad)
REAL :: elvrad(mx_rad)
!
!-----------------------------------------------------------------------
!
! Misc. local variables
!
!-----------------------------------------------------------------------
!
CHARACTER (LEN=4) :: stn
CHARACTER (LEN=80) :: runname
CHARACTER (LEN=132) :: fname
INTEGER :: ireftim,itime,vcpnum,idummy
INTEGER :: iradfmt,strhopt,mapprin
INTEGER :: nchanl,ierr
INTEGER :: iyr, imon, idy, ihr, imin, isec
INTEGER :: i,j,k,krad,kk,ipt,klev
REAL :: dxin,dyin,dzin,dzminin,ctrlatin
REAL :: ctrlonin,tlat1in,tlat2in,tlonin,scalin,rdummy
REAL :: xrd,yrd,gridlat,gridlon,elev
!
!-----------------------------------------------------------------------
!
! Common block that stores remapping parameters for the radar
! data file.
!
!-----------------------------------------------------------------------
!
COMMON/remapfactrs_rad/strhopt,mapprin
COMMON/remapfactrs_rad2/dxin,dyin,dzin,dzminin, &
ctrlatin,ctrlonin,tlat1in,tlat2in,tlonin,scalin
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!-----------------------------------------------------------------------
!
istatus=0
IF (nradfil > mx_rad) THEN
WRITE(6,'(a,i3,a,i3/a)') &
' ERROR: nradfil ',nradfil,' exceeds mx_rad dimension', &
mx_rad,' please increase MX_RAD in the .inc file'
PRINT*,' ABORTING from READRAD......'
STOP
END IF
IF(nradfil < 1) THEN
WRITE(6,*) 'No radar data available. Returning from READRAD...'
RETURN
END IF
!
!-----------------------------------------------------------------------
!
! Initializations
!
!-----------------------------------------------------------------------
!
! OpenMP changed loop order to j,krad,k,i:
!$OMP PARALLEL DO PRIVATE(j,krad,k,i)
DO j=1,ny
DO krad = 1, mx_rad
DO k=1,nz
DO i=1,nx
gridref(i,j,k,krad)=-9999.
gridvel(i,j,k,krad)=-9999.
gridnyq(i,j,k,krad)=-9999.
gridtim(i,j,k,krad)=-9999.
END DO
END DO
END DO
END DO
!
!-----------------------------------------------------------------------
!
! Loop through all radars
!
!-----------------------------------------------------------------------
!
DO krad = 1, nradfil
fname=radfname(krad)
CALL asnctl
('NEWLOCAL', 1, ierr)
CALL asnfile
(fname, '-F f77 -N ieee', ierr)
CALL getunit
( nchanl )
OPEN(UNIT=nchanl,FILE=trim(fname),ERR=399, &
FORM='unformatted',STATUS='old')
!
!-----------------------------------------------------------------------
!
! Read radar description variables
!
!-----------------------------------------------------------------------
!
istatus=1
isrcrad(krad)=1
!
READ(nchanl) stn
stnrad(krad)=stn
READ(nchanl) ireftim,itime,vcpnum,idummy,idummy, &
idummy,idummy,idummy,idummy,idummy
!
CALL abss2ctim
(itime, iyr, imon, idy, ihr, imin, isec )
iyr=MOD(iyr,100)
WRITE(6,'(/a,i2.2,a,i2.2,a,i2.2,1X,i2.2,a,i2.2,a)') &
'Reading remapped raw radar data for: ', &
imon,'/',idy,'/',iyr,ihr,':',imin,' UTC'
!
READ(nchanl) runname
READ(nchanl) iradfmt,strhopt,mapprin,idummy,idummy, &
idummy,idummy,idummy,idummy,idummy
READ(nchanl) dxin,dyin,dzin,dzminin,ctrlatin, &
ctrlonin,tlat1in,tlat2in,tlonin,scalin, &
latrad(krad),lonrad(krad),elvrad(krad), &
rdummy,rdummy
!
DO k=1,nz
kntref(k) = 0
kntvel(k) = 0
END DO
READ(nchanl) nradvr,iradvr
!
DO ipt=1,(nx*ny)
READ(nchanl,END=51) i,j,xrd,yrd, &
gridlat,gridlon,elev,klev
READ(nchanl,END=52) (readk(kk),kk=1,klev)
READ(nchanl,END=52) (readhgt(kk),kk=1,klev)
READ(nchanl,END=52) (readref(kk),kk=1,klev)
READ(nchanl,END=52) (readvel(kk),kk=1,klev)
READ(nchanl,END=52) (readnyq(kk),kk=1,klev)
READ(nchanl,END=52) (readtim(kk),kk=1,klev)
IF(i <= nx.AND.i >= 1 .AND. j <= ny.AND.j >= 1) THEN
DO kk=1,klev
k=nint(readk(kk))
IF(k <= nz.AND.k >= 1) THEN
gridref(i,j,k,krad)=readref(kk)
gridvel(i,j,k,krad)=readvel(kk)
gridnyq(i,j,k,krad)=readnyq(kk)
gridtim(i,j,k,krad)=readtim(kk)
IF (gridref(i,j,k,krad) > -200. .AND. gridref(i,j,k,krad) < 200.) &
kntref(k)=kntref(k)+1
IF (gridvel(i,j,k,krad) > -200. .AND. gridvel(i,j,k,krad) < 200.) &
kntvel(k)=kntvel(k)+1
END IF ! 1 < k < nz
END DO ! kk = 1, klev
END IF ! 1 < i < nx & 1 < j < ny
END DO ! ipt = 1, nx*ny
51 CONTINUE
ipt=ipt-1
WRITE(6,'(a,i6,a)') ' End of file reached after reading', &
ipt,' columns'
GO TO 55
52 CONTINUE
WRITE(6,'(a,i6,a)') ' End of file reached while reading', &
ipt,' column'
55 CONTINUE
!
!-----------------------------------------------------------------------
!
! Write statistics
!
!-----------------------------------------------------------------------
!
WRITE(6,'(a)') ' k n ref n vel'
DO k=1,nz
WRITE(6,'(i3,2i10)') k,kntref(k),kntvel(k)
END DO
!
CLOSE(nchanl)
CALL retunit( nchanl )
GO TO 400
399 CONTINUE
PRINT*,'Error reading the radar file:',fname
400 CONTINUE
END DO ! KRAD = 1, nradfil
RETURN
END SUBROUTINE readrad
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE READ1RAD ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE read1rad(nx,ny,nz,radfname, & 1,35
strhopt_rad,mapproj_rad,dx_rad,dy_rad,dz_rad, &
dzmin_rad,ctrlat_rad,ctrlon_rad, &
tlat1_rad,tlat2_rad,tlon_rad,sclfct_rad, &
isrcrad,stnrad,latrad,lonrad,elvrad, &
gridvel,gridref,gridnyq,gridtim, &
istatus)
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Reads radar data remapped on the ARPS grid.
! This routine requires the remapping to occur on the same grid
! as the analysis.
!
!-----------------------------------------------------------------------
!
! AUTHOR: Jian Zhang
! 05/1996 Read the remapped radar data which was written by the
! corresponding output routine "wrtrad" in remaplib.f.
!
! MODIFICATION HISTORY:
! 03/19/97 J. Zhang
! Added a line of error message when there is trouble
! reading a radar file.
! 04/03/97 J. Zhang
! Added the option of reading the data file created
! from "WTRADCOL". Added output for the remapping
! parameters in the radar file (e.g., strhopt,mapproj,
! dx,dy,dz,dzmin,ctrlat,ctrlon,tlat1,tlat2,tlon,scale)
! 04/07/97 J. Zhang
! Added the QC for the case when i,j,k outside the model
! domain
! 04/09/97 J. Zhang
! Added the Initializations for gridref, girdvel...
! 04/11/97 J. Zhang
! Include dims.inc for nx,ny,nz
! 04/14/97 J. Zhang
! Added message output for the case when actual # of
! radar files exceeds the maximum allowed number in the
! ADAS include file. When that happens, the program will
! stop.
! 03/31/98 J. Zhang
! Deleted the option for reading the radar data file
! created from "WRTRAD".
! 11/01/01 K. Brewster
! Modified readrad to read1rad to read only one radar file
! at a time to save memory.
! 02/02/04 K. Thomas
! Change so a missing HDF4 isn't a fatal error.
! 02/18/04 K. Thomas
! Allocated I/O unit not returned when binary file doesn't exit.
! This update fixes the problem.
!
!-----------------------------------------------------------------------
!
! INPUT:
!
! nx Number of grid points in the x-direction (east/west)
! ny Number of grid points in the y-direction (north/south)
! nz Number of grid points in the vertical
! radfname file name for radar datasets
!
! OUTPUT:
!
! isrcrad index of radar source
! stnrad radar site name character*4
! latrad latitude of radar (degrees N)
! lonrad longitude of radar (degrees E)
! elvrad elevation of feed horn of radar (m MSL)
!
! gridvel radial velocity on ARPS grid
! gridref reflectivity on ARPS grid
! gridnyq nyquist velocity on ARPS grid
! gridtim observation time at ARPS grid
!
! istatus status indicator
!
!
!-----------------------------------------------------------------------
!
! Variable Declarations:
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
!
INTEGER :: nx,ny,nz ! the ARPS grid size
CHARACTER (LEN=132) :: radfname
INTEGER :: strhopt_rad,mapproj_rad
REAL :: dx_rad,dy_rad,dz_rad,dzmin_rad
REAL :: ctrlat_rad,ctrlon_rad,tlat1_rad,tlat2_rad,tlon_rad
REAL :: sclfct_rad
!
! OUTPUT: Radar site variables
!
INTEGER :: isrcrad
CHARACTER (LEN=5) :: stnrad
REAL :: latrad
REAL :: lonrad
REAL :: elvrad
!
! OUTPUT: ARPS radar arrays
!
REAL :: gridvel(nx,ny,nz)
REAL :: gridref(nx,ny,nz)
REAL :: gridnyq(nx,ny,nz)
REAL :: gridtim(nx,ny,nz)
INTEGER :: istatus
!
!-----------------------------------------------------------------------
!
! Misc. local variables
!
!-----------------------------------------------------------------------
!
REAL :: readk(nz)
REAL :: readhgt(nz)
REAL :: readref(nz)
REAL :: readvel(nz)
REAL :: readnyq(nz)
REAL :: readtim(nz)
!
INTEGER, ALLOCATABLE :: kntref(:)
INTEGER, ALLOCATABLE :: kntvel(:)
!
INTEGER :: mxradvr,nradvr
PARAMETER(mxradvr=10)
INTEGER :: iradvr(mxradvr)
CHARACTER (LEN=4) :: stn
CHARACTER (LEN=80) :: runname
INTEGER :: ireftim,itime,vcpnum,idummy
INTEGER :: iradfmt,strhopt,mapprin
INTEGER :: nchanl,ierr
INTEGER :: iyr, imon, idy, ihr, imin, isec
INTEGER :: i,j,k,krad,kk,ipt,klev
REAL :: xrd,yrd,gridlat,gridlon,elev,rdummy
!
!-----------------------------------------------------------------------
!
! hdf arrays
!
!-----------------------------------------------------------------------
!
INTEGER (KIND=selected_int_kind(4)), ALLOCATABLE :: itmp(:,:,:)
REAL, ALLOCATABLE :: hmax(:), hmin(:) ! Temporary array
INTEGER :: lens,dmpfmt,sd_id,isource
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
istatus=0
!
!-----------------------------------------------------------------------
!
! Initializations
!
!-----------------------------------------------------------------------
!
ALLOCATE(kntref(nz))
ALLOCATE(kntvel(nz))
!
! OpenMP changed loop order to j,k,i:
!$OMP PARALLEL DO PRIVATE(j,k,i)
DO j=1,ny
DO k=1,nz
DO i=1,nx
gridref(i,j,k)=-9999.
gridvel(i,j,k)=-9999.
gridnyq(i,j,k)=-9999.
gridtim(i,j,k)=-9999.
END DO
END DO
END DO
!
DO k=1,nz
kntref(k)=0
kntvel(k)=0
END DO
!
!-----------------------------------------------------------------------
!
! Open file
!
!-----------------------------------------------------------------------
!
CALL asnctl
('NEWLOCAL', 1, ierr)
CALL asnfile
(radfname, '-F f77 -N ieee', ierr)
lens=LEN(trim(radfname))
IF(radfname(lens-3:lens)=='hdf4')THEN
dmpfmt=2
ELSE
dmpfmt=1
ENDIF
print*,'radfname=',TRIM(radfname),'dmpfmt=',dmpfmt
IF(dmpfmt==1)THEN
CALL getunit
( nchanl )
OPEN(UNIT=nchanl,FILE=trim(radfname),ERR=399, &
FORM='unformatted',STATUS='old')
!
!-----------------------------------------------------------------------
!
! Read radar description variables
!
!-----------------------------------------------------------------------
!
istatus=1
isrcrad=1
!
READ(nchanl) stn
stnrad=stn
READ(nchanl) ireftim,itime,vcpnum,idummy,idummy, &
idummy,idummy,idummy,idummy,idummy
!
CALL abss2ctim
(itime, iyr, imon, idy, ihr, imin, isec )
iyr=MOD(iyr,100)
WRITE(6,'(/a,i2.2,a,i2.2,a,i2.2,1X,i2.2,a,i2.2,a)') &
'Reading remapped raw radar data for: ', &
imon,'/',idy,'/',iyr,ihr,':',imin,' UTC'
!
READ(nchanl) runname
READ(nchanl) iradfmt,strhopt_rad,mapproj_rad,idummy,idummy, &
idummy,idummy,idummy,idummy,idummy
READ(nchanl) dx_rad,dy_rad,dz_rad,dzmin_rad,ctrlat_rad, &
ctrlon_rad,tlat1_rad,tlat2_rad,tlon_rad,sclfct_rad, &
latrad,lonrad,elvrad, &
rdummy,rdummy
!
READ(nchanl) nradvr,iradvr
!
DO ipt=1,(nx*ny)
READ(nchanl,END=51) i,j,xrd,yrd, &
gridlat,gridlon,elev,klev
READ(nchanl,END=52) (readk(kk),kk=1,klev)
READ(nchanl,END=52) (readhgt(kk),kk=1,klev)
READ(nchanl,END=52) (readref(kk),kk=1,klev)
READ(nchanl,END=52) (readvel(kk),kk=1,klev)
READ(nchanl,END=52) (readnyq(kk),kk=1,klev)
READ(nchanl,END=52) (readtim(kk),kk=1,klev)
IF(i <= nx.AND.i >= 1 .AND. j <= ny.AND.j >= 1) THEN
DO kk=1,klev
k=nint(readk(kk))
IF(k <= nz.AND.k >= 1) THEN
gridref(i,j,k)=readref(kk)
gridvel(i,j,k)=readvel(kk)
gridnyq(i,j,k)=readnyq(kk)
gridtim(i,j,k)=readtim(kk)
IF (gridref(i,j,k) > -200. .AND. gridref(i,j,k) < 200.) &
kntref(k)=kntref(k)+1
IF (gridvel(i,j,k) > -200. .AND. gridvel(i,j,k) < 200.) &
kntvel(k)=kntvel(k)+1
END IF ! 1 < k < nz
END DO ! kk = 1, klev
END IF ! 1 < i < nx & 1 < j < ny
END DO ! ipt = 1, nx*ny
51 CONTINUE
ipt=ipt-1
WRITE(6,'(a,i6,a)') ' End of file reached after reading', &
ipt,' columns'
GO TO 55
52 CONTINUE
WRITE(6,'(a,i6,a)') ' End of file reached while reading', &
ipt,' column'
55 CONTINUE
!
!-----------------------------------------------------------------------
!
! Write statistics
!
!-----------------------------------------------------------------------
!
print*,'finishing reading binary radar file'
CLOSE(nchanl)
CALL retunit( nchanl )
GO TO 400
399 CONTINUE
PRINT*,'Error reading the radar file:',radfname
CALL retunit( nchanl )
400 CONTINUE
ELSE !HDF4 file
ALLOCATE (itmp(nx,ny,nz),stat=istatus)
IF (istatus /= 0) THEN
WRITE (6,*) "READ1RAD: ERROR allocating itmp, returning"
STOP
END IF
ALLOCATE (hmax(nz),stat=istatus)
IF (istatus /= 0) THEN
WRITE (6,*) "READ1RAD: ERROR allocating hmax, returning"
STOP
END IF
ALLOCATE (hmin(nz),stat=istatus)
IF (istatus /= 0) THEN
WRITE (6,*) "READ1RAD: ERROR allocating hmin, returning"
STOP
END IF
CALL hdfopen
(trim(radfname), 1, sd_id)
IF (sd_id < 0) THEN
WRITE (6,*) "READ1RAD: ERROR opening ", &
trim(radfname)," for reading."
istatus = 0
goto 700
END IF
CALL hdfrdc
(sd_id, 4, 'radid', stn, istatus)
stnrad=stn
CALL hdfrdi
(sd_id, 'ireftim', ireftim, istatus)
CALL hdfrdi
(sd_id, 'itime', itime, istatus)
CALL hdfrdi
(sd_id, 'vcpnum', vcpnum, istatus)
CALL hdfrdi
(sd_id, 'isource', isource, istatus)
CALL hdfrdc
(sd_id, 40, 'runname', runname, istatus)
CALL hdfrdi
(sd_id, 'iradfmt', iradfmt, istatus)
CALL hdfrdi
(sd_id, 'strhopt', strhopt_rad, istatus)
CALL hdfrdi
(sd_id, 'mapproj', mapproj_rad, istatus)
CALL hdfrdr
(sd_id, 'dx', dx_rad, istatus)
CALL hdfrdr
(sd_id, 'dy', dy_rad, istatus)
CALL hdfrdr
(sd_id, 'dz', dz_rad, istatus)
CALL hdfrdr
(sd_id, 'dzmin', dzmin_rad, istatus)
CALL hdfrdr
(sd_id, 'ctrlat', ctrlat_rad, istatus)
CALL hdfrdr
(sd_id, 'ctrlon', ctrlon_rad, istatus)
CALL hdfrdr
(sd_id, 'trulat1', tlat1_rad, istatus)
CALL hdfrdr
(sd_id, 'trulat2', tlat2_rad, istatus)
CALL hdfrdr
(sd_id, 'trulon', tlon_rad, istatus)
CALL hdfrdr
(sd_id, 'sclfct', sclfct_rad, istatus)
CALL hdfrdr
(sd_id, 'latrad', latrad, istatus)
CALL hdfrdr
(sd_id, 'lonrad', lonrad, istatus)
CALL hdfrdr
(sd_id, 'elvrad', elvrad, istatus)
CALL hdfrdi
(sd_id, 'nradvr', nradvr, istatus)
CALL hdfrd1di
(sd_id,'iradvr', mxradvr,iradvr,istatus)
PRINT *, ' Got nradvr,iradvr: ',nradvr,iradvr
CALL abss2ctim
(itime, iyr, imon, idy, ihr, imin, isec )
iyr=MOD(iyr,100)
WRITE(6,'(/a,i2.2,a,i2.2,a,i2.2,1X,i2.2,a,i2.2,a)') &
'Reading remapped raw radar data for: ', &
imon,'/',idy,'/',iyr,ihr,':',imin,' UTC'
CALL hdfrd3d
(sd_id,"gridref",nx,ny,nz,gridref,istatus,itmp,hmax,hmin)
IF (istatus /= 0) GO TO 115
CALL hdfrd3d
(sd_id,"gridvel",nx,ny,nz,gridvel,istatus,itmp,hmax,hmin)
IF (istatus /= 0) GO TO 115
CALL hdfrd3d
(sd_id,"gridnyq",nx,ny,nz,gridnyq,istatus,itmp,hmax,hmin)
IF (istatus /= 0) GO TO 115
CALL hdfrd3d
(sd_id,"gridtim",nx,ny,nz,gridtim,istatus,itmp,hmax,hmin)
IF (istatus /= 0) GO TO 115
CALL hdfclose
(sd_id,istatus)
DO j=1,ny
DO k=1,nz
DO i=1,nx
IF (gridref(i,j,k) > -200. .AND. gridref(i,j,k) < 200.) &
kntref(k)=kntref(k)+1
IF (gridvel(i,j,k) > -200. .AND. gridvel(i,j,k) < 200.) &
kntvel(k)=kntvel(k)+1
END DO
END DO
END DO
istatus=1
print*,'finishing reading hdf'
700 CONTINUE
DEALLOCATE(hmin)
DEALLOCATE(hmax)
DEALLOCATE(itmp)
END IF
IF (istatus == 1) THEN
WRITE(6,'(a)') ' k n ref n vel'
DO k=1,nz
WRITE(6,'(i3,2i10)') k,kntref(k),kntvel(k)
END DO
END IF
DEALLOCATE(kntref)
DEALLOCATE(kntvel)
RETURN
!
! Destination for hdf read error
!
115 CONTINUE
WRITE(6,'(/a/)') ' Error reading data in HDFREAD'
istatus=-11
DEALLOCATE(hmin)
DEALLOCATE(hmax)
DEALLOCATE(itmp)
DEALLOCATE(kntref)
DEALLOCATE(kntvel)
RETURN
END SUBROUTINE read1rad
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE GET_VIS ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
!
SUBROUTINE process_vis(solar_alt,nx,ny, & 1
cloud_frac_vis_a,albedo,r_missing,istatus)
!
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Read satellite visible imagery data from LAPS ".lvd" file.
!
!-----------------------------------------------------------------------
!
! AUTHOR: (Jian Zhang)
! 04/1996 Based on the LAPS cloud analysis code of 1995.
!
! MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
! INPUT:
INTEGER :: nx,ny
REAL :: solar_alt(nx,ny)
REAL :: r_missing
!
! OUTPUT:
!
REAL :: albedo(nx,ny)
REAL :: cloud_frac_vis_a(nx,ny)
!
! LOCAL
!
INTEGER :: ihist_alb(-10:20)
INTEGER :: ihist_frac_sat(-10:20)
INTEGER :: ih_cf_sat(-10:20)
!
!-----------------------------------------------------------------------
!
! Misc. variables
!
!-----------------------------------------------------------------------
!
INTEGER :: i,j,iscr_alb
INTEGER :: ibeg,iend,jbeg,jend
INTEGER :: n_missing_albedo
REAL :: albedo_to_cf,cloud_frac_vis
REAL :: frac,term1,term2
INTEGER :: istatus,iscr_frac_sat
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!
!-----------------------------------------------------------------------
!
! Initialize all histogram arrays.
!
!-----------------------------------------------------------------------
!
DO i=-10,20
ihist_alb(i) = 0
ihist_frac_sat(i) = 0
ih_cf_sat(i) = 0
END DO
!
!-----------------------------------------------------------------------
!
! Read the interpolated satellite albedo data.
! These data were created by laps2arps.f (based on ter2arps)
! by interpolating OLAPS (vortex95) grid satellite data onto
! the ARPS grid.
!
!-----------------------------------------------------------------------
!
ibeg=MAX(1,nx/2-5)
iend=MIN(nx,nx/2+5)
jbeg=MAX(1,ny/2-5)
jend=MIN(ny,ny/2+5)
!
WRITE(6,'(a)') ' Satellite albedo value examples in the mid-domain:'
WRITE(6,'(/4x,11(2x,i2,2x))') (i,i=ibeg,iend)
WRITE(6,'(1x,i3,11f6.2)') &
(j,(albedo(i,j),i=ibeg,iend),j=jend,jbeg,-1)
!
n_missing_albedo = 0
!
!-----------------------------------------------------------------------
!
! Horizontal array loop
!
!-----------------------------------------------------------------------
!
DO j = 1,ny
DO i = 1,nx
!
!-----------------------------------------------------------------------
!
! We now only use the VIS data if the solar alt exceeds 15 deg
!
!-----------------------------------------------------------------------
!
IF (solar_alt(i,j) > 15.0 .AND. albedo(i,j) > 0.) THEN
!
!-----------------------------------------------------------------------
!
! Translate the albedo into cloud fraction
! Store histogram information for satellite data
!
!-----------------------------------------------------------------------
!
iscr_alb = nint(albedo(i,j)*10.)
iscr_alb = MIN(MAX(iscr_alb,-10),20)
ihist_alb(iscr_alb) = ihist_alb(iscr_alb) + 1
cloud_frac_vis = albedo_to_cf(albedo(i,j))
!
!-----------------------------------------------------------------------
!
! Fudge the frac at low solar elevation angles
! Note the ramp extrapolates down to 9 deg to account for slight
! errors in determining the solar elevation
!
!-----------------------------------------------------------------------
!
IF(solar_alt(i,j) < 20. .AND. solar_alt(i,j) >= 9.) THEN
frac = (20. - solar_alt(i,j)) / 10.
term1 = .13 * frac
term2 = 1. + term1
cloud_frac_vis = (cloud_frac_vis + term1) * term2
END IF
iscr_frac_sat = nint(cloud_frac_vis*10.)
iscr_frac_sat = MIN(MAX(iscr_frac_sat,-10),20)
ihist_frac_sat(iscr_frac_sat) = &
ihist_frac_sat(iscr_frac_sat) + 1
!
!-----------------------------------------------------------------------
!
! Make sure satellite cloud fraction is between 0 and 1
!
!-----------------------------------------------------------------------
!
cloud_frac_vis=max(min(cloud_frac_vis,1.0),0.0)
cloud_frac_vis_a(i,j) = cloud_frac_vis
iscr_frac_sat = nint(cloud_frac_vis*10.)
iscr_frac_sat = MIN(MAX(iscr_frac_sat,-10),20)
ih_cf_sat(iscr_frac_sat) = &
ih_cf_sat(iscr_frac_sat) + 1
ELSE ! albedo(i,j) = r_missing
n_missing_albedo = n_missing_albedo + 1
cloud_frac_vis_a(i,j) = r_missing
END IF ! albedo(i,j).ne.r_missing
END DO ! i
END DO ! j
WRITE(6,'(/a,i8/)')' N_MISSING_ALBEDO =',n_missing_albedo
IF(n_missing_albedo == nx*ny) THEN ! Return with status = 0
WRITE(6,'(a)')' All albedos were missing, return from process_vis'
istatus = 0
RETURN
END IF
WRITE(6,'(a)')' HISTOGRAMS'
WRITE(6,'(a)')' I Alb CFsat CFsato'
DO i = -5,15
WRITE(6,'(i4,i5,i7,i8)') &
i,ihist_alb(i),ihist_frac_sat(i),ih_cf_sat(i)
END DO ! i
!
WRITE(6,'(a)') ' ==== process_vis: Albedo derived cld cvr'
WRITE(6,'(/4x,11(2x,i2,2x))') (i,i=ibeg,iend)
WRITE(6,'(1X,i3,11f6.2)') &
(j,(cloud_frac_vis_a(i,j),i=ibeg,iend),j=jend,jbeg,-1)
istatus = 1
RETURN
END SUBROUTINE process_vis
!
!##################################################################
!##################################################################
!###### ######
!###### FUNCTION ALBEDO_TO_CF ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
FUNCTION albedo_to_cf( albedo )
!
!-----------------------------------------------------------------------
!
! This version assumes 0.15 land albedo and 0.80 total cloud albedo.
! Albedo fields are now calibrated before this call using the new
! visible calibration files.
!
! cloud_frac_vis = (albedo - 0.15) / (0.80 - 0.15)
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
REAL, INTENT(IN) :: albedo
REAL :: albedo_to_cf
!
! Local Variables
!
REAL, PARAMETER :: land_albedo=0.15
REAL, PARAMETER :: max_albedo=0.80
REAL, PARAMETER :: alb_denom=(1./(max_albedo-land_albedo))
REAL :: cf_vis
cf_vis = (albedo-land_albedo)*alb_denom
albedo_to_cf = MIN(MAX(cf_vis,0.),1.0)
RETURN
END FUNCTION albedo_to_cf
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE SPREAD2 ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE spread2 (cld_snd,wt_snd,i_snd,j_snd,n_cld_snd & 10
,max_cld_snd,nz,iadas,jadas,k,cover,wt)
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! This subroutine inserts the cloud sounding into the analysis arrays
! at one point location.
!
!-----------------------------------------------------------------------
!
! AUTHOR:
! 07/95
!
! MODIFICATION HISTORY:
! 03/20/96. (Jian Zhang)
!
!-----------------------------------------------------------------------
!-----------------------------------------------------------------------
!
! Variable Declarations.
!
!-----------------------------------------------------------------------
IMPLICIT NONE
INTEGER :: nz ! number of cloud analysis levels
INTEGER :: max_cld_snd ! max. possible # of cloud soundings
! in the domain
INTEGER :: n_cld_snd ! sequential index of cloud sounding sta.
INTEGER :: iadas ! i-loc of cld sounding stn in ADAS grid
INTEGER :: jadas ! j-loc of cld sounding stn in ADAS grid
INTEGER :: k ! the level where obs. cloud locates
INTEGER :: i_snd (max_cld_snd) ! array for i-location of
! cloud sounding stations
INTEGER :: j_snd (max_cld_snd) ! array for j-location of
! cloud sounding stations
REAL :: cld_snd(max_cld_snd,nz) ! cloud cover sounding array
REAL :: wt_snd(max_cld_snd,nz) ! weight array for cloud sounding
REAL :: cover ! obs. cloud coverage
REAL :: wt ! weight for the cloud cover obs.
cld_snd(n_cld_snd,k) = cover
wt_snd(n_cld_snd,k) = wt
i_snd(n_cld_snd) = iadas
j_snd(n_cld_snd) = jadas
RETURN
END SUBROUTINE spread2
!
!##################################################################
!##################################################################
!###### ######
!###### FUNCTION T_GROUND_K ######
!###### ######
!##################################################################
!##################################################################
!
FUNCTION t_ground_k (t_sfc_k,solar_alt,solar_ha &
,solar_dec,rlat,cvr_snow,r_missing_data,i,j,nx,ny)
!
!-----------------------------------------------------------------------
!
! PURPOSE:
! Calculate the ground skin temperature as a function of
! the surface air temperature and solar positions.
!
!-----------------------------------------------------------------------
!
! AUTHOR: (Jian Zhang)
! Based on the LAPS cloud analysis code of 09/95
!
! MODIFICATION HISTORY:
! 04/29/96 J. Zhang
! Added ARPS format documents.
!
!-----------------------------------------------------------------------
!
!-----------------------------------------------------------------------
!
! Variable Declarition
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
!
! INPUT:
INTEGER :: i,j,nx,ny
REAL :: t_sfc_k ! surface air temperature
REAL :: solar_alt ! solar altitude angle
REAL :: solar_ha ! solar hour angle
REAL :: solar_dec ! solar declination angle
REAL :: rlat ! latitude of the grid point
REAL :: cvr_snow ! ground snow cover at the grid point
REAL :: r_missing_data ! flag for data hole
!
! OUTPUT:
REAL :: t_ground_k ! ground skin temperature
!
! LOCAL:
INTEGER :: imid,jmid
REAL :: high_alt,low_alt,corr_low,corr_high,corr_ramp
REAL :: t_ground_fullcorr,t_snow_k,corr_negonly
REAL :: solar_transit_alt,corr
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
imid=(nx/2)+1
jmid=(ny/2)+1
solar_transit_alt = 90. - ABS(rlat - solar_dec)
IF(solar_ha < 0.) THEN ! morning
high_alt = solar_transit_alt * .66
low_alt = solar_transit_alt * .36
! low_alt = high_alt - 11.
ELSE ! afternoon
high_alt = solar_transit_alt * .79
low_alt = solar_transit_alt * .49
! low_alt = high_alt - 11.
END IF
corr_high = 4.
corr_low = -4.
corr_ramp = (corr_high - corr_low) / (high_alt - low_alt)
!
!-----------------------------------------------------------------------
!
! Warmer at day, colder at night
!
!-----------------------------------------------------------------------
!
IF(solar_alt < low_alt)THEN
corr = corr_low
ELSE IF(solar_alt > high_alt)THEN
corr = corr_high
ELSE ! ramp the function
corr = corr_low + (solar_alt - low_alt) * corr_ramp
END IF
IF(i == imid .AND. j == jmid) THEN
WRITE(6,'(1x,a,2i4,a)') 'Sample solar position parms for point (', &
i,j,')'
WRITE(6,'(1x,a,a)') ' hangle altitude transalt ratio ', &
' highalt lowalt correctn'
WRITE(6,'(1X,7F9.2)') solar_ha,solar_alt,solar_transit_alt, &
solar_alt/solar_transit_alt,high_alt,low_alt,corr
END IF
corr_negonly = MIN(corr,0.0) ! Only colder at night
IF(cvr_snow /= r_missing_data) THEN
t_ground_fullcorr = t_sfc_k + corr ! Warmer at day, colder at night
t_snow_k = t_sfc_k + corr_negonly ! Only colder at night
t_snow_k = MIN(t_snow_k,273.15) ! Snow can't be above 0C
t_ground_k = t_ground_fullcorr * (1.-cvr_snow) &
+ t_snow_k * cvr_snow
ELSE
t_ground_k = t_sfc_k + corr_negonly ! Only colder at night
END IF
RETURN
END FUNCTION t_ground_k