annotate rdf/RDFImporter.cpp @ 718:f3fd2988fc9b

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