subroutine total(iyear,idoy,nscan,skipit,back,outrng) c c*********************************************************************** c c date c september, 2001 c c author c charlie wellemeyer of ssai c c calling routine c oproc c c purpose c total is the version 8 driver for processing one scan of data of c from the level 1 sbuv record and computing the total ozone used c as first guess in the profiling algorithm. c c modification c c-h Extend photometer reflectivity computation to all 12 channels and c-h save those at the first 4 channels to bufo(496:499) c c variables c name type i/o description c ---- ---- --- ----------- c c arguments c indbuf i*4 i advance scan pointer if indbuf = 2 c back l i descending orbit if true c year i*4 i year of orbit c idoy i*4 i day of year c igmt i*4 i gmt time (seconds) of current scan c ozmin r*4 i/o minimum ozone for the orbit c ozmax r*4 i/o maximum ozone for the orbit c skipit l*4 o logical indicator of no total ozone sol. c error l*4 o indicates fatal processing error c c common/totret/ c i variables for individual scan c c common/contrl/ c lprint(30) l*4 i printout control flags c c common/lpoly/ c iofset i*4 i offset pointer for table interpolation c c subroutines called c name purpose c ---- ------- c scanin loads data from level 1 file, calc interp coeffs c reflec calculates reflectivity and cloud fraction c oznot estimates ozone using b wavelengths c residue calculates residues c aprsbo interpolates a priori from the ozone profile climatology c aprsbt interpolates temperature profile from the climatology c stnp81 interpolates 81 layer standard profile for first guess c getmsr calculates msr part of radfiance and jacobian c delnbyt calculates temperature impact on calculated n-values c blwcld calculates ozone beneath any cloud present c seterr determines if an error flag should be set c lodtoz loads total ozone portion of output buffer c dtailt prints first guess output to the detail unit c c*********************************************************************** c implicit none c logical*4 skipit, back, maxitr, badaer, error, skiprf logical*4 frstrf, frstoz, prntit, outrng integer iyear,algflg,errflg,iplow,iphigh,iter,idoy, 1 i, j, ioz, nscan, iseq, inderr integer lyr,ilmda,irefl real delr,delntt, aiadj real delnt(8,11), fgprf(11), guesoz, fteran, grref, clref, 1 dndr331 real eff(11), delns(8), pcfrac, dnd318 real dnd331, refm, pcld, ccldfs(8) real dnd340, grref1, clref1, ccgrfl(8), cccrfl(8) real rad(8),radmsr(8),radss(8),dndom(8),dndx(8,11), 1 dndxmsr(8,11),dndxss(8,11) real apprf(11), delshp(11),dxdom(11),s2prf(11),resbst(8) 1 ,aptmp(11) c-h Output parameters for reflp that extends to 12 channels real ccgrflx(12),cccrflx(12),scnrflx(12),ccldfsx(12) c-h Variables for getting partial cloud reflectivity at monochromator wavelengths c and LER at monochromator wavelengths (chn-7-12) and at 378 nm of photometer real refx0,prefx0,refx1,prefx1,rsensp0,resnp0,refp0,pcfracx, 1 dnd331x,clfracx,grrefx,clrefx,delrx(8), 2 ccgrflx0(12),cccrflx0(12),scnrflx0(12),ccldfsx0(12) integer isnowx,ichn,i2 logical*4 frstrfx c integer n, nc, ns, nitr, nref, kx parameter (n = 81, nc = 10, ns = 8, nitr = 8, nref = 1690) c include 'contrl.com' include 'totret.com' include 'lpoly.com' include 'prfprm.com' include 'const.com' include 'countr.com' include 'buffout.com' include 'stndprof.com' c c fixed multiple scattering components at 4 shortest wavelengths c real shrtms(4)/0.30,0.29,0.39,0.65/ c c 13 layer standard temperature profile for test purposes c real stndtmp(13)/242.474,256.982,269.299,266.250,250.695, 1 236.870,226.994,222.376,217.826,216.597, 2 216.515,236.470,269.728/ c include 'satnams.h' c c initialize algorithm parameters c ozbst=99999.0 ref=99999.0 estozn=99999.0 stp2oz=99999.0 rsensp=99999.0 resnp=99999.0 pteran=99999.0 pcloud=99999.0 clfrac=99999.0 ozcld=99999.0 isface=99999.0 do i=1,8 sens(i)=99999.0 rsens(i)=99999.0 resn(i)=99999.0 scnrfl(i)=99999.0 cldfrac(i+4)=99999.0 enddo do i=1,11 apprf(i)=99999.0 eff(i)=99999.0 enddo c c -- load in measurement c algflg = 0 skipit=.false. back=.false. maxitr = .false. outrng = .false. c aerind=99999.0 badaer = .false. if(r380.eq.-777.0) badaer = .true. c if(xlat.lt.-90..or.xlat.gt.90.) outrng=.true. if(xlon.lt.-180..or.xlon.gt.180.) outrng=.true. if (.not.skipit) call scanin(iyear,idoy,skipit) if(xlat.lt.xlatlo.or.xlat.gt.xlathi) outrng=.true. if(xlon.lt.xlonlo.or.xlon.gt.xlonhi) outrng=.true. if(skipit) go to 500 c c check for wild radiances c if(.not.n14()) then do i=5,12 if(abs(xnvalp(i)-xnvalp(i-1)) .gt. 0.1) skipit=.true. if(xnvalp(i) .lt. 0.4 .or. xnvalp(i) .gt. 5.) skipit=.true. enddo endif c-lkh Add Nimbus-4 special case to process its B-pair total & LER, March 2012 if(n04()) then do i=5,12 if(xnvalm(i) .lt. 0.4 .or. xnvalm(i) .gt. 5.) then if(i.ge.9) skipit=.true. skiprf=.true. endif enddo else do i=5,12 if(xnvalm(i) .lt. 0.4 .or. xnvalm(i) .gt. 5.) skipit=.true. enddo endif if(skipit) go to 500 c c -- we need to start somewhere in the table c if (abs(xlat) .le. 45.) then guesoz = 260. else if (abs(xlat) .le. 75) then guesoz = 340. else guesoz = 360. end if c c -- the core of the version 8 sbuv algorithm begins here c c -- calculate the terrain factor c fteran = (1.0-pteran)/0.50 c c -- iterate calls to reflec and oznot to determine first guess ozone c frstrf = .true. frstoz = .true. algflg = 1 errflg = 0 ozonin = guesoz ioz = iozon irefl = irflo iter = 0 c print*,'entering total: iyear,idoy,nscan,xlat,xlon,igmt' c print*,iyear,idoy,nscan,xlat,xlon,igmt c c first get dnd340 c grref1=grref clref1=clref call reflec(irfhi,ioz,iofset,ilat,xlat,isnow,grref1,clref1, 1 sza12,pcloud,pteran,ozonin,xnvalm,xnvalp,ramcor,fteran, 2 frstrf,lprint,clfrac,ref,pref,iplow,iphigh, 3 pcfrac,dnd340) frstrf= .true. 200 continue c c -- compute cloud fraction and reflectivity c call reflec(irefl,ioz,iofset,ilat,xlat,isnow,grref,clref, 1 sza12,pcloud,pteran,ozonin,xnvalm,xnvalp,ramcor,fteran, 2 frstrf,lprint,clfrac,ref,pref,iplow,iphigh, 3 pcfrac,dnd331) c c -- compute reflectivity for the photometer measurements c if(.not.n14()) then call reflp(iofset,ilat,xlat,isnow,irefl, 1 sza12,pcloud,pteran,ozonin,xnvalp,ramcor,fteran, 2 lprint,iplow,iphigh,grref,clref,ref,clfrac, 3 rsensp,resnp,ccgrflx,cccrflx,scnrflx,ccldfsx) else if(wlenth(2) .ge. 273.46 .and. wlenth(2) .le. 273.56)then call reflpzz(iofset,ilat,xlat,isnow,irefl, 1 sza12,pcloud,pteran,ozonin,xnvalm,ramcor,fteran, 2 lprint,iplow,iphigh,grref,clref,ref,clfrac,wlenth, 3 rsensp,resnp,ccgrflx,cccrflx,scnrflx,ccldfsx) else if(sza12(1) .gt. 82 .or. sza12(12) .gt. 82)then call reflpmn(iofset,ilat,xlat,isnow,irefl, 1 sza12,pcloud,pteran,ozonin,xnvalm,ramcor,fteran, 2 lprint,iplow,iphigh,grref,clref,ref,clfrac,wlenth, 3 rsensp,resnp,ccgrflx,cccrflx,scnrflx,ccldfsx) else call reflp(iofset,ilat,xlat,isnow,irefl, 1 sza12,pcloud,pteran,ozonin,xnvalp,ramcor,fteran, 2 lprint,iplow,iphigh,grref,clref,ref,clfrac, 3 rsensp,resnp,ccgrflx,cccrflx,scnrflx,ccldfsx) endif endif endif c-h Pass output params for the 8 long wavelength channels do kx=1,8 ccgrfl(kx)=ccgrflx(kx+4) cccrfl(kx)=cccrflx(kx+4) scnrfl(kx)=scnrflx(kx+4) ccldfs(kx)=ccldfsx(kx+4) enddo c-h Pass output params for the 4 short wavelength channels do kx=1,4 scnrfl4s(kx)=scnrflx(kx) enddo c c -- compute ozone using b wavelength (317 nm) c call oznot(ioz,iofset,ilat,xlat,ccldfs(iozon-4), 1 scnrfl(iozon-4),ccgrfl(iozon-4),cccrfl(iozon-4), 1 pteran,pcloud,xnvalm,ozonin,fteran,ramcor, 2 frstoz,lprint,skipit,iplow,iphigh,dnd318,estozn) bufo(40) = estozn c iter = iter + 1 if (iter.eq.1) then ozonin = estozn if ((dnd318-dnd331)/(dnd331-dnd340) .lt. 1.25 .and. 1 abs(wlenth(11)-wlenth(12)) .gt. 0.5) then frstrf = .true. frstoz = .true. ozonin = guesoz ioz = iozhi irefl = irfhi algflg = 3 endif go to 200 endif c if(iter.gt.12.or.estozn.lt.0.0.or.estozn.gt.900.0) then maxitr = .true. go to 500 endif c if(abs(estozn-ozonin).gt.1.0) then ozonin = estozn go to 200 endif c c load cloud fraction array for profiling algorithm c do i=1,8 cldfrac(i+4) = ccldfs(i) enddo c c -- calculate residues and sensitivities using ozone estimate c -- calculated above c call residue(estozn,xlat,pteran,pcloud,iofset,fteran,ramcor, 1 irefl,ilat,isnow,xnvalm,xnvalp,iplow,iphigh,lprint, 3 ccgrfl,cccrfl,scnrfl,ccldfs,resn,sens,rsens,radmsr) if(.not. n07()) r380=resnp if(n14()) r380=99999.0 c c call getmsr to perform table lookup for radiances and sensitivities c call getmsr(estozn,pteran,pcloud,iofset,iplow,iphigh, 1 ramcor,lprint,irefl,ilat,xlat,isnow,fteran,xnvalm,xnvalp, 2 ccgrfl,cccrfl,scnrfl,cldfrac,fgprf,dndom,dxdom,dndxmsr, 3 dndx,dndxss,krngr_mu,krncl_mu) c stp2oz = estozn ozbst = estozn c p_cld = pcloud p_terr = pteran c c call aprioz to get 13 layer apriori ozone profile c call aprsbo(xlat, idoy, lprint, qutot_a, qu_a) c c call aprioz to get 13 layer apriori temperature profile c call aprsbt(xlat, idoy, lprint, tu_a) c c for test purposes only set apriori temp = stndard temp c c print*,'loading standard temperature profile as apriori!!!!' c do i=1,13 c tu_a(i) = stndtmp(i) c enddo c c define 11 layer apriori temperature profile for total ozone algorithm c do i=1,11 aptmp(i)=tu_a(14-i) enddo c c call stnp81 to get 81 layer first guess ozone profile c call stnp81(ilat, estozn, fteran, lprint, q0) c c call delnbyt to compute temperature adjustments for radms using c the 11 lower layers of fgprf, fgtmp, and qt_a c call delnbyt(dndxmsr,fgprf,fgtmp,aptmp,lprint,delnt) c c adjust msr radiances for apriori temperature profile c do i=1,4 rad_m0(i) = shrtms(i) if(i.eq.1.and.(n04().or.n07())) rad_m0(i) = 0.28 enddo do i=5,10 delntt=0.0 do lyr=1,11 delntt=delntt+delnt(i-4,lyr) enddo rad_m0(i) = radmsr(i-4)*(1.0-delntt/43.429448) enddo if(iopts(1)) go to 500 c c -- call getshp to determine apriori profile shape c call getshp(ilat, xlat, idoy, estozn, fteran, fgprf, lprint, 1 apprf, delshp) c c call delnbyt to compute temperature adjustments again for dndx using c the 11 lower layers of fgprf, fgtmp c call delnbyt(dndx,fgprf,fgtmp,aptmp,lprint,delnt) c c -- calculate best ozone c call ozone(ioz,irefl,estozn,xlat,fgprf,fgtmp,dndx, 1 delnt,sens,rsens,dxdom,aptmp,xlon,sza, 2 lprint,delshp,delr,s2prf,eff,stp2oz) c c -- calculate final residues c-h Get 8 channels (5-12) of dRefl for O3 and T profile differences call resadj(ioz,irefl,resn,sens,rsens,dndx,delnt,fgprf,fgtmp, c-h 1 s2prf,aptmp,stp2oz,qutot_a,estozn,delr,lprint,resbst) 1 s2prf,aptmp,stp2oz,qutot_a,estozn,delr,lprint,resbst,delrx) c c-h To get surface reflectivities at other monochromator wavelength channels c from CHN-7 to CHN-12: c 1st, as defined in cloud fraction algorithm c 2nd, as defined LER with reflecting surface pressure at terrain level do i=1,6 ichn=i+6 i2=i+2 grrefx=0.15 clrefx=0.80 frstrfx=.false. c-h Debugged for computing LER and MLER at 340 nm without duplicating c residue correction. Feb 2012 call reflec(ichn,ioz,iofset,ilat,xlat,isnow,grrefx,clrefx, 1 sza12,pcloud,pteran,ozonin,xnvalm,xnvalp,ramcor,fteran, 2 frstrfx,lprint,clfracx,refx1,prefx1,iplow,iphigh, 3 pcfracx,dnd331x) bufo(910+i)=refx1+delrx(i2) grrefx=0.15 clrefx=0.80 isnowx=10 call reflec(ichn,ioz,iofset,ilat,xlat,isnowx,grrefx,clrefx, 1 sza12,pcloud,pteran,ozonin,xnvalm,xnvalp,ramcor,fteran, 2 frstrfx,lprint,clfracx,refx0,prefx0,iplow,iphigh, 3 pcfracx,dnd331x) bufo(916+i)=refx0+delrx(i2) bufo(922+i)=delrx(i2) enddo c-h Get LER as measured by the photometer at 378 nm (not calibrated to c the monochrometer reflectivity channel) if(.not.n14()) then call reflp(iofset,ilat,xlat,isnowx,irefl, 1 sza12,pcloud,pteran,ozonin,xnvalp,ramcor,fteran, 2 lprint,iplow,iphigh,grref,clref,ref,clfrac, 3 rsensp0,resnp0,ccgrflx0,cccrflx0,scnrflx0,ccldfsx0) refp0=ref+resnp0/rsensp0 do i=1,12 bufo(928+i)=refp0+(scnrflx(i)-scnrflx(irefl)) enddo endif c ref = ref + delr c do 300 ilmda=1,8 resn(ilmda) = resbst(ilmda) 300 continue c c compute step 3 ozone based on regressions of r313 and r360 c ozbst = stp2oz if(.not.iopts(2)) then if(.not.n14()) then if(sza12(ioz).le.70.0 .and. algflg .eq. 1) then aiadj=f360(1)+f360(2)*pathl(ioz)+f360(3)*pathl(ioz)**2.0 if(n07()) then if(r380.ne.-777.0) then ozbst = stp2oz + aiadj/100.0 * r380 * 1 (331.0-360.0)/(331.0-380.0) * stp2oz else badaer = .true. ozbst = stp2oz endif else ozbst = stp2oz + aiadj/100.0 * r380 * 1 (331.0-360.0)/(wlenth(irefl)-380.0) * stp2oz endif endif endif if(sza12(ioz).gt.70.0 .and. algflg .eq. 1) then ozbst = stp2oz + f313 * (resn(imixr-4)-resn(irefl-4)) algflg = 2 endif c c check to see if resns are both zero!!!!!!!!!!!!!!! c and if c-pair ever used!!!!!!!!!!!!!!!!!!!!!!!!!!! c if( algflg .eq. 3) then ozbst = stp2oz + (resn(iozhi-4) - resn(irefl-4))/ & (sens(iozhi-4) - sens(irefl-4)) endif c c adjust residues for step 3 ozone change c do i=1,8 resn(i)=resn(i)-sens(i)*(ozbst-stp2oz) enddo c endif c c set aerosol index c if(r380.eq.-777.0) badaer = .true. aerind=99999.0 if(.not.badaer.and..not.n14().and.algflg.ne.3) aerind=-r380 if(aerind.eq.777) then print*,'aerind 1: ',skipit,badaer,n14(),algflg,aerind,xlat endif c c -- calculate ozone below cloud c call blwcld(fgprf,pcloud,clfrac,fteran,lprint,ozcld) c c -- call seterr to set algorithm error flag c 500 continue if(aerind.eq.777) then print*,'aerind 2: ',skipit,badaer,n14(),algflg,aerind,xlat endif back = sublt .lt. sublt_prv c-lkh move to rdatar.f sublt_prv = sublt call seterr(irefl,ioz,iozhi,imixr, 1 algflg,resn,flg3lm,flg4lm,sza,pathl(iozon),back, 2 maxitr,badaer,outrng,lprint,skipit,ozbst,errflg,aerind) c c -- the core of the version 8 algorithm ends here c c -- increment counter if(isnow .ge. 10) algflg=algflg+10 inderr=errflg if(errflg.gt.99) inderr=errflg-100 if(inderr.gt.9) inderr=inderr-10 nocntr(3+inderr) = nocntr(3+inderr) + 1 c c load output buffer with first guess information c iseq=nscan+1 call lodtoz(iseq,iyear,idoy,algflg,errflg,apprf,eff) c c write detail from first guess retrieval to unit 15 c c fgprf(11),resn(8),sens(8),rsens(8), c qu_a(13),tu_a(13),radmsr(8),rad(8),radss(8),dndom(8), c dndxmsr(8,11),dndx(8,11),dndxss(8,11),kern_mu(10,11),delnt(8), c sza12(12),p_cld,p_terr,cldfrac(12) c prntit = .false. c if(.not.skipit) prntit = .true. if(prntit) then c print*,'radss' c write(6,'(8f11.7)') (radss(i),i=1,8) c print*,'radmsr' c write(6,'(8f11.7)') (radmsr(i),i=1,8) c print*,'rad' c write(6,'(8f11.7)') (rad(i),i=1,8) print*,'rad_m0' write(6,'(6f11.7)') (rad_m0(i),i=5,10) c print*,'rad - rad_m0' c write(6,'(6f11.7)') (rad(i)-rad_m0(i+4),i=1,6) c print*,'nval calc' c write(6,'(6f11.3)') (-100.0*log10(rad(i)),i=1,6) c print*,'resn' c write(6,'(8f11.3)') (resn(i),i=1,8) c print*,'nval calc + residue' c write(6,'(8f11.3)') (-100.0*log10(rad(i))+resn(i),i=1,8) c print*,'xnvalm' c write(6,'(6f11.3)') (100.0*xnvalm(i),i=5,10) c print*,'dndxmsr' c write(6,'(8f9.5)') dndxmsr c print*,'krngr_mu' c write(6,'(6f9.5)') ((krngr_mu(i,j),i=5,10),j=1,11) c print*,'krncl_mu' c write(6,'(6f9.5)') ((krncl_mu(i,j),i=5,10),j=1,11) c print*,'dndx' c write(6,'(8f9.5)') dndx c print*,'dndxss' c write(6,'(8f9.5)') dndxss c print*,'iseq =',iseq c stop 1 endif call dtailt(iseq,iyear,idoy,iorbit,igmt,fgprf, 1 resn,sens,rsens,qu_a,tu_a,radmsr,rad,radss, 2 dndom,dndxmsr,dndx,dndxss,delnt,sza12, 3 p_cld,p_terr,cldfrac) c c-lkh Add Nimbus-4 special case to process its B-pair total & LER, March 2012 if(n04().and.skiprf)skipit=.true. c return c end