// ReadFile.java
//
// This file contains the methods needed to read a conditional probability
// matrix or a list of observations from a text file.
//
//
// Tom Chothia T.Chothia@cwi.nl June/2008
// 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 <http://www.gnu.org/licenses/>.
//
// Copyright 2008 Tom Chothia
package sim.app.socialsystems2;
import java.io.*;
import java.util.regex.*;
import java.util.Vector;
public class ReadFile {
int noOfInputs;
String[] outputNames;
String[] inputNames;
double[][] channelMatrix;
Observations obs;
int noOfGroups;
String[] groupNames;
int[] groupForRow;
@SuppressWarnings("unchecked")
Vector[] rowsForGroup;
// boolean multiSender;
// inputsPerRow is a vector of vectors.
// inputPerRow.get(i) are the indexes of the inputs
// on row i of the channel matrix
Vector<Vector<Integer>> inputsPerRow = new Vector<Vector<Integer>>();
Channel channel;
String fileName;
public ReadFile (String channelFile) {fileName = channelFile; }
public Channel getChannel()
{
return channel;
}
@SuppressWarnings("unchecked")
public Vector[] getInputPerRow()
{
return vectorVectorToArrayVector(inputsPerRow);
}
//public boolean multiSender()
//{
// return multiSender;
//}
public Observations getObservations()
{
return obs;
}
public String[] getOutputName()
{
return outputNames;
}
public String[] getInputName ()
{
return inputNames;
}
public double[][] getChannelMatrix ()
{
return channelMatrix;
}
@SuppressWarnings("unchecked")
public void readChannel ()
{
try {
BufferedReader reader = new BufferedReader(new FileReader(fileName));
try {
String line = reader.readLine();
while ( (line.trim()).equalsIgnoreCase("") || (line.trim()).startsWith("//"))
{ line = reader.readLine(); }
channel = new Channel();
String[] terms = line.split("\\|");
Pattern pattern = Pattern.compile("\\([\\s]*([\\d]+)[\\s]*,[\\s]*([\\d]+)[\\s]*\\)[\\s]*:[\\s]*([\\d]+)*[\\s]*");
Matcher matcher = pattern.matcher(terms[0].trim());
if (matcher.find())
{
// It's a conditional channel.
channel.kind = Channel.COND;
int noOfInputs = Integer.parseInt(matcher.group(1));
int noOfOutputs = Integer.parseInt(matcher.group(2));
int noOfGroups = Integer.parseInt(matcher.group(3));
outputNames = new String[noOfOutputs];
inputNames = new String[noOfInputs];
groupNames = new String[noOfGroups];
channelMatrix = new double[noOfInputs][noOfOutputs];
groupForRow = new int[noOfInputs];
rowsForGroup = new Vector[noOfGroups];
for(int i=0;i<noOfGroups;i++)
{
rowsForGroup[i] = new Vector();
}
// Read the output names from along the top of the matrix
for (int i= 1;i<terms.length;i++)
{
outputNames[i-1] = terms[i].trim();
}
channel.setOutputNames(outputNames);
// Read the rest of the matrix one line at a time
int linecounter = 0;
while (( line = reader.readLine()) != null)
{
if (!(line.trim()).equalsIgnoreCase("") && !(line.trim()).startsWith("//") )
{
terms = line.split("\\|");
String[] rowlabel = terms[0].split(":");
inputNames[linecounter] = rowlabel[0].trim();
int groupIndex = addifnew(rowlabel[1].trim(),groupNames);
groupForRow[linecounter] = groupIndex;
rowsForGroup[groupIndex].add(new Integer(linecounter));
for (int i=1;i<terms.length;i++)
{
channelMatrix[linecounter][i-1] = Double.parseDouble(terms[i].trim());
}
linecounter++;
}
}
channel.setRowsForGroup(rowsForGroup);
channel.setGroupForRow(groupForRow);
channel.setInputNames(inputNames);
channel.setMatrix(channelMatrix);
channel.setOutputNames(outputNames);
channel.setGroupNames(groupNames);
}
else
{
pattern = Pattern.compile("\\([\\s]*([\\d]+)[\\s]*,[\\s]*([\\d]+)[\\s]*\\)");
matcher = pattern.matcher(terms[0].trim());
if (matcher.find())
{
// It's a basic channel
channel.kind = Channel.BASIC;
int noOfInputs = Integer.parseInt(matcher.group(1));
int noOfOutputs = Integer.parseInt(matcher.group(2));
outputNames = new String[noOfOutputs];
inputNames = new String[noOfInputs];
channelMatrix = new double[noOfInputs][noOfOutputs];
// Read the output names from along the top of the matrix
for (int i= 1;i<terms.length;i++)
{
outputNames[i-1] = terms[i].trim();
}
channel.setOutputNames(outputNames);
// Read the rest of the matrix one line at a time
int linecounter = 0;
while (( line = reader.readLine()) != null)
{
if (!(line.trim()).equalsIgnoreCase("") && !(line.trim()).startsWith("//") )
{
terms = line.split("\\|");
inputNames[linecounter] = terms[0].trim();
for (int i=1;i<terms.length;i++)
{
channelMatrix[linecounter][i-1] = Double.parseDouble(terms[i].trim());
}
linecounter++;
}
}
channel.setInputNames(inputNames);
channel.setMatrix(channelMatrix);
}
else
{
pattern = Pattern.compile("\\([\\s]*([\\d]+)[\\s]*,[\\s]*([\\d]+)[\\s]*,[\\s]*([\\d]+)[\\s]*\\)*");
matcher = pattern.matcher(terms[0].trim());
if (matcher.find())
{
// Channel is a multi-access channel
channel.kind = Channel.MULTI;
String[] arrayOfInputs;
outputNames = new String[Integer.parseInt(matcher.group(3))];
inputNames = new String[Integer.parseInt(matcher.group(1))];
channelMatrix = new double[Integer.parseInt(matcher.group(2))][Integer.parseInt(matcher.group(3))];
// Read the output names from along the top of the matrix
for (int i= 1;i<terms.length;i++)
{ outputNames[i-1] = terms[i].trim(); }
channel.setOutputNames(outputNames);
// Read the rest of the matrix one line at a time
int rowCounter = 0;
while (( line = reader.readLine()) != null)
{
if (!(line.trim()).equalsIgnoreCase("") && !(line.trim()).startsWith("//") )
{
terms = line.split("\\|");
arrayOfInputs = terms[0].split(",");
// change all the strings to their index's inNames
// add a new entry to inNames if needed
// then add the indexes to inputsPerRow[linecounter]
Vector<Integer> inputIndexRowVector = new Vector<Integer>();
if (!arrayOfInputs[0].trim().equals(""))
{
for (int ic=0;ic<arrayOfInputs.length;ic++)
{
// look up the index of arrayOfInputs[ic]
int inputIndex = 0;
while (inputNames[inputIndex] != null && !(inputNames[inputIndex].equals(arrayOfInputs[ic].trim())))
{ inputIndex++; }
if (inputNames[inputIndex] == null)
{ inputNames[inputIndex] = arrayOfInputs[ic].trim(); }
// inputIndex is the index of arrayOfInputs[ic]
inputIndexRowVector.add(new Integer(inputIndex));
}
}
inputsPerRow.add(inputIndexRowVector);
for (int i=1;i<terms.length;i++)
{ channelMatrix[rowCounter][i-1] = Double.parseDouble(terms[i].trim()); }
rowCounter++;
}
}
channel.setInputNames(inputNames);
channel.setInputsPerRow(vectorVectorToArrayVector(inputsPerRow));
channel.setMatrix(channelMatrix);
}
else
{
// The file has the wrong format
System.out.println("Syntax error while reading line: "+line);
System.out.println(" ... file should start with a term of the form (noOfInputs,noOfOutputs)");
System.out.println(" (noOfInputs,noOfOutputs):noOfGroups or (noOfInputs,noOfRows,noOfOutputs)");
System.exit(0);
}
}
}
}
finally {
reader.close();
}
}
catch (FileNotFoundException ex){
System.out.println("File not found");
System.out.println("I was looking for "+fileName);
System.out.println(" ... but couldn't find it");
System.exit(0);
}
catch (IOException ex){
ex.printStackTrace();
System.exit(0);
}
}
int addifnew(String str, String[] strs)
{
int i;
for(i = 0;i<strs.length;i++)
{
if (strs[i] == null) { strs[i]=str;break;}
if (strs[i].equals(str)) {break;}
}
return i;
}
@SuppressWarnings("unchecked")
public static Vector[] vectorVectorToArrayVector (Vector<Vector<Integer>> v)
{
Vector[] result = new Vector[v.size()];
for (int i=0;i<v.size();i++)
{
result[i] = (v.get(i));
}
return result;
}
// public void readMultiChannel ()
// {
// try {
// BufferedReader reader = new BufferedReader(new FileReader(fileName));
//
// try {
// String line = reader.readLine();
// String[] terms = line.split("\\|");
// String[] arrayOfInputs;
// Pattern pattern = Pattern.compile("\\([\\s]*([\\d]+)[\\s]*,[\\s]*([\\d]+)[\\s]*,[\\s]*([\\d]+)[\\s]*\\)");
// Matcher matcher = pattern.matcher(terms[0].trim());
// if (!matcher.find())
// {
// System.out.println("Syntax error while reading line: "+line);
// System.out.println(" ... wants a term of the form (noOfInputs,noOfRows,noOfOutputs)");
// System.exit(0);
// }
// outputNames = new String[Integer.parseInt(matcher.group(3))];
// inputNames = new String[Integer.parseInt(matcher.group(1))];
// channelMatrix = new double[Integer.parseInt(matcher.group(2))][Integer.parseInt(matcher.group(3))];
// for (int i= 1;i<terms.length;i++)
// { outputNames[i-1] = terms[i].trim(); }
// int rowCounter = 0;
// while (( line = reader.readLine()) != null)
// {
// terms = line.split("\\|");
// arrayOfInputs = terms[0].split(",");
// // change all the strings to their index's inNames
// // add a new entry to inNames if needed
// // then add the indexes to inputsPerRow[linecounter]
// Vector inputIndexRowVector = new Vector();
// if (!arrayOfInputs[0].trim().equals(""))
// {
// for (int ic=0;ic<arrayOfInputs.length;ic++)
// {
// // look up the index of arrayOfInputs[ic]
// int inputIndex = 0;
// while (inputNames[inputIndex] != null && !(inputNames[inputIndex].equals(arrayOfInputs[ic].trim())))
// { inputIndex++; }
// if (inputNames[inputIndex] == null)
// { inputNames[inputIndex] = arrayOfInputs[ic].trim(); }
// // inputIndex is the index of arrayOfInputs[ic]
// inputIndexRowVector.add(new Integer(inputIndex));
// }
// }
// inputsPerRow.add(inputIndexRowVector);
// for (int i=1;i<terms.length;i++)
// { channelMatrix[rowCounter][i-1] = Double.parseDouble(terms[i].trim()); }
// rowCounter++;
// }
// }
// finally { reader.close(); }
// }
// catch (IOException ex){ ex.printStackTrace(); }
// }
public void readObservations ()
{
obs = new Observations();
try
{
BufferedReader input = new BufferedReader(new FileReader(fileName));
try
{
String line = input.readLine();
while ( (line.trim()).equalsIgnoreCase("") || (line.trim()).startsWith("//"))
{ line = input.readLine(); }
Pattern pattern = Pattern.compile("\\([\\s]*([\\w:]+)[\\s]*,[\\s]*([\\w:]+)[\\s]*\\)");
Matcher matcher;
while ( (line.trim()).equalsIgnoreCase("") || (line.trim()).startsWith("//"))
{ line = input.readLine(); }
while ( line != null)
{
matcher = pattern.matcher(line.trim());
if (!matcher.find()) {System.out.println("Syntax error while reading line: "+line);}
obs.addObservation(matcher.group(1),matcher.group(2));
line = input.readLine();
}
}
finally
{
input.close();
}
}
catch (FileNotFoundException ex){
System.out.println("File not found");
System.out.println("I was looking for "+fileName);
System.out.println(" ... but couldn't find it");
System.exit(0);
}
catch (IOException ex){
ex.printStackTrace();
System.exit(0);
}
}
}