#!/bin/bash

#########################################################################
# ------   ELK_TEST  ---- ELK_TEST  ---- ELK_TEST  ---- ELK_TEST  ----  #
#                                                                       #
# Shell script to generate a set of test files using a new version      #
# of the MCTDH program, and compare the files to a standard comparison  #
# set                                                                   #
#                                                                       #
# testcode: name of code to be tested (1st argument)                    #
# auswcode: name of auswert code to be used                             #
# comppath: path to directory containing the comparison set of files.   #
# ntest: number of test input files test1.inp .... test$ntest.inp       #
#                                                                       #
# 4/98  GW                                                              #
#########################################################################



####################################################################
#############--------  SET DEFAULTS HERE  ---------------###########
####################################################################
ver=$MCTDH_VERSION                                                 #
if [ -f  /home/mctdh/elk_test_path ] ; then                        #
   comppath=`head -n 1 /home/mctdh/elk_test_path | cut -d' ' -f1`  #
   comppath=$comppath/                                             #
elif [ -n "$MCTDH_ELK" ] ; then                                    #
   comppath=$MCTDH_ELK/                                            #
else                                                               #
   comppath="$MCTDH_DIR/elk_comp/$MCTDH_PLATFORM"                  #
fi                                                                 #
inppath=$MCTDH_DIR/elk_inputs                                      #
ovlcode=overlap$ver                                                #
compcode=compare$ver                                               #
####################################################################

minus40='----------------------------------------'
star40='****************************************'
etst='ELK_TEST'
blnk='        '
args=$*

#-----------------------------------------------------------------------
# FUNCTION  helpf. Print help information.
#-----------------------------------------------------------------------
helpf() {
    ovlcodename=$ovlcode
    compcodename=$compcode
    if [ -n "${ovlcode##*/*}"  ] ; then ovlcodename=`which $ovlcode`   ; fi
    if [ -n "${compcode##*/*}" ] ; then compcodename=`which $compcode` ; fi

    echo ' '
    echo "$minus40$minus40"
    echo 'Purpose: Test of the MCTDH program'
    echo 'Usage: elk_test [-h -c compname -o overlap -t compare -i inppath'
    echo '       -n number -r -b num -e num -m mpinum -p pthreads] progname '
    echo '   -h:  Print this help text.'
    echo '   -c:  Use "compname" as comparison directory.'
    echo '        If "compname" ends with a slash, $MCTDH_PLATFORM'\
                  'will be appended.'
    echo '   -o:  Use "overlap" program for overlaps.'
    echo '   -t:  Use "compare" program for tests.'
    echo '   -i:  Use test?.inp files from "inppath".'
    echo '        If inppath=c, i.e. "-i c", comppath is used as inppath.'
    echo '   -q:  Re-do the compare-checks but do not re-do tests.'
    echo '   -r:  Re-do tests that failed in a previous elk_test-run.'
    echo '   -s:  Skip the test with the number that follows -s.'
    echo '   -n:  Do tests only for the number(s) that follow -n.'
    echo "        Quote the argument of -n if it contains blanks,"
    echo "        e.g.:  -n 7   or   -n '3 7 21' "
    echo "        With option -n elk_test will run the required tests"
    echo "        regardless whether they already exist or not."
    echo '   -b:  Begin the test with the number following -b.'
    echo '   -e:  End the test with the number following -e.'
    echo '   -C:  Perform only the comparison step for a single test.'
    echo '        The number of the test must follow the -C option. '
    echo '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'
    echo '!  -m:  Specify the number of MPI processes for the elk-test.!'
    echo '!  -p:  Specify the number of POSIX threads for the elk-test.!'
    echo '!  If parallel code is tested the appropriate options must be!'
    echo '!  used. Further a comparison set must be available for the  !'
    echo '!  chosen number of POSIX-threads and MPI processes. Even if !'
    echo '!  the appropriate comparison set is used numerical          !'
    echo '!  differences can occur.                                    !'
    echo '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'
    echo ' '
    echo ' Default overlap    : ' $ovlcodename
    echo ' Default compare    : ' $compcodename
    echo ' Default comparison : ' $comppath
    echo ' Default tests      : ' $inppath
    echo "$minus40$minus40"
    echo ' '
    exit
}


if [ -z "$MCTDH_DIR" ] ; then
   echo $MCTDH_DIR
   ierr=1
fi
if [ -z "$MCTDH_VERSION" ] ; then
   echo $MCTDH_VERSION
   ierr=1
fi
if [ "$ierr" = 1 ] ; then
   echo ' '
   echo 'Check environment variables. '
   echo '$MCTDH_DIR is root directory of MCTDH package installation '
   echo '$MCTDH_VERSION is version of MCTDH package '
   echo ' '
   exit
fi

start=1
stop=49
pthreads=0
mpipro=0

while getopts ":hc:o:t:i:qrs:n:b:e:C:m:p:" opt; do
    case $opt in
    h  )  helpf ;;
    t  )  compcode=$OPTARG  ;;
    o  )  ovlcode=$OPTARG   ;;
    c  )  comppath=$OPTARG  ;;
    i  )  inppath=$OPTARG  ;;
    q  )  query=1  ;;
    r  )  redo=1  ;;
    s  )  skip=$OPTARG  ;;
    n  )  numbers=$OPTARG   ;;
    m  )  mpipro=$OPTARG   ;;
    p  )  pthreads=$OPTARG   ;;
    b  )  start=$OPTARG   ;;
    e  )  stop=$OPTARG   ;;
    C  )  cmp=$OPTARG ; if [ $cmp -gt 0 ] ; then cmp1=1 ; fi 2>/dev/null
          if [ ! "$cmp1" = 1 ] ; then
            echo '#### The number of a test must follow -C ####'
            exit ; fi ;;
    \? )  echo ' Unkown option!'
          helpf ;;
  esac
done
shift $(($OPTIND - 1))

testcode="$1"
testcodename=$testcode
if [ $mpipro -ge 1 ] ; then
   rm -rf $MCTDH_DIR/bin/mpimctdh
   echo '#!/bin/bash' >> mpimctdh
   echo "mpirun -np $mpipro $MCTDH_DIR/bin/$MCTDH_PLATFORM/$1 \$1" >> mpimctdh
   chmod u+x mpimctdh
   mv mpimctdh $MCTDH_DIR/bin/
   testcode=mpimctdh
fi
ovlcodename=$ovlcode
compcodename=$compcode
if [ -n "${testcode##*/*}" ] ; then testcodename=`which $testcode` ; fi
if [ -n "${ovlcode##*/*}"  ] ; then ovlcodename=`which $ovlcode`   ; fi
if [ -n "${compcode##*/*}" ] ; then compcodename=`which $compcode` ; fi

if [ -z "$testcode" ] && [ -z "$cmp" ] ; then
  echo ' '
  echo '#####  No program (argument) specified for test generation !  #####'
  echo ' '
  helpf
fi

# Changing comppath, if debug-version is run and debug-comp-dir exists.
comppath1=${comppath%/*}
mctdhplatf=${comppath##*/}
if [ -z "$mctdhplatf" ]; then mctdhplatf=$MCTDH_PLATFORM ; fi
if [ -z "${testcode%%*d}" ]; then
   if [ -d ${comppath1}d/$mctdhplatf ]; then
      comppath=${comppath1}d/$mctdhplatf
   else
      comppath=${comppath1}/$mctdhplatf
   fi
elif [ -z "${testcode%%*D}" ]; then
   if [ -d ${comppath1}D/$mctdhplatf ]; then
      comppath=${comppath1}D/$mctdhplatf
   elif [ -d ${comppath1}d/$mctdhplatf ]; then
      comppath=${comppath1}d/$mctdhplatf
   else
      comppath=${comppath1}/$mctdhplatf
   fi
else
   comppath=${comppath1}/$mctdhplatf
fi

if [ ! -d $comppath ] ; then
   echo "The comparison data directory $comppath does not exist!"
   echo "Use the -c option to specify a path to a comparison data set."
   exit
fi
parallel=`expr $mpipro + $pthreads`
if [ $parallel -gt 0 ] ; then
   parpath=$comppath/"mpi"$mpipro"pth"$pthreads"/"
   if [ -d $parpath ] ; then
      comppath=$parpath
   else
      echo $star40$star40
      echo '*Directory '$parpath 'does not exist'
      echo '*use '$comppath 'instead.*'
      echo $star40$star40
   fi
fi


# Making comppath absolute and check that $comppath contains elk-data.
here=`pwd`
cd $comppath
comppath=`pwd`
inputs=`ls ch3i*.inp 2>/dev/null | tr '\n' ' ' `
sinput=`echo $inputs | cut -c 1-34 | tr -s ' ' `
if [ "$sinput" != "ch3i01.inp ch3i03.inp ch3i03_1.inp" ] ; then
    if [ -d $comppath/$MCTDH_PLATFORM ] ; then
	comppath=$comppath/$MCTDH_PLATFORM
	cd $comppath
    fi
fi


inputs=0
for i in ch3i*.inp; do
  test -f "$i" && inputs=$(($inputs+1))
done
if [ "$inputs" -ne 3 ] ; then
    echo "$comppath does not seem to contain elk comparison data."
    echo "This is the contents of $comppath"
    ls
    echo "Do you want to continue? (y/n)"
    read answ
    if [ "$answ" != "y" ] ; then exit ; fi
fi
cd $here

# Single comparison
if [ -n "$cmp" ] ; then
   i=$cmp
   cd test$i
   $ovlcode -w $comppath/test$i/psi || exit 1
   cd ..
   echo " "                      >> summary
   echo " ++++ COMPARE ONLY ++++">> summary
   echo " "                      >> results
   echo " ++++ COMPARE ONLY ++++">> results
   echo "------- test$i -------" >> results
   $compcode test$i $comppath/test$i || exit 1
   tail -n 1 summary
   echo ' '
   exit
fi

# Checking that the output directory is empty
if [ -z "$redo" ] && [ -z "$query" ] && [ -z "$numbers" ] ; then
   unset inputs
   inputs=`ls * 2> /dev/null `
   if [ -n "$inputs" ] ; then
      echo "The output directory $here is not empty!"
      echo "This is the contents of $here"
      ls
      echo ' '
      echo 'y=continue anyway, n=exit, r=rm -rf *'
      echo "Type (y|n|r)"
      read answ
      if [ "$answ" = "y" ] || [ "$answ" = "c" ] ; then
         :
      elif [ "$answ" = "r" ] ; then
         unset inputs
         inputs=`ls ch3i* | tr '\n' ' ' `
         sinput=`echo $inputs | cut -c 1-34 | tr -s ' ' `
         if [ "$sinput" != "ch3i01 ch3i03 ch3i03_1" ] ; then
	    ls
            echo "Do you really want to remove all this? (y|n)"
	    read answ
	    if [ "$answ" = "y" ] ; then
               rm -rf *
            fi
          fi
      else
         exit
      fi
   fi
fi

# Check inppath.
if [ "$inppath" = 'c' ] ; then inppath=$comppath ; fi


#-----------------------------------------------------------------------
# Save old log- summary- and results-files.
#-----------------------------------------------------------------------

if [  -e results.old4 ] ; then
   mv -f results.old4 results.old5
   mv -f summary.old4 summary.old5
   mv -f log.old4     log.old5
fi
if [  -e results.old3 ] ; then
   mv -f results.old3 results.old4
   mv -f summary.old3 summary.old4
   mv -f log.old3     log.old4
fi
if [  -e results.old2 ] ; then
   mv -f results.old2 results.old3
   mv -f summary.old2 summary.old3
   mv -f log.old2     log.old3
fi
if [  -e results.old1 ] ; then
   mv -f results.old1 results.old2
   mv -f summary.old1 summary.old2
   mv -f log.old1     log.old2
fi
if [  -e results.old ] ; then
   mv -f results.old results.old1
   mv -f summary.old summary.old1
   mv -f log.old     log.old1
fi
if [  -e results ] ; then
   mv -f results results.old
   mv -f summary summary.old
   mv -f log    log.old
fi

#-----------------------------------------------------------------------
# Print the current parameter setting to screen and results-file.
#-----------------------------------------------------------------------

echo "$minus40$minus40"
echo "***  Running the elk_test  ***********  Running the elk_test  ***"
echo " "
echo "Current directory: $here"
echo "Comparison set   : $comppath"
echo "Input file set   : $inppath"
echo "Overlap  program : $ovlcodename"
echo "Compare  program : $compcodename"
echo "Excecute program : $testcodename"
echo "  "

echo "***  elk_test log  ***  "`date`  > log
echo " "                 >> log
echo "RUNNING  : $0"     >> log
echo "ARGUMENTS: $args"  >> log
echo "PWD: $here"        >> log
echo " "                 >> log
echo "Comparison set   : $comppath" >> log
echo "Input file set   : $inppath"  >> log
echo "Overlap  program : $ovlcodename"  >> log
echo "Compare  program : $compcodename" >> log
echo "Excecute program : $testcodename" >> log
echo "  "                               >> log

echo "$star40$star40" > results
echo "  ELK_TEST    "`date`"      ELK_TEST" >> results
echo "$star40$star40" >> results
echo "Comparison set   : $comppath" >> results
echo "Input file set   : $inppath"  >> results
echo "Overlap  program : $ovlcodename"  >> results
echo "Compare  program : $compcodename" >> results
echo "Excecute program : $testcodename" >> results
echo "running on host  : `hostname`" >> results
echo "PWD              : $here"      >> results

$testcode -ver >> results
echo "              " >> results

#-----------------------------------------------------------------------
# Copy comparison directories and files.
#-----------------------------------------------------------------------

if [ ! -e nocl0 ] ; then
   mkdir nocl0
   cp $comppath/nocl0/restart nocl0
fi
if [ ! -e nocl0fft ] ; then
   mkdir nocl0fft
   cp $comppath/nocl0fft/restart nocl0fft
fi
if [ ! -e nocl1_10 ] ; then
   mkdir nocl1_10
   cp $comppath/nocl1_10/* nocl1_10
fi
if [ ! -e ch3i01 ] ; then
   mkdir ch3i01
   cp $comppath/ch3i01/restart ch3i01
   cp $comppath/ch3i01/dvr ch3i01
fi
if [ ! -e ch3i03 ] ; then
   mkdir ch3i03
   cp $comppath/ch3i03/restart ch3i03
   cp $comppath/ch3i03/dvr ch3i03
fi
if [ ! -e ch3i03_1 ] ; then
   mkdir ch3i03_1
   cp $comppath/ch3i03_1/restart ch3i03_1
   cp $comppath/ch3i03_1/dvr ch3i03_1
fi
if [ ! -e pot_hd2 ] ; then
   mkdir pot_hd2
   cp $comppath/pot_hd2/natpot    pot_hd2
fi
if [ ! -e pot_boson ] ; then
   mkdir pot_boson
   cp $comppath/pot_boson/natpot  pot_boson
fi
if [ ! -e t36go ] ; then
   mkdir t36go
   cp $comppath/t36go/oper t36go
fi


#-----------------------------------------------------------------------
# if -n was set just do the specified tests and exit.
#-----------------------------------------------------------------------
if [ -n "$numbers" ] ; then
    for i in $numbers ; do
       cp $inppath/test$i.inp .
       if [ $mpipro -ge 1 ] ; then
          mv test$i.inp temp.inp
          sed 's/^RUN\-SECTION.*$/&\nusempi/' temp.inp > test$i.inp
          rm -rf temp.inp
       fi
       if [ $pthreads -ge 1 ] ; then
          mv test$i.inp temp.inp
          sed "s/^RUN\-SECTION.*$/&\nusepthreads=$pthreads/" temp.inp > test$i.inp
          rm -rf temp.inp
       fi
       rm -rf test$i
       mkdir test$i
       echo "Running test$i"
       fgrep Test $inppath/test$i.inp
       if [ "$i" = 17 ] ; then
         cp nocl1_10/* test17
       fi
       $testcode test$i || exit 1
       cd test$i
       $ovlcode $comppath/test$i/psi || exit 1
       cd ..
       echo " "                      >> results
       echo "------- test$i -------" >> results
       $compcode test$i $comppath/test$i || exit 1
       tail -n 1 summary
       echo ' '
    done
#.......check if tests have been passed
    echo " "
    echo "**** SUMMARY ****"
    echo " "
    cat summary
    echo "*** done ***  "`date`  >> log
    exit
fi


#-----------------------------------------------------------------------
# Normal flow of the script. Run through all tests.
#-----------------------------------------------------------------------

notfound=0
i=$start
while [ $notfound -le 90 ] && [ $i -le $stop ] ; do
   if [ -e $inppath/test$i.inp ] ; then
        cp $inppath/test$i.inp .
        if [ $mpipro -ge 1 ] ; then
           mv test$i.inp temp.inp
           sed 's/^RUN\-SECTION.*$/&\nusempi/' temp.inp > test$i.inp
           rm -rf temp.inp
        fi
        if [ $pthreads -ge 1 ] ; then
           mv test$i.inp temp.inp
           sed "s/^RUN\-SECTION.*$/&\nusepthreads=$pthreads/" temp.inp > test$i.inp
           rm -rf temp.inp
        fi
        notfound=99
   else
        notfound=$(($notfound+1)) 	
        i=$(($i+1)) 	
   fi
done

if [ $notfound != 99 ] ; then
    echo 'Could not find a test$i.inp between $i = '$start' and '$(($i-1))
    exit
fi

notfound=0
while [ $notfound -le 30 ] && [ $i -le $stop ] ; do
   if [ ! -e test$i ] ; then
      if [ -n "$query" ] ; then
         echo '#####  test$i does not exist! #####'
      else
         run=1
         echo "Running test$i"
         fgrep Test $inppath/test$i.inp
         mkdir test$i
         if [ "$i" = 17 ] ; then
            cp nocl1_10/* test17
         fi
         $testcode test$i || exit 1
      fi
   else
      run=0
      echo "Reading test$i"
      fgrep Test $inppath/test$i.inp
   fi
   cd test$i
   echo " "
   pwd
   $ovlcode $comppath/test$i/psi || exit 1
   cd ..
   echo " "                      >> results
   echo "------- test$i -------" >> results
   $compcode test$i $comppath/test$i || exit 1
   tail -n 1 summary
   echo ' '
   unset tt
   if [ "$redo" = 1 ] && [ "$run" = 0 ] ; then
	tt=`tail -n 1 summary | fgrep FAILED`
   fi
   if [ -n "$tt" ] && [ -z "$query" ] ; then
	rm -rf test$i
      cat summary > summary.1.$$
      cat summary.1.$$ | fgrep -v "$tt" > summary
      rm -rf summary.1.$$
   else
        i=$(($i+1))
        if [ "$i" = "$skip" ] ; then i=$(($i+1)) ; fi
   fi

   while [ $notfound -le 30 ] && [ ! -f test$i.inp ] ; do
      if [ -f $inppath/test$i.inp ] ; then
         cp $inppath/test$i.inp .
         if [ $mpipro -ge 1 ] ; then
            mv test$i.inp temp.inp
            sed 's/^RUN\-SECTION.*$/&\nusempi/' temp.inp > test$i.inp
            rm -rf temp.inp
         fi
         if [ $pthreads -ge 1 ] ; then
            mv test$i.inp temp.inp
            sed "s/^RUN\-SECTION.*$/&\nusepthreads=$pthreads/" temp.inp > test$i.inp
            rm -rf temp.inp
         fi
         notfound=0
      else
	 notfound=$(($notfound+1))
	 i=$(($i+1))
      fi
   done
done

if [ $mpipro -ge 1 ] ; then
   rm -rf $MCTDH_DIR/bin/mpimctdh
fi
#-----------------------------------------------------------------------
# check if tests have been passed
#-----------------------------------------------------------------------
echo " "
echo "**** SUMMARY ****"
echo " "
cat summary
echo "*** done ***  "`date`  >> log
echo "*** done ***  "`date`

exit

