aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlltommy2020-11-13 18:41:08 +0100
committerlltommy2020-11-13 18:41:08 +0100
commitbff4b4af7014fbf325b36e5ee149debe8e5dfd47 (patch)
tree67b8396a71850fa42870cbb091c0e4a0b47febf2
parent87ec8e1d6c5b3ca5375afd4a114f73fad3aa0b68 (diff)
downloadbh20-seq-resource-bff4b4af7014fbf325b36e5ee149debe8e5dfd47.tar.gz
bh20-seq-resource-bff4b4af7014fbf325b36e5ee149debe8e5dfd47.tar.lz
bh20-seq-resource-bff4b4af7014fbf325b36e5ee149debe8e5dfd47.zip
Initial commit: SPARQL playground, which replaces the demo page. Some queries have to be adjusted once changed metadata schema is live
-rw-r--r--bh20simplewebuploader/main.py211
-rw-r--r--bh20simplewebuploader/static/main.css18
-rw-r--r--bh20simplewebuploader/static/main.js84
-rw-r--r--bh20simplewebuploader/templates/demo.html22
-rw-r--r--bh20simplewebuploader/templates/menu.html2
5 files changed, 325 insertions, 12 deletions
diff --git a/bh20simplewebuploader/main.py b/bh20simplewebuploader/main.py
index 0495613..27dcd4b 100644
--- a/bh20simplewebuploader/main.py
+++ b/bh20simplewebuploader/main.py
@@ -949,8 +949,8 @@ def getSEQCountbyLocation():
@app.route('/api/getSEQCountbyContinent', methods=['GET'])
def getSEQCountbyContinent():
query="""SELECT DISTINCT ?continent ?continent_label (count(?fasta) as ?fastaCount) WHERE {
- ?fasta ?x[ <http://purl.obolibrary.org/obo/GAZ_00000448> ?location] .
- ?location <http://www.wikidata.org/prop/direct/P17> ?country .
+ ?fasta ?x [ <http://purl.obolibrary.org/obo/GAZ_00000448> ?location] .
+ ?location <http://www.wikidata.org/prop/direct/P17> ?country .
?country <http://www.wikidata.org/prop/direct/P30> ?continent .
OPTIONAL { ?continent rdfs:label ?key_tmp_label }
BIND(IF(BOUND(?key_tmp_label),?key_tmp_label, ?location) as ?continent_label)
@@ -1064,3 +1064,210 @@ def getSEQbyLocationAndSpecimenSource():
r = requests.get(sparqlURL, params=payload)
result = r.json()['results']['bindings']
return str(result)
+
+
+################## SPARQL PLAYGORUND API function ################
+
+@app.route('/api/demoGetSEQCountbySpecimenSource', methods=['GET'])
+def demoGetSEQCountbySpecimenSource():
+ prefix="""PREFIX obo: <http://purl.obolibrary.org/obo/>
+PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>"""
+
+ query="""SELECT ?specimen_source ?specimen_source_label (count(?seq) as ?seqCount) WHERE
+ {
+ ?seq ?x [obo:OBI_0001479 ?specimen_source] .
+ ?specimen_source rdfs:label ?specimen_source_label
+ }
+ GROUP BY ?specimen_source ?specimen_source_label
+ ORDER BY DESC (?seqCount)
+ """
+
+ description="Get the count of all sequences, grouped by specimen source and specimen label (This is a 1-to-1 relationship). In addition we want to order by the sequence count descending."
+ payload = {'query': prefix+query, 'format': 'json'}
+ r = requests.get(sparqlURL, params=payload)
+ result = r.json()['results']['bindings']
+
+ return jsonify([{'description' : description},{'prefix' : prefix}, {'query': query}],[{'count': x['seqCount']['value'],
+ 'key': x['specimen_source']['value'],
+ 'label': x['specimen_source_label']['value']} for x in result])
+
+
+@app.route('/api/demoGetSEQCountbyLocation', methods=['GET'])
+def demoGetSEQCountbyLocation():
+ prefix="""PREFIX obo: <http://purl.obolibrary.org/obo/>
+PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>"""
+
+ query="""
+ SELECT ?geoLocation ?geoLocation_label (count(?seq) as ?seqCount) WHERE
+ {
+ ?seq ?x [obo:GAZ_00000448 ?geoLocation] .
+ ?geoLocation rdfs:label ?geoLocation_label
+ }
+ GROUP BY ?geoLocation ?geoLocation_label
+ """
+ description = "Get count of all sequences grouped by geoLocation and geoLocation_label (1-to-1 relationship)"
+ payload = {'query': prefix+query, 'format': 'json'}
+ r = requests.get(sparqlURL, params=payload)
+ result = r.json()['results']['bindings']
+ return jsonify([{'description' : description},{'prefix' : prefix}, {'query': query}],[{'count': x['seqCount']['value'],
+ 'key': x['geoLocation']['value'],
+ 'label': x['geoLocation_label']['value']} for x in result])
+
+
+
+@app.route('/api/demoGetAuthors', methods=['GET'])
+def demoGetAuthors():
+ prefix="""PREFIX obo: <http://purl.obolibrary.org/obo/>
+PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
+PREFIX wiki: <http://www.wikidata.org/prop/direct/>"""
+
+ query = """SELECT DISTINCT ?author ?country_label ?continent_label WHERE {
+ ?fasta ?x [ obo:GAZ_00000448 ?location] .
+ ?fasta ?y [ obo:NCIT_C42781 ?author] .
+
+ ?location wiki:P17 ?country .
+ ?country wiki:P30 ?continent .
+ ?country rdfs:label ?country_label .
+ ?continent rdfs:label ?continent_label
+ }
+ ORDER BY ?author
+ LIMIT 500
+ """
+
+ description = "Get all autors (obo:NCIT_C42781) that are in the DB and the country/continent where their samples were taken. The result is limited to 500."
+ payload = {'query': prefix+query, 'format': 'json'}
+ r = requests.get(sparqlURL, params=payload)
+ result = r.json()['results']['bindings']
+ return jsonify([{'description' : description},{'prefix' : prefix}, {'query': query}],[{'author': x['author']['value'],
+ 'country_label': x['country_label']['value'],
+ 'continent_label': x['continent_label']['value']} for x in result])
+
+
+@app.route('/api/demoInstitutesPublications', methods=['GET'])
+def demoInstitutesPublications():
+ prefix="PREFIX obo: <http://purl.obolibrary.org/obo/>"
+ query="""
+ SELECT DISTINCT ?originating_lab ?publication WHERE {
+ ?seq ?x [ obo:NCIT_C37984 ?originating_lab] .
+ ?seq ?y [ obo:NCIT_C19026 ?publication] .
+ }
+ """
+
+ description = "List institutes (originating_lab, obo:NCIT_C37984) associated their publications in the DB"
+ payload = {'query': prefix+query, 'format': 'json'}
+ r = requests.get(sparqlURL, params=payload)
+ result = r.json()['results']['bindings']
+ return jsonify([{'description' : description},{'prefix' : prefix}, {'query': query}],[{'originating_lab': x['originating_lab']['value'],
+ 'publication': x['publication']['value']} for x in result])
+
+
+
+@app.route('/api/demoGetSEQCountbytechContinent', methods=['GET'])
+def demoGetSEQCountbytechContinent():
+ prefix="""PREFIX obo: <http://purl.obolibrary.org/obo/>
+PREFIX wiki: <http://www.wikidata.org/prop/direct/>
+PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>"""
+
+ query="""SELECT DISTINCT ?continent_label ?tech_label (count(?seq) as ?seqCount) WHERE
+ {
+ ?seq ?x [ obo:OBI_0600047 ?tech] .
+ ?seq ?y [ obo:GAZ_00000448 ?location] .
+
+ ?tech rdfs:label ?tech_label .
+
+ ?location wiki:P17 ?country .
+ ?country wiki:P30 ?continent .
+ ?continent rdfs:label ?continent_label
+ }
+
+ GROUP BY ?tech_label ?continent_label
+ ORDER BY ?continent_label ?seqCount
+ """
+
+ description = "List institutes (originating_lab, obo:NCIT_C37984) and their associated publications in the DB"
+ payload = {'query': prefix+query, 'format': 'json'}
+ r = requests.get(sparqlURL, params=payload)
+ result = r.json()['results']['bindings']
+ return jsonify([{'description' : description},{'prefix' : prefix}, {'query': query}],[{'continent_label': x['continent_label']['value'],
+ 'tech_label': x['tech_label']['value'], 'seqCount': x['seqCount']['value']} for x in result])
+
+
+@app.route('/api/demoGetSEQCountbytech', methods=['GET'])
+def dempGetSEQCountbytech():
+ prefix="""PREFIX obo: <http://purl.obolibrary.org/obo/>
+PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>"""
+
+ query="""SELECT ?tech ?tech_label (count(?seq) as ?seqCount) WHERE
+ {
+ ?seq ?x [obo:OBI_0600047 ?tech] .
+ ?tech rdfs:label ?tech_label
+ }
+ GROUP BY ?tech ?tech_label ORDER BY DESC (?seqCount)
+ """
+ description = "Show count per sequence technology"
+ payload = {'query': prefix + query, 'format': 'json'}
+ r = requests.get(sparqlURL, params=payload)
+ result = r.json()['results']['bindings']
+ return jsonify([{'description': description}, {'prefix': prefix}, {'query': query}],
+ [{'tech_label': x['tech_label']['value'],
+ 'tech': x['tech']['value'], 'seqCount': x['seqCount']['value']} for x in result])
+
+
+@app.route('/api/demoGetSequencePerDate', methods=['GET'])
+def demoGetSequencePerDate():
+ prefix=""
+ query="""SELECT ?seq ?date WHERE {
+ ?seq ?a [<http://ncicb.nci.nih.gov/xml/owl/EVS/Thesaurus.owl#C25164> ?date]
+ FILTER ( xsd:date(?date) < xsd:date("2020-03-01") )
+ }
+ ORDER BY ?date"""
+ description = "Show all sequences with a submission date before 2020-03-01! To accomplish this a FILTER expression is used. Since date is a string, we cast xsd:date(...)"
+ payload = {'query': prefix + query, 'format': 'json'}
+ r = requests.get(sparqlURL, params=payload)
+ result = r.json()['results']['bindings']
+ return jsonify([{'description': description}, {'prefix': prefix}, {'query': query}],
+ [{'seq': x['seq']['value'],
+ 'date': x['date']['value']} for x in result])
+
+@app.route('/api/demoLocationGps', methods=['GET'])
+def demoLocationGps():
+ prefix="""PREFIX obo: <http://purl.obolibrary.org/obo/>
+PREFIX wiki: <http://www.wikidata.org/prop/direct/>"""
+
+ query="""SELECT distinct ?location ?GPS WHERE {
+ ?seq ?a [ obo:GAZ_00000448 ?location] .
+ ?location wiki:P625 ?GPS
+ }
+ """
+ description = "Show all locations with their GPS coordinates that we have in the database. GPS coordinates are encoded as Point tuple."
+ payload = {'query': prefix + query, 'format': 'json'}
+ r = requests.get(sparqlURL, params=payload)
+ result = r.json()['results']['bindings']
+ return jsonify([{'description': description}, {'prefix': prefix}, {'query': query}],
+ [{'location': x['location']['value'],
+ 'GPS': x['GPS']['value']} for x in result])
+
+@app.route('/api/getNYsamples', methods=['GET'])
+def getNYsamples():
+ prefix="""PREFIX obo: <http://purl.obolibrary.org/obo/>
+PREFIX wikiE: <http://www.wikidata.org/entity/>"""
+
+ query="""SELECT DISTINCT ?seq ?key_label ?key ?value_label ?value WHERE {
+ ?seq ?x [ obo:GAZ_00000448 wikiE:Q1384] .
+ ?seq ?y [?key ?value] .
+
+ ?key rdfs:label ?key_label .
+ ?value rdfs:label ?value_label
+ }
+ ORDER BY ?seq"""
+
+ description = "Get all samples and their information (key, values) that were taken in New York (Q1384)!"
+ payload = {'query': prefix + query, 'format': 'json'}
+ r = requests.get(sparqlURL, params=payload)
+ result = r.json()['results']['bindings']
+ return jsonify([{'description': description}, {'prefix': prefix}, {'query': query}],
+ [{'seq': x['seq']['value'],
+ 'key_label': x['key_label']['value'],
+ 'key': x['key']['value'],
+ 'value_label': x['value_label']['value'],
+ 'value': x['value']['value']} for x in result]) \ No newline at end of file
diff --git a/bh20simplewebuploader/static/main.css b/bh20simplewebuploader/static/main.css
index 76a1755..36c1a33 100644
--- a/bh20simplewebuploader/static/main.css
+++ b/bh20simplewebuploader/static/main.css
@@ -533,3 +533,21 @@ div.status {
border-bottom: 2px solid white;
padding-bottom: 20px;
}
+
+
+
+/* SPARQL playground CSS*/
+#playground {
+margin-left: 20px;
+}
+
+#playground table{
+border: 1px solid black;
+min-height: 400px;
+}
+
+#playground td{
+border: 1px solid black;
+padding-left:10px;
+padding-right:10px;
+}
diff --git a/bh20simplewebuploader/static/main.js b/bh20simplewebuploader/static/main.js
index 6cc0d9f..0e642c1 100644
--- a/bh20simplewebuploader/static/main.js
+++ b/bh20simplewebuploader/static/main.js
@@ -83,6 +83,48 @@ function fetchHTMLTable(apiEndPoint) {
});
}
+
+
+// changing access for Demo page
+function demofetchHTMLTable(apiEndPoint) {
+ fetch(scriptRoot + apiEndPoint)
+ .then(response => {
+ return response.json();
+ })
+ .then(data => {
+ htmlString="<h3>Description</h3><p>"+data[0][0]["description"]+"</p>"
+ prefix=data[0][1]["prefix"].replaceAll("<","&lt;")
+ htmlString+="<h4>Namespace</h4><pre>"+prefix+"</pre>"//prefix to construct correct query @data[0][1]["prefix"]
+ htmlString+="<h3>SPARQL query</h3><pre>"+data[0][2]["query"]+"</pre>"
+ htmlString+="<h3>SPARQL results table</h3><table>"
+
+ keys=Object.keys(data[1][0])
+ // Add keys as table headers
+ htmlString+="<tr>"
+ for (var j=0; j<keys.length;j++){
+ htmlString+="<td style='font-weight: bold;'>"+keys[j]+"</bold></td>"
+ }
+
+ //Go through the results set given the keys and fill the tail of the table
+ for (var i=0; i<data[1].length;i++) {
+ htmlString+="</tr><tr>"
+ for (var j=0; j<keys.length;j++){
+ htmlString+="<td>"+data[1][i][keys[j]]+"</td>"
+ }
+ htmlString+="</tr>"
+ }
+ htmlString=htmlString+"</table>"
+
+ //Something like this would be nice, hm
+ //htmlString+="Execute this query <a href='http://sparql.genenetwork.org/sparql?query='"+encodeURIComponent(encodeURIComponent(data[0][1]["prefix"]+data[0][2]["query"]))+"'>here</a>"
+
+ document.getElementById("playground").innerHTML = htmlString
+ });
+}
+
+
+
+
/* Fetch record info using a 'global search'. Returns for example
[
@@ -122,14 +164,50 @@ let fetchCountDB = () => {
fetchAPI("/api/getCountDB");
}
-let fetchSEQCountBySpecimen = () => {
- fetchHTMLTable("/api/getSEQCountbySpecimenSource");
+
+//****** SPARQL playground functions // keep old functionality as comments for now, might be transfered elsewhere
+let fetchSEQCountBySpecimen = (toHTML) => {
+ //fetchHTMLTable("/api/getSEQCountbySpecimenSource");
+ demofetchHTMLTable("/api/demoGetSEQCountbySpecimenSource")
}
let fetchSEQCountByLocation = () => {
- fetchHTMLTable("/api/getSEQCountbyLocation");
+ //fetchHTMLTable("/api/getSEQCountbyLocation");
+ demofetchHTMLTable("/api/demoGetSEQCountbyLocation")
+}
+
+//Get authors and there country/contitent where they come from
+let fetchAuthors = () => {
+ demofetchHTMLTable("/api/demoGetAuthors")
+}
+
+// Fetch all institutes/originating labs and their associeted publications
+let fetchInstitutesPublications = () => {
+ demofetchHTMLTable("/api/demoInstitutesPublications")
+}
+
+//Fetch seqeenctechnologies used by continent
+let demoGetSEQCountbytechContinent = () => {
+ demofetchHTMLTable("/api/demoGetSEQCountbytechContinent")
+}
+
+let demoGetSEQCountbytech = () => {
+ demofetchHTMLTable("/api/demoGetSEQCountbytech")
+}
+
+let demoGetSequencePerDate = () => {
+ demofetchHTMLTable('/api/demoGetSequencePerDate')
+}
+
+let demoLocationGps = () => {
+ demofetchHTMLTable("/api/demoLocationGps")
+}
+
+let getNYsamples = () => {
+ demofetchHTMLTable("/api/getNYsamples")
}
+//old/unused functions
let fetchSEQCountByTech = () => {
fetchHTMLTable("/api/getSEQCountbytech");
}
diff --git a/bh20simplewebuploader/templates/demo.html b/bh20simplewebuploader/templates/demo.html
index 1edca00..ffebc91 100644
--- a/bh20simplewebuploader/templates/demo.html
+++ b/bh20simplewebuploader/templates/demo.html
@@ -5,7 +5,7 @@
{% include 'banner.html' %}
{% include 'menu.html' %}
- <p>The Virtuoso database contains <span id="CounterDB"></span> public sequences! The examples here should provide a starting point to explore our data in our public <a href="http://sparql.genenetwork.org/sparql">SPARQL endpoint</a> or via <a href="https://covid-19-sparql.expasy.org/">SIB COVID-19 Integrated Knowledgebase</a>. See also our documentation <a href="http://127.0.0.1:5000/blog?id=using-covid-19-pubseq-part1">here</a> for more information!</p>
+ <p>The Virtuoso database contains <span id="CounterDB"></span> public sequences! The examples here should provide a starting point to explore our data in our public <a href="http://sparql.genenetwork.org/sparql">SPARQL endpoint</a> or via <a href="https://covid-19-sparql.expasy.org/">SIB COVID-19 Integrated Knowledgebase</a>. See also our documentation <a href="http://covid-19.genenetwork.org/blog?id=using-covid-19-pubseq-part1">here</a> for more information!</p>
<!--
<div class="search">
<input id="search-input" type="search" placeholder="FASTA uri" required>
@@ -21,11 +21,21 @@
<section class="search-section">
<div class="filter-options" action="#">
<div>
- <button class="button" onclick="fetchSEQCountBySpecimen()">Count by Specimen source</button>
<button class="button" onclick="fetchSEQCountByLocation()">Count by Location</button>
- <button class="button" onclick="fetchSEQCountByTech()">Count by Sequencer</button>
- <!-- <button class="button" onclick="fetchAllaccessions()">Show All accessions</button> -->
- <button class="button" onclick="fetchSEQCountbyContinent()">Count by Continent</button>
+ <button class="button" onclick="demoGetSEQCountbytech()">Count by Sequencer</button>
+ <button class="button" onclick="fetchInstitutesPublications()">Get list of publications</button>
+ <button class="button" onclick="fetchSEQCountBySpecimen()">Count by Specimen source</button>
+ <button class="button" onclick="demoGetSEQCountbytechContinent()">Sequence Technologies used by continent</button>
+ <button class="button" onclick="getNYsamples()">Get all NY samples</button>
+ <button class="button" onclick="fetchAuthors()">Get authors</button>
+ <button class="button" onclick="demoGetSequencePerDate()">Show Sequences before submission date</button>
+ <button class="button" onclick="demoLocationGps()">Locations and their GPS</button>
+
+
+
+
+ <!-- <button class="button" onclick="fetchAllaccessions()">Show All accessions</button>
+ <button class="button" onclick="fetchSEQCountbyContinent()">Count by Continent</button>-->
</div>
</div>
@@ -36,7 +46,7 @@
<section>
- <div id="table"></div>
+ <div id="playground"></div>
</section>
{% include 'footer.html' %}
diff --git a/bh20simplewebuploader/templates/menu.html b/bh20simplewebuploader/templates/menu.html
index 8e6ef52..cf32fec 100644
--- a/bh20simplewebuploader/templates/menu.html
+++ b/bh20simplewebuploader/templates/menu.html
@@ -4,7 +4,7 @@
<a href="/download" class="{{ 'active' if menu=='DOWNLOAD' }}">DOWNLOAD</a>
<a href="/upload" class="{{ 'active' if menu=='UPLOAD' }}">UPLOAD</a>
<a href="/status" class="{{ 'active' if menu=='STATUS' }}">STATUS</a>
- <a href="/demo" class="{{ 'active' if menu=='DEMO' }}">DEMO</a>
+ <a href="/demo" class="{{ 'active' if menu=='DEMO' }}">SPARQL-PLAYGROUND</a>
<a href="/export" class="{{ 'active' if menu=='EXPORT' }}">EXPORT</a>
<a href="/blog" class="{{ 'active' if menu=='BLOG' }}">DOCS</a>
<a href="/about" class="{{ 'active' if menu=='ABOUT' }}">ABOUT</a>