annotate rdf/RDFImporter.cpp @ 627:080d8bdd8762

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