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 :doc:`DOT-Referenz <../configuration/dot>` 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 :doc:`INI- und DAT-Referenz <../configuration/instrument-data>`. Conditions auswerten --------------------- ``EvaluateConditions`` aktiviert Knoten und Kanten anhand des expliziten Kontexts: .. code-block:: python 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: .. code-block:: dot SwitchLF [condition="FREQUENCY <= 1e9" action="switch.switch_to(0)"] SwitchHF [condition="FREQUENCY > 1e9" action="switch.switch_to(1)"] .. code-block:: python 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: .. code-block:: python 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 ------------------------ .. code-block:: dot 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"] } .. figure:: ../../_static/tutorial/tem-verification-switched-path.svg :alt: Frequenzabhängige LF- und HF-Pfade einer TEM-Verifikation mit Schaltmatrix :width: 100% 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: .. code-block:: python 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: .. code-block:: python 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: .. code-block:: python 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: .. code-block:: python 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.