Skip to content

Commit 7f0e9d3

Browse files
phantomas1234carrascomjMidnighter
authored
Merge devel into master (#284)
* Replace Travis with github actions (#270) * chore: replace travis with gh actions * test: replace TRAVIS env var with CI * test: run CI only linux for now * chore: add release gh action * docs: add docs gh action * fix: get syntax and deps right * chore: merge docs with release action * fix: install openbabel on CI * refactor: merge release and main actions * fix: use secrets for publishing to pypi * chore: install CPLEX on CI py3.6 * fix: typo * fix: extract cplex properly * chore: schedule CI run every month * Fix plotting (#272) * fix: update escher everywhere * docs: explain how to work in jupyterlab * style: apply flake8 * docs: format missing code block properly * fix: remove docstring typo * Refactor bounds behaviour (#273) * fix: update escher everywhere * docs: explain how to work in jupyterlab * style: apply flake8 * docs: format missing code block properly * refactor: adopt new bounds behavior opencobra/cobrapy#793 * style: improve readability * docs: add badge to binder (#274) * Docs enhance (#276) * fix: update escher everywhere * docs: explain how to work in jupyterlab * style: apply flake8 * docs: format missing code block properly * docs: show favicon * docs: regenerate tutorial notebooks * style: use :py: in API links Co-authored-by: Moritz E. Beber <midnighter@posteo.net> * style: remove WARNING Co-authored-by: Moritz E. Beber <midnighter@posteo.net> * fix: reconcile blocked with excluded reactions in OptKnock * chore: unpin optlang * chore: update pickles Co-authored-by: Jorge Carrasco <carrascomurielj@gmail.com> Co-authored-by: Moritz E. Beber <midnighter@posteo.net>
1 parent a522da2 commit 7f0e9d3

27 files changed

+1538
-2945
lines changed

.github/workflows/main.yml

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
- devel
8+
tags:
9+
- '[0-9]+.[0-9]+.[0-9]+'
10+
- '[0-9]+.[0-9]+.[0-9]+a[0-9]+'
11+
pull_request:
12+
branches:
13+
- master
14+
- devel
15+
schedule:
16+
# https://crontab.guru/#0_8_1_*_*
17+
- cron: '0 8 1 * *'
18+
19+
jobs:
20+
test:
21+
runs-on: ${{ matrix.os }}
22+
strategy:
23+
fail-fast: false
24+
matrix:
25+
# consider using these
26+
# os: [ubuntu-latest, macos-latest, windows-latest]
27+
os: [ubuntu-latest]
28+
python-version: [3.6, 3.7, 3.8]
29+
30+
steps:
31+
- uses: actions/checkout@v2
32+
- name: Set up Python ${{ matrix.python-version }}
33+
uses: actions/setup-python@v2
34+
with:
35+
python-version: ${{ matrix.python-version }}
36+
- name: Install dependencies
37+
run: |
38+
sudo apt install openbabel
39+
python -m pip install --upgrade pip setuptools wheel
40+
python -m pip install tox tox-gh-actions
41+
- name: Install CPLEX (when supported)
42+
env:
43+
CPLEX_SECRET: ${{ secrets.CPLEX_SECRET }}
44+
PYTHON_VERSION: ${{ matrix.python-version }}
45+
shell: bash
46+
run: ./scripts/install_cplex.sh
47+
- name: Test with tox
48+
run:
49+
tox -- --cov-report=xml
50+
- name: Report coverage
51+
shell: bash
52+
run: bash <(curl -s https://codecov.io/bash)
53+
54+
release:
55+
needs: test
56+
if: startsWith(github.ref, 'refs/tags')
57+
runs-on: ${{ matrix.os }}
58+
strategy:
59+
matrix:
60+
os: [ubuntu-latest]
61+
python-version: [3.8]
62+
63+
steps:
64+
- uses: actions/checkout@v2
65+
- name: Set up Python ${{ matrix.python-version }}
66+
uses: actions/setup-python@v2
67+
with:
68+
python-version: ${{ matrix.python-version }}
69+
- name: Get tag
70+
id: tag
71+
run: echo "::set-output name=version::${GITHUB_REF#refs/tags/}"
72+
- name: Install dependencies
73+
run: |
74+
python -m pip install --upgrade pip setuptools wheel
75+
python -m pip install twine
76+
- name: Build package
77+
run: python setup.py sdist bdist_wheel
78+
- name: Check the package
79+
run: twine check dist/*
80+
- name: Publish to PyPI
81+
env:
82+
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
83+
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
84+
run:
85+
twine upload --skip-existing --non-interactive dist/*
86+
- name: Create GitHub release
87+
uses: actions/create-release@v1
88+
env:
89+
# This token is set by gh actions
90+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
91+
with:
92+
tag_name: ${{ github.ref }}
93+
release_name: ${{ github.ref }}
94+
body_path: "release-notes/${{ steps.tag.outputs.version }}.md"
95+
draft: false
96+
prerelease: false
97+
98+
deploy-docs:
99+
needs: test
100+
if: startsWith(github.ref, 'refs/tags')
101+
runs-on: ${{ matrix.os }}
102+
strategy:
103+
matrix:
104+
os: [ubuntu-latest]
105+
python-version: [3.8]
106+
107+
steps:
108+
- uses: actions/checkout@v2
109+
- name: Setup Python
110+
uses: actions/setup-python@v2
111+
with:
112+
python-version: ${{ matrix.python-version }}
113+
- name: Install dependencies
114+
# TODO: consider pip cache
115+
run: |
116+
sudo apt-get install pandoc swig
117+
python3 -m pip install ".[docs,jupyter]"
118+
- name: Build docs
119+
run: cd docs && make apidoc && make html && touch _build/html/.nojekyll
120+
- name: Deploy
121+
uses: peaceiris/actions-gh-pages@v3
122+
with:
123+
github_token: ${{ secrets.GITHUB_TOKEN }}
124+
publish_dir: docs/_build/html
125+
cname: cameo.bio

.travis.yml

Lines changed: 0 additions & 95 deletions
This file was deleted.

.travis/install_cplex.sh

Lines changed: 0 additions & 20 deletions
This file was deleted.

README.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Cameo—Computer Aided Metabolic Engineering and Optimization
44
.. summary-start
55
66
|Join the chat at https://gitter.im/biosustain/cameo| |PyPI| |License|
7-
|Build Status| |Coverage Status| |DOI| |zenhub|
7+
|Build Status| |Coverage Status| |DOI| |zenhub| |binder|
88

99
What is cameo?
1010
~~~~~~~~~~~~~~
@@ -141,3 +141,5 @@ Contributions
141141
:target: https://zenodo.org/badge/latestdoi/5031/biosustain/cameo
142142
.. |zenhub| image:: https://img.shields.io/badge/Shipping_faster_with-ZenHub-5e60ba.svg?style=flat-square
143143
:target: https://zenhub.com
144+
.. |binder| image:: https://mybinder.org/badge_logo.svg
145+
:target: https://mybinder.org/v2/gh/biosustain/cameo-notebooks/binder?urlpath=lab/tree/index.ipynb

cameo/flux_analysis/simulation.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -518,9 +518,10 @@ def display_on_map(self, map_name=None, palette="YlGnBu"):
518518

519519
if in_ipnb():
520520
from IPython.display import display
521-
display(builder.display_in_notebook())
521+
display(builder)
522522
else:
523-
builder.display_in_browser()
523+
logger.info(f"Escher Map generated at {map_name}.html")
524+
builder.save_html(f"{map_name}.html")
524525

525526
except ImportError:
526527
print("Escher must be installed in order to visualize maps")

cameo/strain_design/deterministic/flux_variability_based.py

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ class DifferentialFVA(StrainDesignMethod):
7777
7878
Compares flux ranges of a reference model to a set of models that
7979
have been parameterized to lie on a grid of evenly spaced points in the
80-
n-dimensional production envelope (n being the number of reaction bounds
80+
# n-dimensional production envelope (n being the number of reaction bounds
8181
to be varied).
8282
::
8383
production
@@ -626,9 +626,22 @@ def nth_panel(self, index):
626626
"""
627627
return self.groups.get_group(sorted(self.groups.groups.keys())[index]).copy()
628628

629-
def plot(self, index=None, variables=None, grid=None, width=None, height=None, title=None, palette=None, **kwargs):
629+
def plot(
630+
self,
631+
plotter,
632+
index=None,
633+
variables=None,
634+
grid=None,
635+
width=None,
636+
height=None,
637+
title=None,
638+
palette=None,
639+
**kwargs
640+
):
630641
if index is not None:
631-
self._plot_flux_variability_analysis(index, variables=variables, width=width, grid=grid, palette=palette)
642+
self._plot_flux_variability_analysis(
643+
plotter, index, variables=variables, width=width, grid=grid, palette=palette
644+
)
632645
else:
633646
self._plot_production_envelope(title=title, grid=grid, width=width, height=height)
634647

@@ -768,9 +781,10 @@ def _display_on_map_static(self, index, map_name, palette="RdYlBu", **kwargs):
768781

769782
if in_ipnb():
770783
from IPython.display import display
771-
display(builder.display_in_notebook())
784+
display(builder)
772785
else:
773-
builder.display_in_browser()
786+
logger.info(f"Escher Map generated at {map_name}.html")
787+
builder.save_html(f"{map_name}.html")
774788

775789
except ImportError:
776790
print("Escher must be installed in order to visualize maps")
@@ -821,7 +835,7 @@ def _init_builder(self, reaction_data, objective, variable):
821835
dict(type='min', color="red", size=20),
822836
dict(type='median', color="grey", size=7),
823837
dict(type='max', color='green', size=20)], **self.kwargs_for_escher)
824-
display(self.builder.display_in_notebook())
838+
display(self.builder)
825839

826840

827841
class _DifferentialFvaEvaluator(object):
@@ -848,7 +862,7 @@ def _set_bounds(self, point):
848862
reaction.upper_bound = reaction.lower_bound = bound
849863
target_reaction = self.model.reactions.get_by_id(self.objective)
850864
target_bound = point[self.objective]
851-
target_reaction.upper_bound = target_reaction.lower_bound = target_bound
865+
target_reaction.bounds = (target_bound, target_bound)
852866

853867

854868
class FSEOF(StrainDesignMethod):
@@ -964,10 +978,9 @@ def run(self, target=None, max_enforced_flux=0.9, number_of_results=10, exclude=
964978
results = {reaction.id: [] for reaction in model.reactions}
965979

966980
for level in levels:
967-
target.lower_bound = level
968-
target.upper_bound = level
981+
target.bounds = (level, level)
969982
solution = simulation_method(model, **simulation_kwargs)
970-
for reaction_id, flux in solution.fluxes.iteritems():
983+
for reaction_id, flux in solution.fluxes.items():
971984
results[reaction_id].append(round(flux, ndecimals))
972985

973986
# Test each reaction

cameo/strain_design/deterministic/linear_programming.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -120,13 +120,16 @@ def __init__(self, model, exclude_reactions=None, remove_blocked=True, fraction_
120120

121121
if fraction_of_optimum is not None:
122122
fix_objective_as_constraint(self._model, fraction=fraction_of_optimum)
123-
if remove_blocked:
124-
self._remove_blocked_reactions()
123+
blocked = self._remove_blocked_reactions() if remove_blocked else []
125124
if exclude_reactions:
126125
# Convert exclude_reactions to reaction ID's
127126
exclude_reactions = [
128-
r.id if isinstance(r, cobra.core.Reaction) else r for r in exclude_reactions
127+
r.id if isinstance(r, cobra.core.Reaction) else r
128+
for r in exclude_reactions
129129
]
130+
# if a blocked reaction were in exclude reactions, it would raise
131+
# because blocked reactions are removed from the model
132+
exclude_reactions = [r_id for r_id in exclude_reactions if r_id not in blocked]
130133
for r_id in exclude_reactions:
131134
if r_id not in self._model.reactions:
132135
raise ValueError("Excluded reaction {} is not in the model".format(r_id))
@@ -139,13 +142,13 @@ def __init__(self, model, exclude_reactions=None, remove_blocked=True, fraction_
139142

140143
def _remove_blocked_reactions(self):
141144
fva_res = flux_variability_analysis(self._model, fraction_of_optimum=0)
142-
# FIXME: Iterate over the index only (reaction identifiers).
143145
blocked = [
144-
self._model.reactions.get_by_id(reaction) for reaction, row in fva_res.data_frame.iterrows()
146+
reaction for reaction, row in fva_res.data_frame.iterrows()
145147
if (round(row["lower_bound"], config.ndecimals) == round(
146148
row["upper_bound"], config.ndecimals) == 0)
147149
]
148150
self._model.remove_reactions(blocked)
151+
return blocked
149152

150153
def _reduce_to_nullspace(self, reactions):
151154
self.reaction_groups = find_coupled_reactions_nullspace(self._model)

cameo/visualization/escher_ext.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,4 +99,4 @@ def _draw_js(self, the_id, enable_editing, menu, enable_keys, dev,
9999
return draw
100100

101101
def _repr_html_(self):
102-
return self.display_in_notebook()
102+
return display(self)

0 commit comments

Comments
 (0)