diff --git a/site_ansto/instrument/config/hmm/anstohm_linked.xml b/site_ansto/instrument/config/hmm/anstohm_linked.xml index 46d20237..e52ad7da 100644 --- a/site_ansto/instrument/config/hmm/anstohm_linked.xml +++ b/site_ansto/instrument/config/hmm/anstohm_linked.xml @@ -3,7 +3,7 @@ - + diff --git a/site_ansto/instrument/config/hmm/hmm_configuration_common_1.tcl b/site_ansto/instrument/config/hmm/hmm_configuration_common_1.tcl index 1ba12467..a8b94eb5 100644 --- a/site_ansto/instrument/config/hmm/hmm_configuration_common_1.tcl +++ b/site_ansto/instrument/config/hmm/hmm_configuration_common_1.tcl @@ -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 - 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 - 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 diff --git a/site_ansto/instrument/config/scan/scan_common_1.tcl b/site_ansto/instrument/config/scan/scan_common_1.tcl index 2110c45b..37036ed9 100644 --- a/site_ansto/instrument/config/scan/scan_common_1.tcl +++ b/site_ansto/instrument/config/scan/scan_common_1.tcl @@ -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