Skip to content
Snippets Groups Projects
Commit d4d8ddf2 authored by David Hoksza's avatar David Hoksza
Browse files

Initial commit

parents
No related branches found
No related tags found
No related merge requests found
README.md 0 → 100644
# Disease associations
`Disease associations` is a plugin allowing one to see genes associated with given disease
in the context of selected disease map. Currently, the plugin shows genes associations obtained
from [Protein API variation service](https://www.ebi.ac.uk/proteins/api/doc/) (includes also
information about specific variants)
and [Open Targets API](https://docs.targetvalidation.org/tutorials/rest-api).
### General instructions
In order to use the precompiled and publicly available version of the plugin,
open the plugin menu in the MINERVA's upper left corner (see image below) and click plugins.
In the dialog which appears enter the following address in the URL box: `https://minerva-dev.lcsb.uni.lu/plugins/disease-associations/plugin.js` .
The plugin shows up in the plugins panel on the right hand side of the screen.
### Plugin functionality
#### Obtaining disease-gene associations
- The users picks whether she wants to input disease based on [EFO](https://www.ebi.ac.uk/efo/) ontology
or [OMIM](https://www.omim.org/) ontology (see
[Variation information data source section](#Variation-information)
for details).
- In case EFO is selected, when the users starts
inputting the disease of interest in the disease input box the plugin
starts suggesting available diseases from the [EFO ontology](https://www.ebi.ac.uk/efo/)
via the [EBI's ontology lookup service](https://www.ebi.ac.uk/ols/docs/api)
- After a disease is selected, the plugin shows details of the disease including its
synonyms and mapped [OMIM](https://www.omim.org/) ontology terms.
- In case OMIM is selected, the user needs to input OMIM ID and no additional details
are shown.
- After clicking on the <i>Retrieve</i> button,
the plugin connects to the [Protein API variation service](https://www.ebi.ac.uk/proteins/api/doc/)
and [Open Targets API](https://docs.targetvalidation.org/tutorials/rest-api)
and retrieves all available disease-gene associations. In case of Protein API, the associations are
based on the OMIM while in case of Open Targets, the associations are based directly on
the EFO ID which was used to provide the disease details.
#### Disease-gene associations inspection
The obtained associations are shown in tabs based on the the source of information.
##### 1. Variation information from Protein API variation service
The variation service is used to obtain disease-associated variants retrieved from large-scale
genomics projects (see details in the respective section below).
- Returned variants are grouped by isoforms of genes they are involved in.
The plugin groups variants in isoforms by gene name
and displays them in a table where each row contains the gene name, number of occurrences of that gene in
the map and number of isoforms.
- The user can click on the eye icon of a particular gene to show its occurrences in the map.
If there is no occurrence of given gene in the map,
the number of occurrences is zero and no eye icon is displayed.
- By clicking on the plus symbol in each line line, one can explore all the data which was obtained from
the Protein API for that gene.
##### 2. Associations from Open Targets
Open Targets platform is used to obtain disease-gene associations including
an [aggregated association score](https://docs.targetvalidation.org/getting-started/scoring) showing the
strength of the respective association. Only associations with score > 0.2 are retrieved and displayed.
- Each association contains the involved gene, strength of the association and link to Open Targets
where one can inspect detailed information about the particular association.
- The user can click on the eye icon of a particular gene to show its occurrences in the map.
If there is no occurrence of given gene in the map, no eye icon is displayed.
### Data resources
### Ontology Lookup Service (OLS)
EBI's [OLS](https://www.ebi.ac.uk/ols/index) is used to obtain disease
[suggestions](https://www.ebi.ac.uk/ols/docs/api#_suggest_term) and
[disease details]((https://www.ebi.ac.uk/ols/docs/api#resources-term)) from the
[EFO ontology]((https://www.ebi.ac.uk/efo/)), one of the ontologies under the OLS umbrella.
###Variation information
The information about variants comes from EBI's [Proteins API](https://www.ebi.ac.uk/proteins/api/doc/#!/variation/search).
As stated on the pages of Proteins API *"The variation, proteomics and antigen services
provide annotations imported and mapped from large scale data sources,
such as 1000 Genomes, ExAC (Exome Aggregation Consortium),
TCGA (The Cancer Genome Atlas), COSMIC (Catalogue Of Somatic Mutations In Cancer),
PeptideAtlas, MaxQB (MaxQuant DataBase), EPD (Encyclopedia of Proteome Dynamics) and HPA,
along with UniProtKB annotations for these feature types (if applicable)"*.
To specify the disease of interest, the Proteins API can be passed either a text or list of
[OMIM](https://www.omim.org) identifiers. The plugin uses the latter option since
the EFO ontology includes also a mapping from EFO to OMIM. For example,
[Parkinson's disease](https://www.ebi.ac.uk/ols/ontologies/efo/terms?iri=http%3A%2F%2Fwww.ebi.ac.uk%2Fefo%2FEFO_0002508)
is mapped to OMIM:616710, OMIM:616361, OMIM:168600. We should mention here that
OMIM ontology seems to have a more granular distinction of diseases and thus for example
it contains Parkinson disease 1-10 which do not have exact mapping in EFO.
The following image shows an example of the data (a snippet from Google Chrome DevTools)
already grouped by gene name and species information (see above).
![Grouped Proteins API data](img/data_example.png)
### Open Targets
Open Targets platform supports workflows starting
from a target or disease, and shows the available evidence for target – disease associations.
The plugin uses the [Open Targets Platform REST-API](https://docs.targetvalidation.org/tutorials/rest-api)
to obtain the associations and their scores.
\ No newline at end of file
{
"name": "disease-associations",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build-css": "node-sass --include-path src/css src/css/styles.scss src/css/styles.css",
"build": "mkdirp dist && npm run build-css && browserify -t [ babelify --presets es2015 ] -t browserify-css src/js/index.js | uglifyjs --compress --mangle > dist/plugin.js ",
"build-debug": "mkdirp dist && npm run build-css && browserify -t [ babelify --presets es2015 ] -t browserify-css src/js/index.js> dist/plugin.js ",
"watch-js": "mkdirp dist && npm run build-css && watchify -v -t [ babelify --presets es2015 ] -t browserify-css src/js/index.js -o dist/plugin.js",
"clean": "rimraf dist"
},
"author": "David Hoksza",
"license": "MIT",
"devDependencies": {
"babel-core": "^6.26.0",
"babel-preset-es2015": "^6.24.1",
"babelify": "^8.0.0",
"bower": "^1.5.2",
"browserify": "^14.5.0",
"browserify-css": "^0.13.1",
"mkdirp": "^0.5.1",
"node-sass": "^4.6.1",
"rimraf": "latest",
"uglify-js": "^3.1.9",
"watchify": "^3.9.0"
},
"dependencies": {
"bootstrap-table": "^1.12.1",
"bootstrap-treeview": "github:diegokogan/bootstrap-treeview",
"html-linkify": "^1.2.2",
"typeahead.js": "^0.11.1"
}
}
@import url(../../node_modules/bootstrap-table/dist/bootstrap-table.min.css);
.disease-associations-container {
padding: 15px; }
.disease-associations-container .btn-search {
margin-bottom: 10px; }
.disease-associations-container .input-disease {
text-align: center;
font-weight: bold;
width: 100%;
padding: 0; }
.disease-associations-container .disease-submission .panel-heading {
padding: 3px 15px;
font-weight: bold;
cursor: pointer; }
.disease-associations-container .associations-content .error-panel {
margin-top: 10px; }
.disease-associations-container .disease-info {
padding: 3px; }
.disease-associations-container .disease-info-label {
font-weight: bold; }
.disease-associations-container .twitter-typeahead {
width: 100%; }
.disease-associations-container .twitter-typeahead .tt-menu {
width: 100%; }
.disease-associations-container .variation-table .glyphicon-eye-open {
cursor: pointer; }
.disease-associations-container .opentargets-table .glyphicon-eye-open {
cursor: pointer; }
.disease-associations-container .fixed-table-body {
overflow: auto; }
.disease-associations-container .genes-loading {
text-align: center; }
.disease-associations-container .genes-loading .fa-spin {
margin-right: 10px; }
.disease-associations-container .btn-default.btn-on.active {
background-color: #5BB75B;
color: white; }
.disease-associations-container .btn-default.btn-off.active {
background-color: #5BB75B;
color: white; }
@import "../../node_modules/bootstrap-table/dist/bootstrap-table.min.css";
$pluginName: disease-associations;
.#{$pluginName}-container {
padding: 15px;
}
.#{$pluginName}-container .btn-search {
margin-bottom: 10px;
}
.#{$pluginName}-container .input-disease {
text-align: center;
font-weight: bold;
width: 100%;
padding: 0;
}
.#{$pluginName}-container .disease-submission .panel-heading {
padding: 3px 15px;
font-weight: bold;
cursor: pointer;
//background: rgba(0, 0, 0, 0.1);
}
//.#{$pluginName}-container .disease-submission .chevron:after {
// content: "\f078";
//}
//.#{$pluginName}-container .disease-submission.collapsed .chevron:after {
// content: "\f054";
//}
.#{$pluginName}-container .associations-content .error-panel{
margin-top: 10px;
}
.#{$pluginName}-container .disease-infos {
//padding: 3px 0px;
//background: rgba(1, 1, 1, 0.1);
//border-radius: 5px;
}
.#{$pluginName}-container .disease-info {
padding: 3px;
}
.#{$pluginName}-container .disease-info-label {
font-weight: bold;
}
.#{$pluginName}-container .twitter-typeahead {
width: 100%;
}
.#{$pluginName}-container .twitter-typeahead .tt-menu{
width: 100%;
}
.#{$pluginName}-container .variation-table .glyphicon-eye-open {
cursor: pointer;
}
.#{$pluginName}-container .opentargets-table .glyphicon-eye-open {
cursor: pointer;
}
.#{$pluginName}-container .fixed-table-body {
overflow: auto;
}
.#{$pluginName}-container .genes-loading {
text-align: center;
}
.#{$pluginName}-container .genes-loading .fa-spin{
margin-right: 10px;
}
.#{$pluginName}-container .btn-default.btn-on.active{background-color: #5BB75B;color: white;}
.#{$pluginName}-container .btn-default.btn-off.active{background-color: #5BB75B ;color: white;}
\ No newline at end of file
This diff is collapsed.
const getDisease = function(iri){
const encodedIri = encodeURIComponent(encodeURIComponent(iri));
return $.ajax({
url: `https://www.ebi.ac.uk/ols/api/ontologies/efo/terms/${encodedIri}`
});
};
const suggestDiseases = function (text) {
let suggestedDisDesc = []; //array of suggestion-disease description pair
return $.ajax({
url: `https://www.ebi.ac.uk/ols/api/suggest?q=${encodeURIComponent(text)}&ontology=efo&rows=20`
}).then(function (res) {
const suggestions = res.response.docs.map(d => {
suggestedDisDesc.push({suggestion: d.autosuggest, desc: undefined});
return d.autosuggest;
});
const promises = suggestions.map(s => $.ajax({url: `https://www.ebi.ac.uk/ols/api/search?q=${encodeURIComponent(s)}&ontology=efo&queryFields=label,synonym&exact=true`}))
return Promise.all(promises);
}).then(function (ress) {
for (let i = ress.length -1; i >=0; i--) {
const res = ress[i];
if (res.response.docs.length > 0 && 'obo_id' in res.response.docs[0]) {
suggestedDisDesc[i].desc = res.response.docs[0];
} else {
suggestedDisDesc.splice(i, 1);
}
}
const promises = suggestedDisDesc
.map(sdd => $.ajax({url: `https://www.ebi.ac.uk/ols/api/ontologies/efo/ancestors?id=${encodeURIComponent(sdd.desc.obo_id)}`}));
return Promise.all(promises);
}).then(function (ress) {
const sd = {};
suggestedDisDesc.forEach(function (sdd, i) {
if (ancestorsContainDisease(ress[i])) {
sd[sdd.suggestion] = sdd.desc;
}
});
return sd;
})
};
const ancestorsContainDisease = function(ancestorsJson) {
let isDisease = false;
ancestorsJson._embedded.terms.forEach(t => isDisease = isDisease || (t.obo_id === "EFO:0000408"));
return isDisease;
};
module.exports = {
suggestDiseases: suggestDiseases
, getDisease: getDisease
};
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment