Conditions, Schaltmatrix und Pfadkorrekturen¶
Pfadkorrekturen verbinden die in einem DOT-Graph beschriebenen Übertragungswege mit den tatsächlich gemessenen Größen. Bei frequenzabhängigen Messaufbauten müssen drei Schritte zusammenpassen:
aktive Graphzweige auswählen;
reale Geräte und Schaltmatrix auf die Frequenz einstellen;
die Korrektur des aktiven Pfades lesen und anwenden.
Knoten, Kanten, Conditions und dev/what-Attribute sind in der
DOT-Referenz vollständig beschrieben.
Die Korrekturwerte selbst werden typischerweise durch einen INI-Kanal und eine DAT-Datei bereitgestellt. Syntax, Einheiten, komplexe Werte und Unsicherheiten stehen in der INI- und DAT-Referenz.
Conditions auswerten¶
EvaluateConditions aktiviert Knoten und Kanten anhand des expliziten
Kontexts:
mg.EvaluateConditions(context={"frequency": frequency})
Mit doAction=False wird nur der Graphzustand berechnet. Das ist für
Preflight, Scanplanung und Pfadprüfung wichtig, weil dabei keine Hardware
geschaltet werden darf.
Ein aktives Element kann zusätzlich ein action-Attribut besitzen.
Ausgeführt wird ausschließlich ein direkter Methodenaufruf auf einem Objekt
aus dem Kontext mit literalen Argumenten. Beliebiger Python-Code ist nicht
zulässig. Actions eignen sich für kleine, ausdrücklich konfigurierte
Zustandswechsel; gerätespezifische Schaltlogik gehört bevorzugt in den
Treiber.
Eine kleine Matrix kann alternativ direkt über Actions geschaltet werden:
SwitchLF [condition="FREQUENCY <= 1e9"
action="switch.switch_to(0)"]
SwitchHF [condition="FREQUENCY > 1e9"
action="switch.switch_to(1)"]
mg.EvaluateConditions(context={
"frequency": frequency,
"switch": switch_instance,
})
Diese Variante und ein frequenzabhängiges SetFreq im Switch-Treiber sind
Alternativen. Derselbe Relaiszustand soll nicht über beide Wege gleichzeitig
gesetzt werden.
Switch-Matrix über SetFreq¶
Eine Switch-Matrix ist ein reguläres Gerät im MGraph. Ihr Treiber
implementiert SetFreq(frequency) und wählt anhand seiner INI-Konfiguration
den erforderlichen Relaiszustand. SetFreq_Devices ruft diese Methode
zusammen mit den anderen frequenzabhängigen Geräten auf:
mg.EvaluateConditions(context={"frequency": frequency})
mg.SetFreq_Devices(frequency)
Die Conditions und die Schaltschwelle des Treibers müssen dieselben
Bereichsgrenzen verwenden. Der Graph wählt beispielsweise den LF-Zweig bis
einschließlich 1 GHz, während der Switch-Treiber bei f <= 1e9 dieselbe
Relaisstellung wählt.
Vor dem Umschalten wird ein Signalgenerator auf einen sicheren Startpegel gesetzt oder RF abgeschaltet. Das ist besonders wichtig, wenn der Frequenzwechsel einen anderen Verstärker mit abweichender Eingangsgrenze aktiviert.
Komplexeres TEM-Beispiel¶
digraph {
Switch [ini="sw_gtem.ini"]
Sg [ini="sg.ini"]
AmpLF [ini="amp-lf.ini"
condition="FREQUENCY <= 1e9"]
AmpHF [ini="amp-hf.ini"
condition="FREQUENCY > 1e9"]
PathSgLF [ini="sg-lf.ini"]
PathSgHF [ini="sg-hf.ini"]
PathLFCell [ini="lf-cell.ini"]
PathHFCell [ini="hf-cell.ini"]
Sg -> SgLF [condition="FREQUENCY <= 1e9"]
Sg -> SgHF [condition="FREQUENCY > 1e9"]
SgLF -> AmpInLF [dev=PathSgLF what="S21"]
SgHF -> AmpInHF [dev=PathSgHF what="S21"]
AmpInLF -> AmpOutLF [dev=AmpLF what="S21"]
AmpInHF -> AmpOutHF [dev=AmpHF what="S21"]
AmpOutLF -> GTEM [dev=PathLFCell what="S21"]
AmpOutHF -> GTEM [dev=PathHFCell what="S21"]
}
Der Condition-Kontext wählt den roten oder blauen Korrekturpfad. Parallel
dazu stellt SetFreq_Devices die Switch-Matrix und alle aktiven Geräte
auf dieselbe Frequenz ein.¶
Dieses vereinfachte Beispiel zeigt nur den Vorwärtspfad. Eine reale TEM-Verifikation ergänzt Abzweige zu Vorwärts- und Rückwärtsleistungsmessern sowie deren eigene Koppler- und Kabelkorrekturen.
Gesamtkorrektur lesen¶
get_path_correction liefert die Gesamtkorrektur zwischen zwei
Messpositionen:
from mpylab.tools.aunits import POWERRATIO
correction = mg.get_path_correction(
names["sg"],
names["port"],
POWERRATIO,
)
Ohne unit wird AMPLITUDERATIO verwendet. Bei der Umwandlung eines
komplexen Amplitudenverhältnisses in ein Leistungsverhältnis wird
abs(S21) ** 2 gebildet. Einheit und Unsicherheit bleiben erhalten.
get_path_corrections gibt zusätzlich die einzelnen
Korrekturelemente zurück. Der Schlüssel "total" enthält das
Gesamtergebnis:
details = mg.get_path_corrections("Sg", "GTEM")
total = details["total"]
Diese detaillierte Form eignet sich für Diagnose und Reports. Anwendungslogik
sollte für die übliche Gesamtkorrektur get_path_correction verwenden.
Korrektur anwenden¶
Die Richtung muss fachlich ausdrücklich gewählt werden:
corrected = mg.apply_path_correction(
measured,
correction,
operation="divide",
magnitude=True,
output_unit=VOLT,
)
operation ist "multiply" oder "divide". magnitude=False
erhält die Phase; magnitude=True erzeugt eine reelle Betragsgröße mit
Unsicherheit.
Schnelle wiederholte Anwendung¶
Wenn viele Messwerte mit derselben Korrektur verarbeitet werden, kann sie einmal vorbereitet werden:
prepared = mg.prepare_path_correction(
correction,
operation="divide",
magnitude=True,
output_unit=VOLT,
)
corrected = [
mg.apply_path_correction(value, prepared)
for value in measured_values
]
Eine exakt bekannte, konstante Korrektur kann dadurch einen schnellen Skalierungspfad verwenden. Unsichere oder nicht unterstützte Fälle fallen automatisch auf die vollständige SCUQ-Rechnung zurück.
Das vorbereitete Objekt darf nur wiederverwendet werden, solange Frequenz,
aktiver Graphpfad und zugrunde liegende Kalibrierdaten unverändert sind. Nach
jedem EvaluateConditions oder Frequenzwechsel wird die Pfadkorrektur neu
gelesen und gegebenenfalls neu vorbereitet.
Prüfregeln¶
Conditions vor dem Lesen einer Korrektur auswerten.
Schaltmatrix und Graph mit identischen Bereichsgrenzen konfigurieren.
Grenzfrequenzen auf fehlende oder doppelte Pfade testen.
Korrekturen als SCUQ-Quantities führen.
Multiplikation oder Division und das Verwerfen der Phase ausdrücklich angeben.
Vorbereitete Korrekturen nicht über einen Graphzustandswechsel hinweg wiederverwenden.