slmsuite 0.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- slmsuite-0.0.1/LICENSE +21 -0
- slmsuite-0.0.1/PKG-INFO +61 -0
- slmsuite-0.0.1/README.md +52 -0
- slmsuite-0.0.1/README_PYPI.md +46 -0
- slmsuite-0.0.1/pyproject.toml +18 -0
- slmsuite-0.0.1/setup.cfg +4 -0
- slmsuite-0.0.1/setup.py +28 -0
- slmsuite-0.0.1/slmsuite/__init__.py +1 -0
- slmsuite-0.0.1/slmsuite/hardware/__init__.py +1 -0
- slmsuite-0.0.1/slmsuite/hardware/cameras/__init__.py +31 -0
- slmsuite-0.0.1/slmsuite/hardware/cameras/alliedvision.py +289 -0
- slmsuite-0.0.1/slmsuite/hardware/cameras/camera.py +499 -0
- slmsuite-0.0.1/slmsuite/hardware/cameras/flir.py +119 -0
- slmsuite-0.0.1/slmsuite/hardware/cameras/mmcore.py +97 -0
- slmsuite-0.0.1/slmsuite/hardware/cameras/template.py +125 -0
- slmsuite-0.0.1/slmsuite/hardware/cameras/thorlabs.py +458 -0
- slmsuite-0.0.1/slmsuite/hardware/cameras/xenics.py +1553 -0
- slmsuite-0.0.1/slmsuite/hardware/cameraslms.py +1501 -0
- slmsuite-0.0.1/slmsuite/hardware/slms/__init__.py +1 -0
- slmsuite-0.0.1/slmsuite/hardware/slms/_slm_win.py +411 -0
- slmsuite-0.0.1/slmsuite/hardware/slms/meadowlark.py +245 -0
- slmsuite-0.0.1/slmsuite/hardware/slms/santec.py +568 -0
- slmsuite-0.0.1/slmsuite/hardware/slms/screenmirrored.py +370 -0
- slmsuite-0.0.1/slmsuite/hardware/slms/slm.py +594 -0
- slmsuite-0.0.1/slmsuite/hardware/slms/template.py +103 -0
- slmsuite-0.0.1/slmsuite/holography/__init__.py +0 -0
- slmsuite-0.0.1/slmsuite/holography/algorithms.py +3240 -0
- slmsuite-0.0.1/slmsuite/holography/analysis.py +1564 -0
- slmsuite-0.0.1/slmsuite/holography/toolbox/__init__.py +1133 -0
- slmsuite-0.0.1/slmsuite/holography/toolbox/phase.py +583 -0
- slmsuite-0.0.1/slmsuite/misc/__init__.py +1 -0
- slmsuite-0.0.1/slmsuite/misc/files.py +231 -0
- slmsuite-0.0.1/slmsuite/misc/fitfunctions.py +302 -0
- slmsuite-0.0.1/slmsuite/misc/math.py +41 -0
- slmsuite-0.0.1/slmsuite.egg-info/PKG-INFO +61 -0
- slmsuite-0.0.1/slmsuite.egg-info/SOURCES.txt +37 -0
- slmsuite-0.0.1/slmsuite.egg-info/dependency_links.txt +1 -0
- slmsuite-0.0.1/slmsuite.egg-info/requires.txt +6 -0
- slmsuite-0.0.1/slmsuite.egg-info/top_level.txt +1 -0
slmsuite-0.0.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2021 slmsuite Developers.
|
|
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.
|
slmsuite-0.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: slmsuite
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: Package for high-performance spatial light modulator (SLM) control and holography.
|
|
5
|
+
Author: MIT Quantum Photonics Group
|
|
6
|
+
Author-email: qp-slm@mit.edu
|
|
7
|
+
Project-URL: Homepage, https://github.com/QPG-MIT/slmsuite
|
|
8
|
+
Project-URL: Documentation, https://slmsuite.readthedocs.io/en/latest/
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Requires-Python: >=3.8
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
License-File: LICENSE
|
|
15
|
+
|
|
16
|
+
<p align="center">
|
|
17
|
+
<img alt="qp-slm" src="https://raw.githubusercontent.com/QPG-MIT/slmsuite/main/docs/source/static/qp-slm.svg" width="256">
|
|
18
|
+
</p>
|
|
19
|
+
|
|
20
|
+
<h2 align="center">High-Performance Spatial Light Modulator Control and Holography</h2>
|
|
21
|
+
|
|
22
|
+
<p align="center">
|
|
23
|
+
<a href="https://slmsuite.readthedocs.io/en/latest"><img alt="Documentation Status" src="https://readthedocs.org/projects/slmsuite/badge/?version=latest"></a>
|
|
24
|
+
<a href="https://github.com/QPG-MIT/slmsuite/blob/main/LICENSE"><img alt="License: MIT" src="https://img.shields.io/github/license/QPG-MIT/slmsuite?color=purple"></a>
|
|
25
|
+
<!--<a href="https://pepy.tech/project/slmsuite"><img alt="Downloads" src="https://pepy.tech/badge/slmsuite"></a>-->
|
|
26
|
+
<a href="https://github.com/psf/black"><img alt="Code style: black" src="https://img.shields.io/badge/code%20style-black-000000.svg"></a>
|
|
27
|
+
</p>
|
|
28
|
+
|
|
29
|
+
## Installation
|
|
30
|
+
|
|
31
|
+
Install the stable version of `slmsuite` from [PyPi](https://pypi.org/project/slmsuite/) using:
|
|
32
|
+
|
|
33
|
+
```console
|
|
34
|
+
$ pip install slmsuite
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
Install the latest version of `slmsuite` from GitHub using:
|
|
39
|
+
|
|
40
|
+
```console
|
|
41
|
+
$ pip install git+https://github.com/QPG-MIT/slmsuite
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Documentation and Examples
|
|
45
|
+
|
|
46
|
+
Extensive
|
|
47
|
+
[documentation](https://slmsuite.readthedocs.io/en/latest/)
|
|
48
|
+
and
|
|
49
|
+
[API reference](https://slmsuite.readthedocs.io/en/latest/api.html)
|
|
50
|
+
are available through readthedocs.
|
|
51
|
+
|
|
52
|
+
Examples can be found embedded in
|
|
53
|
+
[documentation](https://slmsuite.readthedocs.io/en/latest/examples.html),
|
|
54
|
+
live through
|
|
55
|
+
[nbviewer](https://nbviewer.org/github/QPG-MIT/slmsuite-examples/tree/main/examples/),
|
|
56
|
+
or directly in
|
|
57
|
+
[source](https://github.com/QPG-MIT/slmsuite-examples).
|
|
58
|
+
|
|
59
|
+
<p align="center">
|
|
60
|
+
<img alt="qp-slm" src="https://raw.githubusercontent.com/QPG-MIT/slmsuite/main/docs/source/static/readme-example.png" width="256">
|
|
61
|
+
</p>
|
slmsuite-0.0.1/README.md
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<picture>
|
|
3
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/QPG-MIT/slmsuite/main/docs/source/static/qp-slm-dark.svg">
|
|
4
|
+
<img alt="qp-slm" src="https://raw.githubusercontent.com/QPG-MIT/slmsuite/main/docs/source/static/qp-slm.svg" width="256">
|
|
5
|
+
</picture>
|
|
6
|
+
</p>
|
|
7
|
+
|
|
8
|
+
<h2 align="center">High-Performance Spatial Light Modulator Control and Holography</h2>
|
|
9
|
+
|
|
10
|
+
<p align="center">
|
|
11
|
+
<a href="https://slmsuite.readthedocs.io/en/latest"><img alt="Documentation Status" src="https://readthedocs.org/projects/slmsuite/badge/?version=latest"></a>
|
|
12
|
+
<a href="https://github.com/QPG-MIT/slmsuite/blob/main/LICENSE"><img alt="License: MIT" src="https://img.shields.io/github/license/QPG-MIT/slmsuite?color=purple"></a>
|
|
13
|
+
<!--<a href="https://pepy.tech/project/slmsuite"><img alt="Downloads" src="https://pepy.tech/badge/slmsuite"></a>-->
|
|
14
|
+
<a href="https://github.com/psf/black"><img alt="Code style: black" src="https://img.shields.io/badge/code%20style-black-000000.svg"></a>
|
|
15
|
+
</p>
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
Install the stable version of `slmsuite` from [PyPi](https://pypi.org/project/slmsuite/) using:
|
|
20
|
+
|
|
21
|
+
```console
|
|
22
|
+
$ pip install slmsuite
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
Install the latest version of `slmsuite` from GitHub using:
|
|
27
|
+
|
|
28
|
+
```console
|
|
29
|
+
$ pip install git+https://github.com/QPG-MIT/slmsuite
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Documentation and Examples
|
|
33
|
+
|
|
34
|
+
Extensive
|
|
35
|
+
[documentation](https://slmsuite.readthedocs.io/en/latest/)
|
|
36
|
+
and
|
|
37
|
+
[API reference](https://slmsuite.readthedocs.io/en/latest/api.html)
|
|
38
|
+
are available through readthedocs.
|
|
39
|
+
|
|
40
|
+
Examples can be found embedded in
|
|
41
|
+
[documentation](https://slmsuite.readthedocs.io/en/latest/examples.html),
|
|
42
|
+
live through
|
|
43
|
+
[nbviewer](https://nbviewer.org/github/QPG-MIT/slmsuite-examples/tree/main/examples/),
|
|
44
|
+
or directly in
|
|
45
|
+
[source](https://github.com/QPG-MIT/slmsuite-examples).
|
|
46
|
+
|
|
47
|
+
<p align="center">
|
|
48
|
+
<picture>
|
|
49
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/QPG-MIT/slmsuite/main/docs/source/static/readme-example-dark.png">
|
|
50
|
+
<img alt="qp-slm" src="https://raw.githubusercontent.com/QPG-MIT/slmsuite/main/docs/source/static/readme-example.png" width="256">
|
|
51
|
+
</picture>
|
|
52
|
+
</p>
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img alt="qp-slm" src="https://raw.githubusercontent.com/QPG-MIT/slmsuite/main/docs/source/static/qp-slm.svg" width="256">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h2 align="center">High-Performance Spatial Light Modulator Control and Holography</h2>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="https://slmsuite.readthedocs.io/en/latest"><img alt="Documentation Status" src="https://readthedocs.org/projects/slmsuite/badge/?version=latest"></a>
|
|
9
|
+
<a href="https://github.com/QPG-MIT/slmsuite/blob/main/LICENSE"><img alt="License: MIT" src="https://img.shields.io/github/license/QPG-MIT/slmsuite?color=purple"></a>
|
|
10
|
+
<!--<a href="https://pepy.tech/project/slmsuite"><img alt="Downloads" src="https://pepy.tech/badge/slmsuite"></a>-->
|
|
11
|
+
<a href="https://github.com/psf/black"><img alt="Code style: black" src="https://img.shields.io/badge/code%20style-black-000000.svg"></a>
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
Install the stable version of `slmsuite` from [PyPi](https://pypi.org/project/slmsuite/) using:
|
|
17
|
+
|
|
18
|
+
```console
|
|
19
|
+
$ pip install slmsuite
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
Install the latest version of `slmsuite` from GitHub using:
|
|
24
|
+
|
|
25
|
+
```console
|
|
26
|
+
$ pip install git+https://github.com/QPG-MIT/slmsuite
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Documentation and Examples
|
|
30
|
+
|
|
31
|
+
Extensive
|
|
32
|
+
[documentation](https://slmsuite.readthedocs.io/en/latest/)
|
|
33
|
+
and
|
|
34
|
+
[API reference](https://slmsuite.readthedocs.io/en/latest/api.html)
|
|
35
|
+
are available through readthedocs.
|
|
36
|
+
|
|
37
|
+
Examples can be found embedded in
|
|
38
|
+
[documentation](https://slmsuite.readthedocs.io/en/latest/examples.html),
|
|
39
|
+
live through
|
|
40
|
+
[nbviewer](https://nbviewer.org/github/QPG-MIT/slmsuite-examples/tree/main/examples/),
|
|
41
|
+
or directly in
|
|
42
|
+
[source](https://github.com/QPG-MIT/slmsuite-examples).
|
|
43
|
+
|
|
44
|
+
<p align="center">
|
|
45
|
+
<img alt="qp-slm" src="https://raw.githubusercontent.com/QPG-MIT/slmsuite/main/docs/source/static/readme-example.png" width="256">
|
|
46
|
+
</p>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "slmsuite"
|
|
7
|
+
readme = "README_PYPI.md"
|
|
8
|
+
requires-python = ">=3.8"
|
|
9
|
+
classifiers = [
|
|
10
|
+
"Programming Language :: Python :: 3",
|
|
11
|
+
"License :: OSI Approved :: MIT License",
|
|
12
|
+
"Operating System :: OS Independent",
|
|
13
|
+
]
|
|
14
|
+
dynamic = ["version", "dependencies", "description", "authors"]
|
|
15
|
+
|
|
16
|
+
[project.urls]
|
|
17
|
+
"Homepage" = "https://github.com/QPG-MIT/slmsuite"
|
|
18
|
+
"Documentation" = "https://slmsuite.readthedocs.io/en/latest/"
|
slmsuite-0.0.1/setup.cfg
ADDED
slmsuite-0.0.1/setup.py
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""
|
|
2
|
+
setup.py - this module makes the package installable
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from setuptools import setup
|
|
6
|
+
|
|
7
|
+
NAME = "slmsuite"
|
|
8
|
+
VERSION = "0.0.1"
|
|
9
|
+
DEPENDENCIES = [
|
|
10
|
+
"numpy",
|
|
11
|
+
"scipy",
|
|
12
|
+
"opencv-python",
|
|
13
|
+
"matplotlib",
|
|
14
|
+
"h5py",
|
|
15
|
+
"tqdm"
|
|
16
|
+
]
|
|
17
|
+
DESCRIPTION = ("Package for high-performance spatial light "
|
|
18
|
+
"modulator (SLM) control and holography.")
|
|
19
|
+
AUTHOR = "MIT Quantum Photonics Group"
|
|
20
|
+
AUTHOR_EMAIL = "qp-slm@mit.edu"
|
|
21
|
+
|
|
22
|
+
setup(author=AUTHOR,
|
|
23
|
+
author_email=AUTHOR_EMAIL,
|
|
24
|
+
description=DESCRIPTION,
|
|
25
|
+
install_requires=DEPENDENCIES,
|
|
26
|
+
name=NAME,
|
|
27
|
+
version=VERSION,
|
|
28
|
+
)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '0.0.0'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Interface to experimental devices."""
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# The first line of the docstring might read awkward alone,
|
|
2
|
+
# but it's meant to parallel the slms module description.
|
|
3
|
+
"""
|
|
4
|
+
The sensor arrays used to measure results.
|
|
5
|
+
Computer vision hardware is connected to python by a myriad of SDKs, often provided by hardware
|
|
6
|
+
vendors. However, these SDKs likewise have a myriad of function names and hardware-specific
|
|
7
|
+
quirks. Thus, cameras in :mod:`slmsuite` are integrated as subclasses of
|
|
8
|
+
the abstract class :class:`.Camera`, which requires subclasses to implement a number of methods
|
|
9
|
+
relevant for SLM feedback (see below).
|
|
10
|
+
These subclasses are effectively wrappers for the given SDK, but also include
|
|
11
|
+
quality-of-life features such as image transformations (flips, rotates) and useful common methods.
|
|
12
|
+
A number of SDKs are supported, including:
|
|
13
|
+
|
|
14
|
+
- :class:`.AlliedVision`, for AlliedVision cameras, through :mod:`vimba`
|
|
15
|
+
(`GitHub <https://github.com/alliedvision/VimbaPython>`_),
|
|
16
|
+
- :class:`.Cheetah640`, for Xenics Cheetah cameras, through the
|
|
17
|
+
`Xenics SDK <https://www.xenics.com/software/>`_,
|
|
18
|
+
- :class:`.FLIR`, for Teledyne FLIR cameras, through the :mod:`PySpin`
|
|
19
|
+
interface of the `Spinnaker SDK <https://www.flir.com/products/spinnaker-sdk/>`_,
|
|
20
|
+
- :class:`.MMCore`, for the general microscope control package Micro-Manager,
|
|
21
|
+
through :mod:`pymmcore` (`GitHub <https://github.com/micro-manager/pymmcore>`_), and
|
|
22
|
+
- :class:`.ThorCam`, for Thorlabs scientific cameras, through :mod:`thorlabs_tsi_sdk`
|
|
23
|
+
and the `ThorCam SDK <https://www.thorlabs.com/software_pages/ViewSoftwarePage.cfm?Code=ThorCam>`_.
|
|
24
|
+
|
|
25
|
+
Tip
|
|
26
|
+
~~~~~~~~
|
|
27
|
+
While the superclass :class:`.Camera` only requires a small number of features to
|
|
28
|
+
be implemented as class functions, any further control of a camera interface can be
|
|
29
|
+
accessed by using the given SDK object directly (usually the attribute :attr:`cam` of
|
|
30
|
+
the subclass) or writing additional functions into the subclass.
|
|
31
|
+
"""
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Hardware control for AlliedVision cameras via the :mod:`vimba` interface.
|
|
3
|
+
Install :mod:`vimba` by following the
|
|
4
|
+
`provided instructions <https://github.com/alliedvision/VimbaPython>`_.
|
|
5
|
+
Include the ``numpy-export`` flag in the ``pip install`` command,
|
|
6
|
+
as the :class:`AlliedVision` class makes use of these features. See especially the
|
|
7
|
+
`vimba python manual <https://github.com/alliedvision/VimbaPython/blob/master/Documentation/Vimba%20Python%20Manual.pdf>`_
|
|
8
|
+
for reference.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import time
|
|
12
|
+
import numpy as np
|
|
13
|
+
|
|
14
|
+
from slmsuite.hardware.cameras.camera import Camera
|
|
15
|
+
|
|
16
|
+
try:
|
|
17
|
+
import vimba
|
|
18
|
+
except ImportError:
|
|
19
|
+
print("alliedvision.py: vimba not installed. Install to use AlliedVision cameras.")
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class AlliedVision(Camera):
|
|
23
|
+
r"""
|
|
24
|
+
AlliedVision camera.
|
|
25
|
+
|
|
26
|
+
Attributes
|
|
27
|
+
----------
|
|
28
|
+
sdk : vimba.Vimba
|
|
29
|
+
AlliedVision SDK. Shared among instances of :class:`AlliedVision`.
|
|
30
|
+
cam : vimba.Camera
|
|
31
|
+
Object to talk with the desired camera.
|
|
32
|
+
|
|
33
|
+
Caution
|
|
34
|
+
~~~~~~~~
|
|
35
|
+
The AlliedVision SDK :mod:`vimba` includes protections to maintain camera connectivity:
|
|
36
|
+
specifically, the SDK :class:`vimba.Vimba` and cameras :class:`vimba.Camera` are designed
|
|
37
|
+
to be used in concert with ``with`` statements. Unfortunately, this does not mesh with the
|
|
38
|
+
architecture of :mod:`slmsuite`, where notebook-style operation is desired.
|
|
39
|
+
Using ``with`` statements inside :class:`.AlliedVision` methods is likewise not an option,
|
|
40
|
+
as the methods to :meth:`__enter__()` and :meth:`__exit__()` the ``with`` are time-consuming
|
|
41
|
+
due to calls to :meth:`_open()` and :meth:`_close()` the objects, to the point of
|
|
42
|
+
:math:`\mathcal{O}(\text{s})` overhead. :class:`.AlliedVision` disables these protections by
|
|
43
|
+
calling :meth:`__enter__()` and :meth:`__exit__()` directly during :meth:`.__init__()` and
|
|
44
|
+
:meth:`.close()`, instead of inside ``with`` statements.
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
sdk = None
|
|
48
|
+
|
|
49
|
+
def __init__(self, serial="", verbose=True, **kwargs):
|
|
50
|
+
"""
|
|
51
|
+
Initialize camera and attributes.
|
|
52
|
+
|
|
53
|
+
Parameters
|
|
54
|
+
----------
|
|
55
|
+
serial : str
|
|
56
|
+
Serial number of the camera to open. If empty, defaults to the first camera in the list
|
|
57
|
+
returned by :meth:`vimba.get_all_cameras()`.
|
|
58
|
+
verbose : bool
|
|
59
|
+
Whether or not to print extra information.
|
|
60
|
+
kwargs
|
|
61
|
+
See :meth:`.Camera.__init__` for permissible options.
|
|
62
|
+
"""
|
|
63
|
+
if AlliedVision.sdk is None:
|
|
64
|
+
if verbose:
|
|
65
|
+
print("vimba initializing... ", end="")
|
|
66
|
+
AlliedVision.sdk = vimba.Vimba.get_instance()
|
|
67
|
+
AlliedVision.sdk.__enter__()
|
|
68
|
+
if verbose:
|
|
69
|
+
print("success")
|
|
70
|
+
|
|
71
|
+
if verbose:
|
|
72
|
+
print("Looking for cameras... ", end="")
|
|
73
|
+
camera_list = AlliedVision.sdk.get_all_cameras()
|
|
74
|
+
if verbose:
|
|
75
|
+
print("success")
|
|
76
|
+
|
|
77
|
+
serial_list = [cam.get_serial() for cam in camera_list]
|
|
78
|
+
if serial == "":
|
|
79
|
+
if len(camera_list) == 0:
|
|
80
|
+
raise RuntimeError("No cameras found by vimba.")
|
|
81
|
+
if len(camera_list) > 1 and verbose:
|
|
82
|
+
print("No serial given... Choosing first of ", serial_list)
|
|
83
|
+
|
|
84
|
+
self.cam = camera_list[0]
|
|
85
|
+
serial = self.cam.get_serial()
|
|
86
|
+
else:
|
|
87
|
+
if serial in serial_list:
|
|
88
|
+
self.cam = camera_list[serial_list.index(serial)]
|
|
89
|
+
else:
|
|
90
|
+
raise RuntimeError(
|
|
91
|
+
"Serial " + serial + " not found by vimba. Available: ", serial_list
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
if verbose:
|
|
95
|
+
print("vimba sn " "{}" " initializing... ".format(serial), end="")
|
|
96
|
+
self.cam.__enter__()
|
|
97
|
+
if verbose:
|
|
98
|
+
print("success")
|
|
99
|
+
|
|
100
|
+
super().__init__(
|
|
101
|
+
self.cam.SensorWidth.get(),
|
|
102
|
+
self.cam.SensorHeight.get(),
|
|
103
|
+
bitdepth=int(self.cam.PixelSize.get()),
|
|
104
|
+
dx_um=None,
|
|
105
|
+
dy_um=None,
|
|
106
|
+
name=serial,
|
|
107
|
+
**kwargs
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
self.cam.BinningHorizontal.set(1)
|
|
111
|
+
self.cam.BinningVertical.set(1)
|
|
112
|
+
|
|
113
|
+
self.cam.GainAuto.set("Off")
|
|
114
|
+
|
|
115
|
+
self.cam.ExposureAuto.set("Off")
|
|
116
|
+
self.cam.ExposureMode.set("Timed")
|
|
117
|
+
|
|
118
|
+
self.cam.AcquisitionMode.set("SingleFrame")
|
|
119
|
+
|
|
120
|
+
# Future: triggered instead of SingleFrame.
|
|
121
|
+
self.cam.TriggerSelector.set("AcquisitionStart")
|
|
122
|
+
self.cam.TriggerMode.set("Off")
|
|
123
|
+
self.cam.TriggerActivation.set("RisingEdge")
|
|
124
|
+
self.cam.TriggerSource.set("Software")
|
|
125
|
+
|
|
126
|
+
def close(self, close_sdk=True):
|
|
127
|
+
"""
|
|
128
|
+
See :meth:`.Camera.close`
|
|
129
|
+
|
|
130
|
+
Parameters
|
|
131
|
+
----------
|
|
132
|
+
close_sdk : bool
|
|
133
|
+
Whether or not to close the :mod:`vimba` instance.
|
|
134
|
+
"""
|
|
135
|
+
self.cam.__exit__(None, None, None)
|
|
136
|
+
|
|
137
|
+
if close_sdk:
|
|
138
|
+
self.close_sdk()
|
|
139
|
+
|
|
140
|
+
@staticmethod
|
|
141
|
+
def info(verbose=True):
|
|
142
|
+
"""
|
|
143
|
+
Discovers all Thorlabs scientific cameras.
|
|
144
|
+
|
|
145
|
+
Parameters
|
|
146
|
+
----------
|
|
147
|
+
verbose : bool
|
|
148
|
+
Whether to print the discovered information.
|
|
149
|
+
|
|
150
|
+
Returns
|
|
151
|
+
--------
|
|
152
|
+
list of str
|
|
153
|
+
List of AlliedVision serial numbers.
|
|
154
|
+
"""
|
|
155
|
+
if AlliedVision.sdk is None:
|
|
156
|
+
AlliedVision.sdk = vimba.Vimba.get_instance()
|
|
157
|
+
AlliedVision.sdk.__enter__()
|
|
158
|
+
close_sdk = True
|
|
159
|
+
else:
|
|
160
|
+
close_sdk = False
|
|
161
|
+
|
|
162
|
+
camera_list = AlliedVision.sdk.get_all_cameras()
|
|
163
|
+
serial_list = [cam.get_serial() for cam in camera_list]
|
|
164
|
+
|
|
165
|
+
if verbose:
|
|
166
|
+
print("AlliedVision serials:")
|
|
167
|
+
for serial in serial_list:
|
|
168
|
+
print("\"{}\"".format(serial))
|
|
169
|
+
|
|
170
|
+
if close_sdk:
|
|
171
|
+
AlliedVision.close_sdk()
|
|
172
|
+
|
|
173
|
+
return serial_list
|
|
174
|
+
|
|
175
|
+
@classmethod
|
|
176
|
+
def close_sdk(cls):
|
|
177
|
+
"""
|
|
178
|
+
Close the :mod:`vimba` instance.
|
|
179
|
+
"""
|
|
180
|
+
if cls.sdk is not None:
|
|
181
|
+
cls.sdk.__exit__(None, None, None)
|
|
182
|
+
cls.sdk = None
|
|
183
|
+
|
|
184
|
+
### Property Configuration ###
|
|
185
|
+
|
|
186
|
+
def get_properties(self, properties=None):
|
|
187
|
+
"""
|
|
188
|
+
Print the list of camera properties.
|
|
189
|
+
|
|
190
|
+
Parameters
|
|
191
|
+
----------
|
|
192
|
+
properties : dict or None
|
|
193
|
+
The target camera's property dictionary. If ``None``, the property
|
|
194
|
+
dictionary is fetched from the camera associated with the calling instance.
|
|
195
|
+
"""
|
|
196
|
+
if properties is None:
|
|
197
|
+
properties = self.cam.__dict__.keys()
|
|
198
|
+
|
|
199
|
+
for key in properties:
|
|
200
|
+
prop = self.cam.__dict__[key]
|
|
201
|
+
try:
|
|
202
|
+
print(prop.get_name(), end="\t")
|
|
203
|
+
except BaseException as e:
|
|
204
|
+
print("Error accessing property dictionary, '{}':{}".format(key, e))
|
|
205
|
+
continue
|
|
206
|
+
|
|
207
|
+
try:
|
|
208
|
+
print(prop.get(), end="\t")
|
|
209
|
+
except:
|
|
210
|
+
pass
|
|
211
|
+
|
|
212
|
+
try:
|
|
213
|
+
print(prop.get_unit(), end="\t")
|
|
214
|
+
except:
|
|
215
|
+
pass
|
|
216
|
+
|
|
217
|
+
try:
|
|
218
|
+
print(prop.get_description(), end="\n")
|
|
219
|
+
except:
|
|
220
|
+
print("")
|
|
221
|
+
|
|
222
|
+
def set_adc_bitdepth(self, bitdepth):
|
|
223
|
+
"""
|
|
224
|
+
Set the digitization bitdepth.
|
|
225
|
+
|
|
226
|
+
Parameters
|
|
227
|
+
----------
|
|
228
|
+
bitdepth : int
|
|
229
|
+
Desired digitization bitdepth.
|
|
230
|
+
"""
|
|
231
|
+
bitdepth = int(bitdepth)
|
|
232
|
+
|
|
233
|
+
for entry in self.cam.SensorBitDepth.get_all_entries():
|
|
234
|
+
value = entry.as_tuple() # (name : str, value : int)
|
|
235
|
+
if str(bitdepth) in value[0]:
|
|
236
|
+
self.cam.SensorBitDepth.set(value[1])
|
|
237
|
+
break
|
|
238
|
+
raise RuntimeError("ADC bitdepth {} not found.".format(bitdepth))
|
|
239
|
+
|
|
240
|
+
def get_adc_bitdepth(self):
|
|
241
|
+
"""
|
|
242
|
+
Get the digitization bitdepth.
|
|
243
|
+
|
|
244
|
+
Returns
|
|
245
|
+
-------
|
|
246
|
+
int
|
|
247
|
+
The digitization bitdepth.
|
|
248
|
+
"""
|
|
249
|
+
value = str(self.cam.SensorBitDepth.get())
|
|
250
|
+
bitdepth = int("".join(char for char in value if char.isdigit()))
|
|
251
|
+
return bitdepth
|
|
252
|
+
|
|
253
|
+
def get_exposure(self):
|
|
254
|
+
"""See :meth:`.Camera.get_exposure`."""
|
|
255
|
+
return float(self.cam.ExposureTime.get()) / 1e6
|
|
256
|
+
|
|
257
|
+
def set_exposure(self, exposure_s):
|
|
258
|
+
"""See :meth:`.Camera.set_exposure`."""
|
|
259
|
+
self.cam.ExposureTime.set(float(exposure_s * 1e6))
|
|
260
|
+
|
|
261
|
+
def set_woi(self, woi=None):
|
|
262
|
+
"""See :meth:`.Camera.set_woi`."""
|
|
263
|
+
return
|
|
264
|
+
|
|
265
|
+
def get_image(self, timeout_s=1):
|
|
266
|
+
"""See :meth:`.Camera.get_image`."""
|
|
267
|
+
t = time.time()
|
|
268
|
+
|
|
269
|
+
# Convert timeout_s to ms
|
|
270
|
+
frame = self.cam.get_frame(timeout_ms=int(1e3 * timeout_s))
|
|
271
|
+
frame = frame.as_numpy_ndarray()
|
|
272
|
+
|
|
273
|
+
# We have noticed that sometimes the camera gets into a state where
|
|
274
|
+
# it returns a frame of all zeros apart from one pixel with value of 31.
|
|
275
|
+
# This method is admittedly a hack to try getting a frame a few more times.
|
|
276
|
+
# We welcome contributions to fix this.
|
|
277
|
+
while np.sum(frame) == np.amax(frame) == 31 and time.time() - t < timeout_s:
|
|
278
|
+
frame = self.cam.get_frame(timeout_ms=int(1e3 * timeout_s))
|
|
279
|
+
frame = frame.as_numpy_ndarray()
|
|
280
|
+
|
|
281
|
+
return self.transform(np.squeeze(frame))
|
|
282
|
+
|
|
283
|
+
def flush(self, timeout_s=1e-3):
|
|
284
|
+
"""See :meth:`.Camera.flush`."""
|
|
285
|
+
pass
|
|
286
|
+
|
|
287
|
+
def reset(self):
|
|
288
|
+
"""See :meth:`.Camera.reset`."""
|
|
289
|
+
raise NotImplementedError()
|