view src/org/qmul/eecs/c4dm/sia/SiaVectorTableElementFactory.java @ 90:19076fd08f74

no longer makes unnecessary use of ontModel
author stevenh
date Sat, 31 Aug 2013 17:33:43 +0100
parents d19a0e764a97
children
line wrap: on
line source
package org.qmul.eecs.c4dm.sia;

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

import org.qmul.eecs.c4dm.sia.exceptions.DimensionException;
import org.qmul.eecs.c4dm.sia.model.Datapoint;
import org.qmul.eecs.c4dm.sia.model.DimensionValue;
import org.qmul.eecs.c4dm.sia.model.DirectlyFollows;
import org.qmul.eecs.c4dm.sia.model.FromDatapoint;
import org.qmul.eecs.c4dm.sia.model.MemberOfOrderedSet;
import org.qmul.eecs.c4dm.sia.model.OrderedIndex;
import org.qmul.eecs.c4dm.sia.model.OrderedSet;
import org.qmul.eecs.c4dm.sia.model.ToDatapoint;
import org.qmul.eecs.c4dm.sia.model.VectorTable;
import org.qmul.eecs.c4dm.sia.model.VectorTableElement;

import com.hp.hpl.jena.ontology.OntClass;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntResource;
import com.hp.hpl.jena.rdf.model.AnonId;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.NodeIterator;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.StmtIterator;
import com.hp.hpl.jena.util.iterator.ExtendedIterator;
import com.hp.hpl.jena.vocabulary.RDF;

public class SiaVectorTableElementFactory {

	/**
	 * @param datapoints
	 * @return
	 * @throws DimensionException 
	 */
	public static VectorTable createV(List<Datapoint> datapoints) throws DimensionException {
		return create(datapoints, false);
	}
	
	/**
	 * @param datapoints
	 * @return
	 * @throws DimensionException 
	 */
	public static VectorTable createW(List<Datapoint> datapoints) throws DimensionException {
		return create(datapoints, true);
	}

	/**
	 * @param datapoints
	 * @param returnWResults
	 * @return
	 * @throws DimensionException 
	 */
	public static VectorTable create(List<Datapoint> datapoints, boolean returnWResults) throws DimensionException {
		
		VectorTable vectorTable = new VectorTable();
		
		List<Datapoint> fromDatapoints = datapoints;
		Iterator<Datapoint> fromDatapointsIter = fromDatapoints.iterator();
		
		List<VectorTableElement> vteList = new ArrayList<VectorTableElement>();
		VectorTableElement vte;
		while (fromDatapointsIter.hasNext())
		{
			Datapoint fromDatapoint = fromDatapointsIter.next();

			List<Datapoint> toDatapoints = datapoints;
			Iterator<Datapoint> toDatapointsIter = toDatapoints.iterator();

			while (toDatapointsIter.hasNext())
			{
				Datapoint toDatapoint = toDatapointsIter.next();
				
				vte = new VectorTableElement();
				vte.setFromDatapoint(fromDatapoint);
				vte.setToDatapoint(toDatapoint);
					
				// Only add VectorTableElements whose 'from' ordered index is less than the 'to' ordered index
				if (returnWResults || vte.getFromDatapoint().getOrderedIndex() < vte.getToDatapoint().getOrderedIndex())
				{
					// Find all dimensionValues for this VectorTableElement
					Vector<DimensionValue> dimensionValues = SiaDimensionValueFactory.getDimensionValuesForVectorTableElement(vte);
					vte.setDimensionValues(dimensionValues);
					vteList.add(vte);
				}
			}
		}

		vectorTable.setVteList(vteList);
		vectorTable.setNumDatapoints(datapoints.size());
		return vectorTable;
	}

	/**
	 * Java version of the two sparql construct queries
	 * <i>construct_sia(tec)_vector_table_bnodes.sparql</i> and 
	 * <i>construct_vector_table_details.sparql</i>
	 * for execution time comparison purposes.
	 * 
	 * @param ontModel
	 * @param addWResults
	 */
	public static void addToModel(OntModel ontModel, boolean addWResults) {
		// Replacement code for "construct_sia(tec)_vector_table_bnodes.sparql" start
		
		long startTime = System.currentTimeMillis();

		// (note - we could do this by working exclusively with our OntModel, or we could
		// create separate java objects (as we already have done with Datapoint, VectorTable etc.)
		// as a first attempt, we'll use OntModel in order to avoid too much data model duplication, 
		// but if performance is poor then we should try java objects
		
		// Find all instances of sia:OrderedSet
		OntModel vteTempOntModel = ModelFactory
				.createOntologyModel(); // OntModelSpec.OWL_MEM
		OntClass orderedSetClass = ontModel.getOntClass(OrderedSet.RESOURCE_URI);
		ExtendedIterator<? extends OntResource> orderedSetIter = orderedSetClass.listInstances();
		Property memberOfOrderedSetProperty = ontModel.getOntProperty(MemberOfOrderedSet.PROPERTY_URI);
		Property fromDatapointProperty = ontModel.getOntProperty(FromDatapoint.PROPERTY_URI);
		Property toDatapointProperty = ontModel.getOntProperty(ToDatapoint.PROPERTY_URI);
		Property orderedIndexProperty = ontModel.getOntProperty(OrderedIndex.PROPERTY_URI);
		Property dimensionValueProperty = ontModel.getOntProperty(DimensionValue.PROPERTY_URI);
		Property dimensionProperty = ontModel.getOntProperty(DimensionValue.DIMENSION_URI);
		Property valueProperty = ontModel.getOntProperty(DimensionValue.VALUE_URI);
		Resource vectorTableElementResource = ontModel.createResource(VectorTableElement.RESOURCE_URI);
		
		// For each sia:OrderedSet, find every sia:Datapoint (which has property sia:memberOfOrderedSet object sia:OrderedSet)
		// Make two copies of the list of sia:datapoints
		
		OntResource orderedSet;
		StmtIterator datapoint1StmtIter;
		StmtIterator datapoint2StmtIter;
		while (orderedSetIter.hasNext())
		{
			orderedSet = orderedSetIter.next();
			datapoint1StmtIter = ontModel.listStatements((Resource)null, memberOfOrderedSetProperty, orderedSet);

			// For every pair of sia:Datapoints datapoint1 and datapoint2 (one taken from each list), create a sia:VectorTableElement
			while (datapoint1StmtIter.hasNext())
			{
				Statement datapoint1Stmt = datapoint1StmtIter.next();
				datapoint2StmtIter = ontModel.listStatements((Resource)null, memberOfOrderedSetProperty, orderedSet);
				
				while (datapoint2StmtIter.hasNext())
				{
					// Assert that the sia:VectorTableElement has sia:fromDatapoint ?datapoint1 and sia:toDatapoint ?datapoint2
					// (in the case where we're creating the 'V' vector table (i.e. returnWResults == false), only make this assertion
					// if ((?datapoint1 != ?datapoint2) && (?i1 < ?i2)) where ?datapoint1 sia:orderedIndex ?i1 and ?datapoint2 sia:orderedIndex ?i2
					Statement datapoint2Stmt = datapoint2StmtIter.next();
					Resource fromDatapoint = datapoint1Stmt.getSubject();
					Resource toDatapoint = datapoint2Stmt.getSubject();
					
					Statement i1Stmt = ontModel.getProperty(fromDatapoint, orderedIndexProperty);
					Statement i2Stmt = ontModel.getProperty(toDatapoint, orderedIndexProperty);
					int i1 = i1Stmt.getInt();
					int i2 = i2Stmt.getInt();
										
					if (addWResults || i1 < i2)
					{
						Resource vteBnode = ontModel.createResource(AnonId.create());
						vteTempOntModel.add(vteBnode, RDF.type, vectorTableElementResource);
						vteTempOntModel.add(vteBnode, fromDatapointProperty, fromDatapoint);
						vteTempOntModel.add(vteBnode, toDatapointProperty, toDatapoint);					

						// Replacement code for "construct_sia(tec)_vector_table_bnodes.sparql" end

						// Replacement code for "construct_vector_table_details.sparql" start
						NodeIterator fromDimValIter = ontModel.listObjectsOfProperty(fromDatapoint, dimensionValueProperty);
						while (fromDimValIter.hasNext())
						{
							RDFNode fromDimValNode = fromDimValIter.next();
							Statement fromDimensionStmt = ontModel.getProperty(fromDimValNode.asResource(), dimensionProperty);
							Statement fromValueStmt = ontModel.getProperty(fromDimValNode.asResource(), valueProperty);
							
							int fromDimension = fromDimensionStmt.getInt();
							double fromValue = fromValueStmt.getDouble();
							
							NodeIterator toDimValIter = ontModel.listObjectsOfProperty(toDatapoint, dimensionValueProperty);
							while (toDimValIter.hasNext())
							{
								RDFNode toDimValNode = toDimValIter.next();
								Statement toDimensionStmt = ontModel.getProperty(toDimValNode.asResource(), dimensionProperty);
								
								int toDimension = toDimensionStmt.getInt();
								
								if (fromDimension == toDimension)
								{
									Statement toValueStmt = ontModel.getProperty(toDimValNode.asResource(), valueProperty);
									double toValue = toValueStmt.getDouble();
									double vteValue = toValue - fromValue;

									Resource dimValBnode = ontModel.createResource(AnonId.create());
									vteTempOntModel.add(vteBnode, dimensionValueProperty, dimValBnode);
									vteTempOntModel.addLiteral(dimValBnode, dimensionProperty, toDimension);
									vteTempOntModel.addLiteral(dimValBnode, valueProperty, vteValue);

									break;
								}
							}
						}												
					}					
				}
			}
		}
		
		ontModel.add(vteTempOntModel);
		long endTime = System.currentTimeMillis();
		long elapsedTime = endTime - startTime;
		System.out.println("Completed java replacement for all SPARQL CONSTRUCTs in " + elapsedTime + " ms");
		// Replacement code for "construct_vector_table_details.sparql" end
	}

	public static Datapoint findDatapoint(OntModel ontModel, List<Datapoint> datapoints, Resource resource) {
		Iterator<Datapoint> datapointsIter = datapoints.iterator();
		Datapoint datapoint;
		
		while (datapointsIter.hasNext())
		{
			datapoint = datapointsIter.next();
			
			if (datapoint.getResource().toString().equals(resource.toString()))
				return datapoint;
		}
		
		datapoint = new Datapoint();
		datapoint.setResource(resource);
		Vector<DimensionValue> dimensionValues = SiaDimensionValueFactory.getDimensionValuesForResource(ontModel, resource);
		datapoint.setDimensionValues(dimensionValues);
		return datapoint;
	}

	public static void assertOrder(OntModel ontModel, List<VectorTableElement> vteList) {
		
		Resource bnode = ontModel.createResource(AnonId.create());
		Resource siaOrderedSet = ontModel.createResource(OrderedSet.RESOURCE_URI);
		
		ontModel.add(bnode, RDF.type, siaOrderedSet);
		
		int numVectorTableElements = vteList.size();

		VectorTableElement vte;
		for (int orderedIndex = 0; orderedIndex < numVectorTableElements; orderedIndex++)
		{
			// Assert <bnode, rdf:type, sia:OrderedSet>
			vte = vteList.get(orderedIndex);
			Property memberOfOrderedSetProperty = ontModel.getProperty(MemberOfOrderedSet.PROPERTY_URI);
			ontModel.add(vte.getResource(), memberOfOrderedSetProperty, bnode);
			
			if (orderedIndex < numVectorTableElements - 1)
			{
				// Assert <nextVectorTable, sia:directlyFollows, currentVectorTableElement>
				VectorTableElement nextVte = vteList.get(orderedIndex + 1);
				Property directlyFollowsProperty = ontModel.getProperty(DirectlyFollows.PROPERTY_URI);
				ontModel.add(nextVte.getResource(), directlyFollowsProperty, vte.getResource());
			}
			
			// Assert <currentVectorTableElement, sia:orderedIndex, orderedIndex>
			Property orderedIndexProperty = ontModel.getProperty(OrderedIndex.PROPERTY_URI);
			ontModel.addLiteral(vte.getResource(), orderedIndexProperty, orderedIndex);
			
		}
		
	}

}