This Julia package implements an
interface to some
Andor cameras via the Andor Software
Development Kit (SDK). As of version 3.13 of the SDK, the Neo, Zyla,
Apogee and iStar-SCMOS Andor cameras should be supported. The
AndorCameras package has been tested on under Linux on the Zyla (USB-3
connected) camera, I am interested in feedback about other models.
This document describes:
-
the standard interface which implements all the methods specified by the
ScientificCamerasinterface; -
the advanced interface which provides access to all Andor cameras features and commands;
-
the installation of the
AndorCameraspackage.
To use the AndorCameras package, just write:
using AndorCameraswhich provides all the methods specified by the
ScientificCameras interface.
This interface is fully documented
here and summarized below.
You may also want to:
using AndorCameras.Featuresto use the advanced interface.
To open an Andor camera:
cam = open(AndorCameras.Camera, dev)with dev the device number (0 is the first device). To figure out how many
Andor devices are available:
AndorCameras.getnumberofdevices()To disconnect a camera from the hardware:
close(cam)Note that this is automatically done when the camera instance is claimed by the garbage collector.
A region of interest (ROI) may be selected by:
setroi!(cam, [[xsub, ysub,] xoff, yoff,] width, height)where xsub and ysub are the dimensions of the macro-pixels (in pixels and
both assumed to be 1 if not specified), xoff and yoff are the offsets of
the ROI relative to the sensor (in pixels and both assumed to be 0 if not
specified), width and height are the dimensions of the ROI (in
macro-pixels).
Macro-pixels are blocks of xsub by ysub pixels when rebinning the pixels
of the sensor.
In the Andor SDK documentation, the rebinning features are
AOIHBin and AOIVBin, the offsets (plus one) are AOILeft and AOITop and
the dimensions of the ROI are AOIWidth and AOIHeight.
To query the current ROI call:
roi = getroi(cam)and to reset the ROI to use the full sensor with no rebinning, call:
resetroi!(cam)The full dimensions (in pixels) of the sensor are retrieved by:
fullwidth = getfullwidth(cam)
fullheight = getfullheight(cam)or by:
fullwidth, fullheight = getfullsize(cam)The setspeed! method let you choose the frame rate (fps in Hz) and the
exposure time (exp in seconds) for the captured images:
setspeed!(cam, fps, exp)To retrieve the actual values of these parameters:
fps, exp = getspeed(cam)To acquire a single image (with the current settings):
img = read(cam)which yield an image in the form of a 2D Julia array. To acquire a sequence of
n images:
imgs = read(cam, n)which yields a vector of images: imgs[1], imgs[2], ..., imgs[n]. The
returned images are Julia 2D arrays of same dimensions as the selected region
of interest (ROI) and whose element type is derived from the pixel format of
the camera as given by:
getcapturebitstype(cam)You may specify another element type, say T, for the acquired images:
img = read(cam, T)or
imgs = read(cam, T, n)but there may be restrictions.
The read methods have the following keywords:
-
Use keyword
skipto specify a number of images to skip. -
Use keyword
timeoutto specify the maximum amount of time (in seconds) to wait for acquisition to complete. If acquisition takes longer than this time, aScientificCameras.TimeoutErroris thrown unless keywordtruncateistrue(see below). The default timeout is computed from the acquisition rate and the total number of images. -
When reading a sequence of images, keyword
truncatemay be settrueto print a warning and return a truncated sequence instead of throwing an exception in case of timeout. -
Keyword
quietcan be settrueto suppress the printing of warning messages (see above).
Continuous acquisition (and processing) of images is typically done by:
start(cam, nbufs) # start continuous acquisition with `nbufs` cyclic buffers
while ! finished()
img, ticks = wait(cam, sec) # wait for next image, not longer than `sec` seconds
... # process the image
release(cam) # release the processed image
end
stop(cam) # stop acquisitionwhere it is assumed that finished() returns true when to stop and false
otherwise. Above, img is a 2D Julia array with the last captured image and
ticks is the corresponding timestamp in seconds. Releasing the captured
image with release(cam) when it has been processed is intended to recycle the
image buffer for another acquisition. When the returned image is independent
from the corresponding capture buffer, release(cam) does nothing. It is
nevertheless good practice to call this method when the captured image is no
longer needed because the code is more likely to work with no changes with
another camera.
You may specify another element type, say T, for the captured images:
start(cam, T, nbufs)This section describes advanced use of the interface to Andor cameras provided
by the AndorCameras module. This may be useful to perform specific
configuration or actions not covered by the general interface. Dealing with
all the features of Andor cameras is greatly simplified by the
provided Julia interface.
The constants defined in atcore.h are available in Julia, for instance
AndorCameras.AT_SUCCESS. All constants are prefixed with AT_ and may be
imported by:
using AndorCameras.Constantsso that you just have to write AT_SUCCESS instead of
AndorCameras.AT_SUCCESS.
Andor cameras have features whose value can be retrieved or set using the array index syntax:
cam[key]
cam[key] = valwhere cam is the camera instance, key is the considered feature and val
its value. Here key can be something like AndorCameras.SensorWidth or
just SensorWidth if you have imported all defined features by:
using AndorCameras.FeaturesFor instance:
using AndorCameras.Features
sensorwidth = cam[SensorWidth]
sensorheight = cam[SensorHeight]yields the full dimensions of the sensor of camera cam.
The names of the constants defining the existing features closely follow the Andor Software Development Kit documentation. This documentation should be consulted to figure out the supported features and their meaning. If specific features are missing, it is easy to define new ones.
Julia AndorCameras module takes care of the different kind of features
depending on the type of their values: integer, floating-point, string,
boolean or enumerated. Enumerated features can take integer or string
values, they are described below. There are also
command features which have no value but are used to send
commands to the camera.
To query whether a specific feature is implemented, or whether it is readable, writable or read-only, do one of:
isimplemented(cam, key)
isreadable(cam, key)
iswritable(cam, key)
isreadonly(cam, key)Integer and floating-point features may have restrictions on the allowed range of values. The minimum and maximum allowed values can be retrieved by:
minimum(cam, key)
maximum(cam, key)A string representation of feature key is obtained by:
repr(key)An enumerated feature can only have a limited number of predefined values.
These values can be set by an integer index or by their name. Assuming
cam is the camera instance:
cam[key] = idxor:
cam[key] = strwith key the enumerated feature, e.g. PixelEncoding, idx and str
the index and the name of the chosen value. The following expression:
cam[key]yields the current index of the enumerated feature. Note that enumeration
indices start at 1 (as do indices in Julia). The minimum and maximum
indices are respectively given by:
minimum(cam, key)
maximum(cam, key)the former always yields 1 for an enumerated feature.
To retrieve the string representation of the value an enumerated feature, do one of:
repr(cam, key)
repr(cam, key, idx)which respectively yield the string representation of the current value of the enumerated feature and of the value at a given index.
To query whether a given index is available or implemented for an enumerated feature, call respectively:
isavailable(cam, key, idx)
isimplemented(cam, key, idx)Command features (e.g. AcquisitionStart) are used to identify a specific
command to send to the camera. These features have no values. To send the
commmand cmd to the camera cam, you just have to:
send(cam, cmd)If specific features are not predefined by the AndorCameras package, you may
define them at run-time provided their name and type is known. For instance:
boolkey = AndorCameras.BooleanFeature("SomeBooleanFeature")
intkey = AndorCameras.IntegerFeature("SomeIntegerFeature")
enumkey = AndorCameras.EnumeratedFeature("SomeEnumeratedFeature")
fltkey = AndorCameras.FloatingPointFeature("SomeFloatingPointFeature")
strkey = AndorCameras.StringFeature("SomeStringFeature")would define 5 features of 5 different types given their names. These features can be used as any others. For instance:
cam[boolkey] = falseIf performance and readability are not an issue, a feature may be defined on the fly. For instance:
cam[AndorCameras.BooleanFeature("SomeBooleanFeature")] = falseThe easiest way to install AndorCameras is via the Julia registry
EmmtRegistry:
using Pkg
pkg"registry add https://github.com/emmt/EmmtRegistry"
pkg"add AndorCameras"
pkg"build AndorCameras"The build process assumes that Andor Software Development Kit
(SDK) has
been installed in the usual directory /usr/local/andor for Linux or
C:/Program Files/AndorSDK3 for Windows (read the end of this section if you
have installed the SDK elsewhere).
If Andor SDK is not installed in the usual directory, you can define the
AT_DIR, AT_INCDIR and/or AT_LIBDIR environment variables before building
AndorCameras. These variables are used as follows:
-
AT_DIRis the directory where the Andor SDK has been installed. If this environment variable is not defined, it is assumed to be/usr/local/andorfor Linux orC:/Program Files/AndorSDK3for Windows. -
AT_INCDIRis the directory containing the Andor SDK header fileatcore.h. If this environment variable is not defined, the header file is searched in directories$AT_DIR/includeand$AT_DIR(in that order). -
AT_LIBDIRis the directory containing the Andor SDK library (libatcore.soon Linux,atcore.dllon Windows). If this environment variable is not defined, the library is searched in directories$AT_DIR/liband$AT_DIR(in that order).
For instance id Andor SDK has been installed in /opt/andor, you can define
the AT_DIR environment variable in Julia by:
ENV["AT_DIR"] = "/opt/andor"before building AndorCamera:
using Pkg
pkg"build AndorCameras"