view src/org/qmul/eecs/c4dm/sia/SiaMain.java @ 85:00e46306eaa8

displays number of MTPs and TECs removed TDB dataset reads and writes removed unused imports
author stevenh
date Sat, 31 Aug 2013 14:15:33 +0100
parents 2f5c6ad34a47
children 8277be90601f
line wrap: on
line source
package org.qmul.eecs.c4dm.sia;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

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.SiaDataset;
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.utilities.Display;

import com.hp.hpl.jena.ontology.OntClass;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.ontology.OntResource;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.update.UpdateAction;
import com.hp.hpl.jena.util.iterator.ExtendedIterator;

/**
 * <p>
 * Title: SiaMain
 * </p>
 * <p>
 * Description: An RDF/OWL/Java implementation of the SIA and SIATEC pattern discovery algorithms.
 * See "Algorithms for discovering repeated patterns in multidimensional representations of polyphonic music"
 * by Meredith, D. and Lemstr&ouml;m, K. and Wiggins, G.A.
 * Optionally takes a single command line argument file path to an N3 ontology file, otherwise uses a
 * hardcoded file path.
 * Writes SIA and SIATEC result to stdout and writes the entire RDF model to the TDB dataset described in
 * src/assemblers/tdb-assembler.ttl
 * </p>
 * 
 * @author Steve Hargreaves, C4DM, Queen Mary University of London
 */
public class SiaMain {
	
	// The location of the TDB database
	public static final String assemblerFile = "src/assemblers/tdb-assembler.ttl";
	
	// The name of the graph used in the dataset
	public static final String graph = "http://localhost:3030/siaGraph";

	// The ontology loaded as dataset
	public static String ontology = "file:src/rdf/siaTestDatapointOntology.n3";

	// UPDATE queries
	private static final String insertNewDimValsForVectorTableQuery = "file:src/sparql/insert_new_dimVals_for_vector_table.sparql";
	private static final String insertSiatecVectorTableBNodesQuery = "file:src/sparql/insert_siatec_vector_table_bnodes.sparql";
	private static final String insertVectorTableDetailsQuery = "file:src/sparql/insert_vector_table_details.sparql";

	public void run(String[] args) {
		
		// If a command-line argument was supplied, assume it's the path
		// of an N3 ontology file
		if (args.length == 1)
			ontology = args[0];

		OntModel ontModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
		ontModel.read(ontology, "N3");						

		// 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
		// Run all the UPDATE queries
    	UpdateAction.readExecute(insertSiatecVectorTableBNodesQuery, ontModel);
    	UpdateAction.readExecute(insertNewDimValsForVectorTableQuery, ontModel);
    	UpdateAction.readExecute(insertVectorTableDetailsQuery, ontModel);
    	
		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 3 - Order the VectorTableElement objects
		Collections.sort(vteListV);

		// Add vector table element order info to model
		SiaVectorTableElementFactory.assertOrder(ontModel, vteListV);

		// STEP 4 - Display the results
		displayAndAssertSiaResults(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;
		}
		
		// Sort the elements of x
		Collections.sort(x);
		
		// Rename as y to match algorithm description in paper
		ArrayList<SiatecX> y = (ArrayList<SiatecX>) x.clone();
		
		// Display results using algorithm figures 23, 24 and 25 of the research paper
		
//		// find the blank node that represents this dataset
//		// (for now, assume there's just one of these. In reality
//		// we should make sure we've picked the one associated
//		// with this set of datapoints
//		OntResource siaDataset = getSiaDataset(ontModel);
//
//		Property siatecResultProperty = ontModel.getOntProperty(SiatecResult.PROPERTY_URI);
//		Property mtpDatapointProperty = ontModel.getOntProperty(MtpDatapoint.PROPERTY_URI);
		
		int countTecs = 0;

		int r = y.size();
		m = vteListV.size();
		i = 0;
		System.out.println();
		System.out.print("{");
		if (r > 0)
		{
			do
			{
				int j = y.get(i).getI() - 1;
				List<Integer> iList = new ArrayList<Integer>();
				while (j < m && (vteListV.get(j).compareToIgnoreDatapoints(vteListV.get(y.get(i).getI() - 1)) == 0))
				{
					iList.add(vteListV.get(j).getFromDatapoint().getOrderedIndex());					
					j++;
				}
				countTecs++;
				System.out.print("<");
				Display.printPattern(iList, datapoints);
				
//				// state that blank node has property sia:siatecResult and object (blank node x)
//				Resource siatecResultBnode = ontModel.createResource(AnonId.create());
//				ontModel.add(siaDataset, siatecResultProperty, siatecResultBnode);
//				
//				Iterator<Integer> iListIter = iList.iterator();
//				while (iListIter.hasNext())
//				{
//					int datapointIndex = iListIter.next();
//					Datapoint datapoint = datapoints.get(datapointIndex - 1);
//					ontModel.add(siatecResultBnode, mtpDatapointProperty, datapoint.getResource());
//				}
				
				System.out.print(",");
				printSetOfTranslators(iList, datapoints, vectorTableW);
				System.out.print(">");
				do
				{
					i++;
				} while (i < r && (y.get(i).compareToIgnoreI(y.get(i - 1)) == 0));
				
				if (i < r)
				{
					System.out.print(",");
					System.out.println();
				}
			} while (i < r);
		}
		System.out.println("}");
		
		System.out.println("Number of TECs: " + countTecs);
    	System.out.println("Number of Datapoints (n) = " + 		datapoints.size() + ", k = 3");
	}

	/**
	 * @param ontModel 
	 * @param vteList
	 */
	public void displayAndAssertSiaResults(OntModel ontModel, List<VectorTableElement> vteList) {
		int m = vteList.size();
		int i = 0;
		
		System.out.println();
		System.out.print("{");
		
//		Property siaResultProperty = ontModel.getOntProperty(SiaResult.PROPERTY_URI);
//		Property dimensionValueProperty = ontModel.getOntProperty(DimensionValue.PROPERTY_URI);
//		Property mtpDatapointProperty = ontModel.getOntProperty(MtpDatapoint.PROPERTY_URI);

		int countMtps = 0;
		while (i < m)
		{
			countMtps++;
			System.out.print("<");
			Display.printVector(vteList.get(i));
			
			// find the blank node that represents this dataset
			// (for now, assume there's just one of these. In reality
			// we should make sure we've picked the one associated
			// with this set of datapoints
//			OntResource siaDataset = getSiaDataset(ontModel);
//			
//			// state that blank node has property sia:siaResult and object (blank node x)
//			Resource siaResultBnode = ontModel.createResource(AnonId.create());
//			ontModel.add(siaDataset, siaResultProperty, siaResultBnode);
//			// Assert all the dimensions and dimension values for vteList.get(i).getFromDatapoint()
//			NDimensionalObject vector = vteList.get(i);
//			Vector<DimensionValue> vectorDimVals = vector.getDimensionValues();
//			Iterator<DimensionValue> vectorDimValsIter = vectorDimVals.iterator();
//			while (vectorDimValsIter.hasNext())
//			{
//				DimensionValue vectorDimVal = vectorDimValsIter.next();
//				ontModel.add(siaResultBnode, dimensionValueProperty, vectorDimVal.getResource());
//			}
			
			System.out.print(",{");
			Display.printVector(vteList.get(i).getFromDatapoint());

//			ontModel.add(siaResultBnode, mtpDatapointProperty, vteList.get(i).getFromDatapoint().getResource());
			
			int j = i + 1;
						
			while (j < m && (vteList.get(i).compareToIgnoreDatapoints(vteList.get(j)) == 0))
			{
				System.out.print(",");
				Display.printVector(vteList.get(j).getFromDatapoint());

//				ontModel.add(siaResultBnode, mtpDatapointProperty, vteList.get(j).getFromDatapoint().getResource());

				j++;
			}
			System.out.print("}>");
			if (j < m)
			{
				System.out.print(",");
				System.out.println();
			}
			i = j;
		}
		System.out.println("}");
		System.out.println("Number of MTPs: " + countMtps);
	}

	private OntResource getSiaDataset(OntModel ontModel) {
		OntResource siaDataset = null;
		OntClass siaDatasetClass = ontModel.getOntClass(SiaDataset.RESOURCE_URI);
		ExtendedIterator<? extends OntResource> siaDatasetIter = siaDatasetClass.listInstances();
		int numSiaDatasets = 0;
		while (siaDatasetIter.hasNext())
		{
			siaDataset = siaDatasetIter.next();
			numSiaDatasets++;
		}
		if (numSiaDatasets != 1)
		{
			try {
				throw new Exception("Model should contain exactly one sia:Dataset, but found " + numSiaDatasets);
			} catch (Exception e) {
				e.printStackTrace();
				System.exit(1);
			}
		}
		return siaDataset;
	}

	/**
	 * @param vteIter
	 * @param message
	 */
	public void displayNDimensionalObjects(Iterator<VectorTableElement> vteIter, String message) {
		System.out.println(message);
		System.out.println("----------");
		while (vteIter.hasNext())
		{
			VectorTableElement vte = vteIter.next();
			System.out.println("from: " + vte.getFromDatapoint().getResource().getLocalName() + " to: " + vte.getToDatapoint().getResource().getLocalName());			
		}
	}

	/**
	 * @param datapointIter
	 * @param message
	 */
	public void displayDatapoints(Iterator<Datapoint> datapointIter, String message) {
		System.out.println(message);
		System.out.println("----------");
		while (datapointIter.hasNext())
		{
			Datapoint datapoint = datapointIter.next();
			System.out.println( datapoint.getResource().getLocalName());			
		}
	}

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

		if (p == 1)
		{
			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)
						&& (((VectorTableElement)vectorTableW.getVector(iList.get(k), jList.get(k))).compareToIgnoreDatapoints(((VectorTableElement)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 (((VectorTableElement)vectorTableW.getVector(iList.get(k), jList.get(k))).compareToIgnoreDatapoints(((VectorTableElement)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) {
		long startTime = System.currentTimeMillis();
		SiaMain app = new SiaMain();
		app.run(args);
		long endTime = System.currentTimeMillis();
		long elapsedTime = endTime - startTime;
		System.out.println("Completed in " + elapsedTime + " ms");
	}

}