Unverified Commit fa315426 authored by Miroslav Kratochvil's avatar Miroslav Kratochvil
Browse files

[skip ci] tutorial4 fixes

parent 828ef896
......@@ -2,14 +2,15 @@
# Modifying and saving the models
Making a small modification to the model and reanalyzing them is often a useful
way to explore how the constrains work together and what is the modification
way to explore how the constraints work together, and to inspect the degrees of
freedom in the model.
With `COBREXA.jl`, you have 2 main choices of making such modifications:
- you can manually change the model structures
- many analysis functions accept special arguments that make the modifications
in a declarative way and "on the fly", without requiring to manually interact
with the model.
With `COBREXA.jl`, you have two main choices of making model modifications:
- you can manually change the model structures (i.e. permanently change the
data in of your `model` variable)
- you can use special arguments of analysis functions that allow you to make
the modifications in a declarative way and "on the fly", without having to
manually interact with the model
!!! tip "Notebook available"
The available notebooks demonstrate
......@@ -22,7 +23,7 @@ With `COBREXA.jl`, you have 2 main choices of making such modifications:
## Manual modifications
Certain model types, including [`CoreModel`](@ref) and [`StandardModel`](@ref),
are composed of mutable structures that you are free to modify as you want.
are built from mutable `structs` that you are free to modify as you want.
[`CoreModel`](@ref) consists of sparse matrices and vectors that describe the
model precisely. For example, modifying a bound of the reaction is as simple as
......@@ -48,7 +49,7 @@ the model, e.g. using
indexin(["M_nadh_c", "M_co2_e"], metabolites(m))
```
...which will return the numeric indexes of NADH and CO₂ metabolites. These can
be used e.g. to change the "balance" of the metabolites in the model:
be used to, e.g., change the "balance" of the metabolites in the model:
```
m.b[64] = -1 # model will be losing 1 flux unit of CO₂
```
......@@ -58,15 +59,16 @@ m.S[5,8] = -1
m.S[5,64] = 1
```
While this works well if you are used to work with matrix-like representations
of the model, it is not really convenient if you want to change the reactions
and models in an easy way. [`StandardModel`](@ref) is structured in a much more
"object-oriented" way that makes the manual modifications easiler.
While this works well if you are used to working with matrix-like
representations of the model, it is not really convenient if you want to change
the reactions and models in an easy way. [`StandardModel`](@ref) is structured
in a much more user-friendly way, which makes the manual modifications easier.
In particular, [`StandardModel`](@ref) consists of dictionaries of
[`Reaction`](@ref), [`Metabolite`](@ref) and [`Gene`](@ref) objects that may be
modified and indexed directly using their names. That way, the above
modifications may be done much more semantically, as follows:
modifications may be written in a cleaner, semantic and declarative fashion, as
follows:
```
m = load_model(StandardModel, "e_coli_core.xml")
......@@ -76,15 +78,6 @@ m.reactions["R_GLNS"].metabolites["M_co2_e"] = 1.0
...
```
Finally, let's see the difference that the (biologically irrelevant) change has
done to the optimal flux of the model:
```
flux_balance_analysis_vec(m, GLPK.Optimizer) -
flux_balance_analysis_vec(
load_model(StandardModel, "e_coli_core.xml"), GLPK.Optimizer)
```
There are other functions that may be used to change the StandardModel in a
more systematic way. See the documentation of [`add!`](@ref), [`rm!`](@ref),
[`add_reaction!`](@ref), and [`set_bound`](@ref) for examples.
......@@ -98,14 +91,15 @@ model before modification.
These include e.g.:
- [`change_objective`](@ref) that sets a new optimization objective
- [`change_optimizer`](@ref) and [`change_optimizer_attribute`](@ref) that can
be used to use a different `JuMP.jl` optimizer and set its parameters within
- [`change_optimizer`](@ref) that chooses a different `JuMP.jl` optimizer for
the analysis
- [`change_constraint`](@ref) to change the flux bounds of a reaction
- [`knockout`](@ref) to disable reactions that depend on genes
- [`change_optimizer_attribute`](@ref) that can set various optimizer
parameters
- [`change_constraint`](@ref) that changes the flux bounds of a reaction
- [`knockout`](@ref) that disables reactions that depend on genes
This way, you can easily check out the model state when maximizing the rate of
"TALA" reaction:
"TALA" (transadenolase A) reaction:
```
m = load_model(StandardModel, "e_coli_core.xml")
......@@ -114,16 +108,16 @@ flux_balance_analysis_dict(
modifications=[change_objective("R_TALA")])
```
...or try knocking out a gene combination that disables the "TALA" reaction
(see `m.reactions["R_TALA"].grr`):
...or knock out a gene combination that disables the transadenolase A
completely (see `m.reactions["R_TALA"].grr`):
```
flux_balance_analysis_dict(
m, GLPK.Optimizer;
modifications=[knockout(["G_b0008", "G_b2464"])])
```
...or do both at once; knock out some other genes and try maximizing the
reaction rate:
...or do both at once-- knock out some other genes, and try to maximize the
transadenolase A reaction rate:
```
flux_balance_analysis_dict(
m, GLPK.Optimizer;
......@@ -146,22 +140,24 @@ save_model(m, "myModel.json")
save_model(m, "myModel.mat")
```
The function automatically guesses the appropriate model type to write into the
file from extension; if required, you can choose the type of saved data
The function automatically guesses the appropriate model format to write into
the file from the file extension. If required, you can choose the model format
manually by using [`save_json_model`](@ref) and [`save_mat_model`](@ref).
## Using `Serialization` for quick&efficient model storage
## Using `Serialization` for quick & efficient model storage
If you save the model just "for yourself", for example just for the use in
later analysis, it may be inconvenient (and unnecessarily inefficient) to
encode and decode the models into&from the external format. Moreover, certain
model types (such as [`CoreModelCoupled`](@ref)) cannot be fully represented
in all model formats, thus increasing the chance for accidental data loss.
If you save the model "just for yourself", such as for the use in an
immediately following analysis, it may be inconvenient (and unnecessarily
inefficient) to encode and decode the models to and from the external format.
Moreover, certain model types (such as [`CoreModelCoupled`](@ref)) cannot be
fully represented in all model formats, thus increasing the chance for
accidental data loss.
Instead of that, we recommend `Serialization` package that provides a
straightforward way to write out _any_ Julia data structure to the disk, using
a very efficient data format that can be written and read very quickly.
Instead of that, we recommend using the `Serialization` package. It provides a
straightforward way to save _any_ Julia data structure to the disk, using a
very efficient data format that can be written to and read from the disk very
quickly.
With any model in `m`, you can write it to disk as follows:
```
......@@ -177,12 +173,12 @@ One great advantage of `Serialization` is speed -- models with millions of
reactions are usually loaded and saved with minimal overhead in less than a
second.
!!! note "Limits of `Serialization`"
!!! warning "Limits of `Serialization`"
Serialized models are great for quickly exchanging data objects between
analysis steps. The avoided need for re-encoding can save you a great deal
of analysis time that can be used for better purposes. Despite of that, do
not rely on the stability of the serialized format -- it often changes
between Julia versions, and the data stored in one version may not open
easily after an upgrade. In short, use serialized data within one workflow,
and use standard and stable external formats for publishing and storing the
of analysis time that can be used for better purposes. Despite that, do not
rely on the stability of the serialized format -- it often changes between
Julia versions, and the data stored in one version may not open easily
after an upgrade. In short, use serialized data within one workflow, and
use standard and stable external formats for publishing and storing the
data beyond the scope of a single analysis workflow.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment