InsightRX / mipdtrial

Tools for simulating model-informed precision dosing trials
https://insightrx.github.io/mipdtrial/
Other
2 stars 0 forks source link

Model-based initial regimen for trough targets #12

Open jasmineirx opened 1 week ago

jasmineirx commented 1 week ago

This draft PR is one proposed approach to allow model-based starting doses when the target is a trough.

Due to the way we anchor sampling times for troughs here:

https://github.com/InsightRX/mipdtrial/blob/main/R/get_sampling_times_from_schema.R#L44-L45

We need to have one more dose than otherwise anticipated. One option is to add an additional dose. This works fine for continuous dosing modules (i.e., the expected time/day will be "sampled" to determine target attainment) however it won't work for fixed dosing (busulfan, etc). On the other hand, fixed dosing never targets a trough concentration, since that doesn't really make sense.

Alternatively, we could do some magic with the get_sampling_times_from_scheme function, but I think the logic would be a little more complicated?

  else if(row$base %in% c("trough", "cmin")) {
    # take associated dosing interval if possible, otherwise take prev dosing interval
    # otherwise assume 24
    if (length(regimen$dose_times) > dose_anchor) {
      intv <- diff(regimen$dose_times[dose_anchor:(dose_anchor+1)] 
    } else if (dose_anchor > 1) {
      intv <- diff(regimen$dose_times[(dose_anchor-1):dose_anchor] 
    } else {
      intv <- 24
    }
    t_anchor <- regimen$dose_times[dose_anchor] + intv
  }

Currently, it is not possible to use cmin as a target with a model-based starting dose since there are always insufficient doses in the regimen.

roninsightrx commented 1 week ago

I'm not sure I fully follow. Currently we are able to target Cmin for TDM-based adjustments. Why wouldn't we be able to do it for the initial dose? Can't we just take as the time of simulation: t_last_dose + interval?

jasmineirx commented 1 week ago

I have a minimal reproducible example here, maybe I am doing something wrong but it does not work. If you install my branch, it will work as anticipated.

library(mipdtrial) # works with load_all() dev version on branch
library(pkvancothomson)

# Trial design
tdm_design <- create_sampling_design(
  offset = c(0.75, 12, 0.75, 12),
  at = c(3, 3, 6, 6),
  anchor = "dose"
)

update_design <- create_regimen_update_design(
  at = 4,
  anchor = "dose",
  dose_optimization_method = map_adjust_dose
)
target_design <- create_target_design(
  targettype = "cmin",
  targetmin = 5,
  targetmax = 10,
  at = 8,
  anchor = "day"
)

initial_method <- create_initial_regimen_design(
  method = model_based_starting_dose,
  regimen = list(
    interval = 12,
    type = "infusion",
    t_inf = 0.5
  ),
  settings = list(
    auc_comp = 3,
    dose_resolution = 50,
    dose_grid = c(50, 5000, 50)
  )
)

model_pub <- create_model_design(
  model = pkvancothomson::model(),
  omega_matrix = pkvancothomson::omega_matrix(),
  parameters = pkvancothomson::parameters(),
  ruv = pkvancothomson::ruv()
)

trial1 <- create_trial_design(
  sampling_design = tdm_design,
  target_design = target_design,
  regimen_update_design = update_design,
  initial_regimen_design = initial_method,
  sim_design = model_pub, est_design = model_pub
)

# run trial
set.seed(15)
dat <- data.frame(
  ID = 1:100,
  weight = rnorm(100, 90, 25),               # kg, normally distributed
  crcl = exp(rnorm(100, log(6), log(1.6))),  # L/hr, log-normally distributed
  CL_HEMO = 0
)
cov_map <- c(
  WT = "weight",
  CRCL = "crcl",
  CL_HEMO = "CL_HEMO"
)
res1 <- run_trial(data = dat, design = trial1, cov_mapping = cov_map, seed = 15)
#> Error in get_sampling_time_core(scheme[i, ], regimen): Not enough doses in regimen to update, please increase initial regimen length. For `cmin`, `middle`, or `random` calculation, you will need one more dose in the regimen than the dose for which the `cmin` is calculated.

Created on 2024-11-18 with reprex v2.1.1

jasmineirx commented 1 week ago

we can change the sampling time function instead. i gave some example code for that in my PR description

  else if(row$base %in% c("trough", "cmin")) {
    # take associated dosing interval if possible, otherwise take prev dosing interval
    # otherwise assume 24
    if (length(regimen$dose_times) > dose_anchor) {
      intv <- diff(regimen$dose_times[dose_anchor:(dose_anchor+1)] 
    } else if (dose_anchor > 1) {
      intv <- diff(regimen$dose_times[(dose_anchor-1):dose_anchor] 
    } else {
      intv <- 24
    }
    t_anchor <- regimen$dose_times[dose_anchor] + intv
  }
mccarthy-m-g commented 1 week ago

I have a minimal reproducible example here, maybe I am doing something wrong but it does not work.

I was able to replicate the error, and can confirm your branch fixes the error.

we can change the sampling time function instead. i gave some example code for that in my PR description

All the if-else statements in get_sampling_time_core make it hard to read and follow already, so adding more would only make that worse. If we change this function instead of going with your proposed approach, it might be nice to do some cleanup for readability (e.g., by wrapping the separate if-else statements into helper functions, using switch, etc.).