subroutine filter(tb19v, tb19h, tb22v, tb37v, & 2,1
tb37h, tb85v, tb85h, ipass, iprecip, xlat )
implicit none
real , intent (in) :: tb19v, tb19h, tb22v, tb37v, &
tb37h, tb85v, tb85h, xlat
real :: tb(7)
logical , intent (inout):: ipass
integer , intent (inout):: iprecip
integer :: ipass1, ipass2
real :: sst, dsst
real :: theta,tc,wv,u,alw19,alw37,alw85
! write (unit=stdout,fmt=*) 'tbdata',tb19v, tb19h, tb22v, tb37v,tb37h, tb85v, tb85h
! tc : cloud top temperature (C)
theta = 53.1
tc = 10.0
sst = 23.0
dsst = 1000.0
ipass1 = 0
ipass2 = 0
tb(1) = tb19v
tb(2) = tb19h
tb(3) = tb22v
tb(4) = tb37v
tb(5) = tb37h
tb(6) = tb85v
tb(7) = tb85h
! upper and lower boundary 19h (90,280), others (100,280)
if (tb(1) .lt. 280 .and. tb(1) .gt. 100. .and. &
tb(2) .lt. 280 .and. tb(2) .gt. 90. .and. &
tb(3) .lt. 280 .and. tb(3) .gt. 100. .and. &
tb(4) .lt. 280 .and. tb(4) .gt. 100. .and. &
tb(5) .lt. 280 .and. tb(5) .gt. 100. .and. &
tb(6) .lt. 280 .and. tb(6) .gt. 100. .and. &
tb(7) .lt. 280 .and. tb(7) .gt. 100. .and. &
! horizontal always much less than vertical
tb(1) .gt. tb(2) .and. &
tb(4) .gt. tb(5) .and. &
tb(6) .gt. tb(7) .and. &
! T19V always at least 4 K less than T22V, except in heavy rain
tb(3)-tb(1) .gt. 4.) then
ipass1 = 1
end if
! second check
if (ipass1 .eq. 1) then
call pettyalgos
(tb,theta,tc,sst,dsst, &
wv,u,alw19,alw37,alw85,iprecip, xlat)
if (wv .gt. -999. .and. u .gt. -999. .and. &
alw19 .gt. -999. .and. alw37 .gt. -999. .and. &
alw85 .gt. -999. ) then
ipass2 = 1
! write(unit=stdout,*)a1,a2,lat,long,theta,tb(1),tb(2),tb(3), &
! tb(4),tb(5),tb(6),tb(7)
end if
! third check
! if (ipass2 .eq. 1) then
! if (wv .ge. 5. .and. wv .le. 70 .and. &
! u .ge. -5 .and. u .le. 30 .and. &
! alw19 .ge. -0.01 .and. alw19 .le. 0.5 .and. &
! alw37 .ge. -0.01 .and. alw37 .le. 0.5 .and. &
! alw85 .ge. -0.01 .and. alw85 .le. 0.5) then
! write(unit=stdout,*)a1,a2,lat,long,theta,tb(1),tb(2),tb(3), &
! tb(4),tb(5),tb(6),tb(7)
! ipass = .true.
! end if
! end if
! if (iprecip .eq. 1) then
! ipass = .true.
! write(unit=stdout,*) 'precipitation',lat,long,wv,u,alw19,alw37,alw85,iprecip
! else
! ipass = .true.
! end if
end if
! write(unit=stdout,*) 'pass=',ipass1,ipass2,iprecip,ipass
end subroutine filter
!***************************************************************
! NOTICE
!
! This package of subroutines has been developed by Grant W. Petty
! (Purdue University) for the retrieval of column water vapor, column
! cloud liquid water, and surface wind speed from SSM/I brightness
! temperatures. The algorithm versions contained herein were developed
! in part using data sets provided by NASDA/EORC, Japan and are
! submitted to NASDA for evaluation as part of ADEOS-2/AMSR algorithm
! development activities. Because of the need to meet a submission
! deadline, they have been subject only to limited testing, and it is
! possible that undetected bugs or problems remain in the code that
! follows.
!
! Problems or questions should be directed to
! Grant W. Petty
! Earth and Atmospheric Sciences Dept.
! Purdue University
! West Lafayette, in 47907-1397
! (765) 494-2544
! gpetty@rain.atms.purdue.edu
!
! Version: July 13, 1997
! Copyright 1997, Grant W. Petty
!
! Permission is granted to all scientific users to utilize
! and/or test this set of algorithms without restriction, provided only
! that
! (1) they are not used for commercial Purposes without the
! author's permission
!
! (2) the author is given due credit for their development
!
! (3) any modifications to the algorithms by 3d parties must be
! clearly identified as such and distinguished from the author's
! original code
!
!********************************************************************
! GENERAL COMMENTS ON USAGE
!
! The algorithms that follow can act on single-pixel values of brightness
! temperature and derived variables, such as water vapor, wind speed,
! etc. However, the way they are normally used at Purdue University is
! as follows:
!
! 1 Retrieve Water Vapor and Surface Wind Speed on a pixel-by-pixel basis
!
! 2 Apply mild spatial smoothing to derived wind speed and water vapor
! fields
!
! 3 Used filtered values of wind speed and water vapor to compute
! cloud-free polarization differences
!
! 4 Compute liquid water from unsmoothed, full-resolution brightness
! temperatures, normalized by smoothed cloud-free polarizations.
!
! The smoothing step described above is optional and should not have a
! strong effect on the results outside of precipitation. Normally the
! smoothing step is necessary only for interpolating water vapor and
! wind speed into areas of precipitation, where normalized polarizations
! at 19, 37 and 85 GHz are needed for precipitation retrievals.
!
!
!********************************************************************
! This subroutine accepts SSM/I brightness temperatures and returns
! all over-ocean variables using the algorithms of Petty (1997, unpublished)
! It, and the algorithms it calls, are generally intended for use only outside
! of precipitation, except for the water vapor algorithm, which is believed to
! tolerate significant precipitation without serious errors.
!
! Inputs: tb(7) = 19v,t19h,t22v,t37v,t37h,t85v,t85h
! --- SSM/I brightness temperatures (K)
! theta -- sensor viewing angle
! tc --- assumed cloud temperature in degrees Celsius
! Note: If TC not known, set to a reasonable
! average value, such as 8.0 degrees
!
! sst -- sea surface temperature (deg. C)
! dsst -- uncertainty in the above SST (deg. C)
! (if dsst > 2.8 C, then an wind speed algorithm is
! used that doesn't require SST)
!
! Output: wv ---- column water vapor (kg/m**2) from 19.35 GHz
! u ---- surface wind speed (m/sec)
! alw19 ---- column cloud liquid water (kg/m**2) from 19.35 GHz
! alw37 ---- column cloud liquid water (kg/m**2) from 37 GHz
! alw85 ---- column cloud liquid water (kg/m**2) from 85.5 GHz
! iprecip --- set to 1 if precipitation flag invoked, else 0
!
!
! NOTE: It is not expected that liquid water values from different SSM/I
! frequencies will always closely agree, on account of significant
! differences in spatial resolution, sensitivity, and dynamic range.
! For best comparisons, average results to a common spatial resolution
! first. 19 GHz channels have the least sensitivity to thin clouds; 85
! GHz channels are most severely affected by precipitation and/or strong
! inhomogeneity in cloud fields.
!
! Also, liquid water values in excess of 0.5 kg/m**2 are generally
! flagged as precipitating, and a value of MISSinG is returned. There
! is no known method for separating cloud water from precipitation
! water. Furthermore, any attempt to retrieve total liquid water path
! when precipitation is present will require a considerably more
! sophisticated algorithm than the ones provided here.
!******************************************************************
subroutine pettyalgos(tb,theta,tc,sst,dsst, & 1,5
wv,u,alw19,alw37,alw85,iprecip,xlat)
implicit none
real tb(7),theta,tc,wv,u,alw19,alw37,alw85,xlat, sst,dsst
real, parameter :: BAD = -1000.0
integer iprecip
! get water vapor
! write (unit=stdout,fmt=*) 'tb=',tb
call pettyvapor
(tb,wv)
! write (unit=stdout,fmt=*) 'wv=',wv
! get surface wind speed
call pettywind
(tb,theta,sst,dsst,u)
! get column cloud liquid water, using 3 different algorithms
call pettylwp
(tb,theta,1,tc,alw19,iprecip,xlat)
call pettylwp
(tb,theta,2,tc,alw37,iprecip,xlat)
call pettylwp
(tb,theta,3,tc,alw85,iprecip,xlat)
if (alw19 .eq. BAD .or. alw19 .eq. BAD .or. alw85 .eq. BAD) iprecip=1
! if (iprecip .eq. 1) write (unit=stdout,fmt=*) 'iprecip B=',iprecip,'alw=',alw19,alw37,alw85
end subroutine pettyalgos
!********************************************************************
! This subroutine accepts SSM/I brightness temperatures and returns
! cloud liquid water in kg/m**2.
!
! Inputs: tb(7) = 19v,t19h,t22v,t37v,t37h,t85v,t85h
! --- SSM/I brightness temperatures (K)
! theta -- sensor viewing angle
! ifreq -- frequency to use for computing cloud liquid water
! (1 = 19.35 GHz 2 = 37 GHz 3 = 85.5 GHz)
! tc --- assumed cloud temperature in degrees Celsius
! Note: If not known, set to a reasonable value, such as 8.0 degrees
!
! Output: alw ---- column water vapor (mm)
! iprecip --- set to 1 if precipitation flag invoked, else 0
subroutine pettylwp(tb,theta,ifreq,tc,alw,iprecip,xlat) 3,5
implicit none
real tb(7),theta,alw,tc,xlat
integer ifreq,iprecip
real, parameter :: BAD = -1000.0
real t19v,t19h,t22v,t37v,t37h,t85v,t85h,MISSinG,pclr
real :: p,s85,v0,wv,u
integer :: ich
iprecip = 0
MISSinG = -8888.
pclr=0.
if (ifreq.lt.1 .or. ifreq.gt.3) then
pause "BAD VALUE OF ifREQ in PettyLWP"
alw = BAD
return
end if
! initialize brightness temperatures
t19v = tb(1)
t19h = tb(2)
t22v = tb(3)
t37v = tb(4)
t37h = tb(5)
t85v = tb(6)
t85h = tb(7)
! estimate the clear-sky polarization difference for the scene
call clearpol
(tb,theta,ifreq,pclr,iprecip)
! if value of Tc is invalid, then set to reasonable intermediate value
if (tc .lt. -20.0 .or. tc .gt. 40.0) then
tc = 8.0
end if
! calculate normalized polarization
if (ifreq .eq. 1) then
p = (t19v-t19h)/pclr
else if (ifreq .eq. 2) then
p = (t37v-t37h)/pclr
else if (ifreq .eq. 3) then
p = (t85v-t85h)/pclr
! at 85.5 GHz, there could be errors due to ice, so check S85
call PettyVapor
(tb,wv)
if (wv .eq. BAD) then
alw = BAD
return
end if
call PettyWind
(tb,theta,-99.9,1000.0,u)
if (u .eq. BAD) then
u = 5.0
alw = BAD
end if
ich = 6
call tb_clear
(ich,u,wv,v0)
s85 = p*v0 + (1.0-p)*t_kelvin - t85v
if (s85 .gt. 10.0 .or. (t85v-t85h) .lt. 5.0) p = MISSinG
end if
! convert normalized polarization to LWP
if (p .ne. MISSinG .and. p .lt. 1.4 .and. p .gt. 0.1) then
call P2LWP
(ifreq,p,tc,theta,alw,xlat)
else
alw = BAD
end if
end subroutine PettyLWP
!*********************************************************
! This routine computes liquid water path from normalized polarization
! at 19.35, 37, or 85.5 GHz (indicated by ifREQ)
subroutine p2lwp(ifreq,p,tc,theta,alw,xlat) 1,1
implicit none
integer ifreq
real p,alw,xlat,tc,theta
real alpha(3),threshhold
data alpha/2.08,2.05,1.78/
real, parameter :: BAD = -1000.0
real :: ext, costheta
integer :: iprecip
! check for extreme value due to precipitation
if (p .lt. 0.01) then
alw = BAD
iprecip = 1
return
end if
! get liquid water mass extinction coefficient
ext = alw_ext
(ifreq,tc)
! compute colum cloud liquid water using Beer's Law
costheta = cos(theta*pi/180.0)
alw = (-costheta/(alpha(ifreq)*ext))*log(p)
! check for precipitation
threshhold=0.5
! write (unit=stdout,fmt=*) 'xlat=',xlat
if (xlat .gt. 20) threshhold=0.3
if (xlat .gt. 30) threshhold=0.1
! if (xlat .gt. 40) threshhold=0.25
! if (alw .gt. 0.5) then
if (alw .gt. threshhold) then
alw = BAD
iprecip = 1
end if
end subroutine p2lwp
!***********************************************************************
! This subroutine accepts SSM/I brightness temperatures from a scene and returns
! the predicted cloud-free polarization difference for that scene
!
! Inputs: tb(7) = 19v,t19h,t22v,t37v,t37h,t85v,t85h
! --- SSM/I brightness temperatures (K)
! theta -- sensor viewing angle
! ifreq -- frequency to use for computing cloud liquid water
! (1 = 19.35 GHz 2 = 37 GHz 3 = 85.5 GHz)
!
! Output: pclr ---- cloud free polarization difference (K)
! iprecip --- set to 1 if precipitation flag invoked, else 0
subroutine ClearPol(tb,theta,ifreq,pclr,iprecip) 1,3
implicit none
real tb(7),theta,pclr
integer ifreq,iprecip
real, parameter :: BAD = -1000.0
real :: wv,u
integer :: ich
! check for valid ifREQ
if (ifreq.lt.1 .or. ifreq.gt.3) then
pause 'BAD VALUE OF ifREQ in ClearPol'
pclr = BAD
return
end if
iprecip = 0
! get water vapor estimate. If this value is returned as 'bad', then
! either the brightness temperatures are not valid for over ocean or
! else there is unusually heavy precipitation
call PettyVapor
(tb,wv)
if (wv .lt. 0.0) then
pclr = BAD
return
end if
! get wind speed estimate. If this value is returned as 'bad', assume
! that it is due to precipitation, and substitute a reasonable 'average'
! wind speed.
call PettyWind
(tb,theta,-99.9,1000.0,u)
if (u .eq. BAD) then
iprecip = 1
u = 5.0
end if
! now that we finally have estimates of water vapor and wind speed,
! compute the clear-sky polarization difference at the desired frequency
ich = ifreq + 7
call tb_clear
(ich,u,wv,pclr)
end subroutine ClearPol
!**********************************************************
! The following function returns the microwave mass extinction coefficient
! of cloud water at 19.35, 37.0, or 85.5 GHz.
!
! inputs:
! ifreq -- frequency to use for computing cloud liquid water
! (1 = 19.35 GHz 2 = 37 GHz 3 = 85.5 GHz)
! tc --- cloud temperature in degrees Celsius
!
! returned value: Mass extinction coefficient (m**2/kg)
!
function alw_ext(ifreq,tc) 1
implicit none
integer, intent(in) :: ifreq
real, intent(in) :: tc
real :: alw_ext
real :: tc2,tc3
tc2 = tc*tc
tc3 = tc2*tc
if (ifreq .eq. 1) then
alw_ext = exp(-2.55-2.98e-2*tc-6.81e-4*tc2+3.35e-6*tc3)
else if (ifreq .eq. 2) then
alw_ext = exp(-1.35-0.0234*tc-1.22e-4*tc2+5.48e-6*tc3)
else if (ifreq .eq. 3) then
alw_ext = exp(-0.0713-8.00e-3*tc-1.62e-4*tc2+1.18e-6*tc3)
end if
end function alw_ext
!*****************************************************************************
! The following routine returns approximate clear-sky SSM/I brightness temperature
! over the ocean as a function of column water vapor and surface wind speed.
! This implementation is a bivariate polynomial fit to model computed brightness
! temperatures (see Petty (1992,1994)), where the model was in turn carefully calibrated
! empirically against 200,000 cloud-free SSM/I pixels.
! This routine assumes a viewing angle not too different from 53.4 degrees, and
! it assumes "typical" values for other ocean and atmospheric parameters.
!
! inputs:
! ich = channel no. (1 = 19V, 2 = 19H, ..., 7 = 85V,
! 8 = 19V-19H, 9 = 37V-37H, 10 = 85V-85H)
! u = estimated surface wind speed (m/sec)
! wv = estimated column water vapor (kg/m**2)
!
! output:
! tb = brightness temperature
subroutine tb_clear(ich,u,wv,tb) 2
implicit none
integer, intent(in) :: ich
real, intent(in) :: u
real, intent(in) :: wv
real, intent(out) :: tb
real :: wvp,up,x,x2,x3,y,y2,y3,xy,x2y,xy2
real a(10,10)
data a/ &
0.1984E+03, 0.1674E+02, 0.1998E+00,-0.3868E+00,-0.1818E+00, &
0.7065E-01,-0.8148E+00, 0.6116E-01, 0.1400E-01, 0.0000E+00, &
0.1334E+03, 0.2587E+02, 0.3819E+01,-0.7762E-01, 0.1564E+00, &
0.4968E-01,-0.1232E+01,-0.6779E-01,-0.3083E-01, 0.0000E+00, &
0.2301E+03, 0.2865E+02, 0.5589E+00,-0.4668E+01,-0.7274E-01, &
0.1043E-01,-0.6731E+00, 0.8141E-02,-0.1081E-01, 0.0000E+00, &
0.2126E+03, 0.1103E+02,-0.2488E+00, 0.8614E+00,-0.1298E+00, &
0.4531E-01,-0.8315E+00, 0.5104E-01, 0.1785E-01, 0.0000E+00, &
0.1500E+03, 0.1864E+02, 0.3950E+01, 0.2095E+01,-0.1743E+00, &
0.1170E+00,-0.1345E+01,-0.8584E-01, 0.8143E-02, 0.0000E+00, &
0.2589E+03, 0.1706E+02,-0.7729E+00,-0.2905E+01, 0.2821E+00, &
0.3375E-02,-0.4366E+00,-0.1150E+00, 0.1881E-01, 0.0000E+00, &
0.2265E+03, 0.3363E+02, 0.2050E+01,-0.5701E+01,-0.4185E+00, &
0.8181E-01,-0.4101E+00,-0.1836E+00, 0.2666E-01, 0.0000E+00, &
0.6512E+02,-0.9112E+01,-0.3430E+01,-0.4870E+00, 0.3890E-01, &
0.1031E+00, 0.4424E+00, 0.7264E-01, 0.3514E-02, 0.0000E+00, &
0.6242E+02,-0.7553E+01,-0.4117E+01,-0.1154E+01, 0.2788E+00, &
0.1618E+00, 0.5605E+00, 0.6024E-01,-0.1659E-01, 0.0000E+00, &
0.3255E+02,-0.1698E+02,-0.3049E+01, 0.2481E+01, 0.9171E+00, &
0.1086E+00, 0.2261E+00, 0.4896E-01,-0.3257E-01, 0.0000E+00/
wvp = (wv-30.0)/20.0
up = (u-6.0)/3.0
x = wvp
x2 = x*x
x3 = x2*x
y = up
y2 = y*y
y3 = y2*y
xy = x*y
x2y = x2*y
xy2 = x*y2
tb = a(1,ich) + a(2,ich)*x + a(3,ich)*y + a(4,ich)*x2 &
+ a(5,ich)*xy + a(6,ich)*y2 + a(7,ich)*x3 &
+ a(8,ich)*x2y + a(9,ich)*xy2 + a(10,ich)*y3
end subroutine tb_clear
!**************************************************************
! This subroutine accepts SSM/I brightness temperatures and returns
! column water vapor in mm (or kg per m**2). The algorithm is described
! in the document by Petty (1997) accompanying this FORTRAN module.
!
! Inputs: tb(5) = 19v,t19h,t22v,t37v,t37h
! --- SSM/I brightness temperatures (K)
!
! Output: wv --- column water vapor (mm)
!
!
subroutine PettyVapor(tb,wv) 4
implicit none
real tb(*),wv
real t19v,t19h,t22v,t37v,t37h
real tbold(5),wvold
save tbold,wvold
logical flag
real, parameter :: BAD = -1000.0
integer :: i
real :: del, t1,t2,t3,wv2,wv3
! check for same TBs used in previous call in order to avoid
! redundant calculations
flag = .false.
do i=1,5
if (tbold(i) .ne. tb(i)) flag = .true.
tbold(i) = tb(i)
end do
if (.not. flag) then
wv = wvold
return
end if
! initialize brightness temperatures
t19v = tb(1)
t19h = tb(2)
t22v = tb(3)
t37v = tb(4)
t37h = tb(5)
! check for land, ice, and heavy precipitation
del = t22v-t19v
if (del .lt. 4.0) then
wv = BAD
wvold = wv
return
end if
! special check for sea ice
t1 = 260.0 - 2.0*del
t2 = 270.0 - (120.0/15.0)*del
t3 = 130 + (20./15.)*del
if (t19h .lt. t1 .and. t19h .lt. t2 .and. t19h .gt. t3) then
wv = BAD
wvold = wv
return
end if
! check for abnormally warm brightness temperatures
if (t22v .gt. 285.0 .or. &
t19h .gt. 285.0 .or. &
t37h .gt. 285.0) then
wv = BAD
wvold = wv
return
end if
! compute water vapor from first-stage regression algorithm
wv = 0.1670E+03 &
+ 0.4037E+01*log(295-t19h) &
- 0.5322E+02*log(295-t22v) &
+ 0.1296E+02*log(295-t37h)
! apply polynomial correction to eliminate biases at high
! and low end of range
wv2 = wv*wv
wv3 = wv*wv2
! wv = -0.2079E+01 + 0.1366E+01*wv+ &
! -0.1504E-01*wv2+0.1639E-03*wv3
wv = -2.079 + 1.366*wv-0.01504*wv2+0.0001639*wv3
wvold = wv
end subroutine PettyVapor
!**********************************************************************
! This subroutine accepts SSM/I brightness temperatures and returns
! surface wind speed in m/sec. The algorithm is described
! in the document accompanying this FORTRAN module.
!
! Inputs: t19v,t19h,t22v,t37v,t37h
! --- SSM/I brightness temperatures (K)
! theta -- sensor viewing angle
! sst -- sea surface temperature (deg. C)
! dsst -- uncertainty in the above SST (deg. C)
! (if dsst > 2.8 C, then an algorithm is
! used that doesn't require SST)
!
! Output: u ---- column water vapor (mm)
!
!
subroutine PettyWind(tb,theta,sst,dsst,u) 3,2
implicit none
real tb(5),theta,sst,dsst,u
logical flag
real t19v,t19h,t22v,t37v,t37h
real, parameter :: BAD = -1000.0
real wv, alw37,errwv,p37clr,errlw,erru,p37,wv2,wv3
integer iaold,i,ia
real tbold(5),uold
save tbold,uold,iaold
! choose wind algorithm to use, depending on how well SST is
! known
if (abs(dsst).gt.2.8.or.sst.lt.-4.0.or.sst.gt.35.0) then
ia = 2
else
ia = 1
end if
! check for same TBs used in previous call in order to avoid
! redundant calculations
flag = .false.
if (ia .ne. iaold) flag = .true.
iaold = ia
do i=1,5
if (tbold(i) .ne. tb(i)) flag = .true.
tbold(i) = tb(i)
end do
if (.not. flag) then
u = uold
return
end if
! initialize brightness temperatures
t19v = tb(1)
t19h = tb(2)
t22v = tb(3)
t37v = tb(4)
t37h = tb(5)
! get estimate of column water vapor for use in
! cross talk corrections
call PettyVapor
(tb,wv)
! check for exceptionally high or bad water vapor values
if (wv .gt. 68.0 .or. wv .lt. 0.0) then
u = BAD
uold = u
return
end if
call ualg
(ia,theta,sst,tb,u)
! calculate 37 GHz liquid water using simple algorithm
p37clr = 77.68 -.1782*wv -1.1546*u + &
0.001838*wv*u -.003160*wv*wv + 0.01127*u*u
p37 = (t37v-t37h)/p37clr
alw37 = -(1.0/0.8614)*log(p37)
! check for cloud water exceeding threshold
if (alw37 .gt. 0.5) then
u = BAD
uold = u
return
end if
! select appropriate corrections
if (ia .eq. 1) then
! water vapor cross-talk correction
wv2 = wv*wv
wv3 = wv*wv2
errwv = -0.7173 + 0.1160*wv -0.4238E-02*wv2 + 0.4372E-04*wv3
u = u - errwv
! cloud liquid water cross-talk correction
if (alw37 .lt.0.08) then
errlw = -6.3889*alw37 + 0.36111
else
errlw = 0.83333*alw37 - 0.21667
end if
u = u - errlw
! check for unphysical values
if (u .lt. -2.0) then
u = BAD
uold = u
return
end if
! apply correction for non-linearity
if (u .lt. 2.5) then
erru = -1.267 + 0.7142*u -0.8395E-01*u*u
else if (u .gt. 10.0 ) then
erru = 3.243 -0.3478*u + 0.3679E-02*u*u
else
erru = 0.0
end if
u = u - erru
else if (ia .eq. 2) then
! water vapor cross-talk correction
wv2 = wv*wv
wv3 = wv*wv2
errwv = 0.2945 + 0.01270*wv -0.001654*wv2+ 0.2596E-04*wv3
u = u - errwv
! cloud liquid water cross-talk correction
if (alw37 .lt.0.0) then
errlw = 4.0*alw37 + 0.4
else if (alw37 .ge. 0.0 .and. alw37 .lt. 0.08) then
errlw = -8.125*alw37 + 0.4
else
errlw = -0.25
end if
u = u - errlw
! check for unphysical values
if (u .lt. -2.0) then
u = BAD
uold = u
return
end if
! apply correction for non-linearity
if (u .lt. 2.5) then
erru = -1.219+ 0.9327*u -0.1852*u*u
else if (u .gt. 10.0 ) then
erru = 3.360-0.3918*u + 0.8121E-02*u*u
else
erru = 0.0
end if
u = u - erru
end if
uold = u
end subroutine PettyWind
subroutine ualg(ia,theta,sst,tb,u) 1
!***********************************************************
! This subroutine implements the actual first stage wind speed algorithm.
! When IA=1, an algorithm is employed that makes use of SST.
! When IA=2, the SST information is not used.
implicit none
integer ia,i
real theta,sst,tb(5),u
real coeff1(8)
real coeff2(8)
data coeff1/ 0.1862E+03,0.9951E-01,0.0, &
-0.1829E-01, -0.1438E+01,0.7029, &
0.2329E+01,0.1687/
data coeff2/0.1719E+03,0.2827, 0.0, -0.2549E-01, &
-0.1473E+01, 0.6425, 0.2045E+01, 0.0/
! if theta is out of range, then substitute default value
if (theta .lt. 50.0 .or. theta .gt. 55.0) theta = 53.1
if (ia .eq. 1) then
u = coeff1(1)
do i=1,5
u = u + coeff1(i+1)*tb(i)
end do
u = u + coeff1(7)*(theta-53.0)
u = u + coeff1(8)*sst
else if (ia .eq. 2) then
u = coeff2(1)
do i=1,5
u = u + coeff2(i+1)*tb(i)
end do
u = u + coeff2(7)*(theta-53.0)
else
write (0,*) "Invalid algorithm ID"
end if
end subroutine ualg