Initial scratch file support

Added support for aliasing data.

r2117 | ffr | 2007-08-16 15:11:07 +1000 (Thu, 16 Aug 2007) | 3 lines
This commit is contained in:
Ferdi Franceschini
2007-08-16 15:11:07 +10:00
committed by Douglas Clowes
parent a8d5cff322
commit 01890b5cff

View File

@@ -3,42 +3,76 @@ MakeNXScript
sicsdatafactory new nxscript_data sicsdatafactory new nxscript_data
namespace eval nexus { namespace eval nexus {
variable nxdictionary variable nxdictionary
variable state
set exports [list newfile closefile save data] set exports [list newfile closefile save data]
eval namespace export $exports eval namespace export $exports
datafilename datafilename
proc init {} {
variable state
variable nexusdic
array set state {file,new "true" file,open "false" file,type "data" file,format "hdf"}
set nexusdic "nexus.dic"
}
## \brief Create a nexus file
#
# \param filetype optional, (data,scratch) default=data
#
# Depends on ::nexus variable nexusdic and sics variable SicsDataPostFix
# preconditions:
# state(file,open) false state(file,new) true
# postconditions:
# state(file,open) true state(file,new) false
# /data/currentfiletype == /data/datatype
proc createfile {} { proc createfile {} {
global cfPath global cfPath
variable nexusdic variable nexusdic
variable state variable state
variable nxFileOpen; variable nxFileOpen;
if {$state(file,open) == "true"} {
error_msg "Can't create a new file because the current file is still open"
} elseif {$state(file,new) == "false"} {
error_msg "This function should only be called when state(file,new) = true"
}
set nxdict_path $cfPath(nexus)/$nexusdic set nxdict_path $cfPath(nexus)/$nexusdic
set file_type [SplitReply [SicsDataSuffix]] set file_format [SplitReply [SicsDataPostFix]]
array set nxmode [list nx.hdf create5 hdf create5 h5 create5 nx5 create5 xml createxml]; array set nxmode [list nx.hdf create5 hdf create5 h5 create5 nx5 create5 xml createxml];
dataFileName [newFileName $file_type]
::nexus::gen_nxdict $nexusdic ::nexus::gen_nxdict $nexusdic
nxscript $nxmode($file_type) [SplitReply [dataFileName]] $nxdict_path; if {$state(file,type) == "scratch"} {
dataFileName [format "scratch.%s" $file_format]
} else {
sicsdatanumber incr;
dataFileName [newFileName $file_format]
}
hsetprop /data currentfiletype [::utility::hgetplainprop /data datatype]
nxscript $nxmode($file_format) [SplitReply [dataFileName]] $nxdict_path;
set nxFileOpen true set nxFileOpen true
set state(file,status) open set state(file,open) false
set state(file,new) false
} }
## \brief Sets 'new file' state to true ## \brief Setup file state info for writing a new file.
proc newfile {{type deflt } {nxdic nexus.dic}} { #
variable nexusdic # \param type
#
# postconditions:
# state(file,open) true state(file,new) false
# /data/currentfiletype == UNKNOWN
proc newfile {{type data}} {
variable state variable state
if {$type == "deflt"} {
set type [SplitReply [SicsDataSuffix]] set state(file,type) $type
}
set state(file,new) true set state(file,new) true
set nexusdic $nxdic hsetprop /data currentfiletype UNKNOWN
} }
# Don't overwrite data from a previous SICS session
newfile
proc save_data {point} { proc save_data {point} {
debug_msg "save point $point in [dataFileName]"
::nexus::nxreopenfile ::nexus::nxreopenfile
foreach child [hlist /] { foreach child [hlist /] {
if {[::utility::hgetplainprop /experiment data] == "true"} { if {[::utility::hgetplainprop /$child data] == "true"} {
::nexus::savetree $child $point ::nexus::savetree $child $point
} }
} }
@@ -48,49 +82,77 @@ namespace eval nexus {
# #
# \param point experimental point number, this is the array index for mutable # \param point experimental point number, this is the array index for mutable
# datasets in the nexus file. Optional, default = 0 # datasets in the nexus file. Optional, default = 0
# \param filetype optional, (data,scratch) default=data
# #
# If filetype == scratch then it will create a file called scratch.{xml|hdf}
# The save command will create a new file if the newfile state is set to true, or # The save command will create a new file if the newfile state is set to true, or
# if the datatype property != the currentfiletype property of the /data hdb node. # if the datatype property != the currentfiletype property of the /data hdb node.
proc save {{point 0}} { # arg0 '' n scratch data xml hdf
# arg1 '' scratch data xml hdf
# arg2 '' xml hdf
proc save {args} {
variable state variable state
::data::gumtree_save -set run_number $point if {$args == ""} {
if {$state(file,new) == "true"} { set point 0
createfile
save_data $point
linkdata
hsetprop /data currentfiletype [::utility::hgetplainprop /data datatype]
set state(file,new) false
} else { } else {
if {[::utility::hgetplainprop /data currentfiletype] != [::utility::hgetplainprop /data datatype]} { set point [lindex $args 0]
createfile
save_data $point
linkdata
hsetprop /data currentfiletype [::utility::hgetplainprop /data datatype]
set state(file,new) false
}
save_data $point
} }
if {[string is integer $point] == 0} {
error_msg "save index must be an integer"
} elseif {$point < 0} {
error_msg "save index cannot be negative"
} }
## \brief Reopen the current file. ::data::gumtree_save -set run_number $point
set isNewFile [expr {$state(file,new) == "true"}]
set currFileType [::utility::hgetplainprop /data currentfiletype]
set currDataType [::utility::hgetplainprop /data datatype]
set dataTypeChanged [expr {$currFileType != $currDataType}]
if {$isNewFile || $dataTypeChanged} {
set state(file,new) true
::nexus::createfile
::nexus::save_data $point
::nexus::linkdata
} else {
::nexus::save_data $point
}
return
}
## \brief Reopen the current file, close it with nxclosefile
#
# preconditions:
# none
# postconditions:
# state(file,open) == true
# \see nxclosefile
proc nxreopenfile {} { proc nxreopenfile {} {
global cfPath global cfPath
variable state
variable nxFileOpen variable nxFileOpen
variable nexusdic variable nexusdic
if {$nxFileOpen == "false"} { if {$state(file,open) == "false"} {
nxscript reopen [SplitReply [dataFileName]] $cfPath(nexus)/$nexusdic; nxscript reopen [SplitReply [dataFileName]] $cfPath(nexus)/$nexusdic
set nxFileOpen true; set state(file,open) true
} }
} }
## \brief Close the current file. You can reopen it with nxreopenfile ## \brief Close the current file. You can reopen it with nxreopenfile
# #
# preconditions
# none
# postconditions
# state(file,open) == false
# \see nxreopenfile # \see nxreopenfile
proc nxclosefile {} { proc nxclosefile {} {
variable state
variable nxFileOpen; variable nxFileOpen;
if {$nxFileOpen == "true"} { if {$state(file,open) == "true"} {
nxscript close; nxscript close;
set nxFileOpen false; set state(file,open) false;
set flist [split [SplitReply [dataFileName]] "/"]; set flist [split [SplitReply [dataFileName]] "/"];
set fname [lindex $flist [expr [llength $flist] - 1] ]; set fname [lindex $flist [expr [llength $flist] - 1] ];
clientput "$fname updated" "event"; clientput "$fname updated" "event";
@@ -110,40 +172,73 @@ proc nxclosefile {} {
# Records that /data/axisn should be linked to datsource # Records that /data/axisn should be linked to datsource
# data clear # data clear
# Clears all link targets and sets the data type identifier to unknown # Clears all link targets and sets the data type identifier to unknown
# data alias <name>, remove alias <name>
# data alias <name> <target>, set <name> as an alias for <target> unless it has already been defined.
proc data {args} { proc data {args} {
variable state
set dpath /data set dpath /data
set opt [lindex $args 0] set opt [lindex $args 0]
set arglist [lrange $args 1 end]
switch $opt { switch $opt {
"axis" { "axis" {
debug_msg "'axis' case of switch"
set axnum [lindex $args 1] set axnum [lindex $args 1]
if {[string is integer $axnum] == 0} { if {[string is integer $axnum] == 0} {
error "ERROR: [info level -1]->data, index for data axis should be an integer, not $axnum" error "ERROR: [info level -1]->data, index for data axis should be an integer, not $axnum"
} }
set hp $dpath/axis_$axnum set hp $dpath/axis_$axnum
if {[::utility::hgetplainprop $hp link] == "@none"} { if {[::utility::hgetplainprop $hp link] == "@none"} {
hsetprop $hp link [lindex $args 2] hsetprop $hp link [getatt [lindex $args 2] id]
hsetprop $hp long_name [getatt [lindex $args 2] long_name] hsetprop $hp long_name [getatt [lindex $args 2] long_name]
} }
} }
"data_set" { "data_set" {
debug_msg "'data_set' case of switch"
hsetprop $dpath datatype [lindex [info level -1] 0] hsetprop $dpath datatype [lindex [info level -1] 0]
set hp $dpath/data_set set hp $dpath/data_set
if {[::utility::hgetplainprop $hp link] == "@none"} { if {[::utility::hgetplainprop $hp link] == "@none"} {
hsetprop $hp link [lindex $args 1] hsetprop $hp link [getatt [lindex $args 1] id]
hsetprop $hp long_name [getatt [lindex $args 1] long_name] hsetprop $hp long_name [getatt [lindex $args 1] long_name]
} }
} }
"clear" { "clear" {
debug_msg "'clear' case of switch"
foreach child [hlist $dpath] { foreach child [hlist $dpath] {
hsetprop $dpath/$child link @none hsetprop $dpath/$child link @none
hsetprop $dpath/$child long_name @none hsetprop $dpath/$child long_name @none
} }
} }
"alias" {
debug_msg "'alias' case of switch"
set alias_name [lindex $arglist 0]
set alias_target [lindex $arglist 1]
switch $alias_target {
"" {
if {[info exists state(data,alias,$alias_name)]} {
definealias $alias_name
set state(data,alias,$alias_name) @none
}
}
default {
if {[info exists state(data,alias,$alias_name)]} {
if { $state(data,alias,$alias_name) == "@none" } {
definealias $alias_name $alias_target
}
} else {
definealias $alias_name $alias_target
}
return
}
}
}
default {error "ERROR: [info level -1]->data, Unsupported option $opt"} default {error "ERROR: [info level -1]->data, Unsupported option $opt"}
} }
} }
# Internal commands # Internal commands
# All experimental data of interest is linked under the data group # All experimental data of interest is linked under the data group
## \brief Links data and axis into /data group
proc linkdata {} { proc linkdata {} {
array unset axes array unset axes
set hpath /data set hpath /data
@@ -174,8 +269,9 @@ proc data {args} {
} }
if {[info exists axes]} { if {[info exists axes]} {
foreach n [lsort [array names axes]] { foreach n [lsort [array names axes]] {
nxscript putattribute $data_set_alias axes [set axes($n)] lappend axes_list $axes($n)
} }
nxscript putattribute $data_set_alias axes [join $axes_list :]
} }
::nexus::nxclosefile ::nexus::nxclosefile
::nexus::data clear ::nexus::data clear
@@ -280,7 +376,6 @@ proc data {args} {
sicslist setatt nxscript_data privilege internal; sicslist setatt nxscript_data privilege internal;
# nexus macros # nexus macros
sicslist setatt nxcreatefile privilege internal;
sicslist setatt addnxscanentry privilege internal; sicslist setatt addnxscanentry privilege internal;
sicslist setatt bm_addnxscanentry privilege internal; sicslist setatt bm_addnxscanentry privilege internal;
@@ -305,6 +400,10 @@ proc data {args} {
sicslist setatt $sobj savecmd ::nexus::singlecounter::save sicslist setatt $sobj savecmd ::nexus::singlecounter::save
sicslist setatt $sobj sdsinfo ::nexus::singlecounter::sdsinfo sicslist setatt $sobj sdsinfo ::nexus::singlecounter::sdsinfo
} }
foreach sobj [sicslist kind script] {
sicslist setatt $sobj savecmd ::nexus::script::save
sicslist setatt $sobj sdsinfo ::nexus::script::sdsinfo
}
} }
} }
namespace import ::nexus::* namespace import ::nexus::*
@@ -376,7 +475,11 @@ namespace eval ::nexus {
proc hdb2nx_type {dtype} { proc hdb2nx_type {dtype} {
switch $dtype { switch $dtype {
int {return NX_INT32} int {return NX_INT32}
intar {return NX_INT32}
intvarar {return NX_INT32}
float {return NX_FLOAT32} float {return NX_FLOAT32}
floatar {return NX_FLOAT32}
floatvarar {return NX_FLOAT32}
text {return NX_CHAR} text {return NX_CHAR}
default {error "ERROR: [info level -1]->hdb2nx_type, Unknown type $dtype"} default {error "ERROR: [info level -1]->hdb2nx_type, Unknown type $dtype"}
} }
@@ -385,6 +488,7 @@ namespace eval ::nexus {
namespace eval ::nexus::sicsvariable { namespace eval ::nexus::sicsvariable {
proc save {svar nxalias data_type args} { proc save {svar nxalias data_type args} {
array set attribute [attlist $svar]
set val [SplitReply [$svar]] set val [SplitReply [$svar]]
if {[lindex $args 0] == "point"} { if {[lindex $args 0] == "point"} {
set index [lindex $args 1] set index [lindex $args 1]
@@ -403,6 +507,9 @@ namespace eval ::nexus::sicsvariable {
default {error "ERROR: [info level -1]->::nexus::sicsvariable::save, unknown type $data_type"} default {error "ERROR: [info level -1]->::nexus::sicsvariable::save, unknown type $data_type"}
} }
} }
if {[info exists attribute(units)]} {
nxscript putattribute $nxalias units $attribute(units)
}
} }
proc sdsinfo {svar data_type args} { proc sdsinfo {svar data_type args} {
array set param $args array set param $args
@@ -422,6 +529,34 @@ namespace eval ::nexus::singlecounter {
todo_msg "Get sdsinfo for counter: $counter" todo_msg "Get sdsinfo for counter: $counter"
} }
} }
namespace eval ::nexus::script {
##\brief Save command for hdb nodes associated with a tcl macro
#
# The macro must return a 1D associative array when called with -arrayname.
proc save {script nxalias data_type args} {
array set attribute [attlist $script]
set darray [$script -arrayname]
set size [array size $darray]
switch $data_type {
"intar" - "intvarar" {
nxscript putintarray $nxalias $darray $size
}
"floatar" - "floatvarar" {
nxscript putarray $nxalias $darray $size
}
}
if {[info exists attribute(units)]} {
nxscript putattribute $nxalias units $attribute(units)
}
}
proc sdsinfo {script data_type args} {
set dtype [::nexus::hdb2nx_type $data_type]
set darray [$script -arrayname]
set size [array size $darray]
return " -type $dtype -rank 1 -dim {$size}"
}
}
# TODO Return filename from nxcreatefile and call nxreopen nxclose etc # TODO Return filename from nxcreatefile and call nxreopen nxclose etc
# TODO Make an nxscript namespace for all this. # TODO Make an nxscript namespace for all this.
@@ -433,7 +568,7 @@ namespace eval ::nexus::singlecounter {
set tmpstr [string map {"$" ""} {$Name: not supported by cvs2svn $}] set tmpstr [string map {"$" ""} {$Name: not supported by cvs2svn $}]
set nx_content_release_tag [lindex $tmpstr [expr [llength $tmpstr] - 1]] set nx_content_release_tag [lindex $tmpstr [expr [llength $tmpstr] - 1]]
set tmpstr [string map {"$" ""} {$Revision: 1.25 $}] set tmpstr [string map {"$" ""} {$Revision: 1.26 $}]
set nx_content_revision_num [lindex $tmpstr [expr [llength $tmpstr] - 1]] set nx_content_revision_num [lindex $tmpstr [expr [llength $tmpstr] - 1]]
@@ -442,9 +577,8 @@ proc getVal {msg} {
} }
proc newFileName {postfix} { proc newFileName {postfix} {
array set inst_mnem {quokka QKK womba WBT echidna ECH kowari KWR koala KOL taipan TPN platypus PLP pelican PLN} array set inst_mnem {quokka QKK wombat WBT echidna ECH kowari KWR koala KOL taipan TPN platypus PLP pelican PLN}
# sicsdatanumber incr;
sicsdatanumber incr;
set idNum [SplitReply [sicsdatanumber]]; set idNum [SplitReply [sicsdatanumber]];
set dataPath [SplitReply [sicsdatapath]]; set dataPath [SplitReply [sicsdatapath]];
set prefix [SplitReply [sicsdataprefix]]; set prefix [SplitReply [sicsdataprefix]];
@@ -454,15 +588,6 @@ array set inst_mnem {quokka QKK womba WBT echidna ECH kowari KWR koala KOL taipa
return [format "%s/%s%07d.%s" $dataPath $inst_mnem([instname]) $idNum $postfix] return [format "%s/%s%07d.%s" $dataPath $inst_mnem([instname]) $idNum $postfix]
} }
proc nxcreatefile {nxdic {type nx.hdf}} {
global nxFileOpen cfPath nexusdic;
set nexusdic $nxdic
array set nxmode [list nx.hdf create5 h5 create5 nx5 create5 xml createxml];
dataFileName [newFileName $type]
nxscript $nxmode($type) [SplitReply [dataFileName]] $cfPath(nexus)/$nexusdic;
set nxFileOpen true
}
set dradius 1.25 set dradius 1.25
@@ -702,19 +827,18 @@ proc putslitmotors {nxobj point} {
namespace eval data { namespace eval data {
command gumtree_save {int: run_number} { command gumtree_save {int: run_number} {
save $run_number ::nexus::save $run_number
} }
sicslist setatt ::data::gumtree_save long_name save sicslist setatt ::data::gumtree_save long_name save
array set param [::data::gumtree_save -list param] array set param [::data::gumtree_save -list param]
::utility::mkData $param(run_number) run_number instrument privilege READ_ONLY mutable true control false ::utility::mkData $param(run_number) run_number instrument privilege READ_ONLY mutable true control false
command gumtree_type {text:nx.hdf,xml type} { command gumtree_type {text:nx.hdf,xml type} {
SicsDataSuffix $type SicsDataPostFix $type
} }
sicslist set ::data::gumtree_type long_name file_type sicslist set ::data::gumtree_type long_name file_format
::data::gumtree_type -set type [SplitReply [SicsDataSuffix]] ::data::gumtree_type -set type [SplitReply [SicsDataPostFix]]
} }
Publish nxcreatefile user
Publish addnxscanentry user Publish addnxscanentry user
Publish bm_addnxscanentry user Publish bm_addnxscanentry user
::nexus::init