6#--------------------------------------------------------------------------------------
8# Utility script for zsh library functions.
10#--------------------------------------------------------------------------------------
15if [[ "$DEBUG" == "" ]]; then
16typeset -i DEBUG=0 # debug level
20export DEFAULT_OPTION=-- # default option
22if [[ -n "${BASH_SOURCE}" ]]; then
23 export ULIB_DIR=$(dirname "${BASH_SOURCE[0]}")
24elif [[ -n "${ZSH_VERSION}" ]]; then
25 export ULIB_DIR=$(dirname "${(%):-%x}")
27 export ULIB_DIR=$(dirname "${0}")
30# Wild card for any valid detector identifier or run number; to be used as ${~ANY}.
32export ANY_ID="[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]"
34export PI=3.1415926535897931
42export TIMESTAMP=\#splitline{}{\#splitline{%d-%m-%y}{\ \ %H:%M}}%F1970-01-01\ 00:00:00
44# Array of variable set / unset with set_variable / unset_variable (see below).
46typeset -A ULIB_VARIABLES
49# Array of variables with default values defined with set_variable: or set_variable+ (see below).
51typeset -A UDEF_VARIABLES
58 echo -e $RED`date` FATAL $* $RESET
61function error() { if (( $DEBUG >= 0 )); then echo -e $RED`date` ERROR $* $RESET; fi }
62function notice() { if (( $DEBUG >= 1 )); then echo -e `date` NOTICE $* ; fi }
63function status() { if (( $DEBUG >= 2 )); then echo -e `date` STATUS $* ; fi }
64function warning() { if (( $DEBUG >= 2 )); then echo -e `date` WARNING $* ; fi }
65function debug() { if (( $DEBUG >= 3 )); then echo -e `date` DEBUG $* ; fi }
69# Method to check for usage of script.
71# \param 1-N list of command line options
72# \return 0 for option -h; else 1
76 for variable in $*; do
77 if [[ "$variable" == "-h!" ]]; then
82 for variable in $*; do
83 if [[ "$variable" == "-h" || "$variable" == "-h!" ]]; then
93# Method to print usage of script and exit.
101 if (( $DEBUG >= 3 )); then
102 print_array UDEF_VARIABLES
110# Method to print environment variables.
120# The last parameter refers to the exit code.
125function check_exit_code()
127 if (( $argv[-1] )); then
137# check exit code alias
139alias CHECK_EXIT_CODE="check_exit_code \$0 \$* \$?"
145# \param 1 first value
146# \param 2 second value
148function test_equality
150 if [[ "$1" != "$2" ]]; then
159# Method to check if inside a conda env.
163 if [ -n "${CONDA_PREFIX+1}" ]; then
172# Method to check for CC Lyon.
174# \return 1 for CC Lyon; else 0
180 if [[ -n "${LOCALHOST}" && "${LOCALHOST:0:2}" = "cc" ]]; then
188# Method to check if the local host corresponds to one of the Nikhef computer clusters
190# \return 1 if local host corresponds to one of the Nikhef computer clusters; else false
192function is_CCNikhef()
196 if [[ -n "${LOCALHOST}" && "${LOCALHOST:0:4}" == "stbc" ]]; then
205# Method to define variable.
209function define_variable()
213 eval export $variable
218# Method to set variable.
219# Note that a value equal to $DEFAULT_OPTION will not modify the variable.
224function set_variable()
229 if [[ "$*" != "$DEFAULT_OPTION" ]]; then
230 eval export $variable=\"$\*\"
233 eval ULIB_VARIABLES\[$variable\]=\"\$${variable}\"
238# Method to set variable.
239# The second variable corresponds to a possible default value.
240# If this variable is defined, the first variable is set to its value
241# else to the given value(s).
247function set_variable:()
255 eval value=\"\${$optional:-"$*"}\"
257 set_variable $variable $value
259 UDEF_VARIABLES[$variable]="$optional -> $value"
264# Method to set variable.
265# The second variable corresponds to a possible default value.
266# If this variable is defined, the first variable is set to the given value(s)
267# else to an empty value.
273function set_variable+()
281 eval value=\"\${$optional+"$*"}\"
283 set_variable $variable $value
285 UDEF_VARIABLES[$variable]="$optional -> $value"
290# Method to locally set variable.
291# Note that a value equal to $DEFAULT_OPTION will not modify the variable.
296function set_local_variable()
301 if [[ "$*" != "$DEFAULT_OPTION" ]]; then
302 eval $variable=\"$\*\"
308# Method to unset variable.
312function unset_variable()
317 eval unset \"ULIB_VARIABLES\[$variable\]\"
322# Method to print variables.
324# \param 1-N list of variables
326function print_variable()
328 for variable in $*; do
329 eval value=\${$variable}
330 printf "%-20s = %s\n" ${variable} "${value}"
336# Method to print associative array.
340function print_array()
346 eval keys=\(\${\(@k\)$array}\)
349 if (( ${#key} > $len )); then
355 eval printf \"%-${len}s = %s\\n\" $key \"\$${array}\[$key\]\"
361# Method to check validity of variables.
363# \param 1-N list of variables
365function check_variable()
367 for variable in $*; do
368 eval value=$+${variable}
369 if (( ${value} == 0 )); then
370 fatal "Variable ${variable} not defined."
377# Method to set array.
387 eval $variable=\($\*\)
392# Method to expand array.
394# Tokens <first>-<last> in the array are exanded to <first> <first + 1> .. <last>
398function expand_array()
400 eval __BUFFER__=\(\$$1\[\*\]\)
404 for RANGE in $__BUFFER__[*]; do
405 for (( i = ${RANGE%%-*}; $i <= ${RANGE##*-}; i += 1 )); do
413# Method to count directory in ':' separated path list.
418function count_directory()
423 echo -n $key | tr ":" "\n" | grep "^${value}$" | wc -w
428# Method to remove directory from ':' separated path list.
433function remove_directory()
438 if [[ -n "$key" && -n "$value" ]]; then
439 export $1=`echo $key | tr ":" "\n" | grep -v "^${value}$" | tr "\n" ":" | sed 's/:\$//'`
445# Method to remove variable from ':' separated path list.
450function remove_variable()
455 if [[ -n "$key" && -n "$value" ]]; then
456 remove_directory $1 $value
462# Method to insert directory into ':' separated path list.
467function insert_directory()
471 if [[ -z "$key" ]]; then
473 elif (( `echo -n $key | tr ":" "\n" | grep "^${2}$" | wc -w` == 0 )); then
480# Method to check process path.
482# \param 1-N list of process names
484function check_process()
486 for process in $*; do
488 local bin=`which $process 2>& /dev/null`
489 debug "Check process ${process}=${bin}"
491 if [ -z "${bin}" ]; then
492 fatal "Process ${process} not found."
499# Method to check file access.
501# \param 1-N list of files
503function check_input_file()
505 if (( $# == 0 )); then
506 fatal "No input file."
509 for file in `echo $*`; do
511 debug "Check input file: ${file}"
513 if [[ ! -f ${file} ]]; then
514 fatal "File ${file} not found."
515 elif [[ ! -r ${file} ]]; then
516 fatal "File ${file} not readable."
523# Method to check file access.
525# \param 1-N list of files
527function check_output_file()
529 for file in `echo $*`; do
531 debug "Check output file: ${file}"
533 if [[ -f ${file} ]]; then
534 fatal "File ${file} already exists."
541# Method to reuse file.
542# Note that this method may require user interaction.
545# \return 1 when absent; else 0
553 if [[ ! -f $1 ]]; then
564function get_ip_address()
566 if [[ $(uname) == "Darwin" ]]; then
567 arp $(hostname) | cut -d '(' -f 2 | cut -d ')' -f 1
569 hostname --all-ip-addresses | cut --delimiter=' ' -f1
575# Get process identifier.
583 if (( $# == 1 )); then
586 if (( $# == 2 )); then
593# Method to get least significant digit.
600 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/'`
608 if [[ $(uname) == "Darwin" ]]; then
616# Method to start timer
618function timer_start()
620 let "TIMER = $(get_time)"
625# Method to stop timer
629 let "TIMER = $(get_time) - $TIMER"
634# Method to print timer
636function timer_print()
638 printf "Elapsed time %1.3f s.\n" $TIMER
643# Method to print lap time
647 printf "Elapsed time %1.3f s.\n" $(($(get_time) - $TIMER))
652# Method to convert associative array to list of equations
654# \param 1 associative array
656function make_equation()
662 eval array=\(\${\(kv\)${1}}\)
666 for key in ${(k)array}; do
667 echo -n "$key = ${array[${key}]}; "
675# Test if associative array has given key.
677# \param 1 associative array
679# \return 1 if present; else 0
690# Make communication with process.
693# - FD_O is the actual file descriptor for writing to actual process and
694# - FD_I is the actual file descriptor for reading from process.
696# \param 1 process name
697# \param 2-N optional argument(s)
705 ARGS="$*" # optional arguments
707 FIFO_O=/tmp/${PROCESS}_writing.$$ # named pipe for writing
708 FIFO_I=/tmp/${PROCESS}_reading.$$ # named pipe for reading
713 mkfifo $FIFO_O # create a new FIFO
714 mkfifo $FIFO_I # create a new FIFO
716 eval "exec {FD_O}<>$FIFO_O" # attach file descriptor to FIFO
717 eval "exec {FD_I}<>$FIFO_I" # attach file descriptor to FIFO
719 # launch process in background and cleanup afterwards
731# Remove communication with process.
733# \param 1 file descriptor for writing to process
737 if (( $# == 0 )); then
748# Write to attachted prcess.
756# Read from attachted prcess.
760 eval read $* <\& $FD_I
765# alias to kill all child processes at exit of parent process
767alias kill_child_processes_at_exit="trap 'kill_child_processes $$' EXIT"
771# recursively kill child processes for given parent identifier.
773# \param 1 parent identifier
775kill_child_processes()
779 for child in `ps --ppid $pid -ho "%p"`; do
780 kill_child_processes $child
783 if (( $pid != $$ )); then
784 kill -9 $pid >& /dev/null
789alias sftpget="$ULIB_DIR/sftpget.zsh"
790alias sftpput="$ULIB_DIR/sftpput.zsh"