tclSDDS TCL/TK Extension

Original author - Claude Saunders
Updated by - Robert Soliday

Table of Contents


Operations Analysis Group
Accelerator Systems Division
Argonne National Laboratory
May. 12, 1999

1. Introduction

This document serves as a User's Manual and Reference for the tclSDDS extension for tcl/tk. This extension provides commands to a tcl/tk interpreter which permit reading and writing SDDS files. All of the standard SDDS data types are supported, and all of the data models (parameter, array, column).

All tclSDDS commands begin with "sdds", and are followed by a space and then the desired sub-command. All commands return catchable errors. You can get a usage statement for every command by typing "sdds <sub-command>".

2. Sample Application

The examples in the following sections omit the use of the catch statement for brevity; however, it should always be used, as any and all of the commands return catchable errors. Here is an example of how a catch statement should be used.

# Example
if [catch {sdds open foo.sdds r} result] {
  puts stderr "unable to open foo.sdds: $result"
  exit
} else {
  set fileDescriptor $result
}

2.1. Reading

Assume a file called foo.sdds exists with parameter p1, 2-d array a1, and column c1. There are 2 data pages.

set fd [sdds open foo.sdds r]
# You can retrieve the list of column, parameter, and array names in a file
sdds getNames $fd column
sdds getNames $fd parameter
sdds getNames $fd array
# You can retrieve meta data about any given column, parameter, or array.
# These commands set a tcl array, with one element for each piece of information.
sdds getColumnInformation $fd c1 c1Info
puts "$c1Info(name) $c1Info(units) $c1Info(description) etc.."
# The command parray will print out all the contents of an array
parray c1Info
# The commands for parameter and array are identical
sdds getParameterInformation $fd p1 p1Info
sdds getArrayInformation $fd a1 a1Info
# This returns a list of two parameters, one from each page
set parameterList [sdds getParameter $fd p1]
# This returns a single list of all pages of column data concatenated together
set colData [sdds getColumn $fd c1]
# Alternately, you may cycle through the pages manually until EOF is returned
set moreData 1
set n 1
while {$moreData} {
  if [catch {sdds getColumn $fd c1 -page $n} res] {
    if {![string compare $res EOF]} {
      set moreData 0
    } else {
      puts stderr "error: $res"
      exit
    }
  } else {
    puts "page $n data: $res"
  }
  incr n
}
# Arrays must be retrieved one page at a time. The getArray command does not 
# return the data, but rather sets an array variable in your current scope.
sdds getArray $fd tclArrayName a1 -page 1
parray tclArrayName
# Don't forget to close the file
sdds close $fd

2.2. Writing

Writing SDDS files from tcl/tk closely models the actual SDDS C functions.

# You can also do "sdds open new.sdds w SDDS_BINARY"
set fd [sdds open new.sdds w]
# Define all parameters, columns, and arrays
sdds defineParameter $fd par1 -type SDDS_STRING -fixedValue "any thing"
sdds defineParameter $fd par2 -type SDDS_DOUBLE -description "par" -units Amps
sdds defineColumn $fd col1 -type SDDS_LONG
sdds defineArray $fd sddsArray1 -type SDDS_DOUBLE -dimensions 2
# Write the header out
sdds writeLayout $fd
# Start a data page with 200 row max
sdds startPage $fd 200
# Set the page data
sdds setParameter $fd par2 123.234
sdds setColumn $fd col1 23 43 55 22 0 23 83 220 4401 32
# To set an array, first define the tcl array (a 2x3 array in this case)
set tclArr(0,0) 23.3
set tclArr(0,1) 44.3
set tclArr(0,2) 1.0032
set tclArr(1,0) 2.0093
set tclArr(1,1) 483.0
set tclArr(1,2) 9
# Set the array, giving the range of each dimension as arguments
sdds setArray $fd tclArr sddsArray1 2 3
# Write the data page out
sdds writePage $fd
# Can start additional data pages if desired
sdds startPage $fd 200
...
sdds writePage $fd
# Make sure to close the file
sdds close $fd

3. Another Sample Application

The first example demonstrates how to load an SDDS file into a tcl array. The second example demonstrates how to save an SDDS file using a specially formatted tcl array.

3.1 Loading

# Example on how to load an sdds file into a tcl array.
if [catch {sdds load foo.sdds bar} result] {
  puts stderr "unable to load foo.sdds: $result"
  exit
} else {
  # Printing out all parameter data
  foreach name $bar(ParameterNames) {
    set page 1
    foreach data $bar(Parameter.$name) {
      puts "page $page, $name = $data"
      incr page
    }
  }
  # Printing out all array data
  foreach name $bar(ArrayNames) {
    set page 1
    foreach data $bar(Array.$name) {
      array set temp $data
      foreach index [array names temp] {
        puts "page $page, $name\($index\) = $temp($index)"
      }
      incr page
    }
  }
  # Printing out all column data
  foreach name $bar(ColumnNames) {
    set page 1
    foreach data $bar(Column.$name) {
      set row 1
      foreach item $data {
        puts "page $page, row $row, $name = $item"
        incr row
      }
      incr page
    }
  }
}

3.2 Saving

# Example on how to save a two page sdds file using a predefined tcl array.
# Defining description
set bar(Description.Text) "Example file"
set bar(Description.Contents) "Random data"
# Defining parameters
set bar(ParameterNames) "Time Date"
set bar(ParameterInfo.Time) "type SDDS_LONG"
set now [clock seconds]
set tomorrow [expr $now + 86400]
set bar(Parameter.Time) [list $now $tomorrow]
set bar(Parameter.Date) [list [clock format $now] [clock format $tomorrow]]
# Defining arrays
set bar(ArrayNames) "Direction"
set bar(ArrayInfo.Direction) "type SDDS_CHARACTER dimensions 2"
set bar(Array.Direction) [list "0,0 n 0,1 s 1,0 e 1,1 w" "0,0 N 0,1 S 1,0 E 1,1 W"]
# Defining columns
set bar(ColumnNames) "Days Colors"
set bar(Column.Days) [list "Sunday Monday Tuesday" "Wednesday Thursday Friday Saturday"]
set bar(Column.Colors) [list "Red Orange Yellow" "Green Blue Purple White"]
if [catch {sdds save foo.sdds bar} result] {
  puts stderr "unable to save foo.sdds: $result"
  exit
}

4. Command Reference

sdds open

sdds open <fileName> [<mode>] [SDDS_BINARY]

Open an sdds file for read or write. Opening for write will replace any existing file contents. The SDDS_BINARY option is available when writing a file.

Returns:

sdds close

sdds close <fd>

Closes sdds file and frees up resources.

sdds getColumn

sdds getColumn <fd> <columnName> [-page <n>]

Read given column from file and return as a list with one element per row. If -page is omitted or 0, all pages are read and columns are concatenated. Pages start at number 1. You may proceed to read pages one at a time until a catchable error with return string "EOF" is returned.

Returns:

sdds getParameter

sdds getParameter <fd> <parameterName> [-page <n>]

Read given parameter and return its value in a list. If -page is omitted or 0, all pages are read and values concatenated. "EOF" indicates all pages have been read.

Returns:

sdds getArray

sdds getArray <fd> <tclArrayName> <sddsArrayName> -page <n>

Read array from sdds file and create a tcl array with same dimensions. Nothing is returned other than a catchable status.

sdds getColumnInformation

sdds getColumnInformation <fd> <columnName> <tclArrayName>

Get all information associated with a column and put it in the given tcl array, e.g., array(units), array(symbol), array(type).

sdds getParameterInformation

sdds getParameterInformation <fd> <parameterName> <tclArrayName>

Get all information associated with a parameter; stored in the given tcl array.

sdds getArrayInformation

sdds getArrayInformation <fd> <arrayName> <tclArrayName>

Get all information associated with an array; stored in the given tcl array.

sdds getNames

sdds getNames <fd> [<class>]

Find out what columns, parameters, or arrays are defined in an open file.

Returns:

sdds defineParameter

sdds defineParameter <fd> <parameterName> [-type <string>] [-symbol <string>] [-units <string>] [-description <string>] [-formatString <string>] [-fixedValue <string>]

For writing files. Defines a new parameter. Defaults to type SDDS_STRING.

sdds defineColumn

sdds defineColumn <fd> <columnName> [-type <string>] [-symbol <string>] [-units <string>] [-description <string>] [-formatString <string>] [-fieldLength <string>]

For writing files. Defines a new column. Defaults to type SDDS_STRING.

sdds defineArray

sdds defineArray <fd> <arrayName> [-type <string>] [-symbol <string>] [-units <string>] [-description <string>] [-formatString <string>] [-fieldLength <int>] [-dimensions <int>] [-groupName <string>]

For writing files. Defines a new array. Defaults to type SDDS_STRING.

sdds writeLayout

sdds writeLayout <fd>

Writes SDDS header out after all defines are complete. Must precede sdds startPage.

sdds startPage

sdds startPage <fd> <expectedRows>

Begins a new SDDS data page. User supplies a maximum expected row count. Must precede any sdds set* commands.

sdds setParameter

sdds setParameter <fd> <parameterName> <parameterValue>

Sets a parameter in the current data page. The value must convert to the native SDDS type defined for the parameter.

sdds setColumn

sdds setColumn <fd> <columnName> <columnValue> [columnValue ...]

Sets a column in the current data page. Values must convert to the column's native SDDS type.

sdds setRowValues

sdds setRowValues <fd> <rowNumber> <columnName> <columnValue> [<columnName> <columnValue> ...]

Sets values for a specific row in the current page.

sdds setArray

sdds setArray <fd> <tclArrayName> <sddsArrayName> <dim0Range> ... <dimnRange>

Sets an SDDS array from a tcl array. The arity must match; only 1D, 2D, and 3D arrays are supported. Provide the range of each dimension (e.g., for a 2x3 array, supply 2 3).

sdds writePage

sdds writePage <fd>

Writes the current SDDS data page to file. To add more data, call sdds startPage again.


sdds load

sdds load <fileName> <tclArrayName>

Loads a file into a tcl array.

The created array contains (among others):

For each parameter name:

For each array name:

{{0,0 1.1 0,1 2.2 1,0 3.3 1,1 4.4} {0,0 1.1 0,1 2.2 0,2 3.3 0,3 4.4}}

For each column name:

Returns: nothing (other than catchable error)

sdds save

sdds save <fileName> <tclArrayName>

Saves a file from a tcl array.

The elements of <tclArrayName> mirror those created by sdds load (some are optional):

For each parameter name:

For each array name:

For each column name:

Returns: nothing (other than catchable error)


5. Linking Against the tclSDDS Library

The "sdds" command set is available as a tcl extension library called libtclSDDS.a. The library is located in the EPICS/extensions source tree:

epics/extensions/src/tcl/extensions/sdds

You must also link against the SDDS library which is in EPICS/extensions:

epics/extensions/src/SDDS

The xxAppInit.c file of your interpreter should include the following lines in order to initialize the tclSDDS extension:

if (TclSDDS_Init(interp) == TCL_ERROR) {
  return TCL_ERROR;
}

The link command for your interpreter must include this library along with several SDDS libraries:

-ltclSDDS -lSDDS1 -lrpnlib -lnamelist -lmdblib