Files
sics/site_ansto/instrument/config/scan/scan_common_1.tcl
Ferdi Franceschini 78c42a2427 Don't set plottable data links and data save policy here, this is now taken care of when setting the data file policy with the 'newfile' command.
Only check if  scan variables of type=motor are locked (ie 'fixed') in position before running a scan.

r2161 | ffr | 2007-09-26 16:13:03 +1000 (Wed, 26 Sep 2007) | 3 lines
2012-11-15 13:24:45 +11:00

326 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] == "motor"} {
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
::nexus::newfile HISTOGRAM_XYT data
data axis 1 [::scan::hdb_hmscan -set scan_variable]
}
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 clear data
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 clear data
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]
::nexus::newfile BEAM_MONITOR data
::nexus::data axis 1 [::scan::hdb_bmonscan -set scan_variable]
#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