375 lines
12 KiB
Tcl
375 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 (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
|
|
|
|
namespace eval scan {
|
|
variable save_filetype
|
|
variable reset_position
|
|
set save_filetype "data"
|
|
set reset_position "false"
|
|
|
|
proc scan_collect {sobj uobj point} {
|
|
}
|
|
}
|
|
##
|
|
# @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 "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 "Final position of $target violates $limit_name $limit for $scan_variable"
|
|
}
|
|
}
|
|
default {
|
|
return -code error "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 ::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]]
|
|
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 "Can't drive scan variable, $scan_variable position is set to 'fixed'"
|
|
}
|
|
set target [expr $scan_start + $NP * $scan_increment]
|
|
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
|
|
}
|
|
}
|
|
}
|
|
|
|
##
|
|
# @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
|
|
variable save_filetype
|
|
|
|
if {[::plc::inst_ready] != 1} {
|
|
return -code error "HMSCAN ABORTED: Instrument not ready"
|
|
}
|
|
if [catch {
|
|
::scan::check_scanvar $sobj $uobj
|
|
::scan::pre_hmm_scan_prepare
|
|
}] {
|
|
abortbatch
|
|
return -code error "HMSCAN ABORTED: $::errorInfo"
|
|
}
|
|
|
|
if [catch {
|
|
set numpoints [SplitReply [$sobj np]]
|
|
set vlist [split [$sobj getvarpar 0] = ]
|
|
set scanstart [lindex $vlist 1]
|
|
set scanstep [lindex $vlist 2]
|
|
::scan::hdb_hmscan -set NP $numpoints
|
|
::scan::hdb_hmscan -set scan_variable [string trim [lindex [split [lindex $vlist 0] . ] 1]]
|
|
::scan::hdb_hmscan -set scan_start $scanstart
|
|
::scan::hdb_hmscan -set scan_increment $scanstep
|
|
|
|
set scan_pt_start_time [sicstime]
|
|
|
|
::scan::hdb_hmscan -set feedback status BUSY
|
|
|
|
::nexus::newfile HISTOGRAM_XYT $save_filetype
|
|
data axis 1 [::scan::hdb_hmscan -set scan_variable]
|
|
|
|
clientput "Scan start: $scanstart, Scan step: $scanstep, Number of points: $numpoints"
|
|
clientput "Filetype: HISTOGRAM_XYT"
|
|
# Prime DAE
|
|
hmm pause
|
|
}] {
|
|
return -code error $::errorInfo
|
|
}
|
|
}
|
|
|
|
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 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]]]
|
|
# Start histogram and block until count is complete
|
|
::histogram_memory::start block
|
|
}
|
|
|
|
proc ::scan::hmm_scan_finish {sobj uobj} {
|
|
variable save_filetype
|
|
variable reset_position
|
|
set $save_filetype "data"
|
|
::histogram_memory::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]
|
|
}
|
|
}
|
|
# ::histogram_memory::configure_server Filler_defaults
|
|
}
|
|
|
|
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]
|
|
}
|
|
}
|
|
}
|
|
|
|
# Add an nxentry for the current scan point
|
|
#TODO Is this obsolete?
|
|
proc ::scan::write_nxentry {nxentryCmd point} {
|
|
variable scan_pt_start_time;
|
|
|
|
save $point
|
|
}
|
|
|
|
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 ::scan::hmm_writepoint {sobj uobj pt} {
|
|
variable save_filetype
|
|
# Write hdb tree
|
|
::nexus::save $pt
|
|
}
|
|
|
|
proc ::scan::donothing {args} {}
|
|
|
|
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;
|
|
::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 ::scan::bm_scan_prepare {sobj uobj} {
|
|
|
|
variable scan_pt_start_time
|
|
|
|
if {[::plc::inst_ready] != 1} {
|
|
return -code error "HMSCAN ABORTED: Instrument not ready"
|
|
}
|
|
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;
|
|
|
|
set numpoints [SplitReply [$sobj np]]
|
|
set vlist [split [$sobj getvarpar $varindex] = ]
|
|
set scanstart [lindex $vlist 1]
|
|
set scanstep [lindex $vlist 2]
|
|
::scan::hdb_bmonscan -set feedback filename [SplitReply [dataFileName]]
|
|
::scan::hdb_bmonscan -set NP $numpoints
|
|
::scan::hdb_bmonscan -set scan_variable [string trim [lindex [split [lindex $vlist 0] . ] 1]];
|
|
::scan::hdb_bmonscan -set scan_start $scanstart
|
|
::scan::hdb_bmonscan -set scan_increment $scanstep
|
|
set scanvar_pts [SplitReply [$sobj getvardata $varindex]]
|
|
todo_msg "SET START TIME [sicstime]"
|
|
|
|
::scan::hdb_bmonscan -set feedback status BUSY
|
|
|
|
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;
|
|
clientput "Scan start: $scanstart, Scan step: $scanstep, Number of points: $numpoints"
|
|
clientput "Filetype: BEAM_MONITOR"
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
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
|
|
}
|
|
sicslist setatt ::scan::hdb_bmonscan long_name bmonscan
|
|
sicslist setatt ::scan::hdb_hmscan long_name hmscan
|
|
namespace eval scan {
|
|
namespace export runscan
|
|
proc runscan {scanvar start stop numpoints mode preset {savetype "save"} } {
|
|
variable save_filetype
|
|
variable reset_position
|
|
set reset_position "true"
|
|
if {[is_drivable $scanvar] == 0} {
|
|
return -code error "The scan variable <$scanvar> must be drivable"
|
|
}
|
|
if {[string is integer $numpoints] != 1} {
|
|
return -code error "Number of points <$numpoints> must be an integer"
|
|
}
|
|
if { $numpoints < 1 } {
|
|
return -code error "Number of points <$numpoints> must not be less than one"
|
|
}
|
|
::histogram_memory::count_method $mode
|
|
::histogram_memory::count_size $preset
|
|
|
|
if {$numpoints == 1} {
|
|
set step 0
|
|
} else {
|
|
set step [expr double($stop - $start)/($numpoints - 1.0)]
|
|
}
|
|
if {$step == 0 && $numpoints > 1} {
|
|
clientput "WARNING:Scan step is zero and number of points > 1. Adjusting numpoints to one"
|
|
set numpoints 1
|
|
}
|
|
|
|
switch $savetype {
|
|
"save" {
|
|
set save_filetype data
|
|
}
|
|
"nosave" {
|
|
set save_filetype scratch
|
|
}
|
|
default {
|
|
return -code error "$savetype should be 'save' or 'nosave'"
|
|
}
|
|
}
|
|
|
|
hmscan clear
|
|
hmscan add $scanvar $start $step
|
|
# hmscan ignores mode and preset, we use FAT_COUNT_METHOD and FAT_COUNT_STOP
|
|
set status [catch {hmscan run $numpoints timer 0} msg]
|
|
|
|
if {$status == 0} {
|
|
return $msg
|
|
} else {
|
|
return -code error "ERROR [info level 0]\n$msg"
|
|
}
|
|
}
|
|
}
|
|
namespace import ::scan::runscan
|
|
publish runscan user
|
|
sicslist setatt runscan privilege internal
|