Jpp  18.4.0
the software that should make you happy
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ulib.sh
Go to the documentation of this file.
1 #!/bin/zsh
2 #
3 #
4 # \author mdejong
5 #
6 #--------------------------------------------------------------------------------------
7 #
8 # Utility script for zsh library functions.
9 #
10 #--------------------------------------------------------------------------------------
11 
12 
14 
15 if [[ "$DEBUG" == "" ]]; then
16 typeset -i DEBUG=0 # debug level
17 export DEBUG
18 fi
19 
20 export DEFAULT_OPTION=- # default option
21 
22 export ULIB_DIR=${0:h} # ulib directory
23 
24 # Wild card for any valid detector identifier or run number; to be used as ${~ANY}.
25 
26 export ANY_ID="[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]"
27 
28 export PI=3.1415926535897931
29 
30 export BLUE="\e[94m"
31 export GREEN="\e[92m"
32 export RED="\e[91m"
33 export RESET="\e[0m"
34 export BOLD="\e[1m"
35 
36 export TIMESTAMP=\#splitline{}{\#splitline{%d-%m-%y}{\ \ %H:%M}}%F1970-01-01\ 00:00:00
37 
38 # Array of variable set / unset with set_variable / unset_variable (see below).
39 
40 typeset -A ULIB_VARIABLES
41 export ULIB_VARIABLES
42 
43 # Array of variables with default values defined with set_variable: or set_variable+ (see below).
44 
45 typeset -A UDEF_VARIABLES
46 export UDEF_VARIABLES
47 
48 #
49 # debug messages
50 #
51 function fatal() {
52  echo -e $RED`date` FATAL $* $RESET
53  exit 1
54 }
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 }
60 
61 
62 #
63 # Method to check for usage of script.
64 #
65 # \param 1-N list of command line options
66 # \return 0 for option -h; else 1
67 #
68 function do_usage()
69 {
70  for variable in $*; do
71  if [[ "$variable" == "-h!" ]]; then
72  DEBUG=3
73  fi
74  done
75 
76  for variable in $*; do
77  if [[ "$variable" == "-h" || "$variable" == "-h!" ]]; then
78  return 0
79  fi
80  done
81 
82  return 1
83 }
84 
85 
86 #
87 # Method to print usage of script and exit.
88 #
89 # \param 1-N usage
90 #
91 function usage()
92 {
93  echo "$*"
94 
95  if (( $DEBUG >= 3 )); then
96  print_array UDEF_VARIABLES
97  fi
98 
99  exit
100 }
101 
102 
103 #
104 # Method to print environment variables.
105 #
106 function print_env()
107 {
108  env
109 }
110 
111 
112 #
113 # check exit code
114 # The last parameter refers to the exit code.
115 #
116 # \param 1-N message
117 # \param N exit code
118 #
119 function check_exit_code()
120 {
121  if (( $argv[-1] )); then
122  error $*
123  exit $argv[-1]
124  else
125  notice $*
126  fi
127 }
128 
129 
130 #
131 # check exit code alias
132 #
133 alias CHECK_EXIT_CODE="check_exit_code \$0 \$* \$?"
134 
135 
136 #
137 # test quality
138 #
139 # \param 1 first value
140 # \param 2 second value
141 #
142 function test_equality
143 {
144  if [[ "$1" != "$2" ]]; then
145  fatal "<$1> != <$2>"
146  else
147  debug "<$1> == <$2>"
148  fi
149 }
150 
151 
152 #
153 # Method to check if inside a conda env.
154 #
155 function has_conda()
156 {
157  if [ -n "${CONDA_PREFIX+1}" ]; then
158  return 0
159  else
160  return 1
161  fi
162 }
163 
164 
165 #
166 # Method to check for CC Lyon.
167 #
168 # \return 1 for CC Lyon; else 0
169 #
170 function is_CCLyon()
171 {
172  LOCALHOST=`hostname`
173 
174  if [[ -n "${LOCALHOST}" && "${LOCALHOST:0:2}" = "cc" ]]; then
175  return 0
176  else
177  return 1
178  fi
179 }
180 
181 
182 # Method to check if the local host corresponds to one of the Nikhef computer clusters
183 #
184 # \return 1 if local host corresponds to one of the Nikhef computer clusters; else false
185 #
186 function is_CCNikhef()
187 {
188  LOCALHOST=`hostname`
189 
190  if [[ -n "${LOCALHOST}" && "${LOCALHOST:0:4}" == "stbc" ]]; then
191  return 0
192  else
193  return 1
194  fi
195 }
196 
197 
198 #
199 # Method to define variable.
200 #
201 # \param 1 variable
202 #
203 function define_variable()
204 {
205  local variable=$1
206 
207  eval export $variable
208 }
209 
210 
211 #
212 # Method to set variable.
213 # Note that a value equal to $DEFAULT_OPTION will not modify the variable.
214 #
215 # \param 1 variable
216 # \param 2-N value(s)
217 #
218 function set_variable()
219 {
220  local variable=$1
221  shift
222 
223  if [[ "$*" != "$DEFAULT_OPTION" ]]; then
224  eval export $variable=\"$\*\"
225  fi
226 
227  eval ULIB_VARIABLES\[$variable\]=\"\$${variable}\"
228 }
229 
230 
231 #
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).
236 #
237 # \param 1 variable
238 # \param 2 variable
239 # \param 3-N value(s)
240 #
241 function set_variable:()
242 {
243  local variable=$1
244  shift
245 
246  local optional=$1
247  shift
248 
249  eval value=\"\${$optional:-"$*"}\"
250 
251  set_variable $variable $value
252 
253  UDEF_VARIABLES[$variable]="$optional -> $value"
254 }
255 
256 
257 #
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.
262 #
263 # \param 1 variable
264 # \param 2 variable
265 # \param 3-N value(s)
266 #
267 function set_variable+()
268 {
269  local variable=$1
270  shift
271 
272  local optional=$1
273  shift
274 
275  eval value=\"\${$optional+"$*"}\"
276 
277  set_variable $variable $value
278 
279  UDEF_VARIABLES[$variable]="$optional -> $value"
280 }
281 
282 
283 #
284 # Method to locally set variable.
285 # Note that a value equal to $DEFAULT_OPTION will not modify the variable.
286 #
287 # \param 1 variable
288 # \param 2-N value(s)
289 #
290 function set_local_variable()
291 {
292  local variable=$1
293  shift
294 
295  if [[ "$*" != "$DEFAULT_OPTION" ]]; then
296  eval $variable=\"$\*\"
297  fi
298 }
299 
300 
301 #
302 # Method to unset variable.
303 #
304 # \param 1 variable
305 #
306 function unset_variable()
307 {
308  local variable=$1
309 
310  eval unset $variable
311  eval unset \"ULIB_VARIABLES\[$variable\]\"
312 }
313 
314 
315 #
316 # Method to print variables.
317 #
318 # \param 1-N list of variables
319 #
320 function print_variable()
321 {
322  for variable in $*; do
323  eval value=\${$variable}
324  printf "%-20s = %s\n" ${variable} "${value}"
325  done
326 }
327 
328 
329 #
330 # Method to print associative array.
331 #
332 # \param 1 array
333 #
334 function print_array()
335 {
336  array=$1
337 
338  len=0
339 
340  eval keys=\(\${\(@k\)$array}\)
341 
342  for key in $keys; do
343  if (( ${#key} > $len )); then
344  len=${#key}
345  fi
346  done
347 
348  for key in $keys; do
349  eval printf \"%-${len}s = %s\\n\" $key \"\$${array}\[$key\]\"
350  done
351 }
352 
353 
354 #
355 # Method to check validity of variables.
356 #
357 # \param 1-N list of variables
358 #
359 function check_variable()
360 {
361  for variable in $*; do
362  eval value=$+${variable}
363  if (( ${value} == 0 )); then
364  fatal "Variable ${variable} not defined."
365  fi
366  done
367 }
368 
369 
370 #
371 # Method to set array.
372 #
373 # \param 1 array name
374 # \param 2-N values
375 #
376 function set_array()
377 {
378  local variable=$1
379  shift
380 
381  eval $variable=\($\*\)
382 }
383 
384 
385 #
386 # Method to expand array.
387 #
388 # Tokens <first>-<last> in the array are exanded to <first> <first + 1> .. <last>
389 #
390 # \param 1 array name
391 #
392 function expand_array()
393 {
394  eval __BUFFER__=\(\$$1\[\*\]\)
395 
396  eval $1=\(\)
397 
398  for RANGE in $__BUFFER__[*]; do
399  for (( i = ${RANGE%%-*}; $i <= ${RANGE##*-}; i += 1 )); do
400  eval $1+=\($i\)
401  done
402  done
403 }
404 
405 
406 #
407 # Method to count directory in ':' separated path list.
408 #
409 # \param 1 path list
410 # \param 2 directory
411 #
412 function count_directory()
413 {
414  eval key=\${$1}
415 
416  echo -n $key | tr ":" "\n" | grep "^\\${2}$" | wc -w
417 }
418 
419 
420 #
421 # Method to remove directory from ':' separated path list.
422 #
423 # \param 1 path list
424 # \param 2 directory
425 #
426 function remove_directory()
427 {
428  eval key=\${$1}
429  eval value=$2
430 
431  if [[ -n "$key" && -n "$value" ]]; then
432  export $1=`eval echo $key | tr ":" "\n" | grep -v "^\\\\${value}$" | tr "\n" ":" | sed 's/:\$//'`
433  fi
434 }
435 
436 
437 #
438 # Method to remove variable from ':' separated path list.
439 #
440 # \param 1 path list
441 # \param 2 variable
442 #
443 function remove_variable()
444 {
445  eval key=\${$1}
446  eval value=\${$2}
447 
448  if [[ -n "$key" && -n "$value" ]]; then
449  remove_directory $1 $value
450  fi
451 }
452 
453 
454 #
455 # Method to insert directory into ':' separated path list.
456 #
457 # \param 1 path list
458 # \param 2 directory
459 #
460 function insert_directory()
461 {
462  eval key=\${$1}
463 
464  if [[ -z "$key" ]]; then
465  export $1=$2
466  elif (( `eval echo -n $key | tr ":" "\n" | grep "^\\\\${2}$" | wc -w` == 0 )); then
467  export $1=$2:${key}
468  fi
469 }
470 
471 
472 #
473 # Method to check process path.
474 #
475 # \param 1-N list of process names
476 #
477 function check_process()
478 {
479  for process in $*; do
480 
481  local bin=`which $process 2>& /dev/null`
482  debug "Check process ${process}=${bin}"
483 
484  if [ -z "${bin}" ]; then
485  fatal "Process ${process} not found."
486  fi
487  done
488 }
489 
490 
491 #
492 # Method to check file access.
493 #
494 # \param 1-N list of files
495 #
496 function check_input_file()
497 {
498  if (( $# == 0 )); then
499  fatal "No input file."
500  fi
501 
502  for file in `echo $*`; do
503 
504  debug "Check input file: ${file}"
505 
506  if [[ ! -f ${file} ]]; then
507  fatal "File ${file} not found."
508  elif [[ ! -r ${file} ]]; then
509  fatal "File ${file} not readable."
510  fi
511  done
512 }
513 
514 
515 #
516 # Method to check file access.
517 #
518 # \param 1-N list of files
519 #
520 function check_output_file()
521 {
522  for file in `echo $*`; do
523 
524  debug "Check output file: ${file}"
525 
526  if [[ -f ${file} ]]; then
527  fatal "File ${file} already exists."
528  fi
529  done
530 }
531 
532 
533 #
534 # Method to reuse file.
535 # Note that this method may require user interaction.
536 #
537 # \param 1 file name
538 # \return 1 when absent; else 0
539 #
540 function reuse_file()
541 {
542  if [[ -f $1 ]]; then
543  rm -i $1
544  fi
545 
546  if [[ ! -f $1 ]]; then
547  return 1
548  else
549  return 0
550  fi
551 }
552 
553 
554 #
555 # Get host IP address
556 #
557 function get_ip_address()
558 {
559  hostname --all-ip-addresses | cut --delimiter=' ' -f1
560 }
561 
562 
563 #
564 # Get process identifier.
565 #
566 # \param [hostname]
567 # \param process name
568 # \return PID
569 #
570 function get_pid()
571 {
572  if (( $# == 1 )); then
573  exec ps h -o "%p" -C $1
574  elif (( $# == 2 )); then
575  exec ssh $1 "ps h -o "%p" -C $2"
576  fi
577 }
578 
579 
580 #
581 # Method to get least significant digit.
582 #
583 # \param value
584 # \return value
585 #
586 function getLSD()
587 {
588  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/'`
589 }
590 
591 
592 #
593 # Method to start timer
594 #
595 function timer_start()
596 {
597  let "TIMER = $(date +%s.%N)"
598 }
599 
600 
601 #
602 # Method to stop timer
603 #
604 function timer_stop()
605 {
606  let "TIMER = $(date +%s.%N) - $TIMER"
607 }
608 
609 
610 #
611 # Method to print timer
612 #
613 function timer_print()
614 {
615  printf "Elapsed time %1.3f s.\n" $TIMER
616 }
617 
618 
619 #
620 # Method to print lap time
621 #
622 function timer_lap()
623 {
624  printf "Elapsed time %1.3f s.\n" $(($(date +%s.%N) - $TIMER))
625 }
626 
627 
628 #
629 # Method to convert associative array to list of equations
630 #
631 # \param 1 associative array
632 #
633 function make_equation()
634 {
635  local array
636 
637  typeset -A array
638 
639  eval array=\(\${\(kv\)${1}}\)
640 
641  echo -n "\""
642 
643  for key in ${(k)array}; do
644  echo -n "$key = ${array[${key}]}; "
645  done
646 
647  echo "\""
648 }
649 
650 
651 #
652 # Test if associative array has given key.
653 #
654 # \param 1 associative array
655 # \param 2 key
656 # \return 1 if present; else 0
657 #
658 has_key()
659 {
660  local var="${1}[$2]"
661 
662  echo ${(P)+${var}}
663 }
664 
665 
666 #
667 # Make communication with process.
668 #
669 # Note that:
670 # - FD_O is the actual file descriptor for writing to actual process and
671 # - FD_I is the actual file descriptor for reading from process.
672 #
673 # \param 1 process name
674 # \param 2-N optional argument(s)
675 #
676 function attach()
677 {
678  PROCESS=$1 # process
679 
680  shift
681 
682  ARGS="$*" # optional arguments
683 
684  FIFO_O=/tmp/${PROCESS}_writing.$$ # named pipe for writing
685  FIFO_I=/tmp/${PROCESS}_reading.$$ # named pipe for reading
686 
687  rm -f $FIFO_O
688  rm -f $FIFO_I
689 
690  mkfifo $FIFO_O # create a new FIFO
691  mkfifo $FIFO_I # create a new FIFO
692 
693  eval "exec {FD_O}<>$FIFO_O" # attach file descriptor to FIFO
694  eval "exec {FD_I}<>$FIFO_I" # attach file descriptor to FIFO
695 
696  # launch process in background and cleanup afterwards
697 
698  eval \($PROCESS \
699  $ARGS \
700  \< $FIFO_O \
701  \> $FIFO_I \&\& \
702  rm -f $FIFO_O \&\& \
703  rm -f $FIFO_I\) \&
704 }
705 
706 
707 #
708 # Remove communication with process.
709 #
710 # \param 1 file descriptor for writing to process
711 #
712 function detach()
713 {
714  if (( $# == 0 )); then
715  FD=$FD_O
716  else
717  FD=$1
718  fi
719 
720  print -u $FD "^D"
721 }
722 
723 
724 #
725 # Write to attachted prcess.
726 #
727 function sput()
728 {
729  print -u $FD_O "$*"
730 }
731 
732 #
733 # Read from attachted prcess.
734 #
735 function sget()
736 {
737  eval read $* \<\& $FD_I
738 }
739 
740 
741 #
742 # alias to kill all child processes at exit of parent process
743 #
744 alias kill_child_processes_at_exit="trap 'kill_child_processes $$' EXIT"
745 
746 
747 #
748 # recursively kill child processes for given parent identifier.
749 #
750 # \param 1 parent identifier
751 #
752 kill_child_processes()
753 {
754  local pid=$1
755 
756  for child in `ps --ppid $pid -ho "%p"`; do
757  kill_child_processes $child
758  done
759 
760  if (( $pid != $$ )); then
761  kill -9 $pid >& /dev/null
762  fi
763 }
764 
765 
766 alias sftpget="$ULIB_DIR/sftpget.zsh"
767 alias sftpput="$ULIB_DIR/sftpput.zsh"
then usage $script< detector identifier >< startdate\"YYYY-MM-DDHH:MM:SS\"><finaldate\"YYYY-MM-DDHH:MM:SS\"><QA/QCfile> fi case set_variable QAQC_TXT $argv[4]
Definition: JDataMonitor.sh:24
#define WARNING(A)
Definition: JMessage.hh:65
then fatal No hydrophone data file $HYDROPHONE_TXT fi sort gr k
std::istream & read(std::istream &in, JTestSummary &summary, const char delimiter= ' ')
Read test summary.
then usage $script[< detector identifier >< run range >]< QA/QCfile > nExample script to produce data quality plots nWhen a detector identifier and run range are data are downloaded from the database nand subsequently stored in the given QA QC file
Definition: JDataQuality.sh:19
version
Definition: JEditTuneHV.sh:5
#define STATUS(A)
Definition: JMessage.hh:63
o $QUALITY_ROOT d $DEBUG!CHECK_EXIT_CODE JPlot1D f
Definition: JDataQuality.sh:76
*fatal Wrong number of arguments
static const double H
Planck constant [eV s].
exit
Definition: JPizza.sh:36
then
Definition: datalogs.sh:31
then fatal Wrong number of arguments fi JConvertDetectorFormat a o
then echo Detector $DETECTOR aleady exists
static const double C
Physics constants.
const int n
Definition: JPolint.hh:786
then rm
Definition: sftpput.zsh:30
then JCalibrateToT a
Definition: JTuneHV.sh:113
#define NOTICE(A)
Definition: JMessage.hh:64
#define ERROR(A)
Definition: JMessage.hh:66
then echo Variable JPP_DIR undefined exit fi source $JPP_DIR setenv sh $JPP_DIR &dev null set_variable
static const double PI
Mathematical constants.
* usage
print
Definition: JConvertDusj.sh:44
#define FATAL(A)
Definition: JMessage.hh:67
then usage $script< directory A >< directoryB > nIn each directory
then usage $script< input file >[option[primary[working directory]]] nWhere option can be N
Definition: JMuonPostfit.sh:40
then JMuonMCEvt f $INPUT_FILE o $INTERMEDIATE_FILE d
Definition: JMuonPath.sh:47
Q FIFO
Definition: JDataQuality.sh:61
then fatal Wrong number of arguments fi set_variable DETECTOR $argv[1] set_variable INPUT_FILE $argv[2] eval JPrintDetector a $DETECTOR O IDENTIFIER eval JPrintDetector a $DETECTOR O SUMMARY JAcoustics sh $DETECTOR_ID source JAcousticsToolkit sh CHECK_EXIT_CODE typeset A EMITTERS get_tripods $WORKDIR tripod txt EMITTERS get_transmitters $WORKDIR transmitter txt EMITTERS for EMITTER in
Definition: JCanberra.sh:48
double u[N+1]
Definition: JPolint.hh:865
then echo
Definition: JQAQC.sh:90
static const char *const TIMESTAMP
Time stamp of earliest UTC time.
source $JPP_DIR setenv csh $JPP_DIR &dev null eval JShellParser o a A
*set_variable DETECTOR_FILE set_array INPUT_FILES $argv[2,-3] set_variable WORKDIR $argv[-2] set_variable PMT_PARAMETER_FILE $argv[-1] esac let TIMER
Definition: JTuneHV.sh:50
esac $JPP_BIN JLogger sh $LOGGER until pgrep JGetMessage</dev/null > dev null
int debug
debug level
then $DIR JPlotNPE PDG P
Definition: JPlotNPE-PDG.sh:62
esac done
Definition: JAddHDE.sh:21
#define DEBUG(A)
Message macros.
Definition: JMessage.hh:62