Files
sics/tcl/scancom.tcl
cvs bde19bb973 - Fixes to HM code for AMOR TOF
- A couple of TAS fixes
- o2t was fixed to work with any drivable
- FOCUS was mended to include beam monitor in data file
2002-07-19 15:09:21 +00:00

543 lines
16 KiB
Tcl

#--------------------------------------------------------------------------
# general scan command wrappers for TOPSI and the like.
# New version using the object.tcl system from sntl instead of obTcl which
# caused a lot of trouble with tcl8.0
#
# Requires the built in scan command xxxscan.
#
# Mark Koennecke, February 2000
#--------------------------------------------------------------------------
#---------- adapt to the local settings
set home /data/koenneck/src
source $home/sics/object.tcl
set datapath $home/tmp
set recoverfil $home/tmp/recover.bin
#-------------------------- some utility functions -------------------------
proc MC { t n } {
set string $t
for { set i 1 } { $i < $n } { incr i } {
set string [format "%s%s" $string $t]
}
return $string
}
#--------------------------------------------------------------------------
proc GetNum { text } {
set list [split $text =]
return [lindex $list 1]
}
#---------------------------------------------------------------------------
#************** Definition of scan class **********************************
object_class ScanCommand {
member Mode Monitor
member NP 1
member counter counter
member NoVar 0
member Preset 10000
member File default.dat
member pinterest ""
member Channel 0
member Active 0
member Recover 0
member scanvars
member scanstart
member scanstep
member pinterest
method var {name start step} {
# check for activity
if {$slot(Active)} {
ClientPut "ERROR: cannot change parameters while scanning" error
return
}
# check parameters
set t [SICSType $name]
if { [string compare $t DRIV] != 0 } {
ClientPut [format "ERROR: %s is not drivable" $name] error
return 0
}
set t [SICSType $start]
if { [string compare $t NUM] != 0 } {
ClientPut [format "ERROR: %s is no number!" $start] error
return 0
}
set t [SICSType $step]
if { [string compare $t NUM] != 0 } {
ClientPut [format "ERROR: %s is no number!" $step] error
return 0
}
# install the variable
set i $slot(NoVar)
incr slot(NoVar)
lappend slot(scanvars) $name
lappend slot(scanstart) $start
lappend slot(scanstep) $step
$self SendInterest pinterest ScanVarChange
ClientPut OK
}
method info {} {
if { $slot(NoVar) < 1 } {
return "0,1,NONE,0.,0.,default.dat"
}
append result $slot(NP) "," $slot(NoVar)
for {set i 0} { $i < $slot(NoVar) } { incr i} {
append result "," [lindex $slot(scanvars) $i]
}
append result "," [lindex $slot(scanstart) 0] "," \
[lindex $slot(scanstep) 0]
set r1 [xxxscan getfile]
set l1 [split $r1 "="]
append result "," [lindex $l1 1]
return $result
}
method getvars {} {
set list ""
lappend list $slot(scanvars)
return [format "scan.Vars = %s -END-" $list]
}
method xaxis {} {
if { $slot(NoVar) <= 0} {
#---- default Answer
set t [format "%s.xaxis = %f %f" $self 0 1]
} else {
set t [format "%s.xaxis = %f %f" $self [lindex $slot(scanstart) 0] \
[lindex $slot(scanstep) 0] ]
}
ClientPut $t
}
method cinterest {} {
xxxscan interest
}
method uuinterest {} {
xxxscan uuinterest
}
method pinterest {} {
set nam [GetNum [config MyName]]
lappend $slot(pinterest) $nam
}
method SendInterest { type text } {
#------ check list first
set l1 $slot($type)
set l2 ""
foreach e $l1 {
set b [string trim $e]
set g [string trim $b "{}"]
set ret [SICSType $g]
if { [string first COM $ret] >= 0 } {
lappend l2 $e
}
}
#-------- update scan data and write
set slot($type) $l2
foreach e $l2 {
set b [string trim $e]
$b put $text
}
}
method mode { {NewVal NULL} } {
if { [string compare $NewVal NULL] == 0 } {
set val [format "%s.Mode = %s" $self $slot(Mode)]
ClientPut $val
return $val
} else {
# check for activity
if {$slot(Active)} {
ClientPut "ERROR: cannot change parameters while scanning" error
return
}
set tmp [string tolower $NewVal]
set NewVal $tmp
if { ([string compare $NewVal "timer"] == 0) || \
([string compare $NewVal monitor] ==0) } {
set slot(Mode) $NewVal
ClientPut OK
} else {
ClientPut [format "ERROR: %s not recognized as ScanMode" $NewVal]
}
}
}
method np { { NewVal NULL } } {
if { [string compare $NewVal NULL] == 0 } {
set val [format "%s.NP = %d" $self $slot(NP)]
ClientPut $val
return $val
} else {
# check for activity
if {$slot(Active)} {
ClientPut "ERROR: cannot change parameters while scanning" error
return
}
set t [SICSType $NewVal]
if { [string compare $t NUM] != 0 } {
ClientPut [format "ERROR: %s is no number" $NewVal] error
return
}
set slot(NP) $NewVal
ClientPut OK
}
}
method preset { {NewVal NULL} } {
if { [string compare $NewVal NULL] == 0 } {
set val [format "%s.Preset = %f" $self $slot(Preset)]
ClientPut $val
return $val
} else {
# check for activity
if {$slot(Active)} {
ClientPut "ERROR: cannot change parameters while scanning" error
return
}
set t [SICSType $NewVal]
if { [string compare $t NUM] != 0} {
ClientPut [format "ERROR: %s is no number" $NewVal] error
return
}
set slot(Preset) $NewVal
ClientPut OK
}
}
method file {} {
return [xxxscan file]
}
method setchannel {num} {
set ret [catch {xxxscan setchannel $num} msg]
if { $ret == 0} {
set slot(Channel) $num
} else {
return $msg
}
}
method list { } {
ClientPut [format "%s.Preset = %f" $self $slot(Preset)]
ClientPut [format "%s.Mode = %s" $self $slot(Mode)]
ClientPut [format "%s.File = %s" $self $slot(File)]
ClientPut [format "%s.NP = %d" $self $slot(NP)]
ClientPut [format "%s.Channel = %d" $self $slot(Channel)]
ClientPut "ScanVariables:"
for { set i 0 } {$i < $slot(NoVar) } { incr i } {
ClientPut [format " %s %f %f" [lindex $slot(scanvars) $i] \
[lindex $slot(scanstart) $i] \
[lindex $slot(scanstep) $i] ]
}
}
method clear {} {
# check for activity
if {$slot(Active)} {
ClientPut "ERROR: cannot clear running scan" error
return
}
set slot(NP) 0
set slot(NoVar) 0
set slot(scanvars) ""
set slot(scanstart) ""
set slot(scanstep) ""
$self SendInterest pinterest ScanVarChange
xxxscan clear
ClientPut OK
}
method getcounts {} {
return [xxxscan getcounts]
}
method run { } {
# start with error checking
if { $slot(NP) < 1 } {
ClientPut "ERROR: Insufficient Number of ScanPoints"
return
}
if { $slot(NoVar) < 1 } {
ClientPut "ERROR: No variables to scan given!"
return
}
#------- check for activity
if {$slot(Active)} {
ClientPut "ERROR: Scan already in progress" error
return
}
xxxscan clear
for {set i 0 } { $i < $slot(NoVar)} {incr i} {
set ret [catch {xxxscan add [lindex $slot(scanvars) $i] \
[lindex $slot(scanstart) $i] [lindex $slot(scanstep) $i]} msg]
if {$ret != 0} {
set slot(Active) 0
error $msg
}
}
set slot(Active) 1
set ret [catch \
{xxxscan run $slot(NP) $slot(Mode) $slot(Preset)} msg]
set slot(Active) 0
if {$ret != 0 } {
error $msg
} else {
return "Scan Finished"
}
}
method recover {} {
set slot(Active) 1
catch {xxxscan recover} msg
set slot(Active) 0
return "Scan Finished"
}
method forceclear {} {
set slot(Active) 0
}
}
#---- end of ScanCommand definition
#********************** initialisation of module commands to SICS **********
set ret [catch {scan list} msg]
#if {$ret != 0} {
object_new ScanCommand scan
Publish scan Spy
VarMake lastscancommand Text User
Publish scancounts Spy
Publish textstatus Spy
Publish cscan User
Publish sscan User
Publish sftime Spy
Publish scaninfo Spy
Publish wwwsics Spy
#}
#*************************************************************************
#===================== Helper commands for status display work ============
# a new user command which allows status clients to read the counts in a scan
# This is just to circumvent the user protection on scan
proc scancounts { } {
set status [ catch {scan getcounts} result]
if { $status == 0 } {
return $result
} else {
return "scan.Counts= 0"
}
}
#---------------------------------------------------------------------------
# This is just another utilility function which helps in implementing the
# status display client
proc textstatus { } {
set text [status]
return [format "Status = %s" $text]
}
#---------------------------------------------------------------------------
# Dumps time in a useful format
proc sftime {} {
return [format "sicstime = %s" [sicstime]]
}
#-------------------------------------------------------------------------
# Utility function which gives scan parameters as an easily parsable
# comma separated list for java status client
proc scaninfo {} {
set result [scan info]
set r1 [sample]
set inf [string first = $r1]
if {$inf > 0} {
incr inf
set sa [string range $r1 $inf end]
} else {
set sa Unknown
}
regsub -all , $sa " " sam
append result "," $sam
append result "," [sicstime]
set r1 [lastscancommand]
set l1 [split $r1 "="]
append result "," [lindex $l1 1]
return [format "scaninfo = %s" $result]
}
#----------------------------------------------------------------------
# wwwsics is a procedure which formats the most important status
# information for the WWW-status.
proc wwwsics {} {
#----- get all the data we need
set user [GetNum [user]]
set sample [GetNum [sample]]
set tit [GetNum [title]]
set ret [catch {lambda} msg]
if {$ret != 0 } {
set lam Undetermined
} else {
set lam [GetNum $msg]
}
set lscan [GetNum [lastscancommand]]
set svar [GetNum [scan getvars]]
set ind [string last -END- $svar]
if { $ind > 2 } {
set svar [string range $svar 0 $ind]
} else {
set svar " "
}
set res [scan info]
set l [split $res ,]
set fil [lindex $l 5]
set run [GetNum [sicsdatanumber]]
set stat [GetNum [status]]
#------- html format the reply
append result "<table BORDER=2>"
append result <tr> <th>Run Number</th> <td> $run </td> </tr>
append result <tr> <th>Title</th> <td> $tit </td> </tr>
append result <tr> <th>User</th> <td> $user </td> </tr>
append result <tr> <th>Sample </th> <td> $sample </td> </tr>
append result <tr> <th>wavelength</th> <td> $lam</td> </tr>
append result <tr> <th>Status</th> <td> $stat</td> </tr>
append result <tr> <th>Scan Variables</th> <td> $svar</td> </tr>
append result <tr> <th>File </th> <td> $fil</td> </tr>
append result <tr> <th>Last Scan Command</th> <td> $lscan</td> </tr>
append result </table>
return $result
}
#===================== Syntactical sugar around scan ===================
# center scan. A convenience scan for the one and only Daniel Clemens
# at TOPSI. Scans around a given center point. Requires the scan command
# for TOPSI to work.
#
# another convenience scan:
# sscan var1 start end var1 start end .... np preset
# scans var1, var2 from start to end with np steps and a preset of preset
#
# Mark Koennecke, August, 22, 1997
#-----------------------------------------------------------------------------
proc cscan { var center delta np preset } {
#------ start with some argument checking
set t [SICSType $var]
if { [string compare $t DRIV] != 0 } {
ClientPut [format "ERROR: %s is NOT drivable!" $var]
return
}
set t [SICSType $center]
if { [string compare $t NUM] != 0 } {
ClientPut [format "ERROR: %s is no number!" $center]
return
}
set t [SICSType $delta]
if { [string compare $t NUM] != 0 } {
ClientPut [format "ERROR: %s is no number!" $delta]
return
}
set t [SICSType $np]
if { [string compare $t NUM] != 0 } {
ClientPut [format "ERROR: %s is no number!" $np]
return
}
set t [SICSType $preset]
if { [string compare $t NUM] != 0 } {
ClientPut [format "ERROR: %s is no number!" $preset]
return
}
#-------- store command in lastscancommand
set txt [format "cscan %s %s %s %s %s" $var $center \
$delta $np $preset]
catch {lastscancommand $txt}
#-------- set standard parameters
scan clear
scan preset $preset
scan np [expr $np*2 + 1]
#--------- calculate start
set start [expr $center - $np * $delta]
set ret [catch {scan var $var $start $delta} msg]
if { $ret != 0} {
ClientPut $msg
return
}
#---------- start scan
set ret [catch {scan run} msg]
if {$ret != 0} {
error $msg
}
}
#---------------------------------------------------------------------------
proc sscan args {
scan clear
#------- check arguments: the last two must be preset and np!
set l [llength $args]
if { $l < 5} {
ClientPut "ERROR: Insufficient number of arguments to sscan"
return
}
set preset [lindex $args [expr $l - 1]]
set np [lindex $args [expr $l - 2]]
set t [SICSType $preset]
ClientPut $t
ClientPut [string first $t "NUM"]
if { [string compare $t NUM] != 0 } {
ClientPut [format "ERROR: expected number for preset, got %s" \
$preset]
return
}
set t [SICSType $np]
if { [string compare $t NUM] != 0 } {
ClientPut [format "ERROR: expected number for np, got %s" \
$np]
return
}
scan preset $preset
scan np $np
#--------- do variables
set nvar [expr ($l - 2) / 3]
for { set i 0 } { $i < $nvar} { incr i } {
set var [lindex $args [expr $i * 3]]
set t [SICSType $var]
if {[string compare $t DRIV] != 0} {
ClientPut [format "ERROR: %s is not drivable" $var]
return
}
set start [lindex $args [expr ($i * 3) + 1]]
set t [SICSType $start]
if { [string compare $t NUM] != 0 } {
ClientPut [format "ERROR: expected number for start, got %s" \
$start]
return
}
set end [lindex $args [expr ($i * 3) + 2]]
set t [SICSType $end]
if { [string compare $t NUM] != 0 } {
ClientPut [format "ERROR: expected number for end, got %s" \
$end]
return
}
#--------- do scan parameters
set step [expr double($end - $start)/double($np)]
set ret [catch {scan var $var $start $step} msg]
if { $ret != 0} {
ClientPut $msg
return
}
}
#------------- set lastcommand text
set txt [format "sscan %s" [join $args]]
catch {lastscancommand $txt}
#------------- start scan
set ret [catch {scan run} msg]
if {$ret != 0} {
error $msg
}
}