6#--------------------------------------------------------------------------------------
 
    8#                   Utility script for zsh library functions.
 
   10#--------------------------------------------------------------------------------------
 
   15if [[ "$DEBUG" == "" ]]; then
 
   16typeset -i DEBUG=0                    # debug level
 
   20export DEFAULT_OPTION=--              # default option 
 
   22export ULIB_DIR=${0:h}                # ulib directory
 
   24# Wild card for any valid detector identifier or run number; to be used as ${~ANY}.
 
   26export ANY_ID="[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]"
 
   28export PI=3.1415926535897931
 
   36export 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).
 
   40typeset -A  ULIB_VARIABLES
 
   43# Array of variables with default values defined with set_variable: or set_variable+ (see below).
 
   45typeset -A  UDEF_VARIABLES
 
   52    echo -e $RED`date` FATAL   $* $RESET 
 
   55function error()   { if (( $DEBUG >= 0 )); then echo -e $RED`date` ERROR   $* $RESET; fi }
 
   56function notice()  { if (( $DEBUG >= 1 )); then echo -e     `date` NOTICE  $* ; fi }
 
   57function status()  { if (( $DEBUG >= 2 )); then echo -e     `date` STATUS  $* ; fi }
 
   58function warning() { if (( $DEBUG >= 2 )); then echo -e     `date` WARNING $* ; fi }
 
   59function 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.
 
  119function check_exit_code()
 
  121    if (( $argv[-1] )); then
 
  131# check exit code alias
 
  133alias CHECK_EXIT_CODE="check_exit_code \$0 \$* \$?"
 
  139# \param  1       first  value
 
  140# \param  2       second value
 
  142function 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
 
  186function is_CCNikhef()
 
  190    if [[ -n "${LOCALHOST}" && "${LOCALHOST:0:4}" == "stbc" ]]; then
 
  199# Method to define variable.
 
  203function 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.
 
  218function 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).
 
  241function 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.
 
  267function 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.
 
  290function set_local_variable()
 
  295    if [[ "$*" != "$DEFAULT_OPTION" ]]; then
 
  296        eval $variable=\"$\*\"
 
  302# Method to unset variable.
 
  306function unset_variable()
 
  311    eval unset \"ULIB_VARIABLES\[$variable\]\"
 
  316# Method to print variables.
 
  318# \param  1-N     list of variables
 
  320function print_variable()
 
  322    for variable in $*; do
 
  323        eval value=\${$variable}
 
  324        printf "%-20s = %s\n" ${variable} "${value}"
 
  330# Method to print associative array.
 
  334function 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
 
  359function 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.
 
  381    eval $variable=\($\*\)
 
  386# Method to expand array.
 
  388# Tokens <first>-<last> in the array are exanded to <first> <first + 1> .. <last>
 
  392function 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.
 
  412function count_directory()
 
  417    echo -n $key | tr ":" "\n" | grep "^${value}$" | wc -w
 
  422# Method to remove directory from ':' separated path list.
 
  427function 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.
 
  444function remove_variable()
 
  449    if [[ -n "$key" && -n "$value" ]]; then
 
  450        remove_directory $1 $value
 
  456# Method to insert directory into ':' separated path list.
 
  461function 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
 
  478function 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
 
  497function 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
 
  521function 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
 
  547    if   [[ ! -f $1 ]]; then    
 
  558function 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.
 
  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/'`
 
  602    if [[ $(uname) == "Darwin" ]]; then
 
  610# Method to start timer
 
  612function timer_start()
 
  614    let "TIMER = $(get_time)"
 
  619# Method to stop timer
 
  623    let "TIMER = $(get_time) - $TIMER"
 
  628# Method to print timer
 
  630function 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
 
  650function 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
 
  761alias kill_child_processes_at_exit="trap  'kill_child_processes $$'  EXIT"
 
  765# recursively kill child processes for given parent identifier.
 
  767# \param  1       parent identifier
 
  769kill_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
 
  783alias sftpget="$ULIB_DIR/sftpget.zsh"
 
  784alias sftpput="$ULIB_DIR/sftpput.zsh"