Eigene Messklassen entwickeln¶
Eine Messklasse beschreibt den fachlichen Ablauf einer Messung. Sie koordiniert MGraph, Geräte, Messpunkte, Autosave und Auswertung, enthält aber keine gerätespezifischen SCPI-Befehle und keine Qt-Widgets.
Von Measure erben¶
from mpylab.env.Measure import Measure
class ExampleMeasurement(Measure):
def __init__(self, SearchPaths=None):
super().__init__(SearchPaths=SearchPaths)
self.raw_data = {}
self.processed_data = {}
Measure stellt Logging, Bedienerinteraktion, Autosave,
Geräteinitialisierung, RF-Off und Pickle-Wiederherstellung bereit. Neue
Klassen sollten diese Infrastruktur verwenden, statt eigene Varianten davon
einzuführen.
Messablauf¶
Ein robuster Ablauf hat folgende Form:
Datensatz und Wiederanlaufinformation vorbereiten.
MGraphmit Namen- und Condition-Mapping erzeugen.Geräte erstellen und über
_init_measurement_devicesinitialisieren.Den logischen Graph-Context vor jedem frequenzabhängigen Zugriff explizit anwenden. Für Graphen ohne physischen Controller genügt weiterhin die ausdrückliche Condition-Auswertung.
Nur vollständig gemessene Punkte in die Ergebnisstruktur übernehmen.
Regelmäßig
do_autosaveaufrufen.In einem
finally-Pfad RF abschalten und Geräte beenden.
Die gemeinsame Finalisierung erfolgt über
_finalize_measurement_devices. Fehler beim Messen dürfen diesen
Sicherheitspfad nicht überspringen.
Expliziten Graph-Context anwenden¶
Eigene Messanwendungen sollten Frequenz, Betriebsart und vergleichbare
fachliche Größen gemeinsam an MGraph.ApplyContext übergeben. Dadurch
bleiben Condition-Auswertung, Frequenzeinstellung, physische Umschaltung und
Rücklesekontrolle eine zusammenhängende Operation:
from mpylab.tools.mgraph import (
GraphStateMismatchError,
MGraph,
TEM_CONDITION_MAP,
)
graph = MGraph(
dotfile,
themap=names,
SearchPaths=search_paths,
condition_map=TEM_CONDITION_MAP,
allow_legacy_condition_context=False,
)
graph.CreateDevices()
graph.Init_Devices()
requested_context = {"frequency": frequency, "mode": "GTEM"}
try:
context_result = graph.ApplyContext(requested_context)
except GraphStateMismatchError as error:
# MGraph hat RF bereits abgeschaltet. Die Anwendung protokolliert
# error.mismatches und fragt den Bediener nach einer Entscheidung.
if not operator_explicitly_selected_reapply(error.mismatches):
raise
graph.ReapplyContext()
context_result = graph.ApplyContext(requested_context)
GraphStateMismatchError.mismatches enthält je Controller den erwarteten
und den gelesenen Zustand sowie gegebenenfalls Status- oder Abfragefehler.
Die Anwendung soll diese Information protokollieren und in ihrer CLI oder
Oberfläche neutral anzeigen. Sie darf keinen gerätespezifischen Relaiszustand
interpretieren; diese Fachkenntnis bleibt im Controller-Treiber.
Bei einer Abweichung hat MGraph bereits graphweit RFOff ausgeführt.
Abbrechen ist deshalb die sichere Standardentscheidung. Nur eine
ausdrückliche Bedienerwahl darf zuerst mit ReapplyContext den zuletzt
geplanten Zustand wiederherstellen. Anschließend wird der ursprünglich
angeforderte Context erneut angewendet. Ein bloßes Wiederholen von
ApplyContext ist absichtlich nicht ausreichend, weil die externe
Schaltaktion sonst unbemerkt überschrieben werden könnte.
CheckContextState erzwingt eine sofortige Kontrolle;
PollContextState begrenzt wiederholte Abfragen zeitlich. RFOn_Devices
prüft immer unmittelbar vor dem Einschalten. Read und NBRead binden
eine zeitlich begrenzte Kontrolle in Messschleifen ein. Das ersetzt keinen
asynchronen Hardware-Watchdog, erkennt externe Eingriffe aber an den
relevanten Programmgrenzen.
Die erforderlichen DOT-Attribute und der Treibervertrag sind in der DOT-Referenz beschrieben. Die kuratierte MGraph-API enthält Rückgabewert und Exceptions.
Autosave- und Resume-Schema¶
Vor dem ersten Autosave setzt die Routine eine strukturierte Wiederanlaufinformation:
self.set_autosave_resume(
measurement="example",
method="Measure_Example",
description=description,
)
Die Messroutine muss vorhandene Daten beim Wiederanlauf erkennen und am ersten unvollständigen Punkt fortsetzen. Der zugehörige Test prüft daher Aufrufzahlen und Ergebnisdaten, nicht nur die Lesbarkeit des Pickles.
Datenstruktur¶
Frequenzabhängige Daten werden bevorzugt als
dataset[frequency] = quantity oder in einer klar dokumentierten,
gleichwertigen Struktur abgelegt. Rohdaten, Auswertedaten und Metadaten
bleiben getrennt. Referenzen auf vorbereitende Messungen werden mit
Datensatzschlüssel und Quelle gespeichert, damit Reports die Rückführbarkeit
ohne Neuberechnung darstellen können.
Auswertung¶
Messung und Auswertung sind getrennte Methoden. Dadurch lassen sich
Auswertealgorithmen erneut auf ein after-measure-Pickle anwenden, ohne
Hardware anzusprechen. Eine Auswertung verändert keine Rohdaten und
dokumentiert verwendete Referenzdatensätze sowie relevante Parameter.