From f2dc17ac12b69567d5cf44c7af5801605bee1541 Mon Sep 17 00:00:00 2001 From: ThimotheeV Date: Mon, 6 Jul 2026 15:09:57 +0200 Subject: [PATCH 1/9] make the package more resilient --- R/utils.R | 2 ++ 1 file changed, 2 insertions(+) diff --git a/R/utils.R b/R/utils.R index 67bd4d0..dd4bdd8 100644 --- a/R/utils.R +++ b/R/utils.R @@ -153,6 +153,7 @@ sep <- function() { #' @return A list of model names. #' @export tp_model_library <- function() { + tp_installing_treeppl() # make sure you get the appropriate version if you have more than one treeppl folder in the tmp fd <- list.files("/tmp", pattern = paste0("treeppl-", TPPLC_VERSION), @@ -194,6 +195,7 @@ tp_find <- function(model_name, ext) { full.names = TRUE ) } else { + tp_installing_treeppl() fd <- list.files("/tmp", pattern = paste0("treeppl-", TPPLC_VERSION), full.names = TRUE) From cae2ebb36b8f7fe222d9d8ae01312b9baacad27d Mon Sep 17 00:00:00 2001 From: ThimotheeV Date: Tue, 7 Jul 2026 11:56:43 +0200 Subject: [PATCH 2/9] Temp change compiled_model name to sampler until permanent decision --- R/data.R | 1 + R/model.R | 23 +++++++++---------- R/run.R | 9 ++++---- ...l_Template-class.Rd => sampler_T-class.Rd} | 8 +++---- man/tp_compile.Rd | 4 ++-- man/tp_run.Rd | 5 ++-- 6 files changed, 24 insertions(+), 26 deletions(-) rename man/{compiled_model_Template-class.Rd => sampler_T-class.Rd} (55%) diff --git a/R/data.R b/R/data.R index 50d1c28..a1aef81 100644 --- a/R/data.R +++ b/R/data.R @@ -2,6 +2,7 @@ + #' Import data for TreePPL program #' #' @description diff --git a/R/model.R b/R/model.R index 176955b..41e4d16 100644 --- a/R/model.R +++ b/R/model.R @@ -79,13 +79,12 @@ options_to_string <- function(options) { args_str <- c() if (length(options) != 0) { vec <- c() - args_vec <- unlist(options) - for (i in seq_along(args_vec)) { - if (!is.logical(args_vec[[i]])) { - str <- paste0("--", names(args_vec[i]), " ", args_vec[[i]]) + for (i in seq_along(options)) { + if (!is.logical(options[[i]])) { + str <- paste0("--", names(options[i]), " ", options[[i]]) } else { - if (args_vec[[i]]) { - str <- paste0("--", names(args_vec[i])) + if (options[[i]]) { + str <- paste0("--", names(options[i])) } } vec <- c(vec, str) @@ -98,12 +97,12 @@ options_to_string <- function(options) { #' TreePPL model template #' #' @description -#' `tp_modelT` template for TreePPL code carrying all the informations necessary +#' `sampler_T` template for TreePPL code carrying all the informations necessary #' for compiling and running this model efficently -compiled_model_Template <- +sampler_T <- setRefClass( - "compiled_model_Template", + "sampler_T", fields = list( exe_path = "character", path = "character", @@ -177,7 +176,7 @@ tp_write_model <- function(model, model_file_name = "tmp_model_file") { #' Create a TreePPL model #' #' @description -#' `tp_compile` takes TreePPL model and prepares it to be used by +#' `tp_compile` takes TreePPL model and create a sampler to be used by #' [treepplr::tp_run()]. #' #' @param model One of tree options: @@ -186,7 +185,7 @@ tp_write_model <- function(model, model_file_name = "tmp_model_file") { #' (see [treepplr::tp_model_library()]), OR #' * A string containing the entire TreePPL code. #' -#' @return compiled_model from a compiled_model_Template +#' @return sampler from a sampler_T #' @export tp_compile <- function(model, method = "mcmc", ...) { @@ -212,7 +211,7 @@ tp_compile <- function(model, method = "mcmc", ...) { model_path <- tp_write_model(model) } } - m <- new("compiled_model_Template", path = model_path) + m <- new("sampler_T", path = model_path) user_list <- append(tp_list(...), list(method = method)) tmp <- list_to_options(user_list) diff --git a/R/run.R b/R/run.R index c14d1f2..40d7d8a 100644 --- a/R/run.R +++ b/R/run.R @@ -3,8 +3,7 @@ #' @description #' Run TreePPL and return output. #' -#' @param compiled_model a [base::character] with the full path to the compiled model -#' outputted by [treepplr::tp_compile]. +#' @param sampler a [treepplr::sampler_T] outputted by [treepplr::tp_compile]. #' @param data a [base::character] with the full path to the data file in TreePPL #' JSON format (as outputted by [treepplr::tp_data]). #' @param dir a [base::character] with the full path to the directory where you @@ -41,7 +40,7 @@ #' result <- tp_run(exe_path, data_path, n_runs = 2) #' } -tp_run <- function(compiled_model, +tp_run <- function(sampler, data, dir = NULL, out_file_name = "out", @@ -62,7 +61,7 @@ tp_run <- function(compiled_model, # So the user list have priority options <- list_to_options(tp_list(...)) - if(length(options[["compile"]]) != 0) { + if (length(options[["compile"]]) != 0) { stop("Can't give compile time options here") } @@ -70,7 +69,7 @@ tp_run <- function(compiled_model, # due to conflict with internal env from treeppl self container command <- paste( "LD_LIBRARY_PATH= ", - compiled_model$exe_path, + sampler$exe_path, data, options_to_string(options[["runtime"]]), paste(">", output_path) diff --git a/man/compiled_model_Template-class.Rd b/man/sampler_T-class.Rd similarity index 55% rename from man/compiled_model_Template-class.Rd rename to man/sampler_T-class.Rd index f2ff692..60efa3e 100644 --- a/man/compiled_model_Template-class.Rd +++ b/man/sampler_T-class.Rd @@ -1,12 +1,12 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/model.R \docType{class} -\name{compiled_model_Template-class} -\alias{compiled_model_Template-class} -\alias{compiled_model_Template} +\name{sampler_T-class} +\alias{sampler_T-class} +\alias{sampler_T} \title{TreePPL model template} \description{ -\code{tp_modelT} template for TreePPL code carrying all the informations necessary +\code{sampler_T} template for TreePPL code carrying all the informations necessary for compiling and running this model efficently } diff --git a/man/tp_compile.Rd b/man/tp_compile.Rd index 1799a58..29bc30e 100644 --- a/man/tp_compile.Rd +++ b/man/tp_compile.Rd @@ -16,9 +16,9 @@ tp_compile(model, method = "mcmc", ...) }} } \value{ -compiled_model from a compiled_model_Template +sampler from a sampler_T } \description{ -\code{tp_compile} takes TreePPL model and prepares it to be used by +\code{tp_compile} takes TreePPL model and create a sampler to be used by \code{\link[=tp_run]{tp_run()}}. } diff --git a/man/tp_run.Rd b/man/tp_run.Rd index 38dffbf..255ae9a 100644 --- a/man/tp_run.Rd +++ b/man/tp_run.Rd @@ -4,11 +4,10 @@ \alias{tp_run} \title{Run a TreePPL program} \usage{ -tp_run(compiled_model, data, dir = NULL, out_file_name = "out", ...) +tp_run(sampler, data, dir = NULL, out_file_name = "out", ...) } \arguments{ -\item{compiled_model}{a \link[base:character]{base::character} with the full path to the compiled model -outputted by \link{tp_compile}.} +\item{sampler}{a \link{sampler_T} outputted by \link{tp_compile}.} \item{data}{a \link[base:character]{base::character} with the full path to the data file in TreePPL JSON format (as outputted by \link{tp_data}).} From fa0df19989f191b91ee82f67e0d3eebc5025b053 Mon Sep 17 00:00:00 2001 From: ThimotheeV Date: Tue, 7 Jul 2026 12:02:39 +0200 Subject: [PATCH 3/9] remove reference to n_runs --- R/post_treatment.R | 2 +- R/run.R | 2 +- man/tp_parse_host_rep.Rd | 2 +- man/tp_run.Rd | 2 +- vignettes/treepplr.Rmd | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/R/post_treatment.R b/R/post_treatment.R index 0811318..03631bc 100644 --- a/R/post_treatment.R +++ b/R/post_treatment.R @@ -106,7 +106,7 @@ tp_parse_mcmc <- function(treeppl_out) { #' @param treeppl_out a character vector giving the TreePPL json output #' produced by [tp_run]. #' -#' @return A list (n = n_runs) of data frames with the output from inference +#' @return A list (n = sweeps) of data frames with the output from inference #' in TreePPL under the host repertoire evolution model. #' @export diff --git a/R/run.R b/R/run.R index 40d7d8a..838de95 100644 --- a/R/run.R +++ b/R/run.R @@ -37,7 +37,7 @@ #' data_path <- tp_data(data_input = "coin") #' #' # run TreePPL -#' result <- tp_run(exe_path, data_path, n_runs = 2) +#' result <- tp_run(exe_path, data_path) #' } tp_run <- function(sampler, diff --git a/man/tp_parse_host_rep.Rd b/man/tp_parse_host_rep.Rd index 66f7df7..e96f2b8 100644 --- a/man/tp_parse_host_rep.Rd +++ b/man/tp_parse_host_rep.Rd @@ -11,7 +11,7 @@ tp_parse_host_rep(treeppl_out) produced by \link{tp_run}.} } \value{ -A list (n = n_runs) of data frames with the output from inference +A list (n = sweeps) of data frames with the output from inference in TreePPL under the host repertoire evolution model. } \description{ diff --git a/man/tp_run.Rd b/man/tp_run.Rd index 255ae9a..0c06f8c 100644 --- a/man/tp_run.Rd +++ b/man/tp_run.Rd @@ -47,6 +47,6 @@ exe_path <- tp_compile(model = "coin", method = "mcmc-naive", iterations = 2000) data_path <- tp_data(data_input = "coin") # run TreePPL -result <- tp_run(exe_path, data_path, n_runs = 2) +result <- tp_run(exe_path, data_path) } } diff --git a/vignettes/treepplr.Rmd b/vignettes/treepplr.Rmd index 212267f..593c6c1 100644 --- a/vignettes/treepplr.Rmd +++ b/vignettes/treepplr.Rmd @@ -117,7 +117,7 @@ Now you are ready to run your analysis. All you have to do is to pass your data to the compiled executable and choose how many independent runs you want to do. ```{r} -output <- tp_run(compiled_model = exe_path, data = data_path, n_runs = 4) +output <- tp_run(compiled_model = exe_path, data = data_path) ``` From d5ae80e1c9053db7e59a34085b72ce5295d916e2 Mon Sep 17 00:00:00 2001 From: ThimotheeV Date: Tue, 7 Jul 2026 12:26:40 +0200 Subject: [PATCH 4/9] fix tp_compile_options and add tp_runtime_options --- DESCRIPTION | 2 +- R/model.R | 24 ++++++++++++++++++------ man/tp_compile_options.Rd | 2 +- man/tp_runtime_options.Rd | 14 ++++++++++++++ 4 files changed, 34 insertions(+), 8 deletions(-) create mode 100644 man/tp_runtime_options.Rd diff --git a/DESCRIPTION b/DESCRIPTION index e30b375..d1e7eb4 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: treepplr Title: R Interface to TreePPL -Version: 0.14.0 +Version: 0.14.1 Authors@R: person("Mariana", "P Braga", , "mpiresbr@gmail.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-1253-2536")) diff --git a/R/model.R b/R/model.R index 41e4d16..040239a 100644 --- a/R/model.R +++ b/R/model.R @@ -19,9 +19,21 @@ tpplcCompileOptions <- c( #' Options that can be passed to TreePPL compiler #' -#' @returns A data frame with the output from the compiler's help +#' @returns A data frame with some outputs from the compiler's help #' tp_compile_options <- function() { + tp_find_options("Compile options:", "Runtime options:") +} + +#' Options that can be passed to TreePPL run +#' +#' @returns A data frame with with some outputs from compiler's help +#' +tp_runtime_options <- function() { + tp_find_options("Runtime options:", "Inference methods:") +} + +tp_find_options <- function(str_begin, str_end) { tpplc_path <- tp_installing_treeppl() # treeppl options cmd_opt <- system2( @@ -33,10 +45,11 @@ tp_compile_options <- function() { # Preparing the output # - # find the line containing "Options:" - x <- which(cmd_opt == "Options:") + # find the line between str_begin and str_end + x <- which(cmd_opt == str_begin) + y <- which(cmd_opt == str_end) # extract everything after that line - cmd_opt <- cmd_opt[(x + 1):length(cmd_opt)] + cmd_opt <- cmd_opt[(x + 1):(y - 2)] cmd_opt <- trimws(cmd_opt) cmd_opt <- strsplit(cmd_opt, " {2,}", perl = TRUE) @@ -139,7 +152,7 @@ compilation <- function(path, args_str) { dir_path <- tp_tempdir() # output - output_path <- paste0(dir_path, digest::digest(paste(path,args_str), "sha256"), ".exe") + output_path <- paste0(dir_path, digest::digest(paste(path, args_str), "sha256"), ".exe") options <- paste("--output", output_path, args_str) @@ -166,7 +179,6 @@ compilation <- function(path, args_str) { #' @export #' tp_write_model <- function(model, model_file_name = "tmp_model_file") { - path <- paste0(tp_tempdir(), model_file_name, ".tppl") cat(model, file = path) diff --git a/man/tp_compile_options.Rd b/man/tp_compile_options.Rd index 78c691f..dd41a36 100644 --- a/man/tp_compile_options.Rd +++ b/man/tp_compile_options.Rd @@ -7,7 +7,7 @@ tp_compile_options() } \value{ -A data frame with the output from the compiler's help +A data frame with some outputs from the compiler's help } \description{ Options that can be passed to TreePPL compiler diff --git a/man/tp_runtime_options.Rd b/man/tp_runtime_options.Rd new file mode 100644 index 0000000..e2cafc7 --- /dev/null +++ b/man/tp_runtime_options.Rd @@ -0,0 +1,14 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/model.R +\name{tp_runtime_options} +\alias{tp_runtime_options} +\title{Options that can be passed to TreePPL run} +\usage{ +tp_runtime_options() +} +\value{ +A data frame with with some outputs from compiler's help +} +\description{ +Options that can be passed to TreePPL run +} From 6ac55a04fe702c8876b6fe9dc4d81e05c9c610c2 Mon Sep 17 00:00:00 2001 From: ThimotheeV Date: Thu, 9 Jul 2026 16:14:44 +0200 Subject: [PATCH 5/9] model -> sampler --- R/model.R | 10 +++++----- tests/testthat/test-model.R | 20 ++++++++++---------- vignettes/coin-example.Rmd | 4 ++-- vignettes/treepplr.Rmd | 6 +++--- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/R/model.R b/R/model.R index 040239a..48f60a5 100644 --- a/R/model.R +++ b/R/model.R @@ -118,7 +118,7 @@ sampler_T <- "sampler_T", fields = list( exe_path = "character", - path = "character", + model_path = "character", compile_options = "list" ) ) @@ -223,12 +223,12 @@ tp_compile <- function(model, method = "mcmc", ...) { model_path <- tp_write_model(model) } } - m <- new("sampler_T", path = model_path) + sampler <- new("sampler_T", model_path = model_path) user_list <- append(tp_list(...), list(method = method)) tmp <- list_to_options(user_list) - m$compile_options <- tmp[["compile"]] + sampler$compile_options <- tmp[["compile"]] full_options = append(tmp[["compile"]], tmp[["runtime"]]) - m$exe_path <- compilation(m$path, options_to_string(full_options)) - return(m) + sampler$exe_path <- compilation(sampler$model_path, options_to_string(full_options)) + return(sampler) } diff --git a/tests/testthat/test-model.R b/tests/testthat/test-model.R index caafdb0..a2cd77f 100644 --- a/tests/testthat/test-model.R +++ b/tests/testthat/test-model.R @@ -10,24 +10,24 @@ cat(crayon::yellow("\nTest-model : Compilation and modification of the options.\ test_that("Test-model_1a : tp_compile MCMC", { cat("\tTest-model_1a : tp_compile MCMC \n") - model <- treepplr::tp_compile("crbd") + sampler <- treepplr::tp_compile("crbd") - expect_no_error(readBin(model$exe_path, "raw", 10e6)) + expect_no_error(readBin(sampler$exe_path, "raw", 10e6)) }) test_that("Test-model_1b : tp_compile method SMC", { cat("\tTest-model_1b : tp_compile method SMC \n") - model <- treepplr::tp_compile("crbd", method = "smc-bpf") + sampler <- treepplr::tp_compile("crbd", method = "smc-bpf") - expect_no_error(readBin(model$exe_path, "raw", 10e6)) + expect_no_error(readBin(sampler$exe_path, "raw", 10e6)) }) test_that("Test-model_2a : tp_compile model name", { cat("\tTest-model_2a : tp_compile\n") - model <- treepplr::tp_compile("crbd") + sampler <- treepplr::tp_compile("crbd") version <- list.files("/tmp", pattern = paste0("treeppl-", TPPLC_VERSION), @@ -35,7 +35,7 @@ test_that("Test-model_2a : tp_compile model name", { model_right = system(paste0("find ", version, " -name crbd.tppl"), intern = T) - expect_equal(readr::read_file(model$path), readr::read_file(model_right)) + expect_equal(readr::read_file(sampler$model_path), readr::read_file(model_right)) }) test_that("Test-model_2b : tp_compile model path ", { @@ -46,9 +46,9 @@ test_that("Test-model_2b : tp_compile model path ", { full.names = TRUE) model_right = system(paste0("find ", version, " -name crbd.tppl"), intern = T) - model <- treepplr::tp_compile(model_right) + sampler <- treepplr::tp_compile(model_right) - expect_equal(model$path, model_right) + expect_equal(sampler$model_path, model_right) }) test_that("Test-model_3a : tp_write path", { @@ -75,8 +75,8 @@ test_that("Test-model_4 : tp_compile model string ", { cat("\tTest-model_4 : tp_compile\n") model_string <- "model function blo() => Int {let blo = 3; return blo;}" - model <- treepplr::tp_compile(model_string) + sampler <- treepplr::tp_compile(model_string) model_right <- paste0(temp_dir, "tmp_model_file.tppl") - expect_equal(model$path, model_right) + expect_equal(sampler$model_path, model_right) }) diff --git a/vignettes/coin-example.Rmd b/vignettes/coin-example.Rmd index 7a0198f..41faa82 100644 --- a/vignettes/coin-example.Rmd +++ b/vignettes/coin-example.Rmd @@ -45,11 +45,11 @@ can find all available models and some information about them [here](https://tre If you want to look at the TreePPL code here in R, you can use the following functions: ```{r, eval = FALSE} -model_path <- tp_compile("coin") +sampler <- tp_compile("coin") ``` ```{r, eval=FALSE} -readr::read_file(model_path$path) +readr::read_file(sampler$model_path) ``` The main part of the model is defined in a function called `coinModel`: diff --git a/vignettes/treepplr.Rmd b/vignettes/treepplr.Rmd index 593c6c1..fcb598c 100644 --- a/vignettes/treepplr.Rmd +++ b/vignettes/treepplr.Rmd @@ -103,10 +103,10 @@ to run the chosen inference method. ```{r} # Using a model from the library and a Sequential Monte Carlo method -exe_path <- tp_compile(model = "crbd", method = "smc-apf", particles = 10000) +sampler <- tp_compile(model = "crbd", method = "smc-apf", particles = 10000) # Using a custom model and a Markov chain Monte Carlo method -exe_path <- tp_compile(model = model_path, method = "mcmc-lightweight", +sampler <- tp_compile(model = model_path, method = "mcmc-lightweight", iterations = 10000) ``` @@ -117,7 +117,7 @@ Now you are ready to run your analysis. All you have to do is to pass your data to the compiled executable and choose how many independent runs you want to do. ```{r} -output <- tp_run(compiled_model = exe_path, data = data_path) +output <- tp_run(compiled_model = sampler, data = data_path) ``` From fa99fceee94f0f76a53d5c373ba0db130e6b2f50 Mon Sep 17 00:00:00 2001 From: ThimotheeV Date: Fri, 10 Jul 2026 12:46:44 +0200 Subject: [PATCH 6/9] threading in place --- DESCRIPTION | 1 + R/model.R | 6 +++--- R/run.R | 16 ++++++++++++++-- man/tp_run.Rd | 10 +++++++++- 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index d1e7eb4..19f9dd8 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -16,6 +16,7 @@ Depends: Imports: assertthat, digest, + future.apply, methods, jsonlite, tidytree, diff --git a/R/model.R b/R/model.R index 48f60a5..18cbb1d 100644 --- a/R/model.R +++ b/R/model.R @@ -154,11 +154,11 @@ compilation <- function(path, args_str) { # output output_path <- paste0(dir_path, digest::digest(paste(path, args_str), "sha256"), ".exe") - options <- paste("--output", output_path, args_str) + options <- paste(args_str, "--output", output_path) # Preparing the command line program tpplc_path <- tp_installing_treeppl() - command <- paste(tpplc_path, path, options) + command <- paste(tpplc_path, options, path) # Compile program # Empty LD_LIBRARY_PATH from R_env for this command specifically @@ -224,7 +224,7 @@ tp_compile <- function(model, method = "mcmc", ...) { } } sampler <- new("sampler_T", model_path = model_path) - user_list <- append(tp_list(...), list(method = method)) + user_list <- append(list(method = method), tp_list(...)) tmp <- list_to_options(user_list) sampler$compile_options <- tmp[["compile"]] diff --git a/R/run.R b/R/run.R index 838de95..188db15 100644 --- a/R/run.R +++ b/R/run.R @@ -44,6 +44,8 @@ tp_run <- function(sampler, data, dir = NULL, out_file_name = "out", + n_runs = 1, + n_processes = 3, ...) { if (is.null(dir)) { dir_path <- tp_tempdir() @@ -64,7 +66,6 @@ tp_run <- function(sampler, if (length(options[["compile"]]) != 0) { stop("Can't give compile time options here") } - # Empty LD_LIBRARY_PATH from R_env for this command specifically # due to conflict with internal env from treeppl self container command <- paste( @@ -74,7 +75,18 @@ tp_run <- function(sampler, options_to_string(options[["runtime"]]), paste(">", output_path) ) - system(command) + + if (n_runs > 1) { + plan(multisession, workers = n_processes) + future_sapply( + 1:n_runs, + FUN = function(i) { + system(paste0(command, i)) + } + ) + } else { + system(command) + } # simple parsing #### change this? #### diff --git a/man/tp_run.Rd b/man/tp_run.Rd index 0c06f8c..96ea7a3 100644 --- a/man/tp_run.Rd +++ b/man/tp_run.Rd @@ -4,7 +4,15 @@ \alias{tp_run} \title{Run a TreePPL program} \usage{ -tp_run(sampler, data, dir = NULL, out_file_name = "out", ...) +tp_run( + sampler, + data, + dir = NULL, + out_file_name = "out", + n_runs = 1, + n_processes = 3, + ... +) } \arguments{ \item{sampler}{a \link{sampler_T} outputted by \link{tp_compile}.} From 33d478faaa51a6357d9e3249f0f209cc28a75cdb Mon Sep 17 00:00:00 2001 From: ThimotheeV Date: Fri, 10 Jul 2026 13:48:38 +0200 Subject: [PATCH 7/9] Now handling multi file output --- R/run.R | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/R/run.R b/R/run.R index 188db15..8c61342 100644 --- a/R/run.R +++ b/R/run.R @@ -47,12 +47,20 @@ tp_run <- function(sampler, n_runs = 1, n_processes = 3, ...) { + if (is.null(dir)) { dir_path <- tp_tempdir() } else { dir_path <- dir } + listFiles <- list.files(path = dir_path, + pattern = out_file_name, + full.names = TRUE) + if(length(listFiles) != 0) { + file.remove(listFiles) + } + output_path <- paste0(dir_path, out_file_name, ".json") #If a list have multiple time the same key @@ -61,9 +69,9 @@ tp_run <- function(sampler, #> lis <- list(method = "mcmc", method = "smc") #> lis[["method"]] => "mcmc" # So the user list have priority - options <- list_to_options(tp_list(...)) + tpplc_options <- list_to_options(tp_list(...)) - if (length(options[["compile"]]) != 0) { + if (length(tpplc_options[["compile"]]) != 0) { stop("Can't give compile time options here") } # Empty LD_LIBRARY_PATH from R_env for this command specifically @@ -72,7 +80,7 @@ tp_run <- function(sampler, "LD_LIBRARY_PATH= ", sampler$exe_path, data, - options_to_string(options[["runtime"]]), + options_to_string(tpplc_options[["runtime"]]), paste(">", output_path) ) @@ -88,9 +96,11 @@ tp_run <- function(sampler, system(command) } - # simple parsing - #### change this? #### - json_out <- readLines(output_path) |> + listFiles <- list.files(path = dir_path, + pattern = out_file_name, + full.names = TRUE) + + json_out <- readr::read_lines(listFiles) |> lapply(jsonlite::fromJSON, simplifyVector = FALSE) return(json_out) From daff373aa65ce47ba57359bbc4602c1a2d62ed88 Mon Sep 17 00:00:00 2001 From: ThimotheeV Date: Fri, 10 Jul 2026 16:26:01 +0200 Subject: [PATCH 8/9] tp_compile_methods + test + doxcumentations --- DESCRIPTION | 4 +-- NAMESPACE | 3 ++ R/model.R | 75 +++++++++++++++++++++++++++------------ R/run.R | 13 +++++-- R/zzz.R | 4 +++ man/TPPLC_VERSION.Rd | 11 ++++++ man/compilation.Rd | 23 ++---------- man/options_to_string.Rd | 13 ------- man/tp_compile.Rd | 5 +++ man/tp_compile_methods.Rd | 14 ++++++++ man/tp_compile_options.Rd | 6 ++-- man/tp_run.Rd | 7 +++- man/tp_runtime_options.Rd | 6 ++-- tests/testthat/test-run.R | 19 +++++++--- 14 files changed, 131 insertions(+), 72 deletions(-) create mode 100644 man/TPPLC_VERSION.Rd delete mode 100644 man/options_to_string.Rd create mode 100644 man/tp_compile_methods.Rd diff --git a/DESCRIPTION b/DESCRIPTION index 19f9dd8..d5b77ad 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: treepplr Title: R Interface to TreePPL -Version: 0.14.1 +Version: 0.15.0 Authors@R: person("Mariana", "P Braga", , "mpiresbr@gmail.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-1253-2536")) @@ -16,7 +16,7 @@ Depends: Imports: assertthat, digest, - future.apply, + future, methods, jsonlite, tidytree, diff --git a/NAMESPACE b/NAMESPACE index b0de17e..80ef8b5 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -2,6 +2,8 @@ export(TPPLC_VERSION) export(tp_compile) +export(tp_compile_methods) +export(tp_compile_options) export(tp_data) export(tp_installing_treeppl) export(tp_json_to_phylo) @@ -13,6 +15,7 @@ export(tp_parse_mcmc) export(tp_parse_smc) export(tp_phylo_to_tpjson) export(tp_run) +export(tp_runtime_options) export(tp_smc_convergence) export(tp_tempdir) export(tp_treeppl_json) diff --git a/R/model.R b/R/model.R index 18cbb1d..c1927e4 100644 --- a/R/model.R +++ b/R/model.R @@ -17,18 +17,58 @@ tpplcCompileOptions <- c( "static-delay" ) -#' Options that can be passed to TreePPL compiler +#' Methods to [treepplr::tp_compile()] #' -#' @returns A data frame with some outputs from the compiler's help +#' @returns A data frame with methods that can be passed to [treepplr::tp_compile()] #' +#' @export +tp_compile_methods <- function() { + tpplc_path <- tp_installing_treeppl() + # treeppl options + cmd_opt <- system2( + command = tpplc_path, + args = "--help", + env = "LD_LIBRARY_PATH= ", + stdout = TRUE + ) + + # Preparing the output # + + # find the line between str_begin and str_end + x <- which(cmd_opt == "Inference methods:") + + # extract everything after that line + cmd_opt <- cmd_opt[(x + 1):length(cmd_opt)] + cmd_opt <- trimws(cmd_opt) + cmd_opt <- strsplit(cmd_opt, " ", perl = TRUE) + + + opt_tab <- do.call(rbind, lapply(cmd_opt, function(x) { + # if there is no description, make it NA + data.frame( + argument = x[2], + description = trimws(paste(x[-2:-1], collapse = " ")), + stringsAsFactors = FALSE + ) + })) + + return(opt_tab) +} + +#' Options to [treepplr::tp_compile()] +#' +#' @returns A data frame with options that can be passed to [treepplr::tp_compile()] +#' +#' @export tp_compile_options <- function() { tp_find_options("Compile options:", "Runtime options:") } -#' Options that can be passed to TreePPL run +#' Options to [treepplr::tp_run()] #' -#' @returns A data frame with with some outputs from compiler's help +#' @returns A data frame with options that can be passed to [treepplr::tp_run()] #' +#' @export tp_runtime_options <- function() { tp_find_options("Runtime options:", "Inference methods:") } @@ -86,8 +126,8 @@ list_to_options <- function(user_list) { options } -#' Convert options to a proper string of flags, e.g., `_` to `-`, -#' adding `--` in the beginning, spaces between things, etc. +#Convert options to a proper string of flags, e.g., `_` to `-`, +#adding `--` in the beginning, spaces between things, etc. options_to_string <- function(options) { args_str <- c() if (length(options) != 0) { @@ -114,7 +154,7 @@ options_to_string <- function(options) { #' for compiling and running this model efficently sampler_T <- - setRefClass( + methods::setRefClass( "sampler_T", fields = list( exe_path = "character", @@ -129,20 +169,8 @@ sampler_T <- #' `compilation` compile a TreePPL model and create inference machinery to be #' used by [treepplr::tp_run]. #' -#' @param model One of tree options: -#' * The full path of the model file that contains the TreePPL code, OR -#' * A string with the name of a model supported by treepplr -#' (see [treepplr::tp_model_library()]), OR -#' * A string containing the entire TreePPL code. -#' @param method Inference method to be used. See tp_compile_options() -#' for all supported methods. -#' @param iterations The number of MCMC iterations to be run. -#' @param particles The number of SMC particles to be run. -#' @param dir The directory where you want to save the executable. Default is -#' [base::tempdir()] -#' @param output Complete path to the compiled TreePPL program that will be -#' created. Default is dir/.exe -#' @param ... See tp_compile_options() for all supported arguments. +#' @param path [base::character] to a treppl model +#' @param args_str [base::character] of options for treeppl compiler #' #' @return The path for the compiled TreePPL program. @@ -196,6 +224,9 @@ tp_write_model <- function(model, model_file_name = "tmp_model_file") { #' * A string with the name of a model supported by treepplr #' (see [treepplr::tp_model_library()]), OR #' * A string containing the entire TreePPL code. +#' @param method Inference method to be used. See [treepplr::tp_compile_methods()] +#' for all supported methods. +#' @param ... See [treepplr::tp_compile_options()] for all supported arguments. #' #' @return sampler from a sampler_T #' @export @@ -223,7 +254,7 @@ tp_compile <- function(model, method = "mcmc", ...) { model_path <- tp_write_model(model) } } - sampler <- new("sampler_T", model_path = model_path) + sampler <- methods::new("sampler_T", model_path = model_path) user_list <- append(list(method = method), tp_list(...)) tmp <- list_to_options(user_list) diff --git a/R/run.R b/R/run.R index 8c61342..e8a8192 100644 --- a/R/run.R +++ b/R/run.R @@ -10,7 +10,10 @@ #' want to save the output. Default is [base::tempdir()]. #' @param out_file_name a [base::character] with the name of the output file in #' JSON format. Default is "out". -#' @param ... See [treepplr::tp_run_options] for all supported arguments. +#' @param n_runs a [base::numeric] for the numbers of sweeps(SMC)/Chains(MCMC). +#' @param n_processes a [base::numeric], number of parallel processes to use. +#' Can't be > n_runs. +#' @param ... See [treepplr::tp_runtime_options] for all supported arguments. #' #' #' @return A list of TreePPL output in parsed JSON format. @@ -85,8 +88,12 @@ tp_run <- function(sampler, ) if (n_runs > 1) { - plan(multisession, workers = n_processes) - future_sapply( + if (n_processes > n_runs) { + warning("n_processes reduce to be equal to n_runs.") + n_processes <- n_runs + } + future::plan(future::multisession, workers = n_processes) + future.apply::future_sapply( 1:n_runs, FUN = function(i) { system(paste0(command, i)) diff --git a/R/zzz.R b/R/zzz.R index e89b8ce..6e256fd 100644 --- a/R/zzz.R +++ b/R/zzz.R @@ -6,6 +6,10 @@ #version <- repo_info[[1]]$tag_name ################## +#' TreePPL version +#' +#' @description +#' TreePPL program version in use for this package version #'@export TPPLC_VERSION <- "0.4" diff --git a/man/TPPLC_VERSION.Rd b/man/TPPLC_VERSION.Rd new file mode 100644 index 0000000..16ce9bf --- /dev/null +++ b/man/TPPLC_VERSION.Rd @@ -0,0 +1,11 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/zzz.R +\name{TPPLC_VERSION} +\alias{TPPLC_VERSION} +\title{TreePPL version} +\usage{ +TPPLC_VERSION +} +\description{ +TreePPL program version in use for this package version +} diff --git a/man/compilation.Rd b/man/compilation.Rd index 3b4c31d..37083a8 100644 --- a/man/compilation.Rd +++ b/man/compilation.Rd @@ -7,28 +7,9 @@ compilation(path, args_str) } \arguments{ -\item{model}{One of tree options: -\itemize{ -\item The full path of the model file that contains the TreePPL code, OR -\item A string with the name of a model supported by treepplr -(see \code{\link[=tp_model_library]{tp_model_library()}}), OR -\item A string containing the entire TreePPL code. -}} +\item{path}{\link[base:character]{base::character} to a treppl model} -\item{method}{Inference method to be used. See tp_compile_options() -for all supported methods.} - -\item{iterations}{The number of MCMC iterations to be run.} - -\item{particles}{The number of SMC particles to be run.} - -\item{dir}{The directory where you want to save the executable. Default is -\code{\link[base:tempdir]{base::tempdir()}}} - -\item{output}{Complete path to the compiled TreePPL program that will be -created. Default is dir/\if{html}{\out{}}.exe} - -\item{...}{See tp_compile_options() for all supported arguments.} +\item{args_str}{\link[base:character]{base::character} of options for treeppl compiler} } \value{ The path for the compiled TreePPL program. diff --git a/man/options_to_string.Rd b/man/options_to_string.Rd deleted file mode 100644 index 3a2d299..0000000 --- a/man/options_to_string.Rd +++ /dev/null @@ -1,13 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/model.R -\name{options_to_string} -\alias{options_to_string} -\title{Convert options to a proper string of flags, e.g., \verb{_} to \code{-}, -adding \verb{--} in the beginning, spaces between things, etc.} -\usage{ -options_to_string(options) -} -\description{ -Convert options to a proper string of flags, e.g., \verb{_} to \code{-}, -adding \verb{--} in the beginning, spaces between things, etc. -} diff --git a/man/tp_compile.Rd b/man/tp_compile.Rd index 29bc30e..d827218 100644 --- a/man/tp_compile.Rd +++ b/man/tp_compile.Rd @@ -14,6 +14,11 @@ tp_compile(model, method = "mcmc", ...) (see \code{\link[=tp_model_library]{tp_model_library()}}), OR \item A string containing the entire TreePPL code. }} + +\item{method}{Inference method to be used. See \code{\link[=tp_compile_methods]{tp_compile_methods()}} +for all supported methods.} + +\item{...}{See \code{\link[=tp_compile_options]{tp_compile_options()}} for all supported arguments.} } \value{ sampler from a sampler_T diff --git a/man/tp_compile_methods.Rd b/man/tp_compile_methods.Rd new file mode 100644 index 0000000..47d088f --- /dev/null +++ b/man/tp_compile_methods.Rd @@ -0,0 +1,14 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/model.R +\name{tp_compile_methods} +\alias{tp_compile_methods} +\title{Methods to \code{\link[=tp_compile]{tp_compile()}}} +\usage{ +tp_compile_methods() +} +\value{ +A data frame with methods that can be passed to \code{\link[=tp_compile]{tp_compile()}} +} +\description{ +Methods to \code{\link[=tp_compile]{tp_compile()}} +} diff --git a/man/tp_compile_options.Rd b/man/tp_compile_options.Rd index dd41a36..cf0eb5f 100644 --- a/man/tp_compile_options.Rd +++ b/man/tp_compile_options.Rd @@ -2,13 +2,13 @@ % Please edit documentation in R/model.R \name{tp_compile_options} \alias{tp_compile_options} -\title{Options that can be passed to TreePPL compiler} +\title{Options to \code{\link[=tp_compile]{tp_compile()}}} \usage{ tp_compile_options() } \value{ -A data frame with some outputs from the compiler's help +A data frame with options that can be passed to \code{\link[=tp_compile]{tp_compile()}} } \description{ -Options that can be passed to TreePPL compiler +Options to \code{\link[=tp_compile]{tp_compile()}} } diff --git a/man/tp_run.Rd b/man/tp_run.Rd index 96ea7a3..873700c 100644 --- a/man/tp_run.Rd +++ b/man/tp_run.Rd @@ -26,7 +26,12 @@ want to save the output. Default is \code{\link[base:tempdir]{base::tempdir()}}. \item{out_file_name}{a \link[base:character]{base::character} with the name of the output file in JSON format. Default is "out".} -\item{...}{See \link{tp_run_options} for all supported arguments.} +\item{n_runs}{a \link[base:numeric]{base::numeric} for the numbers of sweeps(SMC)/Chains(MCMC).} + +\item{n_processes}{a \link[base:numeric]{base::numeric}, number of parallel processes to use. +Can't be > n_runs.} + +\item{...}{See \link{tp_runtime_options} for all supported arguments.} } \value{ A list of TreePPL output in parsed JSON format. diff --git a/man/tp_runtime_options.Rd b/man/tp_runtime_options.Rd index e2cafc7..145ba5e 100644 --- a/man/tp_runtime_options.Rd +++ b/man/tp_runtime_options.Rd @@ -2,13 +2,13 @@ % Please edit documentation in R/model.R \name{tp_runtime_options} \alias{tp_runtime_options} -\title{Options that can be passed to TreePPL run} +\title{Options to \code{\link[=tp_run]{tp_run()}}} \usage{ tp_runtime_options() } \value{ -A data frame with with some outputs from compiler's help +A data frame with options that can be passed to \code{\link[=tp_run]{tp_run()}} } \description{ -Options that can be passed to TreePPL run +Options to \code{\link[=tp_run]{tp_run()}} } diff --git a/tests/testthat/test-run.R b/tests/testthat/test-run.R index c9b83da..aea9cbc 100644 --- a/tests/testthat/test-run.R +++ b/tests/testthat/test-run.R @@ -8,10 +8,10 @@ cat(crayon::yellow("\nTest-run : Running TreePPL.\n")) test_that("Test-run_1a : tp_run", { cat("\tTest-run_1a : tp_run \n") - compiled_model <- treepplr::tp_compile("crbd", method = "smc-apf", particles = 2) + sampler <- treepplr::tp_compile("crbd", method = "smc-apf", particles = 2) data <- treepplr::tp_data("crbd") - result <- treepplr::tp_run(compiled_model, data, sweeps = 1) + result <- treepplr::tp_run(sampler, data, sweeps = 1) expect_equal(2, length(result[[1]]$samples)) @@ -20,10 +20,21 @@ test_that("Test-run_1a : tp_run", { test_that("Test-run_1a : tp_run custom name", { cat("\tTest-run_1a : tp_run \n") - compiled_model <- treepplr::tp_compile("crbd", method = "smc-apf", particles = 2) + sampler <- treepplr::tp_compile("crbd", method = "smc-apf", particles = 2) data <- treepplr::tp_data("crbd") - result <-treepplr::tp_run(compiled_model, data, sweeps = 1, out_file_name = "test_out", particles = 5) + result <-treepplr::tp_run(sampler, data, sweeps = 1, out_file_name = "test_out", particles = 5) expect_equal(5, length(result[[1]]$samples)) }) + +test_that("Test-run_1c : tp_run threading", { + cat("\tTest-run_1c : tp_run \n") + + sampler <- treepplr::tp_compile("crbd", method = "smc-apf", particles = 2) + data <- treepplr::tp_data("crbd") + + result <-treepplr::tp_run(sampler, data, sweeps = 1, out_file_name = "test_out", particles = 5, , n_runs = 10) + + expect_equal(10, length(result)) +}) From 5fd151cacf25cebeed98beea96e0dd4f42d2adc4 Mon Sep 17 00:00:00 2001 From: ThimotheeV Date: Mon, 13 Jul 2026 10:55:13 +0200 Subject: [PATCH 9/9] change chains for runs in tp_run doc --- R/run.R | 6 +++--- man/tp_run.Rd | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/R/run.R b/R/run.R index e8a8192..c953a00 100644 --- a/R/run.R +++ b/R/run.R @@ -10,9 +10,9 @@ #' want to save the output. Default is [base::tempdir()]. #' @param out_file_name a [base::character] with the name of the output file in #' JSON format. Default is "out". -#' @param n_runs a [base::numeric] for the numbers of sweeps(SMC)/Chains(MCMC). +#' @param n_runs a [base::numeric] giving the numbers of sweeps(SMC)/runs(MCMC). #' @param n_processes a [base::numeric], number of parallel processes to use. -#' Can't be > n_runs. +#' Can't be superior to n_runs. #' @param ... See [treepplr::tp_runtime_options] for all supported arguments. #' #' @@ -29,7 +29,7 @@ #' data_path <- tp_data(data_input = "coin") #' #' # run TreePPL -#' result <- tp_run(exe_path, data_path, sweeps = 2) +#' result <- tp_run(exe_path, data_path, n_runs = 2) #' #' #' # When using MCMC diff --git a/man/tp_run.Rd b/man/tp_run.Rd index 873700c..b417891 100644 --- a/man/tp_run.Rd +++ b/man/tp_run.Rd @@ -26,10 +26,10 @@ want to save the output. Default is \code{\link[base:tempdir]{base::tempdir()}}. \item{out_file_name}{a \link[base:character]{base::character} with the name of the output file in JSON format. Default is "out".} -\item{n_runs}{a \link[base:numeric]{base::numeric} for the numbers of sweeps(SMC)/Chains(MCMC).} +\item{n_runs}{a \link[base:numeric]{base::numeric} giving the numbers of sweeps(SMC)/runs(MCMC).} \item{n_processes}{a \link[base:numeric]{base::numeric}, number of parallel processes to use. -Can't be > n_runs.} +Can't be superior to n_runs.} \item{...}{See \link{tp_runtime_options} for all supported arguments.} } @@ -49,7 +49,7 @@ exe_path <- tp_compile(model = "coin", method = "smc-bpf", particles = 2000) data_path <- tp_data(data_input = "coin") # run TreePPL -result <- tp_run(exe_path, data_path, sweeps = 2) +result <- tp_run(exe_path, data_path, n_runs = 2) # When using MCMC