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



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)]
APSStandardSetup
set CVSRevisionAuthor "\$Revision: 1.0 $ \$Author: shang $"

APSApplication . -name "BTSQuadsCenter" -version $CVSRevisionAuthor \
  -overview "runs 2D scan to perform BTS orbit centering."

set plane x
proc SelectQuad {} {
    global quad configFile logDir corrector lowerLimit upperLimit stepSize quadScanStart quadScanStop 
    global quadScanStepSize corrScanStart corrScanStop corrScanStepSize plane
    
    set configFile /home/helios/oagData/BTS/configFiles/btsScan-$plane.sdds
    set filename $logDir/${quad}-varInput.$plane.sdds
    if ![file exist $filename] {
        if [catch {exec sddsprocess $configFile -match=col,QuadName=$quad $filename } result] {
            return -code error $result
        }
    }
    
    set corrector [exec sdds2stream -col=ControlName $filename]
    set lowerLimit [format %.4f [exec sdds2stream -col=LowerLimit $filename]]
    set upperLimit [format %.4f [exec sdds2stream -col=UpperLimit $filename]]
    set stepSize [format %.4f [exec sdds2stream -col=InitialChange $filename]]
    set quadScanStart [format %0.4f [exec sdds2stream -col=QuadScanStart $filename]]
    set quadScanStop [format %0.4f [exec sdds2stream -col=QuadScanStop $filename]]
    set quadScanStepSize [format %0.4f [exec sdds2stream -col=QuadScanStepSize $filename]] 
    set corrScanStart [format %0.4f [exec sdds2stream -col=CorrScanStart $filename]]
    set corrScanStop [format %0.4f [exec sdds2stream -col=CorrScanStop $filename]]
    set corrScanStepSize [format %0.4f [exec sdds2stream -col=CorrScanStepSize $filename]]
}

set cycles 1
set logDir .
set quad AQ1
set configFile /home/helios/oagData/BTS/configFiles/btsScan.sdds
set quadList [exec sdds2stream -col=QuadName $configFile]
set commandList [APSReplicateItem -item SelectQuad -number [llength $quadList]]
SelectQuad

set tolerance 0.0001
set abort 0
set pauseBetweenScan 1
proc MakeActionWidget {widget args} {
    set parent ""
    APSParseArguments {parent}
    
    global quad quadList corrector lowerLimit upperLimit commandList tolerance stepSize cycles abort
    global quadScanStart quadScanStop quadScanStepSize corrScanStart corrScanStop corrScanStepSize plane
    APSFrame $widget -parent $parent -label "" \
      -contextHelp "Action buttons"
    set w $parent$widget.frame
    
    APSLabeledEntry .logDir -parent $w -width 60 \
      -textVariable logDir \
      -label "Log directory:" \
      -contextHelp "Directory for log file of minimization."
  #  APSLabeledEntry .tol -parent $w -width 25 \
 #     -label "Tolerance: " -textVariable tolerance \
 #     -contextHelp "optimization tolerance."
    
    APSRadioButtonFrame .plane -parent $w -orientation horizontal -buttonList {x y} -label "plane:" \
	-variable plane -valueList {x y} -commandList {SelectQuad SelectQuad}
    APSRadioButtonFrame .pause -parent $w -orientation horizontal -buttonList {Yes No} \
	-label "Pause between scan?" -valueList {1 0} -variable pauseBetweenScan

    APSButton .daily -parent $w.logDir -packOption "-anchor e" \
      -text "daily" -size small \
      -command {set logDir [APSGoToDailyDirectory -subdirectory btsQuadCentering]}
    

    APSRadioButtonFrame .quads -parent $w -buttonList $quadList -valueList $quadList -variable quad \
        -orientation horizontal -label "" -commandList $commandList

    APSFrame .setup -parent $parent$widget.frame -label "" \
      -contextHelp "Setup quantities."
    set w $parent$widget.frame.setup.frame

    set width 25
    APSLabeledEntry .ik1 -parent $w \
      -label "corrector:" -textVariable corrector -width $width \
      -contextHelp "corrector name for selected quad."

    APSLabeledEntry .init -parent $w \
      -label "Corrector Initial Value:" -textVariable lowerLimit  -width $width  \
      -contextHelp "optimization initial value of corrector."
    
    APSLabeledEntry .final -parent $w \
    -label "Corrector Final Value:" -textVariable upperLimit  -width $width \
      -contextHelp "optimization final value of corrector."
    
   # APSLabeledEntry .step -parent $w 
#	-label "Corrector Step Size:" -textVariable stepSize -width $width \
#	-contextHelp "optimization initial step size of corrector"

    APSLabeledEntry .init0 -parent $w \
      -label "Corr Scan Start (relative):" -textVariable corrScanStart  -width $width  \
      -contextHelp "optimization initial value of corrector."
    
    APSLabeledEntry .final0 -parent $w \
    -label "Corr Scan Stop (relative):" -textVariable corrScanStop  -width $width \
      -contextHelp "optimization final value of corrector."
    
    APSLabeledEntry .step0 -parent $w \
	-label "Corr Scan Step Size:" -textVariable corrScanStepSize -width $width \
	-contextHelp "optimization initial step size of corrector"

    APSLabeledEntry .init1 -parent $w \
      -label "Quad Scan Start (relative):" -textVariable quadScanStart  -width $width  \
      -contextHelp "optimization initial value of corrector."
    
    APSLabeledEntry .final1 -parent $w \
    -label "Quad Scan Stop (relative):" -textVariable quadScanStop  -width $width \
      -contextHelp "optimization final value of corrector."
    
    APSLabeledEntry .step1 -parent $w \
	-label "Quan Scan Step Size:" -textVariable quadScanStepSize -width $width \
	-contextHelp "optimization initial step size of corrector"

    APSFrame .optimize -parent $parent$widget.frame -label "" \
      -contextHelp "Action buttons for skews"
    set w $parent$widget.frame.optimize.frame

  
    APSButton .minimize  -parent $w -text "Run Scan" \
      -command {run} \
      -contextHelp "Starts sddsoptimize for centering BTS orbit."

    APSButton .plotProg  -parent $w -text "Plot Progress" \
	-command {plotProgress -logDir $logDir} \
	-contextHelp "Plots the corrector values and orbit changes.."
    
    APSButton .abort -parent $w -text "Abort" -command "set abort 1"

}

proc plotProgress {args} {
    global logDir quad
    set quantities [exec sdds2stream $logDir/${quad}-varInput.sdds -col=ControlName]
    exec sddsplot -layout=1,2\
	-grap=sym,scale=2  \
	-col=EvalIndex,currentValue $logDir/${quad}.optLog  -endp \
	-col=$quantities,currentValue  $logDir/${quad}.optLog  &
}

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

proc ScanQuad {args} {
    set start -2
    set stop 2
    set stepSize 0.2
    set quad AQ1
    set filename ""
    set corrector ""
    set corrReadback ""
    APSParseArguments {quad corrector filename start stop stepSize corrReadback}

    global abort pauseBetweenScan
    if [catch {exec cavget -list=$corrector -pend=10} corrValue] {
	return -code error "Error in reading $quadName: $corrValue"
    }
    set corrReadbackValue 0
    if [regexp "B:ES2:Voltage" $corrector] {
	set corrReadback B:ES2:DacAI
    }
    if [string length $corrReadback] {
	if [catch {exec cavget -list=$corrReadback -pend=10} corrReadbackValue] {
	    return -code error "Error in reading $quadName: $corrReadbackValue"
	}
    }
    set quadName BTS:${quad}:CurrentAO

    if [catch {exec cavget -list=$quadName -pend=20} origValue] {
	return -code error "Error in reading $quadName: $origValue"
    }
    
    TogglePulsedMagnetEnables -location GuntoBoosterExt
    after 1000

    set xbpmList {APH1 APH2 APH3 BPH1 BPH2 CPH1 CPH2}
    set ybpmList {APV1 APV2 APV3 BPV1 BPV2 CPV1 CPV2}
    set steps [expr int(($stop-$start)/$stepSize)+1]
    if {$steps<=1} {
	set steps 1
	set stepSize 0
    }  else {
	set stepSize [expr ($stop-$start)*1.0/($steps-1.0)]
    }
    
    for {set step 0} {$step<$steps} {incr step} {
	if $abort {
	    set abort 0
	    return -code error "Aborted quad scan"
	}
	set quadValue [expr $origValue + $start + $step*$stepSize]
	if [catch {exec cavput -list=$quadName=$quadValue -pend=10 } result] {
	    return -code error "Error in changing $quadName by $stepSize: $result"
	}
	for {set i 0} {$i<5} {incr i} {
	    if $abort {
		set abort 0
		return -code error "Aborted"
	    }
	    after 1000
	}
	if [catch {exec cavget -list=BTS: -list=[join $xbpmList ,] -list=:x -repeat=number=10,pause=1,average -pend=10 -printErrors} xvalList] {
	    return -code error "Error in reading BTS/PTB charge: $xvalList"
	}
	if [catch {exec cavget -list=BTS: -list=[join $ybpmList ,] -list=:y -repeat=number=10,pause=1,average -pend=10 -printErrors} yvalList] {
	    return -code error "Error in reading BTS/PTB charge: $yvalList"
	}
	if [catch {exec cavget -list=BTS: -list=[join $xbpmList ,] -list=:BPM -repeat=number=10,pause=1,average -pend=10 -printErrors} xsumList] {
	    return -code error "Error in reading BTS/PTB charge: $xsumList"
	}
	if [catch {exec cavget -list=BTS: -list=[join $ybpmList ,] -list=:BPM -repeat=number=10,pause=1,average -pend=10 -printErrors} ysumList] {
	    return -code error "Error in reading BTS/PTB charge: $ysumList"
	}
	lappend stepList $step
	lappend quadValueList $quadValue
	foreach bpm $xbpmList val $xvalList {
	    lappend $bpm $val
	}
	foreach bpm $ybpmList val $yvalList {
	    lappend $bpm $val
	}
	foreach bpm $xbpmList val $xsumList {
	    lappend ${bpm}Sum $val
	}
	foreach bpm $ybpmList val $ysumList {
	    lappend ${bpm}Sum $val
	}
    }
    
    if [catch {exec cavput -list=$quadName=$origValue -pend=30 } result] {
	return -code error "Error in restoring $quadName: $result"
    }
    if [catch {exec sddsmakedataset $filename -par=CorrectorName,type=string -data=$corrector \
		   -par=CorrectorValue,type=double -data=$corrValue \
		   -par=CorrectorReadback,type=double -data=$corrReadbackValue \
		   -par=QuadName,type=string -data=$quad \
		   -col=Step,type=long -data=[join $stepList ,] \
		   -col=$quad,type=double -data=[join $quadValueList ,] \
		   -col=APH1,type=double -data=[join $APH1 ,] \
		   -col=APH2,type=double -data=[join $APH2 ,] \
		   -col=APH3,type=double -data=[join $APH3 ,] \
		   -col=BPH1,type=double -data=[join $BPH1 ,] \
		   -col=BPH2,type=double -data=[join $BPH2 ,] \
		   -col=CPH1,type=double -data=[join $CPH1 ,] \
		   -col=CPH2,type=double -data=[join $CPH2 ,]  \
		   -col=APV1,type=double -data=[join $APV1 ,] \
		   -col=APV2,type=double -data=[join $APV2 ,] \
		   -col=APV3,type=double -data=[join $APV3 ,] \
		   -col=BPV1,type=double -data=[join $BPV1 ,] \
		   -col=BPV2,type=double -data=[join $BPV2 ,] \
		   -col=CPV1,type=double -data=[join $CPV1 ,] \
		   -col=CPV2,type=double -data=[join $CPV2 ,] \
		   -col=APH1:Sum,type=double -data=[join $APH1Sum ,] \
		   -col=APH2:Sum,type=double -data=[join $APH2Sum ,] \
		   -col=APH3:Sum,type=double -data=[join $APH3Sum ,] \
		   -col=BPH1:Sum,type=double -data=[join $BPH1Sum ,] \
		   -col=BPH2:Sum,type=double -data=[join $BPH2Sum ,] \
		   -col=CPH1:Sum,type=double -data=[join $CPH1Sum ,] \
		   -col=CPH2:Sum,type=double -data=[join $CPH2Sum ,]  \
		   -col=APV1:Sum,type=double -data=[join $APV1Sum ,] \
		   -col=APV2:Sum,type=double -data=[join $APV2Sum ,] \
		   -col=APV3:Sum,type=double -data=[join $APV3Sum ,] \
		   -col=BPV1:Sum,type=double -data=[join $BPV1Sum ,] \
		   -col=BPV2:Sum,type=double -data=[join $BPV2Sum ,] \
		   -col=CPV1:Sum,type=double -data=[join $CPV1Sum ,] \
		   -col=CPV2:Sum,type=double -data=[join $CPV2Sum ,] } result] {
	return -code error "Error creating file $filename: $result"
    }
}

proc run {args} {
    global logDir corrector quad lowerLimit upperLimit configFile tolerance corrOrigValues stepSize abort pauseBetweenScan
    global quadScanStart quadScanStop quadScanStepSize corrScanStart corrScanStop corrScanStepSize plane
    #do 2D scan, scan corrector; and at each corrector step scan the related quad with BTSQuadScanScript
    set steps [expr int(($corrScanStop-$corrScanStart)/$corrScanStepSize)+1]
    
    set stepSize [expr ($corrScanStop-$corrScanStart)/($steps-1.0)]
   
    SetStatus "$quad $corrector"
   
    SetStatus "scan $corrector ..."
    if [regexp {B2C8V} $corrector] {
	if [catch {exec ramploadnew /home/helios/oagData/booster/ramps/correctors/lattices/default/HVCorr.ramp} result] {
	    return -code error "Error loading booster reference ramp: $result"
	}
	exec caput B:B2C8V:CorrectionAI 0
    }
    
    if [catch {exec cavget -list=$corrector -pend=10 -printErrors} initCorrValue] {
        return -code error "Error reading $corrector value1: $initCorrValue"
    }
    for {set step 0} {$step<$steps} {incr step} {
	if $pauseBetweenScan {
	    if ![APSYesNoPopUp "Continue scan $corrector now?"] {
		SetStatus "$corrector scan aborted."
		return
	    }
	}
	if [regexp {B2C8V} $corrector] {
	    exec caput B:B2C8V:CorrectionAI 0
	    if [catch {exec ramploadnew /home/helios/oagData/booster/ramps/correctors/lattices/default/HVCorr.ramp} result] {
		return -code error "Error loading booster reference ramp: $result"
	    }
	}
        set filename $logDir/${corrector}.$plane.[format %03d $step]
	set corrValue [format %.4f [expr $initCorrValue + $corrScanStart + $stepSize*$step]]
	
	if {$corrValue<$lowerLimit} {
	    set corrValue $lowerLimit
	}
        if {$corrValue>$upperLimit} {
            set corrValue $upperLimit
        }
        SetStatus "Step $step: set $corrector to $corrValue..."

	if [catch {exec cavput -list=$corrector=$corrValue  -pend=30} result] {
	    return -code error "Error change $corrector to $corrValue: $result"
        }
	if [regexp {B2C8V} $corrector] {
	    if [catch {exec /home/oxygen/SHANG/oag/apps/src/tcltkapp/oagapp/SetBoosterExtBumpAmplitude -load 1 } result] {
		return -code error "Error change booser ramp: $result"
	    }
	}
	for {set i 0} {$i<5} {incr i} {
	    if $abort {
		set abort 0
		SetStatus "Aborted."
		return
	    }
	    after 1000
	}
	if $pauseBetweenScan {
	    if ![APSYesNoPopUp "$corrector was set to $corrValue, scan quads now?"] {
		SetStatus "quads scan aborted."
		return
	    }
	}
        SetStatus " scan quad $quad..."
        if [catch {ScanQuad -start $quadScanStart -stop $quadScanStop \
		       -stepSize $quadScanStepSize -filename $filename  -quad $quad \
		       -corrector $corrector } result] {
            SetStatus "Error scan $quad : $result"
	    return
        }
    }
    if [catch {exec cavput -list=$corrector=$initCorrValue -pend=10} result] {
        return -code error "Error restore corrector $corrector value: $result"
    }
    if [regexp {B2C8V} $corrector] {
	if [catch {exec ramploadnew /home/helios/oagData/booster/ramps/correctors/lattices/default/HVCorr.ramp} result] {
	    return -code error "Error loading booster reference ramp: $result"
	}
	exec caput B:B2C8V:CorrectionAI 0
    }
    SetStatus "Scan $corrector done."
    
    return
    if [catch {exec sddsprocess  $configFile -match=col,QuadName=$quad -pipe=out \
		   | sddsprocess -pipe=in \
		   $logDir/${quad}-varInput.sdds -redefine=col,LowerLimit,$lowerLimit \
		   -redefine=col,UpperLimit,$upperLimit \
		   -redefine=col,InitialChange,$stepSize \
		   -nowarnings} result] {
        return -code error $result
    }
    
    APSExecLog .minimizeCoupling \
      -lineLimit 2048 -width 90 \
      -name "BTS Quads Centering" \
      -unixCommand "sddsoptimize \"-measScript=/home/helios/oagData/BTS/configFiles/BTSBPMMeasureScript -quad $quad -logDir $logDir -corrector $corrector\" \
            -varFile=$logDir/${quad}-varInput.sdds -tolerance=$tolerance \
            -simplex=evaluations=500,no1dscan \
             -verbose \
            -logFile=$logDir/${quad}.optLog"
    return
}


set status "Working."
APSScrolledStatus .status -parent .userFrame -textVariable status -width 90
MakeActionWidget .action -parent .userFrame
set status "Ready."
#save corrector original values
set corrOrigValues /tmp/[APSTmpString].btscorr
#exec sddscasr -save $configFile $corrOrigValues
APSAddToTempFileList -ID btsorbit -fileList $corrOrigValues
