Ibrahim_2023_ibrutinib_sbp <- function() {
  description <- paste(
    "Ibrutinib-induced systolic blood pressure (sBP) turnover model in patients with chronic lymphocytic leukemia,",
    "from the phase Ib/II PCYC-1102 study. A zero-order production / first-order loss turnover model preceded by a",
    "single transit compartment reproduces the slow onset of ibrutinib-associated hypertension; ibrutinib stimulates",
    "the zero-order sBP production rate through an Emax function of the daily AUC(0-24). The transit rate constant",
    "and the turnover rate constant are equal, both set to (n + 1) / MTT with n = 1 transit compartment. Baseline age",
    "lowers the mean transit time (older patients reach the new steady state faster). Ibrutinib enters only through",
    "the time-varying covariate AUC_IBRU; there are no drug-dosing events in this model. Sister model files from the",
    "same paper: modellib('Ibrahim_2023_ibrutinib_dbp'), modellib('Ibrahim_2023_ibrutinib_leukocyte_spd'),",
    "modellib('Ibrahim_2023_ibrutinib_competing_risk')."
  )
  reference <- paste(
    "Ibrahim EIK, Karlsson MO, Friberg LE.",
    "Assessment of ibrutinib scheduling on leukocyte, lymph node size and blood pressure dynamics in chronic",
    "lymphocytic leukemia through pharmacokinetic-pharmacodynamic models.",
    "CPT Pharmacometrics Syst Pharmacol. 2023;12(9):1305-1318.",
    "doi:10.1002/psp4.13010.",
    "Open Access under CC BY-NC.",
    "Structural equations from main-text equations 2 and 3; parameter values from the authors' own nlmixr control",
    "stream (Supporting Information S4, run200) cross-checked against Table 2.",
    sep = " "
  )
  vignette <- "Ibrahim_2023_ibrutinib"
  units <- list(
    time          = "day",
    dosing        = "n/a (no drug-dosing events; ibrutinib exposure enters as the time-varying covariate AUC_IBRU)",
    concentration = "systolic blood pressure in mmHg (not a drug concentration)"
  )

  # Issue #482: what each ODE state holds, in what amount units, in what
  # biological matrix. analyte/specimen proposed by a local model from the
  # model description; units derived from the units block. verified = FALSE
  # means NOT checked against the source paper.
  compartmentData <- list(
    transit1 = list(analyte = "ibrutinib", units = NA_character_, specimen = "administration site", verified = FALSE),
    sbp      = list(analyte = "systolic blood pressure", units = NA_character_, specimen = "blood cell", verified = FALSE)
  )

  covariateData <- list(
    AUC_IBRU = list(
      description        = "Daily 0-24 h area under the ibrutinib plasma concentration-time curve, AUC(0-24).",
      units              = "h*ng/mL",
      type               = "continuous",
      reference_category = NULL,
      notes              = paste(
        "Time-varying: the value tracks the patient's current daily ibrutinib dose level and drops to 0 during",
        "treatment interruptions. Ibrutinib enters this model ONLY through this column -- the model contains no drug",
        "compartment and no dosing events. Ibrahim 2023 derived per-subject AUC(0-24) by integrating the individual",
        "post hoc profiles of the two-compartment ibrutinib population PK model of Marostica et al. (Cancer Chemother",
        "Pharmacol. 2015;75(1):111-121), which is NOT part of nlmixr2lib. Enters the sBP-production stimulation Emax",
        "function as Emax * AUC_IBRU / (AUC50 + AUC_IBRU) with AUC50 = 91.7 h*ng/mL (Ibrahim 2023 Table 2) -- about",
        "three times the corresponding IAUC50 of the pBtk efficacy model (34.1 h*ng/mL), which is why the paper's",
        "de-escalation schedules lose less efficacy than hypertension risk."
      ),
      source_name        = "DAILYAUC"
    ),
    AGE = list(
      description        = "Baseline age.",
      units              = "years",
      type               = "continuous",
      reference_category = NULL,
      notes              = paste(
        "Time-fixed per subject (baseline value). Enters the mean transit time in power form",
        "mtt = exp(lmtt_sbp + etalmtt_sbp + e_age_mtt_sbp * log(AGE / 63)), equivalently",
        "MTT_sBP = 79.9 * (AGE / 63)^-5.04, with reference age 63 years (Ibrahim 2023 Table 2 footnote c:",
        "MTTsBP = e^(LN(79.9) - 5.04 * LN(Age/63))). The population mean baseline age was 62.4 (SD 9.9) years",
        "(Supplementary Table S1). The exponent is large, so MTT_sBP is strongly age-sensitive: older patients reach",
        "the ibrutinib-elevated sBP steady state substantially faster (Ibrahim 2023 Discussion)."
      ),
      source_name        = "LNAGE"
    )
  )

  population <- list(
    species        = "human",
    n_subjects     = 120L,
    n_studies      = 1L,
    age_range      = "mean 62.4 (SD 9.9) years",
    weight_range   = "mean 82.3 (SD 17) kg",
    sex_female_pct = 24.2,
    race_ethnicity = NULL,
    disease_state  = "Chronic lymphocytic leukemia (CLL); 20.8% treatment-naive, 79.2% relapsed/refractory",
    dose_range     = "ibrutinib 420 mg once daily (n = 94) or 840 mg once daily (n = 38) in PCYC-1102",
    regions        = "United States (PCYC-1102, phase Ib/II)",
    notes          = paste(
      "Baseline demographics from Ibrahim 2023 Supplementary Table S1. The blood-pressure dataset contained 2413",
      "paired sBP and dBP measurements (Ibrahim 2023 Appendix S1 section 1). At baseline 10.2% of patients had",
      "sBP >= 140 mmHg; after 2 years of the approved 420 mg/day schedule the model predicted 44.7%",
      "(Ibrahim 2023 Results 'Evaluation of the de-escalation dosing schedules'). The effect of antihypertensive",
      "drugs was tested as a time-varying binary covariate but was NOT retained in the final model",
      "(Ibrahim 2023 Patients and Methods 'PK-blood pressure model'). Estimation used FOCEI in nlmixr 2.0.6."
    )
  )

  covariatesDataExcluded <- list(
    CONMED_ANTIHYPERTENSIVE = list(
      description = "Antihypertensive co-medication indicator.",
      units       = "(binary)",
      type        = "binary",
      notes       = paste(
        "Screened but NOT retained in the final model. Ibrahim 2023 Patients and Methods 'PK-blood pressure model'",
        "tested the effect of antihypertensive drugs as a time-varying binary covariate, 'either as a step function",
        "or as a function in which the antihypertensive effect gradually evolved'; neither form survived the",
        "backward-elimination criterion and no coefficient is reported, so no value can be encoded."
      )
    ),
    SEXF = list(
      description = "Subject sex indicator: 1 = female, 0 = male.",
      units       = "(binary)",
      type        = "binary",
      notes       = paste(
        "Screened but NOT retained in the final sBP model. Ibrahim 2023 Patients and Methods 'Covariate analysis'",
        "evaluated baseline age and gender in the blood pressure and competing risk models; only the age effect on",
        "MTT_sBP was retained (Table 2). No coefficient is reported for sex."
      )
    )
  )

  ini({
    # ------------------------------------------------------------------
    # All log-scale THETA values are the final estimates taken verbatim
    # from the authors' own nlmixr control stream (Ibrahim 2023 Supporting
    # Information S4, run200), which carries more significant figures than
    # the rounded back-transformed values printed in Table 2. Every value
    # below back-transforms to its Table 2 row.
    # ------------------------------------------------------------------
    lrbase_sbp <- 4.83995310
    label("Log baseline systolic blood pressure (mmHg)")  # S4 run200 tsbpbas = 4.83995310 -> 126.5; Table 2 sBPbaseline = 126 (95% CI 124-129)
    lmtt_sbp   <- 4.38126172
    label("Log mean transit time of the sBP transit/turnover chain (day)")  # S4 run200 tmtt = 4.38126172 -> 79.9; Table 2 MTTsBP = 79.9 (95% CI 67.3-94.9)
    lemax_sbp  <- -2.17877709
    label("Log maximum fractional ibrutinib stimulation of sBP production (unitless)")  # S4 run200 temax = -2.17877709 -> 0.113; Table 2 Emax,sBP = 0.113 (95% CI 0.092-0.139)
    lauc50_sbp <- 4.51798998
    label("Log daily AUC(0-24) giving 50% of the maximum sBP stimulation (h*ng/mL)")  # S4 run200 tec50 = 4.51798998 -> 91.7; Table 2 AUC50,sBP = 91.7 (95% CI 42.1-200)

    e_age_mtt_sbp <- -5.03804114
    label("Power coefficient of baseline age (referenced to 63 years) on the sBP mean transit time")  # S4 run200 eff_age_mtt = -5.03804114; Table 2 'Coefficient of baseline age effect on MTTsBP' = -5.04 (95% CI -6.07 to -4)

    ntransit_sbp <- fixed(2)
    label("(n + 1) with n = 1 transit compartment; ktr = kout = ntransit_sbp / MTT (unitless)")  # S4 run200 nn = 2; Ibrahim 2023 main text 'ktr,iBP = (n + 1) / MTTiBP' with a single transit compartment

    # --- IIV ($OMEGA variances, S4 run200) ------------------------------
    # Table 2 reports these as CV% via CV = sqrt(exp(omega^2) - 1); the
    # control stream reports the variances directly, which is what ini()
    # needs, so the variances are used here.
    etalrbase_sbp ~ 0.006833436  # S4 run200 eta.sbpbas; Table 2 sBPbaseline CV% = 8.28
    etalmtt_sbp   ~ 0.9173332    # S4 run200 eta.mtt;    Table 2 MTTsBP CV% = 123
    etalemax_sbp  ~ 0.239243     # S4 run200 eta.emax;   Table 2 Emax,sBP CV% = 52

    # --- residual error --------------------------------------------------
    # Table 2 footnote d: 'Additive residual unexplained variability (RUV)
    # model was implemented on log transformed data'. The authors' code
    # writes `sbp_ipred = log(sbp + 1E-6); sbp_ipred ~ add(add.sd1)`.
    # Additive-on-log is exactly nlmixr2's `lnorm()` residual, so the output
    # stays in mmHg and carries a log-normal residual instead of being
    # emitted on the log scale.
    expSd_sbp <- 0.08438139
    label("Log-scale (log-normal) residual error SD for systolic blood pressure (unitless on the log scale)")  # S4 run200 add.sd1 = 0.08438139; Table 2 'RUV sBP (%) = 8.4'
  })

  model({
    # ------------------------------------------------------------------
    # 1. Individual parameters. Baseline age enters MTT in power form
    #    (Ibrahim 2023 Table 2 footnote c; reference age 63 years).
    # ------------------------------------------------------------------
    sbpbase   <- exp(lrbase_sbp + etalrbase_sbp)
    mtt_sbp   <- exp(lmtt_sbp + etalmtt_sbp + e_age_mtt_sbp * log(AGE / 63))
    emax_sbp  <- exp(lemax_sbp + etalemax_sbp)
    auc50_sbp <- exp(lauc50_sbp)

    # ------------------------------------------------------------------
    # 2. Derived rate constants. The turnover rate constant was assumed
    #    equal to the transit rate constant (Ibrahim 2023 main text,
    #    'PK-blood pressure model' paragraph).
    # ------------------------------------------------------------------
    ktr_sbp  <- ntransit_sbp / mtt_sbp
    kout_sbp <- ktr_sbp
    kin_sbp  <- sbpbase * kout_sbp

    # Emax stimulation of the zero-order sBP production rate.
    effauc <- emax_sbp * AUC_IBRU / (auc50_sbp + AUC_IBRU)

    # ------------------------------------------------------------------
    # 3. ODE system (Ibrahim 2023 equations 2 and 3).
    # ------------------------------------------------------------------
    d/dt(transit1) <- kin_sbp * (1 + effauc) - ktr_sbp * transit1
    transit1(0)    <- sbpbase

    d/dt(sbp) <- ktr_sbp * transit1 - kout_sbp * sbp
    sbp(0)    <- sbpbase

    # ------------------------------------------------------------------
    # 4. Observation. `sbp` is the registered canonical systolic-blood-
    #    pressure PD state and is itself the observation variable, mirroring
    #    the diastolic sibling `dbp`.
    # ------------------------------------------------------------------
    sbp ~ lnorm(expSd_sbp)
  })
}
