#!/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)]
APSDebugPath

set CVSRevisionAuthor "\$Revision: 1.00 $ \$Author: borland $"

APSApplication . -name SRIDLossToRfVoltageFF -version $CVSRevisionAuthor \
  -overview {Runs the feedforward process that adjusts the rf voltage to compensate for changes in energy loss due to variation of ID gaps.}

APSFrameGrid .fg -parent .userFrame -yList {y1 y2 y3}

set ffFractionS40 [expr 1./3.]

set mainStatus ""
proc SetMainStatus {text} {
    global mainStatus
    set mainStatus "[clock format [clock seconds]]: $text"
    update
}

APSScrolledStatus .status -parent .userFrame.fg.y1 -textVariable mainStatus -width 90
SetMainStatus "This application assumes that S36, S37, and S40 cavities are in use with equal voltages."
SetMainStatus "It also assumes that the rf voltage controllaw processes are running."

set dataDir /home/helios/oagData/sr/rfVoltageIDEnergyLossFF/
set lastFFFile ""
set description RfVoltageIDLossFF
proc FindClosestFFFile {} {
    global targetBHH ffFile dataDir lastFFFile syncFreqMode targetSyncFreq ffFractionS40 description
    if !$syncFreqMode {
        set roundedBHH [format %.1f [expr int($targetBHH*10+0.5)/10.0]]
        set desiredFFFile [file join $dataDir BHH${roundedBHH}.sdds]
        set description [format "ID2RF-BHH${roundedBHH}-S40@%.2f" $ffFractionS40]
        if ![file exists $desiredFFFile] {
            SetMainStatus "Error: no appropriate file found for BHH=$roundedBHH"
            set ffFile ""
        } else {
            set ffFile $desiredFFFile
        }
        if [string compare $lastFFFile $ffFile] {
            SetMainStatus "Updating FF file selection"
        }
        set lastFFFile $ffFile
    } else {
        set roundedFS [format %.0f $targetSyncFreq]
        set desiredFFFile [file join $dataDir Fs${roundedFS}Hz.sdds]
        if ![file exists $desiredFFFile] {
            SetMainStatus "Error: no appropriate file found for FS=$roundedFS: $desiredFFFile"
            set ffFile ""
        } else {
            set ffFile $desiredFFFile
        }
        if [string compare $lastFFFile $ffFile] {
            SetMainStatus "Updating FF file selection"
        }
        set lastFFFile $ffFile
        set description [format "ID2RF-Fs${roundedFS}-S40@%.2f" $ffFractionS40]
    }
    if [expr abs($ffFractionS40-1./3.)>1e-6] {
        set tmpRoot /tmp/[APSTmpString]
        exec sddsmakedataset -pipe=out -column=Factor,type=float \
          -data=[expr (1-$ffFractionS40)/(2./3.)],[expr (1-$ffFractionS40)/(2./3.)],[expr $ffFractionS40/(1./3.)] \
          | sddsexpand -pipe=in $tmpRoot.factors 
        exec sddsxref $ffFile -pipe=out $tmpRoot.factors -leave=* -transfer=parameter,Factor \
          | sddsprocess -pipe=in $tmpRoot.rfff \
          "-redefine=col,ActuatorValue,ActuatorValue Factor *"
        set ffFile $tmpRoot.rfff
    } 
}

set w .userFrame.fg.y2

proc SetMode {parent} {
    global syncFreqMode
    if $syncFreqMode {
        APSDisableWidget $parent.bhhTarget
        APSEnableWidget $parent.fsTarget
    } else {
        APSEnableWidget $parent.bhhTarget
        APSDisableWidget $parent.fsTarget
    }
    FindClosestFFFile
}


set syncFreqMode 1
APSRadioButtonFrame .rb1 -parent $w -orientation horizontal -label "Mode: " \
                    -variable syncFreqMode \
                    -buttonList {"Constant Synchrotron Frequency" "Constant Bucket Half Height"} \
                    -valueList "1 0" \
  -commandList {"SetMode $w" "SetMode $w"}
                        
set targetSyncFreq 570
set targetBHH 2.8
APSLabeledEntry .bhhTarget -parent $w -textVariable targetBHH -label "Target Bucket Half-Height (%): " \
                -type real -contextHelp "Enter the desired bucket half-height in percent."
bind $w.bhhTarget.entry <Return> FindClosestFFFile
bind $w.bhhTarget.entry <Leave> FindClosestFFFile

APSLabeledEntry .fsTarget -parent $w -textVariable targetSyncFreq -label "Target Synchrotron Frequency (Hz): " \
                -type real -contextHelp "Enter the desired synchrotron frequency in Hertz."
bind $w.fsTarget.entry <Return> FindClosestFFFile
bind $w.fsTarget.entry <Leave> FindClosestFFFile

SetMode $w

APSLabeledOutput .ffFile -parent $w -textVariable ffFile -label "FF file: " -width 80
FindClosestFFFile

APSLabeledEntry .ff40 -parent $w -textVariable ffFractionS40 -label "Fraction of voltage from S40: " \
                -type real -contextHelp "Enter the fraction of the rf voltage to be provided by S40 cavities." \

set ffInterval 1.0
APSLabeledEntry .ffInterval -parent $w -textVariable ffInterval -label "Interval (s): " \
  -type real -contextHelp "Enter the interval between feedforward steps"

set RCPV OAG191RC
proc RunFF {} {
    global targetBHH ffFile dataDir ffInterval RCPV targetSyncFreq description
    FindClosestFFFile
    APSExecLog .exec -parent .userFrame.fg.y3 -width 100 -packOption "-side bottom" \
               -unixCommand "sddsfeedforward -interval=$ffInterval -infiniteLoop -verbose $ffFile -runControlPV=string=$RCPV,pingTimeout=10 \"-runControlDesc=$description\""
}

proc AbortFF {} {
    global RCPV
    if [catch {exec cavget -list=$RCPV.RUN } running] {
	return -code error "Error reading runControlPV: $result"
    }
    if !$running {
	SetMainStatus "Feedfoward is not running."
	return
    }
    SetMainStatus "Aborting feedforward."
    if [catch {exec cavput -list=$RCPV.ABRT=1 } result] {
	return -code error "Error aborting feedforward: $result"
    }
    exec cawait -waitFor=$RCPV.RUN,equalTo=0
    exec cavput -list=$RCPV.CLR=1
    SetMainStatus "Feedfoward aborted."

}

proc InfoFF {args} {
    global RCPV
    SetMainStatus "Launching info display."
    FindClosestFFFile
    exec medm -local -x -macro RCPV=$RCPV /usr/local/iocapps/adlsys/sr/psApp/APSRunControlSingle.adl  &
}

APSButton .run -parent $w -text "Run" -command RunFF
APSButton .abort -parent $w -text "Abort" -command AbortFF
APSButton .info -parent $w -text "Info" -command InfoFF



