#
# $Log: not supported by cvs2svn $
# Revision 1.32  2008/02/05 23:47:00  borland
# Now allows conditioning if no restore file is given.  Needed for conditioning
# to system lattice files at various energies.
#
# Revision 1.31  2007/12/07 17:09:37  soliday
# Added code to better handle MPEOB faults.
#
# Revision 1.30  2007/11/02 16:01:09  soliday
# The number of conditioning cycles will never be greater than 4 for any power
# supply no matter what conditioning time is given and the length of the
# conditioning cycle for any power supply.
#
# Revision 1.29  2007/03/01 17:41:30  soliday
# Changed conditioning time back to 10 minutes.
#
# Revision 1.28  2007/02/20 16:04:49  soliday
# Updated so that it now uses a 14 minute conditiong time. Which gets converted
# into cycles which ends up being 15-18 minutes of actual conditioning.
#
# Revision 1.27  2006/05/23 14:24:59  soliday
# Added acis checks.
#
# Revision 1.26  2006/04/20 16:06:50  soliday
# Updated APsMpPARLETStartUp so that it now uses the APSMpPARLETCondition routine.
#
# Revision 1.25  2005/09/27 14:23:55  shang
# added prompt dialog box to those pems that do not have
#
# Revision 1.24  2003/10/28 15:50:02  soliday
# These PAR procedures now alert the user if no SCR file has been chosen.
#
# Revision 1.23  2003/10/27 20:13:55  borland
# Added aperture-clearing for PAR bypass.
# Put catch statements around APSMpJoin commands.
# Added status messages inside loops for conditioning and kicker warmup.
#
# Revision 1.22  2003/10/14 16:27:07  soliday
# Added APSMpStep statements at the end of procedures that may be run in parallel.
#
# Revision 1.21  2003/09/24 15:05:39  soliday
# Added catch statement around APSLogScriptAction in case the logDaemon is down.
#
# Revision 1.20  2003/03/06 21:11:43  soliday
# Modified conditioning routines so that they default to blocking mode.
#
# Revision 1.19  2002/10/02 14:45:35  soliday
# Fixed DCPS when it should not start.
#
# Revision 1.18  2002/04/15 17:10:18  soliday
# Changed code for PTB:B1/B2
#
# Revision 1.17  2001/02/22 20:55:19  borland
# Switched to LPL system from PLET.
#
# Revision 1.16  2000/12/05 00:37:12  borland
# Added APSLogScriptAction calls.
#
# Revision 1.15  2000/06/26 17:33:56  borland
# Now uses APSAddSCRDialog to allow selection of the SCR file.
# Uses the SCR file, if any, for configuration of the standardization.
# Also, does a more thorough job of setting the number of cycles for
# a given desired minutes of standardization.
#
# Revision 1.14  2000/05/02 14:55:29  borland
# Added more detailed steps descriptions.
#
# Revision 1.13  2000/04/26 16:41:22  soliday
# Added APSMpStep proc options.
#
# Revision 1.12  1999/07/28 00:43:16  borland
# Replaced 325MeVReference with 325MeVPreferredRFGun.
#
# Revision 1.11  1999/07/27 15:21:03  borland
# Default energy is now 325 MeV and default snapshot is PLET-325MeVPreferredRFGun.gz,
# per G. Banks request.
#
# Revision 1.10  1998/07/27 19:49:57  borland
# Increased default conditioning time from 5 to 10 minutes.  Seemed to get
# problems with 5 minutes in reproducing performance after a shutdown.
#
# Revision 1.9  1998/01/09 19:06:34  borland
# Changed name of PLET refernce file from PLET-Reference to PLET-400MeVReference
#
# Revision 1.8  1998/01/03 01:14:38  borland
# Improved robustness of DCPS turn on procedures.
#
# Revision 1.7  1997/04/18 00:37:58  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.6  1996/11/22 20:18:15  borland
# Added check of MPEOB buttons prior to attempting DCPS turn on.
#
# Revision 1.5  1996/10/09 22:46:48  borland
# Reduced default conditioning times to 5 minutes.
#
# Revision 1.4  1996/10/08 21:44:14  borland
# Reduced default standardization time to 10 minutes.
#
# Revision 1.3  1996/08/09 19:44:35  borland
# Allows individual magnet standardization.
#
# Revision 1.2  1996/07/27 15:29:05  borland
# Now has default restoreFile of PLET-400MeVReference.gz
#
# Revision 1.1  1996/07/26 22:14:17  borland
# New versions using parallel procedure execution and catching of errors.
# Also much better organized and tested than previous versions.
#
#

set PLETSnapshotDir /home/helios/oagData/SCR/snapshots/LPL
set controlFilesDir /home/helios/oagData/controlFiles

proc APSMpPTBStartUpInfo {} {
    return "This is a stand-alone procedure which turns on the PTB magnets, standardizes them, waits for the standardization to finish, and restores an PTB configuration."
}

proc APSMpPTBStartUp {args} {
    global PLETSnapshotDir

    set energy [APSPARLETDefaultEnergy]
    set conditioningTime 10
    set restoreFile ""
    set DCPS 1
    set restoreDCPS 1
    APSStrictParseArguments {energy conditioningTime restoreFile DCPS restoreDCPS}

    global execMode

    if {$execMode != "Automatic"} {
        if {[catch {exec cavget -list=ACIS:LAOL_INH_GUN,ACIS:LBL_GUN_INH,ACIS:LA_BP_MODE,ACIS:LB_BP_MD -num -pend=20} acisState]} {
            APSMpReturn error "APSMpPTBStartUp: $acisState"
        }
        if {([lindex $acisState 0] == 1) || ([lindex $acisState 1] == 1)} {
            if {[APSPEMTKDialog .warningDialog \
                   -text "Linac/PAR is in an acis inhibit state."] == 1} {
                APSMpReturn error "APSMpPTBStartUp: Linac/PAR is in an acis inhibit state."
            }
        } elseif {([lindex $acisState 2] == 0) || ([lindex $acisState 3] == 0)} {
            if {[APSPEMTKDialog .warningDialog \
                   -text "Linac/PAR is in an acis trip state."] == 1} {
                APSMpReturn error "APSMpPTBStartUp: Linac/PAR is in an acis trip state."
            }
        }
    }

    set ShortFilename $restoreFile
    set Description ""
    APSMpStep init -promptDialog APSMpPTBStartUpInitDialog \
      -vars {energy restoreFile conditioningTime ShortFilename}

    set paramString ""
    foreach param  {energy restoreFile conditioningTime ShortFilename} {
        append paramString "$param=\"[set $param]\" "
    }
    catch {APSLogScriptAction -procedure APSMpPTBStartUp -action initialize \
               -state ok -parameters $paramString}

    set restoreFile $ShortFilename
    if {[string length $restoreFile] && ![file exists $PLETSnapshotDir/$restoreFile]} {
        APSMpReturn error "File [file tail $restoreFile] not found."
    }
    if {[string length $restoreFile]} {
        if {[catch {exec sdds2stream $PLETSnapshotDir/$restoreFile -parameter=SnapshotDescription -page=1 -noquotes} results]} {
            APSMpReturn error "APSMpPTBStartUp: Invalid SCR file"
        }
        if {[string first "Limited save:" $results] != -1} {
            if {[catch {exec sddssort $PLETSnapshotDir/$restoreFile -pipe=out -column=Beamline -unique | sdds2stream -pipe=in -col=Beamline} results]} {
                APSMpReturn error "APSMpPTBStartUp: Problem reading beamlines categories from the SCR file"
            } else {
                if {([lsearch -exact $results PTB] == -1) || ([lsearch -exact $results PTB1] == -1) || ([lsearch -exact $results PTB2] == -1) || ([lsearch -exact $results PTB3] == -1)} {
                    APSMpReturn error "APSMpPTBStartUp: LIMITED SAVE SCR file does not include all the PTB beamline categories"
                }
            }
        }
    }
    if {$DCPS == 1} {
        APSMpStep "PTB: Turn On DCPS" -proc "APSMpPTBTurnOnDCPS"
        if [catch APSMpPTBTurnOnDCPS result] {
            if {[APSPEMTKDialog .warningDialog -text "Unable turn on PTB DCPS.\nAPSMpPTBStartUp: $result"] == 1} {
                APSMpReturn error "Unable turn on PTB DCPS: APSMpPTBStartUp: $result"
            }
        }
        
        APSMpStep "PTB: Initiate Standardization" -proc "APSMpPTBStandardize"
        if [catch {APSMpPTBStandardize -energy $energy -restoreFile $restoreFile \
                       -conditioningTime $conditioningTime -block 0} result] {
            APSMpReturn error "Error initiating PTB standardization: $result"
        }
        
        APSMpStep "PTB: Initiate Degaussing" -proc "APSMpPTBDegauss"
        if [catch {APSMpPTBDegauss -degaussTime $conditioningTime -block 0} result] {
            APSMpReturn error "Error initiating PTB degaussing: $result"
        }
        
        APSMpStep "PTB: Wait For Conditioning" -proc "APSMpPTBWaitForConditioning"
        if [catch {APSMpPTBWaitForConditioning} result] {
            APSMpReturn error "Error waiting for PTB conditioning: $result"
        }
    }
    if [string length $restoreFile] {
        APSMpStep "PTB: Restore File (optional)" -proc "APSMpPTBRestoreFile"
        if [catch {APSMpPTBRestoreFile -restoreDCPS $restoreDCPS -restoreFile $restoreFile} result] {
            APSMpReturn error "Error restoring configuration from $restoreFile for PTB: $result"
        }

    }
    
    APSMpStep "PTB: Clear Aperture (of flags/valves)" -proc "APSMpPARLETClearAperture"
    if [catch {APSMpPARLETClearAperture -beamline PTB} result] {
        APSMpReturn error "Unable to clear PTB aperture."
    }
    APSMpStep "PTB StartUp Finished"
    APSMpReturn ok
}
 
proc APSMpPTBStartUpInitDialog {frame} {
    global status PLETSnapshotDir controlFilesDir
    global APSMpPTBStartUp

    APSLabeledEntry .le1 -parent $frame -label "Energy (MeV): " \
      -textVariable APSMpPTBStartUp(energy) \
      -contextHelp "Enter the energy of the beam you will be using in MeV."
      
    APSLabeledEntry .le2 -parent $frame -label "Minutes for conditioning: " \
      -textVariable APSMpPTBStartUp(conditioningTime) \
      -contextHelp "Enter the number of minutes you want to allow for conditioning.  The actual conditioning time may be longer, since each magnet must be put through at least one ramp cycle."

    APSAddSCRDialog .scr -parent $frame -system LPL -arrayName APSMpPTBStartUp \
      -defaultFile $APSMpPTBStartUp(ShortFilename)
}

proc APSMpPTBTurnOnDCPSInfo {} {
    return "Turns on PTB DC power supplies.  Retries several times.  May fail if run immediately after turning off DCPS."
}

proc APSMpPTBTurnOnDCPS {args} {
    global status
    set retries 5
    APSStrictParseArguments {retries}

    catch {APSLogScriptAction -procedure APSMpPTBTurnOnDCPS -action start \
               -state ok -parameters "retries=$retries"}

    #Check MPEOB
    APSMpStep "Check that the MPEOBs are pulled out"
    while {1} {
        if {[catch {APSPLETMPEOBsAreOut} mpeob]} {
            if {[APSPEMTKDialog .warningDialog -text "APSMpPTBTurnOnDCPS: Error checking MPEOB: $mpeob"] == 1} {
                APSMpReturn error "APSMpPTBTurnOnDCPS: Error checking MPEOB: $mpeob"
            }
            continue
        }
        if {!$mpeob} {
            if {[APSPEMTKDialog .warningDialog -text "APSMpPTBTurnOnDCPS: Both MPEOBs must be pulled out to start DCPS."] == 1} {
                APSMpReturn error "APSMpPTBTurnOnDCPS: Both MPEOBs must be pulled out to start DCPS."
            }
            continue
        }
        break
    }

    while {$retries} {
        set statusList [exec cavget -list=PTB:Q -range=beg=1,end=11 -list=:StatusCALC -label]
        set statusList [concat $statusList \
                          [exec cavget -list=PTB:B -list=1,2 -list=:StatusCALC -label]]
	set B1 [exec cavget -list=PTB:B1:StatusCALC -num]
	set B2 [exec cavget -list=PTB:B2:StatusCALC -num]
        set statusList \
          [concat $statusList \
             [exec cavget -list=PTB: -list=H,V -range=beg=1,end=4 -list=:StatusCALC -label]]
        set toDoList0 [APSSearchAssociateListForValue -list $statusList -value 2]
        set toDoList [concat $toDoList0 [APSSearchAssociateListForValue -list $statusList -value 3]]
        regsub -all {:StatusCALC} $toDoList {} toDoList
        if [llength $toDoList] {
            if [catch {exec cavput -list=[join $toDoList ,] -list=:ResetSEQ=1 } result] {
                APSMpReturn error "Error sending on commands: $result"
            }
	    after 50 
	    if {$B1} {
		if [catch {exec cavput -list=PTB:B1:OnSEQ=1 } result] {
		    APSMpReturn error "Error sending on commands: $result"
		}
	    }
	    if {$B2} {
		if [catch {exec cavput -list=PTB:B2:OnSEQ=1 } result] {
		    APSMpReturn error "Error sending on commands: $result"
		}
	    }
            # pause for IOC to deal with processing
            after 8000 
        } else {
            break
        }
        incr retries -1
    }
    set status2List0 [APSSearchAssociateListForValue -list $statusList -value 2]
    set status2List [concat $status2List0 [APSSearchAssociateListForValue -list $statusList -value 3]]
    if [llength $status2List] {
        APSMpReturn error "Unable to turn on PTB DC power supplies: $status2List."
    }
    set status1List [APSSearchAssociateListForValue -list $statusList -value 1]
    if [llength $status1List] {
        regsub -all :StatusCALC [join $status1List ,] "" probList
        APSAlertBox [APSUniqueName .] \
          -errorMessage "Warning: some PTB DC power supplies may need manual turn on.  Look at these supplies: $probList"
    }
    APSMpReturn ok
}

proc APSMpPTBStandardizeInfo {} {
    return "This is a procedure which initiates standardization of PTB.  It permits choosing which magnets to standardize, as well as the standardization time and the energy.  Does not turn the power supplies on, but assumes they are already on."
}

proc APSMpPTBStandardize {args} {
    global status PLETSnapshotDir controlFilesDir

    lappend psList Q1 Q2 Q3 Q4 Q5 Q6 Q7 Q8 Q9 Q10 Q11 B1 B2
    foreach elem $psList { 
        set $elem 1
    }
    set energy [APSPARLETDefaultEnergy]
    set restoreFile ""
    set conditioningTime 10
    set block 1
    APSStrictParseArguments [concat $psList [list energy conditioningTime block restoreFile]]

    set ShortFilename $restoreFile
    APSMpStep init -promptDialog APSMpPTBStandardizeInitDialog \
      -vars [concat [list energy conditioningTime ShortFilename] $psList]
    set restoreFile $ShortFilename
    if {[string length $restoreFile] && ![file exists $PLETSnapshotDir/$restoreFile]} {
        APSMpReturn error "File [file tail $restoreFile] not found."
    }

    set paramString ""
    foreach param {energy conditioningTime block restoreFile} {
        append paramString "$param=\"[set $param]\" "
    }
    catch {APSLogScriptAction -procedure APSMpPTBStandardize \
               -action initialize -state ok -parameters $paramString}

    set nameList ""
    foreach elem $psList {
        if [subst \$$elem] {
            lappend nameList $elem
        }
    }
    if [llength $nameList]==0 {
        APSMpReturn ok
    }
    set nameString [join $nameList ,]

    set file ${controlFilesDir}/PTB/PTB${energy}MeV.std
    if ![file exists $file] {
        APSMpReturn error "PTB standardization file for $energy MeV not found"
    }

    APSMpStep "PTB: Compute Standardization Time"
    set tmpfile /tmp/[APSTmpString]
    if [catch \
           {exec sddsprocess $file $tmpfile  \
              "-redefine=col,NumCycles,$conditioningTime Minutes Seconds 60 / + 2 * / int 4 > ? 4 : $conditioningTime Minutes Seconds 60 / + 2 * / int \$ ,type=long" \
          } result] {
        APSMpReturn error "sddsprocess error preparing to standardize PTB: $result"
    }

    APSMpStep "PTB: Configure Standardization"
    if [string length $restoreFile] {
        APSMpStep "PTB: Configure Standardization from $restoreFile"
        set tmpfile2 /tmp/[APSTmpString]
        set tmpfile3 /tmp/[APSTmpString]
        if [catch {exec sddsprocess $PLETSnapshotDir/$restoreFile $tmpfile2 \
                     -match=column,ControlName=PTB:B*,ControlName=PTB:Q*,| \
                     -edit=column,ElementName,ControlName,%/:CurrentAO// \
                     -scan=column,Finish,ValueString,%le
            exec sddsconvert $tmpfile -pipe=out -delete=column,Finish \
                     | sddsxref -pipe=in $tmpfile2 $tmpfile3 -match=ControlName=ElementName -take=Finish 
            file delete -force $tmpfile
            file rename -force $tmpfile3 $tmpfile
            file delete -force $tmpfile2} result] {
            eval file delete -force $tmpfile $tmpfile2 $tmpfile3
            APSMpReturn error "Error setting up standardization of PTB: $result"
        }
    }
    if  [catch {exec standardize -configure $tmpfile} result] {
        APSMpReturn error "Error initiating standardization: $result"
    }

    if {$B1} {
	if {[catch {exec cavput -list=PTB:B1:modeSetC=0} result]} {
	    APSMpReturn error "Error setting PTB:B1 to DC Mode: $result"
	}
    }
    if {$B2} {
	if {[catch {exec cavput -list=PTB:B2:modeSetC=0} result]} {
	    APSMpReturn error "Error setting PTB:B2 to DC Mode: $result"
	}
    }

    APSMpStep "PTB: Initiate Standardization"
    if [catch {exec cavput -list=PTB: -list=$nameString -list=:StandardizeSUB.PROC=1} result] {
        APSMpReturn error "Error initiating standardization of $nameString: $result"
    }

    if $block {
        APSMpStep "PTB: Wait For Standardization (optional)"
        if [catch {APSMpPTBWaitForConditioning -standardize 1} result] {
            APSMpReturn error "Error waiting for PTB standardization: $result"
        }
    }
    APSMpStep "PTB Standardize Finished"
    APSMpReturn ok
}

proc APSMpPTBStandardizeInitDialog {frame} {
    global status PLETSnapshotDir controlFilesDir
    global APSMpPTBStandardize

    APSLabeledEntry .le1 -parent $frame -label "Energy (MeV): " \
      -textVariable APSMpPTBStandardize(energy) \
      -contextHelp "Enter the energy of the beam you will be using in MeV."
      
    APSLabeledEntry .le2 -parent $frame -label "Minutes for conditioning: " \
      -textVariable APSMpPTBStandardize(conditioningTime) \
      -contextHelp "Enter the number of minutes you want to allow for conditioning.  The actual conditioning time may be longer, since each magnet must be put through at least one ramp cycle."

    APSCheckButtonFrame .cb1 -parent $frame -label "Magnets: " -orientation horizontal \
      -buttonList {Q1 Q2 Q3 Q4 Q5 Q6 Q7 Q8 Q9 Q10 Q11 B1 B2} \
      -allNone 1 \
      -variableList \
      {APSMpPTBStandardize(Q1) APSMpPTBStandardize(Q2) APSMpPTBStandardize(Q3) \
         APSMpPTBStandardize(Q4) APSMpPTBStandardize(Q5) APSMpPTBStandardize(Q6) \
         APSMpPTBStandardize(Q7) APSMpPTBStandardize(Q8) APSMpPTBStandardize(Q9) \
         APSMpPTBStandardize(Q10) APSMpPTBStandardize(Q11) APSMpPTBStandardize(B1) \
         APSMpPTBStandardize(B2)} \
      -contextHelp "Choose which magnets you want to standardize.  If none are chosen, no action is taken."

    APSAddSCRDialog .scr -parent $frame -system LPL -arrayName APSMpPTBStandardize \
      -defaultFile $APSMpPTBStandardize(ShortFilename)
}


proc APSMpPTBDegaussInfo {} {
    return "This is a procedure which initiates degaussing of PTB magnets."
}

proc APSMpPTBDegauss {args} {
    global status PLETSnapshotDir controlFilesDir

    set degaussTime 10
    set block 1
    APSStrictParseArguments {degaussTime block}

    APSMpStep init -promptDialog APSMpPTBDegaussInitDialog \
      -vars {degaussTime}

    catch {APSLogScriptAction -procedure APSMpPTBDegauss -action initialize \
               -state ok -parameters "degaussTime=$degaussTime"}

    set file ${controlFilesDir}/PTB/PTB_degauss.sdds
    set deleteFile 0
    if $degaussTime {
        APSMpStep "PTB: Compute Degaussing Time" 
        set newfile /tmp/[APSTmpString]
        exec sddsconvert $file -pipe=out -delete=col,DecayMinutes,DecaySeconds \
          | sddsprocess -pipe=in $newfile \
          "-define=col,DecayTime,$degaussTime NumDecay /" \
          {-define=col,DecayMinutes,DecayTime int,type=long} \
          {-define=col,DecaySeconds,DecayTime DecayMinutes - 60 * int,type=long}
        set file $newfile
        set deleteFile 1
    }
    APSMpStep "PTB: Configure Degaussing" 
    if [catch {exec degauss $file} result] {
        if $deleteFile {catch {exec rm $file}}
        APSMpReturn error "Error initiating degaussing: $result"
    }
    if $deleteFile {catch {exec rm $file}}

    APSMpStep "PTB: Initiate Degaussing"
    set status "Degaussing initiated."
    if $block {
        APSMpStep "PTB: Wait For Degaussing (optional)"
        set status "Waiting for degaussing to complete."
        if [catch {APSMpPTBWaitForConditioning -degauss 1} result] {
            APSMpReturn error "Error waiting for PTB degaussing: $result"
        }
        set status "Degaussing completed."
    }
    APSMpStep "PTB Degauss Finished"
    APSMpReturn ok
}

proc APSMpPTBDegaussInitDialog {frame} {
    global status PLETSnapshotDir controlFilesDir
    global APSMpPTBDegauss

    APSLabeledEntry .le2 -parent $frame -label "Minutes for conditioning: " \
      -textVariable APSMpPTBDegauss(degaussTime) \
      -contextHelp "Enter the number of minutes you want to allow for conditioning."
}

proc APSMpPTBCheckConditioning {args} {
    global status PLETSnapshotDir controlFilesDir

    set degauss 1
    set standardize 1
    APSStrictParseArguments {degauss standardize}

    catch {APSLogScriptAction -procedure APSMpPTBCheckConditioning \
               -action start -state ok \
               -parameters "degauss=$degauss standardize=$standardize"}

    if $degauss {
        set condList \
          [concat $condList \
             [exec cavget -list=PTB: -list=H,V -range=begin=1,end=4 -list=:StandardizeSUB.PROC -label]] 
    }
    if $standardize {
        set condList \
          [exec cavget -list=PTB:Q -range=begin=1,end=11 -list=:StandardizeSUB.PROC -label]
        set condList \
          [concat $condList \
             [exec cavget -list=PTB:B -list=1,2 -list=:StandardizeSUB.PROC -label]] 
    }

    set problemCond [APSSearchAssociateListForValue -list $condList -value 0]
    if {[llength $problemCond]} {
        APSMpReturn error "PTB magnets not conditioning as expected. ([join $problemCond])"
    }

    APSMpReturn ok
}

proc APSMpPTBWaitForConditioning {args} {
    global status PLETSnapshotDir controlFilesDir

    set degauss 1
    set standardize 1
    catch {APSLogScriptAction -procedure APSMpPTBWaitForConditioning \
               -action start -state ok \
               -parameters "degauss=$degauss standardize=$standardize"}
    set loopCount 0
    if $degauss {
        while {[exec cavget -list=PTB:HV:CondCALC -pend=10]} {
            if [expr $loopCount%15==0] {
                APSMpStep "Waiting For Conditioning"
            }
            incr loopCount
            update
            after 2000
        }

    }
    if $standardize {
        while {[exec cavget -list=PTB:Q:BM:CondCALC -pend=10]} {
            if [expr $loopCount%15==0] {
                APSMpStep "Waiting For Conditioning"
            }
            incr loopCount
            update
            after 2000
        }
    }
    APSMpReturn ok
}

proc APSMpPTBRestoreFile {args} {
    global status PLETSnapshotDir controlFilesDir

    set restoreFile ""
    set restoreDCPS 1
    APSStrictParseArguments {restoreFile restoreDCPS}

    catch {APSLogScriptAction -procedure APSMpPTBRestoreFile -action start \
               -state ok -parameters "restoreFile=$restoreFile"}

    if {![string length $restoreFile]} {
        APSMpReturn error "No restore file given for PTB."
    }

    set tmpfile /tmp/[APSTmpString]
    if {$restoreDCPS} {
        if [catch \
              {exec sddsprocess ${PLETSnapshotDir}/$restoreFile $tmpfile \
                 -match=col,Beamline=PTB* \
                 -match=col,IsReadOnly=+y,! \
                 -match=col,ValueString=,! } result] {
            APSMpReturn error "Error during processing prior restoring file $restoreFile for PTB: $result"
        }
    } else {
        if [catch \
              {exec sddsprocess ${PLETSnapshotDir}/$restoreFile $tmpfile \
                 -match=col,Beamline=PTB* \
                 -match=col,Category=SteeringPS,Category=MainPS,|,! \
                 -match=col,IsReadOnly=+y,! \
                 -match=col,ValueString=,! } result] {
            APSMpReturn error "Error during processing prior restoring file $restoreFile for PTB: $result"
        }
    }
    if [catch {exec sddscasr -restore $tmpfile} result] {
        APSMpReturn error "Error writing back values for PTB: $result"
    }
    if [catch {exec rm $tmpfile } result] {
        APSMpReturn error "Error deleting temporary file during PTB restore: $result"
    }
    APSMpReturn ok
}

proc APSMpPTBStopConditioningInfo {} {
    return "This procedure stops the PTB magnet conditioning."
}


proc APSMpPTBStopConditioning {} {
    global status PLETSnapshotDir controlFilesDir
    APSMpStep init -promptDialog APSMpPromptInitDialog


    if [catch {APSLinkToDeviceConfigPVs -device par} result] {
	return -code error "APSMpPTBStopConditioning: $result"
    }
    if {[catch {APSDevSend \
		  -releaseLinks 1 \
                  -group PSOps \
                  -operation StopConditioning \
                  -deviceList {"PTB:B1" "PTB:B2" "PTB:H1" "PTB:H2" "PTB:H3" "PTB:H4" "PTB:V1" "PTB:V2" "PTB:V3" "PTB:V4" "PTB:Q1" "PTB:Q2" "PTB:Q3" "PTB:Q4" "PTB:Q5" "PTB:Q6" "PTB:Q7" "PTB:Q8" "PTB:Q9" "PTB:Q10" "PTB:Q11"}} result]} {
	APSMpReturn error "APSMpPTBStopConditioning: Error stopping conditioning of PTB DCPS: $result"
    }
    
    APSMpReturn ok
}

proc APSMpPTBClearApertureInfo {} {
    return "This procedure clears the PTB aperture by removing flags and opening valves."
}

proc APSMpPTBClearAperture {} {
    APSMpStep init -promptDialog APSMpPromptInitDialog
    if [catch {APSMpPARLETClearAperture  -beamline PTB} result] {
        APSMpReturn error "Unable to clear PTB aperture"
    }
    APSMpReturn ok
}

proc APSMpSwitchLinacParTo1HzInfo {} {
    return "This procedures switches linac/PAR to 1Hz mode."
}

proc APSMpSwitchLinacParTo1Hz {} {
    if [catch {exec cavput  -list=It:faultDetTimeIntAao.VAL=550,It:faultDetTimeIntBao.VAL=1100,Mt:faultDetTimeIntAao.VAL=550,Mt:faultDetTimeIntBao.VAL=1100   -pend=30 } result] {
        APSMpReturn error "APSMpSwitchLinacParTo1Hz: error change the timeout interval: $result"
    }
    
    if [catch {exec cavput -list=It,Mt -list=:faultDetISelect -list=0,1,2,3,4,5 -list=Bo.VAL=B -pend=30 } result] {
        APSMpReturn error "APSMpSwitchLinacParTo1Hz: error set interval to A: $result"
    }
    
    if [catch {exec cavput -list=It:L:1HzNot2Hz_bo.VAL=1,P:DG1:aDelayAO=780000,PAR:awg:timingModeBO=1  -pend=30
        after 1000
        exec cavput -list=It:L:seq_len_lo.VAL=55,It:L:rfseq_len_lo.VAL=60 -pend=30 } result] {
        APSMpReturn error "APSMpSwitchLinacParTo1Hz: Error changing mode pv and linac sequence: $result"
    }
    if [catch {exec cavput -list=It:L:B0 -range=begin=0,end=8,interval=2 -list=_rfenb_bo.VAL=1
        exec cavput -list=It:L:B0 -range=begin=1,end=9,interval=2 -list=_rfenb_bo.VAL=0
        exec cavput -list=It:L:B -range=begin=10,end=58,interval=2 -list=_rfenb_bo.VAL=1
        exec cavput -list=It:L:B -range=begin=11,end=59,interval=2 -list=_rfenb_bo.VAL=0 } result] {
        APSMpReturn error "APSMpSwitchLinacParTo1Hz: Error changing rf sequence: $result"
    }
    if [catch {exec sddscasr -restore /home/helios/oagData/par/bunchCleaning/parChargeRegionTiming1Hz.sdds -pend=30} result] {
        APSMpReturn error "APSMpSwitchLinacParTo1Hz: Error changing par region timing: $result"
    }
    APSMpReturn ok
}

proc APSMpSwitchLinacParTo2HzInfo {} {
    return "This procedures switches linac/PAR to 2Hz mode."
}

proc APSMpSwitchLinacParTo2Hz {args} {
    #if [catch {exec cavput -list=It:L:1HzNot2Hz_bo.VAL=0,It:L:seq_len_lo.VAL=25,It:L:rfseq_len_lo.VAL=30 -pend=30} result] {
    #    APSMpReturn error "Error switching to 1Hz mode: $result"
    #}
    
    if [catch {exec cavput \
                 -list=It:faultDetTimeIntAao.VAL=550,It:faultDetTimeIntBao.VAL=1100,Mt:faultDetTimeIntAao.VAL=550,Mt:faultDetTimeIntBao.VAL=1100 \
                 -pend=30 } result] {
        APSMpReturn error "APSMpSwitchLinacParTo2Hz: error change the timeout interval: $result"
    }
    if [catch {exec cavput -list=It,Mt -list=:faultDetISelect -list=0,1,2,3,4,5 -list=Bo.VAL=A -pend=30 } result] {
        APSMpReturn error "APSMpSwitchLinacParTo2Hz: error set interval to A: $result"
    }
    
    if [catch {exec cavput -list=It:L:1HzNot2Hz_bo.VAL=0,P:DG1:aDelayAO=350000,PAR:awg:timingModeBO=0  -pend=30
        after 1000
        exec cavput -list=It:L:seq_len_lo.VAL=25,It:L:rfseq_len_lo.VAL=30 -pend=30 } result] {
        APSMpReturn error "APSMpSwitchLinacParTo2Hz: Error changing mode pv and linac sequence: $result"
    }
    if [catch {exec cavput -list=It:L:B0 -range=begin=0,end=8,interval=2 -list=_rfenb_bo.VAL=1
        exec cavput -list=It:L:B0 -range=begin=1,end=9,interval=2 -list=_rfenb_bo.VAL=0
        exec cavput -list=It:L:B -range=begin=10,end=58,interval=2 -list=_rfenb_bo.VAL=1
        exec cavput -list=It:L:B -range=begin=11,end=59,interval=2 -list=_rfenb_bo.VAL=0 } result] {
        APSMpReturn error "APSMpSwitchLinacParTo2Hz: Error changing rf sequence: $result"
    }
    if [catch {exec sddscasr -restore /home/helios/oagData/par/bunchCleaning/parChargeRegionTiming2Hz.sdds -pend=30} result] {
        APSMpReturn error "APSMpSwitchLinacParTo2Hz: Error changing par region timing: $result"
    }
    APSMpReturn ok
}



proc APSMpParResetStreakCamera {args} {
    set statusCallback ""
    APSStrictParseArguments {statusCallback}
    
    set vSweepMode POPC5680:1:VertSweepC
    set hTrigMode POPC5680:1:HorzTrigModeC
    set vSweepTime POPC5680:1:S:VSweepRngC
    set hSweepTime POPC5680:1:S:HSweepRngC
    set gateMode POPC5680:1:GateModeC
    set shutterOpen POPC5680:1:ShutterOpenC
    set initPV POPC5680:1:SetUpDeviceX.PROC
    set connectStat POPC5680:1:ConnectC.PROC
       
    set openCheck 0
    set closeCheck 0
    set count 0
    while {$openCheck==0 || $closeCheck==0} {
        #init
        if [catch {exec cavput -list=POPC5680:1:SetUpDeviceX.PROC=1 -pend=10 } result] {
            return -code error "APSMpParResetStreakCamera1(error initialize camera): $result"
        } 
        after 4000
        #connect/status
        if [catch {exec cavput -list=POPC5680:1:ConnectC.PROC=1 -pend=10} result] {
            return -code error "APSMpParResetStreakCamera2(error connect camera): $result"
        }
        after 2000
        if [catch {exec cavput -list=POPC5680:1:ConnectC.PROC=1 -pend=10} result] {
            return -code error "APSMpParResetStreakCamera3(error connect camera): $result"
        }
        if [string length $statusCallback] {
            eval $statusCallback "check shutter status"
        }
        if [catch { exec cavput -list=POPC5680:1:ShutterOpenC=0 -pend=10} result] {
            return -code error "APSMpParResetStreakCamera4(error close shutter):$result"
        }
        after 1000
        if [catch {exec cavget -list=POPC5680:1:ShutterStatusM -num -pend=10 -printErrors} shutter] {
            return -code error "APSMpParResetStreakCamera5(error check shutter status):$shutter"
        }
        if !$shutter {
            set closeCheck 1
        } else {
            set closeCheck 0
        }
        if [catch {exec cavput -list=POPC5680:1:ShutterOpenC=1 -pend=10 } result] {
            return -code error "APSMpParResetStreakCamera6(error open shutter): $result"
        }
        after 1000
        if [catch {exec cavget -list=POPC5680:1:ShutterStatusM -num -pend=10 -printErrors} shutter] {
            return -code error "APSMpParResetStreakCamera7(error check shutter status):$shutter"
        }
        
        if $shutter {
            set openCheck 1
        } else {
            set openCheck 0
        }
        incr count
        if {$count>10}  {
            break
        }
    }
    if {$count>10} {
        return -code error "Error in reset streak camera, please reboot the ioc!"
    }
    after 2000
    if [string length $statusCallback] {
        eval $statusCallback "shutterCheck okay, close shutter first"
    }
    if [catch {exec cavput -list=POPC5680:1:ShutterOpenC=0 -pend=10 } result] {
        return -code error "APSMpParResetStreakCamera8(error close shutter): $result"
    }
    after 1000
    
    ### toggle vertical sweep mode once
    eval $statusCallback "toggle vertical sweep mode once"
    if [catch {exec cavput -list=POPC5680:1:VertSweepC=0 -pend=10} result] {
        return -code error "APSMpParResetStreakCamera8(error toggel vertical sweep mode): $result"
    }
    after 2000
    if [catch {exec cavput -list=POPC5680:1:VertSweepC=1 -pend=10} result] {
        return -code error "APSMpParResetStreakCamera9(error toggel vertical sweep mode): $result"
    }
    ### vertical sweep mode 1 should be used. 
    after 2000
    if [catch {exec cavput -list=POPC5680:1:VertSweepC=1 -pend=10} result] {
        return -code error "APSMpParResetStreakCamera10(error toggel vertical sweep mode): $result"
    }
    after 2000
    ### 3---50ns
    if [catch {exec cavput -list=POPC5680:1:S:VSweepRngC=7 -pend=10} result] {
        return -code error "APSMpParResetStreakCamera11: $result"
    }
    after 1000
    if [catch {exec cavput -list=POPC5680:1:S:VSweepRngC=7 -pend=10} result] {
        return -code error "APSMpParResetStreakCamera12: $result"
    }
    #### set DG2 vertical delay to 0.25us
    if [string length $statusCallback] {
        eval $statusCallback "set DG2 vertical delay to 0.25us"
    }
    if [catch {exec cavput -list=Popt:DG2:aTimeAO.VAL=0.0 -pend=10} result] {
        return -code error "APSMpParResetStreakCamera13: $result"
    }
    after 2000
    if [catch {exec cavput -list=POPC5680:1:S:VSweepRngC=3 -pend=10} result] {
        return -code error "APSMpParResetStreakCamera14: $result"
    }
    after 2000
    if [catch {exec cavput -list=POPC5680:1:S:VSweepRngC=3  -pend=10} result] {
        return -code error "APSMpParResetStreakCamera15: $result"
    }
    after 2000
    if [catch {exec cavput -list=Popt:DG2:aTimeAO.VAL=0.025  -pend=10} result] {
        return -code error "APSMpParResetStreakCamera16: $result"
    }
    ### setting gate mode appears to stop the image
    if [string length $statusCallback] {
        eval $statusCallback "setting gate mode appears to stop the image"
    }
    if [catch {exec cavput -list=POPC5680:1:GateModeC=0 -pend=10} result] {
        return -code error "APSMpParResetStreakCamera17: $result"
    }
    after 2000
    ### H sweep off 
    if [catch {exec cavput -list=POPC5680:1:S:HSweepRngC=0  -pend=10} result] {
        return -code error "APSMpParResetStreakCamera18: $result"
    }
    after 2000 
    if [catch {exec cavput -list=POPC5680:1:S:HSweepRngC=0 -pend=10} result] {
        return -code error "APSMpParResetStreakCamera19: $result"
    }
    after 2000 
    ### H sweep 25 ms
    if [catch {exec cavput -list=POPC5680:1:S:HSweepRngC=12 -pend=10} result] {
        return -code error "APSMpParResetStreakCamera20: $result"
    }
    after 2000
    if [catch {exec cavput -list=POPC5680:1:S:HSweepRngC=12  -pend=10} result] {
        return -code error "APSMpParResetStreakCamera21: $result"
    }
    after 2000
    if [catch {exec cavput -list=POPC5680:1:HorzTrigModeC=1 -pend=10} result] {
        return -code error "APSMpParResetStreakCamera22: $result"
    }
    after 3000
    if [catch {exec cavput -list=POPC5680:1:HorzTrigModeC=0 -pend=10} result] {
        return -code error "APSMpParResetStreakCamera23: $result"
    }
    after 2000
    if [catch {exec cavput -list=POPC5680:1:HorzTrigModeC=0 -pend=10} result] {
        return -code error "APSMpParResetStreakCamera24: $result"
    }
    after 2000
    if [catch {exec cavput -list=POPC5680:1:MCPgainC=0  -pend=10} result] {
        return -code error "APSMpParResetStreakCamera25: $result"
    }
    after 2000
    if [catch {exec cavput -list=POPC5680:1:MCPgainC=0  -pend=10} result] {
        return -code error "APSMpParResetStreakCamera26: $result"
    }
    after 4000
    if [string length $statusCallback] {
        eval $statusCallback "Open shutter now"
    }
    if [catch {exec cavput -list=POPC5680:1:ShutterOpenC=1  -pend=10} result] {
        return -code error "APSMpParResetStreakCamera27: $result"
    }
    after 2000
    if [catch {exec cavput -list=POPC5680:1:ShutterOpenC=1 -pend=10} result] {
        return -code error "APSMpParResetStreakCamera28: $result"
    }
    after 2000
    if [string length $statusCallback] {
        eval $statusCallback "reset camera done"
    }
}

proc APSMpParBunchLengthMeasSetupWithStreakCameraInfo {args} {
    return "this is streak camera setup procedure for par bunch length measurement."
}

proc APSMpParBunchLengthMeasSetupWithStreakCameraInitDiag {frame} {
    global APSMpParBunchLengthMeasSetupWithStreakCamera

    set APSMpParBunchLengthMeasSetupWithStreakCamera(mode) 1Hz
    set APSMpParBunchLengthMeasSetupWithStreakCamera(ShortFilename) ""
    
    pack [frame $frame.f1]
    APSRadioButtonFrame .hz -parent $frame.f1 -label "1Hz or 2Hz?" -buttonList {1Hz 2Hz} \
      -valueList {1Hz 2Hz} -variable APSMpParBunchLengthMeasSetupWithStreakCamera(mode)
    
    APSAddSCRDialog .scr -parent $frame.f1 -system StreakCamera \
      -arrayName APSMpParBunchLengthMeasSetupWithStreakCamera \
      -defaultFile $APSMpParBunchLengthMeasSetupWithStreakCamera(ShortFilename) \
      -label "Choose streak camera SCR file by clicking on the Preferred/Reference Choices"
}

proc APSMpParBunchLengthMeasSetupWithStreakCamera {args} {
    set mode 1Hz
    set ShortFilename ""
    APSMpStep init -promptDialog APSMpParBunchLengthMeasSetupWithStreakCameraInitDiag \
      -vars {mode ShortFilename}

    if ![string length $ShortFilename] {
        APSMpReturn error "SCR file is not chosen."
    }
    APSMpStep "Switch par to $mode ..."
    switch $mode {
        1Hz {
            if [catch {APSMpSwitchLinacParTo1Hz } result] {
                APSMpReturn error "APSMpParBunchLengthMeasSetup1: error switch par to 1Hz mode: $result"
            }
        }
        2Hz {
             if [catch {APSMpSwitchLinacParTo2Hz } result] {
                APSMpReturn error "APSMpParBunchLengthMeasSetup2: error switch par to 2Hz mode: $result"
            }
        }
    }

    APSMpStep "Turn on camera..."
    if [catch {exec cavget -list=P:Opt:PwrBt5:AC1:pwrC -pend=10 -printErrors -num } cameraOn] {
        APSMpReturn error "Errror reading P:Opt:PwrBt5:AC1:pwrC: $cameraOn"
    }
    if {!$cameraOn} {
       
        APSMpStep "wait for the count to be zero before turning on the camera"
        set i 0
        while {$i<60} {
            if [catch {exec cavget -list=P:Opt:PwrBt5:AC1:CALC.VAL -printErrors -pend=20} count] {
                APSMpReturn error "Error reading P:Opt:PwrBt5:AC1:CALC.VAL: $result"
            }
            if {$count==0} {
                break
            }
            incr i
            after 1000
        }
        APSMpStep "Turn on camera..."
        
        if [catch {exec cavput -list=P:Opt:PwrBt5:AC1:OnSEQ.PROC=1 -pend=30 } result] {
            APSMpReturn error "Error turning on streak camera: $result"
        }
    }
    
    APSMpStep "Setup camera..."
    APSMpStep "Reset streak camera..."
    if [catch {APSMpParResetStreakCamera -statusCallback APSMpStep } result] {
        APSMpReturn error "APSMpParBunchLengthMeasSetup3: error in reset camera: $result"
    }
    
    APSMpStep "restore SCR..."
    if [catch {exec sddsprocess /home/helios/oagData/SCR/snapshots/StreakCamera/$ShortFilename -pipe=out -match=col,IsReadOnly=n \
                 | sddscasr -pipe=in -restore } result] {
        APSMpReturn error "APSMpParBunchLengthMeasSetup4: error restore SCR: $result"
    }
    
    APSMpStep "Check streak camera status..."
    
    if [catch {exec cavget -list=Popt:DG1:errorStatusLI.SEVR,Popt:DG2:errorStatusLI.SEVR -pend=30 -num -printErrors } valList] {
        APSMpReturn error "Error reading streak camera status: $valList"
    }
    set val1 [lindex $valList 0]
    set val2 [lindex $valList 1]
    if {$val1 || $val2} {
        APSMpStep "Streak camera has errors, turn off the camera."
        if [catch {exec cavput -list=P:Opt:PwrBt5:AC1:OnSEQ.PROC=0 -pend=20 } result] {
            APSMpReturn error "Error turn off streak camera: $result"
        }
        APSMpReturn error "Streak camera setup failed, please reboot ioc and reset camera again."
    }
    
    APSMpStep "done."
    APSMpReturn ok
}
proc APSMpTurnOffStreakCameraInfo {args} {
    return "Turn off streak camera."

}

proc APSMpTurnOffStreakCamera {args} {
    APSMpStep "Close the shutter"
    if [catch {exec cavput -list=POPC5680:1:ShutterOpenC=0 -pend=20} result] {
        APSMpReturn error "Error close the shutter: $result"
    }
    APSMpStep "Turn off the motor power"
    if [catch {exec cavput -list=P:Opt:PwrBt5:AC1:OffSEQ.PROC=0 -pend=20} result] {
        APSMpReturn error "Error turn off the motor power: $result"
    }

    APSMpStep "done"
    APSMpReturn ok
}

proc APSMpPARBunchLengthMeasSetupWithDiodeAndScopeInfo {args} {
    return "this is diode and scope setup procedure for par bunch length measurement."
}

proc APSMpPARBunchLengthMeasSetupWithDiodeAndScope {args} {

    set scopeID 164.54.3.155
    APSMpStep "Setup scope $scopeID"
    if [catch {exec hpSocketSend $scopeID ":TRIG:MODE EDGE" -pause=0.5 \
                 ":TRIG:EDGE:SOUR CHAN4" -pause=0.5 \
                 ":CHAN2:DISPLAY ON" -pause=0.5 \
                 ":ACQ:POIN 65536" -pause=0.5 \
                 ":ACQ:SRAT 2e10" -pause=0.5 \
                 ":CHAN2:OFFSET 0" -pause=0.5 \
                 ":CHAN2:SCALE 2.5e-2" -pause=0.5 \
                 ":CHAN4:DISPLAY OFF" -pause=0.5 \
                 ":CHAN4:RANG 8" -pause=0.5 \
                 ":TRIG:LEV CHAN4,1" -pause=0.5 \
                 ":TIM:SCAL 5e-8" -pause=0.5 \
                 ":TIM:DEL 0" -pause=0.5 \
                 ":ACQ:INT OFF" -pause=0.5 \
             } result] {
        APSMpReturn error "Error setup scope ($scopeID): $result"
    }
    APSMpStep "setup streak camera DG1 dtime to 0.4s"
    if [catch {exec cavput -list=Popt:DG1:dTimeAO.VAL=0.4 -pend=20} result] {
        APSMpReturn error "Error change streak camera DG1 dtime to 0.4 seconds!"
    }
    APSMpStep "done."
    APSMpReturn ok
                 
}


proc APSMpPARHighChargeSetupInfo {args} {
    return "par high charge lattice setup."
}

proc APSParUpdateHighChargeMode {args} {
    global APSMpPARHighChargeSetup
    switch $APSMpPARHighChargeSetup(mode) {
        1Hz {
            set APSMpPARHighChargeSetup(FFmode) highQ
        }
        2Hz {
            set APSMpPARHighChargeSetup(FFmode) oper
        }
    }

}

proc APSMpPARHighChargeSetupInitDialog {frame} {
    global APSMpPARHighChargeSetup

    set APSMpPARHighChargeSetup(mode) 1Hz
    set APSMpPARHighChargeSetup(ShortFilename) ""
    set APSMpPARHighChargeSetup(FFmode) highQ
    pack [frame $frame.f1]
   
    APSAddSCRDialog .scr -parent $frame.f1 -system PAR  \
      -arrayName  APSMpPARHighChargeSetup \
      -defaultFile $APSMpPARHighChargeSetup(ShortFilename) \
      -label "Choose PAR SCR file by clicking on the Preferred/Reference Choices"
    
    set categoryList [exec sddsconvert /home/helios/oagData/SCR/requestFiles/PAR.req -retain=col,Category -pipe=out \
                    | sddssort -pipe -col=Category -unique | sdds2stream -pipe=in -col=Category]
    set APSMpPARHighChargeSetup(CategoryList) $categoryList
    set varList ""
    foreach item $categoryList {
        set APSMpPARHighChargeSetup($item) 0
        lappend varList APSMpPARHighChargeSetup($item)
    }
    set APSMpPARHighChargeSetup(SteeringPS) 1
    set APSMpPARHighChargeSetup(SteeringSetpoint) 1
    set APSMpPARHighChargeSetup(StreakCamera) 1
    set APSMpPARHighChargeSetup(Timing) 1
    set APSMpPARHighChargeSetup(BunchCleaning) 1
    set APSMpPARHighChargeSetup(HarmonicRF) 1
    APSCheckButtonFrame .category -parent $frame.f1 \
      -label "Select SCR categories\nto restore" \
      -variableList $varList \
      -buttonList $categoryList \
      -limitPerRow 7 -orientation horizontal -allNone 1
    set APSMpPARHighChargeSetup(beamlines) {LTP Linac PAR PTB}
    set APSMpPARHighChargeSetup(LTP) 0
    set APSMpPARHighChargeSetup(Linac) 0
    set APSMpPARHighChargeSetup(PAR) 1
    set APSMpPARHighChargeSetup(PTB) 0
    APSCheckButtonFrame .beamlines -parent $frame.f1 -label "Select SCR beamline  \nto restore " \
      -variableList {APSMpPARHighChargeSetup(LTP)    \
                       APSMpPARHighChargeSetup(Linac) \
                       APSMpPARHighChargeSetup(PAR) \
                       APSMpPARHighChargeSetup(PTB) \
                   } \
      -buttonList {LTP Linac PAR PTB} \
      -limitPerRow 7 -orientation horizontal -allNone 1

    APSRadioButtonFrame .hz -parent $frame.f1 -label "1Hz or 2Hz mode?     " -buttonList {1Hz 2Hz} -orientation horizontal  \
      -valueList {1Hz 2Hz} -variable  APSMpPARHighChargeSetup(mode) -commandList {APSParUpdateHighChargeMode APSParUpdateHighChargeMode}

    APSRadioButtonFrame .ff -parent $frame.f1 -label "PAR Feedforward mode:" -buttonList {operation highCharge} \
      -valueList {oper highQ} -variable APSMpPARHighChargeSetup(FFmode) -orientation horizontal
  #  set APSMpPARHighChargeSetup(useLPL) 0
    APSMpReturn ok
}

proc APSMpPARHighChargeSetup {args} {
    set ShortFilename ""
    set mode 1Hz
    set highCharge 1
    set useLPL 0
    set Timing 1
    global  APSMpPARHighChargeSetup
    APSStrictParseArguments {ShortFilename mode highCharge useLPL Timing}
    APSMpStep init -promptDialog APSMpPARHighChargeSetupInitDialog \
      -vars {ShortFilename mode Timing}
    
    if !$useLPL {
	set system PAR
    } else {
	set system LPL
    }
    set APSMpPARHighChargeSetup(Timing) $Timing
    
    APSMpStep "use $system SCR"
    set modeInSCR [exec sddsprocess /home/helios/oagData/SCR/snapshots/$system/$APSMpPARHighChargeSetup(ShortFilename) \
			   -pipe=out -match=col,ControlName=It:L:1HzNot2Hz_bo | sdds2stream -pipe=in -col=ValueString] 
    
    if [regexp "1 Hz" $modeInSCR] {
        set mode0 1Hz
    } elseif [regexp "2 Hz" $modeInSCR] {
        set mode0 2Hz
    } else {
        set mode0 unknown
    }
    if {$mode!=$mode0} {
        APSMpReturn error "Error: the selected mode $mode is different from SCR."
    }
    
    if $highCharge {
	set msg "SCR save before setup high charge"
    } else {
	set msg "SCR save before switch to $mode"
    }
    APSMpStep "$msg"
    if [catch {APSSaveMachine -machine $system -description "$system $msg" } result] {
	APSMpReturn error "Error saving $system SCR: $result"
    }
    
    APSMpStep "SCR mode = $mode0, requested mode = $mode"
    
    set opt ""
    foreach item $APSMpPARHighChargeSetup(CategoryList) {
        if [set APSMpPARHighChargeSetup($item)] {
            if {$item=="HarmonicRF"} {
                if ![string length $opt] {
                    set opt -match=col,ControlName=*WT*,ControlName=PAR:Harm:RfPwrDelay,|
                } else {
                    append opt ,ControlName=*WT*,|,ControlName=PAR:Harm:RfPwrDelay,|
                }
            } else {
                if ![string length $opt] {
                    set opt -match=col,Category=$item
                } else {
                    append opt ,Category=$item,|
                }
            }
        }
    }
    set opt1 ""
    foreach item $APSMpPARHighChargeSetup(beamlines) {
        if [set APSMpPARHighChargeSetup($item)] {
            if ![string length $opt1] {
                set opt1 -match=col,Beamline=$item
            } else {
                append opt1 ,Beamline=$item,|
            }
        }
    }
    APSMpStep "Switch to $mode mode..."
    switch $mode {
        1Hz {
            if [catch {APSMpSwitchLinacParTo1Hz } result] {
                APSMpReturn error "APSMpPARHighChargeSetup2: error switching to 1Hz mode: $result"
            }
        }
        2Hz {
            if [catch {APSMpSwitchLinacParTo2Hz } result] {
                APSMpReturn error "APSMpPARHighChargeSetup3: error switching to 2Hz mode: $result"
            }
        }
    }
    APSMpStep "Restore $system SCR ..."
    APSMpStep "$opt $opt1"
    if [catch {eval exec sddsprocess /home/helios/oagData/SCR/snapshots/$system/$APSMpPARHighChargeSetup(ShortFilename) -pipe=out \
                 $opt $opt1  "-match=col,ControlName=It:ListTrig2ParIpAO,!" \
                 -match=col,IsReadOnly=n,ControlName=PAR:Harm:RfPwrDelay,|  \
                 | sddscasr -pipe=in -restore -pend=30 } result] {
        APSMpReturn error "APSMpPARHighChargeSetup1: error restore $system SCR: $result"
    }
    #if [catch {exec sddscasr -restore $tmpFile} result] {
    #	 APSMpReturn error "APSMpPARHighChargeSetup1a: error restore $system SCR (2nd time): $result"
    # }
    if [catch {exec sddsprocess /home/helios/oagData/SCR/snapshots/$system/$APSMpPARHighChargeSetup(ShortFilename) -pipe=out \
		   -match=col,ControlName=It:ListTrig2ParIpAO \
		   | sdds2stream -pipe=in -col=ValueString } value] {
	APSMpReturn -code error "Error obtaing value for It:ListTrig2ParIpAO in SCR: $value"
    }
    APSMpStep "Restore It:ListTrig2ParIpAO to $value ..."
    if [catch {exec cavput -list=It:ListTrig2ParIpAO=$value -pend=30} result] {
	APSMpReturn error "Error set It:ListTrig2ParIpAO to $value: $result"
    }
   # APSAddToTmpFileList -ID highcharge -fileList $tmpFile
    APSMpStep "Relink par FF table to $APSMpPARHighChargeSetup(FFmode) ..."
    set oldDir [pwd]
    cd /home/helios/oagData/par/feedforwardConfig/parTunerFeedforward
    eval file delete -force parRFFeedForwardTube1Tube1.sdds parRFFeedForwardTube2Tube1.sdds \
	parRFFeedForwardTube1Tube2.sdds  parRFFeedForwardTube2Tube2.sdds 
    switch $mode {
	1Hz {
	    exec ln -s oper1HzHarm1/parRFFeedForwardTube1Tube1.sdds parRFFeedForwardTube1Tube1.sdds
	    exec ln -s oper1HzHarm1/parRFFeedForwardTube2Tube1.sdds parRFFeedForwardTube2Tube1.sdds
	    exec ln -s oper1HzHarm2/parRFFeedForwardTube1Tube2.sdds parRFFeedForwardTube1Tube2.sdds 
	    exec ln -s oper1HzHarm2/parRFFeedForwardTube2Tube2.sdds parRFFeedForwardTube2Tube2.sdds
	}
	2Hz {
	    exec ln -s operTube1Tube1/parRFFeedForwardTube1Tube1.sdds parRFFeedForwardTube1Tube1.sdds
	    exec ln -s operTube2Tube1/parRFFeedForwardTube2Tube1.sdds parRFFeedForwardTube2Tube1.sdds
	    exec ln -s operTube1Tube2/parRFFeedForwardTube1Tube2.sdds parRFFeedForwardTube1Tube2.sdds
	    exec ln -s operTube2Tube2/parRFFeedForwardTube2Tube2.sdds parRFFeedForwardTube2Tube2.sdds
	}
    }
    if $highCharge {
	APSMpStep "Relink par FF table to $APSMpPARHighChargeSetup(FFmode) ..."
	if [catch {exec cavget -list=PAR:Fnd:SystemSelect -pend=20 -noquote -printErrors} tube1] {
	    APSMpReturn error "APSMpPARHighChargeSetup4: error reading PAR:Fnd:SystemSelect: $tube1"
	}
	set tube1 [regsub "SYSTEM \#" $tube1 ""]
	
	if [catch {exec cavget -list=PAR:Har:SystemSelect -pend=20 -noquote -printErrors} tube2] {
	    APSMpReturn error "APSMpPARHighChargeSetup5: error reading PAR:Har:SystemSelect: $tube2"
	    
	}
	set tube2 [regsub "SYSTEM \#" $tube2 ""]
	set oldDir [pwd]
	cd /home/helios/oagData/par/feedforwardConfig/parTunerFeedforward
	set ffFile parRFFeedForwardTube${tube1}Tube${tube2}.sdds
	exec rm $ffFile
	exec ln -s $APSMpPARHighChargeSetup(FFmode)Tube${tube1}Tube${tube2}/$ffFile $ffFile
	cd $oldDir
	APSMpStep "create wavetek waveform and load it..."
	if [catch {exec cavput -list=PRF:Har:WT2:StoreWF_BI.PROC=1,PRF:Har:WT1:StoreWF_BI.PROC=1 -pend=20} result] {
	    APSReturn error "Error creating wavetek waveforms: $result"
	}
	after 2000
	if [catch {exec cavput -list=PRF:Har:WT2:LoadTraceBO.PROC=1,PRF:Har:WT1:LoadTraceBO.PROC=1 -pend=20} result] {
	    APSReturn error "Error loading wavetek waveforms: $result"
	}
	APSInfoWindow .info1 -name "Wavetek waveform loaded" -modal 1 -width 40 \
	    -infoMessage "Wavetek waveform loaded!" 
    }
    APSInfoWindow .info -name "Restart PAR Harmonic FF" -modal 1 -width 40 \
	-infoMessage "FF table changed, please restart PAR RF12 Harmonic feedforward" 

    if {$APSMpPARHighChargeSetup(FFmode)=="oper"} {
	#enable par bunch clearning
	APSMpStep "enable bunch cleaning"
	if [catch {APSMpPARStartBunchCleaning } result] {
            APSMpReturn error "Error disabling bunch cleaning: $result"
        }
	
    } elseif {$mode=="1Hz" && $highCharge} {
        APSMpStep "Disable bunch cleaning"
        if [catch {APSMpPARStopBunchCleaning } result] {
            APSMpReturn error "Error disabling bunch cleaning: $result"
        }
    }
    if {$APSMpPARHighChargeSetup(FFmode)=="oper"} {
        #minutes
        set timeout 20
    } else {
        set timeout 60
    }
    if [catch {exec cavput -list=L1:RFG:KIK,It:Par:PSP,It:Par:IK,It:Par:EK,It:Bs:IS,It:Bs:IK,Mt:Bs:ES1,Mt:Bs:ES2,Mt:Bs:EK -list=chargeLimitAO=$timeout -pend=30} result] {
        APSMpReturn error "Error setting charge limit pvs to $timeout minutes: $result"
    }
    if $highCharge {
	APSMpStep "SCR save after setup high charge."	
	if [catch {APSSaveMachine -machine $system -description "$system SCR save after setup high charge." } result] {
	    APSMpReturn error "Error saving $system SCR: $result"
	}
    } else {
	APSMpStep "SCR save after switch to $mode."
	if [catch {APSSaveMachine -machine $system -description "$system SCR save after switch to $mode." } result] {
	    APSMpReturn error "Error saving $system SCR: $result"
	}
    }
    
    APSMpReturn ok
    
}
