diff --git a/RcppTskit/R/Class-TableCollection.R b/RcppTskit/R/Class-TableCollection.R index 80dd49e..ed896b1 100644 --- a/RcppTskit/R/Class-TableCollection.R +++ b/RcppTskit/R/Class-TableCollection.R @@ -205,10 +205,10 @@ TableCollection <- R6Class( #' @description Add a row to the nodes table. #' @param flags integer flags for the new node. #' @param time numeric time value for the new node. - #' @param population integer population row ID (0-based, or \code{-1}); - #' \code{NULL} maps to \code{-1}. - #' @param individual integer individual row ID (0-based, or \code{-1}); - #' \code{NULL} maps to \code{-1}. + #' @param population integer population row ID (0-based); + #' use \code{-1} if not known - \code{NULL} maps to \code{-1}. + #' @param individual integer individual row ID (0-based); + #' use \code{-1} if not known - \code{NULL} maps to \code{-1}. #' @param metadata for the new node; accepts \code{NULL}, #' a raw vector, or a character of length 1. #' @details See the \code{tskit Python} equivalent at @@ -285,17 +285,16 @@ TableCollection <- R6Class( #' @examples #' ts_file <- system.file("examples/test.trees", package = "RcppTskit") #' tc <- tc_load(ts_file) - #' parent <- 0L - #' child <- 1L + #' child <- tc$node_table_add_row(time = 0.0) #' n_before <- tc$num_edges() #' new_id <- tc$edge_table_add_row( - #' left = 0, right = 1, parent = parent, child = child + #' left = 0, right = 50, parent = 16L, child = child #' ) #' new_id <- tc$edge_table_add_row( - #' left = 1, right = 2, parent = parent, child = child, metadata = "abc" + #' left = 50, right = 75, parent = 17L, child = child, metadata = "abc" #' ) #' new_id <- tc$edge_table_add_row( - #' left = 2, right = 3, parent = parent, child = child, metadata = charToRaw("cba") + #' left = 75, right = 100, parent = 18L, child = child, metadata = charToRaw("cba") #' ) #' n_after <- tc$num_edges() edge_table_add_row = function( diff --git a/RcppTskit/man/TableCollection.Rd b/RcppTskit/man/TableCollection.Rd index 513f731..8f54de0 100644 --- a/RcppTskit/man/TableCollection.Rd +++ b/RcppTskit/man/TableCollection.Rd @@ -125,17 +125,16 @@ tc$num_edges() ts_file <- system.file("examples/test.trees", package = "RcppTskit") tc <- tc_load(ts_file) -parent <- 0L -child <- 1L +child <- tc$node_table_add_row(time = 0.0) n_before <- tc$num_edges() new_id <- tc$edge_table_add_row( - left = 0, right = 1, parent = parent, child = child + left = 0, right = 50, parent = 16L, child = child ) new_id <- tc$edge_table_add_row( - left = 1, right = 2, parent = parent, child = child, metadata = "abc" + left = 50, right = 75, parent = 17L, child = child, metadata = "abc" ) new_id <- tc$edge_table_add_row( - left = 2, right = 3, parent = parent, child = child, metadata = charToRaw("cba") + left = 75, right = 100, parent = 18L, child = child, metadata = charToRaw("cba") ) n_after <- tc$num_edges() @@ -619,11 +618,11 @@ Add a row to the nodes table. \item{\code{time}}{numeric time value for the new node.} -\item{\code{population}}{integer population row ID (0-based, or \code{-1}); -\code{NULL} maps to \code{-1}.} +\item{\code{population}}{integer population row ID (0-based); +use \code{-1} if not known - \code{NULL} maps to \code{-1}.} -\item{\code{individual}}{integer individual row ID (0-based, or \code{-1}); -\code{NULL} maps to \code{-1}.} +\item{\code{individual}}{integer individual row ID (0-based); +use \code{-1} if not known - \code{NULL} maps to \code{-1}.} \item{\code{metadata}}{for the new node; accepts \code{NULL}, a raw vector, or a character of length 1.} @@ -723,17 +722,16 @@ Integer row ID (0-based) of the newly added edge. \if{html}{\out{
}} \preformatted{ts_file <- system.file("examples/test.trees", package = "RcppTskit") tc <- tc_load(ts_file) -parent <- 0L -child <- 1L +child <- tc$node_table_add_row(time = 0.0) n_before <- tc$num_edges() new_id <- tc$edge_table_add_row( - left = 0, right = 1, parent = parent, child = child + left = 0, right = 50, parent = 16L, child = child ) new_id <- tc$edge_table_add_row( - left = 1, right = 2, parent = parent, child = child, metadata = "abc" + left = 50, right = 75, parent = 17L, child = child, metadata = "abc" ) new_id <- tc$edge_table_add_row( - left = 2, right = 3, parent = parent, child = child, metadata = charToRaw("cba") + left = 75, right = 100, parent = 18L, child = child, metadata = charToRaw("cba") ) n_after <- tc$num_edges() } diff --git a/RcppTskit/src/RcppTskit.cpp b/RcppTskit/src/RcppTskit.cpp index e38e676..aeaaf63 100644 --- a/RcppTskit/src/RcppTskit.cpp +++ b/RcppTskit/src/RcppTskit.cpp @@ -1246,18 +1246,20 @@ Rcpp::List rtsk_table_collection_metadata_length(const SEXP tc) { // @param flags passed to \code{tskit C}. // @param location numeric vector with the location of the new individual // (can be \code{NULL}). -// @param parents integer vector with parent individual IDs +// @param parents integer vector with parent individual IDs (0-based) // (can be \code{NULL}). // @param metadata raw vector with metadata bytes // (can be \code{NULL}). // @details This function calls // \url{https://tskit.dev/tskit/docs/stable/c-api.html#c.tsk_individual_table_add_row} // on the individuals table of \code{tc}. -// @return The 0-based row ID of the newly added individual. +// @return The row ID (0-based) of the newly added individual. // @examples // ts_file <- system.file("examples/test.trees", package = "RcppTskit") // tc_xptr <- RcppTskit:::rtsk_table_collection_load(ts_file) // n_before <- RcppTskit:::rtsk_table_collection_get_num_individuals(tc_xptr) +// m_before +// <- RcppTskit:::rtsk_table_collection_metadata_length(tc_xptr)$individuals // tc_py <- RcppTskit:::rtsk_table_collection_r_to_py(tc_xptr) // tc_py$individuals$max_rows // tc_py$individuals["flags"] @@ -1279,8 +1281,13 @@ Rcpp::List rtsk_table_collection_metadata_length(const SEXP tc) { // new_id <- RcppTskit:::rtsk_individual_table_add_row(tc = tc_xptr, flags = 3L, // location = c(2, 11), parents = c(1L, 3L), metadata = charToRaw("abc")) // n_after <- RcppTskit:::rtsk_table_collection_get_num_individuals(tc_xptr) -// new_id == as.integer(n_before) && n_after == n_before + 3L -// tc_py <- RcppTskit:::rtsk_table_collection_r_to_py(tc_xptr) +// m_after <- +// RcppTskit:::rtsk_table_collection_metadata_length(tc_xptr)$individuals +// new_id == n_after - 1L +// n_after == n_before + 3L +// m_after == m_before + 3L +// tc_py <- +// RcppTskit:::rtsk_table_collection_r_to_py(tc_xptr) // tc_py$individuals$max_rows // tc_py$individuals["flags"] // tc_py$individuals["location"] @@ -1340,18 +1347,21 @@ int rtsk_individual_table_add_row( // \code{tsk_table_collection_t} object. // @param flags passed to \code{tskit C}. // @param time numeric time value for the new node. -// @param population integer population row ID (0-based, or \code{-1}). -// @param individual integer individual row ID (0-based, or \code{-1}). +// @param population integer population row ID (0-based); +// use \code{-1} if not known. +// @param individual integer individual row ID (0-based); +// use \code{-1} if not known. // @param metadata raw vector with metadata bytes // (can be \code{NULL}). // @details This function calls // \url{https://tskit.dev/tskit/docs/stable/c-api.html#c.tsk_node_table_add_row} // on the nodes table of \code{tc}. -// @return The 0-based row ID of the newly added node. +// @return The row ID (0-based) of the newly added node. // @examples // ts_file <- system.file("examples/test.trees", package = "RcppTskit") // tc_xptr <- RcppTskit:::rtsk_table_collection_load(ts_file) // n_before <- RcppTskit:::rtsk_table_collection_get_num_nodes(tc_xptr) +// m_before <- RcppTskit:::rtsk_table_collection_metadata_length(tc_xptr)$nodes // tc_py <- RcppTskit:::rtsk_table_collection_r_to_py(tc_xptr) // tc_py$nodes$max_rows // tc_py$nodes["flags"] @@ -1370,7 +1380,10 @@ int rtsk_individual_table_add_row( // metadata = charToRaw("abc") // ) // n_after <- RcppTskit:::rtsk_table_collection_get_num_nodes(tc_xptr) -// new_id == as.integer(n_before) && n_after == n_before + 3L +// m_after <- RcppTskit:::rtsk_table_collection_metadata_length(tc_xptr)$nodes +// new_id == n_after - 1L +// n_after == n_before + 4L +// m_after == m_before + 3L // tc_py <- RcppTskit:::rtsk_table_collection_r_to_py(tc_xptr) // tc_py$nodes$max_rows // tc_py$nodes["flags"] @@ -1428,27 +1441,29 @@ int rtsk_node_table_add_row( // @details This function calls // \url{https://tskit.dev/tskit/docs/stable/c-api.html#c.tsk_edge_table_add_row} // on the edges table of \code{tc}. -// @return The 0-based row ID of the newly added edge. +// @return The row ID (0-based) of the newly added edge. // @examples // ts_file <- system.file("examples/test.trees", package = "RcppTskit") // tc_xptr <- RcppTskit:::rtsk_table_collection_load(ts_file) -// parent <- 0L -// child <- 1L +// child <- rtsk_node_table_add_row(tc_xptr, time = 0.0) // n_before <- RcppTskit:::rtsk_table_collection_get_num_edges(tc_xptr) -// m_before <- -// RcppTskit:::rtsk_table_collection_metadata_length(tc_xptr)[["edges"]] new_id -// <- RcppTskit:::rtsk_edge_table_add_row( -// tc = tc_xptr, left = 0, right = 1, parent = parent, child = child +// m_before <- RcppTskit:::rtsk_table_collection_metadata_length(tc_xptr)$edges +// new_id <- RcppTskit:::rtsk_edge_table_add_row( +// tc = tc_xptr, left = 0, right = 50, parent = 16L, child = child // ) // new_id <- RcppTskit:::rtsk_edge_table_add_row( -// tc = tc_xptr, left = 1, right = 2, parent = parent, child = child, -// metadata = charToRaw("abc") +// tc = tc_xptr, left = 50, right = 75, parent = 17L, child = child, +// metadata = "abc" +// ) +// new_id <- RcppTskit:::rtsk_edge_table_add_row( +// tc = tc_xptr, left = 75, right = 100, parent = 18L, child = child, +// metadata = charToRaw("cba") // ) // n_after <- RcppTskit:::rtsk_table_collection_get_num_edges(tc_xptr) -// m_after <- -// RcppTskit:::rtsk_table_collection_metadata_length(tc_xptr)[["edges"]] new_id -// == as.integer(n_before) && n_after == n_before + 2L && m_after == m_before + -// 3L +// m_after <- RcppTskit:::rtsk_table_collection_metadata_length(tc_xptr)$edges +// new_id == n_after - 1L +// n_after == n_before + 3L +// m_after == m_before + 3L // [[Rcpp::export]] int rtsk_edge_table_add_row( const SEXP tc, const double left, const double right, const int parent, diff --git a/RcppTskit/tests/testthat/test_TableCollection.R b/RcppTskit/tests/testthat/test_TableCollection.R index f31751a..4b5752c 100644 --- a/RcppTskit/tests/testthat/test_TableCollection.R +++ b/RcppTskit/tests/testthat/test_TableCollection.R @@ -282,7 +282,7 @@ test_that("individual_table_add_row wrapper expands the table collection and han tc_xptr <- rtsk_table_collection_load(ts_file) n_before <- rtsk_table_collection_get_num_individuals(tc_xptr) - m_before <- rtsk_table_collection_metadata_length(tc_xptr)[["individuals"]] + m_before <- rtsk_table_collection_metadata_length(tc_xptr)$individuals expect_error( rtsk_individual_table_add_row(tc_xptr, flags = -1L), @@ -301,7 +301,7 @@ test_that("individual_table_add_row wrapper expands the table collection and han as.integer(n_before) + 1L ) expect_equal( - as.integer(rtsk_table_collection_metadata_length(tc_xptr)[["individuals"]]), + as.integer(rtsk_table_collection_metadata_length(tc_xptr)$individuals), as.integer(m_before) + 3L ) @@ -317,9 +317,7 @@ test_that("individual_table_add_row wrapper expands the table collection and han tc_xptr <- rtsk_table_collection_load(ts_file) n0 <- as.integer(rtsk_table_collection_get_num_individuals(tc_xptr)) - m0 <- as.integer(rtsk_table_collection_metadata_length(tc_xptr)[[ - "individuals" - ]]) + m0 <- as.integer(rtsk_table_collection_metadata_length(tc_xptr)$individuals) # Defaults map to NULL in the generated R wrapper and should be accepted. id0 <- rtsk_individual_table_add_row(tc_xptr) @@ -329,7 +327,7 @@ test_that("individual_table_add_row wrapper expands the table collection and han n0 + 1L ) expect_equal( - as.integer(rtsk_table_collection_metadata_length(tc_xptr)[["individuals"]]), + as.integer(rtsk_table_collection_metadata_length(tc_xptr)$individuals), m0 ) @@ -375,20 +373,20 @@ test_that("individual_table_add_row wrapper expands the table collection and han ) expect_equal(as.integer(tc$num_individuals()), n_before_method + 1L) - m_before_char <- as.integer(rtsk_table_collection_metadata_length(tc$xptr)[[ - "individuals" - ]]) + m_before_char <- as.integer( + rtsk_table_collection_metadata_length(tc$xptr)$individuals + ) expect_no_warning(tc$individual_table_add_row(metadata = "abc")) expect_equal( - as.integer(rtsk_table_collection_metadata_length(tc$xptr)[["individuals"]]), + as.integer(rtsk_table_collection_metadata_length(tc$xptr)$individuals), m_before_char + 3L ) - m_before_raw <- as.integer(rtsk_table_collection_metadata_length(tc$xptr)[[ - "individuals" - ]]) + m_before_raw <- as.integer( + rtsk_table_collection_metadata_length(tc$xptr)$individuals + ) expect_no_error(tc$individual_table_add_row(metadata = charToRaw("xyz"))) expect_equal( - as.integer(rtsk_table_collection_metadata_length(tc$xptr)[["individuals"]]), + as.integer(rtsk_table_collection_metadata_length(tc$xptr)$individuals), m_before_raw + 3L ) expect_error( @@ -419,7 +417,7 @@ test_that("node_table_add_row wrapper expands the table collection and handles i tc_xptr <- rtsk_table_collection_load(ts_file) n_before <- rtsk_table_collection_get_num_nodes(tc_xptr) - m_before <- rtsk_table_collection_metadata_length(tc_xptr)[["nodes"]] + m_before <- rtsk_table_collection_metadata_length(tc_xptr)$nodes expect_error( rtsk_node_table_add_row(tc_xptr, flags = -1L), @@ -440,7 +438,7 @@ test_that("node_table_add_row wrapper expands the table collection and handles i as.integer(n_before) + 1L ) expect_equal( - as.integer(rtsk_table_collection_metadata_length(tc_xptr)[["nodes"]]), + as.integer(rtsk_table_collection_metadata_length(tc_xptr)$nodes), as.integer(m_before) + 3L ) @@ -456,9 +454,9 @@ test_that("node_table_add_row wrapper expands the table collection and handles i tc_xptr <- rtsk_table_collection_load(ts_file) n0 <- as.integer(rtsk_table_collection_get_num_nodes(tc_xptr)) - m0 <- as.integer(rtsk_table_collection_metadata_length(tc_xptr)[["nodes"]]) + m0 <- as.integer(rtsk_table_collection_metadata_length(tc_xptr)$nodes) - # Defaults map to NULL in the generated R wrapper and should be accepted. + # Testing defaults id0 <- rtsk_node_table_add_row(tc_xptr) expect_equal(id0, n0) expect_equal( @@ -466,7 +464,7 @@ test_that("node_table_add_row wrapper expands the table collection and handles i n0 + 1L ) expect_equal( - as.integer(rtsk_table_collection_metadata_length(tc_xptr)[["nodes"]]), + as.integer(rtsk_table_collection_metadata_length(tc_xptr)$nodes), m0 ) @@ -489,6 +487,13 @@ test_that("node_table_add_row wrapper expands the table collection and handles i ), regexp = "population must not be NA_integer_ in rtsk_node_table_add_row" ) + expect_error( + rtsk_node_table_add_row( + tc = tc_xptr, + flags = 0L, + population = NULL + ) + ) expect_error( rtsk_node_table_add_row( tc = tc_xptr, @@ -497,6 +502,13 @@ test_that("node_table_add_row wrapper expands the table collection and handles i ), regexp = "individual must not be NA_integer_ in rtsk_node_table_add_row" ) + expect_error( + rtsk_node_table_add_row( + tc = tc_xptr, + flags = 0L, + individual = NULL + ) + ) tc <- TableCollection$new(xptr = tc_xptr) n_before_method <- as.integer(tc$num_nodes()) @@ -513,22 +525,23 @@ test_that("node_table_add_row wrapper expands the table collection and handles i expect_no_error(tc$node_table_add_row(population = NULL, individual = NULL)) expect_equal(as.integer(tc$num_nodes()), n_before_method + 2L) - m_before_char <- as.integer(rtsk_table_collection_metadata_length(tc$xptr)[[ - "nodes" - ]]) + m_before_char <- as.integer( + rtsk_table_collection_metadata_length(tc$xptr)$nodes + ) expect_no_warning(tc$node_table_add_row(metadata = "abc")) expect_equal( - as.integer(rtsk_table_collection_metadata_length(tc$xptr)[["nodes"]]), + as.integer(rtsk_table_collection_metadata_length(tc$xptr)$nodes), m_before_char + 3L ) - m_before_raw <- as.integer(rtsk_table_collection_metadata_length(tc$xptr)[[ - "nodes" - ]]) + m_before_raw <- as.integer( + rtsk_table_collection_metadata_length(tc$xptr)$nodes + ) expect_no_error(tc$node_table_add_row(metadata = charToRaw("xyz"))) expect_equal( - as.integer(rtsk_table_collection_metadata_length(tc$xptr)[["nodes"]]), + as.integer(rtsk_table_collection_metadata_length(tc$xptr)$nodes), m_before_raw + 3L ) + expect_error( tc$node_table_add_row(population = NA_integer_), regexp = "population must not be NA_integer_ in rtsk_node_table_add_row" @@ -558,12 +571,12 @@ test_that("node_table_add_row wrapper expands the table collection and handles i test_that("edge_table_add_row wrapper expands the table collection and handles inputs", { ts_file <- system.file("examples/test.trees", package = "RcppTskit") tc_xptr <- rtsk_table_collection_load(ts_file) - expect_gt(as.integer(rtsk_table_collection_get_num_nodes(tc_xptr)), 1L) - parent <- 0L - child <- 1L n_before <- rtsk_table_collection_get_num_edges(tc_xptr) - m_before <- rtsk_table_collection_metadata_length(tc_xptr)[["edges"]] + m_before <- rtsk_table_collection_metadata_length(tc_xptr)$edges + + parent <- 0L + child <- 1L new_id <- rtsk_edge_table_add_row( tc = tc_xptr, @@ -579,7 +592,7 @@ test_that("edge_table_add_row wrapper expands the table collection and handles i as.integer(n_before) + 1L ) expect_equal( - as.integer(rtsk_table_collection_metadata_length(tc_xptr)[["edges"]]), + as.integer(rtsk_table_collection_metadata_length(tc_xptr)$edges), as.integer(m_before) + 3L ) @@ -598,11 +611,9 @@ test_that("edge_table_add_row wrapper expands the table collection and handles i ) tc_xptr <- rtsk_table_collection_load(ts_file) - parent <- 0L - child <- 1L n0 <- as.integer(rtsk_table_collection_get_num_edges(tc_xptr)) - m0 <- as.integer(rtsk_table_collection_metadata_length(tc_xptr)[["edges"]]) + m0 <- as.integer(rtsk_table_collection_metadata_length(tc_xptr)$edges) # Explicit NULL metadata should be accepted. id0 <- rtsk_edge_table_add_row( @@ -619,7 +630,7 @@ test_that("edge_table_add_row wrapper expands the table collection and handles i n0 + 1L ) expect_equal( - as.integer(rtsk_table_collection_metadata_length(tc_xptr)[["edges"]]), + as.integer(rtsk_table_collection_metadata_length(tc_xptr)$edges), m0 ) @@ -707,9 +718,9 @@ test_that("edge_table_add_row wrapper expands the table collection and handles i ) expect_equal(as.integer(tc$num_edges()), n_before_method + 1L) - m_before_char <- as.integer(rtsk_table_collection_metadata_length(tc$xptr)[[ - "edges" - ]]) + m_before_char <- as.integer( + rtsk_table_collection_metadata_length(tc$xptr)$edges + ) expect_no_warning( tc$edge_table_add_row( left = 3, @@ -720,12 +731,12 @@ test_that("edge_table_add_row wrapper expands the table collection and handles i ) ) expect_equal( - as.integer(rtsk_table_collection_metadata_length(tc$xptr)[["edges"]]), + as.integer(rtsk_table_collection_metadata_length(tc$xptr)$edges), m_before_char + 3L ) - m_before_raw <- as.integer(rtsk_table_collection_metadata_length(tc$xptr)[[ - "edges" - ]]) + m_before_raw <- as.integer( + rtsk_table_collection_metadata_length(tc$xptr)$edges + ) expect_no_error( tc$edge_table_add_row( left = 4, @@ -736,7 +747,7 @@ test_that("edge_table_add_row wrapper expands the table collection and handles i ) ) expect_equal( - as.integer(rtsk_table_collection_metadata_length(tc$xptr)[["edges"]]), + as.integer(rtsk_table_collection_metadata_length(tc$xptr)$edges), m_before_raw + 3L ) expect_error( diff --git a/RcppTskit/vignettes/RcppTskit_intro.qmd b/RcppTskit/vignettes/RcppTskit_intro.qmd index fa2f318..b7e3989 100644 --- a/RcppTskit/vignettes/RcppTskit_intro.qmd +++ b/RcppTskit/vignettes/RcppTskit_intro.qmd @@ -270,23 +270,29 @@ ts2 <- tc$tree_sequence() help(package = "RcppTskit") ``` -Developers should also explore the low-level `R` and `C++` functions. +Developers should also explore the internal `R` and `C++` functions. Their names all start with `rtsk_` and are accessible via `RcppTskit:::`. +Since these are internal functions we instruct the linter `jarl` +not to warn about their use. For example, the above `R` function `ts_load()` effectively calls: ```{r} #| label: use_case_1_dev_funcs # Low-level R function, which further calls the C++ function +# jarl-ignore internal_function: exposing for demo/doc RcppTskit:::rtsk_treeseq_load # C++ function (see also the C++ source code) +# jarl-ignore internal_function: exposing for demo/doc RcppTskit:::`_RcppTskit_rtsk_treeseq_load` # The same as the ts_load() example, but exposing the external pointer +# jarl-ignore internal_function: exposing for demo/doc xptr <- RcppTskit:::rtsk_treeseq_load(ts_file) methods::is(xptr) # We pass the external pointer to other low-level functions +# jarl-ignore internal_function: exposing for demo/doc RcppTskit:::rtsk_treeseq_get_num_individuals(xptr) ```