Mercurial > hg > svcore
comparison rdf/RDFImporter.cpp @ 499:b71116d3c180
* Much more sensible pane layouts, etc., when loading RDF; also offer
choice of adding to current session or starting new session if RDF
references audio (needs some refinement)
author | Chris Cannam |
---|---|
date | Fri, 28 Nov 2008 15:45:20 +0000 |
parents | 3931711b5671 |
children | 83eae5239db6 |
comparison
equal
deleted
inserted
replaced
498:fdf5930b7ccc | 499:b71116d3c180 |
---|---|
29 #include "data/model/SparseOneDimensionalModel.h" | 29 #include "data/model/SparseOneDimensionalModel.h" |
30 #include "data/model/SparseTimeValueModel.h" | 30 #include "data/model/SparseTimeValueModel.h" |
31 #include "data/model/EditableDenseThreeDimensionalModel.h" | 31 #include "data/model/EditableDenseThreeDimensionalModel.h" |
32 #include "data/model/NoteModel.h" | 32 #include "data/model/NoteModel.h" |
33 #include "data/model/RegionModel.h" | 33 #include "data/model/RegionModel.h" |
34 #include "data/model/WaveFileModel.h" | |
35 | |
36 #include "data/fileio/FileSource.h" | |
34 | 37 |
35 using std::cerr; | 38 using std::cerr; |
36 using std::endl; | 39 using std::endl; |
37 | 40 |
38 class RDFImporterImpl | 41 class RDFImporterImpl |
44 void setSampleRate(int sampleRate) { m_sampleRate = sampleRate; } | 47 void setSampleRate(int sampleRate) { m_sampleRate = sampleRate; } |
45 | 48 |
46 bool isOK(); | 49 bool isOK(); |
47 QString getErrorString() const; | 50 QString getErrorString() const; |
48 | 51 |
49 QString getAudioAvailableUrl() const { return m_audioAvailableAt; } | |
50 | |
51 std::vector<Model *> getDataModels(ProgressReporter *); | 52 std::vector<Model *> getDataModels(ProgressReporter *); |
52 | 53 |
53 protected: | 54 protected: |
54 QString m_uristring; | 55 QString m_uristring; |
55 QString m_errorString; | 56 QString m_errorString; |
56 QString m_audioAvailableAt; | 57 std::map<QString, Model *> m_audioModelMap; |
57 int m_sampleRate; | 58 int m_sampleRate; |
58 | 59 |
60 void getDataModelsAudio(std::vector<Model *> &, ProgressReporter *); | |
59 void getDataModelsSparse(std::vector<Model *> &, ProgressReporter *); | 61 void getDataModelsSparse(std::vector<Model *> &, ProgressReporter *); |
60 void getDataModelsDense(std::vector<Model *> &, ProgressReporter *); | 62 void getDataModelsDense(std::vector<Model *> &, ProgressReporter *); |
61 | 63 |
62 void getDenseModelTitle(Model *, QString, QString); | 64 void getDenseModelTitle(Model *, QString, QString); |
63 | 65 |
64 void getDenseFeatureProperties(QString featureUri, | 66 void getDenseFeatureProperties(QString featureUri, |
65 int &sampleRate, int &windowLength, | 67 int &sampleRate, int &windowLength, |
66 int &hopSize, int &width, int &height); | 68 int &hopSize, int &width, int &height); |
67 | 69 |
68 | |
69 void fillModel(Model *, long, long, bool, std::vector<float> &, QString); | 70 void fillModel(Model *, long, long, bool, std::vector<float> &, QString); |
70 }; | 71 }; |
71 | 72 |
72 | 73 |
73 QString | 74 QString |
100 | 101 |
101 QString | 102 QString |
102 RDFImporter::getErrorString() const | 103 RDFImporter::getErrorString() const |
103 { | 104 { |
104 return m_d->getErrorString(); | 105 return m_d->getErrorString(); |
105 } | |
106 | |
107 QString | |
108 RDFImporter::getAudioAvailableUrl() const | |
109 { | |
110 return m_d->getAudioAvailableUrl(); | |
111 } | 106 } |
112 | 107 |
113 std::vector<Model *> | 108 std::vector<Model *> |
114 RDFImporter::getDataModels(ProgressReporter *r) | 109 RDFImporter::getDataModels(ProgressReporter *r) |
115 { | 110 { |
118 | 113 |
119 RDFImporterImpl::RDFImporterImpl(QString uri, int sampleRate) : | 114 RDFImporterImpl::RDFImporterImpl(QString uri, int sampleRate) : |
120 m_uristring(uri), | 115 m_uristring(uri), |
121 m_sampleRate(sampleRate) | 116 m_sampleRate(sampleRate) |
122 { | 117 { |
123 SimpleSPARQLQuery::Value value = | |
124 SimpleSPARQLQuery::singleResultQuery | |
125 (SimpleSPARQLQuery::QueryFromSingleSource, | |
126 QString | |
127 (" PREFIX mo: <http://purl.org/ontology/mo/> " | |
128 " SELECT ?url FROM <%1> " | |
129 " WHERE { ?signal a mo:Signal ; mo:available_as ?url } " | |
130 ).arg(m_uristring), | |
131 "url"); | |
132 | |
133 if (value.type == SimpleSPARQLQuery::URIValue) { | |
134 m_audioAvailableAt = value.value; | |
135 } | |
136 } | 118 } |
137 | 119 |
138 RDFImporterImpl::~RDFImporterImpl() | 120 RDFImporterImpl::~RDFImporterImpl() |
139 { | 121 { |
140 SimpleSPARQLQuery::closeSingleSource(m_uristring); | 122 SimpleSPARQLQuery::closeSingleSource(m_uristring); |
154 | 136 |
155 std::vector<Model *> | 137 std::vector<Model *> |
156 RDFImporterImpl::getDataModels(ProgressReporter *reporter) | 138 RDFImporterImpl::getDataModels(ProgressReporter *reporter) |
157 { | 139 { |
158 std::vector<Model *> models; | 140 std::vector<Model *> models; |
141 | |
142 getDataModelsAudio(models, reporter); | |
159 | 143 |
160 if (m_sampleRate == 0) { | 144 if (m_sampleRate == 0) { |
161 std::cerr << "RDFImporter::getDataModels: invalid sample rate" << std::endl; | 145 std::cerr << "RDFImporter::getDataModels: invalid sample rate" << std::endl; |
162 return models; | 146 return models; |
163 } | 147 } |
174 | 158 |
175 return models; | 159 return models; |
176 } | 160 } |
177 | 161 |
178 void | 162 void |
163 RDFImporterImpl::getDataModelsAudio(std::vector<Model *> &models, | |
164 ProgressReporter *reporter) | |
165 { | |
166 SimpleSPARQLQuery query = SimpleSPARQLQuery | |
167 (SimpleSPARQLQuery::QueryFromSingleSource, | |
168 QString | |
169 ( | |
170 " PREFIX mo: <http://purl.org/ontology/mo/> " | |
171 " SELECT ?signal ?source FROM <%1> " | |
172 " WHERE { ?signal a mo:Signal ; mo:available_as ?source } " | |
173 ) | |
174 .arg(m_uristring)); | |
175 | |
176 SimpleSPARQLQuery::ResultList results = query.execute(); | |
177 | |
178 for (int i = 0; i < results.size(); ++i) { | |
179 | |
180 QString signal = results[i]["signal"].value; | |
181 QString source = results[i]["source"].value; | |
182 | |
183 FileSource fs(source, reporter); | |
184 if (fs.isAvailable()) { | |
185 if (reporter) { | |
186 reporter->setMessage(RDFImporter::tr("Importing audio referenced in RDF...")); | |
187 } | |
188 fs.waitForData(); | |
189 WaveFileModel *newModel = new WaveFileModel(fs, m_sampleRate); | |
190 if (newModel->isOK()) { | |
191 std::cerr << "Successfully created wave file model from source at \"" << source.toStdString() << "\"" << std::endl; | |
192 models.push_back(newModel); | |
193 m_audioModelMap[signal] = newModel; | |
194 if (m_sampleRate == 0) { | |
195 m_sampleRate = newModel->getSampleRate(); | |
196 } | |
197 } else { | |
198 std::cerr << "Failed to create wave file model from source at \"" << source.toStdString() << "\"" << std::endl; | |
199 delete newModel; | |
200 } | |
201 } | |
202 } | |
203 } | |
204 | |
205 void | |
179 RDFImporterImpl::getDataModelsDense(std::vector<Model *> &models, | 206 RDFImporterImpl::getDataModelsDense(std::vector<Model *> &models, |
180 ProgressReporter *reporter) | 207 ProgressReporter *reporter) |
181 { | 208 { |
209 if (reporter) { | |
210 reporter->setMessage(RDFImporter::tr("Importing dense signal data from RDF...")); | |
211 } | |
212 | |
182 SimpleSPARQLQuery query = SimpleSPARQLQuery | 213 SimpleSPARQLQuery query = SimpleSPARQLQuery |
183 (SimpleSPARQLQuery::QueryFromSingleSource, | 214 (SimpleSPARQLQuery::QueryFromSingleSource, |
184 QString | 215 QString |
185 ( | 216 ( |
186 " PREFIX mo: <http://purl.org/ontology/mo/>" | 217 " PREFIX mo: <http://purl.org/ontology/mo/>" |
431 | 462 |
432 void | 463 void |
433 RDFImporterImpl::getDataModelsSparse(std::vector<Model *> &models, | 464 RDFImporterImpl::getDataModelsSparse(std::vector<Model *> &models, |
434 ProgressReporter *reporter) | 465 ProgressReporter *reporter) |
435 { | 466 { |
467 if (reporter) { | |
468 reporter->setMessage(RDFImporter::tr("Importing event data from RDF...")); | |
469 } | |
470 | |
436 SimpleSPARQLQuery::QueryType s = SimpleSPARQLQuery::QueryFromSingleSource; | 471 SimpleSPARQLQuery::QueryType s = SimpleSPARQLQuery::QueryFromSingleSource; |
437 | 472 |
438 // Our query is intended to retrieve every thing that has a time, | 473 // Our query is intended to retrieve every thing that has a time, |
439 // and every feature type and value associated with a thing that | 474 // and every feature type and value associated with a thing that |
440 // has a time. | 475 // has a time. |
473 " PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>" | 508 " PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>" |
474 ); | 509 ); |
475 | 510 |
476 QString queryString = prefixes + QString( | 511 QString queryString = prefixes + QString( |
477 | 512 |
478 " SELECT ?signal_source ?timed_thing ?event_type ?value" | 513 " SELECT ?signal ?timed_thing ?event_type ?value" |
479 " FROM <%1>" | 514 " FROM <%1>" |
480 | 515 |
481 " WHERE {" | 516 " WHERE {" |
482 | 517 |
483 " ?signal mo:available_as ?signal_source ." | |
484 " ?signal a mo:Signal ." | 518 " ?signal a mo:Signal ." |
485 | 519 |
486 " ?signal mo:time ?interval ." | 520 " ?signal mo:time ?interval ." |
487 " ?interval tl:onTimeLine ?tl ." | 521 " ?interval tl:onTimeLine ?tl ." |
488 " ?time tl:onTimeLine ?tl ." | 522 " ?time tl:onTimeLine ?tl ." |
541 if (query.wasCancelled()) { | 575 if (query.wasCancelled()) { |
542 m_errorString = "Query cancelled"; | 576 m_errorString = "Query cancelled"; |
543 return; | 577 return; |
544 } | 578 } |
545 | 579 |
546 | |
547 | |
548 /* | 580 /* |
549 | |
550 This function is now only used for sparse data (for dense data | 581 This function is now only used for sparse data (for dense data |
551 we would be in getDataModelsDense instead). | 582 we would be in getDataModelsDense instead). |
552 | 583 |
553 For sparse data, the determining factors in deciding what model | 584 For sparse data, the determining factors in deciding what model |
554 to use are: Do the features have values? and Do the features | 585 to use are: Do the features have values? and Do the features |
564 | 595 |
565 What we _could_ do is to create one of each type of model at the | 596 What we _could_ do is to create one of each type of model at the |
566 start, for each of the source+type keys, and then push each | 597 start, for each of the source+type keys, and then push each |
567 feature into the relevant model depending on what we find out | 598 feature into the relevant model depending on what we find out |
568 about it. Then return only non-empty models. | 599 about it. Then return only non-empty models. |
569 | |
570 | |
571 */ | 600 */ |
572 | 601 |
573 // Map from signal source to event type to dimensionality to | 602 // Map from signal source to event type to dimensionality to |
574 // presence of duration to model ptr. Whee! | 603 // presence of duration to model ptr. Whee! |
575 std::map<QString, std::map<QString, std::map<int, std::map<bool, Model *> > > > | 604 std::map<QString, std::map<QString, std::map<int, std::map<bool, Model *> > > > |
576 modelMap; | 605 modelMap; |
577 | 606 |
578 for (int i = 0; i < results.size(); ++i) { | 607 for (int i = 0; i < results.size(); ++i) { |
579 | 608 |
580 QString source = results[i]["signal_source"].value; | 609 if (i % 4 == 0) { |
610 if (reporter) reporter->setProgress(i/4); | |
611 } | |
612 | |
613 QString source = results[i]["signal"].value; | |
581 QString type = results[i]["event_type"].value; | 614 QString type = results[i]["event_type"].value; |
582 QString thinguri = results[i]["timed_thing"].value; | 615 QString thinguri = results[i]["timed_thing"].value; |
583 | 616 |
584 RealTime time; | 617 RealTime time; |
585 RealTime duration; | 618 RealTime duration; |
686 // std::cerr << "NoteModel" << std::endl; | 719 // std::cerr << "NoteModel" << std::endl; |
687 model = new NoteModel(m_sampleRate, 1, false); | 720 model = new NoteModel(m_sampleRate, 1, false); |
688 } | 721 } |
689 } | 722 } |
690 | 723 |
724 if (m_audioModelMap.find(source) != m_audioModelMap.end()) { | |
725 std::cerr << "source model for " << model << " is " << m_audioModelMap[source] << std::endl; | |
726 model->setSourceModel(m_audioModelMap[source]); | |
727 } | |
728 | |
691 QString titleQuery = QString | 729 QString titleQuery = QString |
692 ( | 730 ( |
693 " PREFIX dc: <http://purl.org/dc/elements/1.1/> " | 731 " PREFIX dc: <http://purl.org/dc/elements/1.1/> " |
694 " SELECT ?title " | 732 " SELECT ?title " |
695 " FROM <%1> " | 733 " FROM <%1> " |
803 RDFImporter::identifyDocumentType(QString url) | 841 RDFImporter::identifyDocumentType(QString url) |
804 { | 842 { |
805 bool haveAudio = false; | 843 bool haveAudio = false; |
806 bool haveAnnotations = false; | 844 bool haveAnnotations = false; |
807 | 845 |
846 // This query is not expected to return any values, but if it | |
847 // executes successfully (leaving no error in the error string) | |
848 // then we know we have RDF | |
849 SimpleSPARQLQuery q(SimpleSPARQLQuery::QueryFromSingleSource, | |
850 QString(" SELECT ?x FROM <%1> WHERE { ?x <y> <z> } ") | |
851 .arg(url)); | |
852 | |
853 SimpleSPARQLQuery::ResultList r = q.execute(); | |
854 if (!q.isOK()) { | |
855 return NotRDF; | |
856 } | |
857 | |
808 SimpleSPARQLQuery::Value value = | 858 SimpleSPARQLQuery::Value value = |
809 SimpleSPARQLQuery::singleResultQuery | 859 SimpleSPARQLQuery::singleResultQuery |
810 (SimpleSPARQLQuery::QueryFromSingleSource, | 860 (SimpleSPARQLQuery::QueryFromSingleSource, |
811 QString | 861 QString |
812 (" PREFIX mo: <http://purl.org/ontology/mo/> " | 862 (" PREFIX mo: <http://purl.org/ontology/mo/> " |
858 } | 908 } |
859 } else { | 909 } else { |
860 if (haveAnnotations) { | 910 if (haveAnnotations) { |
861 return Annotations; | 911 return Annotations; |
862 } else { | 912 } else { |
863 return OtherDocument; | 913 return OtherRDFDocument; |
864 } | 914 } |
865 } | 915 } |
866 | 916 |
867 SimpleSPARQLQuery::closeSingleSource(url); | 917 SimpleSPARQLQuery::closeSingleSource(url); |
868 } | 918 } |