Skip to content

Index

pychilaslasers.laser_components

Laser hardware components package.

This package provides classes for controlling and interfacing with various laser hardware components including diode, TEC and heating elements. It offers both low-level component access and high-level abstractions for laser control operations.

Modules:

  • LaserComponent

    Base class for all laser hardware components

  • Diode

    Laser diode control and monitoring

  • TEC

    Temperature control functionality

  • heaters

    Phase section, ring heaters, and tunable coupler

Authors: SDU

Classes

LaserComponent(laser: Laser)

Bases: ABC


              flowchart TD
              pychilaslasers.laser_components.LaserComponent[LaserComponent]

              

              click pychilaslasers.laser_components.LaserComponent href "" "pychilaslasers.laser_components.LaserComponent"
            

Abstract base class for all laser hardware components.

This class defines the common interface that all laser components must implement. It provides standardized access to the value of the sensor and it's unit.

Attributes:

  • value (float) –

    The current value of the component (implementation-dependent).

  • unit (str) –

    The unit of measurement for this component's values.

Source code in src/pychilaslasers/laser_components/laser_component.py
37
38
39
def __init__(self, laser: Laser) -> None:  # noqa: D107
    super().__init__()
    self._comm: Communication = laser.comm
Attributes
value: float abstractmethod property

Returns the current value of the component in appropriate units.

unit: str property

Returns the unit string (e.g., "mA", "°C", "V") for this component.

Driver(laser: Laser)

Bases: LaserComponent


              flowchart TD
              pychilaslasers.laser_components.Driver[Driver]
              pychilaslasers.laser_components.laser_component.LaserComponent[LaserComponent]

                              pychilaslasers.laser_components.laser_component.LaserComponent --> pychilaslasers.laser_components.Driver
                


              click pychilaslasers.laser_components.Driver href "" "pychilaslasers.laser_components.Driver"
              click pychilaslasers.laser_components.laser_component.LaserComponent href "" "pychilaslasers.laser_components.laser_component.LaserComponent"
            

Abstract base class for all laser drivers.

This class defines the common interface that all laser drivers should implement. It provides standardized access operating ranges of the drivers and setters.

Attributes:

  • value (float) –

    Setter for the value of this driver

  • min_value (float) –

    The minimum allowable value for this component.

  • max_value (float) –

    The maximum allowable value for this component.

Note

Subclasses should initialize self._min, self._max and self._unit during construction.

Source code in src/pychilaslasers/laser_components/driver.py
44
45
def __init__(self, laser: Laser) -> None:  # noqa: D107
    super().__init__(laser)
Attributes
value: float abstractmethod property writable

Returns the current value of the driver in appropriate units.

min_value: float property

Returns the minimum value that can be safely set for this component.

max_value: float property

Returns the maximum value that can be safely set for this component.

TEC(laser: Laser)

Bases: Driver


              flowchart TD
              pychilaslasers.laser_components.TEC[TEC]
              pychilaslasers.laser_components.driver.Driver[Driver]
              pychilaslasers.laser_components.laser_component.LaserComponent[LaserComponent]

                              pychilaslasers.laser_components.driver.Driver --> pychilaslasers.laser_components.TEC
                                pychilaslasers.laser_components.laser_component.LaserComponent --> pychilaslasers.laser_components.driver.Driver
                



              click pychilaslasers.laser_components.TEC href "" "pychilaslasers.laser_components.TEC"
              click pychilaslasers.laser_components.driver.Driver href "" "pychilaslasers.laser_components.driver.Driver"
              click pychilaslasers.laser_components.laser_component.LaserComponent href "" "pychilaslasers.laser_components.laser_component.LaserComponent"
            

Temperature control component for laser thermal management.

This component automatically retrieves its operating range limits from the laser hardware and provides input validation.

Attributes:

  • target (float) –

    The target temperature in Celsius.

  • temp (float) –

    The current measured temperature in Celsius.

  • value (float) –

    Alias for the current temperature (inherited from LaserComponent).

  • current (float) –

    The current applied to the driver.

  • current_limit (float) –

    The maximum current that can be applied to the driver.

  • min_value (float) –

    Minimum allowable temperature target.

  • max_value (float) –

    Maximum allowable temperature target.

  • unit (str) –

    Temperature unit (Celsius).

Sets up the component by querying the laser hardware for its temperature operating limits and configuring the component with appropriate units and ranges.

Parameters:

  • laser (Laser) –

    The laser instance to control.

Source code in src/pychilaslasers/laser_components/tec.py
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
def __init__(self, laser: Laser) -> None:
    """Initialize the temperature control component.

    Sets up the component by querying the laser hardware for its temperature
    operating limits and configuring the component
    with appropriate units and ranges.

    Args:
        laser: The laser instance to control.

    """
    super().__init__(laser=laser)
    self._min: float = float(self._comm.query("TEC:CFG:TMIN?"))
    self._max: float = float(self._comm.query("TEC:CFG:TMAX?"))
    self._unit: str = "°C"
Attributes
target: float property writable

Get the current target temperature in Celsius.

temp: float property

Get the current measured temperature reading in Celsius.

value: float property writable

Get the current temperature value.

Note

This is an alias for the temp property.

current: float property

Return the current applied to the TEC driver.

Returns:

  • float ( float ) –

    current in mA

current_limit: float property

The maximum current that can be applied to the TEC driver.

Returns:

  • float ( float ) –

    maximum current in Ampere

Functions
get_value() -> float

Return the current measured temperature in Celsius.

Returns:

  • float

    The current measured temperature in Celsius.

Source code in src/pychilaslasers/laser_components/tec.py
124
125
126
127
128
129
130
131
def get_value(self) -> float:
    """Return the current measured temperature in Celsius.

    Returns:
        The current measured temperature in Celsius.

    """
    return self.value
set_value(val: float) -> None

Set the target temperature of the TEC.

Parameters:

  • val (float) –

    The desired target temperature in Celsius.

Raises:

  • ValueError

    If target is not a number or is outside the valid range.

Source code in src/pychilaslasers/laser_components/tec.py
133
134
135
136
137
138
139
140
141
142
143
def set_value(self, val: float) -> None:
    """Set the target temperature of the TEC.

    Args:
        val: The desired target temperature in Celsius.

    Raises:
        ValueError: If target is not a number or is outside the valid range.

    """
    self.target = val
get_temp() -> float

Return the current measured temperature in Celsius.

Returns:

  • float

    The current measured temperature in Celsius.

Source code in src/pychilaslasers/laser_components/tec.py
145
146
147
148
149
150
151
152
def get_temp(self) -> float:
    """Return the current measured temperature in Celsius.

    Returns:
        The current measured temperature in Celsius.

    """
    return self.temp
get_target_temp() -> float

Return the current target temperature in Celsius.

Returns:

  • float

    The current target temperature in Celsius.

Source code in src/pychilaslasers/laser_components/tec.py
154
155
156
157
158
159
160
161
def get_target_temp(self) -> float:
    """Return the current target temperature in Celsius.

    Returns:
        The current target temperature in Celsius.

    """
    return self.target
set_target(target: float) -> None

Set the target temperature of the TEC.

Parameters:

  • target (float) –

    The desired target temperature in Celsius.

Raises:

  • ValueError

    If target is not a number or is outside the valid range.

Source code in src/pychilaslasers/laser_components/tec.py
163
164
165
166
167
168
169
170
171
172
173
def set_target(self, target: float) -> None:
    """Set the target temperature of the TEC.

    Args:
        target: The desired target temperature in Celsius.

    Raises:
        ValueError: If target is not a number or is outside the valid range.

    """
    self.target = target

Diode(laser: Laser)

Bases: Driver


              flowchart TD
              pychilaslasers.laser_components.Diode[Diode]
              pychilaslasers.laser_components.driver.Driver[Driver]
              pychilaslasers.laser_components.laser_component.LaserComponent[LaserComponent]

                              pychilaslasers.laser_components.driver.Driver --> pychilaslasers.laser_components.Diode
                                pychilaslasers.laser_components.laser_component.LaserComponent --> pychilaslasers.laser_components.driver.Driver
                



              click pychilaslasers.laser_components.Diode href "" "pychilaslasers.laser_components.Diode"
              click pychilaslasers.laser_components.driver.Driver href "" "pychilaslasers.laser_components.driver.Driver"
              click pychilaslasers.laser_components.laser_component.LaserComponent href "" "pychilaslasers.laser_components.laser_component.LaserComponent"
            

Laser driver diode component for current control.

Parameters:

  • laser (Laser) –

    The laser instance to control.

Attributes:

  • state (bool) –

    The current on/off state of the laser diode.

  • current (float) –

    The drive current level in milliamps.

  • value (float) –

    Alias for the drive current (inherited from LaserComponent).

  • min_value (float) –

    Minimum current (always 0.0 mA).

  • max_value (float) –

    Maximum current.

  • unit (str) –

    Current unit (mA).

Sets up the laser diode component by querying the hardware for its maximum current and configuring the component with appropriate current range and units.

Parameters:

  • laser (Laser) –

    The laser instance to control.

Source code in src/pychilaslasers/laser_components/diode.py
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
def __init__(self, laser: Laser) -> None:
    """Initialize the diode component with laser instance.

    Sets up the laser diode component by querying the hardware for its
    maximum current and configuring the component with
    appropriate current range and units.

    Args:
        laser: The laser instance to control.

    """
    super().__init__(laser=laser)
    self._min: float = 0.0
    self._max: float = float(laser._comm.query("LSR:IMAX?"))
    self._unit: str = "mA"
Attributes
state: bool property writable

Get the current on/off state of the laser diode.

Returns:

  • bool

    True if the laser diode is ON, False if OFF.

current: float property writable

Returns the current drive current in milliamps.

Returns:

  • float

    The current drive current in milliamps.

value: float property writable

Get the current drive current value.

Alias for the current property to implement the LaserComponent interface.

Returns:

  • float

    The current drive current in milliamps.

Functions
get_value() -> float

Alias for the value property getter.

Returns:

  • float

    The current drive current in milliamps.

Source code in src/pychilaslasers/laser_components/diode.py
110
111
112
113
114
115
116
117
def get_value(self) -> float:
    """Alias for the `value` property getter.

    Returns:
        The current drive current in milliamps.

    """
    return self.value
set_value(val: float) -> None

Alias for the value property setter.

Parameters:

  • val (float) –

    The desired drive current in milliamps.

Raises:

  • ValueError

    If current is not a number or is outside the valid range.

Source code in src/pychilaslasers/laser_components/diode.py
119
120
121
122
123
124
125
126
127
128
129
def set_value(self, val: float) -> None:
    """Alias for the `value` property setter.

    Args:
        val: The desired drive current in milliamps.

    Raises:
        ValueError: If current is not a number or is outside the valid range.

    """
    self.value = val
get_current() -> float

Alias for the current property getter.

Returns:

  • float

    The current drive current in milliamps.

Source code in src/pychilaslasers/laser_components/diode.py
131
132
133
134
135
136
137
138
def get_current(self) -> float:
    """Alias for the `current` property getter.

    Returns:
        The current drive current in milliamps.

    """
    return self.current
set_current(current_ma: float) -> None

Alias for the current property setter.

Parameters:

  • current_ma (float) –

    The desired drive current in milliamps.

Raises:

  • ValueError

    If current is not a number or is outside the valid range.

Source code in src/pychilaslasers/laser_components/diode.py
140
141
142
143
144
145
146
147
148
149
150
def set_current(self, current_ma: float) -> None:
    """Alias for the `current` property setter.

    Args:
        current_ma: The desired drive current in milliamps.

    Raises:
        ValueError: If current is not a number or is outside the valid range.

    """
    self.current = current_ma
turn_on() -> None

Turn the laser diode ON.

Alias for setting state to True.

Source code in src/pychilaslasers/laser_components/diode.py
152
153
154
155
156
157
def turn_on(self) -> None:
    """Turn the laser diode ON.

    Alias for setting `state` to True.
    """
    self.state = True
turn_off() -> None

Turn the laser diode OFF.

Alias for setting state to False.

Source code in src/pychilaslasers/laser_components/diode.py
159
160
161
162
163
164
def turn_off(self) -> None:
    """Turn the laser diode OFF.

    Alias for setting `state` to False.
    """
    self.state = False

EnclosureTemp(laser: Laser)

Bases: LaserComponent


              flowchart TD
              pychilaslasers.laser_components.EnclosureTemp[EnclosureTemp]
              pychilaslasers.laser_components.laser_component.LaserComponent[LaserComponent]

                              pychilaslasers.laser_components.laser_component.LaserComponent --> pychilaslasers.laser_components.EnclosureTemp
                


              click pychilaslasers.laser_components.EnclosureTemp href "" "pychilaslasers.laser_components.EnclosureTemp"
              click pychilaslasers.laser_components.laser_component.LaserComponent href "" "pychilaslasers.laser_components.laser_component.LaserComponent"
            

Component representing the temperature sensor on the laser module enclosure.

Parameters:

  • laser (Laser) –

    parent laser

Source code in src/pychilaslasers/laser_components/sensors.py
21
22
23
24
25
26
27
28
def __init__(self, laser: Laser):
    """Sensor on the enclosure of the laser.

    Args:
        laser(Laser): parent laser
    """
    super().__init__(laser)
    self._unit = "°C"
Attributes
temp property

Returns the current temperature readout of the sensor on the enclosure.

Functions

PhotoDiodeChannel

Bases: Enum


              flowchart TD
              pychilaslasers.laser_components.PhotoDiodeChannel[PhotoDiodeChannel]

              

              click pychilaslasers.laser_components.PhotoDiodeChannel href "" "pychilaslasers.laser_components.PhotoDiodeChannel"
            

Enum representing the available photodiode channels.

PhotoDiode(laser: Laser, channel: int | PhotoDiodeChannel)

Bases: LaserComponent


              flowchart TD
              pychilaslasers.laser_components.PhotoDiode[PhotoDiode]
              pychilaslasers.laser_components.laser_component.LaserComponent[LaserComponent]

                              pychilaslasers.laser_components.laser_component.LaserComponent --> pychilaslasers.laser_components.PhotoDiode
                


              click pychilaslasers.laser_components.PhotoDiode href "" "pychilaslasers.laser_components.PhotoDiode"
              click pychilaslasers.laser_components.laser_component.LaserComponent href "" "pychilaslasers.laser_components.laser_component.LaserComponent"
            

Component representing one of the photodiodes in the laser.

Parameters:

  • laser (Laser) –

    Parent laser.

  • channel (int | PhotodiodeChannel) –

    channel of photodiode

Source code in src/pychilaslasers/laser_components/sensors.py
72
73
74
75
76
77
78
79
80
81
82
83
84
def __init__(self, laser: Laser, channel: int | PhotoDiodeChannel) -> None:
    """Photodiode of laser.

    Args:
        laser(Laser): Parent laser.
        channel(int | PhotodiodeChannel): channel of photodiode
    """
    super().__init__(laser)
    self._channel: PhotoDiodeChannel = (
        channel
        if isinstance(channel, PhotoDiodeChannel)
        else PhotoDiodeChannel(channel)
    )
Attributes
readout: float property

Returns the photodiode readout as a float.

channel: PhotoDiodeChannel property

Measurement channel of the photodiode.

Functions

CPU(laser: Laser)

Bases: LaserComponent


              flowchart TD
              pychilaslasers.laser_components.CPU[CPU]
              pychilaslasers.laser_components.laser_component.LaserComponent[LaserComponent]

                              pychilaslasers.laser_components.laser_component.LaserComponent --> pychilaslasers.laser_components.CPU
                


              click pychilaslasers.laser_components.CPU href "" "pychilaslasers.laser_components.CPU"
              click pychilaslasers.laser_components.laser_component.LaserComponent href "" "pychilaslasers.laser_components.laser_component.LaserComponent"
            

Component representing the temperature sensor in the CPU of the laser module.

Source code in src/pychilaslasers/laser_components/sensors.py
45
46
47
48
def __init__(self, laser: Laser) -> None:
    """Temp sensor in the CPU of the laser module."""
    super().__init__(laser)
    self._unit = "°C"
Attributes
temp property

Returns the current temperature readout of the sensor in the CPU.

Functions

Heater(laser: Laser)

Bases: Driver


              flowchart TD
              pychilaslasers.laser_components.Heater[Heater]
              pychilaslasers.laser_components.driver.Driver[Driver]
              pychilaslasers.laser_components.laser_component.LaserComponent[LaserComponent]

                              pychilaslasers.laser_components.driver.Driver --> pychilaslasers.laser_components.Heater
                                pychilaslasers.laser_components.laser_component.LaserComponent --> pychilaslasers.laser_components.driver.Driver
                



              click pychilaslasers.laser_components.Heater href "" "pychilaslasers.laser_components.Heater"
              click pychilaslasers.laser_components.driver.Driver href "" "pychilaslasers.laser_components.driver.Driver"
              click pychilaslasers.laser_components.laser_component.LaserComponent href "" "pychilaslasers.laser_components.laser_component.LaserComponent"
            

Base class for laser heater components.

Provides common functionality for all heater types including value setting and channel management.

Attributes:

Sets up the heater with its operating limits and units by querying the laser hardware.

Parameters:

  • laser (Laser) –

    The laser instance to control.

Source code in src/pychilaslasers/laser_components/heaters/heaters.py
41
42
43
44
45
46
47
48
49
50
51
52
53
54
def __init__(self, laser: Laser) -> None:
    """Initialize the heater component.

    Sets up the heater with its operating limits and units by
    querying the laser hardware.

    Args:
        laser: The laser instance to control.

    """
    super().__init__(laser)
    self._min: float = float(self._comm.query(f"DRV:LIM:MIN? {self.channel.value}"))
    self._max: float = float(self._comm.query(f"DRV:LIM:MAX? {self.channel.value}"))
    self._unit: str = self._comm.query(f"DRV:UNIT? {self.channel.value}").strip()
Attributes
channel: HeaterChannel abstractmethod property

Get the heater channel identifier.

Must be implemented by subclasses to specify which heater channel this component controls.

Returns:

value: float property writable

Get the current heater drive value.

Returns:

  • float

    The current heater drive value.

temp: float property

Returns the temperature measured by the sensor on the heater driver.

Notes

This temperature is the same regardless of instance the method is called on. There is only one sensor for all drivers.

Functions
get_value() -> float

Alias for the value property getter.

Returns:

  • float

    The current heater drive value.

Source code in src/pychilaslasers/laser_components/heaters/heaters.py
117
118
119
120
121
122
123
124
def get_value(self) -> float:
    """Alias for the `value` property getter.

    Returns:
        The current heater drive value.

    """
    return self.value
set_value(value: float) -> None

Alias for the value property setter.

Parameters:

  • value (float) –

    The heater drive value to set.

Raises:

  • ValueError

    If value is not a number or outside valid range.

Source code in src/pychilaslasers/laser_components/heaters/heaters.py
126
127
128
129
130
131
132
133
134
135
136
def set_value(self, value: float) -> None:
    """Alias for the `value` property setter.

    Args:
        value: The heater drive value to set.

    Raises:
        ValueError: If value is not a number or outside valid range.

    """
    self.value = value

LargeRing(laser: Laser)

Bases: Heater


              flowchart TD
              pychilaslasers.laser_components.LargeRing[LargeRing]
              pychilaslasers.laser_components.heaters.heaters.Heater[Heater]
              pychilaslasers.laser_components.driver.Driver[Driver]
              pychilaslasers.laser_components.laser_component.LaserComponent[LaserComponent]

                              pychilaslasers.laser_components.heaters.heaters.Heater --> pychilaslasers.laser_components.LargeRing
                                pychilaslasers.laser_components.driver.Driver --> pychilaslasers.laser_components.heaters.heaters.Heater
                                pychilaslasers.laser_components.laser_component.LaserComponent --> pychilaslasers.laser_components.driver.Driver
                




              click pychilaslasers.laser_components.LargeRing href "" "pychilaslasers.laser_components.LargeRing"
              click pychilaslasers.laser_components.heaters.heaters.Heater href "" "pychilaslasers.laser_components.heaters.heaters.Heater"
              click pychilaslasers.laser_components.driver.Driver href "" "pychilaslasers.laser_components.driver.Driver"
              click pychilaslasers.laser_components.laser_component.LaserComponent href "" "pychilaslasers.laser_components.laser_component.LaserComponent"
            

Large ring heater component.

Source code in src/pychilaslasers/laser_components/heaters/heaters.py
41
42
43
44
45
46
47
48
49
50
51
52
53
54
def __init__(self, laser: Laser) -> None:
    """Initialize the heater component.

    Sets up the heater with its operating limits and units by
    querying the laser hardware.

    Args:
        laser: The laser instance to control.

    """
    super().__init__(laser)
    self._min: float = float(self._comm.query(f"DRV:LIM:MIN? {self.channel.value}"))
    self._max: float = float(self._comm.query(f"DRV:LIM:MAX? {self.channel.value}"))
    self._unit: str = self._comm.query(f"DRV:UNIT? {self.channel.value}").strip()
Attributes
channel: HeaterChannel property

Get the large ring channel.

PhaseSection(laser: Laser)

Bases: Heater


              flowchart TD
              pychilaslasers.laser_components.PhaseSection[PhaseSection]
              pychilaslasers.laser_components.heaters.heaters.Heater[Heater]
              pychilaslasers.laser_components.driver.Driver[Driver]
              pychilaslasers.laser_components.laser_component.LaserComponent[LaserComponent]

                              pychilaslasers.laser_components.heaters.heaters.Heater --> pychilaslasers.laser_components.PhaseSection
                                pychilaslasers.laser_components.driver.Driver --> pychilaslasers.laser_components.heaters.heaters.Heater
                                pychilaslasers.laser_components.laser_component.LaserComponent --> pychilaslasers.laser_components.driver.Driver
                




              click pychilaslasers.laser_components.PhaseSection href "" "pychilaslasers.laser_components.PhaseSection"
              click pychilaslasers.laser_components.heaters.heaters.Heater href "" "pychilaslasers.laser_components.heaters.heaters.Heater"
              click pychilaslasers.laser_components.driver.Driver href "" "pychilaslasers.laser_components.driver.Driver"
              click pychilaslasers.laser_components.laser_component.LaserComponent href "" "pychilaslasers.laser_components.laser_component.LaserComponent"
            

Phase section heater component.

Source code in src/pychilaslasers/laser_components/heaters/phase_section.py
41
42
43
44
45
46
47
48
49
50
def __init__(self, laser: Laser) -> None:
    """Initialize the phase section heater component."""
    super().__init__(laser)

    self._anti_hyst_enabled = True

    self._volts: None | list[float] = None
    self._time_steps: None | list[float] = None

    self._anti_hyst = self.get_antihyst_method(laser=laser)
Attributes
anti_hyst: bool property writable

Get the anti-hysteresis flag.

channel: HeaterChannel property

Get the phase section channel.

value: float property writable

Get the current phase section heater drive value.

Returns:

  • float

    The current heater drive value.

Functions
calibrate(laser: Laser, calibration: Calibration) -> None

Calibrate the phase section heater with the given laser and calibration.

Parameters:

  • laser (Laser) –

    The laser instance to use for calibration.

  • calibration (Calibration) –

    The calibration object containing calibration data.

Source code in src/pychilaslasers/laser_components/heaters/phase_section.py
67
68
69
70
71
72
73
74
75
76
77
78
def calibrate(self, laser: Laser, calibration: Calibration) -> None:
    """Calibrate the phase section heater with the given laser and calibration.

    Args:
        laser: The laser instance to use for calibration.
        calibration: The calibration object containing calibration data.
    """
    self._anti_hyst = self.get_antihyst_method(
        laser=laser,
        voltage_steps=calibration.tune_settings.anti_hyst_voltages,
        time_steps=calibration.tune_settings.anti_hyst_times,
    )
get_antihyst_method(laser: Laser, voltage_steps: list[float] | None = None, time_steps: list[float] | None = None) -> Callable[[float | None], None] staticmethod

Construct an anti-hysteresis correction function for the laser.

This method takes a laser object and returns an appropriate anti-hyst func that can be used independently.

Parameters:

  • laser (Laser) –

    The laser instance to apply anti-hysteresis correction to.

  • voltage_steps (list[float] | None, default: None ) –

    Optional list of voltage step values for the anti-hysteresis procedure. Defaults will be used if None provided.

  • time_steps (list[float] | None, default: None ) –

    Optional list of time step durations (in ms) for each voltage step. Defaults will be used if None provided.

Returns:

  • Callable[[float | None], None]

    A callable that applies anti-hysteresis correction when invoked with an optional phase voltage.

Source code in src/pychilaslasers/laser_components/heaters/phase_section.py
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
@staticmethod
def get_antihyst_method(
    laser: Laser,
    voltage_steps: list[float] | None = None,
    time_steps: list[float] | None = None,
) -> Callable[[float | None], None]:
    """Construct an anti-hysteresis correction function for the laser.

    This method takes a laser object and returns an appropriate anti-hyst func
    that can be used independently.

    Args:
        laser: The laser instance to apply anti-hysteresis correction to.
        voltage_steps: Optional list of voltage step values for the
            anti-hysteresis procedure. Defaults will be used if None provided.
        time_steps: Optional list of time step durations (in ms) for
            each voltage step. Defaults will be used if None provided.

    Returns:
        A callable that applies anti-hysteresis correction when invoked with
          an optional phase voltage.
    """
    query: Callable[[str], str] = laser.comm.query

    phase_min: float
    phase_max: float

    try:
        phase_max = laser._manual_mode.phase_section.max_value
        phase_min = laser._manual_mode.phase_section.min_value
    except AttributeError as e:
        if laser.system_state:
            phase_max = float(
                laser.comm.query(f"DRV:LIM:MAX? {PhaseSection.channel}")
            )
            phase_min = float(
                laser.comm.query(f"DRV:LIM:MIN? {PhaseSection.channel}")
            )
        else:
            raise ModeError(
                "Phase section min-max values could not be obtained", laser.mode
            ) from e

    voltage_steps = (
        Defaults.TUNE_ANTI_HYST[0] if voltage_steps is None else voltage_steps
    )
    time_steps = Defaults.TUNE_ANTI_HYST[0] if time_steps is None else time_steps

    time_steps = (
        [time_steps[0]] * (len(voltage_steps) - 1) + [0]
        if len(time_steps) == 1
        else [*time_steps, 0]
    )

    def antihyst(v_phase: float | None = None) -> None:
        """Apply anti-hysteresis correction to the laser.

        Applies a voltage ramping procedure to the phase section heater to
        minimize hysteresis effects during wavelength changes. The specifics of
        this method are laser-dependent and are specified as part of the calibration
        data.
        """
        if v_phase is None:
            v_phase = float(query(f"DRV:D? {HeaterChannel.PHASE_SECTION.value:d}"))

        for i, voltage_step in enumerate(voltage_steps):
            if v_phase**2 + voltage_step < 0:
                value: float = 0
                logging.getLogger(__name__).warning(
                    "Anti-hysteresis "
                    f"value out of bounds: {value} (min: {phase_min}, max: "
                    f"{phase_max}). Approximating by 0"
                )
            else:
                value = sqrt(v_phase**2 + voltage_step)
            if value < phase_min or value > phase_max:
                logging.getLogger(__name__).error(
                    "Anti-hysteresis"
                    f"value out of bounds: {value} (min: {phase_min}, max: "
                    f"{phase_max}). Approximating with the closest limit."
                )
                value = min(value, phase_max)
                value = max(value, phase_min)
            query(f"DRV:D {HeaterChannel.PHASE_SECTION.value:d} {value:.4f}")
            sleep(time_steps[i] / 1000)

    return antihyst

SmallRing(laser: Laser)

Bases: Heater


              flowchart TD
              pychilaslasers.laser_components.SmallRing[SmallRing]
              pychilaslasers.laser_components.heaters.heaters.Heater[Heater]
              pychilaslasers.laser_components.driver.Driver[Driver]
              pychilaslasers.laser_components.laser_component.LaserComponent[LaserComponent]

                              pychilaslasers.laser_components.heaters.heaters.Heater --> pychilaslasers.laser_components.SmallRing
                                pychilaslasers.laser_components.driver.Driver --> pychilaslasers.laser_components.heaters.heaters.Heater
                                pychilaslasers.laser_components.laser_component.LaserComponent --> pychilaslasers.laser_components.driver.Driver
                




              click pychilaslasers.laser_components.SmallRing href "" "pychilaslasers.laser_components.SmallRing"
              click pychilaslasers.laser_components.heaters.heaters.Heater href "" "pychilaslasers.laser_components.heaters.heaters.Heater"
              click pychilaslasers.laser_components.driver.Driver href "" "pychilaslasers.laser_components.driver.Driver"
              click pychilaslasers.laser_components.laser_component.LaserComponent href "" "pychilaslasers.laser_components.laser_component.LaserComponent"
            

Small ring heater component.

Source code in src/pychilaslasers/laser_components/heaters/heaters.py
41
42
43
44
45
46
47
48
49
50
51
52
53
54
def __init__(self, laser: Laser) -> None:
    """Initialize the heater component.

    Sets up the heater with its operating limits and units by
    querying the laser hardware.

    Args:
        laser: The laser instance to control.

    """
    super().__init__(laser)
    self._min: float = float(self._comm.query(f"DRV:LIM:MIN? {self.channel.value}"))
    self._max: float = float(self._comm.query(f"DRV:LIM:MAX? {self.channel.value}"))
    self._unit: str = self._comm.query(f"DRV:UNIT? {self.channel.value}").strip()
Attributes
channel: HeaterChannel property

Get the small ring channel.

TunableCoupler(laser: Laser)

Bases: Heater


              flowchart TD
              pychilaslasers.laser_components.TunableCoupler[TunableCoupler]
              pychilaslasers.laser_components.heaters.heaters.Heater[Heater]
              pychilaslasers.laser_components.driver.Driver[Driver]
              pychilaslasers.laser_components.laser_component.LaserComponent[LaserComponent]

                              pychilaslasers.laser_components.heaters.heaters.Heater --> pychilaslasers.laser_components.TunableCoupler
                                pychilaslasers.laser_components.driver.Driver --> pychilaslasers.laser_components.heaters.heaters.Heater
                                pychilaslasers.laser_components.laser_component.LaserComponent --> pychilaslasers.laser_components.driver.Driver
                




              click pychilaslasers.laser_components.TunableCoupler href "" "pychilaslasers.laser_components.TunableCoupler"
              click pychilaslasers.laser_components.heaters.heaters.Heater href "" "pychilaslasers.laser_components.heaters.heaters.Heater"
              click pychilaslasers.laser_components.driver.Driver href "" "pychilaslasers.laser_components.driver.Driver"
              click pychilaslasers.laser_components.laser_component.LaserComponent href "" "pychilaslasers.laser_components.laser_component.LaserComponent"
            

Tunable coupler heater component.

Source code in src/pychilaslasers/laser_components/heaters/heaters.py
41
42
43
44
45
46
47
48
49
50
51
52
53
54
def __init__(self, laser: Laser) -> None:
    """Initialize the heater component.

    Sets up the heater with its operating limits and units by
    querying the laser hardware.

    Args:
        laser: The laser instance to control.

    """
    super().__init__(laser)
    self._min: float = float(self._comm.query(f"DRV:LIM:MIN? {self.channel.value}"))
    self._max: float = float(self._comm.query(f"DRV:LIM:MAX? {self.channel.value}"))
    self._unit: str = self._comm.query(f"DRV:UNIT? {self.channel.value}").strip()
Attributes
channel: HeaterChannel property

Get the tunable coupler channel.