
This is our new RELEASE-4_0 branch which was taken from ansto/93d9a7c Conflicts: .gitignore SICSmain.c asynnet.c confvirtualmot.c counter.c devexec.c drive.c event.h exebuf.c exeman.c histmem.c interface.h motor.c motorlist.c motorsec.c multicounter.c napi.c napi.h napi4.c network.c nwatch.c nxscript.c nxxml.c nxxml.h ofac.c reflist.c scan.c sicshipadaba.c sicsobj.c site_ansto/docs/Copyright.txt site_ansto/instrument/lyrebird/config/tasmad/sicscommon/nxsupport.tcl site_ansto/instrument/lyrebird/config/tasmad/taspub_sics/tasscript.tcl statusfile.c tasdrive.c tasub.c tasub.h tasublib.c tasublib.h
506 lines
23 KiB
OpenEdge ABL
506 lines
23 KiB
OpenEdge ABL
|
|
\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.
|
|
|
|
@d Modes @{
|
|
typedef enum {
|
|
eHTransparent,
|
|
eHNormal,
|
|
eHTOF,
|
|
eHStrobo,
|
|
eHRPT,
|
|
ePSD,
|
|
eSANSTOF
|
|
} HistMode;
|
|
@}
|
|
These modes are specific to the SINQ histogram memory.
|
|
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.
|
|
|
|
@d Modes @{
|
|
typedef enum {
|
|
eOIgnore,
|
|
eOCeil,
|
|
eOCount,
|
|
eReflect
|
|
} OverFlowMode;
|
|
@}
|
|
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.
|
|
|
|
The histogram memory supports several dimensions, a time binning
|
|
option and optional buffering of histogram memory data read from the
|
|
actual HM. All this data management stuff is handled in a separate
|
|
class, HMdata. See the documentation for HMdata for more details.
|
|
|
|
|
|
\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:
|
|
|
|
@d HistType @{
|
|
typedef struct __HistDriver {
|
|
pHMdata data;
|
|
/* counting operations data */
|
|
CounterMode eCount;
|
|
float fCountPreset;
|
|
/* status flags */
|
|
int iReconfig;
|
|
int iUpdate;
|
|
pStringDict pOption;
|
|
/* interface functions */
|
|
int (*Configure)(pHistDriver self,
|
|
SConnection *pCon,
|
|
pStringDict pOpt,
|
|
SicsInterp *pSics);
|
|
int (*Start)(pHistDriver self,
|
|
SConnection *pCon);
|
|
int (*Halt)(pHistDriver self);
|
|
int (*GetCountStatus)(pHistDriver self,
|
|
SConnection *pCon);
|
|
int (*GetError)(pHistDriver self,
|
|
int *iCode,
|
|
char *perror,
|
|
int iErrlen);
|
|
int (*TryAndFixIt)(pHistDriver self,
|
|
int iCode);
|
|
int (*GetData)(pHistDriver self,
|
|
SConnection *pCon);
|
|
int (*GetHistogram)(pHistDriver self,
|
|
SConnection *pCon,
|
|
int i,
|
|
int iStart, int iEnd,
|
|
HistInt *pData);
|
|
|
|
int (*SetHistogram)(pHistDriver self,
|
|
SConnection *pCon,
|
|
int i,
|
|
int iStart, int iEnd,
|
|
HistInt *pData);
|
|
long (*GetMonitor)(pHistDriver self,
|
|
int i,
|
|
SConnection *pCon);
|
|
float (*GetTime)(pHistDriver self,
|
|
SConnection *pCon);
|
|
HistInt *(*SubSample)(pHistDriver self,
|
|
SConnection *pCon,int bank,
|
|
char *command);
|
|
int (*Preset)(pHistDriver self,
|
|
SConnection *pCon,
|
|
HistInt iVal);
|
|
int (*Pause)(pHistDriver self,
|
|
SConnection *pCon);
|
|
int (*Continue)(pHistDriver self,
|
|
SConnection *pCon);
|
|
int (*FreePrivate)(pHistDriver self);
|
|
void *pPriv;
|
|
} HistDriver;
|
|
@}
|
|
|
|
Quite a lot, but a histogram memory is quite a complex piece of equipment.
|
|
|
|
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:
|
|
|
|
@d HistDrivProt @{
|
|
pHistDriver CreateHistDriver(pStringDict pDict);
|
|
void DeleteHistDriver(pHistDriver self);
|
|
int HistDriverConfig(pHistDriver self, pStringDict pOpt,
|
|
SConnection *pCon);
|
|
HistInt *DefaultSubSample(pHistDriver self, SConnection *pCon,
|
|
int bank, char *command);
|
|
@}
|
|
|
|
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:
|
|
@d HistST @{
|
|
typedef struct __HistMem {
|
|
pObjectDescriptor pDes;
|
|
int iAccess;
|
|
int iExponent;
|
|
pHistDriver pDriv;
|
|
int iInit;
|
|
pICountable pCountInt;
|
|
pICallBack pCall;
|
|
} HistMem;
|
|
@}
|
|
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:
|
|
|
|
@d Protos @{
|
|
pHistMem CreateHistMemory(char *drivername);
|
|
void DeleteHistMemory(void *self);
|
|
@}
|
|
|
|
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.
|
|
@d Protos @{
|
|
int HistGetOption(pHistMem self, char *name, char *result, int iResultLen);
|
|
int HistSetOption(pHistMem self, char *name, char *value);
|
|
int HistConfigure(pHistMem self, SConnection *pCon, SicsInterp *pSics);
|
|
@}
|
|
|
|
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:
|
|
@d Protos @{
|
|
float GetHistPreset(pHistMem self);
|
|
int SetHistPreset(pHistMem self, float fVal);
|
|
CounterMode GetHistCountMode(pHistMem self);
|
|
int SetHistCountMode(pHistMem self, CounterMode eNew);
|
|
long GetHistMonitor(pHistMem self, int i, SConnection *pCon);
|
|
const float *GetHistTimeBin(pHistMem self, int *iLength);
|
|
int GetHistLength(pHistMem self);
|
|
int GetHistDim(pHistMem self, int iDim[MAXDIM], int *nDim);
|
|
float GetHistCountTime(pHistMem self,SConnection *pCon);
|
|
int HistDoCount(pHistMem self, SConnection *pCon);
|
|
int HistBlockCount(pHistMem self, SConnection *pCon);
|
|
void HistDirty(pHistMem self);
|
|
|
|
int isSecondGen(pHistMem self);
|
|
pHistMem FindHM(SicsInterp *pSics, char *name);
|
|
|
|
@}
|
|
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:
|
|
@d Protos @{
|
|
int SetHistogram(pHistMem self, SConnection *pCon,
|
|
int i,int iStart, int iEnd, HistInt *lData);
|
|
int GetHistogram(pHistMem self, SConnection *pCon,
|
|
int i,int iStart, int iEnd, HistInt *lData, int iDataLen);
|
|
HistInt *GetHistogramPointer(pHistMem self,SConnection *pCon);
|
|
int GetHistogramDirect(pHistMem self, SConnection *pCon,
|
|
int i, int iStart, int iEnd,
|
|
HistInt *lData, int iDataLen);
|
|
int PresetHistogram(pHistMem self, SConnection *pCon, HistInt lVal);
|
|
@}
|
|
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.
|
|
|
|
GetHistogram and GetHistogramPointer try to buffer the data when
|
|
possible and configured. The configuration happens through the
|
|
definition of an update intervall. GetHistogramDirect never buffers
|
|
but goes for the histogram memory directly.
|
|
|
|
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:
|
|
@d Protos @{
|
|
int MakeHistMemory(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|
int argc, char *argv[]);
|
|
|
|
int HistAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|
int argc, char *argv[]);
|
|
|
|
@}
|
|
|
|
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}
|
|
|
|
@o HistMem.h -d @{
|
|
/*--------------------------------------------------------------------------
|
|
H I S T M E M
|
|
|
|
header for the histogram memory object for SICS.
|
|
|
|
copyright: see implementation file.
|
|
Mark Koennecke, April 1997
|
|
-----------------------------------------------------------------------------*/
|
|
#ifndef SICSHISTMEM
|
|
#define SICSHISTMEM
|
|
#define MAXDIM 3
|
|
|
|
typedef struct __HistDriver *pHistDriver;
|
|
typedef struct __HistMem *pHistMem;
|
|
/*-------------------------------------------------------------------------*/
|
|
typedef int HistInt;
|
|
/*
|
|
32 bit integer on a DigitalUnix
|
|
*/
|
|
@< Modes @>
|
|
/*--------------------------------------------------------------------------*/
|
|
@< Protos @>
|
|
|
|
#endif
|
|
@}
|
|
|
|
@o HistDriv.i -d @{
|
|
/*---------------------------------------------------------------------------
|
|
H I S T D R I V
|
|
internal header file which includes the definition of the Histogram memory
|
|
driver structure.
|
|
|
|
Mark Koennecke, April 1997
|
|
----------------------------------------------------------------------------*/
|
|
#ifndef SICSHISTDRIV
|
|
#define SICSHISTDRIV
|
|
#include "hmdata.h"
|
|
|
|
@< HistType@>
|
|
@< HistDrivProt @>
|
|
|
|
#endif
|
|
@}
|
|
|
|
@o HistMem.i -d @{
|
|
/*---------------------------------------------------------------------------
|
|
H I S T M E M -- Internal
|
|
internal header file which includes the definition of the Histogram memory
|
|
data structure.
|
|
|
|
Mark Koennecke, April 1997
|
|
----------------------------------------------------------------------------*/
|
|
#ifndef SICSHISTMEMINT
|
|
#define SICSHISTMEMINT
|
|
@< HistST@>
|
|
|
|
#endif
|
|
@}
|
|
|
|
|
|
|
|
|