#
# $Log: not supported by cvs2svn $
# Revision 1.43  2009/02/17 21:32:00  soliday
# Added the ability to condition LTP:B1 more then the default number of cycles.
#
# Revision 1.42  2008/03/06 18:03:40  soliday
# Updated by removing some old devSend commands.
#
# Revision 1.41  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.40  2007/12/07 17:09:36  soliday
# Added code to better handle MPEOB faults.
#
# Revision 1.39  2007/11/02 16:01:08  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.38  2007/03/01 17:41:30  soliday
# Changed conditioning time back to 10 minutes.
#
# Revision 1.37  2007/03/01 16:54:31  soliday
# Improved the call to APSLogScriptAction for APSMpLTPStandardize.
#
# Revision 1.36  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.35  2006/05/23 14:24:58  soliday
# Added acis checks.
#
# Revision 1.34  2006/04/20 16:06:50  soliday
# Updated APsMpPARLETStartUp so that it now uses the APSMpPARLETCondition routine.
#
# Revision 1.33  2005/09/27 14:23:56  shang
# added prompt dialog box to those pems that do not have
#
# Revision 1.32  2005/05/27 18:45:04  soliday
# Added slightly more informative message when the LTP aperture is not clear.
#
# Revision 1.31  2005/04/07 16:20:03  soliday
# Updated to identify limited save files and not allow the operator to use them.
#
# Revision 1.30  2003/10/28 15:50:01  soliday
# These PAR procedures now alert the user if no SCR file has been chosen.
#
# Revision 1.29  2003/10/27 20:13:54  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.28  2003/10/14 16:27:06  soliday
# Added APSMpStep statements at the end of procedures that may be run in parallel.
#
# Revision 1.27  2003/09/24 15:05:38  soliday
# Added catch statement around APSLogScriptAction in case the logDaemon is down.
#
# Revision 1.26  2003/05/19 14:45:53  soliday
# Increased the pend time when checking for the end of conditioning.
#
# Revision 1.25  2003/03/06 21:11:42  soliday
# Modified conditioning routines so that they default to blocking mode.
#
# Revision 1.24  2002/10/02 14:45:35  soliday
# Fixed DCPS when it should not start.
#
# Revision 1.23  2002/04/03 21:03:30  soliday
# LTP:B1 needed to be reset and turned on.
#
# Revision 1.22  2002/04/02 18:59:01  borland
# No longer disable DC mode after standardizing.
#
# Revision 1.21  2002/04/02 16:12:31  soliday
# Added LTP:B1 DC mode switch.
#
# Revision 1.20  2001/02/22 20:55:19  borland
# Switched to LPL system from PLET.
#
# Revision 1.19  2000/12/05 00:37:12  borland
# Added APSLogScriptAction calls.
#
# Revision 1.18  2000/06/26 17:33:55  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.17  2000/05/02 14:55:27  borland
# Added more detailed steps descriptions.
#
# Revision 1.16  2000/04/26 16:39:46  soliday
# Added APSMpStep proc options.
#
# Revision 1.15  1999/11/08 20:07:00  borland
# Added controls for excluding LTP:B1 from standardization for LTP and
# PAR/LET startup.
#
# Revision 1.14  1999/07/28 00:43:16  borland
# Replaced 325MeVReference with 325MeVPreferredRFGun.
#
# Revision 1.13  1999/07/27 15:21:02  borland
# Default energy is now 325 MeV and default snapshot is PLET-325MeVPreferredRFGun.gz,
# per G. Banks request.
#
# Revision 1.12  1998/10/01 20:35:08  borland
# Should work now for positrons/electrons.
#
# Revision 1.11  1998/07/27 19:49:55  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.10  1998/01/09 19:06:32  borland
# Changed name of PLET refernce file from PLET-Reference to PLET-400MeVReference
#
# Revision 1.9  1998/01/03 01:14:36  borland
# Improved robustness of DCPS turn on procedures.
#
# Revision 1.8  1997/11/21 01:57:35  borland
# Now accepts statusCALC of 2 or 3 as indicating that a supply is off.
# Necessary to make the script work after controls changed the statusCALC
# codes.
#
# Revision 1.7  1997/04/18 00:37:53  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:01  borland
# Added check of MPEOB buttons prior to attempting DCPS turn on.
#
# Revision 1.5  1996/10/09 22:46:43  borland
# Reduced default conditioning times to 5 minutes.
#
# Revision 1.4  1996/10/08 21:44:10  borland
# Reduced default standardization time to 10 minutes.
#
# Revision 1.3  1996/08/09 19:44:37  borland
# Allows individual magnet standardization.
#
# Revision 1.2  1996/07/27 15:29:04  borland
# Now has default restoreFile of PLET-400MeVReference.gz
#
# Revision 1.1  1996/07/26 22:14:10  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 APSMpLTPStartUpInfo {} {
    return "This is a stand-alone procedure which turns on the LTP magnets, standardizes them, waits for the standardization to finish, and restores an LTP configuration."
}

proc APSMpLTPStartUp {args} {
    global PLETSnapshotDir

    set energy [APSPARLETDefaultEnergy]
    set conditioningTime 10
    set restoreFile ""
    set particle electron
    set standardizeB1 1
    set DCPS 1
    set restoreDCPS 1
    set maxLTPB1Cycles 4
    APSStrictParseArguments {energy conditioningTime restoreFile particle standardizeB1 DCPS restoreDCPS maxLTPB1Cycles}
    
    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 "APSMpLTPStartUp: $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 "APSMpLTPStartUp: 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 "APSMpLTPStartUp: Linac/PAR is in an acis trip state."
            }
        }
    }
    if {[catch {APSLinkToLINACPVs} result]} {
	APSMpReturn error "APSMpLTPStartUp: $result"
    }

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

    set paramString ""
    foreach param {energy restoreFile conditioningTime particle standardizeB1 ShortFilename maxLTPB1Cycles} {
        append paramString "$param=\"[set $param]\" "
    }
    catch {APSLogScriptAction -procedure APSMpLTPStartUp -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 "APSMpLTPStartUp: 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 "APSMpLTPStartUp: Problem reading beamlines categories from the SCR file"
            } else {
                if {([lsearch -exact $results LTP] == -1) || ([lsearch -exact $results LTP1] == -1) || ([lsearch -exact $results LTP2] == -1)} {
                    APSMpReturn error "APSMpLTPStartUp: LIMITED SAVE SCR file does not include all the LTP beamline categories"
                }
            }
        }
    }

    if {$DCPS} {
        APSMpStep "LTP: Turn On DCPS" -proc APSMpLTPTurnOnDCPS 
        if [catch APSMpLTPTurnOnDCPS result] {
            if {[APSPEMTKDialog .warningDialog -text "Unable turn on LTP DCPS.\nAPSMpLTPStartUp: $result"] == 1} {
                APSMpReturn error "Unable turn on LTP DCPS: APSMpLTPStartUp: $result"
            }
        }
        
        if {$standardizeB1} {
            if {[catch {exec cavget -list=L5:AM1:PS2:overTempBI -num} result]} {
                APSMpReturn error "Unable to read L5:AM1:PS2:overTempBI: $result"
            }
            if {$result == 0} {
                if {[catch {exec cavput -list=L5:AM1:PS2:resetBO=1} result]} {
                    APSMpReturn error "Unable to reset over temp fault for L5:AM1: $result"
                }
                APSWaitWithUpdate -waitSeconds 2
            }
            if [catch {APSDevSend -group LinacPS -operation QueryOff -deviceList "L3:AM1"} result] {
                APSMpReturn error "APSMpLTPStartUp: $result"
            }
            if {$result} {
                #This is really a reset. It will set the current to 0.
                if {[catch {APSDevSend \
                              -group LinacPS \
                              -operation TurnOn \
                              -deviceList "L3:AM1 L5:AM1"} result]} {
                    if {[APSPEMTKDialog .warningDialog -text "Unable turn on L3:AM1 and/or L5:AM1.\nAPSMpLTPStartUp: $result"] == 1} {
                        APSMpReturn error "Unable turn on L3:AM1 and/or L5:AM1: APSMpLTPStartUp: $result"
                    }
                }
                APSWaitWithUpdate -waitSeconds 15
            }
	    if [catch {APSDevSend \
                         -releaseLinks 1 \
                         -group LinacPS \
                         -operation SetCurrent \
                         -deviceList L3:AM1 \
                         -valueList 63 \
                         -timeout 0} result] {
		APSMpReturn error "APSMpLTPStartUp: $result"
	    }
            APSWaitWithUpdate -waitSeconds 15
            set try 10
            while {$try >= 0} {
                incr try -1
                if {[catch {exec cavget -list=L3:AM1:readyCC,L3:AM1:CurrentAI} result]} {
                    APSMpReturn error "Unable to read current for L3:AM1: APSMpLTPStartUp: $result"
                }
                if {([lindex $result 0] == 1) && ([lindex $result 1] > 60)} {
                    break
                }
                APSWaitWithUpdate -waitSeconds 5
            }
            if {$try == -1} {
                if {([lindex $result 0] != 1) || ([lindex $result 1] <= 60)} {
                    if {[APSPEMTKDialog .warningDialog -text "Unable to set L3:AM1 to 63amps. Please fix manually and then click Continue."] == 1} {
                        APSMpReturn error "Unable to set L3:AM1 to 63amps. Aborted by operator"
                    }
                }
            }
        }
        APSMpStep "LTP: Initialize Standardizing" -proc APSMpLTPStandardize 
        if [catch {APSMpLTPStandardize -particle $particle -maxCycles $maxLTPB1Cycles\
                       -energy $energy -conditioningTime $conditioningTime \
                       -B1 $standardizeB1 -restoreFile $restoreFile -block 0} result] {
            APSMpReturn error "Error initiating LTP standardization: $result"
        }
        
        APSMpStep "LTP: Initialize Degaussing" -proc APSMpLTPDegauss 
        if [catch {APSMpLTPDegauss -degaussTime $conditioningTime -block 0} result] {
            APSMpReturn error "Error initiating LTP degaussing: $result"
        }
        
        APSMpStep "LTP: Wait For Conditioning" -proc APSMpLTPWaitForConditioning 
        if [catch {APSMpLTPWaitForConditioning} result] {
            APSMpReturn error "Error waiting for LTP conditioning: $result"
        }
        if {$standardizeB1} {
	    if [catch {APSDevSend \
                         -releaseLinks 1 \
                         -group LinacPS \
                         -operation SetCurrent \
                         -deviceList L3:AM1 \
                         -valueList 0 \
                         -timeout 0} result] {
		APSMpReturn error "APSMpLTPStartUp: $result"
	    }
            set try 30
            while {$try >= 0} {
                APSWaitWithUpdate -waitSeconds 1
                if {[catch {exec cavget -list=L3:AM1:CurrentAI} result]} {
                    APSMpReturn error "Unable to read current for L3:AM1: APSMpLTPStartUp: $result"
                }
                if {$result <= 3} {
                    break
                }
                incr try -1
            }
            if {[catch {APSDevSend \
                          -group LinacPS \
                          -operation TurnOff \
                          -deviceList L3:AM1} result]} {
                if {[APSPEMTKDialog .warningDialog -text "Unable turn off L3:AM1.\nAPSMpLTPStartUp: $result"] == 1} {
                    APSMpReturn error "Unable turn off L3:AM1: APSMpLTPStartUp: $result"
                }
            }
        }
    }
    if [string length $restoreFile] {
        APSMpStep "LTP: Restore SCR File" -proc APSMpLTPRestoreFile 
        if [catch {APSMpLTPRestoreFile -restoreDCPS $restoreDCPS -restoreFile $restoreFile} result] {
            APSMpReturn error "Error restoring configuration from $restoreFile for LTP: $result"
        }

    }
    
    APSMpStep "PAR/LET: Clear Beam Aperture (of flags/valves)" -proc APSMpLTPClearAperture 
    if [catch {APSMpPARLETClearAperture -beamline LTP} result] {
        APSMpReturn error "Unable to clear LTP aperture. $result"
    }
    APSMpStep "LTP StartUp Finished"
    APSMpReturn ok
}
 
proc APSMpLTPStartUpInitDialog {frame} {
    global status PLETSnapshotDir controlFilesDir
    global APSMpLTPStartUp

    APSLabeledEntry .le1 -parent $frame -label "Energy (MeV): " \
      -textVariable APSMpLTPStartUp(energy) \
      -contextHelp "Enter the energy of the beam you will be using in MeV."
      
    APSRadioButtonFrame .rb1 -parent $frame -label "Particle: " \
      -variable APSMpLTPStartUp(particle) -buttonList "Positron Electron" \
      -valueList "positron electron" -orientation horizontal \
      -contextHelp "Select the type of particle you are running from the LINAC."

    APSLabeledEntry .le2 -parent $frame -label "Minutes for conditioning: " \
      -textVariable APSMpLTPStartUp(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."

    APSRadioButtonFrame .rb2 -parent $frame -label "Standardize LTP:B1: " \
      -variable APSMpLTPStartUp(standardizeB1) -buttonList {Yes No} -valueList {1 0} \
      -orientation horizontal -contextHelp \
      "Select whether to include LTP:B1 in the standardiation or not."

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

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

proc APSMpLTPTurnOnDCPS {args} {
    global status
    set retries 12
    APSStrictParseArguments {retries}
    APSMpStep init -promptDialog "APSMpPromptInitDialog"
    catch {APSLogScriptAction -procedure APSMpLTPTurnOnDCPS -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 "APSMpLTPTurnOnDCPS: Error checking MPEOB: $mpeob"] == 1} {
                APSMpReturn error "APSMpLTPTurnOnDCPS: Error checking MPEOB: $mpeob"
            }
            continue
        }
        if {!$mpeob} {
            if {[APSPEMTKDialog .warningDialog -text "APSMpLTPTurnOnDCPS: Both MPEOBs must be pulled out to start DCPS."] == 1} {
                APSMpReturn error "APSMpLTPTurnOnDCPS: Both MPEOBs must be pulled out to start DCPS."
            }
            continue
        }
        break
    }

    while {$retries} {
        set statusList [exec cavget -list=LTP:Q -range=beg=1,end=10 -list=:StatusCALC -label]
        set statusList [concat $statusList \
                          [exec cavget -list=LTP:B -list=1 -list=:StatusCALC -label]]
	set B1 [exec cavget -list=LTP:B1:StatusCALC -num]
        set statusList \
          [concat $statusList \
             [exec cavget -list=LTP: -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=LTP:B1: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 LTP 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 LTP DC power supplies may need manual turn on.  Look at these supplies: $probList"
    }
    APSMpReturn ok
}

proc APSMpLTPStandardizeInfo {} {
    return "This is a procedure which initiates standardization of LTP.  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 APSMpLTPStandardize {args} {
    global status PLETSnapshotDir controlFilesDir

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

    set ShortFilename $restoreFile
    set Description ""
    APSMpStep init -promptDialog APSMpLTPStandardizeInitDialog \
      -vars [concat [list particle 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 {particle energy conditioningTime block restoreFile maxCycles Q1 Q2 Q3 Q4 Q5 Q6 Q7 Q8 Q9 Q10 B1} {
        append paramString "$param=\"[set $param]\" "
    }
    catch {APSLogScriptAction -procedure APSMpLTPStandardize \
               -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 extra ""
    if [string compare $particle electron]==0 {
        set extra e
    }
    set file ${controlFilesDir}/LTP/LTP${extra}${energy}MeV.std
    if ![file exists $file] {
        APSMpReturn error "LTP $particle standardization file for $energy MeV not found"
    }

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

    APSMpStep "LTP: Configure Standardization"
    if [string length $restoreFile] {
        set tmpfile2 /tmp/[APSTmpString]
        set tmpfile3 /tmp/[APSTmpString]
        if [catch {exec sddsprocess $PLETSnapshotDir/$restoreFile $tmpfile2 \
                     -match=column,ControlName=LTP:B*,ControlName=LTP: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 rename -force $tmpfile3 $tmpfile
            file delete -force $tmpfile2} result] {
            eval file delete -force $tmpfile $tmpfile2 $tmpfile3
            APSMpReturn error "Error setting up standardization of LTP: $result"
        }
    }
    if  [catch {exec standardize -configure $tmpfile} result] {
        APSMpReturn error "Error initiating standardization: $result"
    }
    
    if {$B1} {
	if {[catch {exec cavput -list=LTP:B1:modeSetC=0} result]} {
	    APSMpReturn error "Error setting LTP:B1 to DC Mode: $result"
	}
    }

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

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

proc APSMpLTPStandardizeInitDialog {frame} {
    global status PLETSnapshotDir controlFilesDir
    global APSMpLTPStandardize

    APSLabeledEntry .le1 -parent $frame -label "Energy (MeV): " \
      -textVariable APSMpLTPStandardize(energy) \
      -contextHelp "Enter the energy of the beam you will be using in MeV."
      
    APSRadioButtonFrame .rb1 -parent $frame -label "Particle: " \
      -variable APSMpLTPStandardize(particle) -buttonList "Positron Electron" \
      -valueList "positron electron" -orientation horizontal \
      -contextHelp "Select the type of particle you are running from the LINAC."

    APSLabeledEntry .le2 -parent $frame -label "Minutes for conditioning: " \
      -textVariable APSMpLTPStandardize(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 B1} \
      -allNone 1 \
      -variableList \
      {APSMpLTPStandardize(Q1) APSMpLTPStandardize(Q2) APSMpLTPStandardize(Q3) \
         APSMpLTPStandardize(Q4) APSMpLTPStandardize(Q5) APSMpLTPStandardize(Q6) \
         APSMpLTPStandardize(Q7) APSMpLTPStandardize(Q8) APSMpLTPStandardize(Q9) \
         APSMpLTPStandardize(Q10) APSMpLTPStandardize(B1)} \
      -contextHelp "Choose which magnets you want to standardize.  If none are chosen, no action is taken."

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

proc APSMpLTPDegaussInfo {} {
    return "This is a procedure which initiates degaussing of LTP magnets."
}

proc APSMpLTPDegauss {args} {
    global status PLETSnapshotDir controlFilesDir

    set degaussTime 10
    set block 1
    APSStrictParseArguments {degaussTime block}

    APSMpStep init -promptDialog APSMpLTPDegaussInitDialog \
      -vars {degaussTime}

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

    set file ${controlFilesDir}/LTP/LTP_degauss.sdds
    set deleteFile 0
    if $degaussTime {
        APSMpStep "LTP: 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 "LTP: 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 "LTP: Initiate Degaussing"
    set status "Degaussing initiated."
    if $block {
        APSMpStep "LTP: Wait For Degaussing (optional)"
        set status "Waiting for degaussing to complete."
        if [catch {APSMpLTPWaitForConditioning -degauss 1} result] {
            APSMpReturn error "Error waiting for LTP degaussing: $result"
        }
        set status "Degaussing completed."
    }
    APSMpStep "LTP Degauss Finished"
    APSMpReturn ok
}

proc APSMpLTPDegaussInitDialog {frame} {
    global status PLETSnapshotDir controlFilesDir
    global APSMpLTPDegauss

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

}

proc APSMpLTPCheckConditioning {args} {
    global status PLETSnapshotDir controlFilesDir

    set degauss 1
    set standardize 1
    APSStrictParseArguments {degauss standardize}

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

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

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

    APSMpReturn ok
}

proc APSMpLTPWaitForConditioning {args} {
    global status PLETSnapshotDir controlFilesDir

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

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

proc APSMpLTPRestoreFile {args} {
    global status PLETSnapshotDir controlFilesDir

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

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

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

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

proc APSMpLTPStopConditioningInfo {} {
    return "This procedure stops the LTP magnet conditioning."
}

proc APSMpLTPStopConditioning {} {
    global status PLETSnapshotDir controlFilesDir
    APSMpStep init -promptDialog "APSMpPromptInitDialog"
    catch {APSLogScriptAction -procedure APSMpLTPStopConditioning \
               -action start -state ok -parameters none}

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

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


proc APSMpLTPClearAperture {} {
    APSMpStep init -promptDialog "APSMpPromptInitDialog"
    if [catch {APSMpPARLETClearAperture  -beamline LTP} result] {
        APSMpReturn error "Unable to clear LTP aperture. $result"
    }
    APSMpReturn ok
}
