-
Notifications
You must be signed in to change notification settings - Fork 227
Description
Is there an existing issue for this?
- I have searched the existing issues
Problem description
I wanted to test if two reactions we the same at least as far as having the same metabolites involved with same ratios (cf #1414 ).
I remembered that +
and -
were overloaded on Reaction
s to combine the metabolites.
So I thought if I substracted them I would get an empty set of metabolites,
and thus I could know they were equivalent reactions (at least as far as that was concerned)
I wrote a bunch of test cases before i started and the one where I was comparing two reactions that were expressed in opposite directions failed
Code sample
Code run:
In [1]: import cobra
...:
...: def add_reaction_from_string(model: cobra.Model, reaction_str: str):
...: # helper for demo
...: reaction = cobra.Reaction(f"r_{len(model.reactions)}")
...: model.add_reactions([reaction])
...: # awkwardly, you can't build a reaction from a string without *first* attaching it to am model
...: reaction.build_reaction_from_string(reaction_str)
...: return reaction
...:
...:
...:
...: model1 = cobra.Model("model1")
...: model1.add_metabolites([
...: cobra.Metabolite("m_foo"),
...: cobra.Metabolite("m_bar")
...: ])
...:
...: r1 = add_reaction_from_string(model1, "m_foo --> m_bar")
...: r2 = add_reaction_from_string(model1, "m_bar <-- m_foo")
...: r_diff = r1 - r2
...:
...: r_diff.metabolites
Out[1]:
{<Metabolite m_foo at 0x7f6d668c9730>: -2,
<Metabolite m_bar at 0x7f6d668c9760>: 2}
Rather than being empty the result is as if I had doubled r1
I believe this is because of the bounds:
In [2]: r1.bounds
Out[2]: (0, 1000.0)
In [3]: r2.bounds
Out[3]: (-1000.0, 0)
In [4]: r_diff.bounds
Out[4]: (0, 1000.0)
Then I also checked +
In [5]: r_sum = r1 + r2
In [6]: r_sum.metabolites
Out[6]: {}
In [7]: r_sum.bounds
Out[7]: (0, 1000.0)
which is the result i expected for -
Environment
Package Information
Package | Version |
---|---|
cobra | 0.29.1 |
Dependency Information
Package | Version |
---|---|
appdirs~ | missing |
black | missing |
bumpversion | missing |
depinfo~ | missing |
diskcache~ | missing |
future | 1.0.0 |
httpx~ | missing |
importlib-resources | 6.5.2 |
isort | missing |
numpy | 2.1.3 |
optlang~ | missing |
pandas | 2.2.3 |
pydantic | 2.10.6 |
python-libsbml~ | missing |
rich | 13.9.4 |
ruamel.yaml~ | missing |
scipy | 1.15.2 |
swiglpk | 5.0.12 |
tox | missing |
Build Tools Information
Package | Version |
---|---|
pip | 24.3.1 |
setuptools | 75.8.2 |
wheel | 0.45.1 |
Platform Information
Linux | 6.8.0-49-generic-x86_64 |
CPython | 3.12.9 |
Anything else?
Possible resolution options:
remove reaction addition/subtraction
I don't think it is a particularly intuitive feature.
If people want to do this addition let them just do it on the reaction.metabolites
themselves and then create a new Reaction
object to store the results.
Maybe could define helpers like a subtype of dict
that has math defined.
Which would also force them to make decisions about the bounds
Make this an error when bounds do not agree
Can't add things with different bounds implies can't add things with different directions.
Though this doesn't help for reversible reactions.
Canonicalize sides on creation
In the representation of the metabolites + bounds, arrange things such that the same set of metabolite is always on same side.
This does however mean that not all reactants will be negative and not all products positive in the reaction.metabolites
dictionary
match direction as an initial step during addition/subtraction
Not sure how this would go for reactions that and reversible though.