Skip to content

Commit

Permalink
New interfaces (#84)
Browse files Browse the repository at this point in the history
* Interface (#74)

* Add prelude #63

* Make a step plot

* Add a new interface, Session

* Check dimensionality

* #19 Support a new keyword, proceed

* #19 Enable to extend reserved keywords

* Implement ensemble

* session.Result is picklable

* Use run_ensemble

* Move ecell4.util.viz -> ecell4.plotting

* ecell4.util.viz will be deprecated

* get_range_of_world and get_range_of_trajectories are moved into _core

* Copy deep

* Add plotting._plotly

* Add a datasource for STRING

* Add idmapping using UniProt

* Interface2 (#75)

* Set method

* Add more options

* Fix silly mistakes

* #11 Enable rich display

* Session.run accepts numpy.ndarray as t

* Arithmetic representations in y

* Enable to set own observable in _plotly

* Split elegans-based plot functions into _elegans

* Format before assignment

* Rename plotting.default -> BACKEND

* Enable rule-based descriptions in observables

* Enable observables in plotting.plot_number_observer (#77)

* Session.run accepts numpy.ndarray as t

* Arithmetic representations in y

* Enable to set own observable in _plotly

* Split elegans-based plot functions into _elegans

* Format before assignment

* Rename plotting.default -> BACKEND

* Enable rule-based descriptions in observables

* Load submodules

* Skip some submodules

* Remove a duplicated file

* Remove all

* Update version

* Import all from submodules

* Set __all__

* Rather use the common name

* Update the relative module path

* Move display_anim into _core

* Enable ndiv

* Fix for pi

* Enable to change figsize in _matplotlib

* Add DOI

* Add citation

* Update the citation outputs

* Import citation in prelude

* Put a space after a comma

* load_world is already imported

* Cast to an integer

* Enable to fetch an abstract

* Remove an unnecessary module

* Simplify run_simulation and ensemble_simulations, and deprecate old implementations

* The config yaml is loaded if existing

* Add plot_trajectory in _plotly

* Change the default renderer on Google Colab

* Try STL visualization in Plotly

* Set opacity

* Use default colorscale

* Update

* Enable to show stl

* Enable to check dimensionality of units in a model
  • Loading branch information
kaizu committed May 2, 2020
1 parent 64438e3 commit bf39870
Show file tree
Hide file tree
Showing 28 changed files with 3,600 additions and 2,655 deletions.
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@ Run this with Jupyter Notebook

```python
%matplotlib inline
from ecell4_base.core import *
from ecell4 import *
from ecell4.prelude import *

with species_attributes():
M | {'dimension': 2}
Expand All @@ -60,7 +59,7 @@ run_simulation(
0.4, y0={'A': 10}, structures={'M': surface},
solver='spatiocyte', observers=obs, return_type=None)

viz.plot_trajectory(obs, interactive=False)
show(obs, interactive=False)
```

![png](./samples/hairball.png)
Expand Down
2 changes: 1 addition & 1 deletion ecell4/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
from ecell4.util import *

__version__ = '0.1.0'
__version__ = '1.2.0'
6 changes: 5 additions & 1 deletion ecell4/datasource/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# from . import biocyc, biogrid, ecocyc, pdb, psicquic, pubmed.py, rdf, sbml, sparql, uniprot

def print_descriptions(desc):
for i, entry in enumerate(desc):
if i > 0:
Expand Down Expand Up @@ -56,4 +58,6 @@ def whereis(entity, collections=None):
print_descriptions(desc)


__all__ = ['description', 'whereis']
from .pubmed import citation

__all__ = ['description', 'whereis', 'citation']
62 changes: 56 additions & 6 deletions ecell4/datasource/pubmed.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import re
import numbers

try:
from urllib.request import Request, urlopen, HTTPError # Python3
except ImportError:
from urllib2 import Request, urlopen, HTTPError # Python2

from urllib.request import Request, urlopen, HTTPError # Python3
from xml.dom import minidom


Expand All @@ -31,6 +28,7 @@ def description(entity):
entry.append(('Author(s)', ', '.join(src.data['AuthorList'])))
entry.append(('Source', src.data['Source']))
entry.append(('SO', src.data['SO']))
entry.append(('DOI', 'https://doi.org/{}'.format(src.data['DOI'])))
entry.append(('URL', src.link(entity_id)))
return [entry]

Expand All @@ -47,8 +45,16 @@ def __init__(self, entity=None):
data = self.parse_esummary(read_url(url))
assert len(data) == 1
self.data = data[0]
url = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=pubmed&id={}&rettype=abstract".format(entity_id)
abstract = self.parse_abstract(read_url(url))
if len(abstract) == 0:
self.abstract = ""
else:
assert len(abstract) == 1
self.abstract = abstract[0]
else:
self.data = None
self.abstract = ""

@classmethod
def parse_entity(cls, entity):
Expand All @@ -57,6 +63,8 @@ def parse_entity(cls, entity):
idpttrn = r'\d+'
uri1 = r'https://www.ncbi.nlm.nih.gov/pubmed/(?P<id>{})'.format(idpttrn)
uri2 = r'http://identifiers.org/pubmed/(?P<id>{})'.format(idpttrn)
if isinstance(entity, numbers.Integral) and entity >= 0:
entity = str(entity)
if isinstance(entity, str):
if re.match(r'^{}$'.format(idpttrn), entity) is not None:
return entity
Expand Down Expand Up @@ -87,13 +95,55 @@ def parse_esummary(cls, esummary):
entry['ID'] = entry_node.getElementsByTagName('Id')[0].firstChild.data
for item in entry_node.getElementsByTagName('Item'):
name = item.getAttribute('Name')
if name in ('Title', 'Volume', 'Issue', 'Pages', 'Source', 'PubDate', 'SO'):
if name in ('Title', 'Volume', 'Issue', 'Pages', 'Source', 'PubDate', 'SO', 'DOI', 'FullJournalName'):
entry[name] = item.firstChild.data
elif name == 'AuthorList':
entry['AuthorList'] = [author.firstChild.data for author in item.getElementsByTagName('Item') if author.getAttribute('Name') == 'Author']
retval.append(entry)
return retval

@classmethod
def parse_abstract(cls, efetch):
retval = []
doc = minidom.parseString(efetch)
for node in doc.getElementsByTagName('AbstractText'):
retval.append(node.firstChild.data)
return retval

class Formatter(object):

def __init__(self, entity):
entity_id = PubMedDataSource.parse_entity(entity)
if entity_id is None:
self.src = None
else:
self.src = PubMedDataSource(entity)

@property
def abstract(self):
return self.src.abstract

def __str__(self):
if self.src is None:
return None
authors = ', '.join(self.src.data['AuthorList'])
year = self.src.data['PubDate'].strip().split(' ')[0]
return "{Authors}, {Title} {FullJournalName}, {Issue}({Volume}), {Pages}, {Year}. {DOI}. PubMed MPID: {ID}.".format(Authors=authors, Year=year, **self.src.data)

def _ipython_display_(self):
if self.src is None:
return
from IPython.display import display, Markdown
authors = ', '.join(self.src.data['AuthorList'])
year = self.src.data['PubDate'].strip().split(' ')[0]
doi_url = 'https://doi.org/{}'.format(self.src.data['DOI'])
url = self.src.link(self.src.data['ID'])
text = "{Authors}, {Title} *{FullJournalName}*, **{Issue}**({Volume}), {Pages}, {Year}. [{DOI}]({DOI_URL}). PubMed PMID: [{ID}]({URL}).".format(Authors=authors, Year=year, DOI_URL=doi_url, URL=url, **self.src.data)
display(Markdown(text))

def citation(entity, formatter=Formatter):
return formatter(entity)


if __name__ == "__main__":
print(description("8752322"))
60 changes: 60 additions & 0 deletions ecell4/datasource/string.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import urllib
import time

import requests


class StringDataSource:
"""
See http://string-db.org/cgi/help.pl
"""

wait = 1.0

def __init__(self):
pass

@classmethod
def network(cls, entity, output_format='highres_image', **optional_parameters):
"""
Display STRING network image.
Parameters
----------
output_format : str, optional
'image' or 'highres_image'.
"""
if isinstance(entity, str):
identifiers = [entity]
else:
raise TypeError(f'The given identifier [{entity}] is invalid.')

parameters = {'identifiers': '\r'.join(identifiers)}
parameters.update(optional_parameters)

url = "https://string-db.org/api/{}/network?{}".format(
output_format, urllib.parse.urlencode(parameters))
response = requests.get(url)
time.sleep(cls.wait)

from IPython.display import Image, display_png
display_png(Image(response.content))

@classmethod
def interaction_partners(cls, entity, **optional_parameters):
if isinstance(entity, str):
identifiers = [entity]
else:
raise TypeError(f'The given identifier [{entity}] is invalid.')

parameters = {'identifiers': '\r'.join(identifiers)}
parameters.update(optional_parameters)

output_format = 'json'
url = "https://string-db.org/api/{}/interaction_partners?{}".format(
output_format, urllib.parse.urlencode(parameters))
response = requests.get(url)
time.sleep(cls.wait)
return response.json()
36 changes: 36 additions & 0 deletions ecell4/datasource/uniprot.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import re
import urllib.parse
import urllib.request

from rdflib import Namespace
from rdflib.namespace import RDF, RDFS, SKOS
Expand Down Expand Up @@ -55,6 +57,36 @@ def whereis(entity):
desc.extend(description(topology))
return desc

def idmapping(query, source='ACC+ID', target='ACC'):
"""https://www.uniprot.org/help/api_idmapping"""

if isinstance(query, str):
query = [query]
query = ' '.join(query)

url = 'https://www.uniprot.org/uploadlists/'
params = {
'from': source,
'to': target,
'format': 'tab',
'query': query,
}
data = urllib.parse.urlencode(params)
data = data.encode('utf-8')
req = urllib.request.Request(url, data)
with urllib.request.urlopen(req) as f:
response = f.read()
content = response.decode('utf-8')

import csv
import io
buffer = io.StringIO(content)
reader = csv.reader(buffer, delimiter='\t')
next(reader)
ret = [tuple(row) for row in reader]
buffer.close()
return ret

class UniProtDataSourceBase(rdf.RDFDataSourceBase):

GRAPH = {}
Expand Down Expand Up @@ -221,6 +253,10 @@ def link(cls, entity):
assert entity_id is not None
return 'http://www.uniprot.org/uniprot/{}'.format(entity_id)

@property
def identifier(self):
return self.parse_entity(self.url)

def mnemonic(self):
return [str(obj) for obj in self.graph.objects(predicate=self.UNIPROT.mnemonic)] #XXX: Specify its subject

Expand Down
Loading

0 comments on commit bf39870

Please sign in to comment.