This file is indexed.

/usr/share/votca/scripts/inverse/functions_common.sh is in votca-csg-scripts 1.2.4-1.

This file is owned by root:root, with mode 0o755.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
#! /bin/bash
#
# Copyright 2009-2011 The VOTCA Development Team (http://www.votca.org)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

#-------------------defines----------------

if [[ $1 = "--help" ]]; then
  cat <<EOF
${0##*/}, version %version%

This file defines some commonly used functions:
EOF
sed -n 's/^\(.*\)([)] {[^#]*#\(.*\)$/* \1  -- \2/p' ${0}
echo
exit 0
fi

msg() { #echos a msg on the screen and send it to the logfile if logging is enabled
  local color colors=" blue cyan cyann green red purp "
  if [[ -z ${CSGNOCOLOR} ]]; then
    local blue=""
    local cyan=""
    local cyann=""
    local green=""
    local red=""
    local purp=""
    local off=""
  else
    local blue cyan cyann green red purp off
  fi
  if [[ $1 = "--color" ]]; then
    [[ -z $2 ]] && die "msg: missing argument after --color"
    [[ -n ${colors//* $2 *} ]] && die "msg: Unknown color ($colors allowed)"
    color="${!2}"
    shift 2
  else
    off=""
  fi
  if [[ $1 = "--to-stderr" ]]; then
    shift
    [[ -z $* ]] && return
    if [[ -n ${CSGLOG} ]]; then
      echo -e "${color}$*${off}" >&4
      echo -e "$*" >&2
    else
      echo -e "${color}$*${off}" >&2
    fi
  else
    [[ -z $* ]] && return
    if [[ -n ${CSGLOG} ]]; then
      echo -e "${color}$*${off}" >&3
      echo -e "$*"
    else
      echo -e "${color}$*${off}"
    fi
  fi
}
export -f msg

unset -f die
die () { #make the iterative frame work stopp
  local pid pids c
  msg --color red --to-stderr "$(csg_banner "ERROR:" "$@")"
  [[ -z $CSGLOG ]] || msg --color blue "For details see $CSGLOG"
  if [[ -n ${CSG_MASTER_PID} ]]; then
    #grabbing the pid group would be easier, but it would not work on AIX
    pid="$$"
    pids="$$"
    c=0
    #find the parent of pid until we reach CSG_MASTER_PID
    until [[ ${CSG_MASTER_PID} -eq $pid ]]; do
      #get the parent pid using BSD style due to AIX
      pid=$(ps -o ppid= -p "$pid" 2>/dev/null)
      #store them in inverse order to kill parents before the child
      pids="$pid $pids"
      ((c++))
      #at max 10000 iterations
      if [[ $c -eq 10000 ]]; then
        #failback to default, see comment below
        pids="0"
        break
      fi
    done
    if [[ -n ${CSGLOG} ]]; then
      echo "die: (called from $$)  CSG_MASTER_PID is $CSG_MASTER_PID" >&2
      echo "die: pids to kill: $pids" >&2
    fi
    kill $pids
  else
    #send kill signal to all process within the process groups
    kill 0
  fi
  exit 1
}
export -f die

cat_external() { #takes a two tags and shows content of the according script
  local script
  script="$(source_wrapper $1 $2)" || die "cat_external: source_wrapper $1 $2 failed"
  cat "${script/ *}"
}
export -f cat_external

do_external() { #takes two tags, find the according script and excute it
  local script tags quiet="no" 
  [[ $1 = "-q" ]] && quiet="yes" && shift
  script="$(source_wrapper $1 $2)" || die "do_external: source_wrapper $1 $2 failed"
  tags="$1 $2"
  shift 2

  [[ $quiet = "no" ]] && echo "Running subscript '${script##*/} $*'(from tags $tags)"
  if [[ -n $CSGDEBUG && -n "$(sed -n '1s@bash@XXX@p' "$script")" ]]; then
    bash -x $script "$@"
  elif [[ -n $CSGDEBUG && -n "$(sed -n '1s@perl@XXX@p' "$script")" ]]; then
    local perl_debug="$(mktemp perl_debug.XXX)" ret
    PERLDB_OPTS="NonStop=1 AutoTrace=1 frame=2 LineInfo=$perl_debug" perl -dS $script "$@"
    ret=$?
    cat "$perl_debug" 2>&1
    [[ $ret -eq 0 ]]
  else
    $script "$@"
  fi || die "do_external: subscript $script $* (from tags $tags) failed"
}
export -f do_external

critical() { #executes arguments as command and calls die if not succesful
  local quiet="no"
  [[ $1 = "-q" ]] && quiet="yes" && shift
  [[ -z $1 ]] && die "critical: missing argument"
  #print this message to stderr because $(critical something) is used very often
  [[ $quiet = "no" ]] && echo "Running critical command '$*'" >&2
   "$@" || die "critical: '$*' failed"
}
export -f critical

for_all (){ #do something for all interactions (1st argument)
  local bondtype name interactions quiet="no"
  [[ $1 = "-q" ]] && quiet="yes" && shift
  [[ -z $1 || -z $2 ]] && "for_all need at least two arguments"
  bondtype="$1"
  shift
  #check that type is bonded or non-bonded
  if [[ $bondtype != "non-bonded" ]]; then
    die  "for_all: Argmuent 1 '$bondtype' is not non-bonded"
  fi
  [[ $quiet = "no" ]] && echo "For all $bondtype" >&2
  check_for_duplicated_interactions
  interactions="$(csg_get_property cg.non-bonded.name)"
  for name in $interactions; do
    #print this message to stderr to avoid problem with $(for_all something)
    [[ $quiet = no ]] && echo "for_all: run '$*'" >&2
    #we need to use bash -c here to allow things like $(csg_get_interaction_property name) in arguments
    #write variable defines in the front is better, that export
    #no need to run unset afterwards
    bondtype="$bondtype" \
    bondname="$name" \
    bash -c "$*" || die "for_all: bash -c '$*' failed for bondname '$name'"
  done
}
export -f for_all

check_for_duplicated_interactions() { #checks for duplicated interactions
  local i j names=( $(csg_get_property cg.non-bonded.name) ) 
  for ((i=0;i<${#names[@]};i++)); do
    for ((j=i+1;j<${#names[@]};j++)); do
      [[ ${names[$i]} = ${names[$j]} ]] && die "for_all: the interaction name '${names[$i]}' appeared twice, this is not allowed"
    done
  done
}
export -f check_for_duplicated_interactions

csg_get_interaction_property () { #gets an interaction property from the xml file, should only be called from inside a for_all loop
  local ret allow_empty cmd
  if [[ $1 = "--allow-empty" ]]; then
    shift
    allow_empty="yes"
  else
    allow_empty="no"
  fi
  [[ -n $1 ]] || die "csg_get_interaction_property: Missing argument"
  [[ -n $bondtype ]] || die "csg_get_interaction_property: bondtype is undefined (when calling from csg_call set it by --ia-type option)"
  
  #bondtype is special -> dirty hack - removed whenever issue 13 is fixed
  #make these this case work even without name (called by csg_call)
  [[ $1 = "bondtype" ]] && echo "$bondtype" && return 0

  [[ -n $bondname ]] || die "csg_get_interaction_property: bondname is undefined (when calling from csg_call set it by --ia-name option)"
  #make these this case work even without xml file (called by csg_call)
  [[ $1 = "name" ]] && echo "$bondname" && return 0

  [[ -n $CSGXMLFILE ]] || die "csg_get_interaction_property: CSGXMLFILE is undefined (when calling from csg_call set it by --options option)"
  [[ -n "$(type -p csg_property)" ]] || die "csg_get_interaction_property: Could not find csg_property"
  cmd="csg_property --file $CSGXMLFILE --short --path cg.${bondtype} --filter name=$bondname --print $1"
  #the --filter option will make csg_property fail if $1 does not exist, don't stop if we have an default
  if ! ret="$($cmd)"; then
    [[ $allow_empty = "no" && -z $2 ]] && \
      die "csg_get_interaction_property:\n'$cmd'\nfailed geting '$1' for interaction '$bondname' with error msg:\n $ret\n and no default for $1"
    #ret has error message
    ret=""
  fi
  ret="$(echo "$ret" | trim_all)"
  [[ $allow_empty = no && -z $ret && -n $2 ]] && ret="$2"
  [[ $allow_empty = no && -z $ret ]] && die "csg_get_interaction_property: Could not get '$1' for interaction '$bondname'\nResult of '$cmd' was empty"
  echo "${ret}"
}
export -f csg_get_interaction_property

csg_get_property () { #get an property from the xml file
  local ret allow_empty cmd
  if [[ $1 = "--allow-empty" ]]; then
    shift
    allow_empty="yes"
  else
    allow_empty="no"
  fi
  [[ -n $1 ]] || die "csg_get_property: Missing argument"
  [[ -n $CSGXMLFILE ]] || die "csg_get_property: CSGXMLFILE is undefined (when calling from csg_call set it by --options option)"
  [[ -n "$(type -p csg_property)" ]] || die "csg_get_property: Could not find csg_property"
  cmd="csg_property --file $CSGXMLFILE --path ${1} --short --print ."
  #csg_property only fails if xml file is bad otherwise result is empty
  ret="$(critical -q $cmd)"
  ret="$(echo "$ret" | trim_all)"
  [[ -z $ret && -n $2 ]] && ret="$2"
  [[ $allow_empty = "no" && -z $ret ]] && die "csg_get_property: Could not get '$1'\nResult of '$cmd' was empty"
  echo "${ret}"
}
export -f csg_get_property

trim_all() { #strips white space from beginning and the end of all args
  tr '\n' ' ' | sed -e s'/^[[:space:]]*//' -e s'/[[:space:]]*$//' || die "${FUNCNAME[0]}: sed of argument $i failed"
}
export -f trim_all

mark_done () { #mark a task (1st argument) as done in the restart file
  local file
  [[ -n $1 ]] || die "mark_done: Missing argument"
  file="$(get_restart_file)"
  is_done "$1" || echo "$1 done" >> "${file}"
}
export -f mark_done

is_done () { #checks if something is already do in the restart file
  local file
  [[ -n $1 ]] || die "is_done: Missing argument"
  file="$(get_restart_file)"
  [[ -f ${file} ]] || return 1
  [[ -n "$(sed -n "/^$1 done\$/p" ${file})" ]] && return 0
  return 1
}
export -f is_done

int_check() { #checks if 1st argument is a integer or calls die with error message (2nd argument)
  [[ -n $2 ]] || die "int_check: Missing argument"
  [[ -n $1 && -z ${1//[0-9]} ]] && return 0
  shift
  die "$*"
}
export -f int_check

num_check() { #checks if 1st argument is a number or calls die with error message (2nd argument)
  local res
  [[ -n $1 || -n $2 ]] || die "num_check: Missing argument"
  res=$(awk -v x="$1" 'BEGIN{ print ( x+0==x ) }')
  [[ $res -eq 1 ]] && return 0
  shift
  die "$*"
}
export -f num_check

get_stepname() { #get the dir name of a certain step number (1st argument)
  local name
  [[ -n $1 ]] || die "get_stepname: Missing argument"
  if [[ $1 = "--trunc" ]]; then
    echo "step_"
    return 0
  fi
  int_check "${1#-}" "get_stepname: needs a int as argument, but was $1"
  name="$(printf step_%03i "$1")"
  [[ -z $name ]] && die "get_stepname: Could not get stepname"
  echo "$name"
}
export -f get_stepname

update_stepnames(){ #updated the current working step to a certain number (1st argument)
  local thisstep laststep nr
  [[ -n $1 ]] || die "update_stepnames: Missing argument"
  nr="$1"
  int_check "$nr" "update_stepnames: needs a int as argument"
  [[ -z $CSG_MAINDIR ]] && die "update_stepnames: CSG_MAINDIR is undefined"
  [[ -d $CSG_MAINDIR ]] || die "update_stepnames: $CSG_MAINDIR is not dir"
  thisstep="$(get_stepname $nr)"
  laststep="$(get_stepname $((nr-1)) )"
  export CSG_THISSTEP="$CSG_MAINDIR/$thisstep"
  export CSG_LASTSTEP="$CSG_MAINDIR/$laststep"
}
export -f update_stepnames

get_current_step_dir() { #print the directory of the current step
  [[ -z $CSG_THISSTEP ]] && die "get_current_step_dir: \$CSG_THISSTEP is undefined (when calling from csg_call export it yourself)"
  if [[ $1 = "--no-check" ]]; then
    :
  else
    [[ -d $CSG_THISSTEP ]] || die "get_last_step_dir: $CSG_THISSTEP is not dir"
  fi
  echo "$CSG_THISSTEP"

}
export -f get_current_step_dir

get_last_step_dir() { #print the directory of the last step
  [[ -z $CSG_LASTSTEP ]] && die "get_last_step_dir: CSG_LASTSTEP is undefined  (when calling from csg_call export it yourself)"
  [[ -d $CSG_LASTSTEP ]] || die "get_last_step_dir: $CSG_LASTSTEP is not dir"
  echo "$CSG_LASTSTEP"
}
export -f get_last_step_dir

get_main_dir() { #print the main directory
  [[ -z $CSG_MAINDIR ]] && die "get_main_dir: CSG_MAINDIR is defined"
  [[ -d $CSG_MAINDIR ]] || die "update_stepnames: $CSG_MAINDIR is not dir"
  echo "$CSG_MAINDIR"
}
export -f get_main_dir

get_current_step_nr() { #print the main directory
  local name nr
  name=$(get_current_step_dir)
  nr=$(get_step_nr $name)
  echo "$nr"
}
export -f get_current_step_nr

get_step_nr() { #print the number of a certain step directory (1st argument)
  local nr trunc
  trunc=$(get_stepname --trunc)
  [[ -n $1 ]] || die "get_step_nr: Missing argument"
  nr=${1##*/}
  nr=${nr#$trunc}
  #convert to base 10 and cut leading zeros
  nr=$((10#$nr))
  int_check "$nr" "get_step_nr: Could not fetch step nr"
  echo "$nr"
}
export -f get_step_nr

cp_from_main_dir() { #copy something from the main directory
  if [[ $1 = "--rename" ]]; then
    shift
    [[ $# -eq 2 && -n $1 && -n $2 ]] || die "cp_from_main_dir: with --rename option has to be called with exactly 2 (non-empty) arguments"
    echo "cp_from_main_dir: '$1' to '$2'"
    critical pushd "$(get_main_dir)"
    critical cp $1 "$(dirs -l +1)/$2"
    critical popd
  else
    echo "cp_from_main_dir: '$@'"
    critical pushd "$(get_main_dir)"
    critical cp $@ "$(dirs -l +1)"
    critical popd
  fi
}
export -f cp_from_main_dir

cp_from_last_step() { #copy something from the last step
  if [[ $1 = "--rename" ]]; then
    shift
    [[ $# -eq 2 && -n $1 && -n $2 ]] || die "cp_from_last_step: with --rename option has to be called with exactly 2 (non-empty) arguments"
    echo "cp_from_last_step: '$1' to '$2'"
    critical pushd "$(get_last_step_dir)"
    critical cp $1 "$(dirs -l +1)/$2"
    critical popd
  else
    echo "cp_from_last_step: '$@'"
    critical pushd "$(get_last_step_dir)"
    critical cp $@ "$(dirs -l +1)"
    critical popd
  fi
}
export -f cp_from_last_step

get_time() {
  date +%s || die "get_time:  date +%s failed"
}
export -f get_time

get_number_tasks() { #get the number of possible tasks from the xml file or determine it automatically under linux
  local tasks
  tasks="$(csg_get_property cg.inverse.simulation.tasks "auto")"
  [[ $tasks = "auto" ]] && tasks=0
  int_check "$tasks" "get_number_tasks: cg.inverse.parallel.tasks needs to be a number or 'auto'"
  #this only work for linux
  if [[ $tasks -eq 0 && -r /proc/cpuinfo ]]; then
    tasks=$(sed -n '/processor/p' /proc/cpuinfo | sed -n '$=')
    [[ -z ${tasks//[0-9]} ]] || tasks=1
  fi
  [[ $tasks -le 1 ]] && tasks=1
  echo "$tasks"
}
export -f get_number_tasks

get_table_comment() { #get comment lines from a table and add common information, which include the hgid and other information
  local version co
  [[ -n "$(type -p csg_call)" ]] || die "get_defaults_comment: Could not find csg_version"
  version="$(csg_call --version)" || die "get_defaults_comment: csg_call --version failed"
  echo "Created on $(date) by $USER@$HOSTNAME"
  echo "called from $version" | sed "s/csg_call/${0##*/}/"
  [[ -n ${CSGXMLFILE} ]] && echo "settings file: $(globalize_file $CSGXMLFILE)"
  echo "working directory: $PWD"
  if [[ -f $1 ]]; then 
    co=$(sed -n 's/^[#@][[:space:]]*//p' "$1") || die "get_table_comment: sed failed"
    [[ -n $co ]] && echo "Comments from $(globalize_file $1):\n$co"
  fi
}
export -f get_table_comment

csg_inverse_clean() { #clean out the main directory 
  local i files log
  log="$(csg_get_property cg.inverse.log_file "inverse.log")"
  echo -e "So, you want to clean?\n"
  echo "I will remove:"
  files="$(ls -d done ${log} $(get_stepname --trunc)* *~ 2>/dev/null)"
  if [[ -z $files ]]; then
    echo "Nothing to clean"
  else
    msg --color red $files
    msg --color blue "\nCTRL-C to stop it"
    for ((i=10;i>0;i--)); do
      echo -n "$i "
      sleep 1
    done
    rm -rf $files
    msg --color green "\n\nDone, hope you are happy now"
  fi
}
export -f csg_inverse_clean

add_to_csgshare() { #added an directory to the csg internal search directories
  local dir
  for dir in "$@"; do
    [[ -z $dir ]] && die "add_to_csgshare: Missing argument"
    #dir maybe contains $PWD or something
    eval dir="$dir"
    dir="$(globalize_dir "$dir")"
    export CSGSHARE="$dir${CSGSHARE:+:}$CSGSHARE"
    export PERL5LIB="$dir${PERL5LIB:+:}$PERL5LIB"
  done
}
export -f add_to_csgshare

globalize_dir() { #convert a local directory to a global one
  [[ -z $1 ]] && die "globalize_dir: missing argument"
  [[ -d $1 ]] || die "globalize_dir: '$1' is not a dir"
  cd "$1"
  pwd
}
export -f globalize_dir

globalize_file() { #convert a local file name to a global one
  [[ -z $1 ]] && die "globalize_file: missing argument"
  [[ -f $1 ]] || die "globalize_file: '$1' is not a file"
  local dir
  [[ ${1%/*} = ${1} ]] && dir="." || dir="${1%/*}"
  echo "$(globalize_dir "$dir")/${1##*/}"
}
export -f globalize_file

source_function() { #source an extra function file
  local function_file
  [[ -n $1 ]] || die "source_function: Missing argument"
  function_file=$(source_wrapper functions $1) || die "source_function: source_wrapper functions $1 failed"
  source ${function_file} || die "source_function: source ${function_file} failed"
}
export -f source_function

csg_banner() { #print a big banner
  local i l=0 list=()
  [[ -z $1 ]] && return 0
  for i in "$@"; do
    while [[ -n $i && -z ${i/*\\n*} ]]; do
      list[$l]="${i%%\\n*}"
      ((l++))
      i="${i#*\\n}"
    done
    list[$l]=$i
    ((l++))
  done

  l="1"
  for i in "${list[@]}"; do
    [[ ${#l} -lt ${#i} ]] && l="${i}"
  done

  echo "####${l//?/#}"
  echo "# ${l//?/ } #"
  for i in "${list[@]}"; do
    printf "# %-${#l}s #\n" "$i"
  done
  echo "# ${l//?/ } #"
  echo "####${l//?/#}"
}
export -f csg_banner

csg_calc() { #simple calculator, a + b, ...
  local res ret=0 err="1e-2"
  [[ -z $1 || -z $2 || -z $3 ]] && die "csg_calc: Needs 3 arguments, but got '$*'"
  num_check "$1" "csg_calc: First argument should be a number, but found '$1'"
  num_check "$3" "csg_calc: Third argument should be a number, but found '$3'"
  [[ -n "$(type -p awk)" ]] || die "csg_calc: Could not find awk"
  #we use awk -v because then " 1 " or "1\n" is equal to 1
  case "$2" in
    "+"|"-"|'*'|"/"|"^")
       res="$(awk -v x="$1" -v y="$3" "BEGIN{print ( x $2 y ) }")" || die "csg_calc: awk -v x='$1' -v y='$3' 'BEGIN{print ( x $2 y ) }' failed"
       true;;
    '>'|'<' )
       res="$(awk -v x="$1" -v y="$3" "BEGIN{print ( x $2 y )}")" || die "csg_calc: awk -v x='$1' -v y='$3' 'BEGIN{print ( x $2 y )}' failed"
       #awk return 1 for true and 0 for false, shell exit codes are the other way around
       ret="$((1-$res))"
       #return value matters
       res=""
       true;;
    "="|"==")
       #we expect that x and y are close together
       res="$(awk -v x="$1" -v y="$3" "BEGIN{print ( sqrt(((x-y)/x)^2) < $err )}")" || die "csg_calc: awk -v x='$1' -v y='$3' 'BEGIN{print ( sqrt(((x-y)/x)^2) < $err )}' failed"
       #awk return 1 for true and 0 for false, shell exit codes are the other way around
       ret="$((1-$res))"
       #return value matters
       res=""
       true;;
    *)
       die "csg_calc: unknow operation" 
       true;;
  esac
  [[ -n $res ]] && echo "$res"
  return $ret
}
export -f csg_calc

show_csg_tables() { #show all concatinated csg tables
  local old_IFS dir
  old_IFS="$IFS"
  IFS=":"
  echo "#The order in which scripts get called"
  for dir in ${CSGSHARE}; do
    [[ -f $dir/csg_table ]] || continue
    echo "#From: $dir/csg_table"
    #remove comments and empty line, trim begin and end, tab to spaces
    sed -e '/^#/d' -e '/^[[:space:]]*$/d' -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' -e 's/[[:space:]]\+/ /g' "$dir/csg_table"
  done
  IFS="$old_IFS"
}
export -f show_csg_tables

get_command_from_csg_tables() { #print the name of script belonging to certain tags (1st, 2nd argument)
  [[ -z $1 || -z $2 ]] && die "get_command_from_csg_tables: Needs two tags"
  show_csg_tables | \
    sed -e '/^#/d' | \
    sed -n "s/^$1 $2 \(.*\)$/\1/p" | \
    sed -n '1p'
}
export -f get_command_from_csg_tables

source_wrapper() { #print the full name of a script belonging to two tags (1st, 2nd argument)
  [[ -z $1 || -z $2 ]] && die "source_wrapper: Needs two tags"
  local cmd script
  cmd=$(get_command_from_csg_tables "$1" "$2") || die
  [[ -z $cmd ]] && die "source_wrapper: Could not get any script from tags '$1' '$2'"
  script="${cmd/* }"
  real_script="$(find_in_csgshare "$script")"
  echo "${cmd/${script}/${real_script}}"
}
export -f source_wrapper

find_in_csgshare() { #find a script in csg script search path
  [[ -z $1 ]] && die "find_in_csgshare: missing argument"
  #global path
  if [[ -z ${1##/*} ]]; then
    [[ -f $1 ]] || die "find_in_csgshare: $1 is a script with global path, but was not found"
    echo "$1" && return
  fi
  local old_IFS dir
  old_IFS="$IFS"
  IFS=":"
  for dir in ${CSGSHARE}; do
    [[ -f $dir/$1 ]] && break
  done
  IFS="$old_IFS"
  [[ -f $dir/$1 ]] && echo "$dir/$1" && return
  die "find_in_csgshare: Could not find script $1 in $CSGSHARE"
}
export -f find_in_csgshare

if [ -z "$(type -p mktemp)" ]; then
  #do not document this
  mktemp() {
    [[ -z $1 ]] && die "mktemp: missing argument"
    [[ -z ${1##*X} ]] || die "mktemp: argument has to end at least with X"
    local end trunc i l tmp newend
    end=${1##*[^X]}
    trunc=${1%${end}}
    l=${end//[^X]}
    l=${#l}
    while true; do
      newend="$end"
      for ((i=0;i<$l;i++)); do
        newend="${newend/X/${RANDOM:0:1}}"
      done
      tmp="${trunc}${newend}"
      [[ -f $tmp ]] || break
    done
    echo "$tmp"
  }
  export -f mktemp
fi

enable_logging() { #enables the logging to a certain file (1st argument) or the logfile taken from the xml file
  local log
  if [[ -z $1 ]]; then
    log="$(csg_get_property cg.inverse.log_file "inverse.log")"
  else
    log="$1"
  fi
  log="${PWD}/${log##*/}"
  export CSGLOG="$log"
  if [[ -f $CSGLOG ]]; then
    exec 3>&1 4>&2 >> "$CSGLOG" 2>&1
    echo "\n\n#################################"
    echo "# Appending to existing logfile #"
    echo "#################################\n\n"
    msg --color blue "Appending to existing logfile ${CSGLOG##*/}"
  else
    exec 3>&1 4>&2 >> "$CSGLOG" 2>&1
    msg "For a more verbose log see: ${CSGLOG##*/}"
  fi
}
export -f enable_logging

get_restart_file() { #print the name of the restart file to use
  local file
  file="$(csg_get_property cg.inverse.restart_file "restart_points.log")"
  [[ -z ${file/*\/*} ]] && die "get_restart_file: cg.inverse.restart_file has to be a local file with slash '/'"
  echo "$file"
}
export -f get_restart_file

check_for_obsolete_xml_options() { #check xml file for obsolete options
  local i
  for i in cg.inverse.mpi.tasks cg.inverse.mpi.cmd cg.inverse.parallel.tasks cg.inverse.parallel.cmd \
    cg.inverse.gromacs.mdrun.bin cg.inverse.espresso.bin; do
    [[ -z "$(csg_get_property --allow-empty $i)" ]] && continue #filter me away
    case $i in
      cg.inverse.parallel.cmd|cg.inverse.mpi.cmd)
        new="";;
      cg.inverse.mpi.tasks|cg.inverse.parallel.tasks)
        new="cg.inverse.simulation.tasks";;
      cg.inverse.gromacs.mdrun.bin|cg.inverse.espresso.bin)
        new="${i/bin/command}";;
      *)
        die "check_for_obsolete_xml_options: Unknown new name for obsolete xml option '$i'";;
    esac
    [[ -n $new ]] && new="has been renamed to $new" || new="has been removed"
    die "The xml option $i $new\nPlease remove the obsolete options from the xmlfile"
  done
}
export -f check_for_obsolete_xml_options

command_not_found_handle() { #print and error message if a command or a function was not found
  die "Command/function $1 not found (when calling from csg_call you might need to add --simprog option or set cg.inverse.program in the xml file)"
}
export -f command_not_found_handle

#in bash4 this is not needed, but for older bash we add add a failback from most important simulation functions
for i in simulation_finish checkpoint_exist get_simulation_setting; do
  eval $i\(\) { command_not_found_handle $i\; }
  eval export -f $i 
done
unset i