annotate rdf/RDFImporter.cpp @ 616:3a61a4df6d53

* RDF importer: Features that are on different timeline URIs should go into separate models (_not_ just on separate signal URIs as there may not be any meaningful signal URIs) * FileSource: if a file is not found, try again assuming its name is encoded (not just in tolerant mode)
author Chris Cannam
date Thu, 15 Oct 2009 10:50:43 +0000
parents a03aafaacb5a
children 24f06d34ac99
rev   line source
Chris@439 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@439 2
Chris@439 3 /*
Chris@439 4 Sonic Visualiser
Chris@439 5 An audio file viewer and annotation editor.
Chris@439 6 Centre for Digital Music, Queen Mary, University of London.
Chris@439 7 This file copyright 2008 QMUL.
Chris@439 8
Chris@439 9 This program is free software; you can redistribute it and/or
Chris@439 10 modify it under the terms of the GNU General Public License as
Chris@439 11 published by the Free Software Foundation; either version 2 of the
Chris@439 12 License, or (at your option) any later version. See the file
Chris@439 13 COPYING included with this distribution for more information.
Chris@439 14 */
Chris@439 15
Chris@439 16 #include "RDFImporter.h"
Chris@439 17
Chris@439 18 #include <map>
Chris@439 19 #include <vector>
Chris@439 20
Chris@439 21 #include <iostream>
Chris@439 22 #include <cmath>
Chris@439 23
Chris@439 24 #include "SimpleSPARQLQuery.h"
Chris@439 25
Chris@439 26 #include "base/ProgressReporter.h"
Chris@439 27 #include "base/RealTime.h"
Chris@439 28
Chris@439 29 #include "data/model/SparseOneDimensionalModel.h"
Chris@439 30 #include "data/model/SparseTimeValueModel.h"
Chris@439 31 #include "data/model/EditableDenseThreeDimensionalModel.h"
Chris@449 32 #include "data/model/NoteModel.h"
Chris@510 33 #include "data/model/TextModel.h"
Chris@449 34 #include "data/model/RegionModel.h"
Chris@499 35 #include "data/model/WaveFileModel.h"
Chris@499 36
Chris@499 37 #include "data/fileio/FileSource.h"
Chris@520 38 #include "data/fileio/CachedFile.h"
Chris@581 39 #include "data/fileio/FileFinder.h"
Chris@522 40
Chris@439 41 using std::cerr;
Chris@439 42 using std::endl;
Chris@439 43
Chris@439 44 class RDFImporterImpl
Chris@439 45 {
Chris@439 46 public:
Chris@439 47 RDFImporterImpl(QString url, int sampleRate);
Chris@439 48 virtual ~RDFImporterImpl();
Chris@490 49
Chris@490 50 void setSampleRate(int sampleRate) { m_sampleRate = sampleRate; }
Chris@439 51
Chris@439 52 bool isOK();
Chris@439 53 QString getErrorString() const;
Chris@439 54
Chris@439 55 std::vector<Model *> getDataModels(ProgressReporter *);
Chris@439 56
Chris@439 57 protected:
Chris@439 58 QString m_uristring;
Chris@439 59 QString m_errorString;
Chris@499 60 std::map<QString, Model *> m_audioModelMap;
Chris@439 61 int m_sampleRate;
Chris@439 62
Chris@520 63 static bool m_prefixesLoaded;
Chris@520 64 static void loadPrefixes(ProgressReporter *reporter);
Chris@520 65
Chris@499 66 void getDataModelsAudio(std::vector<Model *> &, ProgressReporter *);
Chris@440 67 void getDataModelsSparse(std::vector<Model *> &, ProgressReporter *);
Chris@440 68 void getDataModelsDense(std::vector<Model *> &, ProgressReporter *);
Chris@440 69
Chris@493 70 void getDenseModelTitle(Model *, QString, QString);
Chris@493 71
Chris@440 72 void getDenseFeatureProperties(QString featureUri,
Chris@440 73 int &sampleRate, int &windowLength,
Chris@440 74 int &hopSize, int &width, int &height);
Chris@440 75
Chris@449 76 void fillModel(Model *, long, long, bool, std::vector<float> &, QString);
Chris@439 77 };
Chris@439 78
Chris@520 79 bool RDFImporterImpl::m_prefixesLoaded = false;
Chris@439 80
Chris@439 81 QString
Chris@439 82 RDFImporter::getKnownExtensions()
Chris@439 83 {
Chris@439 84 return "*.rdf *.n3 *.ttl";
Chris@439 85 }
Chris@439 86
Chris@439 87 RDFImporter::RDFImporter(QString url, int sampleRate) :
Chris@439 88 m_d(new RDFImporterImpl(url, sampleRate))
Chris@439 89 {
Chris@439 90 }
Chris@439 91
Chris@439 92 RDFImporter::~RDFImporter()
Chris@439 93 {
Chris@439 94 delete m_d;
Chris@439 95 }
Chris@439 96
Chris@490 97 void
Chris@490 98 RDFImporter::setSampleRate(int sampleRate)
Chris@490 99 {
Chris@490 100 m_d->setSampleRate(sampleRate);
Chris@490 101 }
Chris@490 102
Chris@439 103 bool
Chris@439 104 RDFImporter::isOK()
Chris@439 105 {
Chris@439 106 return m_d->isOK();
Chris@439 107 }
Chris@439 108
Chris@439 109 QString
Chris@439 110 RDFImporter::getErrorString() const
Chris@439 111 {
Chris@439 112 return m_d->getErrorString();
Chris@439 113 }
Chris@439 114
Chris@439 115 std::vector<Model *>
Chris@439 116 RDFImporter::getDataModels(ProgressReporter *r)
Chris@439 117 {
Chris@439 118 return m_d->getDataModels(r);
Chris@439 119 }
Chris@439 120
Chris@439 121 RDFImporterImpl::RDFImporterImpl(QString uri, int sampleRate) :
Chris@439 122 m_uristring(uri),
Chris@439 123 m_sampleRate(sampleRate)
Chris@439 124 {
Chris@439 125 }
Chris@439 126
Chris@439 127 RDFImporterImpl::~RDFImporterImpl()
Chris@439 128 {
Chris@492 129 SimpleSPARQLQuery::closeSingleSource(m_uristring);
Chris@439 130 }
Chris@439 131
Chris@439 132 bool
Chris@439 133 RDFImporterImpl::isOK()
Chris@439 134 {
Chris@439 135 return (m_errorString == "");
Chris@439 136 }
Chris@439 137
Chris@439 138 QString
Chris@439 139 RDFImporterImpl::getErrorString() const
Chris@439 140 {
Chris@439 141 return m_errorString;
Chris@439 142 }
Chris@439 143
Chris@439 144 std::vector<Model *>
Chris@439 145 RDFImporterImpl::getDataModels(ProgressReporter *reporter)
Chris@439 146 {
Chris@520 147 loadPrefixes(reporter);
Chris@520 148
Chris@439 149 std::vector<Model *> models;
Chris@439 150
Chris@499 151 getDataModelsAudio(models, reporter);
Chris@499 152
Chris@490 153 if (m_sampleRate == 0) {
Chris@616 154 m_errorString = QString("Invalid audio data model (is audio file format supported?)");
Chris@616 155 std::cerr << m_errorString.toStdString() << std::endl;
Chris@490 156 return models;
Chris@490 157 }
Chris@490 158
Chris@508 159 QString error;
Chris@508 160
Chris@522 161 if (m_errorString != "") {
Chris@522 162 error = m_errorString;
Chris@522 163 }
Chris@508 164 m_errorString = "";
Chris@508 165
Chris@440 166 getDataModelsDense(models, reporter);
Chris@440 167
Chris@522 168 if (m_errorString != "") {
Chris@522 169 error = m_errorString;
Chris@522 170 }
Chris@440 171 m_errorString = "";
Chris@440 172
Chris@440 173 getDataModelsSparse(models, reporter);
Chris@440 174
Chris@522 175 if (m_errorString == "" && error != "") {
Chris@522 176 m_errorString = error;
Chris@522 177 }
Chris@440 178
Chris@440 179 return models;
Chris@440 180 }
Chris@440 181
Chris@440 182 void
Chris@499 183 RDFImporterImpl::getDataModelsAudio(std::vector<Model *> &models,
Chris@499 184 ProgressReporter *reporter)
Chris@499 185 {
Chris@589 186 SimpleSPARQLQuery query
Chris@499 187 (SimpleSPARQLQuery::QueryFromSingleSource,
Chris@499 188 QString
Chris@499 189 (
Chris@499 190 " PREFIX mo: <http://purl.org/ontology/mo/> "
Chris@499 191 " SELECT ?signal ?source FROM <%1> "
Chris@589 192 " WHERE { ?source a mo:AudioFile . "
Chris@589 193 " ?signal a mo:Signal . "
Chris@589 194 " ?source mo:encodes ?signal } "
Chris@499 195 )
Chris@499 196 .arg(m_uristring));
Chris@499 197
Chris@499 198 SimpleSPARQLQuery::ResultList results = query.execute();
Chris@499 199
Chris@589 200 if (results.empty()) {
Chris@589 201
Chris@589 202 SimpleSPARQLQuery query2
Chris@589 203 (SimpleSPARQLQuery::QueryFromSingleSource,
Chris@589 204 QString
Chris@589 205 (
Chris@589 206 " PREFIX mo: <http://purl.org/ontology/mo/> "
Chris@589 207 " SELECT ?signal ?source FROM <%1> "
Chris@589 208 " WHERE { ?signal a mo:Signal ; mo:available_as ?source } "
Chris@589 209 )
Chris@589 210 .arg(m_uristring));
Chris@589 211
Chris@589 212 results = query.execute();
Chris@589 213 }
Chris@589 214
Chris@499 215 for (int i = 0; i < results.size(); ++i) {
Chris@499 216
Chris@499 217 QString signal = results[i]["signal"].value;
Chris@499 218 QString source = results[i]["source"].value;
Chris@499 219
Chris@616 220 std::cerr << "NOTE: Seeking signal source \"" << source.toStdString()
Chris@616 221 << "\"..." << std::endl;
Chris@616 222
Chris@522 223 FileSource *fs = new FileSource(source, reporter);
Chris@616 224 if (fs->isAvailable()) {
Chris@616 225 std::cerr << "NOTE: Source is available: Local filename is \""
Chris@616 226 << fs->getLocalFilename().toStdString()
Chris@616 227 << "\"..." << std::endl;
Chris@616 228 }
Chris@616 229
Chris@522 230 #ifdef NO_SV_GUI
Chris@522 231 if (!fs->isAvailable()) {
Chris@522 232 m_errorString = QString("Signal source \"%1\" is not available").arg(source);
Chris@522 233 delete fs;
Chris@522 234 continue;
Chris@522 235 }
Chris@522 236 #else
Chris@522 237 if (!fs->isAvailable()) {
Chris@616 238 std::cerr << "NOTE: Signal source \"" << source.toStdString()
Chris@616 239 << "\" is not available, using file finder..." << std::endl;
Chris@522 240 FileFinder *ff = FileFinder::getInstance();
Chris@581 241 if (ff) {
Chris@581 242 QString path = ff->find(FileFinder::AudioFile,
Chris@581 243 fs->getLocation(),
Chris@581 244 m_uristring);
Chris@581 245 if (path != "") {
Chris@522 246 delete fs;
Chris@581 247 fs = new FileSource(path, reporter);
Chris@581 248 if (!fs->isAvailable()) {
Chris@581 249 delete fs;
Chris@581 250 m_errorString = QString("Signal source \"%1\" is not available").arg(source);
Chris@581 251 continue;
Chris@581 252 }
Chris@522 253 }
Chris@499 254 }
Chris@522 255 }
Chris@522 256 #endif
Chris@522 257
Chris@522 258 if (reporter) {
Chris@522 259 reporter->setMessage(RDFImporter::tr("Importing audio referenced in RDF..."));
Chris@522 260 }
Chris@522 261 fs->waitForData();
Chris@522 262 WaveFileModel *newModel = new WaveFileModel(*fs, m_sampleRate);
Chris@522 263 if (newModel->isOK()) {
Chris@522 264 std::cerr << "Successfully created wave file model from source at \"" << source.toStdString() << "\"" << std::endl;
Chris@522 265 models.push_back(newModel);
Chris@522 266 m_audioModelMap[signal] = newModel;
Chris@522 267 if (m_sampleRate == 0) {
Chris@522 268 m_sampleRate = newModel->getSampleRate();
Chris@499 269 }
Chris@508 270 } else {
Chris@522 271 m_errorString = QString("Failed to create wave file model from source at \"%1\"").arg(source);
Chris@522 272 delete newModel;
Chris@499 273 }
Chris@522 274 delete fs;
Chris@499 275 }
Chris@499 276 }
Chris@499 277
Chris@499 278 void
Chris@440 279 RDFImporterImpl::getDataModelsDense(std::vector<Model *> &models,
Chris@440 280 ProgressReporter *reporter)
Chris@440 281 {
Chris@499 282 if (reporter) {
Chris@499 283 reporter->setMessage(RDFImporter::tr("Importing dense signal data from RDF..."));
Chris@499 284 }
Chris@499 285
Chris@589 286 SimpleSPARQLQuery query
Chris@489 287 (SimpleSPARQLQuery::QueryFromSingleSource,
Chris@480 288 QString
Chris@440 289 (
Chris@440 290 " PREFIX mo: <http://purl.org/ontology/mo/>"
Chris@440 291 " PREFIX af: <http://purl.org/ontology/af/>"
Chris@440 292
Chris@493 293 " SELECT ?feature ?feature_signal_type ?value "
Chris@440 294 " FROM <%1> "
Chris@440 295
Chris@440 296 " WHERE { "
Chris@440 297
Chris@493 298 " ?signal af:signal_feature ?feature . "
Chris@440 299
Chris@440 300 " ?feature a ?feature_signal_type ; "
Chris@440 301 " af:value ?value . "
Chris@440 302
Chris@440 303 " } "
Chris@440 304 )
Chris@440 305 .arg(m_uristring));
Chris@440 306
Chris@440 307 SimpleSPARQLQuery::ResultList results = query.execute();
Chris@440 308
Chris@440 309 if (!query.isOK()) {
Chris@440 310 m_errorString = query.getErrorString();
Chris@440 311 return;
Chris@440 312 }
Chris@440 313
Chris@440 314 if (query.wasCancelled()) {
Chris@440 315 m_errorString = "Query cancelled";
Chris@440 316 return;
Chris@440 317 }
Chris@440 318
Chris@440 319 for (int i = 0; i < results.size(); ++i) {
Chris@440 320
Chris@440 321 QString feature = results[i]["feature"].value;
Chris@440 322 QString type = results[i]["feature_signal_type"].value;
Chris@440 323 QString value = results[i]["value"].value;
Chris@440 324
Chris@440 325 int sampleRate = 0;
Chris@440 326 int windowLength = 0;
Chris@440 327 int hopSize = 0;
Chris@440 328 int width = 0;
Chris@440 329 int height = 0;
Chris@440 330 getDenseFeatureProperties
Chris@440 331 (feature, sampleRate, windowLength, hopSize, width, height);
Chris@440 332
Chris@440 333 if (sampleRate != 0 && sampleRate != m_sampleRate) {
Chris@440 334 cerr << "WARNING: Sample rate in dense feature description does not match our underlying rate -- using rate from feature description" << endl;
Chris@440 335 }
Chris@440 336 if (sampleRate == 0) sampleRate = m_sampleRate;
Chris@440 337
Chris@440 338 if (hopSize == 0) {
Chris@440 339 cerr << "WARNING: Dense feature description does not specify a hop size -- assuming 1" << endl;
Chris@440 340 hopSize = 1;
Chris@440 341 }
Chris@440 342
Chris@440 343 if (height == 0) {
Chris@440 344 cerr << "WARNING: Dense feature description does not specify feature signal dimensions -- assuming one-dimensional (height = 1)" << endl;
Chris@440 345 height = 1;
Chris@440 346 }
Chris@440 347
Chris@440 348 QStringList values = value.split(' ', QString::SkipEmptyParts);
Chris@440 349
Chris@440 350 if (values.empty()) {
Chris@440 351 cerr << "WARNING: Dense feature description does not specify any values!" << endl;
Chris@440 352 continue;
Chris@440 353 }
Chris@440 354
Chris@440 355 if (height == 1) {
Chris@440 356
Chris@440 357 SparseTimeValueModel *m = new SparseTimeValueModel
Chris@440 358 (sampleRate, hopSize, false);
Chris@440 359
Chris@440 360 for (int j = 0; j < values.size(); ++j) {
Chris@440 361 float f = values[j].toFloat();
Chris@440 362 SparseTimeValueModel::Point point(j * hopSize, f, "");
Chris@440 363 m->addPoint(point);
Chris@440 364 }
Chris@493 365
Chris@493 366 getDenseModelTitle(m, feature, type);
Chris@440 367
Chris@558 368 m->setRDFTypeURI(type);
Chris@558 369
Chris@440 370 models.push_back(m);
Chris@440 371
Chris@440 372 } else {
Chris@440 373
Chris@440 374 EditableDenseThreeDimensionalModel *m =
Chris@535 375 new EditableDenseThreeDimensionalModel
Chris@535 376 (sampleRate, hopSize, height,
Chris@535 377 EditableDenseThreeDimensionalModel::NoCompression, false);
Chris@440 378
Chris@440 379 EditableDenseThreeDimensionalModel::Column column;
Chris@440 380
Chris@440 381 int x = 0;
Chris@440 382
Chris@440 383 for (int j = 0; j < values.size(); ++j) {
Chris@440 384 if (j % height == 0 && !column.empty()) {
Chris@440 385 m->setColumn(x++, column);
Chris@440 386 column.clear();
Chris@440 387 }
Chris@440 388 column.push_back(values[j].toFloat());
Chris@440 389 }
Chris@440 390
Chris@440 391 if (!column.empty()) {
Chris@440 392 m->setColumn(x++, column);
Chris@440 393 }
Chris@440 394
Chris@493 395 getDenseModelTitle(m, feature, type);
Chris@493 396
Chris@558 397 m->setRDFTypeURI(type);
Chris@558 398
Chris@440 399 models.push_back(m);
Chris@440 400 }
Chris@440 401 }
Chris@440 402 }
Chris@440 403
Chris@440 404 void
Chris@493 405 RDFImporterImpl::getDenseModelTitle(Model *m,
Chris@493 406 QString featureUri,
Chris@493 407 QString featureTypeUri)
Chris@493 408 {
Chris@493 409 QString titleQuery = QString
Chris@493 410 (
Chris@493 411 " PREFIX dc: <http://purl.org/dc/elements/1.1/> "
Chris@493 412 " SELECT ?title "
Chris@493 413 " FROM <%1> "
Chris@493 414 " WHERE { "
Chris@493 415 " <%2> dc:title ?title . "
Chris@493 416 " } "
Chris@493 417 ).arg(m_uristring);
Chris@493 418
Chris@493 419 SimpleSPARQLQuery::Value v;
Chris@493 420
Chris@493 421 v = SimpleSPARQLQuery::singleResultQuery
Chris@493 422 (SimpleSPARQLQuery::QueryFromSingleSource,
Chris@493 423 titleQuery.arg(featureUri),
Chris@493 424 "title");
Chris@493 425
Chris@493 426 if (v.value != "") {
Chris@493 427 std::cerr << "RDFImporterImpl::getDenseModelTitle: Title (from signal) \"" << v.value.toStdString() << "\"" << std::endl;
Chris@493 428 m->setObjectName(v.value);
Chris@493 429 return;
Chris@493 430 }
Chris@493 431
Chris@493 432 v = SimpleSPARQLQuery::singleResultQuery
Chris@493 433 (SimpleSPARQLQuery::QueryFromSingleSource,
Chris@493 434 titleQuery.arg(featureTypeUri),
Chris@493 435 "title");
Chris@493 436
Chris@493 437 if (v.value != "") {
Chris@493 438 std::cerr << "RDFImporterImpl::getDenseModelTitle: Title (from signal type) \"" << v.value.toStdString() << "\"" << std::endl;
Chris@493 439 m->setObjectName(v.value);
Chris@493 440 return;
Chris@493 441 }
Chris@493 442
Chris@493 443 std::cerr << "RDFImporterImpl::getDenseModelTitle: No title available for feature <" << featureUri.toStdString() << ">" << std::endl;
Chris@493 444 }
Chris@493 445
Chris@493 446 void
Chris@440 447 RDFImporterImpl::getDenseFeatureProperties(QString featureUri,
Chris@440 448 int &sampleRate, int &windowLength,
Chris@440 449 int &hopSize, int &width, int &height)
Chris@440 450 {
Chris@489 451 SimpleSPARQLQuery::QueryType s = SimpleSPARQLQuery::QueryFromSingleSource;
Chris@489 452
Chris@440 453 QString dimensionsQuery
Chris@440 454 (
Chris@440 455 " PREFIX mo: <http://purl.org/ontology/mo/>"
Chris@440 456 " PREFIX af: <http://purl.org/ontology/af/>"
Chris@440 457
Chris@440 458 " SELECT ?dimensions "
Chris@440 459 " FROM <%1> "
Chris@440 460
Chris@440 461 " WHERE { "
Chris@440 462
Chris@440 463 " <%2> af:dimensions ?dimensions . "
Chris@440 464
Chris@440 465 " } "
Chris@440 466 );
Chris@440 467
Chris@440 468 SimpleSPARQLQuery::Value dimensionsValue =
Chris@489 469 SimpleSPARQLQuery::singleResultQuery
Chris@489 470 (s, dimensionsQuery.arg(m_uristring).arg(featureUri), "dimensions");
Chris@440 471
Chris@440 472 cerr << "Dimensions = \"" << dimensionsValue.value.toStdString() << "\""
Chris@440 473 << endl;
Chris@440 474
Chris@440 475 if (dimensionsValue.value != "") {
Chris@440 476 QStringList dl = dimensionsValue.value.split(" ");
Chris@440 477 if (dl.empty()) dl.push_back(dimensionsValue.value);
Chris@440 478 if (dl.size() > 0) height = dl[0].toInt();
Chris@440 479 if (dl.size() > 1) width = dl[1].toInt();
Chris@440 480 }
Chris@440 481
Chris@440 482 QString queryTemplate
Chris@440 483 (
Chris@440 484 " PREFIX mo: <http://purl.org/ontology/mo/>"
Chris@440 485 " PREFIX af: <http://purl.org/ontology/af/>"
Chris@440 486 " PREFIX tl: <http://purl.org/NET/c4dm/timeline.owl#>"
Chris@440 487
Chris@440 488 " SELECT ?%3 "
Chris@440 489 " FROM <%1> "
Chris@440 490
Chris@440 491 " WHERE { "
Chris@440 492
Chris@440 493 " <%2> mo:time ?time . "
Chris@440 494
Chris@440 495 " ?time a tl:Interval ; "
Chris@440 496 " tl:onTimeLine ?timeline . "
Chris@440 497
Chris@440 498 " ?map tl:rangeTimeLine ?timeline . "
Chris@440 499
Chris@440 500 " ?map tl:%3 ?%3 . "
Chris@440 501
Chris@440 502 " } "
Chris@440 503 );
Chris@440 504
Chris@440 505 // Another laborious workaround for rasqal's failure to handle
Chris@440 506 // multiple optionals properly
Chris@440 507
Chris@440 508 SimpleSPARQLQuery::Value srValue =
Chris@489 509 SimpleSPARQLQuery::singleResultQuery(s,
Chris@480 510 queryTemplate
Chris@440 511 .arg(m_uristring).arg(featureUri)
Chris@440 512 .arg("sampleRate"),
Chris@440 513 "sampleRate");
Chris@440 514 if (srValue.value != "") {
Chris@440 515 sampleRate = srValue.value.toInt();
Chris@440 516 }
Chris@440 517
Chris@440 518 SimpleSPARQLQuery::Value hopValue =
Chris@489 519 SimpleSPARQLQuery::singleResultQuery(s,
Chris@480 520 queryTemplate
Chris@440 521 .arg(m_uristring).arg(featureUri)
Chris@440 522 .arg("hopSize"),
Chris@440 523 "hopSize");
Chris@440 524 if (srValue.value != "") {
Chris@440 525 hopSize = hopValue.value.toInt();
Chris@440 526 }
Chris@440 527
Chris@440 528 SimpleSPARQLQuery::Value winValue =
Chris@489 529 SimpleSPARQLQuery::singleResultQuery(s,
Chris@480 530 queryTemplate
Chris@440 531 .arg(m_uristring).arg(featureUri)
Chris@440 532 .arg("windowLength"),
Chris@440 533 "windowLength");
Chris@440 534 if (winValue.value != "") {
Chris@440 535 windowLength = winValue.value.toInt();
Chris@440 536 }
Chris@440 537
Chris@440 538 cerr << "sr = " << sampleRate << ", hop = " << hopSize << ", win = " << windowLength << endl;
Chris@440 539 }
Chris@440 540
Chris@440 541 void
Chris@440 542 RDFImporterImpl::getDataModelsSparse(std::vector<Model *> &models,
Chris@440 543 ProgressReporter *reporter)
Chris@440 544 {
Chris@499 545 if (reporter) {
Chris@499 546 reporter->setMessage(RDFImporter::tr("Importing event data from RDF..."));
Chris@499 547 }
Chris@499 548
Chris@489 549 SimpleSPARQLQuery::QueryType s = SimpleSPARQLQuery::QueryFromSingleSource;
Chris@489 550
Chris@439 551 // Our query is intended to retrieve every thing that has a time,
Chris@439 552 // and every feature type and value associated with a thing that
Chris@439 553 // has a time.
Chris@439 554
Chris@439 555 // We will then need to refine this big bag of results into a set
Chris@439 556 // of data models.
Chris@439 557
Chris@439 558 // Results that have different source signals should go into
Chris@439 559 // different models.
Chris@439 560
Chris@439 561 // Results that have different feature types should go into
Chris@439 562 // different models.
Chris@439 563
Chris@439 564 // Results that are sparse should go into different models from
Chris@439 565 // those that are dense (we need to examine the timestamps to
Chris@439 566 // establish this -- if the timestamps are regular, the results
Chris@439 567 // are dense -- so we can't do it as we go along, only after
Chris@439 568 // collecting all results).
Chris@439 569
Chris@439 570 // Timed things that have features associated with them should not
Chris@439 571 // appear directly in any model -- their features should appear
Chris@439 572 // instead -- and these should be different models from those used
Chris@439 573 // for timed things that do not have features.
Chris@439 574
Chris@439 575 // As we load the results, we'll push them into a partially
Chris@439 576 // structured container that maps from source signal (URI as
Chris@439 577 // string) -> feature type (likewise) -> time -> list of values.
Chris@439 578 // If the source signal or feature type is unavailable, the empty
Chris@439 579 // string will do.
Chris@439 580
Chris@449 581 QString prefixes = QString(
Chris@439 582 " PREFIX event: <http://purl.org/NET/c4dm/event.owl#>"
Chris@449 583 " PREFIX tl: <http://purl.org/NET/c4dm/timeline.owl#>"
Chris@439 584 " PREFIX mo: <http://purl.org/ontology/mo/>"
Chris@439 585 " PREFIX af: <http://purl.org/ontology/af/>"
Chris@449 586 " PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>"
Chris@449 587 );
Chris@439 588
Chris@449 589 QString queryString = prefixes + QString(
Chris@449 590
Chris@616 591 " SELECT ?signal ?timed_thing ?timeline ?event_type ?value"
Chris@439 592 " FROM <%1>"
Chris@439 593
Chris@439 594 " WHERE {"
Chris@440 595
Chris@440 596 " ?signal a mo:Signal ."
Chris@440 597
Chris@439 598 " ?signal mo:time ?interval ."
Chris@616 599 " ?interval tl:onTimeLine ?timeline ."
Chris@616 600 " ?time tl:onTimeLine ?timeline ."
Chris@449 601 " ?timed_thing event:time ?time ."
Chris@440 602 " ?timed_thing a ?event_type ."
Chris@440 603
Chris@439 604 " OPTIONAL {"
Chris@440 605 " ?timed_thing af:feature ?value"
Chris@439 606 " }"
Chris@439 607 " }"
Chris@439 608
Chris@439 609 ).arg(m_uristring);
Chris@439 610
Chris@616 611 //!!! NB we're using rather old terminology for these things, apparently:
Chris@616 612 // beginsAt -> start
Chris@616 613 // onTimeLine -> timeline
Chris@616 614
Chris@449 615 QString timeQueryString = prefixes + QString(
Chris@449 616
Chris@449 617 " SELECT ?time FROM <%1> "
Chris@449 618 " WHERE { "
Chris@449 619 " <%2> event:time ?t . "
Chris@449 620 " ?t tl:at ?time . "
Chris@449 621 " } "
Chris@449 622
Chris@449 623 ).arg(m_uristring);
Chris@449 624
Chris@449 625 QString rangeQueryString = prefixes + QString(
Chris@449 626
Chris@449 627 " SELECT ?time ?duration FROM <%1> "
Chris@449 628 " WHERE { "
Chris@449 629 " <%2> event:time ?t . "
Chris@449 630 " ?t tl:beginsAt ?time . "
Chris@449 631 " ?t tl:duration ?duration . "
Chris@449 632 " } "
Chris@449 633
Chris@449 634 ).arg(m_uristring);
Chris@449 635
Chris@449 636 QString labelQueryString = prefixes + QString(
Chris@449 637
Chris@449 638 " SELECT ?label FROM <%1> "
Chris@449 639 " WHERE { "
Chris@449 640 " <%2> rdfs:label ?label . "
Chris@449 641 " } "
Chris@449 642
Chris@449 643 ).arg(m_uristring);
Chris@449 644
Chris@510 645 QString textQueryString = prefixes + QString(
Chris@510 646
Chris@510 647 " SELECT ?label FROM <%1> "
Chris@510 648 " WHERE { "
Chris@510 649 " <%2> af:text ?label . "
Chris@510 650 " } "
Chris@510 651
Chris@510 652 ).arg(m_uristring);
Chris@510 653
Chris@489 654 SimpleSPARQLQuery query(s, queryString);
Chris@439 655 query.setProgressReporter(reporter);
Chris@439 656
Chris@500 657 // cerr << "Query will be: " << queryString.toStdString() << endl;
Chris@439 658
Chris@439 659 SimpleSPARQLQuery::ResultList results = query.execute();
Chris@439 660
Chris@439 661 if (!query.isOK()) {
Chris@439 662 m_errorString = query.getErrorString();
Chris@440 663 return;
Chris@439 664 }
Chris@439 665
Chris@439 666 if (query.wasCancelled()) {
Chris@439 667 m_errorString = "Query cancelled";
Chris@440 668 return;
Chris@439 669 }
Chris@439 670
Chris@449 671 /*
Chris@449 672 This function is now only used for sparse data (for dense data
Chris@449 673 we would be in getDataModelsDense instead).
Chris@449 674
Chris@449 675 For sparse data, the determining factors in deciding what model
Chris@449 676 to use are: Do the features have values? and Do the features
Chris@449 677 have duration?
Chris@449 678
Chris@449 679 We can run through the results and check off whether we find
Chris@449 680 values and duration for each of the source+type keys, and then
Chris@449 681 run through the source+type keys pushing each of the results
Chris@449 682 into a suitable model.
Chris@449 683
Chris@449 684 Unfortunately, at this point we do not yet have any actual
Chris@449 685 timing data (time/duration) -- just the time URI.
Chris@449 686
Chris@449 687 What we _could_ do is to create one of each type of model at the
Chris@449 688 start, for each of the source+type keys, and then push each
Chris@449 689 feature into the relevant model depending on what we find out
Chris@449 690 about it. Then return only non-empty models.
Chris@449 691 */
Chris@449 692
Chris@616 693 // Map from timeline uri to event type to dimensionality to
Chris@449 694 // presence of duration to model ptr. Whee!
Chris@449 695 std::map<QString, std::map<QString, std::map<int, std::map<bool, Model *> > > >
Chris@449 696 modelMap;
Chris@449 697
Chris@439 698 for (int i = 0; i < results.size(); ++i) {
Chris@439 699
Chris@499 700 if (i % 4 == 0) {
Chris@499 701 if (reporter) reporter->setProgress(i/4);
Chris@499 702 }
Chris@499 703
Chris@499 704 QString source = results[i]["signal"].value;
Chris@616 705 QString timeline = results[i]["timeline"].value;
Chris@449 706 QString type = results[i]["event_type"].value;
Chris@449 707 QString thinguri = results[i]["timed_thing"].value;
Chris@449 708
Chris@449 709 RealTime time;
Chris@449 710 RealTime duration;
Chris@439 711
Chris@449 712 bool haveTime = false;
Chris@449 713 bool haveDuration = false;
Chris@439 714
Chris@510 715 QString label = "";
Chris@510 716 bool text = (type.contains("Text") || type.contains("text")); // Ha, ha
Chris@510 717
Chris@510 718 if (text) {
Chris@510 719 label = SimpleSPARQLQuery::singleResultQuery
Chris@510 720 (s, textQueryString.arg(thinguri), "label").value;
Chris@510 721 }
Chris@510 722
Chris@510 723 if (label == "") {
Chris@510 724 label = SimpleSPARQLQuery::singleResultQuery
Chris@510 725 (s, labelQueryString.arg(thinguri), "label").value;
Chris@510 726 }
Chris@449 727
Chris@489 728 SimpleSPARQLQuery rangeQuery(s, rangeQueryString.arg(thinguri));
Chris@450 729 SimpleSPARQLQuery::ResultList rangeResults = rangeQuery.execute();
Chris@450 730 if (!rangeResults.empty()) {
Chris@450 731 // std::cerr << rangeResults.size() << " range results" << std::endl;
Chris@450 732 time = RealTime::fromXsdDuration
Chris@450 733 (rangeResults[0]["time"].value.toStdString());
Chris@450 734 duration = RealTime::fromXsdDuration
Chris@450 735 (rangeResults[0]["duration"].value.toStdString());
Chris@450 736 // std::cerr << "duration string " << rangeResults[0]["duration"].value.toStdString() << std::endl;
Chris@449 737 haveTime = true;
Chris@450 738 haveDuration = true;
Chris@449 739 } else {
Chris@450 740 QString timestring = SimpleSPARQLQuery::singleResultQuery
Chris@489 741 (s, timeQueryString.arg(thinguri), "time").value;
Chris@520 742 // std::cerr << "timestring = " << timestring.toStdString() << std::endl;
Chris@450 743 if (timestring != "") {
Chris@450 744 time = RealTime::fromXsdDuration(timestring.toStdString());
Chris@449 745 haveTime = true;
Chris@449 746 }
Chris@449 747 }
Chris@439 748
Chris@439 749 QString valuestring = results[i]["value"].value;
Chris@449 750 std::vector<float> values;
Chris@449 751
Chris@439 752 if (valuestring != "") {
Chris@449 753 QStringList vsl = valuestring.split(" ", QString::SkipEmptyParts);
Chris@449 754 for (int j = 0; j < vsl.size(); ++j) {
Chris@449 755 bool success = false;
Chris@449 756 float v = vsl[j].toFloat(&success);
Chris@449 757 if (success) values.push_back(v);
Chris@449 758 }
Chris@439 759 }
Chris@439 760
Chris@449 761 int dimensions = 1;
Chris@449 762 if (values.size() == 1) dimensions = 2;
Chris@449 763 else if (values.size() > 1) dimensions = 3;
Chris@449 764
Chris@449 765 Model *model = 0;
Chris@449 766
Chris@616 767 if (modelMap[timeline][type][dimensions].find(haveDuration) ==
Chris@616 768 modelMap[timeline][type][dimensions].end()) {
Chris@449 769
Chris@449 770 /*
Chris@449 771 std::cerr << "Creating new model: source = " << source.toStdString()
Chris@449 772 << ", type = " << type.toStdString() << ", dimensions = "
Chris@449 773 << dimensions << ", haveDuration = " << haveDuration
Chris@449 774 << ", time = " << time << ", duration = " << duration
Chris@449 775 << std::endl;
Chris@449 776 */
Chris@449 777
Chris@449 778 if (!haveDuration) {
Chris@449 779
Chris@449 780 if (dimensions == 1) {
Chris@449 781
Chris@510 782 if (text) {
Chris@510 783
Chris@510 784 model = new TextModel(m_sampleRate, 1, false);
Chris@510 785
Chris@510 786 } else {
Chris@510 787
Chris@510 788 model = new SparseOneDimensionalModel(m_sampleRate, 1, false);
Chris@510 789 }
Chris@449 790
Chris@449 791 } else if (dimensions == 2) {
Chris@449 792
Chris@510 793 if (text) {
Chris@510 794
Chris@510 795 model = new TextModel(m_sampleRate, 1, false);
Chris@510 796
Chris@510 797 } else {
Chris@510 798
Chris@510 799 model = new SparseTimeValueModel(m_sampleRate, 1, false);
Chris@510 800 }
Chris@449 801
Chris@449 802 } else {
Chris@449 803
Chris@449 804 // We don't have a three-dimensional sparse model,
Chris@449 805 // so use a note model. We do have some logic (in
Chris@449 806 // extractStructure below) for guessing whether
Chris@449 807 // this should after all have been a dense model,
Chris@449 808 // but it's hard to apply it because we don't have
Chris@449 809 // all the necessary timing data yet... hmm
Chris@449 810
Chris@449 811 model = new NoteModel(m_sampleRate, 1, false);
Chris@449 812 }
Chris@449 813
Chris@449 814 } else { // haveDuration
Chris@449 815
Chris@449 816 if (dimensions == 1 || dimensions == 2) {
Chris@449 817
Chris@449 818 // If our units are frequency or midi pitch, we
Chris@449 819 // should be using a note model... hm
Chris@449 820
Chris@449 821 model = new RegionModel(m_sampleRate, 1, false);
Chris@449 822
Chris@449 823 } else {
Chris@449 824
Chris@449 825 // We don't have a three-dimensional sparse model,
Chris@449 826 // so use a note model. We do have some logic (in
Chris@449 827 // extractStructure below) for guessing whether
Chris@449 828 // this should after all have been a dense model,
Chris@449 829 // but it's hard to apply it because we don't have
Chris@449 830 // all the necessary timing data yet... hmm
Chris@449 831
Chris@449 832 model = new NoteModel(m_sampleRate, 1, false);
Chris@449 833 }
Chris@449 834 }
Chris@449 835
Chris@558 836 model->setRDFTypeURI(type);
Chris@558 837
Chris@499 838 if (m_audioModelMap.find(source) != m_audioModelMap.end()) {
Chris@499 839 std::cerr << "source model for " << model << " is " << m_audioModelMap[source] << std::endl;
Chris@499 840 model->setSourceModel(m_audioModelMap[source]);
Chris@499 841 }
Chris@499 842
Chris@493 843 QString titleQuery = QString
Chris@493 844 (
Chris@493 845 " PREFIX dc: <http://purl.org/dc/elements/1.1/> "
Chris@493 846 " SELECT ?title "
Chris@493 847 " FROM <%1> "
Chris@493 848 " WHERE { "
Chris@493 849 " <%2> dc:title ?title . "
Chris@493 850 " } "
Chris@493 851 ).arg(m_uristring).arg(type);
Chris@493 852 QString title = SimpleSPARQLQuery::singleResultQuery
Chris@493 853 (s, titleQuery, "title").value;
Chris@493 854 if (title != "") model->setObjectName(title);
Chris@493 855
Chris@616 856 modelMap[timeline][type][dimensions][haveDuration] = model;
Chris@449 857 models.push_back(model);
Chris@449 858 }
Chris@449 859
Chris@616 860 model = modelMap[timeline][type][dimensions][haveDuration];
Chris@449 861
Chris@449 862 if (model) {
Chris@449 863 long ftime = RealTime::realTime2Frame(time, m_sampleRate);
Chris@449 864 long fduration = RealTime::realTime2Frame(duration, m_sampleRate);
Chris@449 865 fillModel(model, ftime, fduration, haveDuration, values, label);
Chris@439 866 }
Chris@439 867 }
Chris@439 868 }
Chris@439 869
Chris@439 870 void
Chris@449 871 RDFImporterImpl::fillModel(Model *model,
Chris@449 872 long ftime,
Chris@449 873 long fduration,
Chris@449 874 bool haveDuration,
Chris@449 875 std::vector<float> &values,
Chris@449 876 QString label)
Chris@449 877 {
Chris@493 878 // std::cerr << "RDFImporterImpl::fillModel: adding point at frame " << ftime << std::endl;
Chris@492 879
Chris@449 880 SparseOneDimensionalModel *sodm =
Chris@449 881 dynamic_cast<SparseOneDimensionalModel *>(model);
Chris@449 882 if (sodm) {
Chris@449 883 SparseOneDimensionalModel::Point point(ftime, label);
Chris@449 884 sodm->addPoint(point);
Chris@449 885 return;
Chris@449 886 }
Chris@449 887
Chris@510 888 TextModel *tm =
Chris@510 889 dynamic_cast<TextModel *>(model);
Chris@510 890 if (tm) {
Chris@510 891 TextModel::Point point
Chris@510 892 (ftime,
Chris@510 893 values.empty() ? 0.5f : values[0] < 0.f ? 0.f : values[0] > 1.f ? 1.f : values[0], // I was young and feckless once too
Chris@510 894 label);
Chris@510 895 tm->addPoint(point);
Chris@510 896 return;
Chris@510 897 }
Chris@510 898
Chris@449 899 SparseTimeValueModel *stvm =
Chris@449 900 dynamic_cast<SparseTimeValueModel *>(model);
Chris@449 901 if (stvm) {
Chris@449 902 SparseTimeValueModel::Point point
Chris@449 903 (ftime, values.empty() ? 0.f : values[0], label);
Chris@449 904 stvm->addPoint(point);
Chris@449 905 return;
Chris@449 906 }
Chris@449 907
Chris@449 908 NoteModel *nm =
Chris@449 909 dynamic_cast<NoteModel *>(model);
Chris@449 910 if (nm) {
Chris@449 911 if (haveDuration) {
Chris@449 912 float value = 0.f, level = 1.f;
Chris@449 913 if (!values.empty()) {
Chris@449 914 value = values[0];
Chris@449 915 if (values.size() > 1) {
Chris@449 916 level = values[1];
Chris@449 917 }
Chris@449 918 }
Chris@449 919 NoteModel::Point point(ftime, value, fduration, level, label);
Chris@449 920 nm->addPoint(point);
Chris@449 921 } else {
Chris@449 922 float value = 0.f, duration = 1.f, level = 1.f;
Chris@449 923 if (!values.empty()) {
Chris@449 924 value = values[0];
Chris@449 925 if (values.size() > 1) {
Chris@449 926 duration = values[1];
Chris@449 927 if (values.size() > 2) {
Chris@449 928 level = values[2];
Chris@449 929 }
Chris@449 930 }
Chris@449 931 }
Chris@449 932 NoteModel::Point point(ftime, value, duration, level, label);
Chris@449 933 nm->addPoint(point);
Chris@449 934 }
Chris@449 935 return;
Chris@449 936 }
Chris@449 937
Chris@449 938 RegionModel *rm =
Chris@449 939 dynamic_cast<RegionModel *>(model);
Chris@449 940 if (rm) {
Chris@449 941 if (haveDuration) {
Chris@449 942 RegionModel::Point point
Chris@449 943 (ftime, values.empty() ? 0.f : values[0], fduration, label);
Chris@449 944 rm->addPoint(point);
Chris@449 945 } else {
Chris@449 946 // This won't actually happen -- we only create region models
Chris@449 947 // if we do have duration -- but just for completeness
Chris@449 948 float value = 0.f, duration = 1.f;
Chris@449 949 if (!values.empty()) {
Chris@449 950 value = values[0];
Chris@449 951 if (values.size() > 1) {
Chris@449 952 duration = values[1];
Chris@449 953 }
Chris@449 954 }
Chris@449 955 RegionModel::Point point(ftime, value, duration, label);
Chris@449 956 rm->addPoint(point);
Chris@449 957 }
Chris@449 958 return;
Chris@449 959 }
Chris@449 960
Chris@449 961 std::cerr << "WARNING: RDFImporterImpl::fillModel: Unknown or unexpected model type" << std::endl;
Chris@449 962 return;
Chris@449 963 }
Chris@449 964
Chris@490 965 RDFImporter::RDFDocumentType
Chris@490 966 RDFImporter::identifyDocumentType(QString url)
Chris@490 967 {
Chris@490 968 bool haveAudio = false;
Chris@490 969 bool haveAnnotations = false;
Chris@449 970
Chris@499 971 // This query is not expected to return any values, but if it
Chris@499 972 // executes successfully (leaving no error in the error string)
Chris@499 973 // then we know we have RDF
Chris@499 974 SimpleSPARQLQuery q(SimpleSPARQLQuery::QueryFromSingleSource,
Chris@499 975 QString(" SELECT ?x FROM <%1> WHERE { ?x <y> <z> } ")
Chris@499 976 .arg(url));
Chris@499 977
Chris@499 978 SimpleSPARQLQuery::ResultList r = q.execute();
Chris@499 979 if (!q.isOK()) {
Chris@542 980 SimpleSPARQLQuery::closeSingleSource(url);
Chris@499 981 return NotRDF;
Chris@499 982 }
Chris@499 983
Chris@588 984 // "MO-conformant" structure for audio files
Chris@588 985
Chris@490 986 SimpleSPARQLQuery::Value value =
Chris@490 987 SimpleSPARQLQuery::singleResultQuery
Chris@490 988 (SimpleSPARQLQuery::QueryFromSingleSource,
Chris@490 989 QString
Chris@490 990 (" PREFIX mo: <http://purl.org/ontology/mo/> "
Chris@490 991 " SELECT ?url FROM <%1> "
Chris@588 992 " WHERE { ?url a mo:AudioFile } "
Chris@490 993 ).arg(url),
Chris@490 994 "url");
Chris@490 995
Chris@490 996 if (value.type == SimpleSPARQLQuery::URIValue) {
Chris@588 997
Chris@490 998 haveAudio = true;
Chris@588 999
Chris@588 1000 } else {
Chris@588 1001
Chris@588 1002 // Sonic Annotator v0.2 and below used to write this structure
Chris@588 1003 // (which is not properly in conformance with the Music
Chris@588 1004 // Ontology)
Chris@588 1005
Chris@588 1006 value =
Chris@588 1007 SimpleSPARQLQuery::singleResultQuery
Chris@588 1008 (SimpleSPARQLQuery::QueryFromSingleSource,
Chris@588 1009 QString
Chris@588 1010 (" PREFIX mo: <http://purl.org/ontology/mo/> "
Chris@588 1011 " SELECT ?url FROM <%1> "
Chris@588 1012 " WHERE { ?signal a mo:Signal ; mo:available_as ?url } "
Chris@588 1013 ).arg(url),
Chris@588 1014 "url");
Chris@588 1015
Chris@588 1016 if (value.type == SimpleSPARQLQuery::URIValue) {
Chris@588 1017 haveAudio = true;
Chris@588 1018 }
Chris@490 1019 }
Chris@490 1020
Chris@616 1021 std::cerr << "NOTE: RDFImporter::identifyDocumentType: haveAudio = "
Chris@616 1022 << haveAudio << std::endl;
Chris@616 1023
Chris@490 1024 value =
Chris@490 1025 SimpleSPARQLQuery::singleResultQuery
Chris@490 1026 (SimpleSPARQLQuery::QueryFromSingleSource,
Chris@490 1027 QString
Chris@490 1028 (" PREFIX event: <http://purl.org/NET/c4dm/event.owl#> "
Chris@490 1029 " SELECT ?thing FROM <%1> "
Chris@490 1030 " WHERE { ?thing event:time ?time } "
Chris@490 1031 ).arg(url),
Chris@490 1032 "thing");
Chris@490 1033
Chris@490 1034 if (value.type == SimpleSPARQLQuery::URIValue) {
Chris@490 1035 haveAnnotations = true;
Chris@490 1036 }
Chris@490 1037
Chris@490 1038 if (!haveAnnotations) {
Chris@490 1039
Chris@490 1040 value =
Chris@490 1041 SimpleSPARQLQuery::singleResultQuery
Chris@490 1042 (SimpleSPARQLQuery::QueryFromSingleSource,
Chris@490 1043 QString
Chris@490 1044 (" PREFIX af: <http://purl.org/ontology/af/> "
Chris@490 1045 " SELECT ?thing FROM <%1> "
Chris@490 1046 " WHERE { ?signal af:signal_feature ?thing } "
Chris@490 1047 ).arg(url),
Chris@490 1048 "thing");
Chris@490 1049
Chris@490 1050 if (value.type == SimpleSPARQLQuery::URIValue) {
Chris@490 1051 haveAnnotations = true;
Chris@490 1052 }
Chris@490 1053 }
Chris@490 1054
Chris@616 1055 std::cerr << "NOTE: RDFImporter::identifyDocumentType: haveAnnotations = "
Chris@616 1056 << haveAnnotations << std::endl;
Chris@616 1057
Chris@542 1058 SimpleSPARQLQuery::closeSingleSource(url);
Chris@542 1059
Chris@490 1060 if (haveAudio) {
Chris@490 1061 if (haveAnnotations) {
Chris@490 1062 return AudioRefAndAnnotations;
Chris@490 1063 } else {
Chris@490 1064 return AudioRef;
Chris@490 1065 }
Chris@490 1066 } else {
Chris@490 1067 if (haveAnnotations) {
Chris@490 1068 return Annotations;
Chris@490 1069 } else {
Chris@499 1070 return OtherRDFDocument;
Chris@490 1071 }
Chris@490 1072 }
Chris@492 1073
Chris@542 1074 return OtherRDFDocument;
Chris@490 1075 }
Chris@490 1076
Chris@520 1077 void
Chris@520 1078 RDFImporterImpl::loadPrefixes(ProgressReporter *reporter)
Chris@520 1079 {
Chris@520 1080 return;
Chris@520 1081 //!!!
Chris@520 1082 if (m_prefixesLoaded) return;
Chris@520 1083 const char *prefixes[] = {
Chris@520 1084 "http://purl.org/NET/c4dm/event.owl",
Chris@520 1085 "http://purl.org/NET/c4dm/timeline.owl",
Chris@520 1086 "http://purl.org/ontology/mo/",
Chris@520 1087 "http://purl.org/ontology/af/",
Chris@520 1088 "http://www.w3.org/2000/01/rdf-schema",
Chris@520 1089 "http://purl.org/dc/elements/1.1/",
Chris@520 1090 };
Chris@520 1091 for (size_t i = 0; i < sizeof(prefixes)/sizeof(prefixes[0]); ++i) {
Chris@520 1092 CachedFile cf(prefixes[i], reporter, "application/rdf+xml");
Chris@520 1093 if (!cf.isOK()) continue;
Chris@520 1094 SimpleSPARQLQuery::addSourceToModel
Chris@520 1095 (QUrl::fromLocalFile(cf.getLocalFilename()).toString());
Chris@520 1096 }
Chris@520 1097 m_prefixesLoaded = true;
Chris@520 1098 }