From MdsWiki
TDI VMS Help: $ HELP/LIBRARY=MDS$ROOT:[SYSHLP]MDSPLUS.HLB TDISHR C-like syntax case insensitive special functions for working with MDSplus objects ?can be invoked by putting call and args into an expression node in a tree, and then the actual TDI (compiled?) is found by looking in the sharable library pointed to by (TCL or MDS$TCL) SET LIBRARY ... or something like that
[edit] VariablesLocal variables are to be used to optimize code by not recalculating and for writing repeated or more complicated expressions. They should not be used to carry information across trees because access is then order dependent. >>>>>>>>>WARNING, they have side effects!!! You may store any MDSplus data type in a variable and then reference it as you need it in other expressions. >>>>>>>>>WARNING, the order of operations may not be clear (to you or the compiler), so be careful about assigning data to a variable and using the variable in the same expression. COMMA, VECTOR, and statements are left to right but argments of functions may be used in any order. There are two forms of variables: private and public. The usual, private variables are seen only by your current FUN. Whereas, public variables can be seen by all programs. Anywhere a VAR like _X can be used, you may use PRIVATE _X or PUBLIC _X to distinguish the one you want. Otherwise on reading, _X looks for PRIVATE _X first and then PUBLIC _X. On writing, _X will be stored in the private list unless it was a modify operation like _X++ or _X+=6. >>>>>>>>>WARNING, always use PUBLIC for public variables to help you analyze the code later. All user variables should begin with an underscore (_); system variables will begin with a dollar sign ($). Names beginning with alphabetics look like tree members. The length must be less than 200. Upper and lower cases are not distinct, thus _a and _A are the same.
[edit] LiteralsLiterals are constants written as text. Letters used to designate data type and base may be upper or lower case. Integers must begin with a number. Prefixes designate base and are 0B for binary, 0O for octal, 0X for hexadecimal, and none for decimal. [PR: look like SUFFIXES to me...] Suffixes designated data type: BU for byte_unsigned, WU for word_unsigned, LU for long_unsigned, QU for quadword_unsigned, OU for octaword_unsigned, B for byte, W for word, L for long, Q for quadword, and O for octaword. No suffix is type L. You may use UB instead of BU for byte_unsigned and SB or BS instead of B for byte. After 0X use SB for signed bytes because the B looks like a digit. Floating point numbers must have a decimal point or an exponent with following optionally signed digit or digits and at least one digit. The exponent designator is E or F for standard precision, D for double, G for wide-exponent double, and H for quad-precision. Without an exponent, standard precision is assumed. Complex numbers must be formed with the function CMPLX(real,imag). WARNING, you may specify D_COMPLEX and others but the precision of the arguments is determined by each exponent letter. Characters or text may be enclosed in single quotes (apostrophes) or double quotes. TDISHR uses the CC-style designation of control characters (\001 or \n), the quoting character (\' or \"), and the backslash (\\) itself. Hexadecimal control characters (\x8c) must be used with care, because they stop on the first non-hexadecimal character. Octal controls are limited to three digits or the first non-octal one. Adjacent text strings (possibly with white space between) are concatenated. This allows breaking of strings across more than one line. Otherwise, two literals may not be adjacent--bad syntax.
[edit] Glossary
[edit] CC-useThe easiest calls are the MDSLIB routines. To eliminate using the compiler you could write functions to be evaluated. This involves many descriptors and pointers, see OPC$. Between the inefficiency of compilation and the difficulty of function coding is the method of direct calls to the TDISHR library. Like status = TDI$ADD(&first_dsc, &second_dsc, &output_dsc); Other than special calls directly into TDISHR, you call routines by names like TDI$xxx, where xxx is the function to be performed. Each routine returns a VMS-type status code as its function value. The arguments are the addresses of descriptors of each input with the final argument being the one output descriptor. Operations like + have special names like TDI$ADD, see Precedence. [edit] CallsAs an example of TDISHR calls we will add 2 and a tree element. #include descrip int call_test(struct dsc$descriptor *out_dsc_ptr) { static int const two = 2; static struct dsc$descriptor two_dsc This example would be easier to code in VAX Fortran. [edit] MDSLIBAs an example of MDSLIB calls we will add 2 and a tree element. The experiment and shot are assumed identified elsewhere. #include descrip int call_test(struct dsc$descriptor *out_dsc_ptr) { static $DESCRIPTOR(const expression, "2+\\TOP.XRAY.CHAN_01:GAIN"); int status; This example would be easier to code in VAX Fortran. [edit] OPC$The most difficult form of coding is to define all relationships with pointers in special (class-R) descriptors to other descriptors of VMS and MDSplus data. As an example, we will add 2 and a tree element. Use DCL to DEFINE C$LIBRARY MDS$ROOT:[SYSLIB]MDSDEF.TLB before compiling with CC the following code excerpt: #include descrip #include tdescrip int opc_test(struct dsc$descriptor *out_dsc_ptr) { globalref unsigned short OPC$ADD; static int const two = 2; static struct dsc$descriptor const two_dsc = {sizeof(two),DSC$K_DTYPE_L,DSC$K_CLASS_S,&two}; The included files define the descriptor structures, descrip from VAXCDEF and tdescrip from MDSDEF. The global reference is to TDISHR and the function number is used by EVALUATE to do the operation. The node's data is fetched and its data type, and possibly two's data type, are converted to match. The addition is done and the result is embedded in units and signal descriptions as needed. The result is then matched to the output descriptor's data class and type. The output descriptor must be class-XD if the result is more complicated than a standard scalar. The input arguments could be "static const" because they are read only. [edit] StatusEach TDISHR routine returns a longword VMS-type status. [edit] Fortran-useThe easiest calls are the MDSLIB routines. To eliminate using the compiler you could write functions to be evaluated. This involves many descriptors and pointers, see OPC$. Between the inefficiency of compilation and the difficulty of function coding is the method of direct calls to the TDISHR library. status = TDI$ADD(%DESCR(first), %DESCR(second), output_dsc) Other than special calls directly into TDISHR, you call routines by names like TDI$xxx, where xxx is the function to be performed. Each routine returns a VMS-type status code as its function value. The arguments are the addresses of descriptors of each input with the final argument being the one output descriptor. Operations like + have special names like TDI$ADD, see Precedence. [edit] CallsAs an example of TDISHR calls we will add 2 and a tree element. Integer function call_test(out_dsc) Include 'FORSYSDEF.TLB($DSCDEF)' Record /DSCDEF1/ out_dsc Integer two /2/ Character*21 elem = '\TOP.XRAY.CHAN_1:GAIN' We could also have used TDI$ADD(%descr(2), '\TOP.XRAY.CHAN_1:GAIN', out_dsc) [edit] MDSLIBAs an example of MDSLIB calls we will add 2 and a tree element. The experiment and shot are assumed identified elsewhere. Integer function mds_test(dataid) Integer dataid [edit] OPC$The most difficult form of coding is to define all relationships with pointers in special (class-R) descriptors to other descriptors of VMS and MDSplus data. As an example, we will add 2 and a tree element. As of this writing, there is no TDESCRIP definitions for Fortran use. Integer Function opc_test(out_dsc) Include 'FORSYSDEF.TLB($DSCDEF)' Include 'FORMDSDEF.TLB(tdescrip)' Record /DSCDEF1/ out_dsc External OPC$ADD Integer two = 2 Character*21 elem = '\TOP.XRAY.CHAN_1:GAIN' Record /DSC$DESCRIPTOR_R2/ add_dsc The included files define the descriptor structures. The external reference is satisfied by TDISHR and the function number is used by EVALUATE to do the operation. The node's data is fetched and its data type, and possibly two's data type, are converted to match. The addition is done and the result is embedded in units and signal descriptions as needed. The result is then matched to the output descriptor's data class and type. The output descriptor must be class-XD if the result is more complicated than a standard scalar. There is no way in VAX Fortran to "Data" (initialize) a record. [edit] StatusEach TDISHR routine returns a longword VMS-type status. The lowest bit is set (status .AND. 1) if the operation succeeded. Otherwise, the error may be signaled by LIB$SIGNAL(%val(status)) or its text fetched by SYS$GETMSG(%val(status), length_ret, text_ret, %val(15), ).
[edit] PrecedenceTDISHR supports many syntactical forms having different precedence. Operators with equal precedence are evaluated left to right (LR) or right to left (RL). You may use F90 (/ for [, /) for ], and /= for !=.
[edit] SignalsA signal is data with its source (RAW is usually an intermediate expression) and its DIMENSIONs. The dimensions are the independent axes of the dependent data. For example, a waveform is a function of time and the dimension is the time points at which the waveform was recorded. Often this axis is a simple expression that can be expressed as a SLOPE or RANGE. In combining expressions with signals, generally a single signal will dominate. When more than one signal is combined, only one signal can be chosen. The signal selected will be the one with the smaller number of elements as this limits the size of the result.
[edit] UnitsUnits can be added to any data field by the WITH_UNITS descriptor. Spell out units with lowercase or better yet use the abbreviation. The basic unit names are: m meter kg kilogram s second A ampere K kelvin mol mole cd candela The supplementary unit names are: rad radian sr steradian Derived unit names are: Hz hertz J joule N newton Pa pascal W watt C coulomb V volt (Omega) ohm S siemens F farad Wb weber H henry T tesla lm lumen lx lux Bq becquerel Gy gray Use star (*) for multiplication. The use of nonstandard names, like sec for second, will inhibit the use of later (to be written) unit handling. Restrain the use of multipliers. If you do use them, then: f for femto, p for pico, n for nano, u for micro, m for milli, k for kilo, M for mega, G for giga, and T for tera are OK. (Micro is a Greek mu but u is readable.) >>>>>>>>>WARNING, use the preferred SI units: Avoid cm for centimeter, use mm or m. Conversions and simple arithmetic operations do not change the units. The argument of mathematical operations like SIN(x) should not have units because the number must be dimensionless. The units of a result are defined for some binary operations: Multiplication and division try to combine units. [edit] TDI$_direct_callsThese routines directly enter TDISHR and have less error checking. Additional information available: TDI$CONVERT(%descr(IN),%descr(OUT))
[edit] RestrictionsTrouble words for tree node names without preceding . or : are the names of standard operations: NOT BREAK CONTINUE ELSE ELSEWHERE. It is highly recommended that child or member nodes be marked. Partial implementation: No IO nor DECODE/ENCODE/STRING. APD: Array of Pointers to Descriptors
[edit] About TDISHRSoftware version: 9-Oct-1991. The information in these texts is subject to change without notice and should not be construed as a commitment for development by the MDSplus development team. The software described in these texts is furnished under a license and may be used or copied only under the terms of such license. The Tree Data Interface shared library is mostly written by Kenneth A. Klare All rights reserved, 1989, 1990, 1991. |