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

# $Log: not supported by cvs2svn $
# Revision 1.18  2003/05/23 03:11:28  emery
# Added to the zero bpm command setting of the gains to 1.
# Note that the corresponding save and restore doesn't include the
# gains so the gains must be restored manually.
#
# Revision 1.17  2003/04/25 16:03:23  shang
# added checking cogging, corrector current (<100 A) and DCCT current (>15 mA) to
# zero setpoints (before "SCAN")
#
# Revision 1.16  2001/10/26 18:48:00  emery
# Added sddscontrollaw restart feature to be used when
# a timeout error occurs during scans.
#
# Revision 1.15  2001/02/13 13:17:41  emery
# Added more digital bpld support.
#
# Revision 1.14  2000/10/28 12:39:54  emery
# Use SRHVOrbitCorrectionConfig instead of SROrbitCorrectionConfig
#
# Revision 1.13  1999/10/31 08:14:25  emery
# Added a "done" message after zeroing bpm.
#
# Revision 1.12  1999/09/28 16:58:07  emery
# Added button "CHECK STEERING CONFIGURATION..." which brings
# up a orbit configuration configuration tool with the standard
# bpld verification configuration.
#
# Revision 1.11  1999/07/01 23:03:53  emery
# Use multiple-list foreach statement for assigned values to
# firstChannelBPM and secondChannelBPM.
#
# Revision 1.10  1999/02/11 19:36:50  emery
# Corrected a label, and added context help.
#
# Revision 1.9  1999/02/03 06:55:30  emery
# Removed the automatic corrector ramp command because somehow
# the ramp occurs before the scan is completed.
# I'll have to investigatethis  another time.
# Added sector 34 to the list of sectors which uses P1 bpms for bplds.
#
# Revision 1.8  1999/01/21 11:13:37  emery
# Added arrays and firstChannelBPM secondChannelBPM to handle
# bplds that are mixed between P1 and P2.
# Removed sector as a global variable.
# Added an operational info message for the start-up.
# Added ramp correctors button
# and also as part of the procedure following one scan.
#
# Revision 1.7  1998/10/06 12:12:18  emery
# Addes buttons and procedure to save and restore corrector configuration.
#
# Revision 1.6  1998/03/07 08:18:08  emery
# chnged capilatization of global variables to read
# localMPSResults mainMPSResults.
#
# Revision 1.5  1997/10/20 17:26:33  emery
# Added a scroll frame for the BPLD tests.
#
# Revision 1.4  1997/10/18 08:05:24  emery
# Changed the width of the output boxes indicating
# the result of the tests.
#
# Revision 1.3  1997/05/24 14:13:08  emery
# Redesigned interface to display a large table of trip limits
# tests results. Each row represents a BPLD. The SCAN button
# initiates trip limit tests in four direction.
# sddscontrollaw steers the beam along the four direction while
# the BPM setpoints are adjusted.
# A cawait command in an ExecLog determines when
# the sddscontrollaw has converged. A callback is used to start
# the steering of the next trip limit direction.
#
# Revision 1.2  1996/06/19  17:11:12  emery
# Made a loop for the 8 setpoints around the x-y bpm readback space.
#
# Revision 1.1  1996/05/03  13:35:54  emery
# Interface and procedures for SR BPLD verification.
#
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

if [file exists SRBPLDVerification.tcl] {
    source SRBPLDVerification.tcl
}

APSApplication . -name SRBPLDVerification \
  -overview "SRBPLDVerification provides convenience controls for BPLD trip limit testing.\n\nThe closed orbit at a selected ID section is scanned at four point in both the horizontal and vertical planes. The orbit setpoints points are to be chosen a little past the trip limits.\n\nProgram sddscontrollaw is used to steer the beam in a few iterations towards the setpoints. The BPLD status is checked after the beam has settled down and a reset command is sent to clear any trips that might have occured during steering transient. The functioning of the BPLD is displayed in a large table.\n\nBefore scanning the bpm trip limits, the orbit setpoint and offsets at the bplds must be set to zero."

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

proc SetBPLDVerificationStatus {text} {
    global BPLDVerificationStatus
    set BPLDVerificationStatus $text
    update
    bell
}

proc MakeSectorsTable {widget args} {
    global BPLDList IsDigitalList scanButtonWidget

    set directions {xLo xHi yLo yHi}
    foreach direction  {xLo xHi yLo yHi} {
        global ${direction}1Results ${direction}2Results
    }
    global localMPSResults mainMPSResults

    set parent ""
    APSParseArguments {parent}

    set w $parent$widget
    APSFrame $widget -parent $parent -label "BPLD orbit scanning results."\
      -contextHelp {Table of BPLD functioning.} 

    foreach direction  $directions {
        foreach sector $BPLDList {
        set ${direction}1Results($sector) ""
        set ${direction}2Results($sector) ""
        }
    }

    set prefixHelp(xLo) "Lower horizontal limit"
    set prefixHelp(yLo) "Lower vertical limit"
    set prefixHelp(xHi) "Upper horizontal limit"
    set prefixHelp(yHi) "Upper vertical limit"

    APSFrame .labels -parent $w.frame -packOption "-side top -fill x -expand true"
    $w.frame.labels.frame configure -relief flat -bd 0
    label $w.frame.labels.frame.leftPadding -text "   "
    pack $w.frame.labels.frame.leftPadding -side left -fill x -expand true
    set i 0
    foreach text {"X In" "X Out" "Y Bot" "Y Top" "Local\nMPS" "  Main  \nMPS"} {
        APSFrame .l$i -parent $w.frame.labels.frame -label $text \
          -packOption "-side left -fill x -expand true"
        $w.frame.labels.frame.l$i.frame configure -relief flat -bd 0
        if {$i<4} {
            label $w.frame.labels.frame.l$i.frame.label -text " ch. 1   ch. 2  "
            pack $w.frame.labels.frame.l$i.frame.label -side top
        } else {
            label $w.frame.labels.frame.l$i.frame.label -text "  "
            pack $w.frame.labels.frame.l$i.frame.label -side top
        }
        incr i
    }
    label $w.frame.labels.frame.rightPadding -text "     "
    pack $w.frame.labels.frame.rightPadding -side left -fill x -expand true

    set parent $w.frame
    set w [APSScroll .scroll -parent $parent \
              -contextHelp "View BPLD orbit scan results"]
    foreach sector $BPLDList IsDigital $IsDigitalList {
        set sectorWidget $w.s$sector.frame
        APSFrame .s$sector -parent $w -height 20 \
          -contextHelp "Orbit scan test for BPLD$sector"
        $sectorWidget configure -relief flat -bd 0
        label $sectorWidget.label -text "$sector" -width 2 -pady 2
        pack  $sectorWidget.label -side left -fill x
        foreach direction $directions {
            foreach channel {1 2} {
                APSLabeledOutput .testResult${direction}chan${channel} \
                  -parent $sectorWidget \
                  -label ""  -width 7 \
                  -packOption { -side left -padx 0 -pady 0} \
                  -textVariable ${direction}${channel}Results($sector) \
                  -contextHelp "Orbit scan test for BPLD$sector ${direction} direction channel ${channel}"
                $sectorWidget.testResult${direction}chan${channel}.entry \
                  configure -relief flat -bd 0
            }
        }
        APSLabeledOutput .localMPS -parent $sectorWidget \
          -label ""  -width 7 \
          -packOption {-padx 0 -pady 0 -side left} \
          -textVariable localMPSResults($sector)
        $sectorWidget.localMPS.entry configure -relief flat -bd 0
        APSLabeledOutput .mainMPS -parent $sectorWidget \
          -label ""  -width 7 \
          -packOption {-padx 0 -pady 0 -side left} \
          -textVariable mainMPSResults($sector)
        $sectorWidget.mainMPS.entry configure -relief flat -bd 0
        APSButton .scan -parent $sectorWidget -text "SCAN" -size small\
          -highlightColor red -highlight 1 -packOption "-pady 1 -side left" \
          -command "TestLimits -sector $sector -IsDigital $IsDigital" \
          -contextHelp "Scans the orbit at BPLD $sector according to the testing mode selected in the options. The results of the scan is displayed in the table."
        set scanButtonWidget($sector) $sectorWidget.scan.button
        set lastWidget $sectorWidget
    }
    tkwait visibility $lastWidget 
    APSScrollAdjust $parent.scroll -numVisible 10 
}

proc MakeOptionWidget {widget args} {
    global aboveLimit tolerance timeLimit statusCallback

    set parent ""
    APSParseArguments {parent}

    set w $parent$widget
    APSFrame $widget -parent $parent -label "Options" \
        -contextHelp "Options in testing the BPLD limits."
    

    APSLabeledEntry .above -parent $w.frame\
      -label "Steering past trip level (mm)" \
      -textVariable aboveLimit -width 5 \
      -contextHelp "The BPLD will be tested (for tripped state) by moving the orbit to the trip level plus some the small steering excess specified here. Obviously only a positive will make sense."
 
    APSLabeledEntry .tolerance -parent $w.frame \
      -label "Orbit tolerance (mm)" \
      -textVariable tolerance  -width 8 \
      -contextHelp "Orbit correction runs until the orbit is within the tolerance (units of mm) of the target steering (usually 0 mm error). Then the BPLD trip status is checked."
    APSLabeledEntry .timeLimit -parent $w.frame -label "Time limit (sec)" \
      -textVariable timeLimit  -width 8 \
      -contextHelp "Maximum time to wait for sddscontrollaw to steer the beam to the desired setpoints."

    APSRadioButtonFrame .testHeartBeat -parent $w.frame -label "Verification Mode" \
      -variable verificationType -valueList {pendingTrips heartbeatStop} \
      -buttonList {"pending trips"  "heartbeat stop"} \
      -orientation horizontal \
      -contextHelp \
      "Testing \"heartbeat stop\" involves scanning the orbit at the BPLD in one direction only, and checking that the MPS heartbeat is stopped and beam is dumped by the MPS system. (The beam is dumped only when I > 0.5 mA. This requires that the gap on the corresponding ID is closed, i.e. undulator jaws off the limit switches.\n\n
In testing \"pending trips\" the orbit is scanned in four directions. In order to save time, the beam does not have to be dumped at each scan. The gap on the corresponding ID must be open, i.e. undulator jaws on the limit switches."
}

proc MakeActionWidget {widget args} {
    global abortBPLDTests statusCallback 

    set parent ""
    APSParseArguments {parent}
    
    set w $parent$widget
    APSFrame $widget -parent $parent -label "" \
        -contextHelp "Action buttons for BPLD testing."
    $w.frame configure -relief flat
    APSFrame .row1 -parent $w.frame -label "Actions" \
        -contextHelp "BPLD testing and aborting."
    APSFrameGrid .row2 -parent $w.frame  -xList {a b c}
    label $w.frame.row2.a.label -text "Orbit setpoints and offsets"
    pack $w.frame.row2.a.label
    $w.frame.row2.a configure -relief ridge -bd 2
    label $w.frame.row2.b.label -text "Corrector setpoints"
    pack $w.frame.row2.b.label
    $w.frame.row2.b configure -relief ridge -bd 2

    APSButton .checkConfig -text "CHECK STEERING CONFIGURATION..." \
      -command "exec SRHVOrbitCorrectionConfig -initialConfig h.BPLDVerification" \
      -parent $w.frame.row1.frame \
      -contextHelp "Brings up the SRHVOrbitCorrectionConfig to allow the user to check whether the right bpms are selected in the correction configuration for BPLD verification in both h and v planes.\n\nIf the BPLD bpms are not included in the configuration then the user is supposed in make the appropriate changes, otherwise the BPLD verification will not be valid for the particular BPLD."
    APSButton .test -text "TEST ALL LIMITS" \
      -command "TestAllLimits " \
      -parent $w.frame.row1.frame \
      -contextHelp "Tests the BPLD limits for all BPLDs. It must be enabled by the ENABLE button and may be disabled by the DISABLE button.\n\nNot implemented yet."
    APSDisableButton $w.frame.row1.frame.test.button
    APSButton .abort  -text "ABORT" \
      -command "set abortBPLDTests 1" \
      -parent $w.frame.row1.frame \
      -contextHelp "Aborts at the next convenient time during testing."
    APSButton .info -parent $w.frame.row1.frame\
      -text INFO -command ControllawInfoButton \
      -contextHelp "Displays medm screen for the run control PVs used."
    APSButton .restart -parent $w.frame.row1.frame\
      -text RESTART -command "StartControllaw -restartOnly 1"\
      -contextHelp "Restarts sddscontrollaw whenever it times out during the tests."
    APSButton .gen -text "GENERATE" -parent $w.frame.row1.frame \
        -command "GenerateControllawFiles" \
        -contextHelp "generate controllaw files for h/v.BPLDVerification"

    APSButton .save  -text "SAVE" \
      -command "OrbitSetpoints -action save -statusCallback $statusCallback" \
      -parent $w.frame.row2.a \
      -contextHelp "Save current orbit setpoints and offsets. Used normally before any BPLDs are verified."
    APSButton .zero  -text "ZERO" \
      -command "OrbitSetpoints -action zero -statusCallback $statusCallback" \
      -parent $w.frame.row2.a \
      -contextHelp "Zero the orbit setpoints and offsets in preparation to the local orbit controllaw running on each BPLD straight section. Also the gains are set to 1.\n\Saving the orbit setpoints previously is highly recommended for a quick recovery if the testing is interrupted. Note that the gains are not saved or restored.\n\nThe test scan buttons will activate after the ZERO button is pressed. "
    APSButton .restore  -text "RESTORE" \
      -command "OrbitSetpoints -action restore -statusCallback $statusCallback" \
      -parent $w.frame.row2.a \
      -contextHelp "Restore the previously saved orbit setpoints and offsets. Normally used after BPLD verification is finished for all sectors selected. Note that the gains are not saved or restored."
    APSButton .save  -text "SAVE" \
      -command "CorrectorSetpoints -action save -statusCallback $statusCallback" \
      -parent $w.frame.row2.b \
      -contextHelp "Save current correctors setpoints. The gains are not saved.\n\nThis action is highly recommended before doing any scans of the BPLDs."
    APSButton .restore  -text "RESTORE" \
      -command "CorrectorSetpoints -action restore -statusCallback $statusCallback" \
      -parent $w.frame.row2.b \
      -contextHelp "Restore the previously saved correctors. Normally used when there is no beam in the machine."
    APSButton .ramp  -text "RAMP" \
      -command "CorrectorSetpoints -action ramp -statusCallback $statusCallback" \
      -parent $w.frame.row2.b \
      -contextHelp "Ramp to the previously saved correctors. Recommended when there is still beam in the machine. Normally used after BPLD verification is finished for all sectors selected."
    
}

proc GenerateControllawFiles {args} {
    global BPMLimit XBPMLimit corrLimit rangeErrorLimit S35DCCTLimitH S35DCCTLimitV 
    global dialogBoxResponse PVSuffix
    set S35DCCTLimitH 15
    set S35DCCTLimitV 15
    set BPMLimit 10
    set XBPMLimit 0.5
    set corrLimit 149.5
    set rangeErrorLimit 300
    set PVSuffix msAve
    set dialogBoxResponse ""
    SetBPLDVerificationStatus "Generating files for h.BPLDVerification and v.BPLDVerification"
    set win [APSUniqueName .]
    APSDialogBox $win -cancelCommand "set dialogBoxResponse cancel"  \
        -okCommand "set dialogBoxResponse ok"  -name "Controllaw test file limits" 
    set w $win.userFrame
    APSLabeledEntry .le0 -parent $w -label "bpm limit (mm)" \
        -textVariable BPMLimit -width 10
    APSLabeledEntry .le1 -parent $w -label "Xray bpm limit (mm)" \
        -textVariable XBPMLimit -width 10
    APSLabeledEntry .le2 -parent $w -label "corrector limit (A)" \
        -textVariable corrLimit -width 10
    APSLabeledEntry .le3 -parent $w -label "Range Error limit (A)" \
        -textVariable rangeErrorLimit -width 10
    APSLabeledEntry .currLimitH -parent $w -label "S35DCCT lower limit (mA) for H plane" \
        -textVariable S35DCCTLimitH -width 10 \
        -contextHelp "Enter the lower limit of S35DCCT readback below which the sddscontrollaw correction iteration is skipped."
    APSLabeledEntry .currLimitV -parent $w -label "S35DCCT lower limit (mA) for V plane" \
        -textVariable S35DCCTLimitV -width 10 \
        -contextHelp "Enter the lower limit of S35DCCT readback below which the sddscontrollaw correction iteration is skipped."
    APSRadioButtonFrame .pvSuffix -parent $w -label "bpm PV type" \
        -variable PVSuffix -valueList {ms msAve mswAve} \
        -buttonList {ms msAve mswAve} -orientation horizontal -contextHelp \
        "Select the memory/scanner PV type (i.e. bpm data type)."
    tkwait window $win
    update
    if {$dialogBoxResponse=="cancel"} {
        SetBPLDVerificationStatus "Controllaw files regeneration was cancelled."
        return
    }
    set baseDir /home/helios/oagData/sr/orbitControllaw/lattices/default
    foreach plane {h v} {
        set config ${plane}.BPLDVerification
        update
        if [catch {APSGenerateControllawFiles -regenerateFiles 1 \
                       -dataDir $baseDir -directory $config \
                       -PVSuffix $PVSuffix -BPMLimit $BPMLimit -XBPMLimit $XBPMLimit \
                       -corrLimit $corrLimit -rangeErrorLimit $rangeErrorLimit \
                       -S35DCCTLimitH $S35DCCTLimitH -S35DCCTLimitV $S35DCCTLimitV \
                   } result] {
            SetBPLDVerificationStatus "$result"
            return
        }
    }
    SetBPLDVerificationStatus "Generating files done."
}

proc OrbitSetpoints {args} {
    global orbitSnapshot BPLDList firstChannelBPM secondChannelBPM
    global zeroSetpointDone
    set snapDir /home/helios/oagData/SCR/snapshots/SROrbitSetPt

    set action ""
    set statusCallback puts
    APSParseArguments {action statusCallback}
    if ![string length $action] {
        return 1
    }
    switch $action {
        save {    
            eval $statusCallback {"Taking snapshot of setpoint and offsets. (Gains are not saved!) ..."}
            if [catch {APSSaveMachine -machine SROrbitSetPt \
                         -description "Routine save: before BPLD trip limits test."} \
                  orbitSnapshot] {
                return -code error "OrbitSetpoints: $orbitSnapshot"
            }
            eval $statusCallback {"Snapshot taken."}
        }
        restore {
            if {$orbitSnapshot == ""} {
                eval $statusCallback {"No orbit snapshot file found."}
                APSInfoWindow .info -name "Restore Warning"  -infoMessage "The restore operation can't be done. The Orbit setpoints were never saved during this instance of SRBPLDVerification.\n\nIf you're in trouble look for a possible good file in SaveCompareRestore, restore it using SaveCompareRestore, then press the SAVE button in SRBPLDVerification." -modal 1
                eval $statusCallback {"No orbit snapshot file found."}
                return -code ok
            }
            eval $statusCallback {"Restoring original setpoints and offsets (Gains are not restored!) ..."}
            if [catch {exec carestore -sddsin $snapDir/$orbitSnapshot \
                     } result] {
                return -code error "OrbitSetpoints: $result"
            }
            eval $statusCallback {"Restore complete."}
        }
        zero {
            eval $statusCallback {"Zeroing setpoints and offsets and setting gains to 1..."}
            # I should also zero those for bpms involved in the
            # orbit correction in config *.BPLDVerification
            set bpmList ""
            foreach sector $BPLDList {
                lappend bpmList $firstChannelBPM($sector) $secondChannelBPM($sector)
                }
            if [catch {exec cavput -pend=10 \
                         -list=[join $bpmList ,] -list=:ms -list=:x,:y \
                         -list=:SetpointAO=0,:OffsetAO=0,:GainAO=1 \
                     } result ] {
                return -code error "OrbitSetpoints: $result"
            }
            eval $statusCallback {"checking not in cogging ..."}
            if [catch {CheckCogging} result] {
                return -code error $result
            }
            eval $statusCallback {"check corrector and SR current ..."}
            if [catch {CheckCorrectorAndSRCurrent} result] {
                return -code error $result
            }
            if !$zeroSetpointDone {
                eval $statusCallback {"Done."}
                EnableScanButtons
                set zeroSetpointDone 1
            }
            
        }
    }
}

proc CorrectorSetpoints {args} {
    global corrSnapshot
    set snapDir /home/helios/oagData/SCR/snapshots/SRCorSetpts

    set action ""
    set statusCallback puts
    APSParseArguments {action statusCallback}
    if ![string length $action] {
        return 1
    }
    switch $action {
        save {    
            eval $statusCallback {"Taking corrector setpoint snapshot..."}
            if [catch {APSSaveMachine -machine SRCorSetpts \
                         -description "Routine save: before BPLD trip limits test."} \
                  corrSnapshot] {
                return -code error "CorrectorSetpoints: $snapshot"
            }
            eval $statusCallback {"Snapshot taken."}
        }
        restore {
            if {$corrSnapshot == ""} {
                eval $statusCallback {"No corrector snapshot file found."}
                APSInfoWindow .info -name "Restore Warning"  -infoMessage "The restore operation can't be done. The corrector setpoints were never saved during this instance of SRBPLDVerification.\n\nIf you're in trouble look for a possible good file in SaveCompareRestore, restore it using SaveCompareRestore, then press the SAVE button in SRBPLDVerification."  -modal 1
                eval $statusCallback {"CorrectorSetpoints: No corrector snapshot file found."}
                return -code ok
            }
            eval $statusCallback {"Restoring original corrector setpoints..."}
            if [catch {exec carestore -sddsin $snapDir/$corrSnapshot \
                     } result] {
                return -code error "CorrectorSetpoints: $result"
            }
            eval $statusCallback {"Restore complete."}
        }
        ramp {
            if {$corrSnapshot == ""} {
                eval $statusCallback {"CorrectorSetpoints: No corrector snapshot file found."}
                APSInfoWindow .info -name "Ramp Warning"  -infoMessage "The ramp operation can't be done. The Corrector setpoints were never saved during this instance of SRBPLDVerification.\n\nIf you're in trouble look for a possible good file in SaveCompareRestore, restore it using SaveCompareRestore, then press the SAVE button in SRBPLDVerification." -modal 1
                return -code ok
            }
            eval $statusCallback {"Ramping to original corrector setpoints..."}
            set tempFile /tmp/[APSTmpString]
            if [catch {exec gzip -dcn $snapDir/$corrSnapshot > $tempFile
                APSRampToSnapshot -initDialog 1 \
                         -fileName $tempFile \
                     } result] {
                return -code error "CorrectorSetpoints: $result"
            }
            eval $statusCallback {"Ramping complete."}
        }
    }
}

proc TestLimits {args} {
    global aboveLimit tolerance timeLimit statusCallback
    
    APSParseArguments {sector IsDigital}
    if ![string length $sector] {
        eval $statusCallback {"No sector selected"}
        return 1
    }
    if {$aboveLimit<0} {
        eval $statusCallback {"Invalid value for the above limit quantity. Use a positive value like 0.1 mm."}
        return 1
    }
    if {$tolerance<0} {
        eval $statusCallback {"Invalid value for tolerance. Use a positive value like 0.02 mm."}
        return 1
    }
    if {$tolerance>$aboveLimit} {
        eval $statusCallback {"Invalid value for tolerance. The tolerance must be smaller than the steering trip excess level, otherwise the test might not be conclusive."}
        return 1
    }
    if {$timeLimit<0} {
        eval $statusCallback {"Invalid value for timeLimit"}
        return 1
    }
    APSBPLDScan -sector $sector -IsDigital $IsDigital \
      -statusCallback $statusCallback
}

proc TestAllLimits {} {
    global aboveLimit tolerance timeLimit statusCallback BPLDList IsDigitalList
    global abortBPLDTests 
    
    if {$aboveLimit<0} {
        eval $statusCallback {"Invalid value for the above-trip steering"}
        return 1
    }
    if {$tolerance<0} {
        eval $statusCallback {"Invalid value for tolerance"}
        return 1
    }
    if {$timeLimit<0} {
        eval $statusCallback {"Invalid value for timeLimit"}
        return 1
    }

    foreach sector $BPLDList IsDigital $IsDigitalList {
        if $abortBPLDTests {
            eval $statusCallback {"BPLD sequence terminated by abort button press."}
            EnableScanButtons
            set abortBPLDTests 0
            return
        }
        APSBPLDScan -sector $sector -IsDigital $IsDigital \
          -statusCallback $statusCallback
    }
}

proc MakeChannelArrays {} {
    global BPLDList BPLDConfig firstChannelBPM secondChannelBPM
    set Channel1  [lindex $BPLDConfig(Column.Channel1) 0]
    set Channel2  [lindex $BPLDConfig(Column.Channel2) 0]
    foreach sector $BPLDList chan1 $Channel1 chan2 $Channel2 {
        set sector1 [expr $sector + 1]
        set firstChannelBPM($sector) S${sector}B:$chan1
        set secondChannelBPM($sector) S${sector1}A:$chan2
    }
}

proc CheckCogging {args} {
    #these cogging pvs no longer exist, since all rf bpms are FPGA now, 8/12/2014; this procedure is obselete
    return
    set cogpv1 [exec cavget -list=S -rang=begin=1,end=35,interval=2 -list=Bpm:TimingModeMO  -dry]
    set cogpv2 [exec cavget -list=S -rang=begin=36,end=40 -list=Bpm:TimingModeMO  -dry]
    set pvlist [concat $cogpv1 $cogpv2]
    if [catch {exec cavget -list=[join $pvlist ,] -pend=30 -num} valueList] {
        return -code error $valueList
    }
    set badpvList ""
    foreach pv $pvlist val $valueList {
        if {$val!=0} {
            lappend badpvList $pv
        }
    }
    if [llength $badpvList] {
        return -code error "These cogging pvs ([join $badpvList ,]) are in cogging or the IOC has problem!"
    }
}

proc CheckCorrectorAndSRCurrent {args} {
    if [catch {exec cavget -list=S -rang=begin=1,end=40 -list=A:,B: -list=H2:,V2: \
                 -list=CurrentAI -pend=30 -label} result ] {
        return -code error $result
    }
    set badPVs ""
    set badIOCs ""
    for {set i 0} {$i<40} {incr i} {
        set pv [lindex $result [expr 2*$i]]
        set val [lindex $result [expr 2*$i+1]]
        if {$val=="?"} {
         lappend badIOCs $pv
        } else {
            if {[expr abs($val)]>100} {
                lappend badPVs "$pv"
            }
        }
    }
    if [llength $badIOCs] {
        return -code error "Unable to get values of [join $badIOCs ,]"
    }
    if [llength $badPVs] {
        set answer [tk_dialog .dialog "Warning" "Error,following the current of following correctors are more than 100 A:\n[join $badPVs ,]\nChoose one of the following:\n\n" \
                      warning -1 Abort Continue-at-your-own-risk]
        case $answer {
            0 {
                return -code error "Error: the current of following correctors: [join $badPVs ,] are more than 100 A."
            }
            1 {
                set badPVs ""
            }
        }
    }
    if [catch {exec cavget -list=S35DCCT:currentCC -pend=30} current] {
        return -code error $current
    }
    if {$current<15} {
        set answer [tk_dialog .dialog "Warning" "Waring,the storage ring current is less than 15 mA\nChoose one of the following:\n\n" \
                      warning -1 Abort Continue-at-your-own-risk]
        case $answer {
            0 {
                return -code error "Error: the storage ring current is less than 15 mA!"
            }
            1 {
                return
            }
        }
    }
}


set BPLDFile /home/helios/oagData/sr/BPLDs/sectors.sdds
sdds load $BPLDFile BPLDConfig
# take data from first and only page
set BPLDList [lindex $BPLDConfig(Column.Sector) 0]
set IsDigitalList [lindex $BPLDConfig(Column.IsDigital) 0]

set aboveLimit 0.1
set tolerance 0.020
set timeLimit 60
set reportFile /tmp/[APSTmpString]
set writeReport 0
set abortBPLDTests 0
set statusCallback SetBPLDVerificationStatus
set verificationType pendingTrips
set corrSnapshot ""
set orbitSnapshot ""

MakeSectorsTable .sectorsTable -parent .userFrame
MakeOptionWidget .options -parent .userFrame
MakeActionWidget .ops -parent .userFrame
APSBPLDglobals
MakeChannelArrays


set zeroSetpointDone 0
DisableScanButtons

# intruction to save configurations and set setpoints and offsets to zero.
APSInfoWindow .info -name "Operational Recommendations" -infoMessage "It is highly recommended to save the orbit setpoints and offset and to save the corrector setpoints (use buttons at bottom of the main screen), so that the SR configuration can be quickly restored for re-injection after a mps dump test (or for any other interruption).\n\nAs a precondition to start the limits test:\nPress setpoints and offset ZERO button. ZERO button also does:\n1. check that we are not in cogging.\n2. check that none of H2 or V2 correctors are more than 100 A in absolute value.\n3. check that DCCT > 15mA. \n4. Sets the bpms gains to 1. (Note that the original gains will have to be restored manually from an SCR saveset. \nThis action will activate the scan buttons.\n\nAlso a check of the steering configuration is recommended. Press \"CHECK STEERING CONFIGURATION...\" to bring up the orbit correction configuration application.\n\nPress OK button to continue." -modal 1

