All Downloads are FREE. Search and download functionalities are using the official Maven repository.

weka.gui.streams.InstanceJoiner Maven / Gradle / Ivy

Go to download

The Waikato Environment for Knowledge Analysis (WEKA), a machine learning workbench. This version represents the developer version, the "bleeding edge" of development, you could say. New functionality gets added to this version.

There is a newer version: 3.9.6
Show newest version
/*
 *   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");
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy