diff --git a/docs/PyVCAM.md b/docs/PyVCAM.md index f2cd908..a439fb3 100644 --- a/docs/PyVCAM.md +++ b/docs/PyVCAM.md @@ -5,11 +5,10 @@ * [Installing the Package](#installing-the-package) * [Creating a Wheel Package](#creating-a-wheel-package) * [Uninstalling the Package](#uninstalling-the-package) - * [`src` Folder](#src-folder) - * [`pyvcam` Folder](#pyvcam-folder) - * [`camera.py`](#camerapy) + * [`src/pyvcam` Folder](#srcpyvcam-folder) + * [`camera.py` aka `Camera` Class](#camerapy-aka-camera-class) * [Create Camera Example](#create-camera-example) - * [Methods of `Camera` class](#methods-of-camera-class) + * [Methods of `Camera` Class](#methods-of-camera-class) * [Camera Selection](#camera-selection) * [Basic Frame Acquisition](#basic-frame-acquisition) * [Advanced Frame Acquisition](#advanced-frame-acquisition) @@ -19,26 +18,13 @@ * [Properties](#properties) * [Using Properties](#using-properties) * [List of Properties](#list-of-properties) - * [`constants.py`](#constantspy) - * [`pvcmodule.cpp`](#pvcmodulecpp) - * [General Structure of a `pvc` Module Functions](#general-structure-of-a-pvc-module-functions) - * [Retrieving Data](#retrieving-data) - * [Arguments of `PyArg_ParseTuple`](#arguments-of-pyarg_parsetuple) - * [`PyArg_ParseTuple` Example](#pyarg_parsetuple-example) - * [Processing Acquired Data](#processing-acquired-data) - * [Return Data to a Python Script](#return-data-to-a-python-script) - * [Cast to Python Type](#cast-to-python-type) + * [`constants.py` aka `const` Module](#constantspy-aka-const-module) + * [`pvcmodule.cpp` aka `pvc` Module](#pvcmodulecpp-aka-pvc-module) * [Functions of `pvc` Module](#functions-of-pvc-module) - * [The Method Table](#the-method-table) - * [The Module Definition](#the-module-definition) - * [Module Creation](#module-creation) - * [Creating Extension Module](#creating-extension-module) - * [`constants_generator.py`](#constants_generatorpy) - * [Requirements](#requirements) - * [Running the Script](#running-the-script) - * [`tests` Folder](#tests-folder) + * [`examples` Folder](#examples-folder) * [`change_settings_test.py` (needs `camera_settings.py`)](#change_settings_testpy-needs-camera_settingspy) * [`check_frame_status.py`](#check_frame_statuspy) + * [`live_in_subprocess.py`](#live_in_subprocesspy) * [`live_mode.py`](#live_modepy) * [`multi_camera.py`](#multi_camerapy) * [`multi_rois.py`](#multi_roispy) @@ -48,35 +34,35 @@ * [`single_image_polling_show.py`](#single_image_polling_showpy) * [`stream_to_disk.py`](#stream_to_diskpy) * [`sw_trigger.py`](#sw_triggerpy) + * [`tests` Folder](#tests-folder) * [`test_camera.py`](#test_camerapy) *** ## Installing the Package -When you are ready to install the package, navigate to the directory that contains `pyproject.toml` -file and run `python -m pip install .`. +To install the latest stable version, simply run from anywhere `pip install PyVCAM`. + +Optionally, you can build and install the package from the sources. +Navigate to the directory that contains `pyproject.toml` file and run `pip install .`. +Please read the [README.md](https://github.com/Photometrics/PyVCAM/blob/master/README.md) +for more details. ## Creating a Wheel Package To create a PyVCAM Wheel package, navigate to the directory that contains `pyproject.toml` file and run `python -m build`. ## Uninstalling the Package -When you are ready to uninstall the package, run from anywhere `python -m pip uninstall PyVCAM`. +When you are ready to uninstall the package, run from anywhere `pip uninstall PyVCAM`. *** -## `src` Folder +## `src/pyvcam` Folder Where the source code of the `pyvcam` module is located. In addition to the code for the module, -any additional scripts that are used to help write the module are included as well. The most notable -helper script that is not included in the module is `constants_generator.py`, which generates the -`constants.py` module by parsing the PVCAM header file `pvcam.h`. - -## `pyvcam` Folder -The directory that contains the source code to the `pyvcam` module. These are the files installed -when users install the module. +any additional scripts that are used to help write the module are included as well. +These are the files installed when users install the module. -### `camera.py` +### `camera.py` aka `Camera` Class The `camera.py` module contains the `Camera` python class which is used to abstract the need to manually maintain, alter, and remember camera settings through PVCAM. @@ -93,41 +79,39 @@ cam = next(Camera.detect_camera()) # Use generator to find the first camera cam.open() # Open the camera ``` -#### Methods of `Camera` class +#### Methods of `Camera` Class ##### Camera Selection -| Method | Description | -|------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `__init__` | (Magic Method) The `Camera`'s constructor. Note that this method should not be used in the construction of a `Camera`. Instead, use the `detect_camera` class method to generate `Camera` classes of the currently available cameras connected to the system. | -| `__repr__` | (Magic Method) Returns the name of the camera. | -| `get_available_camera_names` | Return a list of camera names connected to the system. Use this method in conjunction with `select_camera`. Refer to `multi_camera.py` for a usage example. | -| `detect_camera` | (Class method) Generator that yields a `Camera` object for a camera connected to the system. For an example of how to call `detect_camera`, refer to the code samples for creating a camera. | -| `select_camera` | (Class method) Generator that yields a `Camera` object for the camera that matches the provided name. Use this method in conjunction with `get_available_camera_names`. Refer to `multi_camera.py` for a usage example. | -| `open` | Opens the camera. Will set `__handle` to the correct value and `__is_open` to `True` if a successful call to PVCAM's open camera function is made. A `RuntimeError` will be raised if the call to PVCAM fails. For more information about how Python interacts with the PVCAM library, refer to the `pvcmodule.cpp` section of these notes. | -| `close` | Closes the camera. Will set `__handle` to the default value for a closed camera (`-1`) and will set `__is_open` to `False` if a successful call to PVCAM's close camera function is made. A `RuntimeError` will be raised if the call to PVCAM fails. For more information about how Python interacts with the PVCAM library, refer to the `pvcmodule.cpp` section of these notes. | +| Method | Description | +|------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `__init__` | (Magic Method) The `Camera`'s constructor. Note that this method should not be used in the construction of a `Camera`. Instead, use the `detect_camera` class method to generate `Camera` classes of the currently available cameras connected to the system. | +| `__repr__` | (Magic Method) Returns the name of the camera. | +| `get_available_camera_names` | Return a list of camera names connected to the system. Use this method in conjunction with `select_camera`. Refer to `multi_camera.py` for a usage example. | +| `detect_camera` | (Class method) Generator that yields a `Camera` object for a camera connected to the system. For an example of how to call `detect_camera`, refer to the code samples for creating a camera. | +| `select_camera` | (Class method) Generator that yields a `Camera` object for the camera that matches the provided name. Use this method in conjunction with `get_available_camera_names`. Refer to `multi_camera.py` for a usage example. | +| `open` | Opens the camera. Will set `__handle` to the correct value and `__is_open` to `True` if a successful call to PVCAM's open camera function is made. A `RuntimeError` will be raised if the call to PVCAM fails. For more information about how Python interacts with the PVCAM library, refer to the `pvcmodule.cpp` section of these notes. | +| `close` | Closes the camera. Will set `__handle` to the default value for a closed camera (`-1`) and will set `__is_open` to `False` if a successful call to PVCAM's close camera function is made. A `RuntimeError` will be raised if the call to PVCAM fails. For more information about how Python interacts with the PVCAM library, refer to the `pvcmodule.cpp` section of these notes. | ##### Basic Frame Acquisition -| Method | Description | -|--------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `get_frame` | Calls the `pvc` module's `get_frame` function with current camera settings to get a 2D numpy array of pixel data from a single snap image. This method can either be called with or without a given exposure time. If given, the method will use the given parameter. Otherwise, if left out, will use the internal `exp_time` attribute.

**Parameters:**
| -| `get_sequence` | Calls the `pvc` module's `get_frame` function with cameras current settings in rapid-succession to get a 3D numpy array of pixel data from a single snap image. Multiple ROIs are not supported.

**Getting a sequence example:**
`# Given that the camera is already opened as openCam`
`stack = openCam.get_sequence(8) # Getting a sequence of 8 frames`
`firstFrame = stack[0] # Accessing 2D frames from 3D stack`
`lastFrame = stack[7]`

**Parameters:**
| -| `get_vtm_sequence` | Modified `get_sequence` to be used for Variable Timed Mode. Before calling it, set the camera's exposure mode to `'Variable Timed'`. The timings will always start at the first given and keep looping around until it is captured the number of frames given. Multiple ROIs are not supported.

**Parameters:**
| +| Method | Description | +|--------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `get_frame` | Calls the `pvc` module's `get_frame` function with current camera settings to get a 2D numpy array of pixel data from a single snap image. This method can either be called with or without a given exposure time. If given, the method will use the given parameter. Otherwise, if left out, will use the internal `exp_time` property.

**Parameters:**
| +| `get_sequence` | Calls the `pvc` module's `get_frame` function with cameras current settings in rapid-succession to get a 3D numpy array of pixel data from a single snap image. Multiple ROIs are not supported.

**Getting a sequence example:**
`# Given that the camera is already opened as openCam`
`stack = openCam.get_sequence(8) # Getting a sequence of 8 frames`
`firstFrame = stack[0] # Accessing 2D frames from 3D stack`
`lastFrame = stack[7]`

**Parameters:**
| +| `get_vtm_sequence` | Modified `get_sequence` to be used for Variable Timed Mode. Before calling it, set the camera's exposure mode to `'Variable Timed'`/`const.VARIABLE_TIMED_MODE`. If the camera doesn't support this mode or when the mode is not set, this function will emulate the same behavior as a sequence of single snaps with given exposure times. The timings will always start at the first given and keep looping around until it is captured the number of frames given. Multiple ROIs are not supported.

**Parameters:**
| ##### Advanced Frame Acquisition -| Method | Description | -|-----------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `start_live` | Calls `pvc.start_live` to setup a live mode acquisition. This must be called before `poll_frame`.

**Parameters:**
| -| `start_seq` | Calls `pvc.start_seq` to setup a sequence mode acquisition. This must be called before `poll_frame`.

**Parameters:**
| -| `check_frame_status` | Calls `pvc.check_frame_status` to report status of camera. This method can be called regardless of an acquisition being in progress.

**Parameters:**
| -| `poll_frame` | Returns a single frame as a dictionary with optional metadata if available. This method must be called after either `start_live` or `start_seq` and before either `abort` or `finish`. Pixel data can be accessed via the `'pixel_data'` key. Available metadata can be accessed via the `'meta_data'` key.

If multiple ROIs are set, pixel data will be a list of region pixel data of length number of ROIs. Metadata will also contain information for ech ROI.

Use `cam.set_param(constants.PARAM_METADATA_ENABLED, True)` or `cam.metadata_enabled = True` to enable the metadata.

**Parameters:**
| -| `reset_frame_counter` | Resets `frame_count` returned by `poll_frame` to zero.

**Parameters:**
| -| `abort` | Calls `pvc.abort` to return the camera to its normal state prior to completing acquisition.

**Parameters:**
| -| `finish` | Calls either `pvc.stop_live` or `pvc.finish_seq` to return the camera to its normal state after acquiring images.

**Parameters:**
| +| Method | Description | +|-----------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `start_live` | Calls `pvc.start_live` to setup a live mode acquisition. This must be called before `poll_frame`.

**Parameters:**
| +| `start_seq` | Calls `pvc.start_seq` to setup a sequence mode acquisition. This must be called before `poll_frame`.

**Parameters:**
| +| `check_frame_status` | Calls `pvc.check_frame_status` to report status of camera. This method can be called regardless of an acquisition being in progress.

**Parameters:**
| +| `poll_frame` | Returns a single frame as a dictionary with optional metadata if available. This method must be called after either `start_live` or `start_seq` and before `finish`. Pixel data can be accessed via the `'pixel_data'` key. Available metadata can be accessed via the `'meta_data'` key.

If multiple ROIs are set, pixel data will be a list of region pixel data of length number of ROIs. Metadata will also contain information for ech ROI.

Use `cam.set_param(constants.PARAM_METADATA_ENABLED, True)` or `cam.metadata_enabled = True` to enable the metadata.

**Parameters:**
| +| `finish` | Calls either `pvc.abort` or `pvc.finish_seq` to return the camera to its normal state after acquiring images.

**Parameters:**
| ##### Acquisition Configuration | Method | Description | |--------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `reset_rois` | Restores region of interest to default which is full frame with binning disabled.

**Parameters:**
| +| `reset_rois` | Restores region of interest to default which is full frame with binning disabled (1x1).

**Parameters:**
| | `set_roi` | Appends a new ROI to the camera's list of regions of interest. If the default ROI is currently set, this method will over-write that ROI. Each camera has a pre-defined maximum number of ROIs, which is typically 15. New ROIs can not exceed the boundaries of the sensor and can not overlap with existing ROIs.

**Parameters:**
| | `shape` | Returns the reshape factor to be used when acquiring a ROI. This is equivalent to an acquired images shape.

**Parameters:**
| @@ -139,11 +123,11 @@ cam.open() # Open the camera ##### Parameters | Method | Description | |-----------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `get_param` | Gets the current value of a specified attribute of given parameter. Usually not called directly since the properties (see below) will handle most cases of getting camera attributes. However, not all cases may be covered by the properties and a direct call may need to be made to PVCAM's `pl_get_param` function.

**Parameters**:
| -| `set_param` | Sets a specified camera parameter to a new value. Usually not called directly since the properties (see below) will handle most cases of setting camera attributes. However, not all cases may be covered by the properties and a direct call may need to be made to PVCAM's `pl_set_param` function.

**Parameters:**
| +| `get_param` | Gets the current value of a specified attribute of given PVCAM parameter. Usually not called directly since the properties (see below) will handle most cases of getting camera parameters. However, not all cases may be covered by the properties and a direct call may need to be made to PVCAM's `pl_get_param` function.

**Parameters**:
| +| `set_param` | Sets a specified camera parameter to a new value. Usually not called directly since the properties (see below) will handle most cases of setting camera parameters. However, not all cases may be covered by the properties and a direct call may need to be made to PVCAM's `pl_set_param` function.

**Parameters:**
| | `check_param` | Checks if a camera parameter is available. This method is useful for checking certain features are available (such as post-processing, expose out mode). Returns `True` if available, `False` if not.

**Parameters:**
| -| `get_post_processing_param` | Gets the current value of a specified post-processing parameter.

**Parameters**:
| -| `set_post_processing_param` | Sets the value of a specified post-processing parameter.

**Parameters**:
| +| `get_post_processing_param` | Gets the current value of a specified post-processing parameter.

**Parameters**:
| +| `set_post_processing_param` | Sets the value of a specified post-processing parameter.

**Parameters**:
| | `reset_pp` | If post-processing is available on the camera, the function will call `pvc.reset_pp` to reset all post-processing features back to their default state.

**Parameters:**
| | `read_enum` | Returns all settings names paired with their values of a specified setting.

**Parameters:**
| @@ -152,51 +136,50 @@ All properties are accessed via getters and setters. This means that it will app accessing instance variables from a camera, but in reality, these properties are making specially formatted calls to the `Camera` methods `get_param` and `set_param`. These getters and setters make use of the property decorator that is built into Python. The reasoning behind the usage of the -property decorator is that attributes will change dynamically during a `Camera`'s lifetime and in +property decorator is that properties will change dynamically during a `Camera`'s lifetime and in order to abstract PVCAM as far away from the end user as possible, the property decorator allows for users to intuitively view and change camera settings. The downside to this approach is that when a new parameter is required, an associated getter/setter -needs to be written and tested. Another downside to this implementation is that attribute lookup -time is not instant; instead, a call must be made to the `pvc` module wrapper which will then call -PVCAM, which will then return a result to the wrapper, which will finally return the result to the -user. The time it takes is currently considered -insignificant, but if this were to become an issue, the code could be refactored such that all -attributes also have instance variables which are changed only when `set_param` or their associated -setter is called on them. +needs to be written and tested. Another downside to this implementation is that property lookup +time is not instant; instead, a call must be made to the `pvc` module which will then call PVCAM, +which will then return a result to the wrapper, which will finally return the result to the user. +The time it takes is currently considered insignificant, but if this were to become an issue, +the code could be refactored such that all properties also have instance variables which are changed +only when `set_param` or their associated setter is called on them. ##### Using Properties ``` # Assume 'cam' is an already constructed 'Camera' instance -current_gain = cam.gain # To call getter, simply read the property value +current_gain = cam.gain # To call getter, simply read the property value cam.gain = current_gain # To call setter, simply assign new value to the property ``` ##### List of Properties | Property | Description | |-------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `adc_offset` | (read-only) **Warning: Camera specific setting. Not all cameras support this attribute. If an unsupported camera attempts to access it, an `AttributeError` will be raised.**

Returns the camera's current ADC offset value. Only CCD camera's have ADCs (analog-to-digital converters). | +| `adc_offset` | (read-only) **Warning: Camera specific setting. Not all cameras support this parameter. If an unsupported camera attempts to access it, an `AttributeError` will be raised.**

Returns the camera's current ADC offset value. Only CCD camera's have ADCs (analog-to-digital converters). | | `binning` | (read-write) Returns or changes the current serial and parallel binning values in a tuple.

The setter can be either a tuple for the binning (x, y) or a single value and will set a square binning with the given number, for example `cam.binning = x` makes `cam.__binning = (x, x)`.

Binning cannot be changed directly on the camera; but is used for setting up acquisitions and returning correctly shaped images returned from `get_frame`. The setter has built in checking to see that the given binning it able to be used later. Binning settings for individual ROIs is not supported. | | `binnings` | (read-only) Returns a list of supported combinations of serial and parallel binning factors if limited by the camera. If the camera supports arbitrary binning `None` is retuned. | | `bit_depth` | (read-only) Returns the native bit depth of pixel data for images collected with this camera.
Bit depth cannot be changed directly; instead, users must select a desired speed that has the desired bit depth. Note that a camera may have additional speed table entries for different readout ports. See [Port and Speed Choices](https://docs.teledynevisionsolutions.com/_speed_table.xhtml) section inside the PVCAM User Manual for a visual representation of a speed table and to see which settings are controlled by which speed is currently selected. | | `bit_depth_host` | (read-only) Returns the bit depth of pixel data outputted to the host. This parameter differs from the `bit_depth` in a way that it reports the bit depth of the output frame - a frame that is delivered to the host. Since PVCAM supports various host side post processing features, the host bit depth may differ from the native camera bit depth, depending on what host-side post processing features are active.
As a general rule, the application should always rely on the host-specific parameters when identifying the output data format. The native parameters should be used only for informational purposes, e.g. to show the camera native format in the GUI. | | `cam_fw` | (read-only) Returns the cameras current firmware version as a string. | -| `centroids_mode` | (read-write) **Warning: Camera specific setting. Not all cameras support this attribute. If an unsupported camera attempts to access it, an `AttributeError` will be raised.**

Returns/changes the current centroids mode, `'Locate'`, `'Track'` or `'Blob'`. | +| `centroids_mode` | (read-write) **Warning: Camera specific setting. Not all cameras support this parameter. If an unsupported camera attempts to access it, an `AttributeError` will be raised.**

Returns/changes the current centroids mode, `'Locate'`/`const.PL_CENTROIDS_MODE_LOCATE`, `'Track'`/`const.PL_CENTROIDS_MODE_TRACK` or `'Blob'`/`const.PL_CENTROIDS_MODE_BLOB`. | | `centroids_modes` | (read-only) Returns a dictionary containing centroid modes supported by the camera. | | `chip_name` | (read-only) Returns the camera sensor's name as a string. | -| `clear_mode` | (read-write): **Warning: Camera specific setting. Not all cameras support this attribute. If an unsupported camera attempts to access it, an `AttributeError` will be raised.**

Returns/changes the current clear mode of the camera. Note that clear modes have names, but PVCAM interprets them as integer values. When called as a getter, the integer value will be returned to the user. However, when changing the clear mode of a camera, either the integer value or the name of the clear mode can be specified. Refer to `constants.py` for the names of the clear modes. | +| `clear_mode` | (read-write): **Warning: Camera specific setting. Not all cameras support this parameter. If an unsupported camera attempts to access it, an `AttributeError` will be raised.**

Returns/changes the current clear mode of the camera. Note that clear modes have names, but PVCAM interprets them as integer values. When called as a getter, the integer value will be returned to the user. However, when changing the clear mode of a camera, either the integer value or the name of the clear mode can be specified. Refer to `constants.py` for the names of the clear modes. | | `clear_modes` | (read-only) Returns a dictionary containing clear modes supported by the camera. | -| `clear_time` | (read-only): **Warning: Camera specific setting. Not all cameras support this attribute. If an unsupported camera attempts to access it, an `AttributeError` will be raised.**

Returns the last acquisition's clearing time as reported by the camera in microseconds. | +| `clear_time` | (read-only): **Warning: Camera specific setting. Not all cameras support this parameter. If an unsupported camera attempts to access it, an `AttributeError` will be raised.**

Returns the last acquisition's clearing time as reported by the camera in microseconds. | | `driver_version` | (read-only) Returns a formatted string containing the major, minor, and build version. When `get_param` is called on the device driver version, it returns a highly formatted 16 bit integer. The first 8 bits correspond to the major version, bits 9-12 are the minor version, and the last nibble is the build number. | | `exp_mode` | (read-write): Returns or changes the current exposure mode of the camera. Note that exposure modes have names, but PVCAM interprets them as integer values. When called as a getter, the integer value will be returned to the user. However, when changing the exposure mode of a camera, either the integer value or the name of the expose out mode can be specified. Refer to `constants.py` for the names of the exposure modes. | | `exp_modes` | (read-only) Returns a dictionary containing exposure modes supported by the camera. | -| `exp_out_mode` | (read-write): **Warning: Camera specific setting. Not all cameras support this attribute. If an unsupported camera attempts to access it, an `AttributeError` will be raised.**

Returns or changes the current expose out mode of the camera. Note that expose out modes have names, but PVCAM interprets them as integer values. When called as a getter, the integer value will be returned to the user. However, when changing the expose out mode of a camera, either the integer value or the name of the expose out mode can be specified. Refer to `constants.py` for the names of the expose out modes. | +| `exp_out_mode` | (read-write): **Warning: Camera specific setting. Not all cameras support this parameter. If an unsupported camera attempts to access it, an `AttributeError` will be raised.**

Returns or changes the current expose out mode of the camera. Note that expose out modes have names, but PVCAM interprets them as integer values. When called as a getter, the integer value will be returned to the user. However, when changing the expose out mode of a camera, either the integer value or the name of the expose out mode can be specified. Refer to `constants.py` for the names of the expose out modes. | | `exp_out_modes` | (read-only) Returns a dictionary containing exposure out modes supported by the camera. | | `exp_res` | (Getter and setter) Returns/changes the current exposure resolution of a camera. Note that exposure resolutions have names, but PVCAM interprets them as integer values. When called as a getter, the integer value will be returned to the user. However, when changing the exposure resolution of a camera, either the integer value or the name of the resolution can be specified. Refer to `constants.py` for the names of the exposure resolutions. | | `exp_res_index` | (read-only): Returns the current exposure resolution index. | | `exp_resolutions` | (read-only) Returns a dictionary containing exposure resolutions supported by the camera. | | `exp_time` | (read-write): Returns or changes the exposure time the camera will use if not given an exposure time. It is recommended to modify this value to modify your acquisitions for better abstraction. | -| `fan_speed` | (read-write): **Warning: Camera specific setting. Not all cameras support this attribute. If an unsupported camera attempts to access it, an `AttributeError` will be raised.**

Returns/changes the current fan speed setpoint of the camera. Note that fan speeds have names, but PVCAM interprets them as integer values. When called as a getter, the integer value will be returned to the user. However, when changing the fan speed of a camera, either the integer value or the name of the fan speed can be specified. Refer to `constants.py` for the names of the fan speeds. | +| `fan_speed` | (read-write): **Warning: Camera specific setting. Not all cameras support this parameter. If an unsupported camera attempts to access it, an `AttributeError` will be raised.**

Returns/changes the current fan speed setpoint of the camera. Note that fan speeds have names, but PVCAM interprets them as integer values. When called as a getter, the integer value will be returned to the user. However, when changing the fan speed of a camera, either the integer value or the name of the fan speed can be specified. Refer to `constants.py` for the names of the fan speeds. | | `fan_speeds` | (read-only) Returns a dictionary containing fan speeds supported by the camera. | | `gain` | (read-write) Returns or changes the current gain index for a camera. A `ValueError` will be raised if an invalid gain index is supplied to the setter. After changing `readout_port` it is strongly recommended to re-apply the settings of `speed` and `gain` exactly in that order. | | `gain_name` | (read-only) Returns the name of currently selected gain via `gain` under selected port and speed. It is either hard-coded generic string or provided by the camera. | @@ -208,264 +191,82 @@ cam.gain = current_gain # To call setter, simply assign new value to the proper | `pix_time` | (read-only) Returns the camera's pixel time, which is the inverse of the speed of the camera. Pixel time cannot be changed directly; instead users must select a desired speed that has the desired pixel time. Note that a camera may have additional speed table entries for different readout ports. See [Port and Speed Choices](https://docs.teledynevisionsolutions.com/_speed_table.xhtml) section inside the PVCAM User Manual for a visual representation of a speed table and to see which settings are controlled by which speed table entry is currently selected. | | `port_speed_gain_table` | (read-only) Returns a dictionary containing the port, speed and gain table, which gives information such as bit depth and pixel time for each readout port, speed and gain. | | `post_processing_table` | (read-only) Returns a dictionary containing post-processing features and parameters as well as the minimum and maximum value for each parameter. | -| `post_trigger_delay` | (read-only): **Warning: Camera specific setting. Not all cameras support this attribute. If an unsupported camera attempts to access it, an `AttributeError` will be raised.**

Returns the last acquisition's post-trigger delay as reported by the camera in microseconds. | -| `pre_trigger_delay` | (read-only): **Warning: Camera specific setting. Not all cameras support this attribute. If an unsupported camera attempts to access it, an `AttributeError` will be raised.**

Returns the last acquisition's pre-trigger delay as reported by the camera in microseconds | -| `prog_scan_mode` | (read-write) **Warning: Camera specific setting. Not all cameras support this attribute. If an unsupported camera attempts to access it, an `AttributeError` will be raised.**

Returns/changes the current programmable scan mode, Auto, Line Delay or Scan Width. | +| `post_trigger_delay` | (read-only): **Warning: Camera specific setting. Not all cameras support this parameter. If an unsupported camera attempts to access it, an `AttributeError` will be raised.**

Returns the last acquisition's post-trigger delay as reported by the camera in microseconds. | +| `pre_trigger_delay` | (read-only): **Warning: Camera specific setting. Not all cameras support this parameter. If an unsupported camera attempts to access it, an `AttributeError` will be raised.**

Returns the last acquisition's pre-trigger delay as reported by the camera in microseconds | +| `prog_scan_mode` | (read-write) **Warning: Camera specific setting. Not all cameras support this parameter. If an unsupported camera attempts to access it, an `AttributeError` will be raised.**

Returns/changes the current programmable scan mode, `Auto`/`const.PL_SCAN_MODE_AUTO`, `Line Delay`/`const.PL_SCAN_MODE_PROGRAMMABLE_LINE_DELAY` or `Scan Width`/`const.PL_SCAN_MODE_PROGRAMMABLE_SCAN_WIDTH`. | | `prog_scan_modes` | (read-only) Returns a dictionary containing programmable scan modes supported by the camera. | -| `prog_scan_dir` | (read-write) **Warning: Camera specific setting. Not all camera's support this attribute. If an unsupported camera attempts to access its readout_port, an AttributeError will be raised.**

Returns/changes the current programmable scan direction, `'Auto'`, `'Line Delay'` or `'Scan Width'`. | +| `prog_scan_dir` | (read-write) **Warning: Camera specific setting. Not all camera's support this parameter. If an unsupported camera attempts to access its readout_port, an AttributeError will be raised.**

Returns/changes the current programmable scan direction, `'Down'`/`const.PL_SCAN_DIRECTION_DOWN`, `'Up'`/`const.PL_SCAN_DIRECTION_UP` or `'Down/Up Alternate'`/`const.PL_SCAN_DIRECTION_DOWN_UP`. | | `prog_scan_dirs` | (read-only) Returns a dictionary containing programmable scan directions supported by the camera. | -| `prog_scan_dir_reset` | (read-write) **Warning: Camera specific setting. Not all cameras support this attribute. If an unsupported camera attempts to access it, an `AttributeError` will be raised.**

Returns/changes scan direction reset state of camera. The parameter is used with alternate scan directions (down-up) to reset the direction with every acquisition. | -| `prog_scan_line_delay` | (read-write) **Warning: Camera specific setting. Not all cameras support this attribute. If an unsupported camera attempts to access it, an `AttributeError` will be raised.**

Returns/changes the scan line delay. The parameter access mode depends on the `prog_scan_mode` selection. | -| `prog_scan_width` | (read-write) **Warning: Camera specific setting. Not all cameras support this attribute. If an unsupported camera attempts to access it, an `AttributeError` will be raised.**

Returns/changes the scan width. The parameter access mode depends on the `prog_scan_mode` selection. | -| `readout_port` | (read-write) **Warning: Camera specific setting. Not all cameras support this attribute. If an unsupported camera attempts to access it, an `AttributeError` will be raised.**

Some cameras may have many readout ports, which are output nodes from which a pixel stream can be read from. After changing `readout_port` it is strongly recommended to re-apply the settings of `speed` and `gain` exactly in that order. For more information about readout ports, refer to the [Port and Speed Choices](https://docs.teledynevisionsolutions.com/_speed_table.xhtml) section inside the PVCAM User Manual. | +| `prog_scan_dir_reset` | (read-write) **Warning: Camera specific setting. Not all cameras support this parameter. If an unsupported camera attempts to access it, an `AttributeError` will be raised.**

Returns/changes scan direction reset state of camera. The parameter is used with alternate scan directions (down-up) to reset the direction with every acquisition. | +| `prog_scan_line_delay` | (read-write) **Warning: Camera specific setting. Not all cameras support this parameter. If an unsupported camera attempts to access it, an `AttributeError` will be raised.**

Returns/changes the scan line delay. The parameter access mode depends on the `prog_scan_mode` selection. | +| `prog_scan_width` | (read-write) **Warning: Camera specific setting. Not all cameras support this parameter. If an unsupported camera attempts to access it, an `AttributeError` will be raised.**

Returns/changes the scan width. The parameter access mode depends on the `prog_scan_mode` selection. | +| `readout_port` | (read-write) **Warning: Camera specific setting. Not all cameras support this parameter. If an unsupported camera attempts to access it, an `AttributeError` will be raised.**

Some cameras may have many readout ports, which are output nodes from which a pixel stream can be read from. After changing `readout_port` it is strongly recommended to re-apply the settings of `speed` and `gain` exactly in that order. For more information about readout ports, refer to the [Port and Speed Choices](https://docs.teledynevisionsolutions.com/_speed_table.xhtml) section inside the PVCAM User Manual. | | `readout_ports` | (read-only) Returns a dictionary containing readout ports supported by the camera. | | `readout_time` | (read-only): Returns the last acquisition's readout time as reported by the camera in microseconds. | -| `scan_line_time` | (Getter) **Warning: Camera specific setting. Not all cameras support this attribute. If an unsupported camera attempts to access it, an `AttributeError` will be raised.**

Returns the scan line time of camera in nano seconds. | +| `scan_line_time` | (Getter) **Warning: Camera specific setting. Not all cameras support this parameter. If an unsupported camera attempts to access it, an `AttributeError` will be raised.**

Returns the scan line time of camera in nano seconds. | | `sensor_size` | (read-only) Returns the sensor size of the current camera in a tuple in the form (serial sensor size, parallel sensor size) | | `serial_no` | (read-only) Returns the camera's serial number as a string. | | `speed` | (read-write) Returns or changes the current numerical index of the speed table of a camera. After changing `readout_port` it is strongly recommended to re-apply the settings of `speed` and `gain` exactly in that order. See the [Port and Speed Choices](https://docs.teledynevisionsolutions.com/_speed_table.xhtml) section inside the PVCAM User Manual for a detailed explanation about PVCAM speed tables. | | `speed_name` | (read-only) Returns the name of currently selected speed via `speed` under selected port. It is either hard-coded generic string or provided by the camera. | -| `temp` | (read-only): **Warning: Camera specific setting. Not all cameras support this attribute. If an unsupported camera attempts to access it, an `AttributeError` will be raised.**

Returns the current temperature of a camera in Celsius. | -| `temp_setpoint` | (read-write): **Warning: Camera specific setting. Not all cameras support this attribute. If an unsupported camera attempts to access it, an `AttributeError` will be raised.**

Returns/changes the camera's temperature setpoint. The temperature setpoint is the temperature that a camera will attempt to keep its temperature (in Celsius) at. | +| `temp` | (read-only): **Warning: Camera specific setting. Not all cameras support this parameter. If an unsupported camera attempts to access it, an `AttributeError` will be raised.**

Returns the current temperature of a camera in Celsius. | +| `temp_setpoint` | (read-write): **Warning: Camera specific setting. Not all cameras support this parameter. If an unsupported camera attempts to access it, an `AttributeError` will be raised.**

Returns/changes the camera's temperature setpoint. The temperature setpoint is the temperature that a camera will attempt to keep its temperature (in Celsius) at. | | `trigger_table` | (read-only) Returns a dictionary containing a table consisting of information of the last acquisition such as exposure time, readout time, clear time, pre-trigger delay, and post-trigger delay. If any of the parameters are unavailable, the dictionary item will be set to `'N/A'`. | -| `vtm_exp_time` | (read-write): **Warning: Camera specific setting. Not all cameras support this attribute. If an unsupported camera attempts to access it, an `AttributeError` will be raised.**

Returns or changes the variable timed exposure time the camera uses for the `'Variable Timed'` exposure mode. | +| `vtm_exp_time` | (read-write): **Warning: Camera specific setting. Not all cameras support this parameter. If an unsupported camera attempts to access it, an `AttributeError` will be raised.**

Returns or changes the variable timed exposure time the camera uses for the `'Variable Timed'` exposure mode.

Warning: New sequence acquisition must be started after setting this property to apply the value to the camera. Reading the value right after it was written will return a value from last VTM acquisition. If unsure, use `get_vtm_sequence` function instead. | -### `constants.py` +### `constants.py` aka `const` Module The `constants.py` is a large data file that contains various camera settings and internal PVCAM structures used to map meaningful variable names to predefined integer values that camera firmware interprets as settings. -This file is not (and should never be) constructed by hand. Instead, use the most recent version -of `pvcam.h` and run `constants_generator.py` to (re)build this file. A more detailed explanation -can be found under the `constants_generator.py` section, but the basic concept is that `pvcam.h` is -parsed line by line, finding all predefined constants, enums, and structs to grant Python users -access to the necessary data to perform basic PVCAM functions that have multiple settings. - -There are four main sections to this file that are found following a formatted comment like this -`# # # # # #`: - -1. Defines - 1. Much of the necessary data from `pvcam.h` is saved as C preprocessor macros which are easy to - strip from the file and construct a Python variable whose name is the macros name and the - value is what the macro expands to. - 2. Macros can be thought of as Python variables in this case, as none (of the necessary macros) - in `pvcam.h` expand to more than a literal. -2. Enums - 1. Enums (also known as enumerated types) are data types that contain named members used to - identify certain integer values. Typically, if no values are specified, the first member will - be assigned the value 0, and the successor will be 1+ the value of their predecessor. However, - you can specify specific numbers for all members. - 2. Vanilla Python has no enum type (it must be imported; see documentation here), and even still - Python's enum class behaves somewhat differently in terms of accessing members. Instead, we - will insert a comment above all enumerated types and have their members just be simple Python - variables whose values where the integer assigned to them in the `pvcam.h` file. -3. Structs - 1. Structs are preserved as Python classes. No testing/implementation has been done with these, - so results may be unexpected if implemented. -4. Added By Hand - 1. These are quality of life/readability dictionaries that map named settings of various camera - modes to their `pvcam.h` integer value. These allow for fast look-up and intuitive setting - changes for end users. - -### `pvcmodule.cpp` +This file is not (and should never be) constructed by hand. Instead, it is generated with the most +recent version of `pvcam.h` and by running `constants_generator.py`. + +### `pvcmodule.cpp` aka `pvc` Module The `pvcmodule.cpp` is a set of C++ functions that make use of and extend the Python C-API known as -a Python Extension Module. The need for a Python extension module is two-fold: first to allow +a Python Extension Module `pvc`. The need for a Python extension module is two-fold: first to allow communication between the static PVCAM library and Python scripts, and second for fast acquisition and conversion from native C types (namely C arrays of pixel data) to Python data types. The extension module needs to be compiled, so it will be necessary to have a C/C++ compiler to -successfully install this application. The module will be compiled into a shared-object library, -which can then be imported from Python; read more here. - -#### General Structure of a `pvc` Module Functions -The registered functions of a `pvc` module usually follow a three-step process: -1. Retrieve data from Python script -2. Process acquired data -3. Return data to Python script - -#### Retrieving Data -Functions receive data dynamically through use of parameters, and the `pvc` module's functions are -no different. However, the Python API states that all data is of type `PyObject`, which the C/C++ -programming language offer no builtin support for. In addition to, each Python-facing function must -only have two arguments: `PyObject* self` (a pointer to the instance of whichever Python object -called this C function) and `PyObject* args` (a Python tuple object that contains all the arguments -passed into the C function call). - -However, we can make use of the `PyArg_ParseTuple` (see example here) function from the Python API -to easily coerce the Python objects from the args tuple to their respective C type. In order for -the conversion to occur, we must specify which type we want to coerce each Python argument to using -a formatted string (see second argument for `PyArg_ParseTuple`). Each character in the formatted -string are known as "format units" and are interpreted in the same order that the variables for -the coerced C data are provided. Find below a small list of C data types and their corresponding -format units. Use Python documentation for complete list. - -| C Type | Character Representation | -|------------------------|--------------------------| -| `long` | `l` | -| `int` | `i` | -| `double` | `d` | -| `float` | `f` | -| string (`const char*`) | `s` | -| `PyObject` | `O` | - -#### Arguments of `PyArg_ParseTuple` -1. `args` (`PyObject*`) - A Python tuple object that contains the arguments from the Python function - call. For example, if a function call from Python is made: `my_c_func(1, "test")`, the `args` - tuple would contain two `PyObject` pointers: one to the Python integer 1 and another to the - Python Unicode-String `"test"`. -2. `format` (`const char*`) - A String containing the format units for all the arguments found in - the args in the same order in which they appear in the tuple. Going off of the example from the - previous argument, the desired formatted string would be `"is"`: `'i'` for the integer 1, and - `'s'` for the string `"test"`. - -In addition to these two arguments, addresses to the variables in which the coerced C data should be -stored must also be passed as arguments to the `PyArg_ParseTuple` call. (See example for more details). - -#### `PyArg_ParseTuple` Example -``` -static PyObject* example(PyObject* self, PyObject* args) -{ - int myNum; - char* myString; - PyArg_ParseTuple(args, "is", &myNum, &myString); - printf("myNum: %d\n", myNum); // Prints "myNum: 1" - printf("myString: %s\n", myString); // Prints "myString: test" - Py_RETURN_NONE; -} -``` - -#### Processing Acquired Data -Using the data supplied by the Python function call, we can now perform normal camera operations -using PVCAM library function calls. The most common form of processing acquired data is to read the -camera handle from the arguments provided, then performing a camera operation (changing/reading -settings, getting images, etc.) using the acquired handle to identify which camera to perform the -action on. - -Generally speaking, this part of the function should be very similar to writing normal C/C++ modules -that use the PVCAM library. If there is any confusion about how to write C/C++ code to make calls to -PVCAM, refer to the PvcamCodeSamples found in the Examples directory of the PVCAM SDK. - -Sometimes, processing data from a Python function call may entail answering a query. If this is the -case, we need to specify what to return, and how to convert it into a corresponding Python type. - -#### Return Data to a Python Script -Similar to how issues arose when passing data from the Python function call to the C/C++ module, -there is no simple casting solution to convert C/C++ data types to Python data types when returning -from a function. - -Thankfully, there are some functions that were included in the Python header file included at the -top of each module to allow us to cast data to an equivalent Python type. - -#### Cast to Python Type -``` -{ - ... - const char* myString = "ika"; - return PyUnicode_FromString(myString); // Returns a Python string back to the calling function -} -``` - -There is one small catch, however. All Python functions must return an object; there is no such -thing as a `void` function. This means that we must always return something in our C/C++ modules as -well (which we can tell by looking at the signature). -If you wish to return `None`, simply use the `Py_RETURN_NONE` macro (see the `PyArg_ParseTuple` -example for a visual representation). +successfully install PyVCAM. The module will be compiled into a shared-object library, +which can then be imported from Python. #### Functions of `pvc` Module **Note:** All functions will always have the `PyObject* self` and `PyObject* args` parameters. When parameters are listed, they are the Python parameters that are passed into the module. -| Function Name | Description | -|---------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `pvc_abort` | Given a camera handle, aborts any ongoing acquisition and de-registers the frame handler callback function.

**Parameters:**