Add reaction & add metabolite with prefix [continue]

299 views
Skip to first unread message

Karen Chung

unread,
Feb 5, 2021, 8:34:04 AM2/5/21
to cobra pie
Hi, I was replying to my previous posted conversation but not sure why it was kept being deleted.


Hi Matthias,

Thanks for your reply.

If I want to the exchange reaction of 3php_c, do I have to change its compartment from _c to _e


Screenshot 2021-02-01 at 6.34.52 PM.png

Moritz Beber

unread,
Feb 5, 2021, 9:18:53 AM2/5/21
to cobr...@googlegroups.com
(It got marked as spam somehow.)
--
You received this message because you are subscribed to the Google Groups "cobra pie" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cobra-pie+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/cobra-pie/8453bd62-1c1b-4adc-a2d1-e06490db3899n%40googlegroups.com.

Karen Chung

unread,
Feb 7, 2021, 11:12:27 PM2/7/21
to cobra pie

I thought there was some problem with my post, so I kept posted and tried for few times.

Anyway, I have question on adding an exchange reaction.

R_EX_3php: 3php_e -> (exchange reaction)

R_3php_cross_om_transport: 3php_e -> 3php_p (extracellular to periplasm)

R_3php_cross_im_transport: 3php_p + h_p -> 3php_c + h_c (periplasm)


The metabolite 3php_c is in my model.

Screenshot 2021-02-01 at 6.32.27 PM.png
To add the exchange reaction, is that I'll need to change its compartment from _c to _e ? or how do I add the exchange reaction?
Screenshot 2021-02-01 at 6.34.52 PM.png

Thank you in advance.

Regards,
Karen

Matthias König

unread,
Feb 8, 2021, 8:54:02 AM2/8/21
to cobra pie
Hi Karen,
There are some strange design decisions in cobrapy which try to enforce good model building behavior.
One of these decisions is apparently that exchange reactions have to be on metabolites in the external compartment.
For me this does not make much sense, because sometimes one wants just to have an unbalanced internal metabolite or in another compartment then the default external compartment.
What you have to do in such a case is to add a dummy external metabolite with corresponding transport reaction. Only afterwards you define the exchange on the dummy metabolite.

This will be the same from an LP problem point of view because you just add a linear chain to the model:
3php_c <--R_3php_c_dummy--> 3php_c_dummy <-- EX_3php_c_dummy -->

Here an example:
from cobra.core import Model, Reaction, Metabolite

# example model with metabolite
model = Model()

# define metabolite
s1 = Metabolite(id="3php_c", compartment="c")
# define external dummy metabolite belonging to the metabolite
s1_dummy = Metabolite(id="3php_c_dummy", compartment="e")
model.add_metabolites([s1, s1_dummy])

# add dummy reaction for the transport to extern
r_dummy = Reaction(id="R_3php_c_dummy")
model.add_reactions([r_dummy])
r_dummy.add_metabolites({"3php_c_dummy": -1.0, "3php_c": 1.0})


# setting this as an objective to get summary functionality (not important, ignore)
model.objective = 'R_3php_c_dummy'

print("exchanges", model.exchanges)
print("-" * 80)

# add exchange reaction for metabolite
model.add_boundary(s1_dummy, type="exchange")
print("exchanges", model.exchanges)


Which adds the exchange to the model
There are no boundary reactions in this model. Therefore specific types of boundary reactions such as 'exchanges', 'demands' or 'sinks' cannot be identified.
exchanges []
--------------------------------------------------------------------------------
exchanges [<Reaction EX_3php_c_dummy at 0x7f92e7871f40>]


I agree. This is confusing and the behavior you expect should work. And I am in a strong support for allowing exchange reactions on any metabolite not only on external metabolites.
E.g. sometimes one has multiple external compartments to drive a model. Some metabolites are pool metabolites such as glycogen which should be handled via an internal exchange reaction.
In summary: this seems to be a design flaw; use a dummy transport to the external compartment as workaround which will give you the same results.

Best Matthias

Moritz Beber

unread,
Feb 8, 2021, 9:55:13 AM2/8/21
to cobr...@googlegroups.com
You can actually add sink reaction which can also act as a source for internal metabolites. The nomenclature is contentious but is based on

Thiele, Ines, and Bernhard Ø Palsson. “A Protocol for Generating a High-Quality Genome-Scale Metabolic Reconstruction.” Nature Protocols 5, no. 1 (January 2010): 93–121. https://doi.org/10.1038/nprot.2009.203.

Take a look at figure 7 in particular.

You can quickly do this by using https://cobrapy.readthedocs.io/en/latest/autoapi/cobra/core/model/index.html#cobra.core.model.Model.add_boundary with type="sink" and your desired cytosolic metabolite.

Best,
Moritz

Amit Kugler

unread,
Feb 8, 2021, 10:50:29 AM2/8/21
to cobra pie
Hi Matthias and Moritz, 

Aa question related to that.

Setting the metabolite/reaction the following way does not work as well?

reaction_3php_c_e  = Reaction('EX_ 3php_c')
reaction_3php_c_e.lower_bound = 0
reaction_3php_c_e.upper_bound = 1000
reaction_3php_c_e.add_metabolites({model.metabolites.get_by_id("3php_c "): -1.0})

model.add_reactions([reaction_3php_c_e ])

Thanks in advance,
Amit

Matthias König

unread,
Feb 9, 2021, 7:49:17 AM2/9/21
to cobra pie
@Moritz and Amit
I updated the documentation to document the exchange reactions.

I was also unaware of the details about exchange/sink/demand. The correct solution is using `sink` for internal metabolites.

Best Matthias
Message has been deleted

Matthias König

unread,
Feb 16, 2021, 8:55:00 AM2/16/21
to Karen Chung, cobra pie
For the external metabolite to be used in the model you require a transport reaction. The dummy reaction would be this transport reaction from the external medium to the cytosol. If this is the wanted model behavior your dummy reaction would be this transporter (just don't call it dummy) and you would add an exchange on the external metabolite. So this would look very similar to the dummy example I gave, you just name your transporter and external metabolite better.

Best Matthias

On Fri, Feb 12, 2021 at 6:45 AM Karen Chung <yanyan.k...@gmail.com> wrote:
Hi Matthias and Moritz, 

Sorry,  I should have mention my objective for better understanding. My purpose of adding the exchange reaction 3php , is to predict model growth upon addition of exogenous metabolite. Thus, 3php should be an exchange reaction. 

My project aim is to predict changes in objective growth when 3php is added as an external source of metabolite. 

Is the 'dummy transport' suit for my case?

Regards,
Karen

--
You received this message because you are subscribed to a topic in the Google Groups "cobra pie" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/cobra-pie/Vg-6qU-AsBI/unsubscribe.
To unsubscribe from this group and all its topics, send an email to cobra-pie+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/cobra-pie/5bca9dad-df49-43d1-8788-2b4d98496a06n%40googlegroups.com.


--
Matthias König, PhD.
Junior Group Leader LiSyM - Systems Medicine of the Liver
Humboldt Universität zu Berlin, Institute of Biology, Institute for Theoretical Biology
  https://livermetabolism.com
koni...@googlemail.com
https://github.com/matthiaskoenig
Tel: +49 30 2093 98435

Karen Chung

unread,
Feb 18, 2021, 6:05:49 AM2/18/21
to cobra pie
Hi Mathhias,

I have this syntax error when I tried to add the metabolite, is it the problem with the name prefix 3- ? I tried change to m_3-phosphohydroxypyruvate , but the error still occurred.

Screenshot 2021-02-18 at 7.00.11 PM.png
Regards,
Karen

Matthias König

unread,
Feb 18, 2021, 6:25:39 AM2/18/21
to cobra pie
Python variables cannot start with numbers or contain `-` characters.
You use a variable 3-... which does not work in python.

Karen Chung

unread,
Feb 18, 2021, 12:05:28 PM2/18/21
to cobra pie
Finally I'm able to add the exchange reaction after I  modified the metabolite name to 'M_3hydroxypyruvate_e'. 

R_EX_3php: 3php_e -> (exchange reaction)

R_3php_cross_om_transport: 3php_e -> 3php_p (transport via diffusion extracellular to periplasm)

R_3php_cross_im_transport: 3php_p + h_p -> 3php_c + h_c (periplasm)


But I have another problem, it seems that the added reaction is not saved in the model. 
After I added the exchange reaction, I checked model.reactions.get_by_id ('EX_3php_e'), it showed the reaction info. [Fig 1]
No. of reaction increased from 2894 to 2895. 

Then I proceed to add next transport reaction from extracellular to periplasm (R_3PHPtex). Checked model.reactions.get_by_id('R_3PHPtex_e'), it showed. [Fig 2]

But when checked again model.reactions.get_by_id (EX_3php_e), it showed KeyError. And the no. of reaction still 2895. [Fig 3]

Another problem I found is, it did not showed model.medium after I add new reaction. [Fig 4]
 before I do anything to the model, it would showed default M9 medium composition. [Fig 5]

Fig 4.png
Fig 3.png
Fig 5.png
Fig 2.png
Fig 1.png

Matthias König

unread,
Feb 19, 2021, 3:30:56 AM2/19/21
to Karen Chung, cobra pie
If you post the complete notebook with model I can have a look. But without access to the code or model this takes me too long.

About the medium: the exchange could just not be active (to be in medium requires to be exchange and active).

@property
def medium(self):
def is_active(reaction):
"""Determine if a boundary reaction permits flux towards creating
metabolites
"""

return (bool(reaction.products) and (reaction.upper_bound > 0)) or (
bool(reaction.reactants) and (reaction.lower_bound < 0)
)

def get_active_bound(reaction):
"""For an active boundary reaction, return the relevant bound"""
if reaction.reactants:
return -reaction.lower_bound
elif reaction.products:
return reaction.upper_bound

return {
rxn.id: get_active_bound(rxn) for rxn in self.exchanges if is_active(rxn)
}
So you should check your bounds on the exchange. Probably they appear if you have [-1000, 1000] instead of [0, 1000] because they become active.

Best Matthias

Karen Chung

unread,
Feb 19, 2021, 6:02:47 AM2/19/21
to cobra pie
Hi Matthias,

I keep having error while posting the .ipynb file, kindly let me know what file I could send.

Screenshot 2021-02-19 at 7.00.51 PM.png




dtm.van...@gmail.com

unread,
Feb 19, 2021, 6:56:09 AM2/19/21
to cobra pie
Hi Karen,

Did you try to put the model and the .ipynb file in a zip archive and then post them? Otherwise just download your workbook as a Python (.py) file and post that with your model.

Good luck,

Dennis

Karen Chung

unread,
Feb 19, 2021, 9:19:48 AM2/19/21
to cobra pie
Thanks, it helps.

Here it is!

model.zip

Karen Chung

unread,
Feb 19, 2021, 10:08:35 AM2/19/21
to cobra pie
Sorry, wrong send. This is the correct one.

Notebook named 'BAA2146'.

Model named 'model'.

In the notebook, it started somewhere at the bottom, In [1] - In [65].

Thank you.



model.zip

dtm.van...@gmail.com

unread,
Feb 19, 2021, 11:18:04 AM2/19/21
to cobra pie
Hi Karen,

I edited your notebook a bit to make it more legible and put all the 3php-changes in one run. I have no idea why the add_boundary function makes all your previous exchange reactions into normal reactions.

I hope Matthias or Moritz can figure out what is going wrong, I used similar code (with a different compound, which did have it's formula defined) in my models and that works.

Kind regards,

Dennis
model Karen Chung.zip

Karen Chung

unread,
Feb 22, 2021, 10:25:08 AM2/22/21
to cobra pie
Hi Dennis,

Thanks for the help in organising my notebook! 

I used similar code (with a different compound, which did have it's formula defined) in my models and that works.

May I ask what did you mean by 'it's formula defined' ?

dtm.van...@gmail.com

unread,
Feb 22, 2021, 10:39:57 AM2/22/21
to cobra pie
Hey Karen,

I noticed that your metabolite does not have a formula, like H2O for water or CH4O for methanol and so on. Normally when you add a metabolite you also put it's chemical formula in the model so you can, for instance, check if the mass balance of your reactions is ok. This way you can see if there is no unrealistic growth because of some mistakes in it's reactions.
The examples in the documentation of cobrapy also add their chemical formula's, for instance:

ACP_c = Metabolite( 'ACP_c', formula='C11H21N2O7PRS', name='acyl-carrier-protein', compartment='c')

Maybe that explains the strange behaviour when you add your exchange reaction?

Kind regards,

Dennis

Matthias König

unread,
Feb 22, 2021, 1:23:21 PM2/22/21
to dtm.van...@gmail.com, cobra pie
This looks like a bug in cobrapy. I tried to figure out what is going on, but it looks like the adding of metabolites removes the existing exchange reactions.
I tried to find some cause for the strange behavior, but nothing obvious came up.
I opened the following issue for the problem:

--
You received this message because you are subscribed to a topic in the Google Groups "cobra pie" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/cobra-pie/Vg-6qU-AsBI/unsubscribe.
To unsubscribe from this group and all its topics, send an email to cobra-pie+...@googlegroups.com.

Karen Chung

unread,
Feb 25, 2021, 4:55:39 AM2/25/21
to cobra pie
Hi Dennis,

Thanks for the suggestion, I've added metabolite with formula defined in my model.

Hi Matthias,

Thanks for the help! It is finally working after corrected the compartment name.

Regards,
Karen



Reply all
Reply to author
Forward
0 new messages