fixed lots of stuff regarding new message format ...

This commit is contained in:
2013-10-17 07:35:28 +02:00
parent 36cd4335ab
commit e2921ff1f4
25 changed files with 533 additions and 956 deletions
@@ -54,7 +54,6 @@ import com.google.common.eventbus.EventBus;
import sun.misc.Signal;
import sun.misc.SignalHandler;
import ch.psi.fda.aq.Acquisition;
import ch.psi.fda.core.messages.DataMessageMetadata;
import ch.psi.fda.gui.ProgressPanel;
import ch.psi.fda.gui.ScrollableFlowPanel;
import ch.psi.fda.install.ApplicationConfigurator;
@@ -262,13 +261,13 @@ public class AcquisitionMain {
EventBus b = new AsyncEventBus(Executors.newSingleThreadExecutor());
DataMessageMetadata dmeta = acquisition.initalize(b, c);
acquisition.initalize(b, c);
Visualizer visualizer = null;
// Only register data visualization task/processor if there are visualizations
if(vis){
visualizer = new Visualizer(dmeta, c.getVisualization());
visualizer = new Visualizer(c.getVisualization());
b.register(visualizer);
// If there is a continous dimension only update plot at the end of a line
if(c.getScan() != null && c.getScan().getCdimension()!=null){
@@ -102,25 +102,25 @@ public class ConversionMain {
DataSerializer serializer;
if(writer.equals(Writer.MAT)){
serializer = new DataSerializerMAT(deserializer.getMetadata(), output);
serializer = new DataSerializerMAT(output);
}
else if(writer.equals(Writer.MAT_2D)){
serializer = new DataSerializerMAT2D(deserializer.getMetadata(), output);
serializer = new DataSerializerMAT2D(output);
}
else if(writer.equals(Writer.TXT)){
serializer = new DataSerializerTXT(deserializer.getMetadata(), output, false);
serializer = new DataSerializerTXT(output, false);
}
else if(writer.equals(Writer.TXT_2D)){
serializer = new DataSerializerTXT2D(deserializer.getMetadata(), output);
serializer = new DataSerializerTXT2D(output);
}
else if(writer.equals(Writer.TXT_SPLIT)){
serializer = new DataSerializerTXTSplit(deserializer.getMetadata(), output);
serializer = new DataSerializerTXTSplit(output);
}
else if(writer.equals(Writer.MDA)){
serializer = new DataSerializerMDA(deserializer.getMetadata(), output);
serializer = new DataSerializerMDA(output);
}
else if(writer.equals(Writer.MAT_2D_Z)){
serializer = new DataSerializerMAT2DZigZag(deserializer.getMetadata(), output);
serializer = new DataSerializerMAT2DZigZag(output);
}
else{
throw new IllegalArgumentException("Writer of type "+writer+" not supported.");
@@ -121,7 +121,7 @@ public class VisualizationMain {
DataDeserializer deserializer = new DataDeserializerTXT(bus, data);
// Create Visualizer
Visualizer visualizer = new Visualizer(deserializer.getMetadata(), configuration.getVisualization());
Visualizer visualizer = new Visualizer(configuration.getVisualization());
// visualizer.setTerminateAtEOS(true);
// Adapt default visualizer behavior to optimize performance for visualization
@@ -65,7 +65,6 @@ import ch.psi.fda.core.loops.otf.OTFNamedChannelSensor;
import ch.psi.fda.core.loops.otf.OTFScalerChannelSensor;
import ch.psi.fda.core.loops.otf.TemplateOTF;
import ch.psi.fda.core.manipulator.JythonManipulation;
import ch.psi.fda.core.messages.DataMessageMetadata;
import ch.psi.fda.core.scripting.JythonGlobalVariable;
import ch.psi.fda.core.scripting.JythonParameterMapping;
import ch.psi.fda.core.scripting.JythonParameterMappingChannel;
@@ -180,7 +179,7 @@ public class Acquisition {
* @param getQueue Flag whether to return a queue or not. If false the return value of the function will be null.
* @throws InterruptedException
*/
public DataMessageMetadata initalize(EventBus bus, Configuration smodel) {
public void initalize(EventBus bus, Configuration smodel) {
// Create notification agent with globally configured recipients
notificationAgent = new NotificationAgent(configuration.getSmptServer(), "fda.notification@psi.ch");
@@ -236,7 +235,6 @@ public class Acquisition {
logger.fine("Map Model to internal logic");
DataMessageMetadata metadata;
if(smodel.getScan().getManipulation()!= null && smodel.getScan().getManipulation().size()>0){
// Setup optimized with manipulations
@@ -251,12 +249,11 @@ public class Acquisition {
// Add manipulator into processing chain
this.manipulator = new Manipulator(bus, collector.getMetadata(), this.manipulations);
this.manipulator = new Manipulator(bus, this.manipulations);
b.register(this.manipulator);
metadata = manipulator.getMetadata();
this.serializer = new DataSerializerTXT(metadata, datafile, true);
this.serializer = new DataSerializerTXT(datafile, true);
bus.register(serializer);
}
else{
@@ -265,13 +262,9 @@ public class Acquisition {
mapScan(collector, smodel);
col = collector;
metadata = collector.getMetadata();
this.serializer = new DataSerializerTXT(metadata, datafile, true);
this.serializer = new DataSerializerTXT(datafile, true);
bus.register(serializer);
}
return (metadata);
}
/**
@@ -19,16 +19,16 @@
package ch.psi.fda.aq;
import java.util.ArrayList;
import java.util.List;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
import ch.psi.fda.core.Manipulation;
import ch.psi.fda.core.messages.ComponentMetadata;
import ch.psi.fda.core.messages.DataMessage;
import ch.psi.fda.core.messages.DataMessageMetadata;
import ch.psi.fda.core.messages.Message;
import ch.psi.fda.core.messages.Metadata;
/**
* Applies manipulations to the data stream
@@ -36,29 +36,33 @@ import ch.psi.fda.core.messages.Message;
public class Manipulator {
private EventBus bus;
private DataMessageMetadata metadata;
private final List<Manipulation> manipulations;
private boolean first = true;
private List<Metadata> metadata = new ArrayList<>();
public Manipulator(EventBus b, DataMessageMetadata meta, List<Manipulation> manipulations){
public Manipulator(EventBus b, List<Manipulation> manipulations){
this.bus = b;
this.manipulations = manipulations;
// Create outgoing data metadata
this.metadata = meta.clone();
// Initialize manipulations and create outgoing metadata
for(Manipulation manipulation: this.manipulations){
manipulation.initialize(this.metadata);
// Add manipulation id to metadata
this.metadata.getComponents().add(new ComponentMetadata(manipulation.getId(),0)); // Calculated component always belongs to lowes dimension
}
}
@Subscribe
public void onMessage(Message message){
if(message instanceof DataMessage){
if(first){
first=false;
metadata.addAll(((DataMessage) message).getMetadata());
for(Manipulation manipulation: this.manipulations){
manipulation.initialize(this.metadata);
// Add manipulation id to metadata
this.metadata.add(new Metadata(manipulation.getId(),0)); // Calculated component always belongs to lowes dimension
}
}
DataMessage dm = (DataMessage) message;
for(Manipulation manipulation: manipulations){
@@ -67,9 +71,4 @@ public class Manipulator {
}
bus.post(message);
}
public DataMessageMetadata getMetadata() {
return metadata;
}
}
@@ -19,8 +19,10 @@
package ch.psi.fda.core;
import java.util.List;
import ch.psi.fda.core.messages.DataMessage;
import ch.psi.fda.core.messages.DataMessageMetadata;
import ch.psi.fda.core.messages.Metadata;
public interface Manipulation {
@@ -34,7 +36,7 @@ public interface Manipulation {
* Initialize the manipulation
* @param metadata Metadata of the incomming data message
*/
public void initialize(DataMessageMetadata metadata);
public void initialize(List<Metadata> metadata);
/**
* Execute the manipulation on the passed data message
@@ -19,6 +19,7 @@
package ch.psi.fda.core.manipulator;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -33,7 +34,7 @@ import javax.script.ScriptException;
import ch.psi.fda.core.Manipulation;
import ch.psi.fda.core.messages.DataMessage;
import ch.psi.fda.core.messages.DataMessageMetadata;
import ch.psi.fda.core.messages.Metadata;
import ch.psi.fda.core.scripting.JythonParameterMapping;
import ch.psi.fda.core.scripting.JythonParameterMappingChannel;
import ch.psi.fda.core.scripting.JythonParameterMappingGlobalVariable;
@@ -84,7 +85,8 @@ public class JythonManipulation implements Manipulation{
* Component index of the script parameter. The sequence of the indexes in this array correspond to the script
* parameter position, i.e. the first index corresponds to the first parameter.
*/
private Integer[] parameterIndex;
// private Integer[] parameterIndex;
private List<String> parameterIds = new ArrayList<>();
/**
* Parameter array of the entry function
*/
@@ -138,7 +140,7 @@ public class JythonManipulation implements Manipulation{
@Override
public void initialize(DataMessageMetadata metadata){
public void initialize(List<Metadata> metadata){
// Workaround for Jython memory leak
// http://blog.hillbrecht.de/2009/07/11/jython-memory-leakout-of-memory-problem/
@@ -172,7 +174,8 @@ public class JythonManipulation implements Manipulation{
// Determine component index of the needed parameters
// If the component index of the parameter cannot be determined an IllegalArgumentException is thrown
parameterIndex = new Integer[parameter.length];
// parameterIndex = new Integer[parameter.length];
parameterIds = new ArrayList<>();
for(int i=0;i<parameter.length; i++){
String p = parameter[i];
p = p.trim();
@@ -183,16 +186,19 @@ public class JythonManipulation implements Manipulation{
if(jpm instanceof JythonParameterMappingID){
JythonParameterMappingID pm = (JythonParameterMappingID)jpm;
// Mapping for parameter found, determine index of the corresponding component
parameterIndex[i] = metadata.getIndex(pm.getRefid());
// parameterIndex[i] = metadata.getIndex(pm.getRefid());
parameterIds.add(pm.getRefid());
}
else if (jpm instanceof JythonParameterMappingChannel){
JythonParameterMappingChannel<?> pm = (JythonParameterMappingChannel<?>) jpm;
parameterIndex[i] = null;
// parameterIndex[i] = null;
parameterIds.add(null);
engine.put(pm.getVariable(), pm.getChannel());
}
else if (jpm instanceof JythonParameterMappingGlobalVariable){
JythonParameterMappingGlobalVariable pm = (JythonParameterMappingGlobalVariable)jpm;
parameterIndex[i] = null;
parameterIds.add(null);
// parameterIndex[i] = null;
engine.put(pm.getVariable(), pm.getGlobalVariable());
}
@@ -233,9 +239,9 @@ public class JythonManipulation implements Manipulation{
}
// Manipulate data
for(int i=0;i<parameterIndex.length;i++){
if(parameterIndex[i] != null){
engine.put(parameter[i], message.getData().get(parameterIndex[i]));
for(int i=0;i<parameterIds.size();i++){
if(parameterIds.get(i) != null){
engine.put(parameter[i], message.getData(parameterIds.get(i)));
}
}
@@ -49,7 +49,6 @@ public class DataMessage extends Message{
return metadata;
}
// Utility functions
@SuppressWarnings("unchecked")
@@ -64,6 +63,15 @@ public class DataMessage extends Message{
throw new IllegalArgumentException("No data found for id: "+id);
}
public Metadata getMetadata(String id){
for(Metadata m: metadata){
if(m.getId().equals(id)){
return m;
}
}
throw new IllegalArgumentException("No data found for id: "+id);
}
@Override
public String toString() {
StringBuffer b = new StringBuffer();
@@ -26,7 +26,7 @@ import java.util.List;
/**
* Structure to hold the metadata of a component of a message.
*/
public class DataMessageMetadata implements Serializable {
private class DataMessageMetadata implements Serializable {
private static final long serialVersionUID = 1L;
/**
@@ -19,18 +19,6 @@
package ch.psi.fda.deserializer;
import ch.psi.fda.core.messages.DataMessageMetadata;
/**
* Data deserializer
*/
public interface DataDeserializer {
/**
* Get message metadata
* @return metadata/information of the message format
*/
public DataMessageMetadata getMetadata();
public void read();
}
@@ -13,11 +13,10 @@ import java.util.logging.Logger;
import com.google.common.eventbus.EventBus;
import ch.psi.fda.core.messages.ComponentMetadata;
import ch.psi.fda.core.messages.DataMessage;
import ch.psi.fda.core.messages.DataMessageMetadata;
import ch.psi.fda.core.messages.EndOfStreamMessage;
import ch.psi.fda.core.messages.Message;
import ch.psi.fda.core.messages.Metadata;
import ch.psi.fda.core.messages.StreamDelimiterMessage;
/**
@@ -29,7 +28,6 @@ public class DataDeserializerMDA implements DataDeserializer {
private static Logger logger = Logger.getLogger(DataDeserializerMDA.class.getName());
private EventBus bus;
private DataMessageMetadata metadata;
private RecursiveReturnContainer c;
public DataDeserializerMDA(EventBus b, File file){
@@ -42,8 +40,6 @@ public class DataDeserializerMDA implements DataDeserializer {
} catch (IOException e) {
throw new RuntimeException(e);
}
this.metadata = c.getMetadata();
}
private RecursiveReturnContainer read(InputStream in) throws IOException {
@@ -217,7 +213,7 @@ public class DataDeserializerMDA implements DataDeserializer {
logger.fine("MDA - number of triggers:: "+ numberOfTriggers);
List<ComponentMetadata> componentMetadataList = new ArrayList<ComponentMetadata>();
List<Metadata> componentMetadataList = new ArrayList<>();
/**
* Read positioners metadata
*/
@@ -233,7 +229,7 @@ public class DataDeserializerMDA implements DataDeserializer {
String positionerName = x.readString();
logger.fine("MDA - positioner name:: "+positionerName);
// MDA starts at dimension number 1 we start at 0
componentMetadataList.add(new ComponentMetadata(positionerName,scanRank-1));
componentMetadataList.add(new Metadata(positionerName,scanRank-1));
}
length = x.readInt();
@@ -287,7 +283,7 @@ public class DataDeserializerMDA implements DataDeserializer {
String detectorName = x.readString();
logger.fine("MDA - detector name:: "+detectorName);
// MDA starts at dimension number 1 we start at 0
componentMetadataList.add(new ComponentMetadata(detectorName, scanRank-1));
componentMetadataList.add(new Metadata(detectorName, scanRank-1));
}
length = x.readInt();
@@ -371,7 +367,7 @@ public class DataDeserializerMDA implements DataDeserializer {
RecursiveReturnContainer cont = new RecursiveReturnContainer();
// Update component metadata
cont.getMetadata().getComponents().addAll(componentMetadataList);
cont.getMetadata().addAll(componentMetadataList);
if(scanRank > 1){
/**
@@ -388,7 +384,7 @@ public class DataDeserializerMDA implements DataDeserializer {
if(i==0){
// For the first scan of each dimension component data is read and stored
cont.getMetadata().getComponents().addAll(container.getMetadata().getComponents());
cont.getMetadata().addAll(container.getMetadata());
}
logger.fine("Convert data structure [rank="+scanRank+"] ...");
@@ -446,16 +442,15 @@ public class DataDeserializerMDA implements DataDeserializer {
public void read() {
// Add data to queue
for(Message m: c.getMessage()){
if(m instanceof DataMessage){
DataMessage dm = (DataMessage)m;
dm.getMetadata().addAll(c.getMetadata()); // WORKAROUND !!!! ideally the reference to metadata is set while creating the
// data message. Then there would be only one list with one reference. In this case we now have multiple lists!
}
bus.post(m);
}
bus.post(new EndOfStreamMessage());
}
@Override
public DataMessageMetadata getMetadata() {
return metadata;
}
}
/**
@@ -465,12 +460,12 @@ public class DataDeserializerMDA implements DataDeserializer {
*/
class RecursiveReturnContainer{
private List<Message> message = new ArrayList<Message>();
private DataMessageMetadata metadata = new DataMessageMetadata();
private List<Metadata> metadata = new ArrayList<>();
public List<Message> getMessage() {
return message;
}
public DataMessageMetadata getMetadata() {
public List<Metadata> getMetadata() {
return metadata;
}
}
@@ -29,9 +29,8 @@ import java.util.logging.Logger;
import com.google.common.eventbus.EventBus;
import ch.psi.fda.core.messages.ComponentMetadata;
import ch.psi.fda.core.messages.DataMessage;
import ch.psi.fda.core.messages.DataMessageMetadata;
import ch.psi.fda.core.messages.Metadata;
import ch.psi.fda.core.messages.StreamDelimiterMessage;
import ch.psi.fda.core.messages.EndOfStreamMessage;
@@ -43,7 +42,7 @@ public class DataDeserializerTXT implements DataDeserializer {
private static Logger logger = Logger.getLogger(DataDeserializerTXT.class.getName());
private EventBus bus;
private DataMessageMetadata metadata;
private List<Metadata> metadata;
private File file;
private List<Integer> dindex;
@@ -59,6 +58,8 @@ public class DataDeserializerTXT implements DataDeserializer {
this.dindex = new ArrayList<Integer>();
this.iindex = new ArrayList<Integer>();
this.metadata = new ArrayList<>();
try{
// Read metadata
// Open file
@@ -78,11 +79,10 @@ public class DataDeserializerTXT implements DataDeserializer {
String[] dimensions = line.split("\t");
// Create data message metadata
metadata = new DataMessageMetadata();
Integer d = -1;
for(int i=0;i<ids.length;i++){
Integer dimension = Integer.parseInt(dimensions[i]);
metadata.getComponents().add(new ComponentMetadata(ids[i], dimension));
metadata.add(new Metadata(ids[i], dimension));
// Store the first index of the first component
// in each dimension ...
@@ -102,11 +102,6 @@ public class DataDeserializerTXT implements DataDeserializer {
}
}
@Override
public DataMessageMetadata getMetadata(){
return(metadata);
}
@Override
public void read() {
try{
@@ -135,7 +130,7 @@ public class DataDeserializerTXT implements DataDeserializer {
// Create and populate new data message
String[] data = line.split("\t");
DataMessage message = new DataMessage();
DataMessage message = new DataMessage(metadata);
for (String d : data) {
// Remove spaces at the end and beginning of the value
d = d.trim();
@@ -29,18 +29,16 @@ import com.jmatio.io.MatFileWriter;
import com.jmatio.types.MLArray;
import com.jmatio.types.MLDouble;
import ch.psi.fda.core.messages.ComponentMetadata;
import ch.psi.fda.core.messages.DataMessage;
import ch.psi.fda.core.messages.DataMessageMetadata;
import ch.psi.fda.core.messages.EndOfStreamMessage;
import ch.psi.fda.core.messages.Message;
import ch.psi.fda.core.messages.Metadata;
/**
* Serialize data received by a DataQueue into a Matlab file
*/
public class DataSerializerMAT implements DataSerializer{
private DataMessageMetadata metadata;
private File file;
private boolean appendSuffix = false;
@@ -51,62 +49,61 @@ public class DataSerializerMAT implements DataSerializer{
* @param queue Data queue holding the data to serialize
* @param file Name of the Matlab file to serialize the data to
*/
public DataSerializerMAT(DataMessageMetadata metadata, File file){
this.metadata = metadata;
public DataSerializerMAT(File file){
this.file = file;
}
File outfile;
List<List<Object>> dlist;
List<Class<?>> clist;
boolean firstF;
private List<Metadata> metadata;
@Subscribe
public void onMessage(Message message) {
try {
if (first) {
first = false;
// WORKAROUND BEGIN
if (appendSuffix) {
// Append a count suffix to the file. If there is already a
// file with
// this suffix increase the counter for the suffix
int cnt = 0;
String fname = this.file.getAbsolutePath(); // Determine
// file name
String extension = fname.replaceAll("^.*\\.", ""); // Determine
// extension
fname = fname.replaceAll("\\." + extension + "$", "");
outfile = new File(String.format("%s_%04d.%s", fname, cnt, extension));
while (outfile.exists()) {
cnt++;
outfile = new File(String.format("%s_%04d.%s", fname, cnt, extension));
}
} else {
outfile = this.file;
}
// WORKAROUND END
// Transposed data list
dlist = new ArrayList<List<Object>>();
clist = new ArrayList<Class<?>>();
firstF = true;
}
if (message instanceof DataMessage) {
DataMessage m = (DataMessage) message;
// Initialize list
if (firstF) {
if (first) {
first = false;
this.metadata = m.getMetadata();
// WORKAROUND BEGIN
if (appendSuffix) {
// Append a count suffix to the file. If there is already a
// file with
// this suffix increase the counter for the suffix
int cnt = 0;
String fname = this.file.getAbsolutePath(); // Determine
// file name
String extension = fname.replaceAll("^.*\\.", ""); // Determine
// extension
fname = fname.replaceAll("\\." + extension + "$", "");
outfile = new File(String.format("%s_%04d.%s", fname, cnt, extension));
while (outfile.exists()) {
cnt++;
outfile = new File(String.format("%s_%04d.%s", fname, cnt, extension));
}
} else {
outfile = this.file;
}
// WORKAROUND END
// Transposed data list
dlist = new ArrayList<List<Object>>();
clist = new ArrayList<Class<?>>();
for (Object o : m.getData()) {
dlist.add(new ArrayList<Object>());
clist.add(o.getClass());
}
firstF = false;
}
// Put data into data list
@@ -120,7 +117,7 @@ public class DataSerializerMAT implements DataSerializer{
ArrayList<MLArray> matlablist = new ArrayList<MLArray>();
for (int t = 0; t < dlist.size(); t++) {
// Get component metadata
ComponentMetadata c = metadata.getComponents().get(t);
Metadata c = metadata.get(t);
c.getId();
List<Object> list = dlist.get(t);
@@ -30,9 +30,8 @@ import com.jmatio.io.MatFileWriter;
import com.jmatio.types.MLArray;
import com.jmatio.types.MLDouble;
import ch.psi.fda.core.messages.ComponentMetadata;
import ch.psi.fda.core.messages.DataMessage;
import ch.psi.fda.core.messages.DataMessageMetadata;
import ch.psi.fda.core.messages.Metadata;
import ch.psi.fda.core.messages.StreamDelimiterMessage;
import ch.psi.fda.core.messages.EndOfStreamMessage;
import ch.psi.fda.core.messages.Message;
@@ -44,7 +43,6 @@ public class DataSerializerMAT2D implements DataSerializer{
private static final Logger logger = Logger.getLogger(DataSerializerMAT2D.class.getName());
private DataMessageMetadata metadata;
private File file;
private boolean appendSuffix = false;
@@ -55,75 +53,78 @@ public class DataSerializerMAT2D implements DataSerializer{
private int dsize;
private int dcount;
private Integer mindsize;
private boolean firstF;
private File outfile;
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 DataSerializerMAT2D(DataMessageMetadata metadata, File file){
this.metadata = metadata;
public DataSerializerMAT2D(File file){
this.file = file;
// Check if input queue does only hold 2D data
int maxdim=0;
for(ComponentMetadata m: metadata.getComponents()){
if(m.getDimension()>maxdim){
maxdim=m.getDimension();
}
if(m.getDimension()>1){
throw new RuntimeException("Serializer does only support 2D data (XD data found)");
}
}
if(maxdim<1){
throw new RuntimeException("Serializer does only support 2D data ("+maxdim+"D data found)");
}
}
@Subscribe
public void onMessage(Message message) {
try{
if(first){
first=false;
// WORKAROUND BEGIN
if(appendSuffix){
// Append a count suffix to the file. If there is already a file with
// this suffix increase the counter for the suffix
int cnt = 0;
String fname = this.file.getAbsolutePath(); // Determine file name
String extension = fname.replaceAll("^.*\\.", ""); // Determine extension
fname = fname.replaceAll("\\."+extension+"$", "");
outfile = new File(String.format("%s_%04d.%s", fname, cnt, extension));
while(outfile.exists()){
cnt++;
outfile = new File(String.format("%s_%04d.%s", fname, cnt, extension));
}
}
else{
outfile = this.file;
}
// WORKAROUND END
// Transposed data list
dlist = new ArrayList<List<List<Object>>>();
clist = new ArrayList<Class<?>>();
dsize = 0; // Size of the dimension
dcount = 0;
mindsize = null;
firstF = true;
}
if(message instanceof DataMessage){
DataMessage m = (DataMessage) message;
// Initialize list
if(firstF){
if(first){
first=false;
this.metadata = m.getMetadata();
// Check if input queue does only hold 2D data
int maxdim=0;
for(Metadata me: metadata){
if(me.getDimension()>maxdim){
maxdim=me.getDimension();
}
if(me.getDimension()>1){
throw new RuntimeException("Serializer does only support 2D data (XD data found)");
}
}
if(maxdim<1){
throw new RuntimeException("Serializer does only support 2D data ("+maxdim+"D data found)");
}
// WORKAROUND BEGIN
if(appendSuffix){
// Append a count suffix to the file. If there is already a file with
// this suffix increase the counter for the suffix
int cnt = 0;
String fname = this.file.getAbsolutePath(); // Determine file name
String extension = fname.replaceAll("^.*\\.", ""); // Determine extension
fname = fname.replaceAll("\\."+extension+"$", "");
outfile = new File(String.format("%s_%04d.%s", fname, cnt, extension));
while(outfile.exists()){
cnt++;
outfile = new File(String.format("%s_%04d.%s", fname, cnt, extension));
}
}
else{
outfile = this.file;
}
// WORKAROUND END
// Transposed data list
dlist = new ArrayList<List<List<Object>>>();
clist = new ArrayList<Class<?>>();
dsize = 0; // Size of the dimension
dcount = 0;
mindsize = null;
for(Object o: m.getData()){
// TODO Create list of lists (for each line one list - to
// be able to fill up empty data points if there are some)
@@ -133,7 +134,6 @@ public class DataSerializerMAT2D implements DataSerializer{
clist.add(o.getClass());
}
firstF=false;
}
// Put data into data list
@@ -179,7 +179,7 @@ public class DataSerializerMAT2D implements DataSerializer{
for(int t=0; t<dlist.size(); t++ ){
// Get component metadata
ComponentMetadata c = metadata.getComponents().get(t);
Metadata c = metadata.get(t);
// Combine all lists to one big list (pad if there are data points missing)
List<Object> list = new ArrayList<Object>();
@@ -31,9 +31,8 @@ import com.jmatio.io.MatFileWriter;
import com.jmatio.types.MLArray;
import com.jmatio.types.MLDouble;
import ch.psi.fda.core.messages.ComponentMetadata;
import ch.psi.fda.core.messages.DataMessage;
import ch.psi.fda.core.messages.DataMessageMetadata;
import ch.psi.fda.core.messages.Metadata;
import ch.psi.fda.core.messages.StreamDelimiterMessage;
import ch.psi.fda.core.messages.EndOfStreamMessage;
import ch.psi.fda.core.messages.Message;
@@ -45,7 +44,7 @@ public class DataSerializerMAT2DZigZag implements DataSerializer{
private static final Logger logger = Logger.getLogger(DataSerializerMAT2DZigZag.class.getName());
private DataMessageMetadata metadata;
private List<Metadata> metadata;
private File file;
private boolean appendSuffix = false;
private boolean first = true;
@@ -67,73 +66,79 @@ public class DataSerializerMAT2DZigZag implements DataSerializer{
* @param queue Data queue holding the data to serialize
* @param file Name of the Matlab file to serialize the data to
*/
public DataSerializerMAT2DZigZag(DataMessageMetadata metadata, File file){
this.metadata = metadata;
public DataSerializerMAT2DZigZag(File file){
this.file = file;
// Check if input queue does only hold 2D data
int maxdim=0;
for(ComponentMetadata m: metadata.getComponents()){
if(m.getDimension()>maxdim){
maxdim=m.getDimension();
}
if(m.getDimension()>1){
throw new RuntimeException("Serializer does only support 2D data (XD data found)");
}
}
if(maxdim<1){
throw new RuntimeException("Serializer does only support 2D data ("+maxdim+"D data found)");
}
}
@Subscribe
public void onMessage(Message message) {
try{
if(first){
first=false;
// WORKAROUND BEGIN
if(appendSuffix){
// Append a count suffix to the file. If there is already a file with
// this suffix increase the counter for the suffix
int cnt = 0;
String fname = this.file.getAbsolutePath(); // Determine file name
String extension = fname.replaceAll("^.*\\.", ""); // Determine extension
fname = fname.replaceAll("\\."+extension+"$", "");
outfile = new File(String.format("%s_%04d.%s", fname, cnt, extension));
while(outfile.exists()){
cnt++;
outfile = new File(String.format("%s_%04d.%s", fname, cnt, extension));
}
}
else{
outfile = this.file;
}
// WORKAROUND END
// Transposed data list
dlist = new ArrayList<List<Object>>();
dlistTmp = new ArrayList<List<Object>>();
clist = new ArrayList<Class<?>>();
dsize = 0; // Size of the dimension
dcount = 0;
delimiterCount = 0;
firstF = true;
firstC = true;
}
if(message instanceof DataMessage){
DataMessage m = (DataMessage) message;
if(first){
first=false;
this.metadata = m.getMetadata();
// Check if input queue does only hold 2D data
int maxdim=0;
for(Metadata me: metadata){
if(me.getDimension()>maxdim){
maxdim=me.getDimension();
}
if(me.getDimension()>1){
throw new RuntimeException("Serializer does only support 2D data (XD data found)");
}
}
if(maxdim<1){
throw new RuntimeException("Serializer does only support 2D data ("+maxdim+"D data found)");
}
// WORKAROUND BEGIN
if(appendSuffix){
// Append a count suffix to the file. If there is already a file with
// this suffix increase the counter for the suffix
int cnt = 0;
String fname = this.file.getAbsolutePath(); // Determine file name
String extension = fname.replaceAll("^.*\\.", ""); // Determine extension
fname = fname.replaceAll("\\."+extension+"$", "");
outfile = new File(String.format("%s_%04d.%s", fname, cnt, extension));
while(outfile.exists()){
cnt++;
outfile = new File(String.format("%s_%04d.%s", fname, cnt, extension));
}
}
else{
outfile = this.file;
}
// WORKAROUND END
// Transposed data list
dlist = new ArrayList<List<Object>>();
dlistTmp = new ArrayList<List<Object>>();
clist = new ArrayList<Class<?>>();
dsize = 0; // Size of the dimension
dcount = 0;
delimiterCount = 0;
firstF = true;
firstC = true;
}
if(firstC){
for(Object o: m.getData()){
dlist.add(new ArrayList<Object>());
@@ -187,7 +192,7 @@ public class DataSerializerMAT2DZigZag implements DataSerializer{
logger.info("dlist size: "+dlist.size());
for(int t=0; t<dlist.size(); t++ ){
// Get component metadata
ComponentMetadata c = metadata.getComponents().get(t);
Metadata c = metadata.get(t);
List<Object> list = dlist.get(t);
@@ -32,11 +32,10 @@ import java.util.logging.Logger;
import com.google.common.eventbus.Subscribe;
import ch.psi.fda.core.messages.ComponentMetadata;
import ch.psi.fda.core.messages.DataMessage;
import ch.psi.fda.core.messages.DataMessageMetadata;
import ch.psi.fda.core.messages.EndOfStreamMessage;
import ch.psi.fda.core.messages.Message;
import ch.psi.fda.core.messages.Metadata;
import ch.psi.fda.core.messages.StreamDelimiterMessage;
/**
@@ -48,7 +47,6 @@ public class DataSerializerMDA implements DataSerializer{
private static final Logger logger = Logger.getLogger(DataSerializerMDA.class.getName());
private DataMessageMetadata metadata;
private File file;
private boolean first = true;
@@ -61,61 +59,65 @@ public class DataSerializerMDA implements DataSerializer{
private HashMap<Integer,List<String>> idMap;
private int numberOfDimensions;
public DataSerializerMDA(DataMessageMetadata metadata, File file){
this.metadata = metadata;
public DataSerializerMDA(File file){
this.file = file;
}
@Subscribe
public void onMessage(Message message) {
if(first){
first = false;
// Analyze header
// Map holding all indexes for a given dimension
dMap = new HashMap<Integer, List<Integer>>();
// Map holding all ids for a given dimension
idMap = new HashMap<Integer, List<String>>();
List<ComponentMetadata> mlist = metadata.getComponents();
for(int index=0;index<mlist.size();index++){
ComponentMetadata m = mlist.get(index);
if(!dMap.containsKey(m.getDimension())){
dMap.put(m.getDimension(), new ArrayList<Integer>());
}
if(!idMap.containsKey(m.getDimension())){
idMap.put(m.getDimension(), new ArrayList<String>());
}
dMap.get(m.getDimension()).add(index);
idMap.get(m.getDimension()).add(m.getId());
}
//dimensions/dimension/dimensioncomponents/component/componentvalue
dimensionList = new ArrayList<List<List<List<Double>>>>();
numberOfDimensions = dMap.size();
logger.info("Number of dimensions: "+numberOfDimensions);
for(int i=0;i<numberOfDimensions; i++){
// For each dimension add an list
dimensionList.add(new ArrayList<List<List<Double>>>());
}
firstL = new ArrayList<Boolean>();
takeData = new ArrayList<Boolean>(); // Flag whether to take data for this dimension
dcountL = new ArrayList<Integer>(); // How many times this dimension is there
for(int i=0;i<numberOfDimensions;i++){
firstL.add(true);
takeData.add(true);
dcountL.add(0);
}
}
// Write data
// Read Message
if(message instanceof DataMessage){
DataMessage m = (DataMessage) message;
if(first){
first = false;
// Analyze header
// Map holding all indexes for a given dimension
dMap = new HashMap<Integer, List<Integer>>();
// Map holding all ids for a given dimension
idMap = new HashMap<Integer, List<String>>();
int index=0;
for(Metadata me: m.getMetadata()){
if(!dMap.containsKey(me.getDimension())){
dMap.put(me.getDimension(), new ArrayList<Integer>());
}
if(!idMap.containsKey(me.getDimension())){
idMap.put(me.getDimension(), new ArrayList<String>());
}
dMap.get(me.getDimension()).add(index);
idMap.get(me.getDimension()).add(me.getId());
index++;
}
//dimensions/dimension/dimensioncomponents/component/componentvalue
dimensionList = new ArrayList<List<List<List<Double>>>>();
numberOfDimensions = dMap.size();
logger.info("Number of dimensions: "+numberOfDimensions);
for(int i=0;i<numberOfDimensions; i++){
// For each dimension add an list
dimensionList.add(new ArrayList<List<List<Double>>>());
}
firstL = new ArrayList<Boolean>();
takeData = new ArrayList<Boolean>(); // Flag whether to take data for this dimension
dcountL = new ArrayList<Integer>(); // How many times this dimension is there
for(int i=0;i<numberOfDimensions;i++){
firstL.add(true);
takeData.add(true);
dcountL.add(0);
}
}
for(Integer dimensionNumberKey : dMap.keySet()){
if(firstL.get(dimensionNumberKey)){
List<List<Double>> l = new ArrayList<List<Double>>();
@@ -27,11 +27,10 @@ import java.util.logging.Logger;
import com.google.common.eventbus.Subscribe;
import ch.psi.fda.core.messages.ComponentMetadata;
import ch.psi.fda.core.messages.DataMessage;
import ch.psi.fda.core.messages.DataMessageMetadata;
import ch.psi.fda.core.messages.EndOfStreamMessage;
import ch.psi.fda.core.messages.Message;
import ch.psi.fda.core.messages.Metadata;
import ch.psi.fda.core.messages.StreamDelimiterMessage;
/**
@@ -49,8 +48,6 @@ public class DataSerializerTXT implements DataSerializer{
private boolean first = true;
private File outfile;
private DataMessageMetadata meta;
private int icount;
private String basename;
private String extension;
@@ -66,8 +63,7 @@ public class DataSerializerTXT implements DataSerializer{
* @param file
* @param appendSuffix Flag whether to append a _0000 suffix after the original file name
*/
public DataSerializerTXT(DataMessageMetadata meta, File file, boolean appendSuffix){
this.meta = meta;
public DataSerializerTXT(File file, boolean appendSuffix){
this.file = file;
this.appendSuffix = appendSuffix;
}
@@ -78,20 +74,7 @@ public class DataSerializerTXT implements DataSerializer{
if(first){
first=false;
// Write header
b = new StringBuffer();
b1 = new StringBuffer();
b.append("#");
b1.append("#");
for(ComponentMetadata c: meta.getComponents()){
b.append(c.getId());
b.append("\t");
b1.append(c.getDimension());
b1.append("\t");
}
b.setCharAt(b.length()-1, '\n');
b1.setCharAt(b1.length()-1, '\n');
icount = 0;
@@ -108,6 +91,22 @@ public class DataSerializerTXT implements DataSerializer{
if(message instanceof DataMessage){
dataInBetween = true;
if(newfile){
b = new StringBuffer();
b1 = new StringBuffer();
b.append("#");
b1.append("#");
for(Metadata c: ((DataMessage) message).getMetadata()){
b.append(c.getId());
b.append("\t");
b1.append(c.getDimension());
b1.append("\t");
}
b.setCharAt(b.length()-1, '\n');
b1.setCharAt(b1.length()-1, '\n');
// Open new file and write header
// Construct file name
if(appendSuffix){
@@ -28,9 +28,8 @@ import java.util.List;
import com.google.common.eventbus.Subscribe;
import ch.psi.fda.core.messages.ComponentMetadata;
import ch.psi.fda.core.messages.DataMessage;
import ch.psi.fda.core.messages.DataMessageMetadata;
import ch.psi.fda.core.messages.Metadata;
import ch.psi.fda.core.messages.StreamDelimiterMessage;
import ch.psi.fda.core.messages.EndOfStreamMessage;
import ch.psi.fda.core.messages.Message;
@@ -40,7 +39,6 @@ import ch.psi.fda.core.messages.Message;
*/
public class DataSerializerTXT2D implements DataSerializer{
private DataMessageMetadata metadata;
private File file;
private boolean appendSuffix = false;
@@ -51,83 +49,84 @@ public class DataSerializerTXT2D implements DataSerializer{
List<Class<?>> clist;
int dsize;
int dcount;
boolean firstF;
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 DataSerializerTXT2D(DataMessageMetadata metadata, File file){
this.metadata = metadata;
public DataSerializerTXT2D(File file){
this.file = file;
// Check if input queue does only hold 2D data
int maxdim=0;
for(ComponentMetadata m: metadata.getComponents()){
if(m.getDimension()>maxdim){
maxdim=m.getDimension();
}
if(m.getDimension()>1){
throw new RuntimeException("Serializer does only support 2D data (XD data found)");
}
}
if(maxdim<1){
throw new RuntimeException("Serializer does only support 2D data ("+maxdim+"D data found)");
}
}
@Subscribe
public void onMessage(Message message) {
try{
if(first){
first = false;
// WORKAROUND BEGIN
if(appendSuffix){
// Append a count suffix to the file. If there is already a file with
// this suffix increase the counter for the suffix
int cnt = 0;
String fname = this.file.getAbsolutePath(); // Determine file name
String extension = fname.replaceAll("^.*\\.", ""); // Determine extension
// fname = fname.replaceAll("(_[0-9]+)?\\."+extension+"$", "");
fname = fname.replaceAll("\\."+extension+"$", "");
outfile = new File(String.format("%s_%04d.%s", fname, cnt, extension));
while(outfile.exists()){
cnt++;
outfile = new File(String.format("%s_%04d.%s", fname, cnt, extension));
}
}
else{
outfile = this.file;
}
// WORKAROUND END
// Transposed data list
dlist = new ArrayList<List<Object>>();
clist = new ArrayList<Class<?>>();
dsize = 0; // Size of the dimension
dcount = 0;
firstF = true;
}
if(message instanceof DataMessage){
DataMessage m = (DataMessage) message;
// Initialize list
if(firstF){
if(first){
first = false;
// Check if input queue does only hold 2D data
int maxdim=0;
metadata = m.getMetadata();
for(Metadata me: m.getMetadata()){
if(me.getDimension()>maxdim){
maxdim=me.getDimension();
}
if(me.getDimension()>1){
throw new RuntimeException("Serializer does only support 2D data (XD data found)");
}
}
if(maxdim<1){
throw new RuntimeException("Serializer does only support 2D data ("+maxdim+"D data found)");
}
// WORKAROUND BEGIN
if(appendSuffix){
// Append a count suffix to the file. If there is already a file with
// this suffix increase the counter for the suffix
int cnt = 0;
String fname = this.file.getAbsolutePath(); // Determine file name
String extension = fname.replaceAll("^.*\\.", ""); // Determine extension
// fname = fname.replaceAll("(_[0-9]+)?\\."+extension+"$", "");
fname = fname.replaceAll("\\."+extension+"$", "");
outfile = new File(String.format("%s_%04d.%s", fname, cnt, extension));
while(outfile.exists()){
cnt++;
outfile = new File(String.format("%s_%04d.%s", fname, cnt, extension));
}
}
else{
outfile = this.file;
}
// WORKAROUND END
// Transposed data list
dlist = new ArrayList<List<Object>>();
clist = new ArrayList<Class<?>>();
dsize = 0; // Size of the dimension
dcount = 0;
for(Object o: m.getData()){
dlist.add(new ArrayList<Object>());
clist.add(o.getClass());
}
firstF=false;
}
// Put data into data list
@@ -156,7 +155,7 @@ public class DataSerializerTXT2D implements DataSerializer{
// Create text images
for(int t=0; t<dlist.size(); t++ ){
// Get component metadata
ComponentMetadata c = metadata.getComponents().get(t);
Metadata c = metadata.get(t);
writer.write(c.getId()+"\n");
@@ -2,15 +2,15 @@
*
* 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 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.
* 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/>.
@@ -28,170 +28,167 @@ import java.util.List;
import com.google.common.eventbus.Subscribe;
import ch.psi.fda.core.messages.ComponentMetadata;
import ch.psi.fda.core.messages.DataMessage;
import ch.psi.fda.core.messages.DataMessageMetadata;
import ch.psi.fda.core.messages.Metadata;
import ch.psi.fda.core.messages.StreamDelimiterMessage;
import ch.psi.fda.core.messages.Message;
/**
* Serialize data received by a DataQueue
*/
public class DataSerializerTXTSplit implements DataSerializer{
private DataMessageMetadata metadata;
public class DataSerializerTXTSplit implements DataSerializer {
private File file;
private int maxdim = 0;
private boolean first = true;
private List<String> header;
private List<String> data;
public DataSerializerTXTSplit(DataMessageMetadata metadata, File file){
this.metadata = metadata;
public DataSerializerTXTSplit(File file) {
this.file = file;
// Determine maximum dimension
for(ComponentMetadata m: metadata.getComponents()){
if(m.getDimension()>maxdim){
maxdim=m.getDimension();
}
}
if(maxdim<1){
throw new RuntimeException("Split serializer only supports data > 1 dimension");
}
}
@Subscribe
public void onMessage(Message message) {
try{
if(first){
first=false;
header = new ArrayList<String>();
data = new ArrayList<String>();
// Write header
StringBuffer b = new StringBuffer();
StringBuffer b1 = new StringBuffer();
b.append("#");
b1.append("#");
for(ComponentMetadata c: metadata.getComponents()){
b.append(c.getId());
b.append("\t");
b1.append(c.getDimension());
b1.append("\t");
}
b.setCharAt(b.length()-1, '\n');
b1.setCharAt(b1.length()-1, '\n');
header.add(b.toString());
header.add(b1.toString());
}
try {
// Write data
// Read Message
if(message instanceof DataMessage){
// Write message to file - each message will result in one line
DataMessage m = (DataMessage) message;
StringBuffer buffer = new StringBuffer();
for(Object o: m.getData()){
if(o.getClass().isArray()){
// If the array object is of type double[] display its content
if(o instanceof double[]){
double[] oa = (double[]) o;
for(double o1 : oa){
buffer.append(o1);
buffer.append(" "); // Use space instead of tab
}
buffer.replace(buffer.length()-1,buffer.length()-1 , "\t"); // Replace last space with tab
}
else if(o instanceof Object[]){
// TODO need to be recursive ...
Object[] oa = (Object[])o;
for(Object o1 : oa){
buffer.append(o1);
buffer.append(" "); // Use space instead of tab
}
buffer.replace(buffer.length()-1,buffer.length()-1 , "\t"); // Replace last space with tab
}
else{
buffer.append("-"); // Not supported
}
}
else{
buffer.append(o);
buffer.append("\t");
if (message instanceof DataMessage) {
if (first) {
first = false;
header = new ArrayList<String>();
data = new ArrayList<String>();
// Write header
StringBuffer b = new StringBuffer();
StringBuffer b1 = new StringBuffer();
b.append("#");
b1.append("#");
for (Metadata c : ((DataMessage) message).getMetadata()) {
b.append(c.getId());
b.append("\t");
b1.append(c.getDimension());
b1.append("\t");
if (c.getDimension() > maxdim) {
maxdim = c.getDimension();
}
}
buffer.deleteCharAt(buffer.length()-1); // Remove last character (i.e. \t)
buffer.append("\n"); // Append newline
data.add(buffer.toString());
}
else if(message instanceof StreamDelimiterMessage){
StreamDelimiterMessage m = (StreamDelimiterMessage) message;
if(m.getNumber()==maxdim-1){
writeData(header, data);
// Clear data
data.clear();
b.setCharAt(b.length() - 1, '\n');
b1.setCharAt(b1.length() - 1, '\n');
header.add(b.toString());
header.add(b1.toString());
if (maxdim < 1) {
throw new RuntimeException("Split serializer only supports data > 1 dimension");
}
}
// Write message to file - each message will result in one line
DataMessage m = (DataMessage) message;
StringBuffer buffer = new StringBuffer();
for (Object o : m.getData()) {
if (o.getClass().isArray()) {
// If the array object is of type double[] display its
// content
if (o instanceof double[]) {
double[] oa = (double[]) o;
for (double o1 : oa) {
buffer.append(o1);
buffer.append(" "); // Use space instead of tab
}
buffer.replace(buffer.length() - 1, buffer.length() - 1, "\t"); // Replace
// last
// space
// with
// tab
} else if (o instanceof Object[]) {
// TODO need to be recursive ...
Object[] oa = (Object[]) o;
for (Object o1 : oa) {
buffer.append(o1);
buffer.append(" "); // Use space instead of tab
}
buffer.replace(buffer.length() - 1, buffer.length() - 1, "\t"); // Replace
// last
// space
// with
// tab
} else {
buffer.append("-"); // Not supported
}
} else {
buffer.append(o);
buffer.append("\t");
}
}
buffer.deleteCharAt(buffer.length() - 1); // Remove last
// character (i.e.
// \t)
buffer.append("\n"); // Append newline
data.add(buffer.toString());
} else if (message instanceof StreamDelimiterMessage) {
StreamDelimiterMessage m = (StreamDelimiterMessage) message;
if (m.getNumber() == maxdim - 1) {
writeData(header, data);
// Clear data
data.clear();
}
}
} catch (IOException e) {
throw new RuntimeException("Data serializer had a problem writing to the specified file",e);
throw new RuntimeException("Data serializer had a problem writing to the specified file", e);
}
}
private void writeData(List<String> header, List<String> data) throws IOException{
private void writeData(List<String> header, List<String> data) throws IOException {
// WORKAROUND BEGIN
File outfile;
// if(appendSuffix){
// Append a count suffix to the file. If there is already a file with
// this suffix increase the counter for the suffix
int cnt = 0;
String fname = this.file.getAbsolutePath(); // Determine file name
String extension = fname.replaceAll("^.*\\.", ""); // Determine extension
fname = fname.replaceAll("\\."+extension+"$", "");
// if(appendSuffix){
// Append a count suffix to the file. If there is already a file with
// this suffix increase the counter for the suffix
int cnt = 0;
String fname = this.file.getAbsolutePath(); // Determine file name
String extension = fname.replaceAll("^.*\\.", ""); // Determine
// extension
fname = fname.replaceAll("\\." + extension + "$", "");
outfile = new File(String.format("%s_%04d.%s", fname, cnt, extension));
while (outfile.exists()) {
cnt++;
outfile = new File(String.format("%s_%04d.%s", fname, cnt, extension));
while(outfile.exists()){
cnt++;
outfile = new File(String.format("%s_%04d.%s", fname, cnt, extension));
}
// }
// else{
// outfile = this.file;
// }
}
// }
// else{
// outfile = this.file;
// }
// WORKAROUND END
// Open file
BufferedWriter writer = new BufferedWriter(new FileWriter(outfile));
// Write header
for(String s: header){
for (String s : header) {
writer.write(s);
}
// Write data
for(String s: data){
for (String s : data) {
writer.write(s);
}
// Close file
writer.close();
}
@@ -19,5 +19,12 @@
package ch.psi.fda.visualizer;
import ch.psi.plot.Plot;
public interface SeriesDataFilter {
/**
* Get the plot for the filter
* @return
*/
public Plot getPlot();
}
@@ -30,15 +30,8 @@ import javax.swing.SwingUtilities;
import com.google.common.eventbus.Subscribe;
import ch.psi.fda.core.messages.DataMessage;
import ch.psi.fda.core.messages.DataMessageMetadata;
import ch.psi.fda.core.messages.StreamDelimiterMessage;
import ch.psi.fda.core.messages.EndOfStreamMessage;
import ch.psi.fda.model.v1.ArrayDetector;
import ch.psi.fda.model.v1.ContinuousPositioner;
import ch.psi.fda.model.v1.Detector;
import ch.psi.fda.model.v1.LinearPositioner;
import ch.psi.fda.model.v1.Positioner;
import ch.psi.fda.model.v1.PseudoPositioner;
import ch.psi.fda.model.v1.Visualization;
import ch.psi.plot.Plot;
import ch.psi.plot.xy.LinePlot;
@@ -56,7 +49,7 @@ public class Visualizer {
private static Logger logger = Logger.getLogger(Visualizer.class.getName());
private List<Plot> plots = new ArrayList<Plot>();
// private List<Plot> plots = new ArrayList<Plot>();
private boolean updateAtStreamElement = true;
private boolean updateAtStreamDelimiter = true;
@@ -66,17 +59,27 @@ public class Visualizer {
private boolean clearPlot;
private List<SeriesDataFilter> filters;
public Visualizer(DataMessageMetadata meta, List<Visualization> vl){
filters = mapVisualizations(meta, vl);
private List<Visualization> visualizations;
private boolean first = true;
public Visualizer(List<Visualization> vl){
this.visualizations = vl;
}
@Subscribe
public void onDataMessage(final DataMessage message){
if(first){
first=false;
filters = VisMapper.mapVisualizations(message.getMetadata(), visualizations);
}
// 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 (Plot plot: plots) {
for (SeriesDataFilter f: filters) {
Plot plot = f.getPlot();
if(plot instanceof MatrixPlot){
((MatrixPlotData) ((MatrixPlot)plot).getData()).clear();
}
@@ -99,8 +102,8 @@ public class Visualizer {
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().get(xyfilter.getIndexX());
Object dY = message.getData().get(xyfilter.getIndexY());
Object dX = message.getData(xyfilter.getIdX());
Object dY = message.getData(xyfilter.getIdY());
Double dataX = Double.NaN;
Double dataY = Double.NaN;
if(dX instanceof Double){
@@ -136,7 +139,7 @@ public class Visualizer {
sc.removeSeries(0);
}
double[] data = (double[]) message.getData().get(xyfilter.getIndexY());
double[] data = message.getData(xyfilter.getIdY());
// Copy data starting from offset to size
int size = data.length;
int offset = xyfilter.getOffset();
@@ -154,7 +157,7 @@ public class Visualizer {
else if(filter instanceof XYZSeriesDataFilter){
XYZSeriesDataFilter xyzfilter = (XYZSeriesDataFilter) filter;
try{
((MatrixPlot)xyzfilter.getPlot()).getData().addData((Double) message.getData().get(xyzfilter.getIndexX()),(Double) message.getData().get(xyzfilter.getIndexY()), (Double) message.getData().get(xyzfilter.getIndexZ()));
((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
@@ -164,8 +167,8 @@ public class Visualizer {
else if(filter instanceof XYZSeriesArrayDataFilter){
XYZSeriesArrayDataFilter xyzfilter = (XYZSeriesArrayDataFilter) filter;
try{
double[] data = (double[]) message.getData().get(xyzfilter.getIndexZ());
double y = (Double) message.getData().get(xyzfilter.getIndexY());
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++){
@@ -201,7 +204,9 @@ public class Visualizer {
// Update matrix plot at the end of each line
if(updateAtStreamDelimiter){
for (Plot plot: plots) {
for(SeriesDataFilter f: filters){
Plot plot = f.getPlot();
// for (Plot plot: plots) {
if(plot instanceof MatrixPlot){
((MatrixPlot)plot).update();
}
@@ -227,7 +232,8 @@ public class Visualizer {
// Update plots if updateAtEndOfStream flag is set
if(updateAtEndOfStream){
// Update matrix plots
for (Plot plot: 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
@@ -244,282 +250,14 @@ public class Visualizer {
clearPlot = false;
}
/**
* Retrieve id string of the passed object
* @param object
* @return Id string of object
*/
private String getId(Object object){
String id;
if(object instanceof Positioner){
id = ((Positioner)object).getId();
}
else if (object instanceof Detector){
id = ((Detector)object).getId();
}
else if (object instanceof ch.psi.fda.model.v1.Manipulation){
id = ((ch.psi.fda.model.v1.Manipulation)object).getId();
}
// For testing purposes
else if(object instanceof String){
id = (String) object;
}
else{
throw new RuntimeException("Unable to identify id of object reference "+object);
}
return id;
}
/**
* Get configured visualizations
* Note: This method is public because it is also used by the VisualizationEngine
* @param vl List of configured visualizations
* @return List of visualization configuration
*/
private List<SeriesDataFilter> mapVisualizations(DataMessageMetadata meta, List<Visualization> vl){
List<SeriesDataFilter> filters = new ArrayList<SeriesDataFilter>();
for(Visualization v: vl){
if(v instanceof ch.psi.fda.model.v1.LinePlot){
ch.psi.fda.model.v1.LinePlot lp = (ch.psi.fda.model.v1.LinePlot) v;
// Create plot for visualization
ch.psi.plot.xy.LinePlot plot = new ch.psi.plot.xy.LinePlot(lp.getTitle());
plots.add(plot);
// Create data filter for visualization
String idX = getId(lp.getX());
int indexX = meta.getIndex(idX);
int dimX = meta.getComponents().get(indexX).getDimension();
List<Object> l = lp.getY();
for(Object o: l){
String idY = getId(o);
int indexY = meta.getIndex(idY);
int dimY = meta.getComponents().get(indexY).getDimension();
XYSeriesDataFilter filter = new XYSeriesDataFilter(idX, idY, indexX, indexY, plot);
filter.setDimensionX(dimX);
filter.setDimensionY(dimY);
filter.setSeriesName(idY);
filters.add(filter);
}
}
else if(v instanceof ch.psi.fda.model.v1.LinePlotArray){
// Array visualization
ch.psi.fda.model.v1.LinePlotArray lp = (ch.psi.fda.model.v1.LinePlotArray) v;
// Create plot for visualization
ch.psi.plot.xy.LinePlot plot = new ch.psi.plot.xy.LinePlot(lp.getTitle());
plots.add(plot);
// Create data filter for visualization
List<Object> l = lp.getY();
for(Object o: l){
String idY = getId(o);
int indexY = meta.getIndex(idY);
int dimY = meta.getComponents().get(indexY).getDimension();
XYSeriesArrayDataFilter filter = new XYSeriesArrayDataFilter(idY, indexY, plot);
filter.setDimensionY(dimY);
filter.setMaxSeries(lp.getMaxSeries()*lp.getY().size()); // Workaround - keep for each array max series
filter.setOffset(lp.getOffset());
filter.setSize(lp.getSize());
filter.setSeriesName(idY);
filters.add(filter);
}
}
else if(v instanceof ch.psi.fda.model.v1.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.model.v1.MatrixPlot mp = (ch.psi.fda.model.v1.MatrixPlot) v;
double minX, maxX;
int nX;
double minY, maxY;
int nY;
String idX, idY, idZ;
// X Axis
if(mp.getX() instanceof LinearPositioner){
LinearPositioner linp = ((LinearPositioner)mp.getX());
idX = linp.getId();
minX = (Math.min(linp.getStart(), linp.getEnd()));
maxX = (Math.max(linp.getStart(), linp.getEnd()));
nX = ((int) Math.floor((Math.abs(maxX-minX))/linp.getStepSize()) + 1);
}
else if(mp.getX() instanceof PseudoPositioner){
PseudoPositioner pp = ((PseudoPositioner)mp.getX());
idX = pp.getId();
minX = (1); // Count starts at 1
maxX = (pp.getCounts());
nX = (pp.getCounts());
}
else if(mp.getX() instanceof ContinuousPositioner){
ContinuousPositioner conp = ((ContinuousPositioner)mp.getX());
idX = conp.getId();
minX = (Math.min(conp.getStart(), conp.getEnd()));
maxX = (Math.max(conp.getStart(), conp.getEnd()));
nX = ((int) Math.floor((Math.abs(maxX-minX))/conp.getStepSize()) + 1);
}
else{
// Fail as we cannot determine the min, max and number of steps
throw new RuntimeException(mp.getX().getClass().getName()+" is not supported as x-axis of a MatrixPlot");
}
// Y Axis
if(mp.getY() instanceof LinearPositioner){
LinearPositioner linp = ((LinearPositioner)mp.getY());
idY = linp.getId();
minY = (Math.min(linp.getStart(), linp.getEnd()));
maxY = (Math.max(linp.getStart(), linp.getEnd()));
nY = ((int) Math.floor((Math.abs(maxY-minY))/linp.getStepSize()) + 1);
}
else if(mp.getY() instanceof PseudoPositioner){
PseudoPositioner pp = ((PseudoPositioner)mp.getY());
idY = pp.getId();
minY = (1); // Count starts at 1
maxY = (pp.getCounts());
nY = (pp.getCounts());
}
else{
// Fail as we cannot determine the min, max and number of steps
throw new RuntimeException(mp.getY().getClass().getName()+" is not supported as y-axis of a MatrixPlot");
}
// Z Dimension
idZ = getId(mp.getZ());
// Create plot for visualization
MatrixPlotData data = new MatrixPlotData(minX, maxX, nX, minY, maxY, nY);
MatrixPlot plot = new MatrixPlot(mp.getTitle(), data);
plots.add(plot);
// Create data filter for visualization
int indexX = meta.getIndex(idX);
int indexY = meta.getIndex(idY);
int indexZ = meta.getIndex(idZ);
int dimX = meta.getComponents().get(indexX).getDimension();
int dimY = meta.getComponents().get(indexY).getDimension();
int dimZ = meta.getComponents().get(indexZ).getDimension();
XYZSeriesDataFilter filter = new XYZSeriesDataFilter(idX, idY, idZ, indexX, indexY, indexZ, plot);
filter.setDimensionX(dimX);
filter.setDimensionY(dimY);
filter.setDimensionZ(dimZ);
filters.add(filter);
}
else if(v instanceof ch.psi.fda.model.v1.MatrixPlotArray){
// Support for 2D waveform plots
ch.psi.fda.model.v1.MatrixPlotArray mp = (ch.psi.fda.model.v1.MatrixPlotArray) v;
// Get size of the array detector
int arraySize = 0;
Object o = mp.getZ();
if(o instanceof ArrayDetector){
ArrayDetector ad = (ArrayDetector) o;
arraySize = ad.getArraySize();
}
else{
// Workaround
arraySize = mp.getSize(); // of array is from a manipulation the size is not known. Then the size will indicate the size of the array to display
}
int offset = mp.getOffset();
// Determine size for array
int size = mp.getSize();
if(size>0 && offset+size<arraySize){
size = mp.getSize();
}
else{
size=arraySize-offset;
}
double minY, maxY;
int nY;
double minX = offset;
double maxX = offset+size-1;
int nX = size;
String idY, idZ;
// Y Axis
if(mp.getY() instanceof LinearPositioner){
LinearPositioner linp = ((LinearPositioner)mp.getY());
idY = linp.getId();
minY = (Math.min(linp.getStart(), linp.getEnd()));
maxY = (Math.max(linp.getStart(), linp.getEnd()));
nY = ((int) Math.floor((Math.abs(maxY-minY))/linp.getStepSize()) + 1);
}
else if(mp.getY() instanceof PseudoPositioner){
PseudoPositioner pp = ((PseudoPositioner)mp.getY());
idY = pp.getId();
minY = (1); // Count starts at 1
maxY = (pp.getCounts());
nY = (pp.getCounts());
}
else if(mp.getY() instanceof ContinuousPositioner){
ContinuousPositioner conp = ((ContinuousPositioner)mp.getY());
idY = conp.getId();
minY = (Math.min(conp.getStart(), conp.getEnd()));
maxY = (Math.max(conp.getStart(), conp.getEnd()));
nY = ((int) Math.floor((Math.abs(maxY-minY))/conp.getStepSize()) + 1);
}
else{
// Fail as we cannot determine the min, max and number of steps
throw new RuntimeException(mp.getY().getClass().getName()+" is not supported as x-axis of a MatrixPlot");
}
// Z Dimension
idZ = getId(mp.getZ());
// Create plot for visualization
MatrixPlotData data = new MatrixPlotData(minX, maxX, nX, minY, maxY, nY);
MatrixPlot plot = new MatrixPlot(mp.getTitle(), data);
plots.add(plot);
// Create data filter for visualization
int indexY = meta.getIndex(idY);
int indexZ = meta.getIndex(idZ);
int dimY = meta.getComponents().get(indexY).getDimension();
int dimZ = meta.getComponents().get(indexZ).getDimension();
XYZSeriesArrayDataFilter filter = new XYZSeriesArrayDataFilter(idY, idZ, indexY, indexZ, offset, size, plot);
filter.setDimensionY(dimY);
filter.setDimensionZ(dimZ);
filters.add(filter);
}
else{
// Visualization type (currently) not supported
throw new RuntimeException(v.getClass().getName()+" is not supported as visualization type");
}
}
return filters;
}
/**
* Get the plot panels for the visualizations
* @return List of configured JPanels
*/
public List<JPanel> getPlotPanels(){
List<JPanel> panels = new ArrayList<JPanel>();
for(Plot plot: plots){
panels.add(plot.getChartPanel());
for(SeriesDataFilter f: filters){
panels.add(f.getPlot().getChartPanel());
}
return panels;
@@ -36,9 +36,6 @@ public class XYSeriesArrayDataFilter implements SeriesDataFilter {
// Name of the series generated by this filter
private String seriesName = "";
// Index of stream message components used for x and y
private final int indexY;
// Dimension of the x,y value - used to determine whether a new series should be created for this filter
private int dimensionY;
@@ -55,9 +52,8 @@ public class XYSeriesArrayDataFilter implements SeriesDataFilter {
// Plot the data of this filter goes to
private final Plot plot;
public XYSeriesArrayDataFilter(String idY, int indexY, Plot plot){
public XYSeriesArrayDataFilter(String idY, Plot plot){
this.idY = idY;
this.indexY = indexY;
this.plot = plot;
}
@@ -82,13 +78,6 @@ public class XYSeriesArrayDataFilter implements SeriesDataFilter {
this.seriesName = seriesName;
}
/**
* @return the indexY
*/
public int getIndexY() {
return indexY;
}
/**
* @return the dimensionY
*/
@@ -38,10 +38,6 @@ public class XYSeriesDataFilter implements SeriesDataFilter{
// Name of the series generated by this filter
private String seriesName = "";
// Index of stream message components used for x and y
private final int indexX;
private final int indexY;
// Dimension of the x,y value - used to determine whether a new series should be created for this filter
private int dimensionX;
private int dimensionY;
@@ -57,129 +53,54 @@ public class XYSeriesDataFilter implements SeriesDataFilter{
private boolean newseries = false;
public XYSeriesDataFilter(String idX, String idY, int indexX, int indexY, Plot plot){
public XYSeriesDataFilter(String idX, String idY, Plot plot){
this.idX = idX;
this.idY = idY;
this.indexX = indexX;
this.indexY = indexY;
this.plot = plot;
}
/**
* @return the xId
*/
public String getIdX() {
return idX;
}
/**
* @return the yId
*/
public String getIdY() {
return idY;
}
/**
* @return the seriesName
*/
public String getSeriesName() {
return seriesName;
}
/**
* @param seriesName the seriesName to set
*/
public void setSeriesName(String seriesName) {
this.seriesName = seriesName;
}
/**
* @return the indexX
*/
public int getIndexX() {
return indexX;
}
/**
* @return the indexY
*/
public int getIndexY() {
return indexY;
}
/**
* @return the dimensionX
*/
public int getDimensionX() {
return dimensionX;
}
/**
* @return the dimensionY
*/
public int getDimensionY() {
return dimensionY;
}
/**
* @param dimensionY the dimensionY to set
*/
public void setDimensionY(int dimensionY) {
this.dimensionY = dimensionY;
}
/**
* @param dimensionX the dimensionX to set
*/
public void setDimensionX(int dimensionX) {
this.dimensionX = dimensionX;
}
/**
* @return the count
*/
public int getCount() {
return count;
}
/**
* @param count the count to set
*/
public void setCount(int count) {
this.count = count;
}
/**
* @return the plot
*/
public Plot getPlot() {
return plot;
}
/**
* @return the actualSeries
*/
public XYSeriesP getActualSeries() {
return actualSeries;
}
/**
* @param actualSeries the actualSeries to set
*/
public void setActualSeries(XYSeriesP actualSeries) {
this.actualSeries = actualSeries;
}
/**
* @return the newseries
*/
public boolean isNewseries() {
return newseries;
}
/**
* @param newseries the newseries to set
*/
public void setNewseries(boolean newseries) {
this.newseries = newseries;
}
@@ -33,10 +33,6 @@ public class XYZSeriesArrayDataFilter implements SeriesDataFilter {
// Name of the series generated by this filter
private String seriesName = "";
// Index of stream message components used for x and y
private final int indexY;
private final int indexZ;
// Dimension of the x,y value - used to determine whether a new series should be created for this filter
private int dimensionY;
private int dimensionZ;
@@ -52,11 +48,9 @@ public class XYZSeriesArrayDataFilter implements SeriesDataFilter {
private final int size;
private final int offset;
public XYZSeriesArrayDataFilter(String idY, String idZ, int indexY, int indexZ, int offset, int size, Plot plot){
public XYZSeriesArrayDataFilter(String idY, String idZ, int offset, int size, Plot plot){
this.idY = idY;
this.idZ = idZ;
this.indexY = indexY;
this.indexZ = indexZ;
this.offset = offset;
this.size = size;
this.plot = plot;
@@ -69,16 +63,6 @@ public class XYZSeriesArrayDataFilter implements SeriesDataFilter {
return idZ;
}
/**
* @return the indexZ
*/
public int getIndexZ() {
return indexZ;
}
/**
* @return the dimensionZ
*/
public int getDimensionZ() {
return dimensionZ;
}
@@ -153,16 +137,6 @@ public class XYZSeriesArrayDataFilter implements SeriesDataFilter {
return idY;
}
/**
* @return the indexX
*/
public int getIndexY() {
return indexY;
}
/**
* @return the offset
*/
public int getOffset() {
return offset;
}
@@ -34,11 +34,6 @@ public class XYZSeriesDataFilter implements SeriesDataFilter {
// Name of the series generated by this filter
private String seriesName = "";
// Index of stream message components used for x and y
private final int indexX;
private final int indexY;
private final int indexZ;
// Dimension of the x,y value - used to determine whether a new series should be created for this filter
private int dimensionX;
private int dimensionY;
@@ -53,13 +48,10 @@ public class XYZSeriesDataFilter implements SeriesDataFilter {
private boolean newseries = false;
public XYZSeriesDataFilter(String idX, String idY, String idZ, int indexX, int indexY, int indexZ, Plot plot){
public XYZSeriesDataFilter(String idX, String idY, String idZ, Plot plot){
this.idX = idX;
this.idY = idY;
this.idZ = idZ;
this.indexX = indexX;
this.indexY = indexY;
this.indexZ = indexZ;
this.plot = plot;
}
@@ -70,16 +62,6 @@ public class XYZSeriesDataFilter implements SeriesDataFilter {
return idZ;
}
/**
* @return the indexZ
*/
public int getIndexZ() {
return indexZ;
}
/**
* @return the dimensionZ
*/
public int getDimensionZ() {
return dimensionZ;
}
@@ -174,24 +156,6 @@ public class XYZSeriesDataFilter implements SeriesDataFilter {
public String getIdY() {
return idY;
}
/**
* @return the indexX
*/
public int getIndexX() {
return indexX;
}
/**
* @return the indexY
*/
public int getIndexY() {
return indexY;
}
/**
* @return the plot
*/
public Plot getPlot() {
return plot;
}