[med-svn] [Git][med-team/python-cobra][upstream] New upstream version 0.26.3
Étienne Mollier (@emollier)
gitlab at salsa.debian.org
Thu Jun 22 21:06:22 BST 2023
Étienne Mollier pushed to branch upstream at Debian Med / python-cobra
Commits:
7c25ffb1 by Étienne Mollier at 2023-06-22T21:20:48+02:00
New upstream version 0.26.3
- - - - -
17 changed files:
- + release-notes/0.26.3.md
- setup.cfg
- setup.py
- src/cobra/__init__.py
- src/cobra/core/dictlist.py
- src/cobra/core/formula.py
- src/cobra/core/metabolite.py
- src/cobra/core/model.py
- src/cobra/core/reaction.py
- src/cobra/core/solution.py
- src/cobra/io/dict.py
- src/cobra/io/sbml.py
- src/cobra/io/web/cobrapy_repository.py
- src/cobra/sampling/hr_sampler.py
- tests/test_flux_analysis/test_deletion.py
- tests/test_io/test_sbml.py
- tests/test_util/test_context.py
Changes:
=====================================
release-notes/0.26.3.md
=====================================
@@ -0,0 +1,20 @@
+# Release notes for cobrapy x.y.z
+
+## New features
+
+## Fixes
+
+Fixed an issue where reaction bounds were being overwritten by global model min/max values
+when writing sbml model to file. See [#1300](https://github.com/opencobra/cobrapy/pull/1312).
+
+Fix an issue where [`runfrog`](https://github.com/matthiaskoenig/fbc_curation/issues/98) does
+not work via github actions or local installation by removing the use of obsolete numpy
+aliases for `float` and `bool`.
+
+Fix a bug where installing httpx>=0.24 would break cobrapy IO.
+
+## Other
+
+## Deprecated features
+
+## Backwards incompatible changes
=====================================
setup.cfg
=====================================
@@ -1,5 +1,5 @@
[bumpversion]
-current_version = 0.26.2
+current_version = 0.26.3
commit = True
tag = True
parse = (?P<major>\d+)
@@ -58,7 +58,7 @@ install_requires =
depinfo ~=1.7
diskcache ~=5.0
future
- httpx ~=0.14
+ httpx ~=0.24
importlib_resources
numpy >=1.13,<1.24
optlang ~=1.5
=====================================
setup.py
=====================================
@@ -19,4 +19,4 @@ if version_info[:2] < (3, 6):
# All other arguments are defined in `setup.cfg`.
if __name__ == "__main__":
- setup(version="0.26.2")
+ setup(version="0.26.3")
=====================================
src/cobra/__init__.py
=====================================
@@ -1,5 +1,5 @@
__author__ = "The cobrapy core development team."
-__version__ = "0.26.2"
+__version__ = "0.26.3"
from cobra.core import (
=====================================
src/cobra/core/dictlist.py
=====================================
@@ -15,8 +15,6 @@ from typing import (
Union,
)
-import numpy as np
-
from .object import Object
@@ -457,7 +455,7 @@ class DictList(list):
selection._extend_nocheck(list.__getitem__(self, i))
return selection
elif hasattr(i, "__len__"):
- if len(i) == len(self) and isinstance(i[0], (bool, np.bool)):
+ if len(i) == len(self) and isinstance(i[0], (bool, bool)):
selection = self.__class__()
result = (o for j, o in enumerate(self) if i[j])
selection._extend_nocheck(result)
=====================================
src/cobra/core/formula.py
=====================================
@@ -63,7 +63,7 @@ class Formula(Object):
return
composition = {}
parsed = element_re.findall(tmp_formula)
- for (element, count) in parsed:
+ for element, count in parsed:
if count == "":
count = 1
else:
=====================================
src/cobra/core/metabolite.py
=====================================
@@ -133,7 +133,7 @@ class Metabolite(Species):
return None
composition = {}
parsed = element_re.findall(tmp_formula)
- for (element, count) in parsed:
+ for element, count in parsed:
if count == "":
count = 1
else:
=====================================
src/cobra/core/model.py
=====================================
@@ -32,7 +32,6 @@ from .solution import get_solution
if TYPE_CHECKING:
-
import pandas as pd
from optlang.container import Container
@@ -781,7 +780,6 @@ class Model(Object):
context = get_context(self)
for reaction in reactions:
-
# Make sure the reaction is in the model
try:
reaction = self.reactions[self.reactions.index(reaction)]
@@ -793,7 +791,6 @@ class Model(Object):
reverse = reaction.reverse_variable
if context:
-
obj_coef = reaction.objective_coefficient
if obj_coef != 0:
=====================================
src/cobra/core/reaction.py
=====================================
@@ -1228,7 +1228,6 @@ class Reaction(Object):
_id_to_metabolites = dict([(x.id, x) for x in self._metabolites])
for metabolite, coefficient in metabolites_to_add.items():
-
# Make sure metabolites being added belong to the same model, or
# else copy them.
if isinstance(metabolite, Metabolite):
=====================================
src/cobra/core/solution.py
=====================================
@@ -177,13 +177,13 @@ def get_solution(
if model.solver.is_integer:
reduced.fill(np.nan)
shadow.fill(np.nan)
- for (i, rxn) in enumerate(reactions):
+ for i, rxn in enumerate(reactions):
rxn_index.append(rxn.id)
fluxes[i] = var_primals[rxn.id] - var_primals[rxn.reverse_id]
met_index = [met.id for met in metabolites]
else:
var_duals = model.solver.reduced_costs
- for (i, rxn) in enumerate(reactions):
+ for i, rxn in enumerate(reactions):
forward = rxn.id
reverse = rxn.reverse_id
rxn_index.append(forward)
@@ -191,7 +191,7 @@ def get_solution(
reduced[i] = var_duals[forward] - var_duals[reverse]
met_index = []
constr_duals = model.solver.shadow_prices
- for (i, met) in enumerate(metabolites):
+ for i, met in enumerate(metabolites):
met_index.append(met.id)
shadow[i] = constr_duals[met.id]
return Solution(
=====================================
src/cobra/io/dict.py
=====================================
@@ -68,13 +68,13 @@ _OPTIONAL_MODEL_ATTRIBUTES = {
def _fix_type(
- value: Union[str, np.float, np.bool, Set, Dict]
+ value: Union[str, float, bool, Set, Dict]
) -> Union[str, float, bool, List, OrderedDict]:
"""Convert possible types to correct Python types.
Parameters
----------
- value : str, np.float, np.bool, set, dict
+ value : str, float, bool, set, dict
The value to fix type for.
Returns
@@ -86,9 +86,9 @@ def _fix_type(
# Because numpy floats can not be pickled to json
if isinstance(value, str):
return str(value)
- if isinstance(value, np.float):
+ if isinstance(value, float):
return float(value)
- if isinstance(value, np.bool):
+ if isinstance(value, bool):
return bool(value)
if isinstance(value, set):
return list(value)
=====================================
src/cobra/io/sbml.py
=====================================
@@ -1038,7 +1038,6 @@ def _sbml_to_model(
model.getListOfReactions(),
model_groups.getListOfGroups(),
]:
-
sbase: "libsbml.SBase"
for sbase in obj_list:
if sbase.isSetId():
@@ -1277,13 +1276,8 @@ def _model_to_sbml(
unit.setScale(u.scale)
unit.setMultiplier(u.multiplier)
- # minimum and maximum value from model
- if len(cobra_model.reactions) > 0:
- min_value = min(cobra_model.reactions.list_attr("lower_bound"))
- max_value = max(cobra_model.reactions.list_attr("upper_bound"))
- else:
- min_value = config.lower_bound
- max_value = config.upper_bound
+ min_value = config.lower_bound
+ max_value = config.upper_bound
_create_parameter(
model, pid=LOWER_BOUND_ID, value=min_value, sbo=SBO_DEFAULT_FLUX_BOUND
@@ -1875,7 +1869,6 @@ def _sbase_annotations(sbase: libsbml.SBase, annotation: dict) -> None:
# rdf_items = []
for provider, data in annotation_data.items():
-
# set SBOTerm
if provider in ["SBO", "sbo"]:
if provider == "SBO":
=====================================
src/cobra/io/web/cobrapy_repository.py
=====================================
@@ -33,7 +33,7 @@ class Cobrapy(AbstractModelRepository):
Passed to the parent constructor in order to enable multiple inheritance.
"""
- super().__init__(url="file:////", **kwargs)
+ super().__init__(url="file://", **kwargs)
def get_sbml(self, model_id: str) -> bytes:
"""
=====================================
src/cobra/sampling/hr_sampler.py
=====================================
@@ -323,9 +323,7 @@ class HRSampler(ABC):
primals = self.model.solver.primal_values
sol = [primals[v.name] for v in self.model.variables]
- self.warmup[
- self.n_warmup,
- ] = sol
+ self.warmup[self.n_warmup,] = sol
self.n_warmup += 1
# Reset objective
@@ -425,33 +423,13 @@ class HRSampler(ABC):
def _bounds_dist(self, p: np.ndarray) -> np.ndarray:
"""Get the lower and upper bound distances. Negative is bad."""
prob = self.problem
- lb_dist = (
- p
- - prob.variable_bounds[
- 0,
- ]
- ).min()
- ub_dist = (
- prob.variable_bounds[
- 1,
- ]
- - p
- ).min()
+ lb_dist = (p - prob.variable_bounds[0,]).min()
+ ub_dist = (prob.variable_bounds[1,] - p).min()
if prob.bounds.shape[0] > 0:
const = prob.inequalities.dot(p)
- const_lb_dist = (
- const
- - prob.bounds[
- 0,
- ]
- ).min()
- const_ub_dist = (
- prob.bounds[
- 1,
- ]
- - const
- ).min()
+ const_lb_dist = (const - prob.bounds[0,]).min()
+ const_ub_dist = (prob.bounds[1,] - const).min()
lb_dist = min(lb_dist, const_lb_dist)
ub_dist = min(ub_dist, const_ub_dist)
@@ -564,38 +542,18 @@ class HRSampler(ABC):
)
feasibility = np.abs(S.dot(samples.T).T - b).max(axis=1)
- lb_error = (
- samples
- - bounds[
- 0,
- ]
- ).min(axis=1)
- ub_error = (
- bounds[
- 1,
- ]
- - samples
- ).min(axis=1)
+ lb_error = (samples - bounds[0,]).min(axis=1)
+ ub_error = (bounds[1,] - samples).min(axis=1)
if samples.shape[1] == len(self.model.variables) and prob.inequalities.shape[0]:
consts = prob.inequalities.dot(samples.T)
lb_error = np.minimum(
lb_error,
- (
- consts
- - prob.bounds[
- 0,
- ]
- ).min(axis=1),
+ (consts - prob.bounds[0,]).min(axis=1),
)
ub_error = np.minimum(
ub_error,
- (
- prob.bounds[
- 1,
- ]
- - consts
- ).min(axis=1),
+ (prob.bounds[1,] - consts).min(axis=1),
)
valid = (
=====================================
tests/test_flux_analysis/test_deletion.py
=====================================
@@ -428,7 +428,7 @@ def test_double_reaction_deletion(model: Model) -> None:
solution_one_process = double_reaction_deletion(
model, reaction_list1=reactions, processes=1
)
- for (rxn_a, sub) in growth_dict.items():
+ for rxn_a, sub in growth_dict.items():
for rxn_b, growth in sub.items():
sol = solution.knockout[{rxn_a, rxn_b}]
sol_one = solution_one_process.knockout[{rxn_a, rxn_b}]
=====================================
tests/test_io/test_sbml.py
=====================================
@@ -511,6 +511,45 @@ def test_boundary_conditions(data_directory: Path) -> None:
assert sol1.objective_value == sol2.objective_value
+def test_bounds_on_write(data_directory: Path, tmp_path: Path) -> None:
+ """Test infinity bound example.
+
+ Parameters
+ ----------
+ data_directory: Path
+ Directory where the data is.
+ """
+ sbml_path1 = data_directory / "fbc_ex1.xml"
+ model1 = read_sbml_model(sbml_path1)
+
+ r_x = model1.reactions.get_by_id("EX_X")
+ r_y = model1.reactions.get_by_id("EX_Ac")
+
+ r_x.bounds = (config.lower_bound - 1000, config.upper_bound + 1000)
+ assert r_x.lower_bound == config.lower_bound - 1000
+ assert r_x.upper_bound == config.upper_bound + 1000
+
+ # Global min/max bounds for other reactions should not change before & after write!
+ r_y.bounds = (config.lower_bound, config.upper_bound)
+ assert r_y.lower_bound == config.lower_bound
+ assert r_y.upper_bound == config.upper_bound
+
+ sbml_path = tmp_path / "test.xml"
+ with open(sbml_path, "w") as f_out:
+ write_sbml_model(model1, f_out)
+
+ with open(sbml_path, "r") as f_in:
+ model2 = read_sbml_model(f_in)
+
+ r2_x = model2.reactions.get_by_id("EX_X")
+ r2_y = model2.reactions.get_by_id("EX_Ac")
+
+ assert r2_x.lower_bound == r_x.lower_bound
+ assert r2_x.upper_bound == r_x.upper_bound
+ assert r2_y.lower_bound == r_y.lower_bound # before fix #1300, this would fail
+ assert r2_y.upper_bound == r_y.upper_bound # before fix #1300, this would fail
+
+
def test_gprs(large_model: Model, tmp_path: Path) -> None:
"""Test that GPRs are written and read correctly.
=====================================
tests/test_util/test_context.py
=====================================
@@ -39,6 +39,7 @@ def test_get_context(model: "Model") -> None:
def test_resettable() -> None:
"""Test if resettable decorator is functional."""
+
# decorate a dummy function
@resettable
def change_my_name(old_name, new_name):
View it on GitLab: https://salsa.debian.org/med-team/python-cobra/-/commit/7c25ffb143e459c6ffb4c1c669292adc43b1b74c
--
View it on GitLab: https://salsa.debian.org/med-team/python-cobra/-/commit/7c25ffb143e459c6ffb4c1c669292adc43b1b74c
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/debian-med-commit/attachments/20230622/c1b76511/attachment-0001.htm>
More information about the debian-med-commit
mailing list