HardwareManager
HardwareManager is the central orchestration layer that owns all live
HardwareObject instances for the active hardware loadout. It
marshals cross-thread hardware calls, fans out connection and sensor-data
notifications to the GUI and acquisition subsystem, and exposes the public
slot surface through which callers request hardware operations without
knowing which thread a given device lives on.
The manager lives on a dedicated QThread created by MainWindow
before the application event loop starts. MainWindow calls
initialize() via the thread’s started() signal; thereafter, the
manager and all its public slots run on that thread. Individual
HardwareObject instances may run on further per-device threads;
HardwareManager mediates all interaction with them through
QMetaObject::invokeMethod (blocking or queued as appropriate) so that
callers on any thread can request hardware operations safely. The static
HardwareManager::constInstance() accessor provides read-only access
to the hardware map from threads that cannot hold a direct reference.
Primary collaborators are HardwareObject (the managed devices),
RuntimeHardwareConfig (the source of truth for which profiles are
active), LoadoutManager (named hardware maps and FTMW presets),
ClockManager (RF clock subsystem, owned by this manager),
Experiment (populated and handed off via experimentInitialized()),
and AcquisitionManager (consumes the experiment lifecycle signals). The
user-facing hardware configuration workflow is described in
Hardware and Library Configuration and its sub-pages; Hardware-menu actions
are covered in Hardware Menu.
Hardware lifecycle
On startup initialize() calls syncWithRuntimeConfig(), which
consults RuntimeHardwareConfig and creates a
HardwareObject for each active profile via
HardwareRegistry. Objects whose d_threaded flag is set are
moved to their own QThread before initialization begins. At runtime the
loadout-switching flow calls applyHardwareMap() or
syncWithRuntimeConfig() to add, remove, or replace hardware objects
without restarting the application; each change is routed through the
internal addHardwareInternal / removeHardwareInternal /
replaceHardwareInternal helpers, which handle thread teardown and
connection cleanup automatically.
Signal surface grouped by purpose
Lifecycle and connection status
hwInitializationComplete() fires once, when the hardware map is first
populated and threads are started. allHardwareConnected(bool) fires after
every connection-test round (see testAll() and testObjectConnection()),
reporting whether all critical devices are connected. The unified
connectionResult(hwKey, success, msg) signal fires for every individual
status change — successful or failed connection test, runtime hardware
failure, hardware removal — so a single connection lets a consumer maintain a
complete picture of the current connection state without tracking each device
separately.
Experiment lifecycle
The acquisition subsystem connects to experimentInitialized(Experiment),
which carries the fully prepared experiment after initializeExperiment()
has configured clocks and called hwPrepareForExperiment() on each object.
beginAcquisition() and endAcquisition() are broadcast to all hardware
objects at acquisition start and end; abortAcquisition() is emitted when
a critical device reports failure during a run.
Auxiliary data fan-out
auxData(AuxDataMap), validationData(AuxDataMap), and
rollingData(AuxDataMap, QDateTime) aggregate sensor readings from all
hardware objects. Each hardware object emits keyed scalar readings;
HardwareManager prefixes each key with the object’s hardware key before
re-emitting, so consumers receive a flat map that is unambiguous across
multiple devices of the same type.
Hardware-type-specific data and control
For each optional hardware category, HardwareManager exposes a set of
type-specific signals carrying the hardware key of the source device as their
first argument. This pattern — one signal per reading type, distinguished by
hwKey — lets the GUI wire per-device widgets dynamically based on which
keys are present in the map, without enumerating every possible device. The
categories and representative signals are:
Pulse generators:
pGenSettingUpdate(hwKey, channel, setting, value)andpGenConfigUpdate(hwKey, config)for per-channel and whole-config updates.Flow controllers:
flowUpdate,flowSetpointUpdate,gasPressureUpdate,gasPressureSetpointUpdate, andgasPressureControlMode, all carrying the controller’s hardware key.Pressure controllers:
pressureUpdate,pressureSetpointUpdate, andpressureControlMode.Temperature controllers:
temperatureUpdateandtemperatureEnableUpdate, each carrying a channel index.
Clocks
clockFrequencyUpdate(type, freqMHz) and clockHardwareUpdate(type,
hwKey, output) propagate incremental changes from
ClockManager. allClocksReady(clocks) fires after
setClocks() completes the digitizer-gated frequency transition and is the
signal AcquisitionManager waits for before resuming the acquisition loop.
LIF
lifSettingsComplete(success) confirms that laser position and pulse delay
have been applied atomically. lifDigitizerShotAcquired(data) delivers raw
waveform samples from the LIF digitizer during configuration acquisition.
lifLaserPosUpdate(pos) and lifLaserFlashlampUpdate(enabled) relay
device state changes from the active LIF laser.
Communication protocol management
hardwareCommunicationInfoReady(hwKey, currentProtocol,
supportedProtocols, connected) answers a getHardwareCommunicationInfo()
request and drives the communication-settings UI described in
Hardware Menu. protocolSetResult(hwKey, success, msg)
confirms the outcome of setHardwareProtocol().
gpibControllersAvailable(controllerKeys) lists active GPIB controllers in
response to getActiveGpibControllers().
Python script hot-reload
pythonScriptReloadResult(hwKey, success, msg) reports the outcome of a
reloadPythonScript() request. Python-backed hardware and the hot-reload
workflow are described in Python Hardware.
Threading and synchronization
HardwareManager uses a multi-lock architecture: a read-write lock
(d_hardwareMapLock) protects the hardware map and allows concurrent
readers, while a separate mutex (d_connectionStateLock) protects
connection-test state without serializing on a single global lock. When
both locks must be held, the hardware-map lock is always acquired first.
Consult the per-member \brief blocks in the API reference below for
which routines acquire which lock and what each lock protects.
API Reference
-
class HardwareManager : public QObject, public SettingsStorage
Orchestration layer that owns all live HardwareObject instances, marshals cross-thread calls, and fans out connection and data notifications to the GUI and acquisition subsystem.
HardwareManager lives on a dedicated QThread created by MainWindow. Every HardwareObject it manages may live on its own further thread; HardwareManager mediates all communication via Qt’s queued-connection and QMetaObject::invokeMethod mechanisms so that callers on any thread can invoke hardware operations safely.
The manager’s public slot surface is the primary interface through which the GUI and AcquisitionManager request hardware operations. Its public signal surface is the source of all hardware-state notifications: connection results, sensor data, clock frequency updates, and experiment lifecycle events.
Hardware is loaded from RuntimeHardwareConfig on startup via initialize() and can be changed at runtime via syncWithRuntimeConfig() and applyHardwareMap(). The internal map d_hardwareMap is protected by d_hardwareMapLock; connection-test state is protected by the separate d_connectionStateLock to avoid holding the map lock during potentially long connection operations.
Public Functions
-
explicit HardwareManager(QObject *parent = 0)
Constructs HardwareManager and wires ClockManager; hardware objects are not created until initialize() is called.
-
~HardwareManager()
Destroys the manager, quitting and joining any per-hardware threads.
-
QString getHwName(const QString key)
Returns the display name string for the hardware identified by key.
- Parameters:
key – Hardware key of the form
"<Type>.<label>".- Returns:
The hardware object’s d_key field, or an empty string if not found.
-
void ensureRequiredSystemProfiles()
Creates any missing required-type system profiles and activates them in the runtime hardware config.
Safe to call from the main thread before the manager has been moved to its worker thread. Idempotent:
initialize()invokes the same two operations when the worker thread starts. The main-thread call exists so that GUI code which reads RuntimeHardwareConfig synchronously during startup (e.g. MainWindow::buildHardwareUI()) sees a healthy active map even when on-disk state was left in a stale “all deactivated” form by an older cancel-on-first-run path.
-
std::map<QString, QStringList, std::less<>> validationKeys() const
Returns the validation data keys reported by all hardware objects.
- Returns:
Map of hardware key → list of validation data keys.
-
void resolveGpibController(const QString &controllerKey, std::function<void(GpibController*)> callback) const
Resolves a GpibController by key and invokes callback with the result, holding the hardware map read-lock during the lookup.
The callback receives a pointer to the controller, or
nullptrif no controller with the given key exists. The callback is invoked synchronously on the calling thread while the read-lock is held; it must not attempt to acquire the write-lock.- Parameters:
controllerKey – Hardware key of the requested GpibController.
callback – Function called with the resolved controller pointer.
-
inline bool connectionTestsInProgress() const
Returns whether connection tests are currently in progress.
- Returns:
truewhile at least one hardware object has not yet responded to the most recent test round.
Public Members
-
std::set<QString> d_optHwTypes
Set of optional hardware type names recognized by storeAllOptHw().
Contains the class names (from
staticMetaObject.className()) of each optional hardware category: FlowController, IOBoard, PressureController, PulseGenerator, and TemperatureController.
Public Slots
-
void initialize()
Loads hardware from RuntimeHardwareConfig, starts per-hardware threads, and emits hwInitializationComplete() when the map is populated.
Called once by the owning QThread’s started() signal. Ensures system profiles exist, calls syncWithRuntimeConfig() to populate d_hardwareMap, and logs warnings for virtual instruments before emitting the completion signal.
-
void handleConnectionResult(const QString &hwKey, bool success, const QString &msg)
Records whether hardware connection was successful.
Invoked (typically via a queued connection) when a HardwareObject emits its
connectedsignal. Updates d_connectionState, emits connectionResult(), and calls checkStatus() to determine whether allHardwareConnected() should fire.- Parameters:
hwKey – Hardware key of the tested object.
success – Whether communication was successful.
msg – Error message; empty on success.
-
void hardwareFailure()
Handles a hardware failure signal from a previously connected device.
Disconnects the hardwareFailure connection so the signal is not re-processed, emits connectionResult() with
success=false, and — if the failing device is critical — emits abortAcquisition() to terminate any in-progress experiment.Note
The sender() is expected to be the HardwareObject that failed.
Warning
Consider generating an abort signal here for non-critical failures.
-
void sleep(bool b)
Puts all connected hardware objects to sleep or wakes them.
- Parameters:
b –
trueto sleep,falseto wake.
Prepares all hardware for the given experiment and emits experimentInitialized() when complete.
Configures clocks via ClockManager, calls hwPrepareForExperiment() on each HardwareObject (blocking across thread boundaries), and validates LIF hardware availability if the experiment requires it.
- Parameters:
exp – The experiment to initialize; d_hardwareSuccess is set on the object before the signal is emitted.
-
void experimentComplete()
Called when an experiment completes; reserved for post-experiment hardware teardown.
-
void testAll()
Triggers a connection test on every hardware object in the map.
-
void testObjectConnection(const QString hwKey)
Triggers a connection test on the hardware object identified by hwKey.
- Parameters:
hwKey – Hardware key to test.
-
void updateObjectSettings(const QString key)
Asks the hardware object identified by key to re-read its settings from QSettings.
- Parameters:
key – Hardware key of the object to update.
-
void getAuxData()
Polls all hardware objects for auxiliary data and accumulates the results into the auxData() signal.
-
QHash<RfConfig::ClockType, RfConfig::ClockFreq> getClocks()
Returns the current clock frequencies from ClockManager.
- Returns:
Map of clock roles to their current frequency descriptors.
-
void configureClocks(QHash<RfConfig::ClockType, RfConfig::ClockFreq> clocks)
Passes a desired clock configuration to ClockManager without applying it to hardware.
- Parameters:
clocks – Desired clock map.
-
void setClocks(QHash<RfConfig::ClockType, RfConfig::ClockFreq> clocks)
Applies a clock configuration to hardware, gating the FTMW digitizer during the transition, and emits allClocksReady() when done.
- Parameters:
clocks – Clock map with desired frequencies; actual achieved frequencies are written back into the map.
-
void setPGenSetting(const QString key, int index, PulseGenConfig::Setting s, QVariant val)
Sets a single channel setting on the pulse generator identified by key.
- Parameters:
key – Hardware key of the pulse generator.
index – Channel index.
s – Which setting to change.
val – New value.
-
void setPGenConfig(const QString key, const PulseGenConfig &c)
Applies a complete PulseGenConfig to the pulse generator identified by key.
- Parameters:
key – Hardware key of the pulse generator.
c – New configuration to apply.
-
PulseGenConfig getPGenConfig(const QString key)
Returns the current PulseGenConfig from the pulse generator identified by key.
- Parameters:
key – Hardware key of the pulse generator.
- Returns:
Current configuration; a default-constructed config if not found.
-
void setFlowSetpoint(const QString key, int index, double val)
Sets a flow-controller channel setpoint.
- Parameters:
key – Hardware key of the flow controller.
index – Channel index.
val – New setpoint.
-
void setFlowChannelName(const QString key, int index, QString name)
Renames a flow-controller channel.
- Parameters:
key – Hardware key of the flow controller.
index – Channel index.
name – New channel name.
-
void setFlowChannelEnabled(const QString key, int index, bool en)
Enables or disables a flow-controller channel.
- Parameters:
key – Hardware key of the flow controller.
index – Channel index.
en –
trueto enable the channel.
-
void setGasPressureSetpoint(const QString key, double val)
Sets the backing-gas pressure setpoint on a flow controller.
- Parameters:
key – Hardware key of the flow controller.
val – New setpoint.
-
void setGasPressureControlMode(const QString key, bool en)
Enables or disables pressure feedback control on a flow controller.
- Parameters:
key – Hardware key of the flow controller.
en –
trueto enable control.
-
FlowConfig getFlowConfig(const QString key)
Returns the current FlowConfig from the flow controller identified by key.
- Parameters:
key – Hardware key of the flow controller.
- Returns:
Current configuration; a default-constructed config if not found.
-
void setPressureSetpoint(const QString key, double val)
Sets the pressure setpoint on a pressure controller.
- Parameters:
key – Hardware key of the pressure controller.
val – New setpoint.
-
void setPressureControlMode(const QString key, bool en)
Enables or disables feedback control on a pressure controller.
- Parameters:
key – Hardware key of the pressure controller.
en –
trueto enable control.
-
void openGateValve(const QString key)
Commands the gate valve on a pressure controller to open.
- Parameters:
key – Hardware key of the pressure controller.
-
void closeGateValve(const QString key)
Commands the gate valve on a pressure controller to close.
- Parameters:
key – Hardware key of the pressure controller.
-
PressureControllerConfig getPressureControllerConfig(const QString key)
Returns the current PressureControllerConfig from the pressure controller identified by key.
- Parameters:
key – Hardware key of the pressure controller.
- Returns:
Current configuration; a default-constructed config if not found.
-
void setTemperatureChannelEnabled(const QString key, uint ch, bool en)
Enables or disables a temperature controller channel.
- Parameters:
key – Hardware key of the temperature controller.
ch – Channel index.
en –
trueto enable the channel.
-
void setTemperatureChannelName(const QString key, uint ch, const QString name)
Renames a temperature controller channel.
- Parameters:
key – Hardware key of the temperature controller.
ch – Channel index.
name – New channel name.
-
TemperatureControllerConfig getTemperatureControllerConfig(const QString key)
Returns the current TemperatureControllerConfig from the controller identified by key.
- Parameters:
key – Hardware key of the temperature controller.
- Returns:
Current configuration; a default-constructed config if not found.
-
IOBoardConfig getIOBoardConfig(const QString key)
Returns the current IOBoardConfig from the I/O board identified by key.
- Parameters:
key – Hardware key of the I/O board.
- Returns:
Current configuration; a default-constructed config if not found.
-
void storeAllOptHw(Experiment *exp, std::map<QString, bool, std::less<>> hw = {})
Reads the current state of all optional hardware types and stores the configs into exp.
Optional hardware types are those in d_optHwTypes. The hw map can selectively suppress reading individual keys by mapping them to
false.- Parameters:
exp – Experiment to populate; configs are appended via addOptHwConfig().
hw – Optional override map; keys absent from the map are read normally.
-
void setLifParameters(double delay, double pos)
Sets LIF laser position and pulse delay atomically, gating the LIF digitizer during the transition, and emits lifSettingsComplete().
- Parameters:
delay – Desired pulse delay for the LIF channel.
pos – Desired laser position.
-
bool setPGenLifDelay(double d)
Sets the LIF pulse delay on all active pulse generators.
- Parameters:
d – Desired delay.
- Returns:
trueif all pulse generators accepted the new delay.
-
bool setLifLaserPos(double pos)
Moves the LIF laser to the requested position.
- Parameters:
pos – Target position.
- Returns:
trueif the laser reported a non-negative achieved position.
-
void startLifConfigAcq(const LifConfig &c)
Starts configuration-mode acquisition on the LIF digitizer.
- Parameters:
c – LIF configuration describing the acquisition parameters.
-
void stopLifConfigAcq()
Stops configuration-mode acquisition on the LIF digitizer.
-
double lifLaserPos()
Returns the current LIF laser position.
- Returns:
Position in native units, or
-1.0if no laser is available.
-
bool lifLaserFlashlampEnabled()
Returns whether the LIF laser flashlamp is enabled.
- Returns:
trueif the flashlamp is active;falseif unavailable.
-
void setLifLaserFlashlampEnabled(bool en)
Enables or disables the LIF laser flashlamp.
- Parameters:
en –
trueto enable the flashlamp.
-
void getHardwareCommunicationInfo(const QString &hwKey)
Queries the communication protocol state of the hardware identified by hwKey and emits hardwareCommunicationInfoReady() with the result.
- Parameters:
hwKey – Hardware key of the device to query.
-
void setHardwareProtocol(const QString &hwKey, CommunicationProtocol::CommType protocol, const QString &gpibControllerKey = QString())
Changes the communication protocol for the hardware identified by hwKey and emits protocolSetResult() when complete.
- Parameters:
hwKey – Hardware key of the target device.
protocol – The protocol to switch to.
gpibControllerKey – Key of the GPIB controller to use; ignored unless protocol is GPIB.
-
void getActiveGpibControllers()
Enumerates all active GpibController objects and emits gpibControllersAvailable() with their keys.
-
bool allCriticalHardwareConnected() const
Returns whether all critical hardware objects are currently connected.
- Returns:
trueif every HardwareObject with d_critical set totruereports isConnected().
-
void syncWithRuntimeConfig()
Synchronizes d_hardwareMap with the current RuntimeHardwareConfig, adding, removing, or replacing hardware objects as needed.
-
void applyHardwareMap(const std::map<QString, QString, std::less<>> &map)
Applies an explicit hardware map, reconciling additions, removals, and replacements against the current d_hardwareMap.
- Parameters:
map – Target hardware map of
"<Type>.<label>"→ implementation keys.
-
bool applyVendorLibraryChanges()
Reapplies vendor library settings to all hardware objects whose driver depends on a runtime-configurable library.
- Returns:
trueif all affected objects accepted the updated library state.
-
void reloadPythonScript(const QString &hwKey)
Triggers a Python script hot-reload for the hardware identified by hwKey and emits pythonScriptReloadResult() when complete.
- Parameters:
hwKey – Hardware key of the Python-backed device to reload.
Signals
-
void statusMessage(QString msg, int timeout = 0)
Emitted to display a transient message in the status bar.
- Parameters:
msg – The message text.
timeout – Display duration in milliseconds; 0 means indefinite.
-
void hwInitializationComplete()
Emitted when all hardware objects have been constructed, threaded, and their initialization slots invoked — before any connection tests run.
-
void allHardwareConnected(bool success)
Emitted after every connection-test round to report whether all critical hardware responded successfully.
- Parameters:
success –
truewhen every critical HardwareObject is connected.
-
void connectionResult(const QString &hwKey, bool success, const QString &msg)
Unified signal for all connection status changes and test results.
Emitted by handleConnectionResult() when a hardware object reports a connection attempt outcome, by hardwareFailure() when a previously connected object signals failure, and by removeHardwareInternal() when an object is removed from the map. Consumers can use this single signal to maintain a current connection-status view across the entire hardware set.
- Parameters:
hwKey – Hardware key (e.g.,
"FtmwDigitizer.main").success –
trueif the connection is now active.msg – Human-readable status or error message; may be empty.
-
void profileDeleted(const QString &hwKey)
Emitted when a hardware profile is permanently deleted (not just deactivated) and its settings have been purged.
- Parameters:
hwKey – The hardware key whose profile was removed.
-
void hardwareCommunicationInfoReady(const QString &hwKey, CommunicationProtocol::CommType currentProtocol, QVector<CommunicationProtocol::CommType> supportedProtocols, bool connected)
Emitted in response to getHardwareCommunicationInfo() with the current and supported communication protocols for a device.
- Parameters:
hwKey – Hardware key of the queried device.
currentProtocol – The protocol currently in use.
supportedProtocols – All protocols the device implementation supports.
connected – Whether the device is currently connected.
-
void protocolSetResult(const QString &hwKey, bool success, const QString &msg)
Emitted after setHardwareProtocol() completes to report whether the protocol change succeeded.
- Parameters:
hwKey – Hardware key of the affected device.
success –
trueif the protocol was changed and reconnected.msg – Diagnostic message; empty on success.
-
void gpibControllersAvailable(QStringList controllerKeys)
Emitted by getActiveGpibControllers() with the keys of all GpibController objects currently in the hardware map.
- Parameters:
controllerKeys – List of hardware keys for available GPIB controllers.
-
void beginAcquisition()
Broadcast to all HardwareObjects to enter acquisition mode.
-
void abortAcquisition()
Broadcast to all HardwareObjects to abort the current acquisition.
Emitted after initializeExperiment() has prepared all hardware and the Experiment object is ready for the acquisition loop to start.
- Parameters:
exp – The prepared experiment, shared with AcquisitionManager.
-
void endAcquisition()
Broadcast to all HardwareObjects to exit acquisition mode.
-
void auxData(AuxDataStorage::AuxDataMap data)
Emitted when any hardware object reads auxiliary (non-rolling) data; keys are prefixed with the hardware key of the source object.
- Parameters:
data – Map of keyed scalar values.
-
void validationData(AuxDataStorage::AuxDataMap data)
Emitted with the same data as auxData() for validation tracking.
- Parameters:
data – Map of keyed scalar values.
-
void rollingData(AuxDataStorage::AuxDataMap data, QDateTime timestamp)
Emitted when any hardware object reads rolling (time-series) auxiliary data; keys are prefixed with the hardware key of the source.
- Parameters:
data – Map of keyed scalar values.
timestamp – Acquisition timestamp for the data point.
-
void clockFrequencyUpdate(RfConfig::ClockType type, double freqMHz)
Emitted when a single clock frequency changes during an experiment (e.g., a sweep step).
- Parameters:
type – The clock role that changed.
freqMHz – New frequency in MHz.
-
void clockHardwareUpdate(RfConfig::ClockType type, const QString &hwKey, int output)
Emitted when the hardware assignment for a clock role changes.
- Parameters:
type – The clock role.
hwKey – Key of the clock hardware now serving this role.
output – Hardware output index used for this role.
-
void allClocksReady(QHash<RfConfig::ClockType, RfConfig::ClockFreq> clocks)
Emitted by setClocks() after all requested clock frequencies have been applied and the digitizer ungated.
- Parameters:
clocks – Map of clock roles to their final frequency descriptors.
-
void pGenSettingUpdate(QString hwKey, int channel, PulseGenConfig::Setting setting, QVariant value)
Emitted when a single pulse-generator channel setting changes.
- Parameters:
hwKey – Hardware key of the pulse generator.
channel – Channel index.
setting – Which setting changed.
value – New value.
-
void pGenConfigUpdate(QString hwKey, PulseGenConfig config)
Emitted when the entire pulse generator configuration is updated.
- Parameters:
hwKey – Hardware key of the pulse generator.
config – New full configuration.
-
void flowUpdate(QString hwKey, int channel, double value)
Emitted when a flow-controller channel flow reading changes.
- Parameters:
hwKey – Hardware key of the flow controller.
channel – Channel index.
value – Flow reading in the controller’s native units.
-
void flowSetpointUpdate(QString hwKey, int channel, double value)
Emitted when a flow-controller channel setpoint changes.
- Parameters:
hwKey – Hardware key of the flow controller.
channel – Channel index.
value – New setpoint in the controller’s native units.
-
void flowChannelEnableUpdate(QString hwKey, int channel, bool enabled)
Emitted when a flow-controller channel is enabled or disabled.
- Parameters:
hwKey – Hardware key of the flow controller.
channel – Channel index.
enabled –
trueif the channel is active.
-
void gasPressureUpdate(QString hwKey, double value)
Emitted when the backing-gas pressure reading from a flow controller changes.
- Parameters:
hwKey – Hardware key of the flow controller.
value – Pressure reading.
-
void gasPressureSetpointUpdate(QString hwKey, double value)
Emitted when the backing-gas pressure setpoint changes.
- Parameters:
hwKey – Hardware key of the flow controller.
value – New setpoint.
-
void gasPressureControlMode(QString hwKey, bool enabled)
Emitted when the backing-gas pressure control mode changes.
- Parameters:
hwKey – Hardware key of the flow controller.
enabled –
trueif pressure feedback control is active.
-
void pressureControlReadOnly(QString hwKey, bool readOnly)
Emitted when the pressure controller becomes read-only (e.g., during an experiment).
- Parameters:
hwKey – Hardware key of the pressure controller.
readOnly –
trueif write operations are disabled.
-
void pressureUpdate(QString hwKey, double value)
Emitted when the pressure reading from a dedicated pressure controller changes.
- Parameters:
hwKey – Hardware key of the pressure controller.
value – Pressure reading.
-
void pressureSetpointUpdate(QString hwKey, double value)
Emitted when the pressure setpoint changes.
- Parameters:
hwKey – Hardware key of the pressure controller.
value – New setpoint.
-
void pressureControlMode(QString hwKey, bool enabled)
Emitted when the pressure control mode changes.
- Parameters:
hwKey – Hardware key of the pressure controller.
enabled –
trueif feedback control is active.
-
void temperatureUpdate(QString hwKey, uint channel, double value)
Emitted when a temperature channel reading changes.
- Parameters:
hwKey – Hardware key of the temperature controller.
channel – Channel index.
value – Temperature reading.
-
void temperatureEnableUpdate(QString hwKey, uint channel, bool enabled)
Emitted when a temperature channel is enabled or disabled.
- Parameters:
hwKey – Hardware key of the temperature controller.
channel – Channel index.
enabled –
trueif the channel is active.
-
void lifDigitizerShotAcquired(QVector<qint8> data)
Emitted when the LIF digitizer acquires a single shot waveform during configuration acquisition.
- Parameters:
data – Raw 8-bit waveform samples.
-
void lifSettingsComplete(bool success = true)
Emitted when LIF hardware setup (laser position, pulse delay, digitizer gate) is complete.
- Parameters:
success –
trueif all LIF hardware accepted the requested parameters.
-
void lifLaserPosUpdate(double pos)
Emitted when the LIF laser reports a new position.
- Parameters:
pos – Laser position in the controller’s native units.
-
void lifConfigAcqStarted()
Emitted when the LIF digitizer completes configuration acquisition and the system is ready to begin data collection.
-
void lifLaserFlashlampUpdate(bool enabled)
Emitted when the LIF laser flashlamp enable state changes.
- Parameters:
enabled –
trueif the flashlamp is active.
-
void pythonScriptReloadResult(const QString &hwKey, bool success, const QString &msg)
Emitted after reloadPythonScript() completes for a Python-backed hardware object.
- Parameters:
hwKey – Hardware key of the reloaded device.
success –
trueif the script was reloaded and the object re-initialized successfully.msg – Diagnostic message; empty on success.
Public Static Functions
-
static const HardwareManager &constInstance()
Returns the single live instance for const (read-only) hardware resolution from any thread.
This static accessor allows code that cannot hold a reference to the manager (e.g., hardware objects themselves resolving GPIB controllers) to reach the map without acquiring any write-capable handle. Callers must not store the reference beyond the current call stack; the instance is valid only for the application lifetime.
Warning
Throws std::runtime_error if called before the first HardwareManager is constructed.
- Returns:
Const reference to the HardwareManager singleton.
Private Functions
-
void checkStatus()
Checks whether all hardware has responded and emits allHardwareConnected() if so.
-
void initializeConnectionTesting()
Initializes d_connectionState for a new test round.
-
void resetConnectionTestState()
Resets d_connectionState without marking a new round as open.
-
void finalizeConnectionTesting()
Marks the current test round as complete.
-
void setupHardwareObject(HardwareObject *obj)
Wires common signal connections from obj to the manager.
-
HardwareObject *createSpecificHardware(const QString &type, const QString &implementation, const QString &label)
Creates a HardwareObject of the given type, implementation, and label via HardwareRegistry.
- Parameters:
type – Hardware type class name.
implementation – Implementation key.
label – User-assigned label.
- Returns:
Newly created object, or
nullptron failure.
-
void removeHardwareInternal(const QString &hwKey)
Removes the hardware object identified by hwKey from the map, disconnects its connections, and cleans up its thread.
-
void addHardwareInternal(const QString &hwKey, const QString &implementation)
Creates and installs the hardware object for hwKey using implementation.
-
void replaceHardwareInternal(const QString &hwKey, const QString &newImplementation)
Replaces the hardware object for hwKey with one built from newImplementation.
-
std::vector<QString> findHardwareToRemove(const std::map<QString, QString, std::less<>> &targetHardware)
Returns the set of hardware keys in d_hardwareMap that are absent from targetHardware and should be removed.
-
std::vector<std::pair<QString, QString>> findHardwareToAdd(const std::map<QString, QString, std::less<>> &targetHardware)
Returns hardware key / implementation pairs present in targetHardware but absent from d_hardwareMap and should be added.
-
std::vector<std::pair<QString, QString>> findHardwareToReplace(const std::map<QString, QString, std::less<>> &targetHardware)
Returns hardware key / implementation pairs whose implementation has changed and should be replaced.
-
void resolveGpibControllersForInstruments()
Ensures every GPIB-dependent instrument has its controller resolved after a sync cycle.
-
void updateClockManager()
Notifies ClockManager of any changes to the set of clock hardware objects after a sync cycle.
-
void addLibraryDependentHardwareToRecreation(const std::map<QString, QString, std::less<>> &targetHardware, std::vector<QString> &toRemove, std::vector<std::pair<QString, QString>> &toAdd, std::vector<std::pair<QString, QString>> &toReplace)
Adds hardware objects whose vendor library configuration has changed to the removal / addition / replacement lists so they are recreated with the new library state.
-
void storeConnection(const QString &hwKey, const QMetaObject::Connection &connection)
Stores a Qt connection handle keyed by hwKey so it can be cleanly disconnected when the object is removed.
-
void setupHardwareObjectWithTracking(HardwareObject *obj)
Wires common signal connections for obj and stores each connection handle in d_hardwareConnections.
-
void setupHardwareSpecificConnectionsWithTracking(HardwareObject *obj)
Wires hardware-type-specific signal connections for obj and stores each handle in d_hardwareConnections.
-
void disconnectStoredConnections(const QString &hwKey)
Disconnects and removes all stored connections for hwKey.
-
template<class T>
inline T *findHardware(const QString key) const Locates a hardware object by exact key and casts it to
T*.Acquires a read lock on d_hardwareMapLock for the duration of the map lookup. Returns
nullptrif the key is absent or the cast fails.- Template Parameters:
T – Target HardwareObject subtype.
- Parameters:
key – Hardware key to look up.
- Returns:
Pointer to the cast object, or
nullptr.
-
template<class T>
inline QVector<T*> findHardwareByType() const Returns all hardware objects of type
Tcurrently in the map.Acquires a read lock on d_hardwareMapLock and iterates the entire map, comparing each entry’s type prefix against
T::staticMetaObject.className(). Uses qobject_cast for safety; entries that fail the cast are skipped.- Template Parameters:
T – Target HardwareObject subtype.
- Returns:
Vector of all matching objects in map-iteration order.
Private Members
-
ConnectionTestState d_connectionState
-
std::map<QString, HardwareObject*, std::less<>> d_hardwareMap
Live map from hardware key to owning HardwareObject pointer.
Protected by d_hardwareMapLock. Keys use the
"<Type>.<label>"format defined by BC::Key::parseKey().
-
std::map<QString, QVector<QMetaObject::Connection>, std::less<>> d_hardwareConnections
Per-hardware-key lists of stored Qt connection handles used for clean disconnection when objects are removed dynamically.
Accessed only on the HardwareManager thread (by storeConnection, setupHardwareObjectWithTracking, and disconnectStoredConnections); not protected by d_hardwareMapLock or any other lock.
-
std::unique_ptr<ClockManager> pu_clockManager
Clock subsystem manager; owned by HardwareManager, lives on the same thread.
-
mutable QReadWriteLock d_hardwareMapLock
Read-write lock protecting d_hardwareMap.
Readers (findHardware, findHardwareByType, checkStatus, validationKeys, resolveGpibController, getActiveGpibControllers, allCriticalHardwareConnected, testAll, testObjectConnection) acquire a read lock; writers (addHardwareInternal, removeHardwareInternal) acquire a write lock. storeAllOptHw acquires a read lock indirectly via the findHardware-based accessors it calls.
-
mutable QMutex d_connectionStateLock
Mutex protecting d_connectionState.
Held briefly while updating responseCount and testsInProgress; never held at the same time as d_hardwareMapLock to prevent deadlocks.
Private Static Attributes
-
static HardwareManager *s_instance = nullptr
Raw pointer to the single live instance, set in the constructor and cleared in the destructor, used by constInstance().
-
struct ConnectionTestState
Tracks the progress of a connection-test round using lock-free atomic counters.
reset() opens a new test round; recordResponse() counts each hardware object that reports back; allResponded() returns
truewhen the count equals the expected number; markComplete() closes the round. Access to this struct is serialized by d_connectionStateLock.Public Functions
-
inline void reset()
Begins a new test round, resetting the response counter.
-
inline void recordResponse()
Records one hardware response.
-
inline bool allResponded(size_t expected) const
Returns
trueif expected responses have been received.
-
inline void markComplete()
Marks the round as complete.
-
inline void reset()
-
explicit HardwareManager(QObject *parent = 0)