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

set args $argv
set CVSRevisionAuthor "H. Shang"


APSApplication . -name optimizeLinacL3Charge -version $CVSRevisionAuthor \
  -overview {This interface optimizer linac L3 charge.}

proc SetL3ChargeStatus {text} {
    global L3chargeStatus
    set L3chargestatus "[exec date] $text"
    update
}
set L3chargeStatus Ready.
APSScrolledStatus .status -parent .userFrame -width 60\
        -textVariable L3chargeStatus 

proc GetGunSelection {} {
    global gun
    if [catch {exec cavget -list=L1:RFG:RF:SW2:positionMI -printErrors -pend=10} gun] {
        puts stderr "Error reading RF gun selection."
        exit 1
    }
   # set gun RG1
}

proc LogFile {text} {
    global logID
    puts $logID "[exec date] $text"
    flush $logID
}

proc Start {args} {
    global outputDir evals 1dscan method cycles stepSize tolerance noise gun runSteering dmatChoice magnets rcdsVerbose rcdsUseMin
    global xPosTol yPosTol objectPV pyoption dryRun
    
    if [catch {exec cavget -list=L1:RFG:RF:SW2:positionMI -printErrors -pend=10} gun1] {
        return -code error "Unable to read RG gun selection: $gun1"
    }
    set gun $gun1
    #temporariy for testing
   # set gun RG1
    
    set logFile $outputDir/${gun}-[clock format [clock seconds] -format %Y-%m%d:%H%M%S]-${method}.log
    
    if $rcdsVerbose {
        set rcdsOpt -rcds=evaluations=$evals,cycles=$cycles,noise=$noise,step=$stepSize,verbose
    } else {
        set rcdsOpt -rcds=evaluations=$evals,cycles=$cycles,noise=$noise,step=$stepSize
    }
    if $rcdsUseMin {
        append rcdsopt ,useMin
    }
   
    #set inputFile /home/helios/oagData/linac/GunOptimize/$gun/${gun}Opt.sdds
    set inputFile $outputDir/${gun}Opt.sdds

    LogFile "variable file: $inputFile"
    
    set measScript "/home/oxygen/SHANG/oag/apps/src/tcltkapp/oagapp/measL3ChargeOnly -chargePV $objectPV -gun $gun -xPosTol $xPosTol -yPosTol $yPosTol"
    if ![file exist $outputDir/test.sdds] {
        exec sddsmakedataset $outputDir/test.sdds -col=ControlName,type=string -data=L1:RG1:KIK:chargeTrigC,L1:RG2:KIK:chargeTrigC \
          -column=MinimumValue,type=double -data=0.5,0.5 \
          -column=MaximumValue,type=double -data=1.5,1.5
    }
    LogFile "logFile: $logFile"
    
    if $dryRun {
	set opt " -dryRun "
    } else {
	set opt ""
    }
    switch $method {
        Simplex {
            if !$1dscan {
                append opt  -simplex=cycles=$cycles,evaluations=$evals,no1dscan
            } else {
                append opt  -simplex=cycles=$cycles,evaluations=$evals
            }
        } 
        RCDS {
            append opt $rcdsOpt
        }
    }
    #check steering controllaw
    if [catch {exec cavget -list=Linac:ControlLawXRC,Linac:ControlLawYRC -list=.RUN -pend=10 -printErrors } running] {
        return -code error "Error checking steering controllaw running: $running"
    }
    set xrun [lindex $running 0]
    set yrun [lindex $running 1]
    if $runSteering {
        if !$xrun {
            SetL3ChargeStatus "x plane steering controllaw is not running, please start it first!"
            return
        }
        if !$xrun {
            SetL3ChargeStatus "y plane steering controllaw is not running, please start it first!"
            return
        }
    } else {
        SetL3ChargeStatus "Suspending steering controllaw..."
        if [catch {exec cavput -list=Linac:ControlLawXRC,Linac:ControlLawYRC -list=.SUSP=1 -pend=10} result] {
            return -code error "Error suspending steering controllaw: $result"
        }
    }

    global optimizationDone
    set optimizationDone 0
    
    set optMethod sddsoptimize
    
    set command "$optMethod -varFile=$inputFile \"-measScript=$measScript\" -testValues=file=$outputDir/test.sdds,limit=1000 $opt  -maximize -tolerance=$tolerance -logFile=$logFile -verbose"
    LogFile "$command"
    
    SetL3ChargeStatus "starting optimization ..."
    APSExecLog .optimize -width 100 -unixCommand $command \
      -callback "set optimizationDone 1" \
      -cancelCallback "set optimizationDone 2" \
      -abortCallback "set optimizationDone 2"
    
}

proc LoadConfig {args} {
    global gun descList indexList steeringList descriptionList
    set configFile /home/helios/oagData/linac/GunOptimize/$gun/${gun}Opt.config
    set descriptionList [exec sdds2stream -col=Description $configFile]
    set indexList [exec sdds2stream -col=Index $configFile]
    set steeringList [exec sdds2stream -col=SteeringControllaw $configFile]
    
}

proc SetInputConfig {args} {
    global descList indexList steeringList gun runSteering Index outputDir
    set index ""
    APSStrictParseArguments {index} 

    set Index [lindex $indexList $index]
    set runSteering [lindex $steeringList $index]
    set oldDir [pwd]
    cd /home/helios/oagData/linac/GunOptimize/$gun/
    exec relink -index $Index
    cd $oldDir
    exec cp /home/helios/oagData/linac/GunOptimize/$gun/${gun}Opt.sdds $outputDir/${gun}Opt.sdds
}

proc EditInputFile {args} {
    global Index gun outputDir
    #set filename /home/helios/oagData/linac/GunOptimize/$gun/${gun}Opt.sdds-[format %04d $Index]
    #exec cp $filename $outputDir/${gun}Opt.sdds
    exec sddsedit $outputDir/${gun}Opt.sdds
}

GetGunSelection

LoadConfig
cd /home/helios/oagData/linac/GunOptimize/$gun/
set Index [scan [file readlink ${gun}Opt.sdds] ${gun}Opt.sdds-%ld]
set index [lsearch -exact $indexList $Index]
#puts $index
set Description [lindex $descriptionList $index]

SetL3ChargeStatus "$gun is in operation."
APSLabeledOutput .gun -parent .userFrame -textVariable gun -width 30 -label "Gun in Operation:" 
APSButton .get -parent .userFrame.gun -packOption "-side right" -text "refresh" -size small \
  -command "GetGunSelection"
set evals 200
set 1dscan 0
set method Simplex
set cycles 6
set stepSize 0.01
set tolerance 0.02
set noise 0.003
set rcdsVerbose 1
set runSteering 0
set useDmatrix 0
set initCharge 0.49
set xPosTol 5.0
set yPosTol 5.0
set dryRun 0
set DmatFile /home/helios/OAG/ocelot/L3:CM1Opt/HessianMatrix/L3:CM1.eigen.sdds
set outputDir [APSGoToDailyDirectory -subdirectory L3chargeOpt]
set textLogFile $outputDir/L3opt.txt
set logID [open $textLogFile "a+"]
exec cp /home/helios/oagData/linac/GunOptimize/$gun/${gun}Opt.sdds $outputDir/${gun}Opt.sdds

APSLabeledEntry .dir -parent .userFrame -label "Output dir:" -width 75 -textVariable outputDir
APSFrameGrid .grid -parent .userFrame -xList {x1 x2}
set w1 .userFrame.grid.x1
set w2 .userFrame.grid.x2

APSLabeledEntry .evals -parent $w1 -label "Number of evaluations:" -width 30 -textVariable evals
APSLabeledEntry .tol -parent $w1 -label "Tolerance" -width 30 -textVariable tolerance
APSLabeledEntry .cycles -parent $w1 -label "Cycles:" -width 30 -textVariable cycles
APSLabeledEntry .noise -parent $w2 -label "Signal noise for RCDS:" -width 30 -textVariable noise
APSLabeledEntry .step -parent $w2 -label "Step size for RCDS:" -width 30 -textVariable stepSize
APSLabeledEntry .xtol -parent $w1 -label "L1:P0 X bpm tolerance(mm):" -width 30 -textVariable xPosTol
APSLabeledEntry .ytol -parent $w1 -label "L1:P0 Y bpm tolerance(mm):" -width 30 -textVariable yPosTol

set pyOption ""

APSRadioButtonFrame .with1d -parent $w1 -label "With 1D scan for simplex?" -buttonList {Yes No} -valueList {1 0} \
  -variable 1dscan -orientation horizontal 
APSRadioButtonFrame .method -parent .userFrame -label "Optimizaton method:" -buttonList {Simplex RCDS PySimplex PyBaysian} \
  -valueList {Simplex RCDS PySimplex PyBaysian} -variable method -orientation horizontal 
APSLabeledEntry .opt -parent .userFrame -label "Pyoptimizer options:" -textVariable pyOption -width 85

APSRadioButtonFrame .steering -parent $w1 -label "With steering controllaw running?" -buttonList {Yes No} \
  -valueList {1 0} -variable runSteering -orientation horizontal
APSRadioButtonFrame .rcdsverbose -parent $w2 -label "RCDS debugger on?" -buttonList {On Off} -valueList {1 0} \
  -orientation horizontal -variable rcdsVerbose
set rcdsUseMin 0
APSRadioButtonFrame .rcdsmin -parent $w2 -label "RCDS use minimum for bracket scan?" -buttonList {Yes No} -valueList {1 0} \
  -orientation horizontal -variable rcdsUseMin
set objectPV L3:CM1:measCurrentCM
APSRadioButtonFrame .obj -parent $w2 -label "Objective PV:" -buttonList {L3:CM1 L1:CM2} \
  -valueList {L3:CM1:measCurrentCM L1:CM2:measCurrentCM} -orientation horizontal -variable objectPV
APSRadioButtonFrame .dry -parent $w2 -label "Dry run mode?" -buttonList {Yes No} \
    -valueList {1 0} -variable dryRun -orientation horizontal

APSComboboxFrame .combo -parent .userFrame -label "Input Variable Config:" \
    -textVariable Description \
    -itemList $descriptionList \
    -width 60 \
    -editable 0 \
    -callback "SetInputConfig -index" \
    -contextHelp "Select a preset bunch pattern for setting the values of the tcl variables that are then used to set up the injection ioc."

APSButton .edit -parent .userFrame.combo -command "EditInputFile" -text edit -size small

APSButton .start -parent .userFrame -text "Start Optimization" -command "Start"




  

