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

# $Log: not supported by cvs2svn $
# Revision 1.7  1998/12/08 17:38:18  emery
# Adjusted the position of daily directory button.
#

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)]
APSDebugPath

set CVSRevisionAuthor "\$Revision: 1.8 $ \$Author: emery $"

APSApplication . -name SRApertureScan -version $CVSRevisionAuthor

set status Ready.
APSScrolledStatus .status -parent .userFrame -textVariable status -width 80 -height 8

set IDNumber 1
set RunIndex 0
set ClickLimit 210
set ClickOffset 70
set BumpPlane H
set outputDirectory [pwd]
APSLabeledEntry .dir -parent .userFrame -label "Directory: " \
   -textVariable outputDirectory -width 70 -contextHelp  \
    "Directory in which to put data files."
APSButton .daily -parent .userFrame -packOption "-side top -anchor w" \
   -text "Go to daily directory" \
   -command {set outputDirectory [APSGoToDailyDirectory -subdirectory apertureScan]} \
   -contextHelp "Setting daily directory in which to put data files."
APSLabeledEntry .id -parent .userFrame -label "ID: " -textVariable IDNumber -width 10  \
    -numberButtons 1 -contextHelp "The number of the ID straight to do the bump in."
APSLabeledEntry .index -parent .userFrame -label "Index: " -textVariable RunIndex -width 10 \
    -numberButtons 1 -contextHelp \
    "The index of the run.  The file rootname will be ID<ID>-<Plane>-<Index>.sdds"
APSLabeledEntry .clickLimit -parent .userFrame -label "Click limit: " \
    -textVariable ClickLimit -width 10 \
    -numberButtons 1 -contextHelp \
    "The maximum number of clicks to make to each side during scans."
APSLabeledEntry .clickOffset -parent .userFrame -label "Click offset: " \
    -textVariable ClickOffset -width 10 \
    -numberButtons 1 -contextHelp \
    "The number of clicks to take to each side prior to beginning data collection.  Helps prevent collecting lots of data with nothing happening."

APSRadioButtonFrame .plane -parent .userFrame -label "Plane: " -variable BumpPlane \
    -buttonList {H V} -valueList {H V} -orientation horizontal -contextHelp \
    "Pick the plane in which to do the scan." \
    -commandList {"SetPlaneDefaults H" "SetPlaneDefaults V"}

APSButton .run -parent .userFrame -text Run -command \
  {RunBumpLimitScan -ID $IDNumber -index $RunIndex -outputDir $outputDirectory \
     -clickLimit $ClickLimit -clickOffset $ClickOffset -plane $BumpPlane \
     -statusCallback "APSSetVarAndUpdate status"; bell ; bell } 

proc SetPlaneDefaults {plane} {
    global ClickLimit ClickOffset
    switch $plane {
        H {
            set ClickLimit 210
            set ClickOffset 70
        }
        V {
            set ClickLimit 40
            set ClickOffset 10
        }
    }
}

proc RunBumpLimitScan {args} {
    set ID 1
    set index 0
    set clickLimit 200
    set clickOffset 70
    set plane H
    set statusCallback APSNoOp
    set outputDir ""
    APSStrictParseArguments {ID index clickLimit statusCallback clickOffset plane outputDir} 

    set inputDir /home/helios/oagData/sr/apertureScan/monitorInputs
    scan $index "%ld" index
    set index [format "%02ld" $index]
    set output $outputDir/ID${ID}-$index.sdds

    set xy x
    set XY X
    if [string compare $plane H] {
        set xy y
        set XY Y
    }
    if {[catch {exec cavget -list=S:RC:OrbitControlLaw${XY}C.SUSP} orbitControllawMode]  || \
          [catch {exec cavput -list=S:RC:OrbitControlLaw${XY}C.SUSP=Suspend} result]} {
        return -code error "$orbitControllawMode$result"
    }

    if {![file exists $output.p.gz] || ![file exists $output.m.gz]} {
        eval $statusCallback {"Enabling thick septum pulsing."}
        exec cavput -list=Mt:Ddg3chan0.GATE=Enabled

        set knobFile /home/helios/oagData/sr/apertureScan/bumps/ID${ID}TwoSectorBumpPV.cokn
        if [catch {APSKnobOpen -fileName $knobFile} knobID] {
            eval $statusCallback {"$knobID"}
            catch {exec cavput -list=S:RC:OrbitControlLaw${XY}C.SUSP=$orbitControllawMode}
            return -code error "$knobID"
        }
        eval $statusCallback {"Knob opened."}
        set bumpName ID${ID}${xy}2sectorBump
        set tmpRoot /tmp/[APSTmpString]
        if [catch {exec sddsprocess $knobFile -pipe=out \
                     -match=parameter,ControlName=$bumpName \
                     | sddsconvert -pipe -dele=param,* \
                     | sddsprocess -pipe \
                     -print=column,ReadbackName,%s,ControlName \
                     -print=column,ReadbackUnits,A \
                     -print=column,ControlType,pv \
                     | sddsconvert -pipe=in $tmpRoot.knobAOs \
                     -retain=col,Control*,Readback*
            exec sddsprocess $tmpRoot.knobAOs $tmpRoot.knobAIs \
                     -reedit=column,ControlName,%/AO/AI/ \
                     -reedit=column,ReadbackName,%/AO/AI/ 
            exec sddscombine $tmpRoot.knobAIs $tmpRoot.knobAOs \
                     $inputDir/IDBumpScan.scalars -merge $tmpRoot.scalars} result] {
            eval $statusCallback {"$result"}
            catch {APSKnobClose -id $knobID}
            catch {exec cavput -list=S:RC:OrbitControlLaw${XY}C.SUSP=$orbitControllawMode}
            return -code error $result
        }
        eval $statusCallback {"Input files created."}

        if [catch {exec burtrb -f $tmpRoot.knobAOs -o $tmpRoot.AOsnap} result] {
            eval $statusCallback {"$result"}
            catch {APSKnobClose -id $knobID}
            catch {exec cavput -list=S:RC:OrbitControlLaw${XY}C.SUSP=$orbitControllawMode}
            return -code error $result
        }

        if [catch {MakeSweep -knobID $knobID -bumpName $bumpName -clickLimit $clickLimit \
                     -clickOffset $clickOffset \
                     -output $output.m -direction down -ID $ID -scalarsFile $tmpRoot.scalars \
                     -current 10 -rampBack 0 -statusCallback $statusCallback} result] {
            eval $statusCallback {"$result"}
            catch {APSKnobClose -id $knobID}
            catch {exec cavput -list=S:RC:OrbitControlLaw${XY}C.SUSP=$orbitControllawMode}
            return -code error $result
        }

        eval $statusCallback {"Restoring original setpoints"}
        if [catch {exec sddscasr -restore $tmpRoot.AOsnap} result] {
            eval $statusCallback {"$result"}
            catch {APSKnobClose -id $knobID}
            catch {exec cavput -list=S:RC:OrbitControlLaw${XY}C.SUSP=$orbitControllawMode}
            return -code error $result
        }
        APSWaitWithUpdate -waitSeconds 30 -updateInterval 1

        if [catch {MakeSweep -knobID $knobID -bumpName $bumpName -clickLimit $clickLimit \
                     -clickOffset $clickOffset \
                     -output $output.p -direction up -ID $ID -scalarsFile $tmpRoot.scalars \
                     -current 10 -rampBack 0 -statusCallback $statusCallback} result] {
            eval $statusCallback {"$result"}
            catch {APSKnobClose -id $knobID}
            catch {exec cavput -list=S:RC:OrbitControlLaw${XY}C.SUSP=$orbitControllawMode}
            return -code error $result
        }
        eval $statusCallback {"Restoring original setpoints"}
        if [catch {exec sddscasr -restore $tmpRoot.AOsnap} result] {
            eval $statusCallback {"$result"}
            catch {APSKnobClose -id $knobID}
            catch {exec cavput -list=S:RC:OrbitControlLaw${XY}C.SUSP=$orbitControllawMode}
            return -code error $result
        }
        eval $statusCallback {"Measurement done."}
    } else {
        eval $statusCallback {"Data already exists with that name."}
    }
    exec sddsplot -parameter=Time,S35DCCT -graph=line,vary $output.m.gz \
        $output.p.gz -ticks=xtime &
    catch {APSKnobClose -id $knobID}
    catch {exec cavput -list=S:RC:OrbitControlLaw${XY}C.SUSP=$orbitControllawMode}
}

proc MakeSweep {args} {
    set knobID ""
    set bumpName ""
    set clickLimit 1
    set output ""
    set direction down
    set ID 1
    set scalarsFile ""
    set current 10
    set rampBack 0
    set statusCallback APSNoOp
    set plane H
    set clickOffset 0
    APSStrictParseArguments {knobID bumpName clickLimit output direction ID scalarsFile current rampBack statusCallback plane clickOffset}
    set tmpRoot /tmp/[APSTmpString]

    set inputDir /home/helios/oagData/sr/apertureScan/monitorInputs

    eval $statusCallback {"Filling to $current mA"}
    TogglePulsedMagnetEnables -location GuntoBoosterExt
    if [catch {DoIOCBunchTrainInjection -start 0 -interval 100 -number 1 \
        -stopAt 10 -cycles 30 -multiplet 6 -callback $statusCallback} result] {
        return -code error $result
    }
    SetPulsedMagnetEnables -state 0 -location All

    eval $statusCallback {"Disabling thick septum pulsing."}
    if [catch {exec cavput -list=Mt:Ddg3chan0.GATE=Disabled} result] {
        return -code error $result
    }

    eval $statusCallback {"Taking reference values and orbit"}
    if [catch {exec sddsvmonitor $inputDir/IDBumpScan$plane.vmon $output.0 -erase \
                 -comment=IDName,ID$ID \
                 -scalars=$scalarsFile \
                 -interval=1,s -step=1} result] {
        return -code error $result
    }

    eval $statusCallback {"Moving beam $clickOffset $direction"}
    set clickLimit1 $clickOffset
    set clickLimit2 [expr $clickLimit-$clickLimit1]
    if [catch {APSKnobTicks -direction $direction -id $knobID \
                 -ticks $clickLimit1 -knob $bumpName -pause 500} result] {
        return -code error $result
    }

    eval $statusCallback {"Starting data collection"}
    set monPID [exec sddsvmonitor $inputDir/IDBumpScan$plane.vmon $output -erase \
                  -comment=IDName,ID$ID \
                  -scalars=$scalarsFile -interval=1,s -time=1,h &]
    APSWaitWithUpdate -waitSeconds 10 -updateInterval 1

    eval $statusCallback {"Moving beam while collecting data."}
    set clicksDone [APSKnobTicks -direction $direction -id $knobID -ticks $clickLimit2 \
      -knob $bumpName -pause 500 -withBeam 1]
    APSWaitWithUpdate -waitSeconds 5 -updateInterval 1

    exec kill $monPID

    eval $statusCallback {"Enabling thick septum pulsing."}
    if [catch {exec cavput -list=Mt:Ddg3chan0.GATE=Enabled} result] {
        return -code error $result
    }

    if $rampBack {
        eval $statusCallback {"Moving correctors back to center"}
        if [string compare $direction down] {
            set direction down 
        } else {
            set direction up
        }
        if [catch {APSKnobTicks -direction $direction \
                     -id $knobID -ticks [expr $clicksDone+$clickLimit1] \
                     -knob $bumpName -pause 500} result] {
            return -code error $result
        }
    }

    if [catch {exec gzip $output} result] {
        return -code error $result
    }
    eval $statusCallback {"Sweep done in $direction direction."}
}

proc APSKnobTicks {args} {
    set id ""
    set direction up
    set knob ""
    set ticks 1
    set pause 500
    set withBeam 0
    APSStrictParseArguments {id direction knob ticks pause withBeam}
    set clicksDone 0
    while {$ticks} {
        if [catch {APSKnobTick -id $id -direction $direction -knob $knob} result] {
            return -code error "$result"
        }
        incr ticks -1
        incr clicksDone
        after $pause
        if {$withBeam && \
            ![catch {exec cavget -list=S-DCCT:CurrentM} current] &&
            $current<0.1} {
            break
        }
    }
    return $clicksDone
}

