diff --git a/src/MNH/aircraft_balloon.f90 b/src/MNH/aircraft_balloon.f90
index 93782678d6ba0e3210ba2bd71f3bf0ffcad20c8a..3ee7836b22949de9e67e9c47a8945aab135dd977 100644
--- a/src/MNH/aircraft_balloon.f90
+++ b/src/MNH/aircraft_balloon.f90
@@ -357,16 +357,16 @@ CHARACTER(LEN=*), INTENT(OUT) :: HLONGTYPE
 character(len=:), allocatable :: ytype
 
 if ( Trim( TPFLYER%TYPE ) == 'AIRCRA' ) then
-  ytype = 'aircraft'
+  ytype = 'Aircrafts'
 else if ( Trim( TPFLYER%TYPE ) == 'RADIOS' ) then
-  ytype = 'radiosonde balloon'
+  ytype = 'Radiosonde balloons'
 else if ( Trim( TPFLYER%TYPE ) == 'ISODEN' ) then
-  ytype = 'iso-density balloon'
+  ytype = 'Iso-density balloons'
 else if ( Trim( TPFLYER%TYPE ) == 'CVBALL' ) then
-  ytype = 'constant volume balloon'
+  ytype = 'Constant volume balloons'
 else
   call Print_msg( NVERB_ERROR, 'GEN', 'AIRCRAFT_BALLOON_LONGTYPE_GET', 'unknown category for flyer ' // Trim( tpflyer%title ) )
-  ytype = 'unknown'
+  ytype = 'Unknown'
 end if
 
 if ( Len_trim( ytype ) > Len( HLONGTYPE ) ) &
diff --git a/src/MNH/modd_budget.f90 b/src/MNH/modd_budget.f90
index 312b4f5194a9a533004531c3b8bba0bcd580712a..7442dfd3e0184598cd4ee7687456a5e31b900e5b 100644
--- a/src/MNH/modd_budget.f90
+++ b/src/MNH/modd_budget.f90
@@ -60,8 +60,6 @@ implicit none
 
 public
 
-character(len=*), parameter :: CNOTSET = 'not set'
-
 integer, parameter :: NBULISTMAXLEN   = 256
 integer, parameter :: NBULISTMAXLINES = 50
 
@@ -80,6 +78,27 @@ integer, parameter :: NBUDGET_RG  = 11 ! Reference number for budget of RhoJrg a
 integer, parameter :: NBUDGET_RH  = 12 ! Reference number for budget of RhoJrh and/or LES budgets with rh
 integer, parameter :: NBUDGET_SV1 = 13 ! Reference number for 1st budget of RhoJsv and/or LES budgets with sv
 
+integer, parameter :: NMAXLEVELS       = 7
+integer, parameter :: NLVL_ROOT        = 0
+integer, parameter :: NLVL_CATEGORY    = 1
+integer, parameter :: NLVL_SUBCATEGORY = 2
+integer, parameter :: NLVL_GROUP       = 3
+integer, parameter :: NLVL_SHAPE       = 4
+integer, parameter :: NLVL_TIMEAVG     = 5
+integer, parameter :: NLVL_NORM        = 6
+integer, parameter :: NLVL_MASK        = 7
+
+#ifdef MNH_IOCDF4
+character(len=*), dimension(NMAXLEVELS), parameter :: CNCGROUPNAMES = [ &
+                                         'category   ', &  !Name of the different type of groups/levels in the netCDF file
+                                         'subcategory', &
+                                         'group      ', &
+                                         'shape      ', &
+                                         'timeavg    ', &
+                                         'norm       ', &
+                                         'mask       '  ]
+#endif
+
 integer :: nbudgets ! Number of budget categories
 
 
@@ -106,19 +125,16 @@ type, extends( tfield_metadata_base ) :: tburhodata
 end type tburhodata
 
 type :: tbudiachrometadata
-  character(len=NCOMMENTLGTMAX) :: ccomment     = CNOTSET
-  character(len=NBUNAMELGTMAX)  :: ccategory    = CNOTSET !budget, LES, aircraft, balloon, series, station, profiler
-  character(len=NBUNAMELGTMAX)  :: csubcategory = CNOTSET
-  character(len=NBUNAMELGTMAX)  :: cgroup       = CNOTSET
-  character(len=NBUNAMELGTMAX)  :: cshape       = CNOTSET !Shape of the domain (mask, cartesian, vertical profile, point)
-  character(len=NBUNAMELGTMAX)  :: cmask        = CNOTSET !Mask defining where data is of meaning
-  character(len=1)              :: cdirection   = ''        !Used for 2pt correlation and spectrum
-  logical :: lmobile    = .false.                          !Is the domain moving? (ie for aircrafts and balloons)
+  character(len=NBUNAMELGTMAX),  dimension(NMAXLEVELS) :: clevels  = '' !Name of the different groups/levels in the netCDF file
+  character(len=NCOMMENTLGTMAX), dimension(NMAXLEVELS) :: ccomments ='' !Comments for the different groups/levels in the netCDF file
+  character(len=1)              :: cdirection   = ''                    !Used for 2pt correlation and spectrum
+  logical :: lmobile    = .false.                                       !Is the domain moving? (ie for aircrafts and balloons)
   logical :: licompress = .false.
   logical :: ljcompress = .false.
   logical :: lkcompress = .false.
   logical :: ltcompress = .false. ! true if values are time averaged (can be on multiple time periods)
   logical :: lnorm      = .false. ! true if values are normalized
+  logical, dimension(NMAXLEVELS) :: lleveluse = .false.
   integer :: nil = -1 !Cartesian box boundaries in physical domain coordinates
   integer :: nih = -1
   integer :: njl = -1
diff --git a/src/MNH/mode_les_diachro.f90 b/src/MNH/mode_les_diachro.f90
index 8284d37499efa6c327aa07341576fb2e94d9ad09..88258d0e605cdee92a9a4a3842c096cda1e5ae3b 100644
--- a/src/MNH/mode_les_diachro.f90
+++ b/src/MNH/mode_les_diachro.f90
@@ -17,7 +17,8 @@
 MODULE MODE_LES_DIACHRO
 !#######################
 
-use modd_budget, only: tbudiachrometadata
+use modd_budget, only: NLVL_CATEGORY, NLVL_SUBCATEGORY, NLVL_GROUP, NLVL_SHAPE, NLVL_TIMEAVG, NLVL_NORM, NLVL_MASK, &
+                       tbudiachrometadata
 use modd_les_n,  only: tles_dates, xles_times
 use modd_lunit
 
@@ -968,7 +969,6 @@ contains
 subroutine Les_diachro_common_intern( oavg, onorm )
 !#######################################################################################
 
-use modd_budget,        only: CNOTSET
 use modd_field,         only: NMNHDIM_BUDGET_LES_TIME, NMNHDIM_BUDGET_LES_AVG_TIME, NMNHDIM_BUDGET_LES_MASK, &
                               NMNHDIM_BUDGET_LES_SV, NMNHDIM_UNUSED
 use modd_les,           only: nles_current_times
@@ -1021,18 +1021,14 @@ if ( oavg ) call Les_time_avg_4d( zfield, tzdates, iresp )
 if ( oavg ) then
   if ( onorm ) then
     ygroup = 'H_' // tpfield%cmnhname
-    tzbudiachro%ccomment = Trim( tpfield%ccomment ) // ' (normalized and time averaged)'
   else
     ygroup = 'A_' // tpfield%cmnhname
-    tzbudiachro%ccomment = Trim( tpfield%ccomment ) // ' (time averaged)'
   end if
 else
   if ( onorm ) then
     ygroup = 'E_' // tpfield%cmnhname
-    tzbudiachro%ccomment = Trim( tpfield%ccomment ) // ' (normalized)'
   else
     ygroup = tpfield%cmnhname
-    tzbudiachro%ccomment = Trim( tpfield%ccomment )
   end if
 endif
 
@@ -1068,11 +1064,50 @@ if ( iresp == 0 .and. any( zfield /= XUNDEF ) ) then
   tzfields(:)%clongname = ytitle(:)
   tzfields(:)%ccomment  = ycomment(:)
 
-  !tzbudiachro%ccomment   = DONE BEFORE
-  tzbudiachro%ccategory  = 'LES'
-!   tzbudiachro%csubcategory  = CNOTSET
-  tzbudiachro%cgroup     = ygroup
-  tzbudiachro%cshape     = 'cartesian'
+  tzbudiachro%lleveluse(NLVL_CATEGORY)    = .true.
+  tzbudiachro%clevels  (NLVL_CATEGORY)    = 'LES budgets'
+  tzbudiachro%ccomments(NLVL_CATEGORY)    = 'Level for the different LES budgets'
+
+  tzbudiachro%lleveluse(NLVL_SUBCATEGORY) = .false.
+  tzbudiachro%clevels  (NLVL_SUBCATEGORY) = ''
+  tzbudiachro%ccomments(NLVL_SUBCATEGORY) = ''
+
+  tzbudiachro%lleveluse(NLVL_GROUP)       = .true.
+  tzbudiachro%clevels  (NLVL_GROUP)       = Trim( ygroup )
+  tzbudiachro%ccomments(NLVL_GROUP)       = ''
+
+  tzbudiachro%lleveluse(NLVL_SHAPE)       = .true.
+  tzbudiachro%clevels  (NLVL_SHAPE)       = 'Cartesian'
+  tzbudiachro%ccomments(NLVL_SHAPE)       = 'cartesian domain'
+
+  tzbudiachro%lleveluse(NLVL_TIMEAVG)     = .true.
+  if ( oavg ) then
+    tzbudiachro%clevels  (NLVL_TIMEAVG)   = 'Time averaged'
+    tzbudiachro%ccomments(NLVL_TIMEAVG)   = 'Values are time averaged'
+  else
+    tzbudiachro%clevels  (NLVL_TIMEAVG)   = 'Not time averaged'
+    tzbudiachro%ccomments(NLVL_TIMEAVG)   = 'Values are not time averaged'
+  end if
+
+  tzbudiachro%lleveluse(NLVL_NORM)        = .true.
+  if ( onorm ) then
+    tzbudiachro%clevels  (NLVL_NORM)      = 'Normalized'
+    tzbudiachro%ccomments(NLVL_NORM)      = 'Values are normalized'
+  else
+    tzbudiachro%clevels  (NLVL_NORM)      = 'Not normalized'
+    tzbudiachro%ccomments(NLVL_NORM)      = 'Values are not normalized'
+  end if
+
+  if ( tzfields(1)%ndimlist(6) == NMNHDIM_BUDGET_LES_MASK ) then
+    tzbudiachro%lleveluse(NLVL_MASK)        = .true.
+!     tzbudiachro%clevels  (NLVL_MASK)        = DONE AFTER
+!     tzbudiachro%ccomments(NLVL_MASK)        = DONE AFTER
+  else
+    tzbudiachro%lleveluse(NLVL_MASK)        = .false.
+    tzbudiachro%clevels  (NLVL_MASK)        = ''
+    tzbudiachro%ccomments(NLVL_MASK)        = ''
+  end if
+
   tzbudiachro%lmobile    = .false.
   tzbudiachro%licompress = .true.
   tzbudiachro%ljcompress = .true.
@@ -1095,12 +1130,13 @@ if ( iresp == 0 .and. any( zfield /= XUNDEF ) ) then
       tzfields(jp)%clongname = Trim( ytitle(jp) ) // ' (' // Trim( hmasks(jp) ) // ')'
       tzfields(jp)%ndims     = tzfields(jp)%ndims - 1
 
-      tzbudiachro%cmask      = hmasks(jp)
+      tzbudiachro%clevels(NLVL_MASK) = hmasks(jp)
+      tzbudiachro%ccomments(NLVL_MASK) = ''
 
       call Write_diachro( tpdiafile, tzbudiachro, [ tzfields(jp) ], tzdates, zwork6(:,:,:,:,:,jp:jp) )
     end do
   else
-    tzbudiachro%cmask      = 'cart'
+    tzbudiachro%clevels(NLVL_MASK) = 'cart'
 
     call Write_diachro( tpdiafile, tzbudiachro, tzfields, tzdates, zwork6 )
   end if
@@ -1259,16 +1295,39 @@ if ( gavg ) then
   end do
 end if
 
-if ( .not. gavg ) then
-  tzbudiachro%ccomment = tzfield%ccomment
+tzbudiachro%lleveluse(NLVL_CATEGORY)    = .true.
+tzbudiachro%clevels  (NLVL_CATEGORY)    = 'LES budgets'
+tzbudiachro%ccomments(NLVL_CATEGORY)    = 'Level for the different LES budgets'
+
+tzbudiachro%lleveluse(NLVL_SUBCATEGORY) = .false.
+tzbudiachro%clevels  (NLVL_SUBCATEGORY) = ''
+tzbudiachro%ccomments(NLVL_SUBCATEGORY) = ''
+
+tzbudiachro%lleveluse(NLVL_GROUP)       = .true.
+tzbudiachro%clevels  (NLVL_GROUP)       = Trim( ygroup )
+tzbudiachro%ccomments(NLVL_GROUP)       = ''
+
+tzbudiachro%lleveluse(NLVL_SHAPE)       = .true.
+tzbudiachro%clevels  (NLVL_SHAPE)       = '2-point correlation'
+tzbudiachro%ccomments(NLVL_SHAPE)       = ''
+
+tzbudiachro%lleveluse(NLVL_TIMEAVG)     = .true.
+if ( gavg ) then
+  tzbudiachro%clevels  (NLVL_TIMEAVG)   = 'Time averaged'
+  tzbudiachro%ccomments(NLVL_TIMEAVG)   = 'Values are time averaged'
 else
-  tzbudiachro%ccomment = Trim( tzfield%ccomment ) // ' (time averaged)'
+  tzbudiachro%clevels  (NLVL_TIMEAVG)   = 'Not time averaged'
+  tzbudiachro%ccomments(NLVL_TIMEAVG)   = 'Values are not time averaged'
 end if
-tzbudiachro%ccategory  = 'LES'
-! tzbudiachro%csubcategory  = CNOTSET
-tzbudiachro%cgroup     = ygroup
-tzbudiachro%cshape     = '2-point correlation'
-! tzbudiachro%cmask      = CNOTSET
+
+tzbudiachro%lleveluse(NLVL_NORM)        = .true.
+tzbudiachro%clevels  (NLVL_NORM)        = 'Not normalized'
+tzbudiachro%ccomments(NLVL_NORM)        = 'Values are not normalized'
+
+tzbudiachro%lleveluse(NLVL_MASK)        = .false.
+tzbudiachro%clevels  (NLVL_MASK)        = ''
+tzbudiachro%ccomments(NLVL_MASK)        = ''
+
 if ( tzfield%ndimlist(1) == NMNHDIM_SPECTRA_2PTS_NI ) then
   tzbudiachro%cdirection = 'I'
 else
@@ -1421,12 +1480,34 @@ tzfield%cmnhname  = ygroup
 tzfield%clongname = ygroup
 tzfield%ccomment  = ycomment(:)
 
-tzbudiachro%ccomment   = tzfield%ccomment
-tzbudiachro%ccategory  = 'LES'
-! tzbudiachro%csubcategory  = CNOTSET
-tzbudiachro%cgroup     = ygroup
-tzbudiachro%cshape     = 'spectrum'
-! tzbudiachro%cmask      = CNOTSET
+tzbudiachro%lleveluse(NLVL_CATEGORY)    = .true.
+tzbudiachro%clevels  (NLVL_CATEGORY)    = 'LES budgets'
+tzbudiachro%ccomments(NLVL_CATEGORY)    = 'Level for the different LES budgets'
+
+tzbudiachro%lleveluse(NLVL_SUBCATEGORY) = .false.
+tzbudiachro%clevels  (NLVL_SUBCATEGORY) = ''
+tzbudiachro%ccomments(NLVL_SUBCATEGORY) = ''
+
+tzbudiachro%lleveluse(NLVL_GROUP)       = .true.
+tzbudiachro%clevels  (NLVL_GROUP)       = Trim( ygroup )
+tzbudiachro%ccomments(NLVL_GROUP)       = ''
+
+tzbudiachro%lleveluse(NLVL_SHAPE)       = .true.
+tzbudiachro%clevels  (NLVL_SHAPE)       = 'Spectrum'
+tzbudiachro%ccomments(NLVL_SHAPE)       = ''
+
+tzbudiachro%lleveluse(NLVL_TIMEAVG)     = .true.
+tzbudiachro%clevels  (NLVL_TIMEAVG)     = 'Not time averaged'
+tzbudiachro%ccomments(NLVL_TIMEAVG)     = 'Values are not time averaged'
+
+tzbudiachro%lleveluse(NLVL_NORM)        = .true.
+tzbudiachro%clevels  (NLVL_NORM)        = 'Not normalized'
+tzbudiachro%ccomments(NLVL_NORM)        = 'Values are not normalized'
+
+tzbudiachro%lleveluse(NLVL_MASK)        = .false.
+tzbudiachro%clevels  (NLVL_MASK)        = ''
+tzbudiachro%ccomments(NLVL_MASK)        = ''
+
 if ( tzfield%ndimlist(1) == NMNHDIM_SPECTRA_SPEC_NI ) then
   tzbudiachro%cdirection = 'I'
 else
@@ -1459,12 +1540,34 @@ end do
 tzfield%cmnhname  = ygroup
 tzfield%clongname = ygroup
 
-tzbudiachro%ccomment   = Trim( tzfield%ccomment ) // ' (time averaged)'
-tzbudiachro%ccategory  = 'LES'
-! tzbudiachro%csubcategory  = CNOTSET
-tzbudiachro%cgroup     = ygroup
-tzbudiachro%cshape     = 'spectrum'
-! tzbudiachro%cmask      = CNOTSET
+tzbudiachro%lleveluse(NLVL_CATEGORY)    = .true.
+tzbudiachro%clevels  (NLVL_CATEGORY)    = 'LES budgets'
+tzbudiachro%ccomments(NLVL_CATEGORY)    = 'Level for the different LES budgets'
+
+tzbudiachro%lleveluse(NLVL_SUBCATEGORY) = .false.
+tzbudiachro%clevels  (NLVL_SUBCATEGORY) = ''
+tzbudiachro%ccomments(NLVL_SUBCATEGORY) = ''
+
+tzbudiachro%lleveluse(NLVL_GROUP)       = .true.
+tzbudiachro%clevels  (NLVL_GROUP)       = Trim( ygroup )
+tzbudiachro%ccomments(NLVL_GROUP)       = ''
+
+tzbudiachro%lleveluse(NLVL_SHAPE)       = .true.
+tzbudiachro%clevels  (NLVL_SHAPE)       = 'Spectrum'
+tzbudiachro%ccomments(NLVL_SHAPE)       = ''
+
+tzbudiachro%lleveluse(NLVL_TIMEAVG)     = .true.
+tzbudiachro%clevels  (NLVL_TIMEAVG)     = 'Time averaged'
+tzbudiachro%ccomments(NLVL_TIMEAVG)     = 'Values are time averaged'
+
+tzbudiachro%lleveluse(NLVL_NORM)        = .true.
+tzbudiachro%clevels  (NLVL_NORM)        = 'Not normalized'
+tzbudiachro%ccomments(NLVL_NORM)        = 'Values are not normalized'
+
+tzbudiachro%lleveluse(NLVL_MASK)        = .false.
+tzbudiachro%clevels  (NLVL_MASK)        = ''
+tzbudiachro%ccomments(NLVL_MASK)        = ''
+
 if ( tzfield%ndimlist(1) == NMNHDIM_SPECTRA_SPEC_NI ) then
   tzbudiachro%cdirection = 'I'
 else
diff --git a/src/MNH/write_aircraft_balloon.f90 b/src/MNH/write_aircraft_balloon.f90
index 3dac58df85c72a9e9d0786672c1b74d9da46759e..0723a49e20ebaf29b0b29f90ccd1c3579d9927d7 100644
--- a/src/MNH/write_aircraft_balloon.f90
+++ b/src/MNH/write_aircraft_balloon.f90
@@ -176,7 +176,8 @@ CONTAINS
 !
 SUBROUTINE FLYER_DIACHRO(TPFLYER)
 
-use modd_budget, only: tbudiachrometadata
+use modd_budget, only: NLVL_CATEGORY, NLVL_SUBCATEGORY, NLVL_GROUP, NLVL_SHAPE, NLVL_TIMEAVG, NLVL_NORM, NLVL_MASK, &
+                       tbudiachrometadata
 use modd_field,  only: NMNHDIM_LEVEL, NMNHDIM_FLYER_PROC, NMNHDIM_FLYER_TIME, NMNHDIM_UNUSED, &
                        tfield_metadata_base, TYPEREAL
 
@@ -854,12 +855,33 @@ tzfields(:)%ndimlist(4) = NMNHDIM_FLYER_TIME
 tzfields(:)%ndimlist(5) = NMNHDIM_UNUSED
 tzfields(:)%ndimlist(6) = NMNHDIM_FLYER_PROC
 
-tzbudiachro%ccomment   = 'Values at position of flyer ' // Trim( tpflyer%title )
-tzbudiachro%ccategory  = 'flyer'
-call Aircraft_balloon_longtype_get( tpflyer, tzbudiachro%csubcategory )
-tzbudiachro%cgroup     = ygroup
-tzbudiachro%cshape     = 'point'
-! tzbudiachro%cmask      = NOT SET (default values)
+tzbudiachro%lleveluse(NLVL_CATEGORY)    = .true.
+tzbudiachro%clevels  (NLVL_CATEGORY)    = 'Flyers'
+tzbudiachro%ccomments(NLVL_CATEGORY)    = 'Level for the different flyers (aircrafts and balloons)'
+
+tzbudiachro%lleveluse(NLVL_SUBCATEGORY) = .true.
+call Aircraft_balloon_longtype_get( tpflyer, tzbudiachro%clevels(NLVL_SUBCATEGORY) )
+tzbudiachro%ccomments(NLVL_SUBCATEGORY) = 'Level for the flyers of type: ' // Trim( tzbudiachro%clevels(NLVL_SUBCATEGORY) )
+
+tzbudiachro%lleveluse(NLVL_GROUP)       = .true.
+tzbudiachro%clevels  (NLVL_GROUP)       = Trim( ygroup )
+tzbudiachro%ccomments(NLVL_GROUP)       = 'Values for flyer ' // Trim( tpflyer%title )
+
+tzbudiachro%lleveluse(NLVL_SHAPE)       = .true.
+tzbudiachro%clevels  (NLVL_SHAPE)       = 'point'
+tzbudiachro%ccomments(NLVL_SHAPE)       = 'Values at position of flyer ' // Trim( tpflyer%title )
+
+tzbudiachro%lleveluse(NLVL_TIMEAVG)     = .false.
+tzbudiachro%clevels  (NLVL_TIMEAVG)     = ''
+tzbudiachro%ccomments(NLVL_TIMEAVG)     = ''
+
+tzbudiachro%lleveluse(NLVL_NORM)        = .false.
+tzbudiachro%clevels  (NLVL_NORM)        = ''
+tzbudiachro%ccomments(NLVL_NORM)        = ''
+
+tzbudiachro%lleveluse(NLVL_MASK)        = .false.
+tzbudiachro%clevels  (NLVL_MASK)        = ''
+tzbudiachro%ccomments(NLVL_MASK)        = ''
 tzbudiachro%lmobile    = .true.
 ! tzbudiachro%licompress = NOT SET (default values)
 ! tzbudiachro%ljcompress = NOT SET (default values)
@@ -895,12 +917,34 @@ tzfields(:)%ndimlist(4) = NMNHDIM_FLYER_TIME
 tzfields(:)%ndimlist(5) = NMNHDIM_UNUSED
 tzfields(:)%ndimlist(6) = NMNHDIM_FLYER_PROC
 
-tzbudiachro%ccomment   = 'Vertical profiles at position of flyer ' // Trim( tpflyer%title )
-! tzbudiachro%ccategory    =  !unchanged
-! tzbudiachro%csubcategory =  !unchanged
-tzbudiachro%cgroup     = ygroupz
-tzbudiachro%cshape     = 'vertical profile'
-! tzbudiachro%cmask      = NOT SET (default values)
+tzbudiachro%lleveluse(NLVL_CATEGORY)    = .true.
+tzbudiachro%clevels  (NLVL_CATEGORY)    = 'Flyers'
+tzbudiachro%ccomments(NLVL_CATEGORY)    = 'Level for the different flyers (aircrafts and balloons)'
+
+tzbudiachro%lleveluse(NLVL_SUBCATEGORY) = .true.
+call Aircraft_balloon_longtype_get( tpflyer, tzbudiachro%clevels(NLVL_SUBCATEGORY) )
+tzbudiachro%ccomments(NLVL_SUBCATEGORY) = 'Level for the flyers of type: ' // Trim( tzbudiachro%clevels(NLVL_SUBCATEGORY) )
+
+tzbudiachro%lleveluse(NLVL_GROUP)       = .true.
+tzbudiachro%clevels  (NLVL_GROUP)       = Trim( ygroupz )
+tzbudiachro%ccomments(NLVL_GROUP)       = 'Values for flyer ' // Trim( tpflyer%title )
+
+tzbudiachro%lleveluse(NLVL_SHAPE)       = .true.
+tzbudiachro%clevels  (NLVL_SHAPE)       = 'Vertical profile'
+tzbudiachro%ccomments(NLVL_SHAPE)       = 'Vertical profiles at position of flyer ' // Trim( tpflyer%title )
+
+tzbudiachro%lleveluse(NLVL_TIMEAVG)     = .false.
+tzbudiachro%clevels  (NLVL_TIMEAVG)     = 'Not time averaged'
+tzbudiachro%ccomments(NLVL_TIMEAVG)     = 'Values are not time averaged'
+
+tzbudiachro%lleveluse(NLVL_NORM)        = .false.
+tzbudiachro%clevels  (NLVL_NORM)        = 'Not normalized'
+tzbudiachro%ccomments(NLVL_NORM)        = 'Values are not normalized'
+
+tzbudiachro%lleveluse(NLVL_MASK)        = .false.
+tzbudiachro%clevels  (NLVL_MASK)        = ''
+tzbudiachro%ccomments(NLVL_MASK)        = ''
+
 tzbudiachro%lmobile    = .true.
 tzbudiachro%licompress = .true.
 tzbudiachro%ljcompress = .true.
diff --git a/src/MNH/write_budget.f90 b/src/MNH/write_budget.f90
index b8df852365e3b74c7d995606a0ee66df106d07cb..e87e4b0c68355cab9fca5ea1eab5be98daa22ab5 100644
--- a/src/MNH/write_budget.f90
+++ b/src/MNH/write_budget.f90
@@ -401,11 +401,12 @@ end subroutine Write_budget
 
 
 subroutine Store_one_budget_rho( tpdiafile, tpdates, tprhodj, knocompress, prhodjn )
-  use modd_budget,            only: cbutype,                                                      &
-                                    lbu_icp, lbu_jcp, lbu_kcp,                                    &
-                                    nbuil, nbuih, nbujl, nbujh, nbukl, nbukh,                     &
-                                    nbuimax, nbuimax_ll, nbujmax, nbujmax_ll, nbukmax, nbutshift, &
-                                    nbumask, nbusubwrite,                                         &
+  use modd_budget,            only: cbutype,                                                                                     &
+                                    lbu_icp, lbu_jcp, lbu_kcp,                                                                   &
+                                    nbuil, nbuih, nbujl, nbujh, nbukl, nbukh,                                                    &
+                                    nbuimax, nbuimax_ll, nbujmax, nbujmax_ll, nbukmax, nbutshift,                                &
+                                    nbumask, nbusubwrite,                                                                        &
+                                    NLVL_CATEGORY, NLVL_SUBCATEGORY, NLVL_GROUP, NLVL_SHAPE, NLVL_TIMEAVG, NLVL_NORM, NLVL_MASK, &
                                     tbudiachrometadata, tburhodata
   use modd_field,             only: NMNHDIM_BUDGET_CART_NI,    NMNHDIM_BUDGET_CART_NJ,   NMNHDIM_BUDGET_CART_NI_U, &
                                     NMNHDIM_BUDGET_CART_NJ_U,  NMNHDIM_BUDGET_CART_NI_V, NMNHDIM_BUDGET_CART_NJ_V, &
@@ -537,17 +538,47 @@ subroutine Store_one_budget_rho( tpdiafile, tpdates, tprhodj, knocompress, prhod
     tzfield%ndimlist(:) = NMNHDIM_UNKNOWN
   end if
 
-  tzbudiachro%ccomment   = tprhodj%ccomment
-  tzbudiachro%ccategory  = 'budget'
-! tzbudiachro%csubcategory  = NOT SET (default values)
-  tzbudiachro%cgroup     = 'RhodJ'
+  tzbudiachro%lleveluse(NLVL_CATEGORY)    = .true.
+  tzbudiachro%clevels  (NLVL_CATEGORY)    = 'Budgets'
+  tzbudiachro%ccomments(NLVL_CATEGORY)    = 'Level for the different budgets'
+
+  tzbudiachro%lleveluse(NLVL_SUBCATEGORY) = .false.
+  tzbudiachro%clevels  (NLVL_SUBCATEGORY) = ''
+  tzbudiachro%ccomments(NLVL_SUBCATEGORY) = ''
+
+  tzbudiachro%lleveluse(NLVL_GROUP)       = .true.
+  tzbudiachro%clevels  (NLVL_GROUP)       = 'RhodJ'
+  tzbudiachro%ccomments(NLVL_GROUP)       = ''
+
+  tzbudiachro%lleveluse(NLVL_SHAPE)       = .false.
+  if ( ybutype == 'CART' ) then
+    tzbudiachro%clevels  (NLVL_SHAPE)     = 'Cartesian'
+    tzbudiachro%ccomments(NLVL_SHAPE)     = 'cartesian domain'
+  else
+    tzbudiachro%clevels  (NLVL_SHAPE)     = 'Mask'
+    tzbudiachro%ccomments(NLVL_SHAPE)     = 'masked domain'
+  end if
+
+  tzbudiachro%lleveluse(NLVL_TIMEAVG)     = .false.
+  tzbudiachro%clevels  (NLVL_TIMEAVG)     = 'Time averaged'
+  tzbudiachro%ccomments(NLVL_TIMEAVG)     = 'Values are time averaged'
+
+  tzbudiachro%lleveluse(NLVL_NORM)        = .false.
+  tzbudiachro%clevels  (NLVL_NORM)        = 'Not normalized'
+  tzbudiachro%ccomments(NLVL_NORM)        = 'Values are not normalized'
+
+  tzbudiachro%lleveluse(NLVL_MASK)        = .false.
+  if ( ybutype == 'MASK' ) then
+    tzbudiachro%clevels  (NLVL_MASK)      = CMASK_VARNAME
+    tzbudiachro%ccomments(NLVL_MASK)      = ''
+  else
+    tzbudiachro%clevels  (NLVL_MASK)      = ''
+    tzbudiachro%ccomments(NLVL_MASK)      = ''
+  end if
+
   if ( ybutype == 'CART' ) then
-    tzbudiachro%cshape   = 'cartesian'
-    ! tzbudiachro%cmask    = NOT SET (default values)
     tzbudiachro%lmobile  = .false.
   else
-    tzbudiachro%cshape   = 'mask'
-    tzbudiachro%cmask    = CMASK_VARNAME
     !Masks are updated at each timestep (therefore the studied domains change during execution)
     tzbudiachro%lmobile  = .true.
   end if
@@ -576,6 +607,7 @@ subroutine Store_one_budget( tpdiafile, tpdates, tpbudget, prhodjn, knocompress,
                                     nbumask, nbusubwrite,                                                                         &
                                     NBUDGET_U, NBUDGET_V, NBUDGET_W, NBUDGET_TH, NBUDGET_TKE, NBUDGET_RV, NBUDGET_RC, NBUDGET_RR, &
                                     NBUDGET_RI, NBUDGET_RS, NBUDGET_RG, NBUDGET_RH, NBUDGET_SV1,                                  &
+                                    NLVL_CATEGORY, NLVL_SUBCATEGORY, NLVL_GROUP, NLVL_SHAPE, NLVL_TIMEAVG, NLVL_NORM, NLVL_MASK,  &
                                     tbudgetdata, tbudiachrometadata, tbugroupdata
   use modd_field,             only: NMNHDIM_BUDGET_CART_NI,    NMNHDIM_BUDGET_CART_NJ,   NMNHDIM_BUDGET_CART_NI_U, &
                                     NMNHDIM_BUDGET_CART_NJ_U,  NMNHDIM_BUDGET_CART_NI_V, NMNHDIM_BUDGET_CART_NJ_V, &
@@ -795,17 +827,47 @@ subroutine Store_one_budget( tpdiafile, tpdates, tpbudget, prhodjn, knocompress,
     end if
   end do
 
-  tzbudiachro%ccomment   = tpbudget%ccomment
-  tzbudiachro%ccategory  = 'budget'
-! tzbudiachro%csubcategory  = NOT SET (default values)
-  tzbudiachro%cgroup     = ygroup_name
+  tzbudiachro%lleveluse(NLVL_CATEGORY)    = .true.
+  tzbudiachro%clevels  (NLVL_CATEGORY)    = 'Budgets'
+  tzbudiachro%ccomments(NLVL_CATEGORY)    = 'Level for the different budgets'
+
+  tzbudiachro%lleveluse(NLVL_SUBCATEGORY) = .false.
+  tzbudiachro%clevels  (NLVL_SUBCATEGORY) = ''
+  tzbudiachro%ccomments(NLVL_SUBCATEGORY) = ''
+
+  tzbudiachro%lleveluse(NLVL_GROUP)       = .true.
+  tzbudiachro%clevels  (NLVL_GROUP)       = ygroup_name
+  tzbudiachro%ccomments(NLVL_GROUP)       = Trim( tpbudget%ccomment )
+
+  tzbudiachro%lleveluse(NLVL_SHAPE)       = .false.
+  if ( ybutype == 'CART' ) then
+    tzbudiachro%clevels  (NLVL_SHAPE)     = 'Cartesian'
+    tzbudiachro%ccomments(NLVL_SHAPE)     = 'Cartesian domain'
+  else
+    tzbudiachro%clevels  (NLVL_SHAPE)     = 'Mask'
+    tzbudiachro%ccomments(NLVL_SHAPE)     = 'Masked domain'
+  end if
+
+  tzbudiachro%lleveluse(NLVL_TIMEAVG)     = .false.
+  tzbudiachro%clevels  (NLVL_TIMEAVG)     = 'Time averaged'
+  tzbudiachro%ccomments(NLVL_TIMEAVG)     = 'Values are time averaged'
+
+  tzbudiachro%lleveluse(NLVL_NORM)        = .false.
+  tzbudiachro%clevels  (NLVL_NORM)        = 'Not normalized'
+  tzbudiachro%ccomments(NLVL_NORM)        = 'Values are not normalized'
+
+  tzbudiachro%lleveluse(NLVL_MASK)        = .false.
+  if ( ybutype == 'MASK' ) then
+    tzbudiachro%clevels  (NLVL_MASK)      = CMASK_VARNAME
+    tzbudiachro%ccomments(NLVL_MASK)      = ''
+  else
+    tzbudiachro%clevels  (NLVL_MASK)      = ''
+    tzbudiachro%ccomments(NLVL_MASK)      = ''
+  end if
+
   if ( ybutype == 'CART' ) then
-    tzbudiachro%cshape   = 'cartesian'
-    ! tzbudiachro%cmask    = NOT SET (default values)
     tzbudiachro%lmobile  = .false.
   else
-    tzbudiachro%cshape   = 'mask'
-    tzbudiachro%cmask    = CMASK_VARNAME
     !Masks are updated at each timestep (therefore the studied domains change during execution)
     tzbudiachro%lmobile  = .true.
   end if
diff --git a/src/MNH/write_diachro.f90 b/src/MNH/write_diachro.f90
index fe8308520df45d9865a7c3a066569fb034df930d..0290a970a1c4a05d86f1be60b6e6a0076fe0aae2 100644
--- a/src/MNH/write_diachro.f90
+++ b/src/MNH/write_diachro.f90
@@ -142,7 +142,7 @@ end subroutine Write_diachro
 subroutine Write_diachro_lfi( tpdiafile, tpbudiachro, tpfields, tpdates, pvar, tpflyer )
 
 use modd_aircraft_balloon, only: flyer
-use modd_budget,         only: nbumask, nbutshift, nbusubwrite, tbudiachrometadata
+use modd_budget,         only: NLVL_CATEGORY, NLVL_GROUP, NLVL_SHAPE, nbumask, nbutshift, nbusubwrite, tbudiachrometadata
 use modd_field,          only: NMNHDIM_ONE, NMNHDIM_UNKNOWN, NMNHDIM_FLYER_TIME, NMNHDIM_NOTLISTED, NMNHDIM_UNUSED, &
                                TYPECHAR, TYPEINT, TYPEREAL,                                                         &
                                tfield_metadata_base, tfielddata
@@ -208,8 +208,8 @@ ijh = tpbudiachro%njh
 ikl = tpbudiachro%nkl
 ikh = tpbudiachro%nkh
 
-ycategory = Trim( tpbudiachro%ccategory )
-yshape    = Trim( tpbudiachro%cshape    )
+ycategory = Trim( tpbudiachro%clevels(NLVL_CATEGORY) )
+yshape    = Trim( tpbudiachro%clevels(NLVL_SHAPE) )
 
 !For backward compatibility of LFI files
 if ( tpbudiachro%cdirection == 'I' ) then
@@ -226,15 +226,15 @@ tzfile%cformat = 'LFI'
 YCOMMENT='NOTHING'
 
 !Set ygroup to preserve backward compatibility of LFI files
-if (      Any( tpbudiachro%cgroup == [ 'UU', 'VV', 'WW', 'TH', 'TK', 'RV', 'RC', 'RR', 'RI', 'RS', 'RG', 'RH' ] ) &
-     .or.    ( tpbudiachro%cgroup(1:2) == 'SV' .and. Len_trim( tpbudiachro%cgroup ) == 5 )                      ) then
+if (      Any( tpbudiachro%clevels(NLVL_GROUP) == [ 'UU', 'VV', 'WW', 'TH', 'TK', 'RV', 'RC', 'RR', 'RI', 'RS', 'RG', 'RH' ] ) &
+     .or.    ( tpbudiachro%clevels(NLVL_GROUP)(1:2) == 'SV' .and. Len_trim( tpbudiachro%clevels(NLVL_GROUP) ) == 5 )         ) then
   Allocate( character(len=9) :: ygroup )
-  ygroup(:) = Trim( tpbudiachro%cgroup )
-  do ji = Len_trim( tpbudiachro%cgroup ) + 1, 5
+  ygroup(:) = Trim( tpbudiachro%clevels(NLVL_GROUP) )
+  do ji = Len_trim( tpbudiachro%clevels(NLVL_GROUP) ) + 1, 5
     ygroup(ji : ji) = '_'
   end do
   Write( ygroup(6:9), '( i4.4 )' ) nbutshift
-else if ( tpbudiachro%cgroup == 'RhodJ' ) then
+else if ( tpbudiachro%clevels(NLVL_GROUP) == 'RhodJ' ) then
   Allocate( character(len=9) :: ygroup )
 
   if ( tpfields(1)%cmnhname == 'RhodJX' ) then
@@ -246,8 +246,8 @@ else if ( tpbudiachro%cgroup == 'RhodJ' ) then
   else if ( tpfields(1)%cmnhname == 'RhodJS' ) then
     ygroup(1:3) = 'RJS'
   else
-    call Print_msg( NVERB_ERROR, 'IO', 'Write_diachro_lfi', &
-                    'unknown variable ' // Trim( tpfields(1)%cmnhname ) // ' for group ' // Trim( tpbudiachro%cgroup ) )
+    call Print_msg( NVERB_ERROR, 'IO', 'Write_diachro_lfi', 'unknown variable ' // Trim( tpfields(1)%cmnhname ) // &
+                    ' for group ' // Trim( tpbudiachro%clevels(NLVL_GROUP) ) )
   end if
 
   ygroup(4:5) = '__'
@@ -256,31 +256,31 @@ else if ( tpbudiachro%nsv > 0 ) then
   Allocate( character(len=9) :: ygroup )
   Write( ygroup, '( "SV", i3.3, i4.4 )' ) tpbudiachro%nsv, nbutshift
 else
-  ygroup = Trim( tpbudiachro%cgroup )
+  ygroup = Trim( tpbudiachro%clevels(NLVL_GROUP) )
 end if
 
 !Recompute old TYPE for backward compatibility
-if ( ycategory == 'budget' ) then
-  if ( yshape == 'cartesian' ) then
+if ( ycategory == 'Budgets' ) then
+  if ( yshape == 'Cartesian' ) then
     ytype = 'CART'
   else
     ytype = 'MASK'
   end if
-else if ( ycategory == 'LES' ) then
-  if ( yshape == 'cartesian' ) then
+else if ( ycategory == 'LES budgets' ) then
+  if ( yshape == 'Cartesian' ) then
     ytype = 'SSOL'
   else
     ytype = 'SPXY'
   end if
-else if ( ycategory == 'flyer' ) then
+else if ( ycategory == 'Flyers' ) then
   if ( yshape == 'point' ) then
     ytype = 'RSPL'
   else
     ytype = 'CART'
   end if
-else if ( ycategory == 'profiler' .or. ycategory == 'station' ) then
+else if ( ycategory == 'Profilers' .or. ycategory == 'Stations' ) then
   ytype = 'CART'
-else if ( ycategory == 'time series'  ) then
+else if ( ycategory == 'Time series'  ) then
   if ( tpbudiachro%licompress ) then
     ytype = 'CART'
   else
@@ -294,8 +294,8 @@ end if
 
 II = SIZE(PVAR,1)
 IJ = SIZE(PVAR,2)
-if ( ycategory == 'budget' .and. tpbudiachro%cshape == 'cartesian' &
-     .and. .not. tpbudiachro%licompress .and. .not. tpbudiachro%ljcompress     ) then
+if ( ycategory == 'Budgets' .and. tpbudiachro%clevels(NLVL_SHAPE) == 'Cartesian' &
+     .and. .not. tpbudiachro%licompress .and. .not. tpbudiachro%ljcompress       ) then
   II=iih-iil+1
   IJ=ijh-ijl+1
   gdistributed = .true.
@@ -317,7 +317,7 @@ IF ( PRESENT( tpflyer ) ) THEN
   IKTRAJX = 1
   ITTRAJX = SIZE( tpflyer%x )
   INTRAJX = 1
-ELSE IF ( ycategory == 'LES' .and.  tpbudiachro%cshape == 'cartesian' ) THEN
+ELSE IF ( ycategory == 'LES budgets' .and.  tpbudiachro%clevels(NLVL_SHAPE) == 'Cartesian' ) THEN
   IKTRAJX = 1
   ITTRAJX = 1
   INTRAJX = IN
@@ -326,7 +326,7 @@ IF ( PRESENT( tpflyer ) ) THEN
   IKTRAJY = 1
   ITTRAJY = SIZE( tpflyer%y )
   INTRAJY = 1
-ELSE IF ( ycategory == 'LES' .and.  tpbudiachro%cshape == 'cartesian' ) THEN
+ELSE IF ( ycategory == 'LES budgets' .and.  tpbudiachro%clevels(NLVL_SHAPE) == 'Cartesian' ) THEN
   IKTRAJY = 1
   ITTRAJY = 1
   INTRAJY = IN
@@ -335,14 +335,14 @@ IF ( PRESENT( tpflyer ) ) THEN
   IKTRAJZ = 1
   ITTRAJZ = SIZE( tpflyer%z )
   INTRAJZ = 1
-ELSE IF ( ycategory == 'LES' .and.  tpbudiachro%cshape == 'cartesian' ) THEN
+ELSE IF ( ycategory == 'LES budgets' .and.  tpbudiachro%clevels(NLVL_SHAPE) == 'Cartesian' ) THEN
   IKTRAJZ = IK
   ITTRAJZ = 1
   INTRAJZ = IN
 ENDIF
 
 IIMASK=0; IJMASK=0; IKMASK=0; ITMASK=0; INMASK=0; IPMASK=0
-IF ( tpbudiachro%cshape == 'mask' ) THEN
+IF ( tpbudiachro%clevels(NLVL_SHAPE) == 'Mask' ) THEN
 !     MASK is written outside this routine but the dimensions must be initialized
 !     the mask is defined on the extended domain
   CALL GET_GLOBALDIMS_ll (IIMAX_ll,IJMAX_ll)
@@ -403,7 +403,7 @@ SELECT CASE(YTYPE)
     ITABCHAR(16)=Merge( 1, 0, tpbudiachro%licompress )
     ITABCHAR(17)=Merge( 1, 0, tpbudiachro%ljcompress )
     ITABCHAR(18)=Merge( 1, 0, tpbudiachro%lkcompress )
-    IF( tpbudiachro%cshape == 'mask' )THEN
+    IF( tpbudiachro%clevels(NLVL_SHAPE) == 'Mask' )THEN
 !     ITABCHAR(10)=1; ITABCHAR(11)=1
 !     ITABCHAR(13)=1; ITABCHAR(14)=1
       ITABCHAR(16)=1; ITABCHAR(17)=1
@@ -598,7 +598,7 @@ IF(PRESENT(tpflyer))THEN
   TZFIELD%NDIMS      = 3
   TZFIELD%LTIMEDEP   = .FALSE.
   CALL IO_Field_write(tzfile,TZFIELD, Reshape( tpflyer%x, [1, Size( tpflyer%x), 1] ) )
-ELSE IF ( ycategory == 'LES' .and.  tpbudiachro%cshape == 'cartesian' ) THEN
+ELSE IF ( ycategory == 'LES budgets' .and.  tpbudiachro%clevels(NLVL_SHAPE) == 'Cartesian' ) THEN
   TZFIELD%CMNHNAME   = TRIM(ygroup)//'.TRAJX'
   TZFIELD%CSTDNAME   = ''
   TZFIELD%CLONGNAME  = TRIM(ygroup)//'.TRAJX'
@@ -629,7 +629,7 @@ IF(PRESENT(tpflyer))THEN
   TZFIELD%NDIMS      = 3
   TZFIELD%LTIMEDEP   = .FALSE.
   CALL IO_Field_write(tzfile,TZFIELD, Reshape( tpflyer%y, [1, Size( tpflyer%y), 1] ) )
-ELSE IF ( ycategory == 'LES' .and.  tpbudiachro%cshape == 'cartesian' ) THEN
+ELSE IF ( ycategory == 'LES budgets' .and.  tpbudiachro%clevels(NLVL_SHAPE) == 'Cartesian' ) THEN
   TZFIELD%CMNHNAME   = TRIM(ygroup)//'.TRAJY'
   TZFIELD%CSTDNAME   = ''
   TZFIELD%CLONGNAME  = TRIM(ygroup)//'.TRAJY'
@@ -660,7 +660,7 @@ IF(PRESENT(tpflyer))THEN
   TZFIELD%NDIMS      = 3
   TZFIELD%LTIMEDEP   = .FALSE.
   CALL IO_Field_write(tzfile,TZFIELD, Reshape( tpflyer%z, [1, Size( tpflyer%z), 1] ) )
-ELSE IF ( ycategory == 'LES' .and.  tpbudiachro%cshape == 'cartesian' ) THEN
+ELSE IF ( ycategory == 'LES budgets' .and.  tpbudiachro%clevels(NLVL_SHAPE) == 'Cartesian' ) THEN
   TZFIELD%CMNHNAME   = TRIM(ygroup)//'.TRAJZ'
   TZFIELD%CSTDNAME   = ''
   TZFIELD%CLONGNAME  = TRIM(ygroup)//'.TRAJZ'
@@ -729,7 +729,10 @@ subroutine Write_diachro_nc4( tpdiafile, tpbudiachro, tpfields, pvar, osplit, tp
 use NETCDF,                only: NF90_DEF_DIM, NF90_NOERR
 
 use modd_aircraft_balloon, only: flyer
-use modd_budget,           only: CNOTSET, nbutshift, nbusubwrite, tbudiachrometadata
+use modd_budget,           only: CNCGROUPNAMES,                                                      &
+                                 NMAXLEVELS, NLVL_ROOT, NLVL_CATEGORY, NLVL_SUBCATEGORY, NLVL_GROUP, &
+                                 NLVL_SHAPE, NLVL_TIMEAVG, NLVL_NORM, NLVL_MASK,                     &
+                                 nbutshift, nbusubwrite, tbudiachrometadata
 use modd_conf,             only: lcartesian
 use modd_field
 use modd_io,               only: isp, tfiledata
@@ -741,24 +744,6 @@ use modd_type_date,        only: date_time
 use mode_io_field_write,   only: IO_Field_create, IO_Field_write, IO_Field_write_box
 use mode_io_tools_nc4,     only: IO_Err_handle_nc4
 
-integer, parameter :: NMAXLEVELS       = 7
-integer, parameter :: NLVL_ROOT        = 0
-integer, parameter :: NLVL_CATEGORY    = 1
-integer, parameter :: NLVL_SUBCATEGORY = 2
-integer, parameter :: NLVL_GROUP       = 3
-integer, parameter :: NLVL_SHAPE       = 4
-integer, parameter :: NLVL_TIMEAVG     = 5
-integer, parameter :: NLVL_NORM        = 6
-integer, parameter :: NLVL_MASK        = 7
-character(len=*), dimension(NMAXLEVELS), parameter :: CNCGROUPNAMES = [ &
-                                         'category   ', &  !Name of the different type of groups/levels in the netCDF file
-                                         'subcategory', &
-                                         'group      ', &
-                                         'shape      ', &
-                                         'timeavg    ', &
-                                         'norm       ', &
-                                         'mask       '  ]
-
 type(tfiledata),                                     intent(in)           :: tpdiafile        ! File to write
 type(tbudiachrometadata),                            intent(in)           :: tpbudiachro
 class(tfield_metadata_base), dimension(:),           intent(in)           :: tpfields
@@ -770,10 +755,7 @@ character(len=:), allocatable :: ycategory
 character(len=:), allocatable :: ylevelname
 character(len=:), allocatable :: ylevels
 character(len=:), allocatable :: yshape
-character(len=:), allocatable :: ygroup
 character(len=:), allocatable :: ystdnameprefix
-character(len=NBUNAMELGTMAX),  dimension(NMAXLEVELS) :: ylevelnames !Name of the different groups/levels in the netCDF file
-character(len=NCOMMENTLGTMAX), dimension(NMAXLEVELS) :: ylevelcomments !Comments for the different groups/levels in the netCDF file
 integer                                       :: iil, iih, ijl, ijh, ikl, ikh
 integer                                       :: idims
 integer                                       :: icount
@@ -787,7 +769,6 @@ integer(kind=CDFINT)                          :: ilevelid
 integer(kind=CDFINT), dimension(0:NMAXLEVELS) :: ilevelids ! ids of the different groups/levels in the netCDF file
 logical                                       :: gdistributed
 logical                                       :: gsplit
-logical(kind=CDFINT), dimension(NMAXLEVELS)   :: gleveluse ! Are the different groups/levels in the netCDF file used?
 logical(kind=CDFINT), dimension(0:NMAXLEVELS) :: gleveldefined ! Are the different groups/levels already defined in the netCDF file
 type(tfielddata)                              :: tzfield
 type(tfiledata)                               :: tzfile
@@ -799,9 +780,8 @@ tzfile = tpdiafile
 !Write only in netCDF files
 tzfile%cformat = 'NETCDF4'
 
-ycategory = Trim( tpbudiachro%ccategory  )
-yshape    = Trim( tpbudiachro%cshape     )
-ygroup    = Trim( tpbudiachro%cgroup )
+ycategory = Trim( tpbudiachro%clevels(NLVL_CATEGORY)  )
+yshape    = Trim( tpbudiachro%clevels(NLVL_SHAPE) )
 
 iil = tpbudiachro%nil
 iih = tpbudiachro%nih
@@ -810,8 +790,8 @@ ijh = tpbudiachro%njh
 ikl = tpbudiachro%nkl
 ikh = tpbudiachro%nkh
 
-if ( ycategory == 'budget' .and. yshape == 'cartesian' &
-     .and. .not. tpbudiachro%licompress .and. .not. tpbudiachro%ljcompress     ) then
+if ( ycategory == 'Budgets' .and. yshape == 'Cartesian' &
+     .and. .not. tpbudiachro%licompress .and. .not. tpbudiachro%ljcompress ) then
   gdistributed = .true.
 else
   !By default data is already collected on the write process for budgets
@@ -827,174 +807,11 @@ end if
 MASTER: if ( isp == tzfile%nmaster_rank) then
   ilevelids(NLVL_ROOT) = tzfile%nncid
 
-  gleveldefined(NLVL_ROOT) = .false.
-
-  gleveldefined(NLVL_CATEGORY) = .false.
-  gleveldefined(NLVL_SUBCATEGORY) = .false.
-  gleveldefined(NLVL_GROUP)    = .false.
-  gleveldefined(NLVL_SHAPE)    = .false.
-  gleveldefined(NLVL_TIMEAVG)  = .false.
-  gleveldefined(NLVL_NORM)     = .false.
-  gleveldefined(NLVL_MASK)     = .false.
-
-  ylevelnames(:)    = ''
-  ylevelcomments(:) = ''
-
-  select case ( ycategory )
-    case ( 'budget' )
-      gleveluse(NLVL_CATEGORY)  = .true.
-      ylevelnames(NLVL_CATEGORY) = 'Budgets'
-      ylevelcomments(NLVL_CATEGORY) = 'Group for the different budgets'
-
-      gleveluse(NLVL_SUBCATEGORY) = .false.
-
-      gleveluse(NLVL_GROUP)    = .true.
-      ylevelnames(NLVL_GROUP)   = Trim( tpbudiachro%cgroup )
-
-      gleveluse(NLVL_SHAPE)    = .false.
-      ylevelnames(NLVL_SHAPE)   = Trim( tpbudiachro%cshape )
-
-      gleveluse(NLVL_TIMEAVG)  = .false.
-      if ( tpbudiachro%ltcompress ) then
-        ylevelnames(NLVL_TIMEAVG) = 'time averaged'
-      else
-        ylevelnames(NLVL_TIMEAVG) = 'not time averaged'
-      end if
-
-      gleveluse(NLVL_NORM)     = .false.
-      if ( tpbudiachro%lnorm ) then
-        ylevelnames(NLVL_NORM) = 'normalized'
-      else
-        ylevelnames(NLVL_NORM) = 'not normalized'
-      end if
-
-      gleveluse(NLVL_MASK)     = .false.
-      ylevelnames(NLVL_MASK)    = tpbudiachro%cmask
-
-    case ( 'LES' )
-      gleveluse(NLVL_CATEGORY)  = .true.
-      ylevelnames(NLVL_CATEGORY) = 'LES budgets'
-      ylevelcomments(NLVL_CATEGORY) = 'Group for the different LES budgets'
-
-      gleveluse(NLVL_SUBCATEGORY) = .false.
-      gleveluse(NLVL_GROUP)    = .false.
-
-      gleveluse(NLVL_SHAPE)    = .true.
-      ylevelnames(NLVL_SHAPE)   = Trim( tpbudiachro%cshape )
-
-      gleveluse(NLVL_TIMEAVG)   = .true.
-      if ( tpbudiachro%ltcompress ) then
-        ylevelnames(NLVL_TIMEAVG) = 'time averaged'
-      else
-        ylevelnames(NLVL_TIMEAVG) = 'not time averaged'
-      end if
-
-      gleveluse(NLVL_NORM)     = .true.
-      if ( tpbudiachro%lnorm ) then
-        ylevelnames(NLVL_NORM) = 'normalized'
-      else
-        ylevelnames(NLVL_NORM) = 'not normalized'
-      end if
-
-      if ( tpbudiachro%cshape == 'cartesian' ) then
-       if ( tpbudiachro%cmask == CNOTSET ) then
-          call Print_msg( NVERB_WARNING, 'IO', 'Write_diachro_nc4', 'mask not set for ' // ygroup  )
-          gleveluse(NLVL_MASK) = .false.
-        else
-          gleveluse(NLVL_MASK)  = .true.
-          ylevelnames(NLVL_MASK) = tpbudiachro%cmask
-        end if
-      else
-        gleveluse(NLVL_MASK)     = .false.
-      end if
-
-    case ( 'profiler' )
-      gleveluse(NLVL_CATEGORY)  = .true.
-      ylevelnames(NLVL_CATEGORY) = 'Profilers'
-      ylevelcomments(NLVL_CATEGORY) = 'Group for the different vertical profilers'
-
-      gleveluse(NLVL_SUBCATEGORY) = .false.
-
-      gleveluse(NLVL_GROUP)    = .true.
-      ylevelnames(NLVL_GROUP)   = Trim( tpbudiachro%cgroup )
-!       ylevelcomments(NLVL_GROUP) =
-
-      gleveluse(NLVL_SHAPE)    = .false.
-      ylevelnames(NLVL_SHAPE)   = Trim( tpbudiachro%cshape )
-
-      gleveluse(NLVL_TIMEAVG)  = .false.
-      gleveluse(NLVL_NORM)     = .false.
-      gleveluse(NLVL_MASK)     = .false.
-
-    case ( 'station' )
-      gleveluse(NLVL_CATEGORY)  = .true.
-      ylevelnames(NLVL_CATEGORY) = 'Stations'
-      ylevelcomments(NLVL_CATEGORY) = 'Group for the different stations'
-
-      gleveluse(NLVL_SUBCATEGORY) = .false.
-
-      gleveluse(NLVL_GROUP)    = .true.
-      ylevelnames(NLVL_GROUP)   = Trim( tpbudiachro%cgroup )
-
-      gleveluse(NLVL_SHAPE)    = .false.
-      ylevelnames(NLVL_SHAPE)   = Trim( tpbudiachro%cshape )
-
-      gleveluse(NLVL_TIMEAVG)  = .false.
-      gleveluse(NLVL_NORM)     = .false.
-      gleveluse(NLVL_MASK)     = .false.
-
-    case( 'flyer' )
-      gleveluse(NLVL_CATEGORY)  = .true.
-      ylevelnames(NLVL_CATEGORY) = 'Flyers'
-      ylevelcomments(NLVL_CATEGORY) = 'Group for the different flyers (aircrafts and balloons)'
-
-      gleveluse(NLVL_SUBCATEGORY) = .true.
-      ylevelnames(NLVL_SUBCATEGORY) = tpbudiachro%csubcategory
-      ylevelcomments(NLVL_SUBCATEGORY) = 'Group for the different ' // Trim( ycategory ) // 's'
-
-      gleveluse(NLVL_GROUP)    = .true.
-      ylevelnames(NLVL_GROUP)   = Trim( tpbudiachro%cgroup )
-
-      gleveluse(NLVL_SHAPE)    = .true.
-      ylevelnames(NLVL_SHAPE) = Trim( tpbudiachro%cshape )
-
-      gleveluse(NLVL_TIMEAVG)  = .false.
-
-      gleveluse(NLVL_NORM)     = .false.
-
-      gleveluse(NLVL_MASK)     = .false.
-
-    case ( 'time series' )
-      gleveluse(NLVL_CATEGORY)  = .true.
-      ylevelnames(NLVL_CATEGORY) = 'Time series'
-      ylevelcomments(NLVL_CATEGORY) = 'Group for the different time series'
-
-      gleveluse(NLVL_SUBCATEGORY) = .false.
-
-      gleveluse(NLVL_GROUP)    = .true.
-      ylevelnames(NLVL_GROUP)   = Trim( tpbudiachro%cgroup )
-
-      gleveluse(NLVL_SHAPE)    = .false.
-      ylevelnames(NLVL_SHAPE)   = Trim( tpbudiachro%cshape )
-
-      gleveluse(NLVL_TIMEAVG)  = .false.
-      gleveluse(NLVL_NORM)     = .false.
-
-      if ( Trim( tpbudiachro%cgroup ) == 'TSERIES' .or. Trim( tpbudiachro%cgroup ) == 'ZTSERIES' ) then
-        gleveluse(NLVL_MASK)   = .true.
-        ylevelnames(NLVL_MASK)  = tpbudiachro%cmask
-      else
-        gleveluse(NLVL_MASK)     = .false.
-      end if
-
-    case default
-      call Print_msg( NVERB_ERROR, 'IO', 'Write_diachro_nc4', 'unknown category ' // ycategory // ' for group ' // ygroup )
-      return
-  end select
+  gleveldefined(:) = .false.
 
   do jl = 1, NMAXLEVELS
-    call Move_to_next_level( ilevelids(jl-1), gleveldefined(jl-1), gleveluse(jl), &
-                           ylevelnames(jl), gleveldefined(jl), ilevelids(jl) )
+    call Move_to_next_level( ilevelids(jl-1), gleveldefined(jl-1), tpbudiachro%lleveluse(jl), &
+                           tpbudiachro%clevels(jl), gleveldefined(jl), ilevelids(jl) )
   end do
 
   tzfile%nncid = ilevelids(NLVL_MASK)
@@ -1003,77 +820,77 @@ MASTER: if ( isp == tzfile%nmaster_rank) then
 
   do jl = NMAXLEVELS, 1, -1
     ylevels = Trim( CNCGROUPNAMES(jl) ) // ' ' // ylevels
-    if ( gleveluse(jl) ) then
-      call Att_write( ylevelnames(jl), ilevelids(jl), 'levels', Trim( ylevels ) )
+    if ( tpbudiachro%lleveluse(jl) ) then
+      call Att_write( tpbudiachro%clevels(jl), ilevelids(jl), 'levels', Trim( ylevels ) )
       ylevels = ''
     end if
   end do
 
   if ( .not. gleveldefined(NLVL_CATEGORY) ) then
-    ylevelname = ylevelnames(NLVL_CATEGORY)
+    ylevelname = tpbudiachro%clevels(NLVL_CATEGORY)
     ilevelid   = ilevelids  (NLVL_CATEGORY)
 
     call Att_write( ylevelname, ilevelid, 'category', ylevelname )
-    if ( gleveluse(NLVL_CATEGORY) .and. Len_trim( ylevelcomments(NLVL_CATEGORY) ) > 0 ) &
-    call Att_write( ylevelname, ilevelid, 'comment',  ylevelcomments(NLVL_CATEGORY) )
+    if ( tpbudiachro%lleveluse(NLVL_CATEGORY) .and. Len_trim( tpbudiachro%ccomments(NLVL_CATEGORY) ) > 0 ) &
+    call Att_write( ylevelname, ilevelid, 'comment',  tpbudiachro%ccomments(NLVL_CATEGORY) )
 
-    if ( ycategory == 'LES' ) &
+    if ( ycategory == 'LES budgets' ) &
     call Att_write( ylevelname, ilevelid, 'temporal sampling frequency', xles_temp_sampling )
   end if
 
   if ( .not. gleveldefined(NLVL_SUBCATEGORY) ) then
-    ylevelname = ylevelnames(NLVL_SUBCATEGORY)
+    ylevelname = tpbudiachro%clevels(NLVL_SUBCATEGORY)
     ilevelid   = ilevelids  (NLVL_SUBCATEGORY)
 
     call Att_write( ylevelname, ilevelid, 'subcategory', ylevelname )
-    if ( gleveluse(NLVL_SUBCATEGORY) .and. Len_trim( ylevelcomments(NLVL_SUBCATEGORY) ) > 0 ) &
-    call Att_write( ylevelname, ilevelid, 'comment',     ylevelcomments(NLVL_SUBCATEGORY) )
+    if ( tpbudiachro%lleveluse(NLVL_SUBCATEGORY) .and. Len_trim( tpbudiachro%ccomments(NLVL_SUBCATEGORY) ) > 0 ) &
+    call Att_write( ylevelname, ilevelid, 'comment',     tpbudiachro%ccomments(NLVL_SUBCATEGORY) )
   end if
 
   if ( .not. gleveldefined(NLVL_GROUP) ) then
-    ylevelname = ylevelnames(NLVL_GROUP)
+    ylevelname = tpbudiachro%clevels(NLVL_GROUP)
     ilevelid   = ilevelids  (NLVL_GROUP)
 
     call Att_write( ylevelname, ilevelid, 'group',   ylevelname )
-    if ( gleveluse(NLVL_GROUP) .and. Len_trim( ylevelcomments(NLVL_GROUP) ) > 0 ) &
-    call Att_write( ylevelname, ilevelid, 'comment', ylevelcomments(NLVL_GROUP) )
+    if ( tpbudiachro%lleveluse(NLVL_GROUP) .and. Len_trim( tpbudiachro%ccomments(NLVL_GROUP) ) > 0 ) &
+    call Att_write( ylevelname, ilevelid, 'comment', tpbudiachro%ccomments(NLVL_GROUP) )
   end if
 
   if ( .not. gleveldefined(NLVL_SHAPE) ) then
-    ylevelname = ylevelnames(NLVL_SHAPE)
+    ylevelname = tpbudiachro%clevels(NLVL_SHAPE)
     ilevelid   = ilevelids  (NLVL_SHAPE)
 
     call Att_write( ylevelname, ilevelid, 'shape',   ylevelname )
-    if ( gleveluse(NLVL_SHAPE) .and. Len_trim( ylevelcomments(NLVL_SHAPE) ) > 0 ) &
-    call Att_write( ylevelname, ilevelid, 'comment', ylevelcomments(NLVL_SHAPE) )
+    if ( tpbudiachro%lleveluse(NLVL_SHAPE) .and. Len_trim( tpbudiachro%ccomments(NLVL_SHAPE) ) > 0 ) &
+    call Att_write( ylevelname, ilevelid, 'comment', tpbudiachro%ccomments(NLVL_SHAPE) )
 
     call Att_write( ylevelname, ilevelid, 'moving', Merge( 'yes', 'no ', tpbudiachro%lmobile ) )
 
-    if (      ( ycategory == 'budget' .and. yshape == 'cartesian' ) &
-         .or. ycategory == 'LES'                                    &
-         .or. tpbudiachro%cgroup      == 'TSERIES'                  &
-         .or. tpbudiachro%cgroup      == 'ZTSERIES'                 &
-         .or. tpbudiachro%cgroup(1:8) == 'XTSERIES'                 ) then
+    if (      ( ycategory == 'Budgets' .and. yshape == 'Cartesian' )             &
+         .or. ycategory == 'LES budgets'                                         &
+         .or. tpbudiachro%clevels(NLVL_GROUP)      == 'TSERIES'                  &
+         .or. tpbudiachro%clevels(NLVL_GROUP)      == 'ZTSERIES'                 &
+         .or. tpbudiachro%clevels(NLVL_GROUP)(1:8) == 'XTSERIES'                 ) then
       call Att_write( ylevelname, ilevelid, 'min I index in physical domain', iil )
       call Att_write( ylevelname, ilevelid, 'max I index in physical domain', iih )
       call Att_write( ylevelname, ilevelid, 'min J index in physical domain', ijl )
       call Att_write( ylevelname, ilevelid, 'max J index in physical domain', ijh )
     end if
 
-    if (      ( ycategory == 'budget' .and. yshape == 'cartesian' ) &
-         .or. tpbudiachro%cgroup      == 'TSERIES'                &
-         .or. tpbudiachro%cgroup      == 'ZTSERIES'               &
-         .or. tpbudiachro%cgroup(1:8) == 'XTSERIES'               ) then
+    if (      ( ycategory == 'Budgets' .and. yshape == 'Cartesian' )           &
+         .or. tpbudiachro%clevels(NLVL_GROUP)      == 'TSERIES'                &
+         .or. tpbudiachro%clevels(NLVL_GROUP)      == 'ZTSERIES'               &
+         .or. tpbudiachro%clevels(NLVL_GROUP)(1:8) == 'XTSERIES'               ) then
       call Att_write( ylevelname, ilevelid, 'min K index in physical domain', ikl )
       call Att_write( ylevelname, ilevelid, 'max K index in physical domain', ikh )
     end if
 
 
-    if (      ( ycategory == 'budget' .and. yshape == 'cartesian' ) &
-         .or. ( ycategory == 'LES'    .and. yshape == 'cartesian' ) &
-         .or. tpbudiachro%cgroup      == 'TSERIES'                &
-         .or. tpbudiachro%cgroup      == 'ZTSERIES'               &
-         .or. tpbudiachro%cgroup(1:8) == 'XTSERIES'               ) then
+    if (      ( ycategory == 'Budgets' .and. yshape == 'Cartesian' )           &
+         .or. ( ycategory == 'LES budgets'    .and. yshape == 'Cartesian' )    &
+         .or. tpbudiachro%clevels(NLVL_GROUP)      == 'TSERIES'                &
+         .or. tpbudiachro%clevels(NLVL_GROUP)      == 'ZTSERIES'               &
+         .or. tpbudiachro%clevels(NLVL_GROUP)(1:8) == 'XTSERIES'               ) then
       call Att_write( ylevelname, ilevelid, &
                       'averaged in the I direction', Merge( 'yes', 'no ', tpbudiachro%licompress ) )
       call Att_write( ylevelname, ilevelid, &
@@ -1084,25 +901,25 @@ MASTER: if ( isp == tzfile%nmaster_rank) then
   end if
 
   if ( .not. gleveldefined(NLVL_TIMEAVG) ) then
-    ylevelname = ylevelnames(NLVL_TIMEAVG)
+    ylevelname = tpbudiachro%clevels(NLVL_TIMEAVG)
     ilevelid   = ilevelids  (NLVL_TIMEAVG)
 
-    if ( gleveluse(NLVL_TIMEAVG) .and. Len_trim( ylevelcomments(NLVL_TIMEAVG) ) > 0 ) &
-    call Att_write( ylevelname, ilevelid, 'comment',        ylevelcomments(NLVL_TIMEAVG) )
+    if ( tpbudiachro%lleveluse(NLVL_TIMEAVG) .and. Len_trim( tpbudiachro%ccomments(NLVL_TIMEAVG) ) > 0 ) &
+    call Att_write( ylevelname, ilevelid, 'comment',        tpbudiachro%ccomments(NLVL_TIMEAVG) )
 
     call Att_write( ylevelname, ilevelid, 'time averaged', Merge( 'yes', 'no ', tpbudiachro%ltcompress ) )
   end if
 
   if ( .not. gleveldefined(NLVL_NORM) ) then
-    ylevelname = ylevelnames(NLVL_NORM)
+    ylevelname = tpbudiachro%clevels(NLVL_NORM)
     ilevelid   = ilevelids  (NLVL_NORM)
 
-    if ( gleveluse(NLVL_NORM) .and. Len_trim( ylevelcomments(NLVL_NORM) ) > 0 ) &
-    call Att_write( ylevelname, ilevelid, 'comment',   ylevelcomments(NLVL_NORM) )
+    if ( tpbudiachro%lleveluse(NLVL_NORM) .and. Len_trim( tpbudiachro%ccomments(NLVL_NORM) ) > 0 ) &
+    call Att_write( ylevelname, ilevelid, 'comment',   tpbudiachro%ccomments(NLVL_NORM) )
 
     call Att_write( ylevelname, ilevelid, 'normalized', Merge( 'yes', 'no ', tpbudiachro%lnorm ) )
 
-    if ( ycategory == 'LES' .and. yshape == 'cartesian' ) then
+    if ( ycategory == 'LES budgets' .and. yshape == 'Cartesian' ) then
       if ( tpbudiachro%lnorm ) then
         if ( cles_norm_type == 'NONE' ) then
           call Att_write( ylevelname, ilevelid, 'normalization', 'none' )
@@ -1118,7 +935,7 @@ MASTER: if ( isp == tzfile%nmaster_rank) then
           call Att_write( ylevelname, ilevelid, 'normalization', 'Monin-Obukhov' )
         else
           call Print_msg( NVERB_WARNING, 'IO', 'Write_diachro_nc4', Trim( tzfile%cname ) // &
-                          ': group ' // Trim( ygroup ) // ': unknown normalization' )
+                          ': group ' // Trim( tpbudiachro%clevels(NLVL_GROUP) ) // ': unknown normalization' )
           call Att_write( ylevelname, ilevelid, 'normalization', 'unknown' )
         end if
       else
@@ -1128,20 +945,18 @@ MASTER: if ( isp == tzfile%nmaster_rank) then
   end if
 
   if ( .not. gleveldefined(NLVL_MASK) ) then
-    ylevelname = ylevelnames(NLVL_MASK)
+    ylevelname = tpbudiachro%clevels(NLVL_MASK)
     ilevelid   = ilevelids  (NLVL_MASK)
 
     call Att_write( ylevelname, ilevelid, 'mask',    ylevelname )
-    if ( gleveluse(NLVL_MASK) .and. Len_trim( ylevelcomments(NLVL_MASK) ) > 0 ) &
-    call Att_write( ylevelname, ilevelid, 'comment', ylevelcomments(NLVL_MASK) )
+    if ( tpbudiachro%lleveluse(NLVL_MASK) .and. Len_trim( tpbudiachro%ccomments(NLVL_MASK) ) > 0 ) &
+    call Att_write( ylevelname, ilevelid, 'comment', tpbudiachro%ccomments(NLVL_MASK) )
 
-    if ( ycategory == 'budget' .and. yshape == 'mask' ) &
-    call Att_write( ylevelname, ilevelid, 'masks are stored in variable', tpbudiachro%cmask )
+    if ( ycategory == 'Budgets' .and. yshape == 'Mask' ) &
+    call Att_write( ylevelname, ilevelid, 'masks are stored in variable', tpbudiachro%clevels(NLVL_MASK) )
   end if
 
 
-
-
 end if MASTER
 
 
@@ -1182,7 +997,7 @@ do jp = 2, Size( tpfields )
 end do
 
 !Check that if cartesian and no horizontal compression, parameters are as expected
-if ( yshape == 'cartesian' .and. .not. tpbudiachro%licompress .and. .not. tpbudiachro%ljcompress ) then
+if ( yshape == 'Cartesian' .and. .not. tpbudiachro%licompress .and. .not. tpbudiachro%ljcompress ) then
   icorr = Merge( 1, 0, tpbudiachro%lkcompress )
   if ( ( idims + icorr ) /= 3 .and. ( idims + icorr ) /= 4 ) then
     call Print_msg( NVERB_ERROR, 'IO', 'Write_diachro_nc4',                                                            &
@@ -1617,7 +1432,7 @@ end  subroutine Write_diachro_nc4
 
 subroutine Diachro_one_field_write_nc4( tpfile, tpbudiachro, tpfield, pvar, kdims, osplit, odistributed, &
                                         kil, kih, kjl, kjh, kkl, kkh )
-use modd_budget,      only: nbutshift, nbusubwrite, tbudiachrometadata
+use modd_budget,      only: NLVL_CATEGORY, NLVL_GROUP, NLVL_SHAPE, nbutshift, nbusubwrite, tbudiachrometadata
 use modd_field,       only: tfielddata, tfield_metadata_base
 use modd_io,          only: isp, tfiledata
 use modd_parameters,  only: jphext
@@ -1656,7 +1471,7 @@ if ( odistributed ) then
     call Print_msg( NVERB_FATAL, 'IO', 'Diachro_one_field_write_nc4',                                &
                    'odistributed=.true. not allowed for dims/=3, field: ' //Trim( tzfield%cmnhname ) )
 
-  if ( tpbudiachro%cshape /= 'cartesian' )                                                                    &
+  if ( tpbudiachro%clevels(NLVL_SHAPE) /= 'Cartesian' )                                                                    &
     call Print_msg( NVERB_FATAL, 'IO', 'Diachro_one_field_write_nc4',                                         &
                    'odistributed=.true. not allowed for shape/=cartesian, field: ' //Trim( tzfield%cmnhname ) )
 end if
@@ -1666,7 +1481,7 @@ if ( osplit ) then
     call Print_msg( NVERB_FATAL, 'IO', 'Diachro_one_field_write_nc4',                                       &
                                  'osplit=.true. not allowed for dims>3, field: ' //Trim( tzfield%cmnhname ) )
 
-  if ( tpbudiachro%ccategory /= 'budget' )                                                               &
+  if ( tpbudiachro%clevels(NLVL_CATEGORY) /= 'Budgets' )                                                  &
     call Print_msg( NVERB_FATAL, 'IO', 'Diachro_one_field_write_nc4',                                    &
                     'osplit=.true. not allowed for category/=budget, field: ' //Trim( tzfield%cmnhname ) )
 end if
@@ -2092,7 +1907,7 @@ use mode_io_tools_nc4, only: IO_Err_handle_nc4
 integer(kind=CDFINT), intent(in)    :: kpreviouslevelid
 logical,              intent(in)    :: gpreviousleveldefined
 logical,              intent(in)    :: oleveluse
-character(len=*),     intent(inout) :: hlevelname
+character(len=*),     intent(in)    :: hlevelname
 logical,              intent(out)   :: gleveldefined
 integer(kind=CDFINT), intent(out)   :: klevelid
 
@@ -2111,7 +1926,6 @@ if ( oleveluse ) then
   end if
 else
   gleveldefined = gpreviousleveldefined
-  if ( Len_trim( hlevelname ) == 0 ) hlevelname = '(unused)'
   klevelid = kpreviouslevelid
 end if
 
diff --git a/src/MNH/write_profilern.f90 b/src/MNH/write_profilern.f90
index 7a9e728fb89184263ef7af7eec52235f62947fb2..4393ffa9e8e149057fefd8d9567ea7304694c015 100644
--- a/src/MNH/write_profilern.f90
+++ b/src/MNH/write_profilern.f90
@@ -127,7 +127,8 @@ CONTAINS
 !----------------------------------------------------------------------------
 SUBROUTINE PROFILER_DIACHRO_n(TPROFILER,II)
 
-use modd_budget, only: tbudiachrometadata
+use modd_budget, only: NLVL_CATEGORY, NLVL_SUBCATEGORY, NLVL_GROUP, NLVL_SHAPE, NLVL_TIMEAVG, NLVL_NORM, NLVL_MASK,  &
+                       tbudiachrometadata
 use modd_field,  only: NMNHDIM_LEVEL, NMNHDIM_PROFILER_TIME, NMNHDIM_PROFILER_PROC, NMNHDIM_UNUSED, &
                        tfield_metadata_base, TYPEREAL
 
@@ -650,12 +651,34 @@ tzfields(:)%ndimlist(4) = NMNHDIM_PROFILER_TIME
 tzfields(:)%ndimlist(5) = NMNHDIM_UNUSED
 tzfields(:)%ndimlist(6) = NMNHDIM_PROFILER_PROC
 
-tzbudiachro%ccomment   = 'Vertical profiles at position of profiler ' // Trim( ygroup )
-tzbudiachro%ccategory  = 'profiler'
-! tzbudiachro%csubcategory  = NOT SET (default values)
-tzbudiachro%cgroup     = ygroup
-tzbudiachro%cshape     = 'vertical profile'
-! tzbudiachro%cmask     = NOT SET (default values)
+tzbudiachro%lleveluse(NLVL_CATEGORY)    = .true.
+tzbudiachro%clevels  (NLVL_CATEGORY)    = 'Profilers'
+tzbudiachro%ccomments(NLVL_CATEGORY)    = 'Level for the different vertical profilers'
+
+tzbudiachro%lleveluse(NLVL_SUBCATEGORY) = .false.
+tzbudiachro%clevels  (NLVL_SUBCATEGORY) = ''
+tzbudiachro%ccomments(NLVL_SUBCATEGORY) = ''
+
+tzbudiachro%lleveluse(NLVL_GROUP)       = .true.
+tzbudiachro%clevels  (NLVL_GROUP)       = ygroup
+tzbudiachro%ccomments(NLVL_GROUP)       = 'Vertical profiles at position of profiler ' // Trim( ygroup )
+
+tzbudiachro%lleveluse(NLVL_SHAPE)       = .false.
+tzbudiachro%clevels  (NLVL_SHAPE)       = 'Vertical profile'
+tzbudiachro%ccomments(NLVL_SHAPE)       = ''
+
+tzbudiachro%lleveluse(NLVL_TIMEAVG)     = .false.
+tzbudiachro%clevels  (NLVL_TIMEAVG)     = 'Not time averaged'
+tzbudiachro%ccomments(NLVL_TIMEAVG)     = 'Values are not time averaged'
+
+tzbudiachro%lleveluse(NLVL_NORM)        = .false.
+tzbudiachro%clevels  (NLVL_NORM)        = 'Not normalized'
+tzbudiachro%ccomments(NLVL_NORM)        = 'Values are not normalized'
+
+tzbudiachro%lleveluse(NLVL_MASK)        = .false.
+tzbudiachro%clevels  (NLVL_MASK)        = ''
+tzbudiachro%ccomments(NLVL_MASK)        = ''
+
 tzbudiachro%lmobile    = .false.
 tzbudiachro%licompress = .true.
 tzbudiachro%ljcompress = .true.
diff --git a/src/MNH/write_seriesn.f90 b/src/MNH/write_seriesn.f90
index 4ec7e6a578b3944af3fc6c785f459bce9a7a75c5..c8424aba1682cf049acc98c6cdd470f479e5a014 100644
--- a/src/MNH/write_seriesn.f90
+++ b/src/MNH/write_seriesn.f90
@@ -69,7 +69,8 @@ END MODULE MODI_WRITE_SERIES_n
 !*    0. Declaration
 !     --------------
 !
-use modd_budget,        only: tbudiachrometadata
+use modd_budget,        only: NLVL_CATEGORY, NLVL_SUBCATEGORY, NLVL_GROUP, NLVL_SHAPE, NLVL_TIMEAVG, NLVL_NORM, NLVL_MASK, &
+                              tbudiachrometadata
 use modd_field,         only: NMNHDIM_NI, NMNHDIM_NI_U,                                                               &
                               NMNHDIM_SERIES_LEVEL, NMNHDIM_SERIES_LEVEL_W, NMNHDIM_SERIES_TIME, NMNHDIM_SERIES_PROC, &
                               NMNHDIM_UNUSED,                                                                         &
@@ -261,12 +262,34 @@ tzfields(:)%ndimlist(5) = NMNHDIM_UNUSED
 ! tzfields(:)%ndimlist(6) = NMNHDIM_SERIES_PROC
 tzfields(:)%ndimlist(6) = NMNHDIM_UNUSED !Set to unused because write are done in a loop (1 write per "process")
 
-tzbudiachro%ccomment   = 'Time series of horizontally and vertically averaged fields'
-tzbudiachro%ccategory  = 'time series'
-! tzbudiachro%csubcategory  = NOT SET (default values)
-tzbudiachro%cgroup     = 'TSERIES'
-tzbudiachro%cshape     = 'cartesian' !It is based on a cartesian domain (with compression in all directions)
-! tzbudiachro%cmask    =  set in the process loop
+tzbudiachro%lleveluse(NLVL_CATEGORY)    = .true.
+tzbudiachro%clevels  (NLVL_CATEGORY)    = 'Time series'
+tzbudiachro%ccomments(NLVL_CATEGORY)    = 'Level for the different time series'
+
+tzbudiachro%lleveluse(NLVL_SUBCATEGORY) = .false.
+tzbudiachro%clevels  (NLVL_SUBCATEGORY) = ''
+tzbudiachro%ccomments(NLVL_SUBCATEGORY) = ''
+
+tzbudiachro%lleveluse(NLVL_GROUP)       = .true.
+tzbudiachro%clevels  (NLVL_GROUP)       = 'TSERIES'
+tzbudiachro%ccomments(NLVL_GROUP)       = 'Time series of horizontally and vertically averaged fields'
+
+tzbudiachro%lleveluse(NLVL_SHAPE)       = .false.
+tzbudiachro%clevels  (NLVL_SHAPE)       = 'Cartesian' !It is based on a cartesian domain (with compression in all directions)
+tzbudiachro%ccomments(NLVL_SHAPE)       = 'Cartesian domain'
+
+tzbudiachro%lleveluse(NLVL_TIMEAVG)     = .false.
+tzbudiachro%clevels  (NLVL_TIMEAVG)     = 'Not time averaged'
+tzbudiachro%ccomments(NLVL_TIMEAVG)     = 'Values are not time averaged'
+
+tzbudiachro%lleveluse(NLVL_NORM)        = .false.
+tzbudiachro%clevels  (NLVL_NORM)        = 'Not normalized'
+tzbudiachro%ccomments(NLVL_NORM)        = 'Values are not normalized'
+
+tzbudiachro%lleveluse(NLVL_MASK)        = .true.
+! tzbudiachro%clevels  (NLVL_MASK)        = DONE LATER
+tzbudiachro%ccomments(NLVL_MASK)        = ''
+
 tzbudiachro%lmobile    = .false.
 tzbudiachro%licompress = .true.
 tzbudiachro%ljcompress = .true.
@@ -283,7 +306,7 @@ tzbudiachro%nkh        = ikmax
 ! Loop on the different masks
 ! Do not provide all tzfields once because they can be stored in different HDF groups (based on masks)
 do jp = 1 , nstemp_serie1
-  tzbudiachro%cmask    = csmask1(jp)
+  tzbudiachro%clevels(NLVL_MASK) = Trim( csmask1(jp) )
 
   call Write_diachro( tpdiafile, tzbudiachro, [ tzfields(jp) ], tpsdates(1:nsnbstept), &
                       xsseries1(1:1,1:1,1:1,1:nsnbstept,1:1,jp:jp)                 )
@@ -366,12 +389,34 @@ tzfields(:)%ndimlist(5) = NMNHDIM_UNUSED
 ! tzfields(:)%ndimlist(6) = NMNHDIM_SERIES_PROC
 tzfields(:)%ndimlist(6) = NMNHDIM_UNUSED !Set to unused because write are done in a loop (1 write per "process")
 
-tzbudiachro%ccomment   = 'Time series of horizontally averaged vertical profile'
-tzbudiachro%ccategory  = 'time series'
-! tzbudiachro%csubcategory  = NOT SET (default values)
-tzbudiachro%cgroup     = 'ZTSERIES'
-tzbudiachro%cshape     = 'cartesian'  !It is based on a cartesian domain (with horizontal compression)
-! tzbudiachro%cmask    =  set in the process loop
+tzbudiachro%lleveluse(NLVL_CATEGORY)    = .true.
+tzbudiachro%clevels  (NLVL_CATEGORY)    = 'Time series'
+tzbudiachro%ccomments(NLVL_CATEGORY)    = 'Level for the different time series'
+
+tzbudiachro%lleveluse(NLVL_SUBCATEGORY) = .false.
+tzbudiachro%clevels  (NLVL_SUBCATEGORY) = ''
+tzbudiachro%ccomments(NLVL_SUBCATEGORY) = ''
+
+tzbudiachro%lleveluse(NLVL_GROUP)       = .true.
+tzbudiachro%clevels  (NLVL_GROUP)       = 'ZTSERIES'
+tzbudiachro%ccomments(NLVL_GROUP)       = 'Time series of horizontally averaged vertical profile'
+
+tzbudiachro%lleveluse(NLVL_SHAPE)       = .false.
+tzbudiachro%clevels  (NLVL_SHAPE)       = 'Cartesian' !It is based on a cartesian domain (with horizontal compression)
+tzbudiachro%ccomments(NLVL_SHAPE)       = 'Cartesian domain'
+
+tzbudiachro%lleveluse(NLVL_TIMEAVG)     = .false.
+tzbudiachro%clevels  (NLVL_TIMEAVG)     = 'Not time averaged'
+tzbudiachro%ccomments(NLVL_TIMEAVG)     = 'Values are not time averaged'
+
+tzbudiachro%lleveluse(NLVL_NORM)        = .false.
+tzbudiachro%clevels  (NLVL_NORM)        = 'Not normalized'
+tzbudiachro%ccomments(NLVL_NORM)        = 'Values are not normalized'
+
+tzbudiachro%lleveluse(NLVL_MASK)        = .true.
+! tzbudiachro%clevels  (NLVL_MASK)        = DONE LATER
+tzbudiachro%ccomments(NLVL_MASK)        = ''
+
 tzbudiachro%lmobile    = .false.
 tzbudiachro%licompress = .true.
 tzbudiachro%ljcompress = .true.
@@ -388,7 +433,7 @@ tzbudiachro%nkh        = ikmax
 ! Loop on the different masks
 ! Do not provide all tzfields once because they can be stored in different HDF groups (based on masks)
 do jp = 1 , nstemp_serie2
-  tzbudiachro%cmask    = csmask2(jp)
+  tzbudiachro%clevels(NLVL_MASK) = csmask2(jp)
 
   call Write_diachro( tpdiafile, tzbudiachro, [ tzfields(jp) ], tpsdates(1:nsnbstept), &
                       xsseries2(1:1,1:1,1:ikmax,1:nsnbstept,1:1,jp:jp)                 )
@@ -473,12 +518,35 @@ DO JS=1,NBJSLICE
   tzfields(:)%ndimlist(5) = NMNHDIM_UNUSED
   tzfields(:)%ndimlist(6) = NMNHDIM_SERIES_PROC
 
-  tzbudiachro%ccomment   = 'Time series of y-horizontally averaged fields at one level or vertically averaged between 2 levels'
-  tzbudiachro%ccategory  = 'time series'
-! tzbudiachro%csubcategory  = NOT SET (default values)
-  tzbudiachro%cgroup     = ygroup
-  tzbudiachro%cshape     = 'cartesian' !It is based on a cartesian domain (with compression in 1 direction)
-!  tzbudiachro%cmask      = NOT SET (default values)
+  tzbudiachro%lleveluse(NLVL_CATEGORY)    = .true.
+  tzbudiachro%clevels  (NLVL_CATEGORY)    = 'Time series'
+  tzbudiachro%ccomments(NLVL_CATEGORY)    = 'Level for the different time series'
+
+  tzbudiachro%lleveluse(NLVL_SUBCATEGORY) = .false.
+  tzbudiachro%clevels  (NLVL_SUBCATEGORY) = ''
+  tzbudiachro%ccomments(NLVL_SUBCATEGORY) = ''
+
+  tzbudiachro%lleveluse(NLVL_GROUP)       = .true.
+  tzbudiachro%clevels  (NLVL_GROUP)       = Trim( ygroup )
+  tzbudiachro%ccomments(NLVL_GROUP)       = 'Time series of y-horizontally averaged fields at one level ' // &
+                                            'or vertically averaged between 2 levels'
+
+  tzbudiachro%lleveluse(NLVL_SHAPE)       = .false.
+  tzbudiachro%clevels  (NLVL_SHAPE)       = 'Cartesian' !It is based on a cartesian domain (with compression in 1 direction)
+  tzbudiachro%ccomments(NLVL_SHAPE)       = 'Cartesian domain'
+
+  tzbudiachro%lleveluse(NLVL_TIMEAVG)     = .false.
+  tzbudiachro%clevels  (NLVL_TIMEAVG)     = 'Not time averaged'
+  tzbudiachro%ccomments(NLVL_TIMEAVG)     = 'Values are not time averaged'
+
+  tzbudiachro%lleveluse(NLVL_NORM)        = .false.
+  tzbudiachro%clevels  (NLVL_NORM)        = 'Not normalized'
+  tzbudiachro%ccomments(NLVL_NORM)        = 'Values are not normalized'
+
+  tzbudiachro%lleveluse(NLVL_MASK)        = .false.
+  tzbudiachro%clevels  (NLVL_MASK)        = ''
+  tzbudiachro%ccomments(NLVL_MASK)        = ''
+
   tzbudiachro%lmobile    = .false.
   tzbudiachro%licompress = .false.
   tzbudiachro%ljcompress = .true.
diff --git a/src/MNH/write_stationn.f90 b/src/MNH/write_stationn.f90
index 61cb5cb77eb56757339cf65aa1d6d0a95e706124..364b4ed1122d521c5a025617d74d6fd9d6ad69be 100644
--- a/src/MNH/write_stationn.f90
+++ b/src/MNH/write_stationn.f90
@@ -123,7 +123,8 @@ CONTAINS
 !----------------------------------------------------------------------------
 SUBROUTINE STATION_DIACHRO_n(TSTATION,II)
 
-use modd_field, only:  NMNHDIM_STATION_TIME, NMNHDIM_STATION_PROC, NMNHDIM_UNUSED, &
+use modd_budget, only: NLVL_CATEGORY, NLVL_SUBCATEGORY, NLVL_GROUP, NLVL_SHAPE, NLVL_TIMEAVG, NLVL_NORM, NLVL_MASK
+use modd_field,  only: NMNHDIM_STATION_TIME, NMNHDIM_STATION_PROC, NMNHDIM_UNUSED, &
                        tfield_metadata_base, TYPEREAL
 
 TYPE(STATION),        INTENT(IN)       :: TSTATION
@@ -735,12 +736,34 @@ tzfields(:)%ndimlist(4) = NMNHDIM_STATION_TIME
 tzfields(:)%ndimlist(5) = NMNHDIM_UNUSED
 tzfields(:)%ndimlist(6) = NMNHDIM_STATION_PROC
 
-tzbudiachro%ccomment   = 'Values at position of station ' // Trim( ygroup )
-tzbudiachro%ccategory  = 'station'
-! tzbudiachro%csubcategory  = NOT SET (default values)
-tzbudiachro%cgroup     = ygroup
-tzbudiachro%cshape     = 'point'
-! tzbudiachro%cmask     = NOT SET (default values)
+tzbudiachro%lleveluse(NLVL_CATEGORY)    = .true.
+tzbudiachro%clevels  (NLVL_CATEGORY)    = 'Stations'
+tzbudiachro%ccomments(NLVL_CATEGORY)    = 'Level for the different stations'
+
+tzbudiachro%lleveluse(NLVL_SUBCATEGORY) = .false.
+tzbudiachro%clevels  (NLVL_SUBCATEGORY) = ''
+tzbudiachro%ccomments(NLVL_SUBCATEGORY) = ''
+
+tzbudiachro%lleveluse(NLVL_GROUP)       = .true.
+tzbudiachro%clevels  (NLVL_GROUP)       = ygroup
+tzbudiachro%ccomments(NLVL_GROUP)       = 'Values at position of station ' // Trim( ygroup )
+
+tzbudiachro%lleveluse(NLVL_SHAPE)       = .false.
+tzbudiachro%clevels  (NLVL_SHAPE)       = 'Point'
+tzbudiachro%ccomments(NLVL_SHAPE)       = 'Values at position of station ' // Trim( ygroup )
+
+tzbudiachro%lleveluse(NLVL_TIMEAVG)     = .false.
+tzbudiachro%clevels  (NLVL_TIMEAVG)     = 'Not time averaged'
+tzbudiachro%ccomments(NLVL_TIMEAVG)     = 'Values are not time averaged'
+
+tzbudiachro%lleveluse(NLVL_NORM)        = .false.
+tzbudiachro%clevels  (NLVL_NORM)        = 'Not normalized'
+tzbudiachro%ccomments(NLVL_NORM)        = 'Values are not normalized'
+
+tzbudiachro%lleveluse(NLVL_MASK)        = .false.
+tzbudiachro%clevels  (NLVL_MASK)        = ''
+tzbudiachro%ccomments(NLVL_MASK)        = ''
+
 tzbudiachro%lmobile    = .false.
 tzbudiachro%licompress = .true.
 tzbudiachro%ljcompress = .true.