├── .gitignore ├── LICENSE ├── README.md ├── docs ├── CheetSheet.txt └── PyVCAM Wrapper.md ├── setup.py ├── src ├── constants_generator.py └── pyvcam │ ├── __init__.py │ ├── camera.py │ ├── constants.py │ ├── pvcmodule.cpp │ └── pvcmodule.h └── tests ├── camera_settings.py ├── change_settings_test.py ├── check_frame_status.py ├── live_mode.py ├── meta_data.py ├── multi_camera.py ├── multi_rois.py ├── newest_frame.py ├── seq_mode.py ├── single_image_polling.py ├── single_image_polling_show.py ├── stream_to_disk.py ├── sw_trigger.py └── test_camera.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # poetry 98 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 99 | # This is especially recommended for binary packages to ensure reproducibility, and is more 100 | # commonly ignored for libraries. 101 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 102 | #poetry.lock 103 | 104 | # pdm 105 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 106 | #pdm.lock 107 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 108 | # in version control. 109 | # https://pdm.fming.dev/#use-with-ide 110 | .pdm.toml 111 | 112 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 113 | __pypackages__/ 114 | 115 | # Celery stuff 116 | celerybeat-schedule 117 | celerybeat.pid 118 | 119 | # SageMath parsed files 120 | *.sage.py 121 | 122 | # Environments 123 | .env 124 | .venv 125 | env/ 126 | venv/ 127 | ENV/ 128 | env.bak/ 129 | venv.bak/ 130 | 131 | # Spyder project settings 132 | .spyderproject 133 | .spyproject 134 | 135 | # Rope project settings 136 | .ropeproject 137 | 138 | # mkdocs documentation 139 | /site 140 | 141 | # mypy 142 | .mypy_cache/ 143 | .dmypy.json 144 | dmypy.json 145 | 146 | # Pyre type checker 147 | .pyre/ 148 | 149 | # pytype static type analyzer 150 | .pytype/ 151 | 152 | # Cython debug symbols 153 | cython_debug/ 154 | 155 | # PyCharm 156 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 157 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 158 | # and can be added to the global gitignore or merged into this file. For a more nuclear 159 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 160 | .idea/ 161 | 162 | # Act secrets (https://github.com/nektos/act) 163 | .secrets 164 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 HerrZiffer 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PyVCAM Wrapper 2 | 3 | PyVCAM Wrapper is a Python3.X wrapper for the PVCAM SDK. 4 | 5 | ## Getting Started 6 | Follow the instructions below to get PyVCAM up and running on your machine for development and testing. 7 | 8 | 9 | ### Prerequisites 10 | * An understanding of PVCAM is very helpful for understanding PyVCAM. 11 | * A C/C++ compiler is needed to build native source code. For Windows, MSVC 1928 was used for testing. 12 | * The newest version of Python 3 which can be downloaded [here](https://www.python.org/downloads/). 13 | * The latest PVCAM and PVCAM SDK which can be downloaded [here](https://www.photometrics.com/support/software/#software). 14 | * PyVCAM was developed and tested using Microsoft Windows 10/64-bit. The build package also supports Linux, but testing has been minimal. 15 | 16 | 17 | ### Installing 18 | When you are ready to install the wrapper use your command prompt to navigate into the directory that contains 19 | setup.py and run ```pip install .``` 20 | 21 | 22 | ### How to use the wrapper 23 | #### Create Camera Example 24 | This will create a camera object using the first camera that is found that can then be used to interact with the camera. 25 | ``` 26 | from pyvcam import pvc 27 | from pyvcam.camera import Camera 28 | 29 | pvc.init_pvcam() # Initialize PVCAM 30 | cam = next(Camera.detect_camera()) # Use generator to find first camera. 31 | cam.open() # Open the camera. 32 | ``` 33 | 34 | #### Single Image Example 35 | This captures a single image with a 20 ms exposure time and prints the values of the first 5 pixels. 36 | ``` 37 | # A camera object named cam has already been created 38 | frame = cam.get_frame(exp_time=20) 39 | print("First five pixels of frame: {}, {}, {}, {}, {}".format(*frame[:5])) 40 | ``` 41 | 42 | #### Changing Settings Example 43 | This is an example of how to change some of the settings on the cameras. 44 | ``` 45 | # A camera object named cam has already been created 46 | cam.clear_mode = "Never" 47 | cam.exp_mode = "Ext Trig Trig First" 48 | cam.readout_port = 0 49 | cam.speed_table_index = 0 50 | cam.gain = 1 51 | ``` 52 | 53 | More information on how to use this wrapper and how it works can be found [here](https://github.com/Photometrics/PyVCAM/blob/master/docs/PyVCAM%20Wrapper.md). 54 | -------------------------------------------------------------------------------- /docs/CheetSheet.txt: -------------------------------------------------------------------------------- 1 | [[Installation]] 2 | pip install . 3 | 4 | [[Camera Class]] 5 | 6 | [Camera Selection] 7 | get_available_camera_names 8 | detect_camera 9 | select_camera 10 | open 11 | close 12 | 13 | [Basic Frame Acquisition] 14 | get_frame 15 | get_sequence 16 | get_vtm_sequence 17 | 18 | [Advanced Frame Acquisition] 19 | start_live 20 | start_seq 21 | check_frame_status 22 | poll_frame 23 | abort 24 | finish 25 | 26 | [Configure Acquisition] 27 | update_mode 28 | reset_pp 29 | reset_rois 30 | set_roi 31 | 32 | [Parameters] 33 | get_param 34 | set_param 35 | check_param 36 | get_post_processing_param 37 | set_post_processing_param 38 | read_enum 39 | 40 | [Camera Object Data] 41 | centroids_modes 42 | clear_modes 43 | exp_modes 44 | exp_out_modes 45 | exp_resolutions 46 | handle 47 | is_open 48 | name 49 | port_speed_gain_table 50 | post_processing_table 51 | prog_scan_modes 52 | prog_scan_dirs 53 | rois 54 | shape 55 | 56 | [Camera Properties] 57 | adc_offset get 58 | bin_x get|set 59 | bin_y get|set 60 | binning get|set 61 | bit_depth get 62 | cam_fw get 63 | centroids_mode get|set 64 | chip_name get 65 | clear_mode get|set 66 | clear_time get 67 | driver_version get 68 | exp_mode get|set 69 | exp_out_mode get|set 70 | exp_res get|set 71 | exp_res_index get 72 | exp_time get|set 73 | gain get|set 74 | last_exp_time get 75 | meta_data_enabled get|set 76 | pix_time get 77 | post_trigger_delay get 78 | pre_trigger_delay get 79 | prog_scan_mode get|set 80 | prog_scan_dir get|set 81 | prog_scan_dir_reset get|set 82 | prog_scan_line_delay get|set 83 | prog_scan_width get|set 84 | readout_port get|set 85 | readout_time get 86 | scan_line_time get 87 | sensor_size get 88 | serial_no get 89 | speed_table_index get|set 90 | temp get 91 | temp_setpoint get|set 92 | trigger_table get 93 | vtm_exp_time get|set 94 | -------------------------------------------------------------------------------- /docs/PyVCAM Wrapper.md: -------------------------------------------------------------------------------- 1 | # PyVCAM Wrapper 2 | 3 | - [PyVCAM Wrapper](#pyvcam-wrapper) 4 | * [src](#src) 5 | * [pyvcam](#pyvcam) 6 | + [camera.py](#camerapy) 7 | - [Create Camera Example](#create-camera-example) 8 | - [Attributes of Camera:](#attributes-of-camera-) 9 | - [Methods of Camera:](#methods-of-camera-) 10 | * [Camera Selection](#camera-selection) 11 | * [Basic Frame Acquisition](#basic-frame-acquisition) 12 | * [Advanced Frame Acquisition](#advanced-frame-acquisition) 13 | * [Acquisition Trigger](#acquisition-trigger) 14 | * [Parameters](#parameters) 15 | * [Internal methods](#internal-methods) 16 | - [Getters/Setters of Camera:](#getters-setters-of-camera-) 17 | * [Using Getters/Setters](#using-getters-setters) 18 | * [List of Getters/Setters](#list-of-getters-setters) 19 | + [constants.py](#constantspy) 20 | + [pvcmodule.cpp](#pvcmodulecpp) 21 | - [General Structure of a pvcmodule Function](#general-structure-of-a-pvcmodule-function) 22 | - [Retrieving Data](#retrieving-data) 23 | - [Arguments of PyArg_ParseTuple](#arguments-of-pyarg-parsetuple) 24 | - [PyArg_ParseTuple Example](#pyarg-parsetuple-example) 25 | - [Processing Acquired Data](#processing-acquired-data) 26 | - [Return Data to a Python Script](#return-data-to-a-python-script) 27 | - [Cast to Python Type](#cast-to-python-type) 28 | - [Functions of pvcmodule.cpp](#functions-of-pvcmodulecpp) 29 | - [The Method Table](#the-method-table) 30 | - [The Module Definition](#the-module-definition) 31 | - [Module Creation](#module-creation) 32 | - [Creating Extension Module](#creating-extension-module) 33 | + [constants_generator.py](#constants-generatorpy) 34 | - [Requirements](#requirements) 35 | - [Running the Script](#running-the-script) 36 | * [tests](#tests) 37 | + [change_settings_test.py (needs camera_settings.py)](#change-settings-testpy--needs-camera-settingspy-) 38 | + [check_frame_status.py](#check-frame-statuspy) 39 | + [live_mode.py](#live-modepy) 40 | + [meta_data.py](#meta-datapy) 41 | + [multi_camera.py](#multi-camerapy) 42 | + [seq_mode.py](#seq-modepy) 43 | + [single_image_polling.py](#single-image-pollingpy) 44 | + [single_image_polling_show.py](#single-image-polling-showpy) 45 | + [sw_trigger.py](#sw-triggerpy) 46 | + [test_camera.py](#test-camerapy) 47 | * [setup.py](#setuppy) 48 | + [Variables](#variables) 49 | + [Installing the Package](#installing-the-package) 50 | - [setup.py Install Command](#setuppy-install-command) 51 | + [Creating a PyVCAM Wheel Package](#creating-a-pyvcam-wheel-package) 52 | - [setup.py Create Wheels Package Command](#setuppy-create-wheels-package-command) 53 | 54 | ## src 55 | 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. 56 | 57 | ## pyvcam 58 | The directory that contains the source code to the pyvcam module. These are the files installed when users install the module. 59 | 60 | ### camera.py 61 | 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. 62 | 63 | #### Create Camera Example 64 | This will create a camera object using the first camera that is found that can then be used to interact with the camera 65 | 66 | ``` 67 | from pyvcam import pvc 68 | from pyvcam.camera import Camera 69 | 70 | pvc.init_pvcam() # Initialize PVCAM 71 | cam = next(Camera.detect_camera()) # Use generator to find first camera. 72 | cam.open() # Open the camera. 73 | ``` 74 | 75 | #### Attributes of Camera: 76 | | Attribute | Description | 77 | | ------------- | ------------- | 78 | | __name | A private instance variable that contains the camera's name. Note that this should be a read only attribute, meaning it should never be changed or set. PVCAM will handle the generation of camera names and will be set to the appropriate name when a Camera is constructed. | 79 | | __handle | A private instance variable that contains the camera's handle. Note that this is a read only variable, meaning it should never be changed or set. PVCAM will handle the updating of this attribute when the camera is opened or closed. | 80 | | __is_open | A private instance variable that is set to True if the camera is currently opened and False otherwise. Note that this is a read only variable, meaning it should never changed or set. PVCAM will handle the updating of this attribute whenever a camera is opened or close. | 81 | | __acquisition_mode | A private instance variable that is to be used internally for determining camera status. The variable is set to Live upon calling start_live, Sequence upon calling start_seq or None upon calling finish. 82 | | __exposure_bytes| A private instance variable that is to be used internally for setting up and capturing a live image with a continuous circular buffer. Note that this is a read only variable, meaning that it should never be changed or set manually. This should only be modified/ read by the start_live and get_live_frame functions. | 83 | | __mode| A private instance variable that is to be used internally for setting the correct exposure mode and expose out mode for the camera acquisition setups. Note that his is a read only variable, meaning that it should never be changed or set manually. This should only be modified by the magic __init__ function and _update_mode function. If you want to change the mode, change the corresponding exposure modes with setters bellow. | 84 | | __exp_time | A private instance variable that is to be used internally as the default exposure time to be used for all exposures. Although this variable is read only, you can access it and change it with setters and getters below. The basic idea behind this abstraction is to use this variable all the time for all exposures, but if you need a single, quick capture at a specific exposure time, you can pass it in the get_frame, get_sequence, and get_live_frame functions as the optional parameter. | 85 | | __rois | A private instance variable that stores a list of regions of interest (rois) objects for acquisitions. A region of interest defines both a box of pixels and binning factors. It's used for setting up acquisitions with the specified rois and resizing the returned pixel data to 2D numpy array. Although this variable is read only, you can access/ modify it below with the set_roi and reset_rois functions. | 86 | | __dtype | A private instance variable that stores the numpy data type for the currently selected port and speed following a call to start_live or start_seq. | 87 | | __port_speed_gain_table | A private instance variable containing definitions of port, speeds and gains available on the camera. Definitions for each speed include pixel_time. Definitions for each gain include bit_depth. | 88 | | __post_processing_table | A private instance variable containing definitions of post-processing parameters available on the camera. The definitions include a valid range for each parameter. | 89 | | __centroids_modes | A private instance variable containing centroid modes supported by the camera. | 90 | | __clear_modes | A private instance variable containing clear modes supported by the camera. | 91 | | __exp_modes | A private instance variable containing exposure modes supported by the camera. | 92 | | __exp_out_modes | A private instance variable containing exposure out modes supported by the camera. | 93 | | __exp_resolutions | A private instance variable containing exposure resolutions supported by the camera. | 94 | | __prog_scan_modes | A private instance variable containing programmable scan modes supported by the camera. | 95 | | __prog_scan_dirs | A private instance variable containing programmable scan directions supported by the camera. | 96 | 97 | #### Methods of Camera: 98 | ##### Camera Selection 99 | | Method | Description | 100 | | ------------- | ------------- | 101 | | \_\_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 current system. | 102 | | \_\_repr__ | (Magic Method) Returns the name of the Camera.| 103 | | get_available_camera_names | Return a list of cameras connected to the system. Use this method in conjunction with select_camera. Refer to multi_camera.py for a usage example. | 104 | | 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 sample for creating a camera. | 105 | | 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. | 106 | | open | Opens a 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. | 107 | | close | Closes a 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. | 108 | 109 | ##### Basic Frame Acquisition 110 | | Method | Description | 111 | | ------------- | ------------- | 112 | | get_frame | Calls the pvcmodule's get_frame function with cameras current 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:**
| 113 | | get_sequence | Calls the pvcmodule'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.

**Example:**
**Getting a sequence**
*# 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:**
| 114 | | 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 its captured the number of frames given. Multiple ROIs are not supported.

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

**Parameters:**
| 120 | | start_seq | Calls pvc.start_seq to setup a seq mode acquisition. This must be called before poll_frame.

**Parameters:**
| 121 | | 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:**
| 122 | | poll_frame | Returns a single frame as a dictionary with optional meta data if available. This method must be called after either stat_live or start_seq and before either abort or finish. Pixel data can be accessed via the pixel_data key. Available meta data 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. Meta data will also contain information for ech ROI.

Use set_param(constants.PARAM_METADATA_ENABLED, True) to enable meta data.

**Parameters:**
| 123 | | abort | Calls pvc.abort to return the camera to it's normal state prior to completing acquisition.

**Parameters:**
| 124 | | finish | Calls either pvc.stop_live or finish_seq to return the camera to it's normal state after acquiring live images.

**Parameters:**
| 125 | 126 | ##### Acquisition Configuration 127 | | Method | Description | 128 | | ------------- | ------------- | 129 | | reset_rois | Restores region of interest to default which is full frame with binning disabled

**Parameters:**
| 130 | | 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:**
| 131 | | shape | Returns the reshape factor to be used when acquiring a ROI. This is equivalent to an acquired images shape.

**Parameters:**
| 132 | 133 | ##### Acquisition Trigger 134 | | Method | Description | 135 | | ------------- | ------------- | 136 | | sw_trigger | This method will issue a software trigger command to the camera. This command is only valid if the camera has been set use a software trigger. Refer to sw_trigger.py for an example. | 137 | 138 | ##### Parameters 139 | | Method | Description | 140 | | ------------- | ------------- | 141 | | get_param | (Method) Gets the current value of a specified parameter. Usually not called directly since the getters/setters (see below) will handle most cases of getting camera attributes. However, not all cases may be covered by the getters/setters and a direct call may need to be made to PVCAM's get_param function. For more information about how to use get_param, refer to the Using get_param and set_param section of the README for the project.

**Parameters**:
| 142 | | set_param| (Method) Sets a specified camera parameter to a new value. Usually not called directly since the getters/setters (see below) will handle most cases of setting camera attributes. However, not all cases may be covered by the getters/setters and a direct call may need to be made to PVCAM's set_param function. For more information about how to use set_param, refer to the Using get_param and set_param section of the README for the project.

**Parameters:**
| 143 | | check_param | (Method) 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:**
| 144 | | get_post_processing_param | (Method) Gets the current value of a specified post-processing parameter.

**Parameters**:
| 145 | | set_post_processing_param | (Method) Sets the value of a specified post-processing parameter.

**Parameters**:
| 146 | | 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:**
| 147 | | read_enum |(Method) Returns all settings names paired with their values of a specified setting.

**Parameters:**
| 148 | 149 | ##### Internal methods 150 | | Method | Description | 151 | | ------------- | ------------- | 152 | | _set_dtype | This method sets the __dtype attribute for numpy pixel data based on current port and speed settings.

**Parameters:**
| 153 | | _update_mode | This method updates the mode of the camera, which is the bit-wise or between exposure mode and expose out mode. It also sets up a temporary sequence to the exposure mode and expose out mode getters will read as expected. This should really only be called internally (and automatically) when exposure mode or expose out mode is modified.

       | 154 | 155 | #### Getters/Setters of Camera: 156 | All getters and setters can be accessed using the example below. There is one large implementation point to make note of: 157 | 158 | 159 | 160 | ##### Using Getters/Setters 161 | ``` 162 | # Assume cam is an already constructed camera. 163 | curr_gain = cam.gain # To call getter, simply access it by attribute from the camera. 164 | ``` 165 | ##### List of Getters/Setters 166 | | Attribute | Getter/Setter Description | 167 | | ------------- | ------------- | 168 | | adc_offset | (Getter only) **Warning: Camera specific setting. Not all camera's support this attribute. If an unsupported camera attempts to access it's readout_port, an AttributeError will be raised.**

Returns the camera's current ADC offset value. Only CCD camera's have ADCs (analog-to-digital converters). | 169 | | bin_x | (Getter and Setter) Returns/ changes the current serial binning value. **Deprecated, use binning **| 170 | | bin_y | (Getter and Setter) Returns/ changes the current parallel binning value. **Deprecated, use binning **| 171 | | binning | (Getter and Setter) Returns/ 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 and get_live_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.| 172 | | bit_depth | (Getter only) Returns the bit depth of pixel data for images collected with this camera. Bit depth cannot be changed directly; instead, users must select a desired speed table index value 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 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 index is currently selected. | 173 | | cam_fw | (Getter only) Returns the cameras current firmware version as a string. | 174 | | centroids_mode | (Getter and Setter) **Warning: Camera specific setting. Not all camera's support this attribute. If an unsupported camera attempts to access it's readout_port, an AttributeError will be raised.**

Returns/changes the current centroids mode, Locate, Track or Blob. | 175 | | centroids_modes | (Getter only) Returns a dictionary containing centroid modes supported by the camera. | 176 | | chip_name | (Getter only) Returns the camera sensor's name as a string. | 177 | | clear_mode | (Getter and Setter): **Warning: Camera specific setting. Not all camera's support this attribute. If an unsupported camera attempts to access it's readout_port, 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. | 178 | | clear_modes | (Getter only) Returns a dictionary containing clear modes supported by the camera. | 179 | | clear_time | (Getter only): **Warning: Camera specific setting. Not all camera's support this attribute. If an unsupported camera attempts to access it's readout_port, an AttributeError will be raised.**

Returns the last acquisition's clearing time as reported by the camera in microseconds. | 180 | | driver_version | (Getter 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.| 181 | | exp_mode | (Getter and Setter): Returns/ 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.| 182 | | exp_modes | (Getter only) Returns a dictionary containing exposure modes supported by the camera. | 183 | | exp_out_mode | (Getter and Setter): **Warning: Camera specific setting. Not all camera's support this attribute. If an unsupported camera attempts to access it's readout_port, an AttributeError will be raised.**

Returns/ 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.| 184 | | exp_out_modes | (Getter only) Returns a dictionary containing exposure out modes supported by the camera. | 185 | | 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. | 186 | | exp_res_index | (Getter only): Returns the current exposure resolution index. | 187 | | exp_resolutions | (Getter only) Returns a dictionary containing exposure resolutions supported by the camera. | 188 | | exp_time | (Getter and Setter): Returns/ 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. | 189 | | gain | (Getter and Setter) Returns/changes the current gain index for a camera. A ValueError will be raised if an invalid gain index is supplied to the setter. | 190 | | handle | (Getter only) Returns the value currently stored inside the Camera's __handle instance variable. | 191 | | is_open | (Getter only) Returns the value currently stored inside the Camera's __is_open instance variable. | 192 | | last_exp_time | (Getter only) Returns the last exposure time the camera used for the last successful non-variable timed mode acquisition in what ever time resolution it was captured at. | 193 | | name |(Getter only) Returns the value currently stored inside the Camera's __name instance variable.| 194 | | pix_time | (Getter 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 table index value 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 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 index is currently selected.| 195 | | port_speed_gain_table | (Getter 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 index and gain.| 196 | | post_processing_table | (Getter only) Returns a dictionary containing post-processing features and parameters as well as the minimum and maximum value for each parameter.| 197 | | post_trigger_delay | (Getter only): **Warning: Camera specific setting. Not all camera's support this attribute. If an unsupported camera attempts to access it's readout_port, an AttributeError will be raised.**

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

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

Returns/changes the current programmable scan mode, Auto, Line Delay or Scan Width. | 200 | | prog_scan_modes | (Getter only) Returns a dictionary containing programmable scan modes supported by the camera. | 201 | | prog_scan_dir | (Getter and Setter) **Warning: Camera specific setting. Not all camera's support this attribute. If an unsupported camera attempts to access it's readout_port, an AttributeError will be raised.**

Returns/changes the current programmable scan direction, Auto, Line Delay or Scan Width. | 202 | | prog_scan_dirs | (Getter only) Returns a dictionary containing programmable scan directions supported by the camera. | 203 | | prog_scan_dir_reset | (Getter and Setter) **Warning: Camera specific setting. Not all camera's support this attribute. If an unsupported camera attempts to access it's readout_port, 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. | 204 | | prog_scan_line_delay | (Getter and Setter) **Warning: Camera specific setting. Not all camera's support this attribute. If an unsupported camera attempts to access it's readout_port, an AttributeError will be raised.**

Returns/changes the scan line delay. The parameter access mode depends on the prog_scan_mode selection. | 205 | | prog_scan_width | (Getter and Setter) **Warning: Camera specific setting. Not all camera's support this attribute. If an unsupported camera attempts to access it's readout_port, an AttributeError will be raised.**

Returns/changes the scan width. The parameter access mode depends on the prog_scan_mode selection. | 206 | | readout_port |(Getter and Setter) **Warning: Camera specific setting. Not all camera's support this attribute. If an unsupported camera attempts to access it's readout_port, an AttributeError will be raised.**

Some camera's may have many readout ports, which are output nodes from which a pixel stream can be read from. For more information about readout ports, refer to the Port and Speed Choices section inside the PVCAM User Manual| 207 | | readout_time | (Getter only): Returns the last acquisition's readout time as reported by the camera in microseconds. | 208 | | scan_line_time | (Getter) **Warning: Camera specific setting. Not all camera's support this attribute. If an unsupported camera attempts to access it's readout_port, an AttributeError will be raised.**

Returns the scan line time of camera in nano seconds. | 209 | | sensor_size | (Getter only) Returns the sensor size of the current camera in a tuple in the form (serial sensor size, parallel sensor size)| 210 | | serial_no | (Getter only) Returns the camera's serial number as a string.| 211 | | speed_table_index| (Getter and Setter) Returns/changes the current numerical index of the speed table of a camera. See the Port and Speed Choices section inside the PVCAM User Manual for a detailed explanation about PVCAM speed tables.| 212 | | temp | (Getter only): **Warning: Camera specific setting. Not all camera's support this attribute. If an unsupported camera attempts to access it's readout_port, an AttributeError will be raised.**

Returns the current temperature of a camera in Celsius. | 213 | | temp_setpoint | (Getter and Setter): **Warning: Camera specific setting. Not all camera's support this attribute. If an unsupported camera attempts to access it's readout_port, 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 it's temperature (in Celsius) at.| 214 | | trigger_table | (Getter 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'. | 215 | | vtm_exp_time | (Getter and Setter): **Warning: Camera specific setting. Not all camera's support this attribute. If an unsupported camera attempts to access it's readout_port, an AttributeError will be raised.**

Returns/ changes the variable timed exposure time the camera uses for the "Variable Timed" exposure mode. | 216 | 217 | ### constants.py 218 | 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. 219 | 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 build/rebuild 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. 220 | There are four main sections to this file that are found following a formatted comment like this ### ###: 221 | 1. Defines 222 | 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 who's name is the macros name and the value is what the macro expands to. 223 | 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. 224 | 2. Enums 225 | 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. 226 | 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 who's values where the integer assigned to them in the pvcam.h file. 227 | 3. Structs 228 | 1. While not used (yet), structs are preserved as Python classes. No testing/implementation has been done with these, so results may be unexpected if implemented. 229 | 4. Added By Hand 230 | 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. 231 | 232 | ### pvcmodule.cpp 233 | 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 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. 234 | 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. 235 | 236 | #### General Structure of a pvcmodule Function 237 | The functions for a pvcmodule function usually follow a three step process: 238 | 1. Retrieve data/query from Python script 239 | 2. Process acquired data 240 | 3. Return data to Python scrip 241 | 242 | #### Retrieving Data 243 | Functions receive data dynamically through use of parameters, and the pvcmodule'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 of 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. 244 | 245 | | C Type | Character Representation | 246 | | -------------- | ------------------------ | 247 | | long | l | 248 | | int | i | 249 | | double | d | 250 | | float | f | 251 | | string (char*) | s | 252 | | PyObject | O | 253 | 254 | #### Arguments of PyArg_ParseTuple 255 | 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". 256 | 2. format (char *) A String containing the format units for all of 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". 257 | 258 | 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). 259 | 260 | #### PyArg_ParseTuple Example 261 | ``` 262 | static PyObject *example(PyObject *self, PyObject *args) { 263 | int myNum; 264 | char *myString; 265 | PyArg_ParseTuple(args, "is", &myNum, &myString); 266 | printf("myNum: %d\n", myNum); // Prints "myNum: 1" 267 | printf("myString: %s\n", myString); // Prints "myString: test" 268 | Py_RETURN_NONE; 269 | } 270 | ``` 271 | 272 | #### Processing Acquired Data 273 | 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. 274 | 275 | 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. 276 | 277 | 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. 278 | 279 | #### Return Data to a Python Script 280 | 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. 281 | 282 | 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. 283 | 284 | #### Cast to Python Type 285 | ``` 286 | { 287 | char *myString = "ika"; 288 | return PyUnicode_FromString(myString); // Returns a Python string back to the calling function. 289 | } 290 | ``` 291 | 292 | 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!) 293 | If you wish to return None, simply use the Py_RETURN_NONE macro (see the PyArg_ParseTuple example for a visual representation). 294 | 295 | #### Functions of pvcmodule.cpp 296 | **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. 297 | 298 | | Function Name | Description | 299 | | ------------- | ----------- | 300 | | NewFrameHandler | Call-back function registered with PVCAM when a new frame is available. | 301 | | check_meta_data_enabled | Given a camera handle, checks if meta data is enabled.

**Parameters:**
| 302 | | is_avail | Given a camera handle, checks if the parameter ID is available.

**Parameters:**
| 303 | | pvc_abort | Given a camera handle, aborts any ongoing acquisition and de-registers the frame handler callback function.

**Parameters:**