Measurement graph¶
MGraph connects logical measurement positions, device instances,
frequency-dependent conditions, switching actions, and path corrections.
New applications should pass an explicit condition context and disable the
caller-frame compatibility fallback.
The bilingual German and English DOT references explain file syntax, attributes, condition contexts, persistence, and validation workflows.
- class mpylab.tools.mgraph.MGraph(fname_or_data=None, themap=None, SearchPaths=None, condition_map=None, allow_legacy_condition_context=True)¶
Represent devices, paths, and conditions in a measurement graph.
- Parameters:
fname_or_data (path-like, file-like, str, pydot.Dot, or object) – Graph input accepted by
Graph.themap (Mapping[str, str], optional) – Mapping from logical application names to physical DOT node names.
SearchPaths (sequence of path-like or path-like, optional) – Directories searched for graph, INI, driver, and data files.
condition_map (Mapping[str, str], optional) – Mapping from variable names used in DOT conditions to application-side condition names.
allow_legacy_condition_context (bool, optional) – Permit condition variables to be resolved from legacy outer-frame context when no explicit value was supplied.
- ApplyContext(context, doAction=True, set_frequency=True, force_controllers=False)¶
Apply logical conditions and declared hardware controllers.
Context-controller nodes opt in through the DOT attribute
context_controller. Their drivers plan, apply, and read back the concrete hardware state while callers provide only logical values.- Parameters:
context (mapping) – Application-level condition values.
doAction (bool, optional) – Execute compatible DOT actions while conditions are evaluated.
set_frequency (bool, optional) – Call
SetFreq_Devices()when the context contains the mapped frequency value.force_controllers (bool, optional) – Reapply controllers even when their declared context keys did not change. Intended for explicit recovery after user confirmation.
- Returns:
Applied context, frequency result, and controller read-back.
- Return type:
- CheckContextState()¶
Verify that physical context controllers still match the graph.
- Returns:
Current controller states indexed by physical graph node.
- Return type:
dict
- Raises:
GraphStateMismatchError – If read-back fails or a controller differs from its expected state. RF is switched off before the exception is raised.
- CreateDevices()¶
Create and configure device instances represented by graph nodes.
This method initializes node activity, reads referenced INI files, and stores each instantiated driver in
nodes[name]['inst']. It should normally be called once after constructing the graph.- Returns:
Mapping from physical graph node names to device instances.
- Return type:
DictObj
- EvaluateConditions(doAction=True, context=None)¶
Evaluate node and edge conditions and update their active state.
context contains application-level names.
condition_mapmaps names used in DOT expressions to those application names. If context is omitted, caller-frame lookup remains available as a deprecated compatibility fallback.- Parameters:
doAction (bool, optional) – Execute actions associated with condition state changes.
context (mapping, optional) – Application-level values used to resolve DOT conditions.
- Init_Devices(IgnoreInactive=True)¶
Initialize selected graph devices.
- Parameters:
IgnoreInactive (bool, optional) – If
True, initialize only active devices. IfFalse, include inactive devices as well.- Returns:
Sum of device status codes.
- Return type:
int
- Raises:
UserWarning – If a device fails to initialize.
- PollContextState(interval=0.5, force=False)¶
Poll declared context controllers at a bounded rate.
- Parameters:
interval (float, optional) – Minimum seconds between hardware queries.
force (bool, optional) – Query immediately regardless of the previous poll time.
- Returns:
Last or newly read controller states.
- Return type:
dict
- Quit_Devices(IgnoreInactive=True)¶
Quit selected devices using
CmdDevices().- Parameters:
IgnoreInactive (bool, optional) – If
True, quit only active devices. IfFalse, include inactive devices as well.- Returns:
Sum of device status codes.
- Return type:
int
- RFOff_Devices(IgnoreInactive=True)¶
Disable RF output on selected devices.
- Parameters:
IgnoreInactive (bool, optional) – If
True, disable only active devices. IfFalse, include inactive devices as well.- Returns:
Sum of device status codes.
- Return type:
int
- RFOn_Devices(IgnoreInactive=True)¶
Enable RF output on selected devices.
- Parameters:
IgnoreInactive (bool, optional) – If
True, enable only active devices. IfFalse, include inactive devices as well.- Returns:
Sum of device status codes.
- Return type:
int
- ReapplyContext()¶
Reapply the stored context after explicit recovery approval.
- Returns:
Reapplied context, frequency result, and controller read-back.
- Return type:
- Raises:
GraphContextError – If the measurement graph has no stored context or a context controller cannot apply it.
GraphStateMismatchError – If a controller’s physical state differs from the reapplied context. RF is switched off before the exception is raised.
- SetFreq_Devices(freq, IgnoreInactive=True)¶
Set the frequency on selected devices.
- Parameters:
freq (Quantity or float) – Requested frequency in the representation accepted by each driver.
IgnoreInactive (bool, optional) – If
True, configure only active devices. IfFalse, include inactive devices as well.
- Returns:
Minimum and maximum frequencies reported by capable devices.
- Return type:
tuple
- static apply_path_correction(value, correction, *, operation='divide', magnitude=True, output_unit=None)¶
Apply a path correction while preserving SCUQ semantics.
Exactly known ratio corrections use a constant-scaling fast path. Uncertain or otherwise unsupported inputs automatically use the full SCUQ expression implementation.
- Parameters:
value (scuq.quantities.Quantity) – Measured value to which the path correction is applied.
correction (scuq.quantities.Quantity or mpylab.tools.quantity_uncertainty.PreparedRatioCorrection) – Ratio correction, or a correction prepared by
prepare_path_correction(). When a prepared correction is supplied, its stored operation, magnitude setting, and output unit are used.operation (str) – Apply an unprepared correction by
"divide"(default) or"multiply". This argument is ignored when correction is already prepared.magnitude (bool) – If true (default), return the magnitude after applying an unprepared correction. If false, preserve phase. This argument is ignored when correction is already prepared.
output_unit (scuq.units.Unit or None) – Optional unit to which the corrected value is reduced. This argument is ignored when correction is already prepared.
- Returns:
Corrected measurement value.
- Return type:
scuq.quantities.Quantity
- Raises:
TypeError – If value or an unprepared correction is not a SCUQ quantity.
ValueError – If operation is neither
"divide"nor"multiply", or the requested correction or unit conversion is invalid.
- capture_configuration_snapshot(*, strict_ambiguity=False, reject_credentials=True, max_resource_bytes=None, max_total_bytes=None)¶
Capture the graph and every resolved configuration resource.
The method is hardware-independent.
CreateDevices()must have run so that node INI files are resolved, butInit_Devices()need not and should not run before a production snapshot is captured.- Parameters:
strict_ambiguity (bool, optional) – Reject references with more than one search-path candidate. The compatibility default records all candidates and captures the same first match used by the runtime resolver.
reject_credentials (bool, optional) – Reject probable credentials while permitting ordinary instrument bus and network addresses.
max_resource_bytes (int or None, optional) – Maximum bytes captured from one resource.
Noneselects the maintained default.max_total_bytes (int or None, optional) – Maximum bytes captured from all unique resources.
Noneselects the maintained default.
- Returns:
Versioned snapshot with exact file content, hashes, and reference relationships.
- Return type:
dict
- Raises:
mpylab.tools.configuration_snapshot.ConfigurationSnapshotError – If complete configuration evidence cannot be captured safely.
RuntimeError – If
CreateDevices()has not resolved the node INI files.
- check_paths(start, end, parameter, *, values=None, start_value=None, stop_value=None, context=None, mode='exactly_one_path')¶
Check condition-controlled paths over a parameter range.
Simple comparison boundaries involving parameter are checked at the boundary itself and at the immediately adjacent floating-point values. Explicit values are checked as well. For more complex parameter expressions,
GraphPathCheckReport.boundary_analysis_completeis false because only the supplied values can be sampled.- Parameters:
start (str) – Start node of the checked path.
end (str) – End node of the checked path.
parameter (str) – Application-level parameter varied by the check.
values (iterable of float, optional) – Explicit parameter values to check.
start_value (float, optional) – Lower boundary of the checked range.
stop_value (float, optional) – Upper boundary of the checked range.
context (mapping, optional) – Fixed application-level condition values.
mode ({"exactly_one_path", "warn_parallel"}, optional) – Classification policy for multiple active paths.
- Returns:
Structured results at explicit and detected critical values.
- Return type:
- get_path_correction(start, end, unit=None)¶
Return the total active path correction from
starttoend.- Parameters:
start (str) – Start node or mapped instrumentation name.
end (str) – End node or mapped instrumentation name.
unit (scuq.units.Unit, optional) –
AMPLITUDERATIOorPOWERRATIO. Amplitude ratio is the default.
- Returns:
Coherent total S21 amplitude, or its real squared magnitude.
- Return type:
scuq.quantities.Quantity
- Raises:
TypeError – If the requested unit or a device quantity has an invalid type.
ValueError – If no active connection exists, a unit is unsupported, or a transfer value is invalid.
ZeroDivisionError – If an inverse or common-parent correction divides by zero.
Notes
Products along paths, sums of parallel paths, and reference ratios are formed as complex amplitudes before power conversion. Reversing a correction means inversion, not the physical reverse S12.
- get_path_corrections(start, end, unit=None)¶
Return individual and total corrections from
starttoend.- Parameters:
start (str) – Start node or mapped instrumentation name.
end (str) – End node or mapped instrumentation name.
unit (scuq.units.Unit, optional) –
AMPLITUDERATIOorPOWERRATIO. Amplitude ratio is the default.
- Returns:
Original device quantities keyed by device name;
"total"contains the coherent amplitude sum or its real squared magnitude in the requested unit. With no active forward path, the total is zero. If a device supplies multiple channels, its last visited channel remains the diagnostic entry.- Return type:
dict
- Raises:
TypeError – If the requested unit or a device quantity has an invalid type.
ValueError – If a unit or transfer value is invalid.
UserWarning – If a correction channel cannot be read.
Notes
Device/channel values are read once per query and reused on shared segments. SCUQ input dependencies are retained across paths. This coherent forward-transfer model does not solve multiple reflections or infer splitter/combiner coefficients.
- static prepare_path_correction(correction, *, operation, magnitude, output_unit=None)¶
Prepare an invariant path correction for repeated application.
Preparation analyzes the correction once. An exact ratio correction can subsequently use constant scaling when magnitude output and an explicit output unit are requested. All other cases retain the full SCUQ calculation.
- Parameters:
correction (scuq.quantities.Quantity) – Amplitude- or power-ratio correction to prepare.
operation (str) – Apply the correction by
"divide"or"multiply". This keyword argument is required so that the correction direction is selected explicitly.magnitude (bool) – If true, return magnitudes when the prepared correction is applied. If false, preserve phase. This keyword argument is required so that discarding phase is explicit.
output_unit (scuq.units.Unit or None) – Optional unit to which corrected values are reduced.
- Returns:
Reusable correction containing the analyzed fast-path properties and all application options.
- Return type:
mpylab.tools.quantity_uncertainty.PreparedRatioCorrection
- Raises:
TypeError – If correction is not a SCUQ quantity.
ValueError – If operation is neither
"divide"nor"multiply".
Reuse the returned object only while the graph path, frequency, active conditions, and relevant calibration data remain unchanged.
Configuration evidence¶
- mpylab.tools.configuration_snapshot.capture_measurement_graph_snapshot(graph, *, strict_ambiguity: bool = True, reject_credentials: bool = True, max_resource_bytes: int | None = 67108864, max_total_bytes: int | None = 268435456) dict¶
Capture the files defining a prepared measurement graph.
- Parameters:
graph (mpylab.tools.mgraph.MGraph) – Graph whose
CreateDevices()method has resolved its node INI files. No device initialization is performed by this function.strict_ambiguity (bool, optional) – Reject a reference when multiple search-path candidates exist.
reject_credentials (bool, optional) – Reject high-confidence credential fields and private-key material. Ordinary VISA, GPIB, serial, and network addresses are not rejected.
max_resource_bytes (int or None, optional) – Maximum size of one resource.
Nonedisables the individual limit.max_total_bytes (int or None, optional) – Maximum combined size of unique resources.
Nonedisables the total limit.
- Returns:
Versioned, pickle-friendly snapshot containing exact resource bytes, hashes, and reference relationships.
- Return type:
dict
- Raises:
ConfigurationSnapshotError – If a resource is missing, ambiguous, unreadable, too large, or appears to contain credentials.
RuntimeError – If graph devices have not yet been created and their INI paths are therefore unresolved.
- mpylab.tools.configuration_snapshot.verify_measurement_graph_snapshot(snapshot: dict) None¶
Verify all resource hashes and the configuration digest.
- Parameters:
snapshot (mapping) – Measurement-graph snapshot returned by
capture_measurement_graph_snapshot().- Raises:
ConfigurationSnapshotError – If the schema is unsupported or stored content does not match its recorded resource or configuration digest.
- mpylab.tools.configuration_snapshot.compare_measurement_graph_snapshots(expected: dict, actual: dict) dict¶
Compare two verified measurement-graph snapshots.
- Parameters:
expected (mapping) – Snapshots to compare. Their embedded hashes are verified first.
actual (mapping) – Snapshots to compare. Their embedded hashes are verified first.
- Returns:
Equality flag plus added and removed resources and changes to graph settings or reference relationships.
- Return type:
dict
- Raises:
ConfigurationSnapshotError – If either snapshot fails verification.
- mpylab.tools.configuration_snapshot.extract_measurement_graph_snapshot(snapshot: dict, destination, *, overwrite: bool = False) dict¶
Extract a verified snapshot without initializing measurement devices.
- Parameters:
snapshot (mapping) – Snapshot to verify and extract.
destination (path-like) – Directory receiving DOT, INI, data, and custom-driver files. Inline data remain embedded in their original INI content.
overwrite (bool, optional) – Replace existing files. By default, an existing file with different content aborts extraction.
- Returns:
Mapping from resource identifiers to their primary extracted path. Every safe logical alias is materialized; inline resources map to
Nonebecause the INI already contains them.- Return type:
dict
- Raises:
ConfigurationSnapshotError – If verification fails, logical names collide, or a target file exists with different content and
overwriteis false.OSError – If the destination cannot be created or written.
- class mpylab.tools.configuration_snapshot.ConfigurationSnapshotError¶
Raised when complete measurement-graph configuration evidence cannot be captured.
Explicit context results and errors¶
- class mpylab.tools.mgraph.GraphContextResult(context: dict[str, object], frequency_result: object = None, expected_controller_states: dict[str, object] = <factory>, actual_controller_states: dict[str, object] = <factory>)¶
Result of applying a logical context to a measurement graph.
- class mpylab.tools.mgraph.GraphContextError¶
Raised when a graph context cannot be applied to its controllers.
- class mpylab.tools.mgraph.GraphStateMismatchError(mismatches)¶
Raised when physical controller state differs from graph context.
- Parameters:
mismatches (Mapping[str, Mapping[str, object]]) – Expected and observed states indexed by controller node name.
Graph validation¶
- class mpylab.tools.mgraph.GraphPathCheckPoint(value: float, paths: tuple[tuple[str, ...], ...], active_branches: tuple[tuple[str, tuple[str, ...]], ...] = (), condition_errors: tuple[str, ...] = ())¶
Path-selection result for one parameter value.
- property status¶
Return the most severe path-selection outcome at this value.
- class mpylab.tools.mgraph.GraphPathCheckReport(start: str, end: str, parameter: str, mode: str, results: list[GraphPathCheckPoint] = <factory>, critical_values: tuple[float, ...]=(), boundary_analysis_complete: bool = True)¶
Structured result returned by
MGraph.check_paths().- property errors¶
Return path-check points classified as errors in this mode.
- format_text()¶
Return a compact human-readable validation report.
- Returns:
Multi-line graph path validation summary.
- Return type:
str
- property ok¶
Whether the report contains no path-selection errors.
- property warnings¶
Return path-check points classified as warnings in this mode.
- class mpylab.tools.mgraph.GraphInputError¶
Raised when a measurement graph input cannot be loaded or parsed.
- class mpylab.tools.mgraph.GraphValidationError¶
Raised when measurement-graph references are semantically invalid.
- class mpylab.tools.mgraph.ConditionContextError¶
Raised when a condition variable cannot be resolved explicitly.
- class mpylab.tools.mgraph.LegacyConditionContextWarning¶
Warn that condition variables were resolved from the caller frame.
Leveling¶
- class mpylab.tools.mgraph.LevelingResult(status: str, applied_level: Quantity, observed_value: Quantity, target_value: Quantity, relative_error: float, iterations: int, limited_by_amplifier_protection: bool = False, reason: str = '')¶
Machine-readable outcome of
Leveler.adjust_level().- as_dict()¶
Return a serialization-friendly representation.
- Returns:
Leveling outcome and all diagnostic fields.
- Return type:
dict
- property converged¶
Whether the leveler reached the requested target tolerance.
- class mpylab.tools.mgraph.LevelingDeviceError¶
Raised when a device operation fails during graph-based leveling.
- class mpylab.tools.mgraph.LevelingDataError¶
Raised when graph-based leveling receives unusable numeric data.
The graph guide explains switched paths and correction semantics in Conditions, switching matrix, and path corrections.