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

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)]
APSStandardSetup

set CVSRevisionAuthor "\$Revision: 1.12 $ \$Author: shang $"

set lastPing 0
set runControlPV B:EnergySaveModeRC


proc PingRunControl {args} {
    global lastPing runControlPV abort
    set sec [clock seconds]
    if {[expr $lastPing + 2] > $sec} {
        return
    } else {
        set lastPing $sec
    }
    
    catch {APSRunControlPing} status
    switch $status {
        RUNCONTROL_OK {}
        RUNCONTROL_ABORT {
	    ResumeRampAfterAbort
            return -code error "Auto-correction was aborted."
        }
        RUNCONTROL_TIMEOUT -
        RUNCONTROL_ERROR {
	    ResumeRampAfterAbort
            return -code error "Unable to ping runcontrol record of $runControlPV: $status."
        }
    }
}

set abort 0
proc Abort {args} {
    global runControlPV abort
    set abort 1
    if [catch {APSAbortSRControllaw -runControlPV $runControlPV} result] {
	return -code error $result
    }
    ResumeRampAfterAbort
   # if [catch {exec cawait -waitfor=$runControlPV.RUN,equal=0 } result] {
#	return -code error $result
 #   }
 #   if [catch {APScavput -list=$runControlPV.CLR=1 -pend=30} result] {
#	return -code error $result
 #   }
}

proc SetStatus {text} {
    global status
    set status "[clock format [clock seconds] -format %H:%M:%S] $text"
    SendToRampLogFile $text
    update
}

proc PlotData {args} {
    global outputDir rootname rmsPV

    set oldDir [pwd]
    cd $outputDir
    set files [lsort [glob ${rootname}-*.sdds.*]]
    eval exec sddsplot -col=Time,$rmsPV -tick=xtime $files &
    eval exec sddsplot -col=Time,It:Bs:QfVafgTrigAO.VAL -tick=xtime $files &
    eval exec sddsplot -col=Time,B:BM:VoltageRT.GAIN -tick=xtime $files &
    after 4000
    cd $oldDir
}

proc WakeUp {args} {
    set cycle ""
    APSParseArguments {cycle}
    
    global outputDir rootname  cycles waveformMon monFile index sleepTime waitTime correctCycles wakeTime
    global correct monID waveID1 waveID2 topup wakeToInj voltageWaveformMon currentWaveformMon wakeupLoadSafety
    global corrWaitTime injWaitTime enable disable measMagnet lastWakeupTime logWaveform wakeToInj IRamp rmsPV
    
    set outputDir [APSGoToDailyDirectory -subdirectory rampTest]
    if [catch {PingRunControl} result] {
	return -code error $result
    }
    SetStatus "enable BM ramp."
    if {$corrWaitTime<5} {
        SetStatus "Ramp auto correction can not be less than 5 seconds, reset it to 5."
        set corrWaitTime 5
    }
    if [catch {APScavput -list=It:Ddg4chan0.GATE=1} result] {
        SetStatus "unable to turn on ramp: $result"
        return -code error $result
    }
    set lastWakeupTime [clock seconds]
    set timenow [clock seconds]
    if $topup {
        set time [expr $wakeToInj - 1]
    } else {
        set time [expr $wakeTime * 60 - 5]
    }
    if $measMagnet {
        set file $outputDir/bmon-[clock format [clock seconds] -format %Y-%m%d:%H%M%S].sdds
        exec  BRampWaveformMon -filename $file
        exec sddsprocess $file -nowarnings -redefine=par,LastWakeupTime,$lastWakeupTime
        set startMon [clock seconds]
    }
    set timeout [expr [clock seconds] + $corrWaitTime]
    set timeoutInj [expr [clock seconds] + $injWaitTime]
    
    if $measMagnet {
        set file $outputDir/bmon-[clock format [clock seconds] -format %Y-%m%d:%H%M%S].sdds
        if $IRamp {
            if  [catch {exec BIRampWaveformMon -filename $file} result] {
                return -code error "Error reading booster Iramp waveforms: $result"
            }
        } else {
            if [catch {exec BRampWaveformMon -filename $file } result] {
                return -code error "Error reading booster Iramp waveforms: $result"
            }
        }
        exec sddsprocess $file -nowarnings -redefine=par,LastWakeupTime,$lastWakeupTime
        set startMon [clock seconds]
    }
    while {1} {
	if [catch {PingRunControl} result] {
	    return -code error $result
	}
        if [catch {ReadPVNumValue -pv $rmsPV } BMDeltaIRms] {
            return -code error "$BMDeltaIRms"
        }
        if {$BMDeltaIRms < 0.100 } {
            break 
	}
        if {$measMagnet && [clock seconds]>[expr $startMon + 10]} {
            set file $outputDir/bmon-[clock format [clock seconds] -format %Y-%m%d:%H%M%S].sdds
            if $IRamp {
                if  [catch {exec BIRampWaveformMon -filename $file} result] {
                    return -code error "Error reading booster Iramp waveforms: $result"
                }
            } else {
                if [catch {exec BRampWaveformMon -filename $file } result] {
                    return -code error "Error reading booster Iramp waveforms: $result"
                }
            }
            exec sddsprocess $file -nowarnings -redefine=par,LastWakeupTime,$lastWakeupTime
            set startMon [clock seconds]
        }
        after 1000
    }
    if [catch {PingRunControl} result] {
	return -code error $result
    }
    if [catch {TurnOnInjection -topup $topup -timeout $timeoutInj -measMagnet $measMagnet} result] {
        return -code error $result
    }
    if [catch {PingRunControl} result] {
	return -code error $result
    }
    if $wakeupLoadSafety {
	SetStatus "load safety when wake up."
        LoadSafetyWhenWakeup
    }
    set first 1
    set endTime [expr [clock seconds] + $time]
    incr correct
    return
}

proc ResumeAutoCorrection {args} {
    set logtime ""
    set starttime ""
    set cycle ""
    set logWaveform ""
    set measMagnet ""
    set timeout ""
    set index ""
    APSParseArguments {logtime starttime cycle logWaveform waittime measMagnet timeout index}
    
    return
    global outputDir
    set startMon 0
    if [catch {PingRunControl} result] {
	return -code error $result
    }
    while {[clock seconds]<$timeout} {
        if [catch {PingRunControl} result] {
	    return -code error $result
	}
        after 1000
        if {$measMagnet && [clock seconds]>[expr $startMon + 10]} {
            set file $outputDir/bmon-[clock format [clock seconds] -format %Y-%m%d:%H%M%S].sdds
            exec  BRampWaveformMon -filename $file
            exec sddsprocess $file -nowarnings -redefine=par,LastWakeupTime,$lastWakeupTime
            set startMon [clock seconds]
        }
        update
    }
  
    if [catch {PingRunControl} result] {
	return -code error $result
    }
    #start log data now
    LogData -logtime $logtime -starttime $starttime -cycle $cycle -logWaveform $logWaveform -index $index
    if [catch {PingRunControl} result] {
	return -code error $result
    }
    SetStatus "after log data."
}

proc LogData {args} {
    set logtime ""
    set starttime ""
    set cycle ""
    set logWaveform 0
    set index ""
    APSParseArguments {logtime starttime cycle logWaveform index}
    global outputDir rootname monFile currentWaveformMon voltageWaveformMon
    set time [expr $logtime - ([clock seconds]-$starttime)]
    set filename $outputDir/${rootname}-[format %04d $index].sdds.[format %03d $cycle]
    if {$time<0} {
        SetStatus "No time left for logging data."
        return
    }
    SetStatus "log data... $time"
    catch {exec sddsmonitor $monFile $filename -interval=2 -time=$time,seconds -erase -pendiotime=60 &} monID
    if $logWaveform {
        catch {exec sddswmonitor $currentWaveformMon $filename.waveform.current  -interval=10 -erase -pendiotime=120 \
                 -time=$time,seconds &} waveID1
        catch {exec sddswmonitor $voltageWaveformMon $filename.waveform.volRef  -interval=10 -erase -pendiotime=120 \
                     -time=$time,seconds &} waveID2
    }
}

proc TurnOnInjection {args} {
    set topup ""
    set timeout ""
    set measMagnet 0
    APSParseArguments {topup timeout measMagnet}

    global outputDir
    set startMon 0
    if [catch {PingRunControl} result] {
	return -code error $result
    }
    while { [clock seconds] < $timeout} {
        after 1000
	if [catch {PingRunControl} result] {
	    return -code error $result
	}
        if {$measMagnet && [clock seconds]>[expr $startMon + 10]} {
            set file $outputDir/bmon-[clock format [clock seconds] -format %Y-%m%d:%H%M%S].sdds
            exec  BRampWaveformMon -filename $file
            exec sddsprocess $file -nowarnings -redefine=par,LastWakeupTime,$lastWakeupTime
            set startMon [clock seconds]
        }
        update 
    }
    #### turn on injection
    if !$topup {
        SetStatus "enable beam..."
        EnableDisableBeam -enable 1
    }
    if [catch {PingRunControl} result] {
	return -code error $result
    }
}

proc EnableDisableBeam {args} {
    set enable 1
    APSParseArguments {enable}
    global disableEnableBeam
    if !$disableEnableBeam {
        #do nothing (to avoid toggling the RFG gun kicker)
        return
    }
    if $enable {
	APScavput -list=L1:RG1:KIK:chargeTrigC=1,L1:RG2:KIK:chargeTrigC=1
	TogglePulsedMagnetEnables -location GuntoBoosterExt
    } else {
	SetPulsedMagnetEnables -location GuntoBoosterExt -state 0 
    }
}

proc ResumeRampAfterAbort {args} {
    if [catch {APScavput -list=It:Ddg4chan0.GATE=1} result] {
        SetStatus "Error in turn on ramp: $result"
        return -code error $result
    }
}

proc ReadPVNumValue {args} {
    set pv ""
    APSParseArguments {pv}
    while {1} {
	if [catch {PingRunControl} result] {
	    return -code error $result
	}
        if [catch {APScavget -list=$pv -pend=10 -num} value] {
            bell 
            SetStatus "Error reading $pv: $value"
            SetStatus "Press abort button if you want to quit."
        } else {
            if [catch {expr $value/2.0} result] {
                bell 
                SetStatus "Invaild value obtained : $value"
                SetStatus "Press abort button if you want to quit."
            } else {
                return $value
            }
        }
        after 1000
        update
    }
}
#BM ramp start PV: It:Ddg4chan0.GATE
set index 0
set pingTimeout 10
proc Start {args} {
    global outputDir rootname  cycles waveformMon monFile index sleepTime waitTime correctCycles wakeTime wakeToInj
    global correct monID waveID1 waveID2 topup sleepLoadSafety runControlPV pingTimeout
    global corrWaitTime injWaitTime enable disable measure measMagnet lastWakeupTime logWaveform abort
    
    if [catch {APScavput -list=$runControlPV.CLR=1 -pend=20} result] {
        SetStatus $result
        return
    }
    if [catch {APSRunControlInit -pv $runControlPV \
		   -description "Booster Energy Saver" \
		   -timeout [expr $pingTimeout * 1000] } result] {
        SetStatus "Unable to initialize runcontrol for booster energy saver mode, the runcontrol record may not be cleared, press the clear button on the medm screen to clear the record and restart: $result"
        return
    }
    if [catch {PingRunControl} result] {
        if [catch {APScavput -list=It:Ddg4chan0.GATE=1} result] {
            SetStatus "unable to turn on ramp: $result"
            return -code error $result
        }
	SetStatus "$result"
	return
    }
    if {$corrWaitTime<5} {
        SetStatus "Ramp auto correction can not be less than 5 seconds, reset it to 5."
        set corrWaitTime 5
    }
    set waveFile $outputDir/${rootname}-[format %04d $index].sdds.0.waveform
    while {1} {
        if ![file exist $waveFile] {
            break
        }
        incr index
        set waveFile $outputDir/${rootname}-[format %04d $index].sdds.0.waveform
    }

    set autocorrect 0
    set i 0
    while {1} {
        incr i
	if [catch {PingRunControl} result] {
            if [catch {APScavput -list=It:Ddg4chan0.GATE=1} result] {
                SetStatus "unable to turn on ramp: $result"
                return -code error $result
            }
	    SetStatus "$result"
	    return
	}
        SetStatus "run cycle $i..."
        SendToRampLogFile "run cycle $i..."
        set correct 0
        if [catch {ReadPVNumValue -pv Mt:TopUpAutoEnableC.VAL } topup] {
            if [catch {APScavput -list=It:Ddg4chan0.GATE=1} result] {
                SetStatus "unable to turn on ramp: $result"
                return -code error $result
            }
            SetStatus $topup
	    return
        }
	if [catch {PingRunControl} result] {
            if [catch {APScavput -list=It:Ddg4chan0.GATE=1} result] {
                SetStatus "unable to turn on ramp: $result"
                return -code error $result
            }
	    SetStatus "$result"
	    return
	}
        if $topup {
            #in topup mode 
            set firstSleep 1
            set firstWake 1
            while {1} {
		if [catch {PingRunControl} result] {
                    if [catch {APScavput -list=It:Ddg4chan0.GATE=1} result] {
                        SetStatus "unable to turn on ramp: $result"
                        return -code error $result
                    }
		    SetStatus "$result"
		    return
		}
                #check the injection time
                if [catch {ReadPVNumValue -pv Mt:TopUpTime2Inject.VAL} inj] {
                    if [catch {APScavput -list=It:Ddg4chan0.GATE=1} result] {
                        SetStatus "unable to turn on ramp: $result"
                        return -code error $result
                    }
                    SetStatus $inj
		    return
                }
		if [catch {PingRunControl} result] {
                    if [catch {APScavput -list=It:Ddg4chan0.GATE=1} result] {
                        SetStatus "unable to turn on ramp: $result"
                        return -code error $result
                    }
		    SetStatus "$result"
		    return
		}
                if {$inj==120 || $inj==240} {
                    set inj 119
                } else {
                    set inj [expr $inj % 120]
                }
                if {$inj>$wakeToInj} {
                    if $firstSleep {
                        set firstSleep 0
                        SetStatus "disable BM ramp."
                        if [catch {APScavput -list=It:Ddg4chan0.GATE=0} result] {
                            if [catch {APScavput -list=It:Ddg4chan0.GATE=1} result] {
                                SetStatus "unable to turn on ramp: $result"
                                return -code error $result
                            }
                            SetStatus "Error in disabling BM ramp: $result"
                            return -code error $result
                        }
			if [catch {PingRunControl} result] {
                            if [catch {APScavput -list=It:Ddg4chan0.GATE=1} result] {
                                SetStatus "unable to turn on ramp: $result"
                                return -code error $result
                            }
			    SetStatus "$result"
			    return
			}
                        SetStatus "sleeping..."
                        LoadSafetyWhenSleeping
                    }
                    if [catch {ReadPVNumValue -pv Mt:TopUpTime2Inject.VAL} inj] {
                        if [catch {APScavput -list=It:Ddg4chan0.GATE=1} result] {
                            SetStatus "unable to turn on ramp: $result"
                            return -code error $result
                        }
                        return -code error $inj
                    }
		    if {$inj==120 || $inj==240} {
			set inj 119
		    } else {
			set inj [expr $inj % 120]
		    }
		    if {$inj<=$wakeToInj} {
			break
		    } else {
			set timeout [expr $inj - $wakeToInj + [clock seconds]]
			while {[clock seconds]<$timeout} {
			    if [catch {PingRunControl} result] {
                                if [catch {APScavput -list=It:Ddg4chan0.GATE=1} result] {
                                    SetStatus "unable to turn on ramp: $result"
                                    return -code error $result
                                }
				SetStatus "$result"
				return
			    }
			    after 500
			    update
			}
			if [catch {PingRunControl} result] {
                            if [catch {APScavput -list=It:Ddg4chan0.GATE=1} result] {
                                SetStatus "unable to turn on ramp: $result"
                                return -code error $result
                            }
			    SetStatus "$result"
			    return
			}
		    }
                } else {
                    if {$firstSleep && $inj<[expr $wakeToInj -10]} {
                        #skip it if there is not enough wake time for the first cycle
                        continue
                    }
		    if [catch {PingRunControl} result] {
                        if [catch {APScavput -list=It:Ddg4chan0.GATE=1} result] {
                            SetStatus "unable to turn on ramp: $result"
                            return -code error $result
                        }
			SetStatus "$result"
			return
		    }
                    if $firstWake {
                        set firstWake 0
                        if [catch {WakeUp -cycle $i} result] {
                            if [catch {APScavput -list=It:Ddg4chan0.GATE=1} result] {
                                SetStatus "unable to turn on ramp: $result"
                                return -code error $result
                            }
			    SetStatus "Error in WakeUp: $result"
			    return
			}
			SetStatus "after wakeup."
                        set startMon [clock seconds]
                        if [catch {ReadPVNumValue -pv Mt:TopUpTime2Inject.VAL} inj] {
                            if [catch {APScavput -list=It:Ddg4chan0.GATE=1} result] {
                                SetStatus "unable to turn on ramp: $result"
                                return -code error $result
                            }
                            return -code error $inj
                        }
			if [catch {PingRunControl} result] {
                            if [catch {APScavput -list=It:Ddg4chan0.GATE=1} result] {
                                SetStatus "unable to turn on ramp: $result"
                                return -code error $result
                            }
			    SetStatus "$result"
			    return
			}
                        if {$inj==120 || $inj==240} {
                            set inj 119
                        } else {
                            set inj [expr $inj % 120]
                        }
                        if {$inj>$wakeToInj} {
                            break
                        }
                        set timeout [expr [clock seconds] + $inj]
			SetStatus "waiting $inj seconds..."
                        while {[clock seconds]<$timeout} {
			    if [catch {PingRunControl} result] {
                                if [catch {APScavput -list=It:Ddg4chan0.GATE=1} result] {
                                    SetStatus "unable to turn on ramp: $result"
                                    return -code error $result
                                }
				SetStatus "$result"
				return
			    }
                            if {$measMagnet && [clock seconds]>[expr $startMon + 10]} {
                                set file $outputDir/bmon-[clock format [clock seconds] -format %Y-%m%d:%H%M%S].sdds
                                exec  BRampWaveformMon -filename $file
                                exec sddsprocess $file -nowarnings -redefine=par,LastWakeupTime,$lastWakeupTime
                                set startMon [clock seconds]
                            }
                            after 500
                            update
                        }
			if [catch {PingRunControl} result] {
                            if [catch {APScavput -list=It:Ddg4chan0.GATE=1} result] {
                                SetStatus "unable to turn on ramp: $result"
                                return -code error $result
                            }
			    SetStatus "$result"
			    return
			}
                    }
                }
                if {!$firstSleep && !$firstWake} {
                    break
                } else {
		    if [catch {PingRunControl} result] {
                        if [catch {APScavput -list=It:Ddg4chan0.GATE=1} result] {
                            SetStatus "unable to turn on ramp: $result"
                            return -code error $result
                        }
			SetStatus "$result"
			return
		    }
                    after 1000
                    continue
                }
		if [catch {PingRunControl} result] {
                    if [catch {APScavput -list=It:Ddg4chan0.GATE=1} result] {
                        SetStatus "unable to turn on ramp: $result"
                        return -code error $result
                    }
		    SetStatus "$result"
		    return
		}
            }
        } else {
	    set endTime [expr [clock seconds] + $wakeTime * 60]
            if [catch {WakeUp -cycle $i } result] {
                if [catch {APScavput -list=It:Ddg4chan0.GATE=1} result] {
                    SetStatus "unable to turn on ramp: $result"
                    return -code error $result
                }
		SetStatus "$result"
		return
	    }
            set startMon [clock seconds]
            SetStatus "Waiting ..."
            while {[clock seconds]<$endTime} {
		if [catch {PingRunControl} result] {
                    if [catch {APScavput -list=It:Ddg4chan0.GATE=1} result] {
                        SetStatus "unable to turn on ramp: $result"
                        return -code error $result
                    }
		    SetStatus "$result"
		    return
		}
                if {$measMagnet && [clock seconds]>[expr $startMon + 10]} {
                    set file $outputDir/bmon-[clock format [clock seconds] -format %Y-%m%d:%H%M%S].sdds
                    exec  BRampWaveformMon -filename $file
                    exec sddsprocess $file -nowarnings -redefine=par,LastWakeupTime,$lastWakeupTime
                    set startMon [clock seconds]
                }
		### disable beam at end of wake time
		set disable 1
                after 1000
                update    
            }
	    if [catch {PingRunControl} result] {
                if [catch {APScavput -list=It:Ddg4chan0.GATE=1} result] {
                    SetStatus "unable to turn on ramp: $result"
                    return -code error $result
                }
		SetStatus "$result"
		return
	    }
            LoadSafetyWhenSleeping
            set endTime [expr [clock seconds] + $sleepTime * 60]
            SetStatus "disable BM ramp."
            if [catch {APScavput -list=It:Ddg4chan0.GATE=0} result] {
                SetStatus "Error in disabling BM ramp: $result"
                return -code error $result
            }
	    if [catch {PingRunControl} result] {
                if [catch {APScavput -list=It:Ddg4chan0.GATE=1} result] {
                    SetStatus "unable to turn on ramp: $result"
                    return -code error $result
                }
		SetStatus "$result"
		return
	    }
            SetStatus "Sleeping $sleepTime minutes..."
	    set disable 1
	    ### disable beam while sleeping
	    EnableDisableBeam -enable 0
            set first 1
            while {[clock seconds]<$endTime} {
		if [catch {PingRunControl} result] {
		    SetStatus "$result"
		    return
		}
		###		EnableDisableBeam
                after 1000
                update
            }
        }
    }
    set abort 0
    if [catch {APScavput -list=It:Ddg4chan0.GATE=1} result] {
        SetStatus "Error in enabling BM ramp: $result"
	return -code error $result
    }
    ResumeRampAfterAbort
    SetStatus "ramp test done."
    incr index
}

proc StartAutoCorrection {args} {
    global apsScriptHost apsScriptCommand apsScriptUser BM QD QF
    
    foreach supply {BM QD QF} {
        if [set $supply] {
            #check auto-correction run control
            if [catch {APScavget -list=B:${supply}:AutoCorrectionControlRC.RUN -pend=10} running] {
                return -code error "unable to read B:${supply}:AutoCorrectionControlRC.RUN: $running."
            }
            if $running {
		SetStatus "suspend $supply auto-correction..."
		if [catch {APScavput -list=B:${supply}:AutoCorrectionControlRC.SUSP=1} result] {
		    return -code error "unable to suspend $supply auto-correction: $result"
		}
		after 1000
	    }
            SetStatus "start $supply ramp auto correction ..."
            if [catch {BoosterRampVCorrectAndCheck -supply $supply -application RampTest \
                         -user $apsScriptUser -host $apsScriptHost } result] {
                SetStatus "$supply auto correction error: $result; the correction may not be done yet."
            } else {
		SetStatus "done."
	    }
	    if $running {
		after 1000
		SetStatus "resume $supply auto-correction..."
		if [catch {APScavput -list=B:${supply}:AutoCorrectionControlRC.SUSP=0} result] {
		    return -code error "unable to resume $supply auto-correction: $result"
		}
	    }
	    
        }
    }
}

set safetyDir /home/helios/oagData/booster/ramps/IRamp/safety
foreach magnet {BM QF QD SF SD} {
    set sleep${magnet}Load 0
}
set  sleepQDLoad  1
proc LoadSafetyWhenSleeping {args} {
    global safetyDir sleepBMLoad sleepQFLoad sleepQDLoad sleepSFLoad sleepSDLoad IRamp
    ## check afg gain and trigger values. If exceed limit load safety ramp.
    set ramp ""
    foreach magnet {BM QF QD SF SD} {
        if [set sleep${magnet}Load] {
            lappend ramp $magnet
        }
    }
    if [llength $ramp] {
        SetStatus "loading safety ramps for [join $ramp ,] when sleeping..."
        if [catch {APSBoosterLoadSafetyRamp -BM $sleepBMLoad -QF $sleepQFLoad \
                     -QD $sleepQDLoad -SF $sleepSFLoad -SD $sleepSDLoad -IRamp $IRamp \
                     -statusCallback SetStatus -description "load safety ramps when sleep from energy saver" } result] {
            return -code error $result
        }
        SetStatus "done."
    }
    return
    set BMgain [exec caget -t B:BM:VoltageRT.GAIN ]
    set BMtrigger [exec caget -t It:Bs:BmVafgTrigAO.VAL ]
    after 3000
    if { $BMgain>=0.98 || $BMtrigger<-0.4 } {
        exec rampload \
          ${safetyDir}/BMVref.afg100
        set BMgain [ exec sdds2stream \
                       ${safetyDir}/BMVref.afg100 \
                       -para=afgGain ]
        set BMtrigger [ exec sdds2stream \
                          ${safetyDir}/BMVref.afg100 \
                          -para=afgTrigger]
        exec caput B:BM:VoltageRT.GAIN $BMgain
        exec caput It:Bs:BmVafgTrigAO.VAL $BMtrigger
        set bcontrolLock [exec caget -t -n B:BM:BconLockedMBBO] 
        if { $bcontrolLock } {
            exec caput B:BM:VoltageRT.SWAP 1
            after 500 
            exec caput B:PSAFG100SyncBO 1
        }
    }
    
}

proc SuspendResumeAutoCorrection {args} {
    set suspend 1
    APSParseArguments {suspend}
    return
    if [catch {APScavput -list=B: -list=BM,QF,QD,SF,SD -list=:AutoCorrectionControlRC.SUSP=$suspend -pend=30} result] {
        return -code error $result
    }
}
set slopeLimit 0.1
proc LoadSafetyWhenWakeup {args} {
    global safetyDir slopeLimit
    #### check to see whether slope outof range. If it is load safety ramp. 
    set BMSlopeSet [exec caget -t B:BM:SlopeRefAO ]
    set BMSlopeMeas [exec caget -t B:BM:RampSlopeAI]
    if { [expr abs($BMSlopeSet-$BMSlopeMeas)] >$slopeLimit } {
        exec rampload \
          ${safetyDir}/BMVref.afg100
        set BMgain [ exec sdds2stream \
                       ${safetyDir}/BMVref.afg100 \
                       -para=afgGain ]
        set BMtrigger [ exec sdds2stream \
                          ${safetyDir}/BMVref.afg100 \
                          -para=afgTrigger]
        exec caput B:BM:VoltageRT.GAIN $BMgain
        exec caput It:Bs:BmVafgTrigAO.VAL $BMtrigger
        set bcontrolLock [exec caget -t -n B:BM:BconLockedMBBO] 
        if { $bcontrolLock } {
            exec caput B:BM:VoltageRT.SWAP 1
            after 500 
            exec caput B:PSAFG100SyncBO 1
	}
    }
}

proc SendToRampLogFile {text} {
    global rampLogFileID
    puts $rampLogFileID "$text (at [clock format [clock seconds]])"
    #flush $rampLogFileID
}

proc Info {args} {
    global runControlPV
    exec medm -x -attach -macro "RCPV=$runControlPV" ./sr/psApp/APSRunControlSingle.adl &
}

proc UpdateRampInfo {args} {
    global IRamp rmsPV rootname safetyDir
    if $IRamp {
        set rmsPV B:BM:DeltaIrmsAO 
        set rootname boosterIRamp
        set safetyDir /home/helios/oagData/booster/ramps/IRamp/safety
    } else {
        set rmsPV B:BM:IRampRMSAI
        set rootname boosterRamp
        set safetyDir /home/helios/oagData/booster/ramps/VRamp/safety
    }
}
                   
set monFile /home/helios/oagData/booster/ramps/rampTest/rampTest.mon
set voltageWaveformMon /home/helios/oagData/booster/ramps/rampTest/voltage.wmon
set currentWaveformMon /home/helios/oagData/booster/ramps/rampTest/current.wmon
set outputDir [APSGoToDailyDirectory -subdirectory rampTest]

APSApplication . -name "Booster Energy Save" -version $CVSRevisionAuthor \
  -overview "scan par kickers and setup par kicker timing."

set status "Ready."
set sleepTime 1
set wakeTime 1
set correctCycles 1
set waitTime 30
set cycles 5
 #in minutes units
set wakeToInj 60
set IRamp 1
set rmsPV B:BM:DeltaIrmsAO 
set rootname boosterIRamp
APSScrolledStatus .status -parent .userFrame -textVariable status \
    -width 70 -height 8


APSLabeledEntry .dir -parent .userFrame -width 70 \
  -label "Output dir: " -textVariable outputDir \
  -contextHelp \
  "Enter a directory in which the output files will be written."
APSButton .dialy -parent .userFrame.dir -text "daily" -size small \
  -command {set outputDir [APSGoToDailyDirectory -subdirectory rampTest]} \
  -packOption "-side right" \
  -contextHelp "Set the output dir to APS daily directory"
APSRadioButtonFrame .type -parent .userFrame -label "Ramp type: " -buttonList {VRamp IRamp} -valueList {0 1} \
  -orientation horizontal -commandList {UpdateRampInfo UpdateRampInfo} -variable IRamp
APSLabeledEntry .rootname -parent .userFrame -width 70 \
  -label "Output rootname: " -textVariable rootname \
  -contextHelp \
  "Enter a rootname for generation of the output filenames."

set width 21
set steps 5
set BM 1
set QF 0
set QD 0
set enable 0
set disable 0
set sleepLoadSafety 0
set wakeupLoadSafety 0
set corrWaitTime 25
set injWaitTime 30 
set logWaveform 0
set logFile /home/helios/oagData/booster/ramps/rampTest/rampTest.log
#set rampLogFileID [open $logFile "a+"]

#APSLabeledEntry .cycles -parent .userFrame -width $width -label "Number of cycles for each ramp auto correction:" \
#  -textVariable correctCycles 
APSLabeledEntry .steps -parent .userFrame -width $width -label "Number to cycles to test:" -textVariable cycles
APSFrameGrid .grid -parent .userFrame -xList {x1 x2}
set w1 .userFrame.grid.x1
set w2 .userFrame.grid.x2
APSFrame .f -parent $w1 -label "Non-topup parameters"
APSLabeledEntry .interval -parent $w1.f.frame -width $width -label "Ramp sleep time (minutes):" \
    -textVariable sleepTime
APSLabeledEntry .wake -parent $w1.f.frame -width $width -label "Ramp wake time (minutes):" \
    -textVariable wakeTime
APSFrame .f -parent $w2 -label "Topup parameters"
APSLabeledEntry .inj -parent $w2.f.frame -label "Wakeup to injection time (seconds):" -textVariable wakeToInj \
  -width $width -contextHelp "define the wakeup time, i.e., wake up when the time to injection is less than the given number."

APSCheckButtonFrame .sleep -parent .userFrame -label "Load safety ramp when sleep for selected magnet:" \
  -buttonList {BM QF QD SF SD} -variableList {sleepBMLoad sleepQFLoad sleepQDLoad sleepSFLoad sleepSDLoad} \
  -orientation horizontal -allNone 1
APSRadioButtonFrame .wake -parent .userFrame -label "Load safety ramp when wakeup?" \
  -buttonList {Yes No} -variable wakeupLoadSafety -valueList {1 0} -orientation horizontal
APSLabeledEntry .wait -parent .userFrame -label "Wait time for ramp correction after wakeup:" -width 15 \
    -textVariable corrWaitTime
APSLabeledEntry .waitInj -parent .userFrame -label "Wait time for turning on injection:" -width 15 \
    -textVariable injWaitTime
APSCheckButtonFrame .ramp -parent .userFrame -buttonList {BM QF QD} -variableList {BM QF QD} -label "select supplies for on/off toggling:" \
  -allNone 1 -orientation horizontal
set measMagnet 0
APSRadioButtonFrame .mag -parent .userFrame -label "Measurement magnetic parameters?" -buttonList {Yes No} \
  -valueList {1 0} -variable measMagnet -orientation horizontal
APSRadioButtonFrame .wav -parent .userFrame -label "Log Waveform file?" -buttonList {Yes No} \
  -valueList {1 0} -variable logWaveform -orientation horizontal
set disableEnableBeam 0
APSRadioButtonFrame .beam -parent .userFrame -label "Disable/Enable beam at non-topup mode?" \
  -variable disableEnableBeam -buttonList {Yes No} -valueList {1 0} \
  -orientation horizontal -contextHelp "choose wether to enable/disable beam when turn on/off BM at non-topup mode."
APSButton .start -parent .userFrame -text "Start" -command "Start"
APSButton .abort -parent .userFrame -text "Abort" -command "Abort"
APSButton .plot -parent .userFrame -text "Plot" -command "PlotData"
APSButton .enable -parent .userFrame -text "Enable BTS beam" -command "set enable 1;APScavput -list=L1:RG1:KIK:chargeTrigC=1,L1:RG2:KIK:chargeTrigC=1;TogglePulsedMagnetEnables -location GuntoBoosterExt"
APSButton .disable -parent .userFrame -text "Disable BTS beam" -command "set disable 1;SetPulsedMagnetEnables -location BoosterExt"
APSButton .info -parent .userFrame -text "Info" -command "Info"




