!-------------------------------------- LICENCE BEGIN ------------------------------------
!Environment Canada - Atmospheric Science and Technology License/Disclaimer,
!                     version 3; Last Modified: May 7, 2008.
!This is free but copyrighted software; you can use/redistribute/modify it under the terms
!of the Environment Canada - Atmospheric Science and Technology License/Disclaimer
!version 3 or (at your option) any later version that should be found at:
!http://collaboration.cmc.ec.gc.ca/science/rpn.comm/license.html
!
!This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
!without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
!See the above mentioned License/Disclaimer for more details.
!You should have received a copy of the License/Disclaimer along with this software;
!if not, you can write to: EC-RPN COMM Group, 2121 TransCanada, suite 500, Dorval (Quebec),
!CANADA, H9P 1J3; or send e-mail to service.rpn@ec.gc.ca
!-------------------------------------- LICENCE END --------------------------------------
!

      SUBROUTINE READCORNS2(KDATESTAMP,KENSEMBLE,poper,knstatlev 1,14
     &     ,kulbgsto,klatbin)
*
#if defined (DOC)
*
***s/r READCORNS2  - 1) Read CORNS and RSTDDEV from RPN standard files
*                    2) Factorize Correlation by RSTDDEV
*                    3) Vertical (optionally) interpolation of correlations
*                    4) Set cross-variable correlations to zero
*                    4) Filter (optionally) eigenvalue of corralations
*                    5) Convolution of filtred and interpolated
*                       RSTDDEV
*                    6) Write (optionally) resulting RSTDDEV and CORNS
*                    7) Re-build filtred-interpolated-convoluted
*                       corralation matrix
*
*Author  : S. Pellerin *ARMA/AES March 2000
*Revision:
*
*          JM Belanger CMDA/SMC  Jul 2000
*                   . 32 bits conversion (Generic MIN)
*    -------------------
**    Purpose:
*Arguments
*     KDATESTAMP: date of validity
*     KENSEMBLE : number of members in the ensemble used to
*                 estimate these correlations
*     POPER(nflev,knstatlev): explicit vertical interpolation operator
*     KNSTATLEV             : Number of level of the original statistics
*     kulbgsto              : Logical unit of backgroud stat output
#endif
      IMPLICIT NONE
*implicits
*
*     Global variables
*
#include "pardim.cdk"
#include "comdim.cdk"
#include "comlun.cdk"
#include "comcorr.cdk"
#include "comstate.cdk"
#include "compstat.cdk"
#include "cominterp.cdk"
*
*     Arguments
*
      character*1 clblock
      integer kdatestamp,kensemble,knstatlev,kulbgsto,klatbin,kip1
      integer jn, istdkey,icornskey,iuleigen
      integer iksdim,ilen,inbrblock,jcol,jrow,jblock,jlevo,jlevi
c Number of additional 2D variable not in CORNS (SS) standard file records
      real*8 zwork,poper(nflev,knstatlev)
      real*8, allocatable, dimension(:) :: zstdsrc
      real*8, allocatable, dimension(:,:) :: zcornssrc, zcornsmix
      real*8 zproj,ztpsproj,zeigen,ztpseigen,zeigenv,
     &        ztpseigenv,zeigmin,zalpha,ztpscorr,zeigminblocks
      logical llrenorm,llprint,llfilttps
c      pointer (pxzcornssrc,zcornssrc((nvsp+nvsaux)*knstatlev+nvsp2d
c     &     ,(nvsp+nvsaux)*knstatlev+nvsp2d))
      pointer (pxztpscorr,ztpscorr(nflev+1,nflev+1))
      pointer (pxzeigminblocks,zeigminblocks(nvsp+nvsaux,0:ntrunc+1))
c
      pointer (pxzproj,zproj(nflev,nflev))
      pointer (pxzeigen,zeigen(nflev,nflev))
      pointer (pxzeigenv,zeigenv(nflev))
      pointer (pxztpsproj,ztpsproj(nflev+1,nflev+1))
      pointer (pxztpseigen,ztpseigen(nflev+1,nflev+1))
      pointer (pxztpseigenv,ztpseigenv(nflev+1))
c
c      pointer (pxzstdsrc,zstdsrc((NVSP+NVSAUX)*knstatlev+NVSP2D))
c      pointer (pxzcornsmix,zcornsmix(nksdim,(NVSP+NVSAUX)*knstatlev
c     &     +nvsp2d))

      integer vfstlir,vfstecr
      external vfstlir,vfstecr
*
#include "rpnstd.cdk"
*-------------------------------------------------------------------
C
      iksdim = (NVSP+NVSAUX)*knstatlev+NVSP2D - nsexist(nstg)
      allocate(zcornssrc(iksdim,iksdim))
c      call hpalloc(pxzcornssrc,max(1,iksdim**2),ierr,8)
      allocate(zstdsrc(iksdim))
c      call hpalloc(pxzstdsrc,max(1,iksdim),ierr,8)
      ilen = nksdim*iksdim
      allocate(zcornsmix(nksdim,iksdim))
c      call hpalloc(pxzcornsmix,max(1,ilen),ierr,8)
      ilen = (nflev+1)*(nflev+1)
      call hpalloc(pxztpscorr,max(1,ilen),ierr,8)
      call hpalloc(pxztpsproj,max(1,ilen),ierr,8)
      call hpalloc(pxztpseigen,max(1,ilen),ierr,8)
      ilen = nflev+1
      call hpalloc(pxztpseigenv,max(1,ilen),ierr,8)
c
      ilen = nflev*nflev
      call hpalloc(pxzproj,max(1,ilen),ierr,8)
      call hpalloc(pxzeigen,max(1,ilen),ierr,8)
      ilen = nflev
      call hpalloc(pxzeigenv,max(1,ilen),ierr,8)
      ilen=(nvsp+nvsaux)*(ntrunc+2)
      call hpalloc(pxzeigminblocks,max(1,ilen),ierr,8)
c
      inbrblock = nvsp+nvsaux
      llfilttps = .false.
      llrenorm = .false.
      llprint = .false.
      zalpha = 0.0
      write(nulout,*)'READCORNS2 FOR REGION #',klatbin
*
*     .    Read the RSTDDEV spectral coefficients
*
      kip1=klatbin
      if(nlatbin.eq.1) kip1=-1
c
      do jn = 0, ntrunc
        write(nulout,*)' Reading RSTDDEV spectral coefficients number'
     &       ,jn
c
c Looking for FST record parameters..
c
        idateo = -1
        cletiket = 'RSTDDEV'
        ip1 = kip1
        ip2 = JN
        ip3 = -1
        cltypvar = 'X'
        clnomvar = 'SS'
c
        istdkey = vfstlir(ZSTDSRC,nulbgst,INI,INJ,INK,idateo,cletiket,
     &                    ip1,ip2,ip3,cltypvar,clnomvar)
c
        if(istdkey .lt.0 ) then
          call abort3d(nulout
     &         ,'READCORNS2: Problem with background stat file')
        endif
c
        if (ini .ne. iksdim) then
          call abort3d(nulout
     &         ,'READCORNS2: BG stat levels inconsitencies')
        endif
c
        write(nulout,*)' Reading CORNS spectral coefficients number'
     &       ,jn
c
c Looking for FST record parameters..
c
        idateo = -1
        cletiket = 'CORRNS'
        ip1 = kip1
        IP2 = JN
        ip3 = -1
        cltypvar = 'X'
        clnomvar = 'ZZ'
        icornskey = vfstlir(ZCORNSSRC,nulbgst,INI,INJ,INK
     S       ,idateo,cletiket,ip1,ip2,ip3,cltypvar,clnomvar)
c
        if(icornskey .lt.0 ) then
          call abort3d(nulout
     &         ,'READCORNS2: Problem with background stat file')
        endif
c
        if (ini .ne. iksdim .or. inj .ne. iksdim) then
          call abort3d(nulout
     &         ,'READCORNS2: BG stat levels inconsitencies')
        endif
c
        if(lvintbgstat) then
c
c Factorization of CORNS with RSTDDEV
c
          do jcol = 1,iksdim
            do jrow = 1,iksdim
              zcornssrc(jrow,jcol) = zstdsrc(jrow) * zcornssrc(jrow,jcol
     &             )* zstdsrc(jcol)
            enddo
          enddo
c
c Vertical interpolation of correlation matrix: C'' = VCV
c
c 1 step: Interpolation of the knstatlev rows of zcornssrc (C matrix) to
c         the nflev rows of zcornsmix (C' matrix) for each of the inbrblock 3D
c         variable block
c
c                     1) C' = VC
c where
c C': zcornsmix
c V : poper
c C : zcornssrc (correlations on original levels)
c
          do jblock= 1, inbrblock
c
            call mxmaop(
     &           poper,1,nflev,zcornssrc(knstatlev*(jblock-1)+1
     &           ,1),1,iksdim,zcornsmix(nflev
     &           *(jblock-1)+1,1),1,nksdim,nflev
     &           ,knstatlev,iksdim)
c
          enddo
c
c Copy of correlation rows corresponding to 2D variables
c
          do jcol = 1,iksdim
            do jrow = 1,nvsp2d - nsexist(nstg)
              zcornsmix(inbrblock*nflev+jrow,jcol) =
     &             zcornssrc(inbrblock*knstatlev+jrow,jcol)
            enddo
          enddo
c
c Step 2: Interpolation of the knstatlev collumns of zcornsmix (C') to the nflev
c collumns of corns (C'') for each of the inbrblock 3D variable block
c                                 T
c                     2) C'' = C'V
c where
c C'  : zcornsmix
c V   : poper (vertical interpolator)
c C'' : corns (correlation on targetted levels)
c
          do jblock= 1, inbrblock
            call mxmaop(
     &           zcornsmix(1,knstatlev*(jblock-1)+1)
     &           ,1,nksdim,poper,knstatlev,1,corns(1,nflev*(jblock
     &           -1)+1,jn,klatbin),1,nksdim,nksdim,knstatlev,nflev)
          enddo
c
c Copy of correlation collumns corresponding to 2D var
c
          do jrow = 1,nksdim
            do jcol = 1,nvsp2d - nsexist(nstg)
              corns(jrow,inbrblock*nflev+jcol,jn,klatbin) =
     &             zcornsmix(jrow,inbrblock*knstatlev+jcol)
            enddo
          enddo
c
c Rest only the lowest and rightmost elements of correlations to copy
c
          do jcol = 1,nvsp2d -nsexist(nstg)
            do jrow = 1,nvsp2d - nsexist(nstg)
              corns(inbrblock*nflev+jrow,inbrblock*nflev+jcol,jn,klatbin) =
     &             zcornssrc(inbrblock*knstatlev+jrow,inbrblock
     &             *knstatlev+jcol)
            enddo
          enddo
        else
c
c No vertical interpolation of correlations
c N.B. zcornssrc does not contain the diagonal (rstddev) in this case
c
cbue
          do jcol = 1,nksdim2
            do jrow = 1,nksdim2
              corns(jrow,jcol,jn,klatbin) = 0.0
            enddo
          enddo
c
          do jcol = 1,iksdim
            do jrow = 1, iksdim
              corns(jrow,jcol,jn,klatbin) = zcornssrc(jrow,jcol)
            enddo
          enddo
c
        endif
c
c So far cross-variables correlations have been interpolated
c along with block diagonal variables.
c
c Set cross-variable correlations to zero except between T' and ln(ps')
c
        call setcrosscorr(jn,klatbin)
c
        if(leigfilt.and.lvintbgstat) then
c
c Filtering of eigenvalues for each block diagonal
c
          do jblock= 1, inbrblock
            if(llprint) then
              write(clblock,'(i1)') jblock
              iuleigen = 0
              ierr = fnom(iuleigen,'eigenv_block_'//clblock//'.asc'
     &             ,'APPEND+FMT',0)
c              open(iuleigen,file='eigenv_block_'//clblock//'.asc',access
c     &             ='APPEND',form='FORMATTED',IOSTAT=ierr)
              write(iuleigen,*) ' '
              write(iuleigen,*) '------------ Coefficient: ',jn,
     &             ' ------------'
            endif
c
            if(jblock.ne.nstt .or. .not. llfilttps) then
c
c Filtering all blocks (but T'T' if llfilttps is true)
c
              if(jblock.eq.nsvor) then
                zeigmin = reigminpsi
              elseif(jblock.eq.nsdiv) then
                zeigmin = reigminchi
              elseif(jblock.eq.nstt) then
                zeigmin = reigmintt
              elseif(jblock.eq.nsps) then
                zeigmin = reigminlq
              else
                zeigmin = 0.0
              endif
c
              call filtmatrix2(corns(nflev*(jblock-1)+1,nflev*(jblock-1)
     &             +1,jn,klatbin),nksdim,zproj,zeigen,zeigenv,nflev,zeigmin
     &             ,zalpha,llrenorm,iuleigen,llprint)
c
              if(llprint) then
c
                if(jn.eq.0) zeigminblocks(jblock,ntrunc+1) = zeigenv(1)
                zeigminblocks(jblock,jn) = zeigenv(1)
c
                do jcol = 1,nflev
                  zeigminblocks(jblock,jn) = min(zeigenv(jcol)
     &                 ,zeigminblocks(jblock,jn))
                  zeigminblocks(jblock,ntrunc+1) = min(zeigenv(jcol)
     &                 ,zeigminblocks(jblock,ntrunc+1))
                enddo
              endif
c
            else
              zeigmin = reigmintt
c
c Filtering combined T'T' and T'ln(ps') block matrix
c
              do jcol = 1,nflev
                do jrow = 1,nflev
                  ztpscorr(jrow,jcol) = corns(nsposit(nstt)+jrow-1
     &                 ,nsposit(nstt)+jcol-1,jn,klatbin)
                enddo
                ztpscorr(nflev+1,jcol) = corns(nsposit(nsps)
     &               ,nsposit(nstt)+jcol-1,jn,klatbin)
              enddo
              do jrow = 1,nflev
                ztpscorr(jrow,nflev+1) = corns(nsposit(nstt)+jrow-1
     &               ,nsposit(nsps),jn,klatbin)
              enddo
              ztpscorr(nflev+1,nflev+1) = corns(nsposit(nsps)
     &             ,nsposit(nsps),jn,klatbin)
c
              call filtmatrix2(ztpscorr,nflev+1,ztpsproj,ztpseigen
     &             ,ztpseigenv,nflev+1,zeigmin,zalpha,llrenorm,iuleigen
     &             ,llprint)
c
              if(llprint) then
c
                if(jn.eq.0) zeigminblocks(jblock,ntrunc+1) = zeigenv(1)
                zeigminblocks(jblock,jn) = zeigenv(1)
c
                do jcol = 1,nflev
                  zeigminblocks(jblock,jn) = min(zeigenv(jcol)
     &                 ,zeigminblocks(jblock,jn))
                  zeigminblocks(jblock,ntrunc+1) = min(zeigenv(jcol)
     &                 ,zeigminblocks(jblock,ntrunc+1))
                enddo
              endif
c
              do jcol = 1,nflev
                do jrow = 1,nflev
                  corns(nsposit(nstt)+jrow-1,nsposit(nstt)+jcol-1,jn,klatbin) =
     &                 ztpscorr(jrow,jcol)
                enddo
                corns(nsposit(nsps),nsposit(nstt)+jcol-1,jn,klatbin) =
     &               ztpscorr(nflev+1,jcol)
              enddo
              do jrow = 1,nflev
                corns(nsposit(nstt)+jrow-1,nsposit(nsps),jn,klatbin) =
     &               ztpscorr(jrow,nflev+1)
              enddo
              corns(nsposit(nsps),nsposit(nsps),jn,klatbin) = ztpscorr(nflev+1
     &             ,nflev+1)
            endif
            if(llprint) ierr = fclos (iuleigen)
          enddo
c
        endif
c
        if(lvintbgstat) then
c
c Get the filtred and interpolated RSTDDEV from diagonal of correlations
c
          do jrow = 1, nksdim
            rstddev(jrow,jn) = sqrt(corns(jrow,jrow,jn,klatbin))
          enddo
c
c Un-factorize filtred and interpolated correlation matrix with
C resulting RSTDDEV
c
          do jrow = 1, nksdim
            do jcol = 1, nksdim
              corns(jrow,jcol,jn,klatbin) = corns(jrow,jcol,jn,klatbin)/(rstddev(jrow,jn
     &             )*rstddev(jcol,jn))
            enddo
          enddo
        else
          do jrow = 1, iksdim
            rstddev(jrow,jn) = zstdsrc(jrow)
          enddo
        endif
c
      enddo
c
      if (leigfilt.and.llprint.and.lvintbgstat) then
        do jblock = 1, inbrblock
          write(clblock,'(i1)') jblock
          iuleigen = 0
          ierr = fnom(iuleigen,'eigenv_block_'//clblock//'.asc'
     &         ,'APPEND+FMT',0)
c          open(nulusr5,file='eigenv_block_'//clblock//'.asc',access
c     &         ='APPEND',form='FORMATTED',IOSTAT=ierr)
          write(iuleigen,*)
     &         ' ----- Summary of original minimum eigenvalues -----'
          write(iuleigen,*) 'wave number - minimum value'
          write(iuleigen,1001) (jn,zeigminblocks(jblock,jn),jn=0,ntrunc)
          write(iuleigen,1000) zeigminblocks(jblock,ntrunc+1)
          close(iuleigen)
        enddo
 1000   format(//,1x,'Absolute original minimum eigenvalue : ',g12.3)
 1001   format(1x,i3,1x,g12.3)
      endif
c
c Apply convolution to RSTDDEV correlations
c
      call convol
c
      do jn = 0, ntrunc

        if ( kulbgsto .gt. 0 ) then
c
c Writing starndard deviation to file
c
          ierr = fstprm(istdkey,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
          ini = nksdim
          inj = 1
          ink = 1
          ip2 = jn
c
          ierr = vfstecr(rstddev(1,jn), zwork, -inbits, kulbgsto, idateo
     &         , ideet,inpas, ini, inj, ink, ip1, ip2, ip3, cltypvar,
     &         clnomvar,cletiket,clgrtyp,ig1, ig2, ig3, ig4, idatyp,
     &         .true.)
c
c Writing correlation matrix to file
c
          ierr = fstprm(icornskey,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
          ini = nksdim
          inj = nksdim
          ink = 1
          ip2 = jn
c
          ierr = vfstecr(corns(1,1,jn,klatbin), zwork, -inbits, kulbgsto, idateo
     &         , ideet,inpas, ini, inj, ink, ip1, ip2, ip3, cltypvar,
     &         clnomvar,cletiket,clgrtyp,ig1, ig2, ig3, ig4, idatyp,
     &         .true.)
        endif
c
c Re-build of correlation matrix: factorization of corns with convoluted RSTDDEV
c
        do jcol = 1,nksdim
          do jrow = 1,nksdim
            corns(jrow,jcol,jn,klatbin) = rstddev(jrow,jn) * corns(jrow,jcol
     &           ,jn,klatbin)* rstddev(jcol,jn)
          enddo
        enddo
c
      enddo
c
      kensemble  = ip3
      kdatestamp = idateo
c
      deallocate(zcornssrc)
c      call hpdeallc(pxzcornssrc,ierr,1)
      deallocate(zstdsrc)
c      call hpdeallc(pxzstdsrc,ierr,1)
      deallocate(zcornsmix)
c      call hpdeallc(pxzcornsmix,ierr,1)
c
      call hpdeallc(pxzproj,ierr,1)
      call hpdeallc(pxzeigen,ierr,1)
      call hpdeallc(pxzeigenv,ierr,1)
      call hpdeallc(pxztpscorr,ierr,1)
      call hpdeallc(pxztpsproj,ierr,1)
      call hpdeallc(pxztpseigen,ierr,1)
      call hpdeallc(pxztpseigenv,ierr,1)
      call hpdeallc(pxzeigminblocks,ierr,1)
c
      write(nulout,*) 'Done in READCORNS2'
c
      return
      end