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

set auto_path [linsert $auto_path 0 /usr/local/oag/apps/lib/$env(HOST_ARCH)]
set auto_path [linsert $auto_path 0 /usr/local/oag/lib_patch/$env(HOST_ARCH)]
APSDebugPath

APSStandardSetup

set mainStatus Ready.
APSApplication . -name SRDispChromMeasWithDimtel  -overview {Measure orbit and tune spectra at different rf frequencies, and computes the dispersions and chromaticities. Use Dimtel}

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

set output dispChrom01
set start -50
set stop 50
set points 11
set pause 5
set args $argv
APSParseArguments {output start stop points pause}
set dispChrom(output) $output
set dispChrom(extraMonFile) "/home/helios/oagData/sr/dispChrom/inputFiles/extraPVs.mon"
set dispChrom(start) $start
set dispChrom(stop) $stop
set dispChrom(points) $points
set dispChrom(pause) $pause
set dispChrom(offset) 0
set dispChrom(review) 0
set dispChrom(finished) 0

# Value for default User lattice.
set latticeDir $OAGGlobal(SRLatticesDirectory)/default
set latticeName [file link $latticeDir]
set dispChrom(momentumCompactionFactor) [format %.3e [exec sdds2stream -para=alphac $latticeDir/aps.twi]]
set dispChrom(momentumCompactionFactor2) [format %.3e [exec sdds2stream -para=alphac2 $latticeDir/aps.twi]]

set latticeFile /home/helios/oagData/sr/calibratedModels/lattices/default/aps.twi
if ![file exist $latticeFile] {
    set latticeFile  $OAGGlobal(SRLatticesDirectory)/default/aps.twi
}
set dispChrom(latticeDir) $latticeDir
set dispChrom(latticeName) $latticeName

# tunes from calibrated file
set nux [exec sdds2stream -par=nux $latticeFile]
set nuy [exec sdds2stream -par=nuy $latticeFile]
set xTune [format %.2f [expr $nux - floor($nux)]]
set yTune [format %.2f [expr $nuy - floor($nuy)]]
set dispChrom(xTune) $xTune
set dispChrom(yTune) $yTune

set dispChrom(mainDir) /home/helios/oagData/sr/dispChrom
set dispChrom(getChromatic) 1
set dispChrom(fullFrequency) [exec cavget -list=A014-IETS:BTC:SRSetFreqM -floatFormat=%.1f -pendIoTime=5]
set dispChrom(rfFrequency) [exec cavget -list=A014-IETS:BTC:SRSetFreqM -floatFormat=%.1f -pendIoTime=5]
set dispChrom(rfFrequency0) $dispChrom(rfFrequency) 
set dispChrom(drfFrequency0) [exec cavget -list=A014-IETS:BTC:SROffsetFreqC -floatFormat=%.1f -pendIoTime=5]
set dispChrom(harmonic) 1296
set dispChrom(revFrequency) [expr $dispChrom(fullFrequency) / 1296.0]
set dispChrom(measHarmonic) 1390
set dispChrom(xchrom) 8.5
set dispChrom(ychrom) 4.5
set dispChrom(measToAve) 1

set dispChrom(sideband) -1
#obtain default parameters

set dispChrom(expectedXtune) $dispChrom(xTune)
set dispChrom(xFreq) [format %.1f [expr $dispChrom(revFrequency) * ($dispChrom(measHarmonic) + $dispChrom(expectedXtune) * $dispChrom(sideband))]]
set dispChrom(expectedYtune) $dispChrom(yTune)
set dispChrom(yFreq) [format %.1f [expr $dispChrom(revFrequency) * ($dispChrom(measHarmonic) + $dispChrom(expectedYtune) * $dispChrom(sideband))]]
set dispChrom(dividingLine) [format %.3f [expr ($dispChrom(xTune) + $dispChrom(yTune))/2.0]]

set dispChrom(chromProcMode) lorentzian
set dispChrom(chromBadPointList) ""

set dispChrom(getDispersion) 1
set dispChrom(npSmooth) 41
set dispChrom(nPasses) 3

#dimetal parameters
proc MakeDimtelWidget {widget args} {
    set parent ""
    APSParseArguments {parent}
    global srTune dimtel
     
    APSFrame $widget -parent $parent -label "Dimtel parameters"
    set w1 $parent$widget.frame
    
    
    APSFrameGrid .grid -parent $w1 -xList {x1 x2}
    set f1 $w1.grid.x1
    set f2 $w1.grid.x2
    set width 15
    APSLabel .label -parent $f1 -text "                               X Plane"
    APSLabel .lable -parent $f2 -text "     Y Plane"
    
    set paramFile /home/helios/oagData/sr/dispChrom/dimtelParameters.sdds
    set nameList [exec sdds2stream -col=ParameterName $paramFile]
    set valList [exec sdds2stream -col=ParameterValue $paramFile]
    foreach name $nameList val $valList {
	set dimtel($name) [format %.1f $val]
    }
    
    APSLabeledEntry .freq -parent $f1 -label "Drive0 frequency (kHz):" -textVariable dimtel(xDriveFreq) -width $width
    APSLabeledEntry .freq -parent $f2 -label "" -textVariable dimtel(yDriveFreq) -width $width
    
    APSLabeledEntry .span -parent $f1 -label "Drive0 frequency span(kHz):" -textVariable dimtel(xDriveFreqSpan) -width $width
    APSLabeledEntry .span -parent $f2 -label "" -textVariable dimtel(yDriveFreqSpan) -width $width
    
    APSLabeledEntry .period -parent $f1 -label "Drive0 Period (us):" -textVariable dimtel(xDrivePeriod) -width $width
    APSLabeledEntry .period -parent $f2 -label "" -textVariable dimtel(yDrivePeriod) -width $width
   
    APSLabeledEntry .amp -parent $f1 -label "Drive0 Amplitude:" -textVariable dimtel(xDriveAmplitude) -width $width
    APSLabeledEntry .amp -parent $f2 -label "" -textVariable dimtel(yDriveAmplitude) -width $width

    APSLabeledEntry .mlow -parent $f1 -label "Lower Marker:" -textVariable dimtel(xMarkerLow) -width $width
    APSLabeledEntry .mlow -parent $f2 -label "" -textVariable dimtel(yMarkerLow) -width $width

    APSLabeledEntry .mhigh -parent $f1 -label "Lower Marker:" -textVariable dimtel(xMarkerHigh) -width $width
    APSLabeledEntry .mhigh -parent $f2 -label "" -textVariable dimtel(yMarkerHigh) -width $width

   
    APSLabeledOutput .peakfreq -parent $f1 -label "SB peak frequency(kHz):" -textVariable dimtel(xPeakFreq) -width $width
    APSLabeledOutput .peakfreq -parent $f2 -label "" -textVariable dimtel(yPeakFreq) -width $width

    APSLabeledOutput .peak -parent $f1 -label "SB waveform peak:" -textVariable dimtel(xPeak) -width $width
    APSLabeledOutput .peak -parent $f2 -label "" -textVariable dimtel(yPeak) -width $width

    set dimtel(xDriveAmplitude) 0.10
    set dimtel(yDriveAmplitude) 0.10
    set dimtel(pause) 5
    set dimtel(average) 2
    APSLabeledEntry .average -parent $w1 -label "Number of average:" -textVariable dimtel(average) -width $width
    APSLabeledEntry .pause  -parent $w1 -label "Pause for dimtel averaging" -textVariable dimtel(pause) -width $width
    
    APSButton .setup -parent $w1 -text "Setup Dimtel" -command "SetupDimtel"
    APSButton .xdim -parent $w1 -text "X Dimtel Medm" -command "exec /home/helios/SR/dimtel/iGp12/bin/iGp_display_APSU_TFB X &"
    APSButton .ydim -parent $w1 -text "Y Dimtel Medm" -command "exec /home/helios/SR/dimtel/iGp12/bin/iGp_display_APSU_TFB Y &"
}

proc UpdateDriveParameter {args} {
    global dimtel
    switch $dimtel(plane) {
	x {
	    set dimtel(xDriveAmplitude) 0.05
	    set dimtel(yDriveAmplitude) 0
	}
	y {
	    set dimtel(xDriveAmplitude) 0
	    set dimtel(yDriveAmplitude) 0.05
	}
	both {
	    set dimtel(xDriveAmplitude) 0.05
	    set dimtel(yDriveAmplitude) 0.05
	}
    }
}

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


proc makeLabeledEntriesAndRbFrame {widget args} {
    set parent .userFrame

    APSParseArguments {parent}

    global dispChrom

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

    APSLabeledEntry .outputDir -parent $w \
      -label "Output directory:" \
      -textVariable dispChrom(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 dispChrom(outputDir) [APSGoToDailyDirectory -subdirectory dispChrom]}
    APSLabeledEntry .output -parent $w \
      -label "Output file:" -textVariable dispChrom(output) \
      -contextHelp "Enter a name for the output file." \
      -width 55
    APSLabeledEntry .extra -parent $w -width 65 \
      -label "Extra monitor file:" \
      -textVariable dispChrom(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."
    APSFrameGrid .grid -parent $w -xList {x1 x2}
    set w1a $w.grid.x1
    set w2a $w.grid.x2
    APSLabeledEntry .start -parent $w1a \
      -label "Start:" -textVariable dispChrom(start) \
      -contextHelp "Enter a value to start with." \
      -width 10
    APSLabeledEntry .stop -parent $w2a \
      -label "Stop:" -textVariable dispChrom(stop) \
      -contextHelp "Enter a value to stop at." \
      -width 10
    APSLabeledEntry .points -parent $w1a \
      -label "Points:" -textVariable dispChrom(points) \
      -contextHelp "Enter the number of points to use." \
      -width 10
    APSLabeledEntry .measToAve -parent $w2a -width 10 \
      -label "Measurements to average: " \
      -textVariable dispChrom(measToAve) \
      -contextHelp "Enter the number of measurements of the PVs to average. Sample interval is 0.5s."
    APSLabeledEntry .pause -parent $w1a \
      -label "Pause (s):" -textVariable dispChrom(pause) \
      -contextHelp "Enter the number of seconds to wait" \
      -width 10
    APSLabeledOutput .lattice -parent $w2a \
      -label "Lattice Name:" -textVariable dispChrom(latticeName) \
      -contextHelp "lattice linked by $dispChrom(latticeDir). If default lattice is changed, then re-start the GUI." \
      -width 20
    APSLabeledEntry .momcompaction -parent $w1a \
      -label "Momentum Compaction Factor :" -textVariable dispChrom(momentumCompactionFactor) \
      -contextHelp "Initially read from above lattice. Enter the momentum compaction factor (used for dispersion processing only)" \
      -width 10
    APSLabeledEntry .momcompaction2 -parent $w2a \
      -label "2nd-order Momentum Compaction Factor :" -textVariable  dispChrom(momentumCompactionFactor2) \
      -contextHelp "Initially read from above lattice. Enter the second-order momentum compaction factor (used for correcting relation between frequency and momentum error)" \
      -width 10
   
    
    APSRadioButtonFrame .chromRb -parent $w1a -label "Get chromatic data: " \
      -variable dispChrom(getChromatic) \
      -buttonList {Yes No} -valueList {1 0} \
      -orientation horizontal
    APSRadioButtonFrame .disp -parent $w2a -label "Get dispersion data?" -variable dispChrom(getDispersion) \
      -buttonList {Yes No} -valueList {1 0} \
      -orientation horizontal 
   
    MakeDimtelWidget .dimtel -parent $w

    if 0 {
    set width 15
    APSFrame .hpvsa -parent $w -label "Other Parameters" 
    set w1 $w.hpvsa.frame
    APSFrame .f -parent $w1
    $w1.f.frame configure -bd 0
    APSButton .measureTunes -parent $w1.f.frame -text "FIND CENTER FREQUENCIES" \
      -command {MeasureInitialTunes \
                  -mainStatus SetStatus} \
      -contextHelp "Finds the center frequencies \
                                          for x and y tune measurement."
   
    APSFrameGrid .grid -parent $w1 -xList {x1 x2}
    APSLabeledOutput .xfreq -parent $w1.grid.x1 -width $width\
      -label "x frequency center (Hz): " \
      -textVariable dispChrom(xFreq)  \
      -contextHelp "This quantity will NOT be used for calculating the center frequency of the range of the HPVSA. It is updated from the x-tune after the measurement has started."
    APSLabeledEntry .xtune -parent $w1.grid.x1 -width $width\
      -label "fractional x tune: " -textVariable dispChrom(xTune) \
      -contextHelp "This quantity will be used for calculating the center frequency of the range of the HPVSA"
    bind $w1.grid.x1.xtune.entry <Leave> {set dispChrom(xFreq) [ComputeFrequencyFromTune -tune $dispChrom(xTune)];UpdateDividingLine}
    APSLabeledOutput .yfreq -parent $w1.grid.x2 -width $width \
	-label "y frequency center (Hz): " \
	-textVariable dispChrom(yFreq)  \
	-contextHelp "This quantity will NOT be used for calculating the center frequency of the range of the HPVSA. It is updated from the x-tune after the measurement has started."
    APSLabeledEntry .ytune -parent $w1.grid.x2 -width $width \
	-label "fractional y tune: " -textVariable dispChrom(yTune) \
	-contextHelp "This quantity will be used for calculating the center frequecny go the range of the HPVSA"
    bind $w1.grid.x2.ytune.entry <Leave> {set dispChrom(yFreq) [ComputeFrequencyFromTune -tune $dispChrom(yTune)];UpdateDividingLine}
    
   
   
    APSLabeledEntry .chromx -parent $w1.grid.x1 \
      -label "x est. chromaticity: " -textVariable dispChrom(xchrom) -contextHelp \
      "estimated x chromaticity" -width $width
    APSLabeledEntry .chromy -parent $w1.grid.x2 \
      -label "y est. chromaticity: " -textVariable dispChrom(ychrom) -contextHelp \
      "estimated y chromaticity." -width $width

    APSLabeledEntry .div -parent $w1.grid.x2 -width $width \
      -label "Dividing line: " \
      -textVariable dispChrom(dividingLine) \
       -contextHelp "This quantity will be separate the NASA spectrum in two parts"
    APSLabeledEntry .smooth -parent $w1.grid.x1 -width $width\
      -label "Points for smoothing: " \
      -textVariable dispChrom(npSmooth) \
       -contextHelp "-points parameter for sddsmooth for waveform processing."
    APSLabeledEntry .pass -parent $w1.grid.x2 -width $width \
      -label "Passes for smoothing: " \
      -textVariable dispChrom(nPasses) \
       -contextHelp "-passes parameter for sddsmooth for waveform processing."
        }
       
    APSRadioButtonFrame .chromProcMode -parent $w \
      -label "Tune change processing mode: " \
      -variable dispChrom(chromProcMode) \
      -buttonList {DIMTEL Smooth+Peakfind Lorentzian} \
      -valueList {DIMTEL peakfind lorentzian} \
      -orientation horizontal 
    APSLabeledEntry .smooth -parent $w -label "Points for smoothing: " -textVariable dispChrom(npSmooth) \
       -contextHelp "Smooth points parameter for sddsmooth for waveform processing."
    APSLabeledEntry .pass -parent $w -label "Passes for smoothing: " -textVariable dispChrom(nPasses) \
       -contextHelp "-passes parameter for sddsmooth for waveform processing."
    APSLabeledEntry .elimPoints -parent $w \
      -label "List of bad point numbers (space separated): " -width 30 \
      -textVariable dispChrom(chromBadPointList) -contextHelp \
	"Enter a list of point numbers for points to be removed from fit.  Point numbers start from 1."
    set  dispChrom(reverseWaveform) 1
    APSRadioButtonFrame .reverse -parent $w \
      -label "Reverse tune waveform: " \
      -variable dispChrom(reverseWaveform) \
      -buttonList {"Do not reverse" Reverse } \
      -valueList {1 -1} \
      -orientation horizontal 
    $w1a.chromRb.frame.button1 invoke
}


set dispChrom(dx0r) 0
set dispChrom(dy0r) 0
set dispChrom(dx0s) 0
set dispChrom(dy0s) 0
set dispChrom(dx1r) 1
set dispChrom(dy1r) 1
set dispChrom(dx1s) 0
set dispChrom(dy1s) 0
set dispChrom(xfit) 1
set dispChrom(yfit) 1

#----------------------------------------------------------------------
#
proc menuPlotting {} {
    global dispChrom dispOrder chromOrder
    global widgetPlottingButton

    #APSEnableButton $widgetPlottingButton.plotDispersion.button
   
    set plotting [APSUniqueName .]
    if $dispOrder==1 {
        set dispChrom(dx1r) 0
        set dispChrom(dy1r) 0
        set dispChrom(dx1s) 0
        set dispCrhom(dy1s) 0
    } elseif {$dispOrder==2} {
	set dispChrom(dx0r) 0
        set dispChrom(dy0r) 0
        set dispChrom(dx0s) 0
        set dispChrom(dy0s) 0
    }
    APSDialogBox $plotting -name Plotting -okCommand doPlotting -cancelCommand ""
    
    APSCheckButtonFrame .d0r -parent ${plotting}.userFrame \
	-label "Dispersion1 over total ring:    " \
	-variableList {dispChrom(dx0r) dispChrom(dy0r)} \
	-buttonList {X Y} \
	-orientation horizontal 
    
    APSCheckButtonFrame .dos -parent $plotting.userFrame \
	-label "Dispersion1 by sectors: " \
	-variableList {dispChrom(dx0s) dispChrom(dy0s)} \
	-buttonList {X Y} \
	-orientation horizontal

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

    APSCheckButtonFrame .fit -parent $plotting.userFrame \
	-label "Raw data with fit:          " \
	-variableList {dispChrom(xfit) dispChrom(yfit)} \
	-buttonList {X Y} \
	-orientation horizontal

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

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

}

proc allButtonOnOff {w args} {
    set on 1
    APSParseArguments {on}
    global dispChrom

    set varList {dx0r dy0r dx0s dy0s dx1r dy1r dx1s dy1s xfit yfit}
    foreach var $varList {
	set dispChrom($var) $on
    }
}

proc makeButtonRow {widget args} {

    global dispOrder chromOrder
    global widgetPlottingButton
    
    set parent .userFrame
    set dispOrder 2
    set chromOrder 2

    APSParseArguments {parent}

    APSFrameGrid $widget -parent $parent -relief flat -xList "one two three"
    set w $parent$widget
    set widgetPlottingButton $w

   
    APSButton .doExperiment -parent $w.one -text "DO\nEXPERIMENT" \
      -command doExperiment \
      -packOption "-side left" 
     
    APSButton .chromProcessing -parent $w.two -text "COMPUTE\nCHROMATICITY" \
      -command chromProcessing \
      -packOption "-side left"

    APSRadioButtonFrame .orderChrom -parent $w.two -label "" -packOption "-side left" \
                         -variable chromOrder -buttonList {"order 1" "order 2"} \
                         -valueList {1 2} -orientation vertical \
                         -contextHelp "Choose the order for the chromaticity fitting."

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

    APSRadioButtonFrame .orderDispersion -parent $w.three -label "" -packOption "-side left" -variable dispOrder \
        -buttonList {"order 1" "order 2"} -valueList {1 2} \
        -orientation vertical -contextHelp "Choose the order for dispersion analysis."
    
    APSButton .plotDispersion -parent $w.three -text "PLOT 2nd ORDER\nDISPERSION"  \
        -command menuPlotting \
        -contextHelp "Plotting of the first/second dispersion functions over x,y and fitting figures" 

}

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

    global dispOrder dispChrom

    set output $dispChrom(output)
    set outputDir $dispChrom(outputDir)
    
    if {$dispOrder == 2} {
       calcDispersion2
    } else {
       calcDispersion1
    }   
}

#----------------------------------------------------------------------
# Procedure measures and sets the initial tune values:  
# returns 1 when completed; returns 0 if the VSA is not selectedfre
#
proc MeasureInitialTunes {args} {
    
    global dispChrom
    set tmpRoot /tmp/[APSTmpString]
    if [catch {exec getxytunesDimtel -root $tmpRoot -description "initial tunes" \
		    -verbose 0 -plot 0 -setup 1} result] {
	return -code error "Error measuring x/y tunes: $result"
    }
    puts $tmpRoot
    set dispChrom(xTune) [format %.4f [lindex [exec sdds2stream -par=xTune $tmpRoot.sdds] 0]]
    set dispChrom(yTune) [format %.4f [lindex [exec sdds2stream -par=yTune $tmpRoot.sdds] 0]]
    set dispChrom(xFreq) [ComputeFrequencyFromTune -tune $dispChrom(xTune)]
    set dispChrom(yFreq) [ComputeFrequencyFromTune -tune $dispChrom(yTune)]
    update
    SetStatus "done."
    return
}

# Procedure computes the tune from the specified tune frequency and returns the tune.
proc UpdateDividingLine {args} {
    global xTune yTune dividingLine
    set dividingLine [format %0.2f [expr ($xTune+$yTune)/2.0]]
}

proc ComputeTuneFromFrequency {args} {
    
    set tuneFreq ""
    APSStrictParseArguments {tuneFreq}
    
    set rfFrequency [exec cavget -list=A014-IETS:BTC:SRSetFreqM -floatFormat=%.1f -pendIoTime=25]
    set revFrequency [expr $rfFrequency / 1296.0]
    set tune [expr int($tuneFreq / $revFrequency) + 1.0 - ($tuneFreq / $revFrequency)]
    return [format %.5f $tune]
}

proc ComputeFrequencyFromTune {args} {
    global dispChrom
    set tune 0
    APSStrictParseArguments {tune}
    
    set rfFrequency [exec cavget -list=A014-IETS:BTC:SRSetFreqM -floatFormat=%.1f -pendIoTime=25]
    set revFrequency [expr $rfFrequency / 1296.0]
    set tuneFrequency [expr $revFrequency * ($dispChrom(measHarmonic) + $tune * $dispChrom(sideband))]
    return [format %.1f $tuneFrequency]
}

proc doExperiment {} {
    global dispChrom review cancel dimtel

    set cancel 0
    checkIfFilesExist
    if $cancel {return}
   
    foreach name $dispChrom(varList) {
	set $name $dispChrom($name)
    }
    
    set xFreq [expr $xFreq + $sideband * $start * $xchrom / $momentumCompactionFactor / 1296.0]
    set yFreq [expr $yFreq + $sideband * $start * $ychrom / $momentumCompactionFactor / 1296.0]

    set deltaFreq [expr ($stop - $start)/($points - 1.0)]
    
    if !$review {
        cd $outputDir

        set xFreq [ComputeFrequencyFromTune -tune $xTune]
        set yFreq [ComputeFrequencyFromTune -tune $yTune]

        SetStatus "Acquiring data..." 
	#setup dimtel
	# build the exp file from *Template.exp and the mon file using extraPV file, if one is given.
        set expFile /tmp/[APSTmpString].exp
        set monFile /tmp/[APSTmpString].mon
        APSAddToTempFileList $expFile $monFile


        # three possibilities
        # getDispersion=1 getChrom=1
        # use dispersion.mon and incorporate extraMonFile
        # getDispersion=0 getChrom=1
        # use extraMonFile only
        # getDispersion=1 getChrom=0
        # use dispersion.mon and incorporate extraMonFile
        
	if [catch {exec sddsprocess $mainDir/inputFiles/dispersion.mon $monFile \
		       -match=column,ControlName=S:VID?:*,!} result] {
	    return -code error "$result"
	}
        
        if [string length $extraMonFile] {
            SetStatus "Incorporating $extraMonFile into $monFile ..."
            # removal of duplicated PV names and column names 
            set extraExpFile /tmp/[APSTmpString].exp
            set extraMonFile1 /tmp/[APSTmpString].mon
            APSAddToTempFileList $extraExpFile $extraMonFile1
            if [catch {exec sddsselect $extraMonFile $monFile \
                         -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  $monFile $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 ""
        }
        
        # three possibilities
        # getDispersion=1 getChrom=1
        # use dispersion.mon and incorporate extraMonFile
        # getDispersion=0 getChrom=1
        # use extraMonFile only
        # getDispersion=1 getChrom=0
        # use dispersion.mon and incorporate extraMonFile
        if {$getChromatic && $getDispersion } {
            set template SchromDispersionTemplateDimtel.exp
            
            exec replaceText $mainDir/inputFiles/$template $expFile \
                -orig=<limit1>,<limit2>,<points>,<measToAve>,<monFile>,<mainFile>,<xFreq>,<yFreq>,<pause>,<dimtelAverage>,<xDriveFreq>,<yDriveFreq>,<xDriveFreqSpan>,<yDriveFreqSpan>,<xDrivePeriod>,<yDrivePeriod>,<xDriveAmplitude>,<yDriveAmplitude>,<xMarkerLow>,<yMarkerLow>,<xMarkerHigh>,<yMarkerHigh>,<dimtelPause>,<sideband>,<deltaFreq>,<alpha_c>,<measHarmonic> \
                -repl=$start,$stop,$points,$measToAve,$monFile,$output,$xFreq,$yFreq,$pause,$dimtel(average),$dimtel(xDriveFreq),$dimtel(yDriveFreq),$dimtel(xDriveFreqSpan),$dimtel(yDriveFreqSpan),$dimtel(xDrivePeriod),$dimtel(yDrivePeriod),$dimtel(xDriveAmplitude),$dimtel(yDriveAmplitude),$dimtel(xMarkerLow),$dimtel(yMarkerLow),$dimtel(xMarkerHigh),$dimtel(yMarkerHigh),$dimtel(pause),$dispChrom(sideband),$deltaFreq,$dispChrom(momentumCompactionFactor),$dispChrom(measHarmonic)
            
        } elseif {!$getChromatic && $getDispersion } {
            # if not getting tunes, then get only the dispersion from 
            set template SdispersionTemplate.exp

            exec replaceText $mainDir/inputFiles/$template $expFile \
                -orig=<limit1>,<limit2>,<points>,<measToAve>,<monFile>,<pause> \
                -repl=$start,$stop,$points,$measToAve,$monFile,$pause
            
        } elseif {$getChromatic && !$getDispersion } {
            # getting tunes only.
            set template SchromTemplateDimtel.exp
            exec replaceText $mainDir/inputFiles/$template $expFile \
                -orig=<limit1>,<limit2>,<points>,<measToAve>,<monFile>,<mainFile>,<xFreq>,<yFreq>,<pause>,<dimtelAverage>,<xDriveFreq>,<yDriveFreq>,<xDriveFreqSpan>,<yDriveFreqSpan>,<xDrivePeriod>,<yDrivePeriod>,<xDriveAmplitude>,<yDriveAmplitude>,<xMarkerLow>,<yMarkerLow>,<xMarkerHigh>,<yMarkerHigh>,<dimtelPause>,<sideband>,<deltaFreq>,<alpha_c>,<measHarmonic> \
                -repl=$start,$stop,$points,$measToAve,$monFile,$output,$xFreq,$yFreq,$pause,$dimtel(average),$dimtel(xDriveFreq),$dimtel(yDriveFreq),$dimtel(xDriveFreqSpan),$dimtel(yDriveFreqSpan),$dimtel(xDrivePeriod),$dimtel(yDrivePeriod),$dimtel(xDriveAmplitude),$dimtel(yDriveAmplitude),$dimtel(xMarkerLow),$dimtel(yMarkerLow),$dimtel(xMarkerHigh),$dimtel(yMarkerHigh),$dimtel(pause),$dispChrom(sideband),$deltaFreq,$dispChrom(momentumCompactionFactor),$dispChrom(measHarmonic)
            
        } else {
            SetStatus "No data is requested: getChromatic $getChromatic and getDispersion $getDispersion"
            return
        }

        if [string length $extraExpFile] {
            exec cat $extraExpFile $expFile > $expFile.1
            file rename -force $expFile.1 $expFile
        }

        # do experiment
        global apsSRDispChromExpDone
        set apsSRDispChromExpDone 0
        set rcList {S:RC:OrbitControlLawXC S:RC:OrbitControlLawYC S:rfFreqControlLawRC S:SlowOrbitControlLawXRC S:SlowOrbitControlLawYRC}
        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
	}
	#have to abort MOFB runcontrol because suspend does not work for it
	if [catch {exec cavput -list=S:RC:OrbitControlLaw -list=X,Y -list=C.ABRT=1 -pend=5} result] {
	    SetStatus "Problem aborting MOFB controllaw: $result"
	    return
	}
        set statusDir /home/helios/oagData/sr/BPMStatus
        
        #modify RTFB regulator, set the filter to higher high-pass 
	#removed RTFB part. Future FOFB change of gain, or suspension etc, would be placed here.
        # record present rf frequency for saving in data file
        SetStatus "read rf frequency ..."
        set dispChrom(rfFrequency0) [exec cavget -list=A014-IETS:BTC:SRSetFreqM -float=%13.10g]
        set dispChrom(drfFrequency0) [exec cavget -list=A014-IETS:BTC:SROffsetFreqC -floatFormat=%.1f -pendIoTime=5]
	
        SetStatus "Launching exec log ..."
        APSExecLog .expExec -name "Experiment log" \
          -cancelCallback "APSSRCleanUpDispChrom -datafile $output" \
          -abortCallback "APSSRCleanUpDispChrom -datafile $output" \
          -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  -pipe=out \
                       "-redefine=parameter,sddsexperimentUsed,1,type=long" \
                       "-redefine=para,alpha,$momentumCompactionFactor" \
                       | sddssortcolumn -pipe=in $output.1 -bpmOrder 
            file delete ${output}~} result] {
            SetStatus "Problem post-processing file: $result"
        } else {
            exec mv $output.1 $output
        }
    }
}

set dispChrom(varList) {xFreq yFreq sideband start stop points xchrom ychrom xTune yTune extraMonFile \
			    momentumCompactionFactor output measToAve outputDir getChromatic getDispersion \
			    mainDir  momentumCompactionFactor2 pause\
			    rfFrequency0 latticeName chromProcMode dividingLine \
			    chromBadPointList dx0r dy0r dx0s dy0s dx1r dy1r dx1s dy1s xfit yfit}

# Procedure is called after sddsexperiment and at the start of processing and re-processing
proc APSSRCleanUpDispChrom {args} {
    global dispChrom
    foreach var $dispChrom(varList) {
	set $var $dispChrom($var)
    }
    
    set datafile ""
    APSStrictParseArguments {datafile}

    global apsSRDispChromExpDone
    set apsSRDispChromExpDone 1

    set parameterList [APSGetSDDSNames -class parameter -fileName $datafile]
    if {[lsearch -exact $parameterList rfFrequency0] != -1} return

    # This post-processing is supposed to be done only once, after sddsexperiment.
    SetStatus "Postprocessing $datafile"
    if [catch {exec sddsprocess $datafile -nowarning \
                   -print=para,Lattice,$latticeName \
                   "-redefine=param,drfFrequency0,$dispChrom(drfFrequency0)" \
                   "-redefine=param,rfFrequency0,$dispChrom(rfFrequency0)" \
                    = rfFrequency is actually the delta frequency = \
                   "-redefine=column,delta,rfFrequency drfFrequency0 - rfFrequency0 / $momentumCompactionFactor / chs  sto deltaFirstOrder = sqr $momentumCompactionFactor2 * $momentumCompactionFactor / -" } result] {
        SetStatus "$result"
    }
}

set review 0
proc chromProcessing {} {
    global dispChrom chromOrder review
    foreach var $dispChrom(varList) {
	set $var $dispChrom($var)
    }
    
    set oldDir [pwd]
    cd $outputDir
    set root [file rootname $output]
    SetStatus "Performing chromatic processing for $output in [pwd]."
    APSSRCleanUpDispChrom -datafile $output

    if [catch {exec sddsquery $output -parameter} parameterList] {
        cd $oldDir
        SetStatus "$parameterList"
        return
    }
    
    set foundAlphaFromFile 0
    if [lsearch -exact $parameterList alpha]!=-1 {
        set foundAlphaFromFile 1
        if [catch {exec sdds2stream -parameter=alpha $output} alphaFromFile] {
            cd $oldDir
            SetStatus "$alphaFromFile"
            return
        }
    }
    # compare alpha_c from file with alpha_c from tcl entry box
    if {$foundAlphaFromFile} {
        if {[expr abs($alphaFromFile - $momentumCompactionFactor) < \
             1e-4 *$momentumCompactionFactor] } {
            # agreement between entry box and file
        } else {
            # ask for change in momentumCompactionFactor value in box
            if [APSYesNoPopUp  "Detected a different value of momentum compaction factor in the data file. Do you want the value in the file ($alphaFromFile) to overwrite the value in the box ($momentumCompactionFactor)?"] {
                set momentumCompactionFactor $alphaFromFile
            }
        }
    }
    

    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]
    }
    
    set tuneFileList0 [lsort [glob -nocomplain ${root}Tunes-\[0-9\]\[0-9\]\[0-9\]]]
    set parameters [exec sddsquery -par [lindex $tuneFileList0 0]]
    
    if !$review {
        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 -
            DIMTEL -
            lorentzian -
            integrate {
                set fitColumnRoot Tune    
            }
            convolve {
                set fitColumnRoot TuneChange
            }
        }
       
	switch $chromProcMode {
            peakfind {
		if [catch {eval exec sddscombine $tuneFileList ${root}traces.sdds -overwrite } result] {
		    SetStatus $result
		    cd $oldDir
		    return
                }
                set nsg [expr int($dispChrom(npSmooth)/2+0.5)]
		if [catch {exec sddssmooth ${root}traces.sdds -pipe=out -column=?SBspectrum -savit=$nsg,$nsg,3 -passes=$dispChrom(nPasses) \
                             | sddsprocess -pipe \
                             -process=xSBspectrum,max,xTunePeakLocation,functionOf=xTune,lower=0.025,position \
                             -process=ySBspectrum,max,yTunePeakLocation,functionOf=yTune,lower=0.025,position \
                             -process=xSBspectrum,max,xTunePeakValue,functionOf=xTune,lower=0.025 \
                             -process=ySBspectrum,max,yTunePeakValue,functionOf=yTune,lower=0.025 \
                             | tee ${root}smtraces.sdds \
                             | sddscollapse -pipe \
                             | sddsxref -pipe ${root}  -take=rfFrequency,S-DCCT:CurrentM -trans=par,*rf* \
                             | sddsprocess -pipe=in ${root}tune.sdds \
                             -process=S-DCCT:CurrentM,min,CurrentMin \
                             -process=S-DCCT:CurrentM,max,CurrentMax \
                             "-print=parameter,CurrentLabel,Current:\[%.2f\\, %.2f\] mA,CurrentMin,CurrentMax" \
                             -define=param,alpha,$momentumCompactionFactor \
                             -define=param,alpha2,$momentumCompactionFactor2 \
                             = rfFrequency is actually the delta frequency = \
                             "-define=col,delta,rfFrequency drfFrequency0 - rfFrequency0 / alpha / chs sto deltaFirstOrder = sqr alpha2 * alpha / -,symbol=\$gd\$r" \
                         } result] {
		    cd $oldDir
		    SetStatus "Error (peakfind): $result"
		    return
                }
                set fitColumnRoot TunePeakLocation
                set xPeakName xTunePeakValue
                set yPeakName yTunePeakValue
            }
	    DIMTEL {
		if [catch {eval exec sddscombine $tuneFileList ${root}traces.sdds -overwrite} result] {
		    SetStatus $result
		    cd $oldDir
		    return
		}
		if [catch {exec sddscollapse ${root}traces.sdds -pipe=out \
			       | sddsxref -pipe ${root}  -take=rfFrequency -trans=par,*rf* \
			       | sddsprocess -pipe=in ${root}tune.sdds \
			       -define=param,alpha,$momentumCompactionFactor \
			       -define=param,alpha2,$momentumCompactionFactor2 \
                               = rfFrequency is actually the delta frequency = \
                               "-define=col,delta,rfFrequency drfFrequency0 - rfFrequency0 / alpha / chs sto deltaFirstOrder = sqr alpha2 * alpha / -,symbol=\$gd\$r" \
			   } result] {
		    cd $oldDir
		    SetStatus "Error (peakfind): $result"
		    return
		}
		set fitColumnRoot Tune
	    } 
	    convolve {
		set referenceFile [lindex $tuneFileList [expr int($tuneFiles/2)]]
		SetStatus "Reference tune file: $referenceFile"
                set tmpRoot ${root}tune-tmp
		#APSAddToTempFileList $tmpRoot.traces $tmpRoot.params $tmpRoot.ref
                set refFiles  [APSReplicateItem -item $referenceFile -number $tuneFiles]
                foreach plane {x y} Plane {X Y} {
                    if [catch {exec sddsprocess $referenceFile -pipe=out \
                                 "-test=column,${plane}Frequency ${Plane}planeDrive0Freq - abs ${Plane}planeDrive0FreqSpan 2 / > !" \
                                 -process=${plane}Frequency,first,%s0 -process=${plane}Frequency,last,%s1 \
                                 | sdds2stream -pipe -parameter=${plane}Frequency0,${plane}Frequency1} result] {
                        cd $oldDir
                        return -code error "Convolve error (0) for $plane: $result"
                    }
                    if [catch {eval exec sddscombine $tuneFileList -pipe=out \
                                 | sddsprocess -pipe -filter=col,${plane}Frequency,$freqMin,$freqMax -clip=15,15 \
                                 "-process=${plane}SBspectrum,min,%sMin" \
                                 "-process=${plane}SBspectrum,spread,%sSpread" \
                                 {"-define=column,%sNorm,%s %sMin - %sSpread /,select=${plane}SBspectrum"} \
                                 | sddssort -pipe=in -column=${plane}Tune,incr $tmpRoot.${plane}traces 
                        exec sddscollapse $tmpRoot.${plane}traces $tmpRoot.${plane}params
                        eval exec sddscombine $refFiles  -pipe=out \
                                 | sddsprocess -pipe -filter=col,${plane}Frequency,$freqMin,$freqMax -clip=15,15 \
                                 "-process=${plane}SBspectrum,min,%sMin" \
                                 "-process=${plane}SBspectrum,spread,%sSpread" \
                                 {"-define=column,%sNorm,%s %sMin - %sSpread /,select=${plane}SBspectrum"} \
                                 | sddssort -pipe=in -column=${plane}Tune,incr $tmpRoot.${plane}ref} result] {
                        cd $oldDir
                        return -code error "Convolve error (1) for $plane: $result"
                    }
		    if [catch { exec sddsconvolve -correlate \
                                  -signal=${plane}Tune,${plane}SBspectrumNorm $tmpRoot.${plane}traces \
                                  -response=${plane}Tune,${plane}SBspectrumNorm $tmpRoot.${plane}ref \
                                  -output=${plane}Tune,WW -pipe=out \
                                  | sddsconvert -pipe -delete=parameter,* \
                                  | tee $tmpRoot.${plane}conv \
                                  | sddsprocess -pipe \
                                  -process=WW,max,${plane}TuneChange,function=${plane}Tune,position \
                                  | sddscollapse -pipe=in $tmpRoot.$plane } result] {
			SetStatus "Convolve error (2) for $plane: $result"
			cd $oldDir
			return
		    }
		}
		if [catch {exec sddsxref $tmpRoot.x $tmpRoot.y -pipe=out \
                             | sddsxref -pipe $tmpRoot.xparams $tmpRoot.yparams -nowarning \
                             | sddsxref -pipe $root -take=rfFrequency,S-DCCT:CurrentM -transfer=par,*rf* \
                             | sddsprocess -pipe=in ${root}tune.sdds \
                             -process=S-DCCT:CurrentM,min,CurrentMin \
                             -process=S-DCCT:CurrentM,max,CurrentMax \
                             -define=param,alpha,$momentumCompactionFactor \
                             -define=param,alpha2,$momentumCompactionFactor2 \
                             "-print=parameter,CurrentLabel,Current:\[%.2f\\, %.2f\] mA,CurrentMin,CurrentMax" \
                             = rfFrequency is actually the delta frequency = \
                             "-define=col,delta,rfFrequency drfFrequency0 - rfFrequency0 / alpha / chs sto deltaFirstOrder = sqr alpha2 * alpha / -,symbol=\$gd\$r" \
                         } result] {
		    cd $oldDir 
		    SetStatus "convolve error3: $result"
		    return
		}
		eval file delete [glob -nocomplain $tmpRoot.*]
		set fitColumnRoot TuneChange
	    }
	    lorentzian {
                set tmpRoot ${root}tune-tmp
		if [catch {eval exec sddscombine $tuneFileList ${root}traces.sdds -overwrite
                    exec sddscollapse ${root}traces.sdds $tmpRoot.params} result] {
		    SetStatus $result
		    cd $oldDir
		    return
		}
                foreach plane {x y} Plane {X Y} {
                    if [catch {exec sddsprocess ${root}traces.sdds -pipe=out \
                                 "-test=column,${plane}Frequency ${Plane}planeDrive0Freq - abs ${Plane}planeDrive0FreqSpan 2 / > !" \
                                 -clip=15,15 \
				 | tee $root.$plane.0 \
                                 | sddsconvert -pipe -delete=parameter,* \
                                 | sddssmooth -pipe -despike -columns=${plane}SBspectrum \
                                 | sddslorentzianfit -pipe -column=${plane}Tune,${plane}SBspectrum \
                                 | sddsconvert -pipe -edit=parameter,lorentzianfit*,%/lorentzianfit/${plane}/a%/Center/Tune/ \
                                 | sddsprocess -pipe=in ${root}.${plane}lfit \
                                 "-define=parameter,${plane}TunePeakValue,${plane}Baseline ${plane}Height +" } result] {
                        cd $oldDir
                        return -code error "Lorentzian fit error (1) for $plane: $result"
                    }
		}
		if [catch {exec sddsxref ${root}.xlfit ${root}.ylfit -take=* -transfer=param,* -pipe=out -nowarn \
                             | sddscollapse -pipe \
                             | sddsxref -pipe $tmpRoot.params -nowarning \
                             | sddsxref -pipe $root -take=rfFrequency,S-DCCT:CurrentM -transfer=par,*rf* \
                             | sddsprocess -pipe=in ${root}tune.sdds \
                             -filter=col,xTune,0.05,0.45 -filter=col,yTune,0.05,0.45 \
                             -process=S-DCCT:CurrentM,min,CurrentMin \
                             -process=S-DCCT:CurrentM,max,CurrentMax \
                             -define=param,alpha,$momentumCompactionFactor \
                             -define=param,alpha2,$momentumCompactionFactor2 \
                             "-print=parameter,CurrentLabel,Current:\[%.2f\\, %.2f\] mA,CurrentMin,CurrentMax" \
                             = rfFrequency is actually the delta frequency = \
                             "-define=col,delta,rfFrequency drfFrequency0 - rfFrequency0 / alpha / chs sto deltaFirstOrder = sqr alpha2 * alpha / -,symbol=\$gd\$r" \
			   } result] {
		    cd $oldDir 
		    SetStatus "Lorentzian fit error (2): $result"
		    return
		}
		eval file delete [glob -nocomplain $tmpRoot.*]
	    }
        }
        
        if {$chromOrder == 1} {set terms 2} else {set terms 3}
        foreach plane {x y} {
            if [catch {exec sddspfit ${root}tune.sdds -pipe=out -col=delta,${plane}${fitColumnRoot} -terms=$terms \
                         | sddsoutlier -pipe -column=${plane}${fitColumnRoot}Residual -stDevLimit=2 \
                         | sddspfit -pipe -col=delta,${plane}${fitColumnRoot} -terms=$terms -generate \
                         | sddsxref ${root}tune.sdds -equate=delta -pipe -take=* -nowarning \
                         | sddsconvert -pipe -rename=param,Slope=${plane}Chromaticity,SlopeSigma=${plane}ChromaticitySigma \
                         -rename=param,Curvature=${plane}Curvature,CurvatureSigma=${plane}CurvatureSigma -nowarning  \
                         | sddsprocess -pipe=in ${root}${plane}Tune.fit \
                         "-redefine=parameter,${plane}Chrom2,Terms 2 > ? ${plane}Curvature 2 * : 0 $ " \
                         "-redefine=parameter,${plane}Chrom2Sigma,Terms 2 > ? ${plane}CurvatureSigma 2 * : 0 $ " \
                         "-redefine=parameter,FitPoints,n_rows,type=long" \
                         "-reprint=param,${plane}FitLabel,${plane}: RMS Residual=%.2g N=%ld,RmsResidual,FitPoints" \
                         "-reprint=param,${plane}ChromLabel,\$gx\$r\$b${plane}\$n=%.2f\$sa\$e%.2f (%.0f\$sa\$e%.0f),${plane}Chromaticity,${plane}ChromaticitySigma,${plane}Chrom2,${plane}Chrom2Sigma" \
                     } result] {
                if {$tuneFiles==2} {
                    SetStatus "ignore sddspfit error for 2 data points."
                } else {
                    SetStatus "sddspfit error: $result"
                    cd $oldDir
                    return
                }
            }
            
            if {$tuneFiles<=2} {
                if [catch {exec sddsprocess ${root}${plane}Tune.fit \
                             -redefine=par,${plane}ChromaticitySigma,0 \
                             "-reprint=param,${plane}FitLabel,${plane}: RMS Residual=%.2g N=%ld,RmsResidual,FitPoints" \
                             "-reprint=param,${plane}ChromLabel,\$gx\$r\$b${plane}\$n = %.2f,${plane}Chromaticity" -nowarnings} result] {
                    SetStatus "Error redefine fit error for 2 points data: $result"
                    cd $oldDir
                    return
                }
                
            }
        }

        if {[catch {exec sddsxref -nowarning ${root}tune.sdds -pipe=out ${root}yTune.fit -leave=* \
                      -transfer=param,yChrom*,yCurvature*,yFitLabel,*Current* \
                      | sddsxref -pipe -nowarning ${root}xTune.fit -leave=* -transfer=param,xChrom*,yCurvature*,xFitLabel \
                      | sddsprocess -pipe=in ${root}tune.sdds1  \
                      "-reprint=param,FitLabel,%s  %s,xFitLabel,yFitLabel" \
                      "-reprint=param,ChromLabel,%s  %s,xChromLabel,yChromLabel" 
            exec mv ${root}tune.sdds1 ${root}tune.sdds } result]}  {
            SetStatus "Error combining tune data: $result"
            cd $oldDir
            return
        }
        
        catch {rm ${root}*~}
    }
    catch {file delete ${root}tune.eps  ${root}tune.png}
    if [catch {exec sddsplot3 ${root}tune \
		   -col=delta,?$fitColumnRoot -graph=sym,vary=subtype,scale=2 \
		   -legend=scale=2 ${root}tune.sdds \
		   -title=@FitLabel -topline=@ChromLabel \
                   -string=$root,p=0.05,q=0.975,justify=lt,scale=1.25 \
                   -string=@CurrentLabel,p=0.05,q=0.925,justify=lt,scale=1.25 \
		   -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
    }

    switch $chromProcMode {
        peakfind {
            set tmpRoot /tmp/[APSTmpString]
            exec sddsexpand ${root}tune.sdds $tmpRoot.pf1
            exec sddsxref ${root}traces.sdds $tmpRoot.pf1 -leave=* -transfer=param,* -nowarning
            file delete $tmpRoot.pf1
            exec sddsplot -groupby=page -split=page -sep=page -limit=xmin=0.025 "-ylabel=Amplitude" -xlabel=Tune \
              "-title=Smoothed tune spectra for $root" \
                 -col=xTune,xSBspectrum ${root}smtraces.sdds  -param=xTunePeakLocation,xTunePeakValue ${root}traces.sdds  -graph=sym,scale=2,fill,subtype=1 \
                 -col=yTune,ySBspectrum ${root}smtraces.sdds  -graph=line,type=5 -param=yTunePeakLocation,yTunePeakValue ${root}traces.sdds  -graph=sym,scale=2,fill,subtype=6 &
        }
        DIMTEL {
            if [catch {exec sddsplot -split=page -separate=page -groupby=page -same \
                         "-ylabel=Waveform" "-xlabel=Tune" \
                         -legend=yname,edit=%/Waveform// -graph=line,vary \
                         -column=xTune,xSBspectrum ${root}traces.sdds \
                         -column=xTune,xSBphase ${root}traces.sdds \
                         -column=yTune,ySBspectrum ${root}traces.sdds \
                         -column=yTune,ySBphase ${root}traces.sdds \
                         -parameter=xTune,XplaneSBPeak -graph=sym,scale=3,subtype=0 \
                         ${root}traces.sdds -legend=spec= \
                         -parameter=yTune,YplaneSBPeak -graph=sym,scale=3,subtype=5 \
                         ${root}traces.sdds -legend=spec= & } result] {
                cd $oldDir
                SetStatus $result
                return
            }
        }
        lorentzian {
            exec sddsplot -groupby=page -split=page -sep=page -limit=xmin=0.025 "-ylabel=Amplitude" -xlabel=Tune \
              "-title=Tune spectra and fits for $root" \
              -col=xTune,xSBspectrum ${root}traces.sdds -graph=line,type=0 -legend=spec=xData \
              -param=xTune,xTunePeakValue ${root}.xlfit  -graph=sym,scale=2,fill,subtype=1 \
              -column=xTune,xSBspectrumFit ${root}.xlfit -graph=line,type=1 -legend=spec=xFit \
              -col=yTune,ySBspectrum ${root}traces.sdds -graph=line,type=2 -legend=spec=yData \
              -param=yTune,yTunePeakValue ${root}.ylfit  -graph=sym,scale=2,fill,subtype=3 \
              -column=yTune,ySBspectrumFit ${root}.ylfit -graph=line,type=3 -legend=spec=yFit &
        }
    }
    cd $oldDir
    APSDeleteTempFiles
    SetStatus Done.
}

#-----------------------------------------------------------------------------
#
proc calcDispersion1 {} {
    global dispChrom OAGGlobal
    foreach var $dispChrom(varList) {
	set $var $dispChrom($var)
    }
    
    #-----------------------------------------------------------------------------
    #
    set oldDir [pwd]
    SetStatus "Calculating the first order dispersion for $output."
    cd $outputDir
    APSSRCleanUpDispChrom -datafile $output
    #    
    #-----------------------------------------------------------------------------
    if [catch {exec sddsquery $output -parameter} parameterList] {
        cd $oldDir
        SetStatus "$parameterList"
        return
    }
    
    set foundAlphaFromFile 0
    if [lsearch -exact $parameterList alpha]!=-1 {
        set foundAlphaFromFile 1
        if [catch {exec sdds2stream -parameter=alpha $output} alphaFromFile] {
            cd $oldDir
            SetStatus "calcDispersion1 (Error1): $alphaFromFile"
            return
        }
    }
    # compare alpha_c from file with alpha_c from tcl entry box
    if {$foundAlphaFromFile} {
        if {[expr abs($alphaFromFile - $momentumCompactionFactor) < \
             1e-4 *$momentumCompactionFactor] } {
            # agreement between entry box and file
        } else {
            # ask for change in momentumCompactionFactor value in box
            if [APSYesNoPopUp  "Detected a different value of momentum compaction factor in the data file. Do you want the value in the file ($alphaFromFile) to overwrite the value in the box ($momentumCompactionFactor)?"] {
                set momentumCompactionFactor $alphaFromFile
            }
        }
    }


    set firstCommand "cat $output"
    if [lsearch [APSGetSDDSNames -fileName $output -class parameter] sddsexperimentUsed]!=-1 {
        if [catch {APSGetSDDSParameter -fileName $output \
                     -parameter sddsexperimentUsed} result] {
            cd $oldDir
            SetStatus "calcDispersion1 (Error2): Problem getting value of sddsexperimentUsed \
                       parameter: $result"
            return
        }
        set sddsexperimentUsed [lindex $result 0]
        if $sddsexperimentUsed {
            set firstCommand "sddscollect $output -pipe=out \
                              -collect=suffix=:x:LowPass1sAdjustedM \
                              -collect=suffix=:y:LowPass1sAdjustedM "
        }
    } else {
        set sddsExperimentUsed 0
    }
    
    # take slopes. rfFrequency0 previously determined in real-time is not
    # available as a global variable, so we have to get it from the saved
    # data, which is probably better
    set rfFrequency0 [lindex [exec sdds2stream -para=rfFrequency0 $output] 0 ]
    set drfFrequency0 [lindex [exec sdds2stream -para=drfFrequency0 $output] 0 ]
    set centerFrequency [expr $rfFrequency0+$drfFrequency0]
    if [catch {eval exec $firstCommand \
                 | sddsprocess -pipe -reprint=param,ActuatorName,rfFrequency \
                 = rfFrequency is actually the delta frequency = \
                 "{-def=para,rfFrequencyDelta,rfFrequency $drfFrequency0 -,units=Hz}" \
                 -nowarning \
                 | sddsvslopes -pipe -indep=rfFrequencyDelta -sigma \
                 | sddsxref    -pipe -match=Rootname=BPMName -noWarning \
                 $OAGGlobal(SRLatticesDirectory)/scripts/SRBPMPosition.xref \
                 -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 \
                 -reprint=param,ActuatorName,rfFrequency \
                 -redefine=param,alpha,$momentumCompactionFactor \
                 -redefine=param,centerFrequency,$centerFrequency,units=Hz \
                 = the data is acquired in microns = \
                 {"-redefine=col,xDispersion,:x:LowPass1sAdjustedMSlope \
              alpha * centerFrequency * chs 1e3 /,symbol=\$gc\$r\$a(1)\$bx\$n,units=mm"} \
                 {"-redefine=col,yDispersion,:y:LowPass1sAdjustedMSlope \
              alpha * centerFrequency * chs 1e3 /,symbol=\$gc\$r\$a(1)\$by\$n,units=mm"} \
                 {"-redefine=col,xDispersionSigma,:x:LowPass1sAdjustedMSlopeSigma \
              alpha * centerFrequency * chs 1e3 /,symbol=\$gc\$r\$a(1)\$bx\$n,units=mm"} \
                 {"-redefine=col,yDispersionSigma,:y:LowPass1sAdjustedMSlopeSigma \
              alpha * centerFrequency * chs 1e3 /,symbol=\$gc\$r\$a(1)\$by\$n,units=mm"} \
             } result] {
        cd $oldDir
        SetStatus "calcDispersion1 (Error3): Problem taking slopes: $result"
        return
    }
    
    exec sddsplot $output.slopes -col=Index,?Dispersion \
      -graph=line,vary -uns=y -axes=x &
    
    #    exec sddsplot $output.slopes  \
        -uns=y -axes=x \
        -col=Index,xDispersion,xDispersionSigma -grap=errorbar,conn=0,sub=1 \
        -col=Index,yDispersion,yDispersionSigma -grap=errorbar,conn=0,sub=2 &
    
    exec sddsplot $output.slopes \
        -uns=y -axes=x \
        -split=column=s,width=55.2,start=0 \
        -sep=subpage -leg \
        -group=subpage -same=y \
        -col=Rootname,xDispersion,xDispersionSigma \
        -graph=errorbar,conn=1,sub=1 \
        -col=Rootname,yDispersion,yDispersionSigma \
        -graph=errorbar,conn=2,sub=2 &
    
#    exec sddsplot $output.slopes -col=Rootname,?Dispersion\
        -graph=errorbar,conn=sub,vary=sub \
        -uns=y -axes=x \
        -split=column=s,width=55.2,start=0 \
        -sep=subpage -leg \
        -group=subpage -same=y & 
    
   
   # menuPlotting
    global widgetPlottingButton 
    #APSEnableButton $widgetPlottingButton.plotDispersion.button
    
    SetStatus Done.
    cd $oldDir
}
    
#-----------------------------------------------------------------------------
#
proc calcDispersion2 {} {
    global dispChrom  OAGGlobal columnList rfFrequency0 drfFrequency0 centerFrequency
    foreach var $dispChrom(varList) {
	set $var $dispChrom($var)
    }
    
    SetStatus "Calculating the second order dispersion for $output."
    set oldDir [pwd]
    cd $outputDir
    APSSRCleanUpDispChrom -datafile $output
    
    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
    }
    if [lsearch $parameterList drfFrequency0]==-1 {
        cd $oldDir
        SetStatus "Problems with parameter drfFrequency0"
        return
    }
    if [lsearch $parameterList sddsexperimentUsed]==-1 {
        cd $oldDir
        SetStatus "Parameter sddsexperimentUsed is unknown"
        return
    } 

    set rfFrequency0 "[APSGetSDDSParameter -fileName $output -parameter rfFrequency0]"
    set drfFrequency0 "[APSGetSDDSParameter -fileName $output -parameter drfFrequency0]"
    set sddsexperimentUsed "[APSGetSDDSParameter -fileName $output -parameter sddsexperimentUsed]"

    SetStatus "rfFrequency0 = $rfFrequency0"
    SetStatus "drfFrequency0 = $drfFrequency0"
    set centerFrequency [expr $rfFrequency0+$drfFrequency0]

    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 :x:LowPass1sAdjustedM $columnName]==0} {
            lappend bpmListHelp $columnName
        } else {
            if {![regexp :y:LowPass1sAdjustedM $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"

    set xrefFile $OAGGlobal(SRLatticesDirectory)/scripts/SRBPMPosition.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 
    # :x:LowPass1sAdjustedM, :y:LowPass1sAdjustedM, :x:LowPass1sAdjustedMFit and :x:LowPass1sAdjustedMFit on rfFrequency for each BPM
    #
    SetStatus "Start of the dispersions calculations." 
   # SetStatus "Wait approximately 40 seconds, please..."
    set dispExpr0x "xSlope alpha * centerFrequency * chs 1e3 /"
    set dispExpr1x "xCurvature alpha * alpha * centerFrequency * centerFrequency * xDispersion1 alpha2 * alpha / - 1e3 /" 
    set dispExpr0y "ySlope alpha * centerFrequency * chs 1e3 /"
    set dispExpr1y "yCurvature alpha * alpha * centerFrequency * centerFrequency * yDispersion1 alpha2 * alpha / - 1e3 /" 
    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"
    # need three terms in order to get a parabola (2nd order dispersion)
    if [catch {eval exec sddsprocess $output -pipe=out \
                 "{-define=column,drfFrequency,rfFrequency drfFrequency0 -,units=Hz}" \
                 | sddsmpfit -pipe -indep=drfFrequency -depend=$bpmNames -terms=3 -copyParameters \
                 | sddsconvert -pipe=in $output.frame \
                 -retain=column,drfFrequency \
                 -retain=column,*x:LowPass1sAdjustedM \
                 -retain=column,*x:LowPass1sAdjustedMFit \
                 -retain=column,*y:LowPass1sAdjustedM \
                 -retain=column,*y:LowPass1sAdjustedMFit \
                 -retain=parameter,*x:LowPass1sAdjustedMCurvature \
                 -retain=parameter,*y:LowPass1sAdjustedMCurvature \
                 -retain=parameter,*x:LowPass1sAdjustedMSlope\
                 -retain=parameter,*y:LowPass1sAdjustedMSlope \
                 -delete=parameter,rfFrequency* \
                 -delete=parameter,Basis \
                 -delete=parameter,Terms \
                 -delete=parameter,*x:LowPass1sAdjustedMRmsResidual \
                 -delete=parameter,*x:LowPass1sAdjustedMFitIsValid \
                 -delete=parameter,*x:LowPass1sAdjustedMSddspfitlabel \
                 -delete=parameter,*x:LowPass1sAdjustedMIntercept \
                 -delete=parameter,*y:LowPass1sAdjustedMRmsResidual \
                 -delete=parameter,*y:LowPass1sAdjustedMFitIsValid \
                 -delete=parameter,*y:LowPass1sAdjustedMSddspfitlabel \
                 -delete=parameter,*y:LowPass1sAdjustedMIntercept \
             } 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=:x:LowPass1sAdjustedMCurvature \
                 -collect=suffix=:x:LowPass1sAdjustedMSlope \
                 -collect=suffix=:x:LowPass1sAdjustedMReducedChiSquared  \
                 -collect=suffix=:x:LowPass1sAdjustedMSignificanceLevel  \
                 -collect=suffix=:y:LowPass1sAdjustedMCurvature \
                 -collect=suffix=:y:LowPass1sAdjustedMSlope \
                 -collect=suffix=:y:LowPass1sAdjustedMReducedChiSquared  \
                 -collect=suffix=:y:LowPass1sAdjustedMSignificanceLevel  \
                 | sddsconvert -pipe \
                 -rename=column,:x:LowPass1sAdjustedMCurvature=xCurvature \
                 -rename=column,:x:LowPass1sAdjustedMSlope=xSlope \
                 -rename=column,:x:LowPass1sAdjustedMReducedChiSquared=xReducedChiSquared \
                 -rename=column,:x:LowPass1sAdjustedMSignificanceLevel=xSignificanceLevel \
                 -rename=column,:y:LowPass1sAdjustedMCurvature=yCurvature \
                 -rename=column,:y:LowPass1sAdjustedMSlope=ySlope \
                 -rename=column,:y:LowPass1sAdjustedMReducedChiSquared=yReducedChiSquared \
                 -rename=column,:y:LowPass1sAdjustedMSignificanceLevel=ySignificanceLevel \
                 | 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,alpha2,$momentumCompactionFactor2 \
                 -redefine=param,centerFrequency,$centerFrequency,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=xSignificanceLevel,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 .] -fileName $output.Xtable \
      -deleteOnClose 1 -width 140 
    #----------------------------------------------------------------------
    # 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=ySignificanceLevel,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 .] -fileName $output.Ytable \
      -deleteOnClose 1 -width 140 
    #menuPlotting  
    global widgetPlottingButton 
    #APSEnableButton $widgetPlottingButton.plotDispersion.button 
    cd $oldDir
}

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

    global columnList rfFrequency0 drfFrequency0 centerFrequency dispChrom
    global dx0r dy0r dx0s dy0s dx1r dy1r dx1s dy1s xfit yfit

    foreach name $dispChrom(varList) {
	set $name $dispChrom($name)
    }

    #----------------------------------------------------------------------
    # Plotting result data for first order dispersions
    #
    #----------------------------------------------------------------------
    #  X over total ring:
    #
    set oldDir [pwd]
    cd $outputDir
    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" 
       set plotList1 ""
       set plotList2 "" 
       foreach columnName $columnList {
           if {[string match *:x:LowPass1sAdjustedM $columnName]} { 
               lappend plotList1 $columnName
               lappend plotList2 ${columnName}Fit 
           }
       }
        
        eval exec sddsplot -ylabel=edit=%/:x:LowPass1sAdjustedM//%/:x:LowPass1sAdjustedM// \"-topline=Horizontal bpm vs. f\" \
            $columnsPlotted \
            -column=drfFrequency,([join $plotList1 ,]) -graph=symbol,scale=3,subtype=1 $output.frame \
            -column=drfFrequency,([join $plotList2 ,]) -graph=line $output.frame &
    }
    
    #----------------------------------------------------------------------
    # Plotting result data for Y-fitting
    #
    if {$yfit == 1} {
       set columnsPlotted "-layout=3,3 -group=nameindex -sep=nameindex"
       set plotList1 ""
       set plotList2 ""

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

       eval exec sddsplot -ylabel=edit=%/:y:LowPass1sAdjustedM//%/:y:LowPass1sAdjustedM// \"-topline=Vertical bpm vs. f\" \
           $columnsPlotted \
           -column=drfFrequency,([join $plotList1 ,]) -graph=symbol,scale=3,subtype=1 $output.frame \
           -column=drfFrequency,([join $plotList2 ,]) -graph=line $output.frame &
    }
    cd $oldDir
    SetStatus Done.

}
#-----------------------------------------------------------------------------

proc checkIfFilesExist {} {
    global dispChrom review cancel
    set outputDir $dispChrom(outputDir)
    set output $dispChrom(output)
    if ![file exists $outputDir] {
        return -code error "not found: $outputDir"
    }
    if ![file isdir $outputDir] {
        return -code error "not a directory: $outputDir"
    }
    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 dispChrom
    set oldDir [pwd]
    set outputDir $dispChrom(outputDir)
    set output $dispChrom(output)
    cd $outputDir
    SetStatus "Removing old experiment files..."
    eval file delete [glob -nocomplain $output*]
    cd $oldDir
    SetStatus "Done."
}

proc SetupHPVSAAndDrvStriplines {args} {
    set hpvsaSelection SR

    set plane x
    set statusCallback ""
    APSParseArguments {plane statusCallback}
    if {$statusCallback!=""} {
        $statusCallback "Setting up Driver striplines and $plane plane measurement..."
    }
    global  xFreq yFreq HPVSATracesToAve range
    switch $plane {
        x {
            set sourceLevel 9
        }
        y {
            set sourceLevel 6
        }
    }
    set output /tmp/[APSTmpString]
    set freq [set ${plane}Freq]
   # if [catch {exec hpVecRestore -unit sr -filename /home/helios/oagData/sr/hp89441A/states/MXA-TUNE.sta } result] {
   #     return -code error "Error in setup VSA for tune measurement: $result"
   # }
    if [catch {APSSetupSRVSAScope  -sourceLevel $sourceLevel -plane $plane -root $output \
                 -average $HPVSATracesToAve -freq $freq -range $range } streamID] {
        return -code error "APSGetSRTunesVSA1: $streamID"
    }
    #APSCloseTelnetStream -streamID $streamID
    if [catch {exec hpSocketSend hpvecsr "OUTP OFF"} result] {
	return -code error "Error in turning off VSA source: $result"
    }
    if {$statusCallback!=""} {
        $statusCallback "done."
    }
    return 1
}

if [catch {exec cavget -list=SR:bunchPatternSO -pend=30} bunchPattern] {
    return -code error "Error in reading SR:bunchPatternSO : $bunchPattern"
}

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