!-------------------------------------- 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 SETFGEDIF(CDFAM) 3,8
#if defined (DOC)
*
***s/r SETFGEDIF   - Interpolation of THE FIRST GUESS ERROR VARIANCES
*                    for data derived through the diff self-differencing variables
*
*
*Author  : J.M. Aparicio *MSC/ARMA November 2004
*Revision:
*
**    Purpose:  -Construct the FIRST GUESS ERROR VARIANCES from the
*                diff-calculated dependencies and the primary errors.
*
*
#endif
      use modgps04profile
      use modgps06gravity
      use modgps07geostruct
      use modgps08refop
      IMPLICIT NONE
*implicits
#include "pardim.cdk"
#include "comdim.cdk"
#include "comgem.cdk"
#include "comdimo.cdk"
#include "comoabdy.cdk"
#include "comoahdr.cdk"
#include "comoba.cdk"
#include "commvo.cdk"
#include "commvohr.cdk"
#include "cvcord.cdk"
#include "comcst.cdk"
#include "comphy.cdk"
*
      CHARACTER*2 CDFAM
      INTEGER JF
      INTEGER IBEGIN  , ILAST
      INTEGER IBEGINOB, ILASTOB, JO
      INTEGER IDATYP
      INTEGER IDATA   , IDATEND, JDATA
      INTEGER NH, NH1
      INTEGER JL, JV, NGPSLEV

      LOGICAL  ASSIM

      REAL*8 ZTODEG
      REAL*8 ZLAT, Lat
      REAL*8 ZLON, Lon
      REAL*8 ZETA(JPNFLEV)
      REAL*8 ZTT (JPNFLEV)
      REAL*8 ZHU (JPNFLEV)
      REAL*8 ZGZ (JPNFLEV)
      REAL*8 ZP0
      REAL*8 ZPT
      REAL*8 ZMT
      REAL*8 ZMHX
      REAL*8 HNH1

      REAL*8 JAC(ngpscvmx)
      REAL*8 DV (ngpscvmx)
      TYPE(GPSPROFILE)           :: PRF
      REAL(DP)     , ALLOCATABLE :: H   (:)
      TYPE(GPSDIFF), ALLOCATABLE :: RSTV(:)
C
C     * 1.  Initializations
C     *     ---------------
C
      ZTODEG = 180.0 / RPI
C
C     *     Eta vector:
C
      NGPSLEV=NLEVTRL
      DO JL = 1, NLEVTRL
         ZETA(JL) = VLEVHR(JL)
      ENDDO  
C
      DO JF = 1,NFILES
         IF ( (CFAMTYP(JF) .EQ. CDFAM ) .AND.( NBEGINTYP(JF) .GT. 0) ) THEN
            IBEGIN   = NBEGINTYP(JF)
            ILAST    = NENDTYP  (JF)
            IBEGINOB = MOBDATA(NCMOBS,IBEGIN)
            ILASTOB  = MOBDATA(NCMOBS,ILAST )
C
C     *     Loop over all observations of the file
C
            DO JO = IBEGINOB, ILASTOB
C     
C     *    .   Process only refractivity data (codtyp 169)
C
               IDATYP = MOD(MOBHDR(NCMITY,JO),1000)
               IF ( IDATYP .EQ. 169 ) THEN
C
C                 Loops over data in the observation
C
                  IDATA   = MOBHDR(NCMRLN,JO)
                  IDATEND = MOBHDR(NCMNLV,JO) + IDATA - 1
                  ASSIM = .FALSE.
C
C                 Scan for requested assimilations, and count them
C
                  NH = 0
                  DO JDATA= IDATA, IDATEND
                     IF ( MOBDATA(NCMASS,JDATA).EQ.1 ) THEN
                        ASSIM = .TRUE.
                        NH = NH + 1
                     ENDIF
                  ENDDO
C
C     *           If assimilations are requested, apply the observation operator
C
                  IF (ASSIM) THEN
C     
C     *              Profile at the observation location:
C
                     Lat  = ROBHDR(NCMLAT,JO)
                     Lon  = ROBHDR(NCMLON,JO)
                     ZLAT = Lat * ZTODEG
                     ZLON = Lon * ZTODEG
                     DO JL = 1, NLEVTRL
C
C     *                 Profile x
C
                        ZTT(JL) = GOMTHR (JL,JO)-273.15
                        ZHU(JL) = GOMQHR (JL,JO)
                        ZGZ(JL) = GOMGZHR(JL,JO)
                     ENDDO
                     ZP0 =  GOMPSHR(1,JO)
                     ZPT = RPPOBSHR(1,JO)
                     ZMT = ZGZ(NLEVTRL)/RG
                     ZMT = gpsgeopotential(Lat, ZMT)/RG
C     
C     *              GPS profile structure:
C
                     CALL GPSSTRUCT1(NGPSLEV,ZLAT,ZLON,ZETA,
     +                    ZTT,ZHU,ZP0,ZMT,ZPT,PRF)
C
C     *              Local error
C
                     DO JL = 1, NLEVTRL
                        DV (        JL) = 1.
                        DV (NLEVTRL+JL) = 1.
                     ENDDO
                     DV (2*NLEVTRL+1)   = 2.

                     IF (JO.EQ.IBEGINOB) THEN
                        DO JL = 1, 2*NFLEV+1
                           WRITE(*,*)'SETFGEDIF', JL, DV(JL)
                        ENDDO
                     ENDIF
C
C     *              PREPARE THE VECTOR OF ALL THE OBSERVATIONS
C
                     ALLOCATE( H    (NH) )
                     ALLOCATE( RSTV (NH) )
                     NH1 = 0
                     DO JDATA= IDATA, IDATEND
                        IF ( MOBDATA(NCMASS,JDATA).EQ.1 ) THEN
                           NH1   = NH1 + 1
                           HNH1  = ROBDATA8(NCMPPP,JDATA)
                           H(NH1)= gpsgeopotential(Lat,HNH1)/9.80616
                        ENDIF
                     ENDDO
C
C     *              Apply the observation operator
C  
                     CALL GPSREFOPV(H, PRF, RSTV)
C
C     *              Perform the H(xb)DV operation
C
                     NH1 = 0
                     DO JDATA= IDATA, IDATEND
                        IF ( MOBDATA(NCMASS,JDATA).EQ.1 ) THEN
                           NH1 = NH1 + 1
C
C     *                    Observation jacobian
C
                           JAC = RSTV(NH1)%DVAR
C
C     *                    Evaluate sqrt( H(xb)DV **2 )
C
                           ZMHX = 0._dp
                           DO JV = 1, 2*PRF%NGPSLEV+1
                              ZMHX = ZMHX + (JAC(JV) * DV(JV))**2
                           ENDDO
                           ZMHX = SQRT(ZMHX)
C     
C     *                    FIRST GUESS ERROR VARIANCE
C
                           ROBDATA(NCMFGE,JDATA) = ZMHX
                           IF (JO.EQ.IBEGINOB) THEN
 11                           FORMAT(A12,2I5,2F12.2,2F12.4)
                              WRITE(*,11)'SETFGEDIFFGE', NH1, NH,
     +                             H(NH1),RSTV(NH1)%VAR,
     +                             ZMHX,ROBDATA8(NCMOER,JDATA)
                           ENDIF
                        ENDIF
                     ENDDO
                     DEALLOCATE( RSTV )
                     DEALLOCATE( H    )
                  ENDIF
               ENDIF
            ENDDO
         ENDIF
      ENDDO
C
      RETURN
      END