Skip to content

Calibration

pychilaslasers.calibration

Calibration data management for Chilas laser systems.

This module provides comprehensive functionality for loading, parsing, and managing calibration data for Chilas laser systems. It supports both ATLAS and COMET laser models with their respective calibration file formats.

Classes:

  • Calibration

    Main calibration data container with wavelength lookup.

  • CalibrationEntry

    Individual calibration data point for a wavelength.

  • TuneSettings

    Configuration for tune mode operation.

  • TuneMethod

    Enum representing the different methods for changing the wavelength

  • SweepSettings

    Configuration for sweep mode operation.

Functions:

Modules:

  • calibration_parsing

    Calibration file parsing and loading functionality.

  • defaults

    Default configuration values for laser calibration.

  • structs

    Data structures for laser calibration management.

Classes

Calibration(entries: list[CalibrationEntry], tune_settings: TuneSettings, sweep_settings: SweepSettings | None, serial_number: str | None = None, model: str = 'ATLAS') dataclass

Comprehensive calibration data container for laser systems.

This class provides a complete representation of laser calibration data, offering convenient access to calibration entries by wavelength with automatic closest-match functionality.

Attributes:

  • model (str) –

    Laser model identifier ("ATLAS" or "COMET").

  • entries (list[CalibrationEntry]) –

    Complete list of calibration entries in file order.

  • min_wl (float) –

    Minimum wavelength in the calibration range.

  • max_wl (float) –

    Maximum wavelength in the calibration range.

  • precision (int) –

    The maximum number of decimals an entry can have after the "."

  • step_size (float) –

    Wavelength step size between entries.

  • tune_settings (TuneSettings) –

    Configuration for tune mode operation.

  • sweep_settings (SweepSettings | None) –

    Configuration for sweep mode (None for ATLAS).

Parameters:

  • model (str, default: 'ATLAS' ) –

    Laser model identifier ("ATLAS" or "COMET").

  • serial_number (str | None, default: None ) –

    of the laser. Used to correlate calibration to specific laser. Can be None.

  • entries (list[CalibrationEntry]) –

    List of calibration entries in original file order. Must not be empty.

  • tune_settings (TuneSettings) –

    Settings for tune mode operation.

  • sweep_settings (SweepSettings | None) –

    Settings for sweep mode operation. Should be None for ATLAS lasers, required for COMET lasers.

Methods:

  • get_mode_hop_start

    Get the calibration entry at the start of a mode hop procedure.

  • __getitem__

    Get calibration entry for a specific wavelength.

  • __iter__

    Iterate over all calibration entries in original file order.

  • __len__

    Return the total number of calibration entries.

  • __contains__

    Check if a wavelength or entry is within this calibration.

Source code in src/pychilaslasers/calibration/structs.py
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
def __init__(
    self,
    entries: list[CalibrationEntry],  # should be in original order
    tune_settings: TuneSettings,
    sweep_settings: SweepSettings | None,
    serial_number: str | None = None,
    model: str = "ATLAS",
) -> None:
    """Initialize Calibration with laser model and calibration data.

    Args:
        model: Laser model identifier ("ATLAS" or "COMET").
        serial_number: of the laser. Used to correlate calibration to specific
            laser. Can be None.
        entries: List of calibration entries in original file order.
            Must not be empty.
        tune_settings: Settings for tune mode operation.
        sweep_settings: Settings for sweep mode operation. Should be
            None for ATLAS lasers, required for COMET lasers.
    """
    self.model = model
    self.serial_number = serial_number
    self.entries = entries
    self.tune_settings = tune_settings
    self.sweep_settings = sweep_settings
    if entries == []:
        raise CalibrationError("Empty calibration received!")
    _wavelengths: list[float] = [entry.wavelength for entry in entries]
    self.max_wl = max(_wavelengths)
    self.min_wl = min(_wavelengths)
    self.precision = max(
        len(s.split(".")[1]) if "." in s else 0 for s in map(str, _wavelengths)
    )

    try:
        self.step_size = min([x - y for x, y in pairwise(_wavelengths)])
    except IndexError:
        logging.getLogger(__name__).warning(
            "Calibration loaded with less than 2 entries"
        )

    self._direct_access = {
        entry.wavelength: entry for entry in entries if not entry.mode_hop_flag
    }
Functions
get_mode_hop_start(wavelength: float) -> CalibrationEntry

Get the calibration entry at the start of a mode hop procedure.

For COMET lasers, mode hops require special handling with multiple calibration entries per wavelength. This method returns the first entry in a mode hop sequence if one exists for the requested wavelength.

Parameters:

  • wavelength (float) –

    Target wavelength in nanometers.

Returns:

  • CalibrationEntry

    The first CalibrationEntry in a mode hop procedure if the wavelength has mode hop entries, otherwise returns the standard entry via __getitem__.

Source code in src/pychilaslasers/calibration/structs.py
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
def get_mode_hop_start(self, wavelength: float) -> CalibrationEntry:
    """Get the calibration entry at the start of a mode hop procedure.

    For COMET lasers, mode hops require special handling with multiple
    calibration entries per wavelength. This method returns the first
    entry in a mode hop sequence if one exists for the requested wavelength.

    Args:
        wavelength: Target wavelength in nanometers.

    Returns:
        The first CalibrationEntry in a mode hop procedure if the wavelength
            has mode hop entries, otherwise returns the standard entry via
            `__getitem__`.

    """
    wavelength = self[wavelength].wavelength
    mode_hops: list[CalibrationEntry] = [
        entry
        for entry in self.entries
        if entry.wavelength == wavelength and entry.mode_hop_flag
    ]
    if mode_hops:
        return mode_hops[0]
    else:
        return self[wavelength]
__getitem__(wavelength: float) -> CalibrationEntry

Get calibration entry for a specific wavelength.

Supports exact wavelength matches and closest approximation for wavelengths within the calibration range. Mode hop entries are excluded from closest-match searches.

Parameters:

  • wavelength (float) –

    Target wavelength in nanometers.

Returns:

  • CalibrationEntry

    CalibrationEntry for the exact wavelength or closest available match.

Raises:

  • KeyError

    If wavelength is outside the calibration range.

Source code in src/pychilaslasers/calibration/structs.py
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
def __getitem__(self, wavelength: float) -> CalibrationEntry:
    """Get calibration entry for a specific wavelength.

    Supports exact wavelength matches and closest approximation for
    wavelengths within the calibration range. Mode hop entries are
    excluded from closest-match searches.

    Args:
        wavelength: Target wavelength in nanometers.

    Returns:
        CalibrationEntry for the exact wavelength or closest available match.

    Raises:
        KeyError: If wavelength is outside the calibration range.
    """
    if wavelength in self._direct_access:
        return self._direct_access[wavelength]
    elif wavelength in self:
        return self._direct_access[
            min(self._direct_access.keys(), key=lambda x: abs(x - wavelength))
        ]
    else:
        raise KeyError(wavelength)
__iter__() -> Iterator[CalibrationEntry]

Iterate over all calibration entries in original file order.

Returns:

Source code in src/pychilaslasers/calibration/structs.py
283
284
285
286
287
288
289
def __iter__(self) -> Iterator[CalibrationEntry]:
    """Iterate over all calibration entries in original file order.

    Returns:
        Iterator yielding CalibrationEntry objects.
    """
    return iter(self.entries)
__len__() -> int

Return the total number of calibration entries.

Returns:

  • int

    Number of entries in the calibration.

Source code in src/pychilaslasers/calibration/structs.py
291
292
293
294
295
296
297
def __len__(self) -> int:
    """Return the total number of calibration entries.

    Returns:
        Number of entries in the calibration.
    """
    return len(self.entries)
__contains__(wl: float | CalibrationEntry) -> bool
__contains__(wl: CalibrationEntry) -> bool
__contains__(wl: float) -> bool

Check if a wavelength or entry is within this calibration.

Supports checking both wavelength ranges and specific entry membership. For wavelengths, uses inclusive range checking between min_wl and max_wl.

Parameters:

  • wl (float | CalibrationEntry) –

    Either a wavelength in nanometers or a CalibrationEntry object.

Returns:

  • bool

    For wavelength: True if within the calibration range [min_wl, max_wl].

  • bool

    For CalibrationEntry: True if the exact entry exists in this calibration.

Source code in src/pychilaslasers/calibration/structs.py
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
def __contains__(self, wl: float | CalibrationEntry) -> bool:
    """Check if a wavelength or entry is within this calibration.

    Supports checking both wavelength ranges and specific entry membership.
    For wavelengths, uses inclusive range checking between min_wl and max_wl.

    Args:
        wl: Either a wavelength in nanometers or a CalibrationEntry object.

    Returns:
        For wavelength: True if within the calibration range [min_wl, max_wl].
        For CalibrationEntry: True if the exact entry exists in this calibration.
    """
    if isinstance(wl, CalibrationEntry):
        return wl in self.entries
    else:
        return self.min_wl <= wl <= self.max_wl

CalibrationEntry(wavelength: float, phase_section: float, large_ring: float, small_ring: float, coupler: float, mode_index: int | None, mode_hop_flag: bool, cycler_index: int) dataclass

Represents a single calibration data entry for a specific wavelength.

This dataclass represents all the calibration parameters for a single wavelength setting, including heater values for the laser's optical components and metadata about mode hops.

Attributes:

  • wavelength (float) –

    Target wavelength in nanometers.

  • phase_section (float) –

    Voltage setting for the phase section heater.

  • large_ring (float) –

    Voltage setting for the large ring heater.

  • small_ring (float) –

    Voltage setting for the small ring heater.

  • coupler (float) –

    Voltage setting for the coupler heater.

  • mode_index (int | None) –

    Mode index for COMET lasers (None for ATLAS).

  • mode_hop_flag (bool) –

    True if this entry is part of a mode hop procedure.

  • cycler_index (int) –

    Sequential index in the original calibration file.

  • heater_values (tuple[float, float, float, float]) –

    Tuple of all heater values (computed automatically).

Example
entry = CalibrationEntry(
    wavelength=1550.0,
    phase_section=10.5,
    large_ring=20.3,
    small_ring=15.1,
    coupler=25.7,
    mode_index=1,
    mode_hop_flag=False,
    cycler_index=42
)

Methods:

  • __post_init__

    Compute heater_values tuple from individual heater settings.

Functions
__post_init__() -> None

Compute heater_values tuple from individual heater settings.

This method is automatically called after object initialization to create a convenient tuple containing all heater values in order: (phase_section, large_ring, small_ring, coupler).

Source code in src/pychilaslasers/calibration/structs.py
75
76
77
78
79
80
81
82
83
84
85
86
87
def __post_init__(self) -> None:
    """Compute heater_values tuple from individual heater settings.

    This method is automatically called after object initialization to
    create a convenient tuple containing all heater values in order:
    (phase_section, large_ring, small_ring, coupler).
    """
    self.heater_values = (
        self.phase_section,
        self.large_ring,
        self.small_ring,
        self.coupler,
    )

TuneSettings(current: float, tec_temp: float, anti_hyst_voltages: list[float], anti_hyst_times: list[float], method: TuneMethod) dataclass

Bases: ModeSetting


              flowchart TD
              pychilaslasers.calibration.TuneSettings[TuneSettings]
              pychilaslasers.calibration.structs.ModeSetting[ModeSetting]

                              pychilaslasers.calibration.structs.ModeSetting --> pychilaslasers.calibration.TuneSettings
                


              click pychilaslasers.calibration.TuneSettings href "" "pychilaslasers.calibration.TuneSettings"
              click pychilaslasers.calibration.structs.ModeSetting href "" "pychilaslasers.calibration.structs.ModeSetting"
            

Configuration settings for laser tune mode operation.

This class extends ModeSetting to include tune-specific parameters for laser systems operating in tune mode with anti-hysteresis control.

Attributes:

  • current (float) –

    Inherited from ModeSetting - Diode current setting in milliamps.

  • tec_temp (float) –

    Inherited from ModeSetting - TEC temperature target in Celsius.

  • anti_hyst_voltages (list[float]) –

    Anti-hysteresis voltage values for tune mode.

  • anti_hyst_times (list[float]) –

    Anti-hysteresis timing values for tune mode.

  • method (TuneMethod) –

    The wavelength changing method to be used.

TuneMethod

Bases: Enum


              flowchart TD
              pychilaslasers.calibration.TuneMethod[TuneMethod]

              

              click pychilaslasers.calibration.TuneMethod href "" "pychilaslasers.calibration.TuneMethod"
            

Enumeration for tune method types.

Specifies the available methods for tuning: from file or cycler.

SweepSettings(current: float, tec_temp: float, interval: int) dataclass

Bases: ModeSetting


              flowchart TD
              pychilaslasers.calibration.SweepSettings[SweepSettings]
              pychilaslasers.calibration.structs.ModeSetting[ModeSetting]

                              pychilaslasers.calibration.structs.ModeSetting --> pychilaslasers.calibration.SweepSettings
                


              click pychilaslasers.calibration.SweepSettings href "" "pychilaslasers.calibration.SweepSettings"
              click pychilaslasers.calibration.structs.ModeSetting href "" "pychilaslasers.calibration.structs.ModeSetting"
            

Configuration settings for laser sweep mode operation.

This class extends ModeSetting to include sweep-specific parameters for COMET laser systems operating in sweep mode.

Attributes:

  • current (float) –

    Inherited from ModeSetting - Diode current setting in milliamps.

  • tec_temp (float) –

    Inherited from ModeSetting - TEC temperature target in Celsius.

  • interval (int) –

    Sweep interval for sweep mode in milliseconds.

Defaults

Hard-coded default values for laser calibration parameters.

Used when calibration files don't contain explicit settings.

Functions

load_calibration(file_path: str | Path) -> Calibration

Load and parse a laser calibration file into a Calibration object.

This function is the main entry point for loading calibration data.

Parameters:

  • file_path (str | Path) –

    Path to the calibration file (CSV format with semicolon delimiters).

Returns:

  • Calibration

    A fully initialized Calibration object containing all calibration

  • Calibration

    data, settings, and metadata.

Raises:

  • FileNotFoundError

    If the specified file doesn't exist.

  • CalibrationError

    If the file format is invalid or contains incomplete data.

Source code in src/pychilaslasers/calibration/calibration_parsing.py
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
def load_calibration(file_path: str | Path) -> Calibration:
    """Load and parse a laser calibration file into a Calibration object.

    This function is the main entry point for loading calibration data.

    Args:
        file_path: Path to the calibration file (CSV format with semicolon
            delimiters).

    Returns:
        A fully initialized Calibration object containing all calibration
        data, settings, and metadata.

    Raises:
        FileNotFoundError: If the specified file doesn't exist.
        CalibrationError: If the file format is invalid or contains
            incomplete data.
    """
    file_path = Path(file_path)
    entries: list[CalibrationEntry] = []

    model: str
    srn_no: str | None
    tune: TuneSettings
    sweep: SweepSettings | None
    with open(file_path, newline="") as f:
        first_line = f.readline()
        if "[default_settings]" in first_line:
            model, srn_no, tune, sweep = _parse_defaults_block(f)
        else:
            # No defaults block: rewind so the first line belongs to the data table
            f.seek(0)
            model = Defaults.LASER_MODEL
            srn_no = Defaults.SERIAL_NUMBER
            tune = TuneSettings(
                current=Defaults.TUNE_CURRENT,
                tec_temp=Defaults.TUNE_TEC_TEMP,
                anti_hyst_voltages=list(Defaults.TUNE_ANTI_HYST[0]),
                anti_hyst_times=list(Defaults.TUNE_ANTI_HYST[1]),
                method=Defaults.TUNE_METHOD,
            )
            sweep = None
        # Now parse the lookup table rows
        entries = _parse_rows(f, model=model)

    return Calibration(
        model=model,
        serial_number=srn_no,
        entries=entries,  # original order retained
        tune_settings=tune,
        sweep_settings=sweep,  # None for non-COMET
    )