
# RFGun Shutdown Procedure
# 1. Signal any active RFGun control script to shut down
# 2. Set the RFGun cathode heater to 1 Amp (standby current)
# 3. Set the alpha magnet to 0 Amps and turn the supply off
# 4. Start the alpha magnet degauss procedure
# 5. Close the RFGun gate valve
# 6. Turn off the kicker voltage

proc RFGUN+LMOCS_ShutdownWithPSInfo {} {
    return "This procedure calls RFGUN_Shutdown, LMOCS_Modulator_Shutdown and APSMpLShutDownPS"
}

proc RFGUN+LMOCS_ShutdownWithPS {args} {
    set sectors "L1 L2 L3 L4 L5 L6"
    foreach sector $sectors {
	set $sector 0
    }
    set turnOffList "" 
    set conditionList "" 
    set turnOffListDetailed "" 
    set conditionListDetailed "" 
    set HTRCurrentAO ""
    set KIKVoltSetSendAO ""
    set RFGUN 0
    set PowerSupplies 0
    set Modulators 0
    set SCRFile ""
    set includeFilament 0
    global execMode

    if {$execMode == "Manual"} {
	set prefix "Press Continue to "
    } else {
	set prefix ""
    }

    if {[catch {APSLinkToLINACPVs} result]} {
	APSMpReturn error "RFGUN+LMOCS_ShutdownWithPS: $result"
    }
    
    if {[catch {APSRFGUN_DetectSelectedGun} gun]} {
	APSMpReturn error "RFGUN+LMOCS_ShutdownWithPS: $gun"
    }
    APSStrictParseArguments {gun L1 L2 L3 L4 L5 L6 RFGUN PowerSupplies Modulators SCRFile turnOffList conditionList turnOffListDetailed conditionListDetailed includeFilament}

    global APSMpLControlPS
    
    set arrayName APSMpLControlPS
    APSLGenericPSArraySetup  \
	-arrayName $arrayName \
	-turnOffList $turnOffList \
        -conditionList $conditionList \
	-turnOffListDetailed $turnOffListDetailed \
        -conditionListDetailed $conditionListDetailed \
        -SCRFile $SCRFile
    
    if {(![file exists $SCRFile]) && ($execMode == "Automatic")} {
	set execMode "Semi-Automatic"
    }

    #foreach var $APSMpLControlPS(TurnOff,DeviceVariableList) {set $var 0}
    #foreach var $APSMpLControlPS(TurnOff,DetailedDeviceVariableList) {set $var 0}

    APSMpStep init -promptDialog \
	"APSLGenericPSDialog -packProc RFGUN+LMOCS_ShutdownWithPSPackProc -packProcBottom RFGUN+LMOCS_ShutdownWithPSPackProcBottom -turnOff 1 -condition 1 -arrayName $arrayName -chooseSCR 1 -frame " -vars {L1 L2 L3 L4 L5 L6 RFGUN PowerSupplies Modulators includeFilament}
    set SCRFile $APSMpLControlPS(Filename)
    set turnOffList [APSLGenericPSArrayQuery -arrayName $arrayName -operation TurnOff]
    set turnOffListDetailed [APSMpLConvertDeviceNames -operation TurnOff -deviceList $turnOffList]
    set turnOffListDetailed [APSMpLConvertDetailedDeviceNames -operation TurnOff -deviceList $turnOffListDetailed -arrayName $arrayName]
    set conditionList [APSLGenericPSArrayQuery -arrayName $arrayName -operation StartConditioning]
    set conditionListDetailed [APSMpLConvertDeviceNames -operation StartConditioning -deviceList $conditionList]
    set conditionListDetailed [APSMpLConvertDetailedDeviceNames -operation StartConditioning -deviceList $conditionListDetailed -arrayName $arrayName]

    if {[file exists $SCRFile]} {
        if {[catch {exec sdds2stream $SCRFile -parameter=SnapshotDescription -page=1 -noquotes} results]} {
            APSMpReturn error "RFGUN+LMOCS_ShutdownWithPS: Invalid SCR file"
        }    
        if {[string first "Limited save:" $results] != -1} {
            if {[catch {exec sddssort $SCRFile -pipe=out -column=Beamline -unique | sdds2stream -pipe=in -col=Beamline} results]} {
                APSMpReturn error "RFGUN+LMOCS_ShutdownWithPS: Problem reading beamlines categories from the SCR file"
            } else {
                if {([lsearch -exact $results L1] == -1) || \
                      ([lsearch -exact $results L2] == -1) || \
                      ([lsearch -exact $results L3] == -1) || \
                      ([lsearch -exact $results L4] == -1) || \
                      ([lsearch -exact $results L5] == -1) || \
                      ([lsearch -exact $results rfGun] == -1) || \
                      ([lsearch -exact $results rfGun1] == -1) || \
                      ([lsearch -exact $results rfGun2] == -1)} {
                    APSMpReturn error "RFGUN+LMOCS_ShutdownWithPS: LIMITED SAVE SCR file does not include all the Linac and rfGun beamline categories"
                }
            }
        }
    }
    set paramString ""
    foreach param {L1 L2 L3 L4 L5 L6 RFGUN PowerSupplies Modulators SCRFile turnOffList conditionList includeFilament} {
        append paramString "$param=\"[set $param]\" "
    }
    catch {APSLogScriptAction -procedure RFGUN+LMOCS_ShutdownWithPS -action initialize -state ok -parameters $paramString}

    if {$RFGUN} {
        APSMpStep "${prefix}Close gate valves" -desc "Close the gate valves"
        if {[catch {
            APSRFGUN_OpenCloseGateValve -deviceList "L1GV1 L1GV2 L2GV1 L3GV1 L4GV1 L5GV1" -value Close -group LinacValves
        } result]} {
            if {[APSPEMTKDialog .warningDialog -text "Unable to close the gate values\nRFGUN+LMOCS_ShutdownWithPS: $result"] == 1} {
                APSMpReturn error "RFGUN+LMOCS_ShutdownWithPS: $result"
            }
#            APSMpReturn error "RFGUN+LMOCS_ShutdownWithPS: $result"
        }
    }

    if {$PowerSupplies} {
        set turnOffList [APSLGenericPSArrayQuery -arrayName $arrayName -operation TurnOff]
        APSMpStep "${prefix}Shut down power supplies" -desc "Shut down power supplies" -proc APSMpLShutDownPS
        set id1 [APSMpParallel \
                     -procedure "APSMpLShutDownPS -turnOffList \"$turnOffList\" -turnOffListDetailed \"$turnOffListDetailed\" -conditionList \"$conditionList\" -conditionListDetailed \"$conditionListDetailed\" -SCRFile $SCRFile" \
                     -mode "Automatic"]
    }
    if {$RFGUN} {
        APSMpStep "${prefix}Shut down RFGUN" -desc "Shut down RFGUN" -proc RFGUN_Shutdown
        set options "-gun $gun "
        if {[llength $HTRCurrentAO]} { append options "-HTRCurrentAO $HTRCurrentAO " }
        if {[llength $KIKVoltSetSendAO]} { append options "-KIKVoltSetSendAO $KIKVoltSetSendAO " }
        set id2 [APSMpParallel \
                     -procedure "RFGUN_Shutdown $options" \
                     -mode "Automatic"]
    }
    if {$Modulators} {
        set LMOCS_Selected 0
        foreach sector $sectors {
            if {[set $sector]} {
                set LMOCS_Selected 1
            }
        }
        if {$LMOCS_Selected} {
            APSMpStep "${prefix}Shutdown Modulators" -desc "Shutdown Modulators" -proc LMOCS_Modulator_Shutdown
            set id3 [APSMpParallel -procedure "LMOCS_Modulator_Shutdown -L1 $L1 -L2 $L2 -L3 $L3 -L4 $L4 -L5 $L5 -L6 $L6 -includeFilament $includeFilament" -mode "Automatic"]
        }
    }

#    APSMpAbort all -onError 1
    if {$Modulators} {
        if {$LMOCS_Selected} {
            if {[catch {APSMpJoin $id3} results]} {
                if {[APSPEMTKDialog .warningDialog -text "Problem occured in modulator shutdown\nRFGUN+LMOCS_ShutdownWithPS: $results"] == 1} {
                    APSMpReturn error "RFGUN+LMOCS_ShutdownWithPS: $results"
                }
#                APSMpReturn error "RFGUN+LMOCS_ShutdownWithPS: $results"
            }
        }
    }
    if {$PowerSupplies} {
        if {[catch {APSMpJoin $id1} results]} {
            if {[APSPEMTKDialog .warningDialog -text "Problem occured in power supply shutdown\nRFGUN+LMOCS_ShutdownWithPS: $results"] == 1} {
                APSMpReturn error "RFGUN+LMOCS_ShutdownWithPS: $results"
            }
#            APSMpReturn error "RFGUN+LMOCS_ShutdownWithPS: $results"
        }
    }
    if {$RFGUN} {
        if {[catch {APSMpJoin $id2} results]} {
            if {[APSPEMTKDialog .warningDialog -text "Problem occured in rfgun shutdown\nRFGUN+LMOCS_ShutdownWithPS: $results"] == 1} {
                APSMpReturn error "RFGUN+LMOCS_ShutdownWithPS: $results"
            }
#            APSMpReturn error "RFGUN+LMOCS_ShutdownWithPS: $results"
        }
        
        if {[catch {APSRFGUN_TurnKickerOnOff -deviceList 1 -value 0 -state off} result]} {
            if {[APSPEMTKDialog .warningDialog -text "Unable to turn rfgun 1 kicker off\nRFGUN+LMOCS_ShutdownWithPS: $result"] == 1} {
                APSMpReturn error "RFGUN+LMOCS_ShutdownWithPS: $result"
            }
#            APSMpReturn error "RFGUN+LMOCS_ShutdownWithPS: $result"
        }
        if {[catch {APSRFGUN_TurnKickerOnOff -deviceList 2 -value 0 -state off} result]} {
            if {[APSPEMTKDialog .warningDialog -text "Unable to turn rfgun 2 kicker off\nRFGUN+LMOCS_ShutdownWithPS: $result"] == 1} {
                APSMpReturn error "RFGUN+LMOCS_ShutdownWithPS: $result"
            }
#            APSMpReturn error "RFGUN+LMOCS_ShutdownWithPS: $result"
        }
        if {[catch {APScavget -list=L1:RG1:HTR:VoltageAO,L1:RG2:HTR:VoltageAO} heaterVoltages]} {
           
        } else {
            if {[lindex $heaterVoltages 0] > 2} {
                catch {APScavget -list=L1:RG1:HTR:VoltageAO=2.0}
            }
            if {[lindex $heaterVoltages 1] > 2} {
                catch {APScavget -list=L1:RG2:HTR:VoltageAO=2.0}
            }
        }

        if {0} {
            if {[catch {
                APSDevSend \
                  -group LinacRFGun \
                  -operation SetCathodeHeaterCurrent \
                  -deviceList "1 2" \
                  -valueList "0 0"
                APSWaitWithUpdate -waitSeconds 5
                APSDevSend \
                  -group LinacRFGun \
                  -operation TurnOffHeaterPower \
                  -deviceList "1 2"
            } result]} {
                if {[APSPEMTKDialog .warningDialog -text "Unable to turn off gun heater power\nRFGUN+LMOCS_ShutdownWithPS: $result"] == 1} {
                    APSMpReturn error "RFGUN+LMOCS_ShutdownWithPS: $result"
                }
            }
        }
    }

    APSMpReturn ok
}

proc RFGUN+LMOCS_ShutdownWithPSPackProc {frame} {
    pack [frame $frame.top]
    button $frame.top.conditioning -text "Toggle with or without conditioning when PS is selected" -command {
        if {[winfo viewable .promptDialog.userFrame.fStartConditioning]} {
            pack forget .promptDialog.userFrame.fStartConditioning
            pack forget .promptDialog.userFrame.scr
        } else {
            pack .promptDialog.userFrame.fStartConditioning
            pack .promptDialog.userFrame.scr
        }
    }
    pack $frame.top.conditioning
    APSCheckButtonFrame .selectSystems \
	-parent $frame.top -label "Select Systems to Shutdown" \
	-variableList {RFGUN+LMOCS_ShutdownWithPS(RFGUN) RFGUN+LMOCS_ShutdownWithPS(PowerSupplies) RFGUN+LMOCS_ShutdownWithPS(Modulators)} \
	-buttonList {"RFGUN                   " "Power Supplies          " "Modulators              "} \
	-allNone 1 \
	-packOption {-side top} \
	-orientation vertical
    APSCheckButtonFrame .selectSectors \
	-parent $frame.top -label "Select Modulators To Shutdown" \
	-variableList {RFGUN+LMOCS_ShutdownWithPS(L1) RFGUN+LMOCS_ShutdownWithPS(L2) RFGUN+LMOCS_ShutdownWithPS(L3) RFGUN+LMOCS_ShutdownWithPS(L4) RFGUN+LMOCS_ShutdownWithPS(L5) RFGUN+LMOCS_ShutdownWithPS(L6)} \
	-buttonList {K1 K2 K3 K4 K5 K6} \
	-allNone 1 \
	-packOption {-side top} \
	-orientation horizontal
    checkbutton $frame.top.filament -text "Include Modulator Filament" \
      -variable RFGUN+LMOCS_ShutdownWithPS(includeFilament)
    pack $frame.top.filament
}
proc RFGUN+LMOCS_ShutdownWithPSPackProcBottom {frame} {
    pack forget .promptDialog.userFrame.fStartConditioning
    pack forget .promptDialog.userFrame.scr
}
proc RFGUN_ShutdownWithPSInfo {} {
    return "This procedure calls RFGUN_Shutdown and APSMpLShutDownPS"
}

proc RFGUN_ShutdownWithPS {args} {
    set turnOffList "" 
    set conditionList ""
    set HTRCurrentAO ""
    set KIKVoltSetSendAO ""
    global execMode

    if {$execMode == "Manual"} {
	set prefix "Press Continue to "
    } else {
	set prefix ""
    }

    if {[catch {APSLinkToLINACPVs} result]} {
	APSMpReturn error "RFGUN_ShutdownWithPS: $result"
    }
    
    if {[catch {APSRFGUN_DetectSelectedGun} gun]} {
	APSMpReturn error "RFGUN_ShutdownWithPS: $gun"
    }
    APSStrictParseArguments {gun}
    if {$gun == "RG2"} {
	lappend turnOffList L1:RG1:H L1:RG1:V L1:RG1:Q L1:RG1:LFA L1:RG1:LFA:TRM L1:RG2:H L1:RG2:V L1:RG2:Q L1:RG2:LFA L1:RG2:LFA:TRM
	#	lappend turnOffList L1:RG2:SC L1:RG2:QM L1:RG2:LFA L1:RG2:LFA:TRM
    } elseif {$gun == "RG1"} {
	lappend turnOffList L1:RG1:H L1:RG1:V L1:RG1:Q L1:RG1:LFA L1:RG1:LFA:TRM L1:RG2:H L1:RG2:V L1:RG2:Q L1:RG2:LFA L1:RG2:LFA:TRM
    } else {
	APSMpReturn error "RFGUN_ShutdownWithPS: Unable to detect which Gun is selected. Check the LINAC RF Switching System State to ensure it is set to RUNNING and not LOCAL SWITCH or REMOTE SWITCH."
    }
    APSStrictParseArguments {turnOnList conditionList}
    global APSMpLControlPS
    
    set arrayName APSMpLControlPS
    APSLGenericPSArraySetup  \
	-arrayName $arrayName \
	-turnOffList $turnOffList \
	-conditionList $conditionList
    
    APSMpStep init -promptDialog \
	"APSLGenericPSDialog -turnOff 1 -condition 1 -arrayName $arrayName -frame "
    set turnOffList [APSLGenericPSArrayQuery -arrayName $arrayName -operation TurnOff]
    set turnOffListDetailed [APSMpLConvertDeviceNames -operation TurnOff -deviceList $turnOffList]
    set turnOffListDetailed [APSMpLConvertDetailedDeviceNames -operation TurnOff -deviceList $turnOffListDetailed -arrayName $arrayName]
    set conditionList [APSLGenericPSArrayQuery -arrayName $arrayName -operation StartConditioning]
    set conditionListDetailed [APSMpLConvertDeviceNames -operation StartConditioning -deviceList $conditionList]
    set conditionListDetailed [APSMpLConvertDetailedDeviceNames -operation StartConditioning -deviceList $conditionListDetailed -arrayName $arrayName]

    APSMpStep "${prefix}Shut down power supplies" -desc "Shut down power supplies" -proc APSMpLShutDownPS
    set id1 [APSMpParallel \
		 -procedure "APSMpLShutDownPS -turnOffList \"$turnOffList\" -conditionList \"$conditionList\" -turnOffListDetailed \"$turnOffListDetailed\" -conditionListDetailed \"$conditionListDetailed\"" \
		 -mode "Automatic"]
    
    APSMpStep "${prefix}Shut down RFGUN" -desc "Shut down RFGUN" -proc RFGUN_Shutdown
    set options "-gun $gun "
    if {[llength $HTRCurrentAO]} { append options "-HTRCurrentAO $HTRCurrentAO " }
    if {[llength $KIKVoltSetSendAO]} { append options "-KIKVoltSetSendAO $KIKVoltSetSendAO " }
    set id2 [APSMpParallel \
		 -procedure "RFGUN_Shutdown $options" \
		 -mode "Automatic"]
    
#    APSMpAbort all -onError 1
    if {[catch {APSMpJoin $id1} results]} {
	APSMpReturn error "RFGUN_ShutdownWithPS: $results"
    }
    if {[catch {APSMpJoin $id2} results]} {
	APSMpReturn error "RFGUN_ShutdownWithPS: $results"
    }
    
    APSMpReturn ok
}



proc RFGUN_ShutdownInfo {} {
    return "RFGun Shutdown Procedure\n\
1. Signal any active RFGun control script to shut down\n\
2. Set the RFGun cathode heater to 1 Amp (standby current)\n\
3. Close the RFGun gate valve\n\
4. Turn off the kicker voltage"
}

proc RFGUN_ShutdownDialog {frame} {
    APSSetVarAndUpdate status "Click OK to shut down the RFGun"
    pack [message $frame.msg -aspect 300 -justify left \
	      -text "Click OK to shut down the RFGun"]
    return
}

proc RFGUN_Shutdown {args} {
    global execMode
    if {$execMode == "Manual"} {
	set prefix "Press Continue to "
    } else {
	set prefix ""
    }
    set k1down 0
    set k2down 0
    set L1VVC1 1
    set closeGateValves 1
    set suspendFixedCurrent 0
    set changeMode 0
    APSMpStep init -promptDialog RFGUN_ShutdownDialog
    APSSetVarAndUpdate status "Working..."

    if {[catch {APSLinkToLINACPVs} result]} {
        APSMpReturn error "RFGUN_Shutdown: $result"
    }

    APSMpStep "${prefix}Detect selected Gun" -desc "Detect selected gun"
    if {[catch {APSRFGUN_DetectSelectedGun} gun]} {
	APSMpReturn error "RFGUN_Shutdown: $gun"
    }
    APSParseArguments {gun L1VVC1 closeGateValves suspendFixedCurrent changeMode}
    if {$gun == "RG2"} {
	set deviceList 2
	set HTRCurrentAO 3.1
	set KIKVoltSetSendAO 5
    } elseif {$gun == "RG1"} {
	set deviceList 1
	set HTRCurrentAO 4.1
	set KIKVoltSetSendAO 0
    } else {
	APSMpReturn error "RFGUN_Shutdown: Unable to detect which Gun is selected. Check the LINAC RF Switching System State to ensure it is set to RUNNING and not LOCAL SWITCH or REMOTE SWITCH."
    }

    APSParseArguments {HTRCurrentAO KIKVoltSetSendAO k1down k2down}

    if {[catch {APSDevSend \
		    -group LinacRFGun \
		    -operation ReadRFCurrentMode \
		    -deviceList 0} linacMode]} {
	APSMpReturn error "RFGUN_Shutdown: $linacMode"
    }
    if {[join $linacMode] == "K1 Down"} {
        set L1SectorSource 3
        set L2SectorSource 2
    } elseif {[join $linacMode] == "K2 Down"} {
        set L1SectorSource 1
        set L2SectorSource 3
    } else {
        set L1SectorSource 1
        set L2SectorSource 2
    }

    APSMpStep "${prefix}Suspend L1, L2 and L3 Power Control Stabilizer" -desc "Suspend L1, L2 and L3 power control stabilizers"
    if {[catch {APSLSuspendResumeRFPowerControllaws -klystronList "1 2 3" -mode suspend} result]} {
        if {[APSPEMTKDialog .warningDialog -text "Unable to suspend L1, L2, and L3 power controls\n$result"] == 1} {
            APSMpReturn error "RFGUN_Shutdown: $result"
        }
#	APSMpReturn error "RFGUN_Shutdown: $result"
    }
    if {$suspendFixedCurrent} {
        APSMpStep "${prefix}Suspend fixedCurrent" -desc "Suspend fixedCurrent"
        if {[catch {APSMpLSuspendResumeRunControl \
                      -value "Suspend" \
                      -name FixedCurrent \
                      -group "LinacRFGun" \
                      -deviceList 0} result]} {
            if {[APSPEMTKDialog .warningDialog -text "Unable to suspend the hold current script\n$result"] == 1} {
                APSMpReturn error "RFGUN_Shutdown: $result"
            }
            #	APSMpReturn error "RFGUN_Shutdown: $result"
        }
    }
    APSMpStep "${prefix}Suspend linac RF phase controllaw" -desc "Suspend linac RF phase controllaw"
    if {[catch {exec cavput -list=L:BPD:RFGUN1:L1L2L4L5RC.SUSP=1,L:BPD:RFGUN2:L1L2L4L5RC.SUSP=1} result]} {
        if {[APSPEMTKDialog .warningDialog -text "Problem suspending the linac RF phase controllaw\nRFGUN_Shutdown: $result"] == 1} {
            APSMpReturn error "Problem suspending the linac RF phase controllaw: RFGUN_Shutdown: $result"
        }
    }
    if {[catch {exec cavput -list=L:BPD:RFGUN1RC.ABRT=1,L:BPD:RFGUN2RC.ABRT=1,L:BPD:RFGUN2K1DnRC.ABRT=1,L:BPD:RFGUN2K2DnRC.ABRT=1,L:BPD:L3P3:L4AS1RC.ABRT=1,L:BPD:L4P1:L5AS1RC.ABRT=1} result]} {
        if {[APSPEMTKDialog .warningDialog -text "Problem suspending the linac RF phase controllaw\nRFGUN_Shutdown: $result"] == 1} {
            APSMpReturn error "Problem suspending the linac RF phase controllaw: RFGUN_Shutdown: $result"
        }
    }
	
    APSWaitWithUpdate -waitSeconds 5
    APSMpStep "${prefix}Initiate shutdown" -desc "Initiate shutdown"
    if {[catch {APSRFGUN_UpdateStatusDescription \
		    -value "Init shutdown"} result]} {
        if {[APSPEMTKDialog .warningDialog -text "Unable to update the status description\n$result"] == 1} {
            APSMpReturn error "RFGUN_Shutdown: $result"
        }
#	APSMpReturn error "RFGUN_Shutdown: $result"
    }
    APSWaitWithUpdate -waitSeconds 1

    APSMpStep "${prefix}Initiate script abort" -desc "Initiate script abort"
    if {[catch {APSRFGUN_AbortAllActiveScripts} result]} {
        if {[APSPEMTKDialog .warningDialog -text "Unable to abort all scripts\n$result"] == 1} {
            APSMpReturn error "RFGUN_Shutdown: $result"
        }
#	APSMpReturn error "RFGUN_Shutdown: $result"
    }

    if {0} {
    if {!$changeMode} {
        APSMpStep "${prefix}Set cathode heater to $HTRCurrentAO Amp" -desc "Set cathode heater to standby current"
        if {[catch {APSRFGUN_SetCathodeHeaterStandbyCurrent \
                      -value $HTRCurrentAO -deviceList $deviceList} result]} {
            if {[APSPEMTKDialog .warningDialog -text "Unable to set cathode heater to 1 Amp\n$result"] == 1} {
                APSMpReturn error "RFGUN_Shutdown: $result"
            }
            #	APSMpReturn error "RFGUN_Shutdown: $result"
        }
    }
    }

    APSWaitWithUpdate -waitSeconds 5

    APSMpStep "${prefix}Turn the kicker charge pulse off" -desc "Turn the kicker charge pulse off"
    if {[catch {exec cavput -list=L1:RG1:KIK:chargeTrigC=0,L1:RG2:KIK:chargeTrigC=0 -pend=20} result]} {
        if {[APSPEMTKDialog .warningDialog -text "Unable to turn the kicker charge pulse off\n$result"] == 1} {
            APSMpReturn error "RFGUN_Shutdown: $result"
        }
#	APSMpReturn error "RFGUN_Shutdown: $result"
    }
    if {$closeGateValves} {
        APSMpStep "${prefix}Close gate valves" -desc "Close the gate valves"
        if {[catch {
            if {$L1VVC1} {
                APSRFGUN_OpenCloseGateValve -deviceList "L1GV1 L1GV2 L1PG1GV2" -value Close -group LinacValves
            } else {
                APSRFGUN_OpenCloseGateValve -deviceList "L1GV2" -value Close -group LinacValves
            }
            APSRFGUN_OpenCloseGateValve -deviceList "1 2" -value Close -group LinacRFGun
        } result]} {
            if {[APSPEMTKDialog .warningDialog -text "Unable to close the gate valves\n$result"] == 1} {
                APSMpReturn error "RFGUN_Shutdown: $result"
            }
            #	APSMpReturn error "RFGUN_Shutdown: $result"
        }
    }
    if {(($k1down) && ($L1SectorSource == 1))} {
        #We want to go to K1 down but we are still in K1 up mode so don't touch L1
    } else {
       APSMpStep "${prefix}Ramp down the L$L1SectorSource LLRF" -desc "Ramp down L$L1SectorSource LLRF"
       if {[catch {APSRFGUN_RampDownLLRF -deviceList $L1SectorSource} result]} {
           if {[APSPEMTKDialog .warningDialog -text "Unable to ramp down L$L1SectorSource LLRF\n$result"] == 1} {
               APSMpReturn error "RFGUN_Shutdown: $result"
           }
#	   APSMpReturn error "RFGUN_Shutdown: $result"
       }
       APSMpStep "${prefix}Select LLRF Off" -desc "Turn L$L1SectorSource LLRF off"
       if {[catch {APSLINAC_LLRFOnOff -button "Off" -deviceList $L1SectorSource} result]} {
           if {[APSPEMTKDialog .warningDialog -text "Unable to turn L$L1SectorSource LLRF off\n$result"] == 1} {
               APSMpReturn error "RFGUN_Shutdown: $result"
           }
#	   APSMpReturn error "RFGUN_Shutdown: $result"
       }
    }
    
    APSWaitWithUpdate -waitSeconds 2

    APSMpStep "Done with shutdown" -desc "Done with shutdown"
    if {[catch {
	APSRFGUN_UpdateStatusDescription \
	    -value "Shutdown done"
    } result]} {
        if {[APSPEMTKDialog .warningDialog -text "Unable to update the status description\n$result"] == 1} {
            APSMpReturn error "RFGUN_Shutdown: $result"
        }
#	APSMpReturn error "RFGUN_Shutdown: $result"
    }
    APSMpReturn ok
}

proc APSRFGUN_DetectSelectedGun {args} {
    if {[catch {APSDevSend \
		    -group LinacRFGun \
		    -operation ReadRFSwitch7 \
		    -deviceList 1} gun1]} {
	return -code error "APSRFGUN_DetectSelectedGun: $gun1"
    }
    if {[catch {APSDevSend \
		    -group LinacRFGun \
		    -operation ReadRFSwitch7 \
		    -deviceList 2} gun2]} {
	return -code error "APSRFGUN_DetectSelectedGun: $gun2"
    }
    if {[catch {APSDevSend \
		    -group LinacRFGun \
		    -operation ReadRFSwitchState \
		    -deviceList 0} state]} {
	return -code error "APSRFGUN_DetectSelectedGun: $state"
    }
    if {($gun1 == "Enabled") && ($state == "RUNNING")} {
	return -code ok RG1
    }
    if {($gun2 == "Enabled") && ($state == "RUNNING")} {
	return -code ok RG2
    }
    return -code ok "FAULT"


#    if {[catch {APSDevSend -group LinacRFGun -operation ReadRFSwitch2 -deviceList 0} gun]} {
#	return -code error "APSRFGUN_DetectSelectedGun: $gun"
#    }
    return -code ok $gun 
}

proc APSRFGUN_UpdateStatusDescription {args} {
    set value ""
    APSStrictParseArguments {value}
    if {[catch {APSDevSend \
		    -group LinacRFGun \
		    -operation SetActiveScriptDesc \
		    -deviceList 0 \
		    -value $value} result]} {
	return -code error "APSRFGUN_UpdateStatusDescription: $result"
    }
}

proc APSRFGUN_AbortAllActiveScripts {args} {
    if {[catch {
	APSRFGUN_UpdateStatusDescription \
	    -value "Script abort..."
	APSDevSend \
	    -group LinacRFGun \
	    -operation AbortAllActiveScripts \
	    -deviceList 0
    } result]} {
	return -code error "APSRFGUN_AbortAllActiveScripts: $result"
    }
    APSWaitWithUpdate -waitSeconds 5
}

proc APSRFGUN_SetCathodeHeaterStandbyCurrent {args} {
    set value ""
    set deviceList ""
    APSStrictParseArguments {value deviceList}
    if {[catch {
	APSRFGUN_UpdateStatusDescription \
	    -value "Cathode standby..."
	APSRFGUN_SetCathodeHeaterCurrent \
	    -value $value \
	    -deviceList $deviceList
    } result]} {
	return -code error "APSRFGUN_SetCathodeHeaterStandbyCurrent: $result"
    }
}

proc APSRFGUN_SetCathodeHeaterCurrent {args} {
    set value ""
    set deviceList ""
    APSStrictParseArguments {value deviceList}
    if {[catch {
	APSDevSend \
	    -group LinacRFGun \
	    -operation SetCathodeHeaterCurrent \
	    -deviceList $deviceList \
	    -value $value
    } result]} {
	return -code error "APSRFGUN_SetCathodeHeaterCurrent: $result"
    }
}


proc APSRFGUN_ShutdownAlphaMagnet {args} {
    set deviceList ""
    APSStrictParseArguments {deviceList}
    if {[catch {
	APSRFGUN_UpdateStatusDescription \
	    -value "Alpha shutdown..."
    } result]} {
	return -code error "APSRFGUN_ShutdownAlphaMagnet: $result"
    }
    if {[catch {
	APSDevSend \
	    -group LinacRFGun \
	    -operation ReadAlphaMagnetCurrent \
	    -deviceList $deviceList
    } alphaCurrent]} {
	return -code error "APSRFGUN_ShutdownAlphaMagnet: $alphaCurrent"
    }
    set steps 30
    set alphaIDelta [expr {$alphaCurrent / double($steps)}]
    if {[catch {
	while {$steps >= 0} {
	    APSSetVarAndUpdate status $steps
	    APSDevSend \
		-group LinacRFGun \
		-operation SetAlphaMagnetCurrent \
		-deviceList $deviceList \
		-value [set alphaCurrent [expr {$alphaCurrent - $alphaIDelta}]]
	    APSWaitWithUpdate -waitSeconds 1
	    incr steps -1
	}
	APSDevSend \
	    -group LinacRFGun \
	    -operation SetAlphaMagnetCurrent \
	    -deviceList $deviceList \
	    -value 0
	APSWaitWithUpdate -waitSeconds 5
	APSDevSend \
	    -group LinacRFGun \
	    -operation DisableAlphaMagnet \
	    -deviceList $deviceList
    } result]} {
	return -code error "APSRFGUN_ShutdownAlphaMagnet: $result"
    }
    APSWaitWithUpdate -waitSeconds 1
}

proc APSRFGUN_StartDeguassAlphaMagnet {args} {
    set deviceList ""
    APSStrictParseArguments {deviceList}
    if {[catch {
	APSRFGUN_UpdateStatusDescription \
	    -value "Start alpha degauss..."
	APSDevSend \
	    -group LinacRFGun \
	    -operation ResetAlphaTrimMagnet \
	    -deviceList $deviceList
	APSWaitWithUpdate -waitSeconds 5
	APSDevSend \
	    -group LinacRFGun \
	    -operation SetAlphaTrimDegaussMinutes \
	    -deviceList $deviceList \
	    -value 3 \
	    -timeout 0
	APSDevSend \
	    -group LinacRFGun \
	    -operation SetAlphaTrimDegaussSeconds \
	    -deviceList $deviceList \
	    -value 0 \
	    -timeout 0
	APSDevSend \
	    -group LinacRFGun \
	    -operation SetAlphaTrimDegaussCycles \
	    -deviceList $deviceList \
	    -value 4 \
	    -timeout 0
	APSDevSend \
	    -group LinacRFGun \
	    -operation SetAlphaTrimDegaussPeriod \
	    -deviceList $deviceList \
	    -value 60 \
	    -timeout 0
	APSDevSend \
	    -group LinacRFGun \
	    -operation SetAlphaTrimDegaussDecayTimes \
	    -deviceList $deviceList \
	    -value 4 \
	    -timeout 0
	APSWaitWithUpdate -waitSeconds 2
	APSDevSend \
	    -group LinacRFGun \
	    -operation StartAlphaTrimMagnetDegauss \
	    -deviceList $deviceList \
	    -timeout 0
    } result]} {
	return -code error "APSRFGUN_StartDeguassAlphaMagnet: $result"
    }
    APSWaitWithUpdate -waitSeconds 5
}

proc APSRFGUN_TurnKickerOnOff {args} {
    set deviceList ""
    set value ""
    set state ""
    APSStrictParseArguments {deviceList value state}
    if {$state == "off"} {
        if {[catch {
            APSRFGUN_UpdateStatusDescription \
              -value "Kicker off..."
            APSDevSend \
              -group LinacRFGun \
              -operation SetKickerVoltage \
              -deviceList $deviceList \
              -value $value
            APSWaitWithUpdate -waitSeconds 5
            APSDevSend \
              -group LinacRFGun \
              -operation TurnOffKicker \
              -deviceList $deviceList
        } result]} {
            return -code error "APSRFGUN_TurnKickerOnOff: $result"
        }
        APSWaitWithUpdate -waitSeconds 5
    } elseif {$state == "on"} {
        if {[catch {exec cavget -list=RG2:KIK:TComplete -num} result]} {
            return -code error "APSRFGUN_TurnKickerOnOff: $result" 
        }
        if {$result != 1} {
            #do not issue an error message if the timer is not complete.
            return
        }
        if {[catch {exec cavget -list=L1:RG1:KIK:chargeTrigC -num} result]} {
            return -code error "APSRFGUN_TurnKickerOnOff: $result" 
        }
        if {$result != 0} {
            if {[catch {exec cavput -list=L1:RG1:KIK:chargeTrigC=0} result]} {
                return -code error "APSRFGUN_TurnKickerOnOff: $result" 
            }    
        }
        if {[catch {exec cavget -list=L1:RG2:KIK:chargeTrigC -num} result]} {
            return -code error "APSRFGUN_TurnKickerOnOff: $result" 
        }
        if {$result != 0} {
            if {[catch {exec cavput -list=L1:RG2:KIK:chargeTrigC=0} result]} {
                return -code error "APSRFGUN_TurnKickerOnOff: $result" 
            }    
        }
        if {[catch {
            APSDevSend \
              -group LinacRFGun \
              -operation TurnOnKicker \
              -deviceList $deviceList
        } result]} {
            return -code error "APSRFGUN_TurnKickerOnOff: $result"
        }
        APSWaitWithUpdate -waitSeconds 8
        if {[catch {
            APSDevSend \
              -group LinacRFGun \
              -operation QueryKickerState \
              -deviceList $deviceList
        } result]} {
            return -code error "APSRFGUN_TurnKickerOnOff: $result"
        }
        if {$result == 1} {
            bell
            if {[APSPEMTKDialog .warningDialog -text "Kicker interlock fault detected."] == 1} {
                return -code error "APSRFGUN_TurnKickerOnOff: Kicker interlock fault detected."
            }
        }
    }
}

proc APSRFGUN_OpenCloseGateValve {args} {
    set deviceList ""
    set value ""
    set group ""
    APSStrictParseArguments {deviceList value group}
    if {($value != "Open") && ($value != "Close")} {
	return -code error "APSRFGUN_OpenCloseGateValve: invalid argument passed"
    }
    if {[catch {
	APSDevSend \
	    -group $group \
	    -operation ${value}GateValve \
	    -deviceList $deviceList
    } result]} {
	return -code error "APSRFGUN_OpenCloseGateValve: $result"
    }

    if {$value == "Close"} {
        set value "Closed"
    }
    set stepLimit 30
    set step 1
    while {$step <= $stepLimit} {
        set pass 1
        foreach device $deviceList {
            if {[catch {APSDevSend \
                          -group $group \
                          -operation QueryGateValve${value} \
                          -deviceList $device} result]} {
                return -code error "APSRFGUN_OpenCloseGateValve: $result"
            }
            if {!$result} {
                set pass 0
                if {$step == $stepLimit} {
                    return -code error "APSRFGUN_OpenCloseGateValve: $device gate valve is not $value"
                }
            }
        }
        if {$pass} {
            break
        }
        incr step
        APSWaitWithUpdate -waitSeconds 1
    }
}

proc APSRFGUN_RampDownLLRF {args} {
    set deviceList ""
    set value 3.34
    APSStrictParseArguments {deviceList value}
    switch -exact -- $deviceList {
	1 {set value 4.0}
	2 {set value 3.1}
	3 {set value 2.8} 
	4 {set value 3.1} 
	5 {set value 2.8} 
	default {return -code error "APSRFGUN_RampDownLLRF: invalid deviceList $deviceList"}
    }
    
    if {[catch {
	APSRFGUN_UpdateStatusDescription \
	    -value "Ramping down L$deviceList LLRF...."
	APSDevSend \
	    -group LinacKlystron \
	    -operation StartIncreasingRFAttenuation \
	    -deviceList $deviceList \
	    -timeout 0
    } result]} {
	return -code error "APSRFGUN_RampDownLLRF: $result"
    }

    set klyPosition L${deviceList}:MA:klyPosAI
    if {![llength [info commands blt::bgexec]]} {
	package require BLT
	global blt_library
	lappend auto_path $blt_library
    }
    if {[catch {eval blt::bgexec apsRFGUNAbortVariable cawait -interval=0.1 -waitFor=$klyPosition,above=$value -timeLimit=120} result]} {
	if {[catch {
	    APSDevSend \
		-group LinacKlystron \
		-operation StopIncreasingRFAttenuation \
		-deviceList $deviceList \
		-timeout 0
	}]} {
	    catch {exec caput L${deviceList}:MA:incKlyBO 0}
	}
	return -code error "APSRFGUN_RampDownLLRF: Timed out waiting for LLRF to ramp down the L$deviceList LLRF: $result"
    }

    if {[catch {
	APSDevSend \
	    -group LinacKlystron \
	    -operation StopIncreasingRFAttenuation \
	    -deviceList $deviceList \
	    -timeout 0
    } result]} {
	return -code error "APSRFGUN_RampDownLLRF: $result"
    }
}

proc APSRFGUN_WaitForDegaussToComplete {args} {
    set deviceList ""
    APSStrictParseArguments {deviceList}
    if {[catch {
	APSRFGUN_UpdateStatusDescription \
	    -value "Degauss in progress..."
    } result]} {
	return -code error "APSRFGUN_WaitForDegaussToComplete: $result"
    }
    set AlphaDegauss L${deviceList}:RG1:LFA:TRM:StdSU.PROC
    if {![llength [info commands blt::bgexec]]} {
	package require BLT
	global blt_library
	lappend auto_path $blt_library
    }
    if {[catch {blt::bgexec apsRFGUNAbortVariable cawait -waitfor=$AlphaDegauss,equalto=0 -timeLimit=1500} results]} {
	return -code error "APSRFGUN_WaitForDegaussToComplete: Unable to use cawait to check the status of the degaussing process: $results"
    }
}

proc APSRFGUN_TurnOffTrimSupply {args} {
    set deviceList ""
    APSStrictParseArguments {deviceList}
    if {[catch {
	APSRFGUN_UpdateStatusDescription \
	    -value "Alpha trim off..."
	APSDevSend \
	    -group LinacRFGun \
	    -operation DisableAlphaTrimMagnet \
	    -deviceList $deviceList
    } result]} {
	return -code error "APSRFGUN_TurnOffTrimSupply: $result"
    }
    APSWaitWithUpdate -waitSeconds 1
}

