The Adam message system extensions provide access to the message system at the level of the ams library and a fairly detailed knowledge of the Adam message system and how it is used by Adam tasks is required. Therefore, this section describes a set of Tcl procedures that use the message system interface to provide a higher level interface that is suitable for controlling Adam tasks from a graphical user interface. The low-level commands are described in appendix C.
Some of the features of Adam tasks described here appeared in release 3.1 and so you must ensure that any tasks to be used with Tcl have been linked with Adam 3.1 or later.
Command languages (such as ICL or Tcl/Tk) control Adam tasks by sending them Adam messages and responding to any messages from the task The messages from the task request such things as new values for parameters or contain text to displayed to the user. This section describes what sort of messages tasks respond to and what replies can be expected; it concentrates on data reduction tasks and ignores some of the more complicated behavour of instrument control tasks.
An adam task supports one or more commands, normally referred to as actions, (e.g. the
KAPPA task supports “add”, “cadd”, “stats” etc.) and is instructed to execute one of them by
sending it an “OBEY” message. The message contains the action name (e.g. “add”) and a
command line which can contain parameter values and any of the keywords that modify the
behaviour of the parameter system (e.g. “in1=test accept”). If the task recognises the action
name3
it responds with an actstart
message; the message name field of the message will be the
action name and the status field will be DTASK__ACTSTART
. The task then starts executing the
command.
In the simplest possible case, where the action writes no text and does not need to prompt for any
parameter values, the task completes the action and sends an endmsg
message to the command
language. The message name is again the action name and the status will be DTASK__ACTCOMPLETE
. The
task is now ready to execute another action.
If, as usually happens, the task does want to display some text, it will send one or more inform
messages; the text to display will be in the value field of the message. Note that the message system
makes no distinction between text and error reports, however, the adam error reporting system
always prefixes the first line of an error message with two exclamation marks and subsequent lines
with a single exclamation mark. If the task needs a value for a parameter it will send a paramreq
message; the value field will contain the parameter name, prompt, default value etc.. The command
language must reply with a paramrep
message with the new parameter value in the value
field.
The only other message that a task might send as a result of an “OBEY” is a sync
message; the
purpose of this message is to instruct the command language to ensure that all output has been
actually written to the screen for the user to read—for example, instructions on how to perform some
interaction with a graphics device. In the context of a GUI, where updates to the screen are performed
asynchronously whenever the GUI process is idle, the message probably has no useful function.
However, a synchrep
message must be sent to acknowledge the sync
message (the adamtask library
described below does this automatically).
If an error occurs during the execution of a command, the status field of the final endmsg
message will
be the final exit status of the action; ie. something other than DTASK__ACTCOMPLETE
. If the
action cannot even be started (if, for example, the action name isn’t recognised) there will
be no actstart
message and the actcomplete
message will contain an error status (eg.
SUBPAR__NOACT
).
To set a parameter, you send a “SET” message with the message name set to the parameter name in the
form action:parameter (eg. stats:ndf) and the value field to the desired parameter value. The task will
respond with a setresponse
message with a status field set to SAI__OK
if the parameter was
sucessfully set. If not, it will send one of more inform
messages containing error messages followed by
a setresponse
message with a status other than SAI__OK
(for example, SUBPAR__NOPAR
if the
parameter didn’t exist). When the task executes the coresponding action it will behave
exactly as if the parameter had been set with a command line argument in the “OBEY”
message.
To get a parameter value, send a “GET” message with the parameter in the message name
field; the
task will respond with a getresponse
message with the name
set to the parameter name and
with the parameter’s value in the value
field. Errors are handled in the same way as for a
“SET”. The “GET” message is only really useful if the task is running with its type set to “I”,
otherwise all of an actions parameters are annulled (set to have no value) when an action
completes.
A “CONTROL” message instructs a task to perform one of the pre-defined actions that all Adam tasks support. There are two control actions recognised:
default
controlresponse
message with the value field set to the new directory. If a “CONTROL” message with the
action set to “default” has a blank value field the value field in the setresponse
message
will be set to the current default directory.
par_reset
controlresponse
message.The final type of message is the “CANCEL” message which is similar to an “OBEY” message but data reduction tasks do not support any “CANCEL” actions.
The interface is loaded by reading the file /star/lib/startcl/adamtask.tcl with the tcl command:
This defines a procedure called adamtask
which starts an Adam task. It takes two arguments: a
name to be used to refer to the task in later Tcl commands, and, optionally, the name of the
executable file to run. if the second argument is omitted, the name must be the name, as
known to the Adam message system, of a task already loaded. In addition it creates a new
Tcl command with the same name as the task which can then be used to communicate with the
task.
For example:
will start the KAPPA monolith and create a Tcl command called kappa which can be used to send
messages to the task. The first argument to this new command is the type of Adam message to send to
the task and is one of set
, get
, obey
, cancel
, paramreply
or syncrep
.
The format of the command to send a task an obey message is:
So, for example, we can instruct KAPPA to execute the add command with:
However, we don’t receive any notification of when the obey has completed.
The action to be taken when a message of a particular type is sent by the task is specified by additional arguments consisting of a message type with a hyphen prepended followed by a Tcl command to be executed when the message is received. The command is executed in global scope in the same way as widget and X event bindings. So, for example:
Will print “add finished” on the terminal when the obey has completed.
The various fields in the message can be inserted in the command to be executed wherever the percent character appears (similar to the substitutions performed when widget bindings are invoked). For example:
will print the messages output by the stats command on the terminal. The following tokens are recognised for all message types:
token | replaced by |
%C | Message context |
%T | Task name |
%N | Message name |
%P | Path |
%M | Message id |
%S | Status |
%V | Message value |
%R | Reply Token |
%% | % |
token | replaced by |
%n | parameter name |
%p | prompt string |
%d | parameter default |
%h | help text |
%e | error message |
Dealing with a paramreq message is more complicated than any other message type because it demands that a reply is sent to the task before it will continue. The format of the command to send a paramreply message is:
The <reply-token>
parameter is used by the message system to route the message back to the task
that made the parameter request and can be extracted from the paramreq message.
About the simplest example is:
This will reply with “!” whenever any parameter is prompted for. A more realistic example is:
Default handlers are provided for paramreq, inform and sync messages. The handler for paramreq messages is the one listed above. The handler for inform messages creates a dialog box (one for each task) containing a scrolling text widget and inserts the message into it. These ensure that, by default, important messages are not ignored; they are adequate during development but for production systems bespoke inform message handlers will almost certainly be required. The handler for sync messages calls the Tcl update command and then sends a syncrep message to the task.
If you want to ignore a message type then specify an empty string as the handler procedure. For example:
will run “stats” and log the output to a file instead of displaying them.
The format of the remaining command options that send messages to a task are:
There are some additional command options that don’t actually send any messages to the task:
adamtask
procedure) and
deletes the task procedure.
loads KAPPA and tries 100 times at 100 millisecond intervals to establish a message system path.
All the task commands return immediately the appropriate message has been sent; they do not wait for the task to acknowledge the receipt of the message. The following code illustrates how to wait for an action (in this case an obey) to be completed:
Note that the set command is executed in global scope so in this case there is no need to declare done to be global. If done were to be set in a procedure as in:
then a global command is required. While the tkwait command is waiting, widget and X event bindings can still be triggered and adam messages received.
If a large number of adam messages are sent without waiting for an acknowledgement there is a risk of filling up the buffers in the message system and causing the system to deadlock. In order to avoid this happening you should:
3Tasks that contain only one command ignore the action name and execute the command regardless