stevenh@14
|
1 package org.qmul.eecs.c4dm.sia;
|
stevenh@14
|
2
|
stevenh@14
|
3 import java.io.File;
|
stevenh@14
|
4 import java.io.FileNotFoundException;
|
stevenh@14
|
5 import java.io.FileOutputStream;
|
stevenh@14
|
6 import java.util.ArrayList;
|
stevenh@14
|
7 import java.util.Collections;
|
stevenh@14
|
8 import java.util.List;
|
stevenh@14
|
9
|
stevenh@14
|
10 import org.mindswap.pellet.jena.PelletReasonerFactory;
|
stevenh@14
|
11 import org.qmul.eecs.c4dm.sia.exceptions.DimensionException;
|
stevenh@14
|
12 import org.qmul.eecs.c4dm.sia.model.Datapoint;
|
stevenh@14
|
13 import org.qmul.eecs.c4dm.sia.model.NDimensionalObject;
|
stevenh@14
|
14 import org.qmul.eecs.c4dm.sia.model.SiatecX;
|
stevenh@14
|
15 import org.qmul.eecs.c4dm.sia.model.VectorTable;
|
stevenh@14
|
16 import org.qmul.eecs.c4dm.sia.model.VectorTableElement;
|
stevenh@14
|
17 import org.qmul.eecs.c4dm.sia.rdf.Namespaces;
|
stevenh@14
|
18 import org.qmul.eecs.c4dm.sia.utilities.Display;
|
stevenh@14
|
19 import org.qmul.eecs.c4dm.sparql.utilities.SparqlWrapperMethods;
|
stevenh@14
|
20
|
stevenh@14
|
21 import com.hp.hpl.jena.ontology.OntModel;
|
stevenh@14
|
22 import com.hp.hpl.jena.rdf.model.Model;
|
stevenh@14
|
23 import com.hp.hpl.jena.rdf.model.ModelFactory;
|
stevenh@14
|
24
|
stevenh@14
|
25 /**
|
stevenh@14
|
26 * <p>
|
stevenh@14
|
27 * Title: SiaTecMain
|
stevenh@14
|
28 * </p>
|
stevenh@14
|
29 * <p>
|
stevenh@14
|
30 * Description: An RDF/OWL/Java implementation of the SIATEC pattern discovery algorithm.
|
stevenh@14
|
31 * See "Algorithms for discovering repeated patterns in multidimensional representations of polyphonic music"
|
stevenh@14
|
32 * by Meredith, D. and Lemström, K. and Wiggins, G.A.
|
stevenh@14
|
33 * </p>
|
stevenh@14
|
34 *
|
stevenh@14
|
35 * @author Steve Hargreaves, C4DM, Queen Mary University of London
|
stevenh@14
|
36 */
|
stevenh@14
|
37 public class SiaTecMain {
|
stevenh@14
|
38
|
stevenh@14
|
39 // The ontology loaded as dataset
|
stevenh@14
|
40 private static final String ontology = "file:src/rdf/siaDatapointOntology.n3";
|
stevenh@14
|
41
|
stevenh@14
|
42 // The final output file
|
stevenh@14
|
43 private static final String finalModelFileName = "src/rdf/finalSiaTecModel";
|
stevenh@14
|
44
|
stevenh@14
|
45 // SPARQL queries
|
stevenh@14
|
46 private static final String[] selectQueries = new String[] {
|
stevenh@14
|
47 // A SPARQL-DL query
|
stevenh@14
|
48 "file:src/sparql/select_all.sparql"
|
stevenh@14
|
49 };
|
stevenh@14
|
50
|
stevenh@14
|
51 // CONSTRUCT queries
|
stevenh@14
|
52 private static final String[] constructQueries = new String[] {
|
stevenh@14
|
53 // SPARQL-DL CONSTRUCT queries
|
stevenh@14
|
54 "file:src/sparql/construct_siatec_vector_table_bnodes.sparql",
|
stevenh@14
|
55 "file:src/sparql/construct_vector_table_details.sparql" };
|
stevenh@14
|
56
|
stevenh@14
|
57 // ASK queries
|
stevenh@14
|
58 private static final String[] askQueries = new String[] {
|
stevenh@14
|
59 // A SPARQL-DL ASK query
|
stevenh@14
|
60 };
|
stevenh@14
|
61
|
stevenh@14
|
62 public void run() {
|
stevenh@14
|
63
|
stevenh@14
|
64 // First create a Jena ontology model backed by the Pellet reasoner
|
stevenh@14
|
65 // (note, the Pellet reasoner is required)
|
stevenh@14
|
66 OntModel ontModel = ModelFactory
|
stevenh@14
|
67 .createOntologyModel(PelletReasonerFactory.THE_SPEC);
|
stevenh@14
|
68
|
stevenh@14
|
69 // Then read the data from the file into the ontology model
|
stevenh@14
|
70 ontModel.read(ontology, "N3");
|
stevenh@14
|
71
|
stevenh@14
|
72 // Set the value of SIA_NS_URI as the namespace for 'sia' found in
|
stevenh@14
|
73 // the ontology
|
stevenh@14
|
74 Namespaces.SIA_NS_URI = ontModel.getNsPrefixURI("sia");
|
stevenh@14
|
75
|
stevenh@14
|
76 // Create custom sia Datapoint objects
|
stevenh@14
|
77 List<Datapoint> datapoints = SiaDatapointFactory.create(ontModel);
|
stevenh@14
|
78
|
stevenh@14
|
79 // STEP 1 - Order the datapoints
|
stevenh@14
|
80 Collections.sort(datapoints);
|
stevenh@14
|
81
|
stevenh@14
|
82 // Add datapoint order info to model
|
stevenh@14
|
83 SiaDatapointFactory.assertOrder(ontModel, datapoints);
|
stevenh@14
|
84
|
stevenh@14
|
85 // STEP 2 - Compute the vector table W, and sort
|
stevenh@14
|
86 // Run all the CONSTRUCT queries
|
stevenh@14
|
87 for (int i = 0; i < constructQueries.length; i++) {
|
stevenh@14
|
88 String constructQuery = constructQueries[i];
|
stevenh@14
|
89
|
stevenh@14
|
90 Model newModel = SparqlWrapperMethods.executeConstructQuery(constructQuery, ontModel);
|
stevenh@14
|
91
|
stevenh@14
|
92 // Add new triples to the current model
|
stevenh@14
|
93 ontModel.add(newModel);
|
stevenh@14
|
94 }
|
stevenh@14
|
95 VectorTable vectorTableW = SiaVectorTableElementFactory.createW(ontModel, datapoints);
|
stevenh@14
|
96
|
stevenh@14
|
97 // STEP 3 - Create custom SIATEC VectorTableElement objects (V)
|
stevenh@14
|
98 VectorTable vectorTableV = SiaVectorTableElementFactory.createV(ontModel, datapoints);
|
stevenh@14
|
99 List<VectorTableElement> vteListV = vectorTableV.getVteList();
|
stevenh@14
|
100
|
stevenh@14
|
101 // STEP 4 - Sort V
|
stevenh@14
|
102 Collections.sort(vteListV);
|
stevenh@14
|
103
|
stevenh@14
|
104 // Add vector table element order info to model
|
stevenh@14
|
105 SiaVectorTableElementFactory.assertOrder(ontModel, vteListV);
|
stevenh@14
|
106
|
stevenh@14
|
107 // STEP 5 - "Vectorize" the MTPs
|
stevenh@14
|
108 int m = vteListV.size();
|
stevenh@14
|
109 int i = 0;
|
stevenh@14
|
110 ArrayList<SiatecX> x = new ArrayList<SiatecX>();
|
stevenh@14
|
111
|
stevenh@14
|
112 while (i < m)
|
stevenh@14
|
113 {
|
stevenh@14
|
114 ArrayList<NDimensionalObject> q = new ArrayList<NDimensionalObject>();
|
stevenh@14
|
115 int j = i + 1;
|
stevenh@14
|
116 while (j < m && (vteListV.get(i).compareToIgnoreDatapoints(vteListV.get(j)) == 0))
|
stevenh@14
|
117 {
|
stevenh@14
|
118 NDimensionalObject vector = vteListV.get(j).getFromDatapoint().subtract(vteListV.get(j - 1).getFromDatapoint());
|
stevenh@14
|
119 q.add(vector);
|
stevenh@14
|
120 j++;
|
stevenh@14
|
121 }
|
stevenh@14
|
122
|
stevenh@14
|
123 SiatecX iq = new SiatecX();
|
stevenh@14
|
124 iq.setI(i+1);
|
stevenh@14
|
125 iq.setQ(q);
|
stevenh@14
|
126 x.add(iq);
|
stevenh@14
|
127 i = j;
|
stevenh@14
|
128 }
|
stevenh@14
|
129
|
stevenh@14
|
130 System.out.println("X");
|
stevenh@14
|
131 printX(x);
|
stevenh@14
|
132
|
stevenh@14
|
133 // Sort the elements of x
|
stevenh@14
|
134 Collections.sort(x);
|
stevenh@14
|
135
|
stevenh@14
|
136 // Rename as y to match algorithm description in paper
|
stevenh@14
|
137 ArrayList<SiatecX> y = (ArrayList<SiatecX>) x.clone();
|
stevenh@14
|
138
|
stevenh@14
|
139 System.out.println("\nY = Sorted X");
|
stevenh@14
|
140 printX(y);
|
stevenh@14
|
141
|
stevenh@14
|
142 // Display results using algorithm figures 23, 24 and 25 of the research paper
|
stevenh@14
|
143 int r = y.size();
|
stevenh@14
|
144 m = vteListV.size();
|
stevenh@14
|
145 i = 0; // *** check indexing
|
stevenh@14
|
146 System.out.println();
|
stevenh@14
|
147 System.out.print("{");
|
stevenh@14
|
148 if (r > 0) // *** check indexing
|
stevenh@14
|
149 {
|
stevenh@14
|
150 do
|
stevenh@14
|
151 {
|
stevenh@14
|
152 int j = y.get(i).getI() - 1; // *** check indexing
|
stevenh@14
|
153 List<Integer> iList = new ArrayList<Integer>();
|
stevenh@14
|
154 while (j < m && (vteListV.get(j).getVector().compareTo(vteListV.get(y.get(i).getI() - 1).getVector()) == 0)) // *** check indexing
|
stevenh@14
|
155 {
|
stevenh@14
|
156 // // debug start
|
stevenh@14
|
157 // for (int hundip = 0; hundip < vteList.size(); hundip++)
|
stevenh@14
|
158 // {
|
stevenh@14
|
159 // System.out.println("v[" + hundip + ",2] = " + vteList.get(hundip).getFromDatapoint().getOrderedIndex());
|
stevenh@14
|
160 // }
|
stevenh@14
|
161 // // debug start
|
stevenh@14
|
162
|
stevenh@14
|
163 iList.add(vteListV.get(j).getFromDatapoint().getOrderedIndex());
|
stevenh@14
|
164 j++;
|
stevenh@14
|
165 }
|
stevenh@14
|
166 System.out.print("<");
|
stevenh@14
|
167 Display.printPattern(iList, datapoints);
|
stevenh@14
|
168 System.out.print(",");
|
stevenh@14
|
169 printSetOfTranslators(iList, datapoints, vectorTableW);
|
stevenh@14
|
170 System.out.print(">");
|
stevenh@14
|
171 do
|
stevenh@14
|
172 {
|
stevenh@14
|
173 i++;
|
stevenh@14
|
174 } while (i < r && (y.get(i).compareToIgnoreI(y.get(i - 1)) == 0)); // *** check indexing
|
stevenh@14
|
175
|
stevenh@14
|
176 if (i < r) // *** check indexing
|
stevenh@14
|
177 {
|
stevenh@14
|
178 System.out.print(",");
|
stevenh@14
|
179 System.out.println();
|
stevenh@14
|
180 }
|
stevenh@14
|
181 } while (i < r); // *** check indexing
|
stevenh@14
|
182 }
|
stevenh@14
|
183 System.out.println("}");
|
stevenh@14
|
184
|
stevenh@14
|
185 // Run all the SELECT queries
|
stevenh@14
|
186 for (i = 0; i < selectQueries.length; i++) {
|
stevenh@14
|
187
|
stevenh@14
|
188 String selectQuery = selectQueries[i];
|
stevenh@14
|
189 SparqlWrapperMethods.queryTheModel(selectQuery, ontModel);
|
stevenh@14
|
190
|
stevenh@14
|
191 }
|
stevenh@14
|
192
|
stevenh@14
|
193 // Run all the ASK queries
|
stevenh@14
|
194 for (i = 0; i < askQueries.length; i++) {
|
stevenh@14
|
195
|
stevenh@14
|
196 String askQuery = askQueries[i];
|
stevenh@14
|
197 SparqlWrapperMethods.askTheModel(askQuery, ontModel);
|
stevenh@14
|
198
|
stevenh@14
|
199 }
|
stevenh@14
|
200
|
stevenh@14
|
201 // Write the model to a file
|
stevenh@14
|
202 File outFileRdf = new File(finalModelFileName + ".rdf");
|
stevenh@14
|
203 File outFileN3 = new File(finalModelFileName + ".n3");
|
stevenh@14
|
204 FileOutputStream outFileOutputStreamRdf;
|
stevenh@14
|
205 FileOutputStream outFileOutputStreamN3;
|
stevenh@14
|
206
|
stevenh@14
|
207 // RDF/XML version
|
stevenh@14
|
208 try {
|
stevenh@14
|
209 outFileOutputStreamRdf = new FileOutputStream(outFileRdf);
|
stevenh@14
|
210 ontModel.writeAll(outFileOutputStreamRdf, "RDF/XML", null);
|
stevenh@14
|
211 } catch (FileNotFoundException e) {
|
stevenh@14
|
212 System.out.println("Unable to write to file: "
|
stevenh@14
|
213 + outFileRdf.getAbsolutePath());
|
stevenh@14
|
214 e.printStackTrace();
|
stevenh@14
|
215 System.exit(1);
|
stevenh@14
|
216 }
|
stevenh@14
|
217
|
stevenh@14
|
218 // N3 version
|
stevenh@14
|
219 try {
|
stevenh@14
|
220 outFileOutputStreamN3 = new FileOutputStream(outFileN3);
|
stevenh@14
|
221 ontModel.writeAll(outFileOutputStreamN3, "N3", null);
|
stevenh@14
|
222 } catch (FileNotFoundException e) {
|
stevenh@14
|
223 System.out.println("Unable to write to file: "
|
stevenh@14
|
224 + outFileN3.getAbsolutePath());
|
stevenh@14
|
225 e.printStackTrace();
|
stevenh@14
|
226 System.exit(1);
|
stevenh@14
|
227 }
|
stevenh@14
|
228
|
stevenh@14
|
229 System.out.println("Model written to files: "
|
stevenh@14
|
230 + outFileRdf.getAbsolutePath() + " and " + outFileN3.getAbsolutePath());
|
stevenh@14
|
231 }
|
stevenh@14
|
232
|
stevenh@14
|
233 private void printSetOfTranslators(List<Integer> iList, List<Datapoint> datapoints, VectorTable vectorTableW) {
|
stevenh@14
|
234 int p = iList.size();
|
stevenh@14
|
235 int n = datapoints.size();
|
stevenh@14
|
236
|
stevenh@14
|
237 if (p == 1)
|
stevenh@14
|
238 {
|
stevenh@14
|
239 // // debug start
|
stevenh@14
|
240 // for (int f = 0; f < vectorTableW.size(); f++)
|
stevenh@14
|
241 // {
|
stevenh@14
|
242 // try {
|
stevenh@14
|
243 // System.out.println("W[" + f + "] = <<" + vectorTableW.getVteList().get(f).getDimensionValue(1) + "," + vectorTableW.getVteList().get(f).getDimensionValue(2) + ">," + vectorTableW.getVteList().get(f).getFromDatapoint().getOrderedIndex() + ">");
|
stevenh@14
|
244 // } catch (DimensionException e) {
|
stevenh@14
|
245 // // TODO Auto-generated catch block
|
stevenh@14
|
246 // e.printStackTrace();
|
stevenh@14
|
247 // }
|
stevenh@14
|
248 // }
|
stevenh@14
|
249 // // debug end
|
stevenh@14
|
250 System.out.print("{");
|
stevenh@14
|
251 Display.printVector(vectorTableW.getVector(iList.get(0), 1));
|
stevenh@14
|
252 for (int k = 2; k <= n; k++)
|
stevenh@14
|
253 {
|
stevenh@14
|
254 System.out.print(",");
|
stevenh@14
|
255 Display.printVector(vectorTableW.getVector(iList.get(0), k));
|
stevenh@14
|
256 }
|
stevenh@14
|
257 System.out.print("}");
|
stevenh@14
|
258 }
|
stevenh@14
|
259 else
|
stevenh@14
|
260 {
|
stevenh@14
|
261 System.out.print("{");
|
stevenh@14
|
262 List<Integer> jList = new ArrayList<Integer>();
|
stevenh@14
|
263 for (int k = 0; k < p; k++)
|
stevenh@14
|
264 {
|
stevenh@14
|
265 jList.add(1);
|
stevenh@14
|
266 }
|
stevenh@14
|
267 boolean finished = false;
|
stevenh@14
|
268 boolean first_vector = true;
|
stevenh@14
|
269 int k = 1;
|
stevenh@14
|
270
|
stevenh@14
|
271 while (!finished)
|
stevenh@14
|
272 {
|
stevenh@14
|
273 if (jList.get(k) <= jList.get(k - 1))
|
stevenh@14
|
274 {
|
stevenh@14
|
275 jList.set(k, jList.get(k - 1) + 1);
|
stevenh@14
|
276 }
|
stevenh@14
|
277
|
stevenh@14
|
278 while (jList.get(k) <= (n - p + k + 1)
|
stevenh@14
|
279 && (vectorTableW.getVector(iList.get(k), jList.get(k)).compareTo(vectorTableW.getVector(iList.get(k - 1), jList.get(k - 1))) < 0))
|
stevenh@14
|
280 {
|
stevenh@14
|
281 jList.set(k, jList.get(k) + 1);
|
stevenh@14
|
282 }
|
stevenh@14
|
283
|
stevenh@14
|
284 if (jList.get(k) > n - p + k + 1)
|
stevenh@14
|
285 {
|
stevenh@14
|
286 finished = true;
|
stevenh@14
|
287 }
|
stevenh@14
|
288 else if (vectorTableW.getVector(iList.get(k), jList.get(k)).compareTo(vectorTableW.getVector(iList.get(k - 1), jList.get(k - 1))) > 0)
|
stevenh@14
|
289 {
|
stevenh@14
|
290 k = 1;
|
stevenh@14
|
291 jList.set(0, jList.get(0) + 1);
|
stevenh@14
|
292 if (jList.get(0) > n - p + 1)
|
stevenh@14
|
293 {
|
stevenh@14
|
294 finished = true;
|
stevenh@14
|
295 }
|
stevenh@14
|
296 }
|
stevenh@14
|
297 else if (k + 1 == p)
|
stevenh@14
|
298 {
|
stevenh@14
|
299 if (!first_vector)
|
stevenh@14
|
300 {
|
stevenh@14
|
301 System.out.print(",");
|
stevenh@14
|
302 }
|
stevenh@14
|
303 else
|
stevenh@14
|
304 {
|
stevenh@14
|
305 first_vector = false;
|
stevenh@14
|
306 }
|
stevenh@14
|
307
|
stevenh@14
|
308 Display.printVector(vectorTableW.getVector(iList.get(k), jList.get(k)));
|
stevenh@14
|
309 k = 0;
|
stevenh@14
|
310
|
stevenh@14
|
311 while (k < p)
|
stevenh@14
|
312 {
|
stevenh@14
|
313 jList.set(k, jList.get(k) + 1);
|
stevenh@14
|
314 if (jList.get(k) > n - p + k +1)
|
stevenh@14
|
315 {
|
stevenh@14
|
316 finished = true;
|
stevenh@14
|
317 k = p -1;
|
stevenh@14
|
318 }
|
stevenh@14
|
319 k++;
|
stevenh@14
|
320 }
|
stevenh@14
|
321 k = 1;
|
stevenh@14
|
322 }
|
stevenh@14
|
323 else
|
stevenh@14
|
324 {
|
stevenh@14
|
325 k++;
|
stevenh@14
|
326 }
|
stevenh@14
|
327 }
|
stevenh@14
|
328 System.out.print("}");
|
stevenh@14
|
329 }
|
stevenh@14
|
330 }
|
stevenh@14
|
331
|
stevenh@14
|
332 private void printX(ArrayList<SiatecX> x) {
|
stevenh@14
|
333 for (SiatecX iq : x)
|
stevenh@14
|
334 {
|
stevenh@14
|
335 System.out.print(iq.getI() + ",");
|
stevenh@14
|
336 for (NDimensionalObject q : iq.getQ())
|
stevenh@14
|
337 {
|
stevenh@14
|
338 System.out.print("<");
|
stevenh@14
|
339 int dimensions = q.getDimensionValues().size();
|
stevenh@14
|
340 for (int dim = 1; dim <= dimensions; dim++)
|
stevenh@14
|
341 {
|
stevenh@14
|
342 try {
|
stevenh@14
|
343 System.out.print(q.getDimensionValue(dim) + (dim == dimensions ? "" : ","));
|
stevenh@14
|
344 } catch (DimensionException e) {
|
stevenh@14
|
345 e.printStackTrace();
|
stevenh@14
|
346 System.exit(1);
|
stevenh@14
|
347 }
|
stevenh@14
|
348 }
|
stevenh@14
|
349 System.out.println(">");
|
stevenh@14
|
350 }
|
stevenh@14
|
351 System.out.println();
|
stevenh@14
|
352 }
|
stevenh@14
|
353 }
|
stevenh@14
|
354
|
stevenh@14
|
355 /**
|
stevenh@14
|
356 * @param args
|
stevenh@14
|
357 */
|
stevenh@14
|
358 public static void main(String[] args) {
|
stevenh@14
|
359 SiaTecMain app = new SiaTecMain();
|
stevenh@14
|
360 app.run();
|
stevenh@14
|
361 }
|
stevenh@14
|
362
|
stevenh@14
|
363 }
|