# VMS MDSplus for NSTX

Last edit: 15-Apr-08

CONTENTS

1.0 Introduction

> Target Audience
>
> Environment definitions
>
> Other Tools and Documentation

2.0 NSTX MDSplus trees on VMS

> Trees and logical names
>
> Trees and disks: MDSPLUS_DATABASES.COM
>
> Write access to NSTX VMS trees
>
> Serving VMS MDSplus trees to other platforms
>
> Accessing Linux (lark.pppl.gov:8501) trees
>
> The event server on VMS

3.0 The NSTX Shot Cycle

> EPICS and the programs that talk to it
>
> Facility clock events
>
> ipcs communication
>
> MDSplus events
>
> ipcs to MDSplus
>
> Shotclock
>
> Clocksync
>
> Redeclare
>
> Mdsplus to ipcs
>
> Building a dispatch table
>
> Dispatching a phase
>
> Defining a phase
>
> Defining a dispatcher and its servers: DECnet
>
> MDSplus Action Nodes
>
> Synchronizing EPICS and MDSplus: runnstx
>
> Detecting and removing hung servers
>
> Action Monitor
>
> Log files and log file comparisons

4.0 Device Support

> Adding an already supported device
>
> Supporting new devices in MDSplus
>
> In C
>
> In TDI

5.0 CAMAC definition and monitoring

> Defining the CAMAC configuration at boot
>
> Setting crates on-line: cratemon
>
> Telling EPICS about highway status: linkmon

6.0 Data Management

> Disk configuration
>
> NSTX_DAILY.COM
>
> NSTX_OLDTOSANSLOW.COM

7.0 NSTX analysis on VMS -- batch queues

8.0 System Startup: what happens at boot

> Startup checks

9.0 Troubleshooting?

10\. Miscellaneous

> SHW command

Appendices

> A
>
> B
>
> C
>
> D
>
> E
>
> F
>
> FIGURES

Shot cycle: appendix?

mdsserver.exe - DECnet

IPCS

LLNL InterProcess Communication System messaging is used for
communication of EPICS state to VMS MDSplus infrastructure (RUNNSTX.EXE,
CLOCKSYNC_NSTX.EXE, NSTX_REDECLARE.EXE). Bill Meyer of LLNL/GA and Jeff
Moller of LLNL are the last remaining developers employed in fusion.

Definitions are established by PPPL_RES:\[COM\]REE\$SYS_STARTUP.COM
(developed for the Remote Experimental Environment project), which runs
from COM\$MGR:COMSYSBAT.COM at system boot (submitted to batch queue
\<hostname\>\_NORM).

The configuration file to edit is
IPCS_DISK:\[IPCS.NETMAILER.EXE\]NETMAILER_KEES.CFG, not
IPCS_DISK:\[IPCS.NETMAILER.EXE\]NETMAILER.CFG as described in TRG's
memo. It contains the names and IP addresses of participating hosts, and
the ports used.

KEES\$ dirw netmailer_kees.cfg;

Directory IPCS_DISK:\[IPCS.NETMAILER.EXE\]

NETMAILER_KEES.CFG;5 1/41 26-JAN-2007 13:59:21.23

Total of 1 file, 1/41 blocks.

KEES\$

KEES\$ type NETMAILER_KEES.CFG

this_host=KEES /cell_netmailer=pppl_res /protected

pppl_res /connection=tcp /internet=198.35.15.21 /port=1000

BIRCH /connection=tcp /internet=192.55.106.24 /port=1000

E2 /connection=tcp /internet=192.55.106.171 /port=1000

LUNA /connection=tcp /internet=198.35.15.125 /port=1000

taurus /CONNECTION=TCP /INTERNET=192.55.106.156 /PORT=22375

epicsrv /CONNECTION=TCP /INTERNET=198.35.10.21 /PORT=22375

KEES\$

To inspect the current makeup of the cell:

KEES\$ \@pppl_res:\[evt\]defs

%DCL-I-SUPERSEDE, previous value of IPCSMAILER has been superseded

KEES\$ nm_status

pppl_res KEES PROTECTED CELL NETMAILER (KEES)

pppl_res pppl_res 0 TCP NULL

BIRCH BIRCH 2 TCP CONN

E2 E2 1 TCP CONN

LUNA LUNA 1 TCP CONN

taurus taurus 1 TCP DISC

epicsrv epicsrv 2 TCP CONN CELL ()

IPCSMAILER pppl_res 23200450 45ba099f REG

ACQ_PARMS pppl_res 23200426 45ba04d7 REG

ACQ_CREATETREE pppl_res 23200436 45ba04d7 REG

RUNNSTX pppl_res 23200451 45ba09ac REG

EVTMGR_NSTX epicsrv epicsrv f34c0000 a10bb945 pppl_res epicsrv

Domalloc buffer count = 17

KEES\$

The notation CONN CELL () after epicsrv indicates that epicsrv.pppl.gov
is part of another cell as well.

runnstx and dispatching

mdsip.exe servers - TCP/IP interface

"The Big Picture"

local disks / SAN disks

NSTX MDSplus computers, VMS, Linux and Windows, and CAMAC highways

Overview of data sources, June 2006

1.0 Introduction

0.  1.1 Target Audience\
    This document is intended for a very small audience of programmers
    and system administrators who are already quite familiar with
    MDSplus from a user viewpoint. NSTX uses MDSplus on both VMS and
    Linux, but this document is intended to describe only the VMS
    environment. It attempts to explain the parts of MDSplus necessary
    for data acquisition and also the NSTX-specific configurations and
    programs that glue MDSplus to the NSTX experiment. A companion
    document will be written for NSTX MDSplus on Linux.\
    \
    A privileged account is required to run many of the necessary
    programs. The most commonly needed privileges are SYSPRV, WORLD and
    CMKRNL. If your account has SETPRV, you will be able to set these
    with\
    \$ SET PROCESS/PRIV=(SYSPRV,WORLD,CMKRNL)

1.  1.2 Environment definitions\
    User: SETUP NSTX\
    Programmer adds: \@DAS:DASLOGIN.COM, \@DAS:DASCAMAC.COM\
    MDSplus servers use: \@MDSPLUS\$:\[000000\]MDSPLUS.COM,
    MDSIP.COM,MDSIP_EFIT_NSTX.COM

2.  1.3 Other Tools and Documentation\
    A brief inventory of other NSTX documentation and tools is provided
    here.

> MDSplus User Documentation
>
> The MDSplus home page: http://mdsplus.org/
>
> The NSTX MDSplus web
> page:http://nstx.pppl.gov/nstx/Software/MDSplus/index.html
>
> Formatted VMS TCL Help:
> http://nstx.pppl.gov/nstx/Software/TCL_index.html
>
> Formatted VMS TDI Help:
> http://nstx.pppl.gov/nstx/Software/TDI/TDI_TOP.HTML
>
> Other MDSplus software group documentation related to VMS
>
> Producing web tool summary pages
>
> http://w3.pppl.gov/%7Eroney/swdoc/pgr_vmswebprogs.html
>
> Startup checks?
>
> MDSplus Tools for looking at data and at trees
>
> Traverser
>
> Scope
>
> TCL
>
> dir/full vs. show data: looking at the properties vs. the subfields of
> a node
>
> mdir MDSplus directory, 1for finding trees (\$HELP mdir)
>
> Tools used for looking at CAMAC topology and devices
>
> CTS
>
> CCL
>
> Examining modules in remote crates: scancrate
>
> Module-specific status programs
>
> Web Tools for looking at NSTX CAMAC
>
> KEES CAMAC Highways status, map & CTS definitions
>
> LUNA CAMAC Highway status, map & CTS definitions
>
> CAMAC manuals
>
> IDL especially for MDSplus
>
> MDS\$PPPLROOT:\[IDL\], includes some CAMAC-related routines
>
> Documented on the web:\
> http://nstx.pppl.gov/nstx/Software/Programming/pppl_idl_routines.html#MDSplus
>
> Web Tools for looking at NSTX MDSplus and image data
>
> http://nstx.pppl.gov/nstx/Software/WebTools/webplottingoptions.html
>
> http://w3.pppl.gov/%7Ebdavis/movies/
>
> http://nstx.pppl.gov/nstx/Software/WebTools/searchcompare.html
>
> http://nstx.pppl.gov/nstx/Software/Diagnostics/FC/
>
> http://w3.pppl.gov/\~szweben/psi/
>
> http://nstx.pppl.gov/nstx/Software/Diagnostics/SpecFit/
>
> Tools for monitoring known MDSplus events
>
> roney\$:\[IDL\]NSTX_SHOT_CYCLE_EVENTS.PRO
>
> Bill Davis' MONEVENTS.PRO (Web documentation)
>
> Examining VMS disk contents: indexf\
> \$ HELP INDEXF
>
> See Appendix XXX for example of usage.

2.0 NSTX MDSplus trees on VMS

2.1 Trees and logical names

An MDSplus tree is a complex data structure used to group all the
information about some logical collection of measurements made during a
plasma shot into a flexible unit with named substructures. Each shot
tree begins as a copy of its corresponding model tree. The model or
template contains no shot data, just structural and sometimes
configuration data. An MDSplus tree consists of three related files,
*all residing in the same directory*, and following a naming convention
of \<treename\>\_\<shotnumber\>.\<MDSplus extension\> where the MDSplus
extensions are tree, characteristics and datafile.

An MDSplus installation may have any number of model trees, and these
trees may be related or unrelated. A tree may contain subtrees, which
are opened when the parent tree is opened. (Only the .TREE file is
opened on MDSopen, so it isn't quite as much I/O as it sounds.) Although
the parent clearly knows its subtrees, the subtrees are completely
unaware that they have a parent. The linkage is in one direction only.

The location of the files for any tree is determined by the logical name
\<treename\>\$DATA.

Disk directory relationships have nothing to do with tree relationships.
Subtrees at PPPL are usually stored in independent directory structures,
all at the same level. The current exceptions are subtrees of EFIT and
LRDFIT, where we have chosen to put all the subtrees into the same
directory structures as the parent.

\<treename\>\$DATA usually translates to a searchlist of directories
containing at least one for new data, one for the model trees, and one
or more for older data. At PPPL older data is stored under searchlist
NSTX\$ARC\$ in subdirectories determined by shot number as well as tree
name, while new data and model trees are stored in tree name
subdirectories under logical names NSTX\$NEW\$ or NSTX\$MODELS\$. All
these logical names are defined in the logical name table LNM\$MDS_NSTX
which is created by COM\$MGR:MDSPLUS_DATABASES.COM. See further
description of this procedure below. LNM\$MDS_NSTX is put into a user's
environment by the **setup** procedure in response to the command **\$
setup nstx** To see all the searchlists defined for NSTX VMS trees:

\$ SHOW LOGICAL \$DATA

There is also a dynamically created web page, updated daily, which shows
the top-level branches of the public NSTX trees as well as the tree
names themselves:
<http://nstx.pppl.gov/nstx/Software/Overview/nstxsubtrees.html>

Private MDSplus trees, owned by individual users, can also be created.
For these, the logical name is put into the system logical name table
via COM\$MGR:MDSPLUS_PRIVATE_DATABASES.COM upon a user request. The user
decides what the translation of the name should be; usually this is a
subdirectory of the user's home directory - typically there are no
searchlists. Private trees are usually used for testing. No NSTX data
management is provided for these trees, and it is not appropriate to
store data in them. The names of any private trees will also appear in
the list produced by "show logical \*\$data."

### 2.2 Trees and disks: MDSPLUS_DATABASES.COM

Nearly all aspects of the NSTX MDSplus disk configuration management are
collected in a single command procedure, COM\$MGR:MDSPLUS_DATABASES.COM.
(Full text as of September 2006 in Appendix XXX.) It creates directory
structures for all VMS NSTX trees as needed and puts the
\<treename\>\$DATA entries into the NSTX logical name table
LNM\$MDS_NSTX. It also defines a number of disk-related logical names
needed for data management. It is invoked at system boot as part of
COM\$MANAGER:COMSYSLNM.COM. See Section 4 for a description of the
current disk organization.

MDSPLUS_DATABASES.COM must be edited in order to add a new tree or a new
disk for either new or "archived" MDSplus data. Running it once on any
node will create any needed directories and then update the logical name
tables on each of the cluster nodes via SYSMAN. No system reboot is
needed to add a new tree or a new disk; just choose a quiet time so that
the procedure can finish on the entire cluster before a shot is taken.
(Unfortunately, BEANIE, a VAX, which is part of the cluster, can no
longer successfully run this procedure. Error messages from BEANIE
should be ignored.)

####### Applying ACL to disk directories; a manual step at present

####### 2.3 Write access to NSTX VMS trees

Write and edit access to MDSplus trees is based on account
rights-identifiers, granted from the AUTHORIZE utility and added to
MDSplus directories with SET ACL command procedures (usually stored in
NSTX\$:\[NSTX.ADMIN\]). A user's rights identifiers are listed at the
end of the account parameters. The attribute RESOURCE allows the
identifier to own file quota and the user to draw against that quota
when creating files. If no file quota is granted to the identifier on a
disk, which is frequently the case, then having attribute RESOURCE means
nothing. Currently managing ACL's is done independently from creating
tree logicals and directories, although it would be desirable to do both
in the same place (and automatically).

######### MCR AUTHORIZE 

######### UAF\> show roney

Username: RONEY Owner: RONEY, P.

Account: CMPOPR UIC: \[166,250\] (\[RONEY\])

CLI: DCL Tables:

Default: AUSER7:\[RONEY\]

LGICMD:

Flags: GenPwd

Primary days: Mon Tue Wed Thu Fri Sat Sun

Secondary days:

No access restrictions

Expiration: (none) Pwdminimum: 6 Login Fails: 0

Pwdlifetime: 360 00:00 Pwdchange: 8-FEB-2006 11:29

Last Login: 12-SEP-2006 08:55 (interactive), 12-SEP-2006 14:00
(non-interactive)

Maxjobs: 0 Fillm: 500 Bytlm: 300000

Maxacctjobs: 0 Shrfillm: 0 Pbytlm: 0

Maxdetach: 0 BIOlm: 300 JTquota: 10000

Prclm: 20 DIOlm: 300 WSdef: 3000

Prio: 4 ASTlm: 1000 WSquo: 3000

Queprio: 0 TQElm: 1000 WSextent: 8000

CPU: (none) Enqlm: 1000 Pgflquo: 2000000

Authorized Privileges:

GROUP GRPNAM NETMBX PRMCEB PRMMBX SETPRV

TMPMBX

Default Privileges:

GROUP GRPNAM NETMBX PRMCEB PRMMBX TMPMBX

**Identifier** Value Attributes

DAS_OWNER %X8001000C RESOURCE

TFTR_RESULTS_OWNER %X8001001E RESOURCE

PBX_OWNER %X8001002C RESOURCE

CHERS_USER %X80010050 RESOURCE DYNAMIC

TRANSPDATA %X8001002A RESOURCE

NSTX_TEMP_DATA %X800100AF RESOURCE

NSTX_CVS %X800100BA

NSTX_RF %X800100B8

NSTX_ENGINEERING %X800100B2

NSTX_OPERATIONS %X800100B1 RESOURCE

NSTX_SW %X800100C0 RESOURCE

NSTX_NBI %X800100B9 RESOURCE

ELECTRONPLASMA %X800100C3 RESOURCE

NSTX_READER %X800100CF RESOURCE

NSTX_MICROWAVE %X800100B3 RESOURCE

NSTX_ACTIVESPEC %X800100B6 RESOURCE

NSTX_CAMERAS %X800100B0 RESOURCE

UAF\>

Creating a new access control identifier

> **MCR AUTHORIZE**
>
> **ADD/IDENTIFIER/ATTRIB=RESOURCE** \<newIDname\>
>
> **GRANT/ID/ATTRIB=RESOURCE** \<newIDname\> **username**

Listing holders of an existing identifier

> **MCR AUTHORIZE**
>
> **UAF\> show/identifier/full pcs_owner**
>
> Name Value Attributes
>
> PCS_OWNER %X800100D8
>
> Holder Attributes
>
> MDSPLUS_GA
>
> DGATES
>
> PENAFLOR
>
> GIBNEY
>
> LUDESCHER
>
> DMASTROVITO

Most of the identifiers we use begin with "NSTX\_"; there is an
identifier NSTX\_\<treename\> for each of the subtrees of NSTX on VMS.
Some diagnostic groups also have their own identifiers. Unfortunately, "
show/identifiers \*" in AUTHORIZE gives not only all the defined rights
identifiers (which is already a long list) but also all the usernames.

2.4 Write (and read) access for remote (non-VMS) users: MDSIP.HOSTS

Remote users accessing MDSplus data via mdsip.exe servers receive the
rights of the account to which their ip address is mapped in
MDS\$ROOT:\[SYSMGR\]MDSIP.HOSTS. Wildcards are supported in the
descriptions in this file, and all users logged in on PPPL machines get
read access via the account NSTXPLAN from the final entry in the file:

\*@\*.pppl.gov \| nstxplan

nstxplan is an unprivileged account.

No LOGIN.COM file gets executed in the process of mapping a remote user
to a local account, so only the authorized properties and any defined
file quotas for that account are significant.

The ip name or address of the user requesting an MDSplus connection is
matched against every line of the MDSIP.HOSTS file in order, so the
first match determines the VMS account to which the user will be mapped.
Default matches like the PPPL one above, should be put at the very end
of the file. If no line matches, the connection request will be denied.
Accepted and denied connections are logged in MDS\$ROOT:\[SYSERR\]
MDSIP\_\<VMShostname\>.LOG .

####### 2.5 Serving VMS MDSplus trees to other platforms

When a remote user executes an "MDSconnect" command or does an "MDSopen"
without an explicit connect, a process will be started up on a VMS node
(if the user is authorized to connect). The node used is selected by the
program if the command is connect; it is obtained from the remote user's
environment variable \<treename\>\_path if there is no explicit connect.
Each remote process gets its own VMS MDSplus server process, which is an
instance of mdsip.exe. Environment variables are usually set on a remote
Linux/UNIX host using "module load nstx/mdsplus" and on Windows by
setting registry entries. The user can override any of these settings.

TCP/IP services are provided on VMS via the Multinet third-party
package. VMS UCX can also provide TCP/IP services, but we no longer use
it for MDSplus. Service MDSIP on port 8000 serves TFTR data; it was
originally used for testing. Services MDSIP_NSTX on port 8501 and
MDSIP_EFIT on port 8502 (higher priority) provide access to NSTX data.

EUROPA\$ show def

MULTINET_ROOT:\[MULTINET\]

= MULTINET_ROOT:\[MULTINET\]

= MULTINET_COMMON_ROOT:\[MULTINET\]

EUROPA\$ dirw services\*.\*;

Directory MULTINET_COMMON_ROOT:\[MULTINET\]

SERVICES.MASTER_SERVER;37 47/54 21-FEB-2006 13:20:18.26

Total of 1 file, 47/54 blocks.

Excerpts from file SERVICES.MASTER_SERVER relating to MDSplus services
are below. This file is *not* edited directly. Tom Gibney's description
of configuring it follows. Probably it will never be necessary to modify
these definitions nor to add to them for NSTX MDSplus. (Note: the
instance of MDSIP.EXE

#Last Change by GIBNEY at Fri Nov 12 11:33:18 1999

**service-name MDSIP**

**program AUTIL:\[MDSPLUS\]MDSIP.COM**

socket-type SOCK_STREAM

socket-options SO_KEEPALIVE

socket-address AF_INET , **8000**

priority 7

INIT TCP_Init

LISTEN TCP_Listen

CONNECTED TCP_Connected

SERVICE Run_Program

#Last Change by SYSTEM at Fri Apr 14 14:26:37 2000

**service-name MDSIP_NSTX**

**program MDS\$TOP:MDSIP_NSTX.COM**

socket-type SOCK_STREAM

socket-options SO_KEEPALIVE

socket-address AF_INET , **8501**

priority 7

INIT TCP_Init

LISTEN TCP_Listen

CONNECTED TCP_Connected

SERVICE Run_Program

send-buffer-space 6144

receive-buffer-space 6144

#Last Change by SYSTEM at Thu Dec 1 09:44:17 2005

**service-name MDSIP_EFIT_NSTX**

**program MDS\$TOP:MDSIP_EFIT_NSTX.COM**

socket-type SOCK_STREAM

socket-options SO_KEEPALIVE

socket-address AF_INET , **8502**

working-set-quota 32000

working-set-extent 64000

pql-astlm 2000

pql-bytlm 30000

INIT TCP_Init

LISTEN TCP_Listen

CONNECTED TCP_Connected

SERVICE Run_Program

send-buffer-space 32768

This appears to add a service for mdsipe, the event server; this is NOT
a Multinet service, it runs from a boot procedure on Europa (now,
formerly Birch) and, according to comments in the command procedure
XXXXX should NOT be defined as a service. But we still need to have doc
on how to set up a service, probably...

EUROPA\$ type gibney\$:\[handbook\]multinet_add_service.mem

To add a new service (like, say, MDSIP) to Multinet, do the following.

Not sure about the order, but hey \...

\$ multinet config/server

\> add mdsipe

\> \--\> multinet will prompt for parameters

-or-

\> select mdsipe

\> set \... ;set/modify parameters

\> enable mdsipe

\$ edit multinet:hosts.local

\--\> add a line for the new service. See mdsipe example.

\$ multinet host_table compile

\$ \@multinet:install_databases.com

used carroll\$:\[nstx\]foo.c foo.com and foo.exe to test (was echo

from multinet examples)

EUROPA\$

2.6 TDI for scopes and analysis; thin and thick clients

Logical name MDS\$PATH defined in MDSPLUS\$:\[000000\]MDSPLUS.COM

\$ DEFLOG MDS\$PATH
MDS\$USER_PATH,MDSPLUS\$:\[PPPL\...\],MDS\$ROOT:\[TDI\...\]

defines places to look for TDI functions. MDS\$USER_PATH is the user's
home directory, not the user's current directory. Users can write their
own TDI functions to use in their own Scope displays. Some user-written
TDI is in MDSPLUS\$:\[PPPL\] and its subdirectories. Software group TDI
has been put either in MDSPLUS\$:\[PPPL\] or in MDS\$PPPLROOT:\[TDI\],
which is the first element of the searchlist for MDS\$ROOT:\[TDI\].

A TDI expression is valid in virtually every field of a Scope data
source definition, and of course in any MDSVALUE (or MDS\$VALUE) call in
analysis programs.

In a standard VMS MDSplus configuration, a Scope running on a remote
host would have its TDI functions execute on that remote host, not on
the VMS server. An MDSplus program that executes in this way is said to
be running a "thick" client as opposed to a "thin" client, which results
from an explicit MDSconnect in the remote code. At present we
*explicitly prevent* execution on the remote client, even when it is
"requested" by omitting the MDSconnect and getting the MDSplus
servername from the environment variable \<treename\>\_path. This
situation arose because many of the NSTX TDI routines call into VMS
Fortran libraries that we did not wish to convert and test and maintain
on the multiple Unix environments present at PPPL in 1999. Preliminary
testing indicated that it was actually more efficient at that time to
let VMS do all the calculations and simply send the result.

PPPL networks are now faster and the CPU advantage of Unix over VMS has
increased greatly. Probably we will eventually convert the Fortran and
permit thick clients to do their own calculations, receiving only the
raw MDSplus data structures across the network from the MDSplus server
process on VMS. (The Linux MDSplus server on lark.pppl.gov has a
standard implementation in this sense; Scope TDI executes wherever the
scope is running, and thus must be available there via MDS_PATH.)

Only a tiny change is needed to permit or prevent the use of thick
clients. The TDI functions serialize_in.fun, serialize_out.fun in
MDS\$MITROOT:\[TDI\] provide the interface between..........

####### 2.7 Accessing Linux (lark.pppl.gov:8501) trees 

Definitions for trees served by lark are entered in
COM\$MGR:COMSYSLNM.COM. "\$ show logical/system \*\$data", below, shows
all the defined remote trees and also the private trees on VMS.

These trees will also be found if a remote user asks a VMS server for
them, although this is not as efficient as connecting to lark directly.
Note that if a remote user uses VMS to read or write lark data, he or
she must have appropriate permission granted in *both* MDSIP.HOST files,
the one on VMS and the one on lark; this is of course also true if the
user asks lark for VMS data, which will also work.

> EUROPA\$ show log/system \*\$data
>
> (LNM\$SYSTEM_TABLE)
>
> \"BDAVIS\$DATA\" = \"BDAVIS\$:\[MDS.TESTDATA\]\"
>
> \"CAMERAS2\$DATA\" = \"LARK.PPPL.GOV:8501::\"
>
> \"DCON\$DATA\" = \"LARK.PPPL.GOV:8501::\"
>
> \"DCON01\$DATA\" = \"LARK.PPPL.GOV:8501::\"
>
> \"DPACELLA\$DATA\" = \"DPACELLA\$:\[MDS.TESTDATA\]\"
>
> \"JBOEDO\$DATA\" = \"JBOEDO\$:\[MDS.TESTDATA\]\"
>
> \"JMENARD\$DATA\" = \"JMENARD\$:\[JMENARD_TREE\]\"
>
> \"JMENARD_RAW\$DATA\" = \"JMENARD\$:\[JMENARD_TREE_RAW\]\"
>
> \"LRDFIT\$DATA\" = \"LARK.PPPL.GOV:8501::\"
>
> \"LRDFIT01\$DATA\" = \"LARK.PPPL.GOV:8501::\"
>
> \"LRDFIT02\$DATA\" = \"LARK.PPPL.GOV:8501::\"
>
> \"LRDFIT03\$DATA\" = \"LARK.PPPL.GOV:8501::\"
>
> \"LRDFIT04\$DATA\" = \"LARK.PPPL.GOV:8501::\"
>
> \"LRDFIT05\$DATA\" = \"LARK.PPPL.GOV:8501::\"
>
> \"LRDFIT06\$DATA\" = \"LARK.PPPL.GOV:8501::\"
>
> \"LRDFIT07\$DATA\" = \"LARK.PPPL.GOV:8501::\"
>
> \"LRDFIT08\$DATA\" = \"LARK.PPPL.GOV:8501::\"
>
> \"LRDFIT09\$DATA\" = \"LARK.PPPL.GOV:8501::\"
>
> \"LRDFIT10\$DATA\" = \"LARK.PPPL.GOV:8501::\"
>
> \"LRDFIT11\$DATA\" = \"LARK.PPPL.GOV:8501::\"
>
> \"LRDFIT12\$DATA\" = \"LARK.PPPL.GOV:8501::\"
>
> \"LRDFIT13\$DATA\" = \"LARK.PPPL.GOV:8501::\"
>
> \"LRDFIT14\$DATA\" = \"LARK.PPPL.GOV:8501::\"
>
> \"LRDFIT15\$DATA\" = \"LARK.PPPL.GOV:8501::\"
>
> \"LRDFIT16\$DATA\" = \"LARK.PPPL.GOV:8501::\"
>
> \"LRDFIT17\$DATA\" = \"LARK.PPPL.GOV:8501::\"
>
> \"LRDFIT18\$DATA\" = \"LARK.PPPL.GOV:8501::\"
>
> \"LRDFIT19\$DATA\" = \"LARK.PPPL.GOV:8501::\"
>
> \"LRDFIT20\$DATA\" = \"LARK.PPPL.GOV:8501::\"
>
> \"MMWR\$DATA\" = \"LARK.PPPL.GOV:8501::\"
>
> \"MSE\$DATA\" = \"LARK.PPPL.GOV:8501::\"
>
> \"NSTXTDI\$DATA\" = \"LARK.PPPL.GOV:8501::\"
>
> \"OPS_PC\$DATA\" = \"LARK.PPPL.GOV:8501::\"
>
> \"PROBES\$DATA\" = \"LARK.PPPL.GOV:8501::\"
>
> \"PROFDB_PED\$DATA\" = \"LARK.PPPL.GOV:8501::\"
>
> \"PSICHTA\$DATA\" = \"PSICHTA\$:\[MDSTST\]\"
>
> \"SLS\$DATA\" = \"SLS\$ROOT:\[DATA.EUROPA\]\"
>
> \"SSABBAGH\$DATA\" = \"SSABBAGH\$:\[MDS.TESTDATA\]\"
>
> \"TR\$DATA\" = \"NSTX0:\[NEW.TR.\]\"
>
> \"UCLA_INTERF\$DATA\" = \"LARK.PPPL.GOV:8501::\"
>
> \"USERNAME\$DATA\" = \"MDSPLUS_LOCAL\$:\[SAMPLE_DATA\]\"
>
> \"USXR\$DATA\" = \"LARK.PPPL.GOV:8501::\"

### 

### 2.8 The MDSplus event server on VMS for remote users

If a remote dwScope program wants event notification, it will use the
VMS node defined by the environment variable "mds_event_server". This
must point to one of the VMS nodes which actually runs a version of
mdsip.exe started with event server switches. Currently both BIRCH and
EUROPA have such servers, but soon EUROPA will be the only valid event
server. "mds_event_server" is defined via "module load nstx/mdsplus".
Overriding this name won't make sense when only one VMS system provides
the service.

3.0 The NSTX Shot Cycle (see appendix X for diagram)

> EPICS & stuff
>
> Facility clock events
>
> ipcs communication
>
> MDSplus events
>
> ipcs to MDSplus
>
> Shotclock
>
> Clocksync
>
> Redeclare nstx_redeclare: redeclares selected MDSplus events as
> **EVT** events\
> (is this still used? Can it be eliminated? -- for PCS, I think)
>
> MDSplus to ipcs

### Building a dispatch table

The TCL command DISPATCH/BUILD causes the currently defined dispatch
server (TCL itself if running interactively) to search through the
currently defined shot tree (there must be one: SET TREE
NSTX/SHOT=123456 defines the tree) and all its subtrees looking for
nodes of type ACTION and collecting them into groups by the name of the
phase for which they are defined.

In a sense, phase names in action nodes are arbitrary, but any phase to
be dispatched in the shot cycle must be defined to MDSplus via
PHASE_TABLE.FUN (below). At PPPL we only use MDSplus to dispatch the
"INIT" (or "INITIALIZATION") phase and the STORE phase. Action nodes are
described in detail in section 3.X.

The DISPATCH/BUILD step is necessary before any tasks can be dispatched
for a phase. It only needs to be done once per shot cycle.

####### Dispatching a phase

## **Dependency-based-dispatching**

###### Server synchronization by priority

**Defining a phase** MDS\$ROOT:\[TDI\]PHASE_TABLE.FUN

/\* PHASE_TABLE.FUN

; PURPOSE: Site customizable phase table

; for use with MIT Dispatch/Serve

; CATEGORY: CMOD (site customizable)

; CALLING SEQUENCE: phase_table = PHASE_TABLE()

; INPUTS: \--

; OPTIONAL INPUT PARAMETERS: \--

; KEYWORD PARAMETERS: \--

; OUTPUTS: \--

; OPTIONAL OUTPUT PARAMETERS: \--

; COMMON BLOCKS: \--

; SIDE EFFECTS: \--

; RESTRICTIONS: \--

; PROCEDURE: \--

; MODIFICATION HISTORY:

; TWF 3-AUG-1992 Initial coding.

This function should return a phase table specific to a MDSplus site.
The

phase table is a one dimensional string array containing a string pair
for

each defined phase. The string pair consists of the phase name and
value,

for example: \'PHASE_ONE\',\'1\'.

\*/

FUN PUBLIC PHASE_TABLE() {

RETURN ( \[

\'OFF\', \'0\',

\'INITIALIZATION\', \'5\',

\'INIT\', \'5\',

\'PULSE_ON\', \'6\',

\'BULK_DATA_ACQUISITION\', \'9\',

\'STORE\', \'9\',

\'SECONDARY_DATA_ACQUISITION\', \'10\',

\'ANALYSIS\', \'10\',

\'FINISH_SHOT\', \'99\'

\]);

}

Any Action node using a phase name not defined in PHASE_TABLE could
never be dispatched. To understand the value of using a

**MPTS "decouple" & "recouple"**

**Running INIT methods in STORE phase (responding to early f.clock
evts)**

####### Defining a dispatcher and its servers: DECnet

One copy of MDS\$ROOT:\[SYSEXE\]MDSSERVER.EXE runs as the Dispatcher.
Additional copies run as Servers, including two CAMAC servers on KEES
and one on LUNA. In the VMS-based system these tasks are installed as
DECnet known network objects. (On Unix, TCP/IP is used for this.) These
tasks run on demand.

The runnstx program starts (and restarts) the dispatch_server. TCL
commands passed to the dispatch_server start the data acquisition
servers (and will restart them if they abort or are interactively
stopped). The action_monitor server is started when a user requests it.

\$ nstxACTMON :== \"spawn/not/now/input=nl: mcr actmon -monitor
kees::mon_server\"

defines a symbol for starting the action monitor. One monitor serves any
number of requesting users, so a second request connects to the existing
monitor rather than restarting another copy.

ncp is the VMS DECnet Network Control Program. NSTX\$:\[NSTX.STARTUP\]
-NSTX_NCP.COM (listing in appendix) has defined the dispatcher (which
runs on KEES), the action_monitor and two CAMAC servers in the permanent
memory of ncp on KEES. The same program defined one CAMAC server and two
servers for remote MDSplus communication on LUNA. All these servers are
running the same image, mdsserver.exe. NSTX_NCP.COM only needs to be run
when adding or removing a server. ncp retains the necessary definitions
across reboots.

Each task definition in ncp includes the name of a command procedure to
run when the task is invoked. This command procedure (see listing of
NSTX\$:\[NSTX.STARTUP\] -GKB2_SERVER.COM in appendix) sets the server's
priority, privileges, the name of its log file (which includes the date)
and defines the NSTX environment before running MDSSERVER.EXE.

SYS\$MANAGER:KEESSYSTRM.COM defines logical names for these servers.
CAMAC_SERVER, in particular, needs to be defined (differently) on each
data acquisition system, because the device action nodes default to a
server name of CAMAC_SERVER. On KEES CAMAC_SERVER is KEES::GKB2_SERVER
(B highway) and on LUNA it is LUNA::GKA2_SERVER (Defined in
LUNASYSTRM.COM).

From SYS\$MANAGER:KEESSYSTRM.COM:

\$! define SYSTEM logical names for MDSplus servers used by RUNNSTX

\$ DEFINE/SYSTEM NSTX_DISPATCH KEES::DISPATCH_SERVER

\$ DEFINE/SYSTEM CAMAC_SERVER KEES::GKB2_SERVER

\$ DEFINE/SYSTEM NSTX_MON_SERVER KEES::MON_SERVER

**Determining if a server is installed**

To verify that a server task is installed, use NCP:

KEES\$ **mcr ncp**

NCP\>**show known objects**

Known Object Volatile Summary as of 17-AUG-2006 16:08:14

Object Number File/PID User Id Password

\$IPCACP 0 20C0040C

\$MOM 0

\$NICONFIG 0

**DISPATCH_SERVER**

**0 NSTX\$STARTUP:DISPATCH_SERV**

**20C00444 RONEY**

DWL_DECNET 0 SYS\$SYSTEM:DWL_DECNET.COM

**GKB2_SERVER 0 NSTX\$STARTUP:GKB2_SERVER.C**

**GKC2_SERVER 0 NSTX\$STARTUP:GKC2_SERVER.C**

**MON_SERVER 0 NSTX\$STARTUP:MON_SERVER.CO**

SMISERVER 0 20C00416

TASK 0 ILLEGAL

X\$X0 0 20C0043A

FAL 17 FAL.EXE

HLD 18

NML 19 NML.EXE NML\$SERVER

REMACP 23 20C00427

MIRROR 25 MIRRO\$SERVER

EVL 26

MAIL 27 MAIL_SERVER.EXE MAIL\$SERVER

PHONE 29 PHONE.EXE PHONE\$SERVER

CTERM 42 20C00427

VPM 51 VPM.EXE VPM\$SERVER

DTR 63

FINGER 117 FINGER

NCP\>

At the time of the report above on KEES, only the dispatch_server is
running. Note that ncp shows the pid of the task if it is currently
running.

KEES\$ shw \*disp\*

Pid Prcname Image State Pri CPU ppgcnt/wspeak Faults

**20C00444** dispatch_server MDSSERVER LEF 9/7 00:00:00.26 5360/8160
1669

KEES\$

DECnet strategy of process optimization and effects on MDSplus

Unlike Unix, where process creation is very computationally "cheap",
creating a process on VMS requires a lot of computation and reserves a
lot of resources. Installed DECnet tasks are assumed to be important
tasks which will probably be needed fairly often. So rather than incur
the process creation overhead every time installed processes are
re-invoked, DECnet keeps released processes around, changing their names
temporarily (to SERVER_nnnn running image NETSERVER) and holds them in
readiness for reuse for a while. (If they are not reused within some
period, they do actually go away). This has some interesting
consequences.

First, when we stop an mdsserver.exe task because it has somehow gotten
"confused" (TCL\> STOP SERVER KEES::DISPATCH_SERVER), we really want a
new process. To guarantee a fresh copy, a DCL stop must be issued
instead. (\$ STOP PROCESS/ID=\<PID\>). We need to "kill" the process,
not just stop it from TCL. *Check the PID and make sure it goes away*.

Second, when runnstx encounters a major problem, it stops some or all of
its servers. DECnet, of course, thriftily keeps the processes hanging
around. When runnstx then requests that the servers be started, the PID
for the process that was previously known as GKB2_SERVER may now be
attached to the name GKC2_SERVER. The processes after all are identical
except for process name and ID. This results in log files, which are
attached to the PID, showing the output from GKB2 for a while and then
GKC2, which can be very confusing when trying to track problems. This is
not a bug; it is a feature and does not cause any other trouble except
the scrambled log files. The same thing happens on LUNA between
FIRETIP_SERVER and HIGHK_SERVER. (It could also happen between
FIRETIP_SERVER and GKA2_SERVER, I think).

Immediately after test shots:

KEES\$ shw \*server\*

Pid Prcname Image State Pri CPU ppgcnt/wspeak Faults

20C00407 CLUSTER_SERVER CSP HIB 12/12 00:00:00.17 1136/1200 58

20C0040B FASTPATH_SERVER FASTPATH_SERHIB 10/10 00:00:00.01 1056/1440 75

20C0040E CACHE_SERVER FILESERV HIB 16/16 00:00:00.01 608/608 28

20C00410 AUDIT_SERVER AUDIT_SERVERHIB 8/8 00:00:00.13 2224/2496 125

20C00414 SECURITY_SERVER SECURITY_SERHIB 10/8 00:00:06.08 5792/7520 400

20C00415 ACME_SERVER ACME_SERVER HIB 8/8 00:00:00.05 6336/8160 361

20C00416 SMISERVER SMISERVER HIB 9/7 00:00:00.12 3232/3712 165

20C00417 TP_SERVER TPSERV HIB 8/8 00:00:17.21 1200/1504 72

20C0042A MULTINET_SERVER SERVER LEF 5/4 00:00:01.40 1808/5504 380

20C0043A DECW\$SERVER_0 DECW\$SERVER_HIB 8/6 00:00:00.2410816/12304 501

**20C0249D dispatch_server MDSSERVER** LEF 9/7 00:00:09.8358128/69264
8183

**20C024F1 gkb2_server MDSSERVER** LEF 9/7 00:00:02.7343072/47248 6237

**20C024F2 gkc2_server MDSSERVER** LEF 9/7 00:00:02.4336096/41264 5337

**20C024F6 mon_server MDSSERVER** LEF 9/7 00:00:00.28 5168/7024 1355

KEES\$

LUNA\$ shw \*server\*

Pid Prcname Image State Pri CPU ppgcnt/wspeak Faults

20A00407 CLUSTER_SERVER CSP HIB 14/12 00:00:00.60 1328/1760 78

20A0040D CACHE_SERVER FILESERV HIB 16/16 00:00:00.00 608/608 28

20A0040F AUDIT_SERVER AUDIT_SERVERHIB 8/8 00:00:00.00 2208/2480 124

20A00411 SECURITY_SERVER SECURITY_SERHIB 10/8 00:00:00.15 5792/7520 398

20A00412 ACME_SERVER ACME_SERVER HIB 8/8 00:00:00.07 6160/7984 354

20A00413 SMISERVER SMISERVER HIB 9/7 00:00:00.14 3232/3760 165

20A00414 TP_SERVER TPSERV HIB 8/8 00:00:01.21 1200/1504 72

20A0041A MULTINET_SERVER SERVER LEF 5/4 00:00:00.04 2064/5824 407

20A00426 NTP_SERVER NTPD LEF 6/4 00:00:00.86 4272/4928 321

**20A0049D gka2_server MDSSERVER** LEF 9/7 00:00:02.9842464/43904 8123

**20A0049E firetip_server MDSSERVER** LEF 9/7 00:00:00.61 6928/8560 1540

**20A0049F highk_server MDSSERVER** LEF 9/7 00:00:00.53 6928/8560 1540

LUNA\$

After stopping the "auxiliary" servers:

KEES\$ mov mds\$ppplroot:\[dispatcher\]

KEES\$ tcl

**TCL\> \@nstx_aux_servers stop**

TCL\> exit

KEES\$ shw \*server\*

Pid Prcname Image State Pri CPU ppgcnt/wspeak Faults

20C00407 CLUSTER_SERVER CSP HIB 12/12 00:00:00.18 1136/1200 58

.

.

**20C0249D dispatch_server MDSSERVER** LEF 7/7 00:00:19.7873296/84928
12756

**20C024F1 SERVER_0271 NETSERVER** LEF 4/4 00:00:05.59 2800/59552 8503

**20C024F2 SERVER_0270 NETSERVER** LEF 4/4 00:00:04.86 3024/58432 8392

**20C024F6 mon_server MDSSERVER** LEF 9/7 00:00:00.29 5168/7024 1355

KEES\$

LUNA\$ shw \*server\*

Pid Prcname Image State Pri CPU ppgcnt/wspeak Faults

20A00407 CLUSTER_SERVER CSP HIB 14/12 00:00:00.68 1328/1760 78

.

.

**20A0049D SERVER_0215 NETSERVER** LEF 4/4 00:00:03.00 2768/43904 8231

**20A0049E SERVER_0214 NETSERVER** LEF 4/4 00:00:00.62 2848/8560 1597

**20A0049F SERVER_0213 NETSERVER** LEF 4/4 00:00:00.53 2848/8560 1597

LUNA\$

### 3.2 MDSplus Action Nodes

##### 3.21 Components of an action node

![](media/image1.pct)

Figure 1 Traverser form for \\CAMERAS::FAST_CAMERA.RAWDATA:INIT_ACTION

An action node defines a "dispatch" structure and a task to be run,
along with other optional arguments. The dispatch structure includes the
server which is to be given the task to execute, the phase and priority
within the phase in which it is to be run, and an event to declare upon
successful completion.

The "type" in the dispatch structure is 1,2 or 3 for asynchronous,
sequential, or conditional (I think: TREE\$K_SCHED_ASYNC 1;
TREE\$K_SCHED_SEQ 2; TREE\$K_SCHED_COND 3, according to the TDI
documentation; but the drop-down list gives "Undefined", "Sequential",
and "Expression"; it's not clear that TYPE can be properly changed from
Traverser). All PPPL action nodes are of Type 2. Theoretically
dispatching can be dependency based rather than sequential with
priorities, in which case Type would be 1 or 3, presumably.

The TDI functions (full text in Appendix ###) are:

BUILD_ACTION
(DISPATCH,TASK,\[ERRORLOGS\],\[COMPLETION\],\[PERFORMANCE\])

BUILD_DISPATCH (TYPE,IDENT,PHASE,WHEN,COMPLETION)

To see the components of any action node in the tree without Traverser,
decompile the node in TCL:

TCL\> set tree cameras

TCL\> set def .fast_camera.rawdata

TCL\> decompile init_action

Build_Action(Build_Dispatch(2, \"KEES::GKC2_SERVER\", \"INIT\",10,
\"fast_camera_init\"),LIBRTL-\>LIB\$SPAWN(
\"@MDS\$ROOT:\[SYSMGR\]KODAK_INIT.COM\" // \$SHOTNAME), \"rmaqueda\")

In this example the components are:

Build_Action(

**DISPATCH** Build_Dispatch(

**TYPE** 2,

**IDENT**(**1)** \"KEES::GKC2_SERVER\",

**PHASE(2)** \"INIT\",

**WHEN (3)** 10,

**COMPLETION(4)** \"fast_camera_init\"),

**TASK** LIBRTL-\>LIB\$SPAWN(

\"@MDS\$ROOT:\[SYSMGR\]KODAK_INIT.COM\"//\$SHOTNAME),

**COMPLETION(5)** \"rmaqueda\")

\(1\) IDENT identifies server which is to carry out action (target of
dispatch)

\(2\) PHASE must be among those defined in
mds\$root:\[tdi\]phase_table.fun if it is to actually get dispatched;
NSTX uses only INIT and STORE; non-defined phase names are routinely
used to avoid dispatching, which is desirable under certain conditions
(if a node is off, even a test routine cannot execute the action; if it
merely is in an undefined phase, the dispatcher ignores it but testing
or calibration may continue, using "DO/METHOD")

\(3\) WHEN is actually dispatching priority; default is usually 50, so
"10" means 'run this extremely early in its phase' (this action wrote a
shot-number notification file that a PC-based diagnostic was polling to
know the shot was coming)

\(4\) Dispatch COMPLETION *here* is the name of the MDSplus event to
declare if the action completes successfully; the event also contains
the shot number for which the event was declared (in the rather strange
case above, success means the spawn occurred, not that the command
procedure succeeded)

\(5\) Action COMPLETION Description in BUILD_ACTION help says there
should be a field before this one, but apparently that is not correct.
This is the account to notify on failure (uses broadcast, not e-mail.)
Not generally used on NSTX, in spite of this example.

A Typical CAMAC STORE Action

![](media/image2.png){width="4.352083333333334in"
height="2.5840277777777776in"}

Figure 2 Traverser form for \\PSPEC_RAW::FV_H908:STORE_ACTION

"Ident" tells the Dispatcher to hand this action off to the C highway
CAMAC server which is on KEES. "Sequence" (priority) of 54 means that
this module will be acquired somewhat late in the C highway acquisition
sequence. Acquisition is accomplished by running the "STORE" method of
the device described inside the \\FV_H908_02 node (H908T in the
PPPL\$DEVICES.EXE sharable library, see TCL below). The actual method
called will be H908T\$STORE, a wrapper for H908T\$\$STORE, the C module
written to support our local H908 slow digitizer. There is no
relationship between the phase name STORE and the method name STORE
except convenience. If the method is successful, an MDSplus event will
be issued with name FV_H908_02_ACQ (not case sensitive) and with the
current shot number in the data field.

On NSTX we never set the Timeout field.

KEES\$ tcl

TCL\> set tree pspec_raw

TCL\> set def .filtered_vis.rawdata

TCL\> **decompile fv_h908_02**

Build_Conglom(\"PPPL\$DEVICES\", \"H908T\", \*, \*)

TCL\>

TCL\> set def fv_h908_02

TCL\> **decompile store_action**

Build_Action(Build_Dispatch(2, \"kees::gkc2_server\", \"STORE\", 54,
\"FV_h908_02_acq\"), Build_Method(\*, \"STORE\", \\FV_H908_02), \"\")

TCL\>

.

Dispatching to remote MDSplus servers: FIReTIP and High-K Scattering

![](media/image3.png){width="5.223611111111111in"
height="3.6743055555555557in"}

Figure 3 High-K Scattering STORE_ACTION with CPCI node name in device
form

Currently there are two remote data-acquisitions systems, both
Linux-based, running MDSplus servers and directly integrated into the
NSTX MDSplus dispatch sequence. They contrast with the dozen or more
other remote systems, mostly PC-based, which only store their data in
the tree, and are responsible for synchronizing themselves with the shot
cycle, usually by polling for the current shot number.

For these two, FIReTIP and High-K Scattering, MDSplus tells a server
running on VMS to execute a store method written in TDI which asks a
remote host (identified as "CPCI node name" in the device form) to
execute another TDI method locally and send the answer back. The server
on VMS declares the event on success. We define a separate server for
each of these systems (on Luna, but it could be anywhere) because of
problems with FIReTIP hanging and preventing anything after it in the
dispatch queue from running. More about this later.

No shareable library is defined in this case (there is an asterisk in
the library field of the device definition):

TCL\> set tree microwav_raw

TCL\> set def .highk.rawdata

TCL\> decompile HK_DTACQ16_1

Build_Conglom(\*, \"DTACQ16\", \*, \*)

MDSplus will look in MDS\$PATH for a TDI routine with name mapped to the
device ("DTACQ16") and method (STORE). In this case it will find
DTACQ16\_\_STORE.FUN.

Directory MDS\$MITROOT:\[TDI.DEVICES\]

DTACQ16\_\_ADD.FUN;4

DTACQ16\_\_INIT.FUN;3

DTACQ16\_\_PART_NAME.FUN;2

DTACQ16\_\_STORE.FUN;34

The uses of the ADD and PART_NAME functions will be discussed later.
Within DTACQ16\_\_STORE.FUN is an explicit connect to the remote host:

\_status = MdsConnect(\_node);

if ((\_status \< 0) && (\_node != \'local\')) {

Write(\*,\"Could not connect to \"//\_node);

Abort();

}

MDSplus takes care of passing "CPCI node name" as the \_node argument.

**Action Node successful completion events** (used for Scope update
events and to synchronize between-shot analysis)

CAMAC Diagnostic convention: \<digraph\>\_\<devicenodename\>\_acq

> e.g.

EPICS convention

\<engineeringtreebranchcode\>\_\<modulewithcrateandslot\>\_acq

e.g. PC_908C16N08_ACQ means that the H908 in slot 8 of EPICS crate 16

was successfully acquired

PC for Power conversion, GS for Gas, TC for thermocouple

Other event naming conventions

PC-based diagnostics typically have no associated device nodes
containing event names that MDSplus will declare. If they declare events
on success (or failure), they do it from within the code that runs on
the PC. Usually the event ends with either \_acq or \_done, but it is
necessary to ask someone associated with the programming of the
acquisition to discover the exact term used and whether only one final
success event is declared or if events are declared for each
successfully acquired subsystem.

**More about Priorities**

The convention in device support programs has been to set the default
sequence (priority) value to 50 when a new device node is added to a
tree. Lower numbers are executed earlier. Theoretically any of the
owners of a tree can change the priority of an action; in practice,
action nodes are obscure enough that only the programmers ever touch
them. (OPERATIONS actions, which are written from a script run by the
physicist, are exceptions.)

To support the objectives of NSTX, some modules must be acquired as
early as possible. On the B highway this includes the various Magnetics
908s in the OPERATIONS tree (with priority set by the scripts just
mentioned). On the C highway the two 908s with the basic engineering
field currents (\\ENGINEERING::PC_H908_01 and \_02) get absolute top
priority; they are needed for EFIT along with some of the B highway
Magnetics. Next in priority on C come the Thomson Scattering (TS) 908s.
As a rule of thumb, if the priority is 50 or more and is going to stay
50 or more, it is safe to change.

**Synchronizing EPICS and MDSplus: runnstx**

> NSTX_CREATE_INIT_TIME (system logical name table; need SYSPRV or
> SYSNAM privilege to set; default is --60 seconds)
>
> MDS\$PPPLROOT:\[DISPATCHER\]NSTX_CREATE_INIT.TCL
>
> declares events NSTX_SHOTTREE_CREATED,
>
> NSTX_DISPATCHBUILD_DONE, NSTX_INITPHASE_DONE, DWSCOPE_CLOSE_FILES
>
> MDS\$PPPLROOT:\[DISPATCHER\]NSTX_STORE.TCL
>
> declares NSTX_ACQ_STARTED, NSTX_FENX_SHOTFLAG (for EFIT processing),
> NSTX_ACQ_DONE
>
> (RECOVER.TCL was formerly used to manually run STORE phase if RUNNSTX
> aborted processing due to INIT phase timeout. Currently runnstx
> continues on to STORE phase if INIT phase times out, presuming that a
> hung DTACQ16-server is the cause)

**Detecting and removing hung servers**

When the INIT phase does not complete by T-7 seconds, the event
NSTX_INIT_TIMEOUT is declared, although processing is not cancelled.
MDS\$ROOT:\[DISPATCHER\]NSTX_CREATE_INIT.TCL will subsequently declare
NSTX_INITPHASE_DONE regardless of success or failure.

There are several possible causes for the INIT phase not being able to
complete, but one common one relates to hung communication with remote
MDSplus servers on either firetip-daq.pppl.gov or rftd.pppl.gov (High-k
scattering). Usually the problem has been with FIReTIP.

To permit the rest of the data acquisition to proceed, the DCL procedure
MDS\$PPPLROOT:\[DISPATCHER\]NSTX_STOP_SPECIAL_SERVERS.COM installed in
batch queue \*\*\*BATCHQUEUE\*\*\* is always waiting for the
NSTX_INIT_TIMEOUT event, and will terminate the MDSplus servers
FIRETIP_SERVER and HIGHK_SERVER on LUNA. (It is not sufficient The
servers will automatically be restarted by the dispatcher. Eventually
the DCL procedure will also send e-mail notification, though it
currently does not.

####### Action Monitor

*The following two sections are currently verbatim from an old MIT
MDSplus web document at:*

> <http://www.mdsplus.org/old/gettingstarted/graphicinterfaces.html>

d\. Action Monitor

The Action Monitor is a graphical display listing all actions that are
part of the MDSplus shot cycle. The display consists of three windows,
one above the other. The top window lists all the actions that are to be
performed during the shot in the order that the MDSplus dispatch server
is to start them. It also lists their present status at any given time.
The middle window lists the actions as they are dispatched and again
every time that their status changes. Also, they are highlighted in this
list until they are complete. This makes it easy to find the active
actions. The status possibilities include \"DISPATCH\", \"DOING\" and
\"DONE\". This middle window is very active because the reports can
scroll by very quickly. The lower window lists all the actions that
ended with error status. This shows quickly and easily what actions did
not complete successfully. The method to start the Action Monitor is
given in Table 4 below.

The Action Monitor will not start monitoring operations in mid cycle.
Regardless of the activity taking place, no actions information will be
displayed until the next time that the cycle enters the Initialization
phase. Also, the top window will display the actions list only if it is
open when the dispatch server creates the list of actions for the cycle
during the initialization phase. If the top window is closed, however,
the two other windows will display information normally.

The default settings are shown below in Figure 5. Only the bottom window
is displayed when the default settings are employed. The \"Action
Outline Off\" controls the display of the top window. The \"\"Action Log
Off\" controls display of the middle window. Use the \"sashes\" to
control the size of the three windows.

![](media/image4.jpeg){width="3.93125in" height="2.1645833333333333in"}

(MIT Figure 5) Default settings in the Options pull down menu of the
Actions Monitor

e\. Actions List

The Actions graphical display lists all the actions in the tree in the
phase and sequence in which they are scheduled to be executed by MDSplus
(Figure 6). Actions preceded by an asterisk are critical to the cycle.
The implementation of testing for completion of critical actions depends
on the site using MDSplus. For the C-Mod experiment, if an
initialization phase critical action ends with error status, the cycle
will not continue. If this happens, it is usually necessary to back out
of the init phase to return to recool and restart the cycle. In other
stages, no testing is done for the successful completion of critical
tasks.

If one of the actions is clicked on with the mouse, a window opens
(Figure 7) that is similar to a node\'s \"Display Data\" pop-up window
which is accessed through the Traverser. Any of the settings displayed
can be modified and written back into the tree. However, it is not
possible to turn the node on or off from this window; nor is it possible
to alter any tag names for the node. Actions are made to be critical by
double clicking on them in the Actions display while the Display Data
window for that action is open.

> ![](media/image5.jpeg){width="4.305555555555555in"
> height="3.495833333333333in"}
>
> (MIT Figure 6) - Small sample of the actions executed in the C-Mod
> shot cycle.

![](media/image6.png){width="6.597222222222222in"
height="4.981944444444444in"}

*End of excerpt from MIT MDSplus web document*

Log files and log file comparisons

Our convention is to put log files for all programs the software group
supports into some subdirectory of NSTX\$:\[LOGS\]. These currently are:

KEES\$ mov nstx\$:\[logs\]

NSTX\$:\[LOGS\]

KEES\$ mov?

Subdirectories of NSTX\$:\[LOGS\]

ACQREMOTE CAMAC CHECKQUEUES DB EVENTS MPTS RF RUNNSTX

SQLSERVER TC_MON VGDS

KEES\$

The logs of most interest for running MDSplus are in
NSTX\$:\[LOGS.RUNNSTX\]. Each of the processes running mdsserver.exe
writes a log file with the process name and the date it was started.
There are often several versions of these in a day. At midnight these
processes are all stopped, to be restarted the next day if NSTX is
running. As a side-effect of changes made last run, the auxiliary
servers do not always stop. If they are running before the first shot
has been taken, it is good practice to restart runnstx (symbol:
**restart_mdsacq**). runnstx.exe also creates a dated log file. In
addition, it appends slightly more information to runnstx.log, for which
a new version gets created only when runnstx.exe gets stopped from DCL
and restarted (manually or by a reboot). runnstx.exe was manually
restarted and MDSplus was tested Monday, August 21, so we have (asking
for most recent versions only by appending ";" to filename):

KEES\$ dirw \*\_060821.log;

Directory NSTX\$:\[LOGS.RUNNSTX\]

DISPATCH_SERVER_060821.LOG;1 186/186 21-AUG-2006 07:56:49.36

FIRETIP_SERVER_060821.LOG;2 2/3 21-AUG-2006 13:50:06.14

GKA2_SERVER_060821.LOG;2 34/36 21-AUG-2006 13:50:05.45

GKB2_SERVER_060821.LOG;2 41/42 21-AUG-2006 13:51:08.71

GKC2_SERVER_060821.LOG;2 47/48 21-AUG-2006 13:51:09.46

HIGHK_SERVER_060821.LOG;2 2/3 21-AUG-2006 13:50:06.81

MON_SERVER_060821.LOG;1 0/0 21-AUG-2006 13:51:25.38

RUNNSTX_060821.LOG;2 4/6 21-AUG-2006 07:56:48.50

Total of 8 files, 316/324 blocks.

KEES\$

KEES\$ dirw runnstx.log;

Directory NSTX\$:\[LOGS.RUNNSTX\]

RUNNSTX.LOG;516 601/606 21-AUG-2006 07:56:47.87

######### COMPARE_INIT_TIMES.COM, COMPARE_STORE_TIMES.COM

These command procedures search through the data acquisition logs for
information about order of execution and elapsed time; they reside in
the same directory as the log files.

If you forget the arguments, the procedure reminds you:

KEES\$ **\@compare_init_times**

Required params are GK_FILENAME SHOT1 \[ SHOT2 \]

for example: gkc2_server_020507.log 108128 108129

In the single shot argument case the second column indicates the number
of (truncated integer) seconds to complete the previous operation. In
the two shot case, the third column gives the difference in times for
the same task for the two shots. In both cases the column beneath the
shot number indicates the time into the shot cycle that the task
executed. The A highway is used in these examples because it produces
the shortest meaningful listing. The FIReTIP and HIGHK server logs can't
be examined this way; there is only one action each for each phase.

KEES\$ **\@compare_init_times gka2_server_060517.log 120670**

Time 120670 elapsed MDSplus device

(hh:mm:ss) (+sec) (sec) \-\-\-\-\-\-\-\-\-\-\-\-\--

08:00:57 0 ( 0) PARTICLES.NPA.RAWDATA:EN_H911_04

08:00:58 1 ( 1) PARTICLES.NPA.RAWDATA:EN_H911_03

08:00:58 1 ( 0) PARTICLES.NPA.RAWDATA:EN_H911_02

08:00:58 1 ( 0) PARTICLES.NPA.RAWDATA:EN_H911_01

08:00:58 1 ( 0) MICROWAVE.MICROWAV_RAW.EBW.RAWDATA:EB_H404_01

08:00:58 1 ( 0) PARTICLES.NPA.RAWDATA:EN_H412_01

08:00:58 1 ( 0) MICROWAVE.MICROWAV_RAW.FIRETIP.RAWDATA:FT_H404_01

08:00:58 1 ( 0) PARTICLES.SFLIP.RAWDATA:SF_H904_01

08:00:59 2 ( 1) PARTICLES.SSNPA.RAWDATA:SN_H412_01

08:00:59 2 ( 0) PARTICLES.SSNPA.RAWDATA:SN_H404_01

08:00:59 2 ( 0) PARTICLES.SFLIP.RAWDATA:SF_H412_01

08:00:59 2 ( 0) PARTICLES.SFLIP.RAWDATA:SF_H404_01

08:00:59 2 ( 0) CAMERAS.CANPHOTON.RAWDATA:CP_H412_01

08:00:59 2 ( 0) CAMERAS.FASTSOFTXRAY.RAWDATA:FX_H408_01

08:00:59 2 ( 0) EDGE.DEPOSITION.RAWDATA:DM_H409_01

08:00:59 2 ( 0) OPERATIONS.RAWDATA:LM_H404_01

08:00:59 2 ( 0) OPERATIONS.RAWDATA:LM_H409_01

08:00:59 2 ( 0) OPERATIONS.RAWDATA:LM_H908_01

08:00:59 2 ( 0) OPERATIONS.RAWDATA:LM_H908_02

08:00:59 2 ( 0) EDGE.FASTPROBES.RAWDATA:FP_H404_01

08:00:59 2 ( 0) EDGE.FASTPROBES.RAWDATA:FP_TR612_01

08:00:59 2 ( 0) PARTICLES.IFLIP.RAWDATA:FI_H908_01

08:00:59 2 ( 0) PARTICLES.NPA.RAWDATA:EN_H320_01

08:00:59 2 ( 0) PARTICLES.NPA.RAWDATA:EN_H320_02

08:00:59 2 ( 0) EDGE.FASTPROBES.RAWDATA:FP_H409_01

08:00:59 2 ( 0) PARTICLES.IFLIP.RAWDATA:FI_H404_01

08:00:59 2 ( 0) PASSIVESPEC.PSPEC_RAW.HARD_XRAY.RAWDATA:XH_H908_01

08:00:59 2 ( 0) EDGE.FASTPROBES.RAWDATA:FP_TR612_02

08:00:59 2 ( 0) EDGE.FASTPROBES.RAWDATA:FP_TR612_03

08:00:59 2 ( 0) PARTICLES.CENA.RAWDATA:CN_TR612_01

08:00:59 2 ( 0) PASSIVESPEC.PSPEC_RAW.GRITS.RAWDATA:GR_H404_01

08:00:59 2 ( 0) PASSIVESPEC.PSPEC_RAW.GRITS.RAWDATA:GR_H412_01

08:01:03 6 ( 4) PARTICLES.NPA.RAWDATA:EN_H322_04

08:01:03 6 ( 0) PARTICLES.NPA.RAWDATA:EN_H322_03

08:01:03 6 ( 0) PARTICLES.NPA.RAWDATA:EN_H322_01

08:01:03 6 ( 0) PARTICLES.NPA.RAWDATA:EN_H322_02

08:04:28 211 (205) PARTICLES.NPA.RAWDATA:EN_H404_01

08:04:28 211 ( 0) PASSIVESPEC.PSPEC_RAW.HARD_XRAY.RAWDATA:XH_H404_01

Shot 120670 start at 08:00:57.92 17-MAY-2006

I = 38

KEES\$

The NPA and X-ray PHA (EN, XH) H404 timing modules display
strange-looking times because their INIT methods run in the STORE phase,
not the INIT phase. At least one of the H404 channels in each must have
been set to T-60 or earlier to make this necessary.

KEES\$ **\@compare_store_times gka2_server_060517.log 120670 120671**

120670 120671 (diff) MDSplus device

(+sec) (+sec) \-\-\-\-\-\-\-\-\-\-\-\-\--

0 0 ( 0) PARTICLES.NPA.RAWDATA:EN_H911_04

1 0 ( -1) PARTICLES.NPA.RAWDATA:EN_H911_02

1 1 ( 0) PARTICLES.NPA.RAWDATA:EN_H911_03

1 1 ( 0) CAMERAS.FASTSOFTXRAY.RAWDATA:FX_H408_01

2 1 ( -1) PARTICLES.NPA.RAWDATA:EN_H911_01

3 3 ( 0) OPERATIONS.RAWDATA:LM_H908_01

4 4 ( 0) OPERATIONS.RAWDATA:LM_H908_02

5 5 ( 0) PARTICLES.NPA.RAWDATA:EN_H322_04

5 5 ( 0) PARTICLES.NPA.RAWDATA:EN_H320_01

5 5 ( 0) PARTICLES.NPA.RAWDATA:EN_H322_01

5 5 ( 0) PARTICLES.NPA.RAWDATA:EN_H320_02

6 5 ( -1) PARTICLES.NPA.RAWDATA:EN_H322_02

6 5 ( -1) PARTICLES.NPA.RAWDATA:EN_H322_03

6 5 ( -1) PARTICLES.IFLIP.RAWDATA:FI_H908_01

6 6 ( 0) EDGE.FASTPROBES.RAWDATA:FP_TR612_02

57 57 ( 0) EDGE.FASTPROBES.RAWDATA:FP_TR612_01

103 104 ( 1) EDGE.FASTPROBES.RAWDATA:FP_TR612_03

149 150 ( 1) PARTICLES.CENA.RAWDATA:CN_TR612_01

154 154 ( 0) PASSIVESPEC.PSPEC_RAW.HARD_XRAY.RAWDATA:XH_H908_01

Shot 120670 start at 08:01:43.88 17-MAY-2006

Shot 120671 start at 08:11:43.57 17-MAY-2006

I = 19

KEES\$

Searching logfiles

There is no procedure to report on the runnstx logs, but the search
command can give a lot of information. To check the variation among INIT
phase elapsed times (maybe to decide if NSTX_CREATE_INIT_TIME needs to
be increased or decreased):

KEES\$ **sea runnstx_060517.log elapsed,\"(-\"/match=and**

\--\> \... elapsed time = 45 sec (-00:30) 17-May-2006 08:01:08

\--\> \... elapsed time = 40 sec (-00:35) 17-May-2006 08:11:03

\--\> \... elapsed time = 46 sec (-00:29) 17-May-2006 12:30:13

\--\> \... elapsed time = 53 sec (-00:22) 17-May-2006 15:02:38

\--\> \... elapsed time = 47 sec (-00:28) 17-May-2006 15:13:28

\--\> \... elapsed time = 48 sec (-00:27) 17-May-2006 15:23:28

\--\> \... elapsed time = 47 sec (-00:28) 17-May-2006 16:01:30

\--\> \... elapsed time = 42 sec (-00:33) 17-May-2006 16:16:25

\--\> \... elapsed time = 42 sec (-00:32) 17-May-2006 16:31:26

\--\> \... elapsed time = 41 sec (-00:34) 17-May-2006 16:51:24

\--\> \... elapsed time = 37 sec (-00:38) 17-May-2006 17:01:20

KEES\$

Similarly for the STORE phase:

KEES\$ **sea runnstx_060517.log elapsed,\"(+\"/mat=and**

\--\> \... elapsed time = 165 sec (+02:54) 17-May-2006 08:04:32

\--\> \... elapsed time = 164 sec (+02:53) 17-May-2006 08:14:31

\--\> \... elapsed time = 167 sec (+02:55) 17-May-2006 12:33:37

\--\> \... elapsed time = 166 sec (+02:55) 17-May-2006 15:05:55

\--\> \... elapsed time = 168 sec (+02:56) 17-May-2006 15:16:52

\--\> \... elapsed time = 168 sec (+02:57) 17-May-2006 15:26:52

\--\> \... elapsed time = 168 sec (+02:57) 17-May-2006 16:19:55

\--\> \... elapsed time = 170 sec (+02:59) 17-May-2006 16:34:57

\--\> \... elapsed time = 168 sec (+02:56) 17-May-2006 16:54:54

\--\> \... elapsed time = 176 sec (+03:05) 17-May-2006 17:05:03

KEES\$

The times in parentheses above are the facility clock times at the
completion of the phase; the date-times at the end of the line are the
times at which the entry in the log file was made.

To check quickly for the most common problems from the acquisition
servers:

KEES\$ **sea \*\_060627.log;\* retry,scc,\"-FLK\"**

NSTX\$:\[LOGS.RUNNSTX\]GKC2_SERVER_060627.LOG;1

\--\> 13:36:06 retryCnt=1 for SFR_L6810_01 chan 0 seg 0

KEES\$

Notice the ";\*" at the end of the file name. On a bad day, there can be
many versions of some of the logs. We want to look through all of them.

The search line above is checking for CAMAC highway problems and MDSplus
file contention problems. Highway synchronization problems result in the
message:

%CAM-E-SCCFAIL, serial crate controller failure

Several of the CAMAC methods are programmed to retry on error; a noisy
highway would result in a lot of errors like:

\--\> 10:39:50 retryCnt=3 for SFW_H908_06 chan 20

Unresolved contention in writing to tree files produces an RMS-E-FLK
error (file is locked and retries have been exhausted).

**4.0 Device support**

Adding an already supported device

New device nodes are typically added using Traverser and selecting from
the list of devices offered under Edit/Add Device (figure below). It is
also possible to add devices directly from TCL using\
TCL\> ADD NODE/MODEL=devicename nodename,\
e.g.\
TCL\> ADD NODE/MODEL=L6810BPPPL \\TOP.CHI.RAWDATA:HI_L6810_01 .

The list of devices is built from MDS\$DEVICES.OLB (from \<device\>\$ADD
entry points in its component device libraries) and from devices
supported in TDI language found in MDS\$PATH (\<device\>\_\_ADD.FUN).

MDS\$ROOT:\[SYSLIB\]MDS\$DEVICES.OLB is a library of shareable images of
device support modules:

KEES\$ **librar/list mds\$root:\[syslib\]mds\$devices.olb**

Directory of ALPHA SHAREABLE IMAGE SYMBOL TABLE library
MDS\$PPPLROOT:\[SYSLIB\]MDS

\$DEVICES.OLB;10 on 23-AUG-2006 09:09:28

Creation date: 28-JUL-2000 14:30:44 Creator: Librarian A09-19

Revision date: 3-NOV-2005 16:48:34 Library format: 3.0

Number of modules: 4 Max. key length: 39

Other entries: 449 Preallocated index blocks: 58

Recoverable deleted blocks: 1 Total index blocks used: 60

Max. Number history records: 20 Library history records: 20

HYBRID\$DEVICES

MIT\$DEVICES

PPPL\$DEVICES

RCPDAQ\$DEVICES

KEES\$

(Full entry-point listing in Appendix ###)

HYBRID\$DEVICES.EXE and MIT\$DEVICES.EXE were supplied with MDSplus;

PPPL\$DEVICES.EXE contains the software written at PPPL for PPPL
devices. RCPDAQ\$DEVICES contains device support for the GL_AD1020
digitizer written at PPPL for the RCPDAQ VMS system at General Atomics
(Rick Moyer, Jose Boedo; Fast Probes).

PPPL\$DEVICES.EXE is built from
NSTX0:\[MDSPLUS_LOCAL.CAMAC\]PPPL\$DEVICESLNK.COM (listing in Appendix
###), and the result copied to MDS\$PPPLROOT:\[SYSLIB\]. Directories of
source code reside below NSTX0:\[MDSPLUS_LOCAL.CAMAC\]. We don't have
link files for the MIT libraries.

![](media/image7.png){width="2.810416666666667in"
height="6.454861111111111in"}

MDSPLUS\$PATH .FUN routines:

KEES\$ dir **mds\$root:\[tdi.devices\];**

Directory MDS\$PPPLROOT:\[TDI.DEVICES\]

DTACQ16\_\_INITTRIGGER.FUN;3

Total of 1 file.

Directory MDS\$MITROOT:\[TDI.DEVICES\]

**A12\_\_ADD.FUN**;4 A12\_\_INIT.FUN;3 A12\_\_PART_NAME.FUN;4

A12\_\_STOP.FUN;3 A12\_\_STORE.FUN;3 A12\_\_TRIGGER.FUN;3

BAD_DTACQ16\_\_STORE.FUN;1 BAD_DTACQ16\_\_STORE_1.FUN;1

BAD_DTACQ16\_\_STORE_2.FUN;1 DT100GETNUMCHANNELS.FUN;1

DT100GETNUMSAMPLES.FUN;1 DT100INIT.FUN;1

DT100READCHANNEL.FUN;1 DT100WRITEMASTER.FUN;1

**DT100\_\_ADD.FUN**;2 DT100\_\_INIT.FUN;3 DT100\_\_PART_NAME.FUN;2

DT100\_\_STORE.FUN;5 **DT101\_\_ADD.FUN**;9 DT101\_\_INIT.FUN;8

DT101\_\_PART_NAME.FUN;5 DT101\_\_STORE.FUN;26

**DTACQ16\_\_ADD.FUN**;4 DTACQ16\_\_INIT.FUN;3
DTACQ16\_\_PART_NAME.FUN;2

DTACQ16\_\_STORE.FUN;34 **DT_ACQ16\_\_ADD.FUN**;1

DT_ACQ16\_\_INIT.FUN;1 DT_ACQ16\_\_PART_NAME.FUN;1

DT_ACQ16\_\_STORE.FUN;1 MDSDEVICES.FUN;1

MITDEVICES.FUN;6

Total of 32 files.

KEES\$ **dir mdsplus\$:\[pppl\]\*904\*.fun**;

Directory MDSPLUS\$:\[PPPL\]

**H904\_\_ADD.FUN**;13 H904\_\_INIT.FUN;38 H904\_\_PART_NAME.FUN;6

Total of 3 files.

Once the device node is added, it is usually also configured in
Traverser using the device setup form:

![](media/image8.png){width="2.557638888888889in"
height="2.1104166666666666in"}![](media/image9.png){width="3.691666666666667in"
height="3.70625in"}

Figure 4 Setup Device command and L8212 device setup form

The device setup form is generated from an X-windows MOTIF UID file,
which is the result of compiling a UIL (User Interface Language) ASCII
form description with the MDSplus widgets library. During a recent VMS
minor upgrade, the uil/motif program produced errors with files that had
previously worked. The older uil.exe program was brought over from an
earlier version MIT system and needs to be defined before doing any
compiles now:

> **\$ set command mds\$root:\[sysexe\]uil**
>
> **\$ uil/motif/widget=xmdsuil h404.uil**

Without such a file, a device could still be used; it would simply be
necessary to enter the necessary data into each device subnode
individually. (I believe some U Washington devices are configured from
IDL GUI's rather than MOTIF forms.) This, in fact, is the case for PPPL
users on Unix, because the UID files and even the UIL files are not
compatible; a separate set of MDSplus widget names must be used in
changing a VMS UIL file to one usable on Unix. (Listing of VMS UID files
in Appendix ###.)

Access to the setup for the action nodes is via the buttons at the
bottom of the device setup form (Init Action and Store Action shown
here; some devices have only one action).

**Supporting new devices in MDSplus**

**BUILD_CONGLOM() example spelled out better**

As mentioned in the section on Action Nodes, MDSplus normally calls
wrapper methods of the form \<devicename\>\$\<phasename\> which in turn
call routines \<devicename\>\$\$\<phasename\>, all of which are defined
in the library specified in the device node. (If no library is
specified, TDI support is assumed.)

Originally the preferred development method was to edit a
\<devicename\>.GEN file (written, apparently, in YACC) and then process
it **\[SYNTAX,example\]** into a \<devicename\>\_GEN.C and
\<devicename\>.H file. The GEN file specifies all the data nodes and can
include valid data values or ranges and error messages to be generated
if configured values do not agree. The \<devicename\>. H file would then
be included in the code directly related to setting up or reading out
the device. The calling sequences for the
\<devicename\>\$\$\<phasename\> routines are established in the
\<devicename\>\_GEN.C programs, where the \<devicename\>\$\<phasename\>
procedures are defined.

The \*\_GEN.C files also contain the methods for creating the structures
("conglomerates") needed for the device when adding a device to a tree
from Traverser or TCL. Any value checking specified in the .GEN file is
also done in the autogenerated \_GEN.C code. Most of the mechanics of
getting configuration information out of tree nodes is handled in the
\*\_GEN.C routines.

\<device\>.GEN, compiled with GEN_DEVICE/SINGLE/SUFFIX=\_GEN
\<device\>.gen

to create \<device\>\_GEN.C

\<device\>.C with all the modules called from \<device\>\_GEN

(\"\$\$\" versions of the \"\$\" methods) and \<device\>\$DW_SETUP,

the device setup code (written in Motif with Xmds widgets)

***EXAMPLE***

At least two generations of C-based support can be seen in the source
code from MIT (which we were able to see during the time we had their
VMS source disk NFS-mounted on Birch; files downloaded during that time
are at COLLAB:\[BE1.NSTX.MDSPLUS.MITSOURCE\]), with the earlier versions
piecing together descriptors in a fairly complex way, and the later
modules using a TDI\$COMPILE() call to do all that work for us.
Simplifying with TDI was then taken one more step, and at this point the
recommendation is pretty much to skip the GEN, C, stuff and do the whole
thing in TDI.

By convention, directories for new devices supported in C are created
beneath MDSPLUS_LOCAL\$:\[CAMAC\].

KEES\$ **dir mdsplus_local\$:\[camac\];**

Directory NSTX0:\[MDSPLUS_LOCAL.CAMAC\]

DBGERR.LOG;2 DD.TCL;3 DEFS.COM;3 DEV\$MESSAGES.MSG;1

DEV\$MESSAGES.OBJ;1 DTACQ16.DIR;1 GL1020.DIR;1 H320.DIR;1

H321.DIR;1 H322.DIR;1 H356.DIR;1 H404.DIR;1

H408.DIR;1 H409.DIR;1 H412.DIR;1 H904.DIR;1

H908.DIR;1 H911.DIR;1 H912R.DIR;1 I1148.DIR;1

IDL_CAM\$\_SUMMARY.TXT;1 J224.DIR;1 KS3421.DIR;1

KS3525.DIR;1 L4202ONLY.DIR;1 L6810.DIR;1 L6810B.DIR;1

L6810ED.DIR;1 L8801.DIR;1 MESSAGES.MSG;7 MESSAGES.OBJ;6

MIT_MESSAGES.MSG;1 MIT_MESSAGES.OBJ;1 PPPL\$DEVICES.EXE;261

PPPL\$DEVICESLNK.COM;76 RCPDAQ\$DEVICES.EXE;47

RCPDAQ\$DEVICESLNK.COM;9 RCPDAQ\$DEVICESLNK.COM_WDECW;1

T4012.DIR;1 T4012NOX.DIR;1 T4032.DIR;1 TR612.DIR;1

Total of 42 files

Writing new device support in TDI

If pure TDI support is written, add the new device name to
MDS\$ROOT:\[TDI.DEVICES\]MDSDEVICES.FUN in order to make it show up in
the "Edit/Add Device" page of Traverser.

An excellent description of writing device support partly with
automatically generated C code and partly with TDI functions can be
found at

http://plasma.aa.washington.edu/mdsplus/LocalDeviceDevelopment/writing_drivers.html

(For convenience, the September 2006 versions of this page and the code
examples it linked to are duplicated here in Appendix XXX. The TDI
INIT.FUN and STORE.FUN in those examples are more thoroughly commented
than the A12 example below.)

\[ H904 is in MDSPLUS\$:\[PPPL\], but probably it should be in
MDS\$PPPLROOT:\[TDI.DEVICES\].\] DTACQ16 is still in
MDS\$MITROOT:\[TDI.DEVICES\] even though it was modified here. The
trigger routine, now originally provided by MIT, does reside in
MDS\$PPPLROOT:\[TDI.DEVICES\].

As in C, providing TDI device support requires two MDSplus methods, ADD
and PART_NAME, plus as many CAMAC methods as desired, usually at least
INIT and STORE. The Joerger A12 digitizer is given as an example. The
ADD and PART_NAME methods are supplied via the \<devicename\>\_GEN.C
routine, generated automatically. For TDI support, they are written
explicitly, making use of a set of TDI device support routines in
MDS\$ROOT:\[TDI.DEVICE_SUPPORT\] that call into the tree libraries.

KEES\$ dir **mds\$root:\[tdi.device_support**\];

Directory MDS\$MITROOT:\[TDI.DEVICE_SUPPORT\]

DEVADDACTION.FUN;4 DEVADDEND.FUN;4 DEVADDNODE.FUN;4 DEVADDSTART.FUN;11

DEVCAMCHK.FUN;4 DEVHEAD.FUN;4 DEVISON.FUN;4 DEVNODEREF.FUN;4

DEVPUTSIGNAL.FUN;4 DEVPUTSIGNALNOBOUNDS.FUN;2

Total of 10 files.

public fun **a12\_\_add**(in \_path, out \_nidout)

{

DevAddStart(\_path,\'A12\',25,\_nidout);

DevAddNode(\_path//\':A12NAME\',\'TEXT\',\*,\*,\_nid);

DevAddNode(\_path//\':COMMENT\',\'TEXT\',\*,\*,\_nid);

DevAddNode(\_path//\':EXT_CLOCK_IN\',\'AXIS\',\*,\'/noshot_write\',\_nid);

DevAddNode(\_path//\':STOP_TRIG\',\'AXIS\',0.,\'/noshot_write\',\_nid);

for (\_c=1;\_c\<7;\_c++)

{

\_cn = \_path//\':INPUT\_\'//TEXT(\_c,1);

DevAddNode(\_cn,\'SIGNAL\',\*,\'/write_once/compress_on_put/nomodel_write\',\_nid);

DevAddNode(\_cn//\':STARTIDX\',\'NUMERIC\',\*,\'/noshot_write\',\_nid);

DevAddNode(\_cn//\':ENDIDX\',\'NUMERIC\',\*,\'/noshot_write\',\_nid);

}

DevAddAction(\_path//\':INIT_ACTION\',\'INIT\',\'INIT\',50,\'CAMAC_SERVER\',\_path,\_nid)

;

DevAddAction(\_path//\':STORE_ACTION\',\'STORE\',\'STORE\',50,\'CAMAC_SERVER\',\_path,\_n

id);

DevAddEnd();

}

This function produces the structure:

![](media/image10.png){width="2.904861111111111in"
height="3.214583333333333in"}

The code for DevAddNode.fun shows some of the calls to TCL and into the
tree libraries that are needed to make these changes.

public fun DevAddNode(in \_path, in \_usage, optional in \_data,
optional in \_flags, out \_nid)

{

\_stat = Tcl(\'add node/usage=\'//\_usage//\' \'//\_path);

if (!\_stat)

{

write(\*,\'Error adding node \'//\_path);

abort();

}

\_nid = getnci(\_path,\'nid_number\');

if (present(\_data))

{

if (is_vms())

\_stat = TreeShr-\>Tree\$Put_Record(\_nid,xd(\_data));

else

\_stat = TreeShr-\>TreePutRecord(val(\_nid),xd(\_data),val(0));

if (!\_stat)

{

write(\*,\'Error writing data to \'//\_path);

abort();

}

}

if (present(\_flags))

{

\_stat = Tcl(\'set node\'//\_flags//\' \'//\_path);

if (!\_stat)

{

write(\*,\'Error setting node characteristics - \'//\_flags//\' on
\'//\_path);

abort();

}

}

return(\_stat);

}

The part_name routine maps a relative node number (0-based) to an ASCII
relative path name:

public fun **A12\_\_PART_NAME**(as_is \_nid, optional in \_method)

{

\_name = (\[

\'\',

\':A12NAME\',

\':COMMENT\',

\':EXT_CLOCK_IN\',

\':STOP_TRIG\',

\':INPUT_1\',

\':INPUT_1:STARTIDX\',

\':INPUT_1:ENDIDX\',

\':INPUT_2\',

\':INPUT_2:STARTIDX\',

\':INPUT_2:ENDIDX\',

\':INPUT_3\',

\':INPUT_3:STARTIDX\',

\':INPUT_3:ENDIDX\',

\':INPUT_4\',

\':INPUT_4:STARTIDX\',

\':INPUT_4:ENDIDX\',

\':INPUT_5\',

\':INPUT_5:STARTIDX\',

\':INPUT_5:ENDIDX\',

\':INPUT_6\',

\':INPUT_6:STARTIDX\',

\':INPUT_6:ENDIDX\',

\':INIT_ACTION\',

\':STORE_ACTION\'\])\[getnci(\_nid,\'conglomerate_elt\')-1\];

return(trim(\_name));

}

For comparison, the original a12.gen file was

device model = A12 library = MIT\$DEVICES with

{

NAME : undefined usage = text;

COMMENT : undefined usage = text;

EXT_CLOCK_IN : undefined options = no_write_shot usage = axis;

STOP_TRIG : datum value = 0. options = no_write_shot usage = numeric;

INPUT_1 : undefined options =no_write_model,write_once,compressible
usage = signal ;

INPUT_1:STARTIDX : undefined options = no_write_shot usage = numeric;

INPUT_1:ENDIDX : undefined options = no_write_shot usage = numeric;

INPUT_2 : undefined options =no_write_model,write_once,compressible
usage = signal ;

INPUT_2:STARTIDX : undefined options = no_write_shot usage = numeric;

INPUT_2:ENDIDX : undefined options = no_write_shot usage = numeric;

INPUT_3 : undefined options =no_write_model,write_once,compressible
usage = signal ;

INPUT_3:STARTIDX : undefined options = no_write_shot usage = numeric;

INPUT_3:ENDIDX : undefined options = no_write_shot usage = numeric;

INPUT_4 : undefined options =no_write_model,write_once,compressible
usage = signal ;

INPUT_4:STARTIDX : undefined options = no_write_shot usage = numeric;

INPUT_4:ENDIDX : undefined options = no_write_shot usage = numeric;

INPUT_5 : undefined options =no_write_model,write_once,compressible
usage = signal ;

INPUT_5:STARTIDX : undefined options = no_write_shot usage = numeric;

INPUT_5:ENDIDX : undefined options = no_write_shot usage = numeric;

INPUT_6 : undefined options =no_write_model,write_once,compressible
usage = signal ;

INPUT_6:STARTIDX : undefined options = no_write_shot

INPUT_6:ENDIDX : undefined options = no_write_shot usage = numeric;

INIT_ACTION : action operation = INIT sequence = 50 phase = INIT
server_class = CAMAC_SERVER;

STORE_ACTION : action operation = STORE sequence = 50 phase = STORE
server_class = CAMAC_SERVER;

}

operation INIT requires {

NAME : string error_message is DEV\$\_BAD_NAME;

EXT_CLOCK_IN;

}

operation TRIGGER requires {

NAME : string error_message is DEV\$\_BAD_NAME;

}

operation STOP requires {

NAME : string error_message is DEV\$\_BAD_NAME;

}

The two files generated from A12.GEN, A12_GEN.C and A12.H, are shown in
the appendix, along with A12.C, the original C-language support file.

There really are two instances of the first CamPiow command in the
source; why?

public fun **A12\_\_INIT**(as_is \_nid, optional \_method)

{

\_name = DevNodeRef(\_nid,1);

\_status = DevCamChk(\_name,CamPiow(\_name,0,9,\_d=0,16),1,1);

\_status = DevCamChk(\_name,CamPiow(\_name,0,9,\_d=0,16),1,1);

\_ext_clock = DevNodeRef(\_nid,3);

\_ext = getnci(\_ext_clock, \'length\') == 0;

\_status = DevCamChk(\_name,CamPiow(\_name,0,17,\_ext,16),1,1);

\_status = DevCamChk(\_name,CamPiow(\_name,0,26,\_d=0,16),1,1);

return(1);

}

public fun **a12\_\_store**(as_is \_nid, optional \_method)

{

\_name = DevNodeRef(\_nid,1);

\_ext_clock = DevNodeRef(\_nid,3);

\_trigger = DevNodeRef(\_nid,4);

/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*

See if digitizer is done digitizing

\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/

DevCamChk(\_name,CamPiow(\_name,0,8,\_d=0,16),1,\*);

if (!CamXandQ())

{

write(\*,\'%CAMERR, module \'//\_name//\', Device not triggered\');

return(0);

}

/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*

Get setup info

\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/

DevCamChk(\_name,CamPiow(\_name,0,0,\_setup,16),1,\*);

\_offsets = \_setup & 0x3f;

\_clk = ((\_setup & 0x80) == 0) ? \_ext_clock : build_range(\*,\*,1E-5);

/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*

Check module id for max samples and channel selection method

\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/

DevCamChk(\_name,CamPiow(\_name,0,6,\_module_id, 16),1,1);

\_max_samples = (\_module_id & 128) ? 32767 : 8192;

/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*

For each channel:

If channel is turned on

Get bounds based on startidx and endidx nodes

Compute channel selection code based on module id

Compute data offset based on offsets bit mask

Select the channel

Read the data

Define the dimension

Write the signal

endif

Endfor

\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/

for (\_chan=0; \_chan \< 6; \_chan++)

{

\_chan_offset = \_chan \* 3 + 5;

\_chan_nid = DevHead(\_nid) + \_chan_offset;

if (DevIsOn(\_chan_nid))

{

\_startidx = DevNodeRef(\_nid,\_chan_offset+1);

\_endidx = DevNodeRef(\_nid,\_chan_offset+2);

\_lbound = if_error(long(data(\_startidx)),0);

\_lbound = min(max(\_lbound,0),\_max_samples-1);

\_ubound = if_error(long(data(\_endidx)),\_max_samples-1);

\_ubound = min(max(\_ubound,\_lbound),\_max_samples-1);

if (((\_module_id \>\> 8) & 0xff) \<= 4)

{

\_chan_sel = 7 - \_chan;

}

else

{

DevCamChk(\_name,CamPiow(\_name,1,24,\_d=0,16),1,1);

\_chan_sel = \_chan;

}

\_offset = ((1 \<\< \_chan) & \_offsets) != 0 ? -2048 : 0;

DevCamChk(\_name,CamPiow(\_name,\_chan_sel,16,\_d=0,16),1,\*);

DevCamChk(\_name,CamFStopw(\_name,0,2,\_max_samples,\_data,16),1,\*);

\_dim = make_dim(make_window(\_lbound,\_ubound,\_trigger),\_clk);

DevPutSignal(\_chan_nid, \_offset, 10./4096, \_data\[\_lbound :
\_ubound\], \_lbound, \_ubound, \_dim);

}

}

return(1);

}

Files:

\<device\>.UIL, compiled with UIL/MOTIF/WIDGET=XMDSUIL \<device\>.UIL

to create \<device\>.UID

\<device\>.GEN, compiled with GEN_DEVICE/SINGLE/SUFFIX=\_GEN
\<device\>.gen

to create \<device\>\_GEN.C

\<device\>.C with all the modules called from \<device\>\_GEN

(\"\$\$\" versions of the \"\$\" methods) and \<device\>\$DW_SETUP,

the device setup code (written in Motif with Xmds widgets)

Relink the site-specific sharable image (PPPL\$DEVICES.EXE at PPPL) and

replace the old sharable image in library MDS\$DEVICES.OLB for
production or TEST\$DEVICES.OLB for testing.

PRODUCTION LIBRARIES RESIDE IN MDS\$ROOT:\[SYSLIB\]

Test libraries reside in NSTX\$:\[CAMAC\]; to use the test library,
define logical name MDS\$DEVICES as NSTX\$:\[CAMAC\]TEST\$DEVICES.OLB.
Deassign the logical name to return to the production environment.

Create the new \<device\>.GEN document, identifying all the inputs and
outputs that will require nodes in the tree for storage -

\[for now, it is necessary to imitate an existing document, there is no
general description\] this defines tree nodes, methods and can
initialize some values

\<device\>\$ADD which puts tree nodes for inputs and outputs into model
tree is generated (GEN_DEVICE) from description file \<device\>.GEN

Interface code for device methods (INIT and STORE, typically) is also
generated automatically; as \<device\>\$INIT and \<device\>\$STORE,
typically

device-specific modules, usually \<device\>\$\$INIT and
\<device\>\$\$STORE, called from the corresponding generated code, must
be written - this is where the

CNAFs go; in the \<device\>\$\$STORE routine it is necessary to put
acquired data into the appropriate MDSplus data structures. This can be
done directly using MDSplus structure definitions (see l8210.c

for an example), or via TDI expressions (see h908.c for an example).

**5.0 CAMAC definition and monitoring**

> Defining the CAMAC configuration at boot
>
> NSTX-related processing is started at system boot from
> SYS\$MANAGER:\<host\>SYSRTM.COM where \<host\> is any one of EUROPA,
> KEES, or LUNA. The RTM (RealTiMe) command procedure is itself run from
> SYS\$MANAGER:SYSTARTUP_VMS_BATCH.COM. This latter procedure contains
> all the secondary startup processing and is submitted to a batch queue
> at boot time, as its name describes, so that any problems in any of
> the contained procedures do not interfere with the actual boot
> process.

CAMAC definitions are present in KEESSYSRTM.COM and LUNASYSRTM.COM as
NSTXCAMSTART.COM (on KEES) and LUNACAMSTART.COM.

There are presently two CAMAC highways (B and C) on KEES, and one (A) on
LUNA. The CAMSTART procedure on the respective machines creates the
special logical name table LNM_CAMAC for CAMAC device-name to
logical-name mapping and, via the add_crates subroutine, populates the
list of crates. The CTS AUTOCONFIGURE process then loads the current
mapping from a disk text file.

Formerly crates were also set on-line at this point, but the CTS method,
sending a C/Z, clears module settings. Since we are using many CAMAC
modules to control the power status of PC's and PC-related diagnostic
equipment, this is no longer done. Instead, CRATEMONITOR.PRO turns each
crate on in turn when it runs about once a minute to status the crates
for the web. This also means that persons in the field making changes to
CAMAC racks do not need access to a computer to put crates back on-line,
a great convenience.

> SYS\$MANAGER:NSTXCAMSTART.COM without history:

\$!\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\$!

\$
create/name_table/parent=lnm\$system_directory/protection=(w:rwed,g:rwed)
-

lnm_camac ! Create logical name table for CAMAC names

\$ define/system/nolog/exec camshr SYS\$SHARE:SCSI_CAMSHR

\$ define/system/nolog/exec NSTX\$STARTUP NSTX0:\[NSTX.NSTX.STARTUP\]

\$ deas/table=lnm_camac/all

\$

\$!

\$!\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-- Add Crates Below this line
\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\$

\$ call add_crates GKB2 1 3

\$ call add_crates GKB2 6 6

\$ call add_crates GKB2 9 15

\$ call add_crates GKB2 17 17

\$ call add_crates GKB2 25 27

\$! omitting 33 & 34

\$ call add_crates GKB2 61 61

\$!

\$ call add_crates GKC2 4 5

\$ call add_crates GKC2 7 8

\$ call add_crates GKC2 16 16

\$ call add_crates GKC2 19 22

\$ call add_crates GKC2 24 24

\$ call add_crates GKC2 28 30

\$ call add_crates GKC2 33 33

\$ call add_crates GKC2 37 40

\$ call add_crates GKC2 42 44

\$ call add_crates GKC2 47 48

\$ call add_crates GKC2 62 62

\$

\$!\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\$! Install MDSplus images that require it

\$ \@AUTIL:\[MDSPLUS\]MDSPLUS.COM ; defines CTS

\$!

\$ CTS

AUTOCONFIGURE

! SET \*/ON ! 15-feb-02 Let CRATEMON do it \"gently\"

SHOW/CRATE

EXIT

\$!

\$ exit

\$

\$ def_crate_sub: subroutine

\$ driver = P1+\"00\"

\$ if .not. f\$getdvi(driver+\":\",\"exists\") then mcr sysman io
connect \'driver\'/noa

dapter/driver=sys\$gkdriver

\$ crate = f\$fao(\"!2ZL\",f\$integer(P2))

\$ define/table=lnm_camac/nolog \'P1\'\'crate\': crate\'crate\'

\$ exit

\$ endsubroutine

\$

\$ add_crates: subroutine

\$ add_crate := call def_crate_sub

\$ idx = f\$integer(p2)

\$ endidx = f\$integer(p3)

\$ add_crates_loop:

\$ if idx .gt. endidx then exit

\$ add_crate \'P1\' \'idx\'

\$ idx = idx + 1

\$ goto add_crates_loop

\$ exit

\$ endsubroutine

######### SYS\$MANAGER:LUNACAMSTART.COM without history

\$!\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\$!

\$
create/name_table/parent=lnm\$system_directory/protection=(w:rwed,g:rwed)
-

lnm_camac ! Create logical name table for CAMAC names

\$ define/system/nolog/exec camshr SYS\$SHARE:SCSI_CAMSHR

\$ define/system/nolog/exec NSTX\$STARTUP NSTX\$:\[NSTX.STARTUP\]

\$ deas/table=lnm_camac/all

\$!

\$!\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-- Add Crates Here
\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\$

\$ call add_crates GKA2 18 18

\$ call add_crates GKA2 23 23

\$ call add_crates GKA2 31 32

\$! omitting 33 & 34 - removed

\$ call add_crates GKA2 34 36

\$ call add_crates GKA2 41 41

\$ call add_crates GKA2 45 46

\$ call add_crates GKA2 60 60 ! to be added

\$!

\$!\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\$! Install MDSplus images that require it

\$ \@AUTIL:\[MDSPLUS\]MDSPLUS.COM ; defines CTS

\$!

\$ CTS

AUTOCONFIGURE

! SET \*/ON ! 15-feb-02 Let CRATEMON do it \"gently\"

SHOW/CRATE

EXIT

\$!

\$ exit

\$

\$ def_crate_sub: subroutine

\$ driver = P1+\"00\"

\$ if .not. f\$getdvi(driver+\":\",\"exists\") then mcr sysman io
connect \'driver\'/noa

dapter/driver=sys\$gkdriver

\$ crate = f\$fao(\"!2ZL\",f\$integer(P2))

\$ define/table=lnm_camac/nolog \'P1\'\'crate\': crate\'crate\'

\$ exit

\$ endsubroutine

\$

\$ add_crates: subroutine

\$ add_crate := call def_crate_sub

\$ idx = f\$integer(p2)

\$ endidx = f\$integer(p3)

\$ add_crates_loop:

\$ if idx .gt. endidx then exit

\$ add_crate \'P1\' \'idx\'

\$ idx = idx + 1

\$ goto add_crates_loop

\$ exit

\$ endsubroutine

\$

LUNA\$

See Appendix XXX for \<host\>SYSRTM.COM startup files.

5.1 CTS and CCL

The CTS (CAMAC Topology Supervisor) and CCL (CAMAC Command Language)
utilities are much the same as the original ORNL implementation once run
on VAXes, and ported to the Alpha architecture and then to Linux by MIT.
CTS permits defining logical names for devices that can be used in
programs and continue valid even when the device is moved to a different
slot, rack or highway. They each provide "help" information.

KEES\$ cts

CTS\> help

.

.

Additional information available:

@ ASSIGN AUTOCONFIGURE COMMENT Crates DEASSIGN

EXIT Highways Modules SET SHOW

KEES\$ ccl

CCL\> help

.

.

Additional information available:

DCLST default_libs EXECUTE FSTOP HELP

initial_keydefs LAMWAIT LPIO LQSCAN LSTOP PIO

PLOT QREP QSCAN QSTOP RDATA SET SHOW

startup STOP WDATA

.

.

5.2 Setting crates on-line: CRATEMON and LUNACRATEMON

> cratemon (on KEES) and lunacratemon are processes started at boot (via
> SYS\$MANAGER: KEESSTSRTM.COM or LUNASYSRTM.COM) in batch queues
> KEES_EVENT and LUNA_EVENT, respectively. If there is a problem, the
> batch job can be stopped (\$STOP/ENTRY=87 to stop CRATEMON in the
> example below) and then restarted\
> (\$ @ NSTX\$:\[NSTX.CAMAC\]CRATEMON_SUBMIT.COM or
>
> @ NSTX\$:\[NSTX.CAMAC\]LUNACRATEMON_SUBMIT.COM)

KEES\$ show que/all kees_event

Batch queue KEES_EVENT, available, on KEES::

Entry Jobname Username Status

\-\-\-\-- \-\-\-\-\-\-- \-\-\-\-\-\-\-- \-\-\-\-\--

32 CWL_VIPS SYSTEM Executing

57 LINKMON SYSTEM Executing

59 RGASHOT_404 RONEY Executing

87 CRATEMON RONEY Executing

999 CAMERAOFF SYSTEM Holding until 10-DEC-2007 20:00:00

84 ATT RONEY Holding until 11-DEC-2007 07:00:00

KEES\$

LUNA\$ show que/all luna_event

Batch queue LUNA_EVENT, available, on LUNA::

Entry Jobname Username Status

\-\-\-\-- \-\-\-\-\-\-- \-\-\-\-\-\-\-- \-\-\-\-\--

92 LUNACRATEMON SYSTEM Executing

94 CAL_ZEFF SYSTEM Executing

97 APPENDBUFFER1ANDCOPY

SYSTEM Executing

98 APPENDBUFFER2ANDCOPY

SYSTEM Executing

99 SFLIP_GAINMON SYSTEM Executing

100 DMANJ BELL Executing

546 DEPMON_PERSEC_BUFFERED

SYSTEM Executing

LUNA\$

> The KEES process statuses and turns on crates on the B and C highways;
> the LUNA process handles highway A. An attempt is made to set online
> each crate in the CTS table, about once a minute. As the tests are
> done, a web page of the results (online or offline) is built up. The
> resulting Web status displays are accessible from the NSTX webtools
> page, <http://nstx.pppl.gov/nstx/Software/WebTools/index.html>
>
> The top portion of the KEES page is shown below.

![](media/image11.png){width="6.593055555555556in" height="5.675in"}

> http://mel.pppl.gov/www_root/serverdoc/nstx/camac/cratestatus.html

Clicking on the name of a crate brings up the current CTS definitions
for that crate. (This is not truth, just what has been recorded. To see
feedback about what is really still in the crate, use the IDL program
SCANCRATE.PRO, running on the appropriate host.)

5.3 Telling EPICS about highway status: LINKMON

> LINKMON (KEES) and LUNLINKMON run in batch queues KEES_EVENT and
> LUNA_NORM, respectively. They each send a CAMAC command (writing F=16,
> A=0) to one H367 module on each highway (n=1 for crates 60, 61 & 62)
> every 10 seconds. EPICS watches an output from these modules that is
> input to an EPICS CAMAC module to make sure the VMS highways are up.
> To restart, stop batch queue entry if necessary and use
> NSTX\$:\[NSTX.CAMAC\]LINKMON_SUBMIT.COM or LUNALINKMON_SUBMIT.COM.

**6.0 Data Management**

> Disk configuration
>
> NSTX_DAILY.COM
>
> NSTX_OLDTOSANSLOW.COM

**7.0 NSTX analysis on VMS -- batch queues**

**8.0 System Startup: what happens at boot**

> NSTX-related processing is started from
> SYS\$MANAGER:\<host\>SYSRTM.COM where \<host\> is any one of EUROPA,
> KEES, or LUNA. The RTM command procedure is itself run from
> SYS\$MANAGER:SYSTARTUP_VMS_BATCH.COM . This latter procedure contains
> all the secondary startup processing and is submitted to a batch queue
> at boot time, as its name describes, so that any problems in any of
> the contained procedures do not interfere with the actual boot
> process.
>
> See Appendix XXX for \<host\>SYSRTM.COM startup files and their
> subprocedures.
>
> Startup checks

9.0 Troubleshooting?

**10. Miscellaneous**

> SHW command

**Appendices**

#### ANNOTATED SHOT CYCLE (need to update to include lark)

![](media/image12.png){width="6.583333333333333in" height="2.45in"}

####### ACTION NODES

> The TDI Help for BUILD_ACTION and BUILD_DISPATCH

BUILD_ACTION
(DISPATCH,TASK,\[ERRORLOGS\],\[COMPLETION\],\[PERFORMANCE\])

MDS Operation.

Make an action descriptor.

Arguments

DISPATCH dispatch descriptor.

TASK procedure, program, routine, or method descriptor.

ERRORLOGS a character scalar for error reports.

COMPLETION notification list.

PERFORMANCE unsigned long vector of statistics from execution.

Result.. Class-R descriptor.

Use BUILD_xxx for immediate structure building.

Use MAKE_xxx in FUNs for evaluated non-PUBLIC variables.

Example. BUILD_ACTION(BUILD_DISPATCH(\"ident\",\"phase\",\"when\",

\"completion\"),BUILD_ROUTINE(timeout,image,routine))

has only dispatch and task.

BUILD_DISPATCH (TYPE,IDENT,PHASE,WHEN,COMPLETION)

MDS Operation.

Make a dispatch descriptor.

Arguments

TYPE byte unsigned scalar, evaluated:

TREE\$K_SCHED_ASYNC 1

TREE\$K_SCHED_SEQ 2

TREE\$K_SCHED_COND 3

IDENT character scalar.

PHASE character scalar.

WHEN character scalar?

COMPLETION character scalar?

Result.. Class-R descriptor.

Use BUILD_xxx for immediate structure building.

Use MAKE_xxx in FUNs for evaluated non-PUBLIC variables.

Example. None, normally done by module add routine.

TDI functions to get the components of an action programmatically:

***COMPLETION_OF***

COMPLETION_MESSAGE_OF

***DISPATCH_OF***

***IDENT_OF***

***METHOD_OF***

PERFORMANCE_OF

***PHASE_OF***

***TASK_OF***

TIME_OUT_OF

***WHEN_OF***

a = strarr(6)

a\[0\] = devicename

a\[1\] = mdsvalue(\'ident_of(\'+devicename+\':INIT_ACTION)\') ; which
mds server?

a\[2\] = mdsvalue(\'when_of(\'+devicename+\':INIT_ACTION)\') ; what
priority

a\[3\] = mdsvalue(\'completion_of(\'+devicename+\':INIT_ACTION)\') ;
name of event declared if successful

.

####### DISPATCHING

NSTX\$:\[NSTX.STARTUP\]NSTX_NCP.COM

\$ NODENAME = f\$getsyi(\"nodename\")

\$!

\$ define NSTX\$STARTUP NSTX0:\[NSTX.NSTX.STARTUP\]

\$ ncp := \$ncp

\$ oldpriv = f\$setprv(\"SYSPRV,OPER\")

\$!

\$!

\$MEL:

\$ if NODENAME.nes.\"MEL\" then goto NOT_MEL

\$!

\$ ncp

clear obj DISPATCH_SERVER all

define obj DISPATCH_SERVER number 0 file
NSTX\$STARTUP:DISPATCH_SERVER.COM US

ER RONEY ACCOUNT RONEY

set obj DISPATCH_SERVER number 0 file NSTX\$STARTUP:DISPATCH_SERVER.COM
USER

RONEY ACCOUNT RONEY

clear obj GKA2_SERVER all

define obj GKA2_SERVER number 0 file NSTX\$STARTUP:GKA2_SERVER.COM

set obj GKA2_SERVER number 0 file NSTX\$STARTUP:GKA2_SERVER.COM

exit

\$!

\$NOT_MEL:

\$ if NODENAME.nes.\"KEES\" then goto NOT_KEES

\$!

\$ ncp

clear obj DISPATCH_SERVER all

define obj DISPATCH_SERVER number 0 file
NSTX\$STARTUP:DISPATCH_SERVER.COM US

ER RONEY ACCOUNT RONEY

set obj DISPATCH_SERVER number 0 file NSTX\$STARTUP:DISPATCH_SERVER.COM
USER

RONEY ACCOUNT RONEY

clear obj GKB2_SERVER all

define obj GKB2_SERVER number 0 file NSTX\$STARTUP:GKB2_SERVER.COM

set obj GKB2_SERVER number 0 file NSTX\$STARTUP:GKB2_SERVER.COM

clear obj GKC2_SERVER all

define obj GKC2_SERVER number 0 file NSTX\$STARTUP:GKC2_SERVER.COM

set obj GKC2_SERVER number 0 file NSTX\$STARTUP:GKC2_SERVER.COM

clear obj MON_SERVER all

define obj MON_SERVER number 0 file NSTX\$STARTUP:MON_SERVER.COM

set obj MON_SERVER number 0 file NSTX\$STARTUP:MON_SERVER.COM

exit

\$!

\$NOT_KEES:

\$ if NODENAME.nes.\"LUNA\" then exit

\$!

\$! \-\-- no DISPATCH_SERVER on LUNA (1/6/05) \-\-\--

\$ ncp

clear obj GKA2_SERVER all

define obj GKA2_SERVER number 0 file NSTX\$STARTUP:GKA2_SERVER.COM

set obj GKA2_SERVER number 0 file NSTX\$STARTUP:GKA2_SERVER.COM

clear obj FIRETIP_SERVER all

define obj FIRETIP_SERVER number 0 file NSTX\$STARTUP:FIRETIP_SERVER.COM

set obj FIRETIP_SERVER number 0 file NSTX\$STARTUP:FIRETIP_SERVER.COM

exit

clear obj HIGHK_SERVER all

define obj HIGHK_SERVER number 0 file NSTX\$STARTUP:HIGHK_SERVER.COM

set obj HIGHK_SERVER number 0 file NSTX\$STARTUP:HIGHK_SERVER.COM

\$!

\$ EXIT

NSTX\$:\[NSTX.STARTUP\]GKB2_SERVER.COM

\$! GKB2_SERVER.COM

\$! Note: server name should match highway name.

\$! Edit:02-Aug-05 PR Change logfile from append to create new version

\$! Edit:06-Dec-99 PR Raise base priority to 7; VGDS jobs at 5

\$! Edit:06-Oct-99 PR Raise base priority to 5

\$

\$ !================================================

\$ ! Set sysprv to allow creation of log file, etc.

\$ !================================================

\$ oldpriv=f\$setprv(\"sysprv\")

\$ set process/priv=ALTPRI

\$ set proc/priority=7

\$

\$ !================================================

\$ ! Re-define sys\$output to something sensible

\$ !================================================

\$ set protection=(sy:rwed,ow:rwed,gr:re,wo:re)/default

\$ NAME = f\$parse(f\$environment(\"procedure\"),,,\"name\")

\$ YY = f\$extract(2,2,f\$cvtime(,,\"year\"))

\$ MM = f\$cvtime(,,\"month\")

\$ DD = f\$cvtime(,,\"day\")

\$ LOGFILE := NSTX\$:\[logs.runnstx\]\'NAME\'\_\'YY\'\'MM\'\'DD\'.log

\$ write sys\$output f\$fao(\"!/Log file is !AS!/\",LOGFILE)

\$

\$ if f\$search(LOGFILE).eqs.\"\"

\$ then

\$ open/write/share=read log\$output \'LOGFILE\'

\$ else

\$ open/write/share=read log\$output \'LOGFILE\'

\$!\$ open/append/share=read log\$output \'LOGFILE\'

\$ endif

\$ define sys\$output log\$output

\$

\$ !================================================

\$ ! Setup nstx; run mdsserver \...

\$ !================================================

\$ setup nstx

\$

\$ mdsserver :== \$mdsserver

\$

\$ mdsserver gkb2_server

#### Normal status displays

**Table of important files and procedures**

COM\$MGR:MDSPLUS_DATABASES.COM

MDS\$PPPLROOT:\[000000\]

> MDS\$PPPLROOT:\[DISPATCHER\]
>
> NSTX_CREATE_INIT.TCL
>
> NSTX_STORE.TCL
>
> NSTX_STOP_SPECIAL_SERVERS.COM
>
> RECOVER.TCL

NSTX\$:\[COM\]DISKS.COM

NSTX\$:\[DATA_MANAGEMENT\]

> NSTX_DAILY.COM
>
> NSTX_OLDTOSANSLOW.COM

NSTX\$:\[NSTX\]

> NSTX\$:\[NSTX.SOURCE.RUNNSTX\]
>
> RUNNSTX.EXE & RUNNSTX.C
>
> RUNNSTX_ENGINEERING.EXE & RUNNSTX_ENGINEERING.C
>
> NSTX\$:\[NSTX.STARTUP\]
>
> NSTX_NCP.COM
>
> DISPATCH_SERVER.COM
>
> GKA2_SERVER.COM
>
> GKB2_SERVER.COM
>
> GKC2_SERVER.COM
>
> NSTX\$:\[NSTX.CAMAC\]
>
> CRATEMON.COM
>
> CRATEMONITOR.PRO
>
> LUNACRATEMON.COM
>
> LUNACRATEMONITOR.PRO
>
> MELCRATEMON.COM
>
> MELCRATEMONITOR.PRO
>
> LINKMON.COM
>
> LINKMONITOR.PRO
>
> LUNALINKMON.COM
>
> LUNALINKMONITOR.PRO
>
> \<no link monitor for MEL test highway\>
>
> NSTX\$:\[NSTX.ADMIN\]
>
> Procedures for setting/changing ACL on NSTX directories
>
> NSTX\$:\[LOGS\]
>
> subdirs
>
> ACQREMOTE CAMAC CHECKQUEUES DB EVENTS MPTS RF **RUNNSTX**
>
> SQLSERVER TC_MON VGDS
>
> NSTX\$:\[LOGS.RUNNSTX\]

######### COMPARE_INIT_TIMES.COM

> COMPARE_STORE_TIMES.COM
>
> RUNNSTX.LOG
>
> RUNNSTX_yymmdd.log;\*
>
> DISPATCH_SERVER_yymmdd.log;\*
>
> GK{A\|B\|C}\_SERVER_yymmdd.log;\*
>
> FIRETIP_SERVER_yymmdd.log;\*
>
> 109
>
> HIGHK_SERVER_yymmdd.log;\*
>
> USR:\[PPPL_RES\]
>
> = USR:\[PPPL_RES\]
>
> = USR:\[PPPL_RES\]
>
> KEES\$ mov?
>
> Subdirectories of USR:\[PPPL_RES\]
>
> DASUTIL EVT IDL LOG MDSIDL MDSPLUS MDSPLUS_LOCAL QCS
>
> **SHOTCLOCK** \[clocksync,shotclock,stopclock\]
>
> BACKUP COM DASUTIL DOC EVT IDL LOG MDSIDL
>
> MDSPLUS MDSPLUS_LOCAL QCS SHOTCLOCK TEDI
>
> GIBNEY\$:\[HANDBOOK\]\*.MEM
>
> Directory GIBNEY\$:\[HANDBOOK\]
>
> ACCOUNTS.MEM;1 ARCHIVER_REQCOUNT.MEM;
>
> CC_PREDEFINED_MACROS.MEM;1 CVS_READONLY.MEM;2
>
> CVS_SETTING_UP.MEM;1 CVS_SOFTWARE_REVISIONS.MEM;1
>
> CW_SHARED_LIBRARY.MEM;4 DECW_RESTART.MEM;1
>
> DSN_MOUNTED_DISMOUNT.MEM;1 FTP.MEM;2
>
> IDL_COLORS.MEM;1 IDL_INSTALL.MEM;1
>
> IDL_OUTPUT.MEM;1 IDL_PROGRAMMING.MEM;5
>
> IPCS_BUILD.MEM;1 IPCS_CONFIG.MEM;2
>
> IPCS_INSTALL.MEM;1 IPCS_LIB.MEM;1
>
> IPCS_NSTX_RESTART.MEM;7 IPCS_TROUBLESHOOTING.MEM;5
>
> MAC.MEM;2 MAIL_RETURN_ADDRESS.MEM;2
>
> MDSPLUS_CREATE_TCL.MEM;2 MDSPLUS_MDS\$MITROOT_REPLACE.MEM;1
>
> MDSPLUS_MDS\$MITROOT_UPDATE.MEM;1 MDSPLUS_PRIVATE_DATABASES.MEM;1
>
> MDSPLUS_UNIX.MEM;27 MDSPLUS_UNIX_INSTALL.MEM;10
>
> MULTINET_ADD_SERVICE.MEM;2 MULTINET_DEBUG.MEM;1
>
> MULTINET_SOCKET_OPTIONS.MEM;1 MULTINET_TRACEROUTE.MEM;1
>
> NETWORK_TROUBLESHOOTING.MEM;1 NSTX_MOVE_MDSPLUS_FILES.MEM;1
>
> PCS_NEW_CATEGORY.MEM;5 PCS_NEW_WAVEFORM.MEM;2
>
> PCS_NOTES.MEM;6 PCS_PSRTC_TESTING.MEM;3
>
> PCS_RTEFIT_SKYVEC.MEM;2 PCS_TESTSHOT.MEM;3
>
> PCS_VERSIONS.MEM;2 PDF.MEM;3
>
> PPCC_ENGINEERING_TESTSHOT.MEM;1 PSRTC_PCS_DISK_SPACE.MEM;2
>
> QCS_ECS.MEM;1 SET_WATCH.MEM;2
>
> SKYCORE_TRACEBACK.MEM;1 TDI_NOTES.MEM;3
>
> UCX.MEM;1 UNIX.MEM;26
>
> UNIX_ADMIN.MEM;2 UNIX_COMPILE_LINK.MEM;2
>
> UNIX_FILE_RESTORE.MEM;2 UNIX_OS_SPECIFIC.MEM;4
>
> UNIX_VARIABLES.MEM;1 VMS_BATCH_JOBS_NOT_CREATED.MEM;1
>
> VMS_BATCH_QUEUE_TRANSFER.MEM;4 VMS_DELETE_BATCH_QUEUE.MEM;5
>
> VMS_EPICS.MEM;3 VMS_EUROPA_ETHERNET_011206.MEM;2
>
> VMS_MESSAGES.MEM;3 VMS_PAGE_AND_SWAP_FILES.MEM;1
>
> VMS_PRINTING.MEM;1 VMS_SYSLOST_RECOVER.MEM;1
>
> VMS_USEFUL.MEM;1 XWINDOWS.MEM;1
>
> XX.MEM;5

MDSPLUS_DATABASES.COM

\$! MDSPLUS_DATABASES.COM \--

\$!

\$! \*NOTE\* This procedure creates new directories if required

\$!

\$! Create MDSplus logical name tables for each experimental machine.

\$! Define MDSplus databases for each machine.

\$!

\$! To add a new MACHINE \"mmm\" :

\$! o Add call to MDSplus_disks at top of this file.

\$! o Create new subroutine mmm_DATABASES at bottom of file:

\$! \-- one call to DEFINE_TREE for each treename

\$!

\$! For existing machine \"mmm\",

\$! To add another TREE definition:

\$! o Add call to DEFINE_TREE inside existing subroutine mmm_DATABASES,

\$! at bottom of this file.

\$! ==\> all required directories will be created automatically.

\$!

\$! Support for multiple \"mmm\$NEW\$\" disks: the \"new\"Idx parameter:
28-Feb-02

\$! If multiple \"NEWDISK\"s are specified in \"call MDSplus_disks\",
then

\$! separate definitions will be made for each disk \"n\": mmm\$NEWn\$.

\$! Inside mmm_DATABASES subroutine, the optional NewIdx parameter

\$! to DEFINE_TREE (called for each tree) specifies which \"new\" disk

\$! which is the primary target for that tree\'s new data.

\$!

\$! History:

\$! 28-Aug-2006 PR Adding NSTX_ARC110 as last ARC disk - FATA, \"old\"

\$! Now defining NSTX\$OLD\$ & NSTX\$OLD\$DISK as NSTX_ARC110

\$! 07-Aug-2006 PR Adding NSTX_ARC109 as last ARC disk - FATA, \"old\"

\$! Defining NSTX\$OLD\$ & NSTX\$OLD\$DISK as NSTX_ARC109

\$! Defining NSTX\$RAWOLD\$ & NSTX\$RAWOLD\$DISK as NSTX_ARC109 too

\$! 07-Jun-2006 PR Adding NSTX_ARC108 as new ARC disk

\$! 31-May-2006 PR Adding NSTX_ARC104 as new RAW disk

\$! 29-Sep-2005 PR Removing TR and TRW\* trees for NSTX; Tina says not
used

\$! 15-Sep-2005 PR Temporarily drop NSTX3 so TGC\'s job clears .cine
files

\$! 01-Sep-2005 PR Adding NSTX_ARC107 as new NSTX_NORMARC DISK

\$! 30-Aug-2005 PR Change NSTX_MODELS to NSTX0 from DISK\$OSVMS

\$! 20-Jul-2005 PR Add NSTX_ARC105 to NSTX\$ARC\$ and make it

\$! and make it the new NSTX_NORMARC_DISK

\$! 07-Jul-2005 PR Making NSTX_ARCRAW103 the new NSTX_RAWARC_DISK

\$! 02-Jun-2005 PR Adding new ARC disk, NSTX_ARC104 (\$1\$DGA4) as

\$! NSTX_NORMARC and at front of NSTX\$ARC\$ list

\$! 19-May-2005 PR Adding new ARCRAW disk, NSTX_ARCRAW103 (\$1\$DGA3)

\$! 26-Apr-2005 PR Changing NBI category to RAW, using NSTX2

\$! 20-Apr-2005 PR Dropping GASPUFF_RAW, adding PSPEC_RAW

\$! 14-Apr-2005 PR Adding GASPUFFIMGNG & GASPUFF_RAW trees

\$! 28-Mar-2005 PR Adding TF_JOINTS tree to contain predicted voltages

\$! 23-Mar-2005 PR Fixing syntax bug wrt FDEV use (no extra :)

\$! 14-Mar-2005 PR Adding NSTX3,NSTX4 to NSTX NEW and RAW lists

\$! 10-Mar-2005 PR Adding four new logical names for RAW/NORM

\$! data archiving: NSTX\$NORMNEW\$,NSTX\$NORMARC\$,

\$! NSTX\$RAWNEW\$, NSTX\$RAWARC\$ \-- only if machine NSTX

\$! 18-Jan-2005 PR Adding RAW trees ACTIVESP_RAW & MICROWAV_RAW

\$! 24-Feb-2005 PR Adding RAW trees EDGE_RAW & MOPS_RAW

\$! 13-Jan-2005 PR Removing NSTX2_DATA,NSTX6_DATA&NSTX7_DATA fr
NSTX\$ARC\$

\$! 04-Jan-2005 PR Change NSTX\$NEW\$ to from KEES0 to NSTX1

\$! 16-Dec-2004 PR Change NSTX\$NEW\$ to use only KEES0 so KEES1&2

\$! can become NSTX0&1

\$! 09-Dec-2004 PR Changes NSTX\$MODELS\$ to DISK\$OSVMSKEES from KEES2

\$! 09-Dec-2004 PR/TRG Modif. NSTX\$NEW\$\* to use KEES0; made all diag
use #1

\$! 22-Nov-2004 PR Added DUMMY_RAW tree for tree-split testing

\$! 17-Nov-2004 PR Changing NSTX\$MODELS\$ back to KEES2 (SAN testing)

\$! 17-Nov-2004 PR Change NSTX\$MODELS\$ from KEES2 to KEES_OS

\$! 19-Aug-2004 PR Removing DCON and DCON01; moved to lark

\$! 09-Jun-2004 PR Putting NSTX7_DATA at beginning of NSTX\$ARC list

\$! 04-Jun-2004 PR Adding NSTX7_DATA to NSTX\$ARC list. (at end)

\$! 23-Apr-2004 TRG Moved NSTX6_DATA to head of NSTX\$ARC list. Note

\$! the peculiar ordering of the searchlist: oldest

\$! files are on NSTX5_DATA, so it\'s last in list of

\$! \"used\" disks. (empty disks are at end of list,

\$! following the \"used\" disks)

\$! 15-Mar-2004 PR Adding FUELING tree

\$! 05-Feb-2004 PR Putting NSTX2_DATA first in NSTX\$ARC\$ list

\$! 21-May-2003 PR Change NSTX\$MODELS\$ to use KEES2 instead of KEES0

\$! 04-Mar-2002 TRG Add optional NEWIDX parameter to DEFINE_TREE subrtn.

\$! See description above.

\$! 27-Jun-2001 TRG Add 2nd NSTX\$ARC\$ disk.

\$! Change mmm\$ARC\$ definition to not-concealed. This

\$! will cause new .TREE files to be in original dir.

\$! 23-May-2001 TRG Add CHI tree, for Brian Nelson.

\$! 27-Mar-2001 TRG Replace \"NSTXTRANSP\" by \"TR\". Easier to type.

\$! 29-Jan-2001 TRG Add NSTXTRANSP and NSTXTRANSPnn\$DATA, like EFIT.

\$! Note: \"NSTXTRANSP\" defs replace old \"MDSTRANSP\".

\$! 25-Jan-2001 TRG Add special TRANSP-related names for Tina & D.Ernst

\$! 11-Feb-2000 TRG Replace TEST machine: it is now an exact duplicate

\$! of NSTX, except that NSTX\$DATA becomes TEST\$DATA.

\$! 16-Dec-1999 TRG Add NSTX\$DERIVED definitions.

\$! Change mmm\$NEW\$ definition to not-concealed. This

\$! will cause new .TREE files to be in original dir.

\$! 19-Aug-1999 TRG Define mmm\$NEW\$ days-of-week in reverse order, so

\$! that more recent directories are at top of list.

\$! 17-Jun-1999 TRG Create separate mmm\$MODELS\$ rooted directory,
similar

\$! to mmm\$NEW\$ and mmm\$ARC\$.

\$! 28-Apr-1999 PR Add MDSTRANSP to NSTX logical name table

\$! 26-Jan-1999 TRG Add SYSMAN feature for served disks; add MINIMAL
opt.

\$! 19-Jan-1999 TRG Top level dir is mmm_NEW, not MDSPLUS_NEW.mmm (like-

\$! wise for mmm_ARC, not MDSPLUS_ARC.mmm).

\$! Add day-of-week specification to mmm\$NEW\$ searchlist.

\$! 24-Sep-1998 TRG Create name table LNM\$MDS_mmm

\$! 20-Jul-1998 TRG Change order of ARC directory search list.

\$! 24-Jun-1998 TRG Create.

\$!

\$!====================================================================

\$

\$ write sys\$output f\$fao(\"!\_!AS on node !AS\",-

f\$environment(\"procedure\"),f\$getsyi(\"nodename\"))

\$

\$ MINIMAL = P1.nes.\"\" !TRUE if P1 exists

\$ INCLUDES_SERVED_DISK == 0 !set TRUE if disk is served by local node

\$

\$ oldpriv = f\$setprv(\"sysnam,sysprv\")

\$

\$!\$ NSTX_RAWNEW_LIST = \"NSTX2,NSTX3,NSTX4\"

\$ NSTX_RAWNEW_LIST = \"NSTX2,NSTX4\"

\$ NSTX_NORMNEW_LIST = \"NSTX1\"

\$ NSTX_RAWARC_DISK = \"NSTX_ARC104\" ! should change name to ARCRAW104

\$ NSTX_NORMARC_DISK = \"NSTX_ARC108\"

\$ NSTX_RAWOLD_DISK = \"NSTX_ARC109\" ! should change name to ARCRAW109

\$ define/nolog/system NSTX\$RAWOLD\$DISK NSTX_ARC109

\$ NSTX_OLD_DISK = \"NSTX_ARC110\"

\$ define/nolog/system NSTX\$OLD\$DISK NSTX_ARC110

\$!

\$! mmm models new arc

\$! Machine disk disks disks

\$! \-\-\-\-\-\-- \-\-\-\-\-\-- \-\-\-\-\-- \-\-\-\--
\-\-\-\-\-\-\-\-\-\-\-\-\--

\$ call MDSplus_disks TRANSP VMEC1 VMEC1 VMEC1,VMEC2

\$!\$ call MDSplus_disks NSTX NSTX0 NSTX1,NSTX2,NSTX3,NSTX4
NSTX_ARC107,NSTX_ARC105,NSTX_ARC104,NSTX_ARC106,NSTX_ARCRAW103,NSTX_ARC101,NSTX_ARCRAW102

\$ call MDSplus_disks NSTX NSTX0 NSTX1,NSTX2,NSTX4
NSTX_ARC108,NSTX_ARC107,NSTX_ARC105,NSTX_ARC104,NSTX_ARC106,NSTX_ARCRAW103,NSTX_ARC101,NSTX_ARCRAW102,NSTX_ARC109,NSTX_ARC110

\$ call MDSplus_disks TFTR VMEC1 VMEC1 TRANSP\$RD,VMEC1

\$ call MDSplus_disks TEST VMEC1 VMEC1,KEES2 VMEC1

\$

\$ set process/priv=(\'oldpriv\')

\$

\$ if .not.MINIMAL .and. INCLUDES_SERVED_DISK

\$ then

\$ oldpriv = f\$setprv(\"oper,setprv\")

\$ set verify

\$ sysman := \$sysman

\$ sysman

set environment/cluster

set profile/priv=(sysprv,sysnam)

do \@com\$mgr:mdsplus_databases.com MINIMAL

exit

\$ set process/priv=(\'oldpriv\')

\$ set noverify

\$ endif

\$

\$ exit

\$

\$

\$!======================================================================

\$!======================================================================

\$

\$MAKE_SEARCHLIST_NEW: subroutine

\$ NEWDISK = P1

\$

\$ DEVCNT = 0 !number of valid devices in SEARCHLIST

\$ IDX = 0

\$ SEARCHLIST = \"\"

\$SEARCHLIST_NEW_LOOP:

\$ DEV = f\$element(IDX,\",\",NEWDISK)

\$ if DEV.eqs.\",\" then goto SEARCHLIST_NEW_END

\$ IDX = IDX+1

\$

\$ ! Check for non-existent device or host not avail

\$
!\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\$ if .not.f\$getdvi(DEV,\"exists\")

\$ then

\$ goto SEARCHLIST_NEW_LOOP

\$ endif

\$

\$ if .not.f\$getdvi(DEV,\"host_avail\") .and. -

.not.f\$getdvi(DEV,\"alt_host_avail\")

\$ then

\$ write sys\$output f\$fao(\"==\> !AS : host !AS not available\", -

DEV,f\$getdvi(DEV,\"host_name\"))

\$ goto SEARCHLIST_NEW_LOOP

\$ endif

\$

\$ DEVCNT = DEVCNT+1

\$ if f\$getdvi(DEV,\"served_device\") then INCLUDES_SERVED_DISK==1

\$

\$ FULLDEVNAM = f\$getdvi(DEV,\"FULLDEVNAM\")

\$ TEMPLIST = \"\'\'FULLDEVNAM\'\[\'\'MMM\'\_NEW.\]\"

\$ call CHECK_DIRECTORY \'FULLDEVNAM\' \[\'MMM\'\_NEW\]

\$ IDAY = 0

\$WEEKDAY_LOOP:

\$ if IDAY.ge.0 then TEMPLIST = TEMPLIST + \",\"

\$ WEEKDAY = f\$extract(0,3,f\$cvtime(\"-\'\'IDAY\'-\",,\"Weekday\"))

\$ TEMPLIST = TEMPLIST +
\"\'\'FULLDEVNAM\'\[\'\'MMM\'\_NEW.\'\'WEEKDAY\'.\]\"

\$ call CHECK_DIRECTORY \'FULLDEVNAM\' \[\'MMM\'\_NEW.\'WEEKDAY\'\]

\$ IDAY = IDAY+1

\$ if IDAY.lt.7 then goto WEEKDAY_LOOP

\$

\$ if DEVCNT .gt. 1 then SEARCHLIST = SEARCHLIST + \",\"

\$ SEARCHLIST = SEARCHLIST + TEMPLIST

\$

\$ goto SEARCHLIST_NEW_LOOP

\$SEARCHLIST_NEW_END:

\$

\$ SEARCHLIST_NEW == SEARCHLIST

\$ exit

\$ endsubroutine

\$

\$

\$!======================================================================

\$!======================================================================

\$!

\$! MDSplus_disks:

\$! P1 = machine name

\$! P2 = disk for models

\$! P3 = disk for new data

\$! P4 = disk(s) for archived data. Note that archived data may

\$! be modified, in which case it will be re-archived.

\$! For multiple disks (searchlist), separate names with a comma.

\$

\$MDSplus_disks: subroutine

\$ MMM = P1 !Machine name

\$ MODELSDISK = P2 !Disk(s) for models

\$ NEWDISK = P3 !Disk(s) for new data

\$ ARCDISK = P4 !Disk(s) for archived data

\$

\$!===================

\$! mmm\$MODELS\$ is the device name (rooted directory, per machine) for

\$! the MDSPLUS model trees.

\$! Note that only one disk can be specified \-- not a problem, I
imagine.

\$

\$ FULLDEVNAM = f\$getdvi(MODELSDISK,\"FULLDEVNAM\")

\$ SEARCHLIST = \"\'\'FULLDEVNAM\'\[\'\'MMM\'\_MODELS.\]\"

\$ call CHECK_DIRECTORY \'FULLDEVNAM\' \[\'MMM\'\_MODELS\]

\$ define/nolog/system/translation=(c) \'MMM\'\$MODELS\$ \'SEARCHLIST\'

\$

\$!===================

\$! mmm\$NEW\$ is the device name (rooted directory, per machine) for
new

\$! data

\$

\$

\$ NUMNEW = 0 !Count number of disks in NEWDISK

\$NUMNEWLOOP:

\$ NUMNEW = NUMNEW+1

\$ if f\$element(NUMNEW,\",\",NEWDISK) .nes. \",\" then goto NUMNEWLOOP

\$

\$ INEW = 0

\$SEARCHLIST_NEW_LOOP:

\$ call MAKE_SEARCHLIST_NEW \'NEWDISK\'

\$ INEW = INEW+1

\$ if INEW .eq. 1 then -

define/nolog/system \'MMM\'\$NEW\$ \'SEARCHLIST_NEW\'

\$

\$ if NUMNEW .ge. 1

\$ then

\$ define/nolog/system \'MMM\'\$NEW\'INEW\'\$ \'SEARCHLIST_NEW\'

\$ K = f\$locate(\",\",NEWDISK)

\$ DISK1 = f\$extract(0,K,NEWDISK)

\$ NEWDISK = f\$extract(K+1,999,NEWDISK) + \",\'\'DISK1\'\"

\$ endif

\$ delete/symbol/global SEARCHLIST_NEW

\$ if INEW .lt. NUMNEW then goto SEARCHLIST_NEW_LOOP

\$

\$ if MMM .nes. \"NSTX\" then goto MAKE_ARCSEARCH

\$!

\$!====================

\$! Adding logic for NSTX\$NEWNORM\$ and NSTX\$NEWRAW\$ for later use by

\$! NSTX\$:\[DATA_MANAGEMENT\]NSTX_DAILY.COM in sending raw & normal
trees to

\$! separate archiving disks - PR 3/10/05

\$!===================

\$!

\$!\$ write sys\$output \"Case is NSTX, define special searchlists for
NEW\"

\$

\$ call MAKE_SEARCHLIST_NEW \'NSTX_RAWNEW_LIST\'

\$ define/nolog/system NSTX\$RAWNEW\$ \'SEARCHLIST_NEW\'

\$ delete/symbol/global SEARCHLIST_NEW

\$

\$ call MAKE_SEARCHLIST_NEW \'NSTX_NORMNEW_LIST\'

\$ define/nolog/system NSTX\$NORMNEW\$ \'SEARCHLIST_NEW\'

\$ delete/symbol/global SEARCHLIST_NEW

\$

\$! =============

\$

\$

\$!

\$MAKE_ARCSEARCH:

\$!===================

\$! mmm\$ARC\$ is the rooted directory for files which are no longer
\"new\".

\$! Data files are moved from mmm\$NEW\$:\[treename\] to
mmm\$ARC\$:\[treename\]

\$! for eventual archival backup (maybe to Archiver, maybe not).

\$! After a file is archived, it is moved to
mmm\$ARC\$:\[treename.tt.hh\],

\$! where tt=ishot/10000 and hh=((ishot/100)%100).

\$! For example, MAGNETICS_123456 would go to
mmm\$ARC\$:\[MAGNETICS.12.34\].

\$! If an archived file is modified, it is moved back to
mmm\$ARC\$:\[treename\]

\$! for eventual re-archiving.

\$

\$ IDX = 0

\$ SEARCHLIST = \"\"

\$SEARCHLIST_ARC:

\$ DEV = f\$element(IDX,\",\",ARCDISK)

\$ if DEV.eqs.\",\" then goto SEARCHLIST_ARC_END

\$

\$ ! Check for non-existent device or host not avail

\$
!\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\$ if .not.f\$getdvi(DEV,\"exists\")

\$ then

\$ IDX = IDX+1

\$ goto SEARCHLIST_ARC

\$ endif

\$

\$ if .not.f\$getdvi(DEV,\"host_avail\") .and. -

.not.f\$getdvi(DEV,\"alt_host_avail\")

\$ then

\$ write sys\$output f\$fao(\"==\> !AS : host !AS not available\", -

DEV,f\$getdvi(DEV,\"host_name\"))

\$ IDX = IDX+1

\$ goto SEARCHLIST_ARC

\$ endif

\$

\$ if f\$getdvi(DEV,\"served_device\") then INCLUDES_SERVED_DISK==1

\$

\$ if f\$length(SEARCHLIST).gt.0 then SEARCHLIST = SEARCHLIST + \",\"

\$ FULLDEVNAM = f\$getdvi(DEV,\"FULLDEVNAM\")

\$ SEARCHLIST = SEARCHLIST + \"\'\'FULLDEVNAM\'\[\'\'MMM\'\_ARC.\]\"

\$ call CHECK_DIRECTORY \'FULLDEVNAM\' \[\'MMM\'\_ARC\]

\$ IDX = IDX+1

\$ goto SEARCHLIST_ARC

\$SEARCHLIST_ARC_END:

\$ define/nolog/system/translation=(c) \'MMM\'\$ARC\$ \'SEARCHLIST\'

\$

\$ if MMM .nes. \"NSTX\" then goto MAKE_LNM

\$!

\$!====================

\$! Adding logic for NSTX\$NORMARC\$ and NSTX\$RAWARC\$ for later use by

\$! NSTX\$:\[DATA_MANAGEMENT\]NSTX_DAILY.COM in sending raw & normal
trees to

\$! separate archiving disks - PR 3/10/05

\$! Adding logic for NSTX\$OLD\$ and NSTX\$RAWOLD\$ for later use by

\$! NSTX\$:\[DATA_MANAGEMENT\]NSTX_OLDTOSANSLOW.COM in sending raw &
normal trees to

\$! separate slow SAN FATA disks - PR 8/7/06

\$!===================

\$!

\$!\$ write sys\$output \"Case is NSTX, define special searchlists for
ARC\"

\$ FDEV = f\$getdvi(NSTX_NORMARC_DISK,\"FULLDEVNAM\")

\$ define/nolog/system/translation=(c) NSTX\$NORMARC\$
\'FDEV\'\[nstx_arc.\]

\$ FDEV = f\$getdvi(NSTX_RAWARC_DISK,\"FULLDEVNAM\")

\$ define/nolog/system/translation=(c) NSTX\$RAWARC\$
\'FDEV\'\[nstx_arc.\]

\$ FDEV = f\$getdvi(NSTX_OLD_DISK,\"FULLDEVNAM\")

\$ define/nolog/system/translation=(c) NSTX\$OLD\$ \'FDEV\'\[nstx_arc.\]

\$ FDEV = f\$getdvi(NSTX_RAWOLD_DISK,\"FULLDEVNAM\")

\$ define/nolog/system/translation=(c) NSTX\$RAWOLD\$
\'FDEV\'\[nstx_arc.\]

\$

\$!===============================

\$!

\$

\$ MAKE_LNM:

\$
!\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\$ !Create logical name table for Machine MMM.

\$ !Define MDS databases in the new table.

\$
!\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\$ TABLE = \"LNM\$MDS\_\'\'MMM\'\"

\$ create/name_table/nolog/prot=(w:r)/parent=lnm\$system_directory
\'TABLE\'

\$

\$ call \'MMM\'\_DATABASES !create treename\$DATA\'s for machine MMM

\$

\$! treename\$DATA is the searchlist for all MDSplus files for
\"treename\".

\$! It will be define for each treename, using mmm\$NEW\$ and mmm\$ARC\$
as

\$! the device names. For example:

\$! \$ define MAGNETICS\$DATA mmm\$NEW\$:\[MAGNETICS\],-

\$! mmm\$MODELS\$:\[MAGNETICS\],-

\$! mmm\$ARC\$:\[MAGNETICS\],-

\$! mmm\$ARC\$:\[MAGNETICS.12.34\]

\$

\$ exit

\$ endsubroutine

\$

\$

\$!======================================================================

\$!======================================================================

\$

\$CHECK_DIRECTORY: subroutine

\$ DEV = P1

\$ DIRNAME = P2

\$ DEVDIR = DEV + DIRNAME

\$ if f\$parse(DEVDIR).eqs.\"\" then -

create/directory/owner=mdsplus/prot=(w:r) \'DEVDIR\' /log

\$ exit

\$ endsubroutine

\$

\$

\$!======================================================================

\$!======================================================================

\$

\$DEFINE_TREE: subroutine

\$ MMM = P1 !Machine name

\$ TREE = P2 !Tree name

\$ OWNER = P3 !Owner

\$ NEWIDX = P4 !\<optional\> specify \"n\" in mmm\$NEWn\$

\$

\$ TABLE = \"LNM\$MDS\_\'\'MMM\'\"

\$

\$ NEW_DEV := \'MMM\'\$NEW\'NEWIDX\'\$

\$ if .not.f\$getdvi(NEW_DEV,\"exists\")

\$ then

\$ write sys\$output f\$fao( -

\"!/!\_!10\*\* \*ERROR\* Device !AS does not exist !10\*\*!/\", -

NEW_DEV)

\$ exit 2

\$ endif

\$ MAX = f\$trnlnm(NEW_DEV,\"lnm\$system\",,,,\"MAX_INDEX\")

\$ IDX = 0

\$NEW_LOOP:

\$ DEV = f\$trnlnm(NEW_DEV,\"lnm\$system\",IDX)

\$ DEVDIR := \'DEV\'\[\'TREE\'\]

\$ if f\$parse(DEVDIR).eqs.\"\" then -

create/dir/owner=\'OWNER\'/prot=(w:r) \'DEVDIR\'/log

\$ IDX = IDX+1

\$ if IDX.le.MAX then goto NEW_LOOP

\$

\$ ARC_DEV := \'MMM\'\$ARC\$

\$ MAX = f\$trnlnm(ARC_DEV,\"lnm\$system\",,,,\"MAX_INDEX\")

\$ IDX = 0

\$ARC_LOOP:

\$ DEV = f\$trnlnm(ARC_DEV,\"lnm\$system\",IDX)

\$ DEVDIR := \'DEV\'\[\'TREE\'\]

\$ if f\$parse(DEVDIR).eqs.\"\" then -

create/dir/owner=\'OWNER\'/prot=(w:r) \'DEVDIR\'/log

\$ DEVDIR := \'DEV\'\[\'TREE\'.MODIFIED\]

\$ if f\$parse(DEVDIR).eqs.\"\" then -

create/dir/owner=\'OWNER\'/prot=(w:r) \'DEVDIR\'/log

\$

\$ DEVDIR := \'DEV\'\[trash\] !Ensure that \[TRASH\] dir exists on
mmm\$ARC\$

\$ if f\$parse(DEVDIR).eqs.\"\" then -

create/dir/owner=\'OWNER\'/prot=(w:r) \'DEVDIR\'/log

\$ IDX = IDX+1

\$ if IDX.le.MAX then goto ARC_LOOP

\$

\$ MODELS_DEV := \'MMM\'\$MODELS\$

\$ MAX = f\$trnlnm(MODELS_DEV,\"lnm\$system\",,,,\"MAX_INDEX\")

\$ IDX = 0

\$MODELS_LOOP:

\$ DEV = f\$trnlnm(MODELS_DEV,\"lnm\$system\",IDX)

\$ DEVDIR := \'DEV\'\[\'TREE\'\]

\$ if f\$parse(DEVDIR).eqs.\"\" then -

create/dir/owner=\'OWNER\'/prot=(w:r) \'DEVDIR\'/log

\$ IDX = IDX+1

\$ if IDX.le.MAX then goto MODELS_LOOP

\$

\$ define/nolog/table=\'TABLE\' \'TREE\'\$DATA
\'NEW_DEV\':\[\'TREE\'\],-

\'MODELS_DEV\':\[\'TREE\'\],-

\'ARC_DEV\':\[\'TREE\'\],-

\'ARC_DEV\':\[\'TREE\'.MODIFIED\]

\$

\$ exit

\$ endsubroutine

\$

\$

\$!======================================================================

\$!======================================================================

\$

\$NSTX_DATABASES: subroutine

\$! mmm Treename\<TAB\> -owner- \"new\"Idx

\$ call DEFINE_TREE NSTX NSTX NSTX_OWNER 1

\$ call DEFINE_TREE NSTX ACTIVESPEC NSTX_OWNER 1

\$ call DEFINE_TREE NSTX ACTIVESP_RAW NSTX_OWNER 2

\$ call DEFINE_TREE NSTX CAMERAS NSTX_OWNER 1

\$ call DEFINE_TREE NSTX CHI NSTX_OWNER 1

\$!\$ call DEFINE_TREE NSTX DCON NSTX_OWNER 1

\$ call DEFINE_TREE NSTX DERIVED NSTX_OWNER 1

\$ call DEFINE_TREE NSTX DUMMYDATA NSTX_OWNER 1

\$ call DEFINE_TREE NSTX DUMMY_RAW NSTX_OWNER 1

\$ call DEFINE_TREE NSTX ED NSTX_OWNER 1 !Electron Density

\$ call DEFINE_TREE NSTX EDGE NSTX_OWNER 1

\$ call DEFINE_TREE NSTX EDGE_RAW NSTX_OWNER 2

\$ call DEFINE_TREE NSTX EFIT NSTX_OWNER 1

\$ call DEFINE_TREE NSTX EFITRT NSTX_OWNER 1

\$ call DEFINE_TREE NSTX FUELING NSTX_OWNER 1

\$ call DEFINE_TREE NSTX ENGINEERING NSTX_OWNER 1

\$ call DEFINE_TREE NSTX GASPUFFIMGNG NSTX_OWNER 2

\$ call DEFINE_TREE NSTX MICROWAVE NSTX_OWNER 1

\$ call DEFINE_TREE NSTX MICROWAV_RAW NSTX_OWNER 2

\$ call DEFINE_TREE NSTX NBI NSTX_OWNER 2

\$ call DEFINE_TREE NSTX NSTX_TREND NSTX_OWNER 1 !Trending database

\$ call DEFINE_TREE NSTX OPERATIONS NSTX_OWNER 1

\$ call DEFINE_TREE NSTX OPS_RAW NSTX_OWNER 2

\$ call DEFINE_TREE NSTX PARTICLES NSTX_OWNER 1

\$ call DEFINE_TREE NSTX PASSIVESPEC NSTX_OWNER 1

\$ call DEFINE_TREE NSTX PSPEC_RAW NSTX_OWNER 2

\$ call DEFINE_TREE NSTX PEST NSTX_OWNER 1

\$ call DEFINE_TREE NSTX RF NSTX_OWNER 1

\$ call DEFINE_TREE NSTX TF_JOINTS NSTX_OWNER 1

\$!\$ call DEFINE_TREE NSTX TR NSTX_OWNER 1 !Transp

\$!\$ call DEFINE_TREE NSTX TRW NSTX_OWNER 1 !Transp

\$ call DEFINE_TREE NSTX WF NSTX_OWNER 1

\$ call DEFINE_TREE NSTX ENG_TREND NSTX_OWNER 1

\$

\$ !Special MPTSCALIB database, same as ACTIVESPEC

\$
!\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\$ define/nolog/table=LNM\$MDS_NSTX MPTSCALIB\$DATA ACTIVESPEC\$DATA

\$

\$ !Special TRANSP-related names \...

\$
!\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\$ define/nolog/table=LNM\$MDS_NSTX TFTR_DATA TR1:\[TRANSP.TFTR.DATA\]

\$ define/nolog/table=LNM\$MDS_NSTX RUNDATA PPL\$TRAN1,TFTR\$R2

\$ define/nolog/table=LNM\$MDS_NSTX TR_DISK
TFTR\$AW3:\[TR.\],TFTR\$AR:\[TR.\]

\$

\$!\$ !Define TRnn\$DATA logicals, nn=1 to 20 \...

\$!\$ I = 0
!\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\$!\$TRLOOP:

\$!\$ I = I+1

\$!\$ LOGNAME = f\$fao(\"TR!2ZL\$DATA\",I)

\$!\$ define/nolog/table=LNM\$MDS_NSTX \'LOGNAME\' TR\$DATA

\$!\$ if I.lt.20 then goto TRLOOP

\$

\$!\$ !Define TRW_username\$DATA logicals for \"work\"

\$!\$
!\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\$!\$ define/nolog/table=LNM\$MDS_NSTX TRW_AROSENBE\$DATA TRW\$DATA

\$!\$ define/nolog/table=LNM\$MDS_NSTX TRW_BUDNY\$DATA TRW\$DATA

\$!\$ define/nolog/table=LNM\$MDS_NSTX TRW_KAYE\$DATA TRW\$DATA

\$!\$ define/nolog/table=LNM\$MDS_NSTX TRW_LEBLANC\$DATA TRW\$DATA

\$!\$ define/nolog/table=LNM\$MDS_NSTX TRW_LUDESCHE\$DATA TRW\$DATA

\$!\$ define/nolog/table=LNM\$MDS_NSTX TRW_TRANSP\$DATA TRW\$DATA

\$

\$ !Define EFITnn\$DATA logical names, nn=1 to 20 \...

\$ I = 0
!\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\$EFITLOOP:

\$ I = I+1

\$ LOGNAME = f\$fao(\"EFIT!2ZL\$DATA\",I)

\$ define/nolog/table=LNM\$MDS_NSTX \'LOGNAME\' EFIT\$DATA

\$ if I.lt.20 then goto EFITLOOP

\$

\$!\$ !Define DCONnn\$DATA logical names, nn=1 to 20 \...

\$!\$ I = 0
!\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\$!\$DCONLOOP:

\$!\$ I = I+1

\$!\$ LOGNAME = f\$fao(\"DCON!2ZL\$DATA\",I)

\$!\$ define/nolog/table=LNM\$MDS_NSTX \'LOGNAME\' DCON\$DATA

\$!\$ if I.lt.20 then goto DCONLOOP

\$

\$ exit

\$ endsubroutine

\$

\$

\$!======================================================================

\$!======================================================================

\$

\$TEST_DATABASES: subroutine

\$! mmm Treename\<TAB\> -owner- \"new\"Idx

\$ call DEFINE_TREE TEST TEST TEST_OWNER 1

\$ call DEFINE_TREE TEST ACTIVESPEC TEST_OWNER 1

\$ call DEFINE_TREE TEST CAMERAS TEST_OWNER 1

\$ call DEFINE_TREE TEST DERIVED TEST_OWNER 1

\$ call DEFINE_TREE TEST EDGE TEST_OWNER 1

\$ call DEFINE_TREE TEST ED TEST_OWNER 1

\$ call DEFINE_TREE TEST EFIT TEST_OWNER 1

\$ call DEFINE_TREE TEST ENGINEERING TEST_OWNER 1

\$ call DEFINE_TREE TEST MICROWAVE TEST_OWNER 1

\$ call DEFINE_TREE TEST NBI TEST_OWNER 1

\$ call DEFINE_TREE TEST TEST_TREND TEST_OWNER 1 !Trending database

\$ call DEFINE_TREE TEST OPERATIONS TEST_OWNER 2

\$ call DEFINE_TREE TEST PARTICLES TEST_OWNER 1

\$ call DEFINE_TREE TEST PASSIVESPEC TEST_OWNER 1

\$ call DEFINE_TREE TEST PEST TEST_OWNER 1

\$ call DEFINE_TREE TEST RF TEST_OWNER 1

\$ call DEFINE_TREE TEST TESTTRANSP TEST_OWNER 1

\$ call DEFINE_TREE TEST WF TEST_OWNER 1

\$ call DEFINE_TREE TEST DUMMYDATA TEST_OWNER 1

\$

\$ !Special TRANSP-related names \...

\$
!\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\$ define/nolog/table=LNM\$MDS_NSTX TFTR_DATA TR1:\[TRANSP.TFTR.DATA\]

\$ define/nolog/table=LNM\$MDS_TEST RUNDATA PPL\$TRAN1,TFTR\$R2

\$ define/nolog/table=LNM\$MDS_TEST TR_DISK
TFTR\$AW3:\[TR.\],TFTR\$AR:\[TR.\]

\$

\$ !Define TESTTRANSPnn\$DATA logicals, nn=1 to 20 \...

\$ I = 0
!\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\$TESTTRANSPLOOP:

\$ I = I+1

\$ LOGNAME = f\$fao(\"TESTTRANSP!2ZL\$DATA\",I)

\$ define/nolog/table=LNM\$MDS_TEST \'LOGNAME\' TESTTRANSP\$DATA

\$ if I.lt.20 then goto TESTTRANSPLOOP

\$

\$ !Define EFITnn\$DATA logical names, nn=1 to 20 \...

\$ I = 0
!\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\$EFITLOOP:

\$ I = I+1

\$ LOGNAME = f\$fao(\"EFIT!2ZL\$DATA\",I)

\$ define/nolog/table=LNM\$MDS_TEST \'LOGNAME\' EFIT\$DATA

\$ if I.lt.20 then goto EFITLOOP

\$

\$ !Define DCONnn\$DATA logical names, nn=1 to 20 \...

\$ I = 0
!\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\$DCONLOOP:

\$ I = I+1

\$ LOGNAME = f\$fao(\"DCON!2ZL\$DATA\",I)

\$ define/nolog/table=LNM\$MDS_TEST \'LOGNAME\' DCON\$DATA

\$ if I.lt.20 then goto DCONLOOP

\$

\$ exit

\$ endsubroutine

\$

\$

\$!===============================================================

\$!===============================================================

\$

\$TRANSP_DATABASES: subroutine

\$! mmm Treename\<TAB\> -owner- \"new\"Idx

\$ call DEFINE_TREE TRANSP TRANSP TRANSPDATA

\$ exit

\$ endsubroutine

\$

\$

\$!===============================================================

\$!===============================================================

\$

\$TFTR_DATABASES: subroutine

\$! mmm Treename\<TAB\> -owner- \"new\"Idx

\$ call DEFINE_TREE TFTR TFTR TFTR_RESULTS_OWNER

\$ call DEFINE_TREE TFTR MAGNETICS TFTR_RESULTS_OWNER

\$ exit

\$ endsubroutine

\$ endsubroutine

APPENDIX \### Device Support

**EUROPA\$ librar/list/names mds\$devices.olb**

Directory of ALPHA SHAREABLE IMAGE SYMBOL TABLE library
MDS\$PPPLROOT:\[SYSLIB\]MDS

\$DEVICES.OLB;10 on 25-AUG-2006 10:58:36

Creation date: 28-JUL-2000 14:30:44 Creator: Librarian A09-19

Revision date: 3-NOV-2005 16:48:34 Library format: 3.0

Number of modules: 4 Max. key length: 39

Other entries: 449 Preallocated index blocks: 58

Recoverable deleted blocks: 1 Total index blocks used: 60

Max. Number history records: 20 Library history records: 20

**Module HYBRID\$DEVICES**

HYB_MATRIX\$ADD

HYB_MATRIX\$DW_SETUP

HYB_MATRIX\$INIT

HYB_MATRIX\$INIT_CYCLIC

HYB_MATRIX\$LOAD_MATRIX

HYB_MATRIX\$PART_NAME

HYB_MATRIX\$STORE

HYB_MATRIX\$WAIT

HYB_WAVEGEN\$ADD

HYB_WAVEGEN\$ARM

HYB_WAVEGEN\$INIT

HYB_WAVEGEN\$PART_NAME

HYB_WAVEGEN\$TRIGGER

HYB_WAVEGEN\$WAIT

HYB_WAVEGEN64\$ADD

HYB_WAVEGEN64\$ARM

HYB_WAVEGEN64\$INIT

HYB_WAVEGEN64\$PART_NAME

HYB_WAVEGEN64\$TRIGGER

HYB_WAVEGEN64\$WAIT

**Module MIT\$DEVICES**

(reformatted to save space)

**A12\$ADD** A12\$INIT A12\$PART_NAME

A12\$STOP A12\$STORE A12\$TRIGGER

**A14\$ADD** A14\$INIT A14\$PART_NAME

A14\$START A14\$STOP A14\$STORE

**A3204\$ADD** A3204\$INIT A3204\$PART_NAME

A3204\$STORE

**B2408\$ADD** B2408\$INIT B2408\$PART_NAME

B2408\$STORE

**B3224\$ADD** B3224\$INIT B3224\$PART_NAME

**B5910A\$ADD** B5910A\$DW_SETUP B5910A\$INIT

B5910A\$LINFIT B5910A\$PART_NAME B5910A\$SPLFIT

**DSP2904\$ADD** DSP2904\$DW_SETUP DSP2904\$INIT

DSP2904\$PART_NAME DSP2904\$STORE

**EC727\$ADD** EC727\$INIT EC727\$PART_NAME

EC727\$STORE

**FERA\$ADD** FERA\$INIT FERA\$PART_NAME

FERA\$STORE

**H908\$ADD** H908\$INIT H908\$PART_NAME

H908\$STOP H908\$STORE H908\$TRIGGER

**H911\$ADD** H911\$INIT H911\$PART_NAME

H911\$STORE

**H912\$ADD** H912\$INIT H912\$PART_NAME

H912\$STOP H912\$STORE H912\$TRIGGER

**HM650\$ADD** HM650\$INIT HM650\$PART_NAME

HM650\$TRIGGER

**HV1440\$ADD** HV1440\$INIT HV1440\$OFF

HV1440\$ON HV1440\$PART_NAME HV1440\$STORE

**HV1443\$ADD** HV1443\$GET_SETTINGS HV1443\$PART_NAME

**HV4032\$ADD** HV4032\$INIT HV4032\$OFF

HV4032\$ON HV4032\$PART_NAME HV4032\$STORE

**HV4032A1\$ADD** HV4032A1\$GET_SETTINGS

HV4032A1\$PART_NAME

**IDL\$ADD** IDL\$EXECUTE IDL\$PART_NAME

**INCAA16\$ADD** INCAA16\$ARM INCAA16\$INIT

INCAA16\$PART_NAME INCAA16\$STORE INCAA16\$TRIGGER

**INCAA4\$ADD** INCAA4\$ARM INCAA4\$INIT

INCAA4\$PART_NAME INCAA4\$STORE INCAA4\$TRIGGER

**INCAA6\$ADD** INCAA6\$ARM INCAA6\$INIT

INCAA6\$PART_NAME INCAA6\$STORE INCAA6\$TRIGGER

**J1819\$ADD** J1819\$INIT J1819\$PART_NAME

J1819\$STORE J1819\$TRIGGER

**J221\$ADD** J221\$INIT J221\$PART_NAME

J221\$TRIGGER

**J412\$ADD** J412\$INIT J412\$PART_NAME

**JOERGER_ADC\$ADD** JOERGER_ADC\$PART_NAME

JOERGER_ADC\$STORE

**JOERGER_ADCP\$ADD** JOERGER_ADCP\$INIT JOERGER_ADCP\$PART_NAME

JOERGER_ADCP\$STORE

**JOERGER_CG\$ADD** JOERGER_CG\$INIT JOERGER_CG\$PART_NAME

JOERGER_CG\$STOP

**JOERGER_DAC16\$ADD** JOERGER_DAC16\$INIT JOERGER_DAC16\$PART_NAME

**JOERGER_TR16\$ADD** JOERGER_TR16\$INIT JOERGER_TR16\$PART_NAME

JOERGER_TR16\$STORE JOERGER_TR16\$TRIGGER

**JOERGER_TR612\$ADD** JOERGER_TR612\$INIT JOERGER_TR612\$PART_NAME

JOERGER_TR612\$STOP JOERGER_TR612\$STORE JOERGER_TR612\$TRIGGER

**JOERGER_TR812\$ADD** JOERGER_TR812\$INIT JOERGER_TR812\$PARTIAL_STORE

JOERGER_TR812\$PART_NAME JOERGER_TR812\$STORE JOERGER_TR812\$TRIGGER

**L2232\$ADD** L2232\$INIT L2232\$PART_NAME

L2232\$STORE

**L2256\$ADD** L2256\$INIT L2256\$PART_NAME

L2256\$STORE L2256\$TRIGGER

**L2415\$ADD** L2415\$INIT L2415\$PART_NAME

L2415\$STORE

**L3512\$ADD** L3512\$INIT L3512\$PART_NAME

L3512\$STORE

**L4202\$ADD** L4202\$INIT L4202\$PART_NAME

L4202\$STORE

**L6810\$ADD** L6810\$INIT L6810\$PART_NAME

L6810\$STORE L6810\$TRIGGER

**L6810A\$ADD** L6810A\$INIT L6810A\$PART_NAME

L6810A\$STORE L6810A\$TRIGGER

**L6810B\$ADD** L6810B\$INIT L6810B\$PART_NAME

L6810B\$STORE L6810B\$TRIGGER

**L6810C\$ADD** L6810C\$INIT L6810C\$PART_NAME

L6810C\$STORE L6810C\$TRIGGER

**L8100\$ADD** L8100\$INIT L8100\$PART_NAME

L8100\$STORE

**L8201\$ADD** L8201\$INIT L8201\$PART_NAME

L8201\$STORE

**L8206\$ADD** L8206\$INIT L8206\$PART_NAME

L8206\$STORE

**L8210\$ADD** L8210\$DW_SETUP L8210\$INIT

L8210\$PART_NAME L8210\$STORE

**L8212_04\$ADD** L8212_04\$DW_SETUP L8212_04\$INIT

L8212_04\$PART_NAME L8212_04\$STORE

**L8212_08\$ADD** L8212_08\$DW_SETUP L8212_08\$INIT

L8212_08\$PART_NAME L8212_08\$STORE

**L8212_16\$ADD** L8212_16\$DW_SETUP L8212_16\$INIT

L8212_16\$PART_NAME L8212_16\$STORE

**L8212_32\$ADD** L8212_32\$DW_SETUP L8212_32\$INIT

L8212_32\$PART_NAME L8212_32\$STORE

**L8501\$ADD** L8501\$DW_SETUP L8501\$INIT

L8501\$PART_NAME L8501\$STORE

**L8590\$ADD** L8590\$INIT L8590\$PART_NAME

L8590\$STORE

**L8590_MEM\$ADD** L8590_MEM\$DW_SETUP L8590_MEM\$INIT

L8590_MEM\$PART_NAME L8590_MEM\$STORE

**L8590_SCLR\$ADD**

L8590_SCLR\$PART_NAME

**L8818\$ADD** L8818\$INIT L8818\$PART_NAME

L8818\$STORE L8818\$TRIGGER

**L8828\$ADD** L8828\$INIT L8828\$PART_NAME

L8828\$STORE L8828\$TRIGGER

**MDSDCL\$ADD** MDSDCL\$DW_SETUP MDSDCL\$EXECUTE

MDSDCL\$PART_NAME

**MIT_CLOCK\$ADD** MIT_CLOCK\$GET_SETUP MIT_CLOCK\$PART_NAME

**MIT_DCLOCK\$ADD** MIT_DCLOCK\$GET_SETUP MIT_DCLOCK\$PART_NAME

**MIT_DECODER\$ADD** MIT_DECODER\$INIT MIT_DECODER\$PART_NAME

**MIT_ENCODER\$ADD** MIT_ENCODER\$INIT MIT_ENCODER\$PART_NAME

MIT_ENCODER\$SET_EVENT MIT_ENCODER\$TRIGGER

**MIT_GATE\$ADD** MIT_GATE\$GET_SETUP MIT_GATE\$PART_NAME

**MIT_GCLOCK\$ADD** MIT_GCLOCK\$GET_SETUP MIT_GCLOCK\$PART_NAME

**MIT_PULSE\$ADD** MIT_PULSE\$GET_SETUP MIT_PULSE\$PART_NAME

**MIT\_\_CLOCK\$ADD** MIT\_\_CLOCK\$GET_SETUP MIT\_\_CLOCK\$PART_NAME

**MIT\_\_DCLOCK\$ADD** MIT\_\_DCLOCK\$GET_SETUP MIT\_\_DCLOCK\$PART_NAME

**MIT\_\_GATE\$ADD** MIT\_\_GATE\$GET_SETUP MIT\_\_GATE\$PART_NAME

**MPB\_\_DECODER\$ADD** MPB\_\_DECODER\$DW_SETUP MPB\_\_DECODER\$INIT

MPB\_\_DECODER\$PART_NAME

**PARAGON_HIST\$ADD** PARAGON_HIST\$INSERT PARAGON_HIST\$PART_NAME

PARAGON_HIST\$STORE

**PARAGON_RPT\$ADD** PARAGON_RPT\$PART_NAME PARAGON_RPT\$STORE

**PREAMP\$ADD** PREAMP\$DW_SETUP PREAMP\$INIT

PREAMP\$PART_NAME

**RETICON120\$ADD** RETICON120\$DW_SETUP RETICON120\$INIT

RETICON120\$PART_NAME RETICON120\$STORE RETICON120\$TRIGGER

**T2812\$ADD** T2812\$PART_NAME

**T2814\$ADD** T2814\$PART_NAME

**T2824\$ADD** T2824\$PART_NAME

**T2825\$ADD** T2825\$PART_NAME

**T2860\$ADD** T2860\$PART_NAME

**T4012\$ADD** T4012\$DW_SETUP T4012\$INIT

T4012\$PART_NAME T4012\$STORE T4012\$TRIGGER

**UMCCD\$ADD** UMCCD\$PART_NAME

**U_OF_M_SPECT\$ADD** U_OF_M_SPECT\$INIT U_OF_M_SPECT\$PART_NAME

U_OF_M_SPECT\$STORE

**Module PPPL\$DEVICES**

**DUMMY908\$ADD** DUMMY908\$INIT DUMMY908\$PART_NAME

DUMMY908\$SELFTEST DUMMY908\$STOP DUMMY908\$STORE

DUMMY908\$TRIGGER

**H320\$ADD** H320\$INIT H320\$PART_NAME

H320\$STORE

**H321\$ADD** H321\$INIT H321\$PART_NAME

H321\$STORE

**H322\$ADD** H322\$INIT H322\$PART_NAME

H322\$STORE

**H356\$ADD** H356\$INIT H356\$PART_NAME

H356\$STORE

**H404\$ADD** H404\$DW_SETUP H404\$INIT

H404\$PART_NAME

**H404COMM\$ADD** H404COMM\$DW_SETUP H404COMM\$INIT

H404COMM\$PART_NAME

**H408\$ADD** H408\$INIT H408\$PART_NAME

H408\$STORE

**H409\$ADD** H409\$INIT H409\$PART_NAME

H409\$STOP H409\$TRIGGER

**H412\$ADD** H412\$INIT H412\$PART_NAME

**H908PPPL\$ADD** H908PPPL\$INIT H908PPPL\$PART_NAME

H908PPPL\$SELFTEST H908PPPL\$STOP H908PPPL\$STORE

H908PPPL\$TRIGGER

**H908T\$AD** H908T\$INIT H908T\$PART_NAME

H908T\$SELFTEST H908T\$STOP H908T\$STORE

H908T\$TRIGGER

**H911PPPL\$ADD** H911PPPL\$INIT H911PPPL\$PART_NAME

H911PPPL\$STORE

**H912R\$ADD** H912R\$INIT H912R\$PART_NAME

H912R\$STOP H912R\$STORE H912R\$TRIGGER

**J_TR612_PPPL\$ADD** J_TR612_PPPL\$INIT J_TR612_PPPL\$PART_NAME

J_TR612_PPPL\$STORE

**K3421\$ADD** K3421\$INIT K3421\$PART_NAME

K3421\$STORE

**K3525\$ADD** K3525\$PART_NAME K3525\$STORE

**L4202ONLY\$ADD** L4202ONLY\$INIT L4202ONLY\$PART_NAME

L4202ONLY\$STORE

**L6810BPPPL\$ADD** L6810BPPPL\$INIT L6810BPPPL\$PART_NAME

L6810BPPPL\$STORE L6810BPPPL\$TRIGGER

**L6810ED\$ADD** L6810ED\$INIT L6810ED\$PART_NAME

L6810ED\$STORE L6810ED\$TRIGGER

**L6810PPPL\$ADD** L6810PPPL\$INIT L6810PPPL\$PART_NAME

L6810PPPL\$STORE L6810PPPL\$TRIGGER

**Module RCPDAQ\$DEVICES**

**GL_AD1020\$ADD**

GL_AD1020\$INIT

GL_AD1020\$PART_NAME

GL_AD1020\$STORE

GL_AD1020\$TRIGGER

**NSTX0:\[MDSPLUS_LOCAL.CAMAC\]PPPL\$DEVICES.EXE built from
PPPL\$DEVICESLNK.COM**

> KEES\$ mov nstx0:\[mdsplus_local.camac\]
>
> NSTX0:\[MDSPLUS_LOCAL.CAMAC\]
>
> KEES\$ dir \*.com;
>
> Directory NSTX0:\[MDSPLUS_LOCAL.CAMAC\]
>
> DEFS.COM;3 PPPL\$DEVICESLNK.COM;76
>
> RCPDAQ\$DEVICESLNK.COM;9
>
> Total of 3 files.
>
> KEES\$ type PPPL\$DEVICESLNK.COM
>
> \$! Edit: 05-Jan-05 PR changing kees0 references to nstx0
>
> \$! Edit: 02-Aug-00 PR adding H321 8 chan DAC, storing settings only
>
> \$! Edit: 14-Apr-00 TG re-adding L6810BPPPL: \"retry-on-error\"
> capability
>
> \$! Edit: 14-Apr-00 PR adding temporary H404COMM, will eventually be
> new H404
>
> \$! Edit: 06-Mar-2000 PR adding temporary L6810ED
>
> \$! Edit: 15-Dec-99 PR removing L6810B - can\'t use fstop
>
> \$! Edit: 08-Dec-99 PR adding H908T - for Timing correction
>
> \$! Edit: 22-Jul-99 PR moved H404 source code to KEES0,
>
> \$! removed \"testmpb_decoder\"
>
> \$! Edit: 21-Jul-99 PR added K3421 digital input w buffer
>
> \$! Edit: 21-Jun-99 PR changed directories from NSTX\$ to
> BE1:\[NSTX.\]
>
> \$! since NSTX\$ is now KEES0:\[NSTX.\]
>
> \$!
>
> \$ link/share/exe=pppl\$devices \'P1\' sys\$input/opt
>
> nstx0:\[mdsplus_local.camac.h404\]h404_gen
>
> nstx0:\[mdsplus_local.camac.h404\]h404
>
> nstx0:\[mdsplus_local.camac.h404\]h404comm_gen
>
> nstx0:\[mdsplus_local.camac.h404\]h404comm
>
> nstx0:\[mdsplus_local.camac.h409\]h409_gen
>
> nstx0:\[mdsplus_local.camac.h409\]h409
>
> nstx0:\[mdsplus_local.camac.h908\]h908pppl_gen
>
> nstx0:\[mdsplus_local.camac.h908\]h908pppl
>
> nstx0:\[mdsplus_local.camac.h908.h908t\]h908t_gen
>
> nstx0:\[mdsplus_local.camac.h908.h908t\]h908t
>
> nstx0:\[mdsplus_local.camac.h908\]dummy908_gen
>
> nstx0:\[mdsplus_local.camac.h908\]dummy908
>
> nstx0:\[mdsplus_local.camac.h911\]h911pppl
>
> nstx0:\[mdsplus_local.camac.h911\]h911pppl_gen
>
> nstx0:\[mdsplus_local.camac.h320\]h320.obj
>
> nstx0:\[mdsplus_local.camac.h320\]h320_gen.obj
>
> nstx0:\[mdsplus_local.camac.h321\]h321.obj
>
> nstx0:\[mdsplus_local.camac.h321\]h321_gen.obj
>
> nstx0:\[mdsplus_local.camac.h322\]h322.obj
>
> nstx0:\[mdsplus_local.camac.h322\]h322_gen.obj
>
> nstx0:\[mdsplus_local.camac.ks3525\]k3525.obj
>
> nstx0:\[mdsplus_local.camac.ks3525\]k3525_gen.obj
>
> nstx0:\[mdsplus_local.camac.ks3421\]k3421
>
> nstx0:\[mdsplus_local.camac.ks3421\]k3421_gen
>
> nstx0:\[mdsplus_local.camac.l6810\]l6810pppl_gen
>
> nstx0:\[mdsplus_local.camac.l6810\]l6810pppl
>
> nstx0:\[mdsplus_local.camac.l6810b\]l6810bpppl_gen
>
> nstx0:\[mdsplus_local.camac.l6810b\]l6810bpppl
>
> nstx0:\[mdsplus_local.camac.l6810ed\]l6810ed_gen
>
> nstx0:\[mdsplus_local.camac.l6810ed\]l6810ed
>
> nstx0:\[mdsplus_local.camac.h912r\]h912r
>
> nstx0:\[mdsplus_local.camac.h912r\]h912r_gen
>
> nstx0:\[mdsplus_local.camac.h356\]h356
>
> nstx0:\[mdsplus_local.camac.h356\]h356_gen
>
> nstx0:\[mdsplus_local.camac.h412\]h412
>
> nstx0:\[mdsplus_local.camac.h412\]h412_gen
>
> nstx0:\[mdsplus_local.camac.l4202only\]l4202only_gen
>
> nstx0:\[mdsplus_local.camac.l4202only\]l4202only
>
> nstx0:\[mdsplus_local.camac.h408\]h408_gen
>
> nstx0:\[mdsplus_local.camac.h408\]h408
>
> nstx0:\[mdsplus_local.camac.tr612\]j_tr612_pppl_gen
>
> nstx0:\[mdsplus_local.camac.tr612\]j_tr612_pppl
>
> nstx0:\[mdsplus_local.camac\]messages.obj
>
> nstx0:\[mdsplus_local.camac\]mit_messages.obj
>
> das\$:\[util\]dasutil/include=(dascam\$error,getmsg,getsyi)
>
> pppl_res:\[dasutil\]dasutil/lib
>
> sys\$share:treeshr/share
>
> sys\$share:tdishr/share
>
> sys\$share:camshr/share
>
> sys\$share:devshr/share
>
> sys\$share:mdsshr/share
>
> sys\$share:xmdsshr/share
>
> sys\$share:gen_deviceshr/share
>
> sys\$share:decw\$mrmlibshr12/share
>
> sys\$share:decw\$dxmlibshr12/share
>
> sys\$share:decw\$xmlibshr12/share
>
> sys\$share:decw\$xtlibshrr5/share
>
> sys\$share:decw\$xlibshr/share
>
> symbol_vector = (-
>
> H404\$ADD=data,-
>
> H404\$PART_NAME=data,-
>
> H404\$DW_SETUP=data,-
>
> H404\$INIT=data,-
>
> H404COMM\$ADD=data,-
>
> H404COMM\$PART_NAME=data,-
>
> H404COMM\$DW_SETUP=data,-
>
> H404COMM\$INIT=data,-
>
> H409\$ADD=data,-
>
> H409\$PART_NAME=data,-
>
> H409\$INIT=data,-
>
> H409\$TRIGGER=data,-
>
> H409\$STOP=data,-
>
> DUMMY908\$ADD=data,-
>
> DUMMY908\$PART_NAME=data,-
>
> DUMMY908\$INIT=data,-
>
> DUMMY908\$STORE=data,-
>
> DUMMY908\$STOP=data,-
>
> DUMMY908\$SELFTEST=data,-
>
> DUMMY908\$TRIGGER=data,-
>
> H908PPPL\$ADD=data,-
>
> H908PPPL\$PART_NAME=data,-
>
> H908PPPL\$INIT=data,-
>
> H908PPPL\$STORE=data,-
>
> H908PPPL\$STOP=data,-
>
> H908PPPL\$SELFTEST=data,-
>
> H908PPPL\$TRIGGER=data,-
>
> H908T\$ADD=data,-
>
> H908T\$PART_NAME=data,-
>
> H908T\$INIT=data,-
>
> H908T\$STORE=data,-
>
> H908T\$STOP=data,-
>
> H908T\$SELFTEST=data,-
>
> H908T\$TRIGGER=data,-
>
> H321\$ADD=data,-
>
> H321\$PART_NAME=data,-
>
> H321\$INIT=data,-
>
> H321\$STORE=data,-
>
> H322\$ADD=data,-
>
> H322\$PART_NAME=data,-
>
> H322\$INIT=data,-
>
> H322\$STORE=data,-
>
> K3525\$ADD=data,-
>
> K3525\$PART_NAME=data,-
>
> K3525\$STORE=data,-
>
> K3421\$ADD=data,-
>
> K3421\$PART_NAME=data,-
>
> K3421\$INIT=data,-
>
> K3421\$STORE=data,-
>
> L6810PPPL\$ADD=data,-
>
> L6810PPPL\$PART_NAME=data,-
>
> L6810PPPL\$INIT=data,-
>
> L6810PPPL\$STORE=data,-
>
> L6810PPPL\$TRIGGER=data,-
>
> L6810BPPPL\$ADD=data,-
>
> L6810BPPPL\$PART_NAME=data,-
>
> L6810BPPPL\$INIT=data,-
>
> L6810BPPPL\$STORE=data,-
>
> L6810BPPPL\$TRIGGER=data,-
>
> L6810ED\$ADD=data,-
>
> L6810ED\$PART_NAME=data,-
>
> L6810ED\$INIT=data,-
>
> L6810ED\$STORE=data,-
>
> L6810ED\$TRIGGER=data,-
>
> H912R\$ADD=data,-
>
> H912R\$PART_NAME=data,-
>
> H912R\$INIT=data,-
>
> H912R\$STOP=data,-
>
> H912R\$STORE=data,-
>
> H912R\$TRIGGER=data,-
>
> H356\$ADD=data,-
>
> H356\$PART_NAME=data,-
>
> H356\$INIT=data,-
>
> H356\$STORE=data, -
>
> H412\$ADD=data,-
>
> H412\$PART_NAME=data,-
>
> H412\$INIT=data, -
>
> L4202ONLY\$ADD=data,-
>
> L4202ONLY\$PART_NAME=data,-
>
> L4202ONLY\$INIT=data, -
>
> L4202ONLY\$STORE=data, -
>
> H408\$ADD=data,-
>
> H408\$PART_NAME=data,-
>
> H408\$INIT=data, -
>
> H408\$STORE=data -
>
> ,H911PPPL\$ADD=data -
>
> ,H911PPPL\$PART_NAME=data -
>
> ,H911PPPL\$INIT=data -
>
> ,H911PPPL\$STORE=data -
>
> ,J_TR612_PPPL\$ADD=data -
>
> ,J_TR612_PPPL\$PART_NAME=data -
>
> ,J_TR612_PPPL\$INIT=data -
>
> ,J_TR612_PPPL\$STORE=data -
>
> ,H320\$ADD=data -
>
> ,H320\$PART_NAME=data -
>
> ,H320\$INIT=data -
>
> ,H320\$STORE=data -
>
> )

MOTIF UID files for device forms for Traverser

KEES\$ dir mds\$root:\[syslib\]\*.uid;

Directory MDS\$PPPLROOT:\[SYSLIB\]

DTACQ16.UID;2 DUMMY908.UID;2 GL_AD1020.UID;11 H320.UID;1

H321.UID;1 H322.UID;9 H356.UID;2 H404.UID;98

H404COMM.UID;19 H408.UID;7 H409.UID;26 H412.UID;1

H904.UID;72 H908.UID;1 H908PPPL.UID;2 H908T.UID;1

H911PPPL.UID;2 H912.UID;1 H912R.UID;3 J412.UID;3

J_TR612_PPPL.UID;1 K3421.UID;1 K3525.UID;5 L4202ONLY.UID;7

L6810A.UID;1 L6810B.UID;1 L6810BPPPL.UID;2 L6810ED.UID;5

L6810PPPL.UID;2 TESTMPB_DECODER.UID;1 XCOUNTDOWN.UID;18

Total of 31 files.

Directory MDS\$MITROOT:\[SYSLIB\]

A12.UID;5 A14.UID;6 A3204.UID;5 ACTIONS.UID;6

ACTMON.UID;9 AUTO_RETRIEVE.UID;6 B2408.UID;5 B3224.UID;5

B5910A.UID;14 CW_WVEDIT.UID;4 DSP2904.UID;5 DT100.UID;3

DT101.UID;18 DWPAD.UID;9 DWSCOPE.UID;30 EC727.UID;2

FERA.UID;5 H908.UID;2 H911.UID;5 H912.UID;2

HM650.UID;5 HV1440.UID;5 HV1443.UID;5 HV4032.UID;5

HV4032A1.UID;5 HYB_MATRIX.UID;2 IDL.UID;6 INCAA16.UID;7

INCAA4.UID;5 INCAA6.UID;9 J1819.UID;6 J221.UID;8

J412.UID;7 JOERGER_ADCP.UID;5 JOERGER_CG.UID;2 JOERGER_DAC16.UID;5

JOERGER_TR16.UID;9 JOERGER_TR612.UID;3 JOERGER_TR812.UID;5 L2232.UID;5

L2256.UID;2 L2415.UID;5 L3512.UID;5 L4202.UID;5

L6810.UID;12 L6810A.UID;2 L6810B.UID;5 L6810C.UID;1

L8100.UID;2 L8201.UID;5 L8206.UID;3 L8210.UID;5

L8210_HEADERS.UID;5 L8212.UID;6 L8212_HEADERS.UID;8 L8501.UID;6

L8590.UID;5 L8590_MEM.UID;5 L8590_SCLR.UID;5 L8818.UID;2

L8828.UID;3 MDSDCL.UID;5 MIT_CLOCK.UID;5 MIT_DCLOCK.UID;6

MIT_DECODER.UID;5 MIT_ENCODER.UID;5 MIT_GATE.UID;5 MIT_GCLOCK.UID;5

MIT_PULSE.UID;5 MIT\_\_CLOCK.UID;3 MIT\_\_DCLOCK.UID;2 MIT\_\_GATE.UID;5

MPB\_\_DECODER.UID;12 PARAGON_HIST.UID;5 PARAGON_RPT.UID;5 PREAMP.UID;5

RETICON120.UID;5 STATE.UID;3 T4012.UID;5 TRAVERSER.UID;10

UMCCD.UID;10 U_OF_M_SPECT.UID;5 WAVEEDIT.UID;3 XMDSDIGCHANS.UID;6

XMDSINPUT.UID;5 XMDSXDBOX.UID;11 XMDS_USAGE_ICONS.UID;6

Total of 87 files.

Grand total of 2 directories, 118 files.

C Language Device Support: Output from processing A12.GEN file

> **a12.h**

#define A12\$K_CONG_NODES 25

#define A12\$N_HEAD 0

#define A12\$N_NAME 1

#define A12\$N_COMMENT 2

#define A12\$N_EXT_CLOCK_IN 3

#define A12\$N_STOP_TRIG 4

#define A12\$N_INPUT_1 5

#define A12\$N_INPUT_1_STARTIDX 6

#define A12\$N_INPUT_1_ENDIDX 7

#define A12\$N_INPUT_2 8

#define A12\$N_INPUT_2_STARTIDX 9

#define A12\$N_INPUT_2_ENDIDX 10

#define A12\$N_INPUT_3 11

#define A12\$N_INPUT_3_STARTIDX 12

#define A12\$N_INPUT_3_ENDIDX 13

#define A12\$N_INPUT_4 14

#define A12\$N_INPUT_4_STARTIDX 15

#define A12\$N_INPUT_4_ENDIDX 16

#define A12\$N_INPUT_5 17

#define A12\$N_INPUT_5_STARTIDX 18

#define A12\$N_INPUT_5_ENDIDX 19

#define A12\$N_INPUT_6 20

#define A12\$N_INPUT_6_STARTIDX 21

#define A12\$N_INPUT_6_ENDIDX 22

#define A12\$N_INIT_ACTION 23

#define A12\$N_STORE_ACTION 24

typedef struct {

struct dsc\$descriptor_xd \*\_\_xds;

int \_\_num_xds;

int head_nid;

struct dsc\$descriptor \*name;

struct dsc\$descriptor \*ext_clock_in;

} InInitStruct;

typedef struct {

struct dsc\$descriptor_xd \*\_\_xds;

int \_\_num_xds;

int head_nid;

struct dsc\$descriptor \*name;

} InTriggerStruct;

typedef struct {

struct dsc\$descriptor_xd \*\_\_xds;

int \_\_num_xds;

int head_nid;

struct dsc\$descriptor \*name;

} InStopStruct;

**a12_gen.c**

#include \<mds_gendevice.h\>

**#include \"A12.h\"**

int **A12\$ADD**(struct dsc\$descriptor \*name_d_ptr, struct
dsc\$descriptor \*dummy_d_pt

r, int \*nid_ptr)

{

static \$DESCRIPTOR(library_d, \"MIT\$DEVICES\");

static \$DESCRIPTOR(model_d, \"A12\");

static \$DESCRIPTOR_CONGLOM(conglom_d, &library_d, &model_d, 0, 0);

int curr_nid, old_nid, head_nid, status;

short flags = NCI\$M_WRITE_ONCE;

NCI_ITM flag_itm\[\] = {{2, NCI\$\_SET_FLAGS, 0, 0},{0, 0, 0, 0}};

flag_itm\[0\].nci_itm\$a_pointer = (unsigned char \*)&flags;

status = TREE\$START_CONGLOMERATE(&A12\$K_CONG_NODES);

if (!(status & 1)) return status;

status = TREE\$ADD_NODE(name_d_ptr, &head_nid, &TREE\$K_USAGE_DEVICE);

if (!(status & 1)) return status;

\*nid_ptr = head_nid;

status = TREE\$SETNCI(&head_nid, flag_itm);

status = TREE\$PUT_RECORD(&head_nid, (struct dsc\$descriptor
\*)&conglom_d);

if (!(status & 1)) return status;

status = TREE\$GET_DEFAULT_NID(&old_nid);

if (!(status & 1)) return status;

status = TREE\$SET_DEFAULT_NID(&head_nid);

if (!(status & 1)) return status;

\$ADD_NODE(:NAME, TREE\$K_USAGE_TEXT)

\$ADD_NODE(:COMMENT, TREE\$K_USAGE_TEXT)

\$ADD_NODE(:EXT_CLOCK_IN, TREE\$K_USAGE_AXIS)

flags \|= NCI\$M_NO_WRITE_SHOT;

status = TREE\$SETNCI(&curr_nid, flag_itm);

\$ADD_NODE_FLOAT(:STOP_TRIG, 0. , TREE\$K_USAGE_NUMERIC)

flags \|= NCI\$M_NO_WRITE_SHOT;

status = TREE\$SETNCI(&curr_nid, flag_itm);

\$ADD_NODE(:INPUT_1, TREE\$K_USAGE_SIGNAL)

flags \|= NCI\$M_WRITE_ONCE;

flags \|= NCI\$M_COMPRESS_ON_PUT;

flags \|= NCI\$M_NO_WRITE_MODEL;

status = TREE\$SETNCI(&curr_nid, flag_itm);

\$ADD_NODE(:INPUT_1:STARTIDX, TREE\$K_USAGE_NUMERIC)

flags \|= NCI\$M_NO_WRITE_SHOT;

status = TREE\$SETNCI(&curr_nid, flag_itm);

\$ADD_NODE(:INPUT_1:ENDIDX, TREE\$K_USAGE_NUMERIC)

flags \|= NCI\$M_NO_WRITE_SHOT;

status = TREE\$SETNCI(&curr_nid, flag_itm);

\$ADD_NODE(:INPUT_2, TREE\$K_USAGE_SIGNAL)

flags \|= NCI\$M_WRITE_ONCE;

flags \|= NCI\$M_COMPRESS_ON_PUT;

flags \|= NCI\$M_NO_WRITE_MODEL;

status = TREE\$SETNCI(&curr_nid, flag_itm);

\$ADD_NODE(:INPUT_2:STARTIDX, TREE\$K_USAGE_NUMERIC)

flags \|= NCI\$M_NO_WRITE_SHOT;

status = TREE\$SETNCI(&curr_nid, flag_itm);

\$ADD_NODE(:INPUT_2:ENDIDX, TREE\$K_USAGE_NUMERIC)

flags \|= NCI\$M_NO_WRITE_SHOT;

status = TREE\$SETNCI(&curr_nid, flag_itm);

\$ADD_NODE(:INPUT_3, TREE\$K_USAGE_SIGNAL)

flags \|= NCI\$M_WRITE_ONCE;

flags \|= NCI\$M_COMPRESS_ON_PUT;

flags \|= NCI\$M_NO_WRITE_MODEL;

status = TREE\$SETNCI(&curr_nid, flag_itm);

\$ADD_NODE(:INPUT_3:STARTIDX, TREE\$K_USAGE_NUMERIC)

flags \|= NCI\$M_NO_WRITE_SHOT;

status = TREE\$SETNCI(&curr_nid, flag_itm);

\$ADD_NODE(:INPUT_3:ENDIDX, TREE\$K_USAGE_NUMERIC)

flags \|= NCI\$M_NO_WRITE_SHOT;

status = TREE\$SETNCI(&curr_nid, flag_itm);

\$ADD_NODE(:INPUT_4, TREE\$K_USAGE_SIGNAL)

flags \|= NCI\$M_WRITE_ONCE;

flags \|= NCI\$M_COMPRESS_ON_PUT;

flags \|= NCI\$M_NO_WRITE_MODEL;

status = TREE\$SETNCI(&curr_nid, flag_itm);

\$ADD_NODE(:INPUT_4:STARTIDX, TREE\$K_USAGE_NUMERIC)

flags \|= NCI\$M_NO_WRITE_SHOT;

status = TREE\$SETNCI(&curr_nid, flag_itm);

\$ADD_NODE(:INPUT_4:ENDIDX, TREE\$K_USAGE_NUMERIC)

flags \|= NCI\$M_NO_WRITE_SHOT;

status = TREE\$SETNCI(&curr_nid, flag_itm);

\$ADD_NODE(:INPUT_5, TREE\$K_USAGE_SIGNAL)

flags \|= NCI\$M_WRITE_ONCE;

flags \|= NCI\$M_COMPRESS_ON_PUT;

flags \|= NCI\$M_NO_WRITE_MODEL;

status = TREE\$SETNCI(&curr_nid, flag_itm);

\$ADD_NODE(:INPUT_5:STARTIDX, TREE\$K_USAGE_NUMERIC)

flags \|= NCI\$M_NO_WRITE_SHOT;

status = TREE\$SETNCI(&curr_nid, flag_itm);

\$ADD_NODE(:INPUT_5:ENDIDX, TREE\$K_USAGE_NUMERIC)

flags \|= NCI\$M_NO_WRITE_SHOT;

status = TREE\$SETNCI(&curr_nid, flag_itm);

\$ADD_NODE(:INPUT_6, TREE\$K_USAGE_SIGNAL)

flags \|= NCI\$M_WRITE_ONCE;

flags \|= NCI\$M_COMPRESS_ON_PUT;

flags \|= NCI\$M_NO_WRITE_MODEL;

status = TREE\$SETNCI(&curr_nid, flag_itm);

\$ADD_NODE(:INPUT_6:STARTIDX, TREE\$K_USAGE_NUMERIC)

flags \|= NCI\$M_NO_WRITE_SHOT;

status = TREE\$SETNCI(&curr_nid, flag_itm);

\$ADD_NODE(:INPUT_6:ENDIDX, TREE\$K_USAGE_NUMERIC)

flags \|= NCI\$M_NO_WRITE_SHOT;

status = TREE\$SETNCI(&curr_nid, flag_itm);

\$ADD_NODE_ACTION(:INIT_ACTION, INIT, INIT, 50, 0, 0, CAMAC_SERVER, 0)

\$ADD_NODE_ACTION(:STORE_ACTION, STORE, STORE, 50, 0, 0, CAMAC_SERVER,
0)

status = TREE\$END_CONGLOMERATE();

if (!(status & 1)) return status;

return(TREE\$SET_DEFAULT_NID(&old_nid));

}

int **A12\$PART_NAME**(struct dsc\$descriptor \*nid_d_ptr, struct
dsc\$descriptor \*method_d_ptr, struct dsc\$descriptor \*out_d)

{

int element = 0, status;

NCI_ITM nci_list\[\] = {{4, NCI\$\_CONGLOMERATE_ELT, 0, 0},{0,0,0,0}};

nci_list\[0\].nci_itm\$a_pointer = (unsigned char \*)&element;

status = TREE\$GETNCI((int \*)nid_d_ptr-\>dsc\$a_pointer, nci_list);

if (!(status & 1)) return status;

switch(element) {

case(A12\$N_HEAD + 1) : str\$free1_dx(out_d); break;

case(A12\$N_NAME + 1) : \$COPY_PART_NAME(:NAME) break;

case(A12\$N_COMMENT + 1) : \$COPY_PART_NAME(:COMMENT) break;

case(A12\$N_EXT_CLOCK_IN + 1) : \$COPY_PART_NAME(:EXT_CLOCK_IN) break;

case(A12\$N_STOP_TRIG + 1) : \$COPY_PART_NAME(:STOP_TRIG) break;

case(A12\$N_INPUT_1 + 1) : \$COPY_PART_NAME(:INPUT_1) break;

case(A12\$N_INPUT_1_STARTIDX + 1) : \$COPY_PART_NAME(:INPUT_1:STARTIDX)
break;

case(A12\$N_INPUT_1_ENDIDX + 1) : \$COPY_PART_NAME(:INPUT_1:ENDIDX)
break;

case(A12\$N_INPUT_2 + 1) : \$COPY_PART_NAME(:INPUT_2) break;

case(A12\$N_INPUT_2_STARTIDX + 1) : \$COPY_PART_NAME(:INPUT_2:STARTIDX)
break;

case(A12\$N_INPUT_2_ENDIDX + 1) : \$COPY_PART_NAME(:INPUT_2:ENDIDX)
break;

case(A12\$N_INPUT_3 + 1) : \$COPY_PART_NAME(:INPUT_3) break;

case(A12\$N_INPUT_3_STARTIDX + 1) : \$COPY_PART_NAME(:INPUT_3:STARTIDX)
break;

case(A12\$N_INPUT_3_ENDIDX + 1) : \$COPY_PART_NAME(:INPUT_3:ENDIDX)
break;

case(A12\$N_INPUT_4 + 1) : \$COPY_PART_NAME(:INPUT_4) break;

case(A12\$N_INPUT_4_STARTIDX + 1) : \$COPY_PART_NAME(:INPUT_4:STARTIDX)
break;

case(A12\$N_INPUT_4_ENDIDX + 1) : \$COPY_PART_NAME(:INPUT_4:ENDIDX)
break;

case(A12\$N_INPUT_5 + 1) : \$COPY_PART_NAME(:INPUT_5) break;

case(A12\$N_INPUT_5_STARTIDX + 1) : \$COPY_PART_NAME(:INPUT_5:STARTIDX)
break;

case(A12\$N_INPUT_5_ENDIDX + 1) : \$COPY_PART_NAME(:INPUT_5:ENDIDX)
break;

case(A12\$N_INPUT_6 + 1) : \$COPY_PART_NAME(:INPUT_6) break;

case(A12\$N_INPUT_6_STARTIDX + 1) : \$COPY_PART_NAME(:INPUT_6:STARTIDX)
break;

case(A12\$N_INPUT_6_ENDIDX + 1) : \$COPY_PART_NAME(:INPUT_6:ENDIDX)
break;

case(A12\$N_INIT_ACTION + 1) : \$COPY_PART_NAME(:INIT_ACTION) break;

case(A12\$N_STORE_ACTION + 1) : \$COPY_PART_NAME(:STORE_ACTION) break;

default : status = TREE\$\_ILLEGAL_ITEM;

}

return status;

}

**extern int A12\$\$INIT();**

#define free_xd_array { int i; for(i=0; i\<2;i++)
if(work_xd\[i\].dsc\$l_length) MDS

\$FREE1_DX(&work_xd\[i\]);}

#define error(nid,code,code1) {free_xd_array return
GEN_DEVICE\$SIGNAL(&nid,code,

code1);}

int **A12\$INIT**(struct dsc\$descriptor \*nid_d_ptr, struct
dsc\$descriptor \*method_d_p

tr)

{

#pragma extern_model save

#pragma extern_model globalvalue

extern DEV\$\_BAD_NAME;

#pragma extern_model restore

declare_variables(InInitStruct)

struct dsc\$descriptor_xd work_xd\[2\];

int xd_count = 0;

memset((char \*)work_xd, \'\\0\', sizeof(struct dsc\$descriptor_xd) \*
2);

initialize_variables(InInitStruct)

read_string_error(A12\$N_NAME,name, DEV\$\_BAD_NAME);

read_descriptor(A12\$N_EXT_CLOCK_IN, ext_clock_in);

status = A12\$\$INIT(nid_d_ptr, &in_struct);

free_xd_array

return status;

}

#undef free_xd_array

extern int A12\$\$TRIGGER();

#define free_xd_array { int i; for(i=0; i\<1;i++)
if(work_xd\[i\].dsc\$l_length) MDS

\$FREE1_DX(&work_xd\[i\]);}

int **A12\$TRIGGER**(struct dsc\$descriptor \*nid_d_ptr, struct
dsc\$descriptor \*method_d_ptr)

{

#pragma extern_model save

#pragma extern_model globalvalue

extern DEV\$\_BAD_NAME;

#pragma extern_model restore

declare_variables(InTriggerStruct)

struct dsc\$descriptor_xd work_xd\[1\];

int xd_count = 0;

memset((char \*)work_xd, \'\\0\', sizeof(struct dsc\$descriptor_xd) \*
1);

initialize_variables(InTriggerStruct)

read_string_error(A12\$N_NAME,name, DEV\$\_BAD_NAME);

status = A12\$\$TRIGGER(nid_d_ptr, &in_struct);

free_xd_array

return status;

}

#undef free_xd_array

extern int A12\$\$STOP();

#define free_xd_array { int i; for(i=0; i\<1;i++)
if(work_xd\[i\].dsc\$l_length) MDS

\$FREE1_DX(&work_xd\[i\]);}

int **A12\$STOP**(struct dsc\$descriptor \*nid_d_ptr, struct
dsc\$descriptor \*method_d_ptr)

{

#pragma extern_model save

#pragma extern_model globalvalue

extern DEV\$\_BAD_NAME;

#pragma extern_model restore

declare_variables(InStopStruct)

struct dsc\$descriptor_xd work_xd\[1\];

int xd_count = 0;

memset((char \*)work_xd, \'\\0\', sizeof(struct dsc\$descriptor_xd) \*
1);

initialize_variables(InStopStruct)

read_string_error(A12\$N_NAME,name, DEV\$\_BAD_NAME);

status = A12\$\$STOP(nid_d_ptr, &in_struct);

free_xd_array

return status;

}

#undef free_xd_array

For some reason, the \$STORE method was not included in the A12_GEN.C
file; A12\$STORE (but NOT A12\$\$STORE) is included in A12.C, which is
an example of first-generation glue-together-the-descriptors
programming.

> A12.C

/\* CMS REPLACEMENT HISTORY, Element A12.C \*/

/\* \*4 8-NOV-1994 15:29:04 JAS \"pad structure to 16 bits\" \*/

/\* \*3 2-NOV-1994 14:36:09 TWF \"decc\" \*/

/\* \*2 24-OCT-1994 12:11:41 TWF \"clean up, no vaxc\" \*/

/\* \*1 7-OCT-1993 09:09:18 TWF \"Aurora 12\" \*/

/\* CMS REPLACEMENT HISTORY, Element A12.C \*/

#include \<descrip.h\>

#include \<tdescrip.h\>

#include \<str\$routines.h\>

#include \<treeshr.h\>

#include \<mdsshr.h\>

#include \<devshr.h\>

#include \"A12.H\"

#pragma extern_model save

#pragma extern_model globalvalue

extern OPC\$\_ADD;

extern OPC\$\_MULTIPLY;

extern OPC\$\_\$VALUE;

#pragma extern_model restore

extern int CAM\$XANDQ();

#define pio(fv,av) {int a = av; int f = fv;\\

if (!((status = DEV\$CAMCHK(CAM\$PIOW(setup-\>name,&a,&f,&0,&16),&1,&1))
& 1)) return status;}

int **a12\$\$init**(struct dsc\$descriptor \*niddsc, InInitStruct
\*setup)

{

int status;

pio(9,0)

pio(9,0)

pio(17,setup-\>ext_clock_in != 0)

pio(26,0)

return status;

}

int **a12\$\$stop**(struct dsc\$descriptor \*niddsc, InStopStruct
\*setup)

{

int status;

pio(25,1)

return status;

}

int **a12\$\$trigger**(struct dsc\$descriptor \*niddsc, InTriggerStruct
\*setup)

{

int status;

pio(25,0)

return status;

}

static int ReadSetup(struct dsc\$descriptor \*key_ptr,

float \*freq_ptr,

int \*polarity);

static int ReadChannel(struct dsc\$descriptor \*key_d_ptr,

int fast,

int \*max_samps_ptr,

int chan,

short \*data_ptr);

static int sinewave;

#define A12\$N_INPUTS 5

#define A12\$K_NODES_PER_INP 3

#define A12\$N_INP_HEAD 0

#define A12\$N_INP_STARTIDX 1

#define A12\$N_INP_ENDIDX 2

int A12\$STORE(struct dsc\$descriptor \*niddsc_ptr)

{

#define return_on_error(f,retstatus) if (!((status = f) & 1)) return
retstatus;

#define CHAN_NID(chan, field)
c_nids\[A12\$N_INPUTS+chan\*A12\$K_NODES_PER_INP+field\]

#define min(a,b) ((a) \<= (b)) ? (a) : (b)

#define max(a,b) ((a) \>= (b)) ? (a) : (b)

static int c_nids\[A12\$K_CONG_NODES\];

static unsigned long OPC\$ADD = OPC\$\_ADD;

static unsigned long OPC\$MULTIPLY = OPC\$\_MULTIPLY;

static unsigned long OPC\$\$VALUE = OPC\$\_\$VALUE;

static struct dsc\$descriptor name =
{0,DSC\$K_DTYPE_T,DSC\$K_CLASS_D,0};

static \$EMPTYXD(setup);

static \$DESCRIPTOR_A_BOUNDS(raw,sizeof(short),DSC\$K_DTYPE_W,0,1,0);

static \$DESCRIPTOR(counts_str,\"counts\");

static \$DESCRIPTOR_WITH_UNITS(counts,&raw, &counts_str);

static \$DESCRIPTOR_LONG(start_d,&raw.dsc\$bounds\[0\].dsc\$l_l);

static \$DESCRIPTOR_LONG(end_d,&raw.dsc\$bounds\[0\].dsc\$l_u);

static \$DESCRIPTOR_NID(trigger_d,&c_nids\[A12\$N_STOP_TRIG\]);

static float frequency;

static \$DESCRIPTOR_FLOAT(frequency_d,&frequency);

static \$DESCRIPTOR_RANGE(int_clock_d,0,0,&frequency_d);

static \$DESCRIPTOR_NID(ext_clock_d,&c_nids\[A12\$N_EXT_CLOCK_IN\]);

static float coefficient = 10.0/4096;

static \$DESCRIPTOR_FLOAT(coef_d,&coefficient);

static short offset = 0;

static struct dsc\$descriptor_s offset_d =
{2,DSC\$K_DTYPE_W,DSC\$K_CLASS_S,(char \*)&offset};

static int key;

static \$DESCRIPTOR_LONG(key_d,&key);

static \$DESCRIPTOR_FUNCTION_1(\$value,(unsigned char
\*)&OPC\$\$VALUE,0);

static \$DESCRIPTOR_FUNCTION_2(add_exp,(unsigned char
\*)&OPC\$ADD,&offset_d,&\$value);

static \$DESCRIPTOR_FUNCTION_2(mult_exp,(unsigned char
\*)&OPC\$MULTIPLY,&coef_d, &add_exp);

static \$DESCRIPTOR(volts_str,\"volts\");

static \$DESCRIPTOR_WITH_UNITS(volts,&mult_exp,&volts_str);

static \$DESCRIPTOR_WINDOW(window,&start_d,&end_d,&trigger_d);

static \$DESCRIPTOR_DIMENSION(dimension,&window,0);

static \$DESCRIPTOR(time_str,\"seconds\");

static \$DESCRIPTOR_WITH_UNITS(time,&dimension,&time_str);

static \$DESCRIPTOR_SIGNAL_1(signal,&volts,&counts,&time);

short channel_data\[32767\];

int status;

int chan;

int samples_to_read;

int i;

int polarity;

int fast;

short int module_id;

int max_samples;

return_on_error(DEV\$NIDS(niddsc_ptr,sizeof(c_nids),c_nids),status);

return_on_error(DEV\$TEXT(&c_nids\[A12\$N_NAME\],
&name),DEV\$\_BAD_NAME);

\$value.dsc\$b_ndesc = 0;

return_on_error(CAM\$ASSIGN(&name,&key),status);

str\$free1_dx(&name);

return_on_error(DEV\$CAMCHK(CAM\$PIOW(&key_d, &0, &8, &0, &16), &1,
0),status);

if ((CAM\$XANDQ()&1) == 0) return DEV\$\_NOT_TRIGGERED;

return_on_error(ReadSetup((struct dsc\$descriptor \*)&key_d, &frequency,
&polarity), status);

dimension.dsc\$a_axis = (frequency == 0) ? (struct dsc\$descriptor
\*)&ext_clock_d : (struct dsc\$descriptor \*)&int_clock_d;

return_on_error(DEV\$CAMCHK(CAM\$PIOW(&key_d, &0, &6, &module_id, &16),
&1, &1), status);

max_samples = (module_id & 128) ? 32767 : 8192;

fast = TREE\$IS_ON(&c_nids\[A12\$N_COMMENT\]) & 1;

for (chan=0;((chan \< 6) && (status & 1));chan++)

{

if (TREE\$IS_ON(&CHAN_NID(chan,A12\$N_INP_HEAD)) & 1)

{

status = DEV\$LONG(&CHAN_NID(chan,A12\$N_INP_STARTIDX),(int
\*)&raw.dsc\$bounds\[0\].dsc\$l_l);

if (status&1) raw.dsc\$bounds\[0\].dsc\$l_l =
min(max_samples-1,max(0,raw.dsc\$bounds\[0\].dsc\$l_l));

else raw.dsc\$bounds\[0\].dsc\$l_l = 0;

status = DEV\$LONG(&CHAN_NID(chan,A12\$N_INP_ENDIDX), (int
\*)&raw.dsc\$bounds\[0\].dsc\$l_u);

if (status&1) raw.dsc\$bounds\[0\].dsc\$l_u =
min(max_samples-1,max(0,raw.dsc\$bounds\[0\].dsc\$l_u));

else raw.dsc\$bounds\[0\].dsc\$l_u = max_samples-1;

raw.dsc\$l_m\[0\] = raw.dsc\$bounds\[0\].dsc\$l_u -
raw.dsc\$bounds\[0\].dsc\$l_l + 1;

if (raw.dsc\$l_m\[0\] \> 0)

{

samples_to_read = raw.dsc\$bounds\[0\].dsc\$l_u + 1;

status = ReadChannel((struct dsc\$descriptor
\*)&key_d,fast,&max_samples, chan,channel_data);

if (status & 1)

{

offset = ((1 \<\< chan) & polarity) != 0 ? -2048 : 0;

raw.dsc\$a_pointer = (char \*)(channel_data +
(raw.dsc\$bounds\[0\].dsc\$l_l));

raw.dsc\$a_a0 = (char \*)channel_data;

raw.dsc\$l_arsize = raw.dsc\$l_m\[0\] \* 2;

status = TREE\$PUT_RECORD(&CHAN_NID(chan,A12\$N_INP_HEAD),(struct
dsc\$descriptor \*)&signal);

}

}

}

}

MDS\$FREE1_DX(&setup);

return status;

}

static int ReadSetup(struct dsc\$descriptor \*key_ptr,

float \*freq_ptr,

int \*offset)

{

struct a12_setup { unsigned a12_setup\$v_offset : 6; /\* Bit on
indicates bipolar, 0:10V, else unipolar +5:-5V \*/

unsigned a12_setup\$v_dummy : 1;

unsigned a12_setup\$v_period : 1;

unsigned : 8;

} setup;

static float freq\[2\] = {0, 1.E-5 };

int status;

status = DEV\$CAMCHK(CAM\$PIOW(key_ptr,&0,&0,&setup,&16),&1,0);

if (status & 1)

{

\*offset = setup.a12_setup\$v_offset;

\*freq_ptr = freq\[setup.a12_setup\$v_period\];

}

return status;

}

static int ReadChannel(struct dsc\$descriptor \*key_d_ptr,

int fast,

int \*max_samps_ptr,

int chan,

short \*data_ptr)

{

int serial;

int chan_sel;

int status;

return_on_error(DEV\$CAMCHK(CAM\$PIOW(key_d_ptr,&0,&6,&serial,&16),&1,&1),status

);

if ( ((serial \>\> 8) & 255) \<= 4) /\* If serial number is less equal
to 4 then\*/

chan_sel = 7 - chan; /\* Channel select backwards from 7 \*/

else { /\* Else

\*/

return_on_error(DEV\$CAMCHK(CAM\$PIOW(key_d_ptr,&1,&24,&0,&16),&1,&1),status);

chan_sel = chan; /\* Channel select starts at 0 \*/

}

return_on_error(DEV\$CAMCHK(CAM\$PIOW(key_d_ptr,&chan_sel,&16,&0,&16),&1,0),status);

if (fast)

{

return_on_error(DEV\$CAMCHK(CAM\$FSTOPW(key_d_ptr,&0,&2,max_samps_ptr,data_ptr,&16),&1,0),status);

}

else

{

return_on_error(DEV\$CAMCHK(CAM\$STOPW(key_d_ptr,&0,&2,max_samps_ptr,data_ptr,&16),&1,0),status);

}

return 1;

}

University of Washington Web Device Support Documentation

<http://plasma.aa.washington.edu/mdsplus/LocalDeviceDevelopment/writing_drivers.html>

University of Washington Plasma Sciences

Writing Device Drivers in TDI

This page gives an overview on writing Device Drivers for CAMAC devices
in TDI for use in MDSplus.

You need the manual for the device so that you can get the F and A codes
for the various functions. It will also help to have any old MDS-
drivers that exist for the device, if you are lucky enough to have them.

The GEN file

The first file to make is the GEN file. This file defines the initial
order and setup of the different parts (nodes) of the device. The
example GEN file should be fairly easy to understand. The NAME node (the
CAMAC name string) is always first and thus gets number 1 for calls to
it later. This is followed by COMMENT, which gets 2, etc. All the way
down to INPUT_8:RANGE which gets 49.

On each line in the GEN file you can set things like usage, options, and
data value. Note the special lines for INIT_ACTION and STORE_ACTION
which give info on how to initialize and store the device.

The GEN file is converted into a C program using the command:

gen_device/single/suffix=\_gen d2028.gen

It is then compiled using:

cc d2028_gen

Finally, it is linked into the library UW\$DEVICES.EXE using something
like this COM file.

The UW\$DEVICES.EXE file is then copied over to the MDS\$ROOT:\[SYSLIB\]
directory.

I discovered a useful error check here when I had a node name too long
(i.e. more than 12 characters) in the GEN file. There would be an error
reported when trying to add the device to the tree. However the device
would still appear in the tree and it would have all the nodes up to the
one that had the extra long name. Therefore it was easy to spot where
the error in the GEN file was by looking to see where it stopped adding
nodes in the tree.

The UIL file

This file is used to create the widgets to interface with the device
when you want to set it up. It is a fairly complex file that will take
some study to fully comprehend.

The first part declares the values for the different parts of the device
as was set up in the GEN file. Thus \"D2028\$N_NAME : 1\" and
\"D2028\$N_COMMENT : 2\", etc. We also declare some values for the pull
down lists here like \"range\" and \"samples\".

Next we declare each object that we will need to use for this device.
This sets up things like the sizes of the boxes and where to put things
in the boxes etc.

Note especially the \"XmNresizePolicy = XmRESIZE_GROW;\" line. This line
lets you resize the box/window which is of immense help when you are
first testing things out but also can be invaluable if someone needs to
display on a terminal with different fonts than you originally planned.
We often run into a window that someone wrote without this line and
since our fonts are larger, we cannot read or edit the fields very well.

Also note that in the XmBulletinBoardDialog widget, we need to declare
the other objects that will be placed in it.

Read through this file carefully and then play around with changing
things to see how the will work for you. After awhile it will start
making more sense and you should at least be able to get what you need
done.

After writing the UIL file, it gets compiled into the UID file using the
command:

uil/motif/widget=xmdsuil d2028.uil

and then copied over to the MDS\$ROOT:\[SYSLIB\] directory. It then is
available for the traverser to bring up when you do a \"setup device\"
on your device.

The INIT file and the STORE file

The initialization file or INIT file is the driver that is used to
initialize the device in preparation for triggering. The STORE file is
the driver that is used to store the data in the device after it has
been triggered. They are written in TDI which has minimal documentation
but should have a lot of familiar things in it if you are acquainted
with FORTRAN, C, or C++. What documentation there is can be found at the
TDI (Tree Data Interface) Information page at PPPL.

Some things to notice:

\* variable names begin with an underscore (\"\_\")

\* comments are encased in /\* and \*/

\* all lines end with a semicolon (probably the first thing to check if
the program is not working)

These files are where you will use the CAMAC F and A codes to get your
device to do what you want. What you need your device to do for
initialization and store will depend upon it and what it is being used
for. This is where it will be very handy to have any old drivers that
exist for the device so that you can copy and improve on it in your new
driver.

I have tried to comment these files extensively so that others as well
as myself can look it over and figure out what is going on and how. So
my best advice is to print them out (in landscape) and study them with
pencil in hand while referencing PPPL pages on TDI.

When writing your own TDI file, you must place your new version in the
MDSplus path on your system and restart the CAMAC server if it is
running in order for the new file to be accessed by MDSplus. To restart
the CAMAC server, do the following:

\* stop the server from TCL with the command:

TCL\> stop server camac_server

\* restart the server with the DCL command:

DCL\> mcr mdsserver tcs_cam_server

(where tcs_cam_server is the name of your server)

A common error you will run into in TCL when trying to run your driver
will state simply, \"No method for this object\". To get more
information for debugging, do as in this example for a tree called
\"tcsdat\" and a digitizer called \"d121\":

\* DCL\> mcr tdic

\* TDI\> tcl set tree tcsdat /shot=0

\* TDI\> d2028\_\_init(\"\\\\top:d121\")

NOTE: You must use \"\\\\top:d121\" here. Setting \_nid and using it
only works within the code, not in the TDI command line.

\* TDI\> exit

This will help to spot the error and figure out where you went wrong so
you can fix your code.

The GEN file

device model = D2028 library = UW\$DEVICES with

{

NAME : undefined usage = text;

COMMENT : undefined usage = text;

SAMP_INTRVAL : datum value = 1.0E-7 options = no_write_shot usage =
numeric;

EXT_CLOCK : undefined options = no_write_shot usage = axis;

TRIGGER : datum value = 0.0 options = no_write_shot usage = numeric;

PRE_TRIGGER : datum value = 1000 options = no_write_shot usage =
numeric;

SAMPLES : datum value = 32768 options = no_write_shot usage = numeric;

INIT_ACTION : action operation = INIT sequence = 50 phase = INIT
server_class = CAMAC_SERVER;

STORE_ACTION : action operation = STORE sequence = 50 phase = STORE
server_class = CAMAC_SERVER;

INPUT_1 : undefined options = no_write_model,write_once,compressible
usage = signal;

INPUT_1:STARTIDX : undefined options = no_write_shot usage = numeric;

INPUT_1:ENDIDX : undefined options = no_write_shot usage = numeric;

INPUT_1:OFFSET : datum value = 128 options = no_write_shot usage =
numeric;

INPUT_1:RANGE : datum value = 5.12 options = no_write_shot usage =
numeric;

INPUT_2 : undefined options = no_write_model,write_once,compressible
usage = signal;

INPUT_2:STARTIDX : undefined options = no_write_shot usage = numeric;

INPUT_2:ENDIDX : undefined options = no_write_shot usage = numeric;

INPUT_2:OFFSET : datum value = 128 options = no_write_shot usage =
numeric;

INPUT_2:RANGE : datum value = 5.12 options = no_write_shot usage =
numeric;

INPUT_3 : undefined options = no_write_model,write_once,compressible
usage = signal;

INPUT_3:STARTIDX : undefined options = no_write_shot usage = numeric;

INPUT_3:ENDIDX : undefined options = no_write_shot usage = numeric;

INPUT_3:OFFSET : datum value = 128 options = no_write_shot usage =
numeric;

INPUT_3:RANGE : datum value = 5.12 options = no_write_shot usage =
numeric;

INPUT_4 : undefined options = no_write_model,write_once,compressible
usage = signal;

INPUT_4:STARTIDX : undefined options = no_write_shot usage = numeric;

INPUT_4:ENDIDX : undefined options = no_write_shot usage = numeric;

INPUT_4:OFFSET : datum value = 128 options = no_write_shot usage =
numeric;

INPUT_4:RANGE : datum value = 5.12 options = no_write_shot usage =
numeric;

INPUT_5 : undefined options = no_write_model,write_once,compressible
usage = signal;

INPUT_5:STARTIDX : undefined options = no_write_shot usage = numeric;

INPUT_5:ENDIDX : undefined options = no_write_shot usage = numeric;

INPUT_5:OFFSET : datum value = 128 options = no_write_shot usage =
numeric;

INPUT_5:RANGE : datum value = 5.12 options = no_write_shot usage =
numeric;

INPUT_6 : undefined options = no_write_model,write_once,compressible
usage = signal;

INPUT_6:STARTIDX : undefined options = no_write_shot usage = numeric;

INPUT_6:ENDIDX : undefined options = no_write_shot usage = numeric;

INPUT_6:OFFSET : datum value = 128 options = no_write_shot usage =
numeric;

INPUT_6:RANGE : datum value = 5.12 options = no_write_shot usage =
numeric;

INPUT_7 : undefined options = no_write_model,write_once,compressible
usage = signal;

INPUT_7:STARTIDX : undefined options = no_write_shot usage = numeric;

INPUT_7:ENDIDX : undefined options = no_write_shot usage = numeric;

INPUT_7:OFFSET : datum value = 128 options = no_write_shot usage =
numeric;

INPUT_7:RANGE : datum value = 5.12 options = no_write_shot usage =
numeric;

INPUT_8 : undefined options = no_write_model,write_once,compressible
usage = signal;

INPUT_8:STARTIDX : undefined options = no_write_shot usage = numeric;

INPUT_8:ENDIDX : undefined options = no_write_shot usage = numeric;

INPUT_8:OFFSET : datum value = 128 options = no_write_shot usage =
numeric;

INPUT_8:RANGE : datum value = 5.12 options = no_write_shot usage =
numeric;

}

The UIL file

/\*

\* Created by Matthew Fishburn.

\*

\* June 2001.

\*

\*/

module MAIN_UIL

version = \'V1.0\'

names = case_sensitive

/\* set up the values \*/

value

DEVICE_NID : -1; /\*example\*/

DEVICE\$N_NAME : 1; /\*example\*/

DEVICE\$N_COMMENT : 2; /\*example\*/

DEVICE\$N_INIT_ACTION : 0; /\*example\*/

DEVICE\$N_STORE_ACTION : 0; /\*example\*/

DEVICE\$K_NODES_PER_INP : 3; /\*example\*/

DEVICE\$N_INP_HEAD : 0; /\*example\*/

DEVICE\$N_INP_ENDIDX : 2; /\*example\*/

DEVICE\$N_INP_STARTIDX : 1; /\*example\*/

DEVICE\$N_INPUTS : 12; /\*example\*/

D2028\$K_CONG_NODES : 36; /\*?\*/

D2028\$N_HEAD : 0;

D2028\$N_NAME : 1;

D2028\$N_COMMENT : 2;

D2028\$N_SAMP_INTRVAL : 3; /\*sampling intErval\*/

D2028\$N_EXT_CLOCK : 4;

D2028\$N_TRIGGER : 5;

D2028\$N_PRE_TRIGGER : 6; /\*number of pre trigger samples\*/

D2028\$N_SAMPLES : 7; /\*number of samples\*/

D2028\$N_INIT_ACTION : 8;

D2028\$N_STORE_ACTION : 9;

D2028\$N_INPUTS : 10; /\*where the inputs start\*/

D2028\$K_NODES_PER_INP : 5; /\*number of nodes for each input\*/

D2028\$N_INP_HEAD : 0; /\*head position w.r.t. start of input\*/

D2028\$N_INP_STARTIDX : 1; /\*start index position w.r.t. start of
input\*/

D2028\$N_INP_ENDIDX : 2; /\*end index position w.r.t. start of input\*/

D2028\$N_INP_OFFSET : 3; /\*channel offset position w.r.t. start of
input\*/

D2028\$N_INP_RANGE : 4; /\*channel range position w.r.t. start of
input\*/

/\*possible range values\*/

ranges : string_table(

compound_string(\"0.512\"),

compound_string(\"1.024\"),

compound_string(\"2.560\"),

compound_string(\"5.120\"));

/\*possible sample values\*/

sample_values : string_table(

compound_string(\"32768\"),

compound_string(\"16384\"),

compound_string(\"8192\"),

compound_string(\"4096\"),

compound_string(\"2048\"),

compound_string(\"1024\"),

compound_string(\"512\"),

compound_string(\"256\"));

/\*define the procedures to be used\*/

procedure AddListTree();

procedure TurnOnOff(integer);

procedure DisplayData();

procedure DisplayNci();

procedure ModifyData();

procedure SetupDevice();

procedure MenuUnmap();

procedure MTurnOnOff(integer);

procedure MSetupDevice();

procedure MDisplayData();

procedure MDisplayNci();

procedure MModifyData();

procedure CloseTree();

procedure OpenTree();

list BaseStyle : arguments {

};

list BaseStyleReasons : callbacks {

};

object D2028 : XmBulletinBoardDialog widget {

arguments {

XmNautoUnmanage = false;

XmNdefaultPosition = true;

XmNresizePolicy = XmRESIZE_GROW;

XmNnoResize = false;

XmNdialogTitle = compound_string(\"D2028 DSP 8 Channel Transie\" &

\"nt Recorder\");

XmNx = 308;

XmNy = 167;

XmNwidth = 1000;

XmNheight = 600;

};

controls {

managed XmLabelGadget CAMACNameLabel;

managed XmdsExprField CAMACNameField;

managed XmLabelGadget CommentLabel;

managed XmdsExprField CommentField;

managed XmdsNidOptionMenu SamlpingIntervalMenu;

managed XmLabelGadget ExternalClockLabel;

managed XmdsExprField ExternalClockField;

managed XmLabelGadget TriggerLabel;

managed XmdsExprField TriggerField;

managed XmLabel PretriggerSampleLabel;

managed XmdsExprField PretriggerSampleField;

managed XmLabel SampleLabel;

managed XmdsNidOptionMenu SampleMenu;

managed XmdsXdBoxOnOffButton InitActionButton;

managed XmdsXdBoxOnOffButton StoreActionButton;

managed XmdsOkButton dsOkButton;

managed XmdsApplyButton dsApplyButton;

managed XmdsResetButton dsResetButton;

managed XmdsCancelButton dsCancelButton;

managed XmBulletinBoard bulletinBoard;

};

callbacks {

};

};

object CAMACNameLabel : XmLabelGadget widget {

arguments {

XmNlabelString = compound_string(\"CAMAC Name:\");

XmNx = 10;

XmNy = 10;

};

controls {

};

callbacks {

};

};

object CAMACNameField : XmdsExprField widget {

arguments {

XmdsNnid = DEVICE_NID;

XmdsNdefaultQuote = true;

XmNcolumns = 32;

XmdsNnidOffset = D2028\$N_NAME;

XmNmarginHeight = 1;

XmdsNautoQuote = true;

XmNx = 150;

XmNy = 10;

};

controls {

};

callbacks {

};

};

object CommentLabel : XmLabelGadget widget {

arguments {

XmNlabelString = compound_string(\"Comment:\");

XmNx = 10;

XmNy = 40;

};

controls {

};

callbacks {

};

};

object CommentField : XmdsExprField widget {

arguments {

XmdsNnid = DEVICE_NID;

XmdsNdefaultQuote = true;

XmNcolumns = 32;

XmdsNnidOffset = D2028\$N_COMMENT;

XmNmarginHeight = 1;

XmdsNautoQuote = true;

XmNx = 110;

XmNy = 40;

};

controls {

};

callbacks {

};

};

object SamlpingIntervalMenu : XmdsNidOptionMenu widget {

arguments {

XmdsNnid = DEVICE_NID;

XmdsNvalueStrings = string_table(

compound_string(\"1.0E-7\"),

compound_string(\"2.0E-7\"),

compound_string(\"5.0E-7\"),

compound_string(\"1.0E-6\"),

compound_string(\"2.0E-6\"),

compound_string(\"5.0E-6\"),

compound_string(\"1.0E-5\"),

compound_string(\"2.0E-5\"),

compound_string(\"5.0E-5\"),

compound_string(\"1.0E-4\"),

compound_string(\"2.0E-4\"),

compound_string(\"5.0E-4\"),

compound_string(\"1.0E-3\"),

compound_string(\"2.0E-3\"),

compound_string(\"5.0E-3\"),

compound_string(\"0.0\"));

XmNlabelString = compound_string(\"Sampling Interval:\");

XmdsNputOnApply = true;

XmdsNnidOffset = D2028\$N_SAMP_INTRVAL;

XmdsNlabelStrings = string_table(

compound_string(\"100 ns\"),

compound_string(\"200 ns\"),

compound_string(\"500 ns\"),

compound_string(\" 1 us\"),

compound_string(\" 2 us\"),

compound_string(\" 5 us\"),

compound_string(\" 10 us\"),

compound_string(\" 20 us\"),

compound_string(\" 50 us\"),

compound_string(\"100 us\"),

compound_string(\"200 us\"),

compound_string(\"500 us\"),

compound_string(\" 1 ms\"),

compound_string(\" 2 ms\"),

compound_string(\" 5 ms\"),

compound_string(\"External Clock\"));

XmNx = 10;

XmNy = 70;

};

controls {

};

callbacks {

};

};

object ExternalClockLabel : XmLabelGadget widget {

arguments {

XmNlabelString = compound_string(\"External Clock:\");

XmNx = 430;

XmNy = 80;

XmNheight = 20;

};

controls {

};

callbacks {

};

};

object ExternalClockField : XmdsExprField widget {

arguments {

XmdsNnid = DEVICE_NID;

XmNcolumns = 20;

XmdsNnidOffset = D2028\$N_EXT_CLOCK;

XmNmarginHeight = 1;

XmNmarginWidth = 1;

XmNx = 560;

XmNy = 75;

};

controls {

};

callbacks {

};

};

object TriggerLabel : XmLabelGadget widget {

arguments {

XmNlabelString = compound_string(\"Trigger:\");

XmNx = 10;

XmNy = 110;

};

controls {

};

callbacks {

};

};

object TriggerField : XmdsExprField widget {

arguments {

XmdsNnid = DEVICE_NID;

XmNcolumns = 20;

XmdsNnidOffset = D2028\$N_TRIGGER;

XmNmarginHeight = 1;

XmNmarginWidth = 1;

XmNx = 80;

XmNy = 110;

};

controls {

};

callbacks {

};

};

object PretriggerSampleLabel : XmLabel widget {

arguments {

XmNlabelString = compound_string(\"Pretrigger Samples:\");

XmNx = 400;

XmNy = 110;

};

controls {

};

callbacks {

};

};

object PretriggerSampleField : XmdsExprField widget {

arguments {

XmdsNnid = DEVICE_NID;

XmdsNnidOffset = D2028\$N_PRE_TRIGGER;

XmNcolumns = 7;

XmdsNputOnApply = true;

XmNmarginHeight = 1;

XmNmarginWidth = 1;

XmNx = 570;

XmNy = 110;

};

controls {

};

callbacks {

};

};

object SampleLabel : XmLabel widget {

arguments {

XmNlabelString = compound_string(\"Samples:\");

XmNx = 750;

XmNy = 110;

};

controls {

};

callbacks {

};

};

object SampleMenu : XmdsNidOptionMenu widget {

arguments {

XmdsNnid = DEVICE_NID;

XmdsNvalueStrings = sample_values;

XmdsNnidOffset = D2028\$N_SAMPLES;

XmdsNlabelStrings = sample_values;

XmNx = 820;

XmNy = 105;

XmNwidth = 160;

XmNheight = 35;

};

controls {

};

callbacks {

};

};

object bulletinBoard : XmBulletinBoard widget {

arguments {

XmNborderWidth = 1;

XmNresizePolicy = XmRESIZE_NONE;

XmNx = 10;

XmNy = 140;

XmNwidth = 980;

XmNheight = 450;

};

controls {

managed XmdsDigChans dsDigChans;

managed XmLabelGadget ChanLabel1;

managed XmLabelGadget ChanLabel2;

managed XmLabelGadget ChanLabel3;

managed XmLabelGadget ChanLabel4;

managed XmLabelGadget ChanLabel5;

managed XmLabelGadget ChanLabel6;

managed XmLabelGadget ChanLabel7;

managed XmLabelGadget ChanLabel8;

managed XmLabelGadget RangeLabel;

managed XmdsNidOptionMenu Range1Menu;

managed XmdsNidOptionMenu Range2Menu;

managed XmdsNidOptionMenu Range3Menu;

managed XmdsNidOptionMenu Range4Menu;

managed XmdsNidOptionMenu Range5Menu;

managed XmdsNidOptionMenu Range6Menu;

managed XmdsNidOptionMenu Range7Menu;

managed XmdsNidOptionMenu Range8Menu;

managed XmLabelGadget OffsetLabel;

managed XmdsExprField Offset1Field;

managed XmdsExprField Offset2Field;

managed XmdsExprField Offset3Field;

managed XmdsExprField Offset4Field;

managed XmdsExprField Offset5Field;

managed XmdsExprField Offset6Field;

managed XmdsExprField Offset7Field;

managed XmdsExprField Offset8Field;

};

callbacks {

};

};

object dsDigChans : XmdsDigChans widget {

arguments {

XmdsNnodesPerChannel = D2028\$K_NODES_PER_INP;

XmdsNnid = DEVICE_NID;

XmdsNchannels = 8;

XmdsNendIdxNidOffset = D2028\$N_INP_ENDIDX;

XmdsNstartIdxNidOffset = D2028\$N_INP_STARTIDX;

XmdsNdataNidOffset = D2028\$N_INP_HEAD;

XmdsNnidOffset = D2028\$N_INPUTS;

XmNx = 10;

XmNy = 10;

XmNwidth = 610;

XmNheight = 330;

};

controls {

};

callbacks {

};

};

object ChanLabel1 : XmLabelGadget widget {

arguments {

XmNlabelString = compound_string(\"Ch. 1\");

XmNx = 650;

XmNy = 35;

};

controls {

};

callbacks {

};

};

object ChanLabel2 : XmLabelGadget widget {

arguments {

XmNlabelString = compound_string(\"Ch. 2\");

XmNx = 650;

XmNy = 75;

};

controls {

};

callbacks {

};

};

object ChanLabel3 : XmLabelGadget widget {

arguments {

XmNlabelString = compound_string(\"Ch. 3\");

XmNx = 650;

XmNy = 115;

};

controls {

};

callbacks {

};

};

object ChanLabel4 : XmLabelGadget widget {

arguments {

XmNlabelString = compound_string(\"Ch. 4\");

XmNx = 650;

XmNy = 155;

};

controls {

};

callbacks {

};

};

object ChanLabel5 : XmLabelGadget widget {

arguments {

XmNlabelString = compound_string(\"Ch. 5\");

XmNx = 650;

XmNy = 195;

};

controls {

};

callbacks {

};

};

object ChanLabel6 : XmLabelGadget widget {

arguments {

XmNlabelString = compound_string(\"Ch. 6\");

XmNx = 650;

XmNy = 235;

};

controls {

};

callbacks {

};

};

object ChanLabel7 : XmLabelGadget widget {

arguments {

XmNlabelString = compound_string(\"Ch. 7\");

XmNx = 650;

XmNy = 275;

};

controls {

};

callbacks {

};

};

object ChanLabel8 : XmLabelGadget widget {

arguments {

XmNlabelString = compound_string(\"Ch. 8\");

XmNx = 650;

XmNy = 315;

};

controls {

};

callbacks {

};

};

object RangeLabel : XmLabelGadget widget {

arguments {

XmNlabelString = compound_string(\"Range (Volts)\");

XmNx = 710;

XmNy = 10;

};

controls {

};

callbacks {

};

};

object Range1Menu : XmdsNidOptionMenu widget {

arguments {

XmdsNnid = DEVICE_NID;

XmdsNvalueStrings = ranges;

XmdsNnidOffset = D2028\$N_INPUTS + 0 \* D2028\$K_NODES_PER_INP +
D2028\$N_INP_RANGE;

XmdsNlabelStrings = ranges;

XmNx = 700;

XmNy = 30;

XmNwidth = 110;

XmNheight = 35;

};

controls {

};

callbacks {

};

};

object Range2Menu : XmdsNidOptionMenu widget {

arguments {

XmdsNnid = DEVICE_NID;

XmdsNvalueStrings = ranges;

XmdsNnidOffset = D2028\$N_INPUTS + 1 \* D2028\$K_NODES_PER_INP +
D2028\$N_INP_RANGE;

XmdsNlabelStrings = ranges;

XmNx = 700;

XmNy = 70;

XmNwidth = 110;

XmNheight = 35;

};

controls {

};

callbacks {

};

};

object Range3Menu : XmdsNidOptionMenu widget {

arguments {

XmdsNnid = DEVICE_NID;

XmdsNvalueStrings = ranges;

XmdsNnidOffset = D2028\$N_INPUTS + 2 \* D2028\$K_NODES_PER_INP +
D2028\$N_INP_RANGE;

XmdsNlabelStrings = ranges;

XmNx = 700;

XmNy = 110;

XmNwidth = 110;

XmNheight = 35;

};

controls {

};

callbacks {

};

};

object Range4Menu : XmdsNidOptionMenu widget {

arguments {

XmdsNnid = DEVICE_NID;

XmdsNvalueStrings = ranges;

XmdsNnidOffset = D2028\$N_INPUTS + 3 \* D2028\$K_NODES_PER_INP +
D2028\$N_INP_RANGE;

XmdsNlabelStrings = ranges;

XmNx = 700;

XmNy = 150;

XmNwidth = 110;

XmNheight = 35;

};

controls {

};

callbacks {

};

};

object Range5Menu : XmdsNidOptionMenu widget {

arguments {

XmdsNnid = DEVICE_NID;

XmdsNvalueStrings = ranges;

XmdsNnidOffset = D2028\$N_INPUTS + 4 \* D2028\$K_NODES_PER_INP +
D2028\$N_INP_RANGE;

XmdsNlabelStrings = ranges;

XmNx = 700;

XmNy = 190;

XmNwidth = 110;

XmNheight = 35;

};

controls {

};

callbacks {

};

};

object Range6Menu : XmdsNidOptionMenu widget {

arguments {

XmdsNnid = DEVICE_NID;

XmdsNvalueStrings = ranges;

XmdsNnidOffset = D2028\$N_INPUTS + 5 \* D2028\$K_NODES_PER_INP +
D2028\$N_INP_RANGE;

XmdsNlabelStrings = ranges;

XmNx = 700;

XmNy = 230;

XmNwidth = 110;

XmNheight = 35;

};

controls {

};

callbacks {

};

};

object Range7Menu : XmdsNidOptionMenu widget {

arguments {

XmdsNnid = DEVICE_NID;

XmdsNvalueStrings = ranges;

XmdsNnidOffset = D2028\$N_INPUTS + 6 \* D2028\$K_NODES_PER_INP +
D2028\$N_INP_RANGE;

XmdsNlabelStrings = ranges;

XmNx = 700;

XmNy = 270;

XmNwidth = 110;

XmNheight = 35;

};

controls {

};

callbacks {

};

};

object Range8Menu : XmdsNidOptionMenu widget {

arguments {

XmdsNnid = DEVICE_NID;

XmdsNvalueStrings = ranges;

XmdsNnidOffset = D2028\$N_INPUTS + 7 \* D2028\$K_NODES_PER_INP +
D2028\$N_INP_RANGE;

XmdsNlabelStrings = ranges;

XmNx = 700;

XmNy = 310;

XmNwidth = 110;

XmNheight = 35;

};

controls {

};

callbacks {

};

};

object OffsetLabel : XmLabelGadget widget {

arguments {

XmNlabelString = compound_string(\"Offset (0:255)\");

XmNx = 860;

XmNy = 10;

};

controls {

};

callbacks {

};

};

object Offset1Field : XmdsExprField widget {

arguments {

XmdsNnid = DEVICE_NID;

XmNcolumns = 4;

XmdsNputOnApply = true;

XmdsNnidOffset = D2028\$N_INPUTS + 0 \* D2028\$K_NODES_PER_INP +
D2028\$N_INP_OFFSET;

XmNmarginHeight = 1;

XmNmarginWidth = 1;

XmNx = 880;

XmNy = 35;

};

controls {

};

callbacks {

};

};

object Offset2Field : XmdsExprField widget {

arguments {

XmdsNnid = DEVICE_NID;

XmNcolumns = 4;

XmdsNputOnApply = true;

XmdsNnidOffset = D2028\$N_INPUTS + 1 \* D2028\$K_NODES_PER_INP +
D2028\$N_INP_OFFSET;

XmNmarginHeight = 1;

XmNmarginWidth = 1;

XmNx = 880;

XmNy = 75;

};

controls {

};

callbacks {

};

};

object Offset3Field : XmdsExprField widget {

arguments {

XmdsNnid = DEVICE_NID;

XmNcolumns = 4;

XmdsNputOnApply = true;

XmdsNnidOffset = D2028\$N_INPUTS + 2 \* D2028\$K_NODES_PER_INP +
D2028\$N_INP_OFFSET;

XmNmarginHeight = 1;

XmNmarginWidth = 1;

XmNx = 880;

XmNy = 115;

};

controls {

};

callbacks {

};

};

object Offset4Field : XmdsExprField widget {

arguments {

XmdsNnid = DEVICE_NID;

XmNcolumns = 4;

XmdsNputOnApply = true;

XmdsNnidOffset = D2028\$N_INPUTS + 3 \* D2028\$K_NODES_PER_INP +
D2028\$N_INP_OFFSET;

XmNmarginHeight = 1;

XmNmarginWidth = 1;

XmNx = 880;

XmNy = 155;

};

controls {

};

callbacks {

};

};

object Offset5Field : XmdsExprField widget {

arguments {

XmdsNnid = DEVICE_NID;

XmNcolumns = 4;

XmdsNputOnApply = true;

XmdsNnidOffset = D2028\$N_INPUTS + 4 \* D2028\$K_NODES_PER_INP +
D2028\$N_INP_OFFSET;

XmNmarginHeight = 1;

XmNmarginWidth = 1;

XmNx = 880;

XmNy = 195;

};

controls {

};

callbacks {

};

};

object Offset6Field : XmdsExprField widget {

arguments {

XmdsNnid = DEVICE_NID;

XmNcolumns = 4;

XmdsNputOnApply = true;

XmdsNnidOffset = D2028\$N_INPUTS + 5 \* D2028\$K_NODES_PER_INP +
D2028\$N_INP_OFFSET;

XmNmarginHeight = 1;

XmNmarginWidth = 1;

XmNx = 880;

XmNy = 235;

};

controls {

};

callbacks {

};

};

object Offset7Field : XmdsExprField widget {

arguments {

XmdsNnid = DEVICE_NID;

XmNcolumns = 4;

XmdsNputOnApply = true;

XmdsNnidOffset = D2028\$N_INPUTS + 6 \* D2028\$K_NODES_PER_INP +
D2028\$N_INP_OFFSET;

XmNmarginHeight = 1;

XmNmarginWidth = 1;

XmNx = 880;

XmNy = 275;

};

controls {

};

callbacks {

};

};

object Offset8Field : XmdsExprField widget {

arguments {

XmdsNnid = DEVICE_NID;

XmNcolumns = 4;

XmdsNputOnApply = true;

XmdsNnidOffset = D2028\$N_INPUTS + 7 \* D2028\$K_NODES_PER_INP +
D2028\$N_INP_OFFSET;

XmNmarginHeight = 1;

XmNmarginWidth = 1;

XmNx = 880;

XmNy = 315;

};

controls {

};

callbacks {

};

};

object InitActionButton : XmdsXdBoxOnOffButton widget {

arguments {

XmdsNnid = DEVICE_NID;

XmNlabelString = compound_string(\"Initialization Action\");

XmdsNnidOffset = D2028\$N_INIT_ACTION;

XmNx = 15;

XmNy = 500;

XmNwidth = 155;

XmNheight = 30;

};

controls {

};

callbacks {

};

};

object StoreActionButton : XmdsXdBoxOnOffButton widget {

arguments {

XmdsNnid = DEVICE_NID;

XmNlabelString = compound_string(\"Store Action\");

XmdsNnidOffset = D2028\$N_STORE_ACTION;

XmNx = 230;

XmNy = 500;

XmNwidth = 120;

XmNheight = 30;

};

controls {

};

callbacks {

};

};

object dsOkButton : XmdsOkButton widget {

arguments {

XmNx = 15;

XmNy = 550;

};

controls {

};

callbacks {

};

};

object dsApplyButton : XmdsApplyButton widget {

arguments {

XmNx = 115;

XmNy = 550;

};

controls {

};

callbacks {

};

};

object dsResetButton : XmdsResetButton widget {

arguments {

XmNx = 210;

XmNy = 550;

};

controls {

};

callbacks {

};

};

object dsCancelButton : XmdsCancelButton widget {

arguments {

XmNx = 315;

XmNy = 550;

};

controls {

};

callbacks {

};

};

end module;

The INIT file

public fun D2028\_\_INIT(as_is \_nid, optional \_method)

{

\_name = DevNodeRef(\_nid,1); /\* get name \*/

\_ext_clock = DevNodeRef(\_nid,4); /\* get external clock if it is
enabled\*/

\_is_ext_clock_enabled = getnci(\_ext_clock,\"LENGTH\") \> 0;

\_samples = DevNodeRef(\_nid,7); /\* get samples \*/

DevCamChk(\_name,CamPiow(\_name,0,25,\_d=0,16),1,1); /\* issue stop
trigger \*/

/\* find post trigger samples (\_post_trig_samp) and make sure it is at
least 1 \*/

\_post_trig_samp = \_samples - DevNodeRef(\_nid,6);

if (\_post_trig_samp == 0) \_post_trig_samp = 1;

/\* find post trigger samples code (\_post_trig_samp_code) for input to
the digitizer \*/

/\* by taking 2s complement of post trigger samples (\_post_trig_samp)
\*/

\_post_trig_samp_code = 65536 - \_post_trig_samp;

/\* set post trigger samples \*/

\_post_trig_samp_code_low = iand(\_post_trig_samp_code, 0X00FF);

\_post_trig_samp_code_high = ishft (iand(\_post_trig_samp_code, 0XFF00),
-8);

DevCamChk(\_name,CamPiow(\_name,4,16,\_post_trig_samp_code_low,16),1,1);

DevCamChk(\_name,CamPiow(\_name,5,16,\_post_trig_samp_code_high,16),1,1);

/\* set up the sampling clock \*/

if (\_is_ext_clock_enabled) \_samp_interval_code = 32;

else

{

\_samp_interval = DevNodeRef(\_nid,3); /\* read value of sampling
interval set by user \*/

\_samp_interval_value =
\[1.0E-7,2.0E-7,5.0E-7,0.0,1.0E-6,2.0E-6,5.0E-6,0.0,1.0E-5,2.0E-5,5.0E-5,0.0,1.0E-4,2.0E-4,5.0E-4,0.0,1.0E-3,2.0E-3,5.0E-3\];

for (\_index=0; \_index \<= 18; \_index++)

{

if (\_samp_interval == \_samp_interval_value\[\_index\])
\_samp_interval_code = \_index; /\* test for match \*/

};

};

/\* check for bad clock \*/

\_bad_clock = 0;

if_error( \_samp_interval_code, \_bad_clock = 1);

if( \_bad_clock )

{

write(\*,\"Bad clock value! \"//\_nid);

return(0);

};

DevCamChk(\_name,CamPiow(\_name,0,16,\_samp_interval_code,16),1,1); /\*
set sampling interval \*/

/\* set up the record length \*/

\_record_code = \_samples / 256;

if (\_record_code == 0) \_record_code = 1;

if (\_record_code \>= 128) \_record_code = 128;

\_record_code = 65535 - \_record_code + 1;

DevCamChk(\_name,CamPiow(\_name,1,16,\_record_code,16),1,1);

/\* set up the gain (range/attenuation) for channels 1 thru 8 \*/

\_attenuation1_4 = 0;

\_attenuation5_8 = 0;

for (\_input_chan=1; \_input_chan \<= 8; \_input_chan++)

{

\_input_chan_nid = \_input_chan \* 5 + 5;

\_chan_nid = DevHead(\_nid) + \_input_chan_nid;

if (DevIsOn(\_chan_nid))

{

\_input_chan_range = \_input_chan_nid + 4;

\_current_chan_range_value = DevNodeRef(\_nid,\_input_chan_range);

\_range_value = \[0.512,1.024,2.56,5.12\];

for (\_index=0; \_index \<= 3; \_index++)

{

if (\_current_chan_range_value == \_range_value\[\_index\])
\_current_chan_atten_code = \_index; /\* test for match \*/

};

if ( \_input_chan \<= 4 ) \_attenuation1_4 = \_attenuation1_4 + ishft
(\_current_chan_atten_code, (\_input_chan - 1) \* 2);

else \_attenuation5_8 = \_attenuation5_8 + ishft
(\_current_chan_atten_code, (\_input_chan - 5) \* 2);

};

};

DevCamChk(\_name,CamPiow(\_name,6,16,\_attenuation1_4,16),1,1);

DevCamChk(\_name,CamPiow(\_name,7,16,\_attenuation5_8,16),1,1);

/\* set up the offsets for channels 1 thru 8 \*/

for (\_input_chan=1; \_input_chan \<= 8; \_input_chan++)

{

\_input_chan_nid = \_input_chan \* 5 + 5;

\_chan_nid = DevHead(\_nid) + \_input_chan_nid;

if (DevIsOn(\_chan_nid))

{

\_input_chan_offset = \_input_chan_nid + 3;

\_current_chan_offset = DevNodeRef(\_nid,\_input_chan_offset);

if ((\_current_chan_offset \> 255) \|\| (\_current_chan_offset \< 0))

{

write(\*,\"Bad offset value! \"//\_nid);

return(0);

};

/\* channel code goes from 7 to 0 for channels 1 to 8 respectively \*/

\_offset_chan_code = 8 - \_input_chan;

DevCamChk(\_name,CamPiow(\_name,\_offset_chan_code,17,\_current_chan_offset,16),1,1);

};

};

DevCamChk(\_name,CamPiow(\_name,0,9,\_d=0,16),1,1); /\* start recording
\*/

DevCamChk(\_name,CamPiow(\_name,0,26,\_d=0,16),1,1); /\* enable LAM \*/

return(1); /\* return nicely\*/

}

The STORE file

public fun d2028\_\_store(as_is \_nid, optional \_method)

{

\_name = DevNodeRef(\_nid,1); /\* get name \*/

\_samp_interval = DevNodeRef(\_nid,3); /\* get sampling interval \*/

\_ext_clock = DevNodeRef(\_nid,4); /\* get external clock \*/

\_trigger = DevNodeRef(\_nid,5); /\* get trigger \*/

\_pre_trigger = DevNodeRef(\_nid,6); /\* get number of pre trigger
samples \*/

\_samples = DevNodeRef(\_nid,7); /\* get number of samples \*/

/\* See if digitizer is done digitizing (check LAM)\*/

DevCamChk(\_name,CamPiow(\_name,0,8,\_d=0,16),1,\*);

if (!CamXandQ())

{

write(\*,\'%CAMERR, module \'//\_name//\', Device not triggered\');

return(0);

}

/\* Clear the LAM\*/

DevCamChk(\_name,CamPiow(\_name,0,10,\_d=0,16),1,\*);

/\* get the setup of the module \*/

if (getnci(\_ext_clock,\"LENGTH\") != 0) \_clock = \_ext_clock; /\*
clock is external \*/

else \_clock = make_range(\*,\*,make_with_units(\_samp_interval,\"s\"));

/\* for each channel\... \*/

for (\_input_chan=1; \_input_chan \<= 8; \_input_chan++)

{

\_input_chan_nid = \_input_chan \* 5 + 5;

\_chan_nid = DevHead(\_nid) + \_input_chan_nid;

if (DevIsOn(\_chan_nid)) /\* if channel is on \*/

{

\_startidx = DevNodeRef(\_nid,\_input_chan_nid+1);

\_endidx = DevNodeRef(\_nid,\_input_chan_nid+2);

\_lbound = if_error(long(data(\_startidx)), -\_pre_trigger);

\_lbound = min(max(\_lbound,-\_pre_trigger), \_samples-\_pre_trigger-1);

\_ubound = if_error(long(data(\_endidx)), \_samples-\_pre_trigger-1);

\_ubound = min(max(\_ubound,\_lbound), \_samples-\_pre_trigger-1);

\_dim = make_dim(make_window(\_lbound,\_ubound,\_trigger),\_clock);

\_input_chan_off = \_input_chan_nid + 3;

\_current_chan_off = DevNodeRef(\_nid,\_input_chan_off); /\* get channel
offset \*/

\_current_chan_off = -1 \* \_current_chan_off; /\* invert channel offset
\*/

\_input_chan_range = \_input_chan_nid + 4;

\_current_chan_range = DevNodeRef(\_nid,\_input_chan_range); /\* get
channel range \*/

\_coefficient = \_current_chan_range / 256;

DevCamChk(\_name,CamPiow(\_name,2,0,\_last_low,16),1,1); /\* low byte of
last address \*/

DevCamChk(\_name,CamPiow(\_name,3,0,\_last_high,16),1,1); /\* high byte
of last address \*/

DevCamChk(\_name,CamPiow(\_name,2,16,\_last_low,16),1,1); /\* low byte
of start address \*/

DevCamChk(\_name,CamPiow(\_name,3,16,\_last_high,16),1,1); /\* high byte
of start address \*/

/\* read out the channel \*/

if (\_samples \> 0)

{

\_samples_read = 0;

\_data = \*;

while (size(\_data) \< \_samples)

{

\_samples_to_read = min(\_samples - size(\_data), 16384); /\* read in
chunks of 16K \*/

DevCamChk(\_name,CamStopw(\_name,\_input_chan-1,2,\_samples_to_read,\_data_part,16),1,\*);

\_data = \[\_data,\_data_part & 255\];

}

DevPutSignal(\_chan_nid, \_current_chan_off, \_coefficient, \_data,
\_lbound, \_ubound, \_dim);

}

};

};

return(1); /\* return nicely \*/

}

**NSTX-specific VMS system startup files**

EUROPA\$ type sys\$manager:**europasysrtm.com**

\$!\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*

\$! EUROPASYSRTM.COM \--

\$!

\$! Startup NSTX-related processes on Europa.

\$!

\$! History:

\$! 12-Sep-2006 PR Add MDSplus event server:start_mdsipe.com

\$! 24-Jun-2003 PR Start daily webpage update job

\$! 13-Jun-2001 TRG Create, copied/edited from KEESSYSRTM.COM

\$! 21-Dec-2001 PR Removed startup of ACQREMOTE jobs; these are on KEES

\$! and are getting duplicated when europa reboots

\$!

\$!\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*

\$!

\$ SET NOON

\$!

\$! Start MDSplus event server on EUROPA - non-VMS nodes need to

\$! define \"mds_event_server\" as \"europa.pppl.gov:8501::\" to use it

\$! for fielding events when not directly connected to an MDS server

\$! (scope displays are most common users)

\$!

\$ \@SYS\$MANAGER:START_MDSIPE.COM

\$!

\$!

\$! \-\-- queue is on KEES, this is done there \-\--

\$! \$! submit \"real-time\" remote acquisition batch jobs

\$! \$ \@NSTX\$:\[ACQREMOTE\]MASTER_ACQREMOTE_SUBMIT.COM

\$!

\$! submit \"real-time\" VGDS batch jobs

\$ \@NSTX\$:\[VGDS.BATCHJOBS\]MASTER_VGDS_SUBMIT.COM

\$!

\$! submit \"real-time\" SQL Database batch jobs

\$ \@NSTX\$:\[DB\]MASTER_DB_SUBMIT.COM

\$

\$! submit jobs to NSTX_EVENT queue

\$ \@NSTX\$:\[EVENTQUEUES\]MASTER_NSTX_EVENT_SUBMIT.COM

\$

\$! submit daily webpage update

\$ \@RONEY\$:\[IDL.WEBTOOLS\]FIRSTTIME_SUBMITWEBUPDATE.COM

\$!

\$ REPLY/TERM=OPA0: \"EUROPASYSRTM - Procedure complete\"

EUROPA\$

KEES\$ type **sys\$manager:keessysrtm.com**

\$!\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*

\$! KEESSYSRTM.COM Install SCSI CAMAC Driver, MDSplus defs and images

\$!

\$! History:

\$! 13-Jan-2004 PR Define REMCAMSHR for TDI devices

\$! 13-Mar-2002 TRG Submit \"testshot\" jobs to create test MDSplus
trees.

\$! 15-Feb-2002 PR Very belated recognition that CTS\> SET \*/ON

\$! sends C-Z to all crates, clearing various

\$! control voltage settings; now letting CRATEMON

\$! set the crates on, so changing NSTXCAMSTART.COM

\$! 06-Feb-2002 PR MASTER_ACQREMOTE_SUBMIT had been removed (by ?)

\$! restored it

\$! 06-Sep-2000 PR adding MASTER_ACQREMOTE_SUBMIT for KEES CAMAC jobs

\$! 29-Aug-2000 PR adding MASTER_CAMAC_SUBMIT for KEES CAMAC jobs

\$! 18-Aug-2000 PR adding MASTER_DB_SUBMIT for SQL database jobs

\$! 17-Jul-2000 PR adding NSTX_MON_SERVER defn for Action Monitor

\$! 29-Jun-2000 PR added MASTER_VGDS_SUBMIT

\$! 13-Jun-2000 PR added START_RUNNSTX.COM to run RUNNSTX detached

\$! 06-Apr-2000 PR added submit of CAMAC link monitoring program

\$! 04-Apr-2000 PR added submit of CAMAC crate monitoring program

\$! 14-Feb-2000 PR added SET_ACL_CAMAC for second highway (GKC2)

\$! 20-Oct-1999 TRG submit NFS_RESTART procedure

\$! 12-Aug-1999 PR add NSTX_ACQREMOTE.COM to submit batch jobs

\$! define \"CAMAC_SERVER\"

\$! 14-Jul-1999 PR CAMAC back on GKB!

\$! 11-Jun-1999 PR Adding logical name NSTX_DISPATCH

\$! This probably belongs in a different system proced

\$! 8-Jun-1999 PR Creating LNM\$GDS_NSTX for VGDS on KEES only

\$! 2-Apr-1999 PR CAMAC is now on GKC, new old SCSI

\$! 14-DEC-1998 PR Create.

\$!\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*

\$

\$ SET NOON

\$

\$ !Restart NFS on Birch, to serve KEES disks to unix

\$
!\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\$ submit/noprint/queue=birch_system ops:\[sysmgr\]nfs_restart.com

\$

\$ !Start CAMAC for NSTX data acquisition

\$
!\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\$ \@SYS\$SYSROOT:\[SYSMGR\]NSTXCAMSTART.COM

\$ \@sys\$manager:SET_ACL_CAMAC.COM gkb200: ! set camac_owner on gkb200:

\$ \@sys\$manager:SET_ACL_CAMAC.COM gkc200: ! set camac_owner on gkc200:

\$

\$ create/name_table/nolog/prot=(w:rw)/parent=lnm\$system_directory -

LNM\$GDS_NSTX

\$

\$! still need to load this table at reboot; not sure from where yet

\$

\$! define SYSTEM logical names for MDSplus servers used by RUNNSTX

\$ DEFINE/SYSTEM NSTX_DISPATCH KEES::DISPATCH_SERVER

\$ DEFINE/SYSTEM CAMAC_SERVER KEES::GKB2_SERVER

\$ DEFINE/SYSTEM NSTX_MON_SERVER KEES::MON_SERVER

\$ DEFINE/SYSTEM REMCAMSHR CAMSHR

\$

\$! submit jobs to queue NSTX_ACQREMOTE on KEES

\$ \@SYS\$SYSROOT:\[SYSMGR\]NSTXACQREMOTE.COM

\$!

\$! start RUNNSTX as a detached process

\$ \@NSTX\$:\[NSTX.SOURCE.RUNNSTX\]START_RUNNSTX.COM

\$!

\$!

\$! submit CAMAC monitor

\$ \@NSTX\$:\[NSTX.CAMAC\]CRATEMON_SUBMIT.COM

\$ \@NSTX\$:\[NSTX.CAMAC\]LINKMON_SUBMIT.COM

\$!

\$! submit \"real-time\" CAMAC batch jobs

\$ \@NSTX\$:\[CAMAC\]MASTER_CAMAC_SUBMIT.COM

\$!

\$! submit \"real-time\" ACQREMOTE batch jobs

\$ \@NSTX\$:\[ACQREMOTE\]MASTER_ACQREMOTE_SUBMIT.COM

\$

\$! submit \"testshot\" jobs to create MDSplus trees for testing

\$ \@NSTX\$:\[ppcc.com\]submit_testshot_jobs.com

\$!

\$ REPLY/TERM=OPA0: \"KEESSYSRTM - CAMAC Procedure complete\"

KEES\$

LUNA\$ type sys\$manager:**lunasysrtm.com**

\$!\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*

\$! LUNASYSRTM.COM Install SCSI CAMAC Driver, MDSplus defs and images

\$!

\$! History:

\$! 01-Jun-2005 PR add submission of MASTER_ACQREMOTE_SUBMIT; checks

\$! for missing acquisition jobs and submits them

\$! 13-Jan-2004 PR define REMCAMSHR for TDI devices

\$! 07-Oct-2003 PR submit LUNAMON batch job

\$! 10-Dec-2002 PR Edit keessysrtm.com for luna

\$! 15-Feb-2002 PR Very belated recognition that CTS\> SET \*/ON

\$! sends C-Z to all crates, clearing various

\$! control voltage settings; now letting CRATEMON

\$! set the crates on, so changing NSTXCAMSTART.COM

\$! 14-DEC-1998 PR Create. (Orig)

\$!\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*

\$

\$ SET NOON

\$

\$

\$ !Start CAMAC for NSTX data acquisition

\$
!\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\$ \@SYS\$SYSROOT:\[SYSMGR\]LUNACAMSTART.COM

\$ \@sys\$manager:SET_ACL_CAMAC.COM gka200: ! set camac_owner on gka200:

\$

\$ create/name_table/nolog/prot=(w:rw)/parent=lnm\$system_directory -

LNM\$GDS_NSTX

\$

\$! still need to load this table at reboot; not sure from where yet

\$

\$! define SYSTEM logical names for MDSplus servers used by RUNNSTX

\$ DEFINE/SYSTEM NSTX_DISPATCH KEES::DISPATCH_SERVER

\$ DEFINE/SYSTEM CAMAC_SERVER KEES::GKB2_SERVER

\$ DEFINE/SYSTEM NSTX_MON_SERVER KEES::MON_SERVER

\$ DEFINE/SYSTEM REMCAMSHR CAMSHR

\$!

\$! submit CAMAC monitor

\$ \@NSTX\$:\[NSTX.CAMAC\]LUNACRATEMON_SUBMIT.COM

\$ \@NSTX\$:\[NSTX.CAMAC\]LUNALINKMON_SUBMIT.COM

\$!

\$! select missing jobs and submit them

\$ \@NSTX\$:\[ACQREMOTE\]MASTER_ACQREMOTE_SUBMIT.COM

\$!

\$! select missing jobs and submit them

\$ \@NSTX\$:\[CAMAC\]MASTER_CAMAC_SUBMIT.COM

\$!

\$ REPLY/TERM=OPA0: \"LUNASYSRTM - CAMAC Procedure complete\"

LUNA\$

Monitoring/restarting CAMAC crates on KEES:
NSTX\$:\[NSTX.CAMAC\]CRATEMON.COM

KEES\$ type cratemon.com

\$! Crate Monitor: controlfile is
NSTX\$:\[NSTX.ADMIN.CTS\]CRATES_ONLINE.TXT

\$! Create: 02-Apr-00 PR

\$!

\$! IDL program loops internally; on failure, mail message is sent,

\$! and program is resubmitted; output of program is written to Web page

\$! http://mel.pppl.gov/www_root/serverdoc/nstx/camac/cratestatus.html

\$!\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\$!

\$ set noon

\$ setup nstx

\$ if f\$mode().eqs.\"BATCH\" then set process/name=CRATEMON

\$

\$ ERRLOOP:

\$ IDL

.RUN NSTX\$:\[NSTX.CAMAC\]CRATEMONITOR.PRO

CRATEMONITOR

EXIT

\$!

\$ write sys\$output \"Unexpected exit from CRATEMONITOR.PRO\"

\$ wait 0:01:00

\$ goto ERRLOOP

KEES\$

Monitoring/restarting CAMAC crates on LUNA:
NSTX\$:\[NSTX.CAMAC\]LUNACRATEMON.COM

KEES\$ type lunacratemon.com

\$! LUNA Crate Monitor: controlfile is
NSTX\$:\[NSTX.ADMIN.CTS\]LUNA_CRATES_ONLIN

.TXT

\$! Edit: 11-Dec-02 PR Version for luna based on version for kees

\$! Create: 02-Apr-00 PR

\$!

\$! IDL program loops internally; on failure, mail message is sent,

\$! and program is resubmitted; output of program is written to Web page

\$!
http://mel.pppl.gov/www_root/serverdoc/nstx/camac/lunacratestatus.html

\$!\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\$!

\$ set noon

\$ setup nstx

\$ setup IDL \"TEK\" ! avoid messages about no X display

\$ if f\$mode().eqs.\"BATCH\" then set process/name=LUNACRATEMON

\$

\$ ERRLOOP:

\$ IDL

.RUN NSTX\$:\[NSTX.CAMAC\]LUNACRATEMONITOR.PRO

LUNACRATEMONITOR

EXIT

\$!

\$ write sys\$output \"Unexpected exit from LUNACRATEMONITOR.PRO\"

\$ wait 0:01:00

\$ goto ERRLOOP

Monitoring/restarting CAMAC crates on MEL:
NSTX\$:\[NSTX.CAMAC\]MELCRATEMON.COM

KEES\$ type melcratemon.com

\$! Crate Monitor: controlfile is
NSTX\$:\[NSTX.ADMIN.CTS\]CRATES_ONLINE.TXT

\$! Create: 02-Apr-00 PR

\$! Edit: 09-Jun-00 PR version for MEL

\$!

\$! IDL program loops internally; on failure, mail message is sent,

\$! and program is resubmitted; output of program is written to Web page

\$!
http://mel.pppl.gov/www_root/serverdoc/nstx/melcamac/cratestatus.html

\$!\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\$!

\$ set noon

\$ setup nstx

\$ setup IDL4 ! no IDL5 on MEL

\$ if f\$mode().eqs.\"BATCH\" then set process/name=MELCRATEMON

\$

\$ ERRLOOP:

\$ IDL

.RUN NSTX\$:\[NSTX.CAMAC\]MELCRATEMONITOR.PRO

MELCRATEMONITOR

EXIT

\$!

\$ write sys\$output \"Unexpected exit from MELCRATEMONITOR.PRO\"

\$ wait 0:01:00

\$ goto ERRLOOP

Provide EPICS with monitor of KEES highways (B and C) status:
NSTX\$:\[NSTX.CAMAC\]LINKMON.COM

KEES\$ type linkmon.com

\$! Link Monitor: alarm reported by EPICS if this prm can\'t address
modules

\$! Create: 04-Apr-00 PR

\$!

\$! IDL program in infinite loop ; on failure, program is resubmitted

\$!\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\$!

\$ set noon

\$ setup nstx

\$ if f\$mode().eqs.\"BATCH\" then set process/name=LINKMON

\$

\$ ERRLOOP:

\$ IDL

.RUN NSTX\$:\[NSTX.CAMAC\]LINKMONITOR.PRO

LINKMONITOR

EXIT

\$!

\$ write sys\$output \"Unexpected exit from LINKMONITOR.PRO\"

\$ wait 0:01:00

\$ goto ERRLOOP

KEES\$

Provide EPICS with monitor of LUNA highway (A) status:
NSTX\$:\[NSTX.CAMAC\]LUNALINKMON.COM

KEES\$ type lunalinkmon.com

\$! Link Monitor: alarm reported by EPICS if this prm can\'t address
modules

\$! Create: 04-Apr-00 PR

\$!

\$! IDL program in infinite loop ; on failure, program is resubmitted

\$!\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\$!

\$ set noon

\$ setup nstx

\$ if f\$mode().eqs.\"BATCH\" then set process/name=LunaLINKMON

\$

\$ ERRLOOP:

\$ IDL

.RUN NSTX\$:\[NSTX.CAMAC\]LUNALINKMONITOR.PRO

LUNALINKMONITOR

EXIT

\$!

\$ SHOW TIME

\$ write sys\$output \"Unexpected exit from LUNALINKMONITOR.PRO\"

\$ wait 0:01:00

\$ goto ERRLOOP

KEES\$

BATCH ANALYSIS

In process of being eliminated, NSTX_VGDS, currently idle

Oct 31, 2006 batch queues with NSTX jobs in bold. Inactive queues at
reduced type size.

**KEES\$ show que/all/batch**

Batch queue ABS\$BIRCH, stopped, on BIRCH::

Batch queue ARCHIVE, stopped, on BEANIE::

Batch queue ATLAS_EVENT, stopped, on ATLAS::

Batch queue ATLAS_NORM, stopped, on ATLAS::

Batch queue ATLAS_SYSTEM, stopped, on ATLAS::

Batch queue BEANIE_BACKUP, idle, on BEANIE::

**Batch queue BEANIE_NORM, available, on BEANIE::**

Entry Jobname Username Status

\-\-\-\-- \-\-\-\-\-\-- \-\-\-\-\-\-\-- \-\-\-\-\--

12 **REE\$SYS_STARTUP** SYSTEM Executing

556 ACCOUNT SYSOPR Holding until 31-OCT-2006 23:30:00

692 ARCH ARC_DISK Holding until 1-NOV-2006 08:00:00

**Batch queue BEANIE_SYSTEM, idle, on BEANIE::**

Entry Jobname Username Status

\-\-\-\-- \-\-\-\-\-\-- \-\-\-\-\-\-\-- \-\-\-\-\--

739 **BATCH_WATCH** SYSOPR Holding until 31-OCT-2006 13:05:00

705 **NSTX_EVERYDAY_BEANIE**

GIBNEY Holding until 31-OCT-2006 13:05:01

517 ***QCS_PURGE*** GIBNEY Holding until 31-OCT-2006 20:30:00

Batch queue BEANIE_TRANSP_NORM, idle, on BEANIE::

Batch queue BEANIE_VMEC, idle, on BEANIE::

Batch queue BIRCH_BACKUP, idle, on BIRCH::

Batch queue BIRCH_EVENT, idle, on BIRCH::

Batch queue BIRCH_NORM, idle, on BIRCH::

Entry Jobname Username Status

\-\-\-\-- \-\-\-\-\-\-- \-\-\-\-\-\-\-- \-\-\-\-\--

613 SHOW_ERRORS GIBNEY Holding until 1-NOV-2006 00:05:00

**Batch queue BIRCH_SYSTEM, idle, on BIRCH::**

Entry Jobname Username Status

\-\-\-\-- \-\-\-\-\-\-- \-\-\-\-\-\-\-- \-\-\-\-\--

555 ACCOUNT SYSOPR Holding until 31-OCT-2006 23:30:00

557 SYNC_TIMES SYSTEM Holding until 31-OCT-2006 23:45:00

561 EVERYDAY SYSOPR Holding until 1-NOV-2006 00:00:00

569 **MDS_EVERYDAY** SYSOPR Holding until 1-NOV-2006 00:00:00

570 **NSTX_EVERYDAY** SYSOPR Holding until 1-NOV-2006 00:00:00

Batch queue BIRCH_TRANSP_NORM, idle, on BIRCH::

Batch queue B_DEFRAG, idle, on BIRCH::

Entry Jobname Username Status

\-\-\-\-- \-\-\-\-\-\-- \-\-\-\-\-\-\-- \-\-\-\-\--

629 RABBIT7_RUNNER SYSOPR Holding until 1-NOV-2006 01:15:00

Generic batch queue DSN\$BATCH

Batch queue DSN\$BATCH_BEANIE, stopped, on BEANIE::

Batch queue DSN\$BATCH_BIRCH, stopped, on BIRCH::

Batch queue DSN\$BATCH_ERIS, stopped, on ERIS::

Batch queue DSN\$BATCH_IO, stopped, on IO::

Batch queue DSN\$BATCH_LEDA, idle, on LEDA::

Batch queue DSN\$BATCH_MANGO, stopped, on MANGO::

Batch queue DSN\$BATCH_MEL, stopped, on MEL::

Batch queue DSN\$BATCH_RAX, stopped, on RAX::

Batch queue DSN\$BATCH_SNAX, stopped, on SNAX::

Batch queue DSN\$BATCH_VS06, stopped, on VS06::

Batch queue DSN\$BATCH_ZENITH, stopped, on ZENITH::

Batch queue D_RESTORE, idle, on BEANIE::

Entry Jobname Username Status

\-\-\-\-- \-\-\-\-\-\-- \-\-\-\-\-\-\-- \-\-\-\-\--

738 RESTOREPBX ARC_PBX Holding until 31-OCT-2006 13:30:00

726 RESTOREPLT ARC_PLT Holding until 1-NOV-2006 10:30:00

Batch queue D_RETRIEVE, idle, on BEANIE::

**Batch queue EUROPA_EVENT, available, on EUROPA::**

Entry Jobname Username Status

\-\-\-\-- \-\-\-\-\-\-- \-\-\-\-\-\-\-- \-\-\-\-\--

46 **CALC_COILDATA_SCRATCHFILE** SYSTEM Executing

**Batch queue EUROPA_NORM, idle, on EUROPA::**

Entry Jobname Username Status

\-\-\-\-- \-\-\-\-\-\-- \-\-\-\-\-\-\-- \-\-\-\-\--

**657 BATCHUPDATEWEBFILES** RONEY Holding until 1-NOV-2006 05:00:00

**Batch queue EUROPA_SYSTEM, idle, on EUROPA::**

Entry Jobname Username Status

\-\-\-\-- \-\-\-\-\-\-- \-\-\-\-\-\-\-- \-\-\-\-\--

528 **NSTX_DAILY** SYSTEM Holding until 31-OCT-2006 22:00:00

982 MONTHLY_DESK_REPORT

CARROLL Holding until 1-NOV-2006 09:00:00

986 MONTHLY_DESK_EMAIL_NOTIFY

HELPDESK Holding until 1-NOV-2006 11:00:00

**Batch queue KEES_EVENT, available, on KEES::**

Entry Jobname Username Status

\-\-\-\-- \-\-\-\-\-\-- \-\-\-\-\-\-\-- \-\-\-\-\--

29 **LINKMON** SYSTEM Executing

30 **RGASHOT_404** RONEY Executing

39 **CWL_VIPS** SYSTEM Executing

50 **FIRETIP_ANALYSIS** KCLEE Executing

361 **CRATEMON** RONEY Executing

506 **CAMERAOFF** SYSTEM Holding until 31-OCT-2006 20:00:00

678 **ATT** RONEY Holding until 1-NOV-2006 07:00:00

Batch queue KEES_NORM, idle, on KEES::

Entry Jobname Username Status

\-\-\-\-- \-\-\-\-\-\-- \-\-\-\-\-\-\-- \-\-\-\-\--

571 ACCOUNT SYSOPR Holding until 31-OCT-2006 23:30:00

**Batch queue KEES_SYSTEM, available, on KEES::**

Entry Jobname Username Status

\-\-\-\-- \-\-\-\-\-\-- \-\-\-\-\-\-\-- \-\-\-\-\--

48 **ENGINEERING_TESTSHOT**

GIBNEY Executing

49 **PCS_TESTSHOT** GIBNEY Executing

Batch queue LEDA_EVENT, idle, on LEDA::

Batch queue LEDA_NORM, idle, on LEDA::

Batch queue LEDA_SYSTEM, idle, on LEDA::

**Batch queue LUNA_EVENT, available, on LUNA::**

Entry Jobname Username Status

\-\-\-\-- \-\-\-\-\-\-- \-\-\-\-\-\-\-- \-\-\-\-\--

31 **DMANJ** BELL Executing

40 **CAL_ZEFF** BDAVIS Executing

57 **LUNACRATEMON** SYSTEM Executing

60 **ACQ_DEPMON** SYSTEM Executing

61 **SFLIP_GAINMON** SYSTEM Executing

**Batch queue LUNA_NORM, available, on LUNA::**

Entry Jobname Username Status

\-\-\-\-- \-\-\-\-\-\-- \-\-\-\-\-\-\-- \-\-\-\-\--

58 **LUNALINKMON** SYSTEM Executing

634 **USERVERSIONS** RONEY Holding until 1-NOV-2006 03:00:00

Batch queue LUNA_SYSTEM, idle, on LUNA::

Batch queue MEL_EVENT, idle, on MEL::

Batch queue MEL_NORM, idle, on MEL::

Entry Jobname Username Status

\-\-\-\-- \-\-\-\-\-\-- \-\-\-\-\-\-\-- \-\-\-\-\--

572 ACCOUNT SYSOPR Holding until 31-OCT-2006 23:30:00

Batch queue MERGE_QUEUE, stopped, on BEANIE::

**Batch queue NSTX_ACQREMOTE, available, on KEES::**

Entry Jobname Username Status

\-\-\-\-- \-\-\-\-\-\-- \-\-\-\-\-\-\-- \-\-\-\-\--

26 **ACQ_PARMS** RONEY Executing

27 **ACQ_PPCC** DMASTROVITO Executing

32 **VIPS2_412** SYSTEM Executing

33 **SPRED_412** SYSTEM Executing

34 **SET_MIG_FILAMENTS** SYSTEM Executing

35 **LOWERDIVCAM_MASK404** SYSTEM Executing

36 **RESET_FV_NIM** SYSTEM Executing

37 **RESET_HIRES_FV_NIMS** SYSTEM Executing

38 **ACQ_EPICS_CREATE_NEWTREE** SYSTEM Executing

42 **ACQ_HSENSOR** SYSTEM Executing

Batch queue NSTX_BULK_RESTORE, idle, on BIRCH::

Batch queue NSTX_DB, stopped, on RHEA::

**Batch queue NSTX_EVENT, available, on EUROPA::**

Entry Jobname Username Status

\-\-\-\-- \-\-\-\-\-\-- \-\-\-\-\-\-\-- \-\-\-\-\--

44 **IR_ADDTOOLDTREE** GZIMMER Executing

45 **IR_ADDTONEWERTREE** GZIMMER Executing

**Batch queue NSTX_VGDS, available, on LEDA::**

Entry Jobname Username Status

\-\-\-\-- \-\-\-\-\-\-- \-\-\-\-\-\-\-- \-\-\-\-\--

759 **DIV_BOLOM_VGDS** RONEY Executing

760 **BOLOM_VGDS** RONEY Executing

761 **WAVEFORMS** RONEY Executing

762 **WAVEFORM_CSXR** RONEY Executing

763 **WAVEFORM_NEL** RONEY Executing

764 **WAVEFORM_COILCURRENTS** RONEY Executing

765 **WAVEFORM_TOTPWR** RONEY Executing

766 **WAVEFORM_NB** RONEY Executing

767 **WRITE_VFLOAT_CLASS4_PERSHOT** RONEY Executing

768 **WRITE_VFLOAT_CLASS3_PERSHOT** RONEY Executing

769 **WRITE_ISAT_CLASS4_PERSHOT** RONEY Executing

770 **WRITE_ISAT_CLASS3_PERSHOT** RONEY Executing

Batch queue NSTX_VGDS_IO, stopped, on IO::

Batch queue RHEA_EVENT, stopped, on RHEA::

Batch queue RHEA_NORM, stopped, on RHEA::

Batch queue RHEA_SYSTEM, stopped, on RHEA::

Batch queue SLS\$, stopped, on BIRCH::

Batch queue SLS\$BIRCH, idle, on BIRCH::

Batch queue SLS\$EUROPA, idle, on EUROPA::

Generic batch queue SYSTEM\$BATCH

Entry Jobname Username Status

\-\-\-\-- \-\-\-\-\-\-- \-\-\-\-\-\-\-- \-\-\-\-\--

607 CHECK_INDEXF SYSTEM Holding until 1-NOV-2006 01:00:00

645 CSD_CLEAN SYSOPR Holding until 1-NOV-2006 04:00:00

Generic batch queue TFTR\$INGRES

Generic batch queue TFTR_ARCHIVE

Entry Jobname Username Status

\-\-\-\-- \-\-\-\-\-\-- \-\-\-\-\-\-\-- \-\-\-\-\--

123 TFTRARC_SUBALL ARC_TFTR_1 Pending

121 TFTR_RETRY ARC_TFTR_1 Pending

Generic batch queue TFTR_ARCHIVE0

Generic batch queue TFTR_ARCHIVE2

Entry Jobname Username Status

\-\-\-\-- \-\-\-\-\-\-- \-\-\-\-\-\-\-- \-\-\-\-\--

125 TFTRARC_SUBALL ARC_TFTR_2 Pending

Generic batch queue TFTR_ARCHIVE3

Entry Jobname Username Status

\-\-\-\-- \-\-\-\-\-\-- \-\-\-\-\-\-\-- \-\-\-\-\--

126 TFTRARC_SUBALL ARC_TFTR_3 Pending

Generic batch queue TFTR_RESTORE

Generic batch queue TFTR_RESTORE_0

Generic batch queue TFTR_RESTORE_2

Generic batch queue TFTR_RESTORE_3

Generic batch queue TFTR_RETRIEVE

Generic batch queue TFTR_RETRIEVE_2

Batch queue TFTR_T_ARCHIVE, stopped, on BEANIE::

Batch queue TFTR_T_ARCHIVE0, idle, on BEANIE::

Batch queue TFTR_T_ARCHIVE2, stopped, on BEANIE::

Batch queue TFTR_T_ARCHIVE3, stopped, on BEANIE::

Batch queue TFTR_T_RESTORE, idle, on BEANIE::

Batch queue TFTR_T_RESTORE_0, idle, on BEANIE::

Batch queue TFTR_T_RESTORE_2, idle, on BEANIE::

Batch queue TFTR_T_RESTORE_3, idle, on BEANIE::

Batch queue TFTR_T_RETRIEVE, idle, on BEANIE::

Batch queue TFTR_T_RETRIEVE_2, idle, on BEANIE::

Batch queue U_ARCHIVE, stopped, on BEANIE::

Entry Jobname Username Status

\-\-\-\-- \-\-\-\-\-\-- \-\-\-\-\-\-\-- \-\-\-\-\--

129 RESTORE_TRANSP ARC_TRANSP Pending

130 RESTORE_USC ARC_USC Pending

KEES\$