Conversation
Add BestDose dose optimization feature ported from Pmetrics_rust bestdose branch: - R/PM_bestdose.R: PM_bestdose and PM_bestdose_problem R6 classes for Bayesian dose optimization with support for concentration and AUC targets - src/rust/src/bestdose_executor.rs: Rust backend for BestDose optimization using pmcore's BestDoseProblem with ODE model support - Updated lib.rs with bestdose, bestdose_prepare, bestdose_optimize exports - Updated extendr-wrappers.R with R-side wrapper functions - Updated NAMESPACE with PM_bestdose, PM_bestdose_problem, bestdose exports - Bumped pmcore dependency from 0.21.1 to 0.22.1 (required for bestdose) - Added libloading dependency for dynamic model loading - Added bestdose example data (past, prior, target CSVs) and test script - Fixed executor.rs mutability issue for pmcore 0.22.1 compatibility
Reworked bd and bd_post R6 classes: bd_post$optimize() now returns a bd object, and bd$new() supports one-shot usage. Removed dead Rust code (bestdose(), bestdose_ode(), bestdose_analytical()). Fixed bias_weight being NULL and print() breaking with variable dose counts. Updated PMcore dep to use relative time_offset gap semantics.
- Combine clean one-shot/two-stage API with inline future=list(...) support - Add top-5 weighted plot curves, triangle dose indicators, plot() method - Fix .sim_future() dose recycling when past doses are present
…sed most of the logs for bestdose, needs more work
There was a problem hiding this comment.
Pull request overview
This PR delivers a broad cleanup + feature update across the R package and Rust backend, including removal of legacy/vignette assets, additions for BestDose reporting, new user options (date formatting), improved model comparison highlighting, and updated Rust logging/dependencies.
Changes:
- Adds BestDose HTML report template and expands user-configurable options (notably
date_format) plus helpers to fetch/download latest R release. - Updates model comparison “best metric” selection/highlighting and refines simulation/model APIs (
quiet, digits handling, arg validation). - Updates Rust backend (pmcore bump, logging defaults, minor executor/settings changes) and removes large amounts of archived/legacy material and old vignette resources.
Reviewed changes
Copilot reviewed 57 out of 88 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| vignettes/Styles/style_old.css | Removed legacy vignette stylesheet. |
| vignettes/Styles/style.css | Removed vignette stylesheet. |
| vignettes/Images/unibv40.png | Vignette image asset update. |
| vignettes/Images/schemaTop.png | Vignette image asset update. |
| vignettes/Images/rust-logo-64x64.png | Vignette image asset update. |
| vignettes/Images/pta2.png | Vignette image asset update. |
| vignettes/Images/pta1.png | Vignette image asset update. |
| vignettes/Images/plotBrowser.png | Vignette image asset update. |
| vignettes/Images/multi-bv40.png | Vignette image asset update. |
| vignettes/Images/model_builder/secondary.png | Vignette image asset update. |
| vignettes/Images/model_builder/primary.png | Vignette image asset update. |
| vignettes/Images/model_builder/output2.png | Vignette image asset update. |
| vignettes/Images/model_builder/output.png | Vignette image asset update. |
| vignettes/Images/model_builder/lag.png | Vignette image asset update. |
| vignettes/Images/model_builder/front.png | Vignette image asset update. |
| vignettes/Images/model_builder/eqn.png | Vignette image asset update. |
| vignettes/Images/model_builder/covariates.png | Vignette image asset update. |
| vignettes/Images/installPkg.png | Vignette image asset update. |
| vignettes/Images/export.png | Vignette image asset update. |
| vignettes/Images/downloadPNG.png | Vignette image asset update. |
| vignettes/Images/Slide2.png | Vignette image asset update. |
| vignettes/Images/Slide1.png | Vignette image asset update. |
| vignettes/Images/Rlogo.png | Vignette image asset update. |
| vignettes/Images/Pmetrics_logo.png | Vignette image asset update. |
| vignettes/Data/reserved.csv | Removed vignette data table. |
| vignettes/Data/mdata.csv | Removed vignette data example. |
| vignettes/Data/fortran2.csv | Removed vignette reference table. |
| vignettes/Data/fortran1.csv | Removed vignette reference table. |
| vignettes/Data/RLcomp_valid.csv | Removed vignette comparison table. |
| vignettes/Data/RLcomp_other.csv | Removed vignette comparison table. |
| vignettes/Data/RLcomp_data.csv | Removed vignette comparison table. |
| vignettes/Data/R6_Legacy_compare.xlsx | Vignette spreadsheet asset update. |
| vignettes/Data/PM_result_methods.csv | Removed vignette data table. |
| vignettes/Data/PM_result_fields.csv | Removed vignette data table. |
| vignettes/Data/PM_result.xlsx | Vignette spreadsheet asset update. |
| vignettes/Data/ObjectsR6.csv | Removed vignette data table. |
| vignettes/Data/ObjectsLegacy.csv | Removed vignette data table. |
| vignettes/Citations.bib | Removed vignette bibliography file. |
| src/rust/src/settings.rs | Sets pmcore log level to INFO when writing settings. |
| src/rust/src/lib.rs | Adjusts tracing subscriber default filter to WARN; formatting/whitespace edits. |
| src/rust/src/executor.rs | Makes fit result mutable before writing outputs. |
| src/rust/Cargo.toml | Bumps pmcore to 0.22.1; adds libloading dependency; keeps extendr-api wildcard. |
| man/summary.PM_sim.Rd | Aligns digits default with getPMoptions("digits"); doc wording updates. |
| man/latestR.Rd | New docs for latestR(). |
| man/downloadR.Rd | New docs for downloadR(). |
| man/PMcheck.Rd | Updates PMcheck() usage default path = ".". |
| man/PM_model.Rd | Documents new quiet parameters for fit, sim, and compile. |
| man/PM_compare.Rd | Clarifies “best metric” rules in return value description. |
| inst/report/templates/bestdose.Rmd | Adds a BestDose report template (DT/plotly-based). |
| inst/options/PMoptions.json | Adds date_format default option. |
| data-raw/data-raw.R | Disables report generation in an example fit (report = "none"). |
| R/zzz.R | Adds interactive attach-time version checks (Pmetrics + R) and related messaging. |
| R/model_transpiler.R | Improves template mapping/validation; errors for unsupported clearance templates; minor Rust header formatting changes. |
| R/PMutilities.R | Updates cli_df highlighting behavior; adds latestR()/downloadR() utilities; retains clear_build(). |
| R/PMoptions.R | Adds locale-based date_format initialization and Shiny UI control for it. |
| R/PM_sim.R | Adds ... arg validation, adjusts parameter counting for theta mode, improves covariate sim summary calcs, changes recompilation behavior, and updates summary docs/behavior. |
| R/PM_post.R | Drops pop_mean/pop_median before reshaping to posterior predictions. |
| R/PM_model.R | Adds quiet plumbing into fit/sim/compile; changes compilation messaging; alters template_path selection. |
| R/PM_compare.R | Updates convergence detection and rewrites “best” metric counting + highlight metadata. |
| NAMESPACE | Exports new latestR and downloadR. |
| DESCRIPTION | Bumps package version to 3.0.10. |
| Archived/summaryPMdopt.R | Removed archived legacy code. |
| Archived/printPMdopt.R | Removed archived legacy code. |
| Archived/pmetrics-logo.png | Archived asset update/removal. |
| Archived/plotPMdopt.R | Removed archived legacy code. |
| Archived/pkgdown.yml | Removed archived CI config. |
| Archived/modelLibrary.R | Removed archived model library script. |
| Archived/makePTA2.R | Removed archived legacy PTA script. |
| Archived/genAlquimiaData.R | Removed archived legacy script. |
| Archived/examples_old.R | Removed archived legacy examples. |
| Archived/Pmetrics_old.css | Removed archived legacy CSS. |
| Archived/Pmetrics.css | Removed archived legacy CSS. |
| Archived/PMupdate.R | Removed archived legacy updater script. |
| Archived/PMsave.R | Removed archived legacy save helper. |
| Archived/PMreport.R | Removed archived legacy reporting implementation. |
| Archived/PMremote.R | Removed archived legacy remote server code. |
| Archived/MMopt.R | Removed archived legacy optimal design implementation. |
| Archived/LegacyPlots.R | Removed archived legacy plotting code. |
| Archived/LICENSE | Removed archived license copy. |
| Archived/ERRrepScript.R | Removed archived legacy script. |
| Archived/.gitignore | Removed archived .gitignore. |
| .gitignore | Stops ignoring inst/Examples/; adds ignore for errors.xlsx; ignores Archived/. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 57 out of 89 changed files in this pull request and generated 5 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| settings.set_output_path(output_path.to_string()); | ||
| settings.set_write_logs(true); | ||
| settings.set_log_level(LogLevel::INFO); | ||
| settings.write()?; |
There was a problem hiding this comment.
settings.set_log_level(LogLevel::INFO) hard-codes INFO logging, but setup_logs() now filters WARN+ by default. Consider making the log level configurable (e.g., from the R settings list) and/or setting it to WARN to match the subscriber default, otherwise INFO logs may be written but never surfaced.
| pmcore = { version = "=0.22.1", features = ["exa"] } | ||
| libloading = "0.9" | ||
|
|
There was a problem hiding this comment.
libloading was added as a dependency but does not appear to be used anywhere in src/rust/src (no references found). Consider removing it to reduce compile time and dependency surface, or add the intended usage so this stays justified.
| fn setup_logs() -> anyhow::Result<()> { | ||
| use tracing::Level; | ||
| use tracing_subscriber::filter::LevelFilter; | ||
|
|
||
| // Create a subscriber with our custom layer using the global timer | ||
| // Filter to show only INFO and above (INFO, WARN, ERROR) | ||
| // Filter to show only WARN and above (WARN, ERROR) by default | ||
| let subscriber = tracing_subscriber::registry() | ||
| .with(RFormatLayer::new()) | ||
| .with(LevelFilter::from_level(Level::INFO)); | ||
| .with(LevelFilter::from_level(Level::WARN)); | ||
|
|
There was a problem hiding this comment.
The Rust tracing subscriber is configured to filter at WARN+ by default here, but settings.rs sets Settings log level to INFO. This mismatch can make it look like INFO logging is enabled (and may generate log files) while nothing shows up in R output. Consider aligning the defaults (both WARN or both INFO) or wiring the subscriber filter from the same setting.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 59 out of 91 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # Validate update settings | ||
| valid_update_check <- c("manual", "never", "daily", "weekly", "monthly") | ||
| update_check <- tolower(as.character(synced_opts$update_check)) | ||
| if (!(update_check %in% valid_update_check)) { | ||
| update_check <- "weekly" | ||
| } | ||
| synced_opts$update_check <- update_check |
There was a problem hiding this comment.
The UI validation for update_check does not include the value "always", but pm_update_interval_days() supports "always" as a valid mode. This makes "always" effectively impossible to persist via the options UI and leaves dead/inconsistent behavior. Either add "always" to the validated choices (and optionally expose it in the UI) or remove it from pm_update_interval_days() to keep the option surface consistent.
| metric_best <- purrr::map(metric_cols, function(col) { | ||
| x_num <- suppressWarnings(as.numeric(df[[col]])) | ||
| valid <- which(!is.na(x_num)) | ||
| if (length(valid) == 0) return(integer(0)) | ||
| target <- ifelse(grepl("Sl|R2", col), 1, 0) | ||
| valid[which(abs(x_num[valid] - target) == min(abs(x_num[valid] - target)))] | ||
| }) |
There was a problem hiding this comment.
The "best"-value highlighting logic treats all non-slope/non-R2 metrics as having an ideal target of 0 (i.e., chooses values closest to 0). This is incorrect for metrics like -2*LL/AIC/BIC where the best value should be the minimum (most negative/lowest), not the closest to 0. Consider special-casing LL/AIC/BIC to use min(x) (and slope/R2 to use closest to 1, bias/imprecision/intercept to use closest to 0) so the CLI highlighting matches the documented metric semantics.
| target <- ifelse(grepl("Sl|R2", col), 1, 0) | ||
| valid[which(abs(x[valid] - target) == min(abs(x[valid] - target)))] |
There was a problem hiding this comment.
The computation of per-metric "best" rows uses a closest-to-target (0 or 1) heuristic for all metric columns. This conflicts with the function documentation for -2*LL/AIC/BIC, where the best model is the one with the lowest value, not the value closest to 0. This can mis-rank models (especially if any of these metrics can be negative). Suggest explicitly selecting minima for ll/aic/bic, closest-to-0 for bias/imprecision/intercepts, and closest-to-1 for slopes/R2 so both the best-counts and highlighting match the documented behavior.
| target <- ifelse(grepl("Sl|R2", col), 1, 0) | |
| valid[which(abs(x[valid] - target) == min(abs(x[valid] - target)))] | |
| # Determine "best" rows per metric: | |
| # - For -2*LL/AIC/BIC, best is the minimum value. | |
| # - For slopes and R2, best is closest to 1. | |
| # - For bias, imprecision, intercepts, best is closest to 0. | |
| if (grepl("LL$|AIC$|BIC$", col, ignore.case = TRUE)) { | |
| # Information criteria / likelihood: smaller is better | |
| best_val <- min(x[valid]) | |
| valid[which(x[valid] == best_val)] | |
| } else if (grepl("Sl|R2", col, ignore.case = TRUE)) { | |
| # Slopes and R2: closer to 1 is better | |
| diffs <- abs(x[valid] - 1) | |
| best_diff <- min(diffs) | |
| valid[which(diffs == best_diff)] | |
| } else { | |
| # Bias, imprecision, intercepts: closer to 0 is better | |
| diffs <- abs(x[valid]) | |
| best_diff <- min(diffs) | |
| valid[which(diffs == best_diff)] | |
| } |
|
@copilot open a new pull request to apply changes based on the comments in this thread |
Number of updates and bug fixes