Minor changes
git-svn-id: https://subversion.xor.aps.anl.gov/synApps/areaDetector/trunk@7672 dc6c5ff5-0b8b-c028-a01f-ffb33f00fc8b
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
|
||||
"http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html lang="en-us" xmlns="http://www.w3.org/1999/xhtml">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>areaDetector ADSC driver</title>
|
||||
<meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type" />
|
||||
</head>
|
||||
<body>
|
||||
<center>
|
||||
<div style="text-align: center">
|
||||
<h1>
|
||||
areaDetector ADSC driver</h1>
|
||||
<h2>
|
||||
@@ -15,7 +15,7 @@
|
||||
Lewis Muir</h2>
|
||||
<h2>
|
||||
University of Chicago</h2>
|
||||
</center>
|
||||
</div>
|
||||
<h2>
|
||||
Table of Contents</h2>
|
||||
<ol>
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
<h2>
|
||||
University of Chicago</h2>
|
||||
</div>
|
||||
<p>
|
||||
</p>
|
||||
<h2>
|
||||
Contents</h2>
|
||||
<ul>
|
||||
@@ -71,9 +69,8 @@
|
||||
<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 an optional Region-Of-Interest (ROI) driver that performs computations
|
||||
on regions within the image data. A basic ROI driver is included in the module,
|
||||
and it is easy to add addtional ROI drivers for specific applications.</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, MAR-CCD x-ray detectors, MAR-345 online
|
||||
imaging plate detectors, the Pilatus pixel-array detector, and the Roper Scientific
|
||||
@@ -149,7 +146,8 @@
|
||||
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 API has the ability to save the data to a file.
|
||||
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
|
||||
@@ -168,8 +166,8 @@
|
||||
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>
|
||||
<h2 id="asynPortDriver">
|
||||
asynPortDriver</h2>
|
||||
<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
|
||||
@@ -432,8 +430,8 @@ public:
|
||||
is a second version of <code>callParamCallbacks</code> that takes an argument specifying
|
||||
the parameter list number, and the asyn address to match.
|
||||
</p>
|
||||
<h2 id="NDArray">
|
||||
NDArray</h2>
|
||||
<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. The NDArray class is defined as follows:
|
||||
@@ -513,7 +511,7 @@ public:
|
||||
first element of the detector in unbinned units. If a selected region of the detector
|
||||
is being read, then this value may be > 0. The offset value is cumulative, so
|
||||
if a plugin such as NDPluginROI further selects a subregion, the offset is relative
|
||||
to the first element in the detector and not to the first element of the region
|
||||
to the first element in the detector, and not to the first element of the region
|
||||
passed to NDPluginROI.</li>
|
||||
<li><code>binning</code> is the binning (sumation of elements) in this dimension.
|
||||
The offset value is cumulative, so if a plugin such as NDPluginROI performs binning,
|
||||
@@ -531,8 +529,9 @@ public:
|
||||
as follows:
|
||||
</p>
|
||||
<ul>
|
||||
<li><code>uniqueId</code> This should be a number that uniquely identifies this array.
|
||||
Detector drivers should assign this number to the NDArray before calling the plugins.</li>
|
||||
<li><code>uniqueId</code> This should be a number that uniquely identifies this array,
|
||||
e.g. frame number. Detector drivers should assign this number to the NDArray before
|
||||
calling the plugins.</li>
|
||||
<li><code>timeStamp</code> This should be a timestamp value in seconds recording when
|
||||
the frame was collected. The time=0 reference is driver-dependent because of differences
|
||||
in vendor libraries. If there is a choice, it is recommended to use timeStamp=0
|
||||
@@ -568,8 +567,8 @@ public:
|
||||
<li><code>release</code>. This method calls NDArrayPool->release() for this object.
|
||||
It decreases the reference count for this array.</li>
|
||||
</ul>
|
||||
<h2 id="NDArrayPool">
|
||||
NDArrayPool</h2>
|
||||
<h3 id="NDArrayPool">
|
||||
NDArrayPool</h3>
|
||||
<p>
|
||||
The NDArrayPool class manages a free list (pool) of NDArray objects (described above).
|
||||
Drivers allocate NDArray objects from the pool, and pass these objects to plugins.
|
||||
@@ -628,8 +627,8 @@ public:
|
||||
<li><code>report</code> This method reports on the free list size and other properties
|
||||
of the NDArrayPool object.</li>
|
||||
</ul>
|
||||
<h2 id="asynNDArrayDriver">
|
||||
asynNDArrayDriver</h2>
|
||||
<h3 id="asynNDArrayDriver">
|
||||
asynNDArrayDriver</h3>
|
||||
<p>
|
||||
asynNDArrayDriver inherits from asynPortDriver. It implements the asynGenericPointer
|
||||
functions, assuming that these reference NDArray objects. This is the class from
|
||||
@@ -665,8 +664,8 @@ public:
|
||||
<li><code>report</code> This method calls the report function in the asynPortDriver
|
||||
base class. It then calls the NDArrayPool->report() method if details > 5.</li>
|
||||
</ul>
|
||||
<h2 id="ADDriver">
|
||||
ADDriver</h2>
|
||||
<h3 id="ADDriver">
|
||||
ADDriver</h3>
|
||||
<p>
|
||||
ADDriver inherits from asynNDArrayDriver. This is the class from which area detector
|
||||
drivers are directly derived. Its public interface is defined as follows:
|
||||
@@ -701,8 +700,8 @@ public:
|
||||
file name in the ADFullFileName parameter from the ADFilePath, ADFileName, ADFileNumber,
|
||||
and ADFileTemplate parameters.</li>
|
||||
</ul>
|
||||
<h2 id="ADStdDriverParams">
|
||||
ADStdDriverParams</h2>
|
||||
<h3 id="ADStdDriverParams">
|
||||
ADStdDriverParams</h3>
|
||||
<p>
|
||||
The file <code>ADStdDriverParams.h</code> defines the following:
|
||||
</p>
|
||||
@@ -761,18 +760,18 @@ typedef enum
|
||||
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 on path name 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 the path name from a string
|
||||
to an integer or byte array before sending the path name to EPICS. This is easy
|
||||
to do in clients like SPEC, Matlab, and IDL.</li>
|
||||
= 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 the path name from a string to an integer
|
||||
or byte array before sending the path name to EPICS. This is easy to do in clients
|
||||
like SPEC, Matlab, and IDL.</li>
|
||||
</ul>
|
||||
<p>
|
||||
Note that for parameters whose values are defined by enum values (e.g ADImageMode,
|
||||
ADTriggerMode, ADFileFormat, ADStatus), drivers can use a different set of enum
|
||||
values for these parameters. They can override the enum menu in ADBase.template
|
||||
with detector-specific choices by loading a detector-specific template file after
|
||||
loading ADBase.template.
|
||||
with detector-specific choices by loading a detector-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>
|
||||
@@ -1352,7 +1351,7 @@ typedef enum
|
||||
<td>
|
||||
r/o</td>
|
||||
<td>
|
||||
Full file name</td>
|
||||
Full file name constructed using the algorithm described in ADFileTemplate</td>
|
||||
<td>
|
||||
FULL_FILE_NAME</td>
|
||||
<td>
|
||||
@@ -1370,7 +1369,7 @@ typedef enum
|
||||
r/w</td>
|
||||
<td>
|
||||
Auto-increment flag. Controls whether FileNumber is automatically incremented by
|
||||
1 each time an acquisition completes (0=No, 1=Yes)</td>
|
||||
1 each time a file is saved (0=No, 1=Yes)</td>
|
||||
<td>
|
||||
AUTO_INCREMENT</td>
|
||||
<td>
|
||||
@@ -1388,7 +1387,8 @@ typedef enum
|
||||
<td>
|
||||
r/w</td>
|
||||
<td>
|
||||
Auto-save flag (0=No, 1=Yes)</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>
|
||||
@@ -1656,5 +1656,9 @@ typedef enum
|
||||
<li><a href="pilatusDoc.html">Pilatus driver</a></li>
|
||||
<li><a href="adscDoc.html">ADSC driver</a></li>
|
||||
</ul>
|
||||
<p>
|
||||
In addition to these drivers, Brian Tieman is writing a driver for the Perkin-Elmer
|
||||
flat-panel amorphous silicon detector. Drivers for the MAR-CCD, MAR-345 online image
|
||||
plate, and the Roper Scientific CCD cameras will be written in the near future.</p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<h1>
|
||||
areaDetector Pilatus driver</h1>
|
||||
<h2>
|
||||
September 17, 2008</h2>
|
||||
September 21, 2008</h2>
|
||||
<h2>
|
||||
Mark Rivers</h2>
|
||||
<h2>
|
||||
@@ -115,8 +115,8 @@
|
||||
<td>
|
||||
$(P$(R)ExposurePeriod</td>
|
||||
<td>
|
||||
Controls the exposure period in seconds. It is only in Internal or External Trigger
|
||||
modes when NumImages > 1.</td>
|
||||
Controls the exposure period in seconds. It applies only in Internal or External
|
||||
Trigger modes when NumImages > 1.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
@@ -159,17 +159,18 @@
|
||||
The areaDetector Pilatus driver only supports TIFF files, so the extension should
|
||||
be .tif. When saving multiple images (NImages>1) camserver has its own rules for
|
||||
creating the names of the individual files. The rules are as follows. The name constructed
|
||||
using the algorithm described for ADFileTemplate in <a href="areaDetectorDoc.html">
|
||||
areaDetectorDoc.html</a> is used as a basename. The following examples show the
|
||||
interpretation of the basename.
|
||||
<pre> Basename Files produced
|
||||
using the algorithm described for ADFileTemplate under <a href="areaDetectorDoc.html#ADStdDriverParams">
|
||||
File Saving Parameters in ADStdDriverParams</a> is used as a basename. The following
|
||||
examples show the interpretation of the basename.
|
||||
<pre>
|
||||
Basename Files produced
|
||||
|
||||
test6.tif test6_00000.tif, test6_00001.tif, ...
|
||||
test6_.tif test6_00000.tif, test6_00001.tif, ...
|
||||
test6_000.tif test6_000.tif, test6_001.tif, ...
|
||||
test6_014.tif test6_014.tif, test6_015.tif, ...
|
||||
test6_0008.tif test6_0008.tif, test6_0009.tif, ...
|
||||
test6_2_0035.tif test6_2_0035.tif, test6_2_0036.tif, ...
|
||||
test6.tif test6_00000.tif, test6_00001.tif, ...
|
||||
test6_.tif test6_00000.tif, test6_00001.tif, ...
|
||||
test6_000.tif test6_000.tif, test6_001.tif, ...
|
||||
test6_014.tif test6_014.tif, test6_015.tif, ...
|
||||
test6_0008.tif test6_0008.tif, test6_0009.tif, ...
|
||||
test6_2_0035.tif test6_2_0035.tif, test6_2_0036.tif, ...
|
||||
</pre>
|
||||
The numbers following the last '_' are taken as a format template, and as a start
|
||||
value. The minimum format is 3; there is no maximum; the default is 5. The format
|
||||
@@ -179,8 +180,8 @@
|
||||
</table>
|
||||
<p>
|
||||
It is useful to use NDPluginROI to define an ROI containing the entire Pilatus detector.
|
||||
This ROI can be monitored to make sure that the 20-bit limit of 1,048,575 is not
|
||||
being approached in any pixel.
|
||||
The MaxValue_RBV PV in this ROI can be monitored to make sure that the 20-bit limit
|
||||
of 1,048,575 is not being approached in any pixel.
|
||||
</p>
|
||||
<h2 id="Driver_parameters" style="text-align: left">
|
||||
Pilatus specific parameters</h2>
|
||||
@@ -317,24 +318,26 @@
|
||||
a valid bad pixel file then no bad pixel mapping is performed. The bad pixel map
|
||||
is used before making the NDArray callbacks. It does not modify the data in the
|
||||
files that camserver writes. This is a simple ASCII file with the following format:
|
||||
<pre> badX1,badY1 replacementX1,replacementY1
|
||||
badX2,badY2 replacementX2,replacementY2
|
||||
...
|
||||
</pre>
|
||||
<pre>
|
||||
badX1,badY1 replacementX1,replacementY1
|
||||
badX2,badY2 replacementX2,replacementY2
|
||||
...
|
||||
</pre>
|
||||
The X and Y coordinates range from 0 to NXPixels-1 and NYPixels-1. Up to 100 bad
|
||||
pixels can be defined. The bad pixel mapping simply replaces the bad pixels with
|
||||
another pixel's value. It does not do any averaging. It is felt that this is sufficient
|
||||
for the purpose for which pilatusROI was written, namely fast on-line viewing of
|
||||
ROIs and ImageData. More sophisticated algorithms can be used for offline analysis
|
||||
for the purpose for which this driver was written, namely fast on-line viewing of
|
||||
ROIs and image data. More sophisticated algorithms can be used for offline analysis
|
||||
of the image files themselves. The following is an example bad pixel file for a
|
||||
GSECARS detector:
|
||||
<pre> 263,3 262,3
|
||||
264,3 266,3
|
||||
263,3 266,3
|
||||
300,85 299,85
|
||||
300,86 299,86
|
||||
471,129 472,129
|
||||
</pre>
|
||||
<pre>
|
||||
263,3 262,3
|
||||
264,3 266,3
|
||||
263,3 266,3
|
||||
300,85 299,85
|
||||
300,86 299,86
|
||||
471,129 472,129
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
BAD_PIXEL_FILE</td>
|
||||
@@ -378,8 +381,9 @@
|
||||
All pixels with intensity < PilatusMinFlatField in the flat field are replaced with
|
||||
averageFlatField. When images are collected before the NDArray callbacks are performed
|
||||
the following per-pixel correction is applied:
|
||||
<pre> ImageData[i] = (averageFlatField * ImageData[i])/flatField[i];
|
||||
</pre>
|
||||
<pre>
|
||||
ImageData[i] = (averageFlatField * ImageData[i])/flatField[i];
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
FLAT_FIELD_FILE</td>
|
||||
@@ -453,8 +457,9 @@
|
||||
The Pilatus driver is created with the following command, either from C/C++ or from
|
||||
the EPICS IOC shell.
|
||||
</p>
|
||||
<pre> pilatusDetectorConfig(const char *portName, const char *camserverPort,
|
||||
int maxSizeX, int maxSizeY, int maxBuffers, size_t maxMemory);
|
||||
<pre>
|
||||
pilatusDetectorConfig(const char *portName, const char *camserverPort,
|
||||
int maxSizeX, int maxSizeY, int maxBuffers, size_t maxMemory);
|
||||
</pre>
|
||||
<table border="1" cellpadding="2" cellspacing="2" style="text-align: left">
|
||||
<tbody>
|
||||
@@ -600,8 +605,8 @@ create_monitor_set("auto_settings.req", 30,"P=13PIL1:,D=cam1:")
|
||||
Note that the general purpose screen ADBase.adl can be used, but it exposes many
|
||||
controls that are not applicable to the Pilatus.</p>
|
||||
<p>
|
||||
<code>pilatusDetector.adl</code> is the main screen used to control the pilatusROI
|
||||
SNL program. All records except those for ROIs are accessed through this screen.
|
||||
<code>pilatusDetector.adl</code> is the main screen used to control the Pilatus
|
||||
driver. All records except those for ROIs are accessed through this screen.
|
||||
</p>
|
||||
<div style="text-align: center">
|
||||
<h3 style="text-align: center">
|
||||
@@ -610,8 +615,8 @@ create_monitor_set("auto_settings.req", 30,"P=13PIL1:,D=cam1:")
|
||||
<p>
|
||||
<code>NDROI8.adl</code> is used to define the ROIs, and to display the statistics
|
||||
for each ROI. In this example there are 3 valid ROIs defined. ROI 0 is the entire
|
||||
detector. ROI 1 is a 100x50 rectangle starting at [300,60], and ROI 2 is a
|
||||
50x30 rectangle starting at [320,70]..</p>
|
||||
detector, ROI 1 is a 100x50 rectangle starting at [300,60], and ROI 2 is a 50x30
|
||||
rectangle starting at [320,70].</p>
|
||||
<div style="text-align: center">
|
||||
<h3 style="text-align: center">
|
||||
NDROI8.adl</h3>
|
||||
@@ -745,21 +750,21 @@ def user_getcounts '{
|
||||
Performance measurements</h2>
|
||||
<p>
|
||||
The following measurements were done to demonstrate the performance that can be
|
||||
obtained with pilatusROI.</p>
|
||||
obtained with the areaDetector Pilatus driver.</p>
|
||||
<ol>
|
||||
<li>AcquireMode=Internal, NImages=1000, ExposureTime=.005, ExposurePeriod=.01, NExposures=1.
|
||||
<li>AcquireMode=Internal, NumImages=1000, AcquireTime=.005, AcquirePeriod=.01, NumExposures=1.
|
||||
The time to collect this series should be exactly 10.0 seconds. The actual time
|
||||
was measured using the EPICS camonitor program. It printed the time when acquisition
|
||||
was started (Acquire changed to Busy) and when acquisition was complete (Acquire
|
||||
changed to Done). The time was 10.274 seconds. This includes the time for camserver
|
||||
was started (Acquire changed to Acquire=1) and when acquisition was complete (Acquire
|
||||
changed to Done=0). The time was 10.022 seconds. This includes the time for camserver
|
||||
to save all 1000 images to disk (366 MB), and for pilatusROI to read each file,
|
||||
correct the bad pixels and flat field, compute the ROIs, and post the ROIs to EPICS.
|
||||
It also posted the images to EPICS at 1Hz (10 images total). The total additional
|
||||
time was less than 0.3 seconds for all 1000 images.</li>
|
||||
It also posted all of the images to EPICS. The total additional time was less than
|
||||
0.03 seconds for all 1000 images.</li>
|
||||
<li>AcquireMode=Internal, NImages=1, ExposureTime=.01, NExposures=1. An EPICS sscan
|
||||
record was used to collect 1000 points. There were no positioner PVs (to eliminate
|
||||
motor overhead). The only detector trigger was the pilatusROI Acquire PV. The only
|
||||
detector PV was ROI1TotalCounts. In this mode camserver is being told to individually
|
||||
motor overhead). The only detector trigger was the Pilatus Acquire PV. The only
|
||||
detector PV was ROI1:0:Total_RBV. In this mode camserver is being told to individually
|
||||
collect each file. If there were no overhead then time to collect this series should
|
||||
be exactly 10.0 seconds. The actual time measured using the EPICS camonitor program
|
||||
was 49.161 seconds. The overhead is thus 39.161 seconds, or 39 ms per point. In
|
||||
|
||||
@@ -7,14 +7,12 @@
|
||||
<h1>
|
||||
areaDetector Prosilica driver</h1>
|
||||
<h2>
|
||||
September 17, 2008</h2>
|
||||
September 20, 2008</h2>
|
||||
<h2>
|
||||
Mark Rivers</h2>
|
||||
<h2>
|
||||
University of Chicago</h2>
|
||||
</div>
|
||||
<p>
|
||||
</p>
|
||||
<h2>
|
||||
Contents</h2>
|
||||
<ul>
|
||||
@@ -22,6 +20,7 @@
|
||||
<li><a href="#Performance measurements">Performance measurements</a></li>
|
||||
<li><a href="#Hardware notes">Hardware notes</a></li>
|
||||
<li><a href="#Restrictions">Restrictions</a></li>
|
||||
<li><a href="#Future">Future enhancements</a></li>
|
||||
</ul>
|
||||
<h2 id="Prosilica Driver">
|
||||
Prosilica Driver</h2>
|
||||
@@ -32,8 +31,8 @@
|
||||
to the Prosilica cameras. The driver is currently only supported under Windows (EPICS
|
||||
win32-x86 architecture) because the vendor library is provided as a Windows DLL.
|
||||
The vendor library provided by Prosilica does callbacks to a user-supplied function
|
||||
each time there is a new frame. Thus, it is not necessary to create a thread for
|
||||
callbacks in this driver.
|
||||
each time there is a new frame. Thus, the driver does not need to create a thread
|
||||
itself for callbacks.
|
||||
</p>
|
||||
<p>
|
||||
The vendor library supports saving individual frames as TIFF files, and this is
|
||||
@@ -246,7 +245,7 @@
|
||||
<td>
|
||||
Number of packets requested</td>
|
||||
<td>
|
||||
PS_PACKETS_RESENT</td>
|
||||
PS_PACKETS_REQUESTED</td>
|
||||
<td>
|
||||
$(P)$(R)PSPacketsRequested_RBV</td>
|
||||
<td>
|
||||
@@ -302,10 +301,21 @@
|
||||
prosilica.adl</h3>
|
||||
<img alt="prosilica.png" src="prosilica.png" /></div>
|
||||
<p>
|
||||
The following is an IDL epics_ad_display screen (discussed below) illustrating the
|
||||
Prosilica detector images.
|
||||
The following is an IDL <a href="http://cars.uchicago.edu/software/idl/imaging_routines.html#epics_ad_display">
|
||||
epics_ad_display</a> screen displaying the Prosilica detector images.
|
||||
</p>
|
||||
<div style="text-align: center">
|
||||
<h3>
|
||||
epics_ad_display.pro</h3>
|
||||
<img alt="prosilica_tvscl.jpg" src="prosilica_tvscl.jpg" /></div>
|
||||
<h2 id="Future">
|
||||
Future enhancements</h2>
|
||||
<p>
|
||||
The driver does not currently support color. This will be added in the near future.
|
||||
</p>
|
||||
<p>
|
||||
Work is needed on connection management. If the camera is unplugged or powered off
|
||||
which the areaDetector driver is running it does not gracefully recover.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<h1 style="text-align: center">
|
||||
areaDetector Simulation driver</h1>
|
||||
<h2>
|
||||
September 5, 2008</h2>
|
||||
September 20, 2008</h2>
|
||||
<h2>
|
||||
Mark Rivers</h2>
|
||||
<h2>
|
||||
@@ -22,7 +22,7 @@
|
||||
<li><a href="#Driver_parameters">Simulation driver specific parameters</a></li>
|
||||
<li><a href="#Unsupported">Unsupported standard driver parameters</a></li>
|
||||
<li><a href="#Screenshots">Screenshots</a></li>
|
||||
<li><a href="#Configuring">Configuring</a></li>
|
||||
<li><a href="#Configuration">Configuration</a></li>
|
||||
</ul>
|
||||
<h2 id="Introduction">
|
||||
Introduction</h2>
|
||||
@@ -35,27 +35,27 @@
|
||||
also very useful for testing plugins and channel access clients. This is part of
|
||||
the definition of the simDetector class:
|
||||
</p>
|
||||
<pre>
|
||||
class simDetector : public ADDriver {
|
||||
public:
|
||||
simDetector(const char *portName, int maxSizeX, int maxSizeY, NDDataType_t dataType,
|
||||
int maxBuffers, size_t maxMemory);
|
||||
|
||||
/* These are the methods that we override from ADDriver */
|
||||
virtual asynStatus writeInt32(asynUser *pasynUser, epicsInt32 value);
|
||||
virtual asynStatus writeFloat64(asynUser *pasynUser, epicsFloat64 value);
|
||||
virtual asynStatus drvUserCreate(asynUser *pasynUser, const char *drvInfo,
|
||||
const char **pptypeName, size_t *psize);
|
||||
void report(FILE *fp, int details);
|
||||
<pre>
|
||||
class simDetector : public ADDriver {
|
||||
public:
|
||||
simDetector(const char *portName, int maxSizeX, int maxSizeY, NDDataType_t dataType,
|
||||
int maxBuffers, size_t maxMemory);
|
||||
|
||||
/* These are the methods that we override from ADDriver */
|
||||
virtual asynStatus writeInt32(asynUser *pasynUser, epicsInt32 value);
|
||||
virtual asynStatus writeFloat64(asynUser *pasynUser, epicsFloat64 value);
|
||||
virtual asynStatus drvUserCreate(asynUser *pasynUser, const char *drvInfo,
|
||||
const char **pptypeName, size_t *psize);
|
||||
void report(FILE *fp, int details);
|
||||
</pre>
|
||||
<p>
|
||||
The portName, maxBuffers, and maxMemory arguments are passed to the ADDriver base
|
||||
class constructor. The maxSizeX, maxSizeY, and dataType arguments are specific to
|
||||
the simulation driver, controlling the maximum image size and initial data type
|
||||
of the computed images. The writeInt32 and writeFloat64 methods override those in
|
||||
the base class. The driver takes action when new parameters are passed via those
|
||||
interfaces. For example, the ADAcquire parameter (on the asynInt32 interface) is
|
||||
used to turn acquisition (i.e. computing new images) on and off.
|
||||
In the constructor <code>simDetector</code> the portName, maxBuffers, and maxMemory
|
||||
arguments are passed to the ADDriver base class constructor. The maxSizeX, maxSizeY,
|
||||
and dataType arguments are specific to the simulation driver, controlling the maximum
|
||||
image size and initial data type of the computed images. The writeInt32 and writeFloat64
|
||||
methods override those in the base class. The driver takes action when new parameters
|
||||
are passed via those interfaces. For example, the ADAcquire parameter (on the asynInt32
|
||||
interface) is used to turn acquisition (i.e. computing new images) on and off.
|
||||
</p>
|
||||
<p>
|
||||
The simulation driver initially sets the image[i, j] = i*gainX + j*gainY * gain
|
||||
@@ -73,19 +73,19 @@ public:
|
||||
is started that thread computes new images and then calls back any registered plugins
|
||||
as follows:
|
||||
</p>
|
||||
<pre>
|
||||
/* Put the frame number and time stamp into the buffer */
|
||||
pImage->uniqueId = imageCounter;
|
||||
pImage->timeStamp = startTime.secPastEpoch + startTime.nsec / 1.e9;
|
||||
|
||||
/* Call the NDArray callback */
|
||||
/* Must release the lock here, or we can get into a deadlock, because we can
|
||||
* block on the plugin lock, and the plugin can be calling us */
|
||||
epicsMutexUnlock(this->mutexId);
|
||||
asynPrint(this->pasynUser, ASYN_TRACE_FLOW,
|
||||
"%s:%s: calling imageData callback\n", driverName, functionName);
|
||||
doCallbacksGenericPointer(pImage, NDArrayData, addr);
|
||||
epicsMutexLock(this->mutexId);
|
||||
<pre>
|
||||
/* Put the frame number and time stamp into the buffer */
|
||||
pImage->uniqueId = imageCounter;
|
||||
pImage->timeStamp = startTime.secPastEpoch + startTime.nsec / 1.e9;
|
||||
|
||||
/* Call the NDArray callback */
|
||||
/* Must release the lock here, or we can get into a deadlock, because we can
|
||||
* block on the plugin lock, and the plugin can be calling us */
|
||||
epicsMutexUnlock(this->mutexId);
|
||||
asynPrint(this->pasynUser, ASYN_TRACE_FLOW,
|
||||
"%s:%s: calling imageData callback\n", driverName, functionName);
|
||||
doCallbacksGenericPointer(pImage, NDArrayData, addr);
|
||||
epicsMutexLock(this->mutexId);
|
||||
</pre>
|
||||
<h2 id="Driver_parameters">
|
||||
Simulation driver specific parameters</h2>
|
||||
@@ -95,7 +95,7 @@ public:
|
||||
<table style="text-align: left" "cellSpacing=2 cellPadding=2 border=1">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<td align="center" colspan="7">
|
||||
<b>Parameter Definitions in simDetector.cpp and EPICS Record Definitions in simDetector.template</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -183,46 +183,74 @@ public:
|
||||
<p>
|
||||
The following is the MEDM screen ADBase.adl connected to a simulation detector.
|
||||
</p>
|
||||
<p>
|
||||
<div style="text-align: center">
|
||||
<h3>
|
||||
ADBase.adl</h3>
|
||||
<img alt="ADBase_sim.png" src="ADBase_sim.png" />
|
||||
</p>
|
||||
</div>
|
||||
<p>
|
||||
The following is the MEDM screen that provides access to the specific parameters
|
||||
for the simulation detector.
|
||||
</p>
|
||||
<p>
|
||||
<div style="text-align: center">
|
||||
<h3>
|
||||
simDetector.adl</h3>
|
||||
<img alt="simDetector.png" src="simDetector.png" />
|
||||
</p>
|
||||
</div>
|
||||
<p>
|
||||
The following is an IDL epics_ad_display screen using image_display (discussed below)
|
||||
illustrating the simulation detector images.
|
||||
The following is an IDL <a href="http://cars.uchicago.edu/software/idl/imaging_routines.html#epics_ad_display">
|
||||
epics_ad_display</a> screen using <a href="http://cars.uchicago.edu/software/idl/imaging_routines.html#image_display">
|
||||
image_display</a> to display the simulation detector images.
|
||||
</p>
|
||||
<p>
|
||||
<div style="text-align: center">
|
||||
<h3>
|
||||
epics_ad_display.pro</h3>
|
||||
<img alt="simDetector_image_display.png" src="simDetector_image_display.png" />
|
||||
</p>
|
||||
<h2 id="Configuring">
|
||||
Configuring</h2>
|
||||
</div>
|
||||
<h2 id="Configuration">
|
||||
Configuration</h2>
|
||||
<p>
|
||||
This driver is configured via the <tt>simDetectorConfig()</tt> function. If this
|
||||
is to be used in an IOC, it must be called before <tt>iocInit()</tt>. It has the
|
||||
following syntax:
|
||||
</p>
|
||||
<dl>
|
||||
<dt><tt>int simDetectorConfig(const char *portName, int maxSizeX, int maxSizeY, int
|
||||
dataType, int maxBuffers, size_t maxMemory)</tt></dt>
|
||||
<dd>
|
||||
<dl>
|
||||
<dt><tt>portName</tt></dt>
|
||||
<dd>
|
||||
ASYN port name for the driver instance</dd>
|
||||
<dt><tt>maxSizeX</tt></dt>
|
||||
<dd>
|
||||
Maximum number of pixels in the X direction for the simulated detector</dd>
|
||||
<dt><tt>maxSizeY</tt></dt>
|
||||
<dd>
|
||||
Maximum number of pixels in the Y direction for the simulated detector</dd>
|
||||
<dt><tt>dataType</tt></dt>
|
||||
<dd>
|
||||
<pre>
|
||||
simDetectorConfig(const char *portName, int maxSizeX, int maxSizeY,
|
||||
int dataType, int maxBuffers, size_t maxMemory)
|
||||
</pre>
|
||||
<table border="1" cellpadding="2" cellspacing="2" style="text-align: left">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>
|
||||
Argument</th>
|
||||
<th>
|
||||
Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>portName</code></td>
|
||||
<td>
|
||||
The name of the asyn port for this detector.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>maxSizeX</code></td>
|
||||
<td>
|
||||
Maximum number of pixels in the X direction for the simulated detector.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>maxSizeY</code></td>
|
||||
<td>
|
||||
Maximum number of pixels in the Y direction for the simulated detector.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>dataType</code></td>
|
||||
<td>
|
||||
Initial data type of the detector data. These are the enum values for NDDataType_t,
|
||||
i.e.
|
||||
<ul>
|
||||
@@ -235,21 +263,29 @@ public:
|
||||
<li>6=NDFloat32</li>
|
||||
<li>7=NDFloat64</li>
|
||||
</ul>
|
||||
</dd>
|
||||
<dt><tt>maxBuffers</tt></dt>
|
||||
<dd>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>maxBuffers</code></td>
|
||||
<td>
|
||||
Maxiumum number of NDArray objects (image buffers) this driver is allowed to allocate.
|
||||
The driver itself requires 2 buffers, and each queue element in a plugin can require
|
||||
one buffer. So, for example, if 3 plugins are connected to this driver, and each
|
||||
has a queue size of 10, then maxBuffers should be at least 32.</dd>
|
||||
<dt><tt>maxMemory</tt></dt>
|
||||
<dd>
|
||||
has a queue size of 10, then maxBuffers should be at least 32.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>maxMemory</code></td>
|
||||
<td>
|
||||
Maxiumum number of bytes of memory for all NDArray objects (image buffers) allocated
|
||||
by this driver. If maxSizeX=maxSizeY=1024, and maxBuffers=32, then maxMemory should
|
||||
be at least 33554432 (~33MB).</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
be at least 33554432 (32MB).
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>
|
||||
If being used in an IOC, and an EPICS PV interface with the driver is desired, the
|
||||
<tt>ADBase.template</tt> and <tt>simDetector.template</tt> databases should also
|
||||
|
||||
Reference in New Issue
Block a user