git-svn-id: https://subversion.xor.aps.anl.gov/synApps/areaDetector/trunk@7657 dc6c5ff5-0b8b-c028-a01f-ffb33f00fc8b
This commit is contained in:
rivers
2008-09-19 22:39:41 +00:00
parent 161f8ea15a
commit 4d9f4a49f4
5 changed files with 1156 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 342 KiB

158
documentation/NDPluginFile.html Executable file
View File

@@ -0,0 +1,158 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>areaDetector Plugin NDPluginFile</title>
</head>
<body>
<div style="text-align: center">
<h1>
areaDetector Plugin NDPluginFile</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>
NDPluginFile saves the NDArray data from a callback to a disk file.
</p>
<p>
NDPluginFile inherits from NDPluginDriver. 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>
<p>
The NDArray callback data can be written to disk in 1 of 3 modes:
</p>
<ol>
<li>Single mode. In this mode each NDArray callback results in a separate disk file.</li>
<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>
<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.</li>
</ol>
<p>
The NDPluginFile public interface is defined in NDPluginFile.h as follows:
</p>
<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>
<h2 id="Configuration">
Configuration</h2>
<p>
The NDPluginFile plugin is created with the following command, either from C/C++
or from the EPICS IOC shell.
</p>
<pre>drvNDFileConfigure(const char *portName, int queueSize, int blockingCallbacks,
const char *NDArrayPort, int NDArrayAddr)
</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>
</table>
<h2 id="Screens">
Screen shots</h2>
<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>
<div style="text-align: center">
<h3>
NDFile.adl</h3>
<p>
<img alt="NDFile.png" src="NDFile.png" /></p>
</div>
</body>
</html>

758
documentation/NDPluginROI.html Executable file
View File

@@ -0,0 +1,758 @@
<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 inherits from NDPluginDriver. 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 definition of the ROI
is currently limited to 2-D. This limitation will be removed in a future release.
</p>
<p>
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
listed above. 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 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 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 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 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.
<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 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>
<div style="text-align: center">
<h3>
NDROI8.adl</h3>
<img alt="NDROI8.png" src="NDROI8.png" />
</div>
<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>
<div style="text-align: center">
<h3>
Highlighted Regions-of-Interest</h3>
<img alt="ROI_outlines.png" src="ROI_outlines.png" />
</div>
</body>
</html>

View File

@@ -0,0 +1,240 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>areaDetector Plugin NDPluginStdArrays</title>
</head>
<body>
<div style="text-align: center">
<h1>
areaDetector Plugin NDPluginStdArrays</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>
<li><a href="#IDLClient">IDL image display client</a></li>
</ul>
<h2 id="Overview">
Overview
</h2>
<p>
This plugin is the tool for converting the NDArray data produced by asynNDArrayDriver
drivers into a form that can be accessed by EPICS.
</p>
<p>
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. 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:</p>
<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>
<p>
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 border="1" cellpadding="2" cellspacing="2" style="text-align: left">
<tbody>
<tr>
<td align="CENTER" colspan="7,">
<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>
If the array data contains more than 16,000 bytes then in order for EPICS clients
to receive this data they must be built with EPICS R3.14 (not R3.13), and the environment
variable EPICS_CA_MAX_ARRAY_BYTES on both the EPICS IOC computer and EPICS client
computer must be set to a value at least as large as the array size in bytes.</p>
<h2 id="Configuration">
Configuration</h2>
<p>
The NDPluginStdArrays plugin is created with the following command, either from
C/C++ or from the EPICS IOC shell.
</p>
<pre>drvNDStdArraysConfigure(const char *portName, int queueSize, int blockingCallbacks,
const char *NDArrayPort, int NDArrayAddr, 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>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 NDStdArrays plugin allocates
2 NDArray objects, so this should be at least twice 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 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>
<div style="text-align: center">
<h3>
NDStdArrays.adl</h3>
<p>
<img alt="NDStdArrays.png" src="NDStdArrays.png" /></p>
</div>
<h2 id="IDLClient">
IDL Image Display Client</h2>
<p>
There is an IDL program called <code>epics_ad_display</code> that can be used to
display 2-dimensional ArrayData that the NDStdArrays plugin sends to EPICS. This
IDL client is available as source code (which requires an IDL license), and also
as a pre-built IDL .sav file that can be run for free under the IDL Virtual Machine.
This IDL program can run on any machine that IDL runs on, and that has the ezcaIDL
shareable library built for it. This includes Windows, Linux, Solaris, and Mac.
<code>epics_ad_display</code> is included in the <a href="http://cars.uchicago.edu/software/IDL/imaging.html">
CARS IDL imaging software.</a>
</p>
<p>
The control window for <code>epics_ad_display</code> is shown below. It has fields
to input the base name of the EPICS PVs with the image data. The client uses the
</p>
<div style="text-align: center">
<h3>
Main window for IDL epics_ad_display</h3>
<p>
<img alt="IDL_epics_ad_display.png" src="IDL_epics_ad_display.png" /></p>
</div>
<p>
<code>epics_ad_display</code> can use the simple IDL routine <code>tv</code> to
display the images. This is the fasted mode, and results in a non-scaleable unadorned
window.</p>
<div style="text-align: center">
<h3>
IDL epics_ad_display using the IDL <code>tv</code> routine.</h3>
<p>
<img alt="IDL_epics_ad_display_tv.png" src="IDL_epics_ad_display_tv.png" /></p>
</div>
<p>
<code>epics_ad_display</code> can also use the routine <a href="http://cars.uchicago.edu/software/IDL/imaging_routines.html#IMAGE_DISPLAY">
image_display.pro</a> to display the images. This routine displays row and column
profiles as the cursor is moved. It allows changing the color lookup tables, and
zooming in and out with the left and right mouse buttons. The following is an example
of <code>image_display</code> displaying an image from the simulation detector.</p>
<div style="text-align: center">
<h3>
epics_ad_display using the image_display routine</h3>
<p>
<img alt="simDetector_image_display.png" src="simDetector_image_display.png" /></p>
</div>
</body>
</html>