subroutine ch_rdspstd(poper,knstatlev,kulbgsto) 1,8
#if defined (DOC)
*
***s/r CH_RDSPSTD  - Read the spectral coefficients of standard deviations
*                    from a RPN standard file and perform vertical
*                    interpolation.
*
*Author  : RDSPSTD by S.Pellerin *ARMA/AES  November, 2000
*          Extended to CH_RDSPSTD by Y. Yang, ARQI 2005
*Revision:
*       JM Belanger CMDA/SMC  Jul 2000
*                   . 32 bits conversion
*
*       J. Halle    CMDA/SMC  April 2003
*                   . Added RFACTHUM, which multiplies background
*                     error std for LQ. Default = 1.0
*       Y. Yang     Oct. 2003
*                   . Added reading std dev for species.
*                   . clvar3d and clvar2d can now be read from namelist
*                     to make it easier for future expansion
*       Y. Yang     Oct. 2004
*                   . Added logical LCHEM for reading NAMVARSTD only when needed.
*                     ie. when assimilating species. Otherwise use default.
*       Y. Yang     Feb. 2005
*                   . Removed 'OZ' as now part of 'TR'
*       Y.J. Rochon *ARQX/MSC May 2005, Feb 2006, April 2007
*                   . Unit for reading species background stats now
*                     NULBGSTR. Correspondingly added if statement for
*                     call to vstlir.
*                   . Added *sigscl2d and *sigscl3d for scaling of std. dev.
*                     Non-default scaling factors provided by NAMVARSTD.
*                   . Reading of NAMVARSTD when available and not just when
*                     LCHEM is true. This allows optional scaling 
*                     of dynamics related std. dev. for either state of LCHEM.
*                   . Changed CGCMT/NGCMT to CSCMT/NSCMT
*       Y.J. Rochon *ARQX Aug 2010
*                   . Added TB and PB as posssible default parameters following
*                     V10.2.2 rdspstd.ftn
*                      
*                    
*
* Arguments:
*   input:
*     POPER(nflev,knstatlev): explicit vertical interpolation operator
*     KNSTATLEV             : Number of level of the original statistics
*     kulbgsto              : Logical unit for backgroud stat output
*
#endif
      implicit none
*implicits
*
*     Global variables
*
#include "comct0.cdk"
#include "pardim.cdk"
#include "comdim.cdk"
#include "comlun.cdk"
#include "comchem.cdk"
#include "comspg.cdk"
#include "rpnstd.cdk"
#include "comleg.cdk"
#include "cominterp.cdk"
#include "compstat.cdk"
#include "comvarstd.cdk"
#include "comcorr.cdk"
#include "comcst.cdk"
#include "comcva.cdk"
*
*     Arguments
*
      integer knstatlev,kulbgsto
      real*8 poper(nflev,knstatlev)
*
*     local variables
*
      integer jptrunc,indyn
      parameter (jptrunc=200)
      character*4 cvar3d(inbrvar3d),cvar2d(inbrvar2d)
      integer jvar,jn,jlevi
      integer ikey, jlevo, ilen, jlat
      integer jtr
      integer iflag
      real*8 zsp,zspbuf,zwork,zsigscl3d(inbrvar3d),zsigscl2d(inbrvar2d)
      real*8 zleg,zgr,zgsig
      pointer (pxzspbuf,zspbuf(knstatlev))
c
      pointer (pxzsp,zsp(0:ntrunc,nflev))
      pointer (pxzgr,zgr(nj,nflev))
      pointer (pxzleg,zleg(0:ntrunc,nj))
      pointer (pxzgsig,zgsig(1,nj,nflev))
c
      integer vfstlir,vfstecr
      external vfstlir,vfstecr
c
c     data clvar3d/'PP','UC','UT','LQ','CC','ES','GZ','TT','UU','VV'/
c     data clvar2d/'UP','P0'/
*---------------------------------------------------------------------
C
C*    Defaults values for clvar*d, sigscl*d
C
      sigscl3d(:)=1.0
      sigscl2d(:)=1.0
      zsigscl3d(:)=1.0
      zsigscl2d(:)=1.0
      clvar3d(:) = ' '
      clvar2d(:) = ' '
      clvar3d(1) ='PP'
      clvar3d(2) ='UC'
      clvar3d(3) ='UT'
      clvar3d(4) ='LQ'
      indyn=4
C
      clvar2d(1) ='UP'
C
      if (nanalvar.eq.4) then
         clvar3d(5)='TB'
         indyn=5
         clvar2d(2) ='PB'
      end if
C
      cvar2d(:)=clvar2d(:)
      cvar3d(:)=clvar3d(:)
C
C*    Read clvar3d and clvar2d from namelist
C
C     Also read std. dev. scaling factors zsigscl*d
C
      IFLAG=1
c
c     Check that inbrvar3d >= ncmtmax+10
c
      if (inbrvar3d .lt. ncmtmax+10)  then
         call abort3d(nulout, 'CH_RDSPSTD: inbrvar3d less than ncmtmax+10 !')
      endif
      CALL READNML('NAMVARSTD',IFLAG)
      if (.NOT.LCHEM.AND.IFLAG.EQ.0) then
C
C        Restrict list to default dynamical variables.
C
         do jn=1,inbrvar3d
            do jvar=1,inbrvar3d
               if (cvar3d(jn).eq.clvar3d(jvar)) then
                  zsigscl3d(jn)=sigscl3d(jvar)
                  exit
               end if
            end do
         end do
         do jn=1,inbrvar2d
            do jvar=1,inbrvar2d
               if (cvar2d(jn).eq.clvar2d(jvar)) then
                  zsigscl2d(jn)=sigscl2d(jvar)
                  exit
               end if 
            end do
         end do
         clvar3d(:)=cvar3d(:)
         clvar2d(:)=cvar2d(:)  
C
      else if (LCHEM) then
C
C        Assumes that all default dynamics variables are included 
C        in the final list of variables!!
C
         zsigscl2d(:)=sigscl2d(:)
         zsigscl3d(:)=sigscl3d(:)
C  
      end if
C
      ilen = knstatlev
      call hpalloc(pxzspbuf,max(1,ilen),ierr,8)

      ilen = (ntrunc+1)*nflev
      call hpalloc(pxzsp,max(1,ilen),ierr,8)
      ilen = nj*nflev
      call hpalloc(pxzgr,max(1,ilen),ierr,8)
      ilen = nj*(ntrunc+1)
      call hpalloc(pxzleg,max(1,ilen),ierr,8)
      ilen = nj*nflev
      call hpalloc(pxzgsig,max(1,ilen),ierr,8)
**
* ----- Reading variances in spectral space -----
*
*     0. Set up simple spectral transforms
*
      call zlegpol(zleg,rmu,nj,ntrunc,ntrunc,nj)
*
      ilen = (njend -njbeg +1)*nkgdim
*
*     Initializing all the variances fields to zero
*
      write(nulout,*)'Zeroing RGSIG'
      call zero(ilen,rgsig)
*
*     2. Reading the data
*
*     .  2.1 Background error standard deviations
*
      idate(1) = -1
      ip1      = -1
      ip2      = -1
      ip3      = -1
*
      cletiket = 'SPSTDDEV'
      cltypvar ='X'
***********************************************************************
      write(nulout,*) 'Reading 3D variables'
      do jvar = 1, inbrvar3d
        if (clvar3d(jvar) .eq. ' ') go to 888
        clnomvar = clvar3d(jvar)
        write(nulout,*)'Reading ',clnomvar
        do jn = 0,ntrunc
          ip2 = jn
          if (jvar.le.indyn) then
             ikey = vfstlir(zspbuf,nulbgst,ini,inj,ink,idate(1)
     s            ,cletiket,ip1,ip2,ip3,cltypvar,clnomvar)
          else            
             ikey = vfstlir(zspbuf,nulbgstr,ini,inj,ink,idate(1)
     s            ,cletiket,ip1,ip2,ip3,cltypvar,clnomvar)
          end if
*
          if(ikey .lt.0 ) then

            call abort3d(nulout
     &           ,'CH_RDSPSTD: Could not find std. dev.')
          endif
c
          if (ini .ne. knstatlev) then
            call abort3d(nulout
     &           ,'CH_RDSPSTD: BG stat levels inconsitencies')
          endif
c
          if(lvintbgstat) then
c
c           Vertical interpolation O'm = Vmn On
c
            call mxmaop1(poper,1,nflev,zspbuf,1,knstatlev,zsp(jn,1)
     &           ,ntrunc+1,(ntrunc+1)*nflev,nflev,knstatlev,1)
          else
            do jlevo = 1, nflev
              zsp(jn,jlevo) = zspbuf(jlevo)
            enddo
          endif
        enddo
c
c       Transform to physical space.
c       N.B.: LQ values are mutiplied by RFACTHUM
*
        call zleginv2(zgr,zsp,zleg,ntrunc,nj,nflev,nj,nflev,ntrunc)
*
C       Apply scaling of std. dev. (optional scaling factors from NAMVARSTD
C       namelist; default value is 1.0)
C
        zgr(:,:)=zgr(:,:)*zsigscl3d(jvar)
C
        if(clnomvar .eq. 'PP') then
          do jlat = 1, nj
            do jlevo = 1, nflev
              rgsiguu(jlat,jlevo) = zgr(jlat,jlevo)
            enddo
          enddo
        elseif(clnomvar .eq. 'UC' .or. clnomvar .eq. 'CC') then
          do jlat = 1, nj
            do jlevo = 1, nflev
              rgsigvv(jlat,jlevo) = zgr(jlat,jlevo)
            enddo
          enddo
        elseif(clnomvar .eq. 'UT') then
          do jlat = 1, nj
            do jlevo = 1, nflev
              rgsigtt(jlat,jlevo) = zgr(jlat,jlevo)
            enddo
          enddo
        elseif(clnomvar .eq. 'TB') then
          do jlat = 1, nj
            do jlevo = 1, nflev
              rgsigtb(jlat,jlevo) = zgr(jlat,jlevo)
            enddo
          enddo
        elseif(clnomvar .eq. 'LQ') then
          do jlat = 1, nj
            do jlevo = 1, nflev
              rgsigq(jlat,jlevo) = zgr(jlat,jlevo)*rfacthum
            enddo
          enddo
        else
C
C*         For chemical species. Find the position of the tracer
C
           do jtr =1,NSCMT
              if(clnomvar .eq. CSCMT(jtr)) then
                do jlat = 1, nj
                  do jlevo = 1, nflev
                    rgsigtr(jlat,jlevo+nflev*(jtr-1)) = zgr(jlat,jlevo)
                  enddo
                enddo
                go to 999
              endif
           enddo
           if (jtr .gt. nscmt) then
              write(nulout, *) 'Skipped background std for variable', clnomvar
           endif
        endif
c
  999   continue
        if ( kulbgsto .gt. 0 ) then
          ierr = fstprm(ikey,idateo,ideet,inpas,ini,inj,ink, inbits,
     &         idatyp,ip1,ip2,ip3,cltypvar,clnomvar,cletiket,clgrtyp,ig1
     &         ,ig2,ig3,ig4,iswa,ilength,idltf,iubc,iextr1,iextr2,iextr3
     &         )
c
          do jlat = 1, nj
            do jlevo = 1,nflev
              zgsig(1,jlat,jlevo) = zgr(nj-jlat+1,jlevo)
            enddo
          enddo
c
          ierr = vfstecr(zgsig, zwork, -inbits, kulbgsto, idateo, ideet,
     &         inpas, 1, nj, nflev, 0, 0, ip3, 'E', clnomvar,
     &         'STDDEV',clgrtyp,ig1, ig2, ig3, ig4, idatyp, .true.)
c
        endif

  888   continue
      enddo
*
      write(nulout,*) 'Reading 2D variables'
      do jvar = 1, inbrvar2d
        if (clvar2d(jvar) .eq. ' ') go to 777
        clnomvar = clvar2d(jvar)
        write(nulout,*)'Reading ',clnomvar
        do jn = 0,ntrunc
          ip2 = jn
          ikey = vfstlir(zspbuf,nulbgst,ini,inj,ink,idate(1)
     s         ,cletiket,ip1,ip2,ip3,cltypvar,clnomvar)
c
          zsp(jn,1) = zspbuf(1)
c
        enddo
c
c       Transform to physical space
c
        call zleginv2(zgr,zsp,zleg,ntrunc,nj,1,nj,nflev,ntrunc)
c
C       Apply scaling of std. dev. (optional scaling factors from NAMVARSTD
C       namelist; default value is 1.0)
C
        zgr(:,:)=zgr(:,:)*zsigscl2d(jvar)
C
        if(clnomvar .eq. 'UP') then
          do jlat = 1, nj
            rgsigps(jlat,1) = zgr(jlat,1)*100.0
c            rgsigps(jlat,1) = 0.0
          enddo
        endif
        if(clnomvar .eq. 'PB') then
          do jlat = 1, nj
            rgsigpsb(jlat) = zgr(jlat,1)*100.0
c            rgsigpsb(jlat) = 0.0
          enddo
        endif

c
c        Compute stddev for all variables (including balanced temperature)
c
c        DO jlevi = 1, NKGDIM
c          DO jlat=1,NJ
c            ZSTDDEV(jlevi,jlat)=CORVERT(jlevi,jlevi)*RGSIG(jlat,jlevi)
c          ENDDO
c        ENDDO
c        DO jlevi = NKGDIM+1, NKGDIM+NFLEV
c          DO jlat=1,NJ
c            ZCORIOLIS = 2.*ROMEGA*RMU(jlat)
c            ZSTDDEV(jlevi,jlat)=CORVERT(jlevi,jlevi)*ZCORIOLIS*RGSIGTB(jlat,jlevi)
c          ENDDO
c        ENDDO
c        write(702,*) zstddev
c
        if ( kulbgsto .gt. 0 ) then
          ierr = fstprm(ikey,idateo,ideet,inpas,ini,inj,ink, inbits,
     &         idatyp,ip1,ip2,ip3,cltypvar,clnomvar,cletiket,clgrtyp,ig1
     &         ,ig2,ig3,ig4,iswa,ilength,idltf,iubc,iextr1,iextr2,iextr3
     &         )
c
          do jlat = 1, nj
            zgsig(1,jlat,1) = zgr(nj-jlat+1,1)
          enddo
c
          ierr = vfstecr(zgsig, zwork, -inbits, kulbgsto, idateo, ideet,
     &         inpas, 1, nj, 1, 0, 0, ip3, 'E', clnomvar,
     &         'STDDEV',clgrtyp,ig1, ig2, ig3, ig4, idatyp, .true.)
c
        endif

 777    continue
      enddo
*
*     9. Deallocate local arrays
*
      call hpdeallc(pxzspbuf,ierr,1)
c
      call hpdeallc(pxzsp,ierr,1)
      call hpdeallc(pxzgr,ierr,1)
      call hpdeallc(pxzleg,ierr,1)
      call hpdeallc(pxzgsig,ierr,1)
*
      WRITE(nulout,*)'DONE in CH_RDSPSTD'
*
      RETURN
      END