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

#
#$Log: not supported by cvs2svn $
#Revision 2.1 2012/07/25 11:38:37 shang
#added windowing to both sides in post-process to avoid errors.
#
#Revision 2.0 2012/07/25  shang
#Added a window function to post-process when sddsprocess fails to detect the center where one side is flat, 
#so that it can always find a best amplitude position.
#
#Revision 1.9  2011/12/15 20:15:24  shang
#corrected the BTS efficiency plot command which used wrong file.
#
#Revision 1.8  2011/12/12 20:36:29  shang
#changed to plot BTSEfficiency instead of charge in the post-processing.
#
#Revision 1.7  2011/08/19 17:25:55  shang
#fixed a bug in post-processing.
#
#Revision 1.6  2011/08/19 14:56:08  shang
#changed made by CY.
#
#Revision 1.5  2011/06/28 19:41:41  shang
#made more changes and tested.
#
#Revision 1.4  2011/05/31 18:03:12  shang
#changed the default parameters and the best amplitude processing per CY's request, and added "loading reference" when "abort" button is clicked.
#
#Revision 1.3  2011/04/27 20:55:29  shang
#corrected the bump coefficient table since the H/V even/odd sectors behave differently, added B1C9H, B3C9H, B2C9V, and B4C9V sectors to missing list because they
#do not meet the requirement for 4-corrector bump (only have one bpm or bpm has been used by other sector)
#
#Revision 1.2  2011/04/25 21:45:22  shang
#remove shang's private version.
#
#Revision 1.1  2011/04/25 21:43:52  shang
#first version for scan booster 4-corrector bumps.
#


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 version "Booster4CorrectorBumpScanNew\n\n\$Revision: 1.10 $\n\$Author: shang $"

proc SetStatus {text} {
    global mainStatus
    set mainStatus "[exec date +%H:%M:%S] $text"
    update
}


proc GenerateBump {args} {
    set amplitude ""
    APSParseArguments {amplitude}
    global plane sector region ampStart lattice dataDir outputDir sectorList ampStart ampEnd missingList
    global startRegion endRegion

    if {$startRegion>$endRegion} {
	SetStatus "Error: startRegion has to be smaller than end region and both has be to number from 0 t0 9"
	return
    }
    if {$endRegion>9} {
	set endRegion 9
    }
    if ![string length $amplitude] {
	set amplitude $ampStart
    }
    set fileList ""
    foreach quad {B1 B2 B3 B4} {
	foreach sector $sectorList {
	    set nm ${quad}$sector
	    global $nm
	    set nm1 ${nm}$plane
	    if [set $nm] {
		if [lsearch -exact $missingList $nm1]>=0 {
		    SetStatus "$nm1 not available, skip."
		    continue
		}
		SetStatus "generate bump for $nm..."
		if [catch {exec SetBoosterBumpAmplitude \
			       -outDir $outputDir \
			       -plane $plane -sector $nm -lattice default \
			       -region $region -amplitude $amplitude \
			  -startRegion $startRegion -endRegion $endRegion} result] {
		    return -code error "SetBoosterBumpAmplitude: $result"
		}
		SetStatus "$result"
		lappend fileList $outputDir/${nm}$plane.ramp
	    }
	}
    }
    if [llength $fileList] {
    	eval exec sddsplot -col=RampTime,OldRampSetpoint -col=RampTime,RampSetpoint -sep=2 -split=page  \
	    -leg -grap=line,vary -topline=@CorrName $fileList &
    }
}

proc LoadBump {args} {
    global dataDir lattice sectorList plane outputDir
    foreach quad {B1 B2 B3 B4} {
	foreach sector $sectorList {
	    set nm ${quad}$sector
	    global $nm
	    set nm1 ${nm}$plane
	    if [set $nm] {
		if [lsearch -exact $missingList $nm1]>=0 {
		    SetStatus "$nm1 not available, skip."
		    continue
		}
		if [lsearch -exact $missingList1 $nm1]>=0 {
		    SetStatus "$nm1 not available for extraction, skip."
		    continue
		}
		set rampFile $outputDir/${nm}${plane}.ramp
		if ![file exist $rampFile] {
		    SetStatus "$rampFile does not exist, generate the bump first."
		    continue
		}
		SetStatus "loading ramps for ${nm}$plane..."
		set command "ramploadnew $rampFile"
		if [catch {eval exec $command} result] {
		    return -code error "Error in loading ramp: $result"
		}
	    }
	}
    }
    SetStatus "done."
}

set processEfficiency 0.9
proc Postprocess {args} {
    global outputDir plane sectorList missingList fileSelection tolerance processEfficiency
    cd $outputDir
    set files [glob -nocomplain *.sdds]
    if ![llength $files] {
	return -code error "No scanned data found."
    }
    APSScrolledListWindow .display -name "scan file selection" \
        -label "Select a flile"  -acceptButton 0 \
        -itemList $files -selectionVar fileSelection \
        -directory $outputDir -appendDescription 0 \
        -rootnameOnly 1 -descriptionName Contents 
    tkwait variable fileSelection
    set sector [file root $fileSelection]
    if [regexp {H} $sector] {
	set plane H
    } else {
	set plane V
    }
    
    set scanType ScanSet
    if [catch {PostprocessScan -filename $fileSelection -sector [string range $sector 0 end-1] -plane $plane -efficiency $processEfficiency -scanType ScanSet} result] {
	return -code error $result
    }
}

proc PostprocessAll {args} {
    global outputDir plane sectorList missingList
    set fileList ""
    foreach quad {B1 B2 B3 B4} {
	foreach sector $sectorList {
	    set nm ${quad}$sector
	    global $nm 
	    set nm1 ${nm}$plane
	    if [set $nm] {
		if [lsearch -exact $missingList $nm1]>=0 {
		    SetStatus "$nm1 not available, skip."
		    continue
		}
		if [file exist $outputDir/${nm}${plane}.ramp] {
		    lappend fileList $outputDir/${nm}${plane}.ramp
		}
	    }
	}
    }
    if ![llength $fileList] {
	SetStatus "No ramp files found."
	return
    }
    set tmpRoot /tmp/[APSTmpString]
    if [catch {eval exec sddscombine $fileList $tmpRoot.all} result] {
	return -code error $result
    }
    set corrList [lsort -unique [exec sdds2stream -par=CorrName $tmpRoot.all]]
    
    set fileList ""
    foreach corr $corrList {
	if [catch {exec sddsprocess $tmpRoot.all $tmpRoot.$corr -match=par,CorrName=$corr} result] {
	    SetStatus "Error in processing $corr : $result"
	    continue
	}
	if [catch {exec sddsenvelope $tmpRoot.$corr -sum=1,RampSetpointDelta1 -copy=RampTime,OriginalRampSetpoint -pipe=out \
		       | sddsxref -pipe $tmpRoot.$corr -transfer=par,* -leave=* \
		       | sddsprocess -pipe=in $tmpRoot.$corr.ramp \
		   "-redefine=col,RampSetpoint,OriginalRampSetpoint RampSetpointDelta1Sum +" } result] {
	    return -code error "Error in computing average: $result"
	}
	lappend fileList $tmpRoot.$corr.ramp
    }
    if [llength $fileList] {
	if [catch {eval exec sddscombine $fileList $outputDir/${plane}bump.ramp -over} result] {
	    return -code error $result
	}
	if [APSYesNoPopUp "load the average bump $outputDir/${plane}bump.ramp now?"] {
	    SetStatus "loading averaged bump..."
	    set command "ramploadnew  $outputDir/${plane}bump.ramp"
	    if [catch {eval exec $command} result] {
		return -code error "Error in loading ramp: $result"
	    }
	}
    }
    SetStatus "done."
}

proc PostprocessScan {args} {
    set filename ""
    set sector ""
    set scanType ""
    set plane ""
    set efficiency ""
    APSParseArguments {filename sector scanType plane efficiency}
    global scanResult$sector outputDir btsCharge ptbCharge btsEfficiency abort bestAmp scanMode prevReference tolerance region
    global efficiencyPV
    
    set dataDir /home/helios/oagData/booster/ramps/correctors/lattices/default
    set tmpRoot /tmp/[APSTmpString]
   # exec sddsplot -col=BpmAmplitude,BTS:CM:q.VAL $filename -topline=${sector}$plane &
    set cols [exec sddsquery -col $filename]
    if ![regexp $efficiencyPV $cols] {
        return -code error "$efficiencyPV does not exist in $filename, please select different efficiency PV."
    }
    if [catch {exec sddsprocess $filename $filename.1 "-redefine=par,bumpRegion,$region,type=long" \
		   "-test=col,PTB:CM:measCurrentCM 0 >" \
		   "-redefine=col,BTSEfficiency,$efficiencyPV PTB:CM:measCurrentCM /" } result] {
	return -code error $result
    }
    exec mv $filename.1 $filename
    catch {file delete -force $outputDir/${sector}${plane}.ramp}
    if [catch {exec sddssmooth $filename -pipe=out -col=BTSEfficiency \
		   | sddsprocess -pipe=in $filename.proc -process=BTSEfficiency,center,best,functionOf=BpmAmplitude} result] {
        SetStatus $result
        #add window function 
        set amps [exec sdds2stream -col=BpmAmplitude $filename]
        set start [lindex $amps 0]
        set end [lindex $amps end]
        if [catch {exec sddsinterp $filename -pipe=out \
                     -col=BpmAmplitude \
                     -sequence=100,$start,$end \
                     -pipe=out \
                     | sddsprocess \
                     "-redefine=col,Index,i_row" \
                     "-redefine=col,w,Index 96 < pop pop ? 1 : 1 0.333 Index 96 - * - \$"  \
                     "-redefine=col,w1,Index 3 > pop pop ? 1 : 0.333 Index * \$" \
                     -pipe \
                     | sddsprocess \
                     "-redefine=col,BTSEfficiency,BTSEfficiency w * w1 * " \
                     -pipe \
                     | sddsprocess -del=para,riseTime,fallTime \
                     -pipe \
                     |  sddsprocess \
                     -process=BTSEfficiency,risetime,riseTime,functionOf=BpmAmplitude \
                     -process=BTSEfficiency,falltime,fallTime,functionOf=BpmAmplitude \
                     -process=BTSEfficiency,center,best,functionOf=BpmAmplitude \
                     -pipe=in $tmpRoot.window } result] {
            return -code error "Error in windowing $filename: $result"
        }
        exec cp $tmpRoot.window $filename.proc
        exec sddsplot -col=BpmAmplitude,BTSEfficiency $filename.proc -topline=${sector}$plane &
    } else {
        exec sddsplot -col=BpmAmplitude,BTSEfficiency $filename -topline=${sector}$plane &
    }
    set maxAmp [   exec sddssmooth -col=BTSEfficiency $filename -pipe=out \
    	-points=3 \
         | sddsconvert -pipe -del=par,amplitudeMax \
	| sddsprocess \
	  -process=BTSEfficiency,maximum,amplitudeMax,position,functionOf=BpmAmplitude  \
	  -pipe \
	  | sdds2stream -para=amplitudeMax -pipe ]
    set bestAmp [exec sdds2stream -par=best $filename.proc]
    
#### insert a prompt message for user input of bestAmp here.
#### 
    update
    if {$scanMode=="Manual"} {
        global popup bestAmpOrig
        set popup 0
        set bestAmpOrig $bestAmp
        APSDialogBox .popup \
          -name bestAmp \
          -okCommand "set popup 1" \
          -cancelCommand "set popup 2"
        APSLabel .title \
          -parent .popup.userFrame \
          -text "You may change the calculated value\nof bestAmp manually or click Cancel.\n"
        APSLabeledEntry .bestAmp \
          -parent .popup.userFrame \
          -label "bestAmp:" \
          -textVariable bestAmp \
          -packOption "-fill x -expand true"
        tkwait variable popup
        if {$popup ==2} {
            SetStatus "set best ramp was cancelled."
            return
        }
        if {$popup != 1 } {
            set bestAmp $bestAmpOrig
        }
    }
    #set prevReference [file readlink /home/helios/oagData/booster/ramps/correctors/lattices/default/HVCorr.ramp]
                       
    if [catch {exec SetBoosterBumpAmplitude \
                 -outDir $outputDir -load 0 \
                 -plane $plane -sector $sector  \
                 -region $region -amplitude $bestAmp } result] {
	return -code error "Error in SetBoosterBumpAmplitude: $result"
    }
    
    switch $scanType {
	ScanSetAve {
	    #wait after all the scan is done, but restore original ramp before next scan
	    set sector1 ${sector}$plane
	    if [catch {exec sddsprocess $dataDir/${plane}coeff.sdds -pipe=out -match=par,Sector=$sector1 \
			   | sdds2stream -pipe -col=CorrectorName} corrList] {
		return -code error "Error in getting scanned correctors: $corrList"
	    }
	    set option "-match=par,CorrName=[lindex $corrList 0]"
	    for {set i 1} {$i<[llength $corrList]} {incr i} {
		append option ",CorrName=[lindex $corrList $i],|"
	    }
	    if [catch {exec sddsprocess $dataDir/HVCorr.ramp $tmpRoot.set "$option"} result] {
		return -code eror "Error processing ramp table: result"
	    }
	    SetStatus "loading original ramp..."
	    set command "ramploadnew $tmpRoot.set"
	    if [catch {eval exec $command} result] {
		return -code error "Error in loading ramp: $result"
	    }
	}
	ScanSet {
	    #set the best ramp after each scan
	    set command "ramploadnew $outputDir/${sector}$plane.ramp"
	    
	    SetStatus "loading $sector $plane best ramp:"
	    if [catch {eval exec $command} result] {
		return -code error "Error in loading ramp: $result"
	    }
            APSWaitWithUpdate -waitSeconds 4 -updateInterval 1
	    if [catch {CheckBTSCharge} result] {
		SetStatus "BTS charge too low."
		set scanResult$sector aborted
		return
	    }
	    if {$btsEfficiency<[expr $efficiency - $tolerance]} {
                if {$scanMode=="Manual"} {
                    set answer [APSMultipleChoice [APSUniqueName .] -name Warning \
                                  -type warning  \
                                  -question "BTS efficiency dropped after loading ramps which means the bump may be bad, do you want to continue or abort scan?" \
                                  -returnList {Continue Abort} -labelList {Continue Abort} ]
                    if {$answer=="Abort"} {
                        SetStatus "aborted due to dropped BTS efficiency."
                        set scanResult$sector aborted
                        return
                    }
                } else {
                    SetStatus "$sector scan failed to improve the BTS efficiency, no action taken. continue to next scan in automatic mode."
                    SetStatus "restore reference..."
                    if [catch {LoadReference -plane $plane} result] {
                        return -code error "Error in loading reference: $result"
                    }
                    if [catch {CheckBTSCharge} result] {
                        return -code error $result
                    }
                    APSWaitWithUpdate -waitSeconds 20 -update 1
                }
	    } else {
                SetStatus "resuming controllaws...."
                if [catch {exec cavput -list=Booster:ControlLawLongRC,Booster:ControlLawXRC \
                             -list=.SUSP=0 -pend=10} result] {
                    return -code error $result
                }
                SetStatus "installing ${sector}$plane ramp to reference..."
                if [catch {MakeReference -newRampFile $outputDir/${sector}${plane}.ramp -yesno 0} result] {
                    SetStatus "Error in making new reference: $result"
                    set scanResult$sector aborted
                    return
                }
                SetStatus "Loading new installed reference."
                if [catch {LoadReference -plane $plane} result] {
                    return -code error "Error in loading reference: $result"
                }
                
                if [catch {CheckBTSCharge} result] {
                    return -code error $result
                }
                SetStatus "done."
            }
	}
    }
    set scanResult$sector done
}

proc ScanStartEndAmplitude {args} {
    set sector ""
    set plane ""
    set start ""
    set end ""
    APSParseArguments {sector plane start end}
    global ampStart ampEnd ampStart1 ampEnd1 region outputDir btsCharge lattice abort
    global btsEfficiency
    set ampStart1 $start
    set ampEnd1 $end
    SetStatus "Search new start amplitude where BTS charge is 0."
    set delta 0.2
    set count 0
    while {1} {
	if $abort {
	    Abort -plane $plane
	    return -code error "Manually aborted."
	}
	SetStatus "now start amp is $ampStart1"
	if [catch {exec SetBoosterBumpAmplitude \
		       -outDir $outputDir -load 1 \
		       -plane $plane -sector $sector -lattice default \
		       -region $region -amplitude $ampStart1 } result] {
	    return -code error "SetBoosterBumpAmplitude: $result"
	}
	ReadBTSCharge
	if {$btsEfficiency>0.6} {
	    set ampStart1 [expr $ampStart1 - $delta]
	} else {
	    break
	}
	incr count
	if {$count>3} {
	    set delta [expr 2.0*$delta]
	    set count 0
	}
	update
    }
    
    if [catch {LoadReference -plane $plane} result] {
	return -code error "Error in loading reference: $result"
    }
    
    if [catch {CheckBTSCharge} result] {
	return -code error $result
    }
    SetStatus "Search new end amplitude where BTS charge is 0."
    set ampEnd1 $ampEnd
    set delta 0.2
    set count 0
    while {1} {
	if $abort {
	    Abort -plane $plane
	    return -code error "Manually aborted."
	}
	SetStatus "Now the end amplitude is $ampEnd1"
	if [catch {exec SetBoosterBumpAmplitude \
		       -outDir $outputDir -load 1 \
		       -plane $plane -sector $sector -lattice default \
		       -region $region -amplitude $ampEnd1 } result] {
	    return -code error "SetBoosterBumpAmplitude: $result"
	}
	ReadBTSCharge
	if {$btsEfficiency>0.6} {
	    set ampEnd1 [expr $ampEnd1 + $delta]
	} else {
	    break
	}
	incr count
	if {$count>3} {
	    set delta [expr 2.0*$delta]
	    set count 0
	}
	update
    }
    SetStatus "Found new amplitude range $ampStart1 -- $ampEnd1 for $sector $plane."
    if [catch {LoadReference -plane $plane} result] {
	return -code error "Error in loading reference: $result"
    }
    after 1000
    
    if [catch {CheckBTSCharge} result] {
	return -code error $result
    }
}

proc GetStartAndEndAmplitude {args} {
    set sector ""
    APSParseArguments {sector}
    global skipSector ampStart1 ampEnd1 outputDir lattice region
    set skipSector 0
    if [regexp {H} $sector] {
	set plane H
	set refFile /home/helios/BOOSTER/correctorBumpScan/xScan-12-86/combinedH.sdds-coll
    } else {
	set plane V
	set refFile /home/helios/BOOSTER/correctorBumpScan/xScan-12-86/combinedV.sdds-coll
    }
    
    if ![file exist $refFile] {
	return -code error "Start/End reference file does not exist."
    }
    set tmpFile /tmp/[APSTmpString]
    
    if [catch {exec sddsprocess $refFile $tmpFile -match=col,Filename=${sector}.sdds} result] {
	set skipSector 1
	SetStatus "$sector not found in reference, skip scan."
	return
    }
    set ampStart1 [format %.2f [exec sdds2stream -col=bumpAmplitudeLow $tmpFile]]
    set ampEnd1 [format %.2f [exec sdds2stream -col=bumpAmplitudeHigh $tmpFile]]
    

    if [catch {LoadReference -plane $plane} result] {
	return -code error "Error in loading reference: $result"
    }
    SetStatus "found $sector start/end amp: $ampStart1 $ampEnd1"
}
proc Abort {args} {
    set plane ""
    APSParseArguments {plane}
    global abort
    if $abort {
	set abort 0
	LoadReference -plane $plane
	SetStatus "resuming controllaws...."
	if [catch {exec cavput -list=Booster:ControlLawLongRC,Booster:ControlLawXRC \
		       -list=.SUSP=0 -pend=10} result] {
	    return -code error $result
	}
	SetStatus "Aborted."
    }
}
set numToAve 10 
set pauseAfterChange 2 
set bestAmp 0.01

set bsp100IocList [exec sddsprocess  /home/helios/oagData/SCR/requestFiles/SBPMWaveform.config \
    -pipe=out -match=par,Location=Accel -match=par,BPMType=Booster | sdds2stream -pipe -par=IOCName]
foreach ioc $bsp100IocList {
    lappend bsp100sectorList $ioc
    set s [string index $ioc end]
    lappend bsp100sectorList [string range $ioc 0 end-1][expr $s + 1]
}

proc StartScan {args} {
    global plane sectorList inputDir outputDir ampStart ampEnd steps numToAve pauseAfterChange scanType ampStart1 ampEnd1 coord region
    global lattice region specialList missingList ptbCharge btsCharge btsEfficiency lastEfficiency abort skipSector bsp100sectorList
    global scanMode
    set skipSector 0
    
    if [catch {LoadReference -plane $plane} result] {
	return -code error "Error in loading reference: $result"
    }
    
    if [catch {CheckBTSCharge} result] {
	return -code error $result
    }
    
    set tmpRoot /tmp/[APSTmpString]
    set lastEfficiency 0
    foreach quad {B1 B2 B3 B4} {
	foreach sector $sectorList {
	    if $abort {
		Abort -plane $plane
		SetStatus "Manually aborted."
		return
	    }
	    set nm ${quad}$sector
	    global $nm scanResult$nm
	    set scanResult$nm 0
	    set nm1 ${nm}$plane
	    if [set $nm] {
		if [lsearch -exact $missingList $nm1]>=0 {
		    SetStatus "$nm1 not available, skip."
		    continue
		}
		if $abort {
		    Abort -plane $plane
		    SetStatus "Manually aborted."
		    return
		}
		SetStatus "suspending controllaws...."
		if [catch {exec cavput -list=Booster:ControlLawLongRC,Booster:ControlLawXRC \
			       -list=.SUSP=1 -pend=10} result] {
		    return -code error $result
		}
	
		if [catch {CheckBTSCharge} result] {
		    SetStatus $result
		    return
		}
		set skipSector 0
		#if [catch {GetStartAndEndAmplitude -sector $nm1} result] {
		#    SetStatus "$result"
		#    if [catch {ScanStartEndAmplitude -sector $nm -plane $plane -start $ampStart1 -end $ampEnd1} result] {
		#	SetStatus $result
		#	return
		#    }
		#}
                
		if $skipSector {
		    continue
		}
		set dateStr [clock format [clock seconds] -format %Y-%j-%m%d:%H%M%S]
		set outputFile $outputDir/${nm}${plane}.sdds
		#if {$ampStart<$ampStart1} {
                #    set ampStart $ampStart1
                #}
                #if {$ampEnd>$ampEnd1} {
                #    set ampEnd $ampEnd1
                #}
                if [lsearch $nm $bsp100sectorList]>=0 {
                    if [catch {exec replaceText /home/helios/oagData/booster/ramps/correctors/inputFiles/bsp100.mon.template $tmpRoot.mon \
                                 -orig=<sector>,<region>,<plane> -repl=$nm,$region,$coord } result] {
                        puts $result
                        return -codee rror "Error in generating monitor file1: $result"
                    }
                    if [catch {exec sddscombine /home/helios/oagData/booster/ramps/correctors/inputFiles/bcorrbump.mon $tmpRoot.mon \
                                 -merge $outputDir/${nm}${plane}.mon } result] {
                        return -codee rror "Error in generating monitor file2: $result"
                    }
                } else {
                    exec cp /home/helios/oagData/booster/ramps/correctors/inputFiles/bcorrbump.mon  $outputDir/${nm}${plane}.mon 
                }
		set expFile $outputDir/${nm}${plane}.exp
               
		if [catch {exec replaceText /home/helios/oagData/booster/ramps/correctors/inputFiles/bumpscanNew.exp $expFile \
                             -orig=<steps>,<start>,<end>,<numToAve>,<region>,<plane>,<sector>,<post_pause>,<monFile> \
			       -repl=$steps,$ampStart,$ampEnd,$numToAve,$region,$plane,$nm,$pauseAfterChange,$outputDir/${nm}${plane}.mon } result] {
		    return -code error "Error in generating exp file: $result"
		}
		catch {exec rm $outputFile}
	
	
		if $abort {
		    Abort -plane $plane
		    SetStatus "Manually aborted."
		    return
		}	
		if [catch {TogglePulsedMagnetEnables -location GunToBoosterExt} result] {
		    return -code error "error in enabling beam: $result"
		}
		after 3000
		if [catch {CheckBTSCharge} result] {
		    SetStatus $result
		    return
		}
                
		APSExecLog .bumpscan -name "$nm $plane  scan" -width 100 \
		    -unixCommand "sddsexperiment $expFile $outputFile -verbose" \
		    -callback "PostprocessScan -filename $outputFile -scanType $scanType -sector $nm -plane $plane -efficiency $btsEfficiency" \
		    -abortCallback "LoadReference -plane $plane;set scanResult$nm aborted" -cancelCallback "set scanResult$nm canceled"
		tkwait variable scanResult$nm
		
		if [string compare [set scanResult$nm] "done"]!=0 {
		    SetStatus "StartScan(2): $nm scan was [set scanResult$nm]"
		    return
		}
		set lastEfficiency $btsEfficiency
		#wait 1 minture
		SetStatus "waiting for 1 minute..."
		set timeout [expr [clock seconds]+20]
		while {[clock seconds]<$timeout} {
		    if $abort {
			Abort -plane $plane
			SetStatus "aborted."
			return
		    }
		    update
		    after 1000
		}
		SetStatus "$nm scan  done, deselect $nm."
                set $nm 0
	    }
	}
    }
    if {$scanType=="ScanSetAve"} {
	PostprocessAll
    }
    
}

proc ChangeLattice {args} {
    global dataDir lattice
    

}

set region 0
proc SelectBumpRange {args} {
    set index ""
    APSStrictParseArguments {index}
    
    global region
    set region $index
}

proc SelectAll {args} {
    set all 1
    APSParseArguments {all}
    global sectorList
    foreach quad {B1 B2 B3 B4} {
	foreach sector $sectorList {
	    set nm ${quad}$sector
	    global $nm
	    set $nm $all
	}
    }
}

proc LoadReference {args} {
    set plane ""
    APSParseArguments {plane}
    set refDir  /home/helios/oagData/booster/ramps/correctors/lattices/default
    set refFile $refDir/HVCorr.ramp
    
    SetStatus "loading reference ramp..."
    set tmpFile /tmp/[APSTmpString]
    if [catch {exec sddsprocess $refFile $tmpFile -match=par,CorrName=*[string toupper $plane]* } result] {
        return -code error "Error loading reference1: $result"
    }
    set command "ramploadnew $tmpFile "
    if [catch {eval exec $command} result] {
	return -code error "Error in loading reference ramp2: $result"
    }
    SetStatus "done."
}

proc MakeReference {args} {
    set newRampFile ""
    set yesno 1
    APSParseArguments {newRampFile yesno}
    global outputDir plane
    if ![string length $newRampFile] {
	set newRampFile  $outputDir/${plane}bump.ramp
    }
    if ![file exist $newRampFile] {
	SetStatus "$newRampFile does not exist."
	return
    }
    set refDir  /home/helios/oagData/booster/ramps/correctors/lattices/default
    set refFile $refDir/HVCorr.ramp
    set origFile [file readlink $refFile]
    set newFile [APSNextGenerationedName -name $origFile -separator - -newFile 1\
		     -directory $refDir ]
    set corrList [exec sdds2stream -par=CorrName $newRampFile]
    set option "-match=par,CorrName=[lindex $corrList 0],!"
    for {set i 1} {$i<[llength $corrList]} {incr i} {
	append option ",CorrName=[lindex $corrList $i],!,&"
    }
    if [catch {exec sddsprocess $refFile $outputDir/tmpFile $option} result] {
	return -code error "Error in filter new correctors from refFile: $result"
    }
    if [catch {exec sddscombine $outputDir/tmpFile $newRampFile -pipe=out \
		   | sddsprocess -pipe "-reprint=par,CorrectorBump,$corrList" \
		   | sddssort -pipe=in -par=CorrName $refDir/$newFile } result] {
	return -code error "Error in generating new file: $result"
    }
    if {$yesno} {
	if ![APSYesNoPopUp "Install new generated file $newFile as HVCorr.ramp?"] {
	    return
	}
    }
    set oldDir [pwd]
    cd $refDir
    exec rm HVCorr.ramp
    exec ln -s $newFile HVCorr.ramp
    cd $oldDir
}

proc CheckBTSCharge {args} {
    global ptbCharge btsCharge btsEfficiency abort efficiencyLimit plane
    
    ReadBTSCharge
    return
    while {1} {
	if $abort {
	    Abort -plane $plane
	    return -code error "Checking BTS charge was aborted."
	}
	if {$btsEfficiency>$efficiencyLimit} {
	    break
	} 
	bell
	set answer [APSMultipleChoice [APSUniqueName .] -name Warning \
			-type warning  \
			-question "BTS charge is too low, To continue, you should get BTS charge through first." \
				    -returnList {Fix-And-Continue Check-Again Abort} -labelList {Continue Check-Again Abort} ]
	if {$answer=="Abort"} {
	    return -code error "abort due to low bts charge."
	}
	if {$answer=="Continue"} {
	    break
	}
	ReadBTSCharge
    }
}
proc ReadBTSCharge {args} {
    global ptbCharge btsCharge btsEfficiency
    if [catch {exec cavget -list=PTB:CM:measCurrentCM,BTS:BESOCM:A:DATA:Beam:QM -pend=10 -repeat=number=5,pause=0.5,average} valList] {
	return -code error "error in reading BTS charge: $valList"
    }
    set ptbCharge [lindex $valList 0]
    set btsCharge [lindex $valList 1]
    set btsEfficiency [expr $btsCharge/$ptbCharge]
    
}

proc SelectEvenOdd {args} {
    set category ""
    set type odd
    APSParseArguments {category type}
    
    switch $type {
	even {
	    set value 0
	}
	odd {
	    set value 1
	}
    }
    for {set i 0} {$i<10} {incr i} {
	set sector ${category}C${i}
	global $sector
	if {[expr $i%2]==$value} {
	    #odd
	    set $sector 1
	} else {
	    set $sector 0
	}
    }
}

proc SetupCorrectors {args} {
    SetStatus "setup (initialize) booster correctors before scan..."
    if [catch {exec cavget -list=BOO:LatticeCALC -pend=10} lattice] {
	return -code error "Unable to read lattice: $lattice"
    }
   
    switch $lattice {
        132 {
	    set Lattice x11.75-y9.80
            set refFile Booster-Reference375.gz
	}
	109 {
	    set Lattice x12.75-y9.80
            set refFile Booster-LowE1Reference325.gz
	}
	92 {
	    set Lattice x13.75-y5.80
            set refFile Booster-LowE2Reference375.gz
	}
	default {
            set Lattice "unknown lattice found."
            return
	}
    }
    if [catch {APSMpBoosterSetCorrAndRampsOnOff -SCRFile /home/helios/oagData/SCR/snapshots/Booster/$refFile \
                 -state1 on } result] {
        SetStatus "Error setting up correctors: $result"
        return
    }
    SetStatus "done."
    return
    
    SetStatus "Load corrector ramps..."
    if [catch {APSMpBoosterLoadCorrectorRamps -loadAdl 0 -lattice default} results] {
        return -code error "APSMpBoosterSetCorrAndRampsOnOff: $results"
    }
    update

    SetStatus "Check and Plot corrector ramps..."
    if {[catch {APSMpBoosterCheckCorrectorRampTable -BoosterLattice default} results]} {
        return -code error "APSMpBoosterSetCorrAndRampsOnOff: $results"
    }
    
    SetStatus "done."
    return
    if [catch {APSMpBoosterSetCorrAndRampsOnOff -SCRFile /home/helios/oagData/SCR/snapshots/Booster/Booster-Reference375.gz \
                 -state1 on } result] {
        SetStatus "Error setting up correctors: $result"
        return
    }
    
    SetStatus "done."
}

proc BringUpStripTool {args} {
    global region plane sectorList bsp100sectorList coord efficiencyPV
    
    set tmpRoot /tmp/[APSTmpString]
    set selected 0
    set nm ""
    foreach quad {B1 B2 B3 B4} {
        foreach sector $sectorList {
            set nm ${quad}$sector
	    global $nm
            if [set $nm] {
                set selected 1
                break
            }
        }
    }
    if {!$selected || [lsearch $bsp100sectorList $nm]<0} {
        exec StripTool /home/helios/oagData/booster/ramps/correctors/inputFiles/boosterCorrectorBumpScanConfig &
    } else {
        if [catch {exec replaceText /home/helios/oagData/booster/ramps/correctors/inputFiles/boosterCorrectorBumpScanConfig.template $tmpRoot.strip \
                     -orig=<sector>,<region>,<plane>,<efficiencyPV> -repl=$nm,$region,$coord,$efficiencyPV } result] {
            return -code error "Error creating strip tool config: $result"
        }
        exec StripTool $tmpRoot.strip &
    }
}


set missingList {B1C9V B2C9V B3C9V B4C9V B2C8V}
set missingList1 {B2C6H B2C7H B2C8H B3C1H B3C2H}
set ampStart -1.5
set ampEnd 1.5
set steps 10
set dataDir /home/helios/oagData/booster/ramps/correctors/lattices/
set lattice [file tail [file readlink $dataDir/default]]
set outputDir [APSGoToDailyDirectory -subdirectory 4corrbump ]
set plane H
set coord X

APSApplication . -name Booster4CorrectorBumpScanNew -version $version -overview "Booster new AFG 4-corrector bump scan" \
  -contextHelp "Booster charge measurement with 4-corrector bump."
set mainStatus ""
APSScrolledStatus .status -parent .userFrame -textVariable mainStatus -width 70
#APSRadioButtonFrame .lattice -parent .userFrame -label "lattice" \
#    -buttonList "x11.75-y9.80 x11.75-y9.80-A x12.75-y9.80 x13.75-y5.80" \
#    -valueList "x11.75-y9.80 x11.75-y9.80-A x12.75-y9.80 x13.75-y5.80" -orientation horizontal -variable lattice

APSLabeledEntry .dir -parent .userFrame -label "Output directory:" -textVariable outputDir -width 70
APSFrameGrid .grid1 -parent .userFrame -xList {x1 x2}
set w1 .userFrame.grid1.x1
set w2 .userFrame.grid1.x2
set refDir  /home/helios/oagData/booster/ramps/correctors/lattices/default
set refFile $refDir/HVCorr.ramp
set timeList [exec sdds2stream -page=1 -col=RampTime $refFile]
set len [llength $timeList]
for {set i 2} {$i<[expr $len -1]} {incr i} {
    set time0 [format %.1f [lindex $timeList [expr $i-1]]]
    set time1 [format %.1f [lindex $timeList $i]]
    lappend itemList ${time0}-${time1}
}

set itemList {0 1 2 3 4 5 6 7 8 9}

set region 0
set efficiencyLimit 0.1
set tolerance 0.05
APSLabeledEntry .steps -parent $w1 -label "Steps" -textVariable steps -width 15
APSLabeledEntry .ave -parent $w1 -label "Number of readback average:" -textVariable numToAve -width 15
APSLabeledEntry .pause -parent $w2 -label "Pause after change (s):" -textVariable pauseAfterChange -width 15
APSComboboxFrame .sel -parent $w2 -label "Select Bump region" -textVariable region \
    -itemList $itemList -editable 0 -width 15 -callback "SelectBumpRange -index" \
    -contextHelp "select the start end bump range of RampTime in ms."

APSLabeledEntry .start1 -parent $w1 -label "Start Amplitude(scan)" -textVariable ampStart -width 15
APSLabeledEntry .end1 -parent $w2 -label "End Amplitude(scan)" -textVariable ampEnd -width 15
APSLabeledEntry .eff -parent $w1 -label "BTS efficiency limit:" -textVariable efficiencyLimit -width 15 \
		-contextHelp "the lowest BTS efficiency that it should reach."
set startRegion 0
set endRegion 0
APSLabeledEntryFrame .startend -parent $w1 -label "Bump Start/End Region:" -orientation horizontal -width 10 \
		-variableList {startRegion endRegion}
APSLabeledEntry .tolerance -parent $w2 -label "BTS efficiency tolerance:" -textVariable tolerance -width 15 -contextHelp \
    "the tolerance of BTS efficiency for installing scanned bumps."
APSLabeledEntry .effici -parent $w2 -label "Efficiency for post-processing:" -textVariable processEfficiency -width 15 -contextHelp \
    "desired efficiency for post-processing to be able to install scanned ramps."
#APSRadioButtonFrame .sector -parent .userFrame -label "Sector" -buttonList $sectorList -valueList $sectorList \
#    -variable sector -commandList $commList -limitPerRow 10 -orientation horizontal
set scanType ScanSet
APSRadioButtonFrame .scan -parent .userFrame -label "Scan and Set or Scan and Set Average?" \
    -buttonList {"Scan_Set" "ScanAll_SetAve"} -valueList {ScanSet ScanSetAve} \
    -variable scanType -orientation horizontal
set scanMode Manual
APSRadioButtonFrame .scanmode -parent .userFrame -label "Scan mode:   " -buttonList {Automatic Manual} \
    -valueList {Auto Manual} -variable scanMode -orientation horizontal 
set efficiencyPV BTS:BESOCM:A:DATA:Beam:QM
APSRadioButtonFrame .eff -parent .userFrame -label "Select current pv for efficiency computation:"  -buttonList {BTS Region1 Region2 Region3 Region4} \
    -valueList {BTS:BESOCM:A:DATA:Beam:QM B:diag1:rms:A:region1 B:diag1:rms:A:region2 B:diag1:rms:A:region3 B:diag1:rms:A:region4} \
    -variable efficiencyPV -orientation horizontal
APSRadioButtonFrame .plane -parent .userFrame -buttonList {H V} -label "Select plane:" \
    -valueList {H V} -variable plane -orientation horizontal -commandList {"set coord X" "set coord Y"}

APSFrame .f1 -parent .userFrame -label "Quadrant Selection"
set w1 .userFrame.f1.frame
set sectorList {C0 C1 C2 C3 C4 C5 C6 C7 C8 C9}
foreach cat {B1 B2 B3 B4} {
    set varList ""
    foreach but $sectorList {
	set ${cat}$but 0
	lappend varList ${cat}$but
    }
    APSCheckButtonFrame .c$cat -parent $w1 -label "$cat" -buttonList $sectorList -variableList $varList \
    -orientation horizontal -allNone 1
    APSButton .c1 -parent $w1.c$cat -packOption "-side right" -text "Odd" -size small -command "SelectEvenOdd -category $cat -type odd"
    APSButton .c2 -parent $w1.c$cat -packOption "-side right" -text "Even" -size small -command "SelectEvenOdd -category $cat -type even"
}

set abort 0
APSButton .all -parent $w1 -text "Select All" -command "SelectAll -all 1" -size small
APSButton .clear -parent $w1 -text "Clear All" -command "SelectAll -all 0" -size small
APSButton .gen -parent .userFrame -text GenerateBump -command "GenerateBump"
APSButton .load -parent .userFrame -text LoadBump -command "LoadBump"
APSButton .setup -parent .userFrame -text "SetupCorrectors" -command "SetupCorrectors" -contextHelp \
  "initialize correctors before scan to make sure the correctors are in correct state."
APSButton .start -parent .userFrame -text StartScan -command "StartScan"
APSButton .proc -parent .userFrame -text "PostProcess" -command "Postprocess"
APSButton .ref -parent .userFrame -text "MakeReference" -command "MakeReference"
APSButton .abort -parent .userFrame -text "Abort" -command "set abort 1"
APSButton .strip -parent .userFrame -text "StripTool" -command "BringUpStripTool"

