.. _edt: EDT - :py:mod:`edt` Camera driver module ======================================== EDT refers to the C application program interface (API) for the Engineering Design Team series of frame-grabbers. ShaneAO uses two varieties of EDT frame-grabber: * EDT PCIe8 DVa C-Link for the wavefront sensor camera (160x160 pixel) * EDT PCIe4 DVa C-Link for the tip/tilt sensor camera (80x80 pixel) *class* Camera ~~~~~~~~~~~~~~~~~~~~~~ .. py:class:: edt.Camera((int)unit,(string)filename) Creates a new object of type Camera. An integer *unit* and configuration *filename* must be specified when creating a :class:`Camera` instance. A background pthread will be invoked to handle image acquisition; the handling of image data is determined dynamically via the :func:`handler` method. The currently used configuration files and unit numbers are: ================ ===================== ======= Camera Configuration File Unit ================ ===================== ======= Wavefront Sensor WFS_BigJoe.cfg 1 Tip/Tilt Sensor TipTilt_LittleJoe.cfg 0 ================ ===================== ======= Example of use:: import edt wfsCam = edt.Camera (1, 'WFS_BigJoe.cfg') wfsCam.handler('wfsFunction') ttCam = edt.Camera (0, 'TipTilt_LittleJoe.cfg') ttCam.handler('ttFunction') wfsCam.start() ttCam.start() ... wfsCam.stop() ttCam.stop() Methods ------- Exposures & Handler +++++++++++++++++++ .. py:function:: edt.Camera.handler(handler) Assign a handler function for any/all camera frames acquired by the background processing thread. The sole argument can be None, which will remove all handlers; it can be a single :class:`Handler` instance; and it can be an iterable sequence of :class:`Handler` instances. .. py:function:: edt.Camera.start() Request that the camera begin exposures, which should in turn prompt the background processing thread to handle the resulting images. .. py:function:: edt.Camera.stop() Request that the camera stop exposures, and pause all activity in the background processing thread. Camera Commands & Messages ++++++++++++++++++++++++++ .. py:function:: edt.Camera.messages() Retrieve all pending messages associated with this :class:`Camera` instance. If there are no messages, an empty tuple will be returned. Once retrieved, the internal queue of messages is emptied. .. py:function:: edt.Camera.notify() Different :class:`Camera` methods may generate messages that could be interpreted for the benefit of a single listening application, such as a KTL dispatcher. The *function* registered with :func:`notify` should accept no arguments, and is only invoked as an indication that events are available. To retrieve messages, invoke :func:`messages`. If *function* is set to None, notification will be "disabled." .. py:function:: edt.Camera.serial(string) Send a *command* string via the serial interface for this Camera instance. The response, if any, will be returned as a string; if there is an error with the command, a :class:`SerialException` will be raised. If *wait* is set to False, :func:`serial` will not wait for a response string, and will return None. In practice, all serial commands generate a response, even if it is just an ACK. .. warning:: If the serial command does generate a response, and *wait* is set to False, this can permanently confuse the edt kernel driver. At least, it does with version 4.2.1.7 of the driver. Queries that expect a response will return nothing; other queries may receive the response generated for a previous query. Unloading and reloading the driver fixes the problem. And yet, when this occurs, the serial_cmd binary continues to work normally; perhaps this is because it doesn't care about the return result from :func:`pdv_serial_wait`. .. py:function:: edt.Camera.timing() Return a dictionary containing the current timing information recorded in the :class:`Camera` instance by the background processing thread. Members ------- .. py:attribute:: edt.Camera.config EDT configuration file .. py:attribute:: edt.Camera.depth camera color depth .. py:attribute:: edt.Camera.handlers sequence of image handling functions .. py:attribute:: edt.Camera.height image height in pixels .. py:attribute:: edt.Camera.interval frame interval in microtenths .. py:attribute:: edt.Camera.processing frame processing in microtenths .. py:attribute:: edt.Camera.unit EDT device unit number .. py:attribute:: edt.Camera.width image width in pixels *class* Handler ~~~~~~~~~~~~~~~ .. py:class:: edt.Handler(CameraObject,(string)functionName) The :class:`Handler` class encapsulates all the necessary metadata for a single image analysis routine. Individual :class:`Handler` instances are linked to a single :class:`Camera` instance. The Handler object is tied to the given Camera object and provides the name of the c function. Calls dlsym() to resolve the pointer to the function with that name. Methods ------- .. py:function:: edt.Handler.configure(data,(string)functionName) A :class:`Handler` instance may be configured before it is invoked, or reconfigured at any time while a sequence of camera frames are being processed. :func:`configure` will block if the current :class:`Handler` instance is being run by the processing thread. The two arguments for :func:`configure` are a Python *data* object, and a C *function* name that will be used to interpret the *data* argument; Handler->pyobject will remain unchanged, leaving it for the *function* to manipulate directly. If a *function* is not specified, *data* will be assigned directly to Handler->pyobject. Members ------- .. py:attribute:: edt.Handler.name Handler function name Processing Thread ~~~~~~~~~~~~~~~~~ The *processingThread.c* file implements the background thread for camera data grabbing and processing. .. c:function:: frameProcessing(void *instance) Started up as a background thread during Camera initialization (*Camera_init*). :mod:`edt.Camera.start` will set self->pause = FALSE which will trigger calls to the handler routine by frameProcessing (line 147):: handler->function (handler, image_data); .. c:function:: void functionName (Camera *instance, u_char *data) All .c files in the directory ../handlers will be linked into the ../edt/edt.so module. Each "handler" defined here should have a function of the following form as its entry point:: void functionName (Camera *instance, u_char *data); Selection of which function to use to handle new data frames is performed via the :mod:`edt.Camera.handler` method. Some questions: * Looks like there is an inconsistency about the first argument - is it the pointer to the Camera instance, or the Handler instance? * How does one call the dpio2 object from this handler?