diff options
-rwxr-xr-x | ratspub.py | 27 | ||||
-rwxr-xr-x | server.py | 43 | ||||
-rw-r--r-- | templates/cytoscape.html | 10 | ||||
-rw-r--r-- | templates/index.html | 16 | ||||
-rw-r--r-- | templates/layout.html | 4 | ||||
-rw-r--r-- | templates/sentences.html | 3 |
6 files changed, 61 insertions, 42 deletions
@@ -3,6 +3,8 @@ from nltk.tokenize import sent_tokenize import os import re +global function_d, brain_d, drug_d, addiction_d + ## turn dictionary (synonyms) to regular expression def undic(dic): return "|".join(dic.values()) @@ -67,27 +69,28 @@ def gene_functional(gene): out+=gene+"\t"+"function\t"+bio0+"\t"+sent+"\n" return(out) -def generate_nodes(nodes_d, nodecolor): +def generate_nodes(nodes_d, nodetype): + nodecolor={'function':"#A9CCE3", 'addiction': "#D7BDE2", 'drug': "#F9E79F", 'brain':"#A3E4D7"} # include all search terms even if there are no edges, just to show negative result - json0 =str() #"{ data: { id: '" + gene + "'} },\n" + json0 =str() for node in nodes_d: - json0 += "{ data: { id: '" + node + "', nodecolor: '" + nodecolor + "' } },\n" + json0 += "{ data: { id: '" + node + "', nodecolor: '" + nodecolor[nodetype] + "', nodetype: '"+nodetype + "', url:'/shownode?nodetype=" + nodetype + "&node="+node+"' } },\n" return(json0) -def generate_edges(data): +def generate_edges(data, filename): json0=str() edgeCnts={} for line in data.split("\n"): if len(line.strip())!=0: (source, cat, target, pmid, sent) = line.split("\t") - edgeID=source+"|"+target + edgeID=filename+"|"+source+"|"+target if edgeID in edgeCnts: edgeCnts[edgeID]+=1 else: edgeCnts[edgeID]=1 for edgeID in edgeCnts: - (source,target)=edgeID.split("|") - json0+="{ data: { id: \'" + edgeID + "\', source: \'" + source + "\', target: '" + target + "\', sentCnt: '" + str(edgeCnts[edgeID]) + "', url:'/sentences?edgeID=" + edgeID + "' } },\n" + (filename, source,target)=edgeID.split("|") + json0+="{ data: { id: '" + edgeID + "', source: '" + source + "', target: '" + target + "', sentCnt: '" + str(edgeCnts[edgeID]) + "', url:'/sentences?edgeID=" + edgeID + "' } },\n" return(json0) addiction_d = {"reward":"reward|hedonic|incentive|intracranial self stimulation|ICSS|reinforcement|conditioned place preference|CPP|self administration|self administered|drug reinforced|operant|instrumental response", @@ -126,9 +129,11 @@ function_d={"neuroplasticity":"neuroplasticity|plasticity|long term potentiation } function=undic(function_d) + + #https://htmlcolorcodes.com/ -n0=generate_nodes(function_d, "#D7BDE2") -n1=generate_nodes(addiction_d,"#A9CCE3") -n2=generate_nodes(drug_d, "#A3E4D7") -n3=generate_nodes(brain_d, "#F9E79F") +n0=generate_nodes(function_d, 'function') +n1=generate_nodes(addiction_d, 'addiction') +n2=generate_nodes(drug_d, 'drug') +n3=generate_nodes(brain_d, 'brain') default_nodes=n0+n1+n2+n3 @@ -1,5 +1,8 @@ #!/bin/env python3 from flask import Flask, render_template, request, redirect +import tempfile +import random +import string from ratspub import * app=Flask(__name__) @@ -11,43 +14,55 @@ def root(): @app.route("/search") def search(): - global all_sentences + tf_path=tempfile.gettempdir() + tf_name=tf_path+"/tmp"+''.join(random.choice(string.ascii_letters) for x in range(6)) all_sentences=str() genes=request.args.get('query') genes=genes.replace(",", " ") genes=genes.replace(";", " ") genes=genes.split() - if len(genes)>=6: + if len(genes)>=6: return render_template('index.html') nodes=default_nodes edges=str() for gene in genes: - nodes+="{ data: { id: '" + gene + "', nodecolor:'#FADBD8', fontweight:700} },\n" + nodes+="{ data: { id: '" + gene + "', nodecolor:'#FADBD8', fontweight:700, url:'https://www.ncbi.nlm.nih.gov/gene/?term="+gene+"'} },\n" sent0=gene_addiction(gene) - e0=generate_edges(sent0) + e0=generate_edges(sent0, tf_name) sent1=gene_functional(gene) - e1=generate_edges(sent1) + e1=generate_edges(sent1, tf_name) sent2=gene_anatomical(gene) - e2=generate_edges(sent2) + e2=generate_edges(sent2, tf_name) edges+=e0+e1+e2 all_sentences+=sent0+sent1+sent2 - #f=open("all_sentences.tab","w") - #f.write(all_sentences) - #f.close() + #session['tmpfile']={'filename':tf_name} + with open(tf_name,"w") as f: + f.write(all_sentences) + f.close() return render_template('cytoscape.html', elements=nodes+edges) @app.route("/sentences") def sentences(): edge=request.args.get('edgeID') - (gene0, cat0)=edge.split("|") - print (gene0 + cat0) - out="<h3>"+gene0 + " and " + cat0 + "</h3>\n" - for sent in all_sentences.split("\n"): + (tf_name, gene0, cat0)=edge.split("|") + out="<h3>"+gene0 + " and " + cat0 + "</h3><hr>\n" + print(tf_name) + with open(tf_name, "r") as df: + all_sents=df.read() + for sent in all_sents.split("\n"): if len(sent.strip())!=0: - (gene,nouse,cat, pmid, text)=sent.split("\t") + (gene,nouse,cat, pmid, text)=sent.split("\t") if (gene == gene0 and cat == cat0) : out+= "<li> "+ text + " <a href=\"https://www.ncbi.nlm.nih.gov/pubmed/?term=" + pmid +"\" target=_new>PMID:"+pmid+"<br></a>" return render_template('sentences.html', sentences="<ol>"+out+"</ol><p>") +@app.route("/shownode") +def shownode(): + node=request.args.get('node') + allnodes={**brain_d, **drug_d, **function_d, **addiction_d} + out="<p>"+node.upper()+"<hr><li>"+ allnodes[node].replace("|", "<li>") + return render_template('sentences.html', sentences=out+"<p>") + + if __name__ == '__main__': app.run(debug=True) diff --git a/templates/cytoscape.html b/templates/cytoscape.html index fd2000e..c0c6bf6 100644 --- a/templates/cytoscape.html +++ b/templates/cytoscape.html @@ -22,7 +22,7 @@ css: { 'content': 'data(sentCnt)', 'curve-style': 'bezier', - 'opacity': '0.3' + 'opacity': 'mapData(sentCnt, 1, 50, 0.2, 0.3)', } }, { selector: 'node.highlight', @@ -50,6 +50,7 @@ name: 'circle' } }); + cy.on('tap', 'edge', function(){ try { // your browser may block popups window.open( this.data('url') ); @@ -57,6 +58,13 @@ window.location.href = this.data('url'); } }); + cy.on('tap', 'node', function(){ + try { // your browser may block popups + window.open( this.data('url') ); + } catch(e){ // fall back on url change + window.location.href = this.data('url'); + } + }); cy.on('mouseover', 'node', function(e){ var sel = e.target; cy.elements().difference(sel.outgoers()).not(sel).addClass('semitransp'); diff --git a/templates/index.html b/templates/index.html index ba18e0c..011aa6f 100644 --- a/templates/index.html +++ b/templates/index.html @@ -3,22 +3,14 @@ <p> <form action="/search"> - <input name="query" class="form-control form-control-lg" type="search" placeholder="e.g., Rgma Nrxn3, up to 5 terms are allowed" aria-label="search" value=""> + <input name="query" class="form-control form-control-lg" type="search" placeholder="Rgma Nrxn3" aria-label="search" value=""> <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button> </form> <br> - This app searches PubMed to find <u>sentences</u> that contain the query terms (e.g., gene symbols) and a drug addiction related keyword. <a href="https://github.com/chen42/RatsPub/blob/master/ratspub.py#L95-L129">These keywords</a> belong to the following categories: -<ul> -<li> names of abused drugs, e.g., opioids</li> -<li> terms describing addiction, e.g., relapse </li> -<li> key brain regions implicated in addiction, e.g., ventral striatum </li> -<li> neurotrasmission, e.g., dopaminergic </li> -<li> synaptic plasticity, e.g., long term potentiation </li> -<li> intracellular signaling, e.g., phosphorylation </li> -</ul> - + This app searches PubMed to find <i>sentences</i> that contain the query terms (e.g., gene symbols, <b>up to five are allowed per search</b>) and <a href="https://github.com/chen42/RatsPub/blob/master/ratspub.py#L95-L129">keywords</a> related to drug addiction. + <p> <br> -Live searches are conducted through PubMed to get relevant PMIDs, which are then used to retrieve the abstracts from a <a href="https://dataguide.nlm.nih.gov/edirect/archive.html">local archive</a>. The relationships are presented as an interactive <a href="https://js.cytoscape.org" >cytoscape</a> graph. The nodes can be moved around to better reveal the connections. Clicking on the links will bring up the corresponding sentences in a new browser window. +Searches are conducted through PubMed to get relevant PMIDs, which are then used to retrieve the abstracts from a <a href="https://dataguide.nlm.nih.gov/edirect/archive.html">local archive</a>. The relationships are presented as an interactive <a href="https://js.cytoscape.org" >cytoscape</a> graph. The nodes can be moved around to better reveal the connections. Clicking on the links will bring up the corresponding sentences in a new browser window. <p> <hr> <a href="https://github.com/chen42/ratspub"> Source code </a> diff --git a/templates/layout.html b/templates/layout.html index d64b331..cf8e8ed 100644 --- a/templates/layout.html +++ b/templates/layout.html @@ -13,7 +13,7 @@ </head> <body> - <nav class="navbar navbar-expand-lg navbar-light bg-light"> + <nav class="navbar navbar-expand-lg navbar-dark bg-dark"> <a class="navbar-brand" href="/">RatsPub:</br> <span style="font-size:small"> <u>R</u>elationship with <u>A</u>ddiction <u>T</u>hrough <u>S</u>earches of <u>Pub</u>Med </span></a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> @@ -24,8 +24,6 @@ {% block content %}{% endblock %} </div> -<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> -<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.6.0/cytoscape.min.js" integrity="sha256-uZV2wRlscgr52q3Wb3Oew0rKCPsM3g4aBTv46sF4qzg=" crossorigin="anonymous"></script> </body> diff --git a/templates/sentences.html b/templates/sentences.html index c481817..f8da871 100644 --- a/templates/sentences.html +++ b/templates/sentences.html @@ -1,8 +1,9 @@ {% extends "layout.html" %} {% block content %} +<br> {{ sentences | safe }} - + {% endblock %} |