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

# $Log: CPUcheckOut,v $

# Revision 1.1  01/29/17 19:46:47:  xiaoam
# First installation for auto CPU checkout application. The old name was CPUorbitCollection.

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

APSStandardSetup

set CVSRevisionAuthor "\$Revision: 1.1 $ \$Author: xiaoam $"

APSApplication . -name "CPUcheckOut" -version \
  $CVSRevisionAuthor -overview "Collects CPU perturbation data for each selected mode to check it working status."

proc DPRTFBOnOff {args} {
    APSParseArguments {mode}

    global apshpFilterCutoffVert apshpFilterCutoffHoriz apshpFilterInitialVert apshpFilterInitialHoriz
    global apshpFilterRampPoints apshpFilterRampInterval
    APSMpSetRTFBGlobalParameters -readonly 1

    if {$mode==1} {set mode On}
    if {$mode==0} {set mode Off}
    switch $mode {
        On {
            set xstatus [exec caget -t -n DP:S:OrbitControlLawXSDDS.RUN]
            set ystatus [exec caget -t -n DP:S:OrbitControlLawYSDDS.RUN]
            if {!$xstatus || !$ystatus} {
                if [catch {exec cavput -list=DP:S: \
                             -list=OrbitControlLawX,OrbitControlLawY \
                             -list=SDDS.SUSP=0 \
                         } result ] {
                    return -code error "$result"
                }
            }
            set hloop [exec caget -t -n SRFB:GBL:HLoopStatusBI.VAL]
            set vloop [exec caget -t -n SRFB:GBL:VLoopStatusBI.VAL]
            set hvloop [exec caget -t -n SRFB:GBL:LoopStatusBI.VAL]
            if {!$hloop || !$vloop || !$hvloop} {
                if [catch {APSMpRTFBCloseLoops -hpFilterCutoffVert $apshpFilterCutoffVert \
                             -hpFilterCutoffHoriz $apshpFilterCutoffHoriz \
                             -hpFilterInitialVert $apshpFilterInitialVert \
                             -hpFilterInitialHoriz $apshpFilterInitialHoriz \
                             -hpFilterRampPoints $apshpFilterRampPoints \
                             -hpFilterRampInterval $apshpFilterRampInterval \
                             -statusCallback "set status" } result] {
                    set status "APSMpRTFBCloseLoops: $result"
                    return
                }   
            }
            SetStatus "Done DPRTFBOnOff mode=$mode"
        }
        Off {
            if [catch {exec cavput -list=S:RC:OrbitControlLawXC,S:RC:OrbitControlLawYC -list=.SUSP=1} result ] {
                return -code error "$result"
            }
            if [catch {exec cavput -list=DP:S: \
                         -list=OrbitControlLawX,OrbitControlLawY \
                         -list=SDDS.SUSP=1 \
                     } result ] {
                return -code error "$result"
            }
            if [catch {APSMpRTFBResetOpenLoops -hpFilterInitialVert $apshpFilterInitialVert \
                         -hpFilterInitialHoriz $apshpFilterInitialHoriz \
                         -runHloop 1 -runVloop 1 } result] {
                return -code error "$result"
            }   
            SetStatus "Done DPRTFBOnOff mode =$mode"
        }
    }
    after 1000
    return
}

proc SetStatus {text} {
    global status
    set status $text
    update
}

proc CollectData {args} {
    APSParseArguments {outputDir comment abortVar}
    global $abortVar CPUMode

    # Step 0: Condition CPU in AC mode
    if [catch {DPRTFBOnOff -mode On} result] {
        return -code error "$result"
    }
    exec cavput -list=ID04b:on_off.VAL=On
    exec cavput -list=ID04b:set_V_coil.VAL=0
    exec cavput -list=ID04b:set_H_coil.VAL=0
    exec cavput -list=ID04b:DesiredMode.VAL=4
    exec cawait -interval=0.5 -waitFor=ID04b:feedback.VAL,sameAs=Ready
    SetStatus "Now doing CPU standardization twice..."
    for {set i 0} {$i<2} {incr i} {
        if ([set $abortVar]) break
        exec cavput -list=ID04b:set_V_coil.VAL=400
        while (1) {
            after 1000
            update
            if ([string match "*Ready*" [exec cavget -list=ID04b:feedback.VAL]]) break
            if ([set $abortVar]) break
        }
        exec cavput -list=ID04b:set_V_coil.VAL=0
        while (1) {
            after 1000
            update
            if ([string match "*Ready*" [exec cavget -list=ID04b:feedback.VAL]]) break
            if ([set $abortVar]) break
        }
    }
    SetStatus "Done with CPU standardization."

    # Step 1: Doing measurement
    set dir [pwd]
    cd $outputDir
    set monFile /home/helios/oagData/sr/IDs/CPU/DCmodes/CPU+orbit.mon

    set videoNum [exec cavget -list=S:VID1:numToAvgC]
    exec cavput -list=S:VID1:numToAvgC=30

    set modeList "$CPUMode(AC) $CPUMode(CW) $CPUMode(CCW) $CPUMode(V) $CPUMode(H)"
    set modeValue "4 0 1 2 3"
    set modeName "AC CW CCW V H"
    foreach run $modeList mode $modeValue Name $modeName {
        if ([set $abortVar]) break
        if {!$run} continue
        SetStatus "Now doing CPU mode $Name..."
        set coil ID04b:set_V_coil.VAL
        set IMax 400
        set rate 2
        # for H mode (v coil only), ramp slowly
        if {$mode==3} {
            set rate 6
        }
        # for V mode, change H coil
        if {$mode==2} {
            set coil ID04b:set_H_coil.VAL
            set IMax 1600
        }

        # Step 1a: Cycle mode twice before measurement
        exec cavput -list=ID04b:rate_=0.5 -list=up,down
        if [catch {DPRTFBOnOff -mode On} result] {
            return -code error "$result"
        }
        exec cavput -list=ID04b:on_off.VAL=On
        exec cavput -list=ID04b:set_V_coil.VAL=0
        exec cavput -list=ID04b:set_H_coil.VAL=0
        exec cavput -list=ID04b:DesiredMode.VAL=$mode
        exec cawait -interval=0.5 -waitFor=ID04b:feedback.VAL,sameAs=Ready 
        SetStatus "Now doing CPU mode $Name standardization twice..."
        for {set i 0} {$i<2} {incr i} {
            if ([set $abortVar]) break
            exec cavput -list=$coil=$IMax
            while (1) {
                after 1000
                update
                if ([string match "*Ready*" [exec cavget -list=ID04b:feedback.VAL]]) break
                if ([set $abortVar]) break
            }
            exec cavput -list=$coil=0
            while (1) {
                after 1000
                update
                if ([string match "*Ready*" [exec cavget -list=ID04b:feedback.VAL]]) break
                if ([set $abortVar]) break
            }
        }
        SetStatus "Done with CPU mode $Name standardization."

        # Step 1b: Perform measurement with DP/RTFB on
        exec cavput -list=ID04b:rate_=$rate -list=up,down
        SetStatus "Now doing CPU mode $Name - DP/RTFB: on ..."
        SetStatus "Launching sddsmonitor..."
        if [catch {set pid [exec sddsmonitor $monFile $Name-On -daily \
                              -step=1200 -interval=1 \
                              "-comment=Comment,[APSMakeSafeQualifierString $comment]" &] \
                 } result ] {
            SetStatus $result
            return
        }
        SetStatus "sddsmonitor launched..."

        for {set i 0} {$i<10} {incr i} {
            if [set $abortVar] break
            after 1000
            update
        }
        exec cavput -list=$coil=$IMax
        while (1) {
            after 1000
            update
            if ([string match "*Ready*" [exec cavget -list=ID04b:feedback.VAL]]) break
            if ([set $abortVar]) break
        }
        for {set i 0} {$i<10} {incr i} {
            if [set $abortVar] break
            after 1000
            update
        }
        exec cavput -list=$coil=0
        while (1) {
            after 1000
            update
            if ([string match "*Ready*" [exec cavget -list=ID04b:feedback.VAL]]) break
            if ([set $abortVar]) break
        }
        for {set i 0} {$i<10} {incr i} {
            if [set $abortVar] break
            after 1000
            update
        }
        SetStatus "Killing sddsmonitor..."
        if [catch {exec kill -KILL $pid} result] {
            SetStatus $result
        }
        SetStatus "Done with CPU mode $Name - DP/RTFB: on."

        # Step 1c: Perform measurement with DP/RTFB off
        if [catch {DPRTFBOnOff -mode Off} result] {
            return -code error "$result"
        }
        SetStatus "Now doing CPU mode $Name - DP/RTFB: off ..."

        SetStatus "Launching sddsmonitor..."
        if [catch {set pid [exec sddsmonitor $monFile $Name-Off -daily \
                              -step=1200 -interval=1 \
                              "-comment=Comment,[APSMakeSafeQualifierString $comment]" &] \
                 } result ] {
            SetStatus $result
            return
        }
        SetStatus "sddsmonitor launched..."

        for {set i 0} {$i<10} {incr i} {
            if [set $abortVar] break
            after 1000
            update
        }
        exec cavput -list=$coil=$IMax
        while (1) {
            after 1000
            update
            if ([string match "*Ready*" [exec cavget -list=ID04b:feedback.VAL]]) break
            if ([set $abortVar]) break
        }
        for {set i 0} {$i<10} {incr i} {
            if [set $abortVar] break
            after 1000
            update
        }
        exec cavput -list=$coil=0
        while (1) {
            after 1000
            update
            if ([string match "*Ready*" [exec cavget -list=ID04b:feedback.VAL]]) break
            if ([set $abortVar]) break
        }
        for {set i 0} {$i<10} {incr i} {
            if [set $abortVar] break
            after 1000
            update
        }
        SetStatus "Killing sddsmonitor..."
        if [catch {exec kill -KILL $pid} result] {
            SetStatus $result
        }
        SetStatus "Done with CPU mode $Name - DP/RTFB: off."
        SetStatus "Done with CPU mode $Name."
    }

    #Step 2: Return to original setup
    exec cavput -list=S:VID1:numToAvgC=$videoNum
    exec cavput -list=ID04b:rate_=0.5 -list=up,down
    exec cavput -list=ID04b:on_off.VAL=Off
    while (1) {
        after 1000
        update
        if ([string match "*Off*" [exec cavget -list=ID04b:feedback.VAL]]) break
    }
    if [catch {DPRTFBOnOff -mode On} result] {
        return -code error "$result"
    }
    cd $dir
    return
}

proc plotData {} {
    global Year Date outputDir
    set dir [pwd]
    cd $outputDir
    set fileList [lsort [glob -nocomplain *-$Year-???-$Date.????]]
    set dataList [APSChooseItemFromList \
                     -name "Data Set Selection" \
                     -itemList $fileList \
                     -returnList $fileList \
                     -returnIndices 0 \
                     -multiItem 1 \
                     -contextHelp "Select a file for plotting."]

    foreach file $dataList {
        APSSetVarAndUpdate status "Processing $file..."
        if ([string match "*Off*" $file]) {
            set options "-layout=1,2 -tick=xtime"
            exec sddsprocess $file -pipe=out \
              -process=S*:msAve:?:ErrorCC,first,%sFirst \
              -process=S*:msAve:?:ErrorCC,standarddeviation,%sStdDev \
              "-redef=col,%s,%s %sFirst -,sel=S*:msAve:?:ErrorCC" \
              | sddsrowstats -pipe=in \
              $file.rowstats \
              -standardDeviation=XOrbitRMS,S*:msAve:x:ErrorCC \
              -standardDeviation=YOrbitRMS,S*:msAve:y:ErrorCC 
            lappend options -col=Time,?OrbitRMS $file.rowstats \
              -topline=@Comment -file -factor=ymult=1e3 \
              {-ylabel=RMS Orbit (um)} -grap=line,vary -leg
            lappend options -col=Time,?coilReadback \
              $file.rowstats -topline=@Comment -file -ylabel=edit=ei/(A)/ \
              -grap=line,type=2 -yscale=id=2 -end
            lappend options -col=Time,*30HzBW $file \
              -topline=@Comment -file  {-ylabel=30 Hz (um)} -grap=line,vary -leg
            lappend options -col=Time,?coilReadback \
              $file -topline=@Comment -file -ylabel=edit=ei/(A)/ \
              -grap=line,type=2 -yscale=id=2 -end
            lappend options -col=Time,*VarBW $file \
              -topline=@Comment -file  {-ylabel=100 Hz (um)} -grap=line,vary -leg
            lappend options -col=Time,?coilReadback \
              $file -topline=@Comment -file -ylabel=edit=ei/(A)/ \
              -grap=line,type=2 -yscale=id=2 -end
            lappend options -col=Time,*FullBW $file \
              -topline=@Comment -file {-ylabel=Full Hz (um)} -grap=line,vary -leg
            lappend options -col=Time,?coilReadback \
              $file -topline=@Comment -file -ylabel=edit=ei/(A)/ \
              -grap=line,type=2 -yscale=id=2 -end
        }
        if ([string match "*On*" $file]) {
            set options "-tick=xtime"
            lappend options -col=Time,couplingEffective $file -topline=@Comment -file \
              -grap=line,vary -leg -yscale=id=coup
            lappend options -col=Time,?coilReadback \
              $file -topline=@Comment -file -file -ylabel=edit=ei/(A)/ \
              -grap=line,type=2 -yscale=id=2 -end
        }
        if [catch {eval exec sddsplot \
                     $options & \
                 } result] {
            APSSetVarAndUpdate status "PlotData: $result"
            return
        }
    }

    APSSetVarAndUpdate status "Done."
    cd $dir
    return
}

set args $argv
set abortRun 0
set comment ""
set outputDir /home/helios/oagData/sr/IDs/CPU/Measurement
APSParseArguments {comment}
set systemTime [clock seconds]
set Year [clock format $systemTime -format %Y]
set Date [clock format $systemTime -format %m%d]

set status "Working..."
APSScrolledStatus .status -parent .userFrame -textVariable status -width 50
APSLabeledEntry .outputDir -parent .userFrame \
  -label "Output directory:" -textVariable outputDir \
  -contextHelp "Enter a name for the output file directory." -width 50
APSLabeledEntry .comment -parent .userFrame -label "Comment: " -textVariable comment \
  -width 55 \
  -contextHelp "Enter a comment to be written as a parameter to the output file."

set CPUMode(CW) 1
set CPUMode(CCW) 1
set CPUMode(V) 1
set CPUMode(H) 1
set CPUMode(AC) 1
APSCheckButtonFrame .mode -parent .userFrame -orientation horizontal \
  -label "CPU mode for measuring: " -contextHelp "Choose CPU mode for measurement." \
  -variableList {CPUMode(CW) CPUMode(CCW) CPUMode(V) CPUMode(H) CPUMode(AC)}  \
  -buttonList {CW CCW V H CW/CCW} 
APSLabeledEntry .year -parent .userFrame -label "Measurement Year\[yyyy\]: " -textVariable Year \
  -width 55 \
  -contextHelp "Enter the measurement year."
APSLabeledEntry .date -parent .userFrame -label "Measurement Date\[mmdd\]: " -textVariable Date \
  -width 55 \
  -contextHelp "Enter the measurement date."

APSButton .run -parent .userFrame -text Collect -command \
  { \
      APSDisableButton .userFrame.run.button 
      APSEnableButton .userFrame.stop.button
      catch {exec StripTool /home/helios/oagData/sr/IDs/CPU/stripPlot.mon &}
      catch {CollectData -outputDir $outputDir -comment $comment \
               -abortVar abortRun} status
      catch {exec play -q -v 3 /usr/local/oag/sounds/game_over.au}
      exec cavput -list=ID04b:on_off.VAL=Off
      update idletasks
      APSDisableButton .userFrame.stop.button
      APSEnableButton .userFrame.run.button
      SetStatus "Done with all checkout $abortRun"
  } \
  -contextHelp "Collects CPU perturbation data. Uses monitor file /home/helios/oagData/sr/IDs/CPU/DCmodes/CPU+orbit.mon"
APSButton .stop -parent .userFrame -text Abort -command \
  { set abortRun 1} \
  -contextHelp "Aborts run."

APSButton .plot -parent .userFrame -text Plot -command \
  { \
      catch {plotData} status
  } \
  -contextHelp "Plot Measurement Result"

set status Ready.
update
APSInfoWindow .info -width 60 -name "CPU Checkout Procedure" -infoMessage "This window can be left open!!!\n\nStep 1: Injecte 324 into SR.\nStep 2: Run DP and RTFB in both plane.\nStep3: Hit the run button;\n       Watch the pop-up stripTools for CPU PS moving;\n       The program should do all the left for you, enjoy!\n\nIn case program aborted - Turn off CPU power supply." -modal 0
# Local Variables:
# mode: tcl
# indent-tabs-mode: nil
# End:
