
! Copyright (C) 2002 - Observatoire de Paris/Meudon
!                      Universite Paris 7
!                      CNRS (France)
!                      Contact : Jacques.Lebourlot@obspm.fr
!
! This program is free software; you can redistribute it and/or
! modify it under the terms of the GNU General Public License version 2
! as published by the Free Software Foundation.
!
! This program is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
! GNU General Public License for more details.
!
! You should have received a copy of the GNU General Public License
! along with this program; if not, write to the Free Software
! Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

! JLB - 22 mai 2008

MODULE PXDR_OUTPUT_ASCII

   USE PXDR_CONSTANTES
   USE PXDR_CHEM_DATA
   USE PXDR_PROFIL

   PUBLIC :: WRITE_ASCII

   INTEGER, PARAMETER                            :: lencol = 1000000  ! Maximum number of characters
                                                                      ! in each line of output ASCII

   CHARACTER(len=lenstrint)                      :: angstr            ! value of the angle (string)
   INTEGER                                       :: angval            ! value of the angle (integer)
   INTEGER                                       :: angidx            ! index of the angle
   INTEGER                                       :: speidx            ! index of the species

   INTEGER                                       :: nbf               ! number of formation   reaction of a given species
   INTEGER                                       :: nbd               ! number of destruction reaction of a given species
   REAL(dp), PUBLIC, ALLOCATABLE, DIMENSION(:,:) :: form_rate         ! formation   rates of a given species at all positions
   REAL(dp), PUBLIC, ALLOCATABLE, DIMENSION(:,:) :: dest_rate         ! destruction rates of a given species at all positions
   INTEGER,  PUBLIC, ALLOCATABLE, DIMENSION(:)   :: idx_freac         ! indices of the formation   reactions
   INTEGER,  PUBLIC, ALLOCATABLE, DIMENSION(:)   :: idx_dreac         ! indices of the destruction reactions

CONTAINS

!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
SUBROUTINE WRITE_ASCII(filedir, metatab, nhdf5)
!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   ! This routine write most of the code standard output (+metadata, see above) in several
   ! ASCII files. Theses ASCII files will be used by BinToHDF5.py to produce HDF5 outputs

   USE PXDR_CONSTANTES
   USE PXDR_PROFIL
   USE PXDR_AUXILIAR

   IMPLICIT none

   CHARACTER(len=lenfilename),                   INTENT(in) :: filedir   ! directory of the ASCII files
   INTEGER,                                      INTENT(in) :: nhdf5     ! dimension of the metatab table
   TYPE (METADATA),            DIMENSION(nhdf5), INTENT(in) :: metatab   ! table of metadata
   CHARACTER(len=lenfilename)                               :: filename  ! name of the ASCII file to create
   INTEGER                                                  :: ndatafile ! number of data to write per file
   INTEGER                                                  :: idx_star  ! dummy integer
   INTEGER                                                  :: i, j      ! dummy integers

   ! =====================================================================================
   ! Create a directory in ../out/modele/ to store temporary ASCII files
   ! =====================================================================================
   sh_cmd = 'sh -c "if [ ! -d '//TRIM(filedir)//" ]; then mkdir "
   sh_cmd = TRIM(sh_cmd)//" "//TRIM(filedir)//'; fi "'
   CALL SYSTEM(sh_cmd)

   ! =====================================================================================
   ! Find the number of data to write per ASCII file
   ! Find the number of ASCII files to create for each line of meta_xxxxxxxx.dat
   ! =====================================================================================
   i = 1
   DO WHILE(i <= nhdf5)
      ! ---------------------------------------------------
      ! Test if several lines in meta_standard.dat have the
      ! same output ASCII file name
      ! ---------------------------------------------------
      filename  = TRIM(metatab(i)%file)
      DO j = i, nhdf5
         IF ( TRIM(metatab(j)%file) /= TRIM(filename) ) EXIT
      ENDDO
      ndatafile = j - i
      filename = TRIM(filedir)//TRIM(filename)
      ! ---------------------------------------------------
      ! Test if we are writing the integrated intensities
      ! or info on the contributions to integ intensities
      ! If so, we need to open as many ASCII files as the
      ! number of angles at which intensities are estimated
      ! ---------------------------------------------------
      IF      ( ( INDEX(metatab(i)%IDname, 'inta_*      ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'abso_*      ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'cont_*      ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'level_ctrb_*', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'avpos_ctrb_*', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'avmoy_ctrb_*', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'avrms_ctrb_*', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'bkgd_ctrb_* ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'dust_ctrb_* ', .false.) == 1 ) ) THEN
         idx_star = INDEX(metatab(i)%file, '*', .false.)
         DO angidx = 1, nangle
            angval = NINT(AngleInt(angidx))
            CALL INT_STR(angval, angstr, 2)
            filename = metatab(i)%file(1:idx_star-1)//TRIM(angstr)//metatab(i)%file(idx_star+1:)
            filename = TRIM(filedir)//TRIM(filename)
            CALL WRITE_METADATA(filename, metatab, nhdf5, i, ndatafile)
         ENDDO
      ! ---------------------------------------------------
      ! Test if we are writing the chemical data
      ! If so, we need to open as many ASCII files as the
      ! number of species treated in the chemical network
      ! ---------------------------------------------------
      ELSE IF ( ( INDEX(metatab(i)%IDname, 'dens_spec_* ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'frate_*     ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'drate_*     ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'tot_frate_* ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'tot_drate_* ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'compo_of_*  ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'mass_of_*   ', .false.) == 1 ) ) THEN
         idx_star = INDEX(metatab(i)%file, '*', .false.)
         IF (   ( INDEX(metatab(i)%file, 'ChemDens*.dat ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%file, 'Compo*.dat    ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%file, 'Mass*.dat     ', .false.) == 1 ) ) THEN
            DO speidx = 1, nspec
               filename = metatab(i)%file(1:idx_star-1)//TRIM(Species(speidx)%SpecyID)//metatab(i)%file(idx_star+1:)
               filename = TRIM(filedir)//TRIM(filename)
               CALL WRITE_METADATA(filename, metatab, nhdf5, i, ndatafile)
            ENDDO
         ELSE
            DO speidx = 1, nspec
               CALL FILL_RATES
               filename = metatab(i)%file(1:idx_star-1)//TRIM(Species(speidx)%SpecyID)//metatab(i)%file(idx_star+1:)
               filename = TRIM(filedir)//TRIM(filename)
               CALL WRITE_METADATA(filename, metatab, nhdf5, i, ndatafile)
               DEALLOCATE (form_rate)
               DEALLOCATE (dest_rate)
               DEALLOCATE (idx_freac)
               DEALLOCATE (idx_dreac)
            ENDDO
         ENDIF
      ELSE
         CALL WRITE_METADATA(filename, metatab, nhdf5, i, ndatafile)
      ENDIF
      ! ---------------------------------------------------
      ! Skip the lines in the metadata file that we have
      ! already treated by defining ndatafile
      ! ---------------------------------------------------
      i = i + ndatafile
   ENDDO

END SUBROUTINE WRITE_ASCII

!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
SUBROUTINE WRITE_METADATA(filename, metatab, nhdf5, ifil, ndatafile)
!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

   USE PXDR_CONSTANTES
   USE PXDR_FLAGS
   USE PXDR_CHEM_DATA
   USE PXDR_PROFIL
   USE PXDR_STR_DATA
   USE PXDR_AUXILIAR
   USE PXDR_RF_TOOLS

   IMPLICIT none

   CHARACTER(len=lenfilename),         INTENT(in) :: filename        ! name of the ASCII file
   INTEGER,                            INTENT(in) :: nhdf5           ! dimension of the metatab table
   TYPE (METADATA),          DIMENSION(nhdf5)     :: metatab         ! table of metadata
   INTEGER,                            INTENT(in) :: ifil            ! starting index in metatab_std
   INTEGER,                            INTENT(in) :: ndatafile       ! number of data to write in the ASCII file
   INTEGER,                  DIMENSION(ndatafile) :: nsubcols        ! number of subcolumns per data
   INTEGER                                        :: nvals           ! number of values per column
   CHARACTER(len=17)                              :: strf            ! string dummy variable to write reals
   CHARACTER(len=10)                              :: stri            ! string dummy variable to write integers
   CHARACTER(len=500)                             :: strs            ! string dummy variable to strings
   CHARACTER(len=lenmetadesc)                     :: template        ! temporary string to store metadata
   CHARACTER(len=lenstrint)                       :: strindex        ! integer index in string format
   CHARACTER(len=lenSpeci)                        :: sp_lowcas       ! name of elemental species (lower case)
   CHARACTER(len=lenSpeci)                        :: sp_uppcas       ! name of elemental species (upper case)
   CHARACTER(len=lenmetakey)                      :: key_temp        ! temporary key string
   INTEGER                                        :: idx_star        ! location of the star the quantities listed in metadata.dat
   INTEGER                                        :: i, j, k, j1, j2 ! dummy indices

   fichier = TRIM(filename)
   OPEN(iwrtmp, FILE=fichier, status="unknown", action="write", RECL=lencol)

   !======================================================================================
   ! Test if the quantity to write in the ASCII file are local 
   !    -> the number of values to write is npo + 1
   ! Test if the quantity to write in the ASCII file is the chemical network
   !    -> the number of values to write is nchemfil
   !======================================================================================
   IF ( INDEX(metatab(ifil)%path, 'Local', .false.) /= 0 ) THEN
      nvals = npo + 1
   ELSE IF ( INDEX(metatab(ifil)%path, 'Spectrum', .false.) /= 0 ) THEN
      nvals = nwl_spectrum
   ELSE IF ( INDEX(metatab(ifil)%path, 'Network', .false.) /= 0 ) THEN
      nvals = nchemfil
   ELSE
      nvals = 1
   ENDIF
   !======================================================================================
   ! Compute the number of subcolumns per data
   ! Note: if a data shouldn't be written in the output (e.g. input nH in the case of an
   !       isobaric model), then we set nsubcols = 0
   ! TODO: if F_DUST_P == 1, the grain parameter in pdr.in are not used and should not be
   !       consider as parameters in the output ascii files
   !======================================================================================
   DO i = ifil, ifil + ndatafile - 1
      nsubcols(i-ifil+1) = 0
      IF      ( ( INDEX(metatab(i)%IDname, 'n_*                  ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'cd_prof_*            ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'cd_*                 ', .false.) == 1 ) ) THEN
         nsubcols(i-ifil+1) = nsubcols(i-ifil+1) + nspec
      ELSE IF ( ( INDEX(metatab(i)%IDname, 'coolrate_*           ', .false.) == 1 ) ) THEN
         nsubcols(i-ifil+1) = nsubcols(i-ifil+1) + nspl
      ELSE IF ( ( INDEX(metatab(i)%IDname, 'temp_grain_r*        ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'charge_grain_r*      ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'radius_grain_r*      ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'dens_grain_r*        ', .false.) == 1 ) ) THEN
         nsubcols(i-ifil+1) = nsubcols(i-ifil+1) + npg
      ELSE IF ( ( INDEX(metatab(i)%IDname, 'elem_*               ', .false.) == 1 ) ) THEN
         nsubcols(i-ifil+1) = nsubcols(i-ifil+1) + natom-1
      ELSE IF ( ( INDEX(metatab(i)%IDname, 'cd_lev_*             ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'cd_lev_prof_*        ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'pop_*                ', .false.) == 1 ) ) THEN
         DO j1 = 1, nspl
            DO j2 = 1, spec_lin(j1)%use
               nsubcols(i-ifil+1) = nsubcols(i-ifil+1) + 1
            ENDDO
         ENDDO
      ELSE IF ( ( INDEX(metatab(i)%IDname, 'photo_prob_*         ', .false.) == 1 ) ) THEN
         DO j = 1, nphot_i
            nsubcols(i-ifil+1) = nsubcols(i-ifil+1) + 1
         ENDDO
      ELSE IF ( ( INDEX(metatab(i)%IDname, 'inta_*               ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'abso_*               ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'cont_*               ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'em_*                 ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'optdep_*             ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'dint_*               ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'level_ctrb_*         ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'avpos_ctrb_*         ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'avmoy_ctrb_*         ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'avrms_ctrb_*         ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'bkgd_ctrb_*          ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'dust_ctrb_*          ', .false.) == 1 ) ) THEN
         DO j1 = 1, nspl
            DO j2 = 1, spec_lin(j1)%ntr
               IF (spec_lin(j1)%iup(j2) > spec_lin(j1)%use) CYCLE
               nsubcols(i-ifil+1) = nsubcols(i-ifil+1) + 1
            ENDDO
         ENDDO
      ELSE IF ( ( INDEX(metatab(i)%IDname, 'frate_*              ', .false.) == 1 ) ) THEN
         DO j = 1, nbf
            nsubcols(i-ifil+1) = nsubcols(i-ifil+1) + 1
         ENDDO
      ELSE IF ( ( INDEX(metatab(i)%IDname, 'drate_*              ', .false.) == 1 ) ) THEN
         DO j = 1, nbd
            nsubcols(i-ifil+1) = nsubcols(i-ifil+1) + 1
         ENDDO
      ELSE IF ( ( INDEX(metatab(i)%IDname, 'compo_of_*           ', .false.) == 1 ) ) THEN
         DO j = 1, natom
            nsubcols(i-ifil+1) = nsubcols(i-ifil+1) + 1
         ENDDO
      ELSE IF ( ( INDEX(metatab(i)%IDname, 'proton_density_input ', .false.) == 1 ).AND.&
                ( ( ifisob == 1 ).OR.( (ifisob == 2).AND.(ifeqth /= 0) ) ) ) THEN
         nsubcols(i-ifil+1) = 0
      ELSE IF ( ( INDEX(metatab(i)%IDname, 'gas_pressure_input   ', .false.) == 1 ).AND.&
                ( ( ifisob == 1 ).OR.( (ifisob == 0).AND.(ifeqth /= 0) ) ) ) THEN
         nsubcols(i-ifil+1) = 0
      ELSE IF ( ( INDEX(metatab(i)%IDname, 'gas_temperature_input', .false.) == 1 ).AND.&
                ( ifeqth /= 0 ) ) THEN
         nsubcols(i-ifil+1) = 0
      ELSE
         nsubcols(i-ifil+1) = nsubcols(i-ifil+1) + 1
      ENDIF
   ENDDO

   !======================================================================================
   ! Open the input chemical file if needed - to copy network in the chemistry hdf5 file
   !======================================================================================
   IF ( INDEX(metatab(ifil)%path, 'Network', .false.) /= 0 ) THEN
      fichier = TRIM(data_dir)//'Chimie/'//chimie
      OPEN (iread1, FILE=fichier, status="old")
   ENDIF

   !======================================================================================
   ! 1 - Write the line containing all the paths in the output ASCII file
   !======================================================================================
   DO i = ifil, ifil + ndatafile - 1
      IF ( nsubcols(i-ifil+1) == 0 ) CYCLE
      IF      ( ( INDEX(metatab(i)%IDname, 'dens_spec_*    ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'frate_*        ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'drate_*        ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'tot_frate_*    ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'tot_drate_*    ', .false.) == 1 ) ) THEN
         idx_star = INDEX(metatab(i)%path, '*', .false.)
         template = metatab(i)%path(1:idx_star-1)//TRIM(Species(speidx)%Hname)//metatab(i)%path(idx_star+1:)
      ELSE
         template = metatab(i)%path
      ENDIF
      DO j = 1, nsubcols(i-ifil+1)
         WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_path)
         WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(template)
      ENDDO
   ENDDO
   WRITE(iwrtmp,*)

   !======================================================================================
   ! 2 - Write the line containing all the datasets in the output ASCII file
   !     Dataset names need to be build here only for lines intensities
   !======================================================================================
   DO i = ifil, ifil + ndatafile - 1
      IF ( nsubcols(i-ifil+1) == 0 ) CYCLE
      IF      ( ( INDEX(metatab(i)%IDname, 'inta_*         ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'abso_*         ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'cont_*         ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'level_ctrb_*   ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'avpos_ctrb_*   ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'avmoy_ctrb_*   ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'avrms_ctrb_*   ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'bkgd_ctrb_*    ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'dust_ctrb_*    ', .false.) == 1 ) ) THEN
         idx_star = INDEX(metatab(i)%datset, '*', .false.)
         template = metatab(i)%datset(1:idx_star-1)//TRIM(angstr)//metatab(i)%datset(idx_star+1:)
      ELSE IF ( ( INDEX(metatab(i)%IDname, 'dens_spec_*    ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'frate_*        ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'drate_*        ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'tot_frate_*    ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'tot_drate_*    ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'compo_of_*     ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'mass_of_*      ', .false.) == 1 ) ) THEN
         idx_star = INDEX(metatab(i)%datset, '*', .false.)
         template = metatab(i)%datset(1:idx_star-1)//TRIM(Species(speidx)%Hname)//metatab(i)%datset(idx_star+1:)
      ELSE
         template = metatab(i)%datset
      ENDIF
      DO j = 1, nsubcols(i-ifil+1)
         WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_datset)
         WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(template)
      ENDDO
   ENDDO
   WRITE(iwrtmp,*)

   !======================================================================================
   ! 3 - Write the line containing all the human readable names in the output ASCII file
   !     if a "*" is present in the pubID, generic names need to be created
   !======================================================================================
   DO i = ifil, ifil + ndatafile - 1
      IF ( nsubcols(i-ifil+1) == 0 ) CYCLE
      IF      ( ( INDEX(metatab(i)%IDname, 'n_*            ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'cd_prof_*      ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'cd_*           ', .false.) == 1 ) ) THEN
         idx_star = INDEX(metatab(i)%Hname, '*', .false.)
         DO j = 1, nspec
            template = metatab(i)%Hname(1:idx_star-1)//&
                       TRIM(Species(j)%Hname)//&
                       metatab(i)%Hname(idx_star+1:)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_Hname)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(template)
         ENDDO
      ELSE IF ( ( INDEX(metatab(i)%IDname, 'coolrate_*     ', .false.) == 1 ) ) THEN
         idx_star = INDEX(metatab(i)%Hname, '*', .false.)
         DO j = 1, nspl
            template = metatab(i)%Hname(1:idx_star-1)//&
                       TRIM(spec_lin(j)%spHname)//&
                       metatab(i)%Hname(idx_star+1:)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_Hname)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(template)
         ENDDO
      ELSE IF ( ( INDEX(metatab(i)%IDname, 'temp_grain_r*  ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'charge_grain_r*', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'radius_grain_r*', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'dens_grain_r*  ', .false.) == 1 ) ) THEN
         idx_star = INDEX(metatab(i)%Hname, '*', .false.)
         DO j = 1, npg
            CALL INT_STR(j, strindex, 2)
            template = metatab(i)%Hname(1:idx_star-1)//&
                       TRIM(strindex)//&
                       metatab(i)%Hname(idx_star+1:)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_Hname)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(template)
         ENDDO
      ELSE IF ( ( INDEX(metatab(i)%IDname, 'elem_*         ', .false.) == 1 ) ) THEN
         idx_star = INDEX(metatab(i)%Hname, '*', .false.)
         DO j = 1, natom-1
            IF ( sp(j) == 'h       ') sp_uppcas = 'H       '
            IF ( sp(j) == 'c       ') sp_uppcas = 'C       '
            IF ( sp(j) == 'n       ') sp_uppcas = 'N       '
            IF ( sp(j) == 'o       ') sp_uppcas = 'O       '
            IF ( sp(j) == 'he      ') sp_uppcas = 'He      '
            IF ( sp(j) == 'd       ') sp_uppcas = 'D       '
            IF ( sp(j) == 'c*      ') sp_uppcas = '13C     '
            IF ( sp(j) == 'n*      ') sp_uppcas = '15N     '
            IF ( sp(j) == 'o*      ') sp_uppcas = '18O     '
            IF ( sp(j) == 'ar      ') sp_uppcas = 'Ar      '
            IF ( sp(j) == 'f       ') sp_uppcas = 'F       '
            IF ( sp(j) == 'na      ') sp_uppcas = 'Na      '
            IF ( sp(j) == 'mg      ') sp_uppcas = 'Mg      '
            IF ( sp(j) == 'al      ') sp_uppcas = 'Al      '
            IF ( sp(j) == 'si      ') sp_uppcas = 'Si      '
            IF ( sp(j) == 'ne      ') sp_uppcas = 'Ne      '
            IF ( sp(j) == 's       ') sp_uppcas = 'S       '
            IF ( sp(j) == 'cl      ') sp_uppcas = 'Cl      '
            IF ( sp(j) == 'ca      ') sp_uppcas = 'Ca      '
            IF ( sp(j) == 'fe      ') sp_uppcas = 'Fe      '
            template = metatab(i)%Hname(1:idx_star-1)//&
                       TRIM(sp_uppcas)//&
                       metatab(i)%Hname(idx_star+1:)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_Hname)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(template)
         ENDDO
      ELSE IF ( ( INDEX(metatab(i)%IDname, 'cd_lev_*       ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'cd_lev_prof_*  ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'pop_*          ', .false.) == 1 ) ) THEN
         idx_star = INDEX(metatab(i)%Hname, '*', .false.)
         DO j1 = 1, nspl
            DO j2 = 1, spec_lin(j1)%use
               template = metatab(i)%Hname(1:idx_star-1)//&
                          TRIM(spec_lin(j1)%spHname)//" "//&
                          TRIM(spec_lin(j1)%LeHname(j2))//&
                          metatab(i)%Hname(idx_star+1:)
               WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_Hname)
               WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(template)
            ENDDO
         ENDDO
      ELSE IF ( ( INDEX(metatab(i)%IDname, 'photo_prob_*   ', .false.) == 1 ) ) THEN
         idx_star = INDEX(metatab(i)%Hname, '*', .false.)
         DO j = 1, nphot_i
            template = metatab(i)%Hname(1:idx_star-1)
            IF ( react(iphot_i+j-1, 1) /= 0 ) template = TRIM(template)//" "//TRIM(Species(react(iphot_i+j-1, 1))%Hname)
            DO j1 = 2, 3
            IF ( react(iphot_i+j-1,j1) /= 0 ) template = TRIM(template)//" + "//TRIM(Species(react(iphot_i+j-1,j1))%Hname)
            ENDDO
            IF ( react(iphot_i+j-1, 4) /= 0 ) template = TRIM(template)//" > "//TRIM(Species(react(iphot_i+j-1, 4))%Hname)
            DO j1 = 5, 7
            IF ( react(iphot_i+j-1,j1) /= 0 ) template = TRIM(template)//" + "//TRIM(Species(react(iphot_i+j-1,j1))%Hname)
            ENDDO
            template = TRIM(template)//" "//metatab(i)%Hname(idx_star+1:)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_Hname)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(template)
         ENDDO
      ELSE IF ( ( INDEX(metatab(i)%IDname, 'em_*           ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'optdep_*       ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'dint_*         ', .false.) == 1 ) ) THEN
         idx_star = INDEX(metatab(i)%Hname, '*', .false.)
         DO j1 = 1, nspl
            DO j2 = 1, spec_lin(j1)%ntr
               IF (spec_lin(j1)%iup(j2) > spec_lin(j1)%use) CYCLE
               template = metatab(i)%Hname(1:idx_star-1)//&
                          TRIM(spec_lin(j1)%spHname)//" "//&
                          TRIM(spec_lin(j1)%LiHname(j2))//&
                          metatab(i)%Hname(idx_star+1:)
               WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_Hname)
               WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(template)
            ENDDO
         ENDDO
      ELSE IF ( ( INDEX(metatab(i)%IDname, 'inta_*         ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'abso_*         ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'cont_*         ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'level_ctrb_*   ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'avpos_ctrb_*   ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'avmoy_ctrb_*   ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'avrms_ctrb_*   ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'bkgd_ctrb_*    ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'dust_ctrb_*    ', .false.) == 1 ) ) THEN
         idx_star = INDEX(metatab(i)%Hname, '*', .false.)
         DO j1 = 1, nspl
            DO j2 = 1, spec_lin(j1)%ntr
               IF (spec_lin(j1)%iup(j2) > spec_lin(j1)%use) CYCLE
               template = metatab(i)%Hname(1:idx_star-1)//&
                          TRIM(spec_lin(j1)%spHname)//" "//&
                          TRIM(spec_lin(j1)%LiHname(j2))//" angle "//&
                          TRIM(angstr)//" deg"//&
                          metatab(i)%Hname(idx_star+1:)
               WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_Hname)
               WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(template)
            ENDDO
         ENDDO
      ELSE IF ( ( INDEX(metatab(i)%IDname, 'dens_spec_*    ', .false.) == 1 ) ) THEN
         idx_star = INDEX(metatab(i)%Hname, '*', .false.)
         template = metatab(i)%Hname(1:idx_star-1)//&
                    TRIM(Species(speidx)%Hname)//&
                    metatab(i)%Hname(idx_star+1:)
         WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_Hname)
         WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(template)
      ELSE IF ( ( INDEX(metatab(i)%IDname, 'frate_*        ', .false.) == 1 ) ) THEN
         idx_star = INDEX(metatab(i)%Hname, '*', .false.)
         DO j = 1, nbf
            template = metatab(i)%Hname(1:idx_star-1)//TRIM(Species(speidx)%Hname)
            IF ( react(idx_freac(j), 1) /= 0 ) template = TRIM(template)//" | "//TRIM(Species(react(idx_freac(j), 1))%Hname)
            DO j1 = 2, 3
            IF ( react(idx_freac(j),j1) /= 0 ) template = TRIM(template)//" + "//TRIM(Species(react(idx_freac(j),j1))%Hname)
            ENDDO
            IF ( react(idx_freac(j), 4) /= 0 ) template = TRIM(template)//" > "//TRIM(Species(react(idx_freac(j), 4))%Hname)
            DO j1 = 5, 7
            IF ( react(idx_freac(j),j1) /= 0 ) template = TRIM(template)//" + "//TRIM(Species(react(idx_freac(j),j1))%Hname)
            ENDDO
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_Hname)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(template)
         ENDDO
      ELSE IF ( ( INDEX(metatab(i)%IDname, 'drate_*        ', .false.) == 1 ) ) THEN
         idx_star = INDEX(metatab(i)%Hname, '*', .false.)
         DO j = 1, nbd
            template = metatab(i)%Hname(1:idx_star-1)//TRIM(Species(speidx)%Hname)
            IF ( react(idx_dreac(j), 1) /= 0 ) template = TRIM(template)//" | "//TRIM(Species(react(idx_dreac(j), 1))%Hname)
            DO j1 = 2, 3
            IF ( react(idx_dreac(j),j1) /= 0 ) template = TRIM(template)//" + "//TRIM(Species(react(idx_dreac(j),j1))%Hname)
            ENDDO
            IF ( react(idx_dreac(j), 4) /= 0 ) template = TRIM(template)//" > "//TRIM(Species(react(idx_dreac(j), 4))%Hname)
            DO j1 = 5, 7
            IF ( react(idx_dreac(j),j1) /= 0 ) template = TRIM(template)//" + "//TRIM(Species(react(idx_dreac(j),j1))%Hname)
            ENDDO
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_Hname)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(template)
         ENDDO
      ELSE IF ( ( INDEX(metatab(i)%IDname, 'tot_frate_*    ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'tot_drate_*    ', .false.) == 1 ) ) THEN
         idx_star = INDEX(metatab(i)%Hname, '*', .false.)
         template = metatab(i)%Hname(1:idx_star-1)//TRIM(Species(speidx)%Hname)
         DO j = 1, nsubcols(i-ifil+1)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_Hname)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(template)
         ENDDO
      ELSE IF ( ( INDEX(metatab(i)%IDname, 'compo_of_*     ', .false.) == 1 ) ) THEN
         idx_star = INDEX(metatab(i)%Hname, '*', .false.)
         DO j = 1, natom
            template = metatab(i)%Hname(1:idx_star-1)//TRIM(Species(speidx)%Hname)//' ('
            IF ( sp(j) == 'h       ') sp_uppcas = 'H       '
            IF ( sp(j) == 'c       ') sp_uppcas = 'C       '
            IF ( sp(j) == 'n       ') sp_uppcas = 'N       '
            IF ( sp(j) == 'o       ') sp_uppcas = 'O       '
            IF ( sp(j) == 'he      ') sp_uppcas = 'He      '
            IF ( sp(j) == 'd       ') sp_uppcas = 'D       '
            IF ( sp(j) == 'c*      ') sp_uppcas = '13C     '
            IF ( sp(j) == 'n*      ') sp_uppcas = '15N     '
            IF ( sp(j) == 'o*      ') sp_uppcas = '18O     '
            IF ( sp(j) == 'ar      ') sp_uppcas = 'Ar      '
            IF ( sp(j) == 'f       ') sp_uppcas = 'F       '
            IF ( sp(j) == 'na      ') sp_uppcas = 'Na      '
            IF ( sp(j) == 'mg      ') sp_uppcas = 'Mg      '
            IF ( sp(j) == 'al      ') sp_uppcas = 'Al      '
            IF ( sp(j) == 'si      ') sp_uppcas = 'Si      '
            IF ( sp(j) == 'ne      ') sp_uppcas = 'Ne      '
            IF ( sp(j) == 's       ') sp_uppcas = 'S       '
            IF ( sp(j) == 'cl      ') sp_uppcas = 'Cl      '
            IF ( sp(j) == 'ca      ') sp_uppcas = 'Ca      '
            IF ( sp(j) == 'fe      ') sp_uppcas = 'Fe      '
            IF ( sp(j) == 'electr  ') sp_uppcas = 'charge  '
            template = TRIM(template)//TRIM(sp_uppcas)//')'
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_Hname)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(template)
         ENDDO
      ELSE IF ( ( INDEX(metatab(i)%IDname, 'mass_of_*      ', .false.) == 1 ) ) THEN
         idx_star = INDEX(metatab(i)%Hname, '*', .false.)
         template = metatab(i)%Hname(1:idx_star-1)//&
                    TRIM(Species(speidx)%Hname)//&
                    metatab(i)%Hname(idx_star+1:)
         WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_Hname)
         WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(template)
      ELSE
         template = metatab(i)%Hname
         DO j = 1, nsubcols(i-ifil+1)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_Hname)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(template)
         ENDDO
      ENDIF
   ENDDO
   WRITE(iwrtmp,*)

   !======================================================================================
   ! 4 - Write the line containing all the unique ID names in the output ASCII file
   !     if a "*" is present in the pubID, generic names need to be created
   !======================================================================================
   DO i = ifil, ifil + ndatafile - 1
      IF ( nsubcols(i-ifil+1) == 0 ) CYCLE
      IF      ( ( INDEX(metatab(i)%IDname, 'n_*            ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'cd_prof_*      ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'cd_*           ', .false.) == 1 ) ) THEN
         idx_star = INDEX(metatab(i)%IDname, '*', .false.)
         DO j = 1, nspec
            template = metatab(i)%IDname(1:idx_star-1)//&
                       TRIM(Species(j)%SpecyID)//&
                       metatab(i)%IDname(idx_star+1:)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_IDname)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(template)
         ENDDO
      ELSE IF ( ( INDEX(metatab(i)%IDname, 'coolrate_*     ', .false.) == 1 ) ) THEN
         idx_star = INDEX(metatab(i)%IDname, '*', .false.)
         DO j = 1, nspl
            template = metatab(i)%IDname(1:idx_star-1)//&
                       TRIM(spec_lin(j)%spID)//&
                       metatab(i)%IDname(idx_star+1:)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_IDname)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(template)
         ENDDO
      ELSE IF ( ( INDEX(metatab(i)%IDname, 'temp_grain_r*  ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'charge_grain_r*', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'radius_grain_r*', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'dens_grain_r*  ', .false.) == 1 ) ) THEN
         idx_star = INDEX(metatab(i)%IDname, '*', .false.)
         DO j = 1, npg
            CALL INT_STR(j, strindex, 2)
            template = metatab(i)%IDname(1:idx_star-1)//&
                       TRIM(strindex)//&
                       metatab(i)%IDname(idx_star+1:)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_IDname)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(template)
         ENDDO
      ELSE IF ( ( INDEX(metatab(i)%IDname, 'elem_*         ', .false.) == 1 ) ) THEN
         idx_star = INDEX(metatab(i)%IDname, '*', .false.)
         DO j = 1, natom-1
            sp_lowcas = sp(j)
            IF ( sp(j) == 'c*      ') sp_lowcas = '13c     '
            IF ( sp(j) == 'n*      ') sp_lowcas = '15n     '
            IF ( sp(j) == 'o*      ') sp_lowcas = '18o     '
            template = metatab(i)%IDname(1:idx_star-1)//&
                       TRIM(sp_lowcas)//&
                       metatab(i)%IDname(idx_star+1:)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_IDname)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(template)
         ENDDO
      ELSE IF ( ( INDEX(metatab(i)%IDname, 'cd_lev_*       ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'cd_lev_prof_*  ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'pop_*          ', .false.) == 1 ) ) THEN
         idx_star = INDEX(metatab(i)%IDname, '*', .false.)
         DO j1 = 1, nspl
            DO j2 = 1, spec_lin(j1)%use
               template = metatab(i)%IDname(1:idx_star-1)//&
                          TRIM(spec_lin(j1)%spID)//"_"//&
                          TRIM(spec_lin(j1)%LeID(j2))//&
                          metatab(i)%IDname(idx_star+1:)
               WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_IDname)
               WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(template)
            ENDDO
         ENDDO
      ELSE IF ( ( INDEX(metatab(i)%IDname, 'photo_prob_*        ', .false.) == 1 ) ) THEN
         idx_star = INDEX(metatab(i)%IDname, '*', .false.)
         DO j = 1, nphot_i
            template = metatab(i)%IDname(1:idx_star-1)//"_"
            IF ( react(iphot_i+j-1, 1) /= 0 ) template = TRIM(template)//"_"//TRIM(Species(react(iphot_i+j-1, 1))%SpecyID)
            DO j1 = 2, 3
            IF ( react(iphot_i+j-1,j1) /= 0 ) template = TRIM(template)//"_"//TRIM(Species(react(iphot_i+j-1,j1))%SpecyID)
            ENDDO
            IF ( react(iphot_i+j-1, 4) /= 0 ) template = TRIM(template)//"_gives_"//TRIM(Species(react(iphot_i+j-1, 4))%SpecyID)
            DO j1 = 5, 7
            IF ( react(iphot_i+j-1,j1) /= 0 ) template = TRIM(template)//"_"//TRIM(Species(react(iphot_i+j-1,j1))%SpecyID)
            ENDDO
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_IDname)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(template)
         ENDDO
      ELSE IF ( ( INDEX(metatab(i)%IDname, 'em_*           ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'optdep_*       ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'dint_*         ', .false.) == 1 ) ) THEN
         idx_star = INDEX(metatab(i)%IDname, '*', .false.)
         DO j1 = 1, nspl
            DO j2 = 1, spec_lin(j1)%ntr
               IF (spec_lin(j1)%iup(j2) > spec_lin(j1)%use) CYCLE
               template = metatab(i)%IDname(1:idx_star-1)//&
                          TRIM(spec_lin(j1)%spID)//"_"//&
                          TRIM(spec_lin(j1)%LiID(j2))//&
                          metatab(i)%IDname(idx_star+1:)
               WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_IDname)
               WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(template)
            ENDDO
         ENDDO
      ELSE IF ( ( INDEX(metatab(i)%IDname, 'inta_*         ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'abso_*         ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'cont_*         ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'level_ctrb_*   ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'avpos_ctrb_*   ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'avmoy_ctrb_*   ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'avrms_ctrb_*   ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'bkgd_ctrb_*    ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'dust_ctrb_*    ', .false.) == 1 ) ) THEN
         idx_star = INDEX(metatab(i)%IDname, '*', .false.)
         DO j1 = 1, nspl
            DO j2 = 1, spec_lin(j1)%ntr
               IF (spec_lin(j1)%iup(j2) > spec_lin(j1)%use) CYCLE
               template = metatab(i)%IDname(1:idx_star-1)//&
                          TRIM(angstr)//"_"//&
                          TRIM(spec_lin(j1)%spID)//"_"//&
                          TRIM(spec_lin(j1)%LiID(j2))//&
                          metatab(i)%IDname(idx_star+1:)
               WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_IDname)
               WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(template)
            ENDDO
         ENDDO
      ELSE IF ( ( INDEX(metatab(i)%IDname, 'dens_spec_*    ', .false.) == 1 ) ) THEN
         idx_star = INDEX(metatab(i)%IDname, '*', .false.)
         template = metatab(i)%IDname(1:idx_star-1)//&
                    TRIM(Species(speidx)%SpecyID)//&
                    metatab(i)%IDname(idx_star+1:)
         WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_IDname)
         WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(template)
      ELSE IF ( ( INDEX(metatab(i)%IDname, 'frate_*        ', .false.) == 1 ) ) THEN
         idx_star = INDEX(metatab(i)%IDname, '*', .false.)
         DO j = 1, nbf
            template = metatab(i)%IDname(1:idx_star-1)//TRIM(Species(speidx)%SpecyID)
            IF ( react(idx_freac(j), 1) /= 0 ) template = TRIM(template)//"_"//TRIM(Species(react(idx_freac(j), 1))%SpecyID)
            DO j1 = 2, 3
            IF ( react(idx_freac(j),j1) /= 0 ) template = TRIM(template)//"_"//TRIM(Species(react(idx_freac(j),j1))%SpecyID)
            ENDDO
            IF ( react(idx_freac(j), 4) /= 0 ) template = TRIM(template)//"_gives_"//TRIM(Species(react(idx_freac(j), 4))%SpecyID)
            DO j1 = 5, 7
            IF ( react(idx_freac(j),j1) /= 0 ) template = TRIM(template)//"_"//TRIM(Species(react(idx_freac(j),j1))%SpecyID)
            ENDDO
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_IDname)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(template)
         ENDDO
      ELSE IF ( ( INDEX(metatab(i)%IDname, 'drate_*        ', .false.) == 1 ) ) THEN
         idx_star = INDEX(metatab(i)%IDname, '*', .false.)
         DO j = 1, nbd
            template = metatab(i)%IDname(1:idx_star-1)//TRIM(Species(speidx)%SpecyID)
            IF ( react(idx_dreac(j), 1) /= 0 ) template = TRIM(template)//"_"//TRIM(Species(react(idx_dreac(j), 1))%SpecyID)
            DO j1 = 2, 3
            IF ( react(idx_dreac(j),j1) /= 0 ) template = TRIM(template)//"_"//TRIM(Species(react(idx_dreac(j),j1))%SpecyID)
            ENDDO
            IF ( react(idx_dreac(j), 4) /= 0 ) template = TRIM(template)//"_gives_"//TRIM(Species(react(idx_dreac(j), 4))%SpecyID)
            DO j1 = 5, 7
            IF ( react(idx_dreac(j),j1) /= 0 ) template = TRIM(template)//"_"//TRIM(Species(react(idx_dreac(j),j1))%SpecyID)
            ENDDO
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_IDname)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(template)
         ENDDO
      ELSE IF ( ( INDEX(metatab(i)%IDname, 'tot_frate_*    ', .false.) == 1 ).OR.&
                ( INDEX(metatab(i)%IDname, 'tot_drate_*    ', .false.) == 1 ) ) THEN
         idx_star = INDEX(metatab(i)%IDname, '*', .false.)
         template = metatab(i)%IDname(1:idx_star-1)//TRIM(Species(speidx)%SpecyID)
         DO j = 1, nsubcols(i-ifil+1)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_IDname)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(template)
         ENDDO
      ELSE IF ( ( INDEX(metatab(i)%IDname, 'compo_of_*     ', .false.) == 1 ) ) THEN
         idx_star = INDEX(metatab(i)%IDname, '*', .false.)
         DO j = 1, natom
            template = metatab(i)%IDname(1:idx_star-1)//TRIM(Species(speidx)%SpecyID)//'_'
            sp_lowcas = sp(j)
            IF ( sp(j) == 'c*      ') sp_lowcas = '13c     '
            IF ( sp(j) == 'n*      ') sp_lowcas = '15n     '
            IF ( sp(j) == 'o*      ') sp_lowcas = '18o     '
            IF ( sp(j) == 'electr  ') sp_lowcas = 'charge  '
            template = TRIM(template)//TRIM(sp_lowcas)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_IDname)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(template)
         ENDDO
      ELSE IF ( ( INDEX(metatab(i)%IDname, 'mass_of_*      ', .false.) == 1 ) ) THEN
         idx_star = INDEX(metatab(i)%IDname, '*', .false.)
         template = metatab(i)%IDname(1:idx_star-1)//&
                    TRIM(Species(speidx)%SpecyID)//&
                    metatab(i)%IDname(idx_star+1:)
         WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_IDname)
         WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(template)
      ELSE
         template = metatab(i)%IDname
         DO j = 1, nsubcols(i-ifil+1)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_IDname)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(template)
         ENDDO
      ENDIF
   ENDDO
   WRITE(iwrtmp,*)

   !======================================================================================
   ! 5 - Write the line containing all the dtypes in the output ASCII file
   !======================================================================================
   DO i = ifil, ifil + ndatafile - 1
      IF ( nsubcols(i-ifil+1) == 0 ) CYCLE
      template = metatab(i)%dtype
      DO j = 1, nsubcols(i-ifil+1)
         WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_dtype)
         WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(template)
      ENDDO
   ENDDO
   WRITE(iwrtmp,*)

   !======================================================================================
   ! 6 - Write the line containing all the dtypes in the output ASCII file
   !     only radm_ini and radp_ini have units that depend on the other input parameters
   !======================================================================================
   DO i = ifil, ifil + ndatafile - 1
      IF ( nsubcols(i-ifil+1) == 0 ) CYCLE
      IF ( ( INDEX(metatab(i)%IDname, 'radm_ini      ', .false.) == 1 ).OR.&
           ( INDEX(metatab(i)%IDname, 'radp_ini      ', .false.) == 1 ) ) THEN
         IF (F_ISRF == 1) THEN
            template = "Mathis unit"
         ELSE IF (F_ISRF == 2) THEN
            template = "Draine unit"
         ENDIF
      ELSE
         template = metatab(i)%unit
      ENDIF
      DO j = 1, nsubcols(i-ifil+1)
         WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_unit)
         WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(template)
      ENDDO
   ENDDO
   WRITE(iwrtmp,*)

   !======================================================================================
   ! 7 - Write the line containing all the SKOS in the output ASCII file
   !     SKOS need to be generated here only in a few cases
   !======================================================================================
   DO i = ifil, ifil + ndatafile - 1
      IF ( nsubcols(i-ifil+1) == 0 ) CYCLE
      IF ( ( INDEX(metatab(i)%IDname, 'n_*           ', .false.) == 1 ).OR.&
           ( INDEX(metatab(i)%IDname, 'cd_prof_*     ', .false.) == 1 ).OR.&
           ( INDEX(metatab(i)%IDname, 'cd_*          ', .false.) == 1 ) ) THEN
         idx_star = INDEX(metatab(i)%SKOS, '*', .false.)
         DO j = 1, nspec
            template = metatab(i)%SKOS(1:idx_star-1)//&
                       TRIM(Species(j)%INCHI)//&
                       metatab(i)%SKOS(idx_star+1:)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_SKOS)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(template)
         ENDDO
      ELSE
         template = metatab(i)%SKOS
         DO j = 1, nsubcols(i-ifil+1)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_SKOS)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(template)
         ENDDO
      ENDIF
   ENDDO
   WRITE(iwrtmp,*)

   !======================================================================================
   ! 8 - Write the line containing all the UCDs in the output ASCII file
   !======================================================================================
   DO i = ifil, ifil + ndatafile - 1
      IF ( nsubcols(i-ifil+1) == 0 ) CYCLE
      template = metatab(i)%ucd
      DO j = 1, nsubcols(i-ifil+1)
         WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_ucd)
         WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(template)
      ENDDO
   ENDDO
   WRITE(iwrtmp,*)

   !======================================================================================
   ! 9 - Write the line containing all the utypes in the output ASCII file
   !======================================================================================
   DO i = ifil, ifil + ndatafile - 1
      IF ( nsubcols(i-ifil+1) == 0 ) CYCLE
      template = metatab(i)%utype
      DO j = 1, nsubcols(i-ifil+1)
         WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_utype)
         WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(template)
      ENDDO
   ENDDO
   WRITE(iwrtmp,*)

   !======================================================================================
   ! 10 - Write the line containing all the groups in the output ASCII file
   !======================================================================================
   DO i = ifil, ifil + ndatafile - 1
      IF ( nsubcols(i-ifil+1) == 0 ) CYCLE
      template = metatab(i)%group
      DO j = 1, nsubcols(i-ifil+1)
         WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_group)
         WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(template)
      ENDDO
   ENDDO
   WRITE(iwrtmp,*)

   !======================================================================================
   ! 11 - Write the line containing all the parents in the output ASCII file
   !======================================================================================
   DO i = ifil, ifil + ndatafile - 1
      IF ( nsubcols(i-ifil+1) == 0 ) CYCLE
      template = metatab(i)%parent
      DO j = 1, nsubcols(i-ifil+1)
         WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_parent)
         WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(template)
      ENDDO
   ENDDO
   WRITE(iwrtmp,*)

   !======================================================================================
   ! 12 - Write the line containing all the descriptions in the output ASCII file
   !======================================================================================
   DO i = ifil, ifil + ndatafile - 1
      IF ( nsubcols(i-ifil+1) == 0 ) CYCLE
      IF      ( ( INDEX(metatab(i)%IDname, 'elem_*        ', .false.) == 1 ) ) THEN
         idx_star = INDEX(metatab(i)%descrp, '*', .false.)
         DO j = 1, natom-1
            IF ( sp(j) == 'h       ') sp_uppcas = 'H       '
            IF ( sp(j) == 'c       ') sp_uppcas = 'C       '
            IF ( sp(j) == 'n       ') sp_uppcas = 'N       '
            IF ( sp(j) == 'o       ') sp_uppcas = 'O       '
            IF ( sp(j) == 'he      ') sp_uppcas = 'He      '
            IF ( sp(j) == 'd       ') sp_uppcas = 'D       '
            IF ( sp(j) == 'c*      ') sp_uppcas = '13C     '
            IF ( sp(j) == 'n*      ') sp_uppcas = '15N     '
            IF ( sp(j) == 'o*      ') sp_uppcas = '18O     '
            IF ( sp(j) == 'ar      ') sp_uppcas = 'Ar      '
            IF ( sp(j) == 'f       ') sp_uppcas = 'F       '
            IF ( sp(j) == 'na      ') sp_uppcas = 'Na      '
            IF ( sp(j) == 'mg      ') sp_uppcas = 'Mg      '
            IF ( sp(j) == 'al      ') sp_uppcas = 'Al      '
            IF ( sp(j) == 'si      ') sp_uppcas = 'Si      '
            IF ( sp(j) == 'ne      ') sp_uppcas = 'Ne      '
            IF ( sp(j) == 's       ') sp_uppcas = 'S       '
            IF ( sp(j) == 'cl      ') sp_uppcas = 'Cl      '
            IF ( sp(j) == 'ca      ') sp_uppcas = 'Ca      '
            IF ( sp(j) == 'fe      ') sp_uppcas = 'Fe      '
            template = metatab(i)%descrp(1:idx_star-1)//&
                       TRIM(sp_uppcas)//&
                       metatab(i)%descrp(idx_star+1:)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_descrp)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(template)
         ENDDO
      ELSE
         template = metatab(i)%descrp
         DO j = 1, nsubcols(i-ifil+1)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_descrp)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(template)
         ENDDO
      ENDIF
   ENDDO
   WRITE(iwrtmp,*)

   !======================================================================================
   ! 13 - Write the final lines containing the actual data in the output ASCII file
   !======================================================================================
   DO k = 1, nvals
      DO i = ifil, ifil + ndatafile - 1
         IF ( nsubcols(i-ifil+1) == 0 ) CYCLE
         key_temp = key_val
         IF (i == ifil) key_temp = ""
         IF      ( ( INDEX(metatab(i)%IDname, 'tauv                  ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') tau(k-1)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'av                    ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') visualext(k-1)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'distance              ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') d_cm(k-1)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'protdens              ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') densh(k-1)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'ntot                  ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') totdensity(k-1)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'tgas                  ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') tgaz(k-1)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'pgas                  ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') gaspressure(k-1)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'iondegree             ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') ionidegree(k-1)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'elecdens_gas          ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') abnua(nspec,k-1)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'uv_flux               ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') fluph(k-1)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'uv_dens               ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') int_rad(k-1)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'h2_form_rate          ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') timh21(k-1)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'h2_dest_rate          ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') timh22(k-1)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'h2_form_rate_lh       ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') timh23(k-1)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'h2_form_rate_er       ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') timh25(k-1)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'h2_dest_rate_ph       ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') timh24(k-1)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'photo_prob_*          ', .false.) == 1 ) ) THEN
            DO j = 1, nphot_i
               IF ( j /=1 ) key_temp = key_val
               WRITE(strf,'(1p,E16.8e3)') pdiesp(j,k-1)
               WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
            ENDDO
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'mol_frac_ab           ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') molfrac_ab(k-1)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'nb_ice_layers         ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') x_lay(k-1)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'n_*                   ', .false.) == 1 ) ) THEN
            DO j = 1,nspec
               IF ( j /=1 ) key_temp = key_val
               WRITE(strf,'(1p,E16.8e3)') abnua(j,k-1)
               WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
            ENDDO
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'cd_prof_*             ', .false.) == 1 ) ) THEN
            DO j = 1,nspec
               IF ( j /=1 ) key_temp = key_val
               WRITE(strf,'(1p,E16.8e3)') codesp(j,k-1)
               WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
            ENDDO
         ELSE IF ( ( INDEX(metatab(i)%IDname, 't01_ab                ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') T01_ab(k-1)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'h2_opr_ab             ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') h2opr_ab(k-1)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'heatrate_tot          ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') chotot(k-1)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'heatrate_pe           ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') chophg(k-1)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'heatrate_h2           ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') choh2g(k-1)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'heatrate_ph           ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') chopht(k-1)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'heatrate_cr           ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') chorc(k-1)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'heatrate_secp         ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') chophs(k-1)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'heatrate_chem         ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') chochi(k-1)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'heatrate_turb         ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') chotur(k-1)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'heatrate_gasgr        ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') choeqg(k-1)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'coolrate_freefree     ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') ref_ff(k-1)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'coolrate_elrecomb     ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') refrec(k-1)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'coolrate_tot          ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') reftot(k-1)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'coolrate_*            ', .false.) == 1 ) ) THEN
            DO j = 1,nspl
               IF ( j /=1 ) key_temp = key_val
               WRITE(strf,'(1p,E16.8e3)') spec_lin(j)%ref(k-1)
               WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
            ENDDO
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'pop_*                 ', .false.) == 1 ) ) THEN
            DO j1 = 1, nspl
               DO j2 = 1, spec_lin(j1)%use
                  IF ( j2 /=1 ) key_temp = key_val
                  WRITE(strf,'(1p,E16.8e3)') spec_lin(j1)%xre(j2,k-1) * spec_lin(j1)%abu(k-1)
                  WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
               ENDDO
            ENDDO
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'cd_lev_prof_*         ', .false.) == 1 ) ) THEN
            DO j1 = 1, nspl
               DO j2 = 1, spec_lin(j1)%use
                  IF ( j2 /=1 ) key_temp = key_val
                  WRITE(strf,'(1p,E16.8e3)') spec_lin(j1)%COD(j2,k-1)
                  WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
               ENDDO
            ENDDO
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'em_*                  ', .false.) == 1 ) ) THEN
            DO j1 = 1, nspl
               DO j2 = 1, spec_lin(j1)%ntr
                  IF ( j2 /=1 ) key_temp = key_val
                  IF (spec_lin(j1)%iup(j2) > spec_lin(j1)%use) CYCLE
                  WRITE(strf,'(1p,E16.8e3)') spec_lin(j1)%emi(j2,k-1)
                  WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
               ENDDO
            ENDDO
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'optdep_*              ', .false.) == 1 ) ) THEN
            DO j1 = 1, nspl
               DO j2 = 1, spec_lin(j1)%ntr
                  IF ( j2 /=1 ) key_temp = key_val
                  IF (spec_lin(j1)%iup(j2) > spec_lin(j1)%use) CYCLE
                  WRITE(strf,'(1p,E16.8e3)') spec_lin(j1)%optdep(j2,k-1)
                  WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
               ENDDO
            ENDDO
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'dint_*                ', .false.) == 1 ) ) THEN
            DO j1 = 1, nspl
               DO j2 = 1, spec_lin(j1)%ntr
                  IF ( j2 /=1 ) key_temp = key_val
                  IF (spec_lin(j1)%iup(j2) > spec_lin(j1)%use) CYCLE
                  WRITE(strf,'(1p,E16.8e3)') spec_lin(j1)%dint(j2,k-1)
                  WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
               ENDDO
            ENDDO
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'n_charge_on_grain     ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') grcharge(k-1)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'elecdens_grain        ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') -grcharge(k-1)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'temp_grain_r*         ', .false.) == 1 ) ) THEN
            DO j = 1, npg
               IF ( j /=1 ) key_temp = key_val
               WRITE(strf,'(1p,E16.8e3)') tdust(j,k-1)
               WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
            ENDDO
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'charge_grain_r*       ', .false.) == 1 ) ) THEN
            DO j = 1, npg
               IF ( j /=1 ) key_temp = key_val
               WRITE(strf,'(1p,E16.8e3)') zmoy(j,k-1)
               WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
            ENDDO
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'dens_grain_r*         ', .false.) == 1 ) ) THEN
            DO j = 1, npg
               IF ( j /=1 ) key_temp = key_val
               WRITE(strf,'(1p,E16.8e3)') wwmg(j) * densh(k-1)
               WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
            ENDDO
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'radius_grain_r*       ', .false.) == 1 ) ) THEN
            DO j = 1, npg
               IF ( j /=1 ) key_temp = key_val
               WRITE(strf,'(1p,E16.8e3)') adust(j)
               WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
            ENDDO
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'cd_*                  ', .false.) == 1 ) ) THEN
            DO j = 1, nspec
               IF ( j /=1 ) key_temp = key_val
               WRITE(strf,'(1p,E16.8e3)') totcoldens(j)
               WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
            ENDDO
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'mol_frac_cd           ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') molfrac_cd(npo)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)           
         ELSE IF ( ( INDEX(metatab(i)%IDname, 't01_cd                ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') T01_cd(npo)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'h2_opr_cd_tot         ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') h2opr_cd_tot(npo)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'h2_opr_cd_emi         ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') h2opr_cd_emi(npo)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'h2_opr_cd_vib         ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') h2opr_cd_vib(npo)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'cd_lev_*              ', .false.) == 1 ) ) THEN
            DO j1 = 1, nspl
               DO j2 = 1, spec_lin(j1)%use
                  IF ( j2 /=1 ) key_temp = key_val
                  WRITE(strf,'(1p,E16.8e3)') spec_lin(j1)%COD(j2,npo)
                  WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
               ENDDO
            ENDDO
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'inta_*                ', .false.) == 1 ) ) THEN
            DO j1 = 1, nspl
               DO j2 = 1, spec_lin(j1)%ntr
                  IF ( j2 /=1 ) key_temp = key_val
                  IF (spec_lin(j1)%iup(j2) > spec_lin(j1)%use) CYCLE
                  WRITE(strf,'(1p,E16.8e3)') spec_lin(j1)%int(j2,angidx)
                  WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
               ENDDO
            ENDDO
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'int_cont_a00_3_3000   ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') Icont_3_1000
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'int_cont_a00_25_60    ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') Icont_25_60
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'int_cont_a00_60_200   ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') Icont_60_200
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'int_cont_a00_200_1000 ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') Icont_200_1000
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'int_cont_a00_60_1000  ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') Icont_60_1000
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'abso_*                ', .false.) == 1 ) ) THEN
            DO j1 = 1, nspl
               DO j2 = 1, spec_lin(j1)%ntr
                  IF ( j2 /=1 ) key_temp = key_val
                  IF (spec_lin(j1)%iup(j2) > spec_lin(j1)%use) CYCLE
                  WRITE(strf,'(1p,E16.8e3)') spec_lin(j1)%abso(j2,angidx)
                  WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
               ENDDO
            ENDDO
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'cont_*                ', .false.) == 1 ) ) THEN
            DO j1 = 1, nspl
               DO j2 = 1, spec_lin(j1)%ntr
                  IF ( j2 /=1 ) key_temp = key_val
                  IF (spec_lin(j1)%iup(j2) > spec_lin(j1)%use) CYCLE
                  WRITE(strf,'(1p,E16.8e3)') spec_lin(j1)%cont(j2,angidx)
                  WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
               ENDDO
            ENDDO
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'level_ctrb_*          ', .false.) == 1 ) ) THEN
            DO j1 = 1, nspl
               DO j2 = 1, spec_lin(j1)%ntr
                  IF ( j2 /=1 ) key_temp = key_val
                  IF (spec_lin(j1)%iup(j2) > spec_lin(j1)%use) CYCLE
                  WRITE(strf,'(1p,E16.8e3)') spec_lin(j1)%lvl_ctr(j2,angidx)
                  WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
               ENDDO
            ENDDO
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'avpos_ctrb_*          ', .false.) == 1 ) ) THEN
            DO j1 = 1, nspl
               DO j2 = 1, spec_lin(j1)%ntr
                  IF ( j2 /=1 ) key_temp = key_val
                  IF (spec_lin(j1)%iup(j2) > spec_lin(j1)%use) CYCLE
                  WRITE(strf,'(1p,E16.8e3)') spec_lin(j1)%pos_ctr(j2,angidx)
                  WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
               ENDDO
            ENDDO
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'avmoy_ctrb_*          ', .false.) == 1 ) ) THEN
            DO j1 = 1, nspl
               DO j2 = 1, spec_lin(j1)%ntr
                  IF ( j2 /=1 ) key_temp = key_val
                  IF (spec_lin(j1)%iup(j2) > spec_lin(j1)%use) CYCLE
                  WRITE(strf,'(1p,E16.8e3)') spec_lin(j1)%moy_ctr(j2,angidx)
                  WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
               ENDDO
            ENDDO
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'avrms_ctrb_*          ', .false.) == 1 ) ) THEN
            DO j1 = 1, nspl
               DO j2 = 1, spec_lin(j1)%ntr
                  IF ( j2 /=1 ) key_temp = key_val
                  IF (spec_lin(j1)%iup(j2) > spec_lin(j1)%use) CYCLE
                  WRITE(strf,'(1p,E16.8e3)') spec_lin(j1)%rms_ctr(j2,angidx)
                  WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
               ENDDO
            ENDDO
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'bkgd_ctrb_*           ', .false.) == 1 ) ) THEN
            DO j1 = 1, nspl
               DO j2 = 1, spec_lin(j1)%ntr
                  IF ( j2 /=1 ) key_temp = key_val
                  IF (spec_lin(j1)%iup(j2) > spec_lin(j1)%use) CYCLE
                  WRITE(strf,'(1p,E16.8e3)') spec_lin(j1)%bkgd_ctr_cont(j2,angidx)
                  WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
               ENDDO
            ENDDO
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'dust_ctrb_*           ', .false.) == 1 ) ) THEN
            DO j1 = 1, nspl
               DO j2 = 1, spec_lin(j1)%ntr
                  IF ( j2 /=1 ) key_temp = key_val
                  IF (spec_lin(j1)%iup(j2) > spec_lin(j1)%use) CYCLE
                  WRITE(strf,'(1p,E16.8e3)') spec_lin(j1)%dust_ctr_cont(j2,angidx)
                  WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
               ENDDO
            ENDDO
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'wavelength            ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') out_spectrum(k,1)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'spec_int_tot          ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') out_spectrum(k,2)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'spec_int_dust         ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') out_spectrum(k,3)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'spec_int_bkgd         ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') out_spectrum(k,4)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'versioncode           ', .false.) == 1 ) ) THEN
            WRITE(strs,'(A)') TRIM(version_code)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strs)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'chemistry_file        ', .false.) == 1 ) ) THEN
            WRITE(strs,'(A)') TRIM(chimie)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strs)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'avmax                 ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') Avmax
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'equation_of_state     ', .false.) == 1 ) ) THEN
            IF      (ifisob == 0 .AND. ifeqth == 1) THEN
               WRITE(strs,'(A)') "isochoric, thermal balance"
            ELSE IF (ifisob == 0 .AND. ifeqth == 0) THEN
               WRITE(strs,'(A)') "isochoric, isothermal"
            ELSE IF (ifisob == 2 .AND. ifeqth == 1) THEN
               WRITE(strs,'(A)') "isobaric, thermal balance"
            ELSE IF (ifisob == 2 .AND. ifeqth == 0) THEN
               WRITE(strs,'(A)') "isobaric, isothermal"
            ELSE IF (ifisob == 1 .AND. ifeqth == 1) THEN
               WRITE(strs,'(A)') "density profile, thermal balance"
            ELSE IF (ifisob == 1 .AND. ifeqth == 0) THEN
               WRITE(strs,'(A)') "density and temperature profiles"
            ELSE IF (ifisob == -1 .AND. ifeqth == 1) THEN
               WRITE(strs,'(A)') "symetric density profile, thermal balance"
            ELSE IF (ifisob == -1 .AND. ifeqth == 0) THEN
               WRITE(strs,'(A)') "symetric density and temperature profiles"
            ENDIF
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strs)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'proton_density_input  ', .false.) == 1 ) ) THEN
            IF (ifisob == 0) THEN
               WRITE(strf,'(1p,E16.8e3)') nh_init
            ELSE IF (ifisob == 2 .AND. ifeqth == 0) THEN
               WRITE(strf,'(1p,E16.8e3)') presse / tg_init
            ENDIF
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'gas_pressure_input    ', .false.) == 1 ) ) THEN
            IF (ifisob == 2) THEN
               WRITE(strf,'(1p,E16.8e3)') presse
            ELSE IF (ifisob == 0 .AND. ifeqth == 0) THEN
               WRITE(strf,'(1p,E16.8e3)') nh_init * tg_init
            ENDIF
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'gas_temperature_input ', .false.) == 1 ) ) THEN
            IF (ifeqth == 0) THEN
               WRITE(strf,'(1p,E16.8e3)') tg_init
            ENDIF
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'f_isrf                ', .false.) == 1 ) ) THEN
            IF (F_ISRF == 1) THEN
               WRITE(strs,'(A)') "Mathis"
            ELSE IF (F_ISRF == 2) THEN
               WRITE(strs,'(A)') "Draine"
            ENDIF
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strs)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'radm_ini              ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') radm_ini
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'radp_ini              ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') radp_ini
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'additional_radfield   ', .false.) == 1 ) ) THEN
            WRITE(strs,'(A)') TRIM(srcpp)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strs)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'd_sour                ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') d_sour
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'zeta                  ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') zeta
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'vturb                 ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') vturb
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'ichh2                 ', .false.) == 1 ) ) THEN
            WRITE(stri,'(I10)') ichh2
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(stri)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'los_ext               ', .false.) == 1 ) ) THEN
            WRITE(strs,'(A)') los_ext
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strs)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'rv                    ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') rrv
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'metal                 ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') metal
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'cdunit_0              ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') cdunit_0
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'g_ratio_0             ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') g_ratio_0
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'cdunit                ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') cdunit
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'g_ratio               ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') g_ratio
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'q_pah                 ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') q_pah
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'a0_pah                ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') a0_pah
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'sigma_pah             ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') sigma_pah
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'alpgr                 ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') alpgr
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'rgrmin                ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') rgrmin
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'rgrmax                ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') rgrmax
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'f_dust_p              ', .false.) == 1 ) ) THEN
            WRITE(stri,'(I10)') F_DUST_P
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(stri)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'iforh2                ', .false.) == 1 ) ) THEN
            WRITE(stri,'(I10)') iforh2
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(stri)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'istic                 ', .false.) == 1 ) ) THEN
            WRITE(stri,'(I10)') istic
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(stri)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'fwlinemap             ', .false.) == 1 ) ) THEN
            WRITE(stri,'(I10)') F_W_LINE_MAP
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(stri)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'fwrfalb               ', .false.) == 1 ) ) THEN
            WRITE(stri,'(I10)') F_W_RF_ALB
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(stri)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'fwallifaf             ', .false.) == 1 ) ) THEN
            WRITE(stri,'(I10)') F_W_ALL_IFAF
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(stri)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 't_cmb                 ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') tcmb
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'isoneside             ', .false.) == 1 ) ) THEN
            WRITE(stri,'(I10)') isoneside+1
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(stri)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'ifafm                 ', .false.) == 1 ) ) THEN
            WRITE(stri,'(I10)') ifafm
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(stri)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'ifaf                  ', .false.) == 1 ) ) THEN
            WRITE(stri,'(I10)') ifaf
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(stri)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'elem_*                ', .false.) == 1 ) ) THEN
            DO j = 1, natom-1
               IF ( j /=1 ) key_temp = key_val
               WRITE(strf,'(1p,E16.8e3)') l_atom(j)%abnorm
               WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
            ENDDO
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'dens_spec_*           ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') abnua(speidx,k-1)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'frate_*               ', .false.) == 1 ) ) THEN
            DO j = 1, nbf
               IF ( j /=1 ) key_temp = key_val
               WRITE(strf,'(1p,E16.8e3)') form_rate(j,k-1)
               WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
            ENDDO
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'drate_*               ', .false.) == 1 ) ) THEN
            DO j = 1, nbd
               IF ( j /=1 ) key_temp = key_val
               WRITE(strf,'(1p,E16.8e3)') dest_rate(j,k-1)
               WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
            ENDDO
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'tot_frate_*           ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') SUM(form_rate(1:nbf,k-1))
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'tot_drate_*           ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') SUM(dest_rate(1:nbd,k-1))
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'compo_of_*            ', .false.) == 1 ) ) THEN
            DO j = 1, natom
               IF ( j /=1 ) key_temp = key_val
               WRITE(stri,'(I10)') ael(speidx,j)
               WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(stri)
            ENDDO
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'mass_of_*             ', .false.) == 1 ) ) THEN
            WRITE(strf,'(1p,E16.8e3)') mol(speidx)
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strf)
         ELSE IF ( ( INDEX(metatab(i)%IDname, 'network        ', .false.) == 1 ) ) THEN
            READ (iread1,'(A)') strs
            WRITE(iwrtmp,'(A)',ADVANCE='no') TRIM(key_temp)//TRIM(strs)
         ENDIF
      ENDDO
      WRITE(iwrtmp,*)
   ENDDO

   !======================================================================================
   ! Close the input chemical file if needed
   !======================================================================================
   IF ( INDEX(metatab(ifil)%path, 'Network', .false.) /= 0 ) THEN
      CLOSE (iread1)
   ENDIF

   !======================================================================================
   ! Close the ASCII file
   !======================================================================================
   CLOSE(iwrtmp)

END SUBROUTINE WRITE_METADATA

!%%%%%%%%%%%%%%%%%%%%
SUBROUTINE FILL_RATES
!%%%%%%%%%%%%%%%%%%%%
   IMPLICIT none
   INTEGER                  :: i, j, ir1, ir2, ir3, ip1, ip2, ip3, ip4
   INTEGER, DIMENSION(neqt) :: multf, multd

   ! -------------------------------------------------------------------------------------
   ! Compute the number of reactions for the formation and destruction of species speidx
   ! -------------------------------------------------------------------------------------
   nbf   = 0
   nbd   = 0
   multf = 0
   multd = 0
   DO j = 1, neqt
     ir1 = react(j,1)
     ir2 = react(j,2)
     ir3 = react(j,3)
     ip1 = react(j,4)
     ip2 = react(j,5)
     ip3 = react(j,6)
     ip4 = react(j,7)
     IF (ir1 == speidx) multd(j) = multd(j) + 1
     IF (ir2 == speidx) multd(j) = multd(j) + 1
     IF (ir3 == speidx) multd(j) = multd(j) + 1
     IF (ip1 == speidx) multf(j) = multf(j) + 1
     IF (ip2 == speidx) multf(j) = multf(j) + 1
     IF (ip3 == speidx) multf(j) = multf(j) + 1
     IF (ip4 == speidx) multf(j) = multf(j) + 1
     IF      (multf(j)-multd(j) > 0) THEN
        nbf = nbf + 1
     ELSE IF (multf(j)-multd(j) < 0) THEN
        nbd = nbd + 1
     ENDIF
   ENDDO

   ! -------------------------------------------------------------------------------------
   ! Allocate and fill the tables that contain the formation and destruction rates
   ! -------------------------------------------------------------------------------------
   ALLOCATE (form_rate(nbf,0:npo))
   ALLOCATE (dest_rate(nbd,0:npo))
   ALLOCATE (idx_freac(nbf))
   ALLOCATE (idx_dreac(nbd))

   nbf   = 0
   nbd   = 0
   DO j = 1, neqt
      IF      (multf(j)-multd(j) > 0) THEN
         nbf = nbf + 1
         DO i = 0, npo
            form_rate(nbf,i) = all_rate_chem(j,i) * ABS(multf(j)-multd(j))
         ENDDO
         idx_freac(nbf) = j
      ELSE IF (multf(j)-multd(j) < 0) THEN
         nbd = nbd + 1
         DO i = 0, npo
            dest_rate(nbd,i) = all_rate_chem(j,i) * ABS(multf(j)-multd(j))
         ENDDO
         idx_dreac(nbd) = j
      ENDIF
   ENDDO

END SUBROUTINE FILL_RATES

END MODULE PXDR_OUTPUT_ASCII
