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

# $Log: not supported by cvs2svn $
# Revision 1.4  2002/11/18 19:38:13  shang
# added setting bpm timing feature
#
# Revision 1.3  2002/10/11 18:49:22  shang
# removed "bell" from SetMainStatus
#
# Revision 1.2  2002/10/11 17:08:39  shang
# added changing Sync/SR Ring, Enable/Inhibit Resync, Switch Booster/BsBypass
# bpm features
#
# Revision 1.1  2002/10/04 00:31:51  shang
# first version
#
# Revision 1.0  2002/09/04 shang

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

APSApplication . -name BoosterBPMConfig -version 1 \
  -overview {Booster bpm config.}

proc MakeBPMSelectionFrame {widget args} {
    set parent ""
    global plane
    APSStrictParseArguments {parent}
    global rootname
    
    set rootname hconfig
    if [winfo exist $parent$widget] {
        destroy $parent$widget
    }
    
    set bpmItemList {C0P1 C0P2 C1P1 C1P2 C2P1 C2P2 C3P1 C3P2 C4P1 \
                       C4P2 C5P1 C5P2 C6P1 C6P2 C7P1 C7P2 C8P1 C8P2 C9P1 C9P2}
    
    set bpmItemLabelList {0P1 0P2 1P1 1P2 2P1 2P2 3P1 3P2 \
                            4P1 4P2 5P1 5P2 6P1 6P2 7P1 7P2 8P1 8P2 9P1 9P2}

    pack [frame $parent$widget]
    APSFrame .up -parent $parent$widget -label "Configuration"
    APSRadioButtonFrame .choosePlane -variable plane -valueList {h v} -buttonList {h v} \
	-parent $parent$widget.up.frame -orientation vertical -packOption "-side left" -label "Plane" \
	-commandList {"setbpmPlane h" "setbpmPlane v"}
    
    #make file frame 
    APSFrame .read -parent $parent$widget.up.frame \
      -contextHelp "Use this frame to read combine bpms."
    set w0 $parent$widget.up.frame.read.frame
    global ${rootname}ReadFile ${rootname}ReadDescription ${rootname}Plane
    global ${rootname}FilterEnd1 ${rootname}MainDir ${rootname}LatSubDir ${rootname}Lattice
    set ${rootname}Plane $plane
    set ${rootname}ReadFile ${plane}.default
    set ${rootname}ReadDescription ""
    set ${rootname}FilterEnd1 .*
    set ${rootname}MainDir /home/helios/oagData/booster/orbitControllaw
    set ${rootname}LatSubDir lattices
    set ${rootname}Lattice default
    APSLabeledEntry .maindir -parent $w0 -label "Main directory: " \
      -textVariable ${rootname}MainDir -width 80 -contextHelp \
      "Enter the name of the main directory for the orbit correction system."
    APSFileSelectWidget .lattice -parent $w0 -label "Lattice: " \
      -pathVariableList [list ${rootname}MainDir ${rootname}LatSubDir] -mode directory -width 76 \
      -variable ${rootname}Lattice -incrementButtons 0 -contextHelp \
      "Enter the name of the lattice with which to work."
    APSFileSelectWidget .file -parent $w0 -variable ${rootname}ReadFile -label "Config: " \
      -pathVariableList [list ${rootname}MainDir ${rootname}LatSubDir ${rootname}Lattice] \
      -mode directory -filterVariableList \
      [list ${rootname}Plane ${rootname}FilterEnd1] -width 76 \
      -incrementButtons 1 -contextHelp \
      "Enter the name of the configuration file to read."
            
    APSButton .io0 -parent $w0 -text Read(replace) -packOption "-side left -anchor n" -size small -command \
          "APSReadOrbitCorrectionConfig -booster 1 -sectorCount 4 -rootname $rootname -filename \$${rootname}MainDir/\$${rootname}LatSubDir/\$${rootname}Lattice/\$${rootname}ReadFile/config -logic replace " \
          -contextHelp "Press to read data to replace the existing configuration, using the named configuration file."
        APSButton .io1 -parent $w0 -text Read(or) -packOption "-side left -anchor n" -size small -command \
          "APSReadOrbitCorrectionConfig -booster 1 -sectorCount 4 -rootname $rootname -filename \$${rootname}MainDir/\$${rootname}LatSubDir/\$${rootname}Lattice/\$${rootname}ReadFile/config -logic or " \
          -contextHelp "Press to read data to or with the existing configuration, using the named configuration file."
        APSButton .io2 -parent $w0 -text Read(and) -packOption "-side left -anchor n" -size small -command \
          "APSReadOrbitCorrectionConfig -booster 1 -sectorCount 4 -rootname $rootname -filename \$${rootname}MainDir/\$${rootname}LatSubDir/\$${rootname}Lattice/\$${rootname}ReadFile/config -logic and " \
          -contextHelp "Press to read data to and with the existing configuration, using the named configuration file."
        APSButton .io3 -parent $w0 -text Read(not) -packOption "-side left -anchor n" -size small -command \
          "APSReadOrbitCorrectionConfig -booster 1 -sectorCount 4 -rootname $rootname -filename \$${rootname}MainDir/\$${rootname}LatSubDir/\$${rootname}Lattice/\$${rootname}ReadFile/config -logic not " \
          -contextHelp "Press to read data specifying elements to turn off, using the named configuration file."
        APSButton .io4 -parent $w0 -text "Refresh good/bad" -packOption "-side left -anchor n" -size small -command \
          "APSRescanBadOrbitDevices -rootname $rootname -plane $plane "
    
    #make cheack button frame
    APSFrame .but -parent $parent$widget 
    set w2 $parent$widget.but.frame
    APSSRSectorButtons .bpm -parent $w2 -rootname $rootname \
      -label "" -sectorCount 4 \
      -itemList $bpmItemList -itemLabelList $bpmItemLabelList \
      -orientation vertical -sectorControl 1 -packOption "-side left" 
   
}

proc setbpmPlane {value} {
    global plane rootname
    global ${rootname}ReadFile ${rootname}ReadDescription ${rootname}Plane
    global ${rootname}FilterEnd1 ${rootname}MainDir ${rootname}LatSubDir ${rootname}Lattice
    
    switch $value {
	h {
	    set plane h
	}
	v {
	    set plane v
	}
    }
    set ${rootname}Plane $plane
    set ${rootname}ReadFile ${plane}.default
    set ${rootname}ReadDescription ""
    set ${rootname}FilterEnd1 .*
    return
}

proc SelectedBPMList {args} {
    global Plane
    global rootname
    
    set names ""
    set sectorCount 4
    set bpmItemList {C0P1 C0P2 C1P1 C1P2 C2P1 C2P2 C3P1 C3P2 C4P1 \
                       C4P2 C5P1 C5P2 C6P1 C6P2 C7P1 C7P2 C8P1 C8P2 C9P1 C9P2}
    for {set sector 1} {$sector<=$sectorCount} {incr sector} {
        
        foreach suffix $bpmItemList {
            set nameFlagx ${rootname}S${sector}${suffix}
            global $nameFlagx 
            if [set $nameFlagx]  {
                lappend names B${sector}$suffix
            }
        }
    }
    return $names
}

proc MakeOptionWidget {widget args} {
    set parent ""
    if [APSStrictParseArguments {parent}]==-1 {
        return
    } 
    set frameWidth 320
    set frameHeight 320
    APSFrame $widget -parent $parent -label "" 
    set w0 $parent$widget.frame
    APSFrameGrid .fg -parent $w0 -xList {x1 x2}
    set w1 $w0.fg.x1
    set w2 $w0.fg.x2

    APSButton .unlock -parent $w1 -text "Unlock" -command "ChangeBPMState -action lock -mode unlock" \
      -contextHelp "Button to unlock all bpms." -packOption "-side top"
    APSButton .lock -parent $w2 -text "lock" -command "ChangeBPMState -action lock -mode lock" \
      -contextHelp "Button to lock all bpms." -packOption "-side top"
    APSButton .ffroff -parent $w1 -text "Force Free Run Off" \
      -command "ChangeBPMState -action freeRun -mode off" \
      -contextHelp "Button to set force free run off." -packOption "-side top"
    APSButton .xenable -parent $w1 -text "X-Enable" \
      -command "ChangeBPMState -action xEnable" -packOption "-side top" \
      -contextHelp "Button to enable horizontal data acquisition."
    APSButton .yenable -parent $w1 -text "Y-Enable" \
      -command "ChangeBPMState -action yEnable " -packOption "-side top" \
      -contextHelp "Button to enable vertical data acquisition."
    APSButton .sumenable -parent $w1 -text "Sum-Enable" \
      -command "ChangeBPMState -action sumEnable" -packOption "-side top" \
      -contextHelp "Button to enable sum signal data acquisition."
    APSButton .polyCalcOn -parent $w1 -text "Polynomial Calc" \
      -command "ChangeBPMState -action polynomial" \
      -contextHelp "Button to enable polynomial calculation." -packOption "-side top"
    APSButton .backupTrigOn -parent $w1 -text "Backup Trigger On" \
      -command "ChangeBPMState -action trigger -mode on" \
      -contextHelp "Button to set the backup trigger on." -packOption "-side top"
    APSButton .lowgain -parent $w1 -text "Low Gain" \
      -command "ChangeBPMState -action ChangeGain -mode low" \
      -contextHelp "Button to set low gain." -packOption "-side top"
    APSButton .syncring -parent $w1 -text "Sync Ring" \
      -command "ChangeBPMState -action ChangeRing -mode Sync" \
      -contextHelp "Button to set Sync ring." -packOption "-side top"
    APSButton .resync -parent $w1 -text "Enable Resync" \
      -command "ChangeBPMState -action ChangeResync -mode Enable" \
      -contextHelp "Button to enable resync." -packOption "-side top"

    APSButton .ffron -parent $w2 -text "Force Free Run On" \
      -command "ChangeBPMState -action freeRun -mode on" \
      -contextHelp "Button to set force free run on." -packOption "-side top"
    APSButton .xdisable -parent $w2 -text "X-Disable" \
      -command "ChangeBPMState -action xDisable" -packOption "-side top" \
      -contextHelp "Button to disable horizontal data acquisition."
    APSButton .ydisable -parent $w2 -text "Y-Disable" \
      -command "ChangeBPMState -action yDisable" -packOption "-side top"\
      -contextHelp "Button to disable vertical data acquisition."
    APSButton .sumdisable -parent $w2 -text "Sum-Disable" \
      -command "ChangeBPMState -action sumDisable" -packOption "-side top" \
      -contextHelp "Button to disable sum signal data acquisition."
    APSButton .linearCalcOn -parent $w2 -text "Linear Calc" \
      -command "ChangeBPMState -action linear" \
      -contextHelp "Button to set linear calculation." -packOption "-side top"
    
    APSButton .backupTrigOff -parent $w2 -text "Backup Trigger Off" \
      -command "ChangeBPMState -action trigger -mode off" \
      -contextHelp "Button to set the backup trigger off." -packOption "-side top"
    APSButton .highgain -parent $w2 -text "High Gain" \
      -command "ChangeBPMState -action ChangeGain -mode high" \
      -contextHelp "Button to set high gain." -packOption "-side top"
    APSButton .bpm -parent $w1 -text "Switch to Booster BPM" \
      -command "ChangeBPMState -action SwitchBPM -mode Booster" \
      -contextHelp "Button to switch to booster bpm." -packOption "-side top"
    APSButton .syncring -parent $w2 -text "SR Ring" \
      -command "ChangeBPMState -action ChangeRing -mode SR" \
      -contextHelp "Button to set SR ring." -packOption "-side top"
    APSButton .resync -parent $w2 -text "Inhibit Resync" \
      -command "ChangeBPMState -action ChangeResync -mode Inhibit" \
      -contextHelp "Button to inhibit resync." -packOption "-side top"
    APSButton .bpm -parent $w2 -text "Switch to Bs Bypass" \
      -command "ChangeBPMState -action SwitchBPM -mode Bs" \
      -contextHelp "Button to switch to Bs Bypass bpm." -packOption "-side top"
    APSButton .transferscdu -parent $w0 -text "Transfer SCDU orbit to Memory Scannaer/SCDU Setpoints" \
      -command "TransferSCDUToSetpoints" \
      -contextHelp "transfer SCDU orbit to memory scanner setpoints"
}

proc ChangeBPMState {args} {
    set mode ""
    set action ""
    APSParseArguments {action mode}
    #set mode [string tolower $mode]
    set bpmList [SelectedBPMList]
    switch $action {
        lock {
            switch $mode {
                lock {
                    set value 1
                }
                unlock {
                    set value 0
                }
                default {
                    SetMainStatus "Unknown lock mode given -- should be either lock or unlock"
                    return
                }
            }
            set extension :lock_bo.VAL
            SetMainStatus "$mode selected bpms..."
        }
        freeRun  {
            switch $mode {
                on {
                    set value 1
                }
                off {
                    set value 0
                }
                default {
                    SetMainStatus "Unknown free run mode given -- should be either on or off"
                    return
                }
            } 
            set extension :ffreerun_bo.VAL
            SetMainStatus "force free run $mode for selected bpms ..."
        }
        trigger {
            switch $mode {
                on {
                    set value 1
                }
                off {
                    set value 0
                }
                default {
                    SetMainStatus "Unknown trigger mode given -- should be either on or off"
                    return
                }
            } 
            set extension :backuptrig_bo.VAL
            SetMainStatus "Set backup trigger $mode..."
        }
        polynomial {
            set value 0
            set extension :ConvertBO.VAL
            SetMainStatus "Enable polynomial calculation ..."
        }
        linear {
            set value 1
            set extension :ConvertBO.VAL
            SetMainStatus "Enable linear calculation ..."
        }
        xEnable {
            set value 0
            set extension :disablex_bo.VAL
            SetMainStatus "Enable horizontal data acquisition"
        }
        xDisable {
            set value 1
            set extension :disablex_bo.VAL
            SetMainStatus "disable horizontal data acquisition."
        }
        yEnable {
            set value 0
            set extension :disabley_bo.VAL
            SetMainStatus "Enable vertical data acquisition"
        }
        yDisable {
            set value 1
            set extension :disabley_bo.VAL
            SetMainStatus "Disable vertical data acquisition"
        }
        sumEnable {
            set value 0
            set extension :disablesum_bo.VAL
            SetMainStatus "Enable sum signal data acquisition."
        }
        sumDisable {
            set value 1
            set extension :disablesum_bo.VAL
            SetMainStatus "Disable sum signal data acquisition." 
        }
	ChangeGain {
	    switch $mode {
		low {
		    set value 0
		}
		high {
		    set value 1
		}
		default {
		    SetMainStatus "Unknow mode given to gain pvs (should be either high or low)"
		    return
		}
	    }
	    set extension :normal_bo.VAL
	}
        ChangeRing {
            set value $mode
            set extension :ring_bo.VAL
        }
        ChangeResync {
            set value $mode
            set extension :resync_bo.VAL
        }
        SwitchBPM {
            switch $mode {
                Booster {
                    set value 0
                }
                Bs {
                    set value 1
                }
                default {
                    SetMainStatus "Incorrect mode supplied for switching bpms."
                    return
                }
            }
            if [catch {exec cavput -list=BB:BpmSelectC=$value -pend=30} result] {
                SetMainStatus "$result."
                return
            }
            SetMainStatus "Switching BPM done."
            return
        }
        default {
            SetMainStatus "Unknow action given to ChangeBPMState."
            return
        }
    }
    
    if ![llength $bpmList] {
        SetMainStatus "ChangeBPMState: No bpm selected!"
        return
    }
    if [catch {exec cavput -list=[join $bpmList ,] -list=$extension=$value -pend=30} result] {
        SetMainStatus "ChangeBPMState: $result"
        return
    }
    SetMainStatus "done!"
}

proc SetMainStatus {text} {
    global mainStatus
    set mainStatus $text 
    update
}

proc SetAverageWeight {args} {
    global AverageWeight
    if [catch {exec cavput -list=B:bpm:memscan_wt_ao.VAL=$AverageWeight -pend=30} result] {
	SetMainStatus "$result"
	return
    }
    SetMainStatus "Set memory scanner average weight to $AverageWeight,  done"
}
proc SetNumToAverage {args} {
    global NumToAve
    set bpmList [SelectedBPMList]
    if ![llength $bpmList] {
        SetMainStatus "ChangeBPMState: No bpm selected!"
        return
    }
    if [catch {exec cavput -list=[join $bpmList ,] -list=:num2ave_ao.VAL=$NumToAve -pend=30} result] {
        SetMainStatus "ChangeBPMState: $result"
        return
    }
}

proc SetBPMTiming {args} {
    global N M

    if {![string length $N] || ![string length $M] } {
        return -code error "Either N or M is not given"
    }
    set bpmList [SelectedBPMList]
    if ![llength $bpmList] {
        return -code error "No bpms are selected!"
    }
    SetMainStatus "Set bpm timing ..."
    set config /home/helios/oagData/booster/orbitControllaw/lattices/config.sdds
    set data(ColumnNames) "Name"
    set data(ColumnInfo.Name) "type SDDS_STRING"
    set data(Column.Name) [list $bpmList]
    set tmpRoot /tmp/[APSTmpString]
    APSAddToTmpFileList -ID BoosterBPMConfig -fileList "$tmpRoot"
    if [catch {sdds save $tmpRoot data} result] {
        return -code error $result
    }
    if [catch {exec sddsprocess $config -pipe=out -match=par,NameType=MonitorNames | \
                 sddsselect -pipe $tmpRoot -match=Name | \
                 sddssort -pipe -column=Timing -unique | \
                 sdds2stream -pipe=in -col=Timing} result] {
        return -code error $result
    }
    set putList1 ""
    set putList2 ""
    foreach timing $result {
        lappend putList1 B:bpmT${timing}:Cycle_count_lo=$M
        lappend putList2 B:bpmT${timing}:Delay_count_lo=$N
    }
    if [catch {exec cavput -list=[join $putList1 ,] -pend=30
        exec cavput -list=[join $putList2 ,] -pend=30 } result] {
        return -code error $result
    }
    SetMainStatus "done."
}

proc TransferSCDUToSetpoints {args} {
    set bpmList [SelectedBPMList]
    
    SetMainStatus "Acquiring SCDU Orbit data..."
    
    if [catch {exec cavget -list=[join $bpmList ,] -list=:scdu:x:AdjustedCC \
                 -repeat=number=10,pause=0.1,average -pend=30} xList] {
	return -code error $xList
    }
    if [catch {exec cavget -list=[join $bpmList ,] -list=:scdu:y:AdjustedCC \
                 -repeat=number=10,pause=0.1,average -pend=30} yList] {
	return -code error $yList
    }
    set putxList ""
    set putyList ""
    foreach x $xList y $yList bpm $bpmList {
	if {$x=="?"} {
	   SetMainStatus "Error in reading  $bpm:scdu:x:AdjustedCC"
	} else {
	    lappend putxList $bpm:scdu:x:SetpointAO=$x
	}
	if {$y=="?"} {
	   SetMainStatus "Error in reading  $bpm:scdu:y:AdjustedCC"
	} else {
	    lappend putxList $bpm:scdu:y:SetpointAO=$y
	}
    }
    SetMainStatus "Transferring SCDU Orbit data to setpoint..."
    
    if [string length $putxList] {
	if [catch {exec cavput -list=[join $putxList ,] -pend=30} result] {
	    return -code error $result
	}
    }
    if [string length $putyList] {
	if [catch {exec cavput -list=[join $putyList ,] -pend=30} result] {
	    return -code error $result
	}
    }
    SetMainStatus "done"
}

set mainStatus "Working..."
set plane h
set AverageWeight 2
set NumToAve 2
set N 256
set M 64

APSScrolledStatus .status -parent .userFrame -textVariable mainStatus -width 80 \
  -height 4
update
APSFrame .entry -parent .userFrame
APSLabeledEntry .weight -label "Memory Scanner Average Weight: " -parent .userFrame.entry.frame \
    -textVariable AverageWeight \
    -contextHelp "Set memory scanner average weight." -width 10 -packOption "-side left"
APSButton .set -parent .userFrame.entry.frame.weight -text "Set" -contextHelp "Press to set the value" \
    -command "SetAverageWeight"
APSLabeledEntry .ave -label "Num To Ave for each bpm: " -parent .userFrame.entry.frame -textVariable NumToAve \
  -contextHelp "Set number of average for each bpm." -width 10 -packOption "-side right"
APSButton .set -parent .userFrame.entry.frame.ave -text "Set" -contextHelp "Press to set the value" \
    -command "SetNumToAverage"
APSFrame .timing -parent .userFrame
APSLabel .time -text "BPM Timing: " -parent .userFrame.timing.frame -packOption "-side left"
APSLabeledEntry .n -label "N:" -parent .userFrame.timing.frame -textVariable N -packOption "-side left" \
  -width 10
APSLabeledEntry .m -label "M:" -parent .userFrame.timing.frame -textVariable M -packOption "-side left" \
  -width 10
APSButton .set -parent .userFrame.timing.frame -text "Set BPM Timing" \
  -contextHelp "Press to set BPM Timing for selected bpms." \
  -command "SetBPMTiming"


MakeBPMSelectionFrame .bpm -parent .userFrame
MakeOptionWidget .opt -parent .userFrame
