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

#

# the interface is copied from quickExperiment, SHANG

set auto_path [linsert $auto_path 0  /usr/local/oag/apps/lib/$env(HOST_ARCH)]
set auto_path [linsert $auto_path 0 /usr/local/oag/lib_patch/$env(HOST_ARCH)]
set CVSRevisionAuthor "\$Revision: 1.9 $ \$Author: shang $"

APSApplication . -name btsResponseMeasurement -version $CVSRevisionAuthor \
  -overview {This is the btsResponseMeasurement utility.  It provides a simple interface to the sddsexperiment program, which allows varying and measuring EPICS data, and logging the results and some statistical analysis to an SDDS file.  The data can be plotted after it is collected. You can also manipulate and display the data offline using the SDDS toolkit programs.}

set Variables 0
set VariableLines 1

set mainStatus "Press ADD to enter more PV names for measurements and variables"

proc SetMainStatus {text} {
    global mainStatus
    set mainStatus "[exec date] $text"
    update 
}

proc ProcessBPMData {args} {
    global responseFile coeff Hcorrector Vcorrector
    
    set respDir [file dirname $responseFile]
    set rawDir $respDir/rawData
   
    
    foreach type {BTS SRH SRV} otherPlane {x y x} {
        foreach plane {H V} {
            set readbacks [exec sddsprocess /home/helios/oagData/BTS.old/responseMeasurement/BTS-SR.meas \
                             "-match=col,SymbolicName=*$otherPlane,!" \
                             "-match=col,SymbolicName=*sum,!" -pipe=out | sdds2stream -pipe=in -col=SymbolicName]
           ### puts $rawDir/${plane}.resp_${type}*.resp
	   
            set files [glob -nocomplain $rawDir/${plane}.resp_${type}*.resp]
            if ![llength $files] {
               continue
            }
            SetMainStatus "process bpm data $plane $type..."
            set fileList ""
            set optList ""
            foreach file $files {
                set corr [lindex [split [file root $file] _] 2]
                if [catch {exec sddsslopes $file [file root $file].slope \
                             -independentVariable=$corr -col=[join $readbacks ,] } result] {
                    return -code error "Error getting slopes1: $result"
                }
                if ![info exist coeff($corr)] {
                    set coeff($corr) 1.0
                }
                if [catch {exec sddsconvert [file root $file].slope -delete=col,*Intercept -pipe=out \
                             | sddstranspose -pipe \
                             | sddsconvert -pipe -rename=col,OldColumnNames=BPMNames \
                             | sddsprocess -pipe=in -reedit=col,BPMNames,%/Slope// \
                             "-redefine=col,$corr,$corr $coeff($corr) /,units=m/rad" \
                             [file root $file].bpm } result] {
                    return -code error "Error processing bpm data: $result"
                }
                lappend optList -col=BPMNames,$corr [file root $file].bpm
                lappend fileList [file root $file].bpm
		
		exec sddsplot -col=$corr,*S*P* -grap=sym,conn,sub=1,scale=2 -sep $file &
            }
            set len [llength $files]
            set n [expr int(($len+2)/3)]
            puts $fileList
            eval exec sddsplot -split=page -sep  -layout=3,$n -gra=sym,conn,scale=2  $optList &
            if [llength $fileList]>1 {
                if [catch {eval exec sddsxref $fileList -pipe=out -match=BPMNames -leave=BPMNames -nowarnings \
                             | sddsprocess -pipe=in -edit=col,BPMName,BPMNames,%/://%/:x//%/:y// $respDir/${plane}.resp.$type } result] {
                    return -code error "Error combining response file: $result"
                }
            } else {
                if [catch {exec sddsprocess $fileList -edit=col,BPMName,BPMNames,%/://%/:x//%/:y// $respDir/${plane}.resp.$type } result] {
                    return -code error "Error processing response file: $result"
                }
            }
         
        }
        
    }
}

proc ProcessRespData {args} {
    global responseFile plane
    set fileList ""
    if ![file exist $responseFile.BTS] {
        #BTS file does not exist, it might be measurend by SRH/SRV
        if [file exist $responseFile.SRH] {
            set file $responseFile.SRH
        } elseif [file exist $responseFile.SRV] {
            set file $responseFile.SRV
        } else {
            SetMainStatus "Response file not found."
            return
        }
        if [catch {exec sddsprocess $file  $responseFile.BTS "-match=col,BPMNames=*H*,BPMNames=*V*,|" -nowarnings } result] {
            return -code error "Error creating BTS resp file: $result"
        }
    }
    set dir [file dir $responseFile]
    cd $dir
    set fileList $responseFile.BTS
    foreach type {SRH SRV} plane1 {x y} {
        if ![file exist $responseFile.$type] {
            continue
        }
        if [catch {exec sddsprocess $responseFile.$type $responseFile.$type.$plane1 \
                     -match=col,BPMNames=*:$plane1 } result] {
            return -code error "Error process resp1: $result"
        }
        lappend fileList $responseFile.$type.$plane1
    }
    if ![llength $fileList] {
        return -code error "No response file found."
    }
   # puts $fileList
    SetMainStatus "combining response data..."
    if [catch {eval exec sddscombine $fileList -merge -pipe=out \
                 | tee $responseFile.all \
                 | sddsconvert -pipe -del=col,Mt:BoosterRampTurnsAO \
                 | sddsprocess -pipe=in "-match=col,BPMNames=*H*,BPMNames=*x,|" $plane.hrm 
        exec sddsprocess  $responseFile.all "-match=col,BPMNames=*V*,BPMNames=*y,|" $plane.vrm } result] {
        return -code error "Error processing response data1: $result"
    }
    #make LOCO resp file
    SetMainStatus "make LOCO resp file..."
    switch $plane {
        H {
            if [catch {exec sddsconvert $plane.hrm -del=col,*IS*,*BET* -pipe=out \
                         | sddsprocess -pipe=in -reedit=col,BPMNames,%/:x// LOCO.hrm 
                exec sddsconvert $plane.vrm -del=col,*IS*,*BET* -pipe=out \
                        | sddsprocess -pipe=in -reedit=col,BPMNames,%/:x//  LOCO.hvrm } result] {
                return -code error "Error creating LOCO resp1: $result"
            }
        }
        V {
            if [catch {exec sddsconvert $plane.vrm -del=col,*IS*,*BET* -pipe=out \
                        | sddsprocess -pipe=in -reedit=col,BPMNames,%/:y//  LOCO.vrm 
                exec sddsconvert $plane.hrm -del=col,*IS*,*BET* -pipe=out \
                        | sddsprocess -pipe=in -reedit=col,BPMNames,%/:y//  LOCO.vhrm } result] {
                return -code error "Error creating LOCO resp1: $result"
            }
        }
    }
    set cols [exec sddsquery -col $responseFile.all]
    if [lsearch -exact $cols "BExtTurn"]>=0 {
        #process dispersion data
        SetMainStatus "process dispersion data..."
        set extTurns  60685
        set E_inj  425 
        set E_ext  7000
        set E_per_turn [expr ($E_ext - $E_inj) * 1.00 / $extTurns ]
        set deltaPerTurn [expr $E_per_turn  * 1.00  / $E_ext]
        if [catch {exec sddsprocess $responseFile.all -pipe=out \
                     "-redefine=col,dispersion,BExtTurn $deltaPerTurn /,units=mm" \
                     | tee $responseFile.disp.all \
                     | sddsprocess -pipe=in "-match=col,BPMNames=*H*,BPMNames=*V*,|" xyDisp-BTS 
            exec sddsprocess $responseFile.disp.all -match=col,BPMNames=*x xDisp-SR
            exec sddsprocess $responseFile.disp.all -match=col,BPMNames=*y yDisp-SR } result] {
            return -code error "Error processing disperson: $result"
        }
    }
    SetMainStatus "resp process done."
}

proc ClearCorrs {args} {
    global plane
    global Hcorrectors Hcorrector Vcorrectors Vcorrector
    set corrs [set ${plane}correctors]
    for {set i 0} {$i<$corrs} {incr i} {
        set ${plane}corrector($i.checked) 0
    }
}

proc LoadCorrector {args} {
    set plane ""
    APSParseArguments {plane}
    
    global Hcorrectors Vcorrectors Hcorrector Vcorrector
    set varFile /home/helios/oagData/BTS.old/responseMeasurement/BTS${plane}.sdds
    set names  [exec sdds2stream -col=ControlName $varFile ]
    set symbols [exec sdds2stream -col=SymbolicName $varFile]
    set initialValues [exec sdds2stream -col=InitialValue $varFile]
    set finalValues [exec sdds2stream -col=FinalValue $varFile]
    set relativeValues [exec sdds2stream -col=Relative $varFile]
    set rows [llength $names]
    set ${plane}correctors $rows
    for {set i 0} {$i<$rows} {incr i} {
        set ${plane}corrector($i.PV) [lindex $names $i]
        set ${plane}corrector($i.symbol) [lindex $symbols $i]
        set ${plane}corrector($i.init) [format %.2f [lindex $initialValues $i]]
        set ${plane}corrector($i.final) [format %.2f [lindex $finalValues $i]]
        set ${plane}corrector($i.relative) [lindex $relativeValues $i]
        set ${plane}corrector($i.checked) 1
    }
    update
}

set Hcorrectors 0
set Vcorrectors 0
proc CreateCorrectorWidget {args} {
    set parent ""
    set plane ""
    APSParseArguments {parent plane}

    global HCorrecgtor VCorrector Hcorrectors Vcorrectors
    set varScroll [APSScroll .varScroll -parent $parent]
    set varScrollFrame $parent.varScroll
    $varScroll configure -relief flat -bd 0
    #load input
    LoadCorrector -plane $plane
    set parent $varScroll
    set rows [set ${plane}correctors]
    for {set i 0} {$i<$rows} {incr i} {
        APSFrame .data$i  -parent $parent -height 1
        set w $parent.data$i.frame
        $w configure -relief flat -bd 0
        APSLabeledEntry .x -parent $w -label "PV:" -textVariable \
          ${plane}corrector($i.PV) -width 20 \
          -contextHelp "Enter the name of a variable process variable (PV) in this field." \
          -packOption "-side left"
        APSLabeledEntry .y -parent $w -label "Symbolic Name:" -textVariable \
          ${plane}corrector($i.symbol) -width 20 \
          -contextHelp "Enter the name of a variable process variable (PV) in this field." \
          -packOption "-side left"
        APSLabeledEntry .init -parent $w -label "Initial:" -textVariable \
          ${plane}corrector($i.init) -width 6 \
          -contextHelp "Enter the initial value for the variable process variable (PV) in this field." \
          -packOption "-side left"
        APSLabeledEntry .final -parent $w -label "Final:" -textVariable \
          ${plane}corrector($i.final) -width 6 \
          -contextHelp "Enter the initial value for the variable process variable (PV) in this field." \
          -packOption "-side left"
        APSCheckButtonFrame .rel -parent $w -label {} -buttonList {Relative} \
          -variableList ${plane}corrector($i.relative) -orientation horizontal \
          -contextHelp "If checked, then the variation range is defined relative to the PV's original value." \
          -packOption "-side left"
        APSCheckButtonFrame .scan -parent $w -label {} -buttonList {Scan} \
          -variableList ${plane}corrector($i.checked) -orientation horizontal \
          -contextHelp "If checked, then the variation range is defined relative to the PV's original value." \
          -packOption "-side left"
        tkwait visibility $w.scan
        APSScrollAdjust $varScrollFrame -numVisible 10
    }
}

set outputDir [APSGoToDailyDirectory -subdirectory btsResponse]

proc ChangePlane {args} {
    set plane0 ""
    APSParseArguments {plane0}
    global plane responseFile outputDir
    if [string length $plane0] {
        set plane $plane0
    }
    set responseFile $outputDir/${plane}.resp

}
proc SelectAll {args} {
    set value 1
    APSParseArguments {value}
    global plane Hcorrectors Hcorrector Vcorrectors Vcorrector
    set corrs [set ${plane}correctors]
    for {set i 0} {$i<$corrs} {incr i} {
        set ${plane}corrector($i.checked) $value
    }
}

proc VerifyBeamAndBPM {args} {
    global SRInjMode
    
    if [catch {exec cavget -list=S-DCCT:CurrentM -pend=30 -printErrors } current] {
            return -code error "Error reading SR current: $current!"
    }
    if {$current>0.5} {
        return -code error "There is stored beam in the ring, please dump it first!"
    }
    SetMainStatus "Loading SR single bunch x configuration..."
    set RAMfile /home/helios/oagData/SCR/snapshots/SBPMWaveform/SBPMWaveform-singleXBTS.gz
    set filename [file readlink $RAMfile]
    set dir /home/helios/oagData/SCR/snapshots/SBPMWaveform
    if [catch {exec sddscasr $filename -restore -pendIOTime=60 \
                 -waveform=directory=$dir,onefile,rootname=[file rootname [file tail $filename]],extension=.waveform.gz } result] {
        SetMainStatus "Error loading ram file: $result"
        return
    }
    
    SetMainStatus "setup SR bpms..."
    if [catch { exec cavput -list=S40,S1,S2 -list=A,B -list=:singleTurn:Enable=1 -pend=30 } result] {
        return -code error "Error arming SR bpms:$result"
    }
    if [catch {SetupSRBPM} result] {
        return -code error "Error setting up SR BPMs: $result"
    }
    
    SetMainStatus "Setup on-axis..."
    if [catch {SetupOnAxis -norm 0} result] {
        return -code error "Error setup onaxis for SR: $result"
    }
    
    SetMainStatus "Setup injection..."
    if { $SRInjMode=="Continuous"} {
        SetMainStatus "Starting injection..."
        if [catch {exec cavput -list=Mt:SRinjectMultiBO.VAL=1 -pend=30} result] {
            return -code error "Error start injecting: $result"
        }
    }
    APSInfoWindow .check -name "Check SR BPM" -message "Setup done. Please check the x bpms and sum signal" \
      -modal 1
    if { $SRInjMode=="Continuous"} {
        SetMainStatus "Stop injection..."
        if [catch {exec cavput -list=Mt:SRinjectMultiStopBO.VAL=1 -pend=30} result] {
            return -code error "Error stop injecting: $result"
        }
        if [catch {exec cavput -list=Mt:SRinjectMaxCyclesAO.VAL=1 -pend=30} result] {
            SetMainStatus "Error changing max. injection cycles to 1: $result"
        }
    }
}

proc SetupSRSingleBunchInjection {args} {
    SetMainStatus "setup SR single bunch injection (one cycle)..."
    exec cavput -list=Mt:SRinjectMaxCyclesAO=1,Mt:SRbunch000=0,Mt:SRinjectNumBunchesAO=1
    after 1000
    exec cavput -list=Mt:SRinjectMultiBO.VAL=1
    if [catch {SetupOnAxis } result] {
	return -code error "Error setup on axis injection: $result"
    }
    SetMainStatus "done."
}

set plane H
set measBTS 0
set measSRH 1
set measSRV 1
set SRInjMode continuous

APSScrolledStatus .status -parent .userFrame -textVariable mainStatus -width 80



APSFrame .variable -parent .userFrame  -label Actuators -packOption \
  "-side top -fill x" -contextHelp "Enter data for variable PVs in this frame."


set Steps 5

APSFrameGrid .grid -parent .userFrame.variable.frame -xList {x1 x2 x3 x4}
APSLabeledEntry .steps -parent .userFrame.variable.frame.grid.x1 -label \
  "Steps:  " -textVariable Steps -width 10 -contextHelp "Enter the number of steps (or samples) in this field." -packOption "-side left"
  

set w1 .userFrame.variable.frame
$w1 configure -relief flat -bd 0
set wList [APSTabFrame .planes -parent $w1 -label "" \
             -labelList "Horizontal Vertical" -width 1000 -height 200 -commandList {"ChangePlane -plane0 H" "ChangePlane -plane0 V"}]
set wH [lindex $wList 0]
set wV [lindex $wList 1]
CreateCorrectorWidget -parent $wH -plane H
$w1.planes.frame.tn select 1
CreateCorrectorWidget -parent $wV -plane V
$w1.planes.frame.tn select 0
APSButton .all -parent $w1 -text "Select All" -command {SelectAll}
APSButton .none -parent $w1 -text "Select None" -command {SelectAll -value 0}

APSRadioButtonFrame .beam -parent .userFrame -label "SR injection mode:      " -variable SRInjMode \
  -valueList {continuous single} -buttonList {continuous single} -orientation horizontal \
    -commandList {"set measBTS 0" "set measBTS 1"}

APSCheckButtonFrame .check -parent .userFrame -label "Select BPMs for measurement:" -buttonList "BTS SRH SRV" -variableList \
{measBTS measSRH measSRV} -orientation horizontal 
 

APSFrame .execution -parent .userFrame -contextHelp "Enter execution parameters here"

set interval 0.5
set PostChangePause 5
set rampSteps 1

set definitionFile ""
set responseFile ""
set invResponseFile ""
set comment ""
set numToAverage 10
set cycles 10
set doStd 1
set doSigma 0
set minimum 0
set saveRawData 1

APSFrameGrid .grid -parent .userFrame.execution.frame -xList {x1 x2}
set w .userFrame.execution.frame.grid.x1
APSLabeledEntry .average -parent $w -label "No. to average:" -width 10 -textVariable numToAverage \
  -contextHelp "The number of averages of the readback values."

APSLabeledEntry .interval -parent $w -label "Interval (s): " \
  -textVariable interval -width 10 \
  -contextHelp "Enter the time in seconds between measurements."
APSLabeledEntry .minimum -parent $w -label "Minimum singular value ratio:" -width 10 \
  -textVariable minimum \
  -contextHelp "minimumSingularValueRatio used in sddspseudoinverse:\nReject singular values less than the\nlargest singular value times this ratio."
APSLabeledEntry .ramp -parent $w -label "Ramp steps:" -width 10 \
  -textVariable rampSteps

set w .userFrame.execution.frame.grid.x2
APSLabeledEntry .cycyle -parent $w -label "No. of cycles.:" -width 10 -textVariable cycles \
  -contextHelp "The number of averages of the readback values."
APSLabeledEntry .postChangePause -parent $w -label "Post change pause (s): " \
  -textVariable PostChangePause -width 10 \
  -contextHelp "Enter the time in seconds to wait after a variable change and before measurements are taken."

APSCheckButtonFrame .std -parent $w -buttonList {stddev sigma} -label {} \
      -variableList "doStd doSigma" -orientation horizontal -allNone 0 \
      -contextHelp "Press these buttons to enable standard deviation or sigma calculation by sddsexperiment."
APSRadioButtonFrame .saverawdata -parent $w -label "Save raw data:" -buttonList {yes no} \
  -valueList {1 0}  -variable saveRawData  -packOption "-side left" -orientation horizontal \
  -contextHelp "if save raw data is chosen, then raw data will save under sub-directory rawData."

APSLabeledEntry .execution.frame.dir -parent .userFrame -label "Output dir:" \
  -textVariable outputDir -width 80
bind .userFrame.execution.frame.dir <Leave> "ChangePlane"
APSButton .daily -parent .userFrame.execution.frame.dir -size small -text "daily" \
  -command "set outputDir [APSGoToDailyDirectory -subdirectory btsResponse]" -packOption "-side right"
APSLabeledEntry .execution.frame.output -parent .userFrame -label "Response file: " \
  -textVariable responseFile -width 80 \
  -contextHelp "Enter a name for the output file to hold the response matrix."
bind .userFrame.execution.frame.output.entry <Leave> SetInvResponseFile
#APSLabeledEntry .execution.frame.inv -parent .userFrame -label "Inverse file: " \
#  -textVariable invResponseFile -width 80 \
 # -contextHelp "Enter a name for inverse response matrix file"

#APSButton .daily -parent .userFrame.execution.frame.output -size small -text "daily" \
#  -command "set responseFile [APSGoToDailyDirectory]" -packOption "-side right"
APSLabeledEntry .execution.frame.comment -parent .userFrame -label "Comment: " \
  -textVariable comment -width 80 \
  -contextHelp "Enter the comment what you want to be saved as a parameter in the output file."

APSFrame .ops -parent .userFrame \
  -contextHelp "Actions are started in this frame."

set abort 0
APSButton .ops.frame.setup -parent .userFrame -text "Setup SR Single Bunch Inj." -command "SetupSRSingleBunchInjection"
APSButton .ops.frame.run -parent .userFrame -text RUN -command "RunExperiment" \
  -contextHelp "Launches a sddsexperiment subprocess to collect the data."
APSButton .ops.frame.abort -parent .userFrame -text ABORT -command "exec cavput -list=Mt:SRinjectMultiStopBO.VAL=1;set abort 1"

APSButton .ops.frame.process -parent .userFrame -text ProcessRespData -command ProcessRespData \
  -contextHelp "process the reponse data."

APSButton .ops.frame.process1 -parent .userFrame -text ProcessBPMData -command ProcessBPMData \
  -contextHelp "process the bpm reponse data."



APSButton .ops.frame.inv -parent .userFrame -text "InvRespMatrix" \
  -command RecalculateInv \
  -contextHelp "recimpute the inverse matrix with different combinations of actuators/measurements and minimum singular value ratio."

APSFrame .ops1 -parent .userFrame
#APSButton .ops1.frame.arm -parent .userFrame -text "Arm single turn SR BPMs" -command "ArmSRBPMs"
#APSButton .ops1.frame.switch1 -parent .userFrame -text "Switch to Continuous Beam" -command "SwitchToBeam -beam 1"
#APSButton .ops1.frame.switch2 -parent .userFrame -text "Switch to Injection Only" -command "SwitchToBeam -beam 0"

APSButton .ops1.frame.setupbpm -parent .userFrame -text "Verify Beam and BPM" -command "VerifyBeamAndBPM"
#APSFrame .ops2 -parent .userFrame
APSButton .ops1.frame.adt -parent .userFrame -text "bts2S2 ADT" -command "exec  adt -geometry +30+0 -f /home/helios/oagData/ADTFiles/bts/bts2S2bpm.pv &"
#APSButton .ops1.frame.arm -parent .userFrame -text "Setup on-axis" \
#  -command "SetupOnAxis -normal 0"
APSButton .ops1.frame.switch1 -parent .userFrame -text "Setup nornaml injection" \
  -command "SetupOnAxis -normal 1"

APSButton .ops1.frame.strip -parent .userFrame -text "SR BPM StripTool" -command "exec StripTool /home/helios/BOOSTER/StripToolConfig/SRSingleTurnBPMXConfig &;exec StripTool /home/helios/BOOSTER/StripToolConfig/SRSingleTurnBPMYConfig &" 

proc ArmSRBPMs {} {
    if [catch { exec cavput -list=S40,S1,S2 -list=A,B -list=:singleTurn:Enable=1 -pend=30 } result] {
        return -code error "Error arming SR bpms:$result"
    }
}


proc SetupOnAxis {args} {
    set normal 0
    set IK3 7.44
    set IK4 10
    set AH2 -14.95
    set AH1 -0.07
    APSParseArguments {normal IK3 IK4 AH1 AH2} 

    if !$normal {
        if [catch {exec cavget -list=S-DCCT:CurrentM -pend=30 -printErrors } current] {
            return -code error "Error reading SR current: $current!"
        }
        if {$current>0.5} {
            return -code error "There is stored beam in the ring, please dump it first!"
        }
        SetMainStatus "setup on-axis... waiting 20 seconds, please be patient..."
        exec cavput -pend=20 -list=Mt:SRinjectZeroBucketsBO=1,Mt:SRinjectBunchCntCC.VAL=0 
        exec cavput -pend=20 -list=S:IK3:VoltageSetSendAO=8.4,S:IK4:VoltageSetSendAO=12
        exec cavput -list=S39A:H1,S39A:H2 -list=:ControlSrcBO=Maintenance
        after 1000
        exec cavput -list=S39A:H2:CurrentAO=100,S39A:H1:CurrentAO=100
        SetMainStatus "Set S40, S1, S2 sextupoles magnets to zero..."
        if [catch {exec cavput -list=S -list=40,1,2 -list=A:S -list=1,2,3,4 -list=:CurrentAO=0 -pend=10
            exec cavput -list=S -list=40,1,2 -list=B:S -list=1,2,3 -list=:CurrentAO=0 -pend=10} result] {
            return -code error "Error seting S40, S1 and S2 sextuples to zero: $result"
        }
        after 10000
        
       # after 20000
       # exec cavput -list=S39A:H1,S39A:H2 -list=:ControlSrcBO=Operation
    } else {
        SetMainStatus "setup normal operation...."
        exec cavput -pend=20  -list=S:IK3:VoltageSetSendAO=$IK3,S:IK4:VoltageSetSendAO=$IK4
        exec cavput -list=S39A:H1,S39A:H2 -list=:ControlSrcBO=Maintenance
        after 1000
        exec cavput -list=S39A:H2:CurrentAO=$AH2,S39A:H1:CurrentAO=$AH1
        after 10000
        exec cavput -list=S39A:H1,S39A:H2 -list=:ControlSrcBO=Operation
        if [catch {exec sddsprocess /home/helios/oagData/SCR/snapshots/SR/SR-UserBeamReference.gz \
                     -match=col,ControlName=S*:S?:CurrentAO -pipe=out \
                     | sddscasr -pipe=in -restore -pend=30} result] {
            return -code error "Error restoring sextuple setting: $result"
        }
        APSInfoWindow .info -modal 1 -name "Standandize sextuples" -infoMessage "Please standardize sextuples to UBOP for normal operation! Press ok when it is done."
        
    }
    SetMainStatus "done."
}

proc SetupSRBPM {args} {
    global SRInjMode 
    
    switch $SRInjMode {
        continuous {
            if [catch {exec cavput -list=Mt:SRinjectMaxCyclesAO.VAL=300,Mt:SRinjectModeBO.VAL=1,Mt:SRinjectNumBunchesAO=1 -pend=10 
                exec cavput -list=S40,S1,S2 -list=A,B -list=:singleTurn:AutoRestart=1 -pend=10 
                exec cavput -list=S40,S1,S2 -list=A,B -list=:singleTurn:Enable=1 -pend=10
                exec cavput -list=S40,S1,S2 -list=A,B -list=:clientEvent2d.OUT1=0 
                exec cavput -list=S40,S1,S2 -list=A,B -list=:clientEvent2d.OUT0=1 } result] {
                return -code error "Error setup sr bpm: $result"
            }
        }
        single {
            if [catch {exec cavput -list=Mt:SRinjectMaxCyclesAO.VAL=1,Mt:SRinjectModeBO.VAL=1 -pend=10 
                exec cavput -list=S40,S1,S2 -list=A,B -list=:singleTurn:AutoRestart=0 -pend=10 
                exec cavput -list=S40,S1,S2 -list=A,B -list=:singleTurn:Enable=1 -pend=10
                exec cavput -list=S40,S1,S2 -list=A,B -list=:clientEvent2d.OUT1=1 
                exec cavput -list=S40,S1,S2 -list=A,B -list=:clientEvent2d.OUT0=0 } result] {
                return -code error "Error setup sr bpm: $result"
            }
        }
    }
}

proc SwitchToBeam {args} {
    set beam 1
    APSParseArguments {beam}

    if !$beam {
        #injection
        if [catch {exec cavput -list=S40,S1,S2 -list=A,B -list=:clientEvent2d.OUT0=0
            exec cavput -list=S40,S1,S2 -list=A,B -list=:clientEvent2d.OUT1=1 } result] {
            return -code error "Error switch to beam: $result"
        }
    } else {
        #continuous
        if [catch {exec cavput -list=S40,S1,S2 -list=A,B -list=:clientEvent2d.OUT1=0
            exec cavput -list=S40,S1,S2 -list=A,B -list=:clientEvent2d.OUT0=1 } result] {
            return -code error "Error switch to injection only: $result"
        }
    }
}

proc RecalculateInv {args} {
    global responseFile invResponseFile
    if ![file exist $responseFile] {
        return -code error "The response file does not exist!"
    }
    SetMainStatus "InvRespMatrix does not work now, checking it..."
  #  exec InvRespMatrix -inputFile $responseFile -outputFile $invResponseFile &
}

proc LoadVariableData {} {
    global env varScroll configDir responseFile
    if ![info exist configDir] {
	set configDir [file dirname $responseFile]
    }
    set filename [APSFileSelectDialog .chooseInputFile -width 40 -path $configDir]
    if [string length $filename]==0 { 
        return 
    }
    if [string first " " $filename]!=-1 {
        SetMainStatus "Filename may not have spaces in it."
        return
    }
    if {![APSCheckSDDSFile -fileName $filename]} {
        SetMainStatus "$filename is not an SDDS file."
        return
    }
    set configDir [file dirname $filename]
    set colNames [APSGetSDDSNames -fileName $filename -class column]
    if {[llength $colNames]<1} {
        SetMainStatus "$filename doesn't contain any data columns from which to get PV names."
        return 
    }
    if {[lsearch -exact $colNames "ControlName"]!=-1} {
        set columnName ControlName
    } elseif {[lsearch -exact $colNames "Device"]!=-1} {
        set columnName Device
    } else {
        SetMainStatus "$filename doesn't contain any data columns from which to get PV names."
        return
    }
    set names [exec sdds2stream $filename -col=$columnName -page=1]
    if {[llength $names]==0} {
        SetMainStatus "$filename has no process variable names."
        return
    }
    if [lsearch -exact $colNames SymbolicName]>=0 {
        set symbols [exec sdds2stream $filename -col=SymbolicName -page=1]
    } else {
        set symbols $names
    }
    set initialValues ""
    if [lsearch -exact $colNames "InitialValue"]!=-1 {
        set initialValues [exec sdds2stream $filename -column=InitialValue -page=1]
    } else {
        for {set i 0} {$i< [llength $names]} {incr i} {
            lappend initialValues 0
        }
    }
    set finalValues ""
    if [lsearch -exact $colNames "FinalValue"]!=-1 {
        set finalValues [exec sdds2stream $filename -column=FinalValue -page=1]
    } else {
        for {set i 0} {$i< [llength $names]} {incr i} {
            lappend finalValues 0
        }
    }
    set relativeValues ""
    if [lsearch -exact $colNames "Relative"]!=-1 {
        set relativeValues [exec sdds2stream $filename -column=Relative -page=1]
    } else {
        for {set i 0} {$i< [llength $names]} {incr i} {
            lappend relativeValues 0
        }
    }
    
    ClearVarSettings $varScroll 0
    foreach name $names symbol $symbols init $initialValues final $finalValues relative $relativeValues {
        MakeNewVariableLine $varScroll -pvName $name  -symbolName $symbol \
          -initVal [format %.3f $init] -finalVal [format %.3f $final] -relative $relative
    }
    SetMainStatus "Measurement data loaded from $filename."
}

proc SaveVariableData {args} {
    global plane Hcorrectors Hcorrector Vcorrectors Vcorrector
    set filename ""
    APSParseArguments {filename}
    set pvList ""
    set symbolList ""
    set initList ""
    set finalList ""
    set relativeList ""
    set corrs [set ${plane}correctors]
    for {set i 1} {$i<$corrs} {incr i} {
        if [set ${plane}corrector($i.checked)] {
            set pvName [set ${plane}corrector($i.PV)]
	    if [catch {SearchPVName -pvName $pvName} result] {
		SetMainStatus "$result"
		continue
	    } else {
		lappend pvList $pvName
                lappend initList [set ${plane}corrector($i.init)]
		lappend finalList [set ${plane}corrector($i.final)]
                lappend relativeList [set ${plane}corrector($i.relative)]
                set symbol [set ${plane}corrector($i.symbol)]
                if [string length $symbol] {
                    lappend symbolList $symbol
                } else {lappend symbolList $pvName }
            }
        }
    }
    if ![llength $pvList] {
        SetMainStatus "No correctors specified--can't save."
        return
    }
    if ![string length $filename] {
	global configDir  responseFile
	if ![info exist configDir] {
	    set configDir [file dirname $responseFile]
	}
	set filename [APSFileSelectDialog .choosedirectory -listDir $configDir \
			  -title "output file for saving variable configuration" -checkValidity 0 ] 
    }
    if [string length $filename]==0 {
        SetMainStatus "Filename is provided!"
        return
    }
    set configDir [file dirname $filename]
    if [string first " " $filename]!=-1 {
        SetMainStatus "Filename may not contain spaces--nothing saved."
        return
    }
    if [file exist $filename] {
        if ![APSYesNoPopUp "$filename already exist, overwrite it?"] {
            SetMainStatus "configuration saving is cancelled."
            return
        }
	exec rm $filename
    }
    if [catch {exec sddsmakedataset $filename -defaultType=string -col=ControlName -data=[join $pvList ,] \
                 -col=ReadbackName -data=[join $pvList ,] \
		   -col=SymbolicName -data=[join $symbolList ,] \
		   -col=InitialValue,type=double -data=[join $initList ,] \
		   -col=FinalValue,type=double -data=[join $finalList ,] \
		   -col=Relative,type=short -data=[join $relativeList ,] } result] {
        return -code error "makedataset(2): $result"
    }
    SetMainStatus "Save completed to file $filename."
}

proc ProcessNewData {args} {
    set symbol ""
    set rootname ""
    APSParseArguments {symbol rootname}
    
    set combineFiles ""
    for {set step 0} {$step<=100} {incr step} {
	set files [glob -nocomplain ${rootname}_${symbol}_*.$step.ave]
	if ![llength $files] {
	    break
	}
	if [catch {eval exec sddscombine $files -pipe=out -merge \
		       | sddsprocess -pipe -process=$symbol,ave,$symbol \
		       -process=*S*P*,ave,%s \
		       | sddscollapse -pipe=in ${rootname}_$symbol.$step } result] {
	    return -code error "Error averaging data for $symbol at step $step: $result"
	}
	lappend combineFiles ${rootname}_${symbol}.$step
    }
    if ![llength $combineFiles] {
	return
    }
    if [catch {eval exec sddscombine $combineFiles -merge ${rootname}_${symbol}.resp } result] {
	return -code error "Error creating response file for $symbol: $result"
    }
}

set outputListLength 0
proc RunExperiment {} {
    global doStd doSigma Average comment startCorrList InitValue FinalValue Relative plane
    global responseFile inputFile experimentDone minimum invResponseFile
    global PostChangePause interval Steps  measBTS measSRH measSRV
    global numToAverage doStd doSigma VarSymName saveRawData rampSteps VarPVname SRInjMode IK3 IK4 AH1 AH2 cycles

    if {$measSRH || $measSRV} {
        while {1} {
            if [catch {exec cavget -list=S-DCCT:CurrentM -pend=30 -printErrors } current] {
                return -code error "Error reading SR current: $current!"
            }
            if {$current>0.5} {
                APSInfoWindow [APSUniqueName .] -name Message -width 30 -infoMessage "There is stored SR beam now,please dump the beam before run the experiment!" \
                  -modal 1
            } else {
                break
            }
        }
        if {$SRInjMode=="continuous"} {
            SetMainStatus "in continuous mode, BTS can be measured with SRH or SRV together, do not need to measure it separately"
            set measBTS 0
        }
    }
    #search for controlname
    
    if [catch {SaveDefinitionFile -plane $plane} result] {
        SetMainStatus "$result"
        return
    }
    SetMainStatus "Checking and creating files ...."
   
    if {[string length $responseFile]==0 || [file isdirector $responseFile]} {
        SetMainStatus "Supply the response filename."
        bell
        return
    }
    if {[string length $invResponseFile]==0 || [file isdirector $invResponseFile]} {
        SetMainStatus "Supply the inverse response filename."
        bell
        return
    }
    if ![string match "*.resp" $responseFile] {
        set responseFile ${responseFile}.resp
    }
    if {[file exists $responseFile]} {
        set ok [APSYesNoPopUp "$responseFile already exists, overwrite it?"]
        if {!$ok} {
            SetMainStatus "Supply a new response matrix filename"
            return
        } else {
            exec rm $responseFile
        }
    }
    if {[file exists $invResponseFile]} {
        set ok [APSYesNoPopUp "$invResponseFile already exist, overwrite it?"]
        if {!$ok} {
            SetMainStatus "Supply a new inverse response filename"
            return
        } else {
            exec rm $invResponseFile
        }
    }
    
    #save measurements into a file
    if $saveRawData {
        set outDir [file dirname $responseFile]/rawData
        set rootname [file tail $responseFile]
        if ![file exist $outDir] {
            if [catch {exec mkdir -p $outDir} result] {
                SetMainStatus "Can not make directory $outDir: $result."
                return
            }
        }
    }
    
    SetMainStatus "Suspending BTS controllaw..."
    if [catch {exec cavput -list=BTS:ControlLaw -list=X,Y -list=RC.SUSP=1 -pend=10} result] {
        return -code error "Error suppending BTS controllaw: $result"
    }
    
    SetMainStatus "starting experiment..."
    #for each plane, need do measurement at different conditions with the same correctors
    #1, meas bts bpms
    #2, meas H plane SR bpms
    #3, meas V plane SR bpms
    
    set respFileList ""
    
    set inputDir  /home/helios/oagData/BTS.old/responseMeasurement
    set scrDir /home/helios/oagData/SCR/snapshots/SBPMWaveform
    
    if [catch {TogglePulsedMagnetEnables -location GunToBoosterExt} result] {
        return -code error "Error enable booster beam to extraction: $result"
    }
    if {$measSRH || $measSRV} {
        if [catch {SetupOnAxis} result] {
            return -code error "Error setup onaxis for SR: $result"
        }
    }
    foreach type {BTS SRH SRV} {
        if ![set meas$type] {
            continue
        }
        set expFile $inputDir/btsResponseMeasTemplate${plane}.exp
        switch $type {
            BTS {
                set RAMfile ""
                #   set expFile $inputDir/btsResponseMeasTemplate${plane}.exp
                set measFile $inputDir/BTS.meas
            }
            SRH {
                set RAMfile $scrDir/SBPMWaveform-singleXBTS.gz
                if {$SRInjMode=="single"} {
                    set expFile $inputDir/bts_sr_ResponseMeasTemplate${plane}.exp
                    set measFile $inputDir/Sbpm.meas.H
                } else {
                    set expFile $inputDir/bts_sr_ResponseMeasTemplateContin${plane}.exp
                    set measFile $inputDir/BTS-SR.meas
                }
            }
            SRV {
                set RAMfile $scrDir/SBPMWaveform-singleYBTS.gz
                if {$SRInjMode=="single"} {
                    set expFile $inputDir/bts_sr_ResponseMeasTemplate${plane}.exp
                    set measFile $inputDir/Sbpm.meas.V
                } else {
                    set expFile $inputDir/bts_sr_ResponseMeasTemplateContin${plane}.exp
                    set measFile  $inputDir/BTS-SR.meas
                }
            }
        }
        if [string length $RAMfile] {
            SetMainStatus "Loading SBPMWaveform RAM file $RAMfile..."
            set filename [file readlink $RAMfile]
            set dir /home/helios/oagData/SCR/snapshots/SBPMWaveform
            if [catch {exec sddscasr $filename -restore -pendIOTime=60 \
                         -waveform=directory=$dir,onefile,rootname=[file rootname [file tail $filename]],extension=.waveform.gz } result] {
                SetMainStatus "Error loading ram file: $result"
                return
            }
        }
        SetMainStatus "starting experiment scan..."
        
        if $saveRawData {
            set tmpRoot ${outDir}/${rootname}_$type
        } else {
            set tmpRoot /tmp/[APSTmpString]_$type
        }
        set respFile $responseFile.$type
        if [catch {doExperiment -tmpRoot $tmpRoot -type $type \
                     -inputFile $expFile -measFile $measFile -responseFile $respFile} result] {
            SetMainStatus "Error meas $type reponse: $result"
            return
        }
        lappend  respFileList $responseFile.$type
    }
    
    if [catch {RestoreOpsState} result] {
        SetMainStatus "Error restore ops state: $result"
    }
    
    if [catch {ProcessRespData } result] {
        SetMainStatus "erorr processing response data: $result"
        return
    }

    SetMainStatus "Resuming BTS controllaw..."
    if [catch {exec cavput -list=BTS:ControlLaw -list=X,Y -list=RC.SUSP=0 -pend=10} result] {
        return -code error "Error resuming BTS controllaw: $result"
    }
    
    SetMainStatus "done for $plane plane."
}

proc RestoreOpsState {args} {
    global SRInjMode IK3 IK4 AH1 AH2
    if {$SRInjMode=="continuous"} {
        SetMainStatus "Stop injection..."
        if [catch {exec cavput -list=Mt:SRinjectMultiStopBO.VAL=1 -pend=30} result] {
            SetMainStatus "Error stop injection: $result"
        }
        if [catch {exec cavput -list=Mt:SRinjectMaxCyclesAO.VAL=1 -pend=30} result] {
            SetMainStatus "Error changing max. injection cycles to 1: $result"
        }
    }
    if [catch {SetupOnAxis -normal 1 -IK3 $IK3 -IK4 $IK4 -AH1 $AH1 -AH2 $AH2} result] {
        return -coe error "Error restore normal ops: $result"
    }
}

proc SearchPVName {args} {
    set pvName ""
    APSParseArguments {pvName}
    if ![string length $pvName] {
        return
    }
    if [catch {exec cavget -list=$pvName -pend=10} result] {
       return -code error "$pvName not found: $result"
    }
    if {$result=="?"} {
        return -code error "$pvName not found"
    }
}

proc ProcessVariableFiles {args} {
    set processList ""
    set outputFile ""
    APSParseArguments {processList outputFile}
    
    if ![llength $processList] {return -code error "Input files are not provided!"}
    if ![string length $outputFile] { return -code error "output file is not given!"}
    set firstFile [lindex $processList 0]
    if ![regexp {\.(.*)} $firstFile a variable] {
        return -code error "Invalid filename provided."
    }
    set columnNames [exec sddsquery $firstFile -col]
    set readbacks ""
    
    foreach col $columnNames {
        if {$col=="ElapsedTime" || $col=="Time" || $col=="TimeOfDay"} {continue}
        if [string compare $col $variable]==0 {continue}
        lappend readbacks $col
    }
    set tmpRoot /tmp/[APSTmpString]
    foreach file $processList {
        if ![regexp {\.(.*)} $file a variable] {
            return -code error "Invalid filename provided."
        }
        foreach readback $readbacks {
            if [catch {exec sddspfit $file -col=$variable,$readback -pipe=out \
                         | sddsconvert -pipe -rename=par,Slope=${Readback}_Slop \
                     } result] {
                return -code error $result
            }
            
        }
        
    }
}

proc SetInvResponseFile {} {
    global responseFile invResponseFile definitionFile
    if [regexp {(.*)\.} $responseFile a name] {
        set invResponseFile $name.inv
        set definitionFile $name.def
    } else {
        set invResponseFile $responseFile.inv
        set definitionFile $responseFile.def
    }
}

proc SaveDefinitionFile {args} {
    global definitionFile  MeasPVname MeasSymName VarPVname VarSymName VariableLines
    set plane ""
    APSParseArguments {plane}
    
    global outputDir Xcorrectors Xcorrector Ycorrectors Ycorrector
    global Hcorrectors Hcorrector Vcorrectors Vcorrector
    set definitionFile $outputDir/$plane.def
    SetMainStatus "save definition file..."
    set measFile /home/helios/oagData/BTS.old/responseMeasurement/BTS-SR.meas
    set controlNameList [join [exec sdds2stream -col=ControlName $measFile]]
    set symbolNameList [join [exec sdds2stream -col=SymbolicName $measFile]]
    
    
    for {set i 0} {$i<[set ${plane}correctors]} {incr i} {
        lappend controlNameList [string trim [set ${plane}corrector($i.PV)]]
        lappend symbolNameList  [string trim [set ${plane}corrector($i.symbol)]]
    }
    if [catch {exec sddsmakedataset -defaultType=string -col=ControlName \
                 -data=[join $controlNameList ,] \
                 -col=SymbolicName -data=[join $symbolNameList ,] \
                 $definitionFile } result] {
        return -code error "makedataset(1): $result"
    }
    SetMainStatus "Definitions are save to $definitionFile!"
   
}

proc SetInvResponseFile {} {
    global responseFile invResponseFile definitionFile
    if [regexp {(.*)\.} $responseFile a name] {
        set invResponseFile $name.inv
        set definitionFile $name.def
    } else {
        set invResponseFile $responseFile.inv
        set definitionFile $responseFile.def
    }
}

proc PlotResponseData {args} {
    global responseFile invResponseFile
    set dir [file dir $responseFile]
    if ![file exist $dir/rawData] {
        SetMainStatus "No data found"
        return
    }
    cd $dir/rawData
    set files [glob *.resp]
    set tmpRoot /tmp/[APSTmpString]
    if ![llength $files] {
        SetMainStatus "No data found"
        return
    }
    foreach file $files {
        set cols [exec sddsquery -col $file]
        set corr [lindex $cols 3]
        if [regexp {H} $corr] {
            set coord x
        } else {
            set coord y
        }
        exec sddsplot $file -grap=line,vary -layout=2,5  \
          -col=$corr,*region0*:$coord -topline=region0 -endp \
          -col=$corr,*region1*:$coord -topline=region1 -endp \
          -col=$corr,*region2*:$coord -topline=region2 -endp \
          -col=$corr,*region3*:$coord -topline=region3 -endp \
          -col=$corr,*region4*:$coord -topline=region4 -endp \
          -col=$corr,*region5*:$coord -topline=region5 -endp \
          -col=$corr,*region6*:$coord -topline=region6 -endp \
          -col=$corr,*region7*:$coord -topline=region7 -endp \
          -col=$corr,*region8*:$coord -topline=region8 -endp \
          -col=$corr,*region9*:$coord -topline=region9 -endp &
    }
}

proc doExperiment {args} {
    set tmpRoot ""
    set measFile ""
    set responseFile ""
    set inputFile ""
    set type BTS
    APSParseArguments {tmpRoot measFile responseFile inputFile type}

    global experimentDone numToAverage doStd doSigma Steps comment
    global PostChangePause interval rampSteps coeff saveRawData SRInjMode
    global plane Hcorrectors Hcorrector Vcorrectors Vcorrector abort cycles
    
    set corrs [set ${plane}correctors]
    set fileList ""
    set processList ""
    set readbacks [exec sddsprocess $measFile -pipe=out "-match=col,SymbolicName=*sum,!" \
       | sdds2stream -pipe=in -col=SymbolicName -page=1]
    set bpmFileList ""
    if [regexp {SR} $type] {
        SetMainStatus "setup sr bpms: ..."
        if [catch {SetupSRBPM} result] {
            return -code error "Error setup sr bpms: $result"
        }
        if { $SRInjMode=="Continuous"} {
            SetMainStatus "Starting injection..."
            if [catch {exec cavput -list=Mt:SRinjectMultiBO.VAL=1 -pend=30} result] {
                return -code error "Error start injecting: $result"
            }
        }
        SetMainStatus "done."
    } else {
        #measBTS with normal mode
        global IK3 IK4 AH1 AH2
        #if [catch {SetupOnAxis -normal 1} result] {
        #    return -code error "Error setup normal operation for BTS measurement: $result"
        #}
        if [catch {exec cavput -list=Mt:SRinjectMultiStopBO.VAL=1 -pend=30} result] {
            return -code error "Error stop injection: $result"
        }
    }
    set optList ""
    for {set i 0} {$i<$corrs} {incr i} {
        set checked [set ${plane}corrector($i.checked)]
        if !$checked {
            continue
        }
        set pv [set ${plane}corrector($i.PV)]
        set symbol [set ${plane}corrector($i.symbol)]
        set relative  [set ${plane}corrector($i.relative)]
        set init [set ${plane}corrector($i.init)]
        set final [set ${plane}corrector($i.final)]
        if ![string length $pv] {
            #in case the pv name is not provided
            continue
        }
        SetMainStatus "$type scan $pv ..."
        
        set experimentDone 0
        if !$saveRawData {
            APSAddToTmpFileList -ID response -fileList ${tmpRoot}_$symbol.resp
        } else {
            set file ${tmpRoot}_$symbol.resp
            if [file exist $file] {
                if ![APSYesNoPopUp "$file already exist, overwrite it?"] {
                    SetMainStatus "$file already exist."
                    return
                } else {
                    file delete -force $file
                }
            }
        }
        lappend processList ${tmpRoot}_$symbol.resp
       
        set macro -macro=monitorFile=$measFile,numToAve=$numToAverage,stddev=$doStd,sigma=$doSigma,actuatorName=$pv,columnName=$symbol,nPoints=$Steps,initialValue=$init,finalValue=$final,relative=$relative,postChangePause=$PostChangePause,interval=$interval,rampSteps=$rampSteps,cycles=$cycles
	
        if {$SRInjMode=="continuous" && [regexp {SR} $type]} {
            #start injection
            SetMainStatus "start injection..."
            if [catch {TogglePulsedMagnetEnables -location GunToBoosterExt} result] {
                return -code error "Error enable booster beam: $result"
            }
            if [catch {exec cavput -list=Mt:SRinjectMultiBO.VAL=1 -pend=30} result] {
                return -code error "Error starting injection: $result"
            }
        }
	if {$symbol=="B2C8V"} {
            #reload reference ramp
            catch { exec ramploadnew /home/helios/oagData/booster/ramps/correctors/lattices/default/HVCorr.ramp}
        }
	SetMainStatus "scanning $pv ..."
	set experimentDone 0
	APSExecLog .runExp -width 80 -unixCommand \
	    "sddsexperiment $inputFile ${tmpRoot}_${symbol}.sdds $macro \"-comment=[APSMakeSafeQualifierStringForEval $comment]\" -verbose" \
	     -cancelCallback "set experimentDone cancelled" \
	    -abortCallback "set experimentDone aborted" \
	    -callback "set experimentDone done"
	tkwait variable experimentDone
	if {$symbol=="B2C8V"} {
            #reload reference ramp
            catch { exec ramploadnew /home/helios/oagData/booster/ramps/correctors/lattices/default/HVCorr.ramp}
        }
	if [catch {exec sddsenvelope ${tmpRoot}_${symbol}.sdds -pipe=out -mean=* \
		       | sddsconvert -pipe=in ${tmpRoot}_${symbol}.resp -edit=col,*,%/Mean// } result] {
	    return -code error "Error processing response data1: $result"
	}
        #if [catch {eval exec sddscombine $combineFiles -merge ${tmpRoot}_${symbol}.resp } result] {
	 #   return -code error "Error creating response file for $symbol: $result"
	#}
        if {[regexp {SR} $type] &&  $SRInjMode=="continuous"} {
            SetMainStatus "Stop injection..."
            if [catch {exec cavput -list=Mt:SRinjectMultiStopBO.VAL=1 -pend=30} result] {
                return -code error "Error stop injection: $result"
            }
        }
        if {$experimentDone!="done"} {
            if [catch {RestoreOpsState} result] {
                return -code error $result
            }
            return -code error "scan was $experimentDone."
        }
        #average the monitor data
	

        #process data
        if $saveRawData {
            APSAddToTmpFileList -ID response -fileList ${tmpRoot}_$symbol.slope
        }
        if [catch {exec sddsslopes ${tmpRoot}_$symbol.resp ${tmpRoot}_$symbol.slope \
                     -independentVariable=$symbol -col=[join $readbacks ,] \
                     -exclude= } result] {
            return -code error "Error in getting slopes: $result; Inverse response matrix is not created"
        }
       
        set col ""
        set color 0
        foreach meas $readbacks {
            append col " -col=$symbol,$meas -graph=sym,scale=2,connected,type=$color,sub=$color"
            incr color
        }
       # eval exec sddsplot ${tmpRoot}_$symbol.resp -legend $col &
        lappend fileList ${tmpRoot}_$symbol.slope
        if ![info exist coeff($symbol)] {
            set coeff($symbol) 1.0
        }
        if [catch {exec sddsconvert ${tmpRoot}_$symbol.slope -delete=col,*Intercept -pipe=out \
                     | sddstranspose -pipe \
                     | sddsconvert -pipe -rename=col,OldColumnNames=BPMNames \
                     | sddsprocess -pipe=in -reedit=col,BPMNames,%/Slope// \
                     "-redefine=col,$symbol,$symbol $coeff($symbol) /,units=m/rad" \
                     ${tmpRoot}_$symbol.bpm } result] {
            return -code error $result
        }
        lappend bpmFileList ${tmpRoot}_$symbol.bpm
        lappend optList -col=BPMNames,$symbol  ${tmpRoot}_$symbol.bpm
    }
    #puts $optList
    set len [llength $bpmFileList]
    set n [expr int(($len+2)/3)]
    eval exec  sddsplot -split=page -sep -layout=3,$n -gra=sym,connect,scale=2  $optList &
    if [catch {exec cavput -list=Mt:SRinjectMultiStopBO.VAL=1 -pend=30} result] {
        return -code error "Error stop injection: $result"
    }
    foreach meas $readbacks {
        lappend renames ${meas}Slope=${meas}
    }
    if ![llength $bpmFileList] {
        return -code error "No reponse file generated!"
    }
    #puts $bpmFileList
    if [llength $bpmFileList]>1 {
        if [catch {eval exec sddsxref $bpmFileList -leave=BPMNames -pipe=out \
                 | sddsprocess -pipe=in $responseFile -reprint=par,SRInjectionMode,$SRInjMode } result] {
            return -code error "Error combining response file: $result"
        }
    } else {
        if [catch {exec sddsprocess [lindex $bpmFileList 0] $responseFile \
                     -reprint=par,SRInjectionMode,$SRInjMode } result] {
            return -code error "Error defining SR inj mode parameter for response file: $result"
        }
    }
    return 
}

proc ComputeISKicker {args} {
    global coeff
    set energy ""
    APSParseArguments {energy}
    
    set E0 7000
    set BRho7G 33.3377
    set energy 7000
    
    set BRho [expr $BRho7G * $energy / $E0]
    ### units: T-m
    set IS1_bdl 1.89
    set IS2_bdl 0.7665
    #set IS1_kick [expr $IS1_bdl / $BRho * 1000]
    set IS1_kick  [expr 0.07352759 * 1000]
    #set IS2_kick [expr $IS2_bdl / $BRho * 1000]
    set IS2_kick  [expr 0.03276141 * 1000]
    set IS1_setp 1234.5
    set IS2_setp 715.1
    set IS1_mradPerVolt [expr $IS1_kick / $IS1_setp]
    set IS2_mradPerVolt [expr $IS2_kick / $IS2_setp]
   # puts "IS1: $IS1_mradPerVolt IS2: $IS2_mradPerVolt"
    set coeff(IS1) ${IS1_mradPerVolt}
    set coeff(IS2) ${IS2_mradPerVolt}
}

# if [catch {exec cavget -list=S:IK3:VoltageSetSendAO,S:IK4:VoltageSetSendAO,S39A:H1:CurrentAO,S39A:H2:CurrentAO -pend=30 } valList] {
#     return -code error "Error reading pvs: $valList"
# }

set IK3 [lindex $valList 0]
set IK4 [lindex $valList 1]
set AH1 [lindex $valList 2]
set AH2 [lindex $valList 3]

set kickerFile /home/helios/oagData/BTS.old/responseMeasurement/correctorKickScaling.kick
set corrName [exec sdds2stream -col=corrName $kickerFile]
set mradPerAmp [exec sdds2stream -col=mradPerAmp $kickerFile]
foreach corr $corrName  val $mradPerAmp {
    set coeff($corr) $val
}
set coeff(B2C8V) 1.0
ComputeISKicker

#catch {exec cavput -list=B:B2C8V:CorrectionAI=0}
