COBREXA can load models stored in .mat, .json, and .xml formats (with the latter denoting SBML formatted models).

We will primarily use the E. coli "core" model to demonstrate the utilities found in COBREXA. First, let's download the model in several formats.

# Downloads the model files if they don't already exist
!isfile("e_coli_core.mat") &&
!isfile("e_coli_core.json") &&
!isfile("e_coli_core.xml") &&
download("http://bigg.ucsd.edu/static/models/e_coli_core.xml", "e_coli_core.xml");
Save bandwidth!

The published models usually do not change very often. It is therefore pretty useful to save them to a central location and load them from there. That saves your time, and does not unnecessarily consume the connectivity resources of the model repository.

Load the models using the load_model function. Models are able to "pretty-print" themselves, hiding the inner complexity:

using COBREXA

mat_model = load_model("e_coli_core.mat")
Metabolic model of type MATModel
sparse([9, 51, 55, 64, 65, 34, 44, 59, 66, 64  …  20, 22, 23, 25, 16, 17, 34, 44, 57, 59], [1, 1, 1, 1, 1, 2, 2, 2, 2, 3  …  93, 93, 94, 94, 95, 95, 95, 95, 95, 95], [1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0  …  1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0], 72, 95)
Number of reactions: 95
Number of metabolites: 72

json_model = load_model("e_coli_core.json")
Metabolic model of type JSONModel
sparse([9, 51, 55, 64, 65, 34, 44, 59, 66, 64  …  20, 22, 23, 25, 16, 17, 34, 44, 57, 59], [1, 1, 1, 1, 1, 2, 2, 2, 2, 3  …  93, 93, 94, 94, 95, 95, 95, 95, 95, 95], [1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0  …  1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0], 72, 95)
Number of reactions: 95
Number of metabolites: 72

sbml_model = load_model("e_coli_core.xml")
Metabolic model of type SBMLModel
sparse([8, 10, 21, 43, 50, 51, 8, 9, 6, 12  …  33, 66, 68, 72, 23, 26, 33, 72, 22, 33], [1, 1, 1, 1, 1, 1, 2, 2, 3, 3  …  93, 93, 93, 93, 94, 94, 94, 94, 95, 95], [-1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0  …  1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0], 72, 95)
Number of reactions: 95
Number of metabolites: 72

Note: load_model infers the input type from the file extension

Notice how each model was read into memory as a model type corresponding to its file type, i.e. the file ending with .json loaded as a JSONModel, the file ending with .mat loaded as MATModel, and the file ending with .xml loaded as an SBMLModel.

The loaded models contain the data in a format that is preferably as compatible as possible with the original representation. In particular, the JSON model contains the representation of the JSON tree:

json_model.json
Dict{String, Any} with 6 entries:
"metabolites"  => Any[Dict{String, Any}("compartment"=>"e", "name"=>"D-Glucos…
"id"           => "e_coli_core"
"compartments" => Dict{String, Any}("c"=>"cytosol", "e"=>"extracellular space…
"reactions"    => Any[Dict{String, Any}("name"=>"Phosphofructokinase", "metab…
"version"      => "1"
"genes"        => Any[Dict{String, Any}("name"=>"adhE", "id"=>"b1241", "notes…

SBML models contain a complicated structure from SBML.jl package:

typeof(sbml_model.sbml)
SBML.Model

MAT models contain MATLAB data:

mat_model.mat
Dict{String, Any} with 17 entries:
"description" => "e_coli_core"
"c"           => [0.0; 0.0; … ; 0.0; 0.0;;]
"rev"         => [0; 0; … ; 1; 0;;]
"mets"        => Any["glc__D_e"; "gln__L_c"; … ; "g3p_c"; "g6p_c";;]
"grRules"     => Any["b3916 or b1723"; "((b0902 and b0903) and b2579) or (b09…
"subSystems"  => Any["Glycolysis/Gluconeogenesis"; "Pyruvate Metabolism"; … ;…
"b"           => [0.0; 0.0; … ; 0.0; 0.0;;]
"metFormulas" => Any["C6H12O6"; "C5H10N2O3"; … ; "C3H5O6P"; "C6H11O9P";;]
"rxnGeneMat"  => sparse([6, 10, 6, 11, 27, 82, 93, 94, 12, 12  …  37, 38, 38,…
"S"           => [0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0; … ; 0.0 0.0 … 0.0 0.0…
"metNames"    => Any["D-Glucose"; "L-Glutamine"; … ; "Glyceraldehyde 3-phosph…
"lb"          => [0.0; 0.0; … ; -1000.0; 0.0;;]
"metCharge"   => [0.0; 0.0; … ; -2.0; -2.0;;]
"ub"          => [1000.0; 1000.0; … ; 1000.0; 1000.0;;]
"rxnNames"    => Any["Phosphofructokinase"; "Pyruvate formate lyase"; … ; "O2…
"rxns"        => Any["PFK"; "PFL"; … ; "O2t"; "PDH";;]
"genes"       => Any["b1241"; "b0351"; … ; "b2935"; "b3919";;]

In all cases, you can access the data in the model in the same way, e.g., using reactions to get a list of the reactions in the models:

reactions(mat_model)[1:5]
5-element Vector{String}:
"PFK"
"PFL"
"PGI"
"PGK"
"PGL"
reactions(json_model)[1:5]
5-element Vector{String}:
"PFK"
"PFL"
"PGI"
"PGK"
"PGL"

You can use the generic accessors to gather more information about the model contents, convert the models into formats more suitable for hands-on processing, and export them back to disk after the modification.

All model types can be directly used in analysis functions, such as flux_balance_analysis.