#!/bin/sh
#
# process_hour.sh
#
# Collect Q transform based analysis results for one hour of science mode data.
#
# usage:
#
#   process_hour.sh startTime [triggers] [event] [properties] [report]
#
# The requested startTime may be in GPS seconds or a format understood
# by the LIGOTools tconvert utility.
#
# The remaining optional arguments specify whether or not trigger production,
# a qscan of the loudest event, plots of trigger properties, or an html report
# is produced.  By default nothing is produced.

# Shourov K. Chatterji
# shourov@ligo.caltech.edu

# $Id: process_hour.sh,v 1.17 2007/08/25 11:03:15 shourov Exp $

################################################################################
#                              Setup environment                               #
################################################################################

# change to directory containing this script
cd `dirname $0`

# path to Q transform installation
Q=../..

# setup environment
. ${Q}/bin/qsetup.sh

################################################################################
#                            Command line arguments                            #
################################################################################

# usage information
if [ $# -eq 0 ]; then
  echo "usage: `basename $0` startTime [triggers] [event] [properties] [report]" 1>&2
  exit 1
fi

# analysis start time
echo "$1" | grep -qv [^0-9] >/dev/null
if [ $? -eq 0 ]; then
   startTime="$1"
else
   startTime=`tconvert "$1"`
fi

# requested products
if [ $# -gt 1 ]; then
  shift 1
  requested="$*"
else
  requested=""
fi

################################################################################
#                              Timing information                              #
################################################################################

# analysis time string truncated to nearest hour
startYear=`tconvert -f "%Y" ${startTime}`
startMonth=`tconvert -f "%m" ${startTime}`
startDay=`tconvert -f "%d" ${startTime}`
startHour=`tconvert -f "%H" ${startTime}`
startTimeString=`tconvert -f "%Y-%m-%d %H:00:00" ${startTime}`

# analysis start time truncated to nearest hour
startTime=`tconvert "${startTimeString}"`

# analysis duration in hours
analysisDuration="1"

# analysis stop time
stopTime=`expr ${startTime} + 3600 \* ${analysisDuration}`

# minimum segment duration in seconds
minimumSegmentDuration=`grep blockDuration parameters.txt | \
                        awk ' { print int($2) } '`

# append minimum segment duration to analysis stop time
stopTime=`expr ${stopTime} + ${minimumSegmentDuration}`

# time of previous hour
previousHour=`tconvert "${startYear}-${startMonth}-${startDay} \
                        ${startHour}:00:00 UTC" - \
                ${analysisDuration}hour`
previousHourYear=`tconvert -f "%Y" ${previousHour}`
previousHourMonth=`tconvert -f "%m" ${previousHour}`
previousHourDay=`tconvert -f "%d" ${previousHour}`
previousHourHour=`tconvert -f "%H" ${previousHour}`

# time of next hour
nextHour=`tconvert "${startYear}-${startMonth}-${startDay} \
                    ${startHour}:00:00 UTC" + \
            ${analysisDuration}hour`
nextHourYear=`tconvert -f "%Y" ${nextHour}`
nextHourMonth=`tconvert -f "%m" ${nextHour}`
nextHourDay=`tconvert -f "%d" ${nextHour}`
nextHourHour=`tconvert -f "%H" ${nextHour}`

# time of previous day
previousDay=`tconvert "${startYear}-${startMonth}-${startDay} \
                       00:00:00 UTC" - 1day`
previousDayYear=`tconvert -f "%Y" ${previousDay}`
previousDayMonth=`tconvert -f "%m" ${previousDay}`
previousDayDay=`tconvert -f "%d" ${previousDay}`

# time of next day
nextDay=`tconvert "${startYear}-${startMonth}-${startDay} \
                   00:00:00 UTC" + 1day`
nextDayYear=`tconvert -f "%Y" ${nextDay}`
nextDayMonth=`tconvert -f "%m" ${nextDay}`
nextDayDay=`tconvert -f "%d" ${nextDay}`

################################################################################
#                             Detector information                             #
################################################################################

# gravitational wave channel name
# *** THIS NEEDS TO BE UPDATED TO HANDLE MULTIPLE DETECTORS ***
channelName=`grep channelName parameters.txt | \
             awk ' { print $2 } ' | sed -e "s|[{}']||g"`

# interferometer identifier
# *** THIS NEEDS TO BE UPDATED TO HANDLE MULTIPLE DETECTORS ***
interferometer=`echo ${channelName} | sed -e 's|:.*$||'`

################################################################################
#                             Directory structure                              #
################################################################################

# day directory name
dayDirectory="${startYear}/${startMonth}/${startDay}"

# hour directory name
hourDirectory="${dayDirectory}/${startHour}"

# create output directory
mkdir -p ${hourDirectory}

# initialize log file
date -u +"%Y-%m-%d %H:%M:%S %Z" >>${hourDirectory}/log.txt

################################################################################
#                              Trigger production                              #
################################################################################

# begin if triggers requested
if [ -n "`echo ${requested} | grep -e triggers`" ]; then

  # copy parameter file
  echo "copying parameter file..." >>${hourDirectory}/log.txt
  cp parameters.txt ${hourDirectory}/parameters.txt

  # determine science mode segments
  echo "getting science mode segments..." >>${hourDirectory}/log.txt
  getsegments.sh ${interferometer} ${startTime} ${stopTime} \
    >${hourDirectory}/segments.txt

  # collect triggers
  echo "collecting triggers..." >>${hourDirectory}/log.txt
  cat ${hourDirectory}/*/triggers.txt \
    >${hourDirectory}/triggers.txt 2>/dev/null

  # down-select triggers
  echo "down-selecting triggers..." >>${hourDirectory}/log.txt
  ${Q}/postprocess/bin/select ${hourDirectory}/triggers.txt \
                              ${hourDirectory}/triggers.txt.tmp
  mv ${hourDirectory}/triggers.txt.tmp ${hourDirectory}/triggers.txt

  # cluster triggers
  echo "clustering triggers..." >>${hourDirectory}/log.txt
  ${Q}/postprocess/bin/select 1.0 \
                              ${hourDirectory}/triggers.txt \
                              ${hourDirectory}/clusters.txt

  # sort triggers by time
  sort -g ${hourDirectory}/triggers.txt >${hourDirectory}/triggers.txt.tmp
  sort -g ${hourDirectory}/clusters.txt >${hourDirectory}/clusters.txt.tmp
  mv ${hourDirectory}/triggers.txt.tmp ${hourDirectory}/triggers.txt
  mv ${hourDirectory}/clusters.txt.tmp ${hourDirectory}/clusters.txt

  # collect livetimes
  echo "collecting livetimes..." >>${hourDirectory}/log.txt
  cat ${hourDirectory}/*/livetime.txt 2>/dev/null | sort -g \
    >${hourDirectory}/livetime.txt

  # merge livetimes
  echo "merging livetimes..." >>${hourDirectory}/log.txt
  segexpr ${hourDirectory}/livetime.txt ${hourDirectory}/livetime.txt.tmp
  mv ${hourDirectory}/livetime.txt.tmp ${hourDirectory}/livetime.txt

# end if triggers requested
fi

################################################################################
#                           Loudest event properties                           #
################################################################################

# begin if loudest event qscan, trigger properties, or html report requested
if [ -n "`echo ${requested} | grep -e event -e properties -e report`" ]; then

  # find loudest event
  echo "finding loudest event..." >>${hourDirectory}/log.txt
  loudestEventProperties=`sort -gk 5,5 ${hourDirectory}/clusters.txt \
                          2>/dev/null | tail -n 1`
  if [ -n "${loudestEventProperties}" ]; then
    loudestEventTime=`echo ${loudestEventProperties} | awk ' { print $1 } '`
    loudestEventFrequency=`echo ${loudestEventProperties} | awk ' { print $2 } '`
    loudestEventDuration=`echo ${loudestEventProperties} | awk ' { print $3 } '`
    loudestEventBandwidth=`echo ${loudestEventProperties} | awk ' { print $4 } '`
    loudestEventSNR=`echo ${loudestEventProperties} | awk ' { printf "%9.3e", sqrt(2 * $5) } '`
  fi

# retrieve loudest event spectrogram
rm -f ${hourDirectory}/loudestevent_thumbnail.png
if [ -n "${loudestEventProperties}" ]; then
  echo "retrieving loudest event spectrogram..." >>${hourDirectory}/log.txt
  loudestEventMinutes=`tconvert -f "%M" ${loudestEventTime} | \
                       awk ' { printf "%02d", $1 - $1 % 10 } '`
  cp ${hourDirectory}/${loudestEventMinutes}/loudestevent_thumbnail.png \
     ${hourDirectory}/loudestevent_thumbnail.png
fi

# end if loudest event qscan, trigger properties, or html report requested
fi

################################################################################
#                              Trigger properties                              #
################################################################################

# begin if trigger properties requested
if [ -n "`echo ${requested} | grep -e properties`" ]; then

  # produce trigger properties
  # *** THIS NEEDS TO BE UPDATED TO HANDLE MULTIPLE DETECTORS ***
  echo "plotting trigger properties..." >>${hourDirectory}/log.txt
  ${Q}/bin/qproperties.sh ${startTime} ${stopTime} \
                          ${hourDirectory}/parameters.txt \
                          ${hourDirectory}/triggers.txt \
                          ${hourDirectory}/clusters.txt \
                          ${hourDirectory}/livetime.txt \
                          ${channelName} \
                          ${hourDirectory}/properties

# end if trigger properties requested
fi

################################################################################
#                                 HTML report                                  #
################################################################################

# begin if html report requested
if [ -n "`echo ${requested} | grep -e report`" ]; then

  # current time stamp
  currentTime=`date -u "+%Y-%m-%d %H:%M:%S %Z"`

  # create hour html report
  echo "creating html report..." >>${hourDirectory}/log.txt
  rm -f ${hourDirectory}/style.css
  ln -s ../../../../style.css ${hourDirectory}/style.css
  sed -e "s|\[START_YEAR\]|${startYear}|g" \
      -e "s|\[START_MONTH\]|${startMonth}|g" \
      -e "s|\[START_DAY\]|${startDay}|g" \
      -e "s|\[START_HOUR\]|${startHour}|g" \
      -e "s|\[PREVIOUSHOUR_YEAR\]|${previousHourYear}|g" \
      -e "s|\[PREVIOUSHOUR_MONTH\]|${previousHourMonth}|g" \
      -e "s|\[PREVIOUSHOUR_DAY\]|${previousHourDay}|g" \
      -e "s|\[PREVIOUSHOUR_HOUR\]|${previousHourHour}|g" \
      -e "s|\[NEXTHOUR_YEAR\]|${nextHourYear}|g" \
      -e "s|\[NEXTHOUR_MONTH\]|${nextHourMonth}|g" \
      -e "s|\[NEXTHOUR_DAY\]|${nextHourDay}|g" \
      -e "s|\[NEXTHOUR_HOUR\]|${nextHourHour}|g" \
      -e "s|\[CURRENT_TIME\]|${currentTime}|g" \
      -e "s|\[ANALYSIS_DURATION\]|${analysisDuration}|g" \
      -e "s|\[INTERFEROMETER\]|${interferometer}|g" \
      -e "s|\[LOUDEST_EVENT_TIME\]|${loudestEventTime}|g" \
      -e "s|\[LOUDEST_EVENT_FREQUENCY\]|${loudestEventFrequency}|g" \
      -e "s|\[LOUDEST_EVENT_DURATION\]|${loudestEventDuration}|g" \
      -e "s|\[LOUDEST_EVENT_BANDWIDTH\]|${loudestEventBandwidth}|g" \
      -e "s|\[LOUDEST_EVENT_SNR\]|${loudestEventSNR}|g" \
      -e "s|\[CHANNEL_NAME\]|${channelName}|g" \
    ../html/index_hour.html >${hourDirectory}/index.html

  # create placeholder day html report
  if [ ! -f ${dayDirectory}/index.html ]; then
    echo "creating placeholder day html report..." >>${hourDirectory}/log.txt
    rm -f ${dayDirectory}/style.css
    ln -s ../../../style.css ${dayDirectory}/style.css
    sed -e "s|\[START_YEAR\]|${startYear}|g" \
        -e "s|\[START_MONTH\]|${startMonth}|g" \
        -e "s|\[START_DAY\]|${startDay}|g" \
        -e "s|\[PREVIOUSDAY_YEAR\]|${previousDayYear}|g" \
        -e "s|\[PREVIOUSDAY_MONTH\]|${previousDayMonth}|g" \
        -e "s|\[PREVIOUSDAY_DAY\]|${previousDayDay}|g" \
        -e "s|\[NEXTDAY_YEAR\]|${nextDayYear}|g" \
        -e "s|\[NEXTDAY_MONTH\]|${nextDayMonth}|g" \
        -e "s|\[NEXTDAY_DAY\]|${nextDayDay}|g" \
        -e "s|\[CURRENT_TIME\]|${currentTime}|g" \
        -e "s|\[ANALYSIS_DURATION\]|${analysisDuration}|g" \
        -e "s|\[INTERFEROMETER\]|${interferometer}|g" \
        -e "s|\[LOUDEST_EVENT_TIME\]||g" \
        -e "s|\[LOUDEST_EVENT_FREQUENCY\]||g" \
        -e "s|\[LOUDEST_EVENT_DURATION\]||g" \
        -e "s|\[LOUDEST_EVENT_BANDWIDTH\]||g" \
        -e "s|\[LOUDEST_EVENT_SNR\]||g" \
        -e "s|\[CHANNEL_NAME\]|${channelName}|g" \
      ../html/index_day.html >${dayDirectory}/index.html
  fi

  # update link to most recent results
  lastStopTime=`awk ' END { printf "%d", $2 } ' \
                latest_hour/livetime.txt 2>/dev/null`
  thisStopTime=`awk ' END { printf "%d", $2 } ' \
                ${hourDirectory}/livetime.txt 2>/dev/null`
  if [ ${thisStopTime:-0} -ge ${lastStopTime:-0} ]; then
    echo "linking html report..." >>${hourDirectory}/log.txt
    rm -f latest_hour
    ln -s ${hourDirectory} latest_hour
  fi

# end if html report requested
fi

################################################################################
#                             Loudest event QScan                              #
################################################################################

# begin if loudest event qscan requested
if [ -n "`echo ${requested} | grep -e event`" ]; then

  # remove existing loudest event qscan
  existingLoudestEvent=`find ${hourDirectory}/loudestevent -printf "%l" 2>/dev/null`
  if [ -n "${existingLoudestEvent}" ]; then
    echo "removing existing loudest event scan..." >>${hourDirectory}/log.txt
    rm -rf ${hourDirectory}/${existingLoudestEvent}
  fi

  # perform loudest event qscan
  # *** THIS NEEDS TO BE UPDATED TO HANDLE MULTIPLE DETECTORS ***
  rm -f ${hourDirectory}/loudestevent
  if [ -n "${loudestEventProperties}" ]; then
    echo "scanning loudest event..." >>${hourDirectory}/log.txt
    ln -s ${loudestEventTime} ${hourDirectory}/loudestevent
    ${Q}/bin/qscan.sh ${loudestEventTime} \
                      configuration_hour.txt \
                      @online \
                      ${hourDirectory}
  fi

# end if loudest event qscan requested
fi

################################################################################
#                                     End                                      #
################################################################################

# return to calling function
echo "done." >>${hourDirectory}/log.txt
exit 0

