### MODIFICATION RECORD #####
#
# $Log: not supported by cvs2svn $
# Revision 1.59  2012/08/14 10:08:47 shang
# added waiting for DSP sample off in addition to stop running since the EPICS waveform is updated right after sample off.
# and added waiting 2 seconds after sample off to be safe.
#
# Revision 1.58  2012/08/14 09:37:53 shang
# added addition waiting time of 5 seconds after DSP stopped running to wait for the EPICS waveform being updated.
#
# Revision 1.57  2012/08/09 16:32:53 shang
# instead of waiting 4 seconds after clicking the "sample" button on DSP scope, it now waits for DSP scope data collection to be completed,
# because it could take much longer than 4 seconds for the DSP scope to collect the data sometimes (depending on the sample skip).
#
# Revision 1.56  2008/02/06 17:44:46  soliday
# Removed calls to setfacl because it is no longer needed.
#
# Revision 1.55  2008/01/17 16:33:51  soliday
# Put setfacl commands inside of catch statements. I don't think the commands
# are needed anymore with the new file servers but I am not sure.
#
# Revision 1.54  2004/06/08 15:54:59  emery
# Added argument -description to APSSaveSRFBDspScope.
#
# Revision 1.53  2004/06/04 17:43:14  emery
# Removed test of presence of Description parameter
# from APSRestoreSRFBDspScope.
#
# Revision 1.52  2004/03/24 07:41:47  emery
# Rewrote the way the list of waveforms names are created for the 40
# channels. Added setfacl to fix the mask of the configuration file.
#
# Revision 1.51  2004/02/21 00:30:55  shang
# added catch statments to APSRestoreSRFBDspScope proc
#
# Revision 1.50  2004/01/25 13:17:52  borland
# Increased all pend-io times to 30s.
#
# Revision 1.49  2003/10/07 16:29:32  emery
# Using new procedure APSMakeSafeQualifierStringForEval for
# APSTrigReadSRFBDspScope sdds command.
#
# Revision 1.48  2003/10/02 15:02:21  soliday
# Added additional sdds close statement.
#
# Revision 1.47  2003/10/01 08:05:01  emery
# Cleaned up APSRestoreSRFBDspScope by replaceing for loops with
# foreach loops with multiple lists.
#
# Revision 1.46  2003/08/19 22:02:54  emery
# Changed error message in APSSaveSRFBDspScope so that the procedure
# returns an error code.
#
# Revision 1.45  2002/12/01 05:52:37  emery
# Forgot a continuation (\) for new sddsprocess argument.
#
# Revision 1.44  2002/12/01 05:45:47  emery
# Added comment option to APSTrigReadSRFBDspScope for including a string
# quantity into the raw files.
#
# Revision 1.43  2002/11/28 12:46:54  emery
# Changed sddswmonitor -ezca argument to -pendiotime=20
#
# Revision 1.42  2002/10/23 14:10:40  soliday
# Replaced directory /home/helios/oagData/sr/orbitFeedback
#
# Revision 1.41  2001/02/06 19:44:25  soliday
# Fixed some tcl warning messages found with procheck
#
# Revision 1.40  2000/08/31 18:42:14  carwar
# Resolved clock format vs date exec conflict from editing older version
#
# Revision 1.39  2000/08/30 21:25:50  carwar
# Fixed text problem (found '<<<<< in APSTrigReadSRFBDspScope tool)
#
# Revision 1.38  2000/07/31 13:31:01  carwar
# Removed temporary patch
#
# Revision 1.37  2000/07/31 10:15:27  carwar
# Temporarily commented out 'set bpmSel...' row
#
# Revision 1.36  1999/02/25 16:41:00  soliday
# Replaced exec date commands with clock commands
#
# Revision 1.35  1998/11/20 22:24:46  carwar
# Changed default view of moreframe command
#
# Revision 1.34  1998/10/14 13:20:13  carwar
# Fixed problem with saving/restoring xbpm setup for dspscope.
#
# Revision 1.33  1998/08/28 20:05:36  carwar
# Added save/restore of dspscope trigger windows.
#
# Revision 1.32  1998/07/30 01:21:49  carwar
# Changed restore configuration to warn about missing params not to bomb.
#
# Revision 1.31  1998/07/09 18:54:34  carwar
# Added support for acvoltmeter to the save/restore files
#
# Revision 1.30  1998/06/25 17:48:40  carwar
# Fixed typo in savedspscope routine with reading bpm error PVs.
#
# Revision 1.29  1998/06/16 18:43:02  carwar
# Fixed type in column names for P0 bpms in savedspscope routine
#
# Revision 1.28  1998/06/15 17:21:43  carwar
# Added A:P0/B:P0 selection to dspscope routines.
#
# Revision 1.27  1998/06/15 16:40:41  carwar
# Added P0 bpms to saveDspscope proc.
#
# Revision 1.26  1998/06/08 18:54:35  carwar
# Made sure clearing is only done when channels are restored
#
# Revision 1.25  1998/06/08 18:49:34  carwar
# Added options to only restore timing or channels to restoredspscope
#
# Revision 1.24  1998/05/15 14:08:41  carwar
# Added saving of sampling rate when collecting data from dspscope
#
# Revision 1.23  1998/03/24 10:21:06  carwar
# Added update cmd to end of 'restoring configuration' line
#
# Revision 1.22  1998/02/05 17:51:19  carwar
# Extended timeout again to 20 seconds
#
# Revision 1.21  1998/02/05 17:36:28  carwar
# Extended ezca timing to trigreadscope because of slow access to waveforms
#
# Revision 1.20  1998/01/08 02:09:46  carwar
# Error routines were pointing at non-existing variables
#
# Revision 1.19  1998/01/06 21:14:11  carwar
# Fixed bug with sddswmonitor collection of scalar values
#
# Revision 1.18  1998/01/06 21:06:19  carwar
# Another try...
#
# Revision 1.17  1998/01/06 21:03:58  carwar
# Trying again to fix bug with sddswmonitor
#
# Revision 1.16  1998/01/06 21:01:49  carwar
# Trying to fix bug in addition of PV names to sddswmonitor
#
# Revision 1.15  1998/01/06 20:56:51  carwar
# Added collecting of feedabck status and beam current to trig-read scope routine
#
# Revision 1.14  1998/01/05 15:36:56  carwar
# Added APSCreateMoreFrame proc
#
# Revision 1.13  1998/01/05 14:50:46  carwar
# Added 'if verbose' statement
#
# Revision 1.12  1998/01/05 14:46:22  carwar
# Added verbose option to restore scope
#
# Revision 1.11  1997/12/15 18:35:02  carwar
# Fixed TrigReadScope application
#
# Revision 1.10  1997/12/09 23:02:33  carwar
# Changed ezca timing on sddswmonitor to get rid of empty data sets being returned
#
# Revision 1.9  1997/12/09 22:24:55  carwar
# Another bug fix.
#
# Revision 1.8  1997/12/09 22:19:41  carwar
# Added extra parameter to collected data file
#
# Revision 1.7  1997/12/09 22:07:31  carwar
# A couple of fixes.
#
# Revision 1.6  1997/12/09 22:04:44  carwar
# Fixed syntax error in TrigReadDspScope
#
# Revision 1.5  1997/12/09 21:58:41  carwar
# Changed name of procedure TrigReadDspScope to be consistent with other names
#
# Revision 1.4  1997/12/08 22:09:42  carwar
# Added xref'ing of dspscope setup parameters to data file.
#
# Revision 1.3  1997/12/08 20:44:43  carwar
# Fixed naming typo
#
# Revision 1.2  1997/12/08 20:43:46  carwar
# Added APSTrigReadDspScope
#
# Revision 1.1  1997/12/08 20:26:53  carwar
# Library file for procedures specific to sr orbit feedback. Includes
# setup/restore for the dspscope.
#
#
#############################

# Variables for dspscope procedures
set apsSRFB_GLOBAL_CRATES_LIST "S1FB:GB1,S1FB:GB2,S3FB:GB3,S3FB:GB4,S5FB:GB5,S5FB:GB6,S7FB:GB7,S7FB:GB8,S9FB:GB9,S9FB:GB10,S11FB:GB11,S11FB:GB12,S13FB:GB13,S13FB:GB14,S15FB:GB15,S15FB:GB16,S17FB:GB17,S17FB:GB18,S19FB:GB19,S19FB:GB20,S21FB:GB21,S21FB:GB22,S23FB:GB23,S23FB:GB24,S25FB:GB25,S25FB:GB26,S27FB:GB27,S27FB:GB28,S29FB:GB29,S29FB:GB30,S31FB:GB31,S31FB:GB32,S33FB:GB33,S33FB:GB34,S35FB:GB35,S35FB:GB36,S37FB:GB37,S37FB:GB38,S39FB:GB39,S39FB:GB40"

set apsSRFB_DSPSCOPE_PARAM_PV_LIST [list SRFB:DS:ModeMO SRFB:DS:RecordLengthAO SRFB:DS:RecordDlyAO \
                                      SRFB:DS:SampleSkipAO SRFB:DS:TrigChanAO SRFB:DS:TrigLevelAO \
                                      SRFB:DS:PreTrigSamplesAO SRFB:DS:TrigDirectionBO SRFB:DS:TrigSourceMO \
                                      SRFB:ACV:freqAO SRFB:ACV:numPointsAO SRFB:ACV:AbsValBO SRFB:ACV:SignInxAO ]

set apsSRFB_PARAM_NAME_LIST [list DSPscopeMode WaveformLength InterRecordDelay \
                               SampleSkip TriggerChannel TriggerLevel \
                               PreTriggerSamples TriggerPolarity TriggerSource \
                               ACVoltmeterFrequency ACVoltmeterPoints ACVoltmeterAbsoluteValue ACVoltmeterSignIndex ]

set apsSRFB_DSPSCOPE_COL_PV_LIST [list SectorAO SourceMO TrigLimLoAO TrigLimHiAO \
                                    RFbpmMO BpmInxAO P0BpmMO XrayBladeMO XrayBpmMO FtestInxAO]
set apsSRFB_DSPSCOPE_COL_NAME_LIST [list Sector Source TrigWindowLo TrigWindowHi \
                                      RFbpm RFbpmIndex P0Bpm XrayBpmBlade XrayBpm TestArrayIndex]

proc APSSaveSRFBDspScope {args} {
    global status
    global apsSRFB_GLOBAL_CRATES_LIST apsSRFB_DSPSCOPE_PARAM_PV_LIST 
    global apsSRFB_PARAM_NAME_LIST apsSRFB_DSPSCOPE_COL_PV_LIST apsSRFB_DSPSCOPE_COL_NAME_LIST
    set description "DSPscope Configuration File"
    APSStrictParseArguments {filename description}
    
    if {[file exists $filename]} {
        if {[APSQueryToProceed -message "File $filename exists, OK to re-use"] != 1} {
            set status "Aborted by user"
            return
        }
        APSWaitWithUpdate -waitSeconds 1
    }

    set status "Saving dspscope configuration..."; update

    set sectorList  [exec cavget -pend=30 "-delim= " -list=SRFB:DS:Chan -range=beg=0,end=39 -list=SectorAO ]
    set sourceList  [exec cavget -pend=30 "-delim= " -list=SRFB:DS:Chan -range=beg=0,end=39 -list=SourceMO ]
    set winLoList   [exec cavget -pend=30 "-delim= " -list=SRFB:DS:Chan -range=beg=0,end=39 -list=TrigLimLoAO ]
    set winHiList   [exec cavget -pend=30 "-delim= " -list=SRFB:DS:Chan -range=beg=0,end=39 -list=TrigLimHiAO ]
    set rfbpmList   [exec cavget -pend=30 "-delim= " -list=SRFB:DS:Chan -range=beg=0,end=39 -list=RFbpmMO ]
    set rfInxList   [exec cavget -pend=30 "-delim= " -list=SRFB:DS:Chan -range=beg=0,end=39 -list=BpmInxAO ]
    set xrayBpmList [exec cavget -pend=30 "-delim= " -list=SRFB:DS:Chan -range=beg=0,end=39 -list=XrayBpmMO ]
    set xrayBladeList [exec cavget -pend=30 "-delim= " -list=SRFB:DS:Chan -range=beg=0,end=39 -list=XrayBladeMO ]
    set bergozList  [exec cavget -pend=30 "-delim= " -list=SRFB:DS:Chan -range=beg=0,end=39 -list=P0BpmMO ]
    set testInxList [exec cavget -pend=30 "-delim= " -list=SRFB:DS:Chan -range=beg=0,end=39 -list=FtestInxAO ]
# this list is 4 times as long as the others.
    set XbpmSelList  [exec cavget -pend=30 "-delim= " -list=$apsSRFB_GLOBAL_CRATES_LIST -list=:bpm -range=beg=1,end=4 -list=:x:SelectedMI ]
    set YbpmSelList  [exec cavget -pend=30 "-delim= " -list=$apsSRFB_GLOBAL_CRATES_LIST -list=:bpm -range=beg=1,end=4 -list=:y:SelectedMI ]
    set params  [exec cavget -pend=30 "-delim= " -list=[join $apsSRFB_DSPSCOPE_PARAM_PV_LIST ,]]
    
    set mode [lindex $params 0]
    set length [lindex $params 1]
    set delay [lindex $params 2]
    set skip [lindex $params 3]
    set trigChan [lindex $params 4]
    set trigLev [lindex $params 5]
    set preTrig [lindex $params 6]
    set trigDir [lindex $params 7]
    set trigSrc [lindex $params 8]
    set acvFreq [lindex $params 9]
    set acvPoints [lindex $params 10]
    set acvAbsVal [lindex $params 11]
    set acvIndex [lindex $params 12]

    set channelList ""
    set wfPVList ""
    set indexList ""
    for {set i 0} {$i < 40} {incr i} {
        lappend channelList $i
        lappend indexList $i
        lappend wfPVList SRFB:DS:Chan${i}WF
    }
    set wfNamesList ""
    set unassigned 0
    foreach i $indexList sector $sectorList source $sourceList winLo $winLoList winHi $winHiList rfbpm $rfbpmList rfInx $rfInxList xrayBpm $xrayBpmList xrayBlade $xrayBladeList bergoz $bergozList testInx $testInxList channel $channelList wfPV $wfPVList {
        switch $source {
            "X Bpm Err"   { 
		set bpmSel [lindex $XbpmSelList [expr 4 * (${sector} - 1)  + $rfInx ]]
		if {$bpmSel == "16"} {
		    set bpmSel "S${sector}unassigned-${unassigned}"
		    incr unassigned 
		}
		lappend wfNamesList ${bpmSel}:Error:x
	    }
            "Y Bpm Err"   { 
		set bpmSel [lindex $YbpmSelList [expr 4 * (${sector} - 1)  + $rfInx ]]
		if {$bpmSel == "16"} {
		    set bpmSel "S${sector}unassigned-${unassigned}"
		    incr unassigned 
		}
		lappend wfNamesList ${bpmSel}:Error:y
	    }
            "X Bpm Pos"   { lappend wfNamesList S${sector}${rfbpm}:x }
            "Y Bpm Pos"   { lappend wfNamesList S${sector}${rfbpm}:y }
            "X P0 Bpm"    { lappend wfNamesList S${sector}${bergoz}:x }
            "Y P0 Bpm"    { lappend wfNamesList S${sector}${bergoz}:y }
            "ID X Bpm Pos"   { lappend wfNamesList S${sector}ID:${xrayBpm}:x }
            "ID Y Bpm Pos"   { lappend wfNamesList S${sector}ID:${xrayBpm}:y }
            "BM Y Bpm Pos"   { lappend wfNamesList S${sector}BM:${xrayBpm}:y }
            "ID X Bpm Blade" {
                scan $xrayBlade %s blade
                lappend wfNamesList S${sector}:ID:${xrayBpm}:Blade${blade}
            }
            "BM X Bpm Blade" {
                scan $xrayBlade %s blade
                lappend wfNamesList S${sector}:BM:${xrayBpm}:Blade${blade}
            }
            "H Corrector" { lappend wfNamesList S${sector}A:H3 }
            "V Corrector" { lappend wfNamesList S${sector}A:V3 }
            "H Corr Err"  { lappend wfNamesList S${sector}A:H3:Error }
            "V Corr Err"  { lappend wfNamesList S${sector}A:V3:Error }
            "Test Array"  { lappend wfNamesList S${sector}:TestArray:Chan${testInx} }
            "None" -
            default { lappend wfNamesList "None" }
        }

    }

    set fd [sdds open $filename w]
    
    sdds defineParameter $fd Description -type SDDS_STRING
    sdds defineParameter $fd TimeStamp -type SDDS_STRING
    sdds defineParameter $fd WaveformLength -type SDDS_LONG
    sdds defineParameter $fd DSPscopeMode -type SDDS_STRING
    sdds defineParameter $fd InterRecordDelay -type SDDS_LONG
    sdds defineParameter $fd SampleSkip -type SDDS_LONG
    sdds defineParameter $fd PreTriggerSamples -type SDDS_LONG
    sdds defineParameter $fd TriggerChannel -type SDDS_LONG
    sdds defineParameter $fd TriggerLevel -type SDDS_DOUBLE
    sdds defineParameter $fd TriggerPolarity -type SDDS_STRING
    sdds defineParameter $fd TriggerSource -type SDDS_STRING
    sdds defineParameter $fd ACVoltmeterFrequency -type SDDS_DOUBLE
    sdds defineParameter $fd ACVoltmeterPoints -type SDDS_LONG
    sdds defineParameter $fd ACVoltmeterAbsoluteValue -type SDDS_STRING
    sdds defineParameter $fd ACVoltmeterSignIndex -type SDDS_LONG

    sdds defineColumn $fd Channel -type SDDS_LONG
    sdds defineColumn $fd WaveformPV -type SDDS_STRING
    sdds defineColumn $fd WaveformName -type SDDS_STRING
    sdds defineColumn $fd Sector -type SDDS_LONG
    sdds defineColumn $fd Source -type SDDS_STRING
    sdds defineColumn $fd TrigWindowHi -type SDDS_DOUBLE
    sdds defineColumn $fd TrigWindowLo -type SDDS_DOUBLE
    sdds defineColumn $fd RFbpm -type SDDS_STRING
    sdds defineColumn $fd RFbpmIndex -type SDDS_LONG
    sdds defineColumn $fd P0Bpm -type SDDS_STRING
    sdds defineColumn $fd XrayBpm -type SDDS_STRING
    sdds defineColumn $fd XrayBpmBlade -type SDDS_STRING
    sdds defineColumn $fd TestArrayIndex -type SDDS_LONG
    sdds writeLayout $fd
    
    sdds startPage $fd 40
    
    sdds setParameter $fd Description $description
    sdds setParameter $fd TimeStamp "[clock format [clock seconds]]"
    sdds setParameter $fd WaveformLength "$length"
    sdds setParameter $fd DSPscopeMode "$mode"
    sdds setParameter $fd InterRecordDelay "$delay"
    sdds setParameter $fd SampleSkip "$skip"
    sdds setParameter $fd PreTriggerSamples "$preTrig"
    sdds setParameter $fd TriggerChannel "$trigChan"
    sdds setParameter $fd TriggerLevel "$trigLev"
    sdds setParameter $fd TriggerPolarity "$trigDir"
    sdds setParameter $fd TriggerSource "$trigSrc"
    sdds setParameter $fd ACVoltmeterFrequency "$acvFreq"
    sdds setParameter $fd ACVoltmeterPoints "$acvPoints"
    sdds setParameter $fd ACVoltmeterAbsoluteValue "$acvAbsVal"
    sdds setParameter $fd ACVoltmeterSignIndex "$acvIndex"

    eval sdds setColumn $fd Channel $channelList
    eval sdds setColumn $fd WaveformPV $wfPVList
    eval sdds setColumn $fd WaveformName $wfNamesList
    eval sdds setColumn $fd Sector $sectorList
    eval sdds setColumn $fd Source $sourceList
    eval sdds setColumn $fd TrigWindowHi $winHiList
    eval sdds setColumn $fd TrigWindowLo $winLoList
    eval sdds setColumn $fd RFbpm $rfbpmList
    eval sdds setColumn $fd RFbpmIndex $rfInxList
    eval sdds setColumn $fd P0Bpm $bergozList
    eval sdds setColumn $fd XrayBpm $xrayBpmList
    eval sdds setColumn $fd XrayBpmBlade $xrayBladeList
    eval sdds setColumn $fd TestArrayIndex $testInxList
    sdds writePage $fd
    sdds close $fd

    # now filter rows with a waveform name of 'None'
    if {[catch {exec sddsprocess -nowarn $filename \
                  -match=col,WaveformName=None,! \
              } result]} {
        return -code error "APSSaveSRFBDspScope: $result"
    }
    file delete ${filename}~
    #catch {exec setfacl -m mask:rwx $filename}
    set status "Done"
}

proc APSRestoreSRFBDspScope {args} {
    global status
    global apsSRFB_PARAM_NAME_LIST apsSRFB_DSPSCOPE_PARAM_PV_LIST
    global apsSRFB_DSPSCOPE_COL_NAME_LIST apsSRFB_DSPSCOPE_COL_PV_LIST

    set verbose 1
    set timing 1
    set channels 1
    set clearMode 1
    APSStrictParseArguments {filename clearMode verbose timing channels}
    
    if [catch {sdds open $filename r} fd] {
        return -code error "APSRestoreSRFBDspScope: Unable to open file $filename as an sdds file"
    }

    set cavputList ""
    if {$timing == 1} {
        foreach param $apsSRFB_PARAM_NAME_LIST pvName $apsSRFB_DSPSCOPE_PARAM_PV_LIST {
            if {[catch {sdds getParameter $fd $param} value]} {
                set status "APSRestoreSRFBDspScope: Warning: parameter $param does not exist in config file"
            } else {
                lappend cavputList $pvName=[lindex $value 0]
            }
        }
    }        
    if {$channels == 1} {
        if {[catch {sdds getColumn $fd Channel} chanList]} {
            return -code error "APSRestoreSRFBDspScope: Error reading columns in $filename"
        }
        foreach col $apsSRFB_DSPSCOPE_COL_NAME_LIST pvName $apsSRFB_DSPSCOPE_COL_PV_LIST {
            if {[catch {sdds getColumn $fd $col} valueList]} {
                set status "Warning: column $col does not exist in config file"
            } else {
                foreach channel $chanList value $valueList {
                    lappend cavputList SRFB:DS:Chan$channel$pvName=$value
                }
            }
        }

        if {$clearMode == 1} {
            if [catch {exec cavput -pend=30 -list=SRFB:DS:Chan -range=begin=0,end=39 \
                         -list=SourceMO=0} result] {
                return -code error "Error in clear mode: $result"
            }
        }
    }

    if [catch {sdds close $fd} result] {
        set status "Warning: Problem closing sdds file $filename."
    }
        
    if {$verbose == 1} {
        set status "Restoring dspscope configuration..."; update
    }

    if [catch {exec cavput -pend=30 -list=[join $cavputList ,] } result] {
        return -code error "Error in APSRestoreSRFBDspScope: $result"
    }
    if [catch {exec cavput -pend=30 -list=SRFB:DS:LoadBO=1,SRFB:ACV:LoadBO=1} result] {
        return -code error "Error in APSRestoreSRFBDspScope: $result"
    }
}   

proc APSTrigReadSRFBDspScope {args} {
    global status tmp
    set tmpfile /tmp/[APSTmpString]
    set scalarsFile /home/helios/oagData/sr/RTFB/monitorFiles/SRFBTrigReadStatus.monitor
    set comment "No description given"
    set verbose 1

    APSStrictParseArguments {datafile monitorfile verbose scalars comment}

    if {$verbose == 1} {
        set status "Triggering dspscope..."; update
    }

    # turn off trigger before retriggering
    if {[catch {eval exec cavput -pend=30 -list=SRFB:DS:SampleBO=0} result]} {
        return -code error "APSTrigReadSRFBDspScope: $result"
    }
    if {[catch {eval exec cavput -pend=30 -list=SRFB:DS:SampleBO=1} result]} {
        return -code error "APSTrigReadSRFBDspScope: $result"
    }
    
    while {[eval exec cavget -pend=30 -list=SRFB:DS:SampleBO] == "Sample"} {
        APSWaitWithUpdate -updateInterval 1 -waitSeconds 1
    }
    
    # need this delay to allow EPICS to catch up with waveform records
    #APSWaitWithUpdate -waitSeconds 4 -updateInterval 1
    #wait for 4 seconds is not long enough if the sample skip is not zero (for example, 3, it takes about 12 seconds for DSP scope to collect
    #the data)
    # added waiting for sample to be off also, since the EPICS waveform is updated right after sample is off.
    if [catch {exec cawait -waitFor=SRFB:DS:StatusMI,sameAs=Stopped \
                 -waitFor=SRFB:DS:SampleBO,sameAs=Off -and -timeLimits=100} result] {
        return -code error "APSTrigReadSRFBDspScope: error in waiting for DSP scope to update: $result"
    }
    after 2000

    if {$verbose == 1} { set status "Collecting data..."; update }
    if {[catch {eval exec sddswmonitor $monitorfile $tmpfile \
                  -scalars=$scalarsFile \
                  -pend=60} result]} {
        return -code error "APSTrigReadSRFBDspScope: $result"
    }
    if {[catch {eval exec sddsxref $tmpfile $monitorfile -pipe=out -leave=* \
                  -transfer=par,WaveformLength,DSPscopeMode,InterRecordDelay,SampleSkip,*Trigger* \
                  | sddsprocess -pipe=in $datafile \
                  \"-def=par,TickTime,SRFB:fsAO rec\" \
                  \"-print=para,Comment,[APSMakeSafeQualifierStringForEval $comment]\" \
                  \"-print=par,FileRoot,[file rootname [file tail $datafile]]\" \
              } result] } {
        return -code error "APSTrigReadSRFBDspScope: $result"
    }
    file delete $tmpfile
}

proc APSCreateMoreFrame {widget args} {
    global APSCreateMoreFrame_morebutton APSCreateMoreFrame_frame
    set label ""
    set relief ridge
    set buttonsize small
    APSStrictParseArguments {window parent label relief buttonsize}
    
    set APSCreateMoreFrame_morebutton ${parent}.morebutton
    set APSCreateMoreFrame_frame  ${parent}${widget}

    APSFrame $widget -parent $parent -label $label -relief $relief
    APSButton .morebutton -parent $parent -text "More>>" -packOption "-side top -anchor w" -size $buttonsize \
      -command { pack forget ${APSCreateMoreFrame_morebutton}; pack $APSCreateMoreFrame_frame -side top -fill x}
    APSFrame .less -parent $APSCreateMoreFrame_frame -packOption "-side top -anchor w" -relief flat
    APSButton .lessbutton -parent ${APSCreateMoreFrame_frame}.less.frame -text "<<Less" -size $buttonsize \
      -command { pack forget $APSCreateMoreFrame_frame; pack $APSCreateMoreFrame_morebutton -side top -anchor w}

    pack forget $APSCreateMoreFrame_frame
    return ${APSCreateMoreFrame_frame}.frame
}

