view src/org/qmul/eecs/c4dm/sia/SiaTecMain.java @ 14:eb086fc26803

new
author stevenh
date Tue, 08 Jan 2013 18:18:52 +0000
parents
children b43260af3de6
line wrap: on
line source
package org.qmul.eecs.c4dm.sia;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.mindswap.pellet.jena.PelletReasonerFactory;
import org.qmul.eecs.c4dm.sia.exceptions.DimensionException;
import org.qmul.eecs.c4dm.sia.model.Datapoint;
import org.qmul.eecs.c4dm.sia.model.NDimensionalObject;
import org.qmul.eecs.c4dm.sia.model.SiatecX;
import org.qmul.eecs.c4dm.sia.model.VectorTable;
import org.qmul.eecs.c4dm.sia.model.VectorTableElement;
import org.qmul.eecs.c4dm.sia.rdf.Namespaces;
import org.qmul.eecs.c4dm.sia.utilities.Display;
import org.qmul.eecs.c4dm.sparql.utilities.SparqlWrapperMethods;

import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;

/**
 * <p>
 * Title: SiaTecMain
 * </p>
 * <p>
 * Description: An RDF/OWL/Java implementation of the SIATEC pattern discovery algorithm.
 * See "Algorithms for discovering repeated patterns in multidimensional representations of polyphonic music"
 * by Meredith, D. and Lemstr&ouml;m, K. and Wiggins, G.A.
 * </p>
 * 
 * @author Steve Hargreaves, C4DM, Queen Mary University of London
 */
public class SiaTecMain {

	// The ontology loaded as dataset
	private static final String ontology = "file:src/rdf/siaDatapointOntology.n3";

	// The final output file
	private static final String finalModelFileName = "src/rdf/finalSiaTecModel";

	// SPARQL queries
	private static final String[] selectQueries = new String[] {
		// A SPARQL-DL query
		"file:src/sparql/select_all.sparql"
		};

	// CONSTRUCT queries
	private static final String[] constructQueries = new String[] {
		// SPARQL-DL CONSTRUCT queries
		"file:src/sparql/construct_siatec_vector_table_bnodes.sparql",
		"file:src/sparql/construct_vector_table_details.sparql" };

	// ASK queries
	private static final String[] askQueries = new String[] {
		// A SPARQL-DL ASK query
		};
	
	public void run() {

		// First create a Jena ontology model backed by the Pellet reasoner
		// (note, the Pellet reasoner is required)
		OntModel ontModel = ModelFactory
				.createOntologyModel(PelletReasonerFactory.THE_SPEC);

		// Then read the data from the file into the ontology model
		ontModel.read(ontology, "N3");
		
		// Set the value of SIA_NS_URI as the namespace for 'sia' found in
		// the ontology
		Namespaces.SIA_NS_URI = ontModel.getNsPrefixURI("sia");

		// Create custom sia Datapoint objects
		List<Datapoint> datapoints = SiaDatapointFactory.create(ontModel);
		
		// STEP 1 - Order the datapoints
		Collections.sort(datapoints);

		// Add datapoint order info to model
		SiaDatapointFactory.assertOrder(ontModel, datapoints);
		
		// STEP 2 - Compute the vector table W, and sort
		// Run all the CONSTRUCT queries
		for (int i = 0; i < constructQueries.length; i++) {
			String constructQuery = constructQueries[i];

			Model newModel = SparqlWrapperMethods.executeConstructQuery(constructQuery, ontModel);

			// Add new triples to the current model
			ontModel.add(newModel);
		}
		VectorTable vectorTableW = SiaVectorTableElementFactory.createW(ontModel, datapoints);

		// STEP 3 - Create custom SIATEC VectorTableElement objects (V)
		VectorTable vectorTableV = SiaVectorTableElementFactory.createV(ontModel, datapoints);
		List<VectorTableElement> vteListV = vectorTableV.getVteList();

		// STEP 4 - Sort V
		Collections.sort(vteListV);

		// Add vector table element order info to model
		SiaVectorTableElementFactory.assertOrder(ontModel, vteListV);
		
		// STEP 5 - "Vectorize" the MTPs
		int m = vteListV.size();
		int i = 0;
		ArrayList<SiatecX> x = new ArrayList<SiatecX>();
		
		while (i < m)
		{
			ArrayList<NDimensionalObject> q = new ArrayList<NDimensionalObject>();
			int j = i + 1;
			while (j < m && (vteListV.get(i).compareToIgnoreDatapoints(vteListV.get(j)) == 0))
			{
				NDimensionalObject vector = vteListV.get(j).getFromDatapoint().subtract(vteListV.get(j - 1).getFromDatapoint());
				q.add(vector);
				j++;
			}
			
			SiatecX iq = new SiatecX();
			iq.setI(i+1);
			iq.setQ(q);
			x.add(iq);
			i = j;
		}
		
		System.out.println("X");
		printX(x);

		// Sort the elements of x
		Collections.sort(x);
		
		// Rename as y to match algorithm description in paper
		ArrayList<SiatecX> y = (ArrayList<SiatecX>) x.clone();
		
		System.out.println("\nY = Sorted X");
		printX(y);
		
		// Display results using algorithm figures 23, 24 and 25 of the research paper
		int r = y.size();
		m = vteListV.size();
		i = 0; // *** check indexing
		System.out.println();
		System.out.print("{");
		if (r > 0) // *** check indexing
		{
			do
			{
				int j = y.get(i).getI() - 1; // *** check indexing
				List<Integer> iList = new ArrayList<Integer>();
				while (j < m && (vteListV.get(j).getVector().compareTo(vteListV.get(y.get(i).getI() - 1).getVector()) == 0)) // *** check indexing
				{
//					// debug start
//					for (int hundip = 0; hundip < vteList.size(); hundip++)
//					{
//						System.out.println("v[" + hundip + ",2] = " + vteList.get(hundip).getFromDatapoint().getOrderedIndex());
//					}
//					// debug start					

					iList.add(vteListV.get(j).getFromDatapoint().getOrderedIndex());					
					j++;
				}
				System.out.print("<");
				Display.printPattern(iList, datapoints);
				System.out.print(",");
				printSetOfTranslators(iList, datapoints, vectorTableW);
				System.out.print(">");
				do
				{
					i++;
				} while (i < r && (y.get(i).compareToIgnoreI(y.get(i - 1)) == 0)); // *** check indexing
				
				if (i < r) // *** check indexing
				{
					System.out.print(",");
					System.out.println();
				}
			} while (i < r); // *** check indexing
		}
		System.out.println("}");

		// Run all the SELECT queries
		for (i = 0; i < selectQueries.length; i++) {

			String selectQuery = selectQueries[i];
			SparqlWrapperMethods.queryTheModel(selectQuery, ontModel);

		}

		// Run all the ASK queries
		for (i = 0; i < askQueries.length; i++) {

			String askQuery = askQueries[i];
			SparqlWrapperMethods.askTheModel(askQuery, ontModel);

		}

		// Write the model to a file
		File outFileRdf = new File(finalModelFileName + ".rdf");
		File outFileN3 = new File(finalModelFileName + ".n3");
		FileOutputStream outFileOutputStreamRdf;
		FileOutputStream outFileOutputStreamN3;

		// RDF/XML version
		try {
			outFileOutputStreamRdf = new FileOutputStream(outFileRdf);
			ontModel.writeAll(outFileOutputStreamRdf, "RDF/XML", null);
		} catch (FileNotFoundException e) {
			System.out.println("Unable to write to file: "
					+ outFileRdf.getAbsolutePath());
			e.printStackTrace();
			System.exit(1);
		}

		// N3 version
		try {
			outFileOutputStreamN3 = new FileOutputStream(outFileN3);
			ontModel.writeAll(outFileOutputStreamN3, "N3", null);
		} catch (FileNotFoundException e) {
			System.out.println("Unable to write to file: "
					+ outFileN3.getAbsolutePath());
			e.printStackTrace();
			System.exit(1);
		}

		System.out.println("Model written to files: "
				+ outFileRdf.getAbsolutePath() + " and " + outFileN3.getAbsolutePath());
	}

	private void printSetOfTranslators(List<Integer> iList, List<Datapoint> datapoints, VectorTable vectorTableW) {
		int p = iList.size();
		int n = datapoints.size();

		if (p == 1)
		{
//			// debug start
//			for (int f = 0; f < vectorTableW.size(); f++)
//			{
//				try {
//					System.out.println("W[" + f + "] = <<" + vectorTableW.getVteList().get(f).getDimensionValue(1) + "," + vectorTableW.getVteList().get(f).getDimensionValue(2) + ">," + vectorTableW.getVteList().get(f).getFromDatapoint().getOrderedIndex() + ">");
//				} catch (DimensionException e) {
//					// TODO Auto-generated catch block
//					e.printStackTrace();
//				}
//			}
//			// debug end
			System.out.print("{");
			Display.printVector(vectorTableW.getVector(iList.get(0), 1));
			for (int k = 2; k <= n; k++)
			{
				System.out.print(",");
				Display.printVector(vectorTableW.getVector(iList.get(0), k));
			}
			System.out.print("}");
		}
		else
		{
			System.out.print("{");
			List<Integer> jList = new ArrayList<Integer>();
			for (int k = 0; k < p; k++)
			{
				jList.add(1);
			}
			boolean finished = false;
			boolean first_vector = true;
			int k = 1;

			while (!finished)
			{
				if (jList.get(k) <= jList.get(k - 1))
				{
					jList.set(k, jList.get(k - 1) + 1);
				}
				
				while (jList.get(k) <= (n - p + k + 1)
						&& (vectorTableW.getVector(iList.get(k), jList.get(k)).compareTo(vectorTableW.getVector(iList.get(k - 1), jList.get(k - 1))) < 0))
				{
					jList.set(k, jList.get(k) + 1);
				}
				
				if (jList.get(k) > n - p + k + 1)
				{
					finished = true;
				}
				else if (vectorTableW.getVector(iList.get(k), jList.get(k)).compareTo(vectorTableW.getVector(iList.get(k - 1), jList.get(k - 1))) > 0)
				{
					k = 1;
					jList.set(0, jList.get(0) + 1);
					if (jList.get(0) > n - p + 1)
					{
						finished = true;
					}
				}
				else if (k + 1 == p)
				{
					if (!first_vector)
					{
						System.out.print(",");
					}
					else
					{
						first_vector = false;
					}
					
					Display.printVector(vectorTableW.getVector(iList.get(k), jList.get(k)));
					k = 0;
					
					while (k < p)
					{
						jList.set(k, jList.get(k) + 1);
						if (jList.get(k) > n - p + k +1)
						{
							finished = true;
							k = p -1;
						}
						k++;
					}
					k = 1;
				}
				else
				{
					k++;
				}
			}
			System.out.print("}");
		}
	}

	private void printX(ArrayList<SiatecX> x) {
		for (SiatecX iq : x)
		{
			System.out.print(iq.getI() + ",");
			for (NDimensionalObject q : iq.getQ())
			{
				System.out.print("<");
				int dimensions = q.getDimensionValues().size();
				for (int dim = 1; dim <= dimensions; dim++)
				{
					try {
						System.out.print(q.getDimensionValue(dim) + (dim == dimensions ? "" : ","));
					} catch (DimensionException e) {
						e.printStackTrace();
						System.exit(1);
					}
				}
				System.out.println(">");
			}
			System.out.println();
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		SiaTecMain app = new SiaTecMain();
		app.run();
	}

}