subroutine qcssmi(nchanl, & sfchgt,luse,sea,ice,snow,mixed, & ts,pems,ierrret,kraintype,tpwc,clw,sgagl, & tbcnob,tb_obs,ssmi,amsre_low,amsre_mid,amsre_hig,ssmis, & ssmis_uas,ssmis_las,ssmis_env,ssmis_img, & varinv,errf,aivals,id_qc ) !$$$ subprogram documentation block ! . . . ! subprogram: qcssmi QC for ssmi/amsre ! ! prgmmr: okamoto org: np23 date: 2004-12-01 ! ! abstract: set quality control criteria for SSM/I,AMSR-E,SSMIS(UKMO) ! ! program history log: ! 2004-12-01 okamoto ! 2005-02-17 derber clean up surface flags ! 2005-03-04 treadon - correct underflow error for varinv ! 2005-09-05 derber - allow max error to change by channel ! 2005-10-07 Xu & Pawlak - add SSMIS qc code, add documentation ! 2005-10-20 kazumori - add AMSR-E qc code, add documentation ! 2006-02-03 derber - modify for new obs control and stats ! 2006-04-26 kazumori - change clw theshold for AMSR-E ! 2006-04-27 derber - modify to do single profile - fix bug ! 2006-07-27 kazumori - modify AMSR-E qc and input of the subroutine ! 2006-12-01 derber - modify id_qc flags ! 2007-01-24 kazumori - modify SSMIS qc and input of the subroutine ! 2008-04-23 safford - rm unused vars ! ! input argument list: ! nchanl - number of channels per obs ! sfchgt - surface height (not use now) ! luse - logical use flag ! sea - logical, sea flag ! ice - logical, ice flag ! snow - logical, snow flag ! mixed - logical, mixed zone flag ! ts - skin temperature ! pems - surface emissivity ! ierrret - result flag of retrieval_mi ! kraintype - [0]no rain, [others]rain ; see retrieval_mi ! clw - retrieve clw [kg/m2] ! sgagl - sun glint angle [degrees] ! tpwc - retrieve tpw [kg/m2] ! tbcnob - Obs - Back TBB without bias correction ! tb_obs - obs TBB ! ssmi - logical true if ssmi is processed ! ssmis - logical true if ssmis is processed ! ssmis_uas - logical true if ssmis_uas is processed ! ssmis_las - logical true if ssmis_las is processed ! ssmis_env - logical true if ssmis_env is processed ! ssmis_img - logical true if ssmis_img is processed ! amsre_low - logical true if amsre_low is processed ! amsre_mid - logical true if amsre_mid is processed ! amsre_hig - logical true if amsre_hig is processed ! ! NOTE! if retrieved clw/tpwc not available over ocean,set -9.99e+11, ! but 0 over land/mixed/ice ! ! output argument list: ! varinv - observation weight (modified obs var error inverse) ! errf - criteria of gross error ! aivals - number of data not passing QC ! id_qc - qc index, common to all ch ! ! Special Notes: ! id_qc is used for tracing each QC ! 0:use ! 2:land/ice/snow, 3:sfchgt>2000, 4:rain 5:retrieval_mi error, 6:clw ! 7:sgagl, 9: amsre dtb 10:clwch, 11:term, 12:gross error, ! When several QC criteria are satisfied, the first QC goes to id_qc ! ! ! ... possibe QC to add .......................... ! * decrease varinv at last several scan position ! ! clwcutofx is used to set cloud qc threshold (kg/m2) ! from Fuzhong Weng (need better reference) ! ................................................ ! ! attributes: ! language: f90 ! machine: ibm RS/6000 SP ! !$$$ end documentation block use kinds, only: r_kind, i_kind use constants, only: izero,half,one,zero,tiny_r_kind,two implicit none ! Declare passed variables integer(i_kind) ,intent(in ) :: nchanl integer(i_kind) ,intent(in ) :: kraintype,ierrret integer(i_kind),dimension(nchanl),intent(inout) :: id_qc logical ,intent(in ) :: sea,snow,ice,mixed,luse logical ,intent(in ) :: ssmi,amsre_low,amsre_mid,amsre_hig,ssmis logical ,intent(in ) :: ssmis_uas,ssmis_las,ssmis_env,ssmis_img real(r_kind) ,intent(in ) :: sfchgt,tpwc,clw,sgagl real(r_kind) ,dimension(nchanl),intent(in ) :: ts,pems real(r_kind) ,dimension(nchanl),intent(in ) :: tbcnob,tb_obs real(r_kind) ,dimension(nchanl),intent(inout) :: varinv,errf real(r_kind) ,dimension(40) ,intent(inout) :: aivals ! Declare local variables integer(i_kind) :: l,i real(r_kind) :: efact,vfact,dtempf,fact,dtbf,term real(r_kind),dimension(nchanl) :: demisf_mi,clwcutofx real(r_kind),parameter:: r2000=2000.0_r_kind real(r_kind),parameter:: r4000=4000.0_r_kind real(r_kind) :: pred9,pred10,pred11 real(r_kind),dimension(nchanl):: tb_ges !------------------------------------------------------------------ tb_ges(:)=tb_obs(:)-tbcnob(:) ! Set cloud qc criteria (kg/m2) : reject when clw>clwcutofx if(ssmi) then clwcutofx(1:nchanl) = & (/0.35_r_kind, 0.35_r_kind, 0.27_r_kind, 0.10_r_kind, & 0.10_r_kind, 0.024_r_kind, 0.024_r_kind/) else if(amsre_low.or.amsre_mid.or.amsre_hig) then clwcutofx(1:nchanl) = & (/0.350_r_kind, 0.350_r_kind, 0.350_r_kind, 0.350_r_kind, & 0.300_r_kind, 0.300_r_kind, 0.250_r_kind, 0.250_r_kind, & 0.100_r_kind, 0.100_r_kind, 0.020_r_kind, 0.020_r_kind/) ! --- amsre separate channel treatment depend on FOV if(amsre_low) varinv(5:12)=zero if(amsre_mid) varinv(1:4)=zero if(amsre_mid) varinv(11:12)=zero if(amsre_hig) varinv(1:10)=zero else if(ssmis) then clwcutofx(1:nchanl) = & !kg/m2 reject when clw>clwcutofx (/ 0.20_r_kind, 0.20_r_kind, & 0.60_r_kind, 0.60_r_kind, & 0.60_r_kind, 0.60_r_kind, & 0.60_r_kind, 0.15_r_kind, & 0.60_r_kind, 0.60_r_kind, & 0.60_r_kind, 0.20_r_kind, & 0.20_r_kind, 0.20_r_kind, & 0.20_r_kind, 0.20_r_kind, & 0.20_r_kind, 0.15_r_kind, & 10.0_r_kind,10.0_r_kind, & 10.0_r_kind,10.0_r_kind, & 10.0_r_kind,10.0_r_kind /) if(ssmis_img) then varinv(1:7)=zero varinv(12:16)=zero varinv(19:24)=zero end if if(ssmis_env) then varinv(1:11)=zero varinv(17:24)=zero end if if(ssmis_las) then varinv(8:23)=zero endif if(ssmis_uas) then varinv(1:18)=zero varinv(24)=zero end if end if dtempf = half demisf_mi(1:nchanl) = 0.01_r_kind ! Loop over observations. efact =one vfact =one ! id_qc = 1 do not use (from setuprad) ! id_qc = 2 not sea ! id_qc = 3 high topography ! id_qc = 4 kraintype /=izero ! id_qc = 5 ierrret > izero ! id_qc = 6 tpwc <=zero ! id_qc = 7 sgagl < 25. and amsre_low ! id_qc = 8 gross check (later in setuprad) ! id_qc = 9 amsre dtb threshold of an inaccuracy of emis model ! id_qc = 10 first channel with clw > cutoff ! id_qc = 11 gross error ! Over sea if(sea) then ! dtb/rain/clw qc using SSM/I RAYTHEON algorithm if( ierrret>izero .or. kraintype/=izero .or. tpwc<zero ) then efact=zero; vfact=zero if(luse) aivals(8) = aivals(8) + one if(luse)then do i=1,nchanl if( id_qc(i)==izero .and. kraintype/=izero ) id_qc(i)=4_i_kind if( id_qc(i)==izero .and. ierrret>izero ) id_qc(i)=5_i_kind if( id_qc(i)==izero .and. tpwc<=zero ) id_qc(i)=6_i_kind end do end if else if(amsre_low .and. sgagl < 25.0_r_kind) then ! ---- sun glint angle qc (for AMSR-E) varinv(1:4)=zero do i=1,4 if(id_qc(i) == izero)id_qc(i) = 7_i_kind end do if(luse) aivals(11) = aivals(11) + one else if(amsre_low .or. amsre_mid .or. amsre_hig)then ! ---- dtb threshold qc for AMSR-E due to an inaccuracy of emis model if( abs(tbcnob(1)) > 6.0_r_kind .or. & abs(tbcnob(2)) > 6.0_r_kind .or. & abs(tbcnob(3)) > 6.0_r_kind .or. & abs(tbcnob(4)) > 6.0_r_kind .or. & abs(tbcnob(5)) > 6.0_r_kind .or. & abs(tbcnob(6)) > 8.0_r_kind .or. & abs(tbcnob(7)) > 8.0_r_kind .or. & abs(tbcnob(8)) > 10.0_r_kind .or. & abs(tbcnob(9)) > 6.0_r_kind .or. & abs(tbcnob(10)) > 6.0_r_kind) then varinv(:)=zero do i=1,nchanl id_qc(i)=9_i_kind end do if(luse) aivals(13) = aivals(13) + one end if else if(clw > zero)then ! If dtb is larger than demissivity and dwmin contribution, ! it is assmued to be affected by rain and cloud, tossing it out do l=1,nchanl ! clw QC using ch-dependent threshold (clwch) if( clw > clwcutofx(l) ) then varinv(l)=zero if(luse) then aivals(10) = aivals(10) + one if(id_qc(l)==izero) then id_qc(l)=10_i_kind aivals(9)=aivals(9) + one end if end if end if end do !l_loop end if ! Use only data over sea else !land,sea ice,mixed ! Reduce q.c. bounds over higher topography if ( .not. ssmis) then if (sfchgt > r2000) then fact = r2000/sfchgt efact = fact*efact vfact = fact*vfact do i=1,nchanl if(id_qc(i)==izero.and.luse) id_qc(i)=3_i_kind end do end if ! demisf_mi=demisf_mi*0.7_r_kind ! not necessary since data not used efact=zero vfact=zero do i=1,nchanl if(id_qc(i)==izero.and.luse) id_qc(i)=2_i_kind end do else if (ssmis) then varinv(1:2)=zero varinv(12:16)=zero if (sfchgt > r2000) then varinv(9)=zero end if if (sfchgt > r4000) then varinv(3)=zero varinv(10)=zero end if if(mixed) then varinv(1:3)=zero varinv(8:18)=zero end if if(ice) then varinv(2:3)=zero varinv(9:11)=zero end if if(snow) then varinv(2:3)=zero varinv(9:11)=zero end if do i=1,nchanl if(id_qc(i)==izero.and.luse) id_qc(i)=2_i_kind end do end if end if if(ssmis)then ! scattering affected data removal pred9 =271.252327_r_kind + tb_ges(17)*(-0.485934_r_kind) + tb_ges(8)*(0.473806_r_kind) pred10 =272.280341_r_kind + tb_ges(17)*(-0.413688_r_kind) + tb_ges(8)*(0.361549_r_kind) pred11 =278.824902_r_kind + tb_ges(17)*(-0.400882_r_kind) + tb_ges(8)*(0.270510_r_kind) if(tbcnob(9) +tb_ges(9) -pred9 <-two) varinv(9) =zero if(tbcnob(10)+tb_ges(10)-pred10<-two) varinv(10)=zero if(tbcnob(11)+tb_ges(11)-pred11<-two) varinv(11)=zero end if ! Generate q.c. bounds and modified variances. do l=1,nchanl errf(l) = efact*errf(l) varinv(l) = vfact*varinv(l) if (varinv(l) > tiny_r_kind) then dtbf = demisf_mi(l)*abs(pems(l)) + dtempf*abs(ts(l)) term = dtbf*dtbf if(term>tiny_r_kind) varinv(l)=one/(one/varinv(l)+term) else if(luse .and. id_qc(l)==izero )then id_qc(l)=11_i_kind endif end do ! l (ch) loop end return end subroutine qcssmi