Source code for instruments.ondax.lm

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Provides the support for the Ondax LM Laser.

Class originally contributed by Catherine Holloway.
"""

# IMPORTS #####################################################################

from __future__ import absolute_import
from __future__ import division

from enum import IntEnum

import quantities as pq

from instruments.abstract_instruments import Instrument
from instruments.util_fns import convert_temperature, assume_units

# CLASSES #####################################################################


[docs]class LM(Instrument): """ The LM is the Ondax SureLock VHG-stabilized laser diode. The user manual can be found on the `Ondax website`_. .. _Ondax website: http://www.ondax.com/Downloads/SureLock/Compact%20laser%20module%20manual.pdf """ def __init__(self, filelike): super(LM, self).__init__(filelike) self.terminator = "\r" self.apc = self._AutomaticPowerControl(self) self.acc = self._AutomaticCurrentControl(self) self.tec = self._ThermoElectricCooler(self) self.modulation = self._Modulation(self) self._enabled = None # ENUMS #
[docs] class Status(IntEnum): """ Enum containing the valid states of the laser """ normal = 1 inner_modulation = 2 power_scan = 3 calibrate = 4 shutdown_current = 5 shutdown_overheat = 6 waiting_stable_temperature = 7 waiting = 8
# INNER CLASSES # class _AutomaticCurrentControl(object): """ Options and functions related to the laser diode's automatic current control driver. .. warning:: This class is not designed to be accessed directly. It should be interfaced via `LM.acc` """ def __init__(self, parent): self._parent = parent self._enabled = False @property def target(self): """ Gets the automatic current control target setting. This property is accessed via the `LM.acc` namespace. Example usage: >>> import instruments as ik >>> laser = ik.ondax.LM.open_serial('/dev/ttyUSB0', baud=1234) >>> print(laser.acc.target) :return: Current ACC of the Laser :units: mA :type: `~quantities.Quantity` """ response = float(self._parent.query("rstli?")) return response*pq.mA @property def enabled(self): """ Get/Set the enabled state of the ACC driver. This property is accessed via the `LM.acc` namespace. Example usage: >>> import instruments as ik >>> laser = ik.ondax.LM.open_serial('/dev/ttyUSB0', baud=1234) >>> print(laser.acc.enabled) >>> laser.acc.enabled = True :type: `bool` """ return self._enabled @enabled.setter def enabled(self, newval): if not isinstance(newval, bool): raise TypeError("ACC driver enabled property must be specified" "with a boolean, got {}.".format(type(newval))) if newval: self._parent.sendcmd("lcen") else: self._parent.sendcmd("lcdis") self._enabled = newval def on(self): """ Turns on the automatic current control driver. This function is accessed via the `LM.acc` namespace. Example usage: >>> import instruments as ik >>> laser = ik.ondax.LM.open_serial('/dev/ttyUSB0', baud=1234) >>> laser.acc.on() """ self._parent.sendcmd("lcon") def off(self): """ Turn off the automatic current control driver. This function is accessed via the `LM.acc` namespace. Example usage: >>> import instruments as ik >>> laser = ik.ondax.LM.open_serial('/dev/ttyUSB0', baud=1234) >>> laser.acc.off() """ self._parent.sendcmd("lcoff") class _AutomaticPowerControl(object): """ Options and functions related to the laser diode's automatic power control driver. .. warning:: This class is not designed to be accessed directly. It should be interfaced via `LM.apc` """ def __init__(self, parent): self._parent = parent self._enabled = False @property def target(self): """ Gets the target laser power of the automatic power control in mW. This property is accessed via the `LM.apc` namespace. Example usage: >>> import instruments as ik >>> laser = ik.ondax.LM.open_serial('/dev/ttyUSB0', baud=1234) >>> print(laser.apc.target) :return: the target laser power :units: mW :type: `~quantities.Quantities` """ response = self._parent.query("rslp?") return float(response)*pq.mW @property def enabled(self): """ Get/Set the enabled state of the automatic power control driver. This property is accessed via the `LM.apc` namespace. Example usage: >>> import instruments as ik >>> laser = ik.ondax.LM.open_serial('/dev/ttyUSB0', baud=1234) >>> print(laser.apc.enabled) >>> laser.apc.enabled = True :type: `bool` """ return self._enabled @enabled.setter def enabled(self, newval): if not isinstance(newval, bool): raise TypeError("APC driver enabled property must be specified " "with a boolean, got {}.".format(type(newval))) if newval: self._parent.sendcmd("len") else: self._parent.sendcmd("ldis") self._enabled = newval def start(self): """ Start the automatic power control scan. This function is accessed via the `LM.apc` namespace. Example usage: >>> import instruments as ik >>> laser = ik.ondax.LM.open_serial('/dev/ttyUSB0', baud=1234) >>> laser.apc.start() """ self._parent.sendcmd("sps") def stop(self): """ Stop the automatic power control scan. This function is accessed via the `LM.apc` namespace. Example usage: >>> import instruments as ik >>> laser = ik.ondax.LM.open_serial('/dev/ttyUSB0', baud=1234) >>> laser.apc.stop() """ self._parent.sendcmd("cps") class _Modulation(object): """ Options and functions related to the laser's optical output modulation. .. warning:: This class is not designed to be accessed directly. It should be interfaced via `LM.modulation` """ def __init__(self, parent): self._parent = parent self._enabled = False @property def on_time(self): """ Gets/sets the TTL modulation on time, in milliseconds. This property is accessed via the `LM.modulation` namespace. Example usage: >>> import instruments as ik >>> import quantities as pq >>> laser = ik.ondax.LM.open_serial('/dev/ttyUSB0', baud=1234) >>> print(laser.modulation.on_time) >>> laser.modulation.on_time = 1 * pq.ms :return: The TTL modulation on time :units: As specified (if a `~quantities.Quantity`) or assumed to be of units milliseconds. :type: `~quantities.Quantity` """ response = self._parent.query("stsont?") return float(response)*pq.ms @on_time.setter def on_time(self, newval): newval = assume_units(newval, pq.ms).rescale(pq.ms).magnitude self._parent.sendcmd("stsont:"+str(newval)) @property def off_time(self): """ Gets/sets the TTL modulation off time, in milliseconds. This property is accessed via the `LM.modulation` namespace. Example usage: >>> import instruments as ik >>> import quantities as pq >>> laser = ik.ondax.LM.open_serial('/dev/ttyUSB0', baud=1234) >>> print(laser.modulation.on_time) >>> laser.modulation.on_time = 1 * pq.ms :return: The TTL modulation off time. :units: As specified (if a `~quantities.Quantity`) or assumed to be of units milliseconds. :type: `~quantities.Quantity` """ response = self._parent.query("stsofft?") return float(response)*pq.ms @off_time.setter def off_time(self, newval): newval = assume_units(newval, pq.ms).rescale(pq.ms).magnitude self._parent.sendcmd("stsofft:"+str(newval)) @property def enabled(self): """ Get/Set the TTL modulation output state. This property is accessed via the `LM.modulation` namespace. Example usage: >>> import instruments as ik >>> laser = ik.ondax.LM.open_serial('/dev/ttyUSB0', baud=1234) >>> print(laser.modulation.enabled) >>> laser.modulation.enabled = True :type: `bool` """ return self._enabled @enabled.setter def enabled(self, newval): if not isinstance(newval, bool): raise TypeError("Modulation enabled property must be specified " "with a boolean, got {}.".format(type(newval))) if newval: self._parent.sendcmd("stm") else: self._parent.sendcmd("ctm") self._enabled = newval class _ThermoElectricCooler(object): """ Options and functions relating to the laser diode's thermo electric cooler. .. warning:: This class is not designed to be accessed directly. It should be interfaced via `LM.tec` """ def __init__(self, parent): self._parent = parent self._enabled = False @property def current(self): """ Gets the thermoelectric cooler current setting. This property is accessed via the `LM.tec` namespace. Example usage: >>> import instruments as ik >>> laser = ik.ondax.LM.open_serial('/dev/ttyUSB0', baud=1234) >>> print(laser.tec.current) :units: mA :type: `~quantities.Quantity` """ response = self._parent.query("rti?") return float(response)*pq.mA @property def target(self): """ Gets the thermoelectric cooler target temperature. This property is acccessed via the `LM.tec` namespace. Example usage: >>> import instruments as ik >>> laser = ik.ondax.LM.open_serial('/dev/ttyUSB0', baud=1234) >>> print(laser.tec.target) :units: Degrees Celcius :type: `~quantities.Quantity` """ response = self._parent.query("rstt?") return float(response)*pq.degC @property def enabled(self): """ Gets/sets the enable state for the thermoelectric cooler. This property is accessed via the `LM.tec` namespace. Example usage: >>> import instruments as ik >>> laser = ik.ondax.LM.open_serial('/dev/ttyUSB0', baud=1234) >>> print(laser.tec.enabled) >>> laser.tec.enabled = True :type: `bool` """ return self._enabled @enabled.setter def enabled(self, newval): if not isinstance(newval, bool): raise TypeError("TEC enabled property must be specified with " "a boolean, got {}.".format(type(newval))) if newval: self._parent.sendcmd("tecon") else: self._parent.sendcmd("tecoff") self._enabled = newval def _ack_expected(self, msg=""): if msg.find("?") > 0: return None return "OK" @property def firmware(self): """ Gets the laser system firmware version. :type: `str` """ response = self.query("rsv?") return response @property def current(self): """ Gets/sets the laser diode current, in mA. :units: As specified (if a `~quantities.Quantity`) or assumed to be of units mA. :type: `~quantities.Quantity` """ response = self.query("rli?") return float(response)*pq.mA @current.setter def current(self, newval): newval = assume_units(newval, pq.mA).rescale(pq.mA).magnitude self.sendcmd("slc:"+str(newval)) @property def maximum_current(self): """ Get/Set the maximum laser diode current in mA. If the current is set over the limit, the laser will shut down. :units: As specified (if a `~quantities.Quantity`) or assumed to be of units mA. :type: `~quantities.Quantity` """ response = self.query("rlcm?") return float(response)*pq.mA @maximum_current.setter def maximum_current(self, newval): newval = assume_units(newval, pq.mA).rescale('mA').magnitude self.sendcmd("smlc:" + str(newval)) @property def power(self): """ Get/Set the laser's optical power in mW. :units: As specified (if a `~quantities.Quantity`) or assumed to be of units mW. :rtype: `~quantities.Quantity` """ response = self.query("rlp?") return float(response)*pq.mW @power.setter def power(self, newval): newval = assume_units(newval, pq.mW).rescale(pq.mW).magnitude self.sendcmd("slp:"+str(newval)) @property def serial_number(self): """ Gets the laser controller serial number :type: `str` """ response = self.query("rsn?") return response @property def status(self): """ Read laser controller run status. :type: `LM.Status` """ response = self.query("rlrs?") return self.Status(int(response)) @property def temperature(self): """ Gets/sets laser diode temperature. :units: As specified (if a `~quantities.Quantity`) or assumed to be of units degrees celcius. :type: `~quantities.Quantity` """ response = self.query("rtt?") return float(response)*pq.degC @temperature.setter def temperature(self, newval): newval = convert_temperature(newval, pq.degC).magnitude self.sendcmd("stt:"+str(newval)) @property def enabled(self): """ Gets/sets the laser emission enabled status. :type: `bool` """ return self._enabled @enabled.setter def enabled(self, newval): if not isinstance(newval, bool): raise TypeError("Laser module enabled property must be specified " "with a boolean, got {}.".format(type(newval))) if newval: self.sendcmd("lon") else: self.sendcmd("loff") self._enabled = newval
[docs] def save(self): """ Save current settings in flash memory. """ self.sendcmd("ssc")
[docs] def reset(self): """ Reset the laser controller. """ self.sendcmd("reset")