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.
Files changed (39) hide show
  1. slmsuite-0.0.1/LICENSE +21 -0
  2. slmsuite-0.0.1/PKG-INFO +61 -0
  3. slmsuite-0.0.1/README.md +52 -0
  4. slmsuite-0.0.1/README_PYPI.md +46 -0
  5. slmsuite-0.0.1/pyproject.toml +18 -0
  6. slmsuite-0.0.1/setup.cfg +4 -0
  7. slmsuite-0.0.1/setup.py +28 -0
  8. slmsuite-0.0.1/slmsuite/__init__.py +1 -0
  9. slmsuite-0.0.1/slmsuite/hardware/__init__.py +1 -0
  10. slmsuite-0.0.1/slmsuite/hardware/cameras/__init__.py +31 -0
  11. slmsuite-0.0.1/slmsuite/hardware/cameras/alliedvision.py +289 -0
  12. slmsuite-0.0.1/slmsuite/hardware/cameras/camera.py +499 -0
  13. slmsuite-0.0.1/slmsuite/hardware/cameras/flir.py +119 -0
  14. slmsuite-0.0.1/slmsuite/hardware/cameras/mmcore.py +97 -0
  15. slmsuite-0.0.1/slmsuite/hardware/cameras/template.py +125 -0
  16. slmsuite-0.0.1/slmsuite/hardware/cameras/thorlabs.py +458 -0
  17. slmsuite-0.0.1/slmsuite/hardware/cameras/xenics.py +1553 -0
  18. slmsuite-0.0.1/slmsuite/hardware/cameraslms.py +1501 -0
  19. slmsuite-0.0.1/slmsuite/hardware/slms/__init__.py +1 -0
  20. slmsuite-0.0.1/slmsuite/hardware/slms/_slm_win.py +411 -0
  21. slmsuite-0.0.1/slmsuite/hardware/slms/meadowlark.py +245 -0
  22. slmsuite-0.0.1/slmsuite/hardware/slms/santec.py +568 -0
  23. slmsuite-0.0.1/slmsuite/hardware/slms/screenmirrored.py +370 -0
  24. slmsuite-0.0.1/slmsuite/hardware/slms/slm.py +594 -0
  25. slmsuite-0.0.1/slmsuite/hardware/slms/template.py +103 -0
  26. slmsuite-0.0.1/slmsuite/holography/__init__.py +0 -0
  27. slmsuite-0.0.1/slmsuite/holography/algorithms.py +3240 -0
  28. slmsuite-0.0.1/slmsuite/holography/analysis.py +1564 -0
  29. slmsuite-0.0.1/slmsuite/holography/toolbox/__init__.py +1133 -0
  30. slmsuite-0.0.1/slmsuite/holography/toolbox/phase.py +583 -0
  31. slmsuite-0.0.1/slmsuite/misc/__init__.py +1 -0
  32. slmsuite-0.0.1/slmsuite/misc/files.py +231 -0
  33. slmsuite-0.0.1/slmsuite/misc/fitfunctions.py +302 -0
  34. slmsuite-0.0.1/slmsuite/misc/math.py +41 -0
  35. slmsuite-0.0.1/slmsuite.egg-info/PKG-INFO +61 -0
  36. slmsuite-0.0.1/slmsuite.egg-info/SOURCES.txt +37 -0
  37. slmsuite-0.0.1/slmsuite.egg-info/dependency_links.txt +1 -0
  38. slmsuite-0.0.1/slmsuite.egg-info/requires.txt +6 -0
  39. 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.
@@ -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>
@@ -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/"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -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()