Grimm_2023_trontinemab <- function() {
  description <- "Trontinemab PK model in non-human primates (Grimm 2023): two-compartment plasma PK with Michaelis-Menten elimination and brain-region effect-compartment distribution (brain_cerebellum, brain_hippocampus, brain_striatum, brain_cortex, choroid plexus, CSF)."
  reference <- "Grimm HP, Schumacher V, Schafer M, et al. Delivery of the Brainshuttle amyloid-beta antibody fusion trontinemab to non-human primate brain and projected efficacious dose regimens in humans. mAbs. 2023;15(1):2261509. doi:10.1080/19420862.2023.2261509"
  vignette <- "Grimm_2023"
  units <- list(
    time = "h",
    dosing = "mg/kg",
    concentration = "ng/mL"
  )

  # 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(
    central              = list(analyte = "trontinemab", units = NA_character_, specimen = "plasma", verified = FALSE),
    peripheral1          = list(analyte = "trontinemab", units = NA_character_, specimen = "plasma", verified = FALSE),
    brain_cerebellum     = list(analyte = "trontinemab", units = NA_character_, specimen = "tissue", verified = FALSE),
    brain_hippocampus    = list(analyte = "trontinemab", units = NA_character_, specimen = "tissue", verified = FALSE),
    brain_striatum       = list(analyte = "trontinemab", units = NA_character_, specimen = "tissue", verified = FALSE),
    brain_cortex         = list(analyte = "trontinemab", units = NA_character_, specimen = "tissue", verified = FALSE),
    brain_choroid_plexus = list(analyte = "trontinemab", units = NA_character_, specimen = "tissue", verified = FALSE),
    csf                  = list(analyte = "trontinemab", units = NA_character_, specimen = "CSF", verified = FALSE)
  )

  covariateData <- list(
    WT = list(
      description        = "Body weight",
      units              = "kg",
      type               = "continuous",
      reference_category = NULL,
      notes              = "Used for allometric scaling; reference weight 5 kg (cynomolgus monkey). Allometric exponent 0.85 on clearances, 1 on volumes.",
      source_name        = "WT"
    )
  )

  population <- list(
    n_subjects     = "TODO: from source paper",
    n_studies      = "TODO: from source paper",
    age_range      = "TODO: from source paper",
    weight_range   = "TODO: from source paper",
    sex_female_pct = "TODO: from source paper",
    species        = "Cynomolgus monkey (Macaca fascicularis)",
    disease_state  = "Healthy non-human primates (no amyloid pathology)",
    dose_range     = "TODO: from source paper (intravenous dosing, mg/kg)",
    regions        = "Preclinical (non-human primate study)",
    notes          = "Non-human primate (NHP) dataset used to characterize plasma PK and brain-region distribution of trontinemab. Reference body weight 5 kg. Demographic details (exact N, age, weight, sex distribution) TODO: extract from Grimm 2023 methods / supplement."
  )

  ini({
    # Structural plasma PK parameters — Grimm 2023 Table 1 (reference WT = 5 kg)
    lvc <- log(45.4);  label("Central volume of distribution (mL/kg)")                   # Table 1
    lcl <- log(1.01);  label("Clearance (mL/h/kg)")                                      # Table 1
    lvp <- log(63.2);  label("Peripheral volume of distribution (mL/kg)")                # Table 1
    lq  <- log(0.746); label("Intercompartmental clearance (mL/h/kg)")                   # Table 1
    lvmax <- log(78.8);  label("Michaelis-Menten maximum clearance Vmax (mL/h/kg)")        # CLmax from supplement
    lkm <- log(78.6);  label("Michaelis-Menten half-maximal concentration (ng/mL)")      # from supplement

    # Allometric exponents — fixed per Grimm 2023 text on page 11
    e_wt_cl_q <- fixed(0.85); label("Allometric exponent for CL and Q (unitless)")       # page 11
    e_wt_vc_vp <- fixed(1);   label("Allometric exponent for Vc and Vp (unitless)")      # page 11

    # Brain-region effect-compartment parameters — Grimm 2023 supplementary Table 1
    # Cerebellum
    kp_cerebellum   <- 5.17e-3; label("Brain distribution coefficient, brain_cerebellum (unitless)")  # supp. Table 1
    kout_cerebellum <- 0.0624;  label("Brain outflow rate, brain_cerebellum (1/h)")                    # supp. Table 1
    lfpla_cerebellum <- log(1.26e-3); label("Residual plasma fraction, brain_cerebellum (log)")        # supp. Table 1: fpla = 1.26e-3
    etalfpla_cerebellum ~ 1.93                                                                   # supp. Table 1: IIV variance on fpla_cerebellum

    # Hippocampus
    kp_hippocampus   <- 5.59e-3;  label("Brain distribution coefficient, brain_hippocampus (unitless)") # supp. Table 1
    kout_hippocampus <- 0.0433;   label("Brain outflow rate, brain_hippocampus (1/h)")                  # supp. Table 1
    lfpla_hippocampus <- log(0.621e-3); label("Residual plasma fraction, brain_hippocampus (log)")      # supp. Table 1: fpla = 0.621e-3
    etalfpla_hippocampus ~ 1.04                                                                   # supp. Table 1

    # Striatum
    kp_striatum   <- 7.76e-3; label("Brain distribution coefficient, brain_striatum (unitless)")        # supp. Table 1
    kout_striatum <- 0.0371;  label("Brain outflow rate, brain_striatum (1/h)")                         # supp. Table 1
    lfpla_striatum <- log(0.298e-3); label("Residual plasma fraction, brain_striatum (log)")            # supp. Table 1: fpla = 0.298e-3
    etalfpla_striatum ~ 1.96                                                                      # supp. Table 1

    # Cortex
    kp_cortex   <- 4.62e-3; label("Brain distribution coefficient, brain_cortex (unitless)")            # supp. Table 1
    kout_cortex <- 0.0344;  label("Brain outflow rate, brain_cortex (1/h)")                             # supp. Table 1
    lfpla_cortex <- log(0.782e-3); label("Residual plasma fraction, brain_cortex (log)")                # supp. Table 1: fpla = 0.782e-3
    etalfpla_cortex ~ 1.57                                                                        # supp. Table 1

    # Choroid plexus
    kp_choroid_plexus   <- 4.31e-3; label("Brain distribution coefficient, choroid plexus (unitless)") # supp. Table 1
    kout_choroid_plexus <- 0.0318;  label("Brain outflow rate, choroid plexus (1/h)")                  # supp. Table 1
    lfpla_choroid_plexus <- log(18.4e-3); label("Residual plasma fraction, choroid plexus (log)")      # supp. Table 1: fpla = 18.4e-3
    etalfpla_choroid_plexus ~ 1.09                                                                     # supp. Table 1

    # Cerebrospinal fluid (no residual plasma fraction)
    kp_csf   <- 2.34e-3; label("Brain distribution coefficient, cerebrospinal fluid (unitless)")  # supp. Table 1
    kout_csf <- 0.0373;  label("Brain outflow rate, cerebrospinal fluid (1/h)")                   # supp. Table 1
    fpla_csf <- fixed(0); label("Residual plasma fraction, cerebrospinal fluid")                  # supp. Table 1: fpla_csf fixed at 0

    # Residual error — source paper does not report residual error magnitudes; left at 0 as placeholders
    propSd <- 0; label("Proportional residual error, plasma Cc (fraction)")
    addSd  <- 0; label("Additive residual error, plasma Cc (ng/mL)")
  })

  model({
    # Individual plasma PK parameters with allometric scaling to 5 kg
    cl <- exp(lcl + log(WT / 5) * e_wt_cl_q)
    vc <- exp(lvc + log(WT / 5) * e_wt_vc_vp)
    vp <- exp(lvp + log(WT / 5) * e_wt_vc_vp)
    q  <- exp(lq  + log(WT / 5) * e_wt_cl_q)
    vmax <- exp(lvmax)
    km   <- exp(lkm)

    # Individual residual plasma fractions per brain region (log-normal IIV)
    fpla_cerebellum     <- exp(lfpla_cerebellum     + etalfpla_cerebellum)
    fpla_hippocampus    <- exp(lfpla_hippocampus    + etalfpla_hippocampus)
    fpla_striatum       <- exp(lfpla_striatum       + etalfpla_striatum)
    fpla_cortex         <- exp(lfpla_cortex         + etalfpla_cortex)
    fpla_choroid_plexus <- exp(lfpla_choroid_plexus + etalfpla_choroid_plexus)

    # Micro-constants
    kel <- cl / vc
    k12 <- q / vc
    k21 <- q / vp

    # Plasma two-compartment model with parallel linear + Michaelis-Menten elimination
    d/dt(central)     <- -kel * central - central * (vmax / vc) / (1 + (central / vc * 1e6) / km) - k12 * central + k21 * peripheral1
    d/dt(peripheral1) <-  k12 * central - k21 * peripheral1

    # Plasma concentration: unit conversion from mg/kg compartment amount to ng/mL
    Cc <- central / vc * 1e6

    # Brain-region effect compartments — Grimm 2023 page 11
    # Equation 1: dCext/dt = kout * (Kp * Cpla - Cext)
    # Equation 2: Cbrn     = fpla * Cpla + Cext
    d/dt(brain_cerebellum)     <- kout_cerebellum     * (kp_cerebellum     * Cc - brain_cerebellum)
    Cbrain_cerebellum     <- fpla_cerebellum     * Cc + brain_cerebellum

    d/dt(brain_hippocampus)    <- kout_hippocampus    * (kp_hippocampus    * Cc - brain_hippocampus)
    Cbrain_hippocampus    <- fpla_hippocampus    * Cc + brain_hippocampus

    d/dt(brain_striatum)       <- kout_striatum       * (kp_striatum       * Cc - brain_striatum)
    Cbrain_striatum       <- fpla_striatum       * Cc + brain_striatum

    d/dt(brain_cortex)         <- kout_cortex         * (kp_cortex         * Cc - brain_cortex)
    Cbrain_cortex         <- fpla_cortex         * Cc + brain_cortex

    d/dt(brain_choroid_plexus) <- kout_choroid_plexus * (kp_choroid_plexus * Cc - brain_choroid_plexus)
    Cbrain_choroid_plexus <- fpla_choroid_plexus * Cc + brain_choroid_plexus

    d/dt(csf)            <- kout_csf            * (kp_csf            * Cc - csf)
    Cbrain_csf            <- fpla_csf            * Cc + csf

    Cc ~ add(addSd) + prop(propSd)
  })
}
