From MdsWiki
|
[edit] Expressions - The TDI LanguageAll 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('\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 t = mdsvalue('dim_of(\ip)')
For signals with more than one dimension, 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: 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 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 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 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 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.
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 Specific details for this process will differ between operating systems. Details can be found in the users guide. |