git-svn-id: https://subversion.xor.aps.anl.gov/synApps/areaDetector/trunk@16079 dc6c5ff5-0b8b-c028-a01f-ffb33f00fc8b
2181 lines
73 KiB
HTML
Executable File
2181 lines
73 KiB
HTML
Executable File
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
|
<html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
|
|
<head>
|
|
<title>areaDetector: EPICS software for area detectors</title>
|
|
<meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type" />
|
|
</head>
|
|
<body>
|
|
<div style="text-align: center">
|
|
<h1>
|
|
areaDetector: EPICS Area Detector Support</h1>
|
|
<h2>
|
|
Release 1-9-1</h2>
|
|
<h2>
|
|
March 11, 2013</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="#Architecture">Architecture</a></li>
|
|
<li><a href="#Implementation_details">Implementation details</a>
|
|
<ul>
|
|
<li><a href="#asynPortDriver">asynPortDriver</a></li>
|
|
<li><a href="#NDArray">NDArray</a></li>
|
|
<li><a href="#NDArrayPool">NDArrayPool</a></li>
|
|
<li><a href="#NDAttribute">NDAttribute</a></li>
|
|
<li><a href="#NDAttributeList">NDAttributeList</a></li>
|
|
<li><a href="#PVAttribute">PVAttribute</a></li>
|
|
<li><a href="#paramAttribute">paramAttribute</a></li>
|
|
<li><a href="#asynNDArrayDriver">asynNDArrayDriver</a></li>
|
|
</ul>
|
|
</li>
|
|
<li>Detector drivers
|
|
<ul>
|
|
<li><a href="#ADDriver">ADDriver</a></li>
|
|
<li><a href="#Guidelines">Guidelines and rules for drivers</a></li>
|
|
<li><a href="adscDoc.html">ADSC driver</a></li>
|
|
<li><a href="andorDoc.html">Andor driver (Andor CCD cameras)</a></li>
|
|
<li><a href="andor3Doc.html">Andor3 driver (Andor sCMOS cameras)</a></li>
|
|
<li><a href="BrukerDoc.html">Bruker driver</a></li>
|
|
<li><a href="http://controls.diamond.ac.uk/downloads/support/firewireDCAM/index.html">
|
|
Firewire Linux driver</a></li>
|
|
<li><a href="FirewireWinDoc.html">Firewire Windows driver</a></li>
|
|
<li><a href="Mar345Doc.html">mar345 driver</a></li>
|
|
<li><a href="MarCCDDoc.html">MarCCD driver</a></li>
|
|
<li><a href="PerkinElmerDoc.html">Perkin-Elmer flat panel driver</a></li>
|
|
<li><a href="pilatusDoc.html">Pilatus driver</a></li>
|
|
<li><a href="prosilicaDoc.html">Prosilica driver</a></li>
|
|
<li><a href="pvcamDoc.html">PVCAM driver</a></li>
|
|
<li><a href="RoperDoc.html">Roper driver</a></li>
|
|
<li><a href="simDetectorDoc.html">Simulation detector driver</a></li>
|
|
<li><a href="URLDriverDoc.html">URL driver</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="pluginDoc.html">Plugins</a>
|
|
<ul>
|
|
<li><a href="pluginDoc.html#NDPluginDriver">NDPluginDriver</a></li>
|
|
<li><a href="pluginDoc.html#Guidelines">Guidelines and rules for plugins</a></li>
|
|
<li><a href="NDPluginStdArrays.html">NDPluginStdArrays</a></li>
|
|
<li><a href="NDPluginFile.html">NDPluginFile</a></li>
|
|
<li><a href="NDPluginROI.html">NDPluginROI</a></li>
|
|
<li><a href="NDPluginStats.html">NDPluginStats</a></li>
|
|
<li><a href="NDPluginProcess.html">NDPluginProcess</a></li>
|
|
<li><a href="NDPluginOverlay.html">NDPluginOverlay</a></li>
|
|
<li><a href="NDPluginTransform.html">NDPluginTransform</a></li>
|
|
<li><a href="NDPluginColorConvert.html">NDPluginColorConvert</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#MEDM_screens">MEDM screens</a></li>
|
|
<li><a href="areaDetectorViewers.html">Viewers</a>
|
|
<ul>
|
|
<li><a href="areaDetectorViewers.html#ImageJViewer">ImageJ Viewer</a></li>
|
|
<li><a href="areaDetectorViewers.html#IDLViewer">IDL Viewer</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Installation">Installation, configuration, and startup</a></li>
|
|
<li><a href="#Acknowledgments">Acknowledgments and licenses</a></li>
|
|
</ul>
|
|
<p>
|
|
</p>
|
|
<h2 id="Overview">
|
|
Overview</h2>
|
|
<p>
|
|
The areaDetector module provides a general-purpose interface for area (2-D) detectors
|
|
in <a href="http://www.aps.anl.gov/epics/">EPICS</a>. It is intended to be used
|
|
with a wide variety of detectors and cameras, ranging from high frame rate CCD and
|
|
CMOS cameras, pixel-array detectors such as the Pilatus, and large format detectors
|
|
like the MAR-345 online imaging plate.</p>
|
|
<p>
|
|
The goals of this module are:
|
|
</p>
|
|
<ul>
|
|
<li>Minimize the amount of code that needs to be written to implement a new detector.</li>
|
|
<li>Provide a standard interface defining the functions and parameters that a detector
|
|
driver must support.</li>
|
|
<li>Provide a set of base EPICS records that will be present for every detector using
|
|
this module. This allows the use of generic EPICS clients for displaying images
|
|
and controlling cameras and detectors.</li>
|
|
<li>Allow easy extensibility to take advantage of detector-specific features beyond
|
|
the standard parameters.</li>
|
|
<li>Have high-performance. Applications can be written to get the detector image data
|
|
through EPICS, but an interface is also available to receive the detector data at
|
|
a lower-level for very high performance.</li>
|
|
<li>Provide a mechanism for device-independent real-time data analysis such as regions-of-interest
|
|
and statistics.</li>
|
|
<li>Provide detector drivers for commonly used detectors in synchrotron applications.
|
|
These include Prosilica GigE video cameras, IEEE 1394 (Firewire) cameras, ADSC and
|
|
MAR CCD x-ray detectors, MAR-345 online imaging plate detectors, the Pilatus pixel-array
|
|
detector, Roper Scientific CCD cameras, and the Perkin-Elmer amorphous silicon detector.</li>
|
|
</ul>
|
|
<p>
|
|
</p>
|
|
<h2 id="Architecture">
|
|
Architecture</h2>
|
|
<p>
|
|
The architecture of the areaDetector module is shown below.</p>
|
|
<p style="text-align: center">
|
|
<img alt="areaDetectorArchitecture.png" src="areaDetectorArchitecture.png" /></p>
|
|
<p>
|
|
From the bottom to the top this architecture consists of the following:</p>
|
|
<ul>
|
|
<li>Layer 1. This is the layer that allows user written code to communicate with the
|
|
hardware. It is usually provided by the detector vendor. It may consist of a library
|
|
or DLL, of a socket protocol to a driver, a Microsoft COM interface, etc.</li>
|
|
<li>Layer 2. This is the driver that is written for the areaDetector application to
|
|
control a particular detector. It is written in C++ and inherits from the ADDriver
|
|
class. It uses the standard asyn interfaces for control and status information.
|
|
Each time it receives a new data array it can pass it as an NDArray object to all
|
|
Layer 3 clients that have registered for callbacks. This is the only code that needs
|
|
to be written to implement a new detector. Existing drivers range from 800 to 1800
|
|
lines of code.</li>
|
|
<li>Layer 3. Code running at this level is called a "plug-in". This code registers
|
|
with a driver for a callback whenever there is a new data array. The existing plugins
|
|
implement file saving (NDPluginFile), region-of-interest (ROI) calculations (NDPluginROI),
|
|
color mode conversion (NDPluginColorConvert), and conversion of detector data to
|
|
standard EPICS array types for use by Channel Access clients (NDPluginStdArrays).
|
|
Plugins are normally written in C++ and inherit from NDPluginDriver. Existing plugins
|
|
range from 300 to 800 lines of code.</li>
|
|
<li>Layer 4. This is standard asyn device support that comes with the EPICS asyn module.</li>
|
|
<li>Layer 5. These are standard EPICS records, and EPICS database (template) files
|
|
that define records to communicate with drivers at Layer 2 and plugins at Layer
|
|
3.</li>
|
|
<li>Layer 6. These are EPICS channel access clients, such as MEDM that communicate
|
|
with the records at Layer 5. areaDetector includes two client applications that
|
|
can display images using EPICS waveform and other records communicating with the
|
|
NDPluginStdArrays plugin at Layer 3. One of these clients is an ImageJ plugin, and
|
|
the other is a freely runnable IDL application.</li>
|
|
</ul>
|
|
<p>
|
|
The code in Layers 1-3 is essentially independent of EPICS. There are only 2 EPICS
|
|
dependencies in this code.
|
|
</p>
|
|
<ol>
|
|
<li><a href="http://www.aps.anl.gov/epics/base/R3-14/10-docs/AppDevGuide.pdf">libCom</a>.
|
|
libCom from EPICS base provides operating-system independent functions for threads,
|
|
mutexes, etc.</li>
|
|
<li><a href="http://www.aps.anl.gov/epics/modules/soft/asyn/">asyn</a>. asyn is a
|
|
module that provides interthread messaging services, including queueing and callbacks.</li>
|
|
</ol>
|
|
<p>
|
|
In particular it is possible to eliminate layers 4-6 in the architecture shown in
|
|
Figure 1, providing there is a programs such as the high-performance GUI shown in
|
|
Layer 3. This means that it is not necessary to run an EPICS IOC or to use EPICS
|
|
Channel Access when using the drivers and plugins at Layers 2 and 3.
|
|
</p>
|
|
<p>
|
|
The plugin architecture is very powerful, because new plugins can be written for
|
|
application-specific purposes. For example, a plugin could be written to analyze
|
|
images and find the center of the beam, and such a plugin would then work with any
|
|
detector driver. Plugins are also powerful because they can be reconfigured at run-time.
|
|
For example the NDPluginStdArrays can switch from getting its array data from a
|
|
detector driver to an NDPluginROI plugin. That way it will switch from displaying
|
|
the entire detector to whatever sub-region the ROI driver has selected. Any Channel
|
|
Access clients connected to the NDPluginStdArrays driver will automatically switch
|
|
to displaying this subregion. Similarly, the NDPluginFile plugin can be switched
|
|
at run-time from saving the entire image to saving a selected ROI, just by changing
|
|
its input source. Plugins can be used to form an image processing pipeline, for
|
|
example with a detector providing data to a color convert plugin, which feeds an
|
|
ROI plugin, which feeds a file saving plugin. Each plugin can run in its own thread,
|
|
and hence in its own core on a modern multi-core CPU.
|
|
</p>
|
|
<p>
|
|
The use of plugins is optional, and it is only plugins that require the driver to
|
|
make callbacks with image data. If there are no plugins being used then EPICS can
|
|
be used simply to control the detector, without accessing the data itself. This
|
|
is most useful when the vendor provides an API has the ability to save the data
|
|
to a file and an application to display the images.
|
|
</p>
|
|
<p>
|
|
What follows is a detailed description of the software, working from the bottom
|
|
up. Most of the code is object oriented, and written in C++.
|
|
</p>
|
|
<h2 id="Implementation_details">
|
|
Implementation details</h2>
|
|
<p>
|
|
The areaDetector module depends heavily on <a href="http://www.aps.anl.gov/epics/modules/soft/asyn/">
|
|
asyn</a>. It is the software that is used for interthread communication, using
|
|
the standard asyn interfaces (e.g. asynInt32, asynOctet, etc.), and callbacks. In
|
|
order to minimize the amount of redundant code in drivers, areaDetector has been
|
|
implemented using C++ classes. The base classes, from which drivers and plugins
|
|
are derived, take care of many of the details of asyn and other common code.
|
|
</p>
|
|
<h3 id="asynPortDriver">
|
|
asynPortDriver</h3>
|
|
<p>
|
|
Detector drivers and plugins are asyn port drivers, meaning that they implement
|
|
one or more of the standard asyn interfaces. They register themselves as interrupt
|
|
sources, so that they do callbacks to registered asyn clients when values change.
|
|
They inherit from the <a href="http://www.aps.anl.gov/epics/modules/soft/asyn/R4-11a/asynPortDriver.html">
|
|
asynPortDriver base C++ class</a> that is provided in the asyn module. That base
|
|
class handles all of the details of registering the port driver, registering the
|
|
supported interfaces, and registering the required interrupt sources. It also provides
|
|
a parameter library for int, double, and string parameters indexed by the integer
|
|
index values defined in the driver. The parameter library provides methods to write
|
|
and read the parameter values, and to perform callbacks to registered clients when
|
|
a parameter value has changed. The <a href="http://www.aps.anl.gov/epics/modules/soft/asyn/R4-11a/asynDoxygenHTML/classasyn_port_driver.html">
|
|
asynPortDriver class documentation</a> describes this class in detail.
|
|
</p>
|
|
<h3 id="NDArray">
|
|
NDArray</h3>
|
|
<p>
|
|
The NDArray (N-Dimensional array) is the class that is used for passing detector
|
|
data from drivers to plugins. An NDArray is a general purpose class for handling
|
|
array data. An NDArray object is self-describing, meaning it contains enough information
|
|
to describe the data itself. It can optionally contain "attributes" (class NDAttribute)
|
|
which contain meta-data describing how the data was collected, etc.
|
|
</p>
|
|
<p>
|
|
An NDArray can have up to ND_ARRAY_MAX_DIMS dimensions, currently 10. A fixed maximum
|
|
number of dimensions is used to significantly simplify the code compared to unlimited
|
|
number of dimensions. Each dimension of the array is described by an <a href="areaDetectorDoxygenHTML/struct_n_d_dimension.html">
|
|
NDDimension structure</a>. The <a href="areaDetectorDoxygenHTML/class_n_d_array.html">
|
|
NDArray class documentation </a>describes this class in detail.
|
|
</p>
|
|
<h3 id="NDArrayPool">
|
|
NDArrayPool</h3>
|
|
<p>
|
|
The NDArrayPool class manages a free list (pool) of NDArray objects. Drivers allocate
|
|
NDArray objects from the pool, and pass these objects to plugins. Plugins increase
|
|
the reference count on the object when they place the object on their queue, and
|
|
decrease the reference count when they are done processing the array. When the reference
|
|
count reaches 0 again the NDArray object is placed back on the free list. This mechanism
|
|
minimizes the copying of array data in plugins. The <a href="areaDetectorDoxygenHTML/class_n_d_array_pool.html">
|
|
NDArrayPool class documentation </a>describes this class in detail.
|
|
</p>
|
|
<h3 id="NDAttribute">
|
|
NDAttribute</h3>
|
|
<p>
|
|
The NDAttribute is a class for linking metadata to an NDArray. An NDattribute has
|
|
a name, description, data type, value, source type and source information. Attributes
|
|
are identified by their names, which are case-insensitive. There are methods to
|
|
set and get the information for an attribute.</p>
|
|
<p>
|
|
It is useful to define some conventions for attribute names, so that plugins or
|
|
data analysis programs can look for a specific attribute. The following are the
|
|
attribute conventions used in current plugins:</p>
|
|
<table border="1" cellpadding="2" cellspacing="2" style="text-align: left">
|
|
<tbody>
|
|
<tr>
|
|
<td align="center" colspan="7">
|
|
<b>Conventions for standard attribute names</b></td>
|
|
</tr>
|
|
<tr>
|
|
<th>
|
|
Attribute name</th>
|
|
<th>
|
|
Description</th>
|
|
<th>
|
|
Data type</th>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
ColorMode</td>
|
|
<td>
|
|
"Color mode"</td>
|
|
<td>
|
|
int (NDColorMode_t)</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
BayerPattern</td>
|
|
<td>
|
|
"Bayer pattern"</td>
|
|
<td>
|
|
int (NDBayerPattern_t)</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>
|
|
Attribute names are case-insensitive in the areaDetector software, but external
|
|
software may not be case-insensitive so the attribute names should generally be
|
|
used exactly as they appear above. For attributes not in this table a good convention
|
|
would be to use the corresponding driver parameter without the leading ND or AD,
|
|
and with the first character of every "word" of the name starting with upper case.
|
|
For example, the standard attribute name for ADManufacturer should be "Manufacturer",
|
|
ADNumExposures should be "NumExposures", etc.</p>
|
|
<p>
|
|
The <a href="areaDetectorDoxygenHTML/class_n_d_attribute.html">NDAttribute class documentation</a>
|
|
describes this class in detail.
|
|
</p>
|
|
<h3 id="NDAttributeList">
|
|
NDAttributeList</h3>
|
|
<p>
|
|
The NDAttributeList implements a linked list of NDAttribute objects. NDArray objects
|
|
contain an NDAttributeList which is how attributes are associated with an NDArray.
|
|
There are methods to add, delete and search for NDAttribute objects in an NDAttributeList.
|
|
Each attribute in the list must have a unique name, which is case-insensitive.
|
|
</p>
|
|
<p>
|
|
When NDArrays are copied with the NDArrayPool methods the attribute list is also
|
|
copied.
|
|
</p>
|
|
<p>
|
|
IMPORTANT NOTE: When a new NDArray is allocated using NDArrayPool::alloc() the behavior
|
|
of any existing attribute list on the NDArray taken from the pool is determined
|
|
by the value of the global variable <code>eraseNDAttributes</code>. By default the
|
|
value of this variable is 0. This means that when a new NDArray is allocated from
|
|
the pool its attribute list is <strong>not</strong> cleared. This greatly improves
|
|
efficiency in the normal case where attributes for a given driver are defined once
|
|
at initialization and never deleted. (The attribute <strong>values</strong> may
|
|
of course be changing.) It eliminates allocating and deallocating attribute memory
|
|
each time an array is obtained from the pool. It is still possible to add new attributes
|
|
to the array, but any existing attributes will continue to exist even if they are
|
|
ostensibly cleared e.g. asynNDArrayDriver::readNDAttributesFile() is called again.
|
|
If it is desired to eliminate all existing attributes from NDArrays each time a
|
|
new one is allocated then the global variable <code>eraseNDAttributes</code> should
|
|
be set to 1. This can be done at the iocsh prompt with the command:</p>
|
|
<pre> var eraseNDAttributes 1
|
|
</pre>
|
|
<p>
|
|
The <a href="areaDetectorDoxygenHTML/class_n_d_attribute_list.html">NDAttributeList
|
|
class documentation</a> describes this class in detail.
|
|
</p>
|
|
<h3 id="PVAttribute">
|
|
PVAttribute</h3>
|
|
<p>
|
|
The PVAttribute class is derived from NDAttribute. It obtains its value by monitor
|
|
callbacks from an EPICS PV, and is thus used to associate current the value of any
|
|
EPICS PV with an NDArray. The <a href="areaDetectorDoxygenHTML/class_p_v_attribute.html">
|
|
PVAttribute class documentation</a> describes this class in detail.
|
|
</p>
|
|
<h3 id="paramAttribute">
|
|
paramAttribute</h3>
|
|
<p>
|
|
The paramAttribute class is derived from NDAttribute. It obtains its value from
|
|
the current value of a driver or plugin parameter. The paramAttribute class is typically
|
|
used when it is important to have the current value of the parameter and the value
|
|
of a corresponding PVAttribute might not be current because the EPICS PV has not
|
|
yet updated. The <a href="areaDetectorDoxygenHTML/classparam_attribute.html">paramAttribute
|
|
class documentation</a> describes this class in detail.
|
|
</p>
|
|
<h3 id="asynNDArrayDriver">
|
|
asynNDArrayDriver</h3>
|
|
<p>
|
|
asynNDArrayDriver inherits from asynPortDriver. It implements the asynGenericPointer
|
|
functions for NDArray objects. This is the class from which both plugins and area
|
|
detector drivers are indirectly derived. The <a href="areaDetectorDoxygenHTML/classasyn_n_d_array_driver.html">
|
|
asynNDArrayDriver class documentation </a>describes this class in detail.
|
|
</p>
|
|
<p>
|
|
The file <a href="areaDetectorDoxygenHTML/asyn_n_d_array_driver_8h.html">asynNDArrayDriver.h</a>
|
|
defines a number of parameters that all NDArray drivers and plugins should implement
|
|
if possible. These parameters are defined by strings (drvInfo strings in asyn) with
|
|
an associated asyn interface, and access (read-only or read-write). There is also
|
|
an integer index to the parameter which is assigned by asynPortDriver when the parameter
|
|
is created in the parameter library. The EPICS database ADBase.template provides
|
|
access to these standard driver parameters. The following table lists the standard
|
|
driver parameters. The columns are defined as follows:
|
|
</p>
|
|
<ul>
|
|
<li><b>Parameter index variable:</b> The variable name for this parameter index in
|
|
the driver. There are several EPICS records in ADBase.template that do not have
|
|
corresponding parameter indices, and these are indicated as Not Applicable (N/A).</li>
|
|
<li><b>asyn interface:</b> The asyn interface used to pass this parameter to the driver.</li>
|
|
<li><b>Access:</b> Read-write (r/w) or read-only (r/o).</li>
|
|
<li><b>drvInfo string:</b> The string used to look up the parameter in the driver
|
|
through the drvUser interface. This string is used in the EPICS database file for
|
|
generic asyn device support to associate a record with a particular parameter. It
|
|
is also used to associate a <a href="areaDetectorDoxygenHTML/classparam_attribute.html">
|
|
paramAttribute</a> with a driver parameter in the XML file that is read by asynNDArrayDriver::readNDAttributesFile</li>
|
|
<li><b>EPICS record name:</b> The name of the record in ADBase.template. Each record
|
|
name begins with the two macro parameters $(P) and $(R). In the case of read/write
|
|
parameters there are normally two records, one for writing the value, and a second,
|
|
ending in _RBV, that contains the actual value (Read Back Value) of the parameter.</li>
|
|
<li><b>EPICS record type:</b> The record type of the record. Waveform records are
|
|
used to hold long strings, with length (NELM) = 256 bytes and EPICS data type (FTVL)
|
|
= UCHAR. This removes the 40 character restriction string lengths that arise if
|
|
an EPICS "string" PV is used. MEDM allows one to edit and display such records correctly.
|
|
EPICS clients will typically need to convert such long strings from a string to
|
|
an integer or byte array before sending the path name to EPICS. In IDL this is done
|
|
as follows:
|
|
<pre> ; Convert a string to a null-terminated byte array and write with caput
|
|
IDL> t = caput('13PS1:TIFF1:FilePath', [byte('/home/epics/scratch'),0B])
|
|
; Read a null terminated byte array
|
|
IDL> t = caget('13PS1:TIFF1:FilePath', v)
|
|
; Convert to a string
|
|
IDL> s = string(v)
|
|
</pre>
|
|
In SPEC this is done as follows:
|
|
<pre> array _temp[256]
|
|
# Setting the array to "" will zero-fill it
|
|
_temp = ""
|
|
# Copy the string to the array. Note, this does not null terminate, so if array already contains
|
|
# a longer string it needs to first be zeroed by setting it to "".
|
|
_temp = "/home/epics/scratch"
|
|
epics_put("13PS1:TIFF1:FilePath", _temp)
|
|
</pre>
|
|
</li>
|
|
</ul>
|
|
<p>
|
|
Note that for parameters whose values are defined by enum values (e.g NDDataType,
|
|
NDColorMode, etc.), drivers can use a different set of enum values for these parameters.
|
|
They can override the enum menu in ADBase.template with driver-specific choices
|
|
by loading a driver-specific template file that redefines that record field after
|
|
loading ADBase.template.
|
|
</p>
|
|
<table border="1" cellpadding="2" cellspacing="2" style="text-align: left">
|
|
<tbody>
|
|
<tr>
|
|
<td align="center" colspan="7">
|
|
<b>Parameter Definitions in asynNDArrayDriver.h and EPICS Record Definitions in ADBase.template
|
|
(file-related records are in NDFile.template)</b></td>
|
|
</tr>
|
|
<tr>
|
|
<th>
|
|
Parameter index variable</th>
|
|
<th>
|
|
asyn interface</th>
|
|
<th>
|
|
Access</th>
|
|
<th>
|
|
Description</th>
|
|
<th>
|
|
drvInfo string</th>
|
|
<th>
|
|
EPICS record name</th>
|
|
<th>
|
|
EPICS record type</th>
|
|
</tr>
|
|
<tr>
|
|
<td align="center" colspan="7">
|
|
<b>Information about the asyn port</b></td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
NDPortNameSelf</td>
|
|
<td>
|
|
asynOctet</td>
|
|
<td>
|
|
r/o</td>
|
|
<td>
|
|
asyn port name</td>
|
|
<td>
|
|
PORT_NAME_SELF</td>
|
|
<td>
|
|
$(P)$(R)PortName_RBV</td>
|
|
<td>
|
|
stringin</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center" colspan="7">
|
|
<b>Data type</b></td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
NDDataType</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
Data type (NDDataType_t).</td>
|
|
<td>
|
|
DATA_TYPE</td>
|
|
<td>
|
|
$(P)$(R)DataType<br />
|
|
$(P)$(R)DataType_RBV</td>
|
|
<td>
|
|
mbbo<br />
|
|
mbbi</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center" colspan="7">
|
|
<b>Color mode</b></td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
NDColorMode</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
Color mode (NDColorMode_t).</td>
|
|
<td>
|
|
COLOR_MODE</td>
|
|
<td>
|
|
$(P)$(R)ColorMode<br />
|
|
$(P)$(R)ColorMode_RBV</td>
|
|
<td>
|
|
mbbo<br />
|
|
mbbi</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center" colspan="7">
|
|
<b>Actual dimensions of array data</b></td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
NDArraySizeX</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/o</td>
|
|
<td>
|
|
Size of the array data in the X direction</td>
|
|
<td>
|
|
ARRAY_SIZE_X</td>
|
|
<td>
|
|
$(P)$(R)ArraySizeX_RBV</td>
|
|
<td>
|
|
longin</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
NDArraySizeY</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/o</td>
|
|
<td>
|
|
Size of the array data in the Y direction</td>
|
|
<td>
|
|
ARRAY_SIZE_Y</td>
|
|
<td>
|
|
$(P)$(R)ArraySizeY_RBV</td>
|
|
<td>
|
|
longin</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
NDArraySizeZ</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/o</td>
|
|
<td>
|
|
Size of the array data in the Z direction</td>
|
|
<td>
|
|
ARRAY_SIZE_Z</td>
|
|
<td>
|
|
$(P)$(R)ArraySizeZ_RBV</td>
|
|
<td>
|
|
longin</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
NDArraySize</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/o</td>
|
|
<td>
|
|
Total size of the array data in bytes</td>
|
|
<td>
|
|
ARRAY_SIZE</td>
|
|
<td>
|
|
$(P)$(R)ArraySize_RBV</td>
|
|
<td>
|
|
longin</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center" colspan="7">
|
|
<b>File saving parameters (records are defined in NDFile.template)</b></td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
NDFilePath</td>
|
|
<td>
|
|
asynOctet</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
File path</td>
|
|
<td>
|
|
FILE_PATH</td>
|
|
<td>
|
|
$(P)$(R)FilePath<br />
|
|
$(P)$(R)FilePath_RBV</td>
|
|
<td>
|
|
waveform<br />
|
|
waveform</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
NDFilePathExists</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/o</td>
|
|
<td>
|
|
Flag indicating if file path exists</td>
|
|
<td>
|
|
FILE_PATH_EXISTS</td>
|
|
<td>
|
|
$(P)$(R)FilePathExists_RBV</td>
|
|
<td>
|
|
bi</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
NDFileName</td>
|
|
<td>
|
|
asynOctet</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
File name</td>
|
|
<td>
|
|
FILE_NAME</td>
|
|
<td>
|
|
$(P)$(R)FileName<br />
|
|
$(P)$(R)FileName_RBV</td>
|
|
<td>
|
|
waveform<br />
|
|
waveform</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
NDFileNumber</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
File number</td>
|
|
<td>
|
|
FILE_NUMBER</td>
|
|
<td>
|
|
$(P)$(R)FileNumber<br />
|
|
$(P)$(R)FileNumber_RBV</td>
|
|
<td>
|
|
longout<br />
|
|
longin</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
NDFileTemplate</td>
|
|
<td>
|
|
asynOctet</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
Format string for constructing NDFullFileName from NDFilePath, NDFileName, and NDFileNumber.
|
|
The final file name (which is placed in NDFullFileName) is created with the following
|
|
code:
|
|
<pre>epicsSnprintf(
|
|
FullFilename,
|
|
sizeof(FullFilename),
|
|
FileTemplate, FilePath,
|
|
Filename, FileNumber);
|
|
</pre>
|
|
FilePath, Filename, FileNumber are converted in that order with FileTemplate. An
|
|
example file format is <code>"%s%s%4.4d.tif"</code>. The first %s converts the FilePath,
|
|
followed immediately by another %s for Filename. FileNumber is formatted with %4.4d,
|
|
which results in a fixed field with of 4 digits, with leading zeros as required.
|
|
Finally, the .tif extension is added to the file name. This mechanism for creating
|
|
file names is very flexible. Other characters, such as _ can be put in Filename
|
|
or FileTemplate as desired. If one does not want to have FileNumber in the file
|
|
name at all, then just omit the %d format specifier from FileTemplate. If the client
|
|
wishes to construct the complete file name itself, then it can just put that file
|
|
name into NDFileTemplate with no format specifiers at all, in which case NDFilePath,
|
|
NDFileName, and NDFileNumber will be ignored.</td>
|
|
<td>
|
|
FILE_TEMPLATE</td>
|
|
<td>
|
|
$(P)$(R)FileTemplate<br />
|
|
$(P)$(R)FileTemplate_RBV</td>
|
|
<td>
|
|
waveform<br />
|
|
waveform</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
NDFullFileName</td>
|
|
<td>
|
|
asynOctet</td>
|
|
<td>
|
|
r/o</td>
|
|
<td>
|
|
Full file name constructed using the algorithm described in NDFileTemplate</td>
|
|
<td>
|
|
FULL_FILE_NAME</td>
|
|
<td>
|
|
$(P)$(R)FullFileName_RBV</td>
|
|
<td>
|
|
waveform<br />
|
|
waveform</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
NDAutoIncrement</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
Auto-increment flag. Controls whether FileNumber is automatically incremented by
|
|
1 each time a file is saved (0=No, 1=Yes)</td>
|
|
<td>
|
|
AUTO_INCREMENT</td>
|
|
<td>
|
|
$(P)$(R)AutoIncrement<br />
|
|
$(P)$(R)AutoIncrement_RBV</td>
|
|
<td>
|
|
bo<br />
|
|
bi</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
NDAutoSave</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
Auto-save flag (0=No, 1=Yes) controlling whether a file is automatically saved each
|
|
time acquisition completes.</td>
|
|
<td>
|
|
AUTO_SAVE</td>
|
|
<td>
|
|
$(P)$(R)AutoSave<br />
|
|
$(P)$(R)AutoSave_RBV</td>
|
|
<td>
|
|
bo<br />
|
|
bi</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
NDFileFormat</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
File format. The format to write/read data in (e.g. TIFF, netCDF, etc.)</td>
|
|
<td>
|
|
FILE_FORMAT</td>
|
|
<td>
|
|
$(P)$(R)FileFormat<br />
|
|
$(P)$(R)FileFormat_RBV</td>
|
|
<td>
|
|
mbbo<br />
|
|
mbbi</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
NDWriteFile</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
Manually save the most recent array to a file when value=1</td>
|
|
<td>
|
|
WRITE_FILE</td>
|
|
<td>
|
|
$(P)$(R)WriteFile<br />
|
|
$(P)$(R)WriteFile_RBV</td>
|
|
<td>
|
|
busy<br />
|
|
bi</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
NDReadFile</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
Manually read a file when value=1</td>
|
|
<td>
|
|
READ_FILE</td>
|
|
<td>
|
|
$(P)$(R)ReadFile<br />
|
|
$(P)$(R)ReadFile_RBV</td>
|
|
<td>
|
|
busy<br />
|
|
bi</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
NDFileWriteMode</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
File saving mode (Single, Capture, Stream)(NDFileMode_t)</td>
|
|
<td>
|
|
WRITE_MODE</td>
|
|
<td>
|
|
$(P)$(R)FileWriteMode<br />
|
|
$(P)$(R)FileWriteMode_RBV</td>
|
|
<td>
|
|
mbbo<br />
|
|
mbbi</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
NDFileWriteStatus</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/o</td>
|
|
<td>
|
|
File write status. Gives status information on last file open or file write operation.
|
|
Values are WriteOK (0) and WriteError (1).</td>
|
|
<td>
|
|
WRITE_STATUS</td>
|
|
<td>
|
|
$(P)$(R)FileWriteStatus</td>
|
|
<td>
|
|
mbbi</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
NDFileWriteMessage</td>
|
|
<td>
|
|
asynOctet</td>
|
|
<td>
|
|
r/o</td>
|
|
<td>
|
|
File write error message. An error message string if the previous file open or file
|
|
write operation resulted in an error.</td>
|
|
<td>
|
|
WRITE_MESSAGE</td>
|
|
<td>
|
|
$(P)$(R)FileWriteMessage</td>
|
|
<td>
|
|
waveform</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
NDFileCapture</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
Start (1) or stop (0) file capture or streaming</td>
|
|
<td>
|
|
CAPTURE</td>
|
|
<td>
|
|
$(P)$(R)Capture<br />
|
|
$(P)$(R)Capture_RBV</td>
|
|
<td>
|
|
busy<br />
|
|
bi</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
NDFileNumCapture</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
Number of frames to acquire in capture or streaming mode</td>
|
|
<td>
|
|
NUM_CAPTURE</td>
|
|
<td>
|
|
$(P)$(R)NumCapture<br />
|
|
$(P)$(R)NumCapture_RBV</td>
|
|
<td>
|
|
longout<br />
|
|
longin</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
NDFileNumCaptured</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/o</td>
|
|
<td>
|
|
Number of arrays currently acquired capture or streaming mode</td>
|
|
<td>
|
|
NUM_CAPTURED</td>
|
|
<td>
|
|
$(P)$(R)NumCaptured_RBV</td>
|
|
<td>
|
|
longin</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
NDFileDeleteDriverFile</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
Flag to enable deleting original driver file after a plugin has re-written the file
|
|
in a different format. This can be useful for detectors that must write the data
|
|
to disk in order for the areaDetector driver to read it back. Once a file-writing
|
|
plugin has rewritten the data in another format it can be desireable to then delete
|
|
the original file.</td>
|
|
<td>
|
|
DELETE_DRIVER_FILE</td>
|
|
<td>
|
|
$(P)$(R)DeleteDriverFile<br />
|
|
$(P)$(R)DeleteDriverFile_RBV</td>
|
|
<td>
|
|
bo<br />
|
|
bi</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center" colspan="7">
|
|
<b>Array data</b></td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
NDArrayCallbacks</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
Controls whether the driver does callbacks with the array data to registered plugins.
|
|
0=No, 1=Yes. Setting this to 0 can reduce overhead in the case that the driver is
|
|
being used only to control the device, and not to make the data available to plugins
|
|
or to EPICS clients.</td>
|
|
<td>
|
|
ARRAY_CALLBACKS</td>
|
|
<td>
|
|
$(P)$(R)ArrayCallbacks<br />
|
|
$(P)$(R)ArrayCallbacks_RBV</td>
|
|
<td>
|
|
bo<br />
|
|
bi</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
NDArrayData</td>
|
|
<td>
|
|
asynGenericPointer</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
The array data as an NDArray object</td>
|
|
<td>
|
|
NDARRAY_DATA</td>
|
|
<td>
|
|
N/A. EPICS access to array data is through NDStdArrays plugin.</td>
|
|
<td>
|
|
N/A</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
NDArrayCounter</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
Counter that increments by 1 each time an array is acquired. Can be reset by writing
|
|
a value to it.</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 at which arrays are being acquired. Computed in the ADBase.template database.
|
|
</td>
|
|
<td>
|
|
N/A</td>
|
|
<td>
|
|
$(P)$(R)ArrayRate_RBV</td>
|
|
<td>
|
|
calc</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center" colspan="7">
|
|
<b>Array attributes</b></td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
NDAttributesFile</td>
|
|
<td>
|
|
asynOctet</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
The name of an XML file defining the PVAttributes and paramAttributes to be added
|
|
to each NDArray by this driver or plugin. The format of the XML file is described
|
|
in the documentation for <a href="areaDetectorDoxygenHTML/classasyn_n_d_array_driver.html">
|
|
asynNDArrayDriver::readNDAttributesFile().</a></td>
|
|
<td>
|
|
ND_ATTRIBUTES_FILE</td>
|
|
<td>
|
|
$(P)$(R)NDAttributesFile</td>
|
|
<td>
|
|
waveform</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center" colspan="7">
|
|
<b>Array pool status</b></td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
NDPoolMaxMemory</td>
|
|
<td>
|
|
asynFloat64</td>
|
|
<td>
|
|
r/o</td>
|
|
<td>
|
|
The maximum number of NDArrayPool memory bytes that can be allocated. 0=unlimited.
|
|
</td>
|
|
<td>
|
|
POOL_MAX_MEMORY</td>
|
|
<td>
|
|
$(P)$(R)PoolMaxMem</td>
|
|
<td>
|
|
ai</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
NDPoolUsedMemory</td>
|
|
<td>
|
|
asynFloat64</td>
|
|
<td>
|
|
r/o</td>
|
|
<td>
|
|
The number of NDArrayPool memory bytes currently allocated. The SCAN rate of this
|
|
record controls the scanning of all of the dynamic NDArrayPool status records.
|
|
</td>
|
|
<td>
|
|
POOL_USED_MEMORY</td>
|
|
<td>
|
|
$(P)$(R)PoolUsedMem</td>
|
|
<td>
|
|
ai</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
NDPoolMaxBuffers</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/o</td>
|
|
<td>
|
|
The maximum number of NDArrayPool buffers that can be allocated. 0=unlimited.</td>
|
|
<td>
|
|
POOL_MAX_BUFFERS</td>
|
|
<td>
|
|
$(P)$(R)PoolMaxBuffers</td>
|
|
<td>
|
|
longin</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
NDPoolAllocBuffers</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/o</td>
|
|
<td>
|
|
The number of NDArrayPool buffers currently allocated.</td>
|
|
<td>
|
|
POOL_ALLOC_BUFFERS</td>
|
|
<td>
|
|
$(P)$(R)PoolAllocBuffers</td>
|
|
<td>
|
|
longin</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
NDPoolFreeBuffers</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/o</td>
|
|
<td>
|
|
The number of NDArrayPool buffers currently allocated but free.</td>
|
|
<td>
|
|
POOL_FREE_BUFFERS</td>
|
|
<td>
|
|
$(P)$(R)PoolFreeBuffers</td>
|
|
<td>
|
|
longin</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
N.A.</td>
|
|
<td>
|
|
N.A.</td>
|
|
<td>
|
|
r/o</td>
|
|
<td>
|
|
The number of NDArrayPool buffers currently in use. This is calculated as NDPoolAllocBuffers
|
|
- NDPoolFreeBuffers.</td>
|
|
<td>
|
|
N.A.</td>
|
|
<td>
|
|
$(P)$(R)PoolUsedBuffers</td>
|
|
<td>
|
|
calc</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center" colspan="7">
|
|
<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>
|
|
<h3 id="ADDriver">
|
|
ADDriver</h3>
|
|
<p>
|
|
ADDriver inherits from asynNDArrayDriver. This is the class from which area detector
|
|
drivers are directly derived. It provides parameters and methods that are specific
|
|
to area detectors, while asynNDArrayDriver is a general NDArray driver. The <a href="areaDetectorDoxygenHTML/class_a_d_driver.html">
|
|
ADDriver class documentation </a>describes this class in detail.
|
|
</p>
|
|
<p>
|
|
The file <a href="areaDetectorDoxygenHTML/_a_d_driver_8h.html">ADDriver.h</a> defines
|
|
the parameters that all areaDetector drivers should implement if possible.
|
|
</p>
|
|
<table border="1" cellpadding="2" cellspacing="2" style="text-align: left">
|
|
<tbody>
|
|
<tr>
|
|
<td align="center" colspan="7">
|
|
<b>Parameter Definitions in ADDriver.h and EPICS Record Definitions in ADBase.template</b>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th>
|
|
Parameter index variable</th>
|
|
<th>
|
|
asyn interface</th>
|
|
<th>
|
|
Access</th>
|
|
<th>
|
|
Description</th>
|
|
<th>
|
|
drvInfo string</th>
|
|
<th>
|
|
EPICS record name</th>
|
|
<th>
|
|
EPICS record type</th>
|
|
</tr>
|
|
<tr>
|
|
<td align="center" colspan="7" style="height: 25px">
|
|
<b>Information about the detector</b></td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
ADManufacturer</td>
|
|
<td>
|
|
asynOctet</td>
|
|
<td>
|
|
r/o</td>
|
|
<td>
|
|
Detector manufacturer name</td>
|
|
<td>
|
|
MANUFACTURER</td>
|
|
<td>
|
|
$(P)$(R)Manufacturer_RBV</td>
|
|
<td>
|
|
stringin</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
ADModel</td>
|
|
<td>
|
|
asynOctet</td>
|
|
<td>
|
|
r/o</td>
|
|
<td>
|
|
Detector model name</td>
|
|
<td>
|
|
MODEL</td>
|
|
<td>
|
|
$(P)$(R)Model_RBV</td>
|
|
<td>
|
|
stringin</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
ADMaxSizeX</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/o</td>
|
|
<td>
|
|
Maximum (sensor) size in the X direction</td>
|
|
<td>
|
|
MAX_SIZE_X</td>
|
|
<td>
|
|
$(P)$(R)MaxSizeX_RBV</td>
|
|
<td>
|
|
longin</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
ADMaxSizeY</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/o</td>
|
|
<td>
|
|
Maximum (sensor) size in the Y direction</td>
|
|
<td>
|
|
MAX_SIZE_Y</td>
|
|
<td>
|
|
$(P)$(R)MaxSizeY_RBV</td>
|
|
<td>
|
|
longin</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
ADTemperature</td>
|
|
<td>
|
|
asynFloat64</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
Detector temperature</td>
|
|
<td>
|
|
TEMPERATURE</td>
|
|
<td>
|
|
$(P)$(R)Temperature<br />
|
|
$(P)$(R)Temperature_RBV<br />
|
|
</td>
|
|
<td>
|
|
ao<br />
|
|
ai</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
ADTemperatureActual</td>
|
|
<td>
|
|
asynFloat64</td>
|
|
<td>
|
|
r/o</td>
|
|
<td>
|
|
Actual detector temperature</td>
|
|
<td>
|
|
TEMPERATURE_ACTUAL</td>
|
|
<td>
|
|
$(P)$(R)Temperature_Actual </td>
|
|
<td>
|
|
ai</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center" colspan="7">
|
|
<b>Detector readout control including gain, binning, region start and size, reversal</b>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
ADGain</td>
|
|
<td>
|
|
asynFloat64</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
Detector gain</td>
|
|
<td>
|
|
GAIN</td>
|
|
<td>
|
|
$(P)$(R)Gain<br />
|
|
$(P)$(R)Gain_RBV</td>
|
|
<td>
|
|
ao<br />
|
|
ai</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
ADBinX</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
Binning in the X direction</td>
|
|
<td>
|
|
BIN_X</td>
|
|
<td>
|
|
$(P)$(R)BinX<br />
|
|
$(P)$(R)BinX_RBV</td>
|
|
<td>
|
|
longout<br />
|
|
longin</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
ADBinY</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
Binning in the Y direction</td>
|
|
<td>
|
|
BIN_Y</td>
|
|
<td>
|
|
$(P)$(R)BinY<br />
|
|
$(P)$(R)BinY_RBV</td>
|
|
<td>
|
|
longout<br />
|
|
longin</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
ADMinX</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
First pixel to read in the X direction.
|
|
<br />
|
|
0 is the first pixel on the detector.</td>
|
|
<td>
|
|
MIN_X</td>
|
|
<td>
|
|
$(P)$(R)MinX<br />
|
|
$(P)$(R)MinX_RBV</td>
|
|
<td>
|
|
longout<br />
|
|
longin</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
ADMinY</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
First pixel to read in the Y direction.<br />
|
|
0 is the first pixel on the detector.</td>
|
|
<td>
|
|
MIN_Y</td>
|
|
<td>
|
|
$(P)$(R)MinY<br />
|
|
$(P)$(R)MinY_RBV</td>
|
|
<td>
|
|
longout<br />
|
|
longin</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
ADSizeX</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
Size of the region to read in the X direction</td>
|
|
<td>
|
|
SIZE_X</td>
|
|
<td>
|
|
$(P)$(R)SizeX<br />
|
|
$(P)$(R)SizeX_RBV</td>
|
|
<td>
|
|
longout<br />
|
|
longin</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
ADSizeY</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
Size of the region to read in the Y direction</td>
|
|
<td>
|
|
SIZE_Y</td>
|
|
<td>
|
|
$(P)$(R)SizeY<br />
|
|
$(P)$(R)SizeY_RBV</td>
|
|
<td>
|
|
longout<br />
|
|
longin</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
ADReverseX</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
Reverse array in the X direction<br />
|
|
(0=No, 1=Yes)</td>
|
|
<td>
|
|
REVERSE_X</td>
|
|
<td>
|
|
$(P)$(R)ReverseX<br />
|
|
$(P)$(R)ReverseX_RBV</td>
|
|
<td>
|
|
longout<br />
|
|
longin</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
ADReverseY</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
Reverse array in the Y direction<br />
|
|
(0=No, 1=Yes)</td>
|
|
<td>
|
|
REVERSE_Y</td>
|
|
<td>
|
|
$(P)$(R)ReverseY<br />
|
|
$(P)$(R)ReverseY_RBV</td>
|
|
<td>
|
|
longout<br />
|
|
longin</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center" colspan="7">
|
|
<b>Image and trigger modes</b></td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
ADImageMode</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
Image mode (ADImageMode_t).</td>
|
|
<td>
|
|
IMAGE_MODE</td>
|
|
<td>
|
|
$(P)$(R)ImageMode<br />
|
|
$(P)$(R)ImageMode_RBV</td>
|
|
<td>
|
|
mbbo<br />
|
|
mbbi</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
ADTriggerMode</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
Trigger mode (ADTriggerMode_t).</td>
|
|
<td>
|
|
TRIGGER_MODE</td>
|
|
<td>
|
|
$(P)$(R)TriggerMode<br />
|
|
$(P)$(R)TriggerMode_RBV</td>
|
|
<td>
|
|
mbbo<br />
|
|
mbbi</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center" colspan="7">
|
|
<b>Frame type</b></td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
ADFrameType</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
Frame type (ADFrameType_t).</td>
|
|
<td>
|
|
FRAME_TYPE</td>
|
|
<td>
|
|
$(P)$(R)FrameType<br />
|
|
$(P)$(R)FrameType_RBV</td>
|
|
<td>
|
|
mbbo<br />
|
|
mbbi</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center" colspan="7">
|
|
<b>Acquisition time and period</b></td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
ADAcquireTime</td>
|
|
<td>
|
|
asynFloat64</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
Acquisition time per image</td>
|
|
<td>
|
|
ACQ_TIME</td>
|
|
<td>
|
|
$(P)$(R)AcquireTime<br />
|
|
$(P)$(R)AcquireTime_RBV</td>
|
|
<td>
|
|
ao<br />
|
|
ai</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
ADAcquirePeriod</td>
|
|
<td>
|
|
asynFloat64</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
Acquisition period between images</td>
|
|
<td>
|
|
ACQ_PERIOD</td>
|
|
<td>
|
|
$(P)$(R)AcquirePeriod<br />
|
|
$(P)$(R)AcquirePeriod_RBV</td>
|
|
<td>
|
|
ao<br />
|
|
ai</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center" colspan="7">
|
|
<b>Number of exposures and number of images</b></td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
ADNumExposures</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
Number of exposures per image to acquire</td>
|
|
<td>
|
|
NEXPOSURES</td>
|
|
<td>
|
|
$(P)$(R)NumExposures<br />
|
|
$(P)$(R)NumExposures_RBV</td>
|
|
<td>
|
|
longout<br />
|
|
longin</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
ADNumImages</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
Number of images to acquire in one acquisition sequence</td>
|
|
<td>
|
|
NIMAGES</td>
|
|
<td>
|
|
$(P)$(R)NumImages<br />
|
|
$(P)$(R)NumImages_RBV</td>
|
|
<td>
|
|
longout<br />
|
|
longin</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center" colspan="7">
|
|
<b>Acquisition control</b></td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
ADAcquire</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
Start (1) or stop (0) image acquisition. This is an EPICS busy record that does
|
|
not process its forward link until acquisition is complete. Clients should write
|
|
1 to the Acquire record to start acquisition, and wait for Acquire to go to 0 to
|
|
know that acquisition is complete.</td>
|
|
<td>
|
|
ACQUIRE</td>
|
|
<td>
|
|
$(P)$(R)Acquire<br />
|
|
$(P)$(R)Acquire_RBV</td>
|
|
<td>
|
|
busy<br />
|
|
bi</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center" colspan="7">
|
|
<b>Status information</b></td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
ADStatus</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/o</td>
|
|
<td>
|
|
Acquisition status (ADStatus_t)</td>
|
|
<td>
|
|
STATUS</td>
|
|
<td>
|
|
$(P)$(R)DetectorState_RBV</td>
|
|
<td>
|
|
mbbi</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
ADStatusMessage</td>
|
|
<td>
|
|
asynOctet</td>
|
|
<td>
|
|
r/o</td>
|
|
<td>
|
|
Status message string</td>
|
|
<td>
|
|
STATUS_MESSAGE</td>
|
|
<td>
|
|
$(P)$(R)StatusMessage_RBV</td>
|
|
<td>
|
|
waveform</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
ADStringToServer</td>
|
|
<td>
|
|
asynOctet</td>
|
|
<td>
|
|
r/o</td>
|
|
<td>
|
|
String from driver to string-based vendor server</td>
|
|
<td>
|
|
STRING_TO_SERVER</td>
|
|
<td>
|
|
$(P)$(R)StringToServer_RBV</td>
|
|
<td>
|
|
waveform</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
ADStringFromServer</td>
|
|
<td>
|
|
asynOctet</td>
|
|
<td>
|
|
r/o</td>
|
|
<td>
|
|
String from string-based vendor server to driver</td>
|
|
<td>
|
|
STRING_FROM_SERVER</td>
|
|
<td>
|
|
$(P)$(R)StringFromServer_RBV</td>
|
|
<td>
|
|
waveform</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
ADNumExposuresCounter</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/o</td>
|
|
<td>
|
|
Counter that increments by 1 each time an exposure is acquired for the current image.
|
|
Driver resets to 0 when acquisition is started.</td>
|
|
<td>
|
|
NUM_EXPOSURES_COUNTER</td>
|
|
<td>
|
|
$(P)$(R)NumExposuresCounter_RBV</td>
|
|
<td>
|
|
longin</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
ADNumImagesCounter</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/o</td>
|
|
<td>
|
|
Counter that increments by 1 each time an image is acquired in the current acquisition
|
|
sequence. Driver resets to 0 when acquisition is started. Drivers can use this as
|
|
the loop counter when ADImageMode=ADImageMultiple.</td>
|
|
<td>
|
|
NUM_IMAGES_COUNTER</td>
|
|
<td>
|
|
$(P)$(R)NumImagesCounter_RBV</td>
|
|
<td>
|
|
longin</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
ADTimeRemaining</td>
|
|
<td>
|
|
asynFloat64</td>
|
|
<td>
|
|
r/o</td>
|
|
<td>
|
|
Time remaining for current image. Drivers should update this value if they are doing
|
|
the exposure timing internally, rather than in the detector hardware.</td>
|
|
<td>
|
|
TIME_REMAINING</td>
|
|
<td>
|
|
$(P)$(R)TimeRemaining_RBV</td>
|
|
<td>
|
|
ai</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
ADReadStatus</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
Write a 1 to this parameter to force a read of the detector status. Detector drivers
|
|
normally read the status as required, so this is usually not necessary, but there
|
|
may be some circumstances under which forcing a status read may be needed.</td>
|
|
<td>
|
|
READ_STATUS</td>
|
|
<td>
|
|
$(P)$(R)ReadStatus</td>
|
|
<td>
|
|
bo</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center" colspan="7">
|
|
<b>Shutter control</b></td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
ADShutterMode</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
Shutter mode (None, detector-controlled or EPICS-controlled) (ADShutterMode_t)
|
|
</td>
|
|
<td>
|
|
SHUTTER_MODE</td>
|
|
<td>
|
|
$(P)$(R)ShutterMode<br />
|
|
$(P)$(R)ShutterMode_RBV</td>
|
|
<td>
|
|
mbbo<br />
|
|
mbbi</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
ADShutterControl</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
Shutter control for the selected (detector or EPICS) shutter (ADShutterStatus_t)
|
|
</td>
|
|
<td>
|
|
SHUTTER_CONTROL</td>
|
|
<td>
|
|
$(P)$(R)ShutterControl<br />
|
|
$(P)$(R)ShutterControl_RBV</td>
|
|
<td>
|
|
bo<br />
|
|
bi</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
ADShutterControlEPICS</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
This record processes when it receives a callback from the driver to open or close
|
|
the EPICS shutter. It triggers the records below to actually open or close the EPICS
|
|
shutter.</td>
|
|
<td>
|
|
SHUTTER_CONTROL_EPICS</td>
|
|
<td>
|
|
$(P)$(R)ShutterControlEPICS</td>
|
|
<td>
|
|
bi</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
N/A</td>
|
|
<td>
|
|
N/A</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
This record writes its OVAL field to its OUT field when the EPICS shutter is told
|
|
to open. The OCAL (and hence OVAL) and OUT fields are user-configurable, so any
|
|
EPICS-controllable shutter can be used.</td>
|
|
<td>
|
|
N/A</td>
|
|
<td>
|
|
$(P)$(R)ShutterOpenEPICS</td>
|
|
<td>
|
|
calcout</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
N/A</td>
|
|
<td>
|
|
N/A</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
This record writes its OVAL field to its OUT field when the EPICS shutter is told
|
|
to close. The OCAL (and hence OVAL) and OUT fields are user-configurable, so any
|
|
EPICS-controllable shutter can be used.</td>
|
|
<td>
|
|
N/A</td>
|
|
<td>
|
|
$(P)$(R)ShutterCloseEPICS</td>
|
|
<td>
|
|
calcout</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
ADShutterStatus</td>
|
|
<td>
|
|
asynInt32</td>
|
|
<td>
|
|
r/o</td>
|
|
<td>
|
|
Status of the detector-controlled shutter (ADShutterStatus_t)</td>
|
|
<td>
|
|
SHUTTER_STATUS</td>
|
|
<td>
|
|
$(P)$(R)ShutterStatus_RBV</td>
|
|
<td>
|
|
bi</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
N/A</td>
|
|
<td>
|
|
N/A</td>
|
|
<td>
|
|
r/o</td>
|
|
<td>
|
|
Status of the EPICS-controlled shutter. This record should have its input link (INP)
|
|
set to a record that contains the open/close status information for the shutter.
|
|
The link should have the "CP" attribute, so this record processes when the input
|
|
changes. The ZRVL field should be set to the value of the input link when the shutter
|
|
is closed, and the ONVL field should be set to the value of the input link when
|
|
the shutter is open.</td>
|
|
<td>
|
|
N/A</td>
|
|
<td>
|
|
$(P)$(R)ShutterStatusEPICS_RBV</td>
|
|
<td>
|
|
mbbi</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
ADShutterOpenDelay</td>
|
|
<td>
|
|
asynFloat64</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
Time required for the shutter to actually open (ADShutterStatus_t)</td>
|
|
<td>
|
|
SHUTTER_OPEN_DELAY</td>
|
|
<td>
|
|
$(P)$(R)ShutterOpenDelay<br />
|
|
$(P)$(R)ShutterOpenDelay_RBV</td>
|
|
<td>
|
|
ao<br />
|
|
ai</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
ADShutterCloseDelay</td>
|
|
<td>
|
|
asynFloat64</td>
|
|
<td>
|
|
r/w</td>
|
|
<td>
|
|
Time required for the shutter to actually close (ADShutterStatus_t)</td>
|
|
<td>
|
|
SHUTTER_CLOSE_DELAY</td>
|
|
<td>
|
|
$(P)$(R)ShutterCloseDelay<br />
|
|
$(P)$(R)ShutterCloseDelay_RBV</td>
|
|
<td>
|
|
ao<br />
|
|
ai</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<h2 id="Guidelines">
|
|
Guidelines and rules for drivers</h2>
|
|
<p>
|
|
The following are guidelines and rules for writing areaDetector drivers</p>
|
|
<ul>
|
|
<li>Drivers will generally implement one or more of the writeInt32(), writeFloat64()
|
|
or writeOctet() functions if they need to act immediately on a new value of a parameter.
|
|
For many parameters it is normally sufficient to simply have them written to the
|
|
parameter library, and not to handle them in the writeXXX() functions. The parameters
|
|
are then retrieved from the parameter library with the getIntParam(), getDoubleParam(),
|
|
or getStringParam() function calls when they are needed.</li>
|
|
<li>If the writeInt32(), writeFloat64() or writeOctet() functions are implemented
|
|
they <b>must</b> call the base class function for parameters that they do not handle
|
|
and whose parameter index value is less than the first parameter of this class,
|
|
i.e. parameters that belong to a base class.</li>
|
|
<li>Drivers will need to call the createParam() function in their constructor if they
|
|
have additional parameters beyond those in the asynPortDriver or ADDriver base classes.</li>
|
|
<li>Drivers will generally need to create a new thread in which they run the acquisition
|
|
task. Some vendor libraries create such a thread themselves, and then the driver
|
|
must just implement a callback function that runs in that thread (the Prosilica
|
|
is an example of such a driver).</li>
|
|
<li>The acquisition thread will typically monitor the acquisition process and perform
|
|
periodic status update callbacks. The details of how to implement this will vary
|
|
depending on the specifics of the vendor API. There are many existing detector drivers
|
|
that can be used as examples of how to write a new driver.</li>
|
|
<li>If the detector hardware does not support fixed-period acquisition or muliple-image
|
|
acquisition sequence (ADNumImages parameter) then these should be emulated in the
|
|
driver. The simDetector, marCCD and other drivers can be used as examples of how
|
|
to do this.</li>
|
|
<li>If NDArrayCallbacks is non-zero then drivers should do the following:
|
|
<ul>
|
|
<li>Call asynNDArrayDriver::getAttributes to attach any attributes defined for this
|
|
driver to the current array.</li>
|
|
<li>Call doCallbacksGenericPointer() so that registered clients can get the values
|
|
of the new arrays. Drivers must release their mutex by calling this->unlock() before
|
|
they call doCallbacksGenericPointer(), or a deadlock can occur if the plugin makes
|
|
a call to one of the driver functions.</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
<h2 id="MEDM_screens">
|
|
MEDM screens</h2>
|
|
<p>
|
|
The following is the top-level MEDM screen that provides links to the screens for
|
|
most of the detectors and plugins that areaDetector supports. This screen is useful
|
|
for testing, and as a source for copying related-display menus to be placed in application-specific
|
|
MEDM screens.
|
|
</p>
|
|
<div style="text-align: center">
|
|
<p>
|
|
<b>ADTop.adl</b></p>
|
|
<img alt="ADTop.png" src="ADTop.png" /></div>
|
|
<p>
|
|
The following is the MEDM screen that provides access to the parameters in asynNDArrayDriver.h
|
|
and ADDriver.h through records in ADBase.template. This is a top-level MEDM screen
|
|
that will work with any areaDetector driver. Note however that many drivers will
|
|
not implement all of these parameters, and there will usually be detector-specific
|
|
parameters not shown in this screen, so detector-specific MEDM screens should generally
|
|
be created that display the EPICS PVs for the features implemented for that detector.
|
|
</p>
|
|
<div style="text-align: center">
|
|
<p>
|
|
<b>ADBase.adl</b></p>
|
|
<img alt="ADBase.png" src="ADBase.png" /></div>
|
|
<p>
|
|
The following is the MEDM screen that provides access to the file-related parameters
|
|
in asynNDArrayDriver.h through records in NDFile.template. This screen is for use
|
|
with detector drivers that directly implement file I/O.
|
|
</p>
|
|
<div style="text-align: center">
|
|
<p>
|
|
<b>NDFile.adl</b></p>
|
|
<img alt="NDFile.png" src="NDFile.png" /></div>
|
|
<p>
|
|
The following is the MEDM screen that provides access to the EPICS shutter parameters
|
|
in ADDriver.h through records in ADBase.template. This screen allows one to define
|
|
the EPICS PVs to open the shutter, close the shutter, and determine the shutter
|
|
status. The values of these PVs for open and close drive and status can also be
|
|
defined. Note that in many cases the same PV will be used for open and close drive,
|
|
but in some cases (e.g. APS safety shutters) different PVs are used for open and
|
|
close.
|
|
</p>
|
|
<div style="text-align: center">
|
|
<p>
|
|
<b>ADEpicsShutter.adl</b></p>
|
|
<img alt="ADEpicsShutter.png" src="ADEpicsShutter.png" /></div>
|
|
<h2 id="Installation">
|
|
Installation, configuration, and running</h2>
|
|
<h3>
|
|
Installation: source code version</h3>
|
|
<p>
|
|
After obtaining a copy of the distribution, it must be installed and built for use
|
|
at your site. These steps only need to be performed once for the site (unless versions
|
|
of the module running under different releases of EPICS and/or the other required
|
|
modules are needed).</p>
|
|
<ol>
|
|
<li>Create an installation directory for the module, usually this will end with<br />
|
|
<br />
|
|
<tt>.../support/</tt>
|
|
<br />
|
|
</li>
|
|
<li>Place the distribution file in this directory. Then issue the commands (Unix style)
|
|
<pre>tar xvzf areaDetectorRX-Y.tgz
|
|
|
|
</pre>
|
|
where X-Y is the release.</li>
|
|
<li>This creates a <top> application.<br />
|
|
<pre>.../support/areaDetectorRX-Y
|
|
</pre>
|
|
</li>
|
|
<li>Download all required supporting modules if you don't already have them. This
|
|
includes asyn, autosave, busy, etc.</li>
|
|
<li>Edit the <tt>configure/RELEASE</tt> file and set the paths to your installation
|
|
of EPICS base and to your versions of supporting modules.</li>
|
|
<li>Run <tt>gnumake</tt> in the top level directory and check for any compilation
|
|
errors.</li>
|
|
</ol>
|
|
<h3>
|
|
Installation: prebuilt version</h3>
|
|
<p>
|
|
Prebuilt versions of areaDetector are provide for Windows (win32-x86), Cygwin (cygwin-x86),
|
|
and Linux (linux-x86). Follow these steps to use the prebuilt version:</p>
|
|
<ol>
|
|
<li>Create an installation directory for the module. On Windows I typically use C:\EPICS\support.
|
|
On Linux I typically use /home/ACCOUNT/epics/support, where ACCOUNT is the name
|
|
of the account that is normally used to run the detector software, e.g. marccd on
|
|
a marCCD detector, mar345 on a mar345 detector, etc.</li>
|
|
<li>Place the distribution file in this directory. Then issue the commands (Unix style)
|
|
<pre>tar xvzf areaDetectorPrebuilt_RX-Y.tgz</pre>
|
|
</li>
|
|
<li>In the iocBoot directory make a <b>copy</b> of the example ioxXXX directory for
|
|
the detector you are using and give it a new local name. By doing this you will
|
|
be able to update to later versions of areaDetector without overwriting modifications
|
|
you make in the iocXXX directory.</li>
|
|
<li>In the new iocXXX directory you just created edit st.cmd to change the PV prefix
|
|
$(P) to one that is unique to your site. PV prefixes must be unique on the subnet,
|
|
and if you use the default prefix there could be a conflict with other detectors
|
|
of the same type. </li>
|
|
<li>In the same iocXXX directory edit the file envPaths to point to the locations
|
|
of all of the support modules on your system. Normally this is handled by the EPICS
|
|
build system, but when using the prebuilt version this must be manually edited.
|
|
Do not worry about the path to EPICS_BASE, it is not required.</li>
|
|
</ol>
|
|
<h3>
|
|
Installation: medm</h3>
|
|
<p>
|
|
areaDetector provides display/control screens for the <a href="http://www.aps.anl.gov/epics/extensions/medm/">
|
|
medm</a> Motif Editor and Display Manager. A prebuilt version of medm for Windows
|
|
can be found in the <a href="http://www.aps.anl.gov/epics/distributions/win32/">EPICS
|
|
WIN32 Extensions</a>. For Linux one can build medm from source code, which requires
|
|
downloading and building <a href="http://www.aps.anl.gov/epics/base/">EPICS base</a>
|
|
first. Alternatively I provide a prebuilt version of medm for Linux in the <a href="http://cars.uchicago.edu/software/pub/EPICS_Linux_binaries.tar">
|
|
EPICS_Linux_binraries.tar</a> package. To use this version copy the medm executable
|
|
to some location in your PATH, e.g. /usr/local/bin, or ~/bin, etc. Copy the 2 shareable
|
|
libraries libCom.so and libca.so to a location which is in your LD_LIBRARY_PATH.
|
|
To use either the source code or prebuilt version you need to have the OpenMotif
|
|
package installed. This typically is <b>not</b> installed by default with recent
|
|
versions of Linux. Go to <a href="http://www.openmotif.org/">www.openmotif.org</a>
|
|
and download and install the appropriate RPM package for your Linux version.</p>
|
|
<h3>
|
|
Configuration</h3>
|
|
<p>
|
|
Before running an areaDetector application it is usually necessary to configure
|
|
a number of items.</p>
|
|
<ul>
|
|
<li>EPICS environment variables. There are several environment variables that EPICS
|
|
uses. I suggest setting these in the .cshrc (or .bashrc) file for the account that
|
|
will be used to run the detector.
|
|
<ul>
|
|
<li>EPICS_CA_AUTO_ADDR_LIST and EPICS_CA_ADDR_LIST. These variables control the IP
|
|
addresses that EPICS clients use when searching for EPICS PVs. The default is EPICS_CA_AUTO_ADDR_LIST=YES
|
|
and EPICS_CA_ADDR_LIST to be the broadcast address of all networks connected to
|
|
the host. Some detectors, for example the marCCD and mar345, come with 2 network
|
|
cards, which are on 2 different subnets, typically a private one connected to the
|
|
detector and a public one connected to the local LAN. If the default value of these
|
|
variables is used then EPICS clients (e.g. medm) running on the detector host computer
|
|
will generate many errors because each EPICS PV will appear to be coming from both
|
|
networks. The solution is to set these variables as follows:
|
|
<pre> setenv EPICS_CA_AUTO_ADDR_LIST NO
|
|
setenv EPICS_CA_ADDR_LIST localhost:XX.YY.ZZ.255
|
|
</pre>
|
|
where XX.YY.ZZ.255 should be replaced with the broadcast address for the public
|
|
network on this computer.</li>
|
|
<li>EPICS_CA_MAX_ARRAY_BYTES. This variable controls the maximum array size that EPICS
|
|
can transmit with Channel Access. The default is only 16kB, which is much too small
|
|
for most detector data. This value must be set to a large enough value on both the
|
|
EPICS server computer (e.g. the one running the areaDetector IOC) and client computer
|
|
(e.g. the one running medm, ImageJ, IDL, etc.). This can simply be set to a very
|
|
large value like 100MB.
|
|
<pre> setenv EPICS_CA_MAX_ARRAY_BYTES 100000000
|
|
</pre>
|
|
</li>
|
|
<li>EPICS_DISPLAY_PATH. This variable controls where medm looks for .adl display files.
|
|
If the recommendation below is followed to copy all adl files to a single directory,
|
|
then this environment variable should be defined to point to that directory. For
|
|
example:
|
|
<pre> setenv EPICS_DISPLAY_PATH /home/mar345/epics/adls
|
|
</pre>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li>medm display files. I find it convenient to copy all medm .adl files to a single
|
|
directory and then point the environment variable EPICS_DISPLAY_PATH to this directory.
|
|
The alternative is to point EPICS_DISPLAY_PATH to a long list of directories where
|
|
the adl files are located in the distributions, which is harder to maintain. On
|
|
the mar345, for example, I create a directory called /home/mar345/epics/adls, where
|
|
I put all of the adl files. To simplify copying the adl files to that location I
|
|
use the following one-line script, which I place in /home/mar345/bin/sync_adls.
|
|
<pre> find /home/mar345/epics/support -name '*.adl' -exec cp -fv {} /home/mar345/epics/adls \;
|
|
</pre>
|
|
This script finds all adl files in the epics/support tree and copies them to /home/mar345/epics/adls.
|
|
That directory must be created before running this script. Similar scripts can be
|
|
used for other Linux detectors (marCCD, Pilatus, etc.) and can be used on Windows
|
|
as well if Cygwin is installed. Each time a new release of areaDetector is installed
|
|
remove the old versions of each support module (areaDetector, asyn, autosave, etc.)
|
|
and then run this script to install the latest medm files. </li>
|
|
</ul>
|
|
<h3>
|
|
Running the IOC</h3>
|
|
<p>
|
|
Each example IOC directory comes with a Linux script (start_epics) or a Windows
|
|
batch file (start_epics.bat) or both depending on the architectures that the detector
|
|
runs on. These scripts provide simple examples of how to start medm and the EPICS
|
|
IOC. For example, for the mar345 iocBoot/iocMAR345/start_epics contains the following:</p>
|
|
<pre> medm -x -macro "P=13MAR345_1:, R=cam1:, I=image1:, ROI=ROI1:, NETCDF=netCDF1:, TIFF=TIFF1:, JPEG=JPEG1:, NEXUS=Nexus1:" mar345.adl &
|
|
../../bin/linux-x86/mar345App st.cmd
|
|
</pre>
|
|
<p>
|
|
This script starts medm in execute mode with the appropriate medm display file and
|
|
macro parameters, running it in the background. It then runs the IOC application.
|
|
This script assumes that iocBoot/iocMAR345 is the default directory when it is run,
|
|
which could be added to the command or set in the configuration if this script is
|
|
set as the target of a desktop shortcut, etc. The script assumes that EPICS_DISPLAY_PATH
|
|
has been defined to be a location where the mar345.adl and related displays that
|
|
it loads can be found. You will need to edit the script in your copy of the iocXXX
|
|
directory to change the prefix (P) from 13MAR345_1: to whatever prefix you chose
|
|
for your IOC. The start_epics script could also be copied to a location in your
|
|
PATH (e.g. /home/mar345/bin/start_epics). Add a command like <code>cd /home/mar345/epics/support/areaDetector/1-5/iocBoot/iocMAR345</code>
|
|
at the beginning of the script and then type <code>start_epics</code> from any directory
|
|
to start the EPICS IOC.</p>
|
|
<h2 id="Acknowledgments">
|
|
Acknowledgements and licenses</h2>
|
|
<p>
|
|
"This software is based in part on the work of the Independent JPEG Group".</p>
|
|
</body>
|
|
</html>
|