changeset 494:81963c51b488

* Add ability to export a transform structure as RDF -- for use when exporting data from runner, so as to refer back to the generating transform from the audio features rdf * some improvements to pane & layer management when importing rdf, but it's all still a big hack here
author Chris Cannam
date Tue, 25 Nov 2008 17:46:02 +0000 (2008-11-25)
parents 3931711b5671
children 438f4e295a9c
files base/RealTime.cpp base/RealTime.h rdf/PluginRDFDescription.cpp rdf/PluginRDFDescription.h rdf/RDFTransformFactory.cpp rdf/RDFTransformFactory.h rdf/SimpleSPARQLQuery.cpp transform/TransformFactory.cpp
diffstat 8 files changed, 118 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/base/RealTime.cpp	Tue Nov 25 13:43:56 2008 +0000
+++ b/base/RealTime.cpp	Tue Nov 25 17:46:02 2008 +0000
@@ -342,6 +342,13 @@
     return s;
 }
 
+std::string
+RealTime::toXsdDuration() const
+{
+    std::string s = "PT" + toString(false) + "S";
+    return s;
+}
+
 RealTime
 RealTime::operator*(int m) const
 {
--- a/base/RealTime.h	Tue Nov 25 13:43:56 2008 +0000
+++ b/base/RealTime.h	Tue Nov 25 17:46:02 2008 +0000
@@ -133,6 +133,11 @@
     std::string toSecText() const;
 
     /**
+     * Return a string in xsd:duration format.
+     */
+    std::string toXsdDuration() const;
+
+    /**
      * Convert a RealTime into a sample frame at the given sample rate.
      */
     static long realTime2Frame(const RealTime &r, unsigned int sampleRate);
--- a/rdf/PluginRDFDescription.cpp	Tue Nov 25 13:43:56 2008 +0000
+++ b/rdf/PluginRDFDescription.cpp	Tue Nov 25 17:46:02 2008 +0000
@@ -149,6 +149,15 @@
     return m_outputUnitMap.find(outputId)->second;
 }
 
+QString
+PluginRDFDescription::getOutputUri(QString outputId) const
+{
+    if (m_outputUriMap.find(outputId) == m_outputUriMap.end()) {
+        return "";
+    }
+    return m_outputUriMap.find(outputId)->second;
+}
+
 bool
 PluginRDFDescription::index() 
 {
@@ -314,6 +323,8 @@
         QString outputId = results[i]["output_id"].value;
         QString outputType = results[i]["output_type"].value;
 
+        m_outputUriMap[outputId] = outputUri;
+
         if (outputType.contains("DenseOutput")) {
             m_outputDispositions[outputId] = OutputDense;
         } else if (outputType.contains("SparseOutput")) {
--- a/rdf/PluginRDFDescription.h	Tue Nov 25 13:43:56 2008 +0000
+++ b/rdf/PluginRDFDescription.h	Tue Nov 25 17:46:02 2008 +0000
@@ -49,6 +49,7 @@
     QString getOutputFeatureAttributeURI(QString outputId) const;
     QString getOutputSignalTypeURI(QString outputId) const;
     QString getOutputUnit(QString outputId) const;
+    QString getOutputUri(QString outputId) const;
 
 protected:    
     typedef std::map<QString, OutputDisposition> OutputDispositionMap;
@@ -67,6 +68,7 @@
     OutputStringMap m_outputFeatureAttributeURIMap;
     OutputStringMap m_outputSignalTypeURIMap;
     OutputStringMap m_outputUnitMap;
+    OutputStringMap m_outputUriMap;
     bool index();
     bool indexMetadata();
     bool indexOutputs();
--- a/rdf/RDFTransformFactory.cpp	Tue Nov 25 13:43:56 2008 +0000
+++ b/rdf/RDFTransformFactory.cpp	Tue Nov 25 17:46:02 2008 +0000
@@ -18,11 +18,14 @@
 #include <map>
 #include <vector>
 
+#include <QTextStream>
+
 #include <iostream>
 #include <cmath>
 
 #include "SimpleSPARQLQuery.h"
 #include "PluginRDFIndexer.h"
+#include "PluginRDFDescription.h"
 #include "base/ProgressReporter.h"
 
 #include "transform/TransformFactory.h"
@@ -45,6 +48,8 @@
 
     std::vector<Transform> getTransforms(ProgressReporter *);
 
+    static QString writeTransformToRDF(const Transform &, QString);
+
 protected:
     QString m_urlString;
     QString m_errorString;
@@ -94,6 +99,12 @@
     return m_d->getTransforms(r);
 }
 
+QString
+RDFTransformFactory::writeTransformToRDF(const Transform &t, QString f)
+{
+    return RDFTransformFactoryImpl::writeTransformToRDF(t, f);
+}
+
 RDFTransformFactoryImpl::RDFTransformFactoryImpl(QString url) :
     m_urlString(url),
     m_isRDF(false)
@@ -160,7 +171,7 @@
     }
 
     // There are various queries we need to make that might include
-    // data from iether the transform RDF or the model accumulated
+    // data from either the transform RDF or the model accumulated
     // from plugin descriptions.  For example, the transform RDF may
     // specify the output's true URI, or it might have a blank node or
     // some other URI with the appropriate vamp:identifier included in
@@ -292,46 +303,26 @@
          (
              " PREFIX vamp: <http://purl.org/ontology/vamp/> "
              
-             " SELECT ?output "
+             " SELECT ?output_id "
 
              " WHERE { "
              "   <%1> vamp:output ?output . "
+             "   ?output vamp:identifier ?output_id "
              " } "
              )
          .arg(transformUri),
-         "output");
+         "output_id");
     
     if (outputValue.type == SimpleSPARQLQuery::NoValue) {
         return true;
     }
-
-    if (outputValue.type != SimpleSPARQLQuery::URIValue) {
-        m_errorString = QString("vamp:output given for transform <%1> is not a URI").arg(transformUri);
+    
+    if (outputValue.type != SimpleSPARQLQuery::LiteralValue) {
+        m_errorString = QString("No vamp:identifier found for output of transform <%1>, or vamp:identifier is not a literal").arg(transformUri);
         return false;
     }
 
-    SimpleSPARQLQuery::Value outputIdValue =
-        SimpleSPARQLQuery::singleResultQuery
-        (SimpleSPARQLQuery::QueryFromModel,
-         QString
-         (
-             " PREFIX vamp: <http://purl.org/ontology/vamp/> "
-             
-             " SELECT ?output_id "
-             
-             " WHERE { "
-             "   <%1> vamp:identifier ?output_id "
-             " } "
-             )
-         .arg(outputValue.value),
-         "output_id");
-    
-    if (outputIdValue.type != SimpleSPARQLQuery::LiteralValue) {
-        m_errorString = QString("No vamp:identifier found for output <%1>, or vamp:identifier is not a literal").arg(outputValue.value);
-        return false;
-    }
-
-    transform.setOutput(outputIdValue.value);
+    transform.setOutput(outputValue.value);
 
     return true;
 }
@@ -383,3 +374,68 @@
     return true;
 }
 
+QString
+RDFTransformFactoryImpl::writeTransformToRDF(const Transform &transform,
+                                             QString uri)
+{
+    QString str;
+    QTextStream s(&str);
+
+    // assumes the usual prefixes are available
+
+    s << uri << " a vamp:Transform ;" << endl;
+
+    QString pluginId = transform.getPluginIdentifier();
+    QString pluginUri = PluginRDFIndexer::getInstance()->getURIForPluginId(pluginId);
+
+    PluginRDFDescription description(pluginId);
+    QString outputUri = description.getOutputUri(transform.getOutput());
+
+    if (transform.getOutput() != "" && outputUri == "") {
+        std::cerr << "WARNING: RDFTransformFactory::writeTransformToRDF: No output URI available for transform output id \"" << transform.getOutput().toStdString() << "\"" << std::endl;
+    }
+
+    s << "    vamp:plugin <" << pluginUri << "> ;" << endl;
+
+    if (transform.getStepSize() != 0) {
+        s << "    vamp:step_size \"" << transform.getStepSize() << "\"^^xsd:int ; " << endl;
+    }
+    if (transform.getBlockSize() != 0) {
+        s << "    vamp:block_size \"" << transform.getBlockSize() << "\"^^xsd:int ; " << endl;
+    }
+    if (transform.getStartTime() != RealTime::zeroTime) {
+        s << "    vamp:start \"" << transform.getStartTime().toXsdDuration().c_str() << "\"^^xsd:duration ; " << endl;
+    }
+    if (transform.getDuration() != RealTime::zeroTime) {
+        s << "    vamp:duration \"" << transform.getDuration().toXsdDuration().c_str() << "\"^^xsd:duration ; " << endl;
+    }
+    if (transform.getSampleRate() != 0) {
+        s << "    vamp:sample_rate \"" << transform.getSampleRate() << "\"^^xsd:float ; " << endl;
+    }
+    
+    QString program = transform.getProgram();
+
+    if (program != "") {
+        s << "    vamp:program \"\"\"" << program << "\"\"\" ;" << endl;
+    }
+
+    Transform::ParameterMap parameters = transform.getParameters();
+    for (Transform::ParameterMap::const_iterator i = parameters.begin();
+         i != parameters.end(); ++i) {
+        QString name = i->first;
+        float value = i->second;
+        s << "    vamp:parameter_binding [" << endl;
+        s << "        vamp:parameter [ vamp:identifier \"" << name << "\" ] ;" << endl;
+        s << "        vamp:value \"" << value << "\"^^xsd:float ;" << endl;
+        s << "    ] ;" << endl;
+    }
+
+    if (outputUri != "") {
+        s << "    vamp:output <" << outputUri << "> ." << endl;
+    } else {
+        s << "    ." << endl;
+    }
+
+    return str;
+}
+
--- a/rdf/RDFTransformFactory.h	Tue Nov 25 13:43:56 2008 +0000
+++ b/rdf/RDFTransformFactory.h	Tue Nov 25 17:46:02 2008 +0000
@@ -42,6 +42,8 @@
 
     std::vector<Transform> getTransforms(ProgressReporter *reporter);
 
+    static QString writeTransformToRDF(const Transform &, QString uri);
+
 protected:
     RDFTransformFactoryImpl *m_d;
 };
--- a/rdf/SimpleSPARQLQuery.cpp	Tue Nov 25 13:43:56 2008 +0000
+++ b/rdf/SimpleSPARQLQuery.cpp	Tue Nov 25 17:46:02 2008 +0000
@@ -516,6 +516,9 @@
 
                 type = BlankValue;
 
+                const char *lit = (const char *)librdf_node_get_literal_value(node);
+                if (lit) text = lit;
+
             } else {
 
                 cerr << "SimpleSPARQLQuery: LIBRDF query returned unknown node type (not resource, literal, or blank)" << endl;
--- a/transform/TransformFactory.cpp	Tue Nov 25 13:43:56 2008 +0000
+++ b/transform/TransformFactory.cpp	Tue Nov 25 17:46:02 2008 +0000
@@ -637,8 +637,8 @@
             TransformId tid = Transform::getIdentifierForPluginOutput(*i, *j);
             
             if (m_transforms.find(tid) != m_transforms.end()) {
-                std::cerr << "TransformFactory::populateUninstalledTransforms: "
-                          << tid.toStdString() << " is installed; adding info url if appropriate, skipping rest" << std::endl;
+//                std::cerr << "TransformFactory::populateUninstalledTransforms: "
+//                          << tid.toStdString() << " is installed; adding info url if appropriate, skipping rest" << std::endl;
                 if (infoUrl != "") {
                     if (m_transforms[tid].infoUrl == "") {
                         m_transforms[tid].infoUrl = infoUrl;
@@ -647,8 +647,8 @@
                 continue;
             }
 
-            std::cerr << "TransformFactory::populateUninstalledTransforms: "
-                      << "adding " << tid.toStdString() << std::endl;
+//            std::cerr << "TransformFactory::populateUninstalledTransforms: "
+//                      << "adding " << tid.toStdString() << std::endl;
 
             QString oname = desc.getOutputName(*j);
             if (oname == "") oname = *j;