.. highlightlang:: us .. _filterfunktionen-fur-xy-datensatze: .. _filter-functions-for-xy-datasets: Filterfunktionen für XY-Datensätze ================================== Ab UniPlot 4.0 können für XY-Datensätze sogenannte Filterfunktionen definiert werden. Die Filterfunktionen sind eine Eigenschaft des Datensatzes und werden im Datensatz gespeichert. Wenn sich die Originaldaten des Datensatzes ändern, werden die Filterfunktionen neu berechnet, z. B. beim Datenaustausch oder wenn ein Datenpunkt interaktiv geändert wird. Im Diagramm werden die berechneten Daten graphisch dargestellt. Die Filterfunktion können für 1D- oder 2D-Datensätze definiert werden. Ein Datensatz kann eine oder mehrere Filterfunktionen enthalten. Die erste Funktion in der Liste verwendet als Eingangsdaten die Originaldaten des Datensatzes. Alle folgenden Funktionen greifen jeweils auf die Ergebnisdaten der vorherigen Filterfunktion zu. Das Ergebnis der letzten Filterfunktion wird graphisch dargestellt. Die Ergebnisdaten der Berechnung werden im Datensatz gespeichert. Wenn Sie eine IPW-Datei weitergeben und eine Filterfunktion bei einem Anwender nicht vorhanden ist, wird der Datensatz zwar korrekt angezeigt, ein Austausch der Daten oder die Bearbeitung der Daten ist jedoch nicht möglich. Die Filterfunktionen sind UniScript-Funktionen, die vom UniPlot-Anwender definiert werden können. Die folgenden Funktion können als Vorlage für eigene Filterfunktionen verwendet werden. Wie neue Filterfunktionen geschrieben werden, wird am Ende dieser Hilfeseite erklärt. .. _liste-der-filterfunktionen: Liste der Filterfunktionen -------------------------- Den Quellcode der folgenden Funktionen finden Sie in der Datei :file:`script\\rs_xy_filt_funcs.ic` Bei den Funktionen spline, fitspline, pspline und akimaspline kann für den Parameter nPoints die Zahl 0 angegeben werden. Die Funktion verwendet dann eine Anzahl an Stützstellen die abhängig von der Anzahl der Originaldatenpunkte n ist: .. list-table:: :header-rows: 1 * - n - nSplinePoints * - 0-2 - 100 * - 3-5 - n\*100 * - 6-19 - n\*50 * - 20-99 - n\*10 * - 100-999 - n\*5 * - 1000-100000 - n\*3 * - >=100000 - n abs ^^^ :: abs() Berechnet den Betrag der y-Koordinaten. bit ^^^ Liefert das n-te Bit von y. nBit beginnt bei 1. Das Ergebnis kann skaliert werden. :: bit(nBit, rsScaleFactor, rsScaleOffset) nBit: Range 1 to 64 Skalierung: y = rsScaleFactor * (0/1-Wert) + rsScaleOffset; min ^^^ :: min() Berechnet das Minimum der y-Koordinaten. max ^^^ :: max() Berechnet das Maximum der y-Koordinaten. mean ^^^^ :: mean() Berechnet den Mittelwert der y-Koordinaten. median ^^^^^^ :: median(nPercent) Berechnet den Median der y-Koordinaten. Dazu werden die Daten in aufsteigender Folge sortiert und für nPercent=50 auf den Wert an der mittleren Stelle gesetzt. Der Index des Medianwerts wird aus der Punktanzahl multipliziert mit dem Prozentwert berechnet. smooth ^^^^^^ :: smooth() smooth(nNeighbor) smooth(nNeighbor, PeakFilterFactor) Glättet einen Datensatz mit dem gleitenden Mittelwert. Der optionale Parameter ``nNeighbor`` gibt die Anzahl der Nachbarpunkte an, die beim Glätten berücksichtigt werden. ``nNeighbor`` ist die halbe Fensterbreite. Die gesamte Fensterbreite ist ``nNeighbor * 2 + 1``. Falls der Parameter nicht angegeben wird, wird ``nNeighbor`` gleich 10 gesetzt. Mit Hilfe des optionalen Parameters ``PeakFilterFactor`` kann festgelegt werden, wie die Spitzen in das gefilterte Signal übernommen werden sollen. Default-Wert ist 0. So funktioniert der Peak-Filter: * Die smooth-Funktion wird auf die Originaldaten angewendet. * Es wird die Differenz zwischen den Originaldaten und dem gefilterten Daten berechnet (= Abweichung). * Es wird das Maximum der Abweichung gesucht und mit dem neuen Faktor multipliziert (= dy). * Es werden alle Punkte in den Originalpunkten gesucht, deren Abweichung größer als dy sind. * Die gefunden Punkte werden in das geglättete Signal wieder eingefügt. .. _smooth_median: smooth_median ^^^^^^^^^^^^^ :: smooth_median(nNeighbor) Gleitender Median. nNeighbor ist die Fensterbreite im Bereich 3 bis 1025. Gerade Zahlen werden auf die nächste ungerade Zahl aufgerundet. Verwendet die Funktion :ref:`moving_median`. Beispiel: ``smooth_median(5)`` 5 aufeinander folgende Punkte aufsteigend sortiert und der dritte Wert wird in den Ergebnisvektor geschrieben. Bei einer Fensterbreite von 5 Punkten werden die ersten zwei Punkte und die letzten zwei Punkte unverändert in den Ergebnisvektor geschrieben. Gegeben: ``[5, 7, 6, 4, 27, 8, 4, 5]`` Ergebnis: ``[5, 7, 6, 7, 6, 8, 4, 5]`` Beispiel für Ausreißerfilterung: .. image:: S:/uniplot-obj/images/peaks.* smooth_golay (Savitzky-Golay) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :: smooth_golay(nPolynomialOrder, nWindowSize) smooth_golay(nPolynomialOrder, nWindowSize, PeakFilterFactor) Die Punkte aus der Umgebung der Filterstelle werden für die Berechnung eines Ausgleichspolynoms verwendet (z. B. 5 Punkte für eine Ausgleichsparabel). Gegenüber dem gleitenden Mittelwert, erhält die Savitzky-Golay-Glättung besser die Form von Peaks. Die Höhe des Peaks wird weniger reduziert und die Breite weniger vergrössert. Allerdings ist auch hier der Einfluss auf die Peakhöhe bzw. die Peakfläche von der ursprünglichen Peakbreite und Peakform abhängig. .. image:: S:/uniplot-obj/images/savitzky-golay.* Glättung mit Peak-Filter. Die Funktionsweise entspricht dem smooth-Filter. .. image:: S:/uniplot-obj/images/savitzky-golay-peak-filter.* spline ^^^^^^ :: spline() spline(nPoints) Berechnet einen kubischen Spline, der alle Datenpunkte schneidet. nPoints: Anzahl der Punkte des Splines. Die Anzahl muss im Bereich von 10 bis 100000 liegen. nPoints = 0: Anzahl der Punkte automatisch bestimmen (siehe oben). oldspline ^^^^^^^^^ :: oldspline() Berechnet einen kubischen Spline, der alle Datenpunkte schneidet. Diese Funktion existiert aus Kompatibilitätsgründen zu UniPlot 3.x. Verwenden Sie statt dessen die Funktion ``spline(0)``. fitspline ^^^^^^^^^ :: fit_spline() fit_spline(smoothfactor) fit_spline(smoothfactor, nPoints) Ausgleichsspline. Die Funktion berechnet einen Spline, der eine Glättung durchführt. smoothfactor: Glättungsfaktor. Ein Wert von 0 ergibt keine Glättung (d.h. alle Punkte des Splines gehen durch die Originaldatenpunkte) und ein Wert größer als 0 führt eine Glättung durch. nPoints: Punktanzahl (10 bis 100000). nPoints = 0: Anzahl der Punkte automatisch bestimmen (siehe oben). akimaspline ^^^^^^^^^^^ :: akimaspline() akimaspline(nPoints) Kubischer Spline der gut mit diskontinuierlichen Änderungen zurecht kommt, ohne zu stark überzuschwingen. Die Akimainterpolationsmethode verzichtet gegenüber rein kubischen Splines auf die Stetigkeit der zweiten Ableitung. nPoints: Anzahl der Punkte des Splines. Die Anzahl muss im Bereich von 10 bis 100000 liegen. nPoints = 0: Anzahl der Punkte automatisch bestimmen (siehe oben). .. index:: Regressionsgerade .. _polyfit-filter: polyfit ^^^^^^^ :: polyfit() polyfit(polynomOrder) polyfit(polynomOrder, nPoints, nInfoText) polyfit(polynomOrder, nPoints, nInfoText, xMin, xMax) Erzeugt ein Ausgleichspolynom 0ter bis 9terOrdnung, wobei order=1 eine Ausgleichsgerade ergibt (Regressionsgerade). polynomOrder: Ordnung des Polynoms (Default = 1). nPoints: Anzahl der Punkte, aus denen die Kurve gebildet werden soll (Default = 1000). Die Punktanzahl muss im Bereich 2 bis 100000 liegen. nInfoText: 0 = kein Text, 1 = Polynomparameter, 2 = Polynomparameter und R2 (Bestimmtheitsmaß) xMin: Startwert. Kann kleiner als der erste Datenpunkt sein. Falls der Wert auf 1e10 gesetzt wird, wird der erste Datenpunkt verwendet. xMax: Endwert. Kann größer als der letzte Datenpunkt sein. Falls der Wert auf 1e10 gesetzt wird, wird der letzte Datenpunkt verwendet. interpol ^^^^^^^^ :: interpol() interpol(nPoints) Berechnet Zwischenpunkte durch lineare Interpolation. nPoints: Anzahl der Punkte, die gleichmäßig über den x-Koordinatenbereich verteilt werden, oder eine Liste der x-Koordinaten durch Komma getrennt. interpol2 ^^^^^^^^^ :: interpol2(xmin, xmax, xdelta) Berechnet Zwischenpunkte von xmin bis xmax in Schritten von xdelta durch lineare Interpolation. Der Datensatz muss monoton sein. Falls xmin oder xmax außerhalb des x-Wertebereichs liegt, wird der Bereich entsprechend korrigiert, da die Funktion keine Extrapolation durchführt. sort ^^^^ :: sort() Sortiert die Datenpunkte nach der x-Koordinate. simplify ^^^^^^^^ :: simplify() simplify(nTolerance) Datenpunkt-Reduzierung mit dem Douglas-Peucker Verfahren. nTolerance: gleich 1 bedeutet, dass alle Punkte der transformierten Kurve höchstens einen Abstand von 10% zur Originalkurve haben. Die Werte 2, 3, 4 bis 30 halbieren die Tolerenz. 4 ist also ein Abstand von 1.25%, bei 20 ist der Abstand nahezu 0. Default-Wert ist 5. .. image:: S:/uniplot-obj/images/filter-simplify.* boundary ^^^^^^^^ :: boundary() boundary(type) boundary(type, width) Berechnet die obere, untere oder obere und untere Hüllkurve, die die Daten einschließt. type: 0 - obere Hüllkurve (Defaultwert: 0). type: 1 - untere Hüllkurve. type: 2 - obere und untere Hüllkurve. width: Klassenbreite in Prozent (Defaultwert 5%). step ^^^^ :: step() step(nType) Berechnet eine Stufen-Kurve (z. B. Cityscape or Skyline). nType: 0 - Kurve beginnt horizontal. nType: 1 - Kurve beginnt vertikal (Defaultwert = 1). integrate ^^^^^^^^^ :: integrate() Berechnet den Integralverlauf mit Hilfe der Trapezmethode. integrate_cycle ^^^^^^^^^^^^^^^ :: integrate_cycle(xCycleLength, xCycleStart, nCycle) Berechnet für jeden Zyklus den Integralverlauf mit Hilfe der Trapezmethode. xCycleLength: Zykluslänge in X-Koordinaten, z. B. 0.2s oder 720 °KW. xCycleStart: Zyklusbeginn in X-Koordianten, z. B. 0s oder -360 °KW. xCycleStart wird auf den Wert von x[1] gesetzt, falls der Wert von xCycleStart kleiner als x[1] ist. nCycle: Anzahl der Zyklen. 0 für alle Zyklen. cycle_value ^^^^^^^^^^^ :: cycle_value(Type, cycle_length, cycle_start, nCycle) Berechnet für jeden Zyklus einen der folgenden Kennwerte: Mittelwert, Minimum oder Maximum. nType: 1: Mittelwert, 2: Maximum, 3: Minimum xCycleLength: Zykluslänge in X-Koordinaten, z. B. 0.2s oder 720 °KW. xCycleStart: Zyklusbeginn in X-Koordinaten, z. B. 0s oder -360 °KW. xCycleStart wird auf den Wert von x[1] gesetzt, falls der Wert von xCycleStart kleiner als x[1] ist. nCycle: Anzahl der Zyklen. 0 für alle Zyklen. differentiate ^^^^^^^^^^^^^ :: differentiate() Berechnet den Verlauf der 1. Ableitung. extract ^^^^^^^ :: extract(xmin, xmax) Die Funktion extract schneidet alle Datenpunkte im X-Koordinatenbereich von xmin bis xmax aus. Die Punkte an den Grenzen xmin und xmax werden durch lineare Interpolation berechnet. Die x-Koordinaten müssen dazu monoton steigend sein. Siehe auch extract_points extract_points ^^^^^^^^^^^^^^ :: extract_points(imin, imax) Die Funktion extract_points schneidet einen Ausschnitt der Datenpunkte von imin bis imax aus. imin: Erster Punkt (imin >= 1 und <= Anzahl Punkte - 2). imax: Letzter Punkt. Falls für imax eine negative Zahl angegeben wird, wird von hinten gezählt, z. B. Punktanzahl ist 17: :: extract_points(1,22) entspricht extract_points(1,17) extract_points(1,-1) entspricht extract_points(1,17) extract_points(1,0) entspricht extract_points(1,17) extract_points(3,-3) entspricht extract_points(3,15) find ^^^^ :: find(min, max, Axis, Type) Liefert die Datenpunkte im Bereich von min bis max. Falls kein Datenpunkt im Bereich liegt, liefert die Funktion den Wert 0. Axis ist einer der folgenden Werte: 1: Filter auf die x-Koordinaten anwenden. 2: Filter auf die y-Koordinaten anwenden. Type ist einer der folgenden Werte: 0: Absolute Werte 1: Relative Werte: Werte werden vor dem Suchen durch den Maximalwert dividiert (xy / xymax). 2: Relative Werte: Werte werden vor dem Suchen auf den Bereich 0 bis 1 skaliert (xy - xymin) / (xymax-xymin). Für den Type 1 oder 2 sollte min und max im Bereich 0 und 1 liegen. Beispiel: Mit dem folgenden Filter können alle Punkte gesucht werden, deren y-Koordinaten im Bereich 90% vom Maximumwert liegen: find(0.9, 1.0, 2, 1). remove_duplicate_points ^^^^^^^^^^^^^^^^^^^^^^^ :: remove_duplicate_points() Entfernt alle aufeinander folgende Punkte mit gleicher x-Koordinate bis auf den ersten Punkt. .. _correction_factor: correction_factor ^^^^^^^^^^^^^^^^^ :: correction_factor(x,y) Korrigiert die y-Koordinate mit einem variablen Korrekturfaktor. .. _schreiben-eigener-filterfunktionen: Schreiben eigener Filterfunktionen ---------------------------------- Das Schreiben einer Filter-Funktion soll an einem Beispiel gezeigt werden. :: def _xy_filter_func_scale(hData, a, b) { if (nargsin() == 1) { _a = 1; _b = 0; } else if (nargsin() == 2) { _a = a; _b = 0; } else if (nargsin() == 3) { _a = a; _b = b; } xy = XYGetData(hData); x = xy[;1]; y = xy[;2]; y = _a * y + _b; return XYSetData(hData, x, y, TRUE); // TRUE ist wichtig! } def _xy_filter_info_scale() { svInfo = ["Y-Skalierung"; "scale(a,b)\n\nSkalierung der y-Koordinaten mit Hilfe" + .... "der Geradengleichung y = a*y + b"; ""; "2"; "Skalierungswert a:1:-1e9:1e9"; "Verschiebungswert b:0:-1e9:1e9"]; return svInfo; } Um eine neue Filterfunktion zu definieren, müssen zwei Funktionen geschrieben werden. Eine Funktion berechnet die Daten, die andere Funktion stellt Informationen für die Benutzerschnittstelle bereit. Bei dem oben gezeigten Beispiel sind das die Funktionen ``_xy_filter_func_scale`` und ``_xy_filter_info_scale``. Die Namen von Filterfunktionen fangen mit den Zeichenfolge ``_xy_filter_func_`` an, gefolgt von dem Anwender-Namen der Filterfunktion, in diesem Beispiel ``scale``. Die Funktionen können in einer Datei mit der Endung :file:`.ic` im :file:`autoload`-Verzeichnis von UniPlot gespeichert werden. Beim Start von UniPlot werden die Funktionen dann automatisch geladen. Die Info-Funktion gibt einen Stringvektor mit mindestens 4 Elementen zurück. .. list-table:: :header-rows: 1 * - Element - Bedeutung * - svInfo[1] - Name der Funktion. * - svInfo[2] - Beschreibungstext der im Hilfefenster angezeigt wird. Falls der Text länger ausfällt, kann man wie im Beispiel den Text auf mehrere Zeilen verteilen. Die Zeilen werden dann mit ``+ ....`` verknüpft. * - svInfo[3] - Nicht benutzt. Muss ein leerer String sein (""). * - svInfo[4] - Anzahl der Parameter "0" bis "8" * - svInfo[5] - Hinter svInfo[4] folgen 0 bis 8 weitere Info-Strings. Sie enthalten den Namen des Parameters, gefolgt von 3 durch Doppelpunkte getrennte Zahlen. Die erste Zahl ist der Defaultwert, gefolgt von einem Minimum- und einem Maximum-Wert, den der Parameter annehmen kann. Beispiel: ``"Verschiebungswert b:0:0:1e9"``. Die Func-Funktion führt die Berechnung durch. Als erster Parameter wird immer der Handle des Datensatzes übergeben. Über den Handle kann auf die Daten des Datensatzes zugegriffen werden (:ref:`XYGetData`). Die Ergebnisdaten werden mit der Funktion :ref:`XYSetData` zurückgeschrieben. Die weiteren Parameter sind optional. .. us.history **History** .. list-table:: :header-rows: 1 * - Version - Beschreibung * - R2022.2 - `correction_factor`_ :sub:`id-1866448`