1#!/usr/local/bin/bash
2#
3# Copyright 2009-2011 The VOTCA Development Team (http://www.votca.org)
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#     http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17
18show_help () {
19  cat << eof
20${0##*/}, version %version%
21
22Start the script to run ibi, imc, etc. or clean out current dir
23
24Usage: ${0##*/} [OPTIONS] --options settings.xml [clean]
25
26Allowed options:
27-h, --help                    show this help
28-N, --do-iterations N         only do N iterations (ignoring settings.xml)
29    --wall-time SEK           Set wall clock time
30    --options FILE            Specify the options xml file to use
31    --debug                   enable debug mode with a lot of information
32    --nocolor                 disable colors
33
34Examples:
35* ${0##*/} --options cg.xml
36* ${0##*/} -6 --options cg.xml
37eof
38}
39
40#--help should always work so leave it here
41if [[ $1 = "--help" ]]; then
42  show_help
43  exit 0
44fi
45
46#do all start up checks option stuff
47source "${VOTCASHARE}/scripts/inverse/start_framework.sh"  || exit 1
48
49#defaults for options
50do_iterations=""
51waittime=10
52
53#unset stuff from enviorment
54unset CSGXMLFILE CSGENDING CSGDEBUG
55
56### begin parsing options
57shopt -s extglob
58while [[ ${1#-} != $1 ]]; do
59 if [[ ${1#--} = $1 && -n ${1:2} ]]; then
60    #short opt with arguments here: fc
61    if [[ ${1#-[fc]} != ${1} ]]; then
62       set -- "${1:0:2}" "${1:2}" "${@:2}"
63    else
64       set -- "${1:0:2}" "-${1:2}" "${@:2}"
65    fi
66 fi
67 case $1 in
68   --do-iterations)
69    do_iterations="$2"
70    is_int "$do_iterations" || die "inverse.sh: --do-iterations need a number as argument, but I got $do_iterations"
71    shift 2 ;;
72   --wall-time)
73    is_int "$2" || die "inverse.sh: --wall-time need a number as argument, but I got $2"
74    export CSGENDING=$(( $(get_time) + $2 ))
75    shift 2 ;;
76   -[0-9]*)
77    do_iterations=${1#-}
78    is_int "$do_iterations" || die "inverse.sh: $1 need a number in its argument, but I got $do_iterations"
79    shift ;;
80   --options)
81    CSGXMLFILE="$2"
82    [[ -f $CSGXMLFILE ]] || die "options xml file '$CSGXMLFILE' not found"
83    export CSGXMLFILE="$(globalize_file "${CSGXMLFILE}")"
84    shift 2;;
85   --nocolor)
86    export CSGNOCOLOR="yes"
87    shift;;
88   --nowait)
89    waittime=0
90    shift;;
91   --debug)
92    export CSGDEBUG="yes"
93    shift;;
94   -h | --help)
95    show_help
96    exit 0;;
97  *)
98   die "Unknown option '$1'";;
99 esac
100done
101### end parsing options
102
103#old style, inform user
104[[ -z ${CSGXMLFILE} ]] && die "Please add your setting xml file behind the --options option (like for all other votca programs) !"
105
106[[ $1 = "clean" ]] && { csg_inverse_clean "$waittime"; exit $?; }
107
108enable_logging
109[[ -n $CSGDEBUG ]] && set -x
110check_for_obsolete_xml_options
111
112echo "Sim started $(date)"
113
114method="$(csg_get_property cg.inverse.method)"
115msg "We are doing Method: $method"
116
117scriptpath="$(csg_get_property --allow-empty cg.inverse.scriptpath)"
118[[ -n $scriptpath ]] && echo "Adding $scriptpath to csgshare" && add_to_csgshare "$scriptpath"
119
120#after scriptpath to allow overwrite
121sim_prog="$(csg_get_property cg.inverse.program)"
122echo "We are using Sim Program: $sim_prog"
123source_function $sim_prog
124
125show_csg_tables
126
127#main script
128[[ -f done ]] && { msg "Job is already done (remove the file named 'done' if you want to go on)"; exit 0; }
129
130######## BEGIN STEP 0 ############
131update_stepnames 0
132restart_file="$(get_restart_file)"
133this_dir=$(get_current_step_dir --no-check)
134if [[ -d $this_dir &&  -f "$this_dir/done" ]]; then
135  msg "step 0 is already done - skipping"
136else
137  echo ------------------------
138  msg --color blue "Prepare (dir ${this_dir##*/})"
139  echo ------------------------
140  if [[ -d $this_dir ]]; then
141    msg "Incomplete step 0"
142    [[ -f "${this_dir}/${restart_file}" ]] || die "No restart file found (remove stepdir '${this_dir##*/}' if you don't know what to do - you will lose the prepare step)"
143  else
144    mkdir -p $this_dir || die "mkdir -p $this_dir failed"
145  fi
146  cd $this_dir || die "cd $this_dir failed"
147  mark_done "stepdir"
148
149  if is_done "Prepare"; then
150    msg "Prepare of potentials already done"
151  else
152    filelist="$(csg_get_property --allow-empty cg.inverse.filelist)"
153    #get need files (leave the " " unglob happens inside the function)
154    [[ -n ${filelist} ]] && cp_from_main_dir "$filelist"
155
156    do_external prepare $method
157    mark_done "Prepare"
158  fi
159
160  touch "done"
161  msg "step 0 done"
162  cd $(get_main_dir)
163fi
164######## END STEP 0 ############
165
166begin=1
167trunc=$(get_stepname --trunc)
168for i in ${trunc}*; do
169  [[ -d $i ]] || continue
170  nr=${i#$trunc}
171  if [[ -n $nr && -z ${nr//[0-9]} ]]; then
172    #convert to base 10, otherwise 008 is interpreted as octal
173    nr=$((10#$nr))
174    [[ $nr -gt $begin ]] && begin="$nr"
175  fi
176done
177unset nr trunc
178[[ $begin -gt 1 ]] && msg "Jumping in at iteration $begin"
179
180avg_steptime=0
181steps_done=0
182i="$(( $begin - 1 ))"
183while true; do
184  ((i++))
185  if [[ -z ${do_iterations} ]]; then
186    iterations_max="$(csg_get_property cg.inverse.iterations_max)"
187    is_int "$iterations_max" || die "inverse.sh: cg.inverse.iterations_max needs to be a number, but I got $iterations_max"
188    echo "We are doing $i of $iterations_max iterations (0=inf)."
189    [[ $iterations_max -ne 0 && $i -gt $iterations_max ]] && break
190  fi
191  step_starttime="$(get_time)"
192  update_stepnames $i
193  last_dir=$(get_last_step_dir)
194  this_dir=$(get_current_step_dir --no-check)
195  echo -------------------------------
196  msg --color blue "Doing iteration $i (dir ${this_dir##*/})"
197  echo -------------------------------
198  if [[ -d $this_dir ]]; then
199    if [[ -f "$this_dir/done" ]]; then
200      msg "step $i is already done - skipping"
201      continue
202    else
203      msg "Incomplete step $i"
204      [[ -f ${this_dir}/${restart_file} ]] || die "No restart file found (remove stepdir '${this_dir##*/}' if you don't know what to do - you will lose one iteration)"
205      [[ ${CSGXMLFILE} -nt "${this_dir}/${restart_file}" ]] &&
206        msg --color blue --to-stderr "WARNING: options file ('${CSGXMLFILE}') was changed since the last execution, these changes will have no effect already finished parts of the iteraction, to take effect remove the current iteration ('${this_dir##*/}')"
207    fi
208  else
209    echo "Step $i started at $(date)"
210    mkdir -p $this_dir || die "mkdir -p $this_dir failed"
211  fi
212
213  cd $this_dir || die "cd $this_dir failed"
214  mark_done "stepdir"
215
216  filelist="$(csg_get_property --allow-empty cg.inverse.filelist)"
217  if is_done "Filecopy"; then
218    echo "Filecopy already done"
219    for f in $filelist; do
220      [[ -f $f ]] || cp_from_main_dir "$f"
221      echo Comparing "$(get_main_dir)/$f" "$f"
222      [[ -z $(type -p cmp) ]] && echo "program 'cmp' not found, comparision skipped" && continue
223      cmp "$(get_main_dir)/$f" "$f" && echo "Unchanged" || \
224	msg --color blue --to-stderr "WARNING: file '$f' in the main dir was changed since the last execution, this will have no effect on the current iteration, to take effect remove the current iteration ('${this_dir##*/}')"
225    done
226  else
227    #get need files (leave the " " unglob happens inside the function)
228    [[ -n ${filelist} ]] && cp_from_main_dir "$filelist"
229
230    mark_done "Filecopy"
231  fi
232
233  if is_done "Initialize"; then
234    echo "Initialization already done"
235  else
236    #get files from last step, init sim_prog and ...
237    do_external initstep $method
238
239    mark_done "Initialize"
240  fi
241
242  if is_done "Simulation"; then
243    echo "Simulation is already done"
244  else
245    msg "Simulation with $sim_prog"
246    do_external run $sim_prog
247  fi
248
249  if simulation_finish; then
250    mark_done "Simulation"
251  elif [[ "$(csg_get_property cg.inverse.simulation.background)" = "yes" ]]; then
252    msg "Simulation is suppose to run in background, which we cannot check."
253    msg "Stopping now, resume csg_inverse whenever the simulation is done."
254    exit 0
255  elif [[ -n ${CSGENDING} ]] && checkpoint_exist; then
256    msg "Simulation is not finished, but a checkpoint was found, so it seems"
257    msg "walltime is nearly up, stopping now, resume csg_inverse whenever you want."
258    exit 0
259  else
260    die "Simulation is in a strange state, it has no checkpoint and is not finished, check ${this_dir##*/} by hand"
261  fi
262
263  do_external pre_update $method
264
265  msg "Make update for $method"
266  do_external update $method
267
268  do_external post_update $method
269  do_external add_pot $method
270
271  msg "Post add"
272  do_external post add
273
274  do_external clean $sim_prog
275
276  step_time="$(( $(get_time) - $step_starttime ))"
277  msg "\nstep $i done, needed $step_time secs"
278  ((steps_done++))
279
280  touch "done"
281
282  convergence_check="$(csg_get_property cg.inverse.convergence_check.type)"
283  if [[ $convergence_check = none ]]; then
284    echo "No convergence check to be done"
285  else
286    msg "Doing convergence check: $convergence_check"
287    [[ -f stop ]] && rm -f stop #just in case a script created a stop file
288    do_external convergence_check "$convergence_check"
289    if [[ -f stop ]]; then
290      msg "Iterations are converged, stopping"
291      break
292    else
293      msg "Iterations are not converged, going on"
294    fi
295  fi
296
297  if [[ -n $CSGENDING ]]; then
298    avg_steptime="$(( ( ( $steps_done-1 ) * $avg_steptime + $step_time ) / $steps_done + 1 ))"
299    echo "New average steptime $avg_steptime"
300    if [[ $(( $(get_time) + $avg_steptime )) -gt ${CSGENDING} ]]; then
301      msg "We will not manage another step due to walltime, stopping"
302      exit 0
303    else
304      msg "We can go for another $(( ( ${CSGENDING} - $(get_time) ) / $avg_steptime - 1 )) steps until walltime is up."
305    fi
306  fi
307
308  if [[ -n $do_iterations ]]; then
309    if [[ $do_iterations -eq $steps_done ]] ; then
310      msg "Stopping at step $i, user requested to take some rest after this amount of iterations"
311      exit 0
312    else
313      msg "Going on for another $(( $do_iterations - $steps_done )) steps"
314    fi
315  fi
316  cd $(get_main_dir) || die "cd $(get_main_dir) failed"
317done
318
319touch "done"
320echo "All done at $(date)"
321exit 0
322
323