areaDetector Simulation driver

January 30, 2009

Mark Rivers

University of Chicago

 

Table of Contents

Introduction

simDetector is a driver for a simulated area detector. It inherits from ADDriver. The simulation detector implements nearly all of the parameters defined in ADStdDriverParams.h, with the exception of the file saving parameters, which it does not implement. It also implements a few parameters that are specific to the simulation detector. The simulation detector is useful as a model for writing real detector drivers. It is also very useful for testing plugins and channel access clients. This is part of the definition of the simDetector class:

class simDetector : public ADDriver {
public:
    simDetector(const char *portName, int maxSizeX, int maxSizeY, NDDataType_t dataType,
                int maxBuffers, size_t maxMemory);
                 
    /* These are the methods that we override from ADDriver */
    virtual asynStatus writeInt32(asynUser *pasynUser, epicsInt32 value);
    virtual asynStatus writeFloat64(asynUser *pasynUser, epicsFloat64 value);
    virtual asynStatus drvUserCreate(asynUser *pasynUser, const char *drvInfo, 
                                     const char **pptypeName, size_t *psize);
    void report(FILE *fp, int details);

In the constructor simDetector the portName, maxBuffers, and maxMemory arguments are passed to the ADDriver base class constructor. The maxSizeX, maxSizeY, and dataType arguments are specific to the simulation driver, controlling the maximum image size and initial data type of the computed images. The writeInt32 and writeFloat64 methods override those in the base class. The driver takes action when new parameters are passed via those interfaces. For example, the ADAcquire parameter (on the asynInt32 interface) is used to turn acquisition (i.e. computing new images) on and off.

The simulation driver initially sets the image[i, j] = i*gainX + j*gainY * gain * exposureTime * 1000. Thus the image is a linear ramp in the X and Y directions, with the gains in each direction being detector-specific parameters. Each subsquent acquisition increments each pixel value by gain*exposureTime*1000. Thus if gain=1 and exposureTime=.001 second then the pixels are incremented by 1. If the array is an unsigned 8 or 16 bit integer then the pixels will overflow and wrap around to 0 after some period of time. This gives the appearance of bands that appear to move with time. The slope of the bands and their periodicity can be adjusted by changing the gains and exposure times.

The driver creates a thread that waits for a signal to start acquisition. When acquisition is started that thread computes new images and then calls back any registered plugins as follows:

        /* Put the frame number and time stamp into the buffer */
        pImage->uniqueId = imageCounter;
        pImage->timeStamp = startTime.secPastEpoch + startTime.nsec / 1.e9;
        
        /* Call the NDArray callback */
        /* Must release the lock here, or we can get into a deadlock, because we can
         * block on the plugin lock, and the plugin can be calling us */
        epicsMutexUnlock(this->mutexId);
        asynPrint(this->pasynUser, ASYN_TRACE_FLOW, 
             "%s:%s: calling imageData callback\n", driverName, functionName);
        doCallbacksGenericPointer(pImage, NDArrayData, addr);
        epicsMutexLock(this->mutexId);

Simulation driver specific parameters

The simulation driver-specific parameters are the following:

Parameter Definitions in simDetector.cpp and EPICS Record Definitions in simDetector.template
Enum name asyn interface Access Description drvUser string EPICS record name EPICS record type
SimGainX asynFloat64 r/w Gain in the X direction SIM_GAINX $(P)$(R)GainX
$(P)$(R)GainX_RBV
ao
ai
SimGainY asynFloat64 r/w Gain in the Y direction SIM_GAINY $(P)$(R)GainY
$(P)$(R)GainY_RBV
ao
ai
SimResetImage asynInt32 r/w Reset image back to initial conditions when 1. RESET_IMAGE $(P)$(R)Reset
$(P)$(R)Reset_RBV
longout
longin

Unsupported standard driver parameters

Screenshots

The following is the MEDM screen ADBase.adl connected to a simulation detector.

ADBase.adl

ADBase_sim.png

The following is the MEDM screen that provides access to the specific parameters for the simulation detector.

simDetector.adl

simDetector.png

The following is an IDL epics_ad_display screen using image_display to display the simulation detector images.

epics_ad_display.pro

simDetector_image_display.png

Configuration

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

simDetectorConfig(const char *portName, int maxSizeX, int maxSizeY, 
                  int dataType, int maxBuffers, size_t maxMemory)
  
Argument Description
portName The name of the asyn port for this detector.
maxSizeX Maximum number of pixels in the X direction for the simulated detector.
maxSizeY Maximum number of pixels in the Y direction for the simulated detector.
dataType Initial data type of the detector data. These are the enum values for NDDataType_t, i.e.
  • 0=NDInt8
  • 1=NDUInt8
  • 2=NDInt16
  • 3=NDUInt16
  • 4=NDInt32
  • 5=NDUInt32
  • 6=NDFloat32
  • 7=NDFloat64
maxBuffers Maxiumum number of NDArray objects (image buffers) this driver is allowed to allocate. The driver itself requires 2 buffers, and each queue element in a plugin can require one buffer. So, for example, if 3 plugins are connected to this driver, and each has a queue size of 10, then maxBuffers should be at least 32.
maxMemory Maxiumum number of bytes of memory for all NDArray objects (image buffers) allocated by this driver. If maxSizeX=maxSizeY=1024, and maxBuffers=32, then maxMemory should be at least 33554432 (32MB).

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

The areaDetector software comes with an example IOC for the simulation driver, iocBoot/iocSimDetector.