1951 lines
64 KiB
Tcl
1951 lines
64 KiB
Tcl
# Author: Ferdi Franceschini
|
|
# Based on the examples in the hs_test.tcl sample configuration by Mark Lesha.
|
|
# http://gumtree.ansto.gov.au:9080/nbicms/bragg-systems/histogram-server/hs_test.tcl/view
|
|
|
|
##
|
|
# @file Provides generic code and parameters for configuring the ANSTO histogram memory server
|
|
# The instrument specific histogram memory configuration files must define an initialisation
|
|
# function with the following signature
|
|
# @code proc ::histogram_memory::initialize {}
|
|
# this function should call the generic initalisation function,
|
|
# ::histogram_memory::ic_initialize
|
|
#
|
|
#@see ::histogram_memory::ic_initialize
|
|
|
|
source $cfPath(hmm)/hmm_object.tcl
|
|
namespace eval histogram_memory {
|
|
# Common config variables
|
|
variable histmem_simulation
|
|
variable ic_count_methods
|
|
variable ic_fsrce_values
|
|
variable preset_mult
|
|
variable monitor_controlled
|
|
|
|
set monitor_controlled "false"
|
|
|
|
# Instrument Specific Config variables
|
|
|
|
set histmem_simulation [SplitReply [hmm_simulation]]
|
|
|
|
proc init_hmm_objs {} {
|
|
variable histmem_simulation
|
|
variable ic_count_methods
|
|
variable ic_fsrce_values
|
|
variable default_frame_source_when_there_is_no_frame_signal
|
|
variable default_frame_source_always_internal
|
|
|
|
if [ catch {
|
|
set ic_fsrce_values [ list INTERNAL EXTERNAL ]
|
|
set ic_count_methods [concat [list time unlimited period count frame count_roi] $::counter::isc_beam_monitor_list ]
|
|
if {$histmem_simulation == "true"} {
|
|
MakeHM hmm SIM
|
|
hmm configure daq Stopped
|
|
hmm configure statuscheck false
|
|
hmm configure num_events_filled_to_histo 12345
|
|
hmm configure daq_dirname "DAQ_2011-05-09T11-52-50"
|
|
hmm configure acq_dataset_active_sec 9.8
|
|
hmm configure acq_start_time_t 1303170800
|
|
hmm configure acq_stop_time_t 1303170818
|
|
hmm configure ratemap_xy_max_bin 123
|
|
hmm configure ratemap_xy_total 321
|
|
hmm configure maximum_period 0
|
|
hmm configure fat_frame_frequency 50
|
|
hmm configure fat_clock_scale 1000
|
|
foreach bm $::counter::isc_beam_monitor_list {
|
|
set bm_num [string index $bm end]
|
|
if [string is integer $bm_num] {
|
|
hmm configure bm${bm_num}_status DISABLED
|
|
hmm configure bm${bm_num}_counts 12345
|
|
hmm configure bm${bm_num}_event_rate 50
|
|
}
|
|
}
|
|
} else {
|
|
ANSTO_MakeHM hmm anstohttp
|
|
}
|
|
|
|
|
|
|
|
# Frame source for each instrument if freq = 0, this can happen when automatically
|
|
# setting frequencies from choppers.
|
|
array set default_frame_source_when_there_is_no_frame_signal {
|
|
echidna INTERNAL
|
|
koala INTERNAL
|
|
kowari EXTERNAL
|
|
pelican INTERNAL
|
|
platypus EXTERNAL
|
|
quokka INTERNAL
|
|
taipan INTERNAL
|
|
wombat INTERNAL
|
|
lyrebird INTERNAL
|
|
kookaburra INTERNAL
|
|
dingo INTERNAL
|
|
bilby INTERNAL
|
|
emu INTERNAL
|
|
}
|
|
|
|
array set default_frame_source_always_internal {
|
|
echidna "true"
|
|
koala "false"
|
|
kowari "false"
|
|
pelican "false"
|
|
platypus "false"
|
|
quokka "false"
|
|
taipan "false"
|
|
wombat "false"
|
|
lyrebird "false"
|
|
kookaburra "false"
|
|
dingo "false"
|
|
bilby "false"
|
|
emu "false"
|
|
}
|
|
|
|
::utility::mkVar detector_active_height_mm Float user active_height true detector true true
|
|
sicslist setatt detector_active_height_mm units mm
|
|
::utility::mkVar detector_active_width_mm Float user active_width true detector true true
|
|
sicslist setatt detector_active_width_mm units mm
|
|
|
|
::utility::mkVar hmm_user_configpath Text manager user_configpath false detector false false
|
|
hmm_user_configpath ../user_config/hmm
|
|
::utility::mkVar hmm_mode Text user mode true detector true true
|
|
::utility::mkVar hmm_preset Float user preset true detector true true
|
|
} message ] {
|
|
return -code error "([info level 0]) $message"
|
|
}
|
|
}
|
|
##############################################
|
|
# Creating the histogram memories in SICS
|
|
##############################################
|
|
|
|
# Make a histogram memory object hmm, allows control of the
|
|
# remote histogram server via http, and acquisition
|
|
# of histogram period data.
|
|
|
|
|
|
##############################################
|
|
# Configuring the histogram server
|
|
##############################################
|
|
|
|
# Procedure to read a single config (or any) file, return content as a string.
|
|
proc returnconfigfile {filename} {
|
|
if [ catch {
|
|
set fh [open $filename]
|
|
set xml [read $fh]
|
|
close $fh
|
|
set cfg [subst $xml]
|
|
} message ] {
|
|
return -code error "([info level 0]) $message"
|
|
}
|
|
return $cfg
|
|
}
|
|
|
|
# Here, define a function to let us read back the value of dictionary items from the hmm
|
|
# such as OAT dimensions.
|
|
proc hmmdictitemval {histomem dictitem} {
|
|
if [ catch {
|
|
set resp [$histomem configure $dictitem]
|
|
set retn [lindex [split $resp " "] 2]
|
|
} message ] {
|
|
return -code error "([info level 0]) $message"
|
|
}
|
|
return $retn
|
|
}
|
|
|
|
##
|
|
# @brief Use histogram server to control acquisitions
|
|
proc set_termination_conditions {count_method count_size count_stop} {
|
|
if [ catch {
|
|
hmm configure FAT_COUNT_METHOD $count_method
|
|
hmm configure FAT_COUNT_SIZE $count_size
|
|
hmm configure FAT_COUNT_STOP $count_stop
|
|
hmm init
|
|
} message ] {
|
|
return -code error "([info level 0]) $message"
|
|
}
|
|
}
|
|
|
|
##############################################
|
|
# Support for using expanded histogram period
|
|
# to create interlaced/overlapped histograms
|
|
##############################################
|
|
|
|
# Define an OAT offset variable to use with both scans:
|
|
# It is possible to effectively offset the histogram filler's
|
|
# OAT table by an arbitrary amount. For overlapped data acquisitions, we can
|
|
# configure an oversized histogram period using the EXPAND_OAT parameters
|
|
# in the FAT. Then at each scan stop, before acqisition commences the offset
|
|
# can be adjusted using the OFFSET_OAT paramters of the FAT. By progressively
|
|
# stepping the OFFSET_OAT, an overlapped image can be built up.
|
|
# The global variable oatoffset is defined for this purpose.
|
|
# During the scan, this variable is incremented and can be passed
|
|
# in to an argument of set_oat_offset to provide progressively
|
|
# increasing offset, producing an overlapped histogram.
|
|
#
|
|
global oatoffset
|
|
#
|
|
#Function to apply OAT offsets to the histogram server.
|
|
proc set_oat_offset {oatoff_x oatoff_y oatoff_t} {
|
|
if [ catch {
|
|
hmm configure FAT_OFFSET_OAT_X $oatoff_x
|
|
hmm configure FAT_OFFSET_OAT_Y $oatoff_y
|
|
hmm configure FAT_OFFSET_OAT_T $oatoff_t
|
|
hmm init
|
|
} message ] {
|
|
return -code error "([info level 0]) $message"
|
|
}
|
|
}
|
|
|
|
##############################################
|
|
# Support for data acquisition
|
|
##############################################
|
|
|
|
# A simple procedure to read the histogram data through SICS
|
|
# and dump the data to a numbered file.
|
|
proc savehistodata {histomem filename} {
|
|
set ::errorInfo ""
|
|
set fh [open $filename "w"]
|
|
# To get the whole memory, we don't need to specify the start or end arguments.
|
|
# But we need to specify the bank number, this sets the type of data to be read.
|
|
#
|
|
set histodata [$histomem get [hmmdictitemval $histomem bank]]
|
|
# clientput $histodata value
|
|
puts -nonewline $fh $histodata
|
|
close $fh
|
|
return
|
|
}
|
|
|
|
##############################################
|
|
##############################################
|
|
## Scan Callback Procedures ##
|
|
##############################################
|
|
##############################################
|
|
proc set_sobj_attributes {} {
|
|
if [ catch {
|
|
# SICS commands
|
|
|
|
# histogram memory macros
|
|
sicslist setatt ::histogram_memory::set_oat_offset privilege internal;
|
|
sicslist setatt ::histogram_memory::scan2_runb privilege internal;
|
|
sicslist setatt ::histogram_memory::scan2_runa privilege internal;
|
|
sicslist setatt ::histogram_memory::returnconfigfile privilege internal;
|
|
sicslist setatt ::histogram_memory::save privilege internal;
|
|
|
|
} message ] {
|
|
return -code error "([info level 0]) $message"
|
|
}
|
|
}
|
|
|
|
|
|
##
|
|
# @brief Returns the histogram memory server clock scale.
|
|
#
|
|
# NOTE: The histmem server doesn't provide the clock scale to SICS\n
|
|
# so we just hardwire 1000 nanoseconds which is the current (10/01/08)\n
|
|
# value on all the servers.
|
|
proc clock_scale {args} {
|
|
switch $args {
|
|
"" { return [expr [SplitReply [hmm configure fat_clock_scale]]/1000.0] }
|
|
"units" { return "microseconds"}
|
|
default {
|
|
return -code error "[info level 0]: Invalid argument $args"
|
|
}
|
|
}
|
|
}
|
|
proc get_clock_scale {} {
|
|
return [SplitReply [hmm configure fat_clock_scale]]
|
|
}
|
|
proc set_clock_scale {val} {
|
|
set catch_status [ catch {
|
|
if {[string is integer $val] == 0} {
|
|
error "ERROR: clock scale should be an integer. NOTE: The clock base is in nanoseconds"
|
|
}
|
|
hmm configure fat_clock_scale $val
|
|
::histogram_memory::stop
|
|
hmm init
|
|
} message ]
|
|
handle_exception $catch_status $message
|
|
}
|
|
## @brief Use boundaries or centres to calculate axis values
|
|
#
|
|
# @param axis_name x_bin, y_bin, x_pixel_offset, y_pixel_offset, two_theta
|
|
# @param type centres or boundaries
|
|
proc set_graphtype {axis_name type} {
|
|
variable state
|
|
|
|
switch -- $type {
|
|
"centres" {
|
|
set state($axis_name,graph_type) "centres"
|
|
}
|
|
"boundaries" {
|
|
set state($axis_name,graph_type) "boundaries"
|
|
}
|
|
default {
|
|
error "ERROR: Unknown graph type $type"
|
|
}
|
|
}
|
|
}
|
|
|
|
proc get_graphtype {axis_name} {
|
|
variable state
|
|
return $state($axis_name,graph_type)
|
|
}
|
|
|
|
## @brief Calculate axis array from a given list of bin boundaries
|
|
# Generates a sicsdata array
|
|
#
|
|
# @param axis_name Fully qualified name of the calling procedure
|
|
# @param scale_factor axis scale factor or @none
|
|
# @param offset axis offset or @none
|
|
# @param boundaries list of bin boundaries or @none
|
|
proc calc_axis {axis_name scale_factor offset boundaries {bb_zero_offset 0}} {
|
|
variable state
|
|
|
|
set bin_array ::histogram_memory::${axis_name}_array
|
|
if [ catch {
|
|
set i 0
|
|
$bin_array clear
|
|
if {$state($axis_name,graph_type) == "boundaries"} {
|
|
foreach bb $boundaries {
|
|
set val [expr {$scale_factor*($bb+$bb_zero_offset) + $offset}]
|
|
$bin_array putfloat $i $val
|
|
incr i
|
|
}
|
|
} else {
|
|
foreach b0 [lrange $boundaries 0 end-1] b1 [lrange $boundaries 1 end] {
|
|
set val [expr {$scale_factor*($bb_zero_offset + ($b1 + $b0)/2.0) + $offset}]
|
|
$bin_array putfloat $i $val
|
|
incr i
|
|
}
|
|
}
|
|
} message ] {
|
|
return -code error "([info level 0]) $message"
|
|
}
|
|
}
|
|
|
|
sicsdatafactory new ::histogram_memory::y_bin_array
|
|
##
|
|
# @brief Provides y_bin boundary array for data axes
|
|
proc y_bin {args} {
|
|
if [ catch {
|
|
::histogram_memory::calc_axis "y_bin" 1.0 0.0 [OAT_TABLE Y -getdata BOUNDARIES]
|
|
if {$args == "-get_data_ref"} {
|
|
set binarray "::histogram_memory::y_bin_array"
|
|
} else {
|
|
set binarray [::histogram_memory::y_bin_array used]
|
|
}
|
|
} message ] {
|
|
return -code error "([info level 0]) $message"
|
|
}
|
|
return $binarray
|
|
}
|
|
set script_name ::histogram_memory::y_bin
|
|
publish $script_name user
|
|
sicslist setatt $script_name privilege user
|
|
sicslist setatt $script_name kind script
|
|
sicslist setatt $script_name access read_only
|
|
sicslist setatt $script_name dtype floatvarar
|
|
sicslist setatt $script_name dlen 100
|
|
sicslist setatt $script_name klass detector
|
|
sicslist setatt $script_name control false
|
|
sicslist setatt $script_name data true
|
|
sicslist setatt $script_name nxsave true
|
|
sicslist setatt $script_name mutable false
|
|
sicslist setatt $script_name long_name y_bin
|
|
unset script_name
|
|
|
|
sicsdatafactory new ::histogram_memory::x_bin_array
|
|
##
|
|
# @brief Provides x_bin boundary array for data axes
|
|
proc x_bin {args} {
|
|
if [ catch {
|
|
::histogram_memory::calc_axis "x_bin" 1.0 0.0 [OAT_TABLE X -getdata BOUNDARIES]
|
|
if {$args == "-get_data_ref"} {
|
|
set binarray "::histogram_memory::x_bin_array"
|
|
} else {
|
|
set binarray [::histogram_memory::x_bin_array used]
|
|
}
|
|
} message ] {
|
|
return -code error "([info level 0]) $message"
|
|
}
|
|
return $binarray
|
|
}
|
|
set script_name ::histogram_memory::x_bin
|
|
publish $script_name user
|
|
sicslist setatt $script_name privilege user
|
|
sicslist setatt $script_name kind script
|
|
sicslist setatt $script_name access read_only
|
|
sicslist setatt $script_name dtype floatvarar
|
|
sicslist setatt $script_name dlen 100
|
|
sicslist setatt $script_name klass detector
|
|
sicslist setatt $script_name control false
|
|
sicslist setatt $script_name data true
|
|
sicslist setatt $script_name nxsave true
|
|
sicslist setatt $script_name mutable false
|
|
sicslist setatt $script_name long_name x_bin
|
|
unset script_name
|
|
|
|
# requires detector_active_width_mm det_radius_mm
|
|
sicsdatafactory new ::histogram_memory::y_pixel_offset_array
|
|
proc y_pixel_offset {args} {
|
|
variable state
|
|
if [ catch {
|
|
set det_height_mm [SplitReply [detector_active_height_mm]]
|
|
set max_chan [OAT_TABLE Y -getdata MAX_CHAN]
|
|
set scale_factor [expr {1.0 * $det_height_mm / $max_chan}]
|
|
set offset 0.0
|
|
::histogram_memory::calc_axis "y_pixel_offset" $scale_factor $offset [OAT_TABLE Y -getdata BOUNDARIES]
|
|
if {$args == "-get_data_ref"} {
|
|
set binarray "::histogram_memory::y_pixel_offset_array"
|
|
} else {
|
|
set binarray [::histogram_memory::y_pixel_offset_array used]
|
|
}
|
|
} message ] {
|
|
return -code error "([info level 0]) $message"
|
|
}
|
|
return $binarray
|
|
}
|
|
set script_name ::histogram_memory::y_pixel_offset
|
|
publish $script_name user
|
|
sicslist setatt $script_name privilege user
|
|
sicslist setatt $script_name kind script
|
|
sicslist setatt $script_name access read_only
|
|
sicslist setatt $script_name dtype floatvarar
|
|
sicslist setatt $script_name dlen 100
|
|
sicslist setatt $script_name klass detector
|
|
sicslist setatt $script_name control false
|
|
sicslist setatt $script_name data true
|
|
sicslist setatt $script_name nxsave true
|
|
sicslist setatt $script_name mutable false
|
|
sicslist setatt $script_name long_name y_pixel_offset
|
|
sicslist setatt $script_name units "mm"
|
|
unset script_name
|
|
|
|
# requires detector_active_width_mm det_radius_mm
|
|
sicsdatafactory new ::histogram_memory::x_pixel_offset_array
|
|
proc x_pixel_offset {args} {
|
|
variable state
|
|
if [ catch {
|
|
set det_width_mm [SplitReply [detector_active_width_mm]]
|
|
set max_chan [OAT_TABLE X -getdata MAX_CHAN]
|
|
set scale_factor [expr {1.0 * $det_width_mm / $max_chan}]
|
|
set offset 0.0
|
|
::histogram_memory::calc_axis "x_pixel_offset" $scale_factor $offset [OAT_TABLE X -getdata BOUNDARIES]
|
|
if {$args == "-get_data_ref"} {
|
|
set binarray "::histogram_memory::x_pixel_offset_array"
|
|
} else {
|
|
set binarray [::histogram_memory::x_pixel_offset_array used]
|
|
}
|
|
} message ] {
|
|
return -code error "([info level 0]) $message"
|
|
}
|
|
return $binarray
|
|
}
|
|
set script_name ::histogram_memory::x_pixel_offset
|
|
publish $script_name user
|
|
sicslist setatt $script_name privilege user
|
|
sicslist setatt $script_name kind script
|
|
sicslist setatt $script_name access read_only
|
|
sicslist setatt $script_name dtype floatvarar
|
|
sicslist setatt $script_name dlen 100
|
|
sicslist setatt $script_name klass detector
|
|
sicslist setatt $script_name control false
|
|
sicslist setatt $script_name data true
|
|
sicslist setatt $script_name nxsave true
|
|
sicslist setatt $script_name mutable false
|
|
sicslist setatt $script_name long_name x_pixel_offset
|
|
sicslist setatt $script_name units "mm"
|
|
unset script_name
|
|
|
|
sicsdatafactory new ::histogram_memory::time_channel_array
|
|
proc time_channel {args} {
|
|
variable state
|
|
if [ catch {
|
|
::histogram_memory::calc_axis "time_channel" [::histogram_memory::clock_scale] 0.0 [OAT_TABLE T -getdata BOUNDARIES]
|
|
if {$args == "-get_data_ref"} {
|
|
set binarray "::histogram_memory::time_channel_array"
|
|
} else {
|
|
set binarray [::histogram_memory::time_channel_array used]
|
|
}
|
|
} message ] {
|
|
return -code error "([info level 0]) $message"
|
|
}
|
|
return $binarray
|
|
}
|
|
set script_name ::histogram_memory::time_channel
|
|
publish $script_name user
|
|
sicslist setatt $script_name privilege user
|
|
sicslist setatt $script_name kind script
|
|
sicslist setatt $script_name access read_only
|
|
sicslist setatt $script_name dtype floatvarar
|
|
sicslist setatt $script_name dlen 100
|
|
sicslist setatt $script_name klass detector
|
|
sicslist setatt $script_name control false
|
|
sicslist setatt $script_name data true
|
|
sicslist setatt $script_name nxsave true
|
|
sicslist setatt $script_name mutable false
|
|
sicslist setatt $script_name long_name time_of_flight
|
|
sicslist setatt $script_name units [::histogram_memory::clock_scale units]
|
|
unset script_name
|
|
}
|
|
|
|
#################################
|
|
# Must always specify number of channels
|
|
# bb list len <= channels+1
|
|
# Calculate the boundaries after successfully uploading a configuration.
|
|
# set values [OAT_TABLE -get X]
|
|
# set channels [OAT_TABLE -get NXC]
|
|
# OAT_TABLE X -setdata BOUNDARIES [calc_boundaries $values $channels]
|
|
proc ::histogram_memory::calc_boundaries {values channels} {
|
|
if [ catch {
|
|
set bbnum [llength $values]
|
|
set maxbblen [expr $channels+1]
|
|
set maxchan [expr $channels - 1]
|
|
if {$bbnum > $maxbblen} {
|
|
error "ERROR: The number of bin boundaries must be less than or equal to $maxbblen"
|
|
}
|
|
set BOUNDARIES ""
|
|
if {$bbnum > 2} {
|
|
set BOUNDARIES $values
|
|
} elseif {$bbnum == 2} {
|
|
foreach {leftbb rightbb} $values {}
|
|
set bstep [expr {$rightbb-$leftbb}]
|
|
if {$bstep == 0} {
|
|
error "ERROR: The generating bin boundaries are equal"
|
|
}
|
|
set startbin [expr ($leftbb+$rightbb)/2.0]
|
|
# FIXME This check doesn't work for time, T
|
|
# if {$startbin < 0.0 || $startbin > $maxchan} {
|
|
# error "ERROR: $leftbb and $rightbb must bound a channel >= 0 or <= $maxchan"
|
|
# }
|
|
for {set bb $leftbb; set i 0} {$i < $maxbblen} {incr i; set bb [expr {$bb + $bstep}]} {
|
|
lappend BOUNDARIES $bb
|
|
}
|
|
} else {
|
|
error "ERROR: You must specify at least two bin boundaries"
|
|
}
|
|
} message ] {
|
|
return -code error $message
|
|
}
|
|
return $BOUNDARIES
|
|
}
|
|
|
|
set hmm_xml ""
|
|
|
|
##
|
|
# @brief Provides a standard set of subcommands for the histogram server table
|
|
# configuration commands.
|
|
#
|
|
# @param tag Table identifier, one of BAT CAT FAT NAT OAT SAT SRV
|
|
# @param attributes Defines the list of attributes which you will be allowed to set.
|
|
# @param element_list Defines the list of elements which you will be allowed to set.
|
|
# Use "" if your table doesn't contain any elements.
|
|
# @param args This can be empty, or a list of name value pairs for the attributes
|
|
# and elements which you want to set or one of the subcommands listed below.
|
|
# If args is empty this function will simply return an xml fragment for the named table,
|
|
#
|
|
# Subcommands\n
|
|
# -clear clears the table\n
|
|
# -init A list of name value pairs. If you use attribute or element names then
|
|
# the corresponding table entries will be initilised to the given values, any
|
|
# attributes or elements which aren't specified will be cleared. You can also
|
|
# specify extra parameters to store in the table which might be required to
|
|
# specify limits or constants which may be necessary for deriving configuration
|
|
# parameters.\n
|
|
# -get return the value for the named attribute or element\n
|
|
# -attlist list all of the attributes with their values.\n
|
|
# TODO Maintain "proposed" and "current" tables. Provide a setcurrent command which can
|
|
# only be called by the upload_config command to set the proposed tables as current
|
|
# TODO Allow for top level content in tables and attributes in sub-elements
|
|
proc HISTMEM_TABLE {tpath args} {
|
|
global hmm_xml
|
|
|
|
if [ catch {
|
|
set retVal ""
|
|
set tpath [string toupper $tpath]
|
|
foreach {opt arglist} [::utility::get_opt_arglist $args] {}
|
|
switch -- $opt {
|
|
"-dump" {
|
|
foreach {k v} $hmm_xml {clientput $k; foreach {name val} $v {clientput "$name: $val"}}
|
|
}
|
|
"-allowed_attributes" {
|
|
if {[llength $arglist] == 0} {
|
|
set retVal [::utility::tabget hmm_xml $tpath/_ALLOWED_ATTRIBUTES_]
|
|
} else {
|
|
::utility::tabset hmm_xml $tpath/_ALLOWED_ATTRIBUTES_ [lindex $arglist 0]
|
|
}
|
|
}
|
|
"-allowed_elements" {
|
|
if {[llength $arglist] == 0} {
|
|
set retVal [::utility::tabget hmm_xml $tpath/_ALLOWED_ELEMENTS_]
|
|
} else {
|
|
::utility::tabset hmm_xml $tpath/_ALLOWED_ELEMENTS_ [lindex $arglist 0]
|
|
::utility::tabset hmm_xml $tpath/_ELEMENTS_ [lindex $arglist 0]
|
|
}
|
|
}
|
|
"-setel" {
|
|
set element [lindex $arglist 0]
|
|
set value [lindex $arglist 1]
|
|
if {[lsearch [::utility::tabget hmm_xml $tpath/_ALLOWED_ELEMENTS_] $element] >= 0} {
|
|
::utility::tabset hmm_xml $tpath/$element/_CONTENT_ $value
|
|
} else {
|
|
error "ERROR: $element is not an allowed element in $tpath"
|
|
}
|
|
}
|
|
"-setatt" {
|
|
set attname [lindex $arglist 0]
|
|
set value [lindex $arglist 1]
|
|
if {[lsearch [::utility::tabget hmm_xml $tpath/_ALLOWED_ATTRIBUTES_] $attname] >= 0} {
|
|
::utility::tabset hmm_xml $tpath/_ATTLIST_/$attname $value
|
|
} else {
|
|
error "ERROR: $attname is not an allowed attribute in $tpath"
|
|
}
|
|
}
|
|
"-getel" {
|
|
set element [lindex $arglist 0]
|
|
set retVal [::utility::tabget hmm_xml $tpath/$element/_CONTENT_]
|
|
}
|
|
"-getatt" {
|
|
set attribute [lindex $arglist 0]
|
|
set retVal [::utility::tabget hmm_xml $tpath/_ATTLIST_/$attribute]
|
|
}
|
|
"-delel" {
|
|
set element [lindex $arglist 0]
|
|
::utility::tabdel hmm_xml $tpath/$element
|
|
}
|
|
"-delatt" {
|
|
set attribute [lindex $arglist 0]
|
|
::utility::tabdel hmm_xml $tpath/_ATTLIST_/$attribute
|
|
}
|
|
"-clear" {
|
|
::utility::tabdel hmm_xml $tpath/_ATTLIST_
|
|
::utility::tabdel hmm_xml $tpath/_CONTENT_
|
|
foreach element [::utility::tabget hmm_xml $tpath/_ELEMENTS_] {
|
|
::utility::tabdel hmm_xml $tpath/$element
|
|
}
|
|
}
|
|
"-setdata" {
|
|
if {[llength $arglist] == 1} {
|
|
set arglist [lindex $arglist 0]
|
|
}
|
|
foreach {name value} $arglist {
|
|
if {$value == ""} {
|
|
error "ERROR: No value supplied when setting $name at $tpath in the histogram memory table"
|
|
}
|
|
::utility::tabset hmm_xml $tpath/_DATA_/$name $value
|
|
}
|
|
}
|
|
"-getdata" {
|
|
if {[llength $arglist] == 1} {
|
|
set arglist [lindex $arglist 0]
|
|
}
|
|
if {[llength $arglist] <= 1} {
|
|
set retVal [::utility::tabget hmm_xml $tpath/_DATA_/$arglist]
|
|
} else {
|
|
foreach name $arglist {
|
|
lappend values [::utility::tabget hmm_xml $tpath/_DATA_/$name]
|
|
}
|
|
set retVal $values
|
|
}
|
|
}
|
|
"-getxml" {
|
|
set retVal [::utility::tabxml hmm_xml $tpath]
|
|
}
|
|
}
|
|
} message ] {
|
|
return -code error "([info level 0]) $message"
|
|
} else {
|
|
return $retVal
|
|
}
|
|
}
|
|
|
|
##
|
|
# @brief Base Address Table configuration parameters as maintained by SICS
|
|
#
|
|
proc BAT_TABLE {args} {
|
|
if [ catch {
|
|
set attributes { NO_BAT_ENTRIES NO_BAT_PERIODS NO_REPEAT_ENTRY NO_REPEAT_TABLE NO_EXECUTE_TABLE }
|
|
set elements {{PERIOD_INDICES }}
|
|
|
|
set tag BAT
|
|
foreach {opt arglist} [::utility::get_opt_arglist $args] {}
|
|
switch -- $opt {
|
|
"" {
|
|
return [HISTMEM_TABLE $tag -getxml]
|
|
}
|
|
"-init" {
|
|
HISTMEM_TABLE $tag -allowed_elements $elements
|
|
HISTMEM_TABLE $tag -allowed_attributes [concat $attributes $arglist]
|
|
}
|
|
"-set" {
|
|
set allowed_atts [HISTMEM_TABLE $tag -allowed_attributes]
|
|
set allowed_els [HISTMEM_TABLE $tag -allowed_elements]
|
|
foreach {arg val} $arglist {
|
|
set index [lsearch -exact $allowed_els $arg]
|
|
if {$index >= 0} {
|
|
incr index
|
|
HISTMEM_TABLE $tag -setel $arg $val
|
|
} else {
|
|
set attname $arg
|
|
set index [lsearch -exact $allowed_atts $attname]
|
|
if {$index >= 0} {
|
|
incr index
|
|
HISTMEM_TABLE $tag -setatt $attname $val
|
|
}
|
|
}
|
|
}
|
|
}
|
|
"-get" {
|
|
set allowed_atts [HISTMEM_TABLE $tag -allowed_attributes]
|
|
set allowed_els [HISTMEM_TABLE $tag -allowed_elements]
|
|
foreach arg $arglist {
|
|
set index [lsearch -exact $allowed_els $arg]
|
|
if {$index >= 0} {
|
|
lappend values [HISTMEM_TABLE $tag -getel $arg]
|
|
} else {
|
|
set attname $arg
|
|
set index [lsearch -exact $allowed_atts $attname]
|
|
if {$index >= 0} {
|
|
lappend values [HISTMEM_TABLE $tag -getatt $attname]
|
|
}
|
|
}
|
|
}
|
|
if {[llength $values] == 1} {
|
|
return [lindex $values 0]
|
|
} else {
|
|
return $values
|
|
}
|
|
}
|
|
"-del" {
|
|
foreach att [lindex $attributes 0] el [lindex $elements 0] {
|
|
set index [lsearch -exact $arglist $el]
|
|
if {$index >= 0} {
|
|
HISTMEM_TABLE $tag -delel $el
|
|
}
|
|
set index [lsearch -exact $arglist $att]
|
|
if {$index >= 0} {
|
|
HISTMEM_TABLE $tag -delatt $att
|
|
}
|
|
}
|
|
}
|
|
"-setdata" {
|
|
HISTMEM_TABLE $tag -setdata $arglist
|
|
}
|
|
"-getdata" {
|
|
return [HISTMEM_TABLE $tag -getdata $arglist]
|
|
}
|
|
"-clear" {
|
|
HISTMEM_TABLE $tag -clear
|
|
}
|
|
default {
|
|
error "ERROR: Unknown subcommand $opt"
|
|
}
|
|
}
|
|
} message ] {
|
|
if {$::errorCode=="NONE"} {return $message}
|
|
return -code error "([info level 0]) $message"
|
|
}
|
|
}
|
|
|
|
##
|
|
# @brief CAlibration Table configuration parameters as maintained by SICS
|
|
#
|
|
proc CAT_TABLE {args} {
|
|
if [ catch {
|
|
set attributes { FRAME_FREQUENCY SIZE_PERIOD COUNT_METHOD COUNT_SIZE READ_DATA_TYPE }
|
|
set elements {{MESYTEC_MPSD8_CHANNEL_GAINS MESYTEC_MPSD8_THRESHOLDS MESYTEC_TUBE_PAIR_RESISTANCE_RATIOS MESYTEC_TUBE_MAGNIFICATIONS MESYTEC_TUBE_OFFSETS MESYTEC_TUBE_HISTOGRAM_WEIGHTS }}
|
|
|
|
set tag CAT
|
|
foreach {opt arglist} [::utility::get_opt_arglist $args] {}
|
|
switch -- $opt {
|
|
"" {
|
|
return [HISTMEM_TABLE $tag -getxml]
|
|
}
|
|
"-init" {
|
|
HISTMEM_TABLE $tag -allowed_elements $elements
|
|
HISTMEM_TABLE $tag -allowed_attributes [concat $attributes $arglist]
|
|
}
|
|
"-set" {
|
|
set allowed_atts [HISTMEM_TABLE $tag -allowed_attributes]
|
|
set allowed_els [HISTMEM_TABLE $tag -allowed_elements]
|
|
foreach {arg val} $arglist {
|
|
set index [lsearch -exact $allowed_els $arg]
|
|
if {$index >= 0} {
|
|
incr index
|
|
HISTMEM_TABLE $tag -setel $arg $val
|
|
} else {
|
|
set attname $arg
|
|
set index [lsearch -exact $allowed_atts $attname]
|
|
if {$index >= 0} {
|
|
incr index
|
|
HISTMEM_TABLE $tag -setatt $attname $val
|
|
}
|
|
}
|
|
}
|
|
}
|
|
"-get" {
|
|
set allowed_atts [HISTMEM_TABLE $tag -allowed_attributes]
|
|
set allowed_els [HISTMEM_TABLE $tag -allowed_elements]
|
|
foreach arg $arglist {
|
|
set index [lsearch -exact $allowed_els $arg]
|
|
if {$index >= 0} {
|
|
lappend values [HISTMEM_TABLE $tag -getel $arg]
|
|
} else {
|
|
set attname $arg
|
|
set index [lsearch -exact $allowed_atts $attname]
|
|
if {$index >= 0} {
|
|
lappend values [HISTMEM_TABLE $tag -getatt $attname]
|
|
}
|
|
}
|
|
}
|
|
if {[llength $values] == 1} {
|
|
return [lindex $values 0]
|
|
} else {
|
|
return $values
|
|
}
|
|
}
|
|
"-del" {
|
|
foreach att [lindex $attributes 0] el [lindex $elements 0] {
|
|
set index [lsearch -exact $arglist $el]
|
|
if {$index >= 0} {
|
|
HISTMEM_TABLE $tag -delel $el
|
|
}
|
|
set index [lsearch -exact $arglist $att]
|
|
if {$index >= 0} {
|
|
HISTMEM_TABLE $tag -delatt $att
|
|
}
|
|
}
|
|
}
|
|
"-setdata" {
|
|
HISTMEM_TABLE $tag -setdata $arglist
|
|
}
|
|
"-getdata" {
|
|
return [HISTMEM_TABLE $tag -getdata $arglist]
|
|
}
|
|
"-clear" {
|
|
HISTMEM_TABLE $tag -clear
|
|
}
|
|
default {
|
|
error "ERROR: Unknown subcommand $opt"
|
|
}
|
|
}
|
|
} message ] {
|
|
if {$::errorCode=="NONE"} {return $message}
|
|
return -code error "([info level 0]) $message"
|
|
}
|
|
}
|
|
|
|
##
|
|
# @brief Frequency Address Table configuration parameters as maintained by SICS
|
|
#
|
|
proc FAT_TABLE {args} {
|
|
if [ catch {
|
|
set attributes { FRAME_FREQUENCY FRAME_BUFFER FRAME_DUTYCYCLE SIZE_PERIOD NOS_PERIODS COUNT_METHOD COUNT_SIZE READ_DATA_TYPE VIEW_MAG_X VIEW_MAG_Y HISTO_STREAMING P7888_PLL_FREQ_CARD_X P7888_PLL_FREQ_CARD_Y P7888_CARD_MODE_X P7888_CARD_MODE_Y RAW_HISTO_XMIN RAW_HISTO_XMAX RAW_HISTO_YMIN RAW_HISTO_YMAX TEST_HISTO_1D_SIZES TEST_HISTO_2D_SIZES P7888_PLL_SYNC_METHOD COUNT_ROI_XMIN COUNT_ROI_XMAX COUNT_ROI_YMIN COUNT_ROI_YMAX COUNT_ROI_TMIN COUNT_ROI_TMAX COUNT_ROI_TYPE COUNT_ROI_REGION COUNT_ROI_K1 }
|
|
|
|
set elements {{ }}
|
|
|
|
set tag FAT
|
|
foreach {opt arglist} [::utility::get_opt_arglist $args] {}
|
|
switch -- $opt {
|
|
"" {
|
|
return [HISTMEM_TABLE $tag -getxml]
|
|
}
|
|
"-init" {
|
|
HISTMEM_TABLE $tag -allowed_elements $elements
|
|
HISTMEM_TABLE $tag -allowed_attributes [concat $attributes $arglist]
|
|
}
|
|
"-set" {
|
|
set allowed_atts [HISTMEM_TABLE $tag -allowed_attributes]
|
|
set allowed_els [HISTMEM_TABLE $tag -allowed_elements]
|
|
foreach {arg val} $arglist {
|
|
set index [lsearch -exact $allowed_els $arg]
|
|
if {$index >= 0} {
|
|
incr index
|
|
HISTMEM_TABLE $tag -setel $arg $val
|
|
} else {
|
|
set attname $arg
|
|
set index [lsearch -exact $allowed_atts $attname]
|
|
if {$index >= 0} {
|
|
incr index
|
|
HISTMEM_TABLE $tag -setatt $attname $val
|
|
}
|
|
}
|
|
}
|
|
}
|
|
"-get" {
|
|
set allowed_atts [HISTMEM_TABLE $tag -allowed_attributes]
|
|
set allowed_els [HISTMEM_TABLE $tag -allowed_elements]
|
|
foreach arg $arglist {
|
|
set index [lsearch -exact $allowed_els $arg]
|
|
if {$index >= 0} {
|
|
lappend values [HISTMEM_TABLE $tag -getel $arg]
|
|
} else {
|
|
set attname $arg
|
|
set index [lsearch -exact $allowed_atts $attname]
|
|
if {$index >= 0} {
|
|
lappend values [HISTMEM_TABLE $tag -getatt $attname]
|
|
}
|
|
}
|
|
}
|
|
if {[llength $values] == 1} {
|
|
return [lindex $values 0]
|
|
} else {
|
|
return $values
|
|
}
|
|
}
|
|
"-del" {
|
|
foreach att [lindex $attributes 0] el [lindex $elements 0] {
|
|
set index [lsearch -exact $arglist $el]
|
|
if {$index >= 0} {
|
|
HISTMEM_TABLE $tag -delel $el
|
|
}
|
|
set index [lsearch -exact $arglist $att]
|
|
if {$index >= 0} {
|
|
HISTMEM_TABLE $tag -delatt $att
|
|
}
|
|
}
|
|
}
|
|
"-setdata" {
|
|
HISTMEM_TABLE $tag -setdata $arglist
|
|
}
|
|
"-getdata" {
|
|
return [HISTMEM_TABLE $tag -getdata $arglist]
|
|
}
|
|
"-clear" {
|
|
HISTMEM_TABLE $tag -clear
|
|
}
|
|
default {
|
|
error "ERROR: Unknown subcommand $opt"
|
|
}
|
|
}
|
|
} message ] {
|
|
if {$::errorCode=="NONE"} {return $message}
|
|
return -code error "([info level 0]) $message"
|
|
}
|
|
}
|
|
|
|
##
|
|
# @brief Offset Address Table configuration parameters as maintained by SICS
|
|
#
|
|
# @param -clear clears OAT_TABLE XML fragment
|
|
# @param -init X_MIN <x0> X_MAX <x1> Y_MIN <y0> Y_MAX <y1>
|
|
# Initialise minimum and maximum bin boundaries.
|
|
# @param -get
|
|
# @param -attlist
|
|
# @param -clear clears the oat table and the fat table SIZE_PERIOD
|
|
#
|
|
# Sets X_BOUNDARIES, Y_BOUNDARIES and T_BOUNDARIES
|
|
proc OAT_TABLE {args} {
|
|
if [ catch {
|
|
array set attlookup {NXC NO_OAT_X_CHANNELS NYC NO_OAT_Y_CHANNELS NTC NO_OAT_T_CHANNELS}
|
|
set elements {{ X Y T }}
|
|
|
|
set tag OAT
|
|
set element [lindex $args 0]
|
|
if {[ lsearch [lindex $elements 0] $element] == -1} {
|
|
unset element
|
|
} else {
|
|
set tag $tag/$element
|
|
set args [lrange $args 1 end]
|
|
}
|
|
foreach {opt arglist} [::utility::get_opt_arglist $args] {}
|
|
switch -- $opt {
|
|
"" {
|
|
return [HISTMEM_TABLE $tag -getxml]
|
|
}
|
|
"-init" {
|
|
HISTMEM_TABLE $tag -allowed_elements $elements
|
|
foreach {n v} [array get attlookup] {
|
|
lappend attributes $v
|
|
}
|
|
HISTMEM_TABLE $tag -allowed_attributes [concat $attributes $arglist]
|
|
}
|
|
"-set" {
|
|
set allowed_atts [HISTMEM_TABLE $tag -allowed_attributes]
|
|
set allowed_els [HISTMEM_TABLE $tag -allowed_elements]
|
|
foreach {arg val} $arglist {
|
|
set index [lsearch -exact $allowed_els $arg]
|
|
if {$index >= 0} {
|
|
incr index
|
|
HISTMEM_TABLE $tag -setel $arg $val
|
|
} else {
|
|
if [info exists attlookup($arg)] {
|
|
set attname $attlookup($arg)
|
|
} else {
|
|
set attname $arg
|
|
}
|
|
set index [lsearch -exact $allowed_atts $attname]
|
|
if {$index >= 0} {
|
|
incr index
|
|
HISTMEM_TABLE $tag -setatt $attname $val
|
|
}
|
|
}
|
|
}
|
|
foreach {nxc nyc} [OAT_TABLE -get NXC NYC] {}
|
|
set max_nxc [::histogram_memory::max_chan_num X]
|
|
set max_nyc [::histogram_memory::max_chan_num Y]
|
|
if {$nxc > $max_nxc} {
|
|
gumput "WARNING: Reducing NO_OAT_X_CHANNELS from $nxc to maximum $max_nxc" warning
|
|
OAT_TABLE -set NXC $max_nxc
|
|
}
|
|
if {$nyc > $max_nyc} {
|
|
gumput "WARNING: Reducing NO_OAT_Y_CHANNELS from $nyc to maximum $max_nyc" warning
|
|
OAT_TABLE -set NYC $max_nyc
|
|
}
|
|
foreach axis {X Y T} {
|
|
set bins [::histogram_memory::oat_bins $axis]
|
|
set nch [::histogram_memory::number_of_channels $axis]
|
|
OAT_TABLE $axis -setdata BOUNDARIES [::histogram_memory::calc_boundaries $bins $nch]
|
|
}
|
|
}
|
|
"-get" {
|
|
set allowed_atts [HISTMEM_TABLE $tag -allowed_attributes]
|
|
set allowed_els [HISTMEM_TABLE $tag -allowed_elements]
|
|
foreach arg $arglist {
|
|
set index [lsearch -exact $allowed_els $arg]
|
|
if {$index >= 0} {
|
|
lappend values [HISTMEM_TABLE $tag -getel $arg]
|
|
} else {
|
|
if [info exists attlookup($arg)] {
|
|
set attname $attlookup($arg)
|
|
} else {
|
|
set attname $arg
|
|
}
|
|
set index [lsearch -exact $allowed_atts $attname]
|
|
if {$index >= 0} {
|
|
lappend values [HISTMEM_TABLE $tag -getatt $attname]
|
|
}
|
|
}
|
|
}
|
|
if {[llength $values] == 1} {
|
|
return [lindex $values 0]
|
|
} else {
|
|
return $values
|
|
}
|
|
}
|
|
"-del" {
|
|
foreach att [array names attlookup] el [lindex $elements 0] {
|
|
set index [lsearch -exact $arglist $el]
|
|
if {$index >= 0} {
|
|
HISTMEM_TABLE $tag -delel $el
|
|
}
|
|
set index [lsearch -exact $arglist $att]
|
|
if {$index >= 0} {
|
|
HISTMEM_TABLE $tag -delatt $attlookup($att)
|
|
}
|
|
}
|
|
}
|
|
"-setdata" {
|
|
HISTMEM_TABLE $tag -setdata $arglist
|
|
}
|
|
"-getdata" {
|
|
return [HISTMEM_TABLE $tag -getdata $arglist]
|
|
}
|
|
"-clear" {
|
|
HISTMEM_TABLE $tag -clear
|
|
}
|
|
default {
|
|
error "ERROR: Unknown subcommand $opt"
|
|
}
|
|
}
|
|
} message ] {
|
|
if {$::errorCode=="NONE"} {return $message}
|
|
return -code error "([info level 0]) $message"
|
|
}
|
|
}
|
|
|
|
# @brief Spatial Allocation Table configuration parameters as maintained by SICS
|
|
#
|
|
# Only one element, ie SPLIT with no content just attributes.
|
|
proc SAT_TABLE {args} {
|
|
if [ catch {
|
|
set attributes { APPLY MIDPOINT DIRECTION WRAP SWAP}
|
|
set elements {{ SPLIT }}
|
|
|
|
set tag SAT
|
|
set attpath SAT/SPLIT
|
|
foreach {opt arglist} [::utility::get_opt_arglist $args] {}
|
|
switch -- $opt {
|
|
"" {
|
|
return [HISTMEM_TABLE $tag -getxml]
|
|
}
|
|
"-init" {
|
|
HISTMEM_TABLE $tag -allowed_elements $elements
|
|
HISTMEM_TABLE $attpath -allowed_attributes [concat $attributes $arglist]
|
|
}
|
|
"-set" {
|
|
set allowed_atts [HISTMEM_TABLE $attpath -allowed_attributes]
|
|
set allowed_els [HISTMEM_TABLE $tag -allowed_elements]
|
|
foreach {arg val} $arglist {
|
|
set index [lsearch -exact $allowed_els $arg]
|
|
if {$index >= 0} {
|
|
incr index
|
|
HISTMEM_TABLE $tag -setel $arg $val
|
|
} else {
|
|
set attname $arg
|
|
set index [lsearch -exact $allowed_atts $attname]
|
|
if {$index >= 0} {
|
|
incr index
|
|
HISTMEM_TABLE $attpath -setatt $attname $val
|
|
}
|
|
}
|
|
}
|
|
}
|
|
"-get" {
|
|
set allowed_atts [HISTMEM_TABLE $attpath -allowed_attributes]
|
|
set allowed_els [HISTMEM_TABLE $tag -allowed_elements]
|
|
foreach arg $arglist {
|
|
set index [lsearch -exact $allowed_els $arg]
|
|
if {$index >= 0} {
|
|
lappend values [HISTMEM_TABLE $tag -getel $arg]
|
|
} else {
|
|
set attname $arg
|
|
set index [lsearch -exact $allowed_atts $attname]
|
|
if {$index >= 0} {
|
|
lappend values [HISTMEM_TABLE $tag -getatt $attname]
|
|
}
|
|
}
|
|
}
|
|
if {[llength $values] == 1} {
|
|
return [lindex $values 0]
|
|
} else {
|
|
return $values
|
|
}
|
|
}
|
|
"-del" {
|
|
foreach att $attributes {
|
|
set index [lsearch -exact $arglist $att]
|
|
if {$index >= 0} {
|
|
HISTMEM_TABLE $attpath -delatt $att
|
|
}
|
|
}
|
|
}
|
|
"-setdata" {
|
|
HISTMEM_TABLE $tag -setdata $arglist
|
|
}
|
|
"-getdata" {
|
|
return [HISTMEM_TABLE $tag -getdata $arglist]
|
|
}
|
|
"-clear" {
|
|
HISTMEM_TABLE $tag -clear
|
|
HISTMEM_TABLE $attpath -allowed_attributes $attributes
|
|
}
|
|
default {
|
|
error "ERROR: Unknown subcommand $opt"
|
|
}
|
|
}
|
|
} message ] {
|
|
if {$::errorCode=="NONE"} {return $message}
|
|
return -code error "([info level 0]) $message"
|
|
}
|
|
}
|
|
|
|
proc ::histogram_memory::pre_count {} {}
|
|
proc ::histogram_memory::post_count {} {}
|
|
|
|
##
|
|
# @brief Resolve dependencies between the histogram memory tables
|
|
proc ::histogram_memory::synch_tables {} {
|
|
if [ catch {
|
|
set noxch [OAT_TABLE -get NXC]
|
|
set noych [OAT_TABLE -get NYC]
|
|
set notch [OAT_TABLE -get NTC]
|
|
FAT_TABLE -set SIZE_PERIOD [expr $noxch*$noych*$notch]
|
|
} message ] {
|
|
return -code error "([info level 0]) $message"
|
|
}
|
|
}
|
|
|
|
proc ::histogram_memory::clear_tables {} {
|
|
if [ catch {
|
|
set ::errorInfo ""
|
|
BAT_TABLE -clear
|
|
CAT_TABLE -clear
|
|
FAT_TABLE -clear
|
|
OAT_TABLE -clear
|
|
SAT_TABLE -clear
|
|
} message ] {
|
|
return -code error "([info level 0]) $message"
|
|
}
|
|
}
|
|
|
|
##
|
|
# @brief Calculate the maximum number of oat channels from the generating bin
|
|
# boundaries of the given axis
|
|
proc ::histogram_memory::max_chan_num {axis} {
|
|
if [ catch {
|
|
set bins [OAT_TABLE -get $axis]
|
|
set numb_bins [llength $bins]
|
|
if {$numb_bins < 2} {
|
|
error "ERROR: $axis must have at least two bin boundaries"
|
|
} elseif {$numb_bins > 2} {
|
|
return $numb_bins
|
|
} else {
|
|
foreach {leftbb rightbb} $bins {}
|
|
set bstep [expr $rightbb - $leftbb]
|
|
if {$bstep == 0} {
|
|
error "ERROR: Bin boundaries for $axis must not be equal"
|
|
} elseif {$bstep < 0} {
|
|
set binlim [OAT_TABLE $axis -getdata BMIN]
|
|
} else {
|
|
set binlim [OAT_TABLE $axis -getdata BMAX]
|
|
}
|
|
}
|
|
set numb_bins [expr {int(floor(($binlim - $leftbb)/$bstep))}]
|
|
return $numb_bins
|
|
} message ] {
|
|
if {$::errorCode=="NONE"} {return $message}
|
|
return -code error "([info level 0]) $message"
|
|
}
|
|
}
|
|
##
|
|
# @brief When called without arguments this returns the name of the filler defaults file
|
|
# for the histogram server. When called with an argument it sets the current name of the
|
|
# filler defaults file.
|
|
#
|
|
# When anstohm_linked.xml is uploaded to the histogram server it calls this via
|
|
# command substitution to set the name of the filler defaults file.
|
|
proc ::histogram_memory::filler_defaults {args} {
|
|
variable hmm_def_filename
|
|
if [ catch {
|
|
if {[llength $args] > 0} {
|
|
set hmm_def_filename $args
|
|
}
|
|
} message ] {
|
|
return -code error "([info level 0]) $message"
|
|
}
|
|
return $hmm_def_filename
|
|
}
|
|
|
|
##
|
|
# @brief Returns the oat table bin boundaries.
|
|
# This function can be replaced with an instrument specific definition
|
|
# in the instrumenent specific configuration file.
|
|
proc ::histogram_memory::oat_bins {axis} {
|
|
if [ catch {
|
|
set bins [OAT_TABLE -get $axis]
|
|
} message ] {
|
|
return -code error "([info level 0]) $message"
|
|
}
|
|
return $bins
|
|
}
|
|
|
|
##
|
|
# @brief Returns the current number of channels for a given axis.
|
|
# This function can be replaced with an instrument specific definition
|
|
# in the instrumenent specific configuration file.
|
|
proc ::histogram_memory::number_of_channels {axis} {
|
|
array set channID {X NXC Y NYC T NTC}
|
|
if [ catch {
|
|
set nchans [OAT_TABLE -get $channID($axis)]
|
|
} message ] {
|
|
return -code error "([info level 0]) $message"
|
|
}
|
|
return $nchans
|
|
}
|
|
|
|
# TODO Set current oat table after uploading proposed oat_table
|
|
proc ::histogram_memory::upload_config {filler_defaults} {
|
|
if [ catch {
|
|
::histogram_memory::synch_tables
|
|
::histogram_memory::filler_defaults $filler_defaults
|
|
hmm astop
|
|
wait 5
|
|
hmm configure init 1
|
|
hmm init
|
|
# Restore the init level to 0
|
|
# subesquent inits will only upload specified FAT settings to histogram server.
|
|
hmm configure init 0
|
|
hmm init
|
|
|
|
# Now issue stop to the server.
|
|
# This not only makes sure it's stopped, but lets us see certain configuration variables
|
|
# which get placed in the dictionary as part of the status checking done during the stop.
|
|
hmm configure statuscheck true
|
|
hmm astop
|
|
hmm configure statuscheck false
|
|
# ::histogram_memory::configure_dims
|
|
# foreach axis {X Y T} {
|
|
# set bins [oat_bins $axis]
|
|
# set nch [number_of_channels $axis]
|
|
# OAT_TABLE $axis -setdata BOUNDARIES [calc_boundaries $bins $nch]
|
|
# }
|
|
clientput "histmem configuration uploaded"
|
|
} message ] {
|
|
if {$::errorCode=="NONE"} {
|
|
return $message
|
|
} else {
|
|
return -code error "([info level 0]) $message"
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
##
|
|
# @brief If set to true then the frame_source will always be set to INTERNAL.
|
|
#
|
|
# @see ::histogram_memory::set_frame_source
|
|
proc ::histogram_memory::frame_source_always_internal {args} {
|
|
variable fs_always_internal
|
|
|
|
if [ catch {
|
|
if {$args == ""} {
|
|
return $fs_always_internal
|
|
}
|
|
set flag [lindex $args 0]
|
|
if {[string is boolean $flag] == 0} {
|
|
error "ERROR: $args must be a boolean"
|
|
} else {
|
|
set fs_always_internal $flag
|
|
}
|
|
} message ] {
|
|
if {$::errorCode=="NONE"} {return $message}
|
|
return -code error "([info level 0]) $message"
|
|
}
|
|
}
|
|
publish ::histogram_memory::frame_source_always_internal mugger
|
|
##
|
|
# @brief Return the last frame source which SICS attempted to set
|
|
proc ::histogram_memory::get_frame_source {} {
|
|
if [ catch {
|
|
if [::histogram_memory::frame_source_always_internal] {
|
|
clientput "WARNING: The frame source is set to always_internal" value
|
|
clientput "Use ::histogram_memory::frame_source_always_internal <true/false> to change this." value
|
|
return INTERNAL
|
|
} else {
|
|
return [SplitReply [hmm configure fat_frame_source]]
|
|
}
|
|
} message ] {
|
|
if {$::errorCode=="NONE"} {return $message}
|
|
return -code error "([info level 0]) $message"
|
|
}
|
|
}
|
|
##
|
|
# @brief Sets the histogram memory frame source to the given value.
|
|
#
|
|
# @param srce EXTERNAL or INTERNAL
|
|
# @param always_internal true or false (optional) (default false)
|
|
proc ::histogram_memory::set_frame_source {srce} {
|
|
variable ic_fsrce_values
|
|
|
|
if [ catch {
|
|
if {[lsearch $ic_fsrce_values $srce] == -1} {
|
|
error "ERROR: $srce is invalid, valid values are \"$ic_fsrce_values\""
|
|
}
|
|
if [::histogram_memory::frame_source_always_internal] {
|
|
clientput "WARNING: The frame source is set to always_internal" value
|
|
clientput "Use ::histogram_memory::frame_source_always_internal <true/false> to change this." value
|
|
hmm configure fat_frame_source INTERNAL
|
|
} else {
|
|
hmm configure fat_frame_source $srce
|
|
}
|
|
::histogram_memory::stop
|
|
hmm init
|
|
} message ] {
|
|
return -code error "([info level 0]) $message"
|
|
}
|
|
}
|
|
##
|
|
# @brief Return the last frame frequency which SICS attempted to set
|
|
proc ::histogram_memory::get_frame_freq {} {
|
|
if [ catch {
|
|
set frameFreq [SplitReply [hmm configure fat_frame_frequency]]
|
|
} message ] {
|
|
return -code error "([info level 0]) $message"
|
|
}
|
|
return $frameFreq
|
|
}
|
|
|
|
##
|
|
# @brief Sets the histogram memory frame frequency to the given value.
|
|
#
|
|
# @param freq Frequency in Hz.\n
|
|
# @param frame_source INTERNAL or EXTERNAL(default)
|
|
#
|
|
# If freq=0 then it sets the frequency to 50Hz with an internal frame source. This is useful
|
|
# if you are setting the frequency from a chopper which is stopped.
|
|
proc ::histogram_memory::set_frame_freq {freq {frame_source EXTERNAL}} {
|
|
variable state
|
|
variable default_frame_source_when_there_is_no_frame_signal
|
|
|
|
if [ catch {
|
|
if {[string is double $freq] == 0 || $freq < 0} {
|
|
error "ERROR: Frequency must be a non-negative floating point number"
|
|
}
|
|
|
|
#TODO Add tolerance parameters to choppercontroller
|
|
if {abs($freq - 0) <= [expr {2.0/60.0}]} {
|
|
set zf_frame_source $default_frame_source_when_there_is_no_frame_signal([instname])
|
|
if {$zf_frame_source == "INTERNAL"} {
|
|
clientput "WARNING: A histmem frame frequency of zero was requested, setting frequency to 50Hz instead" value
|
|
} else {
|
|
clientput "WARNING: A histmem frame frequency of zero was requested, setting frequency to 50Hz instead" value
|
|
clientput "WARNING: You must provide an external oscillator" value
|
|
}
|
|
::histogram_memory::set_frame_source $zf_frame_source
|
|
set newfreq 50
|
|
} else {
|
|
::histogram_memory::set_frame_source [string toupper $frame_source]
|
|
::set newfreq $freq
|
|
}
|
|
::histogram_memory::stop
|
|
hmm configure fat_frame_frequency $newfreq
|
|
hmm init
|
|
} message ] {
|
|
return -code error "([info level 0]) $message"
|
|
}
|
|
}
|
|
publish ::histogram_memory::set_frame_freq user
|
|
|
|
proc ::histogram_memory::t_max {} {
|
|
if [ catch {
|
|
set frame_freq [SplitReply [hmm configure fat_frame_frequency]]
|
|
} message ] {
|
|
return -code error "([info level 0]) $message"
|
|
}
|
|
}
|
|
|
|
##
|
|
# @brief Total counts in histogram defined by the OAT table.
|
|
::utility::macro::getset int ::histogram_memory::total_counts {} {
|
|
return "total_counts = [SplitReply [hmm configure num_events_filled_to_histo]]"
|
|
}
|
|
sicslist setatt ::histogram_memory::total_counts klass detector
|
|
sicslist setatt ::histogram_memory::total_counts long_name total_counts
|
|
sicslist setatt ::histogram_memory::total_counts mutable true
|
|
sicslist setatt ::histogram_memory::total_counts units count
|
|
sicslist setatt ::histogram_memory::total_counts link data_set
|
|
|
|
##
|
|
# @brief Histogram memory dataset directory
|
|
::utility::macro::getset text ::histogram_memory::daq_dirname {} {
|
|
return "daq_dirname = [SplitReply [hmm configure daq_dirname]]"
|
|
}
|
|
sicslist setatt ::histogram_memory::daq_dirname klass detector
|
|
sicslist setatt ::histogram_memory::daq_dirname long_name daq_dirname
|
|
sicslist setatt ::histogram_memory::daq_dirname mutable false
|
|
|
|
##
|
|
# @brief Histogram memory acquisition time
|
|
::utility::macro::getset float ::histogram_memory::time {} {
|
|
return "time = [SplitReply [hmm configure acq_dataset_active_sec]]"
|
|
}
|
|
sicslist setatt ::histogram_memory::time klass detector
|
|
sicslist setatt ::histogram_memory::time long_name time
|
|
sicslist setatt ::histogram_memory::time mutable true
|
|
sicslist setatt ::histogram_memory::time units seconds
|
|
|
|
##
|
|
# @brief Histogram memory acquisition start_time
|
|
::utility::macro::getset int ::histogram_memory::start_time {} {
|
|
set start_time_sec [SplitReply [hmm configure acq_start_time_t]]
|
|
# set start_time [clock format $start_time_sec -format "%G-%m-%d %T"]
|
|
return "start_time = $start_time_sec"
|
|
}
|
|
sicslist setatt ::histogram_memory::start_time klass detector
|
|
sicslist setatt ::histogram_memory::start_time long_name start_time
|
|
sicslist setatt ::histogram_memory::start_time mutable true
|
|
sicslist setatt ::histogram_memory::start_time units seconds
|
|
|
|
##
|
|
# @brief Histogram memory acquisition stop_time
|
|
::utility::macro::getset int ::histogram_memory::stop_time {} {
|
|
set stop_time_sec [SplitReply [hmm configure acq_stop_time_t]]
|
|
# set stop_time [clock format $stop_time_sec -format "%G-%m-%d %T"]
|
|
return "stop_time = $stop_time_sec"
|
|
}
|
|
sicslist setatt ::histogram_memory::stop_time klass detector
|
|
sicslist setatt ::histogram_memory::stop_time long_name stop_time
|
|
sicslist setatt ::histogram_memory::stop_time mutable true
|
|
sicslist setatt ::histogram_memory::stop_time units seconds
|
|
|
|
::utility::macro::getset float ::histogram_memory::ratemap_xy_max_bin {} {
|
|
return "ratemap_xy_max_bin = [lindex [hmm configure ratemap_xy_max_bin] 2]"
|
|
}
|
|
sicslist setatt ::histogram_memory::ratemap_xy_max_bin klass detector
|
|
sicslist setatt ::histogram_memory::ratemap_xy_max_bin long_name max_binrate
|
|
sicslist setatt ::histogram_memory::ratemap_xy_max_bin mutable true
|
|
|
|
::utility::macro::getset float ::histogram_memory::ratemap_xy_total {} {
|
|
return "ratemap_xy_total = [lindex [hmm configure ratemap_xy_total] 2]"
|
|
}
|
|
sicslist setatt ::histogram_memory::ratemap_xy_total klass detector
|
|
sicslist setatt ::histogram_memory::ratemap_xy_total long_name total_maprate
|
|
sicslist setatt ::histogram_memory::ratemap_xy_total mutable true
|
|
|
|
# Returns 0 If all trips acknowledged, -n if n trips unacknowledged, +n if too many acks?
|
|
::utility::macro::getset float ::histogram_memory::reset_trip {args} {
|
|
set num_trips [ SplitReply [hmm configure detector_protect_num_trip] ]
|
|
set num_acks [ SplitReply [hmm configure detector_protect_num_trip_ack] ]
|
|
set trip_cnt_diff [expr {$num_acks - $num_trips}]
|
|
if {$args == ""} {
|
|
return "reset_trip = $trip_cnt_diff"
|
|
} else {
|
|
if {$trip_cnt_diff != 0} {
|
|
hmm configure fat_detector_protect_num_trip_ack $num_trips
|
|
hmm astop
|
|
wait 2
|
|
hmm init
|
|
}
|
|
}
|
|
}
|
|
sicslist setatt ::histogram_memory::reset_trip klass detector
|
|
sicslist setatt ::histogram_memory::reset_trip long_name reset_trip
|
|
sicslist setatt ::histogram_memory::reset_trip data false
|
|
|
|
##
|
|
# @brief Update the beam monitors when the histmem has finished counting.
|
|
proc ::histogram_memory::countend_event {} {
|
|
::histogram_memory::post_count
|
|
::histogram::histmem_cmd -set feedback status IDLE
|
|
bm status
|
|
}
|
|
publish ::histogram_memory::countend_event user
|
|
|
|
##
|
|
# @brief Sets histogram server to default configuration, initialises SICS histogram memory
|
|
# dictionary values and clears SICS OAT BAT CAT FAT ... tables
|
|
proc ::histogram_memory::ic_initialize {} {
|
|
variable default_frame_source_when_there_is_no_frame_signal
|
|
variable default_frame_source_always_internal
|
|
|
|
set ::errorInfo ""
|
|
if [ catch {
|
|
# Generate beam monitor feedback macros
|
|
foreach bm $::counter::isc_beam_monitor_list {
|
|
set bm_num [string index $bm end]
|
|
if [string is integer $bm_num] {
|
|
set bm_status bm${bm_num}_status
|
|
::utility::macro::getset text $bm_status {} [subst -nocommands {
|
|
return "$bm_status = [SplitReply [hmm configure $bm_status]]"
|
|
}]
|
|
sicslist setatt $bm_status klass monitor
|
|
sicslist setatt $bm_status long_name $bm_status
|
|
sicslist setatt $bm_status mutable false
|
|
|
|
set bm_event_rate bm${bm_num}_event_rate
|
|
::utility::macro::getset float $bm_event_rate {} [subst -nocommands {
|
|
return "$bm_event_rate = [lindex [hmm configure $bm_event_rate] 2]"
|
|
}]
|
|
sicslist setatt $bm_event_rate klass monitor
|
|
sicslist setatt $bm_event_rate long_name $bm_event_rate
|
|
sicslist setatt $bm_event_rate mutable true
|
|
sicslist setatt $bm_event_rate units "count/sec"
|
|
} else {
|
|
error "ERROR: Failed to get beam monitor number"
|
|
}
|
|
}
|
|
set configuration "::histogram_memory::returnconfigfile config/hmm/anstohm_linked.xml"
|
|
::histogram_memory::set_graphtype "y_bin" "boundaries"
|
|
::histogram_memory::set_graphtype "x_bin" "boundaries"
|
|
::histogram_memory::set_graphtype "y_pixel_offset" "boundaries"
|
|
::histogram_memory::set_graphtype "x_pixel_offset" "boundaries"
|
|
::histogram_memory::set_graphtype "time_channel" "boundaries"
|
|
::histogram_memory::clear_tables
|
|
# FAT_TABLE -set VIEW_MAG_X -1 VIEW_MAG_Y -1
|
|
|
|
foreach hm_obj [sicslist type histmem] {
|
|
set host [dict get $::HISTMEM_HOSTPORT HMM HOST]
|
|
set port [dict get $::HISTMEM_HOSTPORT HMM PORT]
|
|
$hm_obj configure hmaddress http://$host:$port
|
|
$hm_obj configure username SICS
|
|
$hm_obj configure password SICS
|
|
$hm_obj configure histmode transparent
|
|
}
|
|
# ::histogram_memory::initialise_dictionary
|
|
::histogram_memory::frame_source_always_internal $default_frame_source_always_internal([instname])
|
|
## ffr clock scale, frame freq and source should be set in instrument specific hmm_configuration.tcl to speed up initialisation
|
|
# ::histogram_memory::set_frame_freq 50
|
|
# ::histogram_memory::set_clock_scale 1000
|
|
# ::histogram_memory::set_frame_source $default_frame_source_when_there_is_no_frame_signal([instname])
|
|
::histogram_memory::count_method unlimited
|
|
::histogram_memory::count_size 0
|
|
::histogram_memory::softveto false
|
|
hmm configure hmDataPath ../HMData
|
|
hmm configure hmconfigscript $configuration
|
|
#XXX ::histogram_memory::configure_dims
|
|
scriptcallback connect hmm COUNTEND ::histogram_memory::countend_event
|
|
} message ] {
|
|
return -code error "([info level 0]) $message"
|
|
}
|
|
}
|
|
|
|
Publish ::histogram_memory::set_oat_offset user
|
|
Publish ::histogram_memory::scan2_runb user
|
|
Publish ::histogram_memory::scan2_runa user
|
|
Publish ::histogram_memory::returnconfigfile user
|
|
Publish ::histogram_memory::save user
|
|
Publish BAT_TABLE user
|
|
Publish CAT_TABLE user
|
|
Publish FAT_TABLE user
|
|
Publish OAT_TABLE user
|
|
Publish SAT_TABLE user
|
|
|
|
|
|
##
|
|
# @brief Start an acquisition, non-blocking by default
|
|
#
|
|
# @param block (optional) default="noblock"
|
|
proc ::histogram_memory::start {{blocking "noblock"}} {
|
|
variable histmem_simulation
|
|
variable monitor_controlled
|
|
|
|
if [ catch {
|
|
set options [list block noblock]
|
|
if {[lsearch $options $blocking] == -1} {
|
|
error "ERROR: Valid options are $options"
|
|
}
|
|
::histogram_memory::pre_count
|
|
## TODO Test monitor controlled counting
|
|
# set hm_start {hmm init}
|
|
# if {$monitor_controlled == "true"} {
|
|
# set hm_start {hmm count}
|
|
# } else {
|
|
# bm setmode timer
|
|
# bm setpreset 32000000
|
|
# }
|
|
if {$blocking == "block"} {
|
|
hmm countblock
|
|
} else {
|
|
hmm count
|
|
}
|
|
} message ] {
|
|
return -code error "([info level 0]) $message"
|
|
}
|
|
}
|
|
|
|
proc ::histogram_memory::softveto {{enable ""}} {
|
|
variable state
|
|
|
|
if {$enable == ""} {
|
|
return $state(veto)
|
|
}
|
|
if {[string is boolean $enable] == 0} {
|
|
error "ERROR: $enable must be a boolean"
|
|
} else {
|
|
if {$enable} {
|
|
hmm configure FAT_SOFT_VETO_1 ENABLE
|
|
} else {
|
|
hmm configure FAT_SOFT_VETO_1 DISABLE
|
|
}
|
|
}
|
|
}
|
|
|
|
proc ::histogram_memory::veto {action} {
|
|
switch $action {
|
|
"on" {
|
|
hmm veto
|
|
}
|
|
"off" {
|
|
hmm noveto
|
|
}
|
|
default {
|
|
error "ERROR: $action must be 'on' or 'off'"
|
|
}
|
|
}
|
|
}
|
|
|
|
##
|
|
# @brief This sends the magic incantation which stops the histogram server.
|
|
proc ::histogram_memory::stop {} {
|
|
variable histmem_simulation
|
|
if [ catch {
|
|
hmm pause
|
|
hmm configure statuscheck true
|
|
hmm astop
|
|
hmm configure statuscheck false
|
|
set reply [SplitReply [hmm configure daq]]
|
|
if {$histmem_simulation==false && $reply != "Stopped"} {
|
|
error "ERROR: Histogram server failed to stop"
|
|
}
|
|
} message ] {
|
|
return -code error "([info level 0]) $message"
|
|
}
|
|
clientput "histmem stopped" value
|
|
}
|
|
##
|
|
# @brief Allows resume if MULTIPLE_DATASETS=DISABLE, otherwise if MULTIPLE_DATASETS=ENABLE
|
|
# (the default) this acts like a stop but allows a fast restart.
|
|
proc ::histogram_memory::pause {} {
|
|
variable histmem_simulation
|
|
if [ catch {
|
|
hmm pause
|
|
::histogram_memory::post_count
|
|
set reply [SplitReply [hmm configure daq]]
|
|
if {$histmem_simulation==false && $reply != "Paused"} {
|
|
error "ERROR: Histogram server failed to pause"
|
|
}
|
|
} message ] {
|
|
return -code error "([info level 0]) $message"
|
|
}
|
|
clientput "histmem paused" value
|
|
}
|
|
|
|
##
|
|
# @brief Choose method for controlling acquisition duration.
|
|
#
|
|
# @param method Set histmem mode or return current mode if blank
|
|
proc ::histogram_memory::count_method {{method ""}} {
|
|
variable ic_count_methods
|
|
variable preset_mult
|
|
variable monitor_controlled
|
|
|
|
if {$method==""} {
|
|
return [SplitReply [hmm_mode]]
|
|
}
|
|
if [ catch {
|
|
set modes $ic_count_methods
|
|
if {[lsearch $modes $method] == -1} {
|
|
error "ERROR: Count mode, $method, must be one of $modes"
|
|
}
|
|
if {$method == "time"} {
|
|
set preset_mult 100
|
|
} else {
|
|
set preset_mult 1
|
|
}
|
|
hmm configure FAT_COUNT_METHOD $method
|
|
if {[string range $method 0 [string first "R_" $method]] == "MONITOR"} {
|
|
hmm configure FAT_${method}_CONTROL ENABLE
|
|
set bmchan [expr [string index $method end] - 1]
|
|
bm setchannel $bmchan
|
|
set monitor_controlled "true"
|
|
} else {
|
|
set monitor_controlled "false"
|
|
}
|
|
hmm astop
|
|
hmm init
|
|
hmm_mode $method
|
|
} message ] {
|
|
return -code error "([info level 0]) $message"
|
|
}
|
|
}
|
|
|
|
##
|
|
# @brief Count until the preset count size has been reached.
|
|
#
|
|
# @param preset: The interpretation of the preset depends on the count method.
|
|
# @see count_method
|
|
proc ::histogram_memory::count_size {{preset ""}} {
|
|
variable state
|
|
variable preset_mult
|
|
|
|
if [ catch {
|
|
if {$preset == ""} {
|
|
return $state(preset)
|
|
} else {
|
|
if {[string is double $preset] == 0 || $preset < 0} {
|
|
error "ERROR: The preset must be a non-negative floating point number"
|
|
}
|
|
hmm configure FAT_COUNT_SIZE [expr {$preset_mult * $preset}]
|
|
hmm init
|
|
set state(preset) $preset
|
|
hmm_preset $preset
|
|
}
|
|
} message ] {
|
|
if {$::errorCode=="NONE"} {return $message}
|
|
return -code error "([info level 0]) $message"
|
|
}
|
|
}
|
|
|
|
##
|
|
# @brief Check histogram memory status
|
|
#
|
|
# @return Stopped, Paused, Started, or raises a Tcl error
|
|
proc ::histogram_memory::hmm_status {} {
|
|
if [ catch {
|
|
set reply [SplitReply [hmm configure daq]]
|
|
} message ] {
|
|
return -code error "([info level 0]) $message"
|
|
}
|
|
return $reply
|
|
}
|
|
|
|
##
|
|
# @brief Set stop condition for histogram memory
|
|
#
|
|
# @param condition
|
|
proc ::histogram_memory::stop_condition {condition} {
|
|
variable state
|
|
if [ catch {
|
|
array set count_stop {immediate IMMEDIATE period AT_END_OF_PERIOD}
|
|
if {$condition == ""} {
|
|
return $state(stop_cond)
|
|
} else {
|
|
hmm configure FAT_COUNT_STOP $count_stop($condition)
|
|
hmm init
|
|
set state(stop_cond) $condition
|
|
}
|
|
} message ] {
|
|
if {$::errorCode=="NONE"} {return $message}
|
|
return -code error "([info level 0]) $message"
|
|
}
|
|
}
|
|
|
|
# Make controller for histmem textstatus. Used by hmstat proc
|
|
set host [dict get $::HISTMEM_HOSTPORT HMSTAT HOST]
|
|
set port [dict get $::HISTMEM_HOSTPORT HMSTAT PORT]
|
|
if {$::histogram_memory::histmem_simulation == "false"} {
|
|
MakeSctController sct_hmm astvelsel $host:$port
|
|
}
|
|
|
|
proc ::histogram_memory::hmstat {args} {
|
|
variable histmem_simulation
|
|
if {$histmem_simulation == "true"} {
|
|
return
|
|
}
|
|
set startIndex -1
|
|
# Try three times to get at least some data following the HTTP header.
|
|
# Usually we get all the data but sometimes we just get the header.
|
|
for {set i 0} {$i < 3 && $startIndex == -1} {incr i} {
|
|
set req "GET /admin/textstatus.egi HTTP/1.1\r\nAuthorization: Basic bWFuYWdlcjphbnN0bw==\r\n"
|
|
set textstatus [sct_hmm transact $req]
|
|
set lTextStatus [split $textstatus \n]
|
|
set startIndex [lsearch -glob $lTextStatus HM-Host*]
|
|
}
|
|
# Throw away HTTP header
|
|
set lTextStatus [lrange $lTextStatus $startIndex end]
|
|
|
|
# Create text status array
|
|
foreach l $lTextStatus {
|
|
if {[string length $l] == 0} {
|
|
continue
|
|
}
|
|
set v [split $l ':']
|
|
set key [lindex $v 0]
|
|
set val [lindex $v 1 0]
|
|
if [string is double $val] {
|
|
set hmarr($key) $val
|
|
} else {
|
|
set hmarr($key) '$val'
|
|
}
|
|
}
|
|
|
|
# Return requested values to user
|
|
set argc [llength $args]
|
|
switch $argc {
|
|
0 {
|
|
set keys [array names hmarr]
|
|
foreach k [lrange $keys 0 end-1] {
|
|
lappend d "'$k': $hmarr($k),"
|
|
}
|
|
set k [lindex $keys end]
|
|
lappend d "'$k': $hmarr($k)"
|
|
return [join $d]
|
|
}
|
|
1 {
|
|
return $hmarr($args)
|
|
}
|
|
default {
|
|
foreach k [lrange $args 0 end-1] {
|
|
lappend d "'$k': $hmarr($k),"
|
|
}
|
|
set k [lindex $args end]
|
|
lappend d "'$k': $hmarr($k)"
|
|
return [join $d]
|
|
}
|
|
}
|
|
}
|
|
# Poll to keep HTTP connection alive
|
|
if {$::histogram_memory::histmem_simulation == "false"} {
|
|
sicspoll add ::histogram_memory::hmstat script 30 ::histogram_memory::hmstat
|
|
}
|
|
|
|
|
|
namespace eval ::histogram_memory {
|
|
#TODO Create GumTree commands to setup, start and stop the histmem
|
|
##
|
|
# @brief Choose method for controlling acquisition duration.
|
|
#command mode {text:time,monitor,unlimited,period,count,frame method} {}
|
|
##
|
|
# @brief Count until the preset count size has been reached.
|
|
#
|
|
# @param preset: The interpretation of the preset depends on the count method.
|
|
# @see count_method
|
|
#command preset {float: pre} {}
|
|
##
|
|
# @brief Set stop condition for histogram memory
|
|
#
|
|
# @param condition
|
|
#command stop_condition {text:immediate,period condition}
|
|
}
|
|
|
|
|
|
##
|
|
# @brief Convenience command providing user interface to histogram control
|
|
#
|
|
# @param cmd is one of start, stop, pause, mode, preset, fsrce, status, loadconf
|
|
# @param args is an optional list of arguments for the given command
|
|
proc _histmem {cmd args} {
|
|
#TODO Add "continue"
|
|
set reply ""
|
|
if [ catch {
|
|
switch $cmd {
|
|
"start" {
|
|
eval "::histogram_memory::start $args"
|
|
}
|
|
"stop" {
|
|
::histogram_memory::stop
|
|
}
|
|
"pause" {
|
|
::histogram_memory::pause
|
|
}
|
|
"veto" {
|
|
eval "::histogram_memory::veto $args"
|
|
}
|
|
"mode" {
|
|
if {$args == ""} {
|
|
set reply [::histogram_memory::count_method ]
|
|
} else {
|
|
eval "::histogram_memory::count_method $args"
|
|
}
|
|
}
|
|
"preset" {
|
|
if {$args == ""} {
|
|
set reply [::histogram_memory::count_size ]
|
|
} else {
|
|
eval "::histogram_memory::count_size $args"
|
|
}
|
|
}
|
|
"clockscale" {
|
|
if {$args == ""} {
|
|
set reply [::histogram_memory::get_clock_scale ]
|
|
} else {
|
|
eval "::histogram_memory::set_clock_scale $args"
|
|
}
|
|
}
|
|
"freq" {
|
|
if {$args == ""} {
|
|
set reply [::histogram_memory::get_frame_freq ]
|
|
} else {
|
|
eval "::histogram_memory::set_frame_freq $args"
|
|
}
|
|
}
|
|
"fsrce" {
|
|
if {$args == ""} {
|
|
set reply [::histogram_memory::get_frame_source ]
|
|
} else {
|
|
eval "::histogram_memory::set_frame_source $args"
|
|
}
|
|
}
|
|
"status" {
|
|
set reply [::histogram_memory::hmm_status]
|
|
}
|
|
"textstatus" {
|
|
set reply [eval "::histogram_memory::hmstat $args"]
|
|
}
|
|
"loadconf" {
|
|
# Loads configuration tables (OAT, FAT, ...) to histogram server
|
|
if {$args == ""} {
|
|
::histogram_memory::upload_config Filler_defaults
|
|
} else {
|
|
eval "::histogram_memory::upload_config $args"
|
|
}
|
|
}
|
|
default {
|
|
error "ERROR: Available commands are, start stop pause mode preset freq fsrce status loadconf"
|
|
}
|
|
}
|
|
} message ] {
|
|
return -code error "([info level 0]) $message"
|
|
}
|
|
return $reply
|
|
}
|