Transparent, validated pharmacokinetics and pharmacodynamics modeling infrastructure
Project description
neopkpd
Transparent, validated pharmacokinetics and pharmacodynamics modeling infrastructure
The neopkpd Python package provides a comprehensive interface to the NeoPKPD Julia simulation engine, enabling seamless integration with Python data science workflows.
Installation
From PyPI (Recommended)
pip install neopkpd
# With visualization support
pip install neopkpd[viz]
# With all optional dependencies
pip install neopkpd[all]
From Source
git clone https://github.com/shramish2057/openpkpd.git
cd openpkpd/packages/python
pip install -e ".[all]"
Requirements:
- Python 3.10+
- Julia 1.10+ (automatically managed via juliacall)
- numpy, scipy (installed automatically)
Quick Start
import neopkpd
# Initialize Julia (required once per session)
neopkpd.init_julia()
# Run a simple simulation
result = neopkpd.simulate_pk_iv_bolus(
cl=5.0, v=50.0,
doses=[{"time": 0.0, "amount": 100.0}],
t0=0.0, t1=24.0,
saveat=[float(t) for t in range(25)]
)
print("Concentrations:", result["observations"]["conc"])
Features
PK/PD Simulation
# One-compartment IV bolus
result = neopkpd.simulate_pk_iv_bolus(cl=5.0, v=50.0, ...)
# IV infusion (specify duration)
result = neopkpd.simulate_pk_iv_bolus(
cl=5.0, v=50.0,
doses=[{"time": 0.0, "amount": 100.0, "duration": 1.0}], # 1-hour infusion
...
)
# One-compartment oral
result = neopkpd.simulate_pk_oral_first_order(ka=1.5, cl=5.0, v=50.0, ...)
# Two-compartment models
result = neopkpd.simulate_pk_twocomp_iv_bolus(cl=5.0, v1=50.0, q=2.0, v2=100.0, ...)
result = neopkpd.simulate_pk_twocomp_oral(ka=1.5, cl=5.0, v1=50.0, q=2.0, v2=100.0, ...)
# Three-compartment
result = neopkpd.simulate_pk_threecomp_iv_bolus(cl=5.0, v1=10.0, q2=20.0, v2=50.0, q3=2.0, v3=200.0, ...)
# Advanced models
result = neopkpd.simulate_pk_transit_absorption(ktr=2.0, n_transit=3, cl=5.0, v=50.0, ...)
result = neopkpd.simulate_pk_michaelis_menten(vmax=10.0, km=2.0, v=50.0, ...)
# PK-PD models
result = neopkpd.simulate_pkpd_direct_emax(cl=5.0, v=50.0, e0=0.0, emax=100.0, ec50=2.0, ...)
result = neopkpd.simulate_pkpd_sigmoid_emax(cl=5.0, v=50.0, e0=10.0, emax=40.0, ec50=0.8, gamma=2.0, ...)
result = neopkpd.simulate_pkpd_biophase_equilibration(cl=5.0, v=50.0, ke0=0.5, e0=0.0, emax=100.0, ec50=1.0, ...)
result = neopkpd.simulate_pkpd_indirect_response(cl=5.0, v=50.0, kin=10.0, kout=0.5, ic50=2.0, imax=0.9, ...)
Population Simulation
# Population with IIV
result = neopkpd.simulate_population_iv_bolus(
cl=5.0, v=50.0,
doses=[{"time": 0.0, "amount": 100.0}],
t0=0.0, t1=24.0,
saveat=[float(t) for t in range(25)],
n=100,
seed=12345,
omegas={"CL": 0.3, "V": 0.2}
)
# Access summaries
print("Mean:", result["summaries"]["conc"]["mean"])
print("5th percentile:", result["summaries"]["conc"]["quantiles"]["0.05"])
Parameter Estimation (NLME)
from neopkpd.estimation import estimate, EstimationConfig, FOCEIMethod
config = EstimationConfig(
method=FOCEIMethod(max_inner_iter=100, inner_tol=1e-6),
theta_init=[5.0, 50.0],
theta_lower=[0.1, 1.0],
theta_upper=[100.0, 500.0],
omega_init=[[0.09, 0], [0, 0.04]],
sigma_init={"kind": "proportional", "value": 0.1},
max_iter=500,
compute_se=True
)
result = estimate(observed_data, model_spec, config)
print("Theta:", result.theta)
print("Theta SE:", result.theta_se)
print("OFV:", result.ofv)
print("AIC:", result.aic)
Non-Compartmental Analysis (NCA)
from neopkpd.nca import run_nca, NCAConfig
result = run_nca(
times=[0, 0.5, 1, 2, 4, 8, 12, 24],
conc=[0, 1.8, 2.0, 1.5, 1.0, 0.5, 0.25, 0.06],
dose=100.0,
config=NCAConfig(method="log_linear")
)
print(f"Cmax: {result.cmax:.2f}")
print(f"Tmax: {result.tmax:.2f}")
print(f"AUC0-inf: {result.auc_0_inf:.2f}")
print(f"t1/2: {result.t_half:.2f}")
Visual Predictive Check (VPC)
from neopkpd.analysis import compute_vpc, VPCConfig
config = VPCConfig(
pi_levels=[0.05, 0.50, 0.95],
ci_level=0.95,
n_bins=10,
prediction_corrected=False,
n_bootstrap=500,
seed=12345
)
vpc_result = compute_vpc(observed_data, pop_spec, grid, solver, config=config)
# Visualize
from neopkpd import viz
viz.plot_vpc(vpc_result)
Clinical Trial Simulation
from neopkpd import trial
# Define design
design = trial.parallel_design(n_arms=2)
# Define dosing
regimen = trial.dosing_qd(dose=100.0, duration_days=28)
# Generate population
pop = trial.generate_virtual_population(n=100, seed=42)
# Create trial spec
spec = trial.TrialSpec(
name="Phase 2",
design=design,
arms=[
trial.TreatmentArm("Placebo", regimen=trial.dosing_qd(0.0, 28)),
trial.TreatmentArm("Treatment", regimen=regimen),
],
population=pop
)
# Run simulation
result = trial.simulate_trial(spec, seed=12345)
# Power analysis (multiple replicates)
power_result = trial.run_power_simulation(spec, n_replicates=100, seed=42)
print(f"Power: {power_result.power:.1%}")
Model Import
from neopkpd.import_ import parse_nonmem, parse_monolix
# Import NONMEM control file
model_spec, pop_spec, mapping = parse_nonmem("run001.ctl")
# Import Monolix project
model_spec, pop_spec, mapping = parse_monolix("project.mlxtran")
CDISC Data Import
from neopkpd.data import read_cdisc_csv, cdisc_to_population
# Read CDISC domains
dataset = read_cdisc_csv("pc.csv", "ex.csv", "dm.csv")
# Convert to NeoPKPD format
pop_spec, observed = cdisc_to_population(dataset, model_spec)
Sensitivity Analysis
result = neopkpd.run_sensitivity(
model_kind="OneCompIVBolus",
params={"CL": 5.0, "V": 50.0},
doses=[{"time": 0.0, "amount": 100.0}],
t0=0.0, t1=24.0,
saveat=[float(t) for t in range(25)],
sensitivity_param="CL",
perturbation=0.1,
observation="conc"
)
print("Max relative delta:", result.metrics.max_rel_delta)
Visualization
from neopkpd import viz
# Set backend
viz.set_backend("matplotlib") # or "plotly"
# PK plots
viz.plot_conc_time(result)
viz.plot_spaghetti(pop_result, n_subjects=50)
viz.plot_mean_ribbon(pop_result, ci_levels=[0.05, 0.95])
# VPC
viz.plot_vpc(vpc_result)
# Estimation diagnostics
viz.plot_goodness_of_fit(estimation_result, plot_type="obs_vs_pred")
viz.plot_estimation_summary(estimation_result) # 4-panel summary
# Sensitivity
viz.plot_sensitivity(sensitivity_result)
viz.plot_sensitivity_tornado(sensitivity_results)
# NCA
viz.plot_lambda_z_fit(nca_result, times, conc)
viz.plot_auc_visualization(times, conc, nca_result)
# Trial
viz.plot_power_curve(power_results, target_power=0.80)
viz.plot_tornado(sensitivity_analysis)
Module Structure
neopkpd/
├── __init__.py # Core simulation functions
├── _core.py # Julia bridge utilities
├── simulations/ # PK/PD simulation wrappers
│ ├── pk_onecomp.py
│ ├── pk_twocomp.py
│ ├── pk_threecomp.py
│ ├── pk_advanced.py
│ └── pkpd.py
├── nca/ # Non-compartmental analysis
│ ├── core.py
│ ├── config.py
│ └── bioequivalence.py
├── trial/ # Clinical trial simulation
│ ├── designs.py
│ ├── regimens.py
│ ├── population.py
│ └── power.py
├── estimation/ # NLME parameter estimation
│ ├── config.py
│ ├── nlme.py
│ └── diagnostics.py
├── import_/ # Model import
│ ├── nonmem.py
│ └── monolix.py
├── data/ # Data handling
│ └── cdisc.py
├── analysis/ # VPC, sensitivity
│ ├── vpc.py
│ └── sensitivity.py
└── viz/ # Visualization
├── pk.py
├── nca.py
├── pkpd.py
├── population.py
├── trial.py
└── backends.py
Integration with Data Science Tools
NumPy
import numpy as np
import neopkpd
result = neopkpd.simulate_pk_iv_bolus(...)
t = np.array(result["t"])
conc = np.array(result["observations"]["conc"])
print(f"Cmax: {np.max(conc):.2f}")
print(f"AUC: {np.trapz(conc, t):.2f}")
Pandas
import pandas as pd
# Population results to DataFrame
params_df = pd.DataFrame(pop_result["params"])
print(params_df.describe())
# Concentration data
data = []
for i, ind in enumerate(pop_result["individuals"]):
for t, c in zip(ind["t"], ind["observations"]["conc"]):
data.append({"id": i, "time": t, "conc": c})
conc_df = pd.DataFrame(data)
Performance Tips
- Initialize once: Call
init_julia()once at startup - Batch simulations: Julia JIT makes subsequent calls faster
- Use appropriate tolerances: Higher tolerance = faster, less accurate
- Sparse output: Use fewer
saveatpoints for large populations
Testing
cd packages/python
source .venv/bin/activate
pytest tests/
Documentation
Full documentation: shramish2057.github.io/NeoPKPD
License
MIT License - see LICENSE for details.
Citation
@software{neopkpd,
title = {NeoPKPD: Transparent PK/PD Modeling Infrastructure},
url = {https://github.com/shramish2057/openpkpd},
version = {0.1.0}
}
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file neopkpd-0.1.0.tar.gz.
File metadata
- Download URL: neopkpd-0.1.0.tar.gz
- Upload date:
- Size: 199.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4c10bc0ff09a9f77d42ce3813d3c608416c9235b53d0a5def5c31fb51c32eddc
|
|
| MD5 |
66bf9ed59033eb43a6814d299e6af3e6
|
|
| BLAKE2b-256 |
8f4bec2fd86c9a6313344601deea0206174a8726127a4e65f0cb3865a74096ba
|
Provenance
The following attestation bundles were made for neopkpd-0.1.0.tar.gz:
Publisher:
release.yml on shramish2057/NeoPKPD
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
neopkpd-0.1.0.tar.gz -
Subject digest:
4c10bc0ff09a9f77d42ce3813d3c608416c9235b53d0a5def5c31fb51c32eddc - Sigstore transparency entry: 813321393
- Sigstore integration time:
-
Permalink:
shramish2057/NeoPKPD@269e0c1b68d2e78f1b4c3bfeaeef3fd245c6efb4 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/shramish2057
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@269e0c1b68d2e78f1b4c3bfeaeef3fd245c6efb4 -
Trigger Event:
push
-
Statement type:
File details
Details for the file neopkpd-0.1.0-py3-none-any.whl.
File metadata
- Download URL: neopkpd-0.1.0-py3-none-any.whl
- Upload date:
- Size: 233.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
52394fd871b1e8b65d44bb100148a9c0db06c4d9b4c36f8f53fd16e5e29df6ad
|
|
| MD5 |
5d865ab5ccf9746b94f5c853db2e9e91
|
|
| BLAKE2b-256 |
dba454b03abaabc9ff8ddb617d571b9f8bd917ccb762f64308ac92c8e31ae7e4
|
Provenance
The following attestation bundles were made for neopkpd-0.1.0-py3-none-any.whl:
Publisher:
release.yml on shramish2057/NeoPKPD
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
neopkpd-0.1.0-py3-none-any.whl -
Subject digest:
52394fd871b1e8b65d44bb100148a9c0db06c4d9b4c36f8f53fd16e5e29df6ad - Sigstore transparency entry: 813321395
- Sigstore integration time:
-
Permalink:
shramish2057/NeoPKPD@269e0c1b68d2e78f1b4c3bfeaeef3fd245c6efb4 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/shramish2057
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@269e0c1b68d2e78f1b4c3bfeaeef3fd245c6efb4 -
Trigger Event:
push
-
Statement type: