Skip to contents

Repeatedly simulate null datasets from a createSimulationTemplate() object and analyze each replicate with searchOptimalConfiguration() to estimate the expected false-positive behavior of a candidate bifrost search setup.

Usage

runFalsePositiveSimulationStudy(
  template,
  n_replicates,
  tree_tip_count = NULL,
  simulation_options = list(),
  search_options = list(),
  num_cores = 1,
  seed = NULL
)

Arguments

template

A bifrost_simulation_template returned by createSimulationTemplate().

n_replicates

Integer number of simulation replicates to run.

tree_tip_count

Optional integer tip count for random subtree sampling. If NULL, each replicate uses the full empirical tree.

simulation_options

Named list of additional arguments passed to simulateNullDataset(), including simulation_generator and covariance_df. The manuscript-compatible "original" generator is used by default; request simulation_generator = "empirical" for full-covariance draws. The simulation_generator entry must contain exactly one supported string. For replicated studies, simulation_options$seed is not allowed; use the wrapper-level seed argument instead.

search_options

Named list of arguments passed to searchOptimalConfiguration(). These override the default response-only intercept-only search settings assembled from template. If formula is omitted, the wrapper inherits template$search_formula, which is intercept-only in the empirically calibrated simulation workflow.

num_cores

Integer number of workers used across replicate analyses. When greater than one, outer replicate parallelism takes precedence and each inner search is forced to search_options$num_cores = 1.

seed

Optional integer random seed. When supplied, the wrapper restores the caller's previous RNG state before returning.

Value

A list of class bifrost_simulation_study containing the simulated datasets, raw search results, a per-replicate summary table, and a compact study-level summary for the null scenario.

Details

Simulated datasets, search results, a per-replicate summary table, and a compact study summary are returned in a single object of class bifrost_simulation_study.

Regardless of the global calibration model used to build template, the downstream search is intentionally restricted to intercept-only formulas. This keeps the simulation study focused on branch-shift detection in the response block, matching the residual-calibration logic. The simulated trait_data supplied to each search result therefore contains only the regenerated response variables. Templates calibrated with covariates are supported; those covariates influence the fitted means and residual covariance used to generate each response block, but they are not re-fit within each simulated search replicate.

Failed search replicates are retained in the output, but their inferred-shift and false-positive metrics are recorded as NA and excluded from scientific summaries. Their error messages and candidate counts remain available for diagnosis, and completion and failure rates are reported separately. Reproducibility for replicated studies is controlled by the wrapper-level seed argument. A supplied seed deterministically creates separate per-replicate simulation and search streams, so serial and parallel runs use the same replicate-level random draws. Parallel execution also uses future.seed = TRUE; per-replicate simulator seeds are intentionally disallowed here. If no replicate yields an evaluable false-positive rate, the study-level mean and median false-positive summaries are returned as NA.

Examples

if (FALSE) { # \dontrun{
set.seed(1)
tr <- ape::rtree(30)
X <- matrix(rnorm(30 * 3), ncol = 3)
rownames(X) <- tr$tip.label
tmpl <- createSimulationTemplate(tr, X, formula = "trait_data ~ 1", method = "LL")

fp_study <- runFalsePositiveSimulationStudy(
  tmpl,
  n_replicates = 2,
  tree_tip_count = 20,
  search_options = list(
    formula = "trait_data ~ 1",
    min_descendant_tips = 3,
    shift_acceptance_threshold = 5,
    num_cores = 1,
    IC = "GIC",
    method = "LL"
  ),
  num_cores = 1,
  seed = 2
)

fp_study
} # }