# Copyright 2013 Novo Nordisk Foundation Center for Biosustainability, DTU.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import absolute_import, print_function
import os
import json
import logging
import tempfile
import subprocess
import networkx as nx
from cobra import Metabolite, Reaction
from io import BytesIO
from escher import Builder
try:
from IPython.display import HTML, SVG
except ImportError:
pass
__all__ = ['graph_to_svg', 'draw_knockout_result', 'inchi_to_svg']
logger = logging.getLogger(__name__)
def pathviz_maps():
"""Return a list of maps available in pathviz.m"""
output = subprocess.check_output(['pathviz.m', '-l'])
return output.split('\n')
def pathviz_svg(map_id='EcoliCore_coreMap', **kwargs):
config = {"map": map_id, "ImageSize": 800., "Boundary": False}
for key, value in kwargs.items():
config[key] = value
fd, tmp_pathviz_input = tempfile.mkstemp(prefix='pathviz_svg_', suffix='.json')
with open(tmp_pathviz_input, 'w') as fhandle:
json.dump(config, fhandle)
fd, tmp_pathviz_output = tempfile.mkstemp(prefix='pathviz_svg_', suffix='.svg')
output = subprocess.check_output(['pathviz.m', '-o', tmp_pathviz_output, '-i', tmp_pathviz_input])
logger.debug(output)
with open(tmp_pathviz_output, 'r') as fhandle:
svg_map = fhandle.read()
return SVG(svg_map)
def pathviz_cdf(map_id='EcoliCore_coreMap', **kwargs):
"""Draw pathway using pathviz.m
Parameters
----------
"""
html_template = """<!DOCTYPE html>
<html>
<head>
<title>Map</title>
</head>
<body>
<script type="text/javascript" src="http://www.wolfram.com/cdf-player/plugin/v2.1/cdfplugin.js"></script>
<script type="text/javascript">
var cdf = new cdfplugin();
cdf.embed("%s", 942, 678);
</script>
</body>
</html>"""
html_template2 = """
<iframe width=800 height=700 src="files/%s" id="CDF"></iframe>
"""
config = {"map": map_id, "ImageSize": 800., "Boundary": False}
for key, value in kwargs.items():
config[key] = value
fd, tmp_pathviz_input = tempfile.mkstemp(prefix='pathviz_svg_', suffix='.json')
with open(tmp_pathviz_input, 'w') as fhandle:
json.dump(config, fhandle)
fd, tmp_pathviz_output = tempfile.mkstemp(prefix='pathviz_cdf_', suffix='.cdf', dir='.')
output = subprocess.check_output(['pathviz.m', '-o', tmp_pathviz_output, '-i', tmp_pathviz_input])
logger.debug(output)
fd, tmp_html = tempfile.mkstemp(prefix='pathviz_cdf_embedded_', suffix='.html', dir='.')
with open(tmp_html, 'w') as fhandle:
fhandle.write(html_template % os.path.basename(tmp_pathviz_output))
return HTML(html_template2 % os.path.basename(tmp_html))
[docs]def draw_knockout_result(model, map_name, simulation_method, knockouts, *args, **kwargs):
with model:
for reaction in model.reactions.get_by_any(knockouts):
reaction.knock_out()
solution = simulation_method(model, *args, **kwargs).fluxes
return Builder(map_name, reaction_data=solution)
[docs]def inchi_to_svg(inchi, file=None, debug=False, three_d=False):
"""Generate an SVG drawing from an InChI string.
Parameters
----------
inchi : str
An InChI string.
Returns
-------
str
A vector graphics of the compound represented as SVG.
Examples
--------
Draw water
>>> inchi_to_svg('InChI=1S/H2O/h1H2')
'<?xml version="1.0"?>\n<svg version="1.1" id="topsvg"\nxmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"\nxmlns:cml="http://www.xml-cml.org/schema" x="0" y="0" width="200px" height="200px" viewBox="0 0 100 100">\n<title>OBDepict</title>\n<rect x="0" y="0" width="100" height="100" fill="white"/>\n<text text-anchor="middle" font-size="6" fill ="black" font-family="sans-serif"\nx="50" y="98" ></text>\n<g transform="translate(0,0)">\n<svg width="100" height="100" x="0" y="0" viewBox="0 0 80 80"\nfont-family="sans-serif" stroke="rgb(0,0,0)" stroke-width="2" stroke-linecap="round">\n<text x="36" y="48" fill="rgb(255,12,12)" stroke="rgb(255,12,12)" stroke-width="1" font-size="16" >OH</text>\n<text x="60" y="51.68" fill="rgb(255,12,12)" stroke="rgb(255,12,12)" stroke-width="1" font-size="13" >2</text>\n</svg>\n</g>\n</svg>\n\n' # noqa
"""
in_file = tempfile.NamedTemporaryFile()
in_file.write(inchi.encode('utf-8'))
in_file.flush()
out_file = None
gen = "--gen3d" if three_d else "--gen2d"
error_level = 5 if debug else 1
try:
if file is not None:
os.system("obabel -iinchi %s -osvg -O %s %s -xh 40 ---errorlevel %d" %
(in_file.name, file.name, gen, error_level))
return file.name
else:
out_file = tempfile.NamedTemporaryFile("w+")
os.system("obabel -iinchi %s -osvg -O %s %s -xh 40 ---errorlevel %d"
% (in_file.name, out_file.name, gen, error_level))
return out_file.read()
finally:
in_file.close()
if out_file is not None:
out_file.close()
def inchi_to_ascii(inchi, file=None, debug=False):
"""Generate an ASCII drawing from an InChI string.
Parameters
----------
inchi : str
An InChI string.
Returns
-------
str
A vector graphics of the compound represented as SVG.
Examples
--------
Draw water
>>> inchi_to_ascii('InChI=1S/H2O/h1H2')
"""
in_file = tempfile.NamedTemporaryFile()
in_file.write(inchi.encode('utf-8'))
in_file.flush()
out_file = None
error_level = 5 if debug else 1
try:
if file is not None:
os.system("obabel -iinchi %s -oascii -O %s --gen3d -xh 40 ---errorlevel %d"
% (in_file.name, file.name, error_level))
return file.name
else:
out_file = tempfile.NamedTemporaryFile()
os.system("obabel -iinchi %s -oascii -O %s --gen3d -xh 40 ---errorlevel %d"
% (in_file.name, out_file.name, error_level))
return out_file.read()
finally:
in_file.close()
if out_file is not None:
out_file.close()
[docs]def graph_to_svg(g, layout=nx.spring_layout):
"""return the SVG of a matplotlib figure generated from a graph"""
import matplotlib.pyplot as plt
layout = layout(g)
fig = plt.figure(figsize=(8, 8))
ax = fig.add_subplot(111)
# draw reaction nodes
# rxn_nodes = [node for node in g.nodes() if isinstance(node, Reaction)]
# draw metabolites
met_nodes = [node for node in g.nodes() if isinstance(node, Metabolite)]
nx.draw_networkx_edges(g, nodelist=met_nodes, pos=layout, ax=ax, edge_color='gray', arrows=False, node_color='b')
labels = dict()
for node in g.nodes():
if isinstance(node, Reaction):
labels[node] = node.name
else:
labels[node] = node.name
nx.draw_networkx_labels(g, labels=labels, pos=layout, font_size=9)
output = BytesIO()
fig.savefig(output, format='svg')
plt.close(fig)
return output.getvalue()