#!/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 $"
set mainStatus ""

APSApplication . -name optimizeBoosterRamps -version $CVSRevisionAuthor \
  -overview {This interface provides a simple interface to optimize booster main power supply ramps.}

APSScrolledStatus .status -parent .userFrame -textVariable mainStatus \
  -width 110 -height 5

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


set BM 0
set QF 0
set QD 0
set SF 0
set SD 0
set deltaStart -2.5
set deltaEnd 2.5
set stepSize 0.25
set tolerance 1.0e-4
set correctionTimes 10
set start 10
set end 13
set abort 0

proc GenerateIRampReference {args} {
    #suspend bcontrol
    SetStatus "Regenerate IRef ..."
    if [catch {exec cavget -list=B:SD-U:PoweredM -pend=10} SDstate] {
        return -code error "Error reading B:SD-U:PoweredM: $SDstate"
    }
    switch $SDstate {
        B:SD {
            set magnetList {BM QF QD SF SD}
        }
        B:SD-U {
            set magnetList {BM QF QD SF SD-U}
        }
        default {
            setStatusText "Unknown SD status: $SDstate; nothing will be done for SD/SD-U"
            set magnetList {BM QD QF SF}
        }
    }
    if [catch {exec cavget -list=B: -list=[join $magnetList ,] -list=:IRampDelayErrAI -pend=10} delayList] {
        return -code error "Error in reading delay pvs: $delayList"
    }
    set error 0
    foreach magnet $magnetList delay $delayList {
        if {[expr abs($delay)]>0.2} {
            setStatusText "$magnet delay error is $delay, too big."
            incr error
        }
    }
    if $error {
        return -code error "generating reference was aborted due to too big delay error."
    }
    
    
    if [catch {exec cavput -list=B: -list=BM,QF,QD,SF,SD  -list=bcontrollawRC.SUSP=1 -pend=30} result] {
        return -code error "Error in suspend bcontrols: $result"
    }
  
    if [catch {exec cavput -list=B:InjTune:ControllawRC.ABRT=1 -pend=30 } result] {
         return -code error "Error in suspend injection controllaw: $result"
    }
    
    set refDir /home/helios/oagData/booster/ramps/IRamp/current-IRamp
    set lattice [file readlink /home/helios/oagData/booster/ramps/IRamp]
    set oldFile [file readlink $refDir/IRef]
    set newName [APSNextGenerationedName -directory $refDir -name IRef-0000 -newFile 1 -separator -]
    
    if [catch {exec GetBooRampCurrWF -filename $refDir/$newName } result] {
        return -code error "Error in creating IRamp reference."
    }
  
    if [catch {exec cavput -list=B: -list=[join $magnetList ,] -list=:IRampGainSetAI=1 -pend=10
        exec cavput -list=B: -list=[join $magnetList ,] -list=:IRampDelayOffsetAI=0 -pend=10 } result] {
        return -code error "Error in setting IRamp gain to 1 and delay to 0: $result"
    }
    
    set tmpRoot /tmp/[APSTmpString]
    
    foreach magnet $magnetList {
        if [catch {exec sddsconvert $refDir/$newName -pipe=out \
                     -retain=col,Index,B:${magnet}:CurrentWF -retain=par,${magnet}* \
                     | sddsconvert -pipe -rename=col,B:${magnet}:CurrentWF=Waveform \
                     | sddsprocess -pipe=in -reprint=par,WaveformPV,B:${magnet}:IRampRefWF $tmpRoot.$magnet} result] {
            return -code error $result
        }
        set gain [exec sdds2stream -par=${magnet}AfgGain $tmpRoot.$magnet]
        set delay [exec sdds2stream -par=${magnet}TriggerDelay $tmpRoot.$magnet]
        if [catch {exec cavput -list=B:${magnet}:RefAfgGain=$gain,B:${magnet}:RefTriggerDelay=$delay -pend=20
            exec sddswput $tmpRoot.$magnet -pend=20 } result] {
            return -code error "error in setting reference pvs: $result"
        }
    }
    set oldDir [pwd]
    cd $refDir
    exec rm IRef
    exec ln -s $newName IRef
    cd $oldDir
    file delete -force $tmpRoot.BM $tmpRoot.QF $tmpRoot.QD $tmpRoot.SF $tmpRoot.SD
    
    if [catch {APSSaveMachine -machine Booster -description "Save QF and QD trigger delay offset after generating IRamp reference." } result] {
        return -code error "Error in saving booster SCR: $result"
    }
   
    if [catch {exec cavput -list=B: -list=BM,QF,QD,SF,SD -list=:IRampDelayOffsetAI=0 -pend=10} result] {
        APSMpReturn error "Error in reseting QF, QD trigger offset: $result"
    }
    
    after 1000
  
    if [catch {exec cavput -list=B: -list=BM,QF,QD,SF,SD  -list=bcontrollawRC.SUSP=0 -pend=30} result] {
        return -code error "Error in resume bcontrols: $result"
    }
    SetStatus "Load new IRef..."
    if [catch {LoadIRampReference} result] {
        return -code error "Error loading reference: $result"
    }
    SetStatus "done."
}

proc LoadIRampReference {args} {
    set refFile /home/helios/oagData/booster/ramps/IRamp/current-IRamp/IRef
    set tmpRoot  /tmp/[APSTmpString]
    
    if [catch {exec cavget -list=B:SD-U:PoweredM -pend=10} SDstate] {
        return -code error "Error reading B:SD-U:PoweredM: $SDstate"
    }
    switch $SDstate {
        B:SD {
            set magnetList {BM QF QD SF SD}
        }
        B:SD-U {
            set magnetList {BM QF QD SF SD-U}
        }
        default {
            setStatusText "Unknown SD status: $SDstate; nothing will be done for SD/SD-U"
            set magnetList {BM QD QF SF}
        }
    }
    
    foreach magnet $magnetList {
        if [catch {exec sddsconvert $refFile -pipe=out \
                     -retain=col,Index,B:${magnet}:CurrentWF -retain=par,${magnet}* \
                     | sddsconvert -pipe -rename=col,B:${magnet}:CurrentWF=Waveform \
                     | sddsprocess -pipe=in -reprint=par,WaveformPV,B:${magnet}:IRampRefWF $tmpRoot.$magnet} result] {
            return -code error $result
        }
        set gain [exec sdds2stream -par=${magnet}AfgGain $tmpRoot.$magnet]
        set delay [exec sdds2stream -par=${magnet}TriggerDelay $tmpRoot.$magnet]
        if [catch {exec cavput -list=B:${magnet}:RefAfgGain=$gain,B:${magnet}:RefTriggerDelay=$delay -pend=20
            exec sddswput $tmpRoot.$magnet -pend=20 } result] {
            return -code error "error in setting reference pvs: $result"
        }
        lappend fileList $tmpRoot.$magnet
    }
    eval file delete -force $fileList
}




proc CreateZeroShiftParametersWidget {args} {
    set parent ""
    APSParseArguments {parent}
    
    global BM QF QD SF SD deltaStart deltaEnd stepSize tolerance correctionTimes start end abort
    
   
    APSFrameGrid .grid -parent $parent -xList {x1 x2}
    set w1 $parent.grid.x1
    set w2 $parent.grid.x2
    set width 20
    APSLabeledEntry .lower -parent $w1 -label "Shift lower limit (ms):" -width $width -textVariable start
    APSLabeledEntry .upper -parent $w2 -label "Shift upper limit (ms):" -width $width -textVariable end
    APSLabeledEntry .change -parent $w1 -label "Step size (ms):" -width $width -textVariable stepSize
    
    
    APSButton .run -parent $parent -text "StartScan" -command StartZeroShiftScan
    APSButton .abort -parent $parent -text "Abort" -command {set abort 1}
    APSButton .plot -parent $parent -text "PlotScan" -command "PlotScan -shift 1"
}

proc CreateHLTImeParametersWidget {args} {
    set parent ""
    APSParseArguments {parent}
    
    APSFrameGrid .grid -parent $parent -xList {x1 x2}
    set w1 $parent.grid.x1
    set w2 $parent.grid.x2
    set width 20
    global HLtimeStart HLtimeEnd HLtimeStepSize HLtype
    set HLtimeStart -3.0
    set HLtimeEnd 3.0
    set HLtimeStepSize 0.5
    set HLtype HTime
    APSLabeledEntry .lower -parent $w1 -label "Start change (ms):" -width $width -textVariable HLtimeStart
    APSLabeledEntry .upper -parent $w2 -label "End change (ms):" -width $width -textVariable HLtimeEnd
    APSLabeledEntry .change -parent $w1 -label "Step size (ms):" -width $width -textVariable HLtimeStepSize
    APSRadioButtonFrame .type -parent $w2 -label "Scan HTime/LTime" -buttonList {HTime LTime} -valueList {HTime LTime} -variable HLtype \
      -orientation horizontal
    
    APSButton .run -parent $parent -text "StartScan" -command StartHLTimeScan
    APSButton .abort -parent $parent -text "Abort" -command {set abort 1}
    APSButton .plot -parent $parent -text "PlotScan" -command "PlotScan -Htime 1"
}


proc CreateStartRampParametersWidget {args} {
    set parent ""
    APSParseArguments {parent}
    
   
    set width 25
    global StartRampStart StartRampEnd StartRampStepSize 
    set StartRampStart -5.0
    set StartRampEnd 0
    set StartRampStepSize 0.5
   
    APSLabeledEntry .lower -parent $parent -label "Start change (ms):" -width $width -textVariable StartRampStart
    APSLabeledEntry .upper -parent $parent -label "End change (ms):" -width $width -textVariable StartRampEnd
    APSLabeledEntry .change -parent $parent  -label "Step size (ms):" -width $width -textVariable StartRampStepSize
    
    
    APSButton .run -parent $parent -text "StartScan" -command StartStartRampScan
    APSButton .abort -parent $parent -text "Abort" -command {set abort 1}
    APSButton .plot -parent $parent -text "PlotScan" -command "PlotScan -startRamp 1"
}

proc CreateNewADCDelayParametersWidget {args} {
    set parent ""
    APSParseArguments {parent}
    
    global NewADCDelayStart NewADCDelayEnd NewADCDelayStepSize

    set NewADCDelayStart -2.5
    set NewADCDelayEnd  2.5
    set NewADCDelayStepSize 0.25
    set width 25
    
    APSLabeledEntry .lower -parent $parent -label "Start change (ms):" -width $width -textVariable NewADCDelayStart
    APSLabeledEntry .upper -parent $parent -label "End change (ms):" -width $width -textVariable NewADCDelayEnd
    APSLabeledEntry .change -parent $parent  -label "Step size (ms):" -width $width -textVariable NewADCDelayStepSize
    
    
    APSButton .run -parent $parent -text "StartScan" -command StartNewADCDelayScan
    APSButton .abort -parent $parent -text "Abort" -command {set abort 1}
    APSButton .plot -parent $parent -text "PlotScan" -command "PlotScan -newADCdelay 1"

}

proc CreateFreeWheelParametersWidget {args} {
    set parent ""
    APSParseArguments {parent}
    global FreeWheelStart FreeWheelEnd FreeWheelStepSize
    set FreeWheelStart -5
    set FreeWheelEnd 5
    set FreeWheelStepSize 0.5
    set width 25

    APSLabeledEntry .lower -parent $parent -label "Start change (ms):" -width $width -textVariable FreeWheelStart
    APSLabeledEntry .upper -parent $parent -label "End change (ms):" -width $width -textVariable FreeWheelEnd
    APSLabeledEntry .change -parent $parent  -label "Step size (ms):" -width $width -textVariable FreeWheelStepSize
    
    
    APSButton .run -parent $parent -text "StartScan" -command StartFreeWheelScan
    APSButton .abort -parent $parent -text "Abort" -command {set abort 1}
    APSButton .plot -parent $parent -text "PlotScan" -command "PlotScan -freeWheel 1"
    
}

proc StartZeroShiftScan {args} {
    global BM QF QD SF SD deltaStart deltaEnd dir stepSize tolerance  correctionTimes inputDir dir start end abort
    
    set run 0
    cd $dir
    foreach magnet {BM QF QD SF SD} {
        if [set $magnet] {
            set run 1
            #above auto-correction
            if [catch {exec cavput -list=B:${magnet}:AutoCorrectionControlRC.ABRT=1 -pend=20} result] {
                return -code error "$result"
            }
            if [file exist ${magnet}-shift.log] {
                exec rm ${magnet}-shift.log
            }
            set fileID [open ${magnet}-shift.log "w"]
            puts $fileID "SDDS1"
            puts $fileID "&parameter name=Magnet, type=string, &end"
            puts $fileID "&column name=Step, type=long, &end"
            puts $fileID "&column name=Shift, type=double, &end"
            puts $fileID "&column name=RMSvalue, type=double, &end"
            puts $fileID "&data mode=ascii, no_row_counts=1. &end"
            puts $fileID $magnet
            flush $fileID
            
            set step 0 
            set value $start
            SetStatus "Starting scan for $magnet..."
            while {$value<=$end} {
                if $abort {
                    set abort 0
                    break
                }
                SetStatus "change shift to $value ..."
                catch {exec cavput -list=B:BconLockoutAO=$value -pend=20}
                update
                if [catch {ChangeParameters -magnet $magnet -shift $value } result] {
                    return -code error "Error in changing shift for $magnet: $result"
                }
                puts $fileID "$step $value $result"
                flush $fileID
                incr step
                set value [expr $value + $stepSize]
            }
            close $fileID
            SetStatus "Data for $magnet collected."
        }
    }
    if !$run {
        SetStatus "No magnet selected."
    }
}

proc StartHLTimeScan {args} {
    global BM QF QD SF SD HLtimeStart HLtimeEnd HLtimeStepSize tolerance  correctionTimes inputDir dir abort HLtype
   
    set run 0
    cd $dir
    foreach magnet {BM QF QD SF SD} {
        if [set $magnet] {
            set run 1
            #above auto-correction
            if [catch {exec cavput -list=B:${magnet}:AutoCorrectionControlRC.ABRT=1 -pend=20} result] {
                return -code error "$result"
            }
            if [file exist ${magnet}-$HLtype.log] {
                exec rm ${magnet}-$HLtype.log
            }
            set fileID [open ${magnet}-$HLtype.log "w"]
            puts $fileID "SDDS1"
            puts $fileID "&parameter name=Magnet, type=string, &end"
            puts $fileID "&column name=Step, type=long, &end"
            puts $fileID "&column name=HLtimeDelta, type=double, &end"
            puts $fileID "&column name=RMSvalue, type=double, &end"
            puts $fileID "&data mode=ascii, no_row_counts=1. &end"
            puts $fileID $magnet
            flush $fileID
            
            set step 0
            set value $HLtimeStart
            SetStatus "Starting $HLtype scan for $magnet..."
            switch $HLtype {
                HTime {
                    set var1 HTime
                    set var2 HHTime
                }
                LTime {
                    set var1 LTime
                    set var2 LLTime
                }
            }
            set time1 [exec sddsprocess /home/helios/oagData/booster/ramps/IRamp/rampParametersCurrent.sdds -match=par,Supply=$magnet \
                         -pipe=out -match=col,VariableName=$var1 | sdds2stream -pipe -col=Value]
            set time2 [exec sddsprocess /home/helios/oagData/booster/ramps/IRamp/rampParametersCurrent.sdds -match=par,Supply=$magnet \
                         -pipe=out -match=col,VariableName=$var2 | sdds2stream -pipe -col=Value]
            SetStatus "$value $HLtimeEnd ($time1 $time2)"
            while {$value<=$HLtimeEnd} {
                if $abort {
                    break
                }
                set Time0 [expr $time1 + $value]
                if {$Time0<0} {
                    set value [expr $value + $HLtimeStepSize]
                    continue
                }
                set Time00 [expr $time2 + $value]
                
                SetStatus "change $HLtype by $value ($Time0 $Time00) ..."
                catch {exec cavput -list=B:BconLockoutAO=$value -pend=20}
                update
                switch $HLtype {
                    HTime {
                        if [catch {ChangeParameters -magnet $magnet -HTime $Time0 -HHTime $Time00 } rms] {
                            close $fileID
                            return -code error "Error scan1: $rms"
                        }
                    } 
                    LTime {
                         if [catch {ChangeParameters -magnet $magnet -LTime $Time0 -LLTime $Time00 } rms] {
                            close $fileID
                            return -code error "Error scan1: $rms"
                        }
                    }
                }
                puts $fileID "$step $value $rms"
                flush $fileID
                incr step
                set value [expr $value + $HLtimeStepSize]
            }
            close $fileID
            SetStatus "Data for $magnet collected."
        }
    }
    if !$run {
        SetStatus "No magnet selected."
    }
}

proc StartStartRampScan {args} {
    global BM QF QD SF SD StartRampStart StartRampEnd dir StartRampStepSize
    global correctionTimes inputDir  abort dir
    
    set run 0
    cd $dir
    foreach magnet {BM QF QD SF SD} {
        if [set $magnet] {
            set run 1
            #above auto-correction
            if [catch {exec cavput -list=B:${magnet}:AutoCorrectionControlRC.ABRT=1 -pend=20} result] {
                return -code error "$result"
            }
            
            if [file exist ${magnet}-startramp.log] {
                exec rm ${magnet}-startramp.log
            }
            set fileID [open ${magnet}-startramp.log "w"]
            puts $fileID "SDDS1"
            puts $fileID "&parameter name=Magnet, type=string, &end"
            puts $fileID "&column name=Step, type=long, &end"
            puts $fileID "&column name=StartRamp, type=double, &end"
            puts $fileID "&column name=RMSvalue, type=double, &end"
            puts $fileID "&data mode=ascii, no_row_counts=1. &end"
            puts $fileID $magnet
            flush $fileID
            set step 0 
            set value $StartRampStart
            
            if [catch {exec cavget -list=It:Bs:StartRamp2BsIp.VAL -pend=30 -printErrors } startValue] {
                return -code error "Error reading start ramp value: $startValue"
            }
            SetStatus "Starting start ramp scan for $magnet..."
            while {$value<=$StartRampEnd} {
                if $abort {
                    set abort 0
                    break
                }
                SetStatus "change start ramp by $value ..."
                set newValue [expr $startValue + $value]
                if [catch {exec cavput -list=It:Bs:StartRamp2BsIp.VAL=$newValue  -pend=20} result] {
                    return -code error "Error changing start ramp : $result"
                }
                update
                if [catch {ChangeStartRamp -magnet $magnet } rms] {
                    close $fileID
                    return -code error "Error scan1: $rms"
                }
                
                puts $fileID "$step $newValue $rms"
                flush $fileID
                SetStatus "Reading $magnet AFG waveform and current waveform..."
                if [catch {exec GetBooRampCurrWF -filename ${magnet}CurrentWF.step$step } result] {
                    return -code error "Error reading current waveform: $result"
                }
                exec cp /home/helios/oagData/booster/ramps/IRamp/current-IRamp/${magnet}Vref.afg100 ${magnet}Vref.afg100.step$step
                
                set value [expr $value + $StartRampStepSize]
                incr step
            }
            close $fileID
            SetStatus "Data for $magnet collected."
        }
    }
    if !$run {
        SetStatus "No magnet selected."
    }
}

proc StartNewADCDelayScan {args} {
    global BM QF QD SF SD NewADCDelayStart NewADCDelayEnd NewADCDelayStepSize
    global correctionTimes inputDir  abort dir
    
    set run 0
    cd $dir
    foreach magnet {BM QF QD SF SD} {
        if [set $magnet] {
                set run 1
            #above auto-correction
            if [catch {exec cavput -list=B:${magnet}:AutoCorrectionControlRC.ABRT=1 -pend=20} result] {
                return -code error "$result"
            }
            
            if [file exist ${magnet}-newADCdelay.log] {
                exec rm ${magnet}-newADCdelay.log
            }
            set fileID [open ${magnet}-newADCdelay.log "w"]
            puts $fileID "SDDS1"
            puts $fileID "&parameter name=Magnet, type=string, &end"
            puts $fileID "&column name=Step, type=long, &end"
            puts $fileID "&column name=ADCdelay, type=double, &end"
            puts $fileID "&column name=RMSvalue, type=double, &end"
            puts $fileID "&data mode=ascii, no_row_counts=1. &end"
            puts $fileID $magnet
            flush $fileID
            set step 0 
            set value $NewADCDelayStart
            
            if [catch {exec cavget -list=B:${magnet}:SlopeInterceptSUB.D -pend=30 -printErrors } startValue] {
                return -code error "Error reading new ADC delay: $startValue"
            }
            SetStatus "Starting start new ADC delay scan for $magnet..."
            while {$value<=$NewADCDelayEnd} {
                if $abort {
                    set abort 0
                    break
                }
                SetStatus "change start new ADC delay by $value ..."
                set newValue [expr $startValue + $value]
                if [catch {exec cavput -list=B:${magnet}:SlopeInterceptSUB.D=$newValue  -pend=20} result] {
                    return -code error "Error new ADC delay : $result"
                }
                update
                if [catch {ChangeParameters -magnet $magnet } rms] {
                    close $fileID
                    return -code error "Error scan1: $rms"
                }
                
                puts $fileID "$step $newValue $rms"
                flush $fileID
                SetStatus "Reading $magnet AFG waveform and current waveform..."
                if [catch {exec GetBooRampCurrWF -filename ${magnet}CurrentWF.step$step } result] {
                    return -code error "Error reading current waveform: $result"
                }
                exec cp /home/helios/oagData/booster/ramps/IRamp/current-IRamp/${magnet}Vref.afg100 ${magnet}Vref.afg100.step$step
                
                set value [expr $value + $NewADCDelayStepSize]
                incr step
            }
            close $fileID
            SetStatus "Data for $magnet collected."
        }
    }
    if !$run {
        SetStatus "No magnet selected."
    }
}

proc StartFreeWheelScan {args} {
    #only for BM
    global FreeWheelStart FreeWheelEnd FreeWheelStepSize
    global correctionTimes inputDir  abort dir
    
    set run 0
    cd $dir
    #only for BM
    set magnet BM
    set run 1
            #above auto-correction
    if [catch {exec cavput -list=B:${magnet}:AutoCorrectionControlRC.ABRT=1 -pend=20} result] {
	return -code error "$result"
    }
    
    if [file exist ${magnet}-freeWheel.log] {
	exec rm ${magnet}-freeWheel.log
    }
    set fileID [open ${magnet}-freeWheel.log "w"]
    puts $fileID "SDDS1"
    puts $fileID "&parameter name=Magnet, type=string, &end"
    puts $fileID "&column name=Step, type=long, &end"
    puts $fileID "&column name=FreeWheel, type=double, &end"
    puts $fileID "&column name=RMSvalue, type=double, &end"
    puts $fileID "&data mode=ascii, no_row_counts=1. &end"
    puts $fileID $magnet
    flush $fileID
    set step 0 
    set value $FreeWheelStart
    set PV It:Bs:BmFreeWheelOnAO
    if [catch {exec cavget -list=$PV -pend=30 -printErrors } startValue] {
	return -code error "Error reading free wheel time: $startValue"
    }
    SetStatus "Starting start free wheel scan for $magnet..."
    set step 0
    while {$value<=$FreeWheelEnd} {
	if $abort {
	    set abort 0
	    break
	}
	SetStatus "change start free wheel by $value ..."
	set newValue [expr $value + $startValue]
	if [catch {exec cavput -list=$PV=$newValue  -pend=20} result] {
	    return -code error "Error free wheel : $result"
	}
	update
	if [catch {ChangeParameters -magnet $magnet } rms] {
	    clqose $fileID
	    retqurn -code error "Error scan1: $rms"
	}
	
	puts $fileID "$step $newValue $rms"
	flush $fileID
	
	SetStatus "Reading $magnet AFG waveform and current waveform..."
	if [catch {exec GetBooRampCurrWF -filename ${magnet}CurrentWF.step$step } result] {
	    return -code error "Error reading current waveform: $result"
	}
	exec cp /home/helios/oagData/booster/ramps/IRamp/current-IRamp/${magnet}Vref.afg100 ${magnet}Vref.afg100.step$step
	
	set value [expr $value + $FreeWheelStepSize]
	incr step
    }
    close $fileID
    SetStatus "Data for $magnet collected."
    
}


proc ChangeParameters {args} {
    set magnet ""
    set shift ""
    set HTime ""
    set HHTime ""
    set LTime ""
    set LLTime ""
    APSParseArguments {magnet shift HTime HHTime LTime LLTime}
    
    global correctionTimes abort
    SetStatus "Loading safety for $magnet ..."
    if [catch {APSBoosterLoadSafetyRamp -Magnet $magnet -IRamp 1} result] {
        return -code error "Error in loading safety ramp: $result"
    }
    after 2000
    SetStatus "Correct ramp for $correctionTimes times ..."
    for {set i 0} {$i<$correctionTimes} {incr i} {
        if $abort {
            set abort 0
            return -code error "Scan was abort."
        }
        if [catch {BoosterRampVCurrentCorrectAndCheck -supply $magnet \
                     -shift0 $shift -HTime1 $HTime -HHTime1 $HHTime -LTime1 $LTime -LLTime1 $LLTime \
                     -statusCallback "SetStatus" } result] {
            SetStatus "$result"
            break
        }
        after 2000
    }
    if [catch {exec cavget -list=B:${magnet}:IRampRMSAI -repeat=number=20,pause=0.5,ave -pend=20 -printErrors} rms] {
        return -code error "Error in reading rms: $rms"
    }
    return $rms
}

proc ChangeStartRamp {args} {
    set magnet ""
    APSParseArguments {magnet}
    
    global correctionTimes abort
    SetStatus "Loading safety for $magnet ..."
    if [catch {APSBoosterLoadSafetyRamp -Magnet $magnet -IRamp 1} result] {
        return -code error "Error in loading safety ramp: $result"
    }
    after 2000
    SetStatus "Correct ramp for $correctionTimes times ..."
    for {set i 0} {$i<$correctionTimes} {incr i} {
        if $abort {
            set abort 0
            return -code error "Scan was abort."
        }
        if [catch {BoosterRampVCurrentCorrectAndCheck -supply $magnet  -statusCallback "SetStatus" } result] {
            SetStatus "$result"
            break
        }
        after 2000
    }
    SetStatus "Regenerate IRef ..."
    if [catch {GenerateIRampReference } result] {
        return -code error "Error generating IRef..."
    }
    
    SetStatus "Correct ramp for $correctionTimes again..."
    
    for {set i 0} {$i<$correctionTimes} {incr i} {
        if $abort {
            set abort 0
            return -code error "Scan was abort."
        }
        if [catch {BoosterRampVCurrentCorrectAndCheck -supply $magnet -statusCallback "SetStatus" } result] {
            SetStatus "$result"
            break
        }
        after 2000
    }
    if [catch {exec cavget -list=B:${magnet}:IRampRMSAI -repeat=number=20,pause=0.5,ave -pend=20 -printErrors} rms] {
        return -code error "Error in reading rms: $rms"
    }
    return $rms
}


proc PlotScan {args} {
    set shfit 0
    set Htime 0
    set startRamp 0
    set freeWheel 0
    set newADCdelay 0
    APSParseArguments {shift Htime startRamp freeWheel newADCdelay}
    global dir BM QF QD SF SD
    cd $dir
    foreach magnet {BM QF QD SF SD} {
        if [set $magnet] {
            if $shift {
		if [file exist ${magnet}-shift.log] {
		    exec sddsplot -col=Shift,RMSvalue ${magnet}-shift.log &
		}
            }
            if $HTime {
                if [file exist ${magnet}-Htime.log] {
                    exec sddsplot -col=HLTimeDelta,RMSvalue ${magnet}-Htime.log &
                }
                if [file exist ${magnet}-Ltime.log] {
                    exec sddsplot -col=HLTimeDelta,RMSvalue ${magnet}-Ltime.log &
                }
            }
            if $startRamp {
                if [file exist ${magnet}-startramp.log] {
		    exec sddsplot -col=StartRamp,RMSvalue ${magnet}-startramp.log &
		}
            }
	    if $ZeroShift {
		if [file exist ${magnet}-shift.log] {
		    exec sddsplot -col=Shift,RMSvalue ${magnet}-shift.log &
		}
	    }
	    if $newADCdelay {
		if [file exist ${magnet}-newADCdelay.log] {
		    exec sddsplot -col=ADCDelay,RMSvalue ${magnet}-newADCdelay.log &
		}
	    }
        }
    }
    if $FreeWheel {
	#only BM has
	if [file exist BM-freeWheel.log] {
	    exec sddsplot -col=FreeWheel,RMSvalue BM-freeWheel.log &
	}
    }
}

set dir [APSGoToDailyDirectory -subdirectory booRampOpt]
set inputDir /home/helios/oagData/booster/ramps/rampOptimization

APSLabeledEntry .dir -parent .userFrame -label "Output dir:" -textVariable dir -width 70
set width 20
APSCheckButtonFrame .mag -parent .userFrame  -label "Select Magnet:" -buttonList {BM QF QD SF SD} -variableList {BM QF QD SF SD} \
  -orientation horizontal -allNone 1
APSLabeledEntry .corr -parent .userFrame -label "Ramp correction times (after loading safety):" -width $width \
  -textVariable correctionTimes 

set wList [APSTabFrame .tab -parent .userFrame -labelList {"Free Wheel" "Zero Shift" "HTime/LTime" "StartRamp" "NewADC_delay"} -width 500 -height 100]
CreateFreeWheelParametersWidget -parent [lindex $wList 0]
CreateZeroShiftParametersWidget -parent [lindex $wList 1]
CreateHLTImeParametersWidget -parent [lindex $wList 2]
CreateStartRampParametersWidget -parent [lindex $wList 3]
CreateNewADCDelayParametersWidget -parent [lindex $wList 4]
