SUBROUTINE FGCHK(KOBS,KBODY,KGRP)

!**** SUBROUTINE FGCHK - FIRST GUESS CHECK FOR FOLLOWING VARIABLES:
!                        Z/PS/DZ/T/Q/RH/RH2M/ZRL/DOW


!          HEIKKI JARVINEN   ECMWF          15/MAR/1995
!          DRASKO VASILJEVIC ECMWF          21/10/1999

!*    PURPOSE
!     -------

!        FIRST GUESS CHECK FOR Z/T/Q/RH/TD/T2M/TD2M/RH2M/APD/ZRL/DOW

!**   INTERFACE
!     ---------

!     ***CALL*FGCHK(KOBS,KBODY)
!     WHERE KOBS  = CURRENT REP. POINTER
!           KBODY = CURRENT LEV POINTER

!        FGCHK IS CALLED BY SUBROUTINE FIRST

!*    METHOD
!     ------

!*    EXTERNALS
!     ---------

!        ABOR1   - ABORT
!        NFLGDSE - SET DATUM FLAG

!**   MODIFICATIONS
!     -------------
!     H. Jarvinen 12 Dec 1996 : A modified subroutine call
!     98-05-15 E. Andersson - Changed BgQC limits (in namelist)
!     J.N. Thepaut 26 august 98 : use geographical coordinate for diagnostics.
!     98-12-04 E. Andersson - BgQC for TCWV and TCO3
!     99-04-25 R. Munro - Altered BqQC for Geo radiances
!     01-11-29 A. Dethof - Set fg-err for ozone layers to 20% of fg-value. This is 
!                          a rough first-guess check until the background errors for
!                          ozone layers are calculated properly
!     02-07-03 A. Dethof - Set fg-err for PWC layers to 50% of fg-value. This is a
!                          preliminary value in preparation for ENVISAT data. 
!     12-11-03 S. Healy    set the fg-error to ob error for GPSRO 
!     23-12-04 N. Bormann  Introduce limb radiances; fg-err set to 2.5*obs-err ]
!     30-Mar-05 A.Benedetti introduce aerosol optical depth    
!     05-May-05 A. Dethof - Introduce GRG variables
!     16-03-06 G. Desroziers: Specify constant sigmabs for only not yet assimilated channels
!     22-08-06 S Healy Modify the fg error for GPSRO.  
!     R. El Khatib & NEC 01-Aug-2006 Optimization (initialize a saved ZFGERR
!       only at first call)
!     16-08-07 V. Guidard - Add IASI (after A Collard)
!     09-10-07 T. Montmerle - BgQC for Doppler winds
!     -------------------------------------------------------------------------

USE PARKIND1  ,ONLY : JPIM     ,JPRB
USE YOMHOOK   ,ONLY : LHOOK,   DR_HOOK

USE YOMLUN   , ONLY : NULOUT
USE YOMCOCTP , ONLY : NGTHRB    ,NSTRO3,   NSSMI,  NTEMP,  NPILOT
USE YOMCT0B  , ONLY : LECMWF
USE YOMANCS  , ONLY : RMDI     ,NMDI
USE YOMALIM  , ONLY : NFLLIM
USE YOMVNMB  , ONLY : NVNUMB
USE YOMNMEV  , ONLY : ND1EVENT
USE YOMCOSJO , ONLY : RBGQC    ,RBGQC_RAD1C,NVAR_T,NVAR_Z    ,&
 & NVAR_PS  ,NVAR_DZ  ,NVAR_Q   ,NVAR_H   ,&
 & NVAR_RAD ,NVAR_PWC ,NVAR_TO3, NVAR_APD, NVAR_RO, NVAR_AOD, NVAR_LRA, NVAR_GRG, &
 & NVAR_GHG,NVAR_COD, NVAR_RAO, NVAR_RFA, NVAR_ODA, NVAR_RFL, NVAR_DOW, &
 & NVAR_HLS, NHLSFGOPT, ZHLSFGOPT, &
 & LHUBERBGQC, & 
 & RHUBERBGQC_SONDEGOOD, RHUBERBGQC_SONDEOK, RHUBERBGQC
USE YOMDB
USE YOMDIMO  , ONLY : NMXTCH
USE YOMTVRAD , ONLY : MXSENSOR,MSENSOR_HIRS,MSENSOR_AMSUA,MSENSOR_AMSUB, &
                    & MSENSOR_MSG,MSENSOR_MSG_HR,MSENSOR_METEOSAT,MSENSOR_AIRS,&
                    & MSENSOR_MHS,MSENSOR_IASI
USE YOM_YGFL , ONLY : JPGRG

!     -------------------------------------------------------------------------

IMPLICIT NONE

INTEGER(KIND=JPIM),INTENT(IN)    :: KOBS 
INTEGER(KIND=JPIM),INTENT(IN)    :: KBODY 
INTEGER(KIND=JPIM),INTENT(IN)    :: KGRP 

!     -------------------------------------------------------------------------

INTEGER(KIND=JPIM) :: ICDTYP,ICMVNM,IFLAG,IOBTYP,IVAR,IVCO,ISENSOR,ICHAN
INTEGER(KIND=JPIM) :: JFLAG,JGRG,IOBT,ICDT,IHULEV,ISONDETYPE

REAL(KIND=JPRB) :: Z, ZDEP, ZFAC, ZFG, ZFGE, ZFOE, ZLEFT, &
 & ZPPP, ZRHSIDE, ZRIGHT 


REAL(KIND=JPRB),ALLOCATABLE,SAVE :: ZFGERR(:,:)
LOGICAL :: LLFGERR_EMPTY=.TRUE.
REAL(KIND=JPRB) :: ZHOOK_HANDLE
REAL(KIND=JPRB) :: ZFOELIM

!     -------------------------------------------------------------------------

#include "fcobs.h"
#include "nflgdse.intfb.h"
#include "cmoctmap.intfb.h"
#include "openmp_obs.h"

!     -------------------------------------------------------------------------

IF (LHOOK) CALL DR_HOOK('FGCHK',0,ZHOOK_HANDLE)

!     -------------------------------------------------------------------------
!*
!     ------------------------------------------------------------------

!        1.       INITIALIZE
!                 ----------

ICDTYP = ROBHDR(KOBS,MDB_CODETYPE_AT_HDR)

!* Definition du sigma B dans l espace des obs pour le QC
IF(ICDTYP == NGTHRB .AND..NOT.LECMWF) THEN
  IF(LLFGERR_EMPTY)THEN
    ALLOCATE(ZFGERR(0:MXSENSOR,NMXTCH))
    LLFGERR_EMPTY = .FALSE.
  ENDIF
  !* We only specify constant sigmabs for a subset of
  !  (generally not yet assimilated) channels
  ZFGERR(:,:)=RMDI
  ZFGERR(MSENSOR_HIRS, 1: 3)=(/0.239_JPRB,0.1498_JPRB,0.1265_JPRB/)
  ZFGERR(MSENSOR_HIRS, 8:10)=(/2.448_JPRB,1.4259_JPRB,2.1223_JPRB/)
  ZFGERR(MSENSOR_HIRS, 13)=1.3064_JPRB
  ZFGERR(MSENSOR_HIRS,16:19)=(/0.1_JPRB,0.1_JPRB,0.1_JPRB,0.1_JPRB/)
  ZFGERR(MSENSOR_AMSUA, 1: 4)=(/4.09_JPRB,3.00_JPRB,2.34_JPRB,0.97_JPRB/)
  ZFGERR(MSENSOR_AMSUA,14:15)=(/0.6079_JPRB,4.738_JPRB /)
  ZFGERR(MSENSOR_AMSUB,1:2)=(/4.28_JPRB,3.97_JPRB/)
  ZFGERR(MSENSOR_MHS,1:2)=(/4.28_JPRB,3.97_JPRB/)
  ZFGERR(MSENSOR_AIRS,1:28)       =1.0_JPRB
  ZFGERR(MSENSOR_AIRS,29:168)     =0.9_JPRB
  ZFGERR(MSENSOR_AIRS,169:256)    =0.42_JPRB
  ZFGERR(MSENSOR_AIRS,257:1500)   =1.0_JPRB
  ZFGERR(MSENSOR_AIRS,1501:1852)  =1.2_JPRB
  ZFGERR(MSENSOR_AIRS,1853:NMXTCH)=0.9_JPRB
  ZFGERR(MSENSOR_AIRS,1:NMXTCH)=0.3_JPRB
  ZFGERR(MSENSOR_IASI,1:NMXTCH) = 1.0_JPRB
  ZFGERR(MSENSOR_METEOSAT,1:2)=(/2.0_JPRB,1.0_JPRB /)
  ZFGERR(MSENSOR_MSG_HR,1:8)=(/0.25_JPRB,1.05_JPRB,1.05_JPRB,0.25_JPRB, &
                         &     0.25_JPRB,0.25_JPRB,0.25_JPRB,0.25_JPRB /)
  ZFGERR(MSENSOR_MSG,1:8)=(/0.1_JPRB,0.57_JPRB,0.57_JPRB,0.1_JPRB, &
                         &     0.1_JPRB,0.1_JPRB,0.1_JPRB,0.1_JPRB /)

ENDIF

!*
!     ------------------------------------------------------------------

!        2.       FIND OUT OBSERVATION
!                 --------------------
!*
!           2.1   WHICH VARIABLE

2 CONTINUE
ICMVNM = ROBODY(KBODY,MDBVNM)
!*
!           2.2   COLLECT REPORT/VARIABLE INFORMATION

!              2.2.1   OBS.AND CODE TYPE, LATITUDE, STATION ID

IOBTYP = ROBHDR(KOBS,MDBOTP)

ISENSOR = NMDI
IF(ICDTYP == NGTHRB .OR. ICDTYP == NSSMI) ISENSOR = ROBHDR(KOBS,MDBSSIA)
!*
!              2.2.2   OBSERVATION

Z    = ROBODY(KBODY,MDBVAR)         ! OBSERVED VARIABLE
ZDEP = ROBODY(KBODY,MDBOMF)         ! FIRST GUESS DEPARTURE
ZFOE = ROBODY(KBODY,MDBFOE)         ! FINAL OBSERVATION ERROR
ZFGE = ROBODY(KBODY,MDBFGE)         ! FIRST GUESS ERROR
ZFG  = Z - ZDEP                     ! FIRST GUESS VALUE
IVCO = ROBODY(KBODY,MDBVCO)         ! VERTICAL COORDINATE TYPE
ZPPP = ROBODY(KBODY,MDBPPP)         ! VERTICAL COORDINATE / PRESSURE

IF(.NOT.LECMWF)THEN
  IF (ISENSOR == MSENSOR_IASI) ZFOE = 5.0_JPRB
ENDIF

IF(ICDTYP == NGTHRB .AND. .NOT. LECMWF ) THEN
  IF(ZFGERR(ISENSOR,NINT(ZPPP)) /= RMDI) THEN
    ZFGE = ZFGERR(ISENSOR,NINT(ZPPP))
    ROBODY(KBODY,MDBFGE) = ZFGE
  ENDIF
ENDIF

!           2.2.3   FOR OZONE set fg-error = 0.20*ZFG
IF(ICMVNM == NVNUMB(68)) THEN
  ZFGE = 0.20_JPRB*ZFG            ! FIRST GUESS ERROR
!!  ROBODY(KBODY,MDBFGE) = ZFGE
ENDIF
!           2.2.4   FOR reo3 PWC set fg-error = 0.50*ZFG
IF(ICDTYP == NSTRO3 .AND. ICMVNM == NVNUMB(6)) THEN
  ZFGE = 0.50_JPRB*ZFG            ! FIRST GUESS ERROR 
!!  ROBODY(KBODY,MDBFGE) = ZFGE
ENDIF

!           2.2.5   FOR GPSRO set fg-error = 2*obs-error
IF(ICMVNM == NVNUMB(76) .AND. LECMWF) THEN
  ZFGE = 2.0_JPRB*ZFOE            ! FIRST GUESS ERROR sbh
ENDIF

!           2.2.6   FOR limb radiances set fg-error = 2.0*obs-error
IF(ICMVNM == NVNUMB(79)) THEN
  ZFGE = 2._JPRB*ZFOE            ! FIRST GUESS ERROR
ENDIF

!           2.2.7   FOR Radar reflectivities set fg-error = 3.0
! eric wattrelot temporary  for radar reflectivity
IF(ICMVNM == NVNUMB(74)) THEN
   ZFGE = 3.0_JPRB               ! FIRST GUESS ERROR
   ROBODY(KBODY,MDBFGE) = ZFGE
ENDIF

!           2.2.8   FOR GRG variables set fg-error = 0.2*fgvalue
DO JGRG=1,JPGRG
  IF(ICMVNM == NVNUMB(79+JGRG)) THEN
    ZFGE = 0.2_JPRB*ZFG            ! FIRST GUESS ERROR
!    IF(ICMVNM == NVNUMB(82)) ZFGE=0.10_JPRB*ZFG  !CO test
    ROBODY(KBODY,MDBFGE) = ZFGE
  ENDIF
ENDDO

!           2.2.8   For reo3 GHG set fg-error = 0.50*ZFG
IF(ICMVNM == NVNUMB(94)) THEN
  ZFGE = 0.02_JPRB*ZFG            ! CO2 FIRST GUESS ERROR
ENDIF
IF(ICMVNM == NVNUMB(95)) THEN
  ZFGE = 0.10_JPRB*ZFG            ! CH4 FIRST GUESS ERROR
ENDIF

!           2.2.9   For aerosol optical depth set fg-error = 0.20*ZFG
IF(ICMVNM == NVNUMB(78)) THEN
!  ZFGE = 2._JPRB*ZFOE            ! FIRST GUESS ERROR
  ZFGE = 0.2_JPRB*ZFG             ! FIRST GUESS ERROR
  ROBODY(KBODY,MDBFGE) = ZFGE
ENDIF

!           2.2.10   FOR HLoS, adjust obs error (ZFOE) via options
IF(ICMVNM == NVNUMB(77)) THEN

  ZFOELIM = ZFOE                    ! Max limit on OBS ERROR 

!              2.2.10.1   Option 1 (default)
  IF(NHLSFGOPT == 1) THEN

!    Default leaves ZFOEMAX unchanged

!              2.2.10.2   Option 2 (fixed value)
  ELSEIF(NHLSFGOPT == 2) THEN
     ZFOELIM = ZHLSFGOPT            ! Max limit on OBS ERROR 

!              2.2.10.3   Option 3 (fixed multiple of fg-error)
  ELSEIF(NHLSFGOPT == 3) THEN
     ZFOELIM = ZHLSFGOPT * ZFGE     ! Max limit on OBS ERROR 

!              2.2.10.4  Unknown option
  ELSE
    WRITE(NULOUT,'('' IN FGCHK: USING DEFAULT (1) SINCE NO LOS DEFINITION FOR '',I2)') NHLSFGOPT
  ENDIF

  ZFOE = MIN( ZFOE, ZFOELIM )       ! Max limit on OBS ERROR 
ENDIF
!*

!           2.2.11  DOPPLER WIND
IF(ICMVNM == NVNUMB(93)) THEN
   ZFGE = 3.0_JPRB
   ROBODY(KBODY,MDBFGE) = ZFGE
ENDIF

!*
!           2.3   CHECK IF SOMETHING IS MISSING

IF(ZDEP == RMDI .OR.ZFOE == RMDI .OR.ZFGE == RMDI) GOTO 4

!           2.5   CHECK THAT DIAGNOSED SIGMAB IS NOT TOO SMALL COMPARED TO SIGMAO
IF((ZFGE < (0.10_JPRB*ZFOE)).AND..NOT.LECMWF.AND.(ICMVNM /= NVNUMB(93))) THEN
  ZFGE = 0.10_JPRB*ZFOE
  ROBODY(KBODY,MDBFGE) = ZFGE
ENDIF

!*
!     ------------------------------------------------------------------

!        3.       FIRST GUESS CHECK
!                 -----------------
!*
!           3.0   INITIALIZE FLAG VALUE

IFLAG = NFLLIM(0)
!*
!           3.1   SETUP EQUATION WITH NORMALIZED ERRORS AND DEPARTURES

ZLEFT  = ZDEP*ZDEP
ZRIGHT = ZFOE*ZFOE + ZFGE*ZFGE
ZFAC=1.0_JPRB

!*
!           3.2   FIND FLAG VALUE FOR DIFFERENT VARIABLES

FLAG_LOOP: DO JFLAG = 1, 3

!              3.2.1   GEOPOTENTIAL
  IF(ICMVNM == NVNUMB( 3)) THEN
    IVAR=NVAR_Z

!              3.2.2   SURFACE PRESSURE
  ELSEIF(ICMVNM == NVNUMB(47)) THEN
    IVAR=NVAR_PS

!              3.2.3   THICKNESS
!                      - MODIFY REJECTION LIMITS BY ZFAC
  ELSEIF(ICMVNM == NVNUMB( 4)) THEN
    IVAR=NVAR_DZ

!              3.2.4   TEMPERATURE
  ELSEIF(ICMVNM == NVNUMB( 8) .OR. ICMVNM == NVNUMB(10)) THEN
    IVAR=NVAR_T

!              3.2.5   SPECIFIC HUMIDITY
  ELSEIF(ICMVNM == NVNUMB(63)) THEN
    IVAR=NVAR_Q

!              3.2.6   RELATIVE HUMIDITY
  ELSEIF(ICMVNM == NVNUMB( 5) .OR. ICMVNM == NVNUMB( 7)) THEN
    IVAR=NVAR_H

!              3.2.7   RADIANCE
  ELSEIF(ICMVNM == NVNUMB(50)) THEN
    IVAR=NVAR_RAD

!              3.2.8   TOTAL COLUMN WATER VAPOUR/PWC
  ELSEIF(ICMVNM == NVNUMB(6)) THEN
    IVAR=NVAR_PWC
    
!              3.2.9   TOTAL COLUMN OZONE
  ELSEIF(ICMVNM == NVNUMB(68)) THEN
    IVAR=NVAR_TO3

!              3.2.10   GPS ATMOSPHERIC PATH DELAY
  ELSEIF(ICMVNM == NVNUMB(75)) THEN
    IVAR=NVAR_APD

!              3.2.11   GPS RO measurements
  ELSEIF(ICMVNM == NVNUMB(76)) THEN
    IVAR=NVAR_RO       
                     
!              3.2.12   Limb radiances
  ELSEIF(ICMVNM == NVNUMB(79)) THEN
    IVAR=NVAR_LRA                            

!              3.2.13   AEROSOL OPTICAL DEPTH AT 0.55 MICRONS
  ELSEIF(ICMVNM == NVNUMB(78)) THEN
    IVAR=NVAR_AOD
    ZRIGHT = ZFOE*ZFOE + MINVAL( (/ZFGE*ZFGE,(0.2*Z)**2/) )
!    print*,'RICHARD:',ZFGE*ZFGE,(0.2*Z)**2,MINVAL( (/ZFGE*ZFGE,(0.2*Z)**2/) ),ZFOE*ZFOE,ZRIGHT*25.0,ZDEP*ZDEP

!              3.2.14   GRG1: NO2
  ELSEIF(ICMVNM == NVNUMB(80)) THEN
    IVAR=NVAR_GRG(1)

!              3.2.15   GRG2: SO2
  ELSEIF(ICMVNM == NVNUMB(81)) THEN
    IVAR=NVAR_GRG(2)

!              3.2.16   GRG3: CO
  ELSEIF(ICMVNM == NVNUMB(82)) THEN
    IVAR=NVAR_GRG(3)

!              3.2.17   GRG4: HCHO
  ELSEIF(ICMVNM == NVNUMB(83)) THEN
    IVAR=NVAR_GRG(4)

!              3.2.18   GRG5: GO3   
  ELSEIF(ICMVNM == NVNUMB(84)) THEN
    IVAR=NVAR_GRG(5)

!              3.2.19  CLOUD OPTICAL DEPTH 
  ELSEIF(ICMVNM == NVNUMB(85)) THEN
    IVAR=NVAR_COD

!              3.2.20  RATIO OF FINE MODE TO TOTAL AEROSOL OPTICAL DEPTH AT 0.55 MICRONS
  ELSEIF(ICMVNM == NVNUMB(86)) THEN
    IVAR=NVAR_RAO

!              3.2.21  AEROSOL OPTICAL DEPTH (MULTI-CHANNEL)
  ELSEIF(ICMVNM == NVNUMB(87)) THEN
    IVAR=NVAR_ODA

!              3.2.22  AEROSOL REFLECTANCE 
  ELSEIF(ICMVNM == NVNUMB(88)) THEN
    IVAR=NVAR_RFA

!              3.2.23   GHG1: CO2   
  ELSEIF(ICMVNM == NVNUMB(94)) THEN
    IVAR=NVAR_GHG(1)

!              3.2.24   GHG2: CH4   
  ELSEIF(ICMVNM == NVNUMB(95)) THEN
    IVAR=NVAR_GHG(2)

!              3.2.25  HLoS (LINE-OF-SIGHT) WIND COMPONENT
  ELSEIF(ICMVNM == NVNUMB(77)) THEN
    IVAR=NVAR_HLS

!              3.2.26 REFLECTIVITY RADAR
  ELSEIF(ICMVNM == NVNUMB(74)) THEN
    IVAR=NVAR_RFL

!              3.2.27 DOPPLER WIND
  ELSEIF(ICMVNM == NVNUMB(93)) THEN
    IVAR=NVAR_DOW
    ZFAC = 400.0_JPRB/(ZRIGHT*RBGQC(IVAR,IOBTYP,JFLAG))  ! 20 m/s

!              3.2.28  VARIABLE MISSING FROM F.G. TEST

  ELSE
    WRITE(NULOUT,'('' IN FGCHK: NO FG. DEFINITION FOR '',I2)') ICMVNM
    EXIT FLAG_LOOP
  ENDIF

!*
!           3.3   MODIFY FLAG LIMITS

  IF(ICDTYP == NGTHRB .OR. ICDTYP == NSSMI) THEN
    ICHAN = NINT(ZPPP)
    ZRHSIDE = ZRIGHT*RBGQC_RAD1C(ISENSOR,ICHAN,JFLAG)
  ELSE 
    IF (LHUBERBGQC(IVAR,IOBTYP)) THEN
      IHULEV = 3
      IF (ZPPP < 85000.0_JPRB) THEN
        IHULEV = 2
      ELSEIF (ZPPP < 15000.0_JPRB) THEN
        IHULEV = 1
      ENDIF
      IF (IOBTYP == NTEMP .OR. IOBTYP == NPILOT) THEN
!        IF (IOBTYP == NTEMP) THEN
!          ISONDETYPE = ROBHDR(KOBS,MDB_SONDE_TYPE_AT_HDR)
!        ELSE
          ISONDETYPE = NMDI 
!        ENDIF
! Good sondes: VIZ (10,11,14,21,31,38,49,51), SIPPICAN (82,83,84,85,86,87),
!              VAISALA RS92 (78,79,80,81), VAISALA RS90 (71,72,73,74,78),  
!              MEISEI (22,47,55)     
        IF (ANY(ISONDETYPE == (/10,11,14,21,31,38,49,51,82,83,84,85,86,87, &
                              & 78,79,80,81,71,72,73,74,78,22,47,55/))) THEN
          ZRHSIDE = ZRIGHT*RHUBERBGQC_SONDEGOOD(IVAR,IOBTYP,IHULEV,JFLAG)*ZFAC
        ELSE
         ZRHSIDE = ZRIGHT*RHUBERBGQC_SONDEOK(IVAR,IOBTYP,IHULEV,JFLAG)*ZFAC
        ENDIF
      ELSE
        CALL CMOCTMAP('CODETOSQ',NULOUT,IOBTYP,ICDTYP,IOBT,ICDT)
        ZRHSIDE = ZRIGHT*RHUBERBGQC(IVAR,ICDT,IOBT,IHULEV,JFLAG)*ZFAC
      ENDIF
    ELSE
      ZRHSIDE = ZRIGHT*RBGQC(IVAR,IOBTYP,JFLAG)*ZFAC
    ENDIF
  ENDIF
  
!*
!           3.4   EVALUATE EQUATION

  IF(ZLEFT > ZRHSIDE) IFLAG = JFLAG
  
!*
!           3.5   CLOSE THE LOOP

ENDDO FLAG_LOOP

!*
!           3.6   SET FIRST GUESS DATUM FLAG AND AN EVENT

IF(IFLAG > NFLLIM(0)) THEN
  CALL NFLGDSE(KBODY,'FIRST',IFLAG)
  ROBODY(KBODY,MDBDEV1) = ZCHEV1( ROBODY(KBODY,MDBDEV1),ND1EVENT(10))
ENDIF

!*
!     ------------------------------------------------------------------

!        4.       RETURN
!                 ------
4 CONTINUE

!     -------------------------------------------------------------------------

IF (LHOOK) CALL DR_HOOK('FGCHK',1,ZHOOK_HANDLE)
END SUBROUTINE FGCHK
