From 99de227abf397d493b77beeb142f947127b2f969 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 11 Oct 2026 09:13:15 +0000 Subject: [PATCH] fix(PM_compare): detect PMcore "Stopped (converged)" status The converged column used a case-sensitive grepl("Converged"), so it was FALSE for every run from the Rust backend. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01GTyUgJEd5uCEmv9qYrv8dC --- R/PM_compare.R | 7 ++++++- tests/testthat/test-pm-compare-converged.R | 7 +++++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 tests/testthat/test-pm-compare-converged.R diff --git a/R/PM_compare.R b/R/PM_compare.R index 1be24efe9..86654a27c 100755 --- a/R/PM_compare.R +++ b/R/PM_compare.R @@ -436,7 +436,7 @@ PM_compare <- function(..., icen = "median", outeq = 1, plot = FALSE) { nvar = purrr::map_int(allObj, \(x) length(names(x$final$popMean))), # par = purrr::map_chr(allObj, \(x) paste(names(x$final$popMean), collapse = ", ")), converged = purrr::map_lgl(allObj, \(x) { - grepl("Converged", x$cycle$data$status) + is_converged_status(x$cycle$data$status) }), ll = purrr::map_dbl(allObj, \(x) { tail(x$cycle$data$objective$neg2ll, 1) @@ -629,3 +629,8 @@ print.PM_compare <- function(x, ...) { } } } + +# Status is "Converged" (older runs) or "Stopped (converged)" (PMcore). +is_converged_status <- function(status) { + length(status) > 0 && grepl("converged", status[[1]], ignore.case = TRUE) +} diff --git a/tests/testthat/test-pm-compare-converged.R b/tests/testthat/test-pm-compare-converged.R new file mode 100644 index 000000000..39ab56199 --- /dev/null +++ b/tests/testthat/test-pm-compare-converged.R @@ -0,0 +1,7 @@ +test_that("is_converged_status recognises old and PMcore status text", { + expect_true(is_converged_status("Converged")) + expect_true(is_converged_status("Stopped (converged)")) + expect_false(is_converged_status("Stopped (maximum cycles reached)")) + expect_false(is_converged_status("Posterior")) + expect_false(is_converged_status(character(0))) +})