SUBROUTINE SUJB

!**** *SUJB*   - Routine to initialize Jb management common - YOMJG
!*               Background/First Guess constraint

!     Purpose.
!     --------
!           Initialize YOMJG
!**   Interface.
!     ----------
!        *CALL* *SUJB*

!        Explicit arguments :
!        --------------------

!        Implicit arguments :
!        --------------------
!        COMMON YOMJB

!     Method.
!     -------
!        See documentation

!     Externals.
!     ----------

!     Reference.
!     ----------
!        ECMWF Research Department documentation of the IFS

!     Author.
!     -------
!        Bill Heckley   *ECMWF*

!     Modifications.
!     --------------
!        Original : 91-06-06
!        Modified : 91-10-15 Bill Heckley and Mats Hamrud ECMWF
!                            Use of MIOLIB for IO on forecast error files
!        Bill Heckley 04:02:92 - Provision for use of either P or T as mass
!                                variable
!        Modified by R. EL Khatib : 93-04-02 Set-up defaults controled by LECMWF
!        D. Giard :     93-06-25 Test on NEINI, for it is too late to modify it
!        E Andersson    06:07:93 : Non-separable structure functions
!        Roberto Buizza 93-10-27 : Covariance matrix constraint when
!                                  computing optimal perturbations
!        F. Bouttier    95-02-06 : Rename routine from SUJG0 to SUJB
!                                  Add more adjustable paramters
!        L. Isaksen     96-05-05 : Adapted for Message Passing
!        E. Holm        97-11-18 : Add ozone in Jb
!        F. Rabier      98-01-06 : set switches to false when LGUESS=false
!        G. Gregoric and S. Issara 97-05   3DVAR ALADIN
!        Y.Tremolet     05-01-01 : Remove NEINI
!        M.Hamrud      01-Oct-2003 CY28 Cleaning
!        Y.Tremolet    10-Jun-2004 Initial condition optional in control variable
!        C. Fischer    21-May-2005 Aladin mean (U,V) components std dev (2 profiles)
!                      come in sujb just as spa1 now is in yomsp (so arp/ifs do see it)
!        R. El Khatib: 31-Aug-2007 Initialise uninitialised variable
!        E. Holm        07-12-12   Introduce LJB_SUPSAT for humidity
!                                  control variable setting including 
!                                  supersaturation and q-T balance
!        R. El Ouaraini 11-Feb-2008: add REDQGLOLAM
!        L. Berre      06-Mar-2008 Remplace LDLATLONG by LSBLATLONG
!        Y.Tremolet    27-Nov-2008 Option for no balance in stratosphere
!     D. Dee        10-Oct-2008 generalise VarBC
!     A. Fouilloux  09-09-09 remove any observation calls (LOBS) and varbc_setup...
!     ------------------------------------------------------------------

USE PARKIND1  ,ONLY : JPIM     ,JPRB
USE YOMHOOK   ,ONLY : LHOOK,   DR_HOOK
USE YOMDIM   , ONLY : NFLEVG   ,NSMAX    ,NUNDEFLD
USE YOMCT0   , ONLY : NCONF    ,NCNTVAR  ,LGUESS   ,LOBSC1   ,LBACKG, &
                    & LELAM
USE YOMVAR   , ONLY : LINITCV
USE YOMCT0B  , ONLY : LECMWF
USE YOMLUN   , ONLY : NULOUT   ,NULNAM
USE YOMJG    , ONLY : L3DBGERR ,LCFCE    , LSUBBG, LCTLFG   ,&
 & LRDQERR  ,LSBLATLONG  , LJB_SUPSAT,&
 & LJBTEST  ,LSPFCE   ,LJBENER  ,LFACHRO  ,&
 & LCLMSFCE ,LCORCOSU ,LCORCOSU_VCOR ,&
 & LJB_OMEGA_BALANCE  ,LJB_NONLINEAR_BALANCE ,&
 & LJB_NONLINEAR_CVHUM, LJB_NONLINEAR_CVO3, &
 & LJBBALBETA ,NPSMAX   ,&
 & NGEOBAL  ,NGEOCOR  ,NJBVERB  ,&
 & REDNMC   ,REDQGLOLAM   ,TMEANUVER, LEVSREDNMC, NLEVREDNMC, &
 & RAMENER  ,RSCENER  , RJB_CSLEN,&
 & LJGNRSGP ,L_JBVCOORD, LJB_UNIVARIATE, LJB_TLBALSTAT, &
 & N_SPJB_VARS, SPJB_VARS_INFO, M_GRIBCODES, M_GRIBCODES_FCE, C_COR_STRINGS, &
 & NOFCEF ,&
 & REDINC  ,NLEV_REDINC, &
 & NAEROCV, &
 & LBALSTRATO, NLEVBAL0, NLEVBAL1, &
 & ELC, LJB_OMEGA_BALANCE_RELAX, LJB_NONLINEAR_BALANCE_RELAX
USE YOMCVA   , ONLY : NVA3SP, NVA3D, NVA2D, NVA1D, NGRBVAR
USE YOMCOSJB, ONLY: LJBZERO, LJPZERO, LJLZERO, LJTZERO
USE YOMNMIA  , ONLY : NLEX     ,NITNMI   ,NVMODF   ,NVMODF1  ,&
 & NVMODF2  ,NVMODM   ,NVMOD    ,NVMODJB  ,LNMIRQ   ,&
 & LRPIMP   ,LCONMO   ,LCOIMP  
USE YOMWAVELET,ONLY : LJBWAVELET, LJBWSTATS, CINBGSTATES, &
 & N_BGMEMBERS, N_BGDATES, NSMIN_WAVELET, L_IN_WAVELET_STATS_CALC, SKYLINE_TOL
USE YOM_YGFL , ONLY : YO3, YGFLC, YGFL, YGHG, NGHG, YGRG, NGRG, YAERO, NAERO
USE YOMGRB, ONLY : NGRBLNSP, NGRBVO, NGRBD, NGRBT, NGRBQ, NGRBO3, NGRBAERLG, &
                 & NGRBUCTP, NGRBUCLN, NGRBUCDV,NGRBNOXLOG

IMPLICIT NONE

INTEGER(KIND=JPIM) :: IITNMI, JFIELD, ICODE, IGFL, &
                    & IDIM_SP7A2, IDIM_SP7A3, IDIM_GP7A3
INTEGER(KIND=JPIM) :: JLEV, IZ, IGHG, IGRG, IAERO, IGRIB
INTEGER(KIND=JPIM), ALLOCATABLE :: igrb2(:), igrb3(:)
CHARACTER(LEN=8) :: CLSTRING
REAL(KIND=JPRB) :: ZHOOK_HANDLE

#include "abor1.intfb.h"
#include "posnam.intfb.h"
#include "namjg.h"
#include "namjbcodes.h"
!      -----------------------------------------------------------

!*       1.    Set default values.
!              -------------------

!        1.1 Set implicit default values

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

!BEN
NAEROCV=0
IF (NAERO > 0) NAEROCV=1  ! number of aerosol control variables

NGEOBAL    = 1
NGEOCOR    = 1
NJBVERB    = 1
REDNMC     =  0.7_JPRB
REDQGLOLAM =  1.3_JPRB
RJB_CSLEN  = 1000.E3_JPRB
LEVSREDNMC = .FALSE.
NLEVREDNMC = 0
NLEV_REDINC=0
IF(NFLEVG == 91) NLEV_REDINC=0
RAMENER = -1.0_JPRB
RSCENER = 0.1_JPRB
LCFCE   = .FALSE.
LSPFCE  = .FALSE.
LCTLFG  = .FALSE.
L_JBVCOORD = .FALSE.
LJB_UNIVARIATE=.FALSE.
LJB_OMEGA_BALANCE = .FALSE.
LJB_OMEGA_BALANCE_RELAX = .FALSE.
LJB_NONLINEAR_BALANCE = .FALSE.
LJB_NONLINEAR_BALANCE_RELAX = .FALSE.
ELC        = 50000.0_JPRB
LJB_NONLINEAR_CVHUM = .FALSE.
LJB_NONLINEAR_CVO3 = .FALSE.
LJB_SUPSAT = .FALSE.
LJBBALBETA = .FALSE.
LJB_TLBALSTAT = .FALSE.
NPSMAX = 15
LJGNRSGP= .FALSE.
LFACHRO = .TRUE.
LRDQERR = .FALSE.
LSBLATLONG = .FALSE.
LJBTEST = .FALSE.
LJBENER = .FALSE.
LJBWAVELET = .FALSE.
L_IN_WAVELET_STATS_CALC=.FALSE.
LJBWSTATS  = .FALSE.
CINBGSTATES = 'state_'
N_BGMEMBERS  = 0
N_BGDATES    = 0
NSMIN_WAVELET = MIN(42_JPIM, NSMAX)
SKYLINE_TOL=0.1_JPRB
LJBZERO=.false.
LJPZERO=.false.
LJLZERO=.false.
LJTZERO=.false.
LBALSTRATO=.TRUE.
IF (NFLEVG==91) THEN
  NLEVBAL0=22  ! 20 hPa
  NLEVBAL1=30  ! 50 hPa
ELSEIF (NFLEVG==60) THEN
  NLEVBAL0=11  !  5 hPa
  NLEVBAL1=17  ! 20 hPa
ELSE
  NLEVBAL0=0 ! set NLEVBAL0==NLEVBAL1 now so that the test after the
  NLEVBAL1=0 ! read of NAMJG will fail if the user has not changed them.
ENDIF

! ky: N_SPJB_VARS set to 0 for 9xx configurations (to avoid some aborts
!     later in some parts of the code which are actually useless for such
!     configurations, cf. the ABOR1 later in this routine
!     CALL ABOR1 ('UNRECOGNIZED GRIB CODE IN M_GRIBCODES') ).
!     But it is probable that there are configurations
!     between 1 and 899 which can run with N_SPJB_VARS=0 (probably all
!     configurations other than 131 and 601?).
IF (NCONF/100 == 9) THEN
  N_SPJB_VARS=0
ELSE
  N_SPJB_VARS=5
  IF (YO3%LACTIVE) N_SPJB_VARS=N_SPJB_VARS+1
ENDIF
IF (ANY(YGHG%LACTIVE)) N_SPJB_VARS=N_SPJB_VARS+NGHG
IF (ANY(YGRG%LACTIVE)) N_SPJB_VARS=N_SPJB_VARS+NGRG
IF (ANY(YAERO%LACTIVE))N_SPJB_VARS=N_SPJB_VARS+NAEROCV
WRITE(NULOUT,*)'SUJB: Number of control variables: ',N_SPJB_VARS

IF(ALLOCATED(TMEANUVER)) DEALLOCATE(TMEANUVER)
IF (.NOT.LELAM) THEN
  ALLOCATE(TMEANUVER(1,1))
  TMEANUVER=0.0_JPRB
ELSE
  ALLOCATE(TMEANUVER(NFLEVG,2))
!cf will be set intelligently later on, in suejbstd
  TMEANUVER=0.0_JPRB
ENDIF

!        1.2 Modify default values according to LECMWF

IF (LECMWF) THEN
  IF(NCONF /= 1.OR.LOBSC1) THEN
    NVMODF=MIN(7,NFLEVG)
    NVMODF1=NFLEVG
    NVMODF2=NFLEVG
  ENDIF
  IF(LGUESS.OR.(NCONF==801.AND.LBACKG)) THEN
    L3DBGERR= .TRUE.
    LCLMSFCE= .TRUE.
    LCORCOSU= .TRUE.
  ELSE
    L3DBGERR= .FALSE.
    LCLMSFCE= .FALSE.
    LCORCOSU= .FALSE.
  ENDIF
  IF (NCONF == 131) LJBWAVELET = .TRUE.
  LJB_OMEGA_BALANCE = .TRUE.
  LJB_NONLINEAR_BALANCE = .TRUE.
  LJB_NONLINEAR_CVHUM = .TRUE.
  LJB_NONLINEAR_CVO3 = .FALSE.
  LJB_SUPSAT = .TRUE.
  LJB_TLBALSTAT = .TRUE.
ELSE
  L3DBGERR= .FALSE.
  LCLMSFCE= .FALSE.
  LCORCOSU= .FALSE.
ENDIF
LCORCOSU_VCOR= .FALSE.

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

!*       2.    Read NAMELIST NAMJG
!              -------------------

CALL POSNAM(NULNAM,'NAMJG')
READ(NULNAM,NAMJG)

IF (N_SPJB_VARS<0 .OR. N_SPJB_VARS>SIZE(M_GRIBCODES)) THEN
  WRITE (NULOUT,*) 'Bad value for N_SPJB_VARS...'
  WRITE (NULOUT,*) 'N_SPJB_VARS=',N_SPJB_VARS
  WRITE (NULOUT,*) 'SIZE(M_GRIBCODES)=',SIZE(M_GRIBCODES)
  CALL ABOR1 ('Bad value for N_SPJB_VARS')
ENDIF

IF ((.NOT.LCORCOSU).AND.LCORCOSU_VCOR) THEN
  WRITE(NULOUT,*) 'LCORCOSU switched off but sub-key LCORCOSU_VCOR is active'
  CALL ABOR1('SUJB : UNCONSISTENT LCORCOSU KEYS')
ENDIF

!*       2.2   Initialize default GRIB codes
!              -----------------------------

!--- GRIB codes for fields passed between the model and Jb.
!--- I.e. for fields in SPA3JB and SPA2JB.

M_GRIBCODES(:)=-999
M_GRIBCODES(1) = NGRBVO
M_GRIBCODES(2) = NGRBD
M_GRIBCODES(3) = NGRBT
M_GRIBCODES(4) = NGRBLNSP
M_GRIBCODES(5) = NGRBQ
M_GRIBCODES(6) = NGRBO3
IGRIB = 6
DO IGHG = 1,NGHG
    IGRIB = IGRIB + 1
    M_GRIBCODES(IGRIB) = YGHG(IGHG)%IGRBCODE
ENDDO
DO IGRG = 1,NGRG
    IGRIB = IGRIB + 1
    M_GRIBCODES(IGRIB) = YGRG(IGRG)%IGRBCODE
ENDDO
!BEN This has to be made more general by using JPAEROCV!!!! 
DO IAERO = 1,NAEROCV
    IGRIB = IGRIB + 1
    M_GRIBCODES(IGRIB) = NGRBAERLG 
ENDDO

!--- Define the GRIB codes used for input background error fields
!--- (i.e. for fields in FCEBUF), and the identifying strings used
!--- in the ".cv" file.

M_GRIBCODES_FCE(:)=-999
C_COR_STRINGS(:) = "COR STRING IS UNDEFINED"

M_GRIBCODES_FCE(1) = NGRBVO
C_COR_STRINGS(1) = "VORTICITY"

IF (LJB_UNIVARIATE) THEN
  M_GRIBCODES_FCE(2) = NGRBD
  C_COR_STRINGS(2) = "DIVERGENCE"
  M_GRIBCODES_FCE(3) = NGRBT
  C_COR_STRINGS(3) = "TEMPERATURE AND LNSP"
  M_GRIBCODES_FCE(4) = NGRBLNSP
  C_COR_STRINGS(4) = "COR STRING IS UNDEFINED" ! LNSP stats read with T stats
ELSE
  M_GRIBCODES_FCE(2) = NGRBUCDV   ! Unbalanced divergence
  C_COR_STRINGS(2) = "UNBALANCED DIVERGENCE"
  M_GRIBCODES_FCE(3) = NGRBUCTP   ! Unbalanced T
  C_COR_STRINGS(3) = "UNBALANCED T AND LNSP"
  M_GRIBCODES_FCE(4) = NGRBUCLN   ! Unbalanced LNSP
  C_COR_STRINGS(4) = "COR STRING IS UNDEFINED" ! LNSP stats read with T stats
ENDIF

M_GRIBCODES_FCE(5) = NGRBQ
IF (LJB_NONLINEAR_CVHUM) THEN
  C_COR_STRINGS(5) = "NORMALIZED RELATIVE HUMIDITY"
ELSE
  C_COR_STRINGS(5) = "SPECIFIC HUMIDITY"
ENDIF
M_GRIBCODES_FCE(6) = NGRBO3
C_COR_STRINGS(6) = "UNBALANCED OZONE"

IGRIB = 6
DO IGHG = 1,NGHG
  IGRIB = IGRIB + 1
  M_GRIBCODES_FCE(IGRIB) = YGHG(IGHG)%IGRBCODE
  C_COR_STRINGS(IGRIB) = YGHG(IGHG)%CNAME
  WRITE(NULOUT,*)'SUJB: GEMS GHG control variable : ', &
   & TRIM(C_COR_STRINGS(IGRIB)),M_GRIBCODES(IGRIB)
ENDDO
DO IGRG = 1,NGRG
  IGRIB = IGRIB + 1
  M_GRIBCODES_FCE(IGRIB) = YGRG(IGRG)%IGRBCODE
  IF(YGRG(IGRG)%IGRBCODE == NGRBNOXLOG) THEN
  C_COR_STRINGS(IGRIB) = YGRG(IGRG)%CNAME
    WRITE(NULOUT,*)'SUJB: GEMS GRG LOG NOX control variable : ', &
     & TRIM(C_COR_STRINGS(IGRIB)),M_GRIBCODES(IGRIB)
  ELSE
    C_COR_STRINGS(IGRIB) = YGRG(IGRG)%CNAME
  WRITE(NULOUT,*)'SUJB: GEMS GRG control variable : ', &
   & TRIM(C_COR_STRINGS(IGRIB)),M_GRIBCODES(IGRIB)
  ENDIF
ENDDO
DO IAERO = 1,NAEROCV
  IGRIB = IGRIB + 1
  M_GRIBCODES_FCE(IGRIB) = NGRBAERLG
  C_COR_STRINGS(IGRIB) = "Aerosol large mode mixing ratio" 
  WRITE(NULOUT,*)'SUJB: GEMS AER control variable : ', &
   & TRIM(C_COR_STRINGS(IGRIB)),M_GRIBCODES(IGRIB)
ENDDO

!*       2.5   Read NAMELIST NAMJBCODES
!              ------------------------

IF (N_SPJB_VARS>0) THEN
  CALL POSNAM(NULNAM,'NAMJBCODES')
  READ(NULNAM,NAMJBCODES)
ENDIF

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

!*       3.    Processing of namelist parameters
!              ---------------------------------

LSUBBG  = .NOT.LCTLFG

!           3.1 Modify default settings for treatment of forecast errors
!               --------------------------------------------------------

IF (NCNTVAR == 1) LCFCE = .TRUE.
IF (NCONF==801.AND.LBACKG) THEN
  LSPFCE=.TRUE.
  LCFCE=.FALSE.
ENDIF
L3DBGERR = L3DBGERR .AND. .NOT.LCFCE

!*       3.2   Modify NMI settings if necessary
!              --------------------------------

WRITE(NULOUT,'('' *** Warning NMI settings possibly '',&
 & ''changed by SUJB ***'')')  
!     NITNMI MUST BE SET TO CORRECT VALUE TO ALLOW
!     APPROPRIATE SPACE FOR TRAJECTORY (*SUALLT*)
IITNMI = NITNMI
IF (NCONF/100 == 1) THEN
  IF (.NOT.LNMIRQ) NITNMI = 0
  WRITE(NULOUT,'('' NITNMI='',I3)') NITNMI
ENDIF
IF (NCONF/100 == 1.AND. LGUESS) THEN
  IF (LRPIMP) LCOIMP = .TRUE.
  IF (.NOT.LRPIMP .OR. (LRPIMP .AND.NLEX /= 0)) LCONMO=.TRUE.
  WRITE(NULOUT,'(''LCOIMP='',L1)') LCOIMP
  IF (NVMODF  > NFLEVG  ) NVMODF  = NFLEVG
  IF (NVMODF1 > NFLEVG  ) NVMODF1 = NFLEVG
  IF (NVMODF2 > NFLEVG+1) NVMODF2 = NFLEVG + 1
  IF (NVMODF  <= 0) NVMODF  = MIN(7,NFLEVG)
  IF (NVMODF1 <= 0) NVMODF1 = MIN(5,NFLEVG)
  IF (NVMODF2 <= 0) NVMODF2 = MIN(8,NFLEVG+1)
  IF (NVMODF2 <= NVMODF1) NVMODF2 = NVMODF1 + 1
  NVMODM = MAX(NVMOD,NVMODF)
  WRITE(NULOUT,'('' LCONMO='',L1,'', NVMODM='',I3)')LCONMO,NVMODM
  WRITE(NULOUT,'('' NVMODF ='',I3,'' NVMODF1='',I3,'' NVMODF2='',&
   & I3)') NVMODF,NVMODF1,NVMODF2  
ENDIF
NVMODJB=NVMODF2-1
WRITE(NULOUT,FMT='('' NVMODJB ='',I3)') NVMODJB


!        3.4 Namelist checking

LJBWAVELET = LJBWAVELET.AND.LINITCV

IF (LJBWAVELET .AND. LJBWSTATS .AND. (N_BGMEMBERS<2 .OR. N_BGDATES<1)) THEN
  CALL ABOR1 ('Wavelet Jb: LJBWSTATS .AND. (N_BGMEMBERS<2 .OR. N_BGDATES<1)')  
ENDIF

IF (.NOT.LBALSTRATO .AND. NLEVBAL0>=NLEVBAL1) THEN
  CALL ABOR1 ('NLEVBAL0>=NLEVBAL1 is not allowed for LBALSTRATO==F')
ENDIF

!        3.5 Scaling factor to reduce the increments in upper levels
ALLOCATE(REDINC(NFLEVG))
REDINC(:)=1.0_JPRB
IF(NLEV_REDINC > 0) THEN
  DO JLEV=NLEV_REDINC,1,-1
    IZ=2*(NLEV_REDINC-JLEV)+1
    REDINC(JLEV)=0.5_JPRB**IZ
  ENDDO
  REDINC(1)=0.0_JPRB
ENDIF
WRITE(NULOUT,*)'SUJB: NLEV_REDINC=',NLEV_REDINC
WRITE(NULOUT,*)'SUJB: REDINC: ',(REDINC(JLEV),JLEV=1,NFLEVG)

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

!*       4.    Setup SPJB_VARS_INFO
!              --------------------

IF (N_SPJB_VARS>0) THEN
  IF(ALLOCATED(SPJB_VARS_INFO)) DEALLOCATE(SPJB_VARS_INFO)
  ALLOCATE (SPJB_VARS_INFO(N_SPJB_VARS))

  SPJB_VARS_INFO(:)%L_IN_SPA3  = .FALSE.
  SPJB_VARS_INFO(:)%L_IN_SPA2  = .FALSE.
  SPJB_VARS_INFO(:)%L_IN_SPGFL = .FALSE.
  SPJB_VARS_INFO(:)%L_IN_GPGFL = .FALSE.
  SPJB_VARS_INFO(:)%IPT        = NUNDEFLD
  SPJB_VARS_INFO(:)%IPTJB      = NUNDEFLD
  SPJB_VARS_INFO(:)%IPTBG      = NUNDEFLD
  SPJB_VARS_INFO(:)%IPTFCE     = NUNDEFLD
ENDIF

NVA2D=0
NVA3D=0
NOFCEF=0
IDIM_SP7A2=0
IDIM_SP7A3=0
IDIM_GP7A3=0

ALLOCATE(igrb2(N_SPJB_VARS))
ALLOCATE(igrb3(N_SPJB_VARS))

DO JFIELD=1,N_SPJB_VARS
  ICODE = M_GRIBCODES(JFIELD)

  SPJB_VARS_INFO(JFIELD)%IGRIBCODE     = M_GRIBCODES(JFIELD)
  SPJB_VARS_INFO(JFIELD)%IGRIBCODE_FCE = M_GRIBCODES_FCE(JFIELD)
  SPJB_VARS_INFO(JFIELD)%COR_STRING    = C_COR_STRINGS(JFIELD)

!-- lookup ICODE in the GMV fields

  IF (ICODE==NGRBVO .OR. ICODE==NGRBD .OR. ICODE==NGRBT .OR. &
    & ICODE==NGRBLNSP) THEN

    IF (ICODE==NGRBLNSP) THEN
        NVA2D=NVA2D+1
        igrb2(NVA2D)=NGRBLNSP
        IDIM_SP7A2=IDIM_SP7A2+1
        SPJB_VARS_INFO(JFIELD)%L_IN_SPA2 = .TRUE.
        SPJB_VARS_INFO(JFIELD)%IPT       = 1
        SPJB_VARS_INFO(JFIELD)%IPTJB     = NVA2D
        SPJB_VARS_INFO(JFIELD)%IPTBG     = IDIM_SP7A2
        SPJB_VARS_INFO(JFIELD)%IPTFCE    = NOFCEF+1
        NOFCEF=NOFCEF+1
    ELSEIF (ICODE==NGRBVO) THEN
        NVA3D=NVA3D+1
        igrb3(NVA3D)=NGRBVO
        IDIM_SP7A3=IDIM_SP7A3+1
        SPJB_VARS_INFO(JFIELD)%L_IN_SPA3 = .TRUE.
        SPJB_VARS_INFO(JFIELD)%IPT       = 1
        SPJB_VARS_INFO(JFIELD)%IPTJB     = NVA3D
        SPJB_VARS_INFO(JFIELD)%IPTBG     = IDIM_SP7A3
        SPJB_VARS_INFO(JFIELD)%IPTFCE    = NOFCEF+1
        NOFCEF=NOFCEF+NFLEVG
    ELSEIF (ICODE==NGRBD) THEN
        NVA3D=NVA3D+1
        igrb3(NVA3D)=NGRBD
        IDIM_SP7A3=IDIM_SP7A3+1
        SPJB_VARS_INFO(JFIELD)%L_IN_SPA3 = .TRUE.
        SPJB_VARS_INFO(JFIELD)%IPT       = 2
        SPJB_VARS_INFO(JFIELD)%IPTJB     = NVA3D
        SPJB_VARS_INFO(JFIELD)%IPTBG     = IDIM_SP7A3
        SPJB_VARS_INFO(JFIELD)%IPTFCE    = NOFCEF+1
        NOFCEF=NOFCEF+NFLEVG
    ELSEIF (ICODE==NGRBT) THEN
        NVA3D=NVA3D+1
        igrb3(NVA3D)=NGRBT
        IDIM_SP7A3=IDIM_SP7A3+1
        SPJB_VARS_INFO(JFIELD)%L_IN_SPA3 = .TRUE.
        SPJB_VARS_INFO(JFIELD)%IPT       = 3
        SPJB_VARS_INFO(JFIELD)%IPTJB     = NVA3D
        SPJB_VARS_INFO(JFIELD)%IPTBG     = IDIM_SP7A3
        SPJB_VARS_INFO(JFIELD)%IPTFCE    = NOFCEF+1
        NOFCEF=NOFCEF+NFLEVG
    ELSE
        CALL ABOR1 ('THIS SHOULD NEVER HAPPEN 1')
    ENDIF

!-- lookup ICODE in GFL fields

  ELSEIF (ANY(YGFLC(1:YGFL%NUMFLDS)%IGRBCODE==ICODE)) THEN

    IGFL=1
    DO WHILE (YGFLC(IGFL)%IGRBCODE/=ICODE)
      IGFL=IGFL+1
    ENDDO

    NVA3D=NVA3D+1
    igrb3(NVA3D)=ICODE
    SPJB_VARS_INFO(JFIELD)%IPTJB  = NVA3D

    SPJB_VARS_INFO(JFIELD)%IPTFCE = NOFCEF+1
    NOFCEF=NOFCEF+NFLEVG

    IF (YGFLC(IGFL)%LSP) THEN
      IDIM_SP7A3=IDIM_SP7A3+1
      SPJB_VARS_INFO(JFIELD)%L_IN_SPGFL = .TRUE.
      SPJB_VARS_INFO(JFIELD)%IPT        = YGFLC(IGFL)%MPSP
      SPJB_VARS_INFO(JFIELD)%IPTBG      = IDIM_SP7A3
    ELSEIF (YGFLC(IGFL)%LGP) THEN
      IDIM_GP7A3=IDIM_GP7A3+1
      SPJB_VARS_INFO(JFIELD)%L_IN_GPGFL = .TRUE.
      SPJB_VARS_INFO(JFIELD)%IPT        = YGFLC(IGFL)%MP
      SPJB_VARS_INFO(JFIELD)%IPTBG      = IDIM_GP7A3
    ELSE
      CALL ABOR1 ('THIS SHOULD NEVER HAPPEN 3')
    ENDIF
!=========================================================
!== temporary hack for aerosol
  ELSEIF (ICODE==210048) THEN
    NVA3D=NVA3D+1
    igrb3(NVA3D)=ICODE
    SPJB_VARS_INFO(JFIELD)%IPTJB  = NVA3D

    SPJB_VARS_INFO(JFIELD)%L_IN_GPGFL = .TRUE.
    SPJB_VARS_INFO(JFIELD)%IPT        = HUGE(SPJB_VARS_INFO(JFIELD)%IPT)

    SPJB_VARS_INFO(JFIELD)%IPTFCE = NOFCEF+1
    NOFCEF=NOFCEF+NFLEVG

    IDIM_GP7A3=IDIM_GP7A3+1
    SPJB_VARS_INFO(JFIELD)%IPTBG      = IDIM_GP7A3
!=========================================================

!-- abort if ICODE not found

  ELSE
    WRITE (NULOUT,*) 'SUJB DOESN''T KNOW WHAT TO DO WITH GRIB CODE ',ICODE
    CALL ABOR1 ('UNRECOGNIZED GRIB CODE IN M_GRIBCODES')
  ENDIF
ENDDO

IF (ALLOCATED(NGRBVAR)) DEALLOCATE(NGRBVAR)
ALLOCATE(NGRBVAR(NVA3D+NVA2D))
NGRBVAR(1:NVA3D)=igrb3(1:NVA3D)
NGRBVAR(NVA3D+1:NVA3D+NVA2D)=igrb2(1:NVA2D)

WRITE(NULOUT,*)'SUJB: NVA2D,NVA3D=',NVA2D,NVA3D
WRITE(NULOUT,*)'SUJB: NGRBVAR=',NGRBVAR(:)
IF (NVA3D+NVA2D/=N_SPJB_VARS) CALL ABOR1('SUJB: Error NVA2D+NVA3D')

DEALLOCATE(igrb2,igrb3)

! ------------------------------------------------------------------
! Number of fields in control variable
! ------------------------------------------------------------------

! Used only in cosjr2. Is it really needed?
NVA3SP=0
DO JFIELD=1,N_SPJB_VARS
  IF (SPJB_VARS_INFO(JFIELD)%L_IN_SPA3) THEN
    NVA3SP=NVA3SP+1
  ELSEIF (SPJB_VARS_INFO(JFIELD)%L_IN_SPGFL) THEN
    NVA3SP=NVA3SP+1
  ENDIF
ENDDO
WRITE(NULOUT,*)'SUJB: NVA3SP=',NVA3SP

IF (LELAM) THEN
!cf count for mean U and V in TL/AD models inside control of LAM
  NVA1D=2
ELSE
  NVA1D=0
ENDIF


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

!*       5.    Print final values.
!              -------------------

WRITE(UNIT=NULOUT,FMT='(/,'' NAMELIST NAMJG  '')')
WRITE(NULOUT,NAMJG)

IF (LJBWAVELET) THEN
  WRITE (NULOUT,'(/'' Jb formulation is: Wavelet Jb'')')
  WRITE (NULOUT,'('' -----------------------------''/)')
ELSE
  WRITE(NULOUT,*)&
   & ' Jb is using a statistical balance formulation (J. Derber)'  
ENDIF

IF (LJBWAVELET .AND. LJBWSTATS) &
 & WRITE(NULOUT,'('' Wavelet Jb statistics file will be recalculated'')')  

IF (L_JBVCOORD) &
 & WRITE(NULOUT,'('' Jb vertical coordinate will be used'')')  

IF (LCFCE) &
 & WRITE(NULOUT,'('' Background errors will be horizontally averaged'')')  

IF (LSPFCE) &
 & WRITE(NULOUT,'('' Background error normalization in spectral space'')')  

IF (.NOT. LJBENER) &
 & WRITE(NULOUT,'('' Non-Separable Structure Functions will be used'')')  

IF (LJB_OMEGA_BALANCE) &
 & WRITE(NULOUT,'('' The balance operator includes an omega equation'')')  

IF (LJB_OMEGA_BALANCE_RELAX) &
 & WRITE(NULOUT,'('' Apply scale-dependent relaxation of omega balance'')')

IF (LJB_NONLINEAR_BALANCE) &
 & WRITE(NULOUT,'('' Mass-wind balance is linearized nonlinear balance'')')  

IF (LJB_NONLINEAR_BALANCE_RELAX) &
 & WRITE(NULOUT,'('' Apply scale-dependent relaxation of non linear balance'')')

IF (LJB_NONLINEAR_CVHUM) &
 & WRITE(NULOUT,'('' Nonlinear normalized relative humidity control variable'')')  

IF (LJB_NONLINEAR_CVO3) &
 & WRITE(NULOUT,'('' Nonlinear normalized  control variable'')')  

IF (LJBBALBETA) &
 & WRITE(NULOUT,'('' Mass-wind balance is beta-plane linear balance'')')  

WRITE (NULOUT,'(/)')

WRITE(NULOUT,*)'SUJB: LJBWAVELET=',LJBWAVELET
WRITE(NULOUT,*)'SUJB: LJBWSTATS=',LJBWSTATS
WRITE(NULOUT,*)'SUJB: L_JBVCOORD=',L_JBVCOORD
WRITE(NULOUT,*)'SUJB: LCFCE=',LCFCE
WRITE(NULOUT,*)'SUJB: LSPFCE=',LSPFCE
WRITE(NULOUT,*)'SUJB: LJBENER=',LJBENER
WRITE(NULOUT,*)'SUJB: LJB_OMEGA_BALANCE=',LJB_OMEGA_BALANCE
WRITE(NULOUT,*)'SUJB: LJB_OMEGA_BALANCE_RELAX=',LJB_OMEGA_BALANCE_RELAX
WRITE(NULOUT,*)'SUJB: LJB_NONLINEAR_BALANCE=',LJB_NONLINEAR_BALANCE
WRITE(NULOUT,*)'SUJB: LJB_NONLINEAR_BALANCE_RELAX=',LJB_NONLINEAR_BALANCE_RELAX
WRITE(NULOUT,*)'SUJB: ELC=',ELC
WRITE(NULOUT,*)'SUJB: LJB_NONLINEAR_CVHUM=',LJB_NONLINEAR_CVHUM
WRITE(NULOUT,*)'SUJB: LJB_NONLINEAR_CVO3=',LJB_NONLINEAR_CVO3
WRITE(NULOUT,*)'SUJB: LJB_SUPSAT=',LJB_SUPSAT
WRITE(NULOUT,*)'SUJB: LJBZERO=',LJBZERO,'LJPZERO=',LJPZERO, &
                   & 'LJTZERO=',LJTZERO,'LJLZERO=',LJLZERO
WRITE(NULOUT,*)'SUJB: LBALSTRATO,NLEVBAL0,NLEVBAL1=',LBALSTRATO,NLEVBAL0,NLEVBAL1
WRITE(NULOUT,*)'SUJB: LCTLFG=',LCTLFG

WRITE (NULOUT,&
&'(/''MAPPING OF SPAxJB TO MODEL ARRAYS, FCEBUF AND Jb STATISTICS FILE:'')')
WRITE (NULOUT,&
&'(''VAR     GRIB     GRIBFCE  WHERE    IPT   IPTJB  IPTFCE IPTBG   COR_STRING'')')
WRITE (NULOUT,&
&'(''---     ----     -------  -----    ---   -----  ------ -----   ----------'')')

DO JFIELD=1,N_SPJB_VARS
  IF (SPJB_VARS_INFO(JFIELD)%L_IN_SPA2) THEN
    CLSTRING='IN SPA2 '
  ELSEIF (SPJB_VARS_INFO(JFIELD)%L_IN_SPA3) THEN
    CLSTRING='IN SPA3 '
  ELSEIF (SPJB_VARS_INFO(JFIELD)%L_IN_SPGFL) THEN
    CLSTRING='IN SPGFL'
  ELSEIF (SPJB_VARS_INFO(JFIELD)%L_IN_GPGFL) THEN
    CLSTRING='IN GPGFL'
  ELSE
      CALL ABOR1 ('THIS SHOULD NEVER HAPPEN 4')
  ENDIF

!Antje  WRITE (NULOUT,'(I3,3X,I3,4X,I3,3X,A8,2X,I3,4X,I3,5X,I3,3X,I3,2X,A40)')  &
  WRITE (NULOUT,'(I3,3X,I6,4X,I6,3X,A8,2X,I3,4X,I3,5X,I3,3X,I3,2X,A40)')  &
       & JFIELD, &
       & SPJB_VARS_INFO(JFIELD)%IGRIBCODE,   &
       & SPJB_VARS_INFO(JFIELD)%IGRIBCODE_FCE,   &
       & CLSTRING, &
       & SPJB_VARS_INFO(JFIELD)%IPT,   &
       & SPJB_VARS_INFO(JFIELD)%IPTJB, &
       & SPJB_VARS_INFO(JFIELD)%IPTFCE, &
       & SPJB_VARS_INFO(JFIELD)%IPTBG, &
       & SPJB_VARS_INFO(JFIELD)%COR_STRING
ENDDO
WRITE (NULOUT,'(/)')

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

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