comparison rdf/RDFImporter.cpp @ 730:27c861cce97b dataquay

Further fixes for Dataquay compatibility
author Chris Cannam
date Mon, 21 May 2012 14:33:35 +0100
parents 211efc770335
children 31ab733841d0
comparison
equal deleted inserted replaced
729:11289d40a57a 730:27c861cce97b
63 63
64 std::vector<Model *> getDataModels(ProgressReporter *); 64 std::vector<Model *> getDataModels(ProgressReporter *);
65 65
66 protected: 66 protected:
67 BasicStore *m_store; 67 BasicStore *m_store;
68 Uri expand(QString s) { return m_store->expand(s); }
68 69
69 QString m_uristring; 70 QString m_uristring;
70 QString m_errorString; 71 QString m_errorString;
71 std::map<QString, Model *> m_audioModelMap; 72 std::map<QString, Model *> m_audioModelMap;
72 int m_sampleRate; 73 int m_sampleRate;
200 void 201 void
201 RDFImporterImpl::getDataModelsAudio(std::vector<Model *> &models, 202 RDFImporterImpl::getDataModelsAudio(std::vector<Model *> &models,
202 ProgressReporter *reporter) 203 ProgressReporter *reporter)
203 { 204 {
204 Nodes sigs = m_store->match 205 Nodes sigs = m_store->match
205 (Triple(Node(), "a", m_store->expand("mo:Signal"))).a(); 206 (Triple(Node(), Uri("a"), expand("mo:Signal"))).subjects();
206 207
207 foreach (Node sig, sigs) { 208 foreach (Node sig, sigs) {
208 209
209 Node file = m_store->matchFirst(Triple(Node(), "mo:encodes", sig)).a; 210 Node file = m_store->complete(Triple(Node(), expand("mo:encodes"), sig));
210 if (file == Node()) { 211 if (file == Node()) {
211 file = m_store->matchFirst(Triple(sig, "mo:available_as", Node())).c; 212 file = m_store->complete(Triple(sig, expand("mo:available_as"), Node()));
212 } 213 }
213 if (file == Node()) { 214 if (file == Node()) {
214 std::cerr << "RDFImporterImpl::getDataModelsAudio: ERROR: No source for signal " << sig << std::endl; 215 std::cerr << "RDFImporterImpl::getDataModelsAudio: ERROR: No source for signal " << sig << std::endl;
215 continue; 216 continue;
216 } 217 }
285 if (reporter) { 286 if (reporter) {
286 reporter->setMessage(RDFImporter::tr("Importing dense signal data from RDF...")); 287 reporter->setMessage(RDFImporter::tr("Importing dense signal data from RDF..."));
287 } 288 }
288 289
289 Nodes sigFeatures = m_store->match 290 Nodes sigFeatures = m_store->match
290 (Triple(Node(), "af:signal_feature", Node())).c(); 291 (Triple(Node(), expand("af:signal_feature"), Node())).objects();
291 292
292 foreach (Node sf, sigFeatures) { 293 foreach (Node sf, sigFeatures) {
293 294
294 if (sf.type != Node::URI && sf.type != Node::Blank) continue; 295 if (sf.type != Node::URI && sf.type != Node::Blank) continue;
295 296
296 Node t = m_store->matchFirst(Triple(sf, "a", Node())).c; 297 Node t = m_store->complete(Triple(sf, expand("a"), Node()));
297 Node v = m_store->matchFirst(Triple(sf, "af:value", Node())).c; 298 Node v = m_store->complete(Triple(sf, expand("af:value"), Node()));
298 299
299 QString feature = sf.value; 300 QString feature = sf.value;
300 QString type = t.value; 301 QString type = t.value;
301 QString value = v.value; 302 QString value = v.value;
302 303
384 void 385 void
385 RDFImporterImpl::getDenseModelTitle(Model *m, 386 RDFImporterImpl::getDenseModelTitle(Model *m,
386 QString featureUri, 387 QString featureUri,
387 QString featureTypeUri) 388 QString featureTypeUri)
388 { 389 {
389 Node n = m_store->matchFirst 390 Node n = m_store->complete
390 (Triple(Uri(featureUri), "dc:title", Node())).c; 391 (Triple(Uri(featureUri), expand("dc:title"), Node()));
391 392
392 if (n.type == Node::Literal && n.value != "") { 393 if (n.type == Node::Literal && n.value != "") {
393 SVDEBUG << "RDFImporterImpl::getDenseModelTitle: Title (from signal) \"" << n.value << "\"" << endl; 394 SVDEBUG << "RDFImporterImpl::getDenseModelTitle: Title (from signal) \"" << n.value << "\"" << endl;
394 m->setObjectName(n.value); 395 m->setObjectName(n.value);
395 return; 396 return;
396 } 397 }
397 398
398 n = m_store->matchFirst 399 n = m_store->complete
399 (Triple(Uri(featureTypeUri), "dc:title", Node())).c; 400 (Triple(Uri(featureTypeUri), expand("dc:title"), Node()));
400 401
401 if (n.type == Node::Literal && n.value != "") { 402 if (n.type == Node::Literal && n.value != "") {
402 SVDEBUG << "RDFImporterImpl::getDenseModelTitle: Title (from signal type) \"" << n.value << "\"" << endl; 403 SVDEBUG << "RDFImporterImpl::getDenseModelTitle: Title (from signal type) \"" << n.value << "\"" << endl;
403 m->setObjectName(n.value); 404 m->setObjectName(n.value);
404 return; 405 return;
410 void 411 void
411 RDFImporterImpl::getDenseFeatureProperties(QString featureUri, 412 RDFImporterImpl::getDenseFeatureProperties(QString featureUri,
412 int &sampleRate, int &windowLength, 413 int &sampleRate, int &windowLength,
413 int &hopSize, int &width, int &height) 414 int &hopSize, int &width, int &height)
414 { 415 {
415 Node dim = m_store->matchFirst 416 Node dim = m_store->complete
416 (Triple(Uri(featureUri), "af:dimensions", Node())).c; 417 (Triple(Uri(featureUri), expand("af:dimensions"), Node()));
417 418
418 cerr << "Dimensions = \"" << dim.value << "\"" << endl; 419 cerr << "Dimensions = \"" << dim.value << "\"" << endl;
419 420
420 if (dim.type == Node::Literal && dim.value != "") { 421 if (dim.type == Node::Literal && dim.value != "") {
421 QStringList dl = dim.value.split(" "); 422 QStringList dl = dim.value.split(" ");
432 // ?map tl:rangeTimeLine ?timeline . 433 // ?map tl:rangeTimeLine ?timeline .
433 // ?map tl:sampleRate ?rate . 434 // ?map tl:sampleRate ?rate .
434 // ?map tl:hopSize ?hop . 435 // ?map tl:hopSize ?hop .
435 // ?map tl:windowLength ?window . 436 // ?map tl:windowLength ?window .
436 437
437 Node interval = m_store->matchFirst(Triple(Uri(featureUri), "mo:time", Node())).c; 438 Node interval = m_store->complete(Triple(Uri(featureUri), expand("mo:time"), Node()));
438 439
439 if (!m_store->contains(Triple(interval, "a", m_store->expand("tl:Interval")))) { 440 if (!m_store->contains(Triple(interval, expand("a"), expand("tl:Interval")))) {
440 cerr << "RDFImporterImpl::getDenseFeatureProperties: Feature time node " 441 cerr << "RDFImporterImpl::getDenseFeatureProperties: Feature time node "
441 << interval << " is not a tl:Interval" << endl; 442 << interval << " is not a tl:Interval" << endl;
442 return; 443 return;
443 } 444 }
444 445
445 Node tl = m_store->matchFirst(Triple(interval, "tl:onTimeLine", Node())).c; 446 Node tl = m_store->complete(Triple(interval, expand("tl:onTimeLine"), Node()));
446 447
447 if (tl == Node()) { 448 if (tl == Node()) {
448 cerr << "RDFImporterImpl::getDenseFeatureProperties: Interval node " 449 cerr << "RDFImporterImpl::getDenseFeatureProperties: Interval node "
449 << interval << " lacks tl:onTimeLine property" << endl; 450 << interval << " lacks tl:onTimeLine property" << endl;
450 return; 451 return;
451 } 452 }
452 453
453 Node map = m_store->matchFirst(Triple(Node(), "tl:rangeTimeLine", tl)).a; 454 Node map = m_store->complete(Triple(Node(), expand("tl:rangeTimeLine"), tl));
454 455
455 if (map == Node()) { 456 if (map == Node()) {
456 cerr << "RDFImporterImpl::getDenseFeatureProperties: No map for " 457 cerr << "RDFImporterImpl::getDenseFeatureProperties: No map for "
457 << "timeline node " << tl << endl; 458 << "timeline node " << tl << endl;
458 } 459 }
497 Results that have different feature types should go into 498 Results that have different feature types should go into
498 different models. 499 different models.
499 */ 500 */
500 501
501 Nodes sigs = m_store->match 502 Nodes sigs = m_store->match
502 (Triple(Node(), "a", m_store->expand("mo:Signal"))).a(); 503 (Triple(Node(), expand("a"), expand("mo:Signal"))).subjects();
503 504
504 // Map from timeline uri to event type to dimensionality to 505 // Map from timeline uri to event type to dimensionality to
505 // presence of duration to model ptr. Whee! 506 // presence of duration to model ptr. Whee!
506 std::map<QString, std::map<QString, std::map<int, std::map<bool, Model *> > > > 507 std::map<QString, std::map<QString, std::map<int, std::map<bool, Model *> > > >
507 modelMap; 508 modelMap;
508 509
509 foreach (Node sig, sigs) { 510 foreach (Node sig, sigs) {
510 511
511 Node interval = m_store->matchFirst(Triple(sig, "mo:time", Node())).c; 512 Node interval = m_store->complete(Triple(sig, expand("mo:time"), Node()));
512 if (interval == Node()) continue; 513 if (interval == Node()) continue;
513 514
514 Node tl = m_store->matchFirst(Triple(interval, "tl:onTimeLine", Node())).c; 515 Node tl = m_store->complete(Triple(interval, expand("tl:onTimeLine"), Node()));
515 if (tl == Node()) continue; 516 if (tl == Node()) continue;
516 517
517 Nodes times = m_store->match(Triple(Node(), "tl:onTimeLine", tl)).a(); 518 Nodes times = m_store->match(Triple(Node(), expand("tl:onTimeLine"), tl)).subjects();
518 519
519 foreach (Node tn, times) { 520 foreach (Node tn, times) {
520 521
521 Nodes timedThings = m_store->match(Triple(Node(), "event:time", tn)).a(); 522 Nodes timedThings = m_store->match(Triple(Node(), expand("event:time"), tn)).subjects();
522 523
523 foreach (Node thing, timedThings) { 524 foreach (Node thing, timedThings) {
524 525
525 Node typ = m_store->matchFirst(Triple(thing, "a", Node())).c; 526 Node typ = m_store->complete(Triple(thing, expand("a"), Node()));
526 if (typ == Node()) continue; 527 if (typ == Node()) continue;
527 528
528 Node valu = m_store->matchFirst(Triple(thing, "af:feature", Node())).c; 529 Node valu = m_store->complete(Triple(thing, expand("af:feature"), Node()));
529 530
530 QString source = sig.value; 531 QString source = sig.value;
531 QString timeline = tl.value; 532 QString timeline = tl.value;
532 QString type = typ.value; 533 QString type = typ.value;
533 QString thinguri = thing.value; 534 QString thinguri = thing.value;
557 QString label = ""; 558 QString label = "";
558 bool text = (type.contains("Text") || type.contains("text")); // Ha, ha 559 bool text = (type.contains("Text") || type.contains("text")); // Ha, ha
559 bool note = (type.contains("Note") || type.contains("note")); // Guffaw 560 bool note = (type.contains("Note") || type.contains("note")); // Guffaw
560 561
561 if (text) { 562 if (text) {
562 label = m_store->matchFirst(Triple(thing, "af:text", Node())).c.value; 563 label = m_store->complete(Triple(thing, expand("af:text"), Node())).value;
563 } 564 }
564 565
565 if (label == "") { 566 if (label == "") {
566 label = m_store->matchFirst(Triple(thing, "rdfs:label", Node())).c.value; 567 label = m_store->complete(Triple(thing, expand("rdfs:label"), Node())).value;
567 } 568 }
568 569
569 RealTime time; 570 RealTime time;
570 RealTime duration; 571 RealTime duration;
571 572
572 bool haveTime = false; 573 bool haveTime = false;
573 bool haveDuration = false; 574 bool haveDuration = false;
574 575
575 Node at = m_store->matchFirst(Triple(tn, "tl:at", Node())).c; 576 Node at = m_store->complete(Triple(tn, expand("tl:at"), Node()));
576 577
577 if (at != Node()) { 578 if (at != Node()) {
578 time = RealTime::fromXsdDuration(at.value.toStdString()); 579 time = RealTime::fromXsdDuration(at.value.toStdString());
579 haveTime = true; 580 haveTime = true;
580 } else { 581 } else {
581 //!!! NB we're using rather old terminology for these things, apparently: 582 //!!! NB we're using rather old terminology for these things, apparently:
582 // beginsAt -> start 583 // beginsAt -> start
583 // onTimeLine -> timeline 584 // onTimeLine -> timeline
584 585
585 Node start = m_store->matchFirst(Triple(tn, "tl:beginsAt", Node())).c; 586 Node start = m_store->complete(Triple(tn, expand("tl:beginsAt"), Node()));
586 Node dur = m_store->matchFirst(Triple(tn, "tl:duration", Node())).c; 587 Node dur = m_store->complete(Triple(tn, expand("tl:duration"), Node()));
587 if (start != Node() && dur != Node()) { 588 if (start != Node() && dur != Node()) {
588 time = RealTime::fromXsdDuration 589 time = RealTime::fromXsdDuration
589 (start.value.toStdString()); 590 (start.value.toStdString());
590 duration = RealTime::fromXsdDuration 591 duration = RealTime::fromXsdDuration
591 (dur.value.toStdString()); 592 (dur.value.toStdString());
661 if (m_audioModelMap.find(source) != m_audioModelMap.end()) { 662 if (m_audioModelMap.find(source) != m_audioModelMap.end()) {
662 std::cerr << "source model for " << model << " is " << m_audioModelMap[source] << std::endl; 663 std::cerr << "source model for " << model << " is " << m_audioModelMap[source] << std::endl;
663 model->setSourceModel(m_audioModelMap[source]); 664 model->setSourceModel(m_audioModelMap[source]);
664 } 665 }
665 666
666 QString title = m_store->matchFirst 667 QString title = m_store->complete
667 (Triple(typ, "dc:title", Node())).a.value; 668 (Triple(typ, expand("dc:title"), Node())).value;
668 if (title == "") { 669 if (title == "") {
669 // take it from the end of the event type 670 // take it from the end of the event type
670 title = type; 671 title = type;
671 title.replace(QRegExp("^.*[/#]"), ""); 672 title.replace(QRegExp("^.*[/#]"), "");
672 } 673 }
804 // This is not expected to return anything useful, but if it does 805 // This is not expected to return anything useful, but if it does
805 // anything at all then we know we have RDF 806 // anything at all then we know we have RDF
806 try { 807 try {
807 //!!! non-local document? + may throw!!! 808 //!!! non-local document? + may throw!!!
808 store = BasicStore::load(QUrl(url)); 809 store = BasicStore::load(QUrl(url));
809 Triple t = store->matchFirst(Triple()); 810 Triple t = store->matchOnce(Triple());
810 if (t != Triple()) haveRDF = true; 811 if (t != Triple()) haveRDF = true;
811 } catch (...) { 812 } catch (...) {
812 } 813 }
813 814
814 if (!haveRDF) { 815 if (!haveRDF) {
820 store->addPrefix("event", Uri("http://purl.org/NET/c4dm/event.owl#")); 821 store->addPrefix("event", Uri("http://purl.org/NET/c4dm/event.owl#"));
821 store->addPrefix("af", Uri("http://purl.org/ontology/af/")); 822 store->addPrefix("af", Uri("http://purl.org/ontology/af/"));
822 823
823 // "MO-conformant" structure for audio files 824 // "MO-conformant" structure for audio files
824 825
825 Node n = store->matchFirst(Triple(Node(), "a", store->expand("mo:AudioFile"))).a; 826 Node n = store->complete(Triple(Node(), Uri("a"), store->expand("mo:AudioFile")));
826 if (n != Node() && n.type == Node::URI) { 827 if (n != Node() && n.type == Node::URI) {
827 828
828 haveAudio = true; 829 haveAudio = true;
829 830
830 } else { 831 } else {
831 832
832 // Sonic Annotator v0.2 and below used to write this structure 833 // Sonic Annotator v0.2 and below used to write this structure
833 // (which is not properly in conformance with the Music 834 // (which is not properly in conformance with the Music
834 // Ontology) 835 // Ontology)
835 836
836 Nodes sigs = store->match(Triple(Node(), "a", store->expand("mo:Signal"))).a(); 837 Nodes sigs = store->match(Triple(Node(), Uri("a"), store->expand("mo:Signal"))).subjects();
837 foreach (Node sig, sigs) { 838 foreach (Node sig, sigs) {
838 Node aa = store->matchFirst(Triple(sig, "mo:available_as", Node())).c; 839 Node aa = store->complete(Triple(sig, store->expand("mo:available_as"), Node()));
839 if (aa != Node()) { 840 if (aa != Node()) {
840 haveAudio = true; 841 haveAudio = true;
841 break; 842 break;
842 } 843 }
843 } 844 }
844 } 845 }
845 846
846 SVDEBUG << "NOTE: RDFImporter::identifyDocumentType: haveAudio = " 847 SVDEBUG << "NOTE: RDFImporter::identifyDocumentType: haveAudio = "
847 << haveAudio << endl; 848 << haveAudio << endl;
848 849
849 n = store->matchFirst(Triple(Node(), "event:time", Node())).a; 850 n = store->complete(Triple(Node(), store->expand("event:time"), Node()));
850 if (n != Node()) { 851 if (n != Node()) {
851 haveAnnotations = true; 852 haveAnnotations = true;
852 } 853 }
853 854
854 if (!haveAnnotations) { 855 if (!haveAnnotations) {
855 n = store->matchFirst(Triple(Node(), "af:signal_feature", Node())).a; 856 n = store->complete(Triple(Node(), store->expand("af:signal_feature"), Node()));
856 if (n != Node()) { 857 if (n != Node()) {
857 haveAnnotations = true; 858 haveAnnotations = true;
858 } 859 }
859 } 860 }
860 861