herosdevices.hardware.menlo.repetition_rate
===========================================

.. py:module:: herosdevices.hardware.menlo.repetition_rate

.. autoapi-nested-parse::

   HERO driver for the repetition-rate stabilization loop of a Menlo Systems frequency comb.





Module Contents
---------------

.. py:class:: RepetitionRate(ofc: herosdevices.hardware.menlo.ofc.OFC, amp_node: str | None = None, observables: dict[str, dict[str, str]] | None = None)

   Bases: :py:obj:`herosdevices.hardware.menlo.dds.DDS`, :py:obj:`herosdevices.hardware.menlo.beat_loop.BeatLoop`


   Driver for the repetition-rate stabilization loop of a Menlo Systems frequency comb.

   Wraps the OFC's `functionalLayer.rrSettings` sub-tree, a fixed, singleton module (there is only one
   repetition-rate loop per OFC, so unlike :py:class:`~herosdevices.hardware.menlo.DDS`/
   :py:class:`~herosdevices.hardware.menlo.LaserLock` there is no `funclayer_identifier` to select).

   Combines :py:class:`~herosdevices.hardware.menlo.DDS` (the loop's underlying DDS, confirmed
   identical in shape to a laser-lock module's) with :py:class:`BeatLoop` (the shared lock-loop shape).
   This means `RepetitionRate` implements atomiq's `RFSource` interface via the DDS: `_set_frequency`
   tunes the DDS directly, not the loop's beat-frequency setpoint (see :py:attr:`beat_frequency_setpoint` for
   that).

   Also exposes `select_monitor` (the same node shape seen on CW channels and `CEO`, so treated as a
   general default here). One observed comb additionally has `amp1542` (laser-diode current control, see
   `amp_node`), `frequencyDistributionOpticalBeat`/`frequencyDistributionRfBeat`, and an
   `operationMode.lockMode` single/dual-lock switch - none of those are modeled here, since they weren't
   seen anywhere else and it's unconfirmed whether they're a fixed feature of every Menlo repetition-rate
   loop or specific to that comb's configuration. Poll/control them via `observables` or `ofc.get_node`/
   `set_node` directly if your comb has them.

   :param ofc: The OFC HERO this loop belongs to.
   :param amp_node: Relative node name of this loop's laser-diode current-control block (`amp*`), if it has
                    one. `None` (the default) leaves :py:attr:`current_control` unset.
   :param observables: Additional observables to poll, merged on top of `DEFAULT_OBSERVABLES`, see
                       :py:class:`~herosdevices.hardware.menlo.functional_layer.FunctionalLayerModule`.


   .. py:attribute:: DEFAULT_OBSERVABLES
      :type:  dict[str, dict[str, str]]


   .. py:attribute:: select_monitor


   .. py:attribute:: current_control


   .. py:property:: beat_frequency
      :type: float


      The currently measured repetition-rate beat frequency. Read-only.


   .. py:property:: beat_frequency_setpoint
      :type: float


      Target repetition-rate beat frequency.


   .. py:attribute:: amp_max
      :type:  float
      :value: 1.0



   .. py:attribute:: amp_min
      :type:  float
      :value: 0.0



   .. py:attribute:: freq_max
      :type:  float
      :value: 100000000.0



   .. py:attribute:: freq_min
      :type:  float
      :value: 0.0



   .. py:property:: output_enabled
      :type: bool


      Whether the DDS output is enabled.


   .. py:attribute:: ofc


   .. py:attribute:: base_path


   .. py:attribute:: observables


   .. py:method:: get(relative_path: str) -> Any

      Read the current value of a node relative to this module's settings object.

      Use this for module properties not already exposed as a named attribute. See
      :py:meth:`~herosdevices.hardware.menlo.ofc.OFC.explore` to find the available relative paths,
      e.g. `ofc.explore(module.base_path, depth=2)`.

      :param relative_path: Dotted path relative to `base_path`.

      :returns: The current value of the node.



   .. py:method:: set(relative_path: str, value: Any) -> None

      Set the value of a node relative to this module's settings object.

      :param relative_path: Dotted path relative to `base_path`, see :py:meth:`get`.
      :param value: Value to set.



   .. py:attribute:: frequency
      :type:  float
      :value: 1000000.0



   .. py:attribute:: amplitude
      :type:  float
      :value: 0.1



   .. py:attribute:: phase
      :type:  float
      :value: 0.0



   .. py:attribute:: default_ramp_steps
      :type:  int
      :value: 30



   .. py:attribute:: blind
      :type:  bool
      :value: False



   .. py:property:: locked
      :type: bool


      Whether the loop is currently locked.


   .. py:property:: fast_output_locked
      :type: bool


      Whether the loop's fast feedback branch is currently locked. Read-only status.


   .. py:property:: fast_output_monitor
      :type: float


      Monitor voltage of the loop's fast feedback branch. Read-only.


   .. py:property:: fast_output_setpoint
      :type: float


      Setpoint of the loop's fast feedback branch.


   .. py:property:: slow_output_locked
      :type: bool


      Whether the loop's slow feedback branch is currently locked. Read-only status.


   .. py:property:: slow_output_monitor
      :type: float


      Monitor voltage of the loop's slow feedback branch. Read-only.


   .. py:property:: slow_output_setpoint
      :type: float


      Setpoint of the loop's slow feedback branch.


   .. py:method:: unlock_here() -> None

      Unlock the loop and immediately re-engage it at the current beat frequency.

      Shared with :py:class:`~herosdevices.hardware.menlo.LaserLock`, which uses the same
      `mainControls.unlockHere` node name.

      Inferred from context (Menlo's own naming and the sibling `lock`/setpoint nodes) rather than verified
      against vendor documentation: releases the lock if engaged, then re-engages it using the beat note as
      it currently stands as the new setpoint, instead of servoing to a previously configured setpoint.



