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

#
# $Log: not supported by cvs2svn $
# Revision 1.1  2006/02/20 22:13:34  shang
# first version
#

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.2 $ \$Author: shang $"

APSApplication . -name BoosterTuneMeasurement -version $CVSRevisionAuthor \
  -overview {measure booster tunes.}

set status Working...
APSScrolledStatus .status -parent .userFrame -textVariable status \
        -width 60 -height 6
update

set rootname boostertunes
set archiveDirectory /home/helios/oagData/booster/tuneArchive/data
set dataDirectory .
set dataComment ""
set archive 0 

set recallBooState 0
set yUpperLimit 5.0e-4
set captureBufferLength 100
set Timeout 300
set timeOverlap 0
set stopTime 100
#stopTime should be longer enough so that number of trances is bigger than 201 
#  which is the capture buffer depth
# the delta time between 2 traces is 0.2804
# 60 gives 60/0.2804  214 traces.
set setupVSA 0
set enablePinger 0
if [catch {exec hpSocketSend hpvecboo  "TCAP1:LENG?" } result] {
    return -code error $result
}
set captureBufferLength [expr $result * 1000]
if [catch {exec hpSocketSend hpvecboo "TCAP2:STOP?"} result] {
    return -code error $result
}
set stopTime [format %.3f [expr $result * 1000]]
proc SetStatus {text} {
    global status
    set status $text
    update
}

proc CheckCaptureBufferLength {args} {
    global captureBufferLength
    if {$captureBufferLength<0 || $captureBufferLength>350} {
        set captureBufferLength 100
    }
}
proc MakeSaveWidget {widget args} {
    set parent .userFrame
    APSStrictParseArguments {parent}
    
    global dataDirectory rootname archiveDirectory archive outputFile
    APSFrame $widget -parent $parent -relief flat
    set w $parent$widget.frame
    
    APSLabeledEntry .outputDir -parent $w \
      -label "Output directory:" \
      -textVariable dataDirectory \
      -contextHelp "Enter a name for the output file directory." \
      -width 55
    APSButton .daily -parent $w.outputDir -packOption "-anchor e -side right" \
      -text "daily" -size small \
      -command {set dataDirectory [APSGoToDailyDirectory -subdirectory booTune];set archive 0}
    APSButton .archive -parent $w.outputDir -packOption "-anchor e -side right" \
      -text "archive" -size small \
      -command {set dataDirectory $archiveDirectory; set archive 1}
    
    APSLabeledEntry .rootname -parent $parent -label "Rootname: " \
      -textVariable rootname -width 60 \
      -contextHelp "the rootname of output file for non-achive data, i.e., the output directory is not achive directory"
    APSLabeledOutput .file -parent $parent -label "Output file: "  \
        -textVariable outputFile -width 60
    APSLabeledEntry .comment -parent $parent -label "Comment: " \
      -textVariable dataComment -width 60
  #  APSFrameGrid .grid -parent $parent -xList {x1 x2}
  #  set w1 $parent.grid.x1
  #  set w2 $parent.grid.x2
  #  APSFrame .hp -parent $w1 -label "Hp vec display setup"
  #  set w1 $w1.hp.frame
   set w1 $parent 
    set w2 $parent
    
    APSLabeledEntry .buf -parent $w1 -label "Capture buffer length (ms):" \
        -width 15 -textVariable captureBufferLength \
        -contextHelp "Enter the value of capture buffer length, valid range is 0 - 350 ms."
    bind $w1.buf.entry <Leave> "CheckCaptureBufferLength"
    APSLabeledEntry .overlap -parent $w1 -label "Time overlap (%):" \
        -width 15 -textVariable timeOverlap \
        -contextHelp "The value for time overlapping."
    APSLabeledEntry .ch2pos -parent $w1 -label "Measurement stop time (ms):" -width 15 \
        -textVariable stopTime -contextHelp "the stop time (ms) of measurement." 
   # APSFrame .proc -parent $w2 -label "Display and Process Parameters."
   # set w2 $w2.proc.frame
     APSLabeledEntry .yup -parent $w2 -label "Y-axis upper limit: " -width 15 \
      -textVariable yUpperLimit \
      -contextHelp "enter the y upper limit for displaying"
    APSRadioButtonFrame .recall -parent $w1 -label "Recall Booster State for setup vsa?" \
        -buttonList {Yes No} -packOption "-side top" \
        -valueList {1 0} -variable recallBooState \
        -contextHelp "choose whether to recall BOOTUNES state for hp vec display" \
        -orientation horizontral
    APSRadioButtonFrame .setupvsa -parent $w2 -label "Setup VSA before taking measurement?" \
        -buttonList {Yes No} -packOption "-side top" \
        -valueList {1 0} -variable setupVSA \
        -contextHelp "choose whether to recall BOOTUNES state for hp vec display" \
        -orientation horizontral
    APSRadioButtonFrame .enable -parent $w2 -label "Enable booster pinger before taking measurement?" \
        -valueList {1 0} -variable enablePinger -buttonList "Yes No" \
        -contextHelp "choose whether to recall BOOTUNES state for hp vec display" \
        -orientation horizontral
   
    
}

proc MakeActionWidget {widget args} {
    set parent .userFrame
    APSStrictParseArguments {parent}
    APSFrame $widget -parent $parent -relief flat
    set w $parent$widget.frame 
   
    APSButton .setup -parent $w -text "SetupVSA" -command "SetupVSA" \
        -contextHelp "Press to setup VSA for booster tune measurement"
    #APSButton .setup1 -parent $w -text "SetupBoosterPinger" \
        #    -command "SetupBoosterPinger"
    APSButton .meas -parent $w -text "Take Measurement" -command "TakeMeasurement" \
        -contextHelp "After this button is pressed, if Setup VSA is yes, it sets up VSA; and then if enable booster pinger is Yes, it enables booster pinger--> sends beam to booster --> fills buffer --> disables booster pinger when fill buffer is done; otherwise do nothing; finally, it starts measurement as click the \"Meas\" button on the VSA GUI and waits until measurement is done."
    APSButton .acquire -parent $w -text "GetCaptureBuffer" -command "GetCaptureBuffer" \
        -contextHelp "Downloads the caputered buffer to an sdds file."
    APSButton .display -parent $w -text "Display VSA" -command "exec hpVecDisplay -unit boo" \
        -contextHelp "bring up the hpvec display."
    APSButton .plot -parent $w -text "PlotData" -command "PlotData" \
        -contextHelp "Plot the data of output file where the data was stored."
   # APSDisableButton $w.setup1.button
}

 
proc SetupVSA {args} {
    global timeOverlap captureBufferLength recallBooState  stopTime
    
    set result [exec ping hpvecboo]
    if [string compare -nocase $result "hpvecboo is alive"]!=0 {
        return -code error "Can not connect to hp vec network!"
    }
    if $recallBooState {
        if [catch {exec hpSocketSend hpvecboo \
                       "MMEM:LOAD:STAT 1,'NVRAM:BOOTUNES.STA'" } result] {
            return -code error "Can not restore booster tune VSA configuration: $result"
        }
        after 60000
    }
    set bufferLen [expr $captureBufferLength * 0.001]
    if [catch {exec hpSocketSend hpvecboo "SWE:TIME:OVER $timeOverlap PCT"
        exec  hpSocketSend hpvecboo "TCAP1:LENG $bufferLen S"
        exec hpSocketSend hpvecboo "TCAP2:STOP [expr $stopTime * 0.001] S"} result] {
        return -code error $result
    }
    
}

set InitialBEKValue 23.0
proc SetupBoosterPinger {args} {
    global InitialBEKValue
    if [catch {exec cavget -list=B:EK:VoltageSetSendAO -pend=30} InitialBEKValue] {
        return -code error "Can not read value of B:EK:VoltageSetSendAO: $InitialBEKValue"
    }
    if {$InitialBEKValue=="?"} {
        return -code error "Can not read value of B:EK:VoltageSetSendAO."
    }
    if [catch {exec cavput -list=B:EK:VoltageSetSendAO=1.0 -pend=30} result] {
        return -code error "$result"
    }
    if [catch {exec cavget -list=Mt:Bs:Pinger:ChargeTimeAO.VAL,Mt:Bs:Pinger:RepRateAO.VAL -pend=30} valList] {
        return -code erorr "$result"
    }
    set time [lindex $valList 0]
    set rate [lindex $valList 1]
    if $time!=2.4 {
        if [catch {exec cavput -list=Mt:Bs:Pinger:ChargeTimeAO.VAL=2.4 -pend=30}  result] {
            return -code error $result
        }
    }
    if $rate!=40 {
        if [catch {exec cavput -list=Mt:Bs:Pinger:RepRateAO.VAL=40 -pend=30} result] {
            return -code error $result
        }
    }
    if [catch {exec cavput -list=Mt:Bs:Pinger:EnableBO.VAL=1 -pend=30} result] {
        return -code error $result
    }
}

proc TakeMeasurement {args} {
    global Timeout outputFile dataDirectory rootname setupVSA enablePinger
    
    if $setupVSA {
        SetStatus "Setup VSA..."
        if [catch {SetupVSA} result] {
            SetStatus "Error in setup VSA: $result"
            return
        }
    }
    if $enablePinger {
        SetStatus "Enable booster pinger..."
        if [catch {SetupBoosterPinger} result] {
            SetStatus "Error in enabling booster pinger: $result"
            return
        }
        SetStatus "Send beam to booster..."
        if [catch {TogglePulsedMagnetEnables -location GuntoBoosterInj } result] {
            SetStatus "$result"
            DisableBoosterPinger
            return
        }
        if [catch {TogglePulsedMagnetEnables -location GuntoBoosterExt } result] {
            SetStatus "$result"
            DisableBoosterPinger
            return
        }
        SetStatus "Fill buffer..."
        if [catch {exec hpSocketSend hpvecboo "TCAP1" } result] {
            SetStatus "Unable to fill buffer: $result"
            DisableBoosterPinger
            return
        }
        after 10000 
        SetStatus "Disable booster pinger (it is not good if fill buffer is not done at this time..."
        DisableBoosterPinger
    } else {
        SetStatus "Fill buffer..."
        if [catch {exec hpSocketSend hpvecboo "TCAP1" } result] {
            SetStatus "Unable to fill buffer: $result"
            DisableBoosterPinger
            return
        }
        after 10000
    }
    after 5000
    SetStatus "Start measurement (it may take several minutes)..."
    if [catch {exec hpSocketSend hpvecboo "ABOR;*WAI"} result] {
        SetStatus "Unable to start measurement: $result"
        DisableBoosterPinger
        return
    }
    update
    set timeout [expr $Timeout + [clock seconds]]
    while {[clock seconds]<$timeout} {
        after 1000
        update
        set oper [exec hpSocketSend hpvecboo "STAT:OPER:COND?"]
        if {$oper==32} {
            break
        }
    }
    set oper [exec hpSocketSend hpvecboo "STAT:OPER:COND?"]
    if {$oper!=32} {
        SetStatus "Measurement timeout."
        return
    }
    SetStatus "Measurement done."
}
proc GetCaptureBuffer {args} {
    global dataDirectory rootname stopTime outputFile
    SetStatus "Downloading spectrum to file..."
    set outputFile $dataDirectory/${rootname}-[clock format [clock seconds] -format "%Y-%m%d.%H:%M:%S"]
    update
    if [catch {exec hpSocketSend hpvecboo "SWE:TIME?"} sweepTime] {
        SetStatus "$sweepTime"
        return
    }
    set sweepTime [expr $sweepTime * 1000]
    set endBuffer [expr int($stopTime / $sweepTime)]
    
    if [catch {exec hpSocketSend hpvecboo "DISP:WIND1:TRAC:BUFF?"} bufferDepth] {
        SetStatus "$bufferDepth"
        return
    }
    update
    if {$endBuffer>$bufferDepth} {
        set endBuffer $bufferDepth
    }
    if [catch {exec hpVecTrace -hpvecboo a $outputFile -buffertransfer=1,$endBuffer} result] {
        SetStatus "$result"
        return
    }
    update
    catch {exec sddsplot -same=y -sep=page -split=page -limits=ymin=0,ymax=$yUpperLimit \
               $outputFile -col=Frequency,Waveform & }
    SetStatus "done."
}

set outputFile ""
proc PlotData {args} {
    global outputFile yUpperLimit 
    if ![string length $outputFile] {
        SetStatus "No data was acquired yet."
        return
    }
    if ![file exist $outputFile] {
        SetStatus "$outputFile does not exist!"
        return
    }
    catch {exec sddsplot -same=y -sep=page -split=page -limits=ymin=0,ymax=$yUpperLimit \
               $outputFile -col=Frequency,Waveform & }
}
proc DisableBoosterPinger {} {
    global InitialBEKValue 
    if [catch {exec cavput -list=B:EK:VoltageSetSendAO=$InitialBEKValue,Mt:Bs:Pinger:EnableBO.VAL=0 -pend=30} result] {
        return -code error "$result"
    }
}
MakeSaveWidget .save
MakeActionWidget .action
