#!/bin/bash # # PatchControl # # This script helps the shifter to easily operate both the line and # the DAQ processes until the ControlUnit will be finalised. # # Author: Carmelo Pellegrino <carmelo.pellegrino@bo.infn.it> # # The configuration of this very script is perfomed via shell variables. # Here the list of parameters is reported # # DM_EXE_DIR -> the absolute path of the folder which contains DetectorControl.exe # DM_DATA_DIR -> the absolute path of the folder which contains the detectorfile # PC_CONF_DIR -> the absolute path of the pc.cfg configuration file # DAQ_SERVER -> IP address of the DAQ Server # DAQ_USER -> user name on the DAQ Server SELF_PIPE_PORT=45757 function log() { [ ! -d ${HOME}/.km3_private ] && mkdir -p ${HOME}/.km3_private local logfile="${HOME}/.km3_private/pc.log" echo "$(date): ${*}" >>${logfile} } function check_config() { local missing=() [ -n "${DM_EXE_DIR+x}" ] || missing+=(DM_EXE_DIR) [ -n "${DM_DATA_DIR+x}" ] || missing+=(DM_DATA_DIR) [ -n "${PC_CONF_DIR+x}" ] || missing+=(PC_CONF_DIR) [ -n "${DAQ_SERVER+x}" ] || missing+=(DAQ_SERVER) [ -n "${DAQ_USER+x}" ] || missing+=(DAQ_USER) [ -n "${DETECTOR_ID+x}" ] || missing+=(DETECTOR_ID) if [ ! ${#missing} -eq 0 ]; then zenity --error \ --title "Error (at $(date))" \ --text "The following configuration environment variables are missing:\n${missing[*]}\nPlease set them before run again this program." return 1 fi return 0 } function put_lock() { touch /tmp/pc.lock } function rm_lock() { unlink /tmp/pc.lock } function test_lock() { if [ -e /tmp/pc.lock ]; then return 1 else return 0 fi } function on_exit() { if [ "${LOCK_OWNER}" == "True" ]; then rm_lock fi local pid for pid in ${PROCS[*]}; do kill -9 ${pid} done unset pid log "Quit" } function get_run_setup_file() { local LIST=() local line while IFS=';' read -ra line; do LIST+=("FALSE" "${line[@]}") done < ${PC_CONF_DIR}/pc.cfg zenity --title "Run Setup Selector (at $(date))" \ --list \ --text "Select one of the following Run Setups:" \ --radiolist \ --width=600 \ --height=400 \ --column="Selection" \ --column="Run Setup file" \ --column="Run Setup name" \ --column="Description" \ --hide-column=2 "${LIST[@]}" } function dm_driver() { echo "set session target = On" echo "set session target = Run" sleep $1 echo "set session target = Off" nc -l ${SELF_PIPE_PORT} 2>/dev/null 1>/dev/null echo exit echo y } function nowUTC() { # print the number of seconds elapsed since Jan 1 1970 00:00 in UTC date -u +%s } function get_run_number() { [ ! -d ~/.km3_private ] && mkdir -p ~/.km3_private [ ! -e ~/.km3_private/last_run_number ] && echo 0 >~/.km3_private/last_run_number local last_run_number=`cat ~/.km3_private/last_run_number` local run_number let "run_number = ${last_run_number} + 1" echo ${run_number} > ~/.km3_private/last_run_number echo ${run_number} } # Script begins here check_config || exit 1 test_lock || { zenity --error --text="There is another instance running of this program." --title="Error (at $(date))"; exit 1;} put_lock LOCK_OWNER="True" trap on_exit EXIT while [ 1 ]; do # Ask for the run setup rs_file=`get_run_setup_file` if [ -z "${rs_file}" ]; then zenity --error --text="No Run Setup file selected, aborting" --title="Error (at $(date))" exit -1 fi # Ask for run duration run_duration=`zenity --title "Run duration (at $(date))" \ --list \ --text "Select one of the following duration:" \ --radiolist \ --column="Selection" \ --column="Minutes" \ --column="Duration" \ --hide-column=2 \ --cancel-label=Back \ FALSE 5 "5 minutes" TRUE 10 "10 minutes" FALSE 20 "20 minutes" FALSE 240 "4 hours" FALSE 480 "8 hours" FALSE 900 "15 hours"` if [ "${run_duration}" == "" ]; then continue fi # Ask for duty cycle duty_cycle=`zenity --list \ --title "oDF' duty cycle (at $(date))" \ --text "Select one of the following duty cycles:" \ --radiolist \ --column="Selection" \ --column="N" \ --column="Duty cycle" \ --hide-column=2 \ --cancel-label=Back \ TRUE 1 100% FALSE 2 50% FALSE 10 10% FALSE 20 5% FALSE 50 2%` if [ "${duty_cycle}" == "" ]; then continue fi break done # Wait 10 seconds i=0; while [ $i -lt 100 ]; do let "i = $i + 10" echo $i sleep 1 done | zenity --progress \ --auto-close \ --text="You have 10 seconds to cancel the current operation:\nrunsetup: ${rs_file}\nduration: ${run_duration} minutes\nduty cycle: 1/${duty_cycle}" \ --auto-kill # Peak the run number run_number=`get_run_number` ROOT_FILE=`printf "KM3NeT_%08d.root" ${run_number}` ssh ${DAQ_USER}@${DAQ_SERVER} "[ -e ${ROOT_FILE} ]" && { log "A root file for the current run already exists. Run ${run_number} canceled." zenity --error --text="A root file for the current run already exists. Run ${run_number} canceled." --title="Error (at $(date))" exit 1 } let "run_duration_seconds = ${run_duration} * 60" declare -a PROCS daq_log_file=~/.km3_private/daq_`printf "%08d" ${run_number}`.log JGetMessage -H ${DAQ_SERVER} -T MSG -d 3 >${daq_log_file} & PROCS+=($!) # Copy selected run setup file, changing the run number cat ${rs_file} | sed -e "s/RUNNUMBER/${run_number}/" >${DM_DATA_DIR}/dm.detectorfile run_start_time=`nowUTC` log "Run ${run_number} ready to start. \ Run start time = ${run_start_time}, \ run duration = ${run_duration} minutes, \ duty cycle = 1 / ${duty_cycle}, \ run setup file = ${rs_file}." # Launch the DAQ log "Launching the DAQ with the following command line: daq.sh ${run_number} ${run_start_time} ${run_duration_seconds} ${DAQ_SERVER} ${DAQ_USER} ${duty_cycle}" daq_driver_log_file=~/.km3_private/daq_driver_`printf "%08d" ${run_number}`.log daq.sh ${run_number} ${DETECTOR_ID} ${run_start_time} ${run_duration_seconds} ${DAQ_SERVER} ${DAQ_USER} ${duty_cycle} >${daq_driver_log_file} & DAQ_PROC_ID=$! PROCS+=(${DAQ_PROC_ID}) # Launch the DM dm_driver ${run_duration_seconds} | mono ${DM_EXE_DIR}/DetectorControl.exe --control --reset --jollytoken jollyroger & PROCS+=($!) # Put notification mark in the system tray zenity --notification --text="Run ${run_number} is on going." & PROCS+=($!) # Point the browser to the correct address, if required zenity --question \ --text="Would you like to open the DetectorManager GUI?" \ --title="Question (at $(date))" \ --cancel-label="No, thanks" && firefox http://localhost:8102/gui/main.htm & PROCS+=($!) # Wait the end of the run end_run_time=`nowUTC` let "end_run_time=${end_run_time} + ${run_duration_seconds}" while [ `nowUTC` -lt ${end_run_time} ]; do let "eta=${end_run_time} - `nowUTC`" notify-send "Run ${run_number} is on going. It will end in ${eta} seconds. Total run duration: ${run_duration} minutes." sleep 10 done wait ${DAQ_PROC_ID} log "Run ${run_number} finished." echo quit | nc localhost ${SELF_PIPE_PORT} zenity --info --text="Run ${run_number} finished at $(date)! The DAQ log file is located in ${daq_log_file}." --title="Info (at $(date))" exit 0