annotate rdf/PluginRDFDescription.cpp @ 512:e7a39c45a7a4

* close output streams a little sooner when writing features for more than one file (doesn't affect eventual output though)
author Chris Cannam
date Tue, 09 Dec 2008 16:53:37 +0000
parents 1b8c748fd7ea
children e340b2fb9471
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@457 21 #include "data/fileio/FileSource.h"
Chris@468 22 #include "data/fileio/CachedFile.h"
Chris@457 23
Chris@457 24 #include "base/Profiler.h"
Chris@457 25
Chris@439 26 #include "plugin/PluginIdentifier.h"
Chris@439 27
Chris@439 28 #include <iostream>
Chris@439 29 using std::cerr;
Chris@439 30 using std::endl;
Chris@439 31
Chris@439 32 PluginRDFDescription::PluginRDFDescription(QString pluginId) :
Chris@439 33 m_pluginId(pluginId),
Chris@439 34 m_haveDescription(false)
Chris@439 35 {
Chris@439 36 PluginRDFIndexer *indexer = PluginRDFIndexer::getInstance();
Chris@489 37 m_pluginUri = indexer->getURIForPluginId(pluginId);
Chris@489 38 if (m_pluginUri == "") {
Chris@439 39 cerr << "PluginRDFDescription: WARNING: No RDF description available for plugin ID \""
Chris@439 40 << pluginId.toStdString() << "\"" << endl;
Chris@439 41 } else {
Chris@489 42 // All the data we need should be in our RDF model already:
Chris@489 43 // if it's not there, we don't know where to find it anyway
Chris@489 44 if (index()) {
Chris@439 45 m_haveDescription = true;
Chris@439 46 }
Chris@439 47 }
Chris@439 48 }
Chris@439 49
Chris@439 50 PluginRDFDescription::~PluginRDFDescription()
Chris@439 51 {
Chris@439 52 }
Chris@439 53
Chris@439 54 bool
Chris@439 55 PluginRDFDescription::haveDescription() const
Chris@439 56 {
Chris@439 57 return m_haveDescription;
Chris@439 58 }
Chris@439 59
Chris@457 60 QString
Chris@457 61 PluginRDFDescription::getPluginName() const
Chris@457 62 {
Chris@457 63 return m_pluginName;
Chris@457 64 }
Chris@457 65
Chris@457 66 QString
Chris@457 67 PluginRDFDescription::getPluginDescription() const
Chris@457 68 {
Chris@457 69 return m_pluginDescription;
Chris@457 70 }
Chris@457 71
Chris@457 72 QString
Chris@457 73 PluginRDFDescription::getPluginMaker() const
Chris@457 74 {
Chris@457 75 return m_pluginMaker;
Chris@457 76 }
Chris@457 77
Chris@462 78 QString
Chris@462 79 PluginRDFDescription::getPluginInfoURL() const
Chris@462 80 {
Chris@462 81 return m_pluginInfoURL;
Chris@462 82 }
Chris@462 83
Chris@457 84 QStringList
Chris@457 85 PluginRDFDescription::getOutputIds() const
Chris@457 86 {
Chris@457 87 QStringList ids;
Chris@457 88 for (OutputDispositionMap::const_iterator i = m_outputDispositions.begin();
Chris@457 89 i != m_outputDispositions.end(); ++i) {
Chris@457 90 ids.push_back(i->first);
Chris@457 91 }
Chris@457 92 return ids;
Chris@457 93 }
Chris@457 94
Chris@457 95 QString
Chris@457 96 PluginRDFDescription::getOutputName(QString outputId) const
Chris@457 97 {
Chris@457 98 if (m_outputNames.find(outputId) == m_outputNames.end()) {
Chris@457 99 return "";
Chris@457 100 }
Chris@457 101 return m_outputNames.find(outputId)->second;
Chris@457 102 }
Chris@457 103
Chris@439 104 PluginRDFDescription::OutputDisposition
Chris@439 105 PluginRDFDescription::getOutputDisposition(QString outputId) const
Chris@439 106 {
Chris@439 107 if (m_outputDispositions.find(outputId) == m_outputDispositions.end()) {
Chris@439 108 return OutputDispositionUnknown;
Chris@439 109 }
Chris@439 110 return m_outputDispositions.find(outputId)->second;
Chris@439 111 }
Chris@439 112
Chris@439 113 QString
Chris@439 114 PluginRDFDescription::getOutputEventTypeURI(QString outputId) const
Chris@439 115 {
Chris@439 116 if (m_outputEventTypeURIMap.find(outputId) ==
Chris@439 117 m_outputEventTypeURIMap.end()) {
Chris@439 118 return "";
Chris@439 119 }
Chris@439 120 return m_outputEventTypeURIMap.find(outputId)->second;
Chris@439 121 }
Chris@439 122
Chris@439 123 QString
Chris@440 124 PluginRDFDescription::getOutputFeatureAttributeURI(QString outputId) const
Chris@440 125 {
Chris@440 126 if (m_outputFeatureAttributeURIMap.find(outputId) ==
Chris@440 127 m_outputFeatureAttributeURIMap.end()) {
Chris@440 128 return "";
Chris@440 129 }
Chris@440 130 return m_outputFeatureAttributeURIMap.find(outputId)->second;
Chris@440 131 }
Chris@440 132
Chris@440 133 QString
Chris@440 134 PluginRDFDescription::getOutputSignalTypeURI(QString outputId) const
Chris@440 135 {
Chris@440 136 if (m_outputSignalTypeURIMap.find(outputId) ==
Chris@440 137 m_outputSignalTypeURIMap.end()) {
Chris@440 138 return "";
Chris@440 139 }
Chris@440 140 return m_outputSignalTypeURIMap.find(outputId)->second;
Chris@440 141 }
Chris@440 142
Chris@440 143 QString
Chris@439 144 PluginRDFDescription::getOutputUnit(QString outputId) const
Chris@439 145 {
Chris@439 146 if (m_outputUnitMap.find(outputId) == m_outputUnitMap.end()) {
Chris@439 147 return "";
Chris@439 148 }
Chris@439 149 return m_outputUnitMap.find(outputId)->second;
Chris@439 150 }
Chris@439 151
Chris@494 152 QString
Chris@494 153 PluginRDFDescription::getOutputUri(QString outputId) const
Chris@494 154 {
Chris@494 155 if (m_outputUriMap.find(outputId) == m_outputUriMap.end()) {
Chris@494 156 return "";
Chris@494 157 }
Chris@494 158 return m_outputUriMap.find(outputId)->second;
Chris@494 159 }
Chris@494 160
Chris@439 161 bool
Chris@489 162 PluginRDFDescription::index()
Chris@439 163 {
Chris@489 164 Profiler profiler("PluginRDFDescription::index");
Chris@439 165
Chris@457 166 bool success = true;
Chris@489 167 if (!indexMetadata()) success = false;
Chris@489 168 if (!indexOutputs()) success = false;
Chris@457 169
Chris@457 170 return success;
Chris@457 171 }
Chris@457 172
Chris@457 173 bool
Chris@489 174 PluginRDFDescription::indexMetadata()
Chris@457 175 {
Chris@489 176 Profiler profiler("PluginRDFDescription::index");
Chris@489 177
Chris@489 178 SimpleSPARQLQuery::QueryType m = SimpleSPARQLQuery::QueryFromModel;
Chris@457 179
Chris@457 180 QString queryTemplate =
Chris@457 181 QString(
Chris@457 182 " PREFIX vamp: <http://purl.org/ontology/vamp/> "
Chris@457 183 " PREFIX foaf: <http://xmlns.com/foaf/0.1/> "
Chris@457 184 " PREFIX dc: <http://purl.org/dc/elements/1.1/> "
Chris@489 185 " SELECT ?%3 "
Chris@457 186 " WHERE { "
Chris@489 187 " <%1> %2 ?%3 . "
Chris@457 188 " }")
Chris@489 189 .arg(m_pluginUri);
Chris@457 190
Chris@457 191 SimpleSPARQLQuery::Value v;
Chris@457 192
Chris@457 193 v = SimpleSPARQLQuery::singleResultQuery
Chris@489 194 (m, queryTemplate.arg("vamp:name").arg("name"), "name");
Chris@457 195
Chris@457 196 if (v.type == SimpleSPARQLQuery::LiteralValue && v.value != "") {
Chris@457 197 m_pluginName = v.value;
Chris@457 198 }
Chris@457 199
Chris@457 200 v = SimpleSPARQLQuery::singleResultQuery
Chris@489 201 (m, queryTemplate.arg("dc:description").arg("description"), "description");
Chris@457 202
Chris@457 203 if (v.type == SimpleSPARQLQuery::LiteralValue && v.value != "") {
Chris@457 204 m_pluginDescription = v.value;
Chris@457 205 }
Chris@457 206
Chris@457 207 v = SimpleSPARQLQuery::singleResultQuery
Chris@489 208 (m,
Chris@480 209 QString(
Chris@457 210 " PREFIX vamp: <http://purl.org/ontology/vamp/> "
Chris@457 211 " PREFIX foaf: <http://xmlns.com/foaf/0.1/> "
Chris@489 212 " SELECT ?name "
Chris@457 213 " WHERE { "
Chris@489 214 " <%1> foaf:maker ?maker . "
Chris@457 215 " ?maker foaf:name ?name . "
Chris@457 216 " }")
Chris@489 217 .arg(m_pluginUri),
Chris@489 218 "name");
Chris@457 219
Chris@457 220 if (v.type == SimpleSPARQLQuery::LiteralValue && v.value != "") {
Chris@457 221 m_pluginMaker = v.value;
Chris@457 222 }
Chris@457 223
Chris@462 224 // If we have a more-information URL for this plugin, then we take
Chris@463 225 // that. Otherwise, a more-information URL for the plugin
Chris@462 226 // library would do nicely. Failing that, we could perhaps use
Chris@462 227 // any foaf:page URL at all that appears in the file -- but
Chris@462 228 // perhaps that would be unwise
Chris@462 229
Chris@462 230 v = SimpleSPARQLQuery::singleResultQuery
Chris@489 231 (m,
Chris@480 232 QString(
Chris@462 233 " PREFIX vamp: <http://purl.org/ontology/vamp/> "
Chris@462 234 " PREFIX foaf: <http://xmlns.com/foaf/0.1/> "
Chris@489 235 " SELECT ?page "
Chris@462 236 " WHERE { "
Chris@489 237 " <%1> foaf:page ?page . "
Chris@462 238 " }")
Chris@489 239 .arg(m_pluginUri),
Chris@489 240 "page");
Chris@462 241
Chris@462 242 if (v.type == SimpleSPARQLQuery::URIValue && v.value != "") {
Chris@462 243
Chris@462 244 m_pluginInfoURL = v.value;
Chris@462 245
Chris@462 246 } else {
Chris@462 247
Chris@462 248 v = SimpleSPARQLQuery::singleResultQuery
Chris@489 249 (m,
Chris@480 250 QString(
Chris@462 251 " PREFIX vamp: <http://purl.org/ontology/vamp/> "
Chris@462 252 " PREFIX foaf: <http://xmlns.com/foaf/0.1/> "
Chris@489 253 " SELECT ?page "
Chris@462 254 " WHERE { "
Chris@489 255 " ?library vamp:available_plugin <%1> ; "
Chris@489 256 " a vamp:PluginLibrary ; "
Chris@462 257 " foaf:page ?page . "
Chris@462 258 " }")
Chris@489 259 .arg(m_pluginUri),
Chris@489 260 "page");
Chris@462 261
Chris@462 262 if (v.type == SimpleSPARQLQuery::URIValue && v.value != "") {
Chris@462 263
Chris@462 264 m_pluginInfoURL = v.value;
Chris@462 265 }
Chris@462 266 }
Chris@462 267
Chris@457 268 return true;
Chris@457 269 }
Chris@457 270
Chris@457 271 bool
Chris@489 272 PluginRDFDescription::indexOutputs()
Chris@457 273 {
Chris@457 274 Profiler profiler("PluginRDFDescription::indexOutputs");
Chris@489 275
Chris@489 276 SimpleSPARQLQuery::QueryType m = SimpleSPARQLQuery::QueryFromModel;
Chris@457 277
Chris@439 278 SimpleSPARQLQuery query
Chris@489 279 (m,
Chris@480 280 QString
Chris@439 281 (
Chris@439 282 " PREFIX vamp: <http://purl.org/ontology/vamp/> "
Chris@439 283
Chris@440 284 " SELECT ?output ?output_id ?output_type ?unit "
Chris@439 285
Chris@439 286 " WHERE { "
Chris@439 287
Chris@489 288 " <%1> vamp:output ?output . "
Chris@439 289
Chris@439 290 " ?output vamp:identifier ?output_id ; "
Chris@439 291 " a ?output_type . "
Chris@439 292
Chris@439 293 " OPTIONAL { "
Chris@439 294 " ?output vamp:unit ?unit "
Chris@439 295 " } . "
Chris@439 296
Chris@439 297 " } "
Chris@439 298 )
Chris@489 299 .arg(m_pluginUri));
Chris@439 300
Chris@439 301 SimpleSPARQLQuery::ResultList results = query.execute();
Chris@439 302
Chris@439 303 if (!query.isOK()) {
Chris@489 304 cerr << "ERROR: PluginRDFDescription::index: ERROR: Failed to query outputs for <"
Chris@489 305 << m_pluginUri.toStdString() << ">: "
Chris@439 306 << query.getErrorString().toStdString() << endl;
Chris@439 307 return false;
Chris@439 308 }
Chris@439 309
Chris@439 310 if (results.empty()) {
Chris@489 311 cerr << "ERROR: PluginRDFDescription::indexURL: NOTE: No outputs defined for <"
Chris@489 312 << m_pluginUri.toStdString() << ">" << endl;
Chris@439 313 return false;
Chris@439 314 }
Chris@439 315
Chris@439 316 // Note that an output may appear more than once, if it inherits
Chris@439 317 // more than one type (e.g. DenseOutput and QuantizedOutput). So
Chris@439 318 // these results must accumulate
Chris@439 319
Chris@439 320 for (int i = 0; i < results.size(); ++i) {
Chris@439 321
Chris@440 322 QString outputUri = results[i]["output"].value;
Chris@439 323 QString outputId = results[i]["output_id"].value;
Chris@439 324 QString outputType = results[i]["output_type"].value;
Chris@439 325
Chris@494 326 m_outputUriMap[outputId] = outputUri;
Chris@494 327
Chris@439 328 if (outputType.contains("DenseOutput")) {
Chris@439 329 m_outputDispositions[outputId] = OutputDense;
Chris@439 330 } else if (outputType.contains("SparseOutput")) {
Chris@439 331 m_outputDispositions[outputId] = OutputSparse;
Chris@439 332 } else if (outputType.contains("TrackLevelOutput")) {
Chris@439 333 m_outputDispositions[outputId] = OutputTrackLevel;
Chris@457 334 } else {
Chris@457 335 m_outputDispositions[outputId] = OutputDispositionUnknown;
Chris@439 336 }
Chris@439 337
Chris@439 338 if (results[i]["unit"].type == SimpleSPARQLQuery::LiteralValue) {
Chris@439 339
Chris@439 340 QString unit = results[i]["unit"].value;
Chris@439 341
Chris@439 342 if (unit != "") {
Chris@439 343 m_outputUnitMap[outputId] = unit;
Chris@439 344 }
Chris@439 345 }
Chris@440 346
Chris@457 347 SimpleSPARQLQuery::Value v;
Chris@457 348
Chris@457 349 v = SimpleSPARQLQuery::singleResultQuery
Chris@489 350 (m,
Chris@480 351 QString(" PREFIX vamp: <http://purl.org/ontology/vamp/> "
Chris@457 352 " PREFIX dc: <http://purl.org/dc/elements/1.1/> "
Chris@489 353 " SELECT ?title "
Chris@457 354 " WHERE { <%2> dc:title ?title } ")
Chris@489 355 .arg(outputUri), "title");
Chris@457 356
Chris@457 357 if (v.type == SimpleSPARQLQuery::LiteralValue && v.value != "") {
Chris@457 358 m_outputNames[outputId] = v.value;
Chris@457 359 }
Chris@457 360
Chris@440 361 QString queryTemplate =
Chris@440 362 QString(" PREFIX vamp: <http://purl.org/ontology/vamp/> "
Chris@489 363 " SELECT ?%3 "
Chris@440 364 " WHERE { <%2> vamp:computes_%3 ?%3 } ")
Chris@489 365 .arg(outputUri);
Chris@440 366
Chris@440 367 v = SimpleSPARQLQuery::singleResultQuery
Chris@489 368 (m, queryTemplate.arg("event_type"), "event_type");
Chris@440 369
Chris@440 370 if (v.type == SimpleSPARQLQuery::URIValue && v.value != "") {
Chris@440 371 m_outputEventTypeURIMap[outputId] = v.value;
Chris@440 372 }
Chris@440 373
Chris@440 374 v = SimpleSPARQLQuery::singleResultQuery
Chris@507 375 (m, queryTemplate.arg("feature"), "feature");
Chris@440 376
Chris@440 377 if (v.type == SimpleSPARQLQuery::URIValue && v.value != "") {
Chris@440 378 m_outputFeatureAttributeURIMap[outputId] = v.value;
Chris@507 379 }
Chris@440 380
Chris@440 381 v = SimpleSPARQLQuery::singleResultQuery
Chris@489 382 (m, queryTemplate.arg("signal_type"), "signal_type");
Chris@440 383
Chris@440 384 if (v.type == SimpleSPARQLQuery::URIValue && v.value != "") {
Chris@440 385 m_outputSignalTypeURIMap[outputId] = v.value;
Chris@440 386 }
Chris@439 387 }
Chris@439 388
Chris@439 389 return true;
Chris@439 390 }
Chris@439 391