#
# $Log: not supported by cvs2svn $
# Revision 1.26  2009/03/20 14:47:31  shang
# made the UserDespcription parameter be able to accept "," character.
#
# Revision 1.25  2009/03/03 20:23:22  shang
# modified to get the scalar pvs from the scope configuration file and store their values as parameters in the output file.
#
# Revision 1.24  2009/02/25 17:35:38  shang
# added recording the values of P1IK, P2IK, and P4EK delays as parameters in the output file.
#
# Revision 1.23  2008/07/10 15:15:34  shang
# now writes the topup kicker parameters to the data logger (monitoring) directories
#
# Revision 1.22  2008/07/01 22:56:10  shang
# fixed the parameter processing problem -- should use .gz file instead of the uncompressed file since it no longer exists.
#
# Revision 1.21  2008/06/30 19:55:41  shang
# added units to the reference parameters
#
# Revision 1.20  2008/06/30 19:46:53  shang
# added reference Timing, Amplitude and FWHM to the parameters file.
#
# Revision 1.19  2008/06/26 21:10:53  shang
# added processing kicker parameters after waveform data is taken.
#
# Revision 1.18  2006/11/21 15:53:01  soliday
# Updated so that the timestamp used in the filename is the same time
# as when the file was created. Before there was a 2 or 4 minute offset.
#
# Revision 1.17  2006/02/17 15:22:10  borland
# Added support for continuous looping of scope waveform acquisition.
#
# Revision 1.16  2006/02/16 23:08:07  borland
# Simplified statusCallback code.  Added check for out-of-date raw scope file.
#
# Revision 1.15  2006/02/16 20:28:10  borland
# Modified APSMpDoHPScopeMeas to change order of operations so that the mux and
# scope are set up before the signal-specific routine is run. This allows the
# top-up kicker archiver to work.
#
# Revision 1.14  2001/07/29 22:56:29  borland
# APSMpDoHPScopeMeas now accepts -clipLastHalf option to allow removing the
# corrupted last halfof the waveform (for PAR scope).
#
# Revision 1.13  2000/04/26 16:39:13  soliday
# Added APSMpStep proc options.
#
# Revision 1.12  1998/07/06 17:56:36  borland
# More careful now with NormPVUnits.  Will handle strings with embedded spaces
# properly.
#
# Revision 1.11  1998/06/16 20:39:27  borland
# Now looks for NormPV column in specification files.  If found, uses to
# produce a normalized waveform.  The named PV could be a pulsed magnet
# setpoint, for example.
#
# Revision 1.10  1998/06/11 15:53:36  borland
# Added sdds close command to APSReadHPScopeMeasSpec.
#
# Revision 1.9  1998/05/20 16:11:44  borland
# Now reads and uses tMinimum and tMaximum columns from the scope specification
# files.
#
# Revision 1.8  1998/05/20 14:55:13  borland
# Now optionally prompts user for permission before changing any equipment
# configurations.
#
# Revision 1.7  1998/02/23 22:27:35  borland
# Minor bug fixes. Don't remember details.
#
# Revision 1.6  1997/09/19 15:31:47  borland
# Added -doGzip option to APSMpDoHPScopeMeas.
#
# Revision 1.5  1997/04/18 00:37:52  borland
# Default energy changed to 400MeV.  Turn on/off of rf and pulsed magnets fixed.
# Ramps rf setpoints up to avoid high reflected power.  Fixed turn on of PAR
# DC supplies.  Added combined PAR/LET stop conditioning.
#
# Revision 1.4  1997/04/09 19:54:43  borland
# User description is now accepted and saved with the data.
#
# Revision 1.3  1997/04/08 01:00:56  borland
# Now takes SCRSystem from the setup file, rather than as an argument from
# the calling routine.
#
# Revision 1.2  1997/03/12 20:57:02  borland
# Uses RUN/STOP commands on scope to assure good waveforms.  More robust
# reading of specification files.
#
# Revision 1.1  1997/01/21 23:47:16  borland
# First version.
#
#

proc APSReadHPScopeMeasSpec {args} {
    set file ""
    set variableRootname ""
    APSStrictParseArguments {file variableRootname}

    if {[llength $file]==0 || ![file exists $file]} {
        return -code error "APSReadHPScopeMeasSpec: missing/invalid file: >$file<"
    }
    
    if [catch {sdds open $file r} fid] {
        return -code error "APSReadHPScopeMeasSpec: $fid"
    }
    foreach column {WaveformName DirectoryName MuxFile ScopeFile SetupScript ScopeChannel tMinimum tMaximum NormPV} {
        catch {uplevel unset ${variableRootname}${column} }
        if [catch {sdds getColumn $fid $column} result] {
            catch {sdds close $fid}
            return -code error \
              "APSReadHPScopeMeasSpec: unable to read $column from $file: $result"
        }
        uplevel lappend ${variableRootname}${column} "$result"
    }
    foreach parameter {MainSetupScript ScopeID SCRSystem} {
        catch {uplevel unset ${variableRootname}${parameter} }
        if [catch {sdds getParameter $fid $parameter} result] {
            catch {sdds close $fid}
            return -code error \
              "APSReadHPScopeMeasSpec: unable to read $parameter from $file: $result"
        }
        # For some reason I can't get uplevel to work if the value has spaces in
        # it, so I'm using upvar.
        upvar ${variableRootname}${parameter}  localVar
        set localVar [lindex $result 0]
    }
    catch {sdds close $fid}
}

proc APSMpDoHPScopeMeas {args} {
    global execMode
    set dataDir ""
    set rootname ""
    set statusCallback APSNoOp
    set doPrompt 0
    set userDescription ""
    set doGzip 0
    set clipLastHalf 0
    set continuous 0
    set abortVariable dummyVariableAPSMpDoHPScopeMeas
    APSStrictParseArguments {dataDir rootname statusCallback doPrompt userDescription doGzip clipLastHalf continuous abortVariable}
    global $abortVariable
    set $abortVariable 0
    
    if ![string length $statusCallback] {
        set statusCallback APSNoOp
    }
    
    APSMpStep ReadMeasSpecifications -proc "APSReadHPScopeMeasSpec"
    if [catch {APSReadHPScopeMeasSpec \
                 -file $dataDir/$rootname.spec} result] {
        APSMpReturn error "APSMpDoHPScopeMeas: $result"
    }
    
    APSMpStep SaveSystemState -proc "APSSaveMachine"
    if {[string length $SCRSystem]} {
        eval $statusCallback {"Saving $SCRSystem prior to measurements."}
        if [catch {APSSaveMachine -machine $SCRSystem \
                     -description "Routine save: autosave prior to scope measurement."} \
              snapshot] {
            APSMpReturn error "APSMpDoHPScopeMeas: $snapshot"
        }
    }
    
    APSMpStep SetupEquipment
    set runID [APSTmpString]
    if {[llength $MainSetupScript]} {
        eval $statusCallback {"Doing main setup for measurement."}
        if [catch {eval $MainSetupScript -ID $runID -mode setup -doPrompt $doPrompt} result] {
            catch {eval $MainSetupScript -ID $runID -mode cleanup}
            APSMpReturn error "APSMpDoHPScopeMeas: $MainSetupScript: $result"
        }
    } else {
        set MainSetupScript APSNoOp
    }
    
    set LastScopeFile ""
    set LastMuxFile ""
    set measurements [llength $WaveformName]
    
    while {![set $abortVariable]} {
        set timeset 0
        APSMpStep SaveScopeConfiguration
        set savedScope /tmp/[APSTmpString]
        set savedMux /tmp/[APSTmpString]
        set tmpData /tmp/[APSTmpString]
        APSAddToTempFileList $savedMux $savedScope $tmpData
       # catch {exec getScopeSetup $ScopeID $savedScope}
        catch {exec saveHP54542State -filename $saveScope}
        if [catch {exec burtrb -f $dataDir/mux.req -o $savedMux} result] {
            catch {$MainSetupScript -ID $runID -mode cleanup}
            APSMpReturn error "APSMpDoHPScopeMeas: $result"
        }
       
        for {set measurement 0} {$measurement<$measurements} {incr measurement} {
            foreach column {WaveformName DirectoryName MuxFile ScopeFile SetupScript ScopeChannel tMinimum tMaximum NormPV} {
                set ${column}0 [lindex [subst \$$column] $measurement]
            }
            APSMpStep Measure$WaveformName0
            eval $statusCallback {"Working on $WaveformName0"}
            # If there's no mux file, reset and return an error 
            if ![file exists $dataDir/$MuxFile0] {
               # catch {exec putScopeSetup $ScopeID $savedScope}
                catch {exec restoreHP54542State -filename $savedScope}
                catch {exec sendHP54542ScopeCommand -command ":TRIG:LEV 1.0"}
                catch {exec sddscasr -restore $savedMux}
                catch {$SetupScript0 -ID $runID -mode cleanup}
                catch {$MainSetupScript -ID $runID -mode cleanup}
                APSMpReturn error "APSMpDoHPScopeMeas: missing file: $dataDir/$MuxFile0"
            }
            # If there's no scope setup file, reset and return an error 
            if ![file exists $dataDir/$ScopeFile0] {
                #catch {exec putScopeSetup $ScopeID $savedScope}
                catch {exec restoreHP54542State -filename $savedScope}
                catch {exec sendHP54542ScopeCommand -command ":TRIG:LEV 1.0"}
                catch {exec sddscasr -restore $savedMux}
                catch {$SetupScript0 -ID $runID -mode cleanup}
                catch {$MainSetupScript -ID $runID -mode cleanup}
                APSMpReturn error "APSMpDoHPScopeMeas: missing file: $dataDir/$ScopeFile0"
            }
            # Restore the MUX
	    if [string compare $LastMuxFile $MuxFile0] {
		eval $statusCallback {"Setting up MUX"}
		if {[catch {exec sddscasr -restore $dataDir/$MuxFile0 -pend=10
		    after 1500
		    exec sddscasr -restore $dataDir/$MuxFile0 -pend=10} result]} {
		   # catch {exec putScopeSetup $ScopeID $savedScope}
                    catch {exec restoreHP54542State -filename $savedScope}
                    catch {exec sendHP54542ScopeCommand -command ":TRIG:LEV 1.0"}
		    catch {exec sddscasr -restore $savedMux}
		    catch {$SetupScript0 -ID $runID -mode cleanup}
		    catch {$MainSetupScript -ID $runID -mode cleanup}
		    APSMpReturn error "APSMpDoHPScopeMeas: $result"
		}
		after 1000
	    }
	    set LastMuxFile $MuxFile0
            # Set up the scope, if the setup is not the same as the last channel
            if [string compare $LastScopeFile $ScopeFile0] {
                eval $statusCallback {"Setting up scope"}
                if [catch {exec restoreHP54542State -filename $dataDir/$ScopeFile0} result] {
                    # catch {exec putScopeSetup $ScopeID $savedScope}
                    catch {exec restoreHP54542State -filename $savedScope}
                    catch {exec sendHP54542ScopeCommand -command ":TRIG:LEV 1.0"}
                    catch {exec sddscasr -restore $savedMux}
                    catch {$SetupScript0 -ID $runID -mode cleanup}
                    catch {$MainSetupScript -ID $runID -mode cleanup}
                    APSMpReturn error "APSMpDoHPScopeMeas: putScopeSetup: $result"
                }
                exec sleep 10
                catch {sendHP54542ScopeCommand -command ":TRIG:LEV 1.0"}
            }
	    set LastScopeFile $ScopeFile0
            # Run the channel-specific setup script if there is one
            if {[llength $SetupScript0]} {
                eval $statusCallback {"Running setup script for $WaveformName0."}
                if  [catch {$SetupScript0 -ID $runID -mode setup -doPrompt $doPrompt -statusCallback $statusCallback} result] {
                    catch {$SetupScript0 -ID $runID -mode cleanup}
                    catch {$MainSetupScript -ID $runID -mode cleanup}
                    APSMpReturn error "APSMpDoHPScopeMeas: $SetupScript0: $result"
                }
                if [string compare $result Abort]==0 {
                    APSMpReturn ok "APSMpDoHPScopeMeas: aborted"
                }
            } else {
                set SetupScript0 APSNoOp
            }
            # Read the normalization PV, if any
            set NormPVValue 1
            set NormPVUnits ""
            if [string length $NormPV0] {
                if [catch {exec cavget -list=$NormPV0} NormPVValue] {
                    catch {exec restoreHP54542State -filename $savedScope}
                    catch {exec sendHP54542ScopeCommand -command ":TRIG:LEV 1.0"}
                    #catch {exec putScopeSetup $ScopeID $savedScope}
                    catch {exec sddscasr -restore $savedMux}
                    catch {$SetupScript0 -ID $runID -mode cleanup}
                    catch {$MainSetupScript -ID $runID -mode cleanup}
                    APSMpReturn error "APSMpDoHPScopeMeas: $NormPVValue"
                }
                catch {exec cavget -list=$NormPV0.EGU -noquotes} NormPVUnits
                set NormPVUnits [string trim $NormPVUnits]
            }
            if {[APSMpInterface] && [string compare $execMode Automatic]} {
                set oldMode $execMode
                set execMode Manual
                APSMpStep PleaseCheckEquipment
                set execMode $oldMode
            } elseif $doPrompt {
                switch [APSMultipleChoice [APSUniqueName .] -modal 1 \
                          -question "Measuring waveform $WaveformName0.  Please ensure that equipment is functional." \
                          -labelList "Skip Abort Continue" -returnList "Skip Abort Continue"] {
                              Skip {
                                  set controlMode 1
                              }
                              Abort {
                                  set controlMode 2
                              }
                              Continue {
                                  set controlMode 0
                              }
                              default {
                                  APSMpReturn error "Something impossible has happened (APSMultipleChoice returned invalid value)"
                              }
                          }
                if $controlMode {
                    if {[catch {$SetupScript0 -ID $runID -mode cleanup} result]} {
                        catch {exec putScopeSetup $ScopeID $savedScope}
                        catch {exec sddscasr -restore $savedMux}
                        catch {$MainSetupScript -ID $runID -mode cleanup}
                        APSMpReturn error "APSMpDoHPScopeMeas: $result"
                    }
                    if $controlMode==1 continue
                    break
                }
            }
            if ![string length $NormPV0] {
                set NormPV0 NONE
                set extraDescription ""
                set unitsSuffix ""
            } else {
                if $NormPVValue==0 {
                    set NormPVValue 1e-16
                }
                set extraDescription [format "$NormPV0: %g" $NormPVValue]
                if [string length $NormPVUnits] {
                    if [string match "* *" $NormPVUnits] {
                        set unitsSuffix "/($NormPVUnits)"
                    } else {
                        set unitsSuffix "/$NormPVUnits"
                    }
                }
            }
            set rowFrac 1
            if $clipLastHalf {
                set rowFrac 0.5
            }
            eval $statusCallback {"Acquiring data for $WaveformName0 from channel $ScopeChannel0."}
            set rawdatafile /home/helios4/scopetmp/[regsub {:} ${ScopeID} ""]_rawwaveform
            set mtime0 [file mtime $rawdatafile]
            set seconds [clock seconds]
            if {$timeset == 0} {
                set timeset 1
                set seconds [clock seconds]
                set timeStamp [clock format $seconds]
                set file [clock format $seconds -format %Y-%j-%m%d-%H%M%S]
            }

            if [catch {APSReadScopeScalars -dataDir $dataDir -scopeChannel $ScopeChannel0 -scopeID $ScopeID } extraOpt] {
                APSMpReturn error "APSMpDoHPScopeMeas (Error in read scope scalars): $extraOpt"
            }
            if {[catch \
                   {  exec getHP54542Data \
                        -filename $tmpData -channel $ScopeChannel0 -signalName $WaveformName0
                       eval exec sddsprocess $tmpData $dataDir/$DirectoryName0/$file  \
                        $extraOpt \
                        \"-test=column,i_row n_rows $rowFrac * <\" \
                        \"-filter=column,t,$tMinimum0,$tMaximum0\" \
                        \"-print=param,NormalizationPVName,$NormPV0\" \
                        \"-define=param,NormalizationPVValue,$NormPVValue,units=$NormPVUnits\" \
                        \"-print=param,UserDescription,[APSMakeSafeQualifierString [APSMakeSafeQualifierString $userDescription]]  $extraDescription\" \
                        -define=param,Time,$seconds,units=s \
                        -define=param,Channel,$ScopeChannel0,type=long \
                        \"-define=column,${WaveformName0}Norm,${WaveformName0} NormalizationPVValue /,units=V$unitsSuffix\" \
                        -print=param,WaveformName,$WaveformName0 \
                        \"-print=param,TimeStamp,$timeStamp\"} result]} {
                catch {exec restoreHP54542State -filename $savedScope}
                #catch {exec putScopeSetup $ScopeID $savedScope}
                catch {exec sddscasr -restore $savedMux}
                catch {$SetupScript0 -ID $runID -mode cleanup}
                catch {$MainSetupScript -ID $runID -mode cleanup}
                APSMpReturn error "APSMpDoHPScopeMeas: $result"
            }
            set mtime1 [file mtime $rawdatafile]
            if $mtime0==$mtime1 {
               # APSMpReturn error "APSMpDoHPScopeMeas: raw scope file wasn't updated"
            }
            if {$doGzip && [catch {exec gzip $dataDir/$DirectoryName0/$file} result]} {
                APSMpReturn error "APSMpDoHPScopeMeas: $result"
            }
            catch {APSProcessKickerParameters -file $dataDir/$DirectoryName0/$file} result
	    
            if {[llength $SetupScript0] && \
                    [catch {$SetupScript0 -ID $runID -mode cleanup} result]} {
                catch {exec restoreHP54542State -filename $savedScope}
                #catch {exec putScopeSetup $ScopeID $savedScope}
                catch {exec sddscasr -restore $savedMux}
                catch {$MainSetupScript -ID $runID -mode cleanup}
                APSMpReturn error "APSMpDoHPScopeMeas: $result"
            }
        }
        if !$continuous break
    }
    APSMpStep Cleanup
    #catch {exec putScopeSetup $ScopeID $savedScope}
    catch {exec restoreHP54542State -filename $savedScope}
    catch {exec sendHP54542ScopeCommand -command ":TRIG:LEV 1.0"}
    catch {exec sddscasr -restore $savedMux}
    if [catch {eval $MainSetupScript -ID $runID -mode cleanup} result] {
        APSMpReturn error "APSMpDoHPScopeMeas: $result"
    }
    APSMpReturn ok $measurements
}

proc APSProcessKickerParameters {args} {
    set file ""
    APSStrictParseArguments {file}
   
    set dir [file dir $file]
    if {$dir=="."} {
        set dir [pwd]
    }
    set kicker [scan [file tail $dir] TopUpIK%ld]
    
    if [catch {expr $kicker / 2} result] {
        return
    }
    set rootname [string range [file tail $file] 0 12]
    set tmpRoot /tmp/[APSTmpString]
    if [catch {exec  sddssmooth $dir/IK${kicker}.ref.gz -pipe=out -col=IK$kicker -passes=3 -points=5 \
                   | sddsprocess -pipe  \
                   -proc=IK$kicker,max,RefTiming,position,functionof=t \
                   -proc=IK$kicker,fwhm,RefFWHM,functionof=t \
                   -proc=IK$kicker,amplitude,RefAmplitude \
                   | sddscollapse -pipe=in $tmpRoot.1 } values] {
        return -code error "APSProcessKickerParameters1: $values"
    }
    set timing [exec sdds2stream -col=RefTiming $tmpRoot.1]
    set fwhm [exec sdds2stream -col=RefFWHM $tmpRoot.1]
    set amp [exec sdds2stream -col=RefAmplitude $tmpRoot.1]
    if ![file exist $file] {
	set file $file.gz
	if ![file exist $file] {
            set files [glob ${tmpRoot}*]
            catch {eval file delete -force $files}
	    return -code "APSProcessKickerParameters2: $file does not exist!"
	}
    }
    if [catch {exec sddssmooth $file -pipe=out -col=IK$kicker -passes=3 -points=5 \
                   | sddsprocess -pipe -nowarnings \
                   -proc=IK$kicker,max,Timing,position,functionof=t \
                   -proc=IK$kicker,fwhm,FWHM,functionof=t \
                   -proc=IK$kicker,amplitude,Amplitude \
                   | sddscollapse -pipe \
                   | sddsprocess -pipe=in -redefine=col,ReferenceTiming,$timing,units=s \
                   -redefine=col,ReferenceAmplitude,$amp,units=V \
                   -redefine=col,ReferenceFWHM,$fwhm,units=s $tmpRoot } result] {
        set files [glob ${tmpRoot}*]
        catch {eval file delete -force $files}
        return -code error "APSProcessKickerParameters3: $result"
    }
    #procesPeakByFit: see Louis' script /home/helios/SR/daily/2018/02/02/3/kickerInvestigation/processPeaksByFit
    
    if [catch {exec sddsprocess $file -pipe=out \
                 -proc=IK$kicker,min,%sMin \
                 -proc=IK$kicker,max,%sMax\
                 | sddsprocess -pipe \
                 "-def=para,IK${kicker}FitBoundary,IK${kicker}Max 3 * IK${kicker}Min + 4 /" \
                 | sddsprocess -pipe \
                 -filter=col,IK$kicker,IK${kicker}FitBoundary,1e30 \
                 | sddspfit -pipe  -col=t,IK$kicker  \
                 -order=0,1,2 \
                 -xOffset=3.612e-4 \
                 | tee $tmpRoot.fit \
                 | sddsprocess -pipe \
                 -process=IK${kicker}Fit,max,%sPeakPos,functionof=t,position \
                 -process=IK${kicker}Fit,max,%sPeak,functionof=t \
                 | sddscollapse -pipe=in $tmpRoot.b } result] {
        return -code error "APSProcessKickerParameters4: $result"
    }
    if [catch {exec sddsxref $tmpRoot $tmpRoot.b $tmpRoot.a -take=* } result] {
         return -code error "APSProcessKickerParameters5: $result"
    }
    
    set parDir /home/helios/oagData/monitoring/TopUpIK$kicker
    set filename $parDir/TopUpIK${kicker}-${rootname}.sdds
    if [file exist $filename.gz] {
        if [catch {exec sddscombine $filename.gz $tmpRoot.a $tmpRoot.c -merge -over} result] {
            set files [glob ${tmpRoot}*]
            catch {eval file delete -force $files}
            return -code error $result
        }
        catch {file delete -force $filename $filename.gz}
        exec mv $tmpRoot.c $filename
    } else {
        exec mv $tmpRoot.a $filename
    }
    if [catch {exec gzip $filename} result] {
        set files [glob ${tmpRoot}*]
        catch {eval file delete -force $files}
        return -code error $result
    }
    set files [glob ${tmpRoot}*]
    catch {eval file delete -force $files}
    return
}

proc APSReadScopeScalars {args} {
    set dataDir ""
    set scopeChannel ""
    set scopeID ""
    APSStrictParseArguments {dataDir scopeChannel scopeID} 

    switch $scopeID {
        P:DO1 {
            set scope par
        }
        S:DO1 {
            set scope sr
        }
        default {
            return ""
        }
    }
    if [catch {exec cavget -list=${scope}scopechan$scopeChannel -printErrors} mux] {
        return -code error "APSReadScopeScalars(1): Error in reading ${scope}scopechan$scopeChannel : $mux"
    }
    if [catch {exec sddsprocess $dataDir/scopeCategory.sdds "-match=col,MuxValue=[lindex $mux 0]" -nowarnings -pipe=out \
                 | sdds2stream -pipe -col=Category } category] {
        return -code error "APSReadScopeScalars(2): Error getting the category for $mux : $category"
    }
    if ![string length $category] {
        return ""
    }
    set tmpfile /tmp/[APSTmpString]
    if [catch {exec sddsprocess $dataDir/scopeScalars.sdds "-match=col,Category=[lindex $category 0]" -pipe=out \
                 | sddssort -pipe -col=ControlName -numericHigh -unique \
                 | sddscasr -save -pipe=in $tmpfile } result] {
        return -code error "APSReadScopeScalars(3): Error reading the scalars for $mux : $result"
    }
    set pvList [exec sdds2stream -col=ControlName $tmpfile]
    set valList [exec sdds2stream -col=ValueString $tmpfile]
    set nameList [exec sdds2stream -col=ReadbackName $tmpfile]
    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
        }
    }
    return $extraOpt
}

proc APSMpDoHP9000ScopeMeas {args} {
    global execMode
    set dataDir ""
    set rootname ""
    set statusCallback APSNoOp
    set doPrompt 0
    set userDescription ""
    set doGzip 0
    set clipLastHalf 0
    set continuous 0
    set abortVariable dummyVariableAPSMpDoHPScopeMeas
    set ring PAR
    APSStrictParseArguments {dataDir rootname statusCallback doPrompt userDescription doGzip clipLastHalf continuous abortVariable ring}
    global $abortVariable
    set $abortVariable 0
    
    if ![string length $statusCallback] {
        set statusCallback APSNoOp
    }
    
    APSMpStep ReadMeasSpecifications -proc "APSReadHPScopeMeasSpec"
    if [catch {APSReadHPScopeMeasSpec \
                 -file $dataDir/$rootname.spec} result] {
        APSMpReturn error "APSMpDoHP9000ScopeMeas1: $result"
    }
    
    APSMpStep SaveSystemState -proc "APSSaveMachine"
    if {[string length $SCRSystem]} {
        eval $statusCallback {"Saving $SCRSystem prior to measurements."}
        if [catch {APSSaveMachine -machine $SCRSystem \
                     -description "Routine save: autosave prior to scope measurement."} \
              snapshot] {
            APSMpReturn error "APSMpDoHP9000ScopeMeas2: $snapshot"
        }
    }
    
    APSMpStep SetupEquipment
    set runID [APSTmpString]
    if {[llength $MainSetupScript]} {
        eval $statusCallback {"Doing main setup for measurement."}
        if [catch {eval $MainSetupScript -ID $runID -mode setup -doPrompt $doPrompt} result] {
            catch {eval $MainSetupScript -ID $runID -mode cleanup}
            APSMpReturn error "APSMpDoHP9000ScopeMeas3: $MainSetupScript: $result"
        }
    } else {
        set MainSetupScript APSNoOp
    }
    
    set LastScopeFile ""
    set LastMuxFile ""
    set measurements [llength $WaveformName]
    
    while {![set $abortVariable]} {
        set timeset 0
        APSMpStep SaveScopeConfiguration
        set savedScope /tmp/[APSTmpString]
        set savedMux /tmp/[APSTmpString]
        set tmpData /tmp/[APSTmpString]
        APSAddToTempFileList $savedMux $savedScope $tmpData
	eval $statusCallback {"[exec which hp9000ScopeSocketCommand]"}
        if [catch {exec hp9000ScopeSocketCommand -ring $ring -save $savedScope} result] {
	    APSMpReturn error "APSMpDoHP9000ScopeMeas4a (error saving scope settings: $result"
	}
        if [catch {exec burtrb -f $dataDir/mux.req -o $savedMux} result] {
            catch {$MainSetupScript -ID $runID -mode cleanup}
            APSMpReturn error "APSMpDoHP9000ScopeMeas4: $result"
        }
        set seconds [clock seconds]
        set file [clock format $seconds -format %Y-%j-%m%d-%H%M%S]
        for {set measurement 0} {$measurement<$measurements} {incr measurement} {
            foreach column {WaveformName DirectoryName MuxFile ScopeFile SetupScript ScopeChannel tMinimum tMaximum NormPV} {
                set ${column}0 [lindex [subst \$$column] $measurement]
            }
            APSMpStep Measure$WaveformName0
            eval $statusCallback {"Working on $WaveformName0"}
            # If there's no mux file, reset and return an error 
            if ![file exists $dataDir/$MuxFile0] {
                catch {exec hp9000ScopeSocketCommand  -ring $ring  -restore $savedScope}
                catch {exec sddscasr -restore $savedMux}
                catch {$SetupScript0 -ID $runID -mode cleanup}
                catch {$MainSetupScript -ID $runID -mode cleanup}
                APSMpReturn error "APSMpDoHP9000ScopeMeas5: missing file: $dataDir/$MuxFile0"
            }
            # If there's no scope setup file, reset and return an error 
            if ![file exists $dataDir/$ScopeFile0] {
                catch {exec  hp9000ScopeSocketCommand -ring $ring  -restore $savedScope}
                catch {exec sddscasr -restore $savedMux}
                catch {$SetupScript0 -ID $runID -mode cleanup}
                catch {$MainSetupScript -ID $runID -mode cleanup}
                APSMpReturn error "APSMpDoHP9000ScopeMeas6: missing file: $dataDir/$ScopeFile0"
            }
            # Restore the MUX
	    if [string compare $LastMuxFile $MuxFile0] {
		eval $statusCallback {"Setting up MUX"}
		if {[catch {exec sddscasr -restore $dataDir/$MuxFile0 -pend=10
		    after 1500
		    exec sddscasr -restore $dataDir/$MuxFile0 -pend=10} result]} {
		    catch {exec hp9000ScopeSocketCommand -ring $ring  -restore $savedScope}
		    catch {exec sddscasr -restore $savedMux}
		    catch {$SetupScript0 -ID $runID -mode cleanup}
		    catch {$MainSetupScript -ID $runID -mode cleanup}
		    APSMpReturn error "APSMpDoHP9000ScopeMeas7: $result"
		}
		after 1000
	    }
	    set LastMuxFile $MuxFile0
            # Set up the scope, if the setup is not the same as the last channel
            if [catch {exec cavget -list=ID01:GenericString8 -pend=20} savedScopeFile] {
                catch {$SetupScript0 -ID $runID -mode cleanup}
                catch {$MainSetupScript -ID $runID -mode cleanup}
                APSMpReturn error "APSMpDoHP9000ScopeMeas8: error reading setupFile name: $saveScopeFile"
            }
            if [string compare $savedScopeFile $ScopeFile0] {
                eval $statusCallback {"Setting up scope"}
                if [catch {exec hp9000ScopeSocketCommand -ring $ring  -restore $dataDir/$ScopeFile0} result] {
                    catch {exec hp9000ScopeSocketCommand -ring $ring  -restore $savedScope}
                    catch {exec sddscasr -restore $savedMux}
                    catch {$SetupScript0 -ID $runID -mode cleanup}
                    catch {$MainSetupScript -ID $runID -mode cleanup}
                    APSMpReturn error "APSMpDoHP9000ScopeMeas9: putScopeSetup: $result"
                }
                exec sleep 10
            }
	    set LastScopeFile $ScopeFile0
            # Run the channel-specific setup script if there is one
            if {[llength $SetupScript0]} {
                eval $statusCallback {"Running setup script for $WaveformName0."}
                if  [catch {$SetupScript0 -ID $runID -mode setup -doPrompt $doPrompt -statusCallback $statusCallback} result] {
                    catch {$SetupScript0 -ID $runID -mode cleanup}
                    catch {$MainSetupScript -ID $runID -mode cleanup}
                    APSMpReturn error "APSMpDoHP9000ScopeMeas10: $SetupScript0: $result"
                }
                if [string compare $result Abort]==0 {
                    APSMpReturn ok "APSMpDoHP9000ScopeMeas11: aborted"
                }
            } else {
                set SetupScript0 APSNoOp
            }
            # Read the normalization PV, if any
            set NormPVValue 1
            set NormPVUnits ""
            if [string length $NormPV0] {
                if [catch {exec cavget -list=$NormPV0} NormPVValue] {
                    catch {exec hp9000ScopeSocketCommand -ring $ring  -restore $savedScope}
                    catch {exec sddscasr -restore $savedMux}
                    catch {$SetupScript0 -ID $runID -mode cleanup}
                    catch {$MainSetupScript -ID $runID -mode cleanup}
                    APSMpReturn error "APSMpDoHP9000ScopeMeas12: $NormPVValue"
                }
               
                catch {exec cavget -list=$NormPV0.EGU -noquotes} NormPVUnits
                set NormPVUnits [string trim $NormPVUnits]
            }
            if {[APSMpInterface] && [string compare $execMode Automatic]} {
                set oldMode $execMode
                set execMode Manual
                APSMpStep PleaseCheckEquipment
                set execMode $oldMode
            } elseif $doPrompt {
                switch [APSMultipleChoice [APSUniqueName .] -modal 1 \
                          -question "Measuring waveform $WaveformName0.  Please ensure that equipment is functional." \
                          -labelList "Skip Abort Continue" -returnList "Skip Abort Continue"] {
                              Skip {
                                  set controlMode 1
                              }
                              Abort {
                                  set controlMode 2
                              }
                              Continue {
                                  set controlMode 0
                              }
                              default {
                                  APSMpReturn error "Something impossible has happened (APSMultipleChoice returned invalid value)"
                              }
                          }
                if $controlMode {
                    if {[catch {$SetupScript0 -ID $runID -mode cleanup} result]} {
                        catch {exec  hp9000ScopeSocketCommand -ring $ring  -restore $savedScope}
                        catch {exec sddscasr -restore $savedMux}
                        catch {$MainSetupScript -ID $runID -mode cleanup}
                        APSMpReturn error "APSMpDoHP9000ScopeMeas13: $result"
                    }
                    if $controlMode==1 continue
                    break
                }
            }
            if ![string length $NormPV0] {
                set NormPV0 NONE
                set extraDescription ""
                set unitsSuffix ""
            } else {
                if $NormPVValue==0 {
                    set NormPVValue 1e-16
                }
                set extraDescription [format "$NormPV0: %g" $NormPVValue]
                if [string length $NormPVUnits] {
                    if [string match "* *" $NormPVUnits] {
                        set unitsSuffix "/($NormPVUnits)"
                    } else {
                        set unitsSuffix "/$NormPVUnits"
                    }
                }
            }
            set rowFrac 1
            if $clipLastHalf {
                set rowFrac 0.5
            }
            eval $statusCallback {"Acquiring data for $WaveformName0 from channel $ScopeChannel0."}
            if [catch {APSReadScopeScalars -dataDir $dataDir -scopeChannel $ScopeChannel0 -scopeID $ScopeID } extraOpt] {
                APSMpReturn error "APSMpDoHP9000ScopeMeas14 (Error in read scope scalars): $extraOpt"
            }
            set seconds [clock seconds]
            set timeStamp [clock format $seconds]
            if [catch {exec getHP9000ScopeData -ring $ring -filename  $tmpData -overwrite 1 } result] {
                APSMpReturn error "APSMpDoHP9000ScopeMeas15 (Error in read scope waveform data: $result)"
            }
            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}
            
            foreach par $parList var $varList {
                set $var [exec sdds2stream -page=1 -par=$par $tmpData]
            }
            set div [expr $div/10.0]
            set deltaT [expr 1.0/$rate]
            
            set cols [exec sddsquery -col $tmpData]
            set option ""
            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]
                append option " \"-redefine=col,$col,$col $offset  - $range /,units=Div\""
            }
            if {$peakDect=="PDET"} {
                set rows [exec sdds2stream -rows=bar $tmpData]
                set rows1 [expr $rows /2]
                if [catch {eval exec sddsbreak $tmpData -pipe=out -rowlimit=$rows1 \
                             | sddsprocess -pipe \
                             \"-redefine=col,Index,i_row,type=long\" \
                             \"-redefine=col,t,Index $deltaT * $delay +,units=seconds\" \
                             $option \
                             | sddsconvert -pipe -retain=col,t,Channel$ScopeChannel0 \
                             | sddsconvert -pipe=in -rename=col,Channel$ScopeChannel0=$WaveformName0 $tmpData.convert } result] {
                    return -code error "APSMpDoHP9000ScopeMeas16 (Error in process scope data1: $result)"
                }
            } else {
                if [catch {eval exec sddsprocess $tmpData -pipe=out \
                             \"-redefine=col,Index,i_row,type=long\" \
                             \"-redefine=col,t,Index $deltaT * $delay +,units=seconds\" \
                             $option \
                             | sddsconvert -pipe -retain=col,t,Channel$ScopeChannel0 \
                             | sddsconvert -pipe=in -rename=col,Channel$ScopeChannel0=$WaveformName0 $tmpData.convert } result] {
                    return -code error "APSMpDoHP9000ScopeMeas17 (Error in process scope data2: $result)"
                }
            }
            if [catch {eval exec sddsprocess $tmpData.convert $dataDir/$DirectoryName0/$file \
                         $extraOpt \
                         \"-test=column,i_row n_rows $rowFrac * <\" \
                         \"-filter=column,t,$tMinimum0,$tMaximum0\" \
                         \"-print=param,NormalizationPVName,$NormPV0\" \
                         \"-define=param,NormalizationPVValue,$NormPVValue,units=$NormPVUnits\" \
                         \"-print=param,UserDescription,[APSMakeSafeQualifierString [APSMakeSafeQualifierString $userDescription]]  $extraDescription\" \
                         -define=param,Time,$seconds,units=s \
                         -define=param,Channel,$ScopeChannel0,type=long \
                         \"-define=column,${WaveformName0}Norm,${WaveformName0} NormalizationPVValue /,units=V$unitsSuffix\" \
                         -print=param,WaveformName,$WaveformName0 \
                         \"-print=param,TimeStamp,$timeStamp\"} result] {
                catch {exec hp9000ScopeSocketCommand -ring $ring  -restore $savedScope}
                catch {exec sddscasr -restore $savedMux}
                catch {$SetupScript0 -ID $runID -mode cleanup}
                catch {$MainSetupScript -ID $runID -mode cleanup}
                APSMpReturn error "APSMpDoHP9000ScopeMeas18: $result"
            }
            
            if {$doGzip && [catch {exec gzip $dataDir/$DirectoryName0/$file} result]} {
                APSMpReturn error "APSMpDoHP9000ScopeMeas19: $result"
            }
            catch {APSProcessKickerParameters -file $dataDir/$DirectoryName0/$file} result
	    
            if {[llength $SetupScript0] && \
                    [catch {$SetupScript0 -ID $runID -mode cleanup} result]} {
                catch {exec hp9000ScopeSocketCommand -ring $ring  -restore $savedScope}
                catch {exec sddscasr -restore $savedMux}
                catch {$MainSetupScript -ID $runID -mode cleanup}
                APSMpReturn error "APSMpDoHP9000ScopeMeas20: $result"
            }
            if [catch {exec sendHP9000ScopeCommand -ring $ring -command ":RUN"} result] {
                APSMpReturn error "EAPSMpDoHP9000ScopeMeas21: Error start scope: $result"
            }
        }
        if !$continuous break
    }
    APSMpStep Cleanup
    eval $statusCallback {"restore scope settings: $savedScope"}
    catch {exec hp9000ScopeSocketCommand -ring $ring  -restore $savedScope}
    catch {exec sddscasr -restore $savedMux}
    if [catch {eval $MainSetupScript -ID $runID -mode cleanup} result] {
        APSMpReturn error "APSMpDoHP9000ScopeMeas22: $result"
    }
    APSMpReturn ok $measurements
}

proc APSMpCollectHP9000ScopeData {args} {
    global execMode
    set dataDir ""
    set rootname ""
    set statusCallback APSNoOp
    set userDescription ""
    set doGzip 0
    set clipLastHalf 0
    set ring SR
    set doPrompt 0
    set continuous 0
    set abortVariable dummyVariableAPSMpDoHPScopeMeas
    set process 1
    #save and restore scope state
    APSStrictParseArguments {dataDir rootname statusCallback doPrompt userDescription doGzip clipLastHalf ring continuous abortVariable process}
    global $abortVariable
    set $abortVariable 0
    if ![string length $statusCallback] {
        set statusCallback APSNoOp
    }
    eval $statusCallback {"$userDescription"}
    APSMpStep ReadMeasSpecifications -proc "APSReadHPScopeMeasSpec"
    if [catch {exec sdds2stream -par=OneSetup $dataDir/$rootname.spec} OneSetup] {
        set OneSetup 0
    }
    if !$OneSetup {
        #if different channels have different setup use APSMpDoHP9000ScopeMeas 
        if [catch {APSMpDoHP9000ScopeMeas -dataDir $dataDir -rootname $rootname \
                     -statusCallback $statusCallback -userDescription $userDescription \
                     -doGzip $doGzip -ring $ring -clipLastHalf $clipLastHalf \
                     -doPrompt $doPrompt -continuous $continuous -abortVariable $abortVariable } result] {
            APSMpReturn error "APSMpCollectHP9000ScopeData -- Error in APSMpDoHP9000ScopeMeas: $result"
        }
        APSMpReturn ok
    }
    if [catch {APSReadHPScopeMeasSpec \
                 -file $dataDir/$rootname.spec} result] {
        APSMpReturn error "APSMpCollectHP9000ScopeData1: $result"
    }
    APSMpStep SaveSystemState -proc "APSSaveMachine"
    if {[string length $SCRSystem]} {
        eval $statusCallback {"Saving $SCRSystem prior to measurements."}
        if [catch {APSSaveMachine -machine $SCRSystem \
                     -description "Routine save: autosave prior to scope measurement."} \
              snapshot] {
            APSMpReturn error "APSMpCollectHP9000ScopeData2: $snapshot"
        }
    }
    
    APSMpStep SetupEquipment
    set runID [APSTmpString]
    if {[llength $MainSetupScript]} {
        eval $statusCallback {"Doing main setup for measurement. $MainSetupScript"}
        if [catch {eval $MainSetupScript -ID $runID -mode setup -doPrompt $doPrompt} result] {
            catch {eval $MainSetupScript -ID $runID -mode cleanup}
            APSMpReturn error "APSMpCollectHP9000ScopeData3: $MainSetupScript: $result"
        }
    } else {
        set MainSetupScript APSNoOp
    }
    set measurements [llength $WaveformName]
    set MuxFile0 [lindex $MuxFile 0]
    set ScopeFile0 [lindex $ScopeFile 0]
    set SetupScript0 [lindex $SetupScript 0]

    APSMpStep SaveScopeConfiguration
    set savedScope /tmp/[APSTmpString]
    set savedMux /tmp/[APSTmpString]
    set tmpData /tmp/[APSTmpString]
    APSAddToTempFileList $savedMux $savedScope $tmpData
    
     catch {exec hp9000ScopeSocketCommand -ring $ring -save $savedScope}
    if [catch {exec burtrb -f $dataDir/mux.req -o $savedMux} result] {
        catch {$MainSetupScript -ID $runID -mode cleanup}
        APSMpReturn error "APSMpCollectHP9000ScopeData4: $result"
    }
    
    if ![file exists $dataDir/$MuxFile0] {
      #  catch {exec restoreHP9000State -ring $ring  -filename $savedScope}
        catch {exec sddscasr -restore $savedMux}
        catch {$SetupScript0 -ID $runID -mode cleanup}
        catch {$MainSetupScript -ID $runID -mode cleanup}
        APSMpReturn error "APSMpCollectHP9000ScopeData5: missing file: $dataDir/$MuxFile0"
    }
    if ![file exists $dataDir/$ScopeFile0] {
       # catch {exec  restoreHP9000State -ring $ring  -filename $savedScope}
        catch {exec sddscasr -restore $savedMux}
        catch {$SetupScript0 -ID $runID -mode cleanup}
        catch {$MainSetupScript -ID $runID -mode cleanup}
        APSMpReturn error "APSMpCollectHP9000ScopeData6: missing file: $dataDir/$ScopeFile0"
    }
   
    eval $statusCallback {"[exec date] Setting up MUX $dataDir/$MuxFile0"}
    if {[catch {exec sddscasr -restore $dataDir/$MuxFile0 
        after 1500
        exec sddscasr -restore $dataDir/$MuxFile0} result]} {
       # catch {exec restoreHP9000State -ring $ring  -filename $savedScope}
        catch {exec sddscasr -restore $savedMux}
        catch {$SetupScript0 -ID $runID -mode cleanup}
        catch {$MainSetupScript -ID $runID -mode cleanup}
        APSMpReturn error "APSMpCollectHPScopeData7: $result"
    }
    
    set rowFrac 1
    if $clipLastHalf {
        set rowFrac 0.5
    }
    if {$measurements>4} {
        APSMpReturn error "APSMpCollectHPScopeData7a: there are $measurements, but scope only have 4 available channels."
    }
   
    while {![set $abortVariable]} {
        eval $statusCallback {"[exec date] Setting up scope $dataDir/$ScopeFile0 "}
        if [catch {exec hp9000ScopeSocketCommand -ring $ring  -restore $dataDir/$ScopeFile0} result] {
            #catch {exec restoreHP9000State -ring $ring  -filename $savedScope}
            catch {exec sddscasr -restore $savedMux}
            catch {$SetupScript0 -ID $runID -mode cleanup}
            catch {$MainSetupScript -ID $runID -mode cleanup}
            APSMpReturn error "APSMpCollectHP9000ScopeData9: $result"
        }
        APSWaitWithUpdate -waitSeconds 3
        # Run the channel-specific setup script if there is one
        if {[llength $SetupScript0]} {
            eval $statusCallback {"[exec date]  Running setup script."}
            if  [catch {$SetupScript0 -ID $runID -mode setup -doPrompt $doPrompt -statusCallback $statusCallback} result] {
                catch {$SetupScript0 -ID $runID -mode cleanup}
                catch {$MainSetupScript -ID $runID -mode cleanup}
                APSMpReturn error "APSMpCollectHP9000ScopeData10: $SetupScript0: $result"
            }
            if [string compare $result Abort]==0 {
                APSMpReturn ok "APSMpCollectHP9000ScopeData11: aborted"
            }
        }
        if {[APSMpInterface] && [string compare $execMode Automatic]} {
            set oldMode $execMode
            set execMode Manual
            APSMpStep PleaseCheckEquipment
            set execMode $oldMode
        } elseif $doPrompt {
            switch [APSMultipleChoice [APSUniqueName .] -modal 1 \
                      -question "Measuring waveforms.  Please ensure that equipment is functional." \
                      -labelList "Skip Abort Continue" -returnList "Skip Abort Continue"] {
                          Skip {
                              set controlMode 1
                          }
                          Abort {
                              set controlMode 2
                          }
                          Continue {
                              set controlMode 0
                          }
                          default {
                              APSMpReturn error "Something impossible has happened (APSMultipleChoice returned invalid value)"
                          }
                      }
            if $controlMode {
                if [string length $SetupScript0] {
                    if {[catch {$SetupScript0 -ID $runID -mode cleanup} result]} {
                        #   catch {exec restoreHP9000State -ring $ring  -filename $savedScope}
                        catch {exec sddscasr -restore $savedMux}
                        catch {$MainSetupScript -ID $runID -mode cleanup}
                        APSMpReturn error "APSMpCollectHP9000ScopeData12: $result"
                    }
                }
                if $controlMode==1 continue
                break
            }
        }
        if [catch {APSCollectHP9000Data -dataDir $dataDir -rootname $rootname -ring $ring -userDescription $userDescription \
                     -statusCallback $statusCallback -clipLastHalf $clipLastHalf -doGzip $doGzip -process $process} result] {
           # catch {exec restoreHP9000State -ring $ring  -filename $savedScope}
            catch {exec sddscasr -restore $savedMux}
            catch {$MainSetupScript -ID $runID -mode cleanup}
            APSMpReturn error "APSMpCollectHP9000ScopeData13: $result"
        }
        if {[llength $SetupScript0] && \
              [catch {$SetupScript0 -ID $runID -mode cleanup} result]} {
          #  catch {exec restoreHP9000State -ring $ring  -filename $savedScope}
            catch {exec sddscasr -restore $savedMux}
            catch {$MainSetupScript -ID $runID -mode cleanup}
            APSMpReturn error "APSMpCollectHP9000ScopeData25: $result"
        }
        if !$continuous break
    }
    APSMpStep Cleanup
    catch {exec hp9000ScopeSocketCommand -ring $ring  -restore $savedScope}
    catch {exec sddscasr -restore $savedMux}
    if [string length $MainSetupScript] {
        if [catch {eval $MainSetupScript -ID $runID -mode cleanup} result] {
            APSMpReturn error "APSMpCollectHP9000ScopeData27: $result"
        }
    }
    APSMpReturn ok $measurements
}

#following procedure only works for channels have the same mux and scope setup file
proc APSCollectHP9000Data {args} {
    set dataDir ""
    set rootname ""
    set ring SR
    set userDescription ""
    set statusCallback APSNoOp
    set clipLastHalf 0
    set doGzip 1
    set process 1
    APSStrictParseArguments {dataDir rootname statusCallback userDescription ring clipLastHalf doGzip process}

    if ![file exist $dataDir/${rootname}.spec] {
        return -code error "APSCollectHP9000Data1: $dataDir/$rootname.spec does not exit!"
    }
    foreach column {tMinimum WaveformName NormPV tMaximum DirectoryName ScopeChannel} {
        if [catch {exec sdds2stream -col=$column $dataDir/$rootname.spec } values] {
            return -code error "APSCollectHP9000Data3: $values"
        }
        set $column $values
    }
    set measurements [llength $tMinimum]
    if {$measurements>4} {
        return -code error "APSCollectHP9000Data2: Error: the setup file have more than 4 channels!"
    }
    for {set i 0} {$i<$measurements} {incr i} {
        set tmin($i) [lindex $tMinimum $i]
        set tmax($i) [lindex $tMaximum $i]
        set normPV($i) [lindex $NormPV $i]
        set dir($i) [lindex $DirectoryName $i]
        set name($i) [lindex $WaveformName $i]
        set scope($i) [lindex $ScopeChannel $i]
    }
    
    set tmpData /tmp/[APSTmpString]
    eval $statusCallback {"[exec date] Acquiring data ..."}
   # if [catch {APSReadScopeScalars -dataDir $dataDir -scopeChannel $ScopeChannel0 -scopeID $ScopeID } extraOpt] {
   #     APSMpReturn error "APSMpCollectHP9000ScopeData11 (Error in read scope scalars): $extraOpt"
  #  }
    if [catch {exec sddscasr -save $dataDir/scopeScalars.sdds $tmpData.scalars} result] {
        APSMpReturn error "APSCollectHP9000Data3 (Error in read scope scalars): $result"
    }
    set nameList [exec sdds2stream -col=ReadbackName $tmpData.scalars]
    set valList [exec sdds2stream -col=ValueString $tmpData.scalars]
    set pvList [exec sdds2stream -col=ControlName $tmpData.scalars]
    set extraOpt ""
    foreach nm $nameList val $valList pv $pvList {
        if [catch {expr $val /2} result] {
            #string value
            lappend extraOpt "-reprint=par,$nm,$val,symbol=$pv"
        } else {
            lappend extraOpt -redefine=par,$nm,$val,symbol=$pv
        }
    }
    
    for {set i 0} {$i<$measurements} {incr i} {
        if [string length $normPV($i)] {
            if [catch {exec cavget -list=$normPV($i) -printErrors -pend=10} value] {
                return -code error "APSCollectHP9000Data3a: Error reading $normPV($i): $value"
            }
            if !$value {set value 1.0e-16}
            set normValue($i) $value
            if [catch {exec cavget -list=$normPV($i).EGU -noquotes -pend=10 } units] {
                set units ""
            }       
            set units [string trim $units]
            if [string match "* *" $units] {
                set unitsSuffix($i) "/($units)"
            } else {
                set unitsSuffix($i) "/$units"
            }
            set normUnits($i) $units
            set extraDescription($i) [format "$normPV($i) %g" $value]
        } else {
            set normValue($i) 1
            set normUnits($i) ""
            set extraDescription($i) ""
            set unitsSuffix($i) ""
        }
    }
    set seconds [clock seconds]
    set file [clock format $seconds -format %Y-%j-%m%d-%H%M%S]
    if [catch {exec sendHP9000ScopeCommand -ring $ring -command ":STOP"} result] {
        return -code error "APSCollectHP9000Data4 (Error in stop scope: $result"
    }
    set seconds [clock seconds]
    set timeStamp [clock format $seconds]
    if $process {
        set output $tmpData
    } else {
        set outDir /home/helios/oagData/sr/scope/archiveData1/RawData
        set output $outDir/$file
        exec cp $tmpData.scalars $outDir/${file}.scalars
    }
    if [catch {exec getHP9000ScopeData -ring $ring -filename  $output -overwrite 1 } result] {
        return -code error "APSCollectHP9000Data11 (Error in read scope waveform data: $result)"
    }
    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}
    foreach par $parList var $varList {
        set $var [exec sdds2stream -page=1 -par=$par $output ]
    }
    
    set div [expr $div/10.0]
    
    set deltaT [expr 1.0/$rate]
   
    #it takes 13 seconds to collect 544 waveforms.
    eval $statusCallback {"[exec date] Finished acquiring raw data from scope. Processing data..."}
    if [catch {exec sendHP9000ScopeCommand -ring $ring -command ":RUN"} result] {
        return -code error "APSCollectHP9000Data15: Error start scope: $result"
    }
    set rows [exec sdds2stream -rows=bar $output]
    set points [exec sdds2stream -par=Points $output]
    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 rowFrac 1
    if $clipLastHalf {
        set rowFrac 0.5
    }
    if !$process {
        if {$doGzip && [catch {exec gzip $outDir/$file} result]} {
            return -code error "APSCollectHP9000Data15a: $result"
        }
        
        for {set i 0} {$i<$measurements} {incr i} {
            set chan $scope($i)
            set offset [set chan${chan}offset]
            set range [set chan${chan}range]
            lappend offsetList $offset
            lappend rangeList $range
            lappend scopeChanList Channel$chan
            lappend extraDescList "$extraDescription($i)"
            lappend normPVList $normPV($i)
            lappend normValList $normValue($i)
            lappend normUnitsList $normUnits($i)
            lappend unitsSuffixList $unitsSuffix($i)
            lappend waveformNameList $name($i)
            lappend dirList $dir($i)
            lappend tminList $tmin($i)
            lappend tmaxList $tmax($i)
        }
        if [catch {exec sddsmakedataset $outDir/${file}.scope \
                     -par=TimeStamp,type=string "-data=$timeStamp" \
                     -par=UserDescription,type=string "-data=[APSMakeSafeQualifierString $userDescription]" \
                     -par=Rootname,type=string -data=$rootname \
                     -par=PeakDect,type=string -data=$peakDect \
                     -par=Delay,type=double -data=$delay \
                     -par=Div,type=double -data=$div \
                     -par=DeltaT,type=double -data=$deltaT \
                     -par=RowFractor,type=double -data=$rowFrac \
                     -par=DataDir,type=string -data=$dataDir \
                     -col=Measurement,type=long -data=1,2,3,4 \
                     -col=ScopeChannel,type=string -data=[join $scopeChanList ,] \
                     -col=ExtraDescription,type=string "-data=[join $extraDescList ,]" \
                     -col=Offset,type=double -data=[join $offsetList ,] \
                     -col=Range,type=double -data=[join $rangeList ,] \
                     -col=NormValue,type=double -data=[join $normValList ,] \
                     -col=NormUnits,type=string "-data=[join $normUnitsList ,]" \
                     -col=UnitsSuffix,type=string "-data=[join $unitsSuffixList ,]" \
                     -col=WaveformName,type=string "-data=[join $waveformNameList ,]" \
                     -col=tmin,type=double -data=[join $tminList ,] \
                     -col=tmax,type=double -data=[join $tmaxList ,] \
                     -col=NormPV,type=string -data=[join $normPVList ,] \
                     -col=Directory,type=string "-data=[join $dirList ,]" } result] {
            return -code error "APSCollectHP9000Data15b: $result"
        }
        eval $statusCallback {"[exec date] Acquiring raw data done."}
        set files [glob ${tmpData}*]
        eval file delete -force $files
        return
    }
    
    for {set i 0} {$i < $measurements} {incr i} {
        set chan $scope($i)
        set offset [set chan${chan}offset]
        set range [set chan${chan}range]
        set col Channel$chan
        set option " \"-redefine=col,$col,$col $offset  - $range /,units=Div\""
        set waveformName $name($i)
        if {$peakDect=="PDET"} {
            set rows [exec sdds2stream -rows=bar $tmpData]
            set rows1 [expr $rows /2]
            if [catch {eval exec sddsbreak $tmpData -pipe=out -rowlimit=$rows1 \
                         | sddsprocess -pipe \
                         \"-redefine=col,Index,i_row,type=long\" \
                         \"-redefine=col,t,Index $deltaT * $delay +,units=seconds\" \
                         $option \
                         | sddsconvert -pipe -retain=col,t,$col \
                         | sddsconvert -pipe=in -rename=col,$col=$waveformName $tmpData.convert } result] {
                return -code error "APSCollectHP9000Data12 (Error in process scope data1: $result)"
            }
        } else {
            if [catch {eval exec sddsprocess $tmpData -pipe=out \
                         \"-redefine=col,Index,i_row,type=long\" \
                         \"-redefine=col,t,Index $deltaT * $delay +,units=seconds\" \
                         $option \
                         | sddsconvert -pipe -retain=col,t,$col \
                         | sddsconvert -pipe=in -rename=col,$col=$waveformName $tmpData.convert } result] {
                return -code error "APSCollectHP9000Data13 (Error in process scope data2: $result)"
            }
        }
        if [catch {eval exec sddsprocess $tmpData.convert $dataDir/$dir($i)/$file \
                     $extraOpt \
                     \"-test=column,i_row n_rows $rowFrac * <\" \
                     \"-filter=column,t,$tmin($i),$tmax($i) \" \
                     \"-print=param,NormalizationPVName,$normPV($i) \" \
                     \"-define=param,NormalizationPVValue,$normValue($i),units=$normUnits($i) \" \
                     \"-print=param,UserDescription,[APSMakeSafeQualifierString [APSMakeSafeQualifierString $userDescription]]  $extraDescription($i)\" \
                     -define=param,Time,$seconds,units=s \
                     -define=param,Channel,$chan,type=long \
                     \"-define=column,${waveformName}Norm,$waveformName $normValue($i) /,units=V$unitsSuffix($i)\" \
                     -print=param,WaveformName,$waveformName \
                     \"-print=param,TimeStamp,$timeStamp\"} result] {
            return -code error "APSCollectHP9000Data14: $result"
        }
        
        if {$doGzip && [catch {exec gzip $dataDir/$dir($i)/$file} result]} {
            return -code error "APSCollectHP9000Data15: $result"
        }
       # catch {APSProcessKickerParameters -file $dataDir/$dir($i)/$file} result
    }
    set files [glob ${tmpData}*]
    eval file delete -force $files
    eval $statusCallback {"[exec date] Acquiring data done."}
    return
}
