PyCoMo Basics
PyCoMo is a Python Community metabolic Modelling package. In this tutorial, the core features will be presented.
The expected runtime for this notebook is approximately 10-30 minutes.
Setting up PyCoMo
Clone the package from github. Next, we are going to import all the packages we need in this tutorial.
[1]:
from pathlib import Path
import sys
import cobra
import os
Importing PyCoMo
As PyCoMo is currently only available as a local package, the direct path to the package directory needs to be used on import.
[2]:
path_root = "../src" # Change path according to your PyCoMo location
sys.path.append(str(path_root))
import pycomo
pycomo.configure_logger(level="info")
2025-02-11 16:28:11,142 - pycomo - INFO - Logger initialized.
2025-02-11 16:28:11,144 - pycomo - INFO - Process Pool Logger initialized.
2025-02-11 16:28:11,145 - pycomo - INFO - Utils Logger initialized.
2025-02-11 16:28:11,146 - pycomo - INFO - Multiprocess Logger initialized.
2025-02-11 16:28:11,148 - pycomo - INFO - Log level set to info
Creating a Community Model
The creation of a community model consists of 3 steps:
Loading the member models
Preparing the member models for merging
Creating a community model
Loading the member models
The community model creation process starts with models of the individual members. Note that the quality of the community model heavily depends on the quality of the member models!
In this tutorial we are using metabolic models from the AGORA collection. The models were retrieved from www.vmh.life, and are stored in the data folder of the repository. The selection of models and the resulting community represents a cystic fibrosis airway community, as done by Henson et al. (www.doi.org/10.1128/mSystems.00026-19)
[3]:
test_model_dir = "../data/use_case/henson"
named_models = pycomo.load_named_models_from_dir(test_model_dir)
The models and file names were extracted and stored in named_models. Let’s check the contents:
[4]:
named_models
[4]:
{'Fusobacterium_nucleatum_subsp_nucleatum_ATCC_25586': <Model Fusobacterium_nucleatum_subsp_nucleatum_ATCC_25586 at 0x7f00ac840dd0>,
'Actinomyces_naeslundii_str_Howell_279': <Model Actinomyces_naeslundii_str_Howell_279 at 0x7f004b2c43d0>,
'Burkholderia_cepacia_GG4': <Model Burkholderia_cepacia_GG4 at 0x7f004a9dc210>,
'Veillonella_atypica_ACS_049_V_Sch6': <Model Veillonella_atypica_ACS_049_V_Sch6 at 0x7f0049b44bd0>,
'Neisseria_flavescens_SK114': <Model Neisseria_flavescens_SK114 at 0x7f0049168190>,
'Staphylococcus_aureus_subsp_aureus_USA300_FPR3757': <Model Staphylococcus_aureus_subsp_aureus_USA300_FPR3757 at 0x7f0048940050>,
'Pseudomonas_aeruginosa_NCGM2_S1': <Model Pseudomonas_aeruginosa_NCGM2_S1 at 0x7f0047f74610>,
'Achromobacter_xylosoxidans_NBRC_15126': <Model Achromobacter_xylosoxidans_NBRC_15126 at 0x7f00473e6810>,
'Streptococcus_sanguinis_SK36': <Model Streptococcus_sanguinis_SK36 at 0x7f004647c310>,
'Haemophilus_influenzae_R2846': <Model Haemophilus_influenzae_R2846 at 0x7f0045a1c110>,
'Escherichia_coli_str_K_12_substr_MG1655': <Model Escherichia_coli_str_K_12_substr_MG1655 at 0x7f00452b04d0>,
'Porphyromonas_endodontalis_ATCC_35406': <Model Porphyromonas_endodontalis_ATCC_35406 at 0x7f004465c150>,
'Prevotella_melaninogenica_ATCC_25845': <Model Prevotella_melaninogenica_ATCC_25845 at 0x7f0044bbc410>,
'Ralstonia_sp_5_7_47FAA': <Model Ralstonia_sp_5_7_47FAA at 0x7f00433d4090>,
'Granulicatella_adiacens_ATCC_49175': <Model Granulicatella_adiacens_ATCC_49175 at 0x7f00428b0090>,
'Gemella_haemolysans_ATCC_10379': <Model Gemella_haemolysans_ATCC_10379 at 0x7f0041f340d0>,
'Rothia_mucilaginosa_DY_18': <Model Rothia_mucilaginosa_DY_18 at 0x7f00419dc210>}
Preparing the models for merging
With the models loaded, the next step is preparing them for merging. This is done by creating SingleOrganismModel objects. Using them, the models will be formatted for compliance with the SBML format. Further, an exchange compartment will be generated under the name medium.
One of the requirements for a community metabolic model is a common biomass function. To construct it, PyCoMo requires the biomass of each member represented as a single metabolite. This biomass metabolite ID can be specified when constructing the SingleOrganismModel objects. However, it can also be found or generated automatically, by setting the biomass reaction as the objective of the model. Let’s check if the biomass function is the objective in all the models
[5]:
for model in named_models.values():
print(model.objective)
Maximize
1.0*biomass237 - 1.0*biomass237_reverse_f032e
Maximize
1.0*biomass492 - 1.0*biomass492_reverse_bc961
Maximize
1.0*biomass479 - 1.0*biomass479_reverse_1d1b2
Maximize
1.0*biomass116 - 1.0*biomass116_reverse_02324
Maximize
1.0*biomass339 - 1.0*biomass339_reverse_45ed6
Maximize
1.0*biomass042 - 1.0*biomass042_reverse_2a02b
Maximize
1.0*biomass345 - 1.0*biomass345_reverse_e128f
Maximize
1.0*biomass489 - 1.0*biomass489_reverse_62d1a
Maximize
1.0*biomass164 - 1.0*biomass164_reverse_ca493
Maximize
1.0*biomass252 - 1.0*biomass252_reverse_f6948
Maximize
1.0*biomass525 - 1.0*biomass525_reverse_5c178
Maximize
1.0*biomass326 - 1.0*biomass326_reverse_02060
Maximize
1.0*biomass276 - 1.0*biomass276_reverse_7f92e
Maximize
1.0*biomass525 - 1.0*biomass525_reverse_5c178
Maximize
1.0*biomass091 - 1.0*biomass091_reverse_7b6db
Maximize
1.0*biomass027 - 1.0*biomass027_reverse_af8dc
Maximize
1.0*biomass429 - 1.0*biomass429_reverse_9caa0
With the objective being the biomass function in all models, the biomass metabolite does not need to be specified.
[6]:
single_org_models = []
for name, model in named_models.items():
print(name)
single_org_model = pycomo.SingleOrganismModel(model, name)
single_org_models.append(single_org_model)
Fusobacterium_nucleatum_subsp_nucleatum_ATCC_25586
Actinomyces_naeslundii_str_Howell_279
Burkholderia_cepacia_GG4
Veillonella_atypica_ACS_049_V_Sch6
Neisseria_flavescens_SK114
Staphylococcus_aureus_subsp_aureus_USA300_FPR3757
Pseudomonas_aeruginosa_NCGM2_S1
Achromobacter_xylosoxidans_NBRC_15126
Streptococcus_sanguinis_SK36
Haemophilus_influenzae_R2846
Escherichia_coli_str_K_12_substr_MG1655
Porphyromonas_endodontalis_ATCC_35406
Prevotella_melaninogenica_ATCC_25845
Ralstonia_sp_5_7_47FAA
Granulicatella_adiacens_ATCC_49175
Gemella_haemolysans_ATCC_10379
Rothia_mucilaginosa_DY_18
Creating a community model
With the member models prepared, the community model can be generated. The first step is to create a CommunityModel objects from the member models. The matching of the exchange metabolites can be achieved in two ways: matching via identical metabolite IDs, or via annotation fields. In this tutorial and as all the models come from the same source, matching via identical metabolite IDs will be used.
[7]:
community_name = "henson_community_model"
com_model_obj = pycomo.CommunityModel(single_org_models, community_name)
The cobra model of the community will generated the first time it is needed. We can enforce this now, by calling it via .model
[8]:
com_model_obj.model
2025-02-11 16:28:32,249 - pycomo - INFO - No community model generated yet. Generating now:
2025-02-11 16:28:32,428 - pycomo - INFO - Identified biomass reaction from objective: biomass237
2025-02-11 16:28:32,428 - pycomo - INFO - Note: no products in the objective function, adding biomass to it.
2025-02-11 16:28:37,567 - pycomo - INFO - Identified biomass reaction from objective: biomass492
2025-02-11 16:28:37,567 - pycomo - INFO - Note: no products in the objective function, adding biomass to it.
2025-02-11 16:28:44,909 - pycomo - INFO - Identified biomass reaction from objective: biomass479
2025-02-11 16:28:44,909 - pycomo - INFO - Note: no products in the objective function, adding biomass to it.
2025-02-11 16:28:59,680 - pycomo - INFO - Identified biomass reaction from objective: biomass116
2025-02-11 16:28:59,681 - pycomo - INFO - Note: no products in the objective function, adding biomass to it.
2025-02-11 16:29:06,508 - pycomo - INFO - Identified biomass reaction from objective: biomass339
2025-02-11 16:29:06,509 - pycomo - INFO - Note: no products in the objective function, adding biomass to it.
2025-02-11 16:29:13,745 - pycomo - INFO - Identified biomass reaction from objective: biomass042
2025-02-11 16:29:13,746 - pycomo - INFO - Note: no products in the objective function, adding biomass to it.
2025-02-11 16:29:24,477 - pycomo - INFO - Identified biomass reaction from objective: biomass345
2025-02-11 16:29:24,478 - pycomo - INFO - Note: no products in the objective function, adding biomass to it.
2025-02-11 16:29:37,701 - pycomo - INFO - Identified biomass reaction from objective: biomass489
2025-02-11 16:29:37,702 - pycomo - INFO - Note: no products in the objective function, adding biomass to it.
2025-02-11 16:29:52,668 - pycomo - INFO - Identified biomass reaction from objective: biomass164
2025-02-11 16:29:52,668 - pycomo - INFO - Note: no products in the objective function, adding biomass to it.
2025-02-11 16:30:01,601 - pycomo - INFO - Identified biomass reaction from objective: biomass252
2025-02-11 16:30:01,601 - pycomo - INFO - Note: no products in the objective function, adding biomass to it.
2025-02-11 16:30:11,188 - pycomo - INFO - Identified biomass reaction from objective: biomass525
2025-02-11 16:30:11,189 - pycomo - INFO - Note: no products in the objective function, adding biomass to it.
2025-02-11 16:30:27,457 - pycomo - INFO - Identified biomass reaction from objective: biomass326
2025-02-11 16:30:27,458 - pycomo - INFO - Note: no products in the objective function, adding biomass to it.
2025-02-11 16:30:32,670 - pycomo - INFO - Identified biomass reaction from objective: biomass276
2025-02-11 16:30:32,670 - pycomo - INFO - Note: no products in the objective function, adding biomass to it.
2025-02-11 16:30:39,208 - pycomo - INFO - Identified biomass reaction from objective: biomass525
2025-02-11 16:30:39,209 - pycomo - INFO - Note: no products in the objective function, adding biomass to it.
2025-02-11 16:30:49,904 - pycomo - INFO - Identified biomass reaction from objective: biomass091
2025-02-11 16:30:49,904 - pycomo - INFO - Note: no products in the objective function, adding biomass to it.
2025-02-11 16:30:55,715 - pycomo - INFO - Identified biomass reaction from objective: biomass027
2025-02-11 16:30:55,715 - pycomo - INFO - Note: no products in the objective function, adding biomass to it.
2025-02-11 16:31:01,518 - pycomo - INFO - Identified biomass reaction from objective: biomass429
2025-02-11 16:31:01,519 - pycomo - INFO - Note: no products in the objective function, adding biomass to it.
2025-02-11 16:31:08,936 - pycomo - WARNING - No annotation overlap found for matching several metabolites (552). Please make sure that the matched metabolites are indeed representing the same substance in all models! The list of metaboliteswithout annotation overlap can be accessed via 'model.no_annotation_overlap'
2025-02-11 16:31:26,576 - pycomo - WARNING - Not all reactions in the model are mass and charge balanced. To check which reactions are imbalanced, please run the get_unbalanced_reactions method of this CommunityModel object
2025-02-11 16:31:26,576 - pycomo - INFO - Generated community model.
[8]:
Name | henson_community_model |
Memory address | 7f003738de50 |
Number of metabolites | 51664 |
Number of reactions | 55176 |
Number of genes | 13885 |
Number of groups | 68 |
Objective expression | 1.0*community_biomass - 1.0*community_biomass_reverse_44dc1 |
Compartments | Fusobacterium_nucleatum_subsp_nucleatum_ATCC_25586_c, Fusobacterium_nucleatum_subsp_nucleatum_ATCC_25586_e, Fusobacterium_nucleatum_subsp_nucleatum_ATCC_25586_medium, medium, fraction_reaction, Actinomyces_naeslundii_str_Howell_279_c, Actinomyces_naeslundii_str_Howell_279_e, Actinomyces_naeslundii_str_Howell_279_medium, Burkholderia_cepacia_GG4_e, Burkholderia_cepacia_GG4_c, Burkholderia_cepacia_GG4_medium, Veillonella_atypica_ACS_049_V_Sch6_c, Veillonella_atypica_ACS_049_V_Sch6_e, Veillonella_atypica_ACS_049_V_Sch6_medium, Neisseria_flavescens_SK114_c, Neisseria_flavescens_SK114_e, Neisseria_flavescens_SK114_medium, Staphylococcus_aureus_subsp_aureus_USA300_FPR3757_e, Staphylococcus_aureus_subsp_aureus_USA300_FPR3757_c, Staphylococcus_aureus_subsp_aureus_USA300_FPR3757_medium, Pseudomonas_aeruginosa_NCGM2_S1_c, Pseudomonas_aeruginosa_NCGM2_S1_e, Pseudomonas_aeruginosa_NCGM2_S1_medium, Achromobacter_xylosoxidans_NBRC_15126_c, Achromobacter_xylosoxidans_NBRC_15126_e, Achromobacter_xylosoxidans_NBRC_15126_medium, Streptococcus_sanguinis_SK36_e, Streptococcus_sanguinis_SK36_c, Streptococcus_sanguinis_SK36_medium, Haemophilus_influenzae_R2846_c, Haemophilus_influenzae_R2846_e, Haemophilus_influenzae_R2846_medium, Escherichia_coli_str_K_12_substr_MG1655_e, Escherichia_coli_str_K_12_substr_MG1655_c, Escherichia_coli_str_K_12_substr_MG1655_medium, Porphyromonas_endodontalis_ATCC_35406_c, Porphyromonas_endodontalis_ATCC_35406_e, Porphyromonas_endodontalis_ATCC_35406_medium, Prevotella_melaninogenica_ATCC_25845_c, Prevotella_melaninogenica_ATCC_25845_e, Prevotella_melaninogenica_ATCC_25845_medium, Ralstonia_sp_5_7_47FAA_c, Ralstonia_sp_5_7_47FAA_e, Ralstonia_sp_5_7_47FAA_medium, Granulicatella_adiacens_ATCC_49175_e, Granulicatella_adiacens_ATCC_49175_c, Granulicatella_adiacens_ATCC_49175_medium, Gemella_haemolysans_ATCC_10379_c, Gemella_haemolysans_ATCC_10379_e, Gemella_haemolysans_ATCC_10379_medium, Rothia_mucilaginosa_DY_18_c, Rothia_mucilaginosa_DY_18_e, Rothia_mucilaginosa_DY_18_medium |
The output of the community model creation contains quite some lines of info and warnings. This is to be expected. Let’s have a look at the different types of info:
Ignoring reaction ‘EX_4abz_medium’ since it already exists. This line will come up if a reaction is present in two different community member models under the same ID. This will only happen for exchange reactions in the exchange compartment and are therefor correct behaviour.
WARNING: no annotation overlap found for matching metabolite mn2. Please make sure that the metabolite with this ID is indeed representing the same substance in all models! This warning comes up if exchange metabolites do not contain any matching annotation field. This can be an indicator that metabolites with the same ID are merged, but they represent different chemicals. Another common cause is that no annotation was given for this metabolite in one of the models.
WARNING: matching of the metabolite CO2_EX is unbalanced (mass and/or charge). Please manually curate this metabolite for a mass and charge balanced model! This warning means that the formula of an exchange metabolite was different between member models. This can be due to the formula being omitted in some of the models. The other reason is that the metabolites differ in their mass or charge. As this would lead to generation or loss of matter from nothing, these issues need to be resolved for a consistent metabolic model.
Summary and report
The community model object has two utility methods to display information on the model.
Summary behaves the same as the summary method of COBRApy, displaying the the solution of FBA and its exchange metabolites. In the CommunityModel summary, the exchange reactions of metabolites responsible for scaling the flux bounds to the community composition are hidden.
The report function displays information on the model structure: the number of metabolites, reactions, genes, etc., but also quality control measures on mass and charge balance and internal loops.
[9]:
com_model_obj.summary()
[9]:
Objective
1.0 community_biomass = 1.0
Uptake
Metabolite | Reaction | Flux | C-Number | C-Flux |
---|---|---|---|---|
_26dap_M_medium | EX__26dap_M_medium | 0.02501 | 7 | 0.06% |
_2dmmq8_medium | EX__2dmmq8_medium | 0.003097 | 50 | 0.05% |
adn_medium | EX_adn_medium | 3.582 | 10 | 12.59% |
ala_L_medium | EX_ala_L_medium | 0.503 | 3 | 0.53% |
amp_medium | EX_amp_medium | 0.8121 | 10 | 2.86% |
arg_L_medium | EX_arg_L_medium | 8.031 | 6 | 16.94% |
asn_L_medium | EX_asn_L_medium | 0.2008 | 4 | 0.28% |
asp_L_medium | EX_asp_L_medium | 0.2008 | 4 | 0.28% |
ca2_medium | EX_ca2_medium | 0.003097 | 0 | 0.00% |
cgly_medium | EX_cgly_medium | 0.003097 | 5 | 0.01% |
cl_medium | EX_cl_medium | 0.003097 | 0 | 0.00% |
cobalt2_medium | EX_cobalt2_medium | 0.003096 | 0 | 0.00% |
cu2_medium | EX_cu2_medium | 0.003097 | 0 | 0.00% |
cys_L_medium | EX_cys_L_medium | 0.08234 | 3 | 0.09% |
cytd_medium | EX_cytd_medium | 0.09933 | 9 | 0.31% |
dad_2_medium | EX_dad_2_medium | 7.679 | 10 | 27.00% |
dgsn_medium | EX_dgsn_medium | 0.1599 | 10 | 0.56% |
fe2_medium | EX_fe2_medium | 0.003096 | 0 | 0.00% |
fe3_medium | EX_fe3_medium | 0.003097 | 0 | 0.00% |
gln_L_medium | EX_gln_L_medium | 0.2074 | 5 | 0.36% |
glyleu_medium | EX_glyleu_medium | 0.4606 | 8 | 1.30% |
h_medium | EX_h_medium | 1.543 | 0 | 0.00% |
his_L_medium | EX_his_L_medium | 0.3013 | 6 | 0.64% |
ile_L_medium | EX_ile_L_medium | 0.327 | 6 | 0.69% |
k_medium | EX_k_medium | 0.003097 | 0 | 0.00% |
lys_L_medium | EX_lys_L_medium | 0.2854 | 6 | 0.60% |
met_L_medium | EX_met_L_medium | 0.134 | 5 | 0.24% |
mg2_medium | EX_mg2_medium | 0.003096 | 0 | 0.00% |
mn2_medium | EX_mn2_medium | 0.003096 | 0 | 0.00% |
mqn8_medium | EX_mqn8_medium | 0.003097 | 51 | 0.06% |
nac_medium | EX_nac_medium | 0.006193 | 6 | 0.01% |
o2_medium | EX_o2_medium | 0.003097 | 0 | 0.00% |
phe_L_medium | EX_phe_L_medium | 0.1545 | 9 | 0.49% |
pheme_medium | EX_pheme_medium | 0.003097 | 34 | 0.04% |
pnto_R_medium | EX_pnto_R_medium | 0.006193 | 9 | 0.02% |
pro_L_medium | EX_pro_L_medium | 0.1844 | 5 | 0.32% |
ptrc_medium | EX_ptrc_medium | 0.003097 | 4 | 0.00% |
q8_medium | EX_q8_medium | 0.003097 | 49 | 0.05% |
ribflv_medium | EX_ribflv_medium | 0.006193 | 17 | 0.04% |
sheme_medium | EX_sheme_medium | 0.003097 | 42 | 0.05% |
so4_medium | EX_so4_medium | 0.003096 | 0 | 0.00% |
spmd_medium | EX_spmd_medium | 0.003096 | 7 | 0.01% |
succ_medium | EX_succ_medium | 0.0462 | 4 | 0.06% |
thm_medium | EX_thm_medium | 0.003097 | 12 | 0.01% |
thr_L_medium | EX_thr_L_medium | 0.4718 | 4 | 0.66% |
trp_L_medium | EX_trp_L_medium | 0.0472 | 11 | 0.18% |
ttdca_medium | EX_ttdca_medium | 0.1501 | 14 | 0.74% |
tyr_L_medium | EX_tyr_L_medium | 0.1207 | 9 | 0.38% |
uri_medium | EX_uri_medium | 9.752 | 9 | 30.86% |
val_L_medium | EX_val_L_medium | 0.3522 | 5 | 0.62% |
zn2_medium | EX_zn2_medium | 0.003096 | 0 | 0.00% |
Secretion
Metabolite | Reaction | Flux | C-Number | C-Flux |
---|---|---|---|---|
acald_medium | EX_acald_medium | -8.505 | 2 | 6.94% |
ade_medium | EX_ade_medium | -11.93 | 5 | 24.33% |
but_medium | EX_but_medium | -5.478 | 4 | 8.94% |
co2_medium | EX_co2_medium | -20.76 | 1 | 8.47% |
dcyt_medium | EX_dcyt_medium | -9.644 | 9 | 35.42% |
gcald_medium | EX_gcald_medium | -0.00929 | 2 | 0.01% |
nh4_medium | EX_nh4_medium | -6.363 | 0 | 0.00% |
orn_medium | EX_orn_medium | -7.785 | 5 | 15.88% |
cpd11416_medium | community_biomass | -1 | 0 | 0.00% |
[10]:
com_model_obj.report();
2025-02-11 16:32:21,033 - pycomo - INFO - Note: The model has more than 5000 reactions. Calculation of loops is skipped, as this would take some time. If needed, please run manually via .get_loops()
Name: henson_community_model
------------------
Model overview
Model structure: fixed growth rate
# Metabolites: 51664
# Constraint (f-) Metabolites: 31974
# Model Metabolites: 19690
# Reactions: 55176
# Constraint (f-) Reactions: 31973
# Model Reactions: 23203
# Genes: 13885
# Members: 17
Members:
Fusobacterium_nucleatum_subsp_nucleatum_ATCC_25586
Actinomyces_naeslundii_str_Howell_279
Burkholderia_cepacia_GG4
Veillonella_atypica_ACS_049_V_Sch6
Neisseria_flavescens_SK114
Staphylococcus_aureus_subsp_aureus_USA300_FPR3757
Pseudomonas_aeruginosa_NCGM2_S1
Achromobacter_xylosoxidans_NBRC_15126
Streptococcus_sanguinis_SK36
Haemophilus_influenzae_R2846
Escherichia_coli_str_K_12_substr_MG1655
Porphyromonas_endodontalis_ATCC_35406
Prevotella_melaninogenica_ATCC_25845
Ralstonia_sp_5_7_47FAA
Granulicatella_adiacens_ATCC_49175
Gemella_haemolysans_ATCC_10379
Rothia_mucilaginosa_DY_18
Objective in direction max:
1.0*community_biomass - 1.0*community_biomass_reverse_44dc1
------------------
Model quality
# Reactions unbalanced: 235
# Reactions able to carry flux without a medium: NaN
Setting the growth rate
By default the community model object will have the structure of fixe growth rate. This means, the fractions of the community member abundance is allowed to vary during simulations, but the individual and community growth rate is set to a fixed value (default: 1.0). The next thing we will try is to set the community growth rate to a different value and do a FBA.
[11]:
com_model_obj.apply_fixed_growth_rate(0.5)
com_model_obj.summary()
[11]:
Objective
1.0 community_biomass = 0.5
Uptake
Metabolite | Reaction | Flux | C-Number | C-Flux |
---|---|---|---|---|
_26dap_M_medium | EX__26dap_M_medium | 0.01251 | 7 | 0.06% |
_2dmmq8_medium | EX__2dmmq8_medium | 0.001548 | 50 | 0.05% |
adn_medium | EX_adn_medium | 1.791 | 10 | 12.59% |
ala_L_medium | EX_ala_L_medium | 0.2515 | 3 | 0.53% |
amp_medium | EX_amp_medium | 0.406 | 10 | 2.86% |
arg_L_medium | EX_arg_L_medium | 4.016 | 6 | 16.94% |
asn_L_medium | EX_asn_L_medium | 0.1004 | 4 | 0.28% |
asp_L_medium | EX_asp_L_medium | 0.1004 | 4 | 0.28% |
ca2_medium | EX_ca2_medium | 0.001548 | 0 | 0.00% |
cgly_medium | EX_cgly_medium | 0.001548 | 5 | 0.01% |
cl_medium | EX_cl_medium | 0.001548 | 0 | 0.00% |
cobalt2_medium | EX_cobalt2_medium | 0.001548 | 0 | 0.00% |
cu2_medium | EX_cu2_medium | 0.001548 | 0 | 0.00% |
cys_L_medium | EX_cys_L_medium | 0.04117 | 3 | 0.09% |
cytd_medium | EX_cytd_medium | 0.04967 | 9 | 0.31% |
dad_2_medium | EX_dad_2_medium | 3.839 | 10 | 27.00% |
dgsn_medium | EX_dgsn_medium | 0.07996 | 10 | 0.56% |
fe2_medium | EX_fe2_medium | 0.001548 | 0 | 0.00% |
fe3_medium | EX_fe3_medium | 0.001548 | 0 | 0.00% |
gln_L_medium | EX_gln_L_medium | 0.1037 | 5 | 0.36% |
glyleu_medium | EX_glyleu_medium | 0.2303 | 8 | 1.30% |
h_medium | EX_h_medium | 0.7715 | 0 | 0.00% |
his_L_medium | EX_his_L_medium | 0.1506 | 6 | 0.64% |
ile_L_medium | EX_ile_L_medium | 0.1635 | 6 | 0.69% |
k_medium | EX_k_medium | 0.001548 | 0 | 0.00% |
lys_L_medium | EX_lys_L_medium | 0.1427 | 6 | 0.60% |
met_L_medium | EX_met_L_medium | 0.067 | 5 | 0.24% |
mg2_medium | EX_mg2_medium | 0.001548 | 0 | 0.00% |
mn2_medium | EX_mn2_medium | 0.001548 | 0 | 0.00% |
mqn8_medium | EX_mqn8_medium | 0.001548 | 51 | 0.06% |
nac_medium | EX_nac_medium | 0.003096 | 6 | 0.01% |
o2_medium | EX_o2_medium | 0.001548 | 0 | 0.00% |
phe_L_medium | EX_phe_L_medium | 0.07726 | 9 | 0.49% |
pheme_medium | EX_pheme_medium | 0.001548 | 34 | 0.04% |
pnto_R_medium | EX_pnto_R_medium | 0.003096 | 9 | 0.02% |
pro_L_medium | EX_pro_L_medium | 0.09218 | 5 | 0.32% |
ptrc_medium | EX_ptrc_medium | 0.001548 | 4 | 0.00% |
q8_medium | EX_q8_medium | 0.001548 | 49 | 0.05% |
ribflv_medium | EX_ribflv_medium | 0.003097 | 17 | 0.04% |
sheme_medium | EX_sheme_medium | 0.001548 | 42 | 0.05% |
so4_medium | EX_so4_medium | 0.001548 | 0 | 0.00% |
spmd_medium | EX_spmd_medium | 0.001548 | 7 | 0.01% |
succ_medium | EX_succ_medium | 0.0231 | 4 | 0.06% |
thm_medium | EX_thm_medium | 0.001548 | 12 | 0.01% |
thr_L_medium | EX_thr_L_medium | 0.2359 | 4 | 0.66% |
trp_L_medium | EX_trp_L_medium | 0.0236 | 11 | 0.18% |
ttdca_medium | EX_ttdca_medium | 0.07503 | 14 | 0.74% |
tyr_L_medium | EX_tyr_L_medium | 0.06034 | 9 | 0.38% |
uri_medium | EX_uri_medium | 4.876 | 9 | 30.86% |
val_L_medium | EX_val_L_medium | 0.1761 | 5 | 0.62% |
zn2_medium | EX_zn2_medium | 0.001548 | 0 | 0.00% |
Secretion
Metabolite | Reaction | Flux | C-Number | C-Flux |
---|---|---|---|---|
acald_medium | EX_acald_medium | -4.252 | 2 | 6.94% |
ade_medium | EX_ade_medium | -5.963 | 5 | 24.33% |
but_medium | EX_but_medium | -2.739 | 4 | 8.94% |
co2_medium | EX_co2_medium | -10.38 | 1 | 8.47% |
dcyt_medium | EX_dcyt_medium | -4.822 | 9 | 35.42% |
gcald_medium | EX_gcald_medium | -0.004645 | 2 | 0.01% |
nh4_medium | EX_nh4_medium | -3.182 | 0 | 0.00% |
orn_medium | EX_orn_medium | -3.892 | 5 | 15.88% |
cpd11416_medium | community_biomass | -0.5 | 0 | 0.00% |
Setting the community member composition
The model structure can be changed to fixed abundance, but variable growth rate. To do so, a conversion function needs to be called. Here we then change the community abundance to equal abundances.
[12]:
com_model_obj.convert_to_fixed_abundance()
abundance_dict = com_model_obj.generate_equal_abundance_dict()
com_model_obj.apply_fixed_abundance(abundance_dict)
com_model_obj.summary()
[12]:
Objective
1.0 community_biomass = 43.84820241414374
Uptake
Metabolite | Reaction | Flux | C-Number | C-Flux |
---|---|---|---|---|
_12dgr180_medium | EX__12dgr180_medium | 0.3429 | 39 | 0.19% |
_26dap_M_medium | EX__26dap_M_medium | 0.4749 | 7 | 0.05% |
_2dmmq8_medium | EX__2dmmq8_medium | 0.1014 | 50 | 0.07% |
_2obut_medium | EX__2obut_medium | 106.7 | 4 | 6.13% |
_3mop_medium | EX__3mop_medium | 18.17 | 6 | 1.57% |
_4abz_medium | EX__4abz_medium | 0.0854 | 7 | 0.01% |
_4hbz_medium | EX__4hbz_medium | 0.05693 | 7 | 0.01% |
_5mta_medium | EX__5mta_medium | 0.3696 | 11 | 0.06% |
acgam_medium | EX_acgam_medium | 36.1 | 8 | 4.15% |
acnam_medium | EX_acnam_medium | 1.502 | 11 | 0.24% |
actn_R_medium | EX_actn_R_medium | 52.66 | 4 | 3.02% |
adn_medium | EX_adn_medium | 10.79 | 10 | 1.55% |
alagln_medium | EX_alagln_medium | 48.97 | 8 | 5.63% |
alahis_medium | EX_alahis_medium | 13.11 | 9 | 1.69% |
alathr_medium | EX_alathr_medium | 6.241 | 7 | 0.63% |
amp_medium | EX_amp_medium | 6.277 | 10 | 0.90% |
arab_D_medium | EX_arab_D_medium | 0.1935 | 5 | 0.01% |
arg_L_medium | EX_arg_L_medium | 46.94 | 6 | 4.04% |
asn_L_medium | EX_asn_L_medium | 6.255 | 4 | 0.36% |
ca2_medium | EX_ca2_medium | 0.2225 | 0 | 0.00% |
cgly_medium | EX_cgly_medium | 0.5141 | 5 | 0.04% |
chtbs_medium | EX_chtbs_medium | 7.657 | 16 | 1.76% |
cit_medium | EX_cit_medium | 17.49 | 6 | 1.51% |
cl_medium | EX_cl_medium | 0.2225 | 0 | 0.00% |
cobalt2_medium | EX_cobalt2_medium | 0.2225 | 0 | 0.00% |
cu2_medium | EX_cu2_medium | 0.2225 | 0 | 0.00% |
cys_L_medium | EX_cys_L_medium | 2.619 | 3 | 0.11% |
cytd_medium | EX_cytd_medium | 2.429 | 9 | 0.31% |
dad_2_medium | EX_dad_2_medium | 48.65 | 10 | 6.99% |
ddca_medium | EX_ddca_medium | 0.6451 | 12 | 0.11% |
dgsn_medium | EX_dgsn_medium | 14.45 | 10 | 2.08% |
duri_medium | EX_duri_medium | 0.02266 | 9 | 0.00% |
fe2_medium | EX_fe2_medium | 0.1406 | 0 | 0.00% |
fe3_medium | EX_fe3_medium | 0.3489 | 0 | 0.00% |
fol_medium | EX_fol_medium | 0.3895 | 19 | 0.11% |
fru_medium | EX_fru_medium | 56.58 | 6 | 4.87% |
fum_medium | EX_fum_medium | 15.89 | 4 | 0.91% |
gam_medium | EX_gam_medium | 6.405 | 6 | 0.55% |
gcald_medium | EX_gcald_medium | 0.05684 | 2 | 0.00% |
glc_D_medium | EX_glc_D_medium | 2.409 | 6 | 0.21% |
gln_L_medium | EX_gln_L_medium | 52.68 | 5 | 3.78% |
glyasn_medium | EX_glyasn_medium | 55.54 | 6 | 4.78% |
glyc3p_medium | EX_glyc3p_medium | 88.1 | 3 | 3.79% |
glycys_medium | EX_glycys_medium | 0.5636 | 5 | 0.04% |
glyleu_medium | EX_glyleu_medium | 76 | 8 | 8.73% |
glymet_medium | EX_glymet_medium | 0.7749 | 7 | 0.08% |
glyphe_medium | EX_glyphe_medium | 1.818 | 11 | 0.29% |
glypro_medium | EX_glypro_medium | 11.66 | 7 | 1.17% |
glytyr_medium | EX_glytyr_medium | 1.146 | 11 | 0.18% |
gsn_medium | EX_gsn_medium | 0.3892 | 10 | 0.06% |
gthox_medium | EX_gthox_medium | 0.003993 | 20 | 0.00% |
gthrd_medium | EX_gthrd_medium | 0.03195 | 10 | 0.00% |
his_L_medium | EX_his_L_medium | 2.319 | 6 | 0.20% |
hxan_medium | EX_hxan_medium | 2.697 | 5 | 0.19% |
inulin_medium | EX_inulin_medium | 0.6138 | 180 | 1.59% |
k_medium | EX_k_medium | 0.2225 | 0 | 0.00% |
lys_L_medium | EX_lys_L_medium | 13.26 | 6 | 1.14% |
man_medium | EX_man_medium | 16.75 | 6 | 1.44% |
met_L_medium | EX_met_L_medium | 2.034 | 5 | 0.15% |
metala_medium | EX_metala_medium | 2.891 | 8 | 0.33% |
mg2_medium | EX_mg2_medium | 0.2225 | 0 | 0.00% |
mn2_medium | EX_mn2_medium | 0.2225 | 0 | 0.00% |
mqn7_medium | EX_mqn7_medium | 0.04792 | 46 | 0.03% |
mqn8_medium | EX_mqn8_medium | 0.1173 | 51 | 0.09% |
ncam_medium | EX_ncam_medium | 0.01597 | 6 | 0.00% |
nmn_medium | EX_nmn_medium | 12.43 | 11 | 1.96% |
no3_medium | EX_no3_medium | 0.4119 | 0 | 0.00% |
o2_medium | EX_o2_medium | 227 | 0 | 0.00% |
ocdca_medium | EX_ocdca_medium | 2.289 | 18 | 0.59% |
phe_L_medium | EX_phe_L_medium | 4.973 | 9 | 0.64% |
pheme_medium | EX_pheme_medium | 0.1823 | 34 | 0.09% |
phpyr_medium | EX_phpyr_medium | 0.3986 | 9 | 0.05% |
pnto_R_medium | EX_pnto_R_medium | 0.243 | 9 | 0.03% |
pro_L_medium | EX_pro_L_medium | 21.15 | 5 | 1.52% |
ptrc_medium | EX_ptrc_medium | 0.1184 | 4 | 0.01% |
pullulan1200_medium | EX_pullulan1200_medium | 0.02527 | 7200 | 2.61% |
pydx_medium | EX_pydx_medium | 0.1864 | 8 | 0.02% |
pyr_medium | EX_pyr_medium | 38.37 | 3 | 1.65% |
q8_medium | EX_q8_medium | 0.1094 | 49 | 0.08% |
ribflv_medium | EX_ribflv_medium | 0.1958 | 17 | 0.05% |
ser_L_medium | EX_ser_L_medium | 48.29 | 3 | 2.08% |
sheme_medium | EX_sheme_medium | 0.1378 | 42 | 0.08% |
so4_medium | EX_so4_medium | 0.2225 | 0 | 0.00% |
spmd_medium | EX_spmd_medium | 0.1743 | 7 | 0.02% |
stys_medium | EX_stys_medium | 0.2655 | 24 | 0.09% |
sucr_medium | EX_sucr_medium | 26.43 | 12 | 4.55% |
thm_medium | EX_thm_medium | 0.1823 | 12 | 0.03% |
thr_L_medium | EX_thr_L_medium | 11.84 | 4 | 0.68% |
thymd_medium | EX_thymd_medium | 0.3716 | 10 | 0.05% |
trp_L_medium | EX_trp_L_medium | 1.641 | 11 | 0.26% |
ttdca_medium | EX_ttdca_medium | 2.129 | 14 | 0.43% |
tyr_L_medium | EX_tyr_L_medium | 12.37 | 9 | 1.60% |
uri_medium | EX_uri_medium | 14.92 | 9 | 1.93% |
val_L_medium | EX_val_L_medium | 13.35 | 5 | 0.96% |
zn2_medium | EX_zn2_medium | 0.2225 | 0 | 0.00% |
Secretion
Metabolite | Reaction | Flux | C-Number | C-Flux |
---|---|---|---|---|
_4hphac_medium | EX__4hphac_medium | -8.28 | 8 | 1.26% |
ac_medium | EX_ac_medium | -576.1 | 2 | 21.93% |
ade_medium | EX_ade_medium | -61.57 | 5 | 5.86% |
ala_L_medium | EX_ala_L_medium | -1.969 | 3 | 0.11% |
asp_L_medium | EX_asp_L_medium | -94.37 | 4 | 7.18% |
but_medium | EX_but_medium | -23.2 | 4 | 1.77% |
co2_medium | EX_co2_medium | -101.8 | 1 | 1.94% |
etoh_medium | EX_etoh_medium | -71.47 | 2 | 2.72% |
for_medium | EX_for_medium | -384.4 | 1 | 7.32% |
glu_L_medium | EX_glu_L_medium | -112.3 | 5 | 10.69% |
gly_medium | EX_gly_medium | -116.3 | 2 | 4.43% |
gua_medium | EX_gua_medium | -10.17 | 5 | 0.97% |
h2o_medium | EX_h2o_medium | -521.8 | 0 | 0.00% |
h2s_medium | EX_h2s_medium | -0.1468 | 0 | 0.00% |
ile_L_medium | EX_ile_L_medium | -4.345 | 6 | 0.50% |
lac_D_medium | EX_lac_D_medium | -72.18 | 3 | 4.12% |
lac_L_medium | EX_lac_L_medium | -13.8 | 3 | 0.79% |
leu_L_medium | EX_leu_L_medium | -56.74 | 6 | 6.48% |
mal_L_medium | EX_mal_L_medium | -66.12 | 4 | 5.03% |
nac_medium | EX_nac_medium | -12 | 6 | 1.37% |
nh4_medium | EX_nh4_medium | -336.8 | 0 | 0.00% |
orn_medium | EX_orn_medium | -33.57 | 5 | 3.19% |
pi_medium | EX_pi_medium | -32.8 | 0 | 0.00% |
ppa_medium | EX_ppa_medium | -109.6 | 3 | 6.26% |
ppi_medium | EX_ppi_medium | -15.5 | 0 | 0.00% |
succ_medium | EX_succ_medium | -66.71 | 4 | 5.08% |
ura_medium | EX_ura_medium | -11.12 | 4 | 0.85% |
urea_medium | EX_urea_medium | -8.377 | 1 | 0.16% |
cpd11416_medium | community_biomass | -43.85 | 0 | 0.00% |
Saving and loading community models
Community model objects can be saved and loaded into SBML files. This is different from the other available option to save the cobra model of the community model objects, as the abundance fractions of the organisms are written into the file as well. Saving and loading the community model can be done like this:
[13]:
com_model_obj.save("../data/toy/output/henson_com_model.xml")
[14]:
com_model_obj_loaded = pycomo.CommunityModel.load("../data/toy/output/henson_com_model.xml")
[15]:
com_model_obj_loaded
[15]:
<pycomo.pycomo_models.CommunityModel at 0x7efffe53f450>
[16]:
com_model_obj_loaded.model.optimize()
[16]:
fluxes | reduced_costs | |
---|---|---|
Fusobacterium_nucleatum_subsp_nucleatum_ATCC_25586__15DAPt | 0.000000 | 0.000000e+00 |
Fusobacterium_nucleatum_subsp_nucleatum_ATCC_25586__1P4H2CBXLAH_Fusobacterium_nucleatum_subsp_nucleatum_ATCC_25586_c | 0.000000 | 0.000000e+00 |
Fusobacterium_nucleatum_subsp_nucleatum_ATCC_25586__26DAPLLAT_Fusobacterium_nucleatum_subsp_nucleatum_ATCC_25586_c | -7.830932 | 3.083408e-33 |
Fusobacterium_nucleatum_subsp_nucleatum_ATCC_25586__2DHPL_Fusobacterium_nucleatum_subsp_nucleatum_ATCC_25586_c | 0.000000 | 0.000000e+00 |
Fusobacterium_nucleatum_subsp_nucleatum_ATCC_25586__2DMMQ8abc | 0.007987 | -2.157042e-32 |
... | ... | ... |
SK_Rothia_mucilaginosa_DY_18_biomass429_ub | 0.562442 | 0.000000e+00 |
SK_Rothia_mucilaginosa_DY_18_to_community_biomass_ub | 0.562442 | 0.000000e+00 |
f_final | 1.000000 | 0.000000e+00 |
abundance_reaction | 43.848202 | 4.302114e-16 |
community_biomass | 43.848202 | 0.000000e+00 |
55176 rows × 2 columns
Quality Checks
One of the quality checks that should be done is to look into all unbalanced reactions (mass and charge) in the entire model. As said before, such reactions should only exist in the case of boundary reactions, such as exchange, sink and source reactions.
[17]:
unbalanced_reactions = com_model_obj.get_unbalanced_reactions()
print(f"{len(unbalanced_reactions)} unbalanced reactions")
print(f"Example reactions:")
for rxn in list(unbalanced_reactions.keys())[:10]:
print(f"{rxn.id}: {unbalanced_reactions[rxn]}")
235 unbalanced reactions
Example reactions:
Fusobacterium_nucleatum_subsp_nucleatum_ATCC_25586_DM_5MTR_Fusobacterium_nucleatum_subsp_nucleatum_ATCC_25586_c: {'C': -6.0, 'H': -12.0, 'O': -4.0, 'S': -1.0}
Fusobacterium_nucleatum_subsp_nucleatum_ATCC_25586_DM_dhptd_Fusobacterium_nucleatum_subsp_nucleatum_ATCC_25586_c: {'C': -5.0, 'H': -8.0, 'O': -4.0}
Fusobacterium_nucleatum_subsp_nucleatum_ATCC_25586_DM_hcys_L_Fusobacterium_nucleatum_subsp_nucleatum_ATCC_25586_c: {'C': -4.0, 'H': -9.0, 'N': -1.0, 'O': -2.0, 'S': -1.0}
Fusobacterium_nucleatum_subsp_nucleatum_ATCC_25586_EX_biomass_e_Fusobacterium_nucleatum_subsp_nucleatum_ATCC_25586_c: {'X': -1.0}
Fusobacterium_nucleatum_subsp_nucleatum_ATCC_25586_NADH8: {'H': 3.552713678800501e-15}
Fusobacterium_nucleatum_subsp_nucleatum_ATCC_25586_SHCHCC2_Fusobacterium_nucleatum_subsp_nucleatum_ATCC_25586_c: {'charge': -2.0}
Fusobacterium_nucleatum_subsp_nucleatum_ATCC_25586_dreplication_Fusobacterium_nucleatum_subsp_nucleatum_ATCC_25586_c: {'X': 1.0}
Fusobacterium_nucleatum_subsp_nucleatum_ATCC_25586_pbiosynthesis_Fusobacterium_nucleatum_subsp_nucleatum_ATCC_25586_c: {'X': 1.0}
Fusobacterium_nucleatum_subsp_nucleatum_ATCC_25586_rtranscription_Fusobacterium_nucleatum_subsp_nucleatum_ATCC_25586_c: {'X': 1.0}
Fusobacterium_nucleatum_subsp_nucleatum_ATCC_25586_sink_gthrd_Fusobacterium_nucleatum_subsp_nucleatum_ATCC_25586_c: {'charge': 1.0, 'C': -10.0, 'H': -16.0, 'N': -3.0, 'O': -6.0, 'S': -1.0}
Analysis of community models
PyCoMo offers the option to calculate all potential exchange metabolites and cross-feeding interactions in a community, independent of the community composition. The example for this part will be a three member community published by Koch et al. 2019 (https://doi.org/10.1371/journal.pcbi.1006759). The three member organisms are representatives of functional guilds in a biogas community.
Creating the community model
We repeat the steps as before.
[18]:
test_model_dir = "../data/use_case/koch"
named_models = pycomo.load_named_models_from_dir(test_model_dir)
'3PG' is not a valid SBML 'SId'.
'2PG' is not a valid SBML 'SId'.
'2PG__PEP' is not a valid SBML 'SId'.
'3PG__2PG' is not a valid SBML 'SId'.
'0Pyr__AcCoA' is not a valid SBML 'SId'.
'3PG' is not a valid SBML 'SId'.
'2PG' is not a valid SBML 'SId'.
'5CHOMPT' is not a valid SBML 'SId'.
'3PG__2PG__3PG' is not a valid SBML 'SId'.
'5CHOMPT__CHH4MPT' is not a valid SBML 'SId'.
'5CHOMPT' is not a valid SBML 'SId'.
'3PG' is not a valid SBML 'SId'.
'2PG' is not a valid SBML 'SId'.
'2PG__3PG' is not a valid SBML 'SId'.
'3PG__DPG' is not a valid SBML 'SId'.
'5CHOMPT__CHH4MPT' is not a valid SBML 'SId'.
[19]:
named_models
[19]:
{'dv': <Model CNA_DV at 0x7effe098f590>,
'mb': <Model CNA_MB at 0x7effe087aad0>,
'mh': <Model CNA_MM at 0x7effe08453d0>}
[20]:
single_org_models = []
for name, model in named_models.items():
single_org_model = pycomo.SingleOrganismModel(model, name)
single_org_models.append(single_org_model)
community_name = "koch_community_model"
com_model_obj = pycomo.CommunityModel(single_org_models, community_name)
With the community model generated, we set the medium for the analysis, as done by Koch et al.
[21]:
medium = {
'EX_CO2_EX_medium': 1000.0,
'EX_Eth_EX_medium': 1000.0,
'EX_BM_tot_medium': 1000.0
}
com_model_obj.medium = medium
com_model_obj.apply_medium()
# Some metabolites are not allowed to accumulate in the medium.
com_model_obj.model.reactions.get_by_id("EX_Form_EX_medium").upper_bound = 0.
com_model_obj.model.reactions.get_by_id("EX_H2_EX_medium").upper_bound = 0.
2025-02-11 16:36:37,472 - pycomo - INFO - No community model generated yet. Generating now:
2025-02-11 16:36:37,495 - pycomo - INFO - Identified biomass reaction from objective: r_BMDV2BMc
2025-02-11 16:36:37,646 - pycomo - INFO - Identified biomass reaction from objective: BM_Synth
2025-02-11 16:36:37,836 - pycomo - INFO - Identified biomass reaction from objective: BM_Synth
2025-02-11 16:36:38,015 - pycomo - WARNING - No annotation overlap found for matching several metabolites (8). Please make sure that the matched metabolites are indeed representing the same substance in all models! The list of metaboliteswithout annotation overlap can be accessed via 'model.no_annotation_overlap'
2025-02-11 16:36:38,088 - pycomo - INFO - Generated community model.
Calculating potential metabolite exchange
All potential exchange metabolite fluxes and cross-feeding interactions can be calculated with the potential_metabolite_exchanges method. This is a single FVA, but with a minimum objective of 0 and relaxed constraints. All reaction constraints are changed to include the value 0, which circumvents cases where a specific flux through a reaction is required, leading to infeasible solutions for certain community compositions.
[22]:
com_model_obj.potential_metabolite_exchanges()
2025-02-11 16:36:41,581 - pycomo - INFO - Logger initialized.
2025-02-11 16:36:41,581 - pycomo - INFO - Process Pool Logger initialized.
2025-02-11 16:36:41,581 - pycomo - INFO - Utils Logger initialized.
2025-02-11 16:36:41,583 - pycomo - INFO - Multiprocess Logger initialized.
2025-02-11 16:36:42,374 - pycomo - INFO - Logger initialized.
2025-02-11 16:36:42,411 - pycomo - INFO - Process Pool Logger initialized.
2025-02-11 16:36:42,411 - pycomo - INFO - Utils Logger initialized.
2025-02-11 16:36:42,413 - pycomo - INFO - Multiprocess Logger initialized.
2025-02-11 16:36:43,251 - pycomo - INFO - Logger initialized.
2025-02-11 16:36:43,252 - pycomo - INFO - Process Pool Logger initialized.
2025-02-11 16:36:43,252 - pycomo - INFO - Utils Logger initialized.
2025-02-11 16:36:43,254 - pycomo - INFO - Multiprocess Logger initialized.
2025-02-11 16:36:44,118 - pycomo - INFO - Logger initialized.
2025-02-11 16:36:44,118 - pycomo - INFO - Process Pool Logger initialized.
2025-02-11 16:36:44,118 - pycomo - INFO - Utils Logger initialized.
2025-02-11 16:36:44,122 - pycomo - INFO - Multiprocess Logger initialized.
2025-02-11 16:36:45,089 - pycomo - INFO - Logger initialized.
2025-02-11 16:36:45,091 - pycomo - INFO - Process Pool Logger initialized.
2025-02-11 16:36:45,091 - pycomo - INFO - Utils Logger initialized.
2025-02-11 16:36:45,093 - pycomo - INFO - Multiprocess Logger initialized.
2025-02-11 16:36:46,027 - pycomo - INFO - Logger initialized.
2025-02-11 16:36:46,028 - pycomo - INFO - Process Pool Logger initialized.
2025-02-11 16:36:46,028 - pycomo - INFO - Utils Logger initialized.
2025-02-11 16:36:46,029 - pycomo - INFO - Multiprocess Logger initialized.
2025-02-11 16:36:46,956 - pycomo - INFO - Logger initialized.
2025-02-11 16:36:46,957 - pycomo - INFO - Process Pool Logger initialized.
2025-02-11 16:36:46,957 - pycomo - INFO - Utils Logger initialized.
2025-02-11 16:36:46,959 - pycomo - INFO - Multiprocess Logger initialized.
2025-02-11 16:36:47,001 - pycomo - INFO - Processed 2.82% of find loops steps
2025-02-11 16:36:47,053 - pycomo - INFO - Processed 5.63% of find loops steps
2025-02-11 16:36:47,075 - pycomo - INFO - Processed 8.45% of find loops steps
2025-02-11 16:36:47,095 - pycomo - INFO - Processed 11.27% of find loops steps
2025-02-11 16:36:47,114 - pycomo - INFO - Processed 14.08% of find loops steps
2025-02-11 16:36:47,156 - pycomo - INFO - Processed 16.9% of find loops steps
2025-02-11 16:36:47,206 - pycomo - INFO - Processed 19.72% of find loops steps
2025-02-11 16:36:47,217 - pycomo - INFO - Processed 22.54% of find loops steps
2025-02-11 16:36:47,246 - pycomo - INFO - Processed 25.35% of find loops steps
2025-02-11 16:36:47,275 - pycomo - INFO - Processed 28.17% of find loops steps
2025-02-11 16:36:47,319 - pycomo - INFO - Processed 30.99% of find loops steps
2025-02-11 16:36:47,336 - pycomo - INFO - Processed 33.8% of find loops steps
2025-02-11 16:36:47,372 - pycomo - INFO - Processed 36.62% of find loops steps
2025-02-11 16:36:47,412 - pycomo - INFO - Processed 39.44% of find loops steps
2025-02-11 16:36:47,449 - pycomo - INFO - Processed 42.25% of find loops steps
2025-02-11 16:36:47,458 - pycomo - INFO - Processed 45.07% of find loops steps
2025-02-11 16:36:47,495 - pycomo - INFO - Processed 47.89% of find loops steps
2025-02-11 16:36:47,540 - pycomo - INFO - Processed 50.7% of find loops steps
2025-02-11 16:36:47,570 - pycomo - INFO - Processed 53.52% of find loops steps
2025-02-11 16:36:47,603 - pycomo - INFO - Processed 56.34% of find loops steps
2025-02-11 16:36:47,659 - pycomo - INFO - Processed 59.15% of find loops steps
2025-02-11 16:36:47,678 - pycomo - INFO - Processed 61.97% of find loops steps
2025-02-11 16:36:47,714 - pycomo - INFO - Processed 64.79% of find loops steps
2025-02-11 16:36:47,762 - pycomo - INFO - Processed 67.61% of find loops steps
2025-02-11 16:36:47,786 - pycomo - INFO - Processed 70.42% of find loops steps
2025-02-11 16:36:47,799 - pycomo - INFO - Processed 73.24% of find loops steps
2025-02-11 16:36:47,837 - pycomo - INFO - Processed 76.06% of find loops steps
2025-02-11 16:36:47,886 - pycomo - INFO - Processed 78.87% of find loops steps
2025-02-11 16:36:47,908 - pycomo - INFO - Processed 81.69% of find loops steps
2025-02-11 16:36:47,919 - pycomo - INFO - Processed 84.51% of find loops steps
2025-02-11 16:36:47,970 - pycomo - INFO - Processed 87.32% of find loops steps
2025-02-11 16:36:48,010 - pycomo - INFO - Processed 90.14% of find loops steps
2025-02-11 16:36:48,028 - pycomo - INFO - Processed 92.96% of find loops steps
2025-02-11 16:36:48,045 - pycomo - INFO - Processed 95.77% of find loops steps
2025-02-11 16:36:48,063 - pycomo - INFO - Processed 98.59% of find loops steps
2025-02-11 16:36:48,071 - pycomo - INFO - Processed 100.0% of find loops steps
2025-02-11 16:36:49,148 - pycomo - INFO - Logger initialized.
2025-02-11 16:36:49,149 - pycomo - INFO - Process Pool Logger initialized.
2025-02-11 16:36:49,149 - pycomo - INFO - Utils Logger initialized.
2025-02-11 16:36:49,151 - pycomo - INFO - Multiprocess Logger initialized.
2025-02-11 16:36:49,278 - pycomo - INFO - Log level set to 20
2025-02-11 16:36:50,030 - pycomo - INFO - Logger initialized.
2025-02-11 16:36:50,031 - pycomo - INFO - Process Pool Logger initialized.
2025-02-11 16:36:50,031 - pycomo - INFO - Utils Logger initialized.
2025-02-11 16:36:50,032 - pycomo - INFO - Multiprocess Logger initialized.
2025-02-11 16:36:50,144 - pycomo - INFO - Log level set to 20
2025-02-11 16:36:50,881 - pycomo - INFO - Logger initialized.
2025-02-11 16:36:50,882 - pycomo - INFO - Process Pool Logger initialized.
2025-02-11 16:36:50,882 - pycomo - INFO - Utils Logger initialized.
2025-02-11 16:36:50,884 - pycomo - INFO - Multiprocess Logger initialized.
2025-02-11 16:36:50,995 - pycomo - INFO - Log level set to 20
2025-02-11 16:36:51,730 - pycomo - INFO - Logger initialized.
2025-02-11 16:36:51,730 - pycomo - INFO - Process Pool Logger initialized.
2025-02-11 16:36:51,730 - pycomo - INFO - Utils Logger initialized.
2025-02-11 16:36:51,732 - pycomo - INFO - Multiprocess Logger initialized.
2025-02-11 16:36:51,843 - pycomo - INFO - Log level set to 20
2025-02-11 16:36:52,583 - pycomo - INFO - Logger initialized.
2025-02-11 16:36:52,584 - pycomo - INFO - Process Pool Logger initialized.
2025-02-11 16:36:52,584 - pycomo - INFO - Utils Logger initialized.
2025-02-11 16:36:52,585 - pycomo - INFO - Multiprocess Logger initialized.
2025-02-11 16:36:52,696 - pycomo - INFO - Log level set to 20
2025-02-11 16:36:53,432 - pycomo - INFO - Logger initialized.
2025-02-11 16:36:53,432 - pycomo - INFO - Process Pool Logger initialized.
2025-02-11 16:36:53,433 - pycomo - INFO - Utils Logger initialized.
2025-02-11 16:36:53,434 - pycomo - INFO - Multiprocess Logger initialized.
2025-02-11 16:36:53,546 - pycomo - INFO - Log level set to 20
2025-02-11 16:36:54,279 - pycomo - INFO - Logger initialized.
2025-02-11 16:36:54,279 - pycomo - INFO - Process Pool Logger initialized.
2025-02-11 16:36:54,280 - pycomo - INFO - Utils Logger initialized.
2025-02-11 16:36:54,281 - pycomo - INFO - Multiprocess Logger initialized.
2025-02-11 16:36:54,289 - pycomo - INFO - Loop correction will be applied on dv_TF_H2_TF_dv_External_Species
2025-02-11 16:36:54,289 - pycomo - INFO - Loop correction will be applied on dv_TF_CO2_TF_dv_External_Species
2025-02-11 16:36:54,289 - pycomo - INFO - Loop correction will be applied on dv_TF_Form_TF_dv_External_Species
2025-02-11 16:36:54,574 - pycomo - INFO - Processed 27.78% of fva steps
2025-02-11 16:36:54,596 - pycomo - INFO - Processed 55.56% of fva steps
2025-02-11 16:36:54,608 - pycomo - INFO - Loop correction will be applied on mh_TF_H2_TF_mh_External_Species
2025-02-11 16:36:54,622 - pycomo - INFO - Loop correction will be applied on mh_TF_CO2_TF_mh_External_Species
2025-02-11 16:36:54,623 - pycomo - INFO - Log level set to 20
2025-02-11 16:36:54,628 - pycomo - INFO - Loop correction will be applied on mh_TF_Form_TF_mh_External_Species
2025-02-11 16:36:54,747 - pycomo - INFO - Processed 83.33% of fva steps
2025-02-11 16:36:54,749 - pycomo - INFO - Processed 100.0% of fva steps
[22]:
metabolite_id | metabolite_name | cross_feeding | produced_by | consumed_by | |
---|---|---|---|---|---|
0 | H2_EX_medium | H2_external | True | [dv] | [mb, mh] |
1 | Ac_EX_medium | acetate_external | True | [dv] | [mb] |
2 | CO2_EX_medium | CO2_external | True | [mb, mh] | [dv, mb, mh] |
3 | Form_EX_medium | formate_external | True | [dv] | [mh] |
4 | SO4_EX_medium | sulfate_external | False | [] | [] |
5 | H2S_EX_medium | hydrogensulfide_external | False | [] | [] |
6 | Eth_EX_medium | ethanol_external | False | [] | [dv] |
7 | Lac_EX_medium | lactate_external | False | [] | [] |
8 | Pyr_EX_medium | pyruvate_external | False | [] | [] |
9 | CH4_EX_medium | nethane_external | False | [mb, mh] | [] |
10 | MetOH_EX_medium | nethanol_external | False | [] | [] |
11 | BM_tot_medium | total_biomass | False | [] | [] |
12 | cpd11416_medium | Community Biomass | False | [dv, mb, mh] | [] |
Plotting the maxiumum growth rate over the composition space
[23]:
import pandas as pd
# Iterate over the fractions in steps of 0.01
com_model_obj.convert_to_fixed_abundance()
rows = []
for i in range (0,100,1): # fraction of D. vulgaris
for j in range (0, 100-i, 1): # fraction of M. hungatei
if (100-i-j) < 0:
continue
abundances = {"dv": i/100., "mh": j/100., "mb": (100-i-j)/100.}
# Apply the abuyndances
com_model_obj.apply_fixed_abundance(abundances)
# Reapply the bound restrictions of the exchange reactions
com_model_obj.model.reactions.get_by_id("EX_Form_EX_medium").upper_bound = 0.
com_model_obj.model.reactions.get_by_id("EX_H2_EX_medium").upper_bound = 0.
# Calculate the optimal growth rate
solution = com_model_obj.model.optimize()
growth = 0. if str(solution.status) == "infeasible" else solution.objective_value
rows.append({"dv": i/100., "mh": j/100., "growth": growth})
growth_df = pd.DataFrame(rows)
[24]:
import matplotlib.pyplot as plt
import seaborn as sns
sns.set_theme()
# Restructure dataframe for heatmap
growth_df_pivot = growth_df.pivot(index="mh", columns="dv", values="growth")
# Draw a heatmap with the numeric values in each cell
f, ax = plt.subplots(figsize=(9, 6))
sns.heatmap(growth_df_pivot, ax=ax)
ax.invert_yaxis()

[ ]: