diff --git a/.github/workflows/document.yaml b/.github/workflows/document.yaml index b339650..5adde8e 100644 --- a/.github/workflows/document.yaml +++ b/.github/workflows/document.yaml @@ -38,6 +38,7 @@ jobs: shell: Rscript {0} - name: Commit and push changes + working-directory: RcppTskit run: | git config --local user.name "$GITHUB_ACTOR" git config --local user.email "$GITHUB_ACTOR@users.noreply.github.com" diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index db58706..8127647 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -28,14 +28,14 @@ repos: hooks: - id: air-format name: air format - entry: RcppTskit/tools/run-local-tool.sh air format . + entry: RcppTskit/tools/run_local_tool.sh air format . language: system pass_filenames: false files: '\.(R|Rmd|rmd|qmd|Qmd)$' - id: jarl-lint name: jarl lint - entry: RcppTskit/tools/run-local-tool.sh jarl check . + entry: RcppTskit/tools/run_local_tool.sh jarl check . language: system pass_filenames: false files: '\.(R|Rmd|rmd|qmd|Qmd)$' @@ -48,6 +48,13 @@ repos: - id: clang-tidy name: clang-tidy for RcppTskit - entry: python RcppTskit/tools/clang-tidy.py - language: python + entry: RcppTskit/tools/clang_tidy.py + language: system files: '\.(c|cc|cpp|cxx|h|hh|hpp|hxx)$' + + - id: check-sync-between-cpp-and-hpp + name: check sync between cpp and hpp options and defaults + entry: RcppTskit/tools/check_sync_between_cpp_and_hpp.R + language: system + pass_filenames: false + files: '^(RcppTskit/src/RcppTskit\.cpp|RcppTskit/inst/include/RcppTskit_public\.hpp)$' diff --git a/AGENTS.md b/AGENTS.md index 44de22b..526878f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -167,7 +167,7 @@ Hook responsibilities: * `air format .`: format R, Rmd, and qmd files. * `jarl check .`: lint R, Rmd, and qmd files. * `clang-format -i --style=file`: format C/C++ sources and headers. -* `python RcppTskit/tools/clang-tidy.py`: run clang-tidy checks for C/C++. +* `python RcppTskit/tools/clang_tidy.py`: run clang-tidy checks for C/C++. * Standard pre-commit hygiene hooks: whitespace, line endings, YAML checks, merge-conflict markers, and large-file checks. @@ -202,7 +202,7 @@ export CLANG_TIDY="$(brew --prefix llvm)/bin/clang-tidy" Then you can run the wrapper script directly: ```sh -python RcppTskit/tools/clang-tidy.py RcppTskit/src/RcppTskit.cpp +python RcppTskit/tools/clang_tidy.py RcppTskit/src/RcppTskit.cpp ``` ### Coverage with covr diff --git a/README.md b/README.md index 4c7eb65..050cf30 100644 --- a/README.md +++ b/README.md @@ -17,10 +17,12 @@ The `Python` API can be called from `R` via the `reticulate` `R` package to seamlessly load and analyse a tree sequence, as described at https://tskit.dev/tutorials/RcppTskit.html. `RcppTskit` provides `R` access to the `tskit C` API for use cases where the -`reticulate` option is not optimal. For example, for high-performance and -low-level work with tree sequences. Currently, `RcppTskit` provides a limited -number of `R` functions due to the availability of extensive `Python` API and -the `reticulate` option. +`reticulate` option is not optimal. +For example, for high-performance and low-level work with tree sequences. +Currently, `RcppTskit` provides a limited number of functions +due to the availability of extensive `Python` API and the `reticulate` option. +The provided `RcppTskit R` API mirrors the `tskit Python` API, +while the `RcppTskit C++` API mirrors the `tskit C` API. See more details on the state of the tree sequence ecosystem and aims of `RcppTskit` in [the introduction vignette](https://highlanderlab.r-universe.dev/articles/RcppTskit/RcppTskit_intro.html) ([source](RcppTskit/vignettes/RcppTskit_intro.qmd)). @@ -153,9 +155,13 @@ Specifically, we use: To install the hooks, run: ``` -pre-commit install +pre-commit install --install-hooks +pre-commit install --hook-type pre-push ``` +Run these once per clone. +This enables automatic checks on `commit` and `push`. + ### tskit If you plan to update `tskit`, follow instructions in `extern/README.md`. @@ -203,12 +209,18 @@ On Windows, replace `tar.gz` with `zip`. ### Pre-commit run -Before committing your changes, run the `pre-commit` hooks to ensure code quality: +When committing your changes, +`pre-commit` hooks should kick-in automatically +to ensure code quality. +Manually, you can run them using: ``` -# pre-commit autoupdate # to update the hooks -pre-commit run --all-files -# pre-commit run +pre-commit autoupdate # to update the hooks +pre-commit run # on changed files +pre-commit run --all-files # on all files +pre-commit run # just a specific hook +pre-commit run --all-files # ... on all files +# see also --hook-stage option ``` ### Continuous integration diff --git a/RcppTskit/DESCRIPTION b/RcppTskit/DESCRIPTION index 93583f8..66d3f85 100644 --- a/RcppTskit/DESCRIPTION +++ b/RcppTskit/DESCRIPTION @@ -2,7 +2,7 @@ Type: Package Package: RcppTskit Title: 'R' Access to the 'tskit C' API Version: 0.3.0 -Date: 2026-01-27 +Date: 2026-03-01 Authors@R: c( person("Gregor", "Gorjanc", , "gregor.gorjanc@gmail.com", role = c("aut", "cre", "cph"), comment = c(ORCID = "0000-0001-8008-2787")), @@ -16,14 +16,16 @@ Description: 'Tskit' enables efficient storage, manipulation, and analysis described in Jeffrey et al. (2026) . See also for project news, documentation, and tutorials. 'Tskit' provides 'Python', 'C', and 'Rust' application - programming interfaces (APIs). The 'Python' API can be called from 'R' via - the 'reticulate' package to load and analyse tree sequences as + programming interfaces (APIs). The 'Python' API can be called from 'R' + via the 'reticulate' package to load and analyse tree sequences as described at . 'RcppTskit' provides 'R' access to the 'tskit C' API for cases where the 'reticulate' option is not optimal; for example, high-performance or low-level work with tree sequences. Currently, 'RcppTskit' provides a - limited set of 'R' functions because the 'Python' API and 'reticulate' - already covers most needs. + limited set of functions because the 'Python' API and 'reticulate' + already cover most needs. The provided `RcppTskit R` API mirrors the + `tskit Python` API, while the `RcppTskit C++` API mirrors the `tskit + C` API. License: MIT + file LICENSE URL: https://github.com/HighlanderLab/RcppTskit BugReports: https://github.com/HighlanderLab/RcppTskit/issues diff --git a/RcppTskit/NEWS.md b/RcppTskit/NEWS.md index f2786b3..bce12ab 100644 --- a/RcppTskit/NEWS.md +++ b/RcppTskit/NEWS.md @@ -4,11 +4,11 @@ All notable changes to `RcppTskit` are documented in this file. The file format is based on [Keep a Changelog](https://keepachangelog.com), and releases adhere to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.3.0] 2026-MM-DD +## [0.3.0] 2026-03-02 ### Added (new features) -- Added the following scalar getters to match tskit C/Python API +- Added the following scalar getters to match `tskit C/Python` API - `TreeSequence$discrete_genome()` to query whether genome coordinates are discrete integer values. - `TreeSequence$has_reference_sequence()` to query whether a tree sequence @@ -25,41 +25,56 @@ and releases adhere to [Semantic Versioning](https://semver.org/spec/v2.0.0.html - `TableCollection$has_index()` to query whether edge indexes are present. - Added a public header and defaults for downstream use of `C++` functions in `inst/include/RcppTskit_public.hpp`, included by `inst/include/RcppTskit.hpp`. +- Added `TableCollection$build_index()` to build indexes and + `TableCollection$drop_index()` to drop indexes. - TODO ### Changed -- Renamed low-level external-pointer API names from `*_ptr_*` to `*_xptr_*` - (for example, `ts_ptr_load()` to `ts_xptr_load()`) to make external-pointer - vs standard/raw-pointer semantics explicit. +- Renamed low-level C++ and R API names such that we map onto `tskit C` API, + for example, `ts_ptr_load()` to `rtsk_treeseq_load()`. + This is an internal breaking change, but in a good direction now that the + package is still young and in experimental mode. +- Renamed `TreeSequence` and `TableCollection` external-pointer field and + constructor argument from `pointer` to `xptr`. +- Ensured `TableCollection$tree_sequence()` matches `tskit Python` API: + it now builds indexes on the `TableCollection`, if indexes are not present. +- TODO + +### Maintenance + +- Turn vignette URL as hyperlinks and similar cosmetics. +- State mirroring of the `R/Python` APIs and `C++/C` APIs across the package. +- TODO ## [0.2.0] - 2026-02-22 ### Added (new features) -- Added TableCollection R6 class alongside `tc_load()` or `TableCollection$new()`, - as well as `dump()`, `tree_sequence()`, and `print()` methods. +- Added `TableCollection` `R6` class alongside `tc_load()` or + `TableCollection$new()`, as well as `dump()`, `tree_sequence()`, and + `print()` methods. -- Added `TreeSequence$dump_tables()` to copy tables into a TableCollection. +- Added `TreeSequence$dump_tables()` to copy tables into a `TableCollection`. -- Added TableCollection and reticulate Python round-trip helpers: +- Added `TableCollection` and reticulate `Python` round-trip helpers: `TableCollection$r_to_py()` and `tc_py_to_r()`. -- Changed the R API to follow tskit Python API for loading: +- Changed the `R` API to follow `tskit Python` API for loading: `ts_load()`, `tc_load()`, `TreeSequence$new()`, and `TableCollection$new()` now use `skip_tables` and `skip_reference_sequence` logical arguments instead of an integer `options` bitmask. - Removed user-facing `options` from `TreeSequence$dump()`, `TreeSequence$dump_tables()`, `TableCollection$dump()`, and - `TableCollection$tree_sequence()` to match R API with the tskit Python API, - while C++ API has the bitwise `options` like the tskit C API. + `TableCollection$tree_sequence()` to match `R` API with the `tskit Python` API, + while `C++` API has the bitwise `options` like the `tskit C` API. -- The bitwise options passed to C++ are now validated. +- The bitwise options passed to `C++` are now validated. ### Changed -- We now specify C++20 standard to go around the CRAN Windows issue, +- We now specify `C++20` standard to go around the CRAN Windows issue, see #63 for further details. ### Maintenance @@ -81,21 +96,21 @@ This is the first release. ### Added (new features) -- Initial version of RcppTskit using the tskit C API (1.3.0). +- Initial version of `RcppTskit` using the `tskit C` API (1.3.0). -- TreeSequence R6 class so R code looks Pythonic. +- `TreeSequence R6` class so `R` code looks Pythonic. -- `ts_load()` or `TreeSequence$new()` to load a tree sequence from file into R. +- `ts_load()` or `TreeSequence$new()` to load a tree sequence from file into `R`. - Methods to summarise a tree sequence and its contents `ts$print()`, `ts$num_nodes()`, etc. - Method to save a tree sequence to a file `ts$dump()`. -- Method to push tree sequence between R and reticulate Python +- Method to push tree sequence between `R` and reticulate `Python` `ts$r_to_py()` and `ts_py_to_r()`. -- Most methods have an underlying (unexported) C++ function that works with +- Most methods have an underlying (unexported) `C++` function that works with a pointer to tree sequence object, for example, `RcppTskit:::ts_ptr_load()`. - All implemented functionality is documented and demonstrated with a vignette. diff --git a/RcppTskit/R/Class-TableCollection.R b/RcppTskit/R/Class-TableCollection.R index c8ea710..94a6044 100644 --- a/RcppTskit/R/Class-TableCollection.R +++ b/RcppTskit/R/Class-TableCollection.R @@ -7,15 +7,15 @@ TableCollection <- R6Class( classname = "TableCollection", public = list( - #' @field pointer external pointer to the table collection - pointer = "externalptr", + #' @field xptr external pointer to the table collection + xptr = "externalptr", - #' @description Create a \code{\link{TableCollection}} from a file or a pointer. + #' @description Create a \code{\link{TableCollection}} from a file or an external pointer. #' @param file a string specifying the full path of the tree sequence file. #' @param skip_tables logical; if \code{TRUE}, load only non-table information. #' @param skip_reference_sequence logical; if \code{TRUE}, skip loading #' reference genome sequence information. - #' @param pointer an external pointer (\code{externalptr}) to a table collection. + #' @param xptr an external pointer (\code{externalptr}) to a table collection. #' @details See the corresponding Python function at #' \url{https://github.com/tskit-dev/tskit/blob/dc394d72d121c99c6dcad88f7a4873880924dd72/python/tskit/tables.py#L3463}. #' @return A \code{\link{TableCollection}} object. @@ -28,13 +28,15 @@ TableCollection <- R6Class( file, skip_tables = FALSE, skip_reference_sequence = FALSE, - pointer = NULL + xptr = NULL ) { - if (missing(file) && is.null(pointer)) { - stop("Provide a file or a pointer!") + if (missing(file) && is.null(xptr)) { + stop("Provide a file or an external pointer (xptr)!") } - if (!missing(file) && !is.null(pointer)) { - stop("Provide either a file or a pointer, but not both!") + if (!missing(file) && !is.null(xptr)) { + stop( + "Provide either a file or an external pointer (xptr), but not both!" + ) } if (!missing(file)) { if (!is.character(file)) { @@ -44,12 +46,17 @@ TableCollection <- R6Class( skip_tables = skip_tables, skip_reference_sequence = skip_reference_sequence ) - self$pointer <- tc_xptr_load(file = file, options = options) + self$xptr <- rtsk_table_collection_load( + filename = file, + options = options + ) } else { - if (!is.null(pointer) && !is(pointer, "externalptr")) { - stop("pointer must be an object of externalptr class!") + if (!is.null(xptr) && !is(xptr, "externalptr")) { + stop( + "external pointer (xptr) must be an object of externalptr class!" + ) } - self$pointer <- pointer + self$xptr <- xptr } invisible(self) }, @@ -67,7 +74,7 @@ TableCollection <- R6Class( #' tc$write(dump_file) # alias #' \dontshow{file.remove(dump_file)} dump = function(file) { - tc_xptr_dump(self$pointer, file = file, options = 0L) + rtsk_table_collection_dump(self$xptr, filename = file, options = 0L) }, #' @description Alias for \code{\link[=TableCollection]{TableCollection$dump}}. @@ -86,13 +93,11 @@ TableCollection <- R6Class( #' ts <- tc$tree_sequence() #' is(ts) tree_sequence = function() { - # See https://tskit.dev/tskit/docs/stable/c-api.html#c.TSK_TS_INIT_BUILD_INDEXES - # TSK_TS_INIT_BUILD_INDEXES (1 << 0) is bitwShiftL(1L, 0) or just 1L - # TODO: Should we also use TSK_TS_INIT_COMPUTE_MUTATION_PARENTS in TableCollection$tree_sequence()? #65 - # https://github.com/HighlanderLab/RcppTskit/issues/65 - init_options <- bitwShiftL(1L, 0) - ts_xptr <- tc_xptr_to_ts_xptr(self$pointer, options = init_options) - TreeSequence$new(pointer = ts_xptr) + if (!self$has_index()) { + self$build_index() + } + ts_xptr <- rtsk_treeseq_init(self$xptr) + TreeSequence$new(xptr = ts_xptr) }, #' @description Get the sequence length. @@ -101,7 +106,7 @@ TableCollection <- R6Class( #' tc <- tc_load(tc_file) #' tc$sequence_length() sequence_length = function() { - tc_xptr_sequence_length(self$pointer) + rtsk_table_collection_get_sequence_length(self$xptr) }, #' @description Get the time units string. @@ -110,7 +115,7 @@ TableCollection <- R6Class( #' tc <- tc_load(tc_file) #' tc$time_units() time_units = function() { - tc_xptr_time_units(self$pointer) + rtsk_table_collection_get_time_units(self$xptr) }, #' @description Get whether the table collection has edge indexes. @@ -119,7 +124,37 @@ TableCollection <- R6Class( #' tc <- tc_load(tc_file) #' tc$has_index() has_index = function() { - tc_xptr_has_index(self$pointer) + rtsk_table_collection_has_index(self$xptr) + }, + + #' @description Build edge indexes for this table collection. + #' @details See the corresponding Python function at + #' \url{https://tskit.dev/tskit/docs/latest/python-api.html#tskit.TableCollection.build_index}. + #' @return No return value; called for side effects. + #' @examples + #' tc_file <- system.file("examples/test.trees", package = "RcppTskit") + #' tc <- tc_load(tc_file) + #' tc$has_index() + #' tc$drop_index() + #' tc$has_index() + #' tc$build_index() + #' tc$has_index() + build_index = function() { + rtsk_table_collection_build_index(self$xptr) + }, + + #' @description Drop edge indexes for this table collection. + #' @details See the corresponding Python function at + #' \url{https://tskit.dev/tskit/docs/latest/python-api.html#tskit.TableCollection.drop_index}. + #' @return No return value; called for side effects. + #' @examples + #' tc_file <- system.file("examples/test.trees", package = "RcppTskit") + #' tc <- tc_load(tc_file) + #' tc$has_index() + #' tc$drop_index() + #' tc$has_index() + drop_index = function() { + rtsk_table_collection_drop_index(self$xptr) }, #' @description Get whether the table collection has a reference genome sequence. @@ -131,7 +166,7 @@ TableCollection <- R6Class( #' tc2 <- tc_load(tc_file2) #' tc2$has_reference_sequence() has_reference_sequence = function() { - tc_xptr_has_reference_sequence(self$pointer) + rtsk_table_collection_has_reference_sequence(self$xptr) }, #' @description Get the file UUID string. @@ -142,7 +177,7 @@ TableCollection <- R6Class( #' tc <- tc_load(tc_file) #' tc$file_uuid() file_uuid = function() { - tc_xptr_file_uuid(self$pointer) + rtsk_table_collection_get_file_uuid(self$xptr) }, #' @description This function saves a table collection from R to disk and @@ -175,8 +210,8 @@ TableCollection <- R6Class( #' } #' } r_to_py = function(tskit_module = get_tskit_py(), cleanup = TRUE) { - tc_xptr_r_to_py( - self$pointer, + rtsk_table_collection_r_to_py( + self$xptr, tskit_module = tskit_module, cleanup = cleanup ) @@ -192,7 +227,7 @@ TableCollection <- R6Class( #' tc$print() #' tc print = function() { - ret <- tc_xptr_print(self$pointer) + ret <- rtsk_table_collection_print(self$xptr) # These are not hit since testing is not interactive # nocov start if (interactive()) { diff --git a/RcppTskit/R/Class-TreeSequence.R b/RcppTskit/R/Class-TreeSequence.R index eb5de99..e61d3a0 100644 --- a/RcppTskit/R/Class-TreeSequence.R +++ b/RcppTskit/R/Class-TreeSequence.R @@ -7,16 +7,16 @@ TreeSequence <- R6Class( classname = "TreeSequence", public = list( - #' @field pointer external pointer to the tree sequence - pointer = "externalptr", + #' @field xptr external pointer to the tree sequence + xptr = "externalptr", - #' @description Create a \code{\link{TreeSequence}} from a file or a pointer. + #' @description Create a \code{\link{TreeSequence}} from a file or an external pointer. #' See \code{\link{ts_load}} for details and examples. #' @param file a string specifying the full path of the tree sequence file. #' @param skip_tables logical; if \code{TRUE}, load only non-table information. #' @param skip_reference_sequence logical; if \code{TRUE}, skip loading #' reference genome sequence information. - #' @param pointer an external pointer (\code{externalptr}) to a tree sequence. + #' @param xptr an external pointer (\code{externalptr}) to a tree sequence. #' @details See the corresponding Python function at #' \url{https://tskit.dev/tskit/docs/latest/python-api.html#tskit.load}. #' @return A \code{\link{TreeSequence}} object. @@ -34,13 +34,15 @@ TreeSequence <- R6Class( file, skip_tables = FALSE, skip_reference_sequence = FALSE, - pointer = NULL + xptr = NULL ) { - if (missing(file) && is.null(pointer)) { - stop("Provide a file or a pointer!") + if (missing(file) && is.null(xptr)) { + stop("Provide a file or an external pointer (xptr)!") } - if (!missing(file) && !is.null(pointer)) { - stop("Provide either a file or a pointer, but not both!") + if (!missing(file) && !is.null(xptr)) { + stop( + "Provide either a file or an external pointer (xptr), but not both!" + ) } if (!missing(file)) { if (!is.character(file)) { @@ -50,12 +52,14 @@ TreeSequence <- R6Class( skip_tables = skip_tables, skip_reference_sequence = skip_reference_sequence ) - self$pointer <- ts_xptr_load(file = file, options = options) + self$xptr <- rtsk_treeseq_load(filename = file, options = options) } else { - if (!is.null(pointer) && !is(pointer, "externalptr")) { - stop("pointer must be an object of externalptr class!") + if (!is.null(xptr) && !is(xptr, "externalptr")) { + stop( + "external pointer (xptr) must be an object of externalptr class!" + ) } - self$pointer <- pointer + self$xptr <- xptr } invisible(self) }, @@ -73,7 +77,7 @@ TreeSequence <- R6Class( #' ts$write(dump_file) # alias #' \dontshow{file.remove(dump_file)} dump = function(file) { - ts_xptr_dump(self$pointer, file = file, options = 0L) + rtsk_treeseq_dump(self$xptr, filename = file, options = 0L) }, #' @description Alias for \code{\link[=TreeSequence]{TreeSequence$dump}}. @@ -92,8 +96,8 @@ TreeSequence <- R6Class( #' tc <- ts$dump_tables() #' is(tc) dump_tables = function() { - tc_xptr <- ts_xptr_to_tc_xptr(self$pointer) - TableCollection$new(pointer = tc_xptr) + tc_xptr <- rtsk_treeseq_copy_tables(self$xptr) + TableCollection$new(xptr = tc_xptr) }, #' @description Print a summary of a tree sequence and its contents. @@ -106,7 +110,7 @@ TreeSequence <- R6Class( #' ts$print() #' ts print = function() { - ret <- ts_xptr_print(self$pointer) + ret <- rtsk_treeseq_print(self$xptr) # These are not hit since testing is not interactive # nocov start if (interactive()) { @@ -146,8 +150,8 @@ TreeSequence <- R6Class( #' } #' } r_to_py = function(tskit_module = get_tskit_py(), cleanup = TRUE) { - ts_xptr_r_to_py( - self$pointer, + rtsk_treeseq_r_to_py( + self$xptr, tskit_module = tskit_module, cleanup = cleanup ) @@ -159,7 +163,7 @@ TreeSequence <- R6Class( #' ts <- ts_load(ts_file) #' ts$num_provenances() num_provenances = function() { - ts_xptr_num_provenances(self$pointer) + rtsk_treeseq_get_num_provenances(self$xptr) }, #' @description Get the number of populations in a tree sequence. @@ -168,7 +172,7 @@ TreeSequence <- R6Class( #' ts <- ts_load(ts_file) #' ts$num_populations() num_populations = function() { - ts_xptr_num_populations(self$pointer) + rtsk_treeseq_get_num_populations(self$xptr) }, #' @description Get the number of migrations in a tree sequence. @@ -177,7 +181,7 @@ TreeSequence <- R6Class( #' ts <- ts_load(ts_file) #' ts$num_migrations() num_migrations = function() { - ts_xptr_num_migrations(self$pointer) + rtsk_treeseq_get_num_migrations(self$xptr) }, #' @description Get the number of individuals in a tree sequence. @@ -186,7 +190,7 @@ TreeSequence <- R6Class( #' ts <- ts_load(ts_file) #' ts$num_individuals() num_individuals = function() { - ts_xptr_num_individuals(self$pointer) + rtsk_treeseq_get_num_individuals(self$xptr) }, #' @description Get the number of samples (of nodes) in a tree sequence. @@ -195,7 +199,7 @@ TreeSequence <- R6Class( #' ts <- ts_load(ts_file) #' ts$num_samples() num_samples = function() { - ts_xptr_num_samples(self$pointer) + rtsk_treeseq_get_num_samples(self$xptr) }, #' @description Get the number of nodes in a tree sequence. @@ -204,7 +208,7 @@ TreeSequence <- R6Class( #' ts <- ts_load(ts_file) #' ts$num_nodes() num_nodes = function() { - ts_xptr_num_nodes(self$pointer) + rtsk_treeseq_get_num_nodes(self$xptr) }, #' @description Get the number of edges in a tree sequence. @@ -213,7 +217,7 @@ TreeSequence <- R6Class( #' ts <- ts_load(ts_file) #' ts$num_edges() num_edges = function() { - ts_xptr_num_edges(self$pointer) + rtsk_treeseq_get_num_edges(self$xptr) }, #' @description Get the number of trees in a tree sequence. @@ -222,7 +226,7 @@ TreeSequence <- R6Class( #' ts <- ts_load(ts_file) #' ts$num_trees() num_trees = function() { - ts_xptr_num_trees(self$pointer) + rtsk_treeseq_get_num_trees(self$xptr) }, #' @description Get the number of sites in a tree sequence. @@ -231,7 +235,7 @@ TreeSequence <- R6Class( #' ts <- ts_load(ts_file) #' ts$num_sites() num_sites = function() { - ts_xptr_num_sites(self$pointer) + rtsk_treeseq_get_num_sites(self$xptr) }, #' @description Get the number of mutations in a tree sequence. @@ -240,7 +244,7 @@ TreeSequence <- R6Class( #' ts <- ts_load(ts_file) #' ts$num_mutations() num_mutations = function() { - ts_xptr_num_mutations(self$pointer) + rtsk_treeseq_get_num_mutations(self$xptr) }, #' @description Get the sequence length. @@ -249,7 +253,7 @@ TreeSequence <- R6Class( #' ts <- ts_load(ts_file) #' ts$sequence_length() sequence_length = function() { - ts_xptr_sequence_length(self$pointer) + rtsk_treeseq_get_sequence_length(self$xptr) }, #' @description Get the discrete genome status. @@ -263,7 +267,7 @@ TreeSequence <- R6Class( #' ts2 <- ts_load(ts_file2) #' ts2$discrete_genome() discrete_genome = function() { - ts_xptr_discrete_genome(self$pointer) + rtsk_treeseq_get_discrete_genome(self$xptr) }, #' @description Get whether the tree sequence has a reference genome sequence. @@ -275,7 +279,7 @@ TreeSequence <- R6Class( #' ts2 <- ts_load(ts_file2) #' ts2$has_reference_sequence() has_reference_sequence = function() { - ts_xptr_has_reference_sequence(self$pointer) + rtsk_treeseq_has_reference_sequence(self$xptr) }, #' @description Get the time units string. @@ -284,7 +288,7 @@ TreeSequence <- R6Class( #' ts <- ts_load(ts_file) #' ts$time_units() time_units = function() { - ts_xptr_time_units(self$pointer) + rtsk_treeseq_get_time_units(self$xptr) }, #' @description Get the discrete time status. @@ -298,7 +302,7 @@ TreeSequence <- R6Class( #' ts2 <- ts_load(ts_file2) #' ts2$discrete_time() discrete_time = function() { - ts_xptr_discrete_time(self$pointer) + rtsk_treeseq_get_discrete_time(self$xptr) }, #' @description Get the min time in node table and mutation table. @@ -307,7 +311,7 @@ TreeSequence <- R6Class( #' ts <- ts_load(ts_file) #' ts$min_time() min_time = function() { - ts_xptr_min_time(self$pointer) + rtsk_treeseq_get_min_time(self$xptr) }, #' @description Get the max time in node table and mutation table. @@ -316,7 +320,7 @@ TreeSequence <- R6Class( #' ts <- ts_load(ts_file) #' ts$max_time() max_time = function() { - ts_xptr_max_time(self$pointer) + rtsk_treeseq_get_max_time(self$xptr) }, #' @description Get the length of metadata in a tree sequence and its tables. @@ -326,7 +330,7 @@ TreeSequence <- R6Class( #' ts <- ts_load(ts_file) #' ts$metadata_length() metadata_length = function() { - ts_xptr_metadata_length(self$pointer) + rtsk_treeseq_metadata_length(self$xptr) }, #' @description Get the file UUID string. @@ -337,7 +341,7 @@ TreeSequence <- R6Class( #' ts <- ts_load(ts_file) #' ts$file_uuid() file_uuid = function() { - ts_xptr_file_uuid(self$pointer) + rtsk_treeseq_get_file_uuid(self$xptr) } ) ) diff --git a/RcppTskit/R/RcppExports.R b/RcppTskit/R/RcppExports.R index 9ce813d..1b20348 100644 --- a/RcppTskit/R/RcppExports.R +++ b/RcppTskit/R/RcppExports.R @@ -23,136 +23,144 @@ tskit_version <- function() { .Call(`_RcppTskit_tskit_version`) } -ts_xptr_load <- function(file, options = 0L) { - .Call(`_RcppTskit_ts_xptr_load`, file, options) +rtsk_treeseq_load <- function(filename, options = 0L) { + .Call(`_RcppTskit_rtsk_treeseq_load`, filename, options) } -tc_xptr_load <- function(file, options = 0L) { - .Call(`_RcppTskit_tc_xptr_load`, file, options) +rtsk_table_collection_load <- function(filename, options = 0L) { + .Call(`_RcppTskit_rtsk_table_collection_load`, filename, options) } -ts_xptr_dump <- function(ts, file, options = 0L) { - invisible(.Call(`_RcppTskit_ts_xptr_dump`, ts, file, options)) +rtsk_treeseq_dump <- function(ts, filename, options = 0L) { + invisible(.Call(`_RcppTskit_rtsk_treeseq_dump`, ts, filename, options)) } -tc_xptr_dump <- function(tc, file, options = 0L) { - invisible(.Call(`_RcppTskit_tc_xptr_dump`, tc, file, options)) +rtsk_table_collection_dump <- function(tc, filename, options = 0L) { + invisible(.Call(`_RcppTskit_rtsk_table_collection_dump`, tc, filename, options)) } -ts_xptr_to_tc_xptr <- function(ts, options = 0L) { - .Call(`_RcppTskit_ts_xptr_to_tc_xptr`, ts, options) +rtsk_treeseq_copy_tables <- function(ts, options = 0L) { + .Call(`_RcppTskit_rtsk_treeseq_copy_tables`, ts, options) } -tc_xptr_to_ts_xptr <- function(tc, options = 0L) { - .Call(`_RcppTskit_tc_xptr_to_ts_xptr`, tc, options) +rtsk_treeseq_init <- function(tc, options = 0L) { + .Call(`_RcppTskit_rtsk_treeseq_init`, tc, options) } -ts_xptr_num_provenances <- function(ts) { - .Call(`_RcppTskit_ts_xptr_num_provenances`, ts) +rtsk_treeseq_get_num_provenances <- function(ts) { + .Call(`_RcppTskit_rtsk_treeseq_get_num_provenances`, ts) } -ts_xptr_num_populations <- function(ts) { - .Call(`_RcppTskit_ts_xptr_num_populations`, ts) +rtsk_treeseq_get_num_populations <- function(ts) { + .Call(`_RcppTskit_rtsk_treeseq_get_num_populations`, ts) } -ts_xptr_num_migrations <- function(ts) { - .Call(`_RcppTskit_ts_xptr_num_migrations`, ts) +rtsk_treeseq_get_num_migrations <- function(ts) { + .Call(`_RcppTskit_rtsk_treeseq_get_num_migrations`, ts) } -ts_xptr_num_individuals <- function(ts) { - .Call(`_RcppTskit_ts_xptr_num_individuals`, ts) +rtsk_treeseq_get_num_individuals <- function(ts) { + .Call(`_RcppTskit_rtsk_treeseq_get_num_individuals`, ts) } -ts_xptr_num_samples <- function(ts) { - .Call(`_RcppTskit_ts_xptr_num_samples`, ts) +rtsk_treeseq_get_num_samples <- function(ts) { + .Call(`_RcppTskit_rtsk_treeseq_get_num_samples`, ts) } -ts_xptr_num_nodes <- function(ts) { - .Call(`_RcppTskit_ts_xptr_num_nodes`, ts) +rtsk_treeseq_get_num_nodes <- function(ts) { + .Call(`_RcppTskit_rtsk_treeseq_get_num_nodes`, ts) } -ts_xptr_num_edges <- function(ts) { - .Call(`_RcppTskit_ts_xptr_num_edges`, ts) +rtsk_treeseq_get_num_edges <- function(ts) { + .Call(`_RcppTskit_rtsk_treeseq_get_num_edges`, ts) } -ts_xptr_num_trees <- function(ts) { - .Call(`_RcppTskit_ts_xptr_num_trees`, ts) +rtsk_treeseq_get_num_trees <- function(ts) { + .Call(`_RcppTskit_rtsk_treeseq_get_num_trees`, ts) } -ts_xptr_num_sites <- function(ts) { - .Call(`_RcppTskit_ts_xptr_num_sites`, ts) +rtsk_treeseq_get_num_sites <- function(ts) { + .Call(`_RcppTskit_rtsk_treeseq_get_num_sites`, ts) } -ts_xptr_num_mutations <- function(ts) { - .Call(`_RcppTskit_ts_xptr_num_mutations`, ts) +rtsk_treeseq_get_num_mutations <- function(ts) { + .Call(`_RcppTskit_rtsk_treeseq_get_num_mutations`, ts) } -ts_xptr_sequence_length <- function(ts) { - .Call(`_RcppTskit_ts_xptr_sequence_length`, ts) +rtsk_treeseq_get_sequence_length <- function(ts) { + .Call(`_RcppTskit_rtsk_treeseq_get_sequence_length`, ts) } -ts_xptr_discrete_genome <- function(ts) { - .Call(`_RcppTskit_ts_xptr_discrete_genome`, ts) +rtsk_treeseq_get_discrete_genome <- function(ts) { + .Call(`_RcppTskit_rtsk_treeseq_get_discrete_genome`, ts) } -ts_xptr_has_reference_sequence <- function(ts) { - .Call(`_RcppTskit_ts_xptr_has_reference_sequence`, ts) +rtsk_treeseq_has_reference_sequence <- function(ts) { + .Call(`_RcppTskit_rtsk_treeseq_has_reference_sequence`, ts) } -ts_xptr_time_units <- function(ts) { - .Call(`_RcppTskit_ts_xptr_time_units`, ts) +rtsk_treeseq_get_time_units <- function(ts) { + .Call(`_RcppTskit_rtsk_treeseq_get_time_units`, ts) } -ts_xptr_discrete_time <- function(ts) { - .Call(`_RcppTskit_ts_xptr_discrete_time`, ts) +rtsk_treeseq_get_discrete_time <- function(ts) { + .Call(`_RcppTskit_rtsk_treeseq_get_discrete_time`, ts) } -ts_xptr_min_time <- function(ts) { - .Call(`_RcppTskit_ts_xptr_min_time`, ts) +rtsk_treeseq_get_min_time <- function(ts) { + .Call(`_RcppTskit_rtsk_treeseq_get_min_time`, ts) } -ts_xptr_max_time <- function(ts) { - .Call(`_RcppTskit_ts_xptr_max_time`, ts) +rtsk_treeseq_get_max_time <- function(ts) { + .Call(`_RcppTskit_rtsk_treeseq_get_max_time`, ts) } -ts_xptr_file_uuid <- function(ts) { - .Call(`_RcppTskit_ts_xptr_file_uuid`, ts) +rtsk_treeseq_get_file_uuid <- function(ts) { + .Call(`_RcppTskit_rtsk_treeseq_get_file_uuid`, ts) } -ts_xptr_summary <- function(ts) { - .Call(`_RcppTskit_ts_xptr_summary`, ts) +rtsk_treeseq_summary <- function(ts) { + .Call(`_RcppTskit_rtsk_treeseq_summary`, ts) } -ts_xptr_metadata_length <- function(ts) { - .Call(`_RcppTskit_ts_xptr_metadata_length`, ts) +rtsk_treeseq_metadata_length <- function(ts) { + .Call(`_RcppTskit_rtsk_treeseq_metadata_length`, ts) } -tc_xptr_sequence_length <- function(tc) { - .Call(`_RcppTskit_tc_xptr_sequence_length`, tc) +rtsk_table_collection_get_sequence_length <- function(tc) { + .Call(`_RcppTskit_rtsk_table_collection_get_sequence_length`, tc) } -tc_xptr_has_reference_sequence <- function(tc) { - .Call(`_RcppTskit_tc_xptr_has_reference_sequence`, tc) +rtsk_table_collection_has_reference_sequence <- function(tc) { + .Call(`_RcppTskit_rtsk_table_collection_has_reference_sequence`, tc) } -tc_xptr_time_units <- function(tc) { - .Call(`_RcppTskit_tc_xptr_time_units`, tc) +rtsk_table_collection_get_time_units <- function(tc) { + .Call(`_RcppTskit_rtsk_table_collection_get_time_units`, tc) } -tc_xptr_file_uuid <- function(tc) { - .Call(`_RcppTskit_tc_xptr_file_uuid`, tc) +rtsk_table_collection_get_file_uuid <- function(tc) { + .Call(`_RcppTskit_rtsk_table_collection_get_file_uuid`, tc) } -tc_xptr_has_index <- function(tc) { - .Call(`_RcppTskit_tc_xptr_has_index`, tc) +rtsk_table_collection_has_index <- function(tc, options = 0L) { + .Call(`_RcppTskit_rtsk_table_collection_has_index`, tc, options) } -tc_xptr_summary <- function(tc) { - .Call(`_RcppTskit_tc_xptr_summary`, tc) +rtsk_table_collection_build_index <- function(tc, options = 0L) { + invisible(.Call(`_RcppTskit_rtsk_table_collection_build_index`, tc, options)) } -tc_xptr_metadata_length <- function(tc) { - .Call(`_RcppTskit_tc_xptr_metadata_length`, tc) +rtsk_table_collection_drop_index <- function(tc, options = 0L) { + invisible(.Call(`_RcppTskit_rtsk_table_collection_drop_index`, tc, options)) +} + +rtsk_table_collection_summary <- function(tc) { + .Call(`_RcppTskit_rtsk_table_collection_summary`, tc) +} + +rtsk_table_collection_metadata_length <- function(tc) { + .Call(`_RcppTskit_rtsk_table_collection_metadata_length`, tc) } test_tsk_bug_assert_c <- function() { @@ -175,11 +183,15 @@ tsk_trace_errors_defined <- function() { .Call(`_RcppTskit_tsk_trace_errors_defined`) } -test_ts_xptr_to_tc_xptr_forced_error <- function(ts) { - .Call(`_RcppTskit_test_ts_xptr_to_tc_xptr_forced_error`, ts) +test_rtsk_treeseq_copy_tables_forced_error <- function(ts) { + .Call(`_RcppTskit_test_rtsk_treeseq_copy_tables_forced_error`, ts) +} + +test_rtsk_treeseq_init_forced_error <- function(tc) { + .Call(`_RcppTskit_test_rtsk_treeseq_init_forced_error`, tc) } -test_tc_xptr_to_ts_xptr_forced_error <- function(tc) { - .Call(`_RcppTskit_test_tc_xptr_to_ts_xptr_forced_error`, tc) +test_rtsk_table_collection_build_index_forced_error <- function(tc) { + invisible(.Call(`_RcppTskit_test_rtsk_table_collection_build_index_forced_error`, tc)) } diff --git a/RcppTskit/R/RcppTskit-package.R b/RcppTskit/R/RcppTskit-package.R index 6fe19fb..9ae4696 100644 --- a/RcppTskit/R/RcppTskit-package.R +++ b/RcppTskit/R/RcppTskit-package.R @@ -15,6 +15,8 @@ #' \code{reticulate} option is not optimal; for example; high-performance or low-level #' work with tree sequences. Currently, \code{RcppTskit} provides a limited set of #' R functions because the Python API and \code{reticulate} already covers most needs. +#' The provided \code{RcppTskit R} API mirrors the \code{tskit Python} API, +#' while the \code{RcppTskit C++} API mirrors the \code{tskit C} API. #' @keywords internal #' #' @useDynLib RcppTskit, .registration = TRUE diff --git a/RcppTskit/R/RcppTskit.R b/RcppTskit/R/RcppTskit.R index 48aac27..243893f 100644 --- a/RcppTskit/R/RcppTskit.R +++ b/RcppTskit/R/RcppTskit.R @@ -206,8 +206,8 @@ tc_read <- tc_load # @title Print a summary of a tree sequence and its contents # @param ts an external pointer (\code{externalptr}) to a \code{tsk_treeseq_t} # object. -# @details It uses \code{\link{ts_xptr_summary}} and -# \code{\link{ts_xptr_metadata_length}}. +# @details It uses \code{\link{rtsk_treeseq_summary}} and +# \code{\link{rtsk_treeseq_metadata_length}}. # Note that \code{nbytes} property is not available in \code{tskit} C API # compared to Python API, so also not available here. # @return A list with two data.frames; the first contains tree sequence @@ -217,14 +217,14 @@ tc_read <- tc_load # function is used and presented to users. # @examples # ts_file <- system.file("examples/test.trees", package = "RcppTskit") -# ts_xptr <- ts_xptr_load(ts_file) -# RcppTskit:::ts_xptr_print(ts_xptr) -ts_xptr_print <- function(ts) { +# ts_xptr <- rtsk_treeseq_load(ts_file) +# RcppTskit:::rtsk_treeseq_print(ts_xptr) +rtsk_treeseq_print <- function(ts) { if (!is(ts, "externalptr")) { stop("ts must be an object of externalptr class!") } - tmp_summary <- ts_xptr_summary(ts) - tmp_metadata <- ts_xptr_metadata_length(ts) + tmp_summary <- rtsk_treeseq_summary(ts) + tmp_metadata <- rtsk_treeseq_metadata_length(ts) ret <- list( ts = data.frame( property = c( @@ -293,8 +293,8 @@ ts_xptr_print <- function(ts) { # @title Print a summary of a table collection and its contents # @param tc an external pointer (\code{externalptr}) to a # \code{tsk_table_collection_t} object. -# @details It uses \code{\link{tc_xptr_summary}} and -# \code{\link{tc_xptr_metadata_length}}. +# @details It uses \code{\link{rtsk_table_collection_summary}} and +# \code{\link{rtsk_table_collection_metadata_length}}. # @return A list with two data.frames; the first contains table collection # properties and their value; the second contains the numbers of rows in # tables and the length of their metadata. @@ -302,14 +302,14 @@ ts_xptr_print <- function(ts) { # function is used and presented to users. # @examples # ts_file <- system.file("examples/test.trees", package = "RcppTskit") -# tc_xptr <- tc_xptr_load(ts_file) -# RcppTskit:::tc_xptr_print(tc_xptr) -tc_xptr_print <- function(tc) { +# tc_xptr <- rtsk_table_collection_load(ts_file) +# RcppTskit:::rtsk_table_collection_print(tc_xptr) +rtsk_table_collection_print <- function(tc) { if (!is(tc, "externalptr")) { stop("tc must be an object of externalptr class!") } - tmp_summary <- tc_xptr_summary(tc) - tmp_metadata <- tc_xptr_metadata_length(tc) + tmp_summary <- rtsk_table_collection_summary(tc) + tmp_metadata <- rtsk_table_collection_metadata_length(tc) ret <- list( tc = data.frame( property = c( @@ -379,17 +379,17 @@ tc_xptr_print <- function(tc) { # @seealso \code{\link{ts_py_to_r}}, \code{\link{ts_load}}, and # \code{\link[=TreeSequence]{TreeSequence$dump}} on how this function # is used and presented to users, -# and \code{\link{ts_xptr_py_to_r}}, \code{\link{ts_xptr_load}}, and -# \code{ts_xptr_dump} (Rcpp) for underlying pointer functions. +# and \code{\link{rtsk_treeseq_py_to_r}}, \code{\link{rtsk_treeseq_load}}, and +# \code{rtsk_treeseq_dump} (Rcpp) for underlying pointer functions. # @examples # \dontrun{ # ts_file <- system.file("examples/test.trees", package = "RcppTskit") # ts_r <- ts_load(ts_file) -# ts_xptr_r <- ts_r$pointer -# is(ts_xptr_r) -# RcppTskit:::ts_xptr_num_samples(ts_xptr_r) # 16 +# ts_rtsk <- ts_r$xptr +# is(ts_rtsk) +# RcppTskit:::rtsk_treeseq_get_num_samples(ts_rtsk) # 16 # # Transfer the tree sequence to reticulate Python and use tskit Python API -# ts_py <- RcppTskit:::ts_xptr_r_to_py(ts_xptr_r) +# ts_py <- RcppTskit:::rtsk_treeseq_r_to_py(ts_rtsk) # is(ts_py) # ts_py$num_individuals # 8 # ts2_py <- ts_py$simplify(samples = c(0L, 1L, 2L, 3L)) @@ -398,7 +398,11 @@ tc_xptr_print <- function(tc) { # ts2_py$num_nodes # 8 # ts2_py$tables$nodes$time # 0.0 ... 5.0093910 # } -ts_xptr_r_to_py <- function(ts, tskit_module = get_tskit_py(), cleanup = TRUE) { +rtsk_treeseq_r_to_py <- function( + ts, + tskit_module = get_tskit_py(), + cleanup = TRUE +) { if (!is(ts, "externalptr")) { stop("ts must be an object of externalptr class!") } @@ -407,7 +411,7 @@ ts_xptr_r_to_py <- function(ts, tskit_module = get_tskit_py(), cleanup = TRUE) { if (cleanup) { on.exit(file.remove(ts_file)) } - ts_xptr_dump(ts, file = ts_file) + rtsk_treeseq_dump(ts, filename = ts_file) ts_py <- tskit_module$load(ts_file) return(ts_py) } @@ -429,17 +433,17 @@ ts_xptr_r_to_py <- function(ts, tskit_module = get_tskit_py(), cleanup = TRUE) { # @seealso \code{\link{tc_py_to_r}}, \code{\link{tc_load}}, and # \code{\link[=TableCollection]{TableCollection$dump}} on how this function # is used and presented to users, -# and \code{\link{tc_xptr_py_to_r}}, \code{\link{tc_xptr_load}}, and -# \code{tc_xptr_dump} (Rcpp) for underlying pointer functions. +# and \code{\link{rtsk_table_collection_py_to_r}}, \code{\link{rtsk_table_collection_load}}, and +# \code{rtsk_table_collection_dump} (Rcpp) for underlying pointer functions. # @examples # \dontrun{ # ts_file <- system.file("examples/test.trees", package = "RcppTskit") # tc_r <- tc_load(ts_file) -# tc_xptr_r <- tc_r$pointer -# is(tc_xptr_r) -# RcppTskit:::tc_xptr_summary(tc_xptr_r) +# tc_rtsk <- tc_r$xptr +# is(tc_rtsk) +# RcppTskit:::rtsk_table_collection_summary(tc_rtsk) # # Transfer the table collection to reticulate Python and use tskit Python API -# tc_py <- RcppTskit:::tc_xptr_r_to_py(tc_xptr_r) +# tc_py <- RcppTskit:::rtsk_table_collection_r_to_py(tc_rtsk) # is(tc_py) # tc_py$individuals$num_rows # 8 # tmp <- tc_py$simplify(samples = c(0L, 1L, 2L, 3L)) @@ -448,7 +452,11 @@ ts_xptr_r_to_py <- function(ts, tskit_module = get_tskit_py(), cleanup = TRUE) { # tc_py$nodes$num_rows # 8 # tc_py$nodes$time # 0.0 ... 5.0093910 # } -tc_xptr_r_to_py <- function(tc, tskit_module = get_tskit_py(), cleanup = TRUE) { +rtsk_table_collection_r_to_py <- function( + tc, + tskit_module = get_tskit_py(), + cleanup = TRUE +) { if (!is(tc, "externalptr")) { stop("tc must be an object of externalptr class!") } @@ -457,7 +465,7 @@ tc_xptr_r_to_py <- function(tc, tskit_module = get_tskit_py(), cleanup = TRUE) { if (cleanup) { on.exit(file.remove(tc_file)) } - tc_xptr_dump(tc, file = tc_file) + rtsk_table_collection_dump(tc, filename = tc_file) tc_py <- tskit_module$TableCollection$load(tc_file) return(tc_py) } @@ -473,8 +481,8 @@ tc_xptr_r_to_py <- function(tc, tskit_module = get_tskit_py(), cleanup = TRUE) { # @seealso \code{\link[=TreeSequence]{TreeSequence$r_to_py}}, # \code{\link{ts_load}}, and \code{\link[=TreeSequence]{TreeSequence$dump}} # on how this function is used and presented to users, -# and \code{\link{ts_xptr_r_to_py}}, \code{\link{ts_xptr_load}}, and -# \code{ts_xptr_dump} (Rcpp) for underlying pointer functions. +# and \code{\link{rtsk_treeseq_r_to_py}}, \code{\link{rtsk_treeseq_load}}, and +# \code{rtsk_treeseq_dump} (Rcpp) for underlying pointer functions. # @examples # \dontrun{ # ts_file <- system.file("examples/test.trees", package = "RcppTskit") @@ -492,12 +500,12 @@ tc_xptr_r_to_py <- function(tc, tskit_module = get_tskit_py(), cleanup = TRUE) { # ts2_py$tables$nodes$time # 0.0 ... 5.0093910 # # # Transfer the tree sequence to R and use RcppTskit -# ts2_xptr_r <- RcppTskit:::ts_xptr_py_to_r(ts2_py) +# ts2_xptr_r <- RcppTskit:::rtsk_treeseq_py_to_r(ts2_py) # is(ts2_xptr_r) -# RcppTskit:::ts_xptr_num_individuals(ts2_xptr_r) # 2 +# RcppTskit:::rtsk_treeseq_get_num_individuals(ts2_xptr_r) # 2 # } # } -ts_xptr_py_to_r <- function(ts, cleanup = TRUE) { +rtsk_treeseq_py_to_r <- function(ts, cleanup = TRUE) { if (!reticulate::is_py_object(ts)) { stop("ts must be a reticulate Python object!") } @@ -506,7 +514,7 @@ ts_xptr_py_to_r <- function(ts, cleanup = TRUE) { on.exit(file.remove(ts_file)) } ts$dump(ts_file) - ts_r <- ts_xptr_load(ts_file) + ts_r <- rtsk_treeseq_load(filename = ts_file) return(ts_r) } @@ -522,8 +530,8 @@ ts_xptr_py_to_r <- function(ts, cleanup = TRUE) { # @seealso \code{\link[=TableCollection]{TableCollection$r_to_py}}, # \code{\link{tc_load}}, and \code{\link[=TableCollection]{TableCollection$dump}} # on how this function is used and presented to users, -# and \code{\link{tc_xptr_r_to_py}}, \code{\link{tc_xptr_load}}, and -# \code{tc_xptr_dump} (Rcpp) for underlying pointer functions. +# and \code{\link{rtsk_table_collection_r_to_py}}, \code{\link{rtsk_table_collection_load}}, and +# \code{rtsk_table_collection_dump} (Rcpp) for underlying pointer functions. # @examples # \dontrun{ # ts_file <- system.file("examples/test.trees", package = "RcppTskit") @@ -541,12 +549,12 @@ ts_xptr_py_to_r <- function(ts, cleanup = TRUE) { # tc_py$nodes$time # 0.0 ... 5.0093910 # # # Transfer the table collection to R and use RcppTskit -# tc2_xptr_r <- RcppTskit:::tc_xptr_py_to_r(tc_py) +# tc2_xptr_r <- RcppTskit:::rtsk_table_collection_py_to_r(tc_py) # is(tc2_xptr_r) -# RcppTskit:::tc_xptr_summary(tc2_xptr_r) +# RcppTskit:::rtsk_table_collection_summary(tc2_xptr_r) # } # } -tc_xptr_py_to_r <- function(tc, cleanup = TRUE) { +rtsk_table_collection_py_to_r <- function(tc, cleanup = TRUE) { if (!reticulate::is_py_object(tc)) { stop("tc must be a reticulate Python object!") } @@ -555,7 +563,7 @@ tc_xptr_py_to_r <- function(tc, cleanup = TRUE) { on.exit(file.remove(tc_file)) } tc$dump(tc_file) - tc_r <- tc_xptr_load(tc_file) + tc_r <- rtsk_table_collection_load(filename = tc_file) return(tc_r) } @@ -593,8 +601,8 @@ tc_xptr_py_to_r <- function(tc, cleanup = TRUE) { #' } #' @export ts_py_to_r <- function(ts, cleanup = TRUE) { - xptr <- ts_xptr_py_to_r(ts = ts, cleanup = cleanup) - ts_r <- TreeSequence$new(pointer = xptr) + xptr <- rtsk_treeseq_py_to_r(ts = ts, cleanup = cleanup) + ts_r <- TreeSequence$new(xptr = xptr) return(ts_r) } @@ -632,7 +640,7 @@ ts_py_to_r <- function(ts, cleanup = TRUE) { #' } #' @export tc_py_to_r <- function(tc, cleanup = TRUE) { - xptr <- tc_xptr_py_to_r(tc = tc, cleanup = cleanup) - tc_r <- TableCollection$new(pointer = xptr) + xptr <- rtsk_table_collection_py_to_r(tc = tc, cleanup = cleanup) + tc_r <- TableCollection$new(xptr = xptr) return(tc_r) } diff --git a/RcppTskit/inst/include/RcppTskit.hpp b/RcppTskit/inst/include/RcppTskit.hpp index 8755c7a..18dc921 100644 --- a/RcppTskit/inst/include/RcppTskit.hpp +++ b/RcppTskit/inst/include/RcppTskit.hpp @@ -7,7 +7,7 @@ // Finaliser that frees tsk_treeseq_t when it is garbage collected // See \url{https://tskit.dev/tskit/docs/stable/c-api.html#c.tsk_treeseq_free} // for more details. -static void RcppTskit_treeseq_xptr_delete(tsk_treeseq_t *ptr) { +static void rtsk_treeseq_free(tsk_treeseq_t *ptr) { if (ptr != NULL) { tsk_treeseq_free(ptr); delete ptr; @@ -18,8 +18,7 @@ static void RcppTskit_treeseq_xptr_delete(tsk_treeseq_t *ptr) { // See // \url{https://tskit.dev/tskit/docs/stable/c-api.html#c.tsk_table_collection_free} // for more details. -static void -RcppTskit_table_collection_xptr_delete(tsk_table_collection_t *ptr) { +static void rtsk_table_collection_free(tsk_table_collection_t *ptr) { if (ptr != NULL) { tsk_table_collection_free(ptr); delete ptr; @@ -27,17 +26,17 @@ RcppTskit_table_collection_xptr_delete(tsk_table_collection_t *ptr) { } // Define the external pointer type for tsk_treeseq_t with its finaliser -using RcppTskit_treeseq_xptr = Rcpp::XPtr; +using rtsk_treeseq_t = + Rcpp::XPtr; // Define the external pointer type for tsk_table_collection_t with its // finaliser -using RcppTskit_table_collection_xptr = +using rtsk_table_collection_t = Rcpp::XPtr; + rtsk_table_collection_free, true>; // Package implementation files define RCPPTSKIT_IMPL to avoid pulling -// PUBLIC declarations with default args into the same translation unit. +// PUBLIC declarations with default args into the same translation unit #ifndef RCPPTSKIT_IMPL #include "RcppTskit_public.hpp" #endif diff --git a/RcppTskit/inst/include/RcppTskit_public.hpp b/RcppTskit/inst/include/RcppTskit_public.hpp index 0fb8afc..2be2611 100644 --- a/RcppTskit/inst/include/RcppTskit_public.hpp +++ b/RcppTskit/inst/include/RcppTskit_public.hpp @@ -11,40 +11,42 @@ Rcpp::IntegerVector kastore_version(); Rcpp::IntegerVector tskit_version(); // sync default options with .cpp! -SEXP ts_xptr_load(std::string file, int options = 0); -SEXP tc_xptr_load(std::string file, int options = 0); -void ts_xptr_dump(SEXP ts, std::string file, int options = 0); -void tc_xptr_dump(SEXP tc, std::string file, int options = 0); -SEXP ts_xptr_to_tc_xptr(SEXP ts, int options = 0); -SEXP tc_xptr_to_ts_xptr(SEXP tc, int options = 0); +SEXP rtsk_treeseq_load(std::string filename, int options = 0); +SEXP rtsk_table_collection_load(std::string filename, int options = 0); +void rtsk_treeseq_dump(SEXP ts, std::string filename, int options = 0); +void rtsk_table_collection_dump(SEXP tc, std::string filename, int options = 0); +SEXP rtsk_treeseq_copy_tables(SEXP ts, int options = 0); +SEXP rtsk_treeseq_init(SEXP tc, int options = 0); -int ts_xptr_num_provenances(SEXP ts); -int ts_xptr_num_populations(SEXP ts); -int ts_xptr_num_migrations(SEXP ts); -int ts_xptr_num_individuals(SEXP ts); -int ts_xptr_num_samples(SEXP ts); -int ts_xptr_num_nodes(SEXP ts); -int ts_xptr_num_edges(SEXP ts); -int ts_xptr_num_trees(SEXP ts); -int ts_xptr_num_sites(SEXP ts); -int ts_xptr_num_mutations(SEXP ts); -double ts_xptr_sequence_length(SEXP ts); -bool ts_xptr_discrete_genome(SEXP ts); -bool ts_xptr_has_reference_sequence(SEXP ts); -Rcpp::String ts_xptr_time_units(SEXP ts); -bool ts_xptr_discrete_time(SEXP ts); -double ts_xptr_min_time(SEXP ts); -double ts_xptr_max_time(SEXP ts); -Rcpp::String ts_xptr_file_uuid(SEXP ts); -Rcpp::List ts_xptr_summary(SEXP ts); -Rcpp::List ts_xptr_metadata_length(SEXP ts); +int rtsk_treeseq_get_num_provenances(SEXP ts); +int rtsk_treeseq_get_num_populations(SEXP ts); +int rtsk_treeseq_get_num_migrations(SEXP ts); +int rtsk_treeseq_get_num_individuals(SEXP ts); +int rtsk_treeseq_get_num_samples(SEXP ts); +int rtsk_treeseq_get_num_nodes(SEXP ts); +int rtsk_treeseq_get_num_edges(SEXP ts); +int rtsk_treeseq_get_num_trees(SEXP ts); +int rtsk_treeseq_get_num_sites(SEXP ts); +int rtsk_treeseq_get_num_mutations(SEXP ts); +double rtsk_treeseq_get_sequence_length(SEXP ts); +bool rtsk_treeseq_get_discrete_genome(SEXP ts); +bool rtsk_treeseq_has_reference_sequence(SEXP ts); +Rcpp::String rtsk_treeseq_get_time_units(SEXP ts); +bool rtsk_treeseq_get_discrete_time(SEXP ts); +double rtsk_treeseq_get_min_time(SEXP ts); +double rtsk_treeseq_get_max_time(SEXP ts); +Rcpp::String rtsk_treeseq_get_file_uuid(SEXP ts); +Rcpp::List rtsk_treeseq_summary(SEXP ts); +Rcpp::List rtsk_treeseq_metadata_length(SEXP ts); -double tc_xptr_sequence_length(SEXP tc); -bool tc_xptr_has_reference_sequence(SEXP tc); -Rcpp::String tc_xptr_time_units(SEXP tc); -Rcpp::String tc_xptr_file_uuid(SEXP tc); -bool tc_xptr_has_index(SEXP tc); -Rcpp::List tc_xptr_summary(SEXP tc); -Rcpp::List tc_xptr_metadata_length(SEXP tc); +double rtsk_table_collection_get_sequence_length(SEXP tc); +bool rtsk_table_collection_has_reference_sequence(SEXP tc); +Rcpp::String rtsk_table_collection_get_time_units(SEXP tc); +Rcpp::String rtsk_table_collection_get_file_uuid(SEXP tc); +bool rtsk_table_collection_has_index(SEXP tc, int options = 0); +void rtsk_table_collection_build_index(SEXP tc, int options = 0); +void rtsk_table_collection_drop_index(SEXP tc, int options = 0); +Rcpp::List rtsk_table_collection_summary(SEXP tc); +Rcpp::List rtsk_table_collection_metadata_length(SEXP tc); #endif diff --git a/RcppTskit/inst/include/tskit/core.h b/RcppTskit/inst/include/tskit/core.h index 94b05ce..90a9496 100644 --- a/RcppTskit/inst/include/tskit/core.h +++ b/RcppTskit/inst/include/tskit/core.h @@ -39,23 +39,23 @@ #undef tsk_trace_error #ifdef TSK_TRACE_ERRORS #ifdef __cplusplus -static inline int _RcppTskit_trace_error_cpp(int err, int line, - const char *file) { +static inline int _rtsk_trace_error_cpp(int err, int line, + const char *file) { Rcpp::warning("tskit-trace-error: %d='%s' at line %d in %s\n", err, tsk_strerror(err), line, file); return err; } #define tsk_trace_error(err) \ - (_RcppTskit_trace_error_cpp((err), __LINE__, __FILE__)) + (_rtsk_trace_error_cpp((err), __LINE__, __FILE__)) #else -static inline int _RcppTskit_trace_error_c(int err, int line, - const char *file) { +static inline int _rtsk_trace_error_c(int err, int line, + const char *file) { Rf_warning("tskit-trace-error: %d='%s' at line %d in %s\n", err, tsk_strerror(err), line, file); return err; } #define tsk_trace_error(err) \ - (_RcppTskit_trace_error_c((err), __LINE__, __FILE__)) + (_rtsk_trace_error_c((err), __LINE__, __FILE__)) #endif #else #define tsk_trace_error(err) (err) diff --git a/RcppTskit/man/RcppTskit-package.Rd b/RcppTskit/man/RcppTskit-package.Rd index b601dbf..6ab8ef6 100644 --- a/RcppTskit/man/RcppTskit-package.Rd +++ b/RcppTskit/man/RcppTskit-package.Rd @@ -20,6 +20,8 @@ https://tskit.dev/tutorials/tskitr.html. \code{reticulate} option is not optimal; for example; high-performance or low-level work with tree sequences. Currently, \code{RcppTskit} provides a limited set of R functions because the Python API and \code{reticulate} already covers most needs. +The provided \code{RcppTskit R} API mirrors the \code{tskit Python} API, +while the \code{RcppTskit C++} API mirrors the \code{tskit C} API. } \examples{ vignette("RcppTskit_intro") diff --git a/RcppTskit/man/TableCollection.Rd b/RcppTskit/man/TableCollection.Rd index 42fda20..a780ac0 100644 --- a/RcppTskit/man/TableCollection.Rd +++ b/RcppTskit/man/TableCollection.Rd @@ -64,6 +64,28 @@ tc_file <- system.file("examples/test.trees", package = "RcppTskit") tc <- tc_load(tc_file) tc$has_index() +## ------------------------------------------------ +## Method `TableCollection$build_index` +## ------------------------------------------------ + +tc_file <- system.file("examples/test.trees", package = "RcppTskit") +tc <- tc_load(tc_file) +tc$has_index() +tc$drop_index() +tc$has_index() +tc$build_index() +tc$has_index() + +## ------------------------------------------------ +## Method `TableCollection$drop_index` +## ------------------------------------------------ + +tc_file <- system.file("examples/test.trees", package = "RcppTskit") +tc <- tc_load(tc_file) +tc$has_index() +tc$drop_index() +tc$has_index() + ## ------------------------------------------------ ## Method `TableCollection$has_reference_sequence` ## ------------------------------------------------ @@ -122,7 +144,7 @@ tc \section{Public fields}{ \if{html}{\out{
}} \describe{ -\item{\code{pointer}}{external pointer to the table collection} +\item{\code{xptr}}{external pointer to the table collection} } \if{html}{\out{
}} } @@ -136,6 +158,8 @@ tc \item \href{#method-TableCollection-sequence_length}{\code{TableCollection$sequence_length()}} \item \href{#method-TableCollection-time_units}{\code{TableCollection$time_units()}} \item \href{#method-TableCollection-has_index}{\code{TableCollection$has_index()}} +\item \href{#method-TableCollection-build_index}{\code{TableCollection$build_index()}} +\item \href{#method-TableCollection-drop_index}{\code{TableCollection$drop_index()}} \item \href{#method-TableCollection-has_reference_sequence}{\code{TableCollection$has_reference_sequence()}} \item \href{#method-TableCollection-file_uuid}{\code{TableCollection$file_uuid()}} \item \href{#method-TableCollection-r_to_py}{\code{TableCollection$r_to_py()}} @@ -147,13 +171,13 @@ tc \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-TableCollection-new}{}}} \subsection{Method \code{new()}}{ -Create a \code{\link{TableCollection}} from a file or a pointer. +Create a \code{\link{TableCollection}} from a file or an external pointer. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{TableCollection$new( file, skip_tables = FALSE, skip_reference_sequence = FALSE, - pointer = NULL + xptr = NULL )}\if{html}{\out{
}} } @@ -167,7 +191,7 @@ Create a \code{\link{TableCollection}} from a file or a pointer. \item{\code{skip_reference_sequence}}{logical; if \code{TRUE}, skip loading reference genome sequence information.} -\item{\code{pointer}}{an external pointer (\code{externalptr}) to a table collection.} +\item{\code{xptr}}{an external pointer (\code{externalptr}) to a table collection.} } \if{html}{\out{}} } @@ -334,6 +358,68 @@ tc$has_index() } +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-TableCollection-build_index}{}}} +\subsection{Method \code{build_index()}}{ +Build edge indexes for this table collection. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{TableCollection$build_index()}\if{html}{\out{
}} +} + +\subsection{Details}{ +See the corresponding Python function at + \url{https://tskit.dev/tskit/docs/latest/python-api.html#tskit.TableCollection.build_index}. +} + +\subsection{Returns}{ +No return value; called for side effects. +} +\subsection{Examples}{ +\if{html}{\out{
}} +\preformatted{tc_file <- system.file("examples/test.trees", package = "RcppTskit") +tc <- tc_load(tc_file) +tc$has_index() +tc$drop_index() +tc$has_index() +tc$build_index() +tc$has_index() +} +\if{html}{\out{
}} + +} + +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-TableCollection-drop_index}{}}} +\subsection{Method \code{drop_index()}}{ +Drop edge indexes for this table collection. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{TableCollection$drop_index()}\if{html}{\out{
}} +} + +\subsection{Details}{ +See the corresponding Python function at + \url{https://tskit.dev/tskit/docs/latest/python-api.html#tskit.TableCollection.drop_index}. +} + +\subsection{Returns}{ +No return value; called for side effects. +} +\subsection{Examples}{ +\if{html}{\out{
}} +\preformatted{tc_file <- system.file("examples/test.trees", package = "RcppTskit") +tc <- tc_load(tc_file) +tc$has_index() +tc$drop_index() +tc$has_index() +} +\if{html}{\out{
}} + +} + } \if{html}{\out{
}} \if{html}{\out{}} diff --git a/RcppTskit/man/TreeSequence.Rd b/RcppTskit/man/TreeSequence.Rd index 4e03d68..d439baa 100644 --- a/RcppTskit/man/TreeSequence.Rd +++ b/RcppTskit/man/TreeSequence.Rd @@ -247,7 +247,7 @@ ts$file_uuid() \section{Public fields}{ \if{html}{\out{
}} \describe{ -\item{\code{pointer}}{external pointer to the tree sequence} +\item{\code{xptr}}{external pointer to the tree sequence} } \if{html}{\out{
}} } @@ -286,14 +286,14 @@ ts$file_uuid() \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-TreeSequence-new}{}}} \subsection{Method \code{new()}}{ -Create a \code{\link{TreeSequence}} from a file or a pointer. +Create a \code{\link{TreeSequence}} from a file or an external pointer. See \code{\link{ts_load}} for details and examples. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{TreeSequence$new( file, skip_tables = FALSE, skip_reference_sequence = FALSE, - pointer = NULL + xptr = NULL )}\if{html}{\out{
}} } @@ -307,7 +307,7 @@ Create a \code{\link{TreeSequence}} from a file or a pointer. \item{\code{skip_reference_sequence}}{logical; if \code{TRUE}, skip loading reference genome sequence information.} -\item{\code{pointer}}{an external pointer (\code{externalptr}) to a tree sequence.} +\item{\code{xptr}}{an external pointer (\code{externalptr}) to a tree sequence.} } \if{html}{\out{}} } diff --git a/RcppTskit/notes_pkg_dev.Rmd b/RcppTskit/notes_pkg_dev.Rmd index 9e2e414..146b3e6 100644 --- a/RcppTskit/notes_pkg_dev.Rmd +++ b/RcppTskit/notes_pkg_dev.Rmd @@ -2,160 +2,6 @@ ## Next TODOs -## TableCollection indexes and `tree_sequence()` (notes for future work) - -### Why this note exists - -I got a bit hazy on how indexes are handled across tskit C, tskit Python, -and `RcppTskit` when converting a `TableCollection` to a `TreeSequence`. -This note Codex summarised the current understanding and suggests a future path. -We have to study this and decide how to move onwards. - -### tskit Python API behavior (reference behavior for R API) - -- `TableCollection.tree_sequence()` is user-facing and Pythonic (no bitwise flags). -- It checks `self.has_index()`. -- If indexes are missing, it calls `self.build_index()`. -- Then it calls `tskit.TreeSequence.load_tables(self)`. - -In other words: Python handles index preparation explicitly at the -`TableCollection` layer before creating a `TreeSequence`. - -Python also exposes these `TableCollection` methods: - -- `has_index()` -- `build_index()` -- `drop_index()` - -### tskit C API behavior (reference behavior for low-level C++ wrappers) - -- `tsk_table_collection_has_index(...)` -- `tsk_table_collection_build_index(...)` -- `tsk_table_collection_drop_index(...)` -- `tsk_treeseq_init(..., options)` where `options` may include: - - `TSK_TS_INIT_BUILD_INDEXES` - - `TSK_TS_INIT_COMPUTE_MUTATION_PARENTS` - -`TSK_TS_INIT_BUILD_INDEXES` is a C-level bitwise option and fits naturally in -the low-level `tc_xptr_to_ts_xptr(..., options)` wrapper. - -### Current `RcppTskit` behavior (as of this note) - -- Public R method `TableCollection$tree_sequence()` currently sets - `TSK_TS_INIT_BUILD_INDEXES` (via `bitwShiftL(1L, 0)`) and passes it to - `tc_xptr_to_ts_xptr(...)`. -- This is functionally fine, but it exposes C-style flag handling in the R - method implementation. - -Important nuance: - -- `tc_xptr_to_ts_xptr()` calls `tsk_treeseq_init(...)` without `TSK_TAKE_OWNERSHIP`. -- In tskit C, this means the tree sequence gets its own copied tables. -- If `TSK_TS_INIT_BUILD_INDEXES` is used there, indexes are built on the copied - tables (inside the tree sequence init path), not necessarily on the original - R `TableCollection` object. - -This differs from Python `TableCollection.tree_sequence()` behavior, which -builds indexes on the table collection itself before conversion. - -### Consistency goal (recommended) - -Use two layers with different styles on purpose: - -- R public API: Python-like, simple methods / logical arguments -- C++ low-level wrappers: C-like, bitwise `options` allowed - -That gives: - -- R-Python consistency for user-facing behavior -- C-C++ consistency for thin wrappers - -### Suggested future refactor for `TableCollection$tree_sequence()` - -Refactor R method to follow Python semantics explicitly: - -```r -tree_sequence = function() { - if (!self$has_index()) { - self$build_index() - } - ts_xptr <- tc_xptr_to_ts_xptr(self$pointer, options = 0L) - TreeSequence$new(pointer = ts_xptr) -} -``` - -Benefits: - -- No bitwise flag logic in R method implementation -- Easier to read and explain -- Matches Python behavior more closely -- Makes `has_index()` tests and state transitions clearer - -### Why `skip_tables = TRUE` is not a good "no index" test case - -I initially wondered whether loading a table collection with empty tables would -imply `has_index() == FALSE`. It does not reliably do that. - -Observation from local Python check: - -- `TableCollection.load(..., skip_tables=True)` can still report `has_index() == TRUE` - even when `num_edges == 0`. - -So: - -- "no rows" does not necessarily mean "no index" -- `skip_tables=TRUE` is not a robust negative test for `has_index()` - -### Best way to test `has_index()` false cases - -Add explicit index mutators to R API (matching Python): - -- `tc_xptr_build_index()` + `TableCollection$build_index()` -- `tc_xptr_drop_index()` + `TableCollection$drop_index()` - -Then tests become simple and deterministic: - -1. Load `tc` -2. `expect_true(tc$has_index())` -3. `tc$drop_index()` -4. `expect_false(tc$has_index())` -5. `tc$build_index()` -6. `expect_true(tc$has_index())` - -And for `tree_sequence()` behavior: - -1. Load `tc` -2. `tc$drop_index()` -3. `expect_false(tc$has_index())` -4. `ts <- tc$tree_sequence()` -5. Decide/document expected side effect: - - Python-consistent target: `tc$has_index()` becomes `TRUE` - - Current C-flag-inside-init approach may leave `tc` unchanged - -### Design decision to make explicitly (before implementing) - -Choose one and document it: - -- **Python-consistent behavior (recommended)**: - `TableCollection$tree_sequence()` may build indexes on `self` if missing. -- **Non-mutating conversion behavior**: - `TableCollection$tree_sequence()` builds indexes only in the transient treeseq - init path and leaves `self` as-is. - -The first option is more consistent with tskit Python and easier to reason -about for users switching between R and Python. - -### Minimal next steps when time allows - -1. Add `TableCollection$build_index()` / `$drop_index()` (+ `tc_xptr_*` wrappers). -2. Add focused tests for `has_index()` false/true transitions. -3. Refactor `TableCollection$tree_sequence()` to Python-style pre-check and - `build_index()`. -4. Add a regression test for `tc$tree_sequence()` behavior after dropping index. -5. Keep `tc_xptr_to_ts_xptr(..., options)` as low-level C-like API (do not remove). - -### Optional later (separate concern) - If needed, consider a Python-style logical argument on the R method for mutation-parent computation instead of exposing bitwise flags, e.g. `compute_mutation_parents = FALSE`, while still translating to @@ -172,7 +18,7 @@ extern/tskit/c/examples/multichrom_wright_fisher.c // [[Rcpp::export]] SEXP tc_grow(SEXP tc) { - RcppTskit_table_collection_xptr tc_xptr(tc); + rtsk_table_collection_t tc_xptr(tc); int ret; ret = 0; // Minimal example: grow the table collection in place by appending one child @@ -405,9 +251,9 @@ https://clang.llvm.org/extra/clang-tidy/ echo $(brew --prefix llvm)/bin/clang-tidy # /opt/homebrew/opt/llvm/bin/clang-tidy export CLANG_TIDY="$(brew --prefix llvm)/bin/clang-tidy" -./tools/clang-tidy.py src/RcppTskit.cpp -./RcppTskit/tools/clang-tidy.py RcppTskit/src/test_tsk_abort_stderr.cpp -- -system-headers '-header-filter=.*' -extra-arg=-Wno-unknown-warning-option -./tools/clang-tidy.py src/test_tsk_abort_stderr.cpp -- -system-headers '-header-filter=.*' -extra-arg=-Wno-unknown-warning-option +./tools/clang_tidy.py src/RcppTskit.cpp +./RcppTskit/tools/clang_tidy.py RcppTskit/src/test_tsk_abort_stderr.cpp -- -system-headers '-header-filter=.*' -extra-arg=-Wno-unknown-warning-option +./tools/clang_tidy.py src/test_tsk_abort_stderr.cpp -- -system-headers '-header-filter=.*' -extra-arg=-Wno-unknown-warning-option ``` or diff --git a/RcppTskit/src/RcppExports.cpp b/RcppTskit/src/RcppExports.cpp index f779d57..17b3b35 100644 --- a/RcppTskit/src/RcppExports.cpp +++ b/RcppTskit/src/RcppExports.cpp @@ -30,372 +30,395 @@ BEGIN_RCPP return rcpp_result_gen; END_RCPP } -// ts_xptr_load -SEXP ts_xptr_load(const std::string file, const int options); -RcppExport SEXP _RcppTskit_ts_xptr_load(SEXP fileSEXP, SEXP optionsSEXP) { +// rtsk_treeseq_load +SEXP rtsk_treeseq_load(const std::string filename, const int options); +RcppExport SEXP _RcppTskit_rtsk_treeseq_load(SEXP filenameSEXP, SEXP optionsSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; - Rcpp::traits::input_parameter< const std::string >::type file(fileSEXP); + Rcpp::traits::input_parameter< const std::string >::type filename(filenameSEXP); Rcpp::traits::input_parameter< const int >::type options(optionsSEXP); - rcpp_result_gen = Rcpp::wrap(ts_xptr_load(file, options)); + rcpp_result_gen = Rcpp::wrap(rtsk_treeseq_load(filename, options)); return rcpp_result_gen; END_RCPP } -// tc_xptr_load -SEXP tc_xptr_load(const std::string file, const int options); -RcppExport SEXP _RcppTskit_tc_xptr_load(SEXP fileSEXP, SEXP optionsSEXP) { +// rtsk_table_collection_load +SEXP rtsk_table_collection_load(const std::string filename, const int options); +RcppExport SEXP _RcppTskit_rtsk_table_collection_load(SEXP filenameSEXP, SEXP optionsSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; - Rcpp::traits::input_parameter< const std::string >::type file(fileSEXP); + Rcpp::traits::input_parameter< const std::string >::type filename(filenameSEXP); Rcpp::traits::input_parameter< const int >::type options(optionsSEXP); - rcpp_result_gen = Rcpp::wrap(tc_xptr_load(file, options)); + rcpp_result_gen = Rcpp::wrap(rtsk_table_collection_load(filename, options)); return rcpp_result_gen; END_RCPP } -// ts_xptr_dump -void ts_xptr_dump(const SEXP ts, const std::string file, const int options); -RcppExport SEXP _RcppTskit_ts_xptr_dump(SEXP tsSEXP, SEXP fileSEXP, SEXP optionsSEXP) { +// rtsk_treeseq_dump +void rtsk_treeseq_dump(const SEXP ts, const std::string filename, const int options); +RcppExport SEXP _RcppTskit_rtsk_treeseq_dump(SEXP tsSEXP, SEXP filenameSEXP, SEXP optionsSEXP) { BEGIN_RCPP Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const SEXP >::type ts(tsSEXP); - Rcpp::traits::input_parameter< const std::string >::type file(fileSEXP); + Rcpp::traits::input_parameter< const std::string >::type filename(filenameSEXP); Rcpp::traits::input_parameter< const int >::type options(optionsSEXP); - ts_xptr_dump(ts, file, options); + rtsk_treeseq_dump(ts, filename, options); return R_NilValue; END_RCPP } -// tc_xptr_dump -void tc_xptr_dump(const SEXP tc, const std::string file, const int options); -RcppExport SEXP _RcppTskit_tc_xptr_dump(SEXP tcSEXP, SEXP fileSEXP, SEXP optionsSEXP) { +// rtsk_table_collection_dump +void rtsk_table_collection_dump(const SEXP tc, const std::string filename, const int options); +RcppExport SEXP _RcppTskit_rtsk_table_collection_dump(SEXP tcSEXP, SEXP filenameSEXP, SEXP optionsSEXP) { BEGIN_RCPP Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const SEXP >::type tc(tcSEXP); - Rcpp::traits::input_parameter< const std::string >::type file(fileSEXP); + Rcpp::traits::input_parameter< const std::string >::type filename(filenameSEXP); Rcpp::traits::input_parameter< const int >::type options(optionsSEXP); - tc_xptr_dump(tc, file, options); + rtsk_table_collection_dump(tc, filename, options); return R_NilValue; END_RCPP } -// ts_xptr_to_tc_xptr -SEXP ts_xptr_to_tc_xptr(const SEXP ts, const int options); -RcppExport SEXP _RcppTskit_ts_xptr_to_tc_xptr(SEXP tsSEXP, SEXP optionsSEXP) { +// rtsk_treeseq_copy_tables +SEXP rtsk_treeseq_copy_tables(const SEXP ts, const int options); +RcppExport SEXP _RcppTskit_rtsk_treeseq_copy_tables(SEXP tsSEXP, SEXP optionsSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const SEXP >::type ts(tsSEXP); Rcpp::traits::input_parameter< const int >::type options(optionsSEXP); - rcpp_result_gen = Rcpp::wrap(ts_xptr_to_tc_xptr(ts, options)); + rcpp_result_gen = Rcpp::wrap(rtsk_treeseq_copy_tables(ts, options)); return rcpp_result_gen; END_RCPP } -// tc_xptr_to_ts_xptr -SEXP tc_xptr_to_ts_xptr(const SEXP tc, const int options); -RcppExport SEXP _RcppTskit_tc_xptr_to_ts_xptr(SEXP tcSEXP, SEXP optionsSEXP) { +// rtsk_treeseq_init +SEXP rtsk_treeseq_init(const SEXP tc, const int options); +RcppExport SEXP _RcppTskit_rtsk_treeseq_init(SEXP tcSEXP, SEXP optionsSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const SEXP >::type tc(tcSEXP); Rcpp::traits::input_parameter< const int >::type options(optionsSEXP); - rcpp_result_gen = Rcpp::wrap(tc_xptr_to_ts_xptr(tc, options)); + rcpp_result_gen = Rcpp::wrap(rtsk_treeseq_init(tc, options)); return rcpp_result_gen; END_RCPP } -// ts_xptr_num_provenances -int ts_xptr_num_provenances(const SEXP ts); -RcppExport SEXP _RcppTskit_ts_xptr_num_provenances(SEXP tsSEXP) { +// rtsk_treeseq_get_num_provenances +int rtsk_treeseq_get_num_provenances(const SEXP ts); +RcppExport SEXP _RcppTskit_rtsk_treeseq_get_num_provenances(SEXP tsSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const SEXP >::type ts(tsSEXP); - rcpp_result_gen = Rcpp::wrap(ts_xptr_num_provenances(ts)); + rcpp_result_gen = Rcpp::wrap(rtsk_treeseq_get_num_provenances(ts)); return rcpp_result_gen; END_RCPP } -// ts_xptr_num_populations -int ts_xptr_num_populations(const SEXP ts); -RcppExport SEXP _RcppTskit_ts_xptr_num_populations(SEXP tsSEXP) { +// rtsk_treeseq_get_num_populations +int rtsk_treeseq_get_num_populations(const SEXP ts); +RcppExport SEXP _RcppTskit_rtsk_treeseq_get_num_populations(SEXP tsSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const SEXP >::type ts(tsSEXP); - rcpp_result_gen = Rcpp::wrap(ts_xptr_num_populations(ts)); + rcpp_result_gen = Rcpp::wrap(rtsk_treeseq_get_num_populations(ts)); return rcpp_result_gen; END_RCPP } -// ts_xptr_num_migrations -int ts_xptr_num_migrations(const SEXP ts); -RcppExport SEXP _RcppTskit_ts_xptr_num_migrations(SEXP tsSEXP) { +// rtsk_treeseq_get_num_migrations +int rtsk_treeseq_get_num_migrations(const SEXP ts); +RcppExport SEXP _RcppTskit_rtsk_treeseq_get_num_migrations(SEXP tsSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const SEXP >::type ts(tsSEXP); - rcpp_result_gen = Rcpp::wrap(ts_xptr_num_migrations(ts)); + rcpp_result_gen = Rcpp::wrap(rtsk_treeseq_get_num_migrations(ts)); return rcpp_result_gen; END_RCPP } -// ts_xptr_num_individuals -int ts_xptr_num_individuals(const SEXP ts); -RcppExport SEXP _RcppTskit_ts_xptr_num_individuals(SEXP tsSEXP) { +// rtsk_treeseq_get_num_individuals +int rtsk_treeseq_get_num_individuals(const SEXP ts); +RcppExport SEXP _RcppTskit_rtsk_treeseq_get_num_individuals(SEXP tsSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const SEXP >::type ts(tsSEXP); - rcpp_result_gen = Rcpp::wrap(ts_xptr_num_individuals(ts)); + rcpp_result_gen = Rcpp::wrap(rtsk_treeseq_get_num_individuals(ts)); return rcpp_result_gen; END_RCPP } -// ts_xptr_num_samples -int ts_xptr_num_samples(const SEXP ts); -RcppExport SEXP _RcppTskit_ts_xptr_num_samples(SEXP tsSEXP) { +// rtsk_treeseq_get_num_samples +int rtsk_treeseq_get_num_samples(const SEXP ts); +RcppExport SEXP _RcppTskit_rtsk_treeseq_get_num_samples(SEXP tsSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const SEXP >::type ts(tsSEXP); - rcpp_result_gen = Rcpp::wrap(ts_xptr_num_samples(ts)); + rcpp_result_gen = Rcpp::wrap(rtsk_treeseq_get_num_samples(ts)); return rcpp_result_gen; END_RCPP } -// ts_xptr_num_nodes -int ts_xptr_num_nodes(const SEXP ts); -RcppExport SEXP _RcppTskit_ts_xptr_num_nodes(SEXP tsSEXP) { +// rtsk_treeseq_get_num_nodes +int rtsk_treeseq_get_num_nodes(const SEXP ts); +RcppExport SEXP _RcppTskit_rtsk_treeseq_get_num_nodes(SEXP tsSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const SEXP >::type ts(tsSEXP); - rcpp_result_gen = Rcpp::wrap(ts_xptr_num_nodes(ts)); + rcpp_result_gen = Rcpp::wrap(rtsk_treeseq_get_num_nodes(ts)); return rcpp_result_gen; END_RCPP } -// ts_xptr_num_edges -int ts_xptr_num_edges(const SEXP ts); -RcppExport SEXP _RcppTskit_ts_xptr_num_edges(SEXP tsSEXP) { +// rtsk_treeseq_get_num_edges +int rtsk_treeseq_get_num_edges(const SEXP ts); +RcppExport SEXP _RcppTskit_rtsk_treeseq_get_num_edges(SEXP tsSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const SEXP >::type ts(tsSEXP); - rcpp_result_gen = Rcpp::wrap(ts_xptr_num_edges(ts)); + rcpp_result_gen = Rcpp::wrap(rtsk_treeseq_get_num_edges(ts)); return rcpp_result_gen; END_RCPP } -// ts_xptr_num_trees -int ts_xptr_num_trees(const SEXP ts); -RcppExport SEXP _RcppTskit_ts_xptr_num_trees(SEXP tsSEXP) { +// rtsk_treeseq_get_num_trees +int rtsk_treeseq_get_num_trees(const SEXP ts); +RcppExport SEXP _RcppTskit_rtsk_treeseq_get_num_trees(SEXP tsSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const SEXP >::type ts(tsSEXP); - rcpp_result_gen = Rcpp::wrap(ts_xptr_num_trees(ts)); + rcpp_result_gen = Rcpp::wrap(rtsk_treeseq_get_num_trees(ts)); return rcpp_result_gen; END_RCPP } -// ts_xptr_num_sites -int ts_xptr_num_sites(const SEXP ts); -RcppExport SEXP _RcppTskit_ts_xptr_num_sites(SEXP tsSEXP) { +// rtsk_treeseq_get_num_sites +int rtsk_treeseq_get_num_sites(const SEXP ts); +RcppExport SEXP _RcppTskit_rtsk_treeseq_get_num_sites(SEXP tsSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const SEXP >::type ts(tsSEXP); - rcpp_result_gen = Rcpp::wrap(ts_xptr_num_sites(ts)); + rcpp_result_gen = Rcpp::wrap(rtsk_treeseq_get_num_sites(ts)); return rcpp_result_gen; END_RCPP } -// ts_xptr_num_mutations -int ts_xptr_num_mutations(const SEXP ts); -RcppExport SEXP _RcppTskit_ts_xptr_num_mutations(SEXP tsSEXP) { +// rtsk_treeseq_get_num_mutations +int rtsk_treeseq_get_num_mutations(const SEXP ts); +RcppExport SEXP _RcppTskit_rtsk_treeseq_get_num_mutations(SEXP tsSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const SEXP >::type ts(tsSEXP); - rcpp_result_gen = Rcpp::wrap(ts_xptr_num_mutations(ts)); + rcpp_result_gen = Rcpp::wrap(rtsk_treeseq_get_num_mutations(ts)); return rcpp_result_gen; END_RCPP } -// ts_xptr_sequence_length -double ts_xptr_sequence_length(const SEXP ts); -RcppExport SEXP _RcppTskit_ts_xptr_sequence_length(SEXP tsSEXP) { +// rtsk_treeseq_get_sequence_length +double rtsk_treeseq_get_sequence_length(const SEXP ts); +RcppExport SEXP _RcppTskit_rtsk_treeseq_get_sequence_length(SEXP tsSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const SEXP >::type ts(tsSEXP); - rcpp_result_gen = Rcpp::wrap(ts_xptr_sequence_length(ts)); + rcpp_result_gen = Rcpp::wrap(rtsk_treeseq_get_sequence_length(ts)); return rcpp_result_gen; END_RCPP } -// ts_xptr_discrete_genome -bool ts_xptr_discrete_genome(const SEXP ts); -RcppExport SEXP _RcppTskit_ts_xptr_discrete_genome(SEXP tsSEXP) { +// rtsk_treeseq_get_discrete_genome +bool rtsk_treeseq_get_discrete_genome(const SEXP ts); +RcppExport SEXP _RcppTskit_rtsk_treeseq_get_discrete_genome(SEXP tsSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const SEXP >::type ts(tsSEXP); - rcpp_result_gen = Rcpp::wrap(ts_xptr_discrete_genome(ts)); + rcpp_result_gen = Rcpp::wrap(rtsk_treeseq_get_discrete_genome(ts)); return rcpp_result_gen; END_RCPP } -// ts_xptr_has_reference_sequence -bool ts_xptr_has_reference_sequence(const SEXP ts); -RcppExport SEXP _RcppTskit_ts_xptr_has_reference_sequence(SEXP tsSEXP) { +// rtsk_treeseq_has_reference_sequence +bool rtsk_treeseq_has_reference_sequence(const SEXP ts); +RcppExport SEXP _RcppTskit_rtsk_treeseq_has_reference_sequence(SEXP tsSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const SEXP >::type ts(tsSEXP); - rcpp_result_gen = Rcpp::wrap(ts_xptr_has_reference_sequence(ts)); + rcpp_result_gen = Rcpp::wrap(rtsk_treeseq_has_reference_sequence(ts)); return rcpp_result_gen; END_RCPP } -// ts_xptr_time_units -Rcpp::String ts_xptr_time_units(const SEXP ts); -RcppExport SEXP _RcppTskit_ts_xptr_time_units(SEXP tsSEXP) { +// rtsk_treeseq_get_time_units +Rcpp::String rtsk_treeseq_get_time_units(const SEXP ts); +RcppExport SEXP _RcppTskit_rtsk_treeseq_get_time_units(SEXP tsSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const SEXP >::type ts(tsSEXP); - rcpp_result_gen = Rcpp::wrap(ts_xptr_time_units(ts)); + rcpp_result_gen = Rcpp::wrap(rtsk_treeseq_get_time_units(ts)); return rcpp_result_gen; END_RCPP } -// ts_xptr_discrete_time -bool ts_xptr_discrete_time(const SEXP ts); -RcppExport SEXP _RcppTskit_ts_xptr_discrete_time(SEXP tsSEXP) { +// rtsk_treeseq_get_discrete_time +bool rtsk_treeseq_get_discrete_time(const SEXP ts); +RcppExport SEXP _RcppTskit_rtsk_treeseq_get_discrete_time(SEXP tsSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const SEXP >::type ts(tsSEXP); - rcpp_result_gen = Rcpp::wrap(ts_xptr_discrete_time(ts)); + rcpp_result_gen = Rcpp::wrap(rtsk_treeseq_get_discrete_time(ts)); return rcpp_result_gen; END_RCPP } -// ts_xptr_min_time -double ts_xptr_min_time(const SEXP ts); -RcppExport SEXP _RcppTskit_ts_xptr_min_time(SEXP tsSEXP) { +// rtsk_treeseq_get_min_time +double rtsk_treeseq_get_min_time(const SEXP ts); +RcppExport SEXP _RcppTskit_rtsk_treeseq_get_min_time(SEXP tsSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const SEXP >::type ts(tsSEXP); - rcpp_result_gen = Rcpp::wrap(ts_xptr_min_time(ts)); + rcpp_result_gen = Rcpp::wrap(rtsk_treeseq_get_min_time(ts)); return rcpp_result_gen; END_RCPP } -// ts_xptr_max_time -double ts_xptr_max_time(const SEXP ts); -RcppExport SEXP _RcppTskit_ts_xptr_max_time(SEXP tsSEXP) { +// rtsk_treeseq_get_max_time +double rtsk_treeseq_get_max_time(const SEXP ts); +RcppExport SEXP _RcppTskit_rtsk_treeseq_get_max_time(SEXP tsSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const SEXP >::type ts(tsSEXP); - rcpp_result_gen = Rcpp::wrap(ts_xptr_max_time(ts)); + rcpp_result_gen = Rcpp::wrap(rtsk_treeseq_get_max_time(ts)); return rcpp_result_gen; END_RCPP } -// ts_xptr_file_uuid -Rcpp::String ts_xptr_file_uuid(const SEXP ts); -RcppExport SEXP _RcppTskit_ts_xptr_file_uuid(SEXP tsSEXP) { +// rtsk_treeseq_get_file_uuid +Rcpp::String rtsk_treeseq_get_file_uuid(const SEXP ts); +RcppExport SEXP _RcppTskit_rtsk_treeseq_get_file_uuid(SEXP tsSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const SEXP >::type ts(tsSEXP); - rcpp_result_gen = Rcpp::wrap(ts_xptr_file_uuid(ts)); + rcpp_result_gen = Rcpp::wrap(rtsk_treeseq_get_file_uuid(ts)); return rcpp_result_gen; END_RCPP } -// ts_xptr_summary -Rcpp::List ts_xptr_summary(const SEXP ts); -RcppExport SEXP _RcppTskit_ts_xptr_summary(SEXP tsSEXP) { +// rtsk_treeseq_summary +Rcpp::List rtsk_treeseq_summary(const SEXP ts); +RcppExport SEXP _RcppTskit_rtsk_treeseq_summary(SEXP tsSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const SEXP >::type ts(tsSEXP); - rcpp_result_gen = Rcpp::wrap(ts_xptr_summary(ts)); + rcpp_result_gen = Rcpp::wrap(rtsk_treeseq_summary(ts)); return rcpp_result_gen; END_RCPP } -// ts_xptr_metadata_length -Rcpp::List ts_xptr_metadata_length(const SEXP ts); -RcppExport SEXP _RcppTskit_ts_xptr_metadata_length(SEXP tsSEXP) { +// rtsk_treeseq_metadata_length +Rcpp::List rtsk_treeseq_metadata_length(const SEXP ts); +RcppExport SEXP _RcppTskit_rtsk_treeseq_metadata_length(SEXP tsSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const SEXP >::type ts(tsSEXP); - rcpp_result_gen = Rcpp::wrap(ts_xptr_metadata_length(ts)); + rcpp_result_gen = Rcpp::wrap(rtsk_treeseq_metadata_length(ts)); return rcpp_result_gen; END_RCPP } -// tc_xptr_sequence_length -double tc_xptr_sequence_length(const SEXP tc); -RcppExport SEXP _RcppTskit_tc_xptr_sequence_length(SEXP tcSEXP) { +// rtsk_table_collection_get_sequence_length +double rtsk_table_collection_get_sequence_length(const SEXP tc); +RcppExport SEXP _RcppTskit_rtsk_table_collection_get_sequence_length(SEXP tcSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const SEXP >::type tc(tcSEXP); - rcpp_result_gen = Rcpp::wrap(tc_xptr_sequence_length(tc)); + rcpp_result_gen = Rcpp::wrap(rtsk_table_collection_get_sequence_length(tc)); return rcpp_result_gen; END_RCPP } -// tc_xptr_has_reference_sequence -bool tc_xptr_has_reference_sequence(const SEXP tc); -RcppExport SEXP _RcppTskit_tc_xptr_has_reference_sequence(SEXP tcSEXP) { +// rtsk_table_collection_has_reference_sequence +bool rtsk_table_collection_has_reference_sequence(const SEXP tc); +RcppExport SEXP _RcppTskit_rtsk_table_collection_has_reference_sequence(SEXP tcSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const SEXP >::type tc(tcSEXP); - rcpp_result_gen = Rcpp::wrap(tc_xptr_has_reference_sequence(tc)); + rcpp_result_gen = Rcpp::wrap(rtsk_table_collection_has_reference_sequence(tc)); return rcpp_result_gen; END_RCPP } -// tc_xptr_time_units -Rcpp::String tc_xptr_time_units(const SEXP tc); -RcppExport SEXP _RcppTskit_tc_xptr_time_units(SEXP tcSEXP) { +// rtsk_table_collection_get_time_units +Rcpp::String rtsk_table_collection_get_time_units(const SEXP tc); +RcppExport SEXP _RcppTskit_rtsk_table_collection_get_time_units(SEXP tcSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const SEXP >::type tc(tcSEXP); - rcpp_result_gen = Rcpp::wrap(tc_xptr_time_units(tc)); + rcpp_result_gen = Rcpp::wrap(rtsk_table_collection_get_time_units(tc)); return rcpp_result_gen; END_RCPP } -// tc_xptr_file_uuid -Rcpp::String tc_xptr_file_uuid(const SEXP tc); -RcppExport SEXP _RcppTskit_tc_xptr_file_uuid(SEXP tcSEXP) { +// rtsk_table_collection_get_file_uuid +Rcpp::String rtsk_table_collection_get_file_uuid(const SEXP tc); +RcppExport SEXP _RcppTskit_rtsk_table_collection_get_file_uuid(SEXP tcSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const SEXP >::type tc(tcSEXP); - rcpp_result_gen = Rcpp::wrap(tc_xptr_file_uuid(tc)); + rcpp_result_gen = Rcpp::wrap(rtsk_table_collection_get_file_uuid(tc)); return rcpp_result_gen; END_RCPP } -// tc_xptr_has_index -bool tc_xptr_has_index(const SEXP tc); -RcppExport SEXP _RcppTskit_tc_xptr_has_index(SEXP tcSEXP) { +// rtsk_table_collection_has_index +bool rtsk_table_collection_has_index(const SEXP tc, const int options); +RcppExport SEXP _RcppTskit_rtsk_table_collection_has_index(SEXP tcSEXP, SEXP optionsSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const SEXP >::type tc(tcSEXP); - rcpp_result_gen = Rcpp::wrap(tc_xptr_has_index(tc)); + Rcpp::traits::input_parameter< const int >::type options(optionsSEXP); + rcpp_result_gen = Rcpp::wrap(rtsk_table_collection_has_index(tc, options)); return rcpp_result_gen; END_RCPP } -// tc_xptr_summary -Rcpp::List tc_xptr_summary(const SEXP tc); -RcppExport SEXP _RcppTskit_tc_xptr_summary(SEXP tcSEXP) { +// rtsk_table_collection_build_index +void rtsk_table_collection_build_index(const SEXP tc, const int options); +RcppExport SEXP _RcppTskit_rtsk_table_collection_build_index(SEXP tcSEXP, SEXP optionsSEXP) { +BEGIN_RCPP + Rcpp::RNGScope rcpp_rngScope_gen; + Rcpp::traits::input_parameter< const SEXP >::type tc(tcSEXP); + Rcpp::traits::input_parameter< const int >::type options(optionsSEXP); + rtsk_table_collection_build_index(tc, options); + return R_NilValue; +END_RCPP +} +// rtsk_table_collection_drop_index +void rtsk_table_collection_drop_index(const SEXP tc, const int options); +RcppExport SEXP _RcppTskit_rtsk_table_collection_drop_index(SEXP tcSEXP, SEXP optionsSEXP) { +BEGIN_RCPP + Rcpp::RNGScope rcpp_rngScope_gen; + Rcpp::traits::input_parameter< const SEXP >::type tc(tcSEXP); + Rcpp::traits::input_parameter< const int >::type options(optionsSEXP); + rtsk_table_collection_drop_index(tc, options); + return R_NilValue; +END_RCPP +} +// rtsk_table_collection_summary +Rcpp::List rtsk_table_collection_summary(const SEXP tc); +RcppExport SEXP _RcppTskit_rtsk_table_collection_summary(SEXP tcSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const SEXP >::type tc(tcSEXP); - rcpp_result_gen = Rcpp::wrap(tc_xptr_summary(tc)); + rcpp_result_gen = Rcpp::wrap(rtsk_table_collection_summary(tc)); return rcpp_result_gen; END_RCPP } -// tc_xptr_metadata_length -Rcpp::List tc_xptr_metadata_length(const SEXP tc); -RcppExport SEXP _RcppTskit_tc_xptr_metadata_length(SEXP tcSEXP) { +// rtsk_table_collection_metadata_length +Rcpp::List rtsk_table_collection_metadata_length(const SEXP tc); +RcppExport SEXP _RcppTskit_rtsk_table_collection_metadata_length(SEXP tcSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const SEXP >::type tc(tcSEXP); - rcpp_result_gen = Rcpp::wrap(tc_xptr_metadata_length(tc)); + rcpp_result_gen = Rcpp::wrap(rtsk_table_collection_metadata_length(tc)); return rcpp_result_gen; END_RCPP } @@ -445,72 +468,85 @@ BEGIN_RCPP return rcpp_result_gen; END_RCPP } -// test_ts_xptr_to_tc_xptr_forced_error -SEXP test_ts_xptr_to_tc_xptr_forced_error(const SEXP ts); -RcppExport SEXP _RcppTskit_test_ts_xptr_to_tc_xptr_forced_error(SEXP tsSEXP) { +// test_rtsk_treeseq_copy_tables_forced_error +SEXP test_rtsk_treeseq_copy_tables_forced_error(const SEXP ts); +RcppExport SEXP _RcppTskit_test_rtsk_treeseq_copy_tables_forced_error(SEXP tsSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const SEXP >::type ts(tsSEXP); - rcpp_result_gen = Rcpp::wrap(test_ts_xptr_to_tc_xptr_forced_error(ts)); + rcpp_result_gen = Rcpp::wrap(test_rtsk_treeseq_copy_tables_forced_error(ts)); return rcpp_result_gen; END_RCPP } -// test_tc_xptr_to_ts_xptr_forced_error -SEXP test_tc_xptr_to_ts_xptr_forced_error(const SEXP tc); -RcppExport SEXP _RcppTskit_test_tc_xptr_to_ts_xptr_forced_error(SEXP tcSEXP) { +// test_rtsk_treeseq_init_forced_error +SEXP test_rtsk_treeseq_init_forced_error(const SEXP tc); +RcppExport SEXP _RcppTskit_test_rtsk_treeseq_init_forced_error(SEXP tcSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const SEXP >::type tc(tcSEXP); - rcpp_result_gen = Rcpp::wrap(test_tc_xptr_to_ts_xptr_forced_error(tc)); + rcpp_result_gen = Rcpp::wrap(test_rtsk_treeseq_init_forced_error(tc)); return rcpp_result_gen; END_RCPP } +// test_rtsk_table_collection_build_index_forced_error +void test_rtsk_table_collection_build_index_forced_error(const SEXP tc); +RcppExport SEXP _RcppTskit_test_rtsk_table_collection_build_index_forced_error(SEXP tcSEXP) { +BEGIN_RCPP + Rcpp::RNGScope rcpp_rngScope_gen; + Rcpp::traits::input_parameter< const SEXP >::type tc(tcSEXP); + test_rtsk_table_collection_build_index_forced_error(tc); + return R_NilValue; +END_RCPP +} static const R_CallMethodDef CallEntries[] = { {"_RcppTskit_kastore_version", (DL_FUNC) &_RcppTskit_kastore_version, 0}, {"_RcppTskit_tskit_version", (DL_FUNC) &_RcppTskit_tskit_version, 0}, - {"_RcppTskit_ts_xptr_load", (DL_FUNC) &_RcppTskit_ts_xptr_load, 2}, - {"_RcppTskit_tc_xptr_load", (DL_FUNC) &_RcppTskit_tc_xptr_load, 2}, - {"_RcppTskit_ts_xptr_dump", (DL_FUNC) &_RcppTskit_ts_xptr_dump, 3}, - {"_RcppTskit_tc_xptr_dump", (DL_FUNC) &_RcppTskit_tc_xptr_dump, 3}, - {"_RcppTskit_ts_xptr_to_tc_xptr", (DL_FUNC) &_RcppTskit_ts_xptr_to_tc_xptr, 2}, - {"_RcppTskit_tc_xptr_to_ts_xptr", (DL_FUNC) &_RcppTskit_tc_xptr_to_ts_xptr, 2}, - {"_RcppTskit_ts_xptr_num_provenances", (DL_FUNC) &_RcppTskit_ts_xptr_num_provenances, 1}, - {"_RcppTskit_ts_xptr_num_populations", (DL_FUNC) &_RcppTskit_ts_xptr_num_populations, 1}, - {"_RcppTskit_ts_xptr_num_migrations", (DL_FUNC) &_RcppTskit_ts_xptr_num_migrations, 1}, - {"_RcppTskit_ts_xptr_num_individuals", (DL_FUNC) &_RcppTskit_ts_xptr_num_individuals, 1}, - {"_RcppTskit_ts_xptr_num_samples", (DL_FUNC) &_RcppTskit_ts_xptr_num_samples, 1}, - {"_RcppTskit_ts_xptr_num_nodes", (DL_FUNC) &_RcppTskit_ts_xptr_num_nodes, 1}, - {"_RcppTskit_ts_xptr_num_edges", (DL_FUNC) &_RcppTskit_ts_xptr_num_edges, 1}, - {"_RcppTskit_ts_xptr_num_trees", (DL_FUNC) &_RcppTskit_ts_xptr_num_trees, 1}, - {"_RcppTskit_ts_xptr_num_sites", (DL_FUNC) &_RcppTskit_ts_xptr_num_sites, 1}, - {"_RcppTskit_ts_xptr_num_mutations", (DL_FUNC) &_RcppTskit_ts_xptr_num_mutations, 1}, - {"_RcppTskit_ts_xptr_sequence_length", (DL_FUNC) &_RcppTskit_ts_xptr_sequence_length, 1}, - {"_RcppTskit_ts_xptr_discrete_genome", (DL_FUNC) &_RcppTskit_ts_xptr_discrete_genome, 1}, - {"_RcppTskit_ts_xptr_has_reference_sequence", (DL_FUNC) &_RcppTskit_ts_xptr_has_reference_sequence, 1}, - {"_RcppTskit_ts_xptr_time_units", (DL_FUNC) &_RcppTskit_ts_xptr_time_units, 1}, - {"_RcppTskit_ts_xptr_discrete_time", (DL_FUNC) &_RcppTskit_ts_xptr_discrete_time, 1}, - {"_RcppTskit_ts_xptr_min_time", (DL_FUNC) &_RcppTskit_ts_xptr_min_time, 1}, - {"_RcppTskit_ts_xptr_max_time", (DL_FUNC) &_RcppTskit_ts_xptr_max_time, 1}, - {"_RcppTskit_ts_xptr_file_uuid", (DL_FUNC) &_RcppTskit_ts_xptr_file_uuid, 1}, - {"_RcppTskit_ts_xptr_summary", (DL_FUNC) &_RcppTskit_ts_xptr_summary, 1}, - {"_RcppTskit_ts_xptr_metadata_length", (DL_FUNC) &_RcppTskit_ts_xptr_metadata_length, 1}, - {"_RcppTskit_tc_xptr_sequence_length", (DL_FUNC) &_RcppTskit_tc_xptr_sequence_length, 1}, - {"_RcppTskit_tc_xptr_has_reference_sequence", (DL_FUNC) &_RcppTskit_tc_xptr_has_reference_sequence, 1}, - {"_RcppTskit_tc_xptr_time_units", (DL_FUNC) &_RcppTskit_tc_xptr_time_units, 1}, - {"_RcppTskit_tc_xptr_file_uuid", (DL_FUNC) &_RcppTskit_tc_xptr_file_uuid, 1}, - {"_RcppTskit_tc_xptr_has_index", (DL_FUNC) &_RcppTskit_tc_xptr_has_index, 1}, - {"_RcppTskit_tc_xptr_summary", (DL_FUNC) &_RcppTskit_tc_xptr_summary, 1}, - {"_RcppTskit_tc_xptr_metadata_length", (DL_FUNC) &_RcppTskit_tc_xptr_metadata_length, 1}, + {"_RcppTskit_rtsk_treeseq_load", (DL_FUNC) &_RcppTskit_rtsk_treeseq_load, 2}, + {"_RcppTskit_rtsk_table_collection_load", (DL_FUNC) &_RcppTskit_rtsk_table_collection_load, 2}, + {"_RcppTskit_rtsk_treeseq_dump", (DL_FUNC) &_RcppTskit_rtsk_treeseq_dump, 3}, + {"_RcppTskit_rtsk_table_collection_dump", (DL_FUNC) &_RcppTskit_rtsk_table_collection_dump, 3}, + {"_RcppTskit_rtsk_treeseq_copy_tables", (DL_FUNC) &_RcppTskit_rtsk_treeseq_copy_tables, 2}, + {"_RcppTskit_rtsk_treeseq_init", (DL_FUNC) &_RcppTskit_rtsk_treeseq_init, 2}, + {"_RcppTskit_rtsk_treeseq_get_num_provenances", (DL_FUNC) &_RcppTskit_rtsk_treeseq_get_num_provenances, 1}, + {"_RcppTskit_rtsk_treeseq_get_num_populations", (DL_FUNC) &_RcppTskit_rtsk_treeseq_get_num_populations, 1}, + {"_RcppTskit_rtsk_treeseq_get_num_migrations", (DL_FUNC) &_RcppTskit_rtsk_treeseq_get_num_migrations, 1}, + {"_RcppTskit_rtsk_treeseq_get_num_individuals", (DL_FUNC) &_RcppTskit_rtsk_treeseq_get_num_individuals, 1}, + {"_RcppTskit_rtsk_treeseq_get_num_samples", (DL_FUNC) &_RcppTskit_rtsk_treeseq_get_num_samples, 1}, + {"_RcppTskit_rtsk_treeseq_get_num_nodes", (DL_FUNC) &_RcppTskit_rtsk_treeseq_get_num_nodes, 1}, + {"_RcppTskit_rtsk_treeseq_get_num_edges", (DL_FUNC) &_RcppTskit_rtsk_treeseq_get_num_edges, 1}, + {"_RcppTskit_rtsk_treeseq_get_num_trees", (DL_FUNC) &_RcppTskit_rtsk_treeseq_get_num_trees, 1}, + {"_RcppTskit_rtsk_treeseq_get_num_sites", (DL_FUNC) &_RcppTskit_rtsk_treeseq_get_num_sites, 1}, + {"_RcppTskit_rtsk_treeseq_get_num_mutations", (DL_FUNC) &_RcppTskit_rtsk_treeseq_get_num_mutations, 1}, + {"_RcppTskit_rtsk_treeseq_get_sequence_length", (DL_FUNC) &_RcppTskit_rtsk_treeseq_get_sequence_length, 1}, + {"_RcppTskit_rtsk_treeseq_get_discrete_genome", (DL_FUNC) &_RcppTskit_rtsk_treeseq_get_discrete_genome, 1}, + {"_RcppTskit_rtsk_treeseq_has_reference_sequence", (DL_FUNC) &_RcppTskit_rtsk_treeseq_has_reference_sequence, 1}, + {"_RcppTskit_rtsk_treeseq_get_time_units", (DL_FUNC) &_RcppTskit_rtsk_treeseq_get_time_units, 1}, + {"_RcppTskit_rtsk_treeseq_get_discrete_time", (DL_FUNC) &_RcppTskit_rtsk_treeseq_get_discrete_time, 1}, + {"_RcppTskit_rtsk_treeseq_get_min_time", (DL_FUNC) &_RcppTskit_rtsk_treeseq_get_min_time, 1}, + {"_RcppTskit_rtsk_treeseq_get_max_time", (DL_FUNC) &_RcppTskit_rtsk_treeseq_get_max_time, 1}, + {"_RcppTskit_rtsk_treeseq_get_file_uuid", (DL_FUNC) &_RcppTskit_rtsk_treeseq_get_file_uuid, 1}, + {"_RcppTskit_rtsk_treeseq_summary", (DL_FUNC) &_RcppTskit_rtsk_treeseq_summary, 1}, + {"_RcppTskit_rtsk_treeseq_metadata_length", (DL_FUNC) &_RcppTskit_rtsk_treeseq_metadata_length, 1}, + {"_RcppTskit_rtsk_table_collection_get_sequence_length", (DL_FUNC) &_RcppTskit_rtsk_table_collection_get_sequence_length, 1}, + {"_RcppTskit_rtsk_table_collection_has_reference_sequence", (DL_FUNC) &_RcppTskit_rtsk_table_collection_has_reference_sequence, 1}, + {"_RcppTskit_rtsk_table_collection_get_time_units", (DL_FUNC) &_RcppTskit_rtsk_table_collection_get_time_units, 1}, + {"_RcppTskit_rtsk_table_collection_get_file_uuid", (DL_FUNC) &_RcppTskit_rtsk_table_collection_get_file_uuid, 1}, + {"_RcppTskit_rtsk_table_collection_has_index", (DL_FUNC) &_RcppTskit_rtsk_table_collection_has_index, 2}, + {"_RcppTskit_rtsk_table_collection_build_index", (DL_FUNC) &_RcppTskit_rtsk_table_collection_build_index, 2}, + {"_RcppTskit_rtsk_table_collection_drop_index", (DL_FUNC) &_RcppTskit_rtsk_table_collection_drop_index, 2}, + {"_RcppTskit_rtsk_table_collection_summary", (DL_FUNC) &_RcppTskit_rtsk_table_collection_summary, 1}, + {"_RcppTskit_rtsk_table_collection_metadata_length", (DL_FUNC) &_RcppTskit_rtsk_table_collection_metadata_length, 1}, {"_RcppTskit_test_tsk_bug_assert_c", (DL_FUNC) &_RcppTskit_test_tsk_bug_assert_c, 0}, {"_RcppTskit_test_tsk_bug_assert_cpp", (DL_FUNC) &_RcppTskit_test_tsk_bug_assert_cpp, 0}, {"_RcppTskit_test_tsk_trace_error_c", (DL_FUNC) &_RcppTskit_test_tsk_trace_error_c, 0}, {"_RcppTskit_test_tsk_trace_error_cpp", (DL_FUNC) &_RcppTskit_test_tsk_trace_error_cpp, 0}, {"_RcppTskit_tsk_trace_errors_defined", (DL_FUNC) &_RcppTskit_tsk_trace_errors_defined, 0}, - {"_RcppTskit_test_ts_xptr_to_tc_xptr_forced_error", (DL_FUNC) &_RcppTskit_test_ts_xptr_to_tc_xptr_forced_error, 1}, - {"_RcppTskit_test_tc_xptr_to_ts_xptr_forced_error", (DL_FUNC) &_RcppTskit_test_tc_xptr_to_ts_xptr_forced_error, 1}, + {"_RcppTskit_test_rtsk_treeseq_copy_tables_forced_error", (DL_FUNC) &_RcppTskit_test_rtsk_treeseq_copy_tables_forced_error, 1}, + {"_RcppTskit_test_rtsk_treeseq_init_forced_error", (DL_FUNC) &_RcppTskit_test_rtsk_treeseq_init_forced_error, 1}, + {"_RcppTskit_test_rtsk_table_collection_build_index_forced_error", (DL_FUNC) &_RcppTskit_test_rtsk_table_collection_build_index_forced_error, 1}, {NULL, NULL, 0} }; diff --git a/RcppTskit/src/RcppTskit.cpp b/RcppTskit/src/RcppTskit.cpp index 415480e..ed15cd2 100644 --- a/RcppTskit/src/RcppTskit.cpp +++ b/RcppTskit/src/RcppTskit.cpp @@ -22,8 +22,8 @@ constexpr tsk_flags_t kTreeseqInitSupportedOptions = // @param caller function name // @details See // \url{https://tskit.dev/tskit/docs/stable/c-api.html#c.tsk_table_collection_load}. -// The \code{ts_xptr_load} and \code{tc_xptr_load} allocate objects, so -// we can't work with \code{TSK_NO_INIT} +// The \code{rtsk_treeseq_load} and \code{rtsk_table_collection_load} allocate +// objects, so we can't work with \code{TSK_NO_INIT} // \url{https://tskit.dev/tskit/docs/stable/c-api.html#c.TSK_NO_INIT}. tsk_flags_t validate_load_options(const int options, const char *caller) { const tsk_flags_t load_options = static_cast(options); @@ -46,7 +46,7 @@ tsk_flags_t validate_load_options(const int options, const char *caller) { // \url{https://tskit.dev/tskit/docs/stable/c-api.html#c.tsk_treeseq_copy_tables} // and // \url{https://tskit.dev/tskit/docs/stable/c-api.html#c.tsk_table_collection_copy}. -// The \code{ts_xptr_to_tc_xptr} allocates table collection, so +// The \code{rtsk_treeseq_copy_tables} allocates table collection, so // we can't work with \code{TSK_NO_INIT} // \url{https://tskit.dev/tskit/docs/stable/c-api.html#c.TSK_NO_INIT}. tsk_flags_t validate_copy_tables_options(const int options, @@ -72,17 +72,21 @@ tsk_flags_t validate_copy_tables_options(const int options, // @param caller function name // @details See // \url{https://tskit.dev/tskit/docs/stable/c-api.html#c.tsk_treeseq_init}. -// The \code{tc_xptr_to_ts_xptr} allocates tree sequence from table -// collection, so we can't use \code{TSK_TAKE_OWNERSHIP} as the table -// collection object still exists on R side +// \code{TSK_TAKE_OWNERSHIP} is unsupported because the input +// table collection remains reachable via R external pointer (risk of +// dangling alias / double-free), and because the ownership path of +// \code{tsk_treeseq_free()} is based on C +// \code{malloc()/free()}, while this wrapper manages that outer struct with +// C++ \code{new()/delete()}. // \url{https://tskit.dev/tskit/docs/stable/c-api.html#c.TSK_TAKE_OWNERSHIP}. tsk_flags_t validate_treeseq_init_options(const int options, const char *caller) { const tsk_flags_t init_options = static_cast(options); if (init_options & TSK_TAKE_OWNERSHIP) { Rcpp::stop( - "%s does not support TSK_TAKE_OWNERSHIP because ownership/lifecycle " - "is managed by R external pointers in this wrapper", + "%s does not support TSK_TAKE_OWNERSHIP because ownership " + "is managed by R external pointers and this wrapper manages table " + "collections with C++ new()/delete", caller); } const tsk_flags_t unsupported = init_options & ~kTreeseqInitSupportedOptions; @@ -148,9 +152,9 @@ Rcpp::IntegerVector tskit_version() { Rcpp::_["patch"] = TSK_VERSION_PATCH); } -// PUBLIC +// PUBLIC, wrapper for tsk_treeseq_load // @title Load a tree sequence from a file -// @param file a string specifying the full path of the tree sequence file. +// @param filename a string specifying the full path of the tree sequence file. // @param options \code{tskit} bitwise flags (see details and note that only // \code{TSK_LOAD_SKIP_TABLES} and \code{TSK_LOAD_SKIP_REFERENCE_SEQUENCE}, // but not \code{TSK_NO_INIT}, are supported by this wrapper). @@ -163,20 +167,20 @@ Rcpp::IntegerVector tskit_version() { // and presented to users. // @examples // ts_file <- system.file("examples/test.trees", package = "RcppTskit") -// ts_xptr <- RcppTskit:::ts_xptr_load(ts_file) +// ts_xptr <- RcppTskit:::rtsk_treeseq_load(ts_file) // is(ts_xptr) // ts_xptr -// RcppTskit:::ts_xptr_num_nodes(ts_xptr) -// ts <- TreeSequence$new(pointer = ts_xptr) +// RcppTskit:::rtsk_treeseq_get_num_nodes(ts_xptr) +// ts <- TreeSequence$new(xptr = ts_xptr) // is(ts) // [[Rcpp::export]] -SEXP ts_xptr_load(const std::string file, const int options = 0) { +SEXP rtsk_treeseq_load(const std::string filename, const int options = 0) { const tsk_flags_t load_options = - validate_load_options(options, "ts_xptr_load"); + validate_load_options(options, "rtsk_treeseq_load"); // tsk_treeseq_t ts; // on stack, destroyed end of func, must free resources tsk_treeseq_t *ts_ptr = new tsk_treeseq_t(); // on heap, persists function // See also https://tskit.dev/tskit/docs/stable/c-api.html#api-structure - int ret = tsk_treeseq_load(ts_ptr, file.c_str(), load_options); + int ret = tsk_treeseq_load(ts_ptr, filename.c_str(), load_options); if (ret != 0) { tsk_treeseq_free(ts_ptr); delete ts_ptr; @@ -184,13 +188,13 @@ SEXP ts_xptr_load(const std::string file, const int options = 0) { } // Wrap standard/raw ts_ptr for R as an external pointer handle (xptr) // "true" below means that R will call finaliser on garbage collection - RcppTskit_treeseq_xptr ts_xptr(ts_ptr, true); + rtsk_treeseq_t ts_xptr(ts_ptr, true); return ts_xptr; } -// PUBLIC +// PUBLIC, wrapper for tsk_table_collection_load // @title Load a table collection from a file -// @param file a string specifying the full path of the tree sequence file. +// @param filename a string specifying the full path of the tree sequence file. // @param options \code{tskit} bitwise flags (see details and note that only // \code{TSK_LOAD_SKIP_TABLES} and \code{TSK_LOAD_SKIP_REFERENCE_SEQUENCE}, // but not \code{TSK_NO_INIT}, are supported by this wrapper). @@ -203,18 +207,19 @@ SEXP ts_xptr_load(const std::string file, const int options = 0) { // used and presented to users. // @examples // ts_file <- system.file("examples/test.trees", package = "RcppTskit") -// tc_xptr <- RcppTskit:::tc_xptr_load(ts_file) +// tc_xptr <- RcppTskit:::rtsk_table_collection_load(ts_file) // is(tc_xptr) // tc_xptr -// RcppTskit:::tc_xptr_print(tc_xptr) -// tc <- TableCollection$new(pointer = tc_xptr) +// RcppTskit:::rtsk_table_collection_print(tc_xptr) +// tc <- TableCollection$new(xptr = tc_xptr) // is(tc) // [[Rcpp::export]] -SEXP tc_xptr_load(const std::string file, const int options = 0) { +SEXP rtsk_table_collection_load(const std::string filename, + const int options = 0) { const tsk_flags_t load_options = - validate_load_options(options, "tc_xptr_load"); + validate_load_options(options, "rtsk_table_collection_load"); tsk_table_collection_t *tc_ptr = new tsk_table_collection_t(); - int ret = tsk_table_collection_load(tc_ptr, file.c_str(), load_options); + int ret = tsk_table_collection_load(tc_ptr, filename.c_str(), load_options); if (ret != 0) { tsk_table_collection_free(tc_ptr); delete tc_ptr; @@ -222,15 +227,15 @@ SEXP tc_xptr_load(const std::string file, const int options = 0) { } // Wrap standard/raw tc_ptr for R as an external pointer handle (xptr) // "true" below means that R will call finaliser on garbage collection - RcppTskit_table_collection_xptr tc_xptr(tc_ptr, true); + rtsk_table_collection_t tc_xptr(tc_ptr, true); return tc_xptr; } -// PUBLIC +// PUBLIC, wrapper for tsk_treeseq_dump // @title Write a tree sequence to a file // @param ts an external pointer to tree sequence as a \code{tsk_treeseq_t} // object. -// @param file a string specifying the full path of the tree sequence file. +// @param filename a string specifying the full path of the tree sequence file. // @param options \code{tskit} bitwise flags (see details and note that // these options are currently unused in \code{tskit} and should be \code{0}). // @details This function calls @@ -238,27 +243,27 @@ SEXP tc_xptr_load(const std::string file, const int options = 0) { // @return No return value; called for side effects. // @examples // ts_file <- system.file("examples/test.trees", package = "RcppTskit") -// ts_xptr <- RcppTskit:::ts_xptr_load(ts_file) +// ts_xptr <- RcppTskit:::rtsk_treeseq_load(ts_file) // dump_file <- tempfile() -// RcppTskit:::ts_xptr_dump(ts_xptr, dump_file) +// RcppTskit:::rtsk_treeseq_dump(ts_xptr, dump_file) // file.remove(dump_file) // [[Rcpp::export]] -void ts_xptr_dump(const SEXP ts, const std::string file, - const int options = 0) { +void rtsk_treeseq_dump(const SEXP ts, const std::string filename, + const int options = 0) { const tsk_flags_t dump_options = - validate_dump_options(options, "ts_xptr_dump"); - RcppTskit_treeseq_xptr ts_xptr(ts); - int ret = tsk_treeseq_dump(ts_xptr, file.c_str(), dump_options); + validate_dump_options(options, "rtsk_treeseq_dump"); + rtsk_treeseq_t ts_xptr(ts); + int ret = tsk_treeseq_dump(ts_xptr, filename.c_str(), dump_options); if (ret != 0) { Rcpp::stop(tsk_strerror(ret)); } } -// PUBLIC +// PUBLIC, wrapper for tsk_table_collection_dump // @title Write a table collection to a file // @param tc an external pointer to table collection as a // \code{tsk_table_collection_t} object. -// @param file a string specifying the full path of the tree sequence file. +// @param filename a string specifying the full path of the tree sequence file. // @param options \code{tskit} bitwise flags (see details and note that // these options are currently unused in \code{tskit} and should be \code{0}). // @details This function calls @@ -266,23 +271,23 @@ void ts_xptr_dump(const SEXP ts, const std::string file, // @return No return value; called for side effects. // @examples // ts_file <- system.file("examples/test.trees", package = "RcppTskit") -// tc_xptr <- RcppTskit:::tc_xptr_load(ts_file) +// tc_xptr <- RcppTskit:::rtsk_table_collection_load(ts_file) // dump_file <- tempfile() -// RcppTskit:::tc_xptr_dump(tc_xptr, dump_file) +// RcppTskit:::rtsk_table_collection_dump(tc_xptr, dump_file) // file.remove(dump_file) // [[Rcpp::export]] -void tc_xptr_dump(const SEXP tc, const std::string file, - const int options = 0) { +void rtsk_table_collection_dump(const SEXP tc, const std::string filename, + const int options = 0) { const tsk_flags_t dump_options = - validate_dump_options(options, "tc_xptr_dump"); - RcppTskit_table_collection_xptr tc_xptr(tc); - int ret = tsk_table_collection_dump(tc_xptr, file.c_str(), dump_options); + validate_dump_options(options, "rtsk_table_collection_dump"); + rtsk_table_collection_t tc_xptr(tc); + int ret = tsk_table_collection_dump(tc_xptr, filename.c_str(), dump_options); if (ret != 0) { Rcpp::stop(tsk_strerror(ret)); } } -// PUBLIC +// PUBLIC, wrapper for tsk_treeseq_copy_tables // @title Copy a tree sequence's tables into a table collection // @param ts an external pointer to tree sequence as a \code{tsk_treeseq_t} // object. @@ -291,7 +296,7 @@ void tc_xptr_dump(const SEXP tc, const std::string file, // \code{TSK_COPY_FILE_UUID}). // @details This function calls // \url{https://tskit.dev/tskit/docs/stable/c-api.html#c.tsk_treeseq_copy_tables}. -// See also low-level Python-C call of \code{TreeSequence_dump_tables} in +// See also low-level Python-C call of \code{TreeSequence_dump_tables} at // \url{https://github.com/tskit-dev/tskit/blob/dc394d72d121c99c6dcad88f7a4873880924dd72/python/_tskitmodule.c#L5323} // @return An external pointer to table collection as a // \code{tsk_table_collection_t} object @@ -300,16 +305,16 @@ void tc_xptr_dump(const SEXP tc, const std::string file, // is used and presented to users. // @examples // ts_file <- system.file("examples/test.trees", package = "RcppTskit") -// ts_xptr <- RcppTskit:::ts_xptr_load(ts_file) -// tc_xptr <- RcppTskit:::ts_xptr_to_tc_xptr(ts_xptr) +// ts_xptr <- RcppTskit:::rtsk_treeseq_load(ts_file) +// tc_xptr <- RcppTskit:::rtsk_treeseq_copy_tables(ts_xptr) // is(tc_xptr) // tc_xptr -// RcppTskit:::tc_xptr_print(tc_xptr) +// RcppTskit:::rtsk_table_collection_print(tc_xptr) // [[Rcpp::export]] -SEXP ts_xptr_to_tc_xptr(const SEXP ts, const int options = 0) { +SEXP rtsk_treeseq_copy_tables(const SEXP ts, const int options = 0) { const tsk_flags_t copy_options = - validate_copy_tables_options(options, "ts_xptr_to_tc_xptr"); - RcppTskit_treeseq_xptr ts_xptr(ts); + validate_copy_tables_options(options, "rtsk_treeseq_copy_tables"); + rtsk_treeseq_t ts_xptr(ts); tsk_table_collection_t *tc_ptr = new tsk_table_collection_t(); int ret = tsk_treeseq_copy_tables(ts_xptr, tc_ptr, copy_options); if (ret != 0) { @@ -319,11 +324,11 @@ SEXP ts_xptr_to_tc_xptr(const SEXP ts, const int options = 0) { } // Wrap standard/raw tc_ptr for R as an external pointer handle (xptr) // "true" below means that R will call finaliser on garbage collection - RcppTskit_table_collection_xptr tc_xptr(tc_ptr, true); + rtsk_table_collection_t tc_xptr(tc_ptr, true); return tc_xptr; } -// PUBLIC +// PUBLIC, wrapper for tsk_treeseq_init // @title Initialise a tree sequence from a table collection // @param tc an external pointer to table collection as a // \code{tsk_table_collection_t} object. @@ -332,9 +337,15 @@ SEXP ts_xptr_to_tc_xptr(const SEXP ts, const int options = 0) { // \code{TSK_TS_INIT_BUILD_INDEXES} and // \code{TSK_TS_INIT_COMPUTE_MUTATION_PARENTS}, but not // \code{TSK_TAKE_OWNERSHIP}). +// \code{TSK_TAKE_OWNERSHIP} is unsupported because the input +// table collection remains reachable via R external pointer (risk of +// dangling alias / double-free), and because the ownership path of +// \code{tsk_treeseq_free()} is based on C +// \code{malloc()/free()}, while this wrapper manages that outer struct with +// C++ \code{new()/delete()}. // @details This function calls // \url{https://tskit.dev/tskit/docs/stable/c-api.html#c.tsk_treeseq_init}. -// See also low-level Python-C call of \code{TreeSequence_load_tables} in +// See also low-level Python-C call of \code{TreeSequence_load_tables} at // \url{https://github.com/tskit-dev/tskit/blob/dc394d72d121c99c6dcad88f7a4873880924dd72/python/_tskitmodule.c#L5292} // @return An external pointer to tree sequence as a \code{tsk_treeseq_t} // object @@ -343,15 +354,15 @@ SEXP ts_xptr_to_tc_xptr(const SEXP ts, const int options = 0) { // function is used and presented to users. // @examples // ts_file <- system.file("examples/test.trees", package = "RcppTskit") -// tc_xptr <- RcppTskit:::tc_xptr_load(ts_file) -// RcppTskit:::tc_xptr_print(tc_xptr) -// ts_xptr <- RcppTskit:::tc_xptr_to_ts_xptr(tc_xptr) -// RcppTskit:::ts_xptr_print(ts_xptr) +// tc_xptr <- RcppTskit:::rtsk_table_collection_load(ts_file) +// RcppTskit:::rtsk_table_collection_print(tc_xptr) +// ts_xptr <- RcppTskit:::rtsk_treeseq_init(tc_xptr) +// RcppTskit:::rtsk_treeseq_print(ts_xptr) // [[Rcpp::export]] -SEXP tc_xptr_to_ts_xptr(const SEXP tc, const int options = 0) { +SEXP rtsk_treeseq_init(const SEXP tc, const int options = 0) { const tsk_flags_t init_options = - validate_treeseq_init_options(options, "tc_xptr_to_ts_xptr"); - RcppTskit_table_collection_xptr tc_xptr(tc); + validate_treeseq_init_options(options, "rtsk_treeseq_init"); + rtsk_table_collection_t tc_xptr(tc); tsk_treeseq_t *ts_ptr = new tsk_treeseq_t(); int ret = tsk_treeseq_init(ts_ptr, tc_xptr, init_options); if (ret != 0) { @@ -361,7 +372,7 @@ SEXP tc_xptr_to_ts_xptr(const SEXP tc, const int options = 0) { } // Wrap standard/raw ts_ptr for R as an external pointer handle (xptr) // "true" below means that R will call finaliser on garbage collection - RcppTskit_treeseq_xptr ts_xptr(ts_ptr, true); + rtsk_treeseq_t ts_xptr(ts_ptr, true); return ts_xptr; } @@ -397,120 +408,129 @@ SEXP tc_xptr_to_ts_xptr(const SEXP tc, const int options = 0) { // is a scalar property (which we have strived to implement / mirror here), // but this one requires table-column arrays, which we will look into in #49 -// PUBLIC -// @describeIn ts_xptr_summary Get the number of provenances in a tree sequence +// PUBLIC, wrapper for tsk_treeseq_get_num_provenances +// @describeIn rtsk_treeseq_summary Get the number of provenances in a tree +// sequence // [[Rcpp::export]] -int ts_xptr_num_provenances(const SEXP ts) { - RcppTskit_treeseq_xptr ts_xptr(ts); +int rtsk_treeseq_get_num_provenances(const SEXP ts) { + rtsk_treeseq_t ts_xptr(ts); return static_cast(tsk_treeseq_get_num_provenances(ts_xptr)); } -// PUBLIC -// @describeIn ts_xptr_summary Get the number of populations in a tree sequence +// PUBLIC, wrapper for tsk_treeseq_get_num_populations +// @describeIn rtsk_treeseq_summary Get the number of populations in a tree +// sequence // [[Rcpp::export]] -int ts_xptr_num_populations(const SEXP ts) { - RcppTskit_treeseq_xptr ts_xptr(ts); +int rtsk_treeseq_get_num_populations(const SEXP ts) { + rtsk_treeseq_t ts_xptr(ts); return static_cast(tsk_treeseq_get_num_populations(ts_xptr)); } -// PUBLIC -// @describeIn ts_xptr_summary Get the number of migrations in a tree sequence +// PUBLIC, wrapper for tsk_treeseq_get_num_migrations +// @describeIn rtsk_treeseq_summary Get the number of migrations in a tree +// sequence // [[Rcpp::export]] -int ts_xptr_num_migrations(const SEXP ts) { - RcppTskit_treeseq_xptr ts_xptr(ts); +int rtsk_treeseq_get_num_migrations(const SEXP ts) { + rtsk_treeseq_t ts_xptr(ts); return static_cast(tsk_treeseq_get_num_migrations(ts_xptr)); } -// PUBLIC -// @describeIn ts_xptr_summary Get the number of individuals in a tree sequence +// PUBLIC, wrapper for tsk_treeseq_get_num_individuals +// @describeIn rtsk_treeseq_summary Get the number of individuals in a tree +// sequence // [[Rcpp::export]] -int ts_xptr_num_individuals(const SEXP ts) { - RcppTskit_treeseq_xptr ts_xptr(ts); +int rtsk_treeseq_get_num_individuals(const SEXP ts) { + rtsk_treeseq_t ts_xptr(ts); return static_cast(tsk_treeseq_get_num_individuals(ts_xptr)); } -// PUBLIC -// @describeIn ts_xptr_summary Get the number of samples (of nodes) in a tree +// PUBLIC, wrapper for tsk_treeseq_get_num_samples +// @describeIn rtsk_treeseq_summary Get the number of samples (of nodes) in a +// tree // sequence // [[Rcpp::export]] -int ts_xptr_num_samples(const SEXP ts) { - RcppTskit_treeseq_xptr ts_xptr(ts); +int rtsk_treeseq_get_num_samples(const SEXP ts) { + rtsk_treeseq_t ts_xptr(ts); return static_cast(tsk_treeseq_get_num_samples(ts_xptr)); } -// PUBLIC -// @describeIn ts_xptr_summary Get the number of nodes in a tree sequence +// PUBLIC, wrapper for tsk_treeseq_get_num_nodes +// @describeIn rtsk_treeseq_summary Get the number of nodes in a tree sequence // [[Rcpp::export]] -int ts_xptr_num_nodes(const SEXP ts) { - RcppTskit_treeseq_xptr ts_xptr(ts); +int rtsk_treeseq_get_num_nodes(const SEXP ts) { + rtsk_treeseq_t ts_xptr(ts); return static_cast(tsk_treeseq_get_num_nodes(ts_xptr)); } -// PUBLIC -// @describeIn ts_xptr_summary Get the number of edges in a tree sequence +// PUBLIC, wrapper for tsk_treeseq_get_num_edges +// @describeIn rtsk_treeseq_summary Get the number of edges in a tree sequence // [[Rcpp::export]] -int ts_xptr_num_edges(const SEXP ts) { - RcppTskit_treeseq_xptr ts_xptr(ts); +int rtsk_treeseq_get_num_edges(const SEXP ts) { + rtsk_treeseq_t ts_xptr(ts); return static_cast(tsk_treeseq_get_num_edges(ts_xptr)); } -// PUBLIC -// @describeIn ts_xptr_summary Get the number of trees in a tree sequence +// PUBLIC, wrapper for tsk_treeseq_get_num_trees +// @describeIn rtsk_treeseq_summary Get the number of trees in a tree sequence // [[Rcpp::export]] -int ts_xptr_num_trees(const SEXP ts) { - RcppTskit_treeseq_xptr ts_xptr(ts); +int rtsk_treeseq_get_num_trees(const SEXP ts) { + rtsk_treeseq_t ts_xptr(ts); return static_cast(tsk_treeseq_get_num_trees(ts_xptr)); } -// PUBLIC -// @describeIn ts_xptr_summary Get the number of sites in a tree sequence +// PUBLIC, wrapper for tsk_treeseq_get_num_sites +// @describeIn rtsk_treeseq_summary Get the number of sites in a tree sequence // [[Rcpp::export]] -int ts_xptr_num_sites(const SEXP ts) { - RcppTskit_treeseq_xptr ts_xptr(ts); +int rtsk_treeseq_get_num_sites(const SEXP ts) { + rtsk_treeseq_t ts_xptr(ts); return static_cast(tsk_treeseq_get_num_sites(ts_xptr)); } -// PUBLIC -// @describeIn ts_xptr_summary Get the number of mutations in a tree sequence +// PUBLIC, wrapper for tsk_treeseq_get_num_mutations +// @describeIn rtsk_treeseq_summary Get the number of mutations in a tree +// sequence // [[Rcpp::export]] -int ts_xptr_num_mutations(const SEXP ts) { - RcppTskit_treeseq_xptr ts_xptr(ts); +int rtsk_treeseq_get_num_mutations(const SEXP ts) { + rtsk_treeseq_t ts_xptr(ts); return static_cast(tsk_treeseq_get_num_mutations(ts_xptr)); } -// PUBLIC -// @describeIn ts_xptr_summary Get the sequence length +// PUBLIC, wrapper for tsk_treeseq_get_sequence_length +// @describeIn rtsk_treeseq_summary Get the sequence length // [[Rcpp::export]] -double ts_xptr_sequence_length(const SEXP ts) { - RcppTskit_treeseq_xptr ts_xptr(ts); +double rtsk_treeseq_get_sequence_length(const SEXP ts) { + rtsk_treeseq_t ts_xptr(ts); return tsk_treeseq_get_sequence_length(ts_xptr); } -// PUBLIC -// @describeIn ts_xptr_summary Get the discrete genome status +// PUBLIC, wrapper for tsk_treeseq_get_discrete_genome +// @describeIn rtsk_treeseq_summary Get the discrete genome status // [[Rcpp::export]] -bool ts_xptr_discrete_genome(const SEXP ts) { - RcppTskit_treeseq_xptr ts_xptr(ts); +bool rtsk_treeseq_get_discrete_genome(const SEXP ts) { + rtsk_treeseq_t ts_xptr(ts); return tsk_treeseq_get_discrete_genome(ts_xptr); } -// PUBLIC -// @describeIn ts_xptr_summary Does the tree sequence hold a reference genome +// PUBLIC, wrapper for tsk_treeseq_has_reference_sequence +// @describeIn rtsk_treeseq_summary Does the tree sequence hold a reference +// genome // sequence -// @details Note that tsk_treeseq_has_reference_sequence is undocumented -// method in the tskit C API (see trees.h), but documented in tskit Python API +// @details Note that \code{tsk_treeseq_has_reference_sequence} is undocumented +// method in the \code{tskit C} API (see \code{trees.h}), but documented in +// \code{tskit Python} API // https://tskit.dev/tskit/docs/stable/python-api.html#tskit.TreeSequence.has_reference_sequence // [[Rcpp::export]] -bool ts_xptr_has_reference_sequence(const SEXP ts) { - RcppTskit_treeseq_xptr ts_xptr(ts); +bool rtsk_treeseq_has_reference_sequence(const SEXP ts) { + rtsk_treeseq_t ts_xptr(ts); return tsk_treeseq_has_reference_sequence(ts_xptr); } -// PUBLIC -// @describeIn ts_xptr_summary Get the time units string +// PUBLIC, wrapper for tsk_treeseq_get_time_units and +// tsk_treeseq_get_time_units_length. +// @describeIn rtsk_treeseq_summary Get the time units string // [[Rcpp::export]] -Rcpp::String ts_xptr_time_units(const SEXP ts) { - RcppTskit_treeseq_xptr ts_xptr(ts); +Rcpp::String rtsk_treeseq_get_time_units(const SEXP ts) { + rtsk_treeseq_t ts_xptr(ts); const char *p = tsk_treeseq_get_time_units(ts_xptr); tsk_size_t n = tsk_treeseq_get_time_units_length(ts_xptr); std::string time_units; @@ -520,35 +540,37 @@ Rcpp::String ts_xptr_time_units(const SEXP ts) { return Rcpp::String(time_units); } -// PUBLIC -// @describeIn ts_xptr_summary Get the discrete time status +// PUBLIC, wrapper for tsk_treeseq_get_discrete_time +// @describeIn rtsk_treeseq_summary Get the discrete time status // [[Rcpp::export]] -bool ts_xptr_discrete_time(const SEXP ts) { - RcppTskit_treeseq_xptr ts_xptr(ts); +bool rtsk_treeseq_get_discrete_time(const SEXP ts) { + rtsk_treeseq_t ts_xptr(ts); return tsk_treeseq_get_discrete_time(ts_xptr); } -// PUBLIC -// @describeIn ts_xptr_summary Get the min time in node table and mutation table +// PUBLIC, wrapper for tsk_treeseq_get_min_time +// @describeIn rtsk_treeseq_summary Get the min time in node table and mutation +// table // [[Rcpp::export]] -double ts_xptr_min_time(const SEXP ts) { - RcppTskit_treeseq_xptr ts_xptr(ts); +double rtsk_treeseq_get_min_time(const SEXP ts) { + rtsk_treeseq_t ts_xptr(ts); return tsk_treeseq_get_min_time(ts_xptr); } -// PUBLIC -// @describeIn ts_xptr_summary Get the max time in node table and mutation table +// PUBLIC, wrapper for tsk_treeseq_get_max_time +// @describeIn rtsk_treeseq_summary Get the max time in node table and mutation +// table // [[Rcpp::export]] -double ts_xptr_max_time(const SEXP ts) { - RcppTskit_treeseq_xptr ts_xptr(ts); +double rtsk_treeseq_get_max_time(const SEXP ts) { + rtsk_treeseq_t ts_xptr(ts); return tsk_treeseq_get_max_time(ts_xptr); } -// PUBLIC -// @describeIn ts_xptr_summary Get the file uuid string +// PUBLIC, wrapper for tsk_treeseq_get_file_uuid +// @describeIn rtsk_treeseq_summary Get the file uuid string // [[Rcpp::export]] -Rcpp::String ts_xptr_file_uuid(const SEXP ts) { - RcppTskit_treeseq_xptr ts_xptr(ts); +Rcpp::String rtsk_treeseq_get_file_uuid(const SEXP ts) { + rtsk_treeseq_t ts_xptr(ts); const char *p = tsk_treeseq_get_file_uuid(ts_xptr); if (p == NULL || p[0] == '\0') { return Rcpp::String(NA_STRING); @@ -556,8 +578,8 @@ Rcpp::String ts_xptr_file_uuid(const SEXP ts) { return Rcpp::String(p); } -// PUBLIC -// @name ts_xptr_summary +// PUBLIC, RcppTskit extension +// @name rtsk_treeseq_summary // @title Summary of properties and number of records in a tree sequence // @param ts an external pointer to tree sequence as a \code{tsk_treeseq_t} // object. @@ -582,33 +604,35 @@ Rcpp::String ts_xptr_file_uuid(const SEXP ts) { // \url{https://tskit.dev/tskit/docs/stable/c-api.html#c.tsk_treeseq_get_max_time}, // and // \url{https://tskit.dev/tskit/docs/stable/c-api.html#c.tsk_treeseq_get_file_uuid}, -// @return \code{ts_xptr_summary} returns a named list with numbers and values, -// while functions \code{ts_xptr_*} return the number or value for each item. +// @return \code{rtsk_treeseq_summary} returns a named list with numbers and +// values, while functions \code{rtsk_treeseq_*} return the number or value +// for each item. // @examples // ts_file <- system.file("examples/test.trees", package = "RcppTskit") -// ts_xptr <- RcppTskit:::ts_xptr_load(ts_file) -// RcppTskit:::ts_xptr_summary(ts_xptr) -// RcppTskit:::ts_xptr_num_provenances(ts_xptr) -// RcppTskit:::ts_xptr_num_populations(ts_xptr) -// RcppTskit:::ts_xptr_num_migrations(ts_xptr) -// RcppTskit:::ts_xptr_num_individuals(ts_xptr) -// RcppTskit:::ts_xptr_num_samples(ts_xptr) -// RcppTskit:::ts_xptr_num_nodes(ts_xptr) -// RcppTskit:::ts_xptr_num_edges(ts_xptr) -// RcppTskit:::ts_xptr_num_trees(ts_xptr) -// RcppTskit:::ts_xptr_num_sites(ts_xptr) -// RcppTskit:::ts_xptr_num_mutations(ts_xptr) -// RcppTskit:::ts_xptr_sequence_length(ts_xptr) -// RcppTskit:::ts_xptr_discrete_genome(ts_xptr) -// RcppTskit:::ts_xptr_has_reference_sequence(ts_xptr) -// RcppTskit:::ts_xptr_time_units(ts_xptr) -// RcppTskit:::ts_xptr_discrete_time(ts_xptr) -// RcppTskit:::ts_xptr_min_time(ts_xptr) -// RcppTskit:::ts_xptr_max_time(ts_xptr) -// RcppTskit:::ts_xptr_file_uuid(ts_xptr) -// [[Rcpp::export]] -Rcpp::List ts_xptr_summary(const SEXP ts) { - RcppTskit_treeseq_xptr ts_xptr(ts); +// ts_xptr <- RcppTskit:::rtsk_treeseq_load(ts_file) +// RcppTskit:::rtsk_treeseq_summary(ts_xptr) +// RcppTskit:::rtsk_treeseq_get_num_provenances(ts_xptr) +// RcppTskit:::rtsk_treeseq_get_num_populations(ts_xptr) +// RcppTskit:::rtsk_treeseq_get_num_migrations(ts_xptr) +// RcppTskit:::rtsk_treeseq_get_num_individuals(ts_xptr) +// RcppTskit:::rtsk_treeseq_get_num_samples(ts_xptr) +// RcppTskit:::rtsk_treeseq_get_num_nodes(ts_xptr) +// RcppTskit:::rtsk_treeseq_get_num_edges(ts_xptr) +// RcppTskit:::rtsk_treeseq_get_num_trees(ts_xptr) +// RcppTskit:::rtsk_treeseq_get_num_sites(ts_xptr) +// RcppTskit:::rtsk_treeseq_get_num_mutations(ts_xptr) +// RcppTskit:::rtsk_treeseq_get_sequence_length(ts_xptr) +// RcppTskit:::rtsk_treeseq_get_discrete_genome(ts_xptr) +// RcppTskit:::rtsk_treeseq_has_reference_sequence(ts_xptr) +// RcppTskit:::rtsk_treeseq_get_time_units(ts_xptr) +// RcppTskit:::rtsk_treeseq_get_discrete_time(ts_xptr) +// RcppTskit:::rtsk_treeseq_get_min_time(ts_xptr) +// RcppTskit:::rtsk_treeseq_get_max_time(ts_xptr) +// RcppTskit:::rtsk_treeseq_get_file_uuid(ts_xptr) +// EXTENSION: composite summary helper (no single tsk_* equivalent). +// [[Rcpp::export]] +Rcpp::List rtsk_treeseq_summary(const SEXP ts) { + rtsk_treeseq_t ts_xptr(ts); return Rcpp::List::create( Rcpp::_["num_provenances"] = tsk_treeseq_get_num_provenances(ts_xptr), Rcpp::_["num_populations"] = tsk_treeseq_get_num_populations(ts_xptr), @@ -624,14 +648,14 @@ Rcpp::List ts_xptr_summary(const SEXP ts) { Rcpp::_["discrete_genome"] = tsk_treeseq_get_discrete_genome(ts_xptr), Rcpp::_["has_reference_sequence"] = tsk_treeseq_has_reference_sequence(ts_xptr), - Rcpp::_["time_units"] = ts_xptr_time_units(ts), + Rcpp::_["time_units"] = rtsk_treeseq_get_time_units(ts), Rcpp::_["discrete_time"] = tsk_treeseq_get_discrete_time(ts_xptr), - Rcpp::_["min_time"] = ts_xptr_min_time(ts), - Rcpp::_["max_time"] = ts_xptr_max_time(ts), - Rcpp::_["file_uuid"] = ts_xptr_file_uuid(ts)); + Rcpp::_["min_time"] = rtsk_treeseq_get_min_time(ts), + Rcpp::_["max_time"] = rtsk_treeseq_get_max_time(ts), + Rcpp::_["file_uuid"] = rtsk_treeseq_get_file_uuid(ts)); } -// PUBLIC +// PUBLIC, RcppTskit extension // @title Get the length of metadata in a tree sequence and its tables // @param ts tree sequence as a \code{\link{TreeSequence}} object or // an external pointer to tree sequence as a \code{tsk_treeseq_t} object. @@ -643,11 +667,11 @@ Rcpp::List ts_xptr_summary(const SEXP ts) { // @return A named list with the length of metadata. // @examples // ts_file <- system.file("examples/test.trees", package = "RcppTskit") -// ts_xptr <- RcppTskit:::ts_xptr_load(ts_file) -// RcppTskit:::ts_xptr_metadata_length(ts_xptr) +// ts_xptr <- RcppTskit:::rtsk_treeseq_load(ts_file) +// RcppTskit:::rtsk_treeseq_metadata_length(ts_xptr) // [[Rcpp::export]] -Rcpp::List ts_xptr_metadata_length(const SEXP ts) { - RcppTskit_treeseq_xptr ts_xptr(ts); +Rcpp::List rtsk_treeseq_metadata_length(const SEXP ts) { + rtsk_treeseq_t ts_xptr(ts); const tsk_table_collection_t *tables = ts_xptr->tables; return Rcpp::List::create( // The tree sequence metadata is the tables collection metadata and @@ -676,11 +700,11 @@ Rcpp::List ts_xptr_metadata_length(const SEXP ts) { // This is how we would get metadata, but it will be raw bytes, // so would have to work with schema and codes ... // ts_file <- system.file("examples/test.trees", package = "RcppTskit") -// ts_xptr <- RcppTskit:::ts_xptr_load(ts_file) -// RcppTskit:::ts_xptr_metadata(ts_xptr) +// ts_xptr <- RcppTskit:::rtsk_treeseq_load(ts_file) +// RcppTskit:::rtsk_treeseq_get_metadata(ts_xptr) // slendr::ts_metadata(slim_ts) -Rcpp::String ts_xptr_metadata(const SEXP ts) { - RcppTskit_treeseq_xptr ts_xptr(ts); +Rcpp::String rtsk_treeseq_get_metadata(const SEXP ts) { + rtsk_treeseq_t ts_xptr(ts); const char *p = tsk_treeseq_get_metadata(ts_xptr); tsk_size_t n = tsk_treeseq_get_metadata_length(ts_xptr); std::string metadata; @@ -693,8 +717,8 @@ Rcpp::String ts_xptr_metadata(const SEXP ts) { // TODO: Metadata notes if we do anything with metadata #36 // https://github.com/HighlanderLab/RcppTskit/issues/36 -// int ts_xptr_metadata_schema_length(const SEXP ts) { -// RcppTskit_treeseq_xptr ts_xptr(ts); +// int rtsk_treeseq_metadata_schema_length(const SEXP ts) { +// rtsk_treeseq_t ts_xptr(ts); // return static_cast(tsk_treeseq_get_metadata_schema_length(ts_xptr)); // } // TODO: test the above function @@ -714,11 +738,12 @@ Rcpp::String ts_xptr_metadata(const SEXP ts) { // * tsk_size_t time_units_length; IMPLEMENTED HERE (as part of the above) // TODO: Metadata notes if we do anything with metadata #36 // https://github.com/HighlanderLab/RcppTskit/issues/36 -// * char *metadata; "SCALAR", TODO --> tc_xptr_metadata +// * char *metadata; "SCALAR", TODO --> rtsk_table_collection_metadata // * tsk_size_t metadata_length; SCALAR, TODO as part of the above // TODO: Metadata notes if we do anything with metadata #36 // https://github.com/HighlanderLab/RcppTskit/issues/36 -// * char *metadata_schema; "SCALAR", TODO --> tc_xptr_metadata_schema +// * char *metadata_schema; "SCALAR", TODO --> +// rtsk_table_collection_metadata_schema // * tsk_size_t metadata_schema_length; SCALAR, TODO as part of the above // * tsk_reference_sequence_t reference_sequence; TODO? // * tsk_individual_table_t individuals; TABLE, SKIP OR TODO LATER #49 @@ -739,32 +764,32 @@ Rcpp::String ts_xptr_metadata(const SEXP ts) { // https://tskit.dev/tskit/docs/stable/python-api.html#sec-tables-api-table-collection // https://tskit.dev/tskit/docs/stable/python-api.html#tskit.TableCollection -// PUBLIC -// @describeIn tc_xptr_summary Get the sequence length +// PUBLIC, RcppTskit extension +// @describeIn rtsk_table_collection_summary Get the sequence length // [[Rcpp::export]] -double tc_xptr_sequence_length(const SEXP tc) { - RcppTskit_table_collection_xptr tc_xptr(tc); +double rtsk_table_collection_get_sequence_length(const SEXP tc) { + rtsk_table_collection_t tc_xptr(tc); return tc_xptr->sequence_length; } -// PUBLIC -// @describeIn tc_xptr_summary Does the table collection hold a reference genome -// sequence +// PUBLIC, wrapper for tsk_table_collection_has_reference_sequence +// @describeIn rtsk_table_collection_summary Does the table collection hold a +// reference genome sequence // @details Note that tsk_table_collection_has_reference_sequence is // undocumented method in the tskit C API (see tables.h), // but documented in tskit Python API // https://tskit.dev/tskit/docs/stable/python-api.html#tskit.TableCollection.has_reference_sequence // [[Rcpp::export]] -bool tc_xptr_has_reference_sequence(const SEXP tc) { - RcppTskit_table_collection_xptr tc_xptr(tc); +bool rtsk_table_collection_has_reference_sequence(const SEXP tc) { + rtsk_table_collection_t tc_xptr(tc); return tsk_table_collection_has_reference_sequence(tc_xptr); } -// PUBLIC -// @describeIn tc_xptr_summary Get the time units string +// PUBLIC, RcppTskit extension +// @describeIn rtsk_table_collection_summary Get the time units string // [[Rcpp::export]] -Rcpp::String tc_xptr_time_units(const SEXP tc) { - RcppTskit_table_collection_xptr tc_xptr(tc); +Rcpp::String rtsk_table_collection_get_time_units(const SEXP tc) { + rtsk_table_collection_t tc_xptr(tc); const char *p = tc_xptr->time_units; tsk_size_t n = tc_xptr->time_units_length; std::string time_units; @@ -774,46 +799,110 @@ Rcpp::String tc_xptr_time_units(const SEXP tc) { return Rcpp::String(time_units); } -// PUBLIC -// @describeIn tc_xptr_summary Get the file uuid string +// PUBLIC, RcppTskit extension +// @describeIn rtsk_table_collection_summary Get the file uuid string // [[Rcpp::export]] -Rcpp::String tc_xptr_file_uuid(const SEXP tc) { - RcppTskit_table_collection_xptr tc_xptr(tc); +Rcpp::String rtsk_table_collection_get_file_uuid(const SEXP tc) { + rtsk_table_collection_t tc_xptr(tc); if (tc_xptr->file_uuid == NULL || tc_xptr->file_uuid[0] == '\0') { return Rcpp::String(NA_STRING); } return Rcpp::String(tc_xptr->file_uuid); } -// PUBLIC -// @describeIn tc_xptr_summary Is the table collection indexed +// PUBLIC, wrapper for tsk_table_collection_has_index +// @describeIn rtsk_table_collection_summary Is the table collection indexed // [[Rcpp::export]] -bool tc_xptr_has_index(const SEXP tc) { - RcppTskit_table_collection_xptr tc_xptr(tc); - return tsk_table_collection_has_index(tc_xptr, 0); +bool rtsk_table_collection_has_index(const SEXP tc, const int options = 0) { + rtsk_table_collection_t tc_xptr(tc); + return tsk_table_collection_has_index(tc_xptr, options); } -// PUBLIC +// PUBLIC, wrapper for tsk_table_collection_build_index +// @title Build indexes for a table collection +// @param tc an external pointer to table collection as a +// \code{tsk_table_collection_t} object. +// @param options \code{tskit} bitwise flags, currently unused and should be set +// to 0 +// @details This function calls +// \url{https://tskit.dev/tskit/docs/stable/c-api.html#c.tsk_table_collection_build_index}. +// @return No return value; called for side effects. +// @examples +// ts_file <- system.file("examples/test.trees", package = "RcppTskit") +// tc_xptr <- RcppTskit:::rtsk_table_collection_load(ts_file) +// RcppTskit:::rtsk_table_collection_has_index(tc_xptr) +// RcppTskit:::rtsk_table_collection_drop_index(tc_xptr) +// RcppTskit:::rtsk_table_collection_has_index(tc_xptr) +// RcppTskit:::rtsk_table_collection_build_index(tc_xptr) +// RcppTskit:::rtsk_table_collection_has_index(tc_xptr) +// [[Rcpp::export]] +void rtsk_table_collection_build_index(const SEXP tc, const int options = 0) { + rtsk_table_collection_t tc_xptr(tc); + int ret = tsk_table_collection_build_index(tc_xptr, options); + if (ret != 0) { + Rcpp::stop(tsk_strerror(ret)); + } +} + +// PUBLIC, wrapper for tsk_table_collection_drop_index +// @title Drop indexes for a table collection +// @param tc an external pointer to table collection as a +// \code{tsk_table_collection_t} object. +// @param options \code{tskit} bitwise flags, currently unused and should be set +// to 0 +// @details This function calls +// \url{https://tskit.dev/tskit/docs/stable/c-api.html#c.tsk_table_collection_drop_index}. +// @return No return value; called for side effects. +// @examples +// ts_file <- system.file("examples/test.trees", package = "RcppTskit") +// tc_xptr <- RcppTskit:::rtsk_table_collection_load(ts_file) +// RcppTskit:::rtsk_table_collection_has_index(tc_xptr) +// RcppTskit:::rtsk_table_collection_drop_index(tc_xptr) +// RcppTskit:::rtsk_table_collection_has_index(tc_xptr) +// [[Rcpp::export]] +void rtsk_table_collection_drop_index(const SEXP tc, const int options = 0) { + rtsk_table_collection_t tc_xptr(tc); + int ret = tsk_table_collection_drop_index(tc_xptr, options); + // tsk_table_collection_drop_index() currently documents always returning 0; + // so we test for possible future failures, but we cannot unit-tested. + // # nocov start + if (ret != 0) { + Rcpp::stop(tsk_strerror(ret)); + } + // # nocov end +} + +// TODO: Do we have to add TableCollection$sort() method? #99 +// https://github.com/HighlanderLab/RcppTskit/issues/99 + +// TODO: Do we need any other method on table collection to produce a valid ts? +// #100 +// https://github.com/HighlanderLab/RcppTskit/issues/100 + +// PUBLIC, RcppTskit extension // @title Summary of properties and number of records in a table collection // @param tc an external pointer to table collection as a // \code{tsk_table_collection_t} object. +// @param options \code{tskit} bitwise flags, currently unused and should be set +// to 0 // @details These functions return the summary of properties and number of // records in a table collection, by accessing its elements and/or calling // \url{https://tskit.dev/tskit/docs/stable/c-api.html#c.tsk_table_collection_has_index} -// @return \code{tc_xptr_summary} returns a named list with numbers and values, -// while functions \code{tc_xptr_*} return the number or value for each item. +// @return \code{rtsk_table_collection_summary} returns a named list with +// numbers and values, while functions \code{rtsk_table_collection_*} return +// the number or value for each item. // @examples // ts_file <- system.file("examples/test.trees", package = "RcppTskit") -// tc_xptr <- RcppTskit:::tc_xptr_load(ts_file) -// RcppTskit:::tc_xptr_summary(tc_xptr) -// RcppTskit:::tc_xptr_sequence_length(tc_xptr) -// RcppTskit:::tc_xptr_has_reference_sequence(tc_xptr) -// RcppTskit:::tc_xptr_time_units(tc_xptr) -// RcppTskit:::tc_xptr_file_uuid(tc_xptr) -// RcppTskit:::tc_xptr_has_index(tc_xptr) -// [[Rcpp::export]] -Rcpp::List tc_xptr_summary(const SEXP tc) { - RcppTskit_table_collection_xptr tc_xptr(tc); +// tc_xptr <- RcppTskit:::rtsk_table_collection_load(ts_file) +// RcppTskit:::rtsk_table_collection_summary(tc_xptr) +// RcppTskit:::rtsk_table_collection_get_sequence_length(tc_xptr) +// RcppTskit:::rtsk_table_collection_has_reference_sequence(tc_xptr) +// RcppTskit:::rtsk_table_collection_get_time_units(tc_xptr) +// RcppTskit:::rtsk_table_collection_get_file_uuid(tc_xptr) +// RcppTskit:::rtsk_table_collection_has_index(tc_xptr) +// [[Rcpp::export]] +Rcpp::List rtsk_table_collection_summary(const SEXP tc) { + rtsk_table_collection_t tc_xptr(tc); const tsk_table_collection_t *tables = tc_xptr; return Rcpp::List::create( Rcpp::_["num_provenances"] = tables->provenances.num_rows, @@ -825,24 +914,27 @@ Rcpp::List tc_xptr_summary(const SEXP tc) { Rcpp::_["num_sites"] = tables->sites.num_rows, Rcpp::_["num_mutations"] = tables->mutations.num_rows, Rcpp::_["sequence_length"] = tables->sequence_length, - Rcpp::_["has_reference_sequence"] = tc_xptr_has_reference_sequence(tc), - Rcpp::_["time_units"] = tc_xptr_time_units(tc), - Rcpp::_["file_uuid"] = tc_xptr_file_uuid(tc), - Rcpp::_["has_index"] = tc_xptr_has_index(tc)); + Rcpp::_["has_reference_sequence"] = + rtsk_table_collection_has_reference_sequence(tc), + Rcpp::_["time_units"] = rtsk_table_collection_get_time_units(tc), + Rcpp::_["file_uuid"] = rtsk_table_collection_get_file_uuid(tc), + Rcpp::_["has_index"] = rtsk_table_collection_has_index(tc)); } -// PUBLIC +// PUBLIC, RcppTskit extension // @title Get the length of metadata in a table collection and its tables // @param tc an external pointer to table collection as a // \code{tsk_table_collection_t} object. // @return A named list with the length of metadata. // @examples // ts_file <- system.file("examples/test.trees", package = "RcppTskit") -// tc_xptr <- RcppTskit:::tc_xptr_load(ts_file) -// RcppTskit:::tc_xptr_metadata_length(tc_xptr) +// tc_xptr <- RcppTskit:::rtsk_table_collection_load(ts_file) +// RcppTskit:::rtsk_table_collection_metadata_length(tc_xptr) +// EXTENSION: metadata-length summary across tables (no single tsk_* +// equivalent). // [[Rcpp::export]] -Rcpp::List tc_xptr_metadata_length(const SEXP tc) { - RcppTskit_table_collection_xptr tc_xptr(tc); +Rcpp::List rtsk_table_collection_metadata_length(const SEXP tc) { + rtsk_table_collection_t tc_xptr(tc); return Rcpp::List::create( Rcpp::_["tc"] = static_cast(tc_xptr->metadata_length), Rcpp::_["populations"] = @@ -860,14 +952,14 @@ Rcpp::List tc_xptr_metadata_length(const SEXP tc) { // TODO: Metadata notes if we do anything with metadata #36 // https://github.com/HighlanderLab/RcppTskit/issues/36 -// int tc_xptr_metadata_schema_length(const SEXP tc) { -// RcppTskit_table_collection_xptr tc_xptr(tc); +// int rtsk_table_collection_metadata_schema_length(const SEXP tc) { +// rtsk_table_collection_t tc_xptr(tc); // return static_cast(tc_xptr->metadata_schema_length); // } // TODO: test the above function // TODO: document the above function // TODO: expose the above function to R, including TableCollection method -// TODO: Develop tc_xptr_metadata_schema +// TODO: Develop rtsk_table_collection_metadata_schema // TODO: Metadata notes if we do anything with metadata #36 // https://github.com/HighlanderLab/RcppTskit/issues/36 diff --git a/RcppTskit/src/tests.cpp b/RcppTskit/src/tests.cpp index 91ed807..c92b5ba 100644 --- a/RcppTskit/src/tests.cpp +++ b/RcppTskit/src/tests.cpp @@ -4,22 +4,22 @@ // ---------------------------------------------------------------------------- -extern "C" void RcppTskit_bug_assert_c(void); +extern "C" void rtsk_bug_assert_c(void); // TEST-ONLY // [[Rcpp::export]] -void test_tsk_bug_assert_c() { RcppTskit_bug_assert_c(); } +void test_tsk_bug_assert_c() { rtsk_bug_assert_c(); } // TEST-ONLY // [[Rcpp::export]] void test_tsk_bug_assert_cpp() { tsk_bug_assert(0); } -extern "C" void RcppTskit_trace_error_c(void); +extern "C" void rtsk_trace_error_c(void); // TEST-ONLY // This is tested if we compile with -DTSK_TRACE_ERRORS // [[Rcpp::export]] -void test_tsk_trace_error_c() { RcppTskit_trace_error_c(); } // # nocov +void test_tsk_trace_error_c() { rtsk_trace_error_c(); } // # nocov // TEST-ONLY // This is tested if we compile with -DTSK_TRACE_ERRORS @@ -38,27 +38,23 @@ bool tsk_trace_errors_defined() { // ---------------------------------------------------------------------------- -// Declarations for wrappers implemented in RcppTskit.cpp. -SEXP ts_xptr_to_tc_xptr(const SEXP ts, const int options); -SEXP tc_xptr_to_ts_xptr(const SEXP tc, const int options); - // TEST-ONLY -// @title Force tskit-level error path in \code{ts_xptr_to_tc_xptr} +// @title Force tskit-level error path in \code{rtsk_treeseq_copy_tables} // @param ts an external pointer to tree sequence as a \code{tsk_treeseq_t} // object. // @return No return value; called for side effects - testing. // [[Rcpp::export]] -SEXP test_ts_xptr_to_tc_xptr_forced_error(const SEXP ts) { - RcppTskit_treeseq_xptr ts_xptr(ts); +SEXP test_rtsk_treeseq_copy_tables_forced_error(const SEXP ts) { + rtsk_treeseq_t ts_xptr(ts); tsk_node_table_t &nodes = ts_xptr->tables->nodes; tsk_flags_t *saved_flags = nodes.flags; double *saved_time = nodes.time; nodes.flags = NULL; nodes.time = NULL; try { - SEXP ret = ts_xptr_to_tc_xptr(ts, 0); - // Lines below not hit by tests because ts_xptr_to_tc_xptr() throws error - // # nocov start + SEXP ret = rtsk_treeseq_copy_tables(ts, 0); + // Lines below not hit by tests because rtsk_treeseq_copy_tables() throws + // error # nocov start nodes.flags = saved_flags; nodes.time = saved_time; return ret; @@ -71,22 +67,22 @@ SEXP test_ts_xptr_to_tc_xptr_forced_error(const SEXP ts) { } // TEST-ONLY -// @title Force tskit-level error path in \code{tc_xptr_to_ts_xptr} +// @title Force tskit-level error path in \code{rtsk_treeseq_init} // @param tc an external pointer to table collection as a // \code{tsk_table_collection_t} object. // @return No return value; called for side effects - testing. // [[Rcpp::export]] -SEXP test_tc_xptr_to_ts_xptr_forced_error(const SEXP tc) { - RcppTskit_table_collection_xptr tc_xptr(tc); +SEXP test_rtsk_treeseq_init_forced_error(const SEXP tc) { + rtsk_table_collection_t tc_xptr(tc); tsk_node_table_t &nodes = tc_xptr->nodes; tsk_flags_t *saved_flags = nodes.flags; double *saved_time = nodes.time; nodes.flags = NULL; nodes.time = NULL; try { - SEXP ret = tc_xptr_to_ts_xptr(tc, 0); - // Lines below not hit by tests because ts_xptr_to_tc_xptr() throws error - // # nocov start + SEXP ret = rtsk_treeseq_init(tc, 0); + // Lines below not hit by tests because rtsk_treeseq_copy_tables() throws + // error # nocov start nodes.flags = saved_flags; nodes.time = saved_time; return ret; @@ -97,3 +93,31 @@ SEXP test_tc_xptr_to_ts_xptr_forced_error(const SEXP tc) { throw; } } + +// TEST-ONLY +// @title Force tskit-level error path in +// \code{rtsk_table_collection_build_index} +// @param tc an external pointer to table collection as a +// \code{tsk_table_collection_t} object. +// @return No return value; called for side effects - testing. +// @details Note that we need at least one edge row to force +// rtsk_table_collection_build_index +// error +// [[Rcpp::export]] +void test_rtsk_table_collection_build_index_forced_error(const SEXP tc) { + rtsk_table_collection_t tc_xptr(tc); + tsk_edge_table_t &edges = tc_xptr->edges; + tsk_id_t saved_parent = edges.parent[0]; + edges.parent[0] = (tsk_id_t)tc_xptr->nodes.num_rows; + try { + rtsk_table_collection_build_index(tc, 0); + // Lines below not hit by tests because rtsk_table_collection_build_index() + // throws error # nocov start + edges.parent[0] = saved_parent; + return; + // # nocov end + } catch (...) { + edges.parent[0] = saved_parent; + throw; + } +} diff --git a/RcppTskit/src/tests_c.c b/RcppTskit/src/tests_c.c index bde7e12..87878d8 100644 --- a/RcppTskit/src/tests_c.c +++ b/RcppTskit/src/tests_c.c @@ -1,6 +1,6 @@ #include -void RcppTskit_bug_assert_c(void) { tsk_bug_assert(0); } +void rtsk_bug_assert_c(void) { tsk_bug_assert(0); } // This is tested if we compile with -DTSK_TRACE_ERRORS -void RcppTskit_trace_error_c(void) { (void)tsk_trace_error(-1); } // # nocov +void rtsk_trace_error_c(void) { (void)tsk_trace_error(-1); } // # nocov diff --git a/RcppTskit/tests/testthat/test_TableCollection.R b/RcppTskit/tests/testthat/test_TableCollection.R index c8453bc..430c8eb 100644 --- a/RcppTskit/tests/testthat/test_TableCollection.R +++ b/RcppTskit/tests/testthat/test_TableCollection.R @@ -2,11 +2,11 @@ test_that("TableCollection$new() works", { ts_file <- system.file("examples/test.trees", package = "RcppTskit") expect_error( TableCollection$new(), - regexp = "Provide a file or a pointer!" + regexp = "Provide a file or an external pointer \\(xptr\\)!" ) expect_error( - TableCollection$new(file = "xyz", pointer = "y"), - regexp = "Provide either a file or a pointer, but not both!" + TableCollection$new(file = "xyz", xptr = "y"), + regexp = "Provide either a file or an external pointer \\(xptr\\), but not both!" ) expect_error( TableCollection$new(file = 1L), @@ -36,40 +36,40 @@ test_that("TableCollection$new() works", { ) expect_no_error(TableCollection$new(ts_file)) expect_error( - TableCollection$new(pointer = 1L), - regexp = "pointer must be an object of externalptr class!" + TableCollection$new(xptr = 1L), + regexp = "external pointer \\(xptr\\) must be an object of externalptr class!" ) }) test_that("TableCollection and TreeSequence round-trip works", { ts_file <- system.file("examples/test.trees", package = "RcppTskit") test_trees_file_uuid <- "79ec383f-a57d-b44f-2a5c-f0feecbbcb32" - ts_xptr <- ts_xptr_load(ts_file) + ts_xptr <- rtsk_treeseq_load(ts_file) # ---- Integer bitmask of tskit flags ---- - # See ts_xptr_to_tc_xptr() and tc_xptr_to_ts_xptr() documentation + # See rtsk_treeseq_copy_tables() and rtsk_treeseq_init() documentation unsupported_options <- bitwShiftL(1L, 27) supported_copy_option <- bitwShiftL(1L, 0) supported_init_options <- bitwOr(bitwShiftL(1L, 0), bitwShiftL(1L, 1)) expect_error( - ts_xptr_to_tc_xptr(ts_xptr, options = bitwShiftL(1L, 30)), + rtsk_treeseq_copy_tables(ts_xptr, options = bitwShiftL(1L, 30)), regexp = "does not support TSK_NO_INIT" ) expect_error( - ts_xptr_to_tc_xptr(ts_xptr, options = unsupported_options), + rtsk_treeseq_copy_tables(ts_xptr, options = unsupported_options), regexp = "only supports copy option TSK_COPY_FILE_UUID" ) expect_true(is( - ts_xptr_to_tc_xptr(ts_xptr, options = supported_copy_option), + rtsk_treeseq_copy_tables(ts_xptr, options = supported_copy_option), "externalptr" )) # ---- ts_xptr --> tc_xptr --> ts_xptr ---- - tc_xptr <- ts_xptr_to_tc_xptr(ts_xptr) + tc_xptr <- rtsk_treeseq_copy_tables(ts_xptr) expect_true(is(tc_xptr, "externalptr")) - p <- tc_xptr_print(tc_xptr) + p <- rtsk_table_collection_print(tc_xptr) expect_equal( p, list( @@ -110,20 +110,20 @@ test_that("TableCollection and TreeSequence round-trip works", { ) ) expect_error( - tc_xptr_to_ts_xptr(tc_xptr, options = bitwShiftL(1L, 28)), + rtsk_treeseq_init(tc_xptr, options = bitwShiftL(1L, 28)), regexp = "does not support TSK_TAKE_OWNERSHIP" ) expect_error( - tc_xptr_to_ts_xptr(tc_xptr, options = unsupported_options), + rtsk_treeseq_init(tc_xptr, options = unsupported_options), regexp = "only supports init options" ) expect_true(is( - tc_xptr_to_ts_xptr(tc_xptr, options = supported_init_options), + rtsk_treeseq_init(tc_xptr, options = supported_init_options), "externalptr" )) - ts_xptr2 <- tc_xptr_to_ts_xptr(tc_xptr) - p_ts_xptr <- ts_xptr_print(ts_xptr) - p_ts_xptr2 <- ts_xptr_print(ts_xptr2) + ts_xptr2 <- rtsk_treeseq_init(tc_xptr) + p_ts_xptr <- rtsk_treeseq_print(ts_xptr) + p_ts_xptr2 <- rtsk_treeseq_print(ts_xptr2) i_file_uuid <- p_ts_xptr$ts$property == "file_uuid" p_ts_xptr$ts$value[i_file_uuid] <- NA_character_ p_ts_xptr2$ts$value[p_ts_xptr2$ts$property == "file_uuid"] <- NA_character_ @@ -201,14 +201,56 @@ test_that("TableCollection and TreeSequence round-trip works", { # Edge cases expect_error( - test_ts_xptr_to_tc_xptr_forced_error(ts_xptr), + test_rtsk_treeseq_copy_tables_forced_error(ts_xptr), regexp = "TSK_ERR_BAD_PARAM_VALUE" ) - expect_true(is(ts_xptr_to_tc_xptr(ts_xptr), "externalptr")) + expect_true(is(rtsk_treeseq_copy_tables(ts_xptr), "externalptr")) expect_error( - test_tc_xptr_to_ts_xptr_forced_error(tc_xptr), + test_rtsk_treeseq_init_forced_error(tc_xptr), regexp = "TSK_ERR_BAD_PARAM_VALUE" ) - expect_true(is(tc_xptr_to_ts_xptr(tc_xptr), "externalptr")) + expect_true(is(rtsk_treeseq_init(tc_xptr), "externalptr")) + + expect_error( + test_rtsk_table_collection_build_index_forced_error(tc_xptr), + regexp = "TSK_ERR_NODE_OUT_OF_BOUNDS" + ) +}) + +test_that("TableCollection index lifecycle and tree_sequence index handling works", { + ts_file <- system.file("examples/test.trees", package = "RcppTskit") + ts <- ts_load(ts_file) + tc <- ts$dump_tables() + tc_xptr <- tc$xptr + build_index_option <- bitwShiftL(1L, 0) + + expect_error(rtsk_table_collection_build_index()) + expect_error(rtsk_table_collection_build_index(tc)) + expect_error(rtsk_table_collection_drop_index()) + expect_error(rtsk_table_collection_drop_index(tc)) + + expect_true(tc$has_index()) + expect_no_error(tc$drop_index()) + expect_false(tc$has_index()) + + expect_error( + rtsk_treeseq_init(tc_xptr, options = 0L), + regexp = "TSK_ERR_TABLES_NOT_INDEXED" + ) + expect_true(is( + rtsk_treeseq_init(tc_xptr, options = build_index_option), + "externalptr" + )) + # rtsk_treeseq_init() builds indexes in an internal ts, not in tc itself, + # so the tc in this environment will not have indexes here + expect_false(tc$has_index()) + ts2 <- tc$tree_sequence() + expect_true(is(ts2, "TreeSequence")) + expect_true(tc$has_index()) + + expect_no_error(tc$drop_index()) + expect_false(tc$has_index()) + expect_no_error(tc$build_index()) + expect_true(tc$has_index()) }) diff --git a/RcppTskit/tests/testthat/test_TreeSequence.R b/RcppTskit/tests/testthat/test_TreeSequence.R index 2fdb04b..1b55303 100644 --- a/RcppTskit/tests/testthat/test_TreeSequence.R +++ b/RcppTskit/tests/testthat/test_TreeSequence.R @@ -1,9 +1,12 @@ test_that("TreeSequence$new() works", { ts_file <- system.file("examples/test.trees", package = "RcppTskit") - expect_error(TreeSequence$new(), regexp = "Provide a file or a pointer!") expect_error( - TreeSequence$new(file = "xyz", pointer = "y"), - regexp = "Provide either a file or a pointer, but not both!" + TreeSequence$new(), + regexp = "Provide a file or an external pointer \\(xptr\\)!" + ) + expect_error( + TreeSequence$new(file = "xyz", xptr = "y"), + regexp = "Provide either a file or an external pointer \\(xptr\\), but not both!" ) expect_error( TreeSequence$new(file = 1L), @@ -33,7 +36,7 @@ test_that("TreeSequence$new() works", { ) expect_no_error(TreeSequence$new(ts_file)) expect_error( - TreeSequence$new(pointer = 1L), - regexp = "pointer must be an object of externalptr class!" + TreeSequence$new(xptr = 1L), + regexp = "external pointer \\(xptr\\) must be an object of externalptr class!" ) }) diff --git a/RcppTskit/tests/testthat/test_cpp_public_api.R b/RcppTskit/tests/testthat/test_cpp_public_api.R index 1437dd2..64f6359 100644 --- a/RcppTskit/tests/testthat/test_cpp_public_api.R +++ b/RcppTskit/tests/testthat/test_cpp_public_api.R @@ -11,10 +11,10 @@ test_that("public C++ wrappers compile for downstream-style usage", { Rcpp::List tc_public_scalars(SEXP tc) { return Rcpp::List::create( Rcpp::_["has_reference_sequence"] = - tc_xptr_has_reference_sequence(tc), - Rcpp::_["time_units"] = tc_xptr_time_units(tc), - Rcpp::_["file_uuid"] = tc_xptr_file_uuid(tc), - Rcpp::_["has_index"] = tc_xptr_has_index(tc) + rtsk_table_collection_has_reference_sequence(tc), + Rcpp::_["time_units"] = rtsk_table_collection_get_time_units(tc), + Rcpp::_["file_uuid"] = rtsk_table_collection_get_file_uuid(tc), + Rcpp::_["has_index"] = rtsk_table_collection_has_index(tc) ); }', depends = "RcppTskit", @@ -25,7 +25,7 @@ test_that("public C++ wrappers compile for downstream-style usage", { code = ' #include Rcpp::List ts_public_summary(SEXP ts) { - return ts_xptr_summary(ts); + return rtsk_treeseq_summary(ts); }', depends = "RcppTskit", plugins = "RcppTskit" @@ -35,7 +35,7 @@ test_that("public C++ wrappers compile for downstream-style usage", { code = ' #include Rcpp::List tc_public_summary(SEXP tc) { - return tc_xptr_summary(tc); + return rtsk_table_collection_summary(tc); }', depends = "RcppTskit", plugins = "RcppTskit" @@ -43,27 +43,39 @@ test_that("public C++ wrappers compile for downstream-style usage", { ts_file <- system.file("examples/test.trees", package = "RcppTskit") # jarl-ignore internal_function: it's just a test - ts_xptr <- RcppTskit:::ts_xptr_load(ts_file) + ts_xptr <- RcppTskit:::rtsk_treeseq_load(ts_file) # jarl-ignore internal_function: it's just a test - tc_xptr <- RcppTskit:::tc_xptr_load(ts_file) + tc_xptr <- RcppTskit:::rtsk_table_collection_load(ts_file) tc_scalars <- tc_public_scalars(tc_xptr) # jarl-ignore internal_function: it's just a test expect_identical( tc_scalars$has_reference_sequence, - RcppTskit:::tc_xptr_has_reference_sequence(tc_xptr) + RcppTskit:::rtsk_table_collection_has_reference_sequence(tc_xptr) ) # jarl-ignore internal_function: it's just a test expect_identical( tc_scalars$time_units, - RcppTskit:::tc_xptr_time_units(tc_xptr) + RcppTskit:::rtsk_table_collection_get_time_units(tc_xptr) ) # jarl-ignore internal_function: it's just a test - expect_identical(tc_scalars$file_uuid, RcppTskit:::tc_xptr_file_uuid(tc_xptr)) + expect_identical( + tc_scalars$file_uuid, + RcppTskit:::rtsk_table_collection_get_file_uuid(tc_xptr) + ) # jarl-ignore internal_function: it's just a test - expect_identical(tc_scalars$has_index, RcppTskit:::tc_xptr_has_index(tc_xptr)) + expect_identical( + tc_scalars$has_index, + RcppTskit:::rtsk_table_collection_has_index(tc_xptr) + ) # jarl-ignore internal_function: it's just a test - expect_equal(ts_public_summary(ts_xptr), RcppTskit:::ts_xptr_summary(ts_xptr)) + expect_equal( + ts_public_summary(ts_xptr), + RcppTskit:::rtsk_treeseq_summary(ts_xptr) + ) # jarl-ignore internal_function: it's just a test - expect_equal(tc_public_summary(tc_xptr), RcppTskit:::tc_xptr_summary(tc_xptr)) + expect_equal( + tc_public_summary(tc_xptr), + RcppTskit:::rtsk_table_collection_summary(tc_xptr) + ) }) diff --git a/RcppTskit/tests/testthat/test_load_summary_and_dump.R b/RcppTskit/tests/testthat/test_load_summary_and_dump.R index 1cad22a..909b217 100644 --- a/RcppTskit/tests/testthat/test_load_summary_and_dump.R +++ b/RcppTskit/tests/testthat/test_load_summary_and_dump.R @@ -6,15 +6,15 @@ test_that("ts/tc_load(), ts/tc_summary*(), and ts/tc_dump(x) work", { # ---- ts_load() ---- - expect_error(ts_xptr_load()) + expect_error(rtsk_treeseq_load()) expect_error(ts_load()) - expect_error(ts_xptr_load("nonexistent_ts")) + expect_error(rtsk_treeseq_load("nonexistent_ts")) expect_error(ts_load("nonexistent_ts")) ts_file <- system.file("examples/test.trees", package = "RcppTskit") expect_error( - ts_xptr_load(ts_file, options = bitwShiftL(1L, 30)), - regexp = "ts_xptr_load only supports load options" + rtsk_treeseq_load(ts_file, options = bitwShiftL(1L, 30)), + regexp = "rtsk_treeseq_load only supports load options" # TSK_LOAD_SKIP_TABLES (1 << 0) and TSK_LOAD_SKIP_REFERENCE_SEQUENCE (1 << 1) ) @@ -23,11 +23,11 @@ test_that("ts/tc_load(), ts/tc_summary*(), and ts/tc_dump(x) work", { ts_load(ts_file, skip_tables = "y"), regexp = "skip_tables must be TRUE/FALSE!" ) - expect_no_error(ts_xptr_load(ts_file, options = bitwShiftL(1L, 0L))) + expect_no_error(rtsk_treeseq_load(ts_file, options = bitwShiftL(1L, 0L))) expect_no_error(ts_load(ts_file, skip_tables = TRUE)) check_empty_tables_xptr <- function(ts) { # jarl-ignore implicit_assignment: it's just a test - tmp <- capture.output(p <- ts_xptr_print(ts)) + tmp <- capture.output(p <- rtsk_treeseq_print(ts)) expect_true(all(p$tables$number == 0)) } check_empty_tables <- function(ts) { @@ -35,7 +35,7 @@ test_that("ts/tc_load(), ts/tc_summary*(), and ts/tc_dump(x) work", { tmp <- capture.output(p <- ts$print()) expect_true(all(p$tables$number == 0)) } - ts_xptr <- ts_xptr_load(ts_file, options = bitwShiftL(1L, 0L)) + ts_xptr <- rtsk_treeseq_load(ts_file, options = bitwShiftL(1L, 0L)) check_empty_tables_xptr(ts_xptr) ts <- ts_load(ts_file, skip_tables = TRUE) check_empty_tables(ts) @@ -47,15 +47,15 @@ test_that("ts/tc_load(), ts/tc_summary*(), and ts/tc_dump(x) work", { ts_load(ts_file, skip_reference_sequence = 1L), regexp = "skip_reference_sequence must be TRUE/FALSE!" ) - expect_no_error(ts_xptr_load(ts_file, options = bitwShiftL(1L, 1L))) + expect_no_error(rtsk_treeseq_load(ts_file, options = bitwShiftL(1L, 1L))) expect_no_error(ts_load(ts_file, skip_reference_sequence = TRUE)) ts_with_ref_seq_file <- system.file( "examples/test_with_ref_seq.trees", package = "RcppTskit" ) - expect_no_error(ts_xptr_load(ts_with_ref_seq_file)) - expect_no_error(ts_xptr_load( + expect_no_error(rtsk_treeseq_load(ts_with_ref_seq_file)) + expect_no_error(rtsk_treeseq_load( ts_with_ref_seq_file, options = bitwShiftL(1L, 1L) )) @@ -63,20 +63,20 @@ test_that("ts/tc_load(), ts/tc_summary*(), and ts/tc_dump(x) work", { expect_no_error(ts_load(ts_with_ref_seq_file, skip_reference_sequence = TRUE)) # For tests below - ts_xptr <- ts_xptr_load(ts_file) + ts_xptr <- rtsk_treeseq_load(ts_file) ts <- ts_load(ts_file) # ---- tc_load() ---- - expect_error(tc_xptr_load()) + expect_error(rtsk_table_collection_load()) expect_error(tc_load()) - expect_error(tc_xptr_load("nonexistent_ts")) + expect_error(rtsk_table_collection_load("nonexistent_ts")) expect_error(tc_load("nonexistent_ts")) ts_file <- system.file("examples/test.trees", package = "RcppTskit") expect_error( - tc_xptr_load(ts_file, options = bitwShiftL(1L, 30)), - regexp = "tc_xptr_load only supports load options" + rtsk_table_collection_load(ts_file, options = bitwShiftL(1L, 30)), + regexp = "rtsk_table_collection_load only supports load options" # TSK_LOAD_SKIP_TABLES (1 << 0) and TSK_LOAD_SKIP_REFERENCE_SEQUENCE (1 << 1) ) @@ -85,11 +85,14 @@ test_that("ts/tc_load(), ts/tc_summary*(), and ts/tc_dump(x) work", { tc_load(ts_file, skip_tables = "y"), regexp = "skip_tables must be TRUE/FALSE!" ) - expect_no_error(tc_xptr_load(ts_file, options = bitwShiftL(1L, 0L))) + expect_no_error(rtsk_table_collection_load( + ts_file, + options = bitwShiftL(1L, 0L) + )) expect_no_error(tc_load(ts_file, skip_tables = TRUE)) check_empty_tables_xptr <- function(tc) { # jarl-ignore implicit_assignment: it's just a test - tmp <- capture.output(p <- tc_xptr_print(tc)) + tmp <- capture.output(p <- rtsk_table_collection_print(tc)) expect_true(all(p$tables$number == 0)) } check_empty_tables <- function(tc) { @@ -97,7 +100,7 @@ test_that("ts/tc_load(), ts/tc_summary*(), and ts/tc_dump(x) work", { tmp <- capture.output(p <- tc$print()) expect_true(all(p$tables$number == 0)) } - tc_xptr <- tc_xptr_load(ts_file, options = bitwShiftL(1L, 0L)) + tc_xptr <- rtsk_table_collection_load(ts_file, options = bitwShiftL(1L, 0L)) check_empty_tables_xptr(tc_xptr) tc <- tc_load(ts_file, skip_tables = TRUE) check_empty_tables(tc) @@ -109,15 +112,18 @@ test_that("ts/tc_load(), ts/tc_summary*(), and ts/tc_dump(x) work", { tc_load(ts_file, skip_reference_sequence = 1L), regexp = "skip_reference_sequence must be TRUE/FALSE!" ) - expect_no_error(tc_xptr_load(ts_file, options = bitwShiftL(1L, 1L))) + expect_no_error(rtsk_table_collection_load( + ts_file, + options = bitwShiftL(1L, 1L) + )) expect_no_error(tc_load(ts_file, skip_reference_sequence = TRUE)) ts_with_ref_seq_file <- system.file( "examples/test_with_ref_seq.trees", package = "RcppTskit" ) - expect_no_error(tc_xptr_load(ts_with_ref_seq_file)) - expect_no_error(tc_xptr_load( + expect_no_error(rtsk_table_collection_load(ts_with_ref_seq_file)) + expect_no_error(rtsk_table_collection_load( ts_with_ref_seq_file, options = bitwShiftL(1L, 1L) )) @@ -125,14 +131,14 @@ test_that("ts/tc_load(), ts/tc_summary*(), and ts/tc_dump(x) work", { expect_no_error(tc_load(ts_with_ref_seq_file, skip_reference_sequence = TRUE)) # For tests below - tc_xptr <- tc_xptr_load(ts_file) + tc_xptr <- rtsk_table_collection_load(ts_file) tc <- tc_load(ts_file) - # ---- ts_xptr_summary() ---- + # ---- rtsk_treeseq_summary() ---- # Simple comparison of summaries - expect_error(ts_xptr_summary(ts)) - n_xptr <- ts_xptr_summary(ts_xptr) + expect_error(rtsk_treeseq_summary(ts)) + n_xptr <- rtsk_treeseq_summary(ts_xptr) expect_equal( n_xptr, list( @@ -158,86 +164,86 @@ test_that("ts/tc_load(), ts/tc_summary*(), and ts/tc_dump(x) work", { ) ) - expect_error(ts_xptr_num_provenances()) - expect_error(ts_xptr_num_provenances(ts)) - n_xptr <- ts_xptr_num_provenances(ts_xptr) + expect_error(rtsk_treeseq_get_num_provenances()) + expect_error(rtsk_treeseq_get_num_provenances(ts)) + n_xptr <- rtsk_treeseq_get_num_provenances(ts_xptr) expect_true(is.integer(n_xptr)) expect_equal(n_xptr, 2L) expect_equal(ts$num_provenances(), 2L) - expect_error(ts_xptr_num_populations()) - expect_error(ts_xptr_num_populations(ts)) - n_xptr <- ts_xptr_num_populations(ts_xptr) + expect_error(rtsk_treeseq_get_num_populations()) + expect_error(rtsk_treeseq_get_num_populations(ts)) + n_xptr <- rtsk_treeseq_get_num_populations(ts_xptr) expect_true(is.integer(n_xptr)) expect_equal(n_xptr, 1L) expect_equal(ts$num_populations(), 1L) - expect_error(ts_xptr_num_migrations()) - expect_error(ts_xptr_num_migrations(ts)) - n_xptr <- ts_xptr_num_migrations(ts_xptr) + expect_error(rtsk_treeseq_get_num_migrations()) + expect_error(rtsk_treeseq_get_num_migrations(ts)) + n_xptr <- rtsk_treeseq_get_num_migrations(ts_xptr) expect_true(is.integer(n_xptr)) expect_equal(n_xptr, 0L) expect_equal(ts$num_migrations(), 0L) - expect_error(ts_xptr_num_individuals()) - expect_error(ts_xptr_num_individuals(ts)) - n_xptr <- ts_xptr_num_individuals(ts_xptr) + expect_error(rtsk_treeseq_get_num_individuals()) + expect_error(rtsk_treeseq_get_num_individuals(ts)) + n_xptr <- rtsk_treeseq_get_num_individuals(ts_xptr) expect_true(is.integer(n_xptr)) expect_equal(n_xptr, 8L) expect_equal(ts$num_individuals(), 8L) - expect_error(ts_xptr_num_samples()) - expect_error(ts_xptr_num_samples(ts)) - n_xptr <- ts_xptr_num_samples(ts_xptr) + expect_error(rtsk_treeseq_get_num_samples()) + expect_error(rtsk_treeseq_get_num_samples(ts)) + n_xptr <- rtsk_treeseq_get_num_samples(ts_xptr) expect_true(is.integer(n_xptr)) expect_equal(n_xptr, 16L) expect_equal(ts$num_samples(), 16L) - expect_error(ts_xptr_num_nodes()) - expect_error(ts_xptr_num_nodes(ts)) - n_xptr <- ts_xptr_num_nodes(ts_xptr) + expect_error(rtsk_treeseq_get_num_nodes()) + expect_error(rtsk_treeseq_get_num_nodes(ts)) + n_xptr <- rtsk_treeseq_get_num_nodes(ts_xptr) expect_true(is.integer(n_xptr)) expect_equal(n_xptr, 39L) expect_equal(ts$num_nodes(), 39L) - expect_error(ts_xptr_num_edges()) - expect_error(ts_xptr_num_edges(ts)) - n_xptr <- ts_xptr_num_edges(ts_xptr) + expect_error(rtsk_treeseq_get_num_edges()) + expect_error(rtsk_treeseq_get_num_edges(ts)) + n_xptr <- rtsk_treeseq_get_num_edges(ts_xptr) expect_true(is.integer(n_xptr)) expect_equal(n_xptr, 59L) expect_equal(ts$num_edges(), 59L) - expect_error(ts_xptr_num_trees()) - expect_error(ts_xptr_num_trees(ts)) - n_xptr <- ts_xptr_num_trees(ts_xptr) + expect_error(rtsk_treeseq_get_num_trees()) + expect_error(rtsk_treeseq_get_num_trees(ts)) + n_xptr <- rtsk_treeseq_get_num_trees(ts_xptr) expect_true(is.integer(n_xptr)) expect_equal(n_xptr, 9L) expect_equal(ts$num_trees(), 9L) - expect_error(ts_xptr_num_sites()) - expect_error(ts_xptr_num_sites(ts)) - n_xptr <- ts_xptr_num_sites(ts_xptr) + expect_error(rtsk_treeseq_get_num_sites()) + expect_error(rtsk_treeseq_get_num_sites(ts)) + n_xptr <- rtsk_treeseq_get_num_sites(ts_xptr) expect_true(is.integer(n_xptr)) expect_equal(n_xptr, 25L) expect_equal(ts$num_sites(), 25L) - expect_error(ts_xptr_num_mutations()) - expect_error(ts_xptr_num_mutations(ts)) - n_xptr <- ts_xptr_num_mutations(ts_xptr) + expect_error(rtsk_treeseq_get_num_mutations()) + expect_error(rtsk_treeseq_get_num_mutations(ts)) + n_xptr <- rtsk_treeseq_get_num_mutations(ts_xptr) expect_true(is.integer(n_xptr)) expect_equal(n_xptr, 30L) expect_equal(ts$num_mutations(), 30L) - expect_error(ts_xptr_sequence_length()) - expect_error(ts_xptr_sequence_length(ts)) - n_xptr <- ts_xptr_sequence_length(ts_xptr) + expect_error(rtsk_treeseq_get_sequence_length()) + expect_error(rtsk_treeseq_get_sequence_length(ts)) + n_xptr <- rtsk_treeseq_get_sequence_length(ts_xptr) expect_true(is.numeric(n_xptr)) expect_equal(n_xptr, 100) expect_equal(ts$sequence_length(), 100) - expect_error(ts_xptr_discrete_genome()) - expect_error(ts_xptr_discrete_genome(ts)) - l_xptr <- ts_xptr_discrete_genome(ts_xptr) + expect_error(rtsk_treeseq_get_discrete_genome()) + expect_error(rtsk_treeseq_get_discrete_genome(ts)) + l_xptr <- rtsk_treeseq_get_discrete_genome(ts_xptr) expect_true(is.logical(l_xptr)) expect_true(l_xptr) expect_true(ts$discrete_genome()) @@ -246,38 +252,38 @@ test_that("ts/tc_load(), ts/tc_summary*(), and ts/tc_dump(x) work", { "examples/test_non_discrete_genome.trees", package = "RcppTskit" ) - ts_non_discrete_xptr <- ts_xptr_load(ts_non_discrete_file) + ts_non_discrete_xptr <- rtsk_treeseq_load(ts_non_discrete_file) ts_non_discrete <- ts_load(ts_non_discrete_file) - expect_false(ts_xptr_discrete_genome(ts_non_discrete_xptr)) + expect_false(rtsk_treeseq_get_discrete_genome(ts_non_discrete_xptr)) expect_false(ts_non_discrete$discrete_genome()) - expect_error(ts_xptr_has_reference_sequence()) - expect_error(ts_xptr_has_reference_sequence(ts)) - l_xptr <- ts_xptr_has_reference_sequence(ts_xptr) + expect_error(rtsk_treeseq_has_reference_sequence()) + expect_error(rtsk_treeseq_has_reference_sequence(ts)) + l_xptr <- rtsk_treeseq_has_reference_sequence(ts_xptr) expect_true(is.logical(l_xptr)) expect_false(l_xptr) expect_false(ts$has_reference_sequence()) - ts_with_ref_seq_xptr <- ts_xptr_load(ts_with_ref_seq_file) + ts_with_ref_seq_xptr <- rtsk_treeseq_load(ts_with_ref_seq_file) ts_with_ref_seq <- ts_load(ts_with_ref_seq_file) - expect_true(ts_xptr_has_reference_sequence(ts_with_ref_seq_xptr)) + expect_true(rtsk_treeseq_has_reference_sequence(ts_with_ref_seq_xptr)) expect_true(ts_with_ref_seq$has_reference_sequence()) - f_xptr <- ts_xptr_sequence_length(ts_non_discrete_xptr) + f_xptr <- rtsk_treeseq_get_sequence_length(ts_non_discrete_xptr) expect_true(is.numeric(f_xptr)) expect_equal(f_xptr, 10.5) expect_equal(ts_non_discrete$sequence_length(), 10.5) - expect_error(ts_xptr_time_units()) - expect_error(ts_xptr_time_units(ts)) - c_xptr <- ts_xptr_time_units(ts_xptr) + expect_error(rtsk_treeseq_get_time_units()) + expect_error(rtsk_treeseq_get_time_units(ts)) + c_xptr <- rtsk_treeseq_get_time_units(ts_xptr) expect_true(is.character(c_xptr)) expect_equal(c_xptr, "generations") expect_equal(ts$time_units(), "generations") - expect_error(ts_xptr_discrete_time()) - expect_error(ts_xptr_discrete_time(ts)) - l_xptr <- ts_xptr_discrete_time(ts_xptr) + expect_error(rtsk_treeseq_get_discrete_time()) + expect_error(rtsk_treeseq_get_discrete_time(ts)) + l_xptr <- rtsk_treeseq_get_discrete_time(ts_xptr) expect_true(is.logical(l_xptr)) expect_false(l_xptr) expect_false(ts$discrete_time()) @@ -286,49 +292,52 @@ test_that("ts/tc_load(), ts/tc_summary*(), and ts/tc_dump(x) work", { "examples/test_discrete_time.trees", package = "RcppTskit" ) - ts_discrete_time_xptr <- ts_xptr_load(ts_discrete_time_file) + ts_discrete_time_xptr <- rtsk_treeseq_load(ts_discrete_time_file) ts_discrete_time <- ts_load(ts_discrete_time_file) - expect_true(ts_xptr_discrete_time(ts_discrete_time_xptr)) + expect_true(rtsk_treeseq_get_discrete_time(ts_discrete_time_xptr)) expect_true(ts_discrete_time$discrete_time()) - expect_error(ts_xptr_min_time()) - expect_error(ts_xptr_min_time(ts)) - d_xptr <- ts_xptr_min_time(ts_xptr) + expect_error(rtsk_treeseq_get_min_time()) + expect_error(rtsk_treeseq_get_min_time(ts)) + d_xptr <- rtsk_treeseq_get_min_time(ts_xptr) expect_true(is.numeric(d_xptr)) expect_equal(d_xptr, 0.0) expect_equal(ts$min_time(), 0.0) - expect_error(ts_xptr_max_time()) - expect_error(ts_xptr_max_time(ts)) - d_xptr <- ts_xptr_max_time(ts_xptr) + expect_error(rtsk_treeseq_get_max_time()) + expect_error(rtsk_treeseq_get_max_time(ts)) + d_xptr <- rtsk_treeseq_get_max_time(ts_xptr) expect_true(is.numeric(d_xptr)) expect_equal(d_xptr, 6.9619933371908083) expect_equal(ts$max_time(), 6.9619933371908083) - expect_error(ts_xptr_file_uuid()) - expect_error(ts_xptr_file_uuid(ts)) - c_xptr <- ts_xptr_file_uuid(ts_xptr) + expect_error(rtsk_treeseq_get_file_uuid()) + expect_error(rtsk_treeseq_get_file_uuid(ts)) + c_xptr <- rtsk_treeseq_get_file_uuid(ts_xptr) expect_true(is.character(c_xptr)) expect_equal(length(c_xptr), 1L) expect_equal(c_xptr, test_trees_file_uuid) expect_equal(c_xptr, ts$file_uuid()) expect_equal( - ts_xptr_file_uuid(ts_with_ref_seq_xptr), + rtsk_treeseq_get_file_uuid(ts_with_ref_seq_xptr), test_with_ref_seq_file_uuid ) expect_equal(ts_with_ref_seq$file_uuid(), test_with_ref_seq_file_uuid) - expect_false(identical(c_xptr, ts_xptr_file_uuid(ts_with_ref_seq_xptr))) + expect_false(identical( + c_xptr, + rtsk_treeseq_get_file_uuid(ts_with_ref_seq_xptr) + )) ts_from_tc <- ts$dump_tables()$tree_sequence() expect_true(is.na(ts_from_tc$file_uuid())) - expect_true(is.na(ts_xptr_file_uuid(ts_from_tc$pointer))) + expect_true(is.na(rtsk_treeseq_get_file_uuid(ts_from_tc$xptr))) - # ---- tc_xptr_summary() ---- + # ---- rtsk_table_collection_summary() ---- # Simple comparison of summaries - expect_error(tc_xptr_summary(tc)) - n_xptr_tc <- tc_xptr_summary(tc_xptr) - n_xptr_ts <- ts_xptr_summary(ts_xptr) + expect_error(rtsk_table_collection_summary(tc)) + n_xptr_tc <- rtsk_table_collection_summary(tc_xptr) + n_xptr_ts <- rtsk_treeseq_summary(ts_xptr) shared_items <- c( "num_provenances", "num_populations", @@ -345,9 +354,9 @@ test_that("ts/tc_load(), ts/tc_summary*(), and ts/tc_dump(x) work", { ) expect_equal(n_xptr_tc[shared_items], n_xptr_ts[shared_items]) - expect_error(tc_xptr_sequence_length()) - expect_error(tc_xptr_sequence_length(ts)) - n_xptr <- tc_xptr_sequence_length(tc_xptr) + expect_error(rtsk_table_collection_get_sequence_length()) + expect_error(rtsk_table_collection_get_sequence_length(ts)) + n_xptr <- rtsk_table_collection_get_sequence_length(tc_xptr) expect_true(is.numeric(n_xptr)) expect_equal(n_xptr, 100) expect_equal(tc$sequence_length(), 100) @@ -356,29 +365,29 @@ test_that("ts/tc_load(), ts/tc_summary*(), and ts/tc_dump(x) work", { "examples/test_non_discrete_genome.trees", package = "RcppTskit" ) - tc_non_discrete_xptr <- tc_xptr_load(tc_non_discrete_file) + tc_non_discrete_xptr <- rtsk_table_collection_load(tc_non_discrete_file) tc_non_discrete <- tc_load(tc_non_discrete_file) - f_xptr <- tc_xptr_sequence_length(tc_non_discrete_xptr) + f_xptr <- rtsk_table_collection_get_sequence_length(tc_non_discrete_xptr) expect_true(is.numeric(f_xptr)) expect_equal(f_xptr, 10.5) expect_equal(tc_non_discrete$sequence_length(), 10.5) - expect_error(tc_xptr_has_reference_sequence()) - expect_error(tc_xptr_has_reference_sequence(ts)) - l_xptr <- tc_xptr_has_reference_sequence(tc_xptr) + expect_error(rtsk_table_collection_has_reference_sequence()) + expect_error(rtsk_table_collection_has_reference_sequence(ts)) + l_xptr <- rtsk_table_collection_has_reference_sequence(tc_xptr) expect_true(is.logical(l_xptr)) expect_false(l_xptr) expect_false(tc$has_reference_sequence()) - expect_error(tc_xptr_time_units()) - expect_error(tc_xptr_time_units(ts)) - c_xptr <- tc_xptr_time_units(tc_xptr) + expect_error(rtsk_table_collection_get_time_units()) + expect_error(rtsk_table_collection_get_time_units(ts)) + c_xptr <- rtsk_table_collection_get_time_units(tc_xptr) expect_true(is.character(c_xptr)) expect_equal(c_xptr, "generations") expect_equal(tc$time_units(), "generations") - expect_error(tc_xptr_file_uuid()) - expect_error(tc_xptr_file_uuid(ts)) - c_xptr <- tc_xptr_file_uuid(tc_xptr) + expect_error(rtsk_table_collection_get_file_uuid()) + expect_error(rtsk_table_collection_get_file_uuid(ts)) + c_xptr <- rtsk_table_collection_get_file_uuid(tc_xptr) expect_true(is.character(c_xptr)) expect_equal(length(c_xptr), 1L) expect_equal(c_xptr, test_trees_file_uuid) @@ -386,23 +395,23 @@ test_that("ts/tc_load(), ts/tc_summary*(), and ts/tc_dump(x) work", { tc_from_ts <- ts$dump_tables() expect_true(is.na(tc_from_ts$file_uuid())) - expect_true(is.na(tc_xptr_file_uuid(tc_from_ts$pointer))) + expect_true(is.na(rtsk_table_collection_get_file_uuid(tc_from_ts$xptr))) - expect_error(tc_xptr_has_index()) - expect_error(tc_xptr_has_index(ts)) - l_xptr <- tc_xptr_has_index(tc_xptr) + expect_error(rtsk_table_collection_has_index()) + expect_error(rtsk_table_collection_has_index(ts)) + l_xptr <- rtsk_table_collection_has_index(tc_xptr) expect_true(is.logical(l_xptr)) expect_true(l_xptr) expect_true(tc$has_index()) - # ---- ts_xptr_print() and ts$print() ---- + # ---- rtsk_treeseq_print() and ts$print() ---- # Simple comparison of summaries expect_error( - ts_xptr_print("not an externalptr object"), + rtsk_treeseq_print("not an externalptr object"), regexp = "ts must be an object of externalptr class!" ) - p_xptr <- ts_xptr_print(ts_xptr) + p_xptr <- rtsk_treeseq_print(ts_xptr) # jarl-ignore implicit_assignment: it's just a test tmp <- capture.output(p <- ts$print()) expect_equal( @@ -463,14 +472,14 @@ test_that("ts/tc_load(), ts/tc_summary*(), and ts/tc_dump(x) work", { ) expect_equal(p_xptr, p) - # ---- tc_xptr_print() and tc$print() ---- + # ---- rtsk_table_collection_print() and tc$print() ---- # Simple comparison of summaries expect_error( - tc_xptr_print("not an externalptr object"), + rtsk_table_collection_print("not an externalptr object"), regexp = "tc must be an object of externalptr class!" ) - p_xptr <- tc_xptr_print(tc_xptr) + p_xptr <- rtsk_table_collection_print(tc_xptr) # jarl-ignore implicit_assignment: it's just a test tmp <- capture.output(p <- tc$print()) expect_equal( @@ -521,33 +530,37 @@ test_that("ts/tc_load(), ts/tc_summary*(), and ts/tc_dump(x) work", { ) expect_equal(p_xptr, p) - # ---- ts_xptr_dump() ---- - - expect_error(ts_xptr_dump()) - expect_error(ts_xptr_dump(nonexistent_ts)) - expect_error(ts_xptr_dump(file = 1)) - expect_error(ts_xptr_dump(nonexistent_ts, file = 1)) - expect_error(ts_xptr_dump(1, file = 1)) - expect_error(ts_xptr_dump(1, file = "1")) - expect_error(ts_xptr_dump(1, file = 1)) - expect_error(ts_xptr_dump(ts_xptr)) - expect_error(ts_xptr_dump(ts)) + # ---- rtsk_treeseq_dump() ---- + + expect_error(rtsk_treeseq_dump()) + expect_error(rtsk_treeseq_dump(nonexistent_ts)) + expect_error(rtsk_treeseq_dump(file = 1)) + expect_error(rtsk_treeseq_dump(nonexistent_ts, file = 1)) + expect_error(rtsk_treeseq_dump(1, file = 1)) + expect_error(rtsk_treeseq_dump(1, file = "1")) + expect_error(rtsk_treeseq_dump(1, file = 1)) + expect_error(rtsk_treeseq_dump(ts_xptr)) + expect_error(rtsk_treeseq_dump(ts)) bad_path <- file.path(tempdir(), "no_such_dir", "out.trees") - expect_error(ts_xptr_dump(ts_xptr, file = bad_path)) + expect_error(rtsk_treeseq_dump(ts_xptr, file = bad_path)) expect_error( - ts_xptr_dump(ts_xptr, file = tempfile(fileext = ".trees"), options = 1L), + rtsk_treeseq_dump( + ts_xptr, + file = tempfile(fileext = ".trees"), + options = 1L + ), regexp = "does not support non-zero options" ) # Write ts to disk, read it back, and check that nums are still the same dump_file <- tempfile(fileext = ".trees") - ts_xptr_dump(ts_xptr, dump_file) + rtsk_treeseq_dump(ts_xptr, dump_file) rm(ts_xptr) - ts_xptr <- ts_xptr_load(dump_file) + ts_xptr <- rtsk_treeseq_load(dump_file) file.remove(dump_file) # Simple comparison of summaries - n <- ts_xptr_summary(ts_xptr) + n <- rtsk_treeseq_summary(ts_xptr) expect_equal( n, list( @@ -569,42 +582,46 @@ test_that("ts/tc_load(), ts/tc_summary*(), and ts/tc_dump(x) work", { "discrete_time" = FALSE, "min_time" = 0.0, "max_time" = 6.9619933371908083, - "file_uuid" = ts_xptr_file_uuid(ts_xptr) - # using ts_xptr_file_uuid() here since I don't have UUID + "file_uuid" = rtsk_treeseq_get_file_uuid(ts_xptr) + # using rtsk_treeseq_get_file_uuid() here since I don't have UUID # on this file from Python code due to disk serialisation # on our end (we test for correctness elsewhere anyway) ) ) - # ---- tc_xptr_dump() ---- + # ---- rtsk_table_collection_dump() ---- - expect_error(tc_xptr_dump()) - expect_error(tc_xptr_dump(nonexistent_ts)) - expect_error(tc_xptr_dump(file = 1)) - expect_error(tc_xptr_dump(nonexistent_ts, file = 1)) - expect_error(tc_xptr_dump(1, file = 1)) - expect_error(tc_xptr_dump(1, file = "1")) - expect_error(tc_xptr_dump(1, file = 1)) - expect_error(tc_xptr_dump(tc_xptr)) - expect_error(tc_xptr_dump(tc)) + expect_error(rtsk_table_collection_dump()) + expect_error(rtsk_table_collection_dump(nonexistent_ts)) + expect_error(rtsk_table_collection_dump(file = 1)) + expect_error(rtsk_table_collection_dump(nonexistent_ts, file = 1)) + expect_error(rtsk_table_collection_dump(1, file = 1)) + expect_error(rtsk_table_collection_dump(1, file = "1")) + expect_error(rtsk_table_collection_dump(1, file = 1)) + expect_error(rtsk_table_collection_dump(tc_xptr)) + expect_error(rtsk_table_collection_dump(tc)) bad_path <- file.path(tempdir(), "no_such_dir", "out.trees") - expect_error(tc_xptr_dump(tc_xptr, file = bad_path)) + expect_error(rtsk_table_collection_dump(tc_xptr, file = bad_path)) expect_error( - tc_xptr_dump(tc_xptr, file = tempfile(fileext = ".trees"), options = 1L), + rtsk_table_collection_dump( + tc_xptr, + file = tempfile(fileext = ".trees"), + options = 1L + ), regexp = "does not support non-zero options" ) # Write ts to disk, read it back, and check that nums are still the same dump_file <- tempfile(fileext = ".trees") - tc_xptr_dump(tc_xptr, dump_file) + rtsk_table_collection_dump(tc_xptr, dump_file) rm(tc_xptr) - tc_xptr <- tc_xptr_load(dump_file) - ts_xptr <- ts_xptr_load(dump_file) + tc_xptr <- rtsk_table_collection_load(dump_file) + ts_xptr <- rtsk_treeseq_load(dump_file) file.remove(dump_file) # Simple comparison of summaries - n_ts <- ts_xptr_summary(ts_xptr) - n_tc <- tc_xptr_summary(tc_xptr) + n_ts <- rtsk_treeseq_summary(ts_xptr) + n_tc <- rtsk_table_collection_summary(tc_xptr) shared_items <- c( "num_provenances", @@ -642,7 +659,7 @@ test_that("ts/tc_load(), ts/tc_summary*(), and ts/tc_dump(x) work", { file.remove(dump_file) # Simple comparison of summaries - n_xptr <- ts_xptr_summary(ts$pointer) + n_xptr <- rtsk_treeseq_summary(ts$xptr) expect_equal( n_xptr, list( @@ -664,8 +681,8 @@ test_that("ts/tc_load(), ts/tc_summary*(), and ts/tc_dump(x) work", { "discrete_time" = FALSE, "min_time" = 0.0, "max_time" = 6.9619933371908083, - "file_uuid" = ts_xptr_file_uuid(ts$pointer) - # using ts_xptr_file_uuid() here since I don't have UUID + "file_uuid" = rtsk_treeseq_get_file_uuid(ts$xptr) + # using rtsk_treeseq_get_file_uuid() here since I don't have UUID # on this file from Python code due to disk serialisation # on our end (we test for correctness elsewhere anyway) ) @@ -691,7 +708,7 @@ test_that("ts/tc_load(), ts/tc_summary*(), and ts/tc_dump(x) work", { file.remove(dump_file) # Simple comparison of summaries - n_xptr <- tc_xptr_summary(tc$pointer) + n_xptr <- rtsk_table_collection_summary(tc$xptr) expect_equal( n_xptr, list( @@ -707,18 +724,18 @@ test_that("ts/tc_load(), ts/tc_summary*(), and ts/tc_dump(x) work", { "sequence_length" = 100.0, "has_reference_sequence" = FALSE, "time_units" = "generations", - "file_uuid" = tc_xptr_file_uuid(tc$pointer), + "file_uuid" = rtsk_table_collection_get_file_uuid(tc$xptr), "has_index" = TRUE - # using ts_xptr_file_uuid() here since I don't have UUID + # using rtsk_treeseq_get_file_uuid() here since I don't have UUID # on this file from Python code due to disk serialisation # on our end (we test for correctness elsewhere anyway) ) ) - # ---- ts_xptr_metadata_length() ---- + # ---- rtsk_treeseq_metadata_length() ---- # Simple comparison of the lengths of metadata - n_xptr <- ts_xptr_metadata_length(ts_xptr) + n_xptr <- rtsk_treeseq_metadata_length(ts_xptr) n <- ts$metadata_length() expect_equal( n_xptr, @@ -737,10 +754,10 @@ test_that("ts/tc_load(), ts/tc_summary*(), and ts/tc_dump(x) work", { expect_equal(n_xptr, n) ts_file <- system.file("examples/test2.trees", package = "RcppTskit") - ts_xptr <- ts_xptr_load(ts_file) + ts_xptr <- rtsk_treeseq_load(ts_file) ts <- ts_load(ts_file) - n_xptr <- ts_xptr_summary(ts_xptr) + n_xptr <- rtsk_treeseq_summary(ts_xptr) expect_equal( n_xptr, list( @@ -766,7 +783,7 @@ test_that("ts/tc_load(), ts/tc_summary*(), and ts/tc_dump(x) work", { ) ) - m_xptr <- ts_xptr_metadata_length(ts_xptr) + m_xptr <- rtsk_treeseq_metadata_length(ts_xptr) m <- ts$metadata_length() expect_equal( m_xptr, @@ -784,7 +801,7 @@ test_that("ts/tc_load(), ts/tc_summary*(), and ts/tc_dump(x) work", { ) expect_equal(m_xptr, m) - p_xptr <- ts_xptr_print(ts_xptr) + p_xptr <- rtsk_treeseq_print(ts_xptr) # jarl-ignore implicit_assignment: it's just a test tmp <- capture.output(p <- ts$print()) expect_equal( @@ -845,24 +862,24 @@ test_that("ts/tc_load(), ts/tc_summary*(), and ts/tc_dump(x) work", { ) expect_equal(p_xptr, p) - # ---- tc_xptr_metadata_length() ---- + # ---- rtsk_table_collection_metadata_length() ---- # Simple comparison of the lengths of metadata - n_xptr_tc <- tc_xptr_metadata_length(tc_xptr) + n_xptr_tc <- rtsk_table_collection_metadata_length(tc_xptr) ts_file <- system.file("examples/test.trees", package = "RcppTskit") - ts_xptr <- ts_xptr_load(ts_file) - n_xptr_ts <- ts_xptr_metadata_length(ts_xptr) + ts_xptr <- rtsk_treeseq_load(ts_file) + n_xptr_ts <- rtsk_treeseq_metadata_length(ts_xptr) names(n_xptr_tc)[1] <- "ts" expect_equal(n_xptr_tc, n_xptr_ts) ts_file <- system.file("examples/test2.trees", package = "RcppTskit") - tc_xptr <- tc_xptr_load(ts_file) + tc_xptr <- rtsk_table_collection_load(ts_file) tc <- tc_load(ts_file) - ts_xptr <- ts_xptr_load(ts_file) + ts_xptr <- rtsk_treeseq_load(ts_file) ts <- ts_load(ts_file) - n_xptr_tc <- tc_xptr_summary(tc_xptr) - n_xptr_ts <- ts_xptr_summary(ts_xptr) + n_xptr_tc <- rtsk_table_collection_summary(tc_xptr) + n_xptr_ts <- rtsk_treeseq_summary(ts_xptr) shared_items <- c( "num_provenances", "num_populations", @@ -879,12 +896,12 @@ test_that("ts/tc_load(), ts/tc_summary*(), and ts/tc_dump(x) work", { ) expect_equal(n_xptr_ts[shared_items], n_xptr_tc[shared_items]) - m_xptr_tc <- tc_xptr_metadata_length(tc_xptr) - m_xptr_ts <- ts_xptr_metadata_length(ts_xptr) + m_xptr_tc <- rtsk_table_collection_metadata_length(tc_xptr) + m_xptr_ts <- rtsk_treeseq_metadata_length(ts_xptr) names(m_xptr_tc)[1] <- "ts" expect_equal(m_xptr_tc, m_xptr_ts) - p_xptr <- tc_xptr_print(tc_xptr) + p_xptr <- rtsk_table_collection_print(tc_xptr) # jarl-ignore implicit_assignment: it's just a test tmp <- capture.output(p <- tc$print()) expect_equal( diff --git a/RcppTskit/tests/testthat/test_r_to_py_and_py_to_r.R b/RcppTskit/tests/testthat/test_r_to_py_and_py_to_r.R index c44a07a..e4baf16 100644 --- a/RcppTskit/tests/testthat/test_r_to_py_and_py_to_r.R +++ b/RcppTskit/tests/testthat/test_r_to_py_and_py_to_r.R @@ -15,8 +15,8 @@ test_that("ts_r_to_py() and ts_py_to_r() work", { ts_file <- system.file("examples/test.trees", package = "RcppTskit") ts_r <- ts_load(ts_file) - n <- ts_xptr_summary(ts_r$pointer) - m <- ts_xptr_metadata_length(ts_r$pointer) + n <- rtsk_treeseq_summary(ts_r$xptr) + m <- rtsk_treeseq_metadata_length(ts_r$xptr) expect_error( ts_r$r_to_py(tskit_module = "bla"), @@ -61,14 +61,14 @@ test_that("ts_r_to_py() and ts_py_to_r() work", { expect_equal(length(ts_py$tables$mutations$metadata), m$mutations) expect_error( - ts_xptr_r_to_py("not_an_externalptr_object"), + rtsk_treeseq_r_to_py("not_an_externalptr_object"), regexp = "ts must be an object of externalptr class!" ) expect_error( - ts_xptr_r_to_py(ts_r$pointer, tskit_module = "not_a_module"), + rtsk_treeseq_r_to_py(ts_r$xptr, tskit_module = "not_a_module"), regexp = "object must be a reticulate Python module object!" ) - ts_py <- ts_xptr_r_to_py(ts_r$pointer) + ts_py <- rtsk_treeseq_r_to_py(ts_r$xptr) # Simple comparison of summaries and of the lengths of metadata expect_equal(ts_py$num_provenances, n$num_provenances) @@ -97,7 +97,7 @@ test_that("ts_r_to_py() and ts_py_to_r() work", { # ---- ts_py_to_r() ---- expect_error( - ts_xptr_py_to_r(1L), + rtsk_treeseq_py_to_r(1L), regexp = "ts must be a reticulate Python object!" ) expect_error( @@ -105,7 +105,7 @@ test_that("ts_r_to_py() and ts_py_to_r() work", { regexp = "ts must be a reticulate Python object!" ) expect_error( - ts_xptr_py_to_r(ts_r), + rtsk_treeseq_py_to_r(ts_r), regexp = "ts must be a reticulate Python object!" ) expect_error( @@ -113,10 +113,10 @@ test_that("ts_r_to_py() and ts_py_to_r() work", { regexp = "ts must be a reticulate Python object!" ) ts2_py <- ts_py$simplify(samples = c(0L, 1L, 2L, 3L)) - ts_xptr2_r <- ts_xptr_py_to_r(ts2_py) + ts_xptr2_r <- rtsk_treeseq_py_to_r(ts2_py) ts2_r <- ts_py_to_r(ts2_py) - n2 <- ts_xptr_summary(ts_xptr2_r) - m2 <- ts_xptr_metadata_length(ts_xptr2_r) + n2 <- rtsk_treeseq_summary(ts_xptr2_r) + m2 <- rtsk_treeseq_metadata_length(ts_xptr2_r) # Simple comparison of summaries and of the lengths of metadata expect_equal(ts2_py$num_provenances, n2$num_provenances) @@ -145,7 +145,7 @@ test_that("ts_r_to_py() and ts_py_to_r() work", { # jarl-ignore implicit_assignment: it's just a test tmp <- capture.output(ts2_r_print <- ts2_r$print()) # jarl-ignore implicit_assignment: it's just a test - tmp <- capture.output(ts_xptr2_r_print <- ts_xptr_print(ts_xptr2_r)) + tmp <- capture.output(ts_xptr2_r_print <- rtsk_treeseq_print(ts_xptr2_r)) sel <- ts2_r_print$ts$property == "file_uuid" ts2_r_print$ts$value[sel] <- NA_character_ sel <- ts_xptr2_r_print$ts$property == "file_uuid" @@ -160,8 +160,8 @@ test_that("tc_r_to_py() and tc_py_to_r() work", { ts_file <- system.file("examples/test.trees", package = "RcppTskit") tc_r <- tc_load(ts_file) - n <- tc_xptr_summary(tc_r$pointer) - m <- tc_xptr_metadata_length(tc_r$pointer) + n <- rtsk_table_collection_summary(tc_r$xptr) + m <- rtsk_table_collection_metadata_length(tc_r$xptr) expect_error( tc_r$r_to_py(tskit_module = "bla"), @@ -191,14 +191,14 @@ test_that("tc_r_to_py() and tc_py_to_r() work", { expect_equal(length(tc_py$mutations$metadata), m$mutations) expect_error( - tc_xptr_r_to_py("not_an_externalptr_object"), + rtsk_table_collection_r_to_py("not_an_externalptr_object"), regexp = "tc must be an object of externalptr class!" ) expect_error( - tc_xptr_r_to_py(tc_r$pointer, tskit_module = "not_a_module"), + rtsk_table_collection_r_to_py(tc_r$xptr, tskit_module = "not_a_module"), regexp = "object must be a reticulate Python module object!" ) - tc_py <- tc_xptr_r_to_py(tc_r$pointer) + tc_py <- rtsk_table_collection_r_to_py(tc_r$xptr) # Simple comparison of summaries and of the lengths of metadata expect_equal(tc_py$provenances$num_rows, n$num_provenances) @@ -224,7 +224,7 @@ test_that("tc_r_to_py() and tc_py_to_r() work", { # ---- tc_py_to_r() ---- expect_error( - tc_xptr_py_to_r(1L), + rtsk_table_collection_py_to_r(1L), regexp = "tc must be a reticulate Python object!" ) expect_error( @@ -232,7 +232,7 @@ test_that("tc_r_to_py() and tc_py_to_r() work", { regexp = "tc must be a reticulate Python object!" ) expect_error( - tc_xptr_py_to_r(tc_r), + rtsk_table_collection_py_to_r(tc_r), regexp = "tc must be a reticulate Python object!" ) expect_error( @@ -243,10 +243,10 @@ test_that("tc_r_to_py() and tc_py_to_r() work", { tskit <- get_tskit_py() ts2_py <- tskit$load(ts_file)$simplify(samples = c(0L, 1L, 2L, 3L)) tc2_py <- ts2_py$dump_tables() - tc_xptr2_r <- tc_xptr_py_to_r(tc2_py) + tc_xptr2_r <- rtsk_table_collection_py_to_r(tc2_py) tc2_r <- tc_py_to_r(tc2_py) - n2 <- tc_xptr_summary(tc_xptr2_r) - m2 <- tc_xptr_metadata_length(tc_xptr2_r) + n2 <- rtsk_table_collection_summary(tc_xptr2_r) + m2 <- rtsk_table_collection_metadata_length(tc_xptr2_r) # Simple comparison of summaries and of the lengths of metadata expect_equal(tc2_py$provenances$num_rows, n2$num_provenances) @@ -273,7 +273,7 @@ test_that("tc_r_to_py() and tc_py_to_r() work", { # jarl-ignore implicit_assignment: it's just a test tmp <- capture.output(tc2_r_print <- tc2_r$print()) # jarl-ignore implicit_assignment: it's just a test - tmp <- capture.output(tc_xptr2_r <- tc_xptr_print(tc_xptr2_r)) + tmp <- capture.output(tc_xptr2_r <- rtsk_table_collection_print(tc_xptr2_r)) sel <- tc2_r_print$tc$property == "file_uuid" tc2_r_print$tc$value[sel] <- NA_character_ sel <- tc_xptr2_r$tc$property == "file_uuid" diff --git a/RcppTskit/tools/check_sync_between_cpp_and_hpp.R b/RcppTskit/tools/check_sync_between_cpp_and_hpp.R new file mode 100755 index 0000000..4b54985 --- /dev/null +++ b/RcppTskit/tools/check_sync_between_cpp_and_hpp.R @@ -0,0 +1,141 @@ +#!/usr/bin/env Rscript + +header_path <- "RcppTskit/inst/include/RcppTskit_public.hpp" +source_path <- "RcppTskit/src/RcppTskit.cpp" + +extract_options_defaults <- function(path, signature_pattern) { + text <- paste(readLines(path, warn = FALSE), collapse = "\n") + matches <- gregexpr(signature_pattern, text, perl = TRUE)[[1]] + + if (identical(matches, -1L)) { + return(structure(integer(), names = character())) + } + + signatures <- regmatches(text, list(matches))[[1]] + defaults <- list() + + capture_first_group <- function(string, pattern) { + match <- regexpr(pattern, string, perl = TRUE) + if (match[[1]] == -1L) { + return(NA_character_) + } + starts <- attr(match, "capture.start") + lengths <- attr(match, "capture.length") + if (is.null(starts) || is.null(lengths) || starts[1, 1] == -1L) { + return(NA_character_) + } + substr(string, starts[1, 1], starts[1, 1] + lengths[1, 1] - 1L) + } + + for (signature in signatures) { + if (!grepl("\\boptions\\s*=", signature, perl = TRUE)) { + next + } + + name <- capture_first_group( + signature, + "^[[:space:]]*(?:SEXP|void)\\s+([A-Za-z_][A-Za-z0-9_]*)\\s*\\(" + ) + default_text <- capture_first_group( + signature, + "\\boptions\\s*=\\s*([0-9]+)\\b" + ) + if (is.na(name) || is.na(default_text)) { + next + } + default <- as.integer(default_text) + defaults[[name]] <- default + } + + if (length(defaults) == 0L) { + return(structure(integer(), names = character())) + } + + values <- unlist(defaults, use.names = TRUE) + storage.mode(values) <- "integer" + values +} + +stop_with <- function(lines) { + cat(paste0(lines, collapse = "\n"), "\n") + quit(save = "no", status = 1L) +} + +if (!file.exists(header_path)) { + stop_with(c("ERROR: Missing header file:", paste0(" - ", header_path))) +} +if (!file.exists(source_path)) { + stop_with(c("ERROR: Missing source file:", paste0(" - ", source_path))) +} + +header_defaults <- extract_options_defaults( + header_path, + "(?:SEXP|void)\\s+[A-Za-z_][A-Za-z0-9_]*\\s*\\([^;{}]*?\\)\\s*;" +) +source_defaults <- extract_options_defaults( + source_path, + "(?:SEXP|void)\\s+[A-Za-z_][A-Za-z0-9_]*\\s*\\([^;{}]*?\\)\\s*\\{" +) + +if (length(header_defaults) == 0L || length(source_defaults) == 0L) { + stop_with(c( + "ERROR: Could not parse function defaults for `options`.", + " Update check_sync_between_cpp_and_hpp.R if function signatures changed." + )) +} + +missing_in_header <- setdiff(names(source_defaults), names(header_defaults)) +missing_in_source <- setdiff(names(header_defaults), names(source_defaults)) +common <- intersect(names(header_defaults), names(source_defaults)) +mismatched <- common[header_defaults[common] != source_defaults[common]] + +problems <- character() + +if (length(missing_in_header) > 0L) { + problems <- c( + problems, + "ERROR: Functions with `options` defaults found in .cpp but missing in .hpp:", + paste0(" - ", sort(missing_in_header)) + ) +} +if (length(missing_in_source) > 0L) { + problems <- c( + problems, + "ERROR: Functions with `options` defaults found in .hpp but missing in .cpp:", + paste0(" - ", sort(missing_in_source)) + ) +} +if (length(mismatched) > 0L) { + problems <- c( + problems, + "ERROR: Mismatched `options` defaults between .hpp and .cpp:" + ) + for (name in sort(mismatched)) { + problems <- c( + problems, + sprintf( + " - %s: header=%d, source=%d", + name, + header_defaults[[name]], + source_defaults[[name]] + ) + ) + } +} + +if (length(problems) > 0L) { + stop_with(c( + problems, + "", + "Keep defaults in sync between:", + paste0(" - ", header_path), + paste0(" - ", source_path) + )) +} + +cat( + sprintf( + "OK: %d function default(s) for `options` are in sync between .hpp and .cpp.\n", + length(common) + ) +) diff --git a/RcppTskit/tools/clang-tidy.py b/RcppTskit/tools/clang_tidy.py similarity index 100% rename from RcppTskit/tools/clang-tidy.py rename to RcppTskit/tools/clang_tidy.py diff --git a/RcppTskit/tools/run-local-tool.sh b/RcppTskit/tools/run_local_tool.sh similarity index 100% rename from RcppTskit/tools/run-local-tool.sh rename to RcppTskit/tools/run_local_tool.sh diff --git a/RcppTskit/vignettes/RcppTskit_intro.qmd b/RcppTskit/vignettes/RcppTskit_intro.qmd index 45d1bbb..5b1e958 100644 --- a/RcppTskit/vignettes/RcppTskit_intro.qmd +++ b/RcppTskit/vignettes/RcppTskit_intro.qmd @@ -42,15 +42,13 @@ With this in mind, [@jeffrey2026population], for cases where the `reticulate` option is not optimal; for example, high-performance or low-level work with tree sequences. -As a result, `RcppTskit` currently provides a limited set of `R` functions +As a result, `RcppTskit` currently provides a limited set of functions because the `Python` API (and `reticulate`) already covers most needs. As the name suggests, `RcppTskit` leverages the `R` package `Rcpp` [@eddelbuettel2026rcpp] , -which significantly lowers the barrier to using `C++` in `R`. +which significantly lowers the barrier to using `C++` with `R`. However, we still need to write `C++` wrappers and expose them to `R`, so we recommend using `reticulate` first. -The implemented `R` functions in `RcppTskit` closely mimic -`tskit Python` functions to streamline the use of both the `R` and `Python` APIs. ## State of the tree sequence ecosystem @@ -158,31 +156,34 @@ The four typical use cases are: 4. Call the `tskit C` API from `C++` in another `R` package. Examples for all of these cases are provided below -after we describe the implemented data and class model. +after we describe the implemented data and class model, +and API mirroring across the languages. ## Data and class model `RcppTskit` represents a tree sequence as a lightweight `R6` object of class `TreeSequence`. -The `R6` class was chosen in part so that `TreeSequence` method calls in `R` +The `R6` interface is used so that `TreeSequence` method calls in `R` resemble the `tskit Python` API, particularly when compared to reticulate `Python`. -`TreeSequence` wraps an external pointer (`externalptr`) to -the `tskit C` object structure `tsk_treeseq_t`. +Internally, `TreeSequence` stores an external pointer (`externalptr`) +to a heap-allocated object `tsk_treeseq_t` +from the `tskit C` API. + Most methods (for example, `ts$num_individuals()` and `ts$dump()`) call the `tskit C` API via `Rcpp`, so the calls are fast. -The underlying pointer is exposed as `TreeSequence$pointer` +The external pointer is exposed as `TreeSequence$xptr` for developers and advanced users who work with `C++`. -In `C++`, the pointer has type `RcppTskit_treeseq_xptr`, +In `C++`, the external pointer has type `rtsk_treeseq_t`, and the tree sequence memory is released by the `Rcpp::XPtr` finaliser when the pointer is garbage-collected in `R`. `RcppTskit` also provides a lightweight `TableCollection` `R6` class, -which wraps an an external pointer to the `tskit C` object structure -`tsk_table_collection_t`. -In `C++`, the pointer has type `RcppTskit_table_collection_xptr` with -the same memory management as `RcppTskit_treeseq_xptr`. +which stores an external pointer to a heap-allocated object +`tsk_table_collection_t` from the `tskit C` API. +In `C++`, the external pointer has type `rtsk_table_collection_t` +with the same memory management as `rtsk_treeseq_t`. While tree sequence (`tsk_treeseq_t`) is an immutable object, table collection (`tsk_table_collection_t`) is a mutable object, @@ -190,6 +191,23 @@ which can be edited. No `R` functions for expanding and editing are implemented to date, so all editing should happen in `C/C++` or `Python`. +## API mirroring across the languages + +The provided `RcppTskit R` API mirrors the `tskit Python` API, +while . + +`RcppTskit` aims to keep naming, arguments, defaults, and behaviour aligned +with upstream `tskit` APIs whenever practical. +Specifically, +the provided `RcppTskit R` API mirrors the `tskit Python` API, +that is the functions and `R6` classes (with their methods) aim to mirror +`tskit Python` functions and classes (with their methods). +Note that the `RcppTskit R` API is far more limited than the `tskit Python` API. +The `RcppTskit C++` API aims to mirror the `tskit C` API functions and semantics, +but is deliberately `R` oriented +When we intentionally deviate (for example, to support `R` idioms or safety), +we document the rationale and test the chosen behaviour. + ## Four typical use cases First install `RcppTskit` from CRAN and load it. @@ -305,7 +323,7 @@ if (check_tskit_py(tskit)) { codeString <- ' #include int ts_num_individuals(SEXP ts) { - RcppTskit_treeseq_xptr ts_xptr(ts); + rtsk_treeseq_t ts_xptr(ts); return (int) tsk_treeseq_get_num_individuals(ts_xptr); }' @@ -323,7 +341,7 @@ ts <- ts_load(ts_file) # Apply the compiled function # (on the pointer) -ts_num_individuals2(ts$pointer) +ts_num_individuals2(ts$xptr) # An identical RcppTskit implementation # (available as the method of the TreeSequence class) @@ -333,10 +351,14 @@ ts$num_individuals() ### 4) Call the `tskit C` API from `C++` in another `R` package To call the `tskit C` API in your own `R` package via `Rcpp` -you can leverage `RcppTskit`, which simplifies installation -and provides the linking flags you need. -To do this, follow the steps below and check how these are implemented in -the demo `R` package `RcppTskitTestLinkingTo` at +you can leverage `RcppTskit`, +which simplifies installation, +provides the required linking flags, +bootstraps your work by providing some `RcppTskit C++` functions +that interface `tskit C` API and `R`, etc. +To leverage `RcppTskit`, +follow the steps below and check how they are implemented in +the demo `R` package `RcppTskitTestLinking` at . a) Open the `DESCRIPTION` file and @@ -376,7 +398,7 @@ h) You should now be ready to build, check, and install your package using `devtools::build()`, `devtools::check()`, and `devtools::install()` or their `R CMD` equivalents. -Here is code you can run to check out `RcppTskitTestLinkingTo`: +Here is code you can run to check out `RcppTskitTestLinking`: ```{r} #| label: use_case_4 @@ -386,7 +408,7 @@ remotes::install_github("HighlanderLab/RcppTskitTestLinking") library(RcppTskitTestLinking) # Check the demo function -print(ts_xptr_num_individuals2) +print(rtsk_treeseq_get_num_individuals2) # Example tree sequence ts_file <- system.file("examples", "test.trees", package = "RcppTskit") @@ -396,19 +418,19 @@ ts <- ts_load(ts_file) ts$num_individuals() # Function from RcppTskitTestLinking (working with externalptr) -ts_xptr_num_individuals2(ts$pointer) +rtsk_treeseq_get_num_individuals2(ts$xptr) ``` ## Conclusion `RcppTskit` provides `R` access to the `tskit C` API with a simple installation and a lightweight interface. -It provides a limited number of `R` functions because most users can and should use -`reticulate` to call the `tskit` `Python` API from `R`. -The implemented `R` functions closely mimic `tskit` `Python` functions -to streamline the use of both the `R` and `Python` APIs. -When this option is not optimal, developers and advanced users can call -the `tskit C` API via `Rcpp`. +It provides a limited number of functions because most users can and should use +`reticulate` to call the `tskit Python` API from `R`. +The implemented `RcppTskit R` API closely mimics `tskit Python` API +to streamline their use. +When this option is not optimal, developers and advanced users +can easily use the `RcppTskit C++` API and `tskit C` API. ## Session information