#
# $Log: not supported by cvs2svn $
# Revision 1.28  2009/06/09 22:09:39  shang
# replaced caput by cavput since it does not work for P:BnchCln:Mux20mbbo string put
#
# Revision 1.27  2009/06/09 20:05:16  shang
# added setting more pvs to required states for bunch cleaning, per CY's request
#
# Revision 1.26  2009/06/08 20:05:34  shang
# changed the input mux switches due to hardware changes.
#
# Revision 1.25  2009/06/04 20:12:51  shang
# changed the DS345 drive amptitude to 2.0 VRMS
#
# Revision 1.24  2009/05/26 14:18:28  shang
# commented out the channel accesses of P:BnchClnSelectC since it no longer exists
#
# Revision 1.23  2009/03/25 15:23:26  shang
# skipped testing number 9 waveform in verify bunch cleaning even though it is not good, but does not affect bunch cleaning
#
# Revision 1.22  2009/03/17 19:19:28  shang
# added ds345Freq argument to APSMpPARStartBunchCleaning
#
# Revision 1.21  2009/03/17 19:10:47  shang
# modified  APSParBunchCleaningDrive so that the start and stop bunch cleaning work properly.
#
# Revision 1.20  2008/07/21 18:01:20  shang
# modified the start bunch cleaning pem to use APSParBunchCleaningDrive to turn on the par bunch cleaning drive.
#
# Revision 1.19  2008/07/18 18:48:38  shang
# added turn on/off PAR bunch cleaning drive procedure, and uses it for stopping PAR bunch cleaning, instead of set the DG345 voltage output to 0.04V since there is still a residue drive with 0.04V output.
#
# Revision 1.18  2008/06/16 15:43:31  shang
# added ds345Freq arguments to APSMpPARStartBunchCleaning pem.
#
# Revision 1.17  2008/06/16 15:24:52  shang
# modified the stop bunch cleaning pem to only set the DG345 output to 0.04 per CY's request.
#
# Revision 1.16  2008/06/10 19:45:21  shang
# added restore par beam and set the shift waveform to 0 if verification failed.
#
# Revision 1.15  2008/03/24 20:07:20  shang
# corrected a return statement in verify bunch cleaning procedure.
#
# Revision 1.14  2008/03/11 13:57:12  shang
# moved "enable par beam" after checking  topup.
#
# Revision 1.13  2008/03/11 13:12:32  shang
# changed the verifying time from 50s to 35s since 50s does not work for 60s topup, and added enabling par beam before verifying.
#
# Revision 1.12  2008/03/10 21:30:31  shang
# modified par bunch cleaning procedures to also work in top-up mode.
#
# Revision 1.11  2008/01/17 20:12:06  shang
# replaced the delayline pv P:HPDL1a:DelayC by P:HPDL1a:SetDelay
#
# Revision 1.10  2007/03/01 16:55:04  soliday
# Added calls to APSLogScriptAction to store initialization values
# for APSMpPARStartBunchCleaning.
#
# Revision 1.9  2006/09/21 20:06:17  soliday
# Updated because of a PV name change.
#
# Revision 1.8  2006/03/10 20:01:31  shang
# removed scan delay line procedure
#
# Revision 1.7  2006/03/10 15:23:46  shang
# added set the DG535 channel A and C delay time to 0.35s before starting tune measurement
# and changed the completed condition of VSA setup from 56 (which is no longer true) to 32.
#
# Revision 1.6  2006/03/09 15:42:16  shang
# added a reminding message to verify bunch cleaning.
#
# Revision 1.5  2006/03/09 15:31:32  shang
# changed the number of shift waveform turns from 12 to 18 since the waveform for bunch cleaing now is 18-record.
#
# Revision 1.4  2006/03/08 22:13:23  shang
# changed the pass turn from 0, 6 to 0, 9 to be consistent with hardware changes.
#
# Revision 1.3  2006/03/07 16:09:27  shang
# changed the current threshold from high 1.0 to 0.5, low 0.3 to 0.2 for verifying bunch cleaning.
#
# Revision 1.2  2006/03/06 15:24:29  soliday
# Fixed a humorous typo.
#
# Revision 1.1  2006/01/30 22:43:10  shang
# first version
#

proc APSMpPARStartBunchCleaningInfo {args} {
    return "This procedure restores bunch cleaning parameters from selected SCR file and starts bunch cleaning."
}
proc APSMpPARStartBunchCleaningInitDialog {frame} {
    global APSMpPARStartBunchCleaning
    
    APSRadioButtonFrame .check -parent $frame -label "Load parameters from SCR file?" \
        -buttonList {Yes No} -valueList {1 0} \
        -variable APSMpPARStartBunchCleaning(loadSCR)
    APSAddSCRDialog .scr -parent $frame -system LPL \
        -label "Choose SCR file for restoring proper parameters required by bunch cleaning setup" \
        -arrayName APSMpPARStartBunchCleaning \
        -defaultFile $APSMpPARStartBunchCleaning(ShortFilename) \
        -description $APSMpPARStartBunchCleaning(Description)
    APSMpReturn ok
}

proc APSMpPARStartBunchCleaning {args} {
    global APSMpPARStartBunchCleaning 
    set SCRdir /home/helios/oagData/SCR/snapshots/LPL
    if [catch {exec cavget -list=PAR:Fnd:SystemSelect,PAR:Har:SystemSelect -numerical -printErrors -pend=10} valList] {
	APSMpReturn error $valList
    }
    set tube1 [expr [lindex $valList 0]+1]
    set tube2 [expr [lindex $valList 1]+1]
    set ShortFilename LPL-SysRef_PAR_RF1_T${tube1}_RF12_T${tube2}.gz
    set Description [exec sdds2stream -par=SnapshotDescription $SCRdir/$ShortFilename]
    set statusCallback ""
    set loadSCR 1
    set ds345Freq ""
    APSStrictParseArguments {statusCallback ShortFilename loadSCR ds345Freq}
    set SCRdir /home/helios/oagData/SCR/snapshots/LPL
    set ShortFilename LPL-OpPref.gz
    APSMpStep init -promptDialog APSMpPARStartBunchCleaningInitDialog \
        -vars {ShortFilename loadSCR Description ds345Freq}
  
    set paramString ""
    foreach param {ShortFilename loadSCR Description} {
        append paramString "$param=\"[set $param]\" "
    }
    catch {APSLogScriptAction \
             -procedure APSMpPARStartBunchCleaning \
             -action initialize \
             -state ok \
             -parameters $paramString}

    if $loadSCR {
        APSMpStep "Load parameter from SCR file - $ShortFilename."
        if [catch {APSMpPARLoadBunchCleaningPVsFromSCR -ShortFilename $ShortFilename -ds345Freq $ds345Freq} result] { 
            APSMpReturn error "APSMpPARStartBunchCleaning1: $result"
        }
    } else {
        for {set i 0} {$i<6} {incr i} {
            if [catch {exec cavput -list=P:Ds345:AmplitudeRmsC.VAL=2.0 } result] { 
                APSMpReturn error "APSMpPARStartBunchCleaning2: $result"
            }
        }
    }
    if {0} {
	if [catch {exec cavput -list=P:BnchClnSelectC=0 } result] {
	    APSMpReturn error "APSMpPARStartBunchCleaning3a: $result"
	}
	after 1000
	if [catch {exec cavput -list=P:BnchClnSelectC=2 } result] {
	    APSMpReturn error "APSMpPARStartBunchCleaning3b: $result"
	}
    }
    APSMpStep "Turn on bunch cleaning and PAR beam."
    if [string length $statusCallback] {
        eval $statusCallback {"Turn on bunch cleaning and PAR beam."}
    }
    if [catch {APSParBunchCleaningDrive -drive on} result] {
        APSMpReturn error "APSMpPARStartBunchCleaning4a: $result"
    }
    if [catch {TogglePulsedMagnetEnables -location PAR } result] {
        APSMpReturn error "APSMpPARStartBunchCleaning4: $result"
    }
    exec /home/helios/PAR/bin/shiftWF 0
    if [string length $statusCallback] {
        eval $statusCallback {"PAR bunch cleaning setup completed."}
    }
    APSMpStep "PAR bunch cleaning started."
    APSMpReturn ok
}

proc APSMpPARLoadBunchCleaningPVsFromSCR {args} {
    set ShortFilename ""
    set ds345Freq ""
    set SCRdir /home/helios/oagData/SCR/snapshots/LPL
    set statusCallback ""
    APSStrictParseArguments {ShortFilename ds345Freq statusCallback}
    global DS345Freq
    if ![string length $ShortFilename] {
        APSMpReturn error "APSMpPARLoadBunchCleaningPVsFromSCR: no SCR file is selected for setup bunch cleaning."
    }
    set tmpfile /tmp/[APSTmpString]
    APSAddToTmpFileList -ID 1 -fileList "$tmpfile.1 $tmpfile.2"
   
    set pvList {P:Ds345:FrequencyC P:Ds345:AmplitudeRmsC P:BnchCln:Mux10mbbo \
                    P:DG1:aDelayAO P:DG1:bDelayAO \
                    P:DG1:cDelayAO P:DG1:dDelayAO P:DG1:trigModeSetMO \
                    P:HPDL1a:SetDelay \
                    P:Ds345:FunctionC P:Ds345:ArbSampFreqC \
                    P:Ds345:ModulationC \
                    P:Ds345:ModulationRateC P:Ds345:ModulationTypeC \
                    P:Ds345:ModulationWaveFC P:Ds345:SweepStartFC \
                    P:Ds345:SweepStopFC P:Ds345:FMSpanC}
    if [string length $ds345Freq] {
        set pvList [lreplace $pvList 0 0]
    }
    if [catch {exec sddsmakedataset $tmpfile.1 -col=ControlName,type=string \
                   -data=[join $pvList ,]} result] {
        APSMpReturn error "APSMpPARStartBunchCleaning: $result"
    }
    
    APSMpStep "Set DS345 frequency, scan delayline, and other parameters for the bunch cleaning system"
    if [string length $statusCallback] {
        eval $statusCallback {"Set DS345 frequency, scan delayline, and other parameters for the bunch cleaning system"}
    }
    
    if [catch {exec sddsselect $SCRdir/$ShortFilename $tmpfile.1 $tmpfile.2 -match=ControlName } reuslt] {
        APSMpReturn error "APSMpPARStartBunchCleaning: probably selected SCR file does not have required PVs.\n$result"
    }
    set rows [exec sdds2stream -rows=bare $tmpfile.2]
    if !$rows {
        APSMpReturn error "APSMpPARStartBunchCleaning: selected SCR file does not have required PVs."
    }
    if [catch {exec sddscasr $tmpfile.2 -restore} result] {
        APSMpReturn error "APSMpPARLoadBunchCleaningFromSCR: $result"
    }
    
    if [string length $ds345Freq] {
        if [catch {exec cavput -list=P:Ds345:FrequencyC=$ds345Freq} result] {
            APSMpReturn error "APSMpPARLoadBunchCleaningFromSCR: $result"
        }
    }
    APSAddToTmpFileList -ID 1 -fileList "$tmpfile.1 $tmpfile.2"        
    for {set i 1} {$i<5} {incr i} {
        after 1000
        if [catch {exec cavput -list=P:Ds345:RawReadX.PROC=1 -pend=30} result] {
            return -code error $result
        }
        after 1000
        if [catch {exec cavput -list=P:Ds345:UpdateAllC.PROC=1 -pend=30} result] {
            return -code error $result
        }
    }
    APSMpReturn ok
}

proc APSMpPARSetupVSA {args} {
    #default wait for 10 minutes
    set timeout 600
    APSStrictParseArguments {timeout}
    #restore proper VSA configuration for PAR Horizontal Tune measurement
    if [catch {exec hpSocketSend hpvecboo \
                   "MMEM:LOAD:STAT 1,'NVRAM:PARHVTUN'" } result] {
        APSMpReturn error "APSMpPARSetupVSA: can not restore PAR HV Tune VSA configuration: $result"
    }
    #wait for the configuration restoring done
    set timeout [expr [clock seconds] + $timeout]
    while {[clock seconds]<$timeout} {
        after 6000
        set operationCondition [exec hpSocketSend hpvecboo "STAT:OPER:COND?"]
        if {$operationCondition==32} {
            break
        }
    }
    set operationCondition [exec hpSocketSend hpvecboo "STAT:OPER:COND?"]
    if {$operationCondition!=32} {
        APSMpReturn error "APSMpPARSetupVSA: problem in restoring PAR horizontal tune measurement configuration (something might be wrong with VSA instrument)."
    }
    if [catch {exec hpSocketSend hpvecboo "OUTP ON"
	exec hpSocketSend hpvecboo "SOUR:VOLT -22"
        exec hpSocketSend hpvecboo "AVER ON"
        exec hpSocketSend hpvecboo "AVER:COUN 10"
        exec hpSocketSend hpvecboo "FREQ:CENT 99.67MHZ"
        exec hpSocketSend hpvecboo "FREQ:SPAN 500 KHZ" 
        exec hpSocketSend hpvecboo "AVER:TCON NORM"} result] {
        APSMpReturn error "APSMpPARSetupVSA: error in setting hpvsa parameters: $result"
    }
    APSMpReturn ok
}

proc APSMpPARMeasureTune {args} {
    #starting measurement
    set timeout 600
    set setupVSA 0
    set statusCallback ""
    APSStrictParseArguments {timeout setupVSA statusCallback}
    global dialogBoxResponse beamNumber PARTune DS345Freq
    
    if [string length $statusCallback] {
        eval $statusCallback {"check linac/Par/LTB beam and bunch cleaning amplifiers."}
    }
    APSMpStep "check linac/Par/LTB beam and bunch cleaning amplifiers."
    APSInfoWindow .info -name "Operational Recommendations" -infoMessage "Before you go any further, please make sure the linac/Par/PTB beam is available and the bunch cleaing amplifiers is on." -width 50 -modal 1
    if [string length $statusCallback] {
        eval $statusCallback {"select 2 or 3 linac bunches for Par injection."}
    }
    set beamNumber 2
    set dialogBoxResponse ""
    set w [APSUniqueName .]
    APSDialogBox $w -cancelCommand "set dialogBoxResponse cancel" \
        -okCommand "set dialogBoxResponse ok"  -name "Select linac bunches for Par injection"
    APSRadioButtonFrame .num -parent $w.userFrame -label "linac bunches" \
        -buttonList {2 3} -valueList {2 3} -variable beamNumber
    tkwait window $w
    if [string compare $dialogBoxResponse cancel]==0 {
        APSMpReturn error "Measure PAR tune was cancelled."
    }
    #set the mux to x always for measure par tune.
    if {0} {
    if [catch {exec cavput -list=P:BnchCln:Mux10mbbo=X } result] {
	APSMpReturn error "APSMpPARMeasureTune: Problem setting Mux to X: $result"
    }
    }
    if [catch {exec cavput -list=P:BnchCln:Mux20mbbo=xTune,P:BnchCln:Mux10mbbo=X } result] {
        APSMpReturn error "APSMpPARMeasureTune: Problem setting Mux to X: $result"
    }
    if [catch {exec cavput -list=It:L:B0 -range=begin=2,end=8,interval=2 \
                   -list=_enb_bo.VAL=0 -pend=30} result] {
        APSMpReturn error "APSMpPARMeasureTune: Problem in setting linac injection sequence: $result"
    }
    if [catch {exec cavput -list=It:L:B -range=begin=10,end=12,interval=2 \
                   -list=_enb_bo.VAL=0 -pend=30} result] {
        APSMpReturn error "APSMpPARMeasureTune: Problem in setting linac injection sequence: $result"
    }
    if {$beamNumber==2} {
        set tList {0 2}
    } elseif {$beamNumber==3} {
        set tList {0 2 4}
    }
    if [catch {exec cavput -list=It:L:B0 -list=[join $tList ,] -list=_enb_bo.VAL=1 -pend=30} result] {
        APSMpReturn "APSMpPARMeasureTune: Problem in setting linac injection sequence: $result"
    }
    APSMpStep "Start Par injection/extraction."
    if [string length $statusCallback] {
        eval $statusCallback {"Start Par injection/extraction."}
    }
    if [catch {TogglePulsedMagnetEnables -location PAR } result] {
        APSMpReturn error "APSMpPARMeasureTune: $result"
    }
    if $setupVSA {
        APSMpStep "Setup PAR VSA."
        update
        if [string length $statusCallback] {
            eval $statusCallback {"Setup PAR VSA."}
        }
        if [catch {APSMpPARSetupVSA} result] {
            APSMpReturn error $result
        }
	if [string length $statusCallback] {
            eval $statusCallback {"Setup PAR VSA done."}
        }
        update
    }
    if [string length $statusCallback] {
        eval $statusCallback {"set bunch cleaning mux to tune."}
    }
    APSMpStep "set DG355 Timing."
    if [catch {exec cavput -list=P:DG1:aDelayAO=350000.0,P:DG1:cDelayAO=350000.0 -pend=30} result] {
	APSMpReturn error $result
    }
    APSMpStep "set bunch cleaning mux to tune."
    if [catch {exec cavput -list=P:BnchCln:Mux10mbbo=X,P:BnchCln:Mux20mbbo=xTune \
                   -pend=30} result] {
        APSMpReturn error  "APSMpPARMeasureTune: cannot set bunch cleaning mux: $result"
    }
    if [string length $statusCallback] {
        eval $statusCallback {"start measurement."}
    }
    APSMpStep "start measurement."
    if [catch {exec hpSocketSend hpvecboo "ABOR;*WAI" } result] {
        return -code error "$result"
    }
    set oper 0
    set timeout [expr [clock seconds] + $timeout]
    while {[clock seconds]<$timeout} {
        after 1000
        update
        set oper [exec hpSocketSend hpvecboo "STAT:OPER:COND?"]
        if {$oper==32} {
            break
        }
    }
    set oper [exec hpSocketSend hpvecboo "STAT:OPER:COND?"]
    if {$oper!=32} {
        APSMpReturn error "APSMpPARMeasureTune: arevage timed out."
    }
    after 2000
    if [catch {exec  hpSocketSend hpvecboo "CALC1:MARK:MAX"} result] {
        APSMpReturn error "APSMpPARMeasureTune: can not set mark: $result"
    }
    after 2000
    #read the marker position
    if [catch {exec hpSocketSend hpvecboo "CALC1:MARK:X?"} freq] {
        APSMpReturn error "APSMpPARMeasureTune: can not the mark position: $result"
    }
    if [catch {exec cavget -list=A014-IETS:BTC:BInjSetFreqM -pend=30} rfFreq] {
        APSMpReturn error "APSMpPARMeasureTune: can not read the rf frequency: $rfFreq"
    }
    set freq0 [expr $rfFreq / 36.0]
    set PARTune [expr ($freq/$freq0) - int($freq/$freq0)]
    set DS345Freq [expr $PARTune * $freq0]
    if [string length $statusCallback] {
        eval $statusCallback {"PAR tune measurement done. The par tune is $PARTune, and the DS345 frequency is $DS345Freq Hz"}
    }
    APSMpStep "PAR tune measurement done. The par tune is $PARTune, and the DS345 frequency is $DS345Freq Hz"
     if [catch {exec cavput -list=P:BnchCln:Mux10mbbo=Off,P:BnchCln:Mux20mbbo=Off \
                   -pend=30} result] {
        APSMpReturn error  "APSMpPARMeasureTune: cannot set bunch cleaning mux: $result"
    }
    APSMpReturn ok
}

proc APSMpPARVerifyBunchCleaningInfo {args} {
    return "This procedure verifies if the PAR bunch cleaning works."
}

proc APSMpPARVerifyBunchCleaning {args} {
    #verify bunch cleaning through shift waveform
    set statusCallback ""
    APSStrictParseArguments {statusCallback}
    
    APSMpStep "Check topup..."
   
    if [catch {exec cavget -list=Mt:TopUpAutoEnableC.VAL -num } topup] {
        APSMpReturn "APSMpPARVerifyBunchCleaning(1): unable to read topup pv: $topup"
    }
   
    set first 1
    if $topup {
        while {1} {
            if [catch {exec cavget -list=Mt:TopUpTime2Warn.VAL } time] {
                APSMpReturn "APSMpPARVerifyBunchCleaing(2): unable to read Mt:TopUpTime2Warn.VAL: $time"
            }
            if {$time<35} {
                if $first {
                    APSMpStep "The time to injection is too soon, waiting for next topup cycle..."
                    if [string length $statusCallback] {
                        eval $statusCallback {"The time to injection is too soon, Wait for next topup..."}
                    }
                    set first 0
                }
                APSWaitWithUpdate -waitSeconds $time -updateInterval 1
            } else {
                break
            }
        }
    }
    #enable PAR beam
    if [catch {TogglePulsedMagnetEnables -location PAR } result] {
        APSMpReturn error "APSMpPARVerifyBunchCleaning(3) - unable to enable par beam: $result"
    }
    set turns 18
    if {![APSMultipleChoice [APSUniqueName .] -modal 1 \
              -question "Before you go any further, please make sure that PTB charge is greater than 0.7nc.  Do you want to proceed?" \
              -labelList {No Yes} -returnList {0 1}]} {
        APSMpReturn error "APSMpPARVerifyBunchCleaning(4): aborted by user."
    }
    APSMpStep "Scan waveform shift."
    for {set turn 0} {$turn<$turns} {incr turn} {
        APSMpStep "Switch waveform turn $turn ... /home/helios/PAR/bin/shiftWF $turn"
        if [string length $statusCallback] {
            eval $statusCallback {"Switch waveform turn $turn ... /home/helios/PAR/bin/shiftWF $turn"}
        }
        exec /home/helios/PAR/bin/shiftWF $turn
        after 2000
        if [catch {exec cavget -list=PAR:awg:rms:B:region9 -pend=30} charge] {
            APSMpParRestoreBeam
            APSMpReturn error "APSMpPARVerifyBunchCleaning(5): $charge"
        }
        if {$charge=="?"} {
            APSMpParRestoreBeam
            APSMpReturn error "APSMpPARVerifyBunchCleaning(6): unable to read value of PAR:awg:rms:B:region9"
        }
	APSMpStep "Charge at turn $turn is $charge nC."
        lappend chargeList $charge
    }
    for {set turn 0} {$turn<$turns} {incr turn} {
        set charge [lindex $chargeList $turn]
        if {$turn==0 || $turn==9} {
            #do  not test number 9 since it is not good, but does not affect the bunch cleaning
            if {$charge<0.65 && $turn==0} {
                APSMpParRestoreBeam
                APSMpReturn error "APSMpPARVerifyBunchCleaning(7): waveform does not go through at turn $turn, the charge is $charge nc.\n Bunch cleaning fails."
            }
        } else {
            if {$charge>0.2} {
                APSMpParRestoreBeam
                APSMpReturn error "APSMpPARVerifyBunchCleaning(8): waveform leaks at $turn turn, the current is $charge nc! Bunch cleaning fails."
                
            }
        }
    }
    if [catch {APSMpParRestoreBeam} result] {
        APSMpReturn error "Unable to restore beam: $result"
    }
    APSInfoWindow .info -name "Done" \
        -infoMessage "PAR bunch cleaning is working.!" -modal 1
    
    APSMpReturn ok
}


proc APSMpPARStopBunchCleaningInfo {args} {
    return "This procedure is to stop PAR bunch cleaning."
}

proc APSMpPARStopBunchCleaning {args} {
    set statusCallback ""
    APSStrictParseArguments {statusCallback}
    if [string length $statusCallback] {
        eval $statusCallback {"Stop PAR bunch cleaning ..."}
    }
    APSMpStep "Stop PAR bunch cleaning ..."
    #the mux pv was removed, use DS345 output pv for turn on/off bunch cleaning 
    if [catch {APSParBunchCleaningDrive -drive off} result] {
        APSMpReturn error "APSMpParStopBunchCleaning(1): error in turn off par bunch cleaning drive: $result"
    }
    if [string length $statusCallback] {
        eval $statusCallback {"PAR bunch cleaning stopped."}
    }
    APSMpStep "PAR bunch cleaning stopped."
    APSMpReturn ok
}

proc APSMpParRestoreBeam {args} {
    exec /home/helios/PAR/bin/shiftWF 0
    if [catch {TogglePulsedMagnetEnables -location PAR } result] {
		return -code error "Unable to enable par beam: $result"
    }
}

proc APSParBunchCleaningDrive {args} {
    set drive off
    APSStrictParseArguments {drive} 
    
    switch $drive {
        on {
	    if [catch {exec cavput -list=P:DG1:trigModeSetMO=1,P:DG1:abOutputModeSetMO=0,P:BnchCln:Mux20mbbo=Off,P:BnchCln:Mux21mbbo=Mux1_1,P:BnchCln:Mux10mbbo=Off,P:BnchCln:Mux11mbbo=TO } result] {
		return -code error $result
	    }
        }
        off -
	xtune -
	ytune {
	    if [catch {exec cavput -list=P:DG1:trigModeSetMO=1,P:DG1:abOutputModeSetMO=3,P:DG1:abOutputAmpSetAO=0.1,P:DG1:abOutputOffsetSetAO=4.0} result] {
		return -code error $result
	    }
        }
        default {
            return -code error "APSParBunchCleaningDrive: invalid drive - $drive provided."
        }
    }
    for {set i 1} {$i<=5} {incr i} {
        if [catch {exec cavput -list=P:Ds345:RawReadX.PROC=1 } result] {
            return -code error "APSParBunchCleaningDrive1: $result."
        }
        after 1000
        if [catch {exec cavput -list=P:Ds345:UpdateAllC.PROC=1 } result] {
            return -code error "APSParBunchCleaningDrive2: $result."
        }
        after 1000
    }
}
