From 2d32464411e5baa18947b9c6fb4687a1cdc0e82f Mon Sep 17 00:00:00 2001
From: Philippe WAUTELET <philippe.wautelet@aero.obs-mip.fr>
Date: Thu, 25 Jan 2018 13:56:52 +0100
Subject: [PATCH] Philippe 25/01/2018: IO: add _FillValue, valid_min and
 valid_max attributes for fields in NC4 files

---
 src/LIB/SURCOUCHE/src/mode_field.f90  |  21 ++++-
 src/LIB/SURCOUCHE/src/mode_netcdf.f90 | 115 +++++++++++++++++++-------
 2 files changed, 106 insertions(+), 30 deletions(-)

diff --git a/src/LIB/SURCOUCHE/src/mode_field.f90 b/src/LIB/SURCOUCHE/src/mode_field.f90
index b9a239245..73292321d 100644
--- a/src/LIB/SURCOUCHE/src/mode_field.f90
+++ b/src/LIB/SURCOUCHE/src/mode_field.f90
@@ -4,10 +4,14 @@
 !MNH_LIC for details. version 1.
 MODULE MODE_FIELD
 !
-USE MODD_CONF, ONLY : CPROGRAM
+USE MODD_CONF,  ONLY : CPROGRAM
 USE MODD_IO_ll, ONLY : NVERB_DEBUG,NVERB_INFO,NVERB_WARNING,NVERB_ERROR,NVERB_FATAL
 USE MODD_PARAMETERS
 USE MODD_TYPE_DATE
+#if defined(MNH_IOCDF4)
+USE NETCDF, ONLY : NF90_FILL_INT, NF90_FILL_REAL
+#endif
+!
 USE MODE_MSG
 !
 IMPLICIT NONE
@@ -72,6 +76,21 @@ TYPE TFIELDDATA
   INTEGER            :: NTYPE     = TYPEUNDEF !Datatype
   INTEGER            :: NDIMS     = 0  !Number of dimensions
   !
+#if defined(MNH_IOCDF4)
+  INTEGER            :: NFILLVALUE =  NF90_FILL_INT  !Fill value for integer fields
+  REAL               :: XFILLVALUE =  NF90_FILL_REAL !Fill value for real fields
+                                                     !NF90_FILL_REAL is the default fill value
+                                                     !used by netCDF to pre-fill real and also double
+                                                     !variables
+#else
+  INTEGER            :: NFILLVALUE =  -2147483647            !Fill value for integer fields
+  REAL               :: XFILLVALUE =  9.9692099683868690e+36 !Fill value for real fields
+#endif
+  INTEGER            :: NVALIDMIN  = -2147483646 !Minimum valid value for integer fields
+  INTEGER            :: NVALIDMAX  =  2147483647 !Maximum valid value for integer fields
+  REAL               :: XVALIDMIN  = -1.E36 !Minimum valid value for real fields
+  REAL               :: XVALIDMAX  =  1.E36 !Maximum valid value for real fields
+  !
   TYPE(TFIELDPTR_C0D),DIMENSION(:),ALLOCATABLE :: TFIELD_C0D !Pointer to the character string fields (one per nested mesh)
   !
   TYPE(TFIELDPTR_L0D),DIMENSION(:),ALLOCATABLE :: TFIELD_L0D !Pointer to the scalar logical fields (one per nested mesh)
diff --git a/src/LIB/SURCOUCHE/src/mode_netcdf.f90 b/src/LIB/SURCOUCHE/src/mode_netcdf.f90
index 59e962a95..15224d2a3 100644
--- a/src/LIB/SURCOUCHE/src/mode_netcdf.f90
+++ b/src/LIB/SURCOUCHE/src/mode_netcdf.f90
@@ -47,7 +47,9 @@ INTERFACE IO_READ_FIELD_NC4
 END INTERFACE IO_READ_FIELD_NC4
 
 ! Public from module netcdf
-PUBLIC NF90_CLOSE,NF90_OPEN,NF90_CREATE,NF90_NOWRITE,NF90_CLOBBER,NF90_NETCDF4,NF90_NOERR,NF90_STRERROR
+PUBLIC NF90_CLOSE,NF90_OPEN,NF90_CREATE,                                &
+       NF90_NOWRITE,NF90_CLOBBER,NF90_NETCDF4,NF90_NOERR,NF90_STRERROR, &
+       NF90_FILL_REAL
 ! Public from this module :
 PUBLIC NEWIOCDF,CLEANIOCDF,IO_SET_KNOWNDIMS_NC4,IO_WRITE_COORDVAR_NC4, &
        IO_WRITE_FIELD_NC4,IO_READ_FIELD_NC4,IO_WRITE_HEADER_NC4
@@ -530,18 +532,21 @@ END IF
 END SUBROUTINE IO_WRITE_HEADER_NC4
 
 
-SUBROUTINE IO_WRITE_FIELD_ATTR_NC4(TPFIELD,KNCID,KVARID,KSHAPE,HCALENDAR,OISCOORD)
+SUBROUTINE IO_WRITE_FIELD_ATTR_NC4(TPFILE,TPFIELD,KVARID,KSHAPE,HCALENDAR,OISCOORD)
 !
 USE MODD_CONF,   ONLY: CPROGRAM, LCARTESIAN
 USE MODD_CONF_n, ONLY: CSTORAGE_TYPE
 !
+USE MODE_FIELD,  ONLY: TYPEINT, TYPEREAL
+!
+TYPE(TFILEDATA),                               INTENT(IN) :: TPFILE
 TYPE(TFIELDDATA),                              INTENT(IN) :: TPFIELD
-INTEGER(KIND=IDCDF_KIND),                      INTENT(IN) :: KNCID
 INTEGER(KIND=IDCDF_KIND),                      INTENT(IN) :: KVARID
 INTEGER(KIND=IDCDF_KIND),DIMENSION(:),OPTIONAL,INTENT(IN) :: KSHAPE
 CHARACTER(LEN=*),                     OPTIONAL,INTENT(IN) :: HCALENDAR
 LOGICAL,                              OPTIONAL,INTENT(IN) :: OISCOORD   ! Is a coordinate variable (->do not write coordinates attribute)
 !
+INTEGER(KIND=IDCDF_KIND)     :: INCID
 INTEGER(KIND=IDCDF_KIND)     :: STATUS
 CHARACTER(LEN=:),ALLOCATABLE :: YCOORDS
 LOGICAL                      :: GISCOORD
@@ -562,12 +567,14 @@ ELSE
   GISCOORD = .FALSE.
 END IF
 !
+INCID = TPFILE%NNCID
+!
 ! GRID attribute definition
 IF(TPFIELD%NGRID<0) THEN
   CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_WRITE_FIELD_ATTR_NC4','TPFIELD%NGRID not set for variable '//TRIM(TPFIELD%CMNHNAME))
 !Do not write GRID attribute if NGRID=0
-  ELSE IF (TPFIELD%NGRID>0) THEN
-  STATUS = NF90_PUT_ATT(KNCID, KVARID, 'GRID', TPFIELD%NGRID)
+ELSE IF (TPFIELD%NGRID>0) THEN
+  STATUS = NF90_PUT_ATT(INCID, KVARID, 'GRID', TPFIELD%NGRID)
   IF (STATUS /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'IO_WRITE_FIELD_ATTR_NC4 [NF90_PUT_ATT]')
 ENDIF
 !
@@ -575,7 +582,7 @@ ENDIF
 IF(LEN_TRIM(TPFIELD%CCOMMENT)==0) THEN
   CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_WRITE_FIELD_ATTR_NC4','TPFIELD%CCOMMENT not set for variable '//TRIM(TPFIELD%CMNHNAME))
 ELSE
-  STATUS = NF90_PUT_ATT(KNCID, KVARID,'COMMENT', TRIM(TPFIELD%CCOMMENT))
+  STATUS = NF90_PUT_ATT(INCID, KVARID,'COMMENT', TRIM(TPFIELD%CCOMMENT))
   IF (STATUS /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'IO_WRITE_FIELD_ATTR_NC4 [NF90_PUT_ATT]')
 ENDIF
 !
@@ -583,7 +590,7 @@ ENDIF
 IF(LEN_TRIM(TPFIELD%CSTDNAME)==0) THEN
   CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_WRITE_FIELD_ATTR_NC4','TPFIELD%CSTDNAME not set for variable '//TRIM(TPFIELD%CMNHNAME))
 ELSE
-  STATUS = NF90_PUT_ATT(KNCID, KVARID,'standard_name', TRIM(TPFIELD%CSTDNAME))
+  STATUS = NF90_PUT_ATT(INCID, KVARID,'standard_name', TRIM(TPFIELD%CSTDNAME))
   IF (STATUS /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'IO_WRITE_FIELD_ATTR_NC4 [NF90_PUT_ATT]')
 ENDIF
 !
@@ -591,7 +598,7 @@ ENDIF
 IF(LEN_TRIM(TPFIELD%CLONGNAME)==0) THEN
   CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_WRITE_FIELD_ATTR_NC4','TPFIELD%CLONGNAME not set for variable '//TRIM(TPFIELD%CMNHNAME))
 ELSE
-  STATUS = NF90_PUT_ATT(KNCID, KVARID,'long_name', TRIM(TPFIELD%CLONGNAME))
+  STATUS = NF90_PUT_ATT(INCID, KVARID,'long_name', TRIM(TPFIELD%CLONGNAME))
   IF (STATUS /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'IO_WRITE_FIELD_ATTR_NC4 [NF90_PUT_ATT]')
 ENDIF
 !
@@ -599,14 +606,14 @@ ENDIF
 IF(LEN_TRIM(TPFIELD%CUNITS)==0) THEN
   CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_WRITE_FIELD_ATTR_NC4','TPFIELD%CUNITS not set for variable '//TRIM(TPFIELD%CMNHNAME))
 ELSE
-  STATUS = NF90_PUT_ATT(KNCID, KVARID,'units', TRIM(TPFIELD%CUNITS))
+  STATUS = NF90_PUT_ATT(INCID, KVARID,'units', TRIM(TPFIELD%CUNITS))
   IF (STATUS /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'IO_WRITE_FIELD_ATTR_NC4 [NF90_PUT_ATT]')
 ENDIF
 !
 ! Calendar (CF convention)
 IF(PRESENT(HCALENDAR)) THEN
   CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_WRITE_FIELD_ATTR_NC4','CALENDAR provided for variable '//TRIM(TPFIELD%CMNHNAME))
-  STATUS = NF90_PUT_ATT(KNCID, KVARID,'calendar', TRIM(HCALENDAR))
+  STATUS = NF90_PUT_ATT(INCID, KVARID,'calendar', TRIM(HCALENDAR))
   IF (STATUS /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'IO_WRITE_FIELD_ATTR_NC4 [NF90_PUT_ATT]')
 ENDIF
 !
@@ -642,7 +649,7 @@ IF (.NOT.GISCOORD               &
             CALL PRINT_MSG(NVERB_ERROR,'IO','IO_WRITE_FIELD_ATTR_NC4','invalid NGRID for variable '//TRIM(TPFIELD%CMNHNAME))
         END SELECT
         !
-        STATUS = NF90_PUT_ATT(KNCID, KVARID,'coordinates',YCOORDS)
+        STATUS = NF90_PUT_ATT(INCID, KVARID,'coordinates',YCOORDS)
         IF (STATUS /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'IO_WRITE_FIELD_ATTR_NC4 [NF90_PUT_ATT]')
         DEALLOCATE(YCOORDS)
       ELSE
@@ -655,6 +662,56 @@ IF (.NOT.GISCOORD               &
   END IF
 ENDIF
 !
+IF(TPFIELD%NTYPE==TYPEINT .AND. TPFIELD%NDIMS>0) THEN
+  IF (TPFIELD%NFILLVALUE>=TPFIELD%NVALIDMIN .AND. TPFIELD%XFILLVALUE<=TPFIELD%NVALIDMAX) &
+    CALL PRINT_MSG(NVERB_WARNING,'IO','IO_WRITE_FIELD_ATTR_NC4','_FillValue is not outside of valid_min - valid_max'// &
+                                                                'interval for variable '//TRIM(TPFIELD%CMNHNAME))
+  !
+  ! Fillvalue (CF/COMODO convention)
+  !Remark: the attribute '_FillValue' is also recognized by the netCDF library
+  !        and is used when pre-filling a variable
+  STATUS = NF90_PUT_ATT(INCID, KVARID,'_FillValue', TPFIELD%NFILLVALUE)
+  IF (STATUS /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'IO_WRITE_FIELD_ATTR_NC4 [NF90_PUT_ATT]')
+  !
+  ! Valid_min/max (CF/COMODO convention)
+  STATUS = NF90_PUT_ATT(INCID, KVARID,'valid_min', TPFIELD%NVALIDMIN)
+  IF (STATUS /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'IO_WRITE_FIELD_ATTR_NC4 [NF90_PUT_ATT]')
+  !
+  STATUS = NF90_PUT_ATT(INCID, KVARID,'valid_max',TPFIELD%NVALIDMAX)
+  IF (STATUS /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'IO_WRITE_FIELD_ATTR_NC4 [NF90_PUT_ATT]')
+ENDIF
+!
+IF(TPFIELD%NTYPE==TYPEREAL .AND. TPFIELD%NDIMS>0) THEN
+  IF (TPFIELD%XFILLVALUE>=TPFIELD%XVALIDMIN .AND. TPFIELD%XFILLVALUE<=TPFIELD%XVALIDMAX) &
+    CALL PRINT_MSG(NVERB_WARNING,'IO','IO_WRITE_FIELD_ATTR_NC4','_FillValue is not outside of valid_min - valid_max'// &
+                                                                'interval for variable '//TRIM(TPFIELD%CMNHNAME))
+  !
+  ! Fillvalue (CF/COMODO convention)
+  !Remark: the attribute '_FillValue' is also recognized by the netCDF library
+  !        and is used when pre-filling a variable
+  IF (TPFILE%LNCREDUCE_FLOAT_PRECISION) THEN
+    STATUS = NF90_PUT_ATT(INCID, KVARID,'_FillValue', REAL(TPFIELD%XFILLVALUE,KIND=4))
+  ELSE
+    STATUS = NF90_PUT_ATT(INCID, KVARID,'_FillValue', TPFIELD%XFILLVALUE)
+  END IF
+  IF (STATUS /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'IO_WRITE_FIELD_ATTR_NC4 [NF90_PUT_ATT]')
+  !
+  ! Valid_min/max (CF/COMODO convention)
+  IF (TPFILE%LNCREDUCE_FLOAT_PRECISION) THEN
+    STATUS = NF90_PUT_ATT(INCID, KVARID,'valid_min', REAL(TPFIELD%XVALIDMIN,KIND=4))
+  ELSE
+    STATUS = NF90_PUT_ATT(INCID, KVARID,'valid_min', TPFIELD%XVALIDMIN)
+  END IF
+  IF (STATUS /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'IO_WRITE_FIELD_ATTR_NC4 [NF90_PUT_ATT]')
+  !
+  IF (TPFILE%LNCREDUCE_FLOAT_PRECISION) THEN
+    STATUS = NF90_PUT_ATT(INCID, KVARID,'valid_max', REAL(TPFIELD%XVALIDMAX,KIND=4))
+  ELSE
+    STATUS = NF90_PUT_ATT(INCID, KVARID,'valid_max',TPFIELD%XVALIDMAX)
+  END IF
+  IF (STATUS /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'IO_WRITE_FIELD_ATTR_NC4 [NF90_PUT_ATT]')
+ENDIF
+!
 END SUBROUTINE IO_WRITE_FIELD_ATTR_NC4
 
 FUNCTION GETDIMCDF(TPFILE, KLEN, HDIMNAME)
@@ -874,7 +931,7 @@ ELSE
 END IF
 
 ! Write metadata
-CALL IO_WRITE_FIELD_ATTR_NC4(TPFIELD,INCID,IVARID)
+CALL IO_WRITE_FIELD_ATTR_NC4(TPFILE,TPFIELD,IVARID)
 ! Write the data
 STATUS = NF90_PUT_VAR(INCID, IVARID, PFIELD)
 IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'IO_WRITE_FIELD_NC4_X0[NF90_PUT_VAR] '//TRIM(TPFIELD%CMNHNAME),IRESP)
@@ -934,7 +991,7 @@ ELSE
 END IF
 
 ! Write metadata
-CALL IO_WRITE_FIELD_ATTR_NC4(TPFIELD,INCID,IVARID)
+CALL IO_WRITE_FIELD_ATTR_NC4(TPFILE,TPFIELD,IVARID)
 ! Write the data
 STATUS = NF90_PUT_VAR(INCID, IVARID, PFIELD)
 IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'IO_WRITE_FIELD_NC4_X1[NF90_PUT_VAR] '//TRIM(TPFIELD%CMNHNAME),IRESP)
@@ -1017,7 +1074,7 @@ ELSE
 END IF
 
 ! Write metadata
-CALL IO_WRITE_FIELD_ATTR_NC4(TPFIELD,INCID,IVARID,KSHAPE=INT(SHAPE(PFIELD),KIND=IDCDF_KIND),OISCOORD=OISCOORD)
+CALL IO_WRITE_FIELD_ATTR_NC4(TPFILE,TPFIELD,IVARID,KSHAPE=INT(SHAPE(PFIELD),KIND=IDCDF_KIND),OISCOORD=OISCOORD)
 ! Write the data
 STATUS = NF90_PUT_VAR(INCID, IVARID, PFIELD)
 IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'IO_WRITE_FIELD_NC4_X2[NF90_PUT_VAR] '//TRIM(TPFIELD%CMNHNAME),IRESP)
@@ -1078,7 +1135,7 @@ ELSE
 END IF
 
 ! Write metadata
-CALL IO_WRITE_FIELD_ATTR_NC4(TPFIELD,INCID,IVARID,KSHAPE=INT(SHAPE(PFIELD),KIND=IDCDF_KIND))
+CALL IO_WRITE_FIELD_ATTR_NC4(TPFILE,TPFIELD,IVARID,KSHAPE=INT(SHAPE(PFIELD),KIND=IDCDF_KIND))
 ! Write the data
 STATUS = NF90_PUT_VAR(INCID, IVARID, PFIELD)
 IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'IO_WRITE_FIELD_NC4_X3[NF90_PUT_VAR] '//TRIM(TPFIELD%CMNHNAME),IRESP)
@@ -1139,7 +1196,7 @@ ELSE
 END IF
 
 ! Write metadata
-CALL IO_WRITE_FIELD_ATTR_NC4(TPFIELD,INCID,IVARID,KSHAPE=INT(SHAPE(PFIELD),KIND=IDCDF_KIND))
+CALL IO_WRITE_FIELD_ATTR_NC4(TPFILE,TPFIELD,IVARID,KSHAPE=INT(SHAPE(PFIELD),KIND=IDCDF_KIND))
 ! Write the data
 STATUS = NF90_PUT_VAR(INCID, IVARID, PFIELD)
 IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'IO_WRITE_FIELD_NC4_X4[NF90_PUT_VAR] '//TRIM(TPFIELD%CMNHNAME),IRESP)
@@ -1200,7 +1257,7 @@ ELSE
 END IF
 
 ! Write metadata
-CALL IO_WRITE_FIELD_ATTR_NC4(TPFIELD,INCID,IVARID,KSHAPE=INT(SHAPE(PFIELD),KIND=IDCDF_KIND))
+CALL IO_WRITE_FIELD_ATTR_NC4(TPFILE,TPFIELD,IVARID,KSHAPE=INT(SHAPE(PFIELD),KIND=IDCDF_KIND))
 ! Write the data
 STATUS = NF90_PUT_VAR(INCID, IVARID, PFIELD)
 IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'IO_WRITE_FIELD_NC4_X5[NF90_PUT_VAR] '//TRIM(TPFIELD%CMNHNAME),IRESP)
@@ -1261,7 +1318,7 @@ ELSE
 END IF
 
 ! Write metadata
-CALL IO_WRITE_FIELD_ATTR_NC4(TPFIELD,INCID,IVARID,KSHAPE=INT(SHAPE(PFIELD),KIND=IDCDF_KIND))
+CALL IO_WRITE_FIELD_ATTR_NC4(TPFILE,TPFIELD,IVARID,KSHAPE=INT(SHAPE(PFIELD),KIND=IDCDF_KIND))
 ! Write the data
 STATUS = NF90_PUT_VAR(INCID, IVARID, PFIELD)
 IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'IO_WRITE_FIELD_NC4_X6[NF90_PUT_VAR] '//TRIM(TPFIELD%CMNHNAME),IRESP)
@@ -1312,7 +1369,7 @@ ELSE
 END IF
 
 ! Write metadata
-CALL IO_WRITE_FIELD_ATTR_NC4(TPFIELD,INCID,IVARID)
+CALL IO_WRITE_FIELD_ATTR_NC4(TPFILE,TPFIELD,IVARID)
 ! Write the data
 STATUS = NF90_PUT_VAR(INCID, IVARID, KFIELD)
 IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'IO_WRITE_FIELD_NC4_N0[NF90_PUT_VAR] '//TRIM(TPFIELD%CMNHNAME),IRESP)
@@ -1390,7 +1447,7 @@ ELSE
 END IF
 
 ! Write metadata
-CALL IO_WRITE_FIELD_ATTR_NC4(TPFIELD,INCID,IVARID)
+CALL IO_WRITE_FIELD_ATTR_NC4(TPFILE,TPFIELD,IVARID)
 ! Write the data
 STATUS = NF90_PUT_VAR(INCID, IVARID, KFIELD)
 IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'IO_WRITE_FIELD_NC4_N1[NF90_PUT_VAR] '//TRIM(TPFIELD%CMNHNAME),IRESP)
@@ -1451,7 +1508,7 @@ ELSE
 END IF
 
 ! Write metadata
-CALL IO_WRITE_FIELD_ATTR_NC4(TPFIELD,INCID,IVARID,KSHAPE=INT(SHAPE(KFIELD),KIND=IDCDF_KIND))
+CALL IO_WRITE_FIELD_ATTR_NC4(TPFILE,TPFIELD,IVARID,KSHAPE=INT(SHAPE(KFIELD),KIND=IDCDF_KIND))
 ! Write the data
 STATUS = NF90_PUT_VAR(INCID, IVARID, KFIELD)
 IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'IO_WRITE_FIELD_NC4_N2[NF90_PUT_VAR] '//TRIM(TPFIELD%CMNHNAME),IRESP)
@@ -1511,7 +1568,7 @@ ELSE
 END IF
 
 ! Write metadata
-CALL IO_WRITE_FIELD_ATTR_NC4(TPFIELD,INCID,IVARID,KSHAPE=INT(SHAPE(KFIELD),KIND=IDCDF_KIND))
+CALL IO_WRITE_FIELD_ATTR_NC4(TPFILE,TPFIELD,IVARID,KSHAPE=INT(SHAPE(KFIELD),KIND=IDCDF_KIND))
 ! Write the data
 STATUS = NF90_PUT_VAR(INCID, IVARID, KFIELD)
 IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'IO_WRITE_FIELD_NC4_N3[NF90_PUT_VAR] '//TRIM(TPFIELD%CMNHNAME),IRESP)
@@ -1562,7 +1619,7 @@ ELSE
 END IF
 
 ! Write metadata
-CALL IO_WRITE_FIELD_ATTR_NC4(TPFIELD,INCID,IVARID)
+CALL IO_WRITE_FIELD_ATTR_NC4(TPFILE,TPFIELD,IVARID)
 ! Write the data
 STATUS = NF90_PUT_VAR(INCID, IVARID, IFIELD)
 IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'IO_WRITE_FIELD_NC4_L0[NF90_PUT_VAR] '//TRIM(TPFIELD%CMNHNAME),IRESP)
@@ -1623,7 +1680,7 @@ ELSEWHERE
 END WHERE
 
 ! Write metadata
-CALL IO_WRITE_FIELD_ATTR_NC4(TPFIELD,INCID,IVARID)
+CALL IO_WRITE_FIELD_ATTR_NC4(TPFILE,TPFIELD,IVARID)
 ! Write the data
 STATUS = NF90_PUT_VAR(INCID, IVARID, IFIELD)
 IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'IO_WRITE_FIELD_NC4_L1[NF90_PUT_VAR] '//TRIM(TPFIELD%CMNHNAME),IRESP)
@@ -1680,7 +1737,7 @@ ALLOCATE(CHARACTER(LEN=ILEN)::YFIELD)
 YFIELD(:)=TRIM(HFIELD) !Warning: keep (:) to prevent F2003 automatic reallocation
 YFIELD(LEN_TRIM(HFIELD)+1:)=' '
 ! Write metadata
-CALL IO_WRITE_FIELD_ATTR_NC4(TPFIELD,INCID,IVARID)
+CALL IO_WRITE_FIELD_ATTR_NC4(TPFILE,TPFIELD,IVARID)
 ! Write the data
 STATUS = NF90_PUT_VAR(INCID, IVARID, YFIELD)
 IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'IO_WRITE_FIELD_NC4_C0[NF90_PUT_VAR] '//TRIM(TPFIELD%CMNHNAME),IRESP)
@@ -1732,7 +1789,7 @@ ELSE
 END IF
 
 ! Write metadata
-CALL IO_WRITE_FIELD_ATTR_NC4(TPFIELD,INCID,IVARID)
+CALL IO_WRITE_FIELD_ATTR_NC4(TPFILE,TPFIELD,IVARID)
 ! Write the data
 STATUS = NF90_PUT_VAR(INCID, IVARID, HFIELD(1:ISIZE)(1:ILEN), START=(/IONE,IONE/), COUNT=(/ILEN,ISIZE/))
 IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'IO_WRITE_FIELD_NC4_C1[NF90_PUT_VAR] '//TRIM(TPFIELD%CMNHNAME),IRESP)
@@ -1790,7 +1847,7 @@ ELSE
 END IF
 
 ! Write metadata
-CALL IO_WRITE_FIELD_ATTR_NC4(TZFIELD,INCID,IVARID,HCALENDAR='standard')
+CALL IO_WRITE_FIELD_ATTR_NC4(TPFILE,TZFIELD,IVARID,HCALENDAR='standard')
 ! Write the data
 STATUS = NF90_PUT_VAR(INCID, IVARID, TPDATA%TIME)
 IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'IO_WRITE_FIELD_NC4_X0[NF90_PUT_VAR] '//TRIM(TPFIELD%CMNHNAME),IRESP)
@@ -1820,7 +1877,7 @@ IF (STATUS /= NF90_NOERR) THEN
    ! Define the variable 
    STATUS = NF90_DEF_VAR(INCID, TZFIELD%CMNHNAME, NF90_INT, IVDIMS, IVARID)
    IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'IO_WRITE_FIELD_NC4_T0[NF90_DEF_VAR]')
-   CALL IO_WRITE_FIELD_ATTR_NC4(TZFIELD,INCID,IVARID)
+   CALL IO_WRITE_FIELD_ATTR_NC4(TPFILE,TZFIELD,IVARID)
 ELSE
    CALL PRINT_MSG(NVERB_WARNING,'IO','IO_WRITE_FIELD_NC4_T0',TRIM(TPFILE%CNAME)//': '//TRIM(TZFIELD%CMNHNAME)//' already defined')
 END IF
@@ -1847,7 +1904,7 @@ IF (STATUS /= NF90_NOERR) THEN
    ! Define the scalar variable 
    STATUS = NF90_DEF_VAR(INCID, TZFIELD%CMNHNAME, NF90_DOUBLE, IVARID)
    IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'IO_WRITE_FIELD_NC4_T0[NF90_DEF_VAR]')
-   CALL IO_WRITE_FIELD_ATTR_NC4(TZFIELD,INCID,IVARID)
+   CALL IO_WRITE_FIELD_ATTR_NC4(TPFILE,TZFIELD,IVARID)
 ELSE
    CALL PRINT_MSG(NVERB_WARNING,'IO','IO_WRITE_FIELD_NC4_T0',TRIM(TPFILE%CNAME)//': '//TRIM(TZFIELD%CMNHNAME)//' already defined')
 END IF
-- 
GitLab