Gong_2023_pemigatinib_phosphate <- function() {
  description <- paste(
    "Exposure-response Emax model relating steady-state pemigatinib",
    "exposure to the mean change from baseline in serum phosphate",
    "concentration at cycle 1 day 8 and cycle 1 day 15, in 300 patients",
    "receiving pemigatinib monotherapy across FIGHT-101, FIGHT-102, and",
    "FIGHT-202 (Gong 2023). Pemigatinib inhibits FGFR1-3; FGFR1 blockade",
    "attenuates FGF23 signalling in the renal proximal tubule, reducing",
    "urinary phosphate excretion, so the exposure-dependent rise in serum",
    "phosphate is an on-target class effect that the authors use as a",
    "pharmacodynamic surrogate for pemigatinib exposure. The model is the",
    "paper's three-parameter direct-effect Emax function of the",
    "per-subject steady-state AUC over the 24 h dosing interval, with",
    "baseline serum phosphate entering as an additive covariate:",
    "change = Emax * AUC_PEMI / (EC50 + AUC_PEMI) + coef * baseline, with",
    "Emax = 5.51 mg/dL, EC50 = 1665 h*nM, and coef = -0.185 per mg/dL",
    "(carried as -0.5730 per mmol/L against the SI-canonical PHOS",
    "column). It carries no ODE state -- the exposure metric AUC_PEMI is",
    "supplied as a static covariate derived from the companion population",
    "PK model (see modellib('Gong_2023_pemigatinib')), mirroring the",
    "authors' workflow of simulating a dense steady-state post hoc",
    "profile in NONMEM, deriving AUCss noncompartmentally, and regressing",
    "the biomarker on it in SAS. The endpoint is reported in the paper's",
    "mg/dL. The fitted EC50 of 1665 h*nM approximates the mean AUC0-24h",
    "at 8 mg once daily, which is the basis of the paper's claim that",
    "serum phosphate can serve as an exposure surrogate.",
    sep = " "
  )
  reference <- paste(
    "Gong X, Akil A, Ndi A, Ji T, Liu X, Lovern M, Chen X. (2023).",
    "Population pharmacokinetic and exposure-response analyses of",
    "pemigatinib in patients with advanced solid tumors including",
    "cholangiocarcinoma.",
    "CPT Pharmacometrics Syst Pharmacol 12(11):1784-1794.",
    "doi:10.1002/psp4.13064.",
    "Parameter estimates are Table S2 of Appendix S1 (Supporting",
    "Information), 'Serum phosphate concentration' block. Exposure",
    "covariate AUC_PEMI is generated by the companion population PK",
    "model; see modellib('Gong_2023_pemigatinib')."
  )
  vignette <- "Gong_2023_pemigatinib"
  # The single output is an algebraic change-from-baseline endpoint, not a
  # drug concentration and not an ODE state, so it has no canonical
  # compartment name. Declared here so checkModelConventions() treats it as a
  # documented paper-mechanistic output rather than a naming deviation. The
  # sibling model Gong_2023_pemigatinib_creatinine uses the same convention
  # (operator decision, sidecar request 001 q2: keep the paper-named form).
  paper_specific_compartments <- c("phosChange")
  units    <- list(time = "h", dosing = "mg", concentration = "nM")

  covariateData <- list(
    AUC_PEMI = list(
      description        = "Per-subject steady-state pemigatinib AUC over the 24 h dosing interval",
      units              = "h*nM",
      type               = "continuous",
      reference_category = NULL,
      notes              = paste(
        "Static (time-fixed) drug-exposure covariate. Gong 2023 Methods",
        "'Exposure-response evaluation': NONMEM 7.5 was used to simulate a",
        "dense steady-state post hoc concentration-time profile for each",
        "patient using the updated population PK model, and AUCss was",
        "derived from it by noncompartmental methods; the exposure-response",
        "regressions were then run in SAS 9.4 on those per-subject AUCss",
        "values. Reference values from the paper: the mean AUCss at the",
        "13.5 mg once-daily dose is 2850 h*nM (Results, 'Exposure-response",
        "analysis of efficacy'); the fitted EC50 of 1665 h*nM 'approximates",
        "the mean area under the plasma concentration-time curve from",
        "0-24 h from 8 mg q.d. pemigatinib' (Results, 'Exposure-response",
        "analysis of safety'); the observed AUCss quartile boundaries in the",
        "CCA efficacy population were 817, 1828, 2351, 3104, and 8446 h*nM",
        "(Figure 3b). Set AUC_PEMI = 0 to recover the untreated condition,",
        "where the Emax term vanishes."
      ),
      source_name        = "AUCss"
    ),
    PHOS = list(
      description        = "Baseline serum phosphate concentration",
      units              = "mmol/L",
      type               = "continuous",
      reference_category = NULL,
      notes              = paste(
        "Time-fixed pretreatment value. Gong 2023 Methods,",
        "'Exposure-response evaluation': 'Serum phosphate at baseline was",
        "entered into the model as a covariate.' It is the third parameter",
        "of the paper's 'three-parameter maximum-exposure (Emax) nonlinear",
        "model' and enters additively and uncentered, so the fitted",
        "coefficient is the absolute change in the endpoint per unit of",
        "baseline. Gong 2023 reports the value in mg/dL; the canonical",
        "column is SI mmol/L, so the published coefficient of -0.185 per",
        "mg/dL is carried in ini() rescaled to -0.5730 per mmol/L",
        "(1 mmol/L = 3.0975 mg/dL for elemental phosphorus, atomic mass",
        "30.974 g/mol). The endpoint itself is left in the paper's mg/dL so",
        "that Table S2's Emax and every published anchor stay usable",
        "verbatim. Gong 2023 does not tabulate baseline serum phosphate in",
        "Table 1; the adult clinical reference range is roughly",
        "2.5-4.5 mg/dL (0.81-1.45 mmol/L). Baseline serum phosphate was",
        "also a significant positive predictor of clinically notable",
        "hyperphosphatemia in the paper's separate logistic regression",
        "(odds ratio 2.46, 95% CI 1.32-4.55 for a 50% increase); that",
        "logistic model is not packaged because its intercept is not",
        "reported."
      ),
      source_name        = "PHOS (in mg/dL; convert to canonical mmol/L by multiplying by 0.3229)"
    )
  )

  population <- list(
    species       = "human",
    n_subjects    = 300,
    n_studies     = 3,
    disease_state = paste(
      "Patients with advanced malignancies receiving pemigatinib",
      "monotherapy, pooled across FIGHT-101, FIGHT-102, and FIGHT-202."
    ),
    dose_range    = "1-20 mg orally once daily (continuous and 2-weeks-on / 1-week-off regimens)",
    endpoint      = paste(
      "Change from baseline in mean serum phosphate concentration, where",
      "the on-treatment value is the mean of cycle 1 day 8 (C1D8) and",
      "cycle 1 day 15 (C1D15). Serum phosphate was measured as part of a",
      "comprehensive serum chemistry assessment in FIGHT-101, FIGHT-102,",
      "and FIGHT-202 (Gong 2023 Methods, 'Studies and end points')."
    ),
    notes         = paste(
      "The same 300-patient monotherapy pool was used for the companion",
      "serum-creatinine exposure-response analysis",
      "(see modellib('Gong_2023_pemigatinib_creatinine')). Gong 2023",
      "Discussion frames the phosphate rise as an on-target consequence of",
      "FGFR inhibition and uses it as a surrogate for pemigatinib",
      "exposure; the observed quartile boundaries of the change from",
      "baseline at 13.5 mg once daily were 0.5, 2.1, 2.7, 3.5, and",
      "6.3 mg/dL in the 108-patient cholangiocarcinoma efficacy population",
      "(Figure 3a)."
    )
  )

  ini({
    # ---------------------------------------------------------------------
    # Gong 2023 Table S2 (Appendix S1), 'Serum phosphate concentration'
    # block. This is the paper's "three-parameter maximum-exposure (Emax)
    # nonlinear model" (Methods, 'Exposure-response evaluation'): Emax,
    # EC50, and a coefficient on baseline serum phosphate. Unlike the
    # sibling creatinine model, this endpoint is an ABSOLUTE change in
    # mg/dL, not a percentage change.
    # ---------------------------------------------------------------------
    lemax <- log(5.51)  ; label("Maximum change from baseline in serum phosphate attributable to pemigatinib (mg/dL)")   # Gong 2023 Table S2: Emax 5.51 mg/dL, approximate SE 0.368, 95% CL 4.79-6.23
    lec50 <- log(1665)  ; label("Steady-state pemigatinib AUC producing half-maximal phosphate change (h*nM)")           # Gong 2023 Table S2: EC50 1665 h*nM, approximate SE 357, 95% CL 963-2367

    # ---------------------------------------------------------------------
    # Baseline-phosphate coefficient. Published as -0.185 per mg/dL; the
    # canonical PHOS column is SI mmol/L, so the coefficient is rescaled by
    # the mg/dL-per-mmol/L factor 3.0975 (elemental phosphorus, atomic mass
    # 30.974 g/mol): -0.185 * 3.0975 = -0.5730 mg/dL per mmol/L. This is
    # the same treatment ALB receives in Chen_2021_lorlatinib. The endpoint
    # stays in the paper's mg/dL, so the coefficient's units are
    # (mg/dL of endpoint) per (mmol/L of baseline).
    #
    # The additive (rather than multiplicative) form is fixed by the
    # paper's own prose: "For every 1-mg/dL increase in baseline serum
    # phosphate level, the reduction from baseline was less than or equal
    # to 0.185 mg/dL" -- a constant absolute offset, independent of
    # exposure. A multiplicative form would instead scale with the Emax
    # term and would give a 1.23 mg/dL rise at the 13.5 mg dose against the
    # paper's reported median of about 2.7 mg/dL. See the vignette.
    # ---------------------------------------------------------------------
    e_phos_base <- -0.5730 ; label("Additive effect of baseline serum phosphate on the change from baseline (mg/dL per mmol/L)")   # Gong 2023 Table S2: -0.185 (mg/dL)^-1, approximate SE 0.0812, 95% CL -0.345 to -0.0250; rescaled -0.185 * 3.0975

    # ---------------------------------------------------------------------
    # Residual error. Gong 2023 Figure 2 plots simulated 5th and 95th
    # percentiles around the mean phosphate curve, so the fitted model did
    # carry a residual-variability term, but neither Table S2 nor the main
    # text reports its magnitude. Per the standing convention for
    # unreported variability with structural values present, it is encoded
    # as fixed(0) rather than invented, and the gap is recorded in the
    # vignette's Assumptions and deviations section. The model as shipped
    # is therefore a typical-value (deterministic) predictor.
    # ---------------------------------------------------------------------
    addSd_phosChange <- fixed(0) ; label("Additive residual SD on the serum phosphate change from baseline (mg/dL) -- not reported by the source")   # Gong 2023: magnitude not reported in Table S2 or main text; see vignette Errata
  })

  model({
    # -------------------------------------------------------------------
    # Direct-effect Emax on the static steady-state exposure metric, plus
    # the additive baseline-phosphate term (Gong 2023 Methods,
    # 'Exposure-response evaluation'; Table S2). No ODE state: the
    # response is an algebraic function of AUC_PEMI and PHOS, exactly as
    # the authors fitted it. Setting AUC_PEMI = 0 removes the drug effect
    # and leaves only the baseline term.
    # -------------------------------------------------------------------
    emax <- exp(lemax)
    ec50 <- exp(lec50)

    phosChange <- emax * AUC_PEMI / (ec50 + AUC_PEMI) + e_phos_base * PHOS

    phosChange ~ add(addSd_phosChange)
  })
}
