diff --git a/documentation/adscDoc.html b/documentation/adscDoc.html index 1db16af..c4a8c33 100644 --- a/documentation/adscDoc.html +++ b/documentation/adscDoc.html @@ -1,349 +1,329 @@ - - - -areaDetector ADSC driver - - - - -
-

areaDetector ADSC driver

- -

September 5, 2008

-

Lewis Muir

-

University of Chicago

-
- -

Table of Contents

-
    -
  1. Introduction
  2. -
  3. Dependencies
  4. -
  5. Building
  6. -
  7. Configuring
  8. -
  9. Image Modes
  10. -
  11. Trigger Modes
  12. -
  13. Dark Images
  14. -
  15. Driver Specific Values and Settings
  16. -
  17. Screenshots
  18. -
  19. Unsupported areaDetector base - Features
  20. -
  21. Limitations
  22. -
- -

Introduction

- -

-This is a driver for ADSC detectors. -It has been tested with the ADSC Q210. While not yet tested with other -models, it should work with the ADSC Q4 (with the upgrade to four computers), -Q4r, Q210, Q210r, Q270, Q315, and Q315r. -

- -

Dependencies

- -

-This driver controls the detector via the detcon_lib_th detector -control library provided by ADSC. The detcon_lib_th library must -date from 2008-06-30 or newer. -

- -

Building

- -
    -
  1. Build the ADSC control library
  2. -
  3. Copy and rename, or create a symlink to, the ADSC auxlib.a -library so that it has the name libauxlib.a to satisfy the EPICS -build facility's requirement that a library file name start with -lib
  4. -
  5. Add DIRS += adscSrc to ADApp/Makefile
  6. -
  7. Set ADSC_HOME in ADApp/adscSrc/Makefile
  8. -
  9. Rebuild the areaDetector module
  10. -
- -

Configuring

- -

-This driver is configured via the adscConfig() function. If this is -to be used in an IOC, it must be called before iocInit(). It has the -following signature: -

- -
-
int adscConfig(const char *portName, const char *modelName)
-
-
-
portName
-
ASYN port name for the driver instance
-
modelName
-
ADSC detector model name; must be one of Q4, Q4r, - Q210, Q210r, Q270, Q315, - Q315r
-
-
-
- -

-The underlying ADSC control library obtains its configuration from the -environment. Therefore, the environment must be correctly configured (i.e. -ADSC environment variables set) for the ADSC control library before calling -adscConfig(). -

- -

-If being used in an IOC, and an EPICS PV interface with the driver is desired, -the ADBase.template and adsc.template databases should also -be loaded for the driver instance. -

- -

-An example IOC configuration for this driver is at -iocBoot/iocAdsc/st.cmd. -

- -

Image Modes

- -

Single

- -

-The Single mode acquires just one image. -

- -

Multiple

- -

-The Multiple mode acquires the number of images specified in -$(P)$(R)NumImages_RBV. -

- -

Continuous

- -

-The Continuous mode acquires images indefinitely until last -image is set. In this mode, the last image of the acquisition must be -signaled before exposing the last image by setting -$(P)$(R)ADSCLastImage to 1. This requirement is due to how -the underlying ADSC control library works. -

- -

Trigger Modes

- -

Internal

- -

-The Internal mode will make the driver expose images on its own once -the acquisition is started. -

- -

External

- -

-The External mode will make the driver expose images only when told -to once the acquisition is started. A special protocol must be followed to -trigger each image exposure. This would normally be very simple, but because -the ADSC control library can report that an exposure did not work and should -be retried after any exposure, a more complex protocol is required. -

- -

-The protocol is described in terms of the EPICS PV driver interface, but the -same rules apply if controlling the driver directly through ASYN. The -protocol is as follows: -

- -
    -
  1. Wait for $(P)$(R)ADSCOkToExpose to be Yes
  2. -
  3. Set $(P)$(R)ADSCExTrCtl to Start to start the -exposure
  4. -
  5. Set $(P)$(R)ADSCExTrCtl to Stop to stop the -exposure
  6. -
  7. Wait for $(P)$(R)ADSCExTrCtl_RBV to be OK or -Again
  8. -
  9. If $(P)$(R)ADSCExTrCtl_RBV is Again, the exposure did -not work and should be tried again
  10. -
- -

-Note that care must be taken when waiting for $(P)$(R)ADSCExTrCtl_RBV -to be OK or Again to ensure the PV value is not stale (i.e. -from the previous exposure). There are at least two methods to ensure this: -

- - - -

Dark Images

- -

-Dark images are acquired automatically at the beginning of a data acquisition. -They are taken if any of the following conditions are true: -

- - - -

Driver Specific Values and Settings

- -

-This driver provides status values and settings in addition to what is -provided by areaDetector base. They are listed here according -to their label in the driver specific MEDM GUI and their EPICS PV name in the -EPICS PV driver interface. A screenshot of the driver specific MEDM GUI can -be seen in the Screenshots section. -

- -

Detector Condition

- -
-
State, $(P)$(R)ADSCState
-
State of the detector reported by the ADSC control library.
-
Status, $(P)$(R)ADSCStatus
-
Status message reported by the ADSC control library.
-
Last error, $(P)$(R)ADSCLastError
-
Last error message reported by the ADSC control library.
-
Update rate for above properties, -$(P)$(R)ADSCReadConditn.SCAN
-
How frequently to update the above properties.
-
- -

Detector Error Recovery

- -
-
Software Reset, $(P)$(R)ADSCSoftReset
-
Performs a software reset. Aborts any current operation, clears status -and error messages, and sets detector state to Idle.
-
- -

Detector Continuous Image Mode

- -
-
Last Image, $(P)$(R)ADSCLastImage
-
Signals that the next exposure is the last image when in -Continuous image mode.
-
- -

Detector External Trigger

- -
-
OK to expose, $(P)$(R)ADSCOkToExpose
-
When in External trigger mode, indicates whether it is OK to -start an image exposure.
-
Start, Stop, $(P)$(R)ADSCExTrCtl
-
When in External trigger mode, set to 1 to start an -exposure and 0 to stop it.
-
$(P)$(R)ADSCExTrCtl_RBV
-
When in External trigger mode, will be Start, -Stop, OK, or Again. See Trigger Modes section for more about how this -property will behave.
-
- -

Driver Parameters

- -
-
Reuse darks, $(P)$(R)ADSCReusDrk
-
Reuse dark images when possible. This is useful to avoid wasting time -acquiring dark images when previously acquired dark images are available and -can be reused.
-
Dezinger, $(P)$(R)ADSCDezingr
-
Acquire dezingered images.
-
- -

Detector Hardware Parameters

- -
-
ADC/Binning, $(P)$(R)ADSCAdc
-
For Q4 and Q4r detectors, controls whether to use Fast or -Slow ADC. For all other detectors, controls whether to use -Hardware or Software binning.
-
Raw images, $(P)$(R)ADSCRaw
-
Write raw images.
-
Image transforms, $(P)$(R)ADSCImXform
-
Perform image transformations.
-
Stored darks, $(P)$(R)ADSCStrDrks
-
Use stored dark images. If set to Yes, stored dark images are -assumed to have been installed by ADSC and should be used.
-
- -

Detector File Parameters

- -
-
Beam center X, $(P)$(R)ADSCBeamX
-
Beam center in the X dimension.
-
Beam center Y, $(P)$(R)ADSCBeamY
-
Beam center in the Y dimension.
-
Distance, $(P)$(R)ADSCDistnce
-
Detector distance.
-
Two theta, $(P)$(R)ADSC2Theta
-
Detector 2θ angle.
-
Axis, $(P)$(R)ADSCAxis
-
Crystal rotation axis.
-
Wavelength, $(P)$(R)ADSCWavelen
-
X-ray wavelength.
-
Image width, $(P)$(R)ADSCImWidth
-
Crystal rotation during exposure.
-
Phi, $(P)$(R)ADSCPhi
-
Phi position at start of exposure.
-
Omega, $(P)$(R)ADSCOmega
-
Omega position at start of exposure.
-
Kappa, $(P)$(R)ADSCKappa
-
Kappa position at start of exposure.
-
- -

Screenshots

- - - -

Unsupported areaDetector base -Features

- - - -

Limitations

- - - - - + + + + areaDetector ADSC driver + + + +
+

+ areaDetector ADSC driver

+

+ September 17, 2008

+

+ Lewis Muir

+

+ University of Chicago

+
+

+ Table of Contents

+
    +
  1. Introduction
  2. +
  3. Dependencies
  4. +
  5. Building
  6. +
  7. Configuring
  8. +
  9. Image Modes
  10. +
  11. Trigger Modes
  12. +
  13. Dark Images
  14. +
  15. Driver Specific Values and Settings
  16. +
  17. Screenshots
  18. +
  19. Unsupported areaDetector base Features
  20. +
  21. Limitations
  22. +
+

+ Introduction

+

+ This is a driver for ADSC detectors. It + has been tested with the ADSC Q210. While not yet tested with other models, it should + work with the ADSC Q4 (with the upgrade to four computers), Q4r, Q210, Q210r, Q270, + Q315, and Q315r. +

+

+ Dependencies

+

+ This driver controls the detector via the detcon_lib_th detector control + library provided by ADSC. The detcon_lib_th library must date from 2008-06-30 + or newer. +

+

+ Building

+
    +
  1. Build the ADSC control library
  2. +
  3. Copy and rename, or create a symlink to, the ADSC auxlib.a library so + that it has the name libauxlib.a to satisfy the EPICS build facility's + requirement that a library file name start with lib
  4. +
  5. Add DIRS += adscSrc to ADApp/Makefile
  6. +
  7. Set ADSC_HOME in ADApp/adscSrc/Makefile
  8. +
  9. Rebuild the areaDetector module
  10. +
+

+ Configuring

+

+ This driver is configured via the adscConfig() function. If this is to + be used in an IOC, it must be called before iocInit(). It has the following + signature: +

+
+
int adscConfig(const char *portName, const char *modelName)
+
+
+
portName
+
+ ASYN port name for the driver instance
+
modelName
+
+ ADSC detector model name; must be one of Q4, Q4r, Q210, + Q210r, Q270, Q315, Q315r
+
+
+
+

+ The underlying ADSC control library obtains its configuration from the environment. + Therefore, the environment must be correctly configured (i.e. ADSC environment variables + set) for the ADSC control library before calling adscConfig(). +

+

+ If being used in an IOC, and an EPICS PV interface with the driver is desired, the + ADBase.template and adsc.template databases should also be loaded + for the driver instance. +

+

+ An example IOC configuration for this driver is at iocBoot/iocAdsc/st.cmd. +

+

+ Image Modes

+

+ Single

+

+ The Single mode acquires just one image. +

+

+ Multiple

+

+ The Multiple mode acquires the number of images specified in $(P)$(R)NumImages_RBV. +

+

+ Continuous

+

+ The Continuous mode acquires images indefinitely until last image + is set. In this mode, the last image of the acquisition must be signaled before + exposing the last image by setting $(P)$(R)ADSCLastImage to 1. + This requirement is due to how the underlying ADSC control library works. +

+

+ Trigger Modes

+

+ Internal

+

+ The Internal mode will make the driver expose images on its own once the + acquisition is started. +

+

+ External

+

+ The External mode will make the driver expose images only when told to + once the acquisition is started. A special protocol must be followed to trigger + each image exposure. This would normally be very simple, but because the ADSC control + library can report that an exposure did not work and should be retried after any + exposure, a more complex protocol is required. +

+

+ The protocol is described in terms of the EPICS PV driver interface, but the same + rules apply if controlling the driver directly through ASYN. The protocol is as + follows: +

+
    +
  1. Wait for $(P)$(R)ADSCOkToExpose to be Yes
  2. +
  3. Set $(P)$(R)ADSCExTrCtl to Start to start the exposure
  4. +
  5. Set $(P)$(R)ADSCExTrCtl to Stop to stop the exposure
  6. +
  7. Wait for $(P)$(R)ADSCExTrCtl_RBV to be OK or Again
  8. +
  9. If $(P)$(R)ADSCExTrCtl_RBV is Again, the exposure did not work + and should be tried again
  10. +
+

+ Note that care must be taken when waiting for $(P)$(R)ADSCExTrCtl_RBV to + be OK or Again to ensure the PV value is not stale (i.e. from + the previous exposure). There are at least two methods to ensure this: +

+ +

+ Dark Images

+

+ Dark images are acquired automatically at the beginning of a data acquisition. They + are taken if any of the following conditions are true: +

+ +

+ Driver Specific Values and Settings

+

+ This driver provides status values and settings in addition to what is provided + by areaDetector base. They are listed here according to their label + in the driver specific MEDM GUI and their EPICS PV name in the EPICS PV driver interface. + A screenshot of the driver specific MEDM GUI can be seen in the + Screenshots section. +

+

+ Detector Condition

+
+
State, $(P)$(R)ADSCState
+
+ State of the detector reported by the ADSC control library.
+
Status, $(P)$(R)ADSCStatus
+
+ Status message reported by the ADSC control library.
+
Last error, $(P)$(R)ADSCLastError
+
+ Last error message reported by the ADSC control library.
+
Update rate for above properties, $(P)$(R)ADSCReadConditn.SCAN
+
+ How frequently to update the above properties.
+
+

+ Detector Error Recovery

+
+
Software Reset, $(P)$(R)ADSCSoftReset
+
+ Performs a software reset. Aborts any current operation, clears status and error + messages, and sets detector state to Idle.
+
+

+ Detector Continuous Image Mode

+
+
Last Image, $(P)$(R)ADSCLastImage
+
+ Signals that the next exposure is the last image when in Continuous image + mode.
+
+

+ Detector External Trigger

+
+
OK to expose, $(P)$(R)ADSCOkToExpose
+
+ When in External trigger mode, indicates whether it is OK to start an image + exposure.
+
Start, Stop, $(P)$(R)ADSCExTrCtl
+
+ When in External trigger mode, set to 1 to start an exposure and + 0 to stop it.
+
$(P)$(R)ADSCExTrCtl_RBV
+
+ When in External trigger mode, will be Start, Stop, + OK, or Again. See Trigger Modes section + for more about how this property will behave.
+
+

+ Driver Parameters

+
+
Reuse darks, $(P)$(R)ADSCReusDrk
+
+ Reuse dark images when possible. This is useful to avoid wasting time acquiring + dark images when previously acquired dark images are available and can be reused.
+
Dezinger, $(P)$(R)ADSCDezingr
+
+ Acquire dezingered images.
+
+

+ Detector Hardware Parameters

+
+
ADC/Binning, $(P)$(R)ADSCAdc
+
+ For Q4 and Q4r detectors, controls whether to use Fast or Slow + ADC. For all other detectors, controls whether to use Hardware or Software + binning.
+
Raw images, $(P)$(R)ADSCRaw
+
+ Write raw images.
+
Image transforms, $(P)$(R)ADSCImXform
+
+ Perform image transformations.
+
Stored darks, $(P)$(R)ADSCStrDrks
+
+ Use stored dark images. If set to Yes, stored dark images are assumed to + have been installed by ADSC and should be used.
+
+

+ Detector File Parameters

+
+
Beam center X, $(P)$(R)ADSCBeamX
+
+ Beam center in the X dimension.
+
Beam center Y, $(P)$(R)ADSCBeamY
+
+ Beam center in the Y dimension.
+
Distance, $(P)$(R)ADSCDistnce
+
+ Detector distance.
+
Two theta, $(P)$(R)ADSC2Theta
+
+ Detector 2θ angle.
+
Axis, $(P)$(R)ADSCAxis
+
+ Crystal rotation axis.
+
Wavelength, $(P)$(R)ADSCWavelen
+
+ X-ray wavelength.
+
Image width, $(P)$(R)ADSCImWidth
+
+ Crystal rotation during exposure.
+
Phi, $(P)$(R)ADSCPhi
+
+ Phi position at start of exposure.
+
Omega, $(P)$(R)ADSCOmega
+
+ Omega position at start of exposure.
+
Kappa, $(P)$(R)ADSCKappa
+
+ Kappa position at start of exposure.
+
+

+ Screenshots

+ +

+ Unsupported areaDetector base Features

+ +

+ Limitations

+ + + diff --git a/documentation/areaDetectorDoc.html b/documentation/areaDetectorDoc.html index ccce8c8..329a8e2 100755 --- a/documentation/areaDetectorDoc.html +++ b/documentation/areaDetectorDoc.html @@ -1,1301 +1,1679 @@ - - -areaDetector: EPICS Area Detector Support - - - -
-

areaDetector: EPICS Area Detector Support

- -

R1-2

-

May 16, 2008

-

Mark Rivers

-

University of Chicago

-
- -

 

- -

Contents

- - -

 

- -

- Overview

-

-The areaDetector module provides a general-purpose interface for area (2-D) detectors in EPICS. -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.

-

-The goals of this module are: -

- - - -

 

- -

- Architecture

-

-The architecture of the areaDetector module is shown below. - -areaDetectorArchitecture.png - -From the bottom to the top this architecture consists of the following:

- -

-The code in Layers 1-3 is essentially independent of EPICS. There are only 2 EPICS dependencies in this -code. -

-
    -
  1. libCom. - libCom from EPICS base provides operating-system independent functions for - threads, mutexes, etc.
  2. -
  3. asyn. - asyn is a module that provides interthread messaging services, including queueing - and callbacks.
  4. -
-

-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. -

-

-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. -

-

-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. -

-

-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++. The parts of the code that depend -on anything from EPICS except libCom and asyn have been kept in in separate C files, so that -it should be easy to build applications that do not run as part of an EPICS IOC. -

- -

- Implementation details

-

-The areaDetector module depends heavily on -asyn. -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. -

- -

- asynPortDriver

-

-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. -asynPortDriver is a base C++ class that handles all of the details of registering the port driver, -registering the supported interfaces, -and registering the required interrupt sources. -

-

-Drivers and plugins each need to support a number of parameters that control their operation and provide -status information. Most of these can be treated as 32-bit integers, 64-bit floats, or strings. -When the new value of a parameter is sent to a driver, (e.g. detector binning in the X direction) -from an asyn client (e.g. an EPICS record), -then the driver will need to take some action. It may change some other parameters in response to this -new value (e.g. image size in the X direction). The sequence of operations in the driver can be summarized as -

-
    -
  1. New parameter value arrives, or new data arrives from detector.
  2. -
  3. Change values of one or more parameters.
  4. -
  5. For each parameter whose value changes set a flag noting that it changed.
  6. -
  7. When operation is complete, call the registered callbacks for each changed parameter.
  8. -
-

-asynPortDriver provides methods to simplify the above sequence, which must be -implemented for each of the many parameters that the driver supports. Each parameter is assigned -a number, which is the value in the pasynUser-> reason field that asyn clients pass to -the driver when reading or writing that parameter. asynPortDriver maintains a table -of parameter values, associating each parameter number with a data type (integer, double, or string), -caching the current value, and maintaining a flag indicating if a value has changed. -Drivers use asynPortDriver methods to read the current value -from the table, and to set new values in the table. There is a method to call all registered callbacks -for values that have changed since callbacks were last done. -

-

-The following are the public definitions in the asynPortDriver class: -

-
#define asynCommonMask          0x00000001
-#define asynDrvUserMask         0x00000002
-#define asynOptionMask          0x00000004
-#define asynInt32Mask           0x00000008
-#define asyUInt32DigitalMask    0x00000010
-#define asynFloat64Mask         0x00000020
-#define asynOctetMask           0x00000040
-#define asynInt8ArrayMask       0x00000080
-#define asynInt16ArrayMask      0x00000100
-#define asynInt32ArrayMask      0x00000200
-#define asynFloat32ArrayMask    0x00000400
-#define asynFloat64ArrayMask    0x00000800
-#define asynGenericPointerMask  0x00001000
-
-class asynPortDriver {
-public:
-    asynPortDriver(const char *portName, int maxAddr, int paramTableSize, int interfaceMask, int interruptMask);
-    virtual asynStatus getAddress(asynUser *pasynUser, const char *functionName, int *address); 
-    virtual asynStatus findParam(asynParamString_t *paramTable, int numParams, const char *paramName, int *param);
-    virtual asynStatus readInt32(asynUser *pasynUser, epicsInt32 *value);
-    virtual asynStatus writeInt32(asynUser *pasynUser, epicsInt32 value);
-    virtual asynStatus getBounds(asynUser *pasynUser, epicsInt32 *low, epicsInt32 *high);
-    virtual asynStatus readFloat64(asynUser *pasynUser, epicsFloat64 *value);
-    virtual asynStatus writeFloat64(asynUser *pasynUser, epicsFloat64 value);
-    virtual asynStatus readOctet(asynUser *pasynUser, char *value, size_t maxChars,
-                         size_t *nActual, int *eomReason);
-    virtual asynStatus writeOctet(asynUser *pasynUser, const char *value, size_t maxChars,
-                          size_t *nActual);
-    virtual asynStatus readInt8Array(asynUser *pasynUser, epicsInt8 *value, 
-                                        size_t nElements, size_t *nIn);
-    virtual asynStatus writeInt8Array(asynUser *pasynUser, epicsInt8 *value,
-                                        size_t nElements);
-    virtual asynStatus doCallbacksInt8Array(epicsInt8 *value,
-                                        size_t nElements, int reason, int addr);
-    virtual asynStatus readInt16Array(asynUser *pasynUser, epicsInt16 *value,
-                                        size_t nElements, size_t *nIn);
-    virtual asynStatus writeInt16Array(asynUser *pasynUser, epicsInt16 *value,
-                                        size_t nElements);
-    virtual asynStatus doCallbacksInt16Array(epicsInt16 *value,
-                                        size_t nElements, int reason, int addr);
-    virtual asynStatus readInt32Array(asynUser *pasynUser, epicsInt32 *value,
-                                        size_t nElements, size_t *nIn);
-    virtual asynStatus writeInt32Array(asynUser *pasynUser, epicsInt32 *value,
-                                        size_t nElements);
-    virtual asynStatus doCallbacksInt32Array(epicsInt32 *value,
-                                        size_t nElements, int reason, int addr);
-    virtual asynStatus readFloat32Array(asynUser *pasynUser, epicsFloat32 *value,
-                                        size_t nElements, size_t *nIn);
-    virtual asynStatus writeFloat32Array(asynUser *pasynUser, epicsFloat32 *value,
-                                        size_t nElements);
-    virtual asynStatus doCallbacksFloat32Array(epicsFloat32 *value,
-                                        size_t nElements, int reason, int addr);
-    virtual asynStatus readFloat64Array(asynUser *pasynUser, epicsFloat64 *value,
-                                        size_t nElements, size_t *nIn);
-    virtual asynStatus writeFloat64Array(asynUser *pasynUser, epicsFloat64 *value,
-                                        size_t nElements);
-    virtual asynStatus doCallbacksFloat64Array(epicsFloat64 *value,
-                                        size_t nElements, int reason, int addr);
-    virtual asynStatus readGenericPointer(asynUser *pasynUser, void *pointer);
-    virtual asynStatus writeGenericPointer(asynUser *pasynUser, void *pointer);
-    virtual asynStatus doCallbacksGenericPointer(void *pointer, int reason, int addr);
-    virtual asynStatus drvUserCreate(asynUser *pasynUser, const char *drvInfo, 
-                                     const char **pptypeName, size_t *psize);
-    virtual asynStatus drvUserGetType(asynUser *pasynUser,
-                                        const char **pptypeName, size_t *psize);
-    virtual asynStatus drvUserDestroy(asynUser *pasynUser);
-    virtual void report(FILE *fp, int details);
-    virtual asynStatus connect(asynUser *pasynUser);
-    virtual asynStatus disconnect(asynUser *pasynUser);
-   
-    virtual asynStatus setIntegerParam(int index, int value);
-    virtual asynStatus setIntegerParam(int list, int index, int value);
-    virtual asynStatus setDoubleParam(int index, double value);
-    virtual asynStatus setDoubleParam(int list, int index, double value);
-    virtual asynStatus setStringParam(int index, const char *value);
-    virtual asynStatus setStringParam(int list, int index, const char *value);
-    virtual asynStatus getIntegerParam(int index, int * value);
-    virtual asynStatus getIntegerParam(int list, int index, int * value);
-    virtual asynStatus getDoubleParam(int index, double * value);
-    virtual asynStatus getDoubleParam(int list, int index, double * value);
-    virtual asynStatus getStringParam(int index, int maxChars, char *value);
-    virtual asynStatus getStringParam(int list, int index, int maxChars, char *value);
-    virtual asynStatus callParamCallbacks();
-    virtual asynStatus callParamCallbacks(int list, int addr);
-    virtual void reportParams();
-
-    /* asynUser connected to ourselves for asynTrace */
-    asynUser *pasynUser;
-};
-
- -

-A brief explanation of the methods and data in this class is provided here. Users should look at the -example driver (simDetector) and plugins provided with areaDetector for examples of how this -class is used. -

- -
    asynPortDriver(const char *portName, int maxAddr, int paramTableSize, int interfaceMask, int interruptMask);
-
-

-This is the constructor for the class. -

- -
-
    virtual asynStatus getAddress(asynUser *pasynUser, const char *functionName, int *address); 
-
-

-Returns the value from pasynManager-> getAddr(pasynUser,...). -Returns an error if the address is not valid, e.g. >= this-> maxAddr. -

- -
    virtual asynStatus readInt32(asynUser *pasynUser, epicsInt32 *value);
-    virtual asynStatus readFloat64(asynUser *pasynUser, epicsFloat64 *value);
-    virtual asynStatus readOctet(asynUser *pasynUser, char *value, size_t maxChars,
-                             size_t *nActual, int *eomReason);
-
-

-These methods are called by asyn clients to return the current cached value for the -parameter indexed by pasynUser-> reason in the parameter table defined by getAddress(). -Derived classed typically do not need to implement these methods. -

- -
-
    virtual asynStatus writeInt32(asynUser *pasynUser, epicsInt32 value);
-    virtual asynStatus writeFloat64(asynUser *pasynUser, epicsFloat64 value);
-    virtual asynStatus writeOctet(asynUser *pasynUser, const char *value, size_t maxChars,
-                          size_t *nActual);
-
-

-These methods are called by asynClients to set the new value of a parameter. The -implementation of these methods in asynPortDriver copies the parameter into a cached -location for use by the asynRead(Int32, Float64, and Octet) methods. Most drivers -will provide their own implementations of these methods to do driver-dependent operations -when there is a new value of the parameter. -

- -
-
     
-    virtual asynStatus readXXXArray(asynUser *pasynUser, epicsInt8 *value, 
-                                        size_t nElements, size_t *nIn);
-    virtual asynStatus writeXXXArray(asynUser *pasynUser, epicsInt8 *value,
-                                        size_t nElements);
-    virtual asynStatus doCallbacksXXXArray(epicsInt8 *value,
-                                        size_t nElements, int reason, int addr);
-    virtual asynStatus readGenericPointer(asynUser *pasynUser, void *handle);
-    virtual asynStatus writeGenericPointer(asynUser *pasynUser, void *handle);
-    virtual asynStatus doCallbacksGenericPointer(void *handle, int reason, int addr);
-
-

-where XXX=(Int8, Int16, Int32, Float32, or Float64). -The readXXX and writeXXX methods only have stub methods that return an error in asynPortDriver, so they -must be implemented in the derived classes if the corresponding interface is -used. They are not pure virtual functions so that the derived class need not implement -the interface if it is not used. The doCallbacksXXX methods in asynPortDriver -call any registered asyn clients on the corresponding interface if the reason -and addr values match. It typically does not need to be implemented in derived classes. -

- -
-
     
-    virtual asynStatus findParam(asynParamString_t *paramTable, int numParams, const char *paramName, int *param);
-    virtual asynStatus drvUserCreate(asynUser *pasynUser, const char *drvInfo, 
-                                     const char **pptypeName, size_t *psize);
-    virtual asynStatus drvUserGetType(asynUser *pasynUser,
-                                        const char **pptypeName, size_t *psize);
-    virtual asynStatus drvUserDestroy(asynUser *pasynUser);
-
-

-drvUserCreate must be implemented in derived classes that use the parameter facilities of asynPortDriver. -The findParam method is a convenience function that searches an array of {enum, string} structures -and returns the enum (parameter number) matching the string. This is typically used in the -implementation of drvUserCreate in derived classes. drvUserGetType and -drvUserDestroy typically do not need to be implemented in derived classes. -

- -
-
     
-    virtual void report(FILE *fp, int details);
-    virtual asynStatus connect(asynUser *pasynUser);
-    virtual asynStatus disconnect(asynUser *pasynUser);
-
-

-The report function prints information on registered interrupt clients if details > 0, and prints -parameter table information if details > 5. It is typically called by the implementation of -report in derived classes before or after -they print specific information about themselves. connect and disconnect call -pasynManager-> exceptionConnect and pasynManager-> exceptionDisconnect respectively. -Derived classes may or may not need to implement these functions. -

- -
-
     
-    virtual asynStatus setIntegerParam(int index, int value);
-    virtual asynStatus setIntegerParam(int list, int index, int value);
-    virtual asynStatus setDoubleParam(int index, double value);
-    virtual asynStatus setDoubleParam(int list, int index, double value);
-    virtual asynStatus setStringParam(int index, const char *value);
-    virtual asynStatus setStringParam(int list, int index, const char *value);
-    virtual asynStatus getIntegerParam(int index, int * value);
-    virtual asynStatus getIntegerParam(int list, int index, int * value);
-    virtual asynStatus getDoubleParam(int index, double * value);
-    virtual asynStatus getDoubleParam(int list, int index, double * value);
-    virtual asynStatus getStringParam(int index, int maxChars, char *value);
-    virtual asynStatus getStringParam(int list, int index, int maxChars, char *value);
-    virtual asynStatus callParamCallbacks();
-    virtual asynStatus callParamCallbacks(int list, int addr);
-
-

-The setXXXParam methods set the value of a parameter in the parameter table -in the object. If the value is different from the previous value of the parameter -they also set the flag indicating that the value has changed. The getXXXParam -methods return the current value of the parameter. There are two versions of the -setXXXParam and getXXXParam methods, one with a list -argument, and one without. The one without uses list=0, since there -is often only a single parameter list (i.e. if maxAddr=1). The callParamCallbacks -methods call back any registered clients for parameters that have changed since the last -time callParamCallbacks was called. The version of callParamCallbacks -with no arguments uses the first parameter list and matches asyn address=0. There is a -second version of callParamCallbacks that takes an argument specifying the parameter list -number, and the asyn address to match. -

- -

- NDArray

- -

-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: -

- -
#define ND_ARRAY_MAX_DIMS 10
-
-/* Enumeration of array data types */
-typedef enum
-{
-    NDInt8,
-    NDUInt8,
-    NDInt16,
-    NDUInt16,
-    NDInt32,
-    NDUInt32,
-    NDFloat32,
-    NDFloat64
-} NDDataType_t;
-
-
-typedef struct NDDimension {
-    int size;
-    int offset;
-    int binning;
-    int reverse;
-} NDDimension_t;
-
-typedef struct NDArrayInfo {
-    int nElements;
-    int bytesPerElement;
-    int totalBytes;
-} NDArrayInfo_t;
-
-class NDArray {
-public:
-    /* Data: NOTE this must come first because ELLNODE must be first, i.e. same address as object */
-    /* The first 2 fields are used for the freelist */
-    ELLNODE node;
-    int referenceCount;
-    /* The NDArrayPool object that created this array */
-    void *owner;
-
-    int uniqueId;
-    double timeStamp;
-    int ndims;
-    NDDimension_t dims[ND_ARRAY_MAX_DIMS];
-    NDDataType_t dataType;
-    int dataSize;
-    void *pData;
-
-    /* Methods */
-    NDArray();
-    int          initDimension   (NDDimension_t *pDimension, int size);
-    int          getInfo         (NDArrayInfo_t *pInfo);
-    int          copy            (NDArray *pOut);
-    int          reserve(); 
-    int          release();
-};
-
-
-
-

-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 is not intended to -contain meta-data describing how the data was collected, etc. -

-

-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 NDDimension_t structure. The fields in NDDimension_t are as follows: -

- -

-The first 3 data fields in the NDArray class, (node, referenceCount, owner) are used -by the NDArrayPool class discussed below. -The remaining data fields are as follows: -

- -

-The methods of the NDArray class are: -

- - - -

- NDArrayPool

- -

-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. 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 public interface of the NDArrayPool class is defined as follows: -

- -
class NDArrayPool {
-public:
-                 NDArrayPool   (int maxBuffers, size_t maxMemory);
-    NDArray*     alloc         (int ndims, int *dims, NDDataType_t dataType, int dataSize, void *pData);
-    int          reserve       (NDArray *pArray); 
-    int          release       (NDArray *pArray);
-    int          convert       (NDArray *pIn, 
-                                NDArray **ppOut,
-                                NDDataType_t dataTypeOut,
-                                NDDimension_t *outDims);
-    int          report        (int details);     
-
- -

-The methods of the NDArrayPool class are: -

- - - -

- asynNDArrayDriver

- -

-asynNDArrayDriver inherits from asynPortDriver. It implements the asynGenericPointer functions, assuming that -these reference NDArray objects. This is the class from which both plugins and area detector drivers are -indirectly derived. -Its public interface is defined as follows: -

- -
class asynNDArrayDriver : public asynPortDriver {
-public:
-    asynNDArrayDriver(const char *portName, int maxAddr, int paramTableSize, int maxBuffers, size_t maxMemory,
-                      int interfaceMask, int interruptMask);
-    virtual asynStatus readGenericPointer(asynUser *pasynUser, void *genericPointer);
-    virtual asynStatus writeGenericPointer(asynUser *pasynUser, void *genericPointer);
-    virtual void report(FILE *fp, int details);
-
-};
-
-

-The methods of the asynNDArrayDriver class are: -

- - -

- ADDriver

- -

-ADDriver inherits from asynNDArrayDriver. This is the class from which area detector drivers are directly derived. -Its public interface is defined as follows: -

-
class ADDriver : public asynNDArrayDriver {
-public:
-    ADDriver(const char *portName, int maxAddr, int paramTableSize, int maxBuffers, size_t maxMemory,
-             int interfaceMask, int interruptMask);
-                 
-    /* These are the methods that we override from asynPortDriver */
-     virtual asynStatus drvUserCreate(asynUser *pasynUser, const char *drvInfo, 
-                                     const char **pptypeName, size_t *psize);
-                                     
-    /* These are the methods that are new to this class */
-    int createFileName(int maxChars, char *fullFileName);
-
-

-The methods of the ADDriver class are: -

- - -

- ADStdDriverParams

- -

-The file ADStdDriverParams.h defines the following: -

- -
/* Enumeration of shutter status */
-typedef enum
-{
-    ADShutterClosed, 
-    ADShutterOpen
-} ADShutterStatus_t;
-
-/* Enumeration of detector status */
-typedef enum
-{
-    ADStatusIdle,
-    ADStatusAcquire,
-    ADStatusReadout,
-    ASStatusCorrect,
-    ADStatusSaving,
-    ADStatusAborting,
-    ADStatusError,
-} ADStatus_t;
-
-typedef enum
-{
-    ADImageSingle,
-    ADImageMultiple,
-    ADImageContinuous
-} ADImageMode_t;
-
-typedef enum
-{
-    ADTriggerInternal,
-    ADTriggerExternal
-} ADTriggerMode_t;
-
-
-

-It also defines parameters that all area detector drivers should implement if possible. These parameters are defined -by enum values with an associated asyn interface, and access (read-only or read-write). The EPICS database -ADBase.template provides access to these standard driver parameters. The following table lists the -standard driver parameters. The columns are defined as follows: -

- -

-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. -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Parameter Definitions in ADStdDriverParams.h and EPICS Record Definitions in ADBase.template
Enum nameasyn interfaceAccessDescriptiondrvUser stringEPICS record nameEPICS record type
Information about the detector
ADManufacturerasynOctetr/oDetector manufacturer nameMANUFACTURER$(P)$(R)Manufacturer_RBVstringin
ADModelasynOctetr/oDetector model nameMODEL$(P)$(R)Model_RBVstringin
ADMaxSizeXasynInt32r/oMaximum (sensor) size in the X directionMAX_SIZE_X$(P)$(R)MaxSizeX_RBVlongin
ADMaxSizeYasynInt32r/oMaximum (sensor) size in the Y directionMAX_SIZE_Y$(P)$(R)MaxSizeY_RBVlongin
Detector readout control including gain, binning, region start and size, reversal
ADGainasynFloat64r/wDetector gainGAIN$(P)$(R)Gain
$(P)$(R)Gain_RBV
ao
ai
ADBinXasynInt32r/wBinning in the X directionBIN_X$(P)$(R)BinX
$(P)$(R)BinX_RBV
longout
longin
ADBinYasynInt32r/wBinning in the Y directionBIN_Y$(P)$(R)BinY
$(P)$(R)BinY_RBV
longout
longin
ADMinXasynInt32r/wFirst pixel to read in the X direction.
0 is the first pixel on the detector.
MIN_X$(P)$(R)MinX
$(P)$(R)MinX_RBV
longout
longin
ADMinYasynInt32r/wFirst pixel to read in the Y direction.
0 is the first pixel on the detector.
MIN_Y$(P)$(R)MinY
$(P)$(R)MinY_RBV
longout
longin
ADSizeXasynInt32r/wSize of the region to read in the X directionSIZE_X$(P)$(R)SizeX
$(P)$(R)SizeX_RBV
longout
longin
ADSizeYasynInt32r/wSize of the region to read in the Y directionSIZE_Y$(P)$(R)SizeY
$(P)$(R)SizeY_RBV
longout
longin
ADReverseXasynInt32r/wReverse image in the X direction
(0=No, 1=Yes)
REVERSE_X$(P)$(R)ReverseX
$(P)$(R)ReverseX_RBV
longout
longin
ADReverseYasynInt32r/wReverse image in the Y direction
(0=No, 1=Yes)
REVERSE_Y$(P)$(R)ReverseY
$(P)$(R)ReverseY_RBV
longout
longin
Image and trigger modes
ADImageModeasynInt32r/wImage mode (ADImageMode_t).IMAGE_MODE$(P)$(R)ImageMode
$(P)$(R)ImageMode_RBV
mbbo
mbbi
ADTriggerModeasynInt32r/wTrigger mode (ADTriggerMode_t).TRIGGER_MODE$(P)$(R)TriggerMode
$(P)$(R)TriggerMode_RBV
mbbo
mbbi
Data type
ADDataTypeasynInt32r/wData type (NDDataType_t).DATA_TYPE$(P)$(R)DataType
$(P)$(R)DataType_RBV
mbbo
mbbi
Actual dimensions of image data
ADImageSizeXasynInt32r/oSize of the image data in the X directionIMAGE_SIZE_X$(P)$(R)ImageSizeX_RBVlongin
ADImageSizeYasynInt32r/oSize of the image data in the Y directionIMAGE_SIZE_Y$(P)$(R)ImageSizeY_RBVlongin
ADImageSizeasynInt32r/oTotal size of image data in bytesIMAGE_SIZE$(P)$(R)ImageSize_RBVlongin
Acquisition time and period
ADAcquireTimeasynFloat64r/wAcquisition time per imageACQ_TIME$(P)$(R)AcquireTime
$(P)$(R)AcquireTime_RBV
ao
ai
ADAcquirePeriodasynFloat64r/wAcquisition period between imagesACQ_PERIOD$(P)$(R)AcquirePeriod
$(P)$(R)AcquirePeriod_RBV
ao
ai
Number of exposures and number of images
ADNumExposuresasynInt32r/wNumber of exposures per image to acquireNEXPOSURES$(P)$(R)NumExposures
$(P)$(R)NumExposures_RBV
longout
longin
ADNumImagesasynInt32r/wNumber of images to acquire in one acquisition sequenceNIMAGES$(P)$(R)NumImages
$(P)$(R)NumImages_RBV
longout
longin
Acquisition control
ADAcquireasynInt32r/wStart (1) or stop (0) image acquisition. This record is linked to 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.ACQUIRE$(P)$(R)Acquirebo
File saving parameters
ADFilePathasynOctetr/wFile pathFILE_PATH$(P)$(R)FilePath
$(P)$(R)FilePath_RBV
waveform
waveform
ADFileNameasynOctetr/wFile nameFILE_NAME$(P)$(R)FileName
$(P)$(R)FileName_RBV
waveform
waveform
ADFileNumberasynInt32r/wFile numberFILE_NUMBER$(P)$(R)FileNumber
$(P)$(R)FileNumber_RBV
longout
longin
ADFileTemplateasynOctetr/wFormat string for constructing ADFullFileName from ADFilePath, ADFileName, and ADFileNumber. - The final file name (which is placed in ADFullFileName) is created with the following code: -
        epicsSnprintf(FullFilename, sizeof(FullFilename), FileFormat, 
-                      FilePath, Filename, FileNumber);
-        
- FilePath, Filename, FileNumber are converted in that order with FileFormat. - An example file format is "%s%s%4.4d.tif". 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 FileFormat as desired. If one does not want to have FileNumber in the file name - at all, then just omit the %d format specifier from FileFormat. If the client wishes to construct - the complete file name itself, then it can just put that file name into ADFileFormat with no - format specifiers at all, in which case ADFilePath, ADFileName, and ADFileNumber will be ignored.
FILE_TEMPLATE$(P)$(R)FileTemplate
$(P)$(R)FileTemplate_RBV
waveform
waveform
ADFullFileNameasynOctetr/oFull file nameFULL_FILE_NAME$(P)$(R)FullFileName_RBVwaveform
waveform
ADAutoIncrementasynInt32r/wAuto-increment flag. Controls whether FileNumber is automatically incremented by - 1 each time an acquisition completes (0=No, 1=Yes)AUTO_INCREMENT$(P)$(R)AutoIncrement
$(P)$(R)AutoIncrement_RBV
bo
bi
ADAutoSaveasynInt32r/wAuto-save flag (0=No, 1=Yes)AUTO_SAVE$(P)$(R)AutoSave
$(P)$(R)AutoSave_RBV
bo
bi
ADFileFormatasynInt32r/wFile format. The format to write/read data in (e.g. TIFF, netCDF, etc.)FILE_FORMAT$(P)$(R)FileFormat
$(P)$(R)FileFormat_RBV
mbbo
mbbi
ADWriteFileasynInt32r/wManually save the most recent image to a file when value=1WRITE_FILE$(P)$(R)WriteFilelongout
ADReadFileasynInt32r/wManually read a file when value=1READ_FILE$(P)$(R)ReadFilelongout
Status information
ADStatusasynInt32r/oAcquisition status (ADStatus_t)STATUS$(P)$(R)DetectorState_RBVmbbi
ADStatusMessageasynOctetr/oStatus message stringSTATUS_MESSAGE$(P)$(R)StatusMessage_RBVwaveform
ADStringToServerasynOctetr/oString from driver to string-based vendor serverSTRING_TO_SERVER$(P)$(R)StringToServer_RBVwaveform
ADStringFromServerasynOctetr/oString from string-based vendor server to driverSTRING_FROM_SERVER$(P)$(R)StringFromServer_RBVwaveform
ADImageCounterasynInt32r/wCounter that increments by 1 each time an image is acquiredIMAGE_COUNTER$(P)$(R)ImageCounter
$(P)$(R)ImageCounter_RBV
longout
longin
N/AN/Ar/oRate (Hz) at which ImageCounter is incrementing. Computed in database.N/A$(P)$(R)ImageRate_RBVcalc
Shutter control. Note: no areaDetector drivers yet implement shutter control, - and these parameters may change in the near future.
ADShutterasynInt32r/wShutter control (ADShutterStatus_t)SHUTTER$(P)$(R)ShutterMode
$(P)$(R)ShutterMode_RBV
mbbo
mbbi
Image data
NDArrayDataasynGenericPointerr/wThe image data as an NDArray objectNDARRAY_DATAN/A. EPICS access to image data is through NDStdArrays plugin.N/A
asyn port information
N/AN/AN/AThe name of the asyn port for this driverN/A$(P)$(R)PortName_RBVstringin
N/AN/AN/Aasyn record to control debugging (asynTrace)N/A$(P)$(R)AsynIOasyn
- -

-The following is the MEDM screen that provides access to the parameters in ADStdDriverParams 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, so detector-specific MEDM screens should generally be created that only display the EPICS PVs -for the features implemented for that detector. Note that the section of the screen labeled "Shutter" is not currently -implemented for any areaDetector driver, and is subject to change in the near future. -

-
-
ADBase.png
-
-

- Detector drivers

- -

-areaDetector has been designed to minimize the amount of work required to write a new detector driver. These -drivers are described in separate documents, linked to by the table of contents at the top of this page. -

- - + + + areaDetector: EPICS Area Detector Support + + +
+

+ areaDetector: EPICS Area Detector Support

+

+ September 17, 2008

+

+ Mark Rivers

+

+ University of Chicago

+
+

+  

+

+ Contents

+ +

+  

+
+

+ Overview

+
+

+ The areaDetector module provides a general-purpose interface for area (2-D) detectors + in EPICS. 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.

+

+ The goals of this module are: +

+ +

+  

+
+

+ Architecture

+
+

+ The architecture of the areaDetector module is shown below. + areaDetectorArchitecture.png + From the bottom to the top this architecture consists of the following:

+ +

+ The code in Layers 1-3 is essentially independent of EPICS. There are only 2 EPICS + dependencies in this code. +

+
    +
  1. libCom. + libCom from EPICS base provides operating-system independent functions for threads, + mutexes, etc.
  2. +
  3. asyn. asyn is a module + that provides interthread messaging services, including queueing and callbacks.
  4. +
+

+ 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. +

+

+ 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. +

+

+ 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. +

+

+ 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++. The parts of the code + that depend on anything from EPICS except libCom and asyn have been kept in in separate + C files, so that it should be easy to build applications that do not run as part + of an EPICS IOC. +

+
+

+ Implementation details

+
+

+ The areaDetector module depends heavily on + asyn. 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. +

+
+

+ asynPortDriver

+
+

+ 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. + asynPortDriver is a base C++ class that handles all of the details of registering + the port driver, registering the supported interfaces, and registering the required + interrupt sources. +

+

+ Drivers and plugins each need to support a number of parameters that control their + operation and provide status information. Most of these can be treated as 32-bit + integers, 64-bit floats, or strings. When the new value of a parameter is sent to + a driver, (e.g. detector binning in the X direction) from an asyn client (e.g. an + EPICS record), then the driver will need to take some action. It may change some + other parameters in response to this new value (e.g. image size in the X direction). + The sequence of operations in the driver can be summarized as +

+
    +
  1. New parameter value arrives, or new data arrives from detector.
  2. +
  3. Change values of one or more parameters.
  4. +
  5. For each parameter whose value changes set a flag noting that it changed.
  6. +
  7. When operation is complete, call the registered callbacks for each changed parameter.
  8. +
+

+ asynPortDriver provides methods to simplify the above sequence, which must be implemented + for each of the many parameters that the driver supports. Each parameter is assigned + a number, which is the value in the pasynUser-> reason field that asyn clients + pass to the driver when reading or writing that parameter. asynPortDriver maintains + a table of parameter values, associating each parameter number with a data type + (integer, double, or string), caching the current value, and maintaining a flag + indicating if a value has changed. Drivers use asynPortDriver methods to read the + current value from the table, and to set new values in the table. There is a method + to call all registered callbacks for values that have changed since callbacks were + last done. +

+

+ The following are the public definitions in the asynPortDriver class: +

+
#define asynCommonMask          0x00000001
+#define asynDrvUserMask         0x00000002
+#define asynOptionMask          0x00000004
+#define asynInt32Mask           0x00000008
+#define asyUInt32DigitalMask    0x00000010
+#define asynFloat64Mask         0x00000020
+#define asynOctetMask           0x00000040
+#define asynInt8ArrayMask       0x00000080
+#define asynInt16ArrayMask      0x00000100
+#define asynInt32ArrayMask      0x00000200
+#define asynFloat32ArrayMask    0x00000400
+#define asynFloat64ArrayMask    0x00000800
+#define asynGenericPointerMask  0x00001000
+
+class asynPortDriver {
+public:
+    asynPortDriver(const char *portName, int maxAddr, int paramTableSize, int interfaceMask, int interruptMask);
+    virtual asynStatus getAddress(asynUser *pasynUser, const char *functionName, int *address); 
+    virtual asynStatus findParam(asynParamString_t *paramTable, int numParams, const char *paramName, int *param);
+    virtual asynStatus readInt32(asynUser *pasynUser, epicsInt32 *value);
+    virtual asynStatus writeInt32(asynUser *pasynUser, epicsInt32 value);
+    virtual asynStatus getBounds(asynUser *pasynUser, epicsInt32 *low, epicsInt32 *high);
+    virtual asynStatus readFloat64(asynUser *pasynUser, epicsFloat64 *value);
+    virtual asynStatus writeFloat64(asynUser *pasynUser, epicsFloat64 value);
+    virtual asynStatus readOctet(asynUser *pasynUser, char *value, size_t maxChars,
+                         size_t *nActual, int *eomReason);
+    virtual asynStatus writeOctet(asynUser *pasynUser, const char *value, size_t maxChars,
+                          size_t *nActual);
+    virtual asynStatus readInt8Array(asynUser *pasynUser, epicsInt8 *value, 
+                                        size_t nElements, size_t *nIn);
+    virtual asynStatus writeInt8Array(asynUser *pasynUser, epicsInt8 *value,
+                                        size_t nElements);
+    virtual asynStatus doCallbacksInt8Array(epicsInt8 *value,
+                                        size_t nElements, int reason, int addr);
+    virtual asynStatus readInt16Array(asynUser *pasynUser, epicsInt16 *value,
+                                        size_t nElements, size_t *nIn);
+    virtual asynStatus writeInt16Array(asynUser *pasynUser, epicsInt16 *value,
+                                        size_t nElements);
+    virtual asynStatus doCallbacksInt16Array(epicsInt16 *value,
+                                        size_t nElements, int reason, int addr);
+    virtual asynStatus readInt32Array(asynUser *pasynUser, epicsInt32 *value,
+                                        size_t nElements, size_t *nIn);
+    virtual asynStatus writeInt32Array(asynUser *pasynUser, epicsInt32 *value,
+                                        size_t nElements);
+    virtual asynStatus doCallbacksInt32Array(epicsInt32 *value,
+                                        size_t nElements, int reason, int addr);
+    virtual asynStatus readFloat32Array(asynUser *pasynUser, epicsFloat32 *value,
+                                        size_t nElements, size_t *nIn);
+    virtual asynStatus writeFloat32Array(asynUser *pasynUser, epicsFloat32 *value,
+                                        size_t nElements);
+    virtual asynStatus doCallbacksFloat32Array(epicsFloat32 *value,
+                                        size_t nElements, int reason, int addr);
+    virtual asynStatus readFloat64Array(asynUser *pasynUser, epicsFloat64 *value,
+                                        size_t nElements, size_t *nIn);
+    virtual asynStatus writeFloat64Array(asynUser *pasynUser, epicsFloat64 *value,
+                                        size_t nElements);
+    virtual asynStatus doCallbacksFloat64Array(epicsFloat64 *value,
+                                        size_t nElements, int reason, int addr);
+    virtual asynStatus readGenericPointer(asynUser *pasynUser, void *pointer);
+    virtual asynStatus writeGenericPointer(asynUser *pasynUser, void *pointer);
+    virtual asynStatus doCallbacksGenericPointer(void *pointer, int reason, int addr);
+    virtual asynStatus drvUserCreate(asynUser *pasynUser, const char *drvInfo, 
+                                     const char **pptypeName, size_t *psize);
+    virtual asynStatus drvUserGetType(asynUser *pasynUser,
+                                        const char **pptypeName, size_t *psize);
+    virtual asynStatus drvUserDestroy(asynUser *pasynUser);
+    virtual void report(FILE *fp, int details);
+    virtual asynStatus connect(asynUser *pasynUser);
+    virtual asynStatus disconnect(asynUser *pasynUser);
+   
+    virtual asynStatus setIntegerParam(int index, int value);
+    virtual asynStatus setIntegerParam(int list, int index, int value);
+    virtual asynStatus setDoubleParam(int index, double value);
+    virtual asynStatus setDoubleParam(int list, int index, double value);
+    virtual asynStatus setStringParam(int index, const char *value);
+    virtual asynStatus setStringParam(int list, int index, const char *value);
+    virtual asynStatus getIntegerParam(int index, int * value);
+    virtual asynStatus getIntegerParam(int list, int index, int * value);
+    virtual asynStatus getDoubleParam(int index, double * value);
+    virtual asynStatus getDoubleParam(int list, int index, double * value);
+    virtual asynStatus getStringParam(int index, int maxChars, char *value);
+    virtual asynStatus getStringParam(int list, int index, int maxChars, char *value);
+    virtual asynStatus callParamCallbacks();
+    virtual asynStatus callParamCallbacks(int list, int addr);
+    virtual void reportParams();
+
+    /* asynUser connected to ourselves for asynTrace */
+    asynUser *pasynUser;
+};
+
+

+ A brief explanation of the methods and data in this class is provided here. Users + should look at the example driver (simDetector) and plugins provided with areaDetector + for examples of how this class is used. +

+
    asynPortDriver(const char *portName, int maxAddr, int paramTableSize, int interfaceMask, int interruptMask);
+
+

+ This is the constructor for the class. +

+ +
+
    virtual asynStatus getAddress(asynUser *pasynUser, const char *functionName, int *address); 
+
+

+ Returns the value from pasynManager-> getAddr(pasynUser,...). Returns an error + if the address is not valid, e.g. >= this-> maxAddr. +

+
    virtual asynStatus readInt32(asynUser *pasynUser, epicsInt32 *value);
+    virtual asynStatus readFloat64(asynUser *pasynUser, epicsFloat64 *value);
+    virtual asynStatus readOctet(asynUser *pasynUser, char *value, size_t maxChars,
+                             size_t *nActual, int *eomReason);
+
+

+ These methods are called by asyn clients to return the current cached value for + the parameter indexed by pasynUser-> reason in the parameter table defined by + getAddress(). Derived classed typically do not need to implement these + methods. +

+
+
    virtual asynStatus writeInt32(asynUser *pasynUser, epicsInt32 value);
+    virtual asynStatus writeFloat64(asynUser *pasynUser, epicsFloat64 value);
+    virtual asynStatus writeOctet(asynUser *pasynUser, const char *value, size_t maxChars,
+                          size_t *nActual);
+
+

+ These methods are called by asynClients to set the new value of a parameter. The + implementation of these methods in asynPortDriver copies the parameter into a cached + location for use by the asynRead(Int32, Float64, and Octet) methods. Most drivers + will provide their own implementations of these methods to do driver-dependent operations + when there is a new value of the parameter. +

+
+
     
+    virtual asynStatus readXXXArray(asynUser *pasynUser, epicsInt8 *value, 
+                                        size_t nElements, size_t *nIn);
+    virtual asynStatus writeXXXArray(asynUser *pasynUser, epicsInt8 *value,
+                                        size_t nElements);
+    virtual asynStatus doCallbacksXXXArray(epicsInt8 *value,
+                                        size_t nElements, int reason, int addr);
+    virtual asynStatus readGenericPointer(asynUser *pasynUser, void *handle);
+    virtual asynStatus writeGenericPointer(asynUser *pasynUser, void *handle);
+    virtual asynStatus doCallbacksGenericPointer(void *handle, int reason, int addr);
+
+

+ where XXX=(Int8, Int16, Int32, Float32, or Float64). The readXXX and writeXXX methods + only have stub methods that return an error in asynPortDriver, so they must be implemented + in the derived classes if the corresponding interface is used. They are not pure + virtual functions so that the derived class need not implement the interface if + it is not used. The doCallbacksXXX methods in asynPortDriver call any registered + asyn clients on the corresponding interface if the reason and addr + values match. It typically does not need to be implemented in derived classes. +

+
+
     
+    virtual asynStatus findParam(asynParamString_t *paramTable, int numParams, const char *paramName, int *param);
+    virtual asynStatus drvUserCreate(asynUser *pasynUser, const char *drvInfo, 
+                                     const char **pptypeName, size_t *psize);
+    virtual asynStatus drvUserGetType(asynUser *pasynUser,
+                                        const char **pptypeName, size_t *psize);
+    virtual asynStatus drvUserDestroy(asynUser *pasynUser);
+
+

+ drvUserCreate must be implemented in derived classes that use the parameter facilities + of asynPortDriver. The findParam method is a convenience function that + searches an array of {enum, string} structures and returns the enum (parameter number) + matching the string. This is typically used in the implementation of drvUserCreate + in derived classes. drvUserGetType and drvUserDestroy + typically do not need to be implemented in derived classes. +

+
+
     
+    virtual void report(FILE *fp, int details);
+    virtual asynStatus connect(asynUser *pasynUser);
+    virtual asynStatus disconnect(asynUser *pasynUser);
+
+

+ The report function prints information on registered interrupt clients + if details > 0, and prints parameter table information if details > 5. It is + typically called by the implementation of report in derived classes + before or after they print specific information about themselves. connect + and disconnect call pasynManager-> exceptionConnect + and pasynManager-> exceptionDisconnect respectively. Derived classes + may or may not need to implement these functions. +

+
+
     
+    virtual asynStatus setIntegerParam(int index, int value);
+    virtual asynStatus setIntegerParam(int list, int index, int value);
+    virtual asynStatus setDoubleParam(int index, double value);
+    virtual asynStatus setDoubleParam(int list, int index, double value);
+    virtual asynStatus setStringParam(int index, const char *value);
+    virtual asynStatus setStringParam(int list, int index, const char *value);
+    virtual asynStatus getIntegerParam(int index, int * value);
+    virtual asynStatus getIntegerParam(int list, int index, int * value);
+    virtual asynStatus getDoubleParam(int index, double * value);
+    virtual asynStatus getDoubleParam(int list, int index, double * value);
+    virtual asynStatus getStringParam(int index, int maxChars, char *value);
+    virtual asynStatus getStringParam(int list, int index, int maxChars, char *value);
+    virtual asynStatus callParamCallbacks();
+    virtual asynStatus callParamCallbacks(int list, int addr);
+
+

+ The setXXXParam methods set the value of a parameter in the parameter + table in the object. If the value is different from the previous value of the parameter + they also set the flag indicating that the value has changed. The getXXXParam + methods return the current value of the parameter. There are two versions of the + setXXXParam and getXXXParam methods, one with a list + argument, and one without. The one without uses list=0, since there + is often only a single parameter list (i.e. if maxAddr=1). The callParamCallbacks + methods call back any registered clients for parameters that have changed since + the last time callParamCallbacks was called. The version of callParamCallbacks + with no arguments uses the first parameter list and matches asyn address=0. There + is a second version of callParamCallbacks that takes an argument specifying + the parameter list number, and the asyn address to match. +

+
+

+ NDArray

+
+

+ 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: +

+
#define ND_ARRAY_MAX_DIMS 10
+
+/* Enumeration of array data types */
+typedef enum
+{
+    NDInt8,
+    NDUInt8,
+    NDInt16,
+    NDUInt16,
+    NDInt32,
+    NDUInt32,
+    NDFloat32,
+    NDFloat64
+} NDDataType_t;
+
+
+typedef struct NDDimension {
+    int size;
+    int offset;
+    int binning;
+    int reverse;
+} NDDimension_t;
+
+typedef struct NDArrayInfo {
+    int nElements;
+    int bytesPerElement;
+    int totalBytes;
+} NDArrayInfo_t;
+
+class NDArray {
+public:
+    /* Data: NOTE this must come first because ELLNODE must be first, i.e. same address as object */
+    /* The first 2 fields are used for the freelist */
+    ELLNODE node;
+    int referenceCount;
+    /* The NDArrayPool object that created this array */
+    void *owner;
+
+    int uniqueId;
+    double timeStamp;
+    int ndims;
+    NDDimension_t dims[ND_ARRAY_MAX_DIMS];
+    NDDataType_t dataType;
+    int dataSize;
+    void *pData;
+
+    /* Methods */
+    NDArray();
+    int          initDimension   (NDDimension_t *pDimension, int size);
+    int          getInfo         (NDArrayInfo_t *pInfo);
+    int          copy            (NDArray *pOut);
+    int          reserve(); 
+    int          release();
+};
+
+
+
+

+ 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 is not intended to contain meta-data describing how the data was collected, + etc. +

+

+ 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 NDDimension_t + structure. The fields in NDDimension_t are as follows: +

+ +

+ The first 3 data fields in the NDArray class, (node, referenceCount, owner) + are used by the NDArrayPool class discussed below. The remaining data fields are + as follows: +

+ +

+ The methods of the NDArray class are: +

+ +
+

+ NDArrayPool

+
+

+ 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. + 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 public interface of the NDArrayPool class is defined as follows: +

+
class NDArrayPool {
+public:
+                 NDArrayPool   (int maxBuffers, size_t maxMemory);
+    NDArray*     alloc         (int ndims, int *dims, NDDataType_t dataType, int dataSize, void *pData);
+    int          reserve       (NDArray *pArray); 
+    int          release       (NDArray *pArray);
+    int          convert       (NDArray *pIn, 
+                                NDArray **ppOut,
+                                NDDataType_t dataTypeOut,
+                                NDDimension_t *outDims);
+    int          report        (int details);     
+
+

+ The methods of the NDArrayPool class are: +

+ +
+

+ asynNDArrayDriver

+
+

+ asynNDArrayDriver inherits from asynPortDriver. It implements the asynGenericPointer + functions, assuming that these reference NDArray objects. This is the class from + which both plugins and area detector drivers are indirectly derived. Its public + interface is defined as follows: +

+
class asynNDArrayDriver : public asynPortDriver {
+public:
+    asynNDArrayDriver(const char *portName, int maxAddr, int paramTableSize, int maxBuffers, size_t maxMemory,
+                      int interfaceMask, int interruptMask);
+    virtual asynStatus readGenericPointer(asynUser *pasynUser, void *genericPointer);
+    virtual asynStatus writeGenericPointer(asynUser *pasynUser, void *genericPointer);
+    virtual void report(FILE *fp, int details);
+
+};
+
+

+ The methods of the asynNDArrayDriver class are: +

+ +
+

+ ADDriver

+
+

+ ADDriver inherits from asynNDArrayDriver. This is the class from which area detector + drivers are directly derived. Its public interface is defined as follows: +

+
class ADDriver : public asynNDArrayDriver {
+public:
+    ADDriver(const char *portName, int maxAddr, int paramTableSize, int maxBuffers, size_t maxMemory,
+             int interfaceMask, int interruptMask);
+                 
+    /* These are the methods that we override from asynPortDriver */
+     virtual asynStatus drvUserCreate(asynUser *pasynUser, const char *drvInfo, 
+                                     const char **pptypeName, size_t *psize);
+                                     
+    /* These are the methods that are new to this class */
+    int createFileName(int maxChars, char *fullFileName);
+
+

+ The methods of the ADDriver class are: +

+ +
+

+ ADStdDriverParams

+
+

+ The file ADStdDriverParams.h defines the following: +

+
/* Enumeration of shutter status */
+typedef enum
+{
+    ADShutterClosed, 
+    ADShutterOpen
+} ADShutterStatus_t;
+
+/* Enumeration of detector status */
+typedef enum
+{
+    ADStatusIdle,
+    ADStatusAcquire,
+    ADStatusReadout,
+    ASStatusCorrect,
+    ADStatusSaving,
+    ADStatusAborting,
+    ADStatusError,
+} ADStatus_t;
+
+typedef enum
+{
+    ADImageSingle,
+    ADImageMultiple,
+    ADImageContinuous
+} ADImageMode_t;
+
+typedef enum
+{
+    ADTriggerInternal,
+    ADTriggerExternal
+} ADTriggerMode_t;
+
+
+

+ It also defines parameters that all area detector drivers should implement if possible. + These parameters are defined by enum values with an associated asyn interface, and + access (read-only or read-write). The EPICS database ADBase.template provides access + to these standard driver parameters. The following table lists the standard driver + parameters. The columns are defined as follows: +

+ +

+ 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. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Parameter Definitions in ADStdDriverParams.h and EPICS Record Definitions in ADBase.template
+ Enum name + asyn interface + Access + Description + drvUser string + EPICS record name + EPICS record type
+ Information about the detector
+ ADManufacturer + asynOctet + r/o + Detector manufacturer name + MANUFACTURER + $(P)$(R)Manufacturer_RBV + stringin
+ ADModel + asynOctet + r/o + Detector model name + MODEL + $(P)$(R)Model_RBV + stringin
+ ADMaxSizeX + asynInt32 + r/o + Maximum (sensor) size in the X direction + MAX_SIZE_X + $(P)$(R)MaxSizeX_RBV + longin
+ ADMaxSizeY + asynInt32 + r/o + Maximum (sensor) size in the Y direction + MAX_SIZE_Y + $(P)$(R)MaxSizeY_RBV + longin
+ Detector readout control including gain, binning, region start and size, reversal
+ ADGain + asynFloat64 + r/w + Detector gain + GAIN + $(P)$(R)Gain
+ $(P)$(R)Gain_RBV
+ ao
+ ai
+ ADBinX + asynInt32 + r/w + Binning in the X direction + BIN_X + $(P)$(R)BinX
+ $(P)$(R)BinX_RBV
+ longout
+ longin
+ ADBinY + asynInt32 + r/w + Binning in the Y direction + BIN_Y + $(P)$(R)BinY
+ $(P)$(R)BinY_RBV
+ longout
+ longin
+ ADMinX + asynInt32 + r/w + First pixel to read in the X direction. +
+ 0 is the first pixel on the detector.
+ MIN_X + $(P)$(R)MinX
+ $(P)$(R)MinX_RBV
+ longout
+ longin
+ ADMinY + asynInt32 + r/w + First pixel to read in the Y direction.
+ 0 is the first pixel on the detector.
+ MIN_Y + $(P)$(R)MinY
+ $(P)$(R)MinY_RBV
+ longout
+ longin
+ ADSizeX + asynInt32 + r/w + Size of the region to read in the X direction + SIZE_X + $(P)$(R)SizeX
+ $(P)$(R)SizeX_RBV
+ longout
+ longin
+ ADSizeY + asynInt32 + r/w + Size of the region to read in the Y direction + SIZE_Y + $(P)$(R)SizeY
+ $(P)$(R)SizeY_RBV
+ longout
+ longin
+ ADReverseX + asynInt32 + r/w + Reverse image in the X direction
+ (0=No, 1=Yes)
+ REVERSE_X + $(P)$(R)ReverseX
+ $(P)$(R)ReverseX_RBV
+ longout
+ longin
+ ADReverseY + asynInt32 + r/w + Reverse image in the Y direction
+ (0=No, 1=Yes)
+ REVERSE_Y + $(P)$(R)ReverseY
+ $(P)$(R)ReverseY_RBV
+ longout
+ longin
+ Image and trigger modes
+ ADImageMode + asynInt32 + r/w + Image mode (ADImageMode_t). + IMAGE_MODE + $(P)$(R)ImageMode
+ $(P)$(R)ImageMode_RBV
+ mbbo
+ mbbi
+ ADTriggerMode + asynInt32 + r/w + Trigger mode (ADTriggerMode_t). + TRIGGER_MODE + $(P)$(R)TriggerMode
+ $(P)$(R)TriggerMode_RBV
+ mbbo
+ mbbi
+ Data type
+ ADDataType + asynInt32 + r/w + Data type (NDDataType_t). + DATA_TYPE + $(P)$(R)DataType
+ $(P)$(R)DataType_RBV
+ mbbo
+ mbbi
+ Actual dimensions of image data
+ ADImageSizeX + asynInt32 + r/o + Size of the image data in the X direction + IMAGE_SIZE_X + $(P)$(R)ImageSizeX_RBV + longin
+ ADImageSizeY + asynInt32 + r/o + Size of the image data in the Y direction + IMAGE_SIZE_Y + $(P)$(R)ImageSizeY_RBV + longin
+ ADImageSize + asynInt32 + r/o + Total size of image data in bytes + IMAGE_SIZE + $(P)$(R)ImageSize_RBV + longin
+ Acquisition time and period
+ ADAcquireTime + asynFloat64 + r/w + Acquisition time per image + ACQ_TIME + $(P)$(R)AcquireTime
+ $(P)$(R)AcquireTime_RBV
+ ao
+ ai
+ ADAcquirePeriod + asynFloat64 + r/w + Acquisition period between images + ACQ_PERIOD + $(P)$(R)AcquirePeriod
+ $(P)$(R)AcquirePeriod_RBV
+ ao
+ ai
+ Number of exposures and number of images
+ ADNumExposures + asynInt32 + r/w + Number of exposures per image to acquire + NEXPOSURES + $(P)$(R)NumExposures
+ $(P)$(R)NumExposures_RBV
+ longout
+ longin
+ ADNumImages + asynInt32 + r/w + Number of images to acquire in one acquisition sequence + NIMAGES + $(P)$(R)NumImages
+ $(P)$(R)NumImages_RBV
+ longout
+ longin
+ Acquisition control
+ ADAcquire + asynInt32 + r/w + Start (1) or stop (0) image acquisition. This record is linked to 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. + ACQUIRE + $(P)$(R)Acquire + bo
+ File saving parameters
+ ADFilePath + asynOctet + r/w + File path + FILE_PATH + $(P)$(R)FilePath
+ $(P)$(R)FilePath_RBV
+ waveform
+ waveform
+ ADFileName + asynOctet + r/w + File name + FILE_NAME + $(P)$(R)FileName
+ $(P)$(R)FileName_RBV
+ waveform
+ waveform
+ ADFileNumber + asynInt32 + r/w + File number + FILE_NUMBER + $(P)$(R)FileNumber
+ $(P)$(R)FileNumber_RBV
+ longout
+ longin
+ ADFileTemplate + asynOctet + r/w + Format string for constructing ADFullFileName from ADFilePath, ADFileName, and ADFileNumber. + The final file name (which is placed in ADFullFileName) is created with the following + code: +
        epicsSnprintf(FullFilename, sizeof(FullFilename), FileFormat, 
+                      FilePath, Filename, FileNumber);
+        
+ FilePath, Filename, FileNumber are converted in that order with FileFormat. An example + file format is "%s%s%4.4d.tif". 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 FileFormat as desired. If one does not want to have FileNumber in the file name + at all, then just omit the %d format specifier from FileFormat. If the client wishes + to construct the complete file name itself, then it can just put that file name + into ADFileFormat with no format specifiers at all, in which case ADFilePath, ADFileName, + and ADFileNumber will be ignored.
+ FILE_TEMPLATE + $(P)$(R)FileTemplate
+ $(P)$(R)FileTemplate_RBV
+ waveform
+ waveform
+ ADFullFileName + asynOctet + r/o + Full file name + FULL_FILE_NAME + $(P)$(R)FullFileName_RBV + waveform
+ waveform
+ ADAutoIncrement + asynInt32 + r/w + Auto-increment flag. Controls whether FileNumber is automatically incremented by + 1 each time an acquisition completes (0=No, 1=Yes) + AUTO_INCREMENT + $(P)$(R)AutoIncrement
+ $(P)$(R)AutoIncrement_RBV
+ bo
+ bi
+ ADAutoSave + asynInt32 + r/w + Auto-save flag (0=No, 1=Yes) + AUTO_SAVE + $(P)$(R)AutoSave
+ $(P)$(R)AutoSave_RBV
+ bo
+ bi
+ ADFileFormat + asynInt32 + r/w + File format. The format to write/read data in (e.g. TIFF, netCDF, etc.) + FILE_FORMAT + $(P)$(R)FileFormat
+ $(P)$(R)FileFormat_RBV
+ mbbo
+ mbbi
+ ADWriteFile + asynInt32 + r/w + Manually save the most recent image to a file when value=1 + WRITE_FILE + $(P)$(R)WriteFile + longout
+ ADReadFile + asynInt32 + r/w + Manually read a file when value=1 + READ_FILE + $(P)$(R)ReadFile + longout
+ Status information
+ ADStatus + asynInt32 + r/o + Acquisition status (ADStatus_t) + STATUS + $(P)$(R)DetectorState_RBV + mbbi
+ ADStatusMessage + asynOctet + r/o + Status message string + STATUS_MESSAGE + $(P)$(R)StatusMessage_RBV + waveform
+ ADStringToServer + asynOctet + r/o + String from driver to string-based vendor server + STRING_TO_SERVER + $(P)$(R)StringToServer_RBV + waveform
+ ADStringFromServer + asynOctet + r/o + String from string-based vendor server to driver + STRING_FROM_SERVER + $(P)$(R)StringFromServer_RBV + waveform
+ ADImageCounter + asynInt32 + r/w + Counter that increments by 1 each time an image is acquired + IMAGE_COUNTER + $(P)$(R)ImageCounter
+ $(P)$(R)ImageCounter_RBV
+ longout
+ longin
+ N/A + N/A + r/o + Rate (Hz) at which ImageCounter is incrementing. Computed in database. + N/A + $(P)$(R)ImageRate_RBV + calc
+ Shutter control. Note: no areaDetector drivers yet implement shutter control, and + these parameters may change in the near future.
+ ADShutter + asynInt32 + r/w + Shutter control (ADShutterStatus_t) + SHUTTER + $(P)$(R)ShutterMode
+ $(P)$(R)ShutterMode_RBV
+ mbbo
+ mbbi
+ Image data
+ NDArrayData + asynGenericPointer + r/w + The image data as an NDArray object + NDARRAY_DATA + N/A. EPICS access to image data is through NDStdArrays plugin. + N/A
+ asyn port information
+ N/A + N/A + N/A + The name of the asyn port for this driver + N/A + $(P)$(R)PortName_RBV + stringin
+ N/A + N/A + N/A + asyn record to control debugging (asynTrace) + N/A + $(P)$(R)AsynIO + asyn
+

+ The following is the MEDM screen that provides access to the parameters in ADStdDriverParams + 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, so detector-specific MEDM screens should generally be created + that only display the EPICS PVs for the features implemented for that detector. + Note that the section of the screen labeled "Shutter" is not currently implemented + for any areaDetector driver, and is subject to change in the near future. +

+
+
+ ADBase.png
+
+
+

+ Detector drivers

+
+

+ areaDetector has been designed to minimize the amount of work required to write + a new detector driver. These drivers are described in separate documents, linked + to by the table of contents at the top of this page. +

+ + diff --git a/documentation/pilatusDoc.html b/documentation/pilatusDoc.html index 560f78f..3043f22 100755 --- a/documentation/pilatusDoc.html +++ b/documentation/pilatusDoc.html @@ -1,1029 +1,944 @@ - - -areaDetector Pilatus driver - - - -
-

areaDetector Pilatus driver

- -

September 5, 2008

-

Mark Rivers

-

University of Chicago

-
- -

 

- -

Table of Contents

- - - -

- Introduction

- -This is a driver for the Pilatus pixel array detectors -Dectris. -It inherits from ADDriver and implements many of the parameters in ADStdDriverParams.h. -It also implements a number of parameters that are specific to the Pilatus detectors. -

-The interface to the detector is via a TCP/IP socket interface to the camserver server that Dectris provides. -The camserver program must be started before the areaDetector software is started, typically by running the -camonly script provided by Dectris. -

-

-The camserver program saves the data to disk as TIFF files. The areaDetector software reads these disk files in -order to read the data, because camserver does not provide another mechanism to access the data. -

-

- Implementation of standard driver parameters

- -

-The following table describes how the Pilatus driver implements some of the standard driver parameters. -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Parameter Definitions in pilatusDetector.cpp and EPICS Record Definitions in pilatus.template
Enum nameEPICS record nameDescription
ADTriggerMode$(P$(R)TriggerModeThe driver redefines the choices for the ADTriggerMode parameter (record $(P)$(R)TriggerMode) from ADStdDriverParams.h. - The choices for the Pilatus are: -
    -
  • Internal (external signal not used)
  • -
  • External Enable (count while external trigger line is high, readout on high to low transition)
  • -
  • External Trigger (begin acquisition sequence on high to low transition of external trigger line)
  • -
  • Multiple External Trigger (high to low transition on external signal triggers a single acquisition - for the programmed exposure time)
  • -
  • Alignment (collect images as fast as exposure time and readout permit, images written to a temporary file)
  • -
- The first 4 modes correspond directly to the camserver commands Exposure, - ExtEnable, ExtTrigger, and ExtMTrigger respectively. - Alignment mode uses the Exposure command as well, but continuously takes images into - the same temporary file (alignment.tif). -
ADExposureTime$(P$(R)ExposureTimeIn External Enable mode this value is not - used by camserver. However, it should be set larger than the maximum time exposure time from the - external source, so that pilatusROI.st can estimate how long - to wait for the data files to be created before timing out.
ADNumImages$(P$(R)NumImagesControls the number of images to acquire. It applies in all trigger modes except - Alignment.
ADExposurePeriod$(P$(R)ExposurePeriodControls the exposure period in seconds. It is only in Internal or External Trigger modes - when NumImages > 1.
ADNumExposures$(P$(R)NumExposuresControls the number of exposures per image. It is only used in External Enable mode.
ADAquire$(P$(R)AcquireControls the acquisition. Setting this to 1 starts image acquisition. - The driver sets the record to 0 when acquisition is complete. This means an entire - acquisition series if NImages > 1. Setting this to 0 aborts an acquisition. If the driver - was currently acquiring imges then this record will cause the "Stop" and "K" (Kill) commands to - be sent to camserver.
ADFilePath$(P$(R)FilePathControls the path for saving images. It must be a valid path for camserver - and for the areaDetector driver, which is normally running in an EPICS IOC. - If camserver and the EPICS IOC are not running on the same machine then soft links - will typically be used to make the paths look identical.
ADFileFormat$(P)$(R)FileFormatcamserver uses the file extension to determine what format to save the files in. 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 - areaDetectorDoc.html - is used as a basename. - The following examples show the interpretation of the basename. -
-      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, ...
-      
- - 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 is also constrained by the requested number of images.
- -

- Pilatus specific parameters

-

-The Pilatus driver implements the following parameters in addition to those in ADStdDriverParams.h: -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Parameter Definitions in pilatusDetector.cpp and EPICS Record Definitions in pilatus.template
Enum nameasyn interfaceAccessDescriptiondrvUser stringEPICS record nameEPICS record type
PilatusDelayTimeasynFloat64r/wDelay in seconds between the external trigger - and the start of image acquisition. It only applies in External Trigger modeDELAY_TIME$(P)$(R)DelayTimeao
PilatusThresholdasynFloat64r/wThreshold energy in keVTHRESHOLD$(P)$(R)ThresholdEnergyao
N/AN/Ar/wGain menu. Controls the value of Vrf, which determines the shaping time and gain of the - input amplifiers. The allowed values are: -
    -
  • 0 ("Fast/Low") Fastest shaping time (~125ns) and lowest gain.
  • -
  • 1 ("Medium/Medium") Medium shaping time (~200 ns) and medium gain.
  • -
  • 2 ("Slow/High") Slow shaping time (~400 ns) and high gain.
  • -
  • 3 ("Slow/Ultrahigh") Slowest peaking time (? ns) and highest gain.
  • -
N/A$(P)$(R)GainMenumbbo
PilatusArmedasynInt32r/oFlag to indicate when the Pilatus is ready to accept external trigger signals (0=not ready, 1=ready). - This should be used by clients to indicate when it is OK to start sending trigger pulses - to the Pilatus. If pulses are send before Armed=1 then the Pilatus may miss them, leading to - DMA timeout errors from camserverARMED$(P)$(R)Armedbi
PilatusTiffTimeoutasynFloat64r/wTimeout in seconds when reading a TIFF fileTIFF_TIMEOUT$(P)$(R)ReadTiffTimeoutao
PilatusBadPixelFileasynOctetr/wName of a file to be used to replace bad pixels. - If this record does not point to 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: -
-      badX1,badY1 replacementX1,replacementY1 
-      badX2,badY2 replacementX2,replacementY2
-      ...
-      
- 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 of the image files themselves. - The following is an example bad pixel file for a GSECARS detector: -
-          263,3   262,3
-          264,3   266,3
-          263,3   266,3
-          300,85  299,85
-          300,86  299,86
-          471,129 472,129
-      
BAD_PIXEL_FILE$(P)$(R)BadPixelFilewaveform
PilatusNumBadPixelsasynInt32r/oThe number of bad pixels defined in the bad pixel file. - Useful for seeing if the bad pixel file was read correctly.NUM_BAD_PIXELS$(P)$(R)NumBadPixelslongin
PilatusFlatFieldFileasynOctetr/wName of a file to be used to correct for the flat field. - If this record does not point to a valid flat field file then no flat field correction is performed. - The flat field file is simply a TIFF file collected by the Pilatus that is used to correct for - spatial non-uniformity in the response of the detector. It should be collected with a spatially uniform - intensity on the detector at roughly the same energy as the measurements being corrected. - When the flat field file is read, the average pixel value (averageFlatField) is computed - using all pixels with intensities > PilatusMinFlatField. 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: -
-            ImageData[i] = (averageFlatField * ImageData[i])/flatField[i];
-        
FLAT_FIELD_FILE$(P)$(R)FlatFieldFilewaveform
PilatusMinFlatFieldasynInt32r/wThe mimimum valid intensity in the flat field. This value must be set > 0 to prevent divide by 0 errors. - If the flat field was collected with some pixels having very low intensity then this value can be used to - replace those pixels with the average response.MIN_FLAT_FIELD$(P)$(R)MinFlatFieldlongout
PilatusFlatFieldValidasynInt32r/oThis record indicates if a valid flat field file has been read. 0=No, 1=Yes.FLAT_FIELD_VALID$(P)$(R)FlatFieldValidbi
N/AN/AN/Aasyn record to control debugging communication with camserverN/A$(P)$(R)CamserverAsynasyn
- - - - - - - -
  • FullFilename (waveform, FTVL=UCHAR, NELM=256)
    - This is a read-only record that contains the full filename of the current file, after the above - code has been executed. Note that the FullFilename is not constructed until Acquire is set to 1. - - -The SNL code supports up to 32 rectangular ROIs. Fewer ROIs can be used by loading the pilatusROI_N.template file -fewer than 32 times, and passing NROIS<32 to the SNL program when it is started. In the following -record names $(N) is a number from 1 to 32. ROIs can be any size from a single pixel to the entire -chip. -An ROI is considered invalid and ignorred by the SNL program if any of Xmin, Xmax, YMin, YMax is less than 0 or -greater than the size of the chip in that direction. The ROI is also invalid if Xmin>XMax or YMin>YMax. - -The ROI$(N)TotalCounts and ROI$(N)NetCounts are computed as each TIFF file is read, regardless of the -value of NImages. The ROI$(N)WFTotalCounts and ROI$(N)WFNetCounts arrays are computed and posted to -EPICS when acquiring data with NImages>1. The first element in each array is the for the first image -in the series, etc. - - - - -
  • FlatFieldValid (bo)
    - This record indicates if a valid flat field file has been read. 0=No, 1=Yes. - - - - - - -