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

# $Log: not supported by cvs2svn $
# Revision 1.6  2003/03/26 06:06:15  emery
# Added pulses rgument to the run command.
#
# Revision 1.5  2003/02/12 12:02:43  emery
# Changed tests limit to 20.
#
# Revision 1.4  2002/10/15 07:43:31  emery
# Corrected a missing continuation character.
#
# Revision 1.3  2002/10/15 07:42:05  emery
# Added ezca timing and knob file in sddsoptimize command.
#
# Revision 1.2  2002/03/26 17:14:32  emery
# Changed argument of togglePulseMagnet from PARto.. to Gunto..
#
# Revision 1.1  2002/01/23 14:22:41  emery
# First isntallation.
#

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.7 $ \$Author: emery $"

APSApplication . -name "SROptimizeInjection" -version $CVSRevisionAuthor \
  -overview "SROptimizeInjection runs an optimizer on the BTS corrector(s) and SR septum."

proc MakeActionWidget {widget args} {
    set parent ""
    APSParseArguments {parent}
    
    APSFrame $widget -parent $parent -label "" \
      -contextHelp "Action buttons"
    set w $parent$widget.frame

    APSFrame .setup -parent $parent$widget.frame -label "" \
      -contextHelp "Setup quantities."
    set w $parent$widget.frame.setup.frame

    APSLabeledEntry .logDir -parent $w -width 60 \
      -textVariable logDir \
      -label "Log directory:" \
      -contextHelp "Directory for log file of minimization."

   APSButton .daily -parent $w.logDir -packOption "-anchor e" \
      -text "daily" -size small \
      -command {set logDir [APSGoToDailyDirectory -subDirectory .]}

    APSLabeledEntry .ik1 -parent $w \
      -label "IK1 setpoint:" -textVariable IK1 \
      -contextHelp "Enter a setpoint for IK1, which will kick out the stored beam to prevent accumulation."

    APSLabeledEntry .pulses -parent $w \
      -label "Injection pulses:" -textVariable pulses \
      -contextHelp "Number of injection pulses for which to calculate an average the efficiency."

    APSRadioButtonFrame .plane -parent $w -label "Plane: " -valueList {X Y} \
      -buttonList {x y} -variable plane -orientation horizontal \
      -commandList {{} {}} \
      -contextHelp "If X, BTS:CH3 and septums are used, including a knob file. If Y, then use last two BTS:V correctors."

    APSFrame .optimize -parent $parent$widget.frame -label "" \
      -contextHelp "Action buttons for optimzation"
    set w $parent$widget.frame.optimize.frame

    APSButton .setup  -parent $w -text "Setup pulsing" \
      -command {Setup -IK1 $IK1} \
      -contextHelp "Sets up injection."

    APSButton .minimizeX  -parent $w -text "Optimize X plane" \
      -command {runOptimize -logDir $logDir -pulses $pulses -plane x} \
      -contextHelp "Starts sddsoptimize for maximizing the injection in x-plane."

   APSButton .minimizeY  -parent $w -text "Optimize Y plane" \
      -command {runOptimize -logDir $logDir -pulses $pulses -plane y} \
      -contextHelp "Starts sddsoptimize for maximizing the injection in y-plane."

    APSButton .plotProg  -parent $w -text "Plot Progress" \
      -command {plotProgress -logDir $logDir -plane $plane} \
      -contextHelp "Plots the knob values and emittance."

}

proc plotProgress {args} {
    set logDir .
    APSParseArguments {logDir plane}
    set scriptDir /home/helios/oagData/sr/optimizeScripts/injection
    set quantities [exec sdds2stream $scriptDir/var-$plane -col=ControlName]
    exec sddsplot $logDir/injection-$plane.optLog \
      -grap=line,vary -leg \
      -col=EvalIndex,([join $quantities ,]) -sep \
      -col=EvalIndex,currentValue -grap=line,type=1\
      -yscale=id=eval -uns=y -omni\
      &
}

proc SetStatus {text} {
    global status
    set status $text
}

proc DumpBeamAndResetRF {} {
    if {![APSMultipleChoice [APSUniqueName .] -question "Dump beam before setting IK1?" \
            -labelList {Yes No} -returnList {1 0}]} {
        return
    }
    update
    exec cavput -list=S:MPS:dumpBeamSQ=1 -pend=10
    SetStatus "Beam dumped."
    update
    exec resetMPS
    after 2000
    if [catch {exec cavget -list=S-DCCT:CurrentM \
                 -pend=10 \
             } S35BeamCurrent] {
        return -code error "DumpBeamAndResetRF: $S35BeamCurrent"
    }
    if {$S35BeamCurrent > 0.30} {
        SetStatus "Skipping reseting of RF AGC. Still got stored beam."
        return 0
    }     
    if [catch {exec cavput -list=SRF:AGC:FB_SoftEngage -list=1,2 -list=BO=1 \
                 -pend=10 \
             } result] {
        return -code error "DumpBeamAndResetRF: Problem setting AGC on RF systems: $result"
    }
    SetStatus "RF AGC reset."
    
}

proc Setup {args} {
    set IK1 12.0
    APSParseArguments {IK1}

# dump beam first
    if [catch {exec cavget -list=S-DCCT:CurrentM \
                 -pend=10 \
             } S35BeamCurrent] {
        return -code error "DumpBeamAndResetRF: $S35BeamCurrent"
    }
    # A small beam current may be present from a single shot injection.
    # no need to dump with MPS.
    set beamCurrentLimit 0.30
    if {$S35BeamCurrent > $beamCurrentLimit} {
        DumpBeamAndResetRF
    }
    if [catch {exec cavput -list=BTS:ControlLaw -list=X,Y -list=RC.ABRT=1 \
                 -pen=5 \
             } result ] {
        return -code error "Setup: $result"
    }
    SetStatus "BTS orbit controllaw aborted."

    if [catch {exec cavput -list=S:IK1:VoltageSetSendAO=$IK1 \
                 -pen=5 \
             } result ] {
        return -code error "Setup: $result"
    }

    # toggle injection magnets
    if [catch {TogglePulsedMagnetEnables -location GuntoBoosterExt \
             } result] {
        return -code error "Setup: $result"
    }

    #fire SR septum and kickers
    if [catch {exec cavput -pend=5 -list=Mt:Ddg \
                 -list=3chan4,3chan0,3chan1 \
                 -list=.GATE=Enabled \
             } result]  {
        return -code error "Setup: $result"
    }
    if [catch {APSMpStopSIS1Feedforward} result]  {
        return -code error "Setup: $result"
    }
    after 1000
    if [catch {APSMpStartSIS1Feedforward >& /dev/null} result]  {
        return -code error "Setup: $result"
    }
    SetStatus "Setup done."
}

proc runOptimize {args} {
    set logDir .
    set pulses 5
    APSParseArguments {logDir pulses plane}
    set scriptDir /home/helios/oagData/sr/optimizeScripts/injection

    # only the variables change
    APSExecLog .optimizeUsingXplane \
      -lineLimit 2048 -width 90 \
      -name "SR injection Optimizer" \
      -unixCommand "sddsoptimize \"-measScript=/home/helios/SR/bin/readEffic -pulses $pulses\" \
            -varFile=$scriptDir/var-$plane -maximize -tolerance=0.01 \
            -knobFile=$scriptDir/BTS:CH2.cokn \
            -simplex=restarts=1,cycles=2,evaluations=50,no1dscan \
            -testValues=file=$scriptDir/tests,limit=20 \
            -verbose \
            -logFile=$logDir/injection-$plane.optLog"
    
    return
}

set IK1 12.0
set pulses 10
set status "Working."
APSScrolledStatus .status -parent .userFrame -textVariable status -width 90
MakeActionWidget .action -parent .userFrame
set status "Ready."
