From d4b00c3bd631fe31f12346016faecbc871558e00 Mon Sep 17 00:00:00 2001
From: Philippe WAUTELET <philippe.wautelet@aero.obs-mip.fr>
Date: Tue, 27 Oct 2015 15:24:42 +0100
Subject: [PATCH] lfi2cdf: *added cdf2cdf          *bug correction for lfi2cdf
 and LOWMEM: LFINFO -> LFILEC

---
 tools/lfi2cdf/Makefile          |   5 +-
 tools/lfi2cdf/src/lfi2cdf.f90   |  89 ++--
 tools/lfi2cdf/src/mode_util.f90 | 799 ++++++++++++++++++++------------
 tools/lfi2cdf/src/newmain.c     |  40 +-
 4 files changed, 603 insertions(+), 330 deletions(-)

diff --git a/tools/lfi2cdf/Makefile b/tools/lfi2cdf/Makefile
index 89f8e1833..d37681ce5 100644
--- a/tools/lfi2cdf/Makefile
+++ b/tools/lfi2cdf/Makefile
@@ -35,7 +35,10 @@ include Rules.$(ARCH)
 %.o:%.c $(DIR_OBJ)/.dummy
 	$(CC) $(INC) $(CFLAGS) $(CPPFLAGS) -c $< -o $(DIR_OBJ)/$(*F).o
 
-all : $(PROGS) cdf2lfi
+all : $(PROGS) cdf2cdf cdf2lfi
+
+cdf2cdf: $(PROGS) 
+	cd $(DIR_OBJ); rm -f cdf2cdf; ln -s $(PROGS) cdf2cdf
 
 cdf2lfi: $(PROGS) 
 	cd $(DIR_OBJ); rm -f cdf2lfi; ln -s $(PROGS) cdf2lfi
diff --git a/tools/lfi2cdf/src/lfi2cdf.f90 b/tools/lfi2cdf/src/lfi2cdf.f90
index b4039b446..ebe4f30b9 100644
--- a/tools/lfi2cdf/src/lfi2cdf.f90
+++ b/tools/lfi2cdf/src/lfi2cdf.f90
@@ -1,5 +1,5 @@
-subroutine  LFI2CDFMAIN(hinfile,iiflen,ooutname,houtfile,ioflen,hvarlist,ivlen,olfi2cdf,olfilist,ohdf5,omerge,nb_levels,&
-                        oreduceprecision,osplit,ocompress,compress_level)
+subroutine  LFI2CDFMAIN(hinfile,iiflen,ooutname,houtfile,ioflen,hvarlist,ivlen,ocdf2cdf,olfi2cdf,olfilist,ohdf5,omerge,&
+                        nb_levels,oreduceprecision,osplit,ocompress,compress_level)
   USE mode_util
   IMPLICIT NONE 
   INTEGER :: iiflen, ioflen, ivlen
@@ -7,25 +7,21 @@ 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, oreduceprecision, osplit, ocompress
+  LOGICAL :: ooutname, ocdf2cdf, olfi2cdf, olfilist, ohdf5, omerge, oreduceprecision, osplit, ocompress
   INTEGER :: compress_level
 
   INTEGER :: ibuflen
-  INTEGER :: ilu
   INTEGER :: ji
-  INTEGER :: nbvar_lfi  ! number of variables available in the LFI file
+  INTEGER :: nbvar_infile ! number of variables available in the input file
   INTEGER :: nbvar_tbr  ! number of variables to be read
   INTEGER :: nbvar_calc ! number of variables to be computed from others
   INTEGER :: nbvar_tbw  ! number of variables to be written
   INTEGER :: nbvar      ! number of defined variables
   INTEGER :: first_level, current_level, last_level
-  TYPE(cdf_files) :: cdffiles
+  TYPE(filelist_struct) :: infiles, outfiles
   TYPE(workfield), DIMENSION(:), POINTER :: tzreclist
 
 
-  cdffiles%nbfiles = 0
-  cdffiles%opened  = .FALSE.
-
   !Remove level in the filename if merging LFI splitted files
   if (.NOT.ooutname) then
     if (omerge .AND. .NOT.osplit) then
@@ -49,11 +45,10 @@ subroutine  LFI2CDFMAIN(hinfile,iiflen,ooutname,houtfile,ioflen,hvarlist,ivlen,o
     end if
   end if
 
-  CALL OPEN_FILES(hinfile, houtfile, olfi2cdf, olfilist, ohdf5, cdffiles, ilu, nbvar_lfi, osplit)
+  CALL OPEN_FILES(infiles, outfiles, hinfile, houtfile, ocdf2cdf, olfi2cdf, olfilist, ohdf5, nbvar_infile, osplit)
   IF (olfilist) return
 
-  IF (olfi2cdf) THEN
-     ! Conversion LFI -> NetCDF
+  IF (olfi2cdf .OR. ocdf2cdf) THEN
      IF (ivlen > 0) THEN
         ! nbvar_tbr is computed from number of requested variables
         ! by counting commas, = and +
@@ -73,15 +68,19 @@ subroutine  LFI2CDFMAIN(hinfile,iiflen,ooutname,houtfile,ioflen,hvarlist,ivlen,o
         END DO
         nbvar = nbvar_calc + nbvar_tbr
      ELSE
-        nbvar = nbvar_lfi
+        nbvar = nbvar_infile
      END IF
+  END IF
+
+  IF (olfi2cdf) THEN
+     ! Conversion LFI -> NetCDF
      
      !Standard treatment (one LFI file only)
      IF (.not.omerge) THEN
-       CALL parse_lfi(ilu,hvarlist,nbvar_lfi,nbvar_tbr,nbvar_calc,nbvar_tbw,tzreclist,ibuflen)
-       IF (osplit) call open_split_ncfiles(houtfile,nbvar,tzreclist,cdffiles,ohdf5)
-       CALL def_ncdf(tzreclist,nbvar,oreduceprecision,cdffiles,omerge,ocompress,compress_level)
-       CALL fill_ncdf(ilu,tzreclist,nbvar,ibuflen,cdffiles)
+       CALL parse_infiles(infiles,hvarlist,nbvar_infile,nbvar_tbr,nbvar_calc,nbvar_tbw,tzreclist,ibuflen)
+       IF (osplit) call open_split_ncfiles_out(outfiles,houtfile,nbvar,tzreclist,ohdf5)
+       CALL def_ncdf(outfiles,tzreclist,nbvar,oreduceprecision,omerge,osplit,ocompress,compress_level)
+       CALL fill_ncdf(infiles,outfiles,tzreclist,nbvar,ibuflen,osplit)
 
      ELSE
      !Treat several LFI files and merge into 1 NC file
@@ -92,29 +91,65 @@ subroutine  LFI2CDFMAIN(hinfile,iiflen,ooutname,houtfile,ioflen,hvarlist,ivlen,o
        last_level    = first_level + nb_levels - 1
 
        !Read 1st LFI file
-       CALL parse_lfi(ilu,hvarlist,nbvar_lfi,nbvar_tbr,nbvar_calc,nbvar_tbw,tzreclist,ibuflen,current_level)
-       IF (osplit) call open_split_ncfiles(houtfile,nbvar,tzreclist,cdffiles,ohdf5)
+       CALL parse_infiles(infiles,hvarlist,nbvar_infile,nbvar_tbr,nbvar_calc,nbvar_tbw,tzreclist,ibuflen,current_level)
+       IF (osplit) call open_split_ncfiles_out(outfiles,houtfile,nbvar,tzreclist,ohdf5)
+       !Define NC variables
+       CALL def_ncdf(outfiles,tzreclist,nbvar,oreduceprecision,omerge,osplit,ocompress,compress_level)
+
+       DO current_level = first_level,last_level
+         print *,'Treating level ',current_level
+         IF (current_level/=first_level) THEN
+           CALL open_split_lfifile_in(infiles,hinfile,current_level)
+           CALL read_data_lfi(infiles,hvarlist,nbvar,tzreclist,ibuflen,current_level)
+         END IF
+         CALL fill_ncdf(infiles,outfiles,tzreclist,nbvar,ibuflen,osplit,current_level)
+         IF (current_level/=last_level) CALL close_files(infiles)
+       END DO
+     END IF
+
+  ELSE IF (ocdf2cdf) THEN
+     ! Conversion netCDF -> netCDF
+
+     !Standard treatment (one netCDF file only)
+     IF (.not.omerge) THEN
+       CALL parse_infiles(infiles,hvarlist,nbvar_infile,nbvar_tbr,nbvar_calc,nbvar_tbw,tzreclist,ibuflen,current_level)
+       IF (osplit) call open_split_ncfiles_out(outfiles,houtfile,nbvar,tzreclist,ohdf5)
+       CALL def_ncdf(outfiles,tzreclist,nbvar,oreduceprecision,omerge,osplit,ocompress,compress_level)
+       CALL fill_ncdf(infiles,outfiles,tzreclist,nbvar,ibuflen,osplit)
+
+     ELSE
+     !Treat several NC files and merge into 1 NC file
+
+       !Determine first level (eg needed to find suffix of the variable name)
+       read( hinfile(len(hinfile)-5:len(hinfile)-3) , "(I3)" ) first_level
+       current_level = first_level
+       last_level    = first_level + nb_levels - 1
+
+       !Read 1st NC file
+       CALL parse_infiles(infiles,hvarlist,nbvar_infile,nbvar_tbr,nbvar_calc,nbvar_tbw,tzreclist,ibuflen,current_level)
+       IF (osplit) call open_split_ncfiles_out(outfiles,houtfile,nbvar,tzreclist,ohdf5)
        !Define NC variables
-       CALL def_ncdf(tzreclist,nbvar,oreduceprecision,cdffiles,omerge,ocompress,compress_level)
+       CALL def_ncdf(outfiles,tzreclist,nbvar,oreduceprecision,omerge,osplit,ocompress,compress_level)
 
        DO current_level = first_level,last_level
          print *,'Treating level ',current_level
          IF (current_level/=first_level) THEN
-           CALL open_split_lfifile(ilu,hinfile,current_level)
-           CALL read_data_lfi(ilu,hvarlist,nbvar,tzreclist,ibuflen,current_level)
+           CALL open_split_ncfile_in(infiles,hinfile,current_level)
+           CALL update_varid_in(infiles,hinfile,tzreclist,nbvar,current_level)
          END IF
-         CALL fill_ncdf(ilu,tzreclist,nbvar,ibuflen,cdffiles,current_level)
-         IF (current_level/=last_level) CALL close_split_lfifile(ilu)
+         CALL fill_ncdf(infiles,outfiles,tzreclist,nbvar,ibuflen,osplit,current_level)
+         IF (current_level/=last_level) CALL close_files(infiles)
        END DO
      END IF
 
   ELSE
      ! Conversion NetCDF -> LFI
-     CALL parse_cdf(cdffiles%cdf_id(1),tzreclist,ibuflen)
-     CALL build_lfi(cdffiles%cdf_id(1),ilu,tzreclist,ibuflen)
+     CALL parse_infiles(infiles,hvarlist,nbvar_infile,nbvar_tbr,nbvar_calc,nbvar_tbw,tzreclist,ibuflen,current_level)
+     CALL build_lfi(infiles,outfiles,tzreclist,ibuflen)
   END IF
   
-  CALL CLOSE_FILES(ilu,cdffiles,osplit)
+  CALL CLOSE_FILES(infiles)
+  CALL CLOSE_FILES(outfiles)
   
 end subroutine LFI2CDFMAIN
 
diff --git a/tools/lfi2cdf/src/mode_util.f90 b/tools/lfi2cdf/src/mode_util.f90
index 75058b8fd..31cab4c7e 100644
--- a/tools/lfi2cdf/src/mode_util.f90
+++ b/tools/lfi2cdf/src/mode_util.f90
@@ -8,13 +8,24 @@ MODULE mode_util
 
   INTEGER,PARAMETER :: MAXRAW=10
   INTEGER,PARAMETER :: MAXLEN=512
+  INTEGER,PARAMETER :: MAXFILES=100
 
-  TYPE cdf_files
-    INTEGER :: nbfiles
-    LOGICAL :: opened
-    INTEGER,DIMENSION(:),ALLOCATABLE :: cdf_id !ID of the netCDF file
-    INTEGER,DIMENSION(:),ALLOCATABLE :: var_id !position of the variable in the workfield structure
-  END TYPE cdf_files
+  INTEGER,PARAMETER :: UNDEFINED = -1, READING = 1, WRITING = 2
+  INTEGER,PARAMETER :: UNKNOWN_FORMAT = -1, NETCDF_FORMAT = 1, LFI_FORMAT = 2
+
+  TYPE filestruct
+    INTEGER :: lun_id                  ! Logical ID of file
+    INTEGER :: format = UNKNOWN_FORMAT ! NETCDF, LFI
+    INTEGER :: status = UNDEFINED      ! Opened for reading or writing
+    INTEGER :: var_id                  ! Position of the variable in the workfield structure
+    LOGICAL :: opened = .false.
+  END TYPE filestruct
+
+  TYPE filelist_struct
+    INTEGER :: nbfiles = 0
+!    TYPE(filestruct),DIMENSION(:),ALLOCATABLE :: files
+    TYPE(filestruct),DIMENSION(MAXFILES) :: files
+  END TYPE filelist_struct
 
 
   TYPE workfield
@@ -22,7 +33,7 @@ MODULE mode_util
      INTEGER                                 :: TYPE   ! type (entier ou reel)    
      CHARACTER(LEN=:), POINTER               :: comment
      TYPE(dimCDF),                   POINTER :: dim
-     INTEGER                                 :: id
+     INTEGER                                 :: id_in = -1, id_out = -1
      INTEGER                                 :: grid
      LOGICAL                                 :: found  ! T if found in the input file
      LOGICAL                                 :: calc   ! T if computed from other variables
@@ -82,18 +93,19 @@ CONTAINS
   END IF
   END SUBROUTINE FMREADLFIN1
 
-  SUBROUTINE parse_lfi(klu, hvarlist, nbvar_lfi, nbvar_tbr, nbvar_calc, nbvar_tbw, tpreclist, kbuflen, icurrent_level)
-    INTEGER, INTENT(IN)                    :: klu
-    INTEGER, INTENT(IN)                    :: nbvar_lfi, nbvar_tbr, nbvar_calc, nbvar_tbw
-    CHARACTER(LEN=*), intent(IN)           :: hvarlist
-    TYPE(workfield), DIMENSION(:), POINTER :: tpreclist    
-    INTEGER, INTENT(OUT)                   :: kbuflen
-    INTEGER, INTENT(IN), OPTIONAL          :: icurrent_level
+  SUBROUTINE parse_infiles(infiles, hvarlist, nbvar_infile, nbvar_tbr, nbvar_calc, nbvar_tbw, tpreclist, kbuflen, icurrent_level)
+    TYPE(filelist_struct),      INTENT(IN) :: infiles
+    INTEGER,                    INTENT(IN) :: nbvar_infile, nbvar_tbr, nbvar_calc, nbvar_tbw
+    CHARACTER(LEN=*),           INTENT(IN) :: hvarlist
+    TYPE(workfield), DIMENSION(:), POINTER :: tpreclist
+    INTEGER,                   INTENT(OUT) :: kbuflen
+    INTEGER,          INTENT(IN), OPTIONAL :: icurrent_level
 
-    INTEGER                                  :: ji,jj
+    INTEGER                                  :: ji,jj, kcdf_id, itype
     INTEGER                                  :: ndb, nde, ndey, idx, idx_var, maxvar
+    INTEGER                                  :: idims, idimtmp, jdim, status, var_id
     LOGICAL                                  :: ladvan
-    INTEGER                                  :: ich, current_level
+    INTEGER                                  :: ich, current_level, leng
     INTEGER                                  :: comment_size, fsize, sizemax
     CHARACTER(LEN=FM_FIELD_SIZE)             :: yrecfm
     CHARACTER(LEN=4)                         :: suffix
@@ -101,23 +113,45 @@ CONTAINS
     INTEGER(KIND=8),DIMENSION(:),ALLOCATABLE :: iwork
 #endif
     INTEGER(KIND=LFI_INT)                    :: iresp,ilu,ileng,ipos
+    CHARACTER(LEN=FM_FIELD_SIZE)             :: var_calc
+    CHARACTER(LEN=FM_FIELD_SIZE),dimension(MAXRAW) :: var_raw
+    INTEGER, DIMENSION(10)                   :: idim_id
     !JUAN CYCCL3
     INTEGER                        :: JPHEXT
 
-    ilu = klu
 
-    CALL FMREADLFIN1(klu,'JPHEXT',JPHEXT,iresp)
-    IF (iresp /= 0) JPHEXT=1
-    ! First check if IMAX,JMAX,KMAX exist in LFI file
-    ! to handle 3D, 2D variables -> update IDIMX,IDIMY,IDIMZ
-    CALL FMREADLFIN1(klu,'IMAX',IDIMX,iresp)
-    IF (iresp == 0) IDIMX = IDIMX+2*JPHEXT  ! IMAX + 2*JPHEXT
-    !
-    CALL FMREADLFIN1(klu,'JMAX',IDIMY,iresp)
-    IF (iresp == 0) IDIMY = IDIMY+2*JPHEXT  ! JMAX + 2*JPHEXT
-    !
-    CALL FMREADLFIN1(ilu,'KMAX',IDIMZ,iresp)
-    IF (iresp == 0) IDIMZ = IDIMZ+2  ! KMAX + 2*JPVEXT
+    IF (infiles%files(1)%format == LFI_FORMAT) THEN
+      ilu = infiles%files(1)%lun_id
+
+      CALL FMREADLFIN1(ilu,'JPHEXT',JPHEXT,iresp)
+      IF (iresp /= 0) JPHEXT=1
+
+      ! First check if IMAX,JMAX,KMAX exist in LFI file
+      ! to handle 3D, 2D variables -> update IDIMX,IDIMY,IDIMZ
+      CALL FMREADLFIN1(ilu,'IMAX',IDIMX,iresp)
+      IF (iresp == 0) IDIMX = IDIMX+2*JPHEXT  ! IMAX + 2*JPHEXT
+       !
+      CALL FMREADLFIN1(ilu,'JMAX',IDIMY,iresp)
+      IF (iresp == 0) IDIMY = IDIMY+2*JPHEXT  ! JMAX + 2*JPHEXT
+      !
+      CALL FMREADLFIN1(ilu,'KMAX',IDIMZ,iresp)
+      IF (iresp == 0) IDIMZ = IDIMZ+2  ! KMAX + 2*JPVEXT
+    ELSE IF (infiles%files(1)%format == NETCDF_FORMAT) THEN
+      kcdf_id = infiles%files(1)%lun_id
+
+      status = NF90_INQ_DIMID(kcdf_id, "DIMX", idim_id(1))
+      IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
+      status = NF90_INQUIRE_DIMENSION(kcdf_id,idim_id(1),len = IDIMX)
+
+      status = NF90_INQ_DIMID(kcdf_id, "DIMY", idim_id(2))
+      IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
+      status = NF90_INQUIRE_DIMENSION(kcdf_id,idim_id(2),len = IDIMY)
+
+      status = NF90_INQ_DIMID(kcdf_id, "DIMZ", idim_id(3))
+      IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
+      status = NF90_INQUIRE_DIMENSION(kcdf_id,idim_id(3),len = IDIMZ)
+    END IF
+
     GUSEDIM = (IDIMX*IDIMY > 0)
     IF (GUSEDIM) THEN
       PRINT *,'MESONH 3D, 2D articles DIMENSIONS used :'
@@ -143,11 +177,11 @@ CONTAINS
     !    Pour l'instant tous les articles du fichier LFI sont
     !    convertis. On peut modifier cette phase pour prendre en
     !    compte un sous-ensemble d'article (liste definie par
-    !    l'utilisateur par exemple)  
+    !    l'utilisateur par exemple)
     !
     IF (LEN_TRIM(hvarlist) > 0) THEN
 #ifndef LOWMEM
-      IF(.NOT.ALLOCATED(lfiart)) ALLOCATE(lfiart(nbvar_tbr+nbvar_calc))
+      IF(.NOT.ALLOCATED(lfiart) .AND. infiles%files(1)%format == LFI_FORMAT) ALLOCATE(lfiart(nbvar_tbr+nbvar_calc))
 #endif
       ALLOCATE(tpreclist(nbvar_tbr+nbvar_calc))
       DO ji=1,nbvar_tbr+nbvar_calc
@@ -214,22 +248,48 @@ CONTAINS
 
        DO ji=1,nbvar_tbr+nbvar_calc
           IF (tpreclist(ji)%calc) CYCLE
+
           yrecfm = TRIM(tpreclist(ji)%name)
-          CALL LFINFO(iresp,ilu,trim(yrecfm)//trim(suffix),ileng,ipos)
-          
-          IF (iresp /= 0 .OR. ileng == 0) THEN
+          IF (infiles%files(1)%format == LFI_FORMAT) THEN
+            CALL LFINFO(iresp,ilu,trim(yrecfm)//trim(suffix),ileng,ipos)
+            IF (iresp == 0 .AND. ileng /= 0) tpreclist(ji)%found = .true.
+            leng = ileng
+          ELSE IF (infiles%files(1)%format == NETCDF_FORMAT) THEN
+            status = NF90_INQ_VARID(kcdf_id,trim(yrecfm)//trim(suffix),tpreclist(ji)%id_in)
+            IF (status == NF90_NOERR) THEN
+              tpreclist(ji)%found = .true.
+              status = NF90_INQUIRE_VARIABLE(kcdf_id,tpreclist(ji)%id_in,ndims = idims,dimids = idim_id)
+              IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
+
+!TODO:useful?
+!DUPLICATED
+              IF (idims == 0) THEN
+                 ! variable scalaire
+                 leng = 1
+              ELSE
+                 ! infos sur dimensions
+                 leng = 1
+                 DO jdim=1,idims
+                   status = NF90_INQUIRE_DIMENSION(kcdf_id,idim_id(jdim),len = idimtmp)
+                   IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
+                   leng = leng*idimtmp
+                END DO
+              END IF
+            END IF
+          END IF
+
+          IF (.NOT.tpreclist(ji)%found) THEN
              PRINT *,'Article ',TRIM(yrecfm), ' not found!'
-             tpreclist(ji)%found = .FAlSE.
              tpreclist(ji)%tbw   = .FAlSE.
              tpreclist(ji)%tbr   = .FAlSE.
           ELSE
-             tpreclist(ji)%found = .TRUE.
              ! PRINT *,'Article ',ji,' : ',TRIM(yrecfm),', longueur = ',ileng
-             IF (ileng > sizemax) sizemax = ileng        
+             IF (leng > sizemax) sizemax = leng
 #ifndef LOWMEM
-             ALLOCATE(lfiart(ji)%iwtab(ileng))
+!TODO:useful for netcdf?
+             IF (infiles%files(1)%format == LFI_FORMAT) ALLOCATE(lfiart(ji)%iwtab(leng))
 #endif
-          end IF
+          END IF
        END DO
 
        maxvar = nbvar_tbr+nbvar_calc
@@ -242,29 +302,56 @@ END DO
     ELSE
        ! Entire file is converted
 #ifndef LOWMEM
-       IF(.NOT.ALLOCATED(lfiart)) ALLOCATE(lfiart(nbvar_lfi))
+       IF(.NOT.ALLOCATED(lfiart) .AND. infiles%files(1)%format == LFI_FORMAT) ALLOCATE(lfiart(nbvar_infile))
 #endif
-       ALLOCATE(tpreclist(nbvar_lfi))
-       DO ji=1,nbvar_lfi
+       ALLOCATE(tpreclist(nbvar_infile))
+       DO ji=1,nbvar_infile
          tpreclist(ji)%calc   = .FALSE. !By default variables are not computed from others
          tpreclist(ji)%tbw    = .TRUE.  !By default variables are written
          tpreclist(ji)%src(:) = -1
        END DO
 
-       CALL LFIPOS(iresp,ilu)
-       ladvan = .TRUE.
-       
-       DO ji=1,nbvar_lfi
-          CALL LFICAS(iresp,ilu,yrecfm,ileng,ipos,ladvan)
-          ! PRINT *,'Article ',ji,' : ',TRIM(yrecfm),', longueur = ',ileng
-          tpreclist(ji)%name = trim(yrecfm)
-          tpreclist(ji)%found  = .TRUE.
-          IF (ileng > sizemax) sizemax = ileng        
-#ifndef LOWMEM       
-          ALLOCATE(lfiart(ji)%iwtab(ileng))
+       IF (infiles%files(1)%format == LFI_FORMAT) THEN
+         CALL LFIPOS(iresp,ilu)
+         ladvan = .TRUE.
+
+         DO ji=1,nbvar_infile
+           CALL LFICAS(iresp,ilu,yrecfm,ileng,ipos,ladvan)
+           ! PRINT *,'Article ',ji,' : ',TRIM(yrecfm),', longueur = ',ileng
+           tpreclist(ji)%name = trim(yrecfm)
+           tpreclist(ji)%found  = .TRUE.
+           IF (ileng > sizemax) sizemax = ileng
+#ifndef LOWMEM
+           ALLOCATE(lfiart(ji)%iwtab(ileng))
 #endif
-       END DO
-       maxvar = nbvar_lfi
+         END DO
+       ELSE IF (infiles%files(1)%format == NETCDF_FORMAT) THEN
+         DO ji=1,nbvar_infile
+           tpreclist(ji)%id_in = ji
+           status = NF90_INQUIRE_VARIABLE(kcdf_id,tpreclist(ji)%id_in, name = tpreclist(ji)%name, ndims = idims, &
+                                          dimids = idim_id)
+           IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
+           ! PRINT *,'Article ',ji,' : ',TRIM(tpreclist(ji)%name),', longueur = ',ileng
+           tpreclist(ji)%found  = .TRUE.
+!TODO:useful?
+!DUPLICATED
+           IF (idims == 0) THEN
+             ! variable scalaire
+             leng = 1
+           ELSE
+             ! infos sur dimensions
+             leng = 1
+             DO jdim=1,idims
+               status = NF90_INQUIRE_DIMENSION(kcdf_id,idim_id(jdim),len = idimtmp)
+               IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
+               leng = leng*idimtmp
+             END DO
+           END IF
+           IF (leng > sizemax) sizemax = leng
+         END DO
+       END IF
+
+       maxvar = nbvar_infile
     END IF
 
     kbuflen = sizemax
@@ -273,37 +360,84 @@ END DO
     WRITE(*,'("Taille maximale du buffer :",f10.3," Mio")') sizemax*8./1048576.
     ALLOCATE(iwork(sizemax))
 #endif
-    
+
     ! Phase 2 : Extract comments and dimensions for valid articles.
     !           Infos are put in tpreclist.
     CALL init_dimCDF()
     DO ji=1,maxvar
        IF (tpreclist(ji)%calc .OR. .NOT.tpreclist(ji)%found) CYCLE
 
-       yrecfm = trim(tpreclist(ji)%name)//trim(suffix)
-       CALL LFINFO(iresp,ilu,yrecfm,ileng,ipos)
+       IF (infiles%files(1)%format == LFI_FORMAT) THEN
+         yrecfm = trim(tpreclist(ji)%name)//trim(suffix)
+         CALL LFINFO(iresp,ilu,yrecfm,ileng,ipos)
 #ifdef LOWMEM
-       CALL LFILEC(iresp,ilu,yrecfm,iwork,ileng)
-       tpreclist(ji)%grid = iwork(1)
-       comment_size = iwork(2)
+         CALL LFILEC(iresp,ilu,yrecfm,iwork,ileng)
+         tpreclist(ji)%grid = iwork(1)
+         comment_size = iwork(2)
 #else
-       CALL LFILEC(iresp,ilu,yrecfm,lfiart(ji)%iwtab,ileng)
-       tpreclist(ji)%grid = lfiart(ji)%iwtab(1)
-       comment_size = lfiart(ji)%iwtab(2)
+         CALL LFILEC(iresp,ilu,yrecfm,lfiart(ji)%iwtab,ileng)
+         tpreclist(ji)%grid = lfiart(ji)%iwtab(1)
+         comment_size = lfiart(ji)%iwtab(2)
 #endif
-       tpreclist(ji)%TYPE = get_ftype(yrecfm,current_level)
+         tpreclist(ji)%TYPE = get_ftype(yrecfm,current_level)
 
-       ALLOCATE(character(len=comment_size) :: tpreclist(ji)%comment)
-       DO jj=1,comment_size
+         ALLOCATE(character(len=comment_size) :: tpreclist(ji)%comment)
+         DO jj=1,comment_size
 #ifdef LOWMEM
-          ich = iwork(2+jj)
+           ich = iwork(2+jj)
 #else
-          ich = lfiart(ji)%iwtab(2+jj)
+           ich = lfiart(ji)%iwtab(2+jj)
 #endif
-          tpreclist(ji)%comment(jj:jj) = CHAR(ich)
-       END DO
+           tpreclist(ji)%comment(jj:jj) = CHAR(ich)
+         END DO
+
+         fsize = ileng-(2+comment_size)
+
+       ELSE IF (infiles%files(1)%format == NETCDF_FORMAT) THEN
+         ! GRID attribute definition
+         status = NF90_GET_ATT(kcdf_id,tpreclist(ji)%id_in,'GRID',tpreclist(ji)%grid)
+         IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
+
+         ! COMMENT attribute definition
+         status = NF90_INQUIRE_ATTRIBUTE(kcdf_id,tpreclist(ji)%id_in,'COMMENT',len=comment_size)
+         IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
+         ALLOCATE(character(len=comment_size) :: tpreclist(ji)%comment)
+         status = NF90_GET_ATT(kcdf_id,tpreclist(ji)%id_in,'COMMENT',tpreclist(ji)%comment)
+         IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
+
+         status = NF90_INQUIRE_VARIABLE(kcdf_id,tpreclist(ji)%id_in, xtype = itype, ndims = idims, &
+                                        dimids = idim_id)
+         IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
+
+         SELECT CASE(itype)
+         CASE(NF90_CHAR)
+           tpreclist(ji)%TYPE = TEXT
+         CASE(NF90_INT)
+           tpreclist(ji)%TYPE = INT
+         CASE(NF90_FLOAT,NF90_DOUBLE)
+           tpreclist(ji)%TYPE = FLOAT
+         CASE default
+           PRINT *, 'Attention : variable ',TRIM(tpreclist(ji)%name), ' a un TYPE non reconnu par le convertisseur.'
+           PRINT *, '--> TYPE force a REAL(KIND 8) dans LFI !'
+         END SELECT
+
+!DUPLICATED
+         IF (idims == 0) THEN
+           ! variable scalaire
+           leng = 1
+         ELSE
+           ! infos sur dimensions
+           leng = 1
+           DO jdim=1,idims
+             status = NF90_INQUIRE_DIMENSION(kcdf_id,idim_id(jdim),len = idimtmp)
+             IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
+             leng = leng*idimtmp
+           END DO
+         END IF
+
+         fsize = leng
+       END IF
 
-       fsize = ileng-(2+comment_size)
        tpreclist(ji)%dim=>get_dimCDF(fsize)
     END DO
 
@@ -329,15 +463,15 @@ END DO
     END DO
     END IF
 
-  
+
     PRINT *,'Nombre de dimensions = ', size_dimCDF()
 #ifdef LOWMEM
     DEALLOCATE(iwork)
 #endif
-  END SUBROUTINE parse_lfi
+  END SUBROUTINE parse_infiles
   
-  SUBROUTINE read_data_lfi(klu, hvarlist, nbvar, tpreclist, kbuflen, current_level)
-    INTEGER, INTENT(IN)                    :: klu
+  SUBROUTINE read_data_lfi(infiles, hvarlist, nbvar, tpreclist, kbuflen, current_level)
+    TYPE(filelist_struct),      INTENT(IN) :: infiles
     INTEGER, INTENT(INOUT)                 :: nbvar
     CHARACTER(LEN=*), intent(IN)           :: hvarlist
     TYPE(workfield), DIMENSION(:), POINTER :: tpreclist
@@ -358,7 +492,8 @@ END DO
     CHARACTER(LEN=FM_FIELD_SIZE)             :: var_calc
     CHARACTER(LEN=FM_FIELD_SIZE),dimension(MAXRAW) :: var_raw
 
-    ilu = klu
+
+    ilu = infiles%files(1)%lun_id
 
     IF (present(current_level)) THEN
       write(suffix,'(I4.4)') current_level
@@ -393,16 +528,17 @@ END DO
 
     IF (status /= NF90_NOERR) THEN
        PRINT *, 'line ',line,': ',NF90_STRERROR(status)
-       STOP
+           STOP
     END IF
   END SUBROUTINE HANDLE_ERR
 
-  SUBROUTINE def_ncdf(tpreclist,nbvar,oreduceprecision,cdffiles,omerge,ocompress,compress_level)
+  SUBROUTINE def_ncdf(outfiles,tpreclist,nbvar,oreduceprecision,omerge,osplit,ocompress,compress_level)
+    TYPE(filelist_struct),       INTENT(IN) :: outfiles
     TYPE(workfield),DIMENSION(:),INTENT(INOUT) :: tpreclist
     INTEGER,                     INTENT(IN) :: nbvar
     LOGICAL,                     INTENT(IN) :: oreduceprecision
-    TYPE(cdf_files),             INTENT(IN) :: cdffiles
     LOGICAL,                     INTENT(IN) :: omerge
+    LOGICAl,                     INTENT(IN) :: osplit
     LOGICAL,                     INTENT(IN) :: ocompress
     INTEGER,                     INTENT(IN) :: compress_level
 
@@ -416,7 +552,7 @@ END DO
     CHARACTER(LEN=20)     :: ycdfvar
 
 
-    nbfiles = cdffiles%nbfiles
+    nbfiles = outfiles%nbfiles
 
     IF (oreduceprecision) THEN
       type_float = NF90_REAL
@@ -425,7 +561,7 @@ END DO
     END IF
 
     DO ji = 1,nbfiles
-      kcdf_id = cdffiles%cdf_id(ji)
+      kcdf_id = outfiles%files(ji)%lun_id
 
       ! global attributes
       status = NF90_PUT_ATT(kcdf_id,NF90_GLOBAL,'Title',VERSION_ID)
@@ -487,25 +623,25 @@ END DO
        !! ni les '.' remplaces par '--'
        ycdfvar = str_replace(ycdfvar,'.','--')
 
-       if (nbfiles > 1) kcdf_id = cdffiles%cdf_id(idx)
+       kcdf_id = outfiles%files(idx)%lun_id
 
        SELECT CASE(tpreclist(ji)%TYPE)
        CASE (TEXT)
 !          PRINT *,'TEXT : ',tpreclist(ji)%name
           status = NF90_DEF_VAR(kcdf_id,ycdfvar,NF90_CHAR,&
-                   ivdims(:invdims),tpreclist(ji)%id)
+                   ivdims(:invdims),tpreclist(ji)%id_out)
           IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
 
        CASE (INT,BOOL)
 !          PRINT *,'INT,BOOL : ',tpreclist(ji)%name
           status = NF90_DEF_VAR(kcdf_id,ycdfvar,NF90_INT,&
-                   ivdims(:invdims),tpreclist(ji)%id)
+                   ivdims(:invdims),tpreclist(ji)%id_out)
           IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
 
        CASE(FLOAT)
 !          PRINT *,'FLOAT : ',tpreclist(ji)%name
           status = NF90_DEF_VAR(kcdf_id,ycdfvar,type_float,&
-                   ivdims(:invdims),tpreclist(ji)%id)
+                   ivdims(:invdims),tpreclist(ji)%id_out)
           IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
 
           
@@ -513,7 +649,7 @@ END DO
           PRINT *,'ATTENTION : ',TRIM(tpreclist(ji)%name),' est de&
                & TYPE inconnu --> force a REAL'
           status = NF90_DEF_VAR(kcdf_id,ycdfvar,type_float,&
-                   ivdims(:invdims),tpreclist(ji)%id)
+                   ivdims(:invdims),tpreclist(ji)%id_out)
           IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
           
 
@@ -521,35 +657,35 @@ END DO
 
        ! Compress data (costly operation for the CPU)
        IF (ocompress .AND. invdims>0) THEN
-         status = NF90_DEF_VAR_DEFLATE(kcdf_id,tpreclist(ji)%id,1,1,compress_level)
+         status = NF90_DEF_VAR_DEFLATE(kcdf_id,tpreclist(ji)%id_out,1,1,compress_level)
          IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
        END IF
 
        ! GRID attribute definition
-       status = NF90_PUT_ATT(kcdf_id,tpreclist(ji)%id,'GRID',tpreclist(ji)%grid)
+       status = NF90_PUT_ATT(kcdf_id,tpreclist(ji)%id_out,'GRID',tpreclist(ji)%grid)
        IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
 
        ! COMMENT attribute definition
-       status = NF90_PUT_ATT(kcdf_id,tpreclist(ji)%id,'COMMENT',trim(tpreclist(ji)%comment))
+       status = NF90_PUT_ATT(kcdf_id,tpreclist(ji)%id_out,'COMMENT',trim(tpreclist(ji)%comment))
        IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
 
-       idx = idx + 1
+       IF (osplit) idx = idx + 1
     END DO
     
     DO ji = 1,nbfiles
-      kcdf_id = cdffiles%cdf_id(ji)
+      kcdf_id = outfiles%files(ji)%lun_id
       status = NF90_ENDDEF(kcdf_id)
       IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
     END DO
-    
+
   END SUBROUTINE def_ncdf
 
-  SUBROUTINE fill_ncdf(klu,tpreclist,knaf,kbuflen,cdffiles,current_level)
-    INTEGER,                      INTENT(IN):: klu
+  SUBROUTINE fill_ncdf(infiles,outfiles,tpreclist,knaf,kbuflen,osplit,current_level)
+    TYPE(filelist_struct),        INTENT(IN):: infiles, outfiles
     TYPE(workfield), DIMENSION(:),INTENT(IN):: tpreclist
     INTEGER,                      INTENT(IN):: knaf
     INTEGER,                      INTENT(IN):: kbuflen
-    TYPE(cdf_files),              INTENT(IN):: cdffiles
+    LOGICAl,                      INTENT(IN):: osplit
     INTEGER, INTENT(IN), OPTIONAL           :: current_level
 
 #ifdef LOWMEM
@@ -564,14 +700,16 @@ END DO
     INTEGER                                  :: level
     INTEGER(KIND=LFI_INT)                    :: iresp,ilu,ileng,ipos
     CHARACTER(LEN=4)                         :: suffix
+    INTEGER,DIMENSION(3)                     :: idims, start
     INTEGER,DIMENSION(:),ALLOCATABLE         :: itab
     REAL(KIND=8),DIMENSION(:),ALLOCATABLE    :: xtab
     CHARACTER, DIMENSION(:), ALLOCATABLE     :: ytab
+    REAL(KIND=8), DIMENSION(:,:,:), ALLOCATABLE :: xtab3d, xtab3d2
+    INTEGER,      DIMENSION(:,:,:), ALLOCATABLE :: itab3d, itab3d2
 
 
-    kcdf_id = cdffiles%cdf_id(1)
     !
-    ilu = klu
+    IF (infiles%files(1)%format == LFI_FORMAT) ilu = infiles%files(1)%lun_id
     !
 
     IF (present(current_level)) THEN
@@ -592,7 +730,7 @@ END DO
     DO ji=1,knaf
        IF (.NOT.tpreclist(ji)%tbw) CYCLE
 
-       IF (cdffiles%nbfiles > 1) kcdf_id = cdffiles%cdf_id(idx)
+       kcdf_id = outfiles%files(idx)%lun_id
 
        IF (ASSOCIATED(tpreclist(ji)%dim)) THEN
           extent = tpreclist(ji)%dim%len
@@ -602,8 +740,18 @@ END DO
           ndims = 0
        END IF
 
+       idims(:) = 1
+       if(ndims>0) idims(1) = ptdimx%len
+       if(ndims>1) idims(2) = ptdimy%len
+       if(ndims>2) idims(3) = ptdimz%len
+       if(ndims>3) then
+         PRINT *,'Too many dimensions'
+         STOP
+       endif
+
        SELECT CASE(tpreclist(ji)%TYPE)
        CASE (INT,BOOL)
+        IF (infiles%files(1)%format == LFI_FORMAT) THEN
 #if LOWMEM
          IF (.NOT.tpreclist(ji)%calc) THEN
            CALL LFINFO(iresp,ilu,trim(tpreclist(ji)%name)//trim(suffix),ileng,ipos)
@@ -636,22 +784,58 @@ END DO
            END DO
          END IF
 #endif
+
 !TODO: works in all cases??? (X, Y, Z dimensions assumed to be ptdimx,y or z)
          SELECT CASE(ndims)
          CASE (0)
-           status = NF90_PUT_VAR(kcdf_id,tpreclist(ji)%id,itab(1))
+           status = NF90_PUT_VAR(kcdf_id,tpreclist(ji)%id_out,itab(1))
          CASE (1)
-           status = NF90_PUT_VAR(kcdf_id,tpreclist(ji)%id,itab(1:extent),count=(/extent/))
+           status = NF90_PUT_VAR(kcdf_id,tpreclist(ji)%id_out,itab(1:extent),count=(/extent/))
          CASE (2)
-           status = NF90_PUT_VAR(kcdf_id,tpreclist(ji)%id,reshape(itab,(/ptdimx%len,ptdimy%len/)), &
+           status = NF90_PUT_VAR(kcdf_id,tpreclist(ji)%id_out,reshape(itab,(/ptdimx%len,ptdimy%len/)), &
                                  start = (/1,1,level/) )
          CASE (3)
-           status = NF90_PUT_VAR(kcdf_id,tpreclist(ji)%id,reshape(itab,(/ptdimx%len,ptdimy%len,ptdimz%len/)))
+           status = NF90_PUT_VAR(kcdf_id,tpreclist(ji)%id_out,reshape(itab,(/ptdimx%len,ptdimy%len,ptdimz%len/)))
          CASE DEFAULT
            print *,'Error: arrays with ',tpreclist(ji)%dim%ndims,' dimensions are not supported'
          END SELECT
+
+        ELSE IF (infiles%files(1)%format == NETCDF_FORMAT) THEN
+         ALLOCATE( itab3d(idims(1),idims(2),idims(3)) )
+         IF (.NOT.tpreclist(ji)%calc) THEN
+           status = NF90_GET_VAR(infiles%files(1)%lun_id,tpreclist(ji)%id_in,itab3d)
+           IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
+         ELSE
+           ALLOCATE( itab3d2(idims(1),idims(2),idims(3)) )
+           src=tpreclist(ji)%src(1)
+           status = NF90_GET_VAR(infiles%files(1)%lun_id,tpreclist(src)%id_in,itab3d)
+           IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
+           jj = 2
+           DO WHILE (tpreclist(ji)%src(jj)>0 .AND. jj.LE.MAXRAW)
+             src=tpreclist(ji)%src(jj)
+             status = NF90_GET_VAR(infiles%files(1)%lun_id,tpreclist(src)%id_in,itab3d2)
+             IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
+             itab3d(:,:,:) = itab3d(:,:,:) + itab3d2(:,:,:)
+             jj=jj+1
+           END DO
+           DEALLOCATE(itab3d2)
+         END IF
+
+!TODO: not clean, should be done only if merging z-levels
+         IF (ndims == 2) THEN
+           start = (/1,1,level/)
+         ELSE
+           start = (/1,1,1/)
+         ENDIF
+         status = NF90_PUT_VAR(kcdf_id,tpreclist(ji)%id_out,itab3d,start=start)
+         IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
+
+         DEALLOCATE(itab3d)
+        END IF
+
          
        CASE (FLOAT)
+        IF (infiles%files(1)%format == LFI_FORMAT) THEN
 #if LOWMEM
          IF (.NOT.tpreclist(ji)%calc) THEN
            CALL LFINFO(iresp,ilu,trim(tpreclist(ji)%name)//trim(suffix),ileng,ipos)
@@ -687,19 +871,53 @@ END DO
 !TODO: works in all cases??? (X, Y, Z dimensions assumed to be ptdimx,y or z)
          SELECT CASE(ndims)
          CASE (0)
-           status = NF90_PUT_VAR(kcdf_id,tpreclist(ji)%id,xtab(1))
+           status = NF90_PUT_VAR(kcdf_id,tpreclist(ji)%id_out,xtab(1))
          CASE (1)
-           status = NF90_PUT_VAR(kcdf_id,tpreclist(ji)%id,xtab(1:extent),count=(/extent/))
+           status = NF90_PUT_VAR(kcdf_id,tpreclist(ji)%id_out,xtab(1:extent),count=(/extent/))
          CASE (2)
-           status = NF90_PUT_VAR(kcdf_id,tpreclist(ji)%id,reshape(xtab,(/ptdimx%len,ptdimy%len/)), &
+           status = NF90_PUT_VAR(kcdf_id,tpreclist(ji)%id_out,reshape(xtab,(/ptdimx%len,ptdimy%len/)), &
                                  start = (/1,1,level/) )
          CASE (3)
-           status = NF90_PUT_VAR(kcdf_id,tpreclist(ji)%id,reshape(xtab,(/ptdimx%len,ptdimy%len,ptdimz%len/)))
+           status = NF90_PUT_VAR(kcdf_id,tpreclist(ji)%id_out,reshape(xtab,(/ptdimx%len,ptdimy%len,ptdimz%len/)))
          CASE DEFAULT
            print *,'Error: arrays with ',tpreclist(ji)%dim%ndims,' dimensions are not supported'
          END SELECT
 
+        ELSE IF (infiles%files(1)%format == NETCDF_FORMAT) THEN
+         ALLOCATE( xtab3d(idims(1),idims(2),idims(3)) )
+         IF (.NOT.tpreclist(ji)%calc) THEN
+           status = NF90_GET_VAR(infiles%files(1)%lun_id,tpreclist(ji)%id_in,xtab3d)
+           IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
+         ELSE
+           ALLOCATE( xtab3d2(idims(1),idims(2),idims(3)) )
+           src=tpreclist(ji)%src(1)
+           status = NF90_GET_VAR(infiles%files(1)%lun_id,tpreclist(src)%id_in,xtab3d)
+           IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
+           jj = 2
+           DO WHILE (tpreclist(ji)%src(jj)>0 .AND. jj.LE.MAXRAW)
+             src=tpreclist(ji)%src(jj)
+             status = NF90_GET_VAR(infiles%files(1)%lun_id,tpreclist(src)%id_in,xtab3d2)
+             IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
+             xtab3d(:,:,:) = xtab3d(:,:,:) + xtab3d2(:,:,:)
+             jj=jj+1
+           END DO
+           DEALLOCATE(xtab3d2)
+         END IF
+
+!TODO: not clean, should be done only if merging z-levels
+         IF (ndims == 2) THEN
+           start = (/1,1,level/)
+         ELSE
+           start = (/1,1,1/)
+         ENDIF
+         status = NF90_PUT_VAR(kcdf_id,tpreclist(ji)%id_out,xtab3d,start=start)
+         IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
+
+         DEALLOCATE(xtab3d)
+        END IF
+
        CASE (TEXT)
+        IF (infiles%files(1)%format == LFI_FORMAT) THEN
          ALLOCATE(ytab(extent))
          DO jj=1,extent
 #if LOWMEM
@@ -709,11 +927,19 @@ END DO
 #endif
            ytab(jj) = CHAR(ich)
          END DO
-         status = NF90_PUT_VAR(kcdf_id,tpreclist(ji)%id,ytab,count=(/extent/))
+         status = NF90_PUT_VAR(kcdf_id,tpreclist(ji)%id_out,ytab,count=(/extent/))
          IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
          DEALLOCATE(ytab)
+        ELSE IF (infiles%files(1)%format == NETCDF_FORMAT) THEN
+         status = NF90_GET_VAR(infiles%files(1)%lun_id,tpreclist(ji)%id_in,ytab,count=(/extent/))
+         IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
+
+         status = NF90_PUT_VAR(kcdf_id,tpreclist(ji)%id_out,ytab,count=(/extent/))
+         IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
+        END IF
 
        CASE default
+        IF (infiles%files(1)%format == LFI_FORMAT) THEN
 #if LOWMEM
          IF (.NOT.tpreclist(ji)%calc) THEN
            CALL LFINFO(iresp,ilu,trim(tpreclist(ji)%name)//trim(suffix),ileng,ipos)
@@ -727,7 +953,7 @@ END DO
            jj = 2
            DO WHILE (tpreclist(ji)%src(jj)>0 .AND. jj.LE.MAXRAW)
              src=tpreclist(ji)%src(jj)
-             CALL LFINFO(iresp,ilu,trim(tpreclist(src)%name)//trim(suffix),ileng,ipos)
+             CALL LFILEC(iresp,ilu,trim(tpreclist(src)%name)//trim(suffix),iwork,ileng)
              xtab(1:extent) = xtab(1:extent) + TRANSFER(iwork(3+iwork(2):),(/ 0.0_8 /))
              jj=jj+1
            END DO
@@ -749,22 +975,26 @@ END DO
 !TODO: works in all cases??? (X, Y, Z dimensions assumed to be ptdimx,y or z)
          SELECT CASE(ndims)
          CASE (0)
-           status = NF90_PUT_VAR(kcdf_id,tpreclist(ji)%id,xtab(1))
+           status = NF90_PUT_VAR(kcdf_id,tpreclist(ji)%id_out,xtab(1))
          CASE (1)
-           status = NF90_PUT_VAR(kcdf_id,tpreclist(ji)%id,xtab(1:extent),count=(/extent/))
+           status = NF90_PUT_VAR(kcdf_id,tpreclist(ji)%id_out,xtab(1:extent),count=(/extent/))
          CASE (2)
-           status = NF90_PUT_VAR(kcdf_id,tpreclist(ji)%id,reshape(xtab,(/ptdimx%len,ptdimy%len/)), &
+           status = NF90_PUT_VAR(kcdf_id,tpreclist(ji)%id_out,reshape(xtab,(/ptdimx%len,ptdimy%len/)), &
                                  start = (/1,1,level/) )
          CASE (3)
-           status = NF90_PUT_VAR(kcdf_id,tpreclist(ji)%id,reshape(xtab,(/ptdimx%len,ptdimy%len,ptdimz%len/)))
+           status = NF90_PUT_VAR(kcdf_id,tpreclist(ji)%id_out,reshape(xtab,(/ptdimx%len,ptdimy%len,ptdimz%len/)))
          CASE DEFAULT
            print *,'Error: arrays with ',tpreclist(ji)%dim%ndims,' dimensions are not supported'
          END SELECT
          IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
+        ELSE IF (infiles%files(1)%format == NETCDF_FORMAT) THEN
+         print *,'Error: unknown datatype'
+         STOP
+        END IF
 
        END SELECT
 
-       idx = idx + 1
+       if (osplit) idx = idx + 1
     END DO
     DEALLOCATE(itab,xtab)
 #if LOWMEM
@@ -772,112 +1002,13 @@ END DO
 #endif 
   END SUBROUTINE fill_ncdf
 
-  SUBROUTINE parse_cdf(kcdf_id,tpreclist,kbuflen)
-    INTEGER, INTENT(IN)                    :: kcdf_id
-    TYPE(workfield), DIMENSION(:), POINTER :: tpreclist
-    INTEGER, INTENT(OUT)                   :: kbuflen
-
-
-    INTEGER :: status
-    INTEGER :: nvars, var_id
-    INTEGER :: jdim
-    INTEGER :: sizemax
-    INTEGER :: itype
-    INTEGER, DIMENSION(10) :: idim_id
-    INTEGER :: icomlen,idimlen,idims,idimtmp
-    
-    status = NF90_INQUIRE(kcdf_id, nvariables = nvars)
-    IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
-    ALLOCATE(tpreclist(nvars))
-
-    sizemax = 0
-
-    status = NF90_INQ_DIMID(kcdf_id, "DIMX", idim_id(1))
-    IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
-    status = NF90_INQUIRE_DIMENSION(kcdf_id,idim_id(1),len = IDIMX)
-
-    status = NF90_INQ_DIMID(kcdf_id, "DIMY", idim_id(2))
-    IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
-    status = NF90_INQUIRE_DIMENSION(kcdf_id,idim_id(2),len = IDIMY)
-
-    status = NF90_INQ_DIMID(kcdf_id, "DIMZ", idim_id(3))
-    IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
-    status = NF90_INQUIRE_DIMENSION(kcdf_id,idim_id(3),len = IDIMZ)
-
-    GUSEDIM = (IDIMX*IDIMY > 0)
-
-    CALL init_dimCDF()
-    
-    ! Parcours de toutes les variables et extraction des infos
-    !      - nom de dimension
-    !      - dimension, etendue
-    !      - attributs
-    DO var_id = 1, nvars
-       ! Pour la forme
-       tpreclist(var_id)%id = var_id  
-       
-       ! Nom, type et dimensions de la variable
-       status = NF90_INQUIRE_VARIABLE(kcdf_id, var_id, name = tpreclist(var_id)%name, xtype = itype, ndims = idims, &
-                                      dimids = idim_id)
-       IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
-       
-       SELECT CASE(itype)
-       CASE(NF90_CHAR)
-          tpreclist(var_id)%TYPE = TEXT
-       CASE(NF90_INT)
-          tpreclist(var_id)%TYPE = INT
-       CASE(NF90_FLOAT,NF90_DOUBLE)
-          tpreclist(var_id)%TYPE = FLOAT
-       CASE default 
-          PRINT *, 'Attention : variable ',TRIM(tpreclist(var_id)&
-               & %name), ' a un TYPE non reconnu par le convertisseur.'
-          PRINT *, '--> TYPE force a REAL(KIND 8) dans LFI !'
-       END SELECT
-      
-       IF (idims == 0) THEN
-          ! variable scalaire
-          NULLIFY(tpreclist(var_id)%dim)
-          idimlen = 1
-       ELSE
-          ! infos sur dimensions
-          idimlen = 1
-          DO jdim=1,idims
-            status = NF90_INQUIRE_DIMENSION(kcdf_id,idim_id(jdim),len = idimtmp)
-            IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
-            idimlen = idimlen*idimtmp
-          END DO
-          tpreclist(var_id)%dim=>get_dimCDF(idimlen)
-          tpreclist(var_id)%dim%ndims=idims
-       END IF
-       
-       ! GRID et COMMENT attributes
-       status = NF90_GET_ATT(kcdf_id,var_id,'GRID',tpreclist(var_id)%grid)
-       IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
-
-       status = NF90_INQUIRE_ATTRIBUTE(kcdf_id,var_id,'COMMENT',len = icomlen)
-       IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
-       
-       ALLOCATE(character(len=icomlen) :: tpreclist(var_id)%comment)
-       status = NF90_GET_ATT(kcdf_id,var_id,'COMMENT',tpreclist(var_id)%comment)
-       IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
-
-       
-       IF (sizemax < icomlen+idimlen) sizemax = icomlen+idimlen 
-
-    END DO
-    
-    kbuflen = sizemax
-
-  END SUBROUTINE parse_cdf
-
-  SUBROUTINE build_lfi(kcdf_id,klu,tpreclist,kbuflen)
-    INTEGER,                       INTENT(IN) :: kcdf_id 
-    INTEGER,                       INTENT(IN) :: klu
+  SUBROUTINE build_lfi(infiles,outfiles,tpreclist,kbuflen)
+    TYPE(filelist_struct),         INTENT(IN) :: infiles, outfiles
     TYPE(workfield), DIMENSION(:), INTENT(IN) :: tpreclist
     INTEGER,                       INTENT(IN) :: kbuflen
     
-    INTEGER :: status
-    INTEGER :: ivar,jj,ndims
+    INTEGER :: kcdf_id, status
+    INTEGER :: ivar,ji,jj,ndims
     INTEGER,DIMENSION(3) :: idims
     INTEGER(KIND=8), DIMENSION(:), POINTER  :: iwork
     INTEGER(KIND=8), DIMENSION(:), POINTER  :: idata
@@ -889,6 +1020,10 @@ END DO
     INTEGER :: iartlen, idlen, icomlen
     INTEGER(KIND=LFI_INT) :: iresp,ilu,iartlen8
 
+
+    ilu = outfiles%files(1)%lun_id
+    kcdf_id = infiles%files(1)%lun_id
+
     ! Un article LFI est compose de :
     !   - 1 entier identifiant le numero de grille
     !   - 1 entier contenant la taille du commentaire
@@ -933,7 +1068,7 @@ END DO
        SELECT CASE(tpreclist(ivar)%TYPE)
        CASE(INT,BOOL)
           ALLOCATE( itab3d(idims(1),idims(2),idims(3)) )
-          status = NF90_GET_VAR(kcdf_id,tpreclist(ivar)%id,itab3d)
+          status = NF90_GET_VAR(kcdf_id,tpreclist(ivar)%id_in,itab3d)
           IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
 
 !          PRINT *,'INT,BOOL --> ',tpreclist(ivar)%name,',len = ',idlen
@@ -943,7 +1078,7 @@ END DO
 
        CASE(FLOAT)
           ALLOCATE( xtab3d(idims(1),idims(2),idims(3)) )
-          status = NF90_GET_VAR(kcdf_id,tpreclist(ivar)%id,xtab3d)
+          status = NF90_GET_VAR(kcdf_id,tpreclist(ivar)%id_in,xtab3d)
           IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
 
 !          PRINT *,'FLOAT -->    ',tpreclist(ivar)%name,',len = ',idlen
@@ -953,7 +1088,7 @@ END DO
 
        CASE(TEXT)
           ALLOCATE(ytab(idlen))
-          status = NF90_GET_VAR(kcdf_id,tpreclist(ivar)%id,ytab)
+          status = NF90_GET_VAR(kcdf_id,tpreclist(ivar)%id_in,ytab)
           IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
 
 !          PRINT *,'TEXT -->     ',tpreclist(ivar)%name,',len = ',idlen
@@ -965,7 +1100,7 @@ END DO
 
        CASE default
           ALLOCATE( xtab3d(idims(1),idims(2),idims(3)) )
-          status = NF90_GET_VAR(kcdf_id,tpreclist(ivar)%id,xtab3d)
+          status = NF90_GET_VAR(kcdf_id,tpreclist(ivar)%id_in,xtab3d)
           IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
 
           PRINT *,'Default (ERROR) -->',tpreclist(ivar)%name,',len = ',idlen
@@ -979,7 +1114,6 @@ END DO
        yrecfm = str_replace(tpreclist(ivar)%name,'__','%')
        ! et des '.'
        yrecfm = str_replace(yrecfm,'--','.')
-       ilu = klu
        iartlen8 = iartlen
        CALL LFIECR(iresp,ilu,yrecfm,iwork,iartlen8)
 
@@ -988,50 +1122,87 @@ END DO
 
   END SUBROUTINE build_lfi
 
-  SUBROUTINE OPEN_FILES(hinfile,houtfile,olfi2cdf,olfilist,ohdf5,cdffiles,klu,knaf,osplit)
-    LOGICAL,          INTENT(IN)  :: olfi2cdf, olfilist, ohdf5, osplit
+  SUBROUTINE UPDATE_VARID_IN(infiles,hinfile,tpreclist,nbvar,current_level)
+    !Update the id_in for netCDF files (could change from one file to the other)
+    TYPE(filelist_struct),         INTENT(IN)    :: infiles
+    CHARACTER(LEN=*),              INTENT(IN)    :: hinfile
+    TYPE(workfield), DIMENSION(:), INTENT(INOUT) :: tpreclist
+    INTEGER,                       INTENT(IN)    :: nbvar
+    INTEGER,                       INTENT(IN)    :: current_level
+
+    INTEGER :: ji, status
+    CHARACTER(len=4) :: suffix
+
+
+    if (infiles%files(1)%format /= NETCDF_FORMAT) return
+
+    write(suffix,'(I4.4)') current_level
+
+    DO ji=1,nbvar
+      IF (.NOT.tpreclist(ji)%tbr) CYCLE
+      status = NF90_INQ_VARID(infiles%files(1)%lun_id,trim(tpreclist(ji)%name)//trim(suffix),tpreclist(ji)%id_in)
+      IF (status /= NF90_NOERR .AND. tpreclist(ji)%found) THEN
+        tpreclist(ji)%found=.false.
+        tpreclist(ji)%tbr=.false.
+        tpreclist(ji)%tbw=.false.
+        print *,'Error: variable ',trim(tpreclist(ji)%name),' not found anymore in split file'
+      END IF
+    END DO
+  END SUBROUTINE UPDATE_VARID_IN
+
+  SUBROUTINE OPEN_FILES(infiles,outfiles,hinfile,houtfile,ocdf2cdf,olfi2cdf,olfilist,ohdf5,nbvar_infile,osplit)
+    TYPE(filelist_struct),INTENT(OUT) :: infiles, outfiles
+    LOGICAL,          INTENT(IN)  :: ocdf2cdf, olfi2cdf, olfilist, ohdf5, osplit
     CHARACTER(LEN=*), INTENT(IN)  :: hinfile
     CHARACTER(LEN=*), INTENT(IN)  :: houtfile
-    TYPE(cdf_files) , INTENT(OUT) :: cdffiles
-    INTEGER         , INTENT(OUT) :: klu,knaf
+    INTEGER         , INTENT(OUT) :: nbvar_infile
 
     INTEGER                     :: extindex
-    INTEGER(KIND=LFI_INT)       :: ilu,iresp,iverb,inap,inaf
-    INTEGER                     :: status
+    INTEGER(KIND=LFI_INT)       :: iresp,iverb,inap,inaf
+    INTEGER                     :: idx,status
     CHARACTER(LEN=4)            :: ypextsrc, ypextdest
     LOGICAL                     :: fexist
     INTEGER                     :: omode
 
     iverb = 0
-    ilu   = 11
 
     CALL init_sysfield()
 
     IF (olfi2cdf) THEN 
        ! Cas LFI -> NetCDF
-       CALL LFIOUV(iresp,ilu,ltrue,hinfile,'OLD',lfalse&
+       infiles%nbfiles = infiles%nbfiles + 1
+       idx = infiles%nbfiles
+       infiles%files(idx)%lun_id = 11
+       infiles%files(idx)%format = LFI_FORMAT
+       infiles%files(idx)%status = READING
+       CALL LFIOUV(iresp,infiles%files(idx)%lun_id,ltrue,hinfile,'OLD',lfalse&
             & ,lfalse,iverb,inap,inaf)
+       infiles%files(idx)%opened  = .TRUE.
+
+       nbvar_infile = inaf
 
        IF (olfilist) THEN
-          CALL LFILAF(iresp,ilu,lfalse)
-          CALL LFIFER(iresp,ilu,'KEEP')
+          CALL LFILAF(iresp,infiles%files(idx)%lun_id,lfalse)
+          CALL LFIFER(iresp,infiles%files(idx)%lun_id,'KEEP')
           return
        END IF
 
        IF (.NOT.osplit) THEN
-         cdffiles%nbfiles = 1
-         allocate(cdffiles%cdf_id(1))
+         outfiles%nbfiles = outfiles%nbfiles + 1
 
+         idx = outfiles%nbfiles
+         outfiles%files(idx)%format = NETCDF_FORMAT
+         outfiles%files(idx)%status = WRITING
          IF (ohdf5) THEN
-            status = NF90_CREATE(houtfile, IOR(NF90_CLOBBER,NF90_NETCDF4), cdffiles%cdf_id(1))
+            status = NF90_CREATE(houtfile, IOR(NF90_CLOBBER,NF90_NETCDF4), outfiles%files(idx)%lun_id)
          ELSE
-            status = NF90_CREATE(houtfile, IOR(NF90_CLOBBER,NF90_64BIT_OFFSET), cdffiles%cdf_id(1))
+            status = NF90_CREATE(houtfile, IOR(NF90_CLOBBER,NF90_64BIT_OFFSET), outfiles%files(idx)%lun_id)
          END IF
        
          IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
-         cdffiles%opened  = .TRUE.
+         outfiles%files(idx)%opened  = .TRUE.
 
-         status = NF90_SET_FILL(cdffiles%cdf_id(1),NF90_NOFILL,omode)
+         status = NF90_SET_FILL(outfiles%files(idx)%lun_id,NF90_NOFILL,omode)
          IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
 !!$       SELECT CASE(omode)
 !!$       CASE (NF90_FILL)
@@ -1043,52 +1214,119 @@ END DO
 !!$       END SELECT
          END IF ! .NOT.osplit
        
+    ELSE IF (ocdf2cdf) THEN
+       ! Cas netCDF -> netCDF
+
+       infiles%nbfiles = infiles%nbfiles + 1
+       idx = infiles%nbfiles
+       status = NF90_OPEN(hinfile,NF90_NOWRITE,infiles%files(idx)%lun_id)
+       IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
+       infiles%files(idx)%opened  = .TRUE.
+       infiles%files(idx)%format = NETCDF_FORMAT
+       infiles%files(idx)%status = READING
+
+       status = NF90_INQUIRE(infiles%files(idx)%lun_id, nvariables = nbvar_infile)
+       IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
+
+
+       IF (.NOT.osplit) THEN
+         outfiles%nbfiles = outfiles%nbfiles + 1
+         idx = outfiles%nbfiles
+
+         IF (ohdf5) THEN
+            status = NF90_CREATE(houtfile, IOR(NF90_CLOBBER,NF90_NETCDF4), outfiles%files(idx)%lun_id)
+         ELSE
+            status = NF90_CREATE(houtfile, IOR(NF90_CLOBBER,NF90_64BIT_OFFSET), outfiles%files(idx)%lun_id)
+         END IF
+
+         IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
+         outfiles%files(idx)%opened  = .TRUE.
+         outfiles%files(idx)%format = NETCDF_FORMAT
+         outfiles%files(idx)%status = WRITING
+
+         status = NF90_SET_FILL(outfiles%files(idx)%lun_id,NF90_NOFILL,omode)
+         IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
+       END IF ! .NOT.osplit
+
     ELSE
        ! Cas NetCDF -> LFI
-       cdffiles%nbfiles = 1
-       allocate(cdffiles%cdf_id(1))
-       status = NF90_OPEN(hinfile,NF90_NOWRITE,cdffiles%cdf_id(1))
+       infiles%nbfiles = infiles%nbfiles + 1
+       idx = infiles%nbfiles
+       status = NF90_OPEN(hinfile,NF90_NOWRITE,infiles%files(idx)%lun_id)
        IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
-       cdffiles%opened  = .TRUE.
+       infiles%files(idx)%opened  = .TRUE.
+       infiles%files(idx)%format = NETCDF_FORMAT
+       infiles%files(idx)%status = READING
        
+       status = NF90_INQUIRE(infiles%files(idx)%lun_id, nvariables = nbvar_infile)
+       IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
+
        inap = 100
-       CALL LFIOUV(iresp,ilu,ltrue,houtfile,'NEW'&
+       outfiles%nbfiles = outfiles%nbfiles + 1
+       idx = outfiles%nbfiles
+       outfiles%files(idx)%lun_id = 11
+       outfiles%files(idx)%format = LFI_FORMAT
+       outfiles%files(idx)%status = WRITING
+       CALL LFIOUV(iresp,outfiles%files(idx)%lun_id,ltrue,houtfile,'NEW'&
             & ,lfalse,lfalse,iverb,inap,inaf)
+       outfiles%files(idx)%opened  = .TRUE.
     END IF
 
-    klu  = ilu
-    knaf = inaf
-
     PRINT *,'--> Fichier converti : ', houtfile
 
   END SUBROUTINE OPEN_FILES
 
-  SUBROUTINE OPEN_SPLIT_LFIFILE(ilu,hinfile,current_level)
-    INTEGER,          INTENT(IN) :: ilu
+  SUBROUTINE OPEN_SPLIT_LFIFILE_IN(infiles,hinfile,current_level)
+    TYPE(filelist_struct), INTENT(INOUT) :: infiles
     CHARACTER(LEN=*), INTENT(IN) :: hinfile
     INTEGER,          INTENT(IN) :: current_level
 
-    INTEGER(KIND=LFI_INT) :: iresp,iverb,inap,nbvar
+    INTEGER(KIND=LFI_INT) :: ilu,iresp,iverb,inap,nbvar
 
     CHARACTER(LEN=3)      :: suffix
     CHARACTER(LEN=:),ALLOCATABLE :: filename
 
+
     iverb = 0 !Verbosity level for LFI
 
     ALLOCATE(character(len=len(hinfile)) :: filename)
 
+    ilu = infiles%files(1)%lun_id !We assume only 1 infile
+
     write(suffix,'(I3.3)') current_level
     filename=hinfile(1:len(hinfile)-7)//suffix//'.lfi'
     CALL LFIOUV(iresp,ilu,ltrue,filename,'OLD',lfalse,lfalse,iverb,inap,nbvar)
+    infiles%files(1)%opened = .TRUE.
+
+    DEALLOCATE(filename)
+  END SUBROUTINE OPEN_SPLIT_LFIFILE_IN
+
+  SUBROUTINE OPEN_SPLIT_NCFILE_IN(infiles,hinfile,current_level)
+    TYPE(filelist_struct), INTENT(INOUT) :: infiles
+    CHARACTER(LEN=*), INTENT(IN) :: hinfile
+    INTEGER,          INTENT(IN) :: current_level
+
+    INTEGER :: status
+    CHARACTER(LEN=3)      :: suffix
+    CHARACTER(LEN=:),ALLOCATABLE :: filename
+
+
+    ALLOCATE(character(len=len(hinfile)) :: filename)
+
+    write(suffix,'(I3.3)') current_level
+    filename=hinfile(1:len(hinfile)-6)//suffix//'.nc'
+    status = NF90_OPEN(filename,NF90_NOWRITE,infiles%files(1)%lun_id)
+    IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
+    infiles%files(1)%opened  = .TRUE.
 
     DEALLOCATE(filename)
-  END SUBROUTINE OPEN_SPLIT_LFIFILE
+  END SUBROUTINE OPEN_SPLIT_NCFILE_IN
 
-  SUBROUTINE OPEN_SPLIT_NCFILES(houtfile,nbvar,tpreclist,cdffiles,ohdf5)
+  SUBROUTINE OPEN_SPLIT_NCFILES_OUT(outfiles,houtfile,nbvar,tpreclist,ohdf5)
+    TYPE(filelist_struct),         INTENT(INOUT) :: outfiles
     CHARACTER(LEN=*),              INTENT(IN)    :: houtfile
     INTEGER,                       INTENT(IN)    :: nbvar
     TYPE(workfield), DIMENSION(:), INTENT(IN)    :: tpreclist
-    TYPE(cdf_files),               INTENT(INOUT) :: cdffiles
     LOGICAL,                       INTENT(IN)    :: ohdf5
 
     INTEGER :: ji, idx
@@ -1097,66 +1335,55 @@ END DO
     CHARACTER(LEN=MAXLEN) :: filename
 
 
-    cdffiles%nbfiles = 0
     DO ji = 1,nbvar
-      IF (tpreclist(ji)%tbw) cdffiles%nbfiles = cdffiles%nbfiles + 1
+      IF (tpreclist(ji)%tbw) outfiles%nbfiles = outfiles%nbfiles + 1
     END DO
-    allocate(cdffiles%cdf_id(cdffiles%nbfiles))
-    allocate(cdffiles%var_id(cdffiles%nbfiles))
 
     idx = 1
     DO ji = 1,nbvar
       IF (.NOT.tpreclist(ji)%tbw) CYCLE
-
-      cdffiles%var_id(idx) = ji
+      outfiles%files(idx)%var_id = ji
 
       IF (ohdf5) THEN
         filename = trim(houtfile)//'.'//trim(tpreclist(ji)%name)//'.nc4'
-        status = NF90_CREATE(trim(filename), IOR(NF90_CLOBBER,NF90_NETCDF4), cdffiles%cdf_id(idx))
+        status = NF90_CREATE(trim(filename), IOR(NF90_CLOBBER,NF90_NETCDF4), outfiles%files(idx)%lun_id)
       ELSE
         filename = trim(houtfile)//'.'//trim(tpreclist(ji)%name)//'.nc'
-        status = NF90_CREATE(trim(filename), IOR(NF90_CLOBBER,NF90_64BIT_OFFSET), cdffiles%cdf_id(idx))
+        status = NF90_CREATE(trim(filename), IOR(NF90_CLOBBER,NF90_64BIT_OFFSET), outfiles%files(idx)%lun_id)
       END IF
 
       IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
 
-      status = NF90_SET_FILL(cdffiles%cdf_id(idx),NF90_NOFILL,omode)
+      status = NF90_SET_FILL(outfiles%files(idx)%lun_id,NF90_NOFILL,omode)
       IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
 
+      outfiles%files(idx)%opened  = .TRUE.
+      outfiles%files(idx)%format = NETCDF_FORMAT
+      outfiles%files(idx)%status = WRITING
+
       idx = idx + 1
     END DO
 
-    cdffiles%opened  = .TRUE.
-
-  END SUBROUTINE OPEN_SPLIT_NCFILES
+  END SUBROUTINE OPEN_SPLIT_NCFILES_OUT
   
-  SUBROUTINE CLOSE_FILES(klu,cdffiles,osplit)
-    INTEGER, INTENT(IN) :: klu
-    TYPE(cdf_files),INTENT(INOUT) :: cdffiles
-    LOGICAl, INTENT(IN) :: osplit
+  SUBROUTINE CLOSE_FILES(filelist)
+    TYPE(filelist_struct),INTENT(INOUT) :: filelist
     
-    INTEGER(KIND=LFI_INT) :: iresp,ilu
+    INTEGER(KIND=LFI_INT) :: iresp
     INTEGER               :: ji,status
 
-    ilu = klu
-    ! close LFI file
-    CALL LFIFER(iresp,ilu,'KEEP')
+    DO ji=1,filelist%nbfiles
+      IF ( .NOT.filelist%files(ji)%opened ) CYCLE
 
-    ! close NetCDF files
-    DO ji=1,cdffiles%nbfiles
-      status = NF90_CLOSE(cdffiles%cdf_id(ji))
-      IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
+      IF ( filelist%files(ji)%format == LFI_FORMAT ) THEN
+        CALL LFIFER(iresp,filelist%files(ji)%lun_id,'KEEP')
+      ELSE IF ( filelist%files(ji)%format == NETCDF_FORMAT ) THEN
+        status = NF90_CLOSE(filelist%files(ji)%lun_id)
+        IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
+      END IF
+      filelist%files(ji)%opened=.false.
     END DO
-    cdffiles%opened=.false.
-    
-  END SUBROUTINE CLOSE_files
-
-  SUBROUTINE CLOSE_SPLIT_LFIFILE(ilu)
-    INTEGER, INTENT(IN) :: ilu
-
-    INTEGER(KIND=LFI_INT) :: iresp
 
-    CALL LFIFER(iresp,ilu,'KEEP')
-  END SUBROUTINE CLOSE_SPLIT_LFIFILE
+  END SUBROUTINE CLOSE_FILES
 
 END MODULE mode_util
diff --git a/tools/lfi2cdf/src/newmain.c b/tools/lfi2cdf/src/newmain.c
index 6f56531fb..7ed4be3cf 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*, int*, int*, int*, int*);
+extern lfi2cdfmain_(char*, int*, int *, char*, int*, char*, int*, int*, int*, int*, int*, int*, int*, int*, int*, int*, int*);
 
 char *cleancomma(char *varlist)
 {
@@ -28,6 +28,7 @@ int main(int argc, char **argv)
 {
   int ilen;
   int list_flag;
+  int c2c_flag;
   int l2c_flag;
   int hdf5_flag;
   int merge_flag, nb_levels;
@@ -52,10 +53,11 @@ int main(int argc, char **argv)
   else
     cmd++;
   l2c_flag = strcmp(cmd, "lfi2cdf") == 0 ? 1 : 0;
+  c2c_flag = strcmp(cmd, "cdf2cdf") == 0 ? 1 : 0;
 
   compress_flag = 0;
   list_flag = 0;
-  hdf5_flag = 0;
+  hdf5_flag = 1;
   help_flag = 0;
   outname_flag = 0;
   reduceprecision_flag = 0;
@@ -71,6 +73,7 @@ int main(int argc, char **argv)
     int option_index = 0;
 
     static struct option long_options[] = {
+      {"cdf3",             no_argument,       0, '3' },
       {"cdf4",             no_argument,       0, '4' },
       {"compress",         required_argument, 0, 'c' },
       {"help",             no_argument,       0, 'h' },
@@ -83,7 +86,7 @@ int main(int argc, char **argv)
       {0,                  0,                 0,  0  }
     };
 
-    c = getopt_long(argc, argv, "4c:hlm:o:rsv:",
+    c = getopt_long(argc, argv, "34c:hlm:o:rsv:",
 		    long_options, &option_index);
     if (c == -1)
       break;
@@ -103,6 +106,9 @@ int main(int argc, char **argv)
         exit(EXIT_FAILURE);
       }
       break;
+    case '3':
+      hdf5_flag = 0;
+      break;
     case '4':
       hdf5_flag = 1;
       break;
@@ -128,7 +134,7 @@ int main(int argc, char **argv)
       split_flag = 1;
       break;
     case 'v':
-      if (l2c_flag) {
+      if (l2c_flag || c2c_flag) {
 	lenopt = strlen(optarg);
 	//	printf("option v with value '%s'\n", optarg);
 	if (p+lenopt > buff+BUFSIZE)
@@ -148,32 +154,34 @@ int main(int argc, char **argv)
   }
 
   if (optind == argc || help_flag) {
+//TODO: -l option for cdf2cdf and cdf2lfi
     printf("usage : lfi2cdf [-h --help] [--cdf4 -4] [-l] [-v --var var1[,...]] [-r --reduce-precision] [-m --merge number_of_z_levels] [-s --split] [-o --output output-file.nc] [-c --compress compression_level] input-file.lfi\n");
+    printf("        cdf2cdf [-h --help] [--cdf4 -4] [-v --var var1[,...]] [-r --reduce-precision] [-m --merge number_of_z_levels] [-s --split] [-o --output output-file.nc] [-c --compress compression_level] input-file.nc\n");
     printf("        cdf2lfi [-o --output output-file.lfi] input-file.nc\n");
-    printf("Usage: lfi2cdf [OPTION] ... lfi_file\n");
-    printf("       cdf2lfi [OPTION] ... nc_file\n");
     printf("\nOptions:\n");
-    printf("  --cdf4, -4\n");
-    printf("     Write netCDF file in netCDF-4 format (HDF5 compatible) (lfi2cdf only)\n");
+    printf("  --cdf3, -3\n");
+    printf("     Write netCDF file in netCDF-3 format (cdf2cdf and lfi2cdf only)\n");
+    printf("  --cdf4, -4 (by default)\n");
+    printf("     Write netCDF file in netCDF-4 format (HDF5 compatible) (cdf2cdf and lfi2cdf only)\n");
     printf("  --compress, -c compression_level\n");
     printf("     Compress data. The compression level should be in the 1 to 9 interval.\n");
-    printf("     Only supported with the netCDF-4 format (lfi2cdf only)\n");
+    printf("     Only supported with the netCDF-4 format (cdf2cdf and lfi2cdf only)\n");
     printf("  --help, -h\n");
     printf("     Print this text\n");
     printf("  --list, -l\n");
     printf("     List all the fields of the LFI file and returns (lfi2cdf only)\n");
     printf("  --merge, -m number_of_z_levels\n");
-    printf("     Merge LFI files which are split by vertical level (lfi2cdf only)\n");
+    printf("     Merge LFI files which are split by vertical level (cdf2cdf and lfi2cdf only)\n");
     printf("  --output, -o\n");
     printf("     Name of file for the output\n");
     printf("  --reduce-precision, -r\n");
-    printf("     Reduce the precision of the floating point variables to single precision (lfi2cdf only)\n");
+    printf("     Reduce the precision of the floating point variables to single precision (cdf2cdf and lfi2cdf only)\n");
     printf("  --split, -s\n");
-    printf("     Split variables specified with the -v option (one per file) (lfi2cdf only)\n");
+    printf("     Split variables specified with the -v option (one per file) (cdf2cdf and lfi2cdf only)\n");
     printf("  --var, -v var1[,...]\n");
     printf("     List of the variable to write in the output file. Variables names have to be separated by commas (,).\n");
     printf("     A variable can be computed from the sum of existing variables (format: new_var=var1+var2[+...])\n");
-    printf("     (lfi2cdf only)\n");
+    printf("     (cdf2cdf and lfi2cdf only)\n");
     printf("\n");
     exit(EXIT_FAILURE);
   } 
@@ -196,7 +204,7 @@ int main(int argc, char **argv)
     (void) strncpy(outfile, cp, strlen(cp) + 1);
     if ((sp = strrchr(outfile, '.')) != NULL)
       *sp = '\0';
-    if (l2c_flag){
+    if (l2c_flag || c2c_flag){
       char *ncext;
       ncext = hdf5_flag ? ".nc4" : ".nc"; 
       strcat(outfile,ncext);
@@ -217,13 +225,13 @@ int main(int argc, char **argv)
   */
 
   /* Split flag only supported if -v is set */
-  if (varlistlen==0) {
+  if (varlistlen==0 && split_flag!=0) {
 	  split_flag = 0;
 	  printf("Warning: split option is forced to disable.\n");
   }
 
 
-  lfi2cdfmain_(infile, &ilen, &outname_flag, outfile, &olen, varlist, &varlistlen, &l2c_flag, &list_flag, &hdf5_flag, &merge_flag,
+  lfi2cdfmain_(infile, &ilen, &outname_flag, outfile, &olen, varlist, &varlistlen, &c2c_flag, &l2c_flag, &list_flag, &hdf5_flag, &merge_flag,
 		       &nb_levels, &reduceprecision_flag, &split_flag, &compress_flag, &compress_level);
 
   exit(EXIT_SUCCESS);
-- 
GitLab