subroutine setuprad(jiter,mype_rad,deltat,sigl,sigi,& 1,18
     nsig,lat1,lon1,nsat1,nsatdat_s,lunin,lunout,varst,varprd,&
     npred,mype,nsat,nlath,nlon,rlats,rlons,cbias,tlapmean,&
     predx,ggrid_g31,ggrid_g32,&
     fact10,sfct,isli,sno,veg_type,veg_frac,soil_type,soil_temp,soil_moi, &
     diag_rad,idiag_rad,iout_rad,obstype_all,npes,&
     jppf,jpch,jpchus,tropprs)

!$$$  subprogram documentation block
!                .      .    .                                       .
! subprogram:    setuprad   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
!     mype_rad - processor used for print out
!     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
!     nsat1    - number of satellite observations for every satellites 
!                in each pe subdomain
!     nsatdat_s - total number of observations for all satellites
!     lunin    - unit to read observation distributed data
!     lunout   - unit to save satllite observation
!                processed distributed data
!     npred    - number of predictors
!     mype     - pe number
!     nsat     - number of satellites
!     nlath    - number of gaussian lats in one hemisphere
!     nlon     - number of longitudes
!     rlats    - grid latitudes (radians)
!     rlons    - grid longitudes (radians)
!     cbias    - angle dependent bias (fixed from input file)
!     tlapmean - mean lapse rate (fixed from input file)
!     predx    - current estimate of bias correction coefficients
!     ggrid_g31- atmospheric state at analysis time
!     ggrid_g32- atmospheric state at +/- 3 hrs of analysis time
!     fact10   - 10 meter wind factor
!     sfct     - guess skin temperature
!     isli     - snow-land-ice mask
!     sno      - snow-ice mask
!     veg_type - veg type
!     veg_frac - veg fraction
!     soil_type- soil type
!     soil_temp- soil temp (first layer)
!     soil_moi - soil moisture (first layer)
!     gsstm    - time index of the first guess fields
!     diag_rad - file name for radiance diagnostic file
!     iout_rad - output file for printed output
!     obstype_all - obs. types for input files
!     npes     - number of pe's
!     jppf     - number of profiles processed at once
!     jpch     - total number of channels
!     jpchus   - maximum number of channels for any instruments
!
!   output argument list:
!     varst    - variance for skin temperature
!     varprd   - variance for predictor coefficients
!
! attributes:
!   language: f90
!   machine:  ibm RS/6000 SP
!
!$$$

  use type_kinds, only: fp_kind,single
  use error_handler
  use initialize
  use spectral_coefficients
  implicit none

!
! Declare include files

  include 'mpi_inc.h'
  include 'ijstart.h'


! Declare and set parameters
  integer iint,ireal,ipchan
  parameter (iint=5, ireal=13, ipchan=7)
  

!
! Declare variables

!
!
! Declare input/output arrays

  real(fp_kind),dimension(nsig):: sigl
  real(fp_kind),dimension(nsig+1):: sigi
  real(fp_kind),dimension(2*nlath):: varst
  real(fp_kind),dimension(jpch*npred):: varprd
  real(fp_kind),dimension(2*nlath):: rlats
  real(fp_kind),dimension(nlon):: rlons
  real(fp_kind),dimension(90,jpch):: cbias
  real(fp_kind),dimension(jpch)::tlapmean
  real(fp_kind),dimension(jpch,npred):: predx
  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):: fact10,sfct,sno,veg_type,soil_type,soil_temp
  real(fp_kind),dimension(lat1+2,lon1+2):: soil_moi,veg_frac,tropprs
  integer,dimension(lat1+2,lon1+2):: isli
  character(12) diag_rad
  logical idiag_rad
  integer iout_rad,mype_rad
  character(10),dimension(55)::obstype_all

! Declare variables
  integer ll,ichan5,iyp,l,ixp,ix1,ix,iy,ichan8,ichan18,ichan4,ichan12,kcount
  integer knchpf,m,mm,mype,nlon,nlath,nobs,nblktot,jc,nobs1,nblk,newchn,isz
  integer itoss,nchan,nobs2,nsdata,lon1,nsatdat_s,jier,nsig,lunin,npes,jppf
  integer jpch,lunout,npred,nsat,k,n1,isat,nele,j,i,is,nsigx1,jiter,lat1,jpchus
  integer nstats,nx,mype1,icoast,ireduce,itopo,iobs1,iland,isnoice,ivarl,ich4
  integer ich12,ich8,igross,ich2,ich3,j11,nn,iobs2,j12,j21,j22,iang,ich1,iice
  integer jsat,icerr,isum,ich21,jo,lnbias,ich5,iemiss,jj,kk,icc,jjj,n,nlev,kval
  integer nsig2,nsigx

  real(fp_kind) vfact,efact,efactir,efacts,vfactir,efactmc,dtbf,efact21,vfactmc
  real(fp_kind) efact22,ch18flg,ch12flg,demisf,fact,dtempf,ch8flg,ch8ch10,sph
  real(fp_kind) cenlon,term,sum,tlap,ch6dbc,ch4dbc,dsval,ch15dbc,bcbtm1,emix
  real(fp_kind) ch2dbc,ch1dbc,facth6,dtde3,de2,efact6,de3,dtde1,facth4,dtde2
  real(fp_kind) de1,vfact22,ch4flg,vfact4,vfact21,ch5flg,vfacts,vfact3,vfact2
  real(fp_kind) deltat,diff1,fact1,ch4diff,ch2diff,dsi,si,rsum,svar,cpen,stdev
  real(fp_kind) ch5diff,fact3,drad,ch3diff,fact45,fact2,factch6,vfact7,cor
  real(fp_kind) ch1diff,factch4,efact7,vfact6,d2,dg2rad,rad2dg,d1,dy,wgt10
  real(fp_kind) wgt01,wgt11,dx1,dy1,wgt00,penalty_all,dx,dradnob,varrad,onpp
  real(fp_kind) constoz,fifty,zero


! Declare local arrays

  real(single) svar4,bcor4(2*(npred+1))
  real(fp_kind),dimension(lat1+2,lon1+2):: w10fact
  real(fp_kind),dimension(ireal,jppf):: diagbuf
  real(fp_kind),dimension(npred+jpchus-1,jppf):: pred
  real(fp_kind),dimension(jpchus,jppf):: varinv,errf,btm,tbc,tbcnob,tlapchn,emissav
  real(fp_kind),dimension(npred+1,jpchus,jppf):: bcor
  real(fp_kind),dimension(jpchus):: rhssat,var,tmpvar,tnoise
  real(fp_kind),dimension(1000):: rcount,rcount_all,rpenal
  real(fp_kind),dimension(nsig,jppf):: prsr5,temp5,wmix5,omix5,pin5,qvp,tvp,poz
  real(fp_kind),dimension(jppf):: ts5,soilt5,vegf5,vegtype5,soilm5,soiltype5,snow5,trop5

!     xpath: secant of viewing path angle at surface
!     xpaths: secant of solar zenith angle at surface

  real(fp_kind),dimension(jppf):: xpath,xpaths,dqval,pangs,panglr,cld,cosza
  real(fp_kind),dimension(jppf):: wsp10,cenlat,slats,slons,stfact,pp,zz,sfchgt,zasat
  real(fp_kind),dimension(jppf*jpchus):: pems5,ts,pems,ptbcl5
  real(fp_kind),dimension(nsig,jpchus*jppf):: wmix,temp,omix,ptau5
  real(fp_kind),dimension(3*nsig+1,jpchus):: htlto
  real(fp_kind),dimension(15,nsat):: aivals,aivals1
  real(fp_kind),dimension(6+2*(npred+1),jpch):: stats,stats1
  real(fp_kind),dimension(nsig):: c1,c2,c3,c4
  real(fp_kind),dimension(nsig):: siglr,sigir,ccsig

!     varch: rms error for each channel
!     polar: channel polarization (0=vertical, 1=horizontal, or
!                                  0 to 1=mix of V and H)
!     nuchan: satellite channel numbers
!     nusat:  satellite numbers
!     itype:  0=IR channel, 1=microwave channel
!     wvnum: wavenumber in cm**-1

  real(fp_kind),dimension(jpch):: varch,polar

  integer,dimension(jppf*jpchus):: kchan,kochan,kprof
  integer,dimension(jpchus,jppf):: indexn
  integer,dimension(jppf):: isflg
  integer,dimension(jppf):: lndsea,nadir,knchan
  integer,dimension(iint,jppf):: idiagbuf
  integer,dimension(55):: kidsat,kidsat1,nsat1
  integer,dimension(jpch):: nuchan,nusat,itype,mchannel,ifactq
  integer,dimension(0:jpch):: iuse,iouse
  integer,dimension(jpchus):: icx,iochan
  integer,dimension(jpchus):: ich

  character(10),dimension(50)::sattype
  character(10) obstype


  logical hirs2,msu,goes,hirs3,amsua,amsub,airs,eos_amsua,hsb,goesimg
  logical,dimension(jpchus,jppf):: kuse
  logical,dimension(jppf):: keep,coast,land,ice
  logical delt,first,diagsave
  logical ifirst(1000)

  real(fp_kind),allocatable,dimension(:,:)::data_s
  real(fp_kind),allocatable,dimension(:)::weight_s


!
!
! Initialize variables and constants.
  delt = deltat > 0.
  first = jiter == 1
  diagsave = first .and. idiag_rad
  nsig2    = 2*nsig
  nsigx    = 3*nsig
  nsigx1   = 3*nsig+1
  nstats   = 6+2*(npred+1)
  dg2rad = atan(1.0)/45.0
  rad2dg = 1.0/dg2rad
  d1=.754
  d2=-2.265
  aivals = 0.0
  stats  = 0.0
  nsatdat_s=0
  nx=2*nlath; mype1=mype+1
  kidsat=0
  iuse(0)=-999
  constoz  = 604229. * 9.80665 * 21.4e-9
  fifty=50.0
  zero=0.0
  do n=1,nsig
    sigir(n)=10.*sigi(nsig-n+1)
    siglr(n)=10.*sigl(nsig-n+1)
    ccsig(n)=constoz/(sigi(n)-sigi(n+1))
  end do
!
!
! Set skin temperature and bias correction standard deviations
  varst  = sqrt(1.0)
  varprd = 1./sqrt(.1)

!
! Scale sigma layer 1 wind by 10m wind factor.  Currently, only use
! 6hr guess winds.  These winds are used in the emissivity calculation.
! At a later date, obtain 10m guess wind from time interpolated 3,6,9
! hour surface fields
  do j = 1,lon1+2
    do i = 1,lat1+2
!ibm* prefetch_for_store(w10fact(i,j))
     w10fact(i,j)=fact10(i,j)*sqrt(ggrid_g31(1,i,j,1)**2+& ! u.
                                   ggrid_g31(2,i,j,1)**2) ! v.
    end do
  end do


! Get satellite information
 call satinfo(nusat,nuchan,itype,iuse(1),ifactq,mchannel,varch,polar,wavenumber, &
      frequency,jpch,mype,mype_rad)
!
  rewind lunin

  if (diagsave) then
     open(4,file=diag_rad,form='unformatted')
     rewind 4
! Initialize/write parameters for satellite diagnostic file on
! first outer iteration.
     if(mype==0) then
        write(4) mype,iint,ireal,ipchan,jpchus
        write(6,*)'SETUPRAD:  write header record for mype=',&
             mype,iint,ireal,ipchan,jpchus,' ',diag_rad
     endif
  endif

!
!
!****************************************************************************
! MAIN LOOP OVER SATELLITES (ONE SATELLITE PLATFORM PER INPUT FILE)
!

  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 (nsat1(is) == 0) goto 135
!
     read(lunin,end=135) obstype,isat,nele,nobs                     

!
!    Initialize logical flags for satellite platform

     hirs2      = obstype == 'hirs/2'
     hirs3      = obstype == 'hirs/3'
     msu        = obstype == 'msu'
     goes       = obstype == 'goes'
     amsua      = obstype == 'amsua'
     amsub      = obstype == 'amsub'
     airs       = obstype == 'airs'
     hsb        = obstype == 'hsb'
     eos_amsua  = obstype == 'eos_amsua'
     goesimg    = obstype == 'goesimg'

     if(.not. (amsua     .or. amsub  .or. msu       .or.&
               hirs2     .or. hirs3  .or. goes      .or. &
               airs      .or. hsb    .or. eos_amsua .or. &
               goesimg))then
       read(lunin)
       go to 135
     end if

     if(obstype /= obstype_all(is) .or. is <= 5)then
       write(6,*)' error in setuprad ',is,obstype,obstype_all(is)
       call stop2(93)
     end if

!
!    Based on isat, set new satellite number
!
      
     kidsat(isz)=isat
     if(goes)kidsat(isz)=isat+50
     if(msu)kidsat(isz)=isat+200
     if(goesimg)kidsat(isz)=isat+250
     if(amsua)kidsat(isz)=isat+300
     if(eos_amsua)kidsat(isz)=isat+300
     if(amsub)kidsat(isz)=isat+400
     if(hsb)kidsat(isz)=isat+400
     if(airs)kidsat(isz)=isat+500
     
!    If AMSU-A data set channel indices for later use
     if (amsua .or. eos_amsua) then
        ich(1) = newchn(kidsat(isz),1,nusat,nuchan,jpch)
        ich(2) = newchn(kidsat(isz),2,nusat,nuchan,jpch)
        ich(3) = newchn(kidsat(isz),3,nusat,nuchan,jpch)
        ich(4) = newchn(kidsat(isz),4,nusat,nuchan,jpch)
        ich(5) = newchn(kidsat(isz),5,nusat,nuchan,jpch)
        ich(15)= newchn(kidsat(isz),15,nusat,nuchan,jpch)
     endif


     nchan=nele-10
     if (airs) then
        write(6,*) ' airs data currently not set up'
        read(lunin)                    
        go to 135
     end if
     if (nchan > jpchus) write(6,*)'WARNING*** on mype,is=',mype,is,&
        nchan,jpchus


     tnoise = 1.e10
     itoss = 1
     do jc=1,nchan
!
!    Load channel numbers into local array based on satellite type

        iochan(jc)=newchn(kidsat(isz),jc,nusat,nuchan,jpch)
!
!          Temporary fix for problems with NOAA 11 channel 9 coefficients
!          Use the coefficients from NOAA 14, channel 9.
!       if ((kidsat(isz) == 11) .and. (jc == 9) ) &
!            iochan(jc) = newchn(14,9,nusat,nuchan,jpch)
!
!    Set error instrument channels

        iouse(jc)=iuse(iochan(jc))
        if((iouse(jc) < 0 .and. .not. first) .or. iouse(jc) < -1) then
          tnoise(jc)=1.e10
        else
          tnoise(jc) = varch(iochan(jc))
        end if
        if (tnoise(jc) < 1.e4) itoss = 0
     end do
     if (itoss == 1) then
        if(mype == 0)write(6,*)'SETUPRAD:  all obs variance > 1e4.  do not use ',&
             'data from satellite is=',isat,obstype
        read(lunin)                    
        goto 135
     endif

     idiagbuf= 0
     diagbuf = 0.
     pred=0.0

!    Load data array for current satellite

     allocate(data_s(nele,nsat1(is)))
     allocate(weight_s(nsat1(is)))
     read(lunin) data_s,weight_s
     nblktot=(nsat1(is)-1)/jppf+1

!
!
!*****
!    PROCESS DATA IN BLOCKS OF JPPF

     do nblk = 1,nblktot

!
!        determine block of data to use

      nobs1  = 1 + (nblk-1)*jppf
      nobs2  = min(nobs1+jppf-1,nsat1(is))
      if (nobs2-nobs1+1 <= 0) then
        write(6,*)'setuprad:  nblk not consistent with nblktot ',nblk,nblktot
        goto 134
      end if

!
!        Initialize variables/arrays.
 
      tbc     = 0.
      tbcnob  = 0.
      bcor    = 0.
      emissav = 0.
      pems5   = 1.
      cld     = 0.


!    INITIAL PROCESSING OF SATELLITE DATA
!*****
!
!    Process data

     nsdata = 0
     do n = nobs1,nobs2

       nsdata=nsdata + 1

       if (nsdata>jppf .or. nsdata>nsat1(is)) &
            write(6,*)'setuprad:  ***error*** nsdata,jppf,nsat1(is)=',&
            nsdata,jppf,nsat1(is),is,n,nobs1,nobs2,' ',obstype,' ',&
            kidsat(isz)

!      reuse beginning of weight_s array.
       weight_s(nsdata)   = weight_s(n)
       aivals(1,isz) = aivals(1,isz) + weight_s(nsdata)
!      Extract analysis relative observation time.
       stfact(nsdata) = data_s(2,n)/deltat
!  temporary
       if (airs .or. eos_amsua .or. hsb) stfact(nsdata) = 0.
!      Extract lon and lat.
       cenlat(nsdata) = data_s(3,n)*rad2dg                       
       slats(nsdata) = data_s(3,n)                        
       cenlon = data_s(4,n)*rad2dg                         
       slons(nsdata) = data_s(4,n)                       
       zasat(nsdata)  = data_s(5,n)
       cosza(nsdata)  = cos(zasat(nsdata))

       xpath(nsdata)     = 1./cosza(nsdata) ! view angle path factor

       if(goesimg)then
         panglr(nsdata) = 0.
         cld(nsdata) = data_s(6,n)
       else
         panglr(nsdata) = data_s(6,n)
       end if
!      Extract nadir (scan step position)
       nadir(nsdata) = nint(data_s(7,n))
       pangs(nsdata)  = data_s(8,n)

       if (pangs(nsdata) <= 89.) then
          xpaths(nsdata) = 1./cos(pangs(nsdata)*dg2rad) ! solar path factor
       else             ! if sun near/below horizon,
          xpaths(nsdata) = 1.0e6 ! set to very large value
       endif

       sfchgt(nsdata) = data_s(9,n)

!      Set land/sea flag.  (sea=0, land=1)

       lndsea(nsdata)=nint(data_s(10,n))

        
!          Load channel data into work array.
       do i = 1,nchan
          btm(i,nsdata) = data_s(i+10,n)
       end do

!    Prepare for application of bias correction to simulated values.
!    Construct predictors for 1B radiance bias correction.

       pred(1,nsdata) = 0.01
       pred(2,nsdata) = .1*(xpath(nsdata)-1.)**2-.015
       pred(3,nsdata) = 0.0

!          Save data in diagnostic arrays.
       idiagbuf(1,nsdata) = kidsat(isz)
       idiagbuf(2,nsdata) = nchan
       idiagbuf(5,nsdata) = nadir(nsdata)
       diagbuf(1,nsdata)  = cenlat(nsdata)
       diagbuf(2,nsdata)  = cenlon
       diagbuf(3,nsdata)  = rad2dg*zasat(nsdata)
       diagbuf(5,nsdata)  = pangs(nsdata)
       diagbuf(8,nsdata)  = cld(nsdata)
       diagbuf(9,nsdata)  = pred(2,nsdata)
       diagbuf(12,nsdata) = weight_s(nsdata)

!       End of loop over obs
     end do
!

     aivals(3,isz)  = aivals(3,isz) + nsdata
!
!
     call gdcrdp(slats,nsdata,rlats,nx)
     call gdcrdp(slons,nsdata,rlons,nlon)
!
!    Interpolate model guess to observation locations
!
     call intrppx(nx,ggrid_g31,ggrid_g32,&
          stfact,sfct,w10fact,veg_type,veg_frac,soil_type,soil_temp, &
          soil_moi,sno,tropprs,tvp,qvp,pp,poz,zz,ts5,wsp10,vegtype5,vegf5,soiltype5, &
          soilt5,soilm5,snow5,trop5,&
          slats,slons,nlon,lat1,lon1,nsig,nsdata,delt,mype,npes)
     if (goes .or. airs .or. hsb .or. eos_amsua .or. goesimg) then
           do n = 1,nsdata
               sfchgt(n) = zz(n)
           end do
     endif

!
     coast  = .false.
     isflg = 0
     keep = .true.
     do n = 1,nsdata
!
!    Do some preliminary qc of the data.  Check for points covered
!        with ice/snow, land points, and coastal points.
!
        ix1 = slats(n)
        iy  = slons(n)
        ix1 = max(1,min(ix1,nx))
        ix  = ix1- istart(mype1)+2
        iy  = iy - jstart(mype1)+2
        if (iy<1)      iy = iy+nlon
        if (iy>lon1+1) iy = iy-nlon
        ixp = ix+1
        iyp = iy+1
        if (ix1==nx) ixp = ix

        if (lndsea(n) /= 1)then
           if (isli(ix,iy ) == 1 .or. isli(ixp,iy ) == 1 .or.&
               isli(ix,iyp) == 1 .or. isli(ixp,iyp) == 1) lndsea(n) = 1
        end if
!
!       Check for coastal (transition) points
        if (isli(ix,iy) /= isli(ixp,iy) .or.&
            isli(ix,iy) /= isli(ix ,iyp) .or.&
            isli(ix,iy) /= isli(ixp,iyp)) then
          coast(n) = .true.
          if(isli(ix,iy ) == 1 .or. isli(ixp,iy ) == 1 .or. &
             isli(ix,iyp) == 1 .or. isli(ixp,iyp) == 1) lndsea(n)=1
        end if
!
!       Check for snow of sea ice in surrounding grid box

        if(isli(ix,iy ) == 2 .or. isli(ixp,iy ) == 2 .or. &
           isli(ix,iyp) == 2 .or. isli(ixp,iyp) == 2) isflg(n)=1
        if(isflg(n) /= 1)then
           if(sno(ix ,iy ) > 1. .and. isli(ix ,iy ) /= 0) isflg(n)=1
           if(sno(ixp,iy ) > 1. .and. isli(ixp,iy ) /= 0) isflg(n)=1
           if(sno(ix ,iyp) > 1. .and. isli(ix ,iyp) /= 0) isflg(n)=1
           if(sno(ixp,iyp) > 1. .and. isli(ixp,iyp) /= 0) isflg(n)=1
        end if
        land(n) = lndsea(n) == 1
        ice(n)  = isflg(n) == 1
        

!
!    Initial QC of data.  Set keep to false if we don't want the data.
!    The qc tests screen data over land, snow/ice, and coastal points.

!       Toss obs over land
        if (land(n)) then
           keep(n) = .false.
           aivals(4,isz)   = aivals(4,isz) + weight_s(n)
        end if
        if (ice(n)) then
!
!       Toss obs over snow or ice
           keep(n) = .false.
           aivals(5,isz) = aivals(5,isz) + weight_s(n)
        end if
        if (coast(n)) then
!
!       Toss obs over coastal points
           keep(n) = .false.
           aivals(6,isz)  = aivals(6,isz) + weight_s(n)
        end if
        if (hirs2 .or. goes .or. hirs3) then
!
!    GROSS QC Check.  Compare HIRS and GOES channel 8 with sst.  If the
!    difference is too large, flag the observation as "bad".

           ch8flg = btm(8,n) - ts5(n)
           ch8ch10= btm(8,n) - btm(10,n)
           if(kidsat(isz) == 11)ch8flg=ch8flg-2.19955+1.28578*ch8ch10
           if(kidsat(isz) == 14)ch8flg=ch8flg-2.61089+1.32519*ch8ch10
           if(kidsat(isz) == 15)ch8flg=ch8flg-1.85483+1.30573*ch8ch10
           if(kidsat(isz) == 16)ch8flg=ch8flg-1.85483+1.30573*ch8ch10
           if(kidsat(isz) == 58)ch8flg=ch8flg-2.09303+.277606*ch8ch10
           if(kidsat(isz) == 60)ch8flg=ch8flg-4.22641+.331097*ch8ch10
           if (abs(ch8flg) > 8.) then
              keep(n) = .false.
              aivals(10,isz)  = aivals(10,isz) + weight_s(n)
           endif
        endif
!
!    Now load/compute values for model levels

        snow5(n)=min(snow5(n),fifty)
        pp(n) = exp(pp(n))
        do l = 1,nsig
           pin5(l,n)  = sigir(l)*pp(n)
           prsr5(l,n) = siglr(l)*pp(n)
        end do
        do l = 1,nsig
           temp5(l,n) = tvp(nsig-l+1,n)/(1.+.61*qvp(nsig-l+1,n))
           sph        = max(zero,qvp(nsig-l+1,n))
           wmix5(l,n) = 1000.*sph/(1.-sph)
           omix5(l,n) = max(zero,poz(nsig-l+1,n)*604229.)
         end do
!
!       Save data in diagnostic arrays 
         idiagbuf(3,n)= lndsea(n)
         idiagbuf(4,n)= isflg(n)
         diagbuf(4,n) = ts5(n)
         diagbuf(6,n) = sfchgt(n)
         diagbuf(7,n) = zz(n)
         diagbuf(13,n)= trop5(n)

!
!    End loop over obs
     end do

!
!
!
!*****
!    IDENTIFY CHANNELS TO PROCESS
!*****
!     
!    Load arrays used by forward model to indicate which 
!    profiles and which channels to compute radiances for.
!
!    The tests below screen from the dataset those profiles/
!    channels which are not used (as of 3 Dec 01).
!
     kchan  = 0
     kochan = 0
     kprof  = 0
     knchan = 0
     errf   = 0.0
     varinv = 1.e-12
     kuse   = .false.
!
!    1B HIRS and GOES:  retain all channels over water
!                over land, retain channels 2-5, 12.
!
     if (hirs2 .or. hirs3 .or. goes) then
       do j = 1,nsdata
         do jc = 1,nchan
           kuse(jc,j)=(keep(j) .or. jc <= 5 & 
            .or. jc == 12) .and. tnoise(jc) < 1.e4
         end do
       end do
     elseif(msu .or. amsua .or. eos_amsua .or. amsub .or. hsb .or. goesimg)then
       do j = 1,nsdata
          do jc = 1,nchan
!
!    retain all data, provided assigned channel error
!           is "small"

           kuse(jc,j)= tnoise(jc) < 1.e4
          end do
       end do
     endif
     knchpf = 0
     indexn = 0
     do j = 1,nsdata
       kcount = 0
       do jc = 1,nchan
         if(kuse(jc,j))then
            kcount           = kcount+1
            knchpf           = knchpf+1
            kchan(knchpf)    = iochan(jc)
            kochan(knchpf)   = jc
            kprof(knchpf)    = j
            varinv(jc,j)     = 1.0/tnoise(jc)**2
            errf(jc,j)       = tnoise(jc)
            indexn(kcount,j) = knchpf
         endif
       end do
       knchan(j) = kcount
     end do
     if (knchpf < 1) go to 130

!
!    Compute surface emissivity for observation
!

     call emiss(knchpf,kprof,kchan,kochan,wsp10,zasat,panglr,&
          isflg,lndsea,emissav,pems5,ts5,soiltype5,soilt5, &
          soilm5,vegtype5,vegf5,snow5,polar,frequency,mchannel, &
          itype,nsdata,jppf,jpch,jpchus)

!
!    call radiative transfer (forward) model
!

     call rad_tran_k(pin5,prsr5,temp5,wmix5,omix5,ts5,&
          pems5,xpath,xpaths,knchan,kchan,ptau5,ptbcl5, &
          temp,wmix,omix,ts,pems, &
          itype,nsig,jpch,knchpf,nsdata)

!
!*****
!     COMPUTE AND APPLY BIAS CORRECTION TO SIMULATED VALUES
!*****

!    Compute predictor for AMSU-A cloud liquid water bias correction.

     do i=1,knchpf
       n=kprof(i)
       tbcnob(kochan(i),n) = ptbcl5(i)
       tbc(kochan(i),n) = ptbcl5(i) + cbias(nadir(n),kchan(i))
     end do
     if (amsua .or. eos_amsua) then
        do n=1,nsdata
           dqval(n)=0.0
           if (tbc(1,n)<=284. .and. tbc(2,n)<=284. .and. keep(n)) &
                dqval(n)=d1*(tbc(1,n)-btm(1,n))/(285.-tbc(1,n))+ &
                         d2*(tbc(2,n)-btm(2,n))/(285.-tbc(2,n))


           if (btm(1,n)<0. .or. btm(2,n)<0.) then
              dqval(n)=0.0
              varinv(1,n)=0.0
              varinv(2,n)=0.0
              varinv(3,n)=0.0
              varinv(4,n)=0.0
              varinv(5,n)=0.0
              varinv(6,n)=0.0
              varinv(7,n)=0.0
              varinv(15,n)=0.0
           endif
           pred(3,n) = dqval(n)*cosza(n)*cosza(n)
        end do
     endif

!   Perform bias correction

     do i=1,knchpf
        n=kprof(i)
        m=kochan(i)
        mm=kchan(i)
        tlapchn(m,n)= .01*(ptau5(nsig-1,i)-ptau5(nsig,i))* &
            (ts5(n)-temp5(nsig-1,n))
        do l=2,nsig-1
          tlapchn(m,n)=tlapchn(m,n)+&
              .01*(ptau5(l-1,i)-ptau5(l,i))*(temp5(l+1,n)-temp5(l-1,n))
        end do
        tlap = tlapchn(m,n)-tlapmean(mm)
        sum = tlap*(predx(mm,npred)+tlap*predx(mm,npred-1))
        bcor(1,m,n) = cbias(nadir(n),mm)          !global_satangbias
        bcor(2,m,n) = tlap*predx(mm,npred)        !tlap
        bcor(3,m,n) = tlap*tlap*predx(mm,npred-1) !tlap*tlap
        do j = 1,npred-2
           term = predx(mm,j)*pred(j,n)
           sum  = sum + term
           bcor(j+3,m,n) = term
        end do
        tbc(m,n) = tbc(m,n) + sum
     end do
!
!     
!
!******
!     QC OBSERVATIONS BASED ON VARIOUS CRITERIA
!             Separate blocks for various instruments.
!******
!
!
!    QC HIRS/2, GOES, HIRS/3 data
!
     if (hirs2 .or. goes .or. hirs3 .or. airs) then

     !default channel numbers
        ichan8  = 8
        ichan18 = 18
        ichan12 = 12
        ichan4  = 4
        ichan5  = 5

        ! use proxy channels for AIRS
        !============================
        if (airs) then
          ichan8  = 8
          ichan18 = 18
          ichan12 = 12
          ichan4  = 4
          ichan5  = 5
        endif

!     
!       Loop over observations.
        do n = 1,nsdata
           efact   = 1.
           vfact   = 0.25
           efactir = 1.
           vfactir = 1.
           efacts  = 1.
           vfacts  = 1.
           vfact2  = 1.0
           vfact3  = 1.0
           vfact4  = 1.0
!
!          Apply window check.  Toss obs if fail window test.
           ch4flg  = btm(ichan4,n) - tbc(ichan4,n)
           ch5flg  = btm(ichan5,n) - tbc(ichan5,n)
           ch8flg  = btm(ichan8,n) - tbc(ichan8,n)
           ch12flg = btm(ichan12,n)- tbc(ichan12,n)
           ch18flg = btm(ichan18,n)- tbc(ichan18,n)
           demisf  = .01
           dtempf  = .5
!     
!             Cloud test for channel 2
           if (ch4flg < -20.0) then
              vfact2  = 0.0
              vfact3  = 0.0
              vfact4  = 0.0
              vfactir = 0.0
              aivals(11,isz)   = aivals(11,isz) + weight_s(n)

           else if (ch4flg < -1.0) then
!
!           Cloud test for channel 3

              vfact3  = 0.0
              vfact4  = 0.0
              vfactir = 0.0
              aivals(12,isz)   = aivals(12,isz) + weight_s(n)
           else if(abs(ch4flg) > 1.0 .or. abs(ch5flg) > 1.0)then
              vfact4  = 0.0
              vfactir = 0.0
              aivals(13,isz) = aivals(13,isz) + weight_s(n)

           else if (ch12flg < -10.0)then  !ch12 sees cloud
              vfactir = 0.0
              vfact4 = 0.0
              aivals(14,isz) = aivals(14,isz) + weight_s(n)

!           Channel 8 cloud test
!            + chan 18 cloud test?

           else if (abs(ch8flg) > 1.0 .or. .not. keep(n))then
!             .or. (pangs(n) > 85. .and. abs(ch18flg) > 2.0) )then
!test
!test
              vfactir = 0.0
              if(keep(n))aivals(15,isz) = aivals(15,isz) + weight_s(n)
           end if
!
!          Reduce qc bounds in tropics
           if ( (cenlat(n) > -25.) .and.&
                (cenlat(n) <  25.) ) then
              aivals(7,isz) = aivals(7,isz) + weight_s(n)
              efact   = (abs(cenlat(n))*.5/25.+.5)*efact
           endif
!
!          Reduce weight given to obs for shortwave ir if 
!          solar zenith angle small
           if (pangs(n) <= 60. ) then
              vfacts = .5*vfacts
              efacts = .5*efacts
           endif
           if(ice(n))then
             demisf = .01
             dtempf = 3.0
           else if(land(n))then
             demisf = .01
             dtempf = 2.0
           end if
!
!     
!          Reduce weight for obs over higher topography
           if (sfchgt(n) > 2000.) then
              fact    = 2000./sfchgt(n)
              efactir = fact*efactir
              vfact4  = fact*vfact4
!             if(sfchgt(n) > 2000)then
!               vfact4 = 0.0
!             end if
!              write(6,*)'qc:  height=',mype,n,sfchgt(n),fact,efactif
           endif
!     
!          Reduce weight if model and obs topography too different
           if (abs(zz(n)-sfchgt(n)) > 200.) then
              fact    = 200./abs(zz(n)-sfchgt(n))
              efactir = fact*efactir
              vfact4  = fact*vfact4
              aivals(8,isz)   = aivals(8,isz) + weight_s(n)
           endif
!     
!
!
!             Generate q.c. bounds and modified variances.
           do ll=1,knchan(n)
              l = kochan(indexn(ll,n))
              varinv(l,n)=vfact*varinv(l,n)
              errf(l,n)=3.*efact*errf(l,n)
   
!             Channel 2 test

              if (l == 2) then

                 varinv(l,n) = vfact2*varinv(l,n)
!
!                Channel 3 test

              else if (l == 3) then

                 varinv(l,n) = vfact3*varinv(l,n)

!                Channel 4 and Channel 12 test

              else if (l == 4 .or. l == 12) then

                 varinv(l,n) = vfact4*varinv(l,n)

              else if (l /= 1)then
!
!             Channels 4 and above
                 errf(l,n)   = efactir*errf(l,n)
                 varinv(l,n) = vfactir*varinv(l,n)
                 if (l >= 13) then
                    errf(l,n)   = efacts*errf(l,n)
                    varinv(l,n) = vfacts*varinv(l,n)
                 end if
              end if
              dtbf = demisf*abs(pems(indexn(ll,n)))+dtempf*abs(ts(indexn(ll,n)))
              term = dtbf*dtbf
              if (varinv(l,n)>1.e-12 .and. term>1.e-12) &
                   varinv(l,n)=1./(1./varinv(l,n)+term)

!             emix=abs(pems(indexn(ll,n)))
!             if(emix > .3 .and. (land(n) .or. ice(n) &
!                ) .and. varinv(l,n) > 1.e-9)then
!             print *,' emiss ',l,ll,emix,lndsea(n),isflg(n)
!             varinv(l,n)=0.0
!             end if

           end do
!
!
!       End of loop over observations.
        end do
!
!    End of HIRS and GOES QC blocks

!
!
!    QC MSU data
     else if (msu) then
!
!       Loop over observations.
        do n = 1,nsdata
           efact   = 1.
           vfact   = 0.25
           efactmc = 1.
           efact21 = 1.
           efact22 = 1.
           vfactmc = 1.
           vfact21 = 1.
           vfact22 = 1.
!
!          Reduce qc bounds in tropics
           if ( (cenlat(n) > -25.) .and.&
                (cenlat(n) <  25.) ) then
              aivals(7,isz) = aivals(7,isz) + weight_s(n)
              efact   = (abs(cenlat(n))*.5/25.+.5)*efact
           endif
           demisf = .015
           dtempf = 0.5
!
!          Reduce q.c. bound over land
           if (land(n)) then
!             efact22 = 0.0
!             vfact22 = 0.0
              demisf = .03
              dtempf = 2.5
           end if
           if (coast(n)) then
!             efact22 = 0.0
!             vfact22 = 0.0
              demisf = .20
              dtempf = 4.5
           end if
!
!          Over water apply window test to channel 2 using channel 1
           if (.not. land(n) .or. coast(n)) then
              if (abs(btm(1,n) - tbc(1,n)) > 5.0) then
                 efact22 = 0.0
                 vfact22 = 0.0
                 aivals(10,isz)   = aivals(10,isz) + weight_s(n)
              endif
           endif
!
!          Reduce q.c. bound for likely snow or ice
           if (ice(n)) then
!             efact22 = .5*efact22
!             vfact22 = .5*vfact22
              demisf = .05
              dtempf = 3.0
           end if
!
!
!          Reduce q.c. bounds over higher topography
           if (sfchgt(n) > 2000.) then
              fact = 2000./sfchgt(n)
              efactmc = fact*efactmc
              vfactmc = fact*vfactmc
           end if
!     
!          Reduce q.c. bounds if model and obs topography 
!          too different.
           if (abs(zz(n)-sfchgt(n)) > 200.) then
              fact = 200./abs(zz(n)-sfchgt(n))
              efactmc = fact*efactmc
              vfactmc = fact*vfactmc
              aivals(8,isz)   = aivals(8,isz) + weight_s(n)
           end if
!     
!          Generate q.c. bounds and modified variances.
           errf(1,n) = efactmc*efact21*errf(1,n)
           errf(2,n) = efactmc*efact22*errf(2,n)
           errf(3,n) = 2.0*efactmc*errf(3,n)
           errf(4,n) = 2.0*errf(4,n)
           varinv(1,n) = vfactmc*vfact21*varinv(1,n)
           varinv(2,n) = vfactmc*vfact22*varinv(2,n)
           varinv(3,n) = vfactmc*varinv(3,n)
           varinv(4,n) = vfactmc*varinv(4,n)
           do ll=1,knchan(n)
              l = kochan(indexn(ll,n))
              errf(l,n)   = 3.*efact*errf(l,n)
              varinv(l,n) = vfact*varinv(l,n)
              emix=abs(pems(indexn(ll,n)))
              dtbf = demisf*abs(pems(indexn(ll,n)))+dtempf*abs(ts(indexn(ll,n)))
              term = dtbf*dtbf
              if (varinv(l,n)>1.e-12 .and. term>1.e-12) &
                   varinv(l,n)=1./(1./varinv(l,n)+term)

              if(l == 1)diagbuf(9,n) = dtbf
              if(l == 2)diagbuf(10,n) = dtbf
              if(l == 3)diagbuf(11,n) = dtbf
!             if(emix > .3 .and. (land(n) .or. ice(n) &
!                ) .and. varinv(l,n) > 1.e-9)then
!             print *,' emiss msu',l,ll,emix,lndsea(n),isflg(n)
!             varinv(l,n)=0.0
!             end if
           end do
!     
!       End of loop over observations.
        end do
!
!    End of MSU QC block
!
!
!    QC AMSU-A data
     else if (amsua .or. eos_amsua) then

!       Loop over observations.
        do n = 1,nsdata
          if(knchan(n) > 0)then 
           bcbtm1=btm(1,n)  -cbias(nadir(n),ich(1))
!          bcbtm2=btm(2,n)  -cbias(nadir(n),ich(2))
!          bcbtm15=btm(15,n)-cbias(nadir(n),ich(15))
           ch1dbc=btm(1,n)-tbc(1,n)
           ch2dbc=btm(2,n)-tbc(2,n)
           ch4dbc=btm(4,n)-tbc(4,n)
           ch6dbc=btm(6,n)-tbc(6,n)
           ch15dbc=btm(15,n)-tbc(15,n)
!          sval=-113.2+(2.41-.0049*bcbtm1)*bcbtm1+.454*bcbtm2-bcbtm15
           dsval=(2.41-.0098*bcbtm1)*ch1dbc+.454*ch2dbc-ch15dbc

!          factch6x=((sval-5.)/10.)**2+(ch6dbc/.8)**2
           factch6=(dsval/10.)**2+(ch6dbc/.8)**2
           factch4=(cosza(n)*dqval(n)/.3)**2+(ch4dbc/1.8)**2

!          QC based on ratio of obs-ges increment versus the sensitivity of
!          the simulated brightness temperature to the surface emissivity
!          Y2K hurricane season runs by QingFu Liu found the hurricane
!          forecast tracks to be degraded without this QC.
!
           dtde1 = pems(indexn(1,n))
           de1   = 0.
           if (dtde1 /= 0.) de1=abs((btm(1,n)-tbcnob(1,n))/dtde1)
           dtde2 = pems(indexn(2,n))
           de2   = 0.
           if (dtde2 /= 0.) de2=abs((btm(2,n)-tbcnob(2,n))/dtde2)
           dtde3 = pems(indexn(3,n))
           de3   = 0.
           if (dtde3 /= 0.) de3=abs((btm(3,n)-tbcnob(3,n))/dtde3)
           diagbuf(8,n)  = factch4
!          diagbuf(9,n)  = de1  
!          diagbuf(10,n) = de2
!          diagbuf(11,n) = de3


           efact   = 1.0
           efact6  = 1.0
           efact7  = 1.0
           efactmc = 1.0
           vfact   = 1.0
           vfact6  = 1.0
           vfact7  = 1.0
           vfactmc = 1.0
           demisf = .01
           dtempf = .5

           if (ice(n)) then

!          Decrease likelyhood of using data over snow and ice

              demisf = .05
              dtempf = 3.0
           else if(land(n))then
!
!          Decrease likelyhood and weight of data over land

              demisf = .02
              dtempf = 2.0
           end if
!
!          Reduce qc bounds in tropics
           if ( (cenlat(n) > -25.) .and.&
                (cenlat(n) <  25.) ) then
              aivals(7,isz) = aivals(7,isz) + weight_s(n)
              efact   = (abs(cenlat(n))*.25/25.+.75)*efact
           endif
!
           if(factch6 >= 1. .or. coast(n))then
             efactmc=0.0
             vfactmc=0.0
             efact6=0.0
             vfact6=0.0
             if(.not. coast(n))aivals(11,isz) = aivals(11,isz) + weight_s(n)

           else if (factch4 > 1. .or. de2 > .03 .or.  &
                 de3 > .05 .or. de1 > .05) then
!
              efactmc=0.0
              vfactmc=0.0
              if(.not. coast(n) .and. factch4 > 1.) &
                     aivals(10,isz) = aivals(10,isz) + weight_s(n)
           else if (abs(zz(n)-sfchgt(n)) > 200.) then
!      
!          Reduce q.c. bounds if model and obs topography 
!          too different.

              fact = 200./abs(zz(n)-sfchgt(n))
              efactmc = fact*efactmc
              vfactmc = fact*vfactmc
              aivals(8,isz)   = aivals(8,isz) + weight_s(n)
           end if
           if (sfchgt(n) > 2000.) then
!
!          Reduce q.c. bounds over higher topography

              fact = 2000./sfchgt(n)
              efactmc = fact*efactmc
              efact6 = fact*efact6
              vfactmc = fact*vfactmc
              vfact6 = fact*vfact6
              if(sfchgt(n) > 4000.)then
                fact = 4000./sfchgt(n)
                efact7 = fact*efact7
                vfact7 = fact*vfact7
              end if
           end if

!
!          Generate q.c. bounds and modified variances.
           do ll=1,knchan(n)
              l = kochan(indexn(ll,n))
              errf(l,n)   = 3.*efact*errf(l,n)
              varinv(l,n) = vfact*varinv(l,n)
              if(l <= 5 .or. l == 15)then

!          Adjust observation error based on magnitude of liquid water correction
!                  0.2 is empirical factor

                 cor=0.2*(predx(ich(l),3)*pred(3,n))**2
                 varinv(l,n) = varinv(l,n)/(1.+varinv(l,n)*cor)

                 errf(l,n)   = efactmc*errf(l,n)
                 varinv(l,n) = vfactmc*varinv(l,n)
              else if(l == 6)then
                 errf(l,n)=efact6*errf(l,n)
                 varinv(l,n) = vfact6*varinv(l,n)
              else if(l == 7)then
                 errf(l,n)=efact7*errf(l,n)
                 varinv(l,n) = vfact7*varinv(l,n)
              end if
              dtbf = demisf*abs(pems(indexn(ll,n)))+dtempf*abs(ts(indexn(ll,n)))
              term = dtbf*dtbf
              if (varinv(l,n)>1.e-12 .and. term>1.e-12) &
                   varinv(l,n)=1./(1./varinv(l,n)+term)

!             if(l == 3)diagbuf(8,n) = dtbf
              if(l == 4)diagbuf(9,n) = dtbf
              if(l == 5)diagbuf(10,n) = dtbf
              if(l == 6)diagbuf(11,n) = dtbf
                
              if ( (l <= 5 .or. l == 15) .and. &
                   (varinv(l,n)<1.e-9) ) pred(3,n) = 0.0

           end do
          end if
!     
!       End of loop over observations.
        end do
!
!    End of AMSU-A QC block
!
!    QC AMSU-B data

     else if (amsub .or. hsb) then
!
!       Loop over observations.
        do n = 1,nsdata
         if(knchan(n) > 0)then
           ch1diff=btm(1,n)-tbc(1,n)
           ch2diff=btm(2,n)-tbc(2,n)
           efact   = 1.0
           efactmc = 1.0
           vfact   = 1.0
           vfactmc = 1.0
           if(land(n))then
            dsi=0.85*ch1diff-ch2diff
            si=42.72+0.85*btm(1,n)-btm(2,n)
            demisf = .03
            dtempf = 2.0
            else
            dsi=999.
            if(btm(2,n) < 300.)then
             dsi=0.13*(ch1diff-33.58*ch2diff/(300.-btm(2,n)))
            end if
            si=42.72+0.85*ch1diff-ch2diff
            demisf = .015
            dtempf = 0.5
           end if
           if(ice(n))then
            demisf = .05
            dtempf = 3.0
           end if
           if(coast(n))then
            demisf = .25
            dtempf = 5.0
           end if
           diff1=ch1diff-7.5*dsi
           fact1=(diff1/10.)**2+(dsi/1.)**2
           diagbuf(9,n) = diff1
           diagbuf(10,n) = dsi
           diagbuf(11,n) = fact1
!
!          Reduce q.c. bounds over higher topography
           if (sfchgt(n) > 2000.) then
              fact = 2000./sfchgt(n)
              efactmc = fact*efactmc
              vfactmc = fact*vfactmc
           end if
!     
!          Reduce q.c. bounds if model and obs topography 
!          too different.
           if (abs(zz(n)-sfchgt(n)) > 200.) then
              fact = 200./abs(zz(n)-sfchgt(n))
              efactmc = fact*efactmc
              vfactmc = fact*vfactmc
              aivals(8,isz)   = aivals(8,isz) + weight_s(n)
           end if

           if(fact1 > 1.)then
            efactmc=0.0
            vfactmc=0.0
            if(coast(n))aivals(10,isz) = aivals(10,isz) + weight_s(n)
           else
            efact = (1.-fact1*fact1)*efact
            vfact = (1.-fact1*fact1)*vfact
           end if
!     
!          Generate q.c. bounds and modified variances.
           do ll=1,knchan(n)
              l = kochan(indexn(ll,n))
              errf(l,n)   = 3.*efact*efactmc*errf(l,n)
              varinv(l,n) = vfact*vfactmc*varinv(l,n)
              dtbf = demisf*abs(pems(indexn(ll,n)))+dtempf*abs(ts(indexn(ll,n)))
              term = dtbf*dtbf
              if (varinv(l,n)>1.e-12 .and. term>1.e-12) &
                   varinv(l,n)=1./(1./varinv(l,n)+term)

           end do
!     
        end if
!       End of loop over observations.
        end do
!
!    End of AMSU-B QC block
!
!    GOES imager Q C
!
     else if(goesimg)then
!       Loop over observations.
        do n = 1,nsdata

         ch4diff  = btm(4,n) - tbcnob(4,n)
         ch5diff  = btm(5,n) - tbcnob(5,n)
         ch2diff  = btm(2,n) - tbcnob(2,n)
         ch3diff  = btm(3,n) - tbcnob(3,n)

         if(knchan(n) > 0)then
           efact = 1.0
           vfact = 1.0
           fact45 = 1.0
           fact2 = 1.0
           fact3 = 1.0
           demisf = .01
           dtempf = 0.5
           if(land(n))then
            fact45=0.
            fact2=0.
            if(cld(n) <40.0 ) fact3=0.0
            demisf = .01
            dtempf = 2.0
           end if
           if(ice(n))then
            fact45=0.
            fact2=0.
            fact3=0.0
            demisf = .02
            dtempf = 3.0
           end if
           if(coast(n))then
            fact45=0.
            fact2=0.
            fact3=0.0
            demisf = .02
            dtempf = 5.0
           end if
!
!    
!          Reduce weight for obs over higher topography

!           if(rad2dg*zasat(n) >60.)then
!              vfact=0.
!              aivals(10,isz)= aivals(10,isz) + weight_s(n)
!           end if
           if (sfchgt(n) > 2000.) then
              fact    = 2000./sfchgt(n)
              efact   = fact*efact
              vfact   = fact*vfact
              aivals(11,isz)= aivals(11,isz) + weight_s(n)
!             if(sfchgt(n) > 2000)then
!               vfact4 = 0.0
!             end if
!              write(6,*)'qc:  height=',mype,n,sfchgt(n),fact,efactif
           end if

           if( ch4diff <-3.6 .or. ch5diff <-3.6  ) then
              fact3=0.0
              aivals(13,isz)=aivals(13,isz)+weight_s(n)
           end if

           if (ch4diff >= -3.6 .and. ch4diff <-3.0) then
              if(ch3diff <0.0 ) then
                 fact3=0.0
                 aivals(13,isz)=aivals(13,isz)+weight_s(n)
              end if
           end if

           if (ch5diff >= -3.6 .and. ch5diff <-3.0) then
              if(ch3diff <0.0 ) then
                 fact3=0.0
                 aivals(13,isz)=aivals(13,isz)+weight_s(n)
              end if
           end if
!  end of channel 3 quality control

          if(ch4diff <-3.0 .or. ch4diff > 5.0 .or.ch5diff <-3.0 .or. ch5diff > 5.0)then
              fact45 = 0.
              aivals(14,isz)= aivals(14,isz) + weight_s(n)
           end if
           if(pangs(n) >= 90. )then
             if(ch2diff < -2.5)then
              fact2 = 0.
              aivals(12,isz)= aivals(12,isz) + weight_s(n)
             end if
           else
             fact2 = 0.
           end if

!    
!          Generate q.c. bounds and modified variances.
           do ll=1,knchan(n)
              l = kochan(indexn(ll,n))
              errf(l,n)   = 3.*efact*errf(l,n)
!              if(l == 3) write(99,*) 'GOESIMG:errf=',errf(l,n),efact,l
              varinv(l,n) = vfact*varinv(l,n)
              if(l == 4 .or. l == 5)varinv(l,n) = fact45*varinv(l,n)
              if(l == 2)varinv(l,n) = fact2*varinv(l,n)
              if(l == 3) varinv(l,n) = fact3*varinv(l,n)
              dtbf = demisf*abs(pems(indexn(ll,n)))+dtempf*abs(ts(indexn(ll,n)))
              term = dtbf*dtbf
              if (varinv(l,n)>1.e-12 .and. term>1.e-12) &
              varinv(l,n)=1./(1./varinv(l,n)+dtbf**2)
              if(l == 3)diagbuf(7,n) = sum
              if(l == 3)diagbuf(9,n) = cbias(nadir(n),65)
              if(l == 3)diagbuf(10,n) = pems(indexn(ll,n))
              if(l == 3)diagbuf(11,n) = ts(indexn(ll,n))
           end do

     
        end if
!       End of loop over observations.
        end do

     end if
!
!
!
!    Apply gross check to observations.  Toss obs failing test.
     do k = 1,knchpf
        if (varinv(kochan(k),kprof(k)) > 1.e-6) then
           drad = abs(btm(kochan(k),kprof(k)) - tbc(kochan(k),kprof(k)))
!
!          If mean obs-ges difference around observations
!          location is too large and difference at the 
!          observation location is similarly large, then
!          toss the observation.

           if (drad > errf(kochan(k),kprof(k)) ) then
              varinv(kochan(k),kprof(k)) = 0.
              stats(2,kchan(k)) = stats(2,kchan(k)) + weight_s(kprof(k))
              aivals(9,isz) = aivals(9,isz) + weight_s(kprof(k))
           end if
!
        end if
     end do
     if(amsua .or. amsub .or. msu .or. hsb)then
       if(amsua .or. eos_amsua)nlev=6
       if(amsub)nlev=5
       if(hsb)nlev=4
       if(msu)nlev=4
       do n = 1, nsdata
         kval=0
         do k=2,nlev
           if(varinv(k,n) < 1.e-6)then
             kval=k-1
             if(amsub .or. hsb)kval=nlev
           end if
         end do
         if(kval > 0)then
           do k=1,kval
             varinv(k,n)=0.
           end do
           if(amsua)varinv(15,n)=0.
         end if
       end do
     end if
     do k = 1,knchpf
        n = kprof(k)
        mm = kochan(k)
        if (varinv(mm,n) > 1.e-6) then
!
!             Accumulate data for diagnostic print.

          drad = btm(mm,n) - tbc(mm,n)
          dradnob = btm(mm,n) - tbcnob(mm,n)
          varrad = drad*varinv(mm,n)

          m = kchan(k)

          if (iuse(m) == 1)aivals(2,isz) = aivals(2,isz) + drad*varrad*weight_s(n)

          stats(1,m)  = stats(1,m) + weight_s(n)            !number of obs
          stats(3,m)  = stats(3,m) + drad*weight_s(n)       !obs-mod(w_biascor)
          stats(4,m)  = stats(4,m) + drad*drad*weight_s(n)  !(obs-mod(w_biascor))**2
          stats(5,m)  = stats(5,m) + drad*varrad*weight_s(n)!penalty contribution
          stats(6,m)  = stats(6,m) + dradnob* weight_s(n)   !obs-mod(w/o_biascor)

          do j=1,npred+1               !jj=7=global_satangbias.txt
                                       !jj=8=tlap,  jj=9=tlap*tlap
                                       !jj=10=mean, jj=11=xpath, jj=12=clw
             jj = j+6
             jjj=jj+6                  !jjj=jj+6 is square of jj term

             term = bcor(j,mm,n)
             stats(jj, m)= stats(jj, m) + term*weight_s(n)
             stats(jjj,m)= stats(jjj,m) + term*term*weight_s(n)

          end do

        endif
     end do
!
!
!******
!     CONSTRUCT SENSITIVITY VECTORS.  WRITE TO OUTPUT FILE.
!******
!
!    Generate o3, t, q, and ts sensitivity arrays.

     do n = 1,nsdata
        icc = 0

        onpp=1./pp(n)
        do i=1,nsig
          c1(i)=ccsig(i)*onpp
          c2(i)=1./(1.+.61*qvp(i,n))
          c3(i)=1000./(1.-qvp(i,n))**2
          c4(i)=.61*tvp(i,n)*c2(i)*c2(i)
        end do
        do k = 1,knchan(n)
           kk = indexn(k,n)
           j  = kochan(kk)
           jo = kchan(kk)

!          Only "good" obs are included in calculation.

           if (varinv(j,n) > 1.e-6 .and. iuse(jo)==1 ) then

              icc      = icc+1
              icx(icc) = jo
              var(icc) = varinv(j,n)
              rhssat(icc) = btm(j,n)-tbc(j,n)
              pred(npred-2+icc,n)=tlapchn(j,n)-tlapmean(jo)

              do i = 1,nsig
                htlto(i,icc) = temp(nsig-i+1,kk)*c2(i)
                htlto(nsig+i,icc) = c3(i)*wmix(nsig-i+1,kk) - c4(i)*temp(nsig-i+1,kk)
                htlto(nsig2+i,icc) = omix(nsig-i+1,kk)*c1(i)
              end do
              htlto(nsigx+1,icc) = ts(kk)

!             If we do not use channel 9, turn off ozone sensitivity in all channels.
              if ((hirs2 .or. goes .or. hirs3) .and. (varinv(9,n) < 1.e-6))then
                do i = 1,nsig
                  htlto(nsig2+i,icc) = 0.0
                end do
              endif

!             Reduce amplitude of q sensitivity above tropopause
              do i=1,nsig
                 if (pin5(i,n) < trop5(n)) then
                    term = (pin5(i,n)-trop5(n))/(trop5(n)-pin5(1,n))
                    htlto(nsig+i,icc) = exp(ifactq(jo)*term)*htlto(nsig+i,icc)
                 endif
              end do
!             

           end if

!       End loop over channels.
        end do
!
!   Load data into output arrays
        if (icc>0) then
           n1  = n1+1
           iy = slats(n)
           ix = slons(n)
           dx = slons(n) - ix
           dy = slats(n) - iy
           iy = min(max(1,iy),nx)
           ix = min(max(0,ix),nlon)
           dx1 = 1.0-dx
           dy1 = 1.0-dy
           iy = max(1,min(iy,nx))
           iy  = iy-istart(mype1)+2
           ix  = ix-jstart(mype1)+2
           if (ix < 1)        ix = ix + nlon
           if (ix > lon1 + 1) ix = ix - nlon
           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

!          Write data to output file
           write(lunout) j11,j21,j12,j22,wgt00,wgt10,wgt01,wgt11,icc,weight_s(n)
           write(lunout) (icx(m),m=1,icc),(var(m),m=1,icc),&
              (pred(m,n),m=1,npred+icc-2),(rhssat(m),m=1,icc),&
              ((htlto(m,nn),m=1,nsigx1),nn=1,icc)
!
        end if
        if (diagsave) then
!
!    Write diagnostics to output file.  Only generate
!    file on first outer iteration.

            do nn=1,nchan
               tmpvar(nn) = varinv(nn,n)
               if (iouse(nn)<1) tmpvar(nn)=-tmpvar(nn)
            end do
            write(4) mype,(idiagbuf(nn,n),nn = 1,iint),&
                   (diagbuf(nn,n),nn = 1,ireal),&
                   (float(nn),btm(nn,n),&
                   tbc(nn,n),tbcnob(nn,n),tmpvar(nn),&
                   emissav(nn,n),tlapchn(nn,n),nn=1,nchan)
        endif
!
!    End of loop over profiles
     end do

!
!
!    End of nblk loop
130  continue
     end do
!
!
!    Jump here when there is no more data to process for current satellite
 134 continue
     deallocate(data_s)
     deallocate(weight_s)
 135 continue
     nsatdat_s=nsatdat_s+n1

!
!
!
!*****
!    END MAIN LOOP OVER SATELLITES
!*****

  end do


! Close unit to diagnostic file.
  if (diagsave)close(4)

!
! Collect statistics
  call mpi_reduce(aivals,aivals1,15*nsat,mpi_rtype,mpi_sum,mype_rad,mpi_comm_world,ierror)
  call mpi_reduce(stats,stats1,nstats*jpch,mpi_rtype,mpi_sum,mype_rad,mpi_comm_world,ierror)
  call mpi_reduce(kidsat,kidsat1,nsat,mpi_integer,mpi_max,mype_rad,mpi_comm_world,ierror)


!    Compute and print statistics for current satellite.
  if(mype==mype_rad) then
   penalty_all=0.0
   do is=1,nsat
     obstype=sattype(is)
!
!    Initialize logical flags for satellite platform

     hirs2      = obstype == 'hirs/2'
     hirs3      = obstype == 'hirs/3'
     msu        = obstype == 'msu'
     goes       = obstype == 'goes'
     amsua      = obstype == 'amsua'
     amsub      = obstype == 'amsub'
     airs       = obstype == 'airs'
     hsb        = obstype == 'hsb'
     eos_amsua  = obstype == 'eos_amsua'
     goesimg    = obstype == 'goesimg'

     iobs2 = nint(aivals1(1,is))
     penalty_all=penalty_all+aivals1(2,is)
     if(iobs2 > 0)then

      iobs1 = nint(aivals1(3,is))
      iland   = nint(aivals1(4,is))
      isnoice = nint(aivals1(5,is))
      icoast  = nint(aivals1(6,is))
      ireduce = nint(aivals1(7,is))
      itopo   = nint(aivals1(8,is))
      ivarl   = nint(aivals1(9,is))
      igross  = nint(aivals1(10,is))


      if(hirs2 .or. hirs3 .or. goes .or. airs)then
       ich2    = nint(aivals1(11,is))
       ich3    = nint(aivals1(12,is))
       ich4    = nint(aivals1(13,is))
       ich12   = nint(aivals1(14,is))
       ich8    = nint(aivals1(15,is))
       write(iout_rad,2000) 'sat','type','num','numw','ich2','ich3', &
                            'ich4','ich8','ich12'
       write(iout_rad,2010) kidsat1(is),sattype(is),iobs1,iobs2,ich2,ich3, &
                            ich4,ich8,ich12
       write(iout_rad,2012) 'penalty','iland','isnoice','ireduce','icoast', &
                            'itopo','ivarl','igross'
       write(iout_rad,2011) aivals1(2,is),iland,isnoice,ireduce,icoast,itopo,ivarl,igross
      else if(msu)then
       ich21   = nint(aivals1(10,is))
       write(iout_rad,2000) 'sat','type','num','numw','ich21'
       write(iout_rad,2010) kidsat1(is),sattype(is),iobs1,iobs2,ich21
       write(iout_rad,2012) 'penalty','iland','isnoice','ireduce','icoast', &
                            'itopo','ivarl'
       write(iout_rad,2011) aivals1(2,is),iland,isnoice,ireduce,icoast,itopo,ivarl
      else if(amsua .or. eos_amsua)then
       iemiss = nint(aivals1(10,is))
       iice   = nint(aivals1(11,is))
       write(iout_rad,2000) 'sat','type','num','numw','ch4','ice'
       write(iout_rad,2010) kidsat1(is),sattype(is),iobs1,iobs2,iemiss,iice
       write(iout_rad,2012) 'penalty','iland','isnoice','ireduce','icoast', &
                            'itopo','ivarl'
       write(iout_rad,2011) aivals1(2,is),iland,isnoice,ireduce,icoast,itopo,ivarl
      else if(amsub .or. hsb)then
       ich1   = nint(aivals1(10,is))
       write(iout_rad,2000) 'sat','type','num','numw','ich1'
       write(iout_rad,2010) kidsat1(is),sattype(is),iobs1,iobs2,ich1
       write(iout_rad,2012) 'penalty','iland','isnoice','ireduce','icoast', &
                            'itopo','ivarl'
       write(iout_rad,2011) aivals1(2,is),iland,isnoice,ireduce,icoast,itopo,ivarl
      else if(goesimg)then
       iang   = nint(aivals1(10,is))
       ich1   = nint(aivals1(11,is))
       ich2   = nint(aivals1(12,is))
       ich5   = nint(aivals1(13,is))
       write(iout_rad,2000) 'sat','type','num','numw','hi topo','ch45','ch2'
       write(iout_rad,2010) kidsat1(is),sattype(is),iobs1,iobs2,ich1,ich2,ich5
       write(iout_rad,2012) 'penalty','iland','isnoice','ireduce','icoast', &
                            'itopo','ivarl','iang'
       write(iout_rad,2011) aivals1(2,is),iland,isnoice,ireduce,icoast,itopo,ivarl,iang
      else if (airs) then
       write(iout_rad,2990)
      else
       write(iout_rad,2999)
      end if
      write(iout_rad,'(/)')
     end if

  end do
  write(iout_rad,*)'rad total penalty_all=',penalty_all

! Print counts, bias, rms, stndev as a function of channel.
  rcount=0.0; rcount_all=0.0; rpenal=0.0
  ifirst=.false.
  if (first) then
     lnbias=59
     open(lnbias,file='satbias_pred',form='unformatted')
  end if
  do i = 1,jpch
     isum = nint(stats1(1,i))
     if (isum > 0) then
        jsat = nusat(i)
        svar=varch(i)
        rcount_all(jsat) = rcount_all(jsat) + isum
        if (iuse(i)==1) then
           rcount(jsat) = rcount(jsat) + isum
           rpenal(jsat) = rpenal(jsat) + stats1(5,i)
        else
           svar=-svar
        end if
        ifirst(jsat)=.true.
        rsum = 1./float(isum)
        icerr = nint(stats1(2,i))
        do j=3,6   ! j=3=obs-mod(w_biascor)
                   ! j=4=(obs-mod(w_biascor))**2
                   ! j=5=penalty contribution
                   ! j=6=obs-mod(w/o_biascor)
           
           stats1(j,i) = stats1(j,i)*rsum
        end do
        stats1(4,i) = sqrt(stats1(4,i))
        if (isum > 1) then
           stdev  = sqrt(stats1(4,i)*stats1(4,i)-stats1(3,i)*stats1(3,i))
        else
           stdev = 0.
        end if
        write(iout_rad,1102) i,nuchan(i),nusat(i),isum,icerr,svar,&
             stats1(6,i),stats1(3,i),stats1(5,i),stats1(4,i),stdev
! Print average magnitude of correction for each bias correction term.
!  j=7=satangbias.txt, j=8=tlap, j=9=tlap*tlap, j=10=mean, j=11=xpath, j=12=clw
!  j=13 through j=18 are square of j=7 through j=12
        svar4=svar
        do j=7,nstats
           bcor4(j-6)=stats1(j,i)
        end do
        if(first)write(lnbias) i,nuchan(i),nusat(i),isum,svar4,bcor4
     else
        svar4=-999.
        if(first)write(lnbias) i,nuchan(i),nusat(i),isum,svar4,bcor4
     endif
  end do

  if(first)close(lnbias)

! Write obs count to runtime output file
  write(iout_rad,1109)
  do i=1,jpch
     jsat=nusat(i)
     if (ifirst(jsat)) then
        ifirst(jsat)=.false.
        cpen=0.0
        if (rcount(jsat)>0.) cpen=rpenal(jsat)/rcount(jsat)
        write(iout_rad,1115) jiter,jsat,rcount_all(jsat),rcount(jsat),&
             rpenal(jsat),cpen
     endif
  end do
2000 format(a7,2x,A4,6x,8(a7,1x))
2010 format(i7,1x,A10,1x,8(i7,1x))
2011 format(3x,f16.8,7(i7,1x))
2012 format(7x,A7,5x,7(a7,1x))
2990 format(' airs data not implemented at this time ')
2999 format(' Illegal satellite type ')
1102 format(1x,2i3,i4,2i7,1x,f8.3,1x,6(f11.7,1x))
1109 format(t5,'it',t13,'sat',t20,'num all',t31,'num use',t41,'penalty',t56,&
          'cpen')
1115 format('o-g',1x,i2.2,1x,'rad',2x,i3,2x,f9.0,2x,f9.0,2x,g12.6,2x,g12.6)


!    End of diagnostic print block.
  close(iout_rad)
  end if

! End of routine
  return
end subroutine setuprad