Files
ADAndor/documentation/pluginDoc.html
rivers a4c75d60bc New file
git-svn-id: https://subversion.xor.aps.anl.gov/synApps/areaDetector/trunk@7583 dc6c5ff5-0b8b-c028-a01f-ffb33f00fc8b
2008-09-05 19:48:13 +00:00

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>&nbsp;</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-&gtaddr 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>