PyCoMo Loopless FVA
This tutorial show-cases the use of loopless FVA.
The expected runtime for this notebook is less than 10 minutes.
[1]:
from pathlib import Path
import sys
import os
import cobra
import matplotlib.pyplot as plt
from cobra import Reaction, Metabolite, Model
from cobra.flux_analysis.loopless import add_loopless, loopless_solution
import pandas as pd
import numpy as np
import math
import time
import warnings
[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:57:04,459 - pycomo - INFO - Logger initialized.
2025-02-11 16:57:04,460 - pycomo - INFO - Process Pool Logger initialized.
2025-02-11 16:57:04,461 - pycomo - INFO - Utils Logger initialized.
2025-02-11 16:57:04,462 - pycomo - INFO - Multiprocess Logger initialized.
2025-02-11 16:57:04,465 - pycomo - INFO - Log level set to info
Community toy model
This simple community toy model consists of two identical community members. Each member has a two step conversion of the starting metabolite A. The products of these conversions (B and C) can be secreted and taken up from the medium, thus allowing exchange and forming a cycle. The members also have a biomass reaction with substrates C and D (an additional substrate).
[3]:
model_single = Model()
model_single.add_metabolites([Metabolite(i) for i in "ABCD"])
for met in model_single.metabolites:
met.compartment = "c"
model_single.add_metabolites([Metabolite(i+"_e") for i in "ABCD"])
for i in "ABCD":
model_single.metabolites.get_by_id(i+"_e").compartment = "e"
model_single.add_reactions([Reaction(i) for i in ["EX_A", "EX_B", "EX_C", "EX_D", "TP_A", "TP_B", "TP_C", "TP_D", "bio", "v1", "v2"]])
model_single.reactions.EX_A.add_metabolites({"A_e": 1})
model_single.reactions.EX_B.add_metabolites({"B_e": 1})
model_single.reactions.EX_C.add_metabolites({"C_e": 1})
model_single.reactions.EX_D.add_metabolites({"D_e": 1})
model_single.reactions.TP_A.add_metabolites({"A_e": -1, "A": 1})
model_single.reactions.TP_B.add_metabolites({"B_e": -1, "B": 1})
model_single.reactions.TP_C.add_metabolites({"C_e": -1, "C": 1})
model_single.reactions.TP_D.add_metabolites({"D_e": -1, "D": 1})
model_single.reactions.bio.add_metabolites({"C": -1, "D": -1})
model_single.reactions.v1.add_metabolites({"A": -1, "B": 1})
model_single.reactions.v2.add_metabolites({"B": -1, "C": 1})
model_single.reactions.TP_B.lower_bound = -500
model_single.reactions.TP_C.lower_bound = -500
model_single.reactions.v2.lower_bound = -1000
model_single.objective = 'bio'
Constructing the community model
[4]:
single_org_models_toy = []
for name in ["model_a", "model_b"]:
print(name)
single_org_model = pycomo.SingleOrganismModel(model_single, name)
single_org_models_toy.append(single_org_model)
model_a
model_b
[5]:
community_name = "toy_com"
com_model_obj_toy = pycomo.CommunityModel(single_org_models_toy, community_name)
com_model_obj_toy.convert_to_fixed_abundance()
2025-02-11 16:57:04,528 - pycomo - INFO - No community model generated yet. Generating now:
2025-02-11 16:57:04,534 - pycomo - INFO - Identified biomass reaction from objective: bio
2025-02-11 16:57:04,535 - pycomo - INFO - Note: no products in the objective function, adding biomass to it.
2025-02-11 16:57:04,560 - pycomo - INFO - Identified biomass reaction from objective: bio
2025-02-11 16:57:04,560 - pycomo - INFO - Note: no products in the objective function, adding biomass to it.
2025-02-11 16:57:04,592 - pycomo - WARNING - No annotation overlap found for matching several metabolites (4). 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:57:04,603 - pycomo - INFO - Generated community model.
[ ]:
com_model_obj_toy.medium = {'EX_A_medium': 1000.0, 'EX_D_medium': 1000.0}
com_model_obj_toy.apply_medium()
Name | toy_com |
Memory address | 7f27b1192e10 |
Number of metabolites | 64 |
Number of reactions | 71 |
Number of genes | 0 |
Number of groups | 0 |
Objective expression | 1.0*community_biomass - 1.0*community_biomass_reverse_44dc1 |
Compartments | model_a_c, model_a_e, model_a_medium, medium, fraction_reaction, model_b_e, model_b_c, model_b_medium |
[7]:
com_model_obj_toy.summary()
[7]:
Objective
1.0 community_biomass = 1000.0000000000001
Uptake
Metabolite | Reaction | Flux | C-Number | C-Flux |
---|---|---|---|---|
A_medium | EX_A_medium | 1000 | 0 | 0.00% |
D_medium | EX_D_medium | 1000 | 0 | 0.00% |
Secretion
Metabolite | Reaction | Flux | C-Number | C-Flux |
---|---|---|---|---|
cpd11416_medium | community_biomass | -1000 | 0 | 0.00% |
Loops in the toy model
[8]:
com_model_obj_toy.get_loops()
2025-02-11 16:57:06,931 - pycomo - INFO - Logger initialized.
2025-02-11 16:57:06,934 - pycomo - INFO - Process Pool Logger initialized.
2025-02-11 16:57:06,935 - pycomo - INFO - Utils Logger initialized.
2025-02-11 16:57:06,943 - pycomo - INFO - Multiprocess Logger initialized.
2025-02-11 16:57:07,062 - pycomo - INFO - Processed 33.33% of find loops steps
2025-02-11 16:57:07,095 - pycomo - INFO - Processed 66.67% of find loops steps
2025-02-11 16:57:07,120 - pycomo - INFO - Processed 100.0% of find loops steps
[8]:
reaction | min_flux | max_flux | |
---|---|---|---|
0 | model_a_TF_B_model_a_e | -500.0 | 500.0 |
1 | model_a_TF_C_model_a_e | -500.0 | 500.0 |
2 | model_a_TP_B | -500.0 | 500.0 |
3 | model_a_TP_C | -500.0 | 500.0 |
4 | model_a_v2_model_a_c | -500.0 | 500.0 |
5 | model_b_TF_B_model_b_e | -500.0 | 500.0 |
6 | model_b_TF_C_model_b_e | -500.0 | 500.0 |
7 | model_b_TP_B | -500.0 | 500.0 |
8 | model_b_TP_C | -500.0 | 500.0 |
9 | model_b_v2_model_b_c | -500.0 | 500.0 |
FVA examples
FVA with loops
Normal fva will include the loops including metabolites B and C, reaction v2 and the transporters of B and C in the solutions.
The following scenarios and correct outcomes will be tested on a :
No medium: no reaction can carry flux
100% objective value: reaction v2 carries maximum flux (500; = 1000 * 0.5 as normalized to equal abundance) and transport reactions of B and C are inactive
0% objective value: reactions v2 and transporters of B and C carry maximum flux (250, reverse also for transporters)
80% objective value: reaction v2 carries flux between 300 and 500. Transporter of B can be active between -200 and 200, transporter of C between -100 and 100. This solution arises by one member giving 200 of B to the other (keeping 300), which converts B to C with maximum flux of 500, then gives back 100 of C while keeping the required 400. This results in a biomass reaction of 400 for both (80% of 500).
COBRApy fva
The loopless version of COBRApy cannot be used on PyCoMo community models, due to their bound-free reaction structure. The resulting solutions include the loop:
[9]:
%%time
with com_model_obj_toy.model:
com_model_obj_toy.medium = {}
com_model_obj_toy.apply_medium()
fva = cobra.flux_analysis.flux_variability_analysis(com_model_obj_toy.model,
com_model_obj_toy.model.reactions,
fraction_of_optimum=0.,
loopless=True)
fva
CPU times: user 38 ms, sys: 91.3 ms, total: 129 ms
Wall time: 347 ms
[9]:
minimum | maximum | |
---|---|---|
model_a_TF_A_model_a_e | 0.000000e+00 | 0.000000e+00 |
model_a_TF_B_model_a_e | -2.500000e+02 | 2.500000e+02 |
model_a_TF_C_model_a_e | -2.500000e+02 | 2.500000e+02 |
model_a_TF_D_model_a_e | 0.000000e+00 | 0.000000e+00 |
model_a_TP_A | 0.000000e+00 | -1.934676e-14 |
... | ... | ... |
SK_model_b_v2_model_b_c_ub | 2.500000e+00 | 7.500000e+00 |
SK_model_b_to_community_biomass_ub | 5.000000e+00 | 5.000000e+00 |
f_final | 1.000000e+00 | 1.000000e+00 |
abundance_reaction | -1.298745e-13 | 0.000000e+00 |
community_biomass | 0.000000e+00 | 0.000000e+00 |
71 rows × 2 columns
PyCoMo fva with loops
The PyCoMo wrapper for fva will also include loops, when loopless mode is not activated
[10]:
%%time
com_model_obj_toy.medium = {'EX_A_medium': 1000.0, 'EX_D_medium': 1000.0}
com_model_obj_toy.apply_medium()
with com_model_obj_toy.model:
com_model_obj_toy.medium = {}
com_model_obj_toy.apply_medium()
fva = com_model_obj_toy.run_fva(reactions=com_model_obj_toy.model.reactions, fraction_of_optimum=1., loopless=False)
fva
2025-02-11 16:57:09,823 - pycomo - INFO - Logger initialized.
2025-02-11 16:57:09,827 - pycomo - INFO - Process Pool Logger initialized.
2025-02-11 16:57:09,827 - pycomo - INFO - Utils Logger initialized.
2025-02-11 16:57:09,831 - pycomo - INFO - Multiprocess Logger initialized.
2025-02-11 16:57:09,870 - pycomo - INFO - Logger initialized.
2025-02-11 16:57:09,872 - pycomo - INFO - Process Pool Logger initialized.
2025-02-11 16:57:09,873 - pycomo - INFO - Utils Logger initialized.
2025-02-11 16:57:09,876 - pycomo - INFO - Multiprocess Logger initialized.
2025-02-11 16:57:09,878 - pycomo - INFO - Log level set to 20
2025-02-11 16:57:09,913 - pycomo - INFO - Logger initialized.
2025-02-11 16:57:09,914 - pycomo - INFO - Process Pool Logger initialized.
2025-02-11 16:57:09,914 - pycomo - INFO - Utils Logger initialized.
2025-02-11 16:57:09,917 - pycomo - INFO - Multiprocess Logger initialized.
2025-02-11 16:57:09,921 - pycomo - INFO - Log level set to 20
2025-02-11 16:57:09,928 - pycomo - INFO - Logger initialized.
2025-02-11 16:57:09,929 - pycomo - INFO - Process Pool Logger initialized.
2025-02-11 16:57:09,929 - pycomo - INFO - Utils Logger initialized.
2025-02-11 16:57:09,932 - pycomo - INFO - Multiprocess Logger initialized.
2025-02-11 16:57:09,946 - pycomo - INFO - Processed 66.67% of fva steps
2025-02-11 16:57:09,950 - pycomo - INFO - Processed 100.0% of fva steps
CPU times: user 71 ms, sys: 7.07 ms, total: 78.1 ms
Wall time: 2.46 s
[10]:
reaction_id | min_flux | max_flux | |
---|---|---|---|
model_a_TF_A_model_a_e | model_a_TF_A_model_a_e | 0.0 | 0.000000e+00 |
model_a_TF_B_model_a_e | model_a_TF_B_model_a_e | -250.0 | 2.500000e+02 |
model_a_TF_C_model_a_e | model_a_TF_C_model_a_e | -250.0 | 2.500000e+02 |
model_a_TF_D_model_a_e | model_a_TF_D_model_a_e | 0.0 | 0.000000e+00 |
EX_A_medium | EX_A_medium | 0.0 | 0.000000e+00 |
EX_B_medium | EX_B_medium | 0.0 | -2.892122e-14 |
EX_C_medium | EX_C_medium | 0.0 | 2.892122e-14 |
EX_D_medium | EX_D_medium | 0.0 | 0.000000e+00 |
model_a_to_community_biomass | model_a_to_community_biomass | 0.0 | 0.000000e+00 |
model_b_TF_A_model_b_e | model_b_TF_A_model_b_e | 0.0 | 0.000000e+00 |
model_b_TF_B_model_b_e | model_b_TF_B_model_b_e | -250.0 | 2.500000e+02 |
model_b_TF_C_model_b_e | model_b_TF_C_model_b_e | -250.0 | 2.500000e+02 |
model_b_TF_D_model_b_e | model_b_TF_D_model_b_e | 0.0 | 0.000000e+00 |
model_b_to_community_biomass | model_b_to_community_biomass | 0.0 | 0.000000e+00 |
community_biomass | community_biomass | 0.0 | 0.000000e+00 |
PyCoMo loopless fva
The following examples show that the loopless fva implemented in PyCoMo leads to the correct solutions in the 4 test cases (no medium, 100% objective value, 0% objective value, 80% objective value)
Note: For larger (genome-scale, >4 members) it will be beneficial to use parallel processing for loopless FVA. The number of processes can be specified either using the cobrapy configuration object, or directly in the functions of PyCoMo, with the processes argument.
[11]:
%%time
with com_model_obj_toy.model:
com_model_obj_toy.medium = {}
com_model_obj_toy.apply_medium()
fva = com_model_obj_toy.run_fva(reactions=com_model_obj_toy.model.reactions, fraction_of_optimum=0., loopless=True)
fva
2025-02-11 16:57:12,150 - pycomo - INFO - Logger initialized.
2025-02-11 16:57:12,152 - pycomo - INFO - Process Pool Logger initialized.
2025-02-11 16:57:12,152 - pycomo - INFO - Utils Logger initialized.
2025-02-11 16:57:12,156 - pycomo - INFO - Multiprocess Logger initialized.
2025-02-11 16:57:12,330 - pycomo - INFO - Processed 33.33% of find loops steps
2025-02-11 16:57:12,402 - pycomo - INFO - Processed 66.67% of find loops steps
2025-02-11 16:57:12,453 - pycomo - INFO - Logger initialized.
2025-02-11 16:57:12,454 - pycomo - INFO - Logger initialized.
2025-02-11 16:57:12,455 - pycomo - INFO - Process Pool Logger initialized.
2025-02-11 16:57:12,455 - pycomo - INFO - Process Pool Logger initialized.
2025-02-11 16:57:12,462 - pycomo - INFO - Processed 100.0% of find loops steps
2025-02-11 16:57:12,455 - pycomo - INFO - Utils Logger initialized.
2025-02-11 16:57:12,455 - pycomo - INFO - Utils Logger initialized.
2025-02-11 16:57:12,460 - pycomo - INFO - Multiprocess Logger initialized.
2025-02-11 16:57:12,460 - pycomo - INFO - Multiprocess Logger initialized.
2025-02-11 16:57:14,622 - pycomo - INFO - Logger initialized.
2025-02-11 16:57:14,624 - pycomo - INFO - Process Pool Logger initialized.
2025-02-11 16:57:14,624 - pycomo - INFO - Utils Logger initialized.
2025-02-11 16:57:14,627 - pycomo - INFO - Multiprocess Logger initialized.
2025-02-11 16:57:14,653 - pycomo - INFO - Logger initialized.
2025-02-11 16:57:14,655 - pycomo - INFO - Process Pool Logger initialized.
2025-02-11 16:57:14,655 - pycomo - INFO - Utils Logger initialized.
2025-02-11 16:57:14,659 - pycomo - INFO - Multiprocess Logger initialized.
2025-02-11 16:57:14,674 - pycomo - INFO - Log level set to 20
2025-02-11 16:57:14,678 - pycomo - INFO - Loop correction will be applied on model_a_TF_B_model_a_e
2025-02-11 16:57:14,713 - pycomo - INFO - Loop correction will be applied on model_a_TF_C_model_a_e
2025-02-11 16:57:14,733 - pycomo - INFO - Log level set to 20
2025-02-11 16:57:14,767 - pycomo - INFO - Loop correction will be applied on model_b_TF_B_model_b_e
2025-02-11 16:57:14,767 - pycomo - INFO - Logger initialized.
2025-02-11 16:57:14,768 - pycomo - INFO - Process Pool Logger initialized.
2025-02-11 16:57:14,768 - pycomo - INFO - Utils Logger initialized.
2025-02-11 16:57:14,770 - pycomo - INFO - Loop correction will be applied on model_b_TF_C_model_b_e
2025-02-11 16:57:14,771 - pycomo - INFO - Processed 66.67% of fva steps
2025-02-11 16:57:14,773 - pycomo - INFO - Multiprocess Logger initialized.
2025-02-11 16:57:14,803 - pycomo - INFO - Processed 100.0% of fva steps
CPU times: user 219 ms, sys: 34.8 ms, total: 254 ms
Wall time: 4.83 s
[11]:
reaction_id | min_flux | max_flux | |
---|---|---|---|
model_a_TF_A_model_a_e | model_a_TF_A_model_a_e | 0.0 | 0.0 |
model_a_TF_B_model_a_e | model_a_TF_B_model_a_e | 0.0 | 0.0 |
model_a_TF_C_model_a_e | model_a_TF_C_model_a_e | 0.0 | 0.0 |
model_a_TF_D_model_a_e | model_a_TF_D_model_a_e | 0.0 | 0.0 |
EX_A_medium | EX_A_medium | 0.0 | 0.0 |
EX_B_medium | EX_B_medium | 0.0 | 0.0 |
EX_C_medium | EX_C_medium | 0.0 | 0.0 |
EX_D_medium | EX_D_medium | 0.0 | 0.0 |
model_a_to_community_biomass | model_a_to_community_biomass | 0.0 | 0.0 |
model_b_TF_A_model_b_e | model_b_TF_A_model_b_e | 0.0 | 0.0 |
model_b_TF_B_model_b_e | model_b_TF_B_model_b_e | 0.0 | 0.0 |
model_b_TF_C_model_b_e | model_b_TF_C_model_b_e | 0.0 | 0.0 |
model_b_TF_D_model_b_e | model_b_TF_D_model_b_e | 0.0 | 0.0 |
model_b_to_community_biomass | model_b_to_community_biomass | 0.0 | 0.0 |
community_biomass | community_biomass | 0.0 | 0.0 |
With loopless FVA, PyCoMo correctly calculates 0 flux for all reactions, when no medium is present.
[12]:
%%time
com_model_obj_toy.medium = {'EX_A_medium': 1000.0, 'EX_D_medium': 1000.0}
com_model_obj_toy.apply_medium()
with com_model_obj_toy.model:
fva = com_model_obj_toy.run_fva(reactions=com_model_obj_toy.model.reactions, fraction_of_optimum=1., loopless=True)
fva
2025-02-11 16:57:17,164 - pycomo - INFO - Logger initialized.
2025-02-11 16:57:17,165 - pycomo - INFO - Process Pool Logger initialized.
2025-02-11 16:57:17,165 - pycomo - INFO - Utils Logger initialized.
2025-02-11 16:57:17,166 - pycomo - INFO - Logger initialized.
2025-02-11 16:57:17,167 - pycomo - INFO - Process Pool Logger initialized.
2025-02-11 16:57:17,167 - pycomo - INFO - Utils Logger initialized.
2025-02-11 16:57:17,168 - pycomo - INFO - Multiprocess Logger initialized.
2025-02-11 16:57:17,170 - pycomo - INFO - Multiprocess Logger initialized.
2025-02-11 16:57:17,221 - pycomo - INFO - Logger initialized.
2025-02-11 16:57:17,223 - pycomo - INFO - Process Pool Logger initialized.
2025-02-11 16:57:17,224 - pycomo - INFO - Utils Logger initialized.
2025-02-11 16:57:17,232 - pycomo - INFO - Multiprocess Logger initialized.
2025-02-11 16:57:17,278 - pycomo - INFO - Processed 33.33% of find loops steps
2025-02-11 16:57:17,302 - pycomo - INFO - Processed 66.67% of find loops steps
2025-02-11 16:57:17,314 - pycomo - INFO - Processed 100.0% of find loops steps
2025-02-11 16:57:19,520 - pycomo - INFO - Logger initialized.
2025-02-11 16:57:19,526 - pycomo - INFO - Process Pool Logger initialized.
2025-02-11 16:57:19,527 - pycomo - INFO - Utils Logger initialized.
2025-02-11 16:57:19,531 - pycomo - INFO - Multiprocess Logger initialized.
2025-02-11 16:57:19,585 - pycomo - INFO - Log level set to 20
2025-02-11 16:57:19,591 - pycomo - INFO - Loop correction will be applied on model_a_TF_B_model_a_e
2025-02-11 16:57:19,608 - pycomo - INFO - Loop correction will be applied on model_a_TF_C_model_a_e
2025-02-11 16:57:19,612 - pycomo - INFO - Logger initialized.
2025-02-11 16:57:19,613 - pycomo - INFO - Process Pool Logger initialized.
2025-02-11 16:57:19,613 - pycomo - INFO - Utils Logger initialized.
2025-02-11 16:57:19,616 - pycomo - INFO - Multiprocess Logger initialized.
2025-02-11 16:57:19,628 - pycomo - INFO - Logger initialized.
2025-02-11 16:57:19,634 - pycomo - INFO - Logger initialized.
2025-02-11 16:57:19,635 - pycomo - INFO - Process Pool Logger initialized.
2025-02-11 16:57:19,636 - pycomo - INFO - Utils Logger initialized.
2025-02-11 16:57:19,639 - pycomo - INFO - Multiprocess Logger initialized.
2025-02-11 16:57:19,650 - pycomo - INFO - Processed 66.67% of fva steps
2025-02-11 16:57:19,650 - pycomo - INFO - Loop correction will be applied on model_b_TF_B_model_b_e
2025-02-11 16:57:19,659 - pycomo - INFO - Log level set to 20
2025-02-11 16:57:19,660 - pycomo - INFO - Loop correction will be applied on model_b_TF_C_model_b_e
2025-02-11 16:57:19,670 - pycomo - INFO - Logger initialized.
2025-02-11 16:57:19,672 - pycomo - INFO - Process Pool Logger initialized.
2025-02-11 16:57:19,672 - pycomo - INFO - Logger initialized.
2025-02-11 16:57:19,672 - pycomo - INFO - Utils Logger initialized.
2025-02-11 16:57:19,673 - pycomo - INFO - Process Pool Logger initialized.
2025-02-11 16:57:19,674 - pycomo - INFO - Utils Logger initialized.
2025-02-11 16:57:19,676 - pycomo - INFO - Multiprocess Logger initialized.
2025-02-11 16:57:19,677 - pycomo - INFO - Multiprocess Logger initialized.
2025-02-11 16:57:19,679 - pycomo - INFO - Processed 100.0% of fva steps
CPU times: user 126 ms, sys: 13.1 ms, total: 139 ms
Wall time: 4.86 s
[12]:
reaction_id | min_flux | max_flux | |
---|---|---|---|
model_a_TF_A_model_a_e | model_a_TF_A_model_a_e | 5.000000e+02 | 5.000000e+02 |
model_a_TF_B_model_a_e | model_a_TF_B_model_a_e | 7.340937e-14 | -7.340937e-14 |
model_a_TF_C_model_a_e | model_a_TF_C_model_a_e | 0.000000e+00 | 6.493724e-14 |
model_a_TF_D_model_a_e | model_a_TF_D_model_a_e | 5.000000e+02 | 5.000000e+02 |
EX_A_medium | EX_A_medium | -1.000000e+03 | -1.000000e+03 |
EX_B_medium | EX_B_medium | 0.000000e+00 | -1.312518e-13 |
EX_C_medium | EX_C_medium | 0.000000e+00 | -1.890943e-13 |
EX_D_medium | EX_D_medium | -1.000000e+03 | -1.000000e+03 |
model_a_to_community_biomass | model_a_to_community_biomass | 5.000000e+02 | 5.000000e+02 |
model_b_TF_A_model_b_e | model_b_TF_A_model_b_e | 5.000000e+02 | 5.000000e+02 |
model_b_TF_B_model_b_e | model_b_TF_B_model_b_e | 7.340937e-14 | -7.340937e-14 |
model_b_TF_C_model_b_e | model_b_TF_C_model_b_e | 0.000000e+00 | 0.000000e+00 |
model_b_TF_D_model_b_e | model_b_TF_D_model_b_e | 5.000000e+02 | 5.000000e+02 |
model_b_to_community_biomass | model_b_to_community_biomass | 5.000000e+02 | 5.000000e+02 |
community_biomass | community_biomass | 1.000000e+03 | 1.000000e+03 |
At maximum growht-rate, the reactions that are part of loops are not used, as this would lead to a decrease in growth-rate.
[13]:
%%time
com_model_obj_toy.medium = {'EX_A_medium': 1000.0, 'EX_D_medium': 1000.0}
com_model_obj_toy.apply_medium()
with com_model_obj_toy.model:
fva = com_model_obj_toy.run_fva(reactions=com_model_obj_toy.model.reactions, fraction_of_optimum=0., loopless=True)
fva
2025-02-11 16:57:21,902 - pycomo - INFO - Logger initialized.
2025-02-11 16:57:21,904 - pycomo - INFO - Process Pool Logger initialized.
2025-02-11 16:57:21,904 - pycomo - INFO - Utils Logger initialized.
2025-02-11 16:57:21,909 - pycomo - INFO - Multiprocess Logger initialized.
2025-02-11 16:57:21,986 - pycomo - INFO - Processed 33.33% of find loops steps
2025-02-11 16:57:22,080 - pycomo - INFO - Processed 66.67% of find loops steps
2025-02-11 16:57:22,116 - pycomo - INFO - Processed 100.0% of find loops steps
2025-02-11 16:57:24,218 - pycomo - INFO - Logger initialized.
2025-02-11 16:57:24,220 - pycomo - INFO - Process Pool Logger initialized.
2025-02-11 16:57:24,221 - pycomo - INFO - Utils Logger initialized.
2025-02-11 16:57:24,225 - pycomo - INFO - Logger initialized.
2025-02-11 16:57:24,225 - pycomo - INFO - Multiprocess Logger initialized.
2025-02-11 16:57:24,226 - pycomo - INFO - Process Pool Logger initialized.
2025-02-11 16:57:24,226 - pycomo - INFO - Utils Logger initialized.
2025-02-11 16:57:24,229 - pycomo - INFO - Multiprocess Logger initialized.
2025-02-11 16:57:24,297 - pycomo - INFO - Log level set to 20
2025-02-11 16:57:24,304 - pycomo - INFO - Log level set to 20
2025-02-11 16:57:24,306 - pycomo - INFO - Loop correction will be applied on model_a_TF_B_model_a_e
2025-02-11 16:57:24,319 - pycomo - INFO - Loop correction will be applied on model_a_TF_C_model_a_e
2025-02-11 16:57:24,367 - pycomo - INFO - Loop correction will be applied on model_b_TF_B_model_b_e
2025-02-11 16:57:24,369 - pycomo - INFO - Processed 66.67% of fva steps
2025-02-11 16:57:24,369 - pycomo - INFO - Loop correction will be applied on model_b_TF_C_model_b_e
2025-02-11 16:57:24,370 - pycomo - INFO - Logger initialized.
2025-02-11 16:57:24,371 - pycomo - INFO - Process Pool Logger initialized.
2025-02-11 16:57:24,372 - pycomo - INFO - Utils Logger initialized.
2025-02-11 16:57:24,376 - pycomo - INFO - Multiprocess Logger initialized.
2025-02-11 16:57:24,384 - pycomo - INFO - Logger initialized.
2025-02-11 16:57:24,385 - pycomo - INFO - Process Pool Logger initialized.
2025-02-11 16:57:24,385 - pycomo - INFO - Utils Logger initialized.
2025-02-11 16:57:24,389 - pycomo - INFO - Multiprocess Logger initialized.
2025-02-11 16:57:24,399 - pycomo - INFO - Processed 100.0% of fva steps
CPU times: user 193 ms, sys: 30.3 ms, total: 224 ms
Wall time: 4.71 s
[13]:
reaction_id | min_flux | max_flux | |
---|---|---|---|
model_a_TF_A_model_a_e | model_a_TF_A_model_a_e | -6.493724e-14 | 500.0 |
model_a_TF_B_model_a_e | model_a_TF_B_model_a_e | -2.500000e+02 | 250.0 |
model_a_TF_C_model_a_e | model_a_TF_C_model_a_e | -2.500000e+02 | 250.0 |
model_a_TF_D_model_a_e | model_a_TF_D_model_a_e | 0.000000e+00 | 500.0 |
EX_A_medium | EX_A_medium | -1.000000e+03 | 0.0 |
EX_B_medium | EX_B_medium | 0.000000e+00 | 500.0 |
EX_C_medium | EX_C_medium | 0.000000e+00 | 500.0 |
EX_D_medium | EX_D_medium | -1.000000e+03 | 0.0 |
model_a_to_community_biomass | model_a_to_community_biomass | 0.000000e+00 | 500.0 |
model_b_TF_A_model_b_e | model_b_TF_A_model_b_e | -2.892122e-14 | 500.0 |
model_b_TF_B_model_b_e | model_b_TF_B_model_b_e | -2.500000e+02 | 250.0 |
model_b_TF_C_model_b_e | model_b_TF_C_model_b_e | -2.500000e+02 | 250.0 |
model_b_TF_D_model_b_e | model_b_TF_D_model_b_e | 0.000000e+00 | 500.0 |
model_b_to_community_biomass | model_b_to_community_biomass | 0.000000e+00 | 500.0 |
community_biomass | community_biomass | 0.000000e+00 | 1000.0 |
However, there are valid flux configurations where the “loopy” reactions can carry flux, with both directions being viable without the use of loops.
[14]:
%%time
com_model_obj_toy.medium = {'EX_A_medium': 1000.0, 'EX_D_medium': 1000.0}
com_model_obj_toy.apply_medium()
with com_model_obj_toy.model:
fva = com_model_obj_toy.run_fva(reactions=com_model_obj_toy.model.reactions, fraction_of_optimum=0.8, loopless=True)
fva
2025-02-11 16:57:26,371 - pycomo - INFO - Logger initialized.
2025-02-11 16:57:26,373 - pycomo - INFO - Process Pool Logger initialized.
2025-02-11 16:57:26,373 - pycomo - INFO - Utils Logger initialized.
2025-02-11 16:57:26,377 - pycomo - INFO - Multiprocess Logger initialized.
2025-02-11 16:57:26,494 - pycomo - INFO - Processed 33.33% of find loops steps
2025-02-11 16:57:26,521 - pycomo - INFO - Processed 66.67% of find loops steps
2025-02-11 16:57:26,558 - pycomo - INFO - Processed 100.0% of find loops steps
2025-02-11 16:57:28,464 - pycomo - INFO - Logger initialized.
2025-02-11 16:57:28,465 - pycomo - INFO - Process Pool Logger initialized.
2025-02-11 16:57:28,465 - pycomo - INFO - Utils Logger initialized.
2025-02-11 16:57:28,467 - pycomo - INFO - Multiprocess Logger initialized.
2025-02-11 16:57:28,505 - pycomo - INFO - Log level set to 20
2025-02-11 16:57:28,508 - pycomo - INFO - Loop correction will be applied on model_a_TF_B_model_a_e
2025-02-11 16:57:28,524 - pycomo - INFO - Loop correction will be applied on model_a_TF_C_model_a_e
2025-02-11 16:57:28,614 - pycomo - INFO - Processed 66.67% of fva steps
2025-02-11 16:57:28,614 - pycomo - INFO - Loop correction will be applied on model_b_TF_B_model_b_e
2025-02-11 16:57:28,627 - pycomo - INFO - Loop correction will be applied on model_b_TF_C_model_b_e
2025-02-11 16:57:28,674 - pycomo - INFO - Processed 100.0% of fva steps
CPU times: user 177 ms, sys: 12.9 ms, total: 189 ms
Wall time: 4.26 s
[14]:
reaction_id | min_flux | max_flux | |
---|---|---|---|
model_a_TF_A_model_a_e | model_a_TF_A_model_a_e | 300.0 | 500.0 |
model_a_TF_B_model_a_e | model_a_TF_B_model_a_e | -200.0 | 200.0 |
model_a_TF_C_model_a_e | model_a_TF_C_model_a_e | -100.0 | 100.0 |
model_a_TF_D_model_a_e | model_a_TF_D_model_a_e | 400.0 | 500.0 |
EX_A_medium | EX_A_medium | -1000.0 | -800.0 |
EX_B_medium | EX_B_medium | 0.0 | 200.0 |
EX_C_medium | EX_C_medium | 0.0 | 200.0 |
EX_D_medium | EX_D_medium | -1000.0 | -800.0 |
model_a_to_community_biomass | model_a_to_community_biomass | 400.0 | 500.0 |
model_b_TF_A_model_b_e | model_b_TF_A_model_b_e | 300.0 | 500.0 |
model_b_TF_B_model_b_e | model_b_TF_B_model_b_e | -200.0 | 200.0 |
model_b_TF_C_model_b_e | model_b_TF_C_model_b_e | -100.0 | 100.0 |
model_b_TF_D_model_b_e | model_b_TF_D_model_b_e | 400.0 | 500.0 |
model_b_to_community_biomass | model_b_to_community_biomass | 400.0 | 500.0 |
community_biomass | community_biomass | 800.0 | 1000.0 |
The example of 80% of maximum growth-rate shows, that the loopless solution scales down the flux of the “loopy” reactions, to the level where they can be active without decreasing the maximum growth-rate below the 80% threshold.
[15]:
%%time
com_model_obj_toy.medium = {'EX_A_medium': 1000.0, 'EX_D_medium': 1000.0}
com_model_obj_toy.apply_medium()
with com_model_obj_toy.model:
fva = com_model_obj_toy.run_fva(reactions=com_model_obj_toy.model.reactions, composition_agnostic=True, fraction_of_optimum=0., loopless=True, processes=1)
fva
2025-02-11 16:57:28,801 - pycomo - INFO - Processed 33.33% of find loops steps
2025-02-11 16:57:28,817 - pycomo - INFO - Processed 66.67% of find loops steps
2025-02-11 16:57:28,831 - pycomo - INFO - Processed 100.0% of find loops steps
2025-02-11 16:57:28,842 - pycomo - INFO - Log level set to 20
2025-02-11 16:57:28,845 - pycomo - INFO - Loop correction will be applied on model_a_TF_B_model_a_e
2025-02-11 16:57:28,853 - pycomo - INFO - Loop correction will be applied on model_a_TF_C_model_a_e
2025-02-11 16:57:28,877 - pycomo - INFO - Processed 66.67% of fva steps
2025-02-11 16:57:28,877 - pycomo - INFO - Loop correction will be applied on model_b_TF_B_model_b_e
2025-02-11 16:57:28,886 - pycomo - INFO - Loop correction will be applied on model_b_TF_C_model_b_e
2025-02-11 16:57:28,900 - pycomo - INFO - Processed 100.0% of fva steps
CPU times: user 196 ms, sys: 4.24 ms, total: 200 ms
Wall time: 198 ms
[15]:
reaction_id | min_flux | max_flux | |
---|---|---|---|
model_a_TF_A_model_a_e | model_a_TF_A_model_a_e | 0.000000e+00 | 1.000000e+03 |
model_a_TF_B_model_a_e | model_a_TF_B_model_a_e | -5.000000e+02 | 3.333333e+02 |
model_a_TF_C_model_a_e | model_a_TF_C_model_a_e | -5.000000e+02 | 3.333333e+02 |
model_a_TF_D_model_a_e | model_a_TF_D_model_a_e | -1.298745e-13 | 1.000000e+03 |
EX_A_medium | EX_A_medium | -1.000000e+03 | 1.136868e-13 |
EX_B_medium | EX_B_medium | 0.000000e+00 | 5.000000e+02 |
EX_C_medium | EX_C_medium | 0.000000e+00 | 5.000000e+02 |
EX_D_medium | EX_D_medium | -1.000000e+03 | 0.000000e+00 |
model_a_to_community_biomass | model_a_to_community_biomass | 0.000000e+00 | 1.000000e+03 |
model_b_TF_A_model_b_e | model_b_TF_A_model_b_e | 0.000000e+00 | 1.000000e+03 |
model_b_TF_B_model_b_e | model_b_TF_B_model_b_e | -5.000000e+02 | 3.333333e+02 |
model_b_TF_C_model_b_e | model_b_TF_C_model_b_e | -5.000000e+02 | 3.333333e+02 |
model_b_TF_D_model_b_e | model_b_TF_D_model_b_e | 3.621417e-14 | 1.000000e+03 |
model_b_to_community_biomass | model_b_to_community_biomass | 0.000000e+00 | 1.000000e+03 |
community_biomass | community_biomass | 0.000000e+00 | 1.000000e+03 |
Using the composition agnostic approach to find all potential cross-feeding interactions shows the same pattern of feasible flux directions as with 0% fraction of optimum FVA, but with higher flux ranges due to the relaxed constraints.
This demonstrates that no other flux directions are feasible, even when considering all abundance profiles and not just 50/50 for model a and model b.