#-----------------------------------------------------------------------
# This is a collection of utility procedures to help with Hipadaba and
# Gumtree Swiss Edition. This file is supposed to be sourced by any
# instrument using Hipadaba.
#
# Copyright: see file COPYRIGHT
#
# Collected from various files: Mark Koennecke, March 2008
#
# Requirements:
# * the internal scan command xxxscan
# * scan data to live /graphics/scan_data
#
# Many updates, till November 2008, Mark Koennecke
#----------------------------------------------------------------------
if { [info exists hdbinit] == 0 } {
set hdbinit 1
MakeStateMon
Publish getgumtreexml Spy
if {[string first tmp $home] < 0} {
set tmppath $home/tmp
} else {
set tmppath $home
}
Publish mgbatch Spy
Publish loadmgbatch Spy
Publish hsearchprop Spy
Publish hdbscan User
Publish hdbprepare User
Publish hdbcollect User
Publish listbatchfiles Spy
Publish makemumopos User
Publish dropmumo User
Publish hdbbatchpath User
Publish cscan User
Publish sscan User
Publish scan Spy
Publish hmake Mugger
Publish hmakescript Mugger
Publish hlink Mugger
Publish hcommand Mugger
Publish hdbstorenexus User
Publish scaninfo Spy
}
#===================================================================
# Configuration commands provided:
# hdbReadOnly
# makesampleenv path
# makestdscan path
# makestdscangraphics path
# makestdbatch
# makeQuickPar name path
# makeslit path left right upper lower
# configures a slit. Missing motors can be indicated with NONE
# makestdadmin
# makecount path
# makerepeat path
# makekillfile path
# makesuccess path
# makestdgui
# makewait path
# makeevproxy rootpath hdbname devicename
# makemumo rootpath mumoname
# makeexe
# confnxhdb path alias pass
#===================== hfactory adapters ==========================
proc hmake {path priv type {len 1}} {
hfactory $path plain $priv $type $len
}
#--------------------------------------------------------------------
proc hmakescript {path readscript writescript type {len 1}} {
hfactory $path script $readscript $writescript $type $len
}
#-------------------------------------------------------------------
proc hlink {path obj {treename NONE} } {
if {[string equal $treename NONE]} {
set treename $ob
}
append realpath $path / $treename
hfactory $realpath link $obj
}
#-------------------------------------------------------------------
proc hcommand {path script} {
hfactory $path command $script
}
#================ make XML tree =====================================
proc getdataType {path} {
return [lindex [split [hinfo $path] ,] 0]
}
#---------------------------------------------------------------------
proc makeInitValue {path type prefix} {
append result ""
if {[string compare $type none] != 0 && [string compare $type func] != 0} {
set test [catch {hgetprop $path transfer} msg]
set tst [catch {hval $path} val]
if {$test != 0 && $tst == 0} {
append result "$prefix \n"
append result "$prefix $val\n"
append result "$prefix \n"
}
}
return $result
}
#----------------------------------------------------------------------
proc make_nodes {path result indent} {
set nodename [file tail $path];
set type [getdataType $path]
set prefix [string repeat " " $indent]
set newIndent [expr $indent + 2]
#array set prop_list [ string trim [join [split [hlistprop $path] =]] ]
set prop_list(control) true
set we_have_control [info exists prop_list(control)]
if {$we_have_control == 0 || $we_have_control && $prop_list(control) == "true"} {
append result "$prefix\n"
foreach p [property_elements $path $newIndent] {
append result $p
}
foreach x [hlist $path] {
set result [make_nodes [string map {// /} "$path/$x"] $result $newIndent]
}
# append result [makeInitValue $path $type $prefix]
append result "$prefix\n"
}
return $result
}
#-------------------------------------------------------------------
proc property_elements_old {path indent} {
set prefix [string repeat " " $indent]
foreach {key value} [string map {= " "} [hlistprop $path]] {
if {[string compare -nocase $key "control"] == 0} {continue}
lappend proplist "$prefix\n"
# foreach v [split $value ,] {
# lappend proplist "$prefix$prefix$v\n"
# }
lappend proplist "$prefix$prefix$value\n"
lappend proplist "$prefix\n"
}
if [info exists proplist] {return $proplist}
}
#-----------------------------------------------------------------------
proc property_elements {path indent} {
set prefix [string repeat " " $indent]
set data [hlistprop $path]
set propList [split $data \n]
foreach prop $propList {
set pl [split $prop =]
set key [string trim [lindex $pl 0]]
set value [string trim [lindex $pl 1]]
if {[string length $key] < 1} {
continue
}
lappend proplist "$prefix\n"
lappend proplist "$prefix$prefix$value\n"
lappend proplist "$prefix\n"
}
if [info exists proplist] {return $proplist}
}
#--------------------------------------------------------------------------
proc getgumtreexml {path} {
append result "\n"
append result "\n"
if {[string compare $path "/" ] == 0} {
foreach n [hlist $path] {
set result [make_nodes /$n $result 2]
}
} else {
foreach n [hlist $path] {
set result [make_nodes $path/$n $result 2]
}
}
append result "\n"
}
#==================== Gumtree batch =========================================
proc searchPathForDrivable {name} {
set path [string trim [hmatchprop / sicsdev $name]]
if {[string compare $path NONE] != 0} {
return $path
}
set txt [findalias $name]
if {[string compare $txt NONE] == 0} {
return NONE
}
set l1 [split $txt =]
set l [split [lindex $l1 1] ,]
foreach alias $l {
set alias [string trim $alias]
set path [string trim [hmatchprop / sicsdev $alias]]
if {[string compare $path NONE] != 0} {
return $path
}
}
return NONE
}
#----------------------------------------------------------------
proc searchForCommand {name} {
return [string trim [hmatchprop / sicscommand $name]]
}
#----------------------------------------------------------------
proc treatsscan {scanpath command out} {
set l [split $command]
set len [llength $l]
set noVar [expr ($len-2)/3]
set np [lindex $l [expr $len -2]]
set preset [lindex $l [expr $len -1]]
for {set i 0} {$i < $noVar} {incr i} {
set start [expr $i * 3]
set scanVar [lindex $l [expr 1 + $start]]
set scanStart [lindex $l [expr 2 + $start]]
set scanEnd [lindex $l [expr 3 + $start]]
set scanStep [expr ($scanEnd*1. - $scanStart*1.)/$np*1.]
append hdbVar $scanVar ,
append hdbStart $scanStart ,
append hdbStep $scanStep ,
}
set hdbVar [string trim $hdbVar ,]
set hdbStart [string trim $hdbStart ,]
set hdbStep [string trim $hdbStep ,]
puts $out "\#NODE: $scanpath"
puts $out "clientput BatchPos = 1"
puts $out "hdbscan $hdbVar $hdbStart $hdbStep $np monitor $preset"
}
#----------------------------------------------------------------
proc treatcscan {scanpath command out} {
set l [split $command]
set scanVar [lindex $l 1]
set scanCenter [lindex $l 2]
set scanStep [lindex $l 3]
set np [lindex $l 4]
set preset [lindex $l 5]
set hdbStart [expr $scanCenter - ($np*1.0)/2. * $scanStep*1.0]
puts $out "\#NODE: $scanpath"
puts $out "clientput BatchPos = 1"
puts $out "hdbscan $scanVar $hdbStart $scanStep $np monitor $preset"
}
#----------------------------------------------------------------
proc translateCommand {command out} {
set drivelist [list drive dr run]
set textList [list for while source if]
# clientput "Translating: $command"
set command [string trim $command]
if {[string length $command] < 2} {
return
}
set l [split $command]
set obj [string trim [lindex $l 0]]
#------- check for drive commands
set idx [lsearch $drivelist $obj]
if {$idx >= 0} {
set dev [lindex $l 1]
set path [searchPathForDrivable $dev]
if {[string compare $path NONE] != 0} {
set realTxt [hgetprop $path sicsdev]
set realL [split $realTxt =]
set realDev [lindex $realL 1]
set mapList [list $dev $realDev]
set newCom [string map $mapList $command]
puts $out "\#NODE: $path"
puts $out "clientput BatchPos = 1"
puts $out $newCom
return
}
}
#------ check for well known broken commands
set idx [lsearch $textList $obj]
if {$idx >= 0} {
puts $out "\#NODE: /batch/commandtext"
puts $out "clientput BatchPos = 1"
set buffer [string map {\n @nl@} $command]
puts $out "hset /batch/commandtext $buffer"
return
}
#--------- check for simple commands
set path [searchForCommand $command]
if {[string compare $path NONE] != 0} {
puts $out "\#NODE: $path"
puts $out "clientput BatchPos = 1"
puts $out $command
return
}
set scancom [searchForCommand hdbscan]
#---------- deal with scans
if {[string first sscan $obj] >= 0} {
if {[catch {treatsscan $scancom $command $out}] == 0} {
return
}
}
if {[string first cscan $obj] >= 0} {
if {[catch {treatsscan $scancom $command $out}] == 0} {
return
}
}
#--------- give up: output as a text node
puts $out "\#NODE: /batch/commandtext"
puts $out "clientput BatchPos = 1"
set buffer [string map {\n @nl@} $command]
puts $out "hset /batch/commandtext $buffer"
}
#----------------------------------------------------------------
proc mgbatch {filename} {
global tmppath
set f [open $filename r]
gets $f line
close $f
if {[string first MOUNTAINBATCH $line] > 0} {
#--------- This is a mountaingum batch file which does not need
# to be massaged
return $filename
}
set f [open $filename r]
set realfilename [file tail $filename]
set out [open $tmppath/$realfilename w]
puts $out \#MOUNTAINBATCH
while {[gets $f line] >= 0} {
append buffer $line
if {[info complete $buffer] == 1} {
translateCommand $buffer $out
unset buffer
} else {
append buffer \n
}
}
close $out
return $tmppath/$realfilename
}
#----------------------------------------------------------------
proc loadmgbatch {filename} {
set txt [exe fullpath $filename]
set l [split $txt =]
set realf [lindex $l 1]
set realf [mgbatch $realf]
return [exe print $realf]
}
#============== hdbscan =========================================
proc hdbscan {scanvars scanstart scanincr np mode preset} {
global stdscangraph hdbscanactive
xxxscan clear
xxxscan configure script
xxxscan function prepare hdbprepare
xxxscan function collect hdbcollect
set varlist [split $scanvars ,]
set startlist [split $scanstart ,]
set incrlist [split $scanincr ,]
catch {hset $stdscangraph/scan_variable/name [lindex $varlist 0]}
set count 0
foreach var $varlist {
if {[string first / $var] >= 0} {
set var [string trim [SplitReply [hgetprop $var sicsdev]]]
}
xxxscan add $var [lindex $startlist $count] [lindex $incrlist $count]
incr count
}
set hdbscanactive 1
set status [catch {xxxscan run $np $mode $preset} msg]
set hdbscanactive 0
if {$status == 0} {
return $msg
} else {
error $msg
}
}
#------------------------------------------------------------------------------
proc hdbprepare {obj userdata } {
global stdscangraph
stdscan prepare $obj userdata
catch {hupdate $stdscangraph/dim}
}
#------------------------------------------------------------------------------
proc hdbcollect {obj userobj np} {
global stdscangraph
stdscan collect $obj $userobj $np
catch {hupdate $stdscangraph/scan_variable}
catch {hupdate $stdscangraph/counts}
}
#-----------------------------------------------------------------------------
proc gethdbscanvardata {no} {
set np [string trim [SplitReply [xxxscan np]]]
if {$np == 0} {
return ".0 .0 .0"
}
set status [catch {SplitReply [xxxscan getvardata $no]} txt]
if {$status == 0} {
return [join $txt]
} else {
return ".0 .0 .0"
}
}
#----------------------------------------------------------------------------
proc gethdbscancounts {} {
set np [string trim [SplitReply [xxxscan np]]]
if {$np == 0} {
return "0 0 0"
}
set status [catch {SplitReply [xxxscan getcounts]} txt]
if {$status == 0} {
return [join $txt]
} else {
return "0 0 0"
}
}
#================= helper to get the list of batch files =================
proc listbatchfiles {} {
set ext [list *.tcl *.job *.run]
set txt [SplitReply [exe batchpath]]
set dirlist [split $txt :]
set txt [SplitReply [exe syspath]]
set dirlist [concat $dirlist [split $txt :]]
# clientput $dirlist
set result [list ""]
foreach dir $dirlist {
foreach e $ext {
set status [catch {glob [string trim $dir]/$e} filetxt]
if {$status == 0} {
set filelist [split $filetxt]
foreach f $filelist {
# clientput "Working at $f"
set nam [file tail $f]
if { [lsearch $result $nam] < 0} {
# clientput "Adding $nam"
lappend result $nam
}
}
} else {
# clientput "ERROR: $filetxt"
}
}
}
foreach bf $result {
append resulttxt $bf ,
}
return [string trim $resulttxt ,]
}
#-------------------------------------------------------------------------
proc hsearchprop {root prop val} {
set children [hlist $root]
set childlist [split $children \n]
if {[llength $childlist] <= 0} {
error "No children"
}
foreach child $childlist {
if {[string length $child] < 1} {
continue
}
catch {hgetprop $root/$child $prop} msg
if { [string first ERROR $msg] < 0} {
set value [string trim [SplitReply $msg]]
if { [string equal -nocase $value $val] == 1} {
return $root/$child
}
}
set status [catch {hsearchprop $root/$child $prop $val} node]
if {$status == 0} {
return $node
}
}
error "Not found"
}
#============ various utility routines =====================================
proc hdbReadOnly {} {
error "Parameter is READ ONLY"
}
#---------------------------------------------------------------------------
proc makesampleenv {path} {
hfactory $path plain spy none
hsetprop $path type graphdata
hsetprop $path viewer mountaingumui.TimeSeries
hfactory $path/vars plain user text
hset $path/vars tomato
hfactory $path/rank plain user int
hset $path/rank 1
hfactory $path/dim plain user intar 1
hset $path/dim 300
hfactory $path/getdata plain user text
hsetprop $path/getdata type logcommand
hfactory $path/getdata/starttime plain spy text
hfactory $path/getdata/endtime plain spy text
}
#--------------------------------------------------
proc makestdscan {path} {
hfactory $path command hdbscan
hsetprop $path type command
hsetprop $path viewer mountaingumui.ScanEditor
hsetprop $path priv user
hfactory $path/scan_variables plain user text
hsetprop $path/scan_variables argtype drivable
hfactory $path/scan_start plain user text
hfactory $path/scan_increments plain user text
hfactory $path/NP plain user int
hfactory $path/mode plain user text
hsetprop $path/mode values "monitor,timer"
hfactory $path/preset plain user float
}
#---------------------------------------------------
proc makestdscangraphics {path} {
global stdscangraph
set stdscangraph $path
hfactory $path plain spy none
hsetprop $path type graphdata
hsetprop $path viewer default
hattach $path title title
hfactory $path/rank plain mugger int
hset $path/rank 1
hsetprop $path/rank priv internal
hfactory $path/dim script "xxxscan np" hdbReadOnly intar 1
hsetprop $path/dim priv internal
hfactory $path/scan_variable script "gethdbscanvardata 0" hdbReadOnly floatvarar 1
hsetprop $path/scan_variable type axis
hsetprop $path/scan_variable dim 0
hsetprop $path/scan_variable transfer zip
hsetprop $path/scan_variable priv internal
hfactory $path/scan_variable/name plain user text
hfactory $path/counts script "gethdbscancounts" hdbReadOnly intvarar 1
hsetprop $path/counts type data
hsetprop $path/counts transfer zip
hsetprop $path/counts priv internal
}
#----------------------------------------------------
proc makeQuickPar {name path} {
hfactory /quickview/$name plain mugger text
hset /quickview/$name $path
}
#---------------------------------------------------
proc makestdbatch {} {
hfactory /batch plain spy none
hfactory /batch/bufferlist script listbatchfiles hdbReadOnly text
sicspoll add /batch/bufferlist hdb 30
hfactory /batch/commandtext plain spy text
hsetprop /batch/commandtext viewer mountaingumui.TextEdit
hsetprop /batch/commandtext commandtext true
hfactory /batch/currentline plain user int
}
#-----------------------------------------------------
proc makeslit {path left right upper bottom} {
hfactory $path plain spy none
hsetprop $path type part
if {![string equal $left NONE]} {
hattach $path $left left
}
if {![string equal $right NONE]} {
hattach $path $right right
}
if {![string equal $upper NONE]} {
hattach $path $upper upper
}
if {![string equal $bottom NONE]} {
hattach $path $bottom bottom
}
}
#---------------------------------------------------------
proc makestdadmin {} {
hfactory /instrument/experiment plain spy none
hattach /instrument/experiment title title
hattach /instrument/experiment user user
set status [catch {hattach /instrument/experiment/user adress address} msg]
if {$status != 0} {
set status [catch {hattach /instrument/experiment/user address address} msg]
}
hattach /instrument/experiment/user phone phone
hattach /instrument/experiment/user email email
hfactory /instrument/experiment/datafilenumber script sicsdatanumber \
hdbReadOnly int
hsetprop /instrument/experiment/datafilenumber priv internal
hfactory /instrument/experiment/batchpath script "exe batchpath" \
hdbbatchpath text
hsetprop /instrument/experiment/batchpath priv user
sicspoll add /instrument/experiment/batchpath hdb 60
sicspoll add /instrument/experiment/datafilenumber hdb 60
}
#----------------------------------------------------------
proc makecount {path} {
hfactory $path command count
hsetprop $path type command
hsetprop $path priv user
hfactory $path/mode plain user text
hsetprop $path/mode values "monitor,timer"
hfactory $path/preset plain user float
hset $path/preset 60000
hset $path/mode monitor
}
#----------------------------------------------------------
proc makerepeat {path} {
hfactory $path command repeat
hsetprop $path type command
hsetprop $path priv user
hfactory $path/num plain user int
hfactory $path/mode plain user text
hsetprop $path/mode values "monitor,timer"
hfactory $path/preset plain user float
hset $path/preset 60000
hset $path/mode monitor
}
#----------------------------------------------------------
proc makekillfile {path} {
hcommand $path killfile
hsetprop $path type command
hsetprop $path priv manager
}
#----------------------------------------------------------
proc makesuccess {path} {
hcommand $path success
hsetprop $path type command
hsetprop $path priv user
}
#-----------------------------------------------------------
proc makestdgui {} {
hfactory /gui plain spy none
hfactory /gui/status plain internal text
status hdbinterest /gui/status
}
#------------------------------------------------------------
proc makewait {path} {
hfactory $path command wait
hsetprop $path type command
hsetprop $path priv user
hfactory $path/time plain user int
}
#------------------------------------------------------------
proc makeevproxy {rootpath hdbname devicename} {
MakeProxy p${devicename} $devicename float
p${devicename} map upperlimit upperlimit float user
p${devicename} map lowerlimit lowerlimit float user
hlink $rootpath p${devicename} $hdbname
hsetprop $rootpath/$hdbname sicsdev $devicename
hsetprop $rootpath/$hdbname type drivable
sicspoll add $rootpath/$hdbname hdb 30
}
#================== multi motor stuff =======================
proc getNamposList {mumo} {
set txt [$mumo list]
set l [split $txt "\n"]
set lala [llength $l]
for {set i 1} {$i < [llength $l]} {incr i} {
set pos [lindex $l $i]
if {[string length $pos] > 1} {
append result [lindex $l $i] ","
}
}
if { ![info exists result] } {
# clientput "nampos = $txt"
append result UNKNOWN
}
return [string trimright $result ","]
}
#------------------------------------------------------------
proc getNamPos {mumo} {
set txt [$mumo find]
set l [split $txt =]
return [string trim [lindex $l 1]]
}
#-----------------------------------------------------------
proc updateNamePosValues {rootpath} {
hupdate $rootpath/namedposition/values
hupdate $rootpath/dropnamedposition/name/values
}
#------------------------------------------------------------
proc makemumopos {mumo rootpath name} {
$mumo pos $name
updateNamePosValues $rootpath
}
#-----------------------------------------------------------
proc dropmumo {mumo rootpath name} {
$mumo drop $name
updateNamePosValues $rootpath
}
#------------------------------------------------------------
proc getDropList {mumo} {
set txt [getNamposList $mumo]
append txt ",all"
return $txt
}
#-------------------------------------------------------------
proc makemumo {rootpath mumoname} {
hfactory $rootpath/namedposition script "getNamPos $mumoname" \
$mumoname text
hsetprop $rootpath/namedposition priv user
hfactory $rootpath/namedposition/values script \
"getNamposList $mumoname" hdbReadOnly text
hsetprop $rootpath/namedposition/values visible false
hupdate $rootpath/namedposition/values
hfactory $rootpath/assignname2current command \
"makemumopos $mumoname $rootpath"
hsetprop $rootpath/assignname2current priv user
hsetprop $rootpath/assignname2current type command
hfactory $rootpath/assignname2current/name plain user text
hset $rootpath/assignname2current/name "Undefined"
hfactory $rootpath/dropnamedposition command \
"dropmumo $mumoname $rootpath"
hsetprop $rootpath/dropnamedposition priv user
hsetprop $rootpath/dropnamedposition type command
hfactory $rootpath/dropnamedposition/name plain user text
hfactory $rootpath/dropnamedposition/name/values script \
"getDropList $mumoname" hdbReadOnly text
hsetprop $rootpath/dropnamedposition/name/values visible false
hupdate $rootpath/dropnamedposition/name/values
}
#-----------------------------------------------------------------
proc hdbbatchpath {pathstring} {
exe batchpath $pathstring
catch {batchroot $pathstring}
catch {hupdate /instrument/commands/batch/execute/file/values}
catch {hupdate /instrument/commands/batch/batchpath}
catch {hupdate /instrument/experiment/batchpath}
catch {hupdate /batch/bufferlist}
}
#------------------------------------------------------------------
proc makeexe {} {
set path /instrument/commands/batch
hfactory $path plain spy none
hfactory $path/batchpath script "exe batchpath" hdbbatchpath text
hsetprop $path/batchpath priv user
hfactory $path/execute command exe
hsetprop $path/execute type command
hsetprop $path/execute priv user
hfactory $path/execute/file plain user text
hfactory $path/execute/file/values script listbatchfiles hdbReadOnly text
sicspoll add $path/execute/file/values hdb 60
}
#------------------------------------------------------------------
proc confnxhdb {path alias pass} {
hsetprop $path nxalias $alias
hsetprop $path nxpass $pass
}
#----------------------------------------------------------------------
proc hdbstorenexus args {
if {[llength $args] < 2} {
error "hdbstorenexus called with insufficient number of arguments"
}
set path [lindex $args 0]
set pass [lindex $args 1]
set childlist [split [hlist $path] \n]
foreach child $childlist {
if {[string length $child] < 1} {
continue
}
set status [catch {hgetpropval $path/$child nxpass} passval]
if {$status == 0} {
set status [catch {hgetpropval $path/$child nxslab} slabval]
# ------- slabbed writing
if {$status == 0 && [string first $pass $passval] >= 0} {
set slabsizes [eval $slabval [lrange $args 2 end]]
nxscript puthdbslab $path/$child [lindex $slabsizes 0] [lindex $slabsizes 1]
}
#--------- normal writing
if {[string first $pass $passval] >= 0} {
nxscript puthdb $path/$child
}
}
eval hdbstorenexus $path/$child $pass [lrange $args 2 end]
}
}
#===================== Syntactical sugar around hdbscan ===================
# 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 1997
#
# Reworked for hdbscan, Mark Koennecke, November 2008
#-----------------------------------------------------------------------------
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
}
set mode [string trim [SplitReply [scan mode]]]
#-------- store command in lastscancommand
set txt [format "cscan %s %s %s %s %s" $var $center \
$delta $np $preset]
catch {lastscancommand $txt}
#--------- calculate start and do scan
set start [expr $center - $np * $delta]
set ret [catch {hdbscan $var $start $delta [expr ($np * 2) + 1] $mode $preset} msg]
if { $ret != 0} {
error $msg
} else {
return $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
}
#--------- 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
append scanvars $var ","
append scanstarts $start ","
set step [expr double($end - $start)/double($np-1)]
append scansteps $step ","
}
#------------- set lastcommand text
set txt [format "sscan %s" [join $args]]
catch {lastscancommand $txt}
#------------- start scan
set scanvars [string trim $scanvars ,]
set scanstarts [string trim $scanstarts ,]
set scansteps [string trim $scansteps ,]
set mode [string trim [SplitReply [scan mode]]]
set ret [catch {hdbscan $scanvars $scanstarts $scansteps $np $mode $preset} msg]
if {$ret != 0} {
error $msg
} else {
return $msg
}
}
#------------------------------------------------------------------------------
proc splitScanVar {txt} {
set l1 [split $txt =]
set var [lindex $l1 0]
set vl [split $var .]
lappend result [lindex $vl 1]
lappend result [string trim [lindex $l1 1]]
lappend result [string trim [lindex $l1 2]]
}
#-----------------------------------------------------------------------------
proc scaninfo {} {
set novar [string trim [SplitReply [xxxscan noscanvar]]]
if {$novar == 0} {
return "0,1,NONE,0.,0.,default.dat"
}
append result "scaninfo = "
append result [string trim [SplitReply [xxxscan np]]] "," $novar
for {set i 0} {$i < $novar} {incr i} {
set vl [splitScanVar [xxxscan getvarpar $i]]
append result ", " [lindex $vl 0]
}
set vl [splitScanVar [xxxscan getvarpar 0]]
append result "," [lindex $vl 1]
append result "," [lindex $vl 2]
append result "," [SplitReply [xxxscan getfile]]
append result "," [SplitReply [sample]]
append result "," [sicstime]
append result "," [SplitReply [lastscancommand]]
return $result
}
#-------------------------------------------------------------
proc scan args {
if {[llength $args] < 1} {
error "Need keyword for scan"
}
set key [string trim [lindex $args 0]]
switch $key {
uuinterest { return [xxxscan uuinterest] }
pinterest {}
getcounts { set cts [SplitReply [xxxscan getcounts]]
return "scan.Counts = $cts"
}
mode {
if {[llength $args] > 1} {
return [counter setmode [lindex $args 1]]
} else {
return [counter getmode]
}
}
clear {
return [xxxscan clear]
}
default {
error "scan does not support keyword $key"
}
}
}