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

#
#Modified from APS recordSRBeamDumps script, only keep the RF part.
#
#

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}

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"
        }
    }
}


proc CheckMpsDump {args} {
    #check if there MPS trip
    if [catch {exec cavget -list=S-MPS:MMPS:ReadyM \
                   -numerical -pend=20 -printErrors} mps] {
        return -code error $mps
    }
    if {!$mps} {
        #there is mps trip 
        return 1
    }
    if [catch {exec cavget -list=RF-ACIS:FePermit:Sect1To35IdM,S-DCCT:CurrentM -pend=20 -numerical \
                   -printErrors} valList] {
        return -code error $valList
    }
    set acisPermit [lindex $valList 0]
    set current [lindex $valList 1]
    if {$current<0.5 && $acisPermit} {
	return 1
    }    
    return 0
}

set rmsGlitch 0
proc CheckAlarmStatus {args} {
    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=S-DCCT:CurrentM -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=S-MPS:MMPS:ReadyM -numerical -pend=10 -printErrors} mps] {
        return -code error $mps
    }
    if {!$mps} {
	#do not record glitch when there mps dump
        return 0
    }
    return 0
}

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 -timeLimit=10} result] {
        if $debug { puts stderr "[exec date] Dump recorder is inhibited: $result" }
        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=S-DCCT:CurrentM,above=0.5 \
                   -timeLimit=$timeout}] {
        # still no beam
        continue
    }
    
    if $debug { puts stderr "[exec date] Beam detected" }
    
    updateBeamDumpConfig
    
    # Wait 
    #  MPS trip
    #  I<0.5mA and shutter permit enabled
    if $debug { puts stderr "[exec date] Waiting for beam dump..." }
    if {![catch \
              {exec cawait -interval=0.1 \
                   -waitfor=S-MPS:MMPS:ReadyM,changed \
                   -waitfor=RF-ACIS:FePermit:Sect1To35IdM,changed -or \
                   -waitfor=S-DCCT:CurrentM,below=0.5 -or \
                   -timeLimit=$timeout } ]} {
        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
        }
       
        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:MMPS:ReadyM,S-DCCT:CurrentM -num]
        if $debug { puts stderr "[exec date] Data: [join $data ,]" }
        set readyCC [lindex $data 0]
	set fcurrent [lindex $data 1]
       sendToLogFile "$dateTag0: readyCC=$readyCC pre-current=   current=$fcurrent"

        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=S-DCCT:CurrentM -pend=20} current]} {
            sendToLogFile "Problem reading current: $current"
            set current 0
        }
        sendToLogFile "$dateTag0: current=$current" 
        
        # make snapshot of values related to dump
	if {0} {
	    # there some PVs no longer exist, skip it for now
	    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"
	    }
	}
	
        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"
        }
        
        # 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"
        }
        set trip 1
    }
    if $test {
        break
    }
    if {$trip} {
        while {[catch {exec cawait -interval=0.1 -waitfor=S-MPS:MMPS:ReadyM,equal=1 -timeLimit=$timeout}]} {
            
        }
        sendToLogFile "$dateTag0: trip has been reset."
    }
}

close $logFileID
