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

# $Log: not supported by cvs2svn $
# Revision 1.54 2012/07/24  Shang
# added B:IK system which is a subset of par scope (P:DO1), the purpose is to separate it from par scope signals, requested by Stan Pasky.
#
# Revision 1.53  2010/03/30 17:02:17  shang
# removed shang's private library
#
# Revision 1.52  2010/03/30 17:01:18  shang
# removed printing statements
#
# Revision 1.51  2010/03/30 16:44:54  shang
# added "make references" button
#
# Revision 1.50  2009/03/09 14:50:02  shang
# modified the save signal command so that the filename is update at the time the "save" button is clicked.
#
# Revision 1.49  2009/03/03 19:00:41  shang
# modified to allow collecting data of the muxes that are not included in the category file.
#
# Revision 1.48  2009/03/03 16:16:37  shang
# added logging the scalar PVs for the corresponding muxes as parameters in the output file, and fixed the problem that the output file was overwritten when saving signals if using the same save widget.
#
# Revision 1.47  2009/02/25 17:33:30  shang
# added recording the values of P1IK, P2IK and P4EK delays as parameters in the signal file.
#
# Revision 1.46  2009/01/13 20:24:15  soliday
# Updated to print an error message if the scope does not respond
# to commands instead of crashing.
#
# Revision 1.45  2008/12/17 19:02:09  shang
# added save/restore samples points to scope setup
#
# Revision 1.44  2008/09/19 16:29:26  soliday
# Updated so that the screen does not blow away if the scope PVs can't be read.
#
# Revision 1.43  2008/07/18 18:56:08  borland
# Added preferred-file feature for configuration files.
#
# Revision 1.42  2008/01/21 20:55:55  shang
# added more scope parameters to the output file and added interpolation for less points per division data in review.
#
# Revision 1.41  2002/03/04 14:42:34  borland
# Fixed conversion problem with V -> V/Div.
#
# Revision 1.40  2002/01/21 16:19:59  borland
# Removed special code that cut off the last half of saved PAR waveforms.
# For some reason, it isn't needed now.
#
# Revision 1.39  2001/07/29 23:06:13  borland
# For PAR scope, now remove last half of the waveform record, due to problems
# with the waveform download.
#
# Revision 1.38  2000/10/19 14:58:01  borland
# Supports L1:SCOPE1 more fully (the mux works differently).
#
# Revision 1.37  2000/02/29 22:32:29  borland
# Now works even if the MUX file is empty.
#
# Revision 1.36  1999/12/13 15:09:07  borland
# Modified entry box label for Y2K (YY->YYYY).
#
# Revision 1.35  1999/12/13 15:04:48  borland
# Changed date +%y to date +%Y (Y2K compliant).
#
# Revision 1.34  1999/07/26 00:19:40  borland
# Now allows additional PVs in the mux request file and snapshot.  This supports
# addition of the FCT attenuator to the SR scope request file.
#
# Revision 1.33  1999/04/09 13:31:07  borland
# Restored use of -collapse option on sddscombine following fix to sddscombine.
#
# Revision 1.32  1999/04/07 16:15:02  borland
# Removed use of sddscombine collapse option as it results in an error when
# combining .sig files.
#
# Revision 1.31  1998/12/02 16:44:10  soliday
# Replaced sddscollapse with -collapse option in sddscombine.
#
# Revision 1.30  1998/08/03 16:10:37  borland
# Added the -attach option to "exec medm" commands.
#
# Revision 1.29  1998/01/13 08:22:58  emery
# Fixed adlFileScopeWF variable names in proc MakeDisplaysMenu.
#
# Revision 1.28  1998/01/11 20:09:58  borland
# Added L1:SCOPE1, plus made some changes to allow a scope with
# empty mux and signal list files.
#
# Revision 1.27  1998/01/06 21:22:33  borland
# Fixed problems with medm commands (ADL files were moved).
#
# Revision 1.26  1997/06/09 18:26:45  borland
# Added APSDebugPath, and moved APSStandardSetup near top of script to
# avoid problems getting script name (due to 'cd' in script).
#
# Revision 1.25  1997/04/24 20:33:19  borland
# Trivial change: added an error message.
#
# Revision 1.24  1997/03/28 15:46:47  borland
# No longer prints blank message for 4-channel scope when refreshing.
#
# Revision 1.23  1997/03/28 15:19:33  borland
# Now more tolerant of errors in restoring mux configuration and finding
# signals names for review.
#
# Revision 1.22  1997/03/28 15:12:31  borland
# Now blunders on even if the mux can't be restored.
#
# Revision 1.21  1997/03/28 15:04:21  borland
# Modified to support 5 channel MUX for PAR scope (added trigger channel).
#
# Revision 1.20  1997/03/27 23:03:47  borland
# Now correctly writes to user specified directory.
#
# Revision 1.19  1997/02/20 21:33:51  borland
# Supports extra request file for scope save and restoring of snapshot made
# from the request file.
#
# Revision 1.18  1997/02/20 19:22:22  borland
# Added local memory save/recall feature with workstation storage of
# mux settings and description.
#
# Revision 1.17  1997/02/19 02:28:44  borland
# Added menu entries for peak detect mode and bringing up related
# displays.
#
# Revision 1.16  1997/01/21 21:46:15  borland
# Tested and debugged support for S:DO1 scope.
#
# Revision 1.15  1997/01/16 16:59:07  borland
# Added 25MSa/s rate.
#
# Revision 1.14  1996/12/13 18:18:59  borland
# Added provision for commandline switching of which scope to use.
#
# Revision 1.13  1996/09/19 21:51:28  borland
# Changed from using "exec wish" to "exec oagwish".
#
# Revision 1.12  1996/09/05 14:20:53  borland
# Added catch statements around most sendScopeCommand calls to better
# deal with errors in accessing the scope.
#
# Revision 1.11  1996/08/15 14:08:45  borland
# Fixed bugs in description searches for review and restore (problem if
# spaces appeared in string).  Changed search matching to case-insensitive.
#
# Revision 1.10  1996/07/06  17:36:23  borland
# Removed dependencies on borland account.  All data in oagData
# area now.
#
# Revision 1.9  1996/05/17  20:51:58  borland
# Replaced status lines with scrolled status widgets.
#
# Revision 1.8  1996/05/17  20:36:04  borland
# Added sddsplot options and data export features to review facility.
#
# Revision 1.7  1996/03/04  20:14:13  saunders
# Added revision/author to Version menu.
#
# Revision 1.6  1996/01/17  16:59:25  saunders
# Added /usr/local/oag/lib_patch to front to auto_path.
#
# Revision 1.5  1996/01/16  21:11:57  saunders
# Fixed log entry problem, so now comments and version numbers
# appear properly. Also, renames X.tcl files to just X.
#
# Revision 1.4  1996/01/12 22:36:38  saunders
# Removing dependence on ~borland/tcl/rel auto_path entry. There are still
# references to personal directories. Also fixed minor bugs as encountered.
#
# Revision 1.3  1995/12/15  20:12:29  saunders
# Added proper installation Makefile and Log
#

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


set CVSRevisionAuthor "\$Revision: 1.54 $ \$Author: shang $"

set args $argv
set scopeID P:HP9000
#new=1, the scope configuration will be saved into *_new directory, which is saved by phython socket
set new 1
APSStrictParseArguments {scopeID new}

#add new variable ScopeID for new scope HP9000 which save/restore and scope commands are different from others
#but some commands are the same as P:DO1 (like mux command)
set ScopeID $scopeID
set ring PAR
set cateFile ""
set scalarFile ""
set referenceList ""
switch $scopeID {
    P:DO1 -
    P:HP9000 -
    B:IK {
        set auxFilesDir /home/helios/oagData/par/scope
        set systemDataDir /home/helios/oagData/par/scope/$scopeID:Data
        set muxReqFile /home/helios/oagData/par/scope/PDO1mux.req
        set cateFile  /home/helios/oagData/par/scope/scopeCategory.sdds
        set scalarFile  /home/helios/oagData/par/scope/scopeScalars.sdds
        set windowTitle "PAR Scope $scopeID Save/Restore"
        set fixWfs 0
        set channelName parscopechan
        switch $scopeID {
            P:DO1 {
                set referenceList "EKs ES IKs IS RF12 RF1+RF12-ext"
            }
            B:IK {
                #B:IK is just a special setup of Par scope for reading B:IK trigger waveforms
                set referenceList "BIK"
                set scopeID P:DO1
            }
            P:HP9000 {
               # set scopeID P:DO1
            }
        }
        set ring PAR
    }
    S:DO1 -
    S:HP9000 {
        set auxFilesDir /home/helios/oagData/sr/scope
        set systemDataDir /home/helios/oagData/sr/scope/${scopeID}:Data
        set muxReqFile /home/helios/oagData/sr/scope/SDO1mux.req
        set cateFile /home/helios/oagData/sr/scope/scopeCategory.sdds
        set scalarFile /home/helios/oagData/sr/scope/scopeScalars.sdds
        set windowTitle "SR Scope $scopeID Save/Restore"
        set fixWfs 0
        set channelName srscopechan
        set referenceList "IK IS1 IS2 StoredBeamICT StoredBeamRF TopUpIK"
        set ring SR

    }
    L1:SCOPE1 {
        set auxFilesDir /home/helios/oagData/linac/scope
        set systemDataDir /home/helios/oagData/linac/scope/$scopeID:Data
        set muxReqFile /home/helios/oagData/linac/scope/L1SCOPE1mux.req
        set windowTitle "LINAC L1:SCOPE1 Save/Restore"
        set fixWfs 0
        set ring Linac
    }
    default {
    }
}
if {[regexp {HP9000} $scopeID]} {
    if $new {
        set  systemDataDir /home/helios/oagData/[string tolower $ring]/scope/${scopeID}:Data_New
        set hp9000ScopeCommand /home/oxygen/SHANG/oag/apps/src/pythonapp/hp9000ScopeSocketCommand 
    } else {
        set hp9000ScopeCommand /home/oxygen/SHANG/oag/apps/src/tcltkapp/oagapp/sendHP9000ScopeCommand
    }
}


catch {exec sddsprocess $muxReqFile -pipe=out -match=col,ChannelName=,! -nowarning | sdds2stream -pipe -column=ChannelName } channelNameList
catch {exec sddsprocess $muxReqFile -pipe=out -match=col,ChannelName=,! -nowarning | sdds2stream -pipe -column=ControlName } channelPVList
set channelPVs [llength $channelPVList]

set origDir [pwd]
set dataDir $systemDataDir
cd $systemDataDir

set mainStatus ""
set refreshTime ""

proc SetMainStatus {text} {
    global mainStatus
    set mainStatus $text
    update
}

proc RefreshChannelData {} {
    global signalName signalState scopeID refreshTime
    global channelPVList channelNameList channelPVs
    SetMainStatus "Refresh in progress..."
    if $channelPVs {
        if [string compare $scopeID L1:SCOPE1]==0 {
            set tmpFile /tmp/[APSTmpString]
            APSAddToTempFileList $tmpFile $tmpFile.1
            if [catch {exec burtrb -f ../L1SCOPE1mux.req -o $tmpFile} result] {
                SetMainStatus "Error: $result"
                return
            }
            if [catch {exec sddssort $tmpFile -column=ControlName -pipe=out \
                         | sddsprocess -pipe=in "-reedit=col,ValueString,10%/\"//100%/ //" $tmpFile.1 
                sdds load $tmpFile.1 data} result] {
                SetMainStatus "Error: $result"
                return
            }
            set sigList [lindex $data(Column.ValueString) 0]
            for {set i 0} {$i<$channelPVs} {incr i} {
                set chan [expr $i+1]
                SetMainStatus "Channel [lindex $channelNameList $i]"
                if $i!=4 {
                    if [catch {exec sendScopeCommand $scopeID ":CHAN${chan}:DISP?"} result] {
                        SetMainStatus "Error: $result"
                    }
                } else {
                    set result 1
                }
                if {$result==1} {
                    set signalState($i) ON
                } else {
                    set signalState($i) OFF
                }
                set signalName($i) [lindex $sigList $i]
            }
        } else {
            set fin [open {|sddssnapshot signalXref.sdds -pipe=out \
                             | sddsprocess -pipe "-test=col,Value MuxSetting =="  \
                             | sdds2stream -col=SignalName -pipe } r]
            SetMainStatus "Took snapshot of signal state."
            for {set i 0} {$i<$channelPVs} {incr i} {
                set chan [expr $i+1]
                SetMainStatus "Channel [lindex $channelNameList $i]"
                if $i!=4 {
                    if {![regexp HP9000 $scopeID]} {
                        if [catch {exec sendScopeCommand $scopeID ":CHAN${chan}:DISP?"} result] {
                            SetMainStatus "Error: $result"
                        }
                    } else {
                        set result 1
                    }
                } else {
                    set result 1
                }
                if {$result==1} {
                    set signalState($i) ON
                } else {
                    set signalState($i) OFF
                }
                if {[eof $fin]} {
                    set signalName($i) "?"
                } else {
                    gets $fin signalName($i)
                }
            }
            close $fin
        }
    } else { 
        for {set i 0} {$i<4} {incr i} {
            set chan [expr $i+1]
            if $i!=4 {
                if {![regexp HP9000 $scopeID]} {
                    if [catch {exec sendScopeCommand $scopeID ":CHAN${chan}:DISP?"} result] {
                        SetMainStatus "Error: $result"
                    }
                } else {
                    set result 1
                }
            } else {
                set result 1
            }
            if {$result==1} {
                set signalState($i) ON
            } else {
                set signalState($i) OFF
            }
            set signalName($i) "?"
        }
    }
    SetMainStatus "Refresh done"
    set refreshTime [exec date +%a\ %H:%M:%S]
}

proc RefreshSettings {} {
    global SampleString Clock Delay scopeID TimeDiv ring scopeCommand hp9000ScopeCommand
    
    if {![regexp HP9000 $scopeID]} {
        if [catch {exec sendScopeCommand $scopeID ":TIM:RLEN?"} SampleString] {
            SetMainStatus "Error1a: $SampleString"
        }
        if [catch {exec sendScopeCommand $scopeID ":TIM:SAMP:CLOCK?"} Clock] {
            SetMainStatus "Error2a: $Clock"
        }
        if [catch {exec sendScopeCommand $scopeID ":TIM:DELAY?"} Delay] {
            SetMainStatus "Error3a: $Delay"
        }
        if [catch {exec sendScopeCommand $scopeID ":TIM:RANG?"} TimeDiv] {
            SetMainStatus "Error4a: $TimeDiv"
        } else {
            set TimeDiv [string trim $TimeDiv]
            if {![string length $TimeDiv] || ![string is double $TimeDiv]} {
                SetMainStatus "Error5a: scope not responding to commands"
                bell
            } else {
                set TimeDiv [GetTimeDivLabel $TimeDiv]
            }
        }
    } else {
        
        if [catch {eval exec $hp9000ScopeCommand -ring $ring -command  ":ACQ:POINTs?"} SampleString] {
            SetMainStatus "Error1a: $SampleString"
        }  
        if [catch {eval exec $hp9000ScopeCommand -ring $ring -command  ":ACQ:SRAT:ANAL?"} Clock] {
            SetMainStatus "Error1: $Clock"
        }
        if [catch {eval exec $hp9000ScopeCommand -ring $ring -command  ":TIM:DELAY?"} Delay] {
            SetMainStatus "Error2: $Delay"
        }
        set TimeDiv ""
        if [catch {eval exec $hp9000ScopeCommand -ring $ring -command  ":TIM:RANG?"} TimeDiv] {
            #if [catch {exec ~shang/oag/apps/src/tcltkapp/oagapp/sendHP9000ScopeCommand -ring $ring -command  ":TIM:RANG?"} TimeDiv] {
            #    SetMainStatus "Error3: $TimeDiv"
            #    set TimeDiv ""
            #}
            SetMainStatus "Error3: $TimeDiv"
        } 
        if [string length $TimeDiv] {
            set TimeDiv [string trim $TimeDiv]
            if {![string length $TimeDiv] || ![string is double $TimeDiv]} {
                SetMainStatus "Error4: scope not responding to commands"
                bell
            } else {
                set TimeDiv [GetTimeDivLabel $TimeDiv]
            }
        }
    }
    RefreshChannelData
    #        after 10000 RefreshSettings
}

proc MakeTimebaseMenu {parent} {
    APSMenubarAddMenu .tb -text "Timebase" -parent $parent 
    $parent.tb.menu add cascade -label "Samples" -menu ${parent}.tb.menu.rlen
    $parent.tb.menu add cascade -label "Rate"  -menu $parent.tb.menu.clock
    $parent.tb.menu add cascade -label "Time/div" -menu $parent.tb.menu.tdiv
    SetMainStatus "make rec len menu..."
    MakeRecLenMenu $parent.tb.menu
    SetMainStatus "make clock menu..."
    MakeClockRateMenu $parent.tb.menu
    SetMainStatus "make div menu..."
    MakeTimeDivMenu $parent.tb.menu
}

proc MakePeakDetectMenu {parent} {
    global scopeID PeakDect
    APSMenubarAddMenu .pdet -text "PeakDetect" -parent $parent 
    set w $parent.pdet.menu
    $w add command -label "On" -command \
      "exec sendScopeCommand $scopeID \":ACQ:TYPE PDETECT\""
    $w add command -label "Off" -command \
      "exec sendScopeCommand $scopeID \":ACQ:TYPE NORM\""
}

proc MakeSaveLocalMenu {parent} {
    global scopeID
    APSMenubarAddMenu .save -text "Save-Local" -parent $parent 
    set w $parent.save.menu
    for {set num 1} {$num<10} {incr num} {
        $w add command -label "Setup $num" -command \
          "DoLocalSave -setup $num"
    }
}

proc DoLocalSave {args} {
    global signalName env scopeID systemDataDir
    global muxReqFile

    set setup -1
    APSStrictParseArguments {setup}
    set comment \
      [APSInfoDialog [APSUniqueName .] -name "Local save dialog" \
         -infoMessage "Enter a descriptive comment for the configuration" \
         -width 80]
    if ![string length $comment] {
        SetMainStatus "Save cancelled."
        return
    }
    set comment [APSMakeSafeQualifierString $comment]
    RefreshChannelData
    SetMainStatus "Saving..."
    if {[catch {exec burtrb -f $muxReqFile -sdds \
                  | sddsprocess -pipe=in -nowarning \
                  "-print=param,Description,$comment" \
                  $systemDataDir/Setup${setup}Mux.snap} result] || \
          [catch {exec sendScopeCommand $scopeID "*SAV $setup"} result]} {
        SetMainStatus "Error: $result"
        return
    }
    catch {exec chmod a+w $systemDataDir/Setup${setup}Mux.snap}
    SetMainStatus "Configuration saved locally as setup $setup"
}

proc MakeRecallLocalMenu {parent} {
    global scopeID
    APSMenubarAddMenu .recall -text "Recall-Local" -parent $parent 
    set w $parent.recall.menu
    for {set num 0} {$num<10} {incr num} {
        $w add command -label "Setup $num" -command \
          "DoLocalRecall -setup $num"
    }
}

proc DoLocalRecall {args} {
    global signalName env scopeID systemDataDir
    global muxReqFile

    set setup -1
    APSStrictParseArguments {setup}
    SetMainStatus "Recalling..."
    set muxFile $systemDataDir/Setup${setup}Mux.snap
    if ![file exists $muxFile] {
        SetMainStatus "MUX file not found for setup $setup."
        SetMainStatus "Will recall scope but you may not get the desired result."
    } else {
        if [catch {exec sdds2stream -parameter=Description $muxFile} comment] {
            SetMainStatus "Error: $result"
            return
        }
        if {![APSMultipleChoice [APSUniqueName .] -question \
                "Confirm: restore \"$comment\"" \
                -labelList "Yes No" -returnList "1 0" \
                -name "Local recall confirmation"]} {
            return
        }
        if {[catch {exec sddscasr -restore $muxFile} result]} {
            SetMainStatus "Error: $result"
            return
        }
    }
    if {[catch {exec sendScopeCommand $scopeID "*RCL $setup"} result]} {
        SetMainStatus "Error: $result"
        return
    }
    SetMainStatus "Local configuration $setup restored."
    RefreshChannelData
}

proc MakeDisplaysMenu {parent} {
    global scopeID
    APSMenubarAddMenu .displays -text "Displays" -parent $parent
    set w $parent.displays.menu

    set adlFileScope ""
    set adlFileScopeWF ""
    set adlFileMUX ""
    switch $scopeID {
        P:DO1 -
        P:HP9000  {
            if {$scopeID=="P:DO1"} {
                set adlFileScope ./par/parTopApp/PDO1.adl
            }
            set adlFileMUX ./par/parTopApp/parscopepanel.adl
        } 
        S:DO1 -
        S:HP9000 {
            if {$scopeID=="S:DO1"} {
                set adlFileScope ./booster/mainApp/BDO1.adl
            }
            set adlFileMUX ./booster/mainApp/xxrmA014scope.adl
        }
        L1:SCOPE1 {
            set adlFileScope ./linac/hp54540ctrl.adl
            set adlFileScopeWF ./linac/hp54540.adl
            set adlFileMUX ""
        }
    }
    # scope control display
    if [string length $adlFileScope] {
        $w add command -label "Scope control" -command \
          "exec medm -attach -x $adlFileScope >& /dev/null &"
    }
    # scope waveform display
    if [string length $adlFileScopeWF] {
        $w add command -label "Scope waveform" -command \
          "exec medm -attach -x $adlFileScopeWF >& /dev/null &"
    }
    # mux display
    if [string length $adlFileMUX] {
        $w add command -label "MUX control" -command \
          "exec medm -attach -x $adlFileMUX >& /dev/null &"
    }
}

proc AddRecLenMenuEntry {widget samples} {
    global scopeID SampleString
    $widget add command -label "$samples samples" -command "exec sendScopeCommand $scopeID \":TIM:RLEN $samples\" ; set SampleString $samples" 
}

proc MakeRecLenMenu {parent} {
    global SampleString
    menu ${parent}.rlen
    foreach length {32768 16384 8192 4096 2048 1024 512} {
        AddRecLenMenuEntry ${parent}.rlen $length
    }
}

proc AddClockMenuEntry {widget label value} {
    global scopeID Clock
    $widget  add command -label $label \
      -command "exec sendScopeCommand $scopeID \":TIM:SAMP:CLOC $value\" ; set Clock \"$label\""
}

proc MakeClockRateMenu {parent} {
    global Clock scopeID clockRateList clockValueList
    set clockRateList {"2 GSa/s" "1 GSa/s" "500 MSa/s" "250 MSa/s" "100 MSa/s" "50 MSa/s" "25 MSa/s" "10 MSa/s" "5 MSa/s"
        "2.5 MSa/s" "1 MSa/s" "500 kSa/s" "250 kSa/s" "100 kSa/s" "50 kSa/s" "25 kSa/s" "10 kSa/s" "5 kSa/s"
        "2.5 kSa/s" "1 kSa/s"} 
    set clockValueList {2e9 1e9 500e6 250e6 100e6 50e6 25e6 10e6 5e6 2.5e6 1e6 500e3 250e3 100e3 50e3 25e3 10e3 5e3
        2.5e3 1e3}
    menu ${parent}.clock
    set i 0
    foreach rate $clockRateList {
        AddClockMenuEntry ${parent}.clock $rate [lindex $clockValueList $i]
        incr i
    }
}


proc AddTimeDivMenuEntry {widget label value} {
    global scopeID TimeDiv
    $widget  add command -label $label \
      -command "exec sendScopeCommand $scopeID \":TIM:RANG $value\" ; set TimeDiv \"$label\""
}

proc GetTimeDivLabel {range0} {
    global tdivList rangeList
    set index 0
    foreach range $rangeList {
        set delta [expr abs($range0/$range-1)]
        if {$delta < 1e-6} {
            return [lindex $tdivList $index]
        }
        incr index
    }
}

proc MakeTimeDivMenu {parent} {
    global TimeDiv scopeID
    global tdivList rangeList
    set tdivList {}
    set rangeList {}
    set factor 1e-8
    foreach unit {ns us ms s} {
        foreach num {1 2 5 10 20 50 100 200 500} {
            lappend tdivList $num$unit
            lappend rangeList [expr $num*$factor]
        }
        set factor [expr $factor*1000]
    }
    menu ${parent}.tdiv
    set i 0
    foreach tdiv $tdivList {
        AddTimeDivMenuEntry ${parent}.tdiv $tdiv [lindex $rangeList $i]
        incr i
    }
}

proc setScopeCommand {args} {
    global scopeID ring hp9000ScopeCommand
    set command ""
    APSParseArguments {command} 
    if [regexp HP9000 $scopeID] {
        eval exec $hp9000ScopeCommand -ring $ring -command \"$command\"
    } else {
        exec  sendScopeCommand $scopeID "$command"
    }
}
proc MakeDelayWidget {parent lwidth ewidth} {
    global Delay scopeID

    label ${parent}.delayLabel -text "Delay: "  -width $lwidth 
    entry ${parent}.delay -width $ewidth -relief sunken -bd 2 -textvariable Delay 
    bind ${parent}.delay <Return> {setScopeCommand -command ":TIM:DELAY $Delay"}
    pack ${parent}.delayLabel ${parent}.delay -side left -fill x
}

proc MakeTimebaseWidget {parent tag} {
    global refreshTime SampleString Clock TimeDiv scopeID
    set lwidth 14
    set ewidth 22
    frame ${parent}${tag} -bd 2 -relief raised 
    pack ${parent}${tag} -side left -fill x

    frame ${parent}${tag}.data 
    pack ${parent}${tag}.data -side top
    RefreshSettings
    APSMakeLabeledOutputs ${parent}${tag}.data.rlen "Samples: " -lwidth $lwidth -ewidth $ewidth SampleString
    APSMakeLabeledOutputs ${parent}${tag}.data.clock "Clock rate: " -lwidth $lwidth -ewidth $ewidth Clock
    APSMakeLabeledOutputs $parent$tag.data.tdiv "Time/div: " -lwidth $lwidth -ewidth $ewidth TimeDiv
    frame ${parent}${tag}.data.delay 
    pack ${parent}${tag}.data.delay -side top
    MakeDelayWidget ${parent}${tag}.data.delay $lwidth $ewidth

    button ${parent}$tag.button -text REFRESH -command RefreshSettings -relief raised
    pack ${parent}$tag.button 

    APSMakeLabeledOutputs $parent$tag.updatetime "Last refresh: " refreshTime -ewidth 14
    
}

proc MakeSignalNamesWidget {parent} {
    global signalName signalState channelPVs
    set w ${parent}.signames
    frame $w -bd 6
    pack $w -side top -fill both
    frame $w.signal -bd 2
    frame $w.state -bd 2
    pack $w.signal $w.state -side left -fill x 
    if $channelPVs==4 {
        APSMakeLabeledOutputs $w.signal.col "MUX" -lanchor n -eside top -ewidth 20 signalName(0) signalName(1) signalName(2) signalName(3)
        APSMakeLabeledOutputs $w.state.col "Scope" -lanchor n -eside top -ewidth 20 signalState(0) signalState(1) signalState(2) signalState(3)
    } else {
        APSMakeLabeledOutputs $w.signal.col "MUX" -lanchor n -eside top -ewidth 20 signalName(0) signalName(1) signalName(2) signalName(3) signalName(4)
        APSMakeLabeledOutputs $w.state.col "Scope" -lanchor n -eside top -ewidth 20 signalState(0) signalState(1) signalState(2) signalState(3) signalState(4)
    }
}


proc SetSaveScopeStatus {message} {
    global saveScopeStatus 
    set saveScopeStatus  $message
    update
}


proc SaveScopeSettingsWidget {} {
    global saveScopeStatus dataDir rootSaveScopeSettings extraRequestFile referenceList
    global auxFilesDir
    set w .savescope
    if {[winfo exists $w]} {destroy $w}
    toplevel $w
    wm title $w "Save Scope Settings"
    set comment ""
    set extraRequestFile ""

    SetSaveScopeStatus "Enter a descriptive comment and press SAVE, or press DONE to exit."
    APSScrolledStatus .status -parent $w -width 90 -height 3 \
      -textVariable saveScopeStatus
    APSLabeledEntry .dir -parent $w -label "Directory: " \
      -textVariable dataDir -width 80 -contextHelp \
      "Directory name for save file.  Normally not changed."
    APSLabeledEntry .file -parent $w -label "Rootname: " \
      -textVariable rootSaveScopeSettings  -width 20 \
      -contextHelp "Rootname for the save data.  All files associated with this save will hae this string as the first part of the name."
    APSLabeledEntry .extra -parent $w -label "Extra PV request file: " \
      -textVariable extraRequestFile -width 80 -contextHelp \
      "Name of extra request file to be used to record state of PVs that are needed in addition to the scope settings and scope mux settings.  These PVs might, for example, set up additional equipment for a measurement."
    APSButton .fsel -parent $w.extra -packOption "-side right" \
      -text "F" -contextHelp "Brings up file select dialog for extra request file." \
      -command {set extraRequestFile \
                  [APSFileSelectDialog [APSUniqueName .] \
                     -path $auxFilesDir -pattern "*.req" \
                     -title "Extra request file select dialog" ]}
    set rootSaveScopeSettings [exec date +%Y%m%d-%H%M%S]
    APSLabeledEntry .comment -parent $w -label "Comment: " \
      -textVariable comment -width 80 -contextHelp \
      "Enter a string to describe the save you are making."

    APSButton .save -parent $w -text "SAVE" -command \
      {SaveScopeSettings $dataDir/$rootSaveScopeSettings $comment} \
      -contextHelp "Save the scope, mux, and any auxiliary PVs."
    APSButton .done -parent $w -text "DONE" -command \
      "destroy $w; unset comment rootSaveScopeSettings" \
      -contextHelp "Destroy this window."
}

proc SaveScopeSettings {rootname comment} {
    global signalName env scopeID dataDir rootSaveScopeSettings extraRequestFile SampleString ring
    global muxReqFile auxFilesDir new
    if {[string length $rootname] == 0} {
        SetSaveScopeStatus "Error: No rootname supplied"
        bell
        return
    }
    if {[string length $comment] == 0} {
        SetSaveScopeStatus "Error: No comment supplied"
        bell
        return
    }
    if {[string length $extraRequestFile]} {
        if ![file exists $extraRequestFile] {
            SetSaveScopeStatus "Error: $extraRequestFile not found"
            bell
            return
        }
        set auxFilesDir [file dirname $extraRequestFile]
    }
    if {[file exists ${rootname}.mux] || [file exists ${rootname}.setup]} {
        if {[YesNoPopUp "Overwrite existing save?"] == 0} {
            SetSaveScopeStatus "Not saved"
            return
        }
        SetSaveScopeStatus "Overwriting old save files..."
    } else { 
        SetSaveScopeStatus "Saving..."
    }
    after 500
    RefreshChannelData
    set comment [APSMakeSafeQualifierString $comment]
    set user $env(USER)
    if [catch \
          {exec burtrb -f $muxReqFile -sdds \
             | sddsprocess -pipe=in "-print=param,Description,$comment" ${rootname}.mux \
              -nowarning \
             "-print=param,ChannelLabel,C1=$signalName(0) C2=$signalName(1) C3=$signalName(2) C4=$signalName(3)" \
             "-print=param,UserName,$user"} result] {
        SetSaveScopeStatus $result
        return
        }
    if {![regexp HP9000 $scopeID]} {
        catch {exec getScopeSetup $scopeID ${rootname}.setup.tmp} msg
        if [catch \
              {exec sddsprocess ${rootname}.setup.tmp ${rootname}.setup \
                 -nowarning \
                 "-printe=param,SamplePoints,$SampleString" \
                 "-print=param,Description,$comment" \
                 "-print=param,ChannelLabel,C1=$signalName(0) C2=$signalName(1) C3=$signalName(2) C4=$signalName(3)" \
                 "-print=param,UserName,$user"} result] {
            SetSaveScopeStatus $result
            return
        }
        exec rm ${rootname}.setup.tmp 
    } else {
        if !$new {
            catch {exec saveHP9000State -ring $ring -filename ${rootname}.setup} result
        } else {
            catch {exec hp9000ScopeSocketCommand -ring $ring -save ${rootname}.setup} result
        }
    }
    if {[string length $extraRequestFile]} {
        if [catch {exec burtrb -f $extraRequestFile \
                     -o $rootname.extraSnap} result] {
            SetSaveScopeStatus $result
            return
        }
    }
    APSUpdateUseLog ${rootname}.log create
    exec chmod gou+rw ${rootname}.log
    set rootSaveScopeSettings [exec date +%Y%m%d-%H%M%S]
    SetSaveScopeStatus "Save completed"
}


proc SetRestoreScopeStatus {message} {
    global restoreScopeStatus 
    set restoreScopeStatus  $message
    update
}

set restoreScopeStatus ""
proc RestoreScopeSettingsWidget {} {
    global restoreScopeStatus restoreRootname restoreComment restoreSignals restoreChoicesPresent referenceList
    global restoreTimestamp dataDir
    set restoreScopeStatus ""
    set restoreRootname ""
    set restoreComment ""
    foreach i {0 1 2 3} {
        set restoreSignals($i) ""
    }
    set restoreChoicesPresent 0
    set rootnameFragment ""
    set commentFragment ""
    set w .restorescope
    if {[winfo exists $w]} {destroy $w}
    toplevel $w
    wm title $w "Restore Scope Settings"
    
    APSScrolledStatus .status -parent $w -width 80 -height 3 \
      -textVariable restoreScopeStatus
    SetRestoreScopeStatus "Enter search criteria if desired and/or press SEARCH to see configuration list"
    ### make search frame with rootname and comment entry, plus SEARCH and CLEAR buttons
    frame $w.search -relief raised -bd 2 
    pack $w.search -side top 
    APSMakeLabeledEntries $w.search.dir "Directory: " dataDir -ewidth 80
    APSMakeLabeledEntries $w.search.file "Date search string \[YYYY\[MM\[DD\]\]\]: " rootnameFragment -ewidth 20
    APSMakeLabeledEntries $w.search.comment "Comment search string: " commentFragment -ewidth 80
    set signalFragment(0) ""
    set signalFragment(1) ""
    set signalFragment(2) ""
    set signalFragment(3) ""
    APSMakeLabeledEntries $w.search.signal "Signal search strings: " -ewidth 10 signalFragment(0) signalFragment(1) signalFragment(2) signalFragment(3)
    frame $w.search.op 
    pack $w.search.op -side top 
    button $w.search.op.search -text SEARCH \
      -command {RestoreFileSearch 0 $dataDir/$rootnameFragment $commentFragment [array get signalFragment]}
    button $w.search.op.searchp -text "SEARCH PREFERRED" \
      -command {RestoreFileSearch 1 $dataDir/$rootnameFragment $commentFragment [array get signalFragment]}
    button $w.search.op.clear -text CLEAR \
      -command {set rootnameFragment "" ; set commentFragment "" ; foreach i {0 1 2 3} {set signalFragment($i) ""}}
    pack $w.search.op.search $w.search.op.searchp $w.search.op.clear -side left 

    ### Make restore frame with filename and comment display, RESTORE and DONE buttons
    frame $w.restore -relief raised -bd 2
    pack $w.restore -side top
    frame $w.restore.choice
    pack $w.restore.choice -side top -fill x

    APSMakeLabeledOutputs $w.restore.choice.file "Rootname: " restoreRootname -ewidth 20
    APSMakeLabeledOutputs $w.restore.choice.timestamp "Time stamp: " restoreTimestamp -ewidth 30
    APSMakeLabeledOutputs $w.restore.choice.comment "Comment: " restoreComment -ewidth 80
    APSMakeLabeledOutputs $w.restore.choice.signals "Signals: " -ewidth 15 restoreSignals(0) restoreSignals(1) restoreSignals(2) restoreSignals(3)

    frame $w.restore.op 
    pack $w.restore.op -side top
    button $w.restore.op.restore -text "RESTORE" -relief raised -bd 2 -command \
      {RestoreScopeSettings $restoreRootname}
    button $w.restore.op.delete -text "DELETE" -relief raised -bd 2 -command \
      {DeleteScopeSettings $restoreRootname}
    button $w.restore.op.pref -text "PREFERRED" -relief raised -bd 2 -command \
        {SetScopeSettingsPreferred $restoreRootname 1}
    button $w.restore.op.unpref -text "NOT PREFERRED" -relief raised -bd 2 -command \
        {SetScopeSettingsPreferred $restoreRootname 0}
    
    button $w.restore.op.done -text "DONE" -relief raised -bd 2 -command \
      "destroy $w ; unset restoreRootname restoreComment restoreTimestamp \
                        rootnameFragment commentFragment signalFragment"
    pack $w.restore.op.restore $w.restore.op.delete $w.restore.op.done $w.restore.op.pref $w.restore.op.unpref  -side left
    if [llength $referenceList] {
        button $w.restore.op.ref -text "MAKE REFERENCE FOR..." -relief raised -bd 2 -command \
          {MakeReference $restoreRootname}
        pack $w.restore.op.ref -side left
    }
}

proc MakeReference {filename} {
    global referenceList auxFilesDir reference 
    if ![string length $filename] {
        return -code error "No file chosen."
    }
    set reference ""
    APSScrolledListWindow .process -name "Select a category" \
      -label "Select a category to make reference for it" \
      -itemList $referenceList -selectionVar reference
    tkwait variable reference
    if ![string length $reference] {
        return -code error "No reference is selected."
    }
   
    set newFile [APSNextGenerationedName -directory $auxFilesDir/archiveData \
                   -name ${reference}.setup-0001 -newFile 1 -separator -]
  
    SetRestoreScopeStatus "Make new $filename (copied to $newFile) to be the reference of $reference ..."
    set oldDir [pwd]
    cd $auxFilesDir/archiveData
    exec cp ${filename}.setup $newFile
    catch {exec rm ${reference}.setup}
    exec ln -s $newFile ${reference}.setup
    cd $oldDir
    SetRestoreScopeStatus "done"
}
proc SetScopeSettingsPreferred {filename mode} {
    SetRestoreScopeStatus "preferring: $filename $mode [pwd]"
    if $mode {
        set fd [open $filename.preferred w]
        close $fd
    } else {
        file delete -force $filename.preferred
    }
}

set RCID 0
proc RestoreFileSearch {preferred fileFrag commentFrag signalFragList} {
    global restoreRootname restoreComment restoreSignals scopeID
    global restoreChoicesPresent  errorCode  errorInfo env RCID
    array set signalFrag $signalFragList
    set tmpfile /tmp/[APSTmpString]
    SetRestoreScopeStatus "Searching..."
    if {[string length $fileFrag] == 0} {
        set fileFrag "*"
    } else {
        set fileFrag "$fileFrag*"
    }
    if {[string length $commentFrag] == 0} {
        set commentFrag "*"
    } else {
        set commentFrag "*$commentFrag*"
    }
    for {set i 0} {$i<4} {incr i} {
        if {[string length $signalFrag($i)] == 0} {
            set signalFrag($i) "*"
        } else {
            set signalFrag($i) "*$signalFrag($i)*"
        }
    }
    set errorCode "NONE"
    set fileList [glob -nocomplain $fileFrag*.mux]
    
    if $preferred {
        set fileList1 ""
        foreach file $fileList {
            if [file exists [file rootname $file].preferred] {
                lappend fileList1 $file
            }
        }
        set fileList $fileList1
    }
    if [llength $fileList]==0 {
        SetRestoreScopeStatus "Error: No matches"
        bell
        return
    }
    eval exec sddscombine $fileList -pipe=out -collapse \
      | sddssort -col=Filename,decr -col=Description,incr -pipe \
      | sddsprocess  -pipe=in $tmpfile -nowarn \
      -match=column,Filename=$fileFrag {-match=column,Description=+$commentFrag} \
      {-match=column,ChannelLabel=+$signalFrag(0)} \
      {-match=column,ChannelLabel=+$signalFrag(1)} \
      {-match=column,ChannelLabel=+$signalFrag(2)} \
      {-match=column,ChannelLabel=+$signalFrag(3)}
    if {$errorCode != "NONE" && $errorCode != ""} {
        SetRestoreScopeStatus "Error: No matches"
        puts $errorInfo
        bell
        return
    }
    set count1 [exec sdds2stream -rows $tmpfile]
    set count [lindex [split $count1] 0]
    if {$count == "0"} {
        SetRestoreScopeStatus "no match to search criteria"
        return
    }
    SetRestoreScopeStatus "$count matches found---Double-click to view information."
    set restoreChoicesPresent 1
    set date [exec date]
    APSMakeSDDSListbox $tmpfile .restchoices$RCID -title "Scope $scopeID restore choices ($date)" \
      -page 0 -labelmaker MakeLBoxTextLine  -packOption "-side top -expand true -fill y" \
        -callback DisplayRestoreData  \
        TimeStamp Description Filename
    incr RCID
    exec rm $tmpfile
    
}

proc DisplayRestoreData { timeStamp description filename } {
    global restoreRootname restoreComment restoreSignals restoreTimestamp
    SetRestoreScopeStatus "RESTORE restores, DONE exits.  You may double-click or search again if desired."
    set restoreTimestamp $timeStamp
    set restoreComment $description
    set restoreRootname [file rootname $filename]
    if [catch {exec sddsmxref $restoreRootname.mux signalXref.sdds \
                -nowarning -pipe=out -match=ControlName,ValueString=MuxEnumSetting \
                 -take=SignalName | sdds2stream -column=SignalName -pipe} dataList] {
        SetRestoreScopeStatus "$dataList"
        set dataList {? ? ? ?}
    }
    foreach i { 0 1 2 3} {
        set restoreSignals($i) [lindex $dataList $i]
    }
}

proc RestoreScopeSettings {rootname} {
    global restoreChoicesPresent scopeID signalName signalState SampleString \
      Clock Delay TimeDiv ring hp9000ScopeCommand new
    if {[string length $rootname]==0} {
        if {!$restoreChoicesPresent} {
            SetRestoreScopeStatus "Perform a search first to get a list of choices"
            return 
        }
        SetRestoreScopeStatus "Select a configuration from the list below"
        return
    }
    foreach i {0 1 2 3 4} {
        set signalName($i) "?"
        set signalState($i) "?"
    }
    if {![regexp HP9000 $scopeID]} {
        if [catch {exec sdds2stream -par=SamplePoints $rootname.setup} SampleString] {
            set SampleString "?"
        }
        set Clock "?"
        set Delay "?"
        set TimeDiv "?"
        SetRestoreScopeStatus "Restore in progress..."
        SetRestoreScopeStatus "Reset scope..."
        if [catch {exec cavput -list=${scopeID}:resetBO=1 -pend=10} result] {
            SetRestoreScopeStatus "Error resetting scope: $result"
        }
        after 4000
    }
    SetRestoreScopeStatus "[exec date] sddscasr -restore $rootname.mux"
    if [catch {exec sddscasr -restore $rootname.mux} result] {
        SetRestoreScopeStatus "Error restoring mux: $result"
    }
    if {![regexp HP9000 $scopeID]} {
        catch {exec putScopeSetup $scopeID $rootname.setup}
    } else {
        if !$new {
            SetRestoreScopeStatus "[exec date] restoreHP9000State -ring $ring  -filename $rootname.setup"
            catch {exec restoreHP9000State -ring $ring  -filename $rootname.setup} 
            SetRestoreScopeStatus "[exec date] scope set done."
        } else {
            SetRestoreScopeStatus "[exec date] hp9000ScopeSocketCommand -ring $ring  -restore $rootname.setup"
            catch {exec hp9000ScopeSocketCommand -ring $ring  -restore $rootname.setup} 
            SetRestoreScopeStatus "[exec date] scope set done."
        }
    }
    if {[file exists $rootname.extraSnap] && \
          [catch {exec sddscasr -restore $rootname.extraSnap} result]} {
        SetRestoreScopeStatus "Error restoring extra PVs: $result"
    }
    if {$SampleString!="?"} {
        if {![regexp HP9000 $scopeID]} {
            catch {exec sendScopeCommand $scopeID ":TIM:RLEN $SampleString"}
        } else {
           # catch {exec sendHP9000ScopeCommand -ring $ring -command  ":TIM:RLEN $SampleString"}
            catch {eval exec hp9000ScopeCommand -ring $ring -command  \":ACQuire:POINTs $SampleString\"}
        }
    }
    APSUpdateUseLog $rootname.log restore
    exec chmod gou+w $rootname.log
    after 5000 
    #        SetRestoreScopeStatus "Restore in progress...please wait."
    #        catch {exec putScopeSetup $scopeID $rootname.setup}
    #        after 5000 
    SetRestoreScopeStatus "[exec date] RefreshSetting..."
    RefreshSettings
    SetRestoreScopeStatus "[exec date] Restore done.  Press RESTORE again if it failed."
}

proc DeleteScopeSettings {rootname} {
    global restoreChoicesPresent scopeID signalName signalState SampleString Clock Delay TimeDiv
    if {[string length $rootname]==0} {
        if {!$restoreChoicesPresent} {
            SetRestoreScopeStatus "Perform a search first to get a list of choices"
            return 
        }
        SetRestoreScopeStatus "Select a configuration from the list below"
        return
    }
    set answer [APSYesNoPopUp "Okay to delete configuration $rootname?"]
    if {$answer == 0} {
        return
    }
    SetRestoreScopeStatus "Delete in progress..."
    exec mv $rootname.setup $rootname.mux ./wastebasket
    if {[file exists $rootname.log]} {
        exec mv $rootname.log ./wastebasket
    }
    if {[file exists $rootname.extraSnap]} {
        exec mv $rootname.extraSnap ./wastebasket
    }
    SetRestoreScopeStatus "Delete done."
}


proc SetReviewScopeStatus {message} {
    global reviewScopeStatus 
    set reviewScopeStatus  $message
    update
}

set sddsplotOptions ""
set exportFilename ""
proc ReviewScopeSignalsWidget {} {
    global reviewScopeStatus reviewRootname reviewComment reviewSignals reviewChoicesPresent
    global reviewTimestamp sddsplotOptions
    set reviewScopeStatus ""
    set reviewRootname ""
    set reviewComment ""
    foreach i {0 1 2 3} {
        set reviewSignals($i) ""
    }
    set reviewChoicesPresent 0
    set rootnameFragment ""
    set commentFragment ""
    set w .reviewscope
    if {[winfo exists $w]} {destroy $w}
    toplevel $w
    wm title $w "Review Scope Signals"

    SetReviewScopeStatus "Enter search criteria if desired and/or press SEARCH to see configuration list"
    APSScrolledStatus .status -parent $w -width 80 -height 3 \
      -textVariable reviewScopeStatus 
    ### make search frame with rootname and comment entry, plus SEARCH button
    frame $w.search -relief raised -bd 2 
    pack $w.search -side top 
    APSMakeLabeledEntries $w.search.dir "Directory: " dataDir -ewidth 80
    APSMakeLabeledEntries $w.search.file "Date search string \[YYYY\[MM\[DD\]\]\]: " rootnameFragment -ewidth 20
    APSMakeLabeledEntries $w.search.comment "Comment search string: " commentFragment -ewidth 80
    set signalFragment(0) ""
    set signalFragment(1) ""
    set signalFragment(2) ""
    set signalFragment(3) ""
    APSMakeLabeledEntries $w.search.signal "Signal search strings: " -ewidth 10 signalFragment(0) signalFragment(1) signalFragment(2) signalFragment(3)
    frame $w.search.op 
    pack $w.search.op -side top 
    button $w.search.op.search -text SEARCH \
      -command {ReviewFileSearch $dataDir/$rootnameFragment $commentFragment [array get signalFragment]}
    button $w.search.op.clear -text CLEAR \
      -command {set rootnameFragment "" ; set commentFragment "" ; foreach i {0 1 2 3} {set signalFragment($i) ""}}
    pack $w.search.op.search $w.search.op.clear -side left 
    

    ### Make review frame with filename and comment display, REVIEW and DONE buttons
    frame $w.review -relief raised -bd 2
    pack $w.review -side top
    frame $w.review.choice
    pack $w.review.choice -side top -fill x

    APSMakeLabeledOutputs $w.review.choice.file "Rootname: " reviewRootname -ewidth 20
    APSMakeLabeledOutputs $w.review.choice.timestamp "Time stamp: " reviewTimestamp -ewidth 30
    APSMakeLabeledOutputs $w.review.choice.comment "Comment: " reviewComment -ewidth 80
    APSMakeLabeledOutputs $w.review.choice.signals "Signals: " -ewidth 15 reviewSignals(0) reviewSignals(1) reviewSignals(2) reviewSignals(3)
    APSMakeLabeledEntries $w.review.options "sddsplot options: " sddsplotOptions -ewidth 80
    APSMakeLabeledEntries $w.review.export "export file: " exportFilename -ewidth 80

    frame $w.review.op 
    pack $w.review.op -side top
    button $w.review.op.review -text "REVIEW" -relief raised -bd 2 -command \
      {ReviewScopeSignals $reviewRootname}
    button $w.review.op.delete -text "DELETE" -relief raised -bd 2 -command \
      {DeleteScopeSignals $reviewRootname}
    button $w.review.op.done -text "DONE" -relief raised -bd 2 -command \
      "destroy $w ; unset reviewRootname reviewComment reviewTimestamp \
                        rootnameFragment commentFragment signalFragment"
    button $w.review.op.export -text "EXPORT" -relief raised -bd 2 -command \
        {ExportScopeSignals $reviewRootname $exportFilename}
    
    pack $w.review.op.review $w.review.op.delete $w.review.op.done $w.review.op.export -side left

}

proc ReviewFileSearch {fileFrag commentFrag signalFragList} {
    global reviewRootname reviewComment reviewSignals scopeID
    global reviewChoicesPresent  errorCode  errorInfo env RCID
    array set signalFrag $signalFragList
    set tmpfile /tmp/[APSTmpString]
    SetReviewScopeStatus "Searching..."
    if {[string length $fileFrag] == 0} {
        set fileFrag "*"
    } else {
        set fileFrag "$fileFrag*"
    }
    if {[string length $commentFrag] == 0} {
        set commentFrag "*"
    } else {
        set commentFrag "*$commentFrag*"
    }
    for {set i 0} {$i<4} {incr i} {
        if {[string length $signalFrag($i)] == 0} {
            set signalFrag($i) "*"
        } else {
            set signalFrag($i) "*$signalFrag($i)*"
        }
    }
    set errorCode "NONE"
    set fileList [glob -nocomplain $fileFrag*.sig]
    if [llength $fileList]==0 {
        SetReviewScopeStatus "Error: Nothing for the given date $fileFrag...."
        return
    }
    eval exec sddscombine $fileList -pipe=out -collapse \
      | sddssort -col=Filename,incr -col=Description,incr -unique -pipe \
      | sddsprocess  -pipe=in $tmpfile -nowarn \
      -match=column,Filename=$fileFrag {-match=column,Description=+$commentFrag} \
      {-match=column,ChannelLabel=+$signalFrag(0)} \
      {-match=column,ChannelLabel=+$signalFrag(1)} \
      {-match=column,ChannelLabel=+$signalFrag(2)} \
      {-match=column,ChannelLabel=+$signalFrag(3)}
    if {$errorCode != "NONE" && $errorCode != ""} {
        SetReviewScopeStatus "Error: problem searching for match ($errorCode)"
        puts $errorInfo
        bell
        return
    }
    set count1 [exec sdds2stream -rows $tmpfile]
    set count [lindex [split $count1] 0]
    if {$count == "0"} {
        SetReviewScopeStatus "no match to search criteria"
        return
    }
    SetReviewScopeStatus "$count matches found---Double-click to view information."
    set reviewChoicesPresent 1
    set date [exec date]
    APSMakeSDDSListbox $tmpfile .restchoices$RCID -title "Scope $scopeID review choices ($date)" \
      -page 0 -labelmaker MakeLBoxTextLine -callback DisplayReviewData \
      TimeStamp Description Filename
    incr RCID
    exec rm $tmpfile
    
}

proc DisplayReviewData { timeStamp description filename } {
    global reviewRootname reviewComment reviewSignals reviewTimestamp
    SetReviewScopeStatus "REVIEW reviews, DONE exits.  You may double-click or search again if desired."
    set reviewTimestamp $timeStamp
    set reviewComment $description
    set reviewRootname [file rootname $filename]
    set pars [exec sddsquery -par $filename]
   
    foreach par {Channel1 Channel2 Channel3 Channel4} id {0 1 2 3} {
        if [lsearch -exact $pars $par]>=0 {
            lappend parList $par
            lappend idList $id
        }
    }
    
    set fin [open "|sdds2stream $reviewRootname.sig -param=[join $parList ,]" r]
    foreach i $idList {
        if {[eof $fin]} {
            set reviewSignals($i) "?"
        } else {
            gets $fin reviewSignals($i)
        }
    }
    close $fin
}


proc DeleteScopeSignals {rootname} {
    global reviewChoicesPresent scopeID signalName signalState SampleString Clock Delay TimeDiv
    if {[string length $rootname]==0} {
        if {!$reviewChoicesPresent} {
            SetReviewScopeStatus "Perform a search first to get a list of choices"
            return 
        }
        SetReviewScopeStatus "Select a configuration from the list below"
        return
    }
    set answer [APSYesNoPopUp "Okay to delete signals $rootname?"]
    if {$answer == 0} {
        return
    }
    SetReviewScopeStatus "Delete in progress..."
    exec mv $rootname.sig ./wastebasket
    if {[file exists $rootname.sig.log]} {
        exec mv $rootname.sig.log ./wastebasket
    }
    SetReviewScopeStatus "Delete done."
}

proc ReviewScopeSignals {rootname} {
    global reviewChoicesPresent scopeID signalName signalState SampleString Clock Delay TimeDiv
    global sddsplotOptions
    if {[string length $rootname]==0} {
        if {!$reviewChoicesPresent} {
            SetReviewScopeStatus "Perform a search first to get a list of choices"
            return 
        }
        SetReviewScopeStatus "Select a configuration from the list below"
        return
    }
    SetReviewScopeStatus "Making plot..."
    set otherOption ""
    set doInterp 0
    if [catch {exec sdds2stream -page=1 -par=PointsPerDiv $rootname.sig} points] {
        set doInterp 0
    } else {
        if {$points<10} {
            set doInterp 1
        }
	set delay [exec sdds2stream -par=Delay $rootname.sig -page=1]
	set div [exec sdds2stream -par=TimeDiv $rootname.sig -page=1]
	set x1 [expr $delay - 5.0*$div]
	set x2 [expr $delay + 5.0*$div]
	set otherOption "-filter=col,t,$x1,$x2"
    }
    set dectMode [lindex [exec sdds2stream -par=PeakDect $rootname.sig] 0]
    if {$dectMode=="PDET"} {
        if [regexp "HP9000" $scopeID] {
            set cols [llength [join [exec sddsquery -col $rootname.sig | grep Max]]]
            eval exec sddsplot -split=page -sep=2 $sddsplotOptions -grap=line,vary -layout=1,$cols -group=namestring \
              -yscalesgroup=nameIndex -legend \
              -col=t,*Max $rootname.sig -col=t,*Min  $rootname.sig  -pspace=0.15,0.8,0.175,0.9 \
              -lspace=1.01,1.28,0.0,1.0 $otherOption \
              -legend=ysymbol,scale=1.5 -ylabel=Division  \
              -topline=$rootname -title=@Description 2>/dev/null &
            return
        } else {
            set cols [llength [join [exec sddsquery -col $rootname.sig | grep Scaled]]]
            if [catch {llength [join [exec sddsquery -col $rootname.sig | grep OFF | grep Scaled]] } cols1] {
                set cols1 0
            }
            #  set cols1 [llength [join [exec sddsquery -col $rootname.sig | grep OFF | grep Scaled]]]
            set layout [expr $cols - $cols1]
            set extraOpt " -yExclude=*OFF* -layout=1,$layout -group=namestring -sep=namestring"
        }
    } else {
        set extraOpt "-graph=line,vary"
    }
    if !$doInterp {
	catch {eval exec sddsplot -split=page $extraOpt $sddsplotOptions \
	    -col=t,*Scaled $rootname.sig  -pspace=0.15,0.8,0.175,0.9 \
	    -lspace=1.01,1.28,0.0,1.0 $otherOption \
	    -legend=ysymbol,scale=1.5 -ylabel=Division  \
	    -topline=$rootname -title=@Description 2>/dev/null &  } result
    }  else {
        DoConvolvePlot $rootname
    }
    APSUpdateUseLog $rootname.sig.log review
}

proc ExportScopeSignals {reviewRootname outputFilename} {
    global origDir
    if [string length $reviewRootname]==0 {
        SetReviewScopeStatus "Select a configuration before exporting."
        return
    }
    if [string length $outputFilename] {
        set fileDir [file dirname $outputFilename]
        if {[string length $fileDir]==0 || [string compare $fileDir .]==0} {
            set outputFilename $origDir/$outputFilename
        }
        if [catch {exec cp ${reviewRootname}.sig $outputFilename} result] {
            SetReviewScopeStatus "Error exporting file."
        } else {
            SetReviewScopeStatus "Export done."
        }
    } else {
        SetReviewScopeStatus "Give a filename for exporting."
    }
}

proc MakeLBoxTextLine {data width} {
    set timestamp [lindex $data 0]
    set wt [lindex $width 0]
    set description [lindex $data 1]
    set wd [lindex $width 1]
    set filename [lindex $data 2]
    set wf [lindex $width 2]
    set rootname [file rootname $filename]
    if [file exists $rootname.preferred] {
        set suffix " *"
    } else {
        set suffix "  "
    }
  
    set sform [format "%%%lds    %%%lds$suffix" $wt $wd]
    return [format $sform $timestamp $description]
}


proc SetSaveSignalsStatus {text} {
    global saveSignalsStatus
    set saveSignalsStatus $text
    update
}

proc SaveScopeSignalsWidget {} {
    global saveSignalsStatus rootSaveScopeSignals dataDir
    set w .savesignals
    if {[winfo exists $w]} {destroy $w}
    toplevel $w
    wm title $w "Save Scope Signals"
    set comment ""
    
    SetSaveSignalsStatus "Enter a descriptive comment and press SAVE, or press DONE to exit."
    APSScrolledStatus .status -parent $w -width 80 -height 3 \
      -textVariable saveSignalsStatus

    APSMakeLabeledEntries $w.dir "Directory: " dataDir -ewidth 80
    APSMakeLabeledEntries $w.file "Rootname: " rootSaveScopeSignals  -ewidth 20
    set rootSaveScopeSignals [exec date +%Y%m%d-%H%M%S]
    APSMakeLabeledEntries $w.comment "Comment: " comment -ewidth 80
    
    frame $w.op
    button $w.op.save -text "SAVE" -relief raised -bd 2 -command \
      {SaveScopeSignals  $comment}
    button $w.op.done -text "DONE" -relief raised -bd 2 -command \
      "destroy $w; unset comment rootSaveScopeSignals"
    pack $w.op.save $w.op.done -side left
    pack $w.op -side top 
}

proc SaveHP9000ScopeSignals {comment} {
    global scopeID signalState signalName rootSaveScopeSignals env fixWfs cateFile scalarFile channelName dataDir ring
    global hp9000ScopeCommand
    
    set rootSaveScopeSignals [exec date +%Y%m%d-%H%M%S]
    set rootname $dataDir/$rootSaveScopeSignals
    update
    after 500
    if {[string length $comment]==0} {
        SetSaveSignalsStatus "You must supply a comment in order to save signals"
        bell
        return
    }
    set comment [APSMakeSafeQualifierString $comment]
    SetSaveSignalsStatus "Verifying signal information..."
    RefreshSettings
    set first 1
    set plotlist ""
    foreach i { 0 1 2 3 } {
        if {$signalState($i)} {
            if {$first} { 
                set plotlist $signalName($i)
            } else {
                set plotlist "$plotlist,$signalName($i)"
            }  
            set first 0
        }
    }
    if {[string length $plotlist]==0} {
        SetSaveSignalsStatus "No channels are on---nothing saved."
        bell
        return
    }
    
    set parList {TimeDelay TimebaseRange SampleRateAnalog AcquisitionMode \
                   chan1offset chan1range chan2offset chan2range chan3offset chan3range chan4offset chan4range}
    set varList {delay div rate peakDect chan1offset chan1range chan2offset chan2range chan3offset chan3range chan4offset chan4range}
    
    SetSaveSignalsStatus "Saving scope data ..."
    set tstamp [exec date]
    if [catch {exec /home/oxygen/SHANG/oag/apps/src/tcltkapp/oagapp/getHP9000ScopeData -ring $ring -filename $rootname.sig.tmp} result] {
        SetSaveSignalsStatus "Error getting scope data: $result"
        return
    }
    if [catch {exec /home/oxygen/SHANG/oag/apps/src/tcltkapp/oagapp/sendHP9000ScopeCommand -ring $ring -command ":RUN"} result] {
        SetSaveSignalsStatus "Error start scope running: $result"
    }
    foreach par $parList var $varList {
        set $var [exec sdds2stream -page=1 -par=$par $rootname.sig.tmp]
    }
    SetSaveSignalsStatus "dectmode $peakDect"
    SetSaveSignalsStatus "delay: $delay"
    # use :TRIG:DEL:TDEL:TIME? -- trigger time
    # use :TIM:POS? to get the time position (or delay)
    
    SetSaveSignalsStatus "time range: $div"
    #whole range has 10 divisions, so the time per division is as following
    set div [expr $div/10.0]
    
    set deltaT [expr 1.0/$rate]
    SetSaveSignalsStatus "rate: $rate; deltaT: $deltaT"
   
    set extraOpt ""
    
    if {[string length $cateFile] && [file exist $cateFile] && [file exist $scalarFile]} {
        if [catch {exec cavget -list=${channelName} -list=1,2,3,4 -printErrors } valList] {
            return -code error $result
        }
        set tmpfile /tmp/[APSTmpString]
        
        if [catch {exec sddsprocess $cateFile -pipe=out \
                     "-match=col,MuxValue=[lindex $valList 0],MuxValue=[lindex $valList 1],|,MuxValue=[lindex $valList 2],|,MuxValue=[lindex $valList 3],|" \
                     | sddssort -pipe -col=Category -unique \
                     | sdds2stream -pipe -col=Category } cateList] {
            SetSaveSignalsStatus "No category found for muxes: [join $valList]\nNo scalars will be logged."
        } else {
            set opt ""
            foreach cate $cateList {
                if ![string length $opt] {
                    set opt -match=col,Category=$cate
                } else {
                    append opt ,Category=$cate,|
                }
            }
            if [catch {eval exec sddsprocess $scalarFile $opt -pipe=out \
                         | sddssort -pipe -col=ReadbackName -unique -numericHigh \
                         | sddscasr -pipe=in -save $tmpfile.2 } result] {
                SetSaveSignalsStatus "Error: category $cateList not found in $scalarFile"
                return
            }
            set pvList [exec sdds2stream -col=ControlName $tmpfile.2]
            set valList [exec sdds2stream -col=ValueString $tmpfile.2]
            set nameList [exec sdds2stream -col=ReadbackName $tmpfile.2]
            set extraOpt ""
            
            foreach name $nameList pv $pvList val $valList {
                if [catch {expr $val /2} result] {
                    #string value
                    lappend extraOpt "-reprint=par,$name,$val,symbol=$pv"
                } else {
                    lappend extraOpt -redefine=par,$name,$val,symbol=$pv
                }
            }
        }
        APSAddToTempFileList $tmpfile.2
    }
    
    
   # set tstamp [exec date]
  
    set cols [exec sddsquery -col $rootname.sig.tmp]
    set rows [exec sdds2stream -rows=bar $rootname.sig.tmp]
    set points [exec sdds2stream -par=Points $rootname.sig.tmp]
   
    if {$rows != $points} {
        #at interpolation mode, the waveform data points is different from the scope data points
        #need to recompute the deltaT with time division, deltaT = $deltaT /(($rows-1.0)/($points-1.0))
        #or deltaT can be computed as following too.
        set deltaT [expr $div * 10.0 / ($rows -1)]
    }
    set option ""
    set option1 ""
    
    foreach col $cols {
        set chan [scan $col Channel%ld]
        set i [expr $chan - 1]
        set offset [set chan${chan}offset]
        set range [set chan${chan}range]
        if {$peakDect=="PDET"} {
            set col0 [regsub "Channel$chan" $col "$signalName($i)"]
            append option " \"-redefine=col,$col0,$col0 $offset  - $range /,units=Div\""
            append option1 " \"-rename=col,$col=$col0\""
            
        } else {
            append option " \"-redefine=col,$signalName($i)Scaled,$signalName($i) $offset  - $range /,units=Div\""
        }
        append option " \"-redefine=param,$signalName($i)VDiv,$range,units=V\""
        append option " \"-redefine=param,$signalName($i)Offset,$offset,units=V\""
        append option " \"-reprint=param,Channel$chan,$signalName($i)\""
    }
    SetSaveSignalsStatus "Processing data..."
    if {$peakDect=="PDET"} {
        set rows [exec sdds2stream -rows=bar $rootname.sig.tmp]
        set rows1 [expr $rows /2]
        if [catch {eval exec sddsconvert $rootname.sig.tmp -pipe=out \
                     $option1 \
                     | sddsprocess -pipe \
                     \"-redefine=col,Index,i_row,type=long\" \
                     | sddsprocess -pipe=in $rootname.sig \
                     \"-redefine=col,t,Index $deltaT * $delay +,units=seconds\" \
                     "$option" \
                     \"-reprint=param,TimeStamp,$tstamp\" \
                     \"-reprint=param,Description,[APSMakeSafeQualifierString [APSMakeSafeQualifierString $comment]]\" \
                     \"-reprint=param,UserName,$env(USER)\" \
                     \"-reprint=param,ChannelLabel,C1=$signalName(0) C2=$signalName(1) C3=$signalName(2) C4=$signalName(3)\" \
                     \"-reprint=param,PeakDect,$peakDect\" \
                     \"-redefine=param,TimeDiv,$div,units=seconds\" \
                     \"-reprint=param,Rate,$rate\"  \
                     \"-redefine=param,Delay,$delay\"} result] {
            SetSaveSignalsStatus "Error processing scope data1: $result"
            return
        }
    } else {
        if [catch {eval exec sddsconvert $rootname.sig.tmp -pipe=out \
                     \"-rename=col,Channel1=$signalName(0),Channel2=$signalName(1),Channel3=$signalName(2),Channel4=$signalName(3)\" \
                     | sddsprocess -pipe \
                     $extraOpt \
                     \"-redefine=col,Index,i_row,type=long\" \
                     | sddsprocess -pipe=in $rootname.sig \
                     \"-redefine=col,t,Index $deltaT * $delay +,units=seconds\" \
                     "$option" \
                     \"-reprint=param,TimeStamp,$tstamp\" \
                     \"-reprint=param,Description,[APSMakeSafeQualifierString [APSMakeSafeQualifierString $comment]]\" \
                     \"-reprint=param,UserName,$env(USER)\" \
                     \"-reprint=param,ChannelLabel,C1=$signalName(0) C2=$signalName(1) C3=$signalName(2) C4=$signalName(3)\" \
                     \"-reprint=param,PeakDect,$peakDect\" \
                     \"-redefine=param,TimeDiv,$div,units=seconds\" \
                     \"-reprint=param,Rate,$rate\"  \
                     \"-redefine=param,Delay,$delay\"} result] {
            SetSaveSignalsStatus "Error processing scope data2: $result"
            return
        }
    }
    APSUpdateUseLog $rootname.sig.log create
    exec rm $rootname.sig.tmp

     if [catch {exec sendHP9000ScopeCommand -ring $ring -command ":RUN"} result] {
        SetSaveSignalsStatus "Error: $result"
    }
    if $fixWfs {
        exec sddsprocess $rootname.sig -nowarning \
          "-redefine=col,fRow,i_row n_rows /" \
          -filter=col,fRow,-1,0.5 \
          "-redefine=column,t,t 2 *,units=s" 
        exec rm -f $rootname.sig~
    }
    if [file exists $rootname.sig] {
        SetSaveSignalsStatus "Save completed"
	ReviewScopeSignals $rootname
    } else {
        SetSaveSignalsStatus "Save failed."
        bell
    }
}


proc SaveScopeSignals {comment} {
    global scopeID signalState signalName rootSaveScopeSignals env fixWfs cateFile scalarFile channelName dataDir
    if {[regexp HP9000 $scopeID]} {
        catch {SaveHP9000ScopeSignals $comment} result
        return
    }
    set rootSaveScopeSignals [exec date +%Y%m%d-%H%M%S]
    set rootname $dataDir/$rootSaveScopeSignals
    update
    after 500
    if {[string length $comment]==0} {
        SetSaveSignalsStatus "You must supply a comment in order to save signals"
        bell
        return
    }
   
    set comment [APSMakeSafeQualifierString $comment]
    SetSaveSignalsStatus "Verifying signal information..."
    RefreshSettings
    set first 1
    set plotlist ""
    foreach i { 0 1 2 3 } {
        if {$signalState($i)} {
            if {$first} { 
                set plotlist $signalName($i)
            } else {
                set plotlist "$plotlist,$signalName($i)"
            }  
            set first 0
        }
    }

    if {[string length $plotlist]==0} {
        SetSaveSignalsStatus "No channels are on---nothing saved."
        bell
        return
    }
    if [catch {exec sendScopeCommand $scopeID :STOP} result] {
        SetSaveSignalsStatus "Error: $result"
    }
    if [catch {exec sendScopeCommand $scopeID ":ACQ:TYPE?"} peakDect] {
        SetSaveSignalsStatus "Error: $peakDect"
        set peakDect Unknown
    }
    if [catch {exec sendScopeCommand $scopeID ":TIM:DELAY?"} Delay] {
        SetMainStatus "Error: $Delay"
    }
    if [catch {exec sendScopeCommand $scopeID ":TIM:RANG?"} div] {
        set points 10
    } 
    
    #whole range has 10 divisions, so the time per division is as following
    set div [expr $div/10.0]
    if [catch {exec sendScopeCommand $scopeID ":TIM:SAMP:CLOCK?"} rate] {
        set points 10
    }
    global clockRateList clockValueList
    set rate [string trim $rate]
    set points [expr $div * [lindex $clockValueList [lsearch $clockRateList $rate]]]
    
    set extraOpt ""
    if {[string length $cateFile] && [file exist $cateFile] && [file exist $scalarFile]} {
        if [catch {exec cavget -list=${channelName} -list=1,2,3,4 -printErrors } valList] {
            return -code error $result
        }
        set tmpfile /tmp/[APSTmpString]
        if [catch {exec sddsprocess $cateFile -pipe=out \
                     "-match=col,MuxValue=[lindex $valList 0],MuxValue=[lindex $valList 1],|,MuxValue=[lindex $valList 2],|,MuxValue=[lindex $valList 3],|" \
                     | sddssort -pipe -col=Category -unique \
                     | sdds2stream -pipe -col=Category } cateList] {
            SetSaveSignalsStatus "No category found for muxes: [join $valList]\nNo scalars will be logged."
        } else {
            set opt ""
            foreach cate $cateList {
                if ![string length $opt] {
                    set opt -match=col,Category=$cate
                } else {
                    append opt ,Category=$cate,|
                }
            }
            if [catch {eval exec sddsprocess $scalarFile $opt -pipe=out \
                         | sddssort -pipe -col=ReadbackName -unique -numericHigh \
                         | sddscasr -pipe=in -save $tmpfile.2 } result] {
                return -code error $result
            }
            set pvList [exec sdds2stream -col=ControlName $tmpfile.2]
            set valList [exec sdds2stream -col=ValueString $tmpfile.2]
            set nameList [exec sdds2stream -col=ReadbackName $tmpfile.2]
            set extraOpt ""
            
            foreach name $nameList pv $pvList val $valList {
                if [catch {expr $val /2} result] {
                    #string value
                    lappend extraOpt "-reprint=par,$name,$val,symbol=$pv"
                } else {
                    lappend extraOpt -redefine=par,$name,$val,symbol=$pv
                }
            }
        }
    }
    set first 1
    foreach i { 0 1 2 3 } {
        set channel [expr $i+1]
        if {$signalState($i)} {
            SetSaveSignalsStatus "Saving channel $channel..."
            if {$first} { 
                set filename $rootname.sig
            } else {
                set filename $rootname.$channel
            }  
            catch {exec getScopeWaveform $scopeID c$channel $filename -signal=$signalName($i) -single} 
            if ![file exists $filename] {
                SetSaveSignalsStatus "Failed to save data for channel $channel!"
                bell
                continue
            }
            exec chmod oug+w $filename
            if [catch {exec sendScopeCommand $scopeID ":CHAN$channel:OFFS?"} offset] {
                SetSaveSignalsStatus "Error: $offset"
            }
            if [catch {exec sendScopeCommand $scopeID ":CHAN$channel:RANG?"} range] {
                SetSaveSignalsStatus "Error: $range"
            }
            set range  [expr $range/8.0]
            if {!$first} {
                exec sddsxref $rootname.sig $filename -nowarning
                exec rm $filename
            } else {
                set tstamp [exec date]
                eval  exec sddsprocess $rootname.sig -nowarning \
                  $extraOpt \
                  \"-reprint=param,TimeStamp,$tstamp\" \
                  \"-reprint=param,Description,[APSMakeSafeQualifierString [APSMakeSafeQualifierString $comment]]\" \
                  \"-reprint=param,UserName,$env(USER)\" \
                  \"-reprint=param,Channel1,$signalName(0)\" \
                  \"-reprint=param,Channel2,$signalName(1)\" \
                  \"-reprint=param,Channel3,$signalName(2)\" \
                  \"-reprint=param,Channel4,$signalName(3)\" \
                  \"-reprint=param,ChannelLabel,C1=$signalName(0) C2=$signalName(1) C3=$signalName(2) C4=$signalName(3)\" \
                  \"-reprint=param,PeakDect,$peakDect\" \
                  \"-redefine=param,PointsPerDiv,$points,type=long\" \
                  \"-redefine=param,TimeDiv,$div,units=seconds\" \
                  \"-reprint=param,Rate,$rate\"  \
                  \"-redefine=param,Delay,$Delay\"
                APSUpdateUseLog $rootname.sig.log create
            }
            set rangeLabel [format "%.2g" $range]
            exec sddsprocess $rootname.sig -nowarning -redefine=col,Index,i_row,type=long \
              "-redefine=col,$signalName($i)Scaled,$signalName($i) $offset - $range /,units=Div,symbol=$signalName($i)/($rangeLabel V/div)"  \
              "-redefine=param,$signalName($i)VDiv,$range,units=V" \
              "-redefine=param,$signalName($i)Offset,$offset,units=V"
            if $fixWfs {
                exec sddsprocess $rootname.sig -nowarning \
                    "-redefine=col,fRow,i_row n_rows /" \
                    -filter=col,fRow,-1,0.5 \
                    "-redefine=column,t,t 2 *,units=s" 
            }
            exec rm -f $rootname.sig~
            set first 0
        }
    }
    if [catch {exec sendScopeCommand $scopeID :RUN} result] {
        SetSaveSignalsStatus "Error: $result"
    }
    if [file exists $rootname.sig] {
        SetSaveSignalsStatus "Save completed"
	ReviewScopeSignals $rootname
	if {0} {
	set x1 [expr $Delay - 5*$div]
	set x2 [expr $Delay + 5*$div] 
        exec sddsplot -split=page -col=t,*Scaled $rootname.sig -graph=line,vary -pspace=0.15,0.8,0.175,0.9 \
          -lspace=1.01,1.28,0.0,1.0 -filter=col,t,$x1,$x2 \
          -legend=ysymbol,scale=1.5 -ylabel=Division  \
          -topline=$rootname -title=@Description &
	}
    } else {
        SetSaveSignalsStatus "Save failed."
        bell
    }
    
   # set rootSaveScopeSignals [exec date +%Y%m%d-%H%M%S]
}
 
proc DoConvolvePlot {rootname} {
     
    global sddsplotOptions reviewChoicesPresent
    if {[string length $rootname]==0} {
        if {!$reviewChoicesPresent} {
            SetReviewScopeStatus "Perform a search first to get a list of choices"
            return 
        }
        SetReviewScopeStatus "Select a configuration from the list below"
        return
    }
    
    SetReviewScopeStatus "Doing convovlution..."
    set pars [exec sddsquery -par $rootname.sig] 
    set tmpRoot /tmp/[APSTmpString]
    if [lsearch $pars "Delay"]<0 {
        set rows [exec sdds2stream -rows=bar $rootname.sig]
        if $rows<2000 {
            set row2 $rows
        } else {
            set row2 2000
        }
        if [catch {exec sddsprocess $rootname.sig -pipe=out -redefine=col,Index,i_row,type=long \
                       | sddsprocess -pipe=in $tmpRoot.sig0 -filter=col,Index,0,$row2} result] {
            return -code error $result
        }
    } else {
        set delay [exec sdds2stream -par=Delay -page=1 $rootname.sig]
        set div [exec sdds2stream -par=TimeDiv -page=1 $rootname.sig]
        set t1 [expr $delay - 5 * $div]
        set t2  [expr $delay + 5 * $div]
        if [catch {exec sddsprocess $rootname.sig -pipe=out -filter=col,t,$t1,$t2 \
                       | sddsprocess -pipe=in $tmpRoot.sig0 -redefine=col,Index,i_row,type=long } result] {
            return -code error $result
        }
    }
 
    set expand 10
    set rows [exec sdds2stream -page=1 -rows=bar $tmpRoot.sig0]
    set nTotal [expr $rows * $expand]
    set total [expr $nTotal + 1]
    APSAddToTmpFileList -ID scope -fileList $tmpRoot.sig1
    if [catch {exec sddsprocess $tmpRoot.sig0 -pipe=out "-redefine=col,Index,Index $expand *" \
                   | sddsinterp -pipe -col=Index,*Scaled \
                   -sequence=$total,0,$nTotal \
                   | sddsprocess -pipe=in $tmpRoot.sig \
                   "-redefine=col,%s,Index $expand / int Index $expand / == ? %s : 0 $,select=*Scaled" } result] {
        return -code error $result
    }
    APSAddToTmpFileList -ID scope -fileList "$tmpRoot.sig0 $tmpRoot.sig "
    
    set row1 [expr -($total / 2)]
    set row2 [expr $total + $row1 -1]
    if [catch {exec sddssequence -pipe=out -define=Index -sequence=begin=$row1,end=$row2,delta=1 \
                   | sddsprocess -pipe=in $tmpRoot.sinc \
                   "-redefine=col,sincN,Index 0 == ? 1 : Index pi * $expand / sin Index / pi / $expand * $ " } result] {
        return -code error $result
    } 
    APSAddToTmpFileList -ID scope -fileList "$tmpRoot.sinc $tmpRoot.sig"
    set columns [exec sddsquery -col $rootname.sig]
    set fileList ""

    foreach column $columns {
        if [regexp {Scaled} $column] {
            if [catch {exec sddsconvolve \
                           $tmpRoot.sig $tmpRoot.sinc $tmpRoot.$column \
                           -signal=Index,$column -response=Index,sincN -output=Index,${column}Con } result] {
                return -code error $result
            }              
            lappend fileList $tmpRoot.$column
        }
    }
   
    if [catch {eval exec sddsxref $fileList  -take=*Con -pipe=out \
                   | sddsprocess -pipe=in $tmpRoot.convolve \
                   \"-reprint=par,Rootname,$rootname\" \
                   \"-reprint=par,Description,After Convolution\" } result] {
        return -code error $result
    }
  
    lappend fileList $tmpRoot.convolve
    APSAddToTmpFileList -ID scope -fileList $fileList
    SetReviewScopeStatus "Making plots..."
    eval exec sddsplot -yExclude=*OFF* -split=page $sddsplotOptions -graph=line,vary -pspace=0.15,0.8,0.175,0.9 \
        -lspace=1.01,1.28,0.0,1.0 \
        -legend=ysymbol,scale=1.5 -ylabel=Division  \
        -topline=$rootname -title=@Description \
        -group=namestring -sep=2 \
        -col=Index,*Con $tmpRoot.convolve  &
}

proc MakeSRScopeButtons {parent} {
    frame ${parent}.srscope -bd 6
    pack ${parent}.srscope -side top -fill x
    button ${parent}.srscope.save -text "SAVE SCOPE..." \
      -command SaveScopeSettingsWidget -relief raised
    button ${parent}.srscope.restore -text "RESTORE SCOPE/MAKE REFERENCE..." \
      -command RestoreScopeSettingsWidget -relief raised
    button ${parent}.srscope.sigsave -text "SAVE SIGNALS..." \
      -command SaveScopeSignalsWidget -relief raised
    button ${parent}.srscope.sigreview -text "REVIEW SIGNALS..." \
      -command ReviewScopeSignalsWidget -relief raised
    pack ${parent}.srscope.save ${parent}.srscope.restore ${parent}.srscope.sigsave \
      ${parent}.srscope.sigreview
}


APSApplication . -name $windowTitle -version $CVSRevisionAuthor -overview "This is the scope save/restore utility for scope $scopeID"
MakeTimebaseMenu .menu
MakePeakDetectMenu .menu
MakeDisplaysMenu .menu
MakeSaveLocalMenu .menu
MakeRecallLocalMenu .menu

APSScrolledStatus .status -parent .userFrame \
  -textVariable mainStatus -width 80  -height 5
SetMainStatus "Reading scope parameters..."

MakeSignalNamesWidget .userFrame
MakeTimebaseWidget .userFrame .timebase
SetMainStatus ""
MakeSRScopeButtons .userFrame

