Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
100 commits
Select commit Hold shift + click to select a range
c3eaa06
Initial commit of Omnipath PTM query
johnbachman Jul 24, 2017
c4bb529
Add func to hgnc_client to get db_refs from hgnc name
johnbachman Jul 24, 2017
2dc97c7
Get mod statements from omnipath
johnbachman Jul 24, 2017
f1ea514
Add docs to funcs
johnbachman Jul 24, 2017
91395c3
Build statements for other mod types
johnbachman Jul 24, 2017
a21bb52
Move omnipath_client to sources
johnbachman Nov 8, 2019
fdd3897
Add function to get receptor-ligand interactions
kkaris Nov 12, 2019
e2492f2
WIP Add prototype generator of rec-lig statements
kkaris Nov 12, 2019
3935b28
Formatting
kkaris Nov 12, 2019
f248842
Better docstring
kkaris Nov 12, 2019
39cf353
Get agents contained in op complex string
kkaris Nov 13, 2019
8298e4c
Handle more cases of up_id_strings
kkaris Nov 13, 2019
e83667f
Add helper for making text refs
kkaris Nov 13, 2019
13c7e56
Use PyPath instead of web client
kkaris Nov 13, 2019
65a7263
Manually rebase api.py
kkaris Nov 14, 2019
705046d
Manually rebase omnipath_processor
kkaris Nov 14, 2019
59aba06
Re-rename omnipath_client -> processor
kkaris Nov 14, 2019
4a34e24
Update init
kkaris Nov 14, 2019
b2ef37a
Update with new classes
kkaris Nov 14, 2019
d60b554
Clean up imports, global scope variables
kkaris Nov 14, 2019
7aae009
Fix docstring, add function to delete cache
kkaris Nov 14, 2019
29077a8
Improve hidden method description
kkaris Nov 14, 2019
2c328ae
Add more annotations
kkaris Nov 14, 2019
80891ae
Only add cellphonedb info for cellphonedb stmts
kkaris Nov 14, 2019
21203f0
Comments, info, docstrings
kkaris Nov 14, 2019
1ff1a54
Add check if pypath can be loaded
kkaris Nov 14, 2019
5c74b2e
Inform user PyPath is not available
kkaris Nov 14, 2019
d141209
Bubble up the api functions to __init__
kkaris Nov 14, 2019
ecd9d9b
Try import in processor
kkaris Nov 14, 2019
6b8062b
Bubble up processors in __init__
kkaris Nov 14, 2019
e0d844e
Add pypath to extras_require in setup.py
kkaris Nov 14, 2019
16057be
Add omnipath to packages, format list
kkaris Nov 14, 2019
c809c7d
Make warning more informative
kkaris Nov 14, 2019
a8601d8
Update imports, test general web api
kkaris Nov 14, 2019
b760c4a
Add mods test
kkaris Nov 14, 2019
05cc18f
Test import PyPath
kkaris Nov 14, 2019
e11046f
Start test for ligand-receptor processor
kkaris Nov 14, 2019
5cd47f9
Update docstring, fix args bug
kkaris Nov 14, 2019
0eccf07
Add more tests for ligand-receptor
kkaris Nov 15, 2019
a9628a7
Fix bug testing web api
kkaris Nov 15, 2019
e77103f
Update travis with PyPath dependencies
kkaris Nov 15, 2019
a60e287
Sudo all setup commands for igraph
kkaris Nov 15, 2019
3f5790e
Add dependency url for PyPath
kkaris Nov 15, 2019
ba2daef
Try listing pypath as installable from github
kkaris Nov 15, 2019
502dabf
Try explicit pip-install for pypath
kkaris Nov 15, 2019
0f9e435
Add dependency for pycurl
kkaris Nov 15, 2019
fea1e55
Add more import tests for pypath
kkaris Nov 18, 2019
67a5455
Fix libigraph.so.0 linking issue
kkaris Nov 18, 2019
cea2b5d
Try hpmr as test instead of cellphonedb
kkaris Nov 15, 2019
054237f
Mark PyPyPath test as no-travis
kkaris Nov 19, 2019
79d252f
Catch import errors in pypath network test
kkaris Nov 19, 2019
443f405
Test stmts were produced
kkaris Nov 19, 2019
41c753c
Revert to one class, move preprocessing to api.py
kkaris Nov 19, 2019
d41f40b
Comments, docstrings
kkaris Nov 19, 2019
4db186f
Fix bug in _delete_cache
kkaris Nov 19, 2019
7a4483e
Update tests
kkaris Nov 19, 2019
b72c728
Update __init__
kkaris Nov 19, 2019
dc70526
Add comments
kkaris Nov 20, 2019
b8c3787
Add helper getting interactions
kkaris Aug 14, 2020
0dd266c
WIP First pass at new json format
kkaris Aug 14, 2020
9de7699
Remove pypath dependencies and functions
kkaris Aug 17, 2020
1e98867
Put info in annotations
kkaris Aug 17, 2020
a56ed97
Build single stmt with multiple evidences
kkaris Aug 17, 2020
1605d50
Update exposed functions
kkaris Aug 17, 2020
600ab58
Count skips instead of logging
kkaris Aug 17, 2020
0220f79
Update fields, remove genesymbols
kkaris Aug 17, 2020
84e3d55
Replace ; with , in docstring
kkaris Aug 17, 2020
2b092a8
Add description to docstring
kkaris Aug 17, 2020
d05e464
Skip of protmapper is only source
kkaris Aug 17, 2020
13aa147
Remove unused code
kkaris Aug 17, 2020
d218b02
Remove unused fields, update docstring
kkaris Aug 17, 2020
cfa7666
Add test for ligrec from web
kkaris Aug 17, 2020
0d30be8
Update ptm processing
kkaris Aug 17, 2020
3e9089d
Set source_db as source_sub_id in annotations
kkaris Aug 17, 2020
080f47b
Remove unused imports in omnipath processor
kkaris Aug 17, 2020
4821636
Remove pypath and dependencies from setup.py
kkaris Aug 18, 2020
a6d80a3
Remove docstring overflow
kkaris Aug 18, 2020
5c58d36
Rename helper method
kkaris Aug 18, 2020
409c371
Log count of bad pmids (len>8)
kkaris Aug 18, 2020
5e150ce
Add bound condition regulations
kkaris Aug 18, 2020
0ceca9e
Add docstring for process_from_web
kkaris Aug 18, 2020
85528bb
Add omnipath to docs
kkaris Aug 18, 2020
b56702c
Remove pypath dependencies in travis config
kkaris Aug 18, 2020
8c3d2ef
Add sources/omnipath/index.rst
kkaris Aug 19, 2020
b08c3a5
Reverse removed newline
kkaris Aug 19, 2020
0a58335
Fix grammar
kkaris Aug 19, 2020
4b10355
Write short blurb about module and its usage
kkaris Aug 19, 2020
5dacf51
Standardize logger name
kkaris Aug 19, 2020
61f9260
Directly use name standardization
kkaris Aug 19, 2020
59266c7
Do not initialize the processing from init
kkaris Aug 19, 2020
6464daa
Initialize agent name with up_id as safeguard
kkaris Aug 19, 2020
8ece227
Switch to ontology standardizing in tests
kkaris Aug 19, 2020
45fa569
Add omnipath to list of sources in README
kkaris Aug 19, 2020
8f9713c
Add skips for already known sources
kkaris Aug 19, 2020
82a13df
Remove logger warning
kkaris Aug 19, 2020
74acab5
Add omnipath to belief json
bgyori Aug 20, 2020
943b66d
Add omnipath to HTML assembler
bgyori Aug 20, 2020
59e3a0a
Remove print
bgyori Aug 20, 2020
087987e
Touch up documentation
bgyori Aug 20, 2020
fd5cef4
Add omnipath test UP ids
kkaris Aug 24, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ Biological pathway databases:
| VirHostNet | [`indra.sources.virhostnet`](https://indra.readthedocs.io/en/latest/modules/sources/virhostnet/index.html) | http://virhostnet.prabi.fr/ |
| CTD | [`indra.sources.ctd`](https://indra.readthedocs.io/en/latest/modules/sources/ctd/index.html) | http://ctdbase.org |
| DrugBank | [`indra.sources.drugbank`](https://indra.readthedocs.io/en/latest/modules/sources/drugbank/index.html) | https://www.drugbank.ca/ |
| OmniPath | [`indra.sources.omnipath`](https://indra.readthedocs.io/en/latest/modules/sources/omnipath/index.html) | https://omnipathdb.org/ |


Custom knowledge bases:
Expand Down
1 change: 1 addition & 0 deletions doc/modules/sources/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ Standard Molecular Pathway Databases
virhostnet/index
ctd/index
drugbank/index
omnipath/index
Comment thread
kkaris marked this conversation as resolved.

Custom Knowledge Bases
----------------------
Expand Down
17 changes: 17 additions & 0 deletions doc/modules/sources/omnipath/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
OmniPath (:py:mod:`indra.sources.omnipath`)
===========================================

.. automodule:: indra.sources.omnipath
:members:

OmniPath API (:py:mod:`indra.sources.omnipath.api`)
---------------------------------------------------

.. automodule:: indra.sources.omnipath.api
:members:

OmniPath Processor (:py:mod:`indra.sources.omnipath.processor`)
---------------------------------------------------------------

.. automodule:: indra.sources.omnipath.processor
:members:
4 changes: 2 additions & 2 deletions indra/assemblers/html/assembler.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
'#cab2d6', '#fb9a99', '#a6cee3', '#33a02c', '#b15928', '#e31a1c'],
'light': ['#bc80bd', '#fccde5', '#b3de69', '#80b1d3', '#fb8072', '#bebada',
'#fdb462', '#d9d9d9', '#8dd3c7', '#ffed6f', '#ccebc5', '#e0e03d',
'#ffe8f4', '#acfcfc', '#dd99ff']
'#ffe8f4', '#acfcfc', '#dd99ff', '#00d4a6']
}


Expand All @@ -45,7 +45,7 @@ def color_gen(scheme):

db_sources = ['phosphosite', 'cbn', 'pc11', 'biopax', 'bel_lc',
'signor', 'biogrid', 'lincs_drug', 'tas', 'hprd', 'trrust',
'ctd', 'virhostnet', 'phosphoelm', 'drugbank']
'ctd', 'virhostnet', 'phosphoelm', 'drugbank', 'omnipath']

reader_sources = ['geneways', 'tees', 'isi', 'trips', 'rlimsp', 'medscan',
'sparser', 'eidos', 'reach']
Expand Down
6 changes: 4 additions & 2 deletions indra/resources/default_belief_probs.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
"hypothes.is": 0.01,
"virhostnet": 0.01,
"ctd": 0.01,
"drugbank": 0.01
"drugbank": 0.01,
"omnipath": 0.01
},
"rand": {
"eidos": 0.3,
Expand Down Expand Up @@ -59,6 +60,7 @@
"hypothes.is": 0.1,
"virhostnet": 0.1,
"ctd": 0.1,
"drugbank": 0.1
"drugbank": 0.1,
"omnipath": 0.1
}
}
18 changes: 18 additions & 0 deletions indra/sources/omnipath/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
"""
The OmniPath module accesses biomolecular interaction data from various
curated databases using the OmniPath API (see
https://saezlab.github.io/pypath/html/index.html#webservice) and processes
the returned data into statements using the OmniPathProcessor.

Currently, the following data is collected:
- Modifications from the PTMS endpoint https://saezlab.github.io/pypath/html/index.html#enzyme-substrate-interactions
- Ligand-Receptor data from the interactions endpoint https://saezlab.github.io/pypath/html/index.html#interaction-datasets

To process all statements, use the function `process_from_web`:

>>> from indra.sources.omnipath import process_from_web
>>> omnipath_processor = process_from_web()
>>> stmts = omnipath_processor.statements
"""
from .api import process_from_web
Comment thread
kkaris marked this conversation as resolved.
from .processor import OmniPathProcessor
75 changes: 75 additions & 0 deletions indra/sources/omnipath/api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import logging
import requests
from .processor import OmniPathProcessor

logger = logging.getLogger(__name__)


op_url = 'http://omnipathdb.org'


def process_from_web():
"""Query the OmniPath web API and return an OmniPathProcessor.

Returns
-------
OmniPathProcessor
An OmniPathProcessor object which contains a list of extracted
INDRA Statements in its statements attribute.
"""
ptm_json = _get_modifications()
ligrec_json = _get_interactions()
op = OmniPathProcessor(ptm_json=ptm_json, ligrec_json=ligrec_json)
op.process_ptm_mods()
op.process_ligrec_interactions()
return op


def _get_modifications():
"""Get all PTMs from Omnipath in JSON format.

Returns
-------
JSON content for PTMs.
"""
params = {'format': 'json',
'fields': ['curation_effort', 'isoforms', 'references',
'resources', 'sources']}
ptm_url = '%s/ptms' % op_url
res = requests.get(ptm_url, params=params)
if not res.status_code == 200 or not res.text:
return None
else:
return res.json()


def _get_interactions(datasets=None):
"""Wrapper for calling the omnipath interactions API

See full list of query options here:
https://omnipathdb.org/queries/interactions

Parameters
----------
datasets
A list of dataset names. Options are:
dorothea, kinaseextra, ligrecextra, lncrna_mrna, mirnatarget,
omnipath, pathwayextra, tf_mirna, tf_target, tfregulons
Default: 'ligrecextra'

Returns
-------
dict
json of database request
"""
interactions_url = '%s/interactions' % op_url
params = {
'fields': ['curation_effort', 'entity_type', 'references',
'resources', 'sources', 'type'],
'format': 'json',
'datasets': datasets or ['ligrecextra']
}
res = requests.get(interactions_url, params=params)
res.raise_for_status()

return res.json()
205 changes: 205 additions & 0 deletions indra/sources/omnipath/processor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
from __future__ import unicode_literals
import logging
from collections import Counter
from indra.ontology.standardize import standardize_agent_name
from indra.statements import modtype_to_modclass, Agent, Evidence, Complex, \
get_statement_by_name as stmt_by_name, BoundCondition

logger = logging.getLogger(__name__)


ignore_srcs = [db.lower() for db in ['NetPath', 'SIGNOR', 'ProtMapper',
'BioGRID', 'HPRD-phos', 'phosphoELM']]


class OmniPathProcessor(object):
"""Class to process OmniPath JSON into INDRA Statements."""
def __init__(self, ptm_json=None, ligrec_json=None):
self.statements = []
self.ptm_json = ptm_json
self.ligrec_json = ligrec_json

def process_ptm_mods(self):
"""Process ptm json if present"""
if self.ptm_json:
self.statements += self._stmts_from_op_mods(self.ptm_json)

def process_ligrec_interactions(self):
"""Process ligand-receptor json if present"""
if self.ligrec_json:
self.statements += self._stmt_from_op_lr(self.ligrec_json)

def _stmts_from_op_mods(self, ptm_json):
"""Build Modification Statements from a list of Omnipath PTM entries
"""
ptm_stmts = []
unhandled_mod_types = []
annot_ignore = {'enzyme', 'substrate', 'residue_type',
'residue_offset', 'references', 'modification'}
if ptm_json is None:
return []
for mod_entry in ptm_json:
# Skip entries without references
if not mod_entry['references']:
continue
enz = self._agent_from_up_id(mod_entry['enzyme'])
sub = self._agent_from_up_id(mod_entry['substrate'])
res = mod_entry['residue_type']
pos = mod_entry['residue_offset']
evidence = []
for source_pmid in mod_entry['references']:
source_db, pmid = source_pmid.split(':', 1)
# Skip evidence from already known sources
if source_db.lower() in ignore_srcs:
continue
if 'pmc' in pmid.lower():
text_refs = {'PMCID': pmid.split('/')[-1]}
pmid = None
else:
text_refs = None
evidence.append(Evidence(
source_api='omnipath',
source_id=source_db,
pmid=pmid,
text_refs=text_refs,
annotations={k: v for k, v in mod_entry.items() if k not
in annot_ignore}
))
mod_type = mod_entry['modification']
modclass = modtype_to_modclass.get(mod_type)
if modclass is None:
unhandled_mod_types.append(mod_type)
continue
else:
# All evidences filtered out
if not evidence:
continue
stmt = modclass(enz, sub, res, pos, evidence)
ptm_stmts.append(stmt)
return ptm_stmts

def _stmt_from_op_lr(self, ligrec_json):
"""Make ligand-receptor Complexes from Omnipath API interactions db"""
ligrec_stmts = []
ign_annot = {'source_sub_id', 'source', 'target', 'references'}
no_refs = 0
bad_pmid = 0
no_consensus = 0
if ligrec_json is None:
return ligrec_stmts

for lr_entry in ligrec_json:
if not lr_entry['references']:
no_refs += 1
continue
if len(lr_entry['sources']) == 1 and \
lr_entry['sources'][0].lower() in ignore_srcs:
continue

# Assemble evidence
evidence = []
for source_pmid in lr_entry['references']:
source_db, pmid = source_pmid.split(':')
# Skip evidence from already known sources
if source_db.lower() in ignore_srcs:
continue
if len(pmid) > 8:
bad_pmid += 1
continue
annot = {k: v for k, v in lr_entry.items() if k not in
ign_annot}
annot['source_sub_id'] = source_db
evidence.append(Evidence(source_api='omnipath', pmid=pmid,
annotations=annot))

# Get statements if we have evidences
if evidence:
# Get complexes
ligrec_stmts.append(self._get_op_complex(lr_entry['source'],
lr_entry['target'],
evidence))

# On consensus, make Activations or Inhibitions as well
if bool(lr_entry['consensus_stimulation']) ^ \
bool(lr_entry['consensus_inhibition']):
activation = True if lr_entry['consensus_stimulation'] else \
False
ligrec_stmts.append(self._get_ligrec_regs(
lr_entry['source'], lr_entry['target'], evidence,
activation=activation))
elif lr_entry['consensus_stimulation'] and \
lr_entry['consensus_inhibition']:
no_consensus += 1
# All evidences were filtered out
else:
no_refs += 1

if no_refs:
logger.warning(f'{no_refs} entries without references were '
f'skipped')
if bad_pmid:
logger.warning(f'{bad_pmid} references with bad pmids were '
f'skipped')
if no_consensus:
logger.warning(f'{no_consensus} entries with conflicting '
f'regulation were skipped')

return ligrec_stmts

@staticmethod
def _agent_from_up_id(up_id):
"""Build an Agent object from a Uniprot ID. Adds db_refs for both
Uniprot and HGNC where available."""
db_refs = {'UP': up_id}
ag = Agent(up_id, db_refs=db_refs)
standardize_agent_name(ag)
return ag

def _bc_agent_from_up_list(self, up_id_list):
# Return the first agent with the remaining agents as a bound condition
agents_list = [self._agent_from_up_id(up_id) for up_id in up_id_list]
agent = agents_list[0]
agent.bound_conditions = \
[BoundCondition(a, True) for a in agents_list[1:]]
return agent

def _complex_agents_from_op_complex(self, up_id_str):
"""Return a list of agents from a string containing multiple UP ids
"""
# Get agents
if 'complex' in up_id_str.lower():
up_id_list = [up for up in up_id_str.split(':')[1].split('_')]
else:
up_id_list = [up_id_str]

return [self._agent_from_up_id(up_id) for up_id in up_id_list]

def _get_op_complex(self, source, target, evidence_list):
ag_list = self._complex_agents_from_op_complex(source) + \
self._complex_agents_from_op_complex(target)
return Complex(members=ag_list,
evidence=evidence_list)

def _get_ligrec_regs(self, source, target, evidence_list, activation=True):
# Check if any of the agents is a complex
# Source
if 'complex' in source.lower():
# Make bound condition agent
up_id_list = [up for up in source.split(':')[1].split('_')]
subj = self._bc_agent_from_up_list(up_id_list)
else:
subj = self._agent_from_up_id(source)
# Target
if 'complex' in target.lower():
# Make bound condition agent
up_id_list = [up for up in target.split(':')[1].split('_')]
obj = self._bc_agent_from_up_list(up_id_list)
else:
obj = self._agent_from_up_id(target)

# Regular case:
Regulation = stmt_by_name('activation') if activation else \
stmt_by_name('inhibition')

regulation = Regulation(subj=subj, obj=obj, evidence=evidence_list)
return regulation
3 changes: 2 additions & 1 deletion indra/tests/make_mock_ontology.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@
'UP:Q02750', 'UP:P01112', 'UP:P01019', 'UP:Q9MZT7', 'UP:Q13422',
'HMDB:HMDB0000122', 'HGNC:7', 'HGNC:5', 'MIRBASE:MI0001730',
'HGNC:31476', 'DRUGBANK:DB00001', 'MESH:D013812', 'CHEBI:CHEBI:26523',
'UP:Q99490', 'MESH:D008099', 'MESH:D057189'
'UP:Q99490', 'MESH:D008099', 'MESH:D057189',
'UP:P15056', 'UP:O60674', 'UP:P0DP23', 'UP:Q13507'
}

always_include_ns = {'FPLX', 'INDRA_ACTIVITIES', 'INDRA_MODS'}
Expand Down
Loading