#!/bin/sh  
# \
exec oagtclsh "$0" "$@"

#
# $Log: not supported by cvs2svn $
# Revision 1.87  2011/02/08 20:40:14  shang
# added catch command to APSSRReadBunchCM so that the program can continue when error is returned.
#
# Revision 1.86  2010/11/09 18:54:58  shang
# added log message for FPGA bpm history collection and moved FPGA data collection to the end of data collection because it takes the longest time.
#
# Revision 1.85  2010/11/02 21:07:18  shang
# moved the collecting FPGA bpm history to before reset, where it should be.
#
# Revision 1.84  2010/11/02 16:53:44  shang
# moved the collection of FPGA bpm history to the end since the updating of slow beam history takes time.
#
# Revision 1.83  2010/10/06 16:46:36  shang
# increased EPICS_CA_MAX_ARRAY_BYTES for FPGA bpm history collection.
#
# Revision 1.82  2010/08/24 21:51:35  shang
# added logging of arming FPGA bpms.
#
# Revision 1.81  2009/10/06 18:55:20  soliday
# Changed the S:MSLT:cm1AI PV to S:MSL200:compensatedAdcM
#
# Revision 1.80  2009/08/04 21:35:47  shang
# replaced the setup FPGA bpm triggers statements by APSSetupFPGABpmTriggers
#
# Revision 1.79  2009/06/02 19:38:27  shang
# added setting S38B:turn:gtr:trigger and S38B:motion:gtr:trigger to "event" when rearm the S38 BPMs.
#
# Revision 1.78  2009/06/01 15:16:18  shang
# fixed a problem in checking the SR status, the numerical value instead of string value should be obtained.
#
# Revision 1.77  2009/05/20 16:28:00  shang
# added one more condition for arm FPGA bpms: in user-operation mode.
#
# Revision 1.76  2009/05/20 16:20:16  shang
# modified to arm the FPGA bpm only after a beam dump and the beam is restored.
#
# Revision 1.75  2009/04/21 20:58:20  shang
# added re-arm the FPGA bpm history when beam is restored.
#
# Revision 1.74  2009/04/14 20:27:38  shang
# the collecting FPGA bpm history was put in wrong place -- rms glitch logger, moved it to mps dump recorder.
#
# Revision 1.73  2009/04/14 14:09:58  shang
# added collecting FPGA bpm history after mps dumps
#
# Revision 1.72  2009/02/09 18:02:49  shang
# added recording datapool bpm setpoints after mps dump
#
# Revision 1.71  2008/10/29 22:09:17  shang
# added rms glitch logger
#
# Revision 1.70  2008/03/13 22:01:07  emery
# Removed -waitfor=S35DCCT:CurrentLossAlarmLBO,equal=1
# because they occur to often for no apparent reason.
#
# Revision 1.69  2008/02/25 20:46:51  emery
# Change a current variable name. Added log entry for rf data collection.
#
# Revision 1.68  2006/05/31 18:33:34  soliday
# Now deletes old .update files upon startup.
#
# Revision 1.67  2004/10/05 21:27:50  emery
# Removed variable data1 which isn't defined, but was so
# in the previous version.
#
# Revision 1.66  2004/09/28 05:06:31  emery
# Removed occurences of variables related to the obsolete
# tds_3058 rf scopes.
#
# Revision 1.65  2004/09/22 16:42:44  emery
# Added RF scopes RF1:LL and RF2:LL.
#
# Revision 1.64  2004/07/28 14:42:02  soliday
# If S35DCCT:currentCC is unavailable it will now assume the current is zero.
#
# Revision 1.63  2004/07/16 22:12:05  emery
# Added an action for the catch statement around
# APSSRCollectTrippedBeamHistories which is suspected
# of aborting the script.
#
# Revision 1.62  2004/06/11 16:34:50  soliday
# Modified calls to APSSRSetFifoFillModes and APSSRSetFifoResync by removing
# A:P1 and B:P1 from the BPM list.
#
# Revision 1.61  2004/06/09 04:24:40  emery
# Because the -scalar option in sddswmonitor doesn't handle string PVs,
# the part in rf scope data collection that stores time stamps in
# waveform files had to be rewritten.
#
# Revision 1.60  2004/06/09 03:46:04  emery
# Defined the variable scope for the new rf scope data.
#
# Revision 1.59  2004/06/07 22:39:39  emery
# Added RF scope stamps as parameters to rf scope data.
#  CVS: ----------------------------------------------------------------------
#
# Revision 1.58  2004/06/03 17:43:11  emery
# Wrote the most recent addition of soliday on RF scope data in a different
# way. Added a test for no beam when collecting RF scope data.
#
# Revision 1.57  2004/06/03 17:19:58  soliday
# Set EPICS_CA_MAX_ARRAY_BYTES to 100000
#
# Revision 1.56  2004/06/03 16:55:33  soliday
# The RF HV and RF LL scopes are now archived the same way the previous TDS
# scopes have been.
#
# Revision 1.55  2004/05/22 22:24:08  emery
# Changed the APSCollectFBNbBpmHistory procedure name to APSCollectNbBpmHistory
# to correspond to the procedure in mplib/sr/APSGetFBCorHistory.tcl.
#
# Revision 1.54  2004/05/13 17:17:34  emery
# Added call to APSCollectFBNbBpmHistory. Not tested.
# Corrected some comments in FB history commands.
#
# Revision 1.53  2004/03/09 17:47:00  borland
# Restored ability to open gaps when beam dumps.  Using FCT readout for the
# current and a pre-sleep of 5s (probably longer than needed).
# Removed pointless "if 1" statement around main body.
#
# Revision 1.52  2003/12/04 22:41:20  soliday
# Calls to APSSRSetFifoFillModes and APSSRSetFifoResync are now enclosed in
# catch statements.
#
# Revision 1.51  2003/10/01 06:45:12  emery
# Changed ACIS zone F PV names.
#
# Revision 1.50  2003/09/03 20:35:46  soliday
# Added APSStandardSetup
#
# Revision 1.49  2003/07/08 01:41:07  shang
# corrected the bpm history rootname
#
# Revision 1.48  2003/07/08 01:32:04  shang
# modifed collecting FB bpm history to use the bpm name as columns
#
# Revision 1.47  2003/06/30 22:37:35  emery
# Ensured that datapool corrector vectors are recorded by
# determining the orbit correction mode at the start of the loop.
# Made recordeing of the [xy].steering.log only when doing
# non-datapool OC.
#
# Revision 1.46  2003/06/24 12:49:48  emery
# Added collection of bpm history from RTFB.
#
# Revision 1.45  2003/06/10 18:52:30  soliday
# Fixed a bug with the tds sddsmonitor command.
#
# Revision 1.44  2003/06/10 18:28:38  soliday
# Increased the TDS scope sddswmonitor pend time and launched it in the background.
#
# Revision 1.43  2003/06/06 19:43:20  soliday
# Added logging of the RF scope data
#
# Revision 1.42  2003/04/15 21:40:31  emery
# Added log message if history files are deleted.
#
# Revision 1.41  2002/11/12 10:04:24  emery
# Added call to APSCollectVideoWaveform to collect
# 35BM video beam size.
#
# Revision 1.40  2002/10/06 19:04:00  emery
# Added cd command to /home/helios4 in order to automount the disk.
#
# Revision 1.39  2002/08/21 03:45:18  emery
# Moved the datapool corrector waveform reading block at the end
# of the loop. In case the DP ioc had connection problems.
#
# Revision 1.38  2002/08/20 22:07:09  emery
# Fixed some bugs in the last addition.
#
# Revision 1.37  2002/08/20 22:05:25  emery
# Added collection of DP corrector waveforms if in vector mode.
#
# Revision 1.36  2002/08/12 16:31:33  emery
# Added copying of UBOP file to the dump directory
# with only the bpm setpoints and offsets.
#
# Revision 1.35  2001/11/07 02:19:58  borland
# Increased the DCCT settling time to 10s.
#
# Revision 1.34  2001/11/05 18:15:15  emery
# Added retry argument to burtrb.
#
# Revision 1.33  2001/08/28 23:43:30  emery
# MOdified the df -k command to test the critical disk.
# Added borland to mailing list.
#
# Revision 1.32  2001/08/27 14:14:06  borland
# Fixed bug (use of [hostname] instead of [exec hostname]).
#
# Revision 1.31  2001/08/22 21:51:49  emery
# Increased the wait time for the DCCT to 3 seconds after a beam loss.
# 1 second is too short apparently for some cases.
#
# Revision 1.30  2001/08/08 16:53:37  borland
# Fixed typo in an error message that results in script bombing ($openGap used
# in place of $openGaps)
#
# Revision 1.29  2001/08/06 18:24:06  emery
# Added line to make sure that the histories are not left in a globally
# disabled state. Used more sendToLogFile.
#
# Revision 1.28  2001/08/06 18:02:54  emery
# Added test of existence of disk where bpm history data is supposed to
# be written by IOCs. Mail is sent to emery and asdops.
# Changed some file copy and rm commands.
#
# Revision 1.27  2001/05/21 21:42:00  borland
# Checks inhibit value after dump is detected.
#
# Revision 1.26  2001/05/21 21:39:52  borland
# Now catches errors from scope commands.
#
# Revision 1.25  2001/05/21 21:23:30  borland
# Now uses SR:DumpRecorder:X PVs for external control .
#
# Revision 1.24  2001/05/11 22:13:12  emery
# Added more diagnostics messages when attempting to open gaps or not.
#
# Revision 1.23  2001/02/14 15:17:46  borland
# Rearranged some statements so the time-stamp is more accurate.
# Added a 1s wait so that the post-dump current reading is more accurate.
#
# Revision 1.22  2001/02/13 23:25:09  borland
# Now logs the scope waveform for ICT and the bunch-by-bunch current monitor.
#
# Revision 1.21  2000/01/06 17:37:23  borland
# Set cawait interval to 0.1s following change to cawait that implemented the
# default interval of 1s (lost when switched to raw CA?).
#
# Revision 1.20  2000/01/06 14:54:21  borland
# Fixed Y2K bug (would have named files 1900 instead of 2000).
#
# Revision 1.19  1999/09/13 19:14:20  emery
# Corrected the argument name for  APSSRSetFifoResync from "mode" to "state".
#
# Revision 1.18  1999/09/07 16:33:00  emery
# Added APSSRSetFifoResync command to disable resync to
# BPLD bpms. Added P1 bpms to arguments since in the future we are
# going to be using P1 bpms for BPLDs.
#
# Revision 1.17  1999/06/18 17:00:56  borland
# Now deletes old .update files upon startup.
#
# Revision 1.16  1999/06/18 16:51:42  borland
# Now looks at shutter permit on as well as top-up enable mode; if <0.5mA
# in either mode, dumps data.  Also, no longer rechecks parameters prior
# to dumping data.
#
# Revision 1.15  1999/06/12 02:41:17  borland
# Will now dump beam on a loss alarm even if the pre-alarm current is zero.
# This is to attempt to catch some strange beam losses that leave now
# trace.
#
# Revision 1.14  1999/06/03 01:40:16  borland
# Now looks at all three beam loss alarms, as they don't always all go off.
# Also, explicitly checks for beam loss as a condition for dumping data.
#
# Revision 1.13  1999/03/19 23:11:27  borland
# Modified to account for fact that ID:AccessSecurity return string actually
# has the quotes as part of the value (ROFL).
#
# Revision 1.12  1999/03/19 22:36:30  borland
# Now does not open the gaps when in Machine Physics mode on the IDs.
#
# Revision 1.11  1999/02/04 18:58:04  borland
# Now records data if top-up is unabled and the current falls below 0.5mA.
#
# Revision 1.10  1998/05/21 20:56:12  borland
# Fixed problem with copying of controllaw steering logs.  Someone changed the
# name of the source files, Louis.
#
# Revision 1.9  1997/11/03 18:02:11  borland
# Added statement to remove intermediate files that might not be removed
# if something bombs.
#
# Revision 1.8  1997/09/17 20:04:56  borland
# Added -minimalData option for getting beam histories, so that only
# index, position, and sum signal are stored.
#
# Revision 1.7  1997/09/08 16:40:55  borland
# Added configBPMs control variable to allow control of whether the
# script sets the BPM fifo mode.
#
# Revision 1.6  1997/08/26 18:44:33  borland
# Now sources an external file
# (/home/helios/OAG/oagData/mpsDumps/recordSRBeamDumps.rc) at intervals
# to allow changing the parameters without restarting the script.
#
# Revision 1.5  1997/07/31 13:59:06  borland
# Fixed directory name to which steering logs are copied.
#
# Revision 1.4  1997/07/31 00:48:46  borland
# Fixed more bugs with that code.
#
# Revision 1.3  1997/07/31 00:46:53  borland
# Fixed bug in new code that copies steering log files.
#
# Revision 1.2  1997/07/30 22:52:52  borland
# Added copying of steering log files.
#
# Revision 1.1  1997/07/30 20:42:53  borland
# First version in repository.  Needs some cleaning up.
#
#

set auto_path [linsert $auto_path 0  /usr/local/oag/apps/lib/$env(HOST_ARCH)]
set auto_path [linsert $auto_path 0 /usr/local/oag/lib_patch/$env(HOST_ARCH)]
APSDebugPath
APSStandardSetup
set test 0
set debug 0
set args $argv
APSParseArguments {test debug}

set env(EPICS_CA_MAX_ARRAY_BYTES) 10000000

#Update the EPICS_CA_ADDR_LIST so we can connect to DAQ:RTFB:HISTORY:TCP:DataCaptureC
set env(EPICS_CA_ADDR_LIST) "10.6.32.80 10.6.28.13 iocrtfbdaq"




if [string compare $env(USER) oag]==0 {
    cd /home/helios/oagData/mpsDumps
}

foreach filename [lsort [glob -nocomplain ???????.update]] {
    if [expr int(([clock seconds]-[file mtime $filename])/(24.0*3600.0))>3] {
        file delete -force $filename
    }
}

set testMode $test
set openGaps 1
set timeout 300
set configBPMs 0

proc updateBeamDumpConfig {} {
    if 0 {
        global openGaps timeout configBPMs
        if [catch {exec cavget -pend=30 -list=SR:DumpRecorder: \
                     -list=ConfigBPMs,OpenGaps,Timeout -numerical} result] {
            sendToLogFile "Error getting configuration: $result"
        } else {
            APSSetVarsFromList -valueList $result -variableList "configBPMs openGaps timeout"
        }
    } else {
        global openGaps timeout
        if [catch {exec cavget -pend=30 -list=SR:DumpRecorder: \
                     -list=OpenGaps,Timeout -numerical} result] {
            sendToLogFile "Error getting configuration: $result"
        } else {
            APSSetVarsFromList -valueList $result -variableList "openGaps timeout"
        }
    }
}

set alarmPVList {SRFB:xRMSmotionAlarmM SRFB:xRMSmotion30HzAlarmM SRFB:xRMSmotionVarHzAlarmM \
                         SRFB:yRMSmotionAlarmM SRFB:yRMSmotion30HzAlarmM SRFB:yRMSmotionVarHzAlarmM}
set otherPVList {S:OrbitControlLawXFineBO S:OrbitControlLawYFineBO S:MPS:readyCC}

proc CheckMpsDump {args} {
    #check if there MPS trip
    if [catch {exec cavget -list=S:MPS:readyCC,S35DCCT:CurrentLossAlarmBO,S35DCCT:CurrentLossAlarmMBO \
                   -numerical -pend=20 -printErrors} mpsValues] {
        return -code error $mpsValues
    }
    set mps [lindex $mpsValues 0]
    set loss1 [lindex $mpsValues 1]
    set loss2 [lindex $mpsValues 2]
    if {!$mps || $loss1 || $loss2} {
        #there is mps trip or current loss alarm
        return 1
    }
    if [catch {exec cavget -list=ACIS:FAI_TOP_UP_SW,ACIS:FBI_TOPUP_ENA,ACIS:ShutterPermit,S35DCCT:currentCC -pend=20 -numerical \
                   -printErrors} valList] {
        return -code error $valList
    }
    set topup [lindex $valList 0]
    set acisTopup [lindex $valList 1]
    set acisPermit [lindex $valList 2]
    set current [lindex $valList 3]
    if {$current<0.5} {
        if {$topup || $acisTopup || $acisPermit} {
            return 1
        }
    }
    return 0
}

set rmsGlitch 0
proc CheckAlarmStatus {args} {
    global  otherPVList alarmValueList alarmPVList
    #check if RFFB loops are closed, if open, ignore the rms glitches
    if [catch {exec cavget -pend=20 -list=SRFB:GBL: -list=Hor,Vert -list=:CloseLoopBO -printErrors -numerical} loops] {
        sendToLogFile "Uable to read RTFB loops: $loops"
        return 0
    }
    
    set hloop [lindex $loops 0]
    set vloop [lindex $loops 1]
    if {!$hloop || !$vloop} {
        return 0
    }
    if [catch {exec cavget -pend=20 -list=S:ActualMode -numerical -printErrors } srMode] {
        sendToLogFile "Unable to read SRmode: $srMode"
        return 0
    }
    if {$srMode!=4} {
        #do not record if not user beam time
        return 0
    }
    if [catch {exec cavget -list=S35DCCT:currentCC.VAL -printErrors -pend=20} current] {
        sentToLogFile "Unable to read current: $current"
        return 0
    }
    if {$current<0.5} {
        #only record rms glitch when there is beam
        return 0
    }
    if [catch {exec cavget -list=[join $otherPVList ,] -numerical -pend=10 -printErrors} otherValList] {
        return -code error $otherValList
    }
    #do not log if doing steering or there is mps dump
    set xsteer [lindex $otherValList 0]
    set ysteer [lindex $otherValList 1]
    set mps [lindex $otherValList 2]
    if {$xsteer || $ysteer || !$mps} {
        return 0
    }
    if [catch {exec cavget -list=[join $alarmPVList ,] -pend=30 -printErrors -numerical} alarmValueList] {
        return -code error $alarmValueList
    }
    for {set i 0} {$i<[llength $alarmValueList]} {incr i} {
        set value [lindex $alarmValueList $i]
        if $value {
            return 1
        }
    }
    return 0
}

proc RecordRMSOrbitGlitch {args} {
    set test 0
    set debug 0
    APSParseArguments {test debug}
    global rmsDir alarmPVList alarmValueList rootname rmsGlitch
    
    set SRImageMonDir /home/helios/oagData/TransportLineEmittance/monitorFiles
    if $debug {puts stderr "[exec date] check alaram status..."}
    if [catch {CheckAlarmStatus} result] {
        sendToLogFile "Error in checking alarm status: $result"
        exit 1
    }
    set rmsGlitch $result
    if $rmsGlitch {
        if $debug {
            puts stderr "[exec date] rms glitch detected."
        } 
        #sendToLogFile "rms glitch detected."
    } else {
        if $debug {
            puts stderr "[exec date] no rms glitch detected."
        }
    }
    if $test {
        set result 1
        set suffix .test
    } else {
        set suffix ""
    }
    
    set timeList [split [exec timeconvert -now]]
    set timeHMS [clock format [clock seconds] -format %H%M%S]
    set timeVal [expr int([lindex $timeList 8])]
    set dirName $rmsDir/$rootname/${timeHMS}$suffix
    
    if {$result} {
        exec mkdir -p $dirName
        # determine correction mode now for use later in
        # the procedure.
        if {[catch {exec cavget -pend=20 -list=DP: -list=H,V -list=CorrVectorModeC.VAL -printErrors} vectorMode]} {
            sendToLogFile "Problem connecting with vector mode PVs: $vectorMode"
        }
        set HCorrVectorMode [lindex $vectorMode 0]
        set VCorrVectorMode [lindex $vectorMode 1]
        if $debug {puts stderr "[exec date] write alarmRecord.sdds..."}
        if [catch {exec sddsmakedataset $dirName/alarmRecord.sdds \
                       -col=ControlName,type=string -data=[join $alarmPVList ,] \
                       -col=ValueString,type=string -data=[join $alarmValueList ,] } result] {
            sendToLogFile "Error in generating alarmRecord.sdds: $result"
        }
        catch {exec gzip  alaramRecord.sdds}
        # collect FB corrector error history
        if $debug {puts stderr "[exec date] collecting FB corrector history..."}
        if [catch {APSCollectFBCorrectorHistory -filename \
                       $dirName/FBCorrHistory.sdds} result] {
            sendToLogFile "Error in collect FB corrector history: $result"
        }
        catch {exec gzip $dirName/FBCorrHistory.sdds}
        
        #collect inuse DP corrector error history
        if $debug {puts  stderr "[exec date] collecting orbit corrector history..."}
        if {[string match $VCorrVectorMode Vector] || \
                [string match $HCorrVectorMode Vector] } {
            # collect vector corrector error history
            if [catch {APSCollectInUseDPCorrectorHistory -filename \
                           $dirName/InUseDPCorrHistory.sdds} result] {
                sendToLogFile "Error in collect corrector vector history: $result"
            }
            catch {exec gzip $dirName/InUseDPCorrHistory.sdds}
        } else {
            # workstation-based orbit correction
            # copy the latest steering update files from controllaw area
            sendToLogFile "Collecting last corrector delta (non-datapool)..."
            set steeringDir /home/helios/oagData/controllaw/SRorbit/loggedData
            set xLatest [lindex \
                             [lsort \
                                  [glob -nocomplain $steeringDir/sr.x-*.log]] end]
            set yLatest [lindex \
                             [lsort \
                                  [glob -nocomplain $steeringDir/sr.y-*.log]] end]
            if {[string length $xLatest] && \
                    [catch {file copy $xLatest $dirName/xSteering.log} result]} {
                sendToLogFile "Can not copy  $xLatest to $dirName/xSteering.log: $result"
            }
            if {[string length $yLatest] && \
                    [catch {file copy $yLatest $dirName/ySteering.log} result]} {
                sendToLogFile "Can not copy  $yLatest to $dirName/ySteering.log: $result"
            }
        }
        #collect beam size history
        if $debug {puts stderr "[exec date] collect beam size history"}
        if [catch {exec cavput -pend=20 -list=S:VID1:dumpTestC=1 } result] {
            sendToLogFile "Error in collecting beam size history(1): $result"
        }
        if [catch {exec sddswmonitor -steps=1 -pend=120 $rmsDir/monitorFiles/beamSizeHistory.wmon -erase \
                       $dirName/BeamSizeHistory.sdds} result] {
            sendToLogFile "Error in collecting beam size history(2): $result"
        }
        catch {exec gzip  BeamSizeHistory.sdds}
        #take FB corrector error history snap shot
        if $debug {puts stderr "[exec date] collect FB corrector error history"}
        if [catch {exec sddscasr -save -pend=60 $rmsDir/monitorFiles/FBCorrectorError.mon $dirName/FBCorrectorError.snap.sdds} result] {
            sendToLogFile "Error in collecting FB corrector error snapshot: $result"
        }
        catch {exec gzip  FBCorrectorError.snap.sdds}
        #RMS vectors
        if [catch {exec sddswmonitor $rmsDir/monitorFiles/rmsVectors.wmon $dirName/rmsVectors.sdds -step=1 -erase -pend=10} reusult] {
            sendToLogFile  "Error in collecting rms corrector vector history: $result"
        }
        catch {exec gzip rmsVectors.sdds}
        #take one image from S:VID1
        set filename S-VID1-${rootname}-${timeHMS}
        
        #use sddswmonitor to take the data 
        if [catch {exec cavget -pendIoTime=10 -list=S:VID1:roi -list=YStartC,YSizeC,XStartC,XSizeC} dataList] {
            sendToLogFile  "Error in reading SR VID1 ROI: $result"
        }
        set start [lindex $dataList 0]
        set size  [lindex $dataList 1]
        set end [expr $start+$size]
        set y1 [expr 480-$start]
        set y0 [expr 480-$end]
        set inputFile /tmp/[APSTmpString]
        if [catch {exec sddsprocess $SRImageMonDir/S:VID1.wmon $inputFile -define=column,Index,i_row,type=long \
                       -filter=column,Index,$y0,$y1 } result] {
            sendToLogFile  "Error in processing SR VID1 monitor file: $result"
        }
        if [catch {exec sddswmonitor $inputFile -scalars=$SRImageMonDir/S:VID1.mon \
                       -versus=name=x,deltaPV=LI:VD1:CAL:xScalingC,offsetPV=LI:VD1:CAL:xOriginPixC,unitsPV=S:VID1:CAL:yEgu \
                       $inputFile.1 -erase -step=1} result] {
            sendToLogFile  "Error in collecting SR VID1 image: $result"
        }
        
        set start [lindex $dataList 2]
        set size  [lindex $dataList 3]
        set end [expr $start+$size]
        if [catch {exec sddsprocess $inputFile.1 $dirName/SRImage.sdds -filter=col,Index,$start,$end } result] {
             sendToLogFile  "Error in post-processing SR VID1 image file: $result"
        }
        catch {gzip $dirName/SRImage.sdds}
    }
    if $test {
        $debug {puts stderr "[exec date] testing done, exit!"}
        exit
    }
}

proc UpdateFile {args} {
    global logFile update dateTag0
    
    if [file exists $update] {
        if [catch {open $update a} fid] {
            puts stderr $fid
            exit 1
        }
        if [catch {os lockf $fid F_TLOCK 0} result] {
            sendToLogFile "$dateTag0: still running $update"
            exit 
        }
        sendToLogFile "$dateTag0: no longer running $update"
    } else {
        if [catch {open $update w} fid] {
            puts stderr $fid
            exit 1
        }
        if [catch {os lockf $fid F_LOCK 0} result] {
            puts stderr $result
            exit 1
        }
        catch {file delete [glob -nocomplain *.update$testExten]}
        puts $fid "update file for $dateTag0 started at [clock format [clock seconds]]" 
        flush $fid
        # this is necessary to force NFS to create the file with the
        # name given
        close $fid
        if [catch {open $update a+} fid] {
            puts stderr $fid
            exit 1
        }
        if [catch {os lockf $fid F_LOCK 0} result] {
            puts stderr $result
            exit 1
        }
    }
}

proc sendToLogFile {text} {
    global logFileID
    puts $logFileID "$text (at [clock format [clock seconds]])"
    flush $logFileID
}

set rmsDir /home/helios/oagData/rmsOrbitGlitch

set dateTag0 [exec date +%Y%j]
set rootname [exec date +%Y-%j-%m%d]
if $testMode {
    set testExten .test
} else {
    set testExten ""
}
set year [clock format [clock seconds] -format %Y]
set logFile dumps${year}.log$testExten
set logFileID [open $logFile "a+"]

if ![llength [info commands after]] {
    proc after {ms} {
        exec sleep [expr int(($ms+500.0)/1000.0)]
    }
}

set update $dateTag0.update
set update $update$testExten

UpdateFile
sendToLogFile "$dateTag0: started"

set beamdump 0
while {1} {
    if $debug { puts stderr "[exec date] In main loop" }
    if [catch {exec cawait -interval=1 -waitfor=SR:DumpRecorder:Inhibit,equal=0} result] {
        if $debug { puts stderr "[exec date] Dump recorder is inhibited" }
        sendToLogFile "$dateTag0: exiting: $result"
        exit
    }
    set dateTag1 [exec date +%Y%j]
    if [string compare $dateTag0 $dateTag1] {
        sendToLogFile "$dateTag0: exiting"
        exit
    }
    set trip 0
    if $debug { puts stderr "[exec date] Waiting for beam" }
    if [catch {exec cawait -interval=0.1 -waitfor=S35DCCT:currentCC,above=0.5 \
                   -timeLimit=$timeout}] {
        # still no beam
        continue
    }
    
    #rms orbit glitch logger
    #if $debug {puts stderr "check and record rm orbit glitch"}  
    #catch {RecordRMSOrbitGlitch -test $test -debug $debug} 
    
    if $debug { puts stderr "[exec date] Beam detected" }
    
    updateBeamDumpConfig
    if {!$testMode && $configBPMs} {
        #This is never run now because configBPMs is always 0.
        if $debug { puts stderr "[exec date] Updating BPM configuration" }
        if {[catch {APSSRSetFifoFillModes -mode "Continuous Fill" -BPMList "A:P2 B:P2 B:P5"} result]} {
            sendToLogFile "$result"
            exit
        }
        if {[catch {APSSRSetFifoResync -state "Disable" -BPMList "A:P2 B:P2 B:P5"} result]} {
            sendToLogFile "$result"
            exit
        }
        if [catch {exec cavput -pend=20 -list=Mt:Ddg2chan7.GATE=Enabled} result] {
            sendToLogFile "$result"
        }
        if $debug { puts stderr "[exec date] Done updating BPM configuration" }
    }
    # Wait for one of
    # rms orbit glitch
    #  MPS trip
    #  Current loss alarm
    #  I<0.5mA while top-up permit enabled or shutter permit enabled
    if $debug { puts stderr "[exec date] Waiting for beam dump or rms glitch..." }
    if {![catch \
              {exec cawait -interval=0.1 \
                   -waitfor=SRFB:xRMSmotionAlarmM,changed \
                   -waitfor=SRFB:xRMSmotion30HzAlarmM,changed -or \
                   -waitfor=SRFB:xRMSmotionVarHzAlarmM,changed -or \
                   -waitfor=SRFB:yRMSmotionAlarmM,changed -or\
                   -waitfor=SRFB:yRMSmotion30HzAlarmM,changed -or\
                   -waitfor=SRFB:yRMSmotionVarHzAlarmM,changed -or \
                   -waitfor=S:MPS:readyCC,changed -or \
                   -waitfor=S35DCCT:CurrentLossAlarmBO,changed -or \
                   -waitfor=S35DCCT:CurrentLossAlarmMBO,changed -or \
                   -waitfor=ACIS:FAI_TOP_UP_SW,changed -or -waitfor=ACIS:FBI_TOPUP_ENA,changed -or \
                   -waitfor=ACIS:ShutterPermit,changed -or \
                   -waitfor=S35DCCT:currentCC,below=0.5 -or \
                   -timeLimit=$timeout } ]} {
        catch {RecordRMSOrbitGlitch -test $test -debug $debug} 
        if [catch {CheckMpsDump} result] {
            sendToLogFile "Error in checking mps dump: $result"
        }
	set beamdump $result
        if {$debug} {
            if {!$result} {
                puts stderr "[exec date] No mps dump."
            } else {
                puts stderr "[exec date] Dump detected."
            }
        }
        if $test {
            set result 1
        }
        if !$result {
            #there is no mps dump 
            continue
        }
        catch {exec cavput -list=DAQ:RTFB:HISTORY:TCP:DataCaptureC=1 -pend=5}

        updateBeamDumpConfig
        if [catch {exec cavget -pend=20 -numerical -list=SR:DumpRecorder:Inhibit} result] {
            sendToLogFile "$result" 
        } else {
            if $result continue
        }
        # normal exit means trip detected  
        sendToLogFile "$dateTag0: trip detected, waiting"
        after 5000
        sendToLogFile "$dateTag0: trip detected, reading"
        if $debug { puts stderr "[exec date] Reading data." }
        set data [exec cavget -pend=20 -list=S:MPS:readyCC,S:MPS:M4A:beamCurrAtDumpAI,S35DCCT:CurrentLossAlarmBO,S35DCCT:CurrentLossAlarmLBO,S35DCCT:CurrentLossAlarmMBO,S35DCCT:PreAlarmCurrentAI,S:MSL200:compensatedAdcM -num]
        if $debug { puts stderr "[exec date] Data: [join $data ,]" }
        set readyCC [lindex $data 0]
        set currentAtDump [lindex $data 1]
        set lossAlarm [expr [lindex $data 2]+[lindex $data 3]+[lindex $data 4]]
        set preCurrent [lindex $data 5]
        set fcurrent [lindex $data 6]

       sendToLogFile "$dateTag0: currentAtDump=$currentAtDump current=$fcurrent readyCC=$readyCC   pre-current=$preCurrent alarm=$lossAlarm"

        if {$openGaps && [expr abs($fcurrent)<0.5]} {
            if [catch {exec cavget -list=S:DesiredMode -num -printErrors } srMode] {
                set srMode 1
            }
            if {$srMode==1} {
                #APSSaveMachine changes the pwd and doesn't cd back unless there is an error.
                set oldDir [pwd]
                if [catch {APSSaveMachine -machine SR -description "After mps dump, before opening all gaps." } result] {
                    sendToLogFile "Problem with SR SCR save before opening gaps: $result"
                }
                cd $oldDir
            }
            if [catch {APSIDOpenAllGaps} result] {
                sendToLogFile "Problem with opening gaps: $result"
            } else {
                if $debug { puts stderr "[exec date] Opening gaps" }
                sendToLogFile "Gap open command sent."
            } 
        } else {
            sendToLogFile "Conditions are not met for opening of the gaps: openGaps: $openGaps, Current: $fcurrent mA."
            if $debug { puts stderr "[exec date] Conditions are not met for opening of the gaps: openGaps: $openGaps, Current: $fcurrent mA." }
        }
        
        set timeList [split [exec timeconvert -now]]
        set timeHMS [exec date +%H%M%S]
        set timeVal [expr int([lindex $timeList 8])]
        set dirName $rootname/$timeHMS$testExten
        set dateTag1 [exec date +%Y%j]
        if [string compare $dateTag0 $dateTag1] {
            # assume this one will be picked up by the job for the present date
            exit
        }

        exec mkdir -p $dirName
        # wait to read current to ensure getting the current after the loss
        set DCCTsettlingTime 10
        after [expr 1000 * $DCCTsettlingTime]
        if {[catch {exec cavget -list=S35DCCT:currentCC -pend=20} current]} {
            sendToLogFile "Problem reading current: $current"
            set current 0
        }
        sendToLogFile "$dateTag0: current=$current" 
        
        if [expr abs($current)>0.1] {
            # get scope waveform for ICT
            # only useful if there is still beam left
            if {0} {
                #no longer need it since the bunch current monitor is avaible, 8/23/2016 plus this old scope no longer exist.
                if [catch {exec sendScopeCommand S:DO1 :STOP
                    exec getScopeWaveform S:DO1 c1 $dirName/scopeIctWaveform.sdds -signal=ICT -single
                    exec sendScopeCommand S:DO1 :RUN} result] {
                    sendToLogFile "$result"
                }
            }
            # get bunch-by-bunch CM data
            # only useful if there is still beam left
            if [catch {APSSRReadBunchCM -output $dirName/bunchByBunchCM.sdds -useFillPattern 1 } result] {
		sendToLogFile "$result"
	    }
        }
        
        # determine correction mode now for use later in
        # the procedure.
        if {[catch {exec cavget -pend=20 -list=DP: -list=H,V -list=CorrVectorModeC.VAL} corrMode]} {
            sendToLogFile "Problem connecting with vector mode PVs: $corrMode"
        }
        set VCorrVectorMode [lindex $corrMode 0]
        set HCorrVectorMode [lindex $corrMode 1]
        # make snapshot of values related to dump
        if [catch {exec sddscasr /home/helios/oagData/mpsDumps/dumpRecord.req -save -pipe=out \
                       | tee $dirName/dumpRecord.snap \
                       | sddsprocess -pipe \
                       "-match=col,ValueString=*/*/* *:*:*.*" \
                       | sddssort -pipe=in $dirName/dumpTimeStamps.snap \
                       -col=ValueString,increasing } result] {
            sendToLogFile "$result"
        }
        
        if [catch {exec gzip $dirName/dumpTimeStamps.snap} result] {
            sendToLogFile "$result"
        }
        if [catch {exec gzip $dirName/dumpRecord.snap} result] {
            sendToLogFile "$result"
        }

        # collect FB corrector error history
        if [catch {APSCollectFBCorrectorHistory -filename \
                     $dirName/FBCorrHistory.sdds} result] {
            sendToLogFile "$result"
        }
        catch {exec gzip $dirName/FBCorrHistory.sdds}
	
        # Collect FB bpm history, and rename channel columns as actual bpm
        # names, e.g. S1A:P1 etc. (obtained from channel config).
        # The filenames are created by appending .x and .y to the rootname
        if [catch {APSCollectFBbpmHistory -rootname $dirName/FBbpmHistory -noUpdate 1} result] {
            sendToLogFile "$result"
        }
        catch {exec gzip $dirName/FBbpmHistory.x}
        catch {exec gzip $dirName/FBbpmHistory.y}
        #catch {exec gzip $dirName/FBbpmHistory.sdds}

        # Collect FB Nb bpm history.
        # Note the filename is the same as the rootname
        if [catch {APSCollectNbBpmHistory -rootname $dirName/NbBpmHistory} result] {
            sendToLogFile "$result"
        }
        catch {exec gzip $dirName/NbBpmHistory}

        if [expr abs($current)<1.0] {
            # get scope waveform for RF data
            # only useful if there is NO beam left
            sendToLogFile "$dateTag0: Current is $current < 1.0, then rf data will be taken."
            set newPVs ""
            set tmpfile /tmp/[APSTmpString]
            set newScalars ""
            for {set n 1} {$n <= 4} {incr n} {
                set scope S${n}:K
                # additional scopes. Still some problem with acquisition.
                set scope RF${n}:HV
                append newPVs "${scope}:scaledTimeAxisWF ${scope}:chan1ScaledWaveWF ${scope}:chan2ScaledWaveWF ${scope}:chan3ScaledWaveWF ${scope}:chan4ScaledWaveWF "
                append newScalars "${scope}:WF_timeStampTS "
            }
            # there are now four scopes for RF LL signals.
            for {set n 1} {$n <= 4} {incr n} {
                set scope RF${n}:LL
                append newPVs "${scope}:scaledTimeAxisWF ${scope}:chan1ScaledWaveWF ${scope}:chan2ScaledWaveWF ${scope}:chan3ScaledWaveWF ${scope}:chan4ScaledWaveWF "
                append newScalars "${scope}:WF_timeStampTS "
            }
            catch {exec cavget -pend=20 -list=[join $newScalars ,] -label -embrace} data
            foreach item $data {
                lappend printOptionsNew -print=para,[lindex $item 0],[lindex $item 1]
            }
            # Can't use string PVs in -scalars option
            catch {exec sddswmonitor $dirName/tds3000_rf.sdds \
                     -pv=[join $newPVs ","] \
                     -steps=1 -pend=120 }
            catch {eval exec sddsprocess $dirName/tds3000_rf.sdds $printOptionsNew -noWarning}
            catch {file delete $dirName/tds3000_rf.sdds~}
            catch {exec gzip $dirName/tds3000_rf.sdds}
        }
        # check the existance of /home/helios4/, but
        # first allow automount to work by doing a cd to the disk first
        set criticalDisk /home/helios4
        set oldDir [pwd]
        catch {cd $criticalDisk}
        after 1000
        cd $oldDir
        if [catch {exec df -k $criticalDisk | grep $criticalDisk} result] {
            set hostname [exec hostname]
            sendToLogFile "Could not find disk $criticalDisk on host $hostname."
            APSSendEMail -address "asdops emery soliday" \
              -subject "Problem with $criticalDisk" \
              -message "Could not find disk $criticalDisk on host $hostname for application recordSARBeamDumps"
        }
        if 0 {
            if !$testMode {
                if [catch {APSSRCollectTrippedBeamHistories -doGzip 1 \
                             -minimalData 1 \
                             -namePrefix $dirName/ -nameSuffix .sdds \
                             -statusCallback sendToLogFile \
                         } result ] {
                    sendToLogFile "$dateTag0: Problem with collecting beam histories: $result"
                }
                sendToLogFile "$dateTag0: done collecting beam histories"
            }
        }

        # get rid of any beam history files that weren't moved to subdirectory
        set historyFileList [glob -nocomplain S*\[AB\]:P\[12345\]_??????-??????-\[xy\].sdds]
        if [llength $historyFileList] {
            catch {eval file delete $historyFileList}
            sendToLogFile "Deleted files $historyFileList from [pwd]"
        }
        # make a copy of the bpm setpoints for the current UBOP file
        if [catch {exec sddsprocess /home/helios/oagData/SCR/snapshots/SR/SR-UserBeamPreferred.gz -pipe=out \
                     -match=col,ControlName=S*:P?:ms:?:SetpointAO,ControlName=S*:P?:ms:?:OffsetAO,| \
                     | sddsconvert -pipe=in $dirName/bpmSetpoints \
                     -retain=col,ControlName,ValueString \
                 } results] {
            sendToLogFile "Problem creating bpm setpoint from UBOP: $results"
        }

        if {[string match $VCorrVectorMode Vector] || \
              [string match $HCorrVectorMode Vector] } {
            # collect vector corrector error history
            if [catch {APSCollectDPCorrectorHistory -filename \
                         $dirName/DPCorrHistory.sdds} result] {
                sendToLogFile "$result"
            }
            sendToLogFile "Collecting DP corrector vectors..."
            catch {exec gzip $dirName/DPCorrHistory.sdds}
            if [catch {APSCollectDPBPMs -rootname $dirName/DPbpmSetpoint } result] {
                sendToLogFile "$result"
            }
            sendToLogFile "Collecting DP bpm setpoint vectors..."
            catch {exec gzip $dirName/DPbpmSetpoint.x }
            catch {exec gzip $dirName/DPbpmSetpoint.y }
        } else {
            # workstation-based orbit correction
            # copy the latest steering update files from controllaw area
            sendToLogFile "Collecting last corrector delta (non-datapool)..."
            set steeringDir /home/helios/oagData/controllaw/SRorbit/loggedData
            set xLatest [lindex \
                           [lsort \
                              [glob -nocomplain $steeringDir/sr.x-*.log]] end]
            set yLatest [lindex \
                           [lsort \
                              [glob -nocomplain $steeringDir/sr.y-*.log]] end]
            if {[string length $xLatest] && \
                  [catch {file copy $xLatest $dirName/xSteering.log} result]} {
                sendToLogFile $result
            }
            if {[string length $yLatest] && \
                  [catch {file copy $yLatest $dirName/ySteering.log} result]} {
                sendToLogFile $result
            }
        }
        # collect waveform from max video
        if [catch {APSCollectVideoWaveform -filename \
                     $dirName/VideoHistory.sdds} result] {
            sendToLogFile "$result"
        }
        sendToLogFile "Collecting 35BM video beam size waveforms..."
        catch {exec gzip $dirName/VideoHistory.sdds}
        # collecting FPGA bpm history
        sendToLogFile "Collecting FPGA bpm history..."
        if [catch {APSCollectFPGABpmHistory -directory $dirName } result] {
            sendToLogFile "Error in collect FPGA bpm history: $result"
        }
        set trip 1
    }
    if $test {
        break
    }
    if {$trip} {
        while {[catch {exec cawait -interval=0.1 -waitfor=S:MPS:readyCC,equal=1 -timeLimit=$timeout}]} {
            
        }
        sendToLogFile "$dateTag0: trip has been reset."
    }
    if {$rmsGlitch} {
        
    }
}

close $logFileID
