Index: LMDZ6/trunk/libf/misc/iso_params_mod.F90
===================================================================
--- LMDZ6/trunk/libf/misc/iso_params_mod.F90	(revision 5184)
+++ 	(revision )
@@ -1,10 +1,0 @@
-MODULE iso_params_mod
-
-   REAL, PARAMETER :: tnat_H216O = 1.0000,    alpha_ideal_H216O = 1.000, &
-                      tnat_H217O = 40.000e-6, alpha_ideal_H217O = 1.003, &
-                      tnat_H218O = 2005.2e-6, alpha_ideal_H218O = 1.006, &
-                      tnat_HDO   = 155.76e-6, alpha_ideal_HDO   = 1.010, &
-                      tnat_HTO   = 0.0000,    alpha_ideal_HTO   = 1.000
-
-END MODULE iso_params_mod
-
Index: LMDZ6/trunk/libf/misc/readTracFiles_mod.f90
===================================================================
--- LMDZ6/trunk/libf/misc/readTracFiles_mod.f90	(revision 5184)
+++ LMDZ6/trunk/libf/misc/readTracFiles_mod.f90	(revision 5190)
@@ -10,9 +10,9 @@
 
   PUBLIC :: maxlen                                              !--- PARAMETER FOR CASUAL STRING LENGTH
-  PUBLIC :: keys_type, tracers, setGeneration, indexUpdate      !--- TRACERS  DESCRIPTION DATABASE + ASSOCIATED TOOLS
+  PUBLIC :: trac_type, tracers, setGeneration, indexUpdate      !--- TRACERS  DESCRIPTION DATABASE + ASSOCIATED TOOLS
   PUBLIC :: testTracersFiles, readTracersFiles                  !--- TRACERS FILES READING ROUTINES
   PUBLIC :: getKeysDBase, setKeysDBase                          !--- TOOLS TO GET/SET THE DATABASE (tracers & isotopes)
   PUBLIC :: addTracer, delTracer                                !--- ADD/REMOVE A TRACER FROM
-  PUBLIC :: addKey,    delKey,    getKey                        !--- TOOLS TO SET/DEL/GET KEYS FROM/TO  tracers & isotopes
+  PUBLIC :: addKey,    delKey,    getKey,    keys_type          !--- TOOLS TO SET/DEL/GET KEYS FROM/TO  tracers & isotopes
   PUBLIC :: addPhase,  delPhase,  getPhase,  getiPhase,  &      !--- FUNCTIONS RELATED TO THE PHASES
    nphases, old_phases, phases_sep, known_phases, phases_names  !--- + ASSOCIATED VARIABLES
@@ -35,5 +35,5 @@
   PUBLIC :: itZonIso                                            !--- Idx IN isoName(1:niso) = f(tagging idx, isotope idx)
   PUBLIC :: iqIsoPha                                            !--- Idx IN qx(1:nqtot)     = f(isotope idx,   phase idx)
-  PUBLIC :: iqWIsoPha                                           !--- SAME AS iqIsoPha BUT ISOTOPES LIST STARTS WITH PARENT TRAC
+  PUBLIC :: iqWIsoPha                                           !--- Idx IN qx(1:nqtot)     = f(isotope idx,   phase idx) but with normal water first
   PUBLIC :: isoCheck                                            !--- FLAG TO RUN ISOTOPES CHECKING ROUTINES
 
@@ -41,10 +41,34 @@
 !------------------------------------------------------------------------------------------------------------------------------
   TYPE :: keys_type                                             !=== TYPE FOR A SET OF KEYS ASSOCIATED TO AN ELEMENT
+    CHARACTER(LEN=maxlen)              :: name                  !--- Tracer name
     CHARACTER(LEN=maxlen), ALLOCATABLE :: key(:)                !--- Keys string list
     CHARACTER(LEN=maxlen), ALLOCATABLE :: val(:)                !--- Corresponding values string list
   END TYPE keys_type
 !------------------------------------------------------------------------------------------------------------------------------
-  TYPE :: isot_type                                             !=== TYPE FOR AN ISOTOPES FAMILY DESCENDING ON TRACER "name"
-    CHARACTER(LEN=maxlen)              :: name                  !--- Isotopes family name (example: H2O)
+  TYPE :: trac_type                                             !=== TYPE FOR A SINGLE TRACER NAMED "name"
+    CHARACTER(LEN=maxlen) :: name        = ''                   !--- Name of the tracer
+    TYPE(keys_type)       :: keys                               !--- <key>=<val> pairs vector
+    CHARACTER(LEN=maxlen) :: gen0Name    = ''                   !--- First generation ancestor name
+    CHARACTER(LEN=maxlen) :: parent      = ''                   !--- Parent name
+    CHARACTER(LEN=maxlen) :: longName    = ''                   !--- Long name (with advection scheme suffix)
+    CHARACTER(LEN=maxlen) :: type        = 'tracer'             !--- Type  (so far: 'tracer' / 'tag')
+    CHARACTER(LEN=maxlen) :: phase       = 'g'                  !--- Phase ('g'as / 'l'iquid / 's'olid)
+    CHARACTER(LEN=maxlen) :: component   = ''                   !--- Coma-separated list of components (Ex: lmdz,inca)
+    INTEGER               :: iGeneration = -1                   !--- Generation number (>=0)
+    INTEGER               :: iqParent    = 0                    !--- Parent index
+    INTEGER,  ALLOCATABLE :: iqDescen(:)                        !--- Descendants index (in growing generation order)
+    INTEGER               :: nqDescen    = 0                    !--- Number of descendants (all generations)
+    INTEGER               :: nqChildren  = 0                    !--- Number of children  (first generation)
+    INTEGER               :: iadv        = 10                   !--- Advection scheme used
+    LOGICAL               :: isAdvected  = .FALSE.              !--- "true" tracers: iadv > 0.   COUNT(isAdvected )=nqtrue
+    LOGICAL               :: isInPhysics = .TRUE.               !--- "true" tracers: in tr_seri. COUNT(isInPhysics)=nqtottr
+    INTEGER               :: iso_iGroup  = 0                    !--- Isotopes group index in isotopes(:)
+    INTEGER               :: iso_iName   = 0                    !--- Isotope  name  index in isotopes(iso_iGroup)%trac(:)
+    INTEGER               :: iso_iZone   = 0                    !--- Isotope  zone  index in isotopes(iso_iGroup)%zone(:)
+    INTEGER               :: iso_iPhase  = 0                    !--- Isotope  phase index in isotopes(iso_iGroup)%phase
+  END TYPE trac_type
+!------------------------------------------------------------------------------------------------------------------------------
+  TYPE :: isot_type                                             !=== TYPE FOR AN ISOTOPES FAMILY DESCENDING ON TRACER "parent"
+    CHARACTER(LEN=maxlen)              :: parent                !--- Isotopes family name (parent tracer name ; ex: H2O)
     TYPE(keys_type),       ALLOCATABLE :: keys(:)               !--- Isotopes keys/values pairs list     (length: niso)
     LOGICAL                            :: check=.FALSE.         !--- Flag for checking routines triggering
@@ -64,5 +88,5 @@
   TYPE :: dataBase_type                                         !=== TYPE FOR TRACERS SECTION
     CHARACTER(LEN=maxlen) :: name                               !--- Section name
-    TYPE(keys_type), ALLOCATABLE :: trac(:)                     !--- Tracers descriptors
+    TYPE(trac_type), ALLOCATABLE :: trac(:)                     !--- Tracers descriptors
   END TYPE dataBase_type
 !------------------------------------------------------------------------------------------------------------------------------
@@ -115,5 +139,5 @@
 
   !=== TRACERS AND ISOTOPES DESCRIPTORS, USED BY getKey
-  TYPE(keys_type), ALLOCATABLE, TARGET, SAVE ::  tracers(:)
+  TYPE(trac_type), ALLOCATABLE, TARGET, SAVE ::  tracers(:)
   TYPE(isot_type), ALLOCATABLE, TARGET, SAVE :: isotopes(:)
 
@@ -169,8 +193,8 @@
 !------------------------------------------------------------------------------------------------------------------------------
   CHARACTER(LEN=*),                               INTENT(IN)  :: type_trac     !--- List of components used
-  TYPE(keys_type), ALLOCATABLE, TARGET, OPTIONAL, INTENT(OUT) :: tracs(:)      !--- Tracers descriptor for external storage
+  TYPE(trac_type), ALLOCATABLE, TARGET, OPTIONAL, INTENT(OUT) :: tracs(:)      !--- Tracers descriptor for external storage
   LOGICAL,                              OPTIONAL, INTENT(IN)  :: lRepr         !--- Activate the HNO3 exceptions for REPROBUS
   CHARACTER(LEN=maxlen),  ALLOCATABLE :: s(:), sections(:), trac_files(:)
-  CHARACTER(LEN=maxlen) :: str, fname, tname, pname, cname, ttype
+  CHARACTER(LEN=maxlen) :: str, fname, tname, pname, cname
   INTEGER               :: nsec, ierr, it, ntrac, ns, ip, ix, fType
   INTEGER, ALLOCATABLE  :: iGen(:)
@@ -208,5 +232,5 @@
         CALL msg('This file is for air tracers only',           modname, ns == 3 .AND. it == 1)
         CALL msg('This files specifies the transporting fluid', modname, ns == 4 .AND. it == 1)
-        k => tracers(it)
+        k => tracers(it)%keys
 
         !=== NAME OF THE TRACER
@@ -214,11 +238,13 @@
         ix = strIdx(oldHNO3, s(3))
         IF(ix /= 0 .AND. lRep) tname = newHNO3(ix)                   !--- Exception for HNO3 (REPROBUS ONLY)
-        CALL addKey('name', tname, tracers)                          !--- Set the name of the tracer
-!        tracers(it)%name = tname                                     !--- Copy tracers names in keys components
+        tracers(it)%name = tname                                     !--- Set the name of the tracer
+        CALL addKey('name', tname, k)                                !--- Set the name of the tracer
+        tracers(it)%keys%name = tname                                !--- Copy tracers names in keys components
 
         !=== NAME OF THE COMPONENT
         cname = type_trac                                            !--- Name of the model component
         IF(ANY([(addPhase('H2O', ip), ip = 1, nphases)] == tname)) cname = 'lmdz'
-        CALL addKey('component', cname, tracers)                     !--- Set the name of the model component
+        tracers(it)%component = cname                                !--- Set component
+        CALL addKey('component', cname, k)                           !--- Set the name of the model component
 
         !=== NAME OF THE PARENT
@@ -229,8 +255,10 @@
           IF(ix /= 0 .AND. lRep) pname = newHNO3(ix)                 !--- Exception for HNO3 (REPROBUS ONLY)
         END IF
-        CALL addKey('parent', pname, tracers)                        !--- Set the parent name
+        tracers(it)%parent = pname                                   !--- Set the parent name
+        CALL addKey('parent', pname, k)
 
         !=== PHASE AND ADVECTION SCHEMES NUMBERS
-        CALL addKey('phase', known_phases(ip:ip), tracers)           !--- Set the phase of the tracer (default: "g"azeous)
+        tracers(it)%phase = known_phases(ip:ip)                      !--- Set the phase of the tracer (default: "g"azeous)
+        CALL addKey('phase', known_phases(ip:ip), k)                 !--- Set the phase of the tracer (default: "g"azeous)
         CALL addKey('hadv', s(1),  k)                                !--- Set the horizontal advection schemes number
         CALL addKey('vadv', s(2),  k)                                !--- Set the vertical   advection schemes number
@@ -238,8 +266,8 @@
       CLOSE(90)
       lerr = setGeneration(tracers); IF(lerr) RETURN                 !--- Set iGeneration and gen0Name
-      lerr = getKey('iGeneration', iGen, tracers(:))                 !--- Generation number
+      lerr = getKey('iGeneration', iGen, tracers(:)%keys)            !--- Generation number
+      WHERE(iGen == 2) tracers(:)%type = 'tag'                       !--- Set type:      'tracer' or 'tag'
       DO it = 1, ntrac
-        ttype = 'tracer'; IF(iGen(it) == 2) ttype = 'tag'
-        CALL addKey('type', ttype, tracers(it))                 !--- Set the type of tracer
+        CALL addKey('type', tracers(it)%type, tracers(it)%keys)      !--- Set the type of tracer
       END DO
       lerr = checkTracers(tracers, fname, fname); IF(lerr) RETURN    !--- Detect orphans and check phases
@@ -263,5 +291,5 @@
   END IF
   lerr = indexUpdate(tracers); IF(lerr) RETURN                       !--- Set iqParent, iqDescen, nqDescen, nqChildren
-  IF(PRESENT(tracs)) tracs = tracers
+  IF(PRESENT(tracs)) CALL MOVE_ALLOC(FROM=tracers, TO=tracs)
 END FUNCTION readTracersFiles
 !==============================================================================================================================
@@ -311,8 +339,8 @@
 ! Purpose: Read the sections "snames(is)" (pipe-separated list) from each "fnames(is)"
 !   file and create the corresponding tracers set descriptors in the database "dBase":
-! * dBase(id)%name           : section name
-! * dBase(id)%trac(:)        : tracers descriptor (the key "name" of tracers(i) is the name of the ith tracer)
-! * dBase(id)%trac(it)%key(:): names  of keys associated to tracer dBase(id)%trac(it)%name
-! * dBase(id)%trac(it)%val(:): values of keys associated to tracer dBase(id)%trac(it)%name
+! * dBase(id)%name                : section name
+! * dBase(id)%trac(:)%name        : tracers names
+! * dBase(id)%trac(it)%keys%key(:): names  of keys associated to tracer dBase(id)%trac(it)%name
+! * dBase(id)%trac(it)%keys%val(:): values of keys associated to tracer dBase(id)%trac(it)%name
 !------------------------------------------------------------------------------------------------------------------------------
   CHARACTER(LEN=*), INTENT(IN)  :: fnames(:)                         !--- Files names
@@ -367,7 +395,5 @@
   ndb= SIZE(dBase)                                                   !--- Current number of sections in the database
   IF(PRESENT(defName)) THEN                                          !--- Add default values to all the tracers
-    DO idb=n0,ndb                                                    !--- and remove the virtual tracer "defName"
-       lerr = addDefault(dBase(idb)%trac, defName); IF(lerr) RETURN
-    END DO
+    DO idb=n0,ndb; CALL addDefault(dBase(idb)%trac, defName); END DO !--- and remove the virtual tracer "defName"
   END IF
   ll = strParse(snam, '|', keys = sec)                               !--- Requested sections names
@@ -382,5 +408,6 @@
 !------------------------------------------------------------------------------------------------------------------------------
   CHARACTER(LEN=maxlen), ALLOCATABLE ::  s(:), v(:)
-  TYPE(keys_type),       ALLOCATABLE :: tt(:)
+  TYPE(trac_type),       ALLOCATABLE :: tt(:)
+  TYPE(trac_type)       :: tmp
   CHARACTER(LEN=1024)   :: str, str2
   CHARACTER(LEN=maxlen) :: secn
@@ -418,6 +445,7 @@
       tt = dBase(ndb)%trac(:)
       v(1) = s(1); s(1) = 'name'                                     !--- Convert "name" into a regular key
-      dBase(ndb)%trac = [tt(:), keys_type(s(:), v(:))]
-      DEALLOCATE(tt)
+      tmp%name = v(1); tmp%keys = keys_type(v(1), s(:), v(:))        !--- Set %name and %keys
+      dBase(ndb)%trac = [tt(:), tmp]
+      DEALLOCATE(tt, tmp%keys%key, tmp%keys%val)
     END IF
   END DO
@@ -432,51 +460,52 @@
 
 !==============================================================================================================================
-LOGICAL FUNCTION addDefault(t, defName) RESULT(lerr)
+SUBROUTINE addDefault(t, defName)
 !------------------------------------------------------------------------------------------------------------------------------
 ! Purpose: Add the keys from virtual tracer named "defName" (if any) and remove this virtual tracer.
 !------------------------------------------------------------------------------------------------------------------------------
-  TYPE(keys_type), ALLOCATABLE, TARGET, INTENT(INOUT) :: t(:)
+  TYPE(trac_type), ALLOCATABLE, TARGET, INTENT(INOUT) :: t(:)
   CHARACTER(LEN=*),                     INTENT(IN)    :: defName
   INTEGER :: jd, it, k
-  CHARACTER(LEN=maxlen), ALLOCATABLE :: tname(:)
-  TYPE(keys_type),       ALLOCATABLE :: tt(:)
-  lerr = getKey('name', tname, t(:)); IF(lerr) RETURN
-  jd = strIdx(tname(:), defName)
+  TYPE(keys_type), POINTER :: ky
+  TYPE(trac_type), ALLOCATABLE :: tt(:)
+  jd = strIdx(t(:)%name, defName)
   IF(jd == 0) RETURN
-  DO k = 1, SIZE(t(jd)%key)                                          !--- Loop on the keys of the tracer named "defName"
-!   CALL addKey(t(jd)%key(k), t(jd)%val(k), t(:), .FALSE.)           !--- Add key to all the tracers (no overwriting)
-    DO it = 1, SIZE(t); CALL addKey(t(jd)%key(k), t(jd)%val(k), t(it), .FALSE.); END DO
+  ky => t(jd)%keys
+  DO k = 1, SIZE(ky%key)                                             !--- Loop on the keys of the tracer named "defName"
+!   CALL addKey(ky%key(k), ky%val(k), t(:)%keys, .FALSE.)            !--- Add key to all the tracers (no overwriting)
+    DO it = 1, SIZE(t); CALL addKey(ky%key(k), ky%val(k), t(it)%keys, .FALSE.); END DO
   END DO
   tt = [t(1:jd-1),t(jd+1:SIZE(t))]; CALL MOVE_ALLOC(FROM=tt, TO=t)   !--- Remove the virtual tracer named "defName"
-END FUNCTION addDefault
-!==============================================================================================================================
-
-!==============================================================================================================================
-LOGICAL FUNCTION subDefault(t, defName, lSubLocal) RESULT(lerr)
+END SUBROUTINE addDefault
+!==============================================================================================================================
+
+!==============================================================================================================================
+SUBROUTINE subDefault(t, defName, lSubLocal)
 !------------------------------------------------------------------------------------------------------------------------------
 ! Purpose: Substitute the keys from virtual tracer named "defName" (if any) and remove this virtual tracer.
 !          Substitute the keys locally (for the current tracer) if the flag "lSubLocal" is .TRUE.
 !------------------------------------------------------------------------------------------------------------------------------
-  TYPE(keys_type), ALLOCATABLE, TARGET, INTENT(INOUT) :: t(:)
+  TYPE(trac_type), ALLOCATABLE, TARGET, INTENT(INOUT) :: t(:)
   CHARACTER(LEN=*),                     INTENT(IN)    :: defName
   LOGICAL,                              INTENT(IN)    :: lSubLocal
   INTEGER :: i0, it, ik
-  TYPE(keys_type),       ALLOCATABLE :: tt(:)
-  CHARACTER(LEN=maxlen), ALLOCATABLE :: tname(:)
-  lerr = getKey('name', tname, t(:)); IF(lerr) RETURN
-  i0 = strIdx(tname(:), defName)
+  TYPE(keys_type), POINTER     :: k0, ky
+  TYPE(trac_type), ALLOCATABLE :: tt(:)
+  i0 = strIdx(t(:)%name, defName)
   IF(i0 == 0) RETURN
+  k0 => t(i0)%keys 
   DO it = 1, SIZE(t); IF(it == i0) CYCLE                             !--- Loop on the tracers
+    ky => t(it)%keys
 
     !--- Substitute in the values of <key>=<val> pairs the keys defined in the virtual tracer "defName"
-    DO ik = 1, SIZE(t(i0)%key); CALL strReplace(t(it)%val, t(i0)%key(ik), t(i0)%val(ik), .TRUE.); END DO
+    DO ik = 1, SIZE(k0%key); CALL strReplace(ky%val, k0%key(ik), k0%val(ik), .TRUE.); END DO
 
     IF(.NOT.lSubLocal) CYCLE
     !--- Substitute in the values of <key>=<val> pairs the keys defined locally (in the current tracer)
-    DO ik = 1, SIZE(t(it)%key); CALL strReplace(t(it)%val, t(it)%key(ik), t(it)%val(ik), .TRUE.); END DO
+    DO ik = 1, SIZE(ky%key); CALL strReplace(ky%val, ky%key(ik), ky%val(ik), .TRUE.); END DO
   END DO
   tt = [t(1:i0-1),t(i0+1:SIZE(t))]; CALL MOVE_ALLOC(FROM=tt, TO=t)   !--- Remove the virtual tracer named "defName"
 
-END FUNCTION subDefault
+END SUBROUTINE subDefault
 !==============================================================================================================================
 
@@ -489,8 +518,8 @@
 !        * Default values are provided for these keys because they are necessary.
 !------------------------------------------------------------------------------------------------------------------------------
-  TYPE(keys_type), ALLOCATABLE, INTENT(INOUT) :: tr(:)                 !--- Tracer derived type vector
+  TYPE(trac_type), ALLOCATABLE, INTENT(INOUT) :: tr(:)                 !--- Tracer derived type vector
   CHARACTER(LEN=*),             INTENT(IN)    :: sname                 !--- Current section name
   CHARACTER(LEN=*), OPTIONAL,   INTENT(IN)    :: fname                 !--- Tracers description file name
-  TYPE(keys_type),       ALLOCATABLE :: ttr(:)
+  TYPE(trac_type),       ALLOCATABLE :: ttr(:)
   CHARACTER(LEN=maxlen), ALLOCATABLE :: ta(:), pa(:), tname(:), parent(:), dType(:)
   CHARACTER(LEN=maxlen) :: msg1, modname
@@ -500,7 +529,7 @@
   lerr = .FALSE.
   nt = SIZE(tr)
-  lerr = getKey('name',   tname,  tr(:));                 IF(lerr) RETURN
-  lerr = getKey('parent', parent, tr(:), def = tran0);    IF(lerr) RETURN
-  lerr = getKey('type',   dType,  tr(:), def = 'tracer'); IF(lerr) RETURN
+  lerr = getKey('name',   tname,  tr(:)%keys);                 IF(lerr) RETURN
+  lerr = getKey('parent', parent, tr(:)%keys, def = tran0);    IF(lerr) RETURN
+  lerr = getKey('type',   dType,  tr(:)%keys, def = 'tracer'); IF(lerr) RETURN
   nq = 0
   !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@@ -508,5 +537,6 @@
   !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     !--- Extract useful keys: parent name, type, component name
-    CALL addKey('component', sname,  tr(it))
+    tr(it)%component = sname
+    CALL addKey('component', sname,  tr(it)%keys)
 
     !--- Determine the number of tracers and parents ; coherence checking
@@ -535,10 +565,15 @@
     DO ipr = 1, npr                                                  !--- Loop on parents list elts
       DO itr = 1, ntr                                                !--- Loop on tracers list elts
-        ttr(iq)%key  = tr(it)%key
-        ttr(iq)%val  = tr(it)%val
-        CALL addKey('name',    ta(itr), ttr(iq))
-        CALL addKey('parent',  pa(ipr), ttr(iq))
-        CALL addKey('type',  dType(it), ttr(iq))
-        CALL addKey('component', sname, ttr(iq))
+        ttr(iq)%keys%name = TRIM(ta(itr))
+        ttr(iq)%keys%key  = tr(it)%keys%key
+        ttr(iq)%keys%val  = tr(it)%keys%val
+        ttr(iq)%name      = TRIM(ta(itr))
+        ttr(iq)%parent    = TRIM(pa(ipr))
+        ttr(iq)%type      = dType(it)
+        ttr(iq)%component = sname
+        CALL addKey('name',      ta(itr),   ttr(iq)%keys)
+        CALL addKey('parent',    pa(ipr),   ttr(iq)%keys)
+        CALL addKey('type',      dType(it), ttr(iq)%keys)
+        CALL addKey('component', sname,     ttr(iq)%keys)
         iq = iq + 1
       END DO
@@ -562,5 +597,5 @@
 !          Check also for orphan tracers (tracers without parent).
 !------------------------------------------------------------------------------------------------------------------------------
-  TYPE(keys_type),     INTENT(INOUT) :: tr(:)                        !--- Tracer derived type vector
+  TYPE(trac_type),     INTENT(INOUT) :: tr(:)                        !--- Tracer derived type vector
   INTEGER                            :: iq, jq, ig
   CHARACTER(LEN=maxlen), ALLOCATABLE :: parent(:), tname(:)
@@ -568,6 +603,6 @@
   CHARACTER(LEN=maxlen) :: modname
   modname = 'setGeneration'
-  lerr = getKey('name',   tname,  ky=tr(:)); IF(lerr) RETURN
-  lerr = getKey('parent', parent, ky=tr(:)); IF(lerr) RETURN
+  lerr = getKey('name',   tname,  ky=tr(:)%keys); IF(lerr) RETURN
+  lerr = getKey('parent', parent, ky=tr(:)%keys); IF(lerr) RETURN
   DO iq = 1, SIZE(tr)
     jq = iq; ig = 0
@@ -578,6 +613,8 @@
       ig = ig + 1
     END DO
-    CALL addKey('iGeneration',    ig,  tr(iq))
-    CALL addKey('gen0Name', tname(jq), tr(iq))
+    tr(iq)%gen0Name = tname(jq)
+    tr(iq)%iGeneration = ig
+    CALL addKey('iGeneration',   ig,  tr(iq)%keys)
+    CALL addKey('gen0Name', tname(jq), tr(iq)%keys)
   END DO
 END FUNCTION setGeneration
@@ -592,5 +629,5 @@
 !   * check wether the phases are known or not (elements of "known_phases")
 !------------------------------------------------------------------------------------------------------------------------------
-  TYPE(keys_type),            INTENT(IN) :: tr(:)                    !--- Tracers description vector
+  TYPE(trac_type),            INTENT(IN) :: tr(:)                    !--- Tracer derived type vector
   CHARACTER(LEN=*),           INTENT(IN) :: sname                    !--- Section name
   CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: fname                    !--- File name
@@ -607,6 +644,6 @@
   mesg = 'Check section "'//TRIM(sname)//'"'
   IF(PRESENT(fname)) mesg=TRIM(mesg)//' in file "'//TRIM(fname)//'"'
-  lerr = getKey('iGeneration', iGen, tr(:));                    IF(lerr) RETURN
-  lerr = getKey('name',       tname, tr(:));                    IF(lerr) RETURN
+  lerr = getKey('iGeneration', iGen, tr(:)%keys);               IF(lerr) RETURN
+  lerr = getKey('name',       tname, tr(:)%keys);               IF(lerr) RETURN
 
   !=== CHECK FOR ORPHAN TRACERS
@@ -615,5 +652,5 @@
   !=== CHECK PHASES
   DO iq = 1, nq; IF(iGen(iq) /= 0) CYCLE                             !--- Generation O only is checked
-    IF(getKey(['phases','phase '], pha, iq, tr(:), lDisp=.FALSE.)) pha = 'g'   !--- Phase
+    IF(getKey(['phases','phase '], pha, iq, tr(:)%keys, lDisp=.FALSE.)) pha = 'g'   !--- Phase
     np = LEN_TRIM(pha); bp(iq)=' '
     DO ip = 1, np; p = pha(ip:ip); IF(INDEX(known_phases, p) == 0) bp(iq) = TRIM(bp(iq))//p; END DO
@@ -630,5 +667,5 @@
 ! Purpose: Make sure that tracers are not repeated.
 !------------------------------------------------------------------------------------------------------------------------------
-  TYPE(keys_type),            INTENT(IN) :: tr(:)                    !--- Tracers description vector
+  TYPE(trac_type),            INTENT(IN) :: tr(:)                    !--- Tracer derived type vector
   CHARACTER(LEN=*),           INTENT(IN) :: sname                    !--- Section name
   CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: fname                    !--- File name
@@ -647,7 +684,7 @@
   nq=SIZE(tr,DIM=1); lerr=.FALSE.                                    !--- Number of lines ; error flag
   tdup(:) = ''
-  lerr = getKey('name',       tname, tr); IF(lerr) RETURN
-  lerr = getKey('type',       dType, tr); IF(lerr) RETURN
-  lerr = getKey('iGeneration', iGen, tr); IF(lerr) RETURN
+  lerr = getKey('name',       tname, tr%keys); IF(lerr) RETURN
+  lerr = getKey('type',       dType, tr%keys); IF(lerr) RETURN
+  lerr = getKey('iGeneration', iGen, tr%keys); IF(lerr) RETURN
   DO iq = 1, nq
     IF(dType(iq) == 'tag') CYCLE                                     !--- Tags can be repeated
@@ -661,5 +698,5 @@
         DO k = 1, nq
           IF(.NOT.ll(k)) CYCLE                                       !--- Skip tracers different from current one
-          IF(getKey(['phases','phase '], phase, k, tr, lDisp=.FALSE.)) phase='g'!--- Get current phases
+          IF(getKey(['phases','phase '], phase, k, tr%keys, lDisp=.FALSE.)) phase='g'!--- Get current phases
           IF(INDEX(phase, p) /= 0) np = np + 1                       !--- One more appearance of current tracer with phase "p"
         END DO
@@ -681,7 +718,7 @@
 ! Purpose: Expand the phases in the tracers descriptor "tr". Phases are not repeated for a tracer, thanks to "checkUnique".
 !------------------------------------------------------------------------------------------------------------------------------
-  TYPE(keys_type), ALLOCATABLE, INTENT(INOUT) :: tr(:)               !--- Tracers description vector
-!------------------------------------------------------------------------------------------------------------------------------
-  TYPE(keys_type),       ALLOCATABLE :: ttr(:)
+  TYPE(trac_type), ALLOCATABLE, INTENT(INOUT) :: tr(:)               !--- Tracer derived type vector
+!------------------------------------------------------------------------------------------------------------------------------
+  TYPE(trac_type),       ALLOCATABLE :: ttr(:)
   INTEGER,               ALLOCATABLE ::  i0(:), iGen(:)
   CHARACTER(LEN=maxlen), ALLOCATABLE :: tname(:), gen0N(:), phase(:), parents(:), dType(:)
@@ -695,10 +732,10 @@
   nq = SIZE(tr, DIM=1)
   nt = 0
-  lerr = getKey('name',       tname, tr); IF(lerr) RETURN            !--- Names of the tracers
-  lerr = getKey('gen0Name',   gen0N, tr); IF(lerr) RETURN            !--- Names of the tracers of first generation
-  lerr = getKey('iGeneration', iGen, tr); IF(lerr) RETURN            !--- Generation number
-  lerr = getKey('phases',     phase, tr); IF(lerr) RETURN            !--- Phases names
-  lerr = getKey('parent',   parents, tr); IF(lerr) RETURN            !--- Parents names
-  lerr = getKey('type',       dType, tr); IF(lerr) RETURN            !--- Tracers types ('tracer' or 'tag')
+  lerr = getKey('name',       tname, tr%keys); IF(lerr) RETURN       !--- Names of the tracers
+  lerr = getKey('gen0Name',   gen0N, tr%keys); IF(lerr) RETURN       !--- Names of the tracers of first generation
+  lerr = getKey('iGeneration', iGen, tr%keys); IF(lerr) RETURN       !--- Generation number
+  lerr = getKey('phases',     phase, tr%keys); IF(lerr) RETURN       !--- Phases names
+  lerr = getKey('parent',   parents, tr%keys); IF(lerr) RETURN       !--- Parents names
+  lerr = getKey('type',       dType, tr%keys); IF(lerr) RETURN       !--- Tracers types ('tracer' or 'tag')
   DO iq = 1, nq                                                      !--- GET THE NUMBER OF TRACERS
     IF(iGen(iq) /= 0) CYCLE                                          !--- Only deal with generation 0 tracers
@@ -726,11 +763,16 @@
         IF(lTag) nam = TRIM(nam)//'_'//TRIM(tname(iq))               !--- <parent>_<name> for tags
         ttr(it) = tr(iq)                                             !--- Same <key>=<val> pairs
-        CALL addKey('name', nam, ttr(it))                            !--- Name with possibly phase suffix
-        CALL addKey('phase', p,  ttr(it))                            !--- Single phase entry
+        ttr(it)%name      = TRIM(nam)                                !--- Name with possibly phase suffix
+        ttr(it)%keys%name = TRIM(nam)                                !--- Name inside the keys decriptor
+        ttr(it)%phase     = p                                        !--- Single phase entry
+        CALL addKey('name', nam, ttr(it)%keys)
+        CALL addKey('phase', p,  ttr(it)%keys)
         IF(lExt) THEN
           parent = parents(iq); IF(iGen(iq) > 0) parent = addPhase(parent, p)
           gen0Nm =   gen0N(iq); IF(iGen(iq) > 0) gen0Nm = addPhase(gen0Nm, p)
-          CALL addKey('parent',   parent, ttr(it))
-          CALL addKey('gen0Name', gen0Nm, ttr(it))
+          ttr(it)%parent   = parent
+          ttr(it)%gen0Name = gen0Nm
+          CALL addKey('parent',   parent, ttr(it)%keys)
+          CALL addKey('gen0Name', gen0Nm, ttr(it)%keys)
         END IF
         it = it+1
@@ -740,5 +782,5 @@
   END DO
   CALL MOVE_ALLOC(FROM=ttr, TO=tr)
-  CALL delKey(['phases'], tr)                                        !--- Remove "phases" key, useless since "phase" is defined
+  CALL delKey(['phases'],tr)                                         !--- Remove few keys entries
 
 END FUNCTION expandPhases
@@ -755,8 +797,9 @@
 !   TO BE ADDED IF NECESSARY: HIGHER MOMENTS AT THE END
 !------------------------------------------------------------------------------------------------------------------------------
-  TYPE(keys_type), INTENT(INOUT) :: tr(:)                            !--- Tracers description vector
-!------------------------------------------------------------------------------------------------------------------------------
-  TYPE(keys_type),       ALLOCATABLE :: tr2(:)
-  INTEGER,               ALLOCATABLE :: iy(:), iz(:), iGen(:)
+  TYPE(trac_type), INTENT(INOUT) :: tr(:)                            !--- Tracer derived type vector
+!------------------------------------------------------------------------------------------------------------------------------
+  TYPE(trac_type),       ALLOCATABLE :: tr2(:)
+  INTEGER,               ALLOCATABLE :: iy(:), iz(:)
+  INTEGER,               ALLOCATABLE ::  iGen(:)
   CHARACTER(LEN=maxlen), ALLOCATABLE :: tname(:), gen0N(:)
   INTEGER :: ig, ng, iq, jq, ip, nq, n, ix(SIZE(tr)), k
@@ -764,8 +807,8 @@
 !  tr2 is introduced in order to cope with a bug in gfortran 4.8.5 compiler
 !------------------------------------------------------------------------------------------------------------------------------
-  lerr = getKey('iGeneration', iGen, tr); IF(lerr) RETURN            !--- Generation number
+  lerr = getKey('iGeneration', iGen, tr%keys); IF(lerr) RETURN       !--- Generation number
   nq = SIZE(tr)
   DO ip = nphases, 1, -1
-    lerr = getKey('name',     tname, tr); IF(lerr) RETURN            !--- Names of the tracers of first generation
+    lerr = getKey('name',     tname, tr%keys); IF(lerr) RETURN       !--- Names of the tracers of first generation
     iq = strIdx(tname, addPhase('H2O', ip))
     IF(iq == 0) CYCLE
@@ -783,5 +826,5 @@
     END DO
   ELSE
-    lerr = getKey('gen0Name', gen0N, tr); IF(lerr) RETURN            !--- Names of the tracers    iq = 1
+    lerr = getKey('gen0Name',   gen0N, tr%keys); IF(lerr) RETURN     !--- Names of the tracers    iq = 1
     DO jq = 1, nq                                                    !--- Loop on generation 0 tracers
       IF(iGen(jq) /= 0) CYCLE                                        !--- Skip generations /= 0
@@ -805,6 +848,7 @@
 LOGICAL FUNCTION mergeTracers(sections, tr) RESULT(lerr)
   TYPE(dataBase_type),  TARGET, INTENT(IN)  :: sections(:)
-  TYPE(keys_type), ALLOCATABLE, INTENT(OUT) ::       tr(:)
-  TYPE(keys_type), POINTER ::   t1(:),   t2(:)
+  TYPE(trac_type), ALLOCATABLE, INTENT(OUT) ::       tr(:)
+  TYPE(trac_type), POINTER ::   t1(:),   t2(:)
+  TYPE(keys_type), POINTER ::   k1(:),   k2(:)
   INTEGER,     ALLOCATABLE :: ixct(:), ixck(:)
   INTEGER :: is, ik, ik1, ik2, nk2, i1, i2, nt2
@@ -814,6 +858,6 @@
   lerr = .FALSE.
   keys = ['parent     ', 'type       ', 'iGeneration']               !--- Mandatory keys
-  t1 => sections(1)%trac(:)                                          !--- Alias: first tracers section
-  lerr = getKey('name', n1, t1); IF(lerr) RETURN                     !--- Names of the tracers
+  t1 => sections(1)%trac(:); k1 => t1(:)%keys                        !--- Alias: first tracers section, corresponding keys
+  lerr = getKey('name', n1, k1); IF(lerr) RETURN                     !--- Names of the tracers
   tr = t1
   !----------------------------------------------------------------------------------------------------------------------------
@@ -821,5 +865,6 @@
   !----------------------------------------------------------------------------------------------------------------------------
     t2  => sections(is)%trac(:)                                      !--- Alias: current tracers section
-    lerr = getKey('name', n2, t2); IF(lerr) RETURN                   !--- Names of the tracers
+    k2  => t2(:)%keys
+    lerr = getKey('name', n2, k2); IF(lerr) RETURN                   !--- Names of the tracers
     nt2  = SIZE(t2(:), DIM=1)                                        !--- Number of tracers in section
     ixct = strIdx(n1(:), n2(:))                                      !--- Indexes of common tracers
@@ -829,5 +874,5 @@
     CALL msg(n1(PACK(ixct, MASK = ixct/=0)), modname, nmax=128)      !--- Display duplicates (the 128 first at most)
     !--------------------------------------------------------------------------------------------------------------------------
-    DO i2=1,nt2; tnam = TRIM(n2(i2))                                 !=== LOOP ON COMMON TRACERS
+    DO i2=1,nt2; tnam = TRIM(t2(i2)%name)                            !=== LOOP ON COMMON TRACERS
     !--------------------------------------------------------------------------------------------------------------------------
       i1 = ixct(i2); IF(i1 == 0) CYCLE                               !--- Idx in t1(:) ; skip new tracers
@@ -836,33 +881,34 @@
       s1=' of "'//TRIM(tnam)//'" in "'//TRIM(sections(is)%name)//'" not matching previous value'
       DO ik = 1, SIZE(keys)
-        lerr = getKey(keys(ik), v1, i1, t1)
-        lerr = getKey(keys(ik), v2, i2, t2)
+        lerr = getKey(keys(ik), v1, i1, k1)
+        lerr = getKey(keys(ik), v2, i2, k2)
         lerr = v1 /= v2; IF(fmsg(TRIM(keys(ik))//TRIM(s1), modname, lerr)) RETURN
       END DO
 
-      !=== GET THE INDICES IN tr(i2)%key(:) OF THE KEYS ALSO PRESENT IN tr(i1)%key(:)
-      nk2  =   SIZE(t2(i2)%key(:))                                   !--- Keys number in current section
-      ixck = strIdx(t1(i1)%key(:), t2(i2)%key(:))                    !--- Common keys indexes
-      !--- APPEND THE NEW KEYS PAIRS IN tr(i1)%key(:)
-      tr(i1)%key = [ tr(i1)%key, PACK(tr(i2)%key, MASK = ixck==0)]
-      tr(i1)%val = [ tr(i1)%val, PACK(tr(i2)%val, MASK = ixck==0)]
+      !=== GET THE INDICES IN tr(i2)%keys%key(:) OF THE KEYS ALSO PRESENT IN tr(i1)%keys%key(:)
+      nk2  =   SIZE(k2(i2)%key(:))                                   !--- Keys number in current section
+      ixck = strIdx(k1(i1)%key(:), k2(i2)%key(:))                    !--- Common keys indexes
+      !--- APPEND THE NEW KEYS PAIRS IN tr(i1)%keys%key(:)
+      tr(i1)%keys%key = [ tr(i1)%keys%key, PACK(tr(i2)%keys%key, MASK = ixck==0)]
+      tr(i1)%keys%val = [ tr(i1)%keys%val, PACK(tr(i2)%keys%val, MASK = ixck==0)]
 
       !=== KEEP TRACK OF THE COMPONENTS NAMES: COMA-SEPARATED LIST
-      lerr = getKey('component', v1, i1, t1)
-      lerr = getKey('component', v2, i2, t2)
-      CALL addKey('component', TRIM(v1)//','//TRIM(v2), tr(i1))
+      lerr = getKey('component', v1, i1, k1)
+      lerr = getKey('component', v2, i2, k2)
+      tr(i1)%component = TRIM(v1)//','//TRIM(v2)
+      CALL addKey('component', TRIM(v1)//','//TRIM(v2), tr(i1)%keys)
 
       !=== FOR TRACERS COMMON TO PREVIOUS AND CURRENT SECTIONS: CHECK WETHER SOME KEYS HAVE DIFFERENT VALUES ; KEEP OLD ONE
       DO ik2 = 1, nk2                                                !--- Collect the corresponding indices
         ik1 = ixck(ik2); IF(ik1 == 0) CYCLE
-        IF(t1(i1)%val(ik1) == t2(i2)%val(ik2)) ixck(ik2)=0
+        IF(k1(i1)%val(ik1) == k2(i2)%val(ik2)) ixck(ik2)=0
       END DO
       IF(ALL(ixck==0)) CYCLE                                         !--- No identical keys with /=values => nothing to display
       CALL msg('Key(s)'//TRIM(s1), modname)                          !--- Display the  keys with /=values (names list)
       DO ik2 = 1, nk2                                                !--- Loop on keys found in both t1(:) and t2(:)
-        knam = t2(i2)%key(ik2)                                       !--- Name of the current key
+        knam = k2(i2)%key(ik2)                                       !--- Name of the current key
         ik1 = ixck(ik2)                                              !--- Corresponding index in t1(:)
         IF(ik1 == 0) CYCLE                                           !--- New keys are skipped
-        v1 = t1(i1)%val(ik1); v2 = t2(i2)%val(ik2)                   !--- Key values in t1(:) and t2(:)
+        v1 = k1(i1)%val(ik1); v2 = k2(i2)%val(ik2)                   !--- Key values in t1(:) and t2(:)
         CALL msg(' * '//TRIM(knam)//'='//TRIM(v2)//' ; previous value kept:'//TRIM(v1), modname)
       END DO
@@ -879,5 +925,5 @@
 LOGICAL FUNCTION cumulTracers(sections, tr, lRename) RESULT(lerr)
   TYPE(dataBase_type),  TARGET, INTENT(IN)  :: sections(:)
-  TYPE(keys_type), ALLOCATABLE, INTENT(OUT) ::       tr(:)
+  TYPE(trac_type), ALLOCATABLE, INTENT(OUT) ::       tr(:)
   LOGICAL,            OPTIONAL, INTENT(IN)  :: lRename               !--- .TRUE.: add a section suffix to identical names
   CHARACTER(LEN=maxlen)  :: tnam_new, modname
@@ -888,16 +934,18 @@
   tr = [( sections(is)%trac(:), is = 1, SIZE(sections) )]            !--- Concatenated tracers vector
   IF(PRESENT(lRename)) THEN; IF(lRename) RETURN; END IF              !--- No renaming: finished
-  lerr = getKey('name',     tname, tr); IF(lerr) RETURN              !--- Names
-  lerr = getKey('parent',  parent, tr); IF(lerr) RETURN              !--- Parents
-  lerr = getKey('component', comp, tr); IF(lerr) RETURN              !--- Component name
+  lerr = getKey('name',     tname, tr%keys); IF(lerr) RETURN         !--- Names
+  lerr = getKey('parent',  parent, tr%keys); IF(lerr) RETURN         !--- Parents
+  lerr = getKey('component', comp, tr%keys); IF(lerr) RETURN         !--- Component name
   !----------------------------------------------------------------------------------------------------------------------------
   DO iq = 1, SIZE(tr); IF(COUNT(tname == tname(iq)) == 1) CYCLE      !=== LOOP ON TRACERS
   !----------------------------------------------------------------------------------------------------------------------------
     tnam_new = TRIM(tname(iq))//'_'//TRIM(comp(iq))                  !--- Same with section extension
-    CALL addKey('name', tnam_new, tr(iq))                            !--- Modify tracer name
+    CALL addKey('name', tnam_new, tr(iq)%keys)                       !--- Modify tracer name
+    tr(iq)%name = TRIM(tnam_new)                                     !--- Modify tracer name
     !--------------------------------------------------------------------------------------------------------------------------
     DO jq = 1, SIZE(tr); IF(parent(jq) /= tname(iq)) CYCLE           !=== LOOP ON TRACERS PARENTS
     !--------------------------------------------------------------------------------------------------------------------------
-      CALL addKey('parent', tnam_new, tr(jq))                        !--- Modify tracer name
+      CALL addKey('parent', tnam_new, tr(jq)%keys)                   !--- Modify tracer name
+      tr(jq)%parent = TRIM(tnam_new)                                 !--- Modify tracer name
     !--------------------------------------------------------------------------------------------------------------------------
     END DO
@@ -946,5 +994,5 @@
     tmp = int2str([(iq, iq=1, nq)])
   ELSE
-    lerr = getKey(nam, tmp, dBase(idb)%trac(:), lDisp=lMandatory)
+    lerr = getKey(nam, tmp, dBase(idb)%trac(:)%keys, lDisp=lMandatory)
   END IF
   IF(lerr) THEN; lerr = lMandatory; RETURN; END IF
@@ -965,10 +1013,10 @@
 LOGICAL FUNCTION aliasTracer(tname, trac, alias) RESULT(lerr)                  !=== TRACER NAMED "tname" - SCALAR
   CHARACTER(LEN=*),         INTENT(IN)  :: tname
-  TYPE(keys_type), TARGET,  INTENT(IN)  :: trac(:)
-  TYPE(keys_type), POINTER, INTENT(OUT) :: alias
+  TYPE(trac_type), TARGET,  INTENT(IN)  :: trac(:)
+  TYPE(trac_type), POINTER, INTENT(OUT) :: alias
   INTEGER :: it
   CHARACTER(LEN=maxlen), ALLOCATABLE :: tnames(:)
   alias => NULL()
-  lerr = getKey('name', tnames, trac(:))
+  lerr = getKey('name', tnames, trac(:)%keys)
   it = strIdx(tnames, tname)
   lerr = it /= 0; IF(.NOT.lerr) alias => trac(it)
@@ -976,7 +1024,7 @@
 !==============================================================================================================================
 LOGICAL FUNCTION trSubset_Indx(trac, idx, alias) RESULT(lerr)                  !=== TRACERS WITH INDICES "idx(:)" - VECTOR
-  TYPE(keys_type), ALLOCATABLE, INTENT(IN)  ::  trac(:)
+  TYPE(trac_type), ALLOCATABLE, INTENT(IN)  ::  trac(:)
   INTEGER,                      INTENT(IN)  ::   idx(:)
-  TYPE(keys_type), ALLOCATABLE, INTENT(OUT) :: alias(:)
+  TYPE(trac_type), ALLOCATABLE, INTENT(OUT) :: alias(:)
   alias = trac(idx)
   lerr = indexUpdate(alias)
@@ -984,9 +1032,9 @@
 !------------------------------------------------------------------------------------------------------------------------------
 LOGICAL FUNCTION trSubset_Name(trac, tname, alias) RESULT(lerr)                !=== TRACERS NAMED "tname(:)" - VECTOR
-  TYPE(keys_type), ALLOCATABLE, INTENT(IN)  ::  trac(:)
+  TYPE(trac_type), ALLOCATABLE, INTENT(IN)  ::  trac(:)
   CHARACTER(LEN=*),             INTENT(IN)  :: tname(:)
-  TYPE(keys_type), ALLOCATABLE, INTENT(OUT) :: alias(:)
+  TYPE(trac_type), ALLOCATABLE, INTENT(OUT) :: alias(:)
   CHARACTER(LEN=maxlen), ALLOCATABLE :: tnames(:)
-  lerr = getKey('name', tnames, trac(:))
+  lerr = getKey('name', tnames, trac(:)%keys)
   alias = trac(strIdx(tnames, tname))
   lerr = indexUpdate(alias)
@@ -994,9 +1042,9 @@
 !==============================================================================================================================
 LOGICAL FUNCTION trSubset_gen0Name(trac, gen0Nm, alias) RESULT(lerr)           !=== TRACERS OF COMMON 1st GENERATION ANCESTOR
-  TYPE(keys_type), ALLOCATABLE, INTENT(IN)  :: trac(:)
+  TYPE(trac_type), ALLOCATABLE, INTENT(IN)  :: trac(:)
   CHARACTER(LEN=*),             INTENT(IN)  :: gen0Nm
-  TYPE(keys_type), ALLOCATABLE, INTENT(OUT) :: alias(:)
+  TYPE(trac_type), ALLOCATABLE, INTENT(OUT) :: alias(:)
   CHARACTER(LEN=maxlen), ALLOCATABLE :: gen0N(:)
-  lerr = getKey('gen0Name', gen0N, trac(:))
+  lerr = getKey('gen0Name', gen0N, trac(:)%keys)
   alias = trac(strFind(delPhase(gen0N), gen0Nm))
   lerr = indexUpdate(alias)
@@ -1006,21 +1054,22 @@
 
 !==============================================================================================================================
-!=== UPDATE THE INDEXES iqParent, iqDescen, nqDescen, nqChildren IN THE TRACERS DESCRIPTOR LIST "tr" ==========================
+!=== UPDATE THE INDEXES iqParent, iqDescend AND iGeneration IN THE TRACERS DESCRIPTOR LIST "tr" (USEFULL FOR SUBSETS) =========
 !==============================================================================================================================
 LOGICAL FUNCTION indexUpdate(tr) RESULT(lerr)
-  TYPE(keys_type), INTENT(INOUT) :: tr(:)
+  TYPE(trac_type), INTENT(INOUT) :: tr(:)
   INTEGER :: iq, jq, nq, ig, nGen
   INTEGER,               ALLOCATABLE :: iqDescen(:), ix(:), iy(:)
   CHARACTER(LEN=maxlen), ALLOCATABLE :: tnames(:), parent(:)
   INTEGER,       DIMENSION(SIZE(tr)) :: iqParent, iGen
-  lerr = getKey('name',   tnames, tr); IF(lerr) RETURN               !--- Names
-  lerr = getKey('parent', parent, tr); IF(lerr) RETURN               !--- Parents
+  lerr = getKey('name',   tnames, tr%keys); IF(lerr) RETURN          !--- Names
+  lerr = getKey('parent', parent, tr%keys); IF(lerr) RETURN          !--- Parents
   nq = SIZE(tr)
 
-  !=== iqParent
+  !=== iqParent, iGeneration
   DO iq = 1, nq; iGen(iq) = 0; jq = iq
     iqParent(iq) = strIdx(tnames, parent(iq))
     DO; jq = strIdx(tnames, parent(jq)); IF(jq == 0) EXIT; iGen(iq) = iGen(iq) + 1; END DO
-    CALL addKey('iqParent', iqParent(iq), tr(iq))
+    CALL addKey('iqParent',   parent(iq), tr(iq)%keys)
+    CALL addKey('iqGeneration', iGen(iq), tr(iq)%keys)
   END DO
 
@@ -1029,12 +1078,14 @@
   DO iq = 1, nq
     ix = [iq]; ALLOCATE(iqDescen(0))
-    CALL addKey('nqChildren', 0, tr(iq))
     DO ig = iGen(iq)+1, nGen
       iy = find(iqParent, ix); iqDescen = [iqDescen, iy]; ix = iy
       IF(ig /= iGen(iq)+1) CYCLE
-      CALL addKey('nqChildren', SIZE(iqDescen), tr(iq))
+      CALL addKey('nqChildren', SIZE(iqDescen), tr(iq)%keys)
+      tr(iq)%nqChildren = SIZE(iqDescen)
     END DO
-    CALL addKey('iqDescen', strStack(int2str(iqDescen)), tr(iq))
-    CALL addKey('nqDescen',             SIZE(iqDescen),  tr(iq))
+    CALL addKey('iqDescen', strStack(int2str(iqDescen)), tr(iq)%keys)
+    CALL addKey('nqDescen',             SIZE(iqDescen),  tr(iq)%keys)
+    tr(iq)%iqDescen =      iqDescen
+    tr(iq)%nqDescen = SIZE(iqDescen)
     DEALLOCATE(iqDescen)
   END DO
@@ -1044,10 +1095,10 @@
   
 !==============================================================================================================================
-!=== READ FILE "fnam" TO APPEND THE "dBase" TRACERS DATABASE WITH AS MUCH SECTIONS AS ISOTOPES CLASSES IN "isot(:)%name":  ====
-!===  * Each section dBase(i)%name contains the isotopes "dBase(i)%trac(:)" descending on "dBase(i)%name"="iso(i)%name"    ====
+!=== READ FILE "fnam" TO APPEND THE "dBase" TRACERS DATABASE WITH AS MUCH SECTIONS AS PARENTS NAMES IN "isot(:)%parent":   ====
+!===  * Each section dBase(i)%name contains the isotopes "dBase(i)%trac(:)" descending on "dBase(i)%name"="iso(i)%parent"  ====
 !===  * For each isotopes class, the <key>=<val> vector of each tracer is moved into the isotopes descriptor "isot"        ====
 !=== NOTES:                                                                                                                ====
 !===  * Most of the "isot" components have been defined in the calling routine (processIsotopes):                          ====
-!===      name,  nzone, zone(:),  niso, keys(:)%name,  ntiso, trac(:),  nphas, phas,  iqIsoPha(:,:),  itZonPhi(:,:)        ====
+!===      parent,  nzone, zone(:),  niso, keys(:)%name,  ntiso, trac(:),  nphas, phas,  iqIsoPha(:,:),  itZonPhi(:,:)      ====
 !===  * Same syntax for isotopes file and "tracer.def": a tracers section contains one line for each of its isotopes       ====
 !===  * Each tracers section can contain a "params" virtual isotope line of isotopes parameters default values             ====
@@ -1058,22 +1109,20 @@
 LOGICAL FUNCTION readIsotopesFile(fnam, isot) RESULT(lerr)
   CHARACTER(LEN=*),        INTENT(IN)    :: fnam                     !--- Input file name
-  TYPE(isot_type), TARGET, INTENT(INOUT) :: isot(:)                  !--- Isotopes descriptors (field %name must be defined!)
+  TYPE(isot_type), TARGET, INTENT(INOUT) :: isot(:)                  !--- Isotopes descriptors (field %parent must be defined!)
   LOGICAL :: lFound
   INTEGER :: is, iis, it, idb, ndb, nb0
-  CHARACTER(LEN=maxlen), ALLOCATABLE :: vals(:), tname(:), iname(:)
+  CHARACTER(LEN=maxlen), ALLOCATABLE :: vals(:)
   CHARACTER(LEN=maxlen)              :: modname
-  TYPE(keys_type),           POINTER ::   t
+  TYPE(trac_type),           POINTER ::   tt(:), t
   TYPE(dataBase_type),   ALLOCATABLE ::  tdb(:)
   modname = 'readIsotopesFile'
 
   !--- THE INPUT FILE MUST BE PRESENT
-  INQUIRE(FILE=TRIM(fnam), EXIST=lFound)
-  lerr = .NOT.lFound
-  CALL msg('Missing isotopes parameters file "'//TRIM(fnam)//'"', modname, lerr)
-  IF(lerr) RETURN
-
-  !--- READ THE FILE SECTIONS, ONE EACH ISOTOPES CLASS (FIEDL %name)
+  INQUIRE(FILE=TRIM(fnam), EXIST=lFound); lerr = .NOT.lFound
+  IF(fmsg('Missing isotopes parameters file "'//TRIM(fnam)//'"', modname, lerr)) RETURN
+
+  !--- READ THE FILE SECTIONS, ONE EACH PARENT TRACER
   nb0 = SIZE(dBase, DIM=1)+1                                         !--- Next database element index
-  lerr = readSections(fnam,strStack(isot(:)%name,'|')); IF(lerr) RETURN !--- Read sections, one each isotopes class %name
+  lerr = readSections(fnam,strStack(isot(:)%parent,'|')); IF(lerr) RETURN !--- Read sections, one each parent tracer
   ndb = SIZE(dBase, DIM=1)                                           !--- Current database size
   DO idb = nb0, ndb
@@ -1081,23 +1130,23 @@
 
     !--- GET FEW GLOBAL KEYS FROM "def" FILES AND ADD THEM TO THE 'params' SECTION
-!    lerr = addKeysFromDef(dBase(idb)%trac, 'params');     IF(lerr) RETURN
+    CALL addKeysFromDef(dBase(idb)%trac, 'params')
 
     !--- SUBSTITUTE THE KEYS DEFINED IN THE 'params' VIRTUAL TRACER ; SUBSTITUTE LOCAL KEYS ; REMOVE 'params' VIRTUAL TRACER
-    lerr = subDefault(dBase(idb)%trac, 'params', .TRUE.); IF(lerr) RETURN
+    CALL subDefault(dBase(idb)%trac, 'params', .TRUE.)
+
+    tt => dBase(idb)%trac
 
     !--- REDUCE THE EXPRESSIONS TO OBTAIN SCALARS AND TRANSFER THEM TO THE "isot" ISOTOPES DESCRIPTORS VECTOR
-    lerr = getKey('name', tname, dBase(idb)%trac);        IF(lerr) RETURN
-    lerr = getKey('name', iname, isot(iis)%keys);         IF(lerr) RETURN
     DO it = 1, SIZE(dBase(idb)%trac)
       t => dBase(idb)%trac(it)
-      is = strIdx(iname, tname(it))                                  !--- Index in "iname(:)" of isotope "tname(it)"
+      is = strIdx(isot(iis)%keys(:)%name, t%name)                    !--- Index in "isot(iis)%keys(:)%name" of isotope "t%name"
       IF(is == 0) CYCLE
-      lerr = ANY(reduceExpr(t%val, vals)); IF(lerr) RETURN           !--- Reduce expressions ; detect non-numerical elements
-      isot(iis)%keys(is)%key = t%key
+      lerr = ANY(reduceExpr(t%keys%val, vals)); IF(lerr) RETURN      !--- Reduce expressions ; detect non-numerical elements
+      isot(iis)%keys(is)%key = t%keys%key
       isot(iis)%keys(is)%val = vals
     END DO
 
     !--- CHECK FOR MISSING ISOTOPES (NO KEYS ALLOCATED)
-    lerr = checkList(iname, .NOT.[( ALLOCATED(isot(iis)%keys(is)%key), is=1, SIZE(isot(iis)%keys) )], &
+    lerr = checkList(isot(iis)%keys(:)%name, .NOT.[( ALLOCATED(isot(iis)%keys(is)%key), is=1, SIZE(isot(iis)%keys) )], &
                      'Check file "'//TRIM(fnam)//'" in section "'//TRIM(dBase(idb)%name)//'"', 'isotopes', 'missing')
     IF(lerr) RETURN
@@ -1112,5 +1161,5 @@
 
   !--- GET THE isoCheck ENTRY FROM THE *.DEF FILES (MIGHT BE CHANGED TO A CLASS-DEPENDANT KEYWORD)
-  CALL get_in('ok_iso_verif', isot(strIdx(iname, 'H2O'))%check, .FALSE.)
+  CALL get_in('ok_iso_verif', isot(strIdx(isot%parent, 'H2O'))%check, .FALSE.)
 
   lerr = dispIsotopes()
@@ -1122,8 +1171,7 @@
   INTEGER :: ik, nk, ip, it, nt
   CHARACTER(LEN=maxlen) :: prf
-  CHARACTER(LEN=maxlen), ALLOCATABLE :: ttl(:), val(:,:), tname(:)
+  CHARACTER(LEN=maxlen), ALLOCATABLE :: ttl(:), val(:,:)
   CALL msg('Isotopes parameters read from file "'//TRIM(fnam)//'":', modname)
-  DO ip = 1, SIZE(isot)                                              !--- Loop on isotopes classes
-    IF(SIZE(isot(ip)%keys) == 0) CYCLE
+  DO ip = 1, SIZE(isot)                                              !--- Loop on parents tracers
     nk = SIZE(isot(ip)%keys(1)%key)                                  !--- Same keys for each isotope
     nt = SIZE(isot(ip)%keys)                                         !--- Number of isotopes
@@ -1131,6 +1179,5 @@
     ALLOCATE(ttl(nk+2), val(nt,nk+1))
     ttl(1:2) = ['it  ','name']; ttl(3:nk+2) = isot(ip)%keys(1)%key(:)!--- Titles line with keys names
-    lerr = getKey('name', tname, isot(ip)%keys); IF(lerr) RETURN
-    val(:,1) = tname                                                 !--- Values table 1st column: isotopes names
+    val(:,1) = isot(ip)%keys(:)%name                                 !--- Values table 1st column: isotopes names  
     DO ik = 1, nk
       DO it = 1, nt
@@ -1152,126 +1199,108 @@
 !=== IF ISOTOPES (2ND GENERATION TRACERS) ARE DETECTED:                                                                     ===
 !===    * COMPUTE MOST OF THE RELATED QUANTITIES ("isot" COMPONENTS).                                                       ===
-!===    * COMPUTE FEW ISOTOPES-DEDICATED "trac" COMPONENTS (defined by "keys(:)")                                           ===
-!===    * CALL readIsotopesFile TO GET PHYSICAL QUANTITIES (<key>=<val> PAIRS)     /!\ DISABLED FUNCTION /!\                ===
-!==============================================================================================================================
-LOGICAL FUNCTION processIsotopes(keys, isot, iClasses) RESULT(lerr)
-  TYPE(keys_type),  TARGET,              OPTIONAL, INTENT(INOUT) ::   keys(:)
-  TYPE(isot_type),  TARGET, ALLOCATABLE, OPTIONAL, INTENT(OUT)   ::   isot(:)
-  CHARACTER(LEN=*), TARGET,              OPTIONAL, INTENT(IN)    :: iClasses(:)
-  CHARACTER(LEN=maxlen), ALLOCATABLE :: str1(:), str2(:)             !--- Temporary storage
-  CHARACTER(LEN=maxlen), ALLOCATABLE :: tname(:), parent(:), dType(:), phase(:), gen0N(:), iCla(:)
-  CHARACTER(LEN=maxlen) :: iClass, modname
-  CHARACTER(LEN=1)      :: ph                                        !--- Phase
-  LOGICAL,  ALLOCATABLE :: ll(:)                                     !--- Mask
-  INTEGER,  ALLOCATABLE :: iGen(:)
-  INTEGER :: ic, ip, iq, ii, it, iz
-  TYPE(isot_type), POINTER :: i1
-  TYPE(keys_type), POINTER :: k(:)
+!===    * COMPUTE FEW ISOTOPES-DEDICATED "trac" COMPONENTS                                                                  ===
+!===    * CALL readIsotopesFile TO GET PHYSICAL QUANTITIES (<key>=<val> PAIRS)                                              ===
+!===      NOTE: THIS IS DONE HERE (IN A ROUTINE CALLED BY THE DYNAMIC), BECAUSE THE DYNAMIC NEEDS FEW PHYSICAL PARAMETERS.  ===
+!==============================================================================================================================
+LOGICAL FUNCTION processIsotopes(iNames) RESULT(lerr)
+  CHARACTER(LEN=maxlen), TARGET, OPTIONAL, INTENT(IN)  :: iNames(:)
+  CHARACTER(LEN=maxlen), ALLOCATABLE :: p(:), str(:)                 !--- Temporary storage
+  CHARACTER(LEN=maxlen), ALLOCATABLE :: tname(:), parent(:), dType(:), phase(:), gen0N(:)
+  CHARACTER(LEN=maxlen) :: iName, modname
+  CHARACTER(LEN=1)   :: ph                                           !--- Phase
+  INTEGER, ALLOCATABLE ::  iGen(:)
+  INTEGER :: ic, ip, iq, it, iz
+  LOGICAL, ALLOCATABLE :: ll(:)                                      !--- Mask
+  TYPE(trac_type), POINTER   ::  t(:), t1
+  TYPE(isot_type), POINTER   ::  i
 
   lerr = .FALSE.
   modname = 'readIsotopesFile'
-  k => tracers; IF(PRESENT(keys )) k => keys
-  lerr = getKey('name',       tname, k); IF(lerr) RETURN             !--- Names
-  lerr = getKey('parent',    parent, k); IF(lerr) RETURN             !--- Parents
-  lerr = getKey('type',       dType, k); IF(lerr) RETURN             !--- Tracer type
-  lerr = getKey('phase',      phase, k); IF(lerr) RETURN             !--- Phase
-  lerr = getKey('gen0Name',   gen0N, k); IF(lerr) RETURN             !--- 1st generation ancestor name
-  lerr = getKey('iGeneration', iGen, k); IF(lerr) RETURN             !--- Generation number
-
-  !--- INITIALIZATION IF ISOTOPES-SPECIFIC KEYS (MUST BE DEFINED EVEN WITHOUT ISOTOPES)
-  DO iq = 1, SIZE(k)
-    CALL addKey('iso_iGroup',0, k(iq))                               !--- Family       idx in list "isotopes(:)%parent"
-    CALL addKey('iso_iName', 0, k(iq))                               !--- Isotope      idx in effective isotopes list
-    CALL addKey('iso_iZone', 0, k(iq))                               !--- Tagging zone idx in effective zones    list
-    CALL addKey('iso_iPhas', 0, k(iq))                               !--- Phase        idx in effective phases   list
-  END DO
+
+  t => tracers
+
+  lerr = getKey('name',       tname, t%keys); IF(lerr) RETURN       !--- Names
+  lerr = getKey('parent',    parent, t%keys); IF(lerr) RETURN       !--- Parents
+  lerr = getKey('type',       dType, t%keys); IF(lerr) RETURN       !--- Tracer type
+  lerr = getKey('phase',      phase, t%keys); IF(lerr) RETURN       !--- Phase
+  lerr = getKey('gen0Name',   gen0N, t%keys); IF(lerr) RETURN       !--- 1st generation ancestor name
+  lerr = getKey('iGeneration', iGen, t%keys); IF(lerr) RETURN       !--- Generation number
 
   !--- GET FROM "tracers" THE FULL LIST OF AVAILABLE ISOTOPES CLASSES
-  iCla = PACK(delPhase(parent), MASK = dType=='tracer' .AND. iGen==1)
-  CALL strReduce(iCla)
-
-  !--- CHECK WHETHER NEEDED ISOTOPES CLASSES "iClasses" ARE AVAILABLE OR NOT
-  IF(PRESENT(iClasses)) THEN
-    DO it = 1, SIZE(iClasses)
-      lerr = ALL(iCla /= iClasses(it))
-      IF(fmsg('No isotopes class "'//TRIM(iClasses(it))//'" found among tracers', modname, lerr)) RETURN
+  p = PACK(delPhase(parent), MASK = dType=='tracer' .AND. iGen==1)
+  CALL strReduce(p, nbIso)
+
+  !--- CHECK WHETHER NEEDED ISOTOPES CLASSES "iNames" ARE AVAILABLE OR NOT
+  IF(PRESENT(iNames)) THEN
+    DO it = 1, SIZE(iNames)
+      lerr = ALL(p /= iNames(it))
+      IF(fmsg('No isotopes class "'//TRIM(iNames(it))//'" found among tracers', modname, lerr)) RETURN
     END DO
-    iCla = iClasses
+    p = iNames; nbIso = SIZE(p)
   END IF
-  nbIso = SIZE(iCla)
-
-  !--- USE THE ARGUMENT "isot" TO STORE THE ISOTOPIC DATABASE OR THE LOCAL VECTOR "isotopes"
-  IF(PRESENT(isot)) THEN
-    ALLOCATE(    isot(nbIso))
-  ELSE
-    IF(ALLOCATED(isotopes)) DEALLOCATE(isotopes)
-    ALLOCATE(isotopes(nbIso))
-  END IF
+  IF(ALLOCATED(isotopes)) DEALLOCATE(isotopes)
+  ALLOCATE(isotopes(nbIso))
+
   IF(nbIso==0) RETURN                                                !=== NO ISOTOPES: FINISHED
 
   !--- ISOTOPES RELATED VARIABLES ; NULL OR EMPTY IF NO ISOTOPES
-  DO ic = 1, nbIso                                                   !--- Loop on isotopes classes
-    IF(     PRESENT(isot)) i1 => isot    (ic)
-    IF(.NOT.PRESENT(isot)) i1 => isotopes(ic)
-    iClass = iCla(ic)                                                !--- Current isotopes class name (parent tracer name)
-    i1%name = iClass
-
-    !=== Isotopes children of tracer "iClass": mask, names, number (same for each phase of "iClass")
-    ll = dType=='tracer' .AND. delPhase(parent) == iClass .AND. phase == 'g'
-    str1 = PACK(delPhase(tname), MASK = ll)                          !--- Effectively found isotopes of "iClass"
-    i1%niso = SIZE(str1)                                             !--- Number of "effectively found isotopes of "iname"
-    ALLOCATE(i1%keys(i1%niso))
-    DO it = 1, i1%niso; CALL addKey('name', str1(it), i1%keys(it)); END DO
-
-    !=== Geographic tagging tracers descending on tracer "iClass": mask, names, number
-    ll = dType=='tag'    .AND. delPhase(gen0N) == iClass .AND. iGen == 2
-    i1%zone = PACK(strTail(tname, '_', .TRUE.), MASK = ll)           !--- Tagging zones names  for isotopes category "iname"
-    CALL strReduce(i1%zone)
-    i1%nzone = SIZE(i1%zone)                                         !--- Tagging zones number for isotopes category "iClass"
-
-    !=== Geographic tracers of the isotopes children of tracer "iClass" (same for each phase of "iClass")
+  isotopes(:)%parent = p
+  DO ic = 1, SIZE(p)                                                 !--- Loop on isotopes classes
+    i => isotopes(ic)
+    iname = i%parent                                                 !--- Current isotopes class name (parent tracer name)
+
+    !=== Isotopes children of tracer "iname": mask, names, number (same for each phase of "iname")
+    ll = dType=='tracer' .AND. delPhase(parent) == iname .AND. phase == 'g'
+    str = PACK(delPhase(tname), MASK = ll)                           !--- Effectively found isotopes of "iname"
+    i%niso = SIZE(str)                                               !--- Number of "effectively found isotopes of "iname"
+    ALLOCATE(i%keys(i%niso))
+    FORALL(it = 1:i%niso) i%keys(it)%name = str(it)
+
+    !=== Geographic tagging tracers descending on tracer "iname": mask, names, number
+    ll = dType=='tag'    .AND. delPhase(gen0N) == iname .AND. iGen == 2
+    i%zone = PACK(strTail(tname,'_',.TRUE.), MASK = ll)              !--- Tagging zones names  for isotopes category "iname"
+    CALL strReduce(i%zone)
+    i%nzone = SIZE(i%zone)                                           !--- Tagging zones number for isotopes category "iname"
+
+    !=== Geographic tracers of the isotopes children of tracer "iname" (same for each phase of "iname")
     !    NOTE: One might like to create a similar variable for 2nd generation tagging tracers (tagging the gen1 tracers)
-    str2 = PACK(delPhase(tname), MASK=ll)
-    CALL strReduce(str2)
-    i1%ntiso = i1%niso + SIZE(str2)                                  !--- Number of isotopes + their geographic tracers [ntiso]
-    ALLOCATE(i1%trac(i1%ntiso))
-    DO it =         1, i1%niso;  i1%trac(it) = str1(it);         END DO
-    DO it = i1%niso+1, i1%ntiso; i1%trac(it) = str2(it-i1%niso); END DO
-
-    !=== Phases for tracer "iClass"
-    i1%phase = ''
-    DO ip = 1, nphases; ph = known_phases(ip:ip); IF(ANY(tname == addPhase(iClass, ph))) i1%phase = TRIM(i1%phase)//ph; END DO
-    i1%nphas = LEN_TRIM(i1%phase)                                       !--- Equal to "nqo" for water
+    str = PACK(delPhase(tname), MASK=ll)
+    CALL strReduce(str)
+    i%ntiso = i%niso + SIZE(str)                                     !--- Number of isotopes + their geographic tracers [ntiso]
+    ALLOCATE(i%trac(i%ntiso))
+    FORALL(it = 1:i%niso) i%trac(it) = i%keys(it)%name
+    FORALL(it = i%niso+1:i%ntiso) i%trac(it) = str(it-i%niso)
+
+    !=== Phases for tracer "iname"
+    i%phase = ''
+    DO ip = 1, nphases; ph = known_phases(ip:ip); IF(strIdx(t%name,addPhase(iname, ph)) /= 0) i%phase = TRIM(i%phase)//ph; END DO
+    i%nphas = LEN_TRIM(i%phase)                                       !--- Equal to "nqo" for water
 
     !=== Tables giving the index in a table of effectively found items for each dynamical tracer (1<=iq<=nqtot)
-    DO iq = 1, SIZE(tracers)
-      ii = strIdx(i1%trac, strHead(delPhase(tname(iq)), '_', .TRUE.))
-      iz = strIdx(i1%zone, strTail(         tname(iq),  '_', .TRUE.))
-      ip =  INDEX(i1%phase,            TRIM(phase(iq)              ))
-      IF(delPhase(gen0N(iq)) /= iClass .OR. iGen(iq) == 0) CYCLE     !--- Only deal with tracers descending on "iClass"
-      CALL addKey('iso_iGroup',ic, k(iq))                            !--- Family       idx in list "isotopes(:)%name"
-      CALL addKey('iso_iName', ii, k(iq))                            !--- Isotope      idx in effective isotopes list
-      CALL addKey('iso_iZone', iz, k(iq))                            !--- Tagging zone idx in effective zones    list
-      CALL addKey('iso_iPhas', ip, k(iq))                            !--- Phase        idx in effective phases   list
-      IF(iGen(iq) /= 2) CALL addKey('iso_iZone', 0, k(iq))           !--- Skip possible generation 1 tagging tracers
+    DO iq = 1, SIZE(t)
+      t1 => tracers(iq)
+      IF(delPhase(t1%gen0Name)/=iname .OR. t1%iGeneration==0) CYCLE  !--- Only deal with tracers descending on "iname"
+      t1%iso_iGroup = ic                                             !--- Isotopes family       idx in list "isotopes(:)%parent"
+      t1%iso_iName  = strIdx(i%trac, strHead(delPhase(t1%name),'_',.TRUE.)) !--- Current isotope       idx in effective isotopes list
+      t1%iso_iZone  = strIdx(i%zone,          strTail(t1%name, '_',.TRUE.)) !--- Current isotope zone  idx in effective zones    list
+      t1%iso_iPhase =  INDEX(i%phase,TRIM(t1%phase))                 !--- Current isotope phase idx in effective phases   list
+      IF(t1%iGeneration /= 2) t1%iso_iZone = 0                       !--- Skip possible generation 1 tagging tracers
     END DO
 
     !=== Table used to get iq (index in dyn array, size nqtot) from the isotope and phase indexes ; the full isotopes list
     !    (including tagging tracers) is sorted this way:  iso1, iso2, ..., iso1_zone1, iso2_zone1, ..., iso1_zoneN, iso2_zoneN
-    i1%iqIsoPha = RESHAPE( [( (strIdx(tname,  addPhase(i1%trac(it),i1%phase(ip:ip))),         it=1, i1%ntiso), ip=1, i1%nphas)], &
-                         [i1%ntiso, i1%nphas] )
+    i%iqIsoPha = RESHAPE( [( (strIdx(t%name,  addPhase(i%trac(it),i%phase(ip:ip))),       it=1, i%ntiso), ip=1, i%nphas)], &
+                         [i%ntiso, i%nphas] )
     !=== Table used to get iq (index in dyn array, size nqtot) from the water and isotope and phase indexes ; the full isotopes list
     !    (including tagging tracers) is sorted this way:  iso1, iso2, ..., iso1_zone1, iso2_zone1, ..., iso1_zoneN, iso2_zoneN
-    i1%iqWIsoPha = RESHAPE( [( [strIdx(tname, addPhase('H2O',      i1%phase(ip:ip))), i1%iqIsoPha(:,ip)],      ip=1, i1%nphas)], &
-                         [1+i1%ntiso, i1%nphas] )
+    i%iqWIsoPha = RESHAPE( [( [strIdx(t%name,   addPhase('H2O',i%phase(ip:ip))), i%iqIsoPha(:,ip)], ip=1,i%nphas)], &
+                         [1+i%ntiso, i%nphas] )
     !=== Table used to get ix (index in tagging tracers isotopes list, size ntiso) from the zone and isotope indexes
-    i1%itZonIso = RESHAPE( [( (strIdx(i1%trac(:), TRIM(i1%trac(it))//'_'//TRIM(i1%zone(iz))), iz=1, i1%nzone), it=1, i1%niso )], &
-                         [i1%nzone, i1%niso] )
+    i%itZonIso = RESHAPE( [( (strIdx(i%trac(:), TRIM(i%trac(it))//'_'//TRIM(i%zone(iz))), iz=1, i%nzone), it=1, i%niso )], &
+                         [i%nzone, i%niso] )
   END DO
 
-  !=== READ PHYSICAL PARAMETERS FROM isoFile FILE (COMMENTED => DISABLED)
-!  IF(     PRESENT(isot)) lerr = readIsotopesFile(isoFile, isot)
-!  IF(.NOT.PRESENT(isot)) lerr = readIsotopesFile(isoFile, isotopes)
-!  IF(lerr) RETURN
+  !=== READ PHYSICAL PARAMETERS FROM isoFile FILE
+!  lerr = readIsotopesFile(isoFile, isotopes); IF(lerr) RETURN! on commente pour ne pas chercher isotopes_params.def
 
   !--- GET THE isoCheck ENTRY FROM THE *.DEF FILES (MIGHT BE CHANGED TO A CLASS-DEPENDANT KEYWORD)
@@ -1282,9 +1311,5 @@
 
   !=== SELECT WATER ISOTOPES CLASS OR, IF UNFOUND, THE FIRST ISOTOPES CLASS
-  IF(isoSelect('H2O', lVerbose=.TRUE.)) THEN
-    iH2O = ixIso
-  ELSE
-    lerr = isoSelect(1, lVerbose=.TRUE.)
-  END IF
+  IF(isoSelect('H2O', .TRUE.)) THEN; iH2O = ixIso; ELSE; lerr = isoSelect(1, .TRUE.); END IF
 
 CONTAINS
@@ -1294,18 +1319,18 @@
 !------------------------------------------------------------------------------------------------------------------------------
   INTEGER :: ix, it, ip, np, iz, nz, npha, nzon
+  TYPE(isot_type), POINTER :: i
   DO ix = 1, nbIso
-    IF(     PRESENT(isot)) i1 => isot    (ix)
-    IF(.NOT.PRESENT(isot)) i1 => isotopes(ix)
+    i => isotopes(ix)
     !--- Check whether each isotope and tagging isotopic tracer is present in the same number of phases
-    DO it = 1, i1%ntiso; npha = i1%nphas
-      np = SUM([(COUNT(tname(:) == addPhase(i1%trac(it), i1%phase(ip:ip))), ip=1, npha)])
+    DO it = 1, i%ntiso; npha = i%nphas
+      np = SUM([(COUNT(tracers(:)%name == addPhase(i%trac(it), i%phase(ip:ip))), ip=1, npha)])
       lerr = np /= npha
-      CALL msg(TRIM(int2str(np))//       ' phases instead of '//TRIM(int2str(npha))//' for '//TRIM(i1%trac(it)), modname, lerr)
+      CALL msg(TRIM(int2str(np))//' phases instead of '//TRIM(int2str(npha))//' for '//TRIM(i%trac(it)), modname, lerr)
       IF(lerr) RETURN
     END DO
-    DO it = 1, i1%niso; nzon = i1%nzone
-      nz = SUM([(COUNT(i1%trac == TRIM(i1%trac(it))//'_'//i1%zone(iz)), iz=1, nzon)])
+    DO it = 1, i%niso; nzon = i%nzone
+      nz = SUM([(COUNT(i%trac == TRIM(i%trac(it))//'_'//i%zone(iz)), iz=1, nzon)])
       lerr = nz /= nzon
-      CALL msg(TRIM(int2str(nz))//' tagging zones instead of '//TRIM(int2str(nzon))//' for '//TRIM(i1%trac(it)), modname, lerr)
+      CALL msg(TRIM(int2str(nz))//' tagging zones instead of '//TRIM(int2str(nzon))//' for '//TRIM(i%trac(it)), modname, lerr)
       IF(lerr) RETURN
     END DO
@@ -1320,43 +1345,37 @@
 !==============================================================================================================================
 !=== THE ROUTINE isoSelect IS USED TO SWITCH FROM AN ISOTOPE FAMILY TO ANOTHER: ISOTOPES DEPENDENT PARAMETERS ARE UPDATED
-!     Single generic "isoSelect" routine, using the predefined index of the class (fast version) or its name (first call).
-!==============================================================================================================================
-LOGICAL FUNCTION isoSelectByName(iClass, isot, lVerbose) RESULT(lerr)
+!     Single generic "isoSelect" routine, using the predefined index of the parent (fast version) or its name (first call).
+!==============================================================================================================================
+LOGICAL FUNCTION isoSelectByName(iName, lVerbose) RESULT(lerr)
    IMPLICIT NONE
-   CHARACTER(LEN=*),                  INTENT(IN) :: iClass
-   TYPE(isot_type), OPTIONAL, TARGET, INTENT(IN) :: isot(:)
-   LOGICAL,         OPTIONAL,         INTENT(IN) :: lVerbose
-   TYPE(isot_type), POINTER :: iso(:)
+   CHARACTER(LEN=*),  INTENT(IN) :: iName
+   LOGICAL, OPTIONAL, INTENT(IN) :: lVerbose
    INTEGER :: iIso
    LOGICAL :: lV
-   lV = .FALSE.;    IF(PRESENT(lVerbose)) lV = lVerbose
-   iso => isotopes; IF(PRESENT(isot))    iso => isot
-   iIso = strIdx(iso(:)%name, iClass)
+   lV = .FALSE.; IF(PRESENT(lVerbose)) lV = lVerbose
+   iIso = strIdx(isotopes(:)%parent, iName)
    lerr = iIso == 0
    IF(lerr) THEN
       niso = 0; ntiso = 0; nzone = 0; nphas = 0; isoCheck=.FALSE.
-      CALL msg('no isotope family named "'//TRIM(iClass)//'"', ll=lV)
+      CALL msg('no isotope family named "'//TRIM(iName)//'"', ll=lV)
       RETURN
    END IF
-   lerr = isoSelectByIndex(iIso, iso, lV)
+   lerr = isoSelectByIndex(iIso, lV)
 END FUNCTION isoSelectByName
 !==============================================================================================================================
-LOGICAL FUNCTION isoSelectByIndex(iIso, isot, lVerbose) RESULT(lerr)
+LOGICAL FUNCTION isoSelectByIndex(iIso, lVerbose) RESULT(lerr)
    IMPLICIT NONE
-   INTEGER,                           INTENT(IN)    :: iIso
-   TYPE(isot_type), TARGET, OPTIONAL, INTENT(INOUT) :: isot(:)
-   LOGICAL,                 OPTIONAL, INTENT(IN)    :: lVerbose
-   TYPE(isot_type), POINTER :: i(:)
+   INTEGER,           INTENT(IN) :: iIso
+   LOGICAL, OPTIONAL, INTENT(IN) :: lVerbose
    LOGICAL :: lV
-   lV = .FALSE.;  IF(PRESENT(lVerbose)) lV = lVerbose
-   i => isotopes; IF(PRESENT(isot))      i => isot
+   lv = .FALSE.; IF(PRESENT(lVerbose)) lv = lVerbose
    lerr = .FALSE.
    IF(iIso == ixIso) RETURN                                          !--- Nothing to do if the index is already OK
-   lerr = iIso<=0 .OR. iIso>SIZE(i)
+   lerr = iIso<=0 .OR. iIso>SIZE(isotopes)
    CALL msg('Inconsistent isotopes family index '//TRIM(int2str(iIso))//': should be > 0 and <= '&
-          //TRIM(int2str(SIZE(i)))//'"', ll = lerr .AND. lV)
+          //TRIM(int2str(SIZE(isotopes)))//'"', ll = lerr .AND. lV)
    IF(lerr) RETURN
    ixIso = iIso                                                      !--- Update currently selected family index
-   isotope  => i(ixIso)                                              !--- Select corresponding component
+   isotope  => isotopes(ixIso)                                       !--- Select corresponding component
    isoKeys  => isotope%keys;     niso     = isotope%niso
    isoName  => isotope%trac;     ntiso    = isotope%ntiso
@@ -1365,5 +1384,5 @@
    itZonIso => isotope%itZonIso; isoCheck = isotope%check
    iqIsoPha => isotope%iqIsoPha
-   iqWIsoPha=> isotope%iqWIsoPha
+   iqWIsoPha => isotope%iqWIsoPha
 END FUNCTION isoSelectByIndex
 !==============================================================================================================================
@@ -1509,19 +1528,17 @@
 !=== OVERWRITE THE KEYS OF THE TRACER NAMED "tr0" WITH THE VALUES FOUND IN THE *.def FILES, IF ANY. ===========================
 !==============================================================================================================================
-LOGICAL FUNCTION addKeysFromDef(t, tr0) RESULT(lerr)
-  TYPE(keys_type), ALLOCATABLE, INTENT(INOUT) :: t(:)
+SUBROUTINE addKeysFromDef(t, tr0)
+  TYPE(trac_type), ALLOCATABLE, INTENT(INOUT) :: t(:)
   CHARACTER(LEN=*),             INTENT(IN)    :: tr0
 !------------------------------------------------------------------------------------------------------------------------------
-  CHARACTER(LEN=maxlen), ALLOCATABLE :: tname(:)
   CHARACTER(LEN=maxlen) :: val
   INTEGER               :: ik, jd
-  lerr = getKey('name', tname, t); IF(lerr) RETURN
-  jd = strIdx(tname(:), tr0)
+  jd = strIdx(t%name, tr0)
   IF(jd == 0) RETURN
-  DO ik = 1, SIZE(t(jd)%key)
-    CALL get_in(t(jd)%key(ik), val, '*none*')
-    IF(val /= '*none*') CALL addKey(t(jd)%key(ik), val, t(jd), .TRUE.)
+  DO ik = 1, SIZE(t(jd)%keys%key)
+    CALL get_in(t(jd)%keys%key(ik), val, '*none*')
+    IF(val /= '*none*') CALL addKey(t(jd)%keys%key(ik), val, t(jd)%keys, .TRUE.)
   END DO
-END FUNCTION addKeysFromDef
+END SUBROUTINE addKeysFromDef
 !==============================================================================================================================
 
@@ -1533,5 +1550,5 @@
   INTEGER,          INTENT(IN)    :: itr
   CHARACTER(LEN=*), INTENT(IN)    :: keyn(:)
-  TYPE(keys_type),  INTENT(INOUT) :: ky(:)
+  TYPE(trac_type),  INTENT(INOUT) :: ky(:)
 !------------------------------------------------------------------------------------------------------------------------------
   CHARACTER(LEN=maxlen), ALLOCATABLE :: k(:), v(:)
@@ -1539,12 +1556,12 @@
   INTEGER :: iky
   IF(itr<=0 .OR. itr>SIZE(ky, DIM=1)) RETURN                          !--- Index is out of range
-  ll = [( ALL(keyn/=ky(itr)%key(iky)), iky=1, SIZE(ky(itr)%key) )]
-  k = PACK(ky(itr)%key, MASK=ll); CALL MOVE_ALLOC(FROM=k, TO=ky(itr)%key)
-  v = PACK(ky(itr)%val, MASK=ll); CALL MOVE_ALLOC(FROM=v, TO=ky(itr)%val)
+  ll = [( ALL(keyn/=ky(itr)%keys%key(iky)), iky=1, SIZE(ky(itr)%keys%key) )]
+  k = PACK(ky(itr)%keys%key, MASK=ll); CALL MOVE_ALLOC(FROM=k, TO=ky(itr)%keys%key)
+  v = PACK(ky(itr)%keys%val, MASK=ll); CALL MOVE_ALLOC(FROM=v, TO=ky(itr)%keys%val)
 END SUBROUTINE delKey_1
 !==============================================================================================================================
 SUBROUTINE delKey(keyn, ky)
   CHARACTER(LEN=*), INTENT(IN)    :: keyn(:)
-  TYPE(keys_type),  INTENT(INOUT) :: ky(:)
+  TYPE(trac_type),  INTENT(INOUT) :: ky(:)
 !------------------------------------------------------------------------------------------------------------------------------
   INTEGER :: iky
@@ -1594,5 +1611,5 @@
 !=== TRY TO GET THE KEY NAMED "key" FOR THE "itr"th TRACER IN:                                                              ===
 !===  * ARGUMENT "ky" DATABASE IF SPECIFIED ; OTHERWISE:                                                                    ===
-!===  * IN INTERNAL TRACERS DATABASE "tracers(:)" (IF UNFOUND, IN INTERNAL ISOTOPES DATABASE "isotope%keys(:)")             ===
+!===  * IN INTERNAL TRACERS DATABASE "tracers(:)%keys" (IF UNFOUND, IN INTERNAL ISOTOPES DATABASE "isotope%keys(:)")        ===
 !=== THE RETURNED VALUE (STRING, AN INTEGER, A REAL OR A LOGICAL) CAN BE EITHER:                                            ===
 !===  * A SCALAR                                                                                                            ===
@@ -1660,5 +1677,5 @@
   lerr = .TRUE.
   IF(lerr .AND. PRESENT(ky))         val = fgetKey(ky)                                   !--- "ky"
-  IF(lerr .AND. ALLOCATED (tracers)) val = fgetKey(tracers(:))                           !--- "tracers"
+  IF(lerr .AND. ALLOCATED (tracers)) val = fgetKey(tracers(:)%keys)                      !--- "tracers"
   IF(lerr .AND. ASSOCIATED(isotope)) val = fgetKey(isotope%keys(:))                      !--- "isotope"
   IF(lerr .AND. PRESENT(def)) THEN
@@ -1765,5 +1782,5 @@
   IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN
   val = str2int(svals)
-  lerr = ANY(val == -HUGE(1)) .AND. sval /= ''
+  lerr = ANY(val == -HUGE(1))
   s = 'key "'//TRIM(keyn)//'" of tracer nr. '//TRIM(int2str(itr))//' is not'
   CALL msg(TRIM(s)//' an integer: '//TRIM(sval), modname, lerr)
@@ -1785,5 +1802,5 @@
   IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN
   val = str2real(svals)
-  lerr = ANY(val == -HUGE(1.)) .AND. sval /= ''
+  lerr = ANY(val == -HUGE(1.))
   s = 'key "'//TRIM(keyn)//'" of tracer nr. '//TRIM(int2str(itr))//' is not'
   CALL msg(TRIM(s)//' a real: '//TRIM(sval), modname, lerr)
@@ -1806,5 +1823,5 @@
   IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN
   ivals = str2bool(svals)
-  lerr = ANY(ivals == -1) .AND. sval /= ''
+  lerr = ANY(ivals == -1)
   s = 'key "'//TRIM(keyn)//'" of tracer nr. '//TRIM(int2str(itr))//' is not'
   CALL msg(TRIM(s)//' a boolean: '//TRIM(sval), modname, lerr)
@@ -1843,5 +1860,5 @@
   IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN
   val = str2int(svals)
-  lerr = ANY(val == -HUGE(1)) .AND. sval /= ''
+  lerr = ANY(val == -HUGE(1))
   s = 'key "'//TRIM(strStack(keyn, '/'))//'" of tracer nr. '//TRIM(int2str(itr))//' is not'
   CALL msg(TRIM(s)//' an integer: '//TRIM(sval), modname, lerr)
@@ -1864,5 +1881,5 @@
   IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN
   val = str2real(svals)
-  lerr = ANY(val == -HUGE(1.)) .AND. sval /= ''
+  lerr = ANY(val == -HUGE(1.))
   s = 'key "'//TRIM(strStack(keyn, '/'))//'" of tracer nr. '//TRIM(int2str(itr))//' is not'
   CALL msg(TRIM(s)//' a real: '//TRIM(sval), modname, lerr)
@@ -1886,5 +1903,5 @@
   IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN
   ivals = str2bool(svals)
-  lerr = ANY(ivals == -1) .AND. sval /= ''
+  lerr = ANY(ivals == -1)
   s = 'key "'//TRIM(strStack(keyn, '/'))//'" of tracer nr. '//TRIM(int2str(itr))//' is not'
   CALL msg(TRIM(s)//' a boolean: '//TRIM(sval), modname, lerr)
@@ -1893,49 +1910,55 @@
 !==============================================================================================================================
 !==============================================================================================================================
-LOGICAL FUNCTION getKeyByIndex_s1mm(keyn, val, ky, def, lDisp) RESULT(lerr)
-  CHARACTER(LEN=*),                   INTENT(IN)  :: keyn
-  CHARACTER(LEN=maxlen), ALLOCATABLE, INTENT(OUT) :: val(:)
-  TYPE(keys_type),       OPTIONAL,    INTENT(IN)  ::  ky(:)
-  CHARACTER(LEN=*),      OPTIONAL,    INTENT(IN)  :: def
-  LOGICAL,               OPTIONAL,    INTENT(IN)  :: lDisp
-  lerr = getKeyByIndex_smmm([keyn], val, ky, def, lDisp)
+LOGICAL FUNCTION getKeyByIndex_s1mm(keyn, val, ky, nam, def, lDisp) RESULT(lerr)
+  CHARACTER(LEN=*),                             INTENT(IN)  :: keyn
+  CHARACTER(LEN=maxlen),           ALLOCATABLE, INTENT(OUT) :: val(:)
+  TYPE(keys_type),       OPTIONAL,              INTENT(IN)  ::  ky(:)
+  CHARACTER(LEN=maxlen), OPTIONAL, ALLOCATABLE, INTENT(OUT) :: nam(:)
+  CHARACTER(LEN=*),      OPTIONAL,              INTENT(IN)  :: def
+  LOGICAL,               OPTIONAL,              INTENT(IN)  :: lDisp
+  lerr = getKeyByIndex_smmm([keyn], val, ky, nam, def, lDisp)
 END FUNCTION getKeyByIndex_s1mm
 !==============================================================================================================================
-LOGICAL FUNCTION getKeyByIndex_i1mm(keyn, val, ky, def, lDisp) RESULT(lerr)
-  CHARACTER(LEN=*),                   INTENT(IN)  :: keyn
-  INTEGER,               ALLOCATABLE, INTENT(OUT) :: val(:)
-  TYPE(keys_type),       OPTIONAL,    INTENT(IN)  ::  ky(:)
-  INTEGER,               OPTIONAL,    INTENT(IN)  :: def
-  LOGICAL,               OPTIONAL,    INTENT(IN)  :: lDisp
-  lerr = getKeyByIndex_immm([keyn], val, ky, def, lDisp)
+LOGICAL FUNCTION getKeyByIndex_i1mm(keyn, val, ky, nam, def, lDisp) RESULT(lerr)
+  CHARACTER(LEN=*),                             INTENT(IN)  :: keyn
+  INTEGER,                         ALLOCATABLE, INTENT(OUT) :: val(:)
+  TYPE(keys_type),       OPTIONAL,              INTENT(IN)  ::  ky(:)
+  CHARACTER(LEN=maxlen), OPTIONAL, ALLOCATABLE, INTENT(OUT) :: nam(:)
+  INTEGER,               OPTIONAL,              INTENT(IN)  :: def
+  LOGICAL,               OPTIONAL,              INTENT(IN)  :: lDisp
+  lerr = getKeyByIndex_immm([keyn], val, ky, nam, def, lDisp)
 END FUNCTION getKeyByIndex_i1mm
 !==============================================================================================================================
-LOGICAL FUNCTION getKeyByIndex_r1mm(keyn, val, ky, def, lDisp) RESULT(lerr)
-  CHARACTER(LEN=*),                   INTENT(IN)  :: keyn
-  REAL,                  ALLOCATABLE, INTENT(OUT) :: val(:)
-  TYPE(keys_type),       OPTIONAL,    INTENT(IN)  ::  ky(:)
-  REAL,                  OPTIONAL,    INTENT(IN)  :: def
-  LOGICAL,               OPTIONAL,    INTENT(IN)  :: lDisp
-  lerr = getKeyByIndex_rmmm([keyn], val, ky, def, lDisp)
+LOGICAL FUNCTION getKeyByIndex_r1mm(keyn, val, ky, nam, def, lDisp) RESULT(lerr)
+  CHARACTER(LEN=*),                             INTENT(IN)  :: keyn
+  REAL,                            ALLOCATABLE, INTENT(OUT) :: val(:)
+  TYPE(keys_type),       OPTIONAL,              INTENT(IN)  ::  ky(:)
+  CHARACTER(LEN=maxlen), OPTIONAL, ALLOCATABLE, INTENT(OUT) :: nam(:)
+  REAL,                  OPTIONAL,              INTENT(IN)  :: def
+  LOGICAL,               OPTIONAL,              INTENT(IN)  :: lDisp
+  lerr = getKeyByIndex_rmmm([keyn], val, ky, nam, def, lDisp)
 END FUNCTION getKeyByIndex_r1mm
 !==============================================================================================================================
-LOGICAL FUNCTION getKeyByIndex_l1mm(keyn, val, ky, def, lDisp) RESULT(lerr)
-  CHARACTER(LEN=*),                   INTENT(IN)  :: keyn
-  LOGICAL,               ALLOCATABLE, INTENT(OUT) :: val(:)
-  TYPE(keys_type),       OPTIONAL,    INTENT(IN)  ::  ky(:)
-  LOGICAL,               OPTIONAL,    INTENT(IN)  :: def
-  LOGICAL,               OPTIONAL,    INTENT(IN)  :: lDisp
-  lerr = getKeyByIndex_lmmm([keyn], val, ky, def, lDisp)
+LOGICAL FUNCTION getKeyByIndex_l1mm(keyn, val, ky, nam, def, lDisp) RESULT(lerr)
+  CHARACTER(LEN=*),                             INTENT(IN)  :: keyn
+  LOGICAL,                         ALLOCATABLE, INTENT(OUT) :: val(:)
+  TYPE(keys_type),       OPTIONAL,              INTENT(IN)  ::  ky(:)
+  CHARACTER(LEN=maxlen), OPTIONAL, ALLOCATABLE, INTENT(OUT) :: nam(:)
+  LOGICAL,               OPTIONAL,              INTENT(IN)  :: def
+  LOGICAL,               OPTIONAL,              INTENT(IN)  :: lDisp
+  lerr = getKeyByIndex_lmmm([keyn], val, ky, nam, def, lDisp)
 END FUNCTION getKeyByIndex_l1mm
 !==============================================================================================================================
 !==============================================================================================================================
-LOGICAL FUNCTION getKeyByIndex_smmm(keyn, val, ky, def, lDisp) RESULT(lerr)
-  CHARACTER(LEN=*),                   INTENT(IN)  :: keyn(:)
-  CHARACTER(LEN=maxlen), ALLOCATABLE, INTENT(OUT) ::  val(:)
-  TYPE(keys_type),       OPTIONAL,    INTENT(IN)  ::   ky(:)
-  CHARACTER(LEN=*),      OPTIONAL,    INTENT(IN)  ::  def
-  LOGICAL,               OPTIONAL,    INTENT(IN)  :: lDisp
+LOGICAL FUNCTION getKeyByIndex_smmm(keyn, val, ky, nam, def, lDisp) RESULT(lerr)
+  CHARACTER(LEN=*),                             INTENT(IN)  :: keyn(:)
+  CHARACTER(LEN=maxlen),           ALLOCATABLE, INTENT(OUT) ::  val(:)
+  TYPE(keys_type),       OPTIONAL,              INTENT(IN)  ::   ky(:)
+  CHARACTER(LEN=maxlen), OPTIONAL, ALLOCATABLE, INTENT(OUT) ::  nam(:)
+  CHARACTER(LEN=*),      OPTIONAL,              INTENT(IN)  ::  def
+  LOGICAL,               OPTIONAL,              INTENT(IN)  :: lDisp
 !------------------------------------------------------------------------------------------------------------------------------
   CHARACTER(LEN=maxlen) :: s
+  CHARACTER(LEN=maxlen), ALLOCATABLE :: tname(:)
   INTEGER :: iq, nq(3), k
   LOGICAL :: lD, l(3)
@@ -1944,8 +1967,8 @@
   lerr = .TRUE.
   IF(PRESENT(ky)) THEN;                 val = fgetKey(ky)                                !--- "ky"
-  ELSE IF(ALLOCATED(tracers)) THEN;     val = fgetKey(tracers(:))                        !--- "tracers"
+  ELSE IF(ALLOCATED(tracers)) THEN;     val = fgetKey(tracers(:)%keys)                   !--- "tracers"
      IF(lerr .AND. ASSOCIATED(isotope)) val = fgetKey(isotope%keys(:))                   !--- "isotope"
   END IF
-  IF(.NOT.lerr) RETURN
+  IF(.NOT.lerr) THEN; IF(PRESENT(nam)) nam = tname; RETURN; END IF
   IF(.NOT.PRESENT(def)) THEN; CALL msg('No '//TRIM(s)//' found', modname, lD); RETURN; END IF
 
@@ -1968,4 +1991,5 @@
   INTEGER :: iq
   lerr = SIZE(ky) == 0; IF(lerr) RETURN
+  tname = ky%name
   val = [(fgetKeyIdx(iq, keyn(:), ky, ler(iq)), iq = 1, SIZE(ky))]
   lerr = ANY(ler)
@@ -1974,52 +1998,54 @@
 END FUNCTION getKeyByIndex_smmm
 !==============================================================================================================================
-LOGICAL FUNCTION getKeyByIndex_immm(keyn, val, ky, def, lDisp) RESULT(lerr)
-  CHARACTER(LEN=*),          INTENT(IN)  :: keyn(:)
-  INTEGER,      ALLOCATABLE, INTENT(OUT) ::  val(:)
-  TYPE(keys_type), OPTIONAL, INTENT(IN)  ::   ky(:)
-  INTEGER,         OPTIONAL, INTENT(IN)  ::  def
-  LOGICAL,         OPTIONAL, INTENT(IN)  :: lDisp
+LOGICAL FUNCTION getKeyByIndex_immm(keyn, val, ky, nam, def, lDisp) RESULT(lerr)
+  CHARACTER(LEN=*),                             INTENT(IN)  :: keyn(:)
+  INTEGER,                         ALLOCATABLE, INTENT(OUT) ::  val(:)
+  TYPE(keys_type),       OPTIONAL,              INTENT(IN)  ::   ky(:)
+  CHARACTER(LEN=maxlen), OPTIONAL, ALLOCATABLE, INTENT(OUT) ::  nam(:)
+  INTEGER,               OPTIONAL,              INTENT(IN)  ::  def
+  LOGICAL,               OPTIONAL,              INTENT(IN)  :: lDisp
 !------------------------------------------------------------------------------------------------------------------------------
   CHARACTER(LEN=maxlen) :: s
   CHARACTER(LEN=maxlen), ALLOCATABLE :: svals(:), tname(:)
   LOGICAL,               ALLOCATABLE ::    ll(:)
-  IF(     PRESENT(def)) lerr = getKeyByIndex_smmm(keyn, svals, ky, int2str(def), lDisp)
-  IF(.NOT.PRESENT(def)) lerr = getKeyByIndex_smmm(keyn, svals, ky, lDisp=lDisp)
+  IF(     PRESENT(def)) lerr = getKeyByIndex_smmm(keyn, svals, ky, tname, int2str(def), lDisp)
+  IF(.NOT.PRESENT(def)) lerr = getKeyByIndex_smmm(keyn, svals, ky, tname, lDisp=lDisp)
   IF(lerr) RETURN
   val = str2int(svals)
-  ll = val == -HUGE(1) .AND. (SIZE(svals) /=1 .OR. svals(1) /= '')
-  lerr = ANY(ll); IF(.NOT.lerr) RETURN
-  IF(getKeyByIndex_smmm(['name'], tname, ky)) RETURN
+  ll = val == -HUGE(1)
+  lerr = ANY(ll); IF(.NOT.lerr) THEN; IF(PRESENT(nam)) nam = tname; RETURN; END IF
   s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(strStack(PACK(tname, MASK=ll)))//' is not'
   CALL msg(TRIM(s)//' an integer: '//TRIM(strStack(svals, MASK=ll)), modname, lerr)
+  IF(.NOT.lerr .AND. PRESENT(nam)) nam = tname
 END FUNCTION getKeyByIndex_immm
 !==============================================================================================================================
-LOGICAL FUNCTION getKeyByIndex_rmmm(keyn, val, ky, def, lDisp) RESULT(lerr)
-  CHARACTER(LEN=*),          INTENT(IN)  :: keyn(:)
-  REAL,         ALLOCATABLE, INTENT(OUT) ::  val(:)
-  TYPE(keys_type), OPTIONAL, INTENT(IN)  ::   ky(:)
-  REAL,            OPTIONAL, INTENT(IN)  ::  def
-  LOGICAL,         OPTIONAL, INTENT(IN)  :: lDisp
+LOGICAL FUNCTION getKeyByIndex_rmmm(keyn, val, ky, nam, def, lDisp) RESULT(lerr)
+  CHARACTER(LEN=*),                             INTENT(IN)  :: keyn(:)
+  REAL,                            ALLOCATABLE, INTENT(OUT) ::  val(:)
+  TYPE(keys_type),       OPTIONAL,              INTENT(IN)  ::   ky(:)
+  CHARACTER(LEN=maxlen), OPTIONAL, ALLOCATABLE, INTENT(OUT) ::  nam(:)
+  REAL,                  OPTIONAL,              INTENT(IN)  ::  def
+  LOGICAL,               OPTIONAL,              INTENT(IN)  :: lDisp
 !------------------------------------------------------------------------------------------------------------------------------
   CHARACTER(LEN=maxlen) :: s
   CHARACTER(LEN=maxlen), ALLOCATABLE :: svals(:), tname(:)
   LOGICAL,               ALLOCATABLE ::    ll(:)
-  IF(     PRESENT(def)) lerr = getKeyByIndex_smmm(keyn, svals, ky, real2str(def), lDisp)
-  IF(.NOT.PRESENT(def)) lerr = getKeyByIndex_smmm(keyn, svals, ky, lDisp=lDisp)
+  IF(     PRESENT(def)) lerr = getKeyByIndex_smmm(keyn, svals, ky, tname, real2str(def), lDisp)
+  IF(.NOT.PRESENT(def)) lerr = getKeyByIndex_smmm(keyn, svals, ky, tname, lDisp=lDisp)
   IF(lerr) RETURN
   val = str2real(svals)
-  ll = val == -HUGE(1.) .AND. (SIZE(svals) /=1 .OR. svals(1) /= '')
-  lerr = ANY(ll); IF(.NOT.lerr) RETURN
-  IF(getKeyByIndex_smmm(['name'], tname, ky)) RETURN
+  ll = val == -HUGE(1.)
+  lerr = ANY(ll); IF(.NOT.lerr) THEN; IF(PRESENT(nam)) nam = tname; RETURN; END IF
   s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(strStack(PACK(tname, MASK=ll)))//' is not a'
   CALL msg(TRIM(s)//' a real: '//TRIM(strStack(svals, MASK=ll)), modname)
 END FUNCTION getKeyByIndex_rmmm
 !==============================================================================================================================
-LOGICAL FUNCTION getKeyByIndex_lmmm(keyn, val, ky, def, lDisp) RESULT(lerr)
-  CHARACTER(LEN=*),          INTENT(IN)  :: keyn(:)
-  LOGICAL,      ALLOCATABLE, INTENT(OUT) ::  val(:)
-  TYPE(keys_type), OPTIONAL, INTENT(IN)  ::   ky(:)
-  LOGICAL,         OPTIONAL, INTENT(IN)  ::  def
-  LOGICAL,         OPTIONAL, INTENT(IN)  :: lDisp
+LOGICAL FUNCTION getKeyByIndex_lmmm(keyn, val, ky, nam, def, lDisp) RESULT(lerr)
+  CHARACTER(LEN=*),                             INTENT(IN)  :: keyn(:)
+  LOGICAL,                         ALLOCATABLE, INTENT(OUT) ::  val(:)
+  TYPE(keys_type),       OPTIONAL,              INTENT(IN)  ::   ky(:)
+  CHARACTER(LEN=maxlen), OPTIONAL, ALLOCATABLE, INTENT(OUT) ::  nam(:)
+  LOGICAL,               OPTIONAL,              INTENT(IN)  ::  def
+  LOGICAL,               OPTIONAL,              INTENT(IN)  :: lDisp
 !------------------------------------------------------------------------------------------------------------------------------
   CHARACTER(LEN=maxlen) :: s
@@ -2027,14 +2053,12 @@
   LOGICAL,               ALLOCATABLE ::    ll(:)
   INTEGER,               ALLOCATABLE :: ivals(:)
-  IF(     PRESENT(def)) lerr = getKeyByIndex_smmm(keyn, svals, ky, bool2str(def), lDisp)
-  IF(.NOT.PRESENT(def)) lerr = getKeyByIndex_smmm(keyn, svals, ky, lDisp=lDisp)
+  IF(     PRESENT(def)) lerr = getKeyByIndex_smmm(keyn, svals, ky, tname, bool2str(def), lDisp)
+  IF(.NOT.PRESENT(def)) lerr = getKeyByIndex_smmm(keyn, svals, ky, tname, lDisp=lDisp)
   IF(lerr) RETURN
   ivals = str2bool(svals)
-  ll = ivals == -1 .AND. (SIZE(svals) /=1 .OR. svals(1) /= '')
-  lerr = ANY(ll); IF(.NOT.lerr) RETURN
-  IF(getKeyByIndex_smmm(['name'], tname, ky)) RETURN
+  ll = ivals == -1
+  lerr = ANY(ll); IF(.NOT.lerr) THEN; val = ivals == 1; IF(PRESENT(nam)) nam = tname; RETURN; END IF
   s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(strStack(tname, MASK=ll))//' is not'
   CALL msg(TRIM(s)//' a boolean: '//TRIM(strStack(svals, MASK=ll)), modname)
-  IF(.NOT.lerr) val = ivals == 1
 END FUNCTION getKeyByIndex_lmmm
 !==============================================================================================================================
@@ -2047,5 +2071,5 @@
 !=== TRY TO GET THE KEY NAMED "key" FOR THE TRACER NAMED "tname" IN:                                                        ===
 !===  * ARGUMENT "ky" DATABASE IF SPECIFIED ; OTHERWISE:                                                                    ===
-!===  * IN INTERNAL TRACERS DATABASE "tracers(:)" (IF UNFOUND, IN INTERNAL ISOTOPES DATABASE "isotope%keys(:)")             ===
+!===  * IN INTERNAL TRACERS DATABASE "tracers(:)%keys" (IF UNFOUND, IN INTERNAL ISOTOPES DATABASE "isotope%keys(:)")        ===
 !=== THE RETURNED VALUE (STRING, AN INTEGER, A REAL OR A LOGICAL) CAN BE EITHER:                                            ===
 !===  * A SCALAR                                                                                                            ===
@@ -2109,5 +2133,5 @@
   tnam = strHead(delPhase(tname),'_',.TRUE.)                                             !--- Remove phase and tag
   IF(lerr .AND. PRESENT(ky))         val = fgetKey(ky)                                   !--- "ky"
-  IF(lerr .AND. ALLOCATED (tracers)) val = fgetKey(tracers(:))                           !--- "tracers"
+  IF(lerr .AND. ALLOCATED (tracers)) val = fgetKey(tracers(:)%keys)                      !--- "tracers"
   IF(lerr .AND. ASSOCIATED(isotope)) val = fgetKey(isotope%keys(:))                      !--- "isotope"
   IF(lerr .AND. PRESENT(def)) THEN
@@ -2121,9 +2145,9 @@
  CHARACTER(LEN=maxlen) FUNCTION fgetKey(ky) RESULT(val)
   TYPE(keys_type),  INTENT(IN)  :: ky(:)
-  CHARACTER(LEN=maxlen), ALLOCATABLE :: tname_all(:)
-  lerr = SIZE(ky) == 0;                 IF(lerr) RETURN
-  lerr = getKey('name', tname_all, ky); IF(lerr) RETURN
-           val = fgetKeyIdx(strIdx(tname_all, tname), [keyn], ky, lerr)
-  IF(lerr) val = fgetKeyIdx(strIdx(tname_all, tnam ), [keyn], ky, lerr)
+  lerr = SIZE(ky) == 0
+  IF(lerr) RETURN
+           val = fgetKeyIdx(strIdx(ky%name, tname), [keyn], ky, lerr)
+  IF(lerr) val = fgetKeyIdx(strIdx(ky%name, tnam ), [keyn], ky, lerr)
+
 END FUNCTION fgetKey
 
@@ -2142,5 +2166,5 @@
   IF(lerr) RETURN
   val = str2int(sval)
-  lerr = val == -HUGE(1) .AND. sval /= ''
+  lerr = val == -HUGE(1)
   s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(tname)//' is not'
   CALL msg(TRIM(s)//' an integer: '//TRIM(sval), modname, lerr)
@@ -2159,5 +2183,5 @@
   IF(lerr) RETURN
   val = str2real(sval)
-  lerr = val == -HUGE(1.) .AND. sval /= ''
+  lerr = val == -HUGE(1.)
   s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(tname)//' is not'
   CALL msg(TRIM(s)//' a real: '//TRIM(sval), modname, lerr)
@@ -2177,5 +2201,5 @@
   IF(lerr) RETURN
   ival = str2bool(sval)
-  lerr = ival == -1 .AND. sval /= ''
+  lerr = ival == -1
   s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(tname)//' is not'
   CALL msg(TRIM(s)//' a boolean: '//TRIM(sval), modname, lerr)
@@ -2212,5 +2236,5 @@
   IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN
   val = str2int(svals)
-  lerr = ANY(val == -HUGE(1)) .AND. sval /= ''
+  lerr = ANY(val == -HUGE(1))
   s = 'key "'//TRIM(keyn)//'" of '//TRIM(tname)//' is not'
   CALL msg(TRIM(s)//' an integer: '//TRIM(sval), modname, lerr)
@@ -2232,5 +2256,5 @@
   IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN
   val = str2real(svals)
-  lerr = ANY(val == -HUGE(1.)) .AND. sval /= ''
+  lerr = ANY(val == -HUGE(1.))
   s = 'key "'//TRIM(keyn)//'" of '//TRIM(tname)//' is not'
   CALL msg(TRIM(s)//' a real: '//TRIM(sval), modname, lerr)
@@ -2253,5 +2277,5 @@
   IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN
   ivals = str2bool(svals)
-  lerr = ANY(ivals == -1) .AND. sval /= ''
+  lerr = ANY(ivals == -1)
   s = 'key "'//TRIM(keyn)//'" of '//TRIM(tname)//' is not'
   CALL msg(TRIM(s)//' a boolean: '//TRIM(sval), modname, lerr)
@@ -2288,5 +2312,5 @@
   IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN
   val = str2int(svals)
-  lerr = ANY(val == -HUGE(1)) .AND. sval /= ''
+  lerr = ANY(val == -HUGE(1))
   s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(tname)//' is not'
   CALL msg(TRIM(s)//' an integer: '//TRIM(sval), modname, lerr)
@@ -2308,5 +2332,5 @@
   IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN
   val = str2real(svals)
-  lerr = ANY(val == -HUGE(1.)) .AND. sval /= ''
+  lerr = ANY(val == -HUGE(1.))
   s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(tname)//' is not'
   CALL msg(TRIM(s)//' a real: '//TRIM(sval), modname, lerr)
@@ -2329,5 +2353,5 @@
   IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN
   ivals = str2bool(svals)
-  lerr = ANY(ivals == -1) .AND. sval /= ''
+  lerr = ANY(ivals == -1)
   s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(tname)//' is not'
   CALL msg(TRIM(s)//' a boolean: '//TRIM(sval), modname, lerr)
@@ -2388,5 +2412,5 @@
   lerr = .TRUE.
   IF(PRESENT(ky)) THEN;                 val = fgetKey(ky)                                !--- "ky"
-  ELSE IF(ALLOCATED(tracers)) THEN;     val = fgetKey(tracers(:))                        !--- "tracers"
+  ELSE IF(ALLOCATED(tracers)) THEN;     val = fgetKey(tracers(:)%keys)                   !--- "tracers"
      IF(lerr .AND. ASSOCIATED(isotope)) val = fgetKey(isotope%keys(:))                   !--- "isotope"
   END IF
@@ -2403,9 +2427,7 @@
   TYPE(keys_type),       INTENT(IN)  :: ky(:)
   LOGICAL,               ALLOCATABLE :: ler(:)
-  CHARACTER(LEN=maxlen), ALLOCATABLE :: tname_all(:)
-  lerr = SIZE(ky) == 0;                 IF(lerr) RETURN
-  lerr = getKey('name', tname_all, ky); IF(lerr) RETURN
+  lerr = SIZE(ky) == 0; IF(lerr) RETURN
   ALLOCATE(ler(SIZE(tname)))
-  val = [(fgetKeyIdx(strIdx(tname_all, tname(iq)), keyn, ky, ler(iq)), iq = 1, SIZE(tname))]
+  val = [(fgetKeyIdx(strIdx(ky(:)%name, tname(iq)), keyn, ky, ler(iq)), iq = 1, SIZE(tname))]
   lerr = ANY(ler)
 END FUNCTION fgetKey
@@ -2427,5 +2449,5 @@
   IF(lerr) RETURN
   val = str2int(svals)
-  ll = val == -HUGE(1) .AND. (SIZE(svals) /=1 .OR. svals(1) /= '')
+  ll = val == -HUGE(1)
   lerr = ANY(ll); IF(.NOT.lerr) RETURN
   s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(strStack(tname, MASK=ll))//' is not'
@@ -2447,5 +2469,5 @@
   IF(lerr) RETURN
   val = str2real(svals)
-  ll = val == -HUGE(1.) .AND. (SIZE(svals) /=1 .OR. svals(1) /= '')
+  ll = val == -HUGE(1.)
   lerr = ANY(ll); IF(.NOT.lerr) RETURN
   s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(strStack(tname, MASK=ll))//' is not'
@@ -2468,5 +2490,5 @@
   IF(lerr) RETURN
   ivals = str2bool(svals)
-  ll = ivals == -1 .AND. (SIZE(svals) /=1 .OR. svals(1) /= '')
+  ll = ivals == -1
   lerr = ANY(ll); IF(.NOT.lerr) THEN; val = ivals == 1; RETURN; END IF
   s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(strStack(tname, MASK=ll))//' is not'
@@ -2480,5 +2502,5 @@
 !==============================================================================================================================
 SUBROUTINE setKeysDBase(tracers_, isotopes_, isotope_)
-  TYPE(keys_type), OPTIONAL, INTENT(IN) ::  tracers_(:)
+  TYPE(trac_type), OPTIONAL, INTENT(IN) ::  tracers_(:)
   TYPE(isot_type), OPTIONAL, INTENT(IN) :: isotopes_(:)
   TYPE(isot_type), OPTIONAL, INTENT(IN) :: isotope_
@@ -2489,5 +2511,5 @@
   IF(PRESENT(isotopes_)) THEN; isotopes = isotopes_; ELSE; ALLOCATE(isotopes(0)); END IF
   IF(PRESENT(isotope_ )) THEN
-    ix = strIdx(isotopes(:)%name, isotope_%name)
+    ix = strIdx(isotopes(:)%parent, isotope_%parent)
     IF(ix /= 0) THEN
       isotopes(ix) = isotope_
@@ -2500,5 +2522,5 @@
 !==============================================================================================================================
 SUBROUTINE getKeysDBase(tracers_, isotopes_, isotope_)
-  TYPE(keys_type), OPTIONAL, ALLOCATABLE, INTENT(OUT) ::  tracers_(:)
+  TYPE(trac_type), OPTIONAL, ALLOCATABLE, INTENT(OUT) ::  tracers_(:)
   TYPE(isot_type), OPTIONAL, ALLOCATABLE, INTENT(OUT) :: isotopes_(:)
   TYPE(isot_type), OPTIONAL,              INTENT(OUT) :: isotope_
@@ -2507,5 +2529,5 @@
   IF(PRESENT( tracers_)) THEN;  tracers_ =  tracers; ELSE; ALLOCATE( tracers_(0)); END IF
   IF(PRESENT(isotopes_)) THEN; isotopes_ = isotopes; ELSE; ALLOCATE(isotopes_(0)); END IF
-  IF(PRESENT(isotope_ )) THEN; ix = strIdx(isotopes(:)%name, isotope%name); IF(ix /= 0) isotope_=isotopes(ix); END IF
+  IF(PRESENT(isotope_ )) THEN; ix = strIdx(isotopes(:)%parent, isotope%parent); IF(ix /= 0) isotope_=isotopes(ix); END IF
 END SUBROUTINE getKeysDBase
 !==============================================================================================================================
@@ -2583,10 +2605,10 @@
   CHARACTER(LEN=*),             INTENT(IN)    :: tname
   TYPE(keys_type),              INTENT(IN)    ::  keys
-  TYPE(keys_type), ALLOCATABLE, INTENT(INOUT) :: tracs(:)
-  TYPE(keys_type), ALLOCATABLE :: tr(:)
+  TYPE(trac_type), ALLOCATABLE, INTENT(INOUT) :: tracs(:)
+  TYPE(trac_type), ALLOCATABLE :: tr(:)
   CHARACTER(LEN=maxlen), ALLOCATABLE :: tnames(:)
   INTEGER :: nt, ix
   IF(ALLOCATED(tracs)) THEN
-     lerr = getKey('name', tnames, ky=tracs(:)); IF(lerr) RETURN
+     lerr = getKey('name', tnames, ky=tracs(:)%keys); IF(lerr) RETURN
      nt = SIZE(tracs)
      ix = strIdx(tnames, tname)
@@ -2600,6 +2622,7 @@
      ix = 1; ALLOCATE(tracs(1))
   END IF
-  CALL addKey('name', tname, tracs(ix))
-  tracs(ix) = keys
+  CALL addKey('name', tname, tracs(ix)%keys)
+  tracs(ix)%name = tname
+  tracs(ix)%keys = keys
 
 END FUNCTION addTracer_1
@@ -2616,6 +2639,6 @@
 LOGICAL FUNCTION delTracer_1(tname, tracs) RESULT(lerr)
   CHARACTER(LEN=*),                     INTENT(IN)    :: tname
-  TYPE(keys_type), ALLOCATABLE, TARGET, INTENT(INOUT) :: tracs(:)
-  TYPE(keys_type), ALLOCATABLE :: tr(:)
+  TYPE(trac_type), ALLOCATABLE, TARGET, INTENT(INOUT) :: tracs(:)
+  TYPE(trac_type), ALLOCATABLE :: tr(:)
   CHARACTER(LEN=maxlen), ALLOCATABLE :: tnames(:)
   INTEGER :: nt, ix
@@ -2623,5 +2646,5 @@
   IF(fmsg('Can''t remove tracer "'//TRIM(tname)//'" from an empty tracers descriptor', modname, lerr)) RETURN
   nt = SIZE(tracs)
-  lerr = getKey('name', tnames, ky=tracs(:)); IF(lerr) RETURN
+  lerr = getKey('name', tnames, ky=tracs(:)%keys); IF(lerr) RETURN
   ix = strIdx(tnames, tname)
   CALL msg('Removing tracer "'             //TRIM(tname)//'"', modname, ix /= 0)
@@ -2667,7 +2690,6 @@
 
 !==============================================================================================================================
-!======== CONVERT WATER-DERIVED NAMES FROM FORMER TO CURRENT CONVENTION & VICE VERSA ; OTHER NAMES ARE LEFT UNTOUCHED =========
-!===== OLD NAMES STRUCTURE:  H2O[<phase>][_<isotope>][_<tag>] (<phase> from "old_phases",        <isotope> from "oldH2OIso") ==
-!====  NEW NAMES STRUCTURE: <var>[<phase_sep><phase>][_<tag>] (<phase> from "known_phases", <var>='H2O' or from "newH2OIso") ==
+!============ CONVERT WATER-DERIVED NAMES FROM FORMER TO CURRENT CONVENTION ; OTHER NAMES ARE LEFT UNTOUCHED ==================
+!======= NAMES STRUCTURE: H2O[<phase>][_<isotope>][_<tag>] (<phase> from "old_phases", <isotope> from "oldH2OIso") ============
 !==============================================================================================================================
 CHARACTER(LEN=maxlen) FUNCTION old2newH2O_1(oldName, iPhase) RESULT(newName)
@@ -2702,4 +2724,10 @@
 END FUNCTION old2newH2O_m
 !==============================================================================================================================
+
+
+!==============================================================================================================================
+!============ CONVERT WATER-DERIVED NAMES FROM CURRENT TO FORMER CONVENTION ; OTHER NAMES ARE LEFT UNTOUCHED ==================
+!==== NAMES STRUCTURE: <var>[<phase_sep><phase>][_<tag>] (<phase> from "known_phases", <var> = 'H2O' or from "newH2OIso") =====
+!==============================================================================================================================
 CHARACTER(LEN=maxlen) FUNCTION new2oldH2O_1(newName, iPhase) RESULT(oldName)
   CHARACTER(LEN=*),  INTENT(IN)  :: newName
