Source code for herosdevices.hardware.menlo.fxe

"""HERO driver for the frequency-counter (FXE) module of a Menlo Systems frequency comb."""

from herosdevices.helper import mark_driver

from .functional_layer import FunctionalLayerModule
from .ofc import OFC


[docs] @mark_driver( name="Menlo FXE", info="Frequency-counter module of a Menlo Systems frequency comb, via QWebChannel", state="alpha", additional_docs=["/tutorials/menlo_ofc.rst"], product_page="https://www.menlosystems.com/", ) class FXE(FunctionalLayerModule): """Driver for the frequency-counter (FXE) module of a Menlo Systems frequency comb. Wraps the OFC's `functionalLayer.fxeSettings` sub-tree, a fixed, singleton module (there is only one FXE counter per OFC, so unlike :py:class:`~herosdevices.hardware.menlo.DDS`/ :py:class:`~herosdevices.hardware.menlo.LaserLock` there is no `funclayer_identifier` to select). Confirmed reachable directly at `functionalLayer.fxeSettings` (the same object is also reachable via `modules["SYNCRO3U"].functionalLayer.fxeSettings`). Unlike the other functional-layer modules, FXE has no lock loop or DDS - it is a pure 16-channel frequency counter. Use :py:meth:`channel_frequency` to read a specific channel; which channel carries which physical beat signal is deployment-specific, so there is no fixed per-channel `DEFAULT_OBSERVABLES` here - pass `observables` to poll the channels relevant to your comb. Args: ofc: The OFC HERO this counter belongs to. observables: Additional observables to poll, merged on top of `DEFAULT_OBSERVABLES`, see :py:class:`~herosdevices.hardware.menlo.functional_layer.FunctionalLayerModule`. """ def __init__(self, ofc: OFC, observables: dict[str, dict[str, str]] | None = None) -> None: FunctionalLayerModule.__init__(self, ofc, "functionalLayer.fxeSettings", observables=observables)
[docs] def channel_frequency(self, channel: int) -> float: """Read the currently measured frequency of one counter channel. Args: channel: Channel number, 1-16 (matching the device's `channel01`-`channel16` node names). Returns: The channel's currently measured frequency, in Hz. """ return self.ofc.get_node(self._path(f"counterFrequencies.channel{channel:02d}"))
@property def rate(self) -> int: """The counter's update rate.""" return self.ofc.get_node(self._path("counterSettings.rate")) @rate.setter def rate(self, rate: int) -> None: self.ofc.set_node(self._path("counterSettings.rate"), rate)