6 #--------------------------------------------------------------------------------------
 
    8 #                   Utility script for zsh library functions.
 
   10 #--------------------------------------------------------------------------------------
 
   15 if [[ "$DEBUG" == "" ]]; then
 
   16 typeset -i DEBUG=0                    # debug level
 
   20 export DEFAULT_OPTION=--              # default option 
 
   22 export ULIB_DIR=${0:h}                # ulib directory
 
   24 # Wild card for any valid detector identifier or run number; to be used as ${~ANY}.
 
   26 export ANY_ID="[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]"
 
   28 export PI=3.1415926535897931
 
   36 export TIMESTAMP=\#splitline{}{\#splitline{%d-%m-%y}{\ \ %H:%M}}%F1970-01-01\ 00:00:00
 
   38 # Array of variable set / unset with set_variable / unset_variable (see below).
 
   40 typeset -A  ULIB_VARIABLES
 
   43 # Array of variables with default values defined with set_variable: or set_variable+ (see below).
 
   45 typeset -A  UDEF_VARIABLES
 
   52     echo -e $RED`date` FATAL   $* $RESET 
 
   55 function error()   { if (( $DEBUG >= 0 )); then echo -e $RED`date` ERROR   $* $RESET; fi }
 
   56 function notice()  { if (( $DEBUG >= 1 )); then echo -e     `date` NOTICE  $* ; fi }
 
   57 function status()  { if (( $DEBUG >= 2 )); then echo -e     `date` STATUS  $* ; fi }
 
   58 function warning() { if (( $DEBUG >= 2 )); then echo -e     `date` WARNING $* ; fi }
 
   59 function debug()   { if (( $DEBUG >= 3 )); then echo -e     `date` DEBUG   $* ; fi }
 
   63 # Method to check for usage of script.
 
   65 # \param  1-N     list of command line options
 
   66 # \return         0 for option -h; else 1
 
   70     for variable in $*; do
 
   71         if [[ "$variable" == "-h!" ]]; then
 
   76     for variable in $*; do
 
   77         if [[ "$variable" == "-h" || "$variable" == "-h!" ]]; then
 
   87 # Method to print usage of script and exit.
 
   95     if (( $DEBUG >= 3 )); then
 
   96         print_array UDEF_VARIABLES
 
  104 # Method to print environment variables.
 
  114 # The last parameter refers to the exit code.
 
  119 function check_exit_code()
 
  121     if (( $argv[-1] )); then
 
  131 # check exit code alias
 
  133 alias CHECK_EXIT_CODE="check_exit_code \$0 \$* \$?"
 
  139 # \param  1       first  value
 
  140 # \param  2       second value
 
  142 function test_equality
 
  144     if [[ "$1" != "$2" ]]; then
 
  153 # Method to check if inside a conda env.
 
  157     if [ -n "${CONDA_PREFIX+1}" ]; then
 
  166 # Method to check for CC Lyon.
 
  168 # \return         1 for CC Lyon; else 0
 
  174     if [[ -n "${LOCALHOST}" && "${LOCALHOST:0:2}" =  "cc" ]]; then
 
  182 # Method to check if the local host corresponds to one of the Nikhef computer clusters
 
  184 # \return           1 if local host corresponds to one of the Nikhef computer clusters; else false
 
  186 function is_CCNikhef()
 
  190     if [[ -n "${LOCALHOST}" && "${LOCALHOST:0:4}" == "stbc" ]]; then
 
  199 # Method to define variable.
 
  203 function define_variable()
 
  207     eval export $variable
 
  212 # Method to set variable.
 
  213 # Note that a value equal to $DEFAULT_OPTION will not modify the variable.
 
  216 # \param  2-N     value(s)
 
  218 function set_variable()
 
  223     if [[ "$*" != "$DEFAULT_OPTION" ]]; then
 
  224         eval export $variable=\"$\*\"
 
  227     eval ULIB_VARIABLES\[$variable\]=\"\$${variable}\"
 
  232 # Method to set variable.
 
  233 # The second variable corresponds to a possible default value.
 
  234 # If this variable is defined, the first variable is set to its value
 
  235 # else to the given value(s).
 
  239 # \param  3-N     value(s)
 
  241 function set_variable:()
 
  249     eval value=\"\${$optional:-"$*"}\"
 
  251     set_variable $variable $value
 
  253     UDEF_VARIABLES[$variable]="$optional -> $value"
 
  258 # Method to set variable.
 
  259 # The second variable corresponds to a possible default value.
 
  260 # If this variable is defined, the first variable is set to the given value(s)
 
  261 # else to an empty value.
 
  265 # \param  3-N     value(s)
 
  267 function set_variable+()
 
  275     eval value=\"\${$optional+"$*"}\"
 
  277     set_variable $variable $value
 
  279     UDEF_VARIABLES[$variable]="$optional -> $value"
 
  284 # Method to locally set variable.
 
  285 # Note that a value equal to $DEFAULT_OPTION will not modify the variable.
 
  288 # \param  2-N     value(s)
 
  290 function set_local_variable()
 
  295     if [[ "$*" != "$DEFAULT_OPTION" ]]; then
 
  296         eval $variable=\"$\*\"
 
  302 # Method to unset variable.
 
  306 function unset_variable()
 
  311     eval unset \"ULIB_VARIABLES\[$variable\]\"
 
  316 # Method to print variables.
 
  318 # \param  1-N     list of variables
 
  320 function print_variable()
 
  322     for variable in $*; do
 
  323         eval value=\${$variable}
 
  324         printf "%-20s = %s\n" ${variable} "${value}"
 
  330 # Method to print associative array.
 
  334 function print_array()
 
  340     eval keys=\(\${\(@k\)$array}\)
 
  343         if (( ${#key} > $len )); then
 
  349         eval printf \"%-${len}s = %s\\n\" $key \"\$${array}\[$key\]\"
 
  355 # Method to check validity of variables.
 
  357 # \param  1-N     list of variables
 
  359 function check_variable()
 
  361     for variable in $*; do
 
  362         eval value=$+${variable}
 
  363         if (( ${value} == 0 )); then
 
  364             fatal "Variable ${variable} not defined."
 
  371 # Method to set array.
 
  373 # \param  1       array name
 
  381     eval $variable=\($\*\)
 
  386 # Method to expand array.
 
  388 # Tokens <first>-<last> in the array are exanded to <first> <first + 1> .. <last>
 
  390 # \param  1       array name
 
  392 function expand_array()
 
  394     eval __BUFFER__=\(\$$1\[\*\]\)
 
  398     for RANGE in $__BUFFER__[*]; do
 
  399         for (( i = ${RANGE%%-*}; $i <= ${RANGE##*-}; i += 1 )); do
 
  407 # Method to count directory in ':' separated path list.
 
  412 function count_directory()
 
  417     echo -n $key | tr ":" "\n" | grep "^${value}$" | wc -w
 
  422 # Method to remove directory from ':' separated path list.
 
  427 function remove_directory()
 
  432     if [[ -n "$key" && -n "$value" ]]; then
 
  433         export $1=`echo $key | tr ":" "\n" | grep -v "^${value}$" | tr "\n" ":" | sed 's/:\$//'`
 
  439 # Method to remove variable from ':' separated path list.
 
  444 function remove_variable()
 
  449     if [[ -n "$key" && -n "$value" ]]; then
 
  450         remove_directory $1 $value
 
  456 # Method to insert directory into ':' separated path list.
 
  461 function insert_directory()
 
  465     if [[ -z "$key" ]]; then
 
  467     elif (( `echo -n $key | tr ":" "\n" | grep "^${2}$" | wc -w` == 0 )); then
 
  474 # Method to check process path.
 
  476 # \param   1-N    list of process names
 
  478 function check_process()
 
  480     for process in $*; do
 
  482         local bin=`which $process 2>& /dev/null`
 
  483         debug "Check process ${process}=${bin}"
 
  485         if [ -z "${bin}" ]; then
 
  486             fatal "Process ${process} not found."
 
  493 # Method to check file access.
 
  495 # \param   1-N    list of files
 
  497 function check_input_file()
 
  499     if (( $# == 0 )); then
 
  500         fatal "No input file."
 
  503     for file in `echo $*`; do
 
  505         debug "Check input file: ${file}"
 
  507         if   [[ ! -f ${file} ]]; then
 
  508             fatal "File ${file} not found."
 
  509         elif [[ ! -r ${file} ]]; then
 
  510             fatal "File ${file} not readable."
 
  517 # Method to check file access.
 
  519 # \param   1-N    list of files
 
  521 function check_output_file()
 
  523     for file in `echo $*`; do
 
  525         debug "Check output file: ${file}"
 
  527         if [[ -f ${file} ]]; then
 
  528             fatal "File ${file} already exists."
 
  535 # Method to reuse file.
 
  536 # Note that this method may require user interaction.
 
  539 # \return         1 when absent; else 0
 
  541 function reuse_file()
 
  547     if   [[ ! -f $1 ]]; then    
 
  556 # Get host IP address
 
  558 function get_ip_address()
 
  560     if [[ $(uname) == "Darwin" ]]; then
 
  561       arp $(hostname) | cut -d '(' -f 2 | cut -d ')' -f 1
 
  563       hostname --all-ip-addresses | cut --delimiter=' ' -f1
 
  569 # Get process identifier.
 
  572 # \param          process name
 
  577     if (( $# == 1 )); then
 
  580     if (( $# == 2 )); then
 
  587 # Method to get least significant digit.
 
  594     printf "%f\n" `echo $1  |  sed -n "s/[+-]\?\([0-9]*.\?[0-9]*\)[1-9]\([0]*.\?\)/\1A\2/p" | sed 's/[1-9]/0/g' | sed 's/A/1/'`
 
  598 # Method to get time.
 
  602     if [[ $(uname) == "Darwin" ]]; then
 
  610 # Method to start timer
 
  612 function timer_start()
 
  614     let "TIMER = $(get_time)"
 
  619 # Method to stop timer
 
  621 function timer_stop()
 
  623     let "TIMER = $(get_time) - $TIMER"
 
  628 # Method to print timer
 
  630 function timer_print()
 
  632     printf "Elapsed time %1.3f s.\n" $TIMER
 
  637 # Method to print lap time
 
  641     printf "Elapsed time %1.3f s.\n" $(($(get_time) - $TIMER))
 
  646 # Method to convert associative array to list of equations
 
  648 # \param   1         associative array
 
  650 function make_equation()
 
  656     eval array=\(\${\(kv\)${1}}\)
 
  660     for key in ${(k)array}; do
 
  661         echo -n "$key = ${array[${key}]}; "
 
  669 # Test if associative array has given key.
 
  671 # \param   1         associative array
 
  673 # \return            1 if present; else 0
 
  684 # Make communication with process.
 
  687 #  - FD_O is the actual file descriptor for writing to actual process and
 
  688 #  - FD_I is the actual file descriptor for reading from process.
 
  690 # \param   1         process name
 
  691 # \param   2-N       optional argument(s)
 
  699     ARGS="$*"                                       # optional arguments
 
  701     FIFO_O=/tmp/${PROCESS}_writing.$$               # named pipe for writing
 
  702     FIFO_I=/tmp/${PROCESS}_reading.$$               # named pipe for reading
 
  707     mkfifo $FIFO_O                                  # create a new FIFO
 
  708     mkfifo $FIFO_I                                  # create a new FIFO
 
  710     eval "exec {FD_O}<>$FIFO_O"                     # attach file descriptor to FIFO
 
  711     eval "exec {FD_I}<>$FIFO_I"                     # attach file descriptor to FIFO
 
  713     # launch process in background and cleanup afterwards
 
  725 # Remove communication with process.
 
  727 # \param   1         file descriptor for writing to process
 
  731     if   (( $# == 0 )); then
 
  742 # Write to attachted prcess.
 
  750 # Read from attachted prcess.
 
  754     eval read $* <\& $FD_I
 
  759 # alias to kill all child processes at exit of parent process
 
  761 alias kill_child_processes_at_exit="trap  'kill_child_processes $$'  EXIT"
 
  765 # recursively kill child processes for given parent identifier.
 
  767 # \param  1       parent identifier
 
  769 kill_child_processes()
 
  773     for child in `ps --ppid $pid -ho "%p"`; do
 
  774         kill_child_processes $child
 
  777     if (( $pid != $$ )); then
 
  778         kill -9 $pid >& /dev/null
 
  783 alias sftpget="$ULIB_DIR/sftpget.zsh"
 
  784 alias sftpput="$ULIB_DIR/sftpput.zsh"