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

# $Log: not supported by cvs2svn $
# Revision 1.19  1997/02/19 03:20:54  borland
# Added momentary on control of pulsed magnet charge signals.
#
# Revision 1.18  1996/12/19 23:47:12  borland
# Added default value for septum startup file.
#
# Revision 1.17  1996/10/01 13:43:19  borland
# Fixed exec statement so that the screen actually comes up.
#
# Revision 1.16  1996/09/19 21:51:19  borland
# Changed from using "exec wish" to "exec oagwish".
#
# Revision 1.15  1996/06/18 18:21:33  borland
# Changed name of SR snapshot directory.
#
# Revision 1.14  1996/05/02  23:19:58  borland
# Now has separate buttons for IS1, IS2, and IS1+IS2 startup.
#
# Revision 1.13  1996/03/24  15:56:50  borland
# Changed RESET button so that it brings up new timingResets screen.
#
# Revision 1.12  1996/03/07  16:54:22  borland
# Fixed bug in shutter permt checking.
#
# Revision 1.11  1996/03/04  20:04:27  saunders
# Added revision/author to Version menu.
#
# Revision 1.10  1996/02/19  20:15:50  borland
# Added check of shutter permit prior to directing beam to the ring.
#
# Revision 1.9  1996/01/26  15:55:23  borland
# Added check of photon shutter position prior to switching beam into ring.
#
# Revision 1.8  1996/01/19  16:18:34  borland
# Retargeted to oagData directory from borland account.
#
# Revision 1.7  1996/01/17  16:59:09  saunders
# Added /usr/local/oag/lib_patch to front to auto_path.
#
# Revision 1.6  1996/01/16  21:11:49  saunders
# Fixed log entry problem, so now comments and version numbers
# appear properly. Also, renames X.tcl files to just X.
#
# Revision 1.5  1996/01/12 01:22:39  borland
# Added switching of BTS:AB for beam-to-ring and beam-to-dump buttons.
#
# Revision 1.4  1996/01/09  01:16:28  borland
# Added TogglePulsedMagnetEnables procedure and RESET button to run it.
#
# Revision 1.3  1995/12/15  20:12:22  saunders
# Added proper installation Makefile and Log
#

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

set CVSRevisionAuthor "\$Revision: 1.20 $ \$Author: emery $"

set snapDir /home/helios/oagData/SCR/snapshots/SR

APSApplication . -name SRpulsed -version $CVSRevisionAuthor \
  -overview {This utility permits controlling storage-ring pulsed magnet high-voltage levels and charge pulses.  It also provides one-button switching of the beam between the BTX dump and the storage ring.}

APSFrameGrid .fstack -parent .userFrame -yList {kicker septum both btsx pms charge} -relief ridge

label .userFrame.fstack.kicker.label -text "SR Kickers"
pack .userFrame.fstack.kicker.label
APSButton .kickWarm -parent .userFrame.fstack.kicker -text "KICKER WARMUP"  \
  -command "DoKickerWarmup" \
  -contextHelp "Warms up all of the kickers for the storage ring." 
APSButton .hvon -parent .userFrame.fstack.kicker -text "HV ON" \
  -command "exec SRHVset 1" \
  -contextHelp "Turns on the high voltage for storage ring kickers IK1 through IK4." 
APSButton .hvoff -parent .userFrame.fstack.kicker -text "HV OFF" \
  -command "exec SRHVset 0" \
  -contextHelp "Turns off the high voltage for storage ring kickers IK1 through IK4." 

label .userFrame.fstack.septum.label -text "SR Septum Startup"
pack .userFrame.fstack.septum.label 
APSButton .startup0 -parent .userFrame.fstack.septum -text "IS1" \
  -command "DoSeptumStartup IS1" \
  -contextHelp "Executes startup procedure for IS1.  Note that it is best to start up only one septum at a time.  Use the BOTH button to do the septa sequentially."
APSButton .startup1 -parent .userFrame.fstack.septum -text "IS2" \
  -command "DoSeptumStartup IS2" \
  -contextHelp "Executes startup procedure for IS2.  Note that it is best to start up only one septum at a time. Use the BOTH button to do the septa sequentially."
APSButton .startup2 -parent .userFrame.fstack.septum -text "BOTH" \
  -command "DoSeptumStartup both" \
  -contextHelp "Executes startup procedure for IS1 then IS2."


label .userFrame.fstack.both.label -text "SR Kickers and Septa" 
pack .userFrame.fstack.both.label
APSButton .chargeOn -parent .userFrame.fstack.both -text "CHARGE ON" \
  -command "exec SRChargeSet 1" \
  -contextHelp "Turns on the charge pulses for storage ring kickers and septa." 
APSButton .chargeOff -parent .userFrame.fstack.both -text "CHARGE OFF" \
  -command "exec SRChargeSet 0" \
  -contextHelp "Turns off the charge pulses for storage ring kickers and septa." 

set w .userFrame.fstack.charge
label $w.label -text "Charge momentary on"
pack $w.label
set IS1MomentaryOn 0
set IS2MomentaryOn 1
set IKMomentaryOn 0
APSCheckButtonFrame .cb -parent $w -label "System" \
  -orientation horizontal -buttonList {IS1 IS2 IK} \
  -variableList {IS1MomentaryOn IS2MomentaryOn IKMomentaryOn} \
  -allNone 1 
set MomentaryOnTime 10
set MomentaryTimeLeft ?
APSLabeledEntry .duration -parent $w -label "Duration (s) " \
  -textVariable MomentaryOnTime -width 10 -contextHelp \
  "Enter the duration in seconds of the momentary turn-on of pulsed magnet charge signals."
APSLabeledOutput .left -parent $w -label "Time left (s) " \
  -textVariable MomentaryTimeLeft -width 10 -contextHelp \
  "Shows the duration left in seconds of the momentary turn-on of pulsed magnet charge signals."
APSButton .momOn -parent $w -text "Go" \
  -contextHelp "Turns on selected pulsed supplies for the given time." \
  -command "DoMomentaryOn $w.momOn.button"

proc DoMomentaryOn {widget} {
    global IS1MomentaryOn IS2MomentaryOn IKMomentaryOn MomentaryOnTime
    global MomentaryTimeLeft
    set PVList ""
    if $IS1MomentaryOn {
        lappend PVList Mt:Ddg3chan0
    }
    if $IS2MomentaryOn {
        lappend PVList Mt:Ddg3chan1
    }
    if $IKMomentaryOn {
        lappend PVList Mt:Ddg3chan4
    }
    bell
    if [catch {exec cavput -list=[join $PVList ,] -list=.GATE=1} result] {
        puts stderr $result
    }
    set MomentaryTimeLeft $MomentaryOnTime
    APSDisableButton $widget
    update idletasks
    while {$MomentaryTimeLeft>0} {
        after [expr 1000]
        set MomentaryTimeLeft [expr $MomentaryTimeLeft-1]
        update idletasks
    }
    catch {exec cavput -list=[join $PVList ,] -list=.GATE=0}
    APSEnableButton $widget
    update idletasks
    bell
}


proc ShutterPermit {} {
    global errorCode
    if [catch {exec cavget -list=ACIS:ShutterPermit -pend=5} result] {
        APSAlertBox [APSUniqueName .] \
          -errorMessage "Couldn't read shutter permit PV: $errorCode"
        return 1
    }
    if [string compare $result "PERMIT"]==0 {
        APSAlertBox [APSUniqueName .] \
          -errorMessage "Shutter permit is on--can't direct beam to ring."
        return 1
    }
    return 0
}

set shutterPVList {1ID 1BM 3ID 3BM}
proc PhotonShuttersAreClosed {} {
    global errorCode shutterPVList
    set code [catch {exec cavget -list=ACIS:RAI_ \
                       -list=[join $shutterPVList ,] \
                       -list=_CLOSED \
                       -pend=5} result]
    if $code {
        APSAlertBox [APSUniqueName .] \
          -errorMessage "Couldn't read shutter PVs: Error: $errorCode"
        return 0
    }

    set dataList [split $result "\n"]
    if [llength $dataList]!=[llength $shutterPVList] {
        APSAlertBox [APSUniqueName .] \
          -errorMessage "Insufficient data returned to assess shutter status."
        return 0
    }
    set index 0
    foreach elem $dataList {
        if [string compare $elem "?"]==0 {
            APSAlertBox [APSUniqueName .] \
              -errorMessage "PV [lindex $shutterPVList $index] not found. Can't verify shutter status."
            return 0
        }
        if [string compare $elem 0]!=0 {
            APSAlertBox [APSUniqueName .] \
              -errorMessage "Shutter [lindex $shutterPVList $index] is open.  Can't direct beam to ring."
            return 0
        }
    }
    return 1
}


proc switchRingAndDump {mode} {
    switch $mode {
        ring {
            if [ShutterPermit] {
                return
            }
            catch {exec cavput -list=BTS:BX=0,BTS:AB=319.05 -list=:CurrentAO -pend=10} result
        }
        dump {
            catch  {exec cavput -list=BTS:BX=320,BTS:AB=0 -list=:CurrentAO -pend=10} result
        }
        - {
            APSAlertBox [APSUniqueName .] -errorMessage "Invalid mode $mode to switchRingAndDump" 
        }
    }

    if [string length $result] {
        APSAlertBox [APSUniqueName .] -errorMessage "Error returned from cavput (try again): $result"
    }
}


label .userFrame.fstack.btsx.label  -text "BTS:BX"
pack .userFrame.fstack.btsx.label 
APSButton .toBeamDump -parent .userFrame.fstack.btsx -text "GO TO DUMP" \
  -command "switchRingAndDump dump" \
  -contextHelp "Sets the BTS:BX dipole to 320A and BTS:AB to 0, directing the beam to the BTX dump." 
APSButton .toRing -parent .userFrame.fstack.btsx -text "GO TO RING" \
  -command "switchRingAndDump ring" \
  -contextHelp "Sets the BTS:BX dipole to 0A and BTS:AB to 319.05A directing the beam to the storage ring." 

label .userFrame.fstack.pms.label -text "Pulsed Magnet Timeouts"
pack  .userFrame.fstack.pms.label
APSButton .resetTimeouts -parent .userFrame.fstack.pms -text "RESETS..." \
  -command "exec timingResets & " \
  -contextHelp "Brings up an application for pulsed magnet charge enable control."

set septumStartupFile "SR-InjectionReference.gz"
proc DoSeptumStartup {septum} {
    global snapDir septumStartupFile
    set septumStartupFile \
      [APSInfoDialog .[APSTmpString] \
         -name "Septum startup query" \
         -default $septumStartupFile \
         -infoMessage "Enter the snapshot filename from the SCR tool." -width 50]
    if [string length $septumStartupFile]==0 return

    switch $septum {
        IS1 {
            APSExecLog .[APSTmpString] -unixCommand "SRSeptumStartup IS1 $snapDir/$septumStartupFile" \
              -callback "SignalDone IS1 startup"
        }
        IS2 {
            APSExecLog .[APSTmpString] -unixCommand "SRSeptumStartup IS2 $snapDir/$septumStartupFile" \
              -callback "SignalDone IS2 startup"
        }
        both {
            APSExecLog .[APSTmpString] -unixCommand "SRSeptumStartup IS1 $snapDir/$septumStartupFile" \
              -callback "DoSeptumStartup IS2"
        }
    }
}

proc DoKickerWarmup {} {
    APSExecLog .[APSTmpString] -unixCommand "SRKickerWarmup" \
      -callback "SignalDone kickers warmup"
}

proc SignalDone {thing action} {
    APSInfoWindow .[APSTmpString] -infoMessage "Done with $action for $thing.  Check status in unix command window."
}


proc TogglePulsedMagnetEnables {} {
    for {set i 0} {$i < 2} {incr i} {
        eval exec cavput -list=It:Ddg3chan2.GATE=$i,It:Ddg2chan6.GATE=$i,Mt:Ddg1chan4.GATE=$i,Mt:Ddg1chan5.GATE=$i,Mt:Ddg1chan0.GATE=$i,It:Ddg2chan4.GATE=$i,It:ER1:er.OTL2=$i,It:ParInjChargeDDG.GATE=$i,It:ParExtChargeDDG.GATE=$i,It:Par:PSPchargeBO.VAL=$i
        exec sleep 1
    }
}

