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

wm geometry . -0+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


APSApplication . -name CollectRFSpectrum  \
  -overview {Using MXA, collects HOM spectra and optionally beam spectrum. Some preset frequencies are available in a combobox. The data resides in /home/helios/oagData/sr/HOM/inputFiles/presetSettings.}

set status Working...
APSScrolledStatus .status -parent .userFrame -textVariable status \
        -width 60 -height 6
update


proc MakeCavitySelectionWidget {widget args} {
    set parent ""
    APSStrictParseArguments {parent}
    global Sector Cavity doAllCavities
    
    APSFrame ${widget} -parent $parent -relief flat
    set w $parent${widget}.frame
    APSFrameGrid .fg -parent $w -xList {x1 x2}
    set w1 $w.fg.x1
    set w2 $w.fg.x2
    global S36 S37 S40
    # almost always, we record all cavities.
    set S36 1
    set S37 1
    set S40 1
    APSCheckButtonFrame .sector -parent $w1 -label "Sector" \
      -buttonList {36 37 40} -variableList {S36 S37 S40} -allNone 1
    global Cavity1 Cavity2 Cavity3 Cavity4
    set Cavity1 1
    foreach item {2 3 4} {
        set Cavity$item 1
    }
    
    APSCheckButtonFrame .cavity -parent $w2 -label "Cavity" \
      -buttonList {1 2 3 4} -variableList {Cavity1 Cavity2 Cavity3 Cavity4} -allNone 1
    
}


set MXA 1
proc MakeSetupWidget {widget args} {
    set parent ""
    APSStrictParseArguments {parent}
    global MXA
    APSFrame $widget -parent $parent \
      -label "Instrument Setup Commands" -contextHelp \
      "Setup the instrument with these commands. Usually a setup command takes 20 seconds, which should be done only once at the beginning of a series of measurements."
    APSButton .hom -parent $parent$widget.frame -text "Setup MXA for HOM" -command \
      {SetupMXA -configuration HOM} -contextHelp \
      "Sets up the HP/Aligent/Keysight MXA for RF HOM measurements."
}

set takeBeamData 1
proc MakeSaveWidget {widget args} {
    set parent ""
    APSStrictParseArguments {parent}
    global  span harmonics range Description
    APSFrame $widget -parent $parent \
      -label "Save Data" -contextHelp \
      "Provides for saving the tune spectrum to a file."
    set parent $parent$widget.frame
    APSLabeledEntry .directory -parent $parent -label "Output Directory: " \
      -textVariable dataDirectory -width 60
    APSButton .daily -parent $parent.directory -packOption "-side right"  \
      -text "daily" -size small \
      -command {set dataDirectory [APSGoToDailyDirectory -subdirectory HOM];set archive 0}
    APSButton .archive -parent $parent.directory -packOption "-side right" \
      -text "archive" -size small \
      -command {set dataDirectory /home/helios/oagData/sr/HOM/data;set archive 1}
    APSLabeledEntry .rootname -parent $parent -label "Rootname: " \
      -textVariable dataRootname -width 60

    global presetLabelList presetChoice bunchPattern
    APSComboboxFrame .bunch -parent $parent -label "Bunch Pattern" \
        -packOption "-fill x" \
        -textVariable bunchPattern \
        -itemList "24 48 108 144 162 216 324 single other" \
        -width 58 \
        -editable 0 \
        -contextHelp "Select a bunch pattern."
    APSComboboxFrame .preset -parent $parent -label Presets \
        -packOption "-fill x" \
        -textVariable presetChoice \
        -itemList $presetLabelList \
        -width 58 \
        -editable 0 \
        -callback "SetMXAConfiguration -index" \
        -contextHelp "Select a preset configuration for setting up the VSA for a particular HOM\n\
Rf cavity higher order mode (HOM) frequencies and R/Q \n\
computed using URMEL (T. Smith, LS Note 194 (undated, \n\
ca. 1991)) (m=monopole, d=dipole) \n\
        f(MHz)   R/Q \n\
m0      353.6   114.3 (fundamental) \n\
m1      536.7    40.7 \n\
m2      922.5     5.8 \n\
m3      939.0     5.5 \n\
m4     1173.2     4.1 \n\
m5     1210.8     5.2 \n\
                         \n\
d1      588.7   200 \n\
d2      761.1   483 \n\
d3      962.0   113 \n\
d4     1017.4    63 \n\
d5     1145.1    29 \n\
d6     1219.2    88"

    APSLabeledEntry .startfreq -parent $parent -label "Start Frequency (MHz): " \
      -textVariable startFrequency -width 60
    APSLabeledEntry .stopfreq -parent $parent -label "Stop Frequency (MHz): " \
      -textVariable stopFrequency -width 60 

    APSLabeledEntry .average -parent $parent -label "Averaging: " \
       -textVariable average  -width  60

    APSLabeledEntry .span -parent $parent -label "Span (MHz): " \
      -textVariable span -width 60 \
      -contextHelp "span for individual spectrum measurements, If Span < (Stop Frequency - Start Frequency), then multiple data sets are acquired and concatenated for each spectrum."

    APSLabeledEntry .bw -parent $parent -label "Resolution BW (kHz): " \
      -textVariable resolution -width 60 \
      -contextHelp "resolution bandwidth for individual spectrum measurements"
    APSLabeledEntry .range -parent $parent -label "Attenuation (dBm): " \
      -textVariable range -width 60 \
      -contextHelp "Adjust the sensitivity of the HP VSA with this value. -50 dBm is the maximum sensitivity. For over-voltage condition (i.e. OV1) increase the value of the range in steps of +5 dBm."
    APSLabeledEntry .rangeBeam -parent $parent -label "Attenuation for Beam (dBm): " \
      -textVariable rangeBeam -width 60 \
      -contextHelp "Adjust the sensitivity of the HP VSA with this value when beam spectrum is measured. -50 dBm is the maximum sensitivity. For over-voltage condition (i.e. OV1) increase the value f othe range in steps of +5 dBm."
    APSLabeledEntry .desp -parent $parent -label "Description: " \
      -textVariable Description -width 60 \
      -contextHelp "enter description for experiment."
   
    APSRadioButtonFrame .takeBeamData -parent $parent \
      -label "Take beam data spectrum" \
      -buttonList {Yes No} \
      -valueList {1 0} -orientation horizontal \
      -variable takeBeamData
   
    APSRadioButtonFrame .beamPlotMode -parent $parent \
      -label "Beam spectrum plot mode" \
      -buttonList {None Overlay Separate} \
      -valueList {None Overlay Separate} -orientation horizontal \
      -variable beamPlotMode
   
    APSRadioButtonFrame .movie -parent $parent \
      -label "Plot HOMs of cavities as movie" \
      -buttonList {Yes No} -valueList {1 0} -orientation horizontal \
      -variable plotMovie
    APSRadioButtonFrame .sale -parent $parent -label "Plot with same y scale?" -buttonList {Yes No} \
      -valueList {1 0} -orientation horizontal -variable sameyscale
    APSButton .start -parent $parent -text "Start" -command \
      "APSDisableButton $parent.start.button; APSEnableButton $parent.abort.button; MeasureData; APSEnableButton $parent.start.button; APSDisableButton $parent.abort.button" \
      -contextHelp \
      "starts the measurement."
    APSButton .abort -parent $parent -text "Abort" -command \
      "APSDisableButton $parent.abort.button; APSEnableButton $parent.start.button; Abort" \
      -contextHelp \
      "Abort the measurement."
    APSButton .plot -parent $parent -text "Plot" -command "PlotFile" \
      -contextHelp "Plots the data for the files with the rootname specified in the output directory."
    APSButton .plotList -parent $parent -text "Plot from List..." -command "PlotFromList" \
      -contextHelp "Brings up a list of data already collected in the output directory. The user selects a rootname from the list, and the plot will be produced."


    APSDisableButton $parent.abort.button
}

proc MakeProcessingWidget {widget args} {
    set parent ""
    APSStrictParseArguments {parent}
    APSFrame $widget -parent $parent \
      -label "Processing" -contextHelp \
      "Provides for processing the tune spectrum to a file."
    set parent $parent$widget.frame

    APSLabeledEntry .directory -parent $parent -label "Output Directory: " \
      -textVariable dataDirectory -width 60
    APSButton .daily -parent $parent.directory -packOption "-anchor e" \
      -text "daily" -size small \
      -command {set dataDirectory [APSGoToDailyDirectory -subdirectory HOM]}
    APSLabeledEntry .rootname -parent $parent -label "Rootname: " \
      -textVariable dataRootname -width 60

    APSLabeledEntry .startfreqForNorm -parent $parent -label "Start Frequency in Processing (MHz): " \
      -textVariable startFrequencyForProcessing -width 50 \
      -contextHelp "Use this to limit the processing range of the data for normalization (not directly for resonator fit). This is useful if there is spurious peaks at the ends of the spectrum. This might improve the search for peaks and fitting for resonators."

    APSLabeledEntry .stopfreqForNorm -parent $parent -label "Stop Frequency in Processing (MHz): " \
      -textVariable stopFrequencyForProcessing -width 50 \
      -contextHelp "Use this to limit the processing range of the data for normalization (not directly for resonator fit). This is useful if there is spurious peaks at the ends of the spectrum. This might improve the search for peaks and fitting for resonators."

    APSRadioButtonFrame .ignoreBeam -parent $parent \
      -label "Ignore Beam Spectrum" \
      -buttonList {Yes No} -valueList {1 0} -orientation horizontal \
      -variable ignoreBeamSpectrum \
      -contextHelp "If selected, ignore the beam spectrum when normalizing. The fitting will be done on the unadjusted measured spectrum."

    APSLabeledEntry .numberForFit -parent $parent -label "Points for fit" \
      -textVariable fitPoints -width 50 \
      -contextHelp "Number of harmonic peaks to use for resonator fits. The normalization process results in one peak point per harmonic."

    APSRadioButtonFrame .beamPlotMode -parent $parent \
      -label "Beam spectrum plot mode" \
      -buttonList {None Overlay Separate} \
      -valueList {None Overlay Separate} -orientation horizontal \
      -variable beamPlotMode
    APSRadioButtonFrame .movie -parent $parent \
      -label "Plot HOMs of cavities as movie" \
      -buttonList {Yes No} -valueList {1 0} -orientation horizontal \
      -variable plotMovie

    APSButton .normalize -parent $parent -text "Normalize" \
      -command "NormalizeResponses" \
      -contextHelp "Normalizes the cavity response spectrum to the beam spectrum."
    APSButton .plotNormalized -parent $parent -text "Plot Normalized" \
      -command "PlotFile -mode normalized" \
      -contextHelp "Plots the normalized cavity response spectrum."

    APSButton .fit -parent $parent -text "Fit Resonators" \
      -command "FitResponses" \
      -contextHelp "Fits the cavity response spectrum to standard resonator expression with f0, Q and amplitude. The rms in done on the 10 log of response."
    APSButton .plotFits -parent $parent -text "Plot Fits" \
      -command "PlotFile -mode fit" \
      -contextHelp "Plots the fitted cavity response spectrum."

}

proc PlotFromList {} {
    global dataDirectory dataRootname bunchPattern  archive status
    if !$archive {
        set fileList [glob $dataDirectory/*-cavity-\[34\]\[6780\]-\[1234\]]
    } else {
        if ![string length $bunchPattern] {
            set status "Please select a bunch pattern first for plotting archive data!"
            return
        }
        set fileList [glob $dataDirectory/$bunchPattern/*-cavity-\[34\]\[6780\]-\[1234\]]
    }
    foreach file $fileList {
        regexp {(.*)-cavity-..-.} [file tail $file] match root
        lappend rootnameList $root
    }
    set rootnameList [lsort -unique $rootnameList]
    set dataRootname [APSChooseItemFromList -name "Select rootname of data" \
                        -multiItem 0 \
                        -returnList $rootnameList \
                        -itemList $rootnameList \
                        -contextHelp "Select one of the rootnames for HOM data" ]
    set status $dataRootname
    if [catch {PlotFile} result] {
         return -code error "PlotFromList: $result"
    }
}

proc SetMXAConfiguration {args} {
    global presetChoice presetData dataRootname
    set index ""
    APSParseArguments {index}

    # index of the list box item when the procedure SetVSAConfiguration
    # is made the callback command for the APSComboboxFrame .preset.
    # presetChoice is the global variable for the item selected by the
    # .preset APSComboboxFrame.
    APSSetVarAndUpdate status "$presetChoice preset choice selected."

    # The order of the data in presetData is the same as for the list
    # of items in the .preset APSComboboxFrame, so the index variable choice
    # can be used to refer to the presetData data.
    
    # List of global variables for specifying the VSA setup.
    set variableList {Description startFrequency stopFrequency  average span resolution range rangeBeam}
    # List of columns in the data file 
    # /home/helios/oagData/sr/HOM/inputFiles/presetSettings
    set columnList {Description StartFrequency StopFrequency  Average FrequencySpan ResBW HPVSARange BeamRange}
    foreach var $variableList col $columnList {
        global $var
        # the 0 index refers to the first page of the data file.
        if {$var=="rangeBeam"} {
            continue
        }
        set $var [lindex [lindex $presetData(Column.$col) 0] $index]
    }
    set dataRootname $presetChoice
}


proc SetupMXA {args} {
    global MXAaddress
# six backslashes are required to make the command
# hpSocketSend $MXAaddress ":MMEM:LOAD:STAT '\\\helios\ScopeData/MXA-N9020/Setups/MXA_HOM.state'"
# :/
    set MXAsetupDir "\\\\\\helios\\ScopeData/MXA-N9020/Setups/"
    
    APSStrictParseArguments {configuration}

    if [catch {exec hpSocketSend $MXAaddress ":INST:SEL?"} mode] {
        return -code error "Error reading MXA mode; $mode"
    }
    if {$mode != "SA"} {
        if [catch {exec hpSocketSend $MXAaddress ":INST:SEL SA" } result] {
            return -code error "Error in switching MXA to SA mode: $result"
        }
        after 5000
    }
    set config ${MXAsetupDir}MXA_HOM.state
    APSSetVarAndUpdate status "Restoring configuration $config..."
    if [catch {exec hpSocketSend $MXAaddress ":MMEM:LOAD:STAT '$config'" } result ] {
        return -code error "Error setup MXA-HOM mode: $result"
    }
    APSSetVarAndUpdate status "Done restoring."
}

# this procedure ignores the MXA settings it seems.
proc SetupTuneMultiplexer {args} {
    global Sector Cavity average  span streamID range rangeBeam MXAaddress

    if {![string length $Cavity] || ![string length $Sector] } {
        return -code error "Please select sector and cavity for getting cavity signal!"
    }

    if [catch {exec hpSocketSend $MXAaddress ":POW:ATT $range dB" } result] {
        return -code error "SetupMXAScope: unable to set MXA attenuation: $result"
    }
}

proc SetHOMmultiplexer {args} {
    set sectorLabel(36) S2
    set sectorLabel(37) S3
    set sectorLabel(40) S1

    set cavity ""
    set sector ""
    APSStrictParseArguments {sector cavity}
    
    if {![string length $cavity] || ![string length $sector]} {
        return -code error "SetHOMmultiplexer: cavity or sector is not given!"
    }
    switch $cavity {
        1 -
        2 -
        3 -
        4 {
            set cavityValue "Cav$cavity E1"
        }
        default {
            return -code error "SetHOMmultiplexer: Invalid cavity provided, shouble be {1|2|3|4}"
        }
    }
    set Label $sectorLabel($sector)
    if [catch {exec cavput "-list=${Label}:C:HomRfSwitchReqMO=$cavityValue" \
                 -pend=10 \
             } result] {
        return -code error "SetHOMmultiplexer: unable to set S*:C:HomRfSwitchReqMO: $result"
    }
}

proc checkIfFilesExist {} {
    global dataDirectory dataRootname cancelMeasurement
    set fileList [glob -nocomplain $dataDirectory/$dataRootname-*]
    if [llength $fileList] {
        set done 0
        toplevel .existsBox
        wm title .existsBox "Files Exists"
        message .existsBox.message -text "Files of type $dataDirectory/$dataRootname 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; set cancelMeasurement 0; set done 1} \
          -packOption "-side left -padx 5"
        APSButton .cancel -parent $w -text "Cancel" -command {destroy .existsBox; set cancelMeasurement 1; set done 1} -packOption "-side left"
        tkwait variable done
    }
}


proc MeasureData {args} {
    # frequencies in units of MHz
    global dataRootname dataDirectory startFrequency stopFrequency span resolution Description status presetChoice average
    global abort Measurement Cavity Sector doAllCavities cancelMeasurement Cavity1 Cavity2 Cavity3 Cavity4
    global startFrequencyForProcessing stopFrequencyForProcessing S36 S37 S40 bunchPattern archive MXAaddress takeBeamData range rangeBeam
    global status
    
    set abort 0
    
    set startFrequencyForProcessing $startFrequency
    set stopFrequencyForProcessing $stopFrequency
    
    # number of VSA measurements necessary for frequency range
    set steps [expr 1.0*($stopFrequency - $startFrequency)/$span]
    
    # loop for doAllCavities 
    set sectorList ""
    set cavityList ""
    foreach sector {36 37 40} {
        if [set S$sector] {
            lappend sectorList $sector
        }
    }
    foreach cavity {1 2 3 4} {
        if [set Cavity$cavity] {
            lappend cavityList $cavity
        }
    }
    if ![llength $cavityList] {
        set status "No cavity selected."
        return
    }
    if ![llength $sectorList] {
        set status "No sector selected."
        return
    }
    if ![string length $bunchPattern] {
        set status "bunch pattern is not selected."
        return
    }
    # check whether to overwrite file
    set cancelMeasurement 0
    checkIfFilesExist
    if {$cancelMeasurement} {
        APSSetVarAndUpdate status "MeasureData: Data collection cancelled."
        return
    }
    # check for access permission
    if [catch {exec cavget -list=SRF:accessEnableMISC} permission] {
        APSSetVarAndUpdate status "MeasureData: $permission"
        return
    }
    if {$permission != "ALL"} {
        APSSetVarAndUpdate status "MeasureData: Permission for setting the HOM multplexers denied (PV SRF:accessEnableMISC set to MCR). Contact MCR operators."
        return
    }
    
    APSSetVarAndUpdate status "Taking snapshot of related data ..."
    # Take a snapshot of related PVs.
    set tmpfile /tmp/[APSTmpString]
    set relatedDataFile $tmpfile.para
    set status "take a snapshot of related pvs..."
    if [catch {GetRelatedData -outputFile $relatedDataFile \
               } result] {
        APSSetVarAndUpdate status "MeasureData: $result"
        return
    }
    if [catch {exec sddsprocess $relatedDataFile -nowarning \
                   -print=para,Description,[APSMakeSafeQualifierString $Description]  \
                   -print=para,HOMMode,$presetChoice -print=par,BunchPattern,$bunchPattern \
               } result ] {
        APSSetVarAndUpdate status "MeasureData: $result"
        return
    }
    set dateString [clock format [clock seconds] -format %Y-%m%d:%H%M%S]
    if $archive {
        set outputRoot $dataDirectory/$bunchPattern/$presetChoice-$dateString-$Measurement.beam
        set rootname $dataDirectory/$bunchPattern/$presetChoice-$dateString
    } else {
        set outputRoot $dataDirectory/$dataRootname-$Measurement.beam
        set rootname $dataDirectory/$dataRootname
    }
    if [catch {exec hpSocketSend $MXAaddress "SENS:AVER:COUN $average;:BAND $resolution kHz"  \
               } result] {
        return -code error "MeasureData: error in setting the averaging in MXA: $result"
    }

    APSSetVarAndUpdate status "Measuring data ..."

    # Only the cavity measurement selection has been written to date.
    if {!$takeBeamData} {
        APSSetVarAndUpdate status "MeasureData: Skipping taking beam spectrum as requested."
    } else {
        # Measure beam spectrum using sum measurement.
        set status "We don't have a stripline for beam measurement. Skipping."
        return

        if [catch {exec  hpSocketSend $MXAaddress ":POW:ATT $rangeBeam" } result] {
            return -code error "MeasureData: error in setting the attenuation in MXA: $result"
        }
        set outputfileList ""
        for {set index 0} {$index < $steps} {incr index} {
            if $abort {
                APSSetVarAndUpdate status "MeasureData: Data collection was aborted!"
                set abort 0
                return
            }
            set startFreq [expr $startFrequency + $index * $span]
            set stopFreq [expr $startFreq + $span]
            set centerFreq [expr ($startFreq + $stopFreq)/2.0]
            set output ${outputRoot}.[format %.3d $index]
            lappend outputfileList $output
            # call to procedure
            set tmpfile /tmp/[APSTmpString]
            set status "step $index: collecting data..."
            if [catch {CollectMXAData -startFreq $startFreq -stopFreq $stopFreq -centerFreq $centerFreq -span $span \
                         -outputFile $output \
                     } result ] {
                APSSetVarAndUpdate status "MeasureData: $result!"
                return
            }
        }
        eval exec sddscombine $outputfileList $outputRoot -overWrite
        eval file delete $outputfileList 
        
        if [catch {exec sddsxref $outputRoot $relatedDataFile \
                       -noWarning -reuse=page \
                       -transfer=para,* \
                   } result] {
            APSSetVarAndUpdate status "MeasureData: $result"
            return
        }
        catch {file delete ${outputRoot}~}
    }
    # setup and measure actual cavity data.
    APSSetVarAndUpdate status "Setup for cavities.."
    if [catch {SetupTuneMultiplexer -mode cavity} result] {
        APSSetVarAndUpdate status "MeasureData: Setup HOM measurement failed: $result"
        return
    }
    if [catch {exec  hpSocketSend $MXAaddress ":POW:ATT $range" } result] {
        return -code error "MeasureData(MXA): error in setting the attenuation in MXA: $result"
    }

    APSSetVarAndUpdate status "Cycle through cavities..."
    foreach sector $sectorList {
        set status "sector: $sector "
        foreach cavity $cavityList {
            APSSetVarAndUpdate status "Doing Sector $sector Cavity $cavity ..."
            update
            if [catch {SetHOMmultiplexer -sector $sector -cavity $cavity} result] {
                return -code error "MeasureData: Error in setting HOM multiplexer: $result"
            }

            # Take a snapshot of related PVs. This is repeated for each cavity?
            set tmpfile /tmp/[APSTmpString]
            set relatedDataFile $tmpfile.para
            if [catch {GetRelatedData -outputFile $relatedDataFile \
                     } result] {
                APSSetVarAndUpdate status "MeasureData: $result"
                return
            }
            if [catch {exec sddsprocess $relatedDataFile -nowarning \
                         -print=para,Cavity,S${sector}C${cavity} \
                         -print=par,BunchPattern,$bunchPattern \
                         -print=par,HOMMode,$presetChoice \
                         -print=para,Description,[APSMakeSafeQualifierString $Description]  \
                     } result ] {
                APSSetVarAndUpdate status "MeasureData: $result"
                return
            }
            catch {file delete ${relatedDataFile}~ }
            set outputfileList ""
            for {set index 0} {$index < $steps} {incr index} {
                if $abort {
                    APSSetVarAndUpdate status "MeasureData: Data collection was aborted!"
                    set abort 0
                    return
                }
                set startFreq [expr $startFrequency + $index * $span]
                set stopFreq [expr $startFreq + $span]
                set centerFreq [expr ($startFreq + $stopFreq)/2.0]
                if {$Measurement=="cavity"} {
                    set outputRoot $rootname-$Measurement-$sector-$cavity
                } else {
                    set outputRoot $rootname-$Measurement.[format %.3d $index]
                }
                set output ${outputRoot}.[format %.3d $index]
                lappend outputfileList $output

                # call to procedure
                set tmpfile /tmp/[APSTmpString]
                if [catch {CollectMXAData -startFreq $startFreq -stopFreq $stopFreq -centerFreq $centerFreq -span $span \
                             -outputFile $output \
                         } result ] {
                    APSSetVarAndUpdate status "MeasureData: $result!"
                    return
                }
            }
            eval exec sddscombine $outputfileList $outputRoot -overWrite
            eval file delete $outputfileList 
            
            if [catch {exec sddsxref $outputRoot $relatedDataFile \
                         -noWarning -reuse=page \
                         -transfer=para,* \
                     } result] {
                APSSetVarAndUpdate status "MeasureData: $result"
                return
            }
            # combine all pages if multi-page file.
            set tmpfile /tmp/[file tail $outputRoot]
            if [catch {exec sddscombine $outputRoot -pipe=out -merge \
                         | sddsprocess -pipe=in $tmpfile -noWarning \
                         -proc=WaveformPower,maximum,PeakFrequency,position,function=Frequency \
                         "-def=para,PossibleMode,PeakFrequency revFrequency / 0.5 + int Bunches mod,type=long" \
                     } result] {
                APSSetVarAndUpdate status "MeasureData: $result"
                return
            }
            if [catch {exec mv $tmpfile $outputRoot \
                     } result] {
                APSSetVarAndUpdate status "MeasureData: $result"
                return
            }        
            catch {file delete ${outputRoot}~}
        }
    }
    APSSetVarAndUpdate status "Measurement done."
}

proc GetRelatedData {args} {
    set outputFile ""

    APSParseArguments {outputFile}

    if {$outputFile == "" } {
        return -code error "GetRelatedData: Argument outputFile not supplied"
    }

    set tmpfile /tmp/[APSTmpString]
    if [catch {exec sddsmonitor /home/helios/oagData/sr/HOM/inputFiles/PVs.mon $tmpfile.srData \
                 -step=1 \
             } result] {
        return -code error "GetRelatedData: Data collection failed: $result!"
    }
    if [catch {exec sddsexpand $tmpfile.srData $tmpfile.expand \
             } result] {
        return -code error "GetRelatedData: $result"
    }
    if [catch {exec sddsprocess $tmpfile.expand $outputFile -nowarning \
                 "-convertunits=param,rfFrequency,MHz,Hz,1e-6" \
                 "-define=param,revFrequency,rfFrequency 1296 /,units=MHz" \
                 "-print=para,S-DCCTstring,S-DCCT=%5.2lf mA,S-DCCT" \
                 "-print=para,rfVoltageString,rfVoltage=%5.2lf kV,rfVoltage" \
             } result ] {
        return -code error "GetRelatedData: $result"
    }
}

proc CollectMXAData {args} {
    global abort 
    set startFreq ""
    set stopFreq ""
    set outputFile ""
    set centerFreq ""
    set span ""
    global MXAaddress
    APSParseArguments {startFreq stopFreq outputFile centerFreq span} 

    if {$startFreq == "" || $stopFreq == "" || $outputFile == ""} {
        return -code error "CollectMXAData: At least one of startFreq stopFreq outputFile not supplied"
    }

    # sockets with HP MXA
    if [catch {exec hpSocketSend $MXAaddress ":SENS:FREQ:CENT $centerFreq MHz" -pause=0.1 \
                   ":SENS:FREQ:SPAN $span MHz" -pause=0.1 \
               } result] {
        return -code error "CollectMXAData: error in setting the start and stop frequency: $result"
    }
    if [catch {exec hpSocketSend $MXAaddress ":SENS:AVER:COUN?" \
               } averages] {
        return -code error "CollectMXAData: error in getting sweep time: $averages"
    }
    if [catch {exec hpSocketSend $MXAaddress ":SENS:sweep:time?" \
               } sweepTime] {
        return -code error "CollectMXAData: error in getting sweep time: $sweepTime"
    }
    set waitTime [expr $sweepTime * $averages + 1]
    APSSetVarAndUpdate status "Waiting $waitTime sec for operation complete status..."
    if [catch {exec hpSocketSend $MXAaddress "init:IMM;*opc?" \
               } operationComplete ] {
        return -code error "CollectMXAData: error in getting sweep time: $operationComplete"
    }
    if [catch {exec getVXATraceData -filename $outputFile -measTune 0} result] {
        return -code error "CollectMXAData: error in reading data: $result"
    }
    return

}


proc PlotFile {args} {
    global dataRootname dataDirectory Measurement Sector Cavity archive bunchPattern status archive sameyscale
    global beamPlotMode plotMovie cavityOrder archive

    set mode raw
    APSParseArguments {mode}
    set mode [string tolower $mode]

    if $archive {
        set dir $dataDirectory/$bunchPattern
    } else {
        set dir $dataDirectory
    }
  
    if {$Measurement=="cavity"} {
        # this will sort the files in sector and position order
        switch -exact $mode {
            raw {
                set fileList [lsort [glob -nocomplain $dir/${dataRootname}-$Measurement-??-?]]
            }
            normalized {
                set fileList [lsort [glob -nocomplain $dir/${dataRootname}-$Measurement-??-?.norm]]
            }
            fit {
                set fileList [lsort [glob -nocomplain $dir/${dataRootname}-$Measurement-??-?.norm]]
                set fitFileList [lsort [glob -nocomplain $dir/${dataRootname}-$Measurement-??-?.eval]]
            }
        }
    } else {
        set fileList [glob -nocomplain $dir/${dataRootname}-$Measurement]
    }
    set layoutOptions ""
    set numberPlots [llength $fileList]
    if [string match [string tolower $beamPlotMode] "separate"] {
        incr numberPlots
    }
    if !$plotMovie {
        switch $numberPlots {
            0 { set layoutOption ""}
            1 { set layoutOption -layout=1,1 }
            2 { set layoutOption -layout=1,2 }
            3 -
            4 { set layoutOption -layout=2,2 }
            5 -
            6 { set layoutOption -layout=3,2 }
            7 -
            8 -
            9 { set layoutOption -layout=3,3 }
            10 -
            11 -
            12 { set layoutOption -layout=4,3 }
            13 -
            14 - 
            15 -
            16 { set layoutOption -layout=4,4 }
            default { set layoutOption -layout=4,4 }
        }
    }
    if $sameyscale {
        set scaleOption -same=y,global
    } else {
        set scaleOption ""
    }
    if $plotMovie {
        set layoutOption -layout=1,1
    }
    set beamFile $dir/${dataRootname}-$Measurement.beam
    switch -exact [string tolower $beamPlotMode] {
        overlay {
            set beamPlotOption "-col=Frequency,WaveformPower $beamFile -omnipresent -leg=spec=Beam -grap=line,type=1 -yscale=id=beam"
        }
        separate {
            set beamPlotOption "-col=Frequency,WaveformPower $beamFile -leg=spec=Beam -grap=line,type=1 -endpanel"
        }
        default -
        none {
            set beamPlotOption ""
        }
    }
    if $plotMovie {
        # order files according to cavity length
        set fileList ""
        set fitFileList ""
        switch -exact $mode {
            raw {
                foreach cav $cavityOrder {
                    lappend fileList $dir/${dataRootname}-cavity-${cav}
                }
            }
            normalized {
                foreach cav $cavityOrder {
                    lappend fileList $dir/${dataRootname}-cavity-${cav}.norm
                }
            }
            fit {
                foreach cav $cavityOrder {
                    lappend fileList $dir/${dataRootname}-cavity-${cav}.norm
                    lappend fitFileList $dir/${dataRootname}-cavity-${cav}.eval
                }
            }
        }
    }
    
    switch -exact $mode {
        raw {
            # check for existance of new parameter
            set fileExample [lindex $fileList 0]
            if [catch {exec sddsquery -para $fileExample | grep PossibleMode} result] {
                set PossibleModeExists 0
            } else {
                if [llength $result] {
                    set PossibleModeExists 1
                } else {
                    set PossibleModeExists 0
                }
            }
            if $PossibleModeExists {
                eval exec sddsplot -sep $layoutOption $scaleOption \
                  $beamPlotOption  -same=x,global \
                  -col=Frequency,WaveformPower -grap=line \
                  $fileList \
                  -legend=parameter=Cavity \
                  -title= \
                  \"-topline=@PossibleMode,format=Possible mode at peak: %03ld\" \
                  &
            } else {
                eval exec sddsplot -sep $layoutOption $scaleOption \
                  $beamPlotOption  -same=x,global \
                  -col=Frequency,WaveformPower -grap=line \
                  $fileList \
                  -legend=parameter=Cavity \
                  -title= \
                  \"-topline=HP MXA Waveform vs Frequency\" \
                  &
            }
        }
        normalized {
            eval exec sddsplot -sep $layoutOption $scaleOption \
              $beamPlotOption  -same=x,global \
              -col=Frequency,NormalizedSignalPower -grap=sym \
              $fileList \
              -legend=parameter=Cavity \
              -title= \
              \"-topline=HP MXA Waveform vs Frequency\" \
              &

        }
        fit {
            eval exec sddsplot -sep=fileindex -group=fileindex $scaleOption \
              $layoutOption -same=x,global \
              $beamPlotOption \
              -col=Frequency,NormalizedSignalPower -grap=sym \
              -ylabel=use=name,units \
              $fileList \
              -legend=parameter=Cavity \
              -col=Frequency,NormalizedSignalPowerFit -grap=line \
              $fitFileList \
              -title= \
              -topline=@QString \
              &
        }
    }
    APSSetVarAndUpdate status "Plotting done."
}

proc NormalizeResponses {args} {
    global dataDirectory dataRootname
    set fileList [lsort [glob -nocomplain $dataDirectory/${dataRootname}-$Measurement-??-?]]
    if {$fileList == "" } {
        return -code error "NormalizeResponse: No files matching $dataDirectory/${dataRootname}-$Measurement-??-?"
    }

    foreach file $fileList {
        APSSetVarAndUpdate status "Processing file $file..."
        if [catch {NormalizeOneResponse -signalFile $file \
                     -outputFile ${file}.norm \
                 } result] {
            return -code error "NormalizeResponses: $result"
        }
    }
    APSSetVarAndUpdate status "Done."
}

proc NormalizeOneResponse {args} {
    global startFrequencyForProcessing stopFrequencyForProcessing ignoreBeamSpectrum
    set beamFile ""
    set signalFile ""
    APSParseArguments {beamFile signalFile outputFile}
    if ![string length $signalFile] {
        return -code error "NormalizeResponse: Argument signalFile not specified"    
}
    if ![string length $beamFile] {
        # look for beam file
        regexp {(.*)-..-.} $signalFile match rootname
        set beamFile $rootname.beam
    }
    if {!$ignoreBeamSpectrum && ![file exists $beamFile]} {
        return -code error "NormalizeResponse: Can't find file $beamFile"
    }
    if ![file exists $signalFile] {
        return -code error "NormalizeResponse: Can't find file $signalFile"
        exit
    }

    if {$startFrequencyForProcessing==""} {
        set startFrequency 0
    } else {
        set startFrequency $startFrequencyForProcessing
    }
    if {$stopFrequencyForProcessing==""} {
        set startFrequency 0
    } else {
        set stopFrequency $stopFrequencyForProcessing
    }
    # WaveformMedian 3 * WaveformMin 2 * - 
    # creates a deadband in values for the baseline in between peaks.
    # Need to filter out spurious signals in between harmonics.
    if !$ignoreBeamSpectrum {
        if [catch {exec sddsxref $signalFile $beamFile -pipe=out \
                       -take=WaveformPower -rename=col,WaveformPower=BeamPower \
                       | sddscombine -pipe -merge \
                       | sddsprocess -pipe \
                       -filter=col,Frequency,$startFrequency,$stopFrequency \
                       -proc=Waveform,maximum,PeakPosition,functionof=Frequency,position \
                       -process=BeamPower,baselevel,BeamPowerBaselevel \
                       -process=BeamPower,median,BeamPowerBaselevel2 \
                       "-def=col,Sawtooth,Frequency revFrequency / 1 mod" \
                       "-test=col,Sawtooth 0.15 < Sawtooth 0.85 > ||" \
                       -process=WaveformPower,baselevel,WaveformPowerBaselevel \
                       -process=WaveformPower,median,WaveformPowerBaselevel2 \
                       -process=WaveformPower,standarddeviation,WaveformPowerStdDev \
                       -process=Waveform,baselevel,%sBaselevel \
                       -process=Waveform,minimum,%sMin \
                       -process=Waveform,median,%sMedian \
                       -process=Waveform,standarddeviation,%sStdDev \
                       "-test=col,Waveform WaveformMedian 3 * WaveformMin 2 * -   >"\
                       | sddsbreak -pipe \
                       -gapin=Frequency,amount=0.05 \
                       | sddsprocess -pipe \
                       -proc=Waveform,maximum,%sMax \
                       "-test=col,Waveform WaveformMax ==" \
                       | sddscombine -pipe -merge \
                      | sddsprocess -pipe=in $outputFile  \
                      "-redef=col,BeamPower,BeamPower,symbol=BeamPower" \
                       "-def=col,NormalizedSignalPower,WaveformPower BeamPower -,units=dB" \
                   } result] {
            return -code error "NormalizeOneResponse: $result"
        } 
    } else {
        # break with gaps in 50kHz
        if [catch {exec sddscombine $signalFile -pipe=out -merge \
                       | sddsprocess -pipen  \
                       -filter=col,Frequency,$startFrequency,$stopFrequency \
                       -proc=Waveform,maximum,PeakPosition,functionof=Frequency,position \
                       "-def=col,Sawtooth,Frequency revFrequency / 1 mod" \
                       "-test=col,Sawtooth 0.15 < Sawtooth 0.85 > ||" \
                       -process=WaveformPower,baselevel,WaveformPowerBaselevel \
                       -process=WaveformPower,median,WaveformPowerBaselevel2 \
                       -process=WaveformPower,standarddeviation,WaveformPowerStdDev \
                       -process=Waveform,baselevel,%sBaselevel \
                       -process=Waveform,minimum,%sMin \
                       -process=Waveform,median,%sMedian \
                       -process=Waveform,standarddeviation,%sStdDev \
                       "-test=col,Waveform WaveformMedian 3 * WaveformMin 2 * -   >"\
                       | sddsbreak -pipe \
                       -gapin=Frequency,amount=0.05 \
                       | sddsprocess -pipe \
                       -proc=Waveform,maximum,%sMax \
                       "-test=col,Waveform WaveformMax ==" \
                       | sddscombine -pipe -merge \
                       | sddsprocess -pipe=in $outputFile  \
                       "-def=col,NormalizedSignalPower,WaveformPower,units=dB" \
                   } result] {
            return -code error "NormalizeOneResponse: $result"
        }
    }
}

proc FitResponses {args} {
    global dataDirectory dataRootname Measurement
    set fileList [lsort [glob -nocomplain $dataDirectory/${dataRootname}-$Measurement-??-?]]
    if {$fileList == "" } {
        return -code error "NormalizeResponse: No files matching $dataDirectory/${dataRootname}-$Measurement-??-?"
    }

    foreach file $fileList {
        APSSetVarAndUpdate status "Fitting file $file.norm..."
        if [catch {FitOneResonator -dataFile ${file}.norm \
                     -fitFile ${file}.fit \
                     -evalFile ${file}.eval \
                 } result] {
            return -code error "FitResponses(1): $result"
        }
        lappend resultsFiles ${file}.eval
    }
    set dimensionsFile /home/helios/oagData/sr/HOM/inputFiles/CavityStaggering.sdds
    set finalResultsFile $dataDirectory/${dataRootname}-$Measurement.results
    # some files may not have been fitted, so use glob -nocomplain
    eval set resultsFiles [glob -nocomplain $resultsFiles]
    if [catch {eval exec sddscombine $resultsFiles -pipe=out -collapse \
                 | sddsxref -pipe $dimensionsFile \
                 -take=CavityNumber,IdealDimensionA -match=Cavity \
                 | sddssort -pipe=in $finalResultsFile \
                 -col=IdealDimensionA,decr \
             } result] {
        return -code error "FitResponses(2): $result"
    }

    exec sddsplot \
      "-topline=Fitting results for ${dataRootname}* data" \
      -col=IdealDimensionA,HOMfrequency $finalResultsFile \
      -filter=col,Fitted,1,1 \
      -grap=sym \
      -leg=spec=Fitted \
      -col=IdealDimensionA,HOMfrequency $finalResultsFile \
      -filter=col,Fitted,0,0 \
      -grap=sym,sub=1 \
      -leg=spec=Peak \
      &

    APSSetVarAndUpdate status "Done."
}

proc FitOneResonator {args} {
    global fitPoints
    set dataFile ""
    APSParseArguments {dataFile fitFile evalFile}
    if ![string length $dataFile] {
        return -code error "FitOneResponse: Argument dataFile not specified"    
    }
    if ![file exists $dataFile] {
        return -code error "FitOneResponse: Can't find file $dataFile"
        exit
    }

    set revFrequency 0.271
    set gapAmount [expr $revFrequency / 2]
    if [catch {exec sddsbreak $dataFile -pipe=out \
                 -gapin=Frequency,amount=$gapAmount \
                 | sddsprocess -pipe \
                 -process=*,average,%sAve \
                 | sddscollapse -pipe \
                 | sddsconvert -pipe \
                 -editname=col,*Ave,%/Ave// \
                 | sddssort -pipe \
                 -col=NormalizedSignalPower,decreasing \
                 | sdds2stream -pipe \
                 -col=Frequency } limits ] {
        return -code error "FitOneResponse(1): $limits"
    }
    set limit1 [lindex $limits 0]
    set limit2 [lindex $limits 1]

    if {[llength $limits] <= 3} {
        APSSetVarAndUpdate status "Not enough normalized data points in $dataFile. Processing is skipped, but an empty file is created for a proper plot."
        # Create a one-row file which will be plotted along with files of other
        # cavities that have good data.
        # The HOM frequency is taken to be the frequency of the peak.
        # The flag Fitted will be used for plot filtering purposes.
        if [catch {exec sddsmakedataset -pipe=out -noWarnings \
                     -para=HOMfrequency,type=double -data=$limit1 \
                     -para=Fitted,type=long -data=0 \
                     -para=Q,type=double -data=0 \
                     -para=QString,type=string "-data=Q\= 0" \
                     -para=AmplitudedB,type=double -data=0 \
                     -col=Frequency,type=double -data=$limit1 \
                     -col=NormalizedSignalPowerFit,type=double  -data=-40 \
                     | sddsxref -pipe=in $dataFile $evalFile -noWarning \
                     -transfer=para,* -leave=col,* \
                 } result] {
            return -code error "FitOneResponse(2): $result"
        }
        return 
    }

# starting value should be the absolute peak
    if [catch {exec sdds2stream -para=PeakPosition $dataFile} startingValue] {
        return -code error "FitOneResponse(peak): $result"
    }
    set lower [expr $startingValue - $revFrequency]
    set upper [expr $startingValue + $revFrequency]

    set equation "Frequency HOMfrequency -  HOMfrequency / sqr Q sqr * 4 / 1 + rec AmplitudedB * "
    set equation "Frequency HOMfrequency -  HOMfrequency / sqr Q sqr * 4 / 1 + rec log 10 * AmplitudedB + "
    # fit the first $fitPoints. It is assume that the envelope is shaped in 
    # a reasonable way around the peak
    if [catch {exec sddssort $dataFile -pipe=out \
                   -col=NormalizedSignalPower,decr \
                   | sddsprocess -pipe \
                   -clip=$fitPoints,0,invert \
                   | sddsgenericfit -pipe=in $fitFile \
                   -columns=Frequency,NormalizedSignalPower \
                   -equation=$equation \
                   -simplex=restart=20,cycles=20,evaluations=100 \
                   -variable=name=HOMfrequency,lower=$lower,upper=$upper,step=10,start=$startingValue \
                   -variable=name=Q,lower=5e3,upper=200e3,step=1e3,start=30e3 \
                   -variable=name=AmplitudedB,lower=-80,upper=20,step=1,start=-25  \
               } result] {
        return -code error "FitOneResponse(3): $result"
    }

    if [catch {exec sddsprocess $dataFile -pipe=out -clip=1,1,invert \
                 | sdds2stream -pipe -col=Frequency} range] {
        return -code error "FitOneResponse(3a): $range"
    }      
    # Added Fitted flag.
    if [catch {exec sddssequence -pipe \
                 -def=Frequency,units=MHz \
                 -sequ=begin=[lindex $range 0],end=[lindex $range 1],number=1000 \
                 | sddsxref -pipe $fitFile \
                 -transfer=para,* -leave=* \
                 | sddsprocess -pipe=in $evalFile  \
                 -def=para,Fitted,1,type=long \
                 "-print=para,QString,Q=%6.0f,Q" \
                 "-def=col,NormalizedSignalPowerFit,Frequency HOMfrequency -  HOMfrequency / sqr Q sqr * 4 / 1 + rec log 10 * AmplitudedB + " \
                 "-def=col,NormalizedSignalFit,Frequency HOMfrequency -  HOMfrequency / sqr Q sqr * 4 / 1 + rec AmplitudedB * " \
             } result] {
        return -code error "FitOneResponse(4): $result"
    }

    return
}

set abort 0
proc Abort {args} {
    global abort
    set abort 1
}

proc UpdatePatternAndHOM {args} {
    global compareRoot compareDirectory compareBunchPattern compareHOMMode archiveRoot status
    
    if ![file exist $compareDirectory] {
        set status "$compareDirectory does not exist!"
        set compareDirectory ""
        set compareRoot ""
        set achiveRoot ""
        return
    }
    set fileList [glob -nocomplain $compareDirectory/${compareRoot}*-cavity-\[34\]\[6780\]-\[1234\]]
    if ![llength $fileList] {
        set status "No files found for $compareRoot at $compareDirectory."
        set compareRoot ""
        set achiveRoot ""
        return
    }
    set compareHOMMode ""
    set file [lindex $fileList 0]
    set pars [exec sddsquery -par $file]
    if {[lsearch -exact $pars HOMMode]<0 || [lsearch -exact $pars BunchPattern]<0} {
        if {[lsearch -exact $pars Bunches]>=0} {
            set pattern [format %.0f [exec sdds2stream -par=Bunches -page=1 $file]]
            switch $pattern {
                324 {
                    set compareBunchPattern $pattern
                }
                216 {
                    set compareBunchPattern $pattern
                }
                162 {
                    set compareBunchPattern $pattern
                }
                144 {
                    set compareBunchPattern $pattern
                }
                108 {
                    set compareBunchPattern $pattern
                }
                48 {
                    set compareBunchPattern $pattern
                }
                24 {
                    set compareBunchPattern $pattern
                }
                1 {
                    set compareBunchPattern single
                }
                default {
                    set compareBunchPattern other
                }
            }
        } else {
            set desc [string tolower [exec sdds2stream -par=Description $file -page=1]]
            if [regexp {324} $desc] {
                set compareBunchPattern 324
            } elseif [regexp {216} $desc] {
                set compareBunchPattern 216
            } elseif [regexp {162} $desc] {
                set compareBunchPattern 162
            } elseif [regexp {144} $desc] {
                set compareBunchPattern 144
            } elseif [regexp {108} $desc] {
                set compareBunchPattern 108
            } elseif [regexp {48} $desc] {
                set compareBunchPattern 48
            } elseif [regexp {24} $desc] {
                set compareBunchPattern 24
            } elseif [regexp {single} $desc] {
                set compareBunchPattern single
            } else {
                set compareBunchPattern other
            }
        }
    } else {
        set compareBunchPattern [exec sdds2stream -par=BunchPattern -page=1 $file]
        set compareHOMMode [exec sdds2stream -par=HOMMode -page=1 $file]
        set compareHOMMOde [regsub {zoom} $compareHOMMode ""]
    }
    set archiveRoot ""
}


proc ChooseCompareRoot {args} {
    set index ""
    APSParseArguments {index}
    global compareDirectory$index compareRoot$index
    
    set fileList [glob [set compareDirectory$index]/*-cavity-\[34\]\[6790\]-\[1234\]]
    foreach file $fileList {
        regexp {(.*)-cavity-..-.} [file tail $file] match root
        lappend rootnameList $root
    }
    set rootnameList [lsort -unique $rootnameList]
    set compareRoot$index [APSChooseItemFromList -name "Select rootname of experiment data" \
                       -multiItem 0  \
                       -returnList $rootnameList \
                       -itemList $rootnameList \
                       -contextHelp "Select one of the rootnames for HOM data" ]
    if ![string length $index] {
        UpdatePatternAndHOM
    }
}

proc ChooseArchiveRoot {args} {
    global compareBunchPattern compareHOMMode compareDirectory compareRoot
    global archiveDir archiveRoot status
    if ![string length $compareRoot] {
        set status "Select compare file root first"
        return
    }
    set fileList [glob $archiveDir/data/$compareBunchPattern/${compareHOMMode}*-cavity-\[34\]\[6790\]-\[1234\]]
    foreach file $fileList {
        regexp {(.*)-cavity-..-.} [file tail $file] match root
        lappend rootnameList $root
    }
    set rootnameList [lsort -unique $rootnameList]
    set archiveRoot [APSChooseItemFromList -name "Select rootname of archive data" \
                       -multiItem 0\
                       -returnList $rootnameList \
                       -itemList $rootnameList \
                       -contextHelp "Select one of the rootnames for HOM data" ]
   
}

set compareDirectory1 ""
set compareDirectory2 ""
set compareRoot1 ""
set compareRoot2 ""
proc CompareData {args} {
    global compareDirectory1 compareDirectory2 compareRoot1 compareRoot2 cavityOrder1

     foreach name {compareDirectory1 compareDirectory2 compareRoot1 compareRoot2} {
        if ![string length [set $name]] {
            return -code error "$name is not selected"
        }
    }
    set beamfile1 $compareDirectory1/${compareRoot1}-cavity.beam
    set beamfile2 $compareDirectory2/${compareRoot2}-cavity.beam
    if {[file exist $beamfile1] && [file exist $beamfile2]} {
          exec sddsplot  -grap=line,vary -col=Frequency,WaveformPower $beamfile1 -legend=spec=[file tail $beamfile1] -col=Frequency,WaveformPower $beamfile2 -leg=spec=[file tail $beamfile2] -yscale=id=beam &
    }
     set option ""
    foreach cav $cavityOrder1 {
        set file1 $compareDirectory1/${compareRoot1}-cavity-$cav
        set file2 $compareDirectory2/${compareRoot2}-cavity-$cav
       
        if {[file exist $file1] && [file exist $file2]} {
            append option " -col=Frequency,WaveformPower -grap=line,vary $file1 -leg=spec=[file root $file1]"
            append option " -col=Frequency,WaveformPower -grap=line,vary $file2 -leg=spec=[file root $file2]"
        }
    }
   
    eval exec sddsplot -sep=2 -same=x,global -topline=@Cavity $option &

}

proc CompareWithArchive {args} {
    global compareDirectory compareRoot archiveDir compareBunchPattern compareRoot cavityOrder1 archiveRoot
    if {![info exist compareRoot] || ![string length $compareRoot]} {
        ChooseCompareFile
        ChooseArchiveFile
    } elseif {![info exist archiveRoot] || ![string length $archiveRoot]} {
        ChooseArchiveFile
    }
    
  #  set compareFiles [lsort [glob -nocomplain $compareDirectory/${compareRoot}-cavity-??-?]]
  #  set archiveFiles [lsort [glob -nocomplain $archiveDir/$compareBunchPattern/${archiveRoot}-cavity-??-?]]
    set beamfile1 $compareDirectory/${compareRoot}-cavity.beam
    set beamfile2 $archiveDir/data/$compareBunchPattern/${archiveRoot}-cavity.beam
    
    exec sddsplot  -grap=line,vary -col=Frequency,WaveformPower $beamfile1 -legend=spec=exp -col=Frequency,WaveformPower $beamfile2 -leg=spec=archive -yscale=id=beam &
    set option ""
    foreach cav $cavityOrder1 {
        set file1 $compareDirectory/${compareRoot}-cavity-$cav
        set file2 $archiveDir/data/$compareBunchPattern/${archiveRoot}-cavity-$cav
       
        if {[file exist $file1] && [file exist $file2]} {
            append option " -col=Frequency,WaveformPower -grap=line,vary $file1 -leg=spec=exp"
            append option " -col=Frequency,WaveformPower -grap=line,vary $file2 -leg=spec=archive"
        }
    }
   
    eval exec sddsplot -sep=2 -same=x,global -topline=@Cavity $option &
}

proc SelectCompareDirectory {args} {
    set rootname ""
    APSParseArguments {rootname}
    
    global $rootname HOMDirectory status

    if ![info exist HOMDirectory] {
        set HOMDirectory [exec sdds2stream -col=DirectoryName /home/helios/SR/daily/HOM.searchResults]
    }
    set $rootname [APSChooseItemFromList -name "Select compare directory" \
                     -multiItem 0 \
                     -returnList $HOMDirectory \
                     -itemList $HOMDirectory \
                     -contextHelp "Select one of the HOM data directory" ]
    
}

proc MakeCompareWidget {widget args} {
    set parent ""
    APSStrictParseArguments {parent}
    global compareDirectory compareRoot archiveRoot 
    APSFrame $widget -parent $parent \
      -label "Compare with archive" -contextHelp \
      "Compare with archive data."
    set parent1 $parent$widget.frame
    
    APSLabeledEntry .directory -parent $parent1 -label "Data Directory: " \
      -textVariable compareDirectory -width 60
    APSButton .select -parent $parent1.directory -packOption "-side right" -size small -text F \
      -command "SelectCompareDirectory -rootname compareDirectory"
    APSLabeledEntry .file -parent $parent1 -label "Experiment file root: " \
      -textVariable compareRoot -width 60
    bind $parent1.file.entry <Return> "UpdatePatternAndHOM"
    APSButton .f -parent $parent1.file -packOption "-side right" -size small -text "F" \
      -command "ChooseCompareRoot"
    APSLabeledEntry .f1 -parent $parent1 -label "Archive file root: " \
      -textVariable archiveRoot -width 60
    APSButton .f -parent $parent1.f1 -packOption "-side right" -size small -text "F" \
      -command "ChooseArchiveRoot"
    APSButton .compare -parent $parent1 -text "Compare" -command "CompareWithArchive"

    APSFrame .com1 -parent $parent -label "Compare Two data"
    set parent2 $parent.com1.frame
    global compareDirectory1 compareDirectory2 compareRoot1 compareRoot2
    APSLabeledEntry .dir1 -parent $parent2 -label "Compare1 Directory: " \
      -textVariable compareDirectory1 -width 60
    APSButton .select1 -parent $parent2.dir1 -packOption "-side right" -size small -text F \
      -command "SelectCompareDirectory -rootname compareDirectory1"
    APSLabeledEntry .file1 -parent $parent2 -label "rootname1: " \
      -textVariable compareRoot1 -width 60
    APSButton .f -parent $parent2.file1 -packOption "-side right" -size small -text "F" \
      -command "ChooseCompareRoot -index 1"

    APSLabeledEntry .dir2 -parent $parent2 -label "Compare2 Directory: " \
      -textVariable compareDirectory2 -width 60
    APSButton .select2 -parent $parent2.dir2 -packOption "-side right" -size small -text F \
      -command "SelectCompareDirectory -rootname compareDirectory2"
    APSLabeledEntry .file2 -parent $parent2 -label "rootname2: " \
      -textVariable compareRoot2 -width 60
    APSButton .f -parent $parent2.file2 -packOption "-side right" -size small -text "F" \
      -command "ChooseCompareRoot -index 2"
    APSButton .compare -parent $parent2 -text "Compare" -command "CompareData"
    APSButton .search -parent $parent -text "Search New Directories" -command "exec SearchDailyDirectories -system SR -searchDirectory HOM"
    
}


set compareDirectory /home/helios/SR/daily/0808/13/2/HOM
set archiveDir  /home/helios/oagData/sr/HOM
set compareRoot ""
set sameyscale 0
set cavityOrder "36-2 40-4 40-3 36-1 40-1 40-2 36-4 36-3 37-3 37-2 37-1 37-4"
set cavityOrder1 [lsort $cavityOrder]
# file of HOMs which give a list of preset frequency settings for measurement.
set presetFile /home/helios/oagData/sr/HOM/inputFiles/presetSettings
sdds load $presetFile presetData
set presetLabelList [lindex $presetData(Column.Label) 0]
set presetChoice ""
set bunchPattern 162
set archive 0
set tabWidgetList [APSTabFrame .sections -parent .userFrame -label "" \
                     -labelList {Cavities "Instrument Setup" "Measurement Setup" Processing Compare} \
                     -width 880 -height 500]

MakeCavitySelectionWidget .selection -parent [lindex $tabWidgetList 0]
MakeSetupWidget           .setup     -parent [lindex $tabWidgetList 1]
MakeSaveWidget            .save      -parent [lindex $tabWidgetList 2]
MakeProcessingWidget      .process   -parent [lindex $tabWidgetList 3]
MakeCompareWidget         .compare   -parent [lindex $tabWidgetList 4]

APSSetVarAndUpdate status Ready.

set Sector 36
set Cavity 1
set doAllCavities 0
set dataDirectory "."
set dataRootname rfhom01
# all frequencies in MHz
set startFrequency 530
set stopFrequency 550
set average 1
set span 20
set range -50
set rangeBeam -20
set harmonics 3
set Description "mode 540 MHz"
set Measurement cavity

set takeBeamData 0
set beamPlotMode None
set plotMovie 0
set ignoreBeamSpectrum 1
set fitPoints 5
set startFrequencyForProcessing $startFrequency
set stopFrequencyForProcessing $stopFrequency
set startFrequency 530
set stopFrequency 550

# this will have to change
set MXAaddress 10.6.37.49

# Local Variables:
# mode: tcl
# indent-tabs-mode: nil
# End:
