/*
* Copyright (c) 2004-2009, Jean-Marc François. All Rights Reserved.
* Licensed under the New BSD license. See the LICENSE file.
*/
package be.ac.ulg.montefiore.run.jahmm.io;
import java.io.IOException;
import java.io.StreamTokenizer;
import java.util.ArrayList;
import java.util.List;
import be.ac.ulg.montefiore.run.jahmm.ObservationVector;
/**
* Reads an {@link be.ac.ulg.montefiore.run.jahmm.ObservationVector
* ObservationVector} up to (and including) a semi-colon.
* <p>
* The format of this observation is an opening bracket (<tt>[</tt>) followed
* by the components of the vector separated by spaces or tabs. Each
* component is a number (following the format
* [+-]?[0123456789]+[.]?[0123456789]*).
* <p>
* For example, reading
* <pre>[76 45. -2.23];</pre>
* creates an observation such as the one generated by
* <code>new ObservationVector(new double[] {76., 45., -2.23});</code>
*/
public class ObservationVectorReader
extends ObservationReader<ObservationVector>
{
private int dimension;
/**
* Constructs a reader of {@link ObservationVector ObservationVector}.
*/
public ObservationVectorReader()
{
dimension = -1;
}
/**
* Constructs a reader of {@link ObservationVector ObservationVector}.
* Verifies the dimension of the observations read.
*
* @param dimension The dimension of each observation.
*/
public ObservationVectorReader(int dimension)
{
if (dimension <= 0)
throw new IllegalArgumentException("Argument must be strictly " +
"positive");
this.dimension = dimension;
}
/**
* An {@link be.ac.ulg.montefiore.run.jahmm.ObservationInteger
* ObservationInteger} reader, as explained in
* {@link ObservationReader ObservationReader}.
*
* @param st A stream tokenizer.
* @return An {@link be.ac.ulg.montefiore.run.jahmm.ObservationInteger
* ObservationInteger}.
*/
public ObservationVector read(StreamTokenizer st)
throws IOException, FileFormatException
{
if (st.nextToken() != (int) '[')
throw new FileFormatException(st.lineno(), "'[' expected");
List<Double> values = new ArrayList<Double>();
loop:
while(true)
switch (st.nextToken()) {
case StreamTokenizer.TT_NUMBER:
values.add(new Double(st.nval));
break;
case ']':
if (values.size() == 0)
throw new FileFormatException(st.lineno(),
"Empty vector found");
break loop;
default:
throw new FileFormatException(st.lineno(),
"Number or ']' expected");
}
if (st.nextToken() != (int) ';')
throw new FileFormatException(st.lineno(), "';' expected");
if (dimension > 0 && values.size() != dimension)
throw new FileFormatException(st.lineno(),
"Bad observation: wrong dimension (" + values.size() +
" instead of " + dimension +")");
double[] valuesArray = new double[values.size()];
for (int i = 0; i < values.size(); i++)
valuesArray[i] = (values.get(i)).doubleValue();
return new ObservationVector(valuesArray);
}
}