Source code for pylablib.aux_libs.devices.HighFinesse

from .misc import default_lib_folder, load_lib, default_placing_message
from ...core.devio.interface import IDevice
from ...core.utils import general

import os.path
import time
import ctypes


[docs]class HFError(RuntimeError): """Generic HighFinesse wavemeter error"""
[docs]class WS(IDevice): """ HighFinesse WS6/7 precision wavemeter. Args: lib_path(str): path to the wlmData6.dll or wlmData7.dll (default is to use the library supplied with the package) idx(int): wavemeter input index (starts from 1) serv_path: path to server executable (last executed by default) version: wavemeter version (3-4 digit id number) hide_app: if ``True``, start the wavemeter application hidden; otherwise, start it on top """ def __init__(self, lib_path=None, idx=1, serv_path=None, version=None, hide_app=False, timeout=10.): IDevice.__init__(self) error_message="The library is supplied with the designated HighFinesse wavemeter software;\n{}".format(default_placing_message) if lib_path in [6,7,None]: lib_path=("wlmData6.dll" if lib_path==6 else "wlmData7.dll"), "wlmData.dll" self.dll=load_lib(lib_path,locations=("local","global"),call_conv="stdcall",error_message=error_message) else: self.dll=load_lib(lib_path,call_conv="stdcall",error_message=error_message) self.dll.Instantiate.restype=ctypes.c_long self.dll.Instantiate.argtypes=[ctypes.c_long,ctypes.c_long,ctypes.c_long,ctypes.c_long] self.dll.ControlWLM.restype=ctypes.c_long self.dll.ControlWLM.argtypes=[ctypes.c_long,ctypes.c_char_p,ctypes.c_long] self.dll.Operation.restype=ctypes.c_long self.dll.Operation.argtypes=[ctypes.c_short] self.dll.GetFrequencyNum.restype=ctypes.c_double self.dll.GetFrequencyNum.argtypes=[ctypes.c_long,ctypes.c_double] self.dll.GetWavelengthNum.restype=ctypes.c_double self.dll.GetWavelengthNum.argtypes=[ctypes.c_long,ctypes.c_double] self.dll.GetExposureModeNum.restype=ctypes.c_long self.dll.GetExposureModeNum.argtypes=[ctypes.c_long,ctypes.c_bool] self.dll.SetExposureModeNum.restype=ctypes.c_long self.dll.SetExposureModeNum.argtypes=[ctypes.c_long,ctypes.c_bool] self.dll.GetExposureNum.restype=ctypes.c_long self.dll.GetExposureNum.argtypes=[ctypes.c_long,ctypes.c_long,ctypes.c_long] self.dll.SetExposureNum.restype=ctypes.c_long self.dll.SetExposureNum.argtypes=[ctypes.c_long,ctypes.c_long,ctypes.c_long] self.dll.GetSwitcherMode.restype=ctypes.c_bool self.dll.GetSwitcherMode.argtypes=[ctypes.c_long] self.dll.SetSwitcherMode.restype=ctypes.c_long self.dll.SetSwitcherMode.argtypes=[ctypes.c_long] self.idx=idx self.serv_path=serv_path self.version=version self.hide_app=hide_app self.timeout=timeout self.open() self._add_status_node("frequency",self.get_frequency) self._add_status_node("wavelength",self.get_wavelength) self._add_settings_node("exposure_mode",self.get_exposure_mode,self.set_exposure_mode) self._add_settings_node("exposure",self.get_exposure,self.set_exposure) self._add_settings_node("switcher_mode",self.get_switcher_mode,self.set_switcher_mode)
[docs] def open(self): self.dll.ControlWLM(2 if self.hide_app else 1,self.serv_path,self.version or 0) ctd=general.Countdown(self.timeout) while True: if self.dll.Instantiate(-1,0,0,0): break time.sleep(0.1) if ctd.passed(): raise HFError("Timeout on application start") self.start_measurement()
_GetFunc_err={ 0:"ErrNoValue: No value", -1:"ErrNoSignal: No signal detected", -2:"ErrBadSignal: No calculable signal detected", -3:"ErrLowSignal: Signal too small / underexposed", -4:"ErrBigSignal: Signal too big / overexposed", -5:"ErrWlmMissing: Wavelength meter is not active", -6:"ErrNotAvailable: Function is not available", -8:"ErrNoPulse: Signal can't be separated into pulses", -7:"InfNothingChanged", -13:"ErrDiv0", -14:"ErrOutOfRange", -15:"ErrUnitNotAvaliable"} def _check_getfunc_error(self, func_name, err): if err>=0: return if err in self._GetFunc_err: raise HFError("{} returned error: {} ({})".format(func_name,err,self._GetFunc_err[err])) else: raise HFError("{} returned unknown error: {}".format(func_name,err)) _SetFunc_err={ 0:"ResERR_NoErr: No error", -1:"ResERR_WlmMissing: Wavelength meter is not active", -2:"ResERR_CouldNotSet: Could not set value which should be accessible (contact Angstrom)", -3:"ResERR_ParmOutOfRange: Parameter is out of range", -4:"ResERR_WlmOutOfResources: Wavelength meter is out of memory or resources (contact Angstrom if persists)", -5:"ResERR_WlmInternalError: Wavelength meter internal error (contact Angstrom)", -6:"ResERR_NotAvailable: Parameter setting is not available for this wavelength meter version", -7:"ResERR_WlmBusy: Wavelength meter is busy with another function (contact Angstrom if persists)", -8:"ResERR_NotInMeasurementMode: Call is not allowed in measurement mode", -9:"ResERR_OnlyInMeasurementMode: Call is only allowed in measurement mode", -10:"ResERR_ChannelNotAvailable: Given channel is not available for this device", -11:"ResERR_ChannelTemporarilyNotAvailable: Given channel is generally available, but the device is not in switch mode", -12:"ResERR_CalOptionNotAvailable: Wavelength meter does not dispose of this calibration option", -13:"ResERR_CalWavelengthOutOfRange: The given calibration wavelength is out of its allowed range", -14:"ResERR_BadCalibrationSignal: The given wavelength does not match the connected calibration laser or its signal is of bad quality", -15:"ResERR_UnitNotAvailable: This is not a proper result unit"} def _check_setfunc_error(self, func_name, err): if err>=0: return if err in self._SetFunc_err: raise HFError("{} returned error: {} ({})".format(func_name,err,self._SetFunc_err[err])) else: raise HFError("{} returned unknown error: {}".format(func_name,err))
[docs] def get_frequency(self, return_exp_error=True): """ Get the wavemeter readings (in Hz). If ``return_exp_error==True``, return ``"under"`` if the meter is underexposed or ``"over"`` is it is overexposed. Otherwise, raise an error. """ res=self.dll.GetFrequencyNum(self.idx,0.) if int(res)<=0: err=int(res) if return_exp_error: if err==-1: return "nosig" if err==-2: return "badsig" if err==-3: return "under" if err==-4: return "over" self._check_getfunc_error("GetFrequencyNum",err) return res*1E12
[docs] def get_wavelength(self, return_exp_error=True): """ Get the wavemeter readings (in m, and in vacuum). If ``return_exp_error==True``, return ``"under"`` if the meter is underexposed or ``"over"`` is it is overexposed. Otherwise, raise an error. """ res=self.dll.GetWavelengthNum(self.idx,0) if int(res)<=0: err=int(res) if return_exp_error: if err==-1: return "nosig" if err==-2: return "badsig" if err==-3: return "under" if err==-4: return "over" self._check_getfunc_error("GetWavelengthNum",err) return res*1E-9
[docs] def start_measurement(self): self.dll.Operation(2)
[docs] def stop_measurement(self): self.dll.Operation(0)
[docs] def get_exposure_mode(self): """Get the exposure mode (0 for manual, 1 for auto)""" return bool(self.dll.GetExposureModeNum(self.idx,0))
[docs] def set_exposure_mode(self, auto_exposure=True): """Get the exposure mode (manual or auto)""" err=self.dll.SetExposureModeNum(self.idx,1 if auto_exposure else 0) self._check_setfunc_error("SetExposureModeNum",err) return self.get_exposure_mode()
[docs] def get_exposure(self, sensor=1): """Get the exposure for a given sensor (starting from 1)""" exposure=self.dll.GetExposureNum(self.idx,sensor,0) self._check_getfunc_error("GetExposureNum",exposure) return exposure
[docs] def set_exposure(self, exposure, sensor=1): """Manually set the exposure for a given sensor (starting from 1)""" err=self.dll.SetExposureNum(self.idx,sensor,exposure) self._check_setfunc_error("SetExposureNum",err) return self.get_exposure()
[docs] def get_switcher_mode(self): """Get the switcher mode (0 for off, 1 for on)""" return self.dll.GetSwitcherMode(0)
[docs] def set_switcher_mode(self, switching=True): """Set the switcher mode (True or False)""" err=self.dll.SetSwitcherMode(1 if switching else 0) self._check_setfunc_error("SetSwitcherMode",err) return self.get_switcher_mode()