SUBROUTINE SUREO3
!**** *SUREO3 - Sets up additional parameters for REO3 bias correction
!               and thinning of REO3 data

!     Antje Dethof      ECMWF        24/04/2003

!     PURPOSE
!     -------
!     Set up info for reo3 bias correction and reo3 thinning

!**   INTERFACE
!     ---------
!     *CALL* *SUREO3*

!     sureo3 is called by suobs. It has to be called after surad, because it
!     uses satgr_table which gets filled in surad.

!     METHOD
!     ------

!     Bias correction:
!     ----------------
!     A bcor_reo3 info file is read (if provided) which contains
!     the parameter for the bias correction.
!     This info file is an ASCII file,
!     and it consists of subsequent blocks of the following,
!     one for each satellite/sensor. 

!     A suite of parameters is set between "&reo3_bcor_in" and "/",
!     in the usual FORTRAN-90 namelist way. These parameters are:
!     isat_id            : The (BUFR) satellite ID of the data affected.
!     isensor            : The (BUFR) sensor ID of the data affected.
!     ivarno             : The variable number of the data affected.
!     ipreds:              Number of predictors used for these data.
!                          Default: 0 (= bias correction is switched off)
!                          Only other implemented option: 1 (with solar
!                          elevation (soe) as predictor)
!     clpred_names:        Names of the predictors used (e.g., 'soe')
!     clbcor_inst:         Names of the independent instrument type
!                          used (e.g., 'BREWER','DOBSON')

!     The regression coefficients for the bias correction are given 
!     after the keyword BEGIN REGRESSIONS. The date interval (2 integers 
!     yyyymmdd) for which the coefficients are valid is given first, 
!     then the intercept, then the coefficients for the predictors, 
!     in the order of their names given in clpred_names above.

!     Things outside "&reo3_bcor_in" and "/" and before "BEGIN REGRESSIONS"
!     will be ignored.

!     Thinning:
!     ---------
!     A thin_reo3 info file is read (if provided) which contains
!     the parameters for the thinning. This info file is an ASCII file,
!     and it consists of subsequent blocks of the following,
!     one for each sensor that is to be thinned.

!     A suite of parameters is set between "&reo3_thin_in" and "/",
!     in the usual FORTRAN-90 namelist way. These parameters are:
!     isensor            : The (BUFR) sensor ID of the data affected.
!     ivarno             : The (ODB) varno ID of the data affected.
!     zmind              : Size of first (small) thinning box (in degrees)
!     zrind              : Size of second (bigger) thinning box (in degrees)

!     EXTERNALS
!     ---------

!     MODIFICATIONS
!     -------------
!        M.Hamrud      01-Oct-2003 CY28 Cleaning
!        A.Dethof      06-Aug-2004 Introduce reo thinning
!        R. Dragani    20 Feb 2009 Fill a SATREO3GRP_TABLE (defined in yomtvrad.F90)  
!        A. Inness     19-Aug-2009 Add varno to SATREO3GRP_TABLE
!---------------------------------------------------------

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

USE yom_reo3_bcor, ONLY : reo3_bc_info,o3bc_info,ch4bc_info,nbc_info, &
&  nch4bc_info, jpmax_nam_len, jpmax_npreds
USE yom_reo3_thin, ONLY : reo3_thin_info,o3thin_info,n_reo3_thin_info
USE YOMTVRAD , ONLY : SATGRP_TABLE, SATREO3GRP_TABLE, NSATREO3GRP
USE YOMCOCTP , ONLY : NSTRO3
USE yomlun   , ONLY : nulout
USE yomana   , ONLY : nandat
USE YOMVAR   , ONLY : lreo3_bcor, lch4_bcor
USE YOMOBS   , ONLY : LREO3THIN_NO_SQ
USE GRG_PHOTOLYSIS_MIX , ONLY : FINT
USE YOM_YGFL, ONLY : NGRG, NGHG
USE YOMDB

IMPLICIT NONE

! Local parameters
INTEGER(KIND=JPIM), PARAMETER  :: iutmp=77
CHARACTER(LEN=9) :: clreo3_bcor='bcor_reo3',clreo3_thin='thin_reo3'
CHARACTER(LEN=8) :: clch4_bcor='bcor_ch4'

! Local variables
TYPE(reo3_bc_info), ALLOCATABLE, DIMENSION(:)   :: YL_TMP_O3BC_INFO ! Temporary 
!                                                         storage for bcor info
TYPE(reo3_thin_info), ALLOCATABLE, DIMENSION(:) :: YL_TMP_o3thin_INFO ! Temporary 
!                                                         storage for thinning info
TYPE(reo3_bc_info), ALLOCATABLE, DIMENSION(:)   :: YL_TMP_CH4BC_INFO ! Temporary 
!                                                         storage for bcor info
INTEGER(KIND=JPIM)           :: istat                   ! I/O status
INTEGER(KIND=JPIM)           :: idate_start, idate_end  ! YYYYMMDD read in
INTEGER(KIND=JPIM)           :: jcor, jthin             ! counter
CHARACTER(LEN=256)           :: cldum
LOGICAL                      :: llfileok
LOGICAL, ALLOCATABLE, DIMENSION(:)   :: llgood_reo3_info
LOGICAL, ALLOCATABLE, DIMENSION(:)   :: llgood_o3thin_info
LOGICAL, ALLOCATABLE, DIMENSION(:)   :: llgood_ch4_info

! Namelist variables
INTEGER(KIND=JPIM)           :: IRET,INFO(1), J, ILEN
INTEGER(KIND=JPIM)           :: isensor       ! SENSOR for which bcor is valid
INTEGER(KIND=JPIM)           :: isat_id       ! SATID for which bcor is valid
INTEGER(KIND=JPIM)           :: ipreds        ! Number of predictors
CHARACTER(LEN=jpmax_nam_len),       &
 & DIMENSION(jpmax_npreds)   :: clpred_names  ! Names of predictors  
CHARACTER(LEN=jpmax_nam_len) :: clbcor_inst   ! Name of indep. instrument used 
REAL(KIND=JPRB), &
 & DIMENSION(jpmax_nam_len)  :: zpred_min     ! Min pred value to use  
REAL(KIND=JPRB), &
 & DIMENSION(jpmax_nam_len)  :: zpred_max     ! Max pred value to use  
INTEGER(KIND=JPIM)           :: ivarno        ! varno ID for which thinning is valid
REAL(KIND=JPRB)              :: zmind         ! size of first thinning box in degrees    
REAL(KIND=JPRB)              :: zfind         ! size of 2nd thinning box in degrees    
REAL(KIND=JPRB)              :: ZINFO(1)
REAL(KIND=JPRB)              :: ZHOOK_HANDLE
!                                                for bcor

!GRG photolysis info file
CHARACTER(LEN=10) :: clgrg_fint='grg_fintwb'

NAMELIST  /reo3_bcor_in/  isat_id,isensor,ipreds,clpred_names, &
 & zpred_min,zpred_max,clbcor_inst  

NAMELIST  /reo3_thin_in/  isensor,ivarno,zmind,zfind

NAMELIST  /ch4_bcor_in/  isat_id,isensor,ivarno,ipreds,clpred_names, &
 & zpred_min,zpred_max,clbcor_inst  

INTERFACE
#include "getdb.h"
#include "putdb.h"
END INTERFACE

#include "openmp_obs.h"

!========================================================

!*      1.  READ file with reo3 bias correction information
!       ---------------------------------------------------

!       1.1 Open file and set up
   
IF (LHOOK) CALL DR_HOOK('SUREO3',0,ZHOOK_HANDLE)

! ===========================
!  Fill SATREO3GRP_TABLE: 
IRET = 0
NSATREO3GRP=0

!     1.1.1 ODB is asked to deliver a unique list of
!           satid, codetype, sensor, varno, and retrtype for obstype=satem.

CALL GSTATS(1796,0)
CALL GETDB('GETSATID_REO3', 0, IRET, INFO, 0, ZINFO,0,&
 & -1, -1, -1, -1, -1, -1)  
CALL GSTATS(1796,1)


!     1.1.2 The ROBSU-array may contain duplicates; one per PE
!           The duplicates are removed in this loop.
ILEN=0
IF(IRET > 0) ILEN=1
DO J=2,IRET
    IF(ROBSU(J,MDB_SATID_AT_SAT) /= ROBSU(ILEN,MDB_SATID_AT_SAT) .OR. &
       & ROBSU(J,MDBSSIA)        /= ROBSU(ILEN,MDBSSIA) .OR. &
       & ROBSU(J,MDB_RETRTYPE_AT_HDR) /= ROBSU(ILEN,MDB_RETRTYPE_AT_HDR)) THEN
      ILEN=ILEN+1
      ROBSU(ILEN,MDB_SATID_AT_SAT)=ROBSU(J,MDB_SATID_AT_SAT)
      ROBSU(ILEN,MDB_RETRTYPE_AT_HDR)    =ROBSU(J,MDB_RETRTYPE_AT_HDR)
      ROBSU(ILEN,MDBSSIA)         =ROBSU(J,MDBSSIA)
      ROBSU(ILEN,MDBVNM)         =ROBSU(J,MDBVNM)
      ROBSU(ILEN,MDBRO3PT)        =ROBSU(J,MDBRO3PT) 
    ENDIF
ENDDO
NSATREO3GRP=ILEN

ALLOCATE(SATREO3GRP_TABLE(NSATREO3GRP))

do j=1,NSATREO3GRP
   SATREO3GRP_TABLE(J)%retrtype = ROBSU(j,MDB_RETRTYPE_AT_HDR)
   SATREO3GRP_TABLE(J)%prodtype = ROBSU(j,MDBRO3PT)
   SATREO3GRP_TABLE(J)%bufrid   = ROBSU(j,MDB_SATID_AT_SAT) 
   SATREO3GRP_TABLE(J)%sensor   = ROBSU(j,MDBSSIA)
   SATREO3GRP_TABLE(J)%varno    = ROBSU(j,MDBVNM)
   SATREO3GRP_TABLE(J)%satgroup = j
enddo

CALL GSTATS(1796,0)
CALL PUTDB('GETSATID_REO3', 0, IRET, INFO, 0, ZINFO, 0)
CALL GSTATS(1796,1)

! ===========================

IF(.NOT. lreo3_bcor) THEN
  WRITE(nulout,*) 'INFO SUREO3: No bias correction for REO3.'
  nbc_info = 0
  GO TO 2
ENDIF

INQUIRE(FILE=TRIM(clreo3_bcor),EXIST=llfileok )

IF(.NOT. llfileok)THEN
  WRITE(nulout,*) 'ERROR SUREO3: Cannot read file '//TRIM(clreo3_bcor) 
  WRITE(nulout,*) 'No bias correction applied for REO3.'
  nbc_info = 0
  GO TO 2
ELSE
  WRITE(nulout,*) 'INFO SUREO3: Opening '//TRIM(clreo3_bcor)
  OPEN(iutmp,FORM='FORMATTED',ACTION='READ',STATUS='OLD',   &
   & FILE=TRIM(clreo3_bcor))  
ENDIF

nbc_info = 100     ! Maximum number of satellite/sensor combinations 
      ! with bias correction
ALLOCATE(YL_TMP_O3BC_INFO(nbc_info))
ALLOCATE(llgood_reo3_info(nbc_info))
llgood_reo3_info = .FALSE.

WRITE(nulout,*) 'INFO SUREO3: Reading REO3 bias correction info for ',nandat

!       1.2   Read the correction file

DO jcor = 1,nbc_info 
  ipreds = 0
  isat_id = -1

!       1.2.1  Read the namelist part 

  istat=0
  READ(UNIT=iutmp, NML=reo3_bcor_in, IOSTAT=istat)
  IF (istat /= 0) THEN
    EXIT
  ENDIF

!       1.2.2  Check that ozone data from this satellite actually exist
  
  llgood_reo3_info(jcor) = ANY(satgrp_table%codetype == NSTRO3  .AND.  &
   & satgrp_table%bufrid   == isat_id .AND.  &
   & satgrp_table%sensor   == isensor)   

!       1.2.3 Store values

  YL_TMP_O3BC_INFO(jcor)%sat_id      = isat_id
  YL_TMP_O3BC_INFO(jcor)%sensor      = isensor
  IF( ipreds > jpmax_npreds ) THEN
    WRITE(nulout,*) 'ERROR SUREO3: Too many predictors used: ipreds, max:', &
     & ipreds, jpmax_npreds  
    WRITE(nulout,*) 'No REO3 bias correction done for sensor, satid',  &
     & isensor,isat_id  
    llgood_reo3_info(jcor) = .FALSE.
    CYCLE
  ENDIF
  YL_TMP_O3BC_INFO(jcor)%npreds                = ipreds 
  YL_TMP_O3BC_INFO(jcor)%pred_name(1:ipreds)   = clpred_names(1:ipreds)
  YL_TMP_O3BC_INFO(jcor)%pred_min(1:ipreds)    = zpred_min(1:ipreds)
  YL_TMP_O3BC_INFO(jcor)%pred_max(1:ipreds)    = zpred_max(1:ipreds)
  YL_TMP_O3BC_INFO(jcor)%bcor_inst             = clbcor_inst

  IF (ipreds > 0) THEN
!       1.2.4  Search for next "REGRESSIONS" keyword

    DO 
      READ(UNIT = iutmp,FMT='(A20)',IOSTAT = istat) cldum
      IF(istat < 0) THEN
        WRITE(nulout,*) 'ERROR SUREO3: Missing BEGIN REGRESSIONS.'
        WRITE(nulout,*) 'No REO3 bias correction done for sensor, satid',  &
         & isensor,isat_id        
        llgood_reo3_info(jcor) = .FALSE.
        EXIT
      ENDIF
      IF(TRIM(cldum) == 'BEGIN REGRESSIONS') EXIT
      IF(TRIM(cldum) == 'END REGRESSIONS') THEN
        istat = 1
        EXIT
      ENDIF
    ENDDO

    IF(istat < 0) THEN
      EXIT
    ENDIF
    IF(istat == 1) THEN
      WRITE(nulout,*) 'INFO SUREO3: END REGRESSIONS before BEGIN REGRESSIONS.'
      WRITE(nulout,*) 'No REO3 bias correction done for isensor, satid',  &
       & isensor,isat_id  
      llgood_reo3_info(jcor) = .FALSE.
      CYCLE
    ENDIF

!       1.2.5  Read the coefficients

    DO 
      READ(UNIT = iutmp,FMT='(A256)',IOSTAT = istat) cldum
      IF(TRIM(cldum) == 'END REGRESSIONS' .OR. istat < 0) THEN
        WRITE(nulout,*) 'INFO SUREO3: No coefficients for ',nandat
        WRITE(nulout,*) 'No REO3 bias correction done for sensor, satid',  &
         & isensor,isat_id  
        llgood_reo3_info(jcor) = .FALSE.
        EXIT
      ENDIF
      READ(cldum,FMT=*) idate_start, idate_end, &
       & YL_TMP_O3BC_INFO(jcor)%coef(0:ipreds)  
      IF( idate_start < nandat .AND. idate_end >= nandat)  EXIT
    ENDDO
  ENDIF
ENDDO
CLOSE(iutmp)

!       1.3   Throw out unsuccessful or superflous date
!             Store reo3 bias correction info in final place

nbc_info = COUNT(llgood_reo3_info)

IF( nbc_info == 0 )THEN
  WRITE(nulout,*) 'INFO SUREO3: No bias correction provided for currently used satellites and sensors'
  GO TO 2 
ENDIF

ALLOCATE(o3bc_info(nbc_info))
o3bc_info = PACK(YL_TMP_O3BC_INFO, MASK = llgood_reo3_info)
DEALLOCATE(YL_TMP_O3BC_INFO,llgood_reo3_info)

!       1.5   Give overview of information read

WRITE(nulout,*) 'REO3 bias correction information'
WRITE(nulout,*) '================================'

DO jcor=1,nbc_info
  WRITE(nulout,*) 'Satellite ID: ', o3bc_info(jcor)%sat_id
  WRITE(nulout,*) 'Sensor      : ', o3bc_info(jcor)%sensor
  WRITE(nulout,*) 'Number of predictors: ', o3bc_info(jcor)%npreds
  WRITE(nulout,*) 'Name of predictors: ', o3bc_info(jcor)%pred_name
  WRITE(nulout,*) 'Min val. of pred.   ', o3bc_info(jcor)%pred_min
  WRITE(nulout,*) 'Max val. of pred.   ', o3bc_info(jcor)%pred_max
  WRITE(nulout,*) 'Name of indep. inst: ', o3bc_info(jcor)%bcor_inst

  IF(o3bc_info(jcor)%npreds > 0)THEN
    WRITE(nulout,FMT='(10(A12,1x))') ' Intercept',     &
     & ADJUSTR(o3bc_info(jcor)%pred_name(1:o3bc_info(jcor)%npreds))  
    WRITE(nulout,FMT='(10(F12.6,1x))') &
     & o3bc_info(jcor)%coef(0:o3bc_info(jcor)%npreds)  
  ENDIF
  WRITE(nulout,*) '-----------------------------------------------------'
ENDDO

!*      2.  READ file with reo3 thinning information
!       ---------------------------------------------------

2 CONTINUE

!       2.1 Open file and set up

IF(.NOT.LREO3THIN_NO_SQ ) THEN
  WRITE(nulout,*) 'INFO SUREO3: No thinning for REO3.'
  n_reo3_thin_info = 0
  IF (LHOOK) CALL DR_HOOK('SUREO3',1,ZHOOK_HANDLE)
  RETURN
ENDIF

INQUIRE(FILE=TRIM(clreo3_thin),EXIST=llfileok )

IF(.NOT. llfileok)THEN
  WRITE(nulout,*) 'ERROR SUREO3: Cannot read file '//TRIM(clreo3_thin) 
  WRITE(nulout,*) 'No thinning applied for REO3.'
  n_reo3_thin_info = 0
  IF (LHOOK) CALL DR_HOOK('SUREO3',1,ZHOOK_HANDLE)
  RETURN
ELSE
  WRITE(nulout,*) 'INFO SUREO3: Opening '//TRIM(clreo3_thin)
  OPEN(iutmp,FORM='FORMATTED',ACTION='READ',STATUS='OLD',   &
   & FILE=TRIM(clreo3_thin))  
ENDIF

n_reo3_thin_info = 100   ! Maximum number of satellite/sensor combinations 
                        ! for thinning 
ALLOCATE(yl_tmp_o3thin_info(n_reo3_thin_info))
ALLOCATE(llgood_o3thin_info(n_reo3_thin_info))
llgood_o3thin_info = .FALSE.

WRITE(nulout,*) 'INFO SUREO3: Reading REO3 thinning info'

!       2.2   Read the thinning info file

DO jthin = 1,n_reo3_thin_info 
  isensor=-1

!       2.2.1  Read the namelist part 

  istat=0
  READ(UNIT=iutmp, NML=reo3_thin_in, IOSTAT=istat)
  IF (istat /= 0) THEN
    EXIT
  ENDIF

!       2.2.2  Check that ozone data from this sensor actually exist
  
  llgood_o3thin_info(jthin) = ANY(satgrp_table%codetype == NSTRO3  .AND.  &
   & satgrp_table%sensor   == isensor)   

!       2.2.3 Store values

  YL_TMP_o3thin_INFO(jthin)%sensor  = isensor
  YL_TMP_o3thin_INFO(jthin)%varno   = ivarno
  YL_TMP_o3thin_INFO(jthin)%rmind   = zmind
  YL_TMP_o3thin_INFO(jthin)%rfind   = zfind

ENDDO
CLOSE(iutmp)

!       2.3   Store reo3 thinning info in final place

IF(COUNT(llgood_o3thin_info) > n_reo3_thin_info )THEN
    WRITE(nulout,*) 'ERROR SUREO3: n_reo3_thin_info too small, = ',n_reo3_thin_info
    WRITE(nulout,*) 'ERROR SUREO3: Increase value of n_reo3_thin_info in sureo3.'
    CALL ABOR1('SUREO3: n_reo3_thin_info too small.')
ENDIF

n_reo3_thin_info = COUNT(llgood_o3thin_info)

IF( n_reo3_thin_info == 0 )THEN
  WRITE(nulout,*) 'INFO SUREO3: No thinning info provided for currently used satellites and sensors'
  IF (LHOOK) CALL DR_HOOK('SUREO3',1,ZHOOK_HANDLE)
  RETURN
ENDIF

ALLOCATE(o3thin_info(n_reo3_thin_info))
o3thin_info = PACK(YL_TMP_o3thin_INFO, MASK = llgood_o3thin_info)
DEALLOCATE(YL_TMP_o3thin_INFO,llgood_o3thin_info)

!       2.4   Give overview of information read

WRITE(nulout,*) 'REO3 thinning information'
WRITE(nulout,*) '================================'

DO jthin=1,n_reo3_thin_info
  WRITE(nulout,*) 'Sensor      : ', o3thin_info(jthin)%sensor
  WRITE(nulout,*) 'Varno       : ', o3thin_info(jthin)%varno
  WRITE(nulout,*) 'First thinning box size: ', o3thin_info(jthin)%rmind
  WRITE(nulout,*) 'Second thinning box size: ', o3thin_info(jthin)%rfind

  WRITE(nulout,*) '-----------------------------------------------------'
ENDDO

!       3.0   Read file with infor for GRG photolysis calculations
!       -----------------------------------------------------------

IF (NGRG > 0) THEN
  llfileok=.false.
  INQUIRE(FILE=TRIM(clgrg_fint),EXIST=llfileok )

  IF(.NOT. llfileok)THEN
    WRITE(nulout,*) 'ERROR SUREO3: Cannot read GRG file '//TRIM(clgrg_fint)
    CALL ABOR1('SUREO3: FILE grg_fintwb does not exist.')
  ELSE
    WRITE(nulout,*) 'INFO SUREO3: Opening GRG file '//TRIM(clgrg_fint) 
    OPEN(iutmp,FORM='FORMATTED',ACTION='READ',STATUS='OLD',   &
     & FILE=TRIM(clgrg_fint))
    READ(iutmp,*) fint
    CLOSE(iutmp)
    WRITE(nulout,*) 'INFO SUREO3: Finished reading GRG file '//TRIM(clgrg_fint) 
  ENDIF
ENDIF


!*      4.  READ file with reo3 bias correction information for methane
!       ---------------------------------------------------------------

!       4.1 Open file and set up
   
IF (NGHG > 0) THEN

IF(.NOT. lch4_bcor) THEN
  WRITE(nulout,*) 'INFO SUREO3: No bias correction for CH4.'
  nch4bc_info = 0
  GO TO 3
ENDIF

INQUIRE(FILE=TRIM(clch4_bcor),EXIST=llfileok )

IF(.NOT. llfileok)THEN
  WRITE(nulout,*) 'ERROR SUREO3: Cannot read file '//TRIM(clch4_bcor) 
  WRITE(nulout,*) 'No bias correction applied for CH4.'
  nch4bc_info = 0
  GO TO 3
ELSE
  WRITE(nulout,*) 'INFO SUREO3: Opening '//TRIM(clch4_bcor)
  OPEN(iutmp,FORM='FORMATTED',ACTION='READ',STATUS='OLD',   &
   & FILE=TRIM(clch4_bcor))  
ENDIF

nch4bc_info = 10     ! Maximum number of satellite/sensor combinations 
      ! with bias correction
ALLOCATE(YL_TMP_CH4BC_INFO(nch4bc_info))
ALLOCATE(llgood_ch4_info(nch4bc_info))
llgood_ch4_info = .FALSE.

WRITE(nulout,*) 'INFO SUREO3: Reading CH4 bias correction info for ',nandat

!       4.2   Read the correction file

DO jcor = 1,nch4bc_info 
  ipreds = 0
  isat_id = -1

!       4.2.1  Read the namelist part 

  istat=0
  READ(UNIT=iutmp, NML=ch4_bcor_in, IOSTAT=istat)
  IF (istat /= 0) THEN
    EXIT
  ENDIF

!       4.2.2  Check that methane data from this satellite actually exist
  
  llgood_ch4_info(jcor) = ANY(satgrp_table%codetype == NSTRO3  .AND.  &
   & satgrp_table%bufrid   == isat_id .AND.  &
   & satgrp_table%sensor   == isensor)   

!       4.2.3 Store values

  YL_TMP_CH4BC_INFO(jcor)%sat_id      = isat_id
  YL_TMP_CH4BC_INFO(jcor)%sensor      = isensor
  YL_TMP_CH4BC_INFO(jcor)%varno       = ivarno
  IF( ipreds > jpmax_npreds ) THEN
    WRITE(nulout,*) 'ERROR SUREO3: Too many predictors used: ipreds, max:', &
     & ipreds, jpmax_npreds  
    WRITE(nulout,*) 'No CH4 bias correction done for sensor, satid',  &
     & isensor,isat_id  
    llgood_ch4_info(jcor) = .FALSE.
    CYCLE
  ENDIF
  YL_TMP_CH4BC_INFO(jcor)%npreds                = ipreds 
  YL_TMP_CH4BC_INFO(jcor)%pred_name(1:ipreds)   = clpred_names(1:ipreds)
  YL_TMP_CH4BC_INFO(jcor)%pred_min(1:ipreds)    = zpred_min(1:ipreds)
  YL_TMP_CH4BC_INFO(jcor)%pred_max(1:ipreds)    = zpred_max(1:ipreds)
  YL_TMP_CH4BC_INFO(jcor)%bcor_inst             = clbcor_inst

  IF (ipreds > 0) THEN
!       4.2.4  Search for next "REGRESSIONS" keyword

    DO 
      READ(UNIT = iutmp,FMT='(A20)',IOSTAT = istat) cldum
      IF(istat < 0) THEN
        WRITE(nulout,*) 'ERROR SUREO3: Missing BEGIN REGRESSIONS.'
        WRITE(nulout,*) 'No CH4 bias correction done for sensor, satid',  &
         & isensor,isat_id        
        llgood_ch4_info(jcor) = .FALSE.
        EXIT
      ENDIF
      IF(TRIM(cldum) == 'BEGIN REGRESSIONS') EXIT
      IF(TRIM(cldum) == 'END REGRESSIONS') THEN
        istat = 1
        EXIT
      ENDIF
    ENDDO

    IF(istat < 0) THEN
      EXIT
    ENDIF
    IF(istat == 1) THEN
      WRITE(nulout,*) 'INFO SUREO3: END REGRESSIONS before BEGIN REGRESSIONS.'
      WRITE(nulout,*) 'No CH4 bias correction done for isensor, satid',  &
       & isensor,isat_id  
      llgood_ch4_info(jcor) = .FALSE.
      CYCLE
    ENDIF

!       4.2.5  Read the coefficients

    DO 
      READ(UNIT = iutmp,FMT='(A256)',IOSTAT = istat) cldum
      IF(TRIM(cldum) == 'END REGRESSIONS' .OR. istat < 0) THEN
        WRITE(nulout,*) 'INFO SUREO3: No coefficients for ',nandat
        WRITE(nulout,*) 'No CH4 bias correction done for sensor, satid',  &
         & isensor,isat_id  
        llgood_ch4_info(jcor) = .FALSE.
        EXIT
      ENDIF
      READ(cldum,FMT=*) idate_start, idate_end, &
       & YL_TMP_CH4BC_INFO(jcor)%coef(0:ipreds)  
      IF( idate_start < nandat .AND. idate_end >= nandat)  EXIT
    ENDDO
  ENDIF
ENDDO
CLOSE(iutmp)

!       4.3   Throw out unsuccessful or superflous date
!             Store ch4 bias correction info in final place

nch4bc_info = COUNT(llgood_ch4_info)

IF( nch4bc_info == 0 )THEN
  WRITE(nulout,*) 'INFO SUREO3: No bias correction provided for currently used satellites and sensors'
  GO TO 3 
ENDIF

ALLOCATE(ch4bc_info(nch4bc_info))
ch4bc_info = PACK(YL_TMP_CH4BC_INFO, MASK = llgood_ch4_info)
DEALLOCATE(YL_TMP_CH4BC_INFO,llgood_ch4_info)

!       4.5   Give overview of information read

WRITE(nulout,*) 'CH4 bias correction information'
WRITE(nulout,*) '================================'

DO jcor=1,nch4bc_info
  WRITE(nulout,*) 'Satellite ID: ', ch4bc_info(jcor)%sat_id
  WRITE(nulout,*) 'Sensor      : ', ch4bc_info(jcor)%sensor
  WRITE(nulout,*) 'Varno       : ', ch4bc_info(jcor)%varno
  WRITE(nulout,*) 'Number of predictors: ', ch4bc_info(jcor)%npreds
  WRITE(nulout,*) 'Name of predictors: ', ch4bc_info(jcor)%pred_name
  WRITE(nulout,*) 'Min val. of pred.   ', ch4bc_info(jcor)%pred_min
  WRITE(nulout,*) 'Max val. of pred.   ', ch4bc_info(jcor)%pred_max
  WRITE(nulout,*) 'Name of indep. inst: ', ch4bc_info(jcor)%bcor_inst

  IF(ch4bc_info(jcor)%npreds > 0)THEN
    WRITE(nulout,FMT='(10(A12,1x))') ' Intercept',     &
     & ADJUSTR(ch4bc_info(jcor)%pred_name(1:ch4bc_info(jcor)%npreds))  
    WRITE(nulout,FMT='(10(F12.6,1x))') &
     & ch4bc_info(jcor)%coef(0:ch4bc_info(jcor)%npreds)  
  ENDIF
  WRITE(nulout,*) '-----------------------------------------------------'
ENDDO

3 CONTINUE

ENDIF

IF (LHOOK) CALL DR_HOOK('SUREO3',1,ZHOOK_HANDLE)

END SUBROUTINE SUREO3
