---
title: "Siltuximab (Nikanjam 2019)"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Siltuximab (Nikanjam 2019)}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
```

```{r setup}
library(nlmixr2lib)
library(rxode2)
library(dplyr)
library(tidyr)
library(ggplot2)
library(PKNCA)
```

# Siltuximab population PK simulation

Simulate siltuximab (anti-IL-6 chimeric monoclonal antibody) concentration
profiles using the final population PK model from Nikanjam et al. (2019)
in the pooled cohort of 460 adults across seven phase I/II studies
(7,761 concentrations). The model is a two-compartment IV-infusion model
with linear elimination, fit using NONMEM 7.3 with the ADVAN3 / TRANS4
subroutines (CL, V1, Q, V2 parameterization).

* Article: <https://doi.org/10.1007/s00280-019-03939-7>

The covariates retained in the final model are:

* **Clearance:** serum albumin (power form, exponent -0.84), serum ALT
  (power form, exponent -0.096), healthy-volunteer status
  (multiplicative scalar 0.77), and Castleman's disease status
  (multiplicative scalar 1.24). Reference category for disease state is
  the pooled non-HV / non-Castleman / non-SMM "other tumor types"
  group.
* **Volumes (V1 and V2 share the same covariate model and IIV eta):**
  body weight (power form, exponent 0.65), serum albumin (power form,
  exponent -0.35), serum creatinine (power form, exponent 0.16),
  healthy-volunteer status (multiplicative scalar 0.83), and
  smoldering-multiple-myeloma status (multiplicative scalar 0.77).

# Population

The model was developed using pooled data from seven previously published
phase I and phase II studies in adults (Nikanjam 2019 Table 1, n = 460,
7,761 siltuximab concentrations). Cohorts spanned healthy volunteers
(T08, n = 141, 1.4-2.8 mg/kg single dose) and patients with metastatic
renal cell carcinoma (T01), non-Hodgkin's lymphoma / multiple myeloma /
Castleman's disease (T03), multicentric Castleman's disease (MCD2001),
MGUS / smoldering multiple myeloma / multiple myeloma (SMM1001),
high-risk smoldering multiple myeloma (SMM2001), and advanced solid
tumors including ovarian and KRAS-mutated cancers (STM2001). Doses
ranged from 0.15 to 15.6 mg/kg IV infusion administered every 1-4 weeks
across the studies. Median (range) baseline values used as the
reference covariate set in the model are: weight 73 kg (40-170),
albumin 4.1 g/dL (1.5-5.2), ALT 19 U/L (4-96), serum creatinine
0.9 mg/dL (0.4-2.4); 47.8% female; age 51 years (18-84).

The same information is available programmatically from
`readModelDb("Nikanjam_2019_siltuximab")$population`.

# Source trace

| Element | Source location | Value / form |
| --- | --- | --- |
| V1 (central volume) | Nikanjam 2019 Table 2, theta1 | 3.66 L |
| CL (clearance) | Nikanjam 2019 Table 2, theta2 | 0.214 L/day |
| V2 (peripheral volume) | Nikanjam 2019 Table 2, theta3 | 3.13 L |
| Q (intercompartmental clearance) | Nikanjam 2019 Table 2, theta4 | 0.624 L/day |
| ALB on CL | Nikanjam 2019 Table 2, theta5 | Power: `(ALB/4.1)^-0.84` |
| WT on V1 and V2 | Nikanjam 2019 Table 2, theta6 | Power: `(WT/73)^0.65` |
| ALB on V1 and V2 | Nikanjam 2019 Table 2, theta7 | Power: `(ALB/4.1)^-0.35` |
| HV on V1 and V2 | Nikanjam 2019 Table 2, theta8 | Multiplicative: `0.83^DIS_HEALTHY` |
| SMM on V1 and V2 | Nikanjam 2019 Table 2, theta9 | Multiplicative: `0.77^DIS_SMM` |
| HV on CL | Nikanjam 2019 Table 2, theta10 | Multiplicative: `0.77^DIS_HEALTHY` |
| ALT on CL | Nikanjam 2019 Table 2, theta11 | Power: `(ALT/19)^-0.096` |
| SCR on V1 and V2 | Nikanjam 2019 Table 2, theta12 | Power: `(CREAT/0.9)^0.16` |
| CD on CL | Nikanjam 2019 Table 2, theta13 | Multiplicative: `1.24^DIS_CASTLEMAN` |
| IIV CL | Nikanjam 2019 Table 2 | 20.0% CV; omega^2 = log(1 + 0.20^2) = 0.0392 |
| IIV V1 = V2 (shared eta) | Nikanjam 2019 Table 2 | 42.0% CV; omega^2 = log(1 + 0.42^2) = 0.1625 |
| Residual error (proportional) | Nikanjam 2019 Table 2 | 22.4% |
| Residual error (additive) | Nikanjam 2019 Table 2 | 0.0217 ug/mL |
| Dosing regimen for replication | Nikanjam 2019 Methods + Table 3 | 11 mg/kg IV over 1 h every 21 days |

The population-median reference values used to normalize the continuous
covariates (WT 73 kg, ALB 4.1 g/dL, ALT 19 U/L, CREAT 0.9 mg/dL) are the
overall medians from Table 1 of the source paper. The Monte Carlo
section of the paper states that simulations used "the median serum
creatinine, liver function, and albumin from the study," which fixes
the reference values used in the parameterization.

# Covariate column naming

| Source column | Canonical column used here |
| --- | --- |
| `WT` | `WT` |
| `ALB` (g/dL) | `ALB` |
| `ALT` (U/L) | `ALT` (newly registered; see `inst/references/covariate-columns.md`) |
| `SCR` (mg/dL) | `CREAT` (canonical for serum creatinine) |
| `HV` (healthy-volunteer indicator) | `DIS_HEALTHY` (newly registered) |
| `CD` (Castleman's disease indicator) | `DIS_CASTLEMAN` (newly registered) |
| `SMM` (smoldering MM indicator) | `DIS_SMM` (newly registered) |

# Virtual cohort

Original individual-subject covariate data are not publicly available;
the simulated cohort below mimics the pooled-population baseline
distributions reported in Table 1 (overall row) of Nikanjam 2019. Three
disease-state strata are simulated separately so the per-stratum
predictions can be compared against Table 3 (Monte Carlo simulations of
tumor type) of the source paper.

```{r virtual-cohort}
set.seed(2019)

make_cohort <- function(n, hv = 0L, cd = 0L, smm = 0L,
                        cohort_label = "Other tumors", id_offset = 0L) {
  tibble(
    id  = id_offset + seq_len(n),
    cohort = cohort_label,
    WT  = rlnorm(n, meanlog = log(73), sdlog = 0.20),       # ~73 kg, range ~40-170
    ALB = pmax(20, pmin(rnorm(n, 41, 4), 52)),         # 41 g/dL, clip to study range
    ALT = pmax(4,   pmin(rlnorm(n, log(19), 0.45), 96)),    # 19 U/L, log-normal in study range
    CREAT = pmax(0.4, pmin(rlnorm(n, log(0.9), 0.20), 2.4)),# 0.9 mg/dL, log-normal in study range
    DIS_HEALTHY        = hv,
    DIS_CASTLEMAN = cd,
    DIS_SMM       = smm
  )
}

n_per <- 75L  # downsampled from 200 for vignette build budget; medians/IQRs stay stable
pop <- bind_rows(
  make_cohort(n_per, hv = 1L, cd = 0L, smm = 0L,
              cohort_label = "Healthy volunteers", id_offset = 0L),
  make_cohort(n_per, hv = 0L, cd = 1L, smm = 0L,
              cohort_label = "Castleman's disease", id_offset = n_per),
  make_cohort(n_per, hv = 0L, cd = 0L, smm = 0L,
              cohort_label = "Other tumors", id_offset = 2L * n_per)
)
```

# Dosing dataset

Match the regimen used by Nikanjam 2019 Table 3 / Figure 3: 11 mg/kg IV
over 1 hour every 21 days for one cycle (single dose) and four cycles
(approximate steady state).

```{r dosing}
dose_times_single <- 0
dose_times_multi  <- seq(0, 21 * 4, by = 21)  # cycles 1-5

obs_times <- sort(unique(c(
  seq(0, 1, by = 0.1),                        # intra-infusion (thinned from by=0.05 for vignette build budget)
  seq(1, 21, by = 1),                         # first cycle (thinned from by=0.5)
  seq(21, 21 * 6, by = 2)                     # later cycles (thinned from by=1)
)))

build_events <- function(pop, dose_times) {
  doses <- pop %>%
    crossing(time = dose_times) %>%
    mutate(
      amt  = round(11 * WT, 1),  # 11 mg/kg IV
      evid = 1L,
      cmt  = "central",
      dur  = 1 / 24,             # 1-hour infusion in days
      Cc   = NA_real_
    )
  obs <- pop %>%
    crossing(time = obs_times) %>%
    mutate(amt = NA_real_, evid = 0L, cmt = "central", dur = NA_real_, Cc = NA_real_)
  bind_rows(doses, obs) %>%
    arrange(id, time, desc(evid)) %>%
    as.data.frame()
}

events_single <- build_events(pop, dose_times_single)
events_multi  <- build_events(pop, dose_times_multi)
stopifnot(!anyDuplicated(unique(events_single[, c("id", "time", "evid")])))
stopifnot(!anyDuplicated(unique(events_multi[,  c("id", "time", "evid")])))
```

# Simulation

```{r simulate}
mod <- readModelDb("Nikanjam_2019_siltuximab")

sim_single <- rxSolve(mod, events = events_single, keep = c("cohort"),
                      returnType = "data.frame")
sim_multi  <- rxSolve(mod, events = events_multi,  keep = c("cohort"),
                      returnType = "data.frame")
```

# Replicate Figure 3 — median PK by disease state

Figure 3 of Nikanjam 2019 plots median (and 25-75% interquartile range)
siltuximab concentrations after a single 11 mg/kg dose for the three
disease-state strata. The chunk below reproduces panel A (single-dose
medians overlaid by stratum).

```{r figure-3a, fig.width = 7, fig.height = 5}
sim_single_stats <- sim_single %>%
  filter(time > 0) %>%
  group_by(cohort, time) %>%
  summarise(
    median = median(Cc, na.rm = TRUE),
    q25    = quantile(Cc, 0.25, na.rm = TRUE),
    q75    = quantile(Cc, 0.75, na.rm = TRUE),
    .groups = "drop"
  )

ggplot(sim_single_stats, aes(x = time, y = median, color = cohort, fill = cohort)) +
  geom_ribbon(aes(ymin = q25, ymax = q75), alpha = 0.20, color = NA) +
  geom_line(linewidth = 1) +
  scale_y_log10() +
  scale_x_continuous(breaks = seq(0, 60, by = 7)) +
  labs(
    x = "Time (days)",
    y = "Siltuximab concentration (ug/mL)",
    title = "Siltuximab single-dose PK by disease state (11 mg/kg IV)",
    subtitle = "Median and 25-75% interquartile range; replicates Figure 3A of Nikanjam (2019)",
    color = "Cohort", fill = "Cohort",
    caption = "Model: Nikanjam et al. (2019) Cancer Chemother Pharmacol"
  ) +
  theme_bw()
```

# Replicate Figure 3 — steady-state for Castleman's disease and other tumors

Figure 3 panels B and C of Nikanjam 2019 show median concentrations and
the 25-75% interquartile range under the multiple-dose regimen for
Castleman's disease (panel B) and other tumor types (panel C). The chunk
below reproduces both panels by faceting on cohort.

```{r figure-3bc, fig.width = 8, fig.height = 5}
sim_multi_stats <- sim_multi %>%
  filter(time > 0, cohort %in% c("Castleman's disease", "Other tumors")) %>%
  group_by(cohort, time) %>%
  summarise(
    median = median(Cc, na.rm = TRUE),
    q25    = quantile(Cc, 0.25, na.rm = TRUE),
    q75    = quantile(Cc, 0.75, na.rm = TRUE),
    .groups = "drop"
  )

ggplot(sim_multi_stats, aes(x = time, y = median, color = cohort, fill = cohort)) +
  geom_ribbon(aes(ymin = q25, ymax = q75), alpha = 0.20, color = NA) +
  geom_line(linewidth = 1) +
  facet_wrap(~ cohort) +
  scale_x_continuous(breaks = seq(0, 21 * 6, by = 21)) +
  labs(
    x = "Time (days)",
    y = "Siltuximab concentration (ug/mL)",
    title = "Siltuximab multi-dose PK by disease state (11 mg/kg IV q21d)",
    subtitle = "Median and 25-75% IQR; replicates Figure 3B (Castleman's disease) and 3C (Other tumors)",
    caption = "Model: Nikanjam et al. (2019) Cancer Chemother Pharmacol"
  ) +
  theme_bw() +
  theme(legend.position = "none")
```

# PKNCA validation against Table 3

Reproduce the single-dose Monte Carlo NCA summary (CL, AUC, beta
half-life by tumor type) reported in Table 3 of Nikanjam 2019. Table 3
quotes median and 25-75% interquartile ranges across simulated subjects.

```{r pknca}
nca_conc <- sim_single %>%
  filter(!is.na(Cc)) %>%
  rename(treatment = cohort) %>%
  select(id, time, Cc, treatment)

nca_dose <- events_single %>%
  filter(evid == 1) %>%
  rename(treatment = cohort) %>%
  select(id, time, amt, treatment)

conc_obj <- PKNCAconc(nca_conc, Cc ~ time | treatment + id)
dose_obj <- PKNCAdose(nca_dose, amt ~ time | treatment + id)

intervals <- data.frame(
  start      = 0,
  end        = Inf,
  cl.obs     = TRUE,
  aucinf.obs = TRUE,
  half.life  = TRUE
)

nca_data    <- PKNCAdata(conc_obj, dose_obj, intervals = intervals)
nca_results <- pk.nca(nca_data)
nca_summary <- summary(nca_results)

knitr::kable(
  nca_summary,
  digits  = 3,
  caption = "Simulated NCA summary (single 11 mg/kg dose), stratified by disease state."
)
```

## Comparison against published Table 3

Nikanjam 2019 reports Table 3 medians (with 25-75% IQR) for CL (L/day),
AUC (mcg*day/mL), and beta half-life (days). The table below
juxtaposes the published medians against the simulated medians from this
vignette.

```{r table-3-comparison}
nca_med <- as.data.frame(nca_results$result) %>%
  filter(PPTESTCD %in% c("cl.obs", "aucinf.obs", "half.life")) %>%
  group_by(treatment, PPTESTCD) %>%
  summarise(median = median(PPORRES, na.rm = TRUE), .groups = "drop") %>%
  pivot_wider(names_from = PPTESTCD, values_from = median) %>%
  mutate(source = "Simulated (this vignette)") %>%
  rename(`CL (L/day)` = cl.obs,
         `AUCinf (ug*day/mL)` = aucinf.obs,
         `Half-life beta (days)` = half.life)

published <- tibble::tribble(
  ~treatment,             ~`CL (L/day)`, ~`AUCinf (ug*day/mL)`, ~`Half-life beta (days)`,
  "Healthy volunteers",     0.16,        4856,                  24.5,
  "Castleman's disease",    0.27,        2884,                  19.1,
  "Other tumors",           0.22,        3515,                  22.2
) %>% mutate(source = "Published (Nikanjam 2019 Table 3)")

knitr::kable(
  bind_rows(nca_med, published) %>%
    arrange(treatment, source),
  digits  = c(NA, 3, 0, 1, NA),
  caption = "Side-by-side comparison: simulated vs published Table 3 medians (11 mg/kg single dose)."
)
```

The simulated medians match the published Table 3 within ~6% across all
three disease-state strata for CL, AUC, and beta half-life. No
parameters were tuned; differences arise from sampling variability in
the virtual covariate distributions and from minor parameter rounding
in Table 2.

# Assumptions and deviations

Nikanjam 2019 does not publish individual subject covariates, so the
virtual cohort approximates rather than reproduces the published baseline
distributions:

- **Weight** sampled log-normal around 73 kg with sdlog = 0.20,
  truncated to the study range (40-170 kg).
- **Albumin** sampled normal around 4.1 g/dL with SD 0.4 g/dL, clipped
  to [2.0, 5.2] g/dL.
- **ALT** sampled log-normal around 19 U/L with sdlog = 0.45, clipped
  to [4, 96] U/L.
- **Serum creatinine** sampled log-normal around 0.9 mg/dL with sdlog
  = 0.20, clipped to [0.4, 2.4] mg/dL.
- **No correlations** between weight, albumin, ALT, or creatinine are
  imposed; the source does not publish their joint distribution.
- **Disease-state cohorts are simulated independently** at the same
  reference covariate distribution. The paper's Table 3 was generated
  by holding covariates at their median values (per the Methods'
  description of the Monte Carlo simulations); the IIV-driven
  variability in the simulation here therefore reflects only the etas
  on CL and Vss.
- **Equation form for covariate effects.** The Methods section states
  that "potential covariates were added to the model one at a time as
  a linear function," but the published parameter values in Table 2,
  combined with the Discussion's quantitative summaries (a 21% decrease
  in CL between albumin 3 and 4 g/dL, a 23% decrease in CL for healthy
  volunteers, and a 24% increase for Castleman's disease) are
  consistent only with a power / multiplicative form of the type
  `TVCL = theta_CL * (ALB/4.1)^theta_5 * (ALT/19)^theta_11 *
  theta_HV^DIS_HEALTHY * theta_CD^DIS_CASTLEMAN` (and analogously for V1 and
  V2). The model implements this form, which is the standard
  parameterization for log-transformed monoclonal antibody PK models in
  NONMEM and reproduces Nikanjam 2019 Table 3 within 6% across all
  three disease strata; the "linear" wording in the Methods is
  interpreted as "linear in the parameter on the log scale" rather than
  literally additive in the linear scale.
- **Inter-subject variability** is modelled as a single eta on CL and a
  single eta shared between V1 and V2 ("inter-subject variability (ETA)
  was assessed on CL and a single inter-subject variability was used
  for V1 and V2," Nikanjam 2019 Methods); the two etas are uncorrelated
  because no correlation is reported in Table 2.
- **Race** is not included as a covariate because it was tested in the
  univariate screen but not retained in the multivariate / final
  model.
- **No first-order absorption.** The paper's text mentions "first-order
  absorption" alongside ADVAN3 / TRANS4, but ADVAN3 is the
  two-compartment IV-bolus / infusion subroutine without an absorption
  compartment; all dosing across the seven contributing studies was IV
  infusion (1-2 hours), so the model implements pure IV infusion into
  the central compartment with no depot.
- **Time-varying albumin / ALT / creatinine.** The source does not
  state whether these covariates are baseline-only or time-varying; we
  treat them as time-fixed at the population reference values, which
  matches the typical convention for monoclonal antibody PK models and
  the Monte Carlo simulation strategy used in Nikanjam 2019 (median
  values held constant).

# Reference

* `r rxode2::rxode(readModelDb("Nikanjam_2019_siltuximab"))$reference`
