Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Thorlabs kinesis drivers #262

Open
wants to merge 67 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
8a8b15d
Add Thorlabs Kinesis C API drivers
thangleiter Mar 21, 2023
0f9c165
Fix relative imports
thangleiter Mar 24, 2023
6a6be07
Move more functionality to base classes
thangleiter Mar 24, 2023
f39f98c
Add toggle_position() function
thangleiter Apr 17, 2023
c536b48
Fix issues with connecting and disconnecting
thangleiter Apr 20, 2023
ee52c4b
Add enums and structs and move to separate modules
thangleiter Apr 28, 2023
66f2068
Move _kinesis to private/kinesis
thangleiter Sep 22, 2023
6f7065f
Reorganize directory structure.
thangleiter Sep 22, 2023
eaa358d
Refactor KinesisInstrument to connect in constructor
thangleiter Sep 22, 2023
d9e1f61
__post_init__ is only available to dataclasses...
thangleiter Sep 22, 2023
8bf1e93
Make position val_mapping dynamic
thangleiter Sep 22, 2023
a11e88a
Fix close if not connected to anything
thangleiter Sep 22, 2023
e5c86a5
Add PM100D driver.
thangleiter Sep 22, 2023
ec20283
Add documentation.
thangleiter Sep 22, 2023
e3fa172
Fix super() call
thangleiter Sep 22, 2023
72b1fe4
Format lines to 72/79 characters
thangleiter Sep 22, 2023
4eec1b1
Refactor ThorlabsKinesis to include more basic functionality
thangleiter Sep 22, 2023
de81674
Add position parameter to K10CR1
thangleiter Sep 22, 2023
e523b31
Fix success definition
thangleiter Sep 26, 2023
6898fe8
Add simulation.
thangleiter Sep 26, 2023
f2daeb5
Fix list_available_devices() for n!=1 devices
thangleiter Sep 26, 2023
d53c9fe
Move error and success checks into get_function()
thangleiter Sep 26, 2023
810221d
Rename functions to mirror DLL names
thangleiter Sep 26, 2023
ace54ef
Add get/set_motor_params_ext and documentation
thangleiter Sep 26, 2023
4bf761b
Make hardware_type and _prefix classmethods
thangleiter Oct 19, 2023
31eccc6
Fix MyPy errors
thangleiter Oct 19, 2023
1f45898
Make list_available_devices available at top-level namespace
thangleiter Oct 20, 2023
7cb04dd
Refactor base class using __init_subclass__
thangleiter Nov 6, 2023
85215b0
Add K10CR1 driver.
thangleiter Nov 6, 2023
83c77ae
Use abbreviated unit.
thangleiter Nov 6, 2023
b738be3
Merge remote-tracking branch 'origin/main' into feature/thorlabs_kine…
thangleiter Nov 6, 2023
2639bb4
Add CC instruments driver draft as an example.
thangleiter Nov 6, 2023
3fdfb81
Move more stuff to base classes
thangleiter Nov 6, 2023
13f8f35
Add rotation modes.
thangleiter Nov 6, 2023
c0a48c9
Add jog_mode and stop_mode parameters
thangleiter Nov 6, 2023
117c1b1
Add status update methods and is_moving()
thangleiter Nov 6, 2023
d62e8bf
Add stop profiles
thangleiter Nov 6, 2023
c1999eb
Rename enums.ISCUnitType -> enums.UnitType
thangleiter Nov 6, 2023
78b1789
Always use real units with the outside world
thangleiter Nov 6, 2023
ce3e03f
Mypy
thangleiter Nov 7, 2023
156d406
Try guessing the libary name based on some common patterns
thangleiter Nov 7, 2023
d54e8ed
Return python int instead of c_int
thangleiter Nov 7, 2023
0ff1948
Fix unit mixup bug
thangleiter Nov 7, 2023
3b75e11
Expose fewer methods to target instruments
thangleiter Nov 7, 2023
f37baa5
Drop unused imports.
thangleiter Nov 7, 2023
9228286
Replace barebones visa driver with version from main
thangleiter Nov 7, 2023
fab686f
Merge branch 'main' into feature/thorlabs_kinesis_drivers
astafan8 Nov 20, 2023
08736af
Merge remote-tracking branch 'origin/main' into feature/thorlabs_kine…
thangleiter Nov 20, 2023
a300dc1
Raise Exception if no devices found
thangleiter Nov 20, 2023
dd446f4
Bugfixes
thangleiter Nov 15, 2023
75885aa
Slightly simplify register_prefix
thangleiter Nov 15, 2023
8b6abcf
Default to blocking moves
thangleiter Nov 15, 2023
6d018c9
Implement jogging
thangleiter Nov 15, 2023
72d5365
Block while homing
thangleiter Nov 15, 2023
590b768
Use currently set stop mode for stopping.
thangleiter Nov 15, 2023
a19cea7
Add some message queue functionality
thangleiter Nov 15, 2023
6eb0708
Fix (ignore) Thorlabs PM100D tlpm driver for mypy
thangleiter Nov 20, 2023
d8f87b4
Rename addr arg for consistency with visa driver
thangleiter Nov 20, 2023
57f66eb
Fix mypy errors
thangleiter Nov 21, 2023
fff0dc1
Manually move to src-layout to merge main
thangleiter Mar 14, 2024
22f348d
Merge branch 'main_trunk' into feature/thorlabs_kinesis_drivers
thangleiter Mar 14, 2024
2fe93c0
Add averaging_time parameter
thangleiter Mar 4, 2024
c7e55b4
Merge branch 'main' into feature/thorlabs_kinesis_drivers
astafan8 Apr 11, 2024
8469b12
Add validator to transit time
thangleiter Apr 11, 2024
8899e61
Remove old file
thangleiter May 15, 2024
553f207
Merge branch 'main' into feature/thorlabs_kinesis_drivers
thangleiter May 15, 2024
1cbc4e4
Update __init__ signatures for newest qcodes version
thangleiter Jun 28, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ show_error_codes = true

[[tool.mypy.overrides]]
module = [
"qcodes_contrib_drivers.drivers.Spectrum.pyspcm"
"qcodes_contrib_drivers.drivers.Spectrum.pyspcm",
"qcodes_contrib_drivers.drivers.Thorlabs.Thorlabs_PM100D.tlpm",
]
ignore_errors = true

Expand All @@ -84,7 +85,8 @@ module = [
"spirack",
"zhinst.*",
"ruamel.*",
"msl.loadlib"
"msl.loadlib",
"TLPM"
]
ignore_missing_imports = true

Expand Down
3 changes: 2 additions & 1 deletion src/qcodes_contrib_drivers/drivers/Horiba/Horiba_FHR.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,11 @@ class Dispatcher:
7: 'errAbort',
0xFFFFFFFF: 'errForce32bit'}

config: Mapping[str, str]

def __init__(self, cli, handle):
self.cli = cli
self.handle = handle
self.config: dict[str, str]

def error_check(self, code: int):
if code != 0:
Expand Down
6 changes: 4 additions & 2 deletions src/qcodes_contrib_drivers/drivers/Thorlabs/KDC101.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,7 @@ def __init__(self,
else:
self._dll_path = 'Thorlabs.MotionControl.KCube.DCServo.dll'
self._dll_dir: Optional[str] = dll_dir if dll_dir else None
super().__init__(name, serial_number, self._dll_path, self._dll_dir,
simulation, polling, home, **kwargs)
super().__init__(name, serial_number=serial_number,
dll_path=self._dll_path, dll_dir=self._dll_dir,
simulation=simulation, polling=polling, home=home,
**kwargs)
5 changes: 3 additions & 2 deletions src/qcodes_contrib_drivers/drivers/Thorlabs/KLS1550.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,6 @@ def __init__(self,
else:
self._dll_path = 'Thorlabs.MotionControl.KCube.LaserSource.dll'
self._dll_dir: Optional[str] = dll_dir if dll_dir else None
super().__init__(name, serial_number, self._dll_path, self._dll_dir,
simulation, polling, **kwargs)
super().__init__(name, serial_number=serial_number,
dll_path=self._dll_path, dll_dir=self._dll_dir,
simulation=simulation, polling=polling, **kwargs)
43 changes: 0 additions & 43 deletions src/qcodes_contrib_drivers/drivers/Thorlabs/TDC001.py

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"""Drivers for Thorlabs K10CR1.

There are two driver versions:
- Kinesis
- APT

The APT platform has been deprecated by Thorlabs.
"""
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
from __future__ import annotations

import enum
from typing import Tuple, Optional
import warnings
from typing import Tuple

import qcodes.utils.validators as vals
from qcodes import Instrument

from .private.APT import Thorlabs_APT, ThorlabsHWType
from qcodes_contrib_drivers.drivers.Thorlabs.private.APT import (
ThorlabsHWType, Thorlabs_APT
)


class RotationDirection(enum.Enum):
Expand All @@ -19,7 +23,7 @@ class HomeLimitSwitch(enum.Enum):
FORWARD = "fwd"


class Thorlabs_K10CR1(Instrument):
class ThorlabsK10CR1(Instrument):
"""
Instrument driver for the Thorlabs K10CR1 rotator.

Expand Down Expand Up @@ -169,7 +173,8 @@ def _get_velocity_parameters(self) -> Tuple[float, float, float]:
return self.apt.mot_get_velocity_parameters(self.serial_number)

def _set_velocity_parameters(self,
min_vel: Optional[float] = None, accn: Optional[float] = None, max_vel: Optional[float] = None):
min_vel: float | None = None, accn: float | None = None,
max_vel: float | None = None):
if min_vel is None or accn is None or max_vel is None:
old_min_vel, old_accn, old_max_vel = self._get_velocity_parameters()
if min_vel is None:
Expand Down Expand Up @@ -204,8 +209,8 @@ def _set_velocity_max(self, max_vel: float):
def _get_home_parameters(self) -> Tuple[int, int, float, float]:
return self.apt.mot_get_home_parameters(self.serial_number)

def _set_home_parameters(self, direction: Optional[int] = None, lim_switch: Optional[int] = None,
velocity: Optional[float] = None, zero_offset: Optional[float] = None):
def _set_home_parameters(self, direction: int | None = None, lim_switch: int | None = None,
velocity: float | None = None, zero_offset: float | None = None):
if direction is None or lim_switch is None or velocity is None or zero_offset is None:
old_direction, old_lim_switch, old_velocity, old_zero_offset = self._get_home_parameters()
if direction is None:
Expand Down Expand Up @@ -265,3 +270,10 @@ def _move_home(self):

def _move_home_async(self):
self.apt.mot_move_home(self.serial_number, False)


class K10CR1(ThorlabsK10CR1):
def __init__(self, name: str, device_id: int, apt: Thorlabs_APT, **kwargs):
warnings.warn('This class name is deprecated. Please use the ThorlabsK10CR1 class instead',
DeprecationWarning)
super().__init__(name, device_id, apt, **kwargs)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from __future__ import annotations

from qcodes_contrib_drivers.drivers.Thorlabs.private.kinesis import enums, isc


class ThorlabsK10CR1(isc.KinesisISCInstrument, prefix='ISC',
hardware_type=enums.KinesisHWType.CageRotator):
"""Kinesis driver for Thorlabs K10CR1 cage rotator."""
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"""Drivers for Thorlabs MFF10x.

There are two driver versions:
- Kinesis
- APT

The APT platform has been deprecated by Thorlabs.
"""
Original file line number Diff line number Diff line change
@@ -1,8 +1,30 @@
import warnings

from qcodes import Instrument
from .private.APT import Thorlabs_APT, ThorlabsHWType
from qcodes_contrib_drivers.drivers.Thorlabs.private.APT import (
ThorlabsHWType, Thorlabs_APT
)


def _position_get_parser(val) -> str:
val = int(val)
if val == 0:
return 'open'
elif val == 1:
return 'close'
raise ValueError('Invalid return code', val)


def _position_set_parser(val) -> int:
if val == 'open':
return 0
elif val == 'close':
return 1
else:
return int(val)

class Thorlabs_MFF10x(Instrument):

class ThorlabsMFF10x(Instrument):
"""
Instrument driver for the Thorlabs MFF10x mirror flipper.

Expand Down Expand Up @@ -34,7 +56,8 @@ def __init__(self, name: str, device_id: int, apt: Thorlabs_APT, **kwargs):
self.add_parameter('position',
get_cmd=self._get_position,
set_cmd=self._set_position,
get_parser=int,
get_parser=_position_get_parser,
set_parser=_position_set_parser,
label='Position')

# print connect message
Expand All @@ -52,3 +75,10 @@ def _get_position(self):
# set methods
def _set_position(self, position):
self.apt.mot_move_jog(self.serial_number, position+1, False)


class MFF10x(ThorlabsMFF10x):
def __init__(self, name: str, device_id: int, apt: Thorlabs_APT, **kwargs):
warnings.warn('This class name is deprecated. Please use the ThorlabsMFF10x class instead',
DeprecationWarning)
super().__init__(name, device_id, apt, **kwargs)
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
from __future__ import annotations

import pathlib
from typing import Any, Literal, Mapping

from qcodes.parameters import Parameter
from qcodes.validators import validators as vals
from qcodes_contrib_drivers.drivers.Thorlabs.private.kinesis import enums
from qcodes_contrib_drivers.drivers.Thorlabs.private.kinesis.core import (
KinesisInstrument
)


class ThorlabsMFF10x(KinesisInstrument, prefix='FF',
hardware_type=enums.KinesisHWType.FilterFlipper):
"""Kinesis driver for Thorlabs MFF10x filter flipper.

Args:
name:
An identifier for this instrument.
dll_dir (optional):
The directory where the kinesis dlls reside.
serial (optional):
The serial number of the device to connect to. If omitted,
the first available device found will be used. For a list
of all available devices, use
:meth:`list_available_devices` on an existing instance or
:func:`~qcodes_contrib_drivers.drivers.Thorlabs.private.kinesis.core.list_available_devices`.
simulation (optional):
Enable the Kinesis simulator mode. Note that the serial
number assigned to the simulated device should be given
since otherwise the first available device will be
connected (which might not be a simulated but a real one).
position_mapping (optional):
A val mapping for a more human-readable position mapping
than the internally used 1 and 2. Defaults to
``{'open': 1, 'close': 2}``.
metadata (optional):
Additional static metadata.
label (optional):
Nicely formatted name of the instrument.

"""

def __init__(self, name: str, dll_dir: str | pathlib.Path | None = '',
serial: int | None = None, simulation: bool = False,
polling: int = 200, home: bool = False,
position_mapping: Mapping[str, Literal[1, 2]] | None = None,
metadata: Mapping[Any, Any] | None = None,
label: str | None = None):
super().__init__(name, dll_dir=dll_dir, serial=serial,
simulation=simulation, polling=polling, home=home,
metadata=metadata, label=label)

self.position = Parameter(
'position',
get_cmd=self._kinesis.get_position,
set_cmd=self._kinesis.move_to_position,
val_mapping=position_mapping or {'open': 1, 'close': 2},
label='Position',
instrument=self
)
"""The position of the flipper."""
self.transit_time = Parameter(
'transit_time',
get_cmd=self._kinesis.get_transit_time,
set_cmd=self._kinesis.set_transit_time,
vals=vals.Ints(300, 2800),
set_parser=int,
unit='ms',
label='Transit time',
instrument=self
)
"""The transit time between two positions."""

def toggle_position(self):
"""Toggle the position of the flipper."""
# val_mapping is dynamic, so use inverse_val_mapping together
# with the hardware values
if self.position() == self.position.inverse_val_mapping[1]:
self.position(self.position.inverse_val_mapping[2])
else:
self.position(self.position.inverse_val_mapping[1])
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
"""Drivers for Thorlabs PM100D.

There are two driver versions:
- TLPM (libusb)
- VISA

Newer versions of the Thorlabs Power Meter software use the TLPM driver
and include a utility to switch the device between the two driver
versions.
"""
Loading