#!/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)]
#set auto_path [linsert $auto_path 0 /home/helios/EMERY/oag/apps/lib/$env(HOST_ARCH)]
set auto_path [linsert $auto_path 0 /home/helios/SHANG/oag/apps/src/mplib/sr]
APSDebugPath

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

set mainStatus Ready.
APSApplication . -name BoosterDispChromMeas -version "\$Revision: 1.9 $ \$Author: emery $" \
  -overview {measer boosters tunes and chromaticity}

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

set output dispChrom01
set extraMonFile ""
set start -1000
set stop 1000
set points 3
set pauseNASA 3
set offset 0
set review 0
set finished 0

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

set mainDir /home/helios/oagData/booster/dispChrom
set getChromatic 1
set useVSA 1
set rfFrequency [exec cavget -list=BRF:S:Hp8657RefFreqAO -floatFormat=%.1f -pendIoTime=5]
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 extraMonFile useVSA HPVSABandWidth
    global xFreq yFreq pauseNASA chromBadPointList latticeSelection

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


    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 dispChrom]}
    APSLabeledEntry .output -parent $w \
      -label "Output file:" -textVariable output \
      -contextHelp "Enter a name for the output file." \
      -width 55
#    APSLabeledEntry .extra -parent $w -width 55 \
#      -label "Extra monitor file:" \
#      -textVariable extraMonFile \
#      -contextHelp "Enter the name of an sddsmonitor \
#                                         input file. The PVs listed in this \
#                                         file will be collected along with \
#                                         the rest of the data."
    APSLabeledEntry .start -parent $w \
      -label "Start:" -textVariable start \
      -contextHelp "Enter a value to start with." \
      -width 10
    APSLabeledEntry .stop -parent $w \
      -label "Stop:" -textVariable stop \
      -contextHelp "Enter a value to stop at." \
      -width 10
    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 .pauseNASA -parent $w \
      -label "Pause (s):" -textVariable pauseNASA \
      -contextHelp "Enter the number of seconds to wait for the NA/SA" \
      -width 10
    APSRadioButtonFrame .lattice -parent $w -label "Choose Lattice:" -variable latticeSelection \
      -buttonList {92nm 109nm 132nm} \
      -valueList {x13.75-y5.80 x12.75-y9.80 x11.75-y9.80} -orientation horizontal \
      -commandList {"GetMomentumCompactionFactor" "GetMomentumCompactionFactor" "GetMomentumCompactionFactor"} \
      -contextHelp "Choose current lattice in the measurement, which also determines the momentum compatction factor"
    APSLabeledEntry .momcompaction -parent $w \
      -label "Momentum Compaction Factor :" -textVariable momentumCompactionFactor \
      -contextHelp "Enter the momentum compaction factor (used for dispersion processing only)" \
      -width 10
 #   APSRadioButtonFrame .chromRb -parent $w -label "Get chromatic data: " \
 #     -variable getChromatic \
 #     -buttonList {Yes No} -valueList {1 0} \
 #     -orientation horizontal
 #   APSRadioButtonFrame .vsaRB -parent $w -label "Use VSA: " -variable useVSA \
 #     -buttonList {Yes No} -valueList {1 0} \
 #     -orientation horizontal 

    APSFrame .hpvsa -parent $w -label "VSA parameters" 
    set w1 $w.hpvsa.frame
    APSButton .measureTunes -parent $w1 -text "FIND CENTER FREQUENCIES" \
      -command {MeasureInitialTunes \
                  -mainStatus SetStatus} \
      -packOption "-side top " \
      -contextHelp "Finds the center frequencies \
                                          for x and y tune measurement."
    APSLabeledEntry .xfreq -parent $w1 \
      -label "x frequency center (Hz): " \
      -textVariable xFreq 
    APSLabeledEntry .xtune -parent $w1 \
      -label "fractional x tune: " -textVariable xTune 
    APSLabeledEntry .yfreq -parent $w1 \
      -label "y frequency center (Hz): " \
      -textVariable yFreq 
    APSLabeledEntry .ytune -parent $w1 \
      -label "fractional y tune: " -textVariable yTune 
    APSLabeledEntry .pause -parent $w1 \
      -label "Traces to average: " \
      -textVariable HPVSATracesToAve
    APSLabeledEntry .band -parent $w1 \
      -label "VSA Resolution Bandwidth (Hz):" \
      -textVariable HPVSABandWidth
    APSRadioButtonFrame .chromProcMode -parent $w \
      -label "Tune change processing mode: " \
      -variable chromProcMode \
      -buttonList {Smooth+Peakfind \
                     Convolution Integral} \
      -valueList {peakfind convolve integrate} \
      -orientation horizontal 
    APSLabeledEntry .elimPoints -parent $w \
      -label "List of bad point numbers (space separated): " -width 30 \
      -textVariable chromBadPointList -contextHelp \
      "Enter a list of point numbers for points to be removed from fit.  Point numbers start from 1."
    
  #  $w.chromRb.frame.button1 invoke
}

    global dx0r dy0r dx0s dy0s dx1r dy1r dx1s dy1s xfit yfit
    
    set dx0r 0
    set dy0r 0
    set dx0s 0
    set dy0s 0
    set dx1r 1
    set dy1r 1
    set dx1s 0
    set dy1s 0
    set xfit 0
    set yfit 0

#----------------------------------------------------------------------
#
proc menuPlotting {} {
    global output
    global dx0r dy0r dx0s dy0s dx1r dy1r dx1s dy1s xfit yfit
    global widgetPlottingButton

    APSEnableButton $widgetPlottingButton.plotDispersion.button
    
    set plotting .[APSUniqueName plotting]

    APSDialogBox $plotting -name Plotting -okCommand doPlotting -modal 0

    APSCheckButtonFrame .d0r -parent $plotting.userFrame \
                             -label "Dispersion1 over total ring:    " \
                             -variableList {dx0r dy0r} \
                             -buttonList {X Y} \
                             -orientation horizontal 
    
    APSCheckButtonFrame .dos -parent $plotting.userFrame \
                             -label "Dispersion1 by separate slices: " \
                             -variableList {dx0s dy0s} \
                             -buttonList {X Y} \
                             -orientation horizontal

    APSCheckButtonFrame .d1r -parent $plotting.userFrame \
                             -label "Dispersion2 over total ring:    " \
                             -variableList {dx1r dy1r} \
                             -buttonList {X Y} \
                             -orientation horizontal
 
    APSCheckButtonFrame .d1s -parent $plotting.userFrame \
                             -label "Dispersion2 by separate slices: " \
                             -variableList {dx1s dy1s} \
                             -buttonList {X Y} \
                             -orientation horizontal

    APSCheckButtonFrame .fit -parent $plotting.userFrame \
                             -label "Figures of the fitting:          " \
                             -variableList {xfit yfit} \
                             -buttonList {X Y} \
                             -orientation horizontal

    APSButton .none -parent $plotting.userFrame \
                             -text "None" \
                             -size small -packOption "-side right" \
                             -command "allButtonOff $plotting.userFrame"

    APSButton .all -parent $plotting.userFrame \
                             -text "All" \
                             -size small -packOption "-side right" \
                             -command "allButtonOn $plotting.userFrame"

}

proc allButtonOn {w} {

    global dx0r dy0r dx0s dy0s dx1r dy1r dx1s dy1s xfit yfit
    
    set dx0r 1
    set dy0r 1
    set dx0s 1
    set dy0s 1
    set dx1r 1
    set dy1r 1
    set dx1s 1
    set dy1s 1
    set xfit 1
    set yfit 1
}

proc allButtonOff {w} {

    global dx0r dy0r dx0s dy0s dx1r dy1r dx1s dy1s xfit yfit
    
    set dx0r 0
    set dy0r 0
    set dx0s 0
    set dy0s 0
    set dx1r 0
    set dy1r 0
    set dx1s 0
    set dy1s 0
    set xfit 0
    set yfit 0
    
}

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

    APSButton .doExperiment -parent $w -text "DO EXPERIMENT" \
      -command doExperiment \
      -packOption "-side left" 
     
    APSButton .chromProcessing -parent $w -text "CHROMATIC PROCESSING" \
      -command chromProcessing \
      -packOption "-side left"

    APSButton .calcDispersion -parent $w -text "CALCULATE\nDISPERSION" \
      -command calcDispersion \
      -packOption "-side left" \
      -contextHelp "Calculation of the first/second dispersion \
                   functions over x,y" 

    APSRadioButtonFrame .orderDispersion -parent $w -label "" \
                         -packOption "-side left" \
                         -variable order \
                         -buttonList {"order 1" "order 2"} \
                         -valueList {1 2} \
                         -orientation vertical \
                         -contextHelp "Choose the dispersion order to analyze with"
                         
    APSButton .plotDispersion -parent $w -text "PLOTTING\nDISPERSION" \
                              -packOption "-side right" \
                              -command menuPlotting \
                              -contextHelp "Plotting of the first/second \
                                        dispersion functions over x,y and \
                                        fitting figures" 
                         
    APSDisableButton $widgetPlottingButton.plotDispersion.button
}

#----------------------------------------------------------------------
#
proc calcDispersion {} {

    global order

    if {$order == 2} {
       calcDispersion2
    } else {
       calcDispersion1
    }   
}

#----------------------------------------------------------------------
# Procedure measures and sets the initial tune values:  
# returns 1 when completed; returns 0 if the VSA is not selected.
#
proc MeasureInitialTunes {args} {

    global directory xFreq yFreq xTune yTune streamID hpvsaSelection useVSA
    
    APSParseArguments {mainStatus}
    
    if {![string compare $useVSA 0]} {
        if {$mainStatus!=""} {
            $mainStatus "Vector signal analyzer is not selected."
        }   
        return 0
    }

    if {$mainStatus!=""} {
        $mainStatus "Measuring and setting the horizontal tune..."
    }

    set streamID [APSOpenTelnetStream -IPaddress $hpvsaSelection]
    SetHPVSAHVRange Horizontal 0

    set xFreq [DetermineTuneFromWaveform x]
    set xTune [ComputeTuneFromFrequency -tuneFreq ${xFreq}]

    if {$mainStatus!=""} {
        $mainStatus "Measuring and setting the vertical tune..."
    }

    SetHPVSAHVRange Vertical 0
    update

    set yFreq [DetermineTuneFromWaveform y]
    set yTune [ComputeTuneFromFrequency -tuneFreq ${yFreq}]

    # return stripline to default state.
    # maybe should be replaced by a call such as
    # "SetHPVSAHVRange Diagonal"
   # if [catch {exec cavput -list=SR:TUNE:stripSELmbbo=X/Y \
   #          } result ] {
    #    return -code error "MeasureInitialTunes: $result"
   # }

    if {$mainStatus!=""} {
        $mainStatus "Finished setting the tunes."
    }
    APSCloseTelnetStream -streamID ${streamID}
    return 1
}

# Procedure computes the tune by first acquiring the waveform then computing the tune via the integral method.
# The procedure returns the tune computed from the acquired waveform.

proc DetermineTuneFromWaveform {plane} {
    
    global hpvsaSelection
    set waveformFile /tmp/waveform${plane}.sdds
    exec hpVecTrace -${hpvsaSelection} a $waveformFile
    set selectedTune [expr 1.0e6 * [exec sddssmooth -pipe=out $waveformFile \
                                      -col=Waveform -pass=0 \
                                      -despike=neighbors=5,average=5,passes=5 \
                                      | sddsprocess -pipe -process=Waveform,minimum,WvfMin \
                                      "-redefine=col,Waveform,Waveform WvfMin -" \
                                      | sddsinteg -pipe -integrate=Waveform -versus=Frequency \
                                      | sddsprocess -pipe -process=WaveformInteg,maximum,WvfMax \
                                      "-redefine=col,WaveformInteg,WaveformInteg WvfMax / 0.5 -" \
                                      -process=WaveformInteg,zerocrossing,TuneFreq,functionOf=Frequency \
                                      | sdds2stream -pipe=in -param=TuneFreq -ignore]]
    #file delete $waveformFile
    set selectedTune [format %0.1f $selectedTune]
    return ${selectedTune}
}

# Procedure computes the tune from the specified tune frequency and returns the tune.

proc ComputeTuneFromFrequency {args} {
    
    set tuneFreq ""
    APSStrictParseArguments {tuneFreq}
    
    set rfFrequency [exec cavget -list=BRF:S:Hp8657RefFreqAO -floatFormat=%.1f -pendIoTime=25]
    set revFrequency [expr $rfFrequency / 432.0]

    return [format %.5f [expr -int($tuneFreq / $revFrequency) + ($tuneFreq / $revFrequency)]]
}

# This procedure sets the HPVSA frequency to either one of the tune
# frequencies and the span to 5 kHz.  Returns 1 when completed.
# Returns 0 if $plane != Horizontal || Vertical.

proc SetHPVSAHVRange {plane index} {

    global xFreq newxFreq yFreq newyFreq streamID HPVSATracesToAve HPVSABandWidth

    if {$index==0} {
        set newxFreq $xFreq
        set newyFreq $yFreq
    }
    # Ensure that averaging is normal, i.e. not repeating.
    APSWriteToTelnetStream -command "AVER:TCON NORM" -streamID $streamID
    if {[string match $plane Horizontal]} {
      #  if [catch {exec cavput -list=SR:TUNE:stripSELmbbo=X \
      #           } result ] {
      #      return -code error "SetHPVSAHVRange: $result"
      #  }
        APSWriteToTelnetStream -command "PAUSE" -streamID $streamID
	APSWriteToTelnetStream -command "AVER:COUN $HPVSATracesToAve" -streamID $streamID
        APSWriteToTelnetStream -command "FREQ:CENT ${newxFreq} Hz" -streamID $streamID
        APSWriteToTelnetStream -command "BAND ${HPVSABandWidth} Hz" -streamID $streamID
        APSWriteToTelnetStream -command "ABOR;*WAI" -streamID $streamID
        update
        after 2000
        set operationCondition 256
        while {$operationCondition & 256} {
            after 1000
            set operationCondition [APSWriteToTelnetStream -command "STAT:OPER:COND?" -streamID $streamID]
        }
        APSWriteToTelnetStream -command "PAUSE" -streamID $streamID
        set newxFreq [APSWriteToTelnetStream -command "CALC:MARK:X?" -streamID $streamID]
        APSWriteToTelnetStream -command "BAND ${HPVSABandWidth} Hz" -streamID $streamID
        APSWriteToTelnetStream -command "FREQ:CENT $newxFreq Hz" -streamID $streamID
        APSWriteToTelnetStream -command "PAUSE" -streamID $streamID
        APSWriteToTelnetStream -command "DISP:WIND1:TRAC:Y:AUTO ONCE" -streamID $streamID
        APSWriteToTelnetStream -command "ABOR;*WAI" -streamID $streamID
        update
        after 2000
        set operationCondition 256
        while {$operationCondition & 256 } {
            after 1000
            set operationCondition [APSWriteToTelnetStream -command "STAT:OPER:COND?" -streamID $streamID]
        }
        return 1
    } elseif {[string match $plane Vertical]} {
       # if [catch {exec cavput -list=SR:TUNE:stripSELmbbo=Y \
       #          } result ] {
       #     return -code error "SetHPVSAHVRange: $result"
       # }
        APSWriteToTelnetStream -command "PAUSE" -streamID $streamID
        APSWriteToTelnetStream -command "AVER:COUN $HPVSATracesToAve" -streamID $streamID
        APSWriteToTelnetStream -command "FREQ:CENT ${newyFreq} Hz" -streamID $streamID
        APSWriteToTelnetStream -command "BAND ${HPVSABandWidth} Hz" -streamID $streamID
        APSWriteToTelnetStream -command "ABOR;*WAI" -streamID $streamID
        update
        after 2000
        set operationCondition 256
        while {$operationCondition & 256} {
            after 1000
            set operationCondition [APSWriteToTelnetStream -command "STAT:OPER:COND?" -streamID $streamID]
        }
        APSWriteToTelnetStream -command "PAUSE" -streamID $streamID
        set newyFreq [APSWriteToTelnetStream -command "CALC:MARK:X?" -streamID $streamID]
        APSWriteToTelnetStream -command "BAND ${HPVSABandWidth} Hz" -streamID $streamID
        APSWriteToTelnetStream -command "FREQ:CENT $newyFreq Hz" -streamID $streamID
        APSWriteToTelnetStream -command "PAUSE" -streamID $streamID
        APSWriteToTelnetStream -command "DISP:WIND1:TRAC:Y:AUTO ONCE" -streamID $streamID
        APSWriteToTelnetStream -command "ABOR;*WAI" -streamID $streamID
        update
        after 2000
        set operationCondition 256
        while {$operationCondition & 256} {
            after 1000
            set operationCondition [APSWriteToTelnetStream -command "STAT:OPER:COND?" -streamID $streamID]
        }
        return 1
    } else {
        return 0
     }
}

# Procedure determines the SR quadrupole serial number name from the
# standard Device Name.  Returns the quadrupole serial number name.
# Requires the file ${directory}/SQ_xref.sdds.

proc doExperiment {} {
    global output outputDir start stop points offset review getChromatic cancel mainDir extraMonFile useVSA
    global xFreq yFreq HPVSATracesToAve pauseNASA measToAve
    set cancel 0
    checkIfFilesExist
    if $cancel {return}

    if !$review {
        cd $outputDir
        SetStatus "Acquiring data." 

        if [string length $extraMonFile] {
            set extraExpFile /tmp/[APSTmpString].exp
            set extraMonFile1 /tmp/[APSTmpString].mon
            if [catch {exec sddsselect $extraMonFile $mainDir/inputFiles/dispersion.mon \
                         -match=ControlName -nowarning -invert -pipe=out \
                         | sddsconvert -pipe=in $extraMonFile1 \
                         -retain=column,ControlName,ReadbackName,ReadbackUnits
                exec sdds2stream -rows $extraMonFile1 | token -n=1} rows] {
                SetStatus "Preparing extra PV monitor file: $rows"
                return
            }
            if [lsearch -exact [exec sddsquery -column $extraMonFile1] ReadbackName]!=-1 {
                if [catch {exec sddsselect $extraMonFile1  $mainDir/inputFiles/dispersion.mon \
                             $extraMonFile1.1 \
                             -match=ReadbackName -nowarning -invert
                    exec sdds2stream -rows $extraMonFile1.1 | token -n=1} rows] {
                    SetStatus "Preparing extra PV monitor file: $rows"
                    return
                }
                file delete -force $extraMonFile1
                file copy -force $extraMonFile1.1 $extraMonFile1
            }
            if $rows {
                set fid [open $extraExpFile w]
                puts $fid "&measurement_file filename = $extraMonFile1, number_to_average=$measToAve &end"
                close $fid
            } else {
                set extraExpFile ""
            }
        } else {
            set extraExpFile ""
        }

        set expFile /tmp/[APSTmpString].exp
	set template BoodispchromTemplateVSA.exp
	set pause [expr 15-2*(0.060*$HPVSATracesToAve)]
	if $pause<0 {
	    set pause 0
	}
	exec replace $mainDir/inputFiles/$template $expFile \
	    -orig=<limit1>,<limit2>,<points>,<mainFile>,<xFreq>,<yFreq>,<pause>,<tracesToAve>,<measToAve> \
	    -repl=$start,$stop,$points,$output,$xFreq,$yFreq,$pause,$HPVSATracesToAve,$measToAve
	
        if [string length $extraExpFile] {
            exec cat $extraExpFile $expFile > $expFile.1
            exec mv $expFile.1 $expFile
        }
	
        # do experiment
        global apsSRDispChromExpDone
        set apsSRDispChromExpDone 0
       # set rcList {S:OrbitControlLawXRC S:OrbitControlLawYRC \
       #       S:rfFreqControlLawRC DP:S:OrbitControlLawXSDDS DP:S:OrbitControlLawYSDDS}
       # if [catch {exec cavget -list=[join $rcList ,] \
        #             -list=.SUSP -cavputForm} \
        #      controllawMode] {
        #    SetStatus "Problem getting orbit controllaw status: $controllawMode"
        #    return
        #}
        #if [catch {exec cavput -list=[join $rcList ,] \
        #             -list=.SUSP=1} result] {
        #    SetStatus "Problem suspending controllaw: $result"
         #   return
        #}
        
       
        APSExecLog .expExec -name "Experiment log" \
          -cancelCallback "APSSRCleanUpDispChrom" \
          -abortCallback "APSSRCleanUpDispChrom" \
          -unixCommand "sddsexperiment $expFile $output -verbose" \
          -callback "APSSRCleanUpDispChrom -datafile $output"  -width 80
        tkwait variable apsSRDispChromExpDone

       
       # if {[string length $controllawMode] && \
        #      [catch {exec cavput -list=$controllawMode} result]} {
        #    SetStatus "Problem setting orbit controllaw mode: $result"
       # } else {
       #     SetStatus "Orbit/rf freq controllaws restored."
       # }

        if [catch {exec sddsprocess $output -nowarning \
                     "-define=parameter,HPVSAUsed,$useVSA,type=long" \
                     "-define=parameter,sddsexperimentUsed,1,type=long"
            file delete ${output}~} result] {
            SetStatus "Problem post-processing file."
        }
    }
}

proc APSSRCleanUpDispChrom {args} {
    global momentumCompactionFactor
    set datafile ""
    APSStrictParseArguments {datafile}
    global apsSRDispChromExpDone
    set apsSRDispChromExpDone 1
    SetStatus "Postprocessing $datafile"
    if [catch {exec sddsprocess $datafile -nowarning \
                 -process=rfFrequency,ave,rfFrequency0 \
                 "-define=column,delta,rfFrequency rfFrequency0 - rfFrequency0 / $momentumCompactionFactor / chs"} result] {
        SetStatus "$result"
    }
    SetStatus "done"
}

proc chromProcessing {} {
    global output outputDir start stop points offset review getChromatic chromProcMode
    global momentumCompactionFactor chromBadPointList
    set oldDir [pwd]
    cd $outputDir
    set root [file rootname $output]
    SetStatus "Performing chromatic processing for $output."
    
    if [catch {exec sddsquery $output -parameter} parameterList] {
        cd $oldDir
        SetStatus "$parameterList"
        return
    }
    set HPVSAUsed 0
    if [lsearch -exact $parameterList HPVSAUsed]!=-1 {
        if [catch {exec sdds2stream -parameter=HPVSAUsed $output} HPVSAUsed] {
            cd $oldDir
            SetStatus "$HPVSAUsed"
            return
        }
    }
    if {$HPVSAUsed && [string compare $chromProcMode peakfind]!=0} {
        cd $oldDir
        SetStatus "Data is from HPVSA.  You must use peakfind+smoothing at this time."
        return
    }

    set badPointList ""
    if [string length $chromBadPointList] {
        set badPointList0 [split $chromBadPointList " ,"]
        foreach item0 $badPointList0 {
            if [scan $item0 %ld item]==1 {
                lappend badPointList $item
            }
        }
        set chromBadPointList [join $badPointList]
    }

    if !$review {
        set tuneFileList0 [lsort [glob -nocomplain ${root}Tunes-\[0-9\]\[0-9\]\[0-9\]]]
        if [llength $badPointList] {
            foreach file $tuneFileList0 {
                set isbad 0
                foreach item $badPointList {
                    incr item -1
                    if [string compare $file [format ${root}Tunes-%03ld $item]]==0 {
                        set isbad 1
                        break
                    }
                }
                if !$isbad {
                    lappend tuneFileList $file
                }
            }
        } else {
            set tuneFileList $tuneFileList0
        }
        set tuneFiles [llength $tuneFileList]
        if !$tuneFiles {
            SetStatus "No data matches ${root}Tunes-\[0-9\]\[0-9\]\[0-9\]"
            cd $oldDir
            return
        }
        SetStatus "Processing $tuneFiles files"
        switch $chromProcMode {
            peakfind {
                if [catch {eval exec sddscombine $tuneFileList \
                             ${root}traces.sdds -overwrite \
                         } result] {
                    SetStatus $result
                    cd $oldDir
                    return
                }	
                
                # HPVSA data
                if [catch {exec sddscollapse ${root}traces.sdds -pipe=out \
                             | sddsprocess -pipe=in ${root}tune.sdds \
                             -process=rfFrequency,ave,rfFrequency0 \
                                 -define=param,alpha,$momentumCompactionFactor \
                             "-define=column,delta,rfFrequency rfFrequency0 - rfFrequency0 / alpha / chs,symbol=\$gd\$r" \
                         } result] {
                    cd $oldDir
                    SetStatus $result
                    return
                }
                set fitColumnRoot Tune
            }
            convolve {
                set referenceFile [lindex $tuneFileList [expr int($tuneFiles/2)]]
                SetStatus "Reference tune file: $referenceFile"
                set tmpRoot /tmp/[APSTmpString]
                if [catch {eval exec sddscombine $tuneFileList -pipe=out \
                             | sddssort -pipe=in -column=Tune,incr $tmpRoot.traces 
                    exec sddscollapse $tmpRoot.traces $tmpRoot.params
                    eval exec sddscombine [APSReplicateItem -item $referenceFile -number $tuneFiles] \
                             -pipe=out \
                             | sddssort -pipe=in -column=Tune,incr $tmpRoot.ref} result] {
                    SetStatus $result
                    cd $oldDir
                    return
                }
                set filter -filter=column,Tune,0,0.23 
                foreach plane {x y} {
                    if [catch {exec sddsprocess $tmpRoot.traces $tmpRoot.traces.$plane \
                                 $filter \
                                 -process=SR:TUNE1,spread,WSpread -process=SR:TUNE1,min,WMin \
                                 -process=Tune,ave,Tune0 \
                                 "-define=column,W,SR:TUNE1 WMin - WSpread /" \
                                 "-define=column,dTune,Tune Tune0 -"
                        exec sddsprocess $tmpRoot.ref $tmpRoot.ref.$plane \
                                 $filter \
                                 -process=SR:TUNE1,spread,WSpread -process=SR:TUNE1,min,WMin \
                                 -process=Tune,ave,Tune0 \
                                 "-define=column,W,SR:TUNE1 WMin - WSpread /" \
                                 "-define=column,dTune,Tune Tune0 -"
                        eval exec sddsconvolve -correlate \
                                 -signal=dTune,W $tmpRoot.traces.$plane \
                                 -response=dTune,W $tmpRoot.ref.$plane \
                                 -output=dTune,WW -pipe=out \
                                 | tee convolve.$plane \
                                 | sddsprocess -pipe \
                                 -process=WW,max,${plane}TuneChange,function=dTune,position \
                                 | sddscollapse -pipe=in $tmpRoot.$plane \
                             } result] {
                        SetStatus $result
                        cd $oldDir
                        return
                    }	
                    set filter -filter=column,Tune,0.23,1
                }

                if [catch {exec sddsxref $tmpRoot.x $tmpRoot.y -pipe=out \
                             | sddsxref -pipe $tmpRoot.params \
                             | sddsprocess -pipe=in ${root}tune.sdds \
                             -define=param,alpha,$momentumCompactionFactor \
                             -process=rfFreq,ave,rfFreq0 \
                             "-define=col,delta,rfFreq rfFreq0 - rfFreq0 / alpha / chs,symbol=\$gd\$r" \
                         } result] {
                    cd $oldDir
                    SetStatus $result
                    return
                }
                
                file delete [glob -nocomplain $tmpRoot.*]
                set fitColumnRoot TuneChange
            }
            integrate {
                set tmpRoot /tmp/[APSTmpString]
                if [catch {eval exec sddscombine $tuneFileList \
                             -pipe=out \
                             | sddssort -pipe -column=Tune,incr \
                             | tee ${root}traces.sdds \
                             | sddscollapse -pipe \
                             | sddsconvert -pipe=in -delete=column,?Tune $tmpRoot.params } result] {
                    SetStatus $result
                    cd $oldDir
                    return
                }	
                set filter -filter=column,Tune,0,.23
                foreach plane {x y} {
                    if [catch {exec sddsprocess ${root}traces.sdds -pipe=out $filter \
                                 -delete=param,?Tune \
                                 | sddsinteg -versus=Tune -integrate=SR:TUNE1 -pipe \
                                 | sddsprocess -pipe \
                                 -process=SR:TUNE1Integ,min,SR:TUNE1IntegMin \
                                 -process=SR:TUNE1Integ,spread,SR:TUNE1IntegSpread \
                                 "-define=column,W,SR:TUNE1Integ SR:TUNE1IntegMin - SR:TUNE1IntegSpread /" \
                                 -process=W,zero,${plane}Tune,functionOf=Tune,offset=-0.5 \
                                 | sddscollapse -pipe=in $tmpRoot.$plane} result] {
                        SetStatus $result
                        cd $oldDir
                        return
                    }
                    set filter -filter=column,Tune,0.23,1
                }
                if [catch {exec sddsxref $tmpRoot.x $tmpRoot.y -pipe=out \
                             | sddsprocess -pipe=in ${root}tune.sdds \
                             -define=param,alpha,$momentumCompactionFactor \
                             -process=rfFreq,ave,rfFreq0 \
                             "-define=col,delta,rfFreq rfFreq0 - rfFreq0 / alpha / chs,symbol=\$gd\$r" \
                         } result] {
                    cd $oldDir
                    SetStatus $result
                    return
                }
                
                file delete [glob -nocomplain $tmpRoot.*]
                set fitColumnRoot Tune
            }
        }
        foreach plane {x y} {
            SetStatus "fitting $plane plane ..."
            if [catch {exec sddspfit ${root}tune.sdds -pipe=out -col=delta,${plane}${fitColumnRoot} -terms=2 \
                         | sddsoutlier -pipe -column=${plane}${fitColumnRoot}Residual -stDevLimit=2 \
                         | sddspfit -pipe -col=delta,${plane}${fitColumnRoot} -terms=2 -generate \
                         | sddsconvert -pipe \
                         -rename=param,Slope=${plane}Chromaticity,SlopeSigma=${plane}ChromaticitySigma \
                         -nowarning  \
                         | sddsprocess -pipe=in ${root}${plane}Tune.fit \
                         "-define=parameter,FitPoints,n_rows,type=long" \
                         "-print=param,${plane}FitLabel,${plane}: RMS Residual=%.2g N=%ld,RmsResidual,FitPoints" \
                         "-print=param,${plane}ChromLabel,${plane} = %.2f\$sa\$e%.2f,${plane}Chromaticity,${plane}ChromaticitySigma" \
                     } result] {
                SetStatus $result
                cd $oldDir
                return
            }	
        }
        if {[catch {exec sddsxref -nowarning ${root}tune.sdds -pipe=out \
                      ${root}yTune.fit -leave=* -transfer=param,yChrom*,yFitLabel \
                      | sddsxref -pipe -nowarning ${root}xTune.fit \
                      -leave=* -transfer=param,xChrom*,xFitLabel \
                      | sddsprocess -pipe=in ${root}tune.sdds1  \
                      "-print=param,FitLabel,%s  %s,xFitLabel,yFitLabel" \
                      "-print=param,ChromLabel,Chromaticities: %s %s,yChromLabel,xChromLabel" 
            exec mv ${root}tune.sdds1 ${root}tune.sdds } result]}  {
            SetStatus $result
            cd $oldDir
            return
        }
        
        catch {rm ${root}*~}
    }
    if [catch {exec sddsplot \
                 -col=delta,?$fitColumnRoot -graph=sym,vary=subtype,scale=2 \
                 -legend=scale=2 ${root}tune.sdds \
                 -title=@FitLabel -topline=@ChromLabel \
                 -col=delta,x${fitColumnRoot}Fit ${root}xTune.fit -grap=line,type=0 \
                 -col=delta,y${fitColumnRoot}Fit ${root}yTune.fit -grap=line,type=1 "-ylabel=Tune value" &  \
             } result] {
        cd $oldDir
        SetStatus $result
        return
    }

    
    if [catch {exec sddsplot -split=page -separate=page -groupby=page -same \
                 "-ylabel=Waveform" "-xlabel=Tune" -mode=y=log,y=special \
                 -legend=yname,edit=%/Waveform// -graph=line,vary \
                 -column=xTune,xWaveform \
                 ${root}traces.sdds \
                 -column=xTune,xWaveformSmoothed \
                 ${root}traces.sdds \
                 -column=yTune,yWaveform \
                 ${root}traces.sdds \
                 -column=yTune,yWaveformSmoothed \
                 ${root}traces.sdds \
                 -parameter=xTune,xWaveformPeak -graph=sym,scale=3,subtype=5 \
                 ${root}traces.sdds -legend=spec= \
                 -parameter=yTune,yWaveformPeak -graph=sym,scale=3,subtype=5 \
                 ${root}traces.sdds -legend=spec= & } result] {
        cd $oldDir
        SetStatus $result
        return
    }
    cd $oldDir
    SetStatus Done.
}

#-----------------------------------------------------------------------------
#
proc calcDispersion1 {} {
    #
    #-----------------------------------------------------------------------------
    global output outputDir start stop points offset review momentumCompactionFactor
    #-----------------------------------------------------------------------------
    #
    set oldDir [pwd]
    SetStatus "Calculating the first order dispersion for $output."
    cd $outputDir
    #    
    #-----------------------------------------------------------------------------

    set firstCommand "cat $output"
    if [lsearch [APSGetSDDSNames -fileName $output -class parameter] \
          sddsexperimentUsed]!=-1 {
              if [catch {APSGetSDDSParameter -fileName $output \
                           -parameter sddsexperimentUsed} result] {
                  cd $oldDir
                  SetStatus "Problem getting value of sddsexperimentUsed \
                       parameter: $result"
                  return
              }
              set sddsexperimentUsed [lindex $result 0]
              if $sddsexperimentUsed {
                  set firstCommand "sddscollect $output -pipe=out \
                              -collect=suffix=:ms:x \
                              -collect=suffix=:ms:y "
              }
          } else {
              set sddsExperimentUsed 0
          }

    # take slopes
    #note requires /home/helios/oagData/sr/lattices/scripts/SRBPMPosition.xref file for booster
    set xrefFile /home/helios/oagData/booster/dispChrom/inputFiles/BooBPMPosition.xref
    if [catch {eval exec $firstCommand \
                 | sddsprocess -pipe -print=param,ActuatorName,rfFrequency \
                 -nowarning \
                 | sddsvslopes -pipe -indep=rfFrequency \
                 | sddsxref    -pipe -match=Rootname=BPMName -noWarning \
                 $xrefFile \
                 -take=s \
                 | sddssort    -pipe -col=s \
                 | sddsprocess -pipe -redefine=param,nBPMSectors,40,type=long \
                 | sddsprocess -pipe=in $output.slopes \
                 -redefine=column,Index,i_row,type=long \
                 -print=param,ActuatorName,rfFrequency \
                 -redefine=param,alpha,$momentumCompactionFactor \
                 -redefine=param,centerFrequency,351.927036e6,units=Hz \
                 {"-redefine=col,xDispersion,:ms:xSlope \
              alpha * centerFrequency * chs,symbol=\$gc\$r\$a(1)\$bx\$n,units=mm"} \
                 {"-redefine=col,yDispersion,:ms:ySlope \
              alpha * centerFrequency * chs,symbol=\$gc\$r\$a(1)\$by\$n,units=mm"} \
             } result] {
        cd $oldDir
        SetStatus "Problem taking slopes: $result"
        return
    }
    
    exec sddsplot $output.slopes -col=Index,?Dispersion \
      -graph=line,vary -uns=y -axes=x &

    exec sddsplot $output.slopes -col=Rootname,?Dispersion \
      -graph=sym,conn=sub,vary=sub \
      -uns=y -axes=x \
      -split=column=Index,width=18 \
      -sep=subpage -leg \
      -group=subpage -same=y &

    SetStatus Done.
    cd $oldDir
}
    
#-----------------------------------------------------------------------------
#
proc calcDispersion2 {} {

    global output outputDir start stop points offset review
    global dx0r dy0r dx0s dy0s dx1r dy1r dx1s dy1s xfit yfit
    global columnList rfFrequency0 momentumCompactionFactor

    SetStatus "Calculating the second order dispersion for $output."
    set oldDir [pwd]
    cd $outputDir
    
    set help1 "[APSGetSDDSParameter -fileName $output -parameter rfFrequency0]"
    set help2 "[APSGetSDDSParameter -fileName $output -parameter sddsexperimentUsed]"
    set parameterList [APSGetSDDSNames -fileName $output -class parameter]
    #----------------------------------------------------------------------
    # Obtaining the value of rfFrequency0
    #
    if [lsearch $parameterList rfFrequency0]==-1 {
        cd $oldDir
        SetStatus "Problems with parameter rfFrequency0"
        return
    } else {set rfFrequency0 $help1}
    SetStatus "rfFrequency0 = $rfFrequency0"
    #----------------------------------------------------------------------
    # Obtaining the value of sddsexperimentUsed and it's checking
    #
    if [lsearch $parameterList sddsexperimentUsed]==-1 {
        cd $oldDir
        SetStatus "Parameter sddsexperimentUsed is unknown"
        return
    } else {set sddsexperimentUsed $help2}
    SetStatus "sddsexperimentUsed = $sddsexperimentUsed"
    if $sddsexperimentUsed==0 {
        cd $oldDir
        SetStatus "Calculation is impossible: parameter sddsexperimentUsed=0"
        return
    } 
    #----------------------------------------------------------------------
    # Obtaining the list of the all columns
    #
    if ![catch {eval exec sddsquery $output -columnList} columnList]==0 {
        cd $oldDir
        SetStatus "Problems: $columnList"
        return
    } 
    #----------------------------------------------------------------------
    # Obtaining the list of the BPM with measuring x,y-orbits
    #
    set bpmListHelp ""
    foreach columnName $columnList {
        if {![regexp :ms:x $columnName]==0} {
            lappend bpmListHelp $columnName
        } else {
            if {![regexp :ms:y $columnName]==0} {
                lappend bpmListHelp $columnName
            }
        }
    }
    #    SetStatus "bpmListHelp = $bpmListHelp"
    
    #----------------------------------------------------------------------
    # Preparation of dependent column names for mpfit-function
    #
    set bpmNames ""
    set index -1
    foreach columnName $bpmListHelp {
        if {[regexp :AdjustedCC $columnName]==0} {
            incr index
            if {$index == 0} {
                set bpmNames $columnName
            } else {
                set bpmNames $bpmNames,$columnName
            }
        }
    }
    #    SetStatus "bpmNames = $bpmNames"
    #note requires xrefFile for booster
    set xrefFile /home/helios/oagData/booster/dispChrom/inputFiles/BooBPMPosition.xref

    #----------------------------------------------------------------------
    #
    #                     DISPERSION of first and second orders
    #
    #----------------------------------------------------------------------
    # Fitting with polynomial of the second order
    # 
    # preparation of the file $output.frame with data of the dependence 
    # :ms:x, :ms:y, :ms:xFit and :ms:yFit on rfFrequency for each BPM
    #
    SetStatus "Start of the dispersions calculations." 
    SetStatus "Wait approximately 40 seconds, please..."
    set dispExpr0x "xSlope alpha * centerFrequency * chs"
    set dispExpr1x "xCurvature alpha * alpha * centerFrequency * centerFrequency *" 
    set dispExpr0y "ySlope alpha * centerFrequency * chs"
    set dispExpr1y "yCurvature alpha * alpha * centerFrequency * centerFrequency *" 
    set dispParam0x "symbol=\$gc\$r\$a(1)\$r\$bx\$n,units=mm"
    set dispParam1x "symbol=\$gc\$r\$a(2)\$r\$bx\$n,units=mm"
    set dispParam0y "symbol=\$gc\$r\$a(1)\$r\$by\$n,units=mm"
    set dispParam1y "symbol=\$gc\$r\$a(2)\$r\$by\$n,units=mm"
    if [catch {eval exec sddsmpfit $output -pipe=out \
                 -indep=rfFrequency \
                 -depend=$bpmNames \
                 -xOffset=$rfFrequency0 -term=3 \
                 | sddsconvert -pipe=in $output.frame \
                 -retain=column,rfFrequency \
                 -retain=column,*ms:x \
                 -retain=column,*ms:xFit \
                 -retain=column,*ms:y \
                 -retain=column,*ms:yFit \
                 -retain=parameter,*:ms:xCurvature \
                 -retain=parameter,*:ms:yCurvature \
                 -retain=parameter,*:ms:xSlope\
                 -retain=parameter,*:ms:ySlpoe \
                 -delete=parameter,rfFrequency* \
                 -delete=parameter,Basis \
                 -delete=parameter,Terms \
                 -delete=parameter,*:ms:xRmsResidual \
                 -delete=parameter,*:ms:xFitIsValid \
                 -delete=parameter,*:ms:xSddspfitlabel \
                 -delete=parameter,*:ms:xIntercept \
                 -delete=parameter,*:ms:yRmsResidual \
                 -delete=parameter,*:ms:yFitIsValid \
                 -delete=parameter,*:ms:ySddspfitlabel \
                 -delete=parameter,*:ms:yIntercept \
             } result] {
        cd $oldDir
        SetStatus "Problems: $result"
        APSAddToTempFileList $output.frame     
        return
    }
    SetStatus "File $output.frame is written"   
    APSAddToTempFileList $output.frame    

    #----------------------------------------------------------------------
    # obtaining for each BPM the values of slope and curvature coefficients
    # 
    if [catch {eval exec sddsconvert $output.frame -pipe=out \
                 -delete=column,* \
                 | sddscollapse -pipe \
                 | sddscollect -pipe -collect=suffix=:ms:xCurvature \
                 -collect=suffix=:ms:xSlope \
                 -collect=suffix=:ms:xReducedChiSquared  \
                 -collect=suffix=:ms:xSignicanceLevel  \
                 -collect=suffix=:ms:yCurvature \
                 -collect=suffix=:ms:ySlope \
                 -collect=suffix=:ms:yReducedChiSquared  \
                 -collect=suffix=:ms:ySignicanceLevel  \
                 | sddsconvert -pipe \
                 -rename=column,:ms:xCurvature=xCurvature \
                 -rename=column,:ms:xSlope=xSlope \
                 -rename=column,:ms:xReducedChiSquared=xReducedChiSquared \
                 -rename=column,:ms:xSignicanceLevel=xSignicanceLevel \
                 -rename=column,:ms:yCurvature=yCurvature \
                 -rename=column,:ms:ySlope=ySlope \
                 -rename=column,:ms:yReducedChiSquared=yReducedChiSquared \
                 -rename=column,:ms:ySignicanceLevel=ySignicanceLevel \
                 | sddsxref -pipe -match=Rootname=BPMName $xrefFile \
                 -take=s -noWarning \
                 | sddssort -pipe -col=s \
                 | sddsprocess -pipe \
                 -redefine=param,nBPMSectors,40,type=long \
                 | sddsprocess -pipe=in $output.mpfit \
                 -redefine=column,Index,i_row,type=long \
                 -redefine=param,alpha,$momentumCompactionFactor \
                 -redefine=param,centerFrequency,$rfFrequency0,units=Hz \
                 {"-redefine=col,xDispersion1,$dispExpr0x,$dispParam0x"} \
                 {"-redefine=col,xDispersion2,$dispExpr1x,$dispParam1x"} \
                 {"-redefine=col,yDispersion1,$dispExpr0y,$dispParam0y"} \
                 {"-redefine=col,yDispersion2,$dispExpr1y,$dispParam1y"} \
             } result] {
        cd $oldDir
        SetStatus "Problems: $result"
        APSAddToTempFileList $output.mpfit    
        return
    }
    SetStatus "File $output.mpfit is written"   
    APSAddToTempFileList $output.mpfit    

    #----------------------------------------------------------------------
    # Printing result data (X)
    #
    if [catch {exec sddsprintout $output.mpfit $output.Xtable \
                 -column=Index \
                 -column=Rootname,format=%10s \
                 -column=xDispersion1,format=%12.5f \
                 -column=xDispersion2,format=%12.5f \
                 -column=xSlope,format=%12.5e \
                 -column=xCurvature,format=%12.5e \
                 -column=xReducedChiSquared,format=%12.5e \
                 -column=xSignicanceLevel,format=%12.5f} result] {
        cd $oldDir
        SetStatus "Problems for file $output.Xtable due to $result"
        APSAddToTempFileList $output.Xtable    
    }
    SetStatus "File $output.Xtable is written"   
    APSAddToTempFileList $output.Xtable    
    
    APSFileDisplayWindow .[APSUniqueName printout] -fileName $output.Xtable \
      -deleteOnClose 1 -width 120 
    #----------------------------------------------------------------------
    # Printing result data (Y)
    #
    if [catch {exec sddsprintout $output.mpfit $output.Ytable \
                 -column=Index \
                 -column=Rootname,format=%10s \
                 -column=yDispersion1,format=%12.5f \
                 -column=yDispersion2,format=%12.5f \
                 -column=ySlope,format=%12.5e \
                 -column=yCurvature,format=%12.5e \
                 -column=yReducedChiSquared,format=%12.5e \
                 -column=ySignicanceLevel,format=%12.5f} result] {
        cd $oldDir
        SetStatus "Problems for file $output.Ytable due to $result"
        APSAddToTempFileList $output.Ytable    
    }
    SetStatus "File $output.Ytable is written" 
    APSAddToTempFileList $output.Ytable    
    
    APSFileDisplayWindow .[APSUniqueName printout] -fileName $output.Ytable \
      -deleteOnClose 1 -width 120 
    menuPlotting  
    cd $oldDir
}

#-----------------------------------------------------------------------------
#
#   Plotting of all results
#
proc doPlotting {} {

    global output
    global columnList rfFrequency0
    global dx0r dy0r dx0s dy0s dx1r dy1r dx1s dy1s xfit yfit

    #----------------------------------------------------------------------
    # Plotting result data for first order dispersions
    #
    #----------------------------------------------------------------------
    #  X over total ring:
    #
    
    if {$dx0r == 1} {
       exec sddsplot $output.mpfit -col=Index,xDispersion1 \
                                   -graph=line,vary -uns=y -axes=x &
    }  
    
    #----------------------------------------------------------------------
    #  X over ring by separate pieces:
    #
    if {$dx0s == 1} {
       exec sddsplot $output.mpfit -col=Rootname,xDispersion1 \
                                   -graph=sym,conn=sub,vary=sub \
                                   -uns=y -axes=x \
                                   -split=column=Index,width=18 \
                                   -sep=subpage \
                                   -group=subpage -same=y &
    }

    #----------------------------------------------------------------------
    #  Y over total ring:
    #
    if {$dy0r == 1} {
       exec sddsplot $output.mpfit -col=Index,yDispersion1 \
                                   -graph=line,vary -uns=y -axes=x &
    }
    
    #----------------------------------------------------------------------
    #  Y over ring by separate pieces:
    #
    if {$dy0s == 1} {
       exec sddsplot $output.mpfit -col=Rootname,yDispersion1 \
                                   -graph=sym,conn=sub,vary=sub \
                                   -uns=y -axes=x \
                                   -split=column=Index,width=18 \
                                   -sep=subpage \
                                   -group=subpage -same=y &
    }
    
    #----------------------------------------------------------------------
    # Plotting result data for second order dispersions
    #
    #----------------------------------------------------------------------
    #  X over total ring:
    #
    if {$dx1r == 1} {
       exec sddsplot $output.mpfit -col=Index,xDispersion2 \
                                   -graph=line,vary \
                                   -uns=y -axes=x &
    }
    
    #----------------------------------------------------------------------
    #  X over ring by separate pieces:
    #
    if {$dx1s == 1} {
       exec sddsplot $output.mpfit -col=Rootname,xDispersion2 \
                                   -graph=sym,conn=sub,vary=sub \
                                   -uns=y -axes=x \
                                   -split=column=Index,width=18 \
                                   -sep=subpage \
                                   -group=subpage -same=y &
    }
    
    #----------------------------------------------------------------------
    #  Y over total ring:
    #
    if {$dy1r == 1} {
       exec sddsplot $output.mpfit -col=Index,yDispersion2 \
                                   -graph=line,vary \
                                   -uns=y -axes=x &
    }
    
    #----------------------------------------------------------------------
    #  Y over ring by separate pieces:
    #
    if {$dy1s == 1} {
       exec sddsplot $output.mpfit -col=Rootname,yDispersion2 \
                                   -graph=sym,conn=sub,vary=sub \
                                   -uns=y -axes=x \
                                   -split=column=Index,width=18 \
                                   -sep=subpage \
                                   -group=subpage -same=y &
    }
    
    #----------------------------------------------------------------------
    # Plotting result data for X-fitting
    #
    if {$xfit == 1} {
       set xoffset [expr -1*$rfFrequency0]
       set columnsPlotted "-layout=3,3 -group=nameindex -sep=nameindex \
                           -graph=line,vary -offset=xChange=$xoffset"
       set plotList1 ""
       set plotList2 ""

       foreach columnName $columnList {
           if {[string match *:ms:x $columnName]} {
               lappend plotList1 $columnName
               lappend plotList2 ${columnName}Fit
           }
       }

       eval exec sddsplot $columnsPlotted \
                 -column=rfFrequency,([join $plotList1 ,]) $output.frame \
                 -column=rfFrequency,([join $plotList2 ,]) $output.frame &
    }
    
    #----------------------------------------------------------------------
    # Plotting result data for Y-fitting
    #
    if {$yfit == 1} {
       set xoffset [expr -1*$rfFrequency0]
       set columnsPlotted "-layout=3,3 -group=nameindex -sep=nameindex \
                           -graph=line,vary -offset=xChange=$xoffset"
       set plotList1 ""
       set plotList2 ""

       foreach columnName $columnList {
          if {[string match *:ms:y $columnName]} {
             lappend plotList1 $columnName
             lappend plotList2 ${columnName}Fit
          }
       }

       eval exec sddsplot $columnsPlotted \
                 -column=rfFrequency,([join $plotList1 ,]) $output.frame \
                 -column=rfFrequency,([join $plotList2 ,]) $output.frame &
    }
    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 ChangeBoosterFrequency {args} {
    
    APSParseArguments {BFreq mainStatus}
    #frequency change value in Hz
    
    SetStatus "Change booster frequency ..."
    if ![string $BFreq] {
        return -code error "The frequence for changing is not given!"
    }
    set P1Freq [expr $BSFreq / 36]
    set P12Freq [expr $P1Freq /12]
    
    if [catch {exec cavget -list=BRF:S:Hp8657RefFreq -pend=30} BSCurrentFreq] {
     #   SetStatus "Error in reading BS frequency: $BSCurrentFreq"
        return -code error "Error in reading BS frequency: $BSCurrentFreq"
    }
    
    # Ramp the frequencies down slowly
    while {$BSFreq < $BSCurrentFreq} {
        set P1CurrentFreq [expr $P1CurrentFreq - 10]
        set BSCurrentFreq [expr $P1CurrentFreq * 36]
        if [catch {exec cavput -list=BRF:S:Hp8657RefFreq=$BSFreqCurrent -pend=30} result] {
          #  SetStatus "ChangeBoosterFreq1: $result"
            return -code error "ChangeBoosterFreq1: $result"
        }
        SetStatus "Ramping the booster frequency down to $BSFreq"
        after 2000
    }
    # Ramp the frequencies up slowly
    while {$BSFreq > $BSCurrentFreq} {
        set P1CurrentFreq [expr $P1CurrentFreq + 10]
        set BSCurrentFreq [expr $P1CurrentFreq * 36]
        if [catch {exec cavput -list=BRF:S:Hp8657RefFreq=$BSFreqCurrent -pend=30} result] {
        #    SetStatus "ChangeBoosterFreq1: $result"
            return -code error "ChangeBoosterFreq1: $result"
        }
        SetStatus "Ramping the booster frequency up to $BSFreq"
        after 2000
    }
    if [catch {exec cavput -list=BRF:S:Hp8657RefFreq=$BSFreq -pend=30} result] {
       # SetStatus "ChangeBoosterFreq1: $result"
        return -code error "ChangeBoosterFreq1: $result"
    }
    SetStatus "Booster frequency set to $BSFreq"
    if [catch {exec cavput -list=Mt:P0:resync_counters_bo=1 -pend=30} result] {
       # SetStatus "ChangeBoosterFreq2: $result"
        return -code error "ChangeBoosterFreq2: $result"
    }
    SetStatus "Waiting 5 seconds to return booster efficiency..."
    after 5000
    SetStatus "Change booster frequnce to $BFreq done."
}

proc MeasureBoosterTune {args} {
    set rootname ""
    set outputDir ""
    set step 0
    #step in seconds
    APSParseArguments {rootname outptuDir step}

    set start 0.200
    set end 0.248
    set steps [expr int(($end-$start)/$step+0.5)]
    set index 0
    set turnTime [exec rpnl 1104 c_mks /]
    set HVslope [exec rpnl 6 2 - .248 .075 - /]
    set fileList ""
    SetStatus "Measure Booster Tunes..."
    while {$index < $steps} {
        exec sockex hpvecboo.aps4.anl.gov "swe1:time:del $start s"
        set turns [expr int(($start - 75e-3)/$turnTime +13817) ]
        set HV [expr ($start-75e-3)*$HVslope+2]
        if [catch {exec cavput -list=B:EK:VoltageAO,B:EK:VoltageSetSendAO=$HV -pend=30} result] {
            SetStatus "MeasureBoosterTune: $result"
            return
        }
        after 1000
        exec sockex hpvecboo.aps4.anl.gov "abor;*wai"
        SetStatus "Wait for 12 seconds ..."
        after 12000
        exec hpVecTrace -hpvecboo a $outputDir/${rootname}tmp.sdds
        set index1 [format %.3d $index]
        if [catch {exec sddsprocess $outputDir/${rootname}tmp.sdds $outputDir/${rootname}-${index1}.sdds \
                     -define=parameter,TimeDelay,$start,units=s } result] {
            SetStatus "MeasureBoosterTune: $result"
            return
        }
        lappend fileList $outputDir/${rootname}-${index1}.sdds
        set start [expr $start + $step]
        incr index
    }
    if [catch {eval exec sddscombine $fileList $outputDir/${rootname}.sdds -overwrite} result] {
        SetStatus "MeasureBoosterTune: $result"
        return
    }
    eval file delete -force $fileList
    file delete -force $outputDir/${rootname}tmp.sdds
}

proc GetBoosterTuneOrbitData {args} {
    set startFreq ""
    set endFreq ""
    set points 0
    set outputDir ""
    set inputDir ""
    #freqRange: total range of frequencies in Hz to vary about the normial booster RF frequence"
    APSParseArguments {startFreq endFreq points outputDir inputDir}
  
    SetStatus "Get Booster Tune orbit data..."
    set freqinc [expr int(($endFreq-$startFreq)/$points)]
    
    set HPTrigDelay 0.0000
    if [catch {exec cavget -list=B:bpmT1_8:Delay_count_lo -pend=30} BPMturns] {
        SetStatus "GetBoosterTuneOrbitData: $result"
        return
    }
    set BPMturnsStart 1018
    set BPMturnsEnd 46420
    set start   0.02508
    set end   0.2480082

    set startturns   6810
    set endturns   67346
    set turnsoffset   50
    set currenturns [expr int(($BPMturns -$BPMturnsStart)* \
                                 ($endturns-$startturns)/($BPMturnsEnd-$BPMturnsStart) +$turnsoffset)]
    SetStatus "set current turns to $currentturns"
    if [catch {exec cavput -list=Mt:BoosterRampTurnsAO.VAL=$currentturns -pend=30} result] {
        SetStatus "GetBoosterTuneOrbitData: $result"
        return
    }
    set kickerEndHV [expr 0.6/0.4*7]
    set kickerStartHV 0.25
    set kickerHVSlope [expr ($kickerEndHV - $kickerStartHV)/($endturns - $starturns)]
    set kickerHV [expr $kickerStartHV + $kickerHVSlope*$currenturns]
    SetStatus "set Kicker High Voltage to $kickerHV"
    if [catch {exec cavput -list=B:EK:VoltageAO=$kickerHV -pend=30} result] {
        SetStatus "GetBoosterTuneOrbitData: $result"
        return
    }
    after 2000
    if [catch {exec cavput -list=B:EK:VoltageSetSendAO=$kickerHV -pend=30} result] {
        SetStatus "GetBoosterTuneOrbitData: $result"
        return
    }
    after 2000
    set HPtrigger [expr $start + ($end -$start)/($endturns-$starturns)*$currenturns + $HPTrigDelay]
    set BPMtrigger [expr ($currenturns-$turnsoffset)*($end-$start)/($endturns-$starturns)+$start]
    SetStatus "BPM trigger = $BPMtrigger seconds"
    exec sockex hpvecboo.aps4.anl.gov "swe1:time:del $HPtrigger s"
    SetStatus "HPVSA trigger set to t = $HPtrigger seconds"
    set index 0
    set limit 5
    if [catch {exec cavget -list=BRF:S:Hp8657RefFreq -pend=30} BFreqNominal] {
        SetStatus "GetBoosterTuneOrbitData: $BFreqNominal"
        return
    }
    set BFreq [expr $startFreq+$BFreqNominal]
    if [catch {ChangeBoosterFrequency -BFreq $BFreq } result] {
        SetStatus "GetBoosterTuneOrbitData: $result"
        return
    }
    set fileList1 ""
    set fileList2 ""
    for {set index 0} {$index < $points} {
        exec sockex hpvecboo.aps4.anl.gov "abor;*wai"
        SetStatus "waiting for 13 seconds"
        after 13000
        set index1 [format %.3d $index]
        exec hpVecTrace -hpvecboo a $outputDir/tune-${index1}.sdds
        exec sddsvmonitor -suffixes=$inputDir/BbpmSuffix.sdds $outputDir/Borbit-${index1}.sdds \
          -scalars=$inputDir/OrbitPV.sdds -steps=1
        exec sddsprocess $outputDir/tune-${index1}.sdds -nowarning \
          -define=parameter,BRFrequency,$BFreq,units=Hz \
          -define=parameter,HPtrigger,${HPtrigger},units=s
        exec sddsprocess $outputDir/Borbit-${index1}.sdds -nowarning \
          -define=parameter,BPMtrigger,${BPMtrigger},units=s
        exec \rm $outputDir/tune-${index1}.sdds~
        exec \rm $outputDir/Borbit-${index1}.sdds~
        lappend fileList1 $outputDir/tune-${index1}.sdds
        lappend fileList2 $outputDir/Borbit-${index1}.sdds
        set BFreq [expr $BFreq + $freqinc]
        if [catch {ChangeBoosterFrequency -BFreq $BFreq} result] {
            SetStatus "GetBoosterTuneOrbitData: $result"
            return
        }
        set BFreq [expr $BFreq + $freqinc]
        incr index
    }
    SetStatus "Nominal booster frequency is $BFreqNominal"

    if [catch {exec cavput -list=BRF:S:Hp8657RefFreq=351927036 -pend=30} result] {
        SetStatus "GetBoosterTuneOrbitData: $result"
        return
    }
    if [catch {exec cavput -list=Mt:P0:resync_counters_bo=1 -pend=30} result] {
        SetStatus "GetBoosterTuneOrbitData: $result"
        return
    }
    if [catch {eval exec sddscombine $fileList1 $outputDir/tune_${HPtrigger}.sdds } result] {
        SetStatus "GetBoosterTuneOrbitData: $result"
        return
    }
    if [catch {eval exec sddscombine $fileList2 $outputDir/BOrbit_${HPtrigger}.sdds } result] {
        SetStatus "GetBoosterTuneOrbitData: $result"
        return
    }
    eval file delete -force $fileList1
    eval file delete -force $fileList2
}

proc GetMomentumCompactionFactor {} {
    global momentumCompactionFactor latticeSelection
    set latticeDir /home/helios/oagData/booster/orbitControllaw/lattices/$latticeSelection/refMatrices
    set momentumCompactionFactor [format %.3e [exec sdds2stream -para=alphac \
                                                 $latticeDir/${latticeSelection}.twi]]
    return $momentumCompactionFactor
}

set latticeSelection "x13.75-y5.80"
set HPVSABandWidth 3000
set xTune [ComputeTuneFromFrequency -tuneFreq $xFreq]
set yTune [ComputeTuneFromFrequency -tuneFreq $yFreq]
set hpvsaSelection hpvecboo
# Value for default User lattice.
set latticeDir /home/helios/oagData/booster/orbitControllaw/lattices/default/refMatrices
set momentumCompactionFactor [GetMomentumCompactionFactor]

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