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

# $Log: not supported by cvs2svn $
# Revision 1.48  2006/08/02 00:59:39  emery
# Shang's changes: use -infiniteLoop argument to sddscontrollaw.
#
# Revision 1.47  2005/10/24 20:48:14  shang
# added TEST button to sector dialogs.
#
# Revision 1.46  2005/09/30 21:45:04  shang
# added automatically updating controllaw files when sector button is clicked.
#
# Revision 1.45  2005/08/22 15:27:35  shang
# replaced all old SRIDSteering messages by the correct steering type
#
# Revision 1.44  2005/08/22 15:23:03  shang
# added checking if controllaw directory and controllaw files exist before starting
# controllaw
#
# Revision 1.43  2004/03/12 19:11:09  emery
# Added warning info box for popping up when a bpms about to be used for
# steering is not ok for steering.
#
# Revision 1.42  2002/10/09 10:19:18  emery
# Added status messages for bpms setpoint changes.
#
# Revision 1.41  2002/10/09 07:08:39  shang
# added transferring vector adjust values and running controllaw in ioc
# if the corrector mode is vector
#
# Revision 1.40  2002/10/06 21:14:31  emery
# Added call to APSTransferVectorAdjust in ApplySetpoints.
# Added status message before the call to APSTransferVectorAdjust
# is made.
#
# Revision 1.39  2002/10/06 05:53:53  emery
# Simplified the coding of the cavput in ApplySetpoint.
# Replaced the string values PSCU and Diag with
# Maintenance and Operation.
#
# Revision 1.38  2002/05/30 19:50:35  emery
# Forgot to add the controlQuantityDefinition to sddscontrollaw.
#
# Revision 1.37  2002/02/27 23:54:40  emery
# Added controlQuantityDefinition option to sddscontrollaw to that the
# appropriate definition file will be selected based on the
# setpoint sources (Diag or PSCU) of correctors.
#
# Revision 1.36  2002/02/26 21:07:19  emery
# Changed default steering interval to 0.5 sec since we are now
# using speedy corrector PVs.
#
# Revision 1.35  1999/02/15 16:24:01  emery
# Made variable errorCode global.
#
# Revision 1.34  1999/01/20 15:28:52  borland
# Added -fastClick 1 option to in/out/up/down buttons.
#
# Revision 1.33  1998/10/18 20:58:19  borland
# Uses new data directory.
#
# Revision 1.32  1998/05/27 16:08:26  emery
# Inserted logMessage command to log the start of the steering,
# which was somehow omitted when logMessage commands were inserted
# to log the exit and abort of the steering.
#
# Revision 1.31  1998/05/21 20:55:20  emery
# Changed data file for light source point bpm
# used in DoTransfer procedure.
#
# Revision 1.30  1998/04/02 22:34:26  emery
# Corrected the Instance value to the logMessage command.
#
# Revision 1.29  1997/11/11 15:52:04  emery
# Commented out the high level bpms.
#
# Revision 1.28  1997/08/21 04:57:55  emery
# Added command line argument includeSourcePoints.
#
# Revision 1.27  1997/07/24 23:09:33  emery
# By default only the light sources will have the sector button
# enabled. The command line option allowAllSectors
# may be used to allow steering in all sectors.
#
# Revision 1.26  1997/07/24 15:39:58  emery
# Corrected a few typos that were introduced in the last revision.
#
# Revision 1.25  1997/04/25 19:38:47  emery
# Added -lineLimit 1024 to APSExecLog
#
# Revision 1.24  1997/04/21 18:25:51  emery
# Changed button label START to APPLY/START
#
# Revision 1.23  1997/04/15 17:34:20  emery
# For aplicable sectors, set the high level bpm PV
# to msAve.
#
# Revision 1.22  1997/04/03 08:10:53  emery
# Fixed small bug in ysteering accumulator.
#
# Revision 1.21  1997/03/26 17:00:39  emery
# Added more context help messages.
#
# Revision 1.20  1997/03/26 16:20:04  emery
# Changed coefficients for xp and yp conversion to
# new B:P3 and B:P4 setpoints. The new coefficients
# use the exact disatnaces betwen teh bpms an dthe source,
# while the old coefficients use an approximate value.
#
# Revision 1.19  1997/03/03 16:21:46  emery
# Added default interval and gain.
#
# Revision 1.18  1997/03/03 16:17:56  emery
# Replaced rpnl command with a tcl expr command.
#
# Revision 1.17  1997/03/03 16:16:27  emery
# Added missing argument to format statement.
#
# Revision 1.16  1997/03/03 16:14:32  emery
# Changed ${Sn1}BP$ to ${Sn}BP4.
#
# Revision 1.15  1997/03/03 15:37:38  emery
# To exec log command, added name and various callback arguments.
#
# Revision 1.14  1997/03/01 22:28:37  borland
# Removed previous changes.  Now start controllaw "locally" as before in
# an APSExecLog window.  Sets averaging for BPMs being controlled.  Uses
# new directory and names for matrix and test files.
#
# Revision 1.12  1996/12/13 18:17:28  borland
# Added option to not transfer source point orbit to setpoints.
#
# Revision 1.11  1996/10/08 08:05:46  emery
# Changed the labeling of the DECR INCR buttons to
# read UP DOWN IN OUT for x xp y yp adjustments.
# Adjusted borderwith of LabeledOutputFrame boxes and the
# spacing of the UP DOWN IN OUT buttons to match the
# spacing of the individual labeled entry.
# Replaced $var=="" type statements with ![string length $var]
# statements.
#
# Revision 1.10  1996/10/08 07:31:11  emery
# Made BM selection button labels shorter by removing the "BM"
# part of the string.
#
# Revision 1.9  1996/10/08 03:26:28  borland
# Added status callback option to orbit transfer call.
#
# Revision 1.8  1996/10/08 03:24:27  borland
# Fixed a spelling error.
#
# Revision 1.7  1996/10/08 01:07:33  borland
# Added -allowTransfer and -adjustOnly options for control of what the user
# is allowed to do.
#
# Revision 1.6  1996/10/07 15:44:11  borland
# Added widgets to allow transferring all setpoints for x, y, or both.
#
# Revision 1.5  1996/09/18 20:26:25  borland
# Removed disabling of start buttons.  Replaced with test of whether
# orbit controllaw is running.
#
# Revision 1.4  1996/09/18 20:09:39  borland
# Added APSDisableButton for Start button, to prevent use of screen for
# anything other than changing steering setpoints.
#
# Revision 1.3  1996/08/19 06:21:51  emery
# Simplified interface so that the function of the MORE button
# (i.e. releaving AdjustedCC and ErrorCC values) is always
# in effect. ALso, the delta x x' y y' steering dialog is
# now a permanent part of the ID dialog box.
#
# Revision 1.2  1996/07/02  11:24:16  emery
# Added x x' y y' increment dialog box for changing
# setpoint variables. One still has to press Apply button
# to send the values to EPICS.
#
# Revision 1.1  1996/07/02  08:08:19  emery
# First installation of SR BM steering.
# Controllaw not enabled though.
#

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
APSRenameExecToAPSBGExec

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

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

APSApplication . -name SRBMSteering.new \
  -overview "SRBMSteering provBMes convenience controls for BM steering using sddscontrollaw."
dp_atexit append KillAPSExecLogs
set tcl_precision 6


set BMSteeringStatus Ready.
APSScrolledStatus .status -parent .userFrame -width 80 \
        -textVariable BMSteeringStatus 

proc SetBMSteeringStatus {text} {
    global BMSteeringStatus
    set BMSteeringStatus $text
    update
}

proc MakeSectorsWidget {widget args} {
    global sector allowAllSectors otherDisplay

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

    if !$allowAllSectors {
        set sectorList [APSGetSDDSColumn -column Sector \
                          -fileName /home/helios/oagData/sr/BMs/sectors.sdds]
        #temporarily disable 24BM steering since S24HV3 is leaking
        set sectorList [regsub 24 $sectorList ""]
    }
    
    for {set quad 1} {$quad<5} {incr quad} {
        set start [expr ($quad-1)*10+1]
        set end   [expr $start+9]
        set buttonList {}
        set valueList {}
        APSFrame .sector$quad -parent $w.frame 
        $w.frame.sector$quad.frame configure -relief flat
        for {set sector $start} {$sector<=$end} {incr sector} {
            set cbLabel $sector
            if {$sector<10} {set cbLabel "0$sector"}
            APSButton .sector$sector -parent $w.frame.sector$quad.frame \
              -text "$cbLabel" \
              -command "BMSteeringDialog -sector $sector" \
              -contextHelp "Brings up dialog box for BM$cbLabel steering."
            if !$allowAllSectors {
                if [expr -1 == [lsearch $sectorList $sector]] {
                    APSDisableButton $w.frame.sector$quad.frame.sector$sector.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 &"
}

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
    }
    
}

proc BMSteeringDialog {args} {
    global BP4x BP4y BP3x BP3y allowTransfer adjustOnly sourcePointList errorCode otherDisplay
    global GoodBPMList
    set sector ""
    APSParseArguments {sector}
    if ![string length $sector] {
        APSAlertBox [APSUniqueName .] -errorMessage \
          "No sector variable specified in BMSteeringDialog"
        return 1
    }
    if [catch {APSCheckAndUpdateLocalSteeringConfigs -steeringType BM -sector $sector -statusCallback SetBMSteeringStatus} result] {
	SetBMSteeringStatus "$result"
        APSAlertBox [APSUniqueName .] -errorMessage \
          "Error in updating BM steering configs for sector $sector"
        return 1
    }
    SetBMSteeringStatus "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 BM} result] {
        SetBMSteeringStatus "Error in removing sector $sector xray bpms from orbit correction: $result"
        return
    }
    SetBMSteeringStatus "$result"
# check whether P4 and P3 bpms are OK for steering
    if {-1 == [lsearch $GoodBPMList S${sector}B:P4] ||
        -1 == [lsearch $GoodBPMList S${sector}B:P3] } {
        APSInfoWindow .warning  -packOption "-side left" \
          -infoMessage "** Steering is disabled for ${sector}BM.**\n\nAt last one of S${sector}B:P4 or S${sector}B:P3 is considered bad for steering. \n\nContact experts if steering is really required. Press OK to remove this window." \
          -modal 1
        SetBMSteeringStatus "Disabled ${sector}BM steering not attempted."
        return
    }
    
    set dialogFrame .dialogBM$sector.userFrame
    APSDialogBox .dialogBM$sector  \
      -name "BM$sector Dialog" \
      -contextHelp "Dialog box for steering in BM$sector."

#    if {[expr -1 < [lsearch $sourcePointList $sector]] } {
#        set useHighLevelPV($sector) 1
#    } else {
#        set useHighLevelPV($sector) 0
#    }
    set useHighLevelPV($sector) 0
    set Sn $sector
    if !$useHighLevelPV($sector) {
        if {[pv linkw \
               [list BP4x($sector) BP4y($sector) BP3x($sector) BP3y($sector)] \
               [list S${Sn}B:P4:ms:x:SetpointAO S${Sn}B:P4:ms:y:SetpointAO \
                  S${Sn}B:P3:ms:x:SetpointAO S${Sn}B:P3:ms:y:SetpointAO ]] != 0} {
            APSAlertBox .alert -errorMessage "$errorCode"
            exit
        } 
    } else {
        # set high level PV to msAve
        if [catch {exec cavput -list=S${sector}B:P -list=3,4 -list=:y:ErrorCC:ModeMO=0 \
                 } result ] {
            APSAlertBox .alert -errorMessage "$result\nSomething wrong with a cavput command."
            return
        }
        if {[pv linkw \
               [list BP4x($sector) BP4y($sector) BP3x($sector) BP3y($sector)] \
               [list S${Sn}B:P4:ms:x:SetpointAO S${Sn}B:P4:ms:y:SetpointAO \
                  S${Sn}B:P3:ms:x:SetpointAO S${Sn}B:P3:ms:y:SetpointAO ]] != 0} {
            APSAlertBox .alert -errorMessage "$errorCode"
            exit
        }
    }
    if {[pv umon BP4x($sector)] != 0} {
        APSAlertBox .alert -errorMessage "$errorCode"
        exit
    }
    if {[pv umon BP4y($sector)] != 0} {
        APSAlertBox .alert -errorMessage "$errorCode"
        exit
    }
    if {[pv umon BP3x($sector)] != 0} {
        APSAlertBox .alert -errorMessage "$errorCode"
        exit
    }
    if {[pv umon BP3y($sector)] != 0} {
        APSAlertBox .alert -errorMessage "$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 four bpm readbacks of BM$sector"
    $dialogFrame.parameters.frame.setpoints.frame configure -relief flat
    APSLabeledOutput .bp4x \
      -parent $dialogFrame.parameters.frame.setpoints.frame \
      -label "S${Sn}B:P4:x (mm)"  -width 10\
      -textVariable BP4x($sector) \
      -contextHelp "Enter value for S${Sn}B:P4:ms:x:SetpointAO to be applied. These values change when one of the associated coordinate delta button is pressed."
    APSLabeledOutput .bp4y \
      -parent $dialogFrame.parameters.frame.setpoints.frame \
      -label "S${Sn}B:P4:y (mm)"  -width 10\
      -textVariable BP4y($sector) \
      -contextHelp "Enter value for S${Sn}B:P4:ms:y:SetpointAO to be applied. These values change when one of the associated coordinate delta button is pressed."
    APSLabeledOutput .bp3x \
      -parent $dialogFrame.parameters.frame.setpoints.frame \
      -label "S${Sn}B:P3:x (mm)"  -width 10\
      -textVariable BP3x($sector) \
      -contextHelp "Enter value for S${Sn}B:P3:ms:x:SetpointAO to be applied. These values change when one of the associated coordinate delta button is pressed."
    APSLabeledOutput .bp3y \
      -parent $dialogFrame.parameters.frame.setpoints.frame \
      -label "S${Sn}B:P3:y (mm)"  -width 10\
      -textVariable BP3y($sector) \
      -contextHelp "Enter value for S${Sn}B:P3:ms:y:SetpointAO to be applied. These values change when one of the associated coordinate delta button is pressed."

    global stepSizeLimit
    APSLabeledEntry .limit -parent .dialogBM$sector -label "Corrector change limit (A):" -textVariable stepSizeLimit -width 50
    
    APSButton .adt -parent .dialogBM$sector.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 .dialogBM$sector.buttonRow -text "Review Pending Setpoint Changes"  -command "ApplySetpoints -sector $sector -review 1" -contextHelp  "review above setpoint value changes to setpoint PVs of ID$sector bpms." 
    
    APSButton .apply -parent .dialogBM$sector.buttonRow -text "APPLY Delta Steering"  -command "ApplySetpoints -sector $sector" -contextHelp  "Applies above setpoint values to setpoint PVs of BM$sector bpms."
   
    if {[pv linkw \
           [list BP4xOffset($sector) BP4yOffset($sector) BP3xOffset($sector) BP3yOffset($sector)] \
           [list S${Sn}B:P4:ms:x:OffsetAO S${Sn}B:P4:ms:y:OffsetAO \
              S${Sn}B:P3:ms:x:OffsetAO S${Sn}B:P3:ms:y:OffsetAO ]] != 0} {
        APSAlertBox .alert -errorMessage "$errorCode"
        exit
    }
    if {[pv linkw \
           [list BP4xAdjusted($sector) BP4yAdjusted($sector) BP3xAdjusted($sector) BP3yAdjusted($sector)] \
           [list S${Sn}B:P4:ms:x:AdjustedCC S${Sn}B:P4:ms:y:AdjustedCC \
              S${Sn}B:P3:ms:x:AdjustedCC S${Sn}B:P3:ms:y:AdjustedCC ]] != 0} {
        APSAlertBox .alert -errorMessage "$errorCode"
        exit
    }
    if {[pv linkw \
           [list BP4xError($sector) BP4yError($sector) BP3xError($sector) BP3yError($sector)] \
           [list S${Sn}B:P4:ms:x:ErrorCC S${Sn}B:P4:ms:y:ErrorCC \
              S${Sn}B:P3:ms:x:ErrorCC S${Sn}B:P3:ms:y:ErrorCC ]] != 0} {
        APSAlertBox .alert -errorMessage "$errorCode"
        exit
    }
    if {[pv umon BP4xOffset($sector)] != 0} {
        APSAlertBox .alert -errorMessage "$errorCode"
        exit
    }
    if {[pv umon BP4yOffset($sector)] != 0} {
        APSAlertBox .alert -errorMessage "$errorCode"
        exit
    }
    if {[pv umon BP3xOffset($sector)] != 0} {
        APSAlertBox .alert -errorMessage "$errorCode"
        exit
    }
    if {[pv umon BP3yOffset($sector)] != 0} {
        APSAlertBox .alert -errorMessage "$errorCode"
        exit
    }

    if {[pv umon BP4xAdjusted($sector)] != 0} {
        APSAlertBox .alert -errorMessage "$errorCode"
        exit
    }
    if {[pv umon BP4yAdjusted($sector)] != 0} {
        APSAlertBox .alert -errorMessage "$errorCode"
        exit
    }
    if {[pv umon BP3xAdjusted($sector)] != 0} {
        APSAlertBox .alert -errorMessage "$errorCode"
        exit
    }
    if {[pv umon BP3yAdjusted($sector)] != 0} {
        APSAlertBox .alert -errorMessage "$errorCode"
        exit
    }

    if {[pv umon BP4xError($sector)] != 0} {
        APSAlertBox .alert -errorMessage "$errorCode"
        exit
    }
    if {[pv umon BP4yError($sector)] != 0} {
        APSAlertBox .alert -errorMessage "$errorCode"
        exit
    }
    if {[pv umon BP3xError($sector)] != 0} {
        APSAlertBox .alert -errorMessage "$errorCode"
        exit
    }
    if {[pv umon BP3yError($sector)] != 0} {
        APSAlertBox .alert -errorMessage "$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 "BP4xOffset($sector) BP4yOffset($sector) BP3xOffset($sector) BP3yOffset($sector)"\
      -orientation vertical -width 10 \
      -contextHelp "Electrical offset of BM$sector bpms."
    $dialogFrame.moreParameters.frame.offset.frame configure -relief flat

    APSLabeledOutputFrame .adjusted -parent $dialogFrame.moreParameters.frame \
      -label Adjusted -packOption "-side left" \
      -variableList "BP4xAdjusted($sector) BP4yAdjusted($sector) BP3xAdjusted($sector) BP3yAdjusted($sector)"\
      -orientation vertical -width 10 \
      -contextHelp "Adjusted readbacks of BM$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 "BP4xError($sector) BP4yError($sector) BP3xError($sector) BP3yError($sector)"\
      -orientation vertical -width 10 \
      -contextHelp "Error readbacks of BM$sector bpms: adjusted readback - setpoint."
    $dialogFrame.moreParameters.frame.error.frame configure -relief flat

    set border 3
    foreach outputFrame {offset adjusted error} {
        foreach entry {1 2 3 4} {
            $dialogFrame.moreParameters.frame.${outputFrame}.frame.entry${entry} \
              configure -borderwidth $border
        }
    }

    AdjustSetpoints -sector $sector -parent $dialogFrame
    APSEnableButton .dialogBM$sector.buttonRow.ok.button
    
    if [catch {exec cavput -list=S${Sn}B:P3,S${Sn}B:P4 -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 BM steering." } result] {
        return -code error "Error doing SR bpm setpoint save: $result"
    }
    if [catch {APSSaveMachine -machine SRCorSetpts -description "Save before sector $sector BM steering." } result] {
        return -code error "Error doing SR corrector setpoint save: $result"
    }
}



proc AdjustSetpoints {args} {
    global deltax deltaxp deltay deltayp steeringx steeringxp steeringy steeringyp
    global deltaxAcc deltaxpAcc deltayAcc deltaypAcc
    global BP4x BP4y BP3x BP3y

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

# accumulators for steering changes.
    set deltaxAcc($sector) 0
    set deltaxpAcc($sector) 0
    set deltayAcc($sector) 0
    set deltaypAcc($sector) 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, x', y, y' coordinates  in BM$sector"
    $adjustFrame.parameters.frame.deltas.frame configure -relief flat
    if ![info exists deltax($sector)] {
        set deltax($sector) 0
    }
    if ![info exists deltaxp($sector)] {
        set deltaxp($sector) 0
    }
    if ![info exists deltay($sector)] {
        set deltay($sector) 0
    }
    if ![info exists deltayp($sector)] {
        set deltayp($sector) 0
    }
    APSLabeledEntry .bp4x \
      -parent $adjustFrame.parameters.frame.deltas.frame \
      -label "delta x (um)"  -width 10\
      -textVariable deltax($sector) \
      -contextHelp "Enter value for delta x"
    APSLabeledEntry .bp4y \
      -parent $adjustFrame.parameters.frame.deltas.frame \
      -label "delta xp (urad)"  -width 10\
      -textVariable deltaxp($sector) \
      -contextHelp "Enter value for delta xp"
    APSLabeledEntry .bp3x \
      -parent $adjustFrame.parameters.frame.deltas.frame \
      -label "delta y (um)"  -width 10\
      -textVariable deltay($sector) \
      -contextHelp "Enter value for delta y"
    APSLabeledEntry .bp3y \
      -parent $adjustFrame.parameters.frame.deltas.frame \
      -label "delta yp (urad)"  -width 10\
      -textVariable deltayp($sector) \
      -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

    APSButton .incrx -parent $adjustFrame.parameters.frame.incrButtons.frame  \
        -packOption "-side top" -text OUT -command "IncrX -sector $Sn" \
        -contextHelp  "Changes x setpoints using delta x." -fastClick 1
    APSButton .incrxp -parent $adjustFrame.parameters.frame.incrButtons.frame  \
        -packOption "-side top" -text OUT -command "IncrXp -sector $Sn" \
        -contextHelp  "Changes x setpoints using delta xp." -fastClick 1
   
    APSButton .incry -parent $adjustFrame.parameters.frame.incrButtons.frame  \
        -packOption "-side top" -text UP -command "IncrY -sector $Sn" \
        -contextHelp  "Changes y setpoints using delta y." -fastClick 1
    APSButton .incryp -parent $adjustFrame.parameters.frame.incrButtons.frame  \
        -packOption "-side top" -text UP -command "IncrYp -sector $Sn" \
        -contextHelp  "Changes y setpoints using delta yp." -fastClick 1
   
    APSButton .decrx -parent $adjustFrame.parameters.frame.decrButtons.frame  \
        -packOption "-side top" -text IN -command "IncrX -sector $Sn -sign -1" \
        -contextHelp  "Changes x setpoints using delta x." -fastClick 1
    APSButton .decrxp -parent $adjustFrame.parameters.frame.decrButtons.frame  \
        -packOption "-side top" -text IN -command "IncrXp -sector $Sn -sign -1" \
        -contextHelp  "Changes x setpoints using delta xp." -fastClick 1
   
    APSButton .decry -parent $adjustFrame.parameters.frame.decrButtons.frame  \
        -packOption "-side top" -text DOWN -command "IncrY -sector $Sn -sign -1" \
        -contextHelp  "Changes y setpoints using delta y." -fastClick 1
    APSButton .decryp -parent $adjustFrame.parameters.frame.decrButtons.frame  \
        -packOption "-side top" -text DOWN -command "IncrYp -sector $Sn -sign -1" \
        -contextHelp  "Changes y setpoints using delta yp." -fastClick 1
    
    set steeringx($sector) 0
    set steeringxp($sector) 0
    set steeringy($sector) 0
    set steeringyp($sector) 0
    
    APSLabeledOutputFrame .steering \
      -parent $adjustFrame.parameters.frame \
      -label "Steering delta" -packOption "-side left" \
      -variableList "steeringx($sector) steeringxp($sector) steeringy($sector) steeringyp($sector)" \
      -orientation vertical -width 10 \
      -contextHelp "steeering deltas. Values return to zero when apply button is pressed."
    $adjustFrame.parameters.frame.steering.frame configure -relief flat
    set border 3
    foreach entry {1 2 3 4} {
        $adjustFrame.parameters.frame.steering.frame.entry${entry} \
          configure -borderwidth $border
    }
    
    APSLabeledOutputFrame .accumulation \
      -parent $adjustFrame.parameters.frame \
      -label "Accumulators" -packOption "-side left" \
      -variableList "deltaxAcc($sector) deltaxpAcc($sector) deltayAcc($sector) deltaypAcc($sector)" \
      -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 3 4} {
        $adjustFrame.parameters.frame.accumulation.frame.entry${entry} \
          configure -borderwidth $border
    }
    
    set padding 2
    set width 4
    $adjustFrame.parameters.frame.incrButtons.frame.incrx.button configure -width $width -pady $padding
    $adjustFrame.parameters.frame.incrButtons.frame.incrxp.button configure -width $width -pady $padding
    $adjustFrame.parameters.frame.incrButtons.frame.incry.button configure -width $width -pady $padding
    $adjustFrame.parameters.frame.incrButtons.frame.incryp.button configure -width $width -pady $padding
    $adjustFrame.parameters.frame.decrButtons.frame.decrx.button configure -width $width -pady $padding
    $adjustFrame.parameters.frame.decrButtons.frame.decrxp.button configure -width $width -pady $padding
    $adjustFrame.parameters.frame.decrButtons.frame.decry.button configure -width $width -pady $padding
    $adjustFrame.parameters.frame.decrButtons.frame.decryp.button configure -width $width -pady $padding
   
    return 0
}

proc IncrX {args} {
    global deltax deltaxp deltay deltayp
    global deltaxAcc deltaxpAcc deltayAcc deltaypAcc steeringx
    global BP4x BP4y BP3x BP3y
    set sector ""
    set sign 1
    APSParseArguments {sector sign}
    if ![string length $sector] {
        APSAlertBox [APSUniqueName .] -errorMessage \
          "No sector variable specified in BMSteeringDialog"
        return 1
    }
    set deltax($sector) [scan $deltax($sector) %ld]
    set deltaxAcc($sector) [expr $deltaxAcc($sector) + $sign * $deltax($sector)]
    set steeringx($sector) [expr $steeringx($sector) + $sign * $deltax($sector)]
    
   # set BP4x($sector) [expr $BP4x($sector) + $sign * $deltax($sector)]
   # set BP3x($sector) [expr $BP3x($sector) + $sign * $deltax($sector)]
    return 0
}
proc IncrXp {args} {
    global deltax deltaxp deltay deltayp steeringxp
    global deltaxAcc deltaxpAcc deltayAcc deltaypAcc
    global BP4x BP4y BP3x BP3y
    set sector ""
    set sign 1
    APSParseArguments {sector sign}
    if ![string length $sector] {
        APSAlertBox [APSUniqueName .] -errorMessage \
          "No sector variable specified in BMSteeringDialog"
        return 1
    }
    set deltaxp($sector) [scan $deltaxp($sector) %ld]
    set deltaxpAcc($sector) [expr $deltaxpAcc($sector) + $sign * $deltaxp($sector)]
    set steeringxp($sector) [expr $steeringxp($sector) + $sign * $deltaxp($sector)]
   # set BP4x($sector) [expr $BP4x($sector) - $sign * 0.5015 * $deltaxp($sector)]
   # set BP3x($sector) [expr $BP3x($sector) + $sign * 2.8310 * $deltaxp($sector)]
    return 0
}

proc IncrY {args} {
    global deltax deltaxp deltay deltayp steeringy
    global deltaxAcc deltaxpAcc deltayAcc deltaypAcc
    global BP4x BP4y BP3x BP3y
    set sector ""
    set sign 1
    APSParseArguments {sector sign}
    if ![string length $sector] {
        APSAlertBox [APSUniqueName .] -errorMessage \
          "No sector variable specified in BMSteeringDialog"
        return 1
    }
    set deltay($sector) [scan $deltay($sector) %ld]
    set deltayAcc($sector) [expr $deltayAcc($sector) + $sign * $deltay($sector)]
    set steeringy($sector) [expr $steeringy($sector) + $sign * $deltay($sector)]
    #set BP4y($sector) [expr $BP4y($sector) + $sign * $deltay($sector)]
    #set BP3y($sector) [expr $BP3y($sector) + $sign * $deltay($sector)]
    return 0
}
proc IncrYp {args} {
    global deltax deltaxp deltay deltayp steeringyp
    global deltaxAcc deltaxpAcc deltayAcc deltaypAcc
    global BP4x BP4y BP3x BP3y
    set sector ""
    set sign 1
    APSParseArguments {sector sign}
    if ![string length $sector] {
        APSAlertBox [APSUniqueName .] -errorMessage \
          "No sector variable specified in BMSteeringDialog"
        return 1
    }
    set deltayp($sector) [scan $deltayp($sector) %ld]
    set deltaypAcc($sector) [expr $deltaypAcc($sector) + $sign * $deltayp($sector)]
    set steeringyp($sector) [expr $steeringyp($sector) + $sign * $deltayp($sector)]
  #  set BP4y($sector) [expr $BP4y($sector) - $sign * 0.5015 * $deltayp($sector)]
   # set BP3y($sector) [expr $BP3y($sector) + $sign * 2.8310 * $deltayp($sector)]
    return 0
}

set stepSizeLimit 1
proc ApplySetpoints {args} {
    global BP4x BP4y BP3x BP3y steeringx steeringxp steeringy steeringyp ignoreLock
    global timeLimit tolerance statusCallback FFWaveformFile stepSizeLimit corrRangeFile corrNameFile

    set sector ""
    set review 0
    APSParseArguments {sector review}
    if ![string length $sector] {
        APSAlertBox [APSUniqueName .] -errorMessage \
          "No sector variable specified in BMSteeringDialog"
        return 1
    }

    set Sn $sector 
    set bp4 S${Sn}B:P4
    set bp3 S${Sn}B:P3
# New values due to new circumberefence of the ring calculated
# belatedly for Decker distortion. Old values are:
#    set factorbp4 0.5015
#    set factorbp3 2.8310
    set factorbp4 0.50306
    set factorbp3 2.82951
    
    if {$steeringx($sector)==0 && $steeringxp($sector)==0 && $steeringy($sector)==0 && $steeringyp($sector)==0} {
        SetBMSteeringStatus "All steering deltas for sector $sector are zero, nothing needs to be done."
        return
    }
    set refMatrixDir /home/helios/oagData/sr/orbitControllaw/lattices/default/refMatrices
    set controllawDir /home/helios/oagData/sr/localSteering/lattices/default/BMs/[format %02ld ${sector}]BM
    set waveformDir /home/helios/oagData/sr/orbitControllaw/waveforms
     if {!$review && !$ignoreLock} {
        SetBMSteeringStatus "Lock global steering..."
        if [catch {exec cavput -list=SRID:SteeringLockBI.VAL=1 -pend=30} result] {
            return -code error "Error in locking global steering: $result"
        }
    }
   
    foreach plane {h v} coord {x y} Coord {X Y} {
        set delta [expr [set steering${coord}($sector)]/1000.0]
        set deltap [expr [set steering${coord}p($sector)]/1000.0]
        if {$delta==0 && $deltap==0} {
            SetBMSteeringStatus "No setpoint changes needed for $plane plane."
            continue
        }
        set deltaBP4 [expr $delta - $factorbp4 * $deltap]
        set deltaBP3 [expr $delta + $factorbp3 * $deltap]
        if !$review {
            SetBMSteeringStatus "Change corrector rangeErrors..."
            if [catch {exec sddscasr -restore $controllawDir/$plane.corr.range } result] {
                return -code error "Error changing corrector rangeErrors: $result"
            }
        }
        if [catch {APSSRApplySteeringSetpoints -sector $sector -source BM -plane $plane -bpmList [list $bp4 $bp3] \
                     -xp $steeringxp($sector) -yp $steeringyp($sector) \
                     -stepSizeLimit $stepSizeLimit \
                     -deltaList [list $deltaBP4 $deltaBP3] \
                     -refMatrix $controllawDir/${plane}.steering.rm \
                     -FFWaveform $FFWaveformFile($plane) \
                     -review $review -dryRun 0 \
                     -statusCallback SetBMSteeringStatus } result] {
            if !$review {
                if [catch {exec sddscasr -restore $controllawDir/$plane.corr.range.orig } result1] {
                    return -code error "$result\nError restoring corrector rangeErrors: $result1"
                }
            }
            return -code error "Error applying setpoints for ${plane}-plane: $result"
        }
        if !$review {
            SetBMSteeringStatus "Restore corrector rangeErrors..."
            if [catch {exec sddsprocess $controllawDir/$plane.corrName -pipe=out -edit=col,ControlName,CorrName,ei/:DacAI/ \
                         | sddscasr -pipe -save -pend=30 \
                         | sddsprocess -pipe -reedit=col,ControlName,%/DacAI/RangeErrorCALC.B/ \
                         | sddscasr -pipe=in -restore } result] {
                if [catch {exec sddscasr -restore  $controllawDir/$plane.corr.range.orig } result1] {
                    return -code error "$result\nError restoring corrector rangeErrors: $result1"
                }
                return -code error "Error tranfer DacAI to RangeErrorCALC.B: $result"
            }
            if [catch {exec sddscasr -restore $controllawDir/$plane.corr.range.orig } result] {
                return -code error "Error restoring corrector rangeErrors: $result"
            }
        }
    }
    if $review {
        return
    }
    if !$ignoreLock {
        SetBMSteeringStatus "Unlock global steering..."
        if [catch {exec cavput -list=SRID:SteeringLockBI.VAL=0 -pend=30} result] {
            return -code error "Error in unlocking global steering: $result"
        }
    }
    # save SR. For now use the smaller special files in order to make this quick.
    if [catch {APSSRSaveSteeringToOps -installUBOP 1 -statusCallback SetBMSteeringStatus \
                 -description "Steering save: BM${sector} deltaX: $steeringx($sector) deltaXp: $steeringxp($sector) deltaY: $steeringy($sector) deltaYp: $steeringyp($sector)" } result] {
        return -code error "Error in saving steering to UBOP: $result"
    }
    
    set steeringx($sector) 0
    set steeringxp($sector) 0
    set steeringy($sector) 0
    set steeringyp($sector) 0
    SetBMSteeringStatus "Applying $sector sector setpoints done."
    return
}


set sourcePointList [APSGetSourcePointSectors -group BM]

MakeSectorsWidget .sectors -parent .userFrame

# make list of  P4 and P3 bpms are OK for BM steering
set GoodBPMList [exec sddsprocess /home/helios/oagData/sr/BPMStatus/config.sdds \
               -pipe=out \
               -match=col,DeviceName=*B:P4,DeviceName=*B:P3,| \
               -filter=col,OkForSteeringH,0,0,OkForSteeringV,0,0,|,! \
               | sdds2stream -pipe=in -col=DeviceName]

set tolerance 0.050
set timeLimit 25
set statusCallback SetBMSteeringStatus
set interval 0.5
set gain 0.3
#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:
