From 024f4f788477d41c3f6489e62d882321f89213b4 Mon Sep 17 00:00:00 2001
From: Philippe WAUTELET <philippe.wautelet@aero.obs-mip.fr>
Date: Thu, 21 Feb 2019 15:32:05 +0100
Subject: [PATCH] =?UTF-8?q?Philippe=20and=20S=C3=A9bastien=20Riette=2021/0?=
 =?UTF-8?q?2/2019:=20add=20libs4py=20library=20(for=20epygram=20tool)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 bin/spll                     |   7 +-
 src/LIB/s4py/init_gfortran.c |  15 +
 src/LIB/s4py/libs4py.f90     | 532 +++++++++++++++++++++++++++++++++++
 src/Makefile                 |  24 +-
 src/Makefile.MESONH.mk       |  11 +
 src/Rules.AIX64.mk           |   5 +
 src/Rules.BG.mk              |   5 +
 src/Rules.BGQ.mk             |   5 +
 src/Rules.LXNAGfor.mk        |   5 +
 src/Rules.LXarm.mk           |   4 +
 src/Rules.LXcray.mk          |   5 +
 src/Rules.LXg95.mk           |   5 +
 src/Rules.LXgfortran.mk      |   4 +
 src/Rules.LXifort.mk         |   5 +
 src/Rules.LXpathf95.mk       |   5 +
 src/Rules.LXpgi.mk           |   5 +
 src/Rules.SX8.mk             |   5 +
 17 files changed, 641 insertions(+), 6 deletions(-)
 create mode 100644 src/LIB/s4py/init_gfortran.c
 create mode 100644 src/LIB/s4py/libs4py.f90

diff --git a/bin/spll b/bin/spll
index c8b0ada9e..ba2fd7884 100755
--- a/bin/spll
+++ b/bin/spll
@@ -1,7 +1,7 @@
 #!/bin/bash
-#MNH_LIC Copyright 1994-2014 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.
 #set -x
 if [ $# -ne 2 ]
@@ -26,7 +26,8 @@ ini_cmfshall.f90|mode_double_double.f90|mode_fgau.f90|\
 extern_usersurc_ll.f90|\
 extern_userio.f90|fmreadwrit.f90|fm_read_ll.f90|poub.f90|\
 mode_glt.*.F90|\
-rrtm_.*.F90|srtm_.*.F90"
+rrtm_.*.F90|srtm_.*.F90|\
+libs4py.f90"
 #
 
 if [ "$SUF" = "f" ]
diff --git a/src/LIB/s4py/init_gfortran.c b/src/LIB/s4py/init_gfortran.c
new file mode 100644
index 000000000..2fb55869b
--- /dev/null
+++ b/src/LIB/s4py/init_gfortran.c
@@ -0,0 +1,15 @@
+//MNH_LIC Copyright 2019-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 for details. version 1.
+//-----------------------------------------------------------------
+#ifdef __GFORTRAN__
+/* Philippe Marguinaud idea */
+
+void init_gfortran_big_endian_(){
+  _gfortran_set_convert (2);
+}
+void init_gfortran_native_endian_(){
+  _gfortran_set_convert (0);
+}
+#endif
diff --git a/src/LIB/s4py/libs4py.f90 b/src/LIB/s4py/libs4py.f90
new file mode 100644
index 000000000..94a199754
--- /dev/null
+++ b/src/LIB/s4py/libs4py.f90
@@ -0,0 +1,532 @@
+!MNH_LIC Copyright 2014-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 for details. version 1.
+!-----------------------------------------------------------------
+SUBROUTINE WLFIOUV(KRETURNCODE, CDFILE, CDSTATE, KNUMER)
+! ** PURPOSE
+!    Open a LFI file
+!
+! ** DUMMY ARGUMENTS
+!    KRETURNCODE: error code
+!    CDFILE: path to file to open
+!    CDSTATE: state of file ('NEW', 'OLD', 'UNKNOWN', 'SCRATCH')
+!    KNUMER: logical unit number associated to file
+!
+! ** AUTHOR
+!    9 April 2014, S. Riette
+!
+! ** MODIFICATIONS
+!    26 sept 2014, S. Riette: use 64bits LFI subroutines
+!    8 nov 2018, S. Riette: Meso-NH version
+!  P. Wautelet 21/02/2019: add copyright notice + use INT64 for 64-bits integers
+!
+! I. Dummy arguments declaration
+use iso_fortran_env, only: INT64
+IMPLICIT NONE
+INTEGER(KIND=INT64), INTENT(OUT) :: KRETURNCODE
+CHARACTER(LEN=*), INTENT(IN) :: CDFILE
+CHARACTER(LEN=*), INTENT(IN) :: CDSTATE
+INTEGER(KIND=INT64), INTENT(OUT) :: KNUMER
+!
+! II. Local variables declaration
+INTEGER, PARAMETER :: JPMAXLOGICALUNITNUMBER=5000
+INTEGER(KIND=LFI_INT) :: IRETURNCODE
+LOGICAL :: LLEXISTS, LLOPEN
+INTEGER(KIND=LFI_INT) :: IRECORDNUMBER
+INTEGER(KIND=LFI_INT) :: INUMER
+!
+! III. File opening
+!
+! III.a Search for an available logical unit
+INUMER=0
+LLEXISTS=.FALSE.
+LLOPEN=.TRUE.
+IRETURNCODE=0
+DO WHILE(INUMER.LT.JPMAXLOGICALUNITNUMBER .AND. (LLOPEN .OR. .NOT. LLEXISTS))
+  INUMER=INUMER+1
+  INQUIRE(UNIT=INUMER, EXIST=LLEXISTS, OPENED=LLOPEN)
+ENDDO
+IF(LLOPEN .OR. .NOT. LLEXISTS) THEN
+  IRETURNCODE=-999
+ENDIF
+!
+#ifdef __GFORTRAN__
+! III.b (Re)-init of libgfortran to enable big_endian file reading
+!**** *** ** * only gfortran will work with this * ** *** ****
+CALL INIT_GFORTRAN_BIG_ENDIAN()
+#endif
+!
+! III.c LFI file opening
+CALL LFIOUV(IRETURNCODE, INUMER, .TRUE., CDFILE, CDSTATE, .FALSE.,&
+           &.FALSE., INT(0, LFI_INT), INT(1, LFI_INT), IRECORDNUMBER)
+IF(IRETURNCODE/=0)THEN
+  CALL LFIENG(INUMER, INT(0, LFI_INT), IRETURNCODE, .FALSE., '', 'LFIOUV', '')
+ENDIF
+!
+#ifdef __GFORTRAN__
+! III.d (Re)-init of libgfortran to enable native endianess file reading
+!**** *** ** * only gfortran will work with this * ** *** ****
+CALL INIT_GFORTRAN_NATIVE_ENDIAN()
+#endif
+!
+KNUMER=INT(INUMER, 8)
+KRETURNCODE=INT(IRETURNCODE,8)
+
+END SUBROUTINE WLFIOUV
+
+!______________________________________________________________________
+
+SUBROUTINE WLFINAF(KRETURNCODE, KNUMER, KNALDO, KNTROU, KNARES, KNAMAX)
+! ** PURPOSE
+!    Wrapper to LFINAF
+!
+! ** DUMMY ARGUMENTS
+!    KRETURNCODE: error code
+!    KNUMER: logical unit number associated to file
+!    KNALDO: Number of actual logical data records (holes excluded)
+!    KNTROU: Number of logical records which are holes
+!    KNARES: Number of logical records which can be written in the reserved part of index (holes included)
+!    KNAMAX: Maximum number of logical records which one can write on logical unit
+!
+! ** AUTHOR
+!    9 April 2014, S. Riette
+!
+! ** MODIFICATIONS
+!    26 sept 2014, S. Riette: use 64bits LFI subroutines
+!    8 nov 2018, S. Riette: Meso-NH version
+!
+! I. Dummy arguments declaration
+use iso_fortran_env, only: INT64
+IMPLICIT NONE
+INTEGER(KIND=INT64), INTENT(OUT) :: KRETURNCODE
+INTEGER(KIND=INT64), INTENT(IN) :: KNUMER
+INTEGER(KIND=INT64), INTENT(OUT) :: KNALDO, KNTROU, KNARES, KNAMAX
+!
+! II. Local variables declaration
+INTEGER(KIND=LFI_INT) :: IRETURNCODE
+INTEGER(KIND=LFI_INT) :: INUMER
+INTEGER(KIND=LFI_INT) :: INALDO, INTROU, INARES, INAMAX
+!
+! III. LFINAF call
+INUMER=INT(KNUMER, KIND(INUMER))
+CALL LFINAF(IRETURNCODE, INUMER, INALDO, INTROU, INARES, INAMAX)
+IF(IRETURNCODE/=0)THEN
+  CALL LFIENG(INUMER, INT(0, LFI_INT), IRETURNCODE, .FALSE., '', 'LFINAF', '')
+ENDIF
+KRETURNCODE=INT(IRETURNCODE,8)
+KNALDO=INT(INALDO, 8)
+KNTROU=INT(INTROU, 8)
+KNARES=INT(INARES, 8)
+KNAMAX=INT(INAMAX, 8)
+!
+END SUBROUTINE WLFINAF
+
+!______________________________________________________________________
+
+SUBROUTINE WLFIPOS(KRETURNCODE, KNUMER)
+! ** PURPOSE
+!    Wrapper to LFIPOS
+!
+! ** DUMMY ARGUMENTS
+!    KRETURNCODE: error code
+!    KNUMER: logical unit number associated to file
+!
+! ** AUTHOR
+!    9 April 2014, S. Riette
+!
+! ** MODIFICATIONS
+!    26 sept 2014, S. Riette: use 64bits LFI subroutines
+!    8 nov 2018, S. Riette: Meso-NH version
+!
+! I. Dummy arguments declaration
+use iso_fortran_env, only: INT64
+IMPLICIT NONE
+INTEGER(KIND=INT64), INTENT(OUT) :: KRETURNCODE
+INTEGER(KIND=INT64), INTENT(IN) :: KNUMER
+!
+! II. Local variables declaration
+INTEGER(KIND=LFI_INT) :: IRETURNCODE
+INTEGER(KIND=LFI_INT) :: INUMER
+!
+! III. LFIPOS call
+INUMER=INT(KNUMER, KIND(INUMER))
+CALL LFIPOS(IRETURNCODE, INUMER)
+IF(IRETURNCODE/=0)THEN
+  CALL LFIENG(INUMER, INT(0, LFI_INT), IRETURNCODE, .FALSE., '', 'LFIPOS', '')
+ENDIF
+KRETURNCODE=INT(IRETURNCODE,8)
+!
+END SUBROUTINE WLFIPOS
+
+!______________________________________________________________________
+
+SUBROUTINE WLFICAS(KRETURNCODE, KNUMER, CDNOMA, KLONG, KPOSEX, LDAVAN)
+! ** PURPOSE
+!    Wrapper to LFICAS
+!
+! ** DUMMY ARGUMENTS
+!    KRETURNCODE: error code
+!    KNUMER: logical unit number associated to file
+!    CDNOMA: name of next record
+!    KLONG: length of next record
+!    KPOSEX: position in file of the first word of next record
+!    LDAVAN: true if one must move forward the pointer
+!
+! ** AUTHOR
+!    9 April 2014, S. Riette
+!
+! ** MODIFICATIONS
+!    26 sept 2014, S. Riette: use 64bits LFI subroutines
+!                             use of true logical instead of integer
+!    8 nov 2018, S. Riette: Meso-NH version
+!
+! I. Dummy arguments declaration
+use iso_fortran_env, only: INT64
+IMPLICIT NONE
+INTEGER(KIND=INT64), INTENT(OUT) :: KRETURNCODE
+INTEGER(KIND=INT64), INTENT(IN) :: KNUMER
+CHARACTER(LEN=16), INTENT(OUT) :: CDNOMA
+INTEGER(KIND=INT64), INTENT(OUT) :: KLONG, KPOSEX
+LOGICAL, INTENT(IN) :: LDAVAN
+!
+! II. Local variables declaration
+INTEGER(KIND=LFI_INT) :: IRETURNCODE
+INTEGER(KIND=LFI_INT) :: INUMER
+INTEGER(KIND=LFI_INT) :: ILONG, IPOSEX
+!
+! III. LFICAS call
+INUMER=INT(KNUMER, KIND(INUMER))
+CALL LFICAS(IRETURNCODE, INUMER, CDNOMA, ILONG, IPOSEX, LDAVAN)
+IF(IRETURNCODE/=0)THEN
+  CALL LFIENG(INUMER, INT(0, LFI_INT), IRETURNCODE, .FALSE., '', 'LFICAS', '')
+ENDIF
+KRETURNCODE=INT(IRETURNCODE,8)
+KLONG=INT(ILONG, 8)
+KPOSEX=INT(IPOSEX, 8)
+!
+END SUBROUTINE WLFICAS
+
+!______________________________________________________________________
+
+SUBROUTINE WLFINFO(KRETURNCODE, KNUMER, CDNOMA, KLONG, KPOSEX)
+! ** PURPOSE
+!    Wrapper to LFINFO
+!
+! ** DUMMY ARGUMENTS
+!    KRETURNCODE: error code
+!    KNUMER: logical unit number associated to file
+!    CDNOMA: name of record
+!    KLONG: length of record
+!    KPOSEX: position in file of the first word of next record
+
+! ** AUTHOR
+!    9 April 2014, S. Riette
+!
+! ** MODIFICATIONS
+!    26 sept 2014, S. Riette: use 64bits LFI subroutines
+!    8 nov 2018, S. Riette: Meso-NH version
+!
+! I. Dummy arguments declaration
+use iso_fortran_env, only: INT64
+IMPLICIT NONE
+INTEGER(KIND=INT64), INTENT(OUT) :: KRETURNCODE
+INTEGER(KIND=INT64), INTENT(IN) :: KNUMER
+CHARACTER(LEN=16), INTENT(IN) :: CDNOMA
+INTEGER(KIND=INT64), INTENT(OUT) :: KLONG, KPOSEX
+!
+! II. Local variables declaration
+INTEGER(KIND=LFI_INT) :: IRETURNCODE
+INTEGER(KIND=LFI_INT) :: INUMER
+INTEGER(KIND=LFI_INT) :: ILONG, IPOSEX
+!
+! III. LFINFO call
+INUMER=INT(KNUMER, KIND(INUMER))
+CALL LFINFO(IRETURNCODE, INUMER, CDNOMA, ILONG, IPOSEX)
+IF(IRETURNCODE/=0)THEN
+  CALL LFIENG(INUMER, INT(0, LFI_INT), IRETURNCODE, .FALSE., '', 'LFINFO', '')
+ENDIF
+KRETURNCODE=INT(IRETURNCODE,8)
+KLONG=INT(ILONG, 8)
+KPOSEX=INT(IPOSEX, 8)
+!
+END SUBROUTINE WLFINFO
+
+!______________________________________________________________________
+
+SUBROUTINE WLFILEC(KRETURNCODE, KNUMER, CDNOMA, KLONG, LDABORT, KTAB)
+! ** PURPOSE
+!    Wrapper to LFILEC
+!
+! ** DUMMY ARGUMENTS
+!    KRETURNCODE: error code
+!    KNUMER: logical unit number associated to file
+!    CDNOMA: name of record
+!    KLONG: length of record
+!    LDABORT: must we raise an exception on error -21 ?
+!    KTAB: integer array read
+
+! ** AUTHOR
+!    9 April 2014, S. Riette
+!
+! ** MODIFICATIONS
+!    26 sept 2014, S. Riette: use 64bits LFI subroutines
+!                             use of true logical instead of integer
+!    8 nov 2018, S. Riette: Meso-NH version
+!
+! I. Dummy arguments declaration
+use iso_fortran_env, only: INT64
+IMPLICIT NONE
+INTEGER(KIND=INT64), INTENT(OUT) :: KRETURNCODE
+INTEGER(KIND=INT64), INTENT(IN) :: KNUMER
+CHARACTER(LEN=16), INTENT(IN) :: CDNOMA
+INTEGER(KIND=INT64), INTENT(IN) :: KLONG
+LOGICAL, INTENT(IN) :: LDABORT
+INTEGER(KIND=INT64), INTENT(OUT), DIMENSION(KLONG) :: KTAB
+!
+! II. Local variables declaration
+INTEGER(KIND=LFI_INT) :: IRETURNCODE
+INTEGER(KIND=LFI_INT) :: INUMER, ILONG
+INTEGER(KIND=LFI_INT) :: ITOTLONG, IPOSEX
+INTEGER(KIND=INT64), ALLOCATABLE :: KTABTOT(:)
+!
+! III. LFILEC call
+INUMER=INT(KNUMER, KIND(INUMER))
+ILONG=INT(KLONG, KIND(ILONG))
+!
+!Because NERFAG cannot be changed easily, we read the entire article
+!even if only a part is needed, otherwise NERFAG=2 would be sufficient
+CALL WLFINFO(IRETURNCODE, INUMER, CDNOMA, ITOTLONG, IPOSEX)
+IF(ILONG .LT. ITOTLONG) THEN
+  ALLOCATE(KTABTOT(ITOTLONG))
+  CALL LFILEC(IRETURNCODE, INUMER, CDNOMA, KTABTOT, ITOTLONG)
+ELSE
+  CALL LFILEC(IRETURNCODE, INUMER, CDNOMA, KTAB, ILONG)
+ENDIF
+IF (IRETURNCODE/=0 .AND. .NOT. (IRETURNCODE==-21 .AND. .NOT. LDABORT)) THEN
+  CALL LFIENG(INUMER, INT(0, LFI_INT), IRETURNCODE, .FALSE., '', 'LFILEC', '')
+  KRETURNCODE=INT(IRETURNCODE,8)
+ELSE
+  KRETURNCODE=INT(0,8)
+ENDIF
+IF(ILONG .LT. ITOTLONG) THEN
+  KTAB(:)=KTABTOT(1:ILONG)
+  DEALLOCATE(KTABTOT)
+ENDIF
+!
+END SUBROUTINE WLFILEC
+
+!_________________________________________________________________________________________________
+
+SUBROUTINE WGET_COMPHEADER(KSIZE, KDATA, KLONG, KLONU, KTYPECOMP)
+! ** PURPOSE
+!    Wrapper to GET_COMPHEADER
+!
+! ** DUMMY ARGUMENTS
+!    KSIZE: Size of KDATA
+!    KDATA: (part of) integer array read from record
+!    KLONG: length of compressed data
+!    KLONU: length of uncompressed data
+!    KTYPECOMP: type of compression
+!
+! ** AUTHOR
+!    9 April 2014, S. Riette
+!
+! ** MODIFICATIONS
+!
+! I. Dummy arguments declaration
+use iso_fortran_env, only: INT64
+IMPLICIT NONE
+INTEGER(KIND=INT64), INTENT(IN) :: KSIZE
+INTEGER(KIND=INT64), INTENT(IN), DIMENSION(KSIZE) :: KDATA
+INTEGER(KIND=INT64), INTENT(IN) :: KLONG
+INTEGER(KIND=INT64), INTENT(OUT) :: KLONU
+INTEGER(KIND=INT64), INTENT(OUT) :: KTYPECOMP
+!
+! II. Local variables declaration
+INTEGER :: ILONG
+INTEGER :: ILONU, ITYPECOMP
+!
+! III. GET_COMPHEADER call
+#ifdef MNH_COMPRESS
+ILONG=KLONG
+CALL GET_COMPHEADER(KDATA, ILONG, ILONU, ITYPECOMP)
+KLONU=INT(ILONU, 8)
+KTYPECOMP=INT(ITYPECOMP, 8)
+#else
+print*, "Error: code was compiled without COMPRESS support, please define MNH_COMPRESS"
+KLONU=INT(-1, 8)
+KTYPECOMP=INT(-1, 8)
+#endif
+!
+END SUBROUTINE WGET_COMPHEADER
+
+!_________________________________________________________________________________________________
+
+SUBROUTINE WCOMPRESS_FIELD(KTAB, KX, KY, KSIZEDECOMP, KSIZECOMP)
+! ** PURPOSE
+!    Wrapper to COMPRESS_FIELD
+!
+! ** DUMMY ARGUMENTS
+!    KTAB: decompressed integer array (IN)
+!          compressed data integer array (OUT)
+!    KX, KY: x and y dimensions
+!    KSIZEDECOMP: size of decompressed data
+!    KSIZECOMP: size of compressed integer array
+!
+! ** AUTHOR
+!    16 July 2015, S. Riette
+!
+! ** MODIFICATIONS
+!
+! I. Dummy arguments declaration
+use iso_fortran_env, only: INT64
+IMPLICIT NONE
+INTEGER(KIND=INT64), INTENT(IN) :: KX, KY, KSIZEDECOMP
+INTEGER(KIND=INT64), INTENT(INOUT), DIMENSION(KSIZEDECOMP) :: KTAB
+INTEGER(KIND=INT64), INTENT(OUT) :: KSIZECOMP
+!
+! II. Local variables declaration
+INTEGER :: ISIZEDECOMP, ISIZECOMP, IX, IY
+!
+! III. COMPRESS_FIELD call
+#ifdef MNH_COMPRESS
+ISIZEDECOMP=KSIZEDECOMP
+IX=KX
+IY=KY
+CALL COMPRESS_FIELD(KTAB, IX, IY, ISIZEDECOMP, ISIZECOMP)
+KSIZECOMP=ISIZECOMP
+#else
+print*, "Error: code was compiled without COMPRESS support, please define MNH_COMPRESS"
+KSIZECOMP=INT(-1, 8)
+#endif
+!
+END SUBROUTINE WCOMPRESS_FIELD
+
+!_________________________________________________________________________________________________
+
+SUBROUTINE WDECOMPRESS_FIELD(KSIZE, KCOMP, KTYPECOMP, KLDECOMP, KDECOMP)
+! ** PURPOSE
+!    Wrapper to DECOMPRESS_FIELD
+!
+! ** DUMMY ARGUMENTS
+!    KSIZE: size of KCOMP
+!    KCOMP: compressed integer array
+!    KTYPECOMP: type of compression
+!    KDECOMP: decompressed data integer array
+!    KLDECOMP: length of decompressed data
+!
+! ** AUTHOR
+!    9 April 2014, S. Riette
+!
+! ** MODIFICATIONS
+!
+! I. Dummy arguments declaration
+use iso_fortran_env, only: INT64
+IMPLICIT NONE
+INTEGER(KIND=INT64), INTENT(IN) :: KSIZE
+INTEGER(KIND=INT64), INTENT(IN), DIMENSION(KSIZE) :: KCOMP
+INTEGER(KIND=INT64), INTENT(IN) :: KTYPECOMP
+INTEGER(KIND=INT64), INTENT(IN) :: KLDECOMP
+INTEGER(KIND=INT64), INTENT(OUT), DIMENSION(KLDECOMP) :: KDECOMP
+!
+! II. Local variables declaration
+INTEGER :: ITYPECOMP, ILDECOMP
+!
+! III. DECOMPRESS_FIELD call
+#ifdef MNH_COMPRESS
+ILDECOMP=KLDECOMP
+ITYPECOMP=KTYPECOMP
+CALL DECOMPRESS_FIELD(KDECOMP, ILDECOMP, KCOMP, SIZE(KCOMP,1), ITYPECOMP)
+#else
+print*, "Error: code was compiled without COMPRESS support, please define MNH_COMPRESS"
+KDECOMP(:)=-1
+#endif
+!
+END SUBROUTINE WDECOMPRESS_FIELD
+
+!_________________________________________________________________________________________________
+
+SUBROUTINE WLFIFER(KRETURNCODE, KNUMER, CDSTTC)
+! ** PURPOSE
+!    Close a LFI file
+!
+! ** DUMMY ARGUMENTS
+!    KRETURNCODE: error code
+!    KNUMER: logical unit number associated to file
+!    CDSTTC: close status ('KEEP', 'SCRATCH', 'DELETE')
+!
+! ** AUTHOR
+!    9 April 2014, S. Riette
+!
+! ** MODIFICATIONS
+!    26 sept 2014, S. Riette: use 64bits LFI subroutines
+!    8 nov 2018, S. Riette: Meso-NH version
+!
+! I. Dummy arguments declaration
+use iso_fortran_env, only: INT64
+IMPLICIT NONE
+INTEGER(KIND=INT64), INTENT(OUT) :: KRETURNCODE
+INTEGER(KIND=INT64), INTENT(IN) :: KNUMER
+CHARACTER(LEN=7), INTENT(IN) :: CDSTTC
+!
+! II.  Local variables declaration
+INTEGER(KIND=LFI_INT) :: IRETURNCODE
+INTEGER(KIND=LFI_INT) :: INUMER
+!
+! III. LFIFER call
+INUMER=INT(KNUMER, KIND(INUMER))
+CALL LFIFER(IRETURNCODE, INUMER, CDSTTC)
+IF(IRETURNCODE/=0)THEN
+  CALL LFIENG(INUMER, INT(0, LFI_INT), IRETURNCODE, .FALSE., '', 'LFIFER', '')
+ENDIF
+KRETURNCODE=INT(IRETURNCODE,8)
+!
+END SUBROUTINE WLFIFER
+
+!_________________________________________________________________________________________________
+
+SUBROUTINE WLFIECR(KRETURNCODE, KNUMER, CDNOMA, KSIZE, KTAB)
+! ** PURPOSE
+!    Wrapper to LFIECR
+!
+! ** DUMMY ARGUMENTS
+!    KRETURNCODE: error code
+!    KNUMER: logical unit number associated to file
+!    CDNOMA: name of field to write
+!    KSIZE: Size of KTAB
+!    KTAB: integer array to write
+!
+! ** AUTHOR
+!    9 April 2014, S. Riette
+!
+! ** MODIFICATIONS
+!    26 sept 2014, S. Riette: use 64bits LFI subroutines
+!    8 nov 2018, S. Riette: Meso-NH version
+!
+! I. Dummy arguments declaration
+use iso_fortran_env, only: INT64
+IMPLICIT NONE
+INTEGER(KIND=INT64), INTENT(OUT) :: KRETURNCODE
+INTEGER(KIND=INT64), INTENT(IN) :: KNUMER
+CHARACTER(LEN=16), INTENT(IN) :: CDNOMA
+INTEGER(KIND=INT64), INTENT(IN) :: KSIZE
+INTEGER(KIND=INT64), INTENT(IN), DIMENSION(KSIZE) :: KTAB
+!
+! II.  Local variables declaration
+INTEGER(KIND=LFI_INT) :: IRETURNCODE
+INTEGER(KIND=LFI_INT) :: INUMER
+INTEGER(KIND=LFI_INT) :: ISIZE
+!
+! III. LFIECR call
+INUMER=INT(KNUMER, KIND(INUMER))
+ISIZE=INT(KSIZE, KIND(ISIZE))
+CALL LFIECR(IRETURNCODE, INUMER, CDNOMA, KTAB, ISIZE)
+IF(IRETURNCODE/=0)THEN
+  CALL LFIENG(INUMER, INT(0, LFI_INT), IRETURNCODE, .FALSE., '', 'LFIECR', '')
+ENDIF
+KRETURNCODE=INT(IRETURNCODE,8)
+!
+END SUBROUTINE WLFIECR
+
+!_________________________________________________________________________________________________
diff --git a/src/Makefile b/src/Makefile
index ef5a0b30f..8a1039a07 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,6 +1,6 @@
-#MNH_LIC Copyright 1994-2014 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.
 ##########################################################
 #                                                        #
@@ -58,7 +58,7 @@ include Rules.$(ARCH)$(F).mk
 #   All modification are allowed !!!!!                   #
 #   adding new subroutines                               #
 #       or                                               #
-#   adding new modules                                   #       
+#   adding new modules                                   #
 #                                                        #
 #   REM : if during modification, you deleting some      #
 #         FORTRAN subroutines you must also deleted the  #
@@ -389,8 +389,26 @@ cleanmaster : cleanoasis
 cleanoasis :
 	- [ -d ${OASIS_PATH} ] && rm -fr  ${OASIS_PATH}
 endif
+##########################################################
+#                                                        #
+# EXTRA LIB : S4PY                                       #
+#                                                        #
+##########################################################
+ifdef MNH_S4PY
+all : libs4py.so
 
+OBJ_S4PY=$(OBJDIR_MASTER)/spll_wcompress_field.o $(OBJDIR_MASTER)/spll_wdecompress_field.o \
+$(OBJDIR_MASTER)/spll_wget_compheader.o $(OBJDIR_MASTER)/spll_wlficas.o \
+$(OBJDIR_MASTER)/spll_wlfiecr.o $(OBJDIR_MASTER)/spll_wlfifer.o \
+$(OBJDIR_MASTER)/spll_wlfilec.o $(OBJDIR_MASTER)/spll_wlfinaf.o \
+$(OBJDIR_MASTER)/spll_wlfinfo.o $(OBJDIR_MASTER)/spll_wlfiouv.o $(OBJDIR_MASTER)/spll_wlfipos.o \
+$(OBJDIR_MASTER)/spll_NEWLFI_ALL.o $(OBJDIR_MASTER)/spll_lockasgn.o \
+$(OBJDIR_MASTER)/spll_lockoff.o $(OBJDIR_MASTER)/spll_lockon.o $(OBJDIR_MASTER)/spll_lockrel.o \
+$(OBJDIR_MASTER)/fswap8buff.o $(OBJDIR_MASTER)/spll_remark2.o
 
+libs4py.so : progmaster
+	$(F90) -shared $(LDFLAGS) -o $(OBJDIR_MASTER)/$@ $(OBJ_S4PY) $(LIBS)
+endif
 ##########################################################
 #                                                        #
 # PROGRAM RULES                                          #
diff --git a/src/Makefile.MESONH.mk b/src/Makefile.MESONH.mk
index 90e2b092e..e4f2f56c8 100644
--- a/src/Makefile.MESONH.mk
+++ b/src/Makefile.MESONH.mk
@@ -255,6 +255,17 @@ CPPFLAGS_COMPRESS     ?= -DLITTLE_endian
 CPPFLAGS              += $(CPPFLAGS_COMPRESS)
 endif
 ##########################################################
+#           Source S4PY                                  #
+##########################################################
+ifdef MNH_S4PY
+DIR_S4PY               = LIB/s4py
+INC_S4PY               = -I$(B)$(DIR_S4PY)
+DIR_MASTER            += $(DIR_S4PY)
+OBJS_LISTE_MASTER     += init_gfortran.o
+INC                   += $(INC_S4PY)
+VPATH                 += $(DIR_S4PY)
+endif
+##########################################################
 #           Source FOREFIRE                              #
 ##########################################################
 ifdef MNH_FOREFIRE
diff --git a/src/Rules.AIX64.mk b/src/Rules.AIX64.mk
index c207e6df3..9bf3b1262 100644
--- a/src/Rules.AIX64.mk
+++ b/src/Rules.AIX64.mk
@@ -106,6 +106,11 @@ MNH_TOOLS = yes
 #if MNH_COMPRESS exists => compile the COMPRESS library (for LFI files)
 MNH_COMPRESS=yes
 #
+## S4PY flag
+#
+#if MNH_S4PY exists => compile the libs4py library (for epygram)
+MNH_S4PY=yes
+#
 ##########################################################
 #                                                        #
 # Source of MESONH PACKAGE  Distribution                 #
diff --git a/src/Rules.BG.mk b/src/Rules.BG.mk
index d34ee73ae..bf5f73d9a 100644
--- a/src/Rules.BG.mk
+++ b/src/Rules.BG.mk
@@ -117,6 +117,11 @@ CNAME_GRIBEX=""
 #if MNH_COMPRESS exists => compile the COMPRESS library (for LFI files)
 #MNH_COMPRESS=no
 #
+## S4PY flag
+#
+#if MNH_S4PY exists => compile the libs4py library (for epygram)
+#MNH_S4PY=no
+#
 ##########################################################
 #                                                        #
 # Source of MESONH PACKAGE  Distribution                 #
diff --git a/src/Rules.BGQ.mk b/src/Rules.BGQ.mk
index afd158a03..6418fb149 100644
--- a/src/Rules.BGQ.mk
+++ b/src/Rules.BGQ.mk
@@ -176,6 +176,11 @@ GRIBAPI_CONF= --host=powerpc64-bgq-linux
 #if MNH_COMPRESS exists => compile the COMPRESS library (for LFI files)
 #MNH_COMPRESS=no
 #
+## S4PY flag
+#
+#if MNH_S4PY exists => compile the libs4py library (for epygram)
+#MNH_S4PY=no
+#
 ##########################################################
 #                                                        #
 # Source of MESONH PACKAGE  Distribution                 #
diff --git a/src/Rules.LXNAGfor.mk b/src/Rules.LXNAGfor.mk
index 00f9c48b2..64294f6c0 100644
--- a/src/Rules.LXNAGfor.mk
+++ b/src/Rules.LXNAGfor.mk
@@ -99,6 +99,11 @@ MNH_TOOLS = yes
 #if MNH_COMPRESS exists => compile the COMPRESS library (for LFI files)
 MNH_COMPRESS=yes
 #
+## S4PY flag
+#
+#if MNH_S4PY exists => compile the libs4py library (for epygram)
+MNH_S4PY=yes
+#
 ##########################################################
 #                                                        #
 # Source of MESONH PACKAGE  Distribution                 #
diff --git a/src/Rules.LXarm.mk b/src/Rules.LXarm.mk
index 918d1fc22..dc9369223 100644
--- a/src/Rules.LXarm.mk
+++ b/src/Rules.LXarm.mk
@@ -121,6 +121,10 @@ endif
 #if MNH_COMPRESS exists => compile the COMPRESS library (for LFI files)
 MNH_COMPRESS=yes
 #
+## S4PY flag
+#
+#if MNH_S4PY exists => compile the libs4py library (for epygram)
+MNH_S4PY=yes
 #
 ##########################################################
 #                                                        #
diff --git a/src/Rules.LXcray.mk b/src/Rules.LXcray.mk
index ae24c8420..425a0b9d6 100644
--- a/src/Rules.LXcray.mk
+++ b/src/Rules.LXcray.mk
@@ -114,6 +114,11 @@ MNH_TOOLS = yes
 #if MNH_COMPRESS exists => compile the COMPRESS library (for LFI files)
 MNH_COMPRESS=yes
 #
+## S4PY flag
+#
+#if MNH_S4PY exists => compile the libs4py library (for epygram)
+MNH_S4PY=yes
+#
 ##########################################################
 #                                                        #
 # Source of MESONH PACKAGE  Distribution                 #
diff --git a/src/Rules.LXg95.mk b/src/Rules.LXg95.mk
index cdd6184f0..e08e73ed7 100644
--- a/src/Rules.LXg95.mk
+++ b/src/Rules.LXg95.mk
@@ -86,6 +86,11 @@ MNH_TOOLS = yes
 #if MNH_COMPRESS exists => compile the COMPRESS library (for LFI files)
 MNH_COMPRESS=yes
 #
+## S4PY flag
+#
+#if MNH_S4PY exists => compile the libs4py library (for epygram)
+MNH_S4PY=yes
+#
 ##########################################################
 #                                                        #
 # Source of MESONH PACKAGE  Distribution                 #
diff --git a/src/Rules.LXgfortran.mk b/src/Rules.LXgfortran.mk
index a606a2fc3..58689e968 100644
--- a/src/Rules.LXgfortran.mk
+++ b/src/Rules.LXgfortran.mk
@@ -115,6 +115,10 @@ endif
 #if MNH_COMPRESS exists => compile the COMPRESS library (for LFI files)
 MNH_COMPRESS=yes
 #
+## S4PY flag
+#
+#if MNH_S4PY exists => compile the libs4py library (for epygram)
+MNH_S4PY=yes
 #
 ##########################################################
 #                                                        #
diff --git a/src/Rules.LXifort.mk b/src/Rules.LXifort.mk
index 60af5234d..231f1949a 100644
--- a/src/Rules.LXifort.mk
+++ b/src/Rules.LXifort.mk
@@ -210,6 +210,11 @@ endif
 #if MNH_COMPRESS exists => compile the COMPRESS library (for LFI files)
 MNH_COMPRESS=yes
 #
+## S4PY flag
+#
+#if MNH_S4PY exists => compile the libs4py library (for epygram)
+MNH_S4PY=yes
+#
 ##########################################################
 #                                                        #
 # Source of MESONH PACKAGE  Distribution                 #
diff --git a/src/Rules.LXpathf95.mk b/src/Rules.LXpathf95.mk
index 1e0487f1f..fe34aa467 100644
--- a/src/Rules.LXpathf95.mk
+++ b/src/Rules.LXpathf95.mk
@@ -62,6 +62,11 @@ MNH_TOOLS = yes
 #if MNH_COMPRESS exists => compile the COMPRESS library (for LFI files)
 MNH_COMPRESS=yes
 #
+## S4PY flag
+#
+#if MNH_S4PY exists => compile the libs4py library (for epygram)
+MNH_S4PY=yes
+#
 ##########################################################
 #                                                        #
 # Source of MESONH PACKAGE  Distribution                 #
diff --git a/src/Rules.LXpgi.mk b/src/Rules.LXpgi.mk
index 7bae40f42..498f56f7b 100644
--- a/src/Rules.LXpgi.mk
+++ b/src/Rules.LXpgi.mk
@@ -121,6 +121,11 @@ MNH_TOOLS = yes
 #if MNH_COMPRESS exists => compile the COMPRESS library (for LFI files)
 MNH_COMPRESS=yes
 #
+## S4PY flag
+#
+#if MNH_S4PY exists => compile the libs4py library (for epygram)
+MNH_S4PY=yes
+#
 ##########################################################
 #                                                        #
 # Source of MESONH PACKAGE  Distribution                 #
diff --git a/src/Rules.SX8.mk b/src/Rules.SX8.mk
index 1246647cc..abbaf8722 100644
--- a/src/Rules.SX8.mk
+++ b/src/Rules.SX8.mk
@@ -108,6 +108,11 @@ CNAME_GRIBEX=sxmpif90
 #if MNH_COMPRESS exists => compile the COMPRESS library (for LFI files)
 #MNH_COMPRESS=no
 #
+## S4PY flag
+#
+#if MNH_S4PY exists => compile the libs4py library (for epygram)
+#MNH_S4PY=no
+#
 ##########################################################
 #                                                        #
 # Source of MESONH PACKAGE  Distribution                 #
-- 
GitLab