!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE PREPSGLOBS ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE prepsglobs(mxsng,ntime,srcsng,nsrc_sng,sngfile, & 1,6
stnsng,latsng,lonsng,xsng,ysng,hgtsng, &
obsng,qobsng,qualsng,isrcsng,qsrc,chsrc, &
nx,ny,nz,nvar,anx,xs,ys,zp, &
shght,su,sv,spres,stheta,sqv, &
rmiss,nobsng,istatus)
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! This subroutine reads non-surface single-level data.
! The data are appended to surface data already collected.
!
!-----------------------------------------------------------------------
!
! AUTHOR: Keith Brewster, CAPS
! October, 1997
!
! MODIFICATION HISTORY:
!
! 5/4/98 Developed based on RDRASS to assign height from background
! Can also be used to read satellite winds (John Manobianco).
!
! 1998/07/13 (Gene Bassett) Implemented general format for sgl obs
! and used this for MDCRS data.
!
! 1999/09/16 (Dingchen Hou) Modified the interpretion of MDCRS data.
!
! 1999/11/19 (Gene Bassett, Keith Brewster)
! Modified MDCRS data to use pressure only for deriving other
! observational quantities but not as a pressure observation in
! ADAS proper.
!
! 11/9/2001 (Keith Brewster)
! Added FORTRAN-90 features and rearranged the logic to eliminate
! GO-TOs, added processing for humidity and pressure data,
! and generally make it more suitable for additional data
! sources other than aircraft data.
!
!-----------------------------------------------------------------------
!
! Variable Declarations:
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
INTEGER :: nvar,mxsng,ntime
!
INTEGER :: jsrc
INTEGER :: nsrc_sng
CHARACTER (LEN=132) :: sngfile, line
CHARACTER (LEN=8) :: srcsng(nsrc_sng)
CHARACTER (LEN=8) :: chsrc(mxsng,ntime)
CHARACTER (LEN=5) :: stnsng(mxsng)
REAL :: latsng(mxsng)
REAL :: lonsng(mxsng)
REAL :: xsng(mxsng)
REAL :: ysng(mxsng)
REAL :: hgtsng(mxsng)
REAL :: obsng(nvar,mxsng)
REAL :: qobsng(nvar,mxsng)
INTEGER :: qualsng(nvar,mxsng)
REAL :: qsrc(nvar,mxsng)
INTEGER :: isrcsng(mxsng)
REAL :: rmiss
INTEGER :: nprev
INTEGER :: nobsng
INTEGER :: istatus
INTEGER :: nx,ny,nz
REAL :: anx(nx,ny,nz,nvar)
REAL :: xs(nx),ys(ny)
REAL :: zp(nx,ny,nz)
REAL :: shght(nz)
REAL :: su(nz)
REAL :: sv(nz)
REAL :: spres(nz)
REAL :: stheta(nz)
REAL :: sqv(nz)
REAL :: ktstoms,mbtopa
PARAMETER (ktstoms=0.5144,mbtopa=100.)
!
!-----------------------------------------------------------------------
!
! Misc. local variables
!
!-----------------------------------------------------------------------
!
INTEGER :: ivar,ksta,nsingle
INTEGER :: ipt,jpt,kgrid
INTEGER :: indom
INTEGER :: nlevs
CHARACTER (LEN=8) :: obs_id
INTEGER :: obs_num
CHARACTER (LEN=8) :: date_str
CHARACTER (LEN=6) :: time_str
INTEGER :: num_lines
CHARACTER (LEN=8) :: obs_type
REAL :: obs_lat,obs_lon,hgt_msl,hgt_agl
REAL :: obs_t,obs_td,obs_wspd,obs_wdir,obs_gust
REAL :: obs_psta,obs_pmsl,obs_palt,obs_vis
REAL :: xsta,ysta,tk,tdk,psta,qv,qvsat
CHARACTER (LEN=16) :: obs_wx
CHARACTER (LEN=6) :: fmt_in
INTEGER :: k,iline,istat
REAL :: weight
REAL :: ddrot,selev
REAL :: altpres ! presure derived from altimeter reading
!
!-----------------------------------------------------------------------
!
! Functions
!
!-----------------------------------------------------------------------
!
REAL :: alttostpr
REAL :: msltostpr
REAL :: f_qvsat
REAL :: ztopsa
!fpp$ expand (alttostpr)
!dir$ inline always alttostpr
!*$* inline routine (alttostpr)
!fpp$ expand (msltostpr)
!dir$ inline always msltostpr
!*$* inline routine (msltostpr)
!fpp$ expand (f_qvsat)
!dir$ inline always f_qvsat
!*$* inline routine (f_qvsat)
!fpp$ expand (ztopsa)
!dir$ inline always ztopsa
!*$* inline routine (ztopsa)
!
!-----------------------------------------------------------------------
!
! Include files:
!
!-----------------------------------------------------------------------
!
INCLUDE 'phycst.inc'
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
nprev=nobsng
WRITE(6,'(a,a)') ' Opening: ',sngfile
WRITE(6,'(a,i6,i6)') ' In PREPSGLOBS , mxsng, nprev = ', &
mxsng,nprev
OPEN(12,FILE=trim(sngfile),STATUS='old',iostat=istat)
IF( istat /= 0 ) THEN
WRITE(6,'(a)') ' Error opening file: ',sngfile
istatus=-1
RETURN
END IF
!
!-----------------------------------------------------------------------
!
! Main data-reading loop
!
!-----------------------------------------------------------------------
!
ksta = nobsng
DO iline=1,999999
!
!-----------------------------------------------------------------------
!
! INPUT FORMAT:
!
! first line: obs_id, obs_num, date_str, time_str,
! obs_lat, obs_lon, hgt_msl, hgt_agl,
! obs_type, num_lines
!
! See MDCRS format below.
!
! obs_id station id (8 characters)
! obs_num station id number
! date_str yyyymmdd
! time_str hhmm
! obs_lat latidute (degrees)
! obs_lon longitude (degrees)
! hgt_msl height above mean sea level (m)
! value considered missing if <= rmiss
! hgt_agl height above ground level (m), optional,
! intended for use with surface obs to help with
! mis-matches in terrain
! value considered missing if <= rmiss
! obs_type ADAS observation type (8 characters)
! num_lines number of observation lines to follow
! the header line
!
! currently unused in ADAS:
! obs_id, obs_num, date_str, time_str, hgt_agl
!
!
! currently supported observation lines formatted as follows:
!
! FMT1 20.0 -10.0 215 10.0 100.0 1013.2 1013.2 100. +TSRA
! ______ _____ _____ ___ _____ _____ ______ ______ ____ ________________
!
! FMT1 obs_t, obs_td, obs_wdir, obs_wspd, obs_gust,
! obs_pmsl, obs_palt, obs_vis, obs_wx
!
! obs_t temperature (C)
! value considered missing if <= rmiss
! obs_td dew point (C)
! value considered missing if <= rmiss
! obs_wdir wind direction (degrees clockwise from north)
! value considered missing if < 0
! obs_wspd wind speed (m/s)
! value considered missing if <= rmiss
! obs_wdir wind direction (degrees clockwise from north)
! value considered missing if < 0
! obs_gust wind gust (m/s)
! value considered missing if <= rmiss
! obs_pmsl sea level pressure (mb)
! value considered missing if <= rmiss
! obs_palt altimiter setting (mb)
! value considered missing if <= rmiss
! obs_vis visibility (km)
! value considered missing if < 0
! obs_wx current weather (METAR format)
!
! currently unused in ADAS:
! obs_gust, obs_palt, obs_vis, obs_wx
!
!-----------------------------------------------------------------------
!
!
!-----------------------------------------------------------------------
!
! Initially set all non-header line values to missing
!
!-----------------------------------------------------------------------
!
obs_t = rmiss
obs_td = rmiss
obs_wdir = -1
obs_wspd = rmiss
obs_wdir = -1
obs_gust = rmiss
obs_psta = rmiss
obs_pmsl = rmiss
obs_palt = rmiss
obs_vis = rmiss
obs_wx = ' '
altpres = rmiss
psta = rmiss
!
!-----------------------------------------------------------------------
!
! Read in the info for one station
! Skip comments
! Comments begin with # or !. Also, skip lines that begin with a space.
!
! Sample format
!XXXXXXXX 00000000 19990601_153600 42.7167 -84.9517 9448 -999.00 MDCRS 1
!-------- -------- -------- ------ -------- --------- ------ ------- -------- --
! A8, 1X, I8,1X,I4,2I2,1X,2I2,2X,1X,F8.4,1X,F9.4, 1X, I6,1X,F7.2,1X,A8,1X,I2
! MDCRS -39.8 -999.0 267 28.3 YYZ ORD FSL00307
!-----------------------------------------------------------------------
!
READ (12,'(A)',iostat=istat) line
IF (istat /= 0) EXIT
IF (line(1:1) == '#' .OR. line(1:1) == '!' .OR. line(1:1) == ' ') CYCLE
READ(line, &
'(a8,1x,i8,1x,a8,1x,a6,1x,f8.4,1x,f9.4,1x,f6.0,1x,f7.2,1x,a8,1x,i2)', &
iostat=istat) obs_id, obs_num, date_str, time_str, &
obs_lat, obs_lon, hgt_msl, hgt_agl, obs_type, num_lines
IF (istat /= 0) CYCLE
READ(12, &
'(2X,a6,1X,f6.1,1X,f6.1,1X,f3.0,1X,f5.1)',iostat=istat) &
fmt_in, obs_t, obs_td, obs_wdir, obs_wspd
IF (istat /= 0) CYCLE
! WRITE(6,'(2F9.2, F7.0, 2F7.1, F5.0, F5.1)') &
! obs_lat, obs_lon, hgt_msl, obs_t, obs_td, obs_wdir, obs_wspd
CALL lltoxy
(1,1,obs_lat,obs_lon,xsta,ysta)
CALL findlc
(nx,ny,xs,ys,xsta,ysta,ipt,jpt,indom)
IF(indom == 0) THEN
!
!-----------------------------------------------------------------------
!
! Station pressure (mb)
! Pressure altitude is assumed here.
!
!-----------------------------------------------------------------------
!
IF ( obs_type == 'MDCRS ' ) THEN
!
!-----------------------------------------------------------------------
!
! Need to convert from pressure altitude to pressure and set
! true height based on the background pressure field.
!
!-----------------------------------------------------------------------
!
altpres = mbtopa*ztopsa(hgt_msl)
!
!-----------------------------------------------------------------------
!
! Interpolate background field (in the horizontal)
! for the whole vertical column.
!
!-----------------------------------------------------------------------
!
CALL colint
(nx,ny,nz,nvar, &
xs,ys,zp,xsta,ysta,ipt,jpt,anx, &
su,sv,stheta,spres,shght,sqv,selev, &
nlevs)
!
!-----------------------------------------------------------------------
!
! Interpolate hgts in the vertical from background.
! Interpolation is linear in log-p.
!
!-----------------------------------------------------------------------
!
kgrid = 0
hgt_msl = rmiss
DO k=3,nlevs-1
IF(spres(k) < altpres) THEN
kgrid = k
EXIT
END IF
END DO
IF (kgrid > 0) THEN
weight = (LOG(altpres)-LOG(spres(kgrid)))/ &
(LOG(spres(kgrid-1))-LOG(spres(kgrid)))
hgt_msl = (1.-weight)*shght(kgrid) &
+ weight*shght(kgrid-1)
END IF
END IF
!
!-----------------------------------------------------------------------
!
! Use this datapoint if we have a valid height for it.
!
!-----------------------------------------------------------------------
!
IF (chsrc(ksta,1) == 'MDCRS ') THEN
ksta = ksta + 1
IF(ksta > mxsng) THEN
WRITE(6,'(a,i6,a)') &
' ERROR: number of single level stations,',mxsng, &
'exceeded in PREPSGLOBS. Increase mxsng and retry.'
istatus = -2
STOP
END IF
DO ivar=1,nvar
obsng(ivar,ksta)=rmiss
qobsng(ivar,ksta)=999.
qualsng(ivar,ksta)=-99
END DO
stnsng(ksta) = obs_id(1:5)
latsng(ksta) = obs_lat
lonsng(ksta) = obs_lon
xsng(ksta) = xsta
ysng(ksta) = ysta
chsrc(ksta,1) = obs_type
DO jsrc=1,nsrc_sng
IF (chsrc(ksta,1) == srcsng(jsrc)) THEN
isrcsng(ksta)=jsrc
EXIT
END IF
END DO
jsrc=isrcsng(ksta)
!
!-----------------------------------------------------------------------
!
! Set obs height
!
!-----------------------------------------------------------------------
!
hgtsng(ksta) = hgt_msl
!
!-----------------------------------------------------------------------
!
! Station pressure (mb)
! For now we'll convert msl pressure to station pressure
! using the current temperature.
!
!-----------------------------------------------------------------------
!
IF(obs_psta > rmiss ) THEN
psta=mbtopa*obs_psta
obsng(3,ksta)=psta
qobsng(3,ksta)=qsrc(3,jsrc)
qualsng(3,ksta)=100
ELSE IF(obs_palt > rmiss ) THEN
psta=mbtopa*alttostpr(obs_palt,hgt_msl)
obsng(3,ksta)=psta
qobsng(3,ksta)=qsrc(3,jsrc)
qualsng(3,ksta)=100
ELSE IF(obs_pmsl > rmiss .AND. &
obs_t > rmiss .AND. &
hgt_msl < 500. ) THEN
tk=obs_t + 273.15
psta=mbtopa*msltostpr(obs_pmsl,tk,hgt_msl)
obsng(3,ksta)=psta
qobsng(3,ksta)=qsrc(3,jsrc)
qualsng(3,ksta)=100
ELSE IF (altpres > rmiss) THEN
psta=altpres
ELSE
psta=mbtopa*alttostpr(1013.,hgt_msl)
END IF
!
!-----------------------------------------------------------------------
!
! Set winds.
!
!-----------------------------------------------------------------------
!
IF(obs_wdir >= 0. .AND. obs_wspd >= 0.) THEN
CALL ddrotuv
(1,lonsng(ksta),obs_wdir,obs_wspd,ddrot, &
obsng(1,ksta),obsng(2,ksta))
qualsng(1,ksta)=100
qualsng(2,ksta)=100
qobsng(1,ksta)=qsrc(1,jsrc)
qobsng(2,ksta)=qsrc(2,jsrc)
END IF
!
!-----------------------------------------------------------------------
!
! Potential temperature (K)
!
!-----------------------------------------------------------------------
!
IF(obs_t > rmiss .AND. psta > rmiss) THEN
tk=obs_t + 273.15
obsng(4,ksta)=tk*((p0/psta)**rddcp)
qualsng(4,ksta)=100
qobsng(4,ksta)=qsrc(4,jsrc)
END IF
!-----------------------------------------------------------------------
!
! Specific humidity (kg/kg)
!
!-----------------------------------------------------------------------
!
IF(obs_td > rmiss .AND. obs_t > rmiss .AND. &
psta > rmiss ) THEN
tk=obs_t + 273.15
tdk=obs_td + 273.15
qv = f_qvsat
( psta,tdk )
qvsat = f_qvsat
( psta, tk )
obsng(5,ksta)=max((0.05*qvsat),min(qv,qvsat))
qobsng(5,ksta)=qsrc(5,jsrc)
qualsng(5,ksta)=100
END IF
!
END IF
END IF
END DO
nobsng = ksta
nsingle = nobsng - nprev
WRITE(6,'(a,i6,i6,i6)') ' PREPSGLOBS: nsingle,nprev,nobsng', &
nsingle,nprev,nobsng
istatus=0
CLOSE(12)
RETURN
END SUBROUTINE prepsglobs