Tutorial: Remote Simulations¶
This tutorial walks through authenticating with the VCell server, saving a model, starting a simulation, monitoring progress, and exporting results.
Note: This notebook requires a VCell account and access to the VCell server. It cannot be run in CI.
See also the Remote Simulations reference guide.
Authenticate¶
In [ ]:
Copied!
import pyvcell.vcml as vc
session = vc.connect(login=True)
import pyvcell.vcml as vc
session = vc.connect(login=True)
Build a model locally¶
In [ ]:
Copied!
antimony_str = """
compartment ec = 1;
compartment cell = 2;
compartment pm = 1;
species A in cell;
species B in cell;
J0: A -> B; cell * (k1*A - k2*B)
J0 in cell;
k1 = 5.0; k2 = 2.0
A = 10
"""
biomodel = vc.load_antimony_str(antimony_str)
model = biomodel.model
model.get_compartment("pm").dim = 2
geo = vc.Geometry(name="geo", origin=(0, 0, 0), extent=(10, 10, 10), dim=3)
geo.add_sphere(name="cell_domain", radius=4, center=(5, 5, 5))
geo.add_background(name="ec_domain")
geo.add_surface(name="pm_domain", sub_volume_1="cell_domain", sub_volume_2="ec_domain")
app = biomodel.add_application("app1", geometry=geo)
app.map_compartment("cell", "cell_domain")
app.map_compartment("ec", "ec_domain")
app.map_species("A", init_conc="3+sin(x)", diff_coef=1.0)
app.map_species("B", init_conc="2+cos(x+y+z)", diff_coef=1.0)
sim = app.add_sim(name="sim1", duration=0.5, output_time_step=0.1, mesh_size=(20, 20, 20))
antimony_str = """
compartment ec = 1;
compartment cell = 2;
compartment pm = 1;
species A in cell;
species B in cell;
J0: A -> B; cell * (k1*A - k2*B)
J0 in cell;
k1 = 5.0; k2 = 2.0
A = 10
"""
biomodel = vc.load_antimony_str(antimony_str)
model = biomodel.model
model.get_compartment("pm").dim = 2
geo = vc.Geometry(name="geo", origin=(0, 0, 0), extent=(10, 10, 10), dim=3)
geo.add_sphere(name="cell_domain", radius=4, center=(5, 5, 5))
geo.add_background(name="ec_domain")
geo.add_surface(name="pm_domain", sub_volume_1="cell_domain", sub_volume_2="ec_domain")
app = biomodel.add_application("app1", geometry=geo)
app.map_compartment("cell", "cell_domain")
app.map_compartment("ec", "ec_domain")
app.map_species("A", init_conc="3+sin(x)", diff_coef=1.0)
app.map_species("B", init_conc="2+cos(x+y+z)", diff_coef=1.0)
sim = app.add_sim(name="sim1", duration=0.5, output_time_step=0.1, mesh_size=(20, 20, 20))
Run remotely (blocking)¶
The simplest approach — save, run, wait, and export in one call:
In [ ]:
Copied!
from datetime import datetime
model_name = f"MyRemoteModel_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
store = session.run_sim(biomodel, "sim1", model_name=model_name, on_progress=print)
print(f"Shape: {store.shape}, Dtype: {store.dtype}")
# Shape is (X, Y, Variables, Z, Time)
from datetime import datetime
model_name = f"MyRemoteModel_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
store = session.run_sim(biomodel, "sim1", model_name=model_name, on_progress=print)
print(f"Shape: {store.shape}, Dtype: {store.dtype}")
# Shape is (X, Y, Variables, Z, Time)
Run remotely (non-blocking)¶
For more control, use start_sim() to get a SimulationJob:
In [ ]:
Copied!
model_name = f"MyRemoteModel_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
job = session.start_sim(biomodel, "sim1", model_name=model_name, on_progress=print)
print(f"Simulation started, status: {job.status}")
model_name = f"MyRemoteModel_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
job = session.start_sim(biomodel, "sim1", model_name=model_name, on_progress=print)
print(f"Simulation started, status: {job.status}")
Wait for completion and export results:
In [ ]:
Copied!
# Block until done, then export
store = job.result()
print(f"Shape: {store.shape}, Dtype: {store.dtype}")
# Read a slice — e.g. variable A, all X/Y, first z-slice, first timepoint
slice_data = store[:, :, 0, 0, 0].read().result()
print(f"Slice shape: {slice_data.shape}")
# Block until done, then export
store = job.result()
print(f"Shape: {store.shape}, Dtype: {store.dtype}")
# Read a slice — e.g. variable A, all X/Y, first z-slice, first timepoint
slice_data = store[:, :, 0, 0, 0].read().result()
print(f"Slice shape: {slice_data.shape}")