Skip to content

Commit b6eed1f

Browse files
working on visualization
1 parent 7b3af18 commit b6eed1f

File tree

2 files changed

+95
-21
lines changed

2 files changed

+95
-21
lines changed

setup.cfg

+17-17
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ parse = (?P<major>\d+)
66
\.(?P<minor>\d+)
77
\.(?P<patch>\d+)
88
(?P<release>[a]*)(?P<num>\d*)
9-
serialize =
9+
serialize =
1010
{major}.{minor}.{patch}{release}{num}
1111
{major}.{minor}.{patch}
1212
tag_name = {new_version}
@@ -15,15 +15,15 @@ tag_name = {new_version}
1515
name = sbmlutils
1616
url = https://github.com/matthiaskoenig/sbmlutils
1717
download_url = https://pypi.org/project/sbmlutils
18-
project_urls =
18+
project_urls =
1919
Source Code = https://github.com/matthiaskoenig/sbmlutils
2020
Documentation = https://sbmlutils.readthedocs.io
2121
Bug Tracker = https://github.com/matthiaskoenig/sbmlutils/issues
2222
author = Matthias Koenig
2323
author_email = [email protected]
2424
maintainer = Matthias Koenig
2525
maintainer_email = [email protected]
26-
classifiers =
26+
classifiers =
2727
Development Status :: 5 - Production/Stable
2828
Intended Audience :: Science/Research
2929
License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)
@@ -38,25 +38,25 @@ license = LGPL-3.0
3838
description = sbmlutils are utilities for working with SBML.
3939
long_description = file: README.rst
4040
long_description_content_type = text/x-rst
41-
keywords =
41+
keywords =
4242
modeling
4343
standardization
4444
SBML
4545

4646
[options]
4747
zip_safe = True
4848
python_requires = >=3.10
49-
install_requires =
49+
install_requires =
5050
pymetadata>=0.4.1
51-
51+
5252
depinfo
5353
rich
5454
lxml
5555
requests
5656
jinja2
5757
xmltodict
5858
pydantic>2.8
59-
59+
6060
setuptools # fix for colorbrewer dependency of py4cytoscape
6161
numpy>=1.26.4
6262
python-libsbml>=5.20.4
@@ -65,24 +65,24 @@ install_requires =
6565
pandas>=2.2.0
6666
tabulate>=0.9.0
6767
pint>=0.24.3
68-
68+
6969
markdown-it-py>=3.0.0
7070
openpyxl>=3.1.5
7171
xmlschema>=3.3.2
7272
matplotlib>=3.9
73-
py4cytoscape>=1.9.0
74-
libroadrunner>=1.27.0
75-
73+
py4cytoscape>=1.11.0
74+
libroadrunner>=2.7.0
75+
7676
uvicorn>=0.30.6
7777
fastapi>=0.112.0
7878
python-multipart>=0.0.9
79-
tests_require =
79+
tests_require =
8080
tox>=3.24.3
8181
pytest>=7.0.1
82-
setup_requires =
82+
setup_requires =
8383
pytest-runner
8484
packages = find:
85-
package_dir =
85+
package_dir =
8686
= src
8787
include_package_data = True
8888

@@ -93,7 +93,7 @@ test = pytest
9393
where = src
9494

9595
[options.extras_require]
96-
development =
96+
development =
9797
pip-tools>=7.4.1
9898
black>=24.8.0
9999
bump2version>=1.0.1
@@ -105,7 +105,7 @@ development =
105105
pytest>=7.4.0
106106
pytest-cov>=4.1.0
107107
beautifulsoup4>=4.12.3
108-
docs =
108+
docs =
109109
sphinx>=3.4.3
110110
ipykernel>=5.4.3
111111
nbsphinx>=0.8.1
@@ -119,7 +119,7 @@ universal = 1
119119
[bumpversion:part:release]
120120
optional_value = placeholder
121121
first_value = placeholder
122-
values =
122+
values =
123123
placeholder
124124
a
125125

src/sbmlutils/cytoscape.py

+78-4
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@
33
import os
44
import tempfile
55

6+
import pandas as pd
67

78
os.environ["PY4CYTOSCAPE_DETAIL_LOGGER_DIR"] = str(tempfile.gettempdir())
89

910
from pathlib import Path # noqa: E402
10-
from typing import Any, Union # noqa: E402
11+
from typing import Any, Union, Optional # noqa: E402
1112

13+
import libsbml
1214
import py4cytoscape as p4c # type: ignore # noqa: E402
1315
from requests.exceptions import RequestException # noqa: E402
1416

@@ -30,19 +32,91 @@ def visualize_antimony(source: Union[Path, str], delete_session: bool = False) -
3032
visualize_sbml(Path(f_tmp.name), delete_session=delete_session)
3133

3234

33-
def visualize_sbml(sbml_path: Path, delete_session: bool = False) -> None:
34-
"""Visualize SBML networks in cytoscape."""
35+
def visualize_sbml(sbml_path: Path, delete_session: bool = False) -> Optional[int]:
36+
"""Visualize SBML networks in cytoscape.
37+
38+
Returns dictionary with "networks" and "views".
39+
"""
40+
if sbml_path.suffix != ".xml":
41+
console.error(f"SBML path {sbml_path} does not have .xml extension")
3542

3643
try:
3744
console.print(p4c.cytoscape_version_info())
3845

3946
if delete_session:
4047
p4c.session.close_session(save_before_closing=False)
4148

42-
p4c.networks.import_network_from_file(str(sbml_path))
49+
networks_views = p4c.networks.import_network_from_file(str(sbml_path))
50+
console.print(f"{networks_views}")
51+
network = networks_views["networks"][1]
52+
p4c.set_current_view(network=network) # set the base network
53+
return network
54+
55+
return networks_views
4356

4457
except RequestException:
4558
logger.error(
4659
"Could not connect to a running Cytoscape instance. "
4760
"Start Cytoscape before running the python script."
4861
)
62+
return None
63+
64+
65+
66+
67+
68+
69+
70+
def read_layout_xml(sbml_path: Path, xml_path: Path) -> pd.DataFrame:
71+
"""Read own xml layout information form cytoscape."""
72+
# read positions
73+
df: pd.DataFrame = pd.read_xml(xml_path, xpath="//boundingBox")
74+
df = df[['id', 'xpos', 'ypos']]
75+
df.rename(columns={"xpos": "x", "ypos": "y"}, inplace=True)
76+
df.set_index("id", inplace=True)
77+
return df
78+
79+
def apply_layout(network, layout: pd.DataFrame) -> None:
80+
"""Apply layout information from Cytoscape to SBML networks."""
81+
82+
# get SUIDs, sbml_id from node table;
83+
df_nodes = p4c.get_table_columns(table="node", columns=["sbml id"], network=network)
84+
console.print(df_nodes)
85+
sid2suid = {row["sbml id"]: suid for suid, row in df_nodes.iterrows()}
86+
console.print(sid2suid)
87+
88+
# FIXME: necessary to check that all sids exist
89+
suids = [sid2suid[sid] for sid in layout.index.values]
90+
x_values = layout["x"].values.tolist()
91+
y_values = layout["y"].values.tolist()
92+
93+
# set positions
94+
# see: https://github.com/cytoscape/py4cytoscape/issues/144
95+
p4c.set_node_position_bypass(suids, new_x_locations=x_values, new_y_locations=y_values, network=network)
96+
# p4c.set_node_property_bypass(suids, new_values=x_values, visual_property='NODE_X_LOCATION', network=network)
97+
# p4c.set_node_property_bypass(suids, new_values=y_values, visual_property='NODE_Y_LOCATION', network=network)
98+
p4c.set_current_view(network=network)
99+
100+
# remove bypass
101+
# p4c.clear_node_property_bypass(suids, visual_property='NODE_X_LOCATION', network=network)
102+
# p4c.clear_node_property_bypass(suids, visual_property='NODE_Y_LOCATION', network=network)
103+
104+
# fit content
105+
p4c.fit_content()
106+
107+
108+
109+
if __name__ == "__main__":
110+
pass
111+
# # visual style
112+
# p4c.set_visual_style('Marquee')
113+
#
114+
# # fit the content
115+
# p4c.fit_content()
116+
117+
# p4c.load_table_data
118+
119+
# annotations!
120+
121+
# network_views.export_image
122+

0 commit comments

Comments
 (0)