Cmad Manual

NAME

cmad - areaDetector API for CameraMan

SYNOPSIS

#include <cmad.h>
struct cmad_client *
cmad_client_new(const char *pv_prefix, unsigned long image_width,
    unsigned long image_height, double timeout);
void
cmad_client_free(struct cmad_client *client);
const char *
cmad_error(struct cmad_client *client);
int
cmad_is_connected(struct cmad_client *client);
int
cmad_is_ready(struct cmad_client *client);
int
cmad_start_image_capture(struct cmad_client *client);
int
cmad_stop_image_capture(struct cmad_client *client);
int
cmad_capture_image(struct cmad_client *client, unsigned char *buf,
    size_t buf_size);
int
cmad_capture_image_quick(struct cmad_client *client, unsigned char *buf,
    size_t buf_size);

DESCRIPTION

The cmad library provides an interface enabling CameraMan to capture images from an areaDetector IOC. The library connects to standard areaDetector PVs making it able to capture images from any camera or plug-in supported by areaDetector.

The cmad library is read-only with respect to the areaDetector IOC; it never writes to any areaDetector IOC PV.

An areaDetector IOC client is created by calling the cmad_client_new() function. This function will establish an EPICS CA (Channel Access) connection with the areaDetector IOC.

Before images can be captured, the cmad_start_image_capture() function must be called. This makes the cmad library fetch a new image from the areaDetector IOC whenever the image changes. The fetched image is stored in an internal buffer.

An image is captured by calling the cmad_capture_image() function. This copies the most recently fetched image from the internal buffer into the caller-supplied buffer.

After use, a client should be freed by calling cmad_client_free().

The cmad library is thread-safe. That is, it is permissible to call any API function from more than one thread concurrently. It is not permissible, however, to call any API function from more than one thread concurrently with the same client. Generally, a thread should have its own client, but if threads do share a client, they must coordinate to ensure only one thread is calling any API function at a time with that client. There is one exception to this rule: the cmad_is_connected() and cmad_is_ready() functions may be called concurrently from multiple threads with the same client.

In order for the cmad library to function properly with the areaDetector IOC, the areaDetector IOC must be configured as follows:

The process environment of the cmad library must also be set correctly. The cmad library connects to the areaDetector IOC using the C EPICS CA client library which is configured by setting environment variables in the environment of the process that calls into the cmad library. The environment variables are documented in the EPICS CA reference manual. One environment variable in particular, EPICS_CA_MAX_ARRAY_BYTES, will likely need to be set. It controls the size in bytes of the largest array that EPICS CA will handle. It defaults to 16384 (16 KB). It must be set to a size large enough to transmit the image being captured from the areaDetector IOC. The minimum value should be the image width multiplied by the image height multiplied by 3 (the number of color components multiplied by 1 (the number of bytes per color component)). For example, if the image width was 640 and the image height was 480, the EPICS_CA_MAX_ARRAY_BYTES environment variable should be set to a minimum of 921600 (640 times 480 times 3). Note that this environment variable also needs to be set correctly for the areaDetector IOC.

FUNCTIONS

The following functions create and free client objects:

cmad_client_new()
Allocates a new client object. pv_prefix is the PV prefix of the areaDetector IOC plug-in providing the images to be captured by the client (e.g., “13SIM1:image1:”). image_width is the number of pixels in a row. image_height is the number of pixels in a column. timeout is the maximum time in seconds to wait for an EPICS CA operation or an image capture to complete; it must be greater than zero.
cmad_client_free()
Frees a client object.

The following functions query a client for information:

cmad_error()
Gets the error message for the most recent function call that returned an error status. This will return NULL if there is no error message. The storage of the returned string is only valid until the next call to a cmad library API function or until the client is freed.
cmad_is_connected()
Answers whether the client is connected. “Connected” means the client is connected via EPICS CA to each of the needed PVs on the areaDetector IOC. Returns 1 if connected, 0 otherwise.
cmad_is_ready()
Answers whether the client is ready. “Ready” means the needed areaDetector IOC PVs have values that match or are within a range of values required by the cmad library to capture images. Returns 1 if ready, 0 otherwise.

The following functions start and stop image capturing for a client:

cmad_start_image_capture()
Starts image capturing. While connected and ready, images are transferred from the areaDetector IOC to an internal image buffer for the client. This occurs as fast as the cmad library is able to read images produced by the areaDetector IOC.
cmad_stop_image_capture()
Stops image capturing. While stopped, no images are transferred from the areaDetector IOC to the cmad library.

The following functions capture images:

cmad_capture_image()
Reads an image into buf. buf_size is the size of buf and must be greater than or equal to the size of the image. The size of the image is the product of the image width, the image height, and 3, where the image width and the image height are the image_width and image_height arguments, respectively, passed to the cmad_client_new() function that created the client. For example, if the image width was 640 and the image height was 480, the size of buf would need to be 921600 or greater.

This function blocks until the client is connected, ready, and a new image is available from the areaDetector IOC, or until the timeout (specified when the client was created) is reached. Since the cmad library is designed to capture images from an areaDetector IOC that is continuously acquiring images, it does not directly trigger the acquisition of an image when this function is called. Rather, it waits for notification from the areaDetector IOC that a new image has been acquired and then fetches it. This means there is a small window of time between when an image is acquired and when the cmad library receives notification that it has been acquired, where it is possible that the image captured by this function was actually acquired a short time before this function was called. A calling program that cannot tolerate this will need to do additional work to ensure the captured image was acquired after this function was called. One approach would be to introduce a delay before calling this function equal to the acquire period of the areaDetector IOC. Another approach would be to call this function twice and only use the image read by the second call.

cmad_capture_image_quick()
Reads an image into buf. The arguments are the same as for the cmad_capture_image() function. This function is similar to cmad_capture_image() and will block until the client is connected and ready, or until the timeout (specified when the client was created) is reached, but it does not wait for a new image to become available from the areaDetector IOC, hence the “quick” in the function name. Instead, it captures the latest image that has already been received by the cmad library from the areaDetector IOC. This is well-suited for video capture where a continuous stream of images at an image rate appropriate for video is more desirable than an acquired-after relation.

RETURN VALUES

Functions that return an int will return 0 on success and -1 on error, with the exception of cmad_is_connected() and cmad_is_ready() which return different values as stated above. Functions that return a pointer will return NULL on error, with the exception of cmad_error() which may return NULL on success as stated above.