annotate rdf/RDFImporter.cpp @ 661:a4faa1840384

* If a FileSource URL won't convert at all in strict mode, try again in tolerant mode (necessary for e.g. filenames with square brackets in them)
author Chris Cannam
date Tue, 19 Oct 2010 21:47:55 +0100
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 }