#!/bin/sh  
# \
  exec oagwish "$0" "$@"

set auto_path [linsert $auto_path 0  /usr/local/oag/apps/lib/$env(HOST_ARCH)]
set auto_path [linsert $auto_path 0 /usr/local/oag/lib_patch/$env(HOST_ARCH)]

set CVSRevisionAuthor "\$Revision: 1.24 $ \$Author: gfystro $"

APSStandardSetup

proc setStatusText { text } {
    global statusText
    set statusText "$text ([exec date])"
    update
}

set BMautocorrection 0
set QFautocorrection 0
set QDautocorrection 0
proc StartAutoRampCorrection {args} {
    global triggerType  topupState
    global BM QF QD SF SD BMLimit QFLimit QDLimit SFLimit SDLimit BMSlopeGain
    global BMParentWidget QFParentWidget QDParentWidget SFParentWidget SDParentWidget
    global waitTime w1 IRamp

    set controllaw [file readlink /home/helios/oagData/controllaw/bcontrollaw]
    if [regexp {IRamp} $controllaw] {
        if !$IRamp {
            if ![APSYesNoPopUp "The bcontrollaw is linked to IRamp now, are you sure to start VRamp correction?"] {
                setStatusText "The bcontrollaw is linked to IRamp now, please use PEM switch to VRamp before start VRamp correction."
                return
            }
        }
    } else {
        if $IRamp {
            if ![APSYesNoPopUp "The bcontrollaw is linked to VRamp now, are you sure to start IRamp correction?"] {
                setStatusText "The bcontrollaw is linked to VRamp now, please use PEM switch to IRamp before start IRamp correction!"
                return
            }
        }
    }

    APSDisableButton $w1.start1.button
    
    if [catch {exec cavget -list=B:SD-U:PoweredM -pend=10} SDstate] {
        return -code error "Error reading B:SD-U:PoweredM: $SDstate"
    }
    if {$SDstate!="B:SD"} {
        set SD 0
        setStatusText "Not in SD state, no correction for SD."
    }
    
    foreach magnet {BM QF QD SF SD} {
        if {$magnet=="SF"} {
            setStatusText "no auto-correction is needed for SF-U"
            #SF is being replaced by SF-U, no auto-correction is needed for SF-U"
            continue
        }
        if [set $magnet] {
            set parent [set ${magnet}ParentWidget]
            setStatusText "start $magnet auto correction ..."
            set runControlPV B:$magnet:AutoCorrectionControlRC
            if [catch {APScavget -list=$runControlPV.RUN -pend=30} running] {
                setStatusText "Can not read value of $runControlPV.RUN: $running!"
                setStatusText "$magnet auto-correction can not be started!"
                continue
            }
            if {$running=="?"} {
                setStatusText "Can not read value of $runControlPV.RUN"
                setStatusText "$magnet auto-correction can not be started!"
                continue
            }
            if $running {
                if [catch {APScavget -list=$runControlPV.HOST -pend=30} host] {
                    setStatusText "$magnet auto-correction is already running."
                    setStatusText "Can not read value of $runControlPV.HOST"
                    setStatusText "$magnet auto-correction can not be started!"
                    continue 
                }
                setStatusText "$magnet auto-correction is already running on $host!"
                continue
            }
            if [winfo exist $parent.auto$magnet] {
                destroy $parent.auto$magnet
            }
            if $IRamp {
                exec cp /home/helios/oagData/booster/ramps/IRamp/safety/${magnet}Vref.afg100 /home/helios/oagData/booster/ramps/IRamp/current-IRamp/${magnet}Vref.afg100
            }
            
            APSExecLog .auto$magnet -parent $parent \
              -height 30 -lineLimit 2048 -width 95 \
              -name "Automatic Ramp Correction for $magnet" \
              -unixCommand "BRampAutoCorr -supply $magnet -triggerType $triggerType -BControlSlopeGain $BMSlopeGain -waitTime $waitTime -IRamp $IRamp"
            
        }
    }
    APSEnableButton $w1.start1.button
}

proc AbortAutoCorrection {args} {
    global BM QF QD SF SD
    foreach supply {BM QF QD SF SD} {
        if [set $supply] {
            setStatusText "Abort $supply auto correction ..."
            set runControlPV B:$supply:AutoCorrectionControlRC
            if [catch {APSAbortSRControllaw -runControlPV $runControlPV} result] {
                setStatusText "$result.\nAbort auto-scan failed."
                continue
            }
            setStatusText "Waiting for $runControlPV to clear..."
            if [catch {exec cawait -waitfor=$runControlPV.RUN,equal=0 } result] {
                setStatusText "Problem aborting $supply auto-correction: $result"
                continue
            }
            if [catch {APScavput -list=$runControlPV.CLR=1 -pend=30} result] {
                setStatusText "Problem aborting $supply auto-correction: $result"
                continue
            }
            setStatusText "$supply auto correction was aborted."
        }
    }
}

proc AutoCorrectionInfo {args} {
    foreach supply {BM QF QD SF SD} {
        set runControlPV B:$supply:AutoCorrectionControlRC
        if [catch {exec medm -x -attach -macro "RCPV=$runControlPV" \
                     ./sr/psApp/APSRunControlSingle.adl & \
                 } result ] {
            setStatusText  "$result"
        }
        after 1000
    }
}

proc plotMagnetRamps {quantity} {
    global BM QF QD SF SD magnetlist bcontrollist  bcontrolvarlist magnetDelayPVList IRamp
    
    
    set selectlist ""
    set tmpfile /tmp/bmon-[APSTmpString]
    if {$quantity=="dI/I"} {
        set relCommonPlotCommands "-scale=0,270,-0.01,0.01 -sub=5,5"
        lappend sddsplotCommand sddsplot $relCommonPlotCommands
    } elseif {$quantity=="dI"} {
        set absCommonPlotCommands "-scale=0,270,-1,1 -sub=5,5"
        lappend sddsplotCommand sddsplot $absCommonPlotCommands
    }
    setStatusText "Setting up to plot $quantity..."

    foreach magnet $magnetlist magnetDelayPV $magnetDelayPVList {
        if [set $magnet] {
            lappend selectlist $magnet
            if [catch {computeBeamInjectionTime $magnetDelayPV} magnetInjTime] {
                setStatusText "Can not get beam injection time: $magnetInjTime"
                return
            }
            if [catch {computeBeamExtrationTime $magnetInjTime} magnetExtTime] {
                setStatusText "Can not get beam extraction time: $magnetExtTime"
                return
            }
            set injStringCommand "-string=\$s5\$e,x=$magnetInjTime,y=0,scale=1.5,justify=rc,angle=90,linety=4"
            set extStringCommand "-string=\$s5\$e,x=$magnetExtTime,y=0,scale=1.5,justify=rc,angle=90,linety=6"
            if {$quantity=="dI/I"} {
                lappend sddsplotCommand "-col=time,${magnet}deltaI\/I" "-graph=line,type=1"
            } elseif {$quantity=="dI"} {
                lappend sddsplotCommand "-col=time,${magnet}fitError" "-graph=line,type=1"
            } else {return 0}
            lappend sddsplotCommand "-topline=$quantity for $magnet" $injStringCommand $extStringCommand
            lappend sddsplotCommand $tmpfile -end
        }
    }
    if [llength $selectlist] { 
        setStatusText "Plotting $quantity for $selectlist..."
        APSAddToTmpFileList -ID 1 -fileList "$tmpfile"
        if $IRamp {
            if  [catch {exec BIRampWaveformMon -filename $tmpfile} result] {
                return -code error "Error reading booster Iramp waveforms: $result"
            }
        } else {
            if [catch {exec BRampWaveformMon -filename $tmpfile} result] {
                return -code error $result
            }
        }
        eval exec $sddsplotCommand &
        APSAddToTmpFileList -ID 1 -fileList $tmpfile
    } else {
        setStatusText "No supplies selected for ploting."
    }
}



proc computeBeamInjectionTime {pvname} {
    if [catch {APScavget -list=It:Bs:StartRamp2BsIp.VAL -pend=30} rampstart] {
        return -code error $rampstart
    }
    if [catch {APScavget -list=$pvname -pend=30} magnetDelay] {
        return -code error $magnetDelay
    }
    if {$rampstart=="?" || $magnetDelay=="?"} {
        return -code error "Can not read value of It:Bs:StartRamp2BsIp.VAL or $pvname."
    }
    set injTime [expr $rampstart - $magnetDelay]
    return [format "%.1f" $injTime]
}

proc computeBeamExtrationTime {injTime} {
    if [catch {exec cavget -list=A014-IETS:BTC:BInjectionCycleM,A014-IETS:BTC:BExtractionCycleM,A014-IETS:BTC:SRSetFreqM -pend=20 -printErrors -floatformat=%lf} results] {
        return -code error "Error reading A014-IETS:BTC:BInjectionCycleM,A014-IETS:BTC:BExtractionCycleM,A014-IETS:BTC:SRSetFreqM: $results"
    }
    set bInjectionCycle [lindex $results 0]
    set bExtractionCycle [lindex $results 1]
    set srFreq [lindex $results 2]
    set extTime [expr $injTime + (1000 * ($bExtractionCycle - $bInjectionCycle) / $srFreq)]
    
    return [format "%.1f" $extTime]
}

proc UnlockMagnet {args} {
    global BM QF QD SF SD
    foreach magnet {BM QF QD SF SD} {
        if [set $magnet] {
            if [catch {exec cavput -list=B:${magnet}:BconLockedMBBO=0 -pend=10} result] {
                return -code error "Unable to unlock $magnet: $result"
            }
        }
    }
}
proc BringUpBControl {args} {
    exec controllaw -controlList bcontrollaw &
}

proc KillBControl {args} {
    foreach magnet {BM SF SD QF QD} {
        global $magnet 
        if [set $magnet] {
            if [catch {exec cavput -list=B:${magnet}bcontrollawRC.ABRT=1 -pend=30} result] {
                return -code error "Error in killing bcontrol: $result"
            }
            exec cawait -waitFor=B:${magnet}bcontrollawRC.RUN,equal=0
            if [catch {exec cavput -list=B:${magnet}bcontrollawRC.CLR=1 -pend=30} result] {
                return -code error "Error in clear bcontrol record: $result"
            }
        }
    }
}

proc GenerateIRampReference {args} {
    #suspend bcontrol 
    global ignoreSFSD
    
    
    set magnetList {BM QF QD SF-U SD-U}
    if [catch {exec cavget -list=B: -list=[join $magnetList ,] -list=:IRampDelayErrAI -pend=10} delayList] {
        return -code error "Error in reading delay pvs: $delayList"
    }
    set error 0
    foreach magnet $magnetList delay $delayList {
        if $ignoreSFSD {
            if {$magnet=="SF-U" || $magnet=="SD-U"} {
                continue
            }
        }
        if {[expr abs($delay)]>0.2} {
            setStatusText "$magnet delay error is $delay, too big."
            incr error
        }
    }
    if $error {
        setStatusText "generating reference was aborted due to too big delay error."
        return
    }
    #check if the gain setpoint and readback agrees or not
    set gainTolerance 2.0e-4
    if [catch {exec cavget -list=B: -list=[join $magnetList ,] -list=:IRampGainSetAI -pend=10} setgainList] {
        return -code error "Error in reading IRamp gain setpoint: $setgainList"
    }
    if [catch {exec cavget -list=B: -list=[join $magnetList ,] -list=:IRampGainAI -pend=10} gainList] {
        return -code error "Error in reading IRamp gain setpoint: $gainList"
    }
    foreach set $setgainList readback $gainList magnet $magnetList {
        if $ignoreSFSD {
            if {$magnet=="SF-U" || $magnet=="SD-U"} {
                continue
            }
        }
        if {[expr abs($readback-$set)]>$gainTolerance} {
            setStatusText "$magnet the difference betain gain setpoint and readback > $gainTolerance, generating reference was aborted.."
            return
        }
    }
    set delayTolerance 2e-2
    if [catch {exec cavget -list=B: -list=[join $magnetList ,] -list=:IRampDelayOffsetAI -pend=10} setdelayList] {
        return -code error "Error in reading IRamp gain setpoint: $setdelayList"
    }
    if [catch {exec cavget -list=B: -list=[join $magnetList ,] -list=:IRampDelayAI -pend=10} delayList] {
        return -code error "Error in reading IRamp gain setpoint: $delayList"
    }
    foreach set $setdelayList readback $delayList magnet $magnetList {
        if $ignoreSFSD {
            if {$magnet=="SF-U" || $magnet=="SD-U"} {
                continue
            }
        }
        if {[expr abs($readback-$set)]>$delayTolerance} {
            setStatusText "$magnet the difference between delay setpoint and readback > $delayTolerance, generating reference was aborted.."
            return
        }
    }
    setStatusText "suspending bcontrols ..."
    if [catch {exec cavput -list=B: -list=BM,QF,QD,SF,SD  -list=bcontrollawRC.SUSP=1 -pend=30} result] {
        return -code error "Error in suspend bcontrols: $result"
    }
    setStatusText "aborting injection tune controllaw..."
    if [catch {exec cavput -list=B:InjTune:ControllawRC.ABRT=1 -pend=30 } result] {
        return -code error "Error in suspend injection controllaw: $result"
    }
    
    set refDir /home/helios/oagData/booster/ramps/IRamp/current-IRamp
    set lattice [file readlink /home/helios/oagData/booster/ramps/IRamp]
    set oldFile [file readlink $refDir/IRef]
    set newName [APSNextGenerationedName -directory $refDir -name IRef-0000 -newFile 1 -separator -]
    
    setStatusText "creating IRamp reference ..."
    if [catch {exec GetBooRampCurrWF -filename $refDir/$newName } result] {
        return -code error "Error in creating IRamp reference."
    }
    setStatusText "clear gain and delay..."
    if [catch {exec cavput -list=B: -list=[join $magnetList ,] -list=:IRampGainSetAI=1 -pend=10
        exec cavput -list=B: -list=[join $magnetList ,] -list=:IRampDelayOffsetAI=0 -pend=10 } result] {
        return -code error "Error in setting IRamp gain to 1 and delay to 0: $result"
    }
    
    setStatusText "load reference into reference waveform..."
    
    set tmpRoot /tmp/[APSTmpString]
    
    foreach magnet $magnetList {
        if [catch {exec sddsconvert $refDir/$newName -pipe=out \
                     -retain=col,Index,B:${magnet}:CurrentWF -retain=par,${magnet}* \
                     | sddsconvert -pipe -rename=col,B:${magnet}:CurrentWF=Waveform \
                     | sddsprocess -pipe=in -reprint=par,WaveformPV,B:${magnet}:IRampRefWF $tmpRoot.$magnet} result] {
            return -code error $result
        }
        set gain [exec sdds2stream -par=${magnet}AfgGain $tmpRoot.$magnet]
        set delay [exec sdds2stream -par=${magnet}TriggerDelay $tmpRoot.$magnet]
        if [catch {exec cavput -list=B:${magnet}:RefAfgGain=$gain,B:${magnet}:RefTriggerDelay=$delay -pend=20
            exec sddswput $tmpRoot.$magnet -pend=20 } result] {
            return -code error "error in setting reference pvs: $result"
        }
    }
    set oldDir [pwd]
    cd $refDir
    exec rm IRef
    exec ln -s $newName IRef
    cd $oldDir
    file delete -force $tmpRoot.BM $tmpRoot.QF $tmpRoot.QD $tmpRoot.SF $tmpRoot.SD
    setStatusText "do SCR save..."
    if [catch {APSSaveMachine -machine Booster -description "Save QF and QD trigger delay offset after generating IRamp reference." } result] {
        return -code error "Error in saving booster SCR: $result"
    }
    APSMpStep "Reset QF, QD trigger offset to zero..."
    if [catch {exec cavput -list=B: -list=BM,QF,QD,SF,SD -list=:IRampDelayOffsetAI=0 -pend=10} result] {
        APSMpReturn error "Error in reseting QF, QD trigger offset: $result"
    }
    
    after 1000
    setStatusText "resuming bcontrols ...."
    if [catch {exec cavput -list=B: -list=BM,QF,QD,SF,SD  -list=bcontrollawRC.SUSP=0 -pend=30} result] {
        return -code error "Error in resume bcontrols: $result"
    }
    setStatusText "starting booster injection controllaw..."
    APSInfoWindow .infoing -name "Start booster injection controllaw" -width 70 -infoMessage "Booster injection tune controllaw was aborted, you need to restart it now."  \
      -packOption "-side top -fill both"
    
    if [catch {LoadIRampReference} result] {
        return -code error "Error loading reference: $result"
    }
    
    if [catch {ArchiveDI } archiveFile] {
        return -code error "Error in archiving IRamp dI/I: $archiveFile"
    }
    global env
    if [catch {exec logMessage -sourceId=BRampIRefAudit -tag=User $env(USER) -tag=Host $env(HOST) \
                 -tag=Lattice $lattice -tag=OldFile $oldFile -tag=NewFile $newName \
                 -tag=CurrentWaveformFile $archiveFile } result] {
        return -code error "Error in logMessage: $result"
    }
    setStatusText "done."
}

proc ArchiveDI {args} {
    #set archiveDirectory /home/helios/oagData/booster/ramps/IRamp/archivedData
    set  archiveDirectory /home/helios/oagData/booster/rampLogFiles/IRamp/archivedData
    set dataFileUniqueLabel [APSOffsetDateInfo -today 1 -dateFormat Y-M-D]_[lindex [exec date] 3]
    
    set archiveDataFile ${archiveDirectory}/bmon${dataFileUniqueLabel}.sdds
    
    if  [catch {exec BIRampWaveformMon -filename $archiveDataFile} result] {
        return -code error "Error reading booster Iramp waveforms: $result"
    }
    catch {exec gzip $archiveDataFile}
    return $archiveDataFile.gz
}

proc LoadIRampReference {args} {
    set refFile /home/helios/oagData/booster/ramps/IRamp/current-IRamp/IRef
    set tmpRoot  /tmp/[APSTmpString]
    
    if [catch {exec cavget -list=B:SD-U:PoweredM -pend=10} SDstate] {
        return -code error "Error reading B:SD-U:PoweredM: $SDstate"
    }
    switch $SDstate {
        B:SD {
            set magnetList {BM QF QD SF-U SD}
        }
        B:SD-U {
            set magnetList {BM QF QD SF-U SD-U}
        }
        default {
            setStatusText "Unknown SD status: $SDstate; nothing will be done for SD/SD-U"
            set magnetList {BM QD QF SF-U}
        }
    }
    
    setStatusText "Loading IRamp reference waveform, gain and delays for [join $magnetList]..."
    foreach magnet $magnetList {
        if [catch {exec sddsconvert $refFile -pipe=out \
                     -retain=col,Index,B:${magnet}:CurrentWF -retain=par,${magnet}* \
                     | sddsconvert -pipe -rename=col,B:${magnet}:CurrentWF=Waveform \
                     | sddsprocess -pipe=in -reprint=par,WaveformPV,B:${magnet}:IRampRefWF $tmpRoot.$magnet} result] {
            return -code error $result
        }
        set gain [exec sdds2stream -par=${magnet}AfgGain $tmpRoot.$magnet]
        set delay [exec sdds2stream -par=${magnet}TriggerDelay $tmpRoot.$magnet]
        if [catch {exec cavput -list=B:${magnet}:RefAfgGain=$gain,B:${magnet}:RefTriggerDelay=$delay -pend=20
            exec sddswput $tmpRoot.$magnet -pend=20 } result] {
            return -code error "error in setting reference pvs: $result"
        }
        lappend fileList $tmpRoot.$magnet
    }
    setStatusText "done."
    eval file delete -force $fileList
}

#application starts here
set magnetlist {BM QF QD SF SD} 
set bcontrollist {Slope Zero}
set bcontrolvarlist {slope zero}
set magnetDelayPVList {It:Ddg8chan6.DLY It:Ddg6chan3.DLY It:Ddg8chan7.DLY It:Ddg9chan2.DLY It:Ddg9chan3.DLY}

set statusText ""
set triggerType rms

APSApplication . -name BRampControlAutoCorrection -version "$CVSRevisionAuthor" \
  -overview {This utility allows automatic ramp correction for Booster BM, QF and QD.}

APSScrolledStatus .status  -parent .userFrame  -textVariable statusText -width 60 \
  -height 8 -withButtons 1 -packOption "-fill x"

APSFrame .execlog -parent .userFrame -packOption "-expand 1 -fill both -side top"
.userFrame.execlog.frame configure -relief flat -bd 0
set tabList [APSTabFrame .exec -parent .userFrame.execlog.frame -label "" \
               -labelList {BM QF QD SF SD} -width 800 -height 300 \
               -packOption "-expand 1 -fill both"]
set BMParentWidget [lindex $tabList 0]
set QFParentWidget [lindex $tabList 1]
set QDParentWidget [lindex $tabList 2]
set SFParentWidget [lindex $tabList 3]
set SDParentWidget [lindex $tabList 4]

foreach var {BM QF QD SF SD} {
    set $var 0
}

set waitTime 4
set BMSlopeGain 0.1
set limitWidth 11
APSFrame .limit -parent .userFrame -label "" 
APSLabel .label -parent .userFrame.limit.frame -text "RMS limit:" \
  -packOption "-side left"
APSLabeledEntry .bm1 -parent .userFrame.limit.frame -label "Slope Gain" \
  -textVariable BMSlopeGain -width $limitWidth -packOption "-side left" \
  -contextHelp "This sets the gain that is used for slope adjustments by Bcontol."
APSLabeledEntry .wait -parent .userFrame.limit.frame -label "Wait time after correction (s):" \
  -textVariable waitTime -width $limitWidth -packOption "-side left" \
  -contextHelp "Number of seconds to pause after each correction"
APSButton .limit -parent .userFrame.limit.frame -text "Limit Screen" -command "exec medm -x -attach booster/opsApp/autoCorrParams.adl &"

set IRamp 1

APSCheckButtonFrame .supplys -parent .userFrame -label "Power Supplies:" \
  -buttonList {BM QF QD SF SD} -variableList {BM QF QD SF SD} -orientation horizontal \
  -allNone 1 -contextHelp "select the supply for starting/aborting auto-correction"
APSRadioButtonFrame .type -parent .userFrame -label "Correction Type:" -buttonList {VRamp IRamp} \
  -valueList {0 1} -variable IRamp -orientation horizontal -contextHelp "selection ramp correction type." 
set ignoreSFSD 0
APSRadioButtonFrame .sf -parent .userFrame -label "Ignore SF/SD gain/delay error when generating reference file?" \
  -buttonList {Yes No} -valueList {1 0} -variable ignoreSFSD -orientation horizontal

APSFrame .but1 -parent .userFrame
set w1 .userFrame.but1.frame
$w1 configure -bd 0
APSFrame .but2 -parent .userFrame
set w2 .userFrame.but2.frame
$w2 configure -bd 0

APSButton .start1 -parent $w1 -text "Start AutoCorrection" -command "StartAutoRampCorrection" \
  -contextHelp "This button starts auto-correction for the selected supplies."
APSButton .abort -parent $w1 -text "Abort AutoCorrection" -command "AbortAutoCorrection" \
  -contextHelp "This button aborts auto-correction for the selected supplies."
APSButton .startBcontrol -parent $w1 -text "Bringup Bcontrol Window" \
  -command "BringUpBControl" -contextHelp "This button brings up the bcontrollaw window, where the each bcontrollaw is started."

APSButton .killBcontrol -parent $w1 -text "Kill Bcontrol" -command "KillBControl" \
  -contextHelp "This button kills all 5 bcontrols."

APSButton .swap -parent $w1 -text "Run SwapSync" \
  -command "exec BRampSwapSync &" \
  -contextHelp "This button starts the SwapSync process that is used by Bcontrol."

APSButton .swap1 -parent $w1 -text "Abort SwapSync" \
  -command "exec cavput -list=B:SwapSyncRC.ABRT=1" \
  -contextHelp "This button aborts the SwapSync process that is used by Bcontrol."

APSButton .info -parent $w2 -text "Info" -command AutoCorrectionInfo \
  -contextHelp "This button brings up the runcontrol info medm screens for each of the auto-corrections and Bcontrol."
APSButton .plotdI -parent $w2 -text "dI/I" -command "plotMagnetRamps dI/I" \
  -contextHelp "This button plots the selected booster magnet current relative error dI/I."
APSButton .plotI -parent $w2 -text "dI" -command "plotMagnetRamps dI" \
  -contextHelp "This button plots the selected booster magnet absolute current error dI."

APSButton .trig -parent $w2 -text "Reset Triggers" \
  -command "ResetTriggers" -contextHelp "Press to reset triggers when any of the zero values are out of range."

APSButton .plot -parent $w2 -text "Plot Archive Ramps" \
  -command "PlotArchiveRamp" \
  -contextHelp "This button allows you to plot archived magnet ramp data."

APSButton .ref -parent $w2 -text "Generate IRamp Reference" -command "GenerateIRampReference"
APSButton .load -parent $w2 -text "Load IRamp Reference" -command "LoadIRampReference" -contextHelp "Load the current reference waveforms into reference waveform PVs."

foreach type {current deltaI/I fitError vout BM QD QF SF SD} {
    set plot$type 0
}
proc PlotArchiveRamp {args} {
    global plotcurrent plotdeltaI/I plotfitError plotvout dialogResponse
    global plotBM plotQD plotQF plotSF plotSD
    set archiveDir /home/helios/oagData/booster/rampLogFiles/IRamp/rampCorrectionLogFiles
    
    set dialogResponse 0
    APSDialogBox .plot -name "Plot Autocorrection Archive Ramps" \
      -okCommand "set dialogResponse ok" \
      -cancelCommand "set dialogResponse cancel"
    APSCheckButtonFrame .supply -parent .plot.userFrame \
      -label "Check power supplies for plot:" \
      -buttonList {BM QF QD SF SD} \
      -variableList {plotBM plotQF plotQD plotSF plotSD} \
      -allNone 1
    APSCheckButtonFrame .type -parent .plot.userFrame \
      -label "Check quantity for plot:  " \
      -buttonList {current deltaI/I fitError vout} \
      -variableList {plotcurrent plotdeltaI/I plotfitError plotvout} \
      -allNone 1
    update
    tkwait variable dialogResponse
    set plotColumns ""
    foreach supply {BM QF QD SF SD} {
        if ![set plot$supply] {
            continue
        }
        foreach type {current deltaI/I fitError vout} {
            if ![set plot$type] {
                continue
            }
            lappend plotColumns ${supply}$type
        }
    }
    if ![llength $plotColumns] {
        return -code error "Nothing is selected for plot!"
    }
    set dataFile1 ""
    set dataFile1 [APSFileSelectDialog .dataFileSelectWidget \
                     -path ${archiveDir} \
                     -pattern *_Start.sdds.gz \
                     -title "Ramp data file selection"]
    if ![string length $dataFile1] {
        return -code error "None file is selected for plot."
    }
    regsub {Start} $dataFile1 Finish dataFile2
    #if ![file exist $dataFile2] {
    #   return -code error "$dataFile2 does not exist, i.e., the ramps were not archived after the correction."
    #}
    set corrSupply [string range [file tail $dataFile1] 0 1]
    if [file exist $dataFile2] {
        set plotCmd "sddsplot -grap=line,vary -sep=2 -scale=0,250,0,0"
    } else {
        set plotCmd "sddsplot -grap=line,vary -sep=1 -scale=0,250,0,0"
    }
    lappend plotCmd \"-title=booster ramps before and after $corrSupply correction.\"
    foreach col $plotColumns {
        lappend plotCmd "-col=time,$col -leg=spec=Start $dataFile1"
        if [string match "*deltaI/I" $col] {
            lappend plotCmd "-scal=0,250,-0.01,0.01"
        } else {
            lappend plotCmd "-scal=0,250,0,0"
        }
        if [file exist $dataFile2] {
            lappend plotCmd "-col=time,$col -leg=spec=Finish $dataFile2"
        }
    }
    catch {eval exec [join $plotCmd] &} result
}
proc ResetTriggers {} {
    global BM QF QD SF SD
    global statusText
    APSSetVarAndUpdate statusText  "Resetting triggers...."
    APSMpBoosterPSResetAFGTriggers -BM $BM -QF $QF -QD $QD -SF $SF -SD $SD
    APSSetVarAndUpdate statusText  "Done."
}
proc Restart {args} {
    set magnet ""
    APSParseArguments {magnet}
    global BM QF QD SF SD
    foreach m "BM QF QD SF SD" {
        set $m 0
    }
    set $magnet 1
    StartAutoRampCorrection
}

#port 4583 through 4587 are used to tell the BRampControlAutoCorrection to start the auto correction script
if [catch {socket -server "Restart -magnet BM" 4583}] {
    APSSetVarAndUpdate statusText  "There appears to be another copy of this program already started"
}
if [catch {socket -server "Restart -magnet QF" 4584}] {
    APSSetVarAndUpdate statusText  "There appears to be another copy of this program already started"
}
if [catch {socket -server "Restart -magnet QD" 4585}] {
    APSSetVarAndUpdate statusText  "There appears to be another copy of this program already started"
}
if [catch {socket -server "Restart -magnet SF" 4586}] {
    APSSetVarAndUpdate statusText  "There appears to be another copy of this program already started"
}
if [catch {socket -server "Restart -magnet SD" 4587}] {
    APSSetVarAndUpdate statusText  "There appears to be another copy of this program already started"
}
