Skip to content

Commit

Permalink
feat: allow for multiple Myokit simulations
Browse files Browse the repository at this point in the history
Refactor the Myokit model mixin to allow multiple simulations to be run.
Each simulation has its own dosing protocols and dosing events.
  • Loading branch information
eatyourgreens committed Mar 13, 2024
1 parent f3b3ca0 commit fd817f5
Showing 1 changed file with 62 additions and 0 deletions.
62 changes: 62 additions & 0 deletions pkpdapp/pkpdapp/models/myokit_model_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#

import pkpdapp
from pkpdapp.models import Protocol
import numpy as np
from myokit.formats.mathml import MathMLExpressionWriter
from myokit.formats.sbml import SBMLParser
Expand Down Expand Up @@ -118,6 +119,57 @@ def parse_mmt_string(mmt):
def create_myokit_model(self):
return self.parse_mmt_string(self.mmt)

def create_myokit_simulations_from_dataset(
self,
dataset=None,
variables=None,
time_max=None,
outputs=None
):
override_tlag = self._get_override_tlag(variables),
if dataset is None:
subject_cohorts = []
else:
# TODO: create backend subject cohorts based on the frontend upload stepper
dataset_protocols = [
Protocol.objects.get(pk=p['protocol'])
for p in dataset.subjects.values('protocol').distinct()
if p['protocol'] is not None
]
subject_cohorts = [
dataset.subjects.filter(protocol=protocol)
for protocol in dataset_protocols
]
for cohort in subject_cohorts:
model = self.get_myokit_model()

# Convert units
variables = self._initialise_variables(model, variables)
time_max = self._convert_bound_unit("time", time_max, model)
# get tlag vars
override_tlag = self._get_override_tlag(variables)
# define a dosing protocol for each subject protocol
dosing_protocols = {}
subject_protocols = [
Protocol.objects.get(pk=p['protocol'])
for p in cohort.values('protocol').distinct()
if p['protocol'] is not None
]
for protocol in subject_protocols:
dosing_protocols[protocol.mapped_qname] = protocol
# create simulator
sim = self.create_myokit_simulator(
override_tlag=override_tlag,
model=model,
time_max=time_max,
dosing_protocols=dosing_protocols
)
# TODO: take these from simulation model
sim.set_tolerance(abs_tol=1e-06, rel_tol=1e-08)
# Simulate, logging only state variables given by `outputs`
print('##########################################')
print(self.serialize_datalog(sim.run(time_max, log=outputs), model))

def create_myokit_simulator(
self, override_tlag=None, model=None, time_max=None, dosing_protocols=None
):
Expand Down Expand Up @@ -475,6 +527,16 @@ def simulate(self, outputs=None, variables=None, time_max=None):
**variables,
}

project = self.get_project()
if project is not None:
dataset = project.datasets.first()
self.create_myokit_simulations_from_dataset(
dataset=dataset,
variables=variables,
time_max=time_max,
outputs=outputs
)

model = self.get_myokit_model()
# Convert units
variables = self._initialise_variables(model, variables)
Expand Down

0 comments on commit fd817f5

Please sign in to comment.