Skip to content

Modes

pychilaslasers.modes

PyChilasLasers Modes Module.

Laser modes provide an encapsulation for operations that require common settings and/or cannot be performed together.It includes manual mode for direct control and calibrated modes for steady-state and sweeping operations. The module also defines wavelength change methods and manages the calibration data for different laser models.

Classes:

  • LaserMode

    Enum defining available laser modes

  • Mode

    Abstract base class for all modes

  • ManualMode

    Direct manual control of laser parameters

  • SteadyMode

    Calibrated steady-state wavelength operation

  • SweepMode

    Calibrated sweeping operations

  • _WLChangeMethod

    Abstract base for wavelength change methods

  • _PreLoad

    Preload-based wavelength change method

  • _CyclerIndex

    Cycler index-based wavelength change method

Classes

ManualMode

Bases: Mode

Manual laser control mode for direct heater manipulation.

ManualMode provides unrestricted access to all laser heater channels, allowing users to manually set voltages without calibration constraints. This mode is primarily intended for advanced users, testing, and debugging purposes where precise control over individual components is required at the expense of calibration.

The mode initializes all heater components and provides both individual heater access and a unified interface for driver value setting.

Parameters:

  • laser (Laser) –

    The laser instance to control.

Attributes:

Source code in src/pychilaslasers/modes/manual_mode.py
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
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
class ManualMode(Mode):
    """Manual laser control mode for direct heater manipulation.

    ManualMode provides unrestricted access to all laser heater channels,
    allowing users to manually set voltages without calibration constraints.
    This mode is primarily intended for advanced users, testing, and debugging
    purposes where precise control over individual components is required at the
    expense of calibration.

    The mode initializes all heater components and provides both individual
    heater access and a unified interface for driver value setting.

    Args:
        laser: The laser instance to control.

    Attributes:
        heaters: List of all available heater components.
        phase_section: Phase section heater component.
        large_ring: Large ring heater component.
        small_ring: Small ring heater component.
        tunable_coupler: Tunable coupler heater component.

    """

    def __init__(self, laser: Laser) -> None:
        """Initialize manual mode with laser instance and heater components.

        Creates all heater component instances. The laser is temporarily turned on
        during initialization to gather component characteristics.

        Args:
            laser: The laser instance to control.

        """
        super().__init__(laser)
        self._laser.turn_on()  # Ensure the laser is on after initializing heaters
        self._phase_section: PhaseSection = PhaseSection(laser)
        self._large_ring: LargeRing = LargeRing(laser)
        self._small_ring: SmallRing = SmallRing(laser)
        self._tunable_coupler: TunableCoupler = TunableCoupler(laser)
        self._laser.turn_off()  # Ensure the laser is off after initializing heaters

        self._heaters: list[Heater] = [
            self._phase_section,
            self._large_ring,
            self._small_ring,
            self._tunable_coupler,
        ]

    ########## Main Methods ##########

    def apply_defaults(self) -> None:
        """Apply default settings for manual mode operation."""
        pass

    def set_driver_value(
        self, heater_ch: int | HeaterChannel, heater_value: float
    ) -> None:
        """Manually set the voltage value of a specific driver channel.

        Provides direct low-level access to set heater voltages without
        any validation or safety checks. This method bypasses all calibration
        constraints and allows unrestricted heater control.

        Args:
            heater_ch: The heater channel number or HeaterChannel enum.
                Valid channels are typically 0-3 for the four main heaters.
            heater_value: The voltage value to set in volts.
                Range depends on laser specifications and hardware limits.

        Warning:
            This method performs no validation on the input values.
            Setting inappropriate voltages may result in errors or undefined behavior.

        """
        self._comm.query(f"DRV:D {heater_ch:d} {heater_value:.4f}")

    ########## Properties (Getters/Setters) ##########

    @property
    def mode(self) -> LaserMode:
        """Get the laser operation mode."""
        return LaserMode.MANUAL

    @property
    def phase_section(self) -> PhaseSection:
        """Get the phase section heater."""
        return self._phase_section

    @phase_section.setter
    def phase_section(self, value: float) -> None:
        """Set the phase section heater value.

        Args:
            value: The heater drive value to set.

        """
        self._phase_section.value = value

    @property
    def large_ring(self) -> LargeRing:
        """Get the large ring heater."""
        return self._large_ring

    @large_ring.setter
    def large_ring(self, value: float) -> None:
        """Set the large ring heater value.

        Args:
            value: The heater drive value to set.

        """
        self._large_ring.value = value

    @property
    def small_ring(self) -> SmallRing:
        """Get the small ring heater."""
        return self._small_ring

    @small_ring.setter
    def small_ring(self, value: float) -> None:
        """Set the small ring heater value.

        Args:
            value: The heater drive value to set.

        """
        self._small_ring.value = value

    @property
    def tunable_coupler(self) -> TunableCoupler:
        """Get the tunable coupler."""
        return self._tunable_coupler

    @tunable_coupler.setter
    def tunable_coupler(self, value: float) -> None:
        """Set the tunable coupler heater value.

        Args:
            value: The heater drive value to set.

        """
        self._tunable_coupler.value = value

    ########## Method Overloads/Aliases ##########

    @property
    def heaters(self) -> list[Heater]:
        """Get all heater components as a convenient list.

        Alias that provides all individual heater components in a single list.

        Returns:
            List containing:
                0. phase_section
                1. large_ring
                2. small_ring
                3. tunable_coupler
                In this order for easy iteration and access.

        """
        return self._heaters
Attributes
mode: LaserMode property

Get the laser operation mode.

phase_section: PhaseSection property writable

Get the phase section heater.

large_ring: LargeRing property writable

Get the large ring heater.

small_ring: SmallRing property writable

Get the small ring heater.

tunable_coupler: TunableCoupler property writable

Get the tunable coupler.

heaters: list[Heater] property

Get all heater components as a convenient list.

Alias that provides all individual heater components in a single list.

Returns:

  • list[Heater]

    List containing: 0. phase_section 1. large_ring 2. small_ring 3. tunable_coupler In this order for easy iteration and access.

Functions
__init__(laser: Laser) -> None

Creates all heater component instances. The laser is temporarily turned on during initialization to gather component characteristics.

Parameters:

  • laser (Laser) –

    The laser instance to control.

Source code in src/pychilaslasers/modes/manual_mode.py
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
def __init__(self, laser: Laser) -> None:
    """Initialize manual mode with laser instance and heater components.

    Creates all heater component instances. The laser is temporarily turned on
    during initialization to gather component characteristics.

    Args:
        laser: The laser instance to control.

    """
    super().__init__(laser)
    self._laser.turn_on()  # Ensure the laser is on after initializing heaters
    self._phase_section: PhaseSection = PhaseSection(laser)
    self._large_ring: LargeRing = LargeRing(laser)
    self._small_ring: SmallRing = SmallRing(laser)
    self._tunable_coupler: TunableCoupler = TunableCoupler(laser)
    self._laser.turn_off()  # Ensure the laser is off after initializing heaters

    self._heaters: list[Heater] = [
        self._phase_section,
        self._large_ring,
        self._small_ring,
        self._tunable_coupler,
    ]
apply_defaults() -> None

Apply default settings for manual mode operation.

Source code in src/pychilaslasers/modes/manual_mode.py
84
85
86
def apply_defaults(self) -> None:
    """Apply default settings for manual mode operation."""
    pass
set_driver_value(heater_ch: int | HeaterChannel, heater_value: float) -> None

Manually set the voltage value of a specific driver channel.

Provides direct low-level access to set heater voltages without any validation or safety checks. This method bypasses all calibration constraints and allows unrestricted heater control.

Parameters:

  • heater_ch (int | HeaterChannel) –

    The heater channel number or HeaterChannel enum. Valid channels are typically 0-3 for the four main heaters.

  • heater_value (float) –

    The voltage value to set in volts. Range depends on laser specifications and hardware limits.

Warning

This method performs no validation on the input values. Setting inappropriate voltages may result in errors or undefined behavior.

Source code in src/pychilaslasers/modes/manual_mode.py
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
def set_driver_value(
    self, heater_ch: int | HeaterChannel, heater_value: float
) -> None:
    """Manually set the voltage value of a specific driver channel.

    Provides direct low-level access to set heater voltages without
    any validation or safety checks. This method bypasses all calibration
    constraints and allows unrestricted heater control.

    Args:
        heater_ch: The heater channel number or HeaterChannel enum.
            Valid channels are typically 0-3 for the four main heaters.
        heater_value: The voltage value to set in volts.
            Range depends on laser specifications and hardware limits.

    Warning:
        This method performs no validation on the input values.
        Setting inappropriate voltages may result in errors or undefined behavior.

    """
    self._comm.query(f"DRV:D {heater_ch:d} {heater_value:.4f}")

LaserMode

Bases: Enum

Enumeration of laser modes.

Provides an alternative way of referencing modes without using string literals, classes, or instances. This enumeration ensures type safety and consistency throughout the library.

Attributes:

  • MANUAL

    Manual mode for direct component control.

  • SWEEP

    Sweep mode for wavelength scanning (COMET lasers only).

  • STEADY

    Steady mode for precise wavelength control using calibration data.

Source code in src/pychilaslasers/modes/mode.py
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
class LaserMode(Enum):
    """Enumeration of laser modes.

    Provides an alternative way of referencing modes without using string literals,
    classes, or instances. This enumeration ensures type safety and consistency
    throughout the library.

    Attributes:
        MANUAL: Manual mode for direct component control.
        SWEEP: Sweep mode for wavelength scanning (COMET lasers only).
        STEADY: Steady mode for precise wavelength control using calibration data.

    """

    MANUAL = "Manual"
    SWEEP = "Sweep"
    STEADY = "Steady"

Mode

Bases: ABC

Abstract base class for laser modes.

This class defines the basic structure and properties that all laser modes should implement. It provides a common interface for interacting with different laser modes, such as manual, sweep, and steady modes.

A laser mode is an abstract operational state of the laser that adds functionality and defines how it behaves, the operations available, and the settings required for its operation.

Source code in src/pychilaslasers/modes/mode.py
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
class Mode(ABC):
    """Abstract base class for laser modes.

    This class defines the basic structure and properties that all laser modes
    should implement. It provides a common interface for interacting with different
    laser modes, such as manual, sweep, and steady modes.

    A laser mode is an abstract operational state of the laser that adds functionality
    and defines how it behaves, the operations available, and the settings required
    for its operation.
    """

    def __init__(self, laser: Laser) -> None:
        """Initialize the mode with a reference to the parent laser.

        Args:
            laser: The laser instance that owns this mode.

        """
        super().__init__()
        self._laser: Laser = laser
        self._comm: Communication = laser._comm

    ########## Abstract Methods ##########

    @abstractmethod
    def apply_defaults(self) -> None:
        """Apply default settings for the mode.

        This method is called when the laser switches to this mode and should
        configure all mode-specific parameters to their default values.
        """
        pass

    @property
    @abstractmethod
    def mode(self) -> LaserMode:
        """Return the enumeration value identifying this mode type.

        Returns:
            The enumeration value identifying this mode type.

        """
        pass
Attributes
mode: LaserMode abstractmethod property

Return the enumeration value identifying this mode type.

Returns:

  • LaserMode

    The enumeration value identifying this mode type.

Functions
__init__(laser: Laser) -> None

Parameters:

  • laser (Laser) –

    The laser instance that owns this mode.

Source code in src/pychilaslasers/modes/mode.py
55
56
57
58
59
60
61
62
63
64
def __init__(self, laser: Laser) -> None:
    """Initialize the mode with a reference to the parent laser.

    Args:
        laser: The laser instance that owns this mode.

    """
    super().__init__()
    self._laser: Laser = laser
    self._comm: Communication = laser._comm
apply_defaults() -> None abstractmethod

Apply default settings for the mode.

This method is called when the laser switches to this mode and should configure all mode-specific parameters to their default values.

Source code in src/pychilaslasers/modes/mode.py
68
69
70
71
72
73
74
75
@abstractmethod
def apply_defaults(self) -> None:
    """Apply default settings for the mode.

    This method is called when the laser switches to this mode and should
    configure all mode-specific parameters to their default values.
    """
    pass

SteadyMode

Bases: __Calibrated

Steady operation mode of the laser.

SteadyMode allows for tuning to specific wavelengths

The mode supports anti-hysteresis correction to improve wavelength stability and provides convenient methods for wavelength setting and control.

Parameters:

  • laser (Laser) –

    The laser instance to control.

  • calibration (dict) –

    Calibration data dictionary containing steady mode parameters. as returned by the utils.read_calibration_file method

Attributes:

  • wavelength (float) –

    Current wavelength setting in nanometers.

  • antihyst (bool) –

    Anti-hysteresis correction enable/disable state.

  • mode (LaserMode) –

    Returns LaserMode.STEADY.

Source code in src/pychilaslasers/modes/steady_mode.py
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
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
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
class SteadyMode(__Calibrated):
    """Steady operation mode of the laser.

    SteadyMode allows for tuning to specific wavelengths

    The mode supports anti-hysteresis correction to improve wavelength stability
    and provides convenient methods for wavelength setting and control.

    Args:
        laser: The laser instance to control.
        calibration: Calibration data dictionary containing steady mode parameters.
                as returned by the `utils.read_calibration_file` method

    Attributes:
        wavelength: Current wavelength setting in nanometers.
        antihyst: Anti-hysteresis correction enable/disable state.
        mode: Returns LaserMode.STEADY.

    """

    def __init__(self, laser: Laser, calibration: dict) -> None:
        """Initialize steady mode with laser and calibration data.

        Args:
            laser: The laser instance to control.
            calibration: Calibration data dictionary containing steady mode parameters.

        """
        super().__init__(laser)

        self._calibration = calibration["steady"]["calibration"]
        self._default_TEC = calibration["steady"]["tec_temp"]
        self._default_current = calibration["steady"]["current"]

        self._min_wl: float = min(self._calibration.keys())
        self._max_wl: float = max(self._calibration.keys())
        _wavelengths: list[float] = sorted(list(self._calibration.keys()))
        self._step_size: float = abs(
            _wavelengths[0] - _wavelengths[_wavelengths.count(_wavelengths[0])]
        )

        self._wl: float = self._min_wl  # Default to minimum wavelength

        # Initialize wavelength change method based on laser model
        antihyst_parameters = calibration["steady"]["anti-hyst"]
        if calibration["model"] == "COMET":
            self._change_method: _WLChangeMethod = _PreLoad(
                steady_mode=self,
                laser=laser,
                calibration_table=self._calibration,
                anti_hyst_parameters=antihyst_parameters,
            )
        else:
            # Default to cycler index method for ATLAS
            self._change_method = _CyclerIndex(
                steady_mode=self,
                laser=laser,
                calibration_table=self._calibration,
                anti_hyst_parameters=antihyst_parameters,
            )

    ########## Main Methods ##########

    def apply_defaults(self) -> None:
        """Apply default settings for steady mode operation.

        Sets the TEC temperature and diode current to their default values
        as specified in the calibration data.
        """
        self._laser.tec.target = self._default_TEC
        self._laser.diode.current = self._default_current

    ########## Properties (Getters/Setters) ##########

    @property
    def wavelength(self) -> float:
        """Get the current wavelength setting.

        Returns:
            Current wavelength in nanometers.

        """
        return self._wl

    @wavelength.setter
    def wavelength(self, wavelength: float) -> float:
        """Set the laser wavelength.

        Args:
            wavelength: Target wavelength in nanometers.
                If the wavelength is not in the calibration table, it will find the
                closest available wavelength and use that instead.

        Returns:
            The actual wavelength that was set.

        Raises:
            ValueError: If wavelength is outside the valid calibration range.

        """
        if wavelength < self._min_wl or wavelength > self._max_wl:
            raise ValueError(
                f"Wavelength value {wavelength} not valid: must be between "
                f"{self._min_wl} and {self._max_wl}."
            )
        if wavelength not in self._calibration.keys():
            # Find the closest available wavelength to the requested wavelength
            wavelength = min(
                self._calibration.keys(), key=lambda x: abs(x - wavelength)
            )

        self._change_method.set_wl(wavelength)
        self._wl = wavelength

        # Trigger pulse if auto-trigger is enabled (inherited from parent)
        if self._autoTrig:
            self._laser.trigger_pulse()

        return self._wl

    @property
    def antihyst(self) -> bool:
        """Get the anti-hysteresis correction state.

        Returns:
            True if anti-hysteresis correction is enabled, False otherwise.

        """
        return self._change_method.anti_hyst_enabled

    @antihyst.setter
    def antihyst(self, state: bool) -> None:
        """Set the anti-hysteresis correction state.

        Args:
            state: Enable (True) or disable (False) anti-hysteresis correction.

        """
        self._change_method.anti_hyst_enabled = state

    @property
    def mode(self) -> LaserMode:
        """Get the laser operation mode.

        Returns:
            LaserMode.STEADY indicating steady mode operation.

        """
        return LaserMode.STEADY

    @property
    def step_size(self) -> float:
        """Get the step size between consecutive wavelengths.

        Returns:
            The step size in nanometers between consecutive wavelengths.

        """
        return self._step_size

    ########## Method Overloads/Aliases ##########

    def get_wl(self) -> float:
        """Get the current wavelength setting.

        Alias for the wavelength property getter.

        Returns:
            Current wavelength in nanometers.

        """
        return self.wavelength

    def set_wl_relative(self, delta: float) -> float:
        """Set wavelength relative to current position.

        Args:
            delta: Wavelength change in nanometers, relative to current wavelength.
                Positive deltas increase wavelength, negative deltas decrease it.

        Returns:
            The new absolute wavelength that was set.

        Raises:
            ValueError: If the resulting wavelength is outside the valid range.

        """
        self.wavelength = self.get_wl() + delta

        return self.wavelength

    def toggle_antihyst(self, state: bool | None = None) -> None:
        """Toggle the anti-hysteresis correction state.

        Args:
            state: Optional explicit state to set. If None, toggles current state.
                True enables anti-hysteresis, False disables it.

        """
        if state is None:
            # Toggle the current state
            self._change_method.anti_hyst_enabled = (
                not self._change_method.anti_hyst_enabled
            )
        else:
            self._change_method.anti_hyst_enabled = state
Attributes
wavelength: float property writable

Get the current wavelength setting.

Returns:

  • float

    Current wavelength in nanometers.

antihyst: bool property writable

Get the anti-hysteresis correction state.

Returns:

  • bool

    True if anti-hysteresis correction is enabled, False otherwise.

mode: LaserMode property

Get the laser operation mode.

Returns:

  • LaserMode

    LaserMode.STEADY indicating steady mode operation.

step_size: float property

Get the step size between consecutive wavelengths.

Returns:

  • float

    The step size in nanometers between consecutive wavelengths.

Functions
__init__(laser: Laser, calibration: dict) -> None

Parameters:

  • laser (Laser) –

    The laser instance to control.

  • calibration (dict) –

    Calibration data dictionary containing steady mode parameters.

Source code in src/pychilaslasers/modes/steady_mode.py
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
def __init__(self, laser: Laser, calibration: dict) -> None:
    """Initialize steady mode with laser and calibration data.

    Args:
        laser: The laser instance to control.
        calibration: Calibration data dictionary containing steady mode parameters.

    """
    super().__init__(laser)

    self._calibration = calibration["steady"]["calibration"]
    self._default_TEC = calibration["steady"]["tec_temp"]
    self._default_current = calibration["steady"]["current"]

    self._min_wl: float = min(self._calibration.keys())
    self._max_wl: float = max(self._calibration.keys())
    _wavelengths: list[float] = sorted(list(self._calibration.keys()))
    self._step_size: float = abs(
        _wavelengths[0] - _wavelengths[_wavelengths.count(_wavelengths[0])]
    )

    self._wl: float = self._min_wl  # Default to minimum wavelength

    # Initialize wavelength change method based on laser model
    antihyst_parameters = calibration["steady"]["anti-hyst"]
    if calibration["model"] == "COMET":
        self._change_method: _WLChangeMethod = _PreLoad(
            steady_mode=self,
            laser=laser,
            calibration_table=self._calibration,
            anti_hyst_parameters=antihyst_parameters,
        )
    else:
        # Default to cycler index method for ATLAS
        self._change_method = _CyclerIndex(
            steady_mode=self,
            laser=laser,
            calibration_table=self._calibration,
            anti_hyst_parameters=antihyst_parameters,
        )
apply_defaults() -> None

Apply default settings for steady mode operation.

Sets the TEC temperature and diode current to their default values as specified in the calibration data.

Source code in src/pychilaslasers/modes/steady_mode.py
 94
 95
 96
 97
 98
 99
100
101
def apply_defaults(self) -> None:
    """Apply default settings for steady mode operation.

    Sets the TEC temperature and diode current to their default values
    as specified in the calibration data.
    """
    self._laser.tec.target = self._default_TEC
    self._laser.diode.current = self._default_current
get_wl() -> float

Get the current wavelength setting.

Alias for the wavelength property getter.

Returns:

  • float

    Current wavelength in nanometers.

Source code in src/pychilaslasers/modes/steady_mode.py
193
194
195
196
197
198
199
200
201
202
def get_wl(self) -> float:
    """Get the current wavelength setting.

    Alias for the wavelength property getter.

    Returns:
        Current wavelength in nanometers.

    """
    return self.wavelength
set_wl_relative(delta: float) -> float

Set wavelength relative to current position.

Parameters:

  • delta (float) –

    Wavelength change in nanometers, relative to current wavelength. Positive deltas increase wavelength, negative deltas decrease it.

Returns:

  • float

    The new absolute wavelength that was set.

Raises:

  • ValueError

    If the resulting wavelength is outside the valid range.

Source code in src/pychilaslasers/modes/steady_mode.py
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
def set_wl_relative(self, delta: float) -> float:
    """Set wavelength relative to current position.

    Args:
        delta: Wavelength change in nanometers, relative to current wavelength.
            Positive deltas increase wavelength, negative deltas decrease it.

    Returns:
        The new absolute wavelength that was set.

    Raises:
        ValueError: If the resulting wavelength is outside the valid range.

    """
    self.wavelength = self.get_wl() + delta

    return self.wavelength
toggle_antihyst(state: bool | None = None) -> None

Toggle the anti-hysteresis correction state.

Parameters:

  • state (bool | None, default: None ) –

    Optional explicit state to set. If None, toggles current state. True enables anti-hysteresis, False disables it.

Source code in src/pychilaslasers/modes/steady_mode.py
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
def toggle_antihyst(self, state: bool | None = None) -> None:
    """Toggle the anti-hysteresis correction state.

    Args:
        state: Optional explicit state to set. If None, toggles current state.
            True enables anti-hysteresis, False disables it.

    """
    if state is None:
        # Toggle the current state
        self._change_method.anti_hyst_enabled = (
            not self._change_method.anti_hyst_enabled
        )
    else:
        self._change_method.anti_hyst_enabled = state

SweepMode

Bases: __Calibrated

Manages laser wavelength sweep operations.

SweepMode allows the laser to continuously cycle through a range of wavelengths with custom range, intervals, and repetition settings.

Warning

The sweep operates from high wavelengths to low wavelengths. This means the start wavelength should be the maximum (highest) wavelength and the end wavelength should be the minimum (lowest) wavelength in your desired range.

Parameters:

  • laser (Laser) –

    The laser instance to control.

  • calibration (dict) –

    Calibration data dictionary containing sweep mode parameters as returned by the utils.read_calibration_file method.

Attributes:

  • wavelength (float) –

    Current wavelength setting.

  • start_wavelength (float) –

    of the sweep range in nanometers.

  • end_wavelength (float) –

    of the sweep range in nanometers.

  • interval (int) –

    Time interval between wavelength steps in microseconds.

  • number_sweeps (int) –

    Number of sweep cycles to perform (0 for infinite).

  • mode (LaserMode) –

    Returns LaserMode.SWEEP.

Raises:

  • ValueError

    If laser model is not compatible with sweep mode.

Source code in src/pychilaslasers/modes/sweep_mode.py
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
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
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
class SweepMode(__Calibrated):
    """Manages laser wavelength sweep operations.

    SweepMode allows the laser to continuously cycle through a range of wavelengths
    with custom range, intervals, and repetition settings.

    Warning:
        The sweep operates from high wavelengths to low wavelengths.
        This means the start wavelength should be the maximum (highest) wavelength
        and the end wavelength should be the minimum (lowest) wavelength in your
        desired range.

    Args:
        laser: The laser instance to control.
        calibration: Calibration data dictionary containing sweep mode parameters
            as returned by the `utils.read_calibration_file` method.

    Attributes:
        wavelength: Current wavelength setting.
        start_wavelength: of the sweep range in nanometers.
        end_wavelength: of the sweep range in nanometers.
        interval: Time interval between wavelength steps in microseconds.
        number_sweeps: Number of sweep cycles to perform (0 for infinite).
        mode: Returns LaserMode.SWEEP.

    Raises:
        ValueError: If laser model is not compatible with sweep mode.

    """

    def __init__(self, laser: Laser, calibration: dict) -> None:
        """Initialize sweep mode with laser instance and calibration data.

        Args:
            laser: The laser instance to control.
            calibration: Calibration data dictionary containing sweep mode parameters.
                This should be the full calibration dictionary as returned by
                `utils.read_calibration_file`.

        Raises:
            ValueError: If laser model is not COMET or calibration is invalid.

        """
        super().__init__(laser)
        if (
            laser.model != "COMET"
            or calibration.get("model") != "COMET"
            or "sweep" not in calibration
        ):
            raise ModeError(
                "Sweep mode is only supported for COMET lasers.",
                current_mode=laser.mode,
            )

        # Gather calibration data
        self._calibration = calibration["sweep"]
        self._default_TEC: float = calibration["sweep"]["tec_temp"]
        self._default_current: float = calibration["sweep"]["current"]
        self._default_interval: int = calibration["sweep"]["interval"]
        self._wavelengths: list[float] = calibration["sweep"]["wavelengths"]

        self._min_wl: float = min(self._wavelengths)
        self._max_wl: float = max(self._wavelengths)
        self._step_size: float = abs(
            self._wavelengths[0]
            - self._wavelengths[self._wavelengths.count(self._wavelengths[0])]
        )

        self._no_sweeps: int = 0  # Default to infinite sweeps

    ########## Main Methods ##########

    def apply_defaults(self) -> None:
        """Apply default settings for sweep mode operation.

        Sets the laser to the default TEC temperature, diode current,
        full wavelength range and interval.
        """
        self._laser.tec.target = self._default_TEC
        self._laser.diode.current = self._default_current
        try:
            self.set_range(start_wl=self._max_wl, end_wl=self._min_wl)
        except LaserError as e:
            if "cycler" not in e.message:
                logging.getLogger(__name__).error(f"Failed to set sweep range: {e}")
                raise e

        self.interval = self._default_interval

    def start(self, number_sweeps: int | None = None) -> None:
        """Start the wavelength sweep operation.

        Initiates the sweep operation with the configured number of cycles.
        The laser will begin cycling through the wavelength range according
        to the current range and interval settings.
        """
        if number_sweeps is not None:
            self.number_sweeps = number_sweeps

        self._comm.query(data=f"DRV:CYC:RUN {self.number_sweeps:d}")

    def stop(self) -> None:
        """Stop the current wavelength sweep operation.

        Immediately halts the sweep operation. The laser will remain at its
        current wavelength position. Use `resume` to continue the sweep
        from where it was stopped.
        """
        self._comm.query(data="DRV:CYC:ABRT")

    def resume(self) -> None:
        """Resume a paused wavelength sweep operation.

        Resumes a sweep operation that was previously stopped using the
        `stop` method. The sweep will continue from its current position
        with the same configuration settings.
        """
        self._comm.query(data="DRV:CYC:CONT")

    def get_total_time(self) -> float:
        """Calculate the total estimated time for the complete sweep operation.

        Returns:
            The estimated total time for the sweep in microseconds, based on the current
                interval, number of wavelength points, and number of sweep cycles.
                Returns 0.0 if number of sweeps is 0 (infinite sweeps).

        """
        return (
            self.interval * len(self.get_points()) * self.number_sweeps
            if self.number_sweeps > 0
            else 0.0
        )

    def get_points(self) -> list[float]:
        """Get all wavelength points within the current sweep range.

        Returns:
            List of wavelengths that will be swept through during operation,
                including both the lower and upper wavelengths.

        """
        lower_index: int = self._wavelengths.index(self.start_wavelength)
        upper_index: int = self._wavelengths.index(self.end_wavelength)
        upper_index += self._wavelengths.count(self.end_wavelength) - 1
        return self._wavelengths[lower_index : upper_index + 1]

    ########## Properties (Getters/Setters) ##########

    @property
    def mode(self) -> LaserMode:
        """Get the laser operation mode.

        Returns:
            LaserMode: LaserMode.SWEEP indicating this is a sweep mode instance.

        """
        return LaserMode.SWEEP

    @property
    def wavelength(self) -> float:
        """Get the current wavelength from the laser.

        Returns:
            The wavelength corresponding to the current wavelength
                in nanometers.

        Note:
            Queries the laser hardware for the current position
            and maps it to the corresponding wavelength in the calibration table.

        Warning:
            Depending on the interval, this value may have changed by the
            time it is retrieved due to the continuous sweeping operation.

        """
        current_index: int = int(self._comm.query("DRV:CYC:CPOS?"))
        return self._wavelengths[current_index]

    @property
    def interval(self) -> int:
        """Get the current interval setting.

        Returns:
            The time interval between wavelength steps in milliseconds.

        """
        return int(self._comm.query("DRV:CYC:INT?"))

    @interval.setter
    def interval(self, interval: int) -> None:
        """Set the interval between wavelength steps.

        Args:
            interval: Time interval between wavelength steps in microseconds.
                Must be a positive integer between 20 and 50 000.

        Warning:
            The interval is part of the calibration data. Changing it
            may cause the laser to behave differently than expected.

        Raises:
            ValueError: If interval is not a positive integer within the valid range.

        """
        if 20 > interval or interval > 50000 or not isinstance(interval, int):
            raise ValueError(
                f"Interval value {interval} not valid: must be a positive integer"
                "between 20 and 50 000 microseconds."
            )
        self._comm.query(data=f"DRV:CYC:INT {interval}")

    @property
    def number_sweeps(self) -> int:
        """Get the configured number of sweep cycles.

        Returns:
            The number of sweep cycles configured. 0 indicates infinite sweeps.

        """
        return self._no_sweeps

    @number_sweeps.setter
    def number_sweeps(self, number: int) -> None:
        """Set the number of sweep cycles to perform.

        Args:
            number: Number of sweep cycles to perform. Set to 0 for infinite sweeps.

        Raises:
            ValueError: If number is negative or not an integer.

        """
        if number < 0 or not isinstance(number, int):
            raise ValueError("Number of sweeps must be a non-negative integer.")
        self._no_sweeps = number

    @property
    def range(self) -> tuple[float, float]:
        """Get the current wavelength sweep range.

        Returns:
            A tuple containing (start_wavelength, end_wavelength) where
                start_wavelength is the higher value and end_wavelength is the lower
                value, reflecting the high-to-low sweep direction.

        """
        [index_start, index_end] = self._comm.query("DRV:CYC:SPAN?").split(" ")
        return (self._wavelengths[int(index_start)], self._wavelengths[int(index_end)])

    @range.setter
    def range(self, range: tuple[float, float] | list[float]) -> None:
        """Set the wavelength sweep range.

        Alias for `range`. Returns the current sweep range as configured for
        high-to-low wavelength sweeping.

        Configures the start and end wavelength limits for the sweep operation.
        When setting the range the start wavelength is set to the first occurrence of
        that wavelength in the calibration table and the end wavelength is set to the
        last occurrence. This ensures proper indexing within the calibration table.

        **Important**: The sweep goes from high to low wavelengths. Therefore:
        - `start_wl` should be the highest wavelength (where sweep begins)
        - `end_wl` should be the lowest wavelength (where sweep ends)

        If the specified wavelengths are not exact matches in the calibration table,
        the closest available wavelengths will be used instead.

        Args:
            range: Tuple or list containing (start_wl, end_wl) where start_wl is the
                highest wavelength (where sweep begins) and end_wl is the lowest
                wavelength (where sweep ends), both in nanometers.

        Raises:
            ValueError: If wavelength are outside the calibrated range or if
                start <= end.

        """
        start_wl, end_wl = range
        if end_wl < self._min_wl or start_wl > self._max_wl:
            raise ValueError(f"Range must be in [{self._max_wl} -> {self._min_wl}].")
        if start_wl <= end_wl:
            raise ValueError(
                f"Start wavelength {start_wl} cannot be less than end wavelength "
                f"{end_wl}."
            )
        if start_wl not in self._wavelengths:
            start_wl = self._find_closest_wavelength(start_wl)
        if end_wl not in self._wavelengths:
            end_wl = self._find_closest_wavelength(end_wl)

        # Get the index of the first occurrence of the start wavelength
        index_start: int = self._wavelengths.index(start_wl)
        # Get the index of the first occurrence of the end wavelength
        index_end: int = self._wavelengths.index(end_wl)
        # Get the index of the last occurrence of the end wavelength
        index_end += self._wavelengths.count(end_wl) - 1

        self._comm.query(data=f"DRV:CYC:SPAN {index_start} {index_end}")

    @property
    def step_size(self) -> float:
        """Get the step size between consecutive wavelengths in the sweep range.

        Returns:
            The step size in nanometers between consecutive wavelengths
                in the sweep range.

        """
        return self._step_size

    @property
    def cycler_running(self) -> bool:
        """Indicates if the cycler is currently running.

        Returns:
            (bool): if the cycler is running

        """
        return bool(int(self._comm.query("DRV:CYC:RUN?")))

    ########## Private Methods ##########

    def _find_closest_wavelength(self, wavelength: float) -> float:
        """Find the closest available wavelength in the calibration table.

        This method is used internally to find a wavelength in the calibration table
        that is closest to the specified target wavelength. This is useful when
        the exact requested wavelength is not available in the calibration data.

        Args:
            wavelength: The target wavelength in nanometers.

        Returns:
            The closest valid wavelength from the calibration data in nanometers.

        """
        return min(self._wavelengths, key=lambda x: abs(x - wavelength))

    ########## Method Overloads/Aliases ##########

    def set_count(self, count: int) -> None:
        """Alias for the `number_sweeps` property setter.

        Args:
            count: Number of sweeps to perform. Set to 0 for infinite sweeps.

        Raises:
            ValueError: If count is negative or not an integer.

        """
        self.number_sweeps = count

    def get_wl(self) -> float:
        """Alias for the `wavelength` property getter for convenience.

        Returns:
            Current wavelength in nanometers.

        """
        return self.wavelength

    def set_interval(self, interval: int) -> None:
        """Alias for the `interval` property setter.

        Args:
            interval: Time interval between wavelength steps in microseconds.
                Must be a positive integer between 20 and 50 000.

        Warning:
            The interval is part of the calibration data. Changing it
            may cause the laser to behave differently than expected.

        Raises:
            ValueError: If interval is not a positive integer within the valid range.

        """
        self.interval = interval

    @property
    def start_wavelength(self) -> float:
        """Get the start wavelength of the current sweep range.

        Alias for `get_range` result extraction for convenience.

        Returns:
            The wavelength at the start of the current sweep range
                in nanometers.

        """
        return self.range[0]

    @start_wavelength.setter
    def start_wavelength(self, wavelength: float) -> None:
        """Set the lower wavelength of the sweep range.

        Alias for `set_range` with current end wavelength for convenience.

        Args:
            wavelength: New start wavelength in nanometers.

        Raises:
            ValueError: If wavelength is outside the calibrated wavelength range or
                if it is greater than or equal to the current end wavelength.

        """
        self.range = (wavelength, self.end_wavelength)

    @property
    def end_wavelength(self) -> float:
        """Get the end wavelength of the current sweep range.

        Alias for `get_range` result extraction for convenience.

        Returns:
            The wavelength at the end of the current sweep range
                in nanometers.

        """
        return self.range[1]

    @end_wavelength.setter
    def end_wavelength(self, wavelength: float) -> None:
        """Set the end wavelength of the sweep range.

        Alias for `set_range` with current start wavelength for convenience.

        Args:
            wavelength: New end wavelength in nanometers.

        Raises:
            ValueError: If wavelength is outside the calibrated wavelength range or
                if it is less than or equal to the current start wavelength.

        """
        self.range = (self.start_wavelength, wavelength)

    def get_range(self) -> tuple[float, float]:
        """Alias for `range`.

        Returns the current sweep range as configured for high-to-low wavelength
        sweeping.

        Returns:
            A tuple containing (start_wavelength, end_wavelength) where
                start_wavelength is the higher value and end_wavelength is the lower
                value, reflecting the high-to-low sweep direction.

        """
        return self.range

    def set_range(self, start_wl: float, end_wl: float) -> None:  # set range
        """Alias for `range`.

        Returns the current sweep range as configured for high-to-low wavelength
          sweeping.

        Args:
            start_wl: Start wavelength in nanometers (should be the higher value).
            end_wl: End wavelength in nanometers (should be the lower value).

        Raises:
            ValueError: If wavelength are outside the calibrated range or
                if start <= end.

        """
        self.range = (start_wl, end_wl)
Attributes
mode: LaserMode property

Get the laser operation mode.

Returns:

  • LaserMode ( LaserMode ) –

    LaserMode.SWEEP indicating this is a sweep mode instance.

wavelength: float property

Get the current wavelength from the laser.

Returns:

  • float

    The wavelength corresponding to the current wavelength in nanometers.

Note

Queries the laser hardware for the current position and maps it to the corresponding wavelength in the calibration table.

Warning

Depending on the interval, this value may have changed by the time it is retrieved due to the continuous sweeping operation.

interval: int property writable

Get the current interval setting.

Returns:

  • int

    The time interval between wavelength steps in milliseconds.

number_sweeps: int property writable

Get the configured number of sweep cycles.

Returns:

  • int

    The number of sweep cycles configured. 0 indicates infinite sweeps.

range: tuple[float, float] property writable

Get the current wavelength sweep range.

Returns:

  • tuple[float, float]

    A tuple containing (start_wavelength, end_wavelength) where start_wavelength is the higher value and end_wavelength is the lower value, reflecting the high-to-low sweep direction.

step_size: float property

Get the step size between consecutive wavelengths in the sweep range.

Returns:

  • float

    The step size in nanometers between consecutive wavelengths in the sweep range.

cycler_running: bool property

Indicates if the cycler is currently running.

Returns:

  • bool

    if the cycler is running

start_wavelength: float property writable

Get the start wavelength of the current sweep range.

Alias for get_range result extraction for convenience.

Returns:

  • float

    The wavelength at the start of the current sweep range in nanometers.

end_wavelength: float property writable

Get the end wavelength of the current sweep range.

Alias for get_range result extraction for convenience.

Returns:

  • float

    The wavelength at the end of the current sweep range in nanometers.

Functions
__init__(laser: Laser, calibration: dict) -> None

Parameters:

  • laser (Laser) –

    The laser instance to control.

  • calibration (dict) –

    Calibration data dictionary containing sweep mode parameters. This should be the full calibration dictionary as returned by utils.read_calibration_file.

Raises:

  • ValueError

    If laser model is not COMET or calibration is invalid.

Source code in src/pychilaslasers/modes/sweep_mode.py
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
def __init__(self, laser: Laser, calibration: dict) -> None:
    """Initialize sweep mode with laser instance and calibration data.

    Args:
        laser: The laser instance to control.
        calibration: Calibration data dictionary containing sweep mode parameters.
            This should be the full calibration dictionary as returned by
            `utils.read_calibration_file`.

    Raises:
        ValueError: If laser model is not COMET or calibration is invalid.

    """
    super().__init__(laser)
    if (
        laser.model != "COMET"
        or calibration.get("model") != "COMET"
        or "sweep" not in calibration
    ):
        raise ModeError(
            "Sweep mode is only supported for COMET lasers.",
            current_mode=laser.mode,
        )

    # Gather calibration data
    self._calibration = calibration["sweep"]
    self._default_TEC: float = calibration["sweep"]["tec_temp"]
    self._default_current: float = calibration["sweep"]["current"]
    self._default_interval: int = calibration["sweep"]["interval"]
    self._wavelengths: list[float] = calibration["sweep"]["wavelengths"]

    self._min_wl: float = min(self._wavelengths)
    self._max_wl: float = max(self._wavelengths)
    self._step_size: float = abs(
        self._wavelengths[0]
        - self._wavelengths[self._wavelengths.count(self._wavelengths[0])]
    )

    self._no_sweeps: int = 0  # Default to infinite sweeps
apply_defaults() -> None

Apply default settings for sweep mode operation.

Sets the laser to the default TEC temperature, diode current, full wavelength range and interval.

Source code in src/pychilaslasers/modes/sweep_mode.py
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
def apply_defaults(self) -> None:
    """Apply default settings for sweep mode operation.

    Sets the laser to the default TEC temperature, diode current,
    full wavelength range and interval.
    """
    self._laser.tec.target = self._default_TEC
    self._laser.diode.current = self._default_current
    try:
        self.set_range(start_wl=self._max_wl, end_wl=self._min_wl)
    except LaserError as e:
        if "cycler" not in e.message:
            logging.getLogger(__name__).error(f"Failed to set sweep range: {e}")
            raise e

    self.interval = self._default_interval
start(number_sweeps: int | None = None) -> None

Start the wavelength sweep operation.

Initiates the sweep operation with the configured number of cycles. The laser will begin cycling through the wavelength range according to the current range and interval settings.

Source code in src/pychilaslasers/modes/sweep_mode.py
117
118
119
120
121
122
123
124
125
126
127
def start(self, number_sweeps: int | None = None) -> None:
    """Start the wavelength sweep operation.

    Initiates the sweep operation with the configured number of cycles.
    The laser will begin cycling through the wavelength range according
    to the current range and interval settings.
    """
    if number_sweeps is not None:
        self.number_sweeps = number_sweeps

    self._comm.query(data=f"DRV:CYC:RUN {self.number_sweeps:d}")
stop() -> None

Stop the current wavelength sweep operation.

Immediately halts the sweep operation. The laser will remain at its current wavelength position. Use resume to continue the sweep from where it was stopped.

Source code in src/pychilaslasers/modes/sweep_mode.py
129
130
131
132
133
134
135
136
def stop(self) -> None:
    """Stop the current wavelength sweep operation.

    Immediately halts the sweep operation. The laser will remain at its
    current wavelength position. Use `resume` to continue the sweep
    from where it was stopped.
    """
    self._comm.query(data="DRV:CYC:ABRT")
resume() -> None

Resume a paused wavelength sweep operation.

Resumes a sweep operation that was previously stopped using the stop method. The sweep will continue from its current position with the same configuration settings.

Source code in src/pychilaslasers/modes/sweep_mode.py
138
139
140
141
142
143
144
145
def resume(self) -> None:
    """Resume a paused wavelength sweep operation.

    Resumes a sweep operation that was previously stopped using the
    `stop` method. The sweep will continue from its current position
    with the same configuration settings.
    """
    self._comm.query(data="DRV:CYC:CONT")
get_total_time() -> float

Calculate the total estimated time for the complete sweep operation.

Returns:

  • float

    The estimated total time for the sweep in microseconds, based on the current interval, number of wavelength points, and number of sweep cycles. Returns 0.0 if number of sweeps is 0 (infinite sweeps).

Source code in src/pychilaslasers/modes/sweep_mode.py
147
148
149
150
151
152
153
154
155
156
157
158
159
160
def get_total_time(self) -> float:
    """Calculate the total estimated time for the complete sweep operation.

    Returns:
        The estimated total time for the sweep in microseconds, based on the current
            interval, number of wavelength points, and number of sweep cycles.
            Returns 0.0 if number of sweeps is 0 (infinite sweeps).

    """
    return (
        self.interval * len(self.get_points()) * self.number_sweeps
        if self.number_sweeps > 0
        else 0.0
    )
get_points() -> list[float]

Get all wavelength points within the current sweep range.

Returns:

  • list[float]

    List of wavelengths that will be swept through during operation, including both the lower and upper wavelengths.

Source code in src/pychilaslasers/modes/sweep_mode.py
162
163
164
165
166
167
168
169
170
171
172
173
def get_points(self) -> list[float]:
    """Get all wavelength points within the current sweep range.

    Returns:
        List of wavelengths that will be swept through during operation,
            including both the lower and upper wavelengths.

    """
    lower_index: int = self._wavelengths.index(self.start_wavelength)
    upper_index: int = self._wavelengths.index(self.end_wavelength)
    upper_index += self._wavelengths.count(self.end_wavelength) - 1
    return self._wavelengths[lower_index : upper_index + 1]
set_count(count: int) -> None

Alias for the number_sweeps property setter.

Parameters:

  • count (int) –

    Number of sweeps to perform. Set to 0 for infinite sweeps.

Raises:

  • ValueError

    If count is negative or not an integer.

Source code in src/pychilaslasers/modes/sweep_mode.py
370
371
372
373
374
375
376
377
378
379
380
def set_count(self, count: int) -> None:
    """Alias for the `number_sweeps` property setter.

    Args:
        count: Number of sweeps to perform. Set to 0 for infinite sweeps.

    Raises:
        ValueError: If count is negative or not an integer.

    """
    self.number_sweeps = count
get_wl() -> float

Alias for the wavelength property getter for convenience.

Returns:

  • float

    Current wavelength in nanometers.

Source code in src/pychilaslasers/modes/sweep_mode.py
382
383
384
385
386
387
388
389
def get_wl(self) -> float:
    """Alias for the `wavelength` property getter for convenience.

    Returns:
        Current wavelength in nanometers.

    """
    return self.wavelength
set_interval(interval: int) -> None

Alias for the interval property setter.

Parameters:

  • interval (int) –

    Time interval between wavelength steps in microseconds. Must be a positive integer between 20 and 50 000.

Warning

The interval is part of the calibration data. Changing it may cause the laser to behave differently than expected.

Raises:

  • ValueError

    If interval is not a positive integer within the valid range.

Source code in src/pychilaslasers/modes/sweep_mode.py
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
def set_interval(self, interval: int) -> None:
    """Alias for the `interval` property setter.

    Args:
        interval: Time interval between wavelength steps in microseconds.
            Must be a positive integer between 20 and 50 000.

    Warning:
        The interval is part of the calibration data. Changing it
        may cause the laser to behave differently than expected.

    Raises:
        ValueError: If interval is not a positive integer within the valid range.

    """
    self.interval = interval
get_range() -> tuple[float, float]

Alias for range.

Returns the current sweep range as configured for high-to-low wavelength sweeping.

Returns:

  • tuple[float, float]

    A tuple containing (start_wavelength, end_wavelength) where start_wavelength is the higher value and end_wavelength is the lower value, reflecting the high-to-low sweep direction.

Source code in src/pychilaslasers/modes/sweep_mode.py
466
467
468
469
470
471
472
473
474
475
476
477
478
def get_range(self) -> tuple[float, float]:
    """Alias for `range`.

    Returns the current sweep range as configured for high-to-low wavelength
    sweeping.

    Returns:
        A tuple containing (start_wavelength, end_wavelength) where
            start_wavelength is the higher value and end_wavelength is the lower
            value, reflecting the high-to-low sweep direction.

    """
    return self.range
set_range(start_wl: float, end_wl: float) -> None

Alias for range.

Returns the current sweep range as configured for high-to-low wavelength sweeping.

Parameters:

  • start_wl (float) –

    Start wavelength in nanometers (should be the higher value).

  • end_wl (float) –

    End wavelength in nanometers (should be the lower value).

Raises:

  • ValueError

    If wavelength are outside the calibrated range or if start <= end.

Source code in src/pychilaslasers/modes/sweep_mode.py
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
def set_range(self, start_wl: float, end_wl: float) -> None:  # set range
    """Alias for `range`.

    Returns the current sweep range as configured for high-to-low wavelength
      sweeping.

    Args:
        start_wl: Start wavelength in nanometers (should be the higher value).
        end_wl: End wavelength in nanometers (should be the lower value).

    Raises:
        ValueError: If wavelength are outside the calibrated range or
            if start <= end.

    """
    self.range = (start_wl, end_wl)