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

#
# $Log: not supported by cvs2svn $

set auto_path [linsert $auto_path 0 /usr/local/oag/apps/lib/$env(HOST_ARCH)]
set auto_path [linsert $auto_path 0 /usr/local/oag/lib_patch/$env(HOST_ARCH)]
APSDebugPath

set CVSRevisionAuthor "\$Revision: 1.1 $ \$Author: shang $"

APSApplication . -name "BoosterHVOrbitCorrection" -version $CVSRevisionAuthor \
  -overview "combine booster hv correction config into one."

set Status ""
APSScrolledStatus .status -parent .userFrame -width 100 \
  -textVariable Status 

proc SetStatus {text} {
    global Status
    set Status $text
    update
}

proc GenerateFiles {args} {
    set plane ""
    APSParseArguments {plane}

    global dataDir hConfigDir vConfigDir hRegion vRegion

    set tmpRoot /tmp/[APSTmpString]
    set config [set ${plane}ConfigDir]
    cd $dataDir/$config
   # set region [lindex [exec sdds2stream -par=TimeRegion config] 0]
    set region region[set ${plane}Region]
    switch $plane {
        h {
            set ext :${region}:x:ErrorCC
        }
        v {
            set ext :${region}:y:ErrorCC
        }
    }
    if [catch {exec sddsprocess config -pipe=out -match=par,NameType=MonitorNames \
                 | sddsprocess -pipe -edit=col,ControlName,Name,ei/$ext/ \
                 | sddsconvert -pipe=in $tmpRoot.bpm -rename=col,Name=SymbolicName } result] {
        return -code error "GenerateFiles1: $result"
    }
    
    if [catch {exec sddsprocess config -pipe=out -match=par,NameType=CorrectorNames \
                 | sddsprocess -pipe -edit=col,ControlName,Name,ai/B:/ei/:CorrectionAI/ \
                 | sddsconvert -pipe=in $tmpRoot.corr -rename=col,Name=SymbolicName } result] {
        return -code error "GenerateFiles2: $result"
    }
    #if [catch {exec sddscombine $tmpRoot.corr $tmpRoot.bpm definitions -merge -overwrite} result] {
    #    return -code error "GenerateFiles3: $result"
    #}
    #if [catch {exec sddscasr definitions -save -pipe=out \
    #             | sddsprocess -pipe=in offsets -scan=col,Offset,ValueString,%lf } result] {
    #    return -code error "GenerateFile4: $result"
    #}
    if [catch {exec sddsprocess $tmpRoot.corr \
                 -define=col,MinimumValue,-1 -define=col,MaximumValue,1 corr.tests
        exec sddscombine $dataDir/booOrbitTest corr.tests -merge tests -overwrite } result] {
        return -code error "GenerateFile5: error creating tests file: $result"
    }

    
}

proc Abort {args} {
    set plane ""
    APSParseArguments {plane} 
    
    switch $plane {
        h {
            set coord X
            # set runcontrolPV OAG143RC
            set runcontrolPV B:OrbitControllawXSDDS
        }
        v {
            set coord Y
            # set runcontrolPV OAG144RC
            set runcontrolPV B:OrbitControllawYSDDS
        
        }
    }
    if [catch {exec cavput -list=$runcontrolPV.ABRT=1 -pend=30 } result] {
        return -code error "Error aboring $plane plane orbit correction: $result"
    }
    if [catch {exec cawait -waitfor=$runcontrolPV.RUN,equalto=0 } result] {
        return -code error "Error aboring $plane plane orbit correction1: $result"
    }
    if [catch {exec cavput -list=$runcontrolPV.CLR=1 -pend=30 } result] {
        return -code error "Error aboring $plane plane orbit correction2: $result"
    }
}

proc InstallRamp {args} {
    set plane ""
    APSParseArguments {plane}
    global logDir
    set files [glob -nocomplain $logDir/${plane}*.ramp]
    if ![llength $files] {
        SetStatus "No ramp files found for $plane plane."
        return
    }
    set lastIndex -1
    set lastTime -1
    set i 0
    foreach file $files {
        set time [file mtime $file]
        if {$time>$lastTime} {
            set lastTime $time
            set lastIndex $i
        }
        incr i
    }
    set lastFile [lindex $files $lastIndex]
    if [APSYesNoPopUp "Are you sure to install $lastFile?"] {
        set rampDir /home/helios/oagData/booster/ramps/correctors/lattices/default
        set newFile [APSNextGenerationedName -name HVCorr.ramp-0000 \
                       -separator - -newFile 1 -directory  $rampDir]
        set corrList [join [exec sdds2stream -par=CorrName $lastFile]]
        set matchOpt ""
        foreach corr $corrList {
            lappend matchOpt -match=par,CorrName=$corr,!
        }
        if [catch {eval exec  sddsprocess $rampDir/HVCorr.ramp $matchOpt $logDir/otherRamp 
                   exec sddscombine $logDir/otherRamp $lastFile -pipe=out \
                       | sddssort -pipe=in -par=CorrName $rampDir/$newFile  } result] {
            return -code error "Error generating new Ramp: $result"
        }
        set oldDir [pwd]
        cd $rampDir
        exec rm HVCorr.ramp
        exec ln -s $newFile HVCorr.ramp
        cd $oldDir
        SetStatus "new ramp table installed."
    } else {
        SetStatus "Ramp was not installed."
    }
}

proc StartOrbitCorrection {args} {
    set plane ""
    APSParseArguments {plane}

    global hConfigDir vConfigDir hRegion vRegion refRamp StartBumpList EndBumpList currentRamp referenceRamp
    global dataDir steps gain interval averages averageInterval useReference refRamp proportional logDir 
    set dir [set ${plane}ConfigDir]
    cd $dataDir/$dir

    if {![file exist tests]}  {
        if [catch {GenerateFiles -plane $plane} result] {
            return -code error "StartOrbitCorrect6ion(Error1): $result"
        }
    }
    if $useReference {
        SetStatus "Loading reference ramps..."
        if [catch {exec ramploadnew $refRamp} result] {
            return -code error "Error2: error loading reference ramp: $result"
        }
        set referenceRamp $refRamp
    } else {
        SetStatus "read current ramp table ..."
        if [catch {ReadCurrentRampTable} result] {
            return -code error "Error3: $result"
        }
        set referenceRamp $currentRamp
    }
    
    set logFile $logDir/[APSNextGenerationedName -name orbitcorr.log-0000 -newFile 1 -separator - -directory $logDir]
    
    if [catch {CreateUpdateRampScript -configDir $dir -plane $plane } result] {
        return -code error "Error4: error generate updataCorrRamp script: $result"
    }
    
    set region [set ${plane}Region]
  #  set index [scan $region region%ld]
    set definitionFile /home/helios/oagData/booster/orbitControllaw/lattices/default/${plane}Region${region}.definitions
    SetStatus "Setting booster bpm timing..."
    
    if [catch {exec setBoosterBPMTimeSeg } result] {
        return -code error "Errort5: $result"
    }
    
    SetStatus "Clear corrector settings..."
    if [catch {ResetCorrectors -plane $plane } result] {
        return -code error "Error6: $result"
    }
    
    SetStatus "arming bpms..."
    if [catch {exec cavput -list=B -range=begin=1,end=4 -list=C -range=begin=0,end=9,interval=2 -list=:intervalAvg:AutoRestart=1 -pend=30} result] {
        return -code error "Error7: $result"
    }
    
    if [catch {exec cavput -list=B -range=begin=1,end=4 -list=C -range=begin=0,end=9,interval=2 -list=:turn:gtr:arm=1 -pend=30} result] {
        return -code error "Error9: $result"
    }
    switch $plane {
        h {
            set coord X
          #  set runcontrolPV OAG143RC
            set runcontrolPV B:OrbitControllawXSDDS
        }
        v {
            set coord Y
           # set runcontrolPV OAG144RC
            set runcontrolPV B:OrbitControllawYSDDS
        }
    }
    if [catch {Abort -plane $plane} result] {
        return -code error "Error aborting $plane orbit correcton: $result"
    }
    #set runcontrolPV B:OrbitControllaw${coord}SDDS
   # exec medm -x -attach -macro RCPV=$runcontrolPV ./sr/psApp/APSRunControlSingle.adl &
    SetStatus "starting booster $plane orbit correction ..."
    
    if $proportional {
        #   set command "sddscontrollaw irm $logFile.$plane -steps=$steps -gain=$gain -interval=$interval -average=$averages,interval=$averageInterval -verbose  -controlLogFile=$logFile -testvalues=tests -proportional -controlQuantityDefinitions=definitions -postChangeExec=updateCorrRamp -offsets=offsets"
        set command "sddscontrollaw irm $logFile.$plane -steps=$steps -gain=$gain -interval=$interval -average=$averages,interval=$averageInterval -verbose  -controlLogFile=$logFile -testvalues=tests -proportional -controlQuantityDefinitions=$definitionFile -postChangeExec=$logDir/${plane}updateCorrRamp$region -runControlPV=string=$runcontrolPV,pingTimeout=30 \"-runControlDescription=string=Booster $plane Orbit Correction\""
    } else {
        #  set command "sddscontrollaw irm $logFile.$plane -steps=$steps -gain=$gain -interval=$interval -average=$averages,interval=$averageInterval -verbose  -controlLogFile=$logFile -testvalues=tests  -controlQuantityDefinitions=definitions -postChangeExec=updateCorrRamp -offsets=offsets"
        set command "sddscontrollaw irm $logFile.$plane -steps=$steps -gain=$gain -interval=$interval -average=$averages,interval=$averageInterval -verbose  -controlLogFile=$logFile -testvalues=tests  -controlQuantityDefinitions=$definitionFile -postChangeExec=$logDir/${plane}updateCorrRamp$region -runControlPV=string=$runcontrolPV,pingTimeout=30 \"-runControlDescription=string=Booster $plane Orbit Correction\""
    }
    
    if [catch {exec cavget -list=$runcontrolPV.RUN -printErrors} status] {
        return -code error "Unable to read $runcontrolPV.RUN: $status"
    }
    if $status {
        exec cavput -list=$runcontrolPV.ABRT=1 -pend=30
        SetSROrbitStatus "Waiting for $runcontrolPV to clear..."
        exec cawait -waitfor=$PV.RUN,equal=0
    }
    exec cavput -list=$runcontrolPV.CLR=1 -pend=30
    
    global ControllawDone$plane
    set ControllawDone$plane 0
    APSExecLog .borbitcorr$plane -height 30 -lineLimit 2040 -width 95 \
      -name "Booster $plane plane orbit correction" \
      -unixCommand "$command" \
      -callback "set ControllawDone$plane done" \
      -cancelCallback "set ControllawDone$plane cancelled" \
      -abortCallback "set ControllawDone$plane aborted" 
    tkwait variable ControllawDone$plane
    SetStatus "booster orbit correction for $plane Done"
}

set refRamp /home/helios/oagData/booster/ramps/correctors/lattices/default/HVCorr.ramp


proc ResetCorrectors {args} {
    set plane ""
    APSParseArguments {plane}
    global  dataDir
    SetStatus "Set original corrector amplitude to zero..."
    if [catch {exec sddscasr -restore $dataDir/${plane}corr.zero } result] {
        return -code error "$result"
    }
    #should clear :Ramp:OutOfRange pvs too, set them to zero == modify the above zero file to include them
    SetStatus "done."
}


proc Test {} {
    global dataDir hvConfig
 
    set tmpRoot /tmp/[APSTmpString]
    set testFile $dataDir/booOrbitTest
    set command \
	"sddssnapshot $testFile -pipe=output | sddsprocess -pipe \"-def=col,InBounds,MinimumValue Value < pop pop ? Value MaximumValue < pop pop ? 1 : 0 $ : 0 $,type=long\" | sddssort -pipe -col=InBounds -col=ControlName | sddsprintout -pipe=in -col=ControlName,format=%28s -col=(MinimumValue,Value,MaximumValue,InBounds)"
    APSExecLog .testInfo -unixCommand $command -width 88
    APSWaitWithUpdate -waitSeconds 1
    set data [.testInfo.userFrame.text.text get 1.0 end]
    set indexList ""
    set n 1
    foreach line [split $data \n] {
	if {[lindex $line end] == 0} {
	    append indexList "$n.0 [expr {$n + 1}].0 "
	}
	incr n
    }
    if {[llength $indexList]} {
	eval .testInfo.userFrame.text.text tag add tag1 $indexList
    }
    .testInfo.userFrame.text.text tag configure tag1 -foreground red -background black
}



proc ReadCurrentRampTable {args} {
    global currentRamp logDir refRamp

    set plane ""
    APSParseArguments {plane}
    
    set plane [string toupper $plane]
    set corrList [exec sddsprocess $refRamp -match=par,CorrName=*$plane -pipe=out | sdds2stream -pipe -par=CorrName]
    set timeList [exec sdds2stream -col=RampTime $refRamp -page=1]
    if [llength $timeList]!=20 {
        return -code error "Error: ramptime length is not 20"
    }
    set tmpRoot /tmp/[APSTmpString]
    set currentRamp $logDir/[clock format [clock seconds] -format %Y%m%d:%H%M%S].ramp.ref
    set fileList ""
    foreach corr $corrList {
        set rampsetpoint [lrange [exec caget B:${corr}:source] 2 21]
        if [catch {exec sddsmakedataset $tmpRoot.$corr -par=CorrName,type=string -data=$corr \
                     -col=RampTime,type=double -data=[join $timeList ,] \
                     -col=RampSetpoint,type=double -data=[join $rampsetpoint ,] } result] {
            return -code error "error generating ramptable:$result"
        }
        lappend fileList $tmpRoot.$corr
    }
    APSAddToTempFileList -ID obitcorr -fileList $fileList
    if [catch {eval exec sddscombine $fileList $currentRamp } result] {
        return -code error "Error generating current ramp: $result"
    }
    SetStatus "Current ramp is saved in $currentRamp."
}

proc RunTest {args} {
    set plane ""
    APSParseArguments {plane}
    global dataDir hConfigDir vConfigDir
    set testFile $dataDir/[set ${plane}ConfigDir]/tests
    set tmpRoot /tmp/[APSTmpString]$plane
    if [catch {exec sddscasr -save $testFile -pipe=out \
                 | sddsprocess -pipe -scan=col,Value,ValueString,%lf \
                 | sddsprocess -pipe=in $tmpRoot.test "-test=col,Value MinimumValue < Value MaximumValue > ||" -nowarnings } result] {
        return -code error "Testing failed: $result"
    }
    set rows [exec sdds2stream -rows=bar $tmpRoot.test]
    if !$rows {
        SetStatus "$plane plane tests passed."
        return
    } 
    if [catch {exec sddsprintout $tmpRoot.test $tmpRoot.printout -col=ControlName -col=Value,format=%.3f -col=MaximumValue,format=%.3f \
                 -col=MinimumValue,format=%.3f } result] {
        return -code error "Error print test valus: $result"
    }
    APSFileDisplayWindow .error -fileName $tmpRoot.printout -width 100 -printCommand "enscript -r"
}

proc RunADT {args} {
    set plane ""
    APSParseArguments {plane}
    global hRegion vRegion
    set region region[set ${plane}Region]
    exec adt -geometry +30+0 -f /home/helios/OAG/oagData/ADTFiles/booster/booster.bpmError.pv-${region}.pv &
    
}

set useReference 0
set transferAll 0
set hoursOnly 0
proc MakeOrbitFrame {widget args} {
    set parent ""
    global steps gain interval averages aveInterval  lattice M Einjection Eextraction itemList rampIndex rampItemList proportional
    global rampIndexH rampIndexV proportional logDir hDescription vDescription hoursOnly
    APSParseArguments {parent}
    
    APSFrame $widget -parent $parent -label "BoosterOrbitCorrection options" \
      -contextHelp "Frame to specify arguments for booster orbit correction."
    set w0 $parent$widget.frame
    APSLabeledEntry .log -parent $w0 -label "Log directory:" -width 75 -textVariable logDir
    APSFrameGrid .fg -parent $w0 -xList {x1 x2}
    set w1 $w0.fg.x1
    set w2 $w0.fg.x2
    APSLabeledEntry .steps -parent $w1 -label "steps" \
      -textVariable steps -width 10 \
      -contextHelp "Enter the number of steps to perform."
    APSLabeledEntry .gain -parent $w1 -label "gain" \
      -textVariable gain -width 10 \
      -contextHelp "Enter the gain (i.e. fraction of correction at each interval)"
    APSLabeledEntry .interval -parent $w1 -label "interval (s)" \
      -textVariable interval -width 10 \
      -contextHelp "Enter the interval between correction steps."
    APSRadioButtonFrame .hour -parent $w1 -label "save ramp file with hours only?" -buttonList {Yes No} \
      -variable hoursOnly -valueList {1 0} -orientation horizontal  \
      -contextHelp "if yes, the daily files will be truncated to hours."
    
    
    APSLabeledEntry .averages -parent $w2 -label "averages" \
      -textVariable averages -width 10 \
      -contextHelp "Enter the number of averages of bpms at each iteration."
    APSLabeledEntry .aveInterval -parent $w2 -label "interval in averaging" \
      -textVariable averageInterval -width 10 \
      -contextHelp "Enter the interval between readbacks for the bpm averaging."
   
    global useReference hvConfig dataDir filterEnd1 hvPlane rootname hvMainDir

    APSRadioButtonFrame .ref -parent $w2 -label "Use reference ramp?" -buttonList {Yes No} -variable useReference \
	-valueList {1 0} -orientation horizontal -contextHelp "if yes, the reference ramp table in /home/helios/oagData/booster/ramps/correctors/lattices/default/HVCorr.ramp will be copied to orbit correction dir and starting correction from the reference. Otherwise, the correction will continue with current ramp table in orbit correction dir."
   # APSRadioButtonFrame .mode -parent $w1 -label "Controller Mode:" -buttonList {Integral Proportional} -valueList {0 1} \
   #   -variable proportional -orientation horizontal -contextHelp "choose the controller mode intergral or proportional in orbit correction controllaw."
    APSRadioButtonFrame .transfer -parent $w2 -label "Transfer orbit for all regions?" -buttonList {Yes No} -valueList {1 0} \
      -variable transferAll -orientation horizontal -contextHelp "transfer orbit error to setpoint/offset of all region? or selected region?"

    global plane hConfigDir vConfigDir hRegion vRegion
    set regionList {0 1 2 3 4 5 6 7 8 9}
    set plane h
    set wList [APSTabFrame .plane -parent $parent -label "" -labelList {Horizontal Vertical} -width 950 -height 150]
    $parent.plane.frame.tn select 0
    set w1 [lindex $wList 0]
    set w2 [lindex $wList 1]
    APSFrame .f1 -parent $w1 
   
    #APSLabeledEntry .dir -parent $w1.f1.frame -label "Configuration" -textVariable hConfigDir -width 35 -packOption "-side left"
    #APSButton .p -parent $w1.f1.frame.dir -text F -packOption "-side right" \
    \#    -command {findDir -dirVariable hConfigDir -filter h.*} \
     \#   -contextHelp "bring up a directory selection dialog"
     APSFileSelectWidget .h -parent $w1.f1.frame  -variable hConfigDir -label "Select $plane plane config: " \
	-pathVariableList dataDir \
	-mode directory -filterVariableList  [list hPlane filterEnd1] -width 50
   
    #trace variable hConfigDir w "GetTimeRegion -plane h"
    
    #APSLabeledOutput .region -parent $w1.f1.frame -label "BPM/Corrector Time Region:" -textVariable hRegion -width 35 -packOption "-side left"
   # APSLabeledEntry .desc -parent $w1 -label "Description" -textVariable hDescription -width 100 -contextHelp "description for saving h plane correction result."
    APSRadioButtonFrame .region -parent $w1 -label "                    Select time region:     " -variable hRegion -buttonList $regionList -valueList $regionList -orientation horizontal
    APSFrame .f2 -parent $w1
    APSFrame .f3 -parent $w1
    set f2 $w1.f2.frame
    set f3 $w1.f3.frame
    APSButton .start -parent $f2 -text "Start Orbit Correction" -command "StartOrbitCorrection -plane h"
    APSButton .abort -parent $f2 -text "Abort" -command "Abort -plane h"
    APSButton .reset -parent $f2 -text "Reset Corrector" -command "ResetCorrectors -plane h" -contextHelp "set all h plane corrector ramp amplitude to zero."
   # APSButton .load -parent $w1 -text "Load Reference" -command "exec ramploadnew /home/helios/oagData/booster/ramps/correctors/lattices/default/HVCorr.ramp"
    APSButton .setpoint -parent $f2 -text "Transfer Error To Setpoint" -command "TransferOrbitToSetpoint -plane h" \
      -contextHelp "Transfer orbit error to setpoint setpoint +=Error"
   # APSButton .offset -parent $w1 -text "Transfer Error To Offset" -command "TransferOrbitToOffset -plane h" \
   #   -contextHelp "Transfer orbit error to offset, in each time region, average the errors and transfer the average to offset so that the offsets in each time region are the same."
    APSButton .adt -parent $f3 -text "BPM ADT" -command "RunADT -plane h"
    APSButton .test1 -parent $f3 -text "Test" -command "RunTest -plane h"
    APSButton .info -parent $f3 -text "Info" -command "exec medm -x -cleanup -attach -macro RCPV=B:OrbitControllawXSDDS ./sr/psApp/APSRunControlSingle.adl &"
    APSButton .install -parent $f3 -text "Install" -command "InstallRamp -plane h"
    APSFrame .f2 -parent $w2
   # APSLabeledEntry .dir -parent $w2.f2.frame -label "Configuration" -textVariable vConfigDir -width 35 -packOption "-side left"
   
  #  APSButton .p -parent $w2.f2.frame.dir -text F -packOption "-side right" \
   \#     -command {findDir -dirVariable vConfigDir -filter v.*} \
     \#   -contextHelp "bring up a directory selection dialog"
     APSFileSelectWidget .v -parent $w2.f2.frame  -variable vConfigDir -label "Select $plane plane config: " \
	-pathVariableList dataDir \
	-mode directory -filterVariableList  [list vPlane filterEnd1] -width 50 
   # trace variable vConfigDir w "GetTimeRegion -plane v"
   # APSLabeledOutput .region -parent $w2.f2.frame -label "BPM/Corrector Time Region:" -textVariable vRegion -width 35 -packOption "-side left"
   # APSLabeledEntry .description -parent $w2 -label "Description:" -textVariable vDescription -width 95 -contextHelp \
   #    "description for saving v plane correction result."

  
    APSRadioButtonFrame .region -parent $w2 -label "                    Select time region:     " -variable vRegion -buttonList $regionList -valueList $regionList -orientation horizontal
    
    APSFrame .f -parent $w2
    APSFrame .fa -parent $w2
    set f2 $w2.f.frame
    set f3 $w2.fa.frame
    APSButton .start -parent $f2 -text "Start Orbit Correction" -command "StartOrbitCorrection -plane v"
    APSButton .abort -parent $f2 -text "Abort" -command "Abort -plane v"
    APSButton .reset -parent $f2 -text "Reset Corrector" -command "ResetCorrectors -plane v" -contextHelp "set all v plane corrector ramp amplitude to zero."
   
    APSButton .setpoint -parent $f2 -text "Transfer Error To Setpoint" -command "TransferOrbitToSetpoint -plane v" \
      -contextHelp "Transfer orbit error to setpoint setpoint +=Error"
  #  APSButton .offset -parent $w2 -text "Transfer Error To Offset" -command "TransferOrbitToOffset -plane v" \
   #   -contextHelp "Transfer orbit error to offset, in each time region, average the errors and transfer the average to offset so that the offsets in each time region are the same."
    APSButton .adt -parent $f3 -text "BPM ADT" -command "RunADT -plane v"
    APSButton .test -parent $f3 -text "Test" -command "RunTest -plane v"
   
    APSButton .info -parent $f3 -text "Info" -command "exec medm -x -cleanup -attach -dg +260+5  -macro RCPV=B:OrbitControllawYSDDS ./sr/psApp/APSRunControlSingle.adl &"
    APSButton .install -parent $f3 -text "Install" -command "InstallRamp -plane v"
}



proc GetTimeRegion {args} {
    set plane ""
    APSParseArguments {plane}
    global dataDir hConfigDir vConfigDir hRegion vRegion 

    set config [set ${plane}ConfigDir]
    
    set ${plane}Region [lindex [exec sdds2stream -par=TimeRegion $dataDir/$config/config] 0]
}

proc CreateUpdateRampScript {args} {
    set configDir ""
    set plane ""
    APSParseArguments {configDir plane}
    global referenceRamp logDir dataDir hRegion vRegion logDir hoursOnly
   # set region [set ${plane}Region]
   # set region0 [scan $region region%ld]
    set region [set ${plane}Region]
    
    set fid [open $logDir/${plane}updateCorrRamp$region "w"]
    puts $fid "#!/bin/sh"
    puts $fid "# \\"
    puts $fid "exec tclsh \"\$0\" \"\$@\""
    if $hoursOnly {
        puts $fid "if \[catch \{exec makeboosterbump $dataDir/$configDir/config -dailyFile=dir=$logDir,rootname=${plane}Region${region},ext=.ramp,hoursOnly  -referenceRamp=$referenceRamp -region=$region\} result\] \{"
    } else {
        puts $fid "if \[catch \{exec makeboosterbump $dataDir/$configDir/config -dailyFile=dir=$logDir,rootname=${plane}Region${region},ext=.ramp  -referenceRamp=$referenceRamp -region=$region\} result\] \{"
    }
    puts $fid "puts stderr \$result"
    puts $fid "exit 1"
    puts $fid "\}"
    puts $fid "puts \$result"
    puts $fid "exit 0"
    close $fid
    exec chmod +x $logDir/${plane}updateCorrRamp$region
}

proc findDir {args} {
    set dirVariable ""
    set filter ""
    APSParseArguments {dirVariable filter}
    global dataDir
    cd $dataDir
}

proc TransferOrbitToSetpoint {args} {
    set plane ""
    APSParseArguments {plane}
     global hRegion vRegion transferAll
    set region [set ${plane}Region]
    
    switch $plane {
        h  {
            set coord x
            set Coord X
        }
        v {
            set coord y
            set Coord Y
        }
    }
    SetStatus "check current ..."
    
    if [catch {exec cavget -list=B:diag1:rms:A:region5 -pend=10 -printError} current] {
        return -code error "Error reading current: $current"
    }
    if {$current<1} {
        SetStatus "B:diag1:rms:A:region5 current is too low, quit orbit transfer."
        return
    }
    SetStatus "transfer $plane plane $region orbit error to setpoint..."
    set orbitFile /home/helios/oagData/booster/orbitControllaw/inputFiles/orbit.$coord
    set tmpRoot /tmp/[APSTmpString]
    APSAddToTempFileList -ID booOrbit -fileList $tmpRoot.error
    if $transferAll {
        set matchOpt ""
    } else {
        set matchOpt -match=col,ControlName=*region${region}*
    }
    if [catch {eval exec sddsprocess $orbitFile -pipe=out  \
                 $matchOpt \
                 | sddscasr -pipe -save -pend=30 \
                 | sddsprocess -pipe=in $tmpRoot.error -scan=col,ErrorCC,ValueString,%lf } result] {
        return -code error "Error reading setpoint0: $result"
    }
   
    if [catch {eval exec sddsprocess $orbitFile -pipe=out $matchOpt \
                 -reedit=col,ControlName,%/ErrorCC/SetpointAO/ \
                 | sddscasr -pipe -save -pend=30 \
                 | sddsprocess -pipe -scan=col,Setpoint0,ValueString,%lf \
                 | sddsxref -pipe $tmpRoot.error -take=ErrorCC \
                 | sddsprocess -pipe \"-define=col,Setpoint,Setpoint0 ErrorCC +\" \
                 | sddsprocess -pipe -reprint=col,ValueString,%lf,Setpoint \
                 | sddscasr -pipe=in -restore -pend=30 } result] {
        return -code error "Error transfer orbit error to setpoint: $result"
    }
    SetStatus "done."
}

proc TranfserOrbitToOffset {args} {
    set plane ""
    APSParseArguments {plane}
    global hRegion vRegion transferAll
    set region [set ${plane}Region]
    SetStatus "transfer $plane plane $region zero to offsets..."
    switch $plane {
        h  {
            set coord x
            set Coord X
        }
        v {
            set coord y
            set Coord Y
        }
    }
    if $transferAll {
        set matchOpt ""
    } else {
        set matchOpt -match=col,ControlName=*region${region}*
    }
    set orbitFile /home/helios/oagData/booster/orbitControllaw/inputFiles/orbit.$coord
    if [catch {eval exec sddsprocess $orbitFile -pipe=out \
                 $matchOpt  \
                 | sddscasr -pipe -save -pend=30 \
                 | sddsprocess -pipe -scan=col,Value,ValueString,%lf \
                 | sddsprocess -pipe -process=Value,average,AveError \
                 -reedit=col,ControlName,%/ErrorCC/OffsetAO/ \
                 -reprint=col,ValueString,%lf,AveError \
                 | sddscasr -pipe=in -restore -pend=30 } result] {
        return -code error "Error transfer orbit error to offsets: $result"
    }
    SetStatus "done."

}

proc SaveOrbitCorrectionResult {args} {
    set config ""
    set plane ""
    APSParseArguments {config plane}
    global refRamp  hDescription vDescription hRegion vRegion hConfigDir vConfigDir
    set corrDir /home/helios/oagData/booster/ramps/correctors/lattices/default/orbitCorrection
    set newName [clock format [clock seconds] -format %Y%m%d:%H%M%S].HVRamp
    set corrList [exec sdds2stream -par=CorrName $refRamp]
    set timeList [exec sdds2stream -col=RampTime $refRamp -page=1]

    set tmpRoot /tmp/[APSTmpString]
    
    foreach corr $corrList {
        set rampsetpoint [lrange [exec caget B:${corr}:source] 2 21]
        if [catch {exec sddsmakedataset $tmpRoot.$corr -par=CorrName,type=string -data=$corr \
                     -col=RampTime,type=double -data=[join $timeList ,] \
                     -col=RampSetpoint,type=double -data=[join $rampsetpoint ,] } result] {
            return -code error "error generating ramptable:$result"
        }
        lappend fileList $tmpRoot.$corr
    }
    APSAddToTempFileList -ID obitcorr -fileList $fileList
    if [catch {eval exec sddscombine $fileList $corrDir/$newName } result] {
        return -code error "Error generating current ramp: $result"
    }
    set lattice [file readlink /home/helios/oagData/booster/orbitControllaw/lattices/default]
    if [string length $config] {
        set config /home/helios/oagData/booster/orbitControllaw/lattices/$lattice/$config
    } else {
        set config /home/helios/oagData/booster/orbitControllaw/lattices/$lattice/[set ${plane}ConfigDir]
    }
    if [catch {exec sddsprocess $corrDir/$newName -reprint=par,OrbitCorrectionConfig,$config -nowarnings } result] {
        return -code error "Error redefine OrbitCorrectionConfig parameter: $result"
    }
    {exec rm $corrDir/${newName}~ }
    SetStatus "Correction resulting ramp saved to $corrDir/$newName"
    if [APSYesNoPopUp "Transfer $plane plane orbit to setpoint"] {
        SetStatus "Transfering orbit to setpoint..."
        set Plane [string toupper $plane]
        switch $plane {
            h  {
                set coord x
                set Coord X
            }
            v {
                set coord y
                set Coord Y
            }
        }
        set desc [set ${plane}Description]
        if ![string length $desc] {
            set desc "orbit transferred after $plane plane [set ${plane}Region] orbit correction."
        }
        set orbitFile /home/helios/oagData/booster/responseMeasFiles/meas${Plane}.sdds
        if [catch {exec sddscasr $orbitFile -save -pipe=out \
                     | sddsprocess -pipe -reedit=col,ControlName,%/Avg:${Coord}PositionAI/:${coord}:SetpointAO/ \
                     | sddscasr -pipe=in -restore } result] {
            return -code error "Error transferring orbit to setpoint: $result"
        }
        SetStatus "Do SCR save..."
        if [catch {APSSaveMachine -machine Booster -description "$desc"  } result] {
            return -code error "Error saving Booster SCR: $result"
        }
        SetStatus "Correction orbit saved to [lindex $result 0]."
    }
}


set dataDir  /home/helios/oagData/booster/orbitControllaw/lattices/default
set hConfigDir h.default
set hRegion 0
set hPlane h
set vPlane v
set vConfigDir v.default
set vRegion 0
set filterEnd1 .*
set hvWriteDir ""
set writePlane hv
set writeFilterEnd1 .*
set rootname h
set hvMainDir $dataDir
set hvPlane h
set steps  10000
set gain 0.1
set interval 6
set averages 10
set averageInterval 0.5
set hvConfig hv.defaultRegion1
set region 1
set StartBumpList {0    34.0 56.5 79.0 101.5 124.0 146.5 169.0 191  214.0}
set EndBumpList   {29.0 51.5 74   96.5 119   141.5 164.0 186   209  240.0}
set rampItemList ""
foreach start $StartBumpList end $EndBumpList {
    lappend rampItemList [format %0.1f $start]-[format %.1f $end]
}
set rampIndex [lindex $rampItemList 0]
set proportional 0
set logDir [APSGoToDailyDirectory -subdirectory orbitCorrection]

MakeOrbitFrame .orbit -parent .userFrame
