INI- und DAT-Referenz für Gerätedaten ===================================== INI-Dateien konfigurieren eine konkrete Geräteinstanz. DAT-Dateien liefern frequenzabhängige Größen mit Einheit und Unsicherheit. Eine INI-Datei kann dabei für einen oder mehrere Kanäle auf DAT-Dateien verweisen. INI-Dateien ----------- .. code-block:: ini [DESCRIPTION] description = Virtual 40 dB attenuator type = CABLE driver = nport.py [INIT_VALUE] FSTART = 1e5 FSTOP = 26e9 NR_OF_CHANNELS = 1 [CHANNEL_1] NAME = S21 UNIT = dB FREQUENCY_INTERPOLATION = LINEAR VALUE_INTERPOLATION = LINEAR COMPLEX_INTERPOLATION = POLAR FILE = attenuator.dat ``DESCRIPTION.type`` benennt die Geräteklasse; ``driver`` wählt die Implementierung. ``INIT_VALUE`` enthält geräteweite Grenzen und Kommunikationsparameter. Kanalabschnitte beschreiben Messgrößen, Sicherheitskanäle und Datenquellen. Gerätegrenzen wie ``MAXIN`` gehören auf diese Ebene. Der Treiber kennt die feste interne Einheit des Geräts, während ``UNIT`` die vom Anwender gewünschte Einheit des Kanals festlegt. Welche Einträge erforderlich sind, bestimmt die jeweilige Treiberklasse. DAT-Dateien ----------- :class:`mpylab.tools.dataparser.DatFile` liest textbasierte Kalibrier- und Korrekturdaten und liefert ein Dictionary. Seine Schlüssel sind Frequenzen als ``float`` in Hz; die Werte sind SCUQ-Quantities in der jeweils kanonischen linearen Einheit. Eine minimale Datei sieht so aus: .. code-block:: text FUNIT: Hz UNIT: dB ABSERROR: 0.2 1e6 -39.8 1e9 -40.1 Leerzeilen sind erlaubt. Ein ``#`` beginnt einen Kommentar bis zum Zeilenende. ``FUNIT``, ``UNIT`` und eine Fehlerangabe gelten jeweils ab ihrer Position in der Datei. Eine spätere Deklaration ersetzt die vorherige. Grammatik ~~~~~~~~~ Die fachliche Grammatik lautet: .. code-block:: text line := FUNIT unit | UNIT unit | RELERROR number | ABSERROR value | frequency value | frequency value value value value := number | (real, imaginary) | [magnitude, phase_deg] ``FUNIT`` muss vor dem ersten Datenpunkt eine Frequenzeinheit bezeichnen. ``UNIT`` muss vor der ersten Wert- oder ``ABSERROR``-Angabe stehen. Die historische Schreibweise mit Eingabe- und Zieleinheit in derselben ``UNIT``-Zeile wird nicht unterstützt. Ausgabeumrechnungen erfolgen nach dem Parsen mit :class:`mpylab.tools.uconv.UConv`. Jede umgerechnete Frequenz darf nur einmal vorkommen. Dadurch werden auch Duplikate erkannt, die erst durch verschiedene Frequenzeinheiten entstehen. Wertdarstellungen ~~~~~~~~~~~~~~~~~ Skalar ``-39.8`` beschreibt einen reellen Wert. Kartesisch komplex ``(0.8, -0.2)`` beschreibt Real- und Imaginärteil. Polar komplex ``[0.825, -14.0]`` beschreibt Betrag und Phase. Die Phase wird immer in Grad angegeben, unabhängig von ``UNIT``. Alle Werte werden beim Parsen in die kanonische lineare SCUQ-Einheit umgerechnet. Bei logarithmischen Eingabeeinheiten wird daher kein dB-Wert im Ergebnisobjekt gespeichert. Unsicherheiten -------------- Zweispaltige Datenpunkte ~~~~~~~~~~~~~~~~~~~~~~~~ Bei ``frequency value`` bestimmt die zuletzt gesetzte Fehlerangabe die Unsicherheit. Ohne ``RELERROR`` oder ``ABSERROR`` ist sie null. ``RELERROR`` Eine nichtnegative relative Standardunsicherheit. Sie wird immer auf den bereits linearisierten Wert angewendet. Bei ``UNIT: dB``, ``RELERROR: 0.1`` und dem Wert ``20`` ist der lineare Nominalwert ``100`` und die lineare Unsicherheit ``10``. ``ABSERROR`` Eine absolute Standardunsicherheit in der mit ``UNIT`` deklarierten Eingabeeinheit. Eine neue ``ABSERROR``-Angabe deaktiviert ``RELERROR`` und umgekehrt. Explizite Grenzen ~~~~~~~~~~~~~~~~~ Ein Datenpunkt mit drei Werten enthält Nominalwert, Unter- und Obergrenze: .. code-block:: text 1e6 10.0 9.5 10.8 Die Reihenfolge der drei Werte ist nicht maßgeblich. Der Parser sortiert sie, verwendet den mittleren Wert als Nominalwert und die halbe Spanne zwischen unterem und oberem Wert als Standardunsicherheit. Eine explizite Dreiergruppe hat Vorrang vor einem aktiven ``RELERROR`` oder ``ABSERROR``. dB-Einheiten ~~~~~~~~~~~~ Bei logarithmischen Einheiten ist ``ABSERROR`` eine nichtnegative skalare Differenz auf der dB-Skala. Beispiel: .. code-block:: text FUNIT: Hz UNIT: dBm ABSERROR: 1 1e6 20 Der Parser bildet zunächst die Grenzen ``19 dBm`` und ``21 dBm`` und linearisiert anschließend alle drei Werte. ``1 dBm`` wird nicht als absolute lineare Leistungsunsicherheit interpretiert. SCUQ speichert hier eine symmetrische lineare Unsicherheit. Deshalb wird die halbe lineare Gesamtspanne verwendet. Bei einer späteren Darstellung in dB entstehen daraus im Allgemeinen asymmetrische Grenzen. Eine komplexe ``ABSERROR``-Angabe ist für logarithmische Einheiten nicht zulässig. Komplexe Polarunsicherheit ~~~~~~~~~~~~~~~~~~~~~~~~~~ Für neue komplexe Unsicherheitsdaten wird eine Dreiergruppe in Polardarstellung empfohlen: .. code-block:: text FUNIT: Hz UNIT: powerratio 1e6 [0.8, -1] [1.0, 0] [1.2, 1] Der Wert mit dem mittleren Betrag wird Nominalwert. Die halbe Spanne zwischen kleinstem und größtem Betrag ist die Betragsunsicherheit. Die Phasen werden um die Nominalphase entfaltet; die halbe Phasenspanne wird als Phasenunsicherheit im Bogenmaß gespeichert. Betrag und Phase gelten als unabhängig. ``DatFile`` transformiert dieses Polarmodell in eine komplexe SCUQ-Komponente. Ihre kartesische 2x2-Kovarianzmatrix beschreibt Real- und Imaginärteil. :class:`mpylab.tools.interpol.UQ_interpol` und die Pickle-Serialisierung erhalten diese Kovarianz. Eine kartesische Dreiergruppe ``(real, imaginary)`` behält dagegen die historische skalare Unsicherheitsdarstellung und sollte für neue komplexe Unsicherheitsdaten nicht verwendet werden. Antennen- und Transducerfaktoren -------------------------------- Antennenfaktoren werden intern bewusst nicht auf ihre gekürzte Dimension reduziert. Die Einheiten ``(V/m)/V`` und ``(A/m)/V`` erhalten die Information, ob der Faktor eine Eingangsspannung auf eine elektrische oder magnetische Feldstärke abbildet. Damit bleibt die Rückumrechnung eindeutig. Einheiten mit Klammern werden gequotet: .. code-block:: text UNIT: "dB((V/m)/V)" UNIT: "dB((A/m)/V)" ``UNIT: dB/m`` ist ein Alias für den elektrischen Antennenfaktor. ``UNIT: 1/m`` und das historische ``UNIT: dB1/m`` bleiben generische inverse Längeneinheiten ohne Antennenfaktor-Semantik. Die logarithmischen Werte beziehen sich auf den Wert 1 in der zugehörigen linearen Faktor-Einheit: .. math:: AF_E[\mathrm{dB}((\mathrm{V/m})/\mathrm{V})] = 20 \log_{10}\left( \frac{AF_E}{1\,(\mathrm{V/m})/\mathrm{V}} \right) Unterstützte Einheiten ---------------------- Die verbindliche Liste liegt in :class:`mpylab.tools.uconv.UConv`. Sie kann ohne Duplizieren der Registry abgefragt werden: .. code-block:: pycon >>> from mpylab.tools.uconv import UConv >>> UConv.available_units() ('(a/m)/v', '(v/m)/v', '1', '1/m', ...) Zu den unterstützten Gruppen gehören: * dimensionslose Werte sowie Amplituden- und Leistungsverhältnisse; * Leistung, Spannung und Frequenz; * elektrische und magnetische Feldstärke; * Länge und Winkel; * Leistungsflussdichte und Leitfähigkeit; * elektrische und magnetische Antennenfaktoren; * Henry und Farad. Einheitennamen werden ohne Beachtung der Groß-/Kleinschreibung verarbeitet. Strukturierte Namen müssen wegen ihrer Sonderzeichen gequotet werden. Fehlerbehandlung ---------------- Der Parser verwendet PLY mit einem eigenen Lexer und Parser je ``DatFile``-Instanz. Parallel vorbereitete Dateien beeinflussen ihren Zustand daher nicht gegenseitig. Parse-Tabellen werden im Speicher erzeugt; eine ``parsetab.py`` gehört nicht zur öffentlichen Schnittstelle. Lexikalische und syntaktische Fehler lösen :class:`mpylab.tools.dataparser.DatFileSyntaxError` aus. Die Meldung enthält Quelle, Zeile und Spalte. Fehlerhafte Dateien liefern kein unvollständiges Teilergebnis. Insbesondere werden abgelehnt: * unbekannte oder an falscher Stelle verwendete Einheiten; * ein ``FUNIT``, das keine Frequenzeinheit ist; * negative relative oder logarithmische absolute Fehler; * ``inf``, ``nan`` und bei der Umrechnung entstehende nichtendliche Werte; * doppelte Frequenzen; * unvollständige Datenzeilen. Interpolation ------------- Interpolation ist keine Eigenschaft der DAT-Grammatik. Sie wird vom verwendenden Kanal, insbesondere einem NPORT-Kanal, festgelegt: ``FREQUENCY_INTERPOLATION`` ``LINEAR`` oder ``LOG`` für die Frequenzachse. ``VALUE_INTERPOLATION`` ``LINEAR`` oder ``DB`` für Betrag beziehungsweise Wert. ``COMPLEX_INTERPOLATION`` Behandlung komplexer Größen, typischerweise ``POLAR``. Die Auswahl muss zur Entstehung der Stützstellen und zur physikalischen Größe passen. Zu große Abstände zwischen Stützstellen können auch bei formal gültiger Interpolation fachlich unzureichend sein. Die :doc:`Konfigurationsvalidierung ` beschreibt die zugehörigen Prüfwerkzeuge.