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

#measure booster tunes and chromaticity, modified from SRDispChromMeas
set CVSRevisionAuthor "\$Revision: 1.9 $ \$Author: emery $"

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

#source /home/helios/EMERY/oag/apps/src/mplib/sr/HPVSATunes.tcl
#APSStandardSetup

set mainStatus Ready.
APSApplication . -name BoosterChromCorrection -version "\$Revision: 1.0 $ \$Author: shang $" \
  -overview {measer boosters tunes and chromaticity}

APSScrolledStatus .status -parent .userFrame -textVariable mainStatus -height 50 -width 70 \
  -height 3

set output chromCorr-01
set extraMonFile ""
set start -1000
set stop 1000
set points 3
set pause 15
set offset 0
set review 0
set finished 0
set xChromTarget 3.5
set yChromTarget 2.0
set xChromTarget 5
set yChromTarget 0.5
#set tuneAve 50
#set tuneAVe 20
set tuneAve 10
set gain 0.25
set cycles 10
set numOfPages 100
set freqFinalValue -10000.0

set args $argv
APSParseArguments {output start stop points pauseNASA}

set mainDir /home/helios/oagData/booster/dispChrom/inputFiles
set getChromatic 1
set useVSA 1
#set rfFrequency [exec cavget -list=A014-IETS:BTC:BExtrSetFreqM -floatFormat=%.1f -pendIoTime=5]
set results [exec cavget -list=Mt:BoosterRampTurnsAO,A014-IETS:BTC:BInjectionCycleM,A014-IETS:BTC:BExtractionCycleM,A014-IETS:BTC:SRSetFreqM -pend=5 -floatformat=%lf]
set srExtractionTurns [lindex $results 0]
set bInjectionCycle [lindex $results 1]
set bExtractionCycle [lindex $results 2]
set srFreq [lindex $results 3]
set rfFrequency [expr 432 * $srFreq * 3 * $srExtractionTurns / ($bExtractionCycle - $bInjectionCycle)]

set harmonic 432
set revFrequency [expr $rfFrequency / 432]
set measHarmonic 432
set sideband 1
set expectedXtune 0.742
set xFreq [format %.1f [expr $revFrequency * ($measHarmonic + $expectedXtune * $sideband)]]
set expectedYtune 0.670
set yFreq [format %.1f [expr $revFrequency * ($measHarmonic + $expectedYtune * $sideband)]]
set HPVSATracesToAve 10
set chromProcMode peakfind
set measToAve 1
set chromBadPointList ""

proc SetStatus {text} {
    global mainStatus
    set mainStatus "$text"
    update
}

proc makeLabeledEntriesAndRbFrame {widget args} {
    set parent .userFrame

    APSParseArguments {parent}

    global output outputDir start stop points 
    global pause chromBadPointList xChromTarget yChromTarget tuneAve gain

    APSFrame $widget -parent $parent -relief flat
    set w $parent$widget.frame
    set outputDir  [APSGoToDailyDirectory -subdirectory booChromCorr]

    
    APSLabeledEntry .outputDir -parent $w \
      -label "Output directory:" \
      -textVariable outputDir \
      -contextHelp "Enter a name for the output file directory." \
      -width 55
    APSButton .daily -parent $w.outputDir -packOption "-anchor e" \
      -text "daily" -size small \
      -command {set outputDir [APSGoToDailyDirectory -subdirectory booChromCorr]}
    APSLabeledEntry .output -parent $w \
      -label "Output file:" -textVariable output \
      -contextHelp "Enter a name for the output file." \
      -width 55
    
    
    APSLabeledEntry .stop -parent $w \
      -label "Total RF frequency change (Hz):" -textVariable freqFinalValue \
      -contextHelp "Enter a value to stop at." \
      -width 10
    APSLabeledEntry .cycles -parent $w \
      -label "Cycles:" -textVariable cycles -width 10 \
      -contextHelp "Number of cycles for experiment (interleaving)"

    APSLabeledEntry .points -parent $w \
      -label "Points:" -textVariable points \
      -contextHelp "Enter the number of points to use." \
      -width 10
    APSLabeledEntry .measToAve -parent $w -width 10 \
      -label "Measurements to average: " \
      -textVariable measToAve \
      -contextHelp "Enter the number of measurements \
                                             of the PVs to average. Sample \
                                             interval is 0.5s."
    APSLabeledEntry .tuneAve -parent $w -width 10 \
      -label "Tune waveform average: " -textVariable tuneAve \
      -contextHelp "Enter the number of tune waveform average."
    APSLabeledEntry .pauseNASA -parent $w \
      -label "Pause (s):" -textVariable pause \
      -contextHelp "Enter the number of seconds to wait for the NA/SA" \
      -width 10
    
    APSLabeledEntry .xtarget -parent $w \
      -label "X chromaticity target: " -textVariable xChromTarget \
      -contextHelp "Enter the value of x chromaticity target" \
      -width 10
    
    APSLabeledEntry .ytarget -parent $w \
      -label "Y chromaticity target: " -textVariable yChromTarget \
      -contextHelp "Enter the value of y chromaticity target" \
      -width 10

    APSLabeledEntry .gain -parent $w \
      -label "Correction gain:" -textVariable gain \
      -width 10 -contextHelp "the gain factor for correction."
    
    global xDeltaChrom1 xDeltaChrom2 xDeltaChrom3
    APSLabeledEntryFrame .xdelta -parent $w \
      -label "X chromaticity delta in region1/2/3:" -width 15  -orientation horizontal \
      -variableList {xDeltaChrom1 xDeltaChrom2 xDeltaChrom3} \
      -contextHelp "measure x chromaticity delta in 3 regions from the target"

    global yDeltaChrom1 yDeltaChrom2 yDetlaChrom3
    APSLabeledEntryFrame .ydelta -parent $w \
      -label "Y chromaticity delta in region1/2/3:" -width 15 \
      -variableList {yDeltaChrom1 yDeltaChrom2 yDeltaChrom3} -orientation horizontal  \
      -contextHelp "measure y chromaticity delta in 3 regions from the target"
    

    global SF1 SF2 SF3 SD1 SD2 SD3
    APSLabeledEntryFrame .sf -parent $w \
      -label "SF ramp delta region1/2/3:" -variableList {SF1 SF2 SF3} \
      -orientation horizontal -width 15 \
      -contextHelp "computed SF delta ramp in 3 regions from delta chromaticity and response matrix."
    
    APSLabeledEntryFrame .sd -parent $w \
      -label "SD ramp delta region1/2/3:" -variableList {SD1 SD2 SD3} \
      -orientation horizontal -width 15 \
      -contextHelp "computed SD delta ramp in 3 regions from delta chromaticity and response matrix."

    global tuneFilter tuneLimit tuneNeighbor
    set tuneFitler 0
    set tuneLimit 0.005
    set tuneNeighbor 3
    
    APSLabeledEntryFrame .tune -parent $w -variableList {tuneLimit tuneNeighbor} \
      -orientation horizontal -width 15 \
      -label "Tune process filter, outleir absStd limit/neighbor:" \
      -contextHelp "filter noice for tune waveform with sddsoutlier absDev"
    #APSCheckButton .check -parent $w.tune -packOption "-side right" -variableList tuneFilter -label ""
    checkbutton  $w.tune.frame.check -variable tuneFilter -text ""
    pack $w.tune.frame.check -side right
    APSLabeledEntryFrame .safe -parent $w -variableList {SFsafety1 SDsafety1} \
      -orientation horizontal -width 25 \
      -label "SF-U/SD-U current safety ramp:" 
    APSLabeledEntry .nump -parent $w -label "Number of pages to be processed:" -textVariable numOfPages -width 25
}

proc ScanClockPhase {args} {
    global clockPhase diagresponse acqDelay P0select clockShifts 
    ### switch to sum for scanning and set the extra delay to 200 ms.--CY
    
    SwitchInput S
    if [catch {exec cavput -list=B:tune:boosterInjTriggerEV.OUT -list=0,3,9 -list==0 -pend=10} result] {
        return -code error "Unable to disable booster triggers: $result"
    }
    if [catch {exec cavput -list=B:tune:storageInjTriggerEV.OUT -list=0,3,9 -list==1 -pend=10 } result] {
        return -code error "Unable to enable sr triggers: $result"
    }
    
    SetStatus "Start clock phase scan..."
    if [catch {exec cavput -list=B:tune:adc:gtr:numberPTE=200 -pend=20} result] {
        return -code error "Unable to start clock scan2: $result"
    }
    if [catch {exec  cavput -list=B:tune:ClockScanStartBO=1 -pend=20} result] {
        return -code error "Unable to start clock scan2: $result"
    }
    ### add 20 seconds waiting for the scanning to completed. 
    SetStatus "Wait for 20 seconds...."
    APSWaitWithUpdate -waitSeconds 20 -updateInterval 1
    if [catch {exec cavput -list=B:tune:boosterInjTriggerEV.OUT -list=0,3,9 -list==1 -pend=10} result] {
        return -code error "Unable to disable booster triggers: $result"
    }
    if [catch {exec cavput -list=B:tune:storageInjTriggerEV.OUT -list=0,3,9 -list==0 -pend=10 } result] {
        return -code error "Unable to enable sr triggers: $result"
    }
    SetStatus "done."

}

proc Review {args} {
    global outputDir
    cd $outputDir
    foreach plane {x y} {
        set files [glob -nocomplain *-$plane.chrom]
        if ![llength $files] {
            SetStatus "no files found for $plane plane."
        } else {
            catch {exec rm ${plane}chrom.png ${plane}chrom.eps}
            eval exec sddsplot3 ${plane}chrom \"-topline=$plane plane chromaticity"  -col=time,chrom -gra=sym,vary=sub,conn,scale=2,thick=2 $files -leg=file,edit=%/-${plane}.chrom// &
        }
    }
}

proc makeButtonRow {widget args} {

    global order
    global widgetPlottingButton
    
    set parent .userFrame
    set order 1

    APSParseArguments {parent}

    APSFrame $widget -parent $parent -relief flat
    set w $parent$widget.frame
    set widgetPlottingButton $w

    APSFrame .w2 -parent $parent -relief flat
    set w2 $parent.w2.frame
    
    
    APSButton .doExperiment -parent $w -text "DO \nEXPERIMENT" \
      -command doExperiment \
      -packOption "-side left" 
    
    APSButton .chromProcessing -parent $w -text "CHROMATIC \nPROCESSING" \
      -command PostProcessChrom \
      -packOption "-side left"
    
    APSButton .apply -parent $w -text "Apply Ramp\n Change" \
      -command ApplySFSDRamp -contextHelp "compute the SF SD ramp change and apply SF/SD ramp"
    
    APSButton .install -parent $w -text "Install SF/SD\nSafety Ramp" \
      -command InstallSFSDRamp -contextHelp "install the SF/SD ramp to safety ramp"
    APSButton .tune -parent $w -text "Tune Monitor\n Screen" \
      -command "exec medm -x -macro \"IOC=iocbtune,P=B:tune:\" /usr/local/iocapps/adlsys/booster/boosterTuneApp/TunePlots.adl &"

    APSButton .scan -parent $w -text "Scan Clock\n Phase" \
      -command "ScanClockPhase"
    
    APSButton .strip -parent $w2 -text "SD/SF Ramp\nStripTool" \
      -command "exec StripTool /home/helios/BOOSTER/StripToolConfig/BoosterXYChromMonConfig &" 
    
    APSButton .review -parent $w -text "Review" -command "Review"
    
    APSButton .ff -parent $w -text "Par Timing FF Info" \
      -command "exec medm -x -attach -macro RCPV=OAG190RC ./sr/psApp/APSRunControlSingle.adl &"
    APSButton .safety -parent $w2 -text "Load Safety" \
      -command "LoadSafety" -contextHelp "load the safety ramp of SF/SD"
    
    APSButton .restore -parent $w2 -text "Restore Ops Safety Ramp" -command "RestoreSafetyRamp"

    APSButton .inj1 -parent $w2 -text "Booster InjTune Controllaw Info" -command "exec medm -x -attach -macro RCPV=B:InjTune:ControllawRC ./sr/psApp/APSRunControlSingle.adl & "
    APSButton .inj2 -parent $w2 -text "Booster InjLong Controllaw Info" -command "exec medm -x -attach -macro RCPV=Booster:ControlLawLongRC ./sr/psApp/APSRunControlSingle.adl & "
}

set Xxdrive 134
set Xydrive 154
set Yxdrive 134
set Yydrive 0
set SUMxdrive 120
set SUMydrive 20
proc TurnOnOffTuneDrive {args} {
    set onoff ""
    set xdrive ""
    set ydrive ""
    APSParseArguments {onoff xdrive ydrive}
    global Xxdrive Xydrive Yxdrive Yydrive SUMxdrive SUMydrive
    SetStatus "turn $onoff tune drive ..." 
    if {(![string length $xdrive] || ![string length $ydrive]) && $onoff=="on"} {
        if [catch {exec cavget -list=B:TUNE:HP_1366A_P0_MBBO -pend=20} plane] {
            return -code error "Error turning on booster tune drive1: $plane"
        }
        if {$plane=="OFF" || $plane=="SPARE"} {
            SetStatus "drive is not being turned on.\nPlease select a plane X/Y/S on booster tune measurement multiplexer first before turn it on."
            return
        }
        set xdrive [set ${plane}xdrive]
        set ydrive [set ${plane}ydrive]
    }
    set onPVList [list B:DG1:aDelaySetAO=4.5e-7 \
                    B:DG1:bDelaySetAO=2.0e-6 \
                    B:DG1:cDelaySetAO=7.0e-7 \
                    B:DG1:dDelaySetAO=2.0e-6 \
                    B:DG1:trigModeSetMO=1 \
                    B:DG1:aOutputModeSetMO=0 \
                    B:DG1:cOutputModeSetMO=0 \
                    B:DG1:aOutputZSetBO=0 \
                    B:DG1:cOutputZSetBO=0 \
                    B:DG1:aOutputAmpSetAO=1 \
                    B:DG1:cOutputAmpSetAO=1 \
                    B:DG1:aOutputOffsetSetAO=0.0 \
                    B:DG1:cOutputOffsetSetAO=0.0 \
                    B:DG1:trigInputAmpSetAO=1.0 \
                    BOOTUNE:XAXIS:MATRE200SetVoltage=$xdrive \
                    BOOTUNE:YAXIS:MATRE200SetVoltage=$ydrive ]
    if {$onoff=="on"} {
        if [catch {exec cavput -pend=30 -list=[join $onPVList ,] } result] {
            return -code error "Error turning on booster tune drive: $result"
        }
    } else {
        if [catch {exec cavput -pend=30 \
                     -list=BOOTUNE:XAXIS:MATRE200SetVoltage=0,BOOTUNE:YAXIS:MATRE200SetVoltage=0 } result] {
            return -code error "Error turning off booster tune drive: $result"
        }
    }
    after 2000
    SetStatus "done."
}

proc LoadSafety {args} {
    SetStatus "load SF and SD safety ramp..."
    if [catch {APSBoosterLoadSDUSafetyRamp -magnet SD-U} result] {
        return -code error "Error loading safety ramp for SD-U: $result"
    }
    if [catch {APSBoosterLoadSDUSafetyRamp -magnet SF-U} result] {
        return -code error "Error loading safety ramp for SF-U: $result"
    }
    SetStatus "done."
}

proc SwitchInput {args} {
    global Xxdrive Xydrive Yxdrive Yydrive Sxdrive Sydrive 
    set plane ""
    APSParseArguments {plane}
    
    SetStatus "Switching to $plane ..."
    global inputChannel
    
    set plane [string toupper $plane]
    
    set inputChannel $plane
    switch $plane {
        S {
            set plane SUM
            set xdrive 0
            set ydrive 0
            set onoff off
            
        }
        X {
            set xdrive $Xxdrive
            set ydrive $Xydrive
            set onoff on
        }
        Y {
            set xdrive $Yxdrive
            set ydrive $Yydrive
            set onoff on
        }
        default {
            set xdrive 0
            set ydrive 0
            set onoff off
        }
    }
    if [catch { TurnOnOffTuneDrive -xdrive $xdrive -ydrive $ydrive -onoff $onoff} result] {
        SetStatus "Error in turnOnOffTuneDrive: $result"
        return
    }
    if [catch {exec cavput -list=B:TUNE:HP_1366A_P0_MBBO=$plane,BOOTUNE:XAXIS:MATRE200SetVoltage=$xdrive,BOOTUNE:YAXIS:MATRE200SetVoltage=$ydrive } result] {
        SetStatus "Unable to switch to $plane plane: $result"
        return
    }
    if [catch {exec cavput -list=BOOTUNE:XAXIS:MATRE200SW=1,BOOTUNE:YAXIS:MATRE200SW=1 -pend=20} result] {
        SetStatus "Unable to set  BOOTUNE:XAXIS:MATRE200SW  and BOOTUNE:YAXIS:MATRE200SW to 1: $result"
        return
    }
    #load tune parameters
    if {$plane!="S"} {
        if [catch {exec sddscasr -restore \
                     /home/helios/oagData/booster/tuneArchive/inputFiles/tuneconfig.[string tolower $plane] -pend=30} result] {
            SetStatus "Error in loading tune parameters for $plane plane: $result"
            return 
        }
    }
    after 2000
    SetStatus "done"
}

proc doExperiment {} {
    global output outputDir start stop points offset review getChromatic cancel mainDir cycles
    global HPVSATracesToAve pause measToAve  mainDir tuneAve gain freqFinalValue
    set cancel 0
    
    GetCurrentSafety
    if {0} {
        if [catch {exec cavget -list=OAG190RC.RUN -pen=10} running] {
            return -code error "error reading OAG190RC.RUN: $running"
        }
        if !$running {
            SetStatus "start par timing feedforward..."
            if [catch {APSMpStartParTimingFeedforward} result] {
                return -code error "Error start par timing feedforward: $result"
            }
        }
    }
    if [catch {exec sddscasr -save /home/helios/oagData/par/dispChrom/inputFiles/freqRampInjTimingPVList $outputDir/RFfreq.ref } result] {
        return -code error "Error reading RF freq reference: $result"
    }
    
    #check if it user operation, do not do it during user operation
    if [catch {exec cavget -list=S:DesiredMode -num -pend=10} srMode] {
        return -code error "Error reading SR mode: $srMode"
    }
    if {$srMode==1 || $srMode==2} {
        bell
        SetStatus "Chaning RF frequency is not allowed during user operation!"
        return
    }
    
    checkIfFilesExist
    if $cancel {return}
    
    
    cd $outputDir
    SetStatus "Acquiring data." 
    
    set expFile ${output}.exp
    set template $mainDir/BoosterChromCorrTemplate.exp
    if $pause<0 {
        set pause 2
    }
    global  apsSRDispChromExpDone
    # SetStatus "suspending booster injection longitudidal and tune controllaw..."
    # if [catch {exec cavput -list=B:InjTune:ControllawRC,Booster:ControlLawLongRC,B:SFbcontrollawRC,B:SDbcontrollawRC \
      #     -list=.SUSP=1 -pend=30} result] {
    #    return -code error "Error suspending booster injection tune controllaw: $result"
    #}
    SetStatus "suspending booster  tune controllaw..."
    if [catch {exec cavput -list=B:InjTune:ControllawRC,B:SFbcontrollawRC,B:SDbcontrollawRC \
                 -list=.SUSP=1 -pend=30} result] {
        return -code error "Error suspending booster injection tune controllaw: $result"
    }
    foreach plane {x y} {
        
        # SetStatus "switching to $plane plane ..."
        
        set rootname ${output}-$plane
        if [file exist $rootname] {
            if ![APSYesNoPopUp "$rootname already exist, overwrite it?"] {
                continue
            }
            set files [glob ${rootname}*]
            eval file delete -force $files
        }
        if [catch {SwitchInput -plane $plane} result] {
            return -code error "Error switching plane: $result"
        }
        if ![APSYesNoPopUp "Measure $plane chromaticity now?"] {
            continue
        }
        #total frequency change is -10000.0, steps=points-1
        set deltaFreq [expr $freqFinalValue/(($points-1.0)*1.0)]
        exec replace $template $expFile \
          -orig=<outputDir>,<limit1>,<limit2>,<points>,<mainFile>,<pause>,<measToAve>,<waveAve>,<cycles>,<outputDIr>,<final_value> \
          -repl=$outputDir,$start,$stop,$points,$rootname,$pause,$measToAve,$tuneAve,$cycles,$outputDir,$freqFinalValue
        # do experiment
        set apsSRDispChromExpDone 0
        #turn on booster extraction kicker
        if [catch {TogglePulsedMagnetEnables -location GuntoBoosterExt} result] {
            return -code error "Error turn on booster extraction: $result"
        }
        APSExecLog .expExec -name "Experiment log" \
          -cancelCallback "set  apsSRDispChromExpDone aborted" \
          -abortCallback "set  apsSRDispChromExpDone aborted" \
          -unixCommand "sddsexperiment $expFile $rootname -verbose" \
          -callback "set apsSRDispChromExpDone done;ProcessChrom -datafile $rootname"  -width 80
        tkwait variable apsSRDispChromExpDone
        exec parTimingFeedforward -outputDir $outputDir
        if {$apsSRDispChromExpDone=="aborted"} {
            
            SetStatus "$plane chromaticity measurement was aborted."
        }
    }
    SetStatus "resuming booster injection longitudial and tune controllaw..."
    if [catch {exec cavput -list=B:InjTune:ControllawRC,Booster:ControlLawLongRC -list=.SUSP=0 -pend=30} result] {
        return -code error "Error suspending booster injection tune controllaw: $result"
    }
    SetStatus "experiment done."
}

proc PostProcessChrom {args} {
    global output outputDir gain
    set oldDir [pwd]
    cd $outputDir
    set xdone 0
    set ydone 0
    foreach plane {x y} {
        set file ${output}-$plane
        if [file exist $file] {
            SetStatus "Processing chromaticity for $file..."
            if [catch {ProcessChrom -datafile $file} result] {
                SetStatus "error processing $file: $result"
                return
            }
            SetStatus "done."
            set ${plane}done 1
        } else {
            SetStatus "$file does not exist, no data for $plane to process"
        }
    }
    
    if {$xdone && $ydone} {
        global xDeltaChrom1 yDeltaChrom1 xDeltaChrom2 yDeltaChrom2 xDeltaChrom3 yDeltaChrom3 mainDir
        if [catch {exec sddsmakedataset -col=deltaChrom,type=double \
                     -data=$xDeltaChrom1,$yDeltaChrom1,$xDeltaChrom2,$yDeltaChrom2,$xDeltaChrom3,$yDeltaChrom3 \
                     -col=Name,type=string \
                     -data=xDeltaChrom1,yDeltaChrom1,xDeltaChrom2,yDeltaChrom2,xDeltaChrom3,yDeltaChrom3 \
                     deltaChrom-$output.sdds } result] {
            return -code error "Error creating delta chrom file: $result"
        }
        
        if [catch {exec sddsmatrixmult $mainDir/SFSDChromSimulation.inv deltaChrom-$output.sdds -pipe=out \
                     | sddsprocess -pipe "-redefine=col,deltaChrom,deltaChrom $gain *" \
                     | sddsxref -pipe=in $mainDir/SFSDChromSimulation.inv -take=ActuatorNames SFSDramp-$output.sdds } result] {
            return -code error "Error creating ramp file: $result"
        }
        
        set nameList [exec sdds2stream -col=ActuatorNames  SFSDramp-$output.sdds]
        set valueList [exec sdds2stream -col=deltaChrom SFSDramp-$output.sdds]
        foreach name $nameList value $valueList {
            #reverse sign
            global $name
            set $name [format %.5e [expr -1.0 * $value]]
        }
        SetStatus "SF/SF ramp change updated."
    }
}

proc ProcessChrom {args} {
    global output outputDir start stop points offset review xChromTarget yChromTarget gain
    global tuneFilter tuneLimit tuneNeighbor numOfPages
    set datafile ""
    APSParseArguments {datafile}
    set oldDir [pwd]
    cd $outputDir
    
    set alpha 7.144e-3 
    set alpha 0.009702
    set tuneTimeOffset 13.33 
    set tuneStart 5
    set tuneEnd 126
    set numToAve 5
    
    SetStatus "Performing chromatic processing for $output."
    
    if [regexp "x" $datafile] {
        set plane x
    } elseif [regexp "y" $datafile] {
        set plane y
    } else {
        return -code error "Invalid datafile provided."
    }
    set target [set ${plane}ChromTarget]
    set files [glob -nocomplain ${datafile}Tunes-???]
    if ![llength $files] {
        SetStatus "No tunes files for $datafile found."
        return
    }
    set files [lsort $files]
    set rfFreqList [exec sdds2stream -col=rfFrequency $datafile]
    set tmpRoot /tmp/[APSTmpString]
    set step 0
    set fileList ""
    set steps [llength $files]
    if [catch {exec sddsconvert $datafile -keeppage=1 -pipe=out \
                 | sddsprocess -pipe -redefine=col,Step,i_row,type=long  \
                 | sddspfit -pipe -col=Step,rfFrequency \
                 | sdds2stream -pipe=in -par=Slope } slop] {
        return -code error "Error getting freq step ratio: $slop"
    }
    set freqStepRatio [expr $slop / 1000.0]
    if [catch {exec sddsconvert $datafile -pipe=out -keeppage=1 \
                 | sddsprocess -pipe -process=rfFrequency,ave,rfFreq  \
                 | sdds2stream -pipe=in -par=rfFreq } rfFreq] {
        return -code error "Error getting the rf frequency average: $rfFreq"
    }
    set rfFreq [expr $rfFreq / 1000.0]
    set fileList ""
    foreach file $files {
        puts $file
        if $tuneFilter {
            #remove noices in tune waveform
            if [catch {exec sddsprocess $file -pipe=out -filter=par,B:diag1:rms:A:region4,0.5,5 -nowarn \
                         | sddsconvert -pipe -frompage=1 -topage=$numOfPages \
                         |  sddsoutlier -pipe -col=B:tune:peak:gtr:waveform1 \
                         -absDev=$tuneLimit,n=$tuneNeighbor -replace=interp \
                         | tee $file.proc \
                         | sddsenvelope -pipe -mean=B:tune:peak:gtr:waveform1 -copy=Index \
                         -standardDeviation=B:tune:peak:gtr:waveform1 \
                         | sddsprocess -pipe \
                         -redefine=col,tuneMean,B:tune:peak:gtr:waveform1Mean \
                         -redefine=col,tuneStDev,B:tune:peak:gtr:waveform1StDev  \
                         | tee $file.env \
                         | sddsbreak -pipe  -rowlimits=$numToAve \
                         | sddsprocess -process=tuneMean,average,%s \
                         -process=tuneMean,StandardDeviation,tuneStDev -pipe \
                         -process=Index,first,%s \
                         | sddscollapse -pipe=in $file.env.coll } result] {
                return -code error "ChromProcess1: $result"
            }
        } else {
            if [catch {exec sddsprocess $file -pipe=out -filter=par,B:diag1:rms:A:region4,0.5,5 -nowarn \
                         | sddsconvert -pipe -frompage=1 -topage=$numOfPages \
                         | sddsenvelope -pipe -mean=B:tune:peak:gtr:waveform1 -copy=Index \
                         -standardDeviation=B:tune:peak:gtr:waveform1 \
                         | sddsprocess -pipe \
                         -redefine=col,tuneMean,B:tune:peak:gtr:waveform1Mean \
                         -redefine=col,tuneStDev,B:tune:peak:gtr:waveform1StDev  \
                         | tee $file.env \
                         | sddsbreak -pipe  -rowlimits=$numToAve \
                         | sddsprocess -process=tuneMean,average,%s \
                         -process=tuneMean,StandardDeviation,tuneStDev -pipe \
                         -process=Index,first,%s \
                         | sddscollapse -pipe=in $file.env.coll } result] {
                return -code error "ChromProcess1: $result"
            }
        }
        lappend fileList $file.env.coll
    }
    if [catch {eval exec sddscombine $fileList -pipe=out \
                 | sddsprocess -pipe \"-redefine=par,Step,i_page 1 -\" \
                 | sddsenvelope -slope=Step,tuneMean \
                 -standardDeviation=tuneStDev \
                 -copy=Index \
                 -pipe \
                 | sddsprocess \
                 "-filter=col,Index,$tuneStart,$tuneEnd" \
                 \"-redefine=col,chrom,tuneMeanSlope $alpha * $rfFreq * $freqStepRatio / \" \
                 \"-redefine=para,freqStepRatio,$freqStepRatio\" \
                 \"-redefine=para,alpha,$alpha\" \
                 \"-redefine=para,timePerPoint,1.8,units=ms\" \
                 \"-redefine=col,time,Index 5 - 1.8 *,units=ms\" \
                 \"-redefine=col,chromStdev,tuneStDevStDev $alpha * $rfFreq * $freqStepRatio /\" \
                 -pipe \
                 | tee $datafile.chrom \
                 | sddsenvelope -pipe -mean=chrom -copy=time,Index \
                 | sddsprocess -pipe -redefine=col,target,$target \
                 | sddsprocess -pipe=in $datafile.chromError \
                 \"-redefine=col,ChangeInChrom,chromMean target -\" } result] {
        return -code error "Error processing chromaticity: $result"
    }
    exec sddsplot -col=Index,chrom $datafile.chrom -grap=symbol,sub=2,connect=2,scale=2,fill \
      -filter=col,Index,0,115 \
      -factor=xMultiplier=1.80 \
      -xLabel=time\(ms\) "-topline=$plane plane chromaticity" &
    #get the average chrom by region
    #  set startList {35 99 162}
    # set endList {90 153 207}
    set startList {30 90 150}
    set endList {90 150 210}
    #process region error average
    
    foreach region {1 2 3} start $startList end $endList {
        if [catch {exec sddsprocess $datafile.chromError -pipe=out -filter=col,time,$start,$end \
                     | sddsprocess -pipe -process=ChangeInChrom,ave,ChromError \
                     | sdds2stream -pipe -par=ChromError } chromError] {
            return -code error "Error processing chrom error for region $region: $chromError"
        }
        global ${plane}DeltaChrom$region
        set ${plane}DeltaChrom$region [format %.5e $chromError]
    }
    SetStatus "$plane chromaticity changes in region1/2/3 are: [set ${plane}DeltaChrom1],[set ${plane}DeltaChrom2],[set ${plane}DeltaChrom3]"
    
    
    cd $oldDir
    SetStatus Done.
}


proc checkIfFilesExist {} {
    global output outputDir review cancel
    cd $outputDir
    if {[file exists $output]} {
        toplevel .existsBox
        wm title .existsBox "Experiment Exists"
        message .existsBox.message -text "Experiment [file tail $output] exists:\nPress \"Overwrite\" to overwrite existing files\
		\nor \"Cancel\" to cancel experiment and change name." -width 14c
        pack .existsBox.message -in .existsBox
        APSFrame .buttonRow -relief flat -parent .existsBox
        set w .existsBox.buttonRow.frame
        APSButton .overwrite -parent $w -text "Overwrite" -command {destroy .existsBox; removeOldFiles; set review 0; set done 1} \
          -packOption "-side left -padx 5"
        APSButton .cancel -parent $w -text "Cancel" -command {destroy .existsBox; set cancel 1; set done 1} -packOption "-side left"
        tkwait variable done
    } else {
        set review 0
    }
}

proc removeOldFiles {} {
    global output outputDir
    cd $outputDir
    SetStatus "Removing old experiment files..."
    eval file delete [glob -nocomplain $output*]
    SetStatus "Done."
}

proc RestoreSafetyRamp {args} {
    global SFsafety SDsafety
    
    set rampDir /home/helios/oagData/booster/ramps/IRamp/safety     
    set oldDir [pwd]
    cd $rampDir
    exec rm SF-UIref.afg100
    exec ln -s $SFsafety SF-UIref.afg100
    exec rm SD-UIref.afg100
    exec ln -s $SDsafety SD-UIref.afg100
    cd $oldDir
    SetStatus "SF safety was restored to $SFsafety"
    SetStatus "SD safety was restored to $SDsafety"
}

set rampDir /home/helios/oagData/booster/ramps/IRamp/safety

proc GetCurrentSafety {args} {
    global rampDir outputDir SFsafety1 SDsafety1

    cd $rampDir
    set SFsafety1 [file tail [file readlink SF-UIref.afg100]]
    set SDsafety1 [file tail [file readlink SD-UIref.afg100]]
    update
    cd $outputDir
    
}

proc InstallSFSDRamp {args} {
    global outputDir output SFsafety1 SUsafety1 index output
    GetCurrentSafety
    cd $outputDir
    set dir [pwd]
    set rampDir /home/helios/oagData/booster/ramps/IRamp/safety
    foreach ramp {SF-U SD-U} {
        set file NewRamp-${output}-$ramp
        if ![file exist $file] {
            SetStatus "$file does not exist, skip"
            continue
        }
        if ![APSYesNoPopUp "Are you sure to install $file as $ramp safety ramp?"] {
            SetStatus "install $ramp safety ramp was cancelled."
            continue
        }
        exec cp $file $rampDir/.
        cd $rampDir
        set oldFile [file readlink ${ramp}Iref.afg100]
        SetStatus "$ramp safety ramp was $oldFile."
        exec rm ${ramp}Iref.afg100
        exec ln -s $file ${ramp}Iref.afg100
        cd $dir
        SetStatus "$file install as $ramp safety ramp."
    }
    GetCurrentSafety  
    set rootname [lindex [split $output "-"] 0]
    set index [scan [lindex [split $output "-"] 1] %d]
    set index [expr $index +1]
    set output ${rootname}-[format %02d $index]
    
    update
    SetStatus "done."
}

proc ApplySFSDRamp {args} {
    global SD1 SF1 SD2 SF2 SD3 SF3 mainDir
    global xDeltaChrom1 yDeltaChrom1 xDeltaChrom2 yDeltaChrom2 xDeltaChrom3 yDeltaChrom3
    global outputDir output
    
    GetCurrentSafety

    cd $outputDir
    if ![file exist SFSDramp-$output.sdds] {
        SetStatus "SFSDramp-$output.sdds does not exist yet, process the chromaticity for $output first"
        return
    }
    
    if ![APSYesNoPopUp "Are you sure to apply the changes to SF/SD ramp?"] {
        SetStatus "Apply ramp change was cancelled."
        return
    }
    set nameList [exec sdds2stream -col=ActuatorNames  SFSDramp-$output.sdds]
    set valueList [exec sdds2stream -col=deltaChrom SFSDramp-$output.sdds]
    foreach name $nameList value $valueList {
        #reverse sign
        global $name
        set $name [format %.5e [expr $value*-1.0]]
    }
    #reverse sign
    set sfList [list 0 $SF1 $SF2 $SF3 0]
    set sdList [list 0 $SD1 $SD2 $SD3 0]
    SetStatus "suspending SF/SD bcontrol..."
    if [catch {exec cavput -list=B: -list=SF,SD -list=bcontrollawRC.SUSP=1 -pend=30} result] {
        return -code error "Error suspending SF SD bcontrol: $result"
    }
    if [catch {exec changeBSFSDRamp -valueList "$sfList" -SF 1 -load 1 \
                 -rootname NewRamp-${output}- } result] {
        return -code error "Error apply SF delta ramp: $result"
    }
    SetStatus "newRamp-${output}-SF-U ramp was applied."
    if [catch {exec changeBSFSDRamp -valueList "$sdList" -SD 1 -load 1 \
                 -rootname NewRamp-${output}- } result] {
        return -code error "Error apply SF delta ramp: $result"
    }
    SetStatus "newRamp-${output}-SD-U ramp was applied."
    SetStatus "resuming SF/SD bcontrol..."
    if [catch {exec cavput -list=B: -list=SF,SD -list=bcontrollawRC.SUSP=0 -pend=30} result] {
        return -code error "Error suspending SF SD bcontrol: $result"
    }
    
    SetStatus "SF/SD ramp changes applied."
}

set file $mainDir/SFSDramp0.sdds
set nameList [exec sdds2stream -col=ActuatorNames $file]
set valueList [exec sdds2stream -col=deltaChrom $file]
foreach name $nameList value $valueList {
    set $name [format %.5e $value]
}
set chromFile $mainDir/deltaChrom0.sdds 
set nameList [exec sdds2stream -col=Name $chromFile]
set valueList [exec sdds2stream -col=deltaChrom $chromFile]
foreach name $nameList value $valueList {
    set $name [format %.5e $value]
}

set SFsafety [file readlink /home/helios/oagData/booster/ramps/IRamp/safety/SF-UIref.afg100]
set SDsafety [file readlink /home/helios/oagData/booster/ramps/IRamp/safety/SD-UIref.afg100]
set SDsafety1 [file tail $SDsafety]
set SFsafety1 [file tail $SFsafety]

makeLabeledEntriesAndRbFrame .entries -parent .userFrame
makeButtonRow .buttonRow -parent .userFrame
