Introduction to Superposition in Pumas

Author

Vijay Ivaturi

Load the necessary libraries

using DataFramesMeta
using Pumas
using PharmaDatasets
using Random
using CairoMakie
using AlgebraOfGraphics

1 Introduction

This tutorial will introduce the workflow of performing Superposition (SP) in a command-line based workflow which simulates concentration-time profiles following multiple dosing events based on single-dose data. A graphical user interface for SP is also available for a more interactive experience. Please contact sales@pumas.ai for more information.

For the purpose of this tutorial, we will be using the following dataset:

Blood samples for pharmacokinetics were collected in 30 subjects who received 250 mg, 500 mg and 750 mg of DrugX as a single dose for 24 hours post dose.

We will perform superposition using the single dose data for each dosing group.

In the given dataset

  • Time = hrs
  • Conc = ug/L
  • Amt = ug

1.1 Load Data

Load the pharmacokinetic (PK) dataset using the datasets function from PharmaDatasets.

sd_pk = dataset("iv_sd_1")
sd_pk_250 = @rsubset sd_pk :dose == 250;
first(sd_pk, 5)
5×6 DataFrame
Row id dose time conc amt route
Int64 Int64 Float64 Float64 Int64? String3
1 1 250 0.0 17.29 250 iv
2 1 250 0.25 17.87 missing iv
3 1 250 0.5 25.59 missing iv
4 1 250 0.75 19.52 missing iv
5 1 250 1.0 18.72 missing iv

2 Superposition in Pumas

The NCA.superposition function in Pumas can be used to simulate drug concentration profiles after multiple dosing events, based on single-dose data. Superposition analysis is especially useful for predicting steady-state concentrations without having to collect data from multiple dosing trials. Here, we will explore the details of each parameter involved in the NCA.superposition function, walk through its use, and provide examples to help you understand how to apply it in practice.

2.1 Function Overview: NCA.superposition

NCA.superposition(
    data::Union{NCAPopulation,NCASubject};
    ii,
    ndoses = 5,
    amt = nothing,
    steadystatetol = 3e-2,
    method = :linear,
)

This function calculates the superposition of concentration profiles from single-dose data, simulating what would happen after repeated dosing. The superposition technique assumes that the pharmacokinetics of the drug remain linear and predictable across multiple doses.

2.1.1 Arguments:

  1. ii - Interdose Interval (Required)

    • The interdose interval (ii) is the time between consecutive doses. This is a crucial parameter because it dictates how often the drug is administered.
    • In practice, this value is typically provided in hours or days. For example, if a drug is dosed once daily, you would set ii = 24 (assuming time is measured in hours).

    Example:

    ii = 24  # Once-a-day dosing
  2. ndoses - Number of Doses (Optional)

    • ndoses specifies the total number of doses administered. This can either be a positive integer or infinity (Inf). Setting ndoses = Inf simulates drug administration until steady-state is reached.
    • If the number of doses is set to a finite number (e.g., ndoses = 5), the function will calculate the concentration-time profile up to the specified number of doses.

    Example:

    ndoses = 7  # Administer 7 doses
  3. amt - Dose Amount (Optional)

    • This parameter defines the amount of drug administered with each dose. If not provided, the function uses the dose amount from the original dataset (e.g., AMT).
    • Specifying amt allows you to simulate superposition for different dosing levels without altering the original dataset.

    Example:

    amt = 20000  # Set dose to 20,000 units
  4. steadystatetol - Steady-State Tolerance (Optional)

    • The steady-state tolerance controls how close the concentration profile must be to the steady-state condition before the function terminates further dose additions.
    • Steady-state is typically reached when the difference between drug concentration after two consecutive doses is within a small margin of error. This is defined by the formula: [ | 1 - | ]
    • The default value is 3e-2 (or 3%). You can adjust this parameter based on the precision required for your analysis.

    Example:

    steadystatetol = 1e-2  # Set tolerance to 1%
  5. method - Interpolation Method (Optional)

    • The method parameter defines how the concentration values are interpolated between observed data points. The default method is :linear, meaning the function will use linear interpolation to predict concentrations at unmeasured time points.

    Example:

    method = :linear  # Use linear interpolation

3 How Superposition Works

The superposition principle is based on the concept of linear pharmacokinetics, where the concentration profile following multiple dosing events can be predicted by summing up the individual contributions of each dose. This means the concentration at any given time point after multiple doses is simply the sum of the concentrations produced by each individual dose, shifted by the interdose interval (ii).

4 Example Workflow: Superposition for a 7-Day Dosing Regimen

Let’s walk through a practical example where we simulate the concentration-time profile after a 7-day dosing regimen with a once-daily (24-hour interval) dosing schedule.

4.1 Step 1: Prepare Your NCA Population

First, you need to prepare an NCA population (NCAPopulation) from the observed data. This involves using the read_nca function to load the dataset and specify the important variables (e.g., time, dose, observations):

nca_pop = read_nca(
    sd_pk_250,  # DataFrame containing PK data
    id = :id,  # Subject ID
    time = :time,  # Time column
    observations = :conc,  # Drug concentration column
    amt = :amt,  # Dose amount
    route = :route,  # Dosing route (e.g., iv or ev)
)
NCAPopulation (10 subjects):
  Number of missing observations: 0
  Number of blq observations: 0

4.2 Step 2: Run Superposition Analysis

Next, run the superposition analysis for a 7-day, once-daily dosing regimen:

result = NCA.superposition(nca_pop, ii = 24, ndoses = 7, amt = 20000)
1060×9 DataFrame
1035 rows omitted
Row id abstime time observations amt ii addl route occasion
String Float64 Float64 Float64 Int64 Int64? Int64? String Int64
1 1 0.0 0.0 1383.2 20000 24 6 iv 1
2 1 0.25 0.25 1429.6 0 missing missing iv 1
3 1 0.5 0.5 2047.2 0 missing missing iv 1
4 1 0.75 0.75 1561.6 0 missing missing iv 1
5 1 1.0 1.0 1497.6 0 missing missing iv 1
6 1 1.5 1.5 1579.2 0 missing missing iv 1
7 1 2.0 2.0 1344.0 0 missing missing iv 1
8 1 2.5 2.5 1500.8 0 missing missing iv 1
9 1 3.0 3.0 1369.6 0 missing missing iv 1
10 1 4.0 4.0 996.0 0 missing missing iv 1
11 1 6.0 6.0 840.8 0 missing missing iv 1
12 1 8.0 8.0 684.0 0 missing missing iv 1
13 1 12.0 12.0 525.6 0 missing missing iv 1
1049 10 145.0 1.0 2303.9 0 missing missing iv 7
1050 10 145.5 1.5 2215.64 0 missing missing iv 7
1051 10 146.0 2.0 2334.7 0 missing missing iv 7
1052 10 146.5 2.5 1813.06 0 missing missing iv 7
1053 10 147.0 3.0 1403.52 0 missing missing iv 7
1054 10 148.0 4.0 1722.27 0 missing missing iv 7
1055 10 150.0 6.0 708.507 0 missing missing iv 7
1056 10 152.0 8.0 569.01 0 missing missing iv 7
1057 10 156.0 12.0 215.102 0 missing missing iv 7
1058 10 160.0 16.0 81.0722 0 missing missing iv 7
1059 10 164.0 20.0 36.9055 0 missing missing iv 7
1060 10 168.0 24.0 12.0409 0 missing missing iv 7
  • ii=24: The drug is administered once every 24 hours.
  • ndoses=7: We are simulating a 7-day dosing schedule.
  • amt=20000: Each dose consists of 20,000 units of the drug.

4.3 Step 3: Visualize the Superposition Results

After running the superposition, you can visualize the predicted concentration-time profiles. You might want to plot the results to compare steady-state behavior:

# Example: Use AlgebraOfGraphics for plotting
plt =
    data(result) *
    mapping(:abstime, :observations, group = :id) *
    visual(Lines, color = (:grey, 0.5))
draw(
    plt;
    axis = (;
        xlabel = "Time (hours)",
        ylabel = "Observations (ug/L)",
        xticks = 0:12:160,
        yticks = 0:500:4000,
    ),
)

In this plot, you’ll observe how the drug concentrations change over time with each subsequent dose. By day 7, the drug may reach steady-state, meaning the concentration profile no longer changes significantly from one dose to the next.

4.4 Step 4: Investigate Steady-State Achievements

To understand if the system has reached steady-state, you can adjust the steadystatetol parameter. This allows you to set a stricter or more lenient criterion for steady-state achievement.

result_strict_tol = NCA.superposition(nca_pop, ii = 24, ndoses = Inf, steadystatetol = 1e-3)
[ Info: Subject 1: ndoses is not specified. So 0.001 is used as the steady state tolerance (can be passed in as an argument, e.g.  `steadystatetol =  0.001`)
[ Info: Subject 2: ndoses is not specified. So 0.001 is used as the steady state tolerance (can be passed in as an argument, e.g.  `steadystatetol =  0.001`)
[ Info: Subject 3: ndoses is not specified. So 0.001 is used as the steady state tolerance (can be passed in as an argument, e.g.  `steadystatetol =  0.001`)
[ Info: Subject 4: ndoses is not specified. So 0.001 is used as the steady state tolerance (can be passed in as an argument, e.g.  `steadystatetol =  0.001`)
[ Info: Subject 5: ndoses is not specified. So 0.001 is used as the steady state tolerance (can be passed in as an argument, e.g.  `steadystatetol =  0.001`)
[ Info: Subject 6: ndoses is not specified. So 0.001 is used as the steady state tolerance (can be passed in as an argument, e.g.  `steadystatetol =  0.001`)
[ Info: Subject 7: ndoses is not specified. So 0.001 is used as the steady state tolerance (can be passed in as an argument, e.g.  `steadystatetol =  0.001`)
[ Info: Subject 8: ndoses is not specified. So 0.001 is used as the steady state tolerance (can be passed in as an argument, e.g.  `steadystatetol =  0.001`)
[ Info: Subject 9: ndoses is not specified. So 0.001 is used as the steady state tolerance (can be passed in as an argument, e.g.  `steadystatetol =  0.001`)
[ Info: Subject 10: ndoses is not specified. So 0.001 is used as the steady state tolerance (can be passed in as an argument, e.g.  `steadystatetol =  0.001`)
505×9 DataFrame
480 rows omitted
Row id abstime time observations amt ii addl route occasion
String Float64 Float64 Float64 Int64 Int64? Int64? String Int64
1 1 0.0 0.0 17.29 250 24 3 iv 1
2 1 0.25 0.25 17.87 0 missing missing iv 1
3 1 0.5 0.5 25.59 0 missing missing iv 1
4 1 0.75 0.75 19.52 0 missing missing iv 1
5 1 1.0 1.0 18.72 0 missing missing iv 1
6 1 1.5 1.5 19.74 0 missing missing iv 1
7 1 2.0 2.0 16.8 0 missing missing iv 1
8 1 2.5 2.5 18.76 0 missing missing iv 1
9 1 3.0 3.0 17.12 0 missing missing iv 1
10 1 4.0 4.0 12.45 0 missing missing iv 1
11 1 6.0 6.0 10.51 0 missing missing iv 1
12 1 8.0 8.0 8.55 0 missing missing iv 1
13 1 12.0 12.0 6.57 0 missing missing iv 1
494 10 49.0 1.0 28.7988 0 missing missing iv 3
495 10 49.5 1.5 27.6955 0 missing missing iv 3
496 10 50.0 2.0 29.1837 0 missing missing iv 3
497 10 50.5 2.5 22.6633 0 missing missing iv 3
498 10 51.0 3.0 17.544 0 missing missing iv 3
499 10 52.0 4.0 21.5284 0 missing missing iv 3
500 10 54.0 6.0 8.85634 0 missing missing iv 3
501 10 56.0 8.0 7.11263 0 missing missing iv 3
502 10 60.0 12.0 2.68877 0 missing missing iv 3
503 10 64.0 16.0 1.0134 0 missing missing iv 3
504 10 68.0 20.0 0.461319 0 missing missing iv 3
505 10 72.0 24.0 0.150512 0 missing missing iv 3

In this example, the simulation will stop only when the concentration profile satisfies the 0.1% tolerance for steady-state. This is useful for simulating long-term dosing regimens and understanding how steady-state concentrations are achieved.

5 Performing NCA on Superposition Result

The result of the superposition analysis can easily be sent to compute NCA metrics.

nca_sup = read_nca(
    result,
    group = :occasion,
    ii = :ii,
    observations = :observations,
    time = :time,
    amt = :amt,
    route = :route,
)
NCAPopulation (10 subjects):
  Group: [["occasion" => 1], ["occasion" => 2], ["occasion" => 3], ["occasion" => 4], ["occasion" => 5], ["occasion" => 6], ["occasion" => 7]]
  Number of missing observations: 0
  Number of blq observations: 0

Once the result of the superposition data is read into Pumas as a NCA dataset, we can run NCA on this.

nca_sup_result = run_nca(
    nca_sup,
    parameters = [:cmax, :cmaxss, :cmin, :cminss, :accumulation_index, :cavgss],
    studytitle = "NCA results based on Superposition",
);
nca_sup_result.reportdf
70×8 DataFrame
45 rows omitted
Row id occasion cmax cmaxss cmin cminss accumulation_index cavgss
String Int64 Float64 Float64 Float64 Float64 Float64 Float64
1 1 1 2047.2 2199.37 211.2 226.899 1.07433 660.144
2 2 1 3436.0 3447.71 18.4 18.4627 1.00341 543.678
3 3 1 3512.8 3550.74 80.0 80.8641 1.0108 605.476
4 4 1 2738.4 2798.83 96.0 98.1185 1.02207 660.55
5 5 1 2544.8 2590.35 88.0 89.5752 1.0179 654.691
6 6 1 1920.8 1946.36 104.0 105.384 1.01331 494.529
7 7 1 3153.6 3161.8 17.6 17.6457 1.0026 490.443
8 8 1 2688.0 2803.81 98.4 102.639 1.04308 549.773
9 9 1 2425.6 2464.79 68.8 69.9116 1.01616 627.842
10 10 1 3076.8 3089.31 36.8 36.9497 1.00407 599.588
11 1 2 2186.74 2350.94 228.552 245.715 1.07509 717.879
12 2 2 3440.8 3452.52 18.4221 18.4848 1.00341 544.434
13 3 2 3555.66 3594.25 81.3085 82.1908 1.01085 616.165
59 9 6 2453.46 2492.9 69.4373 70.5535 1.01607 634.527
60 10 6 3087.5 3100.05 36.9055 37.0556 1.00406 601.74
61 1 7 2198.36 2381.56 159.457 172.746 1.08334 730.869
62 2 7 3440.81 3446.21 4.80753 4.81508 1.00157 543.876
63 3 7 3556.29 3608.28 45.4549 46.1194 1.01462 619.67
64 4 7 2805.94 2875.91 72.9751 74.7949 1.02494 688.462
65 5 7 2595.05 2651.35 52.3107 53.4456 1.02169 671.535
66 6 7 1997.71 2087.55 76.9095 80.3684 1.04497 533.38
67 7 7 3159.63 3167.78 6.41651 6.43305 1.00258 491.655
68 8 7 2743.13 2838.27 57.1145 59.0954 1.03468 564.933
69 9 7 2453.46 2477.16 30.6937 30.9902 1.00966 632.726
70 10 7 3087.5 3098.03 12.0409 12.082 1.00341 601.239

6 Practical Applications of Superposition

Superposition analysis is widely used in pharmacokinetics for the following purposes:

  1. Dosing Regimen Design:

    • Helps to predict the concentration profile of a drug after multiple doses and determine whether therapeutic concentrations are achieved and maintained.
  2. Steady-State Prediction:

    • Essential for drugs that require steady-state concentrations for efficacy, such as chronic therapies or antibiotics.
  3. Dose Adjustment:

    • By adjusting the amt parameter, superposition can help simulate different dose levels and guide decisions on appropriate dosing adjustments.
  4. Interdose Interval Analysis:

    • By varying the ii parameter, you can simulate different dosing intervals (e.g., twice daily vs. once daily) to optimize the regimen for efficacy and safety.

7 Conclusion

The NCA.superposition function in Pumas is a flexible and essential tool for pharmacokinetic modeling. By simulating drug concentration profiles under repeated dosing, you can make informed decisions about dosing regimens, steady-state predictions, and dose adjustments. With this detailed understanding of the function parameters and a step-by-step approach, you can apply superposition analysis effectively to your own datasets.