From 2860ba37dbc64c9a44ea45162047e9cf158c00eb Mon Sep 17 00:00:00 2001
From: Philippe WAUTELET <philippe.wautelet@aero.obs-mip.fr>
Date: Fri, 18 Sep 2015 10:04:49 +0200
Subject: [PATCH] lfi2cdf: new option: '-r or --reduce' to reduce precision of
 float (double -> real)

---
 tools/lfi2cdf/src/lfi2cdf.f90   |  9 +++++----
 tools/lfi2cdf/src/mode_util.f90 | 14 +++++++++++---
 tools/lfi2cdf/src/newmain.c     | 14 ++++++++++----
 3 files changed, 26 insertions(+), 11 deletions(-)

diff --git a/tools/lfi2cdf/src/lfi2cdf.f90 b/tools/lfi2cdf/src/lfi2cdf.f90
index bd1342db7..4112840f1 100644
--- a/tools/lfi2cdf/src/lfi2cdf.f90
+++ b/tools/lfi2cdf/src/lfi2cdf.f90
@@ -1,4 +1,5 @@
-subroutine  LFI2CDFMAIN(hinfile,iiflen,ooutname,houtfile,ioflen,hvarlist,ivlen,olfi2cdf,olfilist,ohdf5,omerge,nb_levels)
+subroutine  LFI2CDFMAIN(hinfile,iiflen,ooutname,houtfile,ioflen,hvarlist,ivlen,olfi2cdf,olfilist,ohdf5,omerge,nb_levels,&
+                        oreduceprecision)
   USE mode_util
   IMPLICIT NONE 
   INTEGER :: iiflen, ioflen, ivlen
@@ -6,7 +7,7 @@ subroutine  LFI2CDFMAIN(hinfile,iiflen,ooutname,houtfile,ioflen,hvarlist,ivlen,o
   CHARACTER(LEN=iiflen) :: hinfile
   CHARACTER(LEN=ioflen) :: houtfile
   CHARACTER(LEN=ivlen)  :: hvarlist
-  LOGICAL :: ooutname, olfi2cdf, olfilist, ohdf5, omerge
+  LOGICAL :: ooutname, olfi2cdf, olfilist, ohdf5, omerge, oreduceprecision
   
   INTEGER :: ibuflen
   INTEGER :: ilu
@@ -43,7 +44,7 @@ subroutine  LFI2CDFMAIN(hinfile,iiflen,ooutname,houtfile,ioflen,hvarlist,ivlen,o
      !Standard treatment (one LFI file only)
      IF (.not.omerge) THEN
        CALL parse_lfi(ilu,hvarlist,inaf,tzreclist,ibuflen)
-       CALL def_ncdf(tzreclist,inaf,icdf_id,omerge)
+       CALL def_ncdf(tzreclist,inaf,oreduceprecision,icdf_id,omerge)
        CALL fill_ncdf(ilu,icdf_id,tzreclist,inaf,ibuflen)
      ELSE
      !Treat several LFI files and merge into 1 NC file
@@ -56,7 +57,7 @@ subroutine  LFI2CDFMAIN(hinfile,iiflen,ooutname,houtfile,ioflen,hvarlist,ivlen,o
 
        !Read 1st LFI file
        CALL parse_lfi(ilu,hvarlist,inaf,tzreclist,ibuflen,current_level)
-       CALL def_ncdf(tzreclist,inaf,icdf_id,omerge)
+       CALL def_ncdf(tzreclist,inaf,oreduceprecision,icdf_id,omerge)
 
        DO current_level = first_level,last_level
          print *,'Treating level ',current_level
diff --git a/tools/lfi2cdf/src/mode_util.f90 b/tools/lfi2cdf/src/mode_util.f90
index 5deedbc85..df31e72ae 100644
--- a/tools/lfi2cdf/src/mode_util.f90
+++ b/tools/lfi2cdf/src/mode_util.f90
@@ -274,9 +274,10 @@ CONTAINS
     END IF
   END SUBROUTINE HANDLE_ERR
 
-  SUBROUTINE def_ncdf(tpreclist,knaf,kcdf_id,omerge)
+  SUBROUTINE def_ncdf(tpreclist,knaf,oreduceprecision,kcdf_id,omerge)
     TYPE(workfield),DIMENSION(:),INTENT(INOUT) :: tpreclist
     INTEGER,                     INTENT(IN) :: knaf
+    LOGICAL,                     INTENT(IN) :: oreduceprecision
     INTEGER,                     INTENT(OUT):: kcdf_id
     LOGICAL,                     INTENT(IN) :: omerge
 
@@ -284,10 +285,17 @@ CONTAINS
     INTEGER :: ji
     TYPE(dimCDF), POINTER :: tzdim
     INTEGER               :: invdims
+    INTEGER               :: type_float
     INTEGER, DIMENSION(10) :: ivdims
     CHARACTER(LEN=20)     :: ycdfvar
 
 
+    IF (oreduceprecision) THEN
+      type_float = NF90_REAL
+    ELSE
+      type_float = NF90_DOUBLE
+    END IF
+
       ! global attributes
       status = NF90_PUT_ATT(kcdf_id,NF90_GLOBAL,'Title',VERSION_ID)
       IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
@@ -360,7 +368,7 @@ CONTAINS
 
        CASE(FLOAT)
 !          PRINT *,'FLOAT : ',tpreclist(ji)%name
-          status = NF90_DEF_VAR(kcdf_id,ycdfvar,NF90_DOUBLE,&
+          status = NF90_DEF_VAR(kcdf_id,ycdfvar,type_float,&
                    ivdims(:invdims),tpreclist(ji)%id)
           IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
 
@@ -368,7 +376,7 @@ CONTAINS
        CASE default
           PRINT *,'ATTENTION : ',TRIM(tpreclist(ji)%name),' est de&
                & TYPE inconnu --> force a REAL'
-          status = NF90_DEF_VAR(kcdf_id,ycdfvar,NF90_DOUBLE,&
+          status = NF90_DEF_VAR(kcdf_id,ycdfvar,type_float,&
                    ivdims(:invdims),tpreclist(ji)%id)
           IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
           
diff --git a/tools/lfi2cdf/src/newmain.c b/tools/lfi2cdf/src/newmain.c
index 8b6b9b9d2..2ce8de091 100644
--- a/tools/lfi2cdf/src/newmain.c
+++ b/tools/lfi2cdf/src/newmain.c
@@ -5,7 +5,7 @@
 
 #define BUFSIZE 4096
 
-extern lfi2cdfmain_(char*, int*, int *, char*, int*, char*, int*, int*, int*, int*, int*, int*);
+extern lfi2cdfmain_(char*, int*, int *, char*, int*, char*, int*, int*, int*, int*, int*, int*, int*);
 
 char *cleancomma(char *varlist)
 {
@@ -31,6 +31,7 @@ int main(int argc, char **argv)
   int l2c_flag;
   int hdf5_flag;
   int merge_flag, nb_levels;
+  int reduceprecision_flag;
   int outname_flag;
   char *cmd, *infile;
   int c;
@@ -51,6 +52,7 @@ int main(int argc, char **argv)
 
   list_flag = 0;
   hdf5_flag = 0;
+  reduceprecision_flag = 0;
   p = buff;
   *p = '\0';
 
@@ -66,11 +68,12 @@ int main(int argc, char **argv)
       {"list",             no_argument,       0, 'l' },
       {"merge",            required_argument, 0, 'm' },
       {"output",           required_argument, 0, 'o' },
+      {"reduce-precision", no_argument,       0, 'r' },
       {"var",              required_argument, 0, 'v' },
       {0,                  0,                 0,  0  }
     };
 
-    c = getopt_long(argc, argv, "4lm:o:v:",
+    c = getopt_long(argc, argv, "4lm:o:rv:",
 		    long_options, &option_index);
     if (c == -1)
       break;
@@ -97,6 +100,9 @@ int main(int argc, char **argv)
       outfile = optarg;
       olen = strlen(outfile);
       break;
+    case 'r':
+      reduceprecision_flag = 1;
+      break;
     case 'v':
       if (l2c_flag) {
 	lenopt = strlen(optarg);
@@ -118,7 +124,7 @@ int main(int argc, char **argv)
   }
 
   if (optind == argc) {
-    printf("usage : lfi2cdf [--cdf4 -4] [-l] [-v --var var1[,...]] [-m --merge number_of_z_levels] [-o --output output-file.nc] input-file.lfi\n");
+    printf("usage : lfi2cdf [--cdf4 -4] [-l] [-v --var var1[,...]] [-r --reduce-precision] [-m --merge number_of_z_levels] [-o --output output-file.nc] input-file.lfi\n");
     printf("        cdf2lfi [-o --output output-file.lfi] input-file.nc\n");
     exit(EXIT_FAILURE);
   } 
@@ -156,7 +162,7 @@ int main(int argc, char **argv)
   */
 
   lfi2cdfmain_(infile, &ilen, &outname_flag, outfile, &olen, varlist, &varlistlen, &l2c_flag, &list_flag, &hdf5_flag, &merge_flag,
-		       &nb_levels);
+		       &nb_levels, &reduceprecision_flag);
 
   exit(EXIT_SUCCESS);
 }
-- 
GitLab