@@ -131,6 +131,165 @@ TableCollection <- R6Class(
131131 )
132132 },
133133
134+ # ' @description Simplify this table collection in place.
135+ # ' @param samples optional integer vector of node IDs to retain as samples.
136+ # ' If \code{NULL}, use nodes currently marked with sample flags.
137+ # ' @param reduce_to_site_topology logical; if \code{TRUE}, keep only
138+ # ' topology needed for trees containing sites.
139+ # ' @param filter_populations optional logical; if \code{NULL}, treated as
140+ # ' \code{TRUE}.
141+ # ' @param filter_individuals optional logical; if \code{NULL}, treated as
142+ # ' \code{TRUE}.
143+ # ' @param filter_sites optional logical; if \code{NULL}, treated as
144+ # ' \code{TRUE}.
145+ # ' @param filter_nodes optional logical; if \code{NULL}, treated as
146+ # ' \code{TRUE}.
147+ # ' @param update_sample_flags optional logical; if \code{NULL}, treated as
148+ # ' \code{TRUE}.
149+ # ' @param keep_unary logical; if \code{TRUE}, keep unary nodes.
150+ # ' @param keep_unary_in_individuals optional logical; if \code{NULL},
151+ # ' treated as \code{FALSE}.
152+ # ' @param keep_input_roots logical; if \code{TRUE}, keep input roots.
153+ # ' @param record_provenance logical; if \code{TRUE}, append a provenance row
154+ # ' describing the simplify command.
155+ # ' @param filter_zero_mutation_sites deprecated alias for
156+ # ' \code{filter_sites}.
157+ # ' @details See the \code{tskit Python} equivalent at
158+ # ' \url{https://tskit.dev/tskit/docs/stable/python-api.html#tskit.TableCollection.simplify}.
159+ # ' @return Integer vector mapping input node IDs to simplified node IDs.
160+ # ' Dropped nodes map to \code{-1}.
161+ # ' @examples
162+ # ' ts_file <- system.file("examples/test.trees", package = "RcppTskit")
163+ # ' tc <- tc_load(ts_file)
164+ # ' node_map <- tc$simplify(samples = c(0L, 1L, 2L, 3L))
165+ # ' is.integer(node_map)
166+ simplify = function (
167+ samples = NULL ,
168+ reduce_to_site_topology = FALSE ,
169+ filter_populations = NULL ,
170+ filter_individuals = NULL ,
171+ filter_sites = NULL ,
172+ filter_nodes = NULL ,
173+ update_sample_flags = NULL ,
174+ keep_unary = FALSE ,
175+ keep_unary_in_individuals = NULL ,
176+ keep_input_roots = FALSE ,
177+ record_provenance = TRUE ,
178+ filter_zero_mutation_sites = NULL
179+ ) {
180+ if (! is.null(samples )) {
181+ validate_optional_integer_vector_arg(samples , " samples" )
182+ samples <- as.integer(samples )
183+ }
184+ validate_logical_arg(reduce_to_site_topology , " reduce_to_site_topology" )
185+ validate_logical_arg(keep_unary , " keep_unary" )
186+ validate_logical_arg(keep_input_roots , " keep_input_roots" )
187+ validate_logical_arg(record_provenance , " record_provenance" )
188+
189+ if (! is.null(filter_zero_mutation_sites )) {
190+ validate_logical_arg(
191+ filter_zero_mutation_sites ,
192+ " filter_zero_mutation_sites"
193+ )
194+ if (
195+ ! is.null(filter_sites ) &&
196+ ! identical(filter_sites , filter_zero_mutation_sites )
197+ ) {
198+ stop(" filter_sites and filter_zero_mutation_sites are inconsistent!" )
199+ }
200+ warning(
201+ " filter_zero_mutation_sites is deprecated; use filter_sites" ,
202+ call. = FALSE
203+ )
204+ filter_sites <- filter_zero_mutation_sites
205+ }
206+
207+ resolve_optional_logical <- function (value , name , default ) {
208+ if (is.null(value )) {
209+ return (default )
210+ }
211+ validate_logical_arg(value , name )
212+ return (value )
213+ }
214+
215+ filter_populations <- resolve_optional_logical(
216+ filter_populations ,
217+ " filter_populations" ,
218+ TRUE
219+ )
220+ filter_individuals <- resolve_optional_logical(
221+ filter_individuals ,
222+ " filter_individuals" ,
223+ TRUE
224+ )
225+ filter_sites <- resolve_optional_logical(
226+ filter_sites ,
227+ " filter_sites" ,
228+ TRUE
229+ )
230+ filter_nodes <- resolve_optional_logical(
231+ filter_nodes ,
232+ " filter_nodes" ,
233+ TRUE
234+ )
235+ update_sample_flags <- resolve_optional_logical(
236+ update_sample_flags ,
237+ " update_sample_flags" ,
238+ TRUE
239+ )
240+ keep_unary_in_individuals <- resolve_optional_logical(
241+ keep_unary_in_individuals ,
242+ " keep_unary_in_individuals" ,
243+ FALSE
244+ )
245+
246+ if (keep_unary && keep_unary_in_individuals ) {
247+ stop(" keep_unary and keep_unary_in_individuals cannot both be TRUE!" )
248+ }
249+
250+ options <- 0L
251+ if (filter_sites ) {
252+ options <- bitwOr(options , bitwShiftL(1L , 0 ))
253+ }
254+ if (filter_populations ) {
255+ options <- bitwOr(options , bitwShiftL(1L , 1 ))
256+ }
257+ if (filter_individuals ) {
258+ options <- bitwOr(options , bitwShiftL(1L , 2 ))
259+ }
260+ if (reduce_to_site_topology ) {
261+ options <- bitwOr(options , bitwShiftL(1L , 3 ))
262+ }
263+ if (keep_unary ) {
264+ options <- bitwOr(options , bitwShiftL(1L , 4 ))
265+ }
266+ if (keep_input_roots ) {
267+ options <- bitwOr(options , bitwShiftL(1L , 5 ))
268+ }
269+ if (keep_unary_in_individuals ) {
270+ options <- bitwOr(options , bitwShiftL(1L , 6 ))
271+ }
272+ if (! filter_nodes ) {
273+ options <- bitwOr(options , bitwShiftL(1L , 7 ))
274+ }
275+ if (! update_sample_flags ) {
276+ options <- bitwOr(options , bitwShiftL(1L , 8 ))
277+ }
278+
279+ node_map <- rtsk_table_collection_simplify(
280+ tc = self $ xptr ,
281+ samples = samples ,
282+ options = options
283+ )
284+
285+ if (record_provenance ) {
286+ self $ provenance_table_add_row(
287+ record = " {\" command\" :\" simplify\" ,\" TODO\" :\" add simplify parameters\" }"
288+ )
289+ }
290+ return (node_map )
291+ },
292+
134293 # ' @description Get the number of provenances in a table collection.
135294 # ' @return A signed 64 bit integer \code{bit64::integer64}.
136295 # ' @examples
0 commit comments