git-svn-id: https://subversion.xor.aps.anl.gov/synApps/areaDetector/trunk@7583 dc6c5ff5-0b8b-c028-a01f-ffb33f00fc8b
809 lines
32 KiB
HTML
Executable File
809 lines
32 KiB
HTML
Executable File
<HTML>
|
|
<HEAD>
|
|
<TITLE>areaDetector Plugins</TITLE>
|
|
</HEAD>
|
|
<BODY>
|
|
|
|
<CENTER>
|
|
<H1>areaDetector Plugins</H1>
|
|
|
|
<H2> September 5, 2008</H2>
|
|
<H2> Mark Rivers</H2>
|
|
<H2> University of Chicago</H2>
|
|
</CENTER>
|
|
|
|
<P> </P>
|
|
|
|
<CENTER><H2>Contents</H2></CENTER>
|
|
<UL>
|
|
<LI><A href="#Overview">
|
|
Overview</A>
|
|
<LI><A href="#NDPluginDriver">
|
|
NDPluginDriver</A>
|
|
<LI><A href="#NDPluginStdArrays">
|
|
NDPluginStdArrays</A>
|
|
<LI><A href="#NDPluginFile">
|
|
NDPluginFile</A>
|
|
<LI><A href="#NDPluginROI">
|
|
NDPluginROI</A>
|
|
</UL>
|
|
|
|
<P>
|
|
<CENTER><H2><A name=Overview>
|
|
Overview</A></H2></CENTER>
|
|
|
|
A powerful feature of the
|
|
<A href="areaDetectorDoc.html">
|
|
areaDetector</A>
|
|
module is the concept of plugins. A plugin is code that is called by
|
|
a driver that passes NDArray data in a callback. Plugins can be used to process array data in real time.
|
|
Existing plugins convert data to standard asyn arrays (NDPluginStdArrays)
|
|
save data to disk (NDPluginFile), and select regions-of-interest (NDPluginROI). New plugins could be written to perform
|
|
functions like finding the centroid of a beam, etc. Once a plugin is written it will work with any areaDetector driver.
|
|
Plugins have the the following properties:
|
|
<UL>
|
|
<LI>They can execute either in a blocking mode or a non-blocking mode. In the blocking mode the callback is executed
|
|
by the driver callback thread. In this mode the callback is guaranteed to execute for each NDArray callback. However, it
|
|
can slow down the driver, and does not utilize the multi-core capability of modern CPUs. In the non-blocking mode the driver
|
|
callback simply places the NDArray data in a queue that is part of the plugin. The plugin then executes the callback code
|
|
in it own thread, removes NDArray data from the queue, processes it, and releases the data back to the NDArrayPool when it is done.
|
|
In the non-blocking mode some additional memory is required for the NDArray objects that are in the queue. It is also
|
|
possible to drop NDArray data if the queue is full, i.e. some callback data will not be processed. The non-blocking mode
|
|
can utilize the multi-core capabilities of modern CPUs because each plugin is executing in its own thread. The operation of
|
|
the queue and the NDArrayPool class means that data never needs to be copied, each plugin has a pointer to the data which
|
|
will continue to be valid until the last plugin is done with it.
|
|
<LI>They can be enabled or disabled at run time.
|
|
<LI>They can be throttled to only execute at a limited rate. This means, for example, that a detector can be saving data to disk
|
|
at full speed, but images can be posted to EPICS at a reduced rate.
|
|
<LI>They can be unplugged from one driver, and plugged into another driver at run time. In particular the NDPluginROI driver
|
|
is itself a source of NDArray data callbacks, so a file saving plugin could be unplugged from a detector driver
|
|
(where it would be saving the entire detector), and plugged into a particular ROI, where it would just save a portion
|
|
of the detector.
|
|
</UL>
|
|
<P>
|
|
<CENTER><H2><A name=NDPluginDriver>
|
|
NDPluginDriver</A></H2></CENTER>
|
|
|
|
NDPluginDriver inherits from
|
|
<A href=areaDetectorDoc.html#asynNDArrayDriver>
|
|
asynNDArrayDriver</A>.
|
|
NDPluginDriver is the class from which actual plugins are directly derived.
|
|
The NDPluginDriver class handles most of the details of processing NDArray callbacks from the driver. Plugins
|
|
derived from this class typically need to implement the processCallbacks method, some of the write(Int32, Float64, Octet)
|
|
methods.
|
|
|
|
The NDPluginDriver public interface is defined in NDPluginDriver.h as follows:
|
|
<PRE>
|
|
class NDPluginDriver : public asynNDArrayDriver {
|
|
public:
|
|
NDPluginDriver(const char *portName, int queueSize, int blockingCallbacks,
|
|
const char *NDArrayPort, int NDArrayAddr, int maxAddr, int paramTableSize,
|
|
int maxBuffers, size_t maxMemory, int interfaceMask, int interruptMask);
|
|
|
|
/* These are the methods that we override from asynNDArrayDriver */
|
|
virtual asynStatus writeInt32(asynUser *pasynUser, epicsInt32 value);
|
|
virtual asynStatus writeOctet(asynUser *pasynUser, const char *value, size_t maxChars,
|
|
size_t *nActual);
|
|
virtual asynStatus readInt32Array(asynUser *pasynUser, epicsInt32 *value,
|
|
size_t nElements, size_t *nIn);
|
|
virtual asynStatus drvUserCreate(asynUser *pasynUser, const char *drvInfo,
|
|
const char **pptypeName, size_t *psize);
|
|
|
|
/* These are the methods that are new to this class */
|
|
virtual void processCallbacks(NDArray *pArray);
|
|
virtual void driverCallback(asynUser *pasynUser, void *genericPointer);
|
|
virtual void processTask(void);
|
|
virtual asynStatus setArrayInterrupt(int connect);
|
|
virtual asynStatus connectToArrayPort(void);
|
|
int createFileName(int maxChars, char *fullFileName);
|
|
...
|
|
}
|
|
</PRE>
|
|
The methods of the NDPluginDriver class are:
|
|
<UL>
|
|
<LI><CODE>NDPluginDriver</CODE> This is the constructor for the class. All parameters except queueSize,
|
|
blockingCallbacks, NDArrayPort, and NDArrayAddr
|
|
are just passed to the constructor for asynNDArrayDriver. NDArrayPort and NDArrayAddr, and blockingCallbacks
|
|
are the initial values
|
|
for the NDPluginDriverArrayPort, NDPluginDriverArrayAddr and NDPluginDriverBlockingCallbacks
|
|
parameters described in the table below.
|
|
<LI><CODE>drvUserCreate</CODE> This method returns one of the enum values for the parameters defined in
|
|
NDPluginDriver.h if the driverInfo field matches one the strings defined in that file. Derived classes will
|
|
typically provide an implementation of drvUserCreate() that searches for parameters that are unique to that
|
|
plugin. If a parameter is not matched, then NDPluginDriver->drvUserCreate() will be called to see if it
|
|
is a standard plugin parameter (defined in NDPluginDriver.h).
|
|
<LI><CODE>processCallbacks</CODE> This method is called each time a driver calls the plugin with a new NDArray object.
|
|
Derived classes typically call this base class method, which handles some bookkeeping chores, and then they perform
|
|
whatever operations are specific to that plugin.
|
|
<LI><CODE>createFileName</CODE> This is a convenience function that constructs a complete file name in
|
|
the ADFullFileName parameter from the
|
|
ADFilePath, ADFileName, ADFileNumber, and ADFileTemplate parameters.
|
|
</UL>
|
|
|
|
NDPluginDriver defines parameters that all plugin drivers should implement if possible. These parameters are defined
|
|
by enum values with an associated asyn interface, and access (read-only or read-write). The EPICS database
|
|
NDPluginBase.template provides access to these standard plugin parameters, listed in the following table.
|
|
<P>
|
|
<TABLE style="TEXT-ALIGN: left" cellSpacing=2 cellPadding=2 border=1>
|
|
<TBODY>
|
|
<TR>
|
|
<TD COLSPAN=7, ALIGN=CENTER><B>Parameter Definitions in NDPluginDriver.h and EPICS Record Definitions in NDPluginBase.template</B></TD>
|
|
</TR>
|
|
<TR>
|
|
<TH>Enum name</TH>
|
|
<TH>asyn interface</TH>
|
|
<TH>Access</TH>
|
|
<TH>Description</TH>
|
|
<TH>drvUser string</TH>
|
|
<TH>EPICS record name</TH>
|
|
<TH>EPICS record type</TH>
|
|
</TR>
|
|
<TR>
|
|
<TD COLSPAN=7, ALIGN=CENTER><B>asyn NDArray driver doing callbacks</B></TD>
|
|
</TR>
|
|
<TR>
|
|
<TD>NDPluginDriverArrayPort</TD>
|
|
<TD>asynOctet</TD>
|
|
<TD>r/w</TD>
|
|
<TD>asyn port name for NDArray driver that will make callbacks to this plugin.
|
|
This port can be changed at run time, connecting the plugin to a different NDArray driver.</TD>
|
|
<TD>NDARRAY_PORT</TD>
|
|
<TD>$(P)$(R)NDArrayPort<BR>(P)$(R)NDArrayPort_RBV</TD>
|
|
<TD>stringout<BR>stringin</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD>NDPluginDriverArrayAddr</TD>
|
|
<TD>asynInt32</TD>
|
|
<TD>r/w</TD>
|
|
<TD>asyn port address for NDArray driver that will make callbacks to this plugin.
|
|
This address can be changed at run time, connecting the plugin to a different address in the NDArray driver.</TD>
|
|
<TD>NDARRAY_ADDR</TD>
|
|
<TD>$(P)$(R)NDArrayAddress<BR>(P)$(R)NDArrayAddress_RBV</TD>
|
|
<TD>longout<BR>longin</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD COLSPAN=7, ALIGN=CENTER><B>Callback enable, minimum time, and statistics</B></TD>
|
|
</TR>
|
|
<TR>
|
|
<TD>NDPluginDriverEnableCallbacks</TD>
|
|
<TD>asynInt32</TD>
|
|
<TD>r/w</TD>
|
|
<TD>Enable (1) or disable (0) callbacks from the driver to this plugin. If callbacks are disabled then the plugin
|
|
will normally be idle and consume no CPU resources.</TD>
|
|
<TD>ENABLE_CALLBACKS</TD>
|
|
<TD>$(P)$(R)EnableCallbacks<BR>(P)$(R)EnableCallbacks_RBV</TD>
|
|
<TD>bo<BR>bi</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD>NDPluginDriverMinCallbackTime</TD>
|
|
<TD>asynFloat64</TD>
|
|
<TD>r/w</TD>
|
|
<TD>The minimum time in seconds between calls to processCallbacks. Any callbacks occuring before this minimum
|
|
time has elapsed will be ignored. 0 means no minimum time, i.e. process all callbacks.</TD>
|
|
<TD>MIN_CALLBACK_TIME</TD>
|
|
<TD>$(P)$(R)MinCallbackTime<BR>(P)$(R)MinCallbackTime_RBV</TD>
|
|
<TD>ao<BR>ai</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD>NDPluginDriverArrayCounter</TD>
|
|
<TD>asynInt32</TD>
|
|
<TD>r/w</TD>
|
|
<TD>Counter that increments by 1 each time an NDArray callback is processed</TD>
|
|
<TD>ARRAY_COUNTER</TD>
|
|
<TD>$(P)$(R)ArrayCounter<BR>(P)$(R)ArrayCounter_RBV</TD>
|
|
<TD>longout<BR>longin</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD>N/A</TD>
|
|
<TD>N/A</TD>
|
|
<TD>r/o</TD>
|
|
<TD>Rate (Hz) at which ArrayCounter is incrementing. Computed in database.</TD>
|
|
<TD>N/A</TD>
|
|
<TD>$(P)$(R)ArrayRate_RBV</TD>
|
|
<TD>calc</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD>NDPluginDriverDroppedArrays</TD>
|
|
<TD>asynInt32</TD>
|
|
<TD>r/w</TD>
|
|
<TD>Counter that increments by 1 each time an NDArray callback occurs when NDPluginDriverBlockingCallbacks=0
|
|
and the plugin driver queue is full, so the callback cannot be processed.</TD>
|
|
<TD>DROPPED_ARRAYS</TD>
|
|
<TD>$(P)$(R)DroppedArrays<BR>(P)$(R)DroppedArrays_RBV</TD>
|
|
<TD>longout<BR>longin</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD COLSPAN=7, ALIGN=CENTER><B>Information about last NDArray callback data</B></TD>
|
|
</TR>
|
|
<TR>
|
|
<TD>NDPluginDriverNDimensions</TD>
|
|
<TD>asynInt32</TD>
|
|
<TD>r/o</TD>
|
|
<TD>Number of dimensions in last NDArray callback data</TD>
|
|
<TD>ARRAY_NDIMENSIONS</TD>
|
|
<TD>$(P)$(R)NDimensions_RBV</TD>
|
|
<TD>longin</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD>NDPluginDriverDimensions</TD>
|
|
<TD>asynInt32Array</TD>
|
|
<TD>r/o</TD>
|
|
<TD>Dimensions in last NDArray callback data</TD>
|
|
<TD>ARRAY_DIMENSIONS</TD>
|
|
<TD>$(P)$(R)Dimensions_RBV</TD>
|
|
<TD>waveform</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD>N/A</TD>
|
|
<TD>N/A</TD>
|
|
<TD>r/o</TD>
|
|
<TD>First dimension of NDArray callback data</TD>
|
|
<TD>N/A</TD>
|
|
<TD>$(P)$(R)ArraySize0_RBV</TD>
|
|
<TD>longin</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD>N/A</TD>
|
|
<TD>N/A</TD>
|
|
<TD>r/o</TD>
|
|
<TD>Second dimension of NDArray callback data</TD>
|
|
<TD>N/A</TD>
|
|
<TD>$(P)$(R)ArraySize1_RBV</TD>
|
|
<TD>longin</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD>NDPluginDriverDataType</TD>
|
|
<TD>asynInt32</TD>
|
|
<TD>r/o</TD>
|
|
<TD>Data type of last NDArray callback data (NDDataType_t).</TD>
|
|
<TD>DATA_TYPE</TD>
|
|
<TD>$(P)$(R)DataType_RBV</TD>
|
|
<TD>mbbi</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD>NDPluginDriverUniqueId</TD>
|
|
<TD>asynInt32</TD>
|
|
<TD>r/o</TD>
|
|
<TD>Unique ID number of last NDArray callback data</TD>
|
|
<TD>UNIQUE_ID</TD>
|
|
<TD>$(P)$(R)UniqueId_RBV</TD>
|
|
<TD>longin</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD>NDPluginDriverTimeStamp</TD>
|
|
<TD>asynFloat64</TD>
|
|
<TD>r/o</TD>
|
|
<TD>Time stamp number of last NDArray callback data</TD>
|
|
<TD>TIME_STAMP</TD>
|
|
<TD>$(P)$(R)TimeStamp_RBV</TD>
|
|
<TD>ai</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD COLSPAN=7, ALIGN=CENTER><B>Debugging control</B></TD>
|
|
</TR>
|
|
<TR>
|
|
<TD>N/A</TD>
|
|
<TD>N/A</TD>
|
|
<TD>N/A</TD>
|
|
<TD>asyn record to control debugging (asynTrace)</TD>
|
|
<TD>N/A</TD>
|
|
<TD>$(P)$(R)AsynIO</TD>
|
|
<TD>asyn</TD>
|
|
</TR>
|
|
</TBODY>
|
|
</TABLE>
|
|
|
|
<P>
|
|
<CENTER><H2><A name=NDPluginStdArrays>
|
|
NDPluginStdArrays</A></H2></CENTER>
|
|
|
|
NDPluginStdArrays inherits from
|
|
NDPluginDriver. NDPluginStdArrays converts the NDArray data from a callback into the 1-dimensional
|
|
arrays supported by the standard asyn array interfaces, i.e. asyn[Int8, Int16, Int32, Float32, Float64]Array. These interfaces are
|
|
supported by the EPICS waveform record using standard asyn device support. This plugin is thus the tool for converting the NDArray
|
|
data produced by asynNDArrayDriver drivers into a form that can be accessed by EPICS. Because this plugin inherits from NDPluginDriver
|
|
it also provides additional information
|
|
on the array data (e.g. number of dimensions and dimension data described above)
|
|
that are made available as EPICS PVs so that clients can correctly
|
|
interpret the array data.
|
|
|
|
The NDPluginStdArrays public interface is defined in NDPluginStdArrays.h as follows:
|
|
<PRE>
|
|
class NDPluginStdArrays : public NDPluginDriver {
|
|
public:
|
|
NDPluginStdArrays(const char *portName, int queueSize, int blockingCallbacks,
|
|
const char *NDArrayPort, int NDArrayAddr,
|
|
size_t maxMemory);
|
|
|
|
/* These methods override the virtual methods in the base class */
|
|
void processCallbacks(NDArray *pArray);
|
|
virtual asynStatus readInt8Array(asynUser *pasynUser, epicsInt8 *value,
|
|
size_t nElements, size_t *nIn);
|
|
virtual asynStatus readInt16Array(asynUser *pasynUser, epicsInt16 *value,
|
|
size_t nElements, size_t *nIn);
|
|
virtual asynStatus readInt32Array(asynUser *pasynUser, epicsInt32 *value,
|
|
size_t nElements, size_t *nIn);
|
|
virtual asynStatus readFloat32Array(asynUser *pasynUser, epicsFloat32 *value,
|
|
size_t nElements, size_t *nIn);
|
|
virtual asynStatus readFloat64Array(asynUser *pasynUser, epicsFloat64 *value,
|
|
size_t nElements, size_t *nIn);
|
|
asynStatus drvUserCreate(asynUser *pasynUser, const char *drvInfo,
|
|
const char **pptypeName, size_t *psize);
|
|
...
|
|
}
|
|
</PRE>
|
|
NDPluginStdArrays defines the following parameters. It also implements all of the standard plugin parameters from NDPlugDriver
|
|
listed above. The EPICS database
|
|
NDStdArrays.template provides access to these parameters, listed in the following table.
|
|
<P>
|
|
<TABLE style="TEXT-ALIGN: left" cellSpacing=2 cellPadding=2 border=1>
|
|
<TBODY>
|
|
<TR>
|
|
<TD COLSPAN=7, ALIGN=CENTER><B>Parameter Definitions in NDPluginStdArrays.h and EPICS Record Definitions in NDStdArrays.template</B></TD>
|
|
</TR>
|
|
<TR>
|
|
<TH>Enum name</TH>
|
|
<TH>asyn interface</TH>
|
|
<TH>Access</TH>
|
|
<TH>Description</TH>
|
|
<TH>drvUser string</TH>
|
|
<TH>EPICS record name</TH>
|
|
<TH>EPICS record type</TH>
|
|
</TR>
|
|
<TR>
|
|
<TD>NDPluginStdArraysData</TD>
|
|
<TD>asyn[Int8, Int16, Int32, Float32, Float64]Array</TD>
|
|
<TD>r/o</TD>
|
|
<TD>Array data as a 1-D array, possibly converted in data type from that in the NDArray object to the specific asyn interface.</TD>
|
|
<TD>STD_ARRAY_DATA</TD>
|
|
<TD>$(P)$(R)ArrayData</TD>
|
|
<TD>waveform</TD>
|
|
</TR>
|
|
</TBODY>
|
|
</TABLE>
|
|
<P>
|
|
The following is the MEDM screen that provides access to the parameters in NDPluginDriver.h and NDPluginStdArrays.h through
|
|
records in NDPluginBase.template and NDStdArrays.template. This is the MEDM screen that is normally used to control the
|
|
display of images via EPICS channel access.
|
|
<P>
|
|
<CENTER><IMG src="NDStdArrays.png"></CENTER>
|
|
|
|
<P>
|
|
<CENTER><H2><A name=NDPluginFile>
|
|
NDPluginFile</A></H2></CENTER>
|
|
|
|
NDPluginFile inherits from NDPluginDriver. NDPluginFile saves the NDArray data from a callback to a disk file. This plugin currently
|
|
saves data in the
|
|
<A HREF="http://www.unidata.ucar.edu/software/netcdf">netCDF</A>
|
|
file format, which is a portable self-describing binary file format supported by
|
|
<A HREF="http://www.unidata.ucar.edu/">UniData</A>
|
|
at
|
|
<A HREF="http://www.ucar.edu/">UCAR (University Corporation for Atmospheric Research).</A>
|
|
Additional file formats, such as TIFF and HDF
|
|
may be supported in the future.
|
|
<P>
|
|
The NDArray callback data can be written to disk in 1 of 3 modes:
|
|
<OL>
|
|
<LI>Single mode. In this mode each NDArray callback results in a separate disk file.
|
|
<LI>Capture mode. In this mode a memory buffer is allocated before saving begins. Callback arrays are placed into this
|
|
buffer, and when capture stops the file is written to disk. This mode limits the number of frames that can be
|
|
saved, because they all must fit in a memory buffer. It is the fastest mode, with the least probability of dropping
|
|
arrays, because no disk I/O is required while capture is in progress.
|
|
<LI>Stream mode. In this mode the data are written to a single disk file, with each frame being appended to the file
|
|
without closing it. It is intermediate in speed between single mode and capture mode, but unlike capture mode
|
|
it is not limited by available memory in the number of arrays that can be saved.
|
|
</OL>
|
|
|
|
The NDPluginFile public interface is defined in NDPluginFile.h as follows:
|
|
<PRE>
|
|
|
|
/* Note that the file format enum must agree with the mbbo/mbbi records in the NDFile.template file */
|
|
typedef enum {
|
|
NDFileFormatNetCDF,
|
|
} NDPluginFileFormat_t;
|
|
|
|
typedef enum {
|
|
NDPluginFileModeSingle,
|
|
NDPluginFileModeCapture,
|
|
NDPluginFileModeStream
|
|
} NDPluginFileMode_t;
|
|
|
|
...
|
|
class NDPluginFile : public NDPluginDriver {
|
|
public:
|
|
NDPluginFile(const char *portName, int queueSize, int blockingCallbacks,
|
|
const char *NDArrayPort, int NDArrayAddr);
|
|
|
|
/* These methods override those in the base class */
|
|
void processCallbacks(NDArray *pArray);
|
|
asynStatus writeInt32(asynUser *pasynUser, epicsInt32 value);
|
|
asynStatus writeNDArray(asynUser *pasynUser, void *genericPointer);
|
|
asynStatus drvUserCreate(asynUser *pasynUser, const char *drvInfo,
|
|
const char **pptypeName, size_t *psize);
|
|
|
|
...
|
|
}
|
|
</PRE>
|
|
<P>NDPluginFile also supports all of the file saving parameters defined in ADStdDriverParams.h described above, e.g.ADFilePath, ADFileName, etc.
|
|
Thus, the same interface that is used for saving files directly in a driver are used for this plugin.
|
|
<P>
|
|
The following is the MEDM screen that provides access to the parameters in NDPluginDriver.h and NDPluginFile.h through
|
|
records in NDPluginBase.template and NDFile.template. This is the MEDM screen that is used to control the
|
|
saving of images to disk for drivers that do not support saving files to disk themselves.
|
|
<P>
|
|
<CENTER><IMG src="NDFile.png"></CENTER>
|
|
|
|
<CENTER><H2><A name=NDPluginROI>
|
|
NDPluginROI</A></H2></CENTER>
|
|
|
|
NDPluginROI inherits from NDPluginDriver. NDPluginROI selects one or more "Regions-Of-Interest" (ROIs) from the NDArray
|
|
callback data. It does 3 things with these ROIs:
|
|
<OL>
|
|
<LI>Computes statistics, e.g. mean, maximum, minimum, total value, net (background subtracted) value
|
|
<LI>Computes a histogram of the values (e.g. number of pixels versus intensity per pixel)
|
|
<LI>Exports the ROI as a new NDArray object. In this regard NDPluginROI is different from the NDPluginStdArrays and
|
|
NDPluginFile plugins because it is both a <B>recipient</B> of callbacks (as they are) and a <B>source</B> of NDArray callbacks,
|
|
as a driver is. This means that the NDPluginStdArrays and NDPluginFile plugins can be connected to an NDPluginROI plugin,
|
|
in which case they will save or display the selected ROI rather than the full detector driver data.
|
|
</OL>
|
|
<P>
|
|
Each NDPluginROI can handle any number of ROIs. The maximum number of ROIs that the plugin can support is defined when
|
|
the plugin is created. Several ROI plugins could be created for a single detector driver to
|
|
increase the number of threads running in parallel, maximizing the
|
|
use of multiple CPU cores. Individual ROIs are addressed through the asyn interfaces by the asyn "addr" field in the asynUser structure.
|
|
Note that while the NDPluginROI should be N-dimensional, the definition of the ROI is currently limited to 2-D. This limitation will
|
|
be removed in a future release.
|
|
<P>
|
|
The NDPluginROI public interface is defined in NDPluginROI.h as follows:
|
|
<PRE>
|
|
|
|
class NDPluginROI : public NDPluginDriver {
|
|
public:
|
|
NDPluginROI(const char *portName, int queueSize, int blockingCallbacks,
|
|
const char *NDArrayPort, int NDArrayAddr, int maxROIs, size_t maxMemory);
|
|
/* These methods override the virtual methods in the base class */
|
|
void processCallbacks(NDArray *pArray);
|
|
asynStatus writeInt32(asynUser *pasynUser, epicsInt32 value);
|
|
asynStatus drvUserCreate(asynUser *pasynUser, const char *drvInfo,
|
|
const char **pptypeName, size_t *psize);
|
|
|
|
/* These methods are unique to this class */
|
|
asynStatus readFloat64Array(asynUser *pasynUser, epicsFloat64 *value,
|
|
size_t nelements, size_t *nIn);
|
|
|
|
</PRE>
|
|
<P>
|
|
The readFloat64Array method is used to read the histogram data for the ROI.
|
|
<P>
|
|
NDPluginROI.h defines the following parameters that are global to all ROIs for a plugin.
|
|
It also implements all of the standard plugin parameters from NDPlugDriver
|
|
listed above. The EPICS database
|
|
NDROI.template provide access to these parameters, listed in the following table.
|
|
<P>
|
|
<TABLE style="TEXT-ALIGN: left" cellSpacing=2 cellPadding=2 border=1>
|
|
<TBODY>
|
|
<TR>
|
|
<TD COLSPAN=7, ALIGN=CENTER><B>Parameter Definitions in NDPluginROI.h and EPICS Record Definitions in NDROI.template</B></TD>
|
|
</TR>
|
|
<TR>
|
|
<TH>Enum name</TH>
|
|
<TH>asyn interface</TH>
|
|
<TH>Access</TH>
|
|
<TH>Description</TH>
|
|
<TH>drvUser string</TH>
|
|
<TH>EPICS record name</TH>
|
|
<TH>EPICS record type</TH>
|
|
</TR>
|
|
<TR>
|
|
<TD>NDPluginROIHighlight</TD>
|
|
<TD>asynInt32</TD>
|
|
<TD>r/w</TD>
|
|
<TD>Flag to indicate if the borders of ROIs should be highlighted (0=No, 1=Yes). If set then all ROIs will be highlighted
|
|
in all other ROIs where they overlap. One common use of this is to set the first ROI to be the entire detector,
|
|
and then the location of all other ROIs will be visible when the first ROI is displayed. The highlighting is done by
|
|
replacing the border pixels with the maximum value of the data in that ROI. Statistics are computed before the highlighting
|
|
is done.</TD>
|
|
<TD>HIGHLIGHT</TD>
|
|
<TD>$(P)$(R)Highlight<BR>$(P)$(R)Highlight_RBV</TD>
|
|
<TD>bo<BR>bi</TD>
|
|
</TR>
|
|
</TBODY>
|
|
</TABLE>
|
|
<P>
|
|
NDPluginROI.h defines the following parameters that are specific to each individual ROI in the plugin.
|
|
The EPICS database
|
|
NDROIN.template provide access to these parameters, listed in the following table. The pasynUser->addr is used to control
|
|
which ROI is being addressed.
|
|
<P>
|
|
<TABLE style="TEXT-ALIGN: left" cellSpacing=2 cellPadding=2 border=1>
|
|
<TBODY>
|
|
<TR>
|
|
<TD COLSPAN=7, ALIGN=CENTER><B>Parameter Definitions in NDPluginROI.h and EPICS Record Definitions in NDROIN.template</B></TD>
|
|
</TR>
|
|
<TR>
|
|
<TH>Enum name</TH>
|
|
<TH>asyn interface</TH>
|
|
<TH>Access</TH>
|
|
<TH>Description</TH>
|
|
<TH>drvUser string</TH>
|
|
<TH>EPICS record name</TH>
|
|
<TH>EPICS record type</TH>
|
|
</TR>
|
|
<TR>
|
|
<TD>NDPluginROIName</TD>
|
|
<TD>asynOctet</TD>
|
|
<TD>r/w</TD>
|
|
<TD>Name of this ROI</TD>
|
|
<TD>NAME</TD>
|
|
<TD>$(P)$(R)Name<BR>$(P)$(R)Name_RBV</TD>
|
|
<TD>stringout<BR>stringin</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD>NDPluginROIUse</TD>
|
|
<TD>asynInt32</TD>
|
|
<TD>r/w</TD>
|
|
<TD>Flag to control whether this ROI is used (0=No, 1=Yes). Not using an ROI reduces CPU load.</TD>
|
|
<TD>USE</TD>
|
|
<TD>$(P)$(R)Use<BR>$(P)$(R)Use_RBV</TD>
|
|
<TD>bo<BR>bi</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD COLSPAN=7, ALIGN=CENTER><B>ROI definition</B></TD>
|
|
</TR>
|
|
<TR>
|
|
<TD>NDPluginROIDim0Bin</TD>
|
|
<TD>asynInt32</TD>
|
|
<TD>r/w</TD>
|
|
<TD>Binning in the X direction</TD>
|
|
<TD>DIM0_BIN</TD>
|
|
<TD>$(P)$(R)BinX<BR>$(P)$(R)BinX_RBV</TD>
|
|
<TD>longout<BR>longin</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD>NDPluginROIDim1Bin</TD>
|
|
<TD>asynInt32</TD>
|
|
<TD>r/w</TD>
|
|
<TD>Binning in the Y direction</TD>
|
|
<TD>DIM1_BIN</TD>
|
|
<TD>$(P)$(R)BinY<BR>$(P)$(R)BinY_RBV</TD>
|
|
<TD>longout<BR>longin</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD>NDPluginROIDim0Min</TD>
|
|
<TD>asynInt32</TD>
|
|
<TD>r/w</TD>
|
|
<TD>First pixel in the ROI in the X direction. <BR>0 is the first pixel in the array.</TD>
|
|
<TD>DIM0_MIN</TD>
|
|
<TD>$(P)$(R)MinX<BR>$(P)$(R)MinX_RBV</TD>
|
|
<TD>longout<BR>longin</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD>NDPluginROIDim1Min</TD>
|
|
<TD>asynInt32</TD>
|
|
<TD>r/w</TD>
|
|
<TD>First pixel in the ROI in the Y direction.<BR>0 is the first pixel in the array.</TD>
|
|
<TD>DIM1_MIN</TD>
|
|
<TD>$(P)$(R)MinY<BR>$(P)$(R)MinY_RBV</TD>
|
|
<TD>longout<BR>longin</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD>NDPluginROIDim0Size</TD>
|
|
<TD>asynInt32</TD>
|
|
<TD>r/w</TD>
|
|
<TD>Size of the ROI in the X direction</TD>
|
|
<TD>DIM0_SIZE</TD>
|
|
<TD>$(P)$(R)SizeX<BR>$(P)$(R)SizeX_RBV</TD>
|
|
<TD>longout<BR>longin</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD>NDPluginROIDim0Size</TD>
|
|
<TD>asynInt32</TD>
|
|
<TD>r/w</TD>
|
|
<TD>Size of ROI in the Y direction</TD>
|
|
<TD>DIM1_SIZE</TD>
|
|
<TD>$(P)$(R)SizeY<BR>$(P)$(R)SizeY_RBV</TD>
|
|
<TD>longout<BR>longin</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD>NDPluginROIDim0Reverse</TD>
|
|
<TD>asynInt32</TD>
|
|
<TD>r/w</TD>
|
|
<TD>Reverse ROI in the X direction<BR>(0=No, 1=Yes)</TD>
|
|
<TD>DIM0_REVERSE</TD>
|
|
<TD>$(P)$(R)ReverseX<BR>$(P)$(R)ReverseX_RBV</TD>
|
|
<TD>longout<BR>longin</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD>NDPluginROIDim0Reverse</TD>
|
|
<TD>asynInt32</TD>
|
|
<TD>r/w</TD>
|
|
<TD>Reverse ROI in the Y direction<BR>(0=No, 1=Yes)</TD>
|
|
<TD>DIM1_REVERSE</TD>
|
|
<TD>$(P)$(R)ReverseY<BR>$(P)$(R)ReverseY_RBV</TD>
|
|
<TD>longout<BR>longin</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD>NDPluginROIDataType</TD>
|
|
<TD>asynInt32</TD>
|
|
<TD>r/w</TD>
|
|
<TD>Data type of the ROI (NDDataType_t). This can be different from the data type of the NDArray callback data.</TD>
|
|
<TD>DATA_TYPE</TD>
|
|
<TD>$(P)$(R)DataType<BR>$(P)$(R)DataType_RBV</TD>
|
|
<TD>mbbo<BR>mbbi</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD>NDPluginROIBgdWidth</TD>
|
|
<TD>asynInt32</TD>
|
|
<TD>r/w</TD>
|
|
<TD>Width of the background in pixels to use when computing net counts. 0=no background subtraction.</TD>
|
|
<TD>BGD_WIDTH</TD>
|
|
<TD>$(P)$(R)BgdWidth<BR>$(P)$(R)BgdWidth_RBV</TD>
|
|
<TD>longout<BR>longin</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD>ADImageSizeX</TD>
|
|
<TD>asynInt32</TD>
|
|
<TD>r/o</TD>
|
|
<TD>Size of the ROI data in the X direction</TD>
|
|
<TD>IMAGE_SIZE_X</TD>
|
|
<TD>$(P)$(R)ImageSizeX_RBV</TD>
|
|
<TD>longin</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD>ADImageSizeY</TD>
|
|
<TD>asynInt32</TD>
|
|
<TD>r/o</TD>
|
|
<TD>Size of the ROI data in the Y direction</TD>
|
|
<TD>IMAGE_SIZE_Y</TD>
|
|
<TD>$(P)$(R)ImageSizeY_RBV</TD>
|
|
<TD>longin</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD COLSPAN=7, ALIGN=CENTER><B>ROI statistics</B></TD>
|
|
</TR>
|
|
<TR>
|
|
<TD>NDPluginROIComputeStatistics</TD>
|
|
<TD>asynInt32</TD>
|
|
<TD>r/w</TD>
|
|
<TD>Flag to control whether to compute statistics for this ROI (0=No, 1=Yes). Not computing statistics reduces CPU load.</TD>
|
|
<TD>COMPUTE_STATISTICS</TD>
|
|
<TD>$(P)$(R)ComputeStatistics<BR>$(P)$(R)ComputeStatistics_RBV</TD>
|
|
<TD>bo<BR>bi</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD>NDPluginROIMinValue</TD>
|
|
<TD>asynFloat64</TD>
|
|
<TD>r/o</TD>
|
|
<TD>Minimum value in any element in the ROI</TD>
|
|
<TD>MIN_VALUE</TD>
|
|
<TD>$(P)$(R)MinValue_RBV</TD>
|
|
<TD>ai</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD>NDPluginROIMaxValue</TD>
|
|
<TD>asynFloat64</TD>
|
|
<TD>r/o</TD>
|
|
<TD>Maximum value in any element in the ROI</TD>
|
|
<TD>MAX_VALUE</TD>
|
|
<TD>$(P)$(R)MaxValue_RBV</TD>
|
|
<TD>ai</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD>NDPluginROIMeanValue</TD>
|
|
<TD>asynFloat64</TD>
|
|
<TD>r/o</TD>
|
|
<TD>Mean value in the ROI</TD>
|
|
<TD>MEAN_VALUE</TD>
|
|
<TD>$(P)$(R)MeanValue_RBV</TD>
|
|
<TD>ai</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD>NDPluginROITotal</TD>
|
|
<TD>asynFloat64</TD>
|
|
<TD>r/o</TD>
|
|
<TD>Sum (total) of all elements in the ROI</TD>
|
|
<TD>TOTAL</TD>
|
|
<TD>$(P)$(R)Total_RBV</TD>
|
|
<TD>ai</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD>NDPluginROINet</TD>
|
|
<TD>asynFloat64</TD>
|
|
<TD>r/o</TD>
|
|
<TD>Net (background subtracted) total of all elements in the ROI. The background is calculated by determining the average
|
|
counts per array element in a border around the ROI border of width NDPluginROIBgdWidth. This average background counts per element
|
|
is then subtracted from all elements inside the ROI.</TD>
|
|
<TD>NET</TD>
|
|
<TD>$(P)$(R)Net_RBV</TD>
|
|
<TD>ai</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD COLSPAN=7, ALIGN=CENTER><B>ROI histogram</B></TD>
|
|
</TR>
|
|
<TR>
|
|
<TD>NDPluginROIComputeHistogram</TD>
|
|
<TD>asynInt32</TD>
|
|
<TD>r/w</TD>
|
|
<TD>Flag to control whether to compute the histogram for this ROI (0=No, 1=Yes). Not computing the histogram reduces CPU load.</TD>
|
|
<TD>COMPUTE_HISTOGRAM</TD>
|
|
<TD>$(P)$(R)ComputeHistogram<BR>$(P)$(R)ComputeHistogram_RBV</TD>
|
|
<TD>bo<BR>bi</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD>NDPluginROIHistSize</TD>
|
|
<TD>asynInt32</TD>
|
|
<TD>r/w</TD>
|
|
<TD>Number of elements (bins) in the histogram</TD>
|
|
<TD>HIST_SIZE</TD>
|
|
<TD>$(P)$(R)HistSize<BR>$(P)$(R)HistSize_RBV</TD>
|
|
<TD>longout<BR>longin</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD>NDPluginROIHistMin</TD>
|
|
<TD>asynFloat64</TD>
|
|
<TD>r/w</TD>
|
|
<TD>Minimum value for the histogram. All values less than or equal to this will be in the first bin of the histogram.</TD>
|
|
<TD>HIST_MIN</TD>
|
|
<TD>$(P)$(R)HistMin<BR>$(P)$(R)HistMin_RBV</TD>
|
|
<TD>ao<BR>ai</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD>NDPluginROIHistMax</TD>
|
|
<TD>asynFloat64</TD>
|
|
<TD>r/w</TD>
|
|
<TD>Maximum value for the histogram. All values greater than or equal to this will be in the last bin of the histogram.</TD>
|
|
<TD>HIST_MAX</TD>
|
|
<TD>$(P)$(R)HistMax<BR>$(P)$(R)HistMax_RBV</TD>
|
|
<TD>ao<BR>ai</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD>NDPluginROIHistEntropy</TD>
|
|
<TD>asynFloat64</TD>
|
|
<TD>r/o</TD>
|
|
<TD>Entropy of the image. This is a measure of the sharpness of the histogram, and is often a useful figure of merit
|
|
for determining sharpness of focus, etc. It is defined as -SUM(BIN[i]*log(BIN[i]), where the sum is over the number
|
|
of bins in the histogram and BIN[i] is the number of elements in bin i.</TD>
|
|
<TD>HIST_ENTROPY</TD>
|
|
<TD>$(P)$(R)HistEntropy_RBV</TD>
|
|
<TD>ai</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD>NDPluginROIHistArray</TD>
|
|
<TD>asynFloat64Array</TD>
|
|
<TD>r/o</TD>
|
|
<TD>Histogram array, i.e. counts in each histogram bin.</TD>
|
|
<TD>HIST_ARRAY</TD>
|
|
<TD>$(P)$(R)Histogram_RBV</TD>
|
|
<TD>waveform</TD>
|
|
</TR>
|
|
</TBODY>
|
|
</TABLE>
|
|
<P>
|
|
The following is the MEDM screen that provides access to the parameters in NDPluginDriver.h and NDPluginROI.h through
|
|
records in NDPluginBase.template and NDROI.template. This is the MEDM screen that is used to control the behavior
|
|
of the ROI plugin, but not the individual ROIs.
|
|
<P>
|
|
<CENTER><IMG src="NDROI.png"></CENTER>
|
|
<P>
|
|
The following is the MEDM screen that provides access to the parameters for in NDPluginROI.h through
|
|
records in NDROIN.template. This is the MEDM screen that is used to control the behavior of a specific ROI.
|
|
<P>
|
|
<CENTER><IMG src="NDROIN.png"></CENTER>
|
|
<P>
|
|
The following is another MEDM screen that provides access to the parameters for in NDPluginROI.h through
|
|
records in NDROIN.template. This is the MEDM screen that is used to control the most commonly used properties
|
|
of 8 ROIs.
|
|
<P>
|
|
<CENTER><IMG src="NDROI8.png"></CENTER>
|
|
<P>
|
|
The following is an IDL epics_ad_display screen illustrating the highlighting of ROIs. In this example
|
|
the ROIs defined are those in the 8 ROI display above.
|
|
The NDPluginStdArrays driver has been configured to be receiving its NDArray callbacks from the first ROI (which is defined to
|
|
be the entire detector array), and
|
|
the NDPluginROIHighlight flag is set to Yes.
|
|
<P>
|
|
<CENTER><IMG src="ROI_outlines.png"></CENTER>
|
|
|
|
</BODY>
|
|
</HTML>
|