#!/bin/bash

#set -vx

#=============================================================================
#  F. Hourdin : 2022/05/03
#
#  Objet :
#  -----
#  Script préparant les programes pour rejouer (replay) une paramétrisation
#  ou un morceau de paramétriation.
#
#
#  Applicabilité :
#  ---------------
#  Est fait pour rejouer des paramétisation de LMDZ organisées comme
#    des calcul sur des successions de colonnes indépendantes (boucle
#    interne en $klon) de $klev niveaux verticaux.
#  Demande que la paramétrisation répondent aux règles de codage suivantes :
#  1) Les routines de calcul et les routines ou fonctions qu'elles appellent
#     n'ont que deux interfaces : A) les arguments d'entrée
#                                 B) le use d'un unique module
#     Entre autre, les dimensions de la paramétrisation sont passés
#     en argument, ce qui permet une allocation dynamique implicite
#     de toutes les variables.
#  2) le module d'initialisation doit lui même être initialisé par 
#     une unique routine pilotée entièrement par ses arguments.
#  3) Toutes les variables d'interface doivent être déclarées intent in
#     out, ou inout
#  On appelera la paramétriation "param" et l'intialisation "param_ini"
#     mais les noms de fichiers sont en argument dans le script.
#
#
#  Principe :
#  ----------
#  Dans une première simulation, on écrit dans un fichier binaire toutes
#  les variables "intent in/inout" de la routine d'initialisation et de la routine
#  de calcul.
#
#
#  En pratique :
#  -------------
#
#  Le script a comme argument le nom de la routine à traiter, nommée $param
#   Des correpspondances en déduisent :
#   param_ini=wake_ini  # nom de la subroutine d'intialisation
#   inimod= # nom du module contenant $param_ini
#   klon=klon ; klev=klev  # nom des dimensions horiz; vert utilisée
#
#  Le fichier ${paramfile} contenant $param est detecté automatiquement
#  Le script crée 5 fichiers
#  * dump_param1.h          : écriture de l'interface "in" de param (dump_param.bin fort.82)
#  * dump_param2.h          : écriture des sorties de la routines dans phys.nc
#  * call_param_replay : sous programme d'appelle en boucle à la param
#  * dump_ini_module.f90   : écriture de l'interface "in" de param_ini
#  * call_ini_replay.f90    : lecture de l'interface "in" de param_ini
#                dans ${param_ini}_mod.bin.
#  Par ailleurs, un programme replay1d a été ajouté dans phylmd/dyn1d
#        qui appelle call_param_replay
#  Le script ajoute par ailleurs quelques lignes dans ${paramfile} et
#        ${param_ini}.f90
#  replay_clean.sh élimine toutes les lignes ajoutées 
#
#
#  A travailler :
#  --------------
#  * détecter automatiquement le fichier contenant l'intialisation
#  * détecter automatiquement les dimensions
#  * avoir un moyen de vérifier si les variables intent in et out sont
#    bien les bonnes.
#  * Initialisation plus simple de la routine getin_p
#  * Des choix sur la facon de controler l'initialisation et le pb des getin
#
#=============================================================================

nconly=false
where=-before_return
lonlat=

if [ $# = 0 ] ; then $0 -h ; exit ; fi
while (($# > 0))
   do
   case $1 in
     -h|--help) cat <<........fin
           $0 [-nconly] [-ncvars var1,var2,...] [-pre prefix] [location_in_the_code] [-lonlat lon,lat] routine_name
           The prefix will be put on each variable stored in the nc file to avoid duplicate
                variables names
           If -ncvars is not specified, all the variables are output
           The prefix is used to prevent having twice the same name if the same variable is
              output at two locations in the code.
           The -nconly option can be used to equip other routines with nc output only
           location_in_the_code can be : -before_return               (the default valuer)
                                         -after_declarations
                                         -before_line  "line in code"
                                         -after_line   "line in code"
                                         -before_call  "param_name"   (TO BE DONE)
                                         -after_call   "param_name"   (TO BE DONE)
           -lonlat longitude,latitude
........fin
        exit ;;
     -nconly) nconly=true ; shift ;;
     -before_line|-after_line|-before_call|-after_call) where="$1 $2" ; shift ; shift ;;
     -before_return|-after_declarations) where=$1 ; shift ;;
     -pre) prefix=$2 ; shift ; shift ;;
     -ncvars) ncvars="`echo $2 | sed -e 's/,/ /g'`" ; shift ; shift ;;
     -lonlat) lonlat=$2 ; shift ; shift ;;
     *) if (( $# > 1 )) ; then $0 -h ; exit ; fi ; param=$( basename $( basename $1 .f90 ) .F90 ) ; shift
    esac
done
if [ "$param" = "" ] ; then $0 -h ; exit ; fi

#-----------------------------------------------------------------------------
function get_file_names {
#-----------------------------------------------------------------------------
case $param in
   vdif_k|vdif_cd|vdif|my_25|vdif_dq) param_ini=vdif_ini ; inimod=simple_vdif_ini ; klon=ngrid ; klev=nlay ;;
   thermcell_plume_6A|thermcell_env|thermcell_height|thermcell_dry|\
      thermcell_closure|thermcell_height|thermcell_dq|thermcell_flux2|thermcell_down| \
      thermcell_updown_dq|thermcell_dtke) \
      param_ini=thermcell_ini ; inimod=lmdz_thermcell_ini ; klon=ngrid ; klev=nlay ;;
   wpopdynC|wake_popdyn_3|wake|wake2|wake3|pkupper|wake_popdyn_1|wake_popdyn_2|vdif_kcay|ustarhb) param_ini=wake_ini ; inimod=lmdz_wake_ini ; klon=klon ; klev=klev ;;
   surf_wind) param_ini=surf_wind_ini ; inimod=lmdz_surf_wind_ini ; klon=klon ; klev=nsurfwind ;;
   ratqs_main|ratqs_inter|ratqs_oro|ratqs_hetero|ratqs_tke) param_ini=ratqs_ini ; inimod=lmdz_ratqs_ini ; klon=klon ; klev=klev ;;
   lscp|fisrtilp) param_ini=lscp_ini ; inimod=lmdz_lscp_ini ; klon=klon ; klev=klev ;;
   *) echo Cas non prevu ; exit
esac

set -u ; inimod_file=$( ls $inimod.[fF]90 ) ; set +u
replay_comment="replay automatic include"
dump_param_head=dump_replay_${param}_head.h
dump_param_nc=dump_replay_${param}_nc_${prefix}.h
iniinc=dump_replay_ini.h
echo "grep -i \"subro.* ${param}[\ (]\" *.[fF]90 | sed -e 's/ //g' | grep \"${param}(\" | cut -d: -f1"
paramfile=`grep -i "subro.* ${param}[\ (]" *.[fF]90 | sed -e 's/ //g' | grep "${param}(" | cut -d: -f1`

echo ===================================================================================
echo Equiping $param contained in file $paramfile
if [ `echo ${paramfile} | wc -w` != 1 ] ; then echo file $paramfile multiple  ; $0 -h ; exit ; fi

}

#-----------------------------------------------------------------------------
function get_subroutine_arg(){
#-----------------------------------------------------------------------------
   tmp=tmp_get_subroutine_arg$1
   cat $2 | tr '[A-Z]' '[a-z]' > ${tmp}
   #line1=`sed -n -e '/subrou.*'\`echo $1 | tr '[A-Z]' '[a-z]'\`'.*(/=' ${tmp} | head -1 `
   name_min=$( echo $1 | tr '[A-Z]' '[a-z]' )
   line1=`sed -n -e '/subrou.*'${name_min}'[\ (]/=' ${tmp} | head -1 `
   echo LINE1 $line1 > tmpline$1
   line2=`tail -n +$line1 ${tmp} | sed -n -e '/)/=' | head -1`
   tail -n +$line1 ${tmp} | sed -n -e 1,${line2}p
}

#-----------------------------------------------------------------------------
function var_get_dims(){
#-----------------------------------------------------------------------------
    local var=$1
    local line=$( grep dimension input | grep '::.*'$var | grep -w $var | sed -e 's/ //g' )
    local pattern='dimension\s*\(([a-z0-9,+]*)\)'
    if [[ $line =~ $pattern ]] ; then
        echo ${BASH_REMATCH[1]} | sed -e 's/,/ /g'
    fi
}

#-----------------------------------------------------------------------------
function var_dims(){
#-----------------------------------------------------------------------------
    local var=$1
    local dims=$(var_get_dims $var)
    if [[ "$dims" != "" ]] ; then
       local dims_=
       for d in $dims ; do
           if [[ $d = $klon ]] ; then
              dims_="${dims_} 1:$klon"
           else
              dims_="$dims_ :"
           fi
       done
       echo \(${dims_}\) | sed -e 's/( /(/' -e 's/ /,/g'
    fi
}

#-----------------------------------------------------------------------------
function var_recl(){
#-----------------------------------------------------------------------------
    local var=$1
    local dims=$( var_get_dims $var )
    if [[ "$dims" != "" ]] ; then
       local dims_= ; for i in $dims ; do dims_="$dims_ ($i)" ; done
       echo $dims_ | sed -e 's/ /*/'
    else
       echo 1
    fi
}

#-----------------------------------------------------------------------------
function dump_param_open(){
    #-----------------------------------------------------------------------------
    # Opening an direct access file with one record per time-step 
    # Each record has the size and contains the arguments in and inout of the
    # routine
    #-----------------------------------------------------------------------------
    inout=$1 ; shift
    case $inout in
       out) fort=81 ;;
       in) fort=82
    esac
    echo '! <<< dump_param_open'
    echo 'print*,"NOUVEAU REPLAY"'
    for var in $* ; do
        #echo 'rec_length_replay=rec_length_replay+kind('$var')*size(['$var'])'
        echo 'rec_length_replay=rec_length_replay+kind('$var')*'$( var_recl $var )
    done
    cat <<....eod
    open(${fort},file='dump_param_${inout}.bin',form='unformatted',access='direct',recl=rec_length_replay)  ! $replay_comment
....eod
    echo '! dump_param_open >>> '
}

#-----------------------------------------------------------------------------
function extract_subroutine(){
#-----------------------------------------------------------------------------
   # $1 nom de la subroutine
   # $2 nom du fichier
   # input <- routine under treatment with small caps only
   tmp=tmp_extract_subroutine
   ( cpp $2 2>/dev/null ) | tr '[A-Z]' '[a-z]' > ${tmp}
   name_min=`echo $1 | tr '[A-Z]' '[a-z]'`
   line1=`sed -n -e "/subrou.*${name_min}[\ (]/=" ${tmp} | head -1 `
   tail -n +$line1 ${tmp} > ${tmp}2
   line2=`sed -n -e "/[Rr][Ee][Tt][Uu][Rr][Nn]/=" ${tmp}2 | head -1`
   head -$line2 ${tmp}2  > input
   \rm -f ${tmp} ${tmp}2
}

#-----------------------------------------------------------------------------
function echo_use_module(){
#-----------------------------------------------------------------------------
# Regle tacite : l'instruction MODULE commence à la premiere colonne.
#                Existe-t-i une facon de la faire tomber ?
#                En enlevant tous les blanc dans le input sans doute ...
   param_=$1 ; shift
   paramfile_=$1
   if [ ! -f $paramfile_ ] ; then echo plantage which_module ; exit 1 ; fi
   module=`grep '^[mM][oO][dD][uU][lL][eE] .*[a-Z]' $paramfile_ | head -1 | awk ' { print $2 } '`
   if [ "$module" != "" ] ; then
       echo USE $module, ONLY : $param_
   fi
}

#-----------------------------------------------------------------------------
function include_line(){
#-----------------------------------------------------------------------------
   # Including param_dump*.h in the parameterization
   #set -vx
   tmp=tmp_include_line
   line_to_be_included=$1  ; shift
   param_=$1 ; shift
   paramfile_=$1 ; shift
   name_min=`echo $param_ | tr [A-Z] [a-z]`
   line_subroutine=`cat $paramfile_ | tr '[A-Z]' '[a-z]' | sed -n -e "/subrou.*${name_min}.*(/=" | head -1 `
   tail -n +$line_subroutine $paramfile_ > ${tmp} # file starting at the subroutine instruction
   line_return=`sed -n -e "/[Rr][Ee][Tt][Uu][Rr][Nn]/=" ${tmp} | head -1`
   head -$line_return ${tmp} > ${tmp}2               # file containing the routine
   sed -e 's/\!.*$//' ${tmp}2 > ${tmp}3
   cpp ${tmp}2 > ${tmp}3 2>/dev/null
   cat ${tmp}3 | tr '[A-Z]' '[a-z]' > ${tmp}2_cpp   # same after cpp filtering
   last_line_declaration2="`sed -n -e 's/\!.*$//' -e 's/^/ /' -e '/[\ ,]real[\ ,]/p' -e '/[\ ,]integer[\ ,]/p' -e '/[\ ,]logical[\ ,]/p' -e '/[\ ,]character[\ ,]/p' ${tmp}2_cpp | tail -1 | sed -e 's/  / /g' -e 's/ /.*/g'`"
   line_last_declaration=`cat ${tmp}2 | tr '[A-Z]' '[a-z]' | sed -n -e "/$last_line_declaration2/="`
   echo OK0
   if [ "`grep -i 'end.*module' $paramfile_`" = "" ] ; then echo aka ;  line_end_module=`wc -l $paramfile_ | awk ' { print $1 } '` ; else echo akb ; line_end_module=`sed -n -e '/[eE][nN][dD] .*[mM][oO][dD][uU][lL][eE]/=' $paramfile_` ; fi
   echo OK1
   echo $line_end_module
   if [ "$line_last_declaration" = "" ] ; then echo line_last_declaration $line_last_declaration line $last_line_declaration2  ; exit ; fi
   if (( $# > 0 )) ; then
      wtype=`echo $1 | awk ' { print $1 } '`
      case $wtype in
         -after_declarations)      targeted_line=$line_last_declaration ;;
         -before_return)           targeted_line=$line_return ;;
         -before_end_module)       targeted_line=$line_end_module ;;
         -before_line|-after_line) linestr=`echo $1 | sed -e "s/$wtype //"` ; targeted_line=`sed -n -e "/$linestr/=" ${tmp}2` ;;
         *)                  echo Cas non prevu 0 where=$where in include_file
      esac
      case $wtype in
         -after_declarations|-after_line)  line0=$(( $line_subroutine - 1 )) ;;
         -before_return|-before_line)      line0=$(( $line_subroutine - 2 )) ;;
         -before_end_module)               line0=-1 ;;
         *)                  echo Cas non prevu 1 where=$where in include_file
      esac
      echo Including line $line0 + $targeted_line in $paramfile_ the line : $line_to_be_included
      linebefore_include=$(( $line0 + $targeted_line ))
     sed -i'' -e $linebefore_include"s/$/\n $line_to_be_included \!  $replay_comment/" $paramfile_ 
   fi
}

#-----------------------------------------------------------------------------
function block_Replay0() {
#-----------------------------------------------------------------------------
condition=$1 ; shift
suf1=$1 ; shift
suf2=$1 ; shift
if [ $# -gt 0 ] ; then
   vars=$*
   echo '   if ('$condition') then'
   for var in $vars ; do echo '      '$var$suf1=$var$suf2 ; done
   echo '   endif'
fi
}

#-----------------------------------------------------------------------------
function iotd_calls(){
#-----------------------------------------------------------------------------
    klev_=$1 ; shift
    pre=$1 ; shift
    if (( $# >> 0 )) ; then
       vars=$*
       echo "if ( abs(gr_index_)>0 ) then"
       for var in $vars ; do
          local vardim=$( var_dims $var )
          echo "call iotd_ecrit_seq('"$pre$var"',$klev_,'"$pre$var in $param"',' ',"$var$vardim")"
       done
       echo endif
    fi
}
         
#-----------------------------------------------------------------------------
function b_among_a() {
#-----------------------------------------------------------------------------
   a="$1"
   b="$2"
   o=""
   for v in $a ; do
       for vv in $b ; do
           if [ "$v" = "$vv" ] ; then o="$o $v" ;  fi
       done
   done
   echo $o
}

#-----------------------------------------------------------------------------
function get_all_inout_and_in_variables {
#-----------------------------------------------------------------------------

varin0=`grep inten.*.in input | sed -e 's/\!.*$//' | cut -d: -f3 | sed -e 's/,/ /g'`
varinout0=`grep inten.*.inout input | sed -e 's/\!.*$//' | cut -d: -f3 | sed -e 's/,/ /g'`
echo varin0 $varin0
varin_rec= ; for v in $varin0 ; do varin_rec="$varin_rec $v$( var_dims $v)" ; done
varin=`echo $varin_rec | sed -e 's/ /,/g' -e "s/,,,/,/g" -e "s/,,/,/g"`
#echo $varin $varin
nvar0D=0 ; nvar1D=0 ; nvar2D=0
}

#-----------------------------------------------------------------------------
function get_vars {
#-----------------------------------------------------------------------------

# Extracting list of array variables, either 1D or 2D, and depending
# on their status : in, out, inout

output=full # Attention, l'option full ne marche pas a cause de tableaux locaux undef
case $output in
   light) str_='real.*intent' ;;
   full) str_='real'
esac

str_=real
case $1 in
   in|inout|out) filtre_='grep intent('$1')' ;;
   local) filtre_='sed -e /intent/d' ;;
   all) filtre_='grep '$str_ ;; # Pas très joli
   *) echo Pffff ; exit 1
esac

if [ $2 = 1D ] ; then
    grep $str_ input | sed -e 's/ //g' | $filtre_ | grep $klon | sed -e 's/!.*$//' -e /$klev/d | cut -d: -f3 | sed -e 's/,/ /g'
else
    grep $str_ input | sed -e 's/ //g' | $filtre_ | grep $klon | grep $klev | cut -d: -f3 | sed -e 's/!.*$//' -e 's/,/ /g'
fi

}

#-----------------------------------------------------------------------------
function get_variable_lists {
#-----------------------------------------------------------------------------
var_1D_in=$( get_vars in 1D )
var_2D_in=$( get_vars in 2D )

var_1D_inout=$( get_vars inout 1D )
var_2D_inout=$( get_vars inout 2D )

var_1D=$( get_vars all 1D )
var_2D=$( get_vars all 2D )

var_1D_local=$( get_vars local 1D )
var_2D_local=$( get_vars local 2D )

if [ "$ncvars" != "" ] ; then
   var_1D=$( b_among_a "$var_1D" "$ncvars" )
   var_2D=$( b_among_a "$var_2D" "$ncvars" )
fi

echo Variables in and inout : $varin0
echo 1D variables "(all)" : $var_1D
echo 2D variables "(all)" : $var_2D
echo 1D variables "intent(in)" : $var_1D_in
echo 2D variables "intent(in)" : $var_2D_in
echo 1D variables "intent(inout)" : $var_1D_inout
echo 2D variables "intent(inout)" : $var_2D_inout
echo local 1D variables : $var_1D_local
echo local 2D variables : $var_2D_local
}

#-----------------------------------------------------------------------------
function clean_other_routines {
#-----------------------------------------------------------------------------
# On nettoye les inclusions précédente dans les fichiers .f90
if [ $nconly = false ] ; then
   for file in `grep "$replay_comment" *.[fF]90 2> /dev/null | cut -d: -f1` ; do
      sed -i"" -e "/$replay_comment/d" $file
   done
   #line=`sed -n -e "/CALL "$param_ini"/=" physiq_mod.F90 | head -1`
   line=`sed -n -e "/CALL wake_ini/=" physiq_mod.F90 | head -1`
   if [[ "$lonlat" = "" ]] ; then
        if [[ $klev == klev || $klev == nlay ]] ; then
            klev_=klev
        else
            klev_=$klev
        fi
        pattern="CALL iophys_ini(pdtphys,$klev_)"
   else
        pattern='call iotd_ini("phys.nc",1,1,klev,'$lonlat',presnivs,1,1,1,0.,pdtphys,calend)'
   fi

   sed -i"" -e "${line}s/^/   $pattern ! $replay_comment  ! $replay_comment\n/" physiq_mod.F90
fi
}


#-----------------------------------------------------------------------------
function create_call_param_replay {
#-----------------------------------------------------------------------------

cat > call_param_replay.f90 <<eod
subroutine call_param_replay($klon,$klev)
use IOIPSL, only : getin
use netcdf
$( echo_use_module $param  $paramfile )
IMPLICIT NONE
integer :: ifin,irec,it,rec_length_replay=0,replay_irec0=1,replay_nt=1000
integer :: status,ncid,varid
real*4,dimension($klon,$klev) :: v2d
real*4,dimension($klon) :: v1d
eod
grep 'intent.*::' input | sed -e 's/ //g' -e 's/,intent(.*[nt])//'>> call_param_replay.f90
# duplicating declaration for inout variables

for var in $varinout0 ; do
    sed -e 's/::/ :: /' -e 's/,/ , /g' -e 's/$/ /' input | grep 'intent.*inout.*::.* '$var' ' | sed -e 's/ //g' -e 's/,intent(.*[nt])//' | sed -e 's/::.*$/, allocatable, save :: '$var'_Replay0/' | sed -e 's/'$klon'/:/' -e 's/'${klev}'+1/:/' -e 's/'${klev}'/:/' >> call_param_replay.f90
done
# Initalisation, shared with dump_param1.sh
dump_param_open "in" $varin0 >> call_param_replay.f90
for var in $varinout0 ; do
    sed -e 's/::/ :: /' -e 's/,/ , /g' -e 's/$/ /' input | grep 'intent.*inout.*::.* '$var' ' | sed -e 's/intent(.*t)//' -e 's/^.*(/allocate('$var'_Replay0(/' -e 's/).*$/))/' >> call_param_replay.f90
done

cat >> call_param_replay.f90 <<eod
call getin('replay_nt',replay_nt)
call getin('replay_irec0',replay_irec0)
do it=1,replay_nt
   if (replay_irec0>=0) then
       irec=replay_irec0+it-1
   else
       irec=-replay_irec0
   endif
   print*,'Time step',it,', reading record',irec,'in dump_param.bin'
   read(82,rec=irec,iostat=ifin) $varin
   if (.NOT. ifin == 0 ) stop "Fin du fichier fort.82"
   status = nf90_open("replay_in.nc", nf90_nowrite, ncid)
   if (status == nf90_noerr) then
eod

for var in $var_2D_in $var_2D_inout ; do
   echo "status=nf90_inq_varid(ncid,\"$var\",varid)" >> call_param_replay.f90
   echo "status=nf90_get_var(ncid,varid,v2d,start=(/1,1,1,it/), count=(/1,1,$klev,it/))" >> call_param_replay.f90
   echo "$var(:,1:$klev)=v2d(:,1:$klev)"  >> call_param_replay.f90
done

for var in $var_1D_in $var_1D_inout ; do
   echo "status=nf90_inq_varid(ncid,\"$var\",varid)" >> call_param_replay.f90
   echo "status=nf90_get_var(ncid, varid, v1d, start=(/1,1,it/), count=(/1,1,it/))" >> call_param_replay.f90
   echo "$var=v1d"  >> call_param_replay.f90
done

block_Replay0 "it == 1"          _Replay0   ""       $varinout0 >> call_param_replay.f90
block_Replay0 "replay_irec0 < 0" ""         _Replay0 $varinout0 >> call_param_replay.f90
get_subroutine_arg $param $paramfile | sed -e 's/subroutine/   call/' >> call_param_replay.f90
block_Replay0 "replay_irec0 < 0" _Replay0   ""       $varinout0 >> call_param_replay.f90

cat >> call_param_replay.f90 <<eod
   end if
enddo
return
end subroutine call_param_replay
eod
}

#-----------------------------------------------------------------------------
function create_dump_param_head {
#-----------------------------------------------------------------------------
\rm $dump_param_head
cat> $dump_param_head <<eod
logical, save :: first_replay=.true.
integer, save :: rec_length_replay=0,irec=0,gr_index_=-1
!\$OMP THREADPRIVATE(first_replay,rec_length_replay,irec,gr_index_)
integer, external :: grid_index
eod
if [ "$lonlat" != "" ] ; then echo "if (first_replay) gr_index_=grid_index($lonlat)" >> $dump_param_head ; fi
echo "if ($klon==1) gr_index_=1" >> $dump_param_head
echo "if (abs(gr_index_)>0) then" >> $dump_param_head
echo "if (first_replay) then" >> $dump_param_head
dump_param_open out $varin0 >> $dump_param_head
cat>> $dump_param_head <<eod
endif
irec=irec+1
write(81,rec=irec) $varin
endif
first_replay=.false.
eod

#iotd_calls 1     in_${prefix} $var_1D_inout
iotd_calls 1     in_${prefix} $var_1D_inout >> $dump_param_head
iotd_calls $klev in_${prefix} $var_2D_inout >> $dump_param_head
if [ "`grep $dump_param_head $paramfile`" = "" ] ; then
   # Not changing $dump_param_head if it is already included in the file
   # To allow adding new nc outputs in a routine equiped for replay
   for var in $var_1D_local $var_2D_local ; do echo $var=0. >> $dump_param_head ; done
   include_line "include \"$dump_param_head\"" $param $paramfile -after_declarations
fi
}

#-----------------------------------------------------------------------------
function create_dump_param_nc {
#-----------------------------------------------------------------------------

\rm $dump_param_nc
iotd_calls 1     "${prefix}" $var_1D >> $dump_param_nc
iotd_calls $klev "${prefix}" $var_2D >> $dump_param_nc
include_line "include \"$dump_param_nc\"" $param $paramfile "$where"

if [[ "$lonlat" != "" ]] ; then
    for file in $dump_param_head $dump_param_nc ; do sed -i -e "s/1:$klon/gr_index_/g" -e '/rec_l/s/\*('$klon')//g'  $file ; done
    sed -i -e "/(81/s/,$klon/,1/" $dump_param_head
fi

}

#-----------------------------------------------------------------------------
function create_call_ini_replay {
#-----------------------------------------------------------------------------
varinmod=`grep -i 'intent.in' $inimod_file | sed -e 's/\!.*$//' | cut -d: -f3 | sed -e 's/,/ /g'`
varinmodv=`echo $varinmod | sed -e 's/ /,/g'`
cat > $iniinc <<eod...............................................
   open(90,file='$inimod.bin',form='unformatted')
   write(90) $varinmodv
   close(90)
eod...............................................
for var_ in $varinmod ; do echo "print*,'Interface $param_ini $var_',$var_" >> $iniinc ; done
include_line "include \"$iniinc\"" $param_ini $inimod_file  -before_return

cat > call_ini_replay.f90 <<eod............................................
    subroutine call_ini_replay
    use $inimod
    IMPLICIT NONE
eod............................................
grep -i intent.in $inimod_file  |  tr '[A-Z]' '[a-z]' | sed -e 's/,.*intent.i.*)//' >> call_ini_replay.f90
cat >> call_ini_replay.f90 <<eod...........................................
    open(90,file='$inimod.bin',form='unformatted')
    read(90) $varinmodv
    close(90)
eod...........................................
get_subroutine_arg $param_ini $inimod_file | sed -e 's/subroutine/call/' >> call_ini_replay.f90
cat >> call_ini_replay.f90 <<eod...........................................
    return
    end subroutine call_ini_replay
eod...........................................
}


#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Starting here
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------

get_file_names

if [ $nconly = false ] ; then
   clean_other_routines
fi

# Extracting/formating the target subroutine in "input" file
extract_subroutine $param $paramfile

# Getting all in and inout variables from "input"
get_all_inout_and_in_variables

# Getting lists of 1D and 2D arrays selecting status and 1D and 2D
get_variable_lists

# Specific of routines to be replayed
if [ $nconly = false ] ; then
   create_call_param_replay
   create_dump_param_head
   if [ $param_ini != None ] ; then
      create_call_ini_replay
   fi
fi

# Netcdf outputs in all cases
create_dump_param_nc

# Some cleaning
\rm -f input tmp_get* tmp_include* tmpline*
