Skip to content

Building a Model with QSPy

This guide walks through encoding a model directly in Python using QSPy’s core modules. For this purpose, we will build a relatively simple two-compartment semi-mechanistic pharmacokinetics & receptor-occupancy (PKRO) model. Typically, models are defined in their own Python module file: e.g., pkro_model.py.

1) Import essential modules/objects

from qspy import *

2) Create and instance of the Model class and specify global model units.

Model().with_units(concentration="mg/L", time="h", volume="L")

3) Specify model parameters

with parameters():
    # drug dose
    drug_dose = (100.0, "mg")
    # Compartment volumes
    V_CENTRAL = (10.0, "L")
    V_PERIPHERAL = (1.0, "L")
    # drug distribution rate constants
    k_CP = (1e-1, "1/s")
    k_PC = (1e-3, "1/s")
    # receptor density
    receptor_0 = (100.0, "ug/L")
    # receptor binding rate constants
    k_f = (1.0, "L/(ug * s)")
    k_r = (1e-3, "1/s")

4) Define any expressions

with expressions():
    # Initial drug concentration - bolus dose
    drug_0 = drug_dose / V_CENTRAL

5) Specify the model compartments

with compartments():
    CENTRAL = V_CENTRAL
    PERIPHERAL = V_PERIPHERAL

6) Define any monomer species

with monomers():
    drug = (['b'], None, DRUG.AGONIST)
    receptor = (['b'], None, PROTEIN.RECEPTOR)

7) Specify initial conditions

with initials():
    drug(b=None)**CENTRAL << drug_0
    receptor(b=None)**PERIPHERAL << receptor_0

8) Define reaction rules

with rules():
    # Distribution
    drug_distribution = (drug(b=None)**CENTRAL | drug(b=None)**PERIPHERAL, k_CP, k_PC)
    # Receptor binding
    receptor_binding = (drug(b=None)**PERIPHERAL + receptor(b=None)**PERIPHERAL | drug(b=1)**PERIPHERAL % receptor(b=1)**PERIPHERAL, k_f, k_r)

9) Assign observables

with observables():
    drug(b=1)**PERIPHERAL % receptor(b=1)**PERIPHERAL > "OccupiedReceptor"

10) Assign model metadata and tracker (optional)

__version__ = 0.1.0
__author__ = "Jane Doe"
ModelMetadataTracker(__version__, author=__author__)

Info

Learn more about the metadata tracker

11) Initialize model checker (optional)

ModelChecker()

Info

Learn more about the model checker

12) Include a mermaid diagram generator (optional)

ModelMermaidDiagrammer()

Info

Learn more about the diagram generator


Full example model

pkro_model.py

from qspy import *

with parameters():
    # drug dose
    drug_dose = (100.0, "mg")
    # Compartment volumes
    V_CENTRAL = (10.0, "L")
    V_PERIPHERAL = (1.0, "L")
    # drug distribution rate constants
    k_CP = (1e-1, "1/s")
    k_PC = (1e-3, "1/s")
    # receptor density
    receptor_0 = (100.0, "ug/L")
    # receptor binding rate constants
    k_f = (1.0, "L/(ug * s)")
    k_r = (1e-3, "1/s")

with expressions():
    # Initial drug concentration - bolus dose
    drug_0 = drug_dose / V_CENTRAL

with compartments():
    CENTRAL = V_CENTRAL
    PERIPHERAL = V_PERIPHERAL

with monomers():
    drug = (['b'], None, DRUG.AGONIST)
    receptor = (['b'], None, PROTEIN.RECEPTOR)

with initials():
    drug(b=None)**CENTRAL << drug_0
    receptor(b=None)**PERIPHERAL << receptor_0

with rules():
    # Distribution
    drug_distribution = (drug(b=None)**CENTRAL | drug(b=None)**PERIPHERAL, k_CP, k_PC)
    # Receptor binding
    receptor_binding = (drug(b=None)**PERIPHERAL + receptor(b=None)**PERIPHERAL | drug(b=1)**PERIPHERAL % receptor(b=1)**PERIPHERAL, k_f, k_r)

with observables():
    drug(b=1)**PERIPHERAL % receptor(b=1)**PERIPHERAL > "OccupiedReceptor"

__version__ = 0.1.0
__author__ = "Jane Doe"
ModelMetadataTracker(__version__, author=__author__)
ModelMermaidDiagrammer()
ModelChecker()