#!/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.S
#
#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 "Booster4CorrectorBumpScan\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 startBump endBump ampStart lattice dataDir outputDir sectorList ampStart ampEnd missingList
    if {![string length $startBump] || ![string length $endBump]} {
	return -code error "Bump range not selected."
    }
    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 SetBoosterDCAmplitude \
			       -outDir $outputDir \
			       -plane $plane -sector $nm -lattice $lattice \
			       -amplitude $amplitude } result] {
		    return -code error "SetBoosterBumpAmplitude: $result"
		}
		SetStatus "$result"
		lappend fileList $outputDir/${nm}$plane.ramp
	    }
	}
    }
    if [llength $fileList] {
    	eval exec sddsplot -col=RampTime,OriginalRampSetpoint -col=RampTime,RampSetpoint -sep=2 -split=page  \
	    -leg -grap=line,vary -topline=@CorrName -title=@Sector $fileList &
    }
}

proc LoadBump {args} {
    global dataDir lattice sectorList plane outputDir startBump
    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 && \
		    $startBump >=160 {
		    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 startBump endBump outputDir btsCharge ptbCharge btsEfficiency abort bestAmp scanMode prevReference tolerance
    global region
    
    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 &
    if [catch {exec sddsprocess $filename $filename.1 "-redefine=par,StartBump,$startBump" \
		   "-test=col,PTB:CM:measCurrentCM 0 >" \
		   "-redefine=col,BTSEfficiency,B:diag1:rms:A:region$region " \
		   "-redefine=par,EndBump,$endBump"} result] {
	return -code error $result
    }
    if [catch {exec sddssmooth $filename.1 -pipe=out \
                 -col=BTSEfficiency \
                 | sddsprocess -pipe=in $filename.proc \
                 -process=BTSEfficiency,maximum,amplitudeMax,position,functionOf=BpmAmplitude } result] {
        return -code error "Error processing data: $result"
    }
    exec mv $filename.1 $filename
    catch {file delete -force $outputDir/${sector}${plane}.ramp}
   
    exec sddsplot -col=BpmAmplitude,BTSEfficiency $filename -topline=${sector}$plane &
    
    set maxAmp [ exec  sdds2stream -para=amplitudeMax $filename.proc ]
    set bestAmp [exec sdds2stream -par=amplitudeMax $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 SetBoosterDCAmplitude \
                 -outDir $outputDir -load 0 \
                 -plane $plane -sector $sector   -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,Booster:ControlLawYRC \
                             -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 startBump endBump 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  SetBoosterDCAmplitude \
		       -outDir $outputDir -load 1 \
		       -plane $plane -sector $sector -lattice $lattice \
		        -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 SetBoosterDCAmplitude  \
		       -outDir $outputDir -load 1 \
		       -plane $plane -sector $sector -lattice $lattice \
		       -startBump $startBump -endBump $endBump -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 startBump endBump
    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]
    puts $tmpFile
    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]]
    
#    SetStatus "Testing start amp $ampStart1..."
#    if [catch {exec /home/helios/SHANG/oag/apps/src/tcltkapp/oagapp/SetBoosterBumpAmplitude \
#		   -outDir $outputDir \
#		   -plane $plane -sector $sector -lattice $lattice \
#		   -startBump $startBump -endBump $endBump -amplitude $ampStart1 } result] {
#	return -code error "Invalid start amplitude ($ampStart1) for $sector: $result"
#    }
#    global btsEfficiency
#    ReadBTSCharge
#    if {$btsEfficiency>0.8} {
#	return -code error "Improper start amplitude ($ampStart1) for $sector, the BTS efficiency at this point is too high (greater than 80%)."
#    }
#    if [catch {LoadReference -plane $plane} result] {
#	return -code error "Error in loading reference: $result"
#    }
#    
#    SetStatus "Testing end amp $ampEnd1..."
#    if [catch {exec /home/helios/SHANG/oag/apps/src/tcltkapp/oagapp/SetBoosterBumpAmplitude \
#		   -outDir $outputDir \
#		   -plane $plane -sector $sector -lattice $lattice \
#		   -startBump $startBump -endBump $endBump -amplitude $ampEnd1 } result] {
#	return -code error "Invalid end amplitude ($ampEnd1) for $sector: $result"
#    }
#    ReadBTSCharge
#    if {$btsEfficiency>0.8} {
#	return -code error "Improper end amplitude ($endStart1) for $sector, the BTS efficiency at this point is too high (greater than 80%)."
#    }
    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,Booster:ControlLawYRC \
		       -list=.SUSP=0 -pend=10} result] {
	    return -code error $result
	}
	SetStatus "Aborted."
    }
}
set numToAve 10 
set pauseAfterChange 2 
set bestAmp 0.01
proc StartScan {args} {
    global plane sectorList inputDir outputDir ampStart ampEnd steps numToAve pauseAfterChange scanType ampStart1 ampEnd1
    global lattice startBump endBump specialList missingList ptbCharge btsCharge btsEfficiency lastEfficiency abort skipSector
    global scanMode
    set skipSector 0
    if {![string length $startBump] || ![string length $endBump]} {
	return -code error "bump range not selected."
    }
    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,Booster:ControlLawYRC \
			       -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
                }
		set expFile $outputDir/${nm}${plane}.exp
		if [catch {exec replaceText /home/helios/oagData/booster/ramps/correctors/inputFiles/DCscanNew.exp $expFile \
			       -orig=<steps>,<start>,<end>,<numToAve>,<plane>,<sector>,<post_pause>,<lattice> \
			       -repl=$steps,$ampStart,$ampEnd,$numToAve,$plane,$nm,$pauseAfterChange,$lattice } 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."
	    }
	}
    }
    if {$scanType=="ScanSetAve"} {
	PostprocessAll
    }
    
}

proc ChangeLattice {args} {
    global dataDir lattice
    

}

proc SelectBumpRange {args} {
    set index ""
    APSStrictParseArguments {index}
    
    global dataDir lattice startBump endBump itemList
    set tmpList [split [lindex $itemList $index] "-"]
    set startBump [lindex $tmpList 0]
    set endBump [lindex $tmpList 1]
}

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}
    global lattice
    set refDir  /home/helios/oagData/booster/ramps/correctors/lattices/$lattice
    set refFile $refDir/HVCorr.ramp
    SetStatus "loading reference ramp..."
    if [catch {exec ramploadnew $refFile} result] {
	return -code error "Error in loading ramp: $result"
    }
    SetStatus "done."
}

proc MakeReference {args} {
    set newRampFile ""
    set yesno 1
    APSParseArguments {newRampFile yesno}
    global outputDir plane lattice
    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/$lattice
    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
    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 region
    if [catch {exec cavget -list=PTB:CM:measCurrentCM,BTS:CM:q.VAL -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]
    if [catch {exec cavget -list=B:diag1:rms:A:region$region -pend=30} btsEfficiency] {
        return -code error "Error reading B:diag1:rms:A:region3: $result"
    }
    
}

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 Lattice x13.75-y5.80-0015-DC
            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 $Lattice} results] {
        return -code error "APSMpBoosterSetCorrAndRampsOnOff: $results"
    }
    update

    SetStatus "Check and Plot corrector ramps..."
    if {[catch {APSMpBoosterCheckCorrectorRampTable -BoosterLattice $Lattice} 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."
}

set startBump ""
set endBump ""
set missingList {B1C9V B2C9V B3C9V B4C9V B2C8V}
set missingList1 {B2C6H B2C7H B2C8H B3C1H B3C2H}
set ampStart -0.1
set ampEnd 0.1
set steps 10
set dataDir /home/helios/oagData/booster/ramps/correctors/lattices/
set lattice x13.75-y5.80-0015-DC
set outputDir [APSGoToDailyDirectory -subdirectory 4corrbump ]
set plane H

APSApplication . -name Booster4CorrectorDCScan -version $version -overview "Booster new AFG 4-corrector DC 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-0015-DC" \
    -valueList "x11.75-y9.80 x11.75-y9.80-A x12.75-y9.80 x13.75-y5.80-0015-DC" -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 %.0f [lindex $timeList [expr $i-1]]]
    set time1 [format %.0f [lindex $timeList $i]]
	lappend itemList ${time0}-${time1}
}
set bumpIndex 12-86
set startBump 12
set endBump 86
#puts $itemList 
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 range" -textVariable bumpIndex \
#    -itemList $itemList -editable 0 -width 15 -callback "SelectBumpRange -index" \
#    -contextHelp "select the start end bump range of RampTime in ms."
#APSLabeledOutput .start -parent $w1 -label "Start Bump (ms)" -textVariable startBump -width 15
#APSLabeledOutput .end -parent $w2 -label "End Bump (ms)" -textVariable endBump -width 15
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."
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 region 3
APSRadioButtonFrame .region -parent .userFrame -label "Booster charge region:" -variable region \
  -buttonList {0 1 2 3 4 5 6 7 8 9} -valueList {0 1 2 3 4 5 6 7 8 9} -orientation horizontal

APSRadioButtonFrame .plane -parent .userFrame -buttonList {H V} -label "Select plane:" \
    -valueList {H V} -variable plane -orientation horizontal

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 "exec StripTool  /home/helios/BOOSTER/StripToolConfig/boosterCorrectorBumpScanConfig &"
