subroutine setuppcp(jiter,deltat,sigl,sigi,& 1,7 deltim,dtphys,jcap,& nsig,lat1,lon1,& npcp1,npcpdat_s,& lunin,lunout,varprdp,npredp,predxp,& mype,nsat,& nlath,nlon,rlats,rlons,rbs2,ggrid_g31,ggrid_g32,rdivs,& rcwm,rtlat,rtlon,rqlat,rqlon,& sfct,isli,sno,diag_pcp,idiag_pcp,mype_pcp,iout_pcp,& obstype_all,npes,& xkt2d,jppfp,jtype) !$$$ subprogram documentation block ! . . . . ! subprogram: setuppcp compute rhs of oi equation for radiances ! prgmmr: derber org: w/nmc23 date: 95-07-06 ! ! abstract: read in data, first guess, and obtain rhs of oi equation ! for radiances. ! ! program history log: ! 95-07-06 derber ! 96-11 wu data from prepbufr file ! 96-12- mcnally -changes for diagnostic file and bugfix ! 98-04-30 weiyu yang mpi version ! 99-08-24 derber, j., treadon, r., yang, w., first frozen mpp version ! ! input argument list: ! jiter - outer iteration counter ! deltat - time interval of first guess fields ! sigl - sigma values at mid-point of each sigma layer ! sigi - sigma values at interfaces of sigma layers ! nsig - number of sigma levels ! lat1 - number of gaussian lats in the sub-domain array ! lon1 - number of gaussian longitudes in the sub-domain array ! nn_pcp - length of satellites data ! npcp1 - number of satellite observations for every satellites ! in each pe subdomain ! npcpdat_s - total number of observations for all satellites ! npredp - number of predictors ! mype - pe number ! npcp - number of satellites ! dtskin - skin temperature increment in each subdomain ! nlath - number of gaussian lats in one hemisphere ! nlon - number of longitudes ! rlats - grid latitudes (radians) ! rlons - grid longitudes (radians) ! rz_ges - guess mountains on grid ! rp_ges - guess log(sfcp) on grid ! ru_ges - guess u on grid ! rv_ges - guess v on grid ! rt_ges - guess t on grid ! rq_ges - guess specific humidity on grid ! roz_ges - guess ozone on grid in each pe subdomain ! sfct - guess skin temperature ! isli - snow-land-ice mask ! sno - snow-ice mask ! ! output argument list: ! varprdp - variance for predictor coefficients ! ! attributes: ! language: f90 ! machine: ibm RS/6000 SP ! !$$$ ! ! Include data type module use type_kinds, only: fp_kind,single ! Turn off implicit typing implicit none ! Other include files include 'mpi_inc.h' include 'constant.h' include 'ijstart.h' ! Declare and set parameters integer iint,ireal,ncld parameter (ncld=1) parameter (iint=8, ireal=23) ! ! Declare variables logical idiag_pcp,sea logical ssmi,amsua,tmi logical,dimension(jppfp):: land,coast,ice character(12) diag_pcp character(10),dimension(50)::sattype character(10) obstype character(10),dimension(55)::obstype_all integer ii,i,j,k,m,n,nlath2,nsdata,is,nele,nobs1,nobs2,nobs integer isat,isz,lunin,lunout,k1,ns2,nsig1,ipt,jppfp,jtype integer lat1,lon1,nlath,nlon,nsig,jcap,nsphys,ix,im integer mype,j11,j22,j12,j21,iy,iy1,ix1,ixp,iyp,npes integer npredp,nblk,nblktot,iland integer iout_pcp,mype_pcp,km,mype1 integer isum,icoast,icerr,kx integer isnoice,itotal,ireduce,jiter integer n1,npcpdat_s,nsat,kdt,iratio integer ncloud,igradsml,igradbig integer inumw,inum,iclip,ikeep,itoss integer,dimension(55):: npcp1,npcp1d integer,dimension(lat1+2,lon1+2):: isli integer,dimension(iint,jppfp):: idiagbuf integer,dimension(jppfp,4):: iloc,jloc,ijloc integer,dimension(jppfp):: kbcon,jmin,ktcon,kuo,istype,& lndsea,ksatid,isflg integer,dimension(nsat):: kidsat,kidsat1 integer,dimension(jtype):: nupcp,itypep,iusep,ibias,ifutr real(fp_kind) avg,sdv,rterm1,rterm2,rterm,zero,one,oneneg real(fp_kind) pcpobs0,pcpnbc0,pcpbc0,pcpobs1,pcpnbc1,pcpbc1,error,a0,a1,simerr real(fp_kind) pcpsas0,pcpsas1,errlog,rsum real(fp_kind) rdocp,frain,dtp,dtf,dtphys,deltat,deltim,sum,rad2dg,halfpi real(fp_kind) wgt00,wgt01,wgt10,wgt11,drad,vfact,efact,fhour,rtime real(fp_kind) penalty_all,dx,dx1,dy,dy1,varrad,xlo,xhi real(fp_kind) obserr_wgt,simerr_wgt,wgtij real(fp_kind) rmiss,pterm,tf1,tf2,tf3,tfo real(fp_kind) rmmhr,term real(single),dimension(ireal,jppfp):: diagbuf real(fp_kind),dimension(jtype):: varchp,vfutr real(fp_kind),dimension(2*nlath):: rlats,rbs2 real(fp_kind),dimension(nlon):: rlons real(fp_kind),dimension(jtype*npredp):: varprdp real(fp_kind),dimension(nsig):: sigl,del,slk real(fp_kind),dimension(nsig+1):: sigi real(fp_kind),dimension(npredp,jppfp):: pred real(fp_kind),dimension(jppfp):: plon0,plat0,rmask0,xkt2,psexp0,& rbs0,ts0,cldwrk,rn1,pcpsas,rn4,pcpsas4,pcplrg4,pcpnbc,pcpbc,pcplrg,& ad_rn1,var,obs,ges,varinv,errf,obserr,slats,slons,stfact,cenlat,& satpcp,satclw,satcnv,satcli,pcpnum,pcpsdv real(fp_kind),dimension(jppfp,4):: wgtloc real(fp_kind),dimension(nsig):: dpcpdt,dpcpdq,dpcpdu,dpcpdv,dpcpddiv,dpcpdcwm real(fp_kind),dimension(2):: dpcpmag real(fp_kind),dimension(jtype,npredp):: predxp real(fp_kind),dimension(36,nsat):: aivals,aivals1 real(fp_kind),dimension(nsat):: rpen,cpen real(fp_kind),dimension(lat1+2,lon1+2):: sfct,sno,xkt2d real(fp_kind),dimension(3,lat1+2,lon1+2,npes):: ggrid_g31 real(fp_kind),dimension(3,lat1+2,lon1+2,npes,2):: ggrid_g32 real(fp_kind),dimension(lat1+2,lon1+2,nsig,3):: rtlat,rtlon,rqlat,rqlon,rcwm,rdivs real(fp_kind),allocatable,dimension(:):: weight_p real(fp_kind),allocatable,dimension(:,:):: data_p,tlat0,tlon0,qlat0,qlon0,& t0,q0,cwm0,u0,v0,div0,t1,q1,cwm1,u1,v1,ad_t0,ad_q0,ad_cwm0,& ad_u0,ad_v0,ad_div0,ad_t1,ad_q1,ad_cwm1,ad_u1,ad_v1,ad_t4,& ad_q4,ad_cwm4,ad_u4,ad_v4,ad_div4,tsas,qsas,tlrg,qlrg data rmiss / -999. / ! ! ! !********************************************************************************* ! ONE TIME, INITIAL SETUP PRIOR TO PROCESSING SATELLITE DATA ! Allocate arrays allocate(tsas(nsig,jppfp),qsas(nsig,jppfp),tlrg(nsig,jppfp),qlrg(nsig,jppfp)) allocate(t0(nsig,jppfp),q0(nsig,jppfp),cwm0(nsig,jppfp),u0(nsig,jppfp),& v0(nsig,jppfp),div0(nsig,jppfp),t1(nsig,jppfp),q1(nsig,jppfp),& cwm1(nsig,jppfp),u1(nsig,jppfp),v1(nsig,jppfp),tlat0(nsig,jppfp),& tlon0(nsig,jppfp),qlat0(nsig,jppfp),qlon0(nsig,jppfp)) allocate(ad_t0(nsig,jppfp),ad_q0(nsig,jppfp),ad_cwm0(nsig,jppfp),& ad_u0(nsig,jppfp),ad_v0(nsig,jppfp),ad_div0(nsig,jppfp),& ad_t1(nsig,jppfp),ad_q1(nsig,jppfp),ad_cwm1(nsig,jppfp),& ad_u1(nsig,jppfp),ad_v1(nsig,jppfp),ad_t4(nsig,jppfp),& ad_q4(nsig,jppfp),ad_cwm4(nsig,jppfp),ad_u4(nsig,jppfp),& ad_v4(nsig,jppfp),ad_div4(nsig,jppfp)) ! ! Initialize variables ncloud = ncld nsphys = max(int(2*deltim/dtphys+0.9999),1) dtp = 2*deltim/nsphys dtf = 0.5*dtp frain = dtf/dtp kdt = 1 fhour = kdt*deltim/3600. rtime = 1./(3600.*fhour) rmmhr = 1.e3*rtime * 3600. nlath2=2*nlath mype1=mype+1 nsig1=nsig+1; ns2=2*nsig+2 zero=0.0 one=1.0 oneneg=-1.0 call pcpinfo(mype,jtype,nupcp,itypep,iusep,ibias,ifutr,varchp,vfutr) if (jiter==1 .and. mype==mype_pcp) then write(iout_pcp,*)'deltim,dtphys =',deltim,dtphys write(iout_pcp,*)'nsphys,dtp,dtf=',nsphys,dtp,dtf write(iout_pcp,*)'frain,fhour =',frain,fhour write(iout_pcp,*)'rtime,rmmhr =',rtime,rmmhr write(iout_pcp,*)'kdt =',kdt do j=1,jtype write(iout_pcp,1005) nupcp(j),itypep(j),iusep(j),ibias(j),varchp(j) end do 1000 format(1X,5I5,2E18.10) 1005 format(' ipcp = ',i4, ' itypep= ',i4, & ' iusep = ',i4, ' ibias = ',i4, & ' var = ',e10.4) endif ! ! ! Open units. Set pointers. rewind(lunin) kidsat=0 if (jiter==1 .and. idiag_pcp) then open(4,file=diag_pcp,form='unformatted') rewind 4 endif ! ! Initialize/write parameters for satellite diagnostic file on ! first outer iteration. if (jiter==1 .and. idiag_pcp) then if(mype==0) then write(4) mype,iint,ireal write(6,*)'SETUPPCP: write header record for mype=',& mype,iint,ireal,' ',diag_pcp endif endif ! ! ! Initialize variables. rdocp = rd/cp ! ! ! Set other constants. rad2dg = 45./atan(1.0) halfpi = 0.5*acos(-1.) ! ! ! Set bias correction standard deviations varprdp = 1./sqrt(.1) aivals = 0.0; aivals1=0.0 npcp1d = 0; n1=0 ! ! !**************************************************************************** ! MAIN LOOP OVER OBSERVATION PLATFORMS ! !***** ! INITIALIZE VARIABLE AND DATA ARRAYS !***** do is = 1,nsat+5 n1 = 0 obstype=' '; isat=0; nele=0; nobs=0 isz=is-5 if (is > 5)sattype(isz)=obstype_all(is) if (npcp1(is) == 0) goto 135 read(lunin,end=135) obstype,isat,nele,nobs ! Initialize logical flags for satellite platform ssmi = obstype == 'pcp_ssm/i' tmi = obstype == 'pcp_tmi' amsua = obstype == 'pcp_amsua' if (.not. (ssmi .or. tmi .or. amsua) ) then read(lunin) goto 135 endif if (obstype /= obstype_all(is) .or. is <=5) then write(6,*)' error in setuppcp ',is,obstype,obstype_all(is) call stop2(93) end if ! Save isat. Initialize arrays kidsat(isz) = isat idiagbuf= 0 diagbuf = 0. ! ! Load data array for current satellite allocate(data_p(nele,npcp1(is))) allocate(weight_p(npcp1(is))) read(lunin) data_p,weight_p ! !***** ! PROCESS DATA IN BLOCKS OF JPPFP nblktot=(npcp1(is)-1)/jppfp+1 do nblk = 1,nblktot ! ! Determine block of data to use nobs1 = 1 + (nblk-1)*jppfp nobs2 = min(nobs1+jppfp-1,npcp1(is)) if (nobs2-nobs1+1 <= 0) then write(6,*)'setuppcp: nblk not consistent with nblktot ',nblk,nblktot goto 134 end if ! ! Initialize variables/arrays. varinv = 0. errf = 0. satpcp = 0. satcnv = 0. satclw = 0. satcli = 0. rn1 = 0. pcpsas = 0. pcplrg = 0. lndsea = 0 stfact = 0. idiagbuf= 0 diagbuf = 0. slats = 0. slons = 0. cenlat = 0. ts0 = 0. ! INITIAL PROCESSING OF SATELLITE DATA !***** ! ! Process data nsdata=0 do n=nobs1,nobs2 nsdata = nsdata+1 if (nsdata>jppfp .or. nsdata>npcp1(is)) & write(6,*)'setuppcp: ***error*** nsdata,jppfp,npcp1(is)=',& nsdata,jppfp,npcp1(is),is,n,nobs1,nobs2,' ',obstype,' ',& kidsat(isz) ! Reuse beginning of weight_p array weight_p(nsdata) = weight_p(n) aivals(1,isz) = aivals(1,isz) + weight_p(nsdata) ! Extract satellite id ksatid(nsdata) = nint(data_p(1,n)) kx = -999 do i = 1,jtype if (ksatid(nsdata).eq.nupcp(i)) kx = i end do if (kx<0) write(6,*) & '***WARNING*** Problem with satellite id. ksatid,kx=',& ksatid(nsdata),kx istype(nsdata) = kx ! ! Set observation error errf(nsdata) = varchp(kx) varinv(nsdata) = 1./(varchp(kx)**2) ! Extract land/sea/ice flag (0=sea, 1=land, 2=ice) lndsea(nsdata) = nint(data_p(5,n)) sea = lndsea(nsdata) == 0 ! ! Extract obs lon and lat. slons(nsdata) = data_p(4,n) slats(nsdata) = data_p(3,n) cenlat(nsdata) = slats(nsdata)*rad2dg ! ! Extract obs date/time. stfact(nsdata) = data_p(2,n)/3. ! ! Extract observations if (ssmi) then satpcp(nsdata) = data_p(6,n) pcpsdv(nsdata) = data_p(7,n) pcpnum(nsdata) = data_p(8,n) satcnv(nsdata) = rmiss satclw(nsdata) = rmiss satcli(nsdata) = rmiss elseif (amsua) then ! nothing elseif (tmi) then satpcp(nsdata) = data_p(6,n) satcnv(nsdata) = data_p(7,n) satclw(nsdata) = data_p(8,n) satcli(nsdata) = data_p(9,n) pcpnum(nsdata) = data_p(10,n) pcpsdv(nsdata) = rmiss endif ! ! Adjust obs error based on precipitation rate. ! ! Bill Olson TMI error model. if (ksatid(nsdata)==211) then if (sea) then a0=0.137; a1=0.118 !tmi,sea else a0=0.335; a1=0.045 !tmi, land endif ! Bob Kuligowski SSMI error model elseif (ksatid(nsdata)==264) then if (sea) then a0=0.3835; a1=0.1699 !ssmi, sea (n=50 bin) (scattering) else a0=0.3148; a1=0.1781 !ssmi, land (n=50 bin) endif else a0=0.0; a1=0.0 endif term = log(1.+satpcp(nsdata)) errlog = a0 + a1*term obserr(nsdata) = errlog error = varchp(kx) + obserr(nsdata) errf(nsdata) = error varinv(nsdata) = 1./(error*error) ! ! If negative precipitation, reset to 0.0 if (satpcp(nsdata) < 0.) satpcp(nsdata)=0.0 ! ! Save data in diagnostic arrays. idiagbuf(1,nsdata) = ksatid(nsdata) idiagbuf(2,nsdata) = lndsea(nsdata) diagbuf(1,nsdata) = slats(nsdata)*rad2dg diagbuf(2,nsdata) = slons(nsdata)*rad2dg diagbuf(3,nsdata) = stfact(nsdata) diagbuf(4,nsdata) = pcpnum(nsdata) diagbuf(5,nsdata) = satpcp(nsdata) diagbuf(6,nsdata) = pcpsdv(nsdata) diagbuf(7,nsdata) = satcnv(nsdata) diagbuf(8,nsdata) = satclw(nsdata) diagbuf(9,nsdata) = satcli(nsdata) diagbuf(10,nsdata) = varinv(nsdata) diagbuf(11,nsdata) = errf(nsdata) ! End of loop over obs. end do aivals(2,isz) = aivals(2,isz) + nsdata ! ! ! ! !***** ! IDENTIFY OBSERVATIONS TO PROCESS !***** ! ! ! Get skin temperature at observation location. call gdcrdp(slats,nsdata,rlats,nlath2) call gdcrdp(slons,nsdata,rlons,nlon) call intrp2(nlath2,sfct,ts0,slats,slons,lat1,lon1,nlon,nsdata,mype) ! ! Do some prelimiary qc of the data. Check for points covered ! with ice/snow, land points, and coastal points. ! do n = 1,nsdata isflg(n)=0 icoast =0 land(n) =.false. coast(n)=.false. ice(n) =.false. ! ! Check for ocean temperatures less the freezing (sea ice) ! or probable snow over land isflg(n)=0 if ( (ts0(n) < 272.16) .and. (abs(cenlat(n)) >= 40.) ) isflg(n)=1 ! ! Determine local (i,j) indices of analysis gridpoints surrounding ! the observation. Also determine bilinear interpolation weights ! from analysis gridpoints to observation location. ! respect to the surrounding analysis grid box. iy1 = slats(n) ix1 = slons(n) dx = slons(n)-ix1 dy = slats(n)-iy1 iy1=min(max(1,iy1),nlath2); ix1=min(max(0,ix1),nlon) dx1 = 1.0-dx dy1 = 1.0-dy iy1 = max(1,min(iy1,nlath2)) iy = iy1-istart(mype1)+2 ix = ix1-jstart(mype1)+2 if (ix<1) then ix1 = ix1+nlon ix = ix1-jstart(mype1)+2 end if if (ix>lon1+1) then ix1 = ix1-nlon ix = ix1-jstart(mype1)+2 end if ixp = ix+1 iyp = iy+1 if (iy1==nlath2) iyp=iy wgt00=dx1*dy1; wgt10=dx1*dy; wgt01=dx*dy1; wgt11=dx*dy j11=iy+(ix-1)*(lat1+2); j12=j11+lat1+2; j21=j11+1; j22=j12+1 ! Save (i,j) indices and interpolation weights. iloc(n,1)=iy; iloc(n,2)=iy; iloc(n,3)=iyp; iloc(n,4)=iyp jloc(n,1)=ix; jloc(n,2)=ixp; jloc(n,3)=ix; jloc(n,4)=ixp wgtloc(n,1)=wgt00; wgtloc(n,2)=wgt10 wgtloc(n,3)=wgt01; wgtloc(n,4)=wgt11 ijloc(n,1)=j11; ijloc(n,2)=j21; ijloc(n,3)=j12; ijloc(n,4)=j22 ! Check for coastal observations. Coastal is defined with ! respect to the surrounding analysis grid box. if (lndsea(n) /= 1)then if (isli(iy,ix) .eq. 1 .or. isli(iy,ixp) .eq. 1 .or.& isli(iyp,ix) .eq. 1 .or. isli(iyp,ixp) .eq. 1)& lndsea(n) = 1 end if ! ! Check for snow of sea ice in surrounding grid box if(isflg(n) /= 1)then if((sno(iy,ix) > 1. .and. isli(iy,ix) /= 0) .or.& isli(iy,ix) .eq. 2 ) isflg(n)=1 if((sno(iy,ixp) > 1. .and. isli(iy,ixp) /= 0) .or.& isli(iy,ixp) .eq. 2 ) isflg(n)=1 if((sno(iyp,ix) > 1. .and. isli(iyp,ix) /= 0) .or.& isli(iyp,ix) .eq. 2 ) isflg(n)=1 if((sno(iyp,ixp) > 1. .and. isli(iyp,ixp) /= 0) .or.& isli(iyp,ixp) .eq. 2 ) isflg(n)=1 end if ! ! Check for coastal (transition) points if (isli(iy,ix) /= isli(iy,ixp) .or.& isli(iy,ix) /= isli(iyp,ix) .or.& isli(iy,ix) /= isli(iyp,ixp)) coast(n) = .true. ! Set logical flags land(n) = lndsea(n) == 1 ice(n) = isflg(n) == 1 if (coast(n)) icoast = 1 ! Save data in diagnostic arrays idiagbuf(3,n)= lndsea(n) idiagbuf(4,n)= isflg(n) idiagbuf(5,n)= icoast ! ! End loop over obs end do ! ! ! !***** ! CALL Precipitation (FORWARD) MODEL !***** ! ! ! Call precipitation model. Set ajm forcing ! for precipitation rate to unity. ! Initialize variables and arrays im = nsdata ix = jppfp km = nsig do k = 1,nsig del(k) = sigi(k) - sigi(k+1) slk(k) = sigl(k)**rdocp end do do i = 1,jppfp do k = 1,nsig ad_t0(k,i) = 0.0 ad_q0(k,i) = 0.0 ad_u0(k,i) = 0.0 ad_v0(k,i) = 0.0 ad_div0(k,i) = 0.0 ad_cwm0(k,i) = 0.0 end do rn1(i) = 0.0 pcpsas(i) = 0.0 pcplrg(i) = 0.0 end do ! Loop over four surrounding analysis gridpoints do ipt=1,4 ! Loop over observation points. do n=1,nsdata ! Set (i,j) index for ipt-th point for observation n. i=iloc(n,ipt); j=jloc(n,ipt) ! Load arrays used by forward/adjoint model xkt2(n) = xkt2d(i,j) ii = slats(n)+0.5 rbs0(n) = rbs2(ii) rmask0(n) = isli(i,j) ! Set weights for linear time interpolation. if (deltat>0.0) then tfo=stfact(n) tf1=-min(max(oneneg,tfo),zero) tf2=min(max(zero,1.0-abs(tfo)),one) tf3=min(max(zero,tfo),one) else tf1=0.0; tf2=1.0; tf3=0.0 end if ! Perform interpolation. pterm = tf2*ggrid_g31(3,i,j,nsig1) + tf1*ggrid_g32(3,i,j,nsig1,1) + & tf3*ggrid_g32(3,i,j,nsig1,2) !ibm* prefetch_for_store(psexp0(n),plon0(n),plat0(n)) psexp0(n) = exp(pterm) plon0(n) = tf2*ggrid_g31(2,i,j,ns2) + tf1*ggrid_g32(2,i,j,ns2,1) + & tf3*ggrid_g32(2,i,j,ns2,2) plat0(n) = tf2*ggrid_g31(1,i,j,ns2) + tf1*ggrid_g32(1,i,j,ns2,1) + & tf3*ggrid_g32(1,i,j,ns2,2) !ibm* prefetch_for_store(k1) k1=nsig1 do k=1,nsig k1=k1+1 !ibm* prefetch_for_store(t0(k,n),q0(k,n)) t0(k,n) = tf2*ggrid_g31(3,i,j,k1) + tf1*ggrid_g32(3,i,j,k1,1) + & tf3*ggrid_g32(3,i,j,k1,2) q0(k,n) = tf2*ggrid_g31(1,i,j,k1) + tf1*ggrid_g32(1,i,j,k1,1) + & tf3*ggrid_g32(1,i,j,k1,2) end do do k=1,nsig !ibm* prefetch_for_store(u0(k,n),v0(k,n),div0(k,n),cwm0(k,n),tlon0(k,n),tlat0(k,n)) u0(k,n) = tf2*ggrid_g31(1,i,j,k) + tf1*ggrid_g32(1,i,j,k,1) + & tf3*ggrid_g32(1,i,j,k,2) v0(k,n) = tf2*ggrid_g31(2,i,j,k) + tf1*ggrid_g32(2,i,j,k,1) + & tf3*ggrid_g32(2,i,j,k,2) div0(k,n) = tf2*rdivs(i,j,k,1) + tf1*rdivs(i,j,k,2) + & tf3*rdivs(i,j,k,3) cwm0(k,n) = tf2*rcwm(i,j,k,1) + tf1*rcwm(i,j,k,2) + & tf3*rcwm(i,j,k,3) tlat0(k,n) = tf2*rtlat(i,j,k,1) + tf1*rtlat(i,j,k,2) + & tf3*rtlat(i,j,k,3) tlon0(k,n) = tf2*rtlon(i,j,k,1) + tf1*rtlon(i,j,k,2) + & tf3*rtlon(i,j,k,3) qlat0(k,n) = tf2*rqlat(i,j,k,1) + tf1*rqlat(i,j,k,2) + & tf3*rqlat(i,j,k,3) qlon0(k,n) = tf2*rqlon(i,j,k,1) + tf1*rqlon(i,j,k,2) + & tf3*rqlon(i,j,k,3) end do end do ! Initialize arrays below prior to each call to forward/adjoint model do i = 1,jppfp do k = 1,nsig ad_t4(k,i) = 0.0 ad_q4(k,i) = 0.0 ad_u4(k,i) = 0.0 ad_v4(k,i) = 0.0 ad_div4(k,i) = 0.0 ad_cwm4(k,i) = 0.0 ad_t1(k,i) = 0.0 ad_q1(k,i) = 0.0 ad_u1(k,i) = 0.0 ad_v1(k,i) = 0.0 ad_cwm1(k,i) = 0.0 t1(k,i) = 0.0 q1(k,i) = 0.0 u1(k,i) = 0.0 v1(k,i) = 0.0 cwm1(k,i) = 0.0 end do rn4(i) = 0.0 ad_rn1(i) = 1.0 pcpsas4(i) = 0.0 pcplrg4(i) = 0.0 end do ! Call forward/adjoint model call ajmpcp(im,ix,km,jcap,dtp,del,sigl,slk,rbs0, & rmask0,nlon,xkt2,ncloud,frain,rmmhr,& psexp0,plat0,plon0,& t0,q0,u0,v0,div0,cwm0,tlat0,tlon0,qlat0,qlon0,& tsas,qsas,pcpsas4,cldwrk,kbcon,ktcon,jmin,kuo, & tlrg,qlrg,pcplrg4, & t1,q1,cwm1,u1,v1,rn4,& ad_t4,ad_q4,ad_cwm4,ad_u4,ad_v4,ad_div4,& ad_t1,ad_q1,ad_cwm1,ad_u1,ad_v1,ad_rn1,mype) ! Based on bilinear interpolation weights, accumulate rain rates ! and sensitivity over four surrounding analysis gridpoints. do n=1,nsdata wgtij=wgtloc(n,ipt) pcpsas(n) = pcpsas(n) + wgtij*pcpsas4(n) pcplrg(n) = pcplrg(n) + wgtij*pcplrg4(n) rn1(n) = rn1(n) + wgtij*rn4(n) do k=1,nsig ad_t0(k,n) = ad_t0(k,n) + wgtij*ad_t4(k,n) ad_q0(k,n) = ad_q0(k,n) + wgtij*ad_q4(k,n) ad_cwm0(k,n) = ad_cwm0(k,n) + wgtij*ad_cwm4(k,n) ad_u0(k,n) = ad_u0(k,n) + wgtij*ad_u4(k,n) ad_v0(k,n) = ad_v0(k,n) + wgtij*ad_v4(k,n) ad_div0(k,n) = ad_div0(k,n) + wgtij*ad_div4(k,n) end do end do ! End of loop over analysis gridpoints end do ! Load model simulated rain rates into work array. ! NOTE: simulated values converted to units of mm/hr ! in ajmpcp. obs already in mm/hr do n = 1,nsdata pcpnbc(n) = rn1(n) end do !!test ! Adjust error based on estimated forward model error. do n=1,nsdata if (ksatid(n)==211) then if (land(n)) then a0=0.1244544; a1=0.3883144 !tmi, land else a0=0.1764123; a1=0.3948465 !tmi, sea endif elseif (ksatid(n)==264) then if (land(n)) then a0=0.1282869; a1=0.4108055 !ssmi, land else a0=0.0917045; a1=0.4757942 !ssmi, sea endif else a0=0.0; a1=0.0 endif term = log(1.+pcpnbc(n)) simerr = a0 + a1*term simerr = max(zero,simerr) obserr_wgt = varchp(istype(n)) simerr_wgt = 1.-obserr_wgt error = max(obserr(n),obserr_wgt*obserr(n) + simerr_wgt*simerr) errf(n) = error varinv(n)=1./(error*error) end do !!test ! Save cloud base, downdraft origin, cloud top, cloud work function ! for diagnostics do n = 1,nsdata idiagbuf(6,n) = kbcon(n) idiagbuf(7,n) = ktcon(n) idiagbuf(8,n) = jmin(n) diagbuf(12,n) = rmiss diagbuf(13,n) = rmiss diagbuf(14,n) = rmiss if (kbcon(n)>=1 .and. kbcon(n)<=nsig) diagbuf(12,n) = 10.*psexp0(n) * sigl(kbcon(n)) if (ktcon(n)>=1 .and. ktcon(n)<=nsig) diagbuf(13,n) = 10.*psexp0(n) * sigl(ktcon(n)) if (jmin(n)>=1 .and. jmin(n)<=nsig) diagbuf(14,n) = 10.*psexp0(n) * sigl(jmin(n)) diagbuf(15,n) = cldwrk(n) diagbuf(23,n) = xkt2(n) end do ! If magnitude of sensitivity vector is zero, set inverse observation ! error to zero since we don't have gradient information for this ! observation. For now, ommit divergence sensitivity since it is ! not used in pcgsoi. Likewise, if the gradient is too large, do not ! use this observation (this check rarely catches any points). rterm1=1./float(nsig) rterm2=1./float(nsig*(nsig-1)) do n = 1,nsdata dpcpmag=0.0 do k=1,nsig dpcpmag(1) = dpcpmag(1) + ad_t0(k,n) dpcpmag(1) = dpcpmag(1) + ad_q0(k,n) dpcpmag(1) = dpcpmag(1) + ad_u0(k,n) dpcpmag(1) = dpcpmag(1) + ad_v0(k,n) dpcpmag(1) = dpcpmag(1) + ad_cwm0(k,n) dpcpmag(2) = dpcpmag(2) + ad_t0(k,n)*ad_t0(k,n) dpcpmag(2) = dpcpmag(2) + ad_q0(k,n)*ad_q0(k,n) dpcpmag(2) = dpcpmag(2) + ad_u0(k,n)*ad_u0(k,n) dpcpmag(2) = dpcpmag(2) + ad_v0(k,n)*ad_v0(k,n) dpcpmag(2) = dpcpmag(2) + ad_cwm0(k,n)*ad_cwm0(k,n) end do avg = dpcpmag(1)*rterm1 term= (nsig*dpcpmag(2)-dpcpmag(1)**2)*rterm2 sdv = 0.0 if (term>0) sdv=sqrt(term) dpcpmag(2)=sqrt(dpcpmag(2)) if (dpcpmag(2)<1.e-10) then aivals(26,isz) = aivals(26,isz) + weight_p(n) varinv(n)=0.0 endif if (dpcpmag(2)>1.e4) then aivals(27,isz) = aivals(27,isz) + weight_p(n) varinv(n)=0.0 elseif (abs(avg)>0.) then if (abs(sdv/avg)>25.) then aivals(28,isz) = aivals(28,isz) + weight_p(n) varinv(n) = 0.0 endif endif if (varinv(n)>1.e-6) aivals(3,isz) = aivals(3,isz) + weight_p(n) end do ! ! ! ! ! !***** ! COMPUTE AND APPLY BIAS CORRECTION TO SIMULATED VALUES !***** ! ! Prepare for application of bias correction to simulated values. pred=0.0 ! ! Construct predictors for bias correction. do n = 1,nsdata diagbuf(16,n) = pcpsas(n) diagbuf(17,n) = pcpnbc(n) pred(1,n) = 0.0 pred(2,n) = 0.0 pred(3,n) = 0.0 pred(4,n) = 0.0 pred(5,n) = 0.0 pred(6,n) = 0.0 end do ! ! ! Apply bias correction to simulated values. do n = 1,nsdata sum = 0.0 do j = 1,npredp sum = sum + predxp(istype(n),j)*pred(j,n)* & ibias(istype(n)) end do pcpbc(n) = pcpnbc(n) + sum diagbuf(18,n) = pcpbc(n) end do ! ! ! ! !*** ! QC OBSERVATIONS BASED ON VARIOUS CRITERIA !*** ! ! QC SSMI, TMI, and AMSUA precipitation. if (ssmi .or. tmi .or. amsua) then ! ! Loop over observations. do n = 1,nsdata efact = 1. vfact = 0.25 ! ! Reduce qc bounds in extratropics. Between 50 ! and 80 degrees latitude linearly reduce error ! bound. Poleward of 80 degrees latitude do not use if ( abs(cenlat(n)) > 50. ) then aivals(4,isz) = aivals(4,isz) + weight_p(n) term = (80.-abs(cenlat(n)))/30. term = max(zero,term) term = min(term,one) if (abs(cenlat(n)) > 80.) term=0.0 efact = term*efact endif ! ! If land obs, reduce error bounds and weight if (land(n)) then efact = 0.7*efact vfact = 0.7*vfact aivals(5,isz) = aivals(5,isz) + weight_p(n) end if ! ! Toss obs if over snow or ice if (ice(n)) then efact = 0.0 vfact = 0.0 aivals(6,isz) = aivals(6,isz) + weight_p(n) end if ! ! If coastal obs, reduce error bounds and weight if (coast(n)) then efact = 0.5*efact vfact = 0.5*vfact aivals(7,isz) = aivals(7,isz) + weight_p(n) end if ! ! Reduce weight and tighten obs-ges bound as function of obs time. term = cos(halfpi*stfact(n)) term = term**3 term = max(zero,min(term,one)) efact = term*efact vfact = term*vfact ! ! Generate q.c. bounds and modified variances. errf(n) = efact*errf(n) varinv(n) = vfact*varinv(n) diagbuf(19,n) = varinv(n) ! ! End of loop over observations. end do ! ! End of SSMI, TMI, and AMSUA qc block endif ! ! ! Apply gross check to good pcp obs. do n = 1,nsdata xlo = -3.*errf(n) xhi = +3.*errf(n) if (varinv(n) > 1.e-6) then drad = log(1.+satpcp(n)) - log(1.+pcpbc(n)) if (drad < xlo .or. drad > xhi) then varinv(n) = 0.0 aivals(12,isz) = aivals(12,isz) + weight_p(n) endif endif diagbuf(20,n) = varinv(n) diagbuf(21,n) = errf(n) end do ! ! !*** ! CONSTRUCT SENSITIVITY VECTORS !*** ! ! Initialize dpcp/dT, dq, du, dv, dd sensitivity vectors. do n = 1,nsdata var(n) = 0. obs(n) = 0. ges(n) = 0. end do do k = 1,nsig dpcpdt(k) = 0. dpcpdq(k) = 0. dpcpdu(k) = 0. dpcpdv(k) = 0. dpcpddiv(k) = 0. dpcpdcwm(k) = 0. end do ! Load information pcgsoi needs into output arrays. do n = 1,nsdata ! Load values for "good" obs. if (varinv(n) > 1.e-6) then var(n) = varinv(n) obs(n) = satpcp(n) ges(n) = pcpbc(n) ! Load sensitivity vector. do i = 1,nsig dpcpdt(i) = ad_t0(i,n) dpcpdq(i) = ad_q0(i,n) dpcpdu(i) = ad_u0(i,n) dpcpdv(i) = ad_v0(i,n) dpcpddiv(i)= ad_div0(i,n) dpcpdcwm(i)= ad_cwm0(i,n) end do end if ! ! Write diagnostics to output file. if (jiter==1 .and. idiag_pcp) then ! if (varinv(n)>1.e-6) then diagbuf(22,n) = weight_p(n) write(4) mype,(idiagbuf(m,n),m=1,iint),& (diagbuf(m,n),m=1,ireal) ! endif endif ! Optionally, set parameter to turn off data. if (iusep(istype(n))<1) then do i=1,nsig dpcpdt(i) = 0.0 dpcpdq(i) = 0.0 dpcpdu(i) = 0.0 dpcpdv(i) = 0.0 dpcpddiv(i)= 0.0 dpcpdcwm(i)= 0.0 end do var(n) = 0.0 obs(n) = 0.0 ges(n) = 0.0 endif ! Write data needed by pcgsoi to file if (varinv(n)>1.e-6) then n1 = n1+1 write(lunout) (ijloc(n,m),m=1,4),(wgtloc(n,m),m=1,4),weight_p(n) write(lunout) istype(n),var(n),(pred(m,n),m=1,npredp),& obs(n),ges(n),& (dpcpdt(m),m=1,nsig),(dpcpdq(m),m=1,nsig),& (dpcpdu(m),m=1,nsig),(dpcpdv(m),m=1,nsig),& (dpcpdcwm(m),m=1,nsig) ! For now, do not include divergence sensitivity ! (dpcpddiv(m,n),m=1,nsig) ! End of pcgsoi write block end if ! ! End of loop over profiles end do ! ! ! !****** ! DIAGNOSTIC CALCULATIONS. !****** ! ! ! Accumulate data for diagnostic print. do n = 1,nsdata if (varinv(n) > 1.e-6) then drad = log(1.+satpcp(n)) - log(1.+pcpbc(n)) varrad = drad*varinv(n) error = sqrt(1./varinv(n)) aivals(11,isz) = aivals(11,isz) + weight_p(n) aivals(13,isz) = aivals(13,isz) + drad*weight_p(n) !bias aivals(14,isz) = aivals(14,isz) + drad*drad*weight_p(n) !bias**2 aivals(15,isz) = aivals(15,isz) + drad*varrad*weight_p(n) !pen aivals(16,isz) = aivals(16,isz) + error*weight_p(n) !obs error aivals(21,isz) = aivals(21,isz) + satpcp(n)*weight_p(n) aivals(22,isz) = aivals(22,isz) + pcpnbc(n)*weight_p(n) aivals(23,isz) = aivals(23,isz) + pcpbc(n) *weight_p(n) aivals(24,isz) = aivals(24,isz) + pcpsas(n)*weight_p(n) aivals(25,isz) = aivals(25,isz) + weight_p(n) else aivals(31,isz) = aivals(31,isz) + satpcp(n)*weight_p(n) aivals(32,isz) = aivals(32,isz) + pcpnbc(n)*weight_p(n) aivals(33,isz) = aivals(33,isz) + pcpbc(n) *weight_p(n) aivals(34,isz) = aivals(34,isz) + pcpsas(n)*weight_p(n) aivals(35,isz) = aivals(35,isz) + weight_p(n) endif end do ! ! End of nblk loop end do ! ! ! Jump here when there is no more data to process for current satellite 134 continue deallocate(data_p) deallocate(weight_p) 135 continue npcp1d(is)=n1 ! ! !***** ! END MAIN LOOP OVER SATELLITES !***** end do npcpdat_s=0 do k=1,nsat+5 npcpdat_s=npcpdat_s+npcp1d(k) end do ! Close unit to diagnostic file. if (jiter==1 .and. idiag_pcp) close(4) ! ! Collect statistics call mpi_reduce(aivals,aivals1,36*nsat,mpi_rtype,mpi_sum,mype_pcp,mpi_comm_world,ierror) call mpi_reduce(kidsat,kidsat1, nsat,mpi_integer,mpi_max,mype_pcp,mpi_comm_world,ierror) ! Compute and print statistics for current satellite. if(mype==mype_pcp) then penalty_all=0.0 do is=1,nsat obstype=sattype(is) if(obstype .eq. 'pcp_ssm/i')ssmi=.true. if(obstype .eq. 'pcp_tmi')tmi=.true. if(obstype .eq. 'pcp_amsua')amsua=.true. inumw = nint(aivals1(1,is)) inum = nint(aivals1(2,is)) itotal = nint(aivals1(3,is)) ireduce = nint(aivals1(4,is)) iland = nint(aivals1(5,is)) isnoice = nint(aivals1(6,is)) icoast = nint(aivals1(7,is)) iclip = nint(aivals1(12,is)) igradsml = nint(aivals1(26,is)) igradbig = nint(aivals1(27,is)) iratio = nint(aivals1(28,is)) rterm=0.0 if (aivals1(25,is) > 0.) rterm=1./aivals1(25,is) pcpobs0 = aivals1(21,is)*rterm pcpnbc0 = aivals1(22,is)*rterm pcpbc0 = aivals1(23,is)*rterm pcpsas0 = aivals1(24,is)*rterm ikeep = nint(aivals1(25,is)) rterm=0.0 if (aivals1(35,is) > 0.) rterm=1./aivals1(35,is) pcpobs1 = aivals1(31,is)*rterm pcpnbc1 = aivals1(32,is)*rterm pcpbc1 = aivals1(33,is)*rterm pcpsas1 = aivals1(34,is)*rterm itoss = nint(aivals1(35,is)) ! Print qc counts. if (inum > 0) then write(iout_pcp,*)' ' write(iout_pcp,2000) 'type',' ','num','numw',& 'itotal','ireduce','iland','isnoice','icoast',& 'grad<1e-10','grad>1e4','ratio>3' write(iout_pcp,2010) obstype,inum,inumw,& itotal,ireduce,iland,isnoice,icoast,& igradsml,igradbig,iratio write(iout_pcp,2012) obstype,aivals1(15,is) write(iout_pcp,2000) 'qc-flag','satpcp ','pcpnbc ',& 'pcpsas ','pcplrg ','pcpbc ',' count ' write(iout_pcp,2013)'keep',pcpobs0,pcpnbc0,pcpsas0,& pcpnbc0-pcpsas0,pcpbc0,ikeep write(iout_pcp,2013)'toss',pcpobs1,pcpnbc1,pcpsas1,& pcpnbc1-pcpsas1,pcpbc1,itoss end if 2000 format(15(a10,1x)) 2010 format(1x,A10,' counts ',2x,12(i10,1x)) 2011 format(2012 format(1x,A10,' penalty ',g18.12) 2013 format(a10,1x,5(e10.4,1x),i6) 2014 format( ! Print penalties penalty_all=penalty_all+aivals1(15,is) end do write(iout_pcp,*)' ' write(iout_pcp,*)'pcp total penalty_all=',penalty_all ! Print counts, bias, rms, stndev as a function of channel. do is = 1,nsat isum = nint(aivals1(11,is)) if (isum > 0) then rpen(is) = aivals1(15,is) rsum = 1./float(isum) icerr = nint(aivals1(12,is)) do j=13,16 aivals1(j,is)=aivals1(j,is)*rsum end do aivals1(14,is) = sqrt(aivals1(14,is)) cpen(is) = aivals1(15,is) if (isum > 1) then sdv = sqrt(& aivals1(14,is)*aivals1(14,is)- & aivals1(13,is)*aivals1(13,is)) else sdv = 0.0 endif write(iout_pcp,1102) kidsat1(is),sattype(is),isum,icerr,& aivals1(16,is),aivals1(13,is),aivals1(15,is),aivals1(14,is),sdv 1102 format(1x,i3,1x,a10,1x,2(i6,1x),6(g18.12,1x)) else rpen(is) = 0.0 cpen(is) = 0.0 end if end do write(iout_pcp,1109) do i=1,nsat if (aivals1(11,i)>0.) & write(iout_pcp,1115) jiter,kidsat1(i),aivals1(11,i),& aivals1(13,i),aivals1(14,i),rpen(i),cpen(i) end do 1109 format(t6,'it',t14,'sat',t21,'num use',t35,'bias',t45,'rms',t55,'penalty',t69,'cpen') 1115 format(t2,'o-g',1x,i2.2,1x,'pcp',2x,i3,2x,f9.0,2x,g10.4,2x,g10.4,2x,f9.4,2x,f12.6) ! End of diagnostic print block. close(iout_pcp) end if ! ! Deallocate arrays deallocate(tsas,qsas,tlrg,qlrg) deallocate(t0,q0,cwm0,u0,v0,div0,t1,q1,cwm1,u1,v1,tlat0,tlon0,qlat0,qlon0) deallocate(ad_t0,ad_q0,ad_cwm0,ad_u0,ad_v0,ad_div0,ad_t1,ad_q1,ad_cwm1,& ad_u1,ad_v1,ad_t4,ad_q4,ad_cwm4,ad_u4,ad_v4,ad_div4) ! End of routine return end subroutine setuppcp