#!/bin/bash
banner[1]='_______________________________________________________________________________'
banner[2]='                                                                               '
banner[3]='             IOSPEED = Test I/O Speed of Hard Drives on FITS Images            '
banner[4]='              Alexander Men`shchikov, SAp IRFU CEA Saclay, France              '
banner[5]='                                Version 1.140127                               '
banner[6]='_______________________________________________________________________________'
#
# Development initiated on 2010/12/24 by A.M. (alexander.menshchikov@cea.fr)
#___________________________________________________________________________________________________________________________________

CONDITIONS ()
{
  echo '#  _____________________________________________________________________________'
  echo '# |                                                                             '
  echo '# |               IOSPEED = Test I/O Speed of Disks on FITS Images              '
  echo '# |             Alexander Men''shchikov, SAp IRFU CEA Saclay, France             '
  echo '# |_____________________________________________________________________________'
  echo '# |                                                                             '
  echo '# |    CONDITIONS OF USE (*1)                                                   '
  echo '# |                                                                             '
  echo '# | In what follows, "this software" refers to the Bash scripts GETSOURCES,     '
  echo '# | CONVOLVE, IOSPEED, PREPAREOBS, RESAMPLE, & the associated FORTRAN utilities '
  echo '# | CLEANBG, ELLIPSES, EXPANDA, FFTCONV, FINALCAT, FITFLUXES, FMEASURE, IMGSTAT,'
  echo '# | MODFITS, OPERATE, READHEAD, SEPARATE, SFINDER, SMEASURE, SPLITCUBE, and the '
  echo '# | library TOOLS, and "the author" refers to Alexander Men'\''shchikov of the  '
  echo '# | Service d'\''Astrophysique, IRFU, CEA Saclay, France.                          '
  echo '# |                                                                             '
  echo '# | It is assumed that anyone using this code ("the user") has read, understood,'
  echo '# | and agreed to the following conditions of use:                              '
  echo '# |                                                                             '
  echo '# | 1. Distribution of this software shall remain the purview of the author. A  '
  echo '# |    user is free to share this code with co-workers and students, but if it  '
  echo '# |    is requested by a colleague not working directly with the user, the user '
  echo '# |    is asked to redirect such requests to: alexander.menshchikov@cea.fr      '
  echo '# |                                                                             '
  echo '# | 2. This software shall be used exclusively for education, research, non-    '
  echo '# |    profit, and non-military purposes. Specific written permission from the  '
  echo '# |    author must be obtained before any commercial use of this software is    '
  echo '# |    undertaken.                                                              '
  echo '# |                                                                             '
  echo '# | 3. The banners of this software, these conditions of use, and information   '
  echo '# |    about the author shall remain with this software and any descendent      '
  echo '# |    developed from and still based substantially upon this software.         '
  echo '# |                                                                             '
  echo '# | 4. The names of the institutions with which the author is or has been       '
  echo '# |    affiliated shall not be used to publicise any data and (or) results      '
  echo '# |    generated by this software. All findings and their interpretation are    ' 
  echo '# |    the opinions of the user and do not necessarily reflect those of the     '
  echo '# |    author nor the institutions with which the author is or has been         '
  echo '# |    affiliated.                                                              '
  echo '# |                                                                             '
  echo '# | The author makes no representations about the suitability of this software  '
  echo '# | for any purpose. Subject to the above conditions, this software are provided'
  echo '# | "as is" without any expressed or implied warranty.                          '
  echo '# |                                                                             '
  echo '# | Inquiries about the code, bug reports, constructive criticism, etc., can be '
  echo '# | directed to: alexander.menshchikov@cea.fr                                   '
  echo '# |                                                                             '
  echo '# |    CITATIONS AND ACKNOWLEDGEMENTS (*1)                                      '
  echo '# |                                                                             '
  echo '# | The algorithms used in this software are described in:                      '
  echo '# | Men'\''shchikov A. 2013, A&A, 560, A63                                         '
  echo '# | Men'\''shchikov A., Andre Ph., Didelon P., et al. 2012, A&A, 542, A81          '
  echo '# |                                                                             '
  echo '# | A very brief description of GETSOURCES has been published in:               '
  echo '# | Men'\''shchikov A., Andre Ph., Didelon P., et al. 2010, A&A, 518, L103         '
  echo '# |                                                                             '
  echo '# | It is requested that any publication reporting results obtained using this  '
  echo '# | software or any of its derivatives includes:                                '
  echo '# |                                                                             '
  echo '# | "Use of GETSOURCES (GETFILAMENTS), developed by A. Men'\''shchikov             '
  echo '# | at the SAp, IRFU, CEA Saclay, France, is hereby acknowledged." (*2)         '
  echo '# |_____________________________________________________________________________'
  echo '#                                                                               '
  echo '# (*1) Adapted from those written by David Clarke for the MHD code AZEuS.       '
  echo '# (*2) If only individual scripts or utilities (not the GETSOURCES script)      '
  echo '#      were used, substitute "GETSOURCES" with their names.                     '
}
#___________________________________________________________________________________________________________________________________
#
scriptname=`basename "$0"`; script=`echo $scriptname | tr a-z A-Z`; fun=''; fitsimage=$1; numtry=$2; verb=$3
#___________________________________________________________________________________________________________________________________

chk_rc () # internal function 'chk_rc' for checking return code and exiting if abnormal termination.
{
  rc=$?; if [[ "$rc" != "0" ]]; then echo; echo ' Error in '$script': '$fun': Aborted.'; exit "$rc"; fi
}
#___________________________________________________________________________________________________________________________________

POSITION ()
{
# Finding position of a substring in a string.

  local funo=$fun; fun='POSITION'
  if [[ $2 == "" ]]
  then echo; echo ' '$script': '$funo': '$fun': ERROR:'
    echo ' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
    echo ' INFO: Too few parameters: "'$1'" "'$2'"'
    echo ' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
    echo; fun=$funo; return 99
  fi
  local substr=$1; local string=$2 

  lensub=${#substr}; lenstr=${#string}; local dlen=$(( lenstr - lensub )); local i; returnposition=0
  if [[ $lensub -le $lenstr ]]
  then for (( i=0; i <= $dlen; i++ ))
  do if [[ "$substr" == "${string:$i:$lensub}" ]]; then returnposition=$(( i + 1 )); break; fi; done; fi

  fun=$funo; return $returnposition
}
#___________________________________________________________________________________________________________________________________

PROGRESS_BAR ()
{ 
  local funo=$fun; fun='PROGRESS_BAR'
  if [[ $1 != "complete" && $5 == "" ]]
  then echo; echo ' '$script': '$funo': '$fun': ERROR:'
    echo ' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
    echo ' INFO: Too few parameters: "'$1'" "'$2'" "'$3'" "'$4'" "'$5'"'
    echo ' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
    echo; fun=$funo; return 99
  fi
  local i; local nbeg; local nend; local width; local ncur; local sym='='; local nrange
  progresstitle=$1; ncur=$2; nbeg=$3; nend=$4; width=$5

  if [[ "$1" != "complete" ]]
  then
    if [[ $ncur -eq $nbeg ]]
    then                                   
      lnend=${#nend}; ltitle=${#progresstitle}; lbar=$(( width - 3 - ltitle - 1 - lnend - 1 ))
      if [[ $lbar -gt $nend ]]; then lbar=$nend; fi; lbarp1=$(( lbar + 1 )); lback=$(( lbarp1 + lnend + 1 ))
      echo; echo -en ' '$progresstitle' ['; for (( i=1; i <= $lbar; i++ )); do echo -en "-"; done; echo -en "] $nend\033[${lback}D"
      nprogress=1; npos=0; sleep 1
    else
      if [[ $nprogress -eq 0 ]]
      then echo; echo ' '$script': '$funo': '$fun': ERROR:'
        echo ' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
        echo ' INFO: Initial value /= lower bound: '$ncur $nbeg $nend $width
        echo ' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
        echo; fun=$funo; return 99
      fi
    fi
  fi
  nbegm1=$(( nbeg - 1 )); nrange=$(( nend - nbegm1 ))
  ncurm1=$(( ncur - 1 )); lncur=${#ncur}; lncurm1=${#ncurm1}; lncurm1p1=$(( lncurm1 + 1 ))
  lenr=$(echo "scale=20; $nbegm1+($ncur-($nbeg-1))*($lbar-$nbeg)/$nrange" | bc); chk_rc
  if [[ ${lenr:0:1} != "-" ]]; then leni=${lenr%.*}; else leni=0; fi

  if [[ $1 == "complete" ]]
  then 
    if [[ $ncur -ge $nend ]]
    then
      many=''
      for (( i=1; i <= $lncur; i++ )); do many=$many$sym; done
      echo -en "\033[${lncur}D$many"
    fi
    echo; fun=$funo; return 0
  fi
  lenrold=$lenr
  leniold=$leni
  if [[ $leni -lt $nprogress ]]
  then
    if [[ $ncur -eq $nbeg ]]
    then 
      echo -en "$ncur"; npos=$(( npos + lncur )); sleep 1
    else 
      npos=$(( npos - lncurm1 + lncur ))
      if [[ $npos -gt $lbar ]]; then lncorr=$(( npos - lbar )); echo -en "\033[${lncorr}D"; npos=$(( npos - lncorr )); fi
      echo -en "\033[${lncurm1}D$ncur"
    fi
  else
    nprogress=$(( nprogress + 1 )); many=''; for (( i=1; i <= $lncurm1p1; i++ )); do many=$many$sym; done
    if [[ $npos -lt $lbar ]]; then echo -en "$sym"; npos=$(( npos + 1 )); fi
    echo -en "\033[${lncurm1p1}D$many\033[${lncur}D$ncur"
  fi
  
  fun=$funo
}
#___________________________________________________________________________________________________________________________________

# Read and store the header (version) information from the very beginning of this script.

l=0
{
while read linefromthisfile
do
  if [[ ${linefromthisfile:0:7} == "banner[" && $l -le 7 ]]
  then
    l=$(( l + 1 ))
    len=${#linefromthisfile}; last=$(( len - 12 ))
    version[l]="${linefromthisfile:11:$last}"
    'POSITION' ' Version' "${version[l]}"; ncv=$returnposition
    if [[ $ncv -gt 0 ]]; then versnum=${version[l]:ncv:16}; fi
  fi
  if [[ $l -eq 7 ]]; then break; fi
done
} < $0

headerinfo[1]='#  ___________________________________________________________________________________________________________________________________'
headerinfo[2]='# |                                                                                                                                   '
headerinfo[3]='# | IOSPEED = Test I/O Speed of Disks on FITS Images = '$versnum' = Alexander Men'\''shchikov, SAp IRFU CEA Saclay                 '
headerinfo[4]='# |___________________________________________________________________________________________________________________________________'

if [[ "$*" == ":" ]]
then
  echo "${headerinfo[3]:3:93}"
  exit 0
fi

'CONDITIONS' >> '+log.CONDITIONS'

for (( b=1; b <= 6; b++ ))
do echo "${banner[b]}"; done

if [[ $fitsimage == "" ]]
then
  echo
  echo ' USAGE: iospeed <fitsimage> [<numtry>] [-verb[0|1|2]]'
  echo
  echo '        This script will test the I/O speed of hard drives by reading a FITS image,'
  echo '        multiplying it by 1.0, and writing it back to the disk (<numtry> times).'
  echo '        Execution time will be measured that will allow an estimate of relative'
  echo '        speeds of hard drives to facilitate choosing the fastest one.'
  echo '        Default value for <numtry> is 100; default verbosity is 0.'
  echo; exit 1
fi

if [[ $numtry == "" || ${numtry:0:5} == "-verb" ]]; then numtry=100; fi
if [[ $verb == "" ]]; then verb='-verb0'; fi

time {

echo
echo ' Reading a FITS image, multiplying it by 1, and writing back '$numtry' times.'

for (( i=1; i <= $numtry; i++ ))
do
  if [[ $verb == "-verb0" ]]
  then 
    if [[ $nwaves -eq 1 ]]; then iw=''; else iw=$i; fi
    'PROGRESS_BAR' "$script: TESTING" $i 1 $numtry 79
  fi
  'modfits' multiply '1' $fitsimage -o $fitsimage $verb; chk_rc
done

if [[ $verb == "-verb0" ]]
then 
  'PROGRESS_BAR' 'complete' $numtry 1 $numtry 79
fi

cdate=`date +%d\ %b\ %Y\ %a\ %H:%M:%S\ %Z`
echo
echo ' '$script' DONE.'
echo
echo ' '$cdate

}

exit