
proc APSGetSRTuneWaveformHPVSA {args} {
    set output ""
    set description ""
    set statusCallback APSNoOp
    set plane x
    set harmonic 1296
    set measHarmonic 1316
    set dividingLine 0.2
    set MXA 0
    set xP0ReducedGain 2.0
    set yP0ReducedGain 2.0
    set xDimtelReducedGain 2
    set yDimtelReducedGain 2
    if {[APSStrictParseArguments {output description plane statusCallback harmonic measHarmonic dividingLine MXA xP0ReducedGain yP0ReducedGain xDimtelReducedGain yDimtelReducedGain}] || \
          ![string length $output]} {
        return -code error "APSGetSRTuneWaveformHPVSA: bad arguments"
    }
    switch [string tolower $plane] {
        x -
        h {
            set dimtelPV IGPF:Z:SHIFTGAIN
            set dimtelReducedGain $xDimtelReducedGain
        }
        y -
        v {
            set dimtelPV IGPF:Y:SHIFTGAIN
            set dimtelReducedGain $yDimtelReducedGain
        }

    }
    if [catch {exec cavget -list=$dimtelPV -pend=10} dimtelGain] {
        #return -code error "Error reading dimtel gain: $dimtelGain"
    }
    set tmpRoot /tmp/[APSTmpString]
    if [catch {exec sddswget -pv=Mt:S:FillPatternWF.VAL $tmpRoot.pattern} result] {
        APSMpReturn -code error "APSMpMeasureTunes: Unable to read bunch pattern WF: $result"
    }
    if [catch {exec sddsdiff -col=Index,Waveform $tmpRoot.pattern  \
                 /home/helios/oagData/sr/bunchPatterns/bunchPatternFillRef.hybrid561} result] {
        set reduceGain 1
    } else {
        #do not reduce P0Feedback gain for hybrid pattern
        set reduceGain 0
    }
    if {$dimtelGain<=$dimtelReducedGain} {
        #already lower than required, do nothing
    } else {
        if [catch {exec cavput -list=$dimtelPV=$dimtelReducedGain -pend=10} result] {
            return -code error "Error reduce dimtel gain: $result"
        }
    }
    if $reduceGain {
        foreach system {P0 TFB} prefix {S:P0FB S:TFB:M} {
            set gainPV ${prefix}:AcqGain[string toupper $plane]_SetWF
            if [catch {exec sddswget -pv=$gainPV $tmpRoot.$plane.$system.gain -pend=30} result] {
                APSMpReturn error "APSGetSRTuneWaveformHPVSA: Error in saving $gainPV : $result."
            }
            if [catch {exec sddsprocess $tmpRoot.$plane.$system.gain -pipe=out \
                         -process=Waveform,first,Gain \
                         | sdds2stream -pipe -par=Gain } currentGain] {
                APSMpReturn error "APSMpMeasureTunes: Error getting curreng gain: $currentGain"
            }
            set rGain [set ${plane}P0ReducedGain]
           # puts $currentGain
            if {[expr abs($currentGain)]<=[expr abs($rGain)]} {
                #do not change the gain if current gain is less than
                APSMpStep "$system $plane gain is less than the reduced gain, skip."
                puts "$system $plane gain is less than the reduced gain, skip."
                continue
            }
            
            if [catch {exec sddsprocess $tmpRoot.$plane.$system.gain $tmpRoot.$plane.$system.gain1 \
                         "-redefine=col,Waveform,[set ${plane}P0ReducedGain]" \
                     } result] {
                APSMpReturn error "APSGetSRTuneWaveformHPVSA: Error in process P0 feedback gain: $result"
            }
        }
        
        #check topup status
        if [catch {exec cavget -list=Mt:TopUpAutoEnableC.VAL -pend=10 -printErrors -num} topup] {
            APSMpReturn error "APSGetSRTuneWaveformHPVSA: Error in checking topup status: $topup"
        }
        if $topup {
            puts "wait for topup..."
            #check the topup count>40
            eval $statusCallback "{waiting for topup shot...}"
            while {1} {
                if [catch {exec cavget -list=Mt:TopUpTime2Inject.VAL -pend=10 -printErrors} count] {
                    APSMpReturn error "APSGetSRTuneWaveformHPVSA: Error in reading topup to injection count: $count"
                }
                # it takes 25 seconds to do the whole measurement
                # so I reduced the limit from 40 to 30. LEm
                if {$count>30} {
                    break
                }
                after 1000
            }
        }
        foreach system {P0 TFB} {
            if [file exist $tmpRoot.$plane.$system.gain1] {
                puts "reduce $system Feedback gain..."
                if [catch {exec sddswput $tmpRoot.$plane.$system.gain1 -pend=30} result] {
                    APSMpReturn error "APSGetSRTuneWaveformHPVSA: Error in reducing P0 feedback gain: $result"
                }
            }
        }
    }
    after 3000
    # get some vital statistics and ensure that the numbers returned are valid
    set try 1
    while {$try<10} {
        eval $statusCallback "{Getting tune-related data ($try)}"
        if [catch {exec cavget -list=S-DCCT:CurrentM,SR:C:cavTotalGapVolt,SRF:S40:cavTotalGapVolt,SRF:S36:cavTotalGapVolt,SRF:S37:cavTotalGapVolt,SRF:S38:cavTotalGapVolt,A014-IETS:BTC:SRSetFreqM,SR:tune:hpdl:x:SetDelay,SR:tune:hpdl:y:SetDelay  -float=%.15e -pend=30 \
                 } result ] {
            if $reduceGain {
                if [catch {exec sddswput $tmpRoot.$plane.gain -pend=30} result] {
                    APSMpReturn error "APSGetSRTuneWaveformHPVSA: Error in restoring P0 feedback $plane gain: $result"
                }
            }
            return -code error "APSGetSRTuneWaveformHPVSA: $result"
        }
        set allOk 1
        foreach item $result {
            if [string compare $item ?]==0 {
                set allOk 0
            }
        }
        if $allOk break
        incr try 1
    }
    if !$allOk {
        if $reduceGain {
            if [catch {exec sddswput $tmpRoot.$plane.gain -pend=30} result] {
                APSMpReturn error "APSGetSRTuneWaveformHPVSA: Error in restoring P0 feedback $plane gain: $result"
            }
        }
        return -code error "APSGetSRTuneWaveformHPVSA: problem reading PV data!"
    }
   
    set S35DCCT    [lindex $result 0]
    set rfVoltage  [lindex $result 1]
    set rf1Voltage [lindex $result 2]
    set rf2Voltage [lindex $result 3]
    set rf3Voltage [lindex $result 4]
    set rf4Voltage [lindex $result 5]
    set rfFrequency [lindex $result 6]
    set xshift [lindex $result 7]
    set yshift [lindex $result 8]
    switch $plane {
	x {
	    set extraOpt "-filter=col,xTune,0,$dividingLine"
	} 
	y {
	    set extraOpt "-filter=col,yTune,$dividingLine,1"
	}
    }
    # grab the current trace
    set goodData 0
    set try 1
    while {!$goodData && $try<11} {
        eval $statusCallback "{Getting HP VSA trace ($try)}"
        if $MXA {
            set timeout [expr [clock seconds] + 10000]
            puts "Reading MXA waveform points..."
            while {[clock seconds]<$timeout} {
                if [catch {exec hpSocketSend 164.54.3.0 ":CALC:VECT:DATA:POIN?" } points] {
                    return -code error "APSGetSRTuneWaveformHPVSA (error reading MXA waveform points): $points"
                }
                if {$points>0} {
                    break
                }
                after 1000
            }
            if {!$points} {
                return -code error "APSGetSRTuneWaveformHPVSA (error reading MXA waveform points): no data"
            }
            puts "reading data from MXA..."
            if [catch {exec getVXATraceData -filename $output.tmp} result ] {
                puts $result
                if $reduceGain {
                    if [catch {exec sddswput $tmpRoot.$plane.gain -pend=30} result] {
                        APSMpReturn error "APSGetSRTuneWaveformHPVSA: Error in restoring P0 feedback $plane gain: $result"
                    }
                }
                return -code error "APSGetSRTuneWaveformHPVSA: $result"
            }
            puts "Reading data done..."
        } else {
            if [catch {exec hpVecTrace  -hpvecsr a $output.tmp} result ] {
                if $reduceGain {
                    if [catch {exec sddswput $tmpRoot.$plane.gain -pend=30} result] {
                        APSMpReturn error "APSGetSRTuneWaveformHPVSA: Error in restoring P0 feedback $plane gain: $result"
                    }
                }
                return -code error "APSGetSRTuneWaveformHPVSA: $result"
            }
        }
        if [exec sdds2stream $output.tmp -rows=bare,total] {
            set goodData 1
        }
        incr try 1
        after 1000
    }
    if $try==11 {
        if $reduceGain {
            foreach system {P0 TFB} {
                if [catch {exec sddswput $tmpRoot.$plane.$system.gain -pend=30} result] {
                    APSMpReturn error "APSGetSRTuneWaveformHPVSA: Error in restoring P0 feedback $plane gain: $result"
                }
            }
        }
        return -code error "APSGetSRTuneWaveformHPVSA: unable to get HP VSA data"
    }
    # compute tune and frequency offset from rev harmonic
    # also define parameters for values read above
    # replaced the smooth+peak method by peakfind method to find the tune, Shang, 8/13/2013
    if $reduceGain {
        foreach system {P0 TFB} {
            if [catch {exec sddswput $tmpRoot.$plane.$system.gain -pend=30} result] {
                APSMpReturn error "APSGetSRTuneWaveformHPVSA: Error in restoring P0 feedback $plane gain: $result"
            }
        }
    }
    #restore dimtel gain
    if {$dimtelGain<=$dimtelReducedGain} {
        #already lower than required, do nothing
    } else {
        if [catch {exec cavput -list=$dimtelPV=$dimtelGain -pend=10} result] {
            return -code error "Error restore dimtel gain: $result"
        }
    }
    eval $statusCallback "{Processing HP VSA trace}"
    if [catch {eval exec sddsconvert $output.tmp -pipe=out \
                 -rename=column,Frequency=${plane}Frequency,Waveform=${plane}Waveform \
                 | sddsprocess -pipe -nowarning \
                 \"-define=param,rfFrequency,$rfFrequency 1e6 /,units=MHz"\ \
                 \"-define=param,revHarmonic,rfFrequency  $harmonic / $measHarmonic *,units=MHz\" \
                 \"-define=param,revFrequency,rfFrequency $harmonic /,units=MHz" \
                 \"-define=col,${plane}Tune,${plane}Frequency revFrequency mod revFrequency / 0.5 > ?  pop 1 swap - : pop \$\" \
                 \"-define=col,${plane}Offset,${plane}Frequency revFrequency mod revFrequency 2 / > ?  pop revFrequency - : pop \$ 1e3 *,units=kHz,description=Offset from harmonic\" \
                 -define=para,S35DCCT,$S35DCCT \
                 -define=para,rfVoltage,$rfVoltage \
                 -define=para,rf1Voltage,$rf1Voltage \
                 -define=para,rf2Voltage,$rf2Voltage \
                 -define=para,rf3Voltage,$rf3Voltage \
                 -define=para,rf4Voltage,$rf4Voltage \
                 -define=para,coblyPhaseShiftDelayX,$xshift \
                 -define=para,colbyPhaseShiftDelayY,$yshift \
                 \"-print=para,S35DCCTstring,S35DCCT=%5.2lf ma,S35DCCT\" \
                 \"-print=para,rfVoltagestring,rfVoltage=%5.2lf MV,rfVoltage\" \
                 -print=para,Description,$description  \
                 -print=parameter,Instrument,HPVSA \
                 | tee $output.1 \
                 | sddsprocess -pipe $extraOpt -nowarning \
                 | sddsprocess -pipe -process=${plane}Waveform,max,WaveformMax \
                 | sddsprocess -pipe \"-define=col,NormWaveform,${plane}Waveform WaveformMax /\" \
                 | sddspeakfind -pipe -col=NormWaveform -threshold=0.5 -exclusion=0.2 \
                 | sddssort -pipe=in $output.2 -column=NormWaveform,decr } result] {
        catch {file delete $output.tmp}
        return -code error "APSGetSRTuneWaveformHPVSA: $result"
    }
    set tune [lindex [exec sdds2stream -col=${plane}Tune $output.2] 0]
    if [catch {exec sddsprocess $output.1 $output \
                 "-print=par,${plane}TuneString,${plane}Tune\=[format %.4f $tune]" \
                 -process=${plane}Waveform,max,${plane}WaveformPeak \
                 "-define=par,${plane}Tune,$tune" } result] {
	return -code error "APSGetSRTuneWaveformHPVSA: error in proceesing tunes: $result"
    }
    catch {file delete $output.tmp $output.1 $output.2}
    
}

proc APSGetSRTunesHPVSA {args} {
    set output ""
    set description ""
    set average 100
    set statusCallback APSNoOp
    set rfFrequency [exec cavget -list=A014-IETS:BTC:SRSetFreqM -floatFormat=%.1f -pendIoTime=5]
    set harmonic 1296
    set revFrequency [expr $rfFrequency / 1296]
    set measHarmonic 1316
    set sideband -1
    set expectedXtune 0.2
    set xFrequency [expr $revFrequency * ($measHarmonic + $expectedXtune * $sideband)]
    set expectedYtune 0.27
    set yFrequency [expr $revFrequency * ($measHarmonic + $expectedYtune * $sideband)]
    set xP0ReducedGain 2.0
    set yP0ReducedGain 2.0
    set xDimtelReducedGain 2
    set yDimtelReducedGain 2
    if {[APSStrictParseArguments {output description xFrequency yFrequency average statusCallback xP0ReducedGain yP0ReducedGain xDimtelReducedGain yDimtelReducedGain}] || \
          ![string length $output] || $xFrequency<=0 || $yFrequency<=0 || $average<=0} {
        return -code error "APSGetSRTunesHPVSA: bad arguments"
    }
    
    set freq $xFrequency
    foreach plane {x y} {
        eval $statusCallback "{Getting HP VSA data for plane $plane}"
        set Plane [string toupper $plane]
        # Possible values
        # X   "X Tune"
        # Y   "Y Tune"
        if [catch {exec cavput -list=SR:TUNE:HP_1366A_C0P1_MBBO=$Plane,SR:TUNE:HP_1366A_C0P0_MBBO=VSA,SR:TUNE:HP_1366A_C2P1_MBBO=X/Y,SR:TUNE:Mux4Sw0BO=VSA,SR:TUNE:Mux4Sw1BO=$Plane -pend=20 \
                 } result ] {
            return -code error "MeasureInitialTunes: $result"
        }
        
        # Can't use open telnet stream here since this
        # hangs up when this procedure is run within sddsexperiement
        # APSExecLog. So we use hpSocketSend instead.
        # AVER:TCON NORM ensures that averaging is normal, i.e. not repeating.
        if [catch {exec hpSocketSend hpvecsr.aps4.anl.gov \
                     "AVER:TCON NORM" -pause=0.1 "PAUS" -pause=0.1 \
                     "AVER:COUN $average" -pause=0.1 \
                     "FREQ:CENT $freq" -pause=2.0 "ABOR;*WAI"\
                 } result] {
            return -code error "APSGetSRTunesHPVSA: $result"
        }
        eval $statusCallback "{Pause for 7 seconds for HP VSA to start averaging.}"
        after 7000
        eval $statusCallback "{HP VSA configuration set up}"
        set operationCondition 1
        eval $statusCallback "{HP VSA operationCondition is $operationCondition}"
        while {$operationCondition} {
            eval $statusCallback "{Waiting for HP VSA to acquire data. Using hpSocketSend}"
            set operationCondition [exec hpSocketSend hpvecsr.aps4.anl.gov \
                                      "STAT:OPER:COND?"]
            eval $statusCallback "{HP VSA operationCondition is $operationCondition}"
            after 3000
        } 
        eval $statusCallback "{HP VSA has completed data acquisition}"
        if [catch {APSGetSRTuneWaveformHPVSA -output $output.$plane \
                     -xP0ReducedGain $xP0ReducedGain \
                     -yP0ReducedGain $yP0ReducedGain \
                     -MXA $MXA \
                     -xDimtelReducedGain $xDimtelReducedGain \
                     -yDimtelReducedGain $yDimtelReducedGain \
                     -dividingLine $dividingLine \
                     -description "$description" \
                     -plane $plane -statusCallback $statusCallback \
                 } result] {
            return -code error "APSGetSRTunesHPVSA: $result"
        }
        set freq $yFrequency
    }
    if [catch {exec sddsxref $output.x $output.y $output -take=* -transfer=parameter,* -nowarning} result] {
        return -code error "APSGetSRTunesHPVSA: $result"
    }
    eval $statusCallback "{HP VSA tune data acquired}"
    catch {file delete  $output.x  $output.y}
}

proc APSGetBoosterTunesHPVSA {args} {
    set output ""
    set description ""
    set average 100
    set rfPVName BRF:S:Hp8657RefFreq
    set statusCallback APSNoOp

    set results [exec cavget -list=Mt:BoosterRampTurnsAO,A014-IETS:BTC:BInjectionCycleM,A014-IETS:BTC:BExtractionCycleM,A014-IETS:BTC:SRSetFreqM -pend=5 -floatformat=%lf]
    set srExtractionTurns [lindex $results 0]
    set bInjectionCycle [lindex $results 1]
    set bExtractionCycle [lindex $results 2]
    set srFreq [lindex $results 3]
    set rfFrequency [expr 432 * $srFreq * 3 * $srExtractionTurns / ($bExtractionCycle - $bInjectionCycle)]
    set harmonic 432
    set revFrequency [expr $rfFrequency / 432]
    set measHarmonic 432
    set sideband 1
    set expectedXtune 0.742
    set xFrequency [expr $revFrequency * ($measHarmonic + $expectedXtune * $sideband)]
    set expectedYtune 0.670
    set yFrequency [expr $revFrequency * ($measHarmonic + $expectedYtune * $sideband)]
    if {[APSStrictParseArguments {output description xFrequency yFrequency average statusCallback rfPVName}] || \
          ![string length $output] || $xFrequency<=0 || $yFrequency<=0 || $average<=0} {
        return -code error "APSGetBoosterTunesHPVSA: bad arguments"
    }
    set rfPVName1 $rfPVName
   # set freq $xFrequency
    foreach plane {x y} {
        eval $statusCallback "{Getting HP VSA data for plane $plane}"
        set Plane [string toupper $plane]
        set freq [set ${plane}Frequency]
	eval $statusCallback "{set to $plane frequency: $freq}"
        # Can't use open telnet stream here since this
        # hangs up when this procedure is run within sddsexperiement
        # APSExecLog. So we use hpSocketSend instead.
        # AVER:TCON NORM ensures that averaging is normal, i.e. not repeating.
        if [catch {exec hpSocketSend hpvecboo.aps4.anl.gov \
		       "AVER:TCON NORM" -pause=0.1 "PAUS" -pause=0.1 \
		       "AVER:COUN $average" -pause=0.1 \
		       "FREQ:CENT $freq" -pause=0.1 "ABOR;*WAI"\
                 } result] {
            return -code error "APSGetBoosterTunesHPVSA: $result"
        }
        after 5000
        eval $statusCallback "{HP VSA configuration set up}"
        set operationCondition 1
        while {$operationCondition !=32} {
            eval $statusCallback "{Waiting for HP VSA to acquire data}"
            set operationCondition [exec hpSocketSend hpvecboo.aps4.anl.gov \
                                      "STAT:OPER:COND?"]
            after 2000
        } 
        eval $statusCallback "{HP VSA has completed data acquisition}"
        if [catch {APSGetBoosterTuneWaveformHPVSA -output $output.$plane -rfPVName $rfPVName1 \
                     -description "$description" -harmonic 432 -measHarmonic 432 \
                     -plane $plane -statusCallback $statusCallback \
                 } result] {
            return -code error "APSGetBoosterTunesHPVSA: $result"
        }
        set freq $yFrequency
    }
    if [catch {exec sddsxref $output.x $output.y $output -take=* -transfer=parameter,* -nowarning} result] {
        return -code error "APSGetBoosterTunesHPVSA: $result"
    }
    eval $statusCallback "{HP VSA tune data acquired}"
    catch {file delete  $output.x  $output.y}
}

proc APSGetBoosterTuneWaveformHPVSA {args} {
    set output ""
    set description ""
    set statusCallback APSNoOp
    set plane x
    set harmonic 432
    set measHarmonic 432
    if {[APSStrictParseArguments {output description plane statusCallback harmonic measHarmonic rfPVName}] || \
          ![string length $output]} {
        return -code error "APSGetBoosterTuneWaveformHPVSA: bad arguments"
    }

    # get some vital statistics and ensure that the numbers returned are valid
    set results [exec cavget -list=Mt:BoosterRampTurnsAO,A014-IETS:BTC:BInjectionCycleM,A014-IETS:BTC:BExtractionCycleM,A014-IETS:BTC:SRSetFreqM -pend=5 -floatformat=%lf]
    set srExtractionTurns [lindex $results 0]
    set bInjectionCycle [lindex $results 1]
    set bExtractionCycle [lindex $results 2]
    set srFreq [lindex $results 3]
    set rfFrequency [expr 432 * $srFreq * 3 * $srExtractionTurns / ($bExtractionCycle - $bInjectionCycle)]
    # grab the current trace
    set goodData 0
    set try 1
    while {!$goodData && $try<11} {
        eval $statusCallback "{Getting HP VSA trace ($try)}"
        if [catch {exec hpVecTrace  -hpvecboo a $output.tmp} result ] {
            return -code error "APSGetBoosterTuneWaveformHPVSA: $result"
        }
        if [exec sdds2stream $output.tmp -rows=bare,total] {
            set goodData 1
        }
        incr try 1
        after 1000
    }
    if $try==11 {
        return -code error "APSGetBoosterTuneWaveformHPVSA: unable to get HP VSA data"
    }
    # compute tune and frequency offset from rev harmonic
    # also define parameters for values read above
    eval $statusCallback "{Processing HP VSA trace}"
    if [catch {exec sddsconvert $output.tmp -pipe=out \
                 -rename=column,Frequency=${plane}Frequency,Waveform=${plane}Waveform \
                 | sddsprocess -pipe -nowarning \
                 "-define=param,rfFrequency,$rfFrequency 1e6 /,units=MHz" \
                 "-define=param,revHarmonic,rfFrequency  $harmonic / $measHarmonic *,units=MHz" \
                 "-define=param,revFrequency,rfFrequency $harmonic /,units=MHz" \
                 "-define=col,${plane}Tune,${plane}Frequency revFrequency / ${plane}Frequency revFrequency / int -" \
                 "-define=col,${plane}Offset,${plane}Tune revFrequency * 1e3 *,units=kHz,description=Offset from harmonic" \
                 -print=para,Description,$description  \
                 -print=parameter,Instrument,HPVSA \
                 | sddssmooth -pipe \
                 -column=${plane}Waveform -despike=passes=4 -pass=0 -newColumn \
                 | sddsprocess -pipe=in $output \
                 -process=${plane}WaveformSmoothed,max,${plane}WaveformPeak \
                 -process=${plane}WaveformSmoothed,max,${plane}Tune,position,functionOf=${plane}Tune \
             } result ] {
        catch {file delete $output.tmp}
        return -code error "APSGetBoosterTuneWaveformHPVSA: $result"
    }
    catch {file delete $output.tmp}
}


proc APSSetupSRVSAScope {args} {
    set sourceLevel 12
    set plane x
    set root ""
    set freq ""
    set average 100
    set MXA 0
    set span 20000
    set range -3
    APSStrictParseArguments {sourceLevel plane root freq average MXA span range}
    switch $plane {
	x -
	y {

	}
	default {
	    return -code error "SetupVSAScope1: invalid plane provided."
	}
    }
    # Set number of  greeting lines to zero because
    # somehow that is the only way to prevent
    # telnet from hanging up. By not having hte
    # required number of "gets" statement, any information
    # from the VSA through telnet will be incorrect.
    
    #replaced all telnet commands for VSA by hpSocketSend since telnet often hangs up 7/2/2017 HS
    
    if [catch {APSSetTuneMultiplexer -mode VSA } result] {
        return -code error "SetupVSAScope4: unable to set VSA mux: $result"
    }
    if [catch {APSSetupStriplineDrive -plane [string toupper $plane] -rf 0} result ] {
	return -code error "SetupVSAScope4a: unable to set stripline and HP switch to $plane plane: $result"
    }
    #puts stderr "Writing to telnet stream FREQ:CENT $xFrequency"
    if [catch {exec hpSocketSend hpvecsr  "FREQ:CENT $freq"  -pause=0.1 \
                 "FREQ:SPAN $span" -pause=0.1 \
                 "SOUR:VOLT $sourceLevel" } result ] {
	return -code error "SetupVSAScope5: unable to set VSA scope center frequency: $result"
    }
    # Ensure that averaging is normal, i.e. not repeating.
    if  {!$MXA} {
        if [catch {exec hpSocketSend hpvecsr "AVER:IRES ON" -pause=0.1 \
                     "AVER:TCON NORM" -pause=0.1 \
                     "AVER:COUN $average" -pause=0.1 \
                     "ABOR;*WAI" } result] {
            return -code error "SetupVSAScope3: unable to turn on VSA scope average: $result"
        }
    }
    # turn on VSA source
    if [catch {exec hpSocketSend hpvecsr "OUTP ON" \
             } result ] {
        return -code error "SetupVSAScope2: unable to turn on VSA scope: $result"
    }
    #setup VXA scope
    if $MXA {
        if [catch {exec hpSocketSend 164.54.3.0 ":INST:SEL?"} mode] {
            puts $mode
            return -code error "SetupVSAScope4b: Error reading MXA mode; $mode"
        }
        if {$mode=="SA"} {
            if [catch {exec hpSocketSend 164.54.3.0 ":INST:SEL VSA" } result] {
                return -code error "SetupVSAScope4c: Error in switching MXA to VSA mode: $result"
            }
            after 5000
        }
        if [catch {exec hpSocketSend 164.54.3.0 ":SENS:FREQ:CENT $freq;:SENS:FREQ:SPAN $span;:VECT:AVER:COUN 50;:TRIG:VECT:SOUR EXT1;:SENS:VECT:SWE:POIN 6401;:VECT:SWE:TIME 0.03203125;:SENS:POW:RF:RANG $range;VECT:AVER:TCON REP;VECT:AVER:TYPE RMS;:SENS:VECT:FFT:WIND:TYPE HANN;VECT:AVER:FAST ON;:SENS:VECT:AVER:STAT ON;INIT:REST;*WAI" \
                 } result] {
            puts $result
            return -code error "SetupVSAScope5a: unable to set MXA commands: $result"
        }
        after 1000
    }
    
    #after 3000
    if {!$MXA} {
        set operationCondition 256
        while {$operationCondition & 256} {
            after 1000
            if [catch {exec hpSocketSend hpvecsr "STAT:OPER:COND?" } operationCondition] {
                return -code error "SetupVSAScope5b: $operationCondition"
            }
        }
        # testing for overvoltage on channel 1.
        if [catch {exec  hpSocketSend hpvecsr "STAT:QUES:VOLT:COND?" } voltageRegister] {
            return -code error "SetupVSAScope5c: $voltageRegister"
        }
        if [expr $voltageRegister & 128] {
            return -code error "Questionable voltage condition present. Check instrument range."
        }
    }
}


proc APSGetSRTunesVSA {args} {
    set output ""
    set description ""
    set average 100
    set statusCallback APSNoOp
    set rfFrequency [exec cavget -list=A014-IETS:BTC:SRSetFreqM -floatFormat=%.1f -pendIoTime=5]
    set harmonic 1296
    set revFrequency [expr $rfFrequency / 1296]
    set measHarmonic 1316
    set sideband -1
    set expectedXtune 0.2
    set xFrequency [expr $revFrequency * ($measHarmonic + $expectedXtune * $sideband)]
    set expectedYtune 0.26
    set yFrequency [expr $revFrequency * ($measHarmonic + $expectedYtune * $sideband)]
    set dividingLine 0.2
    set MXA 1
    set xSourceLevel 9
    set ySourceLevel 6
    set xP0ReducedGain 2.0
    set yP0ReducedGain 2.0
    set xDimtelReducedGain 2
    set yDimtelReducedGain 2
    set xrange -3
    set yrange -3
    set xchrom 6
    set ychrom 4
    set deltaFreq 0
    set alpha_c 2.819e-04
    set steps 5
    if {[APSStrictParseArguments {output description xFrequency yFrequency average statusCallback dividingLine MXA xSourceLevel ySourceLevel xP0ReducedGain yP0ReducedGain xrange yrange xchrom ychrom deltaFreq alpha_c measHarmonic steps xDimtelReducedGain yDimtelReducedGain}] || \
          ![string length $output] || $xFrequency<=0 || $yFrequency<=0 || $average<=0} {
        return -code error "APSGetSRTunesVSA: bad arguments"
    }
    
    #correct the delta frequency computation.
    set deltaFreq [expr $deltaFreq * $measHarmonic / 1296.0]
    foreach plane {x y} {
        set freq [set ${plane}Frequency]
        if $deltaFreq {
            set chrom [set ${plane}chrom]
            set step [lindex [split $output "-"] 1]
            set step [scan $step %ld]
            set step [expr $step - ($steps-1.0) / 2.0 ]
            set freq [expr $freq - $sideband * $deltaFreq * $step * $chrom / $alpha_c / 1296.0]
           # puts "$step $freq"
        }
        set sourceLevel [set ${plane}SourceLevel]
        set range [set ${plane}range]
        eval $statusCallback "{set up HP VSA for...}"
        #turn VSA off before switching mux to avoid the VSA drive the beam
         if [catch {exec hpSocketSend hpvecsr "OUTP OFF" \
                  } result ] {
            return -code error "APSGetSRTuneVSA1a: unable to turn off VSA scope: $result"
        }
        after 1000
        if [catch {APSSetupSRVSAScope -sourceLevel $sourceLevel -plane $plane -root $output \
                     -average $average -freq $freq  -MXA $MXA -range $range} result] {
            return -code error "APSGetSRTunesVSA1b: $result"
        }
        
        #turn VSA on before taking measurment
        if [catch {exec hpSocketSend hpvecsr "OUTP ON" \
                 } result ] {
            return -code error "APSGetSRTuneVSA1c: unable to turn on VSA scope: $result"
        }
        after 1000
        eval $statusCallback "{HP VSA has completed data acquisition}"
        if [catch {APSGetSRTuneWaveformHPVSA -output $output.$plane -dividingLine $dividingLine \
                     -description "$description" -MXA $MXA -xP0ReducedGain $xP0ReducedGain -yP0ReducedGain $yP0ReducedGain \
                     -xDimtelReducedGain $xDimtelReducedGain -yDimtelReducedGain $yDimtelReducedGain \
                     -plane $plane -statusCallback $statusCallback -measHarmonic $measHarmonic  \
                 } result] {
            return -code error "APSGetSRTunesVSA2: $result"
        }
        if [catch {exec sddsprocess $output.$plane "-redefine=par,${plane}CenterFreq,$freq 1.0e6 /,units=MHz" -nowarnings} result] {
            return -code error "APSGetSRTunesVSA2a: $result"
        }
    }
    
    if [catch {exec sddsxref $output.x $output.y $output -take=* -transfer=parameter,* -nowarning} result] {
        return -code error "APSGetSRTunesVSA3: $result"
    }
    
    eval $statusCallback "{HP VSA tune data acquired}"
    catch {file delete  $output.x  $output.y}
    
}

proc APSSetupPARVSAScope {args} {
    set plane x
    set freq 9.97e7
    set sourceLevel -10DBM
    set freqPoints 1601
    set span 5e5
    set resolution 3000
    set averageNumber 10
    set average ON
    set repeat NORM
    set waitTime 30
    set statusCallback ""
    APSStrictParseArguments {plane freq sourceLevel span resolution average averageNumber repeat waitTime statusCallback}
    
    if {$plane=="s"} {
        set plane0 x
    } else {
        set plane0 $plane
    }
    if [string length $statusCallback] {
        eval $statusCallback {"switching mux..."}
    }
    if [catch {exec cavput -list=P:BnchCln:Mux10mbbo=[string toupper $plane0],P:BnchCln:Mux20mbbo=${plane0}Tune -pend=30} result] {
        return -code error "APSSetupPARVSAScope1: Error changing tune mux: $result"
    }
    if [string length $statusCallback] {
        eval $statusCallback {"setup par VSA..."}
    }
    if [string length $statusCallback] {
        eval $statusCallback {"Turn on par vsa..."}
    }
    # turn on VSA source
    if [catch {exec hpSocketSend hpvecpar "OUTP ON" \
             } result ] {
        return -code error "APSSetupPARVSAScope3: unable to turn on VSA scope: $result"
    }
    #setup VSA 
    #average value should be ON/OFF, repeat value should be NORM/REP (for repeat off/on)
   
    if [catch {exec hpSocketSend hpvecpar "FREQ:CENT $freq" -pause=0.1 \
                 "FREQ:SPAN $span" -pause=0.1 \
                 "SOUR:VOLT $sourceLevel" \
                 "AVER:STAT $average" -pause=0.1 \
                 "AVER:COUNT $averageNumber" -pause=0.1 \
                 "AVER:TCON $repeat" -pause=0.1 \
                 "SENSE:SWE:POIN $freqPoints" -pause=0.1 \
                 "BAND $resolution" -pause=0.1 \
                 "SOUR:FUNC PCH" -pause=0.1 \
                 "WIND:GATE UNIF" -pause=5 \
                 "ABOR;*WAI" } result] {
        return -code error "APSSetupPARVSAScope2: error setup par vsa scope: $result"
    }
    
    APSWaitWithUpdate -waitSeconds $averageNumber
    
    set timeout [expr [clock seconds] + $waitTime]
    if [string length $statusCallback] {
        eval $statusCallback {"Waiting $waitTime seconds for HP VSA to acquire data"}
    }
    while {[clock seconds]<$timeout} {
        set operationCondition [exec hpSocketSend hpvecpar \
                                  "STAT:OPER:COND?"]
        if {$operationCondition ==32} {
            break
        }
        after 2000
    }
    
    set operationCondition [exec hpSocketSend hpvecpar \
                              "STAT:OPER:COND?"]
    if {$operationCondition!=32} {
        return -code error "APSSetupPARVSAScope4: Failed to acquire waveform in 30 seconds, check the par VSA."
    }
}

proc APSGetPARTuneHPVSA {args} {
    set output ""
    set description ""
    set plane ""
    set freq ""
    set average ""
    set sourceLevel ""
    set span ""
    set resolution ""
    set freqPoints ""
    set statusCallback APSNoOp
    set rfFrequency [exec cavget -list=A014-IETS:BTC:BInjSetFreqM -floatFormat=%.10e -pendIoTime=5]
    set parRF [expr $rfFrequency / 36.0]
    
    APSStrictParseArguments {output description plane freq statusCallback average sourceLevel span resolution freqPoints}
    set pvList {A014-IETS:BTC:BInjSetFreqM LTP:FCM:qTotalAI PTB:CM:qTotalAI PAR:awg:rms:B:region6 PAR:awg:rms:B:region7 PAR:awg:rms:B:region8}
    set nameList {RFFrequency LTPCurrent PTBCurrnt PARTRegion6BCurrent PARRegion7BCurrent PARRegion8BCurrent}
    if [string length $statusCallback] {
        eval $statusCallback "{set up par VSA for $plane...}"
    }
    if [catch {exec hpSocketSend hpvecpar "OUTP OFF" \
             } result ] {
        return -code error "APSGetPARTuneVSA1: unable to turn off par VSA scope: $result"
    }
    after 1000
    if [catch {APSSetupPARVSAScope -sourceLevel $sourceLevel -plane $plane -root $output \
                 -average $average -freq $freq  -statusCallback $statusCallback -resolution $resolution \
                 -span $span \
                 -averageNumber $average -freqPoints $freqPoints} result] {
        return -code error "APSGetParTuneVSA2: $result"
    }
    if [string length $statusCallback] {
        eval $statusCallback "saving VSA waveform..."
    }
    if [catch {exec cavget -list=[join $pvList ,] -pend=30 -floatformat=%.15e -printErrors} valList] {
        return -code error "APSGetParTuneVSA3: error reading pv values: $valList"
    }
       
    if [catch {exec hpVecTrace -hpvecpar a $output.tmp } result] {
        return -code error "APSGetParTuneVSA4: Error reading hpvecpar waveform data: $result"
    }
    set opt ""
    foreach name $nameList val $valList {
        lappend opt -redefine=par,$name,$val
    }
   
    if [catch {eval exec sddsprocess $output.tmp -pipe=out \
                 \"-redefine=par,${plane}CenterFreq,$freq 1.0e6 /,units=MHz\" \
                 \"-redefine=col,Tune,Frequency $parRF / 1.0e6 * 1 mod\" \
                 $opt \
                 | sddsconvert -pipe  -edit=col,*,ai/$plane/ \
                 | sddsprocess -pipe=in $output.1  \
                 "-reprint=par,Description,$description" \
                 -process=${plane}Waveform,max,${plane}Tune,pos,functionOf=${plane}Tune  } result] {
        return -code error "APSGetParTuneVSA5: error processing tune: $result"
    }
    set tune [exec sdds2stream -par=${plane}Tune $output.1]
    if [catch {exec sddsprocess $output.1 $output.$plane \
                 "-print=par,${plane}TuneString,${plane}Tune\=[format %.4f $tune]" } result] {
        return -code error "APSGetParTuneVSA6: error define tune: $result"
    }
   
    catch {file delete $output.tmp $output.1}
}

proc APSGetPARTunesHPVSA {args} {
    set output ""
    set description ""
    set average 10
    set statusCallback APSNoOp
    set rfFrequency [exec cavget -list=A014-IETS:BTC:BInjSetFreqM -floatFormat=%.10e -pendIoTime=5]
    set parRF [expr $rfFrequency / 36.0]
    set expectedXtune 0.2
    set xFrequency [expr $parRF * (10.0 + $expectedXtune)]
    set expectedYtune 0.2
    set yFrequency [expr $parRF * (10.0 + $expectedYtune)]
    set xSourceLevel -10DBM
    set ySourceLevel -10DBM
    set xspan 5e5
    set yspan 5e5
    set xresolution 3000
    set yresolution 3000
    set freqPoints 1601
    if {[APSStrictParseArguments {output description xFrequency yFrequency average statusCallback xSourceLevel ySourceLevel xspan yspan xresolution yresolution 1601}] || \
          ![string length $output] || $xFrequency<=0 || $yFrequency<=0 || $average<=0} {
        return -code error "APSGetPARTunesVSA1: bad arguments"
    }
   
    foreach plane {x y} {
        set freq [set ${plane}Frequency]
        set sourceLevel [set ${plane}SourceLevel]
        set resolution [set ${plane}resolution]
        set span [set ${plane}span]
        if [catch {APSGetPARTuneHPVSA -plane $plane -freq $freq -sourceLevel $sourceLevel -resolution $resolution -output $output \
                     -span $span -average $average -freqPoints $freqPoints -statusCallback $statusCallback } result] {
            return -code error "APSGetParTunesVSA2: $result"
        }
    }
    
    if [catch {exec sddsxref $output.x $output.y $output -take=* -transfer=parameter,* -nowarning} result] {
        return -code error "APSGetPARTunesVSA3: $result"
    }
    
    eval $statusCallback "{HP VSA tune data acquired}"
    catch {file delete  $output.x  $output.y}

}
