Root

The pyrogue.Root class is the top-level node in a PyRogue tree. It owns the application lifecycle, coordinates bulk read/write operations, manages background workers (poll and update), and provides APIs for YAML save/load and external listeners.

For polling internals and usage patterns, see PollQueue.

Most user applications define a subclass of pyrogue.Root and add devices inside __init__.

In practice, Root is also where hardware connections are usually created and bound into the tree. A typical pattern is:

  • create a memory interface (for example AXI PCIe, TCP simulation, etc.)

  • register it with pyrogue.Root.addInterface()

  • pass that interface as memBase when adding top-level devices

  • optionally add management/control interfaces (such as ZMQ) to the same root

import pyrogue as pr
import rogue
import pyrogue.interfaces
import axipcie

class EvalBoard(pr.Root):
    def __init__(self, dev='/dev/datadev_0', sim=False, **kwargs):
        super().__init__(name='EvalBoard', description='Evaluation board root', **kwargs)

        # Create the memory-mapped hardware/simulation interface.
        if sim:
            self.memMap = rogue.interfaces.memory.TcpClient('localhost', 11000)
        else:
            self.memMap = rogue.hardware.axi.AxiMemMap(dev)

        # Register memory interface with Root so tree transactions route correctly.
        self.addInterface(self.memMap)

        # Optional management API for GUIs/remote clients.
        self.zmqServer = pyrogue.interfaces.ZmqServer(
            root=self,
            addr='127.0.0.1',
            port=0,
        )
        self.addInterface(self.zmqServer)

        # Add top-level devices and bind them to the same memory interface.
        self.add(axipcie.AxiPcieCore(
            offset=0x00000000,
            memBase=self.memMap,
            expand=True,
        ))

Key Attributes

Along with inherited Node attributes, root adds:

  • running: True when pyrogue.Root.start() has been called.

  • system commands and variables that support whole-tree control (see sections below).

Key Methods

getNode resolves dotted paths such as EvalBoard.AxiVersion.ScratchPad.

Lifecycle: start(), stop(), and _rootAttached()

Root owns the runtime lifecycle of the full tree. The call to pyrogue.Root.start() is more than “start threads”; it finishes root attachment, final initialization, interface startup, optional initial read/write, and poll scheduling.

What Root.start() does

When pyrogue.Root.start() is called:

  1. Validates the root is not already running.

  2. Calls Root._rootAttached() to attach root/parent/path references for the full tree and build device blocks.

  3. Calls _finishInit() recursively on all nodes.

  4. Validates block address overlap (per slave-id address space).

  5. Applies timeout settings to nodes/blocks.

  6. Starts background workers:

    • update worker thread

    • optional heartbeat thread

  7. Calls pyrogue.Device._start() on the root device recursively. This is where managed interfaces/protocols (added with pyrogue.Device.addInterface()) get their _start() callback. See Managed Interfaces: addInterface() and addProtocol().

  8. Optionally performs initial full-tree read/write depending on root settings.

  9. Starts pyrogue.PollQueue and applies PollEn.

What Root.stop() does

When pyrogue.Root.stop() is called:

  1. Clears running and stops the update worker.

  2. Stops pyrogue.PollQueue.

  3. Calls pyrogue.Device._stop() recursively from the root. This is where managed interfaces/protocols receive _stop().

_rootAttached() in root startup

Root._rootAttached() sets:

  • root _parent to itself

  • root _root to itself

  • root _path to root.name

Then it recursively calls node._rootAttached(parent, root) across the tree. For each node this establishes parent/root/path/logger state before runtime operations begin. Device-level _rootAttached additionally builds local variable/block mappings and applies default overrides.

_finishInit() in root startup

After _rootAttached(), pyrogue.Root.start() calls _finishInit() recursively across all nodes before worker threads and interfaces are started.

_finishInit() is the final tree-initialization stage used to complete node setup that depends on full tree attachment and resolved node references. At this point, every node has a valid parent/root/path context, so deferred initialization logic can run with complete hierarchy information.

Temporarily Blocking Polling

Use pyrogue.Root.pollBlock() when you need a short critical section that should not race with background poll reads.

with root.pollBlock():
    root.MyDevice.SomeControl.set(1)
    root.MyDevice.OtherControl.set(0)

ZmqServer Interface

pyrogue.interfaces.ZmqServer exposes the root over a ZeroMQ control channel used by tools such as PyDM-based GUIs and external clients.

Common initialization pattern in Root.__init__:

Notes:

  • port=0 auto-selects the first available base port starting at 9099 (the server then uses base, base+1, and base+2)

  • binding to 127.0.0.1 keeps the server local to the host

  • non-local deployments can bind to another interface/address as needed

Yaml File Configuration

Saving and Restoring Configurations

System-wide state/configuration can be exported to YAML text/files and loaded back with:

Built-in Groups

PyRogue root-level configuration/state commands use group filtering to include or exclude variables and commands from bulk operations.

Common built-in group names:

  • NoConfig: excluded from configuration save/load operations.

  • NoState: excluded from state snapshot/export operations.

  • Hidden: hidden from normal GUI views unless explicitly included.

See Groups for full built-in group behavior and filtering semantics.

Configuration Array Matching

YAML load supports node-array style matching and slicing. For example:

  • AmcCard[0] - DacEnable[0], DacEnable[1]

  • AmcCard[1] - DacEnable[0], DacEnable[1]

  • AmcCard[2] - DacEnable[0], DacEnable[1]

Use Python-like slicing and wildcards:

  • Enable DAC channel 0 in all cards:

    • AmcCard[:]:DacEnable[0]: True

  • Enable both DAC channels in cards 1 and 2:

    • AmcCard[1:3]: DacEnable: True

  • List slicing behavior:

    • AmcCard[1:3] -> cards 1 and 2

    • AmcCard[:2] -> cards 0 and 1

    • AmcCard[:] -> all cards

  • Wildcards:

    • AmcCard -> all cards

    • AmcCard[*] -> all cards

Included Command Objects

The following pyrogue.LocalCommand objects are all created when the Root node is created.

  • WriteAll: Write every variable value to hardware (hidden from the GUI).

  • ReadAll: Read every variable value from hardware.

  • SaveState: Save state to file in yaml format.

  • SaveConfig: Save configuration to file. Data is saved in YAML format.

  • LoadConfig: Read configuration from file. Data is read in YAML format.

  • RemoteVariableDump: Save a dump of the remote variable state.

  • RemoteConfigDump: Save a dump of the remote configuration state.

  • Initialize: Generate a soft reset to each device in the tree.

  • HardReset: Generate a hard reset to each device in the tree.

  • CountReset: Generate a count reset to each device in the tree.

  • ClearLog: Clear the message log contained in the SystemLog variable.

  • SetYamlConfig: Set configuration from YAML string.

  • GetYamlConfig: Get configuration in YAML string.

  • GetYamlState: Get current state as YAML string.

Included Variable Objects

The following pyrogue.LocalVariable objects are all created when the Root node is created.

  • RogueVersion: Rogue version string.

  • RogueDirectory: Rogue Library Directory.

  • SystemLog: String containing newline separated system logic entries. Allows remote management interfaces to know when an error has occurred. This string contains a summary of the error while the full trace method is dumped to the console.

  • SystemLogLast: String containing last system log entry.

  • ForceWrite: Controls how system level writes are handled. Configuration flag to always write non stale blocks for WriteAll, LoadConfig and setYaml.

  • InitAfterConfig: Configuration flag to execute initialize after LoadConfig or setYaml.

  • Time: Current time in seconds since EPOCH UTC.

  • LocalTime: Local time.

  • PollEn: Polling worker.

Root Class Documentation

See Root for generated API details.