
set apsDebugDCPS 0

#
# APSCheckStandardizeFile <filename>
#

proc APSCheckStandardizeFileHelp { } {
    global apsDebugDCPS
    return "APSCheckStandardizeFile <filename>"
}

proc APSCheckStandardizeFile { filename } {
    global apsDebugDCPS
    if {[string length $filename]==0 || ![file exists $filename]} { 
        return [APSErrorReturn 0 "$filename blank or nonexistent"] }
    set check [exec sddscheck $filename]
    if {$check!="ok"} { 
        return [APSErrorReturn 0 "$filename is not an SDDS file"] }

    lappend columnsExpected ControlName ControlType From To Minutes Seconds NumCycles \
      Approach Finish

    set columnsPresent [exec sddsquery -column $filename ]
    foreach expected $columnsExpected {
        if {[lsearch -exact $columnsPresent $expected]==-1} { 
            return [APSErrorReturn 0 "$filename is not a standardize file"] }
    }
    return 1
}


proc APSCheckDegaussFileHelp { } {
    global apsDebugDCPS
    return "APSCheckDegaussFile <filename>"
}

#
# APSCheckDegaussFile <filename>
#

proc APSCheckDegaussFile { filename } {
    global apsDebugDCPS
    if {[string length $filename]==0 || ![file exists $filename]} {
        return [APSErrorReturn 0 "$filename blank or nonexistent"] }
    set check [exec sddscheck $filename]
    if {$check!="ok"} {
        return [APSErrorReturn 0 "$filename is not an SDDS file"] }

    lappend columnsExpected ControlName ControlType DecayMinutes DecaySeconds MaxCurrent \
      NumDecay PeriodSeconds

    set columnsPresent [exec sddsquery -column $filename ]
    foreach expected $columnsExpected {
        if {[lsearch -exact $columnsPresent $expected]==-1} { 
            return [APSErrorReturn 0 "$filename is not a degauss file"] }
    }
    return 1
}

proc APSSrTurnOnDcpsHelp {} {
    return "APSSrTurnOnDcps -family {Q S H V QS BM MT QS4 C:BM C:H C:V} \
 \[-sectors <sector-list>\] \[-pause <millsec>\] \[-tries <number>\]"
}

#No longer used
proc APSSrTurnOnDcps {args} {
    global apsDebugDCPS
    set family ""
    set sectors ""
    set statusCallback ""
    set tries 1
    set pause 5000
    APSStrictParseArguments {family sectors statusCallback tries pause}

    if {([string compare $family "C:BM"] == 0) || 
        ([string compare $family "C:H"] == 0) || 
        ([string compare $family "C:V"] == 0)} {
        if [llength $sectors]==0 {
            for {set i 1} {$i <= 40} {incr i} {
                append sectors "$i "
            }
        }
        set sectorsList $sectors
        if {[catch {exec sdds2stream \
                      -col=Sector,CUflag,CUdipoleExists /home/helios/oagData/sr/XAXSTF/sectors.sdds} results]} {
            return -code error  "APSSrDcpsAction: $results"
        } else {
            set sectorsList ""
            foreach "sector flag bmFlag" $results {
                if {([string compare $family "C:BM"] == 0) && ($bmFlag == 0)} {
                    continue
                }
                if {$flag} {
                    if {[lsearch -exact $sectors $sector] != -1} {
                        lappend sectorsList $sector
                    }
                }
            }
            if {![llength $sectorsList]} {
                return
            }
        }
        set sectors $sectorsList
    }
    
    if [llength $sectors]==0 {
        lappend lists -list=S -range=begin=1,end=40
    } else {
        lappend lists -list=S -list=[join $sectors ,]
    }

    switch $family {
        "QS" { 
            return [APSSrSkewAction -action on -sectors $sectors -pause $pause]
        }
        "BM" { 
            set lists -list=S:BM
        }
        "C:BM"  { 
            lappend lists -list=C:BM
        }
        "Q"  { 
            lappend lists -list=A:Q,B:Q -range=begin=1,end=5
        }
        "C:V"  { 
            lappend lists -list=C:V1
        }
        "C:H"  { 
            lappend lists -list=C:H1
        }
        "V"  { 
            lappend lists -list=A:V,B:V -range=begin=1,end=4
        }
        "H"  { 
            lappend lists -list=A:H,B:H -range=begin=1,end=4
        }
        "S"  { 
            lappend lists -list=A:S1,A:S2,A:S3,A:S4,B:S3,B:S2,B:S1
        }
        "MT" { 
            lappend lists -list=A:MT,B:MT
        }
        "QS4" {
            lappend lists -list=A:QS4
        }
        default { 
            return -code error  "APSSrTurnOnDcps: Invalid family $family."  
        }
    }
    
    while {$tries} {
        incr tries -1
        if [catch {eval APScavget $lists -list=:StatusCALC -pend=30 -label} result] {
            return -code error "APSSrTurnOnDcps: $result"
        }
        set statusList [APSSearchAssociateListForValue -list $result -notvalue 0]
        if ![llength $statusList] {
            return 
        }
        regsub -all {:StatusCALC} $statusList {} statusList
        if [catch {eval APScavput -pend=10 -blunder=silent -list=[join $statusList ,] -list=:ResetSEQ=1} result] {
            return -code error "APSSrTurnOnDcps: $result"
        }
        if $tries {
            after $pause
        }
    }
}

proc APSSrDcpsActionHelp {} {
    global apsDebugDCPS
    return "APSSrDcpsAction -family {Q S H V QS BM MT QS4 C:BM C:H C:V} -action {on off configure condition}\
 \[-value <value>\] \[-configFile <file>\] \[-sectors <sector-list>\] \[-pause <millsec>\]"
}

#No longer used
proc APSSrDcpsAction {args} {
    global apsDebugDCPS
    set family ""
    set action ""
    set configFile ""
    APSParseArguments {family action configFile}

    if {$family=="" || $action==""} {
        return -code error  "-family and -action must be supplied."
    }
    if {$action=="on"} {
        return [eval APSSrTurnOnDcps -family $family $args]
    }
    if {$action=="validateconnections"} {
        return -code error "Validate Connections is only implemented for the APSU"
    }

    if [lsearch -exact [list Q S BM H V QS QS4 MT C:BM C:H C:V] $family]==-1 {
        return -code error  "unknown family: $family"
    }

    if [lsearch -exact [list configure standardize degauss] $action]!=-1 {
        if {$configFile==""} { 
            return -code error  "-configFile must be given."
        }
        switch $family {
            Q -
            S -
            BM -
            C:BM {
                if {![APSCheckStandardizeFile $configFile]} {
                    return -code error  "$configFile nonexistent or invalid."
                }
            }
            H -
            V -
            QS -
            C:H -
            C:V {
                if {![APSCheckDegaussFile $configFile]} {
                    return -code error  "$configFile nonexistent or invalid."
                }
            }
            default {
                return -code error  "Can't condition family $family" 
            }
        }
    }

    if {($family=="QS") && ($action != "configure")} {
        return [eval APSSrSkewAction -action $action -configFile $configFile $args]
    }
    
    set value ""
    set sectors ""
    set statusCallback ""
    set pause 500
    APSParseArguments {value sectors statusCallback pause}
    APSClearOptions
    
    if {([string compare $family "C:BM"] == 0) || 
        ([string compare $family "C:H"] == 0) || 
        ([string compare $family "C:V"] == 0)} {
        if [llength $sectors]==0 {
            for {set i 1} {$i <= 40} {incr i} {
                append sectors "$i "
            }
        }
        set sectorsList $sectors
        if {[catch {exec sdds2stream \
                      -col=Sector,CUflag,CUdipoleExists /home/helios/oagData/sr/XAXSTF/sectors.sdds} results]} {
            return -code error  "APSSrDcpsAction: $results"
        } else {
            set sectorsList ""
            foreach "sector flag bmFlag" $results {
                if {[string compare $family "C:BM"] == 0} {
                    if {$bmFlag} {
                        if {[lsearch -exact $sectors $sector] != -1} {
                            lappend sectorsList $sector
                        }
                    }
                } else {
                    if {$flag} {
                        if {[lsearch -exact $sectors $sector] != -1} {
                            lappend sectorsList $sector
                        }
                    }
                }
            }
            if {![llength $sectorsList]} {
                return
            }
        }
        set sectors $sectorsList
    }
    lappend command -pend=15 -list=S
    if [llength $sectors]==0 {
        lappend command -range=begin=1,end=40
    } else {
        lappend command -list=[join $sectors ,]
    }

    set matchString \[AB\]:$family\[0-9\]*
    set configCommand standardize
    set prefix ""
    switch $family {
        "QS" { 
            #return -code error  "APSSrDcpsAction: invalid family in switch statement: QS"
            set matchString \[AB\]:QS
            set configCommand degauss
        }
        "BM" { 
            set matchString S:BM*
            set command ""
            lappend command -pend=10 -list=S:BM
        }
        "C:BM"  { 
            set matchString C:BM*
            lappend command -pend=10 -list=C:BM
        }
        "Q"  { 
            lappend command -list=A:Q,B:Q -range=begin=1,end=5
        }
        "C:V"  { 
            set matchString C:V1*
            lappend command -pend=10 -list=C:V1
            set configCommand degauss
        }
        "C:H"  { 
            set matchString C:H1*
            lappend command -pend=10 -list=C:H1
            set configCommand degauss
        }
        "V"  { 
            lappend command -list=A:V,B:V -range=begin=1,end=4 
            set configCommand degauss
        }
        "H"  { 
            lappend command -list=A:H,B:H -range=begin=1,end=4 
            set configCommand degauss
        }
        "S"  { 
            lappend command -list=A:S1,A:S2,A:S3,A:S4,B:S3,B:S2,B:S1
        }
        "MT" { 
            lappend command -list=A:MT,B:MT
        }
        "QS4" {
            #QS4 replaced A:V4 but B:V4 is still there
            lappend command -list=A:QS4
        }
        default { 
            return -code error  "Invalid family $family."  
        }
    }

    switch -exact $action {
        set {
            if {[string compare $family "H"]==0 || [string compare $family "V"]==0} {
                set prefix "-list=,SFB:"
            }
            lappend command -list=:CurrentAO=$value
        }
        setTol {
            lappend command -list=:ToleranceCALC.C=$value
        }
        on { 
            lappend command -list=:ResetSEQ=1
        }
        off { 
            if {[string compare $family "C:BM"]==0} {
                lappend command -list=:OffSEQ.PROC=1
            } elseif {[string compare $family "BM"]==0} {
                lappend command -list=:OffBO=1
            } else {
                lappend command -list=:OnBO=0
            }
        }
        forcecondition -
        forcestandardize -
        forcedegauss { 
            lappend command -list=:StandardizeSUB.PROC=1
        }
        condition -
        standardize -
        degauss { 
            switch $family {
                Q -
                S -
                BM -
                C:BM {
                    set checkcommand "$command -list=:CnditValCC,:StandardizeSUB.G,:StandardizeSUB.H,:CurrentAO -label"
                    set command ""
                    set command2 ""
                    set command3 ""
                    if [catch {eval exec cavget $checkcommand} result] {
                        return -code error  "APSSrDcpsAction1: $result"
                    }
                    foreach "cnditName cnditVal finishName finishVal approachName approachVal currentName currentVal" $result {
                        if {($cnditVal == 1) && ((($approachVal == 0) && ($finishVal >= $currentVal)) || 
                                                 (($approachVal == 1) && ($finishVal <= $currentVal)))} {
                            #If no conditioning is needed just set the final value. This way
                            #the end result will be exactly the same as if conditioning was done.
                            lappend command2 ${currentName}=$finishVal
                            #if {[catch {APScavput -pend=15 -blunderAhead=silently -list=${currentName}=$finishVal} result]} {
                            #    return -code error "APSSrDcpsAction2: $result"
                            #}
                        } elseif {$cnditVal == 1} {
                            #set cycles to zero
                            set basename [string range $cnditName 0 [expr {[string last : $cnditName] - 1}]]
                            lappend command3 ${basename}:StandardizeSUB.F=0
                            #if {[catch {exec cavput -pend=15 -blunderAhead=silently -list=${basename}:StandardizeSUB.F=0} result]} {
                            #   return -code error "APSSrDcpsAction: $result" 
                            #}
                            lappend command "[string range $cnditName 0 [expr {[string last : $cnditName] - 1}]]"
                        } else {
                            lappend command "[string range $cnditName 0 [expr {[string last : $cnditName] - 1}]]"
                        }
                    }
                    if {[llength $command2]} {
                        if {[catch {exec cavput -pend=15 -blunderAhead=silently -list=[join $command2 ,]} result]} {
                            return -code error "APSSrDcpsAction: $result"
                        }
                    }
                    if {[llength $command3]} {
                        if {[catch {exec cavput -pend=15 -blunderAhead=silently -list=[join $command3 ,]} result]} {
                            return -code error "APSSrDcpsAction: $result"
                        }
                        after 1000
                    }
                    if {[llength $command]} {
                        set command "-pend=15 -blunderAhead=silently -list=[join $command ,]"
                    } else {
                        return -code ok
                    }
                }
            }

            lappend command -list=:StandardizeSUB.PROC=1
        }
        stopcond {
            lappend command -blunderAhead=silently -list=:StandardizeSUB.PROC=0
        }
        setcycles {
            lappend command -blunderAhead=silently -list=:StandardizeSUB.F=$value
        }    
        configure {
            set configFile1 [APSTmpDir]/[APSTmpString]
            if [string compare $family BM]==0 {
                exec sddsprocess $configFile $configFile1 \
                  "-match=column,ControlName=S:BM*" -nowarnings
                if {[exec sdds2stream -rows $configFile1]=="0 rows"} {
                    return -code error  "No configuration data for S:BM"
                }
                if {$statusCallback!=""} {
                    $statusCallback "Configuring S:BM"
                }
                if [catch {exec $configCommand -configure $configFile1} result] {
                    return -code error $result
                }
            } else {
                foreach sector [split [string trim $sectors]] {
                    if ![string length $sector] continue
                    exec sddsprocess $configFile $configFile1 \
                      "-match=column,ControlName=S${sector}$matchString" -nowarnings
                    if {[exec sdds2stream -rows $configFile1]=="0 rows"} {
                        if {$family == "QS"} {
                            continue
                        }
                        return -code error  "No configuration data for S${sector}:$family"
                    }
                    if {$statusCallback!=""} {
                        $statusCallback "Configuring S${sector} family $family"
                    }
                    if [catch {exec $configCommand -configure $configFile1} result] {
                        if {$family != "QS"} {
                            return -code error $result
                        }
                    }
                }
            }
            return -code ok
        }
    }
    if $apsDebugDCPS {
        puts stderr "$command"
        return -code ok
    } 
    #    puts "\n\nexec cavput $prefix $command"
    if [catch {eval exec cavput $prefix $command} result] {
        return -code error  "APSSrDcpsAction3: $result"
    }
    if {0} {
        if {$family=="QS4"} {
            #need do the same thing for B:V4 at the same sectors
            set command [regsub -all {A:QS4} $command "B:V4"]
            if [catch {eval exec cavput -list=SFB: $command } result] {
                return -code error  "APSSrDcpsAction4: $result"
            }
        }
    }
    return -code ok
}

proc APSSetSrDcpsFamilyHelp {} {
    global apsDebugDCPS
    return "APSSetSrDcpsFamily -family {Q S QS BM H V MT QS4 C:BM C:H C:V} -value <value> \[-sectors <sectors>\] \[-pause <millsec>\]\n\
Default is all sectors."
}

proc APSSetSrDcpsFamily {args} {
    return [eval APSSrDcpsAction -action set $args]
}


proc APSSrSkewAction {args} {
    global apsDebugDCPS
    #        puts -nonewline "APSSrSkewAction: "
    #        foreach arg $args {puts -nonewline "$arg "}
    #        puts ""

    global apsSrSkewName
    if {![info exists apsSrSkewName]} { APSMakeSrSkewNames }

    set action ""
    set value ""
    set configFile ""
    set sectors ""
    set pause 250
    APSStrictParseArguments {action value configFile sectors pause}
    APSClearOptions

    set skewList ""
    if [llength $sectors]==0 {
        for {set sector 1} {$sector<40} {incr sector 2} {
            lappend skewList $apsSrSkewName($sector)
            lappend sectorList $sector
        }
    } else {
        foreach sector $sectors {
            if {$sector>0 && $sector<40 && [expr $sector%2]} {
                lappend skewList $apsSrSkewName($sector)
                lappend sectorList $sector
            }
        }
    }       
    if {![llength $sectorList]} { 
        return -code error  "No valid sectors given for skew quads"
    }

    lappend command APScavput -pend=15 -blunderAhead=silently -list=[join $skewList ,]
    switch $action {
        set {
            lappend command -list=:CurrentAO=$value
        }
        setTol {
            lappend command -list=:ToleranceCALC.C=$value
        }
        on { 
            lappend command -list=:ResetSEQ=1
        }
        off { 
            lappend command -list=:OnBO=0
        }
        forcecondition -
        forcestandardize -
        forcedegauss - 
        condition -
        standardize -
        degauss { 
            lappend command -list=:StandardizeSUB.PROC=1
        }
        stopcond {
            lappend command -list=:StandardizeSUB.PROC=0
        }
        configure {
            if {$configFile==""} { 
                return -code error  "No configuration file given for skew quads"
            }
        }
        default { 
            return -code error  "Invalid skew quad action"
        }
    }
    if $apsDebugDCPS {
        puts stderr "$command"
        return -code ok
    }
    if [catch $command result] {
        return -code error  "APSSrDcpsAction: $result"
    }
    return -code ok 
}

proc APSMakeSrSkewNames {} {
    global apsDebugDCPS
    global apsSrSkewName
    for {set sector 1} {$sector<41} {incr sector} {
        set apsSrSkewName($sector) ""
    }
    foreach sector {3 7 11 15 19 23 27 31 35 39} {
        set apsSrSkewName($sector) "S${sector}A:QS"
    }
    foreach sector {1 5  9 13 17 21 25 29 33 37} {
        set apsSrSkewName($sector) "S${sector}B:QS"
    }
}


proc APSSrRpsAction {args} {
    #This uses the older style names and not the newer *PSRAW* style
    #The PSRAW style PVs are aliaes to the older PVs, so it doen't really matter.
    global apsDebugDCPS
    set action ""
    set group ""
    set sectors ""
    APSStrictParseArguments {action group sectors}

    if [string compare $action ""]==0 {
        return -code error  "No action supplied for RPS."
    }
    if [lsearch -exact [list on off] $action]==-1 {
        return -code error  "Unknown raw PS action: $action"
    }
    if [lsearch -exact [list R1 R2 R3 R4 R] $group]==-1 {
        return -code error  "No valid group supplied for RPS."
    }
    
    if [llength $sectors]==0 {
        set sectorList {}
        for {set sector 1} {$sector<40} {incr sector 2} {
            lappend sectorList $sector
        }
    } else {
        foreach sector $sectors {
            if {$sector>0 && $sector<40} {
                lappend sectorList $sector
            }
        }
    }
    if {![llength $sectorList]} { 
        return -code error  "No valid sectors given for RPS"
    }
    
    set prefixList {}
    foreach sector $sectorList {
        if {$sector<0 || $sector>40 || [expr $sector%2]==0} { 
            continue
        }
        set other [expr $sector-1]
        if {$other==0} { set other 40 }
        lappend prefixList S${other}:${sector}:
    }
    
    lappend command APScavput -blunderAhead=silently -pend=15 -list=[join $prefixList ,]
    
    switch $group {
        R1 -
        R2 -
        R3 -
        R4 {
            lappend command -list=$group
        }
        R {
            lappend command -list=R1,R2,R3,R4
        }
    }

    switch $action {
        on {
            #lappend command -list=:ResetSEQ=1,:ONSEQ=1
            lappend command -list=:ResetSEQ=1
        }
        off {
            #lappend command -list=:OffBO=1,:OFFSEQ=1
            lappend command -list=:OffBO=1
        }
    }
    if $apsDebugDCPS {
        puts stderr "$command"
        return -code ok
    }
    if [catch $command result] {
        return -code error  "APSSrRpsAction: $result"
    }
    return -code ok
}


proc SRTurnOnSectorHelp {} {
    return "SRTurnOnSector -family {Q S H V} -sector <number> \[-pause <millisec>\] \[-repeats <integer>\] \[-statusCallback <procName>\]"
}

# this routine is basically obsolete
proc SRTurnOnSector {args} {
    set family "?"
    set sector 0
    set pause 10000
    set repeats 1
    set statusCallback ""
    if [APSStrictParseArguments {family sector pause repeats statusCallback}]==-1 {
        return -code error  "Bad arguments to SRTurnOnSector"
    }
    if [lsearch -exact {Q S H V} $family]==-1 {
        return -code error  "SRTurnOnSector: Unknown family: $family"
    }
    if {$sector<0 || $sector>40} {
        return -code error  "SRTurnOnSector: Bad sector: $sector"
    }
    if $repeats<=0 {
        return -code error  "SRTurnOnSector: Bad repeats: $repeats"
    }
    if $pause<0 {
        return -code error  "SRTurnOnSector: Bad pause: $pause"
    }
    if $pause<1000 {
        set pause 1000
        if [string length $statusCallback] {
            $statusCallback "Pause too small--set to 1000 milliseconds"
        }
    }
    if [catch {eval APSSrTurnOnDcps -family $family -sectors $sector -pause $pause -tries $repeats \
                 -statusCallback $statusCallback} result] {
        return -code error "SRTurnOnSector: $result"
    }
}

proc MakeSectorList {SectorSelectionList} {
    global apsDebugDCPS
    array set SectorSelection $SectorSelectionList
    set sectors {}
    foreach sector [array names SectorSelection] {
        if {$sector>40 || $sector<0} { continue }
        if {$SectorSelection($sector)} {
            lappend sectors $sector
        }
    }
    return [lsort -integer $sectors]
}

##### APSU STUFF ######

proc APSUSrDcpsGetValidNames {args} {
    set arrayName validNames
    set families ""
    set sectors ""
    set filter "*"
    APSStrictParseArguments {families sectors arrayName filter}

    upvar 1 $arrayName validNames

    if {[llength $sectors] == 0} {
        for {set i 1} {$i <= 40} {incr i} {
            lappend sectors [format %02d $i]
        }
    } else {
        foreach s $sectors {
            lappend ssectors [format %02d $s]
        }
        set sectors $ssectors
    }

    set biPolarCategories ""
    set uniPolarCategories ""
    set uniPolarCategoriesSM ""
    foreach family $families {
        switch $family {
            "H"  { 
                append biPolarCategories "A:H1 A:H7 B:H1 B:H7 "
            }
            "Hmod"  { 
                append biPolarCategories "A:H1 B:H1 "
            }
            "V"  { 
                append biPolarCategories "A:V1 A:V7 A:V8 B:V1 B:V7 B:V8 "
            }
            "Vmod"  { 
                append biPolarCategories "A:V1 B:V1 "
            }
            "CH"  { 
                append biPolarCategories "C:H2 "
            }
            "CV"  { 
                append biPolarCategories "C:V2 "
            }
            "FH"  { 
                append biPolarCategories "A:FH1 A:FH2 B:FH1 B:FH2 "
            }
            "FV"  { 
                append biPolarCategories "A:FV1 A:FV2 B:FV1 B:FV2 "
            }
            "SQ"  { 
                append biPolarCategories "A:SQ1 A:SQ2 B:SQ1 B:SQ2 "
            }
            "QT"  { 
                append biPolarCategories "A:Q4T A:Q5T A:Q8T B:Q4T B:Q5T B:Q8T "
            }
            "MT"  { 
                append biPolarCategories "A:M3T A:M4T B:M3T "
            }
            "CM"  { 
                append biPolarCategories "C:M1 C:M2 "
            }
            "M"  { 
                append uniPolarCategories "A:M3 A:M4 B:M3 "
            }
            "Q"  { 
                append uniPolarCategories "A:Q1 A:Q2 A:Q3 A:Q6 B:Q1 B:Q2 B:Q3 B:Q6  "
            }
            "Q7"  { 
                append uniPolarCategories "A:Q7 B:Q7  "
            }
            "QD"  { 
                append uniPolarCategories "A:Q4 A:Q5 A:Q8 B:Q4 B:Q5 B:Q8 "
            }
            "S"  { 
                append uniPolarCategories "A:S1 A:S2 A:S3 B:S1 B:S2 B:S3 "
            }
            "SM1"  { 
                append uniPolarCategoriesSM "S:M1 "
            }
            "SM2"  { 
                append uniPolarCategoriesSM "S:M2 "
            }
            default {
                return -code error "Invalid family $family"
            }
        }
    }

    set BiPolarResults ""
    if {[llength $biPolarCategories]} {
        if {[catch {exec cavget -pend=2 -label -list=S -list=[join ${sectors} ,] -list=[join $biPolarCategories ,] -list=:StandardizeC} BiPolarResults]} {
            return -code error "$BiPolarResults"
        }
    }

    set UniPolarResults ""
    if {[llength $uniPolarCategories]} {
        if {[catch {exec cavget -pend=2 -label -list=S -list=[join ${sectors} ,] -list=[join $uniPolarCategories ,] -list=:StandardizeC} UniPolarResults]} {
            return -code error "$UniPolarResults"
        }
    }

    set UniPolarResultsSM ""
    if {[llength $uniPolarCategoriesSM]} {
        if {[catch {exec cavget -pend=2 -label -list=[join $uniPolarCategoriesSM ,] -list=:StandardizeC} UniPolarResultsSM]} {
            return -code error "$UniPolarResultsSM"
        }
    }

    set lines [split $BiPolarResults \n]
    foreach line $lines {
        if {([lindex $line 1] != "?") && ([string match -nocase "*${filter}*" [lindex $line 0]])} {
            lappend validNames(bipolar) [string range [lindex $line 0] 0 end-13]
        }
    }
    set validNames(bipolar) [lsort $validNames(bipolar)]

    set lines [split $UniPolarResults \n]
    foreach line $lines {
        if {([lindex $line 1] != "?") && ([string match -nocase "*${filter}*" [lindex $line 0]])} {
            lappend validNames(unipolar) [string range [lindex $line 0] 0 end-13]
        }
    }
    set validNames(unipolar) [lsort $validNames(unipolar)]

    set lines [split $UniPolarResultsSM \n]
    foreach line $lines {
        if {([lindex $line 1] != "?") && ([string match -nocase "*${filter}*" [lindex $line 0]])} {
            lappend validNames(unipolar) [string range [lindex $line 0] 0 end-13]
        }
    }
    set validNames(unipolar) [lsort $validNames(unipolar)]
}

proc APSUSrValidateConnectionsDcps {args} {
    set bipolar ""
    set unipolar ""
    set statusCallback ""
    set families ""
    APSStrictParseArguments {bipolar unipolar statusCallback families}
    set allNames [lsort "$bipolar $unipolar"]

    foreach name $bipolar {
        if {[lsearch -glob $name "S???:FH?"] != -1} {
            lappend biSupplies(FH) $name
        } elseif {[lsearch -glob $name "S???:FV?"] != -1} {
            lappend biSupplies(FV) $name
        } elseif {[lsearch -glob $name "S???:SQ?"] != -1} {
            lappend biSupplies(SQ) $name
        } elseif {[lsearch -glob $name "S???:Q?T"] != -1} {
            lappend biSupplies(QT) $name
        } elseif {[lsearch -glob $name "S???:M?T"] != -1} {
            lappend biSupplies(MT) $name
        } elseif {[lsearch -glob $name "S???:Q?"] != -1} {
            lappend biSupplies(Q) $name
        } elseif {[lsearch -glob $name "S???:S?"] != -1} {
            lappend biSupplies(S) $name
        } elseif {[lsearch -glob $name "S???:M?"] != -1} {
            lappend biSupplies(M) $name
        } elseif {[lsearch -glob $name "S???:H?"] != -1} {
            lappend biSupplies(H) $name
        } elseif {[lsearch -glob $name "S???:V?"] != -1} {
            lappend biSupplies(V) $name
        }
    }
    foreach name $unipolar {
        if {[lsearch -glob $name "S???:FH?"] != -1} {
            lappend uniSupplies(FH) $name
        } elseif {[lsearch -glob $name "S???:FV?"] != -1} {
            lappend uniSupplies(FV) $name
        } elseif {[lsearch -glob $name "S???:SQ?"] != -1} {
            lappend uniSupplies(SQ) $name
        } elseif {[lsearch -glob $name "S???:Q?T"] != -1} {
            lappend uniSupplies(QT) $name
        } elseif {[lsearch -glob $name "S???:M?T"] != -1} {
            lappend uniSupplies(MT) $name
        } elseif {[lsearch -glob $name "S???:Q?"] != -1} {
            lappend uniSupplies(Q) $name
        } elseif {[lsearch -glob $name "S???:S?"] != -1} {
            lappend uniSupplies(S) $name
        } elseif {[lsearch -glob $name "S???:M?"] != -1} {
            lappend uniSupplies(M) $name
        } elseif {[lsearch -glob $name "S???:H?"] != -1} {
            lappend uniSupplies(H) $name
        } elseif {[lsearch -glob $name "S???:V?"] != -1} {
            lappend uniSupplies(V) $name
        }
    }
    set count(FH) 5
    set count(FV) 5
    set count(SQ) 5
    set count(QT) 6
    set count(MT) 3
    set count(Q) 16
    set count(S) 6
    set count(M) 5
    set count(H) 5
    set count(V) 7
    
    foreach family $families {
        if {[info exists biSupplies($family)]} {
            append supplies($family) "$biSupplies($family) "
        }
        if {[info exists uniSupplies($family)]} {
            append supplies($family) "$uniSupplies($family) "
        }
    }

    for {set test 1} {$test <= 2} {incr test} {
        $statusCallback "Running validation test $test of 2"
        if {$test == 1} {
            set biBaseValue 0
            set uniBaseValue 5
        } elseif {$test == 2} {
            set biBaseValue 0.5
            set uniBaseValue 5.5
        }
        foreach family $families {
            set nameValuePair ""
            if {[catch {APScavget -pend=15 -list=[join $supplies($family) ,] -list=:PS:SetCurrentC -label} nameValueList]} {
                return -code error "APSUSrValidateConnectionsDcps: $nameValueList"
            }
            if {[catch {APScavget -pend=15 -list=[join $supplies($family) ,] -list=:PS:SetCurrentC.HOPR} hoprList]} {
                return -code error "APSUSrValidateConnectionsDcps: $hoprList"
            }
            if {[catch {APScavget -pend=15 -list=[join $supplies($family) ,] -list=:PS:SetCurrentC.LOPR} loprList]} {
                return -code error "APSUSrValidateConnectionsDcps: $loprList"
            }
            if {($family == "M") || ($family == "Q") || ($family == "S")} {
                set baseValue $uniBaseValue
            } else {
                set baseValue $biBaseValue
            }
            set setValue $baseValue
            foreach "name value" $nameValueList lopr $loprList hopr $hoprList supply $supplies($family) {
                if {$setValue > $hopr} {
                    set setValue $baseValue
                }
                if {$setValue < $lopr} {
                    set setValue [expr $lopr + $baseValue]
                }
                set initValue($supply) $setValue
                lappend nameValuePair "${name}=${setValue}"
                set setValue [expr $setValue + 2]
                if {$setValue >= [expr $count($family) * 2]} {
                    set setValue $baseValue
                }
            }
            $statusCallback "Setting test $test values for $family power supplies"
            if {[catch {APScavput -pend=15 -list=[join $nameValuePair ,] -printError} results]} {
                $statusCallback "Error setting test $test values: $results"
                return -code error "APSUSrValidateConnectionsDcps: $results"
            }
        }
        $statusCallback "Waiting for power supplies to reach test $test setpoints"
        for {set step 1} {$step <= 2} {incr step} {
            APSWaitWithUpdate -waitSeconds 5
            set pass 1
            set suspectNames ""
            foreach family $families {
                if {[catch {APScavget -pend=15 -list=[join $supplies($family) ,] -list=:PS:MeasCurrentM,:DCCT:CurrentM  -label} nameValueList]} {
                    return -code error "APSUSrValidateConnectionsDcps: $nameValueList"
                }
                if {[info exists biSupplies($family)]} {
                    if {[catch {APScavget -pend=15 -list=[join $biSupplies($family) ,] -list=:PS:DacCurrentM  -label} nameValueList2]} {
                        return -code error "APSUSrValidateConnectionsDcps: $nameValueList2"
                    }
                }
                if {[info exists uniSupplies($family)]} {
                    if {[catch {APScavget -pend=15 -list=[join $uniSupplies($family) ,] -list=:DCCT:SlowCurrentM  -label} nameValueList3]} {
                        return -code error "APSUSrValidateConnectionsDcps: $nameValueList4"
                    }
                }
                foreach "name value name2 value2" $nameValueList supply $supplies($family) {
                    set diff [expr abs($initValue($supply) - $value)]
                    set diff2 [expr abs($initValue($supply) - $value2)]
                    if {($diff > .1) || ($diff2 > .1)} {
                        set pass 0
                        lappend suspectNames $supply
                    }
                }
                if {[info exists biSupplies($family)]} {
                    foreach "name value" $nameValueList2 {
                        set supply [join [lrange [split $name :] 0 end-2] :]
                        set diff [expr abs($initValue($supply) - $value)]
                        if {$diff > .1} {
                            set pass 0 
                            lappend suspectNames $supply
                        }
                    }
                }
                if {[info exists uniSupplies($family)]} {
                    foreach "name value" $nameValueList3 {
                        set supply [join [lrange [split $name :] 0 end-2] :]
                        set diff [expr abs($initValue($supply) - $value)]
                        if {$diff > .1} {
                            set pass 0 
                            lappend suspectNames $supply
                        }
                    }
                }
            }
            if {$pass} {
                break
            }
            set suspectNames [lsort -unique $suspectNames]
            if {$step == 10} {
                $statusCallback "Readback values do not match setpoint values for [join $suspectNames ,]"
                return -code error "APSUSrValidateConnectionsDcps: Readback values do not match setpoint values"
            }
            $statusCallback "Continue waiting for [llength $suspectNames] power supplies (step $step of 10)"
        }
        $statusCallback "Waiting for readback values to reach setpoint values"
    }
    $statusCallback "No problems were found. Please restore the proper setpoints now."
    return
    
}

proc APSUSrDcpsAction {args} {
    set action ""
    set value 0
    set families ""
    set sectors ""
    set configFile ""
    set statusCallback ""
    set maxTries 20
    set filter "*"
    set SCRFile ""
    APSStrictParseArguments {action value families sectors configFile statusCallback SCRFile filter}
    set validNames(bipolar) ""
    set validNames(unipolar) ""
    if {[catch {APSUSrDcpsGetValidNames -arrayName validNames -families $families -sectors $sectors -filter $filter} result]} {
        return -code error "APSUSrDcpsAction: $result"
    }

    set allNames [lsort "$validNames(bipolar) $validNames(unipolar)"]
    if {[llength $allNames] == 0} {
        return
    }
    if {$action=="validateconnections"} {
        return [APSUSrValidateConnectionsDcps \
                  -bipolar $validNames(bipolar) \
                  -unipolar $validNames(unipolar) \
                  -families $families \
                  -statusCallback $statusCallback]
    }

    set try 1
    while {$try <= $maxTries} {
        if {($action == "on") || ($action == "off") || ($action == "setAndWait") || ($action == "setIfOff")} {
            if {[llength $validNames(bipolar)]} {
                if {[catch {exec cavget -pend=2 -list=[join $validNames(bipolar) ,] -list=:PS:OnOffStatusM.RVAL} onOffList]} {
                    return -code error "APSUSrDcpsAction: $onOffList"
                }
                if {[catch {exec cavget -pend=2 -list=[join $validNames(bipolar) ,] -list=:PS:FaultStatusM} faultList]} {
                    return -code error "APSUSrDcpsAction: $faultList"
                }
                foreach name $validNames(bipolar) faultValue $faultList {
                    if {$faultValue == 0} {
                        set faultStatus($name) "No Fault"
                    } else {
                        set faultStatus($name) "Fault"
                    }
                }
                foreach name $validNames(bipolar) onOffValue $onOffList {
                    if {$onOffValue == 0} {
                        set onOff($name) "Power On"
                    } else {
                        set onOff($name) "Power Off"
                    }
                }
            }
            if {[llength $validNames(unipolar)]} {
                if {[catch {exec cavget -pend=2 -list=[join $validNames(unipolar) ,] -list=:PS:OnOffM} onOffList]} {
                    return -code error "APSUSrDcpsAction: $onOffList"
                }
                if {[catch {exec cavget -pend=2 -list=[join $validNames(unipolar) ,] -list=:PS:FaultsM} faultList]} {
                    return -code error "APSUSrDcpsAction: $faultList"
                }
                foreach name $validNames(unipolar) faultValue $faultList {
                    if {$faultValue == 0} {
                        set faultStatus($name) "No Fault"
                    } else {
                        set faultStatus($name) "Fault"
                    }
                }
                foreach name $validNames(unipolar) onOffValue $onOffList {
                    set onOff($name) $onOffValue
                }
            }
            
            set poweredOnList ""
            set poweredOffList ""
            foreach name $allNames {
                if {$action == "off"} {
                    if {($onOff($name) != "Power Off")} {
                        lappend poweredOnList $name
                    } else {
                        lappend poweredOffList $name
                    }
                }
                if {$action == "on"} {
                    if {($onOff($name) != "Power On") || ($faultStatus($name) != "No Fault")} {
                        lappend poweredOffList $name
                    } else {
                        lappend poweredOnList $name
                    }
                }
            }
        }
        
        if {$action == "on"} {
            if {$try == 1} {
                #Check if S:M1 or S:M2 were selected then clear faults
                if {[lsearch -exact $allNames "S:M1"] != -1} {
                    if [catch {APScavget -pend=1 -list=S:M1:PS:FaultStateM -num} result] {
                        return -code error "APSUSrDcpsAction: $result"
                    }
                    if {$result == 1} {
                        if [catch {APScavput -pend=1 -blunder=silent -list=S:M1:PS:ResetSupplyC.PROC=1} result] {
                            return -code error "APSUSrDcpsAction: $result"
                        }
                        APSWaitWithUpdate -waitSeconds 10
                        if [catch {APScavget -pend=1 -list=S:M1:PS:FaultStateM -num} result] {
                            return -code error "APSUSrDcpsAction: $result"
                        }
                        if {$result == 1} {
                            return -code error "APSUSrDcpsAction: S:M1 stuck in fault state"
                        }
                    }
                }
                if {[lsearch -exact $allNames "S:M2"] != -1} {
                    if [catch {APScavget -pend=1 -list=S:M2:PS:FaultStateM -num} result] {
                        return -code error "APSUSrDcpsAction: $result"
                    }
                    if {$result == 1} {
                        if [catch {APScavput -pend=1 -blunder=silent -list=S:M2:PS:ResetSupplyC.PROC=1} result] {
                            return -code error "APSUSrDcpsAction: $result"
                        }
                        APSWaitWithUpdate -waitSeconds 10
                        if [catch {APScavget -pend=1 -list=S:M2:PS:FaultStateM -num} result] {
                            return -code error "APSUSrDcpsAction: $result"
                        }
                        if {$result == 1} {
                            return -code error "APSUSrDcpsAction: S:M2 stuck in fault state"
                        }
                    }
                }
                #Check if S:M1 or S:M2 were selected then turn on the DC Link
                set dclinkPauseNeeded 0
                if {[lsearch -exact $allNames "S:M1"] != -1} {
                    if [catch {APScavget -pend=1 -list=S:M1:PS:DCLinkM -num} result] {
                        return -code error "APSUSrDcpsAction: $result"
                    }
                    if {$result == 0} {
                        if [catch {APScavput -pend=1 -blunder=silent -list=S:M1:PS:DCLinkOnC.PROC=1} result] {
                            return -code error "APSUSrDcpsAction: $result"
                        }
                        set dclinkPauseNeeded 1
                    }
                }
                if {[lsearch -exact $allNames "S:M2"] != -1} {
                    if [catch {APScavget -pend=1 -list=S:M2:PS:DCLinkM -num} result] {
                        return -code error "APSUSrDcpsAction: $result"
                    }
                    if {$result == 0} {
                        if [catch {APScavput -pend=1 -blunder=silent -list=S:M2:PS:DCLinkOnC.PROC=1} result] {
                            return -code error "APSUSrDcpsAction: $result"
                        }
                        incr dclinkPauseNeeded 2
                    }
                }
                if {$dclinkPauseNeeded == 1} {
                    if {[catch {exec cawait -timeLImit=45 -waitFor=S:M1:PS:DCLinkM,equalTo=1} result]} {
                        return -code error "APSUSrDcpsAction: S:M1 DC Link didn't turn on"
                    }
                } elseif {$dclinkPauseNeeded == 2} {
                    if {[catch {exec cawait -timeLImit=45 -waitFor=S:M2:PS:DCLinkM,equalTo=1} result]} {
                        return -code error "APSUSrDcpsAction: S:M2 DC Link didn't turn on"
                    }
                } elseif {$dclinkPauseNeeded == 3} {
                    if {[catch {exec cawait -timeLImit=45 -waitFor=S:M1:PS:DCLinkM,equalTo=1 -waitFor=S:M2:PS:DCLinkM,equalTo=1 -and } result]} {
                        return -code error "APSUSrDcpsAction: S:M1 and/or S:M2 DC Link didn't turn on"
                    }
                }
                if {$dclinkPauseNeeded} {
                    APSWaitWithUpdate -waitSeconds 30
                }
            }
            if {[llength $poweredOffList] == 0} {
                return
            } elseif {$try == $maxTries} {
                return -code error "APSUSrDcpsAction: Unable to turn on: $poweredOffList"
            }
            if {$try == [expr $maxTries - 1]} {
                foreach pv $poweredOffList {
                    if [catch {eval APScavput -pend=1 -blunder=silent -list=$pv -list=:PS:SupplyOnC.PROC=1} result] {
                        return -code error "APSUSrDcpsAction: $result"
                    }
                    after 10
                }
            } else {
                if [catch {eval APScavput -pend=1 -blunder=silent -list=[join $poweredOffList ,] -list=:PS:ResetSupplyC.PROC=1} result] {
                    return -code error "APSUSrDcpsAction: $result"
                }
                if [catch {eval APScavput -pend=1 -blunder=silent -list=[join $poweredOffList ,] -list=:PS:SupplyOnC.PROC=1} result] {
                    return -code error "APSUSrDcpsAction: $result"
                }
                after 750
            }
            incr try
        } elseif {$action == "off"} {
            if {[llength $poweredOnList] == 0} {
                #When everything is off, check if S:M1 or S:M2 were selected then turn off the DC Link
                if {[lsearch -exact $allNames "S:M1"] != -1} {
                    if [catch {APScavget -pend=1 -list=S:M1:PS:DCLinkM -num} result] {
                        return -code error "APSUSrDcpsAction: $result"
                    }
                    if {$result == 1} {
                        if [catch {APScavput -pend=1 -blunder=silent -list=S:M1:PS:DCLinkOffC.PROC=1} result] {
                            return -code error "APSUSrDcpsAction: $result"
                        }
                    }
                }
                if {[lsearch -exact $allNames "S:M2"] != -1} {
                    if [catch {APScavget -pend=1 -list=S:M2:PS:DCLinkM -num} result] {
                        return -code error "APSUSrDcpsAction: $result"
                    }
                    if {$result == 1} {
                        if [catch {APScavput -pend=1 -blunder=silent -list=S:M2:PS:DCLinkOffC.PROC=1} result] {
                            return -code error "APSUSrDcpsAction: $result"
                        }
                    }
                }
                return
            } elseif {$try == $maxTries} {
                return -code error "APSUSrDcpsAction: Unable to turn off: $poweredOnList"
            }
            if {$try == [expr $maxTries - 1]} {
                foreach pv $poweredOnList {
                    if [catch {eval APScavput -pend=1 -blunder=silent -list=$pv -list=:PS:SupplyOffC.PROC=1} result] {
                        return -code error "APSUSrDcpsAction: $result"
                    }
                    after 10
                }
            } else {
                if {$try == 1} {
                    #Ramp to 0
                    if [catch {eval APScavput -pend=1 -blunder=silent -list=[join $poweredOnList ,] -list=:PS:SetCurrentC=0} result] {
                        return -code error "APSUSrDcpsAction: $result"
                    }
                    after 10
                    if [catch {eval APScavput -pend=1 -blunder=silent -list=[join $poweredOnList ,] -list=:PS:SetCurrentC=0} result] {
                        return -code error "APSUSrDcpsAction: $result"
                    }
                    after 10
                    if [catch {eval APScavput -pend=1 -blunder=silent -list=[join $poweredOnList ,] -list=:PS:SetCurrentC=0} result] {
                        return -code error "APSUSrDcpsAction: $result"
                    }
                    set powerDownTry 1
                    set suppliesWithoutPower ""
                    while {1} {
                        APSWaitWithUpdate -waitSeconds 1
                        set suppliesWithPower ""
                        set newSuppliesWithoutPower ""
                        if [catch {eval APScavget -pend=1 -list=[join $poweredOnList ,] -list=:PS:MeasCurrentM -printerror} result] {
                            return -code error "APSUSrDcpsAction: $result"
                        }
                        foreach pv $poweredOnList val $result {
                            if {$val > 1} {
                                lappend suppliesWithPower $pv
                            } elseif {[lsearch -exact $suppliesWithoutPower $pv] == -1} { 
                                lappend suppliesWithoutPower $pv
                                lappend newSuppliesWithoutPower $pv
                            }
                        }
                        if {[llength $suppliesWithPower] == 0} {
                            break
                        }
                        #Turn off the supplies that successfully make it to 0 Amps. 
                        foreach pv $newSuppliesWithoutPower {
                            if [catch {eval APScavput -pend=1 -blunder=silent -list=$pv -list=:PS:SupplyOffC.PROC=1} result2] {
                                return -code error "APSUSrDcpsAction: $result2"
                            }
                            after 1
                        }
                        #S:M1 takes 25 seconds to ramp to 0 from full power
                        if {$powerDownTry > 30} {
                            catch {APSSendEMail -address soliday \
                                     -subject "APSUSrDcpsAction turn off issue"  \
                                     -message "$suppliesWithPower SR power supplies are not going to 0 amps prior to shutdown\n $poweredOnList \n $result"} 	    
                            return -code error "APSUSrDcpsAction: $suppliesWithPower SR power supplies are not going to 0 amps prior to shutdown"
                        }                   
                        incr powerDownTry
                    }
                }
                if [catch {eval APScavput -pend=1 -blunder=silent -list=[join $poweredOnList ,] -list=:PS:SupplyOffC.PROC=1} result] {
                    return -code error "APSUSrDcpsAction: $result"
                }
                after 750
            }
            incr try
        } elseif {$action == "set"} {
            if [catch {eval APScavput -pend=1 -blunder=silent -list=[join $allNames ,] -list=:PS:SetCurrentC=$value} result] {
                return -code error "APSUSrDcpsAction: $result"
            }
            return
        } elseif {$action == "setIfOff"} {
            if {[llength $poweredOffList]} {
                if [catch {eval APScavput -pend=1 -blunder=silent -list=[join $poweredOffList ,] -list=:PS:SetCurrentC=$value} result] {
                    return -code error "APSUSrDcpsAction: $result"
                }
            }
            return
        } elseif {$action == "setAndWait"} {
            if [catch {eval APScavput -pend=1 -blunder=silent -list=[join $allNames ,] -list=:PS:SetCurrentC=$value} result] {
                return -code error "APSUSrDcpsAction: $result"
            }
            if {[llength $poweredOnList]} {
                for {set steps 1} {$steps <= 60} {incr steps} {
                    if [catch {eval APScavget -pend=1 -blunder=silent -list=[join $poweredOnList ,] -list=:PS:MeasCurrentM=$value} results] {
                        return -code error "APSUSrDcpsAction: $results"
                    }
                    set pass 1
                    foreach v $results {
                        if {([string compare $v "?"] != 0) && ([expr abs($v - $value)] > 1)} {
                            set pass 0
                            break
                        }
                    }
                    if {$pass} {
                        break
                    }
                    APSWaitWithUpdate -waitSeconds 1
                }
            }
            return
        } elseif {$action == "setFromSCR"} {
            set configFile1 [APSTmpDir]/[APSTmpString]
            set tmpfile [APSTmpDir]/[APSTmpString]
            if {[llength $validNames(bipolar)]} {
                #degauss
                set configFile "/home/helios/oagData/sr/magnetConditioning/degauss.config"
                set matchOption "-match=column,ControlName=[lindex $validNames(bipolar) 0]"
                foreach name [lrange $validNames(bipolar) 1 end] {
                    append matchOption ",ControlName=${name},|"
                }
                if {[catch {exec sddsprocess $configFile $configFile1 $matchOption -nowarnings} result]} {
                    return -code error "APSUSrDcpsAction: $result"
                }
                if {[catch {exec sdds2stream -rows $configFile1} result]} {
                    return -code error "APSUSrDcpsAction: $result"
                }
                if {$result == "0 rows"} {
                    return -code error  "No configuration data"
                }

                if {[catch {exec sddsprocess $configFile1 $tmpfile "-edit=column,CurrentName,ControlName,ei/:PS:SetCurrentC/"} result]} {
                    return -code error "APSUSrDcpsAction: $result"
                }
                file delete $configFile1
                if {[catch {exec sddsselect $SCRFile $tmpfile ${tmpfile}.2 \
                              -match=ControlName=CurrentName} result]} {
                    return -code error "APSUSrDcpsAction: $result"
                }
                file delete $tmpfile
                set restoreFile ${tmpfile}.2

                if {[catch {exec sddscaramp -rampTo=${restoreFile},steps=20,pause=.5 -resendFinal -pendIOTime=10} result]} {
                    return -code error "APSUSrDcpsAction: $result"
                }
                #if {[catch {exec sddspvasaverestore $restoreFile -restore -pendIOTime=10} result]} {
                #    return -code error "APSUSrDcpsAction: $result"
                #}

                after 1000
                file delete ${tmpfile}.2
            }
            if {[llength $validNames(unipolar)]} {
                #standardize
                set configFile "/home/helios/oagData/sr/magnetConditioning/standardize.config"
                set matchOption "-match=column,ControlName=[lindex $validNames(unipolar) 0]"
                foreach name [lrange $validNames(unipolar) 1 end] {
                    append matchOption ",ControlName=${name},|"
                }
                if {[catch {exec sddsprocess $configFile $configFile1 $matchOption -nowarnings} result]} {
                    return -code error "APSUSrDcpsAction: $result"
                }
                if {([llength $SCRFile]) && ([file exists $SCRFile])} {
                    file delete $tmpfile
                }
                if {[catch {exec sdds2stream -rows $configFile1} result]} {
                    return -code error "APSUSrDcpsAction: $result"
                }
                if {$result == "0 rows"} {
                    return -code error  "No configuration data"
                }

                if {[catch {exec sddsprocess $configFile1 $tmpfile "-edit=column,CurrentName,ControlName,ei/:PS:SetCurrentC/"} result]} {
                    return -code error "APSUSrDcpsAction: $result"
                }
                file delete $configFile1
                if {[catch {exec sddsselect $SCRFile $tmpfile ${tmpfile}.2 \
                              -match=ControlName=CurrentName} result]} {
                    return -code error "APSUSrDcpsAction: $result"
                }
                file delete $tmpfile
                set restoreFile ${tmpfile}.2

                if {[catch {exec sddspvasaverestore $restoreFile -restore -pendIOTime=10} result]} {
                    return -code error "APSUSrDcpsAction: $result"
                }

                after 1000
                file delete ${tmpfile}.2
            }
            return


        } elseif {$action == "setcycles"} {
            if {[llength $validNames(bipolar)]} {
                #degauss
                if [catch {eval APScavput -pend=1 -blunder=silent -list=[join $validNames(bipolar) ,] -list=:StandardizeC.C=$value} result] {
                    return -code error "APSUSrDcpsAction: $result"
                }
            }
            if {[llength $validNames(unipolar)]} {
                #standardize
                if [catch {eval APScavput -pend=1 -blunder=silent -list=[join $validNames(unipolar) ,] -list=:StandardizeC.F=$value} result] {
                    return -code error "APSUSrDcpsAction: $result"
                }
            }            
            return
        } elseif {$action == "configure"} {
            set configFile1 [APSTmpDir]/[APSTmpString]
            if {[llength $validNames(bipolar)]} {
                #degauss
                set configFile "/home/helios/oagData/sr/magnetConditioning/degauss.config"
                set matchOption "-match=column,ControlName=[lindex $validNames(bipolar) 0]"
                foreach name [lrange $validNames(bipolar) 1 end] {
                    append matchOption ",ControlName=${name},|"
                }
                if {[catch {exec sddsprocess $configFile $configFile1 $matchOption -nowarnings} result]} {
                    return -code error "APSUSrDcpsAction: $result"
                }
                if {[catch {exec sdds2stream -rows $configFile1} result]} {
                    return -code error "APSUSrDcpsAction: $result"
                }
                if {$result == "0 rows"} {
                    return -code error  "No configuration data"
                }
                if {[catch {exec degauss -configure $configFile1} result]} {
                    return -code error "APSUSrDcpsAction: $result"
                }
                file delete $configFile1
            }
            if {[llength $validNames(unipolar)]} {
                #standardize
                set configFile "/home/helios/oagData/sr/magnetConditioning/standardize.config"
                if {([llength $SCRFile]) && ([file exists $SCRFile])} {
                    set tmpfile [APSTmpDir]/[APSTmpString]
                    if {[catch {exec sddsprocess $configFile \
                                  -pipe=out "-edit=column,CurrentName,ControlName,ei/:PS:SetCurrentC/" -delete=column,Finish | \
                                  sddsxref -pipe $SCRFile \
                                  -match=CurrentName=ControlName -take=ValueString | \
                                  sddsprocess -pipe=in $tmpfile -scan=column,Finish,ValueString,%lf,type=double} result]} {
                        return -code error "APSUSrDcpsAction: $result"
                    }
                    set configFile $tmpfile
                }
                set matchOption "-match=column,ControlName=[lindex $validNames(unipolar) 0]"
                foreach name [lrange $validNames(unipolar) 1 end] {
                    append matchOption ",ControlName=${name},|"
                }
                if {[catch {exec sddsprocess $configFile $configFile1 $matchOption -nowarnings} result]} {
                    return -code error "APSUSrDcpsAction: $result"
                }
                if {([llength $SCRFile]) && ([file exists $SCRFile])} {
                    file delete $tmpfile
                }
                if {[catch {exec sdds2stream -rows $configFile1} result]} {
                    return -code error "APSUSrDcpsAction: $result"
                }
                if {$result == "0 rows"} {
                    return -code error  "No configuration data"
                }
                if {[catch {exec standardize -configure $configFile1} result]} {
                    return -code error "APSUSrDcpsAction: $result"
                }
                file delete $configFile1
            }
            return
        } elseif {$action == "forcecondition"} {
            if {[catch {APSUSrDcpsPreCondition} result]} {
                return -code error "APSUSrDcpsAction: $result"
            }
            if {[llength $validNames(bipolar)]} {
                #degauss
                if [catch {eval APScavput -pend=1 -blunder=silent -list=[join $validNames(bipolar) ,] -list=:StandardizeC.PROC=1} result] {
                    return -code error "APSUSrDcpsAction: $result"
                }
            }
            if {[llength $validNames(unipolar)]} {
                #standardize
                if [catch {eval APScavput -pend=1 -blunder=silent -list=[join $validNames(unipolar) ,] -list=:StandardizeC.PROC=1} result] {
                    return -code error "APSUSrDcpsAction: $result"
                }
            }
            return
        } elseif {$action == "stopcond"} {
            if {[llength $validNames(bipolar)]} {
                #degauss
                if [catch {eval APScavput -pend=1 -blunder=silent -list=[join $validNames(bipolar) ,] -list=:StandardizeC.PROC=0} result] {
                    return -code error "APSUSrDcpsAction: $result"
                }
            }
            if {[llength $validNames(unipolar)]} {
                #standardize
                if [catch {eval APScavput -pend=1 -blunder=silent -list=[join $validNames(unipolar) ,] -list=:StandardizeC.PROC=0} result] {
                    return -code error "APSUSrDcpsAction: $result"
                }
            }
            return
        } elseif {$action == "listcond"} {
            set names ""
            if {[llength $validNames(bipolar)]} {
                #degauss
                if [catch {eval APScavget -pend=1 -list=[join $validNames(bipolar) ,] -list=:StandardizeC.PROC} result] {
                    return -code error "APSUSrDcpsAction: $result"
                }
                foreach name $validNames(bipolar) val $result {
                    if {$val != 0} {
                        lappend names $name
                    }
                }
            }
            if {[llength $validNames(unipolar)]} {
                #standardize
                if [catch {eval APScavget -pend=1 -list=[join $validNames(unipolar) ,] -list=:StandardizeC.PROC} result] {
                    return -code error "APSUSrDcpsAction: $result"
                }
                foreach name $validNames(unipolar) val $result {
                    if {$val != 0} {
                        lappend names $name
                    }
                }
            }
            return -code ok $names
        } else {
            return
        }
    }
}


proc APSUSrDcpsPreCondition {} {
    upvar validNames vn
    set options ""
    set removeList ""
    foreach ps $vn(unipolar) {
        set sector [string range $ps 0 2]
        set type [string range $ps 3 end]
        switch $type {
            "A:Q4" {
                lappend removeList ${sector}A:Q4T
                #lappend options "${sector}${type}:StandardizeC.OUTB=${sector}A:Q4T:StandardizeC.PROC"
                #lappend options "${sector}${type}:StandardizeC.OUTC=${sector}A:Q4T:PS:SetCurrentC"
                #lappend options "${sector}${type}:StandardizeC.OUTD=\"\""
            }
            "B:Q4" {
                lappend removeList ${sector}B:Q4T
                #lappend options "${sector}${type}:StandardizeC.OUTB=${sector}B:Q4T:StandardizeC.PROC"
                #lappend options "${sector}${type}:StandardizeC.OUTC=${sector}B:Q4T:PS:SetCurrentC"
                #lappend options "${sector}${type}:StandardizeC.OUTD=\"\""
            }
            "A:Q5" {
                lappend removeList ${sector}A:Q5T
                #lappend options "${sector}${type}:StandardizeC.OUTB=${sector}A:Q5T:StandardizeC.PROC"
                #lappend options "${sector}${type}:StandardizeC.OUTC=${sector}A:Q5T:PS:SetCurrentC"
                #lappend options "${sector}${type}:StandardizeC.OUTD=\"\""
            }
            "B:Q5" {
                lappend removeList ${sector}B:Q5T
                #lappend options "${sector}${type}:StandardizeC.OUTB=${sector}B:Q5T:StandardizeC.PROC"
                #lappend options "${sector}${type}:StandardizeC.OUTC=${sector}B:Q5T:PS:SetCurrentC"
                #lappend options "${sector}${type}:StandardizeC.OUTD=\"\""
            }
            "A:Q7" {
                lappend removeList ${sector}A:H7
                lappend removeList ${sector}A:V7
                #lappend options "${sector}${type}:StandardizeC.OUTB=${sector}A:H7:StandardizeC.PROC"
                #lappend options "${sector}A:H7:StandardizeC.OUTB=${sector}A:V7:StandardizeC.PROC"
                #lappend options "${sector}${type}:StandardizeC.OUTC=${sector}A:H7:PS:SetCurrentC"
                #lappend options "${sector}${type}:StandardizeC.OUTD=${sector}A:V7:PS:SetCurrentC"
            }
            "B:Q7" {
                lappend removeList ${sector}B:H7
                lappend removeList ${sector}B:V7
                #lappend options "${sector}${type}:StandardizeC.OUTB=${sector}B:H7:StandardizeC.PROC"
                #lappend options "${sector}B:H7:StandardizeC.OUTB=${sector}B:V7:StandardizeC.PROC"
                #lappend options "${sector}${type}:StandardizeC.OUTC=${sector}B:H7:PS:SetCurrentC"
                #lappend options "${sector}${type}:StandardizeC.OUTD=${sector}B:V7:PS:SetCurrentC"
            }
            "A:Q8" {
                lappend removeList ${sector}A:Q8T
                lappend removeList ${sector}A:V8
                #lappend options "${sector}${type}:StandardizeC.OUTB=${sector}A:Q8T:StandardizeC.PROC"
                #lappend options "${sector}A:Q8T:StandardizeC.OUTB=${sector}A:V8:StandardizeC.PROC"
                #lappend options "${sector}${type}:StandardizeC.OUTC=${sector}A:Q8T:PS:SetCurrentC"
                #lappend options "${sector}${type}:StandardizeC.OUTD=${sector}A:V8:PS:SetCurrentC"
            }
            "B:Q8" {
                lappend removeList ${sector}B:Q8T
                lappend removeList ${sector}B:V8
                #lappend options "${sector}${type}:StandardizeC.OUTB=${sector}B:Q8T:StandardizeC.PROC"
                #lappend options "${sector}B:Q8T:StandardizeC.OUTB=${sector}B:V8:StandardizeC.PROC"
                #lappend options "${sector}${type}:StandardizeC.OUTC=${sector}B:Q8T:PS:SetCurrentC"
                #lappend options "${sector}${type}:StandardizeC.OUTD=${sector}B:V8:PS:SetCurrentC"
            }
            "A:S1" {
                lappend removeList ${sector}A:H1
                lappend removeList ${sector}A:V1
                #lappend options "${sector}${type}:StandardizeC.OUTB=${sector}A:H1:StandardizeC.PROC"
                #lappend options "${sector}A:H1:StandardizeC.OUTB=${sector}A:V1:StandardizeC.PROC"
                #lappend options "${sector}${type}:StandardizeC.OUTC=${sector}A:H1:PS:SetCurrentC"
                #lappend options "${sector}${type}:StandardizeC.OUTD=${sector}A:V1:PS:SetCurrentC"
            }
            "B:S1" {
                lappend removeList ${sector}B:H1
                lappend removeList ${sector}B:V1
                #lappend options "${sector}${type}:StandardizeC.OUTB=${sector}B:H1:StandardizeC.PROC"
                #lappend options "${sector}B:H1:StandardizeC.OUTB=${sector}B:V1:StandardizeC.PROC"
                #lappend options "${sector}${type}:StandardizeC.OUTC=${sector}B:H1:PS:SetCurrentC"
                #lappend options "${sector}${type}:StandardizeC.OUTD=${sector}B:V1:PS:SetCurrentC"
            }
            "A:M3" {
                lappend removeList ${sector}A:M3T
                #lappend options "${sector}${type}:StandardizeC.OUTB=${sector}A:M3T:StandardizeC.PROC"
                #lappend options "${sector}${type}:StandardizeC.OUTC=${sector}A:M3T:PS:SetCurrentC"
                #lappend options "${sector}${type}:StandardizeC.OUTD=\"\""
            }
            "A:M4" {
                lappend removeList ${sector}A:M4T
                #lappend options "${sector}${type}:StandardizeC.OUTB=${sector}A:M4T:StandardizeC.PROC"
                #lappend options "${sector}${type}:StandardizeC.OUTC=${sector}A:M4T:PS:SetCurrentC"
                #lappend options "${sector}${type}:StandardizeC.OUTD=\"\""
            }
            "B:M3" {
                lappend removeList ${sector}B:M3T
                #lappend options "${sector}${type}:StandardizeC.OUTB=${sector}B:M3T:StandardizeC.PROC"
                #lappend options "${sector}${type}:StandardizeC.OUTC=${sector}B:M3T:PS:SetCurrentC"
                #lappend options "${sector}${type}:StandardizeC.OUTD=\"\""
            }
        }
    }
    foreach ps $removeList {
        set i [lsearch -exact $vn(bipolar) $ps]
        if {$i != -1} {
            set vn(bipolar) [lreplace $vn(bipolar) $i $i]
        }
    }
    if {[llength $options]} {
        catch {APScavput -list=[join $options ,]}
        after 1000
    }
}

