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

# $Log: not supported by cvs2svn $
# Revision 1.12  2009/10/14 05:20:27  lemery
# Changed default interval to 1.5 (until S24A:H3 is fixed).
#
# Revision 1.11  2006/08/08 23:49:50  emery
# Changed the APPLY/START button to just a START button. (Shang.)
#
# Revision 1.10  2006/05/28 18:58:57  emery
# medm screens for correctors pop up for any sector selected.
#
# Revision 1.9  2005/11/29 15:55:29  shang
# fixed a spelling error
#
# Revision 1.8  2005/10/24 20:48:14  shang
# added TEST button to sector dialogs.
#
# Revision 1.7  2005/10/03 13:08:07  shang
# made the sign of accumulator agree with delta, made new array elements for
# up and down streams, moved displaying the S23C:H[V]1 corrector so that they
# are displayed only when the 23US/DS button is clicked.
#
# Revision 1.6  2005/10/02 16:43:26  shang
# added displaying S23C:H1, S23C:V1 and datapool steering control pv, and
# changed the sign for vertical up and down button.
#
# Revision 1.5  2005/10/02 14:36:53  shang
# changed the controllaw labels and the default value of steps
#
# Revision 1.4  2005/10/02 14:13:04  shang
# added checking if special controllaw is running to start PSCU slow controllaw
#
# Revision 1.3  2005/09/30 21:42:58  shang
# Added automatically updating controllaws when sector button is clicked.
# changed the runControlPV to APS:RunControlSlot0RC
#  for workstation controllaw, since the datapool
# control pv does not work. will change to the specific control pv that
# will be created by Frank.
#
# Revision 1.2  2005/05/31 14:16:06  shang
# modified to use the third controllaw for special controllaw and run PSCU controllaw
# only if the CU correctors are that not avaible for fast DC orbit correction.
#
# Revision 1.1  2005/03/22 06:13:12  shang
# first version
#
#

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)]
#set auto_path [linsert $auto_path 0  /home/oxygen/SHANG/oag/apps/src/mplib/sr]
APSDebugPath

set args $argv
set allowAllSectors 0
set ignoreLock 0
APSStrictParseArguments {allowAllSectors ignoreLock}


#if [regexp {.0} $env(DISPLAY)] {
#    set otherDisplay :0.1
#} else {
    set otherDisplay :0.0
#}

APSApplication . -name SRCUSteering.new \
  -overview "SRCUSteering provides convenience controls for ID steering."

set tcl_precision 6



set CUSteeringStatus Ready.
APSScrolledStatus .status -parent .userFrame -width 60\
  -textVariable CUSteeringStatus 

proc SetCUSteeringStatus {text} {
    global CUSteeringStatus
    set CUSteeringStatus $text
    update
}

proc SetCUSteeringStatusBell {text} {
    global CUSteeringStatus
    set CUSteeringStatus $text
    update
    bell
}

proc MakeSectorsWidget {widget args} {
    global sector stream CUSectorList OKCUSectorList otherDisplay

    set parent ""
    APSParseArguments {parent}

    set w $parent$widget
    APSFrame $widget -parent $parent \
      -label "Storage Ring canted undulator selection for steering." \
      -contextHelp {ID selection frame} 

    foreach stream {US DS} quad {1 2} {
        APSFrame .sector$quad -parent $w.frame 
        $w.frame.sector$quad.frame configure -relief flat
        foreach sector $CUSectorList {
            set cbLabel $sector$stream
            APSButton .sector$sector$stream \
              -parent $w.frame.sector$quad.frame \
              -text "$cbLabel" \
              -command "CUSteeringDialog -sector $sector -stream $stream" \
              -contextHelp "Brings up dialog box for CU $sector $stream end steering."
            if [lsearch $OKCUSectorList $sector]<0 {
                APSDisableButton $w.frame.sector$quad.frame.sector$sector$stream.button
            }
        }
    }
    APSFrame .adt -parent $parent
    APSButton .adt -parent $parent.adt.frame  -text "SR BPM AdjustedCC ADT (difference mode)" -command "exec adt -f /home/helios/OAG/oagData/ADTFiles/srBpm/sr.bpm.adjusted.pv -z 3 -d &"
}

# same found in other new steering GUIs and SRAutoSteering
proc PrepareFFFiles {args} {
    global FFWaveformFile
    set tmpRoot [APSGoToDailyDirectory -subdirectory IDsteering]/[APSTmpString]
    set waveformDir /home/helios/oagData/sr/orbitControllaw/waveforms
    foreach plane {h v} coord {x y} {
        if [catch {exec sddsprocess $waveformDir/RTFB[string toupper $coord]bpmInfo.sdds \
            -edit=col,ControlName,DeviceName,ei/:${coord}:SelectedMI/ -pipe=out \
            | sddscasr -save -pipe \
            | sddsconvert -pipe=in $tmpRoot.$plane -rename=col,ValueString=BPMName } result] {
            return -code error $result
        }
        set FFWaveformFile($plane) $tmpRoot.$plane
        APSAddToTmpFileList -ID steering -fileList $tmpRoot.$plane
    }
    
}

set stepSizeLimit 1
proc CUSteeringDialog {args} {
    global P0Sector CUSectorList otherDisplay

    set sector ""
    set stream ""
    APSParseArguments {sector stream}
    SetCUSteeringStatus "$sector $stream was selected."
    exec medm -attach -x /usr/local/iocapps/adlsys/sr/psApp/S${sector}CH1.adl &
    exec medm -attach -x /usr/local/iocapps/adlsys/sr/psApp/S${sector}CV1.adl &
    if ![string length $sector] {
        APSAlertBox [APSUniqueName .] -errorMessage \
          "No sector variable specified in CUSteeringDialog"
        return 1
    }
    if [catch {APSCheckAndUpdateLocalSteeringConfigs -steeringType CU -stream $stream -sector $sector -statusCallback SetCUSteeringStatus} result] {
        SetCUSteeringStatus "$result"
        APSAlertBox [APSUniqueName .] -errorMessage \
          "Error in updating CU steering configs for sector $sector"
        return 1
    }
    global waveformFile
    # set waveformFile($sector) p0BpmInfo.sdds
    if {-1<[lsearch $CUSectorList $sector]} {
        SetCUSteeringStatus "Check and remove sector $sector xbpms if they are in orbit correction..."
        # Here source is expected to be only the BM and ID, no CU side specified.
        if [catch {APSSRRemoveXrayBPMFromOrbitCorrection -sector $sector  -restart 1 -source ID -side $stream } result] {
            SetStatus "Error in removing sector $sector xray bpms from orbit correction: $result"
            return
        }
        SetCUSteeringStatus "$result"
    }
    
    global USx USy C0x C0y DSx DSy
    global BPx BPy APx APy
    global statusCallback adjustOnly allowTransfer errorCode

    set dialogFrame .dialogID$sector$stream.userFrame
    APSDialogBox .dialogID$sector$stream  \
      -name "CU$sector $stream side Dialog" \
      -contextHelp "Dialog box for steering in CU$sector $stream end."

    set Sn $sector
    set Sn1 [exec rpnl "$Sn 1 + 40 > pop ? 40 - : \$"]
    switch $stream {
        US {
            set variableList [list USx($sector) USy($sector)]
            set pvList [list S${Sn}B:P0:ms:x:SetpointAO S${Sn}B:P0:ms:y:SetpointAO]
            set widgetList {.usx .usy}
            set offsetVarList [list USxOffset($sector) USyOffset($sector)]
            set offsetPVList [list S${Sn}B:P0:ms:x:OffsetAO S${Sn}B:P0:ms:y:OffsetAO]
            set adjustVarList [list USxAdjusted($sector) USyAdjusted($sector)]
            set adjustPVList [list S${Sn}B:P0:mswAve:x:AdjustedCC S${Sn}B:P0:mswAve:y:AdjustedCC]
            set errorVarList [list USxError($sector) USyError($sector)]
            set errorPVList [list S${Sn}B:P0:mswAve:x:ErrorCC S${Sn}B:P0:mswAve:y:ErrorCC]
            set enablePVList S${Sn}B:P0
        }
        DS {
            set variableList [list C0x($sector) C0y($sector) DSx($sector) DSy($sector)]
	    
            set pvList [list S${Sn}C:P0:ms:x:SetpointAO S${Sn}C:P0:ms:y:SetpointAO \
			    S${Sn1}A:P0:ms:x:SetpointAO S${Sn1}A:P0:ms:y:SetpointAO ]
	    
            set widgetList {.c0x .c0y .dsx .dsy}
            set offsetVarList [list C0xOffset($sector) C0yOffset($sector) \
                                 DSxOffset($sector) DSyOffset($sector)]
            set offsetPVList [list S${Sn}C:P0:ms:x:OffsetAO S${Sn}C:P0:ms:y:OffsetAO \
                                S${Sn1}A:P0:ms:x:OffsetAO S${Sn1}A:P0:ms:y:OffsetAO ]
            set adjustVarList [list C0xAdjusted($sector) C0yAdjusted($sector) \
                                 DSxAdjusted($sector) DSyAdjusted($sector)]
            set adjustPVList [list S${Sn}C:P0:mswAve:x:AdjustedCC S${Sn}C:P0:mswAve:y:AdjustedCC \
                                S${Sn1}A:P0:mswAve:x:AdjustedCC S${Sn1}A:P0:mswAve:y:AdjustedCC ]
            set errorVarList [list C0xError($sector) C0yError($sector) \
                                DSxError($sector) DSyError($sector)]
            set errorPVList [list S${Sn}C:P0:mswAve:x:ErrorCC S${Sn}C:P0:mswAve:y:ErrorCC \
                               S${Sn1}A:P0:mswAve:x:ErrorCC S${Sn1}A:P0:mswAve:y:ErrorCC]
            set enablePVList [list S${Sn}C:P0 S${Sn1}A:P0]
        }
    }
    if {[pv linkw $variableList $pvList]!=0} {
        APSAlertBox .alert -errorMessage "linkw error $errorCode"
        exit
    }
    foreach var $variableList {
        if {[pv umon $var] !=0} {
            APSAlertBox .alert -errorMessage "umon error $errorCode"
            exit
        }
    }
    APSFrame .parameters -parent $dialogFrame -packOption "-side left"
    $dialogFrame.parameters.frame configure -relief flat
    APSFrame .setpoints -parent $dialogFrame.parameters.frame -packOption "-side left" \
      -label "Setpoints for bpms"  -width 10 \
      -contextHelp "Enter setpoints for the six bpm readbacks of CU$sector"
    $dialogFrame.parameters.frame.setpoints.frame configure -relief flat
    foreach widget $widgetList pv $pvList var $variableList {
        APSLabeledEntry $widget -parent $dialogFrame.parameters.frame.setpoints.frame \
          -label "$pv (mm)"  -width 10 \
          -textVariable $var \
          -contextHelp "Enter value for S${Sn}B:P0:ms:x:SetpointAO to be applied. These values change when one of the associated coordinate delta button is pressed."
    }
    global stepSizeLimit
    APSLabeledEntry .limit -parent .dialogID$sector$stream -label "Corrector change limit (A):" -textVariable stepSizeLimit -width 50
    APSButton .adt -parent .dialogID$sector$stream.buttonRow -text "SR BPM AdjustedCC ADT (difference mode)" -command "exec adt -f /home/helios/OAG/oagData/ADTFiles/srBpm/sr.bpm.adjusted.pv -s $sector -z 3 -d &"
    
    APSButton .review -parent .dialogID$sector$stream.buttonRow -text "Review Pending Setpoint Changes"  -command "ApplySetpoints -sector $sector -stream $stream -review 1" \
      -contextHelp  "review above setpoint value changes to setpoint PVs of CU$sector $stream end bpms." 
    
    APSButton .apply -parent .dialogID$sector$stream.buttonRow -text "APPLY Steering Delta" \
      -command "ApplySetpoints -sector $sector -stream $stream -review 0" \
      -contextHelp  "Applies  delta setpoint values to setpoint PVs and waveforms of CU$sector $stream end bpms."
    
    if {[pv linkw $offsetVarList $offsetPVList] !=0 || \
          [pv linkw $adjustVarList $adjustPVList] !=0 || \
          [pv linkw $errorVarList $errorPVList] !=0} {
        APSAlertBox .alert -errorMessage "$errorCode"
        exit
    }
    foreach name {offset adjust error} {
        set varList [set ${name}VarList]
        foreach var $varList {
            if {[pv umon $var] !=0} {
                APSAlertBox .alert -errorMessage "umon error $errorCode"
                exit
            }
        }
    }
    APSFrame .moreParameters -parent $dialogFrame -packOption "-side left"
    $dialogFrame.moreParameters.frame configure -relief flat
    APSLabeledOutputFrame .offset -parent $dialogFrame.moreParameters.frame \
      -label Offsets -packOption "-side left" \
      -variableList "$offsetVarList"\
      -orientation vertical -width 10 \
      -contextHelp "Electrical offset of ID$sector$ bpms."
    $dialogFrame.moreParameters.frame.offset.frame configure -relief flat
    
    APSLabeledOutputFrame .adjusted -parent $dialogFrame.moreParameters.frame \
      -label "Adjusted" -packOption "-side left" \
      -variableList "$adjustVarList"\
      -orientation vertical -width 10 \
      -contextHelp "Adjusted readbacks of ID$sector bpms: raw readback - offsets."
    $dialogFrame.moreParameters.frame.adjusted.frame configure -relief flat
    
    APSLabeledOutputFrame .error -parent $dialogFrame.moreParameters.frame \
      -label "Error" -packOption "-side left" \
      -variableList "$errorVarList"\
      -orientation vertical -width 10 \
      -contextHelp "Error readbacks of ID$sector bpms: adjusted readback - setpoint."
    $dialogFrame.moreParameters.frame.error.frame configure -relief flat

    set len [llength $offsetVarList]
    set border 3
    foreach outputFrame {offset adjusted error} {
        for {set entry 1} {$entry<=$len} {incr entry} {
            $dialogFrame.moreParameters.frame.${outputFrame}.frame.entry${entry} \
              configure -borderwidth $border
        }
    }
    AdjustSetpoints -sector $sector -parent $dialogFrame -stream $stream
    APSEnableButton .dialogID$sector$stream.buttonRow.ok.button
    
    update
    
    if {$statusCallback!=""} {
        $statusCallback "Enabling averaging for $enablePVList."
    }
    if [catch {exec cavput -list=[join $enablePVList ,] \
                 -list=:msAve:AveEnbBO=Enable \
                 -pendIoTime=10 \
             } result ] {
        APSAlertBox .alert -errorMessage "$result\nSomething wrong with a cavput command. Averaging may not be enabled."
        return
    }
   
    if [catch {APSSaveMachine -machine SROrbitSetPt -description "Save before sector $sector $stream CU steering." } result] {
        return -code error "Error doing SR bpm setpoint save: $result"
    }
    if [catch {APSSaveMachine -machine SRCorSetpts -description "Save before sector $sector $stream CU steering." } result] {
        return -code error "Error doing SR corrector setpoint save: $result"
    }
}

proc AdjustSetpoints {args} {
    global  deltaxp  deltayp  
    global  deltaxpAcc deltaypAcc

    set sector ""
    set stream ""
    set parent ""
    APSParseArguments {sector parent stream}
    if ![string length $sector] {
        APSAlertBox [APSUniqueName .] -errorMessage \
          "No sector variable specified in AdjustSetpoints"
        return 1
    }
    global USx USy C0x C0y DSx DSy
    set adjustFrame $parent.adjust.frame
    APSFrame .adjust -parent $parent
    $adjustFrame configure -relief flat

    # accumulators for steering changes.
    set deltaxpAcc($sector.$stream) 0
    set deltaypAcc($sector.$stream) 0

    set Sn $sector
    set Sn1 [exec rpnl "$Sn 1 + 40 > pop ? 40 - : \$"]
    APSFrame .parameters -parent $adjustFrame -packOption "-side left"
  #  $adjustFrame.parameters.frame configure -relief flat
    APSFrame .deltas -parent $adjustFrame.parameters.frame -packOption "-side left" \
      -label "Coordinate deltas"  -width 10\
      -contextHelp "Enter deltas for the x', y' coordinates  in ID$sector"
    $adjustFrame.parameters.frame.deltas.frame configure -relief flat
    if ![info exists deltaxp($sector.$stream)] {
        set deltaxp($sector.$stream) 0
    }
    if ![info exists deltayp($sector.$stream)] {
        set deltayp($sector.$stream) 0
    }
    APSLabeledEntry .bpx \
      -parent $adjustFrame.parameters.frame.deltas.frame \
      -label "delta xp (urad)"  -width 10\
      -textVariable deltaxp($sector.$stream) \
      -contextHelp "Enter value for delta xp"
    APSLabeledEntry .apy \
      -parent $adjustFrame.parameters.frame.deltas.frame \
      -label "delta yp (urad)"  -width 10\
      -textVariable deltayp($sector.$stream) \
      -contextHelp "Enter value for delta yp"

   
    APSFrame .incrButtons -parent $adjustFrame.parameters.frame -packOption "-side left" \
      -label " "  -width 10\
      -contextHelp "Causes setpoints to increment by the corresponding coordinate"
    $adjustFrame.parameters.frame.incrButtons.frame configure -relief flat

    APSFrame .decrButtons -parent $adjustFrame.parameters.frame -packOption "-side left" \
      -label " "  -width 10\
      -contextHelp "Causes setpoints to decrement by the corresponding coordinate"
    $adjustFrame.parameters.frame.decrButtons.frame configure -relief flat
 
    global steeringxp steeringyp
    set steeringxp($sector.$stream) 0
    set steeringyp($sector.$stream) 0
    

     APSLabeledOutputFrame .steering \
      -parent $adjustFrame.parameters.frame \
      -label "Pending steering" -packOption "-side left" \
      -variableList "steeringxp($sector.$stream) steeringyp($sector.$stream)" \
      -orientation vertical -width 10 \
      -contextHelp "pending steerings deltas. Values return to zero after apply button is pressed."
    
    set border 3
    foreach entry {1 2} {
        $adjustFrame.parameters.frame.steering.frame.entry${entry} \
          configure -borderwidth $border
    }
   

    APSLabeledOutputFrame .accumulation \
      -parent $adjustFrame.parameters.frame \
      -label "Accumulators" -packOption "-side left" \
      -variableList "deltaxpAcc($sector.$stream) deltaypAcc($sector.$stream)" \
      -orientation vertical -width 10 \
      -contextHelp "Accumulated coordinate deltas. Values return to zero when dialog box is closed and reopened."
    $adjustFrame.parameters.frame.accumulation.frame configure -relief flat
    set border 3
    foreach entry {1 2} {
        $adjustFrame.parameters.frame.accumulation.frame.entry${entry} \
          configure -borderwidth $border
    }
    $adjustFrame.parameters.frame.decrButtons.frame configure -relief flat
    
    # switch $stream {
    #	US -
    #	us {
    #    set sign 1
    #}
    #DS -
    #d#s {
    #    set sign -1
    #}
    #}
    APSButton .incrxp -parent $adjustFrame.parameters.frame.incrButtons.frame  \
      -packOption "-side top" -text OUT -command "IncrXp -sector $Sn -stream $stream" \
      -contextHelp  "Changes x setpoints using delta xp." -fastClick 1
    
    APSButton .incryp -parent $adjustFrame.parameters.frame.incrButtons.frame  \
      -packOption "-side top" -text UP -command "IncrYp -sector $Sn -stream $stream" \
      -contextHelp  "Changes y setpoints using delta yp." -fastClick 1
    
    APSButton .decrxp -parent $adjustFrame.parameters.frame.decrButtons.frame  \
      -packOption "-side top" -text IN -command "IncrXp -sector $Sn -sign -1 -stream $stream" \
      -contextHelp  "Changes x setpoints using delta xp." -fastClick 1
    
    APSButton .decryp -parent $adjustFrame.parameters.frame.decrButtons.frame  \
      -packOption "-side top" -text DOWN -command "IncrYp -sector $Sn -sign -1 -stream $stream" \
      -contextHelp  "Changes y setpoints using delta yp." -fastClick 1
    set padding 2
    set width 4
    $adjustFrame.parameters.frame.incrButtons.frame.incrxp.button configure -width $width -pady $padding
    $adjustFrame.parameters.frame.incrButtons.frame.incryp.button configure -width $width -pady $padding
    $adjustFrame.parameters.frame.decrButtons.frame.decrxp.button configure -width $width -pady $padding
    $adjustFrame.parameters.frame.decrButtons.frame.decryp.button configure -width $width -pady $padding

    return 0
}


proc IncrXp {args} {
    global  deltaxp  deltayp R12 steeringxp steeringyp
    global  deltaxpAcc deltaypAcc
    set sector ""
    set sign 1
    set stream ""
    APSParseArguments {sector sign stream}
    if ![string length $sector] {
        APSAlertBox [APSUniqueName .] -errorMessage \
          "No sector variable specified in CUSteeringDialog"
        return 1
    }
    global USx USy C0x C0y DSx DSy
    set deltaxp($sector.$stream) [scan $deltaxp($sector.$stream) %ld]
    set deltaxpAcc($sector.$stream) [expr $deltaxpAcc($sector.$stream) + $sign * $deltaxp($sector.$stream)]
    set steeringxp($sector.$stream) [expr $steeringxp($sector.$stream)  + $sign * $deltaxp($sector.$stream)]
    return 0
    switch $stream {
        US {
            set USx($sector) [expr $USx($sector) - $sign * $R12(us) * $deltaxp($sector.$stream)]
        }
        DS {
            set DSx($sector) [expr $DSx($sector) + $sign * $R12(ds) * $deltaxp($sector.$stream)]
            set C0x($sector) [expr $C0x($sector) + $sign * $R12(dsc0) * $deltaxp($sector.$stream)]
        }
    }
    #  set deltaxpAcc($sector) [expr $deltaxpAcc($sector) + $sign * $deltaxp($sector)]
    #  set BPx($sector) [expr $BPx($sector) - $sign * $R12($sector) * $deltaxp($sector)]
    #  set APx($sector) [expr $APx($sector) + $sign * $R12($sector) * $deltaxp($sector)]
    return 0
}


proc IncrYp {args} {
    global  deltaxp deltayp R34 steeringyp
    global  deltaxpAcc deltaypAcc

    set sector ""
    set sign 1
    set stream ""
    APSParseArguments {sector sign stream}
    if ![string length $sector] {
        APSAlertBox [APSUniqueName .] -errorMessage \
          "No sector variable specified in CUSteeringDialog"
        return 1
    }
    
    global USx USy C0x C0y DSx DSy
    set deltayp($sector.$stream) [scan $deltayp($sector.$stream) %ld]
    set deltaypAcc($sector.$stream) [expr $deltaypAcc($sector.$stream) + $sign * $deltayp($sector.$stream)]
    set steeringyp($sector.$stream) [expr $steeringyp($sector.$stream) + $sign * $deltayp($sector.$stream)]
    return 0
   
    switch $stream {
        US {
            set USy($sector) [expr $USy($sector) - $sign * $R34(us) * $deltayp($sector.$stream)]
        }
        DS {
            set C0y($sector) [expr $C0y($sector) - $sign * $R34(dsc0) * $deltayp($sector.$stream)]
            set DSy($sector) [expr $DSy($sector) - $sign * $R34(ds) * $deltayp($sector.$stream)]
        }
    }
    # set deltaypAcc($sector) [expr $deltaypAcc($sector) + $sign * $deltayp($sector)]
    # set BPy($sector) [expr $BPy($sector) - $sign * $R34($sector) * $deltayp($sector)]
    # set APy($sector) [expr $APy($sector) + $sign * $R34($sector) * $deltayp($sector)]
    return 0
}

proc ApplySetpoints {args} {
    global timeLimit tolerance statusCallback steps steeringxp steeringyp R12 R34 
    global stepSizeLimit FFWaveformFile ignoreLock
    
    set sector ""
    set returnerror 0
    set stream ""
    set review 0
    APSParseArguments {sector returnerror stream review}
    if ![string length $sector] {
        APSAlertBox [APSUniqueName .] -errorMessage \
          "No sector variable specified in CUSteeringDialog"
        if {$returnerror} {
            return -code error "AppySetpoints: No sector variable specified in CUSteeringDialog"  
        } else {
            return 1
        }
    }
    global USx USy DSx DSy C0x C0y
    if {$steeringxp($sector.$stream)==0 && $steeringyp($sector.$stream)==0 } {
        SetCUSteeringStatus "All steering deltas are zero, no steering is needed."
        return
    }
    set Sn $sector
    set Sn1 [exec rpnl "$Sn 1 + 40 > pop ? 40 - : \$"]
    
    set otherBPM A:P0
    switch $stream {
        US {
            set pvList S${Sn}B:P0
        }
        DS {
            set pvList [list S${Sn1}A:P0 S${Sn}C:P0]
        }
    }
    set source CU${stream}P0
    if {!$review && !$ignoreLock} {
        SetCUSteeringStatus "Lock global steering..."
        if [catch {exec cavput -list=SRID:SteeringLockBI.VAL=1 -pend=30} result] {
            return -code error "Error in locking global steering: $result"
        }
    }
    set controllawDir /home/helios/oagData/sr/localSteering/lattices/default/${source}s/[format %02ld ${sector}]$source
    foreach plane {h v} coord {x y} {
        if [set steering${coord}p($sector.$stream)]==0 {
            continue
        }
        switch $stream {
            US {
                switch $plane {
                    h {
                        set deltaList [expr -1.0 * $R12(us) * $steeringxp($sector.$stream)/1000.0]
                    }
                    v {
                        set deltaList [expr -1.0 * $R34(us) * $steeringyp($sector.$stream)/1000.0]
                    }
                }
            }
            DS {
                switch $plane {
                    h {
                        set delta1 [expr $R12(ds) * $steeringxp($sector.$stream)/1000.0]
                        set delta2 [expr $R12(dsc0) * $steeringxp($sector.$stream)/1000.0]
                    }
                    v {
                        set delta1 [expr $R34(ds) * $steeringyp($sector.$stream)/1000.0]
                        set delta2 [expr $R34(dsc0) * $steeringyp($sector.$stream)/1000.0]
                    }
                }
                set deltaList [list $delta1 $delta2]
            }
        }
        if [catch {APSSRApplySteeringSetpoints -sector $sector -source $source -plane $plane \
                     -xp $steeringxp($sector.$stream) -yp $steeringyp($sector.$stream) \
                     -bpmList $pvList -deltaList $deltaList \
                     -refMatrix $controllawDir/${plane}.steering.rm \
                     -FFWaveform $FFWaveformFile($plane) \
                     -review $review -dryRun 0 -statusCallback SetCUSteeringStatus \
                     -stepSizeLimit $stepSizeLimit } result] {
            return -code error "ApplySetpoints: $result"
        }
    }
    if $review {
        return
    }
    if !$ignoreLock {
        SetCUSteeringStatus "Unlock global steering..."
        if [catch {exec cavput -list=SRID:SteeringLockBI.VAL=0 -pend=30} result] {
            return -code error "Error in unlocking global steering: $result"
        }
    }
    
    if [catch {APSSRSaveSteeringToOps -installUBOP 1 -statusCallback SetCUSteeringStatus \
                 -description "Steering save: ID${sector}${stream}  deltaXp: $steeringxp($sector.$stream); deltaYp: $steeringyp($sector.$stream)" \
             } result] {
        return -code error "Error in saving steering to UBOP: $result"
    }
    
    set steeringxp($sector.$stream) 0
    set steeringyp($sector.$stream) 0

    SetCUSteeringStatusBell "Steering done."
    return
}

proc GetCUSectorsAndCorrectorStatus {args} {
    global CUSectorList OkForFastDCOrbitCorrection
    set  CUdataDir /home/helios/oagData/sr/XAXSTF
    if [catch {exec sddsprocess $CUdataDir/sectors.sdds -pipe=out \
                 -filter=col,CUflag,1,1 \
                 | sdds2stream -pipe -col=Sector} CUSectorList] {
        return -code error "$CUSectorlist"
    }
    set index 0
    foreach sector $CUSectorList {
        if $index {
            append xmatchOpt ",DeviceName=S${sector}C:H1,|"
            append ymatchOpt ",DeviceName=S${sector}C:V1,|"
        } else {
            set xmatchOpt "-match=col,DeviceName=S${sector}C:H1"
            set ymatchOpt "-match=col,DeviceName=S${sector}C:V1"
        }
        incr index
    }
    set tmpfile /tmp/[APSTmpString]
    set hFile /home/helios/oagData/sr/HCorrectorStatus/config.sdds
    set vFile /home/helios/oagData/sr/VCorrectorStatus/config.sdds
    if [catch {exec sddsprocess $hFile -pipe=out "$xmatchOpt" \
                 -scan=col,sector,DeviceName,S%ld,type=long \
                 | sddssort -pipe -col=DeviceName \
                 | tee $tmpfile \
                 | sdds2stream -pipe -col=OkForFastDCOrbitCorrection } xOk] {
        return -code error $xOk
    }
    if [catch {exec sddsprocess $vFile -pipe=out "$ymatchOpt" \
                 | sddssort -pipe -col=DeviceName \
                 | sdds2stream -pipe -col=OkForFastDCOrbitCorrection } yOk] {
        return -code error $yOk
    }
    set sectorList [exec sdds2stream $tmpfile -col=sector]
    foreach sector $sectorList x $xOk y $yOk {
        if {$x!=$y} {
            puts stderr "sector $sector C:H1 and C:V1 correctors have different configurations!"
            set OkForFastDCOrbitCorrection($sector) 0
        } else {
            set OkForFastDCOrbitCorrection($sector) $x
        }
    }
    file delete -force $tmpfile
}

proc GetOKCUSectorList {args} {
    global CUSectorList OKCUSectorList 
    set index 0
    foreach sector $CUSectorList {
        if $index {
            append matchOpt ",DeviceName=S${sector}C:P0,|"
        } else {
            set matchOpt "-match=col,DeviceName=S${sector}C:P0"
        }
        incr index
    }
    if [catch {exec sddsprocess /home/helios/oagData/sr/BPMStatus/config.sdds -pipe=out "$matchOpt" \
                 -filter=col,OkForSteeringH,0.5,1.5 -filter=col,OkForSteeringV,0.5,1.5 \
                 | sddsprocess -pipe -scan=col,Sector,DeviceName,S%ld,type=long \
                 | sdds2stream -pipe -col=Sector} OKCUSectorList] {
        return -code error "$okSectorList"
    }
}

GetCUSectorsAndCorrectorStatus
GetOKCUSectorList
MakeSectorsWidget .sectors -parent .userFrame

set statusCallback SetCUSteeringStatus

set R12(us) 2.4627
set R34(us) 2.4627
set R12(ds) 2.4827
set R34(ds) 2.4827

#updated the coefficents by Louis 11/26/2015
set R12(usc0) 0
set R34(usc0) 0
set R12(dsc0) 0.2558
set R34(dsc0) 0.2558

set R12(us) 2.3297
set R34(us) 2.3297
set R12(ds) 2.6157
set R34(ds) 2.6157

#PrepareFFFiles
set FFWaveformFile(h) /home/helios/oagData/sr/orbitControllaw/waveforms/FFwaveform.h
set FFWaveformFile(v) /home/helios/oagData/sr/orbitControllaw/waveforms/FFwaveform.v

# Local Variables:
# mode: tcl
# End:
