Camera helpers¶
Every camera driver built on CameraTemplate can offer five
properties. Each reads and writes the active configuration. Exposure time, binning and frame rate have the same units
for all drivers. The ROI uses the pixels of the vendor API and the gain the native unit of the driver, see
ROI units and Gain and frame rate.
Property |
Type |
Unit |
|---|---|---|
|
seconds |
|
|
pixels of the vendor API, see ROI units |
|
|
pixel factors |
|
|
driver specific, see Gain and frame rate |
|
|
Hz, |
The ROI and binning getters return a tuple or None, also if the stored configuration holds a list (for
example from a JSON file).
Reading¶
A getter returns None if the value is not set in the active configuration or if the driver does not support the
feature. supported_features() tells the cases apart. It
returns the sorted names of the properties the driver supports.
Some getters return None for stored values they cannot interpret, for example a DCAM binning mode that is not a
symmetric factor of 1, 2 or 4.
get_available_options() is the second
introspection call. It lists the raw device and configuration keys, which are the keys to use in a configuration
dict. supported_features() lists which helper properties the driver implements. On GenICam drivers the helpers
write keys that get_available_options() also lists, for example Gain and AcquisitionFrameRate.
Drivers whose vendor API cannot enumerate options raise NotImplementedError, for example
PvcamCamera.
Writing¶
A setter computes a configuration patch, merges it into the active configuration and calls
configure(). It fails in these ways:
The acquisition is running:
RuntimeError. Nothing is changed. Stop the acquisition and set again._set_configreturnsFalseor raises: the previous configuration is restored and the device is re-configured with it on a best-effort basis. A returnedFalseraisesRuntimeError, an exception from the driver is re-raised. If the re-configuration fails too, the error is logged and the hardware may be partially configured.The driver does not support the feature:
FeatureNotSupportedError, a subclass ofNotImplementedError. Nothing is changed.The driver supports the feature but the camera model has no node for it: the same error, naming the node. The previous configuration is restored. The IDS driver, for example, checks this.
The value is invalid for the driver:
ValueError. Nothing is changed. Examples are asymmetric DCAM binning or a PVCam exposure time that is not a whole number of microseconds.The patched configuration lacks a required config key:
ValueError. Nothing is changed.
Config key order¶
Most drivers apply the configuration in key order, for example the IDS driver, and the valid range of some properties
depends on others. A setter moves the keys of its patch to the end of the stored configuration of the active name, in patch order.
Keys that are also in default_config_dict keep their position in
get_configuration(), because the defaults
are merged first.
Example¶
from herosdevices.hardware.dummy.cameras import CameraDummy
camera = CameraDummy(config_dict={"default": {"exposure_time": 0.01}})
camera.supported_features()
camera.roi_coordinates # None, no ROI configured
camera.roi_coordinates = (0, 0, 256, 128)
camera.binning = (2, 2)
camera.roi_coordinates # (0, 0, 256, 128)
Writing a driver¶
The ten hooks _get_*/_set_* for exposure time, ROI, binning, gain and frame rate are optional. A feature
counts as supported if the subclass overrides both hooks of its pair. A pair with only one hook overridden is
unsupported, and a warning is logged the first time supported_features() is called for the class. The property
still calls the overridden hook, while the other direction raises
FeatureNotSupportedError.
A
_get_*hook reads the value from the stored configuration only (self.get_configuration()), never from the device. It may returnNone.A
_set_*hook only returns a configuration patch. It does not write to the device or changeself._config. The driver applies the patch in_set_config.A hook that needs another value, such as the binning for a ROI conversion, reads it from the configuration instead of calling the other hook, which may be unsupported.
If the device model may lack the node of a helper,
_set_configraisesFeatureNotSupportedErrorfor it. While a setter applies its patch, the patch keys are inself._patch_keys, so the driver can raise only for these keys and handle a missing node for a key from the user configuration as before. The setter restores the configuration and passes the error on.
To add a feature, add to CameraTemplate the pair of hooks with the
default body raise FeatureNotSupportedError(...) and the property. The getter returns None on
FeatureNotSupportedError. The setter passes the hook result to
_apply_config_patch. Add the pair to _FEATURE_HOOKS. In tests/hardware/test_camera_helpers.py, add a test
value to FEATURE_VALUES and the feature to the expected features of each driver that supports it.
ROI units¶
roi_coordinates is (x_offset, y_offset, width,
height) in the pixels the vendor API uses for its ROI. Some APIs count binned pixels once the binning is larger
than 1, for example the GenICam nodes OffsetX, OffsetY, Width and Height. The same values then cover a
different area of the sensor after the binning changes. Other APIs count unbinned sensor pixels. Check the vendor
documentation of the camera.
Gain and frame rate¶
The gain has no common unit. Each driver passes the value to its vendor API unchanged, for example to the GenICam
Gain node. The setter raises a ValueError for NaN, infinity, booleans and non-numbers. Range checks and
side effects, such as switching automatic gain off, depend on the driver and are described in its class documentation.
frame_rate is a limit, not a measurement. The camera may deliver fewer frames if the exposure time, the ROI or the
interface bandwidth do not allow the rate. Setting None removes the limit. The getter returns None for a
removed limit and also if no frame rate is configured or the driver does not support the feature. Use
supported_features() to tell unsupported from unlimited.
How a driver removes the limit depends on the vendor API, for example the IDS driver writes the maximum of the
AcquisitionFrameRate node.
The exposure time must not exceed the frame period. A driver that retries rejected keys after the others, for example
the IDS driver, accepts ExposureTime and AcquisitionFrameRate in either order.
The setter raises a ValueError for a frame rate that is not positive and finite. None is allowed.