Documentation:Beginners:Expressions - MdsWiki
Navigation
Personal tools

From MdsWiki

Jump to: navigation, search

Expressions - The TDI Language

All interfaces to MDSplus data are based on the evaluation of expressions. These expressions are written in a language called TDI (tree data interface) which supports a large number of functions and commands. TDI language has several hundred commands and programming constructs, fortunately, most users need only a handful of these. The simplest expressions are just node names and the evaluation returns the data in that node. Simple mathematical and logical operations are supported, along with string manipulation, simple programming instructions and commands to analyze or create specific MDSplus constructs. External routines written in other programming languages can be invoked, providing almost limitless flexibility. This capability has been widely used to provide access to legacy data through the MDSplus API.

Expressions are strings which can be evaluated by mdsvalue calls. To evaluate an expression you must be connected to an MDSplus server. If that expression calls for retrieving or storing information from a tree, you must first open that tree with mdsopen. The simplest and most common expressions used are just (fully qualified) node names. Evaluation of such an expression will return the data stored in the node. If the node contains a composite data type like a signal, the value portion of the data is returned. For example, using the magnetics tree above:

mdsvalue('\magnetics::top.processed.current_data:ip')  

or using the tag name

ip = mdsvalue('\ip')

will return an array containing the plasma current for the currently open shot. To get the time base for this data use the TDI function dim_of.

t = mdsvalue('dim_of(\ip)')

For signals with more than one dimension, dim_of takes an argument specifying which dimension is to be returned. For one dimensional arrays the argument is optional. Given a two dimension signal stored in a node \sig_name which is a function of space and time, these axes can be retrieved with:

x = mdsvalue('dim_of(\sig_name,0)')  
t = mdsvalue('dim_of(\sig_name,1)')

For many applications, this is all the knowledge of TDI that is needed. However, it is often convenient to use additional features.

Arithmetic Functions

mdsvalue('2+2') = 4
mdsvalue('2-2') = 0
mdsvalue('2*3') = 6
mdsvalue('6/2') = 3
mdsvalue('3^2') = 9

Thus calibration or normalization factors can be applied to data:

mdsvalue('\ip/1.e6')  converts Ip from Amps to MAmps

or

mdsvalue('\calib_factor_1*\sig_name+\calib_factor_2')

A number of basic mathematical functions are built into TDI as well, including trigonometric, logarithmic, exponential, modulo, complex conjugate, and absolute value functions. Sums and products of arrays are available along with minima, maxima, and means. Logical operations, string manipulation, bitwise operations and variable type conversions can also be carried out. (See TDI manual for complete list.)

a = mdsvalue('sin(\x)')
b = mdsvalue('sum(\y)')
c = mdsvalue('mean(\z)')
d = mdsvalue('abs(\w)')

Arrays of sequential integers or floats can be created:

mdsvalue('0:10') will yield [0,1,2,3,4,5,6,7,8,9,10]

String concatenation is useful for labeling plots in the SCOPE utility

mdsvalue('"abc" // "def"') = "abcdef"

TDI will attempt to reconcile mathematical operations with variables of different type or shape. Multiplying a scalar times a vector will return a vector. Adding an integer to a complex number returns a complex number. Specific details can be found in the TDI reference manual.

TDI Variables

For convenience and to improve performance, intermediate results can be cached in memory using TDI VARIABLES. These variables are global in scope - that is they are available to all modules of an application. TDI variables are also useful for writing multi-line expressions

TDI variables always begin with the underscore character for example: _x or _y.

ip = mdsvalue('_ip = \ip')
t = mdsvalue('dim_of(_ip)')

Note that commas are used to separate "lines" in TDI code. So that the example above could be written:

t = mdsvalue('_ip = \ip, dim_of(_ip)')

Where TDI returns the value of the last "line" in the expression.

"Constant" expressions

For convenience, a set of mathematical and physical constants are built into TDI. These are preceded by a $ sign for example

mdsvalue('$pi') = 3.14159
mdsvalue('$qe') = 1.60218e-19  (electron charge)

Information on the current MDSplus session is available with the same syntax. The currently open shot, tree and the default node can be retrieved as follows:

mdsopen,'magnetics',1234

then

mdsvalue('$shot') = 1234
mdsvalue('$expt') = magnetics
mdsvalue('$default') = \magnetics::top

Array Subscripting

Arrays of any type can be subscripted to obtain particular values or subarrays.

mdsvalue('_x = 10*(0:10)')
mdsvalue('_x[3]') = 30
mdsvalue('_x[3:6]') = [30, 40, 50, 60]

If the variable being subscripted is a signal, the subscripting is carried out not with indices but in terms of the independent variables. For example the signal \ip as defined in our tree example has an independent dimension time in units of seconds:

mdsvalue('\ip[1.2]')  yields the value of ip at 1.2 seconds

Note: subscripting on left side of equivalence statements is not allowed.

Passing Parameters to TDI Expressions

It is often necessary or useful to pass arguments from a program or procedure into a TDI expression. This is most commonly used when creating composite variable types as described in the next section. Parameters to be substituted are indicated by a "$" sign in the TDI expression. The arguments are passed to the mdsvalue call in the order that they appear in the expression.

b = 3
mdsvalue('_a = 0:4')
mdsvalue('_a*$',b) = [0, 3, 6, 9, 12]

The order in which external arguments are used can be defined explicitly by numbering the "$" signs. Consider the following examples

mdsvalue('$-$',2,1)     =  1
mdsvalue('$-$',1,2)     = -1
mdsvalue('$1-$2',2,1)   =  1
mdsvalue('$2-$1',2,1)   = -1

Creating Signals, Units

Composite variable types are built with TDI expressions. The most useful of these types are signals and data "with units" and are created with:

make_with_units(DATA,UNITS)
make_signal(DATA,RAW,[DIMENSION,...])

Where DATA is any expression including TDI variables. Often parameter substitution is used to pass arrays into these functions. UNITS is a character string containing the units label. RAW is an optional component of a signal and is generally used to store the "counts" from a piece of data acquisition hardware. A "*" symbol is used when this argument is not supplied.

A typical use of these commands would be:

.
code to define variables x which is a position measured in meters
and its independent variable t measured in seconds
.
.
mdsvalue('_x = make_with_units($,"meters")',x)
mdsvalue('_t = make_with_units($,"seconds")',t)
mdsvalue('_a = make_signal(_x,*,_t)')

Resulting in the signal _a.

Retrieving Components of Composite Datatypes

TDI functions exist which retrieve individual components of composite datatypes like signals. We've already been introduced to one of these dim_of which returns the independent axes of a signal.

mdsvalue('dim_of(signal[,n])')  returns the nth dimension of a 
                                  signal, defaults to 0th dimension
mdsvalue('data(signal)')        returns the data part of a signal
mdsvalue('units(a)')            returns the units of data with units
mdsvalue('units(signal)')       returns the units of a signal
mdsvalue('units(dim_of(signal)')  returns units of the dimension of a signal
mdsvalue('raw_of(signal)')      returns the raw part of a signal (if it exists)

Getting Information on Arrays

A number of functions are available to get the size and shape of multidimensional arrays. For example, given a, a node containing a floating point array with 10 x 24 elements:

mdsvalue('size(a)')   = 240    (total number of elements)
mdsvalue('sizeof(a)') = 960    (total number of bytes)
mdsvalue('shape(a)')  = 10, 24 (number of elements in each dimension)

Getting MDSplus Metadata

The TDI function getnci can be used to return the metadata - that is information about the data stored in MDSplus nodes. Getnci stands for "get node characteristic information". The syntax for this functions is 'getnci([node],string,[usage])'. The arguments of this function are:

NODE    Usually a string containing a fully qualified node name 
        but may also be a node's numerical id (NID) or an array of NIDs.  
        If not present, this argument defaults to the current default node.
        Wildcards may be used in the path name.  See users manual
        section on tree syntax for details. 
STRING  A case-insensitive character scalar chosen from the table below. 
        The string may be abbreviated in upper or lower case to any 
        unique form. 
USAGE   A character scalar or array. This optional argument limits the 
        search of NODE names. It must be a valid usage name like "SIGNAL",
        or "TEXT".  "ANY" will cause nodes of all usage
        types to be searched.

mdsvalue('getnci([node],string,[usage])') will return a scalar or simple vector list of results. The metadata returned depends on the value of the STRING argument in the call. The table below describes some of the more commonly used calls. See the TDI reference manual for the complete list.

The STRING names by returned type follow.

 Type of data returned   STRING                  Metadata returned

 ---------------------   ------                  -----------------

         Character       FULLPATH                path from top of tree
                         MINPATH                 shortest relative path
                         NODE_NAME               last part of pathname
                         PATH                    path from top or tag
         Logicals        IS_CHILD                parent relationship
                         IS_MEMBER               parent relationship
                         PARENT_STATE            parent on or off
                         STATE                   on or off
         Long            DEPTH                   tree parents above
                         LENGTH                  data size
                         NID_NUMBER              tree logical offset
                         NUMBER_OF_CHILDREN      number of child nodes
                         NUMBER_OF_MEMBERS       number of member nodes
                         PARENT_RELATIONSHIP     child or member
         Long unsigned   OWNER_ID                rights identifier
                         STATUS                  status
         Node data       RECORD                  actual data
         Quadword unsigned TIME_INSERTED         encoded date and time
 

Some examples of the getnci function (refering to tree in section?):

Get the full path corresponding to the tag name "ip"
mdsvalue('getnci(\ip,"fullpath")') = '\MAGNETICS::TOP.PROCESSED.CURRENT_DATA:IP'
Get the depth of \ip in the magnetics tree hierarchy (see note 2)
mdsvalue('getnci("\\ip","depth")') = 4
Same command using argument substitution
mdsvalue('getnci($,"depth")',"\\ip") = 4
mdsvalue('getnci(\ip,"nid_number")') = 1299
mdsvalue('getnci(1299,"fullpath")') = '\MAGNETICS::TOP.PROCESSED.CURRENT_DATA:IP'

Note 1: If a node is itself an expression, getnci(node,"length") will return the size of the expression not the size of the array.

Note 2: Node references are usually not quoted. However getnci will accept this argument as a text string. In this case the double backslash is needed since \ is a reserved character in the C language (which MDSplus is written in). For more details see the discussion on "Node Spec or Character String?" in users guide.

Calling External Routines

TDI functionality can be extended via calls to external routines. These may be written in the TDI language itself and saved in files with the extension .fun into directories in the users MDS path. Compiled routines written in fortran or c and built into a shared library can also be accessed. The syntax for calling these routines from TDI is: _result=shared_library->routine(arguments,..). The users path must include the shared library.

Specific details for this process will differ between operating systems. Details can be found in the users guide.

next page