#!/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)]
APSDebugPath

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

APSApplication . -name "SRtrajectoryResponse" -version $CVSRevisionAuthor \
  -overview "SRtrajectoryResponse measures the trajectory repsonse to a corrector,
then compares the results with the model trajectory response of lattices of various tunes."

set SRTrajectoryStatus "Initializing ..."
APSScrolledStatus .status -parent .userFrame -width 60 \
  -textVariable SRTrajectoryStatus 

proc SetSRTrajectoryStatus {text} {
    global SRTrajectoryStatus
    set SRTrajectoryStatus $text
    update
    bell
}

proc MakeInputFrame {widget args} {
    APSStrictParseArguments {parent}
    
    set w $parent$widget.frame
    APSFrame $widget -parent $parent -label "Input parameters"

    # select corrector (plane) and amplitude
    APSLabeledEntry .outputDir -parent $w \
      -label "Output directory:" -textVariable outputDir \
      -contextHelp "Enter a name for the output file directory." -width 50
    APSButton .daily -parent $w.outputDir -packOption "-side top" \
      -text "daily" -size small \
      -command {set outputDir [APSGoToDailyDirectory -subdirectory response]}
    APSLabeledEntry .root -parent $w -label "Root name of file: " \
      -textVariable root \
      -contextHelp "Enter the root name of the file for the processed output <root>-nnn."
    APSLabeledEntry .index -parent $w -label "Index: " -textVariable index \
      -contextHelp "Enter the index (minus 1) to be part of the name of the output file. The index is incremented by 1 before execution."
    APSLabeledEntry .comment -parent $w -label "Comment: " -textVariable comment \
      -width 55 \
      -contextHelp "Enter a comment to be written as a parameter to the output file."

    APSRadioButtonFrame .plane -parent $w \
      -buttonList {H V} -label [format %-20s Plane] \
      -variable Plane \
      -commandList {{setTrajPlane H} {setTrajPlane V}} \
      -valueList {H V} \
      -orientation Horizontal -packOption "-anchor w -side top" \
      -contextHelp "Selects the plane for trajectory measurement."
    APSLabeledOutput .corr -parent $w -label "Corrector used: " \
      -textVariable corr -width 6 \
      -contextHelp "Corrector for trajectory measurement in plane selected."
    APSLabeledEntry .amplitude -parent $w -label "Amplitude (A): " \
      -textVariable amplitude -width 6 \
      -contextHelp "Enter the desired value for corrector amplitude."
    APSLabeledEntry .ave -parent $w -label "Averager weight: " \
      -textVariable average -width 6 \
      -contextHelp "Enter the averager weight for trajectory. Choosing n will make 2^n averages."
    
    # collect trajectory before and after
    APSButton .collect -parent $parent \
      -text "Take Data"  \
      -packOption "-side left" \
      -command {incr index; CollectData -outputDir $outputDir -root $root -index $index \
                  -corrector $corr -plane $Plane -average $average \
                  -amplitude $amplitude} \
      -contextHelp "Collects trajectory data for two values of the corrector"
    APSButton .process -parent $parent \
      -text "Process"  \
      -packOption "-side left" \
      -command {ProcessTrajectory -outputDir $outputDir -root $root -index $index \
                  -corrector $corr -plane $Plane} \
      -contextHelp "Processes trajectory data for two values of the corrector"
    APSButton .plot -parent $parent \
      -text "Plot"  \
      -packOption "-side left" \
      -command {PlotTrajectory -outputDir $outputDir -root $root -index $index \
                  -corrector $corr -plane $Plane \
                  -sector $sector -numSector $numSector} \
      -contextHelp "Plots trajectory data for two values of the corrector with the difference."
    APSButton .compare -parent $parent \
      -text "Compare/Match"  \
      -packOption "-side left" \
      -command {CompareTrajectory -corrector $corr -plane $Plane} \
      -contextHelp "Compares and matches with trajectory calculated from models of different tunes."

    APSLabeledEntry .sectorCompare -parent $w -label "Start Sector to compare: " \
      -textVariable sector -width 6 \
      -contextHelp "Enter the desired sector to compare measurement with models."
    APSLabeledEntry .numSector -parent $w -label "Number of sectors to compare: " \
      -textVariable numSector -width 6 \
      -contextHelp "Enter the number of sectors to compare measurement with models."
}

proc setTrajPlane {Plane} {
    global corr
    switch $Plane {
        H { set corr S1A:H1 }
        V { set corr S1A:V1 }
    }
}

proc CollectData {args} {
    APSStrictParseArguments {outputDir root index plane corrector \
                               average amplitude}
    set delta $amplitude
    set monitorDir /home/helios/oagData/sr/sddsmonitorFiles
  
    if {![string length $outputDir] || ![string length $root]} {
        APSSetVarAndUpdate SRTrajectoryStatus "Output directory or root not given."
        return
    }

    set output $outputDir/$root-[format %03ld $index]
    if [file exists ${output}.${corrector}.raw] {
        APSSetVarAndUpdate SRTrajectoryStatus "File ${output}.${corrector}.raw exists."
        return
    }

    exec sddsprocess $monitorDir/SROrbit-ms.vmon SROrbit-ms.vmon \
      -match=col,Suffix=:sum.RVAL,!

    # make corrector monitor file
    catch {file delete -force -- corr.mon}
    set fid [open corr.mon w]
    puts $fid "SDDS1"
    puts $fid "&column name=ControlName type=string &end"
    puts $fid "&data mode=ascii no_row_counts=1 &end"
    puts $fid "$corrector:CurrentAO"
    close $fid

    APSSetVarAndUpdate SRTrajectoryStatus "cavput -delta=factor=1 -list=SFB:, -list=${corrector}:CurrentAO=$delta"
    exec cavput -delta=factor=1 -list=SFB:, -list=${corrector}:CurrentAO=$delta -pend=5
    exec cavput -list=S:bpm:memscan_wt_ao.VAL=$average

# wait for some time for correctors and bpms to settle
    set correctorSettling [expr int($amplitude / 4.0 + 1)]
    set interval [expr int(pow(2,$average))]
    APSSetVarAndUpdate SRTrajectoryStatus "Averaging interval for bpms: $interval seconds"
    APSSetVarAndUpdate SRTrajectoryStatus "Waiting for corrector and trajectory..."
    after [expr 1000 * ($correctorSettling + $interval)]
    set monID [open "|sddsvmonitor -erase \
        -rootname=$monitorDir/SROrbit-Rootnames.vmon \
        -suffixes=SROrbit-ms.vmon \
        ${output}.${corrector}.raw \
        -scalars=corr.mon \
        -singleShot=noprompt -steps=2" w]
    puts $monID "y"
    flush $monID
    after 3000
    APSSetVarAndUpdate SRTrajectoryStatus "Setting -delta=factor=-2 -list=${corrector}:CurrentAO=$delta"
    exec cavput -delta=factor=-2 -list=SFB:, -list=${corrector}:CurrentAO=$delta -pend=5
    APSSetVarAndUpdate SRTrajectoryStatus "Waiting for corrector and trajectory..."
    after [expr 1000 * ($correctorSettling + $interval)]
    puts $monID "y"
    flush $monID
    after 1000
    catch {close $monID}
    APSSetVarAndUpdate SRTrajectoryStatus "cavput -delta=factor=1 -list=SFB:, -list=${corrector}:CurrentAO=$delta"
    exec cavput -delta=factor=1 -list=SFB:, -list=${corrector}:CurrentAO=$delta -pend=5
    APSSetVarAndUpdate SRTrajectoryStatus "Done."
}

proc ProcessTrajectory {args} {
    global OAGGlobal
    APSParseArguments {outputDir root index plane corrector}

    set output $outputDir/$root-[format %03ld $index]
    if ![file exists ${output}.${corrector}.raw] {
        APSSetVarAndUpdate SRTrajectoryStatus "File $output.${corrector}.raw doesn't exists."
        return
    }
    switch $plane {
        H {set coord x}
        V {set coord y}
    }

# measurement is in mm/A 
    set factor [expr 150 / 1.2]
    set xrefFile $OAGGlobal(SRLatticesDirectory)/default/aps.twi
    exec sddsenvelope ${output}.${corrector}.raw -pipe=out \
      -copy=Rootname -slope=$corrector:CurrentAO,:ms:$coord \
      | sddsxref -pipe $xrefFile \
      -match=Rootname=ElementName -take=s \
      | sddsprocess -pipe=in ${output}.${corrector}.diff \
      -match=col,Rootname=*P0,! \
      -convertUnits=col,:ms:${coord}Slope,m/rad,mm,$factor

    APSSetVarAndUpdate SRTrajectoryStatus "Processing done."
    return

}

proc PlotTrajectory {args} {
    APSParseArguments {outputDir root index plane corrector sector numSector}

    set output $outputDir/$root-[format %03ld $index]
    if ![file exists ${output}.${corrector}.diff] {
        APSSetVarAndUpdate SRTrajectoryStatus "File $output.${corrector}.diff doesn't exists."
        return
    }
    switch $plane {
        H {set coord x}
        V {set coord y}
    }
    set refDataDir /home/oxygen/SAJAEV/APS/FIRST_TURN
    set refDataFile Q${coord}.mon

    set tmpfile /tmp/[APSTmpString]
    set factor [expr 5e3]
    exec sddsprocess $refDataDir/$refDataFile $tmpfile \
      -convertUnits=col,C${coord},m/rad,m,$factor \
      -print=para,TuneString,nu${coord}=%5.2f,nu${coord}

#    exec sddsplot -axes=x \
      -enum=int=18 \
      -grap=sym,conn=sub,sca=2,sub=1 \
      -col=Rootname,:ms:${coord}Slope ${output}.${corrector}.diff -omni \
      -match=col,Rootname=*P0,! \
      -leg=spec=Measured \
      -col=ElementName,C${coord} $tmpfile \
      -match=col,ElementName=*P0,! \
      -leg=spec=Models \
      -split=pages -sep=pages -grap=sym,conn,sca=2 \
      &

    set sStart [expr ($sector - 1) * 27.6]
    set sEnd [expr ($sector + $numSector - 1) * 27.6]
    if {$sEnd > 1104} {
        set sEnd 1104
    }
    exec sddsplot -axes=x \
      -same \
      -grap=sym,conn=sub,sca=2,sub=1 \
      -col=Rootname,:ms:${coord}Slope ${output}.${corrector}.diff -omni \
      -match=col,Rootname=*P0,! \
      -filter=col,s,$sStart,$sEnd \
      -leg=spec=Measured \
      -col=ElementName,C${coord} $tmpfile \
      -match=col,ElementName=*P0,! \
      -filter=col,s,$sStart,$sEnd \
      -leg=para=TuneString -topline=@TuneString \
      -split=pages -sep=pages -grap=sym,conn,sca=2 \
      &
    exec sddsplot -axes=x \
      -same \
      -grap=sym,conn=sub,sca=2,sub=1 \
      -col=s,:ms:${coord}Slope ${output}.${corrector}.diff -omni \
      -match=col,Rootname=*P0,! \
      -filter=col,s,$sStart,$sEnd \
      -leg=spec=Measured \
      -col=s,C${coord} $tmpfile \
      -match=col,ElementName=*P0,! \
      -filter=col,s,$sStart,$sEnd \
      -leg=para=TuneString -topline=@TuneString \
      -split=pages -sep=pages -grap=sym,conn,sca=2 \
      &
    APSSetVarAndUpdate SRTrajectoryStatus "Plotting done."
}

proc CompareTrajectory {args} {
    APSSetVarAndUpdate SRTrajectoryStatus "Command not implemented yet."
    return
}

MakeInputFrame .input -parent .userFrame
set SRTrajectoryStatus "Ready."
set abortRun 0
set outputDir .
set index 0
set root Tweak
set Plane H
setTrajPlane $Plane
set amplitude 20
set average 5
set sector 38
set numSector 2
set outputDir [APSGoToDailyDirectory -subdirectory response]
update
