Initial revision

This commit is contained in:
cvs
2000-02-07 10:38:55 +00:00
commit fdc6b051c9
846 changed files with 230218 additions and 0 deletions

45
doc/manager/alias.htm Normal file
View File

@ -0,0 +1,45 @@
<HTML>
<HEAD>
<TITLE>Aliases in SICS</TITLE>
</HEAD>
<BODY>
<H1>Aliases in SICS</H1>
<P>
SICS knows two different kinds of aliases: object aliases and command
aliases. This is confusing but finds its explanation in the structure
of SICS internals.
</P>
<h2>Object Aliases</h2>
<p>
An object alias is another name for a first class object installed
into the SICS interpreter. For instance a second name for a motor. For
instance the motor twotheta is quite often aliased to a4. Such an
alias can be used like a normal SICS objects. Even in commands which
access internal SICS interfaces like the drive command or
others. Object aliases are installed into SICS with the SICSAlias
command:
<DL>
<DT>SicsAlias newname oldname
<DD>This command installs newname as alias for the object oldname.
</dl>
SicsAlias can only be used within initialization scripts.
</p>
<h2>Command Aliases</h2>
<p>
Command aliases are shortcuts for lengthy commands. For instance one
might want to define A4LL as a shortcut for "a4 softlowerlim". This is
just to save typing or adapt SICS to MAD users who appear to have an
unlimited memory for 2-4 letter acronyms. It is possible to redefine a
SICS object with this for instance to define tt as an alias for
temperature. However if one tries to use tt in a drive command it will
fail because it is just a text replacement. A command alias can be
installed into SICS at any time with manager privilege and the
command:
<DL>
<DT>alias shortcut bla bla bla ....
<DD>This define shortcut as an alias for everything behind it.
</DL>
A shortcut may take parameters.
</p>
</BODY>
</HTML>

55
doc/manager/client.htm Normal file
View File

@ -0,0 +1,55 @@
<HTML>
<HEAD>
<TITLE>SICS Client Configuration</TITLE>
</HEAD>
<BODY>
<H1>SICS Client Configuration</H1>
<P>
Currently, SICS clients are written in Tcl/TK. This means that these programs
are just scripts wich can be edited. Such editing is necessary in order to let
the clients know how to connect to a server. All client configuration
information is kept in an array named INI which is at the very top of the file.
Configurable values in INI are:
<DL>
<DT> DefUser
<DD> The SICS user name for the initial logon to the server when connecting.
<DT>DefPasswd
<DD> The password of the default user for logon.
<DT>ServerPort
<DD> The port number where the server is listening.
<DT>InterruptPort
<DD> The interrupt port number of the server.
<DT>box
<DD> The computer on which the SICS server is running.
<DT>usPasswd
<DD>The password of the SICS user. This is used as password when setting
user rights from the menu.
<DT>muPasswd
<DD>The password of the SICS managers. This is used as password when setting
user rights from the menu.
<DT>logpath
<DD>Only for the command line client. On request of the SICS users each
command line client logs all I/O into a logfile. This logfile resides on the
computer running the SICS server. This allows SICS managers to check what
user have done to the machine. The logpath element defines the path to the
directory where the automatically
created log files are kept on the computer running the SICS server.
</DL>
The rest of the parameters and the file is programmers only. Reasonable values
for those parameters can be found in the server configuration file. And of course,
you need to know where the server is running.
</P>
<p>
At the very top of the client script there is the full path name of the Tcl/TK
interpreter to run in. This must be a wish for the command line client and a
blt_wish for the status display client. This may need to be changed if a client
comes up with: command not found. Valid copies of these executables can be
found in /data/lnslib/bin. Tcl/TK needs own libraries of scripts as well. The
places where these libraries sit is defined through the environment variables
TCL_LIBRARY and TK_LIBRARY. Suitable libraries are under /data/lnslib. For
details inspect /data/lnlib/bin/lns.login. When moving a client to a machine
where the clients need to run stand alone this stuff needs to be copied and
TCL_LIBRARY and TK_LIBRARY properly defined in the .login file.
</p>
</BODY>
</HTML>

68
doc/manager/cliinst.htm Normal file
View File

@ -0,0 +1,68 @@
<HTML>
<HEAD>
<TITLE>Installing SICS Java Clients on PC's</TITLE>
</HEAD>
<BODY>
<H1>Installing SICS Java Clients on PC's</H1>
<P>
Some of the newer SICS clients are written in Java. Java is a platform
independent system. This means the SICS client applications can be run as
native PC systems as well. Both at home and at SINQ. In order to do this two
pieces of software are required:
<ul>
<li>A Java Runtime system.
<li>The SICS application.
</ul>
And the two of them need to be married which each other in some secret way.
This document tells you how to do it.
</P>
<h2>Installing SICS Java Clients on IBM compatible PC's</h2>
<p>
A prerequisite for the installation of the software is either the Windows 95
or Windows NT operating system. Pure DOS or Windows 3.* systems won't do.
</p>
<p>
Installing the java runtime on your computer is easy: On the laboratory
Windows NT server, lns00, there exists a share called lnslib. Below lnslib
there is a directory called java. In this directory there is a executable
file called jdk115-win32. Simply double clicking that one will invoke an
installer which installs java on your PC's harddisk.
Answer questions as required and soon you will be done.
</p>
<p>
In the same directory: lns00//lnslib/java, the SICS client application files
can be found as well. Currently available are:
<ul>
<li>sicsclient.jar or zip for the SICS Command Line Client
<li>powderstatus.jar or zip for the powder diffractometer status display (DMC and
HRPT).
<li>sansstatus.jar or zip for the SANS status display.
</ul>
Copy those files wherever you like on your harddisk. But remember where you
put them. You may even consider to use the ones stored at lns00.
</p>
<p>
Now the java run time and the SICS application need to be married. This is
done via batch files. Template batch files to be configured by you are
stored at lns00//lnslib/java. Currently availabel are:
<ul>
<li>sics.bat for the Sics Command Line Client
<li>powderstatus.bat for the Powder Diffractometer Status Display
<li>sansstatus.bat for the SANS Status Display
</ul>
Copy the required batch files to a place somewhere on your path. Copying
alone does not do the job, the batch files need to be configured. Edit the
batch file with notepad. Make the variable jheim point to the directory
where you installed the java run time kit. Set the variabel sheim to the
directory to which you copied the SICS application jar file.
</p>
<p>
Then you should be done. You may start the application by invoking the batch
file from the command line. You may also create a shortcut on your desktop
to the batch file using standard windows procedures. If you start the
application from the desktop you also get a DOS window each time. If you
dislike this go into Properties/shortcut of the shortcut on the desktop and
configure the textfield labelled Run to Minimized.
</p>
</BODY>
</HTML>

217
doc/manager/command.htm Normal file
View File

@ -0,0 +1,217 @@
<html>
<head>
<title>Command Initialisation</title>
</head>
<body>
<h2>Command Initialisation</h2>
<p>
Besides the general SICS commands which are available for all instruments,
there exist instrument specific commands. Such instrument specific
objects are configured into the system through special commands in the
initialisation file. Such special commands are described here.
<DL>
<DT>MakeRuenBuffer
<DD>MakeRuenBuffer makes the R&#252;nBuffer system available.
<DT>MakeDrive
<DD>MakeDrive craetes the drive command.
<DT>MakeScanCommand name countername headfile recoverfil
<DD>MakeScanCommand initialises the SICS internal scan command. It will be
accessible as name in the system. The next parameter is the name of a valid
counter object to use for counting. The next parameter is the full pathname of
a header description file. This file describes the contents of the header of
the data file. The format of this file is described below. The parameter
recoverfil is the full pathname of a file to store recover data. The internal
scan command writes the state of the scan to a binary file after each scan point.
This allows for restarting of aborted scans.
<DT>MakePeakCenter scancommand
<DD>MakePeakCenter initialises the peak analysis commands peak and center. The
only parameter is the name of the internal scan command.
<DT>DMCInit
<DD>DMCInit creates the DMC StoreData command. This command writes NeXus files
for DMC.
<DT>InitSANS dictionary-filename
<DD>InitSANS creates the StoreData command for SANS. This command writes
the current state of the instrument into a NeXus file. The structure of the
NeXus file is described in a special dictionary file which is a required
parameter to this command. For details about the format of this file see
the NXDICT-API documentation.
<DT> Publish name access
<DD> The SICS server uses Tcl as its internal macro language. However, it was felt
that the whole Tcl command set should not be available to all users
from the command line without any protection. There are reasons for this: careless use
of Tcl may clog up memory, thereby grinding the system to a halt. Invalid Tcl statements
may cause the server to hang. Last not least, Tcl contains commands to manipulate files
and access the operating system. This is a potential security problem when the server
is hacked. However, in order to make macro procedures available the Publish
command exists. It makes a Tcl command name available to SICS users with the
access code access. Valid values for access are: Internal, Mugger, User and Spy.
<DT> MakeMulti name
<DD> SANS uses a special syntax feature where several motors are grouped into a
component group. For example beamstop or detector. MakeMulti creates such a
group with the name name. Once such a group has been created, it has to be
configured. For this a few configuration commands are available:
<DL>
<DT>name alias motname compname
<DD> This command makes motor motname available as component motor compname.
For example: <b>bs alias bsx x</b> makes motor bsx available as x in the beamstop
group. Then the bsx motor can be driven by the command <b>bx x = 12.</b>.
<DT> name pos posname motname value motname value ....
<DD> The group command supports the notion of named positions. This means that
a special combination of angles can be accessed through a name. This commands
defines such a named position with the name posname. posname is followed by pairs
of motorname value which define the position.
<DT>name endconfig
<DD>Once a group has been completely defined the configuration process must be
ended with endconfig.
</DL>
<DT>MakeMono name M1 M2 M3 M4
<DD>This command creates a crystal monochromator object. Such a
monochromator object is necessary for the usage of the wavelength or energy
variables. The parameter name defines the name of the monochromator object
in the system. M1 and M2 are the names of the Theta and two Theta motors
respectively. M3 is an optional parameter defining a motor for driving the
horizontal curvature. M4 is an optional parameter defining a motor for
driving the vertical curvature of the monochromator.
<DT>InitToken tokenpassword
<DD> This command initialises the token control management system with the
token command. The single parameter tokenpassword specifies the password for
the token force command.
<DT>MakeHKL theta omega chi phi
<DD>MakeHKL creates the hkl command for the calculation of settings for a four
circle diffractometer. The four parameters are the names of the motors
driving the two theta, omega, chi and phi circles of the diffractometer.
These motors must already exists before this command may succeed.
<DT>MakeDifrac tth om chi phi cter
<DD>This command installs the Difrac subsystem into SICS. Difrac is a
whole F77 package for controlling a four circle
diffractometer. Afterwards Difrac commands are available in SICS with
the prefix dif, for example dif ah calls the difrac ah command. Difrac
is described in more detail elsewhere. The parameters are the four
circle motors two theta, omega, chi and phi and the counter.
<DT>MakeOptimise name countername
<DD>This command installs the Peak Optimiser into the SICS server. The Peak
Optimiser is an object which can locate the maximum of a peak with respect
to several variables. The arguments are: name, the name under which the Peak
Optimiser can be accessed within SICS and countername, which is the name of
an already configured SICS counter box.
<DT>MakeTRICSNEXUS datanumber fileroot dictionaryfile
<DD>MakeTRICSNEXUS creates the object for writing TRICS NeXus files. This
command creates a new command with the name nexus which is is used for
interacting with this object. MakeTRICSNEXUS expects three parameters: The
first one is the name of a data number object used for automatic data file
name creation. The second is the full pathname to the directory where the
dat should go. The third one is the full path name of the NXDICT dictionary
file to use for positioning data in the NeXus file. Besides these explicit
parameter the nexus object relies on the presence of a plethora of other
objects in the system. The MakeTRICSNEXUS command should be at the end of
the file.
<DT>MakeAmor2T name da
<DD>This creates a virtual two theta motor for the reflectometer
AMOR. The two parameters are the name of the object in SICS and a
Tcl-array with configuration parameters. The needed elements of this
array are:
<DL>
<DT>mom
<DD>The monochromator omega motor.
<DT>som
<DD>The sample omega motor.
<DT>coz
<DD> The height movement of the detector.
<DT>cox
<DD> The movement of the detector along the optical bench.
<DT>stz
<DD> The height movement of the sample connected to the omega circle.
<DT>soz
<DD> The height movement of the sample table.
<DT>d4b
<DD>The motor moving the whole diaphragm 4 up.
<DT>d5b
<DD>The motor moving the whole diaphragm 5 up.
<DT>com
<DD>The omega mevement of the detector.
</DL>
An example:
<pre>
set a2t(mom) mom
set a2t(som) som
set a2t(coz) coz
set a2t(cox) cox
set a2t(stz) stz
set a2t(soz) soz
set a2t(d4b) d4b
set a2t(d5b) d5b
set a2t(com) com
MakeAmor2T a2t a2t
</pre>
creates a virtual AMOR two theta motor with the name a2t.
<dt>MakeStoreAmor hm
<dd>Creates an object for writing reflectometer data files. The name
of the command is storeamor. The parameter hm denotes the histogram
memory object.
<dt>MakeAmorStatus name scan hm
<dd>This creates a helper object for the reflectometer status display
with name name. This object performs some operations on behalf of the
status display for the reflectometer AMOR. The parameter scan denotes
the name of the scan object. The parameter hm the name of the
histogram memory object.
<DT>MakeMesure name scanobject hklobject omega o2t fileroot datanumberobject
<DD>MakeMesure installs the single counter four circle diffractometer
measurement procedure into SICS. It will be accessible as object name
afterwards. MakeMesure takes a lot of parameters:
<dl>
<Dt>scanobject
<DD>The name of the internal scan object.
<DT>hklobject
<DD>The name of the object which does crystallographic calculations.
<DT>omega
<DD>The name of the motor driving omega.
<DT>o2t
<DD>The name of the omega two theta virtual motor for omega two theta scans.
<DT>fileroot
<DD>The full path to the data file directory without final /
<dt>datanumberobject
<DD>The name of the SICS data number object for creating unique file
numbers.
</dl>
<DT>MakeSANSWave name velo_name
<DD>> Installs a velocity selector wavelength variable into SICS. The
variable will have the name given as first parameter. Usually lambda is a
good idea. The second parameter, velo_name, is the name of the velocity
selector which is controlled by this wavelength variable.
<DT>MakeHklscan scan hkl
<DD>Installs a command named hklscan which allows scans in reciprocal space
expressed as Miller Indizes on a four circle diffractometer. scan must be
the name of a scan object as created by MakeScanCommand. hkl is the name of
a hkl calculation object as created by makeHKL.
<dT>MakeXYTable myname
<DD>Creates a XYTable object with the name myname. This object can store a
list of x-y values.
</DL>
</p>
<h4>The Scan Command Header Description File</h4>
<p>
The SICS internal scan command allows to configure the contents of the header of
the ASCII scan data file through a template header file. This section describes
the contents of this file. This header description file consists of normal
text mixed with a few special keywords. The normal test will be copied to
output verbatim. The keywords indicate that their place will be replaced by
values at run time. Currently only one keyword per line is supported.
Keywords recognized are:
<DL>
<DT>!!DATE!!
<DD>Will be replaced with the file creation date.
<DT>!!VAR(name)!!
<DD>Will be replaced with the value of the SICS variable name.
<DT>!!DRIV(name)!!
<DD>Will be replaced with the value drivable variable name. Drivable variables are
all motors and all variables which may be used in a drive or run command.
<DT>!!ZERO(name)!!
<DD>Will be replaced with the value of the softzero point for motor name.
<DT>!!FILE!!
<DD>Will be replaced by the creation name of the file.
</DL>
Please note that text behind such a keyword in the line will not be copied to
the output.
</p>
</body>
</html>

18
doc/manager/cron.htm Normal file
View File

@ -0,0 +1,18 @@
<HTML>
<HEAD>
<TITLE>Reoccuring Tasks</TITLE>
</HEAD>
<BODY>
<H1>Reoccuring Tasks</H1>
<P>
Sometimes it may be necessary to execute a SICS command at regular
time intervalls. This can be achieved with the sicscron command:
<DL>
<DT>sicscron intervall bla blab blab
<DD>This command installs a reoccuring task into SICS. The first
parameter is the intervall in seconds between calls to the SICS
command. Everything behind that is treated as the command to execute.
</DL>
</P>
</BODY>
</HTML>

190
doc/manager/hwini.htm Normal file
View File

@ -0,0 +1,190 @@
<html>
<head>
<title> SICS Hardware Configuration</title>
</head>
<body>
<h2>SICS Hardware Configuration</h2>
<p>
Hardware is configured into the SICS system by executing special hardware
configuration commands from the server initialisation file. These commands
are described here. Much SICS hardware is hooked up to the system via RS-232
interfaces. The SICS server communicates with such devices through a serial
port server program running on a Macintosh PC. All such devices require on
initialisation the following parameters:
<ul>
<li><b>hostname</b> The name of the macintosh computer.
<li><b>port</b> The port number where the serial port server program is
listening for requests. It is given on the Macintosh screen when the serial
port server is running. It is usually 4000.
<li><b>channel</b> The number of the RS-232 interface on the Macintosh. 0 is
the standard Macintosh modem port, 1 is the standard Macintosh printer port,
2 is the first connector on the interface extension box. This leads to much
confusion which can be healed with a simple rule: If a device is connected
to the Macintosh serial port extension box, then its channel number is the
interface number on the box plus one.
</ul>
</p>
<h3> Motors</h3>
<p>
The following commands are available to install motors into the system:
<DL>
<DT> Motor name SIM lowlim uplim err speed
<DD> This command creates a simulated
motor with the lower limits lowlim, the upper limit uplim, an ratio of
randomly generated errors err and a driving speed of speed. Use this for
testing and instrument simulation.
<DT>Motor name EL734 host port chan no
<DD>This command creates a stepper motor named name which is controlled through a
El734 motor controller. The
parameters host, port, chan have the meanings defined above. no is the
number of the motor in the EL734 motor controller.
<DT>Motor name EL734DC host port chan no
<DD>This command creates an analog motor named name which is controlled through a
El734DC motor controller. The
parameters host, port, chan have the meanings defined above. no is the
number of the motor in the EL734DC motor controller.
</DL>
</p>
<h3>Counting Devices</h3>
<p>
<DL>
<DT>MakeCounter name SIM
<DD>This command creates a simulated single counter
accessible as object name.
<DT>MakeCounter name EL737 host port chan
<DD>This command creates a single
counter name, using an EL737 driver. The counter is at host host, listening
at port port and sits at serial port chan.
</DL>
</p>
<h4>Histogram Memory</h4>
<p>
Due to the large amount of parameters, histogram memories are configured
differently. A histogram memory object is created using a special
creation command. This command is described below. Then a lot of options need to
be configured. The commands used for setting these options and their meanings
are defined in the <a href =
../user/histogram.htm> user </a> documentation because histogram memories
may be reconfigured at runtime. The sequence of configuartion options is
ended with the command hmname init. This last command actually initialises the
HM. Histogram memory objects can be created using the command:
<DL>
<DT> MakeHM name type
<DD> The parameter name specifies the name under which the HM will be
avialable in the system. type specifies which type of driver to use.
Currently two types of drivers are supported: SIM for a simulated HM and
SINQHM for the SINQ histogram memory. Please care to note, that the SINQHM
requires a EL737 counter box for count control. This counter must have been
defined before creating the HM object.
</DL>
As an example the configuration of a SINQHM HM with the name banana will be
shown:
<pre>
MakeHM banana SINQHM
banana configure HistMode Normal
banana configure OverFlowMode Ceil
banana configure Rank 1
banana configure Length 400
banana configure BinWidth 4
banana preset 100.
banana CountMode Timer
banana configure HMComputer psds04.psi.ch
banana configure HMPort 2400
banana configure Counter counter
banana init
</pre>
</p>
<h3>Velocity Selectors</h3>
<p>
A velocity selector is configured in a three step process. First a Tcl array
is filled with the necessary configuration options for the actual velocity
selector driver. In a second step the
velocity selector is created with a special command. In a third step the
forbidden regions for the velocity selector are defined. Currently two
drivers for velocity selctors are known: a SIM driver for a simulated
velocity selector and a DORNIER driver for a Dornier velocity selector
hooked to a SINQ serial port setup. The last one needs a parameter array
containing the fields Host, Port, Channel and Timeout. Host, Port and
Channel have the meanings as defined at the very top of this section.
Timeout is the maximum time to wait for responses from the velocity selector.
A large value is required as the dornier velocity selector is very slow.
The second step is performed through the following commands:
<DL>
<DT>VelocitySelector name tilt-motor SIM
<DD> This command installs a simulated velocity selector with the name name
into the system. tilt-motor is used for driving the tilt angle of the
selector. tilt-motor must exist before this command can be executed
successfully.
<DT>VelocitySelector name tilt-motor DORNIER arrayname
<DD> This command installs a dornier velocity selector into the system. name
and tilt-motor have the same meanings as described above. arrayname is the
Tcl-array with the driver configuration parameters.
</DL>
As an example the configuration of a dornier velocity selector named
nvs is shown:
<pre>
set dornen(Host) lnsp25.psi.ch
set dornen(Port) 4000
set dornen(Channel) 6
set dornen(Timeout) 5000
VelocitySelector nvs tilt DORNIER dornen
nvs add -20 28800
nvs add 3800 4500
nvs add 5900 6700
nvs add 8100 9600
</pre>
</p>
<h3>Chopper</h3>
<p>
Chopper systems are handled via a generic controller object. This basicly
consists of two components: One object represents the actual
controller. This basic object allows to query parameters only. Then
there is for each parameter which can be controlled from SICS in this
controller an adapter object. These adapter object are virtual motors
which can be driven with the normal run or drive commands. Currently
two drivers for this scheme exists: one for a simulated device, the
other for the Dornier Chopper Controller at FOCUS. The first step when
initializing this system is the installation of the general controller
object into SICS. This is done with the commands:
<pre>
MakeChopper name sim
MakeChopper name docho mac port channel
</pre>
The first command simply installs a simulated controller.
The second command install a controller with a driver for the FOCUS
Dornier Chopper system. Mac, port and channel are the usual Macintosh
terminal server parameters which describe where the chopper controller
is connected to through its RS-232 interface. After both commands the
controller is available as command name within SICS.
</p>
<p>
A drivable parameter at this controller is installed with a command
similar to this:
<pre>
ChopperAdapter vname cname pname lower upper
</pre>
vname is the name under which the virtual motor will appear in
SICS. cname is the name of the controller object installed into SICS
with the commands in the previous paragraph. pname is the name of the
drivable parameter in the controller. upper and lower are the upper
and lower limits for this parameter. More then one of these commands
can be given for each general controller.
</p>
<p>
After this, the parameter can be modified by a command like:
<pre>
drive vname newvalue
</pre>
</p><p>
To be expanded. Please note, that environment devices such as temperature
controllers are dynamically configured into the system at run time.
Therefore the necessary commands are described in the user documentation.
</body>
</html>

39
doc/manager/ini.htm Normal file
View File

@ -0,0 +1,39 @@
<html>
<head>
<title> Overview of SICS Initialization </title>
</head>
<body>
<h2>Overview of SICS Initialization</h2>
<p>
The command to start the SICServer is: <b> SICServer inifile </b>. So, what
happens at the initialization of the SICS server? First, internally, a set
of standard SICS commands is initialized, than a set of special
initialization commands. These are special commands which help to configure
the SICS server to match the actual hardware present on the hall floor and
to define the commands available later on. Following this, the SICS server
will read the initialization file specified on the command line or servo.tcl
as a default. Using the data supplied in this file, the server will be
configured. At this stage all special initialization commands, all
Tcl-mechanisms and all SICS commands already initialized are available.
After this is done, the server will delete the initialisation commands from
its internal command list (No need to carry them around all the time). Now a
status backup file will be read. This file contains normal SICS statements
which initialise parameter values to the values they had before the last
shutdown of the server. Such a file is automatically written whenever a
normal shutdown of the server happens.
</p>
<p>
The SICS server configuration file is essentially a SICS macro language
file. This implies that all general SICS commands and Tcl mechanisms are
available. Additionally the configuration file (and only the configuration
file) may use special commands for the installation of:
<ul>
<li>SICS server options.
<LI>SICS variables.
<LI>Special commands.
<LI>Hardware
</ul>
</p>
</body>
</html>

26
doc/manager/inifile.htm Normal file
View File

@ -0,0 +1,26 @@
<HTML>
<HEAD>
<TITLE>SICS Xerver Configuration</TITLE>
</HEAD>
<BODY>
<H1>SICS Server Configuration</H1>
<P>
There is only one executable image of the SICS server for all instruments. The
commands and hardware available for a particular instrument is defined
through the instrument initialisation file. The contents of this file are
described below.
</P>
<!latex-off>
<p>
Go to:
<ul>
<li> An <a href = ini.htm> Overview </a> about SICS initialisation.
<li> A description of SICS <a href = option.htm>options</a>.
<li> A discussion of SICS <a href = var.htm> variables</a>.
<li> Advice about <a href=hwini.htm> hardware </a> configuration.
<li> A description of <a href = command.htm> command </a> initialisation.
</ul>
</p>
<!latex-on>
</BODY>
</HTML>

116
doc/manager/iscan.htm Normal file
View File

@ -0,0 +1,116 @@
<HTML>
<HEAD>
<TITLE>The Internal Scan Command</TITLE>
</HEAD>
<BODY>
<H1>The Internal Scan Command</H1>
<P>
Scans are preformed from a variety of commands in SICS. All these commands
are just Tcl--wrappers around an internal scan object implemented in C. This
section describes this internal scan command and how it works. This internal
scan command is installed into the SICS server via the <a href=command.htm>MakeScanCommand
command</a> in the initialisation file. This command install the internal
scan object under a user defined name. For the rest of this document it is
assumed that this name is xxscan.
</P>
The scan object (named here xxscan, but may have another name) understands
the following commands:
<DL>
<DT>xxscan add name start step
<DD>This command adds the variable specified by the argument name to the
list of variables scanned in the next scan. The arguments start and step
define the starting point and the sptep width for the scan on this variable.
<DT>xxscan clear
<DD>clears the list of scan variables. Must be called before each scan with
different parameters.
<DT>xxscan run NP mode preset
<DD>Executes a scan. The arguments are: NP the number of scan points, mode
the counter mode to use (this can be either timer or monitor) and preset
which is the preset value for the counter. Scan data is written to an output
file.
<DT>xxscan silent NP mode preset
<DD>Executes a scan. The arguments are: NP the number of scan points, mode
the counter mode to use (this can be either timer or monitor) and preset
which is the preset value for the counter. The difference to run is, that
this scan does not produce an output file.
<DT>xxscan recover
<DD>Recovers an aborted scan. The scan object writes a file with all data
necessary to continue the scan after each scan point. If for some reason a
scan has been aborted due to user intervention or a system failure, this
scheme allows to continue the scan when everything is alright again. This
works only if the scan has been started with run, not with silent.
<DT>xxscan getfile
<DD>This command retuns the name of the current data file.
<DT>xxscan setchannel n
<DD>Sometimes it is required to scan not the counter but a monitor. This
command sets the channel to collect data from. The argument n is an integer
ID for the channel to use.
<DT>xxscan getcounts
<DD>Retrieves the counst collected during the scan.
<DT>xxscan getvardata n
<DD>This command retrieves the values of a scan variable during the scan
(the x axis). The argument n is the ID of the scan variable to retrieve data
for. ID is 0 for the first scan variable added, 1 for the second etc.
<DT>xxscan interest
<DD>A SICS client can be automatically notified about scan progress. This is
switched on with this command. Three types of messages are sent: A string
NewScan on start of the scan, a string ScanEnd after the scan has finished
and a string scan.Counts = {109292 8377 ...} with the scan values after each
finished scan point.
<DT>xxscan uninterest
<DD> Uninterest switches automatic notification about scan progress off.
<DT>xxscan integrate
<DD> Calculates the integrated intensity of the peak and the variance of teh
intensity for the last scan. Returns either an error, when insufficient scan
data is available or a pair of numbers. Peak integration is performed along
the method described by Grant and Gabe in J. Appl. Cryst. (1978), 11,
114-120.
<DT>xxscan window [newval]
<DD>Peak Integration uses a window in order to determine if it is still in the
peak or in background. This command allows to request the size of this
window (without argument) or set it (with argument giving the new window
size).
<DT>xxscan simscan pos FWHM height
<DD>This is a debugging command. It simulates scan data with a hundred
points between an x axis ranging from 10 to 20. A gauss peak is produced
from the arguments given: pos denotes the position of the peak maximum, FWHM
is the full width at half maximum for the peak and height is its height.
<DT>xxscan command tclcommand
<DD>Sets the tcl command procedure to invoke at each scan point. See below
for the description of user defined scans. Invoked without argument command
returns the name of the current command procedure.
<dt>xxscan configure mode
<dd>Confugures the several possible scan modes for the scan
object. Currently there are two:
<ul>
<li><b>standard</b>, the default mode writing ASCII files.
<li><b>amor</b>, a special mode the reflectometer AMOR which writes
NeXus files.
</ul>
</DL>
</P>
<p>
<h2>User Defined Scans</h2>
In some cases users wish to exert more influence about the scan. Especially
about what gets counted. In order to cater for this a hook was implemented
in the internal scan command. This hook allows to run a tcl procedure at each
scan point. This Tcl procedure is required to return a string containing
up to 11 values for counters and monitors. The first value will be the one
used as counts in the data file. The others will be placed as monitors.
Please note, that only the first three monitors are written to file as of
current. In order to use this facility the following steps are required:
<ol>
<li>Write The Tcl-macro procedure to run. Make sure that is creates proper
output.
<li>Test the Tcl-procedure in SICS.
<li>Install the Tcl-procedure into the scan object with the
xxscan command name syntax.
<li>Make the scan command use the Tcl procedure by setting channel to -10 with
the xxscan setchannel -10 command.
</ol>
A hint: If you need to control the counting operation as well (because you
are not using a counter to count) just run the scan object with a very low
preset and do the counting yourself in your procedure.
</p>
</BODY>
</HTML>

9
doc/manager/keepalive Executable file
View File

@ -0,0 +1,9 @@
#!/usr/bin/ksh
#---------------------------------------------------------------------------
# script starts a program and restarts it whenever it dies.
#
# Mark Koennecke, Juli 1998
#--------------------------------------------------------------------------
while true; do
$1
done

82
doc/manager/macroman.htm Normal file
View File

@ -0,0 +1,82 @@
<HTML>
<HEAD>
<TITLE>Programming SICS Macros</TITLE>
</HEAD>
<BODY>
<H2>Programming SICS Macros</H2>
<P>
The SICS server has a built in macro language. This macro language is basically
John Ousterhout's Tool Command Language Tcl. Tcl is described elsewhere.
A sound knowledge of Tcl is required for programming SICS macros. The SICS macro
language can be used for the following purposes:
<UL>
<li>Add hoc measurement procedures.
<LI>Trial measurement procedures.
<LI>Syntax adaptions to one's own favourite syntax.
<LI>Building of cmore complex commands from the SICS primitives.
</ul>
The general procedure for defining a macro requires defining the macro in a new
file, source this file from the configuration script and the use of the Publish
command to make it available. New commands can best be defined as Tcl procedures,
but the obTcl object oriented extension to Tcl is known to work as well. The SICS
macro language allows to access:
<ul>
<li>Most Tcl commands.
<li>All SICS commands.
</ul>
In the following sections a few pecularities of the SICS macro system will be
discussed.
</P>
<h3>Input/Output</h3>
<p>
It would be quite verbose and confusing for the user if all output from SICS
commands called from a macro would appear on the screen during macro execution.
Therefore all
normal SICS output to a client is suppressed while executing a macro. Except
error messages and warnings which will always be written to the
client executing the macro. The output of a SICS command is available within the
macro script through the normal Tcl mechanism as a return value. This allows for
processing of SICS output within a macro. If the output to the client executing
the macro is required this can be done with the ClientPut command, detailed in the
user documantation.
</p>
<h3>Error Handling</h3>
<p>
Tcl has the feature that it aborts execution of a script when an error occurs.
If a macro script needs to handle errors either from Tcl or from SICS commands
this can be achieved by using the Tcl catch mechanism. A script can inquire the current interrupt value of the
connection with the command <b>GetInt</b>. If a script can handle an error condition
it may set the interrupt on the connection object with the <b>SetInt</b> command.
The textual representations of interrupts for these commands are:
continue, abortop, abortscan, abortbatch, halt, free, end.
</p>
<h3>Interacting with SICS within a Script</h3>
<p>
There exist a few commands which allow to inquire or manipulate SICS
internals. Most of these commands are only available in macro scripts.
<DL>
<DT>SICSType thing.
<DD> SICSType lets SICS find out if thing has some meaning within SICS. Possible return
values are: DRIV for a drivable variable, COM for a SICS command, NUM for a numeric
value and TEXT for anything else.
<DT>SICSBounds var newval
<DD>SICSBounds checks if newval violates the hardware or software limits of
the variable var.
<DT>SetStatus newval
<DD>SetStatus sets the SICS status line to a new value. Possible values for
newval are: Eager, UserWait, Count, NoBeam, Paused, Driving, Running,
Scanning, Batch, Halt, Dead.
<DT>SICSStatus var
<DD>SICSStatus returns a integer value representing the current status of
the object var. var must be a drivable or countable object. The integer code returned
are defined in the SICS programmers documentation.
</DL>
</p>
<p>
Currently it is not possible to define object interfaces from within the SICS
macro language. For the notion of object interfaces see the
SICS programmers documentation. This may be implemented in future when needed.
</p>
</BODY>
</HTML>

49
doc/manager/manager.htm Normal file
View File

@ -0,0 +1,49 @@
<html>
<head>
<title> SICS-Manager documentation </title>
</head>
<body>
<h1>SICS Manager Documentation</h1>
<hr size=4 width="66%">
<p ALIGN=CENTER>
Mark K&ouml;nnecke
</p>
<p ALIGN=CENTER>
Labor f&#252;r Neutronenstreuung
</p>
<p ALIGN=CENTER>
Paul Scherrer Institut
</p>
<p ALIGN=CENTER>
CH-5232 Villigen-PSI
</p>
<p ALIGN=CENTER>
Switzerland
</p>
<p>
This document describes the general setup of SICS, the configuration of the
SICS server and its clients and the writing of macros in the
SICS macro language. This document is aimed at SICS system managers and
instrument scientists. This document requires that the SICS user documentation
has been read and understood beforehand. For writing macros it is essential
to understand John Ousterhouts Tool Command Language,
which is described elsewhere.
</p>
<!latex-off>
<p>
Where to you want to go today?
<ul>
<li> To the general <a href =setup.htm> setup</a> section.
<Li> To the <a href = inifile.htm> server initialision</a> section.
<li> To the <a href = client.htm>client </a> configuration section.
<li> To the section describing <a href=special.htm>special commands</a> for
SICS administrators or programmers.
<li> Commands for <a href=status.htm>status display</a> support.
<li> To the <a href="macroman.htm">macro</a> programming section.
<LI> <a href = trouble.htm>Troubleshooting</a> hints.
<Li> Hints for <a href = "move.htm">moving</a> the SICS server or for Exchanging the serial port server.
</ul>
</p>
<!latex-on>
</body>
</html>

59
doc/manager/managerman Normal file
View File

@ -0,0 +1,59 @@
\documentclass[12pt,a4paper]{report}
%%\usepackage[dvips]{graphics}
%%\usepackage{epsf}
\setlength{\textheight}{24cm}
\setlength{\textwidth}{16cm}
\setlength{\headheight}{0cm}
\setlength{\headsep}{0cm}
\setlength{\topmargin}{0cm}
\setlength{\oddsidemargin}{0cm}
\setlength{\evensidemargin}{0cm}
\setlength{\hoffset}{0cm}
\setlength{\marginparwidth}{0cm}
\begin{document}
%html -d hr " "
%html -s report
\begin{center}
\begin{huge}
SICS--Managers--Manual \\
\end{huge}
Version 1.0, October,1997\\
Dr. Mark K\"onnecke \\
Labor f\"ur Neutronenstreuung\\
Paul Scherrer Institut\\
CH--5232 Villigen--PSI\\
Switzerland\\
\end{center}
\clearpage
\tableofcontents
\clearpage
\chapter{Introduction}
This document describes the general setup of SICS, the configuration of the
SICS server and its clients and the writing of macros in the
SICS macro language. This document is aimed at SICS system managers and
instrument scientists. This document requires that the SICS user
documentation
has been read and understood beforehand. For writing macros it is essential
to understand John Ousterhouts Tool Command Language,
which is described elsewhere.
%html setup.htm 1
%html inifile.htm 1
%html ini.htm 1
%html option.htm 1
%html var.htm 1
%html hwini.htm 1
%html command.htm 1
%html special.htm 1
%html serial.htm 2
%html status.htm 2
%html sps.htm 2
%html iscan.htm 2
%html alias.htm 2
%html cron.htm 2
%html client.htm 1
%html ../user/trouble.htm 1
%html move.htm 1
\end{document}

64
doc/manager/motor.tex Normal file
View File

@ -0,0 +1,64 @@
\documentclass[12pt,a4paper]{article}
%%\usepackage[dvips]{graphics}
%%\usepackage{epsf}
\setlength{\textheight}{24cm}
\setlength{\textwidth}{16cm}
\setlength{\headheight}{0cm}
\setlength{\headsep}{0cm}
\setlength{\topmargin}{0cm}
\setlength{\oddsidemargin}{0cm}
\setlength{\evensidemargin}{0cm}
\setlength{\hoffset}{0cm}
\setlength{\marginparwidth}{0cm}
\parskip .5cm
\begin{document}
\begin{center}
\begin{huge}
Saving EL734 Motor Parameters on Unix
\end{huge}
16-October-1998\\
\end{center}
EL734 motor controllers occasionally loose their built in parameters.
Therefore it is necessary to save their parameters and to have a way to load
them to the motor controller when need arises. This can be done with
David Maden's EL734\_test
program. This program has now been made available on DigitalUnix. For each
SICS instrument motor parameters are stored at two independent locations:
\begin{itemize}
\item In the motor directory of the instrument account. For example:
/home/DMC/motor
\item On lnsa10 in the lnslib account in a motor/instrument directory. For
example: /data/lnslib/motor/dmc
\end{itemize}
In each of these directories there is an instrument specific shell script
which does the job. It has a name such as instrumentmotor, for example
dmcmotor . This shell script expects one argument which must be one of the
keywords load or save. With the option save specified motor parameters are
read from the controller and stored into files. With the option load the
stored motor parameters are loaded into the motor controller. Thus the
procedure for saving and restoring motor parameters becomes:
\begin{enumerate}
\item change to the directory with the motor parameters
(/home/INSTRUMENT/motor or /data/lnslib/motor/instrument).
\item type: instrumentmotor save for saving motor parameters to disk.
\item type instrumentmotor load for loading motor parameters to the
controller.
\end{enumerate}
\begin{Large}
It is the instrument scientists responsability to save motor parameters to
disk after changes to both locations.
\end{Large}
In order to make this more interesting, files at lnsa10 are write protected.
In order to overwrite those you need to use the unix command chmod.
Saving motor parameters generates files with names like motNUM1@NUM2.par
with NUM1, NUM2 being numbers. This means: motor number NUM1 at EL734 motor
controller at Macintosh channel NUM2. These files can be edited when you
know what you are doing. The command syntax is described in the El734 motor
controller manual.
\end{document}

59
doc/manager/move.htm Normal file
View File

@ -0,0 +1,59 @@
<HTML>
<HEAD>
<TITLE>Moving SICS</TITLE>
</HEAD>
<BODY>
<H1>Moving SICS</H1>
<H2> Moving the SICS Server to a new Computer</h2>
<P>
Moving the SICS server from one computer to another involves quite a
few steps:
<OL>
<LI>Recreate the directory structure on the new computer.
<LI>Copy all necessary files across:
<ul>
<li> A copy of the SICServer.
<li> A copy of the instrument configuration file.
<li> All macro scripts used by this instrument.
<li> The DataNumber file.
<li> The necessary data file dictionary or header description files.
<li> The client programs.
</ul>
All necessary files should be available from backup or under the
/data/lnslib/sics/instrument tree on lnsa10.
<LI>Edit the instrument configuration file and make all pathnames reflect the
new directory structure. It should be enough to adapt the home variable at the
top, but better check. All paths references must be renewed if the directory
structure is changed from the one described <a href = "setup.htm">above</a>.
<LI>Edit the client scripts to reflect the new location of the server. Only the
box and logpath parameters should need to be changed.
<LI> Edit the DataNumber file and set the number above the last valid data file
number used. Otherwise the automatic numbering scheme
for data files gets messed up.
<LI>Test the new Installation!
</OL>
</P>
<h2>Exchanging the Macintosh Serial Port Server</h2>
<p>In its current configuration at SINQ, SICS requires a Macintosh PC running a serial
port server program. Exchanging this Macintosh requires the following steps:
<OL>
<LI>Exchange the Macintosh physically. Plug everything as it was before the
exchange. Not every Macintosh can be used. Any other Macintosh from another
instrument or the spare Macintosh from the EDV-cabin will do. Other
Macintoshs require some serious screwing and software installation
procedures.
<LI>Edit the instrument configuration file and replace all references to the name of
the old Macintosh PC with the name of the new Macintosh PC.
<LI>Test it!
</OL>
If you do not plug the serial devices back onto the Macintosh as they were, you
need to adapt the channel numbers in the configuration file as well. The standard
plugging scheme for the serial port extension box on the Macintosh is like this:
<OL>
<LI>Motor Controller 1
<LI>Motor Controller 2
<LI>Counter Box
</OL>
</p>
</BODY>
</HTML>

82
doc/manager/mug Normal file
View File

@ -0,0 +1,82 @@
\documentclass[12pt,a4paper]{article}
%%\usepackage[dvips]{graphics}
%%\usepackage{epsf}
\setlength{\textheight}{24cm}
\setlength{\textwidth}{16cm}
\setlength{\headheight}{0cm}
\setlength{\headsep}{0cm}
\setlength{\topmargin}{0cm}
\setlength{\oddsidemargin}{0cm}
\setlength{\evensidemargin}{0cm}
\setlength{\hoffset}{0cm}
\setlength{\marginparwidth}{0cm}
\parskip .5cm
\begin{document}
%html -d hr " "
%html -s article
\begin{center}
\begin{huge}
Notes To SICS Instrument Scientists\\
\end{huge}
3-Juli-1998\\
\end{center}
%html ../user/sicsinvoc.htm
%html sicsnews.htm
\section{User Names and Passwords}
\begin{itemize}
\item All instruments have know an account {\bf lnsuser 98lns2} with user
privilege.
\item Manager passwords are:
\begin{itemize}
\item TOPSI: Mugger Daniel
\item DMC: Manager Lucas
\item SANS: Manager Joachim
\end{itemize}
User names and passwords can be changed by editing the instrument
configuration file.
\end{itemize}
\section{SICS on the WWW}
\subsection{Client access}
Following decisions made at a recent SICS user meeting, SICS clients are
made avaialable on the WWW. Access is restricted to the PSI domain. A
username and a password is needed in order to access the clients. This is
currently set to: sinquser 98sinq2.
The URL's for the clients are:
\begin{description}
\item[Command Line Client]http://lns00.psi.ch/sics/client/sicsclient.html
\item[DMC Status]http://lns00.psi.ch/sics/client/powderstatus.html
\item[TOPSI Status]http://lns00.psi.ch/sics/client/topsistatus.html
\item[SANS Status]http://lns00.psi.ch/sics/client/sansstatus.html
\end{description}
\subsection{Documentation}
All SICS User documentation is accessible at:\\
http://lns00.psi.ch/sics/index.html \\
Postscript versions of the SICS user
documentation inhabit the doc directory of your instrument account.
The SICS manager documentation is also available on WWW. URL:\\
http://lns00.psi.ch/sics/manager/manager.htm \\Access
to this directory is
restricted to the psi.ch domain. A username and password must be given in
order to be given access to these pages. These values are currently set to:
bigboss DJLmanager (can be remembered as: Daniel, Joachim, Lukas manager).
There is now a WWW document which informs about new SICS features, bug fixes
etc. This is available at:\\
http://lns00.psi.ch/sics/manager/sicsnews.htm \\
The same access restrictions as given for the manager documentation above
apply.
Installation instructions for SICS clients on PC's can be found at:\\
http://lns00.psi.ch/sics/cliinst.htm\\
Currently only real PC's are covered,
but instructions for Mac's will follow some day or another. Any volunteers?
\end{document}

173
doc/manager/mug.tex Normal file
View File

@ -0,0 +1,173 @@
\documentclass[12pt,a4paper]{article}
%%\usepackage[dvips]{graphics}
%%\usepackage{epsf}
\setlength{\textheight}{24cm}
\setlength{\textwidth}{16cm}
\setlength{\headheight}{0cm}
\setlength{\headsep}{0cm}
\setlength{\topmargin}{0cm}
\setlength{\oddsidemargin}{0cm}
\setlength{\evensidemargin}{0cm}
\setlength{\hoffset}{0cm}
\setlength{\marginparwidth}{0cm}
\parskip .5cm
\begin{document}
\begin{center}
\begin{huge}
Notes To SICS Instrument Scientists\\
\end{huge}
3-Juli-1998\\
\end{center}
% html: Beginning of file: `../user/sicsinvoc.htm'
\section{SICS Invocation}
\label{f0}
SICS is a client server system. This means there are two programs. The first
is a
SICServer which does the actual instrument control work. A user rarely needs
to bother about this server program as it is meant to run all the time.
See instructions below if things go wrong. The user has only to deal with
the SICS client programs. These implement the user interface to SICS.
SICS Clients and the SICServer communicate with each other through TCP/IP
sockets.
Currently four SICS clients are available:
\begin{itemize}
\item A command line control client which allows to control the measurement.
\item A status display for DMC.
\item A status display for TOPSI.
\item A status display for SANS.
\end{itemize}
These programs can be started on a DigitalUnix system by issuing the
following commands at the command prompt:
\begin{description}
\item[sics \&] for the control client.
\item[powderstatus \&] for the DMC status display client.
\item[topsistatus \&] for the TOPSI status display.
\item[sansstatus \&] for the SANS status display.
\end{description}
On a PC you may find icons for starting the different prograsm on the
desktop.
Each of these clients has usage instructions online which can be displayed
through the help/about menu entry.
\subsection{Connecting and Logging in}
After startup any SICS client is not connected to a SICS server and thus not
active. A connection is established through the connect menu of the client.
SICS is a multi user instrument control system. In order to prevent
malicious manipulations of the instrument SICS supports a hierarchy of user
rights. In order to run an experiment you need at least user level privilege.
In order to achieve this privilege you have to invoke the User Parameter/Set
Rights dialog. There you have to enter the apropriate username and password
kindly provided by your instrument scientist.
\subsection{Restarting the Server}
The SICS server should be running all the time. It is only down if something
went wrong. You can check for the presence of the SICS server by loging in
to the instrument computer and typing {\bf CheckSICS} at the command
prompt. The output will tell you what is happening. If you need to restart
the SICS server log in as the instrument user at the instrument computer and
invoke the apropriate command to start the server. These are:
\begin{description}
\item[DMC] Computer = lnsa05,User = DMC, Command = DMCServer
\item[TOPSI] Computer = lnsa03,User = TOPSI, Command = TOPSIServer
\item[SANS] Computer = lnsa07,User = SANS, Command = SANSServer
\end{description}
If all this does not help look under trouble shooting
SICS.
% html: End of file: `../user/sicsinvoc.htm'
% html: Beginning of file: `sicsnews.htm'
\section{SICS News Ticker}
\label{f2}
This page contains information about the latest bug fixes, releases and other
miscellaneous information about SICS.
\subsection{Juli 1998}
\begin{description}
\item[Status OutOfMemory] Bug in status display clients fixed which caused OutOfMemory after
some time of automatic update.
\item[topsistatus ] TOPSI has got a java status client now as well. Can be invoked with
{\bf topsistatus}. On the WWW also.
\item[commandlog] On popular demand the SICS server can now write a log file which logs all
communication between clients with user or manager privilege and the SICserver.
This log is off by default. There is a new SICS command
commandlog which serves to configure this log.
\item[8-fold counterboxes.] SICS now reads all eight monitors.
\item[sicsinstall] There is now a shell script which automatizes updating and installing SICS. For more
information see the setup section of the SICS managers guide.
\end{description}
% html: End of file: `sicsnews.htm'
\section{User Names and Passwords}
\begin{itemize}
\item All instruments have know an account {\bf lnsuser 98lns2} with user
privilege.
\item Manager passwords are:
\begin{itemize}
\item TOPSI: Mugger Daniel
\item DMC: Manager Lucas
\item SANS: Manager Joachim
\end{itemize}
User names and passwords can be changed by editing the instrument
configuration file.
\end{itemize}
\section{SICS on the WWW}
\subsection{Client access}
Following decisions made at a recent SICS user meeting, SICS clients are
made avaialable on the WWW. Access is restricted to the PSI domain. A
username and a password is needed in order to access the clients. This is
currently set to: sinquser 98sinq2.
The URL's for the clients are:
\begin{description}
\item[Command Line Client]http://lns00.psi.ch/sics/client/sicsclient.html
\item[DMC Status]http://lns00.psi.ch/sics/client/powderstatus.html
\item[TOPSI Status]http://lns00.psi.ch/sics/client/topsistatus.html
\item[SANS Status]http://lns00.psi.ch/sics/client/sansstatus.html
\end{description}
\subsection{Documentation}
All SICS User documentation is accessible at:\\
http://lns00.psi.ch/sics/index.html \\
Postscript versions of the SICS user
documentation inhabit the doc directory of your instrument account.
The SICS manager documentation is also available on WWW. URL:\\
http://lns00.psi.ch/sics/manager/manager.htm \\Access
to this directory is
restricted to the psi.ch domain. A username and password must be given in
order to be given access to these pages. These values are currently set to:
bigboss DJLmanager (can be remembered as: Daniel, Joachim, Lukas manager).
There is now a WWW document which informs about new SICS features, bug fixes
etc. This is available at:\\
http://lns00.psi.ch/sics/manager/sicsnews.htm \\
The same access restrictions as given for the manager documentation above
apply.
Installation instructions for SICS clients on PC's can be found at:\\
http://lns00.psi.ch/sics/cliinst.htm\\
Currently only real PC's are covered,
but instructions for Mac's will follow some day or another. Any volunteers?
\end{document}

86
doc/manager/mug.txt Normal file
View File

@ -0,0 +1,86 @@
SICS Invocation
SICS is a client server system. This means there are two programs. The first
is a SICServer which does the actual instrument control work. A user rarely
needs to bother about this server program as it is meant to run all the
time. See instructions below if things go wrong. The user has only to deal
with the SICS client programs. These implement the user interface to SICS.
SICS Clients and the SICServer communicate with each other through TCP/IP
sockets.
Currently four SICS clients are available:
* A command line control client which allows to control the measurement.
* A status display for DMC.
* A status display for TOPSI.
* A status display for SANS.
These programs can be started on a DigitalUnix system by issuing the
following commands at the command prompt:
sics &
for the control client.
powderstatus &
for the DMC status display client.
topsistatus &
for the TOPSI status display.
sansstatus &
for the SANS status display.
On a PC you may find icons for starting the different prograsm on the
desktop. Each of these clients has usage instructions online which can be
displayed through the help/about menu entry.
Connecting and Logging in
After startup any SICS client is not connected to a SICS server and thus not
active. A connection is established through the connect menu of the client.
SICS is a multi user instrument control system. In order to prevent
malicious manipulations of the instrument SICS supports a hierarchy of user
rights. In order to run an experiment you need at least user level
privilege. In order to achieve this privilege you have to invoke the User
Parameter/Set Rights dialog. There you have to enter the apropriate username
and password kindly provided by your instrument scientist.
Restarting the Server
The SICS server should be running all the time. It is only down if something
went wrong. You can check for the presence of the SICS server by loging in
to the instrument computer and typing CheckSICS at the command prompt. The
output will tell you what is happening. If you need to restart the SICS
server log in as the instrument user at the instrument computer and invoke
the apropriate command to start the server. These are:
DMC
Computer = lnsa05,User = DMC, Command = DMCServer
TOPSI
Computer = lnsa03,User = TOPSI, Command = TOPSIServer
SANS
Computer = lnsa07,User = SANS, Command = SANSServer
If all this does not help look under trouble shooting SICS.
SICS News Ticker
This page contains information about the latest bug fixes, releases and
other miscellaneous information about SICS.
Juli 1998
Status OutOfMemory
Bug in status display clients fixed which caused OutOfMemory after some
time of automatic update.
topsistatus
TOPSI has got a java status client now as well. Can be invoked with
topsistatus. On the WWW also.
commandlog
On popular demand the SICS server can now write a log file which logs
all communication between clients with user or manager privilege and
the SICserver. This log is off by default. There is a new SICS command
commandlog which serves to configure this log.
8-fold counterboxes.
SICS now reads all eight monitors.
sicsinstall
There is now a shell script which automatizes updating and installing
SICS. For more information see the setup section of the SICS managers
guide.

60
doc/manager/option.htm Normal file
View File

@ -0,0 +1,60 @@
<html>
<head>
<TITLE>Sics options</TITLE>
</head>
<body>
<h2>SICS Options and Users</h2>
<p>
The SICS server has an internal options database which holds such values
as port number to listen too and the like. Additionally there exists a user
database. Currently these values are configured from the initialisation
file. The commands to do this are:<ul>
<li> <b> ServerOption name value </b> defines the server option name to be
value.
<li> <b> SicsUser name password accesscode </b> defines a user with name
and password and an access right accesscode. Accesscode is an integer from 1
to 3 for User, Manager and Spy rights. A user with Spy right may look at
everything but cannot change anything. A user with user privilege may change
most of the SICS parameters, perform measurements etc. A user with manager
privilege may do everything to the system.
</ul>
The Sics server currently uses the following options:<ul>
<li> <b> ReadTimeOut </b> The server checks in each cycle of the main loop
fro pending commands. Het waits for new commands for a specific period of
time. This value is the ReadTimeOut. It should be as short as possible. This
value may need to be increased if there are network performance problems. A
good value is 100.
<li> <b> ReadUserPasswdTimeout </b> This is the time a client has to send a
username password pair after a connection request. If nothing comes in in
that time, the connection request is terminated.
<li> <b>LogFileBaseName </b> defines the path and the base name for the
server log file.
<li> <b> ServerPort </b> defines the port number the server is listening
to. Should be greater than 1024 and less than 64000. The port number should
also be different from any other server port number in use on the system.
Otherwise evil things may happen.
<li> <b> InterruptPort </b> The SICS server can handle interrupts coming in
as UDP messages on a special port. This option defines this UDP port
number. The choice of possible port numbers is limited by the constraints
given above in the ServerPort section. Espacillay this port number MUST be
different from the ServerPort number. The UDP messages accepted are expected to consist of the string
SICSINT followed by an interrupt number. For interrupt numbers see file
interrupt.h.
<li> <b> DefaultTclDirectory </b> specifies where Tcl defined commands are
stored. When this is properly defined Tcl will autoload commands.
<li> <b> StatusFile </b> defines the file to which he current state will be
saved on close down of the server and restored from at startup time.
<li><b>TelnetPort</b> The port number where the SICS server will be
listening for telnet connections. If this option is missing login via telent
to the SICS server is disabled.
<li><b>TelWord</b> In order to login to SICS via telnet a magic word is
needed. The login word, This option defines this word. If this option is
missing telnet login to SICS is disabled.
<li><b>LogFileDir</b> This server option defines the directory where
commandlog log files are kept.
</ul>
</p>
</body>
</html>

103
doc/manager/serial.htm Normal file
View File

@ -0,0 +1,103 @@
<HTML>
<HEAD>
<TITLE>Accessing Macintosh Serial Ports</TITLE>
</HEAD>
<BODY>
<H1>Accessing Macintosh Serial Ports</H1>
<P>
Occasionally, it may be necessary to access the serial ports of the Macintosh PC
directly in order to give commands to the motor controller, counter box or any
device directly. Furthermore such a faclility is useful for coding
environment device drivers in the SICS server macro language. The implementation
of serial port access is highly SINQ specific and relies on the SINQ hardware
concept. Besides, serial port access is realized in a different
way then usual SICS objects. Usually SICS objects live in the SICS interpreter.
Serial port access is implemented as an extension to the Tcl macro language.
Essentially this is the same implementation as used in the psish.
This section describes how to use serial port access. Several steps have to be performed:
<ol>
<li>Install the serialport command into the SICS server. This requires two lines to be added to
the server startup script:
<ul>
<li>SerialInit
<li>TclPublish serialport UserRights
</ul>
Where UserRights stands for one of the possible SICS user rights. See documentation
for TclPublish above.
<li> Each separate serial port will be represented by a name in the SICS server
after it has been initialized. This name is also a command. These port names live
in the Tcl interpreter and must be made accessible with TclPublish. For example for
a port named p1 include this line in the server startup script:
<ul>
<li>TclPublish p1 User
</ul>
Replace User with the correct access code you want for a serial port. It is recommended
to restrict serial port access to SICS managers only.
<li> After starting the SICS server the command serialport is now available.
<li> Now a serial port can be initialized with a command like this:
<ul>
<li>serialport name1 macintosh.name port channel force
<li>Example: serialport p1 lnsp20.psi.ch 4000 5
</ul>
Such a command creates the command name1 and links it with serial port channel
channel on the Macintosh-PC macintosh.name. Port is the port number on which the
Macintosh serial port server is listening for connections (usually 4000).
The last flag force is optional. If something is there, the connection to that
port is done on a separate socket of its own. This has to do with some
feature of the software interface to the Macintosh serial port server. This
software interface tries to direct messages for multiple channels through one
socket connection between the host and the Macintosh server. This is perfectly
fine as long as none of the commands through this socket takes a long time
to execute. However, if a RS-232 device takes a long time to respond, the whole
socket is blocked. Fortunately, the Macintosh serial port server runs a separate
thread of execution for each different socket. By forcing a new socket it can
be achieved that such a slow device is decoupled from the rest. Exactly this
is achieved with the force flag.
<li> Once the port has been initialised (for example p1) it is ready to operate.
The port object allows to send data to the serial port and receive data from
it. Furthermore some configuration is possible. The syntax is like this:
<DL>
<DT>portname -tmo number
<DD>Sets the timeout for the serial port. This is the maximum amount of time
the Macintosh serial port server waits for data to arrive from the RS-232 device.
Increase this if a lot of <code>_BAD_TMO</code> error messages creep up.
<DT>portname -sendterm string
<DD> Sets the terminator which will be automatically added to the string which is
sent. Some RS-232 devices require special terminators in order to accept a command.
The serial port implementation ensures that such a terminator is sent after
each message. This command allows to configure this terminator. Please note,
that the terminator string needs to be enclosed in quotes. An example:
<ul>
<li><code>p1 -sendterm "\r\n"</code>
</ul>
This sets the terminator to carriage return - line feed.
<DT>portname -replyterm string.
<DD>The Macintosh terminal server expects the RS-232 device to send a terminator
when it is done with sending answers. It even supports multiple lines to be
sent as a reply. This expected reply terminator is set with this command.
The string may may be four characters long. An example: <code>1\r\n</code> sets
the expected terminator to one of <code>\r\n</code>. One of them is expected. Thus the
first character is the count of terminators to expect, followed by the characters
possible as terminators. This string must usually be quoted.
<DT>portname blablalakjdl
<DD>When none of the options -tmo, -replyterm, -sendterm, is found everything after
portname is sent to the RS-232 device. The reply from the RS-232 device is printed.
</DL>
</ol>
The defaults set for the configuration parameters of the serial port connection
are suited for the EL734, EL737 and ITC4 devices usually encountered at SINQ. For
other RS-232 devices consult the manuals hopefully delivered with the device.
The defaults are: 100 for timeout, <code>1\r\n</code> for the reply terminator and
<code>\r\n</code>for the send terminator.
</p>
<p>
Please note, that the SICS server serial port access is a convenience feature for
SICS managers and instrument scientists. It is needed for implementing
environment device drivers in the Tcl macro language. If serial port connections must be
debugged the Macintosh versaterm software or on a IBM-PC the kermit program
are much better suited to the task.
</P>
</BODY>
</HTML>

89
doc/manager/setup.htm Normal file
View File

@ -0,0 +1,89 @@
<HTML>
<HEAD>
<TITLE>General SICS Setup</TITLE>
</HEAD>
<BODY>
<H1>General SICS Setup</H1>
<P>
SICS is a client server system. This implies that there is a server program
which implements all the functionlity and client programs which implement
the user interface. The client program is the only thing the user is
intended to see. This also means that the location of the client programs is
quite independent from the computer where the server runs. In the following
the layout of a server installation is described as established at SINQ.
</P>
<p>
For each instrument there is a data aquisition computer. On this computer
there exists a user name and consequently a home directory for the
instrument. In the following text this instrument root directory will be called
sicsroot. This root directory has the following subdirectories:
<DL>
<DT>bin
<DD> The bin directory is the place where the actual executable for the SICS
server is kept along with local copies of all necessary clients, the server
initialisation files and special macro files defined for the instrument.
<DT>data
<DD>The data directory is the central place where all data files collected
at the instrument are stored. Additionally this directory holds a file named
DataNumber which keeps the current serial number of the data files. This
file should never be edited. However, on the first of january an instrument
manager should reset the serial number in this file to 0.
<DT>log
<DD> The log directory contains the server log files and the automatically
generated client log files. Any now and then, and especially when disk space
problems loom, the client*.log files should be deleted by the instrument
manager.
<DT> doc
<DD> This directory holds a copy of the SICS user documentation for the
instrument. These are html files which can be viewed with WWW-browsers such
as lynx or netscape.
<DT> sim
<DD> The sim directory is meant to hold all files necessary for a SICServer
initialised for the instrument but configured with simulated hardware. This
facility is meant for testing of command files.
</DL>
Besides these directories there should be nothing on the instrument account.
All evaluated data, personal command files etc. should be held on the normal
user account of the instrument user.
</p>
<p>
For this purpose the /data/lnslib/bin directory holds copies of the
apropriate command line and status display clients for each instrument. A user can make
this directory (and much more) available by including the line <b>
source /data/lnslib/bin/lns.login</b> into her .login file.
</p>
<h2> SICS Installation</h2>
<p>
All executables and files necessary to run SICS for each instrument is
avaialable under the /data/lnslib/src/sics hierarchy. The bin directory
holds general executable files and a directory for each instrument which
holds instrument specific files. SICS installation on a unix system is
greatly simplified by using the <b>sicsinstall</b> korn shell script. This
script is available to each user. sicsinstall can be invoked simply by
typing sicsinstall at the command prompt. sicsinstall needs a subcommand in
order to know what it is expected to do:
<dl>
<DT>dev
<DD>copies knew executables from the development area to the distribution
directory. This command is meant to be used by computing staff only.
<DT>devfull
<DD>as dev, but copies all files. This command is meant to be used by computing staff only.
<DT>dmc
<DD>copies all files necessary for the instrument DMC.
<DT>topsi
<DD>copies all files necessary for the instrument TOPSI.
<DT>sans
<DD>copies all files necessary for the instrument SANS.
<DT>doc
<DD>updates only the documentation on your disk.
<DT>exe
<DD>copies only new executable files from the distribution area. This is the
recommended option when you want to be sure, that you have the latest
version of SICS before reporting a bug.
</dl>
Most of these options require you to be in the home directory of the
instrument account. sicsinstall checks for this and warns you if this is not
the case. Directory structures are checked for and created as needed.
</p>
</BODY>
</HTML>

221
doc/manager/sicsinstall Executable file
View File

@ -0,0 +1,221 @@
#!/usr/bin/ksh
#----------------------------------------------------------------------------
# script for installing SICS software on to a system.
# The source of the data muste be visible to the filesystem.
# This script installs SW into directories beyond your current directory
# So, on an instrument account it would be feasible to run this from the
# home directory. The script checks if we are at home, else it will print
# a warning.
#
# this script understands a few arguments:
#
# dev - copies new executables from development area to
# distribution area
# devfull - copies all files from development area to
# distribution area
# dmc - installs all files for running dmc
# topsi - install all files for topsi
# sans - installs all files for sans
# doc - updates only the documentation
# exe - installs only new executables
# debug - copies only the server to current directory
# lib - copies clients from the distribution area to
# the common program library.
#
# Mark Koennecke, Juli 1998
#----------------------------------------------------------------------------
#=========================== data area ====================================
devdir=/data/koenneck/src/sics # development directory
disdir=/data/lnslib/src/sics # distribution directory
dirdir="bin data doc log" # SICS directories
bindir=/data/lnslib/bin # common directory for binaries
clients="sicsclient.jar powderstatus.jar sansstatus.jar topsistatus.jar"
#======================= Functions ========================================
#------------------ check if in home directory
checkhome() {
if [ $HOME != $(pwd) ]; then
echo "You are not in your home directory."
echo "This may cause a non standard SICS installation"
echo "Do you want me to continue(Y,y) or abort(any other character)"
read answer
if [ \( $answer = Y \) -o \( $answer = y \) ]; then
echo "OK, I start clobbering......"
else
echo "Script aborting........."
exit 0
fi
fi
}
#------------------- print usage
usage() {
echo "USAGE:"
echo "This script copies SICS software. You need to tell this program"
echo "what to do by specifying one of the keywords below:"
echo ""
echo "dev - copies new executables from development area to"
echo " distribution area (MK only)"
echo "devfull - copies all files from development area to"
echo " distribution area (MK only)"
echo "dmc - installs all files for running dmc"
echo "topsi - install all files for topsi"
echo "sans - installs all files for sans "
echo "doc - updates only the documentation"
echo "exe - installs only new executables"
echo "lib - copies new clients to common program area"
echo ""
echo "Mark Koennecke, LNS, Juli 1998"
}
#------------------ copy new executables
copydev () {
echo "Copying new executable files from development area to distribution.."
cp $devdir/SICServer $devdir/psish/psish $devdir/psish/pish $disdir/bin
for cl in $clients; do
cp $devdir/SicsClient/$cl $disdir/bin
done
cp $devdir/replicator/replicator.jar $disdir/bin
}
#------------------ copy to common program area
copylib() {
echo "Copying new client files to common LNS program area"
cp $disdir/bin/*.jar $bindir
}
#------------------ copy all new stuff
copydevfull () {
echo "Copying ALL files from development area to distribution.."
copydev
echo "Copying documentation"
cp $devdir/user/*.htm $disdir/doc
cp $devdir/user/*.html $disdir/doc
cp $devdir/user/*.ps $disdir/doc
cp $devdir/manager/*.htm $disdir/manager
}
#------------------ copy only new executables
copyexe () {
echo "Copying new executable files"
cp $disdir/bin/SICServer $disdir/bin/psish $disdir/bin/pish bin
for cl in $clients; do
cp $disdir/bin/$cl bin
done
cp $disdir/bin/sics bin
cp $disdir/bin/powderstatus bin
cp $disdir/bin/sansstatus bin
cp $disdir/bin/topsistatus bin
cp $disdir/bin/replicator.jar
}
#----------------- copy documentation
copydoc () {
echo "Copying documentation"
cp $disdir/doc/*.htm doc
cp $disdir/doc/*.html doc
cp $disdir/doc/*.ps doc
}
#----------------- DMC special files
copydmc () {
echo "Copying DMC special files"
cp $disdir/bin/count.tcl $disdir/bin/init.tcl \
$disdir/bin/log.tcl $disdir/bin/xydialog.tcl $disdir/bin/CheckSICS bin
cp $disdir/bin/dmc/* bin
if [ -e data/DataNumber ]; then
echo "DataNumber found, OK"
else
echo "WARNING: Creating new DataNumber file with 0, adjust as needed"
echo " 0" > data/DataNumber
fi
echo "Done, configuration files may need editing"
}
#----------------- TOPSI special files
copytopsi () {
echo "Copying TOPSI special files"
cp $disdir/bin/count.tcl $disdir/bin/init.tcl \
$disdir/bin/log.tcl $disdir/bin/CheckSICS bin
cp $disdir/bin/topsi/* bin
if [ -e data/DataNumber ]; then
echo "DataNumber found, OK"
else
echo "WARNING: Creating new DataNumber file with 0, adjust as needed"
echo " 0" > data/DataNumber
fi
echo "Done, configuration files may need editing"
}
#----------------- SANS special files
copysans() {
echo "Copying SANS special files"
cp $disdir/bin/count.tcl $disdir/bin/init.tcl \
$disdir/bin/log.tcl $disdir/bin/CheckSICS bin
cp $disdir/bin/sans/* bin
if [ -e data/DataNumber ]; then
echo "DataNumber found, OK"
else
echo "WARNING: Creating new DataNumber file with 0, adjust as needed"
echo " 0" > data/DataNumber
fi
echo "Done, configuration files may need editing"
}
#------------------ check SICS directories
checkdir() {
echo "Checking directory structure, creating as needed"
for dd in $dirdir; do
if [ -d $dd ]; then
echo "$dd present"
else
echo "Creating $dd"
mkdir $dd
fi
done
}
#-------------- the case for checking the command parameter
case ${1-nix} in
dev)
copydev
;;
devfull)
copydevfull
;;
exe)
checkhome
checkdir
copyexe
;;
doc)
checkhome
checkdir
copydoc
;;
dmc)
checkhome
checkdir
copyexe
copydoc
copydmc
;;
topsi)
checkhome
checkdir
copyexe
copydoc
copytopsi
;;
sans)
checkhome
checkdir
copyexe
copydoc
copysans
;;
lib)
copylib
;;
debug)
cp $devdir/SICServer .
;;
*)
usage
;;
esac
echo "sicsinstall finished with more or less success"

33
doc/manager/sicsnews.htm Normal file
View File

@ -0,0 +1,33 @@
<HTML>
<HEAD>
<TITLE>SICS News Ticker</TITLE>
</HEAD>
<BODY>
<H1>SICS News Ticker</H1>
<P>
This page contains information about the latest bug fixes, releases and other
miscellaneous information about SICS.
</P>
<p>
<h2>Juli 1998</h2>
<DL>
<DT>Status OutOfMemory
<DD>Bug in status display clients fixed which caused OutOfMemory after
some time of automatic update.
<DT>topsistatus
<DD>TOPSI has got a java status client now as well. Can be invoked with
<b>topsistatus</b>. On the WWW also.
<DT>commandlog
<DD>On popular demand the SICS server can now write a log file which logs all
communication between clients with user or manager privilege and the SICserver.
This log is off by default. There is a new SICS command <a href="../commandlog.htm">
commandlog</a> which serves to configure this log.
<DT>8-fold counterboxes.
<DD>SICS now reads all eight monitors.
<DT>sicsinstall
<DD>There is now a shell script which automatizes updating and installing SICS. For more
information see the <a href="setup.htm">setup section</a> of the SICS managers guide.
</DL>
</p>
</BODY>
</HTML>

264
doc/manager/sicsstat.tcl Normal file
View File

@ -0,0 +1,264 @@
# Motor phi
phi SoftLowerLim 0.000000
phi SoftUpperLim 360.000000
phi SoftZero 0.000000
phi Fixed -1.000000
phi InterruptMode 0.000000
phi AccessCode 2.000000
# Motor chi
chi SoftLowerLim 0.000000
chi SoftUpperLim 360.000000
chi SoftZero 0.000000
chi Fixed -1.000000
chi InterruptMode 0.000000
chi AccessCode 2.000000
# Motor omega
omega SoftLowerLim -180.000000
omega SoftUpperLim 360.000000
omega SoftZero 0.000000
omega Fixed -1.000000
omega InterruptMode 0.000000
omega AccessCode 2.000000
# Motor twotheta
twotheta SoftLowerLim 5.000000
twotheta SoftUpperLim 120.000000
twotheta SoftZero 0.000000
twotheta Fixed -1.000000
twotheta InterruptMode 0.000000
twotheta AccessCode 2.000000
banana CountMode timer
banana preset 100.000000
sample_mur (null)
sample_mur setAccess 2
email UNKNOWN
email setAccess 2
fax UNKNOWN
fax setAccess 2
phone UNKNOWN
phone setAccess 2
adress UNKNOWN
adress setAccess 2
# Counter counter
counter SetPreset 1000.000000
counter SetMode Timer
# Motor som
som SoftLowerLim 0.000000
som SoftUpperLim 360.000000
som SoftZero 0.000000
som Fixed -1.000000
som InterruptMode 0.000000
som AccessCode 2.000000
# Motor sax
sax SoftLowerLim -30.000000
sax SoftUpperLim 30.000000
sax SoftZero 0.000000
sax Fixed -1.000000
sax InterruptMode 0.000000
sax AccessCode 2.000000
# Motor tilt
tilt SoftLowerLim -15.000000
tilt SoftUpperLim 15.000000
tilt SoftZero 0.000000
tilt Fixed -1.000000
tilt InterruptMode 0.000000
tilt AccessCode 0.000000
# Motor detectorrotation
detectorrotation SoftLowerLim -20.000000
detectorrotation SoftUpperLim 20.000000
detectorrotation SoftZero 0.000000
detectorrotation Fixed -1.000000
detectorrotation InterruptMode 0.000000
detectorrotation AccessCode 2.000000
# Motor detectory
detectory SoftLowerLim -20.000000
detectory SoftUpperLim 20.000000
detectory SoftZero 0.000000
detectory Fixed -1.000000
detectory InterruptMode 0.000000
detectory AccessCode 2.000000
# Motor detectorx
detectorx SoftLowerLim -20.000000
detectorx SoftUpperLim 20.000000
detectorx SoftZero 0.000000
detectorx Fixed -1.000000
detectorx InterruptMode 0.000000
detectorx AccessCode 2.000000
# Motor beamstopy
beamstopy SoftLowerLim -20.000000
beamstopy SoftUpperLim 20.000000
beamstopy SoftZero 0.000000
beamstopy Fixed -1.000000
beamstopy InterruptMode 0.000000
beamstopy AccessCode 2.000000
# Motor beamstopx
beamstopx SoftLowerLim -20.000000
beamstopx SoftUpperLim 20.000000
beamstopx SoftZero 0.000000
beamstopx Fixed -1.000000
beamstopx InterruptMode 0.000000
beamstopx AccessCode 2.000000
# Motor d2t
d2t SoftLowerLim -20.000000
d2t SoftUpperLim 20.000000
d2t SoftZero 0.000000
d2t Fixed -1.000000
d2t InterruptMode 0.000000
d2t AccessCode 2.000000
# Motor d2l
d2l SoftLowerLim -20.000000
d2l SoftUpperLim 20.000000
d2l SoftZero 0.000000
d2l Fixed -1.000000
d2l InterruptMode 0.000000
d2l AccessCode 2.000000
# Motor d2r
d2r SoftLowerLim -20.000000
d2r SoftUpperLim 20.000000
d2r SoftZero 0.000000
d2r Fixed -1.000000
d2r InterruptMode 0.000000
d2r AccessCode 2.000000
# Motor d1t
d1t SoftLowerLim -20.000000
d1t SoftUpperLim 20.000000
d1t SoftZero 0.000000
d1t Fixed -1.000000
d1t InterruptMode 0.000000
d1t AccessCode 2.000000
# Motor d1l
d1l SoftLowerLim -20.000000
d1l SoftUpperLim 20.000000
d1l SoftZero 0.000000
d1l Fixed -1.000000
d1l InterruptMode 0.000000
d1l AccessCode 2.000000
# Motor d1r
d1r SoftLowerLim -20.000000
d1r SoftUpperLim 20.000000
d1r SoftZero 0.000000
d1r Fixed -1.000000
d1r InterruptMode 0.000000
d1r AccessCode 2.000000
# Motor tasse
tasse SoftLowerLim -130.000000
tasse SoftUpperLim 130.000000
tasse SoftZero 0.000000
tasse Fixed -1.000000
tasse InterruptMode 0.000000
tasse AccessCode 2.000000
# Motor sdm
sdm SoftLowerLim -5.000000
sdm SoftUpperLim 5.000000
sdm SoftZero 0.000000
sdm Fixed -1.000000
sdm InterruptMode 0.000000
sdm AccessCode 2.000000
# Motor sgu
sgu SoftLowerLim -20.000000
sgu SoftUpperLim 20.000000
sgu SoftZero 0.000000
sgu Fixed -1.000000
sgu InterruptMode 0.000000
sgu AccessCode 2.000000
# Motor sgl
sgl SoftLowerLim -20.000000
sgl SoftUpperLim 20.000000
sgl SoftZero 0.000000
sgl Fixed -1.000000
sgl InterruptMode 0.000000
sgl AccessCode 2.000000
# Motor mgu
mgu SoftLowerLim -50.000000
mgu SoftUpperLim 50.000000
mgu SoftZero 0.000000
mgu Fixed -1.000000
mgu InterruptMode 0.000000
mgu AccessCode 2.000000
# Motor stu
stu SoftLowerLim -30.000000
stu SoftUpperLim 30.000000
stu SoftZero 0.000000
stu Fixed -1.000000
stu InterruptMode 0.000000
stu AccessCode 2.000000
# Motor stl
stl SoftLowerLim -30.000000
stl SoftUpperLim 30.000000
stl SoftZero 0.000000
stl Fixed -1.000000
stl InterruptMode 0.000000
stl AccessCode 2.000000
# Motor mtu
mtu SoftLowerLim -30.000000
mtu SoftUpperLim 30.000000
mtu SoftZero 0.000000
mtu Fixed -1.000000
mtu InterruptMode 0.000000
mtu AccessCode 2.000000
# Motor mtl
mtl SoftLowerLim -30.000000
mtl SoftUpperLim 30.000000
mtl SoftZero 0.000000
mtl Fixed -1.000000
mtl InterruptMode 0.000000
mtl AccessCode 2.000000
# Motor a6
a6 SoftLowerLim -30.000000
a6 SoftUpperLim 30.000000
a6 SoftZero 0.000000
a6 Fixed -1.000000
a6 InterruptMode 0.000000
a6 AccessCode 2.000000
# Motor a5
a5 SoftLowerLim -30.000000
a5 SoftUpperLim 30.000000
a5 SoftZero 0.000000
a5 Fixed -1.000000
a5 InterruptMode 0.000000
a5 AccessCode 2.000000
# Motor a4
a4 SoftLowerLim -130.000000
a4 SoftUpperLim 130.000000
a4 SoftZero 0.000000
a4 Fixed -1.000000
a4 InterruptMode 0.000000
a4 AccessCode 2.000000
# Motor a3
a3 SoftLowerLim 0.000000
a3 SoftUpperLim 360.000000
a3 SoftZero 0.000000
a3 Fixed -1.000000
a3 InterruptMode 0.000000
a3 AccessCode 2.000000
# Motor a2
a2 SoftLowerLim 30.000000
a2 SoftUpperLim 120.000000
a2 SoftZero 0.000000
a2 Fixed -1.000000
a2 InterruptMode 0.000000
a2 AccessCode 2.000000
# Motor a1
a1 SoftLowerLim 30.000000
a1 SoftUpperLim 120.000000
a1 SoftZero 0.000000
a1 Fixed -1.000000
a1 InterruptMode 0.000000
a1 AccessCode 2.000000
user Daniel_the_Clementine
user setAccess 2
temperature ine
0
00
00
<EFBFBD>
temperature setAccess 2
sample DanielOxid
sample setAccess 2
title TopsiTupsiTapsi
title setAccess 2

21
doc/manager/special.htm Normal file
View File

@ -0,0 +1,21 @@
<HTML>
<HEAD>
<TITLE>Special Commands for SICS Administrators and Programmers</TITLE>
</HEAD>
<BODY>
<H1>Special Commands for SICS Administrators and Programmers</H1>
<P>
This section describes a few commands which need not be known to SICS users.
<!latex-off>
<UL>
<li> Access Macintosh <a href="serial.htm"> serial </a>ports.
<li> An internal <a href=iscan.htm> scan command</a>.
<li> Accessing Siematic <a href="sps.htm">SPS</a> controllers.
<li> <a href="alias.htm">Aliases</a>.
<li> <a href="cron.htm">Reoccuring tasks</a>.
</uL>
<!latex-on>
</P>
</BODY>
</HTML>

58
doc/manager/sps.htm Normal file
View File

@ -0,0 +1,58 @@
<HTML>
<HEAD>
<TITLE>Siematic SPS Controllers</TITLE>
</HEAD>
<BODY>
<H1>Siematic SPS Controllers</H1>
<P>
Siematic SPS controllers are used at SinQ for handling all the things which
fit in nowhere else. Such as operating air cushions on some instruments,
reading variables from ADC's, reading status of shutters or other parts of
the instrument and the like. Those SPS units have an RS-232 connector and
understand a simple ASCII command protocoll.
The Siematic SPS and its command protocoll are
special to PSI and this section is probably of no interest to SICS managers
outside. The SPS basiaclly support three operations:
<ul>
<li>Push a button.
<li>Request status of instrument status packed into a bit.
<li>Read an ADC.
</ul>
This is so user unfriendly that the usage of the SPS will mostly be packaged
into Tcl-macros.
</P>
<p>
A SPS unit can be configured into the SICS server with the command:<br>
<b>MakeSPS name macintosh port channel</b> <br>
The parameters are: the name of the SPS in SICS, the serial port server
computer, the port where the serial port server is listening and the
channel number of the SPS unit at the serial port server computer. An
example: <br>
MakeSPS sps1 lnsp25.psi.ch 4000 6 <br>
configures a SPS unit at lnsp25.psi.ch at channel 5. The serial port server
is listening at port number 4000. The SPS unit will be accessible as sps1 in
SICS.
</p>
<p>
After configuartion the following four commands are understood by name,
shown with sps1 as example:
<DL>
<DT>sps1 push byte bit
<DD>Corresponds to pushing the button mapped to the bit bit in the byte
byte.
<DT>sps1 adc num
<DD> Reads the value in the ADC num. num can be between 0 to 7 for a maximum
of eight ADC's. Please note, that the values read are raw values which
usually must be converted in some way to physically meaningful values.
<DT>sps1 status bit
<DD>Reads the status of the bit bit. bit can be in the range 0 - 128.
<DT>sps1 stat2 byte bit
<DD>Reads the status bit bit in status byte byte. Is equivalent to status,
but adds some syntatctic sugar.
</DL>
For all conversion factors, for all mappings of bytes and bits, consult the
electronician who coded the SPS.
</p>
</BODY>
</HTML>

36
doc/manager/startsics Executable file
View File

@ -0,0 +1,36 @@
#!/usr/bin/ksh
#-------------------------------------------------------------------------
# shell sript to start the servers necessary for running SICS.
# checks if they are not already running.
#
# Mark Koennecke, Juli 1998
#------------------------------------------------------------------------
inst=test
shome=$HOME/src/sics
# start SICServer
ps waux > /tmp/ps.lis
grep SICServer /tmp/ps.lis > /dev/null
if [ $? -eq 1 ] ; then
echo "Starting SICServer"
cd $shome
com="SICServer $inst.tcl"
keepalive "$com" &
else
echo "SICServer exists"
fi
rm /tmp/ps.lis
# start replicator service
ps waux > /tmp/ps.lis
grep replicator.jar /tmp/ps.lis > /dev/null
if [ $? -eq 1 ] ; then
echo "Starting Data Replicator"
cd $shome
com1="jre -classpath /usr/lib/classes.zip:$shome/replicator.jar Replicator "
com2=$sheim/replicator.conf
com=$com1$com2
keepalive "$com" &
else
echo "Data Replicator exists"
fi
rm /tmp/ps.lis

63
doc/manager/status.htm Normal file
View File

@ -0,0 +1,63 @@
<HTML>
<HEAD>
<TITLE>Commands supporting SICS status displays</TITLE>
</HEAD>
<BODY>
<H1>Commands For Supporting SICS Status Displays</H1>
<P>
The implementation of many status displays is greatly simplified by
letting the SICS server do some of the hard work. The operation of
these commands is usually invisible to users. Some even do not
generate output accessible to the user because they send uuencoded
information. This section documents these commands for completeness
and as a reference for status display client writers.
</P>
<h2>The Reflectometer AMOR</h2>
<p>
The reflectometer AMOR probably has the most extensive of such
modules. It does a lot of things. It is configured into SICS with the
MakeAmorStatus command. Let us assume that it is configured into the
system as amorstatus. This object supports the following commands:
<dl>
<dt>amorstatus interest
<dd>This registers this connection for receiving automatic
notifications. Automatic notifications send are:
<DL>
<dt>SCANSTART
<dd> At scan start a message <b>ScanClear</b> is sent followed by the
uuencoded new x-axis for the plot.
<dt>SCANPOINT
<dd>At each scan point the arrays of counts in both detector are sent
in uuencoded form labelled arrow_spinupup and arrow_spinuplo.
<DT>COUNTSTART
<DD>The start of counting on the histogram memory. Send a message
<b>TOFClear</b> and then the uuencoded time binning labelled
arrow_time.
<DT>FILELOADED
<DD>activated each time user defined model data is loaded into the
SICS server. This data gets send as arrow_name in uuencoded form. Both
x- and y-axis are sent in floating point.
</DL>
Please note that floating point data is transformed to fixed point by
multiplication of 65653 before transfer. The first number in each
uuencoded message is an integer describing the length of the data. In
case of double data such as fileloaded the y-data follows immediatetly
after the x-data. Also the approriate data is automatically sent after
the interest command.
<dt>amorstatus collapse
<dd>sums all counts in all detectors in time and sends the data back
as an uuencoded image. The first two numbers in the message define the
dimensions of the data.
<dt>amorstatus sample name x1 x2 y1 y2
<dd>Sums the detector counts on an area defined by the rectangle x1,
x2, y1, y2. The length of this is the time binning. The data is sent
back in uuencoded form labelled arrow_name.
<dt>amorstatus clear
<dd> Clears all user loaded data.
<dt>amorstatus load filename scale
<dd> loads user defined data for distribution to the status display
clients. The y data is scaled according to the scale factor provided.
</dl>
</p>
</BODY>
</HTML>

11
doc/manager/template.htm Normal file
View File

@ -0,0 +1,11 @@
<HTML>
<HEAD>
<TITLE>The Tcl-interface to the SINQ histogram memory</TITLE>
</HEAD>
<BODY>
<H1>The Tcl-interface to The SINQ histogram memory</H1>
<P>
</P>
</BODY>
</HTML>

207
doc/manager/trouble.htm Normal file
View File

@ -0,0 +1,207 @@
<html>
<head>
<title>SICS Trouble Shooting</title>
</head>
<body>
<h1>SICS Trouble Shooting </h1>
<hr size=4 width="66%">
<p>
There is no such thing as bug free software. There are always bugs, nasty
behaviour etc. This document shall help to solve these problems. The usual
symptom will be that a client cannot connect to the server or the server is
not responding.
</p>
<p>
An essential prerequisite of SICS is that the server is up
and running. The system is configured to restart the SICServer whenever it
fails. Only after a reboot or when the keepalive processes were killed (see
below) the SICServer must be restarted. This is done for all instruments by
typing:
<pre>
startsics
</pre>
at the command prompt. startsics actually starts two programs: one is
the replicator application which is responsible for the automatic
copying of data files to the laboratory server. The other is the SICS
server. Both programs are started by means of a shell script called
<b>keepalive</b>. keepalive is basically an endless loop which calls
the program again and agaian and thus ensures that the program will
never stop running.
</p>
<p>
When the SICS server hangs, or you want to enforce an reinitialization of
everything the server process must be killed. This can be accomplished either manually or through a shell script.
</p>
<h2>Stopping SICS</h2>
<p>
All SICS processes can be stopped through the command:
<pre>
killsics
</pre>
given at the unix command line. You must be the instrument user
(for example DMC) on the instrument computer for this to work properly.
</p>
<h2>Finding the SICS server</h2>
<p>The first thing when killing the SICS server manually is to find the
server process.
Log in as Instrument user on the instrument computer (for instance DMC on
lnsa05). Type the command:
<pre>
/home/DMC> ps -A
</pre>
Note the capital A given as parameter. The reward will be listing like this:
<pre width =132>
PID TTY S TIME CMD
0 ?? R 01:56:28 [kernel idle]
1 ?? I 1:24.44 /sbin/init -a
3 ?? IW 0:00.20 /sbin/kloadsrv
24 ?? S 40:39.58 /sbin/update
97 ?? S 0:04.87 /usr/sbin/syslogd
99 ?? IW 0:00.03 /usr/sbin/binlogd
159 ?? S 1:43.70 /usr/sbin/routed -q
285 ?? S 1:00.45 /usr/sbin/portmap
293 ?? S 6:03.45 /usr/sbin/ypserv
299 ?? I 0:00.37 /usr/sbin/ypbind -s -S psunix,lnsa05.psi.ch
307 ?? I 0:00.52 /usr/sbin/mountd -i
309 ?? I 0:00.07 /usr/sbin/nfsd -t8 -u8
311 ?? I 0:00.09 /usr/sbin/nfsiod 7
317 ?? S 5:51.54 /usr/sbin/automount -f /etc/auto.master -M /psi
370 ?? I 0:28.58 -accepting connections (sendmail)
389 ?? S 1:41.15 /usr/sbin/xntpd -g -c /etc/ntp.conf
419 ?? S 6:00.16 /usr/sbin/snmpd
422 ?? S 1:00.91 /usr/sbin/os_mibs
438 ?? S 34:29.67 /usr/sbin/advfsd
449 ?? I 3:16.29 /usr/sbin/inetd
482 ?? IW 0:11.53 /usr/sbin/cron
510 ?? IW 0:00.02 /usr/lbin/lpd
525 ?? I 5:31.67 /usr/opt/psw/psw_agent -x/dev/null -f/usr/opt/psw/psw_agent.conf
532 ?? I 0:00.74 /usr/opt/psw/psw_sensor_syswd 1 -x/dev/null
555 ?? I 0:00.58 /usr/bin/nsrexecd
571 ?? I 0:20.27 /usr/dt/bin/dtlogin -daemon
583 ?? S 1:38.27 lpsbootd -F /etc/lpsodb -l 0 -x 1
585 ?? IW 0:00.04 /usr/sbin/getty /dev/lat/620 console vt100
586 ?? IW 0:00.03 /usr/sbin/getty /dev/lat/621 console vt100
587 ?? I 35:59.85 /usr/bin/X11/X :0 -auth /var/dt/authdir/authfiles/A:0-aaarBa
657 ?? I 0:01.46 rpc.ttdbserverd
4705 ?? IW 0:00.05 dtlogin -daemon
9127 ?? I 0:00.37 /usr/bin/X11/dxconsole -geometry 480x150-0-0 -daemon -nobuttons -verbose -notify -exitOnFail -nostdin -bg gray
9317 ?? IW 0:00.73 dtgreet -display :0
14412 ?? S 0:39.71 netscape
15524 ?? I 0:00.57 rpc.cmsd
21678 ?? S 0:00.11 telnetd
31912 ?? S 0:10.65 /home/DMC/bin/SICServer /home/DMC/bin/dmc.tcl
584 console IW + 0:00.21 /usr/sbin/getty console console vt100
21978 ttyp1 S 0:00.63 -tcsh (tcsh)
22269 ttyp1 R + 0:00.10 ps -A
</pre>
This is a listing of all running processes on the machine where this command
has been typed. Note, in this case, at the bottom in the line starting with
<tt> 31912 ?? </tt> an entry for the SICS server. In this example the server
is running. If the server is down, no such entry would be present.
</p>
<h2> Killing a hanging SICS server </h2>
<p>
Suppose, the situation is that the SICS server does not respond anymore. It
needs to be forcefully exited. Please note, that it is always better to
close the server via the <tt>Sics_Exitus</tt> command typed with manager
privilege in one of the command clients. In order to kill the server it is
needed to find him first using the scheme given above. The information
needed is the number given as first item in the same line where the server
is listed. In this case: <tt>31912</tt>. Please note, that this number will
always be different. The command to force the server to stop is:
<pre>
/home/DMC> kill -9 31912
</pre>
Note, the second parameter is the number found with <tt>ps -A</tt>. The
SICServer will be restarted automatically by the system. Occasionally, it
may happen, that you cannot connect to the SICS server after such an
operation. This is due to some network buffering problems. Doing the killing
again usually solves the problem.
</p>
<h2> Shutting The SICS Server Down Completely</h2>
<p>
This is done for you by the killsics shell script. Just type
<pre>
killsics
</pre>
at the unix command line. Here is what killsics does for you:
In order to completely shutdown the SICS server two process must be killed:
the actual SICS server and the process which automatically restarts the
SICServer. The latter must be killed first. It can be found in the ps -A
listing as a line reading <b>keepalive SICServer </b>. Kill that one as
described above, then kill the SICServer. For restarting SICS after this,
use the startsics command.
</p>
<h2>Restart Everything</h2>
<p>
If nothing seems to work any more, no connections can be obtained etc, then
the next guess is to restart everything. This is especially necessary if
mechanics or electronics people were closer to the instrument then 400 meters.
<OL>
<LI> Reboot the Macintosh PC by switching it off at the silver button on the
left. Press deep and a few seconds to achieve an effect. The LED right to the
button should be off, before you press again to boot the Macintosh.
<LI> Reboot the histogram memory. It has a tiny button labelled RST. That' s
the one. Can be operated with a hairpin, a ball point pen or the like.
<LI> Wait 5 minutes. The Macintosh may take that time to come up again.
<LI> Restart the SICServer. Watch for any messages about things not being
connected or configured.
<LI> Restart and reconnect the client programs.
</OL>
If this fails (even after a second) time there may be a network problem which
can not be resolved by simple means.
</p>
<h2>Getting New SICS Software</h2>
<p>
Sometimes you might want to be sure that you have the latest SICS software.
This is how to get it:
<ol>
<li>Login to the instrument account.
<li>If you are no there type cd to get into the home directory.
<li>Type <b>killsics</b> at the unix prompt in order to stop the SICS server.
<li>Type <b>sicsinstall exe</b> at the unix prompt for copying new
SICS software from the general distribution area.
<li>Type <b> startsics</b> to restart the SICS software.
</ol>
</p>
<h2>Hot Fixes</h2>
<p>
When there is trouble with SICS you may be asked by one of the SICS
programmers to copy the most recent development reason of the SICS server
to your machine. This is done as follows:
<ol>
<li>Login to the instrument account.
<li>cd into the bin directory, for example: /home/DMC/bin.
<li>Type <b> killsics</b> at the unix prompt in order to stop the SICS server.
<li>Type <b>cp /data/koenneck/src/sics/SICServer .</b> at the unix prompt.
<li>Type <b> startsics</b> to restart the SICS software.
</ol>
<b>!!!!!! WARNING !!!!!!!. Do this only when advised to do so by a competent
SICS programmer. Otherwise you might be copying a SICS server in an
instable experimental state!</b>
</p>
<h2> HELP debugging!!!!</h2>
<p>
The SICS server hanging or crashing should not happen. In order to sort such
problems out it is very helpful if any available debugging information is
saved and presented to the programmers. Information available are the log
files as written continously by the SICS server and posssible core files
lying around. They have just this name: core. In order to save them create a
new directory (for example dump2077) and copy the stuff in there. This looks
like:
<pre>
/home/DMC> mkdir dump2077
/home/DMC> cp log/*.log dump2077
/home/DMC> cp core dump2077
</pre>
The <tt>/home/DMC> </tt> is just the command prompt. Please note, that core
files are only available after crashes of the server. These few commands
will help to analyse the cause of the problem and to eventually resolve it.
</p>
</body>
</html>

86
doc/manager/var.htm Normal file
View File

@ -0,0 +1,86 @@
<html>
<head>
<title>SICS Variables</title>
</head>
<body>
<h2>SICS Variables </h2>
<p>
In SICS most parameters necessary for instrument control are kept with the SICS
object implementing the functionality. However, there are some odd bits of
information which need to be known, mostly additional information about and
from the user, which should go into data files. Such information is kept in
SICS variables, created with the command VarMake detailed below.
</p>
<p>
Another usage for variables is to control composite movements of instrument
components. For instance for changing the wavelength it is necessary to
drive at least two motors, Theta and TwoTheta. Such behaviour is implemented
with some SICS special variables. Their creation is described below.
</p>
<p>
Variables are also used in order to control the SINQ automatic file name
creation scheme for data files. At SINQ, data files are put into a special
directory. The actual name consists of a prefix, a sequential number, the
last two digits of the year and an ending. All these components are
controlled by variables.
</p>
<p>
The exact syntax for creating variables lokks like this:
<ul>
<li> <b> VarMake name type access </b> creates a simple variable name. The
variable type can be Text, Int or Float. The access parameter defines who
may may change the variable. Possible values are: Internal, Manager, User
and Spy.
<li> <b> MakeWaveLength nam mono </b> creates a wavelength variable nam.
The monochromator mono is used for adjustment.
<li> <b> MakeEnergy nam mono </b> creates a energy variable nam. The
monochromator mono is used for adjustment.
<li> <b> MakeO2T nam OM 2TM </b> creates an omega 2Theta dummy variable
with name nam for omega 2Theta scans. OM defines an omega motor, 2TM a two
theta motor.
<li><b>MakeDataNumber SicsDataNumber filename</b> This command makes a
variable SicsDataNumber available which holds the current sequential data
file number. filename is the complete path to the file were this data
number is stored. This file should never, ever be edited without good
reason, i.e. resetting the sequential number to 0 at the beginning of a
year.
</ul>
</p>
<p>
There are quite a few SICS variables which have special usages and should be
present. Some of them may need to be set by the user, all of them should be
inspectable by the user. Many of these variables are used when writing
NeXus data files. These special variables are:
<DL>
<DT> sample
<DD> The sample name. To be set by the user.
<DT> title.
<DD> The experiment title.
<DT> User
<DD> The name of the user to be specified in a data file.
<DT> Instrument.
<DD> The name of the instrument.
<DT> SicsDataPath
<DD>The full path name of the instruments data directory. Should have a / at
the end.
<DT> SicsDataPrefix
<DD> The prefix to use for data file names.
<DT> SicsDataPostFix
<DD> The ending to use for the data file name. Including the '.'.
<DT> Adress
<DD> The users adress.
<DT> phone
<DD> The users phone number.
<DT> email
<DD> The users e-mail adress.
<DT> fax
<DD> The users fax number.
</DL>
</p>
<p>
Some of the variables stated above should never be changed by a user. This
can be achieved by the variable lock command described in the user
documentation.
</p>
</body>
</html>

1
doc/programmer/...aux Normal file
View File

@ -0,0 +1 @@
\relax

5
doc/programmer/README Normal file
View File

@ -0,0 +1,5 @@
The entry points in this file are:
pub.tex for a SICS publication
programmer.tex for a SICS programming guide
reference.tex for the SICS reference manual

140
doc/programmer/SCinter.tex Normal file
View File

@ -0,0 +1,140 @@
\subsection{The SICS Interpreter} \label{scinter}
The SICS interpreter does the first step of command interpretation. Each
SICS command is a name followed by parameters. The interpreter holds for
each command a function (the object function) and a data structure. When a
command is invoked the list will be searched for a fitting command and then
its object function will be invoked for further processing.
The object
function is the object wrapper function as discussed in much detail in the
Guide to Object Writers. It looks like this:
\begin{verbatim}
typedef int (*ObjectFunc)(pSConnection pCon, pSicsInterp pInter, void
*pData, int argc, char *argv[]);
\end{verbatim}
{\bf pCon} is a pointer to the the connection for which the command
was invoked. {\bf pInter} is the SICS interpreter in which the command
was invoked. {argc, argv[]} are the command arguments similar to the
classic C main() function arguments. This is an objects interface to
the SICS interpreter.
{\bf pData} is a pointer to a command own data structure. This data structure
is deleted by the interpreter when the command is removed by calling
a special removal function with the pointer as parameter. This
function looks like this:
\begin{verbatim}
typedef void (*KillFunc)(void *pData);
\end{verbatim}
In order to do ist job the SICS interpreter has for each command a data
structure defined below:
\begin{verbatim}
typedef struct __Clist {
char *pName;
ObjectFunc OFunc;
KillFunc KFunc;
void *pData;
struct __Clist *pNext;
struct __Clist *pPrevious;
} CommandList;
\end{verbatim}
The fields are: \begin{description}
\item[name] The command name.
\item[OFunc] The object wrapper function.
\item[KFunc] The object data structure removal function.
\item[pData] The objects data structure.
\item[pNext, pPrevious] pointers necessary to maintain the doubly linked
list of commands.
\end{description}
The interpreter itself is described by the following data structure:
\begin{verbatim}
typedef struct __SINTER
{
CommandList *pCList;
OutCode eOut;
void *pTcl;
char **argv;
int iDeleting;
}SicsInterp;
\end{verbatim}
The fields are: \begin{description}
\item[pCList] A pointer to the command list.
\item[eOut] an out code.
\item[pTcl] a pointer to the Tcl macro interpreter.
\item[argv] An argv[] array with command arguments.
\item[iDeleting] a flag which is set when the interpreter is in the
process of being removed.
\end{description}
Please note, that currently commands are searched for by linear scanning of
the command list, doing a strcmp at each stop. This is inherently
inefficient. If in some stage interpreter inefficiency is a problem this
scheme should be chnaged to a hash table system or a randomized binary tree.
The interpreter can be controlled with the following functions:
\begin{description}
\item[SicsInterp *InitInterp(void)]
Makes a new interpreter. Returns him on success, else NULL
\item[int AddCommand(SicsInterp *pInterp, char *pName, ObjectFunc pFunc,
KillFunc pKFunc, void *pData)]
Adds a new command, Returns True or False, depending on success
Parameters:
\begin{itemize}
\item pInterp : the interpreter to add the command to.
\item pName : the commands name
\item pFunc : the object function to call when this command is
invoked. Definition of type: see above
\item pKFunc : function to call in order to delete command data.
type definition: above
\item pData : pointer to the command's own datastructure. Will be
passed as pData with each call to Ofunc.
\end{itemize}
It is possible to install commands without an associated data structure.
Then pData must be NULL. In such cases AddCommand provides a default data
structure with a default object descriptor.
\item[int RemoveCommand(SicsInterp *pInterp, char *pName)]
Kills the command name from the interpreter pInterp
\item[int InterpExecute(SicsInterp *self,pSConnection pCon,char *pCommand)]
Executes a command in the interpreter self. Essentially converts
pCommand in an argc, argv[] pair, sets various status things and
invokes the object function. Takes care of status and error reporting
afterwards.
Parameters: \begin{itemize}
\item self : interpreter to invoke command in.
\item The connection pCon will be used for I/O and status reporting.
\item The command to invoke is the string pCommand.
\end{itemize}
Returns -1 if the command can not be found.
If the command is found, 1 is returned on success, 0 on failure in
the command.
\item[CommandList *FindCommand(SicsInterp *pInterp, char *name)]
Searches the Interpreters pInterp command list for a command
with name. Returns its data structure if found, NULL else
\item[int WriteSicsStatus(SicsInterp *pSics,char *file)]
SICS needs a way to save the status of each object into a file.
This is done by invoking for each object the object descriptor
function SaveStatus. This function does just that.
Parameters: \begin{itemize}
\item pSics : the interpreter to use.
\item file : the file to write the information to.
\end{itemize}
Returns: 1 on success, 0 on failure.
\item[int InterpWrite(SicsInterp *pSics, char *buffer)]
Writes result to Tcl, used for Macro mechanism.
This is an internal function and should not be used.
\item[void DeleteInterp(SicsInterp *self)]
Deletes the interpreter self aand clears all asoociated datastructures.
self will no longer be vaild after this.
\item[FindAlias] find the alias for a given data structure. This is a
special function required internally.
\item[FindCommandData] is a convenience wrapper around FindCommand
which returns the commands data structure instead the CommandList
entry fo a given command name. Returns NULL, if the command was not
found.
\end{description}

37
doc/programmer/alias.tex Normal file
View File

@ -0,0 +1,37 @@
\subsection{The Alias Facility}
Aliases make commands available under a different name. SICS currently supports two types of aliases:
\begin{itemize}
\item Object aliases. This is a facility for renaming first class SICS
objects such as commands and hardware objects. This is installed into
SICS by creating a new name in the interpreter but with the data
structures of the original object. Thus all interface operations such
as driving etc will work. Object aliases are installed from the
initialization script through the SicsAlias command.
\item Command aliases. This is just plain text replacement. For
instance one may define ``sttll'' instead of ``a4 softlowerlim''. Such
an alias can be installed with the ``alias'' command at any
time. However, renaming a motor with this scheme will not work
properly as this alias facility has no way to forward interfaces
properly.
\end{itemize}
There is no
data structure associated with object aliases. The trick is done by
just putting in
the same command as a new name into the interpreter.
Corrspondingly there is only one function to it:
\begin{verbatim}
int SicsAlias(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
\end{verbatim}
SicsAlias is the object wrapper function which implements the alias command.
Command aliases are implemented through:
\begin{verbatim}
int MakeAlias(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
\end{verbatim}
There is a little trivial data structure associated with command
aliases which is defined in alias.c.

176
doc/programmer/amor2t.tex Normal file
View File

@ -0,0 +1,176 @@
\subsection{AMOR Two Theta}
AMOR is SINQ's new reflectometer. It has the peculiar feature that the
two theta movement of the detector is expressed in translations along
the reflectometer base axis and the detector height. Additionally the
detector is tilted. The height of two diaphragms has to be adjusted as
well. And, in polarizing mode, the analyzer has to be operated as
well. Quite a complicated movement. I fear this module may only be
useful for AMOR, but may be, other reflectometers may profit as well.
This object implements this complex movement as a virtual motor.
The following formulas are used for the necessary calculations:
\begin{eqnarray}
delta height & = & h_{s} - R \sin \alpha \\
delta x & = & |x_{c} - x_{s}| - R \cos \alpha \\
omega & = & -2 MOM + 2 SOM \\
\end{eqnarray}
with
\begin{eqnarray}
h_{s} & = & \tan(2MOM)|x_{c} - x_{s}| \\
R & = & \sqrt{hs^{2} - |x_{c} - x_{s}|^{2}} \\
\alpha & = & 180 -90 - \beta - 2SOM \\
\beta & = & 180 - 90 - 2MOM \\
MOM & = & polarizer \omega \\
SOM & = & sample \omega \\
x_{c} & = & counter position \\
x_{s} & = & sample position\\
\end{eqnarray}
The same equations hold true for the calculations of the diaphragm
heights, just replace the distances. The equations for the analyzer
are not yet known.
Due to this complicated movement this module needs to know about a lot
of motors and a lot of parameters. The distances of the various
components need to be modified at run time in order to allow for
configuration changes. These are not motorized but must be entered
manually.
\subsubsection{Data Structures}
Consequently data structures are complex. The first data structure
used is an entry in an array of motors to start:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap1}
$\langle$putput {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ typedef struct {@\\
\mbox{}\verb@ pMotor pMot;@\\
\mbox{}\verb@ char pName[80];@\\
\mbox{}\verb@ float fTarget;@\\
\mbox{}\verb@ }MotEntry, *pMotEntry;@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
\begin{description}
\item[pMot] is a pointer to the motors data structure.
\item[pName] is the name of the motor to start.
\item[fTarget] is the target value for the motor.
\end{description}
The next data structure is the class data structure for amor2t:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap2}
$\langle$amoredata {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ typedef struct __AMOR2T {@\\
\mbox{}\verb@ pObjectDescriptor pDes;@\\
\mbox{}\verb@ pIDrivable pDriv;@\\
\mbox{}\verb@ pMotor aEngine[MAXMOT];@\\
\mbox{}\verb@ MotEntry toStart[MAXMOT];@\\
\mbox{}\verb@ int iStart;@\\
\mbox{}\verb@ ObPar *aParameter;@\\
\mbox{}\verb@ }Amor2T;@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
\begin{description}
\item[pDes] The standard SICS object descriptor.
\item[pDriv] The drivable interface. The functions defined for the
drivable interface implement most of the work of this class.
\item[aEngine] An array of pointers to the motor data structures this
class has to deal with. The proper initialization of this is taken
care of during the initialization of the object.
\item[toStart] An array of motors to start when all calculations have
been performed.
\item[iStart] The number of valid entries in toStart.
\item[aParameter] An array of parameters for this object.
\end{description}
\subsubsection{The Interface}
The interface to this module is quite primitive. Most of the
functionality is hidden in the drivable interface. So there are only
functions for interacting with the interpreter.
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap3}
$\langle$amorinterface {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ typedef struct __AMOR2T *pAmor2T;@\\
\mbox{}\verb@@\\
\mbox{}\verb@ int Amor2TFactory(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@ int Amor2TAction(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@ void Amor2TKill(void *pData); @\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap4}
\verb@"amor2t.i"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*--------------------------------------------------------------------------@\\
\mbox{}\verb@ A m o r 2 T . i@\\
\mbox{}\verb@ Internal data structure definitions for Amor2T. For details see amor2t.tex.@\\
\mbox{}\verb@ DO NOT TOUCH! This file is automatically created from amor2t.w.@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Mark Koennecke, September 1999@\\
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
\mbox{}\verb@@$\langle$putput {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@@\\
\mbox{}\verb@@$\langle$amoredata {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap5}
\verb@"amor2t.h"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*-------------------------------------------------------------------------@\\
\mbox{}\verb@ A m o r 2 T@\\
\mbox{}\verb@ A class for controlling the two theta movement of a reflectometer. @\\
\mbox{}\verb@ Especially the AMOR reflectometer at SINQ. For details see the file @\\
\mbox{}\verb@ amor2t.tex. DO NOT TOUCH! This file is automatically created from amor2t.w@\\
\mbox{}\verb@ with nuweb.@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Mark Koennecke, September 1999@\\
\mbox{}\verb@---------------------------------------------------------------------------*/@\\
\mbox{}\verb@#ifndef AMOR2T@\\
\mbox{}\verb@#define AMOR2T@\\
\mbox{}\verb@@$\langle$amorinterface {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@#endif @\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}

View File

@ -0,0 +1,71 @@
\subsection{Amor Scan}
This is a special adaption of the general scan routines for the
reflectometer AMOR at SINQ. It works by replacing the configurable
routines in the general scan command with special ones, suited to the
reflectometers purpose. There are several adaptions to the standard
scan command:
\begin{itemize}
\item Data is written to NeXus files instead of ASCII files.
\item There are two counters to keep track of.
\item Furthermore stubs are provided for dealing with spin flippers.
\end{itemize}
In order to keep track of counters and monitors the following
convention has been devised:
\begin{itemize}
\item GetCounts gets the main detector.
\item GetMonitor 0 the second detector
\item GetMonitor 1 the first detector other spin
\item GetMonitor 2 the second detector other spin
\item GetMonitor 3 the first monitor
\item GetMonitor 4 the second monitor
\end{itemize}
Thus the monitor channels are used to keep the additional counter
information.
This module provides only one external function:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap1}
$\langle$amorscan {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ int ConfigureAmor(pScanData pScan);@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
which configures the variable fields and function pointers in pScan to
functions defined in this module. These then do the right thing. This
module is also an example of how the scan command can be configured to do
tricks based on the syntax and hooks defined in scan.*.
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap2}
\verb@"amorscan.h"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*-----------------------------------------------------------------------@\\
\mbox{}\verb@ A M O R S C A N@\\
\mbox{}\verb@ Adaption of the scan command to do things specific to the@\\
\mbox{}\verb@ reflectometer AMOR at SINQ.@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Mark Koennecke, September 1999@\\
\mbox{}\verb@-----------------------------------------------------------------------*/@\\
\mbox{}\verb@#ifndef AMORSCAN@\\
\mbox{}\verb@#define AMORSCAN@\\
\mbox{}\verb@@$\langle$amorscan {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@#endif@\\
\mbox{}\verb@@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}

138
doc/programmer/amorstat.tex Normal file
View File

@ -0,0 +1,138 @@
\subsection{Amor Status Display Support}
The reflectometer AMOR has a few unique status display requirements:
\begin{itemize}
\item In scan mode up to four detector counts curves must be shown for
the two counters in spin-up or spin-down mode. This needs to be
updated after each scan point.
\item Additionally user defined curves may need to be displayed.
\item The usual helper information muste be displayed.
\item In TOF mode it must be possible to define a region on the
detector whose summed counts are displayed versus the time
binning. This must be sent on request.
\end{itemize}
In order to cover all this a special object within SICS is required
which deals with all this and packages information in a status display
compliant way.
In order to do this the amorstatus object registers callbacks both
with the histogram memory and the scan object. These callback
functions are then responsible for updating the status displays. In
order for amorstatus to be able to do this, the client must register
itself with a special command.
In order to achieve all this some data structures are needed:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap1}
$\langle$asdata {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*---------------------------------------------------------------------*/@\\
\mbox{}\verb@ typedef struct {@\\
\mbox{}\verb@ float *fX, *fY;@\\
\mbox{}\verb@ int iNP;@\\
\mbox{}\verb@ char *name;@\\
\mbox{}\verb@ }UserData, *pUserData; @\\
\mbox{}\verb@/*---------------------------------------------------------------------*/@\\
\mbox{}\verb@ typedef struct __AMORSTAT {@\\
\mbox{}\verb@ pObjectDescriptor pDes;@\\
\mbox{}\verb@ pICallBack pCall;@\\
\mbox{}\verb@ int iUserList;@\\
\mbox{}\verb@ pScanData pScan;@\\
\mbox{}\verb@ pHistMem pHM;@\\
\mbox{}\verb@ int iTOF;@\\
\mbox{}\verb@ }AmorStat, *pAmorStat;@\\
\mbox{}\verb@ @\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
The fourth data structure is the amor status object data structure. It
has the following fields:
\begin{description}
\item[pDes] The standard SICS object descriptor.
\item[pCall] The callback interface.
\item[iUserList] A list of user data loaded data.
\item[pScan] A pointer to the scan object.
\item[pHM] A pointer to the histogram memory.
\item[iTOF] A flag which is true if we are taking measurements in TOF
mode.
\end{description}
In terms of a function interface this object has not much to
offer. Its main purpose is really as an interface to the status
display clients and thus it is configured through the interpreter
interface function. No need for other SICS objects to access it.
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap2}
$\langle$asinter {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ int AmorStatusFactory(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@ int AmorStatusAction(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@ void KillAmorStatus(void *pData);@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap3}
\verb@"amorstat.i"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*------------------------------------------------------------------------@\\
\mbox{}\verb@ A M O R S T A T U S@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Internal data structure definitions for the AMOR status display @\\
\mbox{}\verb@ facilitator object. DO NOT CHANGE. This file is automatically@\\
\mbox{}\verb@ created from amorstat.w.@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Mark Koennecke, September 1999@\\
\mbox{}\verb@---------------------------------------------------------------------*/@\\
\mbox{}\verb@@$\langle$asdata {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@ @\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap4}
\verb@"amorstat.h"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*------------------------------------------------------------------------@\\
\mbox{}\verb@ A M O R S T A T U S@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Public definitions for the AMOR status display @\\
\mbox{}\verb@ facilitator object. DO NOT CHANGE. This file is automatically@\\
\mbox{}\verb@ created from amorstat.w.@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Mark Koennecke, September 1999@\\
\mbox{}\verb@---------------------------------------------------------------------*/@\\
\mbox{}\verb@#ifndef AMORSTATUS@\\
\mbox{}\verb@#define AMORSTATUS@\\
\mbox{}\verb@@$\langle$asinter {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@#endif@\\
\mbox{}\verb@@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}

64
doc/programmer/bruker.tex Normal file
View File

@ -0,0 +1,64 @@
\subsubsection{Bruker Magnet Controller B-EC-1}
SANS is using a Bruker magnet controller. This controller is integrated
into SICS as a derivate of an environment controller. The Bruker controller
can be operated in two modes: in the first the current is controlled,
in the second the current
is controlled by an external hall sensor giving the magnetic field. Whatever
is the controlling sensor, the magnetic field and the current need to be
read. Furthermore this device supports switching the polarity. All this is
achieved with a special driver and an additional wrapper function for
handling extra commands. All this is implemented in the file bruker.h
and bruker.c. The functions defined are:
\begin{verbatim}
pEVDriver CreateBrukerDriver(int argc, char *argv[]);
int BrukerReadField(pEVControl self, float *fField);
int BrukerReadCurrent(pEVControl self, float *fCurrent);
int BrukerAction(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
\end{verbatim}
\begin{description}
\item[CreateBrukerDriver] creates a driver for the bruker magnet
controller.
\item[BrukerReadField] reads the current magnetic field.
\item[BrukerReadCurrent] reads the current current in Ampere.
\item[BrukerAction] a special SICS interpreter wrapper function for
the Bruker Magnet. This function handles the few special Bruker
commands and passes everything else to the standard environment
controller handler function.
\end{description}

81
doc/programmer/buffer.tex Normal file
View File

@ -0,0 +1,81 @@
\subsection{The LNS R\"unbuffer}
R\"unbuffers are a special LNS feature for handling instruments. Essentially
a R\"unbuffer is a list of commands which can be executed as a block. On
line editing of such a R\"unbuffer is supported as well. R\"unbuffers can
also be saved to or read from disk files. R\"unbuffers are related to the
batch file processing facility FileEval. However, there are subtle
differences. The first is I/O: When evaluating a batch file with FileEval
all messages except errors and warnings are suppressed. This is a nice
feature if the file evaluated contains a macro, where a user might be
confused when confronted with all internal messages. With R\"unbuffers all
output is written to the user. R\"unbuffers support only SICS commands, with
FileEval Tcl commands can be given as well.
It turned out that the R\"unbuffer system together with the R\"unlist
facility documented in the next section is rarely
used. Experimentators prefer the batch file facility ``fileeval''
instead. Consequently, this may be retracted and cleaned out in some
stage.
A R\"unbuffer is characterized by a an own data structure:
\begin{verbatim}
typedef struct {
pObjectDescriptor pDes; /* needed */
char *name; /* BufferName */
int iLineList; /* Handle to the Line List */
} RuenBuffer, *pRuenBuffer;
\end{verbatim}
The fields:
\begin{description}
\item[pDes] A pointer to the usual SICS object descriptor.
\item[name] The name of the R\"unbuffer.
\item[iLineList] The handle of the lldlist holding the lines of the
R\"unbuffer.
\end{description}
Interaction with R\"unbuffers happesn through the functions listed below.
All functions return 0 on failure or 1 on success, if not stated otherwise.
Most functions take as first parameter a pointer to the R\"unbuffer to act
upon.
\begin{description}
\item[pRuenBuffer CreateRuenBuffer(char *name)] creates a R\"unbuffer.
Returns the pointer to the new r\"unbuffer on success, or NULL on failure.
\item[void DeleteRuenBuffer(void *pSelf)] Deletes a R\"unbuffer.
\item[pRuenBuffer CopyRuenBuffer(pRuenBuffer pOld, char *NewName)] copies a
R\"unbuffer including all data lines. Returns NULL on failure, a pointer to
a new R\"unbuffer structure otherwise.
\item[int BufferAppendLine(pRuenBuffer self, char *line)] appends line to
r\"unbuffer self.
\item[int BufferDel(pRuenBuffer self, int iLine)] deletes line iLine from
r\"unbuffer self.
\item[int BufferInsertAfter(pRuenBuffer self, int iLine, char *line)]
inserts line line AFTER line number iLine in the RuenBuffer self.
\item[int BufferPrint(pRuenBuffer self, SConnection *pCon)]
lists the contents of the RuenBuffer on the Connection pCon.
\item[int BufferReplace(pRuenBuffer self, char *pattern, char *pReplace)]
replaces all occurences of the string pattern in the whole RuenBuffer
by the replacement string pReplace.
\item[int BufferRun(pRuenBuffer self, SConnection *pCon, SicsInterp *pSics)]
executes the lines of the Ruenbuffer one by one.
Returns 1 on success, 0 on error.
\item[int BufferSave(pRuenBuffer self, char *file)]
writes the contents of Ruenbuffer self to the file specified by
file.
Returns 1 on success, 0 on error.
\item[int BufferLoad(pRuenBuffer self, char *file)]
reads the contents of file into the RuenBuffer self.
Returns 1 on success, 0 on error.
\item[int InitBufferSys(SConnection *pCon, SicsInterp *pSics, void *pData,\\
int argc, char *argv[])] The factory function for the
R\"unbuffer system. Initialises the Buf command and the ruli command.
\item[int BufferCommand(SConnection *pCon, SicsInterp *pSics, void *pData,\\
int argc, char *argv[])] The object wrapper function
which implements the Buf command.
\item[int BufferAction(SConnection *pCon, SicsInterp *pSics, void *pData,\\
int argc, char *argv[])] The object wrapper function for
the R\"unbuffer itself.
\item[pRuenBuffer FindRuenBuffer(SicsInterp *pSics, char *name)] finds
r\"unbuffer name in the interpreter pSics. Returns a pointer to the
r\"unbuffers data structure if it exists, NULL otherwise.
\end{description}

75
doc/programmer/center.tex Normal file
View File

@ -0,0 +1,75 @@
\subsection{Fit and Center}
This is a fit routine for SICS. It takes a scan and tries to find a peak and
its position. Trials showed that fitting a gauss function is not robust
enough for this facility which has to cope with bizarre peak shapes, half
finished measurements and the like. The algorithm choosen tries to find the
center of gravity of the peak. It does this by searching for the maximum
point in the diagram first. Then the points where the peak is below
half maximum are searched for either side of the peak. Within these
limits the COG is calculated. When this is done fit will print some
info about the peak.
Center will the drive the scan variable to the COG of the peak.
The interface to this simple facility is simple:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap1}
$\langle$fitinter {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ typedef struct __FitCenter *pFit;@\\
\mbox{}\verb@@\\
\mbox{}\verb@/*--------------------------------------------------------------------------*/@\\
\mbox{}\verb@ pFit CreateFitCenter(pScanData pScan);@\\
\mbox{}\verb@ void DeleteFitCenter(void *pData);@\\
\mbox{}\verb@/*-------------------------------------------------------------------------*/@\\
\mbox{}\verb@ int CalculateFit(pFit self);@\\
\mbox{}\verb@ /* @\\
\mbox{}\verb@ CalcluateFit returns: -1 when left FWHM could not be found@\\
\mbox{}\verb@ -2 when right FWHM could not be found@\\
\mbox{}\verb@ 1 on success@\\
\mbox{}\verb@ */@\\
\mbox{}\verb@ int DriveCenter(pFit self, SConnection *pCon, SicsInterp *pSics);@\\
\mbox{}\verb@/*-------------------------------------------------------------------------*/@\\
\mbox{}\verb@ int FitFactory(SConnection *pCon,SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@ int FitWrapper(SConnection *pCon,SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@ int CenterWrapper(SConnection *pCon,SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap2}
\verb@"fitcenter.h"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*---------------------------------------------------------------------------@\\
\mbox{}\verb@ F I T C E N T E R@\\
\mbox{}\verb@@\\
\mbox{}\verb@ A simple peak finding and center of gravity determination facility for@\\
\mbox{}\verb@ SICS.@\\
\mbox{}\verb@@\\
\mbox{}\verb@ copyright: see copyright.h@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Mark Koennecke, October 1997@\\
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
\mbox{}\verb@#ifndef SICSFITCENTER@\\
\mbox{}\verb@#define SICSFITCENTER@\\
\mbox{}\verb@@$\langle$fitinter {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@#endif@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}

351
doc/programmer/choco.tex Normal file
View File

@ -0,0 +1,351 @@
\subsection{Chopper Controller}
Yet another way to deal with a controller has beenn devised for
SICS. This uses the concept of a general controller which can have
parameters enquired and set. Furthermore it may have parameters which
may be driven like a motor through a special adapter. This scheme is
used for the chopper controller for FOCUS.
\begin{itemize}
\item A driver for a particular controller which allows to set and get
parameters.
\item The general controller object which holds things together.
\item An adapter object which allows to drive special parameters in a general
controller. Such adapter objects can be configured for each drivable parameter
in a controller.
\end{itemize}
The test case for this way of doing things is a controller for running
choppers. This is why it gets the name.
The chopper system in question is the FOCUS chopper system. There are two
choppers, a fermi chopper and a disk chopper. This system can be run in two
different modes: In synchronous mode both choppers run at a
predefined ratio of speeds. For instance the fermi chopper is two
times faster then the disk chopper. This means, that setting a new
value for one chopper also changes the speed of the other chopper. In
asynchronous mode both choppers operate independently. Also the ration
to use for synchronous mode can be changed. Another parameter which
frequently changes is the phase of the two choppers. In order to
compensate for the fligh path between the two choppers there is a
small angular displacement of the choppers against each other which
varies with wavelength.
\subsubsection{The Controller Driver}
The controller driver is represented by the following data structure:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap1}
$\langle$codri {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ typedef struct __CODRI *pCodri;@\\
\mbox{}\verb@ typedef struct __CODRI {@\\
\mbox{}\verb@ int (*Init)(pCodri self);@\\
\mbox{}\verb@ int (*Close)(pCodri self);@\\
\mbox{}\verb@ int (*Delete)(pCodri self);@\\
\mbox{}\verb@ int (*SetPar)(pCodri self, @\\
\mbox{}\verb@ char *parname,@\\
\mbox{}\verb@ float fValue);@\\
\mbox{}\verb@ int (*SetPar2)(pCodri self, @\\
\mbox{}\verb@ char *parname,@\\
\mbox{}\verb@ char *value);@\\
\mbox{}\verb@ int (*GetPar)(pCodri self,@\\
\mbox{}\verb@ char *parname,@\\
\mbox{}\verb@ char *pBuffer,@\\
\mbox{}\verb@ int iBufLen);@\\
\mbox{}\verb@ int (*CheckPar)(pCodri self, @\\
\mbox{}\verb@ char *parname);@\\
\mbox{}\verb@ int (*GetError)(pCodri self, int *iCode,@\\
\mbox{}\verb@ char *pError, @\\
\mbox{}\verb@ int iErrLen);@\\
\mbox{}\verb@ int (*TryFixIt)(pCodri self, int iCode);@\\
\mbox{}\verb@ int (*Halt)(pCodri self);@\\
\mbox{}\verb@ char *pParList;@\\
\mbox{}\verb@ void *pPrivate;@\\
\mbox{}\verb@ }Codri;@\\
\mbox{}\verb@ @\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
All functions take a pointer to the controller driver itself as a
parameter. All functions except TryFixIt and CheckPar
return 0 on failure and 1 for success.
\begin{description}
\item[Init] initializes the controller driver. The parameters argc,
argv are main() style parameters for the initialization of the
controller driver.
\item[Close] closes the connection to the controller but does not delete a thing.
\item[Delete] closes the connection to the controller and deletes private data structures. Called when deleting the controller.
\item[SetPar] tries to set the parameter parname to the value
fValue. The last is floating point which covers the frequent
occurence of numeric values.
\item[SetPar2] The same as SetPar but uses test string as input for
parameter setting.
\item[GetPar] retrieves the parameter parname formatted as test. The
value is put into the buffer pBuffer. iBufLen is the maximum number of
bytes permissable for pBuffer.
\item[CheckPar] When parameters are driven a means is needed to find
out about the progress of operations and errors during the
operation. This is done by CheckPar for the parameter parname. The
return value of this function must be one of the HWBusy, HWError,
HWDone family documented in the motor driver object description.
\item[GetError] retrieves the last error. An integer error code is
placed into iCode and a textual description of the problem is written
to pError. Maximum iErrLen bytes are copied to pError.
\item[TryFixIt] tries to fix the error condition specified by iCode in
software if this possible. TryFisIt returns HWRedo if the last command
needs to resent, HWFault if the problem could not be fixed and HWOK if
the error can be ignored or was fully resolved.
\item[pParList] is text string containing a comma separated list of
all parameters understood by this driver.
\item[pPrivate] Is a pointer to a driver specific specific data
structure. This data structure will not be messed with by upper level code.
\end{description}
\subsubsection{The Controller Object}
This is the general controller object visible from the SICS
interpreter. This object allows to list all possible
parameters. Internal functions are provided for setting
parameters. But this is meant to be operated through a drive adapter
object (see below) in SICS. Thus the interface to this object
includes:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap2}
$\langle$chocoint {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ typedef struct __CHOCO *pChoco;@\\
\mbox{}\verb@/*------------------------------------------------------------------------*/@\\
\mbox{}\verb@ int CHGetParameter(pChoco self, char *pParName, @\\
\mbox{}\verb@ char *pParValue, int iBuflen); @\\
\mbox{}\verb@ @\\
\mbox{}\verb@ pCodri CHGetDriver(pChoco self);@\\
\mbox{}\verb@ int CHList(pChoco self, SConnection *pCon, char *name);@\\
\mbox{}\verb@/*------------------------------------------------------------------------*/@\\
\mbox{}\verb@ int ChocoAction(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@ int ChocoFactory(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@ @\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
\begin{description}
\item[CHGetParameter] retrieves the value of the parameter ParName
converted to text. Maximum iBufLen of result or error text are copied into the
buffer pParvalue.
\item[CHGetDriver] returns a pointer to the controller driver. This
function will be used by the drive adapters for interfacing with the
driver directly.
\item[CHList] prints a listing of all parameters to the client
described by pCon. name is the name of the controller.
\item[ChocoAction] is the SICS interpreter interface function for the
controller.
\item[ChocoFactory] is the SICS interpreter interface function which
installs a controller into SICS.
\end{description}
Most of the actual work of the controller is left to the driver. Thus
the internal data structure for a controller object is very simple:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap3}
$\langle$chocodata {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ typedef struct __CHOCO {@\\
\mbox{}\verb@ pObjectDescriptor pDes;@\\
\mbox{}\verb@ pCodri pDriv;@\\
\mbox{}\verb@ } Choco;@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
It consists just of the standard SICS object descriptor and a pointer
to the driver.
\subsubsection{The Drive Adapter}
Most of the work of the drive adaptor is hidden in the functions
implementing the drivable interface. Thus the interface to the
DriveAdapter is fairly simple:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap4}
$\langle$adapter {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ typedef struct __CHADAPTER *pCHAdapter;@\\
\mbox{}\verb@/*-----------------------------------------------------------------------*/@\\
\mbox{}\verb@ int CHAdapterFactory(SConnection *pCon, SicsInterp *pSics, @\\
\mbox{}\verb@ void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@ @\\
\mbox{}\verb@ int CHAdapterAction(SConnection *pCon, SicsInterp *pSics, @\\
\mbox{}\verb@ void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@ @\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
\begin{description}
\item[CHAdapterFactory] is the SICS interpreter factory function for
creating a drive adapter.
\item[CHAdapterAction] is the SICS interpreter function for
representing the object in SICS. Just a single action is supported:
request the value of the parameter.
\end{description}
The data structure for the drive adapter is slightly more interesting:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap5}
$\langle$adadata {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ typedef struct __CHADAPTER {@\\
\mbox{}\verb@ pObjectDescriptor pDes;@\\
\mbox{}\verb@ pCodri pDriv;@\\
\mbox{}\verb@ pIDrivable pInt;@\\
\mbox{}\verb@ float fUpper;@\\
\mbox{}\verb@ float fLower;@\\
\mbox{}\verb@ float fTarget;@\\
\mbox{}\verb@ char *pParName;@\\
\mbox{}\verb@ }CHAdapter;@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
\begin{description}
\item[pDes] is the standard object descriptor.
\item[pDriv] is a pointer to the controller driver.
\item[pInt] is a pointer to the drivable interface implemented by the
adapter.
\item[fUpper] upper limit for the parameter.
\item[fLower] lower limit for the parameter.
\item[pParName] is the name of the parameter which is driven through
this adapter.
\end{description}
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap6}
\verb@"codri.h"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*-------------------------------------------------------------------------@\\
\mbox{}\verb@ C o n t r o l l e r D r i v e r@\\
\mbox{}\verb@@\\
\mbox{}\verb@ This file contains the description of the data structure for a@\\
\mbox{}\verb@ general controller driver.@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Mark Koennecke, January 1998@\\
\mbox{}\verb@--------------------------------------------------------------------------*/@\\
\mbox{}\verb@#ifndef CODRIV@\\
\mbox{}\verb@#define CODRIV@\\
\mbox{}\verb@#define CHFAIL -1@\\
\mbox{}\verb@#define CHREDO -2@\\
\mbox{}\verb@#define CHOK -3@\\
\mbox{}\verb@@$\langle$codri {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@#endif@\\
\mbox{}\verb@@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap7}
\verb@"choco.h"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*-----------------------------------------------------------------------@\\
\mbox{}\verb@ C h o p p e r C o n t r o l l e r@\\
\mbox{}\verb@@\\
\mbox{}\verb@ This is both the header file for a general controller and a SICS@\\
\mbox{}\verb@ chopper controller.@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Mark Koennecke, January 1998@\\
\mbox{}\verb@--------------------------------------------------------------------------*/@\\
\mbox{}\verb@#ifndef CHOCOSICS@\\
\mbox{}\verb@#define CHOCOSICS@\\
\mbox{}\verb@#include "codri.h"@\\
\mbox{}\verb@@$\langle$chocoint {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@#ifdef CHOCOINTERNAL@\\
\mbox{}\verb@@$\langle$chocodata {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@#endif@\\
\mbox{}\verb@#endif @\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap8}
\verb@"chadapter.h"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*------------------------------------------------------------------------@\\
\mbox{}\verb@ C H a d a p t e r@\\
\mbox{}\verb@@\\
\mbox{}\verb@ This is the header file for a drive adapter for collaboration with a@\\
\mbox{}\verb@ general device controller as implemented in choco.*@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Mark Koennecke, January 1998@\\
\mbox{}\verb@--------------------------------------------------------------------------*/@\\
\mbox{}\verb@#ifndef SICSCHADA@\\
\mbox{}\verb@#define SICSCHADA@\\
\mbox{}\verb@#include "codri.h"@\\
\mbox{}\verb@@$\langle$adapter {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@#ifdef CHADAINTERNAL@\\
\mbox{}\verb@@$\langle$adadata {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@#endif@\\
\mbox{}\verb@#endif@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}
\subsubsection{To Do}
This scheme seems to be quite promising for handling many SICS
objects. The following enhancements could be considered. Allow to set
certain primitive parameters without a drivable interface. And add an
adapter for an environment variable in the controller.

108
doc/programmer/costa.tex Normal file
View File

@ -0,0 +1,108 @@
\subsection{The Command Stack}
This is a helper class to the connection class.
Each connection to a client has a command stack associated with it. The
command stack is a stack of command strings as generated by the SICS
clients. Commands are added to the top of the command queue by the network
reader. Each time the task associated with a connection runs one command
is popped from the command stack and executed. During execution the command
stack must be locked in order to prevent commands being accepted by tasks
busy waiting for some other process to finish.
Correspondingly, the interface to the command stack looks like this:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap1}
$\langle$costaint {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ typedef struct __costa *pCosta;@\\
\mbox{}\verb@@\\
\mbox{}\verb@/*----------------------------- live & death ----------------------------*/@\\
\mbox{}\verb@ pCosta CreateCommandStack(void);@\\
\mbox{}\verb@ void DeleteCommandStack(pCosta self);@\\
\mbox{}\verb@ int SetCommandStackMaxSize(pCosta self, int iNewSize);@\\
\mbox{}\verb@/*----------------------------------------------------------------------*/@\\
\mbox{}\verb@ int CostaTop(pCosta self, char *pCommand);@\\
\mbox{}\verb@ int CostaBottom(pCosta self, char *pCommand);@\\
\mbox{}\verb@ int CostaPop(pCosta self,char **pPtr);@\\
\mbox{}\verb@/*----------------------------------------------------------------------*/@\\
\mbox{}\verb@ void CostaLock(pCosta self);@\\
\mbox{}\verb@ void CostaUnlock(pCosta self);@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
Internally, two data structure need to be defined, the first for the
list implementing the command stack, the second for the command stack
itself.
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap2}
$\langle$costadat {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@@\\
\mbox{}\verb@/*------------------------------------------------------------------------*/@\\
\mbox{}\verb@ typedef struct __costa {@\\
\mbox{}\verb@ int iLock;@\\
\mbox{}\verb@ int iList;@\\
\mbox{}\verb@ int iMaxSize;@\\
\mbox{}\verb@ int iCount;@\\
\mbox{}\verb@ } Costa;@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap3}
\verb@"costa.h"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*-------------------------------------------------------------------------@\\
\mbox{}\verb@ C O S T A@\\
\mbox{}\verb@@\\
\mbox{}\verb@ A command stack implementation for SICS. To be used by each connection.@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Mark Koennecke, September 1997@\\
\mbox{}\verb@@\\
\mbox{}\verb@ copyright: see implementation file.@\\
\mbox{}\verb@@\\
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
\mbox{}\verb@#ifndef SICSCOSTA@\\
\mbox{}\verb@#define SICSCOSTA@\\
\mbox{}\verb@@$\langle$costaint {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@#endif@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap4}
\verb@"costa.i"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*---------------------------------------------------------------------------@\\
\mbox{}\verb@ C O S T A@\\
\mbox{}\verb@ Internal data structures for the command stack.@\\
\mbox{}\verb@--------------------------------------------------------------------------*/@\\
\mbox{}\verb@@$\langle$costadat {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}

180
doc/programmer/counter.tex Normal file
View File

@ -0,0 +1,180 @@
\subsection{The Counter}
This is the SICS object responsible for handling single counters and
monitors. As usual for SICS hardware objects the
counter is subdivided in a driver and a logical object. The driver will be
discussed first. The same concept with overlaying structures is used
for counters as for motors in order to allow for different drivers.
\subsubsection{The Counter Driver}
Counter drivers are polymorphic. This means that different drivers look the
same to the logical counter objects. This is achieved by having pointers to
functions in the driver. These pointers must be initialised by an actual driver
with functions which implement the required behaviour.
The counter driver is a large data structure defined below:
\begin{verbatim}
typedef struct __COUNTER {
/* variables */
char *name;
char *type;
CounterMode eMode;
float fPreset;
int iNoOfMonitors;
long lCounts[MAXCOUNT];
int iPause;
/* functions */
int (*GetStatus)(struct __COUNTER *self, float *fControl);
int (*Start)(struct __COUNTER *self);
int (*Pause)(struct __COUNTER *self);
int (*Continue)(struct __COUNTER *self);
int (*Halt)(struct __COUNTER *self);
int (*ReadValues)(struct __COUNTER *self);
int (*GetError)(struct __COUNTER *self, int *iCode,
char *error, int iErrLen);
int (*TryAndFixIt)(struct __COUNTER *self, int iCode);
void *pData; /* counter specific data goes here, ONLY for
internal driver use!
*/
} CounterDriver, *pCounterDriver;
\end{verbatim}
All functions take a pointer to a counter structure as first parameter. If
not described otherwise all functions return 0 on failure and 1 on success.
The fields have the following meanings:
\begin{description}
\item[name] The counter name in the system.
\item[type] A string describing the counter type.
\item[eMode] The counting mode of the counter. Can be eTimer for counting
till a preset time has passed or ePreset for counting until one of the
monitors has reached a certain count rate.
\item[fPreset] Depending on the count mode either the time to count or the
monitor rate to wait for for.
\item[iNoOfMonitors] The number of monitors handled by this counter.
\item[lCounts] An array which stores the counts in the array position 0, and
the monitor counts in the other fields of the array.
\item[iPause] A logical which is set when the counter is paused.
\item[GetStatus] GetStatus is the first of the functions a driver has to
define. GetStatus reads the counter status. Possible return values are:
\begin{description}
\item[HWIdle, OKOK] The counter is finished or idle.
\item[HWFault] A fault has been found at the counter instead of an
reasonable answer.
\item[HWNoBeam] There is currently no incident beam. This is usually
detected through a monitor which does not increase over time.
\item[HWPause] Counting has been paused.
\item[HWBusy] The counter is busy counting.
\end{description}
The parameter fControl is set to the current value of the counting control
variable. This can either be the counting time already passed or the count
rate of the control monitor in ePreset mode.
\item[Start] Starts counting with the current mode and preset parameters.
\item[Pause] pauses a counting operation.
\item[Continue] continues a paused counting operation.
\item[Halt] cancels a counting operation. This a emergency stop used when
interrupting an operation.
\item[ReadValues] reads the counter and the monitors in the lCounts array.
This gets automatically called through the TransferData routine of the
countable interface after a counting operations finishes. The point is that
data is transfered from the counter once and further requests operate on the
contents of the local array instead of bothering the hardware again.
\item[GetError] This gets called when an error has been detected during one
of the previous operations. The function has to return more information
about the error: iCode an driver dependent integer error code and maximum
iErrLen characters of problem description in error.
\item[TryAndFixIt] takes the integer error code returned in iCode from
GetError and tries to solve the problem with the hardware. This function can
either return COREDO which means the problem has been fixed and the
operation needs to redone or COTERM which means that it is not possible to
resolve the problem in software.
\item[pData] A pointer to a driver dependent data structure. Whereas the
fields above are required and expected by the counter module for a driver,
this is an area private to the actual driver.
\end{description}
As most of the action of the counter driver is done in the functions given
in its data structure only few functions are available in order to interact
with it:
\begin{description}
\item[pCounterDriver CreateCounterDriver(char *name, char *type)] creates a
general default counter driver structure.
\item[void DeleteCounterDriver(pCounterDriver self)] deletes a counter
driver.
\item[pCounterDriver NewEL737Counter(char *name, char *host, int iPort,
int iChannel)] creates a PSI--EL737 counter
driver. The counter box is meant to be reachable at the terminal server
host, listening at iPort and connected to channel iChannel at the macintosh.
\item[void KillEL737Counter(pCounterDriver self)] deletes an EL737 counter
driver.
\item[pCounterDriver NewSIMCounter(char *name)] creates a simulated counter
driver. Needed for software testing and instrument simulation.
\item[void KillSIMCounter(pCounterDriver self)] deletes a simulated counter
driver.
\end{description}
\subsubsection{The Logical Counter Object}
This is the object which represents the counter to the system. For all
actual hardware action the driver is called. The counter objects data
structure:
\begin{verbatim}
typedef struct {
pObjectDescriptor pDes;
char *name;
int isUpToDate;
int iExponent;
pICountable pCountInt;
pCounterDriver pDriv;
pICallBack pCall;
unsigned long tStart;
} Counter, *pCounter;
\end{verbatim}
The fields:\begin{description}
\item[pDes] The required object descriptor for any SICS object.
\item[name] The counters name in the system.
\item[isUpToDate] a logical which is true when counting is finished and the
data in the drivers lCount array represent the correct values.
\item[iExponent] The exponent to apply on preset values in monitor mode. At
SINQ monitor count rates in millions are usual. The exponent saves typing
all those 0's. Each monitor preset value given is multiplied by this value.
\item[pCountInt] A pointer to the countable interface.
\item[pDriv] A pointer to a counter driver for this counter.
\item[pCall] A pointer to the callback interface implemented by this
counter.
\item[tStart] The start time of the last counting operation.
\end{description}
Unlike the counter driver, there exist many functions for interaction with
the counter. Mosts functions take a pointer to a counter structure as first
parameter. In order to communicate error messages, functions which interact
with hardware take a pointer to a connection object as parameter.
\begin{description}
\item[pCounter CreateCounter(char *name, pCounterDriver pDriv)] Creates a
new counter object with name name and counter driver pDriv.
\item[void DeleteCounter(void *self)] deletes a counter object.
\item[int MakeCounter(SConnection *pCon, SicsInterp *pSics, void *pData,\\
int argc, char *argv[])] The counter object factory
function. The function to be hacked (plus DeleteCounter) when a new driver
needs to be introduced into the system.
\item[int SetCounterMode(pCounter self, CounterMode eNew)] sets a new
counter mode.
\item[CounterMode GetCounterMode(pCounter self)] requests the current
counter mode.
\item[int SetCounterPreset(pCounter self, float fVal)] sets a new preset
time or monitor.
\item[float GetCounterPreset(pCounter self)] returns the current preset time
or monitor.
\item[long GetCounts(pCounter self, SConnection *pCon)] returns the detector
counts.
\item[long GetMonitor(pCounter self, int iNum, SConnection *pCon)] returns
the monitor counts in monitor iNum. This function returns -1 when the
requetsed monitor does not exist.
\item[ GetNMonitor(pCounter self)] returns the number of monitors
available.
\item[int DoCount(pCounter self,float fPreset, SConnection *pCon, SicsInterp
*pSics)] does a count operation with fPreset as preset value.
\item[int CountAction(SConnection *pCon, SicsInterp *pSics, void *pData,\\
int argc, char *argv[])] The counter objects wrapper
function. This function defines the user interface to the counter object.
\end{description}

16
doc/programmer/cron.tex Normal file
View File

@ -0,0 +1,16 @@
\subsection{cron}
This module allows to install commands into SICS which will be repeated
periodically. The syntax is: sicscron intervall command. intervall is
the time intervall and command is the command to execute. A problem
is I/O becasue the original connection which installed the cron job
may be lost. Therefore cron commands are executed within the context
of special connection which does not do socket output. All I/O will be
logged into the command log though for control. As
this is a single system facility all data structure will be defined
in the implementation file. The public interface to this is just the
installation routine. This stuff is implemented in the files
sicscron.h and sicscron.c.
The installation routine installs another task into the SICS system
which will invoke the command to be executed at the predefined
intervalls.

92
doc/programmer/danu.tex Normal file
View File

@ -0,0 +1,92 @@
\subsection{Data Number}
In some points of its life SICS has to write data files. The file names
usually consist of a header, a serial number and an indicator for the
year. The serial number must be unique and steadliy increasing. In order to
achieve this, the serial number are written into a file after any change.
Incrementing the serial number thus involves the following steps:
\begin{itemize}
\item Open file and read current number.
\item Increment number
\item Write File and close
\end{itemize}
This little task is implemented in this module.
The interface to this looks like:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap1}
$\langle$dni {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ typedef struct __DataNumber *pDataNumber;@\\
\mbox{}\verb@@\\
\mbox{}\verb@ pDataNumber CreateDataNumber(char *pFilename);@\\
\mbox{}\verb@ void DeleteDataNumber(void *pData);@\\
\mbox{}\verb@@\\
\mbox{}\verb@ int IncrementDataNumber(pDataNumber self, int *iYear);@\\
\mbox{}\verb@@\\
\mbox{}\verb@ int DecrementDataNumber(pDataNumber self);@\\
\mbox{}\verb@@\\
\mbox{}\verb@ int DNWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@@\\
\mbox{}\verb@ int DEWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@@\\
\mbox{}\verb@ int DNFactory(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
\begin{description}
\item [CreateDataNumber] creates a data number data structure. It checks if
the file requested as parameter exists and asserts if not. Returns a pointer
on success, NULL else.
\item [DeleteDataNumber] deletes a data number structure form memory.
\item [IncrementDataNumber] is the main working function of this module.
It performs the steps listed above. It returns a new id for the data number
in case of success, a negative value otherwise. iYear is filled with a value
for the year.
\item[DecrementDataNumber] decrements the data number and is used for
implementing the killdata function. Whis is the invalidation of a
data file by overwriting it.
\item[DNWrapper] is the wrapper function which makes DataNumber accessible
from within SICS.
\item[DEWrapper] is the wrapper for the killdata functionality.
\item [DNFactory] is the SICS factory function which creates a Data Number
object from the initialisation file. Only parameter is the filename.
\end{description}
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap2}
\verb@"danu.h"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*-----------------------------------------------------------------------@\\
\mbox{}\verb@ D A T A N U M B E R@\\
\mbox{}\verb@@\\
\mbox{}\verb@ A module to provide a unique data number for data file writing.@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Mark Koennecke, Juli 1997@\\
\mbox{}\verb@ @\\
\mbox{}\verb@ copyright: see implementation file.@\\
\mbox{}\verb@@\\
\mbox{}\verb@---------------------------------------------------------------------------*/@\\
\mbox{}\verb@#ifndef SICSDATANUMBER@\\
\mbox{}\verb@#define SICSDATANUMBER@\\
\mbox{}\verb@@\\
\mbox{}\verb@@$\langle$dni {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@@\\
\mbox{}\verb@#endif@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}

322
doc/programmer/devexec.tex Normal file
View File

@ -0,0 +1,322 @@
\subsection{The Device Executor}
The Device Executor (devexec) is a core component of the system. It has to
fulfill three main tasks:
\begin{itemize}
\item Permit non--blocking hardware operations.
\item Ensure regular monitoring of running devices.
\item Ensure that only one client controls the hardware.
\end{itemize}
The devexec in its current form monitors driving and counting
operations only. The emonitor implements another monitor for
environment controllers.
Please note, that this module is quite crucial for the functioning of
SICS. Any changes here may have side effects throughout the whole
system. Be VERY careful with any changes. The current version does its job!
Some users want to continue typing commands while some hardware device is
still running. This is sensible, because some hardware devices require a
lot of time before they run to completion. Some people also require to count
while driving motors for quick overview measurements. This requirement was
the main reason for the invention of the devexec.
Of course, when devices are in operation it is needed to check on them
regularly in order to catch and report error conditions and in order to
find out when devices are finished with their job.
In a client server system many clients might issue commands to the hardware.
This could quickly lead into an undesirable form of chaos (There are
desirable forms of chaos, but not here!). In order to prevent this a means
is needed to ensure that at any given time only one client controls the
hardware. This function is also performed by the devexec.
The device executor also has to take care of special error conditions.
\subsubsection{Starting Devices}
These are the most important SICS operations. Environment controllers are
monitored by the environment monitor. Then here is a convention: {\bf Any
SICS object which
initiates driving or counting operations has to do so by registering this
operation with the devexec}. For this purpose the following interface
functions are provided.
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap1}
$\langle$devreg {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ int StartDevice(pExeList self, char *name, pObjectDescriptor pDes,@\\
\mbox{}\verb@ void *pData, SConnection *pCon, float fNew);@\\
\mbox{}\verb@ int StartMotor(pExeList self, SicsInterp *pSics, SConnection *pCon,@\\
\mbox{}\verb@ char *name, float fNew);@\\
\mbox{}\verb@ int StartCounter(pExeList self, SicsInterp *pSics, SConnection *pCon,@\\
\mbox{}\verb@ char *name); @\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
The main interface function is {\bf StartDevice}. The parameters are:
\begin{itemize}
\item {\bf self}. A pointer to the device executor in which SICS operates.
\item {\bf name}. The name of the object which operates.
\item {\bf pDes}. A pointer to the ObjectDescriptor of the object to drive or count.
\item {\bf pData}. A pointer to the data structure coming with the object.
\item {\bf pCon}. A pointer to the client connection on whose request the
operation was initiated.
\item {\bf fNew}. A floating point value which sets the target value for
drivable devices.
\end{itemize}
{\bf StartMotor, StartCounter} are just convenience wrappers around
StartDevice which retrieve objects from the SICS interpreter and calls
StartDevice thereafter.
Once invoked StartDevice takes care of the following operations:
\begin{itemize}
\item It first checks on the connection object. If nobody else is running
hardware it enters the connection object specifed as owner of the devexec in
its data structure. If an owner was already specified by a prior drive or
count request StartDevice checks if the connection requesting the new
operation is the same. If this is not the case, an error message about this
situation will be issued. If it is the case, i. e. the client requesting the
new operation is the same as the one who has reserved the devexec, the
operation is performed. This scheme reserves the devexec to one client.
\item If the authorisation is OK, StartDevice then proceeds to start the
drive or counting operation.
\item StartDevice then enters all information regarding
the running device into an list for future monitoring.
\item If it not already running a DevExecTask is registered with the
task module in order to ensure the monitoring of the devices running.
\end{itemize}
\subsubsection{Monitoring devices}
From within the SICS main loops this special function is called:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap2}
$\langle$devcheck {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ int CheckExeList(pExeList self);@\\
\mbox{}\verb@ /*@\\
\mbox{}\verb@ checks the entries for success and deletes entries which have finished@\\
\mbox{}\verb@ operation. If there are none left, the pOwner will be set to NULL.@\\
\mbox{}\verb@ */ @\\
\mbox{}\verb@ int Wait4Success(pExeList self);@\\
\mbox{}\verb@@\\
\mbox{}\verb@ long GetDevexecID(pExeList self);@\\
\mbox{}\verb@@\\
\mbox{}\verb@ int DevExecTask(void *pEL);@\\
\mbox{}\verb@ void DevExecSignal(void *pEL, int iSignal, void *pSigData);@\\
\mbox{}\verb@@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
CheckExeList then scan through its list of executing objects and request a
status from each of them. The next action depend on the status returned from
the device and any pending interrupts:
\begin{itemize}
\item If the device is still busy and no interrupts are pending, nothing
happens.
\item If there is a hardware error, this will be reported and apropriate
actions are intitiated depending on the type of problem and possible
interrupts being sets.
\item If a device is done, either naturally or due to an error or interrupt,
it is removed from devexec's list.
\item If the list is empty, the owner field of the devexec's datastructure
is reset to NULL. Then a new client is free to grab control over the
hardware.
\end{itemize}
{\bf DevExecTask} is the task function for the device executor. Calls
CheckExeList in the end. If all devices registered with the devexec
are finished running this function returns 0 and thus stops.
{\bf DevExecSignal} is the signal function for the device executor task.
{\bf Wait4Success} This function waits for the DevExecTask to
end. This is the case when the current devices running are finished.
There are occasions in the program where it is needed to wait for
an operation to complete before other tasks can be tackled. Wait4Success is
the function to call in such cases. Wait4Success returns DEVDONE for a
properly finished operation, DEVERROR for an operation which finished
with an error code and DEVINT for an aoperation which was interrupted
by the user.
\subsubsection{Influencing Execution}
In certain cases it is necessary to interact with running devices directly.
This is done via the following interface.
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap3}
$\langle$devstop {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ int StopExe(pExeList self, char *name);@\\
\mbox{}\verb@ int StopExeWait(pExeList self);@\\
\mbox{}\verb@ /*@\\
\mbox{}\verb@ will stop the entry name and its subentries from executing.@\\
\mbox{}\verb@ If ALL is specified as name, everything will be stopped and@\\
\mbox{}\verb@ the Executor cleared.@\\
\mbox{}\verb@ StopExeWait will stop all running things and wait for the stop@\\
\mbox{}\verb@ to complete.@\\
\mbox{}\verb@ */@\\
\mbox{}\verb@/*------------------------------------------------------------------------*/@\\
\mbox{}\verb@ void ClearExecutor(pExeList self);@\\
\mbox{}\verb@ /*@\\
\mbox{}\verb@ clears the executor without sending commands to the devices.@\\
\mbox{}\verb@ */@\\
\mbox{}\verb@/*-----------------------------------------------------------------------*/@\\
\mbox{}\verb@ int IsCounting(pExeList self);@\\
\mbox{}\verb@ int PauseExecution(pExeList self);@\\
\mbox{}\verb@ int ContinueExecution(pExeList self);@\\
\mbox{}\verb@@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
{\bf StopExe} tackles the interrupting of pending operations. This may
happen on a users request. StopExe then invokes a halt on that device.
As parameters, the name of a device to stop can be specified. If ALL is
given as name to StopExe all executing devices are stopped. Please note, that
this stop does not automatically finish the operation. Motors need some time
to stop, too. This function is usally called as consequence of an
interrupt.
{\bf ClearExecutor} clears the executor without invoking commands on the
devices. Is probably only used internally to clean out the executor.
I some cases, for example if a environment controller gets out of range, an
error handling strategy may want to pause counting until the problem has
been rectified and continue afterwards. {\bf PauseExecution, ContinueExecution}
take care of invoking the apropriate commands on all registered counting
devices.
\subsubsection{The Rest}
The rest of the interface includes initialisation and deletion routines
and some access routines. With the devexec being such an important system
component a function {\bf GetExecutor} is provided which retrieves a pointer
to the global SICS device executor.
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap4}
\verb@"devexec.h"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*----------------------------------------------------------------------------@\\
\mbox{}\verb@@\\
\mbox{}\verb@ D E V I C E E X E C U T O R@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Joachim Kohlbrecher wants to give several commands to the server@\\
\mbox{}\verb@ and than wait for them to happen before proceeding. Actually a useful@\\
\mbox{}\verb@ thing. A command will map to one or several positioning commands for a@\\
\mbox{}\verb@ device. This scheme is also useful for implementing objects which@\\
\mbox{}\verb@ drive several motors simulataneously, such as Monochromators. etc.@\\
\mbox{}\verb@ However, the whole thing is rather complicated.@\\
\mbox{}\verb@ @\\
\mbox{}\verb@ It is forbidden, that several clients drive the instrument. In order@\\
\mbox{}\verb@ to ensure this the Executor remembers the connection which emitted the@\\
\mbox{}\verb@ first command. Subsequent AddExeEntries from different clients will@\\
\mbox{}\verb@ be rejected. The owner will be reset when the execution is found finished@\\
\mbox{}\verb@ in calls to CheckExe, Wait4Success or StopExe.@\\
\mbox{}\verb@ @\\
\mbox{}\verb@ @\\
\mbox{}\verb@ Mark Koennecke, December 1996@\\
\mbox{}\verb@ @\\
\mbox{}\verb@ copyright: see implementation file@\\
\mbox{}\verb@---------------------------------------------------------------------------*/@\\
\mbox{}\verb@#ifndef SICSDEVEXEC@\\
\mbox{}\verb@#define SICSDEVEXEC@\\
\mbox{}\verb@#include "obdes.h"@\\
\mbox{}\verb@#include "task.h"@\\
\mbox{}\verb@@\\
\mbox{}\verb@ typedef struct __EXELIST *pExeList;@\\
\mbox{}\verb@@\\
\mbox{}\verb@/* Returncodes */@\\
\mbox{}\verb@@\\
\mbox{}\verb@#define DEVDONE 1@\\
\mbox{}\verb@#define DEVINT 0@\\
\mbox{}\verb@#define DEVERROR 2@\\
\mbox{}\verb@#define DEVBUSY 3@\\
\mbox{}\verb@@\\
\mbox{}\verb@/*------------------------------------------------------------------------@\\
\mbox{}\verb@ B I R T H & D E A T H@\\
\mbox{}\verb@*/@\\
\mbox{}\verb@ pExeList CreateExeList(pTaskMan pTask);@\\
\mbox{}\verb@ void DeleteExeList(void *self);@\\
\mbox{}\verb@ @\\
\mbox{}\verb@/* ================= Functions to talk to the above ====================== */@\\
\mbox{}\verb@@$\langle$devreg {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@/*------------------------------------------------------------------------*/@\\
\mbox{}\verb@@$\langle$devcheck {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@@\\
\mbox{}\verb@ /*@\\
\mbox{}\verb@ Waits for execution to finish. returns 1 on Success, 0 if problems@\\
\mbox{}\verb@ ocurred. Than the Interrupt code shall be checked and acted upon@\\
\mbox{}\verb@ accordingly.@\\
\mbox{}\verb@ */@\\
\mbox{}\verb@@\\
\mbox{}\verb@/*-------------------------------------------------------------------------*/@\\
\mbox{}\verb@ SConnection *GetExeOwner(pExeList self);@\\
\mbox{}\verb@/*-------------------------------------------------------------------------*/@\\
\mbox{}\verb@ int isInRunMode(pExeList self);@\\
\mbox{}\verb@/*--------------------------------------------------------------------------*/@\\
\mbox{}\verb@ int ListPending(pExeList self, SConnection *pCon);@\\
\mbox{}\verb@ /*@\\
\mbox{}\verb@ lists the Operations still pending on pCon. @\\
\mbox{}\verb@ */@\\
\mbox{}\verb@/*-------------------------------------------------------------------------*/@\\
\mbox{}\verb@@$\langle$devstop {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@/*-------------------------- Commands ------------------------------------*/@\\
\mbox{}\verb@ int StopCommand(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@ /*@\\
\mbox{}\verb@ implements the stop command@\\
\mbox{}\verb@ */@\\
\mbox{}\verb@ @\\
\mbox{}\verb@ int ListExe(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@@\\
\mbox{}\verb@ /*@\\
\mbox{}\verb@ lists all currently executing objects@\\
\mbox{}\verb@ */@\\
\mbox{}\verb@ int Success(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@ /*@\\
\mbox{}\verb@ waits until completion of all pending operations. Used in@\\
\mbox{}\verb@ connection with non blocking operation such as motors started@\\
\mbox{}\verb@ with run.@\\
\mbox{}\verb@ */@\\
\mbox{}\verb@ @\\
\mbox{}\verb@/* -------------------------- Executor management -------------------------*/@\\
\mbox{}\verb@ @\\
\mbox{}\verb@ pExeList GetExecutor(void);@\\
\mbox{}\verb@ void SetExecutor(pExeList pExe);@\\
\mbox{}\verb@ @\\
\mbox{}\verb@#endif @\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}

52
doc/programmer/difrac.tex Normal file
View File

@ -0,0 +1,52 @@
\subsection{The Difrac Subsystem}
Difrac is a F77 package for controlling a four circle diffractometer
developed by P. Gabe and White for PC's. This package became only
available very late. This package has been included into SICS for four
circle diffraction. All the code for the difrac package resides in the
difrac subdirectory to sics. For more information about the difrac
system see the documentation coming with difrac. In order to
integrate difrac into SICS the following steps had to be taken:
\begin{itemize}
\item Define an interface from SICS to DIFRAC.
\item Modify the DIFRAC hardware control to run the hardware through
SICS.
\item Adapt I/O
\item Modify DIFRAC to be a subsystem instead of a program of its own.
\item Adapt measurement procedures to the special needs of TRICS.
\end{itemize}
\subsubsection{The Interface SICS to DIFRAC}
This is implemented in difrac.c. It it is just a interface wrapper
function which takes the command given and forwards it to the DIFRAC
interpreter. A tricky bit about this ist, that this module has to keep
track of which cconnection issued the command. This is done through a
connection stack.
\subsubsection{DIFRAC HW control}
DIFRAC controls the hardware through a couple of function originally
defined in the file ralf.f. This file has been replaced by a file
trics.f which in turn calls C-functions implemented in difrac.c which
do the actual job.
\subsubsection{DIFRAC I/O}
In contrast to many F77 prograsm DIFRAC has a very intelligent I/O
system. All input is channelled through the function GETLIN in
gwrite.f. This function has been modified to call a C-function which
gets a line of input from SICS. This adpater is again in difrac.c. All
output is printed first into a internal string buffer, COUT, and then
printed using the function GWRITE. This function has been modified to
call a C-function which writes the output to a SICS connection. The
integration of DIFRAC into SICS was only possible because of the
existence of this I/O system.
\subsubsection{Changes in DIFRAC}
The DIFRAC main program was taken apart into a initialisation routine
(difini.f) and a callable interpreter function (difint.f). Further
changes were required because TRICS does not do continous scans in the
way a X-ray four circle diffractometer does. DIFRAC's concept of a
scan drives a motor slowly and collects data. This has been modified
to do step scans for TRICS. Some commands which do not make sense
within SICS have been disabled. Some little changes to measurement
routines were necessary.

48
doc/programmer/dmc.tex Normal file
View File

@ -0,0 +1,48 @@
\subsection{DMC module}
This module initialises all DMC specific commands. Currently there is only
one: StoreData. This does not do much, it is just here as a container for
things to come.
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap1}
$\langle$Protos {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ int InitDmc(SConnection *pCon, SicsInterp *pSics, void *pData, @\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap2}
\verb@"dmc.h"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*-------------------------------------------------------------------------@\\
\mbox{}\verb@ D M C @\\
\mbox{}\verb@@\\
\mbox{}\verb@ this modules purpose is solely to initialise the commands specific to@\\
\mbox{}\verb@ the powder diffractometer DMC.@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Mark Koenencke, March 1997@\\
\mbox{}\verb@ @\\
\mbox{}\verb@ copyright: see implementation file.@\\
\mbox{}\verb@@\\
\mbox{}\verb@--------------------------------------------------------------------------*/@\\
\mbox{}\verb@#ifndef SICSDMC@\\
\mbox{}\verb@#define SICSDMC@\\
\mbox{}\verb@@$\langle$Protos {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@#endif@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}

30254
doc/programmer/dmccom.eps Normal file

File diff suppressed because it is too large Load Diff

BIN
doc/programmer/dmccom.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

22
doc/programmer/drive.tex Normal file
View File

@ -0,0 +1,22 @@
\subsection{The Drive and Run Command}
This command implements driving of real motors or virtual motors (variables
which control multiple motors). The drive command has no associated data
structure going with it. There are just a few function:
\begin{description}
\item[int Drive(SConnection *pCon,SicsInterp *pSics, char *name, float
fNew)] drives motor name to fNew and waits for the motor to finish. Possible
errors will be written to the connection object pCon.
\item[int Start2Run(SConnection *pCon, SicsInterp *pSics, char *name, float
fNew)] starts the motor name to run to fNew. This
function will NOT wait for the motor to get there. In spite of this,
possible errors will be printed to the connection object pCon.
\item[int DriveWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])] the object wrapper
function for the drive command.
\item[int RunWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])] the object wrapper
function for the run command.
\item[int MakeDrive(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])]
The factory command which installs the drive and run commands into SICS.
\end{description}

140
doc/programmer/dynar.tex Normal file
View File

@ -0,0 +1,140 @@
\subsection{Dynamic Array}
This section describes a dynamic array of arbitrary pointers. Dynamic means,
that the array gets enlarged automatically when an index outside of the
current bounds has been requested. Negative values are supported as well.
The interface to this module looks like this:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap1}
$\langle$dynarint {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ typedef struct __SDynar *pDynar;@\\
\mbox{}\verb@/*-------------------------------------------------------------------------*/@\\
\mbox{}\verb@ pDynar CreateDynar(int iStart, int iEnd, int iGrain, @\\
\mbox{}\verb@ void (*DataFree)(void *pData));@\\
\mbox{}\verb@ void DeleteDynar(pDynar self);@\\
\mbox{}\verb@/*------------------------------------------------------------------------*/@\\
\mbox{}\verb@ int DynarPut(pDynar self, int iIndex, void *pData);@\\
\mbox{}\verb@ int DynarPutCopy(pDynar self, int iIndex, void *pData, int iDataLen);@\\
\mbox{}\verb@ int DynarReplace(pDynar self, int iIndex, void *pData, int iDatLen);@\\
\mbox{}\verb@ @\\
\mbox{}\verb@ int DynarGet(pDynar self, int iIndex, void **pData);@\\
\mbox{}\verb@ int DynarGetCopy(pDynar self, int iIndex, void *pData, int iDataLen);@\\
\mbox{}\verb@@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
If not stated otherwise, all functions return 1 on success and 0 on failure.
\begin{description}
\item[CreateDynar] creates a new dynamic array. On success a pointer to a
new dynamic array is returned, else NULL. The parameters are: iStart, the
initial start index of the array, iEnd, the initial end index of the array,
iGrain, the packet of new space to allocate when the array is enlarged
dynamically, DataFree, a function which takes a pointer to one of the data
items stored in the dynamic array and the free's all the memory associated
with the data item. DataFree will be used automatically by Dynar for
releasing memory when data items are replaced or the whole array is deleted.
\item[DeleteDynar] removes the dynamic arary from memory. The pointer to
self will point to rubbish afterwards and shall not be used.
\item[DynarPut] puts the pointer pData at position iIndex in the dynamic
array. pData needs to be allocated from dynamic memory, otherwise you'll
experience core dumps. A data item which was previously at the position
denoted by iIndex will be freed.
\item[DynarPutCopy] does the same as DynarPut, but copies the data item.
iDataLen bytes of new memory will be allocated and the data from pData be
put into it. Then this will be entered into the dynamic array at position
iIndex.
\item[DynarReplace] replaces the data at iIndex by the data pointed to by
pData by a memcpy. If there was no data defined previously, this call has
the same effect as DynarPutCopy.
\item[DynarGet] retrieves the pointer pData at position iIndex from the dynamic
array.
\item[DynarGetCopy] copies iDataLen bytes from the data at position iIndex
into the buffer pData. pData must be large enough to hold iDataLen bytes.
\end{description}
Nowe, here is the definition of the internal datastructure for the
dynamic array class.
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap2}
$\langle$dynardat {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ typedef struct __SDynar {@\\
\mbox{}\verb@ int iStart;@\\
\mbox{}\verb@ int iEnd;@\\
\mbox{}\verb@ int iGrain;@\\
\mbox{}\verb@ void **pArray;@\\
\mbox{}\verb@ void (*DataFree)(void *pData);@\\
\mbox{}\verb@ } Dynar;@\\
\mbox{}\verb@ @\\
\mbox{}\verb@ @\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap3}
\verb@"sdynar.h"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*---------------------------------------------------------------------------@\\
\mbox{}\verb@ D Y N A M I C A R R A Y@\\
\mbox{}\verb@@\\
\mbox{}\verb@ This file describes the interface to a dynamic array module for pointers.@\\
\mbox{}\verb@ This sort of array resizes dynamically.@\\
\mbox{}\verb@ @\\
\mbox{}\verb@ Mark Koennecke, September 1997@\\
\mbox{}\verb@@\\
\mbox{}\verb@ copyright: see copyright.h@\\
\mbox{}\verb@@\\
\mbox{}\verb@-----------------------------------------------------------------------------*/@\\
\mbox{}\verb@#ifndef SICSDYNAR@\\
\mbox{}\verb@#define SICSDYNAR@\\
\mbox{}\verb@@$\langle$dynarint {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@#endif@\\
\mbox{}\verb@@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap4}
\verb@"sdynar.i"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*----------------------------------------------------------------------------@\\
\mbox{}\verb@ D Y N A M I C A R R A Y@\\
\mbox{}\verb@@\\
\mbox{}\verb@ This file defines the internal data structure used by the dynamic@\\
\mbox{}\verb@ array module.@\\
\mbox{}\verb@ @\\
\mbox{}\verb@ More info: see sdynar.h@\\
\mbox{}\verb@-----------------------------------------------------------------------------*/@\\
\mbox{}\verb@@$\langle$dynardat {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}

218
doc/programmer/emonitor.tex Normal file
View File

@ -0,0 +1,218 @@
\subsection{SICS Sample Environment Handling}
In addition to driving motors and counting SICS has to take care of sample
environment devices as well. These can be temperature controllers, current
controllers etc. It can be assumed, that SICS has to take care of
intelligent sample environment devices only, i. e. devices which do their
own realtime processing. SICS, however, has to implement the logic to drive
an environment controller to a new value. Furthermore SICS has to do the
error handling when an environment controller fails. In order to do this the
following software components will be needed:
\begin{itemize}
\item An environment monitor. This component will register any active
environment control device. A test function will be called from the main
loop which checks for controller out of range and initiates error handling.
\item A new interface, the environment interface (see \ref{interface}).
\item Controller objects. One for each environment controller. Again, the
SICS distinction between logical objects and hardware drivers will be
maintained.
\end{itemize}
Controller objects will be able to share some code among them. Each
environemnt controller will hold a target value, a permissable tolerance,
a selctor variable which defines the type of error handling to perform and
an interrupt code to issue when that form of error handling is choosen.
Furthermore each environment controller needs to implement the drivable
interface (for driving to new values) and the environment interface (for
monitoring the controller). Controller object will also share the error
handling during the monitor phase between them. The scheme is that each controller will have a
variable which selects the error handling mechanism. Depending on this
variable an error managment routine will be invoked. Current two schemes for
handling errors are supported:
\begin{itemize}
\item Print a warning but do nothing else.
\item Interrupt: an interrupt will be issued.
\item Pause: the measurement will be paused.
\item Try to drive to a safe value. This may be used to rescue a oven
gone haywire by setting a low setpoint where the device is safe.
\end{itemize}
This scheme allows for adding more error handling strategies when necessary
and to implement them in one place for all environment controllers.
Consequently, there will be some some general controller code in files
evcontrol.*. In the object oriented paradigm environment controller would
inherit from this general controller. This is implemented by delegation in
SICS.
Please note, that any environment device has three modes of
operation. The first, trivial one, is idle. The second one is the driving
phase. This phase is entered when a drive or run command tries to set the
controller to a new value. Once this target has been reached a environment
controller will be registered in the environment monitor which will take
care of monitoring the controller during its operation. This is the
third stage: inMonitor.
\subsection{The Environment Monitor}
The environment monitors (emon) task is to register all active environment
controllers. It will be called from the main loop to check if each
registered environment controller is still within tolerances. If not, emon
has to enforce error processing. Else it does nothing.
The environment monitor uses the following datastructures:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap1}
$\langle$emondat {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ typedef struct __EnvMon {@\\
\mbox{}\verb@ pObjectDescriptor pDes;@\\
\mbox{}\verb@ int iList;@\\
\mbox{}\verb@ int iEnd;@\\
\mbox{}\verb@ } EnvMon;@\\
\mbox{}\verb@/*---------------------------------------------------------------------------*/@\\
\mbox{}\verb@ typedef struct {@\\
\mbox{}\verb@ pDummy pDum;@\\
\mbox{}\verb@ char *pName;@\\
\mbox{}\verb@ pEVInterface pInter;@\\
\mbox{}\verb@ } EVEntry, *pEVEntry; @\\
\mbox{}\verb@@\\
\mbox{}\verb@@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
As it it will be accessible as SICS object emon needs an object descriptor.
The other data member is a list of active controllers.
The EVEntry structure contains the data held in the list for each active
controller. It is, disguised as pDum, a pointer to the controllers
datastructure, the name of the controller, and the environment interface of
the controller.
The following interface is implemented by the environment monitor:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap2}
$\langle$emonint {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@@\\
\mbox{}\verb@ pEnvMon CreateEnvMon(void);@\\
\mbox{}\verb@ void DeleteEnvMon(void *pData);@\\
\mbox{}\verb@@\\
\mbox{}\verb@ int EVRegisterController(pEnvMon self, char *pName, void *pData,@\\
\mbox{}\verb@ SConnection *pCon);@\\
\mbox{}\verb@ int EVUnregister(pEnvMon self, char *name);@\\
\mbox{}\verb@ @\\
\mbox{}\verb@ int EVMonitorControllers(pEnvMon self);@\\
\mbox{}\verb@@\\
\mbox{}\verb@ int EVList(pEnvMon self, SConnection *pCon);@\\
\mbox{}\verb@@\\
\mbox{}\verb@ int EVWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@@\\
\mbox{}\verb@ pEnvMon FindEMON(SicsInterp *pSics);@\\
\mbox{}\verb@ @\\
\mbox{}\verb@ int EnvMonTask(void *pEv);@\\
\mbox{}\verb@ void EnvMonSignal(void *pEndv, int iSignal, void *pSigData);@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
{\bf CreateEnvMon} initialises a emon data structure. As usual it returns
NULL on error, a pointer to a new structure on success.
{\bf DeleteEnvMon} deletes and emon data structure and frees all memory
associated with it.
{\bf EVRegisterController} registers a controller for monitoring. The
parameters are:
\begin{itemize}
\item {\bf self}. A pointer to the environment monitor where to register the
controller.
\item {\bf pName}. The name of the controller object.
\item {\bf pData}. A pointer to the data structure belonging to the
controller object.
\item {\bf pCon}. A pointer to the client connection to which erros shall be
reported.
\end{itemize}
{\bf EVUnregister} Removes the controller name from the monitoring list.
{\bf EVMonitorControllers} is the function which will be called from the
main loop and which is responsible for monitoring the registered
controllers.
{\bf EVList} prints a status report about the emon to the Connection object
specified.
{\bf EVWrapper} is the wrapper function necessary to make the emon
available from SICS. The user may interact with the emon through SICS. The
user will be enabled to list the currently registered environment
controllers and their current state and to register and unnregister
controllers.
{\bf EnvMonTask} is the task function associated with the environment
monitor. This is called by the task handling object and eventually
invokes EVMonitorControllers for checking on the environment
controllers configured into SICS.
{\bf EnvMonSignal} is the signale handler for the environment monitor task.
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap3}
\verb@"emon.h"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*--------------------------------------------------------------------------@\\
\mbox{}\verb@ E N V I R O N M E N T M O N I T O R@\\
\mbox{}\verb@@\\
\mbox{}\verb@ The environment monitor is responsible for monitoring active environment@\\
\mbox{}\verb@ devices. @\\
\mbox{}\verb@@\\
\mbox{}\verb@ Mark Koennecke, Juli 1997@\\
\mbox{}\verb@@\\
\mbox{}\verb@ copyright: see implementation file.@\\
\mbox{}\verb@ doc: programmers reference.@\\
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
\mbox{}\verb@#ifndef SICSEMON@\\
\mbox{}\verb@#define SICSEMON@\\
\mbox{}\verb@ typedef struct __EnvMon *pEnvMon;@\\
\mbox{}\verb@/*-------------------------------------------------------------------------*/@\\
\mbox{}\verb@@$\langle$emonint {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@#endif@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap4}
\verb@"emon.i"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*--------------------------------------------------------------------------@\\
\mbox{}\verb@ Internal header file defining the datastructure for the environment@\\
\mbox{}\verb@ controller.@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Mark Koennecke, Juli 1997@\\
\mbox{}\verb@---------------------------------------------------------------------------*/@\\
\mbox{}\verb@@$\langle$emondat {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}

View File

@ -0,0 +1,321 @@
\subsection{Environment Controller}
An environemnet controller controls a piece of sample environemnet
equipment. Thereby it does not really matter if the device in question
is a temperature controller or a magnet or whatever. All devices need
to be driven to a new value and there must be some scheme for
monitoring the device during a measurement. This monitoring is done by the
environment monitor described in the kernel section of this book.
Then there must be some type of logging facility. SICS defers logging to
a separate module, the varlogger.
The Environment Controller (EVControl) is a kind of base class for all
environment devices. This poses the question how SICS implements
inheritance. The scheme is simple:
\begin{itemize}
\item The base class (in this case EVControl) will hold a void pointer.
Derived classes are meant to add their datastructures at that level.
Furthermore derived classes are required to provide a function, which
deletes its private data.
\item When overloading functions of the base class, the derived class
should call the overloaded function of the base class whenever apropriate.
\end{itemize}
\subsubsection{Environment Controller Datastructures}
To enhance understanding of this, see the definition of the datastructure
used by EVControl:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap1}
$\langle$evdata {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ typedef struct __EVControl {@\\
\mbox{}\verb@ pObjectDescriptor pDes;@\\
\mbox{}\verb@ pIDrivable pDrivInt;@\\
\mbox{}\verb@ pEVInterface pEnvir;@\\
\mbox{}\verb@ pEVDriver pDriv;@\\
\mbox{}\verb@ EVMode eMode;@\\
\mbox{}\verb@ float fTarget;@\\
\mbox{}\verb@ char *pName;@\\
\mbox{}\verb@ ObPar *pParam;@\\
\mbox{}\verb@ int iLog;@\\
\mbox{}\verb@ pVarLog pLog;@\\
\mbox{}\verb@ int iWarned;@\\
\mbox{}\verb@ int iTcl;@\\
\mbox{}\verb@ int iStop;@\\
\mbox{}\verb@ void *pPrivate;@\\
\mbox{}\verb@ void (*KillPrivate)(void *pData);@\\
\mbox{}\verb@ } EVControl;@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
The first field is a pointer to the usual object descriptor,
the second field a pointer to an Drivable interface. Each environment
controller needs to implement that in order to allow SICS drive the device
to a new value. The third field is a pointer to an environment interface.
This is needed in order to enable monitoring of the device when it has
reached its target value. The fourth field is a pointer to the driver for
the actual hardware. Next is the mode the device is in. Of course there
must be floating point value which defines the current target value for the
device. pName is a pointer to a string representing the name of the
controller. Then there is a
parameter array. iLog is a boolean which says if data should be logged
for this controller or not. pLog is the a pointer to a Varlog structure
holding the logging information. Then there is a switch, iWarned, which is
used to prevent execessive output on environment controller error handling.
iTcl is a boolean stating if the driver used is a proper C language driver
or a Tcl driver.
This is followed by the void pointer for use by a derived
class. KillPrivate is a pointer to a function capable of deleting pPrivate
properly.
For the hardware drivers for environment controllers a similar scheme is
used:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap2}
$\langle$evdriv {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ typedef struct __EVDriver {@\\
\mbox{}\verb@ int (*SetValue)(pEVDriver self, float fNew);@\\
\mbox{}\verb@ int (*GetValue)(pEVDriver self, float *fPos);@\\
\mbox{}\verb@ int (*Send)(pEVDriver self, char *pCommand,@\\
\mbox{}\verb@ char *pReplyBuffer, int iReplBufLen); @\\
\mbox{}\verb@ int (*GetError)(pEVDriver self, int *iCode,@\\
\mbox{}\verb@ char *pError, int iErrLen);@\\
\mbox{}\verb@ int (*TryFixIt)(pEVDriver self, int iCode);@\\
\mbox{}\verb@ int (*Init)(pEVDriver self);@\\
\mbox{}\verb@ int (*Close)(pEVDriver self);@\\
\mbox{}\verb@ void *pPrivate;@\\
\mbox{}\verb@ void (*KillPrivate)(void *pData);@\\
\mbox{}\verb@ } EVDriver;@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
If not stated otherwise, member functions return 0 on failure and 1 on
success.
This datastructure in detail: \begin{description}
\item [SetValue] Sends a command to the environment device which drives it
to a new value specified as second parameter. Translation to device specific
values is done here. If an error occurs, SetValue returns 0, else 1.
\item [GetValue] Asks the device its current measured value.
If an error occurs, GetValue returns 0, 1 on success and -1 when there is
data pending. GetValue will be used for enquiring status. Some devices have
such a slow response that the first call will issue the command and the next
ones will check for data availability and read eventually.
\item [Send] Sends the command in pCommand to the environment device. For
replies, a pointer to a ReplyBuffer is provided. iReplBufLen is the maximum
length permissable for the ReplyBuffer. Send copies maximum iReplBufLen
bytes into pReplyBuffer in order to prevent memory overwrite. The idea of
send is to provide a means to load calibration data and parameters to the
environment device.
\item [GetError] GetError will be called when an error occurs. It is meant
to set iCode to an internal error code and fill pError with an textual
description of the error observed. Maximum iErrLen bytes of information
will be copied to pError.
\item [TryFixIt] TryFixIt will be called with the internal error code
retuned by GetError in iCode as second parameter. TryAndFixIt then analyses
the error code and figures out if something can be done in software to fix
the problem. If so, the apropriate actions are performed. TryFixIt returns
either DEVOK, if the device is OK, DEVFAULT, if TryFixIt cannot fix the
problem and DEVREDO if TryFixIt manged to fix the problem but requires the
last command to be resent.
\item [Init] Init is meant to initialise or reinitialise the driver.
\item [Close] Close is meant to close the driver and bring the device into a
safe state.
\item [pPrivate] is a pointer to a driver specific datastructure.
\item [KillPrivate] is a pointer to a function which is capable of removing
a drivers specific datastructure properly.
\end{description}
\subsubsection{Environment Controller Funtions}
All of the functions below return 1 on success, 0 on failure if not sated
otherwise. Most functions take a pointer to an environment controller
data structure as first parameter.
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap3}
$\langle$dvfunc {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*--------------------------- live & death --------------------------------*/ @\\
\mbox{}\verb@ typedef struct __EVControl *pEVControl;@\\
\mbox{}\verb@ typedef struct __EVDriver *pEVDriver;@\\
\mbox{}\verb@@\\
\mbox{}\verb@ pEVControl CreateEVController(pEVDriver pDriv, char *pName, int *iErr);@\\
\mbox{}\verb@ void DeleteEVController(void *pData);@\\
\mbox{}\verb@@\\
\mbox{}\verb@/*-------------------------- driving ---------------------------------*/@\\
\mbox{}\verb@ int EVCDrive(pEVControl self,SConnection *pCon, float fNew);@\\
\mbox{}\verb@ int EVCGetPos(pEVControl self, SConnection *pCon,float *fVal);@\\
\mbox{}\verb@@\\
\mbox{}\verb@/*------------------------ parameters ----------------------------------*/@\\
\mbox{}\verb@ EVMode EVCGetMode(pEVControl self);@\\
\mbox{}\verb@ int EVCSetMode(pEVControl self, EVMode eNew);@\\
\mbox{}\verb@ int EVCSetPar(pEVControl self, char *name, float fNew, SConnection *pCon);@\\
\mbox{}\verb@ int EVCGetPar(pEVControl self, char *name, float *fVal);@\\
\mbox{}\verb@ int EVCList(pEVControl self, SConnection *pCon);@\\
\mbox{}\verb@/*------------------------- logging -----------------------------------*/@\\
\mbox{}\verb@ pVarLog EVCGetVarLog(pEVControl self);@\\
\mbox{}\verb@/*----------------- Interface to SICS interpreter -----------------------*/@\\
\mbox{}\verb@ int EVControlWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@ @\\
\mbox{}\verb@ int EVControlFactory(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@ @\\
\mbox{}\verb@@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
The functions in more detail:
\begin{description}
\item [CreateEVController] CreateEVController creates and initialises a
EVController. All interface functions are initialised with default
functions. The first parameter is a pointer to the driver to use, the second
the name of the thing.
\item [DeleteEVController] cleans a EVController from memory. A
KillFunction type for the SICS interpreter.
\item [EVCDrive] drives an EVcontroller to the new value fNew.
\item [EVCGetPos] retrieves the actual value of the environment value from
the device. It is put into fVal.
\item [EVCSetPar] sets a parameter in the EVControllers internal database.
name is the name of the parameter, fNew the value it should get. A
connection object is passed in this call, which will be used for error
reporting and in order to check if the client is permitted to change the
parameter.Parameters recognized are:
\begin{description}
\item [Tolerance] The permissable deviation from the target value before an
error is raised.
\item [Access] which user id has permission to access this controller.
Permited values are: 0 == internal, 1 == Manager, 2 == User, 3 == Spy.
\item [ErrorHandler] determines which error handling strategy will be used
if the EVcontroller gets out of range. Recognized values are:
0 == do nothing, 1 == pause measurement till back in tolerance, 2 ==
interrupt, 3 == drive controller to a value considered safe.
\item [SaveValue] Value to be used as safe value if ErrorHandler 3 is
requested.
\item [Interrupt] The interrupt to issue, when interrupt error handling had
been requested. Will also be used as interrupt if a hardware failure is
detected while driving. Valid values are: 0 == Continue, 1 == Abort
Operation (Count), 2 == Abort Scan, 3 == Abort Batch processing, 4 == Halt
system, 6 == end SICS server.
\item [UpperLimit] The upper limit of values possible for the environment
device.
\item [LowerLimit] The lower limit of values possible for the environment
device.
\end{description}
\item [EVCGetPar] retrieves the value of a parameter. Name must be one of
the recognized names.
\item [EVCGetMode] retrieves the mode the EVController is in.
\item [EVCList] lists all the parameters to pCon.
\item[EVCGetVarLog] returns a pointer to the variable logger for this
controller.
\item [EVControlWrapper] is the interpreter interface to the EVController.
See the documentation for commands understood.
\item [EVControlFactory] is the SICS function needed for creation and
deletion of environment controllers.
\end{description}
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap4}
\verb@"evcontroller.h"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*--------------------------------------------------------------------------@\\
\mbox{}\verb@ E N V I R O N M E N T C O N T R O L L E R@\\
\mbox{}\verb@@\\
\mbox{}\verb@ This is the base class for all environment controllers. @\\
\mbox{}\verb@@\\
\mbox{}\verb@ Mark Koennecke, Juli 1997@\\
\mbox{}\verb@@\\
\mbox{}\verb@ copyright: see implementation file@\\
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
\mbox{}\verb@#ifndef SICSEVCONTROL@\\
\mbox{}\verb@#define SICSEVCONTROL@\\
\mbox{}\verb@#include "varlog.h"@\\
\mbox{}\verb@@$\langle$dvfunc {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@#endif@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap5}
\verb@"evcontroller.i"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*-------------------------------------------------------------------------@\\
\mbox{}\verb@ Environment controller datastructure@\\
\mbox{}\verb@ @\\
\mbox{}\verb@ Mark Koennecke, Juli 1997@\\
\mbox{}\verb@@\\
\mbox{}\verb@---------------------------------------------------------------------------*/@\\
\mbox{}\verb@/*-------- Parameter defines */@\\
\mbox{}\verb@#define TOLERANCE 0@\\
\mbox{}\verb@#define ACCESS 1@\\
\mbox{}\verb@#define ERRORHANDLER 2@\\
\mbox{}\verb@#define INTERRUPT 3@\\
\mbox{}\verb@#define UPLIMIT 4@\\
\mbox{}\verb@#define LOWLIMIT 5@\\
\mbox{}\verb@#define SAFEVALUE 6@\\
\mbox{}\verb@@\\
\mbox{}\verb@@$\langle$evdata {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap6}
\verb@"evdriver.i"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*-------------------------------------------------------------------------@\\
\mbox{}\verb@ Environment device driver datastructure@\\
\mbox{}\verb@ @\\
\mbox{}\verb@ Mark Koennecke, Juli 1997@\\
\mbox{}\verb@@\\
\mbox{}\verb@---------------------------------------------------------------------------*/@\\
\mbox{}\verb@#define DEVOK 1@\\
\mbox{}\verb@#define DEVFAULT 0@\\
\mbox{}\verb@#define DEVREDO 2@\\
\mbox{}\verb@@\\
\mbox{}\verb@@$\langle$evdriv {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@/*-------------------- life & death of a driver --------------------------*/@\\
\mbox{}\verb@ pEVDriver CreateEVDriver(int argc, char *argv[]);@\\
\mbox{}\verb@ void DeleteEVDriver(pEVDriver pDriv);@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}

View File

@ -0,0 +1,110 @@
\subsubsection{LTC-11 Driver}
This is a driver for the Kyocera LTC-11 temperature controller which
is used with the Kryo furnace at SINQ (funny idea, a kryo
furnace). As with the ITC-4 this device has a few special functions
and requires an additional interpreter function which delegates to the
standard one for the general stuff. This is mainly the switching of
the operation mode of the LTC-11. It has two modes: analog mode and
heater mode. For more details about this see the controller
manual. The driver is implemented in the
file ltc11.h and ltc11.c. The following functions, besides those
required for the standard driver, are defined:
\begin{verbatim}
pEVDriver CreateLTC11Driver(int argc, char *argv[]);
int LTC11GetMode(pEVDriver self, int *iMode);
int LTC11SetMode(pEVDriver self, int iMode);
int LTC11Action(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
\end{verbatim}
These are:
\begin{description}
\item[CreateLTC11Driver] creates a driver for a LTC-11. Returns a
pointer to a newly allocated LTC-11 driver or NULL in case of failure.
\item[LTC11GetMode] retrieves the current operation mode of the
LTC-11.
\item[LTC11SetMode] sets the operation mode for the LTC-11.
\item[LTC11Action] The interpreter interface function for the
LTC-11. Implements the special commands for the LTC-11 and calls
EVControlWrapper for anything else.
\end{description}
\subsubsection{The Dillution Cryostat}
This is the old monster cryostat inherited from Saphir. Its driver is
implemented in dilludriv.h and dilludriv.c. There is additional code
for this device in the hardsup subdirectory in the file dillutil.h and
dillutil.c. This device has a fairly involved command protocoll. A
change of the set point requires heater output and and various
parameters for the resistance bridge used for temperature measurement
to be set. Then the set value has to be formatted in a range specific
way in a hexidecimal format. Most of this code is a C adaption of an
earlier F77 code from Elsenhans. Additionally this controller does not
provide a temperature but a resistance value. This resistance value
has to be converted to temperature through a calibration table. Thus
there is an additional file, dilu.tem, which holds this conversion
table.
\subsubsection{Eurotherm Temperature Controller}
SANS is Eurotherm temperature controller somewhere. These controllers
are quite common and the problem may come up again. The Eurotherm
supports not one but several command protocolls, each weirder then the
other. The implementation here serves the EI-Bisynch protocoll. The
thing ahs to be configured manually to run this protocoll. This
protocoll uses specific message formats for communication, the command
protocoll is not plain ASCII. For more details about the protocoll see
the documentation coming with the gadget. Due to this protocoll
restriction the usual Send function of the driver just returns an
error. The driver is impelemwnted
in file eurodriv.h and eurodriv.c. The following functions are
provided:
\begin{verbatim}
pEVDriver CreateEURODriv(int argc, char *argv[]);
/*
these are hooks to implement further functionality which,
I'am sure, Joachim Kohlbrecher will request.
*/
int EuroGetParameter(void **pData, char *pPar, int iLen, float *fVal);
int EuroSetParameter(void **pData, char *pPar, int iLen,
char *pFormat, float fVal);
\end{verbatim}
These are:
\begin{description}
\item[CreateEuroDriver] creates a driver for a Eurotherm controller. Returns a
pointer to a newly allocated Eurotherm driver or NULL in case of failure.
\item[EuroGetParameter] gets one out of many parameters possible with
the Eurotherm. This is a hook to implement further functionality. For
possible values for parameter names pPar see the Eurotherm
documentation. iLen is the length of pPar.
\item[LTC11SetParameter] retrieves the value of a parameter from the
Eurotherm. Again a hook for further expansion. pFormat is the format
how to print the parameter into the command string.
\end{description}
\subsubsection{EL755 Magnet Controller}
This is a driver for the PSI manufactured EL755 magnet
controller. There is additional code for this in the hardsup directory
with files el755\_utility.*. The functions there are documented in that
file. For SICS there is only an adapter to this implemented in
el755driv.h and el755driv.c. The only external function is a driver
creation function with the usual parameters and return values.

143
doc/programmer/event.tex Normal file
View File

@ -0,0 +1,143 @@
\subsection{SICS Events}
This section lists the callback events known to Sics, their purpose, and
their associated event datastructures when applicable. See the
\ref{inter} section about callbacks for more information about
callbacks. This only defines the integer codes possible. Please be
aware that the implementation of the callbacks is a duty of the SICS
objects generating it. The mentioning of an event code here means it
is used somewhere in SICS but does not mean that it is implemented by
all objects which might implement the event.
This module defines several event related functions as well.
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap1}
$\langle$eFunc {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ int Text2Event(char *pText);@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
{\bf Text2Event } converts a text value into an event code. It returns -1
if the event code is not known, else the apropriate event code.
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap2}
$\langle$VE {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@#define VALUECHANGE 0@\\
\mbox{}\verb@#define MOTDRIVE 1@\\
\mbox{}\verb@#define MONITOR 2 @\\
\mbox{}\verb@#define ROTSTART 3@\\
\mbox{}\verb@#define ROTMOVE 4@\\
\mbox{}\verb@#define SCANEND 5@\\
\mbox{}\verb@#define SCANSTART 6@\\
\mbox{}\verb@#define SCANPOINT 7@\\
\mbox{}\verb@#define WLCHANGE 8@\\
\mbox{}\verb@#define REFLECTIONDONE 9@\\
\mbox{}\verb@#define COUNTSTART 10@\\
\mbox{}\verb@#define COUNTEND 11@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
\begin{description}
\item[VALUECHANGE] This is a variable changing its value. As event data a pointer to the
SicsVariable is passed along. This is defined in sicsvar.h.
\item[MOTDRIVE] a motor is moving. The event data is the current position.
\item[MONITOR] The control value for a counting operation has changed.
The event data is the new value.
\item[ROTSTART] A velocity selector is starting up.
\item[ROTMOVE] A velocity selector changes its rotation speed.
\item[SCANEND] A scan has ended.
\item[SCANSTART] A new scan has been started.
\item[SCANPOINT] A scan point has finished and there is new data.
\item[WLCHANGE] is incoked when the wavelength of a crystal monochromator
changes. The event parameter is a pointer to the wave length or energy
variable being driven. Client code can then get what it needs to know.
\item[REFLECTIONDONE] is issued when a single reflection of a four circle
fiffractometer has been measured.
\item[COUNTSTART] is an event which signals the start of a counting
operation.
\item[COUNTEND] is an event signalling the end of a counting operation.
\end{description}
Furthermore event contains system wide signal codes which are interpreted in
the signal functions provided by each SICS task. These code are
evaluated by the TaskSignalFunction which may be configured for each
SICS task. See the task section for more information. Here, only
possible codes are defined.
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap3}
$\langle$VSIG {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@#define SICSINT 300@\\
\mbox{}\verb@#define SICSBROADCAST 301@\\
\mbox{}\verb@#define TOKENGRAB 302@\\
\mbox{}\verb@#define TOKENRELEASE 303@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
\begin{description}
\item[SICSINT] An interrupt has ocurred. The signal data is the interrupt
number which ocurred.
\item[SICSBROADCAST] A message shall be sent to each SICS client. The signal
data is the string to send.
\item[TOKENGRAB] A connection has successfully grabbed the control token.
\item[TOKENRELEASE] A connection has released the control token.
\end{description}
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap4}
\verb@"event.h"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*----------------------------------------------------------------------------@\\
\mbox{}\verb@ E V E N T@\\
\mbox{}\verb@@\\
\mbox{}\verb@ This header file lists the event codes known to SICS. These event code@\\
\mbox{}\verb@ are used in callback functions. Where apropriate, the event data@\\
\mbox{}\verb@ structures are also defined in this file.@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Mark Koennecke, 1997@\\
\mbox{}\verb@@\\
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
\mbox{}\verb@#ifndef SICSEVENT@\\
\mbox{}\verb@#define SICSEVENT@\\
\mbox{}\verb@@$\langle$eFunc {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@@\\
\mbox{}\verb@@$\langle$VE {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@@\\
\mbox{}\verb@/*--------------- Signals for the Signalfunction of each task ------------*/@\\
\mbox{}\verb@@$\langle$VSIG {\footnotesize ?}$\rangle$\verb@ @\\
\mbox{}\verb@#endif@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}

View File

@ -0,0 +1,70 @@
\subsection{The FOCUS Averager}
This is a special object for the instrument FOCUS and its Status display
client. In the FOCUS status display the averaged data from a number of
detectors is displayed. Thus there is already a reduced form of data. The
actual raw data would be 150*1024*4 bytes of data and possibly more. Rather
then transporting all this data to the status display client at regular
intervalls it was choosen to implement this averaging process at the server
and only send the reduced form to the status display client. Which is two
arrays of floating point data 1024 items long. This little object implements this
averager.
As all SICS objects this object has a little data structure:
\begin{verbatim}
typedef struct __FocusAverager {
pObjectDescriptor pDes;
pHistMem pHist;
} FocusAverager;
\end{verbatim}
The two fields are the standard object descriptor and a pointer to the
histogram memory object holding the data.
The interface is minimal: it consists just of the factory function for
installing this object into SICS and the actual function doing the
averaging in the interpreter.
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap1}
$\langle$faint {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ int MakeFA(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@@\\
\mbox{}\verb@ int FocusAverageDo(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap2}
\verb@"faverage.h"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*-----------------------------------------------------------------------@\\
\mbox{}\verb@ F o c u s A v e r a g e@\\
\mbox{}\verb@@\\
\mbox{}\verb@ An averager for FOCUS data. See faverage.tex for more details.@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Mark Koennecke, October 1998@\\
\mbox{}\verb@@\\
\mbox{}\verb@--------------------------------------------------------------------------*/@\\
\mbox{}\verb@#ifndef FOCUSAVERAGE@\\
\mbox{}\verb@#define FOCUSAVERAGE@\\
\mbox{}\verb@@$\langle$faint {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@#endif@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}

View File

@ -0,0 +1,22 @@
\subsection{FOCUS Data File Writing}
FOCUS writes NeXus files. This file writing is impleneted in the files
fowrite.h and fowrite.c. So these files contain the code for writing
FOCUS NeXus files. But there is more to it: FOCUS has a scheme where
the data file is updated any 20 minutes during the course of an
measurement. This scheme is implemented with the following bits and
pieces:
\begin{itemize}
\item Data file updating is triggered by a special task function,
FoTask, which is installed into the SICS tasker when counting starts.
\item The module registers callbacks with the histogram memory which
are invoked when counting starts or ends. These callback functions
take care of craeting a new file and updating it.
\item There is a special command which allows to start and update the
data file manually.
\end{itemize}
As is it not likely that more then one FOCUS writing object is ever
needed, all the data structures are file statics in fowrite.c. The
external interface of this module is just a interpreter initialisation
function and a interpreter interface function for interacting with the
data file writing object.

83
doc/programmer/fupa.tex Normal file
View File

@ -0,0 +1,83 @@
\subsection{Function Parser}
A utility module to take some of the pain from parsing input while
writing text wrapper function for SICS.
The idea is that you specify an array of function templates.
These function templates will contain function names and argument
information. This module will than parse the input against this
template. It will return -1 if an error occurs and provide error
information.
On success the index of the function found will be returned.
Arguments will have been updated with their proper values.
Invoking functions ist still your job, probably in a switch statement
following the call to the evaluation function.
The function parser supports these different argument types:
\begin{verbatim}
#define FUPATEXT 0 /* text*/
#define FUPAINT 1 /* integer */
#define FUPAFLOAT 2 /* a float */
#define FUPAOPT 3 /* optional argument, in this case text contains it
and iVal indicates its presence
*/
\end{verbatim}
Each template for a function has these fields:
\begin{verbatim}
typedef struct {
char *name;
int iArgs;
int pArgs[MAXARG];
} FuncTemplate, *pFuncTemplate;
\end{verbatim}
\begin{description}
\item[name] the name of the function.
\item[iArgs] The number of arguments to the function.
\item[pArgs] An array with iArgs entries of the integer argument description
types stated above.
\end{description}
On return the actual values of the arguments will be returned as a field in
this structure, according to type.
\begin{verbatim}
typedef struct {
char text[80];
int iVal;
float fVal;
} FuPaArg;
\end{verbatim}
The whole result is returned in the structure defined below:
\begin{verbatim}
typedef struct {
char pError[132];
int iArgs;
FuPaArg Arg[MAXARG];
} FuPaResult;
\end{verbatim}
The fields are: \begin{description}
\item[pError] An error description in case of an error.
\item[iArgs] the number of arguments actually read.
\item[Arg] An array of argumnet result structures as defined above.
\end{description}
Function parsing is done with this function:
\begin{verbatim}
int EvaluateFuPa(pFuncTemplate pTemplate,int iFunc, int argc, char *argv[],
FuPaResult *pRes);
\end{verbatim}
The parameters are:
\begin{description}
\item[pTemplate] a parsing template.
\item[iFunc] The number of functions in the template array.
\item[argc,argv] The text to parse.
\item[pRes] A pointer to a retuned result array.
\end{description}
The return value is -1 on error, or the number of the template identified on
success.
For more information, look on a usage example in counter.c.

463
doc/programmer/hart.eps Normal file
View File

@ -0,0 +1,463 @@
%!
%%BoundingBox: 24 540 514 775
%%Title: hart
%%CreationDate: Fri May 30 10:02:56 1997
%%Creator: Tgif-3.0-p7 by William Chia-Wei Cheng (william@cs.UCLA.edu)
/tgifdict 4 dict def
tgifdict begin
/tgifellipsedict 6 dict def
tgifellipsedict /mtrx matrix put
/tgifellipse
{ tgifellipsedict begin
/yrad exch def
/xrad exch def
/y exch def
/x exch def
/savematrix mtrx currentmatrix def
x y translate
xrad yrad scale
0 0 1 0 360 arc
savematrix setmatrix
end
} def
end
%%PageBoundingBox: 24 540 514 775
tgifdict begin
/tgifsavedpage save def
1 setmiterlimit
1 setlinewidth
0 setgray
72 0 mul 72 11.00 mul translate
72 128 div 100.000 mul 100 div dup neg scale
gsave
/tgiforigctm matrix currentmatrix def
% BOX
0 setgray
gsave
10 setmiterlimit
gsave
newpath
112 163 moveto 227 163 lineto 227 189 lineto 112 189 lineto
closepath
stroke
grestore
grestore
% BOX
0 setgray
gsave
10 setmiterlimit
gsave
newpath
125 99 moveto 214 99 lineto 214 150 lineto 125 150 lineto
closepath
stroke
grestore
grestore
% RCBOX
0 setgray
gsave
gsave
newpath
202 112 moveto 202 138 lineto 138 138 lineto 138 112 lineto
closepath
stroke
grestore
grestore
% BOX
0 setgray
gsave
10 setmiterlimit
gsave
newpath
368 99 moveto 509 99 lineto 509 176 lineto 368 176 lineto
closepath
stroke
grestore
grestore
% TEXT
0 setgray
/Courier findfont [17 0 0 -17 0 0] makefont setfont
gsave
573 75 moveto (Motor Controller) show
grestore
% TEXT
0 setgray
/Courier findfont [17 0 0 -17 0 0] makefont setfont
gsave
573 139 moveto (Motor Controller) show
grestore
% TEXT
0 setgray
/Courier findfont [17 0 0 -17 0 0] makefont setfont
gsave
573 228 moveto (Counter Box) show
grestore
% TEXT
0 setgray
/Courier findfont [17 0 0 -17 0 0] makefont setfont
gsave
573 305 moveto (Counter) show
grestore
% TEXT
0 setgray
/Courier findfont [17 0 0 -17 0 0] makefont setfont
gsave
368 382 moveto (Histogram) show
368 399 moveto (Memory) show
grestore
% BOX
0 setgray
gsave
10 setmiterlimit
gsave
newpath
560 202 moveto 726 202 lineto 726 240 lineto 560 240 lineto
closepath
stroke
grestore
grestore
% BOX
0 setgray
gsave
10 setmiterlimit
gsave
newpath
330 355 moveto 483 355 lineto 483 445 lineto 330 445 lineto
closepath
stroke
grestore
grestore
% POLY/OPEN-SPLINE
0 setgray
gsave
newpath
48 266 moveto
483 266 lineto
tgiforigctm setmatrix
5 setlinewidth
stroke
1 setlinewidth
grestore
% POLY/OPEN-SPLINE
0 setgray
gsave
newpath
432 176 moveto
432 266 lineto
tgiforigctm setmatrix
5 setlinewidth
stroke
1 setlinewidth
grestore
% POLY/OPEN-SPLINE
0 setgray
gsave
newpath
150 189 moveto
150 266 lineto
tgiforigctm setmatrix
5 setlinewidth
stroke
1 setlinewidth
grestore
% POLY/OPEN-SPLINE
0 setgray
gsave
newpath
381 266 moveto
381 355 lineto
tgiforigctm setmatrix
5 setlinewidth
stroke
1 setlinewidth
grestore
% TEXT
0 setgray
/Courier findfont [17 0 0 -17 0 0] makefont setfont
gsave
176 292 moveto (TCP/IP) show
grestore
% POLY/OPEN-SPLINE
0 setgray
gsave
newpath
509 112 moveto
560 74 lineto
tgiforigctm setmatrix
2 setlinewidth
stroke
1 setlinewidth
grestore
% POLY/OPEN-SPLINE
0 setgray
gsave
newpath
509 138 moveto
560 138 lineto
tgiforigctm setmatrix
2 setlinewidth
stroke
1 setlinewidth
grestore
% POLY/OPEN-SPLINE
0 setgray
gsave
newpath
509 163 moveto
560 214 lineto
tgiforigctm setmatrix
2 setlinewidth
stroke
1 setlinewidth
grestore
% POLY/OPEN-SPLINE
0 setgray
gsave
newpath
611 240 moveto
611 291 lineto
tgiforigctm setmatrix
2 setlinewidth
stroke
1 setlinewidth
grestore
% POLY/OPEN-SPLINE
0 setgray
gsave
newpath
624 240 moveto
624 291 lineto
tgiforigctm setmatrix
2 setlinewidth
stroke
1 setlinewidth
grestore
% TEXT
0 setgray
/Courier findfont [17 0 0 -17 0 0] makefont setfont
gsave
483 75 moveto (RS-232) show
grestore
% BOX
0 setgray
gsave
10 setmiterlimit
gsave
newpath
560 48 moveto 752 48 lineto 752 96 lineto 560 96 lineto
closepath
stroke
grestore
grestore
% BOX
0 setgray
gsave
10 setmiterlimit
gsave
newpath
560 112 moveto 752 112 lineto 752 160 lineto 560 160 lineto
closepath
stroke
grestore
grestore
% BOX
0 setgray
gsave
10 setmiterlimit
gsave
newpath
560 288 moveto 672 288 lineto 672 320 lineto 560 320 lineto
closepath
stroke
grestore
grestore
% TEXT
0 setgray
/Courier findfont [17 0 0 -17 0 0] makefont setfont
gsave
384 126 moveto (Terminal) show
384 143 moveto (Server) show
grestore
% TEXT
0 setgray
/Courier findfont [17 0 0 -17 0 0] makefont setfont
gsave
864 62 moveto (M1) show
grestore
% TEXT
0 setgray
/Courier findfont [17 0 0 -17 0 0] makefont setfont
gsave
864 126 moveto (M2) show
grestore
% TEXT
0 setgray
/Courier findfont [17 0 0 -17 0 0] makefont setfont
gsave
864 190 moveto (M3) show
grestore
% TEXT
0 setgray
/Courier findfont [17 0 0 -17 0 0] makefont setfont
gsave
864 254 moveto (M4) show
grestore
% TEXT
0 setgray
/Courier findfont [17 0 0 -17 0 0] makefont setfont
gsave
864 334 moveto (M5) show
grestore
% OVAL
0 setgray
gsave
gsave
newpath 864 56 32 24 tgifellipse
stroke
grestore
grestore
% OVAL
0 setgray
gsave
gsave
newpath 880 120 32 24 tgifellipse
stroke
grestore
grestore
% OVAL
0 setgray
gsave
gsave
newpath 880 184 32 24 tgifellipse
stroke
grestore
grestore
% OVAL
0 setgray
gsave
gsave
newpath 880 248 32 24 tgifellipse
stroke
grestore
grestore
% OVAL
0 setgray
gsave
gsave
newpath 880 328 32 24 tgifellipse
stroke
grestore
grestore
% POLY/OPEN-SPLINE
0 setgray
gsave
newpath
752 64 moveto
832 48 lineto
tgiforigctm setmatrix
1 setlinewidth
stroke
grestore
% POLY/OPEN-SPLINE
0 setgray
gsave
newpath
752 80 moveto
848 112 lineto
tgiforigctm setmatrix
1 setlinewidth
stroke
grestore
% POLY/OPEN-SPLINE
0 setgray
gsave
newpath
752 144 moveto
848 176 lineto
tgiforigctm setmatrix
1 setlinewidth
stroke
grestore
% POLY/OPEN-SPLINE
0 setgray
gsave
newpath
752 144 moveto
848 240 lineto
tgiforigctm setmatrix
1 setlinewidth
stroke
grestore
% POLY/OPEN-SPLINE
0 setgray
gsave
newpath
752 144 moveto
848 320 lineto
tgiforigctm setmatrix
1 setlinewidth
stroke
grestore
% TEXT
0 setgray
/Courier findfont [17 0 0 -17 0 0] makefont setfont
gsave
96 238 moveto (Data Aquisition Computer) show
grestore
grestore
tgifsavedpage restore
end
%MatchingCreationDate: Fri May 30 10:02:56 1997

BIN
doc/programmer/hart.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

@ -0,0 +1,656 @@
\subsection{Histogram memory}
A histogram memory is the interface to a large multidetector. This is quite
a complex piece of equipment. It does not only provide lots of data but also
has a lot of configuration options. Things which need configuration are:
histogram mode, overflow mode, measurement mode and the layout of the
histograms. Let's discuss these different modes first.
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap1}
$\langle$Modes {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ typedef enum {@\\
\mbox{}\verb@ eHTransparent,@\\
\mbox{}\verb@ eHNormal,@\\
\mbox{}\verb@ eHTOF,@\\
\mbox{}\verb@ eHStrobo,@\\
\mbox{}\verb@ eHRPT@\\
\mbox{}\verb@ } HistMode;@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro defined by scraps ?, ?.
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
A histogram memory can be operated in transparent mode. It has not yet been
defined what this means but it is sort of storing raw data from the detector
without any summing or processing. Normal mode is better defined, this is
sorting and summing data from the detector into apropriate bins for each
detector. Time is not resolved. TOF mode means time of flight mode. In this
mode incoming is not only sorted and summed into the correct detector bins
but also resolved in time (which means energy for neutrons). This means for
each detector there is a histogram counts versus time. Similar is
stroboscopic mode (eHStrobo). In stroboscopic mode there is a histogram
counts versus pulses for each physical detector. The bin switching is done
via a secondary hardware signal or from software. This is useful for
measuring diffraction data versus oscillating environment conditions. eHRPT
is a special mode for the HRPT Cerca detector. It requires special handling,
this is why there is a special flag.
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap2}
$\langle$Modes {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ typedef enum {@\\
\mbox{}\verb@ eOIgnore,@\\
\mbox{}\verb@ eOCeil,@\\
\mbox{}\verb@ eOCount,@\\
\mbox{}\verb@ eReflect@\\
\mbox{}\verb@ } OverFlowMode;@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro defined by scraps ?, ?.
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
Histogram memories may support different schemes for handling overflow
conditions. In this condition there are more counts than fit into the
configured
binwidth. The simplest thing to do is to ignore the condition and simply
wrap over to zero (eOIgnore). The other mode is to keep the bin at the
highest count possible (eOCeil). More sophisticated histogram memories
maintain a separate list where all those overflowed bins are registered.
This is eOCount. eReflect has nothing to do with overflows. It says that the
histogram should be reflected. This means counter 1 becomes counter max etc.
This is special for HRPT. It happens to live in the OverFlowMode enum because
this is really a sub mode descriptor.
The measurement mode is the simple counter operation mode: wait for a timer
or wait for a monitor to run full.
The layout of the histogram memory (HM) is defined by the rank (i.e. the number
of dimensions of the HM, the number of points in each dimension and by the
binwidth in bits for each bin. For TOF and stroboscopic modes information
about the binning in time or pulses is needed as well. Needless to say that
these values have to match the geometry of the detector.
Histograms usually have a number type associated with them. In order to
minimise conversion overhead in the logical object, the data size will
defined by a typedef, HistInt.
There is a scheme for handling all this configuration information
which may even be more for a Histogram memory with a specific
driver. There is a dictionary of configuration options in the logical
histogram memory object. These options can be set with a special
command. Then on initialisation first the logical histogram memory
evaluates the general options and then the driver in its Config
function evaluates the driver specific options.
\subsubsection{The Histogram memory driver}
Adhering to the Sics paradigm of dividing any device into a logical device
and a hardware driver, the Sics histogram memory needs drivers as well. This
section describes this driver interface. For an overview, see the structure
definition:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap3}
$\langle$HistType {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ typedef struct __HistDriver {@\\
\mbox{}\verb@ /* configuration data */@\\
\mbox{}\verb@ HistMode eHistMode;@\\
\mbox{}\verb@ OverFlowMode eFlow;@\\
\mbox{}\verb@ int iRank;@\\
\mbox{}\verb@ int iDims[MAXDIM];@\\
\mbox{}\verb@ int nDim;@\\
\mbox{}\verb@ int iLength;@\\
\mbox{}\verb@ int iBinWidth;@\\
\mbox{}\verb@ float fTime[MAXCHAN];@\\
\mbox{}\verb@ int iTimeChan;@\\
\mbox{}\verb@ /* counting operations data */@\\
\mbox{}\verb@ CounterMode eCount;@\\
\mbox{}\verb@ float fCountPreset;@\\
\mbox{}\verb@ /* status flags */@\\
\mbox{}\verb@ int iReconfig;@\\
\mbox{}\verb@ int iUpdate;@\\
\mbox{}\verb@ /* interface functions */@\\
\mbox{}\verb@ int (*Configure)(pHistDriver self,@\\
\mbox{}\verb@ SConnection *pCon,@\\
\mbox{}\verb@ pStringDict pOpt,@\\
\mbox{}\verb@ SicsInterp *pSics);@\\
\mbox{}\verb@ int (*Start)(pHistDriver self, @\\
\mbox{}\verb@ SConnection *pCon);@\\
\mbox{}\verb@ int (*Halt)(pHistDriver self);@\\
\mbox{}\verb@ int (*GetCountStatus)(pHistDriver self,@\\
\mbox{}\verb@ SConnection *pCon);@\\
\mbox{}\verb@ int (*GetError)(pHistDriver self, @\\
\mbox{}\verb@ int *iCode,@\\
\mbox{}\verb@ char *perror,@\\
\mbox{}\verb@ int iErrlen);@\\
\mbox{}\verb@ int (*TryAndFixIt)(pHistDriver self,@\\
\mbox{}\verb@ int iCode);@\\
\mbox{}\verb@ int (*GetData)(pHistDriver self,@\\
\mbox{}\verb@ SConnection *pCon);@\\
\mbox{}\verb@ int (*GetHistogram)(pHistDriver self,@\\
\mbox{}\verb@ SConnection *pCon,@\\
\mbox{}\verb@ int i,@\\
\mbox{}\verb@ int iStart, int iEnd,@\\
\mbox{}\verb@ HistInt *pData);@\\
\mbox{}\verb@@\\
\mbox{}\verb@ int (*SetHistogram)(pHistDriver self,@\\
\mbox{}\verb@ SConnection *pCon,@\\
\mbox{}\verb@ int i,@\\
\mbox{}\verb@ int iStart, int iEnd,@\\
\mbox{}\verb@ HistInt *pData);@\\
\mbox{}\verb@ long (*GetMonitor)(pHistDriver self, @\\
\mbox{}\verb@ int i,@\\
\mbox{}\verb@ SConnection *pCon);@\\
\mbox{}\verb@ float (*GetTime)(pHistDriver self,@\\
\mbox{}\verb@ SConnection *pCon);@\\
\mbox{}\verb@ int (*Preset)(pHistDriver self,@\\
\mbox{}\verb@ SConnection *pCon,@\\
\mbox{}\verb@ HistInt iVal);@\\
\mbox{}\verb@ int (*Pause)(pHistDriver self,@\\
\mbox{}\verb@ SConnection *pCon);@\\
\mbox{}\verb@ int (*Continue)(pHistDriver self,@\\
\mbox{}\verb@ SConnection *pCon);@\\
\mbox{}\verb@ int (*FreePrivate)(pHistDriver self);@\\
\mbox{}\verb@ void *pPriv;@\\
\mbox{}\verb@ } HistDriver;@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
Quite a lot, but a histogram memory is quite a complex piece of equipment.
The configuration information is in the elements EhistMode, eOverFlowMode,
iRank, iDims and iBinWidth fields. iDim and nDim desribe the logical
dimensions of the histogram memory. These may be different from the
dimensions used for data transfer. For instance the SANS detector is
handled internally as 1600+ numbers where it really is a filed o
128*128.
Additionally there is an array of
floating point values which denote the time binning for time-o-flight
operation or the stroboscopic binning axis in stroboscopic mode.
The fields fPreset and CounterMode hold the counting parameter data.
Than there are two status fields. The first is iReconfig. This will be set
to true, whenever any changes to the configuration to the HM are made. This
will be tested against when starting a measurement and will force a
configuration call to be issued. A call to the interface function Configure
clears this flag. The other flag is iUpdate. This is only useful when an in
memory copy of the histogrammed data is maintained on the host computer.
This flag is set when a count gets started and gets cleared when counting is
finished and all data has been transferred.
The next part defines the hardware interface functions to the histogram
memory. Each of these functions must be defined by any complete
implementation of a HM driver. If not stated otherwise these functions
return 1 on success and 0 on failure. All functions take a pointer to their
HistDriver structure as first parameter. Many functions have a pointer to an
SConnection as parameter. This connection will be used for error reporting.
\begin{itemize}
\item {\bf Configure} configures the histogram memory to the specifications
given in the fields of the HMdriver structure. Further driver specific
information can be read from the options dictionary passed in.
\item {\bf Start} starts a counting operation according to the current
settings of the counter mode parameters.
\item {\bf Halt} implements an emergency stop of a counting operation.
\item {\bf GetCountStatus} serves to monitor the status of the counting
operation. Possible return values to this call are:
\begin{itemize}
\item HWBUSY when still counting.
\item HWNoBeam when the monitor is to low.
\item HWIDLE or OKOK when nothing is going on.
\item HWFault when there is an error on the device.
\end{itemize}
\item {\bf GetError} will be called whenever an error has been detected on
the device. The task is to put an internal error code into the iCode
parameter. The string parameter error will be filled with a text description
of the error. But maximum iLen characters will be transferred to the error
string in order to protect against memory corruption. Therefore iLen must be
the maximum field length of error.
\item {\bf TryAndFixIt} is the next function called in case of an error on
the device. Its second parameter is the internal code obtained in the ICode
parameter of the call to GetError. The task of this function is to examine
the error code and do whatever is possible in software to fix the problem.
TryAndFixIt returns one of the following values:
\begin{itemize}
\item MOTREDO when the error could be fixed, but the upper level code will
need to rerun the command which failed.
\item MOTFAIL when the software is unable to fix the problem and a real
mechanic with a hammer is needed (or somebody able to reboot!).
\item MOTOK when the error was fixed and nor further action is necessary.
\end{itemize}
\item {\bf GetData} transfers all the data collected in the HM into the
host computers memory.
\item {\bf GetHistogram} copies the histogram number i into the data space
given by the pointer to a long array. A conversion from different binwidth
to long is performed as well.
\item {\bf SetHistogram} presets the histogram number i with the data
given in lData. A conversion from different binwidth
to long is performed as well. iStart and iStop define the start and end of
the stretch of histogram to replace.
\item {\bf GetMonitor} returns the counts in the monitor i. Returns a
negative value on error. The error will have been printed to pCon.
\item {\bf GetTime} returns the actual counting time.
\item {\bf Preset} initializes the histogram memory to the value given by
iVal.
\item {\bf Pause} pauses data collection.
\item {\bf Continue} continues a paused data collection.
\item {\bf FreePrivate} will be called automatically by DeleteHistDriver and
has the task to remove the private data installed by implementations of an
actual histogram memory driver.
\end{itemize}
The last entry in the HistDriver structure is a pointer to void. Rather then use the overlay structure as with motor drivers, histogram
memory stores driver specific information in a driver specific sub
data structure. This is the pointer to pPrivate. KillPrivate is a
function which is able to delete the driver specific data structure
properly.
As all the burden is up to the implementation of the histogram memory driver
only these few functions operate on histogram memory drivers in general:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap4}
$\langle$HistDrivProt {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ pHistDriver CreateHistDriver(pStringDict pDict);@\\
\mbox{}\verb@ void DeleteHistDriver(pHistDriver self);@\\
\mbox{}\verb@ int HistDriverConfig(pHistDriver self, pStringDict pOpt,@\\
\mbox{}\verb@ SConnection *pCon);@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
CreateHistDriver creates a new HistDriver data structure and returns it. Or
NULL when the memory is exhausted. It also initialises the options database
in pDict to the apropriate values.
DeleteHistDriver removes a histogram memory driver from memory. It will
automatically try and call Freeprivate in order to remove driver specific
data. Than an the rest is removed. After this call self will point to
rubbish.
\subsubsection{The histogram memory object}
Most of the HM data will be held with the driver as it is needed there for
performing operations. Accordingly the datastructure associated with the
histogram memory object is fairly simple:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap5}
$\langle$HistST {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ typedef struct __HistMem {@\\
\mbox{}\verb@ pObjectDescriptor pDes;@\\
\mbox{}\verb@ int iAccess;@\\
\mbox{}\verb@ int iExponent;@\\
\mbox{}\verb@ pHistDriver pDriv;@\\
\mbox{}\verb@ int iInit;@\\
\mbox{}\verb@ pICountable pCountInt;@\\
\mbox{}\verb@ pICallBack pCall;@\\
\mbox{}\verb@ pStringDict pOption;@\\
\mbox{}\verb@ HistInt *iLocalData;@\\
\mbox{}\verb@ int iLocalLength;@\\
\mbox{}\verb@ int iLocalUpdate;@\\
\mbox{}\verb@ time_t tLocal;@\\
\mbox{}\verb@ int iUpdateIntervall;@\\
\mbox{}\verb@ } HistMem;@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
According to the general Sics object interface the first field is the object
descriptor. Note, that the histogram memory has to adhere to the countable
objects interface. iAccess is the access code used to control user
interaction with the HM. iExponent is the force of 10 used for calculating
the actual preset value for counting in monitor mode.
However, note, that all configuration commands will
require Manager privilege at least. Then there is a pointer to the
driver followed by pointers to the interfaces implemented by the histogram
memory. pOption is a string dictionary of configuration options for the
histogram memory.
In order to save network bandwidth and for efficiency the histogram memory
object buffers the histogram memory in memory. The histogram itself resides
in iLocalData. iLocalLength is the length of iLocalData. iLocalUpdate is a
flag which will be set when counting operations (histogram changes ) are
going on and cleared when the histogram has been completely read.
When counting the local data will be updated only at certain intervalls.
This is a configuration option. iUpdateIntervall is that intervall in
seconds, tLocal is the time for the next scheduled update.
The interaction with the histogram memory can be classified into four
groups: basic initialisation and destruction, configuration, counting and
data retrieval. The first group to look at are the basics:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap6}
$\langle$Protos {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ pHistMem CreateHistMemory(char *drivername);@\\
\mbox{}\verb@ void DeleteHistMemory(void *self);@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro defined by scraps ?, ?, ?, ?, ?.
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
CreateHistMem creates a new histogram memory.
On error this
call returns NULL. On success a pointer to the new histogram memory object.
CreateHistMem does NOT configure anything! A driver gets selected according
to the driver name.
DeleteHistMemory removes a histogram memory from computer memory.
Any references to self afterwards will
point to rubbish.
The next group of functions refer to configuration.
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap7}
$\langle$Protos {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ int HistGetOption(pHistMem self, char *name, char *result, int iResultLen);@\\
\mbox{}\verb@ int HistSetOption(pHistMem self, char *name, char *value);@\\
\mbox{}\verb@ int HistConfigure(pHistMem self, SConnection *pCon, SicsInterp *pSics);@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro defined by scraps ?, ?, ?, ?, ?.
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
HistGetOption caters for the retrieval of the current option given in name.
Maximum iResultLen characters of result will be copied into result, or an
error message if things go wrong.
HistSetOption sets the option name to value specified in value. No error
checking except availability of the option and permission is done here.
HistConfigure updates the internal datastructures from the dictionary and
does the actual configuration of the HM. Tons of error messages will be
printed to pCon.
Valid names for the options in the dictionary are all the names in the
histogram datastructure. Please note, that counting options are handled
separately (see below). Additionally there may be driver specific options
available. For iDim iRank numbers are expected which represent the
dimensions of the HM.
The functions for counting and manipulation of counting parameters have been
separated from the rest of the configuration. The reason is that the main
configuration will only be performed by highly privileged users, whereas
the counting operations will be accessible by normal users. Counting is
controlled by the following functions:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap8}
$\langle$Protos {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ float GetHistPreset(pHistMem self);@\\
\mbox{}\verb@ int SetHistPreset(pHistMem self, float fVal);@\\
\mbox{}\verb@ CounterMode GetHistCountMode(pHistMem self);@\\
\mbox{}\verb@ int SetHistCountMode(pHistMem self, CounterMode eNew);@\\
\mbox{}\verb@ long GetHistMonitor(pHistMem self, int i, SConnection *pCon);@\\
\mbox{}\verb@ const float *GetHistTimeBin(pHistMem self, int *iLength);@\\
\mbox{}\verb@ int GetHistLength(pHistMem self);@\\
\mbox{}\verb@ int GetHistDim(pHistMem self, int iDim[MAXDIM], int *nDim);@\\
\mbox{}\verb@ float GetHistCountTime(pHistMem self,SConnection *pCon);@\\
\mbox{}\verb@ int HistDoCount(pHistMem self, SConnection *pCon);@\\
\mbox{}\verb@ int HistBlockCount(pHistMem self, SConnection *pCon);@\\
\mbox{}\verb@@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro defined by scraps ?, ?, ?, ?, ?.
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
The first four functions are simple parameter enquiry and manipulation
functions. GetHistMonitor returns the count on monitor number i for the
histogram memory. This function returns a negative value when the value
specified for i is invalid.
HistDoCount actually starts a counting operation. It will not
block and wait for counting to finish. Please note, that many counting
manipulation functions are hidden in the functions of the countable
interface, which the HM has to implement.
HistBlockCount also starts counting. But will block until counting has
finished.
Another set of functions is needed for manipulation of the data in the
histogram memory:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap9}
$\langle$Protos {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ int SetHistogram(pHistMem self, SConnection *pCon,@\\
\mbox{}\verb@ int i,int iStart, int iEnd, HistInt *lData);@\\
\mbox{}\verb@ int GetHistogram(pHistMem self, SConnection *pCon,@\\
\mbox{}\verb@ int i,int iStart, int iEnd, HistInt *lData, int iDataLen);@\\
\mbox{}\verb@ HistInt *GetHistogramPointer(pHistMem self,SConnection *pCon);@\\
\mbox{}\verb@ int PresetHistogram(pHistMem self, SConnection *pCon, HistInt lVal);@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro defined by scraps ?, ?, ?, ?, ?.
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
For histogram I/O the following aproach has been taken: Histograms are kept
as linear arrays of data regardless of the layout of the detector. It is the
task of upper level code to map the right histogram to the right position.
This aproach was choosen for two reasons: 1.) simplification of interface,
2.) easier to retrieve smaller chunks of data at a time.
With both SetHistogram and GetHistogram the parameter i denotes the
histogram to retrieve. A value of -1 retrieves the whole lot. iStart and
iEnd allow for extraction of a subset of a histogram. These values get
ignored when trying to retrieve a whole HM content. These routines
perform conversion to and from long to the binwidth of the HM. SetHistogram
initialises the HM from the lData provided. GetHistogram reads an histogram
into lData but maximum iDataLen items. PresetHistogram presets the HM to the
value lVal. Can be used to clear the HM.
The histogram memory object buffers the histograms for a adjustable
period of time. GetHistogramPointer retrieves a pointer to the local
histogram buffer. It also makes sure, that the histogram has been
updated if appropriate. This is provided for efficiency and saves some
memory copying and duplication of data during operations. Thus memory
consumption can be reduced. However, the drawback is that you mess
directly with the histogram memory content which is potentially
dangerous. Use this method with great care!
A last group of functions are those needed to interface to the Sics
interpreter:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap10}
$\langle$Protos {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ int MakeHistMemory(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@@\\
\mbox{}\verb@ int HistAction(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@ @\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro defined by scraps ?, ?, ?, ?, ?.
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
MakeHistMem is supposed to be called with two parameters: name and driver
which denote the name of the HM object and the type of driver to use. If all
is well, this call will create a command named name. Remember, that
the HM is
not yet configured!
HistAction is supposed to be where the action goes. HistAction understands
the commands:\begin{itemize}
\item {\bf name config option value} sets a configuration option.
\item {\bf name init} configures the HM.
\item {\bf name Preset val} returns the preset value if val is missing, else
it sets it.
\item {\bf name Mode val} returns the counting mode if val is missing, else
it sets it.
\item {\bf name count} starts a counting operation.
\item {\bf name get number} gets histogram number. -1 as histogram number
gets all.
\item {\bf name set number val........} sets histogram number to the values
following.
\item {\bf name clear val} sets all the HM to val.
\end{itemize}
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap11}
\verb@"HistMem.h"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*--------------------------------------------------------------------------@\\
\mbox{}\verb@ H I S T M E M @\\
\mbox{}\verb@@\\
\mbox{}\verb@ header for the histogram memory object for SICS.@\\
\mbox{}\verb@@\\
\mbox{}\verb@ copyright: see implementation file.@\\
\mbox{}\verb@ Mark Koennecke, April 1997@\\
\mbox{}\verb@-----------------------------------------------------------------------------*/@\\
\mbox{}\verb@#ifndef SICSHISTMEM@\\
\mbox{}\verb@#define SICSHISTMEM@\\
\mbox{}\verb@#define MAXDIM 3@\\
\mbox{}\verb@@\\
\mbox{}\verb@ typedef struct __HistDriver *pHistDriver;@\\
\mbox{}\verb@ typedef struct __HistMem *pHistMem;@\\
\mbox{}\verb@/*-------------------------------------------------------------------------*/@\\
\mbox{}\verb@ typedef int HistInt;@\\
\mbox{}\verb@/*@\\
\mbox{}\verb@ 32 bit integer on a DigitalUnix@\\
\mbox{}\verb@*/@\\
\mbox{}\verb@@$\langle$Modes {\footnotesize ?, \ldots\ }$\rangle$\verb@@\\
\mbox{}\verb@/*--------------------------------------------------------------------------*/@\\
\mbox{}\verb@@$\langle$Protos {\footnotesize ?, \ldots\ }$\rangle$\verb@@\\
\mbox{}\verb@@\\
\mbox{}\verb@#endif@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap12}
\verb@"HistDriv.i"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*---------------------------------------------------------------------------@\\
\mbox{}\verb@ H I S T D R I V@\\
\mbox{}\verb@ internal header file which includes the definition of the Histogram memory@\\
\mbox{}\verb@ driver structure.@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Mark Koennecke, April 1997@\\
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
\mbox{}\verb@#ifndef SICSHISTDRIV@\\
\mbox{}\verb@#define SICSHISTDRIV@\\
\mbox{}\verb@#define MAXCHAN 4096@\\
\mbox{}\verb@@\\
\mbox{}\verb@@$\langle$HistType {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@@$\langle$HistDrivProt {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@@\\
\mbox{}\verb@#endif@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap13}
\verb@"HistMem.i"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*---------------------------------------------------------------------------@\\
\mbox{}\verb@ H I S T M E M -- Internal@\\
\mbox{}\verb@ internal header file which includes the definition of the Histogram memory@\\
\mbox{}\verb@ data structure.@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Mark Koennecke, April 1997@\\
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
\mbox{}\verb@#ifndef SICSHISTMEMINT@\\
\mbox{}\verb@#define SICSHISTMEMINT@\\
\mbox{}\verb@@$\langle$HistST {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@@\\
\mbox{}\verb@#endif@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}

View File

@ -0,0 +1,50 @@
\subsubsection{Simulated histogram memory driver}
This is a driver for a simulated histogram memory needed for software
testing.
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap1}
$\langle$Protos {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ pHistDriver CreateSIMHM(pStringDict pOpt);@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
The only visible function defined is a creation function. Please note that
all the interface functions need to be defined as well. For implementation
of the countable interface this thing will use the simulated counter. All
data retrieval members will return random numbers in the required amount.
The call to configure will actually do nothing.
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap2}
\verb@"histsim.h"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*--------------------------------------------------------------------------@\\
\mbox{}\verb@ H I S T S I M@\\
\mbox{}\verb@@\\
\mbox{}\verb@ A simulated histogram memory for software testing.@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Mark Koennecke, April 1997@\\
\mbox{}\verb@@\\
\mbox{}\verb@ copyright: see implementation file.@\\
\mbox{}\verb@---------------------------------------------------------------------------*/@\\
\mbox{}\verb@#ifndef SICSHISTSIM@\\
\mbox{}\verb@#define SICSHISTSIM@\\
\mbox{}\verb@@$\langle$Protos {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@#endif@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}

215
doc/programmer/hkl.tex Normal file
View File

@ -0,0 +1,215 @@
\subsection{Crystallographic Computations}
The HKL object performs standard four circle calculations. I.e., given a UB
matrix it calculates the four circle diffractometer setting angles required
for a reflection with index hkl. The UB must be determined from a set of
reflections found manually or automatically. This is done in an offline
program. The code in this module is a direct reimplementation of fortran code
provided by Jean Allibon, ILL with the MAD four circle diffractometer
control program in ANSI-C. For theory, see the contribution by
W.C. Hamilton in the International Tables for Crystallography, 1974 edition.
The object uses the following object data structure:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap1}
$\langle$hkldat {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ typedef struct __HKL {@\\
\mbox{}\verb@ pObjectDescriptor pDes;@\\
\mbox{}\verb@ double fUB[9];@\\
\mbox{}\verb@ double fLambda;@\\
\mbox{}\verb@ int iManual;@\\
\mbox{}\verb@ double fLastHKL[5];@\\
\mbox{}\verb@ int iNOR;@\\
\mbox{}\verb@ int iQuad;@\\
\mbox{}\verb@ pMotor pTheta;@\\
\mbox{}\verb@ pMotor pOmega;@\\
\mbox{}\verb@ pMotor pChi;@\\
\mbox{}\verb@ pMotor pPhi;@\\
\mbox{}\verb@ pMotor pNu;@\\
\mbox{}\verb@ pSelVar pMono;@\\
\mbox{}\verb@ long lID;@\\
\mbox{}\verb@ } HKL;@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
The fields are more or less self explaining:
\begin{description}
\item[pDes] The standard object descriptor.
\item[fUB] The UB matrix.
\item[iUB] is a flag which spcifies if a UB is specified.
\item[fLambda] The wavelength of the neutrons.
\item[iManual] A flag which defines if the wavelength has been set manually
or is updated automatically from a wavelength variable.
\item[fLastHKL] the HKL of the last reflection calculated.
\item[iNor] a flag for normal beam calculation mode.
\item[pTheta] The two theta motor. All motor are needed for boundary
checking.
\item[pOmega] The omega axis motor.
\item[pChi] The chi axis motor.
\item[pPhi] the phi axis motor.
\item[pNu] the nu axis motor for normal beam geometry.
This is detector tilt.
\item[pMono] The selector variable doing the wavelength.
\end{description}
The wavelength is a bit tricky. As it would be to time consuming to read two
motors each time a calculation is performed, the lambda variable is updated
by registering a callback with the selector variable handling the
monochromator wavelength. As TriCS will be run with two monochromators on a
lift a means has to be provided to change the selector variable online. An
additonal feature is that the wavelength can be manipulated manually. This
adresses the issue that automatic wavelength may be inaccurate due to
lazy instrument scientists not adjusting their instruments.
In terms of an interface the following functions will be provided by this
module:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap2}
$\langle$hklint {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ typedef struct __HKL *pHKL;@\\
\mbox{}\verb@/*-------------------------------------------------------------------------*/@\\
\mbox{}\verb@ pHKL CreateHKL(pMotor pTheta, pMotor pOmega, @\\
\mbox{}\verb@ pMotor pChi, pMotor pPhi, pMotor pNu);@\\
\mbox{}\verb@ void DeleteHKL(void *pData);@\\
\mbox{}\verb@ @\\
\mbox{}\verb@ int HKLFactory(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@/*------------------------------------------------------------------------*/@\\
\mbox{}\verb@ int SetWavelengthVariable(SConnection *pCon, pHKL self, pSelVar pVar);@\\
\mbox{}\verb@ int SetWavelengthManual(pHKL self, float fVal);@\\
\mbox{}\verb@ int SetUB(pHKL self, float fUB[9]);@\\
\mbox{}\verb@ int GetUB(pHKL self, float fUB[9]);@\\
\mbox{}\verb@ int SetNOR(pHKL self, int iNOB);@\\
\mbox{}\verb@ int GetLambda(pHKL self, float *fVal);@\\
\mbox{}\verb@ int GetCurrentHKL(pHKL self, float fVal[3]);@\\
\mbox{}\verb@ int GetCurrentPosition(pHKL self, SConnection *pCon, float fPosition[4]);@\\
\mbox{}\verb@@\\
\mbox{}\verb@ int CalculateSettings(pHKL self, float fHKL[3], float fPsi, int iHamil,@\\
\mbox{}\verb@ float fSet[4],SConnection *pCon);@\\
\mbox{}\verb@ int RunHKL(pHKL self, float fHKL[3], float fPsi, int iHamil, SConnection@\\
\mbox{}\verb@ *pCon);@\\
\mbox{}\verb@ int DriveHKL(pHKL self, float fHKL[3], float fPsi, int iHamil,@\\
\mbox{}\verb@ SConnection *pCon);@\\
\mbox{}\verb@@\\
\mbox{}\verb@ int DriveSettings(pHKL self, float fSet[4],SConnection *pCon);@\\
\mbox{}\verb@@\\
\mbox{}\verb@ int HKLAction(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]); @\\
\mbox{}\verb@@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
All functions return 0 on failure, 1 on success if not stated otherwise.
Most functions take a pointer to a HKL data structure as first parameter.
The function in more detail:
\begin{description}
\item[CreateHKL] creates a HKL object. The parameters are pointers to the
four four circle motors. Returns NULL on failure, a pointer to the new
object on success.
\item[DeleteHKL] properly removes an HKL object from the system.
\item[HKLFactory] The factory function which initialises an HKL object from
the initialisation script.
\item[SetWavelengthVariable] sets a new wavelength variable. Installs all
necesarry callbacks for automatic update.
\item[SetWaveLengthManual] deinstall all callbacks and forces the wavelength
to the value specified a second parameter.
\item[SetUB] sets the UB matrix.
\item[SetNOR] sets the normal beam calculation flag to iNOR.
\item[CalculateSettings] is the heart of this all. As the name suggests
calculates the settings for a four circle diffractometer. The parameters
are:
\begin{description}
\item[self] A pointer to a HKL data structure.
\item[fHKL] The reflection indices to calculate the settings for.
\item[fPsi] The psi value for the reflection. For psi scans. Set to 0 if not
used.
\item[iHamil] The index of the hamilton position to calculate. Can be an
integer between 0 to 8. 0 denotes the normal case.
\item[fSet] contains the required settings if the function returns with
success. 0 = two theta, 1 = omega, 2 = chi, 3 = phi.
\end{description}
The function returns 1 on success, a negative value on failure. Possible
error returns are:
\begin{description}
\item[HKLIMPOSSIBLE] the calculation was impossible.
\item[HKLTHETALIMIT] a setting could be calculated but can not be accessed
due to a limit on two theta.
\end{description}
\item[DriveHKL] calculates a setting and drives to the position. The
parameters are the same as with CalculateSettings. With the addition of a
pointer to the connection object doing the command for error messages and
everything. The error returns are the same as with CalculateSettings
well. With the addition of HKJMOTFAIL, which means that a motor failed to
drive properly.
\item[DriveSettings] drives to the the settings given in fSet.
\item[HKLAction] is the interpreter wrapper function for the HKL object.
\end{description}
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap3}
\verb@"hkl.i"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*-------------------------------------------------------------------------@\\
\mbox{}\verb@ H K L@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Internal data structure description. See hkl.h, c,w for more details.@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Mark Koennecke, February 1998@\\
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
\mbox{}\verb@@$\langle$hkldat {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap4}
\verb@"hkl.h"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*---------------------------------------------------------------------------@\\
\mbox{}\verb@ H K L@\\
\mbox{}\verb@ This SICS object performs angle setting calculations for a four circle @\\
\mbox{}\verb@ diffractometer. The heart of this code is a C transcriptions of routines@\\
\mbox{}\verb@ written by Jean Allibon at ILL for the MAD program. Theory is explained in@\\
\mbox{}\verb@ the article by W. C. Hamilton in International Tables for Crystallography,@\\
\mbox{}\verb@ 1974 edition.@\\
\mbox{}\verb@@\\
\mbox{}\verb@ copyright: see copyright.h@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Mark Koennecke, February 1998@\\
\mbox{}\verb@@\\
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
\mbox{}\verb@#ifndef SICSHKL@\\
\mbox{}\verb@#define SICSHKL@\\
\mbox{}\verb@#include "selector.h"@\\
\mbox{}\verb@#include "selvar.h"@\\
\mbox{}\verb@@$\langle$hklint {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@#endif @\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}

111
doc/programmer/hklscan.tex Normal file
View File

@ -0,0 +1,111 @@
\subsection{hklscan}
hklscan is an object which implements scanning in reciprocal space. It belongs
to the four circle diffraction line of commands. It requires the hkl object
for doing four circle calculations and a scan object for doing the scanning.
The scan object is configured by overloading its WriteScanPoints and
ScanDrive functions to do the right thing for this. Thus most of the work
is done in scan and hkl.
hklscan has its own data structure looking like this:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap1}
$\langle$hklscandat {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ typedef struct __HKLSCAN {@\\
\mbox{}\verb@ pObjectDescriptor pDes;@\\
\mbox{}\verb@ pScanData pScan;@\\
\mbox{}\verb@ pHKL pCalc; @\\
\mbox{}\verb@ float fStart[3];@\\
\mbox{}\verb@ float fStep[3];@\\
\mbox{}\verb@ float fPos[3];@\\
\mbox{}\verb@ } sHklscan;@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
\begin{description}
\item[pDes] The standard object descriptor.
\item[pScan] The scan object used for scanning.
\item[pCalc] The hkl object used for crystallographic computations.
\item[fStart] The start values in H, K, L for scanning.
\item[fStep] The step width in H, K, L.
\item[fPos] The last position in H, K, L.
\end{description}
The hklscan object defines the following external interface:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap2}
$\langle$hklscanfunc {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ typedef struct __HKLSCAN *pHklscan;@\\
\mbox{}\verb@/*--------------------------------------------------------------------------*/@\\
\mbox{}\verb@ int HklScan(pHklscan self, SConnection *pCon, int iNP, int iMode,@\\
\mbox{}\verb@ float fPreset);@\\
\mbox{}\verb@/*---------------- interpreter functions -----------------------------------*/@\\
\mbox{}\verb@ int HklscanFactory(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@ int HklscanAction(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap3}
\verb@"hklscan.i"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*-------------------------------------------------------------------------@\\
\mbox{}\verb@ Internal data structure for the hklscan object. DO NOT MODIFY. @\\
\mbox{}\verb@ Modifications only in hklscan.i@\\
\mbox{}\verb@ @\\
\mbox{}\verb@ Mark Koennecke, June 1999@\\
\mbox{}\verb@--------------------------------------------------------------------------*/@\\
\mbox{}\verb@@$\langle$hklscandat {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap4}
\verb@"hklscan.h"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*--------------------------------------------------------------------------@\\
\mbox{}\verb@ H K L S C A N@\\
\mbox{}\verb@@\\
\mbox{}\verb@ A class for doing scans in reciprocal space. This makes only sense at an@\\
\mbox{}\verb@ four circle diffractometer. Most of the work is done in the HKL and scan@\\
\mbox{}\verb@ objects. This class just adapts and used both objects to do the right thing.@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Mark Koennecke, June 1999@\\
\mbox{}\verb@---------------------------------------------------------------------------*/@\\
\mbox{}\verb@#ifndef HKLSCAN@\\
\mbox{}\verb@#define HKLSCAN@\\
\mbox{}\verb@@$\langle$hklscanfunc {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@#endif@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}

32
doc/programmer/ini.tex Normal file
View File

@ -0,0 +1,32 @@
\subsection{Initialisation file management}
This module supports initialisation files with a simple structure.
This is used to hold the internal SICS server options which are
installed with the SicsOption initialisation commands. All the file
handling stuff is dead code not used by SICS as of current. Any line
is intended to
contain one name value pair separated by an equlity sign. Lines beginning
with a \verb+#+ are treated as comments, other lines not conforming to the name =
value scheme are ignored. Another option (and the currently preferred one)
to get values into the initialisation database is to use a special command
SicsOption from the SICS initialisation file.
These initialisation files are manipulated through
the ifile module, implemented in ifile.h and ifile.c. The class in more
detail:
After reading the configuration options are stored in memory as a linked list with entries if the type shown below. \begin{verbatim}
typedef struct __IFileE
{
char *name;
char *value;
struct __IFileE *pNext;
} IPair;
\end{verbatim}
This datastructure is manipulated using the following functions:\begin{itemize}
\item {\bf IPair *IFReadConfigFile(FILE *fp) }, expects as input a pointer to the configuration file. Than the function will read the file and initialise the configuration linked list from the data found in the file. On success a pointer to the head of the linked list is returned which is to be used in further calls to the configuration management functions. On failure NULL is returned.
\item {\bf char *IFindOption(IPair *pList,char *name) }. Input is a pointer to a configuration list as returned by IFReadConfigFile and the name of the option requested (case sensitive). If this option exists a pointer to its value will be returned, else NULL. Never, ever, free the returned pointer as it belongs to this module.
\item {\bf IPair *IFAddOption(IPair *pList,char *name, char *value) } Adds a name value pair to the list specified as first parameter. Returns a pointer to the new list including the new name value pair on succes, else the old pointer specified as input.
\item {\bf int IFSaveOptions(IPair *pList,FILE *fp) }. Saves the options in the list to the file fp.
\item {\bf void IFDeleteOptions(IPair *pList) }. Use this to delete the list after use. The list pList is no longer valid after this call. Omission of this call will result in wasted memory.
\end{itemize}

View File

@ -0,0 +1,52 @@
\subsection{Integrate}
For four circle diffractometers it is usefull to be able to integrate the
intensity of the peak from a collected counting profile. This module does
just this. It uses the method as described by Grant \& Gabe in J. Appl. Cryst
(1987), 11, 114-120. This method uses a moving window technique for finding
the limits of the peak. This method was choosen for reason of its
simplicity. The authors state, that the results are comparable to the
Lehmann Larsen method used elsewhere. This is a utility module. Just a
single function is implemented:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap1}
\verb@"integrate.h"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*--------------------------------------------------------------------------@\\
\mbox{}\verb@@\\
\mbox{}\verb@ I N T E G R A T E@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Peak integration follwing the method described by Grant & Gabe in@\\
\mbox{}\verb@ J. Appl. Cryst (1978), 11, 114-120.@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Mark Koennecke, March 1998@\\
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
\mbox{}\verb@#ifndef GABEINTEGRATE@\\
\mbox{}\verb@#define GABEINTEGRATE@\\
\mbox{}\verb@@\\
\mbox{}\verb@#define INTEGLEFT -1@\\
\mbox{}\verb@#define INTEGRIGHT -2@\\
\mbox{}\verb@#define INTEGNOPEAK -3@\\
\mbox{}\verb@#define INTEGFUNNYBACK -4@\\
\mbox{}\verb@@\\
\mbox{}\verb@ int GabePeakIntegrate(int m, int iCounts, long lCounts[], @\\
\mbox{}\verb@ float *fIntens, float *fVariance);@\\
\mbox{}\verb@#endif@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}
Input to this routine is the number of counts and the counts themselves.
Then m, the number of lookahead points to use. As a result fIntens will
contain the summed Intensity and fVariance the sigma of the summed
intensity. The function retusn 1 for success or a negative error code in
case of trouble. These error codes are:
\begin{description}
\item[INTEGLEFT] no left side background found.
\item[INTEGRIGHT] nor right side background found.
\item[INTEGNOPEAK] The data does not contain a peak.
\item[INTEGFUNNYBACK] the data has a strange background.
\end{description}

69
doc/programmer/inter.tex Normal file
View File

@ -0,0 +1,69 @@
\subsection{The SICS Interpreter}
The SicsInterpreter implements a Tcl-look alike command list with each
object having a similar wrapper function to those used in Tcl. But
augmented with a pointer to a Connection structure in order to enable
authorisation checking and providing the I/O context. The object wrapper
function has a prototype looking like this:
{\bf int ObjectWrapper(SConnection *pCon, SicsInterp *pInter, void *pData,
int argc, char *argv); }
pCon is the connection responsible for this call and holds necessary
information for authorisation checking. pInter is the Sics interpreter.
pData is a pointer to an object specific datastructure (the struct holding
the motor data for instance). Argc and argv hold the arguments as in a C
main program. The object wrapper is meant to evaluate the arguments, do the
right thing to the object with them and than pass results back. There are
two ways to do that. The prefered one is to copy results or error messages
into the interpreters result space and associate an output code with the
result space. After returning the interpreter will than copy these results
to the client. However, a scan routine might want to print status
information to the client during a lengthy operation. In this case the
object can write directly to the connnection usinfg the provided connection
pointer. The object wrapper function returns true or false depending on the
success of the operation.
The command list is a doubly linked list holding for each command a record
containing: the commands name, a pointer to the objects object function, a
pointer to the objects data structure (passed as pData) on invocations and a
pointer to a function which is capable to delete the objects data structure.
This function will be called when the object/command is removed. In the end
the SicsInterpreter implements the following datastrucures an
interfaces:\begin{verbatim} typedef struct __Clist {
char *pName;
ObjectFunc OFunc;
KillFunc KFunc;
void *pData;
struct __Clist *pNext;
struct __Clist *pPrevious;
} CommandList;
\end{verbatim}
The structure held in a doubly linked list for each command.\begin{verbatim}
typedef struct __SINTER
{
CommandList *pCList;
char *pErrors;
int iSpace;
OutCode eOut;
}SicsInterp;
\end{verbatim}
The interpreter data structure. Access only through the interface functions given below:\begin{itemize}
\item {\bf SicsInterp *InitInterp(void) } creates a new interpreter. Returns a pointer on success, NULL on failure.
\item {\bf int AddCommand(SicsInterp *pInterp, char *pName, ObjectFunc pFunc, KillFunc pKFunc, void *pData); } adds a new command to the commandlist of the specified interpreter. Returns True or false depending on success.
\item {\bf int RemoveCommand(SicsInterp *pInterp, char *pName) } finds command name and removes it from the list. Returns True on success (command found) and False if it fails.
\item {\bf int InterpExecute(SicsInterp *self,pSConnection pCon, char *pCommand) } executes pcommand in the SICS interpreter. Returns -1 if the command did not exist. If ist exists True or False is returned depending on the success of the command.
\item {\bf int InterpWriteResult(SicsInterp *self,char *text) } used within object wrapper functions to append result text to the interpreter. Allocating sufficient memory is taken care of by this function.
\item {\bf void InterpSetOutCode(SicsInterp *self, OutCode eCode) } does what it says.
\item {\bf OutCode InterpGetOutCode(SicsInterp *self) } return the current output code for the interpreters result.
\item {\bf CommandList *FindCommand(SicsInterp *pInterp, char *name) } return a pointer to a commandlist structure if the object specified by name exists, NULL else. Used in the definition of interpreter and macro functionality.
\item {\bf const char *InterpGetResult(SicsInterp *self) } returns a pointer to the interpreter result space. This space is managed by the interpreter, never ever delete it in client code.
\item {\bf void DeleteInterp(SicsInterp *self) } removes the interpreter, his command list etc. Frees all allocated memory for this interpreter.
\item {\bf WriteSicsStatus(SicsInterp *pSics, char *file)} opens the file
for writing and writes the current status of SICS objects int the file. In
order to do so, the SaveStatus function of each object registered in the
interpreter is called.
\end{itemize}

View File

@ -0,0 +1,497 @@
\subsection{Object interfaces}\label{inter}
In order to present themselves to the system SICS objects need to adhere to
certyain interfaces. These interfaces are described in this
section. Thus this section is one of the most important sections of
theis document, read carefully!
A first
requirement was that it must be possible to inquire the capabilities of an
object at run time. A second one was that the system should be extendable.
This means it should be possible to add new interfaces or modify them as the
need arises. In order to achieve this the idea of the interface
datastructure (INDS) was conceived. An INDS contains all the variables and
functions which make up an interface. Then it is possible to create such a
datastructure and pass it around. Each object can now be requested to pass
an INDS of a certain type on demand. What is still needed is a standard way
of asking a SICS object for such a datastructure. This is achieved by the
means of the object descriptor. This is a datastructure which contains
everything necessary to identify an object to SICS. This requires a
convention which is that {\em each SICS objects has to have a pointer to an
object descriptor as first element of its own datastructure.} All this
probably gets clearer once the actual datastructures have been discussed.
As usual, functions return 1 on success and 0 on failure.
\subsubsection{The object descriptor}
Let's start with the objectdescriptor:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap1}
$\langle$obdes {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*--------------------------------------------------------------------------@\\
\mbox{}\verb@ In SICS there is the to find out what an@\\
\mbox{}\verb@ object is capable of at runtime. If this has been done a general@\\
\mbox{}\verb@ way to access those capabilities is needed. In order to do all@\\
\mbox{}\verb@ this each SICS-object is required to carry an object descriptor@\\
\mbox{}\verb@ struct as first parameter in its class/object struct. Additionslly@\\
\mbox{}\verb@ it is required to initialize this struct to something sensible.@\\
\mbox{}\verb@ @\\
\mbox{}\verb@ This file defines this struct. Additionally a few functions of@\\
\mbox{}\verb@ general use are prototyped.@\\
\mbox{}\verb@ @\\
\mbox{}\verb@ Mark Koennecke, June, 1997@\\
\mbox{}\verb@ @\\
\mbox{}\verb@ copyrigth: see implementation file @\\
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
\mbox{}\verb@#ifndef SICSDESCRIPTOR@\\
\mbox{}\verb@#define SICSDESCRIPTOR@\\
\mbox{}\verb@#include <stdio.h>@\\
\mbox{}\verb@@\\
\mbox{}\verb@ typedef struct {@\\
\mbox{}\verb@ char *name;@\\
\mbox{}\verb@ int (*SaveStatus)(void *self, char *name,FILE *fd);@\\
\mbox{}\verb@ void *(*GetInterface)(void *self, int iInterfaceID);@\\
\mbox{}\verb@ } ObjectDescriptor, *pObjectDescriptor;@\\
\mbox{}\verb@@\\
\mbox{}\verb@ /*---------------------------------------------------------------------------*/@\\
\mbox{}\verb@ pObjectDescriptor CreateDescriptor(char *name);@\\
\mbox{}\verb@ void DeleteDescriptor(pObjectDescriptor self);@\\
\mbox{}\verb@ @\\
\mbox{}\verb@/*============================================================================@\\
\mbox{}\verb@ Objects which do not carry data need a dummy descriptor. Otherwise@\\
\mbox{}\verb@ drive or scan will protection fault when trying to drive something@\\
\mbox{}\verb@ which should not be driven. This is defined below.@\\
\mbox{}\verb@*/@\\
\mbox{}\verb@@\\
\mbox{}\verb@typedef struct {@\\
\mbox{}\verb@ pObjectDescriptor pDescriptor;@\\
\mbox{}\verb@ }Dummy, *pDummy;@\\
\mbox{}\verb@ @\\
\mbox{}\verb@@\\
\mbox{}\verb@ pDummy CreateDummy(char *name);@\\
\mbox{}\verb@ void KillDummy(void *pData); @\\
\mbox{}\verb@@\\
\mbox{}\verb@ int iHasType(void *pData, char *Type);@\\
\mbox{}\verb@ @\\
\mbox{}\verb@#endif @\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
The first element of the object descriptor is a {\bf name} which is better
described as a type identifier. This specifies the type of the object.
The function {\bf SaveStatus} will be called automatically by SICS when the
server is closing down or a status backup is requested. Each object is meant
to print the commands necessary to configure it back into its current state
into the file passed as a parameter. The idea is that by executing the file
thus created the system gets back into the state before closedown.
The heart of the interface system is the {\bf GetInterface}
function. It takes as arguments a pointer to the datastructure on which it
is called and an integer ID
for the interface. These ID's are defined in the file interface.h. This
function is meant to return a pointer to the apropriate interface
datastructure after this call. If the object does not implement the interface
requested, this function should return NULL. New interfaces can be added
into the scheme by defining new ID's, interfaces and objects which implement
them.
It is {\bf important} to note, that the objects themselves are responsible
for allocating and freeing memory for the interface structures. Client never
should need to worry how to dispose of these structures. Moreover this
scheme ensures that changes to the interface due to some command given to
the object are immediatetly visible through the whole system.
Additionally this header file defines a few relatively uninteresting
functions for object descriptor maintainance. Slightly more interesting is
the Dummy structure, which will be used to find the object descriptor in a
given objects data structure.
\subsubsection{The drivable interface}
As first example of an interface the drivable interface will be given. This
interface is implemented by all devices or varaibles which can be driven to
a value. Most notable example are motors, but composite variables and
environment controllers fit this bill as well.
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap2}
$\langle$driv {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@@\\
\mbox{}\verb@ typedef struct {@\\
\mbox{}\verb@ int ID;@\\
\mbox{}\verb@ int (*Halt)(void *self);@\\
\mbox{}\verb@ int (*CheckLimits)(void *self, float fVal, @\\
\mbox{}\verb@ char *error, int iErrLen);@\\
\mbox{}\verb@ long (*SetValue)(void *self, SConnection *pCon,@\\
\mbox{}\verb@ float fVal);@\\
\mbox{}\verb@ int (*CheckStatus)(void *self, SConnection *pCon);@\\
\mbox{}\verb@ float (*GetValue)(void *self, SConnection *pCon); @\\
\mbox{}\verb@ int iErrorCount;@\\
\mbox{}\verb@ } IDrivable, *pIDrivable;@\\
\mbox{}\verb@@\\
\mbox{}\verb@ pIDrivable GetDrivableInterface(void *pObject); @\\
\mbox{}\verb@@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
The first member of this structure is an ID which can be used in order to
check if the right datastructure has been obtained.
The second field is a pointer to a {\bf Halt} function. This function will be
called in an emergency and is meant to send a stop command to the device.
The third field is a pointer to the {\bf CheckLimits} function. This function is
given a float value as second parameter. This is the new value the device
should go to. CheckLimits checks if this position is permitted. If so it
returns 1 else 0.
The {\bf SetValue} member is a pointer to a function which actually makes the
object start to move to its new position.
The {\bf CheckStatus} function will be called in order to check for the current
status of the device during operation. Possible return values are:
\begin{itemize}
\item OKOK if everything is OK.
\item HWIdle if the device is idle i. e. doing nothing.
\item HWFault if the device is in trouble.
\item HWBusy if the device is still running.
\item HWPosFault when the device is principally OK but has not reached the
position specified, for instance because somebody has put a slab of concrete
into the instruments way.
\end{itemize}
The last function which makes up this interface is {\bf GetValue} which is meant
to return the current position of the device.
{\bf iErrorCount} is the number of number of failed driving commands on this drivable
item. This can be used by motors to check and abort the experiment if there
are to many errors. This is to stop a scan command hammer at a blocked motor
a hundred times.
{\bf GetDrivableInterface} is a convenience function which checks object pData for
the existence of a drivable interface. If it exists a pointer to it will be
returned. NEVER free this pointer. If no drivable interface exists, NULL
will be returned.
\subsubsection{The Countable Interface}
This is an interface for interacting with anything which counts.
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap3}
$\langle$count {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ typedef struct {@\\
\mbox{}\verb@ int ID;@\\
\mbox{}\verb@ int (*Halt)(void *self);@\\
\mbox{}\verb@ int (*StartCount)(void *self, SConnection *pCon);@\\
\mbox{}\verb@ int (*CheckCountStatus)(void *self, SConnection *pCon);@\\
\mbox{}\verb@ int (*Pause)(void *self, SConnection *pCon);@\\
\mbox{}\verb@ int (*Continue)(void *self, SConnection *pCon);@\\
\mbox{}\verb@ int (*TransferData)(void *self, SConnection *pCon);@\\
\mbox{}\verb@ } ICountable, *pICountable;@\\
\mbox{}\verb@@\\
\mbox{}\verb@ pICountable GetCountableInterface(void *pObject); @\\
\mbox{}\verb@@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
{\bf Halt and StartCount} are self explaining, they just do what they say. Please
note, that counting configuration must have happened before usage of this
interface.
{\bf Pause} pauses a data aquisition. It does NOT abort it. {\bf Continue}
continues a paused data aquisition.
{\bf CheckCountStatus} works much like CheckStatus in the IDrivable interface
described above. However, there is an additional return code: HWNoBeam. This
is retuned if a monitor is below a certain threshold, i. e. the beam is off.
{\bf TransferData} will be called at the end of each counting operation and is
meant to update the internal datastructures of the counter. Some counters
choose to keep the last count in their own datastructure, some such as
histogram memories might choose to leave them in the hardware. This function
has been conceived in order to ensure that the first type of counters is
supported.
{\bf GetCountableInterface} is a convenience function which checks object pData for
the existence of a countable interface. If it exists a pointer to it will be
returned. NEVER free this pointer. If no countable interface exists, NULL
will be returned.
\subsubsection{The Callback Interface}
The Callback Interface is SICS suport for component behaviour for objects.
Consider objects A and B. A now is able to generate certain events when it's
state changes. For instance if A is a variable that its value is changed.
B may then choose to register a function with A which gets automatically
called whenever A generates the apropriate event. B is thus automatically
notified about A's status change and can act accordingly to it. In contrast
to the interfaces defined above, this interface is defined in terms of a set
of functions which manipulate the interface and not as a data structure of
overloadable functions.
The first thing to define for such an interface is the type of the callback
function:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap4}
$\langle$callfunc {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ typedef void (*KillFuncIT)(void *pData);@\\
\mbox{}\verb@ typedef int (*SICSCallBack)(int iEvent, void *pEventData, @\\
\mbox{}\verb@ void *pUserData);@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
The callback function is meant to return 0 for failure or 1 for success.
This infomation may be needed by an event invoking object if to continue an
operation or not. The first parameter passed to {\bf SICSCallBack} is the id of
the generated event. Clearly the communicating objects need to agree on
these event. In SICS events types will be held in an header file event.h.
The next parameter to SICSCallBack is a pointer to void. The event
generating object may choose to pass additional data along with the event.
Suitable event datastructures are also defined in event.h. The last
parameter to SICSCallBack is a pointer to a datastructure defined by the
owner of the callback routine when registering the callback. {\bf pKill} is a
function which will be called automatically when the callback is deleted and
whose sole task is to delete pUserData properly.
Then there are the functions needed to interface with the callback
interface:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap5}
$\langle$cifunc {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ typedef struct __ICallBack *pICallBack;@\\
\mbox{}\verb@ @\\
\mbox{}\verb@ /* event source side */@\\
\mbox{}\verb@ pICallBack CreateCallBackInterface(void);@\\
\mbox{}\verb@ void DeleteCallBackInterface(pICallBack self);@\\
\mbox{}\verb@ int InvokeCallBack(pICallBack pInterface, int iEvent, void *pEventData); @\\
\mbox{}\verb@@\\
\mbox{}\verb@ /* callback client side */@\\
\mbox{}\verb@ long RegisterCallback(pICallBack pInterface, int iEvent, SICSCallBack pFunc,@\\
\mbox{}\verb@ void *pUserData, KillFuncIT pKill);@\\
\mbox{}\verb@ int RemoveCallback(pICallBack pInterface, long iID);@\\
\mbox{}\verb@ int RemoveCallback2(pICallBack pInterface, void *pUserData);@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
The callback interface has two parts: A part the event generating object has
to deal with and a part the interested object has to use. There is no way of
enforcing this convention. However, SICS programmers should stick to it,
otherwise weird things may happen.
The first two functions just deal with creating and deleting the callback
interface data structure. {\bf CreateCallBackInterface} returns NULL if the
request fails, or a pointer on success.
{\bf InvokeCallBack} is responsible for invoking the registered callback functions
and will be called only by the source object for the event. This function
will scan the list of registered callback function for callback function
which are registered for the event ID specified as second parameter. Each of
them will be invoked with the event data given as third parameter. If any of
the callback functions returns Failure this function will do so as well.
Else 1 is returned. The event data structure belongs to the object invoking
the callback. It should never be deleted in callback functions.
The next functions deal with the client side of the callback interface.
{\bf RegisterCallBack} registers a callback function with the interface. The first
parameter is the interface to register the callback with. The second
parameter is the event ID for which this callback is defined. pFunc is the
pointer to the actual callback function. Finally pUserData is a pointer to
some user defined data structure which shall be passed as pUserData when the
callback is called. RegisterCallback retuns a long value which server as an
identifier for the callback registration. If the registration fails, this
function returns 0.
{\bf RemoveCallBack} is used to delete a registered callback. The first parameter
is the interface to act upon, the second is the callback ID as returned by
RegisterCallBack.
{\bf RemoveCallback2} is another variant for removing callbacks. This time the
search key for deletion is the pointer to user data. All callbacks related
to this user data in the interface specified will be removed.
All these functions are implemented in the file callback.c.
\subsubsection{The Environment Interface}
This interface is used by the environment monitor in order to monitor
the status of a environment controller. The interface looks like this:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap6}
$\langle$envir {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ typedef enum { EVIdle, EVDrive, EVMonitor, EVError } EVMode;@\\
\mbox{}\verb@ typedef struct {@\\
\mbox{}\verb@ int iID;@\\
\mbox{}\verb@ EVMode (*GetMode)(void *self);@\\
\mbox{}\verb@ int (*IsInTolerance)(void *self);@\\
\mbox{}\verb@ int (*HandleError)(void *self);@\\
\mbox{}\verb@ } EVInterface, *pEVInterface;@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
The enum {\bf EVMode} describes the mode a environment controller can be in. The
default is Idle, no action necessary. EVDrive means that the controller is
currently being driven to a new value and the device executor has control.
EVMonitor means that the environment monitor has to take care of the
controller. EVError is set if the controller is out of tolerances.
{\bf GetMode} retrieves the current operation mode of the controller.
{\bf IsInTolerance} returns 1 if the controller is still within tolerances,
0 otherwise.
{\bf HandleError} will be automatically called when IsInTolerance returns 0.
Its purpose is to implemnt the error handling startegy for the controller
in question.
The environment interface has just one function associated with it:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap7}
$\langle$envfunc {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ pEVInterface CreateEVInterface(void);@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
{\bf CreateEVInterface} just creates an environment interface.
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap8}
\verb@"obdes.h"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@@$\langle$obdes {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap9}
\verb@"interface.h"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*---------------------------------------------------------------------------@\\
\mbox{}\verb@ I N T E R F A C E S@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Any object in SICS has to adhere to the object descriptor interface (see@\\
\mbox{}\verb@ file obdes.h). Furthermore SICS objects may choose to support other@\\
\mbox{}\verb@ interfaces as well. These interfaces are defined.@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Mark Koennecke, June 1997@\\
\mbox{}\verb@@\\
\mbox{}\verb@ For more documentation see interface.w, interface.tex@\\
\mbox{}\verb@@\\
\mbox{}\verb@ copyright: see SICS impelementation files@\\
\mbox{}\verb@---------------------------------------------------------------------------*/@\\
\mbox{}\verb@@\\
\mbox{}\verb@#ifndef SICSINTERFACES@\\
\mbox{}\verb@#define SICSINTERFACES@\\
\mbox{}\verb@@\\
\mbox{}\verb@/* interface ID's used to recognize an interface */@\\
\mbox{}\verb@#define DRIVEID 513@\\
\mbox{}\verb@#define COUNTID 713@\\
\mbox{}\verb@#define CALLBACKINTERFACE 947@\\
\mbox{}\verb@#define ENVIRINTERFACE 949@\\
\mbox{}\verb@@\\
\mbox{}\verb@/* ----------------------- The drivable interface -----------------------*/@\\
\mbox{}\verb@@$\langle$driv {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@@\\
\mbox{}\verb@ pIDrivable CreateDrivableInterface(void);@\\
\mbox{}\verb@@\\
\mbox{}\verb@/* ------------------------ The countable interface ---------------------*/@\\
\mbox{}\verb@@$\langle$count {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@@\\
\mbox{}\verb@ pICountable CreateCountableInterface(void);@\\
\mbox{}\verb@@\\
\mbox{}\verb@/* ------------------------- The CallBack Interface --------------------*/@\\
\mbox{}\verb@@$\langle$callfunc {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@@$\langle$cifunc {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@/*---------------------- The Environment Interface --------------------*/@\\
\mbox{}\verb@@$\langle$envir {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@@$\langle$envfunc {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@#endif@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}
\subsection{More interfaces}
For completeness it should be mentioned that besides these interfaces
there exist further important interfaces in SICS. This includes the
interface to the SICS interpreter defined in
\ref{scinter}. Furthermore the data structures defined for the various
types of drivers within SICS may be considered interfaces as
well. Then there is the interface to the client as defined by the
functions of the connection interface.

View File

@ -0,0 +1,53 @@
\subsection{Interrupt Handling}
SICS needs a way to interrupt server processsing. This is done
with this module.
Interrupts may come in through two ways: They may be created
internally or they may be user requested. For the last ones
the main loop will poll an additional special interrupt
port.
In order to do interrupting a set of interrupt codes are defined:
\begin{verbatim}
#define eContinue 0
#define eAbortOperation 1
#define eAbortScan 2
#define eAbortBatch 3
#define eHaltSystem 4
#define eFreeSystem 5
#define eEndServer 6
\end{verbatim}
Their meanings:
\begin{description}
\item[eContinue] Go on, interrupt nothing.
\item[eAbortOperation] stop current hardware operation but no scans or
batchfiles.
\item[eAbortScan] stop current scan or operation but continue processing of
batch files with next command.
\item[eAbortBatch] Stop all processing, even batch files.
\item[eHaltSystem, eFreeSystem] are currently unused.
\item[eEndServer] is used internally by the SicsExitus command to run down
the server.
\end{description}
The interrupt module supports the following interface:
\begin{description}
\item[void ServerStopInterrupt(void)] stops interrupt processing.
\item[void SetInterrupt(int iCode)]
Send an interrupt to all connections. Use with care! More often an
interrupt need to be set on a special connection. This can be done with
SCSetInterrupt defined in conman.h.
\item[int Interrupt2Text(int iInterrupt, char *text, int iTextLen)] converts
iInterrupt to a text. Maximum iTextLen characters will be copied to text.
\item[int Text2Interrupt(char *text)] Converts text, when applicable to an
interrupt code which is returned. If the text is invalid -1 is returned.
\item[int ClientSetupInterrupt(char *host, int iPort)] Creates a client side
interrupt UDP port.
\item[void ClientStopInterrupt(void)] removes an client side interrupt port
created by ClientSetupInterrupt.
\item[void SendInterrupt( int iCode)] sends an interrupt through the UDP
port.
\end{description}
Please note, that the interrupt implementation is distributed into two
files: intserv.c for the server side stuff and intcli.c for the client side
part. UDP interrupting is not fully tested.

107
doc/programmer/itc4.tex Normal file
View File

@ -0,0 +1,107 @@
\subsubsection{Oxford Instruments ITC4 Temperature Controllers}
SINQ makes heavy use of Oxford Instruments ITC4 temperature controllers. In
order to support them the following software components had to be defined in
addition to the basic environmet controller interfaces:
\begin{itemize}
\item ITC4driver, naturally.
\item A ITC4-controller object as derivation of environment controller. ITC4
's allow you to select a sensor which you read as your standard sensor and a
sensor which is used for automatic control. The ITC4 controller object adds
just that additional functionality to the statndard environment controller.
\end{itemize}
The additional data, the selection of sensors, will be kept in the driver.
This serves also an example for implementing inheritance without C++.
The driver interface:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap1}
$\langle$itcd {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ pEVDriver CreateITC4Driver(int argc, char *argv[]);@\\
\mbox{}\verb@ int ConfigITC4(pEVDriver self);@\\
\mbox{}\verb@ int SetSensorITC4(pEVDriver self, int iSensor);@\\
\mbox{}\verb@ int SetControlITC4(pEVDriver self, int iSensor);@\\
\mbox{}\verb@ int GetSensorITC4(pEVDriver self);@\\
\mbox{}\verb@ int GetControlITC4(pEVDriver self);@\\
\mbox{}\verb@ int SetDivisorITC4(pEVDriver self, float iSensor);@\\
\mbox{}\verb@ float GetDivisorITC4(pEVDriver self);@\\
\mbox{}\verb@ int SetMultITC4(pEVDriver self, float iSensor);@\\
\mbox{}\verb@ float GetMultITC4(pEVDriver self);@\\
\mbox{}\verb@ int SetTMOITC4(pEVDriver self, int iSensor);@\\
\mbox{}\verb@ int GetTMOITC4(pEVDriver self);@\\
\mbox{}\verb@@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
The ConfigITC4 is special. It has to be called to commit changes to the
driver read and control parameters.
The ITC4 object interface:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap2}
$\langle$itco {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ int ITC4Wrapper(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@ int ITC4SetPar(pEVControl self, char *name, float fNew, @\\
\mbox{}\verb@ SConnection *pCon);@\\
\mbox{}\verb@ int ITC4GetPar(pEVControl self, char *name, float *fVal);@\\
\mbox{}\verb@ int ITCList(pEVControl self, SConnection *pCon);@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
The functions defined are: new parameter handling functions, with just
support for the two extra parameters added and a new Wrapper function for
SICS. The meaning of all these functions, their parameters and return values
are identical to those defined for an environment controller. Additionally,
the standard environment controller functions will work as described. The
functions described above are just needed to implement the extra parameters.
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap3}
\verb@"itc4.h"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*-------------------------------------------------------------------------@\\
\mbox{}\verb@ ITC 4@\\
\mbox{}\verb@ @\\
\mbox{}\verb@ Support for Oxford Instruments ITC4 Temperature controllers for SICS.@\\
\mbox{}\verb@ The meaning and working of the functions defined is as desribed for a@\\
\mbox{}\verb@ general environment controller.@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Mark Koennecke, Juli 1997@\\
\mbox{}\verb@@\\
\mbox{}\verb@ copyright: see implementation file.@\\
\mbox{}\verb@@\\
\mbox{}\verb@-----------------------------------------------------------------------------*/@\\
\mbox{}\verb@#ifndef SICSITC4@\\
\mbox{}\verb@#define SICSITC4@\\
\mbox{}\verb@/*------------------------- The Driver ------------------------------------*/@\\
\mbox{}\verb@@$\langle$itcd {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@/*------------------------- The ITC4 object ------------------------------*/@\\
\mbox{}\verb@@$\langle$itco {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@@\\
\mbox{}\verb@#endif @\\
\mbox{}\verb@ @\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}

View File

@ -0,0 +1,355 @@
\chapter{Guide To SICS Kernel Facilities}
In this chapter the facilities of the SICS servers kernel will be examined
more closely. All the kernel modules and their function will be listed,
together with some explanatory information and an overview about the
application programmers interfaces (API) provided. This section should
answer the questions: WHat is available?, Where to find what?,
Why did they do that? Details of
the API's mentioned are given in the reference section.
The SICS servers kernel consists of the following objects and modules:
\begin{itemize}
\item The task manager , Files tasker.*.
\item The network reader, Files nread.*.
\item The network module, Files network.*.
\item The connection object, Files conman.*.
\item The SICS interpreter, Files SCinter.*.
\item The SICS macro facility, Files macro.*, script.*.
\item The device executor, Files devexec.*.
\item The environment monitor, Files emon.c.
\item The server himself, Files nserver.*
\item The serverlog, Files servlog.*.
\item A performance monitor, Files perfmon.*.
\item The object factory, Files ofac.*.
\item The options database, Files ifile.*.
\item The password database, Files passwd.*.
\item The main program, File SICSmain.c.
\end{itemize}
\section{The Task Manager}
The task manager implements cooperative multitasking in SICS. A task in the
SICS sense is defined by a function, the task function. It is of the type:
\begin{verbatim}
int TaskFunction(void *pData);
\end{verbatim}
When it is time for the task to execute this function is called, with a
parameter to a the tasks own data structure. This data structure must have
been defined by the user of this module. The task function returns 1, if it
shall continue to live, or 0 if it should be deleted from the task list.
These task functions are kept in a list. The elements of this list are
visited cyclically, when the scheduler runs.
The API to this object consists of functions for creating a task manager,
adding tasks to the task list and to run the task list. Other functions
allow to put a task into a wait state. This means that the task will not
execute until another task has died (returned 0). Then the waiting task will
continue execution at the point where it has called the wait function.
For example, consider a task which wants to wait for say 10 seconds. This
tasks name shall be BedTask. It does so by starting a second task, called
ClockTask which checks if 10 seconds have passed and dies after this.
BedTask then waits for this task. This makes BedTask look like this:
\begin{verbatim}
int BedTask(void *pData)
{
/* Code block 1.
Fill in horrendously complex operations here.
*/
lID = TaskRegister(pTasker, ClockTask,....)
TaskWait(pTasker, lID, ....);
/* Code block 2.
More horrendous computations.
Will be executed after ClockTask died.
*/
/* Beds never die!!! */
return 1;
}
\end{verbatim}
and ClockTask:
\begin{verbatim}
int ClockTask(void *pData)
{
if(10 seconds are gone)
{
/* death is lurking */
return 0;
}
else
{
/* continue running */
return 1;
}
}
\end{verbatim}
The task manager supports a primitive means of inter task communication as
well. Each registered task may not only have a task function associated with
it, but also a SignalFunction. When a task feels like it, it may advise the
task manager to send a signal and some data to all the other tasks. Signals
are identified by integer numbers. The SignalFunction of each task will then
be called. It has to check the signal and if it is of meaning to the task,
do something appropriate with it. SICS uses this facility to distribute
interrupts and broadcast messages to all tasks. Currently defined signal
IDs are defined in file event.h.
\section{The Network Reader and the Network Module}
The network module implements the mechanics of network connection. This
module is the one which needs heavy reworking if the network protocol for
SICS should be changed. For instance to Token--Ring or AppleTalk or
whatever.
The network reader implements the polling for network message in the SICS
server. It is organized as one of the SICS system tasks. Polling in a POSIX
environment is all about the select system call. The select system call
allows to enquire if an open TCP/IP socket has data pending to be read, can
be written to etc. For more details see the unix man pages for the select
system call. An earlier version of the SICS server had a list of connection
objects and each of them were checked for pending commands with a call to
select. This proved to be inefficient with the system spending two thirds
of its time in select. Then it was decided to make use of the fact that
select can check more then one socket in one call. This gave birth to the
network reader. Each network user in the SICS server can register his socket
with the network reader. When the network reader tasks executes, it checks
all registered sockets for pending data with one central select system call.
This scheme improved system performance by a factor of 900.
What happens when data is pending on a socket depends on the type of the
socket.
The network reader currently supports four types of sockets:
\begin{itemize}
\item Accept type sockets.
\item Normal client sockets.
\item UDP sockets.
\item User sockets.
\end{itemize}
The accept type of socket is the main server port where clients try to
connect to. The network reader accepts the connection and tries to read a
username/password pair for a specified amount of time.
If the username/password is valid, the connection will be accepted,
else it will be broken again. The username/password pair will be verified
against the data in the password database. If a connection is accepted, a
new connection object is created, a new connection task is registered into
the system and the network reader registers a new client command port.
The normal client command ports are accepted connections from a client. The
SICS server expects commands to be sent from the clients. Thus any data
pending on such a socket will be read, split into single commands at the \\n
and put into the connections command stack for execution. At this place
there is also the check for the special interrupt string on command
connections (see \ref{prot1}).
The SICS server accepts only interrupts on its UDP port. This will be checked
for when handling data pending on the servers UDP port.
User type sockets are a feature for dealing with extremely slow hardware
connections. Some hardware devices require a long time to answer requests.
For example the Dornier velocity selector. This would block the SICS server
or diminish its performance to unbearable levels. If situations like that
occur somewhere in SICS object code, the object may call a special wait
function which returns when data is pending on the socket. Thereby, other
clients requests would be served, as the task switcher would run.
This special wait facility is implemented in the network reader.
\section{The Connection Object}
The connection object holds the execution context of the current client
connection. Its data structure holds information about the network channel to
the client connection, the command stack which the network reader fills with
commands, a list of files where all I/O to and from this connection will be
logged, the user rights associated with this client connection, interrupts,
and flags which determine if the connection is currently executing in a
macro or is busy. Functions exist which allow to interact with this object.
Most of them will be discussed in section \ref{gow}. Associated with each
connection is a task and a task function. Whenever this task executes, it
will pop a command from the command stack and execute it in the
interpreter. More details about the usage of the connection object can be
found in the next chapter \ref{gow}.
\section{The SICS Interpreter and Macro Language}
In order to understand this section a knowledge of some aspects of the C
language interface to the Tcl interpreter helps. Interesting chapters include
the sections about defining new commands in Tcl and the Tcl unknown
mechanism. For more details see John Ousterhout's book.
In an earlier stage it was considered to use the Tcl interpreter as the SICS
interpreter. This idea was discarded for some reasons: One was the
difficulty of transporting the client execution context (i.e. the connection
object) through the Tcl interpreter. There is no standard Tcl mechanism for
doing that. The second was security: the Tcl
interpreter is very powerful and can be abused. It was felt that the system
had to be protected against such problems. The third reasons was that the
set of user commands should not be cluttered with Tcl commands in order to
prevent confusion. Programming macros is anyway something which is done by
SICS managers or programmers. However, the SICS interpreter is still modeled
very much like the Tcl-interpreter. A Tcl interpreter is still included in
order to provide a full featured macro language. The SICS interpreter and the
Tcl macro interpreter are still tightly coupled.
The SICS interpreter must forward commands to the SICS objects. For this the
interpreter needs some help from the objects themselves. Each SICS object
has to provide a wrapper function of the type:
\begin{verbatim}
int ObjectWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
\end{verbatim}
in order to be visible from the interpreter. The parameters to this function
are: a pointer to the client connection executing the command,
the interpreter in which the command
executes, a pointer to the objects data structure and an argc,
\verb+argv[]+ pair
like for an C language main program. This argc, \verb+argv[]+ pair contains the
arguments to the wrapper function. The wrapper function is responsible for
evaluating the arguments and do whatever is appropriate. It returns 0 on
failure and 1 on success. The SICS interpreter holds a list of such wrapper
functions. For each object the list holds:
\begin{itemize}
\item The name of the SICS object.
\item The address of the objects wrapper function.
\item The address of the objects data structure.
\item The address of a function which can remove the objects data structure
from memory cleanly. This is used when deleting an object/command from the
interpreter to clean up memory.
\end{itemize}
Command interpretation then involves the following steps:
\begin{enumerate}
\item The command is parsed into an argc, \verb+argv[]+ pair.
\item Using the first word of the command as a key, the list of objects is
searched for a match.
\item If a match is found, the objects wrapper function is invoked with the
appropriate parameters.
\item All the rest of command interpretation is done by the wrapper
function.
\end{enumerate}
The SICS interpreter interface offers functions which allow to add or remove
entries to and from the interpreters list of objects. Other functions allow
to find objects (and their data structures) in this list. And of course,
there is a function which executes a command in this interpreter.
The Tcl macro interpreter is invoked either through the FileEval command or
through commands made available through the Publish mechanism. Publish
is a SICS manager command which makes a Tcl command or procedure
visible in the SICS interpreter. Publish provides a special wrapper for a
Tcl command, which first checks the user rights of the client connection which
wants to execute the Tcl command. If the user rights are appropriate the
command is invoked in the Tcl--interpreter. The Tcl interpreter has access
to all normal SICS commands. This is implemented by using the Tcl
unknown mechanism. If Tcl cannot find a command it invokes a command named
unknown with the missing commands name as a parameter. Unknown is usually
implemented as a Tcl script, loaded at Tcl startup time. The unknown function
is then responsible for finding the missing command and execute it. The
usual Tcl mechanism tries to find the missing command in Tcl libraries and
as operating system commands. This mechanism has been modified for SICS such
that unknown tries to find missing commands in Tcl libraries or in the SICS
interpreter. This last bit is implemented as a special Tcl command
SISCUnknown defined in macro.c. In order to invoke SICS command a connection
object is needed. A suitable connection object is provided through a stack.
Before invoking the Tcl-interpreter, the connection object from which the
request has come is put at the bottom of a stack. The SICSUnknown routine
then uses the last element of the stack as the connection object for
invoking SICS. When control returns from the Tcl-interpreter, the connection
is popped from the stack.
%% Idea: simplify: use Tcl as interpreter, have a wrapper around SICS
%% objects which provide the SICS wrapper contexts. Add SICS commands to Tcl
%% in a special data structure:
%% struct TclSICS {
%% (*ObjectWrapper);
%% void *ObjectData;
%% (*KillObject)
%% };
%% The Tcl wrapper function gets the connection object from the stack and
%% invokes the SICS object function.
%% This does not solve the Tcl security issue, though.
%%
\section{The Device Executor}
The device executor is responsible for executing and monitoring requests to
the actual instrument hardware. In its current form the device executor can
do this for any variable which can be driven (motors, temperature, composite
variables) and counters (single counters, histogram memory). How this is
done is explained in some detail in the section about SICS interfaces (see
\ref{inter}) in the object writers guide. The interface to the device
executor includes functions for starting, pausing, continuing devices and
monitoring their status. Additionally there are some functions and SICS
commands which allow to enquire about the status of the executor. If
hardware is active, the device executor has a SICS system task running
which initiates monitoring of devices. The device executor is built around a
list of currently active hardware devices.
\section{The Environment Monitor}
For the SICS concept for handling sample environment devices see
\ref{evdev}.
\section{The Server}
The server module defines a server data structure. A pointer to this
data structure is the sole global variable in the SICS system. Its name is
{\bf {\huge pServ}}. This data structure contains pointers to the most
important SICS components: the interpreter, the task switcher, the device
executor, the environment monitor and the network reader. This module also
contains the code for initializing, running and stopping the server.
\section{The ServerLog}
As part of the SICS kernel there exists a global server log file. This file
contains:
\begin{itemize}
\item All traffic on all client connections. Even messages suppressed by the
clients.
\item All internal error messages.
\item Notifications about important internal status changes.
\end{itemize}
This server log is meant as an aid in debugging the server. As the SICS
server may run for days, weeks and months uninterrupted this log file may
become very large. However, only the last thousand or so messages are really
of interest when tracking a problem. Therefore a scheme is implemented to
limit the disk space used by the server log. The server log writes
cyclically into a number of files. A count of the lines is kept which were
written to each file. Above a predefined count, a new file is started.
As an interface the server log provides a function which allows to write
a message to it. This can be used by any object in the system for
interesting messages. The number of files to cycle through and the length of
each file can be configured by defines at the top of servlog.c.
\section{The Performance Monitor}
This facility provides the data for the Performance (see user documentation)
command. The Performance Monitor is a task which increments a counter each
time it is executed. After a predefined integration time (20 seconds) a new
value cycles/per second is calculated. This is the data retrievable by the
Performance command. This facility is not particularly necessary but proved
useful for judging the impact of various system conditions on server
performance. If at some stage performance needs to be boosted to the utmost
and it is no longer the hardware which makes things slow, the performance
monitor may well be removed from the system without harm.
\section{The Object Factory}
During SICS initialization the SICS interpreters command list needs to be
initialized. This is the task of the object factory. Its function
IniIniCommand initializes all fixed, general SICS commands and all object
creation commands. Then the server initialization file is processed from the
server initialization code. After this is done, the server initialization
code calls KillIniCommands which removes the now surplus object creation
commands from the SICS interpreter. If new commands get added to SICS the
object creation command or (for a permanent command) the object wrapper have
to be registered with these two functions.
\section{SICS Options}
Any system needs a way to configure itself. SICS uses options for internal
parameters which should or need not be visible from the SICS interpreter. An
option is a name value pair. For a definition of currently valid SICS
options and how to create them see the SICS manager documentation. In terms
of an interface this module allows to retrieve an option from the options
database.
\section{The Password Database}
The password database holds a triplet of username password and rights code
for each user. This information is currently initialized from the server
initialization file. This scheme is not very secure, as anybody with an
account on the DAQ computer may view the file and thus the list of valid
users. If this becomes a serious concern, this module has to be rewritten.
\section{The Server Main Function}
This does not do much, just initialize the server, run it, and stop it.

49
doc/programmer/macro.tex Normal file
View File

@ -0,0 +1,49 @@
\subsection{The Macro Interpreter}
This module is responsible for splicing the Tcl macro interpreter into
the SICS framework. In order to achieve this several problems have to be
adressed:
\begin{itemize}
\item How to make Tcl commands available from within SICS.
\item How to call SICS with the correct execution context from Tcl macros.
\end{itemize}
The first problem is solved by overloading Tcl's unknown mechanism. The Tcl
interpreter automatically invokes a procedure {\bf unknown} when it cannot
find a command. The usual procedure in this case searches for Tcl procedures
in libraries and then tries to invoke the command as a shell command. For
SICS the last part has been cut off and replaced by a call to SICSUnknown
which tries to find an appropriate SICS command.
The second problem is solved by maintaing a stack of connection objects.
Before a Tcl command is invoked from SICS the current connection object is
pushed on the stack. If in due course SICSUnknown needs to find a connection
object in order to invoke a SICS object the last object from the stack will
be used. If Tcl finishes, the connection object is popped from the stack.
This is nicely shown in the TclAction code.
All this is implemented in macro.c.
The macro module presents the following interface to the outside world:\begin{itemize}
\item {\bf Tcl\_Interp *MacroInit(SicsInterp *pInter,SConnection *pCon) } initialises a Tcl interpreter with a SICS unknown mechanism. Furthermore deletes some Tcl standard commands which can be harmful in SICS. Returns a pointer to an interpreter on success, NULL else.
\item {\bf void MacroDelete(Tcl\_Interp *pInter) } deletes an interpreter.
\item {\bf int MacroFileEval(SConnection *pCon, SicsInterp *pInter, void *pData, int argc, char *argv) }, the SICS object wrapper function for script processing.
\item {\bf int InternalFileEval(SConnection *pCon, SicsInterp *pInter,
void *pData, int argc, char *argv) }, the SICS object wrapper
function for script processing. This version suppresses output to the
client however. All output goes into the command log only.
\item {\bf int ClientPut(SConnection *pCon, SicsInterp *pInter, void *pData, int argc, char *argv) },
the SICS object wrapper function for writing datato a client from
within a Tcl--script.
\item {\bf int MacroWhere(SConnection *pCon, SicsInterp *pInter,
void *pData, int argc, char *argv) }, the SICS object wrapper
function implementing the filewhere command.
\item {\bf int TclPublish(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])} is the implmentation of the Publish command for the
interpreter which installs a Tcl command into the system.
\item {\bf int TransactAction (SConnection *pCon, SicsInterp *pInter,
void *pData, int argc, char *argv) } This Function implements the
transact command which executes an command and sends a string
``TRANSACTIONFINISHED'' when the command finished executing.
\item {\bf MacroPush} pushes a connection onto the Tcl connection
stack.
\item {\bf MacroPop} removes a connection for the Tcl connection
stack.
\end{itemize}

126
doc/programmer/mesure.tex Normal file
View File

@ -0,0 +1,126 @@
\subsection{Four Circle Single Counter Measurement Object}
This object implements a basic single counter reflection measurement routine
for four circle diffractometers. This object is able to read a reflection
listing, drive to each reflection in the list, do a scan on it, integrate
the scan results and write the results to ASCII files. Nothing sophisticated
such as optimised measurement procedures and special background measurement
programs. Three files will be created as output: one file with the ending
.rfl which contains the reflection profiles for each reflection, a file .asc
which contains a summary in form of HKL, I, sigma(I) for each reflection
and a file ending .err which contains all the error messages obtained during
the run.
The interface to this object consists of these functions:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap1}
$\langle$mesureint {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ typedef struct __Mesure *pMesure;@\\
\mbox{}\verb@/*--------------------- live & death --------------------------------------*/@\\
\mbox{}\verb@ pMesure CreateMesure(pHKL pCryst, pScanData pScanner, @\\
\mbox{}\verb@ pMotor pOmega, char *pom, char *po2t,@\\
\mbox{}\verb@ char *pFileRoot,pDataNumber pDanu);@\\
\mbox{}\verb@ void DeleteMesure(void *pData);@\\
\mbox{}\verb@@\\
\mbox{}\verb@ int MesureFactory(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@/*------------------- object functions -----------------------------------*/@\\
\mbox{}\verb@ int MesureReflection(pMesure self, float fHKL[3], SConnection *pCon);@\\
\mbox{}\verb@ int MesureGenReflection(pMesure self, float fHKL[3],float fSet[4], SConnection *pCon);@\\
\mbox{}\verb@ int MesureStart(pMesure self, SConnection *pCon);@\\
\mbox{}\verb@ int MesureReopen(pMesure self, char *filename, SConnection *pCon);@\\
\mbox{}\verb@ int MesureClose(pMesure self);@\\
\mbox{}\verb@ int MesureFile(pMesure self, char *pFile, int iSkip, SConnection *pCon);@\\
\mbox{}\verb@ int MesureGenFile(pMesure self, char *pFile, int iSkip, SConnection *pCon);@\\
\mbox{}\verb@ int MesureSetPar(pMesure self, char *name, float fVal);@\\
\mbox{}\verb@ int MesureGetPar(pMesure self, char *name, float *fVal);@\\
\mbox{}\verb@@\\
\mbox{}\verb@ int MesureAction(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@ @\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
All functions return 1 on success, 0 on failure.
\begin{description}
\item[CreateMesure] creates a new pMesure object. Parameters are the HKL
object to use for cystallographic conversions and the scan object to use for
doing the scans. This is followd by the motor for running omega, its name
and the name of the motor for driving omega 2 theta. Finnaly the path to the
data directory and the data number object for automatic filename creation is
specified.
\item[DeleteMesure] wipes the mesure object pData from memory.
\item[MesureFactory] is the factory function for mesure which will be used
by the interpreter to install mesure into the system.
\item[MesureReflection] measures the single reflection fHKL. It drives
there, calculates scan borders and performs the scan.
\item[MesureGenReflection] measures the single reflection fHKL. It drives
there, calculates scan borders and performs the scan. This version uses
supplied values for the instrument settings.
\item[MesureStart] sets everything up for a new measurement with new file
names.
\item[MesureReopen] reopens the files belonging to the file name given as
base for appending. This is a recovery feature.
\item[MesureFile] opens the file specified as second parameter and reads
each line. Expected is a reflection to measure. Each reflection is then
measured and output written. The last parameter iSkip allows to skip iSkip
lines of the reflection file. This facility exists in order to restart work
on an reflection file which had been interrupted for some reason.
\item[MesureGenFile] opens the file specified as second parameter and reads
each line. Expected is a reflection to measure. Each reflection is then
measured and output written. The last parameter iSkip allows to skip iSkip
lines of the reflection file. This facility exists in order to restart work
on an reflection file which had been interrupted for some reason. This
version acts upon files created by the program HKLGEN.
\item[MesureSetPar] sets the parameter name of Mesure to fVal. A listing of
possible parameters is given below.
\item[MesureGetPar] returns the value of the parameter name in fVal.
\item[MesureAction] implements the interpreter interface to the mesure
object.
\end{description}
Mesure supports the following parameters:
\begin{description}
\item[np] the number of points per scan.
\item[preset] The preset value for counting.
\item[countmode] the counting mode, can be 0 for timer or 1 for monitor
mode.
\item[mode] can be 0 for omega 2theta scans or 1 for omega scans.
\item[step] the scan step widths. This is allways in omega, in omega 2theta
mode 2theta is always the double of this.
\end{description}
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap2}
\verb@"mesure.h"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*----------------------------------------------------------------------------@\\
\mbox{}\verb@ M E S U R E@\\
\mbox{}\verb@@\\
\mbox{}\verb@ A SICS object for doing simple four circle measurements with a single@\\
\mbox{}\verb@ counter. @\\
\mbox{}\verb@@\\
\mbox{}\verb@ copyright: see copyright.h@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Mark Koenencke, April 1998@\\
\mbox{}\verb@---------------------------------------------------------------------------*/@\\
\mbox{}\verb@#ifndef SICSMESURE@\\
\mbox{}\verb@#define SICSMESURE@\\
\mbox{}\verb@@$\langle$mesureint {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@#endif@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}

209
doc/programmer/motor.tex Normal file
View File

@ -0,0 +1,209 @@
\subsection{Motors}
Most neutron scattering instruments have lots of motors to drive
monochromators, samples and detectors through space.This module implements
support for them. As usual for hardware objects in SICS motors are
subdivided into a driver and the logical object.
\subsubsection{The Motor Driver}
There is a problem here. There are some data fields and functions
which must be present for any motor driver. Then there are fields
which are specific just to a special implementation of a mot
driver. There are several ways to deal with this. The way choosen for
the motor driver is a kind of overlay. The first few fields of a valid
motor driver structure MUST be specified in the same order as given
below. A special motor driver can add additional fields at the end of
the standard list. As an example for this scheme compare the
AbstractMoDriv structure with the one for the EL734 motor driver.
\begin{verbatim}
typedef struct __AbstractMoDriv {
/* general motor driver interface
fields. REQUIRED!
*/
float fUpper; /* upper limit */
float fLower; /* lower limit */
char *name;
int (*GetPosition)(void *self, float *fPos);
int (*RunTo)(void *self,float fNewVal);
int (*GetStatus)(void *self);
void (*GetError)(void *self, int *iCode, char *buffer, int iBufLen);
int (*TryAndFixIt)(void *self, int iError,float fNew);
int (*ContinueAfterWarn)(void *self);
int (*Halt)(void *self);
}
MotorDriver;
\end{verbatim}
All functions return 0 on failure or 1 on success, if not stated otherwise.
The first parameter is always a pointer to the motor driver structure.
The fields and their meanings: \begin{description}
\item[fUpper,fLower] The hardware upper and lower limits for the motor.
These are the real hardware limits as implemented by limit switches bolted
to the instrument.
\item[name] The real motor name.
\item[GetPosition] retrieves the current hardware position of the motor into
fPos.
\item[RunTo] starts the motor to run to fNewVal. This sends a command to the
motor and returns immediately.
\item[GetStatus] requests the status from the motor. Possible answers are:
\begin{description}
\item[HWIdle, OKOK] The motor has finished or is idle.
\item[HWFault] A fault has been found at the motor.
\item[HWBusy] The motor is busy moving.
\item[HWWarn] The motor hardware complained but managed to reach the
requested position.
\item[HWPosFault] The motor could not go where it should go for some reason.
However, the motor is intact and ready to move somewhere else. This can
happen when there is a concrete block in the instruments way which is not
accounted for by a limit switch. This can also happen when the motor hits a
limit switch. However, the general idea of SICS is that the limits will be
checked for before even starting to run the motor. In order for this to
work, the limits SICS knows about must macth those actually implemented.
\end{description}
\item[GetError] This gets called when an error has been detected during one
of the previous operations. The function has to return more information
about the error: iCode an driver dependent integer error code and maximum
iErrLen characters of problem description in error.
\item[TryAndFixIt] takes the integer error code returned in iCode from
GetError and tries to solve the problem with the hardware. This function can
either return MOTREDO which means the problem has been fixed and the
operation needs to be redone, MOTOK when the problem has been fixed and no
resending of a command is necessary or MOTFAIL which means that it is not
possible to resolve the problem in software.
\item[ContinueAfterWarn] will be called after a warning from the motor. This
function is supposed to do whatever is needed to clear the warning from the
motor and keep him going.
\item[Halt] emergency stop the motor, NOW.
\end{description}
As an example for a derived motor driver the SINQ EL734 motor driver is
shown below. It add to the general fields the special things for that motor:
host, port and channel number of the motor controller and a pointer to the
driver communications structure.
\begin{verbatim}
typedef struct __MoDriv {
/* general motor driver interface
fields. REQUIRED!
*/
float fUpper; /* upper limit */
float fLower; /* lower limit */
char *name;
int (*GetPosition)(void *self,float *fPos);
int (*RunTo)(void *self, float fNewVal);
int (*GetStatus)(void *self);
void (*GetError)(void *self, int *iCode, char *buffer, int iBufLen);
int (*TryAndFixIt)(void *self,int iError, float fNew);
int (*ContinueAfterWarn)(void *self);
int (*Halt)(void *self);
/* EL-734 specific fields */
int iPort;
char *hostname;
int iChannel;
int iMotor;
void *EL734struct;
int iMSR;
} EL734Driv;
\end{verbatim}
Most of the interaction with the motor driver happens through the functions
defined in its data structure. The rest is creation and deletion:
\begin{description}
\item[MotorDriver *CreateEL734(SConnection *pCon, int argc, char
*argv[])]
creates a EL734 motor driver. The argc, \verb+argv[]+ pair contains the
necessary drive parameters.
\item[MotorDriver *CreateEL734DC(SConnection *pCon, int argc, char
*argv[])]
created an EL734 DC motor driver.
\item[void KillEL734(void *pData)] deletes a EL734 motor driver.
\item[MotorDriver *CreateSIM(SConnection *pCon, int argc, char *argv[])]
creates a simulation motor driver.
\item[void KillSIM(void *pData)] deletes a simulated motor driver.
\end{description}
\subsubsection{The Motor Logical Object}
The motor object represents the motor to SICS. One of its responsabilities
is to drive motor operations and error checking. The scheme
implemented is that the motor object tries to bring the motor to its
position at least three times before a failure is recorded. Also the
motor object keeps track of a count of failed operations. If this
count gets to high an interrupt is issued to stop the instrument. This
was put in after Druechal tried to drive over a slab of concrete for a
whole night and subsequently broke a clutch.
Motors are represented by the
following data structure:
\begin{verbatim}
typedef struct __Motor {
pObjectDescriptor pDescriptor;
ObPar *ParArray;
pIDrivable pDrivInt;
pICallBack pCall;
char *drivername;
char *name;
MotorDriver *pDriver;
float fTarget;
float fPosition;
} Motor;
typedef Motor *pMotor;
\end{verbatim}
The fields: \begin{description}
\item[pDescriptor] The usual SICS object descriptor.
\item[ParArray] A dictionary of parameter names and float values. This array
holds all the different parameters used to operate the motor.
\item[pDrivInt] A pointer to the drivable interface implemented by the motor
object.
\item[pCall] A pointer to the callback interface implemented by the motor
object.
\item[drivername] The name of the motor driver.
\item[name] The name of the motor.
\item[pDriver] A pointer to the motor driver to use.
\item[fTarget] The target position for the motor.
\item[fPosition] The last known position of the motor.
\end{description}
Much of the action of the motor is hidden in the implementation of the
drivable interface to the motor. Additionally the functions as given below
are defined. All functions take a pointer to the motor object data structure
as a parameter. They retun 0 on success or 1 on failure while not stated
otherwise.
\begin{description}
\item[int MotorGetPar(pMotor self, char *name, float *fVal)] retrieves the
value of the parameter name in fVal.
\item[int MotorSetPar(pMotor self, SConnection *pCon, char *name, float
fVal)] tries to write fVal to the parameter name. Errors are written to
the connection pCon.
\item[long MotorRun(void *self, SConnection *pCon, float fNew)] starts a
motor running to fNew. Does not wait for the motor to finish.
\item[int MotorCheckBoundary(pMotor self, float fVal, float *fHard,
char *error, int iErrLen)] checks if the position
fVal violates any of the motors software or hardware limits. In case of
success a new hardware position is returned in fHard. fHard is then
corrected for possible software zero points. In case of a limit violation
maximum iErrLen characters of error information are returned in error.
\item[int MotorCheckPosition(void *self, SConnection *pCon)] returns 1 if
the motor is at the target position, 0 else, or -1 if the motor could not be
read.
\item[int MotorGetSoftPosition(pMotor self,SConnection *pCon, float *fVal)]
reads the current motor position into fVal. This position is corrected for
software zero points.
\item[int MotorGetHardPosition(pMotor self,SConnection *pCon, float *fVal)]
reads the current position of the motor as returned from the hardware.
\item[int MakeMotor(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])] the motor factory function. To
be hacked when a new driver needs to be included.
\item[pMotor MotorInit(char *drivername,char *name, MotorDriver *pDriv)]
creates a new motor object with driver pDriv. Returns NULL on failure.
\item[void MotorKill(void *self)] deletes a motor object. Needs to be
modified for a new driver in order to clean out the new driver properly.
\item[int MotorAction(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])] the object wrapper function for
the motor. Implements the user interface.
\item[pMotor FindMotor(SicsInterp *pSics, char *name)] finds a motor name in
the interpreter pSics. This is a convenience function. Returns NULL if no
motor could be found, else a pointer to its data structure.
\end{description}

49
doc/programmer/mumo.tex Normal file
View File

@ -0,0 +1,49 @@
\subsection{Multiple Motors}
Multiple Motors is a module which implements a special syntax for SANS.
Motors are collected into a group. For example beamstop and manipulated
through them. Furthermore multiple motors support named positions and a
special position {\bf back} which is the position before the last movement.
Multiple Motors works, but it if larger changes become necessary it might be
sensible to drop it and replace it by a work alike in the macro language.
Please note, that multiple motors starts motors to run, but does not wait
for them to finish.
Multiple motors are characterized through the following data structure:
\begin{verbatim}
typedef struct __MULMOT {
pObjectDescriptor pDes;
char *name;
pStringDict pAlias;
pStringDict pNamPos;
ObPar *pParam;
} MulMot;
\end{verbatim}
The fields are:
\begin{description}
\item[pDes] A pointer to the usual SICS object descriptor.
\item[name] The name of the multi motor.
\item[pAlias] A string dictionary which maps group internal motor names to
real SICS motor names.
\item[pNamPos] A string dictionary which maps named positions to the SICS
command necessary to run to that position.
\end{description}
Multiple motors are interfaced to with the following functions:
\begin{description}
\item[pMulMot MakeMultiMotor(void)] creates multi motors device. Returns a
pointer to a new data structure on success, NULL in case of failure.
\item[void KillMultiMotor(void *pData)] deletes a multi motor device.
\item[int MultiWrapper(SConnection *pCon, SicsInterp *pSics, void *pData, \\
int argc, char *argv[])] The object wrapper function for
multiple motors.
\item[int MakeMulti(SConnection *pCon, SicsInterp *pSics, void *pData,\\
int argc, char *argv[])] The object factory function for
multiple motors.
\item[int ConfigMulti(SConnection *pCon, SicsInterp *pSics, void *pData,\\
int argc, char *argv[])] The configuration function for
multiple motors.
\end{description}
The implementation of multiple motors can be found in files mumo.c,
mumoconf.c, mumo.h and mumo.i.

1850
doc/programmer/napi.tex Normal file

File diff suppressed because it is too large Load Diff

383
doc/programmer/nconman.tex Normal file
View File

@ -0,0 +1,383 @@
\subsection{The Connection Object}
The connection object is a major player in the SICS world. The connection
object represents an active connection between the SICS server and a client.
There will be one connection object for each client connection. A lot of
stuff is associated with a client connection:
\begin{itemize}
\item A task. This task will read one command from the command fifo and
execute it.
\item A command fifo which will be filled by the network reader.
\item An execution context consisting of user rights for this connection
and interrupt status.
\item A communication channel to the client.
\item A list of log files to which all traffic on the connection will be
logged.
\item An interface to the SICS interpreter which allows to configure
certain aspects of the connection and makes the connection available as
a command.
\item A list of callbacks registered for the connection. A connection can
be automatically notified about changes in system state. These callbacks
have to be removed when the client server connection terminates. Otherwise
callback code would write to a dead connection causing the program to
crash.
\end{itemize}
\subsubsection{Connection I/O}
Due to user requirements for features not considered in the design the
I/O facilities of connection have become quite involved.
Incoming commands are printed into client log files if configured, and
into the commandlog if the connection has a privilege $\ge$ user
privilege. This is implemented in SCInvoke. Also each command is
printed to the server log.
Output is more sophisticated. First of all there are different output
codes given as last parameter to SCWrite. The most important of these
are:
\begin{description}
\item[eError] Error messages.
\item[Warning] warnings.
\item[Value] values requested by the client.
\item[Status] status messages.
\end{description}
Clients can choose to suppress certain types of messages in order to
reduce I/O.
The logic is mostly implemented in the
file static function SCNormalWrite. The follwoing conditions are
implemented:
\begin{itemize}
\item Any output is logged to the
server log.
\item If the privilege of the connection is $\ge$ user the
output is printed to the commandlog as well.
\item If the command is executing as part of a Tcl--macro script
output to the socket is suppressed. The output is copied into the
interpreter for further evaluation instead. This is done in order to
prevent excessive output during macro evaluation and in order to make
SICS results available in the Tcl interpreter. However, messages of
type error or warning are printed to the socket even during macro
evaluation.
\item In the normal case the output is printed to the socket and all
log files configured for the connection.
\item As of recent the output function can be modified by setting a
new function. One sich function exists which supresses all output to
the socket. This is done in order to help when the connection gets
lost. For instance with the cron command.
\end{itemize}
This aspect of the connection object could do with a cleanup. A
possible cleanup path is the implementation of the different output
strategies in different functions and devise a SCsetOutMode function which
switches between the various possibilities. Also, it can be argued if
the client specific log files are still needed. Then this part of the
code can be cleaned out as well.
\subsubsection{Command Execution Path}
In the course of the SICS development the path of a command through
the system has become more complex as well. This section describes how
it works. The incoming command is collected at the socket by the
NetReaderTask. This does a little processing and checks for interrupts
issued on the connection and invokes them. But any normal command is
put into the connections Command-FIFO. Thus ends the business of the
NetReaderTask. The connections task function SCTaskFunction is
invoked by the task manager in due time and checks for pending
commands on the command stack. If a command is pending it is taken
from the stack and executed through SCInvoke.
\subsubsection{Execution context}
Each connection has a user right code associated with it. The there is
a second protection scheme in SICS with the token system. This system
reserves command input to a certain connection. In the connection
object this scheme requires the iGrab field which defines if this
connection may execute commands or not. This field is modified through
the tasks signal handling function. Code implementing a command may
call SCMatchRights in order to check for permission. SCMatchRights
will also send appropriate error messages.
Errors are usually signalled by setting an interrupt code on the
connection. An additional field, iError allows to give a more detailed
error description if required.
\subsubsection{Callbacks}
SICS can be configured to forward notifications about certain state
changes to a connection automatically. This is implemented through the
callback system. For more details see \ref{inter}. However, it is
important that any callback acting on a connection is registered with
the connection object. This allows the removal of the callback when
the connection is closed. Otherwsie the system gets filled up with
dead callbacks which usuallly cause core dumps when it is tried to
send a message to a dead connection.
\subsubsection{The Connection Data Structure}
Given the plethora of things to take care of, each connection is
represented by a rather large data structure.
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap1}
$\langle$condat {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ typedef struct __SConnection {@\\
\mbox{}\verb@ /* object basics */@\\
\mbox{}\verb@ pObjectDescriptor pDes;@\\
\mbox{}\verb@ char *pName;@\\
\mbox{}\verb@ long lMagic;@\\
\mbox{}\verb@ @\\
\mbox{}\verb@ /* I/O control */@\\
\mbox{}\verb@ mkChannel *pSock;@\\
\mbox{}\verb@ FILE *pFiles[MAXLOGFILES];@\\
\mbox{}\verb@ int iMacro;@\\
\mbox{}\verb@ int iTelnet;@\\
\mbox{}\verb@ int iOutput; @\\
\mbox{}\verb@ int iFiles;@\\
\mbox{}\verb@ int (*write)(SConnection *pCon,@\\
\mbox{}\verb@ char *pMessage, int iCode);@\\
\mbox{}\verb@@\\
\mbox{}\verb@ /* execution context */@\\
\mbox{}\verb@ int eInterrupt;@\\
\mbox{}\verb@ int iUserRights;@\\
\mbox{}\verb@ int inUse;@\\
\mbox{}\verb@ int iGrab;@\\
\mbox{}\verb@ int iErrCode;@\\
\mbox{}\verb@ SicsInterp *pSics;@\\
\mbox{}\verb@ @\\
\mbox{}\verb@ /* a FIFO */@\\
\mbox{}\verb@ pCosta pStack;@\\
\mbox{}\verb@@\\
\mbox{}\verb@ /* callback registry */@\\
\mbox{}\verb@ int iList;@\\
\mbox{}\verb@ @\\
\mbox{}\verb@ /* Tasking Stuff */@\\
\mbox{}\verb@ int iEnd;@\\
\mbox{}\verb@ }SConnection;@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
The fields are:
\begin{description}
\item[pDes] The usual object descriptor belonging to any object within the
SICS interpreter. See \ref{inter} for details.
\item[pName] The automatically generated name of the connection object in the
interpreter.
\item[lMagic] is a magic number used internally in order to check if
the connection object given as a parameter is valid.
\item[pChannel] A pointer to a network channel structure. This channel
will be used for I/O to the client. If thispointer is NULL I/O is done onto
stdin/stdout instead.
\item[pFiles] An array of file to which all I/O on this connection will be
logged.
\item[iOutPut] The currently valid output mask. SICS messages are classified
into several output classes. If a message is going to be printed it must
have a output class above the one configured as the mask. This was made in
order to allow clients to suppress certain messages which are not of
interest.
\item[iFiles] The number of configured log files.
\item[write] a pointer to a function which does the actual writing of
a message to the connection.
\item[iTelnet] is true when I/O is through a telnet connection.
\item[iMacro] This flag is set when the connection is executing a Tcl
script. In this mode mode all output is written into the Tcl interpreter and
not written to the client. Thus a script can execute silently. As always,
there is an exception: errors and warning will still be written to the
client.
\item[iGrab] This is 0 when the connection may execute commands. It is 1 if
another connection has grabbed the control token and commands may not be
executed. For details about the token system, see the token reference.
\item[eInterrupt] This is the current interrupt status of the connection.
\item[iUserRights] This integer denotes the user rights associated with the
connection. This value is initially deducted from the username password pair
given at login to SICS. The value can be configured otherwise afterwards.
iUserRights will be used to check at object level if a client may perform
the requested operation or not.
\item[iErrCode] is the last error code. I think this field is no longer
used.
\item[pSics] is a pointer to an SICS interpreter where to invoke commands.
\item[pStack] Is the command FIFO.
\item[iList] This is the identifier of a lld list which holds the callbacks
registered on this connection object.
\item[iEnd] iEnd is a flag which is usually 0. It is set by certain
interrupts or if the connection is broken and causes the connection task to
end and the connection data structure to be removed from the system.
\end{description}
Quite a few places in SICS refer to this data structure directly,
without a function interface. The reason for this is performance. Therefore
this data structure is made public in the conman.h file.
\subsubsection{Connection Functions}
The interface to this data structure is defined by the following functions:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap2}
$\langle$conint {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*------------------------------ live & death ----------------------------*/@\\
\mbox{}\verb@ SConnection *SCreateConnection(SicsInterp *pSics, mkChannel *pSock,@\\
\mbox{}\verb@ int iUserRights);@\\
\mbox{}\verb@ SConnection *SCCreateDummyConnection(SicsInterp *pSics);@\\
\mbox{}\verb@ void SCDeleteConnection(void *pVictim);@\\
\mbox{}\verb@ @\\
\mbox{}\verb@/*------------------------------- tasking --------------------------------*/@\\
\mbox{}\verb@ int SCTaskFunction(void *pCon);@\\
\mbox{}\verb@ void SCSignalFunction(void *pCon, int iSignal, void *pSigData);@\\
\mbox{}\verb@/* ***************************** I/O ************************************** */@\\
\mbox{}\verb@ int SCAddLogFile(SConnection *self, char *name);@\\
\mbox{}\verb@ void SCSetOutputClass(SConnection *self, int iClass);@\\
\mbox{}\verb@ int SCWrite(SConnection *self, char *pBuffer, int iOut);@\\
\mbox{}\verb@ int SCRead(SConnection *self, char *pBuffer, int iBufLen); @\\
\mbox{}\verb@ int SCPrompt(SConnection *pCon, char *pPrompt, char *pResult, int iLen);@\\
\mbox{}\verb@ int SCSendOK(SConnection *self);@\\
\mbox{}\verb@ int SCnoSock(SConnection *pCon);@\\
\mbox{}\verb@/************************* CallBack *********************************** */@\\
\mbox{}\verb@ int SCRegister(SConnection *pCon, SicsInterp *pSics,@\\
\mbox{}\verb@ void *pInter, long lID);@\\
\mbox{}\verb@ int SCUnregister(SConnection *pCon, void *pInter);@\\
\mbox{}\verb@/******************************* Error **************************************/@\\
\mbox{}\verb@ void SCSetInterrupt(SConnection *self, int eCode);@\\
\mbox{}\verb@ int SCGetInterrupt(SConnection *self); @\\
\mbox{}\verb@ void SCSetError(SConnection *pCon, int iCode);@\\
\mbox{}\verb@ int SCGetError(SConnection *pCon); @\\
\mbox{}\verb@/****************************** Macro ***************************************/@\\
\mbox{}\verb@ int SCinMacro(SConnection *pCon);@\\
\mbox{}\verb@ int SCsetMacro(SConnection *pCon, int iMode); @\\
\mbox{}\verb@@\\
\mbox{}\verb@/* *************************** Info *************************************** */@\\
\mbox{}\verb@ int SCGetRights(SConnection *self);@\\
\mbox{}\verb@ int SCSetRights(SConnection *pCon, int iNew);@\\
\mbox{}\verb@ int SCMatchRights(SConnection *pCon, int iCode);@\\
\mbox{}\verb@ int SCGetOutClass(SConnection *self);@\\
\mbox{}\verb@ int SCGetGrab(SConnection *pCon);@\\
\mbox{}\verb@@\\
\mbox{}\verb@/* **************************** Invocation ******************************** */@\\
\mbox{}\verb@ int SCInvoke(SConnection *self,SicsInterp *pInter,char *pCommand);@\\
\mbox{}\verb@ @\\
\mbox{}\verb@/*************************** User Command **********************************/@\\
\mbox{}\verb@ int ConfigCon(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]); @\\
\mbox{}\verb@ int ConSicsAction(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]); @\\
\mbox{}\verb@ @\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
The functions in more detail:
\begin{description}
\item[SCreateConnection] creates a new connection object. Parameters to this
call are a pointer to a server data structure, a pointer to a network
connection object and the user rights to use in this connection. This
also adds a new task function for this connection to the task object.
\item[SCCreateDummyConnection] creates a dummy connection for use during
system initialisation. Printing to a socket will be suppressed for such a connection. But the output is printed to stdout.
\item[SCTaskFunction] is the task function which will be registered with the
Tasker. This function reads a new command from the command stack (if
available) and executes it in the interpreter.
\item[SCSignalFunction] is the signal function for the connection
object. This function handles interrupts and the token security
system.
\item[SCDeleteConnection] deletes a connection object and all its data
structures. This function will be automatically called by the tasker when
the task function returns with a 0.
\item[SCAddLogFile] configures the log file name into the connection object.
If this suceeds all I/O to the connection will be logged to this file as
well.
\item[SCSetOutputClass] sets the output class for the connection.
\item[SCGetOutClass] returns the output class of the connection.
\item[SCWrite] is the most important function of SConnection. Writes the
buffer pBuffer with output code iOut to the client. {\em All output to the
client has to be channelled through this function!}
\item[SCRead] reads data from the client connection into the buffer pBuffer,
but maximum iBufLen bytes.
\item[SCPrompt] prompts the client for a reply. But waits only for certain
timeout period. pPrompt is the prompt for the client, pResult is the buffer
with the client reply. Maximum iLen bytes will be copied to
pResult. Returns true (1) on a successfull read, else 0 (false).
\item[SCSendOK] A short cut which sends OK to the client.
\item[SCRegister] registers a callback with the connection. Parameters are:
The interpreter to use, the interface with which the callback was
registered and the ID of the callback. All automatic notifications to a
client MUST be registered with this call. When the connection is deleted all
these callbacks will be removed as well. Otherwise a core dump is bound to
happen.
\item[SCUnregister] will remove all callbacks on interface pInter for this
connection.
\item[SCSetInterrupt] sets an interrupt on the connection.
\item[SCGetInterrupt] retrives the current interrupt status of the
connection.
\item[SCSetError] sets an error code in the connection.
\item[SCGetError] retreives the current error code on the connection.
\item[SCinMacro] returns true if the connection is executing a tcl script,
returns false otherwise.
\item[SCsetMacro] sets the iMacro flag.
\item[SCGetRights] returns the current user rights associated with the
connection.
\item[SCGetGrab] gets the status of the control token for this connection.
This calls returns 0 if the connection may execute commands and 1 if another
connection has the control token.
\item[SCSetRights] sets the user rights for the connection to a new value.
\item[SCMatchRights] return true (1) if the iCode matches with the user
rights of the connection, 0 (false) otherwise. SCMatchRights also checks for
the status of the control token. Suitable error messages are written to pCon
if the user rights do not match.
\item[SCInvoke] invokes pCommand in the SICS interpreter pSics for the
connection pCon. This function also prints the executed command into
logfiles and into the commandlog.
\end{description}
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap3}
\verb@"conman.h"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*--------------------------------------------------------------------------@\\
\mbox{}\verb@ C O N N E C T I O N O B J E C T@\\
\mbox{}\verb@@\\
\mbox{}\verb@ This file defines the connection object data structure and the interface to@\\
\mbox{}\verb@ this data structure. This is one of the most important SICS components.@\\
\mbox{}\verb@@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Substantially revised from a prior version.@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Mark Koennecke, September 1997@\\
\mbox{}\verb@@\\
\mbox{}\verb@ copyright: see copyright.h@\\
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
\mbox{}\verb@#ifndef SICSCONNECT@\\
\mbox{}\verb@#define SICSCONNECT@\\
\mbox{}\verb@#include <stdio.h>@\\
\mbox{}\verb@#include "costa.h"@\\
\mbox{}\verb@#include "SCinter.h"@\\
\mbox{}\verb@#include "network.h"@\\
\mbox{}\verb@#include "obdes.h"@\\
\mbox{}\verb@@\\
\mbox{}\verb@#define MAXLOGFILES 10@\\
\mbox{}\verb@@$\langle$condat {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@#include "nserver.h"@\\
\mbox{}\verb@@$\langle$conint {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@@\\
\mbox{}\verb@#endif @\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}

View File

@ -0,0 +1,38 @@
\subsection{The network module}
The network class encapsulates the network protocoll used for client server communications in SICS. This is the place to hack if SICS needs porting to other protocols. This class implements:\begin{verbatim}
typedef struct {
int sockid;
int iType;
struct sockaddr_in adresse;
} mkChannel;
\end{verbatim}
This is the datastructure maintained for each socket. Never deal with it
directly but through the functions given below. Wherever a timeout is
specified as a parameter below the following rule applies: If timout is
greater 0, then timeout means a time in milliseconds to wait with a select
system call for data to arrive. If timeout is less or equal then 0 the
socket will block on input.
\begin{itemize}
\item {\bf mkChannel *NETOpenPort(int iPort) }, opens a server port on port number iPort for listening. If successful returns a pointer to a fresh mkChannel datastructure , else NULL.
\item {\bf mkChannel *NETAccept(mkChannel *self, int timeout) }, waits timeout microseconds for a client requesting a connection to the server This is done with thke select system call. If a request comes in a new mkChannel structure is created and returned. If not NULL will be returned.
\item {\bf mkChannel *NETConnect(char *name, int port) } tries to connect to a server specified by the hostname name and the port number port. Returns a pointer to a new mkChannel structure on success, NULL else.
\item {\bf int NETWrite(mkChannel *self, char *buffer, long lLen) } writes lLen bytes from buffer to the socket specified by self. Returns True on succees, else False.
\item {\bf long NETRead(mkChannel *self, char *buffer, long lLen, int timeout) } waits timeout microseconds for data to arrive at the socket specified by self. If data is available it will be copied into the buffer, but to a maximum length of lLen. Returns the length of data read, 0 if there is no data and -1 if an EOF occured on the socket (i.e the partner closed the connection).
\item {\bf int NETClosePort(mkChannel *self) } If you are done with talking you can use this to close the connection. The socket specified by self can no longer be used after this. You still have to free the mkChannel though, if you want to do it properly. The function returns True on success, False (0) if the call failed.
\item {\bf mkChannel *UDPOpen(int iPort) } opens a port for connectionless UDP-connection.
\item {\bf mkChannel UDPConnect(int iPort) } connects a client to a UDP port for Data transfer.
\item {\bf long UDPRead(mkChannel self, char *buffer, long lLen, int timeout) } reads data from a UDP port inot buffer, but maximum lLen bytes. Waits maximum timeout microseconds for data. Returns the number of bytes read or -1 for end of file.
\item {\bf int UDPWrite(mkChannel *self, char *buffer, long lLen); } writes lLen bytes from buffer into an UDP channel.
\end{itemize}
SICS needs I/O multiplexing, that is it needs to be able to handle request
from many clients. Instead of spawning more processes or using threads with
all the synchronisation problems associated with both of the above, I/O
multiplexing is done with the select() system call here. Select uses a
funny mask as input which specifies the id of the stream it is interested
in. It requires the (stream-number (number, not FILE *) + 1 ) bit of the
mask to be set for interest in stream number. This mask is set using macros
defined in the apropriate header files.

660
doc/programmer/newsics.eps Normal file
View File

@ -0,0 +1,660 @@
%!
%%BoundingBox: 2 358 358 785
%%Title: newsics
%%CreationDate: Thu Nov 20 13:43:31 1997
%%Creator: Tgif-3.0-p7 by William Chia-Wei Cheng (william@cs.UCLA.edu)
/tgifdict 4 dict def
tgifdict begin
/tgifarrowtipdict 8 dict def
tgifarrowtipdict /mtrx matrix put
/tgifarrowtip
{ tgifarrowtipdict begin
/dy exch def
/dx exch def
/h exch def
/w exch def
/y exch def
/x exch def
/savematrix mtrx currentmatrix def
x y translate
dy dx atan rotate
0 0 moveto
w neg h lineto
w neg h neg lineto
savematrix setmatrix
end
} def
end
%%PageBoundingBox: 2 358 358 785
tgifdict begin
/tgifsavedpage save def
1 setmiterlimit
1 setlinewidth
0 setgray
72 0 mul 72 11.00 mul translate
72 128 div 100.000 mul 100 div dup neg scale
gsave
/tgiforigctm matrix currentmatrix def
% TEXT
0 setgray
/Courier-Bold findfont [24 0 0 -24 0 0] makefont setfont
gsave
192 36 moveto (The Taskloop) show
grestore
% TEXT
0 setgray
/Courier findfont [17 0 0 -17 0 0] makefont setfont
gsave
192 94 moveto (Device) show
192 111 moveto (Executor) show
grestore
% TEXT
0 setgray
/Courier findfont [17 0 0 -17 0 0] makefont setfont
gsave
112 190 moveto (Network) show
112 207 moveto (Reader) show
grestore
% TEXT
0 setgray
/Courier findfont [17 0 0 -17 0 0] makefont setfont
gsave
224 270 moveto (Client1 ) show
grestore
% TEXT
0 setgray
/Courier findfont [17 0 0 -17 0 0] makefont setfont
gsave
352 270 moveto (Client2) show
grestore
% TEXT
0 setgray
/Courier findfont [17 0 0 -17 0 0] makefont setfont
gsave
448 222 moveto (Client3) show
grestore
% TEXT
0 setgray
/Courier findfont [17 0 0 -17 0 0] makefont setfont
gsave
384 142 moveto (Emon) show
grestore
% RCBOX
0 setgray
gsave
gsave
newpath
272 80 moveto
288 80 288 128 16 arcto 4 {pop} repeat
288 112 lineto
288 128 176 128 16 arcto 4 {pop} repeat
192 128 lineto
176 128 176 80 16 arcto 4 {pop} repeat
176 96 lineto
176 80 288 80 16 arcto 4 {pop} repeat
closepath
stroke
grestore
grestore
% RCBOX
0 setgray
gsave
gsave
newpath
192 176 moveto
208 176 208 224 16 arcto 4 {pop} repeat
208 208 lineto
208 224 96 224 16 arcto 4 {pop} repeat
112 224 lineto
96 224 96 176 16 arcto 4 {pop} repeat
96 192 lineto
96 176 208 176 16 arcto 4 {pop} repeat
closepath
stroke
grestore
grestore
% RCBOX
0 setgray
gsave
gsave
newpath
432 128 moveto
448 128 448 160 16 arcto 4 {pop} repeat
448 144 lineto
448 160 368 160 16 arcto 4 {pop} repeat
384 160 lineto
368 160 368 128 16 arcto 4 {pop} repeat
368 144 lineto
368 128 448 128 16 arcto 4 {pop} repeat
closepath
stroke
grestore
grestore
% RCBOX
0 setgray
gsave
gsave
newpath
288 240 moveto
304 240 304 288 16 arcto 4 {pop} repeat
304 272 lineto
304 288 208 288 16 arcto 4 {pop} repeat
224 288 lineto
208 288 208 240 16 arcto 4 {pop} repeat
208 256 lineto
208 240 304 240 16 arcto 4 {pop} repeat
closepath
stroke
grestore
grestore
% RCBOX
0 setgray
gsave
gsave
newpath
416 240 moveto
432 240 432 288 16 arcto 4 {pop} repeat
432 272 lineto
432 288 336 288 16 arcto 4 {pop} repeat
352 288 lineto
336 288 336 240 16 arcto 4 {pop} repeat
336 256 lineto
336 240 432 240 16 arcto 4 {pop} repeat
closepath
stroke
grestore
grestore
% RCBOX
0 setgray
gsave
gsave
newpath
512 192 moveto
528 192 528 240 16 arcto 4 {pop} repeat
528 224 lineto
528 240 448 240 16 arcto 4 {pop} repeat
464 240 lineto
448 240 448 192 16 arcto 4 {pop} repeat
448 208 lineto
448 192 528 192 16 arcto 4 {pop} repeat
closepath
stroke
grestore
grestore
% POLY/OPEN-SPLINE
0 setgray
gsave
newpath
152 224 moveto
32 48 atan dup cos 12.000 mul 200 exch sub
exch sin 12.000 mul 256 exch sub lineto
tgiforigctm setmatrix
3 setlinewidth
stroke
1 setlinewidth
grestore
gsave
tgiforigctm setmatrix
newpath
200 256 12.000 5.000 48 32 tgifarrowtip
1 setgray closepath fill
0 setgray
newpath
200 256 12.000 5.000 48 32 tgifarrowtip
closepath fill
grestore
% POLY/OPEN-SPLINE
0 setgray
gsave
newpath
304 264 moveto
0 24 atan dup cos 12.000 mul 328 exch sub
exch sin 12.000 mul 264 exch sub lineto
tgiforigctm setmatrix
3 setlinewidth
stroke
1 setlinewidth
grestore
gsave
tgiforigctm setmatrix
newpath
328 264 12.000 5.000 24 0 tgifarrowtip
1 setgray closepath fill
0 setgray
newpath
328 264 12.000 5.000 24 0 tgifarrowtip
closepath fill
grestore
% POLY/OPEN-SPLINE
0 setgray
gsave
newpath
432 272 moveto
-24 32 atan dup cos 12.000 mul 464 exch sub
exch sin 12.000 mul 248 exch sub lineto
tgiforigctm setmatrix
3 setlinewidth
stroke
1 setlinewidth
grestore
gsave
tgiforigctm setmatrix
newpath
464 248 12.000 5.000 32 -24 tgifarrowtip
1 setgray closepath fill
0 setgray
newpath
464 248 12.000 5.000 32 -24 tgifarrowtip
closepath fill
grestore
% POLY/OPEN-SPLINE
0 setgray
gsave
newpath
504 192 moveto
-40 -48 atan dup cos 12.000 mul 456 exch sub
exch sin 12.000 mul 152 exch sub lineto
tgiforigctm setmatrix
3 setlinewidth
stroke
1 setlinewidth
grestore
gsave
tgiforigctm setmatrix
newpath
456 152 12.000 5.000 -48 -40 tgifarrowtip
1 setgray closepath fill
0 setgray
newpath
456 152 12.000 5.000 -48 -40 tgifarrowtip
closepath fill
grestore
% POLY/OPEN-SPLINE
0 setgray
gsave
newpath
368 144 moveto
32 -152 atan dup cos 12.000 mul 216 exch sub
exch sin 12.000 mul 176 exch sub lineto
tgiforigctm setmatrix
3 setlinewidth
stroke
1 setlinewidth
grestore
gsave
tgiforigctm setmatrix
newpath
216 176 12.000 5.000 -152 32 tgifarrowtip
1 setgray closepath fill
0 setgray
newpath
216 176 12.000 5.000 -152 32 tgifarrowtip
closepath fill
grestore
% POLY/OPEN-SPLINE
0 setgray
gsave
[4 12] 0 setdash
newpath
368 136 moveto
-32 -64 atan dup cos 10.000 mul 304 exch sub
exch sin 10.000 mul 104 exch sub lineto
tgiforigctm setmatrix
2 setlinewidth
stroke
[] 0 setdash
1 setlinewidth
grestore
gsave
tgiforigctm setmatrix
newpath
304 104 10.000 4.000 -64 -32 tgifarrowtip
1 setgray closepath fill
0 setgray
newpath
304 104 10.000 4.000 -64 -32 tgifarrowtip
closepath fill
grestore
% POLY/OPEN-SPLINE
0 setgray
gsave
[4 12] 0 setdash
newpath
176 104 moveto
64 -32 atan dup cos 10.000 mul 144 exch sub
exch sin 10.000 mul 168 exch sub lineto
tgiforigctm setmatrix
2 setlinewidth
stroke
[] 0 setdash
1 setlinewidth
grestore
gsave
tgiforigctm setmatrix
newpath
144 168 10.000 4.000 -32 64 tgifarrowtip
1 setgray closepath fill
0 setgray
newpath
144 168 10.000 4.000 -32 64 tgifarrowtip
closepath fill
grestore
% TEXT
0 setgray
/Courier-Bold findfont [20 0 0 -20 0 0] makefont setfont
gsave
128 407 moveto (SICS Interpreter and Macro Language) show
grestore
% TEXT
0 setgray
/Courier-Bold findfont [25 0 0 -25 0 0] makefont setfont
gsave
136 508 moveto (SICS Object Database) show
grestore
% BOX
0 setgray
gsave
10 setmiterlimit
gsave
newpath
104 472 moveto 536 472 lineto 536 536 lineto 104 536 lineto
closepath
2 setlinewidth
stroke
grestore
grestore
% TEXT
0 setgray
/Courier-Bold findfont [25 0 0 -25 0 0] makefont setfont
gsave
128 700 moveto (Hardware ) show
grestore
% BOX
0 setgray
gsave
10 setmiterlimit
gsave
newpath
112 664 moveto 576 664 lineto 576 768 lineto 112 768 lineto
closepath
2 setlinewidth
stroke
grestore
grestore
% POLY/OPEN-SPLINE
0 setgray
gsave
newpath
280 432 moveto
40 0 atan dup cos 14.000 mul 280 exch sub
exch sin 14.000 mul 472 exch sub lineto
tgiforigctm setmatrix
4 setlinewidth
stroke
1 setlinewidth
grestore
gsave
tgiforigctm setmatrix
newpath
280 472 14.000 6.000 0 40 tgifarrowtip
1 setgray closepath fill
0 setgray
newpath
280 472 14.000 6.000 0 40 tgifarrowtip
closepath fill
grestore
% POLY/OPEN-SPLINE
0 setgray
gsave
newpath
176 536 moveto
120 0 atan dup cos 14.000 mul 176 exch sub
exch sin 14.000 mul 656 exch sub lineto
tgiforigctm setmatrix
4 setlinewidth
stroke
1 setlinewidth
grestore
gsave
tgiforigctm setmatrix
newpath
176 656 14.000 6.000 0 120 tgifarrowtip
1 setgray closepath fill
0 setgray
newpath
176 656 14.000 6.000 0 120 tgifarrowtip
closepath fill
grestore
% POLY/OPEN-SPLINE
0 setgray
gsave
newpath
320 536 moveto
120 -104 atan dup cos 14.000 mul 216 exch sub
exch sin 14.000 mul 656 exch sub lineto
tgiforigctm setmatrix
4 setlinewidth
stroke
1 setlinewidth
grestore
gsave
tgiforigctm setmatrix
newpath
216 656 14.000 6.000 -104 120 tgifarrowtip
1 setgray closepath fill
0 setgray
newpath
216 656 14.000 6.000 -104 120 tgifarrowtip
closepath fill
grestore
% POLY/OPEN-SPLINE
0 setgray
gsave
newpath
408 536 moveto
120 80 atan dup cos 14.000 mul 488 exch sub
exch sin 14.000 mul 656 exch sub lineto
tgiforigctm setmatrix
4 setlinewidth
stroke
1 setlinewidth
grestore
gsave
tgiforigctm setmatrix
newpath
488 656 14.000 6.000 80 120 tgifarrowtip
1 setgray closepath fill
0 setgray
newpath
488 656 14.000 6.000 80 120 tgifarrowtip
closepath fill
grestore
% POLY/OPEN-SPLINE
0 setgray
gsave
[12 4] 0 setdash
newpath
248 288 moveto
80 0 atan dup cos 8.000 mul 248 exch sub
exch sin 8.000 mul 368 exch sub lineto
tgiforigctm setmatrix
1 setlinewidth
stroke
[] 0 setdash
grestore
gsave
tgiforigctm setmatrix
newpath
248 368 8.000 3.000 0 80 tgifarrowtip
1 setgray closepath fill
0 setgray
newpath
248 368 8.000 3.000 0 80 tgifarrowtip
closepath fill
grestore
% POLY/OPEN-SPLINE
0 setgray
gsave
[12 4] 0 setdash
newpath
376 288 moveto
80 -120 atan dup cos 8.000 mul 256 exch sub
exch sin 8.000 mul 368 exch sub lineto
tgiforigctm setmatrix
1 setlinewidth
stroke
[] 0 setdash
grestore
gsave
tgiforigctm setmatrix
newpath
256 368 8.000 3.000 -120 80 tgifarrowtip
1 setgray closepath fill
0 setgray
newpath
256 368 8.000 3.000 -120 80 tgifarrowtip
closepath fill
grestore
% POLY/OPEN-SPLINE
0 setgray
gsave
[12 4] 0 setdash
newpath
504 240 moveto
496 312 lineto
56 -224 atan dup cos 8.000 mul 272 exch sub
exch sin 8.000 mul 368 exch sub lineto
tgiforigctm setmatrix
1 setlinewidth
stroke
[] 0 setdash
grestore
gsave
tgiforigctm setmatrix
newpath
272 368 8.000 3.000 -224 56 tgifarrowtip
1 setgray closepath fill
0 setgray
newpath
272 368 8.000 3.000 -224 56 tgifarrowtip
closepath fill
grestore
% TEXT
0 setgray
/Courier findfont [17 0 0 -17 0 0] makefont setfont
gsave
504 310 moveto (send commands) show
grestore
% TEXT
0 setgray
/Courier findfont [17 0 0 -17 0 0] makefont setfont
gsave
488 166 moveto (pass execution) show
grestore
% BOX
0 setgray
gsave
10 setmiterlimit
gsave
newpath
96 368 moveto 624 368 lineto 624 432 lineto 96 432 lineto
closepath
2 setlinewidth
stroke
grestore
grestore
% POLY/OPEN-SPLINE
0 setgray
gsave
newpath
8 16 moveto
56 120 lineto
64 72 lineto
104 168 lineto
tgiforigctm setmatrix
4 setlinewidth
stroke
1 setlinewidth
grestore
% POLY/OPEN-SPLINE
0 setgray
gsave
newpath
104 168 moveto
80 152 lineto
tgiforigctm setmatrix
4 setlinewidth
stroke
1 setlinewidth
grestore
% POLY/OPEN-SPLINE
0 setgray
gsave
newpath
104 168 moveto
112 144 lineto
tgiforigctm setmatrix
4 setlinewidth
stroke
1 setlinewidth
grestore
% TEXT
0 setgray
/Courier findfont [17 0 0 -17 0 0] makefont setfont
gsave
40 62 moveto (TCP/IP) show
grestore
grestore
tgifsavedpage restore
end
%MatchingCreationDate: Thu Nov 20 13:43:31 1997

BIN
doc/programmer/newsics.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

160
doc/programmer/nread.tex Normal file
View File

@ -0,0 +1,160 @@
\subsection{The Network Reader}
The network readers task is to read incoming messages for the SICS server.
These may come in four main forms.
\begin{itemize}
\item connection requests
\item commands
\item interrupts
through a command channel
\item interrupt messages on the UDP port.
\end{itemize}
A prior
version of SICS had a select system call for each of these cases. It was
found, that the code spent most of its time in the select system call
thus intrdoducing a major performance problem.
The select system call can handle more then one file descriptor in one call.
This is exactly what this module handles. It does a global select on
all open sockets and forwards any pending data to approriate handlers.
This scheme brought a drastic
performance improvement.
Each of the messages to SICS is handled
differently:
A connection request will be validated, a new connection object will be
created and a new task for this connection object will be started.
A command will be placed in the apropriate command stack for the task
belonging to this connection to work on in a later stage. The netreader will
also take care that all commands are complete, this is the terminator
\verb+\n+ or \verb+\r+ has been sent.
Both forms of interrupt will be interpreted and a suitable signal
will be sent to all runing tasks if the interrupt request is valid.
In order to perform his tasks the network reader needs to maintain a list of
all open sockets and their types. Additionally it needs to know about the
SICS tasker.
The early version of SICS only supported connections on a plain
socket. This feauture is not used any more in favour of the Telnet
option described below. However, as this may be used to transport
binary data, the obsolete code has not been removed.
Support for the internet TCP/IP standard telnet protocoll has been added in
January 1998. Telnet things need to be handled differently, therefore two
more socket types have been defined: A telnet listen socket on which
requests for telnet connections are listened for, and a telnet command
socket which actually process the telnet messages.
Support for user sockets was added in February 1998. User sockets provides a
primitive interface to the network readers monitoring functions. This is
part of a solution to one problem which can occur in SICS: The whole server
is blocked if one of the serial devices is slow in responding. User sockets
now provide a method for client code to register a socket for monitoring
with the network reader and find out if data is pending at it. This support
is provided by the functions: NetReadRegisterUserSocket,
NetReadRemoveUserSocket, NetReadReadable and NetReadResetUser described
below. NetReadWait4Data is a special wait function which waits for data to
come in on a user socket. This function is problematic with dynamically
creates and deleted objects such as environment device objects. Its use is
therefore no longer recommended.
Thus the interface looks like this:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap1}
$\langle$nrint {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*--------------------------------------------------------------------------*/@\\
\mbox{}\verb@ typedef struct __netreader *pNetRead;@\\
\mbox{}\verb@ typedef enum {naccept, command, udp, user, taccept, tcommand} eNRType;@\\
\mbox{}\verb@/*--------------------------------------------------------------------------*/@\\
\mbox{}\verb@ pNetRead CreateNetReader(pServer pServ, int iPasswdTimeout,@\\
\mbox{}\verb@ int iReadTimeout);@\\
\mbox{}\verb@ void DeleteNetReader(void *pData);@\\
\mbox{}\verb@/*--------------------------------------------------------------------------*/@\\
\mbox{}\verb@ int NetReadRegister(pNetRead self, mkChannel *pSock, eNRType eType,@\\
\mbox{}\verb@ SConnection *pCon);@\\
\mbox{}\verb@ int NetReadRegisterUserSocket(pNetRead self, int iSocket);@\\
\mbox{}\verb@ int NetReadRemove(pNetRead self, mkChannel *pSock);@\\
\mbox{}\verb@ int NetReadRemoveUserSocket(pNetRead self, int iSocket);@\\
\mbox{}\verb@/*-------------------------------------------------------------------------*/@\\
\mbox{}\verb@ int NetReaderTask(void *pReader); @\\
\mbox{}\verb@ void NetReaderSignal(void *pUser, int iSignal, void *pSigData);@\\
\mbox{}\verb@ int NetReadWait4Data(pNetRead self, int iSocket);@\\
\mbox{}\verb@ int NetReadReadable(pNetRead self, int iSocket);@\\
\mbox{}\verb@ int NetReadResetUser(pNetRead self, int iSocket);@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
This starts off with the definition of a data type for the net reader and an
enum which denotes the possible types of connections.
\begin{description}
\item[CreateNetReader] sets a new net reader up. Only parameter is a pointer
to the task manager to use while creating new connections. iPasswdTimeout
is the period in which a client is expected to send his userid/password
pair. iReadTimeout is the time to wait on the select statement for a
channel to become readable. Both time values are specified in milliseconds.
\item[DeleteNetReader] deletes the net reader and all its data structures.
Must be called in order to free all memory.
\item[NetReadRegister] register the channel pSock of type eType with the net
reader self. The parameter pData will only be interpreted for connections
of type command. It must point to the command stack belonging to the
connection which registers this socket.
\item[NetReadRegisterUserSocket] registers a socket from within SICS foth
the network reader. The client code to this module may then find out with a
call to NetReadReadable if data is pending on this socket. This a
convenience wrapper to NetReadRegister.
\item[NetReadRemove] removes the socket pSock from the net reader. This must
be done when closing the socket, otherwise the net reader will continue
checking for pending data on this socket.
\item[NetReadRemoveUserSocket] removes a user socket from
monitoring. Again, this is a vonvenience wrapper around NetReadRemove.
\item[NetReaderTask] is the net reader task function which will be
registered with the task manager. This function builds the select
mask, does the select and forwards incoming data to the appropriate
handler functions. These are not documented here, as they are file
static function in nread.c.
\item[NetReaderSignal] is the signal handler for the net reader. It
just stops the NetReaderTask when the SICS server is run down.
\item[NetReadReadable] returns 1 if data is pending at the user socket or 0
if not.
\item[NetReadResetUser] resets a user socket to not readable.
\end{description}
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap2}
\verb@"nread.h"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*------------------------------------------------------------------------@\\
\mbox{}\verb@ N E T R E A D E R@\\
\mbox{}\verb@@\\
\mbox{}\verb@ This module will check for pending requests to the SICS server and@\\
\mbox{}\verb@ initiate apropriate actions.@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Mark Koenencke, September 1997@\\
\mbox{}\verb@@\\
\mbox{}\verb@ copyright: see copyright.h@\\
\mbox{}\verb@@\\
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
\mbox{}\verb@#ifndef SICSNETREADER@\\
\mbox{}\verb@#define SICSNETREADER@\\
\mbox{}\verb@@$\langle$nrint {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@#endif@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}

123
doc/programmer/nserver.tex Normal file
View File

@ -0,0 +1,123 @@
\subsection{The SICS Server Object}
This objects responsability is the proper initialisation and shutdown
of the SICS server and the provision of some utility functions.
The Server's data structure holds pointers to the most important parts of
the system:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap1}
$\langle$servdat {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@@\\
\mbox{}\verb@ typedef struct __SicsServer {@\\
\mbox{}\verb@ SicsInterp *pSics;@\\
\mbox{}\verb@ pTaskMan pTasker;@\\
\mbox{}\verb@ pExeList pExecutor;@\\
\mbox{}\verb@ pEnvMon pMonitor;@\\
\mbox{}\verb@ mkChannel *pServerPort;@\\
\mbox{}\verb@ pNetRead pReader;@\\
\mbox{}\verb@ } SicsServer;@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
The fields are:
\begin{description}
\item[pSics] is a pointer to the SICS interpreter.
\item[pTasker] is a pointer to the task scheduler.
\item[pExecutor] is a pointer to the device executor. This module monitors
variables during counting and driving operations.
\item[pMonitor] is a pointer to an environment device controller monitor.
This module monitors sample environment controllers.
\item[pServerPort] points to a data structure describing the port at which
the SICS server is listening for connections.
\item[pReader] points to a data structure which defines the network
communication object.
\end{description}
In terms of a function interface the server module supplies.
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap2}
$\langle$servint {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*----------------------------------------------------------------------*/@\\
\mbox{}\verb@ int InitServer(char *file, pServer *pServ);@\\
\mbox{}\verb@ void RunServer(pServer self);@\\
\mbox{}\verb@ void StopServer(pServer self);@\\
\mbox{}\verb@/*----------------------------------------------------------------------*/@\\
\mbox{}\verb@ SicsInterp *GetInterpreter(void);@\\
\mbox{}\verb@ pExeList GetExecutor(void);@\\
\mbox{}\verb@ pTaskMan GetTasker(void);@\\
\mbox{}\verb@ void ServerWriteGlobal(char *pMessage, int iCode);@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
For most functions the name already says what it does. {\bf
InitServer} initializes the SICS servers data structures. {\bf
RunServer} implements the main loop and essentially calls the task
modules ScheduleTask function for running all the SICS tasks which
will handle the rest of the job. {\bf Stopserver} is responisble for
closing the SICS server down in a sensible manner and in a well
defined sequence of events.
{\bf ServerWriteGlobal}
is special. This function sends the message pMessage to all clients
currently connected to the SICS server with the output code iCode. iCode has
the same meaning as in the connection object.
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap3}
\verb@"nserver.h"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*--------------------------------------------------------------------------@\\
\mbox{}\verb@ N S E R V E R@\\
\mbox{}\verb@@\\
\mbox{}\verb@ The SICS server main data structure and functions.@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Restructured: September 1997@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Mark Koennecke.@\\
\mbox{}\verb@ @\\
\mbox{}\verb@ copyright: see copyright.h@\\
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
\mbox{}\verb@#ifndef SICSNSERVER@\\
\mbox{}\verb@#define SICSNSERVER@\\
\mbox{}\verb@#include "conman.h"@\\
\mbox{}\verb@#include "SCinter.h"@\\
\mbox{}\verb@#include "emon.h"@\\
\mbox{}\verb@#include "devexec.h"@\\
\mbox{}\verb@#include "task.h"@\\
\mbox{}\verb@#include "network.h"@\\
\mbox{}\verb@@\\
\mbox{}\verb@ typedef struct __SicsServer *pServer;@\\
\mbox{}\verb@@\\
\mbox{}\verb@#include "nread.h"@\\
\mbox{}\verb@@$\langle$servdat {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@@$\langle$servint {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@ int UserWait(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@@\\
\mbox{}\verb@ int SicsWait(long lTime);@\\
\mbox{}\verb@#endif@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}

69
doc/programmer/nxamor.tex Normal file
View File

@ -0,0 +1,69 @@
\subsection{AMOR NeXus Routines}
This module implements a few functions for writing NeXus data files
for the reflectoemter AMOR at SINQ, PSI. Nothing very exciting here:
this is mostly boring repetetive code. Three functions are defined:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap1}
$\langle$namor {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ int WriteAmorHeader(char *file, SConnection *pCon);@\\
\mbox{}\verb@@\\
\mbox{}\verb@ int WriteAmorScan(char *file, SConnection *pCon, pScanData pScan);@\\
\mbox{}\verb@@\\
\mbox{}\verb@ int WriteAmorTOF(char *file, SConnection *pCon, pHistMem pHM);@\\
\mbox{}\verb@@\\
\mbox{}\verb@ int AmorStore(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@ int AmorStoreMake(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
\begin{description}
\item[WriteAmorHeader] writes all the AMOR header information and the
zillions of motors.
\item[WriteAmorScan] writes data when AMOR was operated in scanning
mode.
\item[WriteAmorTOF] writes AMOR data when used with the PSD in
time-of-flight mode.
\item[AmorStore] the command function implementing the storeamor
command.
\item[AmorStoreMake] the initialization function which creates the
storeamor command.
\end{description}
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap2}
\verb@"nxamor.h"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*------------------------------------------------------------------------@\\
\mbox{}\verb@ N X A M O R@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Some routines for writing NeXus files for the reflectometer AMOR at@\\
\mbox{}\verb@ SINQ.@\\
\mbox{}\verb@ @\\
\mbox{}\verb@ copyright: see copyright.h@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Mark Koennecke, September 1999@\\
\mbox{}\verb@----------------------------------------------------------------------*/@\\
\mbox{}\verb@#ifndef NXAMOR@\\
\mbox{}\verb@#define NXAMOR@\\
\mbox{}\verb@@$\langle$namor {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@#endif@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}

192
doc/programmer/nxdata.tex Normal file
View File

@ -0,0 +1,192 @@
\subsection{NXdata}
NXdata is a module for writing Powder Diffraction Data files. The
routines here are somewhat obsolete as they refer to NeXus writing
using the standard Napi routines which is quite involved. Usually,
NeXus files are written from SICS through the NXDICT aware utility
routines in NXUTIL.
If not stated
otherwise, all routines return 1 on successful completion and 0 when an
error is detected. Please note, that many of these routines expect to find
certain data items in the Sics Interpreter. This implies, that any naming
changes in the initialisation file might force changes in here as well.
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap1}
$\langle$Protos {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ char *SNXMakeFileName(SicsInterp *pSics, SConnection *pCon);@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro defined by scraps ?, ?, ?, ?, ?, ?, ?.
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
SNXMakeFileName creates a new filename from the SICS variables SicsDataPath,
SicsDataPresript, SicsDataNumber and SicsDataEnding. SicsDataNumber will be
incremented as well. The function returns a newly allocate buffer with the
assembled filename or NULL on error. Note, that the caller is responsible
for freeing the memory associated with the filename afterwards.
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap2}
$\langle$Protos {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ NXhandle SNXStartFile(SConnection *pCon, SicsInterp *pSics); @\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro defined by scraps ?, ?, ?, ?, ?, ?, ?.
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
First calls SNXMakeFileName in order to get a new Filename.
Then a new Nexus file is
created and all the standard headings are filled in: Filename, User,
instrument, date etc. This routine also installs an error handler which
prints errors to pCon.
If successful, the SicsDataNumber is incremented and
an NXhandle into the new file is returned. If there is a problem, NULL
will be returned. The file returned will be positioned at root level.
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap3}
$\langle$Protos {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ int SNXStartEntry(NXhandle Nfil, int iNew, SicsInterp *pSics);@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro defined by scraps ?, ?, ?, ?, ?, ?, ?.
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap4}
$\langle$Protos {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ void SNXFormatTime(char *pBuffer, int iBufLen);@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro defined by scraps ?, ?, ?, ?, ?, ?, ?.
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
SNXFormatTime formats the current system time in a form compatible to the
NeXus standard. Input parameters is a Buffer to hold the string and a
length of the buffer. Maximum iBufLen characters will be copied to that
buffer.
SNXStartEntry creates a new entry corresponding to iNew in the Nexus file
Nfil. SNXStartEntry will position Nfil in this new entry. Any data items
labeled as Comment or intent will be written to the file as well.
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap5}
$\langle$Protos {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ int SNFinishFile(NXhandle Nfil);@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro defined by scraps ?, ?, ?, ?, ?, ?, ?.
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
SNFinishFile will end a Nexus file properly.
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap6}
$\langle$Protos {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ int SNMakeDMC(SConnection *pCon, SicsInterp *pSics);@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro defined by scraps ?, ?, ?, ?, ?, ?, ?.
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
SNMakeDMC produces a Nexus DMC data file from the currently valid
information. It orchestrates all of the above.
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap7}
$\langle$Protos {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@int SNStoreDMC(SConnection *pCon, SicsInterp *pSics, void *pData, int argc,@\\
\mbox{}\verb@ char *argv[]);@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro defined by scraps ?, ?, ?, ?, ?, ?, ?.
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
SNStoreData is the wrapper function used to install a DMC data storage
command in the Sics interpreter.
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap8}
\verb@"nxdata.h"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*-------------------------------------------------------------------------@\\
\mbox{}\verb@ N X D A T A@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Some routines for handling Nexus data file writing.@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Mark Koennecke, April 1997@\\
\mbox{}\verb@ @\\
\mbox{}\verb@ copyright: see implementation file.@\\
\mbox{}\verb@--------------------------------------------------------------------------*/@\\
\mbox{}\verb@#ifndef SICSNXDATA@\\
\mbox{}\verb@#define SICSNXDATA@\\
\mbox{}\verb@@$\langle$Protos {\footnotesize ?, \ldots\ }$\rangle$\verb@ @\\
\mbox{}\verb@#endif @\\
\mbox{}\verb@@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}

3053
doc/programmer/nxdict.tex Normal file

File diff suppressed because it is too large Load Diff

42
doc/programmer/nxsans.tex Normal file
View File

@ -0,0 +1,42 @@
\subsection{NXUTIL}
Ther are some utility functions for writing NeXus data files from
SICS with the NXDICT-API. These are collected in the files nxutil.h
and nxutil.c.
\begin{description}
\item[int SNXSPutMotor(SicsInterp *pSics, SConnection *pCon, NXhandle hFil,
NXdict pDict, char *pAlias, char *pName)] writes the
value of a motor to file. The parameters are: \begin{description}
\item[pSics] The SICS interpreter to search for the motor.
\item[pCon] The connection object to which to print errors.
\item[hFil] The handle of the NeXus file to write.
\item[pDict] The handle of the NeXus dictionary to use.
\item[pAlias] The alias name to use for writing.
\item[pName] The name of the motor.
\end{description}
\item[SNXSPutMotorNULL] writes the motor zero point. Same parameters
as above.
\item[int SNXSPutVariable(SicsInterp *pSics, SConnection *pCon,\\
NXHandle hFil, NXdict pDict, char *pAlias,\\
char *pName)] writes a SICS variable to a NeXus file
using the dictionary. Parameters similar to SNXSPutMotor.
\item[SNXSPutEVVar(NXhandle hfil,NXdict pDict,char *pName, SConnection
*pCon,\\ char *pValAlias, char *pStddevAlias)]
This writes an environment variable pName to the file described by hfil,
using the dictionary pDict. A warning is printed if the variable is
not configured. If a variable is found its value and standard
deviation are written to file using the aliases given as parameters.
\item[SNXSPutGlobals] writes global data to the file.
\item[SNXSFormatTime] returns the current time formatted according to
the NeXus specification in buffer. Max iLen characters will be copied
to buffer.
\item[SNXSMakeFileName] returns a pointer to a buffer containing a new
file name for a data file. This function assembles the filename from
the DataNUmber and various SICS variables. The caller has to free the
buffer containg the name.
\item[SNXSPutDrivable] writes any variable adhering to the drivable
interface.
\end{description}

42
doc/programmer/o2t.tex Normal file
View File

@ -0,0 +1,42 @@
\subsection{Omega 2Theta}
This is an example for a simple virtual motor. It uses two motors and runs
the second one to exactly the double value of the first one. It can be used
to implement omega--two--theta (o2t) scans at reflectometers of four circle
diffractometers using the normal scan command.
The o2t module uses the following data structure:
\begin{verbatim}
typedef struct __SicsO2T {
pObjectDescriptor pDes;
pIDrivable pDrivInt;
pMotor pOmega;
pMotor pTheta;
} SicsO2T;
\end{verbatim}
The fields:
\begin{description}
\item[pDes] A pointer to the usual SICS object descriptor.
\item[pDrivInt] A pointer to the drivable interface implemented by this
variable.
\item[pOmega] A pointer to the first motor to use.
\item[pTheta] A pointer to the motor data structure of the second (double)
motor to use.
\end{description}
Most of this modules action lives in the drivable interface. The rest is
achieved through the following functions:
\begin{description}
\item[pSicsO2T MakeO2T(char *omega, char *theta, SicsInterp *pSics)] creates
a new o2t object from motors omega and theta. Returns NULL on failure and a
pointer to an o2t data structure on success.
\item[void DeleteO2T(void *pData)] deletes an o2t object.
\item[int CreateO2T(SConnection *pCon, SicsInterp *pSics, void *pData,\\
int argc, char *argv[])] The object factory function for o2t
objects.
\end{description}
Please note, that o2t is just a helper variable and can not be manipualted
from the SICS interpreter.

44
doc/programmer/obpar.tex Normal file
View File

@ -0,0 +1,44 @@
\subsection{SICS Parameter Array}
This thing holds an array of floating point numbers, their names and their access codes.
It is used in SICS object implementations to hold larger amounts of
configurable parameters. It provides functions for simplifying the
management of such parameters.
Each parameter is described by a structure shown below:
\begin{verbatim}
typedef struct {
char *name;
float fVal;
int iCode;
} ObPar;
\end{verbatim}
The fields are: \begin{description}
\item[name] The name of the parameter.
\item[fVal] The parameters value.
\item[iCode] The access code necessary to modify the parameter.
\end{description}
Parameter arrays are maintained by the functions described below:
\begin{description}
\item[ float ObVal(ObPar *self, int i)] gets the value of parameter i from
the array self. This call is for module internal usage.
\item[int ObParLength(ObPar *self)]
finds the length of an ObPar array.
\item[ObPar *ObParFind(ObPar *self, char *name)]
finds a ObPar struct for a name, return NULL if none.
\item[int ObParInit(ObPar *self,int i, char *name, float fVal, int iCode)]
sets a ObPar entry. self is a pointer to the array.
\item[int ObParSet(ObPar *self, char *obname,char *name, float fVal, SConnection
*pCon)]
checks if the connections permissions are alright and changes value
if so. Returns 1 on success, 0 on failure. Prints errors directly to
pCon. The parameter obname is the name of the object the parameters belong
to. Needed for error printing. name is the parameter name, fVal the new
value.
\item[void ObParDelete(ObPar *self)]
Deletes an ObPar array.
\item[ObPar *ObParCreate(int iArrayLong)]
creates an array with iASrrayLong entries. Returns NULL on failure, else
a pointer to the array.
\end{description}

24
doc/programmer/ofac.tex Normal file
View File

@ -0,0 +1,24 @@
\subsection{The Object Factory}
SICS is a highly configurable system. This module implements
the configurable. Configuration is meant to happen via a Tcl-
configuration script. This module will initialize commands which
create SICS-objects. Than an initialization file is evaluated
via the macro facility. As most of the initialization commands
will no longer be needed after this, they will be deleted.
All this will be run with a higly privileged connection which
prints to stdout/stdin. This module contains the file static functions:
InitIniCommands and KillIniCommands. {\bf InitIniCommands}
intializes all SICS common commands plus the object creation
commands. Once a new class has been devised its object
creation function needs to be entered into this
function. {\bf KillIniCommands} removes all the initialization
commands no longer needed after the initialization file has
been evaluated. Make sure to add an entry for your new
classes creation command here as well.
The interface consists of a single function: \begin{verbatim}
int InitObjectCommands(pServer pServ, char *file);
\end{verbatim}
Commands will be initialized for the server pServ from the file file.

804
doc/programmer/oguide.tex Normal file
View File

@ -0,0 +1,804 @@
\chapter{Guide To SICS Object Writers}
This chapter describes the necessary steps for adding new objects to the SICS server. In order to live
happily within SICS an object is obliged to stick to a set of rules and interfaces already defined. Such
interfaces will be described here as well. For the following text it is assumed, that the reader has studied
the SICS overview and kernel guide.
In general the following steps will be necessary in order to introduce a new object into SICS:
\begin{enumerate}
\item Define a new object data structure.
\item Define a function capable of deleting the object from memory.
\item Define a set of functions which define the operations on this object.
\item Create an object wrapper function which defines the user commands
the object can handle.
\item Create an object creation function, which is capable of initializing
the object and creates a new command in the SICS interpreter.
\item Add the new objects creation command into the IniInitCommand and
KillIniCommands functions defined in ofac.c.
\item Document the new object.
\end{enumerate}
All these steps will now be discussed together with some additional SICS
concepts applicable to writing new objects. Not all of the above mentioned
steps will be necessary in all cases. If a new general SICS object is defined,
no object creation function may be needed. Then it is sufficient to register
the new object/command with the SICS interpreter in IniInitCommands, file ofac.c.
In the rare cases where an object needs no data structure, the system will provide a dumb
default which will not harm the system. Some objects may have more then one
command associated with them. Some more care has to be taken when adding a
new piece of hardware into the system. If it is just a variant of an already
known type (for instance a new type of motor) it will be sufficient to introduce
a new driver into the system. The procedures for doing this will be described
in the reference sections for the appropriate device. Otherwise the SICS rule
to divide a hardware object into a logical object and a driver should be
observed. At minimum two drivers are necessary anyway in the first place:
the driver for the actual device and a simulation driver which permits some
debugging to take place while the hardware is still unavailable.
\section{Mapping Object Oriented Concepts into ANSI--C}
SICS is in principle an object oriented system. However, it is implemented
in ANSI--C. Therefore object oriented concepts must be mapped into C. The
three object oriented concepts which need to be mapped are:
\begin{itemize}
\item Data Encapsulation.
\item Polymorphism.
\item Inheritance.
\end{itemize}
Of these, data encapsulation is by far the most important concept. Objects
in computer science can be understood as little boxes which contain some
data describing their state and which understand messages sent by other
objects. If such a message comes in, the object performs some action,
perhaps changes its internal state or sends new messages to other objects.
It is understood that changes to the internal data of the object can be
achieved only through messages to the object and not by directly manipulating
variables from the outside. In ANSI--C an object maps to a structure holding
the objects data and the messages map to functions which act upon the data
structure. In order to do this, the functions must take a pointer to the
objects data structure as first parameter. In order to prevent messing with
an objects data structure, only a pointer to a structure is declared in the
header file. The actual definition of the data structure happens only in
the implementation file. All functions belonging to an object are defined in that
implementation file and have full access to the data structure.
Users of the object see only the header file and thus only a pointer to the
objects data structure which prevents
them from messing with the objects data directly.
In order to illustrate the concepts lets look at
a primitive integer object defined in such a way.
\begin{verbatim}
/*-----------------------------------------------------------------------
ExampleInt.h
------------------------------------------------------------------------*/
typedef struct __ExampleInt *pExampleInt;
int GetInt(pExampleInt self);
void SetInt(pExampleInt self, int iNew);
/*------------------- EOF ExampleInt.h---------------------------------*/
/*----------------------------------------------------------------------
ExampleInt.c, Implementation file
-----------------------------------------------------------------------*/
typedef struct __ExampleInt {
int iExample;
} ExampleInt;
/*--------------------------------------------------------------------*/
int GetInt(pExampleInt self)
{
return self->iExample;
}
/*---------------------------------------------------------------------*/
void SetInt(pExampleInt self, int iNew)
{
self->iExample = iNew;
}
\end{verbatim}
Using this scheme all code changing the internal state of an object lives
in one file. Changes to the objects data structure affect only the
implementation file and no other files.
This scheme is used for almost all SICS objects. A few system objects and
older SICS objects define their data structures in header files. This is
either a relic or had to be done for performance reasons.
The next concept is polymorphism. This describes the situation when a group
of objects respond to the same message but doing different things. For
instance a whole set of objects would implement a write functionality
which writes the objects state to a file. Higher level would then not need
to know of which type the actual object is, it just can send the write message
and the rest is taken care of by the object. This concept is used for all
hardware drivers in SICS. Mapping this to C requires to expose the objects
data structure and let the data structure include a pointer to that polymorphic
function. As an example, the ExampleInteger with a write function:
\begin{verbatim}
/*-----------------------------------------------------------------------
ExampleInt.h
------------------------------------------------------------------------*/
typedef struct __ExampleInt{
int iExample;
void (*write)(struct __ExampleInt *self, FILE *fd);
} *pExampleInt, ExampleInt;
pExampleInt MakeInt(int iNew);
int GetInt(pExampleInt self);
void SetInt(pExampleInt self, int iNew);
/*------------------- EOF ExampleInt.h---------------------------------*/
/*----------------------------------------------------------------------
ExampleInt.c, Implementation file
-----------------------------------------------------------------------*/
static void ExampleWrite(struct _-ExampleInt *self, FILE *fd)
{
fprintf(fd,"INT = %d",self->iExample);
}
/*---------------------------------------------------------------------*/
pExampleInt MakeInt(int iNew)
{
pExampleInt pNew = NULL;
pNew = (pExampleInt)malloc(sizeof(ExampleInt));
pNew->iExample = iNew;
pNew->write = ExampleWrite;
return pNew;
}
.
.
.
\end{verbatim}
This can then be called:
\begin{verbatim}
void SomeFunc()
{
pExampleInt pTest;
pTest = MakeInt(25);
.
.
.
pTest->write(pTest,fd);
}
\end{verbatim}
This example also illustrates the concept of a special function which creates
a new object of the appropriate type and initializes its data structure
properly.
The last concept to discuss is inheritance. Inheritance can be used when
an object is a derivative of another object. For instance a truck is a
derivative of a motor car. Much of the behavior of a motor car will be the
same as for a truck. In order to prevent rewriting of code, the truck
should use the same data structures and code as the motor car. And add
or modify only what is special. Inheritance is not much used in SICS. It can
be implemented by overlaying data structures. This means the derived
classes data structure has the same fields in the same order as the parent
class and adds its specials at the end. For example:
\begin{verbatim}
typedef struct __MotorCar {
int iWheels;
float fSpeed;
} *pMotorCar, MotorCar;
typedef struct __Truck {
int iWheels;
float fSpeed; /* same as MotorCar */
double dPayLoad; /* special for Truck */
} *pTruck, Truck;
\end{verbatim}
Thus functions defined for motor car can operate on trucks as well.
For more details study the relationship between the ITC4 controller and
general environment controllers. This is the only place where SICS
currently uses inheritance.
\section{The Object Data Structure}
Nearly all SICS objects require some data. This data is collected in a
C structure typical for the object. This is just a normal C struct with one
exception:
\begin{center}
\rule{9cm}{2mm}
\end{center}
\leftline{{\huge Rule 1}}
The first item in a SICS object data structure MUST be a pointer to a
ObjectDescriptor data structure. This looks like:
\begin{verbatim}
typedef struct __MyObject {
pObjectDescriptor pDes;
int iMyExtremlyImportantInt;
.
.
.
} MyObject;
\end{verbatim}
\begin{center}
\rule{9cm}{2mm}
\end{center}
Otherwise the SICS server will crash on you sooner or later. The reason for
this is that SICS needs a means to identify a object and its capabilities
from inside its code. For example a user has typed: {\em drive mot1 26} into
the server. Now drive needs to verify that mot1 is really a motor or
something else which can be driven. This can be done in the following way:
\begin{enumerate}
\item First find the object in the SICS interpreter
(function FindCommand, SCinter.h).
\item Get the pointer to the objects data structure.
\item Assign this pointer to a dummy data structure (defined in obdes.h)
which has a pointer to the ObjectDescriptor as single element.
\item Ask the ObjectDescriptor if the object can be driven.
\end{enumerate}
In object speak this is called run time type information (RTTI).
It is interesting to look at the object descriptor in more detail. It is
again a data structure and a good example for polymorphism:
\begin{verbatim}
typedef struct {
char *name;
int (*SaveStatus)(void *self, char *name,FILE *fd);
void *(*GetInterface)(void *self, int iInterfaceID);
} ObjectDescriptor, *pObjectDescriptor;
\end{verbatim}
The first field contains a string defining a type name. The next field is a
pointer to a save function. This function is automatically called for all objects
in the SICS interpreter when the server shuts down. This function is supposed to
write all SICS commands necessary to reconfigure the object back into its current state
into file fd. The middle parameter is the name of the object in the interpreter
which must not necessarily be known to the object.
The next field, a pointer to a function GetInterface is used in order to inquire
the capabilities of an object. Object capabilities in SICS are defined in terms of
{\bf {\Large Interfaces}}. An Interface in the SICS sense is again a data structure
which contains data fields and pointers to functions implementing the capability. As
an example see the Drivable interface which is implemented by motors, environment
devices and variables such as lambda which can be driven to a new value:
\begin{verbatim}
typedef struct {
int ID;
int (*Halt)(void *self);
int (*CheckLimits)(void *self, float fVal,
char *error, int iErrLen);
long (*SetValue)(void *self, SConnection *pCon,
float fVal);
int (*CheckStatus)(void *self, SConnection *pCon);
float (*GetValue)(void *self, SConnection *pCon);
} IDrivable, *pIDrivable;
\end{verbatim}
Each SICS interface is identified by an integer ID number (defined in interface.h).
GetInterface returns a pointer to an interface data structure for an ID if the object
implements that interface. If not a NULL is returned.
\section{SICS Interfaces}\label{gow}
Thus SICS interfaces define the capabilities of an object. The concept of
Interfaces is similar to interfaces in the Java programming language
or abstract base classes in C++ or other object oriented languages.
As can be seen from the example
given above, the interface implements the most common operations on an object with
capabilities as defined by the interface. Currently, SICS knows four different kinds of
Interfaces:
\begin{description}
\item[Drivable] The Drivable interface for objects such as motors, adjustable parameters
and the like. Anything which can be driven to a value.
\item[Countable] The Countable interface used for everything which can count: single
counters, histogram memories or whatever may creep up.
\item[CallBack] The CallBack interface introduces some component programming techniques
into SICS. This technique lets an object, name it object A, issue events when its internal
state changes. For example if object A is a motor, any time it drives to a new value
an event is issued. Then another object, name it object B, can register an interest in
such events with object A. It does so by giving A the address of a function to call
when such an event occurs. A now calls all functions thus registered when the event
occurs. Object B thus gets automatically notified when A changes its state. Currently
this scheme is only used for implementing automatic notifications of clients when a
SICS object changes its state. But there is a lot of potential in this scheme.
\item[Environment] The Environment device is a interface implemented by all devices which
need to be regularly monitored by the environment monitor.
\end{description}
For more details about the SICS interfaces see the reference section: \ref{interref}.
The list of SICS interfaces can be extended when a novel abstract capability of an object
is needed. This is also the main reason why this sophisticated scheme was chosen.
The question may arise how to use SICS interfaces. For example consider an object defining
a drivable variable. The following steps are necessary:
\begin{enumerate}
\item Define functions with matching parameters to the ones requested by the interface.
Tip: the first parameter, the pointer to void, is always the pointer to the object data
structure to operate on. These functions must implement appropriate actions. What these
are: see the documentation of the interface.
\item Define a GetInterface function which returns a suitable interface
data structure when asked for an interface with the Drivable ID. The fields of the interface
structure returned must be set to the addresses of the functions you defined in step 1.
\item Create an object initialization function.
\item In this object initialization function: assign the object descriptors filed GetInterface
to the address of your GetInterface function.
\end{enumerate}
Usually, the interfaces an object implements are made a field in the objects data
structure. This interface is then initialized with appropriate function pointers when
creating the object. GetInterface then returns this pointer when the interface is
requested. Due to this usage a rule exits:
\begin{center}
\rule{9cm}{2mm}
\end{center}
\leftline{{\huge Rule 2}}
Any interface data structure provided by an object belongs to the object providing
it. The owner object is responsible for deleting it. Never free an interface data structure
provided by another object.
\begin{center}
\rule{9cm}{2mm}
\end{center}
Note, that the SICS interfaces are not the only interfaces to take care of. As SICS uses
this duality between logical hardware objects and hardware drivers, the interfaces defined
by the logical hardware devices can been seen as yet another internal interface. This leads to:
\begin{center}
\rule{9cm}{2mm}
\end{center}
\leftline{{\huge Recommendation}}
Watch your neighbors! Use the interfaces provided by the logical hardware objects for
your objects business, when applicable.
\begin{center}
\rule{9cm}{2mm}
\end{center}
\section{The Object Deletion Function}
When the SICS server exits or when a command is removed from the SICS
interpreter the interpreter will call a function which should free the memory
associated with the deleted object. This is absolutely necessary in order to
prevent memory leakage. Such a function has the form:
\begin{verbatim}
void ObjectKiller(void *pData);
\end{verbatim}
with pData being the pointer to the object to delete.
\section{Writing Object Functions}
The rules specified in this section apply to all kinds of object functions:
those which implement functionality as well as the object wrapper
functions. Please note, that any SICS object has two interfaces: an internal
C--language interface and a user visible interface defined by the object
wrapper functions. There are reasons why those two interfaces might not
provide equivalent functionality.
\subsection{Input and OutPut}
\begin{center}
\rule{9cm}{2mm}
\end{center}
\leftline{{\huge Rule 3}}
All input and output to the client executing the command must go through the
connection object functions SCWrite and SCPrompt.
\begin{center}
\rule{9cm}{2mm}
\end{center}
These function will now be inspected in more detail:
\begin{verbatim}
int SCWrite(SConnection *pCon, char *pText, int eCode);
int SCPrompt(SConnection *pCon, char *pPrompt, char *pBuffer, int iBufLen);
\end{verbatim}
SCWrite writes the data pText to the connection specified by pCon. The
parameter eCode denotes the output code of the data in pText. SICS clients
can choose to suppress some I/O from the SICS server. For instance a
GUI--client might chooses not to receive scan status reports. For this
purpose it was necessary to stick an output code onto each message to the
client. Possible output codes are: eError, eWarning, eValue, eStatus and
some internal codes. The names are self explaining. eValue denotes a value
which has been explicitly asked for by the client. The rule specified above
becomes understandable and thus bearable when looking at all the things
SCWrite does with the message:
\begin{itemize}
\item It is written to the client connection socket, subject to the output
code specified.
\item The message is written to all log files configured for the client
connection.
\item The message is written to the server log together with the socket
number of the connection.
\item SCWrite stores the message into the Tcl macro interpreter in order to
enable processing of data from SICS commands in Tcl scripts.
\item SCWrite suppresses all messages to the client while executing a macro.
This stops spurious output to appear at the client connection when running a
command defined in the macro language. The exception are messages of type
eError and eWarning. Such messages are always sent to the client.
\end{itemize}
SCPrompt prompts the user at the client connection for data. The prompt
string pPrompt is sent. Data entered by the user is returned in buffer
pBuffer. Maximum iBufLen character are returned. While waiting for client to
provide data, the SICS task switcher runs.
There is another convenience function SCSendOK(SConnection *pCon) which is
just a wrapper around SCWrite. SCSendOk sends an 'OK' to the client. It is good
practice to let the user know that the operation requested had been
performed.
Given the rule stated above, it follows that connection objects have to
be passed through the system to nearly everywhere. Especially where
reportable errors are found.
All other I/O, for instance to files sitting at the computer running the
SICS server, is not subjected to Rule 3.
\subsection{Error Handling}
Error handling is two thirds of the code written. Errors can be caused by
faulty users or faulty hardware. In any case, the first thing to do is:
report it using SCWrite! The next thing is to get the system into a state
that it can continue execution. This is particularly important for a server
program which might run for months on end. This means, free all memory used
before the error occurred, get system variables into safe values and the
like.
Sometimes error conditions arise in lower level code which should cause all
upper level code to finish execution. Such conditions may be the result of a
critical hardware fault or may even be requested by a user who wants to
abort an operation. A standard method for communicating such conditions
through the system is necessary. SICS uses interrupts for such conditions.
The current interrupt active interrupt is located at the connection object
and can be retrieved with {\bf SCGetInterrupt} and set with {\bf
SCSetInterrupt}. Interrupt codes are defined in interrupt.h and are ordered
into a hierarchy:
\begin{description}
\item[eContinue] Everything is just fine.
\item[eAbortOperation] Stop the current scan point or whatever is done,
but do not stop altogether.
\item[eAbortScan] Abort the current scan, but continue processing of further
commands in R\"unbuffers or command files.
\item[eAbortBatch] Aborts everything, operations, scans and batch processing
and leaves the system ready to enter new commands.
\item[eHaltSystem] As eAbortBatch, but lock the system.
\item[eFreeSystem] Unlocks a system halted with eHaltSystem.
\item[eEndServer] Makes the SICS server run down and exit.
For internal usage only.
\end{description}
In most cases interrupts shall only effect the client connection executing
the command. In such cases user code should use SCSetInterrupt in order to
set an interrupt at the connection executing the command only. Very rarely
conditions occur when an interrupt should affect the whole system. Then
SetInterrupt (defined in intserv.h) should be used. SetInterrupt forwards
the interrupt to all running tasks.
Objects implementing higher level commands such as scan commands might be
able to handle interrupt conditions and thus consume an interrupt. Then the
interrupt must be released with SCSetInterrupt and setting the interrupt to
eContinue. The interrupt on a connection will automatically be set to
eContinue when executing a new command from the command stack.
Objects are responsible for checking for interrupt conditions when
applicable. This is specially true for objects performing complex or
lengthy
operations with hardware. Whenever a hardware operation finishes, the
interrupt must be checked for and handled. The called hardware object or
the user might have set an interrupt which needs to be honored.
Thus two new rules can be defined:
\begin{center}
\rule{9cm}{2mm}
\end{center}
\leftline{{\huge Rule 4}}
Signal critical error conditions with interrupts.
\begin{center}
\rule{9cm}{2mm}
\end{center}
\begin{center}
\rule{9cm}{2mm}
\end{center}
\leftline{{\huge Rule 5}}
Check for pending interrupts wherever applicable.
\begin{center}
\rule{9cm}{2mm}
\end{center}
\subsection{Authorisation}
Objects are also responsible for checking if the client requesting an
operation may actually perform the operation. There are two cases when an
operation may be forbidden:
\begin{itemize}
\item The user is not suitably authorized.
\item The user is about to change critical parameters affecting a running
measurement.
\end{itemize}
Both conditions must be checked for by the objects code. Where else then at
the object can be known which operations are critical or not? This gives a
new rule:
\begin{center}
\rule{9cm}{2mm}
\end{center}
\leftline{{\huge Rule 6}}
Objects have to check authorisation!
\begin{center}
\rule{9cm}{2mm}
\end{center}
The user rights code for a client connection can be retrieved with
SCGetRights. SCGetGrab finds out if a connection has the control token.
A match with a value can be checked for with SCMatchRights which
returns true (1) if the connection has a user rights equal or higher then the
one necessary. SCMatchRights also checks for the status of the control token
and prints messages. SCMatchRights is the recommended function for checking
access rights in SICS.
An object can find out if some hardware operation is running by calling
the function isInRunMode prototyped in devexec.h.
An object can find out, if it is executing in a macro by calling SCinMacro.
Might be useful if the code is dependent on this condition. Usually all
details associated with running in a macro are dealt with by the system.
\subsection{Driving Hardware}
\begin{center}
\rule{9cm}{2mm}
\end{center}
\leftline{{\huge Rule 7}}
Use the device executor!
\begin{center}
\rule{9cm}{2mm}
\end{center}
With respect to hardware, there are two different kinds of objects in SICS:
some objects represent hardware. Examples are motors, counters. This group
also includes drivable variables which implement coordinated movements of
hardware. Such objects have to implement the necessary interfaces: either
the drivable or the countable interface. The second class are objects which
implement commands which use the hardware. For instance a drive command.
This second class of commands has to find the necessary hardware objects and
then run the actual hardware through the device executor. The function to
use is StartDevice or its derivatives, prototyped in devexec.h. After this
is done, there are tow options. In a scan command it might be needed to wait for
the hardware to finish before continuing your code. In this case use
function TaskWait, prototyped in tasker.h.
In other cases execution of the function may just
continue. The device executor will the take care of the task of monitoring
the hardware operation. The following code snippet gives an example how to
start a counter properly and wait for it to finish:
\begin{verbatim}
/*-------------- count */
pDum = (pDummy)self->pCounterData;
iRet = StartDevice(pServ->pExecutor, /* the executor, from global pServ */
"ScanCounter", /* a name */
pDum->pDescriptor, /* the descriptor of the cter */
self->pCounterData, /* pointer to counter data */
self->pCon, /* pointer to connection object */
self->fPreset); /* count preset */
if(!iRet)
{
SCWrite(self->pCon,"ERROR: Cannot Count, Scan aborted",eError);
return 0;
}
/* wait for finish */
lTask = GetDevexecID(pServ->pExecutor); /* get ID of device
executor task */
if(lTask > 0);
{
TaskWait(pServ->pTasker,lTask);
}
/* finished, check for interrupts. Whatever happened, user
interrupt or HW interrupt, it will be on our connection
*/
iInt = SCGetInterrupt(self->pCon);
switch(iInt)
{
case eContinue:
break;
case eAbortOperation:
continue;
break;
case eAbortScan:
SCWrite(self->pCon,"ERROR: Scan aborted",eError);
/* eat the interrupt, the requested op has been
done
*/
SCSetInterrupt(self->pCon,eContinue);
return 0;
break;
default: /* all others */
SCWrite(self->pCon,"ERROR: Scan aborted",eError);
return 0;
break;
}
\end{verbatim}
The above code (taken from the implementation of the scan command) also
shows an example for handling interrupts as a followup to running hardware.
Such a procedure is highly recommended.
\subsection{Working with the CallBack Interface}
Working with the callback interface is usually simple: just use the
functions as defined in interface.h. Add new event codes to event.h, in
order to make them known. A problem arises if an object which has callbacks
registered with other objects gets deleted. For the following discussion:
let us denote the object registering the callback as the client object and
the object which generates the event (where the callback was registered) as
source object. A typical example for a client is a
connection object which had configured itself to be automatically notified
of motor movements, variable changes and the like. Typically this is a
status display client. In such cases the client object has to keep
track of the callbacks it registered and delete them when the client objects gets
deleted. Otherwise the source object would invoke a callback on an non
existing client object. This usually results in a lovely core dump. For the
connection object this is taken care of automatically. The only thing needed
to be done, is to register the callback on the connection object with
SCRegister prototyped in conman.h. If user codes removes a callback later on,
it may call SCUnregister on the connection object to remove it from the
connection objects callback database as well. All registered callback will
be properly removed when the connection object is deleted.
\begin{center}
\rule{9cm}{2mm}
\end{center}
\leftline{{\huge Rule 8}}
Remove registered callbacks when deleting an object. For connection objects:
register your callbacks!
\begin{center}
\rule{9cm}{2mm}
\end{center}
\section{The Object Wrapper Function}
The object wrapper function makes the SICS object visible as a command in
the interpreter. It has to analyze parameters given to the command and act
accordingly. The object wrapper function has the following form:
\begin{verbatim}
int ObjectWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
\end{verbatim}
The parameters are:
\begin{itemize}
\item A pointer to the connection object and the client invoking the command.
\item A pointer to the SICS interpreter in which the command was executed.
As the interpreter also doubles as a database for objects it is often needed
to locate other objects.
\item A pointer to the objects data structure (pData).
\item The number of arguments specified to the command.
\item The text of the arguments specified. \verb+argv[0]+ is the name of the
command invoked. The argc, \verb+argv[]+ are almost the same as the argc,
\verb+argv[]+ pair given to a C main program.
\end{itemize}
In order to give the macro interpreter a hint if things are okay, the object
wrapper function has to return 1 for success and 0 if it fails. The rules
stated above for normal object functions apply.
\section{The Object Creation Function}
The object creation function has the same form as the object wrapper
function. Its purpose is to analyze parameters and to create the requested
object from them. In the end the object creation function will probably
create a new command in the SICS interpreter. The function to do this is the
AddCommand function. The prototype for AddCommand looks like this:
\begin{verbatim}
int AddCommand(SicsInterp *pSics,
char *name,
ObjectFunc pObFunc,
KillFunc pKill,
void *pData);
\end{verbatim}
The parameters are:
\begin{itemize}
\item A pointer to the SICS interpreter into which the new command shall be
installed.
\item The name of the new command.
\item The object function implementing the command.
\item An optional function which is able to remove the object data structure
given as last parameter from memory. This is mandatory for any object with
an own data structure.
\item A pointer to the object data structure.
\end{itemize}
\section{Writing Data}
For simple ASCII files at instruments doing scans, see the SICS manager
documentation for the template file description. Other instruments should
use the NeXus data format. Especially the NXDICT implementation. For more
documentation see the napi and nxdict documents. An example for using NXDICT
is given in the file nxsans.c.
\section{Hardware Objects}
\begin{center}
\rule{9cm}{2mm}
\end{center}
\leftline{{\huge Rule 9}}
Obey the division between driver code and logical object for hardware
objects.
\begin{center}
\rule{9cm}{2mm}
\end{center}
The concept of separating a hardware object in two components: a driver
which implements primitive operations and a logical object with which SICS
interacts internally has proven very valuable. First of all two drivers are
needed anyway: a simulation driver for simulating hardware and a
driver for the real hardware. Simulating hardware proved invaluable for
debugging of higher level code and can be used later on for testing command
files.
Please note that sample environment devices are handled slightly
differently. There exists a more general sample environment object which
handles many aspects of such a device. If the logical interface provided by
this general sample environment objects suffices, a new sample environment
device requires just a new driver. If the sample environment needs some
specials the study the relationship between the itc4 object and the general sample
environment object. Basically such a derived object implements in its
functions just the specials and calls the appropriate functions of the
general environment device object at the end. This is a simple form of
inheritance by delegation. This scheme has been devised in order to reduce
the need for code duplication when introducing new environment devices. For
more details see the reference section on environment devices.
\section{Examples}
For a deeper understanding of the concepts explained above it may help to
look at some source code. A nice example for the whole SICS object setup
including a callback interface is the implementation of the SICS variables
in files sicsvar.h and sicvar.c. For the implementation of a hardware object
including a drivable interface, the code in motor.h, motor.c and the motor
drivers: simdriv.c, el734dc.c and el734driv.c may be a suitable example. The
motor object creation function also shows how to handle multiple drivers for
a logical object.
SICS knows a omega-two-theta variable o2t. This variable coordinates two
motors in a way that the second motor has exactly the double value of the
first. This was meant to implement a omega-two-theta scan. Anyway, o2t is
a good example for implementing a drivable interface and how to handle such
coordinated movements. An example for the implementation of a countable
interface can be found in counter.h, counter.c for a single counter.
\section{Documentation}
If a new object has been defined two documentation files should be provided:
\begin{itemize}
\item A html file which describes the user interface to the object.
\item A latex file which describes the data structures used to implement the
object, the interface to the object and as much internal knowledge about the
working of the object as you care to provide. Being generous with
information helps maintaining the code later on!
\end{itemize}
Furthermore it is required to update the SICS managers documentation so that
the object creation function is known.
\section{Introducing a new Hardware Driver}
A new hardware driver for an existing objects can be introduced into the
system with the following two steps:
\begin{itemize}
\item Write the new driver. Use an existing driver as template.
\item Locate the objects factory function. Modify it so that it knows about
the new driver and how to initialise it.
\item Depending of the implementation of the object, the object deletion
function may need to know about the new driver as well in order to delete it
properly.
\end{itemize}
Do not forget to update the SICS manager documentation to include the new
driver!
\section{Coding Considerations}
The header file {\em sics.h} includes all the SICS kernel header files in
the right order. It is recommended to include sics.h at the top of
your implementation file.
A server program has to run for times on end. Thus a server program is more
sensitive than any other program to memory leakage or memory overwrites.
Therefore the current SICS implementation utilizes a memory debugging tool
called fortify. It is highly recommended to include fortify.h into your
implementation file in order to enable memory debugging. More information
about the inner working and usage of fortify can be found in the file fortify.doc in
the sics source code directory. Fortify has given some false alarms already
but it also helped to eliminate a couple of nasty problems at a very early
stage. A nasty feature of fortify is that its header file, fortify.h, has
to be included in ALL relevant source files. Otherwise nasty pseudo bugs
creep up when fortify is enabled. Please note, that fortify is only enabled
when all source files have been compiled with the flag -DFORTIFY. Otherwise
fortify compiles to nothing. More information about fortify can be found in
file fortify.h.
Names in the SICS source code are often made up along the following pattern:
\begin{itemize}
\item Use the full name of the thing or sensible and command abbreviations.
Write the variable as one word, with word boundaries being marked by capital
letters.
\item Most variables are prefixed with a letter denoting type. Letters used
are:
\begin{itemize}
\item p for pointer.
\item i for integer.
\item f for float.
\item d for double.
\item l for long.
\item s for struct.
\end{itemize}
Combinations of letters are also possible.
\end{itemize}
Some more general data structure implementations are used in SICS: There is
a general linked list package from a dutch men documented in lld.h. There is
a dynamical array in dynar.* and a parameter array in obpar.*.

194
doc/programmer/optimise.tex Normal file
View File

@ -0,0 +1,194 @@
\subsection{Optimise}
In instrument control the need arises to optimise a peak with respect to
several variables. This is usually the case during instrument calibration.
Four circle diffractometers however use this facility on a day to day basis
for finding and verifying the exact position of reflections. In order to
support both usages a more general module has been implemented. The way of
operation is like this:
\begin{verbatim}
while errors > precision and cycles < maxcycles
for all variables treated
do a scan
Try find the maximum, two halfwidth points and the peak center.
if failure extend the scan.
if success shift the variable, remember last shift.
If shift < precicison mark this variable as done
end for
end while
\end{verbatim}
Possible outcomes of this procedure are: success, the peak was lost or the
maximum number of cycles was reached. This routine requires that the
instrument is currently placed somewhere on the peak and not miles away.
In order to use this scheme some general control variables are required:
\begin{description}
\item[iMaxCycles] The maximum number of cycles to run.
\item[lThreshold] A threshold value used when determining if the peak was
lost.
\item[eMode] The counter mode to count in.
\item[fPreset] The preset to use when counting.
\item[iChannel] The channel to use as signal when counting. This is to
support this technique on a monitor rather then with a counter. Useful for
calibration.
\end{description}
For each variable to optimise we have to hold the following items:
\begin{description}
\item[name] Variable name.
\item[fStep] The step size to use for scanning
\item[nStep] The number of steps to go in each direction by default. This
parameter and the step size should together encompass somewhat more then the
width of the peak.
\item[fPrecision] The precision required or expected for this variable.
\item[fShift] The shift necessary for the last variable.
\end{description}
Of this the user is required to enter: name, fStep, nStep and fPrecision.
For some of its work, this module relies on the scan object (scan.*) and the
fitcenter object (fitcenter.*).
Internally the optimiser uses the following data structures:
\begin{verbatim}
typedef struct {
char *pName;
float fStep;
int iStep;
float fPrecision;
float fCenter;
float fShift;
pIDrivable pDriv;
void *pData;
int iLost;
} OVarEntry, *pOVarEntry;
\end{verbatim}
This is the data structure for each variable to optimise during an
optimser run. The fields are:
\begin{description}
\item[pName] the name of the variable.
\item[fStep] The step width to use for scanning the variable.
\item[fPrecision] The precision required for this variable. Used to
mark this variable OK if the last shift is less then this precision
value.
\item[fCenter] The calculated center of this variable.
\item[fShift] The last shift calculated for this variable.
\item[pDriv] A pointer to the drivable interface of this variable.
\item[pData] A pointer to this variables data structure.
\item[iLost] A flag which marks if the peak has been lost with respect
to this variable.
\end{description}
The optimiser itself uses the following data structure:
\begin{verbatim}
typedef struct __OptimiseStruct {
pObjectDescriptor pDes;
int iMaxCycles;
CounterMode eCount;
float fPreset;
int iChannel;
float fThreshold;
int iVar;
pDynar pVariables;
pScanData pScanner;
pFit pPeakFitter;
} Optimiser;
\end{verbatim}
The fields are:
\begin{description}
\item[pDes]The usual object descriptor.
\item[iMaxCycles] The maximum number of cycles to perform.
\item[eCount] The countmode to use for scanning.
\item[fPreset] The preset to use for scanning.
\item[iChannel] The channel to use for scanning.
\item[fThreshold] The threshold to use for identifying lost peaks.
\item[iVar] The number of variables to optimise.
\item[pVariables] A dynamic array of variables to optimise.
\item[pScanner] The scan object to use for scanning.
\item[pFit] The peak center determination object to use.
\end{description}
The interface to this object looks like this:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap1}
\verb@"optimise.h"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*-------------------------------------------------------------------------@\\
\mbox{}\verb@ O P T I M I S E@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Optimise a peak with respect to several variables.@\\
\mbox{}\verb@@\\
\mbox{}\verb@ copyright: see copyright.h@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Mark Koennecke, March 1998-1999@\\
\mbox{}\verb@-----------------------------------------------------------------------------*/@\\
\mbox{}\verb@#ifndef SICSOPTIMISE@\\
\mbox{}\verb@#define SICSOPTIMISE@\\
\mbox{}\verb@@\\
\mbox{}\verb@ typedef struct __OptimiseStruct *pOptimise;@\\
\mbox{}\verb@@\\
\mbox{}\verb@/*------------------- live & death -----------------------------------------*/@\\
\mbox{}\verb@ pOptimise CreateOptimiser(pCounter pCount);@\\
\mbox{}\verb@ void DeleteOptimiser(void *pData);@\\
\mbox{}\verb@ int MakeOptimiser(SConnection *pCon, SicsInterp *pSics,@\\
\mbox{}\verb@ void *pData, int argc, char *argv[]);@\\
\mbox{}\verb@/*------------------- operation -------------------------------------------*/@\\
\mbox{}\verb@#define PEAKLOST -1@\\
\mbox{}\verb@#define MAXCYCLE -2@\\
\mbox{}\verb@#define SCANERROR -3@\\
\mbox{}\verb@#define SCANABORT -4@\\
\mbox{}\verb@#define SYSERROR -5@\\
\mbox{}\verb@#define DRIVEERROR -6@\\
\mbox{}\verb@@\\
\mbox{}\verb@ void OptimiserClear(pOptimise self);@\\
\mbox{}\verb@ int OptimiserAdd(pOptimise self,@\\
\mbox{}\verb@ char *pVarName, @\\
\mbox{}\verb@ float fStep, @\\
\mbox{}\verb@ int nStep, @\\
\mbox{}\verb@ float fPrecision);@\\
\mbox{}\verb@ int OptimiserSetPar(pOptimise self, char *name, float fVal);@\\
\mbox{}\verb@ int OptimiserGetPar(pOptimise self, char *name, float *fVal);@\\
\mbox{}\verb@@\\
\mbox{}\verb@ int OptimiserRun(pOptimise self, SConnection *pCon); @\\
\mbox{}\verb@@\\
\mbox{}\verb@ int OptimiserAction(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@#endif@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}
All functions except the installation functions take a pointer to the
optimiser structure as first parameter. The function reference:
\begin{description}
\item[CreateOptimiser] creates an optimiser object. Takes a pointer to
a counter object as a parameter. Returns a pointer to a nice and good
optimiser object on return. Or NULL, if there was some sort of
problem.
\item[DeleteOptimiser] is the deletion function used in the
interpreter for properly removing the optimiser object from the
system.
\item[MakeOptimiser] is the installation function which configures an
optimiser into SICS.
\item[OptimiserClear] removes all configured optimisation variables
and all remnants of a previous optimiser run.
\item[OptimiserAdd] adds a variable to be optimised. Parameter to this
call are: pVarName, the name of the variable to optimise, fStep, the
step width to use for scanning, nStep, the initial number of steps to
use for scanning, fPrecision, the precision to achive for this
variable.
\item[OptimiserSetPar] sets the configuration parameters for the
optimiser. The parameter name is the same name as stated in the
command reference.
\item[OptimiserGetPar] retrieves the value of a configuration
parameters for the
optimiser. The parameter name is the same name as stated in the
command reference.
\item[OptimiserRun] starts the optimser run with the current
parameters. Output is sent to the connection pCon.
\item[OptimiserAction] is the interpreter interface function for the
optimiser.
\end{description}

437
doc/programmer/overview.tex Normal file
View File

@ -0,0 +1,437 @@
\chapter{SICS Overview}
\section{Introduction}
At the new spallation source SINQ at PSI a whole set of new neutron
scattering instruments are being installed. All these new instruments need a
computer instrument control control system. After a review of similar systems
out in the market it was found that none fully met the requirements defined
for SINQ or could easily be extended to do so. Therefore it was decided to
design a new system. This new system SICS, the SINQ Instrument Control
System, had to meet the following specifications:
\begin{itemize}
\item Control the instrument reliably.
\item Good remote access to the instrument via the internet.
\item Portability across operating system platforms.
\item Enhanced portability across instrument hardware. This means that it
should be easy to add other types of motors, counters or other hardware to
the system.
\item Support authorization on the command and variable level. This means
that certain instrument settings can be protected against random changes by
less knowledgable users.
\item Good maintainability and extendability.
\item Be capable to acomodate graphical user interfaces (GUI).
\item One code base for all instruments.
\item Powerful macro language.
\end{itemize}
A suitable new system was implemented using an object oriented design which
matches the above criteria.
\section{The SINQ Hardware Setup}
SICS had to take in account the SINQ hardware setup which had been decided
upon earlier on. Most hardware such as motors and counters is controlled via
RS--232 interfaces. These devices connect to a Macintosh PC which has a
terminal server program running on it. This terminal server program collects
request to the hardware from a TCP/IP port and forwards them to the serial
device. The instrument control program runs on a workstation running
DigitalUnix. Communication with the hardware happens via TCP/IP through the
terminal server. Some hardware devices, such as the histogram memory, can handle
TCP/IP themselves. With such devices the instrument control program
communicates directly through TCP/IP, without a terminal server. All
hardware devices take care of their real time needs themselves. Thus the
only task of the instrument control program is to orchestrate the hardware
devices. SICS is designed with this setup up in mind, but is not restricted
to this setup. A schematic view of this setup is given in picture
\ref{hard}.
\begin{figure}
%% \epsfxsize=0.65\textwidth
\epsfxsize=160mm
\epsffile{hart.eps}
\caption{Instrument control hardware setup at SINQ}\label{hard}
\end{figure}
\section{SICS Overall Design}
In order to achieve the design goals stated above it was decided to divide
the system into a client server system. This means that there are at least
two programs necessary to run an instrument: a client program and a server
program. The server program, the SICS server, does all the work and
implements the actual instrument control. The SICS server usually runs on
the DAQ computer. The client program may run on any computer on the world
and implements the user interface to the instrument. Any numbers of clients
can communicate with one SICS server. The SICS server and the clients
communicate via a simple ASCII command protocol through TCP/IP sockets.
With this design good remote control through the network is easily achieved.
As clients can be implemented in any language or system capable of handling
TCP/IP the user interface and the functional aspect are well separated. This
allows for easy exchange of user interfaces by writing new clients.
\section{SICS Clients}
SICS Clients implement the SICS user interface. Current client
programs are mostly implemented in Java for platform independence.
This is a real concern at SINQ where VMS,
Intel-PC, Macintosh and Unix users have to be satisfied.
As many instrument scientists still prefer
the command line for interacting with instruments, the most used client is a
visual command line client. Status displays are another sort of specialized
client programs. Graphical user interfaces are under consideration for some
instruments. As an example for a client a screen shot of the status display
client for a powder diffractometer is given in picture \ref{dmc}
\ref{hard}.
\begin{figure}
%% \epsfxsize=0.65\textwidth
\epsfxsize=160mm
%% \epsffile{dmc.eps}
\caption{Example for a SICS client: Powder Diffractometer Status Display}\label{dmc}
\end{figure}
\section{The SICS Server}
The SICS server is the core component of the SICS system. The SICS server is
responsible for doing all the work in instrument control. Additionally the
server has to answer the requests of possibly multiple clients.
The SICS server can be subdivided into three subsystems: The kernel, a database
of SICS objects and an interpreter. The SICS server kernel takes care of
client multitasking and the preservation of the proper I/O and error context
for each client command executing.
SICS objects are software modules which represent all aspects
of an instrument: hardware devices, commands, measurement strategies
and data storage. This database of objects is initialized at server startup
time from an initialization script. The third SICS server component is an
interpreter which allows to issue commands to the objects in the objects database.
The schematic drawing of the SICS server's structure is given in picture
\ref{newsics}.
\begin{figure}
%% \epsfxsize=0.65\textwidth
\epsfxsize=160mm
\epsffile{newsics.eps}
\caption{Schematic Representation of the SICS server's structure}\label{sicsnew}
\end{figure}
\subsection{The SICS Server Kernel}
In more detail the SICS server kernel has the following tasks:
\begin{itemize}
\item Accept and verify client connection requests.
\item Read and execute client commands.
\item Maintain the I/O and error context for each client connection.
\item Serialize data access.
\item Serialize hardware access.
\item Monitor HW--operations.
\item Monitor environment devices.
\end{itemize}
Any server serving multiple clients has the problem how to organize multiple
clients accessing the same server and how to stop one client reading data,
which another client is just writing. The approach used for the SICS server
is a combination of polling and cooperative multitasking. This scheme is
simple and can be implemented in an operating system independent manner. One
way to look at the SICS server is as a series of tasks in a circular queue
executing one after another. The servers main loop does nothing but
executing the tasks in this circular buffer in an endless loop.
There are several system tasks and one such
task for each living client connection. Thus only one task executes at any
given time and data access is efficiently serialized. One of the main system
tasks (and the one which will be always there) is the network reader. The
network reader has a list of open network connections and checks each of
them for pending requests. What happens when a data is pending on an open
network port depends on the type of port: If it is the servers main
connection port, the network reader will try to accept and verify a new
client connection and create the associated data structures. If the port
belongs to an open client connection the network reader will read the
command pending and put it onto a command stack existing for each client
connection. When it is time for a client task to execute, it will fetch a
command from its very own command stack and execute it. When the net reader
finds an user interrupt pending, the interrupt is executed.
This is how the SICS server deals with client requests.
The scheme described above relies on the fact that most SICS command need
only very little time to execute. A command needing time extensive
calculations may effectively block the server. Implementations of such
commands have to take care that control passes back to the task switching
loop at regular intervalls in order to prevent the server from blocking.
Another problem in a server handling multiple client requests is how to
maintain the proper execution context for each client. This includes the
clients I/O-context (socket), the authorisation of the client and possible
error conditions pending for a
client connection. SICS does this via a connection object, a special
data structure holding all the above information plus a set of functions
operating on this data structure. This connection object is passed along
with many calls throughout the whole system.
Multiple clients issuing commands to the SICS server may mean that multiple
clients might try to move motors or access other hardware in conflicting
ways. As there is only one set of instrument hardware this needs to be
prevented. This is achieved by a convention. No SICS object drives hardware
directly but registers it's request with a special object, the device
executor. This device executor starts the requested operation and reserves
the hardware for the length of the operation. During the execution of such
an hardware request all other clients requests to drive the hardware will
return an error. The device executor is also responsible for monitoring the
progress of an hardware operation. It does so by adding a special task into
the system which checks the status of the operation each time this tasks
executes. When the hardware operation is finished (one way or another) this
device executor task will end. A special system facility allows a client
task to wait for the device executor task to end while the rest of the task
queue is still executing. In this way time intensive hardware operations can
be performed by drive, count or scan commands without blocking the whole
system for other clients. \label{devexec}
The SICS server can be configured to support another security feature, the
token system. In this scheme a client can grab control of the instrument.
With the control token grabbed, only the client which has the token may
control the instrument. Any other client may look at things in the SICS server
but does not have permission to change anything. Passing the control token
requires that the client which has the token releases the token so that
another client may grab it. There exists a password protected back door for
SICS managers which allows to force the release of a control token.
Most experiments do not happen at ambient room conditions but
require some special environment for the sample. Mostly this is temperature
but it can also be magnetic of electric fields etc. Most of such devices
can regulate themselves but the data acquisition program needs to monitor
such devices. Within SICS this is done via a special system object, the
environment monitor. A environment device, for example a temperature
controller, registers it's presence with this object. Then an special system
task will control this device when it is executing, check for possible out
of range errors and initiates the proper error handling if such a problem is
encountered.
\subsection{The SICS Interpreter}
When a task belonging to a client connection executes a command it will pass
the command along with the connection object to the SICS interpreter. The
SICS interpreter will then analyze the command and forward it to the
appropriate SICS object in the object database for further action. The SICS
interpreter is very much modeled after the Tcl interpreter as devised by
John Ousterhout$^{1}$. For each SICS object visible from the interpreter there is
a wrapper function. Using the first word of the command as a key, the
interpreter will locate the objects wrapper function. If such a function is
found it is passed the command parameters, the interpreter object and the
connection object for further processing. An interface exists to add and
remove commands to this interpreter very easily. Thus the actual command
list can be configured easily to match the instrument in question, sometimes
even at run time. Given the closeness of the design of the SICS interpreter
to the Tcl interpreter, the reader may not be surprised to learn that the
SICS server incorporates Tcl as its internal macro language. The internal
macro language may use Tcl commands as well as SICS commands.
\subsection{SICS Objects}
As already said, SICS objects implement the true functionality of SICS
instrument control. All hardware, all commands and procedures, all data
handling strategies are implemented as SICS objects. Hardware objects, for
instance motors deserve some special attention. Such objects are divided
into two objects in the SICS system: A logical hardware object and a driver
object. The logical object is responsible for implementing all the nuts and
bolts of the hardware device, whereas the driver defines a set of primitive
operations on the device. The benefit of this scheme is twofold:
switching to new hardware, for instance a new type of motor, just requires
to incorporate a new driver into the system. Internally, independent from
the actual hardware, all hardware object of the same type (for example
motors) look the same and can be treated the same by higher level objects.
No need to rewrite a scan command because a motor changed.
In order to live happily within the SICS system SICS object have to adhere
to a system of protocols. There are protocols for:
\begin{itemize}
\item Input/Output to the client.
\item Error handling.
\item Interaction with the interpreter.
\item For identification of the object to the system at run time.
\item For interacting with hardware (see device executor above).
\item For checking the authorisation of the client who wants to execute the
command.
\end{itemize}
SICS uses NeXus$^{2}$, the upcoming standard for data exchange for neutron
and x\_ray scattering as its raw data format.
SICS objects have the ability to notify clients and other objects of
internal state changes. For example when a motor is driven, the motor object
can be configured to tell SICS clients or other SICS objects about his new
position.
\section{SICS Working Examples}
In order to get a better feeling for the internal working of SICS the course
of a few different requests through the SICS system is traced in this
section. The examples traced will be:
\begin{itemize}
\item A request for a new client connection.
\item A simple command.
\item A command to drive a motor in blocking mode.
\item A command to drive a motor which got interrupted by the user.
\item A command to drive a motor in non blocking mode.
\end{itemize}
For the whole discussion it is assumed that the main loop is running,
executing cyclically each single task registered in the server. Task switching is
done by a special system component, the task switcher.
\subsection{The Request for a new Client Connection}
\begin{itemize}
\item The network reader recognizes pending data on its main server port.
\item The network reader accepts the connection and tries to read a
username/password pair.
\item If such a username/password pair comes within a suitable time
intervals it is checked for validity. On failure the connection is closed
again.
\item If a valid connection has been found: A new connection object is
created, a new task for this client connection is introduced into the
system and the network reader registers a new client port to check for
pending commands.
\item Control is passed back to the task switcher.
\end{itemize}
\subsection{A Simple Command}
\begin{itemize}
\item The network reader finds data pending at one of the client ports.
\item The network reader reads the command, splits it into single lines and
put those on the top of the client connections command stack. The network
reader passes control to the task switcher.
\item In due time the client connection task executes, inspects its command
stack, pops the command pending and forwards it together with a pointer to
itself to the SICS interpreter.
\item The SICS interpreter inspects the first word of the command. Using
this key the interpreter finds the objects wrapper function and passes
control to that function.
\item The object wrapper function will check further arguments, checks the
clients authorisation if appropriate for the action requested. Depending on
the checks, the wrapper function will create an error message or do its
work.
\item This done, control passes back through the interpreter and the connection
task to the task switcher.
\item The next task executes.
\end{itemize}
\subsection{A Drive Command in Blocking Mode}
\begin{itemize}
\item The network reader finds data pending at one of the client ports.
\item The network reader reads the command, splits it into single lines and
put those on the top of the client connections command stack. The network
reader passes control to the task switcher.
\item In due time the client connection task executes, inspects its command
stack, pops the command pending and forwards it together with a pointer to
itself to the SICS interpreter.
\item The SICS interpreter inspects the first word of the command. Using
this key the interpreter finds the drive command wrapper function and passes
control to that function.
\item The drive command wrapper function will check further arguments,
checks the
clients authorisation if appropriate for the action requested. Depending on
the checks, the wrapper function will create an error message or do its
work.
\item Assuming everything is OK, the motor is located in the system.
\item The drive command wrapper function asks the device executor to run the
motor.
\item The device executor verifies that nobody else is driving, then starts
the motor and grabs hardware control. The device executor also starts a task
monitoring the activity of the motor.
\item The drive command wrapper function now enters a wait state. This means
the task switcher will execute other tasks, except the connection task
requesting the wait state. The client connection and task executing the drive command
will not be able to process further commands.
\item The device executor task will keep on monitoring the progress of the motor
driving whenever the task switcher allows it to execute.
\item In due time the device executor task will find that the motor finished
driving. The task will then die. The clients grab of the hardware driving
permission will be released.
\item At this stage the drive command wrapper function will awake and
continue execution. This means inspecting errors and reporting to the client
how things worked out.
\item This done, control passes back through the interpreter and the connection
task to the task switcher. The client connection is free to execute
other commands.
\item The next task executes.
\end{itemize}
\subsection{A Drive Command Interrupted}
\begin{itemize}
\item The network reader finds data pending at one of the client ports.
\item The network reader reads the command, splits it into single lines and
put those on the top of the client connections command stack. The network
reader passes control to the task switcher.
\item In due time the client connection task executes, inspects its command
stack, pops the command pending and forwards it together with a pointer to
itself to the SICS interpreter.
\item The SICS interpreter inspects the first word of the command. Using
this key the interpreter finds the drive command wrapper function and passes
control to that function.
\item The drive command wrapper function will check further arguments,
checks the
clients authorisation if appropriate for the action requested. Depending on
the checks, the wrapper function will create an error message or do its
work.
\item Assuming everything is OK, the motor is located in the system.
\item The drive command wrapper function asks the device executor to run the
motor.
\item The device executor verifies that nobody else is driving, then starts
the motor and grabs hardware control. The device executor also starts a task
monitoring the activity of the motor.
\item The drive command wrapper function now enters a wait state. This means
the task switcher will execute other tasks, except the connection task
requesting the wait state.
\item The device executor task will keep on monitoring the progress of the
driving of the motor when it is its turn to execute.
\item The network reader finds a user interrupt pending. The interrupt will
be forwarded to all tasks in the system.
\item In due time the device executor task will try to check on the progress
of the motor. It will recognize the interrupt. If appropriate the motor will
get a halt command. The task will then die.
The clients grab of the hardware driving permission will be released.
\item At this stage the drive command wrapper function will awake and
continue execution. This means it finds the interrupt, tells the user what he
already knows: an interrupt was issued.
\item This done, control passes back through drive command wrapper,
the interpreter and the connection
task to the task switcher.
\item The next task executes.
\end{itemize}
\subsection{A Run Command in Non Blocking Mode}
\begin{itemize}
\item The network reader finds data pending at one of the client ports.
\item The network reader reads the command, splits it into single lines and
put those on the top of the client connections command stack. The network
reader passes control to the task switcher.
\item In due time the client connection task executes, inspects its command
stack, pops the command pending and forwards it together with a pointer to
itself to the SICS interpreter.
\item The SICS interpreter inspects the first word of the command. Using
this key the interpreter finds the drive command wrapper function and passes
control to that function.
\item The run command wrapper function will check further arguments,
checks the
clients authorisation if appropriate for the action requested. Depending on
the checks, the wrapper function will create an error message or do its
work.
\item Assuming everything is OK, the motor is located in the system.
\item The drive command wrapper function asks the device executor to run the
motor.
\item The device executor verifies that nobody else is driving, then starts
the motor and grabs hardware control. The device executor also starts a task
monitoring the activity of the motor.
\item The run command wrapper function passes control through the interpreter and
the clients task function back to the task switcher. The client connection can handle
new commands.
\item The device executor task will keep on monitoring the progress of the motor
driving whenever the task switcher allows it to execute.
\item In due time the device executor task will find that the motor finished
driving. The task will then die silently. The clients grab of the hardware driving
permission will be released. If errors occurred, however a they will be reported.
\item At this stage the drive command wrapper function will awake and
continue execution. This means inspecting errors and reporting to the client
how things worked out.
\item This done, control passes back through the interpreter and the connection
task to the task switcher. The client connection is free to execute
other commands.
\item The next task executes.
\end{itemize}
All this seems to be pretty complex and time consuming. But it is the complexity needed to
do so many things, especially the non blocking mode of operation requested
by users. Tests have shown that the task switcher manages +900 cycles per second
through
the task list on a DigitalUnix machine and 50 cycles per second on a pentium 133mhz
machine running linux. Both data were obtained with software simulation of
hardware devices. With real SINQ hardware these numbers drop 4 cycles per
second. This shows clearly that the communication with the hardware is the
systems bottleneck and not the task switching scheme.

20
doc/programmer/passwd.tex Normal file
View File

@ -0,0 +1,20 @@
\subsection{The Password Database}
This is just a simple password database. It keeps for each user an
record containing username, password and an integer code. The code
is meant to encode the users rights within the system. On
initialisation the information is read from a file. Currently there
is no encryption in this. Rely on the filesytem protection mechanisms
for protecting passwords. Though SICS will have only a limited number
of different user levels, the password class is designed to cope with
more and stores its data in a linked list. Currently user names and
passwords are entered into the database through the SicsUser
initialization command.
The interface:\begin{itemize}
\item {\bf int InitPasswd(char *filename) } reads user data from the file specified. Returns True on success, false else.
\item {\bf void AddUser(char *name, char *passwd, int iCode) }, adds a new user to the database.
\item {\bf int IsValidUser(char *name, char *passwd) }, checks a users authorisation information. Returns a negative value if the user is invalid, the users rights code if he is valid.
\item {\bf void KillPasswd(void) }, deletes the password data structures, when it is no longer needed. Omission of this call will result in wasted memory.
\end{itemize}

119
doc/programmer/perfmon.tex Normal file
View File

@ -0,0 +1,119 @@
\subsection{Performance Monitor}
This object implements a performance monitor for SICS. Please note that SICS
performance is determined not only by processor speed but by a whole range
of factors:
\begin{itemize}
\item Processor speed and memory.
\item Speed of network connctions to hardware devices.
\item Number of clients connected.
\end{itemize}
The PerfMonTask is called from the SICS task modules main loop. It will then
increment a cycle counter and check if a predefined intergration time has
passed. If so a new
value for cycle per seconds will be calculated. This is also the main
output of PerfMon. PerfMon implements a callback interface in order to allow
automatical notification about system performance.
PerfMon has a little datastructure:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap1}
$\langle$pdata {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ typedef struct __PerfMon {@\\
\mbox{}\verb@ pObjectDescriptor pDes;@\\
\mbox{}\verb@ pICallBack pCall;@\\
\mbox{}\verb@ int iLog; /* flag for@\\
\mbox{}\verb@ serverlog writing */ @\\
\mbox{}\verb@ float fCPS; /* cycles per seconds */@\\
\mbox{}\verb@ int iInteg; /* integration time */@\\
\mbox{}\verb@ int iCount;@\\
\mbox{}\verb@ time_t tLast; /* last time calculated */@\\
\mbox{}\verb@ time_t tTarget; /* next target time */@\\
\mbox{}\verb@ int iEnd;@\\
\mbox{}\verb@ }PerfMon;@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
The interface consists of the following functions:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap2}
$\langle$pInter {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ typedef struct __PerfMon *pPerfMon;@\\
\mbox{}\verb@/*---------------------- live and death ----------------------------------*/@\\
\mbox{}\verb@ pPerfMon CreatePerfMon(int iInteg);@\\
\mbox{}\verb@ void DeletePerfMon(void *pData);@\\
\mbox{}\verb@/*---------------------- increment ---------------------------------------*/@\\
\mbox{}\verb@ int IncrementPerfMon(pPerfMon self);@\\
\mbox{}\verb@/*------------------------------------------------------------------------*/@\\
\mbox{}\verb@ float GetPerformance(pPerfMon self);@\\
\mbox{}\verb@/*------------------------------------------------------------------------*/@\\
\mbox{}\verb@ int PerfMonWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@/*-----------------------------------------------------------------------*/@\\
\mbox{}\verb@ int PerfMonTask(void *pPerf);@\\
\mbox{}\verb@ void PerfMonSignal(void *pPerf, int iSignal, void *pSigData); @\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
There is really not much to this.
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap3}
\verb@"perfmon.h"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*-------------------------------------------------------------------------@\\
\mbox{}\verb@ P E R F M O N@\\
\mbox{}\verb@ A performance monitor for SICS. Maintains and calculates a value for@\\
\mbox{}\verb@ cycles per seconds. @\\
\mbox{}\verb@@\\
\mbox{}\verb@ Mark Koennecke, Juli 1997@\\
\mbox{}\verb@@\\
\mbox{}\verb@ copyright: see implementation file@\\
\mbox{}\verb@---------------------------------------------------------------------------*/@\\
\mbox{}\verb@#ifndef SICSPERFMON@\\
\mbox{}\verb@#define SICSPERFMON@\\
\mbox{}\verb@@\\
\mbox{}\verb@@$\langle$pInter {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@#endif@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap4}
\verb@"perfmon.i"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*--------------------------------------------------------------------------@\\
\mbox{}\verb@ The P E R F M O N datastructure.@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Mark Koennecke, Juli 1997@\\
\mbox{}\verb@---------------------------------------------------------------------------*/@\\
\mbox{}\verb@@$\langle$pdata {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}

View File

@ -0,0 +1,67 @@
\subsubsection{Physik Instrumente DC-Motor Controller}
This is a mainly a driver for a C-804 DC-motor Controller as produced by the
Company Physik Instrumente. This controller drives up to four high precision
motors. These motors do not have reference points and have variable speeds.
Therefore some additional code is needed to handle motor specific commands.
This problem is solved by handling these specific additional commands in a
new wrapper routine which finally calls the main motor wrapper routine for
all the other commands. Of course, a special factory method is needed for
this device as well.
The public interface for this motor includes the following functions:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap1}
$\langle$pimoti {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@@\\
\mbox{}\verb@ int PIMotorWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@ int PIMotorFactory(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@@\\
\mbox{}\verb@ int PISetSpeed(pMotor self, SConnection *pCon, float fNew);@\\
\mbox{}\verb@ int PIGetSpeed(pMotor self, SConnection *pCon, float *fVal);@\\
\mbox{}\verb@@\\
\mbox{}\verb@ int PIHome(pMotor self, SConnection *pCon);@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap2}
\verb@"pimotor.h"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*--------------------------------------------------------------------------@\\
\mbox{}\verb@ P I M O T O R@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Driver and add on code for the Physik Instrument Motor Controller C-804.@\\
\mbox{}\verb@ @\\
\mbox{}\verb@ Mark Koennecke, September 1998@\\
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
\mbox{}\verb@#ifndef PIMOTOR@\\
\mbox{}\verb@#define PIMOTOR@\\
\mbox{}\verb@@$\langle$pimoti {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@#endif@\\
\mbox{}\verb@@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}
\subsubsection{Physik Instrument Piezo Controller E-255}
This is piezo translator. A voltage is set and it elongates. It is
handled as a motor because it is going to be scanned. A driver has
been implemented in the file pipiezo.c. For
the command protocoll, see the documentation coming with the gadget.

View File

@ -0,0 +1,47 @@
\chapter{SICS Programmers Reference}
This chapter is a boring listing of the interfaces and functions provided by
the SICS modules.
\section{Kernel Objects and Modules}
This section describes the objects and modules defining the SICS kernel.
\include{nserver}
\include{nread}
\include{nconman}
\include{emonitor}
\include{event}
\include{interface}
\include{devexec}
\include{perfmon}
\include{ini}
\include{inter}
\include{macro}
\include{network}
\include{passwd}
\section{SICS Objects}
This section describes the SICS objects implementing commands and hardware
objects.
\include{velo}
\include{velodorn}
\include{scan}
\include{evcontroller}
\include{center}
\include{danu}
\include{evcontroller}
\include{itc4}
\include{histogram}
\include{histsim}
\include{sinqhmdriv}
\include{nxdata}
\section{Helper Objects}
This section describes helper objects which implement useful data
structures or utilities.
\include{varlog}
\include{dynar}
\include{costa}
\include{stringdict}
\include{splitter}

View File

@ -0,0 +1,37 @@
% Copyleft (c) 1997-2000 by Mark Koennecke at PSI, Switzerland.
%
%
%
\documentclass[12pt]{report}
\usepackage{epsf}
\setlength{\oddsidemargin}{-.1in}
\setlength{\evensidemargin}{0in}
\setlength{\topmargin}{0in}
\addtolength{\topmargin}{-\headheight}
\addtolength{\topmargin}{-\headsep}
\setlength{\textheight}{8.9in}
\setlength{\textwidth}{6.2in}
\setlength{\marginparwidth}{0.5in}
\begin{document}
\title{The SICS Programmers Reference}
\author{Mark K\"onnecke\\
Labor f\"ur Neutronenstreuung\\
Paul Scherrer Institut\\
CH-5232 Villigen PSI\\
Switzerland\\
Mark.Koennecke@psi.ch \\
}
\maketitle
\tableofcontents
\include{overview}
\include{proto}
\include{kernelguide}
\include{oguide}
\end{document}

61
doc/programmer/proto.tex Normal file
View File

@ -0,0 +1,61 @@
\chapter{The SICS Server Client Protocol}
This short chapter describes the command protocol between the SICS server
and possible SICS clients. All this is very simple.
\section{Logging in to the SICS Server}
In order to log in to the SICS server it needs to be known on which
machine the server runs and at which port number the server listens for
connection requests. Also needed is a valid username/ password pair for the
SICS server in question. Given that the procedure for connecting to a SICS
server requires the following steps:
\begin{enumerate}
\item Open a TCP/IP connection to the SICS server port at the machine
where it is running.
\item Immediately after opening the connection send the username/password
pair. If everything is OK, a string OK is sent. Else the server will break
the connection again.
\end{enumerate}
\section{Sending Commands}
After login, two means of communications exist. The communication
protocoll is choosen through the server port the client connects too.
The recommended way is
to adhere to the telnet protocoll as described in RFC-854. Just a
basic NVT (Network Virtual Terminal) with no options is
implemented. Binary communication is not possible on a telnet port.
The older way of communication is to send commands directly on the
TCP/IP port. Commands are strings terminated by a \verb+\n+. Return
messages from the server have the same format. This scheme is
obsolete but it has been left in because the need for a binary
communication may arise and this would help implement such a thing.
For a list of possible commands consult the
user documentation.
\section{Issuing Interrupts}
In some cases a user might want to stop the operation of the server. In
order to do this the client must send an interrupt to the SICS server. There
are two ways to do this: through the normal connection socket and through
the a special UDP message to the server. Let us first discuss the first
method, which uses the normal command socket for sending an interrupt.
In order to send an interrupt through the normal command socket a special
message must be sent, consisting of a special command string. The command
string is again all ASCII. The first part of this command string must read:
INT1712, followed by a number denoting the interrupt. The meaning of these
numbers is resolved in file interrupt.h. For example, the string 'INT1712 2'
will abort the current scan. The presence of an interrupt string will be
checked for already by the network reader. This means that such interrupts
will even be honored when the client connection is waiting for some hardware
to finish its job and would not accept normal commands. \label{prot1}
The SICS server also checks a special TCP/IP port for UDP messages which
denote an interrupt. In order to send an interrupt through this channel, a
UDP connection to the SICS servers UDP port must be opened. Then an special
ASCII string of the form: {\bf SICSINT num} must be sent. num must be
replaced by the number of the interrupt to issue. Again interrupt codes are
resolved in file interrupt.h.

Some files were not shown because too many files have changed in this diff Show More