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]: