Skip to content

Activities

When dealing with complex biological systems, and biomedical research, it is common that you have complex time-dependent inputs to the system. This might include e.g. stepwise increases of a dosing, or using multiple doses at multiple time points. Traditionally, you would have to run multiple short simulations, manually setting the values of these inputs at all of the timepoints where the inputs change. This is still possible with this toolbox, but a better way is to define these inputs using an activity object.

Defining the model inputs

In short, the models can have predefined inputs by specifying this in the INPUTS header.

For example, assume that the the model needs two inputs ins and epi that vary over time from an external source:

graph LR
    %% Add text above the boxes

    subgraph "External variables"
        shared_ins["ins"]
        shared_epi["epi"]

    end
    subgraph "Model"
        m_ins["ins"]
        m_epi["epi"]
    end

    %% Define the variable renaming flow
    shared_ins -->|ins=ins| m_ins
    shared_epi -->|epi=epi| m_epi

In the model file, we specify this dependency in the INPUTS header:

########## INPUTS
ins = ins
epi = epi

It is also possible to rename the inputs, if the variables provided in the "external pool of variables" provides the input in a different name. In this example, the "external variable" is named ins_plasma and our model needs ins:

########## INPUTS
ins = ins_plasma
epi = epi_plasma

Getting inputs from an activity

Now, these "external variables" can either come from the outputs of another model, or as in this case, from an activity:

graph LR
    %% Add text above the boxes

    subgraph "Activity"
        activity_ins["ins_plasma"]
        activity_epi["epi_plasma"]

    end

    subgraph "External variables"
        shared_ins["ins_plasma"]
        shared_epi["epi_plasma"]

    end
    subgraph "Model"
        m_ins["ins"]
        m_epi["epi"]
    end

    %% Define the variable renaming flow
    activity_ins --> shared_ins
    activity_epi --> shared_epi
    shared_ins -->|ins=ins_plasma| m_ins
    shared_epi -->|epi=epi_plasma| m_epi

The activity object can provide outputs using different types (such as piecewise constant, piecewise linear, cubic spline etc). Lets assume that our system have two piecewise constant inputs, starting at 0, and switching to different values at given times. Also, lets assume that our activity is defined in minutes ('m'):

input_activity = sund.Activity(time_unit = 'm')
input_activity.add_output("piecewise_constant", 'epi_plasma', t=[10,15,70,75], f=[0,10,0,20,0])
input_activity.add_output("piecewise_constant", 'ins_plasma', t=[30], f=[0, 15])

Simulating the model with the activity

Once we have the model and activities defined, it is possible to construct a simulation which uses this activity to provide inputs to the model:

model = sund.load_model('model_example')
simulation = sund.Simulation(time_unit='m', models=[model], activities=[input_activity])

Now, the simulation will automatically map the outputs from the activity object to the inputs that the model needs.