Animating Simulations with Escher

This example shows how simulation results can be displayed on an escher map. Using the reactive options of Escher, the results of a simulation can also be animated.

For this particular example, a simple toy model is used.

[1]:
from os import path
from time import sleep

from matplotlib.cm import get_cmap
import numpy as np

import escher

from mass import MassConfiguration, Simulation
from mass.example_data import create_example_model, MAPS_DIR


mass_config = MassConfiguration()
mass_config.decimal_precision = 8
# Turns off the warning message when leaving or refreshing this page.
escher.rc['never_ask_before_quit'] = True

Load Model and Map

[2]:
model = create_example_model("Simple_Toy")

# Set the path to the map file
map_filepath = path.join(MAPS_DIR, "simple_toy_map.json")
Set parameter Username

Make color scales

Metabolites

[3]:
num_scales = 6
min_value, max_value = (0, 1)
min_size, max_size = (10, 30)
colors = 255 * get_cmap("bwr", num_scales)(np.linspace(0, 1, num_scales))
colors = np.flip(colors, axis=0)

metabolite_data_scale = []
for i in range(num_scales):
    scale_stop = {}
    scale_stop["type"] = "value"
    if i == 0:
        scale_stop["value"] = min_value
        scale_stop["size"] = min_size
    elif i == num_scales - 1:
        scale_stop["value"] = max_value
        scale_stop["size"] = max_size
    else:
        scale_stop["value"] = i*(max_value - min_value)/(num_scales - 1)
        scale_stop["size"] = min_size + i * (max_size - min_size)/(num_scales - 1)
    scale_stop["color"] = "rgb({0}, {1}, {2})".format(*colors[i])
    metabolite_data_scale.append(scale_stop)

Reactions

[4]:
stops = ["min", "Q1", "median", "Q3", "max"]
num_scales = len(stops)
min_value, max_value = (0, 1)
min_size, max_size = (10, 30)
colors = 255 * get_cmap("Purples", num_scales)(np.linspace(0, 1, num_scales))

reaction_data_scale = []
for i, stop_type in enumerate(stops):
    scale_stop = {}
    scale_stop["type"] = stop_type
    scale_stop["color"] = "rgb({0}, {1}, {2})".format(*colors[i])
    scale_stop["size"] = min_size + i * (max_size - min_size)/(num_scales - 1)
    reaction_data_scale.append(scale_stop)
reaction_data_scale.append(
    {"type": "value", "value": 0, "color": "grey", "size": 8})

Animate Simulation

Simulate model

[5]:
sim = Simulation(model, verbose=True)
conc_sol, flux_sol = sim.simulate(model, time=(0, 1e6),
                                  decimal_precision=True)
WARNING: No compartments found in model. Therefore creating compartment 'compartment' for entire model.
Successfully loaded MassModel 'Simple_Toy' into RoadRunner.

Render map

[6]:
escher_builder = escher.Builder(
    model=model,
    map_json=map_filepath,
    reaction_scale=tuple(reaction_data_scale),
    metabolite_scale=tuple(metabolite_data_scale)
)
escher_builder

Animate results

[8]:
for i in range(len(conc_sol.time)):
    # Map metabolite data onto map per solution point
    escher_builder.metabolite_data = {
        met: solution[i] for met, solution in conc_sol.items()}
    # Map reaction data onto map per solution point
    escher_builder.reaction_data = {
        rxn: solution[i] for rxn, solution in flux_sol.items()}
    sleep(0.05)

The video of the created animation:

[9]:
from IPython.display import Video
Video("../../media/videos/escher_toy_animation.mp4", embed=True, width=500)
[9]: