Compare commits
23 Commits
3.0.1
...
zmq_stream
| Author | SHA1 | Date | |
|---|---|---|---|
| 166e8d325a | |||
| 03ac83adf6 | |||
| edf3672317 | |||
| 10f0fcdde2 | |||
| 19d2b28f25 | |||
| ac04a730a3 | |||
| 87ed988dfe | |||
| fb21986493 | |||
| 1601fbcbfd | |||
| c25a80ddfb | |||
| ba630a44e1 | |||
| 5316773104 | |||
| 38b60f3f5e | |||
| 31d37c7c45 | |||
| 366a7f2a74 | |||
| e5cc3126ab | |||
| 45505b511d | |||
| e21b3d64ee | |||
| 1a294a1a75 | |||
| fb5b2ff257 | |||
| 8d9fba4be6 | |||
| 065ed130a6 | |||
| 074ac2caff |
7
.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/bin
|
||||
/target
|
||||
/build
|
||||
.gradle
|
||||
.settings
|
||||
.project
|
||||
.classpath
|
||||
63
build.gradle
Normal file
@@ -0,0 +1,63 @@
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'eclipse'
|
||||
|
||||
sourceCompatibility = 1.7
|
||||
|
||||
version = '2.6.2'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven { url "http://artifacts.psi.ch/artifactory/libs-releases" }
|
||||
maven { url "http://artifacts.psi.ch/artifactory/libs-snapshots" }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile 'ch.psi:ch.psi.fda.core:2.3.4'
|
||||
compile 'ch.psi.fda:ch.psi.fda.xscan:2.6.2'
|
||||
compile 'ch.psi:ch.psi.fda.cdump:2.3.4'
|
||||
compile 'ch.psi:ch.psi.fda.fdaq:2.3.4'
|
||||
compile 'ch.psi:jcae:2.4.1'
|
||||
compile 'com.google.inject:guice:3.0'
|
||||
compile 'org.glassfish.jersey.containers:jersey-container-grizzly2-http:2.5.1'
|
||||
compile 'org.glassfish.jersey.media:jersey-media-sse:2.5.1'
|
||||
compile 'org.glassfish.jersey.media:jersey-media-json-jackson:2.5.1'
|
||||
compile 'org.zeromq:jeromq:0.3.5'
|
||||
compile 'org.apache.commons:cli:1.2'
|
||||
// For reading/writing Matlab files
|
||||
compile 'com.jmatio:jmatio:0.2u2psi1'
|
||||
// Library for reading/writing XDR Format (MDA)
|
||||
compile 'org.freehep:freehep-xdr:2.0.4'
|
||||
compile 'ch.psi:plot:2.1-SNAPSHOT'
|
||||
|
||||
testCompile 'junit:junit:4.+'
|
||||
}
|
||||
|
||||
task sourcesJar(type: Jar, dependsOn: classes) {
|
||||
classifier = 'sources'
|
||||
from sourceSets.main.allSource
|
||||
}
|
||||
|
||||
task javadocJar(type: Jar, dependsOn: javadoc) {
|
||||
classifier = 'javadoc'
|
||||
from javadoc.destinationDir
|
||||
}
|
||||
|
||||
artifacts {
|
||||
archives sourcesJar
|
||||
archives javadocJar
|
||||
}
|
||||
|
||||
|
||||
apply plugin: 'maven'
|
||||
|
||||
uploadArchives {
|
||||
repositories {
|
||||
mavenDeployer {
|
||||
repository(url: "http://artifacts.psi.ch/artifactory/libs-releases-local"){
|
||||
authentication(userName: "upload", password: "{DESede}eWKHxAtQ2Dc=")
|
||||
}
|
||||
pom.groupId = 'ch.psi'
|
||||
pom.artifactId = 'fda'
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="target/classes" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
1
ch.psi.fda/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
/target
|
||||
@@ -1,23 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>ch.psi.fda</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -1,3 +0,0 @@
|
||||
eclipse.preferences.version=1
|
||||
encoding//src/main/java=UTF-8
|
||||
encoding//src/test/java=UTF-8
|
||||
@@ -1,5 +0,0 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
|
||||
org.eclipse.jdt.core.compiler.compliance=1.7
|
||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
||||
org.eclipse.jdt.core.compiler.source=1.7
|
||||
@@ -1,5 +0,0 @@
|
||||
#Tue Oct 18 15:52:42 CEST 2011
|
||||
activeProfiles=
|
||||
eclipse.preferences.version=1
|
||||
resolveWorkspaceProjects=true
|
||||
version=1
|
||||
@@ -1,2 +0,0 @@
|
||||
# 3.0.0
|
||||
* Update the fda.properties file and replace ch.psi.fda.aq.data.baseDirectory with ch.psi.fda.aq.data.dir.
|
||||
@@ -1,155 +0,0 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>ch.psi</groupId>
|
||||
<artifactId>fda</artifactId>
|
||||
<version>2.4.3</version>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>ch.psi</groupId>
|
||||
<artifactId>ch.psi.fda.core</artifactId>
|
||||
<version>2.3.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- These 3 libraries are just needed for testing -->
|
||||
<dependency>
|
||||
<groupId>ch.psi.fda</groupId>
|
||||
<artifactId>ch.psi.fda.xscan</artifactId>
|
||||
<version>2.3.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.psi</groupId>
|
||||
<artifactId>ch.psi.fda.cdump</artifactId>
|
||||
<version>2.3.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.psi</groupId>
|
||||
<artifactId>ch.psi.fda.fdaq</artifactId>
|
||||
<version>2.3.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>ch.psi</groupId>
|
||||
<artifactId>jcae</artifactId>
|
||||
<version>2.4.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>ch.psi</groupId>
|
||||
<artifactId>plot</artifactId>
|
||||
<version>1.1.31</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.inject</groupId>
|
||||
<artifactId>guice</artifactId>
|
||||
<version>3.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jersey.containers</groupId>
|
||||
<artifactId>jersey-container-grizzly2-http</artifactId>
|
||||
<version>2.5.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jersey.media</groupId>
|
||||
<artifactId>jersey-media-sse</artifactId>
|
||||
<version>2.5.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jersey.media</groupId>
|
||||
<artifactId>jersey-media-json-jackson</artifactId>
|
||||
<version>2.5.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jeromq</groupId>
|
||||
<artifactId>jeromq</artifactId>
|
||||
<version>0.2.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>cli</artifactId>
|
||||
<version>1.2</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Library to Read Matlab Files -->
|
||||
<dependency>
|
||||
<groupId>com.jmatio</groupId>
|
||||
<artifactId>jmatio</artifactId>
|
||||
<version>0.2u2psi1</version>
|
||||
</dependency>
|
||||
<!-- Library for reading/writing XDR Format (MDA) -->
|
||||
<dependency>
|
||||
<groupId>org.freehep</groupId>
|
||||
<artifactId>freehep-xdr</artifactId>
|
||||
<version>2.0.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.8.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<encoding>UTF-8</encoding>
|
||||
<source>1.7</source>
|
||||
<target>1.7</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<configuration>
|
||||
<additionalparam>-Xdoclint:none</additionalparam> <!-- Disable Java8 strict Javadoc checking -->
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-javadocs</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-sources</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<distributionManagement>
|
||||
<snapshotRepository>
|
||||
<id>i.snapshots</id>
|
||||
<name>Artifactory Snapshots</name>
|
||||
<url>http://yoke.psi.ch:8081/artifactory/libs-snapshots-local</url>
|
||||
</snapshotRepository>
|
||||
<repository>
|
||||
<id>i.releases</id>
|
||||
<name>Atrifactory Releases</name>
|
||||
<url>http://yoke.psi.ch:8081/artifactory/libs-releases-local</url>
|
||||
</repository>
|
||||
</distributionManagement>
|
||||
</project>
|
||||
@@ -1,341 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2010 Paul Scherrer Institute. All rights reserved.
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but without any warranty; without even the implied warranty of
|
||||
* merchantability or fitness for a particular purpose. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this code. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.psi.fda.ui.visualizer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
|
||||
import ch.psi.fda.messages.DataMessage;
|
||||
import ch.psi.fda.messages.EndOfStreamMessage;
|
||||
import ch.psi.fda.messages.StreamDelimiterMessage;
|
||||
import ch.psi.fda.vdescriptor.Series;
|
||||
import ch.psi.fda.vdescriptor.VDescriptor;
|
||||
import ch.psi.fda.vdescriptor.XYSeries;
|
||||
import ch.psi.fda.vdescriptor.XYZSeries;
|
||||
import ch.psi.fda.vdescriptor.YSeries;
|
||||
import ch.psi.fda.vdescriptor.YZSeries;
|
||||
import ch.psi.plot.Plot;
|
||||
import ch.psi.plot.xy.LinePlot;
|
||||
import ch.psi.plot.xy.XYSeriesCollectionP;
|
||||
import ch.psi.plot.xy.XYSeriesP;
|
||||
import ch.psi.plot.xyz.MatrixPlot;
|
||||
import ch.psi.plot.xyz.MatrixPlotData;
|
||||
|
||||
/**
|
||||
* Visualizer for visualizing data
|
||||
*/
|
||||
public class Visualizer {
|
||||
|
||||
private static Logger logger = Logger.getLogger(Visualizer.class.getName());
|
||||
|
||||
private boolean updateAtStreamElement = true;
|
||||
private boolean updateAtStreamDelimiter = true;
|
||||
private boolean updateAtEndOfStream = false;
|
||||
|
||||
private int ecount;
|
||||
private boolean clearPlot;
|
||||
private List<SeriesDataFilter> filters;
|
||||
|
||||
private boolean first = true;
|
||||
|
||||
public Visualizer(VDescriptor vdescriptor){
|
||||
filters = new ArrayList<SeriesDataFilter>();
|
||||
|
||||
for(ch.psi.fda.vdescriptor.Plot vplot: vdescriptor.getPlots()){
|
||||
if(vplot instanceof ch.psi.fda.vdescriptor.LinePlot){
|
||||
ch.psi.fda.vdescriptor.LinePlot lp = (ch.psi.fda.vdescriptor.LinePlot) vplot;
|
||||
|
||||
// Create plot for visualization
|
||||
ch.psi.plot.xy.LinePlot plot = new ch.psi.plot.xy.LinePlot(lp.getTitle());
|
||||
|
||||
for(Series s: lp.getData()){
|
||||
if(s instanceof XYSeries){
|
||||
XYSeries sxy = (XYSeries)s;
|
||||
XYSeriesDataFilter filter = new XYSeriesDataFilter(sxy.getX(), sxy.getY(), plot);
|
||||
filter.setSeriesName(sxy.getY());
|
||||
filters.add(filter);
|
||||
}
|
||||
else if(s instanceof YSeries){
|
||||
YSeries sy = (YSeries)s;
|
||||
|
||||
XYSeriesArrayDataFilter filter = new XYSeriesArrayDataFilter(sy.getY(), plot);
|
||||
// filter.setMaxSeries(lp.getMaxSeries()*lp.getY().size()); // Workaround - keep for each array max series
|
||||
// filter.setOffset(lp.getOffset());
|
||||
// filter.setSize(lp.getSize());
|
||||
filter.setSeriesName(sy.getY());
|
||||
filters.add(filter);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if(vplot instanceof ch.psi.fda.vdescriptor.MatrixPlot){
|
||||
|
||||
// MatrixPlot does currently not support RegionPositioners because of the
|
||||
// plotting problems this would cause. If regions of the positioner have different
|
||||
// step sizes it is not easily possible (without (specialized) rasterization) to plot the data.
|
||||
|
||||
ch.psi.fda.vdescriptor.MatrixPlot lp = (ch.psi.fda.vdescriptor.MatrixPlot) vplot;
|
||||
MatrixPlotData data = new MatrixPlotData(lp.getMinX(), lp.getMaxX(), lp.getnX(), lp.getMinY(), lp.getMaxY(), lp.getnY());
|
||||
MatrixPlot plot = new MatrixPlot(lp.getTitle(), data);
|
||||
|
||||
for(Series s: lp.getData()){
|
||||
if(s instanceof XYZSeries){
|
||||
XYZSeries sxyz = (XYZSeries) s;
|
||||
filters.add(new XYZSeriesDataFilter(sxyz.getX(), sxyz.getY(), sxyz.getZ(), plot));
|
||||
|
||||
}
|
||||
else if(s instanceof YZSeries){
|
||||
YZSeries syz = (YZSeries) s;
|
||||
XYZSeriesArrayDataFilter filter = new XYZSeriesArrayDataFilter(syz.getY(), syz.getZ(), 0, 0, plot);
|
||||
filters.add(filter);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Subscribe
|
||||
public void onDataMessage(final DataMessage message){
|
||||
|
||||
if(first){
|
||||
first=false;
|
||||
// filters = VisMapper.mapVisualizations(visualizations);
|
||||
// TODO somehow handle dimension / clear
|
||||
}
|
||||
|
||||
// Clear is here as the plot should not be cleared after the last point is plotted
|
||||
// but just before the first point of the next plot (cycle)
|
||||
if (clearPlot) {
|
||||
for (SeriesDataFilter f: filters) {
|
||||
Plot plot = f.getPlot();
|
||||
if(plot instanceof MatrixPlot){
|
||||
((MatrixPlotData) ((MatrixPlot)plot).getData()).clear();
|
||||
}
|
||||
}
|
||||
clearPlot = false;
|
||||
}
|
||||
|
||||
for(SeriesDataFilter filter: filters){
|
||||
if(filter instanceof XYSeriesDataFilter){
|
||||
XYSeriesDataFilter xyfilter = (XYSeriesDataFilter) filter;
|
||||
|
||||
if(xyfilter.getActualSeries()==null || xyfilter.isNewseries()){
|
||||
// First series that is filled by this filter!
|
||||
XYSeriesP s = new XYSeriesP(xyfilter.getSeriesName() + " " + ecount + "-" + xyfilter.getCount());
|
||||
((LinePlot)xyfilter.getPlot()).getData().addSeries(s);
|
||||
xyfilter.setActualSeries(s);
|
||||
xyfilter.setNewseries(false);
|
||||
}
|
||||
|
||||
XYSeriesP series = xyfilter.getActualSeries(); // TODO Does not work with multiple series filter per plot !!!!
|
||||
|
||||
// There might be other values than double in the data, therefore we have to check for it
|
||||
Object dX = message.getData(xyfilter.getIdX());
|
||||
Object dY = message.getData(xyfilter.getIdY());
|
||||
Double dataX = Double.NaN;
|
||||
Double dataY = Double.NaN;
|
||||
if(dX instanceof Double){
|
||||
dataX = (Double) dX;
|
||||
}
|
||||
if(dY instanceof Double){
|
||||
dataY = (Double) dY;
|
||||
}
|
||||
|
||||
// Add Data to the series
|
||||
series.add(dataX , dataY, updateAtStreamElement);
|
||||
}
|
||||
if(filter instanceof XYSeriesArrayDataFilter){
|
||||
final XYSeriesArrayDataFilter xyfilter = (XYSeriesArrayDataFilter) filter;
|
||||
|
||||
// Ensure that there is no concurrent modification exception or synchronization problems with the
|
||||
// Swing update task
|
||||
SwingUtilities.invokeLater(new Runnable(){
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
XYSeriesP series = new XYSeriesP(xyfilter.getSeriesName() + "-" + xyfilter.getCount()); // Series name must be unique
|
||||
xyfilter.incrementCount();
|
||||
|
||||
// ((LinePlot)xyfilter.getPlot()).getData().removeAllSeries(); // Remove all series from the data
|
||||
// If we can agree only to display one series at a time also a clear() on the actual series is better
|
||||
XYSeriesCollectionP sc = ((LinePlot)xyfilter.getPlot()).getData();
|
||||
sc.addSeries(series);
|
||||
|
||||
// Remove outdated series
|
||||
if(sc.getSeriesCount()>xyfilter.getMaxSeries()){
|
||||
// Remove oldest series
|
||||
sc.removeSeries(0);
|
||||
}
|
||||
|
||||
double[] data = message.getData(xyfilter.getIdY());
|
||||
// Copy data starting from offset to size
|
||||
int size = data.length;
|
||||
int offset = xyfilter.getOffset();
|
||||
if(xyfilter.getSize()>0 && offset+xyfilter.getSize()<data.length){
|
||||
size = offset + xyfilter.getSize();
|
||||
}
|
||||
for(int i=offset;i<size;i++){
|
||||
series.add(i,data[i], false); // Do not fire change event - this would degrade performance drastically
|
||||
}
|
||||
series.fireSeriesChanged();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
else if(filter instanceof XYZSeriesDataFilter){
|
||||
XYZSeriesDataFilter xyzfilter = (XYZSeriesDataFilter) filter;
|
||||
try{
|
||||
((MatrixPlot)xyzfilter.getPlot()).getData().addData((Double) message.getData(xyzfilter.getIdX()),(Double) message.getData(xyzfilter.getIdY()), (Double) message.getData(xyzfilter.getIdZ()));
|
||||
}
|
||||
catch (Exception e) {
|
||||
// Ignore if something goes wrong while adding a datapoint
|
||||
logger.log(Level.WARNING, "Unable to plot datapoint in matrix plot", e);
|
||||
}
|
||||
}
|
||||
else if(filter instanceof XYZSeriesArrayDataFilter){
|
||||
XYZSeriesArrayDataFilter xyzfilter = (XYZSeriesArrayDataFilter) filter;
|
||||
try{
|
||||
double[] data = (double[]) message.getData(xyzfilter.getIdZ());
|
||||
double y = (Double) message.getData(xyzfilter.getIdY());
|
||||
// int offset = xyzfilter.getOffset();
|
||||
// int size = xyzfilter.getSize();
|
||||
// for(int i=offset;i<offset+size; i++){
|
||||
for(int i=0;i<data.length; i++){
|
||||
((MatrixPlot)xyzfilter.getPlot()).getData().addData(i, y, data[i]);
|
||||
}
|
||||
// Update data if update by point is enabled
|
||||
if(updateAtStreamElement){
|
||||
xyzfilter.getPlot().update();
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
// Ignore if something goes wrong while adding a datapoint
|
||||
logger.log(Level.WARNING, "Unable to plot datapoint in matrix plot", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Subscribe
|
||||
public void onStreamDelimiterMessage(StreamDelimiterMessage message){
|
||||
for(SeriesDataFilter filter: filters){
|
||||
if(filter instanceof XYSeriesDataFilter){
|
||||
// Create new series
|
||||
XYSeriesDataFilter xyfilter = (XYSeriesDataFilter) filter;
|
||||
// if (message.getNumber() == xyfilter.getDimensionX()) {
|
||||
if (message.getNumber() == 0) { // TODO need to check this - here we assume that always at the lowest level we create a new series
|
||||
// Indicate to create new series at the next message
|
||||
xyfilter.setCount(xyfilter.getCount()+1); // Increment count of the filter
|
||||
xyfilter.setNewseries(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update matrix plot at the end of each line
|
||||
if(updateAtStreamDelimiter){
|
||||
for(SeriesDataFilter f: filters){
|
||||
Plot plot = f.getPlot();
|
||||
// for (Plot plot: plots) {
|
||||
if(plot instanceof MatrixPlot){
|
||||
((MatrixPlot)plot).update();
|
||||
}
|
||||
else if(plot instanceof LinePlot){
|
||||
((LinePlot) plot).update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clear matrix plot if iflag is encountered
|
||||
// TODO: One need to check whether the iflag belongs to a delimiter
|
||||
// of a higher dimension than the highest dimension (axis) that
|
||||
// is involved in the plot
|
||||
if (message.isIflag()) {
|
||||
clearPlot = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onEndOfStreamMessage(EndOfStreamMessage message){
|
||||
ecount++;
|
||||
|
||||
// Update plots if updateAtEndOfStream flag is set
|
||||
if(updateAtEndOfStream){
|
||||
// Update matrix plots
|
||||
for(SeriesDataFilter f: filters){
|
||||
Plot plot = f.getPlot();
|
||||
if(plot instanceof MatrixPlot){
|
||||
((MatrixPlot)plot).update();
|
||||
((MatrixPlot)plot).adaptColorMapScale(); // Update color scale at the end
|
||||
}
|
||||
else if(plot instanceof LinePlot){
|
||||
((LinePlot) plot).update();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void configure(){
|
||||
ecount = 0;
|
||||
clearPlot = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the plot panels for the visualizations
|
||||
* @return List of configured JPanels
|
||||
*/
|
||||
public List<JPanel> getPlotPanels(){
|
||||
List<JPanel> panels = new ArrayList<JPanel>();
|
||||
for(SeriesDataFilter f: filters){
|
||||
panels.add(f.getPlot().getChartPanel());
|
||||
}
|
||||
|
||||
return panels;
|
||||
}
|
||||
|
||||
public boolean isUpdateAtStreamElement() {
|
||||
return updateAtStreamElement;
|
||||
}
|
||||
public void setUpdateAtStreamElement(boolean updateAtStreamElement) {
|
||||
this.updateAtStreamElement = updateAtStreamElement;
|
||||
}
|
||||
public boolean isUpdateAtStreamDelimiter() {
|
||||
return updateAtStreamDelimiter;
|
||||
}
|
||||
public void setUpdateAtStreamDelimiter(boolean updateAtStreamDelimiter) {
|
||||
this.updateAtStreamDelimiter = updateAtStreamDelimiter;
|
||||
}
|
||||
public boolean isUpdateAtEndOfStream() {
|
||||
return updateAtEndOfStream;
|
||||
}
|
||||
public void setUpdateAtEndOfStream(boolean updateAtEndOfStream) {
|
||||
this.updateAtEndOfStream = updateAtEndOfStream;
|
||||
}
|
||||
|
||||
}
|
||||
|
Before Width: | Height: | Size: 9.7 KiB After Width: | Height: | Size: 9.7 KiB |
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 730 B After Width: | Height: | Size: 730 B |
|
Before Width: | Height: | Size: 854 B After Width: | Height: | Size: 854 B |
|
Before Width: | Height: | Size: 730 B After Width: | Height: | Size: 730 B |
|
Before Width: | Height: | Size: 730 B After Width: | Height: | Size: 730 B |
|
Before Width: | Height: | Size: 766 B After Width: | Height: | Size: 766 B |
|
Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 8.6 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
@@ -24,7 +24,7 @@ import java.io.ObjectOutputStream;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.jeromq.ZMQ;
|
||||
import org.zeromq.ZMQ;
|
||||
|
||||
import ch.psi.fda.messages.Message;
|
||||
|
||||
@@ -51,8 +51,8 @@ public class ZMQDataService {
|
||||
}
|
||||
|
||||
public void initialize(){
|
||||
context = ZMQ.context();
|
||||
zmq.ZError.clear(); // Clear error code
|
||||
context = ZMQ.context(1);
|
||||
// zmq.ZError.clear(); // Clear error code
|
||||
socket = context.socket(ZMQ.PUB);
|
||||
socket.setHWM(bufferSize);
|
||||
socket.bind("tcp://*:"+port);
|
||||
@@ -61,7 +61,7 @@ public class ZMQDataService {
|
||||
public void terminate(){
|
||||
socket.close();
|
||||
context.term();
|
||||
zmq.ZError.clear(); // Clear error code
|
||||
// zmq.ZError.clear(); // Clear error code
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@@ -46,7 +46,6 @@ public class SerializerMAT {
|
||||
|
||||
/**
|
||||
* Construtor
|
||||
* @param queue Data queue holding the data to serialize
|
||||
* @param file Name of the Matlab file to serialize the data to
|
||||
*/
|
||||
public SerializerMAT(File file){
|
||||
@@ -58,7 +58,6 @@ public class SerializerMAT2D {
|
||||
private List<Metadata> metadata;
|
||||
|
||||
/**
|
||||
* @param queue Data queue holding the data to serialize
|
||||
* @param file Name of the Matlab file to serialize the data to
|
||||
*/
|
||||
public SerializerMAT2D(File file){
|
||||
@@ -63,7 +63,6 @@ public class SerializerMAT2DZigZag {
|
||||
|
||||
/**
|
||||
* Construtor
|
||||
* @param queue Data queue holding the data to serialize
|
||||
* @param file Name of the Matlab file to serialize the data to
|
||||
*/
|
||||
public SerializerMAT2DZigZag(File file){
|
||||
@@ -53,7 +53,6 @@ public class SerializerTXT2D {
|
||||
private List<Metadata> metadata;
|
||||
|
||||
/**
|
||||
* @param queue Data queue holding the data to serialize
|
||||
* @param file Name of the Matlab file to serialize the data to
|
||||
*/
|
||||
public SerializerTXT2D(File file){
|
||||
@@ -71,7 +71,6 @@ import ch.psi.jcae.impl.DefaultChannelService;
|
||||
/**
|
||||
* Entry class for command line based data acquisition
|
||||
*/
|
||||
@SuppressWarnings("restriction")
|
||||
public class AcquisitionMain {
|
||||
|
||||
private static Logger logger = Logger.getLogger(AcquisitionMain.class.getName());
|
||||
@@ -175,7 +174,6 @@ public class AcquisitionMain {
|
||||
* @param iterations Number of iterations
|
||||
* @param autoclose Flag whether to close the application automatically after the scan
|
||||
* @param nogui Flag whether to run the scan with a GUI
|
||||
* @param variables Table of scan variables
|
||||
*/
|
||||
public static void run(final File file, Integer iterations, boolean autoclose, boolean nogui){
|
||||
|
||||
@@ -94,9 +94,9 @@ public class ApplicationConfigurator {
|
||||
* Function to determine home directory. This function assumes that the application directories are
|
||||
* ordered as follows:
|
||||
* HOME
|
||||
* |-<version>
|
||||
* |-version
|
||||
* | |-lib
|
||||
* | | |-<jars>
|
||||
* | | |-jars
|
||||
* | |-bin
|
||||
* |-config
|
||||
* |-logs
|
||||
@@ -104,7 +104,7 @@ public class ApplicationConfigurator {
|
||||
* |-scans
|
||||
* | |-templates
|
||||
* | |-users
|
||||
* @return
|
||||
* @return file
|
||||
*/
|
||||
public File determineHome(){
|
||||
File home = null;
|
||||
@@ -144,8 +144,6 @@ public class ApplicationConfigurator {
|
||||
/**
|
||||
* Initialize fda home directory
|
||||
* Will create the home directory directory structure
|
||||
*
|
||||
* @param home Home directory
|
||||
*/
|
||||
public void createApplicationHome(){
|
||||
|
||||
@@ -57,13 +57,6 @@ public class ConversionMain {
|
||||
public enum Reader {TXT, MDA};
|
||||
|
||||
|
||||
/**
|
||||
* Visualize data
|
||||
* @param input
|
||||
* @param output
|
||||
* @param writer Type of writer to use
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void convert(File input, File output, Reader reader, Writer writer) throws InterruptedException{
|
||||
|
||||
// Check existence input file
|
||||
@@ -65,7 +65,6 @@ import ch.psi.fda.messages.EndOfStreamMessage;
|
||||
import ch.psi.fda.ui.visualizer.Visualizer;
|
||||
import ch.psi.fda.vdescriptor.VDescriptor;
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
public class RemoteAcquisitionMain {
|
||||
|
||||
private static Logger logger = Logger.getLogger(RemoteAcquisitionMain.class.getName());
|
||||
@@ -144,12 +143,6 @@ public class RemoteAcquisitionMain {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Execute the given scan on the server
|
||||
* @param file
|
||||
* @param iterations
|
||||
* @param nogui
|
||||
*/
|
||||
public void execute(final String server, File file, boolean nogui) {
|
||||
|
||||
trackingId = UUID.randomUUID().toString();
|
||||
@@ -30,7 +30,7 @@ import java.util.logging.Logger;
|
||||
import org.codehaus.jackson.JsonFactory;
|
||||
import org.codehaus.jackson.map.ObjectMapper;
|
||||
import org.codehaus.jackson.type.TypeReference;
|
||||
import org.jeromq.ZMQ;
|
||||
import org.zeromq.ZMQ;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
@@ -48,11 +48,11 @@ public class StreamClient {
|
||||
}
|
||||
|
||||
public void listen(String endpoint) {
|
||||
ZMQ.Context context = ZMQ.context();
|
||||
zmq.ZError.clear(); // Clear error code
|
||||
ZMQ.Context context = ZMQ.context(1);
|
||||
// zmq.ZError.clear(); // Clear error code
|
||||
ZMQ.Socket socket = context.socket(ZMQ.SUB);
|
||||
socket.connect(endpoint);
|
||||
socket.subscribe(""); // SUBSCRIBE !
|
||||
socket.subscribe("".getBytes()); // SUBSCRIBE !
|
||||
|
||||
while (true) {
|
||||
String tid = null;
|
||||
@@ -34,7 +34,6 @@ import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTabbedPane;
|
||||
import javax.swing.ScrollPaneLayout;
|
||||
import javax.xml.bind.JAXBException;
|
||||
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
import org.apache.commons.cli.CommandLineParser;
|
||||
@@ -44,7 +43,6 @@ import org.apache.commons.cli.Option;
|
||||
import org.apache.commons.cli.OptionBuilder;
|
||||
import org.apache.commons.cli.Options;
|
||||
import org.apache.commons.cli.ParseException;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import com.google.common.eventbus.AsyncEventBus;
|
||||
import com.google.common.eventbus.EventBus;
|
||||
@@ -69,14 +67,7 @@ public class VisualizationMain {
|
||||
public VisualizationMain(){
|
||||
}
|
||||
|
||||
/**
|
||||
* Visualize data based on the configuration file
|
||||
* @param configuration
|
||||
* @param data
|
||||
* @throws InterruptedException
|
||||
* @throws SAXException
|
||||
* @throws JAXBException
|
||||
*/
|
||||
// Visualize data based on the configuration file
|
||||
public void visualize(File configuration, File data) throws InterruptedException{
|
||||
|
||||
if(configuration==null){
|
||||
@@ -103,12 +94,6 @@ public class VisualizationMain {
|
||||
visualize(vdescriptor, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Visualize data
|
||||
* @param configuration
|
||||
* @param data
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void visualize(VDescriptor vdescriptor, File data) throws InterruptedException{
|
||||
|
||||
if(data==null){
|
||||
@@ -130,7 +115,7 @@ public class VisualizationMain {
|
||||
visualizer.setUpdateAtStreamElement(false);
|
||||
visualizer.setUpdateAtStreamDelimiter(false);
|
||||
visualizer.setUpdateAtEndOfStream(true);
|
||||
|
||||
|
||||
JPanel opanel = new ScrollableFlowPanel();
|
||||
opanel.setLayout(new FlowLayout());
|
||||
|
||||
@@ -59,12 +59,7 @@ public class VisualizationZMQMain {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visualize data
|
||||
* @param configuration
|
||||
* @param data
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
|
||||
public void visualize() throws InterruptedException{
|
||||
|
||||
final JPanel opanel = new ScrollableFlowPanel();
|
||||
@@ -20,11 +20,13 @@
|
||||
package ch.psi.fda.ui.visualizer;
|
||||
|
||||
import ch.psi.plot.Plot;
|
||||
import ch.psi.plot.PlotSeries;
|
||||
|
||||
public interface SeriesDataFilter {
|
||||
/**
|
||||
* Get the plot for the filter
|
||||
* @return
|
||||
* @return Plot
|
||||
*/
|
||||
public Plot getPlot();
|
||||
public PlotSeries getSeries();
|
||||
}
|
||||
415
src/main/java/ch/psi/fda/ui/visualizer/Visualizer.java
Normal file
@@ -0,0 +1,415 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2010 Paul Scherrer Institute. All rights reserved.
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but without any warranty; without even the implied warranty of
|
||||
* merchantability or fitness for a particular purpose. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this code. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.psi.fda.ui.visualizer;
|
||||
|
||||
import ch.psi.fda.messages.DataMessage;
|
||||
import ch.psi.fda.messages.EndOfStreamMessage;
|
||||
import ch.psi.fda.messages.StreamDelimiterMessage;
|
||||
import ch.psi.fda.vdescriptor.Series;
|
||||
import ch.psi.fda.vdescriptor.VDescriptor;
|
||||
import ch.psi.fda.vdescriptor.XYSeries;
|
||||
import ch.psi.fda.vdescriptor.XYZSeries;
|
||||
import ch.psi.fda.vdescriptor.YSeries;
|
||||
import ch.psi.fda.vdescriptor.YZSeries;
|
||||
import ch.psi.plot.LinePlot;
|
||||
import ch.psi.plot.LinePlotBase;
|
||||
import ch.psi.plot.LinePlotSeries;
|
||||
import ch.psi.plot.MatrixPlot;
|
||||
import ch.psi.plot.MatrixPlotBase;
|
||||
import ch.psi.plot.MatrixPlotSeries;
|
||||
import ch.psi.plot.Plot;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
import java.awt.Font;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
/**
|
||||
* Visualizer for visualizing data
|
||||
*/
|
||||
public class Visualizer {
|
||||
|
||||
private static Logger logger = Logger.getLogger(Visualizer.class.getName());
|
||||
|
||||
private boolean updateAtStreamElement = true;
|
||||
private boolean updateAtStreamDelimiter = true;
|
||||
private boolean updateAtEndOfStream = false;
|
||||
|
||||
private int ecount;
|
||||
private boolean clearPlot;
|
||||
private List<SeriesDataFilter> filters;
|
||||
|
||||
int subsampling;
|
||||
int subsamplingCounter=0;
|
||||
|
||||
public static final Font TITLE_FONT = new Font("Tahoma", Font.BOLD, 18);
|
||||
|
||||
private boolean first = true;
|
||||
public Visualizer(VDescriptor vdescriptor){
|
||||
this(vdescriptor,null);
|
||||
}
|
||||
public Visualizer(VDescriptor vdescriptor, String linePlotImpl){
|
||||
if (linePlotImpl==null){
|
||||
linePlotImpl="jfree";
|
||||
}
|
||||
String matrixPlotImpl="jfree";
|
||||
|
||||
filters = new ArrayList<SeriesDataFilter>();
|
||||
|
||||
try{
|
||||
for(ch.psi.fda.vdescriptor.Plot vplot: vdescriptor.getPlots()){
|
||||
if(vplot instanceof ch.psi.fda.vdescriptor.LinePlot){
|
||||
ch.psi.fda.vdescriptor.LinePlot lp = (ch.psi.fda.vdescriptor.LinePlot) vplot;
|
||||
|
||||
// Create plot for visualization
|
||||
LinePlot plot = LinePlotBase.newPlot(linePlotImpl);
|
||||
plot.setTitle(lp.getTitle());
|
||||
plot.getAxis(Plot.AxisId.X).setLabel(null);
|
||||
plot.getAxis(Plot.AxisId.Y).setLabel(null);
|
||||
plot.setTitleFont(TITLE_FONT);
|
||||
|
||||
for(Series s: lp.getData()){
|
||||
if(s instanceof XYSeries){
|
||||
XYSeries sxy = (XYSeries)s;
|
||||
XYSeriesDataFilter filter = new XYSeriesDataFilter(sxy.getX(), sxy.getY(), plot);
|
||||
filter.setSeriesName(sxy.getY());
|
||||
if (sxy.getMaxItemCount()>=0)
|
||||
filter.setMaxNumberOfPoints(sxy.getMaxItemCount());
|
||||
filters.add(filter);
|
||||
}
|
||||
else if(s instanceof YSeries){
|
||||
YSeries sy = (YSeries)s;
|
||||
|
||||
XYSeriesArrayDataFilter filter = new XYSeriesArrayDataFilter(sy.getY(), plot);
|
||||
// filter.setMaxSeries(lp.getMaxSeries()*lp.getY().size()); // Workaround - keep for each array max series
|
||||
// filter.setOffset(lp.getOffset());
|
||||
// filter.setSize(lp.getSize());
|
||||
filter.setMaxSeries(lp.getMaxSeries());
|
||||
filter.setOffset(lp.getMinX().intValue());
|
||||
filter.setSize(Double.valueOf(lp.getMaxX()-lp.getMinX()).intValue());
|
||||
filter.setSeriesName(sy.getY());
|
||||
filters.add(filter);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if(vplot instanceof ch.psi.fda.vdescriptor.MatrixPlot){
|
||||
|
||||
// MatrixPlot does currently not support RegionPositioners because of the
|
||||
// plotting problems this would cause. If regions of the positioner have different
|
||||
// step sizes it is not easily possible (without (specialized) rasterization) to plot the data.
|
||||
|
||||
ch.psi.fda.vdescriptor.MatrixPlot lp = (ch.psi.fda.vdescriptor.MatrixPlot) vplot;
|
||||
MatrixPlotSeries data = new MatrixPlotSeries("", lp.getMinX(), lp.getMaxX(), lp.getnX(), lp.getMinY(), lp.getMaxY(), lp.getnY());
|
||||
if ("3D".equals(lp.getType()))
|
||||
matrixPlotImpl="jzy3d";
|
||||
MatrixPlot plot = MatrixPlotBase.newPlot(matrixPlotImpl);
|
||||
plot.setTitle(lp.getTitle());
|
||||
plot.setTitleFont(TITLE_FONT);
|
||||
plot.addSeries(data);
|
||||
|
||||
for(Series s: lp.getData()){
|
||||
if(s instanceof XYZSeries){
|
||||
XYZSeries sxyz = (XYZSeries) s;
|
||||
XYZSeriesDataFilter filter=new XYZSeriesDataFilter(sxyz.getX(), sxyz.getY(), sxyz.getZ(), plot);
|
||||
filter.setSeries(data);
|
||||
filters.add(filter);
|
||||
|
||||
}
|
||||
else if(s instanceof YZSeries){
|
||||
YZSeries syz = (YZSeries) s;
|
||||
XYZSeriesArrayDataFilter filter = new XYZSeriesArrayDataFilter(syz.getY(), syz.getZ(), 0, 0, plot);
|
||||
filter.setSeries(data);
|
||||
filters.add(filter);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// Ignore if something goes wrong while adding a datapoint
|
||||
logger.log(Level.SEVERE, null, ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Subscribe
|
||||
public void onDataMessage(final DataMessage message){
|
||||
|
||||
if(first){
|
||||
first=false;
|
||||
// filters = VisMapper.mapVisualizations(visualizations);
|
||||
// TODO somehow handle dimension / clear
|
||||
}
|
||||
|
||||
// Clear is here as the plot should not be cleared after the last point is plotted
|
||||
// but just before the first point of the next plot (cycle)
|
||||
if (clearPlot) {
|
||||
for (SeriesDataFilter f: filters) {
|
||||
Plot plot = f.getPlot();
|
||||
if(plot instanceof MatrixPlot){
|
||||
f.getSeries().clear();
|
||||
}
|
||||
}
|
||||
clearPlot = false;
|
||||
}
|
||||
|
||||
if (subsampling>1){
|
||||
if ((subsamplingCounter++) > subsampling) {
|
||||
subsamplingCounter=0;
|
||||
}
|
||||
else{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for(SeriesDataFilter filter: filters){
|
||||
if(filter instanceof XYSeriesDataFilter){
|
||||
XYSeriesDataFilter xyfilter = (XYSeriesDataFilter) filter;
|
||||
|
||||
if(xyfilter.getSeries()==null || xyfilter.isNewseries()){
|
||||
// First series that is filled by this filter!
|
||||
LinePlotSeries s = new LinePlotSeries(xyfilter.getSeriesName() + " " + ecount + "-" + xyfilter.getCount());
|
||||
if (xyfilter.getMaxNumberOfPoints()>=0)
|
||||
s.setMaxItemCount(xyfilter.getMaxNumberOfPoints());
|
||||
((LinePlot)xyfilter.getPlot()).addSeries(s);
|
||||
xyfilter.setSeries(s);
|
||||
xyfilter.setNewseries(false);
|
||||
}
|
||||
|
||||
LinePlotSeries series = xyfilter.getSeries(); // TODO Does not work with multiple series filter per plot !!!!
|
||||
|
||||
// There might be other values than double in the data, therefore we have to check for it
|
||||
Object dX = message.getData(xyfilter.getIdX());
|
||||
Object dY = message.getData(xyfilter.getIdY());
|
||||
Double dataX = getDoubleValue (dX);
|
||||
Double dataY = getDoubleValue (dY);
|
||||
|
||||
// Add Data to the series
|
||||
((LinePlot)xyfilter.getPlot()).setUpdatesEnabled(updateAtStreamElement);
|
||||
series.appendData(dataX , dataY);
|
||||
((LinePlot)xyfilter.getPlot()).setUpdatesEnabled(true);
|
||||
}
|
||||
if(filter instanceof XYSeriesArrayDataFilter){
|
||||
final XYSeriesArrayDataFilter xyfilter = (XYSeriesArrayDataFilter) filter;
|
||||
|
||||
// Ensure that there is no concurrent modification exception or synchronization problems with the
|
||||
// Swing update task
|
||||
SwingUtilities.invokeLater(new Runnable(){
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
LinePlotSeries series = new LinePlotSeries(xyfilter.getSeriesName() + "-" + xyfilter.getCount()); // Series name must be unique
|
||||
xyfilter.incrementCount();
|
||||
|
||||
// ((LinePlot)xyfilter.getPlot()).getData().removeAllSeries(); // Remove all series from the data
|
||||
// If we can agree only to display one series at a time also a clear() on the actual series is better
|
||||
((LinePlot)xyfilter.getPlot()).addSeries(series);
|
||||
xyfilter.setSeries(series);
|
||||
|
||||
// Remove outdated series
|
||||
if(((LinePlot)xyfilter.getPlot()).getNumberOfSeries()>xyfilter.getMaxSeries()){
|
||||
// Remove oldest series
|
||||
LinePlotSeries s = ((LinePlot)xyfilter.getPlot()).getSeries(0);
|
||||
((LinePlot)xyfilter.getPlot()).removeSeries(s);
|
||||
}
|
||||
|
||||
double[] data = message.getData(xyfilter.getIdY());
|
||||
|
||||
|
||||
// Copy data starting from offset to size
|
||||
int size = data.length;
|
||||
int offset = xyfilter.getOffset();
|
||||
if(xyfilter.getSize()>0 && offset+xyfilter.getSize()<data.length){
|
||||
size = offset + xyfilter.getSize();
|
||||
}
|
||||
|
||||
((LinePlot)xyfilter.getPlot()).setUpdatesEnabled(updateAtStreamElement);
|
||||
for(int i=offset;i<size;i++){
|
||||
//series.add(i,data[i], false); // Do not fire change event - this would degrade performance drastically
|
||||
series.appendData(i,data[i]);
|
||||
}
|
||||
((LinePlot)xyfilter.getPlot()).setUpdatesEnabled(true);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
else if(filter instanceof XYZSeriesDataFilter){
|
||||
XYZSeriesDataFilter xyzfilter = (XYZSeriesDataFilter) filter;
|
||||
try{
|
||||
xyzfilter.getPlot().setUpdatesEnabled(updateAtStreamElement);
|
||||
xyzfilter.getSeries().appendData((Double) message.getData(xyzfilter.getIdX()),(Double) message.getData(xyzfilter.getIdY()), (Double) message.getData(xyzfilter.getIdZ()));
|
||||
xyzfilter.getPlot().setUpdatesEnabled(true);
|
||||
}
|
||||
catch (Exception e) {
|
||||
// Ignore if something goes wrong while adding a datapoint
|
||||
logger.log(Level.WARNING, "Unable to plot datapoint in matrix plot", e);
|
||||
}
|
||||
}
|
||||
else if(filter instanceof XYZSeriesArrayDataFilter){
|
||||
XYZSeriesArrayDataFilter xyzfilter = (XYZSeriesArrayDataFilter) filter;
|
||||
try{
|
||||
double[] data = (double[]) message.getData(xyzfilter.getIdZ());
|
||||
double y = (Double) message.getData(xyzfilter.getIdY());
|
||||
// int offset = xyzfilter.getOffset();
|
||||
// int size = xyzfilter.getSize();
|
||||
// for(int i=offset;i<offset+size; i++){
|
||||
xyzfilter.getPlot().setUpdatesEnabled(updateAtStreamElement);
|
||||
for(int i=0;i<data.length; i++){
|
||||
((MatrixPlot)xyzfilter.getPlot()).getSeries("").appendData(i, y, data[i]);
|
||||
}
|
||||
xyzfilter.getPlot().setUpdatesEnabled(true);
|
||||
}
|
||||
catch (Exception e) {
|
||||
// Ignore if something goes wrong while adding a datapoint
|
||||
logger.log(Level.WARNING, "Unable to plot datapoint in matrix plot", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Double getDoubleValue(Object value){
|
||||
if(value instanceof Double){
|
||||
return (Double) value;
|
||||
}
|
||||
if(value instanceof Integer){
|
||||
return (double)((Integer) value);
|
||||
}
|
||||
else if(value instanceof Short){
|
||||
return (double)((Short) value);
|
||||
}
|
||||
else if(value instanceof Long){
|
||||
return (double)((Long) value);
|
||||
}
|
||||
else if(value instanceof Float){
|
||||
return (double)((Float) value);
|
||||
}
|
||||
else if(value instanceof Boolean){
|
||||
return ((Boolean) value)?1.0:0.0;
|
||||
}
|
||||
return Double.NaN;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onStreamDelimiterMessage(StreamDelimiterMessage message){
|
||||
for(SeriesDataFilter filter: filters){
|
||||
if(filter instanceof XYSeriesDataFilter){
|
||||
// Create new series
|
||||
XYSeriesDataFilter xyfilter = (XYSeriesDataFilter) filter;
|
||||
// if (message.getNumber() == xyfilter.getDimensionX()) {
|
||||
if (message.getNumber() == 0) { // TODO need to check this - here we assume that always at the lowest level we create a new series
|
||||
// Indicate to create new series at the next message
|
||||
xyfilter.setCount(xyfilter.getCount()+1); // Increment count of the filter
|
||||
xyfilter.setNewseries(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update matrix plot at the end of each line
|
||||
if(updateAtStreamDelimiter){
|
||||
for (Plot plot:getPlots()) {
|
||||
plot.update(true);
|
||||
}
|
||||
}
|
||||
|
||||
// Clear matrix plot if iflag is encountered
|
||||
// TODO: One need to check whether the iflag belongs to a delimiter
|
||||
// of a higher dimension than the highest dimension (axis) that
|
||||
// is involved in the plot
|
||||
if (message.isIflag()) {
|
||||
clearPlot = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onEndOfStreamMessage(EndOfStreamMessage message){
|
||||
ecount++;
|
||||
|
||||
// Update plots if updateAtEndOfStream flag is set
|
||||
if(updateAtEndOfStream){
|
||||
// Update matrix plots
|
||||
for (Plot plot:getPlots()) {
|
||||
plot.update(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void configure(){
|
||||
ecount = 0;
|
||||
clearPlot = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the plot panels for the visualizations
|
||||
* @return List of configured JPanels
|
||||
*/
|
||||
public List<JPanel> getPlotPanels(){
|
||||
List<JPanel> panels = new ArrayList<JPanel>();
|
||||
for(SeriesDataFilter f: filters){
|
||||
JPanel panel=(JPanel) f.getPlot();
|
||||
if ((panel!=null) &&(!panels.contains(panel)))
|
||||
panels.add(panel);
|
||||
}
|
||||
|
||||
return panels;
|
||||
}
|
||||
|
||||
public List<Plot> getPlots(){
|
||||
List<Plot> plots = new ArrayList<Plot>();
|
||||
for(SeriesDataFilter f: filters){
|
||||
Plot plot=f.getPlot();
|
||||
if ((plot!=null) &&(!plots.contains(plot)))
|
||||
plots.add(plot);
|
||||
}
|
||||
return plots;
|
||||
}
|
||||
|
||||
public boolean isUpdateAtStreamElement() {
|
||||
return updateAtStreamElement;
|
||||
}
|
||||
public void setUpdateAtStreamElement(boolean updateAtStreamElement) {
|
||||
this.updateAtStreamElement = updateAtStreamElement;
|
||||
}
|
||||
public boolean isUpdateAtStreamDelimiter() {
|
||||
return updateAtStreamDelimiter;
|
||||
}
|
||||
public void setUpdateAtStreamDelimiter(boolean updateAtStreamDelimiter) {
|
||||
this.updateAtStreamDelimiter = updateAtStreamDelimiter;
|
||||
}
|
||||
public boolean isUpdateAtEndOfStream() {
|
||||
return updateAtEndOfStream;
|
||||
}
|
||||
public void setUpdateAtEndOfStream(boolean updateAtEndOfStream) {
|
||||
this.updateAtEndOfStream = updateAtEndOfStream;
|
||||
}
|
||||
|
||||
public int getSubsampling() {
|
||||
return subsampling;
|
||||
}
|
||||
public void setSubsampling(int factor) {
|
||||
this.subsampling = factor;
|
||||
subsamplingCounter=subsampling;//To plot first point
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
package ch.psi.fda.ui.visualizer;
|
||||
|
||||
import ch.psi.plot.LinePlotSeries;
|
||||
import ch.psi.plot.Plot;
|
||||
|
||||
/**
|
||||
@@ -72,7 +73,18 @@ public class XYSeriesArrayDataFilter implements SeriesDataFilter {
|
||||
this.seriesName = seriesName;
|
||||
}
|
||||
|
||||
/**
|
||||
private LinePlotSeries series = null;
|
||||
|
||||
@Override
|
||||
public LinePlotSeries getSeries(){
|
||||
return series;
|
||||
}
|
||||
|
||||
public void setSeries(LinePlotSeries series){
|
||||
this.series=series;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the count
|
||||
*/
|
||||
public int getCount() {
|
||||
@@ -19,8 +19,9 @@
|
||||
|
||||
package ch.psi.fda.ui.visualizer;
|
||||
|
||||
import ch.psi.plot.Plot;
|
||||
import ch.psi.plot.xy.XYSeriesP;
|
||||
import ch.psi.plot.LinePlot;
|
||||
import ch.psi.plot.LinePlotSeries;
|
||||
import ch.psi.plot.PlotSeries;
|
||||
|
||||
/**
|
||||
* Metadata of a group of XYSeries.
|
||||
@@ -37,16 +38,25 @@ public class XYSeriesDataFilter implements SeriesDataFilter{
|
||||
|
||||
// Number of series generated for this filter
|
||||
private int count = 0;
|
||||
|
||||
// Max number of points per series (additional appends make oldest value to be )
|
||||
private int maxNumberOfPoints=-1;
|
||||
|
||||
// Plot the data of this filter goes to
|
||||
private final Plot plot;
|
||||
|
||||
// TODO WORKAROUND - XYZ filter must not have this property !!!!
|
||||
private XYSeriesP actualSeries = null;
|
||||
private final LinePlot plot;
|
||||
|
||||
private boolean newseries = false;
|
||||
|
||||
private LinePlotSeries series = null;
|
||||
@Override
|
||||
public LinePlotSeries getSeries(){
|
||||
return series;
|
||||
}
|
||||
public void setSeries(LinePlotSeries series){
|
||||
this.series=series;
|
||||
}
|
||||
|
||||
|
||||
public XYSeriesDataFilter(String idX, String idY, Plot plot){
|
||||
public XYSeriesDataFilter(String idX, String idY, LinePlot plot){
|
||||
this.idX = idX;
|
||||
this.idY = idY;
|
||||
this.plot = plot;
|
||||
@@ -70,20 +80,19 @@ public class XYSeriesDataFilter implements SeriesDataFilter{
|
||||
public void setCount(int count) {
|
||||
this.count = count;
|
||||
}
|
||||
public Plot getPlot() {
|
||||
public LinePlot getPlot() {
|
||||
return plot;
|
||||
}
|
||||
public XYSeriesP getActualSeries() {
|
||||
return actualSeries;
|
||||
}
|
||||
public void setActualSeries(XYSeriesP actualSeries) {
|
||||
this.actualSeries = actualSeries;
|
||||
}
|
||||
public boolean isNewseries() {
|
||||
return newseries;
|
||||
}
|
||||
public void setNewseries(boolean newseries) {
|
||||
this.newseries = newseries;
|
||||
}
|
||||
|
||||
public int getMaxNumberOfPoints() {
|
||||
return maxNumberOfPoints;
|
||||
}
|
||||
public void setMaxNumberOfPoints(int count) {
|
||||
this.maxNumberOfPoints = count;
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
package ch.psi.fda.ui.visualizer;
|
||||
|
||||
import ch.psi.plot.MatrixPlotSeries;
|
||||
import ch.psi.plot.Plot;
|
||||
|
||||
public class XYZSeriesArrayDataFilter implements SeriesDataFilter {
|
||||
@@ -57,6 +58,16 @@ public class XYZSeriesArrayDataFilter implements SeriesDataFilter {
|
||||
public void setSeriesName(String seriesName) {
|
||||
this.seriesName = seriesName;
|
||||
}
|
||||
private MatrixPlotSeries series = null;
|
||||
|
||||
@Override
|
||||
public MatrixPlotSeries getSeries(){
|
||||
return series;
|
||||
}
|
||||
|
||||
public void setSeries(MatrixPlotSeries series){
|
||||
this.series=series;
|
||||
}
|
||||
public int getCount() {
|
||||
return count;
|
||||
}
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
package ch.psi.fda.ui.visualizer;
|
||||
|
||||
import ch.psi.plot.MatrixPlotSeries;
|
||||
import ch.psi.plot.Plot;
|
||||
|
||||
public class XYZSeriesDataFilter implements SeriesDataFilter {
|
||||
@@ -55,6 +56,16 @@ public class XYZSeriesDataFilter implements SeriesDataFilter {
|
||||
public void setSeriesName(String seriesName) {
|
||||
this.seriesName = seriesName;
|
||||
}
|
||||
|
||||
private MatrixPlotSeries series = null;
|
||||
|
||||
@Override
|
||||
public MatrixPlotSeries getSeries(){
|
||||
return series;
|
||||
}
|
||||
public void setSeries(MatrixPlotSeries series){
|
||||
this.series=series;
|
||||
}
|
||||
public int getCount() {
|
||||
return count;
|
||||
}
|
||||