#!/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)]
set apsttk 1
APSDebugPath

set CVSRevisionAuthor "\$Revision: 1.34 $ \$Author: emery $"

proc MakeDateTimeFrame {widget args} {
    set parent .
    set rootname ""
    APSStrictParseArguments {parent rootname glitchMode}
    set label "Date/Time Range of Interest"

    APSFrame $widget -parent $parent -label $label
    set w $parent$widget.frame

    APSDateTimeAdjEntry .startDate -parent $w \
      -yearVariable ${rootname}StartYear \
      -monthVariable ${rootname}StartMonth \
      -dayVariable ${rootname}StartDay \
      -hourVariable ${rootname}StartHour \
      -label "Start (year, month, day, hour): " -defaultHour 0 \
      -command ResetDataFileList -buttonSize small
    APSDateTimeAdjEntry .endDate -parent $w \
      -yearVariable ${rootname}EndYear \
      -monthVariable ${rootname}EndMonth \
      -dayVariable ${rootname}EndDay \
      -hourVariable ${rootname}EndHour \
      -label "End (year, month, day, hour):   " -defaultHour 24 \
      -command ResetDataFileList -buttonSize small

    SetDateTimeToToday -rootname ${rootname}Start -hour 0
    SetDateTimeToToday -rootname ${rootname}End  -hour 24
}

proc SetDateTimeToToday {args} {
    set rootname ""
    set hour 0
    ResetDataFileList
    APSStrictParseArguments {rootname hour}

    global ${rootname}Month ${rootname}Year ${rootname}Day ${rootname}Hour
    
    APSDateBreakDown -dayVariable ${rootname}Day -yearVariable ${rootname}Year \
      -monthVariable ${rootname}Month -twoDigitYear 0 -leadingZeros 0
    set ${rootname}Hour $hour
}

proc ResetDataFileList {} {
    global dataFileList  dataFileListIsOld
    set dataFileList ""
    set dataFileListIsOld 1
}

proc MakeFilterFrame {widget args} {
    global minDCCT maxDCCT userBeamModeOnly
    set parent ""
    APSStrictParseArguments {parent}

    APSFrame $widget -parent $parent -label "Filters" 
    set w $parent$widget.frame
    APSLabeledEntryFrame .dcct -parent $w -label "Current (min, max mA): " \
      -variableList {minDCCT maxDCCT} -width 6 -orientation horizontal \
      -contextHelp "Enter the minimum and maximum values for the DCCT.  If the values are equal, no filter is applied."
    APSRadioButtonFrame .userbeam -parent $w -label "User beam mode only: " \
      -buttonList {Yes No} -valueList {1 0} -orientation horizontal -variable userBeamModeOnly \
      -contextHelp "Choose whether to show only data from user beam time or not."
}

proc MakeSmoothWidget {widget args} {
    global hDespikeNeighbors hDespikeAverage hDespikePasses hDespikeThreshold hDespike
    global vDespikeNeighbors vDespikeAverage vDespikePasses vDespikeThreshold vDespike
    set parent ""
    APSStrictParseArguments {parent}

    APSFrame $widget -parent $parent -label "Smoothing parameters"
    set w $parent$widget.frame

    APSCheckButtonFrame .checkButton -parent $w -label "Despike                        " \
      -buttonList {"H " "V "} \
      -variableList {hDespike vDespike} \
      -orientation horizontal \
      -contextHelp "Select whether to apply the despiking filter to the orbit before display."

    APSLabeledEntryFrame .despike2 -parent $w \
      -label "Despike passes (H, V):         " \
      -variableList {hDespikePasses vDespikePasses} -width 5 -orientation horizontal \
      -contextHelp "Enter the number of passes to make through the despiker to get the smoothed orbit."
    APSLabeledEntryFrame .despike0 -parent $w \
      -label "Spike find neighbors (H, V):   " \
      -variableList {hDespikeNeighbors  vDespikeNeighbors} -width 5 -orientation horizontal  \
      -contextHelp "Enter the number of neighbors to average over for the spike finder."
    APSLabeledEntryFrame .despike1 -parent $w \
      -label "Spike smooth neighbors (H, V): " \
      -variableList {hDespikeAverage vDespikeAverage} -width 5 -orientation horizontal \
      -contextHelp "Enter the number of neighbors to average over for the spike smoother.  Must be less than the number used for the spike finder."
    APSLabeledEntryFrame .despike3 -parent $w \
      -label "Spike threshold in mm (H, V):  " \
      -variableList {hDespikeThreshold vDespikeThreshold} -width 5 -orientation horizontal \
      -contextHelp "Enter the threshold below which despiking will not occur."

    APSButton .hRevert -parent $w -text "H defaults" -width "" \
      -command {setDespikeDefaults -plane H} \
      -contextHelp {Reverts to the H plane despiking defaults.}
    APSButton .vRevert -parent $w -text "V defaults" -width "" \
      -command {setDespikeDefaults -plane V} \
      -contextHelp {Reverts to the V plane despiking defaults.}
    setDespikeDefaults -plane both
}

proc setDespikeDefaults {args} {
    global hDespikeNeighbors hDespikeAverage hDespikePasses hDespikeThreshold hDespike
    global vDespikeNeighbors vDespikeAverage vDespikePasses vDespikeThreshold vDespike
    global mode

    APSParseArguments {plane}
    if {[string compare $plane both]==0} {
        set plane {H V}
    }
    foreach eachPlane $plane {
        switch $eachPlane {
            H {
                set hDespikeNeighbors 36
                set hDespikeAverage 4
                set hDespikePasses 2
                set hDespikeThreshold 0.02
                set hDespike 0
            }
            V {
                set vDespikeNeighbors 36
                set vDespikeAverage 4
                set vDespikePasses 2
                set vDespikeThreshold 0.02
                set vDespike 0
            }
        }
    }
    return
}


proc APSSetLabeledEntryFrameState {widget args} {
    set state normal
    APSStrictParseArguments {state}
    set index 1
    while 1 {
        if [winfo exists $widget.frame.entry$index] {
            $widget.frame.entry$index configure -state $state
        } else {
            break
        }
        incr index
    }
}

proc MakeButtonRow {widget args} {
    set parent ""
    set label1 BPMs:
    set label2 mm
    APSStrictParseArguments {parent label1 label2}
    global review
    APSFrame $widget -parent $parent -label "Plot Controls" -packOption "-side top -anchor nw"
    set w $parent$widget.frame
    if {[string compare $review SROrbit] == 0} {
        APSRadioButtonFrame .item -parent $w -label "Readback Type" \
          -buttonList {LowPass1s LowPass8s LowPass64s Unadjusted Adjusted Error Sampled SampledAdjusted Position Setpoint Offset Gain} \
          -valueList {LowPass1s LowPass8s LowPass64s Unadjusted Adjusted Error Sampled SampledAdjusted Position Setpoint Offset Gain} \
          -orientation vertical -limitPerRow 3 \
          -variable readbackChoice \
          -contextHelp "Choose which type of BPM readback you want to look at.  Error is the ErrorCC readback that we correct on.  Setpoint is the orbit setpoint that we steer to.  Offset is the offset of the BPM, a combination of the measured offset and the intensity compensated offset.  Unadjusted is the raw value before removing the offset and setpoint.  Adjusted is the raw value with the offset removed."
        pack configure $w.item -fill both
    }
    frame $w.f1
    pack $w.f1 -side top -expand true -fill x
    grid columnconfigure $w.f1 0 -weight 0
    grid columnconfigure $w.f1 1 -weight 1

    ttk::label $w.f1.label1 -text Planes:
    APSCheckButtonFrame .planes -parent $w.f1 -label "" \
      -buttonList {x/H y/V} -variableList {doHPlots doVPlots} \
      -orientation horizontal \
      -contextHelp "Choose which planes of the orbit to plot." \
      -allNone 1 -noPack 1
    grid $w.f1.label1 -column 0 -row 0 -sticky e -padx 10
    grid $w.f1.planes -column 1 -row 0 -sticky w

    ttk::label $w.f1.label2 -text "Show changes:"
    APSRadioButtonFrame .changes -parent $w.f1 -label "" \
      -buttonList {Yes No} -valueList {1 0} -variable showChanges \
      -orientation horizontal -noPack 1 -contextHelp \
      "Choose whether to look at orbit changes relative to the first orbit, or at the actual values."
    grid $w.f1.label2 -column 0 -row 1 -sticky e -padx 10
    grid $w.f1.changes -column 1 -row 1 -sticky w

    ttk::label $w.f1.label3 -text "Plot vs.:"
    APSRadioButtonFrame .abscissa -parent $w.f1 -noPack 1 -label "" \
      -buttonList {s Sector Time} -valueList {s Sector Time} -variable abscissaColumn \
      -commandList [list "APSControlRadioButtonFrame $w.stats -state 0"  \
                      "APSControlRadioButtonFrame $w.stats -state 0"  \
                      "APSControlRadioButtonFrame $w.stats -state 1" ] \
      -orientation horizontal -contextHelp \
      "Choose whether to plot vs s (in meters), sector number, or time."
    grid $w.f1.label3 -column 0 -row 2 -sticky e -padx 10
    grid $w.f1.abscissa -column 1 -row 2 -sticky w

    ttk::label $w.f1.label4 -text "Show point label:"
    APSRadioButtonFrame .labelpoint -parent $w.f1 -noPack 1 -label ""\
      -buttonList {Yes No} -valueList {1 0} -variable showPointLabel \
      -orientation horizontal -contextHelp \
      "choose whether to show the bpm name of each plot point for orbit plots (note you do not want to choose this option for plotting more than 2 sectors)"
    grid $w.f1.label4 -column 0 -row 3 -sticky e -padx 10
    grid $w.f1.labelpoint -column 1 -row 3 -sticky w

    ttk::label $w.f1.label5 -text "Time plot statistics:"
    APSRadioButtonFrame .stats -parent $w.f1 -noPack 1 -label "" \
      -buttonList {Yes No} -valueList {1 0} -variable bpmStatistics \
      -orientation horizontal -contextHelp \
      "Choose whether to show individual BPM data (statistics off) or statistics over all BPMs."
    grid $w.f1.label5 -column 0 -row 4 -sticky e -padx 10
    grid $w.f1.stats -column 1 -row 4 -sticky w
    APSControlRadioButtonFrame $w.stats -state 0

    ttk::label $w.f1.label6 -text "Statistics limit ($label2):"
    APSLabeledEntry .statLim -parent $w.f1 -noPack 1 -label "" \
      -textVariable statisticsLimit -contextHelp \
      "Enter the limit on values that are included in statistics.  Used to remove outliers."
    grid $w.f1.label6 -column 0 -row 5 -sticky e -padx 10
    grid $w.f1.statLim -column 1 -row 5 -sticky w

    ttk::label $w.f1.label7 -text "Sparsing factor:"
    APSLabeledEntry .sparse -parent $w.f1 -noPack 1 -label "" \
      -textVariable sparsingFactor -contextHelp \
      "Allows displaying only every Nth orbit, where N is the sparsing factor."
    grid $w.f1.label7 -column 0 -row 6 -sticky e -padx 10
    grid $w.f1.sparse -column 1 -row 6 -sticky w

    ttk::label $w.f1.label8 -text "Sector range:"
    APSLabeledEntryFrame .sectorLimits -parent $w.f1 -noPack 1 -label "" \
      -variableList {sectorLowerLimit sectorUpperLimit} -width 4 \
      -orientation horizontal -contextHelp \
      "Enter the first and last sector to be shown on the plots."
    grid $w.f1.label8 -column 0 -row 7 -sticky e -padx 10
    grid $w.f1.sectorLimits -column 1 -row 7 -sticky w
    
    global BPMLabelList BPMVarList
    if {[string compare $review SROrbit] == 0} {
        APSCheckButtonFrame .bpmType -parent $w -label "$label1 " \
          -buttonList $BPMLabelList -limitPerRow 7 -variableList $BPMVarList \
          -orientation vertical -contextHelp "Choose which BPM types to include in plots." \
          -allNone 1
    } else {
        APSCheckButtonFrame .bpmType -parent $w -label "$label1 " \
          -buttonList $BPMLabelList -limitPerRow 7 -variableList $BPMVarList \
          -orientation vertical -contextHelp "Choose which BPM types to include in plots." \
          -allNone 1
    }
    foreach plane {h v} {
        APSFrame .${plane}scale -parent $w -label "$plane plane plotting" 
        set w1 $w.${plane}scale.frame
        APSRadioButtonFrame .mode -parent $w1 -label "Plot scaling mode" \
          -buttonList {"Variable Autoscale" "Fixed Autoscale" "User-supplied"} \
          -valueList {variableAuto fixedAuto userSupplied} \
          -commandList [list \
                          "APSSetLabeledEntryFrameState $w1.ulimits -state disabled" \
                          "APSSetLabeledEntryFrameState $w1.ulimits -state disabled" \
                          "APSSetLabeledEntryFrameState $w1.ulimits -state normal"] \
          -variable ${plane}ScalingMode -orientation vertical \
          -contextHelp \
          "Choose mode for vertical plot scale.  Variable autoscale finds appropriate scales for each page of the plot.  Fixed autoscale finds a single scale appropriate for all pages.  User-supplied does no autoscaling, but instead uses the values below, which you must enter."
        APSLabeledEntryFrame .ulimits -parent $w1 -label "Plot limits (mm): " \
          -variableList "${plane}UserLowerScale ${plane}UserUpperScale" \
          -orientation horizontal -width 6
        APSSetLabeledEntryFrameState $w1.ulimits -state disabled
    }
    APSButton .plot -parent $parent$widget.frame -width "" \
      -text "Plot" -command {OutputData -dataChoice $readbackChoice} \
      -contextHelp "Plots the chosen readback data."
    APSButton .output -parent $parent$widget.frame -width "" \
      -text "Export" -command {OutputData -dataChoice $readbackChoice -outputToFile 1}
}

proc FindPVDataFiles {args} {
    set ReadbackName ""
    set StartTime [clock scan "Jan 01 00:00:00 1990"]
    set EndTime [clock seconds]
    set startDateList ""
    set endDateList ""
    set SampleIntervals "1 2 4 8 16 32 64 128 256"
    APSStrictParseArguments {ReadbackName StartTime EndTime SampleIntervals startDateList endDateList}

    if {[llength $startDateList]} {
        set StartTime [clock scan "[lindex $startDateList 2]/[lindex $startDateList 3]/[lindex $startDateList 0]"]
    }
    if {[llength $endDateList]} {
        set EndTime [clock scan "23:59:59 [lindex $endDateList 2]/[lindex $endDateList 3]/[lindex $endDateList 0]"]
    }
    
    set fileList ""
    set ReadbackName [join [split $ReadbackName / ] + ]
    set year [clock format $StartTime -format %Y]
    set month [clock format $StartTime -format %m]
    set endyear [clock format $EndTime -format %Y]
    set endmonth [clock format $EndTime -format %m]
    while {($year < $endyear) || (($year == $endyear) && ($month <= $endmonth))} {
        append fileList "[lsort [glob -nocomplain /home/helios/oagData/logging/Variable/[string index ${ReadbackName} 0]/${ReadbackName}/log-${year}-${month}.{gz,xz}]] "
        append fileList "[lsort [glob -nocomplain /home/helios/oagData/logging/\{[join $SampleIntervals ,]\}/${ReadbackName}/log-${year}-${month}.{gz,xz,????}]] "
        if {$month == 12} {
            set month 01
            incr year
        } else {
            scan $month %d month
            incr month
            set month [format %02d $month]
        }
    }
    return $fileList
}

proc APSGatherOrbitData {args} {
    global review
    set readingType ""
    set startDateList ""
    set startHour 0
    set endDateList ""
    set endHour 24
    set minDCCT 0
    set maxDCCT 0
    set userBeamOnly 0
    set sparsingFactor 1
    set statusProc APSNoOp
    set outputFile ""
    set BPMList {A:P0 A:P1 A:P2 A:P3 A:P4 B:P5 B:P4 B:P3 B:P2 B:P1 B:P0}
    set sectorLowerLimit 0
    set sectorUpperLimit 0
    APSStrictParseArguments {readingType startDateList endDateList \
                               startHour endHour statusProc \
                               sectorLowerLimit sectorUpperLimit \
                               minDCCT maxDCCT userBeamOnly sparsingFactor \
                               outputFile BPMList}

   # if {$sectorLowerLimit==$sectorUpperLimit} {
    #    set sectorLowerLimit 1
    #    set sectorUpperLimit 40
    #}
    if $sectorLowerLimit<1 {
        set sectorLowerLimit 1
    }
    if $sectorUpperLimit>40 {
        set sectorUpperLimit 40
    }

    # find a list of all the files for the date range given
    set startTime \
      [exec timeconvert \
         -breakDown=year=[lindex $startDateList 0],julianDay=[lindex $startDateList 1],hour=$startHour]
    set endTime \
      [exec timeconvert \
         -breakDown=year=[lindex $endDateList 0],julianDay=[lindex $endDateList 1],hour=$endHour]
    
    set tag "$readingType,$startTime,$endTime,$minDCCT,$maxDCCT,$userBeamOnly,$sparsingFactor,[join $BPMList ,],$sectorLowerLimit,$sectorUpperLimit"
    set value [APSRetrieveTaggedValue -listID gatheredData -tag "$tag" -mustBeFile 1]
    if {[lindex $value 0]!=-1} {
        set filename [lindex $value 1]
        if {[string length $outputFile] && [string compare $outputFile $filename]!=0} {
            if [catch {exec cp $filename $outputFile} result] {
                return -code error "$result"
            }
            return $outputFile
        }
        return $filename
    }
    global dataRootname dataDir existingDataFile

    set dataFileList \
      [APSFindFilesBetweenDates -tailsOnly 0 \
         -rootname ${dataRootname}- \
         -directory $dataDir \
         -startDateList $startDateList -endDateList $endDateList]

    eval $statusProc {"[llength $dataFileList] files found"}
    if ![llength $dataFileList] {
        return ""
    }

    # create a temporary file with the required data in it.
    if [string length $outputFile] {
        set output $outputFile
    } else {
        set output /tmp/[APSTmpString]
        APSAddToTempFileList $output
    }
    if {[string compare $review SROrbit] == 0} {
#TODO: Update with proper filters for the APSU once the IOCs are online.
        set retain Time*,SRDesiredMode,S-DCCT:CurrentM
        for {set sector $sectorLowerLimit} {$sector<=$sectorUpperLimit} {incr sector} {
            set ssector [format %02d $sector]
            foreach item $BPMList {
                if [string length $readingType] {
                    set retain $retain,S${ssector}$item*${readingType}*
                } else {
                    set retain $retain,S${ssector}$item*x,S${sector}$item*y
                }
            }
        }
    } else {
        set retain Time*
        for {set sector $sectorLowerLimit} {$sector<=$sectorUpperLimit} {incr sector} {
            set ssector [format %02d $sector]
            foreach item $BPMList {
                set retain $retain,S$ssector$item$readingType
            }
        } 
    }
    set filterCmd "sddsprocess -nowarning -filter=column,TimeOfDay,0,24"
    if {$startTime<$endTime} {
        set filterCmd "$filterCmd -filter=column,Time,$startTime,$endTime"
    }
    if {$minDCCT<$maxDCCT} {
        set filterCmd "$filterCmd -filter=column,S-DCCT:CurrentM,$minDCCT,$maxDCCT"
    }
    if {$userBeamOnly==1} {
        set filterCmd "$filterCmd -filter=column,SRDesiredMode,0.5,2.5"
    }

    eval $statusProc {"Gathering data..."}
    if {$sparsingFactor<1} {
        set sparsingFactor 1
    }

    if [catch {eval exec sddscombine -merge $dataFileList -sparse=$sparsingFactor \
                 -retain=column,$retain -pipe=out \
                 | $filterCmd -pipe=in $output} result] {
        APSSetVarAndUpdate status "Processing problem: $result"
        return ""
    }
    if {[string compare $review SROrbit] == 0} {
        if [string length $readingType] {
            if {[catch {KeepXYPairs -filename $output -readingType $readingType} results]} {
                APSSetVarAndUpdate status "Processing problem: $result"
                return ""
            }
        }
    }
    
    APSAddToTagValueList -listID gatheredData -tag "$tag" -value $output
    return $output
}

proc KeepXYPairs {args} {
    set filename ""
    set readingType ""
    APSStrictParseArguments {filename readingType}
    if {[catch {exec sddsquery $filename -col} cols]} {
        return -code error $cols
    }
    set cols [lsort $cols]
    foreach "c" $cols {
        set len [expr [string length ${readingType}] ]
        if {[string compare x$readingType [string range $c end-${len} end]] == 0} {
            lappend xCols $c
        } elseif {[string compare y$readingType [string range $c end-${len} end]] == 0} {
            lappend yCols $c
        }
    }
    set filterCols ""
    foreach x $xCols {
        set len [expr 1 + [string length ${readingType}]]
        set i [string first [string range $x 0 end-$len] $yCols]
        if {$i == -1} {
            lappend filterCols $x
        }
    }
    foreach y $yCols {
        set len [expr 1 + [string length ${readingType}]]
        set i [string first [string range $y 0 end-$len] $xCols]
        if {$i == -1} {
            lappend filterCols $y
        }
    }
    if {[llength $filterCols]} {
        if {[catch {exec sddsconvert $filename -delete=column,[join $filterCols ,] -nowarn} results]} {
            return -code error $results
        }
        file delete ${filename}~
    }
}

proc APSOutputFileDialog {args} {
    set allowOverwrite 0
    set autoOverwrite 0
    set defaultDir ""
    APSStrictParseArguments {allowOverwrite autoOverwrite defaultDir}
    if $autoOverwrite {
        set allowOverwrite 1
    }

    set inputMessage "Enter output filename"
    while 1 {
        set outputFile \
          [APSInfoDialog [APSUniqueName .] \
             -name "File name dialog" -width 80 \
             -infoMessage $inputMessage -default $defaultDir]
        if ![string length $outputFile] {
            return ""
        }
        if ![file exists [file dirname $outputFile]] {
            set inputMessage "Directory [file dirname $outputFile] not found.  Enter another filename."
            continue
        }
        set defaultDir [file dirname $outputFile]
        if {[file exists $outputFile]} {
            if {!$allowOverwrite} {
                set inputMessage "$outputFile exists.  Enter another filename."
            } else {
                if {!$autoOverwrite} {
                    set choice [APSMultipleChoice [APSUniqueName .] \
                                  -question "$outputFile exists.  Overwrite?" \
                                  -labelList {Yes No Cancel} \
                                  -returnList {Yes No Cancel}] 
                } else {
                    set choice Yes
                }
                switch $choice {
                    Yes {
                        if [catch {exec rm -f $outputFile} result] {
                            set inputMessage "Couldn't remove $outputFile.  Enter another filename or nothing to cancel."
                        }
                        return $outputFile
                    }
                    No {
                        set inputMessage "$outputFile exists.  Enter another filename."
                    }
                    Cancel {
                        return ""
                    }
                }
            }
        } else {
            return $outputFile
        }
    }
}

proc OutputData {args} {
    global dataFileList minDCCT maxDCCT
    global StartMonth StartYear StartDay StartHour
    global EndMonth EndYear EndDay EndHour 
    global sparsingFactor sectorLowerLimit sectorUpperLimit
    global userBeamModeOnly bpmStatistics statisticsLimit
    global abscissaColumn review

    if {[string compare $abscissaColumn Time]!=0} {
        set bpmStatistics 0
    }

    # do some rounding of the input values so that when the
    # tags are made, they have a standardize format.
    set fixVarList {minDCCT maxDCCT StartMonth StartYear StartDay \
                      EndMonth EndYear EndDay sparsingFactor sectorLowerLimit sectorUpperLimit \
                      statisticsLimit}
    set fixVarPrecisionList {1 1 0 0 0 0 0 0 0 0 0 3}
    set index -1
    foreach var $fixVarList {
        incr index
        set $var [format "%.[lindex $fixVarPrecisionList $index]f" [set $var]]
    }
    update

    set dataChoice ""
    set outputToFile 0
    APSStrictParseArguments {dataChoice outputToFile}

    if [catch {APSConvertTimeToHours $StartHour} startHour] {
        APSSetVarAndUpdate status "Invalid starting hour: $StartHour"
        return
    }
    if [catch {APSConvertTimeToHours $EndHour} endHour] {
        APSSetVarAndUpdate status "Invalid ending hour: $EndHour"
        return
    }

    set allowDespiking 0

    if {[string compare $review SROrbit] == 0} {
        switch $dataChoice {
            LowPass1s {
                set msType ""
                set readingType :LowPass1sAdjustedM
            }
            LowPass8s {
                set msType ""
                set readingType :LowPass8sAdjustedM
            }
            LowPass64s {
                set msType ""
                set readingType :LowPass64sAdjustedM
            }
            Sampled {
                set msType ""
                set readingType :SampledM
            }
            SampledAdjusted {
                set msType ""
                set readingType :SampledAdjustedM
            }
            Position {
                set msType ""
                set readingType :PositionM
            }
            Offset {
                set msType ms
                set readingType :OffsetM
            }
            Setpoint {
                set msType ""
                set readingType :SetpointM
            }
            Gain {
                set msType ""
                set readingType :GainC
            }
            Error {
                set msType ""
                set readingType :ErrorM
                set allowDespiking 1
            }
            Unadjusted {
                set msType ""
                set readingType ""
                set allowDespiking 1
            }
            Adjusted {
                set msType ""
                set readingType :AdjustedM
                set allowDespiking 1
            }
            default {
                APSSetVarAndUpdate status "No data chosen!"
                return
            }
        }
    } else {
        set msType ""
        set readingType :PS:MeasCurrentM
    }

    set outputFile ""
    if $outputToFile {
        set outputFile [APSOutputFileDialog -allowOverwrite 1 \
                          -autoOverwrite 0]
        if ![string length $outputFile] {
            APSSetVarAndUpdate status "Output cancelled."
            return 
        }
    }

    set description "$StartYear/$StartMonth/$StartDay@$StartHour to $EndYear/$EndMonth/$EndDay@$EndHour "
    if {$minDCCT<$maxDCCT} {
        set description "$description $minDCCT to $maxDCCT mA "
    }
    if $userBeamModeOnly {
        set description "$description User Mode"
    }
    set description2 "Sparsing $sparsingFactor  Sectors $sectorLowerLimit to $sectorUpperLimit  "
    if $bpmStatistics {
        set description2 "$description2 Stat limit ${statisticsLimit}mm  "
    }
    APSSetVarAndUpdate status "Working..."
    global BPMVarList BPMTypeList
    set index -1
    set BPMList ""
    if {[string compare $review SROrbit] == 0} {
        foreach item $BPMVarList {
            incr index
            global $item
            if ![subst \$$item] continue
            lappend BPMList [lindex $BPMTypeList $index]
        }
    } else {
        foreach item $BPMVarList {
            incr index
            global $item
            if {[set $item] == 0} {continue}
            if {[lindex [lindex $BPMTypeList $index] 0] != ""} {
                lappend BPMList [lindex [lindex $BPMTypeList $index] 0]
            }
            if {[lindex [lindex $BPMTypeList $index] 1] != ""} {
                lappend BPMList [lindex [lindex $BPMTypeList $index] 1]
            }
        }
    }	
    if ![llength $BPMList] {
        APSSetVarAndUpdate status "No BPMs selected"
        return
    }
    set description2 "$description2  [join $BPMList ,]"
    set datafile [APSGatherOrbitData -readingType $readingType \
                    -statusProc "APSSetVarAndUpdate status" \
                    -startDateList [APSFormatDate -year $StartYear -month $StartMonth \
                                      -day $StartDay -dateFormat list] \
                    -startHour $startHour \
                    -endDateList [APSFormatDate -year $EndYear -month $EndMonth \
                                    -day $EndDay -dateFormat list] \
                    -endHour $endHour \
                    -minDCCT $minDCCT -maxDCCT $maxDCCT \
                    -sectorLowerLimit $sectorLowerLimit \
                    -sectorUpperLimit $sectorUpperLimit \
                    -userBeamOnly $userBeamModeOnly \
                    -sparsingFactor $sparsingFactor \
                    -BPMList $BPMList]
    if ![string length $datafile] {
        APSSetVarAndUpdate status "No data found."
        return
    }

    if $bpmStatistics {
        set tag "$StartYear/$StartMonth/$StartDay@$StartHour,$EndYear/$EndMonth/$EndDay@$EndHour,$minDCCT,$maxDCCT,$userBeamModeOnly,[join $BPMList ,],$sectorLowerLimit,$sectorUpperLimit,$sparsingFactor,$bpmStatistics,$statisticsLimit"
        set value [APSRetrieveTaggedValue -listID statData -tag "$tag" -mustBeFile 1]
        if [lindex $value 0]==-1 {
            if [string length $readingType] {
                set rT ${readingType}
            } else {
                set rT ""
            }
            set datafile1 /tmp/[APSTmpString]
            if $statisticsLimit<0 {
                set statisticsLimit [expr abs($statisticsLimit)]
            }
            if $statisticsLimit==0 {
                set statisticsLimit 100
            }
            set rowstatsOptions ""
            if {[string compare $review SROrbit] == 0} {
                foreach stat {MAD DRange QRange Largest} {
                    lappend rowstatsOptions -$stat=${msType}:x${rT}Change$stat,topLimit=$statisticsLimit,bottomLimit=-$statisticsLimit,*${msType}:x${rT}
                    lappend rowstatsOptions -$stat=${msType}:y${rT}Change$stat,topLimit=$statisticsLimit,bottomLimit=-$statisticsLimit,*${msType}:y${rT}
                }
                if [catch {eval exec sddsprocess $datafile -pipe=out \
                             -process=*${msType}:\\\[xy\\\]${rT},first,%sFirst \
                             {"-redefine=column,%s,%s %sFirst -,select=*${msType}:\[xy\]${rT}"} \
                             | sddsrowstats -pipe=in $datafile1 -nowarning $rowstatsOptions} result] {
                    APSSetVarAndUpdate status "$result"
                    return
                }
            } else {
                foreach stat {MAD DRange QRange Largest} {
                    lappend rowstatsOptions -$stat=H${rT}Change$stat,topLimit=$statisticsLimit,bottomLimit=-$statisticsLimit,*H*${rT}
                    lappend rowstatsOptions -$stat=V${rT}Change$stat,topLimit=$statisticsLimit,bottomLimit=-$statisticsLimit,*V*${rT}
                }
                if [catch {eval exec sddsprocess $datafile -pipe=out \
                             -process=*\\\[HV\\\]*${rT},first,%sFirst \
                             {"-redefine=column,%s,%s %sFirst -,select=*\[HV\]*${rT}"} \
                             | sddsrowstats -pipe=in $datafile1 $rowstatsOptions} result] {
                    APSSetVarAndUpdate status "$result"
                    return
                }
            }
            set datafile $datafile1
            APSAddToTagValueList -listID statData -tag "$tag" -value $datafile
        } else {
            set datafile [lindex $value 1]
        }
    }

    if !$outputToFile {
        if {[string compare $review SROrbit] == 0} {
            MakePlots -fileName $datafile -msType $msType -readingType $readingType \
              -plotStatistic $bpmStatistics \
              -allowDespiking $allowDespiking -topline "$description" \
              -title "$description2"
        } else {
            MakePlots -fileName $datafile -readingType $readingType \
              -plotStatistic $bpmStatistics \
              -allowDespiking 0 -topline "$description" \
              -title "$description2"
        }
    } else {
        if [catch {exec cp $datafile $outputFile} result] {
            APSSetVarAndUpdate status "$result"
            return
        }
    }
    APSSetVarAndUpdate status "Done."
}

proc MakePlots {args} {
    global plotDevice printerName labelSizeOption 
    global env plotTitle userPlotOptions
    global doHPlots doVPlots showChanges hScalingMode vScalingMode showPointLabel
    global hUserLowerScale hUserUpperScale vUserLowerScale vUserUpperScale
    global abscissaColumn
    global dataDir review xrefDir

    set fileName ""
    set msType mswAve
    set readingType :ErrorCC
    set allowDespiking 1
    set topline ""
    set title ""
    set plotStatistic Off
    set sectorLimits [list 1 40]
    APSStrictParseArguments {fileName title msType readingType allowDespiking topline plotStatistic title sectorLimits}
    if ![file exists $fileName] {
        return
    }

    if {[string compare $abscissaColumn s]==0 || 
        [string compare $abscissaColumn Sector]==0} {
        set collectedData /tmp/[APSTmpString]
        APSAddToTempFileList $collectedData
        set tag "$fileName,$msType,$readingType"
        set value [APSRetrieveTaggedValue -listID collectedData \
                     -tag $tag -mustBeFile 1]
        if [lindex $value 0]==-1 {
            APSSetVarAndUpdate status "Collecting data..."
            if [catch {APSSRCollectOrbitData -input $fileName -output $collectedData \
                         -msType $msType -readingType $readingType} result] {
                APSSetVarAndUpdate status $result
                return
            }
            APSSetVarAndUpdate status $sectorLimits
            set dataFile $collectedData
            APSAddToTagValueList -listID collectedData -tag "$tag" \
              -value $dataFile
        } else {
            set dataFile [lindex $value 1]
            set collectedData $dataFile
        }

        global hDespikeNeighbors hDespikeAverage hDespikePasses hDespikeThreshold hDespike
        global vDespikeNeighbors vDespikeAverage vDespikePasses vDespikeThreshold vDespike
        set hDespiked 0
        set vDespiked 0
        set pointLabel ""
        if $showPointLabel {
            set pointLabel -pointLabel=Rootname,edit=Z:
        }
        if {$allowDespiking && (($hDespike && $doHPlots) || ($vDespike && $doVPlots))} {
            set tag "$collectedData,$hDespikeNeighbors,$hDespikeAverage,$hDespikePasses,$hDespikeThreshold,$hDespike,$vDespikeNeighbors,$vDespikeAverage,$vDespikePasses,$vDespikeThreshold,$vDespike"
            set value [APSRetrieveTaggedValue -listID despikedData \
                         -tag "$tag" -mustBeFile 1]
            if [lindex $value 0]==-1 {
                set despikedData /tmp/[APSTmpString]
                APSAddToTempFileList $despikedData
                APSSetVarAndUpdate status "Despiking..."
                set hDespiked [expr $hDespike && $doHPlots] 
                set vDespiked [expr $vDespike && $doVPlots] 
                if [catch {APSSRDespikeOrbitData -input $collectedData -output $despikedData \
                             -msType $msType -readingType $readingType \
                             -hDespikeNeighbors $hDespikeNeighbors \
                             -hDespikeAverage $hDespikeAverage \
                             -hDespikePasses $hDespikePasses \
                             -hDespikeThreshold $hDespikeThreshold \
                             -hDespike $hDespiked \
                             -vDespikeNeighbors $vDespikeNeighbors \
                             -vDespikeAverage $vDespikeAverage \
                             -vDespikePasses $vDespikePasses \
                             -vDespikeThreshold $vDespikeThreshold \
                             -vDespike $vDespiked} result] {
                    APSSetVarAndUpdate status $result
                    return
                }
                set dataFile $despikedData
                APSAddToTagValueList -listID despikedData \
                  -tag "$tag" -value $dataFile
            } else {
                set dataFile [lindex $value 1]
            }
        }
        if $showChanges {
            set value [APSRetrieveTaggedValue -listID changeData \
                         -tag "$dataFile" -mustBeFile 1]
            if [lindex $value 0]==-1 {
                APSSetVarAndUpdate status "Computing changes..."
                if {[string compare $review SROrbit] == 0} {
                    if [catch {exec sddschanges $dataFile $dataFile.ch \
                                 -copy=s,Sector,Rootname -changesIn=*:*} result] {
                        return -code error $result
                    }
                } else {
                    if [catch {exec sddschanges $dataFile $dataFile.ch \
                                 -copy=s,Sector,Rootname -changesIn=*Current} result] {
                        if {[lrange $result end-5 end] == "number of rows in file changed"} {
                            APSSetVarAndUpdate status "No changes found"
                            return
                        }
                        return -code error $result
                    }
                }
                APSAddToTempFileList $dataFile.ch
                APSAddToTagValueList -listID changeData -tag "$dataFile" \
                  -value $dataFile.ch
                set dataFile $dataFile.ch
            } else {
                set dataFile [lindex $value 1]
            }
        }
    }

    if [string compare $plotDevice motif] {
        set commandTail "| lpr -P$printerName"
    } else {
        set commandTail ""
    }
    set title "$title $plotTitle"
    if {$doHPlots && $doVPlots} {
        set planes "h v"
        set HV H
        set xy x
    } elseif {$doHPlots} {
        set planes "h"
        set HV H
        set xy x
    } elseif {$doVPlots} {
        set planes "v"
        set HV V
        set xy y
    }
    foreach plane $planes {
        if [subst \$do[string toupper $plane]Plots] {
            switch [subst \$${plane}ScalingMode] {
                fixedAuto {
                    set scaleOption -samescales=y
                }
                variableAuto {
                    set scaleOption ""
                }
                userSupplied {
                    set scaleOption -scale=0,0,[subst \$${plane}UserLowerScale],[subst \$${plane}UserUpperScale]
                }
            }
            if {[string compare $abscissaColumn s]==0 || 
                [string compare $abscissaColumn Sector]==0} {
                set yLabelOption ""
                if [subst \$${plane}Despiked] {
                    set yLabelOption "-ylabel=edit=%/ms/Despiked:ms/"
                }
                if {[string compare $review SROrbit] == 0} {
                    eval exec sddsplot $pointLabel -title=@PageLabel $yLabelOption \
                      -sep=page -split=page $scaleOption \
                      {"-topline=[APSMakeSafeQualifierString $topline]"} \
                      $labelSizeOption \
                      -device=$plotDevice $dataFile $userPlotOptions \
                      -column=${abscissaColumn},*${msType}*${xy}${readingType} \
                      $commandTail &
                } else { 
                    eval exec sddsplot -match=parameter,Plane=${HV} $yLabelOption -title=@PageLabel \
                      -sep=page -split=page $scaleOption \
                      {"-topline=${HV}-Plane  [APSMakeSafeQualifierString $topline]"} \
                      $labelSizeOption \
                      -device=$plotDevice $dataFile $userPlotOptions \
                      -column=${abscissaColumn},Current \
                      $commandTail &		    
                }
            } else {
                # plots vs time
                set changesOption ""
                set yLabelOption ""
                set columnOption ""
                if !$plotStatistic {
                    if {[string compare $review SROrbit] == 0} {
                        if {0} {
                            if [catch {exec sddsquery $fileName -column -sddsOutput \
                                         | sddsprocess -pipe \
                                         -match=column,Name=*${msType}*${xy}${readingType} \
                                         -edit=column,BPMName,Name,S/:/3f100D \
                                         | sddsxref -nowarning -pipe $xrefDir/SRBPMPosition.xref \
                                         -match=BPMName -take=s \
                                         | sddssort -pipe -column=s \
                                         | sdds2stream -pipe -column=Name} columnList] {
                                return -code error "$columnList"
                            }
                        }
                        if [catch {exec sddsquery $fileName -column -sddsOutput \
                                     | sddsprocess -pipe \
                                     -match=column,Name=*${msType}*${xy}${readingType} \
                                     -edit=column,BPMName,Name,s/:/S/:/100D \
                                     | sddsxref -nowarning -pipe $xrefDir/SRBPMPosition.xref \
                                     -match=BPMName -take=s \
                                     | sddssort -pipe -column=s \
                                     | sdds2stream -pipe -column=Name} columnList] {
                            return -code error "$columnList"
                        }
                    } else {
                        if [catch {exec sddsquery $fileName -column -sddsOutput \
                                     | sddsprocess -pipe \
                                     -match=column,Name=*${HV}*$readingType \
                                     -edit=column,ElementName,Name,s/:/S/:/100D \
                                     | sddsxref -nowarning -pipe $xrefDir/SRCorrPosition.xref \
                                     -match=ElementName -take=s \
                                     | sddssort -pipe -column=s \
                                     | sdds2stream -pipe -column=Name} columnList] {
                            return -code error "$columnList"
                        }			
                    }
                    if $showChanges {
                        set changesOption -mode=y=offset
                        set yLabelOption {{-ylabel=edit=i/Change in /}}
                        set columnOption -column=Time,([join $columnList ,])
                    } else {
                        set columnOption -column=Time,([join $columnList ,])
                    }
                } else {
                    if {[string compare $review SROrbit] == 0} {
                        set columnOption -column=Time,*${xy}*Change*
                    } else {
                        set columnOption -column=Time,*${HV}*Change*
                    }
                }
                eval exec sddsplot -sep=page -split=page $scaleOption $changesOption $yLabelOption \
                  {"-topline=[APSMakeSafeQualifierString $topline]"} \
                  {"-title=[APSMakeSafeQualifierString $title]"} \
                  -device=$plotDevice $fileName $userPlotOptions -ticks=xtime \
                  $columnOption -sep=namestring -graph=dot \
                  $commandTail &
            }
        }
        set xy y
        set HV V
    }


    APSSetVarAndUpdate status "Plots launched."
}

proc APSSRCollectOrbitData {args} {
    global review dataDir xrefDir
    set input ""
    set output ""
    set msType mswAve
    set readingType :ErrorCC
    set startTime 0
    set endTime 0
    set sparsingFactor 1
    set sectorLimits [list 1 40]
    set minDCCT 0
    set maxDCCT 0
    set userBeamOnly 0
    APSStrictParseArguments {input output msType readingType startTime endTime \
                               sparsingFactor sectorLimits minDCCT maxDCCT userBeamOnly}
    if {![string length $input] || ![file exists $input]} {
        return -code error "APSSRCollectOrbitData: not found: $input"
    }
    if ![string length $output] {
        return -code error "APSSRCollectOrbitData: no output file named."
    }
    if {$startTime<$endTime || $sparsingFactor>1 || $minDCCT<$maxDCCT || $userBeamOnly==1} {
        set filterCmd "sddsprocess -pipe=out -nowarning $input"
        if {$startTime<$endTime} {
            set filterCmd "$filterCmd -filter=column,Time,$startTime,$endTime"
        }
        if {$sparsingFactor>1} {
            set filterCmd "$filterCmd {-test=column,i_row SparsingFactor / = int - 0 ==}"
        }
        if {$minDCCT<$maxDCCT} {
            set filterCmd "$filterCmd -filter=column,S-DCCT:CurrentM,$minDCCT,$maxDCCT"
        }
        if {$userBeamOnly==1} {
            set filterCmd "$filterCmd -filter=column,SRDesiredMode,0.5,2.5"
        }
    } else {
        set filterCmd "cat $input"
    }
    if {[string compare $review SROrbit] == 0} {
        if [catch {eval exec $filterCmd \
                     | sddscollect -pipe \
                     -collect=suffix=:x${readingType},column=:x${readingType} \
                     -collect=suffix=:y${readingType},column=:y${readingType}  \
                     | sddsxref -nowarning -pipe $xrefDir/SRBPMPosition.xref -take=s,Sector \
                     -reuse=page -match=Rootname=BPMName \
                     | sddssort -pipe -column=s \
                     | sddstimeconvert -pipe -breakdown=parameter,Time,text=TimeText \
                     | sddsprocess -pipe=in $output -nowarning \
                     {"-filter=column,Sector,[lindex $sectorLimits 0],[expr [lindex $sectorLimits 1] + 1]"} \
                     {"-print=parameter,PageLabel,%s %.1fmA,TimeText,S-DCCT:CurrentM"} } result] {
            return -code error "APSSRCollectOrbitData1: $result"
        }
    } else {
        set tmpfile /tmp/[APSTmpString]
        if {[catch {eval exec $filterCmd \
                      | sddsconvert -pipe=in $tmpfile \
                      -editNames=column,*H*PS:MeasCurrentM,%/PS:MeasCurrentM/HCurrent/ \
                      -editNames=column,*V*PS:MeasCurrentM,%/PS:MeasCurrentM/VCurrent/ } result]} {
            return -code error "APSSRCollectOrbitData2: $result"
        }
        if {[catch {exec sddscollect -nowarnings $tmpfile -pipe=out -collect=suffix=:HCurrent,column=Current \
                  | sddsprocess -pipe=in $tmpfile.1 -retain=parameter,Time -print=parameter,Plane,H} result]} {
            return -code error "APSSRCollectOrbitData2: $result"
        }
        if {[catch {exec sddscollect -nowarnings $tmpfile -pipe=out -collect=suffix=:VCurrent,column=Current \
                  | sddsprocess -pipe=in $tmpfile.2 -retain=parameter,Time -print=parameter,Plane,V} result]} {
            return -code error "APSSRCollectOrbitData2: $result"
        }
        if {[catch {eval exec sddscombine $tmpfile.1 $tmpfile.2 -pipe=out \
                      | sddsxref -nowarning -pipe $xrefDir/SRCorrPosition.xref \
                      -take=s,Sector -reuse=page -match=Rootname=ElementName \
                      | sddssort -pipe -columns=s \
                      | sddstimeconvert -pipe -breakdown=parameter,Time,text=TimeText \
                      | sddsprocess -pipe=in $output -nowarning \
                      {"-filter=column,Sector,[lindex $sectorLimits 0],[expr [lindex $sectorLimits 1] + 1]"} \
                      {"-print=parameter,PageLabel,%s,TimeText"}} result]} {
            return -code error "APSSRCollectOrbitData2: $result"
        }
        file delete $tmpfile $tmpfile.1 $tmpfile.2 $tmpfile.3
    }
    APSSetVarAndUpdate status "APSCollectOrbitData done"
}

proc APSSRDespikeOrbitData {args} {
    set hDespikeNeighbors 36
    set hDespikeAverage 4
    set hDespikePasses 2
    set hDespikeThreshold 0.02
    set hDespike 1
    set vDespikeNeighbors 36
    set vDespikeAverage 4
    set vDespikePasses 2
    set vDespikeThreshold 0.02
    set vDespike 1
    set input ""
    set output ""
    set msType mswAve
    set readingType :ErrorCC
    APSStrictParseArguments {hDespikeNeighbors hDespikeAverage hDespikePasses hDespikeThreshold \
                               hDespike vDespikeNeighbors vDespikeAverage vDespikePasses \
                               vDespikeThreshold vDespike input output msType readingType}
    if {![string length $input] || ![file exists $input]} {
        return -code error "APSSRDespikeOrbitData: not found: $input"
    }
    if ![string length $output] {
        return -code error "APSSRDespikeOrbitData: no output file named."
    }

    if {!$hDespike && !$vDespike} {
        if [catch {exec cp $input $output} result] {
            return -code error "APSSRDespikeOrbitData: $result"
        }
        return
    }

    set xy x
    foreach plane {h v} {
        if [subst \$${plane}Despike] {
            lappend ${plane}OptionList -columns=*${msType}:${xy}${readingType}
            lappend ${plane}OptionList -despike=neighbors=[subst \$${plane}DespikeNeighbors],passes=[subst \$${plane}DespikePasses],averageOf=[subst \$${plane}DespikeAverage],threshold=[subst \$${plane}DespikeThreshold]
        }
        set xy y
    }

    if {$hDespike && $vDespike} {
        if [catch {eval exec sddssmooth $input -pipe=out $hOptionList -pass=0 \
                     | sddssmooth -pipe=in $output $vOptionList -pass=0} result] {
            return -code error "APSSRDespikeOrbitData: $result"
        }
    } elseif {$hDespike} {
        if [catch {eval exec sddssmooth $input $output $hOptionList -pass=0} result] {
            return -code error "APSSRDespikeOrbitData: $result"
        }
    } else {
        if [catch {eval exec sddssmooth $input $output $vOptionList -pass=0} result] {
            return -code error "APSSRDespikeOrbitData: $result"
        }
    }
}

proc MakePlotControls {widget args} {
    global plotDevice 
    global printerName labelSizeOption env groupMode plotTitle userPlotOptions
    set plotDevice motif
    set sameScaleY 0
    set layoutChoice -layout=1,1
    set labelSizeOption -labelsize=0.02
    set groupMode sector
    set plotTitle ""
    set userPlotOptions "-axes=x -grap=sym,fil,conn,sca=2"
    if [info exists env(PRINTER)] {
        set printerName $env(PRINTER)
    } else {
        set printerName mcr1
    }

    set parent "" 
    APSStrictParseArguments {parent}

    APSFrame $widget -parent $parent -label "Plot controls"
    set parent $parent$widget.frame

    APSFrameGrid .grid -parent $parent \
      -width 10 \
      -xList {x1 x2}
    
    APSRadioButtonFrame .labelsize -parent ${parent}.grid.x1 \
      -label "Label size" -orientation vertical -variable labelSizeOption \
      -buttonList {normal +15% +30% +45% +60%} \
      -valueList {-labelsize=0.02 -labelsize=0.023 -labelsize=0.026 -labelsize=0.029 -labelsize=0.032} \
      -contextHelp "For layouts with many panels, the labels may be hard to read.  You can increase the size of the labels using these options."
    APSRadioButtonFrame .device  -parent ${parent}.grid.x2 \
      -label Device -orientation vertical \
      -variable plotDevice \
      -buttonList {X-windows "B&W Postscript" "Color Postscript"} \
      -valueList {motif postscript cpostscript} \
      -contextHelp "Choose the plotting device.  Postscript is for delivery to a printer only."
    
    APSLabeledEntry .printer -parent $parent \
      -label "Printer: " -textVariable printerName -width 40
    APSLabeledEntry .title -parent $parent \
      -label "Title: " -textVariable plotTitle -width 40 \
      -contextHelp "Enter a text string to be used as a plot title."
    APSLabeledEntry .extra -parent $parent \
      -label "Extra options: " -textVariable userPlotOptions -width 40 \
      -contextHelp "Enter sddsplot options to be used for plotting."
}


set dataFileList ""
set dataFileListIsOld 1
set doHPlots 1
set doVPlots 1
set hScalingMode fixedAuto
set vScalingMode fixedAuto
set abscissaColumn Sector
set sparsingFactor 1
set sectorLowerLimit 1
set sectorUpperLimit 40
set existingDataFile ""
set status "Ready."
set minDCCT 0
set maxDCCT 0
set userBeamModeOnly 0
set readbackChoice Error
set showChanges 0
set showPointLabel 0
set bpmStatistics 0
set statisticsLimit 100


proc startSROrbitReview {} {
    global hUserLowerScale hUserUpperScale vUserLowerScale vUserUpperScale CVSRevisionAuthor\
      BPMLabelList BPMTypeList BPMVarList dataDir dataRootname xrefDir OAGGlobal

    #This is just temporary until the APSU starts
    if {[llength [glob -nocomplain /home/helios/oagData/logging/srBPMAve.test/srBPMAve-[clock format [clock seconds] -format "%Y-%j"]-*]] > 0} {
        set dataDir /home/helios/oagData/logging/srBPMAve.test
    } else {
        set dataDir /home/helios/oagData/logging/srBPMAve
    }
    set dataRootname srBPMAve
    
    APSApplication . -name SROrbitReview -version $CVSRevisionAuthor \
      -overview "Shows storage ring orbit data in graphical form\
	    as a function of position around the ring."
    
    set xrefDir $OAGGlobal(SRLatticesDirectory)/scripts
    APSScrolledStatus .status -parent .userFrame -textVariable status -width 80 \
      -height 5 -packOption "-fill x -expand true" -noPack 1
    pack configure .userFrame.status.frame -fill both -expand true
    set hUserLowerScale -0.1
    set hUserUpperScale 0.1
    set vUserLowerScale -0.1
    set vUserUpperScale 0.1
    set BPMLabelList {AP0 AP1 AP2 AP3 AP4 AP5 AP6 BP6 BP5 BP4 BP3 BP2 BP1 BP0 CP0}
    set BPMTypeList {A:P0 A:P1 A:P2 A:P3 A:P4 A:P5 A:P6 B:P6 B:P5 B:P4 B:P3 B:P2 B:P1 B:P0 C:P0}
    foreach item $BPMLabelList {
        global doPlot$item
        set doPlot$item 1
        lappend BPMVarList doPlot$item
    }
    APSFrameGrid .fg -parent .userFrame -xList {left right} -noPack 1
    MakePlotControls .plotcontrol -parent .userFrame.fg.right
    MakeSmoothWidget .smooth -parent .userFrame.fg.right
    MakeDateTimeFrame .date -parent .userFrame.fg.right
    MakeFilterFrame .filter -parent .userFrame.fg.right
    MakeButtonRow .ops -parent .userFrame.fg.left
    grid .userFrame.status -column 0 -row 0 -sticky nsew
    grid .userFrame.fg -column 0 -row 1 -sticky nsew
    grid rowconfigure .userFrame 0 -weight 1
    grid columnconfigure .userFrame 0 -weight 1
    update
}

proc startSRCorrectorReview {} {
    global hUserLowerScale hUserUpperScale vUserLowerScale vUserUpperScale CVSRevisionAuthor\
      BPMLabelList BPMTypeList BPMVarList dataDir dataRootname xrefDir OAGGlobal
    set dataDir /home/helios/oagData/logging/SRDCPS-HVD
    set dataRootname SRDCPS-HVD
    
    APSApplication . -name SRCorrectorReview -version $CVSRevisionAuthor \
      -overview "Shows storage ring corrector data in graphical\
	    form as a function of position around the ring.  Allows\
	    computation of the orbit change that would result from\
	    action of the correctors alone."
    set xrefDir $OAGGlobal(SRLatticesDirectory)/scripts
    
    
    APSScrolledStatus .status -parent .userFrame -textVariable status -width 60 \
      -height 5 -packOption "-fill x -expand true" -noPack 1
    pack configure .userFrame.status.frame -fill both -expand true
    set hUserLowerScale -1
    set hUserUpperScale 1
    set vUserLowerScale -1
    set vUserUpperScale 1
    set BPMLabelList {A:\[HV\]1 A:\[HV\]7 A:V8 B:V8 B:\[HV\]7 B:\[HV\]1 C:\[HV\]2 A:F\[HV\]1 A:F\[HV\]2 B:F\[HV\]2 B:F\[HV\]1}
    set BPMTypeList {"A:H1 A:V1" "A:H7 A:V7" "{} A:V8" "{} B:V8" "B:H7 B:V7" "B:H1 B:V1" "C:H2 C:V2" "A:FH1 A:FV1" "A:FH2 A:FV2" "B:FH2 B:FV2" "B:FH1 B:FV1"}
#    set BPMLabelList {A1 A7 A8 B8 B7 B1 C2}
#    set BPMTypeList {"A:H1 A:V1" "A:H7 A:V7" "A:V8" "B:H8" "B:H7 B:V7" "B:H1 B:V1" "C:H2 C:V2"}
#    set BPMLabelList {A1 A2 A3 A4 B5 B4 B3 B2 B1 C1}
#    set BPMTypeList {"A:H1 A:V1" "A:H2 A:V2" "A:H3 A:V3" "A:H4 A:V4" "B:H5 B:V5" "B:H4 B:V4" "B:H3 B:V3" "B:H2 B:V2" "B:H1 B:V1" "C:H1 C:V1"}
    foreach item $BPMLabelList {
        global doPlot$item
        set doPlot$item 1
        lappend BPMVarList doPlot$item
    }
    set doPlotC:\[HV\]2 0
    APSFrameGrid .fg -parent .userFrame -xList {left right} -noPack 1
    MakePlotControls .plotcontrol -parent .userFrame.fg.right
    MakeDateTimeFrame .date -parent .userFrame.fg.right
    MakeButtonRow .ops -parent .userFrame.fg.left -label1 PS: -label2 A
    grid .userFrame.status -column 0 -row 0 -sticky nsew
    grid .userFrame.fg -column 0 -row 1 -sticky nsew
    grid rowconfigure .userFrame 0 -weight 1
    grid columnconfigure .userFrame 0 -weight 1    
    update

}

#check the command line arguments
set args $argv
set review ""
APSStrictParseArguments {review}
# note that when reviewing correctors, the variables
# BPMLabelList BPMTypeList take on values of corrector names.
if {[string compare $review SRCorrector] == 0} {
    startSRCorrectorReview
} else {
    set review SROrbit
    startSROrbitReview
}
