模型模拟相关 API#

SimulationResult#

class SimulationResult#
import polars as pl
import numpy as np

from mas.model import *


class WarfarinPkPd(OdeModule):
    def __init__(self) -> None:
        super().__init__(odeint.DVERK(tol=1e-3))
        self.dose_cmt = compartment(default_dose=True)
        self.central_cmt = compartment(default_obs=True)
        self.effect_cmt = compartment()

        self.theta_cl = theta(0.132, bounds=(0.01, 1))
        self.theta_v = theta(7.978, bounds=(0.01, 20))
        self.theta_ka = theta(1.359, bounds=(0.01, 5))
        self.theta_alag = theta(0.828, bounds=(0.01, 24))

        self.theta_e0 = theta(100, bounds=(0.01, 500))
        self.theta_emax = theta(-250, bounds=(-500, 0))
        self.theta_ec50 = theta(10, bounds=(0.01, 20))
        self.theta_ke0 = theta(0.2, bounds=(0.001, 3))

        self.eta_V = omega(0.08)
        self.eta_Cl = omega(0.08)
        self.eta_ka = omega(0.16)
        self.eta_alag = omega(0.15)

        self.eta_e0 = omega(0.09)
        self.eta_emax = omega(0, fixed=True)
        self.eta_ec50 = omega(0.4)
        self.eta_ke0 = omega(0.3)

        self.eps_prop_pk = sigma(0.01)
        self.eps_add_pk = sigma(0.06)
        self.eps_add_pd = sigma(15)

        self.dvid = column("DVID")

    def pred(self):
        # PD 参数
        cl = self.theta_cl * exp(self.eta_Cl)
        v = self.theta_v * exp(self.eta_V)
        ka = self.theta_ka * exp(self.eta_ka)
        alag = self.theta_alag * exp(self.eta_alag)
        k = cl / v

        # PD 参数
        e0 = self.theta_e0 * exp(self.eta_e0)
        emax = self.theta_emax * exp(self.eta_emax)
        ec50 = self.theta_ec50 * exp(self.eta_ec50)
        ke0 = self.theta_ke0 * exp(self.eta_ke0)

        # 定义微分方程组
        conc = self.central_cmt.A / v
        ce = self.effect_cmt.A

        self.dose_cmt.alag = alag
        self.dose_cmt.dAdt = -ka * self.dose_cmt.A
        self.central_cmt.dAdt = ka * self.dose_cmt.A - k * self.central_cmt.A
        self.effect_cmt.dAdt = ke0 * (conc - ce)

        eff = e0 + (emax * ce) / (ec50 + ce)

        if self.dvid == 1:  # PK 预测值
            y = conc * (1 + self.eps_prop_pk) + self.eps_add_pk
        else:  # PD 预测值
            y = eff + self.eps_add_pd

        return y


scenario = (
    EventTable()
    .add_dosing(
        time=0,
        amt=100,
    )
    .add_sampling(time=np.arange(0, 121))
    .with_covariates(DVID=1)
    .with_ids(np.arange(0, 1001))
    .merge(
        EventTable()
        .add_sampling(
            time=np.arange(0, 121),
        )
        .with_covariates(DVID=2)
        .with_ids(np.arange(0, 1001))
    )
)

pop_model = PopModel(mod=WarfarinPkPd, data=scenario)
res = pop_model.simulate()
res
➡️ Since build cache already exists, skip compile
[WARNING] Casting DVID to numeric dtype

Summary

N SubjectN ObsSeedSimulation Time
100124324312340:00:03.41

output#

property output

模拟得到的数据集。

类型:

DataFrame

示例:

res.output.head(10)
shape: (10, 29)
IDTIMEDVAMTCMTEVIDMDVSSRATEDURADDLIIDVID_IPRED__PRED__Y_alagceclconce0ec50effemaxkkake0vy
i64f64f64f64i64i64i64i64f64f64i64f64f64f64f64f64f64f64f64f64f64f64f64f64f64f64f64f64f64
00.0null100.0111nullnullnullnullnull1.00.00.0-0.1445641.0274340.00.1316310.0117.3828659.965346117.382865-250.00.0112752.3308350.18163511.674763-0.144564
00.0nullnull201nullnullnullnullnull1.00.00.0-0.2018691.0274340.00.1316310.0117.3828659.965346117.382865-250.00.0112752.3308350.18163511.674763-0.201869
00.0nullnull201nullnullnullnullnull2.0117.382865100.0122.9953361.0274340.00.1316310.0117.3828659.965346117.382865-250.00.0112752.3308350.18163511.674763122.995336
01.0nullnull201nullnullnullnullnull1.00.02.60881-0.3172761.0274340.00.1316310.0117.3828659.965346117.382865-250.00.0112752.3308350.18163511.674763-0.317276
01.0nullnull201nullnullnullnullnull2.0117.38286598.852754108.7559621.0274340.00.1316310.0117.3828659.965346117.382865-250.00.0112752.3308350.18163511.674763108.755962
02.0nullnull201nullnullnullnullnull1.07.6212649.8647678.2582651.0274340.8516630.1316317.621264117.3828659.96534697.69945-250.00.0112752.3308350.18163511.6747638.258265
02.0nullnull201nullnullnullnullnull2.097.6994570.49597395.8655091.0274340.8516630.1316317.621264117.3828659.96534697.69945-250.00.0112752.3308350.18163511.67476395.865509
03.0nullnull201nullnullnullnullnull1.08.33109411.5780749.1210941.0274342.0604930.1316318.331094117.3828659.96534674.548165-250.00.0112752.3308350.18163511.6747639.121094
03.0nullnull201nullnullnullnullnull2.074.54816541.1005773.8724531.0274342.0604930.1316318.331094117.3828659.96534674.548165-250.00.0112752.3308350.18163511.67476373.872453
04.0nullnull201nullnullnullnullnull1.08.31500111.8698528.1200681.0274343.1029180.1316318.315001117.3828659.96534658.023066-250.00.0112752.3308350.18163511.6747638.120068

data#

property data

用于模拟的原始数据集。

类型:

DataFrame

seed#

property seed

设定的随机种子号。

类型:

int

elapsed_time#

property elapsed_time

模拟耗时。

类型:

timedelta

plot_ind()#

plot_ind(filter=None, idv_name=None, y_name='_IPRED_') Plot

绘制个体模拟数据折线图。

参数:

  • filter (Expr, optional): 筛选条件,对于部分数据进行个体模拟图绘制。默认值为 None

  • idv_name (str, optional):因变量名。若为 None,则自动推断。默认值为 None

  • y_name (str, optional):自变量名。默认值为 "_IPRED_"

返回值:

绘制完成的个体模拟数据折线图。

返回类型:

Plot

示例:

res.plot_ind().with_facet_wrap("DVID", shared_y_axis=False)
[WARNING] Sampling data for better performance...

plot_interval()#

plot_interval(filter=None, idv_name=None, y_name='_IPRED_') Plot

绘制模拟数据区间图(5% 分位数至 95% 分位数)。

参数:

  • filter (Expr, optional): 筛选条件,对于部分数据进行个体模拟图绘制。默认值为 None

  • idv_name (str, optional):因变量名。若为 None,则自动推断。默认值为 None

  • y_name (str, optional):自变量名。默认值为 "_IPRED_"

示例:

绘制在 100 mg 给药时华法林的血药浓度个体预测值 95% 置信区间图:

from mas.plotting import GridPlot

GridPlot(
    [
        res.plot_interval(filter=pl.col("DVID") == 1),
        res.plot_interval(filter=pl.col("DVID") == 2),
    ],
    n_cols=2,
    shared_x_axis=True,
    shared_y_axis=False,
)