Getting started with cameo

cameo reuses and extends model data structures defined by cobrapy (COnstraints-Based Reconstruction and Analysis tool for Python). So, in addition to following this quick start guide and other cameo tutorials, we encourage you to explore cobrapy's documentation as well.

Step 1: Load a model

Loading a model is easy. Just import the ~cameo.io.load_model function.

In [1]:
from cameo import load_model

For example, load a genome-scale metabolic reconstruction of Escherichia coli.

In [2]:
model = load_model("iJO1366")

Models, reactions, metabolites, etc., return HTML when evaluated in Jupyter notebooks and can be easily inspected.

In [3]:
model
Out[3]:
Name iJO1366
Memory address 0x01120756d8
Number of metabolites 1805
Number of reactions 2583
Objective expression -1.0*BIOMASS_Ec_iJO1366_core_53p95M_reverse_5c8b1 + 1.0*BIOMASS_Ec_iJO1366_core_53p95M
Compartments extracellular space, cytosol, periplasm

Step 2: Simulate a model

The model can be simulated by executing optimize.

In [4]:
solution = model.optimize()

A quick overview of the solution can be obtained in inspecting it.

In [5]:
solution
Out[5]:
Optimal solution with objective value 0.982
fluxes reduced_costs
12DGR120tipp 0.000000 0.000000
12DGR140tipp 0.000000 0.000000
12DGR141tipp 0.000000 0.000000
12DGR160tipp 0.000000 0.000000
12DGR161tipp 0.000000 -0.008295
... ... ...
ZN2abcpp 0.000000 -0.008295
ZN2t3pp 0.000000 -0.002074
ZN2tpp 0.000335 0.000000
ZNabcpp 0.000000 -0.008295
Zn2tex 0.000335 -0.000000

2583 rows × 2 columns

A data frame representation of the solution is accessible via solution.to_frame().

In [6]:
solution.to_frame()
Out[6]:
fluxes reduced_costs
12DGR120tipp 0.000000 0.000000e+00
12DGR140tipp 0.000000 0.000000e+00
12DGR141tipp 0.000000 0.000000e+00
12DGR160tipp 0.000000 0.000000e+00
12DGR161tipp 0.000000 -8.295308e-03
12DGR180tipp 0.000000 0.000000e+00
12DGR181tipp 0.000000 0.000000e+00
12PPDRtex 0.000000 0.000000e+00
12PPDRtpp 0.000000 0.000000e+00
12PPDStex 0.000000 0.000000e+00
12PPDStpp 0.000000 0.000000e+00
14GLUCANabcpp 0.000000 -5.551115e-17
14GLUCANtexi 0.000000 0.000000e+00
23CAMPtex 0.000000 0.000000e+00
23CCMPtex 0.000000 0.000000e+00
23CGMPtex 0.000000 0.000000e+00
23CUMPtex 0.000000 0.000000e+00
23DAPPAt2pp 0.000000 1.517883e-18
23DAPPAtex 0.000000 0.000000e+00
23PDE2pp 0.000000 0.000000e+00
23PDE4pp 0.000000 0.000000e+00
23PDE7pp 0.000000 0.000000e+00
23PDE9pp 0.000000 0.000000e+00
26DAHtex 0.000000 0.000000e+00
2AGPA120tipp 0.000000 0.000000e+00
2AGPA140tipp 0.000000 0.000000e+00
2AGPA141tipp 0.000000 0.000000e+00
2AGPA160tipp 0.000000 0.000000e+00
2AGPA161tipp 0.000000 0.000000e+00
2AGPA180tipp 0.000000 0.000000e+00
... ... ...
VALTRS 0.000000 0.000000e+00
VALabcpp 0.000000 -6.221481e-03
VALt2rpp 0.000000 0.000000e+00
VALtex 0.000000 0.000000e+00
VPAMTr 0.000000 0.000000e+00
WCOS 0.000000 0.000000e+00
X5PL3E 0.000000 0.000000e+00
XAND 0.000000 0.000000e+00
XANt2pp 0.000000 -2.073827e-03
XANtex 0.000000 0.000000e+00
XANtpp 0.000000 0.000000e+00
XMPtex 0.000000 0.000000e+00
XPPT 0.000000 0.000000e+00
XTSNH 0.000000 -8.295308e-03
XTSNt2rpp 0.000000 0.000000e+00
XTSNtex 0.000000 0.000000e+00
XYLI1 0.000000 0.000000e+00
XYLI2 0.000000 0.000000e+00
XYLK 0.000000 -1.387779e-17
XYLK2 0.000000 -1.387779e-17
XYLUt2pp 0.000000 0.000000e+00
XYLUtex 0.000000 0.000000e+00
XYLabcpp 0.000000 -6.221481e-03
XYLt2pp 0.000000 0.000000e+00
XYLtex 0.000000 0.000000e+00
ZN2abcpp 0.000000 -8.295308e-03
ZN2t3pp 0.000000 -2.073827e-03
ZN2tpp 0.000335 0.000000e+00
ZNabcpp 0.000000 -8.295308e-03
Zn2tex 0.000335 -0.000000e+00

2583 rows × 2 columns

Data frames make it very easy to process results. For example, let's take a look at reactions with flux != 0

In [7]:
solution.to_frame().query('fluxes != 0')
Out[7]:
fluxes reduced_costs
3OAR140 0.076452 0.000000e+00
3OAS140 0.076452 0.000000e+00
5DOAN 0.000221 0.000000e+00
A5PISO 0.038226 0.000000e+00
AACPS3 0.125378 -1.387779e-16
AACPS4 0.147776 -2.775558e-17
AACPS7 0.076452 -2.775558e-17
ACACT1r 0.349606 0.000000e+00
ACACT2r 0.349606 0.000000e+00
ACACT3r 0.349606 0.000000e+00
ACACT4r 0.349606 0.000000e+00
ACACT5r 0.349606 0.000000e+00
ACACT6r 0.273154 0.000000e+00
ACACT7r 0.273154 0.000000e+00
ACCOAC 0.076458 -7.090682e-17
ACGK 0.290578 0.000000e+00
ACGS 0.290578 2.927346e-17
ACHBS 0.285408 -6.938894e-18
ACLS 0.858857 0.000000e+00
ACOAD1f -0.349606 0.000000e+00
ACOAD2f -0.349606 0.000000e+00
ACOAD3f -0.349606 0.000000e+00
ACOAD4f -0.349606 0.000000e+00
ACOAD5f -0.349606 0.000000e+00
ACOAD6f -0.273154 0.000000e+00
ACOAD7f -0.125378 0.000000e+00
ACODA 0.290578 0.000000e+00
ACONTa 4.857777 0.000000e+00
ACONTb 4.857777 0.000000e+00
ACOTA -0.290578 0.000000e+00
... ... ...
TMDS 0.025705 -5.551115e-17
TMPK 0.000219 0.000000e+00
TMPPP 0.000219 0.000000e+00
TPI 7.645371 0.000000e+00
TRDR 0.243502 0.000000e+00
TRPAS2 -0.055841 0.000000e+00
TRPS3 0.055841 2.775558e-17
TYRL 0.000219 0.000000e+00
TYRTA -0.135684 0.000000e+00
U23GAAT 0.038226 0.000000e+00
UAAGDS 0.027298 0.000000e+00
UAGAAT 0.038226 0.000000e+00
UAGCVT 0.027298 0.000000e+00
UAGDP 0.092822 0.000000e+00
UAGPT3 0.027298 -5.551115e-17
UAMAGS 0.027298 0.000000e+00
UAMAS 0.027298 5.551115e-17
UAPGR 0.027298 0.000000e+00
UDCPDP 0.027298 0.000000e+00
UDCPDPS 0.000054 0.000000e+00
UGMDDS 0.027298 1.110223e-16
UHGADA 0.038226 0.000000e+00
UMPK 0.371375 0.000000e+00
UPP3MT 0.000219 1.110223e-16
UPP3S 0.000438 0.000000e+00
UPPDC1 0.000219 0.000000e+00
USHD 0.019113 0.000000e+00
VALTA -0.415702 0.000000e+00
ZN2tpp 0.000335 0.000000e+00
Zn2tex 0.000335 -0.000000e+00

436 rows × 2 columns

Step 3: Exploring a model

Objects—models, reactions, metabolites, genes—can easily be explored in the Jupyter notebook, taking advantage of tab completion. For example, place your cursor after the period in model.reactions. and press the TAB key. A dialog will appear that allows you to navigate the list of reactions encoded in the model.

In [8]:
model.reactions.PGK # delete PGK, place your cursor after the period and press the TAB key.
Out[8]:
Reaction identifierPGK
NamePhosphoglycerate kinase
Memory address 0x01129829b0
Stoichiometry

3pg_c + atp_c <=> 13dpg_c + adp_c

3-Phospho-D-glycerate + ATP C10H12N5O13P3 <=> 3-Phospho-D-glyceroyl phosphate + ADP C10H12N5O10P2

GPRb2926
Lower bound-1000.0
Upper bound1000.0

For example, you can access the E4PD (Erythrose 4-phosphate dehydrogenase) reaction in the model.

In [9]:
model.reactions.E4PD
Out[9]:
Reaction identifierE4PD
NameErythrose 4-phosphate dehydrogenase
Memory address 0x0112606160
Stoichiometry

e4p_c + h2o_c + nad_c <=> 4per_c + 2.0 h_c + nadh_c

D-Erythrose 4-phosphate + H2O H2O + Nicotinamide adenine dinucleotide <=> 4-Phospho-D-erythronate + 2.0 H+ + Nicotinamide adenine dinucleotide - reduced

GPRb2927 or b1779
Lower bound-1000.0
Upper bound1000.0

Be aware that, due to variable naming restrictions in Python, dot notation access to reactions (and other objects) might not work in some cases.

In [10]:
# model.reactions.12DGR120tipp  # uncommenting and running this cell will produce a syntax error

In those cases you need to use the model.reactions.get_by_id.

In [11]:
model.reactions.get_by_id('12DGR120tipp')
Out[11]:
Reaction identifier12DGR120tipp
Name1,2 diacylglycerol transport via flipping (periplasm to cytoplasm, n-C12:0)
Memory address 0x0112506ba8
Stoichiometry

12dgr120_p --> 12dgr120_c

1,2-Diacyl-sn-glycerol (didodecanoyl, n-C12:0) --> 1,2-Diacyl-sn-glycerol (didodecanoyl, n-C12:0)

GPR
Lower bound0.0
Upper bound1000.0

Metabolites are accessible through model.metabolites. For example, D-glucose in the cytosol compartment.

In [12]:
model.metabolites.glc__D_c
Out[12]:
Metabolite identifierglc__D_c
NameD-Glucose
Memory address 0x01120db4a8
FormulaC6H12O6
Compartmentc
In 19 reaction(s) GLCt2pp, GLCATr, TRE6PH, MLTG2, G6PP, LACZ, MLTG3, AMALT1, HEX1, XYLI2, MLTG4, GALS3, GLCabcpp, AMALT2, MLTG5, AMALT3, AMALT4, TREH, MLTG1

And it is easy to find the associated reactions

In [13]:
model.metabolites.glc__D_c.reactions
Out[13]:
frozenset({<Reaction AMALT1 at 0x11257a978>,
           <Reaction AMALT2 at 0x11257aa58>,
           <Reaction AMALT3 at 0x11257aa90>,
           <Reaction AMALT4 at 0x11257ab00>,
           <Reaction G6PP at 0x112671940>,
           <Reaction GALS3 at 0x112679630>,
           <Reaction GLCATr at 0x1126864e0>,
           <Reaction GLCabcpp at 0x11268d240>,
           <Reaction GLCt2pp at 0x11268d438>,
           <Reaction HEX1 at 0x1126bf588>,
           <Reaction LACZ at 0x1126e2940>,
           <Reaction MLTG1 at 0x1129253c8>,
           <Reaction MLTG2 at 0x112925518>,
           <Reaction MLTG3 at 0x112925550>,
           <Reaction MLTG4 at 0x1129255c0>,
           <Reaction MLTG5 at 0x112925630>,
           <Reaction TRE6PH at 0x112a0b4e0>,
           <Reaction TREH at 0x112a0b748>,
           <Reaction XYLI2 at 0x112a30940>})

A list of the genes encoded in the model can be accessed via model.genes.

In [14]:
model.genes[0:10]
Out[14]:
[<Gene b0002 at 0x103f25748>,
 <Gene b0003 at 0x1034ec2e8>,
 <Gene b0004 at 0x1034fe3c8>,
 <Gene b0007 at 0x1034fe438>,
 <Gene b0008 at 0x1034f4780>,
 <Gene b0009 at 0x1034f4c88>,
 <Gene b0019 at 0x11237cd30>,
 <Gene b0025 at 0x11237cd68>,
 <Gene b0026 at 0x11237cda0>,
 <Gene b0029 at 0x11237cdd8>]

Other additional attributes can be accessed to explore the model. For example, exchange reactions that allow certain metabolites to enter or leave the model can be accessed through model.exchanges.

In [15]:
model.exchanges[0:10]
Out[15]:
[<Reaction DM_4crsol_c at 0x1125f7160>,
 <Reaction DM_5drib_c at 0x1125f7470>,
 <Reaction DM_aacald_c at 0x1125f74a8>,
 <Reaction DM_amob_c at 0x1125f75c0>,
 <Reaction DM_mththf_c at 0x1125f75f8>,
 <Reaction DM_oxam_c at 0x1125f7630>,
 <Reaction EX_12ppd__R_e at 0x112613438>,
 <Reaction EX_12ppd__S_e at 0x112613470>,
 <Reaction EX_14glucan_e at 0x112613668>,
 <Reaction EX_15dap_e at 0x112613780>]

Or, the current medium can be accessed through model.medium.

In [16]:
model.medium
Out[16]:
{'EX_ca2_e': 1000.0,
 'EX_cbl1_e': 0.01,
 'EX_cl_e': 1000.0,
 'EX_co2_e': 1000.0,
 'EX_cobalt2_e': 1000.0,
 'EX_cu2_e': 1000.0,
 'EX_fe2_e': 1000.0,
 'EX_fe3_e': 1000.0,
 'EX_glc__D_e': 10.0,
 'EX_h2o_e': 1000.0,
 'EX_h_e': 1000.0,
 'EX_k_e': 1000.0,
 'EX_mg2_e': 1000.0,
 'EX_mn2_e': 1000.0,
 'EX_mobd_e': 1000.0,
 'EX_na1_e': 1000.0,
 'EX_nh4_e': 1000.0,
 'EX_ni2_e': 1000.0,
 'EX_o2_e': 1000.0,
 'EX_pi_e': 1000.0,
 'EX_sel_e': 1000.0,
 'EX_slnt_e': 1000.0,
 'EX_so4_e': 1000.0,
 'EX_tungs_e': 1000.0,
 'EX_zn2_e': 1000.0}

It is also possible to get a list of essential reactions ...

In [17]:
from cobra.flux_analysis import find_essential_reactions
list(find_essential_reactions(model))[0:10]
Out[17]:
[<Reaction THDPS at 0x1129fc080>,
 <Reaction UAAGDS at 0x112a1a080>,
 <Reaction PPNDH at 0x1129a60b8>,
 <Reaction CYSTL at 0x1125d40f0>,
 <Reaction E4PD at 0x112606160>,
 <Reaction KDOPP at 0x1126e2198>,
 <Reaction DHAD2 at 0x1125ea198>,
 <Reaction APRAUR at 0x1125881d0>,
 <Reaction METS at 0x11291e1d0>,
 <Reaction PAPPT3 at 0x11297c1d0>]

... and essential genes.

In [18]:
from cobra.flux_analysis import find_essential_genes
list(find_essential_genes(model))[0:10]
Out[18]:
[<Gene b1662 at 0x1123b6048>,
 <Gene b4245 at 0x112506128>,
 <Gene b3633 at 0x1123f0198>,
 <Gene b3634 at 0x1123f01d0>,
 <Gene b3639 at 0x1123f0208>,
 <Gene b4261 at 0x112506208>,
 <Gene b1415 at 0x1123ae240>,
 <Gene b4262 at 0x112506240>,
 <Gene b3642 at 0x1123f0278>,
 <Gene b1693 at 0x1123b6278>]