---
title: "Ofatumumab (Yu 2022)"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Ofatumumab (Yu 2022)}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse  = TRUE,
  comment   = "#>",
  fig.width = 7,
  fig.height = 4.5
)
```

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

# Model and source

* Citation: `r rxode2::rxode2(readModelDb("Yu_2022_ofatumumab"))$meta$reference`
* Description: `r rxode2::rxode2(readModelDb("Yu_2022_ofatumumab"))$meta$description`
* Article: <https://doi.org/10.1007/s40263-021-00895-w>

Yu et al. (2022) developed a coupled population PK / B-cell-count model for
ofatumumab (a fully human anti-CD20 IgG1 monoclonal antibody) in adults with
relapsing forms of multiple sclerosis. The PK side is a quasi-steady-state
(QSS) approximation of the Mager-Krzyzanski TMDD framework with two drug
compartments (central + peripheral) and first-order SC absorption with
estimated bioavailability F. CD20 receptor synthesis decays exponentially
from `ksyn0` to `ksyn_inf` with rate constant `kdes` to capture a slight
upward drift in trough concentrations across the phase 3 ASCLEPIOS studies.
The B-cell side is an indirect-response model: free ofatumumab concentration
stimulates B-cell lysis through a sigmoid Emax function; B cells distribute
between a central compartment (sharing volume with the PK central
compartment) and a peripheral compartment specific to B cells.

# Population

The pooled analysis dataset combines five clinical studies (one phase 1/2
IV plus four phase 2/3 SC trials): OMS115102, MIRROR, APLIOS, ASCLEPIOS I,
and ASCLEPIOS II. The final PK-B-cell model was fit to 1486 adults with
relapsing MS (RMS) or relapsing-remitting MS (RRMS), median age 38 years
(range 18-56), median weight 70 kg (range 40.5-171.6), 67.8 % female,
predominantly White (91 %). Median baseline CD19+ B cell count was 200
cells/uL (range 0-1520). Patients across the SC studies received the
licensed regimen of three weekly 20-mg loading doses followed by 20 mg
SC q4w, delivered by prefilled syringe (PFS, n=1320) or autoinjector (AI,
n=141; APLIOS only). The OMS115102 cohort received IV infusions
(100/300/700 mg; the 700-mg arm was excluded from the PK analysis because
of an under-prediction not seen in any other dose). The MIRROR cohort
received SC dose-finding regimens (3-60 mg q12w or 60 mg q4w). PK dataset:
9168 plasma concentrations from 1440 patients (placebo and 700-mg cohorts
excluded). PD dataset: 17,158 CD19+ B-cell counts from all 1486 patients;
ASCLEPIOS B-cell counts were modelled as interval-censored (LLOQ bins of
0/5/15/25 cells/uL). Anti-drug antibody incidence was < 2 % with no
detectable PK or B-cell impact (Yu 2022 Methods "Data" + Table 1, Table 2,
Results "Data").

The full population descriptor is available programmatically:

```{r population}
str(rxode2::rxode2(readModelDb("Yu_2022_ofatumumab"))$meta$population)
```

# Source trace

The per-parameter origin is recorded as an in-file comment next to each
`ini()` entry in `inst/modeldb/specificDrugs/Yu_2022_ofatumumab.R`. The
table below collects equation and parameter provenance in one place.

| Element | Paper value | Stored value | Source location |
|---|---|---|---|
| `ka` (SC absorption rate) | 0.157 /day | 0.157 /day | Table 3 |
| `F` (SC bioavailability) | 0.685 | logit(0.685) | Table 3 |
| `Vc` (central volume) | 2.62 L | 2.62 L | Table 3 |
| `k_e(P)` (complex internalisation) | 1.31 /day | 1.31 /day | Table 3 |
| `CL` (linear free-drug clearance) | 0.34 L/day | 0.34 L/day | Table 3 |
| `Q` (intercompartmental clearance) | 0.358 L/day | 0.358 L/day | Table 3 |
| `Vp` (peripheral volume; FIXED) | 2.8 L | 2.8 L | Table 3 (fixed; Ryman & Meibohm 2017) |
| `R0` (baseline CD20 receptor) | 32.5 nmol/L | 4.8425 mg/L (drug-eq) | Table 3 |
| `ksyn0` (CD20 synthesis at t=0) | 0.985 nmol/L/day | 0.146765 mg/L/day | Table 3 |
| `ksyn_inf` (synthesis at t=inf) | 0.0554 nmol/L/day | 0.0082546 mg/L/day | Table 3 |
| `KD` (binding constant; FIXED) | 0.167 nmol/L | 0.024883 mg/L (drug-eq) | Table 3 (fixed; preclinical) |
| `k_off` (dissociation; FIXED) | 5.53 /day | 5.53 /day | Table 3 (fixed; preclinical) |
| `kdes` (synthesis-decay rate) | 2.58 /year | 2.58 /year | Table 3 |
| `B0` (baseline B cell count) | 194 cells/uL | 194 cells/uL | Table 3 |
| `Emax` (max lysis stimulation) | 159 | 159 | Table 3 |
| `EC50` (lysis 50 % concentration) | 0.0057 mg/L | 0.0057 mg/L | Table 3 |
| `gamma` (Hill exponent) | 2.81 | 2.81 | Table 3 |
| `kout` (B-cell elimination rate) | 0.0124 /day | 0.0124 /day | Table 3 |
| `QB` (B-cell flow; FIXED) | 0.78 L/day | 0.78 L/day | Table 3 (fixed; no IIV) |
| `Vb` (peripheral B-cell volume) | 3.7 L | 3.7 L | Table 3 |
| beta(WT, ka)               | -0.457 | -0.457 | Table 3 |
| beta(WT, Vc)               |  1.2  |  1.2  | Table 3 |
| beta(WT, ksyn0)            | -1.52 | -1.52 | Table 3 |
| beta(WT, CL)               |  1.52 |  1.52 | Table 3 |
| beta(WT, B0)               |  0.271 | 0.271 | Table 3 |
| beta(WT, kout)             | -0.624 | -0.624 | Table 3 |
| beta(AGE, B0)              | -0.282 | -0.282 | Table 3 |
| beta(BLBCELL, Emax)        |  0.275 | 0.275 | Table 3 |
| beta(IV, R0)               |  0.987 | 0.987 | Table 3 |
| beta(IV, CL)               | -1.07 | -1.07 | Table 3 |
| beta(IV, Q)                | -2.31 | -2.31 | Table 3 |
| beta(IV, ksyn_inf)         |  2.49 | 2.49  | Table 3 |
| beta(AI, k_e(P))           |  0.713 | 0.713 | Table 3 |
| beta(AI, R0)               | -0.544 | -0.544 | Table 3 |
| beta(APLIOS, Emax)         |  0.503 | 0.503 | Table 3 |
| beta(MIRROR, kout)         | -0.554 | -0.554 | Table 3 |
| Block 1 IIV (CL, ka, kdes) | rho_ka_cl=-0.294, rho_kdes_cl=0.642, rho_kdes_ka=0.433 | covariances computed from rho * sd_i * sd_j | Table 3 |
| Block 2 IIV (k_e(P), R0, ksyn_inf) | rho_keP_R0=-0.551, rho_ksyninf_R0=0.47, rho_ksyninf_keP=-0.464 | covariances computed | Table 3 |
| Block 3 IIV (Vb, kout, Emax) | rho_Vb_Emax=0.28, rho_kout_Vb=-0.336, rho_kout_Emax=0.423 (typo-corrected) | covariances computed | Table 3 (see Assumptions and deviations) |
| Ofatumumab residual prop. | 0.278 | 0.278 | Table 3 |
| Ofatumumab residual add.  | 0.0316 mg/L | 0.0316 mg/L | Table 3 |
| B-cell residual prop.     | 0.381 | 0.381 | Table 3 |
| B-cell residual add.      | 0.153 cells/uL | 0.153 cells/uL | Table 3 |
| Drug ODEs (depot, central, peripheral, total_target) | n/a | mass-conserving 2-compartment QSS form | Methods "Final Model Description" |
| QSS quadratic for Lc | Lc = 0.5*(Ltot - Rtot - Ks + sqrt(...)) | n/a | Methods "Final Model Description" |
| Time-varying ksyn(t) | ksyn_inf + (ksyn0 - ksyn_inf) exp(-kdes t / 365.25) | n/a | Methods "Final Model Description" |
| B-cell ODEs (B, Bp) | indirect response with peripheral exchange | n/a | Methods "Final Model Description" |
| stim(L) function | Emax L^gamma / (EC50^gamma + L^gamma) | n/a | Methods "Final Model Description" |
| Initial conditions | B(0) = B0, Bp(0) = B0 * Vb / Vc, Rtot(0) = R0 | matched | Methods "Final Model Description" |

# Covariate column naming

| Source column | Canonical column used here |
| --- | --- |
| `WT` (body weight, kg) | `WT` (canonical) |
| `Age` (baseline age, years) | `AGE` (canonical) |
| `Bcell0` (baseline CD19+ B cell count, cells/uL) | `BLBCELL` (newly registered specific-scope) |
| "Admin route = IV" indicator | `ROUTE_IV` (newly registered specific-scope binary) |
| "Formulation = AI" indicator | `DEVICE_AI` (newly registered specific-scope binary) |
| "Study = APLIOS" indicator | `STUDY_APLIOS` (newly registered specific-scope binary) |
| "Study = MIRROR" indicator | `STUDY_MIRROR` (newly registered specific-scope binary) |

# Virtual cohort

Original individual data are not publicly available. We simulate
typical-value scenarios (between-subject variability turned off via
`rxode2::zeroRe()`) for figure replication, and a covariate-stratified
typical-value cohort for the dose-response / weight-effect comparisons in
Figures 4 and 7.

```{r cohort}
mod         <- readModelDb("Yu_2022_ofatumumab")
mod_typical <- rxode2::zeroRe(mod)

# Phase 3 schedule: three weekly loading doses (days 0, 7, 14) followed by
# monthly 20-mg doses from week 4 (day 28) onward. The Yu 2022 paper reports
# steady-state metrics at ~2 years (weeks 104-108) and a B-cell-repletion
# follow-up after dosing stops at 2 years. We dose monthly through week 108
# (day 756) so the inter-dose interval at weeks 104-108 is fully covered for
# the steady-state AUC comparison, then follow for an additional year to see
# the post-treatment B-cell repletion.
loading_days     <- c(0, 7, 14)
maintenance_days <- seq(28, 756, by = 28)
all_dose_days    <- c(loading_days, maintenance_days)
end_followup     <- max(all_dose_days) + 365   # one-year post-last-dose follow-up
```

# Simulation

```{r sim_helper}
# Helper: simulate a typical subject under the phase 3 SC PFS regimen with
# a given dose level and covariate vector, returning Cc and B cell counts.
sim_one <- function(dose_mg, wt = 70, age = 38, bcell = 200,
                    route_iv = 0, device_ai = 0,
                    study_aplios = 0, study_mirror = 0,
                    sample_grid = NULL) {
  if (is.null(sample_grid)) {
    sample_grid <- sort(unique(c(
      seq(0, 90, by = 0.5),
      seq(91, end_followup, by = 1)
    )))
  }
  ev <- rxode2::et(id = 1)
  for (td in all_dose_days) {
    ev <- rxode2::et(ev, amt = dose_mg, cmt = "depot", time = td, id = 1)
  }
  ev <- rxode2::et(ev, time = sample_grid, cmt = "Cc",    id = 1)
  ev <- rxode2::et(ev, time = sample_grid, cmt = "Bcell", id = 1)
  iCov <- data.frame(id = 1, WT = wt, AGE = age, BLBCELL = bcell,
                     ROUTE_IV = route_iv, DEVICE_AI = device_ai,
                     STUDY_APLIOS = study_aplios, STUDY_MIRROR = study_mirror)
  s <- rxode2::rxSolve(mod_typical, ev, iCov = iCov, returnType = "data.frame")
  s[!duplicated(s$time), ]
}
```

# Replicate published figures

## Figure 4 — Dose-response of B cell depletion

Yu 2022 Figure 4 shows simulated B cell counts at 7, 28, 84, 182, 365, and
730 days under the phase 3 dose schedule (three loading doses followed by
monthly maintenance) for doses of 1, 2, 5, 10, 20, and 40 mg. The plot
demonstrates that the 20-mg dose achieves near-complete depletion and that
no further benefit is gained at 40 mg.

```{r figure-4-dose-response, fig.height = 4}
dose_levels <- c(1, 2, 5, 10, 20, 40)
sim_doses <- bind_rows(
  lapply(dose_levels, function(d) {
    sim_one(d) |>
      mutate(dose_mg = d)
  })
)

eval_days <- c(7, 28, 84, 182, 365, 730)
sim_doses_eval <- sim_doses |>
  filter(time %in% eval_days) |>
  mutate(time_label = factor(paste0(time, " d"),
                             levels = paste0(eval_days, " d")))

ggplot(sim_doses_eval,
       aes(factor(dose_mg), Bcell)) +
  geom_point(size = 2, colour = "steelblue") +
  geom_line(aes(group = time_label), colour = "steelblue", alpha = 0.5) +
  facet_wrap(~ time_label, ncol = 3) +
  scale_y_log10() +
  geom_hline(yintercept = 8,  linetype = "dashed", colour = "grey40") +
  geom_hline(yintercept = 40, linetype = "dotted", colour = "grey40") +
  labs(
    x = "Dose (mg, monthly schedule with three weekly loading doses)",
    y = "B cell count (cells/uL, log scale)",
    title   = "Replicates Figure 4 of Yu 2022 (typical-value lines)",
    caption = "Dashed line = B cell target (8 cells/uL); dotted line = LLN (40 cells/uL)."
  )
```

## Figure 5 — Concentration-time profile under the 20 mg monthly regimen

Yu 2022 Figure 5 shows the typical-value drug concentration over the first
year and after the last dose at 2 years for 20 mg SC q4w (with three weekly
loading doses).

```{r figure-5-pk, fig.height = 4}
sim_20mg <- sim_one(20)

ggplot(sim_20mg, aes(time, Cc)) +
  geom_line(colour = "steelblue", linewidth = 0.7) +
  scale_y_log10() +
  labs(
    x = "Time (days)",
    y = "Total ofatumumab concentration (mg/L, log scale)",
    title   = "Replicates Figure 5 of Yu 2022",
    caption = "Typical 70 kg, 38 y subject. Three weekly loading doses (days 0/7/14) then 20 mg q4w."
  )
```

## Figure 6 — B-cell-count profile under the 20 mg monthly regimen

Yu 2022 Figure 6 shows that the 20 mg monthly regimen achieves median B-cell
depletion below 8 cells/uL within ~11 days and that B-cell counts return
toward the LLN of 40 cells/uL by ~23 weeks after dosing stops at 2 years.

```{r figure-6-bcell, fig.height = 4}
ggplot(sim_20mg, aes(time, Bcell)) +
  geom_line(colour = "darkred", linewidth = 0.7) +
  geom_hline(yintercept = 8,  linetype = "dashed", colour = "grey40") +
  geom_hline(yintercept = 40, linetype = "dotted", colour = "grey40") +
  scale_y_log10() +
  labs(
    x = "Time (days)",
    y = "B cell count (cells/uL, log scale)",
    title   = "Replicates Figure 6 of Yu 2022",
    caption = "Dashed line = B cell target (8 cells/uL); dotted line = LLN (40 cells/uL)."
  )
```

```{r figure-6-summary}
# Day at which simulated B cell count first drops below 8 cells/uL.
day_target <- sim_20mg |>
  filter(time > 0, Bcell <= 8) |>
  slice_head(n = 1) |>
  pull(time)
cat(sprintf("Simulated time to B cell <=8 cells/uL: %.1f days (paper: 11 days)\n",
            day_target))

# Days post-last-dose to reach LLN (40 cells/uL) again.
last_dose_day <- max(maintenance_days)
recovery <- sim_20mg |>
  filter(time > last_dose_day, Bcell >= 40) |>
  slice_head(n = 1) |>
  mutate(days_post_last = time - last_dose_day)
cat(sprintf("Simulated days post-last-dose to LLN: %.1f days (paper: ~23 weeks ~= 161 days)\n",
            recovery$days_post_last))
```

## Figure 7 — Steady-state AUC by body weight

Yu 2022 Figure 7 / Table 4 reports the inter-dosing AUC at steady state
(weeks 104-108) by baseline weight: median 33.3 mg.day/L at 70 kg, 71.8 %
higher at 50 kg, and 52.0 % lower at 110 kg.

```{r figure-7-auc, fig.height = 4}
weight_levels <- c(50, 70, 90, 110)
auc_window <- c(104 * 7, 108 * 7)   # weeks 104-108 (steady state, 4-week)

sim_by_wt <- bind_rows(lapply(weight_levels, function(w) {
  s <- sim_one(20, wt = w, sample_grid = sort(unique(c(
    seq(auc_window[1], auc_window[2], by = 0.5),
    auc_window
  ))))
  s |> filter(time >= auc_window[1], time <= auc_window[2]) |>
    mutate(WT = w)
}))

auc_by_wt <- sim_by_wt |>
  group_by(WT) |>
  summarise(
    auc_mg_day_L = sum(diff(time) * (head(Cc, -1) + tail(Cc, -1)) / 2),
    .groups = "drop"
  )
auc_70 <- auc_by_wt |> filter(WT == 70) |> pull(auc_mg_day_L)
auc_by_wt <- auc_by_wt |>
  mutate(pct_vs_70 = (auc_mg_day_L / auc_70 - 1) * 100)

knitr::kable(
  auc_by_wt, digits = 2,
  caption = "Steady-state AUC (weeks 104-108) by body weight (typical-value)."
)

cat(sprintf("Paper Table 4 reference: 50 kg +71.8%%, 110 kg -52.0%% relative to 70 kg.\n"))
cat(sprintf("Simulated:                50 kg %+.1f%%, 110 kg %+.1f%%.\n",
            auc_by_wt$pct_vs_70[auc_by_wt$WT == 50],
            auc_by_wt$pct_vs_70[auc_by_wt$WT == 110]))
```

# PKNCA validation

Yu 2022 reports a steady-state half-life of ~11 days for ofatumumab under
the 20 mg q4w regimen (Results "Concentration-Time (PK) Simulations"). The
TMDD-QSS model is multi-phasic in elimination — once the dose is stopped,
ofatumumab first decays at the apparent slow eigenvalue of the 2-compartment
disposition (~11 days), then accelerates as the receptor pool re-replenishes
and free-drug-mediated TMDD internalisation takes over. The paper's 11 days
corresponds to the first ~60 days of post-last-dose decay (the pre-LLOQ
portion of Figure 5 right panel), which is the regime relevant to clinical
exposure. PKNCA's automatic terminal-phase selection picks the very deepest
tail and so gives a shorter apparent t1/2; we restrict the half-life
calculation to days 14-60 post-last-dose for the paper-comparable window.

```{r pknca}
# Slice 14-60 days post-last-dose to capture the paper-comparable
# elimination phase. PKNCA's `start` and `end` arguments delimit the AUC
# / half-life window.
nca_window <- sim_20mg |>
  filter(time >= last_dose_day + 14, time <= last_dose_day + 60) |>
  transmute(id = 1L,
            time = time - last_dose_day,   # re-zero to last dose
            Cc,
            treatment = "20 mg SC q4w SS -> PFS, days 14-60 post-last-dose")

dose_df <- data.frame(id = 1L, time = 0, amt = 20,
                      treatment = "20 mg SC q4w SS -> PFS, days 14-60 post-last-dose")

conc_obj <- PKNCA::PKNCAconc(nca_window, Cc ~ time | treatment + id)
dose_obj <- PKNCA::PKNCAdose(dose_df, amt ~ time | treatment + id)

intervals <- data.frame(start = 14, end = 60,
                        cmax = TRUE, tmax = TRUE,
                        aucinf.obs = TRUE, half.life = TRUE)
nca_data <- PKNCA::PKNCAdata(conc_obj, dose_obj, intervals = intervals)
nca_res  <- PKNCA::pk.nca(nca_data)

knitr::kable(
  as.data.frame(nca_res), digits = 3,
  caption = "PKNCA summary on the 14-60 day post-last-dose tail of the typical-value simulation."
)
```

```{r consistency}
nca_df <- as.data.frame(nca_res)
hl_row <- nca_df[nca_df$PPTESTCD == "half.life", ]
if (nrow(hl_row) >= 1) {
  cat(sprintf("Simulated apparent t1/2 (days 14-60 post-last-dose): %.2f days (paper: ~11 days)\n",
              as.numeric(hl_row$PPORRES[1])))
}
```

| Quantity | Yu 2022 | Simulated (this vignette) | Discrepancy |
|---|---|---|---|
| Time to median B cell <= 8 cells/uL (20 mg q4w) | 11 days (Results "B Cell Count Simulations") | 11.5 days | +5 % |
| Days post-last-dose to median B cell at LLN (40 cells/uL) | ~23 weeks (~= 161 days) (Results) | ~123 days | -24 % |
| Steady-state apparent t1/2 (20 mg q4w; days 14-60 post-last-dose) | ~11 days (Results "Concentration-Time (PK) Simulations") | ~9.3 days | -16 % |
| AUC change at 50 kg vs 70 kg (steady state, weeks 104-108) | +71.8 % (Table 4) | +69 % | -3 percentage points |
| AUC change at 110 kg vs 70 kg (steady state, weeks 104-108) | -52.0 % (Table 4) | -51 % | +1 percentage point |

# Assumptions and deviations

* **Concentration units and MW conversion.** Drug `central` is in `mg`, so
  `Cc = central / Vc` is natively in `mg/L`. The QSS-TMDD arithmetic
  requires drug, target receptor, and `Ks` to share a single concentration
  scale; the paper's `nmol/L` values for `R0`, `ksyn0`, `ksyn_inf`, and
  `KD` are stored as drug-equivalent `mg/L` using `MW = 149 kDa`:
  - `R0 = 32.5 nmol/L * 0.149 = 4.8425 mg/L`
  - `ksyn0 = 0.985 nmol/L/day * 0.149 = 0.146765 mg/L/day`
  - `ksyn_inf = 0.0554 nmol/L/day * 0.149 = 0.0082546 mg/L/day`
  - `KD = 0.167 nmol/L * 0.149 = 0.024883 mg/L`

  `EC50` is already reported in `mg/L` in Table 3 and is stored unchanged.
  This convention follows `Berends_2019_infliximab.R` and
  `Valenzuela_2025_nipocalimab.R`.
* **Mass-conserving QSS form (vs. paper's literal equations).** Yu 2022's
  printed PK equations write the peripheral and central ODE coefficients
  as `kcp = Q/Vc` and `kpc = Q/Vp` (Methods "Final Model Description"),
  which evaluated literally do not conserve mass when `Vc != Vp` — the
  inflow rate to peripheral implied by the peripheral concentration ODE
  (`Vp * (Q/Vc) * Lc = (Q*Vp/Vc) * Lc`) does not match the outflow from
  central in the central concentration ODE. The standard mass-conserving
  2-compartment form (used by Monolix's TMDD library, against which the
  parameter estimates were obtained) sets the analogous coefficients to
  `Q/Vc` for the central ODE's Lp term and `Q/Vp` for the peripheral
  ODE's Lp term, equivalent to the standard amount-form
  `dAp/dt = Q*(Lc - Lp)`. This file uses the standard mass-conserving
  form. The numerical impact is small in this study (the discrepancy
  scales with `Vp/Vc = 2.8/2.62 = 1.07`, so ~7 % on the affected fluxes)
  and the reported parameter estimates are interpreted as belonging to the
  standard parameterisation.
* **Block 3 IIV typo (Vb / kout / Emax).** Table 3 lists "Corr_kout_Vb"
  twice (-0.336 and 0.423) and is missing a `Corr_kout_Emax` entry,
  although the text describes the block as covering Vb, kout, and Emax —
  three pairwise correlations are expected. The most parsimonious
  interpretation is that the second 0.423 entry is a typo for
  `Corr_kout_Emax`. The implied 3 x 3 correlation matrix
  `[[1, -0.336, 0.28]; [-0.336, 1, 0.423]; [0.28, 0.423, 1]]` is positive
  semidefinite (det approximately 0.855), supporting this reading. The
  model file uses this typo-corrected interpretation.
* **Time-varying `kdeg`.** The paper writes `kdeg = ksyn(t) / R0`, which
  makes the receptor degradation rate time-dependent; the model file
  implements this directly (`kdeg_t <- ksyn_t / r0`). At baseline (no
  drug) this enforces `dRtot/dt = 0` so the receptor compartment holds at
  `R0` until perturbed.
* **Bioavailability handling.** SC bioavailability `F` is logit-transformed
  for IIV per the paper (Methods "Final Model Description"). The model
  applies `F` only to the SC depot via `f(depot) = expit(logit_f)`. For
  IV simulation, dose into the `central` compartment directly; `F` defaults
  to 1 for the central compartment and the `ROUTE_IV = 1` covariate
  switches in the paper's IV-specific effects on `R0`, `CL`, `Q`, and
  `ksyn_inf`. `DEVICE_AI` should be set to 0 for IV subjects (device is
  undefined for IV; route-specific effects are carried by `ROUTE_IV`).
* **Non-canonical compartment names.** `bcell` and `bcell_periph` are not
  in the canonical compartment list (`naming-conventions.md`). They are
  retained because they describe a mechanism-specific B-cell pool that does
  not map onto the standard PK-only compartment nomenclature; the standard
  set (`depot`, `central`, `peripheral1`, `target`, `total_target`) is used
  for the drug and target-receptor side. `checkModelConventions()` raises
  these as warnings (not errors).
* **Race / ethnicity.** Race was tested in the covariate analysis and not
  retained in the final model (Yu 2022 Methods + Results "PKPD Modeling").
  No race covariate is therefore exposed by this model, even though the
  population was predominantly White (91 %).
* **ADA.** Anti-drug-antibody incidence was < 2 % across the pooled
  cohort and had no detectable PK or B-cell impact (Results "Data"); ADA is
  not a covariate in the final model and is not exposed by this file.
* **Missing baseline imputations.** Two participants had missing baseline
  B-cell values (imputed to 200 cells/uL, the cohort median) and two had
  baseline B-cell = 0 (imputed to 1 to avoid log singularities). These are
  per-subject data preprocessing choices; the model itself does not
  re-impute.
* **B-cell repletion timing.** The simulated time post-last-dose for the
  median B-cell count to return to the LLN (40 cells/uL) is ~123 days,
  about 24 % shorter than the paper's quoted ~23 weeks (~161 days). The
  short time to depletion (11.5 days vs 11 days) and the inter-dose
  steady-state AUC by weight (within 3 percentage points of Table 4) match
  closely, so the discrepancy localises to the long-tail repletion phase.
  The likely contributors are the time-varying receptor synthesis rate
  `ksyn(t)` (which slowly decays the kdeg balance after dosing stops) and
  the receptor-pool buffering of free drug at very low concentrations,
  both of which propagate small numerical / parameterisation differences
  into the deep elimination tail. No parameter values were tuned to make
  the repletion-time estimate match.
* **700-mg IV cohort excluded.** The OMS115102 700-mg arm was excluded from
  the PK analysis because of an under-prediction not seen at any other dose
  (Results "Data"). Predictions outside the 100-300 mg IV envelope are
  extrapolations.
* **Dosing schedule.** The figures here use the paper's phase 3 schedule
  (three weekly 20-mg loading doses on days 0/7/14, then 20 mg q4w from
  week 4 for two years). Other regimens (60 mg q12w from MIRROR; 100 or
  300 mg IV from OMS115102) can be simulated by changing the dose-event
  table and setting the route / device covariates accordingly.

# Reference

* `r rxode2::rxode2(readModelDb("Yu_2022_ofatumumab"))$meta$reference`
