Skip to content

Commit

Permalink
Merge devel into master (#284)
Browse files Browse the repository at this point in the history
* 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 <[email protected]>

* style: remove WARNING

Co-authored-by: Moritz E. Beber <[email protected]>

* fix: reconcile blocked with excluded reactions in OptKnock

* chore: unpin optlang

* chore: update pickles

Co-authored-by: Jorge Carrasco <[email protected]>
Co-authored-by: Moritz E. Beber <[email protected]>
  • Loading branch information
3 people authored Oct 5, 2021
1 parent a522da2 commit 7f0e9d3
Show file tree
Hide file tree
Showing 27 changed files with 1,538 additions and 2,945 deletions.
125 changes: 125 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
name: CI

on:
push:
branches:
- master
- devel
tags:
- '[0-9]+.[0-9]+.[0-9]+'
- '[0-9]+.[0-9]+.[0-9]+a[0-9]+'
pull_request:
branches:
- master
- devel
schedule:
# https://crontab.guru/#0_8_1_*_*
- cron: '0 8 1 * *'

jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
# consider using these
# os: [ubuntu-latest, macos-latest, windows-latest]
os: [ubuntu-latest]
python-version: [3.6, 3.7, 3.8]

steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
sudo apt install openbabel
python -m pip install --upgrade pip setuptools wheel
python -m pip install tox tox-gh-actions
- name: Install CPLEX (when supported)
env:
CPLEX_SECRET: ${{ secrets.CPLEX_SECRET }}
PYTHON_VERSION: ${{ matrix.python-version }}
shell: bash
run: ./scripts/install_cplex.sh
- name: Test with tox
run:
tox -- --cov-report=xml
- name: Report coverage
shell: bash
run: bash <(curl -s https://codecov.io/bash)

release:
needs: test
if: startsWith(github.ref, 'refs/tags')
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
python-version: [3.8]

steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Get tag
id: tag
run: echo "::set-output name=version::${GITHUB_REF#refs/tags/}"
- name: Install dependencies
run: |
python -m pip install --upgrade pip setuptools wheel
python -m pip install twine
- name: Build package
run: python setup.py sdist bdist_wheel
- name: Check the package
run: twine check dist/*
- name: Publish to PyPI
env:
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
run:
twine upload --skip-existing --non-interactive dist/*
- name: Create GitHub release
uses: actions/create-release@v1
env:
# This token is set by gh actions
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: ${{ github.ref }}
body_path: "release-notes/${{ steps.tag.outputs.version }}.md"
draft: false
prerelease: false

deploy-docs:
needs: test
if: startsWith(github.ref, 'refs/tags')
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
python-version: [3.8]

steps:
- uses: actions/checkout@v2
- name: Setup Python
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
# TODO: consider pip cache
run: |
sudo apt-get install pandoc swig
python3 -m pip install ".[docs,jupyter]"
- name: Build docs
run: cd docs && make apidoc && make html && touch _build/html/.nojekyll
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: docs/_build/html
cname: cameo.bio
95 changes: 0 additions & 95 deletions .travis.yml

This file was deleted.

20 changes: 0 additions & 20 deletions .travis/install_cplex.sh

This file was deleted.

4 changes: 3 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Cameo—Computer Aided Metabolic Engineering and Optimization
.. summary-start
|Join the chat at https://gitter.im/biosustain/cameo| |PyPI| |License|
|Build Status| |Coverage Status| |DOI| |zenhub|
|Build Status| |Coverage Status| |DOI| |zenhub| |binder|

What is cameo?
~~~~~~~~~~~~~~
Expand Down Expand Up @@ -141,3 +141,5 @@ Contributions
:target: https://zenodo.org/badge/latestdoi/5031/biosustain/cameo
.. |zenhub| image:: https://img.shields.io/badge/Shipping_faster_with-ZenHub-5e60ba.svg?style=flat-square
:target: https://zenhub.com
.. |binder| image:: https://mybinder.org/badge_logo.svg
:target: https://mybinder.org/v2/gh/biosustain/cameo-notebooks/binder?urlpath=lab/tree/index.ipynb
5 changes: 3 additions & 2 deletions cameo/flux_analysis/simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -518,9 +518,10 @@ def display_on_map(self, map_name=None, palette="YlGnBu"):

if in_ipnb():
from IPython.display import display
display(builder.display_in_notebook())
display(builder)
else:
builder.display_in_browser()
logger.info(f"Escher Map generated at {map_name}.html")
builder.save_html(f"{map_name}.html")

except ImportError:
print("Escher must be installed in order to visualize maps")
Expand Down
33 changes: 23 additions & 10 deletions cameo/strain_design/deterministic/flux_variability_based.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class DifferentialFVA(StrainDesignMethod):
Compares flux ranges of a reference model to a set of models that
have been parameterized to lie on a grid of evenly spaced points in the
n-dimensional production envelope (n being the number of reaction bounds
# n-dimensional production envelope (n being the number of reaction bounds
to be varied).
::
production
Expand Down Expand Up @@ -626,9 +626,22 @@ def nth_panel(self, index):
"""
return self.groups.get_group(sorted(self.groups.groups.keys())[index]).copy()

def plot(self, index=None, variables=None, grid=None, width=None, height=None, title=None, palette=None, **kwargs):
def plot(
self,
plotter,
index=None,
variables=None,
grid=None,
width=None,
height=None,
title=None,
palette=None,
**kwargs
):
if index is not None:
self._plot_flux_variability_analysis(index, variables=variables, width=width, grid=grid, palette=palette)
self._plot_flux_variability_analysis(
plotter, index, variables=variables, width=width, grid=grid, palette=palette
)
else:
self._plot_production_envelope(title=title, grid=grid, width=width, height=height)

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

if in_ipnb():
from IPython.display import display
display(builder.display_in_notebook())
display(builder)
else:
builder.display_in_browser()
logger.info(f"Escher Map generated at {map_name}.html")
builder.save_html(f"{map_name}.html")

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


class _DifferentialFvaEvaluator(object):
Expand All @@ -848,7 +862,7 @@ def _set_bounds(self, point):
reaction.upper_bound = reaction.lower_bound = bound
target_reaction = self.model.reactions.get_by_id(self.objective)
target_bound = point[self.objective]
target_reaction.upper_bound = target_reaction.lower_bound = target_bound
target_reaction.bounds = (target_bound, target_bound)


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

for level in levels:
target.lower_bound = level
target.upper_bound = level
target.bounds = (level, level)
solution = simulation_method(model, **simulation_kwargs)
for reaction_id, flux in solution.fluxes.iteritems():
for reaction_id, flux in solution.fluxes.items():
results[reaction_id].append(round(flux, ndecimals))

# Test each reaction
Expand Down
13 changes: 8 additions & 5 deletions cameo/strain_design/deterministic/linear_programming.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,16 @@ def __init__(self, model, exclude_reactions=None, remove_blocked=True, fraction_

if fraction_of_optimum is not None:
fix_objective_as_constraint(self._model, fraction=fraction_of_optimum)
if remove_blocked:
self._remove_blocked_reactions()
blocked = self._remove_blocked_reactions() if remove_blocked else []
if exclude_reactions:
# Convert exclude_reactions to reaction ID's
exclude_reactions = [
r.id if isinstance(r, cobra.core.Reaction) else r for r in exclude_reactions
r.id if isinstance(r, cobra.core.Reaction) else r
for r in exclude_reactions
]
# if a blocked reaction were in exclude reactions, it would raise
# because blocked reactions are removed from the model
exclude_reactions = [r_id for r_id in exclude_reactions if r_id not in blocked]
for r_id in exclude_reactions:
if r_id not in self._model.reactions:
raise ValueError("Excluded reaction {} is not in the model".format(r_id))
Expand All @@ -139,13 +142,13 @@ def __init__(self, model, exclude_reactions=None, remove_blocked=True, fraction_

def _remove_blocked_reactions(self):
fva_res = flux_variability_analysis(self._model, fraction_of_optimum=0)
# FIXME: Iterate over the index only (reaction identifiers).
blocked = [
self._model.reactions.get_by_id(reaction) for reaction, row in fva_res.data_frame.iterrows()
reaction for reaction, row in fva_res.data_frame.iterrows()
if (round(row["lower_bound"], config.ndecimals) == round(
row["upper_bound"], config.ndecimals) == 0)
]
self._model.remove_reactions(blocked)
return blocked

def _reduce_to_nullspace(self, reactions):
self.reaction_groups = find_coupled_reactions_nullspace(self._model)
Expand Down
2 changes: 1 addition & 1 deletion cameo/visualization/escher_ext.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,4 @@ def _draw_js(self, the_id, enable_editing, menu, enable_keys, dev,
return draw

def _repr_html_(self):
return self.display_in_notebook()
return display(self)
Loading

0 comments on commit 7f0e9d3

Please sign in to comment.