From 93f8e4e71ae18473b2220f23d5e463e95f3acfe9 Mon Sep 17 00:00:00 2001
From: Philippe WAUTELET <philippe.wautelet@aero.obs-mip.fr>
Date: Thu, 19 Sep 2019 13:34:17 +0200
Subject: [PATCH] Philippe 19/09/2019: CDF2CDF: add possibility to provide a
 fallback file if some information are not found in the input file

---
 LIBTOOLS/tools/lfi2cdf/src/lfi2cdf.f90      |  17 ++-
 LIBTOOLS/tools/lfi2cdf/src/mode_options.f90 |  32 ++++--
 LIBTOOLS/tools/lfi2cdf/src/mode_util.f90    | 121 +++++++++++++++++---
 3 files changed, 137 insertions(+), 33 deletions(-)

diff --git a/LIBTOOLS/tools/lfi2cdf/src/lfi2cdf.f90 b/LIBTOOLS/tools/lfi2cdf/src/lfi2cdf.f90
index 3e0a8b2d7..b76d3ce23 100644
--- a/LIBTOOLS/tools/lfi2cdf/src/lfi2cdf.f90
+++ b/LIBTOOLS/tools/lfi2cdf/src/lfi2cdf.f90
@@ -1,8 +1,11 @@
-!MNH_LIC Copyright 1994-2018 CNRS, Meteo-France and Universite Paul Sabatier
+!MNH_LIC Copyright 1994-2019 CNRS, Meteo-France and Universite Paul Sabatier
 !MNH_LIC This is part of the Meso-NH software governed by the CeCILL-C licence
-!MNH_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt  
+!MNH_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt
 !MNH_LIC for details. version 1.
 !-----------------------------------------------------------------
+! Modifications:
+!  P. Wautelet 19/09/2019: add possibility to provide a fallback file if some information are not found in the input file
+!-----------------------------------------------------------------
 program LFI2CDF
   USE MODD_CONF,          ONLY: CPROGRAM
   USE MODD_CONFZ,         ONLY: NB_PROCIO_R
@@ -31,7 +34,7 @@ program LFI2CDF
   INTEGER :: IINFO_ll         ! return code of // routines
   INTEGER :: nfiles_out   = 0 ! number of output files
   CHARACTER(LEN=:),allocatable :: hvarlist
-  TYPE(TFILE_ELT),DIMENSION(1)        :: infiles
+  TYPE(TFILE_ELT),DIMENSION(2)        :: infiles
   TYPE(TFILE_ELT),DIMENSION(MAXFILES) :: outfiles
 
   TYPE(workfield), DIMENSION(:), POINTER :: tzreclist
@@ -150,7 +153,11 @@ program LFI2CDF
      CALL fill_files(infiles,outfiles,tzreclist,nbvar,options)
   END IF
 
-  CALL CLOSE_FILES(infiles, 1)
+  if ( options( OPTFALLBACK )%set ) then
+    CALL CLOSE_FILES(infiles, 2)
+  else
+    CALL CLOSE_FILES(infiles, 1)
+  end if
   CALL CLOSE_FILES(outfiles,nfiles_out)
-  
+
 end program LFI2CDF
diff --git a/LIBTOOLS/tools/lfi2cdf/src/mode_options.f90 b/LIBTOOLS/tools/lfi2cdf/src/mode_options.f90
index 1740187f0..3eea538aa 100644
--- a/LIBTOOLS/tools/lfi2cdf/src/mode_options.f90
+++ b/LIBTOOLS/tools/lfi2cdf/src/mode_options.f90
@@ -1,20 +1,23 @@
-!MNH_LIC Copyright 2015-2018 CNRS, Meteo-France and Universite Paul Sabatier
+!MNH_LIC Copyright 2015-2019 CNRS, Meteo-France and Universite Paul Sabatier
 !MNH_LIC This is part of the Meso-NH software governed by the CeCILL-C licence
-!MNH_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt  
+!MNH_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt
 !MNH_LIC for details. version 1.
 !-----------------------------------------------------------------
+! Modifications:
+!  P. Wautelet 19/09/2019: add possibility to provide a fallback file if some information are not found in the input file
+!-----------------------------------------------------------------
 module mode_options
   USE MODE_FIELD, ONLY: TYPEUNDEF, TYPEINT, TYPELOG, TYPEREAL, TYPECHAR, TYPEDATE
 
   implicit none
 
-  integer,parameter :: nbavailoptions = 10
+  integer,parameter :: NBAVAILOPTIONS = 11
   integer,parameter :: MODEUNDEF = -11, MODECDF2CDF = 11, MODELFI2CDF = 12, MODECDF2LFI = 13
 
-  integer,parameter :: OPTCOMPRESS = 1, OPTHELP   = 2, OPTLIST   = 3
-  integer,parameter :: OPTMERGE    = 4, OPTOUTPUT = 5, OPTREDUCE = 6
-  integer,parameter :: OPTMODE     = 7, OPTSPLIT  = 8, OPTVAR    = 9
-  integer,parameter :: OPTVERBOSE  = 10
+  integer,parameter :: OPTCOMPRESS = 1,  OPTHELP     = 2,  OPTLIST   = 3
+  integer,parameter :: OPTMERGE    = 4,  OPTOUTPUT   = 5,  OPTREDUCE = 6
+  integer,parameter :: OPTMODE     = 7,  OPTSPLIT    = 8,  OPTVAR    = 9
+  integer,parameter :: OPTVERBOSE  = 10, OPTFALLBACK = 11
 
   type option
     logical :: set = .false.
@@ -153,6 +156,12 @@ subroutine init_options(options)
   options(OPTVERBOSE)%long_name    = "verbose"
   options(OPTVERBOSE)%short_name   = 'V'
   options(OPTVERBOSE)%has_argument = .false.
+
+  options(OPTFALLBACK)%long_name    = "fallback-file"
+  options(OPTFALLBACK)%short_name   = 'f'
+  options(OPTFALLBACK)%has_argument = .true.
+  options(OPTFALLBACK)%type         = TYPECHAR
+
 end subroutine init_options
 
 subroutine get_option(options,finished)
@@ -323,18 +332,21 @@ subroutine help()
 !TODO: -l option for cdf2cdf and cdf2lfi
   print *,"Usage : lfi2cdf [-h --help] [-l] [-v --var var1[,...]] [-r --reduce-precision]"
   print *,"                [-m --merge number_of_z_levels] [-s --split] [-o --output output-file.nc]"
-  print *,"                [-R --runmode mode] [-V --verbose]"
+  print *,"                [-R --runmode mode] [-V --verbose] [-f --fallback-file fallback-file]"
   print *,"                [-c --compress compression_level] input-file.lfi"
   print *,"        cdf2cdf [-h --help] [-v --var var1[,...]] [-r --reduce-precision]"
   print *,"                [-m --merge number_of_split_files] [-s --split] [-o --output output-file.nc]"
-  print *,"                [-R --runmode mode] [-V --verbose]"
+  print *,"                [-R --runmode mode] [-V --verbose] [-f --fallback-file fallback-file]"
   print *,"                [-c --compress compression_level] input-file.nc"
-  print *,"        cdf2lfi [-o --output output-file.lfi] [-R --runmode mode]  [-V --verbose] input-file.nc"
+  print *,"        cdf2lfi [-o --output output-file.lfi] [-R --runmode mode]  [-V --verbose]"
+  print *,"                [-f --fallback-file fallback-file] input-file.nc"
   print *,""
   print *,"Options:"
   print *,"  --compress, -c compression_level"
   print *,"     Compress data. The compression level should be in the 1 to 9 interval."
   print *,"     Only supported with the netCDF format (cdf2cdf and lfi2cdf only)"
+  print *,"  -f --fallback-file fallback-file"
+  print *,"     File to use to read some grid information if not found in input-file"
   print *,"  --help, -h"
   print *,"     Print this text"
   print *,"  --list, -l"
diff --git a/LIBTOOLS/tools/lfi2cdf/src/mode_util.f90 b/LIBTOOLS/tools/lfi2cdf/src/mode_util.f90
index 18475b01b..9b3ade544 100644
--- a/LIBTOOLS/tools/lfi2cdf/src/mode_util.f90
+++ b/LIBTOOLS/tools/lfi2cdf/src/mode_util.f90
@@ -6,6 +6,7 @@
 ! Modifications:
 !  P. Wautelet 01/08/2019: allow merge of entire Z-split files
 !  P. Wautelet 18/09/2019: correct support of 64bit integers (MNH_INT=8)
+!  P. Wautelet 19/09/2019: add possibility to provide a fallback file if some information are not found in the input file
 !-----------------------------------------------------------------
 MODULE mode_util
   USE MODD_IO_ll,  ONLY: TFILE_ELT, TFILEDATA
@@ -960,6 +961,7 @@ END DO
   SUBROUTINE OPEN_FILES(infiles,outfiles,KNFILES_OUT,hinfile,houtfile,nbvar_infile,options,runmode)
     USE MODD_CONF,          ONLY: LCARTESIAN
     USE MODD_CONF_n,        ONLY: CSTORAGE_TYPE
+    USE MODD_CONFZ,         ONLY: NB_PROCIO_R
     USE MODD_DIM_n,         ONLY: NIMAX_ll, NJMAX_ll, NKMAX
     USE MODD_GRID,          ONLY: XBETA, XRPK, XLAT0, XLON0, XLATORI, XLONORI
     USE MODD_GRID_n,        ONLY: LSLEVE, XXHAT, XYHAT, XZHAT
@@ -981,6 +983,7 @@ END DO
     INTEGER,                     INTENT(IN)  :: runmode
 
     INTEGER                     :: idx, IRESP2
+    integer                     :: inb_procio_r_save
     INTEGER(KIND=IDCDF_KIND)    :: omode
     INTEGER(KIND=IDCDF_KIND)    :: status
     INTEGER(KIND=LFI_INT)       :: ilu,iresp
@@ -1000,6 +1003,15 @@ END DO
        CALL IO_FILE_OPEN_ll(INFILES(1)%TFILE)
 
        nbvar_infile = INFILES(1)%TFILE%NNCNAR
+
+       !Open fallback file if provided
+       if ( options( OPTFALLBACK )%set ) then
+         inb_procio_r_save = NB_PROCIO_R
+         NB_PROCIO_R = 1
+         CALL IO_FILE_ADD2LIST(INFILES(2)%TFILE,options( OPTFALLBACK )%cvalue,'UNKNOWN','READ',HFORMAT='NETCDF4')
+         CALL IO_FILE_OPEN_ll(INFILES(2)%TFILE)
+         NB_PROCIO_R = inb_procio_r_save
+       end if
    ELSE
        !
        ! LFI
@@ -1017,49 +1029,122 @@ END DO
           CALL IO_FILE_CLOSE_ll(INFILES(1)%TFILE)
           return
        END IF
+
+       !Open fallback file if provided
+       if ( options( OPTFALLBACK )%set ) then
+         inb_procio_r_save = NB_PROCIO_R
+         NB_PROCIO_R = 1
+         CALL IO_FILE_ADD2LIST(INFILES(2)%TFILE,options( OPTFALLBACK )%cvalue,'UNKNOWN','READ', &
+                               HFORMAT='LFI',KLFIVERB=0)
+         CALL IO_FILE_OPEN_ll(INFILES(2)%TFILE)
+         NB_PROCIO_R = inb_procio_r_save
+       end if
    END IF
    !
    !Read problem dimensions and some grid variables (needed to determine domain size and also by IO_FILE_OPEN_ll to create netCDF files)
-   CALL IO_READ_FIELD(INFILES(1)%TFILE,'JPHEXT',JPHEXT)
+   JPHEXT = 1
+   CALL IO_READ_FIELD(INFILES(1)%TFILE,'JPHEXT',JPHEXT,IRESP2)
+   !If not found in main file, try the fallback one
+   if ( options( OPTFALLBACK )%set .and. iresp2 /= 0 ) CALL IO_READ_FIELD(INFILES(2)%TFILE,'JPHEXT',JPHEXT,IRESP2)
+   if ( iresp2 /= 0 ) call Print_msg( NVERB_ERROR, 'IO', 'OPEN_FILES', 'JPHEXT not found')
+
    JPHEXT_ll = JPHEXT
    JPVEXT_ll = JPVEXT
    !
    ALLOCATE(NIMAX_ll,NJMAX_ll,NKMAX)
-   CALL IO_READ_FIELD(INFILES(1)%TFILE,'IMAX',NIMAX_ll)
-   CALL IO_READ_FIELD(INFILES(1)%TFILE,'JMAX',NJMAX_ll)
+   CALL IO_READ_FIELD(INFILES(1)%TFILE,'IMAX',NIMAX_ll,IRESP2)
+   !If not found in main file, try the fallback one
+   if ( options( OPTFALLBACK )%set .and. iresp2 /= 0 ) CALL IO_READ_FIELD(INFILES(2)%TFILE,'IMAX',NIMAX_ll,IRESP2)
+   if ( iresp2 /= 0 ) call Print_msg( NVERB_ERROR, 'IO', 'OPEN_FILES', 'IMAX not found')
+
+   CALL IO_READ_FIELD(INFILES(1)%TFILE,'JMAX',NJMAX_ll,IRESP2)
+   !If not found in main file, try the fallback one
+   if ( options( OPTFALLBACK )%set .and. iresp2 /= 0 ) CALL IO_READ_FIELD(INFILES(2)%TFILE,'JMAX',NJMAX_ll,IRESP2)
+   if ( iresp2 /= 0 ) call Print_msg( NVERB_ERROR, 'IO', 'OPEN_FILES', 'JMAX not found')
+
    CALL IO_READ_FIELD(INFILES(1)%TFILE,'KMAX',NKMAX,IRESP2)
+   !If not found in main file, try the fallback one
+   if ( options( OPTFALLBACK )%set .and. iresp2 /= 0 ) CALL IO_READ_FIELD(INFILES(2)%TFILE,'KMAX',NKMAX,IRESP2)
    IF (IRESP2/=0) NKMAX = 0
    !
-   CALL IO_READ_FIELD(INFILES(1)%TFILE,'PROGRAM',CPROGRAM_ORIG)
+   CALL IO_READ_FIELD(INFILES(1)%TFILE,'PROGRAM',CPROGRAM_ORIG,IRESP2)
+   !If not found in main file, try the fallback one
+   if ( options( OPTFALLBACK )%set .and. iresp2 /= 0 ) CALL IO_READ_FIELD(INFILES(2)%TFILE,'PROGRAM',CPROGRAM_ORIG,IRESP2)
+   if ( iresp2 /= 0 ) call Print_msg( NVERB_ERROR, 'IO', 'OPEN_FILES', 'PROGRAM not found')
    !
    ALLOCATE(CSTORAGE_TYPE)
-   CALL IO_READ_FIELD(INFILES(1)%TFILE,'STORAGE_TYPE',CSTORAGE_TYPE)
+   CALL IO_READ_FIELD(INFILES(1)%TFILE,'STORAGE_TYPE',CSTORAGE_TYPE,IRESP2)
+   !If not found in main file, try the fallback one
+   if ( options( OPTFALLBACK )%set .and. iresp2 /= 0 ) CALL IO_READ_FIELD(INFILES(2)%TFILE,'STORAGE_TYPE',CSTORAGE_TYPE,IRESP2)
+   if ( iresp2 /= 0 ) call Print_msg( NVERB_ERROR, 'IO', 'OPEN_FILES', 'STORAGE_TYPE not found')
    !
    ALLOCATE(XXHAT(NIMAX_ll+2*JPHEXT))
-   CALL IO_READ_FIELD(INFILES(1)%TFILE,'XHAT',XXHAT)
+   CALL IO_READ_FIELD(INFILES(1)%TFILE,'XHAT',XXHAT,IRESP2)
+   !If not found in main file, try the fallback one
+   if ( options( OPTFALLBACK )%set .and. iresp2 /= 0 ) CALL IO_READ_FIELD(INFILES(2)%TFILE,'XHAT',XXHAT,IRESP2)
+   if ( iresp2 /= 0 ) call Print_msg( NVERB_ERROR, 'IO', 'OPEN_FILES', 'XHAT not found')
+
    ALLOCATE(XYHAT(NJMAX_ll+2*JPHEXT))
-   CALL IO_READ_FIELD(INFILES(1)%TFILE,'YHAT',XYHAT)
-   CALL IO_READ_FIELD(INFILES(1)%TFILE,'CARTESIAN',LCARTESIAN)
-   !
-   CALL IO_READ_FIELD(INFILES(1)%TFILE,'LAT0',XLAT0)
-   CALL IO_READ_FIELD(INFILES(1)%TFILE,'LON0',XLON0)
-   CALL IO_READ_FIELD(INFILES(1)%TFILE,'BETA',XBETA)
-   !
+   CALL IO_READ_FIELD(INFILES(1)%TFILE,'YHAT',XYHAT,IRESP2)
+   !If not found in main file, try the fallback one
+   if ( options( OPTFALLBACK )%set .and. iresp2 /= 0 ) CALL IO_READ_FIELD(INFILES(2)%TFILE,'YHAT',XYHAT,IRESP2)
+   if ( iresp2 /= 0 ) call Print_msg( NVERB_ERROR, 'IO', 'OPEN_FILES', 'YHAT not found')
+
+   CALL IO_READ_FIELD(INFILES(1)%TFILE,'CARTESIAN',LCARTESIAN,IRESP2)
+   !If not found in main file, try the fallback one
+   if ( options( OPTFALLBACK )%set .and. iresp2 /= 0 ) CALL IO_READ_FIELD(INFILES(2)%TFILE,'CARTESIAN',LCARTESIAN,IRESP2)
+   if ( iresp2 /= 0 ) call Print_msg( NVERB_ERROR, 'IO', 'OPEN_FILES', 'CARTESIAN not found')
+
+   CALL IO_READ_FIELD(INFILES(1)%TFILE,'LAT0',XLAT0,IRESP2)
+   !If not found in main file, try the fallback one
+   if ( options( OPTFALLBACK )%set .and. iresp2 /= 0 ) CALL IO_READ_FIELD(INFILES(2)%TFILE,'LAT0',XLAT0,IRESP2)
+   if ( iresp2 /= 0 ) call Print_msg( NVERB_ERROR, 'IO', 'OPEN_FILES', 'LAT0 not found')
+
+   CALL IO_READ_FIELD(INFILES(1)%TFILE,'LON0',XLON0,IRESP2)
+   !If not found in main file, try the fallback one
+   if ( options( OPTFALLBACK )%set .and. iresp2 /= 0 ) CALL IO_READ_FIELD(INFILES(2)%TFILE,'LON0',XLON0,IRESP2)
+   if ( iresp2 /= 0 ) call Print_msg( NVERB_ERROR, 'IO', 'OPEN_FILES', 'LON0 not found')
+
+   CALL IO_READ_FIELD(INFILES(1)%TFILE,'BETA',XBETA,IRESP2)
+   !If not found in main file, try the fallback one
+   if ( options( OPTFALLBACK )%set .and. iresp2 /= 0 ) CALL IO_READ_FIELD(INFILES(2)%TFILE,'BETA',XBETA,IRESP2)
+   if ( iresp2 /= 0 ) call Print_msg( NVERB_ERROR, 'IO', 'OPEN_FILES', 'BETA not found')
+
    IF (.NOT.LCARTESIAN) THEN
-     CALL IO_READ_FIELD(INFILES(1)%TFILE,'RPK',   XRPK)
-     CALL IO_READ_FIELD(INFILES(1)%TFILE,'LATORI',XLATORI)
-     CALL IO_READ_FIELD(INFILES(1)%TFILE,'LONORI',XLONORI)
+     CALL IO_READ_FIELD(INFILES(1)%TFILE,'RPK',   XRPK,   IRESP2)
+    !If not found in main file, try the fallback one
+    if ( options( OPTFALLBACK )%set .and. iresp2 /= 0 ) CALL IO_READ_FIELD(INFILES(2)%TFILE,'RPK',   XRPK,IRESP2)
+    if ( iresp2 /= 0 ) call Print_msg( NVERB_ERROR, 'IO', 'OPEN_FILES', 'RPK not found')
+
+     CALL IO_READ_FIELD(INFILES(1)%TFILE,'LATORI',XLATORI,IRESP2)
+    !If not found in main file, try the fallback one
+    if ( options( OPTFALLBACK )%set .and. iresp2 /= 0 ) CALL IO_READ_FIELD(INFILES(2)%TFILE,'LATORI',XLATORI,IRESP2)
+    if ( iresp2 /= 0 ) call Print_msg( NVERB_ERROR, 'IO', 'OPEN_FILES', 'LATORI not found')
+
+     CALL IO_READ_FIELD(INFILES(1)%TFILE,'LONORI',XLONORI,IRESP2)
+    !If not found in main file, try the fallback one
+    if ( options( OPTFALLBACK )%set .and. iresp2 /= 0 ) CALL IO_READ_FIELD(INFILES(2)%TFILE,'LONORI',XLONORI,IRESP2)
+    if ( iresp2 /= 0 ) call Print_msg( NVERB_ERROR, 'IO', 'OPEN_FILES', 'LONORI not found')
    ENDIF
    !
    IF (TRIM(CPROGRAM_ORIG)/='PGD' .AND. TRIM(CPROGRAM_ORIG)/='NESPGD' .AND. TRIM(CPROGRAM_ORIG)/='ZOOMPG' &
        .AND. .NOT.(TRIM(CPROGRAM_ORIG)=='REAL' .AND. CSTORAGE_TYPE=='SU') ) THEN !condition to detect PREP_SURFEX
      ALLOCATE(XZHAT(NKMAX+2*JPVEXT))
-     CALL IO_READ_FIELD(INFILES(1)%TFILE,'ZHAT',XZHAT)
+     CALL IO_READ_FIELD(INFILES(1)%TFILE,'ZHAT',XZHAT,IRESP2)
+     !If not found in main file, try the fallback one
+     if ( options( OPTFALLBACK )%set .and. iresp2 /= 0 ) CALL IO_READ_FIELD(INFILES(2)%TFILE,'ZHAT',XZHAT,IRESP2)
+     if ( iresp2 /= 0 ) call Print_msg( NVERB_ERROR, 'IO', 'OPEN_FILES', 'ZHAT not found')
+
      ALLOCATE(LSLEVE)
-     CALL IO_READ_FIELD(INFILES(1)%TFILE,'SLEVE',LSLEVE)
+     CALL IO_READ_FIELD(INFILES(1)%TFILE,'SLEVE',LSLEVE,IRESP2)
+     !If not found in main file, try the fallback one
+     if ( options( OPTFALLBACK )%set .and. iresp2 /= 0 ) CALL IO_READ_FIELD(INFILES(2)%TFILE,'SLEVE',LSLEVE,IRESP2)
+     if ( iresp2 /= 0 ) call Print_msg( NVERB_ERROR, 'IO', 'OPEN_FILES', 'SLEVE not found')
+
      ALLOCATE(TDTMOD)
      CALL IO_READ_FIELD(INFILES(1)%TFILE,'DTMOD',TDTMOD,IRESP2)
      IF(IRESP2/=0) DEALLOCATE(TDTMOD)
+
      ALLOCATE(TDTCUR)
      CALL IO_READ_FIELD(INFILES(1)%TFILE,'DTCUR',TDTCUR,IRESP2)
      IF(IRESP2/=0) DEALLOCATE(TDTCUR)
-- 
GitLab