Implements a protocol handler for the protek 608 multimeters which just allows us to read the display. It reports all elements of the display including the bar graph, it does not provide remote control of the multimeter. The protocol handler broadcasts a warning to all clients if the auto-off function is enabled. sct_rfamp.c This is a protocol handler for the Mirrortron 35V 7A AC Generator (ANSFR-83B). sinqhttpprot.c Copied the PSI script context http protocol handler. sct_orhvpsprot.c Ordela high voltage power supply protocol handler now catches unknown commands. sct_eurotherm_2000.tcl Eurotherm controller for the kowari load frame by Douglas Clowes. sct_lakeshore_3xx.tcl Latest update from Arndt. The two control loops are now independent, settletime and tolerance now work properly. common_instrument_dictionary.tcl Make instrument/status saveable. sct_orhvps_common.tcl Provides voltage ramping and implements the dhv1 command for the Ordela HVPS via the sct_orhpsprot.c protocol handler. hmm_configuration_common_1.tcl Adds new "histmem clockscale" subcommand to get and set the clock scale from the fat_clock_scale FAT parameter. You can now upload the FAT FRAME_BUFFER and FRAME_DUTYCYCLE parameters to the histogram memory. The veto commands are now "histmem veto on" and "histmem veto off". hmm_object.tcl The axis order for the histmem object has been restore to t,y,x sct_positmotor_common.tcl Code has been simplified. nxscripts_common_1.tcl Removed obsolete ::nexus::data function. TOF axis now correctly report time_of_flight instead of "time". plc_common_1.tcl Make PLC info saveable. scan_common_1.tcl SICS-385 The scan command should check the final scan variable value against he soft upper and lower limits, not against the hard limits. Make sure that the scan variable axis is saved. platypus, kowari, quokka hmm_configuration.tcl Use the HOR and VER entries in the new histmem_axes hash to select the horizontal and vertical axes for the histmem. kowari motor_configuration.tcl secondary_slit_configuration.tcl Flatten slits motor structure to match old layout in data files. quokka commands.tcl SICS-380 EApPosYmm -> EApPosY quokka detector.tcl Use new script context controller for Ordela HVPS quokka hmm_configuration.tcl Set detector height to 5.08*192 the same as the width quokka motor_configuration.tcl Code cleanup quokka positmotor_configuration.tcl Use new positmotor code. quokka aperture_configuration.tcl Added attenuation factor column to AttRotLookupTable quokka parameters.tcl SICS-380 Refactor nexus, remove redundant parameters. site_ansto.c Added the following protocols, Httpl, Protek608, aand RFAmp. scriptcontext.c SICS-386 SctActionHandler: set "send" string to NULL when a chain of scripts completes with state=idle. It turns out that if none of the scripts in the "read chain" call [sct send] each time the chain is executed, then SICS will hammer the device with calls to AsconWrite(). This can be avoided if SctActionHandler sets the 'send' string to NULL before "goto finish" in the idle state. This will be safer and still let you have chains with multiple [sct send] and read scripts. asyncprotocol.c Fix platypus memory leak. devser.c SICS-387 Started adding code to pass signals on to script context drivers. ascon.c AsconTask(): Make sure we return to the AsconIdle state when sending a command which expect no response, also only reconnect if there is a Timeout when there has been an error. r2888 | ffr | 2010-04-19 14:04:41 +1000 (Mon, 19 Apr 2010) | 90 lines
465 lines
16 KiB
Tcl
465 lines
16 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.\n
|
|
# ::scan::reset_position true/false (default=true), drive motor back to start
|
|
# position at end of scan\n
|
|
# ::scan::force_scan true/false, (default=false), Will force a scan if the
|
|
# instrument isn't ready, eg shutters closed. Note: The scan will still fail if
|
|
# you are scanning against a motor and motion control is disabled.\n
|
|
# If force_scan is true it is immediately reset to false after it is checked.
|
|
#TODO Get rid of duplication in bmonscan and hmscan code
|
|
|
|
namespace eval scan {
|
|
variable ic_runscanpar
|
|
|
|
variable ic_hmm_datatype
|
|
variable save_filetype
|
|
variable reset_position
|
|
variable check_thread0
|
|
variable check_instrument_ready
|
|
variable force_scan
|
|
|
|
set check_thread0 true
|
|
set check_instrument_ready true
|
|
set force_scan false
|
|
set save_filetype "data"
|
|
set reset_position "false"
|
|
|
|
if {[SplitReply [motor_simulation]] == "true"} {
|
|
set check_thread0 false
|
|
}
|
|
|
|
}
|
|
|
|
##
|
|
# @brief This is a convenience command which allows hmscans to be forced.
|
|
# Call this before calling hmscan run to force a scan if the instrument isn't ready.
|
|
proc force_scan {} {
|
|
set ::scan::force_scan "true"
|
|
}
|
|
publish force_scan user
|
|
|
|
proc ::scan::bm_scan_collect {sobj uobj point} {
|
|
set vlist [split [$sobj getvarpar 0] = ];
|
|
|
|
set w(NP) $point
|
|
set sv [string trim [lindex [split [lindex $vlist 0] . ] 1]]
|
|
set header [format "%-4.4s %-9.9s %-14s %-7.7s" NP $sv Counts Time]
|
|
set varval [SplitReply [$sv]]
|
|
set counts [SplitReply [bm getcounts]]
|
|
set time [SplitReply [bm gettime]]
|
|
set data [format "%-4d %-9.3f %-14d %-7.2f" $point $varval $counts $time]
|
|
clientput $header
|
|
clientput $data
|
|
for {set chn 0} {$chn < $::counter::isc_numchannels} {incr chn} {
|
|
clientput "Channel $chn [SplitReply [bm getmonitor $chn]]"
|
|
}
|
|
}
|
|
|
|
proc ::scan::hmm_scan_collect {sobj uobj point} {
|
|
set vlist [split [$sobj getvarpar 0] = ];
|
|
|
|
set w(NP) $point
|
|
set sv [string trim [lindex [split [lindex $vlist 0] . ] 1]]
|
|
set header [format "%-4.4s %-9.9s %-14s %-7.7s" NP $sv Counts Time]
|
|
set varval [SplitReply [$sv]]
|
|
set counts [SplitReply [::histogram_memory::total_counts]]
|
|
set time [SplitReply [::histogram_memory::time]]
|
|
set data [format "%-4d %-9.3f %-14d %-7.2f" $point $varval $counts $time]
|
|
clientput $header
|
|
clientput $data
|
|
for {set bmn 1} {$bmn <= $::counter::isc_numchannels} {incr bmn} {
|
|
set bmon bm$bmn
|
|
clientput "Monitor $bmn [SplitReply [$bmon getcounts]]"
|
|
}
|
|
}
|
|
|
|
proc ::scan::ic_initialize {} {
|
|
if [ catch {
|
|
variable ic_runscanpar
|
|
variable ic_hmm_datatype
|
|
|
|
set ic_hmm_datatype HISTOGRAM_XYT
|
|
|
|
MakeScanCommand hmscan bm $::cfPath(scan)/scan_common_1.hdd recover.bin
|
|
MakeScanCommand bmonscan bm $::cfPath(scan)/scan_common_1.hdd recover.bin
|
|
|
|
bmonscan configure script
|
|
bmonscan function writeheader ::scan::donothing
|
|
bmonscan function writepoint ::scan::bm_writepoint
|
|
bmonscan function count ::scan::bm_count
|
|
bmonscan function collect ::scan::bm_scan_collect
|
|
bmonscan function prepare ::scan::bm_scan_prepare
|
|
bmonscan function finish ::scan::bm_scan_finish
|
|
|
|
|
|
hmscan configure script
|
|
hmscan function writeheader ::scan::donothing
|
|
hmscan function writepoint ::scan::hmm_writepoint
|
|
hmscan function count ::scan::hmm_count
|
|
hmscan function collect ::scan::hmm_scan_collect
|
|
hmscan function prepare ::scan::hmm_scan_prepare
|
|
hmscan function finish ::scan::hmm_scan_finish
|
|
|
|
# TODO Use ic_runscanpar to create the ::scan::runscan command and
|
|
# to validate the "runscan" proc parameters.
|
|
array set ic_runscanpar [subst {
|
|
scanvar text=drivable
|
|
start float
|
|
stop float
|
|
numpoints int=0,inf
|
|
mode text=[join [concat [list time unlimited period count frame] $::counter::isc_beam_monitor_list ] , ]
|
|
preset float=0,inf
|
|
datatype text=[join [array names ::nexus::histmem_filetype_spec] , ]
|
|
savetype text=save,nosave
|
|
force boolean
|
|
}]
|
|
} message ] {
|
|
if {$::errorCode=="NONE"} {return $message}
|
|
return -code error $message
|
|
}
|
|
}
|
|
|
|
##
|
|
# @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} {
|
|
variable check_thread0
|
|
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 "ERROR: Can't drive scan variable, $scan_variable position is set to 'fixed'"
|
|
} elseif {$check_thread0 && [SplitReply [$scan_variable thread0]] == -1} {
|
|
return -code error "ERROR: Can't scan ${scan_variable}. Thread zero has stopped running on the motion controller"
|
|
}
|
|
set scan_final [expr $scan_start + ($NP-1) * $scan_increment]
|
|
if [catch {
|
|
::scan::check_limit $scan_variable softlowerlim $scan_final
|
|
::scan::check_limit $scan_variable softupperlim $scan_final
|
|
::scan::check_limit $scan_variable softlowerlim $scan_start
|
|
::scan::check_limit $scan_variable softupperlim $scan_start
|
|
}] {
|
|
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 save_filetype
|
|
variable ic_hmm_datatype
|
|
variable check_instrument_ready
|
|
variable force_scan
|
|
|
|
if {$force_scan || $check_instrument_ready && [::plc::inst_ready]} {
|
|
set force_scan false
|
|
if [catch {
|
|
::scan::check_scanvar $sobj $uobj
|
|
::scan::pre_hmm_scan_prepare
|
|
}] {
|
|
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::runscan_cmd -set feedback status BUSY
|
|
run_mode "hmscan"
|
|
|
|
set ::histogram_memory::histmem_axes(SVAR) [SplitReply [sicslist [::scan::runscan_cmd -set scan_variable] hdb_path] ]
|
|
::nexus::newfile $ic_hmm_datatype $save_filetype
|
|
|
|
clientput "Scan start: $scanstart, Scan step: $scanstep, Number of points: $numpoints"
|
|
clientput "Datatype: $ic_hmm_datatype"
|
|
# Prime DAE
|
|
hmm pause
|
|
}] {
|
|
run_mode "normal"
|
|
return -code error $::errorInfo
|
|
}
|
|
} else {
|
|
return -code error "HMSCAN ABORTED: Instrument not ready"
|
|
}
|
|
}
|
|
|
|
proc ::scan::hmm_count {sobj uobj point mode preset} {
|
|
::scan::runscan_cmd -set feedback scanpoint $point
|
|
::scan::runscan_cmd -set feedback scan_variable_value [SplitReply [[::scan::runscan_cmd -set scan_variable]]]
|
|
# Start histogram and block until count is complete
|
|
::histogram_memory::start block
|
|
}
|
|
|
|
#TODO rangescan: drive to original position for rangescans, not the start position.
|
|
proc ::scan::hmm_scan_finish {sobj uobj} {
|
|
variable save_filetype
|
|
variable reset_position
|
|
set $save_filetype "data"
|
|
::histogram_memory::stop
|
|
::scan::runscan_cmd -set feedback status IDLE
|
|
run_mode "normal"
|
|
# 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::runscan_cmd -get scan_variable]
|
|
set svtype [getatt $svar type]
|
|
if {$svtype == "motor" || $svtype == "configurablevirtualmotor"} {
|
|
drive $svar [::scan::runscan_cmd -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
|
|
run_mode "normal"
|
|
# 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]
|
|
}
|
|
}
|
|
}
|
|
|
|
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 check_instrument_ready
|
|
variable force_scan
|
|
|
|
if {$force_scan || $check_instrument_ready && [::plc::inst_ready]} {
|
|
set force_scan false
|
|
if [catch {
|
|
::scan::check_scanvar $sobj $uobj
|
|
::scan::pre_hmm_scan_prepare
|
|
}] {
|
|
return -code error "BMONSCAN ABORTED: $::errorInfo"
|
|
}
|
|
|
|
if [catch {
|
|
#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 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]]
|
|
|
|
::scan::hdb_bmonscan -set feedback status BUSY
|
|
run_mode "bmonscan"
|
|
|
|
array set bm_fb [::scan::hdb_bmonscan -list feedback]
|
|
set ::histogram_memory::histmem_axes(SVAR) [SplitReply [sicslist [::scan::hdb_bmonscan -set scan_variable] hdb_path] ]
|
|
::nexus::newfile BEAM_MONITOR data
|
|
#stdscan prepare $sobj $uobj;
|
|
clientput "Scan start: $scanstart, Scan step: $scanstep, Number of points: $numpoints"
|
|
clientput "Datatype: BEAM_MONITOR"
|
|
}] {
|
|
run_mode "normal"
|
|
return -code error $::errorInfo
|
|
}
|
|
} else {
|
|
return -code error "BMONSCAN ABORTED: Instrument not ready"
|
|
}
|
|
}
|
|
|
|
|
|
|
|
Publish ::scan::hmm_count user
|
|
Publish ::scan::hmm_scan_prepare user
|
|
Publish ::scan::hmm_scan_finish user
|
|
Publish ::scan::hmm_scan_collect 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_scan_collect user
|
|
Publish ::scan::bm_writepoint user
|
|
Publish ::scan::bm_count user
|
|
|
|
namespace eval scan {
|
|
namespace export runscan
|
|
VarMake ::scan::runscan_reset_position Text internal
|
|
::scan::runscan_reset_position false
|
|
#TODO Add counter (monitor_1 monitor_2 ... histmem) and filetype BEAM_MONITOR HISTMEM_?
|
|
##
|
|
# @brief Run a histogram memory scan
|
|
# @param filetype one of the histogram filetypes (default=HISTOGRAM_XYT)
|
|
# @param savetype save/nosave (default=save)
|
|
# @param force true/false (default=false)
|
|
|
|
proc runscan {scanvar start stop numpoints mode preset args} {
|
|
variable ic_hmm_datatype
|
|
variable save_filetype
|
|
variable reset_position
|
|
variable force_scan
|
|
|
|
if [ catch {
|
|
set force_scan false
|
|
|
|
set hm_ft_names [array names ::nexus::histmem_filetype_spec]
|
|
|
|
# Default filetype for histogram memory scans
|
|
set ic_hmm_datatype "HISTOGRAM_XYT"
|
|
# Default save uniquely numbered files
|
|
set savetype "save"
|
|
set reset_position [SplitReply [::scan::runscan_reset_position]]
|
|
if {[is_drivable $scanvar] == 0} {
|
|
error "The scan variable <$scanvar> must be drivable"
|
|
}
|
|
if {[string is integer $numpoints] != 1} {
|
|
error "Number of points <$numpoints> must be an integer"
|
|
}
|
|
if { $numpoints < 1 } {
|
|
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
|
|
}
|
|
|
|
foreach {arg val} $args {
|
|
switch $arg {
|
|
"force" {
|
|
if [string is boolean $val] {
|
|
set force_scan $val
|
|
} else {
|
|
error "ERROR: force must be true or false"
|
|
}
|
|
}
|
|
"datatype" {
|
|
set ic_hmm_datatype $val
|
|
}
|
|
"savetype" {
|
|
switch $val {
|
|
"save" {
|
|
set save_filetype data
|
|
}
|
|
"nosave" {
|
|
set save_filetype scratch
|
|
}
|
|
default {
|
|
error "ERROR: $arg $val, valid values for $arg are 'save' or 'nosave'"
|
|
}
|
|
}
|
|
}
|
|
default {
|
|
error "ERROR: $arg should be 'datatype' 'savetype' or 'force'"
|
|
}
|
|
}
|
|
}
|
|
|
|
hmscan clear
|
|
hmscan add $scanvar $start $step
|
|
# hmscan ignores mode and preset, we use FAT_COUNT_METHOD and FAT_COUNT_STOP
|
|
::scan::runscan_cmd -set numpoints $numpoints
|
|
::scan::runscan_cmd -set scan_variable $scanvar
|
|
::scan::runscan_cmd -set scan_start $start
|
|
::scan::runscan_cmd -set scan_stop $stop
|
|
::scan::runscan_cmd -set feedback scan_step $step
|
|
::scan::runscan_cmd -set mode $mode
|
|
::scan::runscan_cmd -set preset $preset
|
|
hmscan run $numpoints timer 0
|
|
} message ] {
|
|
set force_scan false
|
|
return -code error "ERROR [info level 0]\n$message"
|
|
} else {
|
|
set force_scan false
|
|
return $message
|
|
}
|
|
}
|
|
}
|
|
namespace import ::scan::runscan
|
|
publish runscan user
|
|
sicslist setatt runscan privilege internal
|