weka.gui.streams.InstanceJoiner Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of weka-stable Show documentation
Show all versions of weka-stable Show documentation
The Waikato Environment for Knowledge Analysis (WEKA), a machine
learning workbench. This is the stable version. Apart from bugfixes, this version
does not receive any other updates.
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
/*
* InstanceJoiner.java
* Copyright (C) 1999-2012 University of Waikato, Hamilton, New Zealand
*
*/
package weka.gui.streams;
import java.io.Serializable;
import java.util.Vector;
import weka.core.Instance;
import weka.core.Instances;
/**
* A bean that joins two streams of instances into one.
*
* @author Len Trigg ([email protected])
* @version $Revision: 10222 $
*/
public class InstanceJoiner implements Serializable, InstanceProducer,
SerialInstanceListener {
/** for serialization */
private static final long serialVersionUID = -6529972700291329656L;
/** The listeners */
private final Vector listeners;
/** Debugging mode */
private boolean b_Debug;
/** The input format for instances */
protected Instances m_InputFormat;
/** The current output instance */
private Instance m_OutputInstance;
/** Whether the first input batch has finished */
private boolean b_FirstInputFinished;
// private boolean b_SecondInputFinished; NOT USED
/** Setup the initial states of the member variables */
public InstanceJoiner() {
listeners = new Vector();
m_InputFormat = null;
m_OutputInstance = null;
b_Debug = false;
b_FirstInputFinished = false;
// b_SecondInputFinished = false; NOT USED
}
/**
* Sets the format of the input instances. If the filter is able to determine
* the output format before seeing any input instances, it does so here. This
* default implementation assumes the output format is determined when
* batchFinished() is called.
*
* @param instanceInfo an Instances object containing the input instance
* structure (any instances contained in the object are ignored -
* only the structure is required).
* @return true if the outputFormat may be collected immediately
*/
public boolean inputFormat(Instances instanceInfo) {
m_InputFormat = new Instances(instanceInfo, 0);
notifyInstanceProduced(new InstanceEvent(this,
InstanceEvent.FORMAT_AVAILABLE));
b_FirstInputFinished = false;
// b_SecondInputFinished = false; NOT USED
return true;
}
/**
* Gets the format of the output instances. This should only be called after
* input() or batchFinished() has returned true.
*
* @return an Instances object containing the output instance structure only.
* @throws Exception if no input structure has been defined (or the output
* format hasn't been determined yet)
*/
@Override
public Instances outputFormat() throws Exception {
if (m_InputFormat == null) {
throw new Exception("No output format defined.");
}
return new Instances(m_InputFormat, 0);
}
public boolean input(Instance instance) throws Exception {
if (m_InputFormat == null) {
throw new Exception("No input instance format defined");
}
if (instance != null) {
m_OutputInstance = (Instance) instance.copy();
notifyInstanceProduced(new InstanceEvent(this,
InstanceEvent.INSTANCE_AVAILABLE));
return true;
}
return false;
}
/**
* Signify that this batch of input to the filter is finished. If the filter
* requires all instances prior to filtering, output() may now be called to
* retrieve the filtered instances. Any subsequent instances filtered should
* be filtered based on setting obtained from the first batch (unless the
* inputFormat has been re-assigned or new options have been set). This
* default implementation assumes all instance processing occurs during
* inputFormat() and input().
*
* @throws Exception if no input structure has been defined
*/
public void batchFinished() throws Exception {
if (m_InputFormat == null) {
throw new Exception("No input instance format defined");
}
notifyInstanceProduced(new InstanceEvent(this, InstanceEvent.BATCH_FINISHED));
}
/**
* Output an instance after filtering but do not remove from the output queue.
*
* @return the instance that has most recently been filtered (or null if the
* queue is empty).
* @throws Exception if no input structure has been defined
*/
@Override
public Instance outputPeek() throws Exception {
if (m_InputFormat == null) {
throw new Exception("No output instance format defined");
}
if (m_OutputInstance == null) {
return null;
}
return (Instance) m_OutputInstance.copy();
}
public void setDebug(boolean debug) {
b_Debug = debug;
}
public boolean getDebug() {
return b_Debug;
}
@Override
public synchronized void addInstanceListener(InstanceListener ipl) {
listeners.addElement(ipl);
}
@Override
public synchronized void removeInstanceListener(InstanceListener ipl) {
listeners.removeElement(ipl);
}
@SuppressWarnings("unchecked")
protected void notifyInstanceProduced(InstanceEvent e) {
if (listeners.size() > 0) {
if (b_Debug) {
System.err.println(this.getClass().getName()
+ "::notifyInstanceProduced()");
}
Vector l;
synchronized (this) {
l = (Vector) listeners.clone();
}
for (int i = 0; i < l.size(); i++) {
l.elementAt(i).instanceProduced(e);
}
// If there are any listeners, and the event is an INSTANCE_AVAILABLE,
// they should have retrieved the instance with outputPeek();
try {
if (e.getID() == InstanceEvent.INSTANCE_AVAILABLE) {
m_OutputInstance = null;
}
} catch (Exception ex) {
System.err.println("Problem: notifyInstanceProduced() was\n"
+ "called with INSTANCE_AVAILABLE, but output()\n"
+ "threw an exception: " + ex.getMessage());
}
}
}
public void instanceProduced(InstanceEvent e) {
Object source = e.getSource();
if (source instanceof InstanceProducer) {
try {
InstanceProducer a = (InstanceProducer) source;
switch (e.getID()) {
case InstanceEvent.FORMAT_AVAILABLE:
if (b_Debug) {
System.err.println(this.getClass().getName()
+ "::firstInstanceProduced() - Format available");
}
inputFormat(a.outputFormat());
break;
case InstanceEvent.INSTANCE_AVAILABLE:
if (b_Debug) {
System.err.println(this.getClass().getName()
+ "::firstInstanceProduced() - Instance available");
}
input(a.outputPeek());
break;
case InstanceEvent.BATCH_FINISHED:
if (b_Debug) {
System.err.println(this.getClass().getName()
+ "::firstInstanceProduced() - End of instance batch");
}
batchFinished();
b_FirstInputFinished = true;
break;
default:
System.err.println(this.getClass().getName()
+ "::firstInstanceProduced() - unknown event type");
break;
}
} catch (Exception ex) {
System.err.println(ex.getMessage());
}
} else {
System.err.println(this.getClass().getName()
+ "::firstInstanceProduced() - Unknown source object type");
}
}
@Override
public void secondInstanceProduced(InstanceEvent e) {
Object source = e.getSource();
if (source instanceof InstanceProducer) {
try {
if (!b_FirstInputFinished) {
throw new Exception(this.getClass().getName()
+ "::secondInstanceProduced() - Input received from"
+ " second stream before first stream finished");
}
InstanceProducer a = (InstanceProducer) source;
switch (e.getID()) {
case InstanceEvent.FORMAT_AVAILABLE:
if (b_Debug) {
System.err.println(this.getClass().getName()
+ "::secondInstanceProduced() - Format available");
}
// Check the formats are compatible
if (!(a.outputFormat()).equalHeaders(outputFormat())) {
throw new Exception(this.getClass().getName()
+ "::secondInstanceProduced() - incompatible instance streams\n"
+ (a.outputFormat()).equalHeadersMsg(outputFormat()));
}
break;
case InstanceEvent.INSTANCE_AVAILABLE:
if (b_Debug) {
System.err.println(this.getClass().getName()
+ "::secondInstanceProduced() - Instance available");
}
input(a.outputPeek());
break;
case InstanceEvent.BATCH_FINISHED:
if (b_Debug) {
System.err.println(this.getClass().getName()
+ "::secondInstanceProduced() - End of instance batch");
}
batchFinished();
break;
default:
System.err.println(this.getClass().getName()
+ "::secondInstanceProduced() - unknown event type");
break;
}
} catch (Exception ex) {
System.err.println(ex.getMessage());
}
} else {
System.err.println(this.getClass().getName()
+ "::secondInstanceProduced() - Unknown source object type");
}
}
}