annotate rdf/PluginRDFDescription.cpp @ 449:a75edaa08d28

* Support importing features from RDF whose times are intervals rather than only instants; import them into region or note models. Sadly this makes RDF import much, much slower, because we need to work around Rasqal's single-OPTIONAL limitation by repeatedly querying each feature for time and range. * Add segmentation view to region layer, and display label texts
author Chris Cannam
date Tue, 07 Oct 2008 12:42:17 +0000
parents 5746c559af15
children ef14acd6d102
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 "PluginRDFDescription.h"
Chris@439 17
Chris@439 18 #include "PluginRDFIndexer.h"
Chris@439 19 #include "SimpleSPARQLQuery.h"
Chris@439 20
Chris@439 21 #include "plugin/PluginIdentifier.h"
Chris@439 22
Chris@439 23 #include <iostream>
Chris@439 24 using std::cerr;
Chris@439 25 using std::endl;
Chris@439 26
Chris@439 27 PluginRDFDescription::PluginRDFDescription(QString pluginId) :
Chris@439 28 m_pluginId(pluginId),
Chris@439 29 m_haveDescription(false)
Chris@439 30 {
Chris@439 31 PluginRDFIndexer *indexer = PluginRDFIndexer::getInstance();
Chris@439 32 QString url = indexer->getDescriptionURLForPluginId(pluginId);
Chris@439 33 if (url == "") {
Chris@439 34 cerr << "PluginRDFDescription: WARNING: No RDF description available for plugin ID \""
Chris@439 35 << pluginId.toStdString() << "\"" << endl;
Chris@439 36 } else {
Chris@439 37 if (!indexURL(url)) {
Chris@439 38 cerr << "PluginRDFDescription: ERROR: Failed to query RDF description for plugin ID \""
Chris@439 39 << pluginId.toStdString() << "\"" << endl;
Chris@439 40 } else {
Chris@439 41 m_haveDescription = true;
Chris@439 42 }
Chris@439 43 }
Chris@439 44 }
Chris@439 45
Chris@439 46 PluginRDFDescription::~PluginRDFDescription()
Chris@439 47 {
Chris@439 48 }
Chris@439 49
Chris@439 50 bool
Chris@439 51 PluginRDFDescription::haveDescription() const
Chris@439 52 {
Chris@439 53 return m_haveDescription;
Chris@439 54 }
Chris@439 55
Chris@439 56 PluginRDFDescription::OutputDisposition
Chris@439 57 PluginRDFDescription::getOutputDisposition(QString outputId) const
Chris@439 58 {
Chris@439 59 if (m_outputDispositions.find(outputId) == m_outputDispositions.end()) {
Chris@439 60 return OutputDispositionUnknown;
Chris@439 61 }
Chris@439 62 return m_outputDispositions.find(outputId)->second;
Chris@439 63 }
Chris@439 64
Chris@439 65 QString
Chris@439 66 PluginRDFDescription::getOutputEventTypeURI(QString outputId) const
Chris@439 67 {
Chris@439 68 if (m_outputEventTypeURIMap.find(outputId) ==
Chris@439 69 m_outputEventTypeURIMap.end()) {
Chris@439 70 return "";
Chris@439 71 }
Chris@439 72 return m_outputEventTypeURIMap.find(outputId)->second;
Chris@439 73 }
Chris@439 74
Chris@439 75 QString
Chris@440 76 PluginRDFDescription::getOutputFeatureAttributeURI(QString outputId) const
Chris@440 77 {
Chris@440 78 if (m_outputFeatureAttributeURIMap.find(outputId) ==
Chris@440 79 m_outputFeatureAttributeURIMap.end()) {
Chris@440 80 return "";
Chris@440 81 }
Chris@440 82 return m_outputFeatureAttributeURIMap.find(outputId)->second;
Chris@440 83 }
Chris@440 84
Chris@440 85 QString
Chris@440 86 PluginRDFDescription::getOutputSignalTypeURI(QString outputId) const
Chris@440 87 {
Chris@440 88 if (m_outputSignalTypeURIMap.find(outputId) ==
Chris@440 89 m_outputSignalTypeURIMap.end()) {
Chris@440 90 return "";
Chris@440 91 }
Chris@440 92 return m_outputSignalTypeURIMap.find(outputId)->second;
Chris@440 93 }
Chris@440 94
Chris@440 95 QString
Chris@439 96 PluginRDFDescription::getOutputUnit(QString outputId) const
Chris@439 97 {
Chris@439 98 if (m_outputUnitMap.find(outputId) == m_outputUnitMap.end()) {
Chris@439 99 return "";
Chris@439 100 }
Chris@439 101 return m_outputUnitMap.find(outputId)->second;
Chris@439 102 }
Chris@439 103
Chris@439 104 bool
Chris@439 105 PluginRDFDescription::indexURL(QString url)
Chris@439 106 {
Chris@439 107 QString type, soname, label;
Chris@439 108 PluginIdentifier::parseIdentifier(m_pluginId, type, soname, label);
Chris@439 109
Chris@439 110 SimpleSPARQLQuery query
Chris@439 111 (QString
Chris@439 112 (
Chris@439 113 " PREFIX vamp: <http://purl.org/ontology/vamp/> "
Chris@439 114
Chris@440 115 " SELECT ?output ?output_id ?output_type ?unit "
Chris@439 116 " FROM <%1> "
Chris@439 117
Chris@439 118 " WHERE { "
Chris@439 119
Chris@439 120 " ?plugin a vamp:Plugin ; "
Chris@439 121 " vamp:identifier \"%2\" ; "
Chris@440 122 " vamp:output ?output . "
Chris@439 123
Chris@439 124 " ?output vamp:identifier ?output_id ; "
Chris@439 125 " a ?output_type . "
Chris@439 126
Chris@439 127 " OPTIONAL { "
Chris@439 128 " ?output vamp:unit ?unit "
Chris@439 129 " } . "
Chris@439 130
Chris@439 131 " } "
Chris@439 132 )
Chris@439 133 .arg(url)
Chris@439 134 .arg(label));
Chris@439 135
Chris@439 136 SimpleSPARQLQuery::ResultList results = query.execute();
Chris@439 137
Chris@439 138 if (!query.isOK()) {
Chris@439 139 cerr << "ERROR: PluginRDFDescription::indexURL: ERROR: Failed to query document at <"
Chris@439 140 << url.toStdString() << ">: "
Chris@439 141 << query.getErrorString().toStdString() << endl;
Chris@439 142 return false;
Chris@439 143 }
Chris@439 144
Chris@439 145 if (results.empty()) {
Chris@439 146 cerr << "ERROR: PluginRDFDescription::indexURL: NOTE: Document at <"
Chris@439 147 << url.toStdString()
Chris@440 148 << "> does not appear to describe any outputs for plugin with id \""
Chris@440 149 << label.toStdString() << "\"" << endl;
Chris@439 150 return false;
Chris@439 151 }
Chris@439 152
Chris@439 153 // Note that an output may appear more than once, if it inherits
Chris@439 154 // more than one type (e.g. DenseOutput and QuantizedOutput). So
Chris@439 155 // these results must accumulate
Chris@439 156
Chris@439 157 for (int i = 0; i < results.size(); ++i) {
Chris@439 158
Chris@440 159 QString outputUri = results[i]["output"].value;
Chris@439 160 QString outputId = results[i]["output_id"].value;
Chris@439 161 QString outputType = results[i]["output_type"].value;
Chris@439 162
Chris@439 163 if (outputType.contains("DenseOutput")) {
Chris@439 164 m_outputDispositions[outputId] = OutputDense;
Chris@439 165 } else if (outputType.contains("SparseOutput")) {
Chris@439 166 m_outputDispositions[outputId] = OutputSparse;
Chris@439 167 } else if (outputType.contains("TrackLevelOutput")) {
Chris@439 168 m_outputDispositions[outputId] = OutputTrackLevel;
Chris@439 169 }
Chris@439 170
Chris@439 171 if (results[i]["unit"].type == SimpleSPARQLQuery::LiteralValue) {
Chris@439 172
Chris@439 173 QString unit = results[i]["unit"].value;
Chris@439 174
Chris@439 175 if (unit != "") {
Chris@439 176 m_outputUnitMap[outputId] = unit;
Chris@439 177 }
Chris@439 178 }
Chris@440 179
Chris@440 180 QString queryTemplate =
Chris@440 181 QString(" PREFIX vamp: <http://purl.org/ontology/vamp/> "
Chris@440 182 " SELECT ?%3 FROM <%1> "
Chris@440 183 " WHERE { <%2> vamp:computes_%3 ?%3 } ")
Chris@440 184 .arg(url).arg(outputUri);
Chris@440 185
Chris@440 186 SimpleSPARQLQuery::Value v;
Chris@440 187
Chris@440 188 v = SimpleSPARQLQuery::singleResultQuery
Chris@440 189 (queryTemplate.arg("event_type"), "event_type");
Chris@440 190
Chris@440 191 if (v.type == SimpleSPARQLQuery::URIValue && v.value != "") {
Chris@440 192 m_outputEventTypeURIMap[outputId] = v.value;
Chris@440 193 }
Chris@440 194
Chris@440 195 v = SimpleSPARQLQuery::singleResultQuery
Chris@440 196 (queryTemplate.arg("feature_attribute"), "feature_attribute");
Chris@440 197
Chris@440 198 if (v.type == SimpleSPARQLQuery::URIValue && v.value != "") {
Chris@440 199 m_outputFeatureAttributeURIMap[outputId] = v.value;
Chris@440 200 }
Chris@440 201
Chris@440 202 v = SimpleSPARQLQuery::singleResultQuery
Chris@440 203 (queryTemplate.arg("signal_type"), "signal_type");
Chris@440 204
Chris@440 205 if (v.type == SimpleSPARQLQuery::URIValue && v.value != "") {
Chris@440 206 m_outputSignalTypeURIMap[outputId] = v.value;
Chris@440 207 }
Chris@439 208 }
Chris@439 209
Chris@439 210 return true;
Chris@439 211 }
Chris@439 212