Files
sics/site_ansto/instrument/config/scan/scan_common_1.tcl
Ferdi Franceschini 6ce90065d3 Check scan variable limits before starting a scan.
Added reset_position option to hmm_scan_finish to drive motors back to their start position at the end of a scan.

r2119 | ffr | 2007-08-16 16:03:14 +1000 (Thu, 16 Aug 2007) | 3 lines
2012-11-15 13:22:14 +11:00

331 lines
12 KiB
Tcl

## \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
#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} {
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"
}
}
"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"
}
}
default {
error_msg "Invalid limit name $limit_name"
}
}
}
## \brief check final position against scan variable limits
#
# NOTE: The sics scan object alread checks if a variable is drivable
# 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} {
set vlist [split [$sobj getvarpar 0] = ];
set NP [SplitReply [$sobj np]]
set scan_variable [string trim [lindex [split [lindex $vlist 0] . ] 1]]
set scan_start [lindex $vlist 1];
set scan_increment [lindex $vlist 2];
if {[getatt $scan_variable type] != "configurablevirtualmotor"} {
if {[SplitReply [$scan_variable fixed]] >= 0} {
return -code error "Scan aborted. $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
}
}
proc hmm_scan_prepare {sobj uobj} {
variable scan_pt_start_time
::scan::check_scanvar $sobj $uobj
# 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]]
::scan::hdb_hmscan -set scan_start [lindex $vlist 1];
::scan::hdb_hmscan -set scan_increment [lindex $vlist 2];
set scan_pt_start_time [sicstime]
#FIXME remove dependency on hdb path
::scan::hdb_hmscan -set feedback status BUSY
::histogram_memory::prepare
data axis 1 [::scan::hdb_hmscan -set scan_variable]
::hdb::set_save / true
::nexus::newfile data
}
proc hmm_count {sobj uobj point mode preset} {
::scan::hdb_hmscan -set mode $mode
::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 scan_variable_value [SplitReply [[::scan::hdb_hmscan -set scan_variable]]]
::histogram_memory::count_bm_controlled $mode $preset;
}
proc hmm_scan_finish {sobj uobj} {
variable save_filetype
variable reset_position
set $save_filetype "data"
::histogram_memory::finish;
::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 data
::nexus::data clear
if {$reset_position == "true"} {
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
}
proc 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 data
::nexus::data clear
if {$reset_position == "true"} {
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;
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]]];
::nexus::save $pt
::scan::hdb_bmonscan -set feedback counts [SplitReply [bm getcounts]];
}
#TODO Feedback for Histogram memory scan
proc hmm_writepoint {sobj uobj pt} {
variable save_filetype
# Write hdb tree
::nexus::save $pt
}
proc donothing {args} {}
proc bm_count {sobj uobj point mode preset} {
variable event;
::scan::hdb_bmonscan -set mode $mode
::scan::hdb_bmonscan -set preset $preset
::scan::hdb_bmonscan -set feedback scanpoint $point;
::scan::hdb_bmonscan -set feedback mode $mode;
::scan::hdb_bmonscan -set feedback preset $preset;
::scan::hdb_bmonscan -set feedback scan_variable_value [SplitReply [[::scan::hdb_bmonscan -set scan_variable]]]
::monitor::count $mode $preset
}
proc bm_scan_prepare {sobj uobj} {
variable event;
variable bmoncounts_array;
variable bmoncounts_axis;
variable scan_pt_start_time
set bmoncounts_array [list]
#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]"
::scan::hdb_bmonscan -set feedback status BUSY
#FIXME remove dependency on hdb path
array set bm_fb [::scan::hdb_bmonscan -list feedback]
data axis 1 [::scan::hdb_bmonscan -set scan_variable]
::hdb::set_save / true
::hdb::set_save /instrument/detector false
::nexus::newfile data
#stdscan prepare $sobj $uobj;
}
# 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
Publish ::scan::hmm_count user
Publish ::scan::hmm_scan_prepare user
Publish ::scan::hmm_scan_finish user
Publish ::scan::hmm_writepoint user
Publish ::scan::donothing user
Publish ::scan::bm_scan_prepare user
Publish ::scan::bm_scan_finish user
Publish ::scan::bm_writepoint user
Publish ::scan::bm_count user
bmonscan configure script
bmonscan function writeheader ::scan::donothing
bmonscan function writepoint ::scan::bm_writepoint
bmonscan function count ::scan::bm_count
#bmonscan function collect ::scan::scan_collect
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
hmscan function writeheader ::scan::donothing
hmscan function writepoint ::scan::hmm_writepoint
hmscan function count ::scan::hmm_count
#hmscan function collect ::scan::scan_collect
hmscan function prepare ::scan::hmm_scan_prepare
hmscan function finish ::scan::hmm_scan_finish
namespace eval scan {
command hdb_bmonscan { text:drivable scan_variable float: scan_start float: scan_increment int: NP text:monitor,timer mode float: preset int:0,2 channel} {
bmonscan clear
# bmonscan configure script
bmonscan add $scan_variable $scan_start $scan_increment
bmonscan setchannel $channel;
set status [catch {bmonscan run $NP $mode $preset} msg]
# bmonscan configure soft
if {$status == 0} {
return $msg
} else {
return -code error "ERROR [info level 0]"
}
}
::scan::hdb_bmonscan -addfb text filename text mode float preset float scan_variable_value int scanpoint int counts text status
::scan::hdb_bmonscan -set feedback status IDLE
command hdb_hmscan { text:drivable scan_variable float: scan_start float: scan_increment int: NP text:monitor,timer mode float: preset int:0,2 channel} {
hmscan clear
hmscan add $scan_variable $scan_start $scan_increment
hmscan setchannel $channel;
set status [catch {hmscan run $NP $mode $preset} msg]
if {$status == 0} {
return $msg
} else {
return -code error "ERROR [info level 0]"
}
}
::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