Files
ADAndor/documentation/NDPluginROI.html
rivers 891b4e48ab Minor changes
git-svn-id: https://subversion.xor.aps.anl.gov/synApps/areaDetector/trunk@7671 dc6c5ff5-0b8b-c028-a01f-ffb33f00fc8b
2008-09-23 13:33:55 +00:00

762 lines
21 KiB
HTML
Executable File

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>areaDetector Plugin NDPluginROI</title>
</head>
<body>
<div style="text-align: center">
<h1>
areaDetector Plugin NDPluginROI</h1>
<h2>
September 19, 2008</h2>
<h2>
Mark Rivers</h2>
<h2>
University of Chicago</h2>
</div>
<h2>
Contents</h2>
<ul>
<li><a href="#Overview">Overview</a></li>
<li><a href="#Configuration">Configuration</a></li>
<li><a href="#Screens">Screen shots</a></li>
</ul>
<h2 id="Overview">
Overview
</h2>
<p>
NDPluginROI selects one or more rectangular "Regions-Of-Interest" (ROIs) from the
NDArray callback data. The maximum number of ROIs is defined when the plugin is
created. Each ROI can be any size, from a single array element to the entire array.
NDPluginROI does 3 things with these ROIs:
</p>
<ol>
<li>Computes statistics, e.g. mean, maximum, minimum, total value, net (background
subtracted) value</li>
<li>Computes a histogram of the values (e.g. number of pixels versus intensity per
pixel)</li>
<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.</li>
</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 EPICS interface to
the definition of the ROI is currently limited to 2-D. This limitation will be removed
in a future release.
</p>
<p>
NDPluginROI inherits from NDPluginDriver. The NDPluginROI public interface is defined
in NDPluginROI.h as follows:
</p>
<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>
<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.
The EPICS database NDROI.template provide access to these parameters, listed in
the following table.
</p>
<table border="1" cellpadding="2" cellspacing="2" style="text-align: left">
<tbody>
<tr>
<td align="CENTER" colspan="7,">
<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 the borders of 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 border="1" cellpadding="2" cellspacing="2" style="text-align: left">
<tbody>
<tr>
<td align="CENTER" colspan="7,">
<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 align="CENTER" colspan="7,">
<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, so the net counts is the same as the total counts.</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 align="CENTER" colspan="7,">
<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 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 align="CENTER" colspan="7,">
<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>
<h2 id="Configuration">
Configuration</h2>
<p>
The NDPluginROI plugin is created with the following command, either from C/C++
or from the EPICS IOC shell.
</p>
<pre>drvNDROIConfigure(const char *portName, int queueSize, int blockingCallbacks,
const char *NDArrayPort, int NDArrayAddr, int maxROIs,
size_t maxMemory)
</pre>
<table border="1" cellpadding="2" cellspacing="2" style="text-align: left">
<tr>
<th>
Argument</th>
<th>
Description</th>
</tr>
<tr>
<td>
<code>portName</code></td>
<td>
The name of the asyn port for this plugin.
</td>
</tr>
<tr>
<td>
<code>queueSize</code></td>
<td>
The maximum number of NDArray objects that can be queued for processing. Passed
to the NDPluginDriver base class constructor.
</td>
</tr>
<tr>
<td>
<code>blockingCallbacks</code></td>
<td>
Flag controlling whether callbacks block. Passed to the NDPluginDriver base class
constructor.
</td>
</tr>
<tr>
<td>
<code>NDArrayPort</code></td>
<td>
The name of the asyn port of the driver that will provide the NDArray data. Passed
to the NDPluginDriver base class constructor.
</td>
</tr>
<tr>
<td>
<code>NDArrayAddr</code></td>
<td>
The asyn addr of the asyn port of the driver that will provide the NDArray data.
Passed to the NDPluginDriver base class constructor.
</td>
</tr>
<tr>
<td>
<code>maxROIs</code></td>
<td>
Maximum number of ROIs that this plugin will support.
</td>
</tr>
<tr>
<td>
<code>maxMemory</code></td>
<td>
Maximum number of bytes of memory to be allocated from the NDArrayPool. Passed to
the constructor for the NDPluginDriver base class. The NDPluginROI plugin allocates
one NDArray object for each ROI, so this should be at least maxROIs times the size
of the largest NDArray to be used.</td>
</tr>
</table>
<h2 id="Screens">
Screen shots</h2>
<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>
<div style="text-align: center">
<h3>
NDROI.adl</h3>
<img alt="NDROI.png" src="NDROI.png" />
</div>
<p>
The following is the MEDM screen that provides access to the parameters in NDPluginROI.h
for an individual ROI through records in NDROIN.template. This is the MEDM screen
that is used to control the behavior of a specific ROI.
<br />
</p>
<div style="text-align: center">
<h3>
NDROIN.adl</h3>
<img alt="NDROIN.png" src="NDROIN.png" />
</div>
<p>
The following is another MEDM screen that provides access to the parameters 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>
<div style="text-align: center">
<h3>
NDROI8.adl</h3>
<img alt="NDROI8.png" src="NDROI8.png" />
</div>
<p>
The following is an IDL <a href="http://cars.uchicago.edu/software/idl/imaging_routines.html#epics_ad_display">
epics_ad_display</a> 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>
<div style="text-align: center">
<h3>
Highlighted Regions-of-Interest</h3>
<img alt="ROI_outlines.png" src="ROI_outlines.png" />
</div>
</body>
</html>