Terminition conditions when acquiring detector data are now controlled by the histogram server instead of the beam monitor. So more termination methods are now available and timed counts should be more precise.

hmm_configuration_common_1.tcl
Map hmm dim0,1,2 to histogram server OAT dimensions.
Added commands to set the histogram server count method, size and stop condition.

scan_common_1.tcl
hmscan is now controlled by the histogram server instead of the beam monitor.
NOTE: the mode and preset parameters for hmscan run are now ignored in favour of the parameters set on the hmm object.

r2189 | ffr | 2007-10-23 12:40:09 +1000 (Tue, 23 Oct 2007) | 10 lines
This commit is contained in:
Ferdi Franceschini
2007-10-23 12:40:09 +10:00
committed by Douglas Clowes
parent 8e6d4e4da6
commit 8b1996996a
3 changed files with 276 additions and 386 deletions

View File

@@ -3,7 +3,7 @@
<anstohm:anstohm filler="ansto1" >
<config_links>
<config_link filename="../HMconfig/Default/Server_defaults.xml" />
<config_link filename="../HMconfig/Default/[inst_defaults].xml" />
<config_link filename="../HMconfig/Default/[::histogram_memory::filler_defaults].xml" />
</config_links>
<config_fillers>
<config_filler instrument="[instname]">

View File

@@ -1,22 +1,19 @@
# $Revision: 1.18 $
# $Date: 2007-10-03 00:07:26 $
# Author: Mark Lesha (mle@ansto.gov.au)
# $Revision: 1.19 $
# $Date: 2007-10-23 02:40:09 $
# 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
# Last revision by: $Author: ffr $
##\file Provides generic code and parameters for configuring the ANSTO histogram memory server
##
# @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 {}
# @code proc ::histogram_memory::initialize {}
# this function should call the generic initalisation function,
# ::histogram_memory::_initialize
#
#\see ::histogram_memory::_initialize
#-------------------------------------------------------------------------
# System: Histogram Server (sample)
#------------------------------------------------------------------------
#ffr MakeHM hmm anstohttp, move to inst specific config
#@see ::histogram_memory::_initialize
namespace eval histogram_memory {
::utility::mkVar detector_active_height_mm Float user active_height true detector true true
@@ -26,12 +23,6 @@ namespace eval histogram_memory {
::utility::mkVar hmm_user_configpath Text manager user_configpath false detector true false
hmm_user_configpath ../user_config/hmm
::utility::mkVar hmm_dim0 Int user dim0 true detector true true
::utility::mkVar hmm_dim1 Int user dim1 true detector true true
::utility::mkVar hmm_dim2 Int user dim2 true detector true true
::utility::mkVar hmm_rank Int user rank true detector false true
::utility::mkVar hmm_start Int user start false detector false false
::utility::mkVar hmm_length Int user length false detector false false
::utility::mkVar hmm_mode Text user mode true detector true true
::utility::mkVar _hmm_vert_axis Text user vert_axis true detector false true
::utility::mkVar _hmm_hor_axis Text user hor_axis true detector false true
@@ -60,7 +51,6 @@ namespace eval histogram_memory {
proc returnconfigfile {filename} {
set fh [open $filename]
set xml [read $fh]
#set xml [list [read $fh]]
debug_msg $xml value
close $fh
return [subst $xml]
@@ -116,105 +106,23 @@ namespace eval histogram_memory {
return $retn
}
##############################################
# Create beam monitor counter
# and histogram memory control object
# (ANSTO customized versions)
##############################################
# Make our special HMControl_ANSTO object with the bm controlling the hmm.
# This version can pause the histogram server after the count expires
# instead of just stopping it, so we can generate multiple datasets
# during a scan, or overlap data acquired at different scan stations.
# It can also terminate either on the counter or any of the histogram objects.
#ffr MakeHMControl_ANSTO hmc bm hmm, move to inst specific config
##############################################
# Creating scans and creating/attaching
# associated objects such as motors to drive,
# extra counters etc.
##############################################
#
# Define two scan objects which use the beam monitor counter.
#
# For hmscan, the hmc object uses the bm counter to control
# acquisition duration. In other words, the acquisition duration
# is controlled via SICS. This is fine if the duration doesn't
# need to be controlled to an accuracy of less than one second.
# The bm only allows control of acquisition duration based on
# elapsed time or number of monitor counts.
#
# For scan2, the histogram server controls acquisition duration.
# In addition to time or monitor count based termination conditions,
# the histogram server can be configured to terminate after a
# specific number of frames or periods have elapsed, or can be
# terminated in response to an external dataset signal.
# The accuracy of control of the acquisition duration is much higher
# (milliseconds versus hundreds of milliseconds).
# Also, the histogram server can be configured to extend acquisition
# so that only whole frames or periods are acquired.
# Termination condition is normally already configured via
# the histogram server's configuration files.
# If a static termination condition is already configured,
# scan2_runa can be called, with no termination condition required.
# But if the SICS user wants to dynamically commit the termination
# condition configuration to the histogram server,
# a wrapper function scan2_runb should be called instead.
# This allows the termination condition configuration to be written to
# the histogram server dynamically, under the control of SICS.
# The histogram server has a wider range of options for
# termination condition, and there are three termination condition
# arguments instead of the usual two for SICS counter objects.
#
# In both cases, we make the bm the master counter for the scan,
# so that bm statistics are acquired during the scan.
#
# 17/11/06 NOTE: The Beam Monitor is not yet interfaced directly to the
# Histogram Server. This means that for BM-controlled acquisitions,
# SICS needs to use the BM counter (i.e. use hmscan not scan2).
#
# EXAMPLES: For scan running over 5 stops and acquisition of 1 sec at each stop:
# hmscan run 5 timer 1 (termination controlled by the beam monitor)
# scan2_runb 5 TIME 100 IMMEDIATE (termination controlled by the histogram server)
#
#
# Call is: scan2_runa <n>
proc scan2_runa {n} {
# The termination condition is ignored, because the
# histogram server controls the acquisition duration
# directly in this case.
scan2 run $n timer 0
}
#
# Call is: scan2_runb <n>
proc scan2_runb {n count_method count_size count_stop} {
# Commit the termination conditions to the histogram server.
# hmm configure stores the values in the dictionary,
# then hmm init causes them to be sent to the histogram server.
# We just 'assume' they are successfully written.
##
# @brief Use histogram server to control acquisitions
proc set_termination_conditions {count_method count_size count_stop} {
hmm configure FAT_COUNT_METHOD $count_method
hmm configure FAT_COUNT_SIZE $count_size
hmm configure FAT_COUNT_STOP $count_stop
hmm init
# The termination condition is ignored, because the
# histogram server controls the acquisition duration
# directly in this case. So, use 'timer 0' here.
scan2 run $n timer 0
hmm configure FAT_COUNT_SIZE $count_size
hmm configure FAT_COUNT_STOP $count_stop
hmm init
}
# Simulated counter. No error rate. Required for technical reasons...
# This counter is used only to block execution till the bm count is actually reached,
# The simulated counter is used only to block execution till the bm count is actually reached,
# for the scan example using hmc and bm objects to control the acquisition duration from SICS.
MakeCounter blockctr SIM -1.0
blockctr SetExponent 0
blockctr SetMode timer
blockctr SetPreset 0
# Later on we can add some motors to drive...
#Motor som2 ASIM 0 100 -1.0 0.01
#hmscan add som2 0 1
##############################################
# Support for using expanded histogram period
@@ -268,131 +176,6 @@ namespace eval histogram_memory {
##############################################
##############################################
# The prepare callback gets called at the start of the scan.
# We use it to pause the histogram server, in order to commence the DAQ.
# This 'primes' the DAE also (i.e. device drivers reboot the hardware,
# buffering processes are started, etc.)
proc prepare {} {
#clientput "Enter prepare" value
#
# Before configuring the bm, do a short count.
# This will cause the counter to reconnect if it needs to...
bm count 0 timer
# Now configure the beam monitor counter for better performance.
# (Set a high counter sample rate to get better accuracy).
bm send set scan=1
bm send set sample=1000
# Make sure the histogram server is stopped, this guarantees DAQ not in progress already.
hmm stop
# Zero the OAT offsets (whether used or not).
global oatoffset
set oatoffset 0
set_oat_offset 0 0 0
#
# stdscan prepare $scanobjectname $userobjectname
#clientput "hmm pause being done..." value
# Pause the histogram server, this primes the DAE for acqisition.
hmm pause
#clientput "Exit prepare" value
return
}
# The count_bm_controlled callback gets called at the start of dataset acquisition.
# We use it to perform the dataset acquisition, via the hmc object.
# Note we do NOT call stdscan count, since we don't need to run the bm counter twice.
proc count_bm_controlled {mode preset} {
::histogram_memory::count -set feedback status BUSY
#clientput "Enter count" value
#stdscan count $scanobjectname $userobjectname $point $mode $preset
# Start the acquisition, runs till the beam monitor terminates
# and then enter paused mode (we have added fifth argument to allow this).
# In fact, execution proceeds immediately (the hmc call doesn't block).
hmc start $preset $mode pause
# Now call the simulated counter. This will cause execution to block
# till the hmc acquisition actually finishes. Otherwise, execution will
# charge on regardless and the finish callback function gets called
# before the last dataset acquisition has finished!
blockctr count 0
#clientput "Exit count" value
::histogram_memory::count -set feedback status IDLE
return
}
# The count_hs_controlled callback gets called at the start of dataset acquisition.
# We use it to perform the dataset acquisition, controlled by the histogram server.
# Note we do NOT call stdscan count, since we don't need to run the bm counter twice.
proc hs_count_hs_controlled {scanobjectname userobjectname point mode preset} {
#clientput "Enter count" value
#stdscan count $scanobjectname $userobjectname $point $mode $preset
# Start the acquisition, runs till the histogram server auto-terminates.
# This is done by specifying the termination object to be the histogram server,
# not the counter object (place a 1 in 6th argument to hmc object).
# The termination condition for the bm counter is just set to a large time period.
# After the acquisition terminates, the beam monitor therefore has the correct
# status reading and the 'Monitor' entry in the scan data table will be correct.
hmc start 1000000000 timer pause 1
# Now call the simulated counter. This will cause execution to block
# till the hmc acquisition actually finishes. Otherwise, execution will
# charge on regardless and the finish callback function gets called
# before the last dataset acquisition has finished!
blockctr count 0
#clientput "Exit count" value
return
}
# The collect callback gets called at the end of the dataset acquisition.
# We can put stuff here to retrieve data collected at each scan point,
# and set up OAT offsets or other parameters that might need to be varied
# from point to point at the histogram server, ready for the next scan point.
# In this example, an increasing oatoffset variable is used to configure
# the histogram server's OAT offset in the x direction, to produce
# an overlapped histogram period acquisition.
# Other things might be done here including adjustment of termination
# condition based on beam monitor count.
# Code for adjusting ancillaries, moving secondary motion stages etc. etc.
# from point to point should probably be put into a drive callback function
# (but not in this example script).
proc hs_collect {scanobjectname userobjectname point} {
#clientput "Enter collect" value
set rslt [stdscan collect $scanobjectname $userobjectname $point]
# Apply an OAT offset in the x direction (e.g. along tube number axis).
global oatoffset
incr oatoffset
set_oat_offset $oatoffset 0 0
# Checking the beam monitor
#clientput [bm send read] value
# At each scan point, read the total x-y histogram
# ans save it. This gets cleared at the start of
# each dataset (when restarting from paused state),
# so it represents the hstogram acquired per scan point.
#clientput "Exit collect" value
return
}
# The finish callback gets called at the end of the scan.
# We use it to stop the histogram server, terminating the dataset.
proc finish {} {
#clientput "Enter finish" value
# stdscan finish $scanobjectname $userobjectname
#clientput "hmm stop being done..." value
hmm stop
# Just in case someone expects zero OAT offsets later on ;)
set_oat_offset 0 0 0
# Get and write the data from the main histogram to disk (filename "HistoData").
# Sicne this is the first (and only) access to hmm data, it is retrieved from
# the server and we don't need to do hmm init first to force update hmm memory.
# hmm init
# savehistodata hmm "../data/HistoData"
#
#clientput "Exit finish" value
return
}
proc count_withbm {mode preset} {
prepare;
count_bm_controlled $mode $preset;
finish;
}
proc init {} {
}
@@ -410,15 +193,10 @@ namespace eval histogram_memory {
sicslist setatt blockctr privilege internal;
# histogram memory macros
sicslist setatt ::histogram_memory::finish privilege internal;
sicslist setatt ::histogram_memory::hs_count_hs_controlled privilege internal;
sicslist setatt ::histogram_memory::count_bm_controlled privilege internal;
sicslist setatt ::histogram_memory::prepare privilege internal;
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::count_withbm privilege internal;
sicslist setatt ::histogram_memory::save privilege internal;
foreach hm_obj [sicslist type histmem] {
@@ -725,7 +503,7 @@ proc XXX_TABLE {tag attributes element_list args} {
#
# @see XXX_TABLE for subcommands.
proc BAT_TABLE {args} {
set attributes {FRAME_FREQUENCY SIZE_PERIOD COUNT_METHOD COUNT_SIZE READ_DATA_TYPE}
set attributes {}
set elements ""
set tag BAT
global hmm_xml
@@ -749,7 +527,7 @@ BAT_TABLE -clear
#
# @see XXX_TABLE for subcommands.
proc CAT_TABLE {args} {
set attributes {FRAME_FREQUENCY SIZE_PERIOD COUNT_METHOD COUNT_SIZE READ_DATA_TYPE}
set attributes {}
set elements ""
set tag CAT
global hmm_xml
@@ -880,7 +658,7 @@ OAT_TABLE -clear
#
# @see XXX_TABLE for subcommands.
proc SAT_TABLE {args} {
set attributes {FRAME_FREQUENCY SIZE_PERIOD COUNT_METHOD COUNT_SIZE READ_DATA_TYPE}
set attributes {}
set elements ""
set tag SAT
global hmm_xml
@@ -907,61 +685,144 @@ proc ::histogram_memory::clear_tables {} {
SAT_TABLE -clear
}
proc inst_defaults {} {
global ::histogram_memory::hmm_def_filename
return $::histogram_memory::hmm_def_filename
}
proc dae_type {} {
global ::histogram_memory::hmm_dae_type
return $::histogram_memory::hmm_dae_type
}
proc ::histogram_memory::configure_server {instdef} {
variable hmm_def_filename
variable hmm_dae_type
set hmm_def_filename $instdef
# rank is always 3, but some or all of the dimensions can be 1
hmm configure rank 3
foreach hm_obj [sicslist type histmem] {
$hm_obj configure hmaddress http://das1-[instname].nbi.ansto.gov.au:8080
$hm_obj configure username spy
$hm_obj configure password 007
}
::histogram_memory::setup
if {[instname] == "wombat"} {
hmm_dim1 [hmmdictitemval hmm stitch_nyc]
hmm_dim2 [hmmdictitemval hmm stitch_nxc]
##
# @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 {[llength $args] == 0} {
return $hmm_def_filename
} else {
hmm_dim1 [hmmdictitemval hmm oat_nyc_eff]
hmm_dim2 [hmmdictitemval hmm oat_nxc_eff]
set hmm_def_filename $args
}
hmm_dim0 [hmmdictitemval hmm oat_ntc_eff]
hmm_length [expr {[SplitReply [hmm_dim0]] * [SplitReply [hmm_dim1]] * [SplitReply [hmm_dim2]]} ]
hmm configure dim0 [SplitReply [hmm_dim0]]
hmm configure dim1 [SplitReply [hmm_dim1]]
hmm configure dim2 [SplitReply [hmm_dim2]]
}
## \brief Sets histogram server to default configuration, initialises SICS histogram memory
# dictionary values and clears and initialises SICS OAT BAT CAT FAT ... tables
proc ::histogram_memory::configure_server {instdef} {
clientput "WARNING: ::histogram_memory::configure_server is deprecated, call ::histogram_memory::upload_config instead"
::histogram_memory::upload_config $instdef
}
proc ::histogram_memory::upload_config {instdef} {
::histogram_memory::filler_defaults $instdef
#XXX ::histogram_memory::setup
hmm stop
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
# 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 stop
hmm configure statuscheck false
::histogram_memory::configure_dims
}
##
# @brief Configure the dimensions for the controlling histogram object, and for
# each auxiliary histogram object.
proc ::histogram_memory::configure_dims {} {
# set hmm_dim0 [hmmdictitemval hmm oat_ntc_eff]
# if {[instname] == "wombat"} {
# set hmm_dim1 [hmmdictitemval hmm stitch_nyc]
# set hmm_dim2 [hmmdictitemval hmm stitch_nxc]
# } else {
# set hmm_dim1 [hmmdictitemval hmm oat_nyc_eff]
# set hmm_dim2 [hmmdictitemval hmm oat_nxc_eff]
# }
if {[instname] == "wombat"} {
array set dim_map {
hmm {{hmm_dim0 oat_ntc_eff} {hmm_dim1 stitch_nyc} {hmm_dim2 stitch_nxc}}
hmm,fat_read_data_type HISTOPERIOD_XYT
hmm_xy {{hmm_dim0 stitch_nyc} {hmm_dim1 stitch_nxc}}
hmm_xy,fat_read_data_type TOTAL_HISTOGRAM_XY
hmm_xt {{hmm_dim0 oat_ntc_eff} {hmm_dim1 stitch_nxc}}
hmm_xt,fat_read_data_type TOTAL_HISTOGRAM_XT
hmm_yt {{hmm_dim0 oat_ntc_eff} {hmm_dim1 stitch_nyc}}
hmm_yt,fat_read_data_type TOTAL_HISTOGRAM_YT
hmm_x {{hmm_dim0 stitch_nxc}}
hmm_x,fat_read_data_type TOTAL_HISTOGRAM_X
hmm_y {{hmm_dim0 stitch_nyc}}
hmm_y,fat_read_data_type TOTAL_HISTOGRAM_Y
hmm_t {{hmm_dim0 oat_ntc_eff}}
hmm_t,fat_read_data_type TOTAL_HISTOGRAM_T
}
} else {
array set dim_map {
hmm {{hmm_dim0 oat_ntc_eff} {hmm_dim1 oat_nyc_eff} {hmm_dim2 oat_nxc_eff}}
hmm,fat_read_data_type HISTOPERIOD_XYT
hmm_xy {{hmm_dim0 oat_nyc_eff} {hmm_dim1 oat_nxc_eff}}
hmm_xy,fat_read_data_type TOTAL_HISTOGRAM_XY
hmm_xt {{hmm_dim0 oat_ntc_eff} {hmm_dim1 oat_nxc_eff}}
hmm_xt,fat_read_data_type TOTAL_HISTOGRAM_XT
hmm_yt {{hmm_dim0 oat_ntc_eff} {hmm_dim1 oat_nyc_eff}}
hmm_yt,fat_read_data_type TOTAL_HISTOGRAM_YT
hmm_x {{hmm_dim0 oat_nxc_eff}}
hmm_x,fat_read_data_type TOTAL_HISTOGRAM_X
hmm_y {{hmm_dim0 oat_nyc_eff}}
hmm_y,fat_read_data_type TOTAL_HISTOGRAM_Y
hmm_t {{hmm_dim0 oat_ntc_eff}}
hmm_t,fat_read_data_type TOTAL_HISTOGRAM_T
}
}
foreach hm_obj [sicslist type histmem] {
set rank [SplitReply [$hm_obj configure rank]]
set hmm_length 1
foreach elmt $dim_map($hm_obj) {
set [lindex $elmt 0] [hmmdictitemval hmm [lindex $elmt 1]]
}
$hm_obj configure FAT_READ_DATA_TYPE $dim_map($hm_obj,fat_read_data_type)
$hm_obj stop
$hm_obj init 0
$hm_obj init
for {set i 0} {$i < $rank} {incr i} {
set hmm_length [expr $hmm_length * [set hmm_dim$i] ]
$hm_obj configure dim$i [set hmm_dim$i]
}
}
}
##
# @brief Sets histogram server to default configuration, initialises SICS histogram memory
# dictionary values and clears SICS OAT BAT CAT FAT ... tables
proc ::histogram_memory::_initialize {} {
set configuration "::histogram_memory::returnconfigfile config/hmm/anstohm_linked.xml"
y_pixel_offset -centres
x_pixel_offset -centres
time_channel -boundaries
::histogram_memory::clear_tables
::histogram_memory::configure_server Filler_defaults
#XXX ::histogram_memory::upload_config Filler_defaults
OAT_TABLE -init T_MIN 0 T_MAX 200000
FAT_TABLE -init SIZE_PERIOD_MAX 125000000
foreach hm_obj [sicslist type histmem] {
$hm_obj configure hmaddress http://das1-[instname].nbi.ansto.gov.au:8080
$hm_obj configure username spy
$hm_obj configure password 007
$hm_obj configure histmode transparent
}
hmm configure init 0
hmm init
hmm configure statuscheck true
hmm stop
hmm configure statuscheck false
hmm configure hmDataPath ../HMData
hmm configure hmconfigscript $configuration
::histogram_memory::configure_dims
}
Publish ::histogram_memory::finish user
#Publish ::histogram_memory::hs_collect user
Publish ::histogram_memory::hs_count_hs_controlled user
Publish ::histogram_memory::count_bm_controlled user
Publish ::histogram_memory::prepare user
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::count_withbm user
Publish ::histogram_memory::save user
Publish BAT_TABLE user
Publish CAT_TABLE user
@@ -969,12 +830,68 @@ Publish FAT_TABLE user
Publish OAT_TABLE user
Publish SAT_TABLE user
proc ::histogram_memory::pre_count {} {}
proc ::histogram_memory::post_count {} {}
namespace eval ::histogram_memory {
command count {text:monitor,timer mode float: preset} {
::histogram_memory::prepare
::histogram_memory::count_bm_controlled $mode $preset;
::histogram_memory::finish
}
::histogram_memory::count -addfb text status
::histogram_memory::count -set feedback status IDLE
##
# @brief Start an acquisition, non-blocking by default
#
# @param block (optional) default="noblock"
proc start {{blocking "block"}} {
::histogram_memory::pre_count
hmm init 0
hmm init
hmc start 1000000000 timer pause 1
if {$blocking == "block"} {
blockctr count 0
::histogram_memory::stop
}
}
proc stop {} {
# pausing actually stops the acquisition but leaves the
# histogram server in a ready state for the next acquisition
hmm pause
::histogram_memory::post_count
}
##
# @brief Choose method for controlling acquisition duration.
command count_method {text:time,monitor,unlimited,period,count,frame method} {
hmm configure FAT_COUNT_METHOD $method
hmm init 0
hmm init
}
##
# @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 count_size {float: preset} {
hmm configure FAT_COUNT_SIZE $preset
hmm init 0
hmm init
}
##
# @brief Set stop condition for histogram memory
#
# @param stop_method
command stop_condition {text:immediate,period condition} {
array set count_stop {immediate IMMEDIATE period AT_END_OF_PERIOD}
hmm configure FAT_COUNT_STOP $count_stop($condition)
hmm init 0
hmm init
}
}
##
# @brief Start an acquisition on the histogram server, this blocks by default
#
# @param method: count method, available methods are time,monitor,unlimited,period,count,frame
# @param preset: termination condition
proc ::histogram_memory::count {method preset stop_condition {blockmode "block"}} {
array set count_stop {immediate IMMEDIATE period AT_END_OF_PERIOD}
hmm configure FAT_COUNT_METHOD $method
hmm configure FAT_COUNT_STOP $count_stop($stop_condition)
hmm configure FAT_COUNT_SIZE $preset
::histogram_memory::start $blockmode
}
publish ::histogram_memory::count user

View File

@@ -1,48 +1,40 @@
## \file Scan functionality and common high level commands are defined here.
##
# @file Scan functionality and common high level commands are defined here.
#
# namespace variables\n
# ::scan::save_filetype data/scratch, controls if data will be saved to a scratch file.
# ::scan::reset_position true/false, drive motor back to start position at end of scan
# ::scan::reset_position true/false (default=true), drive motor back to start position at end of scan
#TODO Get rid of duplication in bmonscan and hmscan code
MakeScanCommand hmscan bm $cfPath(scan)/scan_common_1.hdd recover.bin
MakeScanCommand bmonscan bm $cfPath(scan)/scan_common_1.hdd recover.bin
MakeScanCommand scan2 bm $cfPath(scan)/scan_common_1.hdd recover.bin
namespace eval scan {
variable event;
# List of counts
variable bmoncounts_array
variable bmoncounts_axis
variable save_filetype
variable reset_position
set save_filetype "data"
set reset_position "false"
variable bmonscanvar_axis_hpath
# hpath to values from bmoncounts_array
# we use this to get auto-notification on update of bmonscancounts_array_hpath
variable bmonscancounts_array_hpath
variable scanVariable scan_var scanVarStart 0 scanVarStep 1
proc scan_collect {sobj uobj point} {
}
## \brief Aborts scan if a scan variable target position exeeds the limits.
proc check_limit {scan_variable limit_name target} {
}
##
# @brief Returns an error if a scan variable target position exceeds the limits.
proc ::scan::check_limit {scan_variable limit_name target} {
switch $limit_name {
"hardlowerlim" - "softlowerlim" {
set limit [SplitReply [$scan_variable $limit_name]]
if { $target < $limit} {
return -code error "ERROR Scan aborted. Final position of $target violates $limit_name $limit for $scan_variable"
return -code error "Final position of $target violates $limit_name $limit for $scan_variable"
}
}
"hardupperlim" - "softupperlim" {
set limit [SplitReply [$scan_variable $limit_name]]
if { $target > $limit} {
return -code error "ERROR Scan aborted. Final position of $target violates $limit_name $limit for $scan_variable"
return -code error "Final position of $target violates $limit_name $limit for $scan_variable"
}
}
default {
error_msg "Invalid limit name $limit_name"
return -code error "Invalid limit name $limit_name"
}
}
}
@@ -52,7 +44,7 @@ proc check_limit {scan_variable limit_name target} {
# so we don't have to.
# TODO We can't check limits of virtual motors yet because the
# configurablevirtualmotor doesn't set a checklimits function.
proc check_scanvar {sobj uobj} {
proc ::scan::check_scanvar {sobj uobj} {
set vlist [split [$sobj getvarpar 0] = ];
set NP [SplitReply [$sobj np]]
set scan_variable [string trim [lindex [split [lindex $vlist 0] . ] 1]]
@@ -60,21 +52,45 @@ proc check_limit {scan_variable limit_name target} {
set scan_increment [lindex $vlist 2];
if {[getatt $scan_variable type] == "motor"} {
if {[SplitReply [$scan_variable fixed]] >= 0} {
return -code error "Scan aborted. $scan_variable position is set to 'fixed'"
return -code error "Can't drive scan variable, $scan_variable position is set to 'fixed'"
}
set target [expr $scan_start + $NP * $scan_increment]
::scan::check_limit $scan_variable hardlowerlim $target
::scan::check_limit $scan_variable hardupperlim $target
::scan::check_limit $scan_variable softlowerlim $target
::scan::check_limit $scan_variable softupperlim $target
if [catch {
::scan::check_limit $scan_variable hardlowerlim $target
::scan::check_limit $scan_variable hardupperlim $target
::scan::check_limit $scan_variable softlowerlim $target
::scan::check_limit $scan_variable softupperlim $target
}] {
return -code error $::errorInfo
}
}
}
proc hmm_scan_prepare {sobj uobj} {
##
# @brief Instrument specific scan configurations can override this procedure to perform some setup
# before running a scan, eg setting hmm frame frequency.
#
# NOTES\n
# Returning an error will cause the scan to abort before it starts\n
# eg\n
# return -code error "error message"
proc ::scan::pre_hmm_scan_prepare {} {}
##
# @brief Do some pre-scan checks and prime the DAE
proc ::scan::hmm_scan_prepare {sobj uobj} {
variable scan_pt_start_time
::scan::check_scanvar $sobj $uobj
if [catch {
::scan::check_scanvar $sobj $uobj
::scan::pre_hmm_scan_prepare
}] {
abortbatch
return -code error "HMSCAN ABORTED: $::errorInfo"
}
# Prime DAE
hmm pause
# stdscan prepare $sobj $uobj;
::scan::hdb_hmscan -set NP [SplitReply [$sobj np]]
set vlist [split [$sobj getvarpar 0] = ];
::scan::hdb_hmscan -set scan_variable [string trim [lindex [split [lindex $vlist 0] . ] 1]]
@@ -83,98 +99,84 @@ proc check_limit {scan_variable limit_name target} {
set scan_pt_start_time [sicstime]
#FIXME remove dependency on hdb path
::scan::hdb_hmscan -set feedback status BUSY
::histogram_memory::prepare
::nexus::newfile HISTOGRAM_XYT data
data axis 1 [::scan::hdb_hmscan -set scan_variable]
}
proc hmm_count {sobj uobj point mode preset} {
proc ::scan::hmm_count {sobj uobj point mode preset} {
::scan::hdb_hmscan -set mode $mode
::scan::hdb_hmscan -set preset $preset;
::scan::hdb_hmscan -set preset $preset
::scan::hdb_hmscan -set feedback scanpoint $point
::scan::hdb_hmscan -set feedback mode $mode;
::scan::hdb_hmscan -set feedback preset $preset;
::scan::hdb_hmscan -set feedback mode $mode
::scan::hdb_hmscan -set feedback preset $preset
::scan::hdb_hmscan -set feedback scan_variable_value [SplitReply [[::scan::hdb_hmscan -set scan_variable]]]
::histogram_memory::count_bm_controlled $mode $preset;
# Start histogram and block until count is complete
::histogram_memory::start block
}
proc hmm_scan_finish {sobj uobj} {
proc ::scan::hmm_scan_finish {sobj uobj} {
variable save_filetype
variable reset_position
set $save_filetype "data"
::histogram_memory::finish;
hmm pause
hmm stop
::scan::hdb_hmscan -set feedback status IDLE
# Make sure that the next save command doesn't overwrite our scan data.
# and clear any data links
::nexus::newfile clear data
if {$reset_position == "true"} {
set reset_position "false"
set svar [::scan::hdb_hmscan -get scan_variable]
set svtype [getatt $svar type]
if {$svtype == "motor" || $svtype == "configurablevirtualmotor"} {
drive $svar [::scan::hdb_hmscan -get scan_start]
}
set reset_position "false"
}
::histogram_memory::configure_server Filler_defaults
# ::histogram_memory::configure_server Filler_defaults
}
proc bm_scan_finish {sobj uobj} {
proc ::scan::bm_scan_finish {sobj uobj} {
variable reset_position
::scan::hdb_bmonscan -set feedback status IDLE
# Make sure that the next save command doesn't overwrite our scan data.
# and clear any data links
::nexus::newfile clear data
if {$reset_position == "true"} {
set reset_position "false"
set svar [::scan::hdb_bmonscan -get scan_variable]
set svtype [getatt $svar type]
if {$svtype == "motor" || $svtype == "configurablevirtualmotor"} {
drive $svar [::scan::hdb_bmonscan -get scan_start]
}
set reset_position "false"
}
}
#proc hmm_scan_finish {sobj uobj} {
# nxclosefile;
#}
# Add an nxentry for the current scan point
#TODO Is this obsolete?
proc write_nxentry {nxentryCmd point} {
variable scanVarStart;
variable scanVarStep;
variable scanVariable;
proc ::scan::write_nxentry {nxentryCmd point} {
variable scan_pt_start_time;
set scanVarPos [expr {$scanVarStart + $point * $scanVarStep} ];
save $point
# nxreopenfile;
# $nxentryCmd nxscript scan_[format "%05d" $point] $scanVariable $scanVarPos $scanVarStep $scan_pt_start_time;
# $nxentryCmd nxscript entry1 $point $scanVariable $scanVarPos $scanVarStep $scan_pt_start_time;
# nxclosefile;
}
proc bm_writepoint {sobj uobj pt} {
variable bmoncounts_array
set bmoncounts_array [string map {\{ "" \} ""} [SplitReply [bmonscan getcounts]]];
proc ::scan::bm_writepoint {sobj uobj pt} {
::nexus::save $pt
::scan::hdb_bmonscan -set feedback counts [SplitReply [bm getcounts]];
}
#TODO Feedback for Histogram memory scan
proc hmm_writepoint {sobj uobj pt} {
proc ::scan::hmm_writepoint {sobj uobj pt} {
variable save_filetype
# Write hdb tree
::nexus::save $pt
}
proc donothing {args} {}
proc ::scan::donothing {args} {}
proc bm_count {sobj uobj point mode preset} {
variable event;
proc ::scan::bm_count {sobj uobj point mode preset} {
::scan::hdb_bmonscan -set mode $mode
::scan::hdb_bmonscan -set preset $preset
::scan::hdb_bmonscan -set feedback scanpoint $point;
@@ -184,30 +186,31 @@ proc check_limit {scan_variable limit_name target} {
::monitor::count $mode $preset
}
proc bm_scan_prepare {sobj uobj} {
variable event;
proc ::scan::bm_scan_prepare {sobj uobj} {
variable bmoncounts_array;
variable bmoncounts_axis;
variable scan_pt_start_time
set bmoncounts_array [list]
if [catch {
::scan::check_scanvar $sobj $uobj
::scan::pre_hmm_scan_prepare
}] {
abortbatch
return -code error "BMONSCAN ABORTED: $::errorInfo"
}
#TODO Parameterise varindex in some way
set varindex 0;
::scan::hdb_bmonscan -set feedback filename [SplitReply [dataFileName]]
::scan::hdb_bmonscan -set NP [SplitReply [$sobj np]];
# set event(hdb_bmonscan/graphics,dim) [::scan::hdb_bmonscan -set NP]
set vlist [split [$sobj getvarpar $varindex] = ];
::scan::hdb_bmonscan -set scan_variable [string trim [lindex [split [lindex $vlist 0] . ] 1]];
::scan::hdb_bmonscan -set scan_start [lindex $vlist 1];
::scan::hdb_bmonscan -set scan_increment [lindex $vlist 2];
set scanvar_pts [SplitReply [$sobj getvardata $varindex]]
set bmoncounts_axis [string map {\{ "" \} ""} $scanvar_pts]
todo_msg "SET START TIME set event(hdb_bmonscan,scan_pt_start_time) [sicstime]"
todo_msg "SET START TIME [sicstime]"
::scan::hdb_bmonscan -set feedback status BUSY
#FIXME remove dependency on hdb path
array set bm_fb [::scan::hdb_bmonscan -list feedback]
::nexus::newfile BEAM_MONITOR data
@@ -216,18 +219,6 @@ proc check_limit {scan_variable limit_name target} {
}
# group=beam_monitor_scan
proc hdb_bmonscan_graphics {process args} {
set eid hdb_bmonscan/graphics
$process $args path beam_monitor_scan prop_list {data false control true nxsave false klass @none type graphdata viewer default rank 1}
$process $args kind event node beam_monitor_scan/dim dtype int priv user eventid $eid;
$process $args kind event node beam_monitor_scan/point dtype int priv user eventid $eid;
$process $args kind event node beam_monitor_scan/lastaxis dtype float priv user eventid $eid;
$process $args kind event node beam_monitor_scan/lastdata dtype int priv user eventid $eid;
$process $args kind script node beam_monitor_scan/axis dtype floatvarar dlen 100 priv user rscript "set ::scan::bmoncounts_axis" wscript hdbReadOnly prop_list {type axis}
$process $args kind script node beam_monitor_scan/data dtype floatvarar dlen 100 priv user rscript "set ::scan::bmoncounts_array" wscript hdbReadOnly prop_list {type data}
}
}
Publish ::scan::scan_collect user
Publish ::scan::write_nxentry user
@@ -251,23 +242,6 @@ bmonscan function prepare ::scan::bm_scan_prepare
bmonscan function finish ::scan::bm_scan_finish
#scan2 function writeheader ::scan::donothing
#scan2 function writepoint ::scan::nxaddpoint
#scan2 function prepare ::scan::hmm_scan_prepare
# Configure script mode, then we can configure all the scan callbacks.
# The scan list command can be used to check that the callbacks
# are properly defined.
# A different count callback is defined in the two cases.
#
scan2 configure script
#scan2 function prepare ::histogram_memory::prepare
scan2 function count ::histogram_memory::hs_count_hs_controlled
#scan2 function collect ::histogram_memory::hs_collect
scan2 function finish ::histogram_memory::hs_finish
#
# That's all, folks...
hmscan configure script
#hmscan function prepare hdbprepare
#hmscan function collect hdbcollect
@@ -320,6 +294,5 @@ command hdb_hmscan { text:drivable scan_variable float: scan_start float: scan_i
::scan::hdb_hmscan -addfb text filename text mode float preset float scan_variable_value int scanpoint int counts text status
::scan::hdb_hmscan -set feedback status IDLE
}
publish ::scan::hdb_bmonscan_graphics user
sicslist setatt ::scan::hdb_bmonscan long_name bmonscan
sicslist setatt ::scan::hdb_hmscan long_name hmscan