Plotten von Messdaten

Zur Vorstellung von Komponenten und Units für Lazarus
magnetron
Beiträge: 44
Registriert: Di 4. Nov 2014, 14:04

Plotten von Messdaten

Beitrag von magnetron »

Hallo zusammen,

nun hab ich mich angemeldet und hoffe, dass ich hier ab und an etwas sinnvolles beitragen kann.
Ich nutze Lazarus als "Mittel zum Zweck" um technische Probleme zu lösen
wie Gerätesteuerung, Meßtechnik usw..

Anbei möchte ich meine Plotkomponente vorstellen, die vor längerer Zeit begann
als TAChart nichts mit der heutigen Version zu tun hatte (jedenfalls für mich damals nicht nutzbar)
und die Steuerung von Gnuplot über eine pipe zu langsam.

Die Komponente ist dafür gedacht, Messdaten grafisch darzustellen,
speziell nützlich als Display für Oszilloskope, Spektrumanalysatoren
und als Wasserfall display.

Siehe auch die Screenshots auf https://github.com/gyrotron/MAAplot ,
damit ist fast alles gesagt (oder siehe example).

pro:
- Einfach zu nutzen (siehe example_basic)
- Konfigurierbare Darstellung
- Maus support (Zoom, Pan, Marker)
- Export und Import von (Mess)daten
- Transparante Darstellung mit einem TLazIntfImage
- Relativ schnell, zumindest locker ausreichend um 96000 Punkte vom
soundcard sampling pro Sekunde zu plotten.
- Achsen linear oder logarithmisch zu beliebiger Basis
- Beschriftungen (Zahlenwerte) bleiben lesbar bei verkleinern des Fensters.
- Legende und Colorscale
- Werte einzelner Achsen können als Farbwerte dargestellt werden
contra:
- Daten, Achsentransformation und Darstellung sind nicht getrennt
- Implementierung neuer Darstellungen (Smith, Polar etc.) deswegen weniger sinnvoll

Letztendlich bin ich (immer noch) auf der Suche nach einer Plotkomponente für
ingenieursmässige Darstellung von Mess- und Audiodaten.
Vielleicht hat jemand einen Tip ? Lohnt es TAChart nochmal genauer anzusehen ?

Kompatibilität:
- Lazarus >= 1.0 (getestet 1.02 und 1.2.4, früher auch 0.9.28)
- Linux (getestet Ubuntu 12.04 und 14.04) mit QT4 oder GTK2.
- Windows (getestet XP, 7)

Bugs:
unter windows, teilweise auch gtk2:
- diverse Transparenzprobleme wegen windows spezifischen Automatismen
(workarounds siehe compilerschalter >usegtk2< in den units)
- selten: floating point exceptions unter windows (mir unklar, wie ich fpu exceptions unter
windows abfangen kann. Daher muss vorher auf x/0 bzw. log(-x) geprüft werden -
wo dies evtl. übersehen wurde bitte einfach entsprechende Prüfung einfügen).
- Zahlen kleiner 1e-30 oder größer 1e30 sind nicht vorgesehen.

MAAPlot 1.0 Version 141020
Lizenz: EUPL

Kommentare gerne willkommen - fragen zur Nutzung auch.
Grüße, Stefan

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Plotten von Messdaten

Beitrag von wp_xyz »

Höchsten Respekt! Bei TAChart hat sich zwar einiges getan seit Lazarus 0.9x, aber 3D kann es immer noch nicht.

Schau dir mal die wiki-Seiten http://wiki.lazarus.freepascal.org/TACh ... umentation und http://wiki.lazarus.freepascal.org/TAChart_Demos an, da kriegst du am schnellsten einen Überblick, was sich seit "deiner" Zeit verändert hat.

rds
Beiträge: 17
Registriert: Di 4. Nov 2014, 18:32

Re: Plotten von Messdaten

Beitrag von rds »

Hallo,
bin gerade dabei deine plot-units auszuprobieren.
Die Beispielanwendung example_basic-master konnte ich problemlos kompilieren und ausführen.

Das andere, etwas komplexere Beispiel, will nicht so recht.
Der Compiler meldet: Projekt "Maaplot_demo1" erfolgreich kompiliert.
Das Demoprogramm wird gestartet und danach sofort mit der Meldung: "Anwendung beendet" abgebrochen.
Woran könnte das liegen?
Ich arbeite unter Win 7 mit Lazarus v1.2.6
Grüsse
rds

magnetron
Beiträge: 44
Registriert: Di 4. Nov 2014, 14:04

Re: Plotten von Messdaten

Beitrag von magnetron »

Hallo rds,
ausprobieren mit win7 kann ich das leider erst vermutlich morgen - generell habe ich es unter win7 getestet
also kann der fehler nicht gross sein.
Eventuell könnte es liegen
a) am debugger, probier mal die exe zu starten ohne debugger.
b) es könnte noch die ein oder andere konsolenausgabe (mit writeln) im code sein.
Unter windows braucht es dann den schalter "konsolenanwendung" in den compilereinstellungen,
sonst crasht es.
Ich vermute b), weil ich vermutlich zuletzt unter linux kompiliert habe und dieser haken bei
"windows konsolenanwendung" nicht gesetzt ist.
Wenns nicht geht bitte nochmal Bescheid sagen, wie gesagt kanns erst morgen ansehen.
Grüße, Stefan

rds
Beiträge: 17
Registriert: Di 4. Nov 2014, 18:32

Re: Plotten von Messdaten

Beitrag von rds »

Hallo Stefan,
hab den Fehler gefunden. In den Compilereinstellungen war unter LCLWidgetTyp der Haken bei gtk2 gesetzt.
Ich hab ihn weggenommen. Jetzt klappt's.
Grüsse
rds

rds
Beiträge: 17
Registriert: Di 4. Nov 2014, 18:32

Re: Plotten von Messdaten

Beitrag von rds »

Hallo Stefan
anbei ein paar Fragen zu deinen für meine Begriffe wirklich bemerkenswerten Units:
Export/Import: Mit welchem Dateiformat kann ich Daten importieren? Excel?, Import von .csv möglich?
Den Datenexport habe ich ausprobiert. Es wird eine Datei im Format .mdt erzeugt. Mit welchem Programm kann ich das lesen? Access klappt nicht.
Eine ganz dumme Frage: Wie kann ich den Output der Soundkarte mit deinen Units darstellen?
Grüsse rds

magnetron
Beiträge: 44
Registriert: Di 4. Nov 2014, 14:04

Re: Plotten von Messdaten

Beitrag von magnetron »

Hallo rds,

vielen Dank für die positive Rückmeldung. Mich würde natürlich interessieren, was Du mit dem plot vor hast..

Das mit dem export ist eine gute Frage, die ich kurz auflösen kann.
Während das Teil immer grösser wurde, ist mir aufgefallen, dass es nachteilig ist, dass die Datenserien vier
verschiedene Datentypen verwenden (Record mit X,Y Werten, solche mit X,Y,Z Werten und das ganze noch jeweils als
array für die fast series).
Das sollte zukünftig dahingehend modifiziert werden, dass es nur einen Datentyp gibt.
Vorschlag der funktioniert: TMeasResult = record siehe uPlotDataTypes.
Das ist ein Record, wo alles nötige drin steht,
Anzahl der Dimensionen (meist 2 für XY oder 3 für XYZ), Anzahl der Punkte und die Daten.

Der Export / Import läuft nun schon mit diesem Datentyp.
In den Methoden ExportSeriesData und ImportSeriesData der Serien (siehe uPlotSeries)
wird nun der interne Datentyp in ein "TMeasResult" umkopiert.
Dieses wird dann einem TPlot_ResultWriter übergeben (unit uPlot_Resultwriter).

Eine mdt Datei ist meine bisher einzige Implementierung eines TPlot_ResultWriter,
der die Daten einfach mit einem Header versieht und binär in einen filestream schreibt.
Aufgrund der Struktur die keiner kennt (ausser der TPLotResultWriter) kann das erstmal nur mit dem
TPlot_ResultReaderMAAResult (auch unit uPLot_ResultWriter) gelesen werden.
Im kompilierten Demo sollte das im Kontextmenü klappen, da wo auch der export zu finden ist
(Series->name->Data->Import).

Und ich gebe Dir Recht, menschenlesbare Dateien wie s2p oder CSV haben Vorteile.
Die Import/Export Klasse habe ich geschrieben um das Konzept auszuprobieren.
Für ein CSV würde ich nun wenn ich Zeit finde (oder Du ?) in der Unit uPlot_Resultwriter
eine neue Klasse von TPlot_ResultWriter (und ..Reader) ableiten, so wie den
TPlot_ResultWriterMAAResult auch, nur eben nun einen TPlot_ResultWriterCSV der statt einem binären
filestream dann ein CSV schreibt.

Frage dazu: wie schreibe ich am besten ein CSV bzw. ASCII Daten ?
Auch mit TFileStream und einfach ASCII Zeichen rein ?

In der unit uPlotSeries könnte man dann die Methoden ExportSeriesData (und Import...)
anpassen.
Vorschlag:
- Im filedialog filter passend setzen (*.mdt, *.csv)
- Gewünschten Datentyp an Methode ExportSeriesData übergeben
- passenden exporter erzeugen (z.B. dann vExporter := TPlot_ResultWriterCSV.Create
antatt jetzt vExporter := TPlot_ResultWriterMAAResult.Create).
- diesen Exporter vorher programmieren (abgeleitet von TPlot_Resultwriter).
- beim Import umgekehrt genauso

Zum experimentieren... ich habe einen kleinen stand-alone resultviewer hier angehängt.
Dort würde ich neue importer/exporter testen nach dem Motto mdt rein, CSV raus - das könnte man dann
auch zur Konvertierung nutzen bzw. wenn der neue exporter läuft in den Plot aufnehmen.
Das Teil nutzt nur die Plotkomponente (mit Resultwriter etc.) die Du schon hast.

Wegen Soundcard siehe nächsten post... Grüsse, Stefan

p.s. im anliegenden prog bitte wieder compilereinstellungen anpassen (widgetset, prozessor, OS...)
und PlotClass in searchpath aufnehmen.
Dateianhänge
MAA_resultviewer1.lpi.zip
stand alone resultviewer
(6.64 KiB) 246-mal heruntergeladen

magnetron
Beiträge: 44
Registriert: Di 4. Nov 2014, 14:04

Re: Plotten von Messdaten

Beitrag von magnetron »

Die soundcard Frage lässt vermuten, dass Du die Daten von der Soundkarte bereits hast ?
Wenn ja würde mich Deine Lösung sehr interessieren...
Wenn Du also die gesampleten Daten (z.B. 1024 X/Y Werte von der Soundkarte) hast,
dann einfach so:

Code: Alles auswählen

         for vLoop := 0 to vDataSizeInput-1 do begin
           vPlotLine[vLoop].X := Xwerte[vLoop];
           vPlotLine[vLoop].Y := Ywerte[vLoop];
         end;      // sampledaten in eine TXYLine kopieren
         IF TXYSpectrumPlotSeries(Series).Visible THEN
             TXYSpectrumPlotSeries(Series).AddLine(vPlotLine);     // TXYLine in die Plotseries schieben.


Im Demo Beispiel (ohne Soundcard) mache ich das im Timer so:
_GenerateData(vXYLine);
TXYSpectrumPlotSeries(Plot.Series[0]).AddLine(vXYLine);
wobei _GenerateData einfach DummyDaten für einen Sinus erzeugt,
die auch aus der Soundkarte kommen könnten.

Eine "light" Version meiner Soundcard Lösung ohne Aufteilung in dlls (und nur mit einem Teil der units)
stelle ich in kürze vermutlich zur Diskussion auf github, bei Interesse bitte vorab melden.
Ohne Doku leider etwas kompliziert, multithreaded etc.
Vielleicht aber allgemein interessant, weil ich selbst recht wenig zu diesem Thema gefunden habe.

Die einfachere Version:
Daten mit portaudio samplen und in einen (ring)buffer schreiben...
(nachdem ich erst alsa und WAVE api unter windows verwendet habe,
muss nach sehr guten Erfahrungen nun portaudio empfehlen).
Hauptprog Bescheid geben dass Daten da sind...
Im Hauptprog Daten abholen, nach Wunsch verarbeiten (z.B. FFT), dann in Plot schieben.

Auch diese Lösung geht gut. Allerdings läuft dann viel im GUI Thread ab.
Wenn dann zu viele Daten kommen kann es sein, daß die GUI einfriert (im PLot habe ich als Gegenmassnahme
die property TimedRefresh vorgesehen).
Gerade zu dieser performance Thematik würde ich mich dann über Kommentare und Vorschläge freuen.
Irgendwann bei ein paar hundertausend Messpunkten pro Sekunde und vielleicht 100FFTs pro Sekunde
steigt die Prozessorlast doch bedenklich an - ich konnte bislang aber keinen bottleneck finden.

Hoffe das hilft erstmal weiter, Grüsse, Stefan

rds
Beiträge: 17
Registriert: Di 4. Nov 2014, 18:32

Re: Plotten von Messdaten

Beitrag von rds »

Hallo Stefan,

"Mich würde natürlich interessieren, was Du mit dem plot vor hast.."

Ich habe Datenlogger in Grundwassermeßstellen im Einsatz. Da werden Wasserstände über einen längeren Zeitraum stündlich aufgezeichnet. Nach einem bestimmten Beobachtungszeitraum (z.B. einem viertel Jahr) werden die Daten ausgelesen, zB. in dem für solche Anwendungen üblichen .csv-Format. Zur Auswertung und Begutachtung müssen die Daten grafisch dargestellt werden. Im Moment verwende ich dazu MS Excel. Deine Plot-Komponente wäre dazu natürlich auch ideal geeignet. Für die praktische Anwendung wäre natürlich eine Daten-Import/Export-Schnittstelle mit einem Dateiformat wie es von den gängigen Datenerfassungssystemen verwendet wird, von Vorteil.

Zur Soundkartenfrage:
Vieleicht kennst du das Programm SpectrumLab (http://www.qsl.net/dl4yhf/spectra1.html). Mit der Soundkarte werden Frequenzen im ELF und VLF-Bereich empfangen und z.B. "on the fly" als waterfall display geplottet. Im Grunde das, was deine Units leisten können. Meine Frage zielte darauf ab, wie der Datentransfer von der Soundkarte zum Plotprogramm von statten geht, ohne dass eine Sampling-Software dazwischen ist. Es soll ja simultan gehen.
Grüsse
rds

rds
Beiträge: 17
Registriert: Di 4. Nov 2014, 18:32

Re: Plotten von Messdaten

Beitrag von rds »

Nachtrag zum .csv-Problem.
Die Klasse TStringGrid bringt eine Methode namens SaveToCSVFile mit. Das wäre eine Möglichkeit. Es gibt auch Beiträge dazu hier im Forum. Ich komme leider erst am WE dazu etwas rumzuprobieren.

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Plotten von Messdaten

Beitrag von wp_xyz »

Es ist weiter oben der Begriff Excel-Import/Export gefallen: Dafür kannst du fpspreadsheet verwenden: http://wiki.lazarus.freepascal.org/FPSpreadsheet - in dem Artikel findest du auch den Link zum Download.

rds
Beiträge: 17
Registriert: Di 4. Nov 2014, 18:32

Re: Plotten von Messdaten

Beitrag von rds »

Nachtrag zum Sounkarten-Problem: Der direkte Zugriff auf den Output der Soundkarte scheint über bass.dll zu funktionieren, für die es auch Delphi-Anbindungen gibt. Da gibt es also noch viel zu ausprobieren. Vielleicht hat ja jemand in diesem Forum Erfahrung damit. Vielleicht sollte ich im Forum unter Audio/Multimedia einmal nachfragen.
rds

magnetron
Beiträge: 44
Registriert: Di 4. Nov 2014, 14:04

Re: Plotten von Messdaten

Beitrag von magnetron »

Vielen Dank für die Kommentare, auch an wp_xyz.
FPSpreadsheet ist wohl das swiss army knife für Datenaustausch mit Spreadsheets.
Ich hab (nur CSV) nun einfacher gelöst - anbei - würde mich freuen, wenn das funktioniert.
Das ganze nutzt CsvDocument Version 0.5 von Vladimir Zhirov - schönes tool.

Zu beachten ist, dass die Plotkomponente als (nur) Komponente nicht die Fähigkeit hat,
neue Series verschiedener Art on the fly zu erzeugen.
Das geht, sollte aber vom Hauptprog übernommen werden, weil ja nur dieses die Daten kennt
und entscheiden kann wie die Daten dargestellt werden sollen.

Denoch war der vorhandene importer im Plot nun doch eine geeignete Stelle...
Gerade beim CSV gibt es viele Möglichkeiten wie die Daten aussehen und was sie bedeuten.
Ich habe das unter folgender Voraussetzung implementiert:
- Datenpunkte (n>1 Dimensionen) in Reihen
- n Reihen am Beginn können übersprungen werden
- Spalten sind Dimensionen zu den Messpunkten
oder... erste Spalte ist X für alle, jede weitere Spalte ist ein Y Wert verschiedener Datenreihen.
Diese Auswahl und der Delimiter kann eingestellt werden beim Import.

Weitere Datenformate müssten nach Bedarf implementiert werden.
Fehlerhandling für leere Zellen etc. etc. sowie nicht-rechteckige Datensaetze sind nicht implementiert.
Zur Performance: Ist im Moment mit Standard Series xySeries kompiliert, weil da verschiedene Symbole für verschiedene
Datenreihen (schon) implementiert sind. Beim Import grosser Datenmengen klemmts da aber.
Wenn man es mit der XYSpectrum Serie kompiliert (uresultviewer etwa Zeile 137) geht alles schnell
aber es gibt leider (noch) keine Kreuze, Plusse, etc. Symbole für die Datenpunkte (verschiedene Farben natürlich schon).

Bezüglich Soundkarte auch Danke für die Infos. Beide tools scheinen closed source zu sein dafür sehr umfangreich - hab beides noch nicht ausprobiert.
Letztlich nutze ich portaudio (unter windows als portaudio.dll) innerhalb meines Programmes.
Ich erhalte dann (sozusagen auch direkt) die gesampelten Werte von der Soundkarte - nichts weiter dazwischen.
Aus den Werten mache ich (z.B. mit FFTW) eine FFT und schiebe sie in den Plot - geht gut.
Vor portaudio (geht mindestens für windows und linux) habe ich wie gesagt die windows api direkt genutzt (bzw. alsa unter linux).
Mit portaudio geht das aber viel besser und viel einfacher.
Viele Grüsse, Stefan
Dateianhänge
resultviewer_141121.zip
CSV Import Beispiel
(14.98 KiB) 259-mal heruntergeladen
PlotClass_141121b.zip
modified plot includes CSV importer
(119.75 KiB) 248-mal heruntergeladen

rds
Beiträge: 17
Registriert: Di 4. Nov 2014, 18:32

Re: Plotten von Messdaten

Beitrag von rds »

Hallo Stefan,
vielen Dank für deine schnelle Hilfe bzgl. csv-Import/Export. Bin gerade am ausprobieren. Leider klappt es noch nicht.
Beim Compilieren des resultviewer-Beispiels wird die unit uMAADataTypes nicht gefunden. Das Verzeichnis mit den angepassten Plot-Units und auch csvdocument habe ich über den Units-Pfad eingebunden.
Grüsse
rds

magnetron
Beiträge: 44
Registriert: Di 4. Nov 2014, 14:04

Re: Plotten von Messdaten

Beitrag von magnetron »

ups, sorry mein Fehler.
uMAADatatypes hat alles mögliche für meine Messungen ...
Damit das nicht verwirrt habe ich den hier wichtige DatenTyp (TMeasResult) in uPLotDatatypes gepackt.
Bitte nur uMAADataTypes aus den Abhängigkeiten oben in der unit uResultViewer1 entfernen.
Dann sollte es gehen (nach den windows spezifischen Anpassungen für die Compilereinstellungen).

Danke fürs testen, ich glaube es ist ganz gut so, habs probiert - mir ging nur die unit uMAADatatypes wohl durch die Lappen.
Wenn Du im Programm "open" auswählst und dann den Dateifilter CSV und dann eine Datei öffnest,
dann geht das settings Fenster auf, wo Du auswählen kannst, wie die Daten organisiert sind.
IM PLot selbst beim Import in eine "Series" geht erstmal kein CSV, weil ich den Filter *.CSV nicht anbiete.
Ich finde es besser, das Hauptprog erzeugt die Datenserien die es braucht.

Grüße und vorab ein schönes WE, Stefan

Antworten