diff src/org/qmul/eecs/c4dm/sia/midi/MidiParser.java @ 71:39106212a3c6

modified to take into account that sia:Datapoints now have sia:vector properties which then have sia:dimVals, rather than sia:Datapoints having their own sia:dimVal properties added various RDF property and class definitions associates the whole dataset with a Dataset bnode ensures dimVals are unique
author stevenh
date Fri, 02 Aug 2013 15:11:23 +0100
parents fa9030705e93
children 4ef262740ceb
line wrap: on
line diff
--- a/src/org/qmul/eecs/c4dm/sia/midi/MidiParser.java	Fri Aug 02 15:01:59 2013 +0100
+++ b/src/org/qmul/eecs/c4dm/sia/midi/MidiParser.java	Fri Aug 02 15:11:23 2013 +0100
@@ -5,9 +5,7 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Vector;
 
@@ -24,23 +22,34 @@
 import org.qmul.eecs.c4dm.sia.SiaMain;
 import org.qmul.eecs.c4dm.sia.model.Datapoint;
 import org.qmul.eecs.c4dm.sia.model.DimensionValue;
+import org.qmul.eecs.c4dm.sia.model.MemberOfDataset;
+import org.qmul.eecs.c4dm.sia.model.SiaDataset;
+import org.qmul.eecs.c4dm.sia.model.SiaVector;
 import org.qmul.eecs.c4dm.sia.rdf.Namespaces;
 
+import com.hp.hpl.jena.datatypes.xsd.XSDDatatype;
+import com.hp.hpl.jena.graph.Node;
+import com.hp.hpl.jena.graph.Triple;
 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.query.Dataset;
+import com.hp.hpl.jena.query.Query;
+import com.hp.hpl.jena.query.QueryExecution;
+import com.hp.hpl.jena.query.QueryExecutionFactory;
+import com.hp.hpl.jena.query.QueryFactory;
+import com.hp.hpl.jena.query.QuerySolution;
 import com.hp.hpl.jena.query.ReadWrite;
+import com.hp.hpl.jena.query.ResultSet;
 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.sparql.core.Var;
+import com.hp.hpl.jena.sparql.syntax.ElementGroup;
+import com.hp.hpl.jena.sparql.syntax.ElementTriplesBlock;
 import com.hp.hpl.jena.tdb.TDBFactory;
-import com.hp.hpl.jena.util.iterator.ExtendedIterator;
 import com.hp.hpl.jena.vocabulary.RDF;
 import com.sun.media.sound.MidiUtils;
 
@@ -50,6 +59,15 @@
 	public static final int PITCH_DIMENSION = 2;
 	public static final int CHANNEL_DIMENSION = 3;
 
+	private static Property siaDimValProperty;
+	private static Property siaDimensionProperty;
+	private static Property siaValueProperty;
+	private static Property siaMemberOfDatasetProperty;
+	private static OntClass datapointClass;
+	private static OntClass datasetClass;
+	private static OntClass siaVectorClass;
+	private static Property siaVectorProperty;
+	
 	// The ontology loaded as dataset
 	private static final String ontology = "file:src/rdf/siaDatapointOntology.n3";
 
@@ -62,18 +80,23 @@
 	public static void main(String[] args)
 	{
 		// First create a Jena ontology model
-		OntModel ontModel = ModelFactory
+		OntModel model = ModelFactory
 				.createOntologyModel(); // OntModelSpec.OWL_MEM
 
 		// Then read the data from the file into the ontology model
-		ontModel.read(ontology, "N3");
+		model.read(ontology, "N3");
 		
-		OntClass datapointClass = ontModel.getOntClass(Datapoint.RESOURCE_URI);
-		Resource datapointResource = ontModel.getOntResource(datapointClass);
-		Property siaDimValProperty = ontModel.createProperty(DimensionValue.PROPERTY_URI);
-		Property siaDimensionProperty = ontModel.createProperty(DimensionValue.DIMENSION_URI);
-		Property siaValueProperty = ontModel.createProperty(DimensionValue.VALUE_URI);
-
+		datapointClass = model.getOntClass(Datapoint.RESOURCE_URI);
+		datasetClass = model.getOntClass(SiaDataset.RESOURCE_URI);
+		siaVectorClass = model.getOntClass(SiaVector.RESOURCE_URI);
+		Resource datapointResource = model.getOntResource(datapointClass);
+		Resource datasetResource = model.getOntResource(datasetClass);
+		siaDimValProperty = model.createProperty(DimensionValue.PROPERTY_URI);
+		siaDimensionProperty = model.createProperty(DimensionValue.DIMENSION_URI);
+		siaValueProperty = model.createProperty(DimensionValue.VALUE_URI);
+		siaMemberOfDatasetProperty = model.createProperty(MemberOfDataset.PROPERTY_URI);
+		siaVectorProperty = model.createProperty(SiaVector.PROPERTY_URI);
+		
 		File midiFile1 = new File(midiFileName);
 	
 		Sequence sequence = null;
@@ -106,6 +129,10 @@
 			}
 		}
 		
+		// Add a dataset, represented by a blank node, to the model
+		Resource datasetBnode = model.createResource(AnonId.create());
+		model.add(datasetBnode, RDF.type, datasetResource);
+		
 		long maxTick = 0;
 				
 		for (int trackIdx = 0; trackIdx < numTracks; trackIdx++)
@@ -208,24 +235,25 @@
 						datapoints.add(datapoint);
 						
 						// RDF
-						Resource datapointBnode = ontModel.createResource(AnonId.create());
-						ontModel.add(datapointBnode, RDF.type, datapointResource);
+						
+						Resource datapointBnode = model.createResource(AnonId.create());
+						model.add(datapointBnode, RDF.type, datapointResource);
 
-						Resource timeDimValBnode = ontModel.createResource(AnonId.create());
-						Resource pitchDimValBnode = ontModel.createResource(AnonId.create());
-						Resource channelDimValBnode = ontModel.createResource(AnonId.create());
-
-						ontModel.add(datapointBnode, siaDimValProperty, timeDimValBnode);
-						ontModel.addLiteral(timeDimValBnode, siaDimensionProperty, TIME_DIMENSION);
-						ontModel.addLiteral(timeDimValBnode, siaValueProperty, secs);
-
-						ontModel.add(datapointBnode, siaDimValProperty, pitchDimValBnode);
-						ontModel.addLiteral(pitchDimValBnode, siaDimensionProperty, PITCH_DIMENSION);
-						ontModel.addLiteral(pitchDimValBnode, siaValueProperty, data1);
-
-						ontModel.add(datapointBnode, siaDimValProperty, channelDimValBnode);
-						ontModel.addLiteral(channelDimValBnode, siaDimensionProperty, CHANNEL_DIMENSION);
-						ontModel.addLiteral(channelDimValBnode, siaValueProperty, trackDimensionMap.get(trackIdx).intValue());
+						// Find or create a DimVal for the TIME dimension
+						Resource timeDimValBnode = findOrCreateDimValBNode(model, TIME_DIMENSION, secs);
+						
+						// Find or create a DimVal for the PITCH dimension
+						Resource pitchDimValBnode = findOrCreateDimValBNode(model, PITCH_DIMENSION, data1);
+						
+						// Find or create a DimVal for the CHANNEL dimension
+						Resource channelDimValBnode = findOrCreateDimValBNode(model, CHANNEL_DIMENSION, trackDimensionMap.get(trackIdx));
+						
+						// Find or create a Vector for these three DimVals
+						Resource vectorBnode = findOrCreateVectorBNode(model, timeDimValBnode, secs,
+								pitchDimValBnode, data1, channelDimValBnode, trackDimensionMap.get(trackIdx));
+												
+						model.add(datapointBnode, siaVectorProperty, vectorBnode);
+						model.add(datapointBnode, siaMemberOfDatasetProperty, datasetBnode);
 
 					}
 					else if (messageCommand == ShortMessage.PITCH_BEND)
@@ -307,7 +335,7 @@
 	    	    
 		// Print out what we've got now
 		System.out.println("------------------");
-		StmtIterator stmtIterator = ontModel.listStatements();
+		StmtIterator stmtIterator = model.listStatements();
 		printStmts(stmtIterator);
 
 		// TODO write rdf to file
@@ -319,7 +347,7 @@
 		// RDF/XML version
 		try {
 			outFileOutputStreamRdf = new FileOutputStream(outFileRdf);
-			ontModel.writeAll(outFileOutputStreamRdf, "RDF/XML", null);
+			model.writeAll(outFileOutputStreamRdf, "RDF/XML", null);
 		} catch (FileNotFoundException e) {
 			System.out.println("Unable to write to file: "
 					+ outFileRdf.getAbsolutePath());
@@ -337,7 +365,7 @@
 		// N3 version
 		try {
 			outFileOutputStreamN3 = new FileOutputStream(outFileN3);
-			ontModel.writeAll(outFileOutputStreamN3, "N3", null);
+			model.writeAll(outFileOutputStreamN3, "N3", null);
 		} catch (FileNotFoundException e) {
 			System.out.println("Unable to write to file: "
 					+ outFileN3.getAbsolutePath());
@@ -359,7 +387,7 @@
 		Dataset dataset = TDBFactory.assembleDataset(SiaMain.assemblerFile);
         dataset.begin(ReadWrite.WRITE) ;
         try {
-        	dataset.replaceNamedModel(SiaMain.graph, ontModel);
+        	dataset.replaceNamedModel(SiaMain.graph, model);
         	dataset.commit();
         	System.out.println("dataset.commit() done");
         } finally {
@@ -374,6 +402,120 @@
 		
 	}
 
+	private static Resource findOrCreateVectorBNode(OntModel model, Resource timeDimValBnode,
+			double timeVal, Resource pitchDimValBnode, double pitchVal, Resource channelDimValBnode,
+			double channelVal) {
+
+		Resource bnode;
+
+		String vectorVarStr = "vector";
+		String dimVal1VarStr = "dimVal1";
+		String dimVal2VarStr = "dimVal2";
+		String dimVal3VarStr = "dimVal3";
+		
+		Var vectorVar = Var.alloc(vectorVarStr);
+		Var dimVal1Var = Var.alloc(dimVal1VarStr);
+		Var dimVal2Var = Var.alloc(dimVal2VarStr);
+		Var dimVal3Var = Var.alloc(dimVal3VarStr);
+
+		Node timeDimensionLiteralNode = Node.createUncachedLiteral(TIME_DIMENSION, XSDDatatype.XSDinteger);
+		Node timeValueLiteralNode = Node.createUncachedLiteral(timeVal, XSDDatatype.XSDdouble);
+		Node pitchDimensionLiteralNode = Node.createUncachedLiteral(PITCH_DIMENSION, XSDDatatype.XSDinteger);
+		Node pitchValueLiteralNode = Node.createUncachedLiteral(pitchVal, XSDDatatype.XSDdouble);
+		Node channelDimensionLiteralNode = Node.createUncachedLiteral(CHANNEL_DIMENSION, XSDDatatype.XSDinteger);
+		Node channelValueLiteralNode = Node.createUncachedLiteral(channelVal, XSDDatatype.XSDdouble);
+
+		Query query = QueryFactory.make();
+		query.setPrefix("sia", Namespaces.SIA_NS_URI);
+		query.setQuerySelectType();
+		query.setDistinct(true);
+		query.addResultVar(vectorVar);
+
+		ElementTriplesBlock etp = new ElementTriplesBlock();
+
+		Triple vectorTriple = new Triple(vectorVar, RDF.type.asNode(), siaVectorClass.asNode());
+		Triple dimVal1Triple = new Triple(vectorVar, siaDimValProperty.asNode(), dimVal1Var);
+
+		Triple dimVal1DimTriple = new Triple(dimVal1Var, siaDimensionProperty.asNode(), timeDimensionLiteralNode);
+		Triple dimVal1ValTriple = new Triple(dimVal1Var, siaValueProperty.asNode(), timeValueLiteralNode);
+		Triple dimVal2Triple = new Triple(vectorVar, siaDimValProperty.asNode(), dimVal2Var);
+		Triple dimVal2DimTriple = new Triple(dimVal2Var, siaDimensionProperty.asNode(), pitchDimensionLiteralNode);
+		Triple dimVal2ValTriple = new Triple(dimVal2Var, siaValueProperty.asNode(), pitchValueLiteralNode);
+		Triple dimVal3Triple = new Triple(vectorVar, siaDimValProperty.asNode(), dimVal3Var);
+		Triple dimVal3DimTriple = new Triple(dimVal3Var, siaDimensionProperty.asNode(), channelDimensionLiteralNode);
+		Triple dimVal3ValTriple = new Triple(dimVal3Var, siaValueProperty.asNode(), channelValueLiteralNode);
+		
+		etp.addTriple(vectorTriple);
+		etp.addTriple(dimVal1Triple);
+		etp.addTriple(dimVal1DimTriple);
+		etp.addTriple(dimVal1ValTriple);
+		etp.addTriple(dimVal2Triple);
+		etp.addTriple(dimVal2DimTriple);
+		etp.addTriple(dimVal2ValTriple);
+		etp.addTriple(dimVal3Triple);
+		etp.addTriple(dimVal3DimTriple);
+		etp.addTriple(dimVal3ValTriple);
+				
+		ElementGroup body = new ElementGroup();
+		body.addElement(etp);
+		query.setQueryPattern(body);
+				
+		QueryExecution qe = QueryExecutionFactory.create(query, model);
+		ResultSet rs = qe.execSelect();
+		
+		if (rs.hasNext())
+		{
+			QuerySolution querySolution = rs.next();
+			bnode = querySolution.get(vectorVarStr).asResource();
+		}
+		else
+		{
+			bnode = model.createResource(AnonId.create());							
+			model.add(bnode, RDF.type, siaVectorClass);
+			model.add(bnode, siaDimValProperty, timeDimValBnode);
+			model.add(bnode, siaDimValProperty, pitchDimValBnode);
+			model.add(bnode, siaDimValProperty, channelDimValBnode);
+		}
+		return bnode;
+	}
+
+	private static Resource findOrCreateDimValBNode(OntModel model, int dimension, double value) {
+		Resource bnode;
+
+		String dimValVarStr = "dimVal";
+		Var dimValVar = Var.alloc(dimValVarStr);
+		Query query = QueryFactory.make();
+		query.setPrefix("sia", Namespaces.SIA_NS_URI);
+		query.setQuerySelectType();
+		query.setDistinct(true);
+		query.addResultVar(dimValVar);
+		ElementTriplesBlock etp = new ElementTriplesBlock();
+		Node dimensionLiteralNode = Node.createUncachedLiteral(dimension, XSDDatatype.XSDinteger);
+		Node valueLiteralNode = Node.createUncachedLiteral(value, XSDDatatype.XSDdouble);
+		
+		Triple dimensionTriple = new Triple(dimValVar, siaDimensionProperty.asNode(), dimensionLiteralNode);
+		Triple valueTriple = new Triple(dimValVar, siaValueProperty.asNode(), valueLiteralNode);
+		etp.addTriple(dimensionTriple);
+		etp.addTriple(valueTriple);
+		query.setQueryPattern(etp);
+		
+		QueryExecution qe = QueryExecutionFactory.create(query, model);
+		ResultSet rs = qe.execSelect();
+		
+		if (rs.hasNext())
+		{
+			QuerySolution querySolution = rs.next();
+			bnode = querySolution.get(dimValVarStr).asResource();
+		}
+		else
+		{
+			bnode = model.createResource(AnonId.create());							
+			model.addLiteral(bnode, siaDimensionProperty, dimension);
+			model.addLiteral(bnode, siaValueProperty, value);
+		}
+		return bnode;
+	}
+
 	private static HashMap<Integer, Integer> getTrackToDimensionIndexMap(Sequence sequence) {
 		
 		int numTracks = sequence.getTracks().length;