#! /bin/tcsh -f
# Time-stamp: <2017-11-13 19:17:13 sander>
# Author: Rolf Sander, Max-Planck-Institute, Mainz, Germany
# xcaaba = eXecute CAABA

##############################################################################

# status remains <> 0 if any error occurs:
set anyerror

# define hline string:
set hline = `printf '%74s' | tr ' ' -`

# what is the current operating system?
set system = "`uname`"
if ( "$HOST" =~ hydra.* ) set system = hydra
# now system = hydra, Linux, or OSF1

# default is not to start xmecca:
unset xmecca

# ensure that $HOME/tmp directory exists:
if ( ! -d $HOME/tmp ) then
  mkdir $HOME/tmp
endif

##############################################################################

setenv basedir "`pwd`"

if ( "$1" == "" ) then
  echo;echo "You can create a new chemical mechanism with xmecca now."
  echo "This is necessary, if:"
  echo "- you have changed any of the *.eqn, *.spc, or *.kpp files"
  echo "- you have changed your *.bat batch file"
  echo "Start xmecca? [y|n|q|default=n]"
  set inputstring = "$<"
  if ( "$inputstring" == "q" ) exit
  if ( "$inputstring" == "y" ) then
    set xmecca
  endif
else
  set xmecca
endif

if (! ${?xmecca}) then
  # check that kpp-generated f90 files are newer than kpp files:
  # get time (seconds since the epoch) of kpp files:
  @ gaseqntime = -M mecca/gas.eqn
  @ gasspctime = -M mecca/gas.spc
  @ aqueouseqntime = -M mecca/aqueous.eqn
  @ aqueousspctime = -M mecca/aqueous.spc
  @ kpptime    = -M mecca/messy_mecca_kpp.kpp
  @ f90time    = -M messy_mecca_kpp.f90
  unset xmeccayes
  if ($gaseqntime>$f90time) then
    echo "WARNING: gas.eqn is newer than kpp-generated f90 files"
    set xmeccayes
  endif
  if ($gasspctime>$f90time) then
    echo "WARNING: gas.spc is newer than kpp-generated f90 files"
    set xmeccayes
  endif
  if ($aqueouseqntime>$f90time) then
    echo "WARNING: aqueous.eqn is newer than kpp-generated f90 files"
    set xmeccayes
  endif
  if ($aqueousspctime>$f90time) then
    echo "WARNING: aqueous.spc is newer than kpp-generated f90 files"
    set xmeccayes
  endif
  if ($kpptime>$f90time) then
    echo "WARNING: messy_mecca_kpp.kpp is newer than kpp-generated f90 files"
    set xmeccayes
  endif
  if (${?xmeccayes}) then
    echo "It is strongly suggested to create new f90 files via xmecca."
    echo "Start xmecca? [y|n|q|default=y]"
    set inputstring = "$<"
    if ( "$inputstring" == "q" ) exit
    if ( "$inputstring" != "n" ) then
      set xmecca
    endif
  endif
endif

if (${?xmecca}) then
  echo;echo "starting xmecca."
  (cd mecca ; ./xmecca $1)
  set exitstatus = "$status"
  if ( $exitstatus == '0' ) then
    echo;echo "xmecca has finished successfully"
  else
    echo
    echo "Stopping xcaaba here because xmecca returned exit status: $exitstatus"
    exit 1
  endif
  echo;echo "$hline"
endif

##############################################################################

set s_string = "Start from scratch"
set c_string = "Compile"
set r_string = "Run existing executable"

echo;echo "Choose an option [default=c]:"
echo "s = $s_string"
echo "c = $c_string"
if (! ${?xmecca}) then
echo "r = $r_string"
endif
echo "h = Help"
echo "q = Quit"
set inputstring = "$<"
if ( "$inputstring" == "q" ) exit
switch ("$inputstring")
case "r":
  if (${?xmecca}) then
    echo "ERROR: You must choose option c"
    echo "       after creating a new chemical mechanism with xmecca"
    exit 1
  else
    set option = "r"
    echo "You have chosen: r = $r_string"
  endif
  breaksw
case "h":
  echo ""
  echo "s = $s_string."
  echo "    This will first remove existing object files (*.o and"
  echo "    *.mod) with 'gmake clean' and then compile the code."
  echo "c = $c_string."
  echo "    Compile recently changed files with 'gmake'."
  echo "r = $r_string."
  echo "    Run already existing executable."
  exit
case "s":
    set option = "s"
    echo "You have chosen: s = $s_string"
  breaksw
default:
  set option = "c"
  echo "You have chosen: c = $c_string"
  breaksw
endsw
echo;echo "$hline"

##############################################################################

if ( "$option" == "s" ) then

  echo "gmake clean"
  gmake clean

endif

##############################################################################

if (( "$option" == "c" ) || ( "$option" == "s" )) then

  gmake validate
  set exitstatus = "$status"
  echo "exit status from 'gmake validate' is: $exitstatus"
  if ( $exitstatus != '0' ) exit
  echo;echo "$hline"

  echo "gmake (writing output to gmake.log)"
  # the option "-j" allows simultaneous jobs:
  gmake -j |& tee gmake.log
  # activate next line (instead of the one above) to show basic debugging info:
  #gmake -j --debug=basic |& tee gmake.log
  set exitstatus = "$status"
  echo "exit status from 'gmake' is: $exitstatus"
  if ( $exitstatus != '0' ) exit 1
  echo;echo "$hline"

endif

##############################################################################

# namelist selection, part 1:

set defaultnml = `ls -l caaba.nml | sed 's/.*\///g'`
echo;echo "Choose a namelist file from the nml/ directory:"
echo "(or type 'm' for multirun)"
set inn = "0"
cd nml
set allfiles = *.nml
cd -
foreach i ($allfiles) # list all possibilities
  @ inn=$inn + 1
  printf "%2d) %s\n" $inn $allfiles[$inn]
end
echo " m) multirun (namelists created by multirun.tcsh)"
echo " v) volcano-multirun"
echo " q) quit"
echo "The default is to use the same file as last time:"
echo "default=$defaultnml"
set inputstring = "$<"
if ( "$inputstring" == "q" ) exit 1

##############################################################################

# multirun:

if ( "$inputstring" == "m" ) then
  set inputdir = "$basedir/multirun/input"
  echo;echo "Choose an input file from the directory"
  echo "$inputdir"
  echo "[q|number|default=loop over all files]"
  set inn = "0"
  set allfiles = $inputdir/*.nc
  foreach i ($allfiles) # list all possibilities
    @ inn=$inn + 1
    echo "$inn) $allfiles[$inn]:t"
  end
  set inputstring = "$<"
  if ( "$inputstring" == "q" ) exit 1
  if(($inputstring <= $#allfiles) && ($inputstring >= 1)) then
    set inputfile = $allfiles[$inputstring]
    ./multirun/multirun.tcsh "$inputfile"
  else
    foreach inputfile ($inputdir/*.nc)
      ./multirun/multirun.tcsh "$inputfile"
    end
  endif
  exit
endif

##############################################################################

# volcano-multirun:

if ( "$inputstring" == "v" ) then
  ./multirun-volcano/multirun-volcano.py
  exit
endif

##############################################################################

# namelist selection, part 2:

if(($inputstring <= $#allfiles) && ($inputstring >= 1)) then
  set nmlfile = $allfiles[$inputstring]
  ln -fs nml/$nmlfile caaba.nml
else
  set nmlfile = $defaultnml
endif
echo "The active contents of the selected"
echo "namelist ($nmlfile) is:"
sed -ne '/^&CAABA[ ]*$/,/^\//p' caaba.nml | grep -v "^!" | grep -v '^ *$'
echo;echo "The active contents of mecca.nml is:"
sed -ne '/^&CTRL/,/^\//p' mecca.nml | grep -v "^!" | grep -v '^ *$'
echo;echo "$hline"
echo;echo "Before you continue, ensure that the namelist is consistent"
echo "with the selected chemistry mechanism\!"

##############################################################################

# check if MECCA code was prepared for Monte-Carlo simulations:
set test = `grep -i "REQ_MCFCT *= *\.TRUE\." messy_mecca_kpp*.f90`
if ( "$test" != "" ) then
  echo;echo "Run Monte-Carlo simulations with CAABA? [y|n|q|default=y]"
  set inputstring = "$<"
  if ( "$inputstring" == "q" ) exit
  if ( "$inputstring" != "n" ) then
    echo;echo "Starting montecarlo.tcsh..."
    ./montecarlo/montecarlo.tcsh
    exit
  endif
endif

##############################################################################

echo;echo "Run CAABA boxmodel with MECCA chemistry?"
echo "y = Yes (default)"
echo "n = No"
echo "q = Quit"

set inputstring = "$<"
echo "$hline"
if ( "$inputstring" == "q" ) exit
if ( "$inputstring" != "n" ) then
  set date_now = `date +"%Y-%m-%d"`
  set time_now = `date +"%H:%M:%S"`
  echo " xcaaba was run on $date_now at $time_now by $user on machine $HOST" > caaba.log
  # remove old files, if any:
  rm caaba_*.nc >& /dev/null
  echo "Starting CAABA. Please wait..." ; echo
  if ( "$HOST" =~ grand ) then
    # on grand, the queueing system must be used:
    set qsub_tmp = `qsub /soft/bin/qexec.tcsh ./caaba.exe`
    set jobnum = $qsub_tmp[3]
    echo "CAABA is now in the queueing system with jobnumber $jobnum ..."
    set done = no
    while ($done == no)
      set test = `qstat | grep $jobnum`
      if ( "$test" != "" ) then
        sleep 20s
      else
        set done = yes
      endif
    end
    cat qexec.tcsh.$jobnum.log >> caaba.log
  else
    # run the CAABA/MECCA box model:
    # unbuffer needs expect, see: http://expect.nist.gov/
    #if ( ( -e `which unbuffer` ) && ( -e `which expect` ) ) then
      #unbuffer \time -p ./caaba.exe |& tee caaba.log
    #else
      \time -p ./caaba.exe |& tee -a caaba.log
    #endif
  endif
  set exitstatus = `cat status.log`
  if ( "$exitstatus" == "0" ) then
    echo;echo "caaba.exe has finished successfully"
  else
    echo;echo "ERROR: exit status from 'caaba.exe' is: $exitstatus"
    exit 1
  endif
  echo "Log output is now available in ./caaba.log"
endif

##############################################################################

# check if the necessary netcdf tools exist:
if ( ( -e `which ncks` ) && ( -e `which ncdump` ) ) then
  # check if there are any reaction rates RR* in caaba_mecca.nc:
  set tmpfile = tmp_rr.txt
  ncdump -h caaba_mecca.nc | grep "float RR" > $tmpfile
  if ( -s $tmpfile != 0 ) then
    echo
    echo "Splitting caaba_mecca.nc into species and reactions with ncks..."
    mv caaba_mecca.nc caaba_mecca-ori.nc
    # put all species (i.e. all variables except for RR*) into caaba_mecca.nc:
    ncks -x -v "RR.*" caaba_mecca-ori.nc caaba_mecca.nc
    # put all RR* variables into caaba_mecca_rr.nc:
    ncks    -v "RR.*" caaba_mecca-ori.nc caaba_mecca_rr.nc
    rm caaba_mecca-ori.nc
  endif
  rm $tmpfile
else
  echo "WARNING: ncks and/or ncdump are not available, caaba_mecca.nc"
  echo "         cannot be split into species and reactions."
endif

##############################################################################

set defaultoutputdir = "output/$date_now-$time_now"
echo;echo "Save the output and model code?"
echo "Choose an option or type a directory name:"
echo "y (default) = yes, save in $defaultoutputdir"
echo "n           = no (output stays in current directory)"
echo "q           = quit"
echo "<dirname>   = save in output/<dirname>"
set inputstring = "$<"
switch ("$inputstring")
case "":
case "y":
  set outputdir = "$defaultoutputdir"
  breaksw
case "n":
  unset outputdir
  breaksw
case "q":
  exit
default:
  # all characters okay?
  set myoutputdir = `echo "$inputstring" | sed 's/[^-A-Za-z0-9:_+=.]//g'`
  if ("$inputstring" != "$myoutputdir") then
    echo "Unsuitable characters (e.g., from pressing arrow keys) have been"
    echo "removed from the name of the output directory. The new name is:"
    echo "$myoutputdir"
  endif
  set outputdir = "output/$myoutputdir"
  # is this a new directory?
  if ( -d $outputdir ) then
    echo "Directory $outputdir already exists."
    echo "Using default directory instead."
    set outputdir = "$defaultoutputdir"
  endif
  # confirmation:
  echo "Name of output directory = $outputdir"
  echo "Confirm to save output now [y|n|q, default=y]"
  set inputstring2 = "$<"
  switch ("$inputstring2")
  case "n":
    unset outputdir
    breaksw
  case "q":
    exit
  endsw
endsw
if ($?outputdir) then
  echo "Creating zip file of caaba model code. Please wait..."
  mkdir $outputdir
  gmake zip >> caaba.log
  mv `basename $PWD`.zip $outputdir
  cp -p caaba.log *.nc *.dat $outputdir
  echo "Model code and output have been saved to ${outputdir}:"
  ls -la $outputdir
else
  echo "Model code and output have not been saved."
endif

echo;echo "The results can be plotted with:"
echo "  cd plot"
echo "  ./caabaplot.py"

##############################################################################

echo;echo "$hline"
echo "                             xcaaba has finished"
echo "$hline" ; echo

##############################################################################

exit
