Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
98 changes: 46 additions & 52 deletions microscope/cameras/atmcd.py
Original file line number Diff line number Diff line change
Expand Up @@ -1134,7 +1134,7 @@ def __str__(self):
from threading import Lock
import functools
from microscope import devices
from microscope.devices import keep_acquiring, Setting, Binning, ROI
from microscope.devices import keep_acquiring, Binning, ROI
import time

# A lock on the DLL used to ensure DLL calls act on the correct device.
Expand Down Expand Up @@ -1255,17 +1255,17 @@ def initialize(self):
# Mode
name = 'readout mode'
if self._readout_modes:
self.settings[name] = Setting(name, 'enum',
None,
self._set_readout_mode,
lambda: [str(mode) for mode in self._readout_modes])
self.add_setting(name, 'enum',
None,
self._set_readout_mode,
lambda: [str(mode) for mode in self._readout_modes])
self.settings[name].set(0)
# TriggerMode
name = 'TriggerMode'
self.settings[name] = Setting(name, 'enum',
None,
self._bind(SetTriggerMode),
TriggerMode)
self.add_setting(name, 'enum',
None,
self._bind(SetTriggerMode),
TriggerMode)
if self._caps.ulTriggerModes & AC_TRIGGERMODE_EXTERNAL:
self.settings[name].set(TriggerMode.EXTERNAL)
elif self._caps.ulTriggerModes & AC_TRIGGERMODE_CONTINUOUS:
Expand All @@ -1284,9 +1284,7 @@ def initialize(self):
setter = self._bind(SetMCPGain)
vrange = self._bind(GetMCPGainRange)
if getter or setter:
self.settings[name] = Setting(name, 'int',
getter, setter, vrange,
setter is None)
self.add_setting(name, 'int', getter, setter, vrange, setter is None)
# Temperature
name = 'TemperatureSetPoint'
getter, setter, vrange = None, None, None
Expand All @@ -1295,77 +1293,73 @@ def initialize(self):
if self._caps.ulGetFunctions & AC_GETFUNCTION_TEMPERATURERANGE:
vrange = self._bind(GetTemperatureRange)
if setter:
self.settings[name] = Setting(name, 'int',
None, setter, vrange,
setter is None)
self.add_setting(name, 'int', None, setter, vrange, setter is None)
# Set a conservative default temperature set-point.
self.settings[name].set(-20)
# Fan control
name = 'Temperature'
self.settings[name] = Setting(name, 'int',
self.get_sensor_temperature,
None, (None, None), True)
self.add_setting(name, 'int', self.get_sensor_temperature, None, (None, None), True)
name = 'Fan mode'
self.settings[name] = Setting(name, 'enum',
None, # Can't query fan mode
self._bind(SetFanMode),
{0:'full', 1:'low', 2:'off'}
)
self.add_setting(name, 'enum',
None, # Can't query fan mode
self._bind(SetFanMode),
{0:'full', 1:'low', 2:'off'}
)
# Cooler control
name = 'Cooler Enabled'
self.settings[name] = Setting(name, 'bool',
None,
self._set_cooler_state,
None)
self.add_setting(name, 'bool',
None,
self._set_cooler_state,
None)
self.settings[name].set(True)
# Binning
name = 'Binning'
self.settings[name] = Setting(name, 'tuple',
self.get_binning,
self.set_binning,
None)
self.add_setting(name, 'tuple',
self.get_binning,
self.set_binning,
None)
# Roi
name = 'Roi'
self.settings[name] = Setting(name, 'tuple',
self.get_roi,
lambda roi: self.set_roi(*roi),
None)
self.add_setting(name, 'tuple',
self.get_roi,
lambda roi: self.set_roi(*roi),
None)
# BaselineClamp
name = 'BaselineClamp'
if self._caps.ulSetFunctions & AC_SETFUNCTION_BASELINECLAMP:
self.settings[name] = Setting(name, 'bool',
None,
self._bind(SetBaselineClamp))
self.add_setting(name, 'bool',
None,
self._bind(SetBaselineClamp))
self.settings[name].set(False)
# BaselineOffset
nam = 'BaselineOffset'
if self._caps.ulSetFunctions & AC_SETFUNCTION_BASELINEOFFSET:
self.settings[name] = Setting(name, 'int',
None,
self._bind(SetBaselineOffset),
(-1000, 1000))
self.add_setting(name, 'int',
None,
self._bind(SetBaselineOffset),
(-1000, 1000))
self.settings[name].set(0)
# EMAdvanced
name = 'EMAdvanced'
if self._caps.ulSetFunctions & AC_SETFUNCTION_EMADVANCED:
self.settings[name] = Setting(name, 'bool',
None,
self._bind(SetEMAdvanced))
self.add_setting(name, 'bool',
None,
self._bind(SetEMAdvanced))
self.settings[name].set(False)
# GateMode
name = 'GateMode'
if self._caps.ulSetFunctions & AC_SETFUNCTION_GATEMODE:
vrange = range(0, [5,6][self._caps.ulCameraType & AC_CAMERATYPE_ISTAR])
self.setings[name] = Setting(name, 'int',
None,
self._bind(SetGateMode),
vrange)
self.add_setting(name, 'int',
None,
self._bind(SetGateMode),
vrange)
# HighCapacity
name = 'HighCapacity'
if self._caps.ulSetFunctions & AC_SETFUNCTION_HIGHCAPACITY:
self.settings[name] = Setting(name, 'bool',
None,
self._bind(SetHighCapacity))
self.add_setting(name, 'bool',
None,
self._bind(SetHighCapacity))

def _fetch_data(self):
"""Poll for data and return it, with minimal processing.
Expand Down
9 changes: 5 additions & 4 deletions microscope/devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,10 @@
_call_if_callable = lambda f: f() if callable(f) else f


class Setting():
class _Setting():
# TODO: refactor into subclasses to avoid if isinstance .. elif .. else.
# Settings classes should be private: devices should use a factory method
# rather than instantiate settings directly; most already use add_setting for this.
def __init__(self, name, dtype, get_func, set_func=None, values=None, readonly=False):
"""Create a setting.

Expand Down Expand Up @@ -265,8 +268,6 @@ def make_safe(self):
def add_setting(self, name, dtype, get_func, set_func, values, readonly=False):
"""Add a setting definition.

Can also use self.settings[name] = Setting(name, dtype,...)

:param name: the setting's name
:param dtype: a data type from ('int', 'float', 'bool', 'enum', 'str')
:param get_func: a function to get the current value
Expand All @@ -290,7 +291,7 @@ class with getter, setter, etc., and adding Setting instances as
raise Exception("Invalid values type for %s '%s': expected function or %s" %
(dtype, name, DTYPES[dtype][1:]))
else:
self.settings[name] = Setting(name, dtype, get_func, set_func, values, readonly)
self.settings[name] = _Setting(name, dtype, get_func, set_func, values, readonly)

def get_setting(self, name):
"""Return the current value of a setting."""
Expand Down
3 changes: 1 addition & 2 deletions microscope/stages/linkam.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,9 @@
* get_id returns an empty string, not the device serial number."""

import ctypes
from ctypes import addressof, byref, POINTER
from ctypes import byref, POINTER
from enum import Enum, IntEnum
from microscope import devices
from microscope.devices import Setting
import datetime, time

_max_version_length = 20
Expand Down
4 changes: 2 additions & 2 deletions microscope/testsuite/test_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ def create_enum_setting(default, with_getter=True, with_setter=True):
thing = ThingWithSomething(EnumSetting(default))
getter = thing.get_val if with_getter else None
setter = thing.set_val if with_setter else None
setting = microscope.devices.Setting('foobar', 'enum', get_func=getter,
set_func=setter, values=EnumSetting)
setting = microscope.devices._Setting('foobar', 'enum', get_func=getter,
set_func=setter, values=EnumSetting)
return setting, thing


Expand Down