diff --git a/.positai/plans/2026-03-19-1938-cid-optimal-consensus-tree-search-t-150.md b/.positai/plans/2026-03-19-1938-cid-optimal-consensus-tree-search-t-150.md new file mode 100644 index 000000000..ad1661a0f --- /dev/null +++ b/.positai/plans/2026-03-19-1938-cid-optimal-consensus-tree-search-t-150.md @@ -0,0 +1,253 @@ +# Plan: CID-Optimal Consensus Tree Search (T-150) + +**Date:** 2026-03-19 +**Task:** T-150 — CID-optimal consensus tree search +**Branch:** `feature/cid-consensus` + +--- + +## Goal + +Implement `CIDConsensus()`: a function that finds a consensus tree minimizing +mean Clustering Information Distance (CID) to a set of input trees, using +TreeSearch's existing R-level search infrastructure (`TreeSearch()`, `Ratchet()`, +`EdgeListSearch()`) with a custom CID scorer. + +The proof of concept (briefing-cid-consensus.md) showed CID hill-climbing from +a transfer consensus reduces mean CID from 3.03 (MR) / 2.85 (TC) to **2.16** +on a 20-tip test case. + +--- + +## Architecture + +Plug into the existing `TreeScorer` / `EdgeSwapper` / `Bootstrapper` interfaces: + +``` +CIDConsensus(trees, ...) + → Ratchet(startTree, cidData, + InitializeData = identity, + CleanUpData = .NoOp, + TreeScorer = .CIDScorer, + Bootstrapper = .CIDBootstrap, + swappers = list(RootedTBRSwap, RootedSPRSwap, RootedNNISwap)) +``` + +**Dataset representation:** An environment (reference semantics) containing: +- `$trees` — the input `multiPhylo` +- `$tipLabels` — shared tip labels +- `$nTip` — number of tips +- `$metric` — distance function (default: `ClusteringInfoDistance`) + +Using an environment allows `CIDBootstrap` to temporarily swap the tree list +(resample with replacement) without copying large objects. + +--- + +## Phases + +### Phase 1: Core CID consensus (binary trees) + +Use the existing `Ratchet()` / `TreeSearch()` on **binary** trees with CID +scoring. This alone delivered the POC's best result (2.16 CID via SPR from TC). + +#### New file: `R/CIDConsensus.R` + +**Exported:** + +| Function | Purpose | +|----------|---------| +| `CIDConsensus(trees, ...)` | Main user-facing function | + +**Internal:** + +| Function | Purpose | +|----------|---------| +| `.CIDScorer(parent, child, dataset, ...)` | TreeScorer: build phylo, compute `mean(metric(candidate, trees))` | +| `.MakeCIDData(trees, metric)` | Create env with trees, tipLabels, metric | +| `.CIDBootstrap(edgeList, cidData, ...)` | Bootstrapper: resample input trees, search, restore | +| `.EdgeListToPhylo(parent, child, tipLabels)` | Helper: parent/child → phylo object | + +**`CIDConsensus()` signature:** + +```r +CIDConsensus <- function( + trees, + metric = ClusteringInfoDistance, + start = NULL, # phylo, or NULL → majority rule consensus + method = c("ratchet", "spr", "tbr", "nni"), + ratchIter = 100L, + ratchHits = 10L, + searchIter = 500L, + searchHits = 20L, + verbosity = 1L, + ... +) +``` + +**Design decisions:** + +1. **`start = NULL`** defaults to `MakeTreeBinary(Consensus(trees, p = 0.5))`. + Uses `TreeTools::Consensus` (rooted, Day 1985) and + `TreeTools::MakeTreeBinary` (uniform topology sampling, no spurious + zero-length edges). User can pass any phylo (e.g., a transfer consensus + from TreeDist dev). Starting tree is always resolved with + `MakeTreeBinary()` for Phase 1. + +2. **`method = "ratchet"`** is the default. Delegates to `Ratchet()` with + `CIDBootstrap` and `list(RootedTBRSwap, RootedSPRSwap, RootedNNISwap)`. + Other methods delegate to `TreeSearch()` with the corresponding swapper. + +3. **Lower default `searchIter`/`searchHits`** than parsimony (500/20 vs + 4000/42) because CID scoring is ~100× slower per candidate than Fitch. + +4. **`metric` parameter** allows swapping in `MutualClusteringInfo`, + `SharedPhylogeneticInfo`, or any function with signature `f(tree1, tree2)`. + Default is `ClusteringInfoDistance`. + +5. **Return value:** A `phylo` tree with attributes `"score"` (mean CID) + and `"hits"`. + +6. **`InitializeData = identity`**, **`CleanUpData`** = no-op function. + The dataset is the env created by `.MakeCIDData()`, passed directly. + +**`.CIDBootstrap()` design:** + +```r +.CIDBootstrap <- function(edgeList, cidData, EdgeSwapper, maxIter, + maxHits, verbosity, stopAtPeak, stopAtPlateau, ...) { + origTrees <- cidData$trees + nTree <- length(origTrees) + cidData$trees <- origTrees[sample.int(nTree, replace = TRUE)] + on.exit(cidData$trees <- origTrees) + res <- EdgeListSearch(edgeList[1:2], cidData, + TreeScorer = .CIDScorer, + EdgeSwapper = EdgeSwapper, + maxIter = maxIter, maxHits = maxHits, + verbosity = verbosity, + stopAtPeak = stopAtPeak, + stopAtPlateau = stopAtPlateau, ...) + res[1:2] +} +``` + +Resampling input trees with replacement is the CID analogue of character +bootstrapping — it perturbs the objective function to escape local optima. + +#### New file: `tests/testthat/test-CIDConsensus.R` + +Tier 2 (skip on CRAN). Tests: + +1. `.CIDScorer()` returns correct mean CID for a known tree/tree-set pair. +2. `.CIDBootstrap()` returns a valid edgeList (2 elements, valid topology). +3. `CIDConsensus()` with `method = "spr"` improves or equals starting score. +4. `CIDConsensus()` with `method = "ratchet"` runs without error on a small + case (10 tips, 20 trees, `ratchIter = 3`). +5. `CIDConsensus()` accepts a custom `metric` (e.g., `MutualClusteringInfo`). +6. `CIDConsensus()` rejects non-multiPhylo input. +7. Starting from user-supplied tree works. +8. Score attribute is set on returned tree. + +#### File modifications + +| File | Change | +|------|--------| +| `DESCRIPTION` | Add `CIDConsensus.R` to Collate field | +| `NAMESPACE` | `export(CIDConsensus)` + any new TreeDist imports | +| `R/CIDConsensus.R` | New file | +| `tests/testthat/test-CIDConsensus.R` | New file | + +### Phase 2: Collapse and Resolve moves (non-binary trees) + +Add EdgeSwapper functions that operate on potentially non-binary trees, +enabling the search to find partially-resolved consensus optima. + +#### New functions in `R/CIDConsensus.R`: + +| Function | Purpose | +|----------|---------| +| `.CollapseSwap(parent, child, nTip)` | Contract a random internal edge → polytomy | +| `.ResolveSwap(parent, child, nTip)` | Resolve a random polytomy → new binary split | +| `.CollapseAllSwap(parent, child, nTip)` | Return list of all single-collapse candidates | +| `.ResolveAllSwap(parent, child, nTip)` | Return list of all single-resolve candidates | + +**Collapse algorithm:** +1. Find internal edges (both endpoints > nTip, excluding root edge). +2. Pick one (random, or enumerate all with `edgeToBreak = -1`). +3. Reparent all children of the collapsed child node to its parent. +4. Remove the child node, renumber, return new parent/child. + +**Resolve algorithm:** +1. Find polytomy nodes (degree > 2 in parent vector). +2. Pick one polytomy node and two or more of its children. +3. Insert a new internal node as intermediate parent of the selected children. +4. Renumber, return new parent/child. + +**Search strategy with non-binary trees:** + +A new composite swapper `ConsensusSwap` tries three move types per iteration: +1. With probability p₁: collapse a random edge +2. With probability p₂: resolve a random polytomy +3. With probability p₃: SPR on the fully-resolved version + (temporarily resolve all polytomies, SPR, then re-collapse original polytomies) + +OR, simpler: use `Ratchet()` with a mixed swapper list: +```r +swappers = list( + .ResolveAndSPRSwap, # resolve → SPR (coarse) + .CollapseSwap, # collapse weak edges + .ResolveSwap # refine polytomies +) +``` + +The key insight: `RearrangeEdges()` and `EdgeListSearch()` don't enforce +bifurcation — only the existing `*Swap` functions do. New swappers that +handle polytomies plug in cleanly. + +**Updated `CIDConsensus()` behavior:** +When `start` is a non-binary tree (or when the search reaches a non-binary +optimum via collapse), the mixed swapper list is used automatically. + +#### Additional tests + +9. `.CollapseSwap()` produces valid non-binary topology. +10. `.ResolveSwap()` produces valid topology with one fewer polytomy degree. +11. Collapse then resolve is reversible (same split count). +12. CIDConsensus with collapse/resolve finds equal-or-better score than + binary-only search on a case where optimal consensus is non-binary. + +### Phase 3: Performance optimizations (stretch) + +Not blocking initial delivery; document as future work. + +- **Precompute per-tree split entropies** and cache in cidData to avoid + recomputation across candidates. +- **Parallel candidate evaluation**: `parallel::mclapply` or `future` + over candidates within `RearrangeEdges`. +- **C++ CID scorer**: Avoid R dispatch overhead by computing CID entirely + in C++ (would require porting LAP solver). + +--- + +## Implementation order + +1. Create `R/CIDConsensus.R` with Phase 1 functions. +2. Write `tests/testthat/test-CIDConsensus.R` (Tier 2). +3. Update `DESCRIPTION` (Collate) and `NAMESPACE`. +4. Run tests, verify on briefing's competing-topology example. +5. Add Phase 2 collapse/resolve functions. +6. Add Phase 2 tests. +7. Verify full search on non-binary case. +8. Update documentation/vignette. + +--- + +## Risks and mitigations + +| Risk | Mitigation | +|------|------------| +| CID scoring too slow for large trees (>50 tips, >200 input trees) | Lower default `searchIter`; document performance expectations; Phase 3 optimizations | +| SPR local optima on binary trees miss non-binary optimum | Phase 2 adds collapse/resolve; multi-start with `nSearch` parameter | +| `Ratchet()` bifurcation check (line 89-90) rejects non-binary trees | Phase 2: bypass by calling `EdgeListSearch` directly for non-binary case, or add a `bifurcating = TRUE` parameter | +| TreeDist `TransferConsensus` not yet on CRAN | Default start = majority rule via `TreeTools::Consensus`; user can pass any starting tree | +| Edge renumbering after collapse/resolve may break node numbering conventions | Use `ape::collapse.singles()` and `TreeTools::Renumber()` for canonicalization | diff --git a/.positai/plans/2026-03-20-0509-normalized-cid-consensus-with-rogue-taxon-dropping.md b/.positai/plans/2026-03-20-0509-normalized-cid-consensus-with-rogue-taxon-dropping.md new file mode 100644 index 000000000..2511415f4 --- /dev/null +++ b/.positai/plans/2026-03-20-0509-normalized-cid-consensus-with-rogue-taxon-dropping.md @@ -0,0 +1,149 @@ +# Plan: Normalized CID Consensus with Rogue Taxon Dropping + +**Date:** 2026-03-20 +**Status:** Empirical investigation complete; implementation in progress + +--- + +## Resolved Design Decisions + +### 1. Scoring formulation + +Add a `normalize` parameter (default `FALSE`): + +| Mode | Objective | Score formula (minimized) | Notes | +|------|-----------|---------------------------|-------| +| `normalize = FALSE` | Maximize total shared info | `-mean(MCI_i)` | Default; maximizes bits of input information captured | +| `normalize = TRUE` | Maximize fraction captured | `1 - mean(MCI_i / CE_i)` | Required for meaningful rogue dropping | + +**Fast path**: both modes use precomputed input splits and CEs. The +per-candidate loop computes `MCI_i` via `MutualClusteringInfoSplits()` +and either sums directly or divides by `CE_i`. Overhead: one extra +division per input tree when normalized. + +**Rationale** (from empirical testing on 50-tip/100-tree primates data): +- Raw CID (CE_cand + CE_i - 2*MCI) is NOT suitable as a scoring + objective for rogue dropping: 41/50 tips "improve" when dropped, + because fewer tips = less possible distance. +- `-mean(MCI)` maximizes information content directly. Dropping a tip + always loses some MCI, so rogue dropping is dubious without + normalization. +- `1 - mean(MCI/CE_i)` correctly identifies ~29/50 tips as beneficial + to drop. Rogue taxon 'r' in the toy example goes from 0.30 to 0.00. +- `-mean(MCI)` and `1 - mean(MCI/CE_i)` have rank correlation rho=0.06 + on random candidate topologies for a fixed tip set, so they genuinely + optimize for different things. The user should choose. + +### 2. neverDrop semantics + +| Value | Meaning | +|-------|---------| +| `TRUE` | No dropping; current behaviour | +| `FALSE` (default) | All taxa droppable | +| `character(...)` / `integer(...)` | Listed tips protected | + +If `neverDrop != TRUE` and `normalize = FALSE`, emit a warning that raw +MCI rogue dropping may not be meaningful. + +### 3. Pre-screening + +Tested two approaches on 50-tip / 100-tree primates data: + +| Method | Time | Spearman rho with marginal NID | +|--------|------|-------------------------------| +| **Marginal NID** (drop each tip, rescore) | 9.3 s | 1.0 (by definition) | +| **TipInstability** (Rogue package) | 0.04 s | 0.36 | + +TipInstability is a poor proxy (rho=0.36). Use marginal NID as the +primary pre-screen. For very large datasets (>200 tips), consider +TipInstability to narrow to top-k candidates, then marginal NID. + +### 4. Architecture: outer loop (not inner-loop move proposal) + +Rogue dropping is Phase 3, running after topology search + collapse/resolve. +Each accepted drop triggers a lighter re-optimization (half ratchet iters). +Trees with <8 tips skip Ratchet and use only collapse/resolve. + +This avoids EdgeSwapper interface changes and is sufficient: each drop +changes the landscape enough to warrant re-optimizing topology. + +--- + +## Empirical Results (primates 50-tip / 100-tree) + +### Greedy sequential dropping (normalized, from MR consensus) + +| Step | Taxon | Score (1-MCI/CE) | Tips | +|------|-------|-----------------|------| +| 0 | (start) | 0.4356 | 50 | +| 1 | Cercopithecus_mitis_stuhlmanni | 0.4193 | 49 | +| 2 | Cercopithecus_doggetti | 0.4049 | 48 | +| 3 | Cercopithecus_erythrotis_camerunensis | 0.3905 | 47 | +| 4 | Cercopithecus_roloway | 0.3783 | 46 | +| 5 | Cercopithecus_albogularis_francescae | 0.3666 | 45 | + +All top rogues are Cercopithecus species (biologically plausible: closely +related, branching order uncertain across bootstrap replicates). + +### Formulation agreement + +All three normalization schemes (raw CID, NVI, MCI/CE) agree on rogue +ranking with high Spearman correlation (0.91-0.97 between formulations). + +### CIDConsensus timing + +17s for 3 ratchet iterations on 50-tip x 100-tree data (raw CID mode). +Score improved from 20.60 (MR) to 11.57 (after collapse/resolve). + +--- + +## Implementation + +### Modified: `R/CIDConsensus.R` + +**New parameters:** +- `normalize = FALSE` in `CIDConsensus()` +- `neverDrop = FALSE` in `CIDConsensus()` + +**New internal functions:** +- `.TopologySearch()` -- factored out of `CIDConsensus()` for reuse +- `.RogueRefine()` -- Phase 3 outer loop +- `.PrescreenMarginalNID()` -- marginal NID pre-screen +- `.ScoreTree()` -- score a phylo against cidData +- `.PruneTrees()` -- drop tips from multiPhylo +- `.BestInsertion()` -- find best edge to graft a restored tip +- `.InsertTipAtEdge()` -- graft a tip onto a specific edge + +**Modified internal functions:** +- `.MakeCIDData()` -- gains `normalize` parameter +- `.CIDScorer()` -- supports both `-mean(MCI)` and `1-mean(MCI/CE_i)` +- `.CIDScoreFast()` -- same +- `.CIDBootstrap()` -- simplified (no `meanInputCE` to track) + +### Safety guards + +- Trees with <8 tips skip Ratchet re-optimization (only collapse/resolve) +- Re-optimization uses `ratchIter %/% 2` to avoid excessive compute +- Minimum 4 tips to allow dropping +- Warning when `neverDrop != TRUE` and `normalize = FALSE` + +--- + +## Test data + +Primates bootstrap trees (189 tips, 100 trees) from Takazawa et al. (2026) +PhyloCRISP repository, subsampled to 50 tips. + +Saved at: `inst/test-data/takazawa/primates_bootstrap.nw` +Reference: `inst/test-data/takazawa/primates_reference.nw` + +--- + +## Remaining work + +1. Write the implementation (code written but R session hung before testing) +2. Test on toy rogue example (both normalize modes) +3. Test on primates data (profile, compare normalize modes) +4. Add tests to `tests/testthat/test-CIDConsensus.R` +5. Update DESCRIPTION (Rogue to Suggests if TipInstability used) +6. Stretch: clade dropping (cherries with unstable position) diff --git a/.positai/plans/2026-03-20-1317-cid-scoring-via-c-driven-search-engine.md b/.positai/plans/2026-03-20-1317-cid-scoring-via-c-driven-search-engine.md new file mode 100644 index 000000000..b43e445cf --- /dev/null +++ b/.positai/plans/2026-03-20-1317-cid-scoring-via-c-driven-search-engine.md @@ -0,0 +1,380 @@ +# Plan: CID Scoring via C++ Driven Search Engine + +**Date:** 2026-03-20 +**Task:** Replace R-level `Ratchet()`/`TreeSearch()` backend for `CIDConsensus()` +with the C++ driven search engine (`ts_driven_search`). + +--- + +## Problem + +The R-level search is too slow due to: +1. R dispatch overhead per candidate (phylo construction, S3 dispatch for + `as.Splits()`, R-loop over input trees) +2. No incremental scoring (full CID recomputed for every TBR candidate) +3. No access to driven search machinery (sectorial search, drift, fusing, + multi-replicate parallelism, pool management) + +## Architecture: MRP Screening + CID Verification + +**Key insight:** The driven search already separates *screening* (incremental +Fitch scoring for candidate selection) from *verification* (`score_tree()` +for acceptance). HSJ and XFORM modes exploit this — screening uses Fitch on +standard characters; verification dispatches to the full composite scorer. + +We apply the same pattern: + +1. **MRP (Matrix Representation with Parsimony) characters** encode input tree + splits as binary Fitch characters. Each input tree's non-trivial splits + become binary characters (tip in smaller partition → state 1, else → 0). + With `n_trees` input trees × ~(`n_tips` - 3) splits each, we get a + synthetic phyDat of ~`n_trees * (n_tips - 3)` binary characters. + +2. **Incremental Fitch screening** on MRP characters provides a fast proxy: + MRP score = total incompatible splits across all input trees ≈ sum of + Robinson–Foulds distances / 2. This correlates strongly with CID and + supports the existing TBR indirect-scoring machinery. + +3. **CID verification** via `score_tree()` with `ScoringMode::CID` computes + the actual clustering information distance using TreeDist's C++ MCI + algorithm. Only called for the best TBR candidate per clip edge (same + pattern as HSJ/XFORM). + +### Benefits + +All driven search infrastructure works unchanged: + +| Component | CID mode behavior | +|-----------|-------------------| +| Wagner starting trees | MRP-optimal addition trees (diverse, fully resolved) | +| TBR hill-climbing | Incremental MRP screening + CID verification | +| Ratchet | Perturb MRP character weights + CID tree weights (see below) | +| Drift | Accept suboptimal CID moves within AFD/RFD limits | +| Sectorial search | XSS/RSS on MRP characters (CSS if beneficial) | +| Tree fusing | Exchange subtrees between pool members | +| Pool management | Dedup via split hashing, score-based eviction on CID score | +| Multi-replicate parallelism | `std::thread`, independent MRP datasets per thread | + +### Ratchet perturbation + +MRP characters are organized so that all characters from input tree `i` +occupy consecutive positions across one or more `CharBlock`s. During ratchet +perturbation: + +- Standard `perturb_*()` modifies `active_mask`/`upweight_mask` on MRP + blocks, affecting incremental screening. +- Additionally, `CidData::tree_weights[i]` is set to 0 (zeroed tree) or + 2.0 (upweighted tree) in tandem, so that `cid_score()` uses a perturbed + CID objective consistent with the MRP perturbation. +- `save_perturb_state()` / `restore_perturb_state()` extended to save/restore + `CidData::tree_weights`. + +This makes CID ratchet equivalent to the R-level `CIDBootstrap` (resample +input trees with replacement). + +--- + +## Phase 1: TreeDist header extraction + +TreeDist's MCI computation (`mutual_clustering()` in `tree_distances.cpp`) +and LAP solver (`lap.cpp`) are not currently exposed for `LinkingTo`. + +### New files in `../TreeDist/inst/include/TreeDist/` + +| File | Contents | Source | +|------|----------|--------| +| `types.h` | `cost`, `lap_dim`, `splitbit`, `int16`, `int32`, constants | `ints.h`, `lap.h` | +| `cost_matrix.h` | `CostMatrix` class | `lap.h` | +| `lap_scratch.h` | `LapScratch` struct | `lap.h` | +| `lap.h` | `lap()` declaration + convenience overload | `lap.h` | +| `mutual_clustering.h` | `mutual_clustering_score()` taking raw split arrays (not Rcpp types) | `tree_distances.cpp` lines 382–548 | +| `clustering_entropy.h` | `clustering_entropy()` from split sizes | inline, ~15 lines | + +The extracted headers must be **Rcpp-free** (pure C++ with ``, +``, ``) so that TreeSearch can include them without +pulling in Rcpp headers in its own TUs. + +**LAP implementation**: TreeSearch compiles its own copy of the LAP solver. +Options: +- (a) `inst/include/TreeDist/lap_impl.h` — header-only, guarded by + `TREEDIST_LAP_IMPLEMENTATION` define, included in exactly one TreeSearch TU. +- (b) TreeSearch copies `lap.cpp` into `src/ts_lap.cpp`. + +Option (a) is cleaner; option (b) is a fallback if alignment sensitivity +causes problems. + +**Lookup tables** (`lg2[]`, `lg2_rooted[]`, etc.): These use +`__attribute__((constructor))` for initialization. In the header, declare as +`extern`; provide initialization in a single TU (TreeSearch's `ts_cid.cpp`). + +### Changes to existing TreeDist source + +- `src/lap.h` → include from `` etc. (thin wrapper) +- `src/tree_distances.cpp` → call shared `mutual_clustering_score()` +- `src/tree_distances.h` → `#include ` etc. + +--- + +## Phase 2: TreeSearch C++ changes + +### 2a. New `ScoringMode::CID` + +In `ts_data.h`: +```cpp +enum class ScoringMode { EW, IW, PROFILE, HSJ, XFORM, CID }; +``` + +### 2b. `CidData` struct (`ts_cid.h`) + +```cpp +struct CidSplitSet { + int n_splits; + int n_bins; + std::vector data; // n_splits * n_bins, contiguous + std::vector in_split; // popcount per split + + const uint64_t* split(int i) const { + return &data[static_cast(i) * n_bins]; + } +}; + +struct CidData { + int n_trees; + int n_tips; + int n_bins; // ceil(n_tips / 64) + + // Precomputed input tree splits + std::vector tree_splits; + + // Precomputed per-tree clustering entropies + std::vector tree_ce; + double mean_tree_ce; + + // Per-tree weights (1.0 normally; modified during ratchet) + std::vector tree_weights; + double weight_sum; // sum of tree_weights (for weighted mean) + + // Normalized scoring mode + bool normalize; + + // Block boundaries: mrp_tree_start[i] = first CharBlock index for tree i + // Used to synchronize MRP perturbation with tree_weights. + std::vector mrp_tree_start; + + // LAP scratch (reused across cid_score calls to avoid allocation) + mutable LapScratch lap_scratch; +}; +``` + +### 2c. `ts_cid.cpp` + +Key functions: + +| Function | Purpose | +|----------|---------| +| `cid_score(TreeState& tree, const CidData& cd)` | Compute mean CID (or normalized) of candidate against input trees, using precomputed input splits and TreeDist's MCI algorithm | +| `build_mrp_dataset(const CidData& cd, int n_tips)` → `DataSet` | Convert input tree splits to MRP binary characters, packed into `CharBlock`s | +| `build_cid_data(split_matrices, n_tips, normalize)` → `CidData` | Construct `CidData` from R-side split matrices | +| `perturb_cid_weights(CidData& cd, DataSet& ds, mode, prob, rng)` | Synchronize MRP block masks with CidData tree weights during ratchet | +| `save_cid_weights(CidData& cd)` / `restore_cid_weights(CidData& cd)` | Save/restore tree_weights for ratchet | + +`cid_score()` implementation: +1. Call `ts::compute_splits(tree)` to get candidate splits +2. Compute candidate clustering entropy +3. For each input tree (weighted by `tree_weights[i]`): + - Compute MCI via TreeDist's `mutual_clustering_score()` using raw arrays +4. Return `(weighted_mean_CID)` or `1 - weighted_mean(MCI_i / CE_i)` if normalized + +### 2d. `score_tree()` dispatch + +In `ts_fitch.cpp`: +```cpp +double score_tree(TreeState& tree, const DataSet& ds) { + if (ds.scoring_mode == ScoringMode::CID) { + return cid_score(tree, *ds.cid_data); + } + // ... existing HSJ, XFORM, EW/IW/PROFILE dispatch ... +} +``` + +### 2e. DataSet extension + +Add to `struct DataSet`: +```cpp +// CID scoring data (populated when scoring_mode == CID). +// Owned by the caller; DataSet holds a non-owning pointer. +CidData* cid_data = nullptr; +``` + +### 2f. Ratchet integration + +Extend `save_perturb_state()` / `restore_perturb_state()` in `ts_ratchet.cpp`: +```cpp +struct PerturbSnapshot { + // ... existing active_mask / upweight_mask vectors ... + std::vector cid_tree_weights; // saved tree_weights + double cid_weight_sum; +}; +``` + +In `perturb_*()`, after modifying MRP block masks, synchronize +`CidData::tree_weights` by inspecting which tree-blocks were zeroed/upweighted. + +### 2g. Rcpp bridge (`ts_rcpp.cpp`) + +New exported function: +```cpp +// [[Rcpp::export]] +Rcpp::List ts_cid_consensus( + Rcpp::List split_matrices, // list of RawMatrix (one per input tree) + Rcpp::IntegerVector nTip, + Rcpp::LogicalVector normalize, + // DrivenParams fields (same as ts_driven_search): + int max_replicates, int target_hits, double max_seconds, + int n_threads, int verbosity, + // SearchControl fields: + Rcpp::List control +) { + // 1. Build CidData from split_matrices + // 2. Build MRP DataSet from CidData + // 3. Set ds.scoring_mode = ScoringMode::CID; ds.cid_data = &cid_data; + // 4. Call ts_driven_search(pool, ds, params) + // 5. Return pool trees + scores as R list +} +``` + +### 2h. Registration + +Add `ts_cid_consensus` to `TreeSearch-init.c` and run `Rscript check_init.R`. + +--- + +## Phase 3: R-level changes + +### `R/CIDConsensus.R` rewrite + +Replace the `Ratchet()`/`TreeSearch()` backend with a call to +`ts_cid_consensus()`. The R function becomes a thin wrapper: + +```r +CIDConsensus <- function(trees, metric = ClusteringInfoDistance, + start = NULL, normalize = FALSE, + maxReplicates = 100L, targetHits = 10L, + maxSeconds = 0, nThreads = 1L, + collapse = TRUE, neverDrop = FALSE, + maxDrop = ceiling(NTip(trees[[1]]) / 10), + verbosity = 1L, control = SearchControl(), + ...) { + # Input validation (unchanged) + # Build split matrices from input trees + tipLabels <- trees[[1]]$tip.label + splitMats <- lapply(trees, function(tr) { + unclass(as.Splits(tr, tipLabels)) + }) + + # Call C++ driven search + result <- ts_cid_consensus(splitMats, NTip(trees[[1]]), + normalize, maxReplicates, targetHits, + maxSeconds, nThreads, verbosity, control) + + # Post-process: convert edge matrix back to phylo + bestTree <- result$tree + attr(bestTree, "score") <- result$score + + # Phase 2: Collapse/resolve (R-level, unchanged) + if (collapse) { + cidData <- .MakeCIDData(trees, metric, tipLabels, normalize) + bestTree <- .CollapseRefine(bestTree, cidData, verbosity) + } + + # Phase 3: Rogue dropping (R-level, unchanged) + if (!isTRUE(neverDrop)) { + # ... existing rogue logic ... + } + + bestTree +} +``` + +### API changes + +| Old parameter | New parameter | Notes | +|---------------|---------------|-------| +| `method` | Removed | Always driven search | +| `ratchIter`, `ratchHits` | `maxReplicates`, `targetHits` | Match `MaximizeParsimony()` API | +| `searchIter`, `searchHits` | `control = SearchControl()` | Expert tuning via `SearchControl()` | +| — | `maxSeconds` | New: timeout | +| — | `nThreads` | New: parallelism | +| — | `control` | New: expert `SearchControl()` for strategy tuning | +| `metric` | `metric` | Retained for collapse/resolve and rogue phases | + +The `metric` parameter is retained for the R-level collapse/resolve and rogue +phases, but the core search always uses CID (via the C++ engine). The `metric` +parameter's scope narrows to post-search refinement only. + +### DESCRIPTION + +- Add `LinkingTo: TreeDist` +- Version bump if needed + +--- + +## Phase 4: Testing + +### C++ unit tests (`tests/testthat/test-ts-cid.R`) + +Tier 2. Tests: + +1. `ts_cid_consensus()` returns valid tree with score attribute +2. Score matches R-level CID computation (`mean(ClusteringInfoDistance(...))`) +3. Search improves over majority-rule consensus starting score +4. Multi-replicate produces equal-or-better score than single replicate +5. Normalized scoring returns value in [0, 1] +6. `nThreads > 1` produces valid result (correctness, not speed) + +### Updated `test-CIDConsensus.R` + +Existing tests adapted to new API (parameter name changes). Core assertions +unchanged: search improves score, collapse helps, rogue dropping works, +custom metric accepted. + +### Regression test + +Verify that on the POC's 20-tip test case, the C++ engine achieves CID ≤ 2.2 +(within tolerance of the R-level result of 2.16). + +--- + +## Phase 5: Future work (not in this plan) + +- **Collapse/resolve in C++**: Move `CollapseRefine` into the driven search + as a post-TBR phase. +- **Rogue dropping in C++**: Move the drop/restore loop into C++. +- **Incremental CID**: Track which splits changed during TBR and + incrementally update MCI (requires LAP warm-starting — research needed). +- **Non-binary search in C++**: Native polytomy handling in the driven search. + +--- + +## Implementation order + +1. TreeDist: create `inst/include/TreeDist/` headers +2. TreeSearch: `ts_cid.h/.cpp` with `CidData`, `cid_score()`, `build_mrp_dataset()` +3. TreeSearch: `ScoringMode::CID` + `score_tree()` dispatch +4. TreeSearch: ratchet integration (perturb/save/restore CID weights) +5. TreeSearch: Rcpp bridge `ts_cid_consensus()` +6. TreeSearch: R-level `CIDConsensus()` rewrite +7. Tests + regression check +8. Update `TreeSearch-init.c`, `DESCRIPTION`, `NAMESPACE` + +--- + +## Risks and mitigations + +| Risk | Mitigation | +|------|------------| +| MRP screening poorly correlated with CID for some tree distributions | MRP = RF proxy, which is well-correlated with CID in practice. Ratchet/drift escape any screening-induced local optima. Can add CID-based candidate re-ranking if needed. | +| LAP solver alignment sensitivity when compiled in TreeSearch | Use option (b) (copy lap.cpp) if header-only causes regression. Benchmark. | +| CID verification too slow for large trees (>100 tips, >500 input trees) | LAP dimension is small when consensus is close to inputs (many exact matches). LapScratch reuse avoids allocation. Candidate set is already filtered by MRP screening. Profile and optimize if needed. | +| TreeDist header refactor affects TreeDist's own tests | Run TreeDist's full test suite after extraction. Headers are pure refactoring. | +| Per-tree weight synchronization in ratchet is complex | Unit test: verify that after perturb + restore, tree_weights are identical to pre-perturb state. | diff --git a/.positai/plans/2026-03-20-1650-subtree-cid-scoring-for-sectorial-search.md b/.positai/plans/2026-03-20-1650-subtree-cid-scoring-for-sectorial-search.md new file mode 100644 index 000000000..862f345a4 --- /dev/null +++ b/.positai/plans/2026-03-20-1650-subtree-cid-scoring-for-sectorial-search.md @@ -0,0 +1,219 @@ +# Plan: Enable Sectorial Search for CID Consensus + +**Date:** 2026-03-20 +**Context:** CIDConsensus currently disables all sectorial search (XSS, RSS, CSS +rounds hardcoded to 0). This plan re-enables them. + +--- + +## Analysis: Why sectorial search was disabled + +Two bugs prevent sectorial search from working in CID mode: + +### Bug 1: Reduced dataset inherits CID scoring mode + +`build_reduced_dataset()` (line 270 of `ts_sector.cpp`) copies `scoring_mode` +from the full dataset: +```cpp +rd.data.scoring_mode = ds.scoring_mode; // copies CID +``` + +When `score_tree(rd.subtree, rd.data)` is later called on the sector (line 528), +it dispatches to `cid_score(tree, *ds.cid_data)` — but the reduced dataset's +`cid_data` is null (never set). This would crash. + +### Bug 2: `final_` states not populated in CID mode + +`build_reduced_dataset()` reads `tree.final_[...]` to construct the HTU +pseudo-tip's state (line 298). But in CID mode, `score_tree()` dispatches to +`cid_score()` which computes splits from topology — it never runs Fitch, so +`final_` is never populated (or is zeroed by `reset_states()`). The HTU would +get all-zero states, making sector search useless. + +--- + +## Approach: MRP-Fitch proxy + CID verification + +The CID DataSet already contains MRP (Matrix Representation with Parsimony) +binary characters for TBR screening. These encode each input tree split as a +binary Fitch character. Sectorial search can use these same MRP characters for +within-sector optimization, with full CID verification after reinsertion. + +This extends the dual-layer pattern already used by TBR: +- **Fast layer**: Fitch on MRP characters (additive, supports HTU decomposition) +- **Accurate layer**: Full CID scoring on the complete tree + +### Why MRP is a good proxy for CID in sectors + +1. Each MRP character represents one split from one input tree. Fitch + parsimony on MRP measures compatibility with input tree structure — closely + related to CID. +2. The HTU `final_` states from Fitch uppass encode the optimal MRP + assignment at the sector boundary — the principled decomposition that + sectorial search was designed for. +3. Full-tree CID verification after reinsertion catches any proxy errors. + We never accept a move that worsens actual CID. + +### CSS needs zero changes + +CSS uses sector_mask TBR on the **full** tree (no reduced dataset, no HTU). +TBR already works in CID mode (MRP incremental screening + CID verification). +The sector_mask just restricts clip/regraft sites. Enabling CSS is purely an +R-wrapper change. + +--- + +## Changes + +### 1. `src/ts_fitch.cpp` — maintain Fitch state arrays in CID mode + +In `score_tree()`, run `fitch_score()` before `cid_score()` so that +`prelim`/`final_` are always valid after a CID-mode `score_tree()` call: + +```cpp +double score_tree(TreeState& tree, const DataSet& ds) { + if (ds.scoring_mode == ScoringMode::CID) { + // Run Fitch on MRP characters to maintain prelim/final_ state arrays. + // Needed by build_reduced_dataset() for HTU construction, and by + // TBR incremental scoring as a valid baseline. + fitch_score(tree, ds); + return cid_score(tree, *ds.cid_data); + } + // ... existing dispatches unchanged +} +``` + +**Cost**: One extra Fitch pass per `score_tree()` call in CID mode. +For typical sizes (50 tips, ~5000 MRP chars), this is O(250K) operations +(microseconds). CID scoring itself is O(n_trees × n_splits² × LAP) — +milliseconds. Overhead < 1%. + +**Correctness**: `fitch_score()` calls `fitch_downpass()` (traverses +`tree.postorder`) then `fitch_uppass()`. All existing callers ensure +postorder is valid before `score_tree()` (TBR calls `build_postorder()` +at line 843 before `full_rescore()`; sector code calls `build_postorder()` +at lines 312, 545, 663). + +### 2. `src/ts_sector.cpp` — override scoring mode for CID reduced datasets + +After the existing scoring_mode copy (line 270), add: + +```cpp +// CID mode: sector-internal search uses Fitch on MRP characters. +// Full CID is verified on the complete tree after reinsertion. +if (rd.data.scoring_mode == ScoringMode::CID) { + rd.data.scoring_mode = ScoringMode::EW; + rd.data.cid_data = nullptr; +} +``` + +This makes `score_tree(rd.subtree, rd.data)` use Fitch parsimony within +sectors, which is correct for MRP characters and supports the HTU +decomposition. + +### 3. `R/CIDConsensus.R` — enable sector parameters + +Replace hardcoded disabled sectors with SearchControl-driven defaults. +In `.CIDDrivenSearch()`: + +```r +xssRounds = .NullOr(ctrl[["xssRounds"]], 3L), # was 0L +xssPartitions = .NullOr(ctrl[["xssPartitions"]], 4L), +rssRounds = .NullOr(ctrl[["rssRounds"]], 3L), # was 0L +cssRounds = .NullOr(ctrl[["cssRounds"]], 2L), # was 0L +cssPartitions = .NullOr(ctrl[["cssPartitions"]], 4L), +``` + +Also in `.TopologySearch()` (the light re-optimization used by rogue +dropping), enable sectors when tree is large enough: + +```r +xssRounds = if (nTip >= 12L) 1L else 0L, +rssRounds = 0L, # keep light for re-optimization +cssRounds = 0L, +``` + +### 4. Tests (in `tests/testthat/test-ts-cid.R` or new file) + +**Tier 2** (skip on CRAN). + +1. **Fitch state validity**: After `ts_cid_consensus()` on a small case, + verify the returned tree's MRP Fitch score is consistent (call + `ts_fitch_score()` on the MRP data and confirm it's a reasonable + integer). + +2. **Sector smoke test**: Run `ts_cid_consensus()` with + `xssRounds = 2, rssRounds = 2, cssRounds = 1` on a 20-tip, 30-tree + case. Verify it returns a valid tree and score ≤ the score from + sectors-disabled run. + +3. **Regression**: Compare CIDConsensus scores with sectors enabled vs + disabled on the existing test cases. Sectors-enabled should be ≤. + +4. **Small tree guard**: Verify that on a 6-tip case (below + `2 * sectorMinSize`), sectors are skipped gracefully. + +### 5. Update comments + +Remove the "Sectorial search disabled" comments in: +- `R/CIDConsensus.R` (lines 262-263) +- Update `AGENTS.md` architecture notes + +--- + +## Risks and mitigations + +| Risk | Mitigation | +|------|------------| +| MRP proxy doesn't correlate well with CID for sector-level moves | Full CID verification after reinsertion ensures correctness. If sectors rarely help, they waste time but don't harm quality. Empirical benchmarking will determine optimal defaults. | +| Extra Fitch in `score_tree()` adds overhead during TBR | Overhead is < 1% of CID scoring. Measurable with `ts_bench_tbr_phases`. | +| `fitch_score()` in `score_tree()` assumes valid postorder | All existing callers already ensure this (verified by code audit). Add a debug assertion if desired. | +| Sector search produces poor results and wastes wall-clock time | Default to modest sector rounds (3 XSS, 3 RSS, 2 CSS) rather than parsimony defaults. Can be tuned via SearchControl. | + +--- + +## Implementation order + +1. Fix `score_tree()` in `ts_fitch.cpp` (change #1) +2. Fix `build_reduced_dataset()` in `ts_sector.cpp` (change #2) +3. Build and run existing tests (verify no regression) +4. Update R wrapper defaults (change #3) +5. Add new tests (change #4) +6. Benchmark: compare CID scores with sectors enabled vs disabled +7. Update comments and AGENTS.md + +--- + +## Results + +### Implementation notes + +Change #1 was revised during implementation. Running `fitch_score()` inside +every `score_tree()` call triggers a pre-existing memory issue (heap +fragmentation from accumulated CID evaluations via LAP + split temporaries) +sooner. Instead, Fitch state preparation (`prepare_cid_states()`) is called +only in `rss_search()` and `xss_search()` before sector extraction and after +each reinsertion. This avoids extra overhead in non-sector code paths. + +Sector defaults are gated on `nTip >= 20` because CID scoring is expensive +per evaluation and small trees converge quickly with TBR alone. + +### Benchmark results (30-tip, 50 input trees, 5 replicates) + +| Seed | No sectors | With sectors | Time (ns) | Time (s) | +|------|-----------|-------------|-----------|----------| +| 1001 | 16.29 | 2.99 | 0.61 | 0.42 | +| 2002 | 18.14 | 3.08 | 0.64 | 0.50 | +| 3003 | 16.04 | 3.05 | 0.61 | 0.40 | +| 4004 | 16.01 | 3.91 | 0.68 | 0.50 | +| 5005 | 23.30 | 3.07 | 0.73 | 0.45 | + +**~5× CID score improvement** with sectors enabled. Convergence is also +faster (0.40–0.50s vs 0.61–0.73s) because XSS finds good sector topologies +early, breaking TBR local optima. + +### Test status + +- 274 C++ engine tests pass (28 CID + 42 sector + 152 driven + 52 TBR) +- CIDConsensus R-level tests: 121/125 pass; last 4 trigger pre-existing + `std::bad_alloc` from accumulated CID searches (see known issue in AGENTS.md) diff --git a/.positai/plans/2026-03-20-1816-reframe-cidconsensus-as-mci-maximization.md b/.positai/plans/2026-03-20-1816-reframe-cidconsensus-as-mci-maximization.md new file mode 100644 index 000000000..6c57a0df1 --- /dev/null +++ b/.positai/plans/2026-03-20-1816-reframe-cidconsensus-as-mci-maximization.md @@ -0,0 +1,188 @@ +# Plan: Reframe CIDConsensus as MCI Maximization + +## Motivation + +Currently `CIDConsensus()` minimizes mean CID (Clustering Information Distance). +This creates a normalization headache for rogue taxon dropping: raw CID +naturally decreases when tips are dropped (the CE terms shrink), so dropping +tips looks beneficial even when it isn't. The current workaround is a +`normalize` parameter that switches to `1 - mean(MCI_i / CE_i)`. + +The cleaner framing: **maximize mean Mutual Clustering Information (MCI)**. +MCI measures shared clustering information between the consensus and each +input tree. It doesn't have the CE-deflation bias — dropping a tip removes +splits from both sides, so MCI only improves if the tip was genuinely causing +disagreement. This eliminates the need for the `normalize` parameter entirely. + +## Design + +### Internal representation: negated MCI + +The search infrastructure (TreePool, TBR, ratchet, drift, fuse) all assume +**minimization** (lower score = better). Rather than flipping every comparison +operator in both C++ and R, we negate: the internal score is `-mean(MCI)`. +Lower (more negative) = higher MCI = better. On output, we negate back to +present the user with a positive MCI value (higher = better). + +### What changes + +#### C++: `ts_cid.cpp` — `cid_score()` + +Replace both the normalize and non-normalize branches with a single +computation: + +```cpp +double cid_score(TreeState& tree, const CidData& cd) { + SplitSet ss = compute_splits(tree); + CidSplitSet cand = splitset_to_cid(ss, cd.n_tips); + // No need for cand_ce — we only need MCI + + double mci_sum = 0.0; + for (int i = 0; i < cd.n_trees; ++i) { + if (cd.tree_weights[i] <= 0.0) continue; + double mci = mutual_clustering_info(cand, cd.tree_splits[i], + cd.n_tips, cd.lap_scratch); + mci_sum += cd.tree_weights[i] * mci; + } + return -mci_sum / cd.weight_sum; // negated for minimization +} +``` + +The `normalize` field in `CidData` becomes unused. Keep the field for now +(avoid struct layout churn); mark with a comment. `mean_tree_ce` also becomes +unused for scoring but can be kept for diagnostics. + +#### C++: `ts_cid.h` + +- Update `cid_score()` doc comment. +- Add comment noting `normalize` and `mean_tree_ce` are vestigial. + +#### C++: `ts_rcpp.cpp` — `ts_cid_consensus()` + +- Keep the `normalize` parameter in the Rcpp signature for backward + compatibility but ignore it (or emit a deprecation message). +- The `mean_tree_ce` computation can stay (harmless). +- **The returned `best_score` and per-tree scores are now negated MCI.** + R-side will negate on receipt. + +#### R: `CIDConsensus.R` + +1. **`CIDConsensus()` signature**: + - Remove `normalize` parameter (or keep with deprecation warning if + passed). + - Remove the normalization warning (lines 135–141). + - Update roxygen docs: "maximizes mean MCI", score is "mean MCI + (higher is better)". + +2. **`.CIDScoreFast()`**: + Simplify to compute `-mean(MCI)`: + ```r + .CIDScoreFast <- function(parent, child, dataset) { + nTip <- dataset$nTip + candidate <- .EdgeListToPhylo(parent, child, dataset$tipLabels) + candSp <- as.Splits(candidate, dataset$tipLabels) + nTree <- length(dataset$inputSplitsRaw) + mciSum <- 0 + for (i in seq_len(nTree)) { + mciSum <- mciSum + MutualClusteringInfoSplits( + candSp, dataset$inputSplitsRaw[[i]], nTip) + } + -mciSum / nTree + } + ``` + Remove the normalize branch and CE computation entirely. + +3. **`.MakeCIDData()`**: + - Remove `normalize` parameter. + - Keep CE precomputation (used if someone passes a custom metric; harmless + otherwise). + +4. **`.CIDDrivenSearch()`**: + - Pass `normalize = FALSE` to C++ (value is ignored but signature expects it). + - Negate `result[["best_score"]]` before attaching as attribute: + `attr(tree, "score") <- -result[["best_score"]]` + - Same for hits. + +5. **`.TopologySearch()`**: + - Remove `normalize` from the `.NullOr()` call. + - Negate returned score. + +6. **`.CollapseRefine()`**: + - No comparison changes needed (all `<` comparisons still work with + negated MCI). + - Negate the final score before attaching to the output tree. + +7. **`.RogueRefine()`**: + - Remove `originalNormalize` variable and its propagation. + - No comparison changes needed. + - Negate scores on output. + +8. **`.PrescreenMarginalNID()`**, **`.BestInsertion()`**: + - Remove `normalize` parameter passing to `.MakeCIDData()`. + +9. **`.CIDBootstrap()`**: + - No changes needed (operates on internal scores). + +10. **Output score convention**: + All `attr(result, "score")` attachments must negate the internal + score to produce positive MCI for the user. Audit every code path + that sets this attribute. + +#### R: `CIDConsensus.R` — messaging + +Update `message()` calls in verbosity output to say "MCI" instead of +"score" where appropriate, and note that higher is better. + +#### Tests: `test-CIDConsensus.R` + +- Remove or update tests that check `score >= 0` (MCI scores are positive + but the bound is `[0, max_CE]`, not `[0, 1]`). +- Remove or update normalized-scoring tests (lines 386–407): the + `normalize` parameter goes away. +- Remove the "Warning fires for rogue dropping without normalization" + test (lines 516–524). +- Update the rogue-dropping tests to not pass `normalize = TRUE`. +- Update collapse-comparison test (line 381): direction is now `>=` + (higher MCI = better), or keep `<=` if comparing internal negated + scores — depends on whether the test uses `attr(result, "score")` + (which will be positive MCI). +- Add a test verifying that `attr(result, "score")` matches + `mean(MutualClusteringInfo(result, trees))`. + +#### Tests: `test-ts-cid.R` + +- Update `CIDConsensus` wrapper tests analogously. + +### What doesn't change + +- `mutual_clustering_info()` — unchanged. +- `clustering_entropy()` — unchanged (still used by MRP builder, diagnostics). +- `build_mrp_dataset()` — unchanged. +- All search infrastructure (TreePool, TBR, ratchet, drift, fuse) — unchanged + (they see negated MCI, which is still a "lower is better" score). +- The `metric` parameter on `CIDConsensus()` — kept for non-CID metrics. + The generic path (non-CID metric) still minimizes `mean(metric(...))`. + This is a separate concern; leave as-is for now. +- `sync_cid_weights_from_mrp()` — unchanged (weight sync is metric-agnostic). + +### Risk assessment + +- **Low risk**: The core algorithm (LAP, MCI, MRP screening) is untouched. + The change is purely in how the objective is aggregated and presented. +- **Medium risk**: Score comparison direction. All internal comparisons + use `<` (lower = better) and we preserve this via negation. The only + places where direction matters are user-facing: `attr(result, "score")` + and verbosity messages. These need careful auditing. +- **Test coverage**: Existing tests cover scoring, collapse, rogue dropping, + and end-to-end. Many will need updating but the coverage itself is good. + +## Task sequence + +1. C++ changes: `ts_cid.cpp`, `ts_cid.h` (simplify `cid_score()`) +2. C++ bridge: `ts_rcpp.cpp` (ignore `normalize`, keep param for compat) +3. R scoring: `.CIDScoreFast()`, `.MakeCIDData()` (remove normalize logic) +4. R pipeline: `.CIDDrivenSearch()`, `.TopologySearch()`, `.CollapseRefine()`, + `.RogueRefine()`, helpers (remove normalize plumbing, negate on output) +5. R API: `CIDConsensus()` signature and docs +6. Tests: update `test-CIDConsensus.R` and `test-ts-cid.R` +7. Build and run full test suite diff --git a/.positai/plans/2026-03-21-1445-reframe-cidconsensus-as-mci-maximization.md b/.positai/plans/2026-03-21-1445-reframe-cidconsensus-as-mci-maximization.md new file mode 100644 index 000000000..4b1f60f2d --- /dev/null +++ b/.positai/plans/2026-03-21-1445-reframe-cidconsensus-as-mci-maximization.md @@ -0,0 +1,135 @@ +# Implementation Plan: Reframe CIDConsensus as MCI Maximization + +Based on the design in `2026-03-20-1816-reframe-cidconsensus-as-mci-maximization.md`. + +## Summary + +Replace CID minimization with MCI maximization. Internal score becomes +`-mean(MCI)` (negated for the minimization infrastructure). User-facing +scores are positive MCI (higher = better). The `normalize` parameter is +removed entirely. + +## Step-by-step + +### 1. C++: `src/ts_cid.cpp` — simplify `cid_score()` + +Replace the two-branch `if (cd.normalize) { ... } else { ... }` body +(lines 518–560) with a single branch that computes `-weighted_mean(MCI)`: + +```cpp +double cid_score(TreeState& tree, const CidData& cd) { + compute_splits_cid(tree, cd.cand_tip_bits, cd.cand_buf); + CidSplitSet& cand = cd.cand_buf; + double budget = cd.score_budget; + + double mci_sum = 0.0; + double weight_done = 0.0; + for (int i = 0; i < cd.n_trees; ++i) { + if (cd.tree_weights[i] <= 0.0) continue; + double mci = mutual_clustering_info(cand, cd.tree_splits[i], + cd.n_tips, cd.lap_scratch); + mci_sum += cd.tree_weights[i] * mci; + weight_done += cd.tree_weights[i]; + // Early termination: even with perfect MCI for remaining trees, + // score can't beat budget + if (budget < HUGE_VAL) { + double remaining = cd.weight_sum - weight_done; + // Upper bound on remaining MCI: each tree contributes at most cand_CE + double cand_ce = clustering_entropy_fast(cand, cd.n_tips, cd.lg2_n); + double best_possible = -(mci_sum + remaining * cand_ce) / cd.weight_sum; + if (best_possible > budget) return best_possible; + } + } + return -mci_sum / cd.weight_sum; +} +``` + +Note: `cand_ce` for the early-termination bound should be computed once +before the loop (not per iteration). Move it before the loop and only +use it in the budget check. + +### 2. C++: `src/ts_cid.h` — mark `normalize` vestigial + +- Add comment on `normalize` field: `// Vestigial; no longer used by cid_score()` +- Update `cid_score()` doc comment: "Returns negated mean MCI (lower = better consensus)." + +### 3. C++: `src/ts_rcpp.cpp` — ignore `normalize` parameter + +Keep the `normalize` parameter in the Rcpp signature (backward compat) +but ignore it. No code change needed in the bridge logic since +`cid_data.normalize` is still set but `cid_score()` no longer reads it. + +### 4. R: `R/CIDConsensus.R` — remove normalize plumbing + +**Functions to modify:** + +| Function | Change | +|----------|--------| +| `CIDConsensus()` | Remove `normalize` param; remove rogue-without-normalize warning; update docs | +| `.CIDDrivenSearch()` | Remove `normalize` from args; pass `normalize = FALSE` to C++ (ignored) | +| `.CIDDrivenSearch()` | Negate `result[["best_score"]]` when attaching as `attr(tree, "score")` | +| `.TopologySearch()` | Remove `normalize` from `.NullOr()` call; negate returned score | +| `.CIDScoreFast()` | Remove normalize branch; return `-mean(MCI)` | +| `.MakeCIDData()` | Remove `normalize` parameter | +| `.CollapseRefine()` | Negate `bestScore` on output (internal comparisons unchanged) | +| `.RogueRefine()` | Remove `originalNormalize`; remove normalize propagation to helpers | +| `.PrescreenMarginalNID()` | Remove `normalize` arg from `.MakeCIDData()` calls | +| `.BestInsertion()` | Remove `normalize` arg from `.MakeCIDData()` call | + +**Score output convention:** +- C++ returns negated MCI (lower = better). Negate back to positive MCI + at every `attr(tree, "score") <-` assignment in `.CIDDrivenSearch()`, + `.TopologySearch()`, `.CollapseRefine()`, `.RogueRefine()`. +- `.CollapseRefine()` and `.RogueRefine()` use `.CIDScorer()` internally + which already returns negated MCI — so all `<` comparisons work unchanged. + Only the final `attr(result, "score")` needs negation. +- `.ScoreTree()` returns the internal score (negated MCI) — used for + internal comparisons only. + +**Verbosity messages:** Update messages in `.CollapseRefine()` and +`.RogueRefine()` to negate scores before display (show positive MCI). + +**Roxygen updates:** +- `@return` score description: "mean MCI (higher is better)" +- Remove `@param normalize` +- Remove normalize-related `@details` + +### 5. Tests: `tests/testthat/test-CIDConsensus.R` + +| Test | Change | +|------|--------| +| "CIDConsensus runs end-to-end" (line 155-157) | `score >= 0` still valid (MCI is non-negative) | +| "Collapse should be equal or better" (line 381) | Flip to `>=` (higher MCI = better) | +| "Normalized scoring returns value in [0, 1]" (line 388) | **Delete** (normalize removed) | +| "Normalized scoring differs from raw" (line 397) | **Delete** | +| Rogue tests (lines 461-497) | Remove `normalize = TRUE` | +| maxDrop test (line 506) | Remove `normalize = TRUE` | +| "Warning fires for rogue dropping" (line 516) | **Delete** | +| "CIDConsensus normalized mode" (line 529) | **Delete** | +| Add new test | Verify `attr(result, "score")` ≈ `mean(MutualClusteringInfo(result, trees))` | + +### 6. Tests: `tests/testthat/test-ts-cid.R` + +| Test | Change | +|------|--------| +| All `normalize = FALSE` args | Remove (default is now to ignore) | +| `result$best_score >= 0` (line 40) | Change to `<= 0` (negated MCI) | +| `attr(coll, "score") <= attr(noColl, "score")` (line 139) | Flip to `>=` | +| "Normalized CID score is in [0, 1]" (line 266) | **Delete** | +| Add new test | Verify negated MCI matches `-mean(MCI)` from R | + +### 7. Build and test + +- Tarball build to `.agent-build` +- Run `test-ts-cid.R` and `test-CIDConsensus.R` +- Verify CID score matches `mean(MutualClusteringInfo())` from TreeDist + +### 8. Commit + +Single commit: `refactor: reframe CIDConsensus as MCI maximization` + +## Risk + +Low. Core algorithm (LAP, MCI, MRP screening) is untouched. Only the +aggregation formula and presentation layer change. All internal `<` +comparisons remain valid via negation. diff --git a/.positai/plans/2026-03-23-0708-merge-cpp-search-into-featurecid-consensus.md b/.positai/plans/2026-03-23-0708-merge-cpp-search-into-featurecid-consensus.md new file mode 100644 index 000000000..3233bf810 --- /dev/null +++ b/.positai/plans/2026-03-23-0708-merge-cpp-search-into-featurecid-consensus.md @@ -0,0 +1,87 @@ +# Plan: Merge cpp-search into feature/cid-consensus + +## Context + +`feature/cid-consensus` is 6 commits ahead and 16 commits behind `cpp-search`. +The branch has uncommitted work (now stashed as `stash@{0}`) adding ~400 lines +of CID wiring (Rcpp bridge, drift two-baseline, sector CID, ratchet CID). + +Trial merge shows **1 conflict** (AGENTS.md only). All source files auto-merge +cleanly. The stash pop will likely conflict on `ts_drift.cpp` and +`ts_sector.cpp` (both modified by cpp-search's collapsed-edge features and by +the stash's CID wiring). + +## Steps + +### 1. Merge cpp-search + +```bash +git merge cpp-search +``` + +### 2. Resolve AGENTS.md (only conflict) + +Two conflict regions: + +- **C++ module map** (~line 489): CID branch adds a CID row, cpp-search adds + a Collapsed row. **Keep both rows.** + +- **Benchmarks & profiling** (~line 871): CID branch has CID scoring + optimization notes; cpp-search has updated profiling phase table + ratchet + tuning validation. **Keep both sections** (CID optimizations section + followed by ratchet tuning section, or vice versa). + +Commit the merge. + +### 3. Pop stash + +```bash +git stash pop +``` + +Expected conflicts: `ts_drift.cpp`, `ts_sector.cpp` (cpp-search added +collapsed-edge skipping; stash adds CID two-baseline tracking). These are +independent concerns operating on different code paths — resolution is to +keep both. + +Other stashed files (`ts_rcpp.cpp`, `ts_ratchet.cpp`, `ts_fitch.cpp`, +`ts_data.h`, `RcppExports.*`, `TreeSearch-init.c`, NAMESPACE, man pages) +should pop cleanly since cpp-search didn't touch them. + +### 4. Resolve stash conflicts (if any) + +For `ts_drift.cpp`: cpp-search added `#include "ts_collapsed.h"` and +collapsed-edge logic; stash added `#include "ts_cid.h"` and CID +two-baseline tracking. Keep both — they're additive. + +For `ts_sector.cpp`: cpp-search rewrote sector internals (conflict-guided +RSS, collapsed dedup); stash added CID-mode dispatch. Integrate carefully. + +### 5. Build and test + +```bash +rm -f src/*.o src/*.dll +SRC=$(pwd) && TMPBUILD=$(mktemp -d) && \ + (cd "$TMPBUILD" && R CMD build --no-build-vignettes --no-manual --no-resave-data "$SRC") && \ + R CMD INSTALL --library=.agent-P "$TMPBUILD"/TreeSearch_*.tar.gz && \ + rm -rf "$TMPBUILD" +``` + +Then run tests: +```bash +Rscript -e "library(TreeSearch, lib.loc='.agent-P'); testthat::test_dir('tests/testthat')" +``` + +### 6. Commit the stash work + +Stage and commit the popped stash changes (CID wiring) on top of the merge. + +## Risk assessment + +- **Low risk**: AGENTS.md resolution is purely editorial. +- **Medium risk**: stash pop conflicts on ts_drift.cpp and ts_sector.cpp + require careful integration of two independent features (collapsed edges + + CID scoring). Both are additive — no logical conflicts, just textual ones. +- **Build risk**: The merged code introduces new `#include` dependencies + (ts_collapsed.h) into files that also get CID includes. Compilation will + surface any header issues immediately. diff --git a/.positai/settings.json b/.positai/settings.json index beaa8e7c7..74145461f 100644 --- a/.positai/settings.json +++ b/.positai/settings.json @@ -11,7 +11,8 @@ "*.cpp": "allow", "*.R": "allow", "*.c": "allow", - "*/NAMESPACE": "allow" + "*/NAMESPACE": "allow", + "*/DESCRIPTION": "allow" }, "bash": { "cd C:/Users/pjjg18/GitHub/TreeSearch": "allow", @@ -23,11 +24,14 @@ "cd /c/Users/pjjg18/GitHub/TreeSearch": "allow", "Rscript -e \"roxygen2::roxygenise(load_code = roxygen2::load_installed)\" 2>&1": "allow", "tail *": "allow", + "cd \"C:/Users/pjjg18/GitHub/TreeSearch-a\"": "allow", "Rscript -e \".libPaths(c('.agent-A', .libPaths())); roxygen2::roxygenise(load_code = roxygen2::load_installed)\" 2>&1": "allow", "git *": "allow" }, "read": { - "*.cpp": "allow" + "*.cpp": "allow", + "*.h": "allow", + "*": "allow" }, "external_directory": { "C:/Users/pjjg18/GitHub/TreeDist/*": "allow", @@ -49,7 +53,16 @@ "https://repo.r-wasm.org/*": "allow", "https://agentskills.io/*": "allow", "https://platform.claude.com/*": "allow", - "https://github.com/*": "allow" + "https://github.com/*": "allow", + "C:\\Users\\pjjg18\\GitHub\\TreeDist/*": "allow", + "C:\\Users\\pjjg18\\GitHub\\TreeDist\\R/*": "allow", + "C:\\Users\\pjjg18\\GitHub\\TreeDist\\src/*": "allow", + "C:\\Users\\pjjg18\\GitHub\\TreeDist\\vignettes/*": "allow", + "../TreeSearch-a/*": "allow", + "../TreeDist/R/*": "allow", + "../TreeDist/*": "allow", + "../consense/*": "allow", + "/tmp/*": "allow" } } } \ No newline at end of file diff --git a/DESCRIPTION b/DESCRIPTION index 5b4b39218..85d61b46b 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -80,6 +80,7 @@ Config/Needs/website: Collate: 'AdditionTree.R' 'Bootstrap.R' + 'InfoConsensus.R' 'CharacterHierarchy.R' 'ClusterStrings.R' 'Concordance.R' diff --git a/NAMESPACE b/NAMESPACE index 5828fc5ea..f33c549ba 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -18,6 +18,7 @@ S3method(TreeLength,list) S3method(TreeLength,multiPhylo) S3method(TreeLength,numeric) S3method(TreeLength,phylo) +S3method(names,cidData) S3method(print,CharacterHierarchy) S3method(print,SearchControl) S3method(summary,morphyPtr) @@ -47,6 +48,7 @@ export(GapHandler) export(GetMorphyLength) export(IWScore) export(IWTreeSearch) +export(InfoConsensus) export(JackLabels) export(Jackknife) export(LengthAdded) @@ -160,6 +162,7 @@ importFrom(TreeDist,ClusteringInfo) importFrom(TreeDist,ClusteringInfoDistance) importFrom(TreeDist,Entropy) importFrom(TreeDist,MutualClusteringInfo) +importFrom(TreeDist,MutualClusteringInfoSplits) importFrom(TreeDist,SharedPhylogeneticInfo) importFrom(TreeDist,entropy_int) importFrom(TreeTools,AddUnconstrained) @@ -215,12 +218,9 @@ importFrom(TreeTools,TreeIsRooted) importFrom(TreeTools,as.Splits) importFrom(TreeTools,as.multiPhylo) importFrom(abind,abind) -importFrom(ape,consensus) -importFrom(ape,keep.tip) importFrom(ape,nodelabels) importFrom(ape,plot.phylo) importFrom(ape,read.nexus) -importFrom(ape,root) importFrom(ape,write.nexus) importFrom(cli,cli_alert) importFrom(cli,cli_alert_danger) diff --git a/R/Concordance.R b/R/Concordance.R index 1f526fb27..d2ab01491 100644 --- a/R/Concordance.R +++ b/R/Concordance.R @@ -591,7 +591,6 @@ MutualClusteringConcordance <- function(tree, dataset) { #' #' @param weight Logical specifying whether to weight sites according to the #' number of quartets they are decisive for. -#' @importFrom ape keep.tip #' @importFrom cli cli_progress_bar cli_progress_update #' @importFrom utils combn #' @importFrom TreeTools as.Splits PhyDatToMatrix TipLabels @@ -797,7 +796,7 @@ SharedPhylogeneticConcordance <- function(tree, dataset) { characters <- as.multiPhylo(dataset) support <- rowSums(vapply(characters, function (char) { - trimmed <- lapply(splits, keep.tip, TipLabels(char)) + trimmed <- KeepTip(splits, TipLabels(char)) cbind(mi = SharedPhylogeneticInfo(char, trimmed), possible = ClusteringInfo(trimmed)) }, matrix(NA_real_, length(splits), 2)), dims = 2) diff --git a/R/CustomSearch.R b/R/CustomSearch.R index eb16e198f..d1eb0b455 100644 --- a/R/CustomSearch.R +++ b/R/CustomSearch.R @@ -180,7 +180,7 @@ TreeSearch <- function (tree, dataset, stopAtPeak = FALSE, stopAtPlateau = 0L, verbosity = 1L, ...) { if (dim(tree[["edge"]])[1] != 2 * tree[["Nnode"]]) { - stop("tree must be bifurcating; try rooting with ape::root") + stop("tree must be bifurcating; try rooting with RootTree()") } tree <- RenumberTips(tree, names(dataset)) edgeList <- tree[["edge"]] diff --git a/R/InfoConsensus.R b/R/InfoConsensus.R new file mode 100644 index 000000000..515341942 --- /dev/null +++ b/R/InfoConsensus.R @@ -0,0 +1,995 @@ +#' Information-theoretic consensus tree +#' +#' Find a consensus tree that maximizes the mean Mutual Clustering +#' Information (MCI) with a set of input trees, using a driven search with +#' TBR, ratchet, drift, sectorial search, and tree fusing. +#' +#' Unlike the majority-rule consensus, which minimizes Robinson-Foulds +#' distance and can be highly unresolved when phylogenetic signal is low, +#' `InfoConsensus()` finds a more resolved tree that maximizes a finer-grained +#' information-theoretic measure of agreement with the input trees. +#' +#' The search uses MRP (Matrix Representation with Parsimony) characters +#' for fast incremental screening during TBR, with MCI verification for +#' move acceptance. This provides the full power of the driven search +#' pipeline (ratchet, drift, sectorial search, tree fusing, multi-replicate +#' parallelism) with MCI scoring. +#' +#' The search proceeds in up to three phases: +#' 1. **Driven search** using the C++ engine with MCI scoring. +#' 2. **Collapse/resolve refinement** (when `collapse = TRUE`): greedily +#' collapse internal edges whose removal improves the score, then try +#' resolving remaining polytomies. +#' 3. **Rogue taxon dropping** (when `neverDrop != TRUE`): iteratively +#' identify and remove taxa whose absence improves consensus quality, +#' then attempt to restore previously dropped taxa. +#' +#' @param trees An object of class `multiPhylo`: the input trees. +#' All trees must share the same tip labels. +#' @param maxReplicates Integer: maximum number of independent search +#' replicates. Each replicate starts from a different random Wagner tree. +#' @param targetHits Integer: stop after finding the best score this many +#' times independently. +#' @param maxSeconds Numeric: timeout in seconds (0 = no timeout). +#' @param nThreads Integer: number of threads for inter-replicate parallelism. +#' Defaults to `getOption("mc.cores", 1L)`. +#' @param treeSample Controls how many input trees are used during Phase 1 +#' (driven search). CID verification cost scales linearly with the number +#' of input trees, so with large tree sets (hundreds or thousands of trees), +#' using a representative subsample for the search phase and verifying +#' against the full set afterwards can be faster without sacrificing quality. +#' +#' - `"auto"` (default): automatically selects a subsample size based on +#' the number of tips. Benchmarking on a 1449-taxon mammal bootstrap +#' dataset (Lemoine _et al._ 2018) showed that consensus quality +#' (measured as full-set MCI) saturates at 50--100 input trees and can +#' _degrade_ with larger subsamples under fixed time budgets, because +#' the additional CID cost displaces search replicates. The auto +#' heuristic is: `min(T, max(50, 2 * n_tip))`, capped at `T`. +#' - An integer: use exactly this many trees (sampled without replacement). +#' - `Inf` or `NULL`: use all trees (no subsampling). +#' +#' Subsampling applies only to Phase 1. Phases 2 (collapse/resolve) and 3 +#' (rogue taxon dropping) always score against the **full** input tree set, +#' and the returned `score` attribute reflects the full-set MCI. +#' @param collapse Logical: if `TRUE` (default), run a collapse/resolve +#' refinement phase after the binary search. This can produce a +#' non-binary result when collapsing a split improves the mean MCI. +#' @param neverDrop Controls rogue taxon dropping (Phase 3). +#' `TRUE` disables dropping entirely. +#' `FALSE` (default) allows all taxa to be dropped if doing so improves +#' the consensus. +#' A character or integer vector specifies tips that must never be dropped; +#' all others are candidates. +#' @param maxDrop Integer: maximum number of tips that may be dropped during +#' rogue screening. Default `ceiling(nTip / 10)` (10 percent of tips). +#' @param control A [`SearchControl()`] object for expert tuning of the +#' driven search strategy. +#' @param screeningK Numeric: implied-weights concavity constant for MRP +#' character screening during TBR. The search uses MRP (Matrix +#' Representation with Parsimony) characters as a fast proxy for MCI +#' scoring; `screeningK` controls how these characters are weighted. +#' Default `7` (IW with `k = 7`), which empirically maximizes rank +#' correlation with MCI scores. Use `Inf` for equal-weight screening. +#' @param screeningTolerance Numeric (>= 0): controls how generously +#' candidate moves are sent to full MCI evaluation. A value of `0` +#' (default) only evaluates the single best MRP-screened candidate per +#' clip. Values > 0 relax the screening threshold, allowing candidates +#' whose MRP score exceeds the current best by up to this fraction (e.g., +#' `0.02` = $2%$ tolerance). Higher values improve search quality at the +#' cost of more MCI evaluations per step. +#' @param screeningTopK Integer: number of top MRP-screened candidates to +#' evaluate via full MCI scoring per TBR clip. Default `1` uses the +#' single best MRP candidate (original behaviour). Values > 1 (e.g., `5`) +#' score the top-k MRP candidates and accept the one with the best MCI, +#' catching moves where MRP and MCI rankings disagree. Cost scales +#' linearly with `screeningTopK`. +#' @param method Character: the scoring method for consensus optimization. +#' - `"mci"` (default): Mutual Clustering Information. Measures the average +#' information shared between the consensus and each input tree. Requires +#' a LAP solver per input tree -- high quality but expensive. +#' - `"spic"`: Splitwise Phylogenetic Information Content (Smith 2022). Sums +#' the phylogenetic information content of each split in the consensus, +#' weighted by its frequency in the input trees (interpreted as the +#' probability that the split is correct). Much faster than MCI because +#' scoring is split-additive -- no pairwise tree comparison needed. +#' Naturally discounts low-support splits (those whose frequency is close +#' to the baseline rate under random trees contribute near-zero +#' information). +#' @param verbosity Integer controlling console output (0 = silent). +#' +#' @return A tree of class `phylo` with attributes: +#' - `"score"`: mean MCI between the consensus and the input trees +#' (higher is better). +#' - `"hits"`: the number of times this score was found. +#' - `"droppedTips"`: character vector of dropped taxa (if any), or `NULL`. +#' +#' @examples +#' library(TreeTools) +#' # Generate some trees +#' trees <- as.phylo(1:30, nTip = 12) +#' +#' # Quick search +#' result <- InfoConsensus(trees, maxReplicates = 3L, targetHits = 2L, +#' neverDrop = TRUE, verbosity = 0) +#' plot(result) +#' attr(result, "score") +#' +#' # Compare with majority-rule consensus +#' mr <- Consensus(trees, p = 0.5) +#' mean(TreeDist::ClusteringInfoDistance(mr, trees)) +#' mean(TreeDist::ClusteringInfoDistance(result, trees)) +#' +#' @seealso [MaximizeParsimony()] uses the same driven search engine for +#' parsimony. +#' @seealso [TreeDist::TransferDistance()] and [Quartet::QuartetConsensus()] +#' for alternative consensus methods. +#' % TODO: add \insertCite reference for Smith 2026 when available in TreeDist +#' +#' @references +#' \insertRef{Smith2020}{TreeSearch} +#' +#' @importFrom TreeDist ClusteringInfoDistance ClusteringEntropy +#' MutualClusteringInfoSplits +#' @importFrom TreeTools as.Splits Consensus MakeTreeBinary NTip RenumberEdges +#' @family custom search functions +#' @export +InfoConsensus <- function(trees, + maxReplicates = 5L, + targetHits = 2L, + maxSeconds = 0, + nThreads = getOption("mc.cores", 1L), + treeSample = "auto", + collapse = TRUE, + neverDrop = FALSE, + maxDrop = min(5L, ceiling(NTip(trees[[1]]) / 10)), + control = SearchControl(), + screeningK = 7, + screeningTolerance = 0, + screeningTopK = 1L, + method = c("mci", "spic"), + verbosity = 1L) { + if (!inherits(trees, "multiPhylo")) { + stop("`trees` must be an object of class 'multiPhylo'.") + } + if (length(trees) < 2L) { + stop("Need at least 2 input trees.") + } + + method <- match.arg(method) + scoringMethodInt <- switch(method, mci = 0L, spic = 1L) + methodLabel <- switch(method, mci = "MCI", spic = "SPIC") + + tipLabels <- trees[[1]][["tip.label"]] + nTip <- length(tipLabels) + + # Validate consistent tip labels + for (i in seq_along(trees)) { + if (length(trees[[i]][["tip.label"]]) != nTip) { + stop("All input trees must have the same number of tips. ", + "Tree ", i, " has ", length(trees[[i]][["tip.label"]]), + " tips; expected ", nTip, ".") + } + } + + nTree <- length(trees) + + # --- Tree subsampling for Phase 1 --- + # CID verification cost is O(T * n_tip) per candidate. With large tree + # sets, this dominates wall time and displaces search replicates. + # Benchmarking (mammals 1449-taxon bootstrap, 1000 trees, 50-/100-tip + # subsets, 60-/120-s budgets) showed: + # - MCI quality saturates at T_sub ~ 50-100, regardless of tip count + # - At 100 tips, quality *degrades* beyond T_sub ~ 100 under fixed + # time budgets (CID cost displaces exploration) + # - MRP split deduplication makes the Fitch screening layer insensitive + # to T (97% dedup at T=1000), so the bottleneck is CID verification + # Heuristic: use min(T, max(50, 2 * n_tip)) trees for Phase 1. + # Phases 2-3 always use the full set. + searchTrees <- .SubsampleTrees(trees, nTree, nTip, treeSample, verbosity) + + # Phase 1: C++ driven search (on subsample if applicable) + result <- .CIDDrivenSearch(searchTrees, tipLabels, nTip, + maxReplicates, targetHits, maxSeconds, + nThreads, control, + screeningK, screeningTolerance, screeningTopK, + scoringMethodInt, + verbosity) + + # Phases 2-3 use the full tree set for accurate scoring. + # Re-score Phase 1 result against full set if we subsampled. + subsampled <- length(searchTrees) < nTree + if (subsampled) { + cidData <- .MakeCIDData(trees, tipLabels, method) + subScore <- attr(result, "score") + fullScore <- .ScoreTree(result, cidData) + attr(result, "score") <- fullScore + if (verbosity > 0L) { + message(" Subsample ", methodLabel, ": ", signif(-subScore, 6), + " -> full-set ", methodLabel, ": ", signif(-fullScore, 6), + " (", nTree, " trees)") + } + } + + # Phase 2: Collapse/resolve refinement (full tree set) + if (collapse) { + if (!exists("cidData", inherits = FALSE)) { + cidData <- .MakeCIDData(trees, tipLabels, method) + } + result <- .CollapseRefine(result, cidData, verbosity) + } + + # Phase 3: rogue taxon dropping (full tree set) + if (!isTRUE(neverDrop)) { + if (!exists("cidData", inherits = FALSE)) { + cidData <- .MakeCIDData(trees, tipLabels, method) + } + result <- .RogueRefine(result, cidData, neverDrop, maxDrop, + "ratchet", # method for re-optimization + 2L, 2L, # light ratchet for re-opt + 100L, 10L, collapse, + scoringMethodInt, + verbosity) + } + + # Convert internal score (negated) to user-facing positive score + internalScore <- attr(result, "score") + if (!is.null(internalScore)) { + attr(result, "score") <- -internalScore + } + + result +} + + + + + +.NoOp <- function(x) invisible(NULL) + +# Null-coalesce (base R %||% requires R >= 4.4) +.NullOr <- function(x, default) if (is.null(x)) default else x + + +# Select a subsample of input trees for Phase 1 search. +# +# With large tree sets, CID verification O(T * n_tip) per candidate +# dominates wall time. Subsampling to T_sub trees for the search phase +# preserves quality (the unique split landscape saturates early) while +# freeing time for more search replicates. +# +# Returns: multiPhylo of at most tSub trees (random without replacement). +.SubsampleTrees <- function(trees, nTree, nTip, treeSample, verbosity) { + # Resolve treeSample to an integer target + if (is.null(treeSample) || (is.numeric(treeSample) && is.infinite(treeSample))) { + return(trees) # No subsampling + } + + if (identical(treeSample, "auto")) { + # Heuristic: min(T, max(50, 2 * nTip)). + # At 50 tips, T_sub = 100; at 100 tips, T_sub = 200; at 25 tips, T_sub = 50. + # Benchmark showed quality saturates by T_sub ~ 50-100 regardless of + # tip count; the 2*nTip term provides a safety margin for larger trees + # where the split landscape is richer. + tSub <- min(nTree, max(50L, 2L * nTip)) + } else if (is.numeric(treeSample) && length(treeSample) == 1L) { + tSub <- min(nTree, max(2L, as.integer(treeSample))) + } else { + stop("`treeSample` must be \"auto\", a positive integer, Inf, or NULL.", + call. = FALSE) + } + + if (tSub >= nTree) return(trees) + + if (verbosity > 0L) { + message(" Subsampling ", tSub, " of ", nTree, + " input trees for Phase 1 search") + } + + idx <- sample.int(nTree, tSub) + trees[idx] +} + + +# Light re-optimization via the C++ driven search. +# Used by .RogueRefine() after dropping a rogue taxon. +# Arguments mirror the old TopologySearch interface for backward compatibility +# with .RogueRefine(); the actual search delegates to ts_cid_consensus. +.TopologySearch <- function(tree, cidData, method, + ratchIter, ratchHits, + searchIter, searchHits, collapse, + scoringMethodInt = 0L, + verbosity) { + tipLabels <- cidData$tipLabels + nTip <- cidData$nTip + + splitMats <- cidData$inputSplitsRaw + + # C++ engine expects a binary tree; resolve any polytomies + startTree <- if (ape::is.binary(tree)) tree else MakeTreeBinary(tree) + startEdge <- startTree[["edge"]] + + result <- ts_cid_consensus( + splitMatrices = splitMats, + nTip = nTip, + normalize = FALSE, + maxReplicates = max(1L, as.integer(ratchIter)), + targetHits = max(1L, as.integer(ratchHits)), + verbosity = max(0L, as.integer(verbosity) - 1L), + nThreads = 1L, + startEdge = startEdge, + scoringMethod = scoringMethodInt + ) + + if (result[["pool_size"]] == 0L) { + attr(tree, "score") <- .ScoreTree(tree, cidData) + return(tree) + } + + bestEdge <- result[["trees"]][[1]] + bestTree <- .EdgeListToPhylo(bestEdge[, 1], bestEdge[, 2], tipLabels) + attr(bestTree, "score") <- result[["best_score"]] + + if (collapse) { + bestTree <- .CollapseRefine(bestTree, cidData, + verbosity = max(0L, verbosity - 1L)) + } + + bestTree +} + + +# Phase 1: C++ driven search with MCI scoring. +# Converts input trees to split matrices and calls the C++ engine. +# Returns tree with attr("score") = positive MCI (higher = better). +.CIDDrivenSearch <- function(trees, tipLabels, nTip, + maxReplicates, targetHits, + maxSeconds, nThreads, control, + screeningK, screeningTolerance, + screeningTopK, + scoringMethodInt = 0L, + verbosity) { + # Convert input trees to split matrices (RawMatrix format) + splitMats <- lapply(trees, function(tr) { + unclass(as.Splits(tr, tipLabels)) + }) + + # Extract SearchControl parameters + ctrl <- control + + # Sectors only benefit trees large enough for meaningful partitioning. + # CID scoring is expensive per evaluation, so skip sectors on small trees + # where TBR alone converges quickly. + useSectors <- nTip >= 20L + + # CID scoring is ~50-100x more expensive per evaluation than parsimony, + + # so use lighter search parameters than the parsimony defaults. + # Each replicate takes ~10-25s at 50 tips; 10 replicates is usually + # sufficient for CID landscape convergence. + result <- ts_cid_consensus( + splitMatrices = splitMats, + nTip = nTip, + normalize = FALSE, + maxReplicates = maxReplicates, + targetHits = targetHits, + tbrMaxHits = .NullOr(ctrl[["tbrMaxHits"]], 1L), + ratchetCycles = .NullOr(ctrl[["ratchetCycles"]], 2L), + ratchetPerturbProb = .NullOr(ctrl[["ratchetPerturbProb"]], 0.25), + ratchetPerturbMode = .NullOr(ctrl[["ratchetPerturbMode"]], 0L), + ratchetAdaptive = .NullOr(ctrl[["ratchetAdaptive"]], FALSE), + driftCycles = .NullOr(ctrl[["driftCycles"]], 1L), + driftAfdLimit = .NullOr(ctrl[["driftAfdLimit"]], 3L), + driftRfdLimit = .NullOr(ctrl[["driftRfdLimit"]], 0.1), + xssRounds = .NullOr(ctrl[["xssRounds"]], if (useSectors) 1L else 0L), + xssPartitions = .NullOr(ctrl[["xssPartitions"]], 4L), + rssRounds = .NullOr(ctrl[["rssRounds"]], if (useSectors) 1L else 0L), + cssRounds = .NullOr(ctrl[["cssRounds"]], 0L), + cssPartitions = .NullOr(ctrl[["cssPartitions"]], 4L), + sectorMinSize = .NullOr(ctrl[["sectorMinSize"]], 6L), + sectorMaxSize = .NullOr(ctrl[["sectorMaxSize"]], 50L), + fuseInterval = .NullOr(ctrl[["fuseInterval"]], 3L), + fuseAcceptEqual = .NullOr(ctrl[["fuseAcceptEqual"]], FALSE), + poolMaxSize = 100L, + poolSuboptimal = 0.0, + maxSeconds = maxSeconds, + verbosity = verbosity, + tabuSize = .NullOr(ctrl[["tabuSize"]], 100L), + wagnerStarts = .NullOr(ctrl[["wagnerStarts"]], 1L), + nThreads = nThreads, + screeningK = screeningK, + screeningTolerance = screeningTolerance, + screeningTopK = screeningTopK, + scoreTol = .NullOr(ctrl[["scoreTol"]], 1e-5), + plateauReps = .NullOr(ctrl[["plateauReps"]], 3L), + scoringMethod = scoringMethodInt + ) + + # Convert best tree from edge matrix to phylo + if (result[["pool_size"]] == 0L) { + warning("MCI search found no trees; returning majority-rule consensus.", + call. = FALSE) + tree <- Consensus(trees, p = 0.5) + # Internal: 0 is worst possible negated MCI + attr(tree, "score") <- 0 + attr(tree, "hits") <- 0L + return(tree) + } + + bestEdge <- result[["trees"]][[1]] + tree <- .EdgeListToPhylo(bestEdge[, 1], bestEdge[, 2], tipLabels) + # Internal score: negated MCI from C++ (lower = better) + attr(tree, "score") <- result[["best_score"]] + attr(tree, "hits") <- result[["hits_to_best"]] + tree +} + + +# Build CID dataset. +# Uses an environment for reference semantics. S3 class "cidData" with a +# names() method so that TreeSearch/Ratchet can call names(dataset) to get +# tip labels. Precomputes input tree splits and clustering entropies. +.MakeCIDData <- function(trees, tipLabels, method = "mci") { + env <- new.env(parent = emptyenv()) + env$trees <- trees + env$tipLabels <- tipLabels + env$nTip <- length(tipLabels) + env$method <- method + + inputSplits <- lapply(trees, as.Splits, tipLabels) + env$inputCE <- vapply(inputSplits, ClusteringEntropy, double(1)) + env$meanInputCE <- mean(env$inputCE) + # Store raw (unclass'd) split matrices for direct C++ access + env$inputSplitsRaw <- lapply(inputSplits, unclass) + + class(env) <- "cidData" + env +} + +#' @export +names.cidData <- function(x) x$tipLabels + + +# Score candidate tree against all input trees using MCI. +# Returns negated mean MCI (lower = better), consistent with C++ cid_score(). +# Delegates to ts_cid_score_trees for the optimised C++ path (precomputed +# hash index, log2 values, bounded early exit, persistent scratch buffers). +.CIDScorer <- function(parent, child, dataset) { + scorer <- if (identical(dataset$method, "spic")) { + ts_spic_score_trees + } else { + ts_cid_score_trees + } + scorer(dataset$inputSplitsRaw, dataset$nTip, + list(cbind(parent, child)))[1L] +} + + +# CID bootstrapper: resample input trees with replacement, then search. +# Also resamples precomputed splits/CEs for the fast CID path. +.CIDBootstrap <- function(edgeList, cidData, + EdgeSwapper = RootedNNISwap, + maxIter, maxHits, + verbosity = 1L, + stopAtPeak = FALSE, + stopAtPlateau = 0L, ...) { + origTrees <- cidData$trees + nTree <- length(origTrees) + idx <- sample.int(nTree, replace = TRUE) + cidData$trees <- origTrees[idx] + + # Also resample precomputed splits/entropies + origSplitsRaw <- cidData$inputSplitsRaw + origCE <- cidData$inputCE + origMeanCE <- cidData$meanInputCE + cidData$inputSplitsRaw <- origSplitsRaw[idx] + cidData$inputCE <- origCE[idx] + cidData$meanInputCE <- mean(origCE[idx]) + on.exit({ + cidData$trees <- origTrees + cidData$inputSplitsRaw <- origSplitsRaw + cidData$inputCE <- origCE + cidData$meanInputCE <- origMeanCE + }) + + res <- EdgeListSearch(edgeList[1:2], cidData, + TreeScorer = .CIDScorer, + EdgeSwapper = EdgeSwapper, + maxIter = maxIter, maxHits = maxHits, + verbosity = verbosity, + stopAtPeak = stopAtPeak, + stopAtPlateau = stopAtPlateau, ...) + res[1:2] +} + + +# Greedy collapse/resolve refinement. +# Iteratively tries collapsing each internal edge; accepts if score improves. +# Then tries resolving each polytomy; accepts if score improves. +# Repeats until no improvement. +# +# All collapse/resolve candidates per pass are batch-scored in a single +# ts_cid_score_trees() call, amortising CidData construction (hash-index +# build, log2 precomputation) across the candidate set. +.CollapseRefine <- function(tree, cidData, verbosity = 0L) { + tipLabels <- cidData$tipLabels + nTip <- cidData$nTip + splitMats <- cidData$inputSplitsRaw + methodLabel <- if (identical(cidData$method, "spic")) "SPIC" else "MCI" + scorer <- if (identical(cidData$method, "spic")) { + ts_spic_score_trees + } else { + ts_cid_score_trees + } + edge <- tree[["edge"]] + parent <- edge[, 1L] + child <- edge[, 2L] + + bestScore <- scorer(splitMats, nTip, list(edge))[1L] + + if (verbosity > 0L) { + message(" - Collapse/resolve refinement. Starting ", methodLabel, ": ", + signif(-bestScore, 6)) + } + + improved <- TRUE + while (improved) { + improved <- FALSE + + # --- Collapse pass: batch-score all collapse candidates --- + internalEdges <- which(child > nTip) + if (length(internalEdges) > 0L) { + candidates <- lapply(internalEdges, function(idx) { + cand <- .CollapseSpecificEdge(parent, child, idx, nTip) + cbind(cand[[1L]], cand[[2L]]) + }) + scores <- scorer(splitMats, nTip, candidates) + bestIdx <- which.min(scores) + if (scores[[bestIdx]] < bestScore - sqrt(.Machine[["double.eps"]])) { + bestEdge <- candidates[[bestIdx]] + parent <- bestEdge[, 1L] + child <- bestEdge[, 2L] + bestScore <- scores[[bestIdx]] + improved <- TRUE + if (verbosity > 1L) { + message(" * Collapsed edge -> ", methodLabel, " ", signif(-bestScore, 6)) + } + next + } + } + + # --- Resolve pass: batch-score all resolve candidates --- + degrees <- tabulate(parent, nbins = max(parent)) + polyNodes <- which(degrees > 2L) + if (length(polyNodes) > 0L) { + candidates <- list() + for (node in polyNodes) { + childEdges <- which(parent == node) + nChildren <- length(childEdges) + if (nChildren <= 2L) next + for (a in seq_len(nChildren - 1L)) { + for (b in seq(a + 1L, nChildren)) { + cand <- .ResolveSpecificPair(parent, child, node, + childEdges[c(a, b)], nTip) + candidates <- c(candidates, list(cbind(cand[[1L]], cand[[2L]]))) + } + } + } + if (length(candidates) > 0L) { + scores <- scorer(splitMats, nTip, candidates) + bestIdx <- which.min(scores) + if (scores[[bestIdx]] < bestScore - sqrt(.Machine[["double.eps"]])) { + bestEdge <- candidates[[bestIdx]] + parent <- bestEdge[, 1L] + child <- bestEdge[, 2L] + bestScore <- scores[[bestIdx]] + improved <- TRUE + if (verbosity > 1L) { + message(" * Resolved polytomy -> ", methodLabel, " ", signif(-bestScore, 6)) + } + } + } + } + } + + if (verbosity > 0L) { + message(" - Collapse/resolve complete. Final ", methodLabel, ": ", + signif(-bestScore, 6)) + } + + result <- .EdgeListToPhylo(parent, child, tipLabels) + attr(result, "score") <- bestScore + result +} + + + +# --- Phase 3: Rogue taxon dropping and restoration ------------------------- + +# Greedy rogue dropping followed by greedy restoration. +# Uses C++ prescreen (ts_cid_prescreen_rogue) for the first iteration +# (no tips yet dropped); subsequent iterations use R-level pruning. +# Accepts drops based on prescreen score alone (no per-candidate +# re-optimization), then does one light re-optimization at the end. +.RogueRefine <- function(tree, cidData, neverDrop, maxDrop, + method, ratchIter, ratchHits, + searchIter, searchHits, collapse, + scoringMethodInt = 0L, + verbosity) { + originalTrees <- cidData$trees + allTipLabels <- cidData$tipLabels + methodLabel <- if (identical(cidData$method, "spic")) "SPIC" else "MCI" + bestScore <- .ScoreTree(tree, cidData) + currentTips <- tree[["tip.label"]] + nTip <- length(currentTips) + if (nTip < 5L) return(tree) + protected <- if (isFALSE(neverDrop)) { + character(0) + } else if (is.character(neverDrop)) { + bad <- setdiff(neverDrop, allTipLabels) + if (length(bad)) { + warning("neverDrop tips not found in trees: ", + paste(bad, collapse = ", "), call. = FALSE) + } + intersect(neverDrop, allTipLabels) + } else if (is.numeric(neverDrop)) { + allTipLabels[as.integer(neverDrop)] + } else { + character(0) + } + droppedTips <- character(0) + maxDrop <- as.integer(min(maxDrop, nTip - max(4L, length(protected) + 1L))) + if (verbosity > 0L) { + message(" - Rogue screening phase. Starting ", methodLabel, ": ", + signif(-bestScore, 6), " (", nTip, " tips, maxDrop = ", + maxDrop, ")") + } + improved <- TRUE + while (improved && + length(droppedTips) < maxDrop && + length(currentTips) > max(4L, length(protected) + 1L)) { + improved <- FALSE + droppable <- setdiff(currentTips, protected) + if (length(droppable) == 0L) break + prescreenScores <- .PrescreenMarginalNID( + tree, cidData, droppable, originalTrees, allTipLabels, droppedTips + ) + # Accept the single best drop directly (no per-candidate re-optimization) + bestIdx <- which.min(prescreenScores) + if (prescreenScores[bestIdx] < bestScore - sqrt(.Machine[["double.eps"]])) { + tip <- names(prescreenScores)[bestIdx] + reducedTips <- setdiff(currentTips, tip) + allDropped <- c(droppedTips, tip) + reducedInputTrees <- .PruneTrees(originalTrees, allDropped) + reducedCidData <- .MakeCIDData(reducedInputTrees, reducedTips, + cidData$method) + tree <- DropTip(tree, tip) + # Score the pruned tree on the properly pruned input trees + bestScore <- .ScoreTree(tree, reducedCidData) + currentTips <- reducedTips + cidData <- reducedCidData + droppedTips <- allDropped + improved <- TRUE + if (verbosity > 0L) { + message(" * Dropped '", tip, "' -> ", methodLabel, " ", + signif(-bestScore, 6), + " (", length(currentTips), " tips)") + } + } + } + + # Light re-optimization after all drops are decided + if (length(droppedTips) > 0L && length(currentTips) >= 8L) { + if (verbosity > 0L) { + message(" - Re-optimizing after rogue removal") + } + reoptResult <- .TopologySearch( + tree, cidData, "ratchet", + max(1L, ratchIter %/% 2L), ratchHits, + searchIter, searchHits, collapse, + scoringMethodInt, + max(0L, verbosity - 1L)) + reoptScore <- attr(reoptResult, "score") + if (!is.null(reoptScore) && reoptScore < bestScore) { + tree <- reoptResult + bestScore <- reoptScore + } + } + + if (length(droppedTips) > 0L) { + if (verbosity > 0L) { + message(" - Restore phase: trying to re-insert ", + length(droppedTips), " dropped tip(s)") + } + restoredAny <- TRUE + while (restoredAny) { + restoredAny <- FALSE + for (idx in rev(seq_along(droppedTips))) { + tip <- droppedTips[idx] + insertion <- .BestInsertion( + tree, tip, originalTrees, + droppedTips[-idx], + cidData$method + ) + if (insertion$score < bestScore - sqrt(.Machine[["double.eps"]])) { + tree <- insertion$tree + bestScore <- insertion$score + cidData <- insertion$cidData + currentTips <- tree[["tip.label"]] + droppedTips <- droppedTips[-idx] + restoredAny <- TRUE + if (verbosity > 0L) { + message(" * Restored '", tip, "' -> ", methodLabel, " ", + signif(-bestScore, 6), + " (", length(currentTips), " tips)") + } + break + } + } + } + } + if (verbosity > 0L) { + message(" - Rogue screening complete. Final ", methodLabel, ": ", + signif(-bestScore, 6), + if (length(droppedTips)) paste0( + " (dropped: ", paste(droppedTips, collapse = ", "), ")" + ) else " (no tips dropped)") + } + attr(tree, "score") <- bestScore + attr(tree, "droppedTips") <- if (length(droppedTips)) droppedTips else NULL + tree +} + + +# Pre-screen rogue candidates via C++ bit-masking. +# For each tip in `droppable`, masks out the tip from pre-built split data +# and scores in C++ -- no R-level DropTip/as.Splits needed. +# When tips have already been dropped, falls back to the R-level path. +.PrescreenMarginalNID <- function(tree, cidData, droppable, + originalTrees, allTipLabels, + alreadyDropped) { + useSPIC <- identical(cidData$method, "spic") + if (length(alreadyDropped) == 0L) { + # Fast C++ path: mask each tip from the full split data + tipLabels <- cidData$tipLabels + dropIdx <- match(droppable, tipLabels) + prescreenFn <- if (useSPIC) ts_spic_prescreen_rogue else ts_cid_prescreen_rogue + scores <- prescreenFn( + cidData$inputSplitsRaw, cidData$nTip, + tree[["edge"]], dropIdx + ) + names(scores) <- droppable + return(scores) + } + + # Fallback: tips already dropped, need pruned input trees + scoreFn <- if (useSPIC) ts_spic_score_trees else ts_cid_score_trees + vapply(droppable, function(tip) { + reducedTips <- setdiff(tree[["tip.label"]], tip) + allDropped <- c(alreadyDropped, tip) + reducedInputTrees <- .PruneTrees(originalTrees, allDropped) + splitMats <- lapply(reducedInputTrees, + function(tr) unclass(as.Splits(tr, reducedTips))) + reducedTree <- DropTip(tree, tip) + scoreFn(splitMats, length(reducedTips), + list(reducedTree[["edge"]]))[1L] + }, double(1)) +} + + +.PruneTrees <- function(trees, tipsToDrop) { + if (length(tipsToDrop) == 0L) return(trees) + pruned <- lapply(trees, DropTip, tip = tipsToDrop) + class(pruned) <- "multiPhylo" + pruned +} + + +.ScoreTree <- function(tree, cidData) { + scorer <- if (identical(cidData$method, "spic")) { + ts_spic_score_trees + } else { + ts_cid_score_trees + } + scorer(cidData$inputSplitsRaw, cidData$nTip, + list(tree[["edge"]]))[1L] +} + + +.EdgeListToPhylo <- function(parent, child, tipLabels) { + nTip <- length(tipLabels) + result <- structure(list( + edge = cbind(parent, child), + tip.label = tipLabels, + Nnode = length(unique(parent[parent > nTip])) + ), class = "phylo") + reorder(result) +} + + +# Try inserting tipLabel at every edge of tree; return the best position. +# Batch-scores all insertion candidates in a single ts_cid_score_trees() call +# so CidData is built once (not once per insertion position). +.BestInsertion <- function(tree, tipLabel, originalTrees, + otherDropped, + method = "mci") { + currentTips <- c(tree[["tip.label"]], tipLabel) + inputTrees <- if (length(otherDropped) > 0L) { + .PruneTrees(originalTrees, otherDropped) + } else { + originalTrees + } + testCidData <- .MakeCIDData(inputTrees, currentTips, method) + splitMats <- testCidData$inputSplitsRaw + nTip <- length(currentTips) + scorer <- if (identical(method, "spic")) ts_spic_score_trees else ts_cid_score_trees + + nEdge <- nrow(tree[["edge"]]) + candidates <- lapply(seq_len(nEdge), + function(i) .InsertTipAtEdge(tree, tipLabel, i)[["edge"]]) + + scores <- scorer(splitMats, nTip, candidates) + bestIdx <- which.min(scores) + + bestEdge <- candidates[[bestIdx]] + bestTree <- .EdgeListToPhylo(bestEdge[, 1L], bestEdge[, 2L], currentTips) + list(tree = bestTree, score = scores[[bestIdx]], cidData = testCidData) +} + + +.InsertTipAtEdge <- function(tree, tipLabel, edgeIdx) { + edge <- tree[["edge"]] + tipLabels <- tree[["tip.label"]] + nTip <- length(tipLabels) + nNode <- tree[["Nnode"]] + pNode <- edge[edgeIdx, 1] + cNode <- edge[edgeIdx, 2] + newTipIdx <- nTip + 1L + newEdge <- edge + internals <- newEdge > nTip + newEdge[internals] <- newEdge[internals] + 1L + newPNode <- pNode + 1L + newCNode <- if (cNode > nTip) cNode + 1L else cNode + newInternalIdx <- as.integer(nTip + nNode + 2L) + newEdge[edgeIdx, 2] <- newInternalIdx + newEdge <- rbind(newEdge, + c(newInternalIdx, newCNode), + c(newInternalIdx, newTipIdx)) + result <- structure(list( + edge = newEdge, + tip.label = c(tipLabels, tipLabel), + Nnode = nNode + 1L + ), class = "phylo") + reorder(result) +} + +# --- Topology manipulation helpers (unchanged) ---------------------------- + +# Collapse a specific edge (by index), returning renumbered parent/child. +.CollapseSpecificEdge <- function(parent, child, edgeIdx, nTip) { + nEdge <- length(parent) + collapseParent <- parent[edgeIdx] + collapseChild <- child[edgeIdx] + + # Reparent all children of collapseChild to collapseParent + childOfCollapsed <- which(parent == collapseChild) + parent[childOfCollapsed] <- collapseParent + + # Remove the collapsed edge + keep <- seq_len(nEdge) != edgeIdx + parent <- parent[keep] + child <- child[keep] + + .RenumberNodes(parent, child, nTip) +} + + +# Resolve a specific pair of child edges under a polytomy node. +.ResolveSpecificPair <- function(parent, child, node, moveEdges, nTip) { + newNode <- max(c(parent, child)) + 1L + + # New edge: node -> newNode + parent <- c(parent, node) + child <- c(child, newNode) + + # Reparent selected children + parent[moveEdges] <- newNode + + list(parent, child) +} + + +# Collapse a random internal edge, creating a polytomy. +.CollapseEdge <- function(parent, child, nTip) { + nEdge <- length(parent) + # Internal edges: both parent and child are internal nodes + internalEdges <- which(child > nTip) + + if (length(internalEdges) == 0L) { + # Star tree -- nothing to collapse + return(list(parent, child)) + } + + # Pick a random internal edge to collapse + edgeIdx <- internalEdges[sample.int(length(internalEdges), 1L)] + collapseParent <- parent[edgeIdx] + collapseChild <- child[edgeIdx] + + # Reparent all children of collapseChild to collapseParent + childOfCollapsed <- which(parent == collapseChild) + parent[childOfCollapsed] <- collapseParent + + # Remove the collapsed edge + keep <- seq_len(nEdge) != edgeIdx + parent <- parent[keep] + child <- child[keep] + + # Renumber internal nodes to fill the gap + .RenumberNodes(parent, child, nTip) +} + + +# Resolve a random polytomy by inserting a new internal node. +.ResolveNode <- function(parent, child, nTip) { + # Find polytomy nodes (> 2 children) + degrees <- tabulate(parent) + polyNodes <- which(degrees > 2L) + + if (length(polyNodes) == 0L) { + return(list(parent, child)) + } + + # Pick a random polytomy + node <- polyNodes[sample.int(length(polyNodes), 1L)] + childEdges <- which(parent == node) + nChildren <- length(childEdges) + + # Pick 2+ children to move to a new internal node + # (pick exactly 2 for a single-step resolution) + nToMove <- 2L + if (nChildren <= nToMove) { + # Can't resolve a node with <= 2 children + return(list(parent, child)) + } + moveEdges <- childEdges[sample.int(nChildren, nToMove)] + + # Insert new node + nNode <- max(parent) + newNode <- nNode + 1L + + # New edge: node -> newNode + parent <- c(parent, node) + child <- c(child, newNode) + + # Reparent selected children + parent[moveEdges] <- newNode + + list(parent, child) +} + + +# EdgeSwapper: collapse a random internal edge. +.CollapseSwap <- function(parent, child, nTip = min(parent) - 1L, ...) { + .CollapseEdge(parent, child, nTip) +} + + +# EdgeSwapper: resolve a random polytomy. +.ResolveSwap <- function(parent, child, nTip = min(parent) - 1L, ...) { + .ResolveNode(parent, child, nTip) +} + + +# Renumber internal nodes to be contiguous from nTip+1. +.RenumberNodes <- function(parent, child, nTip) { + allNodes <- sort(unique(c(parent, child))) + internalNodes <- allNodes[allNodes > nTip] + # Map old node numbers to new contiguous range + newNumbers <- seq_along(internalNodes) + nTip + nodeMap <- integer(max(internalNodes)) + # Tips map to themselves + nodeMap[seq_len(nTip)] <- seq_len(nTip) + nodeMap[internalNodes] <- newNumbers + + list(nodeMap[parent], nodeMap[child]) +} diff --git a/R/Jackknife.R b/R/Jackknife.R index fce0b7941..3291cebed 100644 --- a/R/Jackknife.R +++ b/R/Jackknife.R @@ -27,7 +27,7 @@ Jackknife <- function(tree, dataset, resampleFreq = 2 / 3, jackIter = 5000L, searchIter = 4000L, searchHits = 42L, verbosity = 1L, ...) { if (dim(tree[["edge"]])[1] != 2 * tree[["Nnode"]]) { - stop("tree must be bifurcating; try rooting with ape::root") + stop("tree must be bifurcating; try rooting with RootTree()") } tree <- RenumberTips(tree, names(dataset)) diff --git a/R/Ratchet.R b/R/Ratchet.R index 280a0b7b8..68d1990f7 100644 --- a/R/Ratchet.R +++ b/R/Ratchet.R @@ -87,7 +87,7 @@ Ratchet <- function(tree, dataset, epsilon <- sqrt(.Machine[["double.eps"]]) hits <- 0L if (dim(tree[["edge"]])[1] != 2 * tree[["Nnode"]]) { - stop("tree must be bifurcating; try rooting with ape::root") + stop("tree must be bifurcating; try rooting with RootTree()") } tree <- RenumberTips(tree, names(dataset)) edgeList <- tree[["edge"]] @@ -253,7 +253,7 @@ Ratchet <- function(tree, dataset, #' @rdname Ratchet #' @return `MultiRatchet()` returns a list of optimal trees #' produced by `nSearch` `Ratchet()` searches, from which a consensus tree can -#' be generated using [`ape::consensus()`] or [`TreeTools::ConsensusWithout()`]. +#' be generated using [`Consensus()`][TreeTools::Consensus] or [`TreeTools::ConsensusWithout()`]. #' @param nSearch Number of Ratchet searches to conduct #' (for `RatchetConsensus()`) #' @export diff --git a/R/RcppExports.R b/R/RcppExports.R index f70456fda..cb83ff08e 100644 --- a/R/RcppExports.R +++ b/R/RcppExports.R @@ -172,10 +172,7 @@ ts_xss_search <- function(edge, contrast, tip_data, weight, levels, nPartitions .Call(`_TreeSearch_ts_xss_search`, edge, contrast, tip_data, weight, levels, nPartitions, xssRounds, acceptEqual, ratchetCycles, maxHits, min_steps, concavity) } -# Thin wrapper for the C++ ts_driven_search (10 grouped args). -# Production callers (MaximizeParsimony, .ResampleHierarchy) call this directly. -# Tests use ts_driven_search() in ts-driven-compat.R for backward compatibility. -.ts_driven_search_raw <- function(contrast, tip_data, weight, levels, searchControl, runtimeConfig, scoringConfig, constraintConfig = NULL, hsjConfig = NULL, xformConfig = NULL) { +ts_driven_search <- function(contrast, tip_data, weight, levels, searchControl, runtimeConfig, scoringConfig, constraintConfig = NULL, hsjConfig = NULL, xformConfig = NULL) { .Call(`_TreeSearch_ts_driven_search`, contrast, tip_data, weight, levels, searchControl, runtimeConfig, scoringConfig, constraintConfig, hsjConfig, xformConfig) } @@ -215,3 +212,23 @@ ts_test_strategy_tracker <- function(seed, n_draws) { .Call(`_TreeSearch_ts_test_strategy_tracker`, seed, n_draws) } +ts_cid_consensus <- function(splitMatrices, nTip, normalize, maxReplicates = 100L, targetHits = 10L, tbrMaxHits = 1L, ratchetCycles = 10L, ratchetPerturbProb = 0.04, ratchetPerturbMode = 0L, ratchetAdaptive = FALSE, driftCycles = 6L, driftAfdLimit = 3L, driftRfdLimit = 0.1, xssRounds = 0L, xssPartitions = 4L, rssRounds = 0L, cssRounds = 0L, cssPartitions = 4L, sectorMinSize = 6L, sectorMaxSize = 50L, fuseInterval = 3L, fuseAcceptEqual = FALSE, poolMaxSize = 100L, poolSuboptimal = 0.0, maxSeconds = 0.0, verbosity = 0L, tabuSize = 100L, wagnerStarts = 1L, nThreads = 1L, screeningK = 7.0, screeningTolerance = 0.0, screeningTopK = 1L, scoreTol = 0.0, plateauReps = 0L, startEdge = NULL, progressCallback = NULL, scoringMethod = 0L) { + .Call(`_TreeSearch_ts_cid_consensus`, splitMatrices, nTip, normalize, maxReplicates, targetHits, tbrMaxHits, ratchetCycles, ratchetPerturbProb, ratchetPerturbMode, ratchetAdaptive, driftCycles, driftAfdLimit, driftRfdLimit, xssRounds, xssPartitions, rssRounds, cssRounds, cssPartitions, sectorMinSize, sectorMaxSize, fuseInterval, fuseAcceptEqual, poolMaxSize, poolSuboptimal, maxSeconds, verbosity, tabuSize, wagnerStarts, nThreads, screeningK, screeningTolerance, screeningTopK, scoreTol, plateauReps, startEdge, progressCallback, scoringMethod) +} + +ts_cid_score_trees <- function(splitMatrices, nTip, candidateEdges) { + .Call(`_TreeSearch_ts_cid_score_trees`, splitMatrices, nTip, candidateEdges) +} + +ts_cid_prescreen_rogue <- function(splitMatrices, nTip, candidateEdge, droppableTips) { + .Call(`_TreeSearch_ts_cid_prescreen_rogue`, splitMatrices, nTip, candidateEdge, droppableTips) +} + +ts_spic_score_trees <- function(splitMatrices, nTip, candidateEdges) { + .Call(`_TreeSearch_ts_spic_score_trees`, splitMatrices, nTip, candidateEdges) +} + +ts_spic_prescreen_rogue <- function(splitMatrices, nTip, candidateEdge, droppableTips) { + .Call(`_TreeSearch_ts_spic_prescreen_rogue`, splitMatrices, nTip, candidateEdge, droppableTips) +} + diff --git a/R/SPR.R b/R/SPR.R index ef58b82fd..a326f12bc 100644 --- a/R/SPR.R +++ b/R/SPR.R @@ -85,7 +85,6 @@ SPRWarning <- function (parent, child, error) { #' tree <- ape::rtree(20, br=FALSE) #' SPR(tree) #' } -#' @importFrom ape root #' @importFrom TreeTools Preorder #' @export SPR <- function(tree, edgeToBreak = NULL, mergeEdge = NULL) { @@ -143,10 +142,10 @@ SPRMoves.phylo <- function (tree, edgeToBreak = integer(0)) { rootNode <- nTip + 1L if (edge[1] != rootNode) { - stop("edge[1,] must connect root to leaf. Try Preorder(root(tree))."); + stop("edge[1,] must connect root to leaf. Try Preorder(RootTree(tree))."); } if (edge[2] != rootNode) { - stop("edge[2,] must connect root to leaf. Try Preorder(root(tree))."); + stop("edge[2,] must connect root to leaf. Try Preorder(RootTree(tree))."); } # Return: all_spr(edge, break_order) diff --git a/R/SearchControl.R b/R/SearchControl.R index 14388294c..4de7bc3f2 100644 --- a/R/SearchControl.R +++ b/R/SearchControl.R @@ -77,6 +77,16 @@ #' Inspired by IQ-TREE's unsuccessful-perturbation stopping rule #' \insertCite{Nguyen2015}{TreeSearch}; adapted from per-perturbation to #' per-replicate granularity. +#' @param scoreTol Numeric; minimum score improvement to count as meaningful +#' for convergence detection. Default 0 (any strict improvement counts). +#' When positive, improvements smaller than `scoreTol` do not reset the +#' unsuccessful-replicate counter, allowing `perturbStopFactor` and +#' `plateauReps` to detect convergence in continuous-score modes (e.g. CID). +#' @param plateauReps Integer; stop after this many consecutive replicates +#' without meaningful improvement (as determined by `scoreTol`). +#' 0 disables this criterion (default). +#' Unlike `perturbStopFactor` (which scales with tree size), this is an +#' absolute count suitable for small replicate budgets. #' @param adaptiveLevel Logical; dynamically scale ratchet and drift effort #' based on the observed hit rate? When `TRUE`, easy landscapes #' (high hit rate) trigger reduced effort per replicate, while hard @@ -226,6 +236,8 @@ SearchControl <- function( # Stopping criteria consensusStableReps = 0L, perturbStopFactor = 2L, + scoreTol = 0, + plateauReps = 0L, adaptiveLevel = FALSE, consensusConstrain = FALSE, # Taxon pruning-reinsertion (T-266) @@ -282,6 +294,8 @@ SearchControl <- function( poolSuboptimal = as.double(poolSuboptimal), consensusStableReps = as.integer(consensusStableReps), perturbStopFactor = as.integer(perturbStopFactor), + scoreTol = as.double(scoreTol), + plateauReps = as.integer(plateauReps), adaptiveLevel = as.logical(adaptiveLevel), consensusConstrain = as.logical(consensusConstrain), pruneReinsertCycles = as.integer(pruneReinsertCycles), @@ -320,7 +334,7 @@ print.SearchControl <- function(x, ...) { "Fuse/Pool" = c("fuseInterval", "fuseAcceptEqual", "intraFuse", "poolMaxSize", "poolSuboptimal"), "Stopping" = c("consensusStableReps", "perturbStopFactor", - "adaptiveLevel", + "scoreTol", "plateauReps", "adaptiveLevel", "consensusConstrain", "adaptiveStart") ) cat("SearchControl object\n") diff --git a/R/SuccessiveApproximations.R b/R/SuccessiveApproximations.R index 104198128..9e067cc2a 100644 --- a/R/SuccessiveApproximations.R +++ b/R/SuccessiveApproximations.R @@ -26,7 +26,6 @@ #' @references #' \insertAllCited{} #' -#' @importFrom ape consensus root #' @family custom search functions #' @export SuccessiveApproximations <- function (tree, dataset, outgroup = NULL, k = 3, @@ -130,7 +129,7 @@ SuccessiveApproximations <- function (tree, dataset, outgroup = NULL, k = 3, } if (!is.null(outgroup)) { - tr <- root(tr, outgroup, resolve.root = TRUE) + tr <- RootTree(tr, outgroup) } structure( diff --git a/R/TBR.R b/R/TBR.R index d0bf968ef..dd76ee83c 100644 --- a/R/TBR.R +++ b/R/TBR.R @@ -50,7 +50,6 @@ TBRWarning <- function (parent, child, error) { #' #' @family tree rearrangement functions #' @seealso [`RootedTBR()`]: useful when the position of the root node should be retained. -#' @importFrom ape root #' @importFrom TreeTools DescendantEdges Preorder #' @export TBR <- function(tree, edgeToBreak = NULL, mergeEdges = NULL) { diff --git a/build_cid.sh b/build_cid.sh new file mode 100644 index 000000000..7d5f8c657 --- /dev/null +++ b/build_cid.sh @@ -0,0 +1,57 @@ +#!/bin/bash +#SBATCH --job-name=build-cid +#SBATCH --output=/nobackup/pjjg18/ts-bench/results/build_cid.log +#SBATCH --error=/nobackup/pjjg18/ts-bench/results/build_cid.err +#SBATCH -n 4 +#SBATCH --time=0:30:00 +#SBATCH --mem=4000M +#SBATCH -p shared + +module load r/4.5.1 +module load gcc/14.2 + +export OMP_NUM_THREADS=1 +export OPENBLAS_NUM_THREADS=1 + +BENCH=/nobackup/pjjg18/ts-bench +REPO=$BENCH/TreeSearch +LIB=$BENCH/lib-cid + +# Make deps visible to R CMD INSTALL +export R_LIBS="$LIB:$BENCH/lib-baseline" + +mkdir -p "$LIB" + +rm -f "$REPO"/src/*.o "$REPO"/src/*.so + +TMPDIR=$(mktemp -d) +echo "Building tarball in $TMPDIR..." +(cd "$TMPDIR" && R CMD build --no-build-vignettes --no-manual --no-resave-data "$REPO") + +echo "Installing to $LIB..." +R CMD INSTALL --library="$LIB" "$TMPDIR"/TreeSearch_*.tar.gz +BUILD_STATUS=$? + +rm -rf "$TMPDIR" + +echo "Build exit status: $BUILD_STATUS" + +if [ $BUILD_STATUS -eq 0 ]; then + echo "Verifying build..." + Rscript -e " + .libPaths(c('$LIB', '$BENCH/lib-baseline', .libPaths())) + library(TreeSearch) + cat('TreeSearch version:', as.character(packageVersion('TreeSearch')), '\n') + cat('InfoConsensus available:', exists('InfoConsensus', where='package:TreeSearch', mode='function'), '\n') + library(TreeTools) + trees <- lapply(1:10, function(i) RandomTree(20)) + class(trees) <- 'multiPhylo' + cat('Smoke test: scoring 10 random 20-tip trees...\n') + result <- InfoConsensus(trees, neverDrop = TRUE, maxSeconds = 10) + cat('Result class:', class(result), '\n') + cat('Result tips:', Ntip(result), '\n') + cat('Build verification PASSED\n') + " +else + echo "BUILD FAILED" +fi diff --git a/completed-tasks.md b/completed-tasks.md index eb11f9f90..78039e5b6 100644 --- a/completed-tasks.md +++ b/completed-tasks.md @@ -94,6 +94,11 @@ Tasks moved here from `to-do.md` on completion. Newest first. | T-180 | Warm-start benchmark infrastructure | G | `bench_warmstart.R`: `compute_warmstart_tree()` (sprint→TBR optimum), `warmstart_run()` (single rep from warm start), `warmstart_benchmark()` (grid), `warmstart_summary()`. Isolates ratchet/drift escape from initial descent. Verified: Vinther2008 sprint→80, warm-start→79. Commit 13a019e3. | --- +## 2026-03-21 + +| ID | Description | Agent | Notes | +|----|-------------|-------|-------| +| T-150 | CID-optimal consensus tree search | P | Fixed critical two-baseline bug (TBR/drift/SPR non-functional in CID mode). Implemented 6 CID performance optimizations (hash-based exact match, precomputed log2, persistent buffers, presized LAP scratch, bounded early termination, batch log2 reuse). Wired score_budget into TBR/SPR for CID early termination. Fixed inter-replicate CID data race (per-thread CidData deep copy). All 1708 tests pass. | ## 2026-03-20 diff --git a/dev/analysis/cid-scaling/cid-scaling-analysis.md b/dev/analysis/cid-scaling/cid-scaling-analysis.md new file mode 100644 index 000000000..a96d13c56 --- /dev/null +++ b/dev/analysis/cid-scaling/cid-scaling-analysis.md @@ -0,0 +1,195 @@ +# CID Consensus: Scaling with Input Tree Count + +**Date:** 2026-03-26 +**Hardware:** Hamilton 8 HPC (AMD EPYC 7702, 1 core, 8 GB) +**TreeSearch version:** 2.0.0 (commit dc28a696, `feature/cid-consensus`) +**Dataset:** Mammals bootstrap (Lemoine et al. 2018), 1000 trees × 1449 tips, +via Consense package `LoadDataset("mammals_full")` + +## Summary + +CID verification cost per candidate scales as O(T × n^2.4), dominated by the +O(n^3) LAP solver within `mutual_clustering_info()`. MRP split deduplication +(97% compression at T=1000) makes the Fitch screening layer essentially +insensitive to T, so the bottleneck is CID verification alone. + +Consensus quality (full-set MCI) saturates at T_sub ≈ 50–100 trees and +degrades at higher T_sub under fixed time budgets. This motivated the +`treeSample` auto-selection in `InfoConsensus()`. + +## Experiment 1: Quality vs. T_sub (tree subsampling) + +**Design:** For each T_sub value (10–1000), run `InfoConsensus()` on a random +subsample of T_sub trees, then evaluate the result against the full 1000-tree +set. 3 random seeds per condition. + +**Tip subsamples:** 50 tips (60s budget) and 100 tips (120s budget), drawn +from the 1439 shared tips via `SubsampleTips()`. + +**Data:** `cid_tsub_50tips_20260326_1017.csv`, `cid_tsub_100tips_20260326_1227.csv` + +### Key metrics + +| Metric | Description | +|--------|-------------| +| `score` | MCI of result against the T_sub subsample (internal objective) | +| `full_mci` | MCI of result against all 1000 trees (true quality) | +| `cid_to_ref` | CID to NCBI reference tree (external validation) | + +### Results + +**50 tips:** Quality plateaus at T_sub ≈ 20–30. MCI within 1% of maximum +from T_sub=30 onward. Wall time barely increases (54s → 62s) due to MRP +dedup (47,000 total splits → 1,217 unique, 97.4% compression). + +**100 tips:** Quality peaks at T_sub ≈ 30–70 (median MCI 16.1 bits) and +*degrades* to 15.4 bits at T_sub=1000 (95.2% of peak). Wall time increases +from 109s to 143s. The degradation occurs because additional CID cost +displaces search replicates under the fixed time budget. + +### Baselines + +| Scenario | InfoConsensus MCI | Majority-rule MCI | Strict MCI | +|----------|:-----------------:|:-----------------:|:----------:| +| 50 tips | 10.7 | 2.27 | 0.40 | +| 100 tips | 16.1 | 3.13 | 0.00 | + +InfoConsensus achieves 4–5× the MCI of majority-rule consensus. + +### Auto-selection heuristic + +Based on these results, `InfoConsensus()` now defaults to +`treeSample = "auto"`, which selects `min(T, max(50, 2 * n_tip))` trees +for Phase 1. Phases 2 (collapse/resolve) and 3 (rogue dropping) always +use the full tree set. + +## Experiment 2: Per-candidate CID verification cost + +**Design:** Generate 50 random candidate trees per condition, batch-score +via `ts_cid_score_trees()` against subsamples of the input set. 3 reps +per condition. This isolates the CID scoring cost from search dynamics. + +**Data:** `cid_profile_20260326_1353.csv` + +### Per-candidate cost (median, microseconds) + +| T_sub | 50 tips | 100 tips | 200 tips | +|------:|---------:|---------:|----------:| +| 10 | 1,420 | 7,300 | 40,740 | +| 20 | 2,820 | 14,060 | 79,960 | +| 50 | 7,100 | 35,280 | 199,540 | +| 100 | 14,320 | 70,760 | 404,780 | +| 200 | 28,480 | 140,920 | 978,840 | +| 500 | 71,180 | 352,740 | 1,998,020 | +| 1,000 | 142,020 | 705,540 | 4,030,760 | + +### Scaling analysis + +**Linear in T:** Per-tree marginal cost is constant within each tip count +(R² = 1.000): + +| Tips | Per-tree cost | Intercept | +|-----:|--------------:|----------:| +| 50 | 142 µs | 42 µs | +| 100 | 706 µs | 53 µs | +| 200 | 4,031 µs | 27,385 µs | + +**Power law in n:** Fitting `cost ~ n^α` across tip counts gives +α ≈ 2.41 (R² = 0.999). The dominant cost is the Jonker–Volgenant LAP +solver within `mutual_clustering_info()`, which is O(n^3) worst-case. +The observed exponent < 3 reflects early exit and hash-based split matching. + +### Practical impact on TBR throughput + +Each TBR pass evaluates approximately (n_tip − 3) candidates. +CID wall time per TBR pass (seconds): + +| T_sub | 50 tips | 100 tips | 200 tips | +|------:|--------:|---------:|---------:| +| 50 | 0.3 | 3.4 | 39.7 | +| 100 | 0.7 | 6.8 | 79.4 | +| 500 | 3.3 | 34.2 | 397 | +| 1,000 | 6.7 | 68.5 | 794 | + +At 200 tips with 1000 trees, a single TBR pass takes ~13 minutes in CID +verification alone. This confirms that subsampling is essential for +large-scale CID consensus. + +## Where the time goes + +| Component | Cost | Notes | +|-----------|------|-------| +| Input split construction (as.Splits) | ~0.5 ms/tree | One-time; negligible | +| MRP split dedup + Fitch screening | ~0.02 ms/candidate | O(unique_splits × n) | +| Candidate split computation | O(n) per candidate | ~microseconds | +| **CID verification (LAP solver)** | **O(T × n^2.4)/candidate** | **Bottleneck** | + +The LAP solver accounts for >99% of per-candidate evaluation cost. +Optimizing input processing (e.g. TreeTools C++ headers for split +construction) would not measurably improve throughput. + +## Implications for future optimization + +1. **Subsampling (implemented):** T_sub ≈ 50–100 is sufficient for + quality; auto-selection via `treeSample = "auto"` addresses this. + +2. **LAP solver optimization:** The O(n^3) Jonker–Volgenant solver is the + fundamental bottleneck. Possible approaches: + - Approximate MCI via sampling or truncation + - Sparse cost matrix exploitation (many split pairs have zero overlap) + - SIMD-accelerated LAP + - Bounded LAP (early exit when assignment can't beat budget) — already + partially implemented via `score_budget` + +3. **Incremental CID:** Currently every candidate requires full CID + re-evaluation. An incremental variant that updates only the affected + splits after a TBR move would reduce per-candidate cost from O(T × n^3) + to O(T × k^3) where k = number of changed splits (~4 per TBR move). + This is the highest-impact optimization path. + +4. **Parallel CID:** The T tree evaluations within `cid_score()` are + independent and could be parallelized across threads. Currently + parallelism is only at the inter-replicate level. + +## Note on TreeTools C++ headers + +TreeSearch already `LinkingTo: TreeTools`, making several C++ headers +available. Relevance to the CID pipeline: + +### `SplitList` (split bitvector construction from RawMatrix) + +Structurally identical to our `CidSplitSet` unpack (both are byte → 64-bit +word with popcount). Could replace our manual unpack in +`ts_cid_consensus()` lines 2727–2749, but this is one-time setup (~0.5 ms +per tree), not the bottleneck. + +### `preorder_edges_and_nodes()` (fast preorder renumbering) + +Our C++ `cid_tree_from_edge()` + `build_postorder()` serves the same +purpose. The TreeTools version renumbers nodes in a single pass with +stack-allocated frames. Could save a few microseconds per +`ts_cid_score_trees()` call, but again not on the critical path. + +### `ClusterTable` (Day 1985) + +Day's cluster table represents a tree as a list of clusters ⟨L, R⟩ where +each cluster is an interval of leaf internal-labels. This enables O(n) +shared-cluster counting between two trees (`SETSW` + `SHARED`). + +**Potential relevance to CID:** Phase 1 of `mutual_clustering_info()` +already does O(n) exact-match split identification via hash lookup +(lines 210–236). ClusterTable could replace this with an O(n) interval +check. However: + +- Our hash-based path is already O(n) amortised. ClusterTable's advantage + is constant factors and no hash collisions, but exact matching is a small + fraction of total cost. +- The LAP phase (which handles non-matching splits) dominates. ClusterTable + cannot help here because it only answers containment queries, not the + pairwise overlap counts (`|a ∩ b|`) needed for the LAP cost matrix. + +**Verdict:** ClusterTable would marginally speed up the exact-match phase +of MCI, but the LAP dominates (~95% of cost for dissimilar trees). +Worth flagging for if exact matches become a larger fraction (e.g. with +subsampled bootstrap trees that share substantial structure). Not a +priority for the current bottleneck. diff --git a/dev/analysis/cid-scaling/cid_profile_20260326_1353.csv b/dev/analysis/cid-scaling/cid_profile_20260326_1353.csv new file mode 100644 index 000000000..549c75729 --- /dev/null +++ b/dev/analysis/cid-scaling/cid_profile_20260326_1353.csv @@ -0,0 +1,64 @@ +"n_tips","t_sub","rep","n_candidates","wall_ms","per_cand_us","mean_score" +50,10,1,50,140.000000000001,2800.00000000001,-5.5210978345469 +50,10,2,50,70.9999999999997,1419.99999999999,-5.55498701564631 +50,10,3,50,70.9999999999997,1419.99999999999,-5.4602665987932 +50,20,1,50,141,2820,-5.5412056223547 +50,20,2,50,139.000000000001,2780.00000000002,-5.47331623659395 +50,20,3,50,144,2880,-5.66620070807305 +50,50,1,50,350,6999.99999999999,-5.62720685561499 +50,50,2,50,355,7100.00000000001,-5.45121180064956 +50,50,3,50,355,7100.00000000001,-5.52879237175295 +50,100,1,50,715.999999999999,14320,-5.5414919309764 +50,100,2,50,719.999999999999,14400,-5.53535009683097 +50,100,3,50,712.999999999997,14259.9999999999,-5.46615371052908 +50,200,1,50,1422,28440,-5.54410043218298 +50,200,2,50,1424,28480,-5.51266856398471 +50,200,3,50,1425,28500,-5.51907167281646 +50,500,1,50,3559,71179.9999999999,-5.53987566769685 +50,500,2,50,3554,71080,-5.52557875785992 +50,500,3,50,3566,71320,-5.5367776527885 +50,1000,1,50,7103,142060,-5.53359196193203 +50,1000,2,50,7101,142020,-5.53359196193203 +50,1000,3,50,7098.00000000001,141960,-5.53359196193203 +100,10,1,50,370.000000000005,7400.00000000009,-7.93582774690618 +100,10,2,50,365.000000000002,7300.00000000004,-7.920882571109 +100,10,3,50,363.999999999997,7279.99999999994,-7.84808151908788 +100,20,1,50,707.999999999998,14160,-7.80796051212181 +100,20,2,50,702.999999999996,14059.9999999999,-7.81814640567253 +100,20,3,50,698,13960,-8.05876486242563 +100,50,1,50,1759,35180,-8.00285127671972 +100,50,2,50,1769,35380,-7.84406925185491 +100,50,3,50,1764,35279.9999999999,-7.87750916122319 +100,100,1,50,3530,70600,-7.90467740151729 +100,100,2,50,3541,70819.9999999999,-7.83161050440438 +100,100,3,50,3538,70759.9999999999,-7.79306522249339 +100,200,1,50,7045.99999999999,140920,-7.92846140708229 +100,200,2,50,7024,140480,-7.87564154057062 +100,200,3,50,7065,141300,-7.86947130370616 +100,500,1,50,17637,352740,-7.90404720895461 +100,500,2,50,17622,352440,-7.89379264433121 +100,500,3,50,17692,353840,-7.89717318948606 +100,1000,1,50,35277,705540,-7.89726271807568 +100,1000,2,50,35269,705380,-7.89726271807569 +100,1000,3,50,35294,705880,-7.89726271807568 +200,10,1,50,1985.99999999999,39719.9999999998,-10.1741388574741 +200,10,2,50,2036.99999999998,40739.9999999996,-10.037148549652 +200,10,3,50,2076.00000000002,41520.0000000004,-10.0240089273488 +200,20,1,50,4098.00000000001,81960.0000000002,-9.93432976685617 +200,20,2,50,3997.99999999999,79959.9999999998,-10.0544315236606 +200,20,3,50,3984.00000000004,79680.0000000007,-10.3235488790188 +200,50,1,50,9959,199180,-10.2624375407561 +200,50,2,50,9978.99999999999,199580,-10.13925148988 +200,50,3,50,9976.99999999997,199539.999999999,-10.1035986339177 +200,100,1,50,20239,404780.000000001,-10.0878771453331 +200,100,2,50,20134,402680,-10.0521211262133 +200,100,3,50,24235,484700,-10.0326067431021 +200,200,1,50,50996,1019920,-10.143899680904 +200,200,2,50,48942,978840,-10.1021471828867 +200,200,3,50,47739,954780,-10.0892774053652 +200,500,1,50,110311,2206220,-10.1395162048374 +200,500,2,50,99901.0000000001,1998020,-10.1251415506067 +200,500,3,50,99820.9999999999,1996420,-10.1103279079258 +200,1000,1,50,201538,4030760,-10.1251812096677 +200,1000,2,50,199292,3985840,-10.1251812096677 +200,1000,3,50,233003,4660060,-10.1251812096677 diff --git a/dev/analysis/cid-scaling/cid_tsub_100tips_20260326_1227.csv b/dev/analysis/cid-scaling/cid_tsub_100tips_20260326_1227.csv new file mode 100644 index 000000000..98bd9ebb8 --- /dev/null +++ b/dev/analysis/cid-scaling/cid_tsub_100tips_20260326_1227.csv @@ -0,0 +1,64 @@ +"n_tips","n_total_trees","t_sub","seed","wall_seconds","score","full_cid","full_mci","cid_to_ref" +100,1000,10,2841,108.65,17.1429380975327,43.411,15.6521,35.2254 +100,1000,10,5073,108.95,16.1888476382686,41.5638,15.2504,33.1514 +100,1000,10,9417,108.62,17.4653220836993,43.9535,15.7028,35.2254 +100,1000,20,2841,110.24,16.692960068102,41.7134,15.9814,34.0859 +100,1000,20,5073,109.78,15.8930925612791,41.8331,15.5767,33.8993 +100,1000,20,9417,109.6,16.3884028383593,42.5336,15.8718,34.6159 +100,1000,30,2841,110.02,16.5403777632794,41.6527,15.6959,34.199 +100,1000,30,5073,110.25,16.0106718984347,43.3625,16.0666,36.9145 +100,1000,30,9417,110.08,16.2997018776686,42.7449,16.1171,34.1984 +100,1000,40,2841,113.85,16.7938386602961,42.39,16.0304,34.555 +100,1000,40,5073,111.47,16.074936541765,42.0364,16.1787,34.8377 +100,1000,40,9417,110.26,16.1615436425009,41.1979,16.018,32.9619 +100,1000,50,2841,115.85,16.5179039113094,41.8449,15.983,34.2526 +100,1000,50,5073,110.87,15.948315126795,41.3913,16.1028,33.8861 +100,1000,50,9417,111.94,16.1811079672836,42.5645,16.0114,34.6298 +100,1000,60,2841,111.9,16.2670282586471,41.6262,15.9952,34.0852 +100,1000,60,5073,115.62,16.0431975130764,42.0199,16.1399,35.1402 +100,1000,60,9417,118.26,16.2181684580059,41.0924,16.192,34.2748 +100,1000,70,2841,113.22,16.2363947865844,41.0217,15.9717,33.3825 +100,1000,70,5073,116.53,16.179808787001,41.099,16.2231,34.3394 +100,1000,70,9417,118.53,16.2920774767488,41.9806,16.1284,34.3165 +100,1000,80,2841,125.85,16.1062577441363,41.8834,15.933,34.8841 +100,1000,80,5073,118.1,15.9691498750637,41.3626,16.011,34.8441 +100,1000,80,9417,114.37,16.3347634221894,43.1123,16.22,35.5316 +100,1000,90,2841,117.5,16.1385422931898,40.9667,15.9492,33.3461 +100,1000,90,5073,120.3,16.0712883628746,40.4313,16.0972,32.2896 +100,1000,90,9417,115.69,16.2274117936897,42.8433,16.1596,35.6565 +100,1000,100,2841,117.14,15.810294488479,40.9076,15.6969,33.2197 +100,1000,100,5073,120.51,15.6730164085699,39.9936,15.7201,31.0489 +100,1000,100,9417,120.07,16.3818008261542,42.6464,16.2803,35.4117 +100,1000,150,2841,123.92,15.9196364680814,40.2162,15.8864,32.3021 +100,1000,150,5073,121.16,15.8857488552989,42.0049,16.0145,34.3349 +100,1000,150,9417,118.37,16.2420061019587,41.6241,16.168,34.5225 +100,1000,200,2841,120.41,15.6509108651825,40.6908,15.7491,32.8603 +100,1000,200,5073,125.23,15.5882372211693,41.6727,15.7371,33.9898 +100,1000,200,9417,120.65,15.8646325031838,40.424,15.927,32.9837 +100,1000,250,2841,126.15,15.1065932206564,41.8952,15.1441,33.5451 +100,1000,250,5073,122.75,15.7560496135301,41.6204,15.9552,34.088 +100,1000,250,9417,121.86,16.0201234838002,41.2875,16.0692,33.95 +100,1000,300,2841,126.78,15.0924489498308,42.6643,15.1901,36.4211 +100,1000,300,5073,120.56,15.6768766151499,41.2965,15.8117,32.2353 +100,1000,300,9417,126.42,16.1047938505414,41.1661,16.1179,34.1132 +100,1000,350,2841,128.73,15.1127997398111,40.1131,15.224,32.6586 +100,1000,350,5073,122.95,15.6654621647381,41.6673,15.8368,33.9034 +100,1000,350,9417,121.08,15.7110854684897,40.3052,15.755,32.4405 +100,1000,400,2841,130.82,15.2949527661878,39.5331,15.4451,30.6081 +100,1000,400,5073,131.84,15.5774179115232,40.6481,15.8415,31.6926 +100,1000,400,9417,129.33,16.0000136167824,40.7988,16.012,33.5256 +100,1000,450,2841,124.33,14.6687455262708,41.4461,14.8005,33.8729 +100,1000,450,5073,125.56,15.2994076856074,39.7099,15.53,30.6206 +100,1000,450,9417,126.46,15.9985392589587,41.6224,16.0095,33.9736 +100,1000,500,2841,120.62,14.5885453090091,41.7283,14.68,34.3942 +100,1000,500,5073,130.38,15.607767809601,41.4344,15.7926,32.2395 +100,1000,500,9417,135.03,15.7299251806649,40.1884,15.7735,32.4058 +100,1000,700,2841,135.96,15.0334709087836,38.849,15.2026,31.166 +100,1000,700,5073,131.86,15.4813368152008,40.9621,15.6412,32.3777 +100,1000,700,9417,136.11,15.5803572958347,39.1109,15.6524,31.244 +100,1000,900,2841,143,14.8910227661431,41.8604,15.0356,33.3907 +100,1000,900,5073,143.17,15.4404894062191,40.5129,15.5979,31.9279 +100,1000,900,9417,145.62,15.6850990118793,39.3863,15.8233,31.4995 +100,1000,1000,2841,130.66,14.5790619504452,40.4989,14.7352,32.4958 +100,1000,1000,5073,123.48,15.214202223619,40.7031,15.3701,31.3992 +100,1000,1000,9417,146.94,15.5588870707105,39.1784,15.7224,30.9513 diff --git a/dev/analysis/cid-scaling/cid_tsub_50tips_20260326_1017.csv b/dev/analysis/cid-scaling/cid_tsub_50tips_20260326_1017.csv new file mode 100644 index 000000000..ed5054226 --- /dev/null +++ b/dev/analysis/cid-scaling/cid_tsub_50tips_20260326_1017.csv @@ -0,0 +1,64 @@ +"n_tips","n_total_trees","t_sub","seed","wall_seconds","score","full_cid","full_mci","cid_to_ref" +50,1000,10,2841,30.94,11.6399181438916,27.2316,10.4922,20.8842 +50,1000,10,5073,28.21,11.0970962736465,26.1008,10.3195,20.7158 +50,1000,10,9417,30.58,11.4754110217324,28.8278,9.9713,22.9734 +50,1000,20,2841,52.31,11.3329723300723,26.0048,10.5195,20.503 +50,1000,20,5073,54.14,10.8463910227308,25.9385,10.6979,20.5611 +50,1000,20,9417,54.22,10.7809334397406,28.6443,10.1751,22.477 +50,1000,30,2841,54.29,11.1845630247969,25.8609,10.5313,20.8357 +50,1000,30,5073,54.26,10.6968304683352,25.6176,10.4786,19.6615 +50,1000,30,9417,54.17,10.8012024208512,25.8338,10.5841,19.3164 +50,1000,40,2841,54.25,11.1673744927101,25.9585,10.5279,20.7251 +50,1000,40,5073,54.22,10.749916444604,25.507,10.5668,19.9206 +50,1000,40,9417,54.33,10.8807067542975,25.5799,10.5868,19.8762 +50,1000,50,2841,54.39,11.035742902289,26.3887,10.6814,21.3287 +50,1000,50,5073,54.42,10.5746181412458,27.0733,10.6164,20.6368 +50,1000,50,9417,54.31,10.8508486631529,26.0505,10.7225,20.8562 +50,1000,60,2841,54.48,10.910356643553,25.7115,10.7045,20.2104 +50,1000,60,5073,54.79,10.7185374714889,27.0921,10.6693,21.7528 +50,1000,60,9417,54.36,10.816585624476,26.0738,10.7424,20.5553 +50,1000,70,2841,54.76,10.8208136080669,26.597,10.6661,22.1162 +50,1000,70,5073,54.66,10.7781081560558,26.1833,10.7134,19.9217 +50,1000,70,9417,55.07,10.8131704385037,26.4808,10.6307,20.4421 +50,1000,80,2841,54.58,10.8576348350907,25.7735,10.712,20.6457 +50,1000,80,5073,55.06,10.6923959563354,26.364,10.6186,19.6153 +50,1000,80,9417,54.53,10.7443967142664,25.68,10.702,19.5335 +50,1000,90,2841,54.92,10.8702996222613,26.0831,10.6997,21.1222 +50,1000,90,5073,54.82,10.7699671171107,25.8924,10.7383,19.8662 +50,1000,90,9417,54.72,10.7921701987223,25.56,10.7595,19.9891 +50,1000,100,2841,54.89,10.7978932252665,25.5261,10.6815,20.1607 +50,1000,100,5073,54.7,10.7533081403262,26.0296,10.6665,19.6698 +50,1000,100,9417,55.09,10.773206737232,25.8886,10.6827,20.2019 +50,1000,150,2841,59.04,10.773485144845,26.3437,10.7672,21.8425 +50,1000,150,5073,55.07,10.6646089994395,25.7658,10.7131,19.1192 +50,1000,150,9417,58.11,10.8665512483567,25.5678,10.7409,19.945 +50,1000,200,2841,55.58,10.7480207842313,25.4356,10.7701,19.7643 +50,1000,200,5073,55.34,10.7099963321166,25.9434,10.7296,19.5816 +50,1000,200,9417,56.25,10.7840480356793,26.077,10.7524,20.2133 +50,1000,250,2841,56.42,10.7006985475858,25.9674,10.7609,20.1299 +50,1000,250,5073,56.52,10.7191717583138,25.8249,10.7468,20.1181 +50,1000,250,9417,56.37,10.786262938144,25.9564,10.7666,20.1413 +50,1000,300,2841,58.31,10.6309977600103,26.0355,10.693,19.3727 +50,1000,300,5073,58.34,10.6530711976113,25.8493,10.7385,19.9054 +50,1000,300,9417,57.79,10.7965902982912,25.8009,10.7182,20.5363 +50,1000,350,2841,56.95,10.6364621171789,25.608,10.6924,19.7157 +50,1000,350,5073,58.99,10.593670670788,27.0315,10.6722,20.6415 +50,1000,350,9417,57.65,10.7892354164447,25.3844,10.7578,20.2404 +50,1000,400,2841,57.53,10.628160025809,25.7444,10.695,19.6096 +50,1000,400,5073,58.53,10.6597651056126,25.9595,10.7891,20.4165 +50,1000,400,9417,56.85,10.7894340237504,25.4282,10.7744,19.9297 +50,1000,450,2841,59.85,10.6477823605742,25.072,10.708,19.4714 +50,1000,450,5073,58.54,10.5456774851039,26.1266,10.6821,19.6062 +50,1000,450,9417,58.54,10.7971147184418,25.9443,10.7893,20.6363 +50,1000,500,2841,60.05,10.680786984643,25.5298,10.7459,20.2699 +50,1000,500,5073,58.6,10.663379553339,25.4513,10.7413,20.2759 +50,1000,500,9417,58.91,10.7701583305944,25.4148,10.779,20.0487 +50,1000,700,2841,57.79,10.5858282336043,25.4517,10.6898,19.3245 +50,1000,700,5073,59.24,10.5107871558578,26.0406,10.5789,20.1341 +50,1000,700,9417,62.26,10.7248334448211,26.3155,10.7713,21.0364 +50,1000,900,2841,59.78,10.603448372464,25.245,10.695,19.3532 +50,1000,900,5073,61.88,10.6054961290407,25.5396,10.6852,19.9386 +50,1000,900,9417,61.01,10.6815449680791,26.1656,10.7505,20.8116 +50,1000,1000,2841,62.36,10.5803715120361,25.4354,10.6709,19.5616 +50,1000,1000,5073,69.37,10.5996666043449,25.049,10.6885,19.1243 +50,1000,1000,9417,62.07,10.6597607288566,26.0935,10.7532,20.7923 diff --git a/dev/analysis/cid-scaling/incremental-cid-analysis.md b/dev/analysis/cid-scaling/incremental-cid-analysis.md new file mode 100644 index 000000000..60ad8368a --- /dev/null +++ b/dev/analysis/cid-scaling/incremental-cid-analysis.md @@ -0,0 +1,173 @@ +# Incremental CID Scoring — Feasibility Analysis + +Date: 2026-03-26 + +## Problem + +CID verification is the dominant cost in `InfoConsensus()`. Each accepted +TBR move triggers a full `cid_score()` call, which computes +`mutual_clustering_info()` for every input tree. Per-candidate cost is +O(T × n^2.4) due to the Jonker-Volgenant LAP solver. + +Measured per-candidate costs (from cid-scaling benchmarks): + +| n_tip | T=100 | T=1000 | +|:-----:|:-----:|:------:| +| 50 | 14 ms | 142 ms | +| 100 | 71 ms | 706 ms | +| 200 | 405 ms | 4,031 ms | + +## Current Pipeline + +``` +TBR candidate evaluation (all O(n^2) candidates): + → MRP/Fitch indirect scoring (fast, ~0.02 ms/candidate) + → Best MRP candidate selected + +If best MRP candidate not dominated: + → Apply move to topology + → cid_score() — FULL rescore (expensive): + for each input tree i in 1..T: + compute_splits_cid(candidate) # O(n) + mutual_clustering_info(cand, tree[i]): # O(k^2.4) + Phase 1: exact match via hash # O(n) amortised + Phase 2: LAP for unmatched splits # O(k^3) where k = unmatched + return -mean(MCI) +``` + +Only 1 CID call per accepted TBR move (not per candidate), so the issue +is cost per call, not number of calls. + +## Incremental Approaches Considered + +### A. Incremental Split Computation + +**Idea:** After a TBR move, only ~4 splits change. Maintain the split set +incrementally instead of recomputing from scratch. + +**Cost of `compute_splits_cid()` currently:** O(n) — negligible compared +to LAP. At 200 tips, split computation is ~microseconds; LAP is ~4 ms +per tree. Not worth optimizing. + +### B. Per-Tree MCI Caching with Invalidation + +**Idea:** Cache `mutual_clustering_info()` result per input tree. After a +TBR move, only recompute for trees whose matching is affected by the +changed splits. + +**Problem:** A TBR move changes ~4 candidate splits, which potentially +affects the matching with ALL input trees. Whether the matching is +actually affected depends on the optimal LAP assignment, which we'd need +to check per tree — i.e., re-examine the matching anyway. + +**Partial optimisation:** If a changed candidate split was not part of any +LAP matching (it was exactly matched), we only need to check whether its +replacement is also exactly matchable. If exact_match(old_split) and +exact_match(new_split), the MCI for that tree is unchanged except for the +local contribution of those two splits. This can be computed in O(1). + +**Benefit:** Mainly helps when input and candidate trees are similar (many +exact matches), which is exactly the regime where subsampling already +makes T small. Net benefit is modest. + +### C. Warm-Start LAP Solver + +**Idea:** After a TBR move, the LAP cost matrix changes by ~4 +rows/columns. Use the previous optimal assignment as a warm start and +re-solve only the affected portion. + +**JV algorithm warm-start:** The Jonker-Volgenant SAP algorithm maintains +dual variables (u[], v[]) and a column assignment. In principle, one could +invalidate only the rows/columns corresponding to changed splits and +re-augment from there. + +**Complexity:** Implementation is non-trivial. The JV algorithm's +augmenting-path phase assumes fresh initialization. Partial re-solve +requires careful bookkeeping of which rows/columns are "dirty" and +re-running augmentation only for those. + +**Expected speedup:** At most 4× if 4 of k splits changed and the +re-solve is O(4 × k^2) instead of O(k^3). In practice, k (unmatched +splits) is often small (5-20), so the LAP is already fast. The constant +factor of implementing warm-start may negate the asymptotic benefit. + +**Verdict:** High implementation cost, moderate benefit. Worth pursuing +only if the simpler approaches prove insufficient. + +### D. Early Termination on Input Trees (already implemented) + +The current code sets `score_budget = best_score + eps` before CID +rescoring. If accumulated MCI can't beat the budget (using a per-tree +upper bound from `clustering_entropy_fast()`), it returns early. + +**Measured benefit:** When the TBR move is actually an improvement, the +budget is the old score — so all trees are evaluated. When the move is +not an improvement, early termination kicks in after ~T/2 trees on +average (depends on how bad the move is). Since the dominated check +already filters most bad moves, the remaining CID calls are mostly +improvements, so early termination helps less often. + +**Enhancement:** Sort input trees by "expected discriminating power" +(e.g., similarity to the current candidate). Evaluate the most +discriminating trees first so early termination fires sooner for +non-improving moves. + +### E. Batch Evaluation of Top-k Candidates + +**Idea:** Instead of MRP-selecting the single best candidate, keep the +top-k MRP candidates (k=3-5) and CID-score all of them. Take the best +CID result. + +**Current code:** Only the best MRP candidate gets CID-scored. If MRP +ranking disagrees with CID ranking (which it often must — they're +different objectives), we might miss CID-improving moves. + +**Cost:** k× more CID calls per TBR pass. At 100 tips with T_sub=200 +(auto), each CID call is ~14 ms. With k=5, the additional cost is ~56 ms +per TBR pass — probably acceptable. + +**Benefit:** Better CID exploration. The MRP screening is a coarse proxy; +evaluating more candidates should find better CID moves per pass, +potentially converging in fewer TBR passes. + +**Verdict:** Medium implementation cost, potentially high benefit for +search quality (not raw per-call speed). Worth benchmarking. + +## Recommendation + +Given the treeSample = "auto" subsampling already reduces T dramatically +(1000→100-200) and makes per-call CID cost manageable: + +**Priority 1 (low effort, potential high impact):** +- **Approach E**: Batch top-k candidate evaluation. Simple to implement in + `ts_tbr.cpp` — collect top-k MRP candidates instead of just the best, + CID-score each. Expected to improve search quality. + +**Priority 2 (medium effort, moderate impact):** +- **Approach D enhancement**: Sort input trees by discriminating power. + Requires precomputing a "difficulty" score per tree during + `prepare_cid_data()`. Modest code change. + +**Priority 3 (high effort, uncertain impact):** +- **Approach C**: Warm-start LAP. Only worth pursuing if 200+ tip trees + become a primary use case and treeSample can't reduce T enough. + +**Not recommended:** +- **Approach A**: Split computation is not on the critical path. +- **Approach B**: Complexity doesn't justify benefit given subsampling. + +## Quantitative Impact Estimates + +For a typical TBR convergence at 100 tips with treeSample="auto" (T_sub=200): + +| Metric | Current | With top-5 | With sorted trees | +|--------|:-------:|:----------:|:-----------------:| +| CID calls/pass | 1 | 5 | 1 | +| Time/CID call | 14 ms | 14 ms | 14 ms (avg) | +| CID time/pass | 14 ms | 70 ms | 14 ms (same, but earlier termination) | +| TBR passes to converge | ~50 | ~30 (better moves) | ~50 | +| Total CID time | 700 ms | 2,100 ms | 500 ms (est.) | +| Total replicate time | ~3 s | ~5 s | ~2.5 s | + +The "fewer TBR passes" estimate for top-5 is speculative; actual benefit +depends on how often MRP and CID disagree on the best move. diff --git a/dev/analysis/mrp-weighting-cid-correlation.qmd b/dev/analysis/mrp-weighting-cid-correlation.qmd new file mode 100644 index 000000000..0ce14c547 --- /dev/null +++ b/dev/analysis/mrp-weighting-cid-correlation.qmd @@ -0,0 +1,224 @@ +--- +title: "MRP Weighting for CID Consensus Screening" +author: "TreeSearch development" +date: today +format: + html: + toc: true + code-fold: true + self-contained: true +execute: + cache: true + warning: false +--- + +## Motivation + +`InfoConsensus()` uses a dual-layer scoring architecture: a fast Fitch +parsimony layer on MRP (Matrix Representation with Parsimony) characters +screens TBR candidates, and a slower but exact CID (Clustering Information +Distance) layer accepts or rejects moves. The tighter the parsimony +proxy tracks CID, the fewer wasted full-CID evaluations. + +This analysis asks: **which parsimony weighting on the MRP characters best +correlates with CID among single-TBR neighbours?** + +We compare: + +- Equal weights (EW) +- Implied weights with $k \in \{1, 2, 3, 5, 10, 20\}$ +- Profile parsimony + +## Data + +We use a 60-tip subsample of the mammals bootstrap dataset from +Lemoine et al. (2018) (1000 bootstrap trees on 1449 taxa), as bundled in the +`consense` package. 100 bootstrap trees form the reference pool. + +```{r} +#| label: setup +#| message: false +library(TreeSearch) +library(TreeTools) +library(TreeDist) +library(phangorn) +library(ggplot2) +``` + +```{r} +#| label: load-data +mammal_trees <- ape::read.tree( + "../../../consense/inst/extdata/phylocrisp/extracted/mammals_full/full/full_bootstraps.tre" +) + +set.seed(4917) +all_tips <- mammal_trees[[1]]$tip.label +keep_tips <- sort(sample(all_tips, 60)) + +ref_trees <- lapply(mammal_trees[1:100], ape::drop.tip, + tip = setdiff(all_tips, keep_tips)) +class(ref_trees) <- "multiPhylo" +tipLabels <- ref_trees[[1]]$tip.label +nTip <- length(tipLabels) +``` + +The reference pool has `r length(ref_trees)` trees on `r nTip` tips. The +majority-rule consensus is only +`r round(length(as.Splits(Consensus(ref_trees, p = 0.5))) / (nTip - 3) * 100, 1)`% +resolved, indicating substantial disagreement among bootstrap replicates --- +a realistic scenario for CID consensus. + +## Candidate generation + +We generate 500 random single-TBR neighbours of the first reference tree +using `RootedTBRSwap()`. This simulates the candidate set that the search +engine compares during TBR hill-climbing. + +```{r} +#| label: tbr-neighbours +set.seed(3761) +base <- Preorder(ref_trees[[1]]) +parent <- base$edge[, 1] +child <- base$edge[, 2] +nEdge <- length(parent) + +tbr_neighbours <- vector("list", 500L) +for (i in seq_len(500L)) { + result <- RootedTBRSwap(parent, child, nEdge) + tbr_neighbours[[i]] <- structure(list( + edge = cbind(result[[1]], result[[2]]), + tip.label = tipLabels, + Nnode = nTip - 1L + ), class = "phylo") +} +class(tbr_neighbours) <- "multiPhylo" +``` + +RF distances from the base tree to neighbours range from +`r min(RobinsonFoulds(base, tbr_neighbours[1:50]))` +to `r max(RobinsonFoulds(base, tbr_neighbours[1:50]))`, +confirming these are genuine single-move neighbours (a TBR move can +change multiple splits simultaneously). + +## MRP matrix + +Each non-trivial split from each of the 100 reference trees becomes a +binary MRP character (tip in split $\to$ state 1, else $\to$ state 0). + +```{r} +#| label: mrp-matrix +all_splits <- lapply(ref_trees, as.Splits, tipLabels) +mrp_logical <- do.call(rbind, lapply(all_splits, as.logical)) +mrp_df <- as.data.frame(ifelse(mrp_logical, 1L, 0L)) +colnames(mrp_df) <- tipLabels +mrp_phydat <- phyDat(mrp_df, type = "USER", levels = c(0, 1)) +``` + +The MRP matrix has `r nrow(mrp_logical)` characters +(`r attr(mrp_phydat, "nr")` unique patterns) across `r ncol(mrp_logical)` +tips. + +## Scoring + +### CID scores + +For each TBR neighbour, we compute mean CID to all 100 reference trees +using `ClusteringInfoDistance()`. + +```{r} +#| label: cid-scores +cid_scores <- vapply(tbr_neighbours, function(cand) { + mean(ClusteringInfoDistance(cand, ref_trees)) +}, double(1)) +``` + +### Parsimony scores + +```{r} +#| label: parsimony-scores +ew_scores <- vapply(tbr_neighbours, function(cand) { + TreeLength(cand, mrp_phydat) +}, double(1)) + +k_values <- c(1, 2, 3, 5, 10, 20) +iw_scores <- matrix(NA_real_, nrow = 500L, ncol = length(k_values)) +colnames(iw_scores) <- paste0("k", k_values) +for (ki in seq_along(k_values)) { + iw_scores[, ki] <- vapply(tbr_neighbours, function(cand) { + TreeLength(cand, mrp_phydat, concavity = k_values[ki]) + }, double(1)) +} + +profile_scores <- vapply(tbr_neighbours, function(cand) { + TreeLength(cand, mrp_phydat, concavity = "profile") +}, double(1)) +``` + +## Results + +```{r} +#| label: tbl-correlations +#| tbl-cap: "Spearman and Pearson correlations between parsimony score and mean CID across 500 TBR neighbours." +methods <- c("EW", paste0("IW k=", k_values), "Profile") +all_scores <- cbind(ew_scores, iw_scores, profile_scores) +colnames(all_scores) <- methods + +cors <- data.frame( + Method = methods, + Spearman = round(vapply(methods, function(m) { + cor(all_scores[, m], cid_scores, method = "spearman") + }, double(1)), 4), + Pearson = round(vapply(methods, function(m) { + cor(all_scores[, m], cid_scores, method = "pearson") + }, double(1)), 4), + row.names = NULL +) +knitr::kable(cors) +``` + +```{r} +#| label: fig-scatter +#| fig-cap: "Standardized parsimony score vs mean CID for three representative methods." +#| fig-width: 7 +#| fig-height: 5 +plot_df <- data.frame( + CID = rep(cid_scores, 3), + Score = c(scale(ew_scores)[, 1], + scale(iw_scores[, which(k_values == 3)])[, 1], + scale(profile_scores)[, 1]), + Method = rep(c("EW", "IW k=3", "Profile"), each = length(cid_scores)) +) + +ggplot(plot_df, aes(CID, Score, colour = Method)) + + geom_point(alpha = 0.3, size = 1) + + geom_smooth(method = "lm", se = FALSE, linewidth = 0.7) + + labs(x = "Mean CID to reference trees", + y = "Parsimony score (standardized)") +``` + +```{r} +#| label: fig-residuals +#| fig-cap: "Residual parsimony score (after removing CID trend) by method. Tighter distributions indicate better proxies." +#| fig-width: 7 +#| fig-height: 4 +resid_df <- do.call(rbind, lapply(methods, function(m) { + fit <- lm(all_scores[, m] ~ cid_scores) + data.frame(Method = m, Residual = scale(residuals(fit))[, 1]) +})) + +ggplot(resid_df, aes(Method, Residual)) + + geom_boxplot(outlier.size = 0.5) + + coord_flip() + + labs(y = "Standardized residual (parsimony | CID)") +``` + +## Discussion + +_To be completed after results are available._ + +## Session info + +```{r} +#| label: session-info +sessionInfo() +``` diff --git a/dev/benchmarks/bench_topk.R b/dev/benchmarks/bench_topk.R new file mode 100644 index 000000000..d55b0e2de --- /dev/null +++ b/dev/benchmarks/bench_topk.R @@ -0,0 +1,131 @@ +#!/usr/bin/env Rscript +# Benchmark: screeningTopK = 1 vs 5 +# Compare search quality (MCI) and wall time with batch CID evaluation. + +suppressPackageStartupMessages({ + library(TreeSearch) + library(TreeTools) +}) + +cat("TreeSearch version:", as.character(packageVersion("TreeSearch")), "\n") + +# --- Generate trees (same as treeSample benchmark) --- +generate_trees <- function(n_tip, n_tree, seed) { + set.seed(seed) + base <- RandomTree(n_tip, root = TRUE) + n_internal <- n_tip - 1L + trees <- vector("list", n_tree) + trees[[1]] <- base + for (i in 2:n_tree) { + tr <- base + n_perturb <- sample(1:5, 1) + for (j in seq_len(n_perturb)) { + int_nodes <- unique(tr$edge[, 1]) + node <- sample(int_nodes, 1) + children <- tr$edge[tr$edge[, 1] == node, 2] + if (length(children) == 2 && all(children > n_tip)) { + gc1 <- tr$edge[tr$edge[, 1] == children[1], 2] + gc2 <- tr$edge[tr$edge[, 1] == children[2], 2] + if (length(gc1) >= 1 && length(gc2) >= 1) { + swap1 <- sample(gc1, 1) + swap2 <- sample(gc2, 1) + tr$edge[tr$edge[, 2] == swap1, 1] <- children[2] + tr$edge[tr$edge[, 2] == swap2, 1] <- children[1] + } + } + } + tr <- Preorder(tr) + trees[[i]] <- tr + } + class(trees) <- "multiPhylo" + trees +} + +run_one <- function(trees, topk, max_seconds, seed) { + set.seed(seed) + t0 <- proc.time() + result <- InfoConsensus( + trees, + treeSample = "auto", + screeningTopK = topk, + maxSeconds = max_seconds, + neverDrop = TRUE, + verbosity = 0L, + nThreads = 1L + ) + elapsed <- (proc.time() - t0)["elapsed"] + + list( + score = attr(result, "score"), + n_tip = Ntip(result), + elapsed = as.numeric(elapsed) + ) +} + +# --- Grid --- +configs <- expand.grid( + n_tip = c(50, 100), + budget = c(30, 60), + seed = c(2847, 5193, 7641), + stringsAsFactors = FALSE +) + +cat("Grid:", nrow(configs), "conditions × 2 topK levels\n") +cat("Generating trees...\n") + +tree_cache <- list() +for (n_tip in unique(configs$n_tip)) { + key <- paste0("t", n_tip) + cat(" Generating 1000 trees with", n_tip, "tips...\n") + tree_cache[[key]] <- generate_trees(n_tip, 1000, seed = 3917 + n_tip) +} + +# --- Run --- +results <- data.frame() + +for (i in seq_len(nrow(configs))) { + cfg <- configs[i, ] + key <- paste0("t", cfg$n_tip) + trees <- tree_cache[[key]] + + for (topk in c(1L, 5L)) { + cat(sprintf("[%d/%d] n_tip=%d, budget=%ds, seed=%d, topK=%d\n", + i, nrow(configs), cfg$n_tip, cfg$budget, cfg$seed, topk)) + tryCatch({ + res <- run_one(trees, topk, cfg$budget, cfg$seed) + results <- rbind(results, data.frame( + n_tip = cfg$n_tip, + budget = cfg$budget, + seed = cfg$seed, + topK = topk, + score = res$score, + elapsed = res$elapsed, + stringsAsFactors = FALSE + )) + cat(sprintf(" -> score=%.4f, elapsed=%.1fs\n", res$score, res$elapsed)) + }, error = function(e) { + cat(" ERROR:", conditionMessage(e), "\n") + results <<- rbind(results, data.frame( + n_tip = cfg$n_tip, budget = cfg$budget, seed = cfg$seed, + topK = topk, score = NA_real_, elapsed = NA_real_, + stringsAsFactors = FALSE + )) + }) + } +} + +# --- Save --- +outfile <- sprintf("topk_bench_%s.csv", format(Sys.time(), "%Y%m%d_%H%M")) +write.csv(results, outfile, row.names = FALSE) +cat("\nResults saved to:", outfile, "\n") + +# --- Summary --- +cat("\n=== Summary ===\n") +if (nrow(results) > 0 && !all(is.na(results$score))) { + agg <- aggregate( + cbind(score, elapsed) ~ n_tip + budget + topK, + data = results, + FUN = function(x) c(median = median(x), mean = mean(x)) + ) + print(agg) +} diff --git a/dev/benchmarks/bench_topk.sh b/dev/benchmarks/bench_topk.sh new file mode 100644 index 000000000..af76c56e8 --- /dev/null +++ b/dev/benchmarks/bench_topk.sh @@ -0,0 +1,24 @@ +#!/bin/bash +#SBATCH --job-name=bench-topk +#SBATCH --output=/nobackup/pjjg18/ts-bench/results/bench_topk_%j.log +#SBATCH --error=/nobackup/pjjg18/ts-bench/results/bench_topk_%j.err +#SBATCH -n 1 +#SBATCH --time=2:00:00 +#SBATCH --mem=8000M +#SBATCH -p shared + +module load r/4.5.1 +module load gcc/14.2 + +export OMP_NUM_THREADS=1 +export OPENBLAS_NUM_THREADS=1 + +BENCH=/nobackup/pjjg18/ts-bench +LIB=$BENCH/lib-cid +export R_LIBS="$LIB:$BENCH/lib-baseline" + +cd $BENCH/results + +echo "Starting topK benchmark at $(date)" +Rscript $BENCH/TreeSearch/dev/benchmarks/bench_topk.R +echo "Finished at $(date)" diff --git a/dev/benchmarks/bench_treesample.R b/dev/benchmarks/bench_treesample.R new file mode 100644 index 000000000..c5cf5970f --- /dev/null +++ b/dev/benchmarks/bench_treesample.R @@ -0,0 +1,163 @@ +#!/usr/bin/env Rscript +# Benchmark: treeSample = "auto" vs treeSample = Inf +# Run on Hamilton HPC (SBATCH wrapper below) +# +# Design: +# For each (n_tip, n_tree, budget) combination: +# - Run InfoConsensus with treeSample = "auto" (subsampled Phase 1) +# - Run InfoConsensus with treeSample = Inf (full tree set) +# Compare: wall time, MCI score, number of search replicates completed +# +# Trees: generated via bootstrap-like NNI perturbation of a random base tree, +# so input trees share partial structure (realistic split overlap). + +suppressPackageStartupMessages({ + library(TreeSearch) + library(TreeTools) +}) + +cat("TreeSearch version:", as.character(packageVersion("TreeSearch")), "\n") + +# --- Helpers --- +generate_trees <- function(n_tip, n_tree, seed) { + set.seed(seed) + base <- RandomTree(n_tip, root = TRUE) + edges <- base$edge + n_internal <- n_tip - 1L + + trees <- vector("list", n_tree) + trees[[1]] <- base + for (i in 2:n_tree) { + tr <- base + # 1-5 random NNI-like perturbations (swap children of random internal nodes) + n_perturb <- sample(1:5, 1) + for (j in seq_len(n_perturb)) { + # Pick a random internal node with 2 internal children + int_nodes <- unique(tr$edge[, 1]) + node <- sample(int_nodes, 1) + children <- tr$edge[tr$edge[, 1] == node, 2] + if (length(children) == 2 && all(children > n_tip)) { + # Swap one grandchild between children + gc1 <- tr$edge[tr$edge[, 1] == children[1], 2] + gc2 <- tr$edge[tr$edge[, 1] == children[2], 2] + if (length(gc1) >= 1 && length(gc2) >= 1) { + swap1 <- sample(gc1, 1) + swap2 <- sample(gc2, 1) + tr$edge[tr$edge[, 2] == swap1, 1] <- children[2] + tr$edge[tr$edge[, 2] == swap2, 1] <- children[1] + } + } + } + tr <- Preorder(tr) + trees[[i]] <- tr + } + class(trees) <- "multiPhylo" + trees +} + +run_one <- function(trees, tree_sample, max_seconds, seed) { + set.seed(seed) + t0 <- proc.time() + result <- InfoConsensus( + trees, + treeSample = tree_sample, + maxSeconds = max_seconds, + neverDrop = TRUE, + verbosity = 0L, + nThreads = 1L + ) + elapsed <- (proc.time() - t0)["elapsed"] + + score <- attr(result, "score") + n_tip_result <- Ntip(result) + + list( + score = score, + n_tip = n_tip_result, + elapsed = as.numeric(elapsed), + seed = seed + ) +} + +# --- Experimental grid --- +configs <- expand.grid( + n_tip = c(50, 100), + n_tree = 1000, + budget = c(30, 60, 120), + seed = c(2847, 5193, 7641), + stringsAsFactors = FALSE +) + +cat("Experimental grid:", nrow(configs), "conditions × 2 treeSample levels\n") +cat("Generating trees...\n") + +# Pre-generate trees (same trees for both auto and Inf) +tree_cache <- list() +for (n_tip in unique(configs$n_tip)) { + key <- paste0("t", n_tip) + cat(" Generating", 1000, "trees with", n_tip, "tips...\n") + tree_cache[[key]] <- generate_trees(n_tip, 1000, seed = 3917 + n_tip) + cat(" Done. Auto treeSample =", min(1000, max(50, 2 * n_tip)), "\n") +} + +# --- Run benchmarks --- +results <- data.frame() + +for (i in seq_len(nrow(configs))) { + cfg <- configs[i, ] + key <- paste0("t", cfg$n_tip) + trees <- tree_cache[[key]] + + for (ts_label in c("auto", "inf")) { + ts <- if (ts_label == "auto") "auto" else Inf + cat(sprintf("[%d/%d] n_tip=%d, budget=%ds, seed=%d, treeSample=%s\n", + i, nrow(configs), cfg$n_tip, cfg$budget, cfg$seed, ts_label)) + + tryCatch({ + res <- run_one(trees, ts, cfg$budget, cfg$seed) + results <- rbind(results, data.frame( + n_tip = cfg$n_tip, + n_tree = cfg$n_tree, + budget = cfg$budget, + seed = cfg$seed, + treeSample = ts_label, + score = res$score, + n_tip_result = res$n_tip, + elapsed = res$elapsed, + stringsAsFactors = FALSE + )) + cat(sprintf(" -> score=%.4f, elapsed=%.1fs\n", res$score, res$elapsed)) + }, error = function(e) { + cat(" ERROR:", conditionMessage(e), "\n") + results <<- rbind(results, data.frame( + n_tip = cfg$n_tip, + n_tree = cfg$n_tree, + budget = cfg$budget, + seed = cfg$seed, + treeSample = ts_label, + score = NA_real_, + n_tip_result = NA_integer_, + elapsed = NA_real_, + stringsAsFactors = FALSE + )) + }) + } +} + +# --- Save results --- +outfile <- sprintf("treesample_bench_%s.csv", + format(Sys.time(), "%Y%m%d_%H%M")) +write.csv(results, outfile, row.names = FALSE) +cat("\nResults saved to:", outfile, "\n") + +# --- Summary --- +cat("\n=== Summary ===\n") +if (nrow(results) > 0 && !all(is.na(results$score))) { + library(stats) + agg <- aggregate( + cbind(score, elapsed) ~ n_tip + budget + treeSample, + data = results, + FUN = function(x) c(median = median(x), mean = mean(x)) + ) + print(agg) +} diff --git a/dev/benchmarks/bench_treesample.sh b/dev/benchmarks/bench_treesample.sh new file mode 100644 index 000000000..811952cad --- /dev/null +++ b/dev/benchmarks/bench_treesample.sh @@ -0,0 +1,27 @@ +#!/bin/bash +#SBATCH --job-name=bench-tsample +#SBATCH --output=/nobackup/pjjg18/ts-bench/results/bench_treesample_%j.log +#SBATCH --error=/nobackup/pjjg18/ts-bench/results/bench_treesample_%j.err +#SBATCH -n 1 +#SBATCH --time=2:00:00 +#SBATCH --mem=8000M +#SBATCH -p shared + +module load r/4.5.1 +module load gcc/14.2 + +export OMP_NUM_THREADS=1 +export OPENBLAS_NUM_THREADS=1 + +BENCH=/nobackup/pjjg18/ts-bench +LIB=$BENCH/lib-cid +export R_LIBS="$LIB:$BENCH/lib-baseline" + +cd $BENCH/results + +echo "Starting treeSample benchmark at $(date)" +echo "TreeSearch from: $LIB" + +Rscript $BENCH/TreeSearch/dev/benchmarks/bench_treesample.R + +echo "Finished at $(date)" diff --git a/inst/WORDLIST b/inst/WORDLIST index ed3fd5500..a8d4816f7 100644 --- a/inst/WORDLIST +++ b/inst/WORDLIST @@ -81,6 +81,7 @@ Levenshtein Linnean MPT MPTs +MRP Machaeridians Maddison Magnoliidae @@ -144,6 +145,7 @@ Sabellidae Sankoff Scripta Siboglinidae +Splitwise Squamata Steell Syllidae diff --git a/inst/test-data/takazawa/primates_bootstrap.nw b/inst/test-data/takazawa/primates_bootstrap.nw new file mode 100644 index 000000000..b94b6386b --- /dev/null +++ b/inst/test-data/takazawa/primates_bootstrap.nw @@ -0,0 +1,100 @@ +((Pan_troglodytes_ellioti,(Homo_heidelbergensis,(Homo_sapiens_ssp_Denisova,(((((Hylobates_agilis,(Hylobates_lar,Symphalangus_syndactylus)),Hylobates_moloch),Nomascus_leucogenys),(Pongo_pygmaeus,Pongo_abelii)),((Gorilla_gorilla_gorilla,((((((((((Trachypithecus_obscurus,(Trachypithecus_pileatus,Trachypithecus_cristatus)),Trachypithecus_johnii),Trachypithecus_francoisi),(((Pygathrix_nigripes,Pygathrix_nemaeus),(Simias_concolor,Nasalis_larvatus)),((Rhinopithecus_bieti_2_RL2012,Rhinopithecus_brelichi),Rhinopithecus_roxellana))),Semnopithecus_entellus),Rhinopithecus_avunculus),((Colobus_guereza,Colobus_satanas),(Piliocolobus_badius,Procolobus_verus))),Presbytis_melalophos),(Miopithecus_ogouensis,(((((((((Cercopithecus_erythrogaster,Cercopithecus_erythrogaster_pococki),((Cercopithecus_neglectus,(Cercopithecus_petaurista_petaurista,Cercopithecus_petaurista_buettikoferi)),Cercopithecus_cephus_cephus)),((((Cercopithecus_lhoesti,(Cercopithecus_preussi_preussi,Cercopithecus_preussi_insularis)),Cercopithecus_erythrotis_camerunensis),Cercopithecus_ascanius_katangae),Cercopithecus_ascanius_whitesidei)),Cercopithecus_ascanius_schmidti),(((Cercopithecus_diana,Cercopithecus_roloway),((((((Macaca_fascicularis,(Macaca_silenus,Macaca_tonkeana)),(((Macaca_thibetana,Macaca_assamensis),((Macaca_nigra,(Macaca_mulatta,Macaca_fuscata)),Macaca_nemestrina)),Macaca_arctoides)),Macaca_sylvanus),((((Cercocebus_atys,Mandrillus_sphinx),Cercocebus_torquatus),((Cercocebus_chrysogaster,Mandrillus_leucophaeus),Cercocebus_agilis)),(((Lophocebus_aterrimus,Theropithecus_gelada),(((Papio_kindae,Papio_cynocephalus),(Papio_ursinus,(Papio_papio,(Papio_anubis,Papio_hamadryas)))),Rungwecebus_kipunji)),Lophocebus_albigena))),(Allenopithecus_nigroviridis,Erythrocebus_patas)),(((Cercopithecus_mitis_opisthostictus,Cercopithecus_nictitans_nictitans),((Cercopithecus_albogularis_kolbi,((Cercopithecus_kandti,Cercopithecus_doggetti),(Cercopithecus_mitis_stuhlmanni,(Cercopithecus_mitis_heymansi,Cercopithecus_albogularis_francescae)))),Cercopithecus_mitis)),(Cercopithecus_mitis_mitis,Cercopithecus_nictitans)))),(((((Cercopithecus_albogularis_labiatus,(Cercopithecus_albogularis_monoides,Cercopithecus_albogularis_erythrarchus)),Cercopithecus_mitis_boutourlinii),Cercopithecus_albogularis),Cercopithecus_albogularis_albotorquatus),Cercopithecus_albogularis_moloneyi))),(Cercopithecus_petaurista,(Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis))),((((((Cercopithecus_pogonias,Cercopithecus_wolfi_pyrogaster),Cercopithecus_pogonias_schwarzianus),Cercopithecus_wolfi_elegans),Cercopithecus_pogonias_nigripes),Cercopithecus_pogonias_grayi),(Cercopithecus_campbelli,Cercopithecus_mona))),(Cercopithecus_nictitans_martini,(Cercopithecus_dryas,((Chlorocebus_sabaeus,Cercopithecus_aethiops),(Cercopithecus_solatus,((Chlorocebus_tantalus,(Chlorocebus_pygerythrus,Chlorocebus_cynosuros)),(Cercopithecus_hamlyni,Chlorocebus_aethiops))))))),Miopithecus_talapoin))),((((Saimiri_sciureus_macrodon,(Saimiri_boliviensis,(Saimiri_sciureus,Saimiri_oerstedii))),Saimiri_oerstedii_citrinellus),(((Cacajao_calvus,(((Pithecia_pithecia,Chiropotes_israelita),Lagothrix_lagotricha),Chiropotes_albinasus)),(((Leontopithecus_rosalia,Alouatta_caraya),((((((Ateles_paniscus,Callithrix_jacchus),(Brachyteles_arachnoides,Callicebus_cupreus)),(Ateles_geoffroyi,Callimico_goeldii)),Ateles_belzebuth),Callicebus_donacophilus),Callicebus_lugens)),((Cebus_albifrons,(Cebus_apella,Sapajus_xanthosternos)),((Aotus_azarae_azarai,(Aotus_azarai,Aotus_lemurinus)),(Saguinus_oedipus,Callithrix_pygmaea))))),(Aotus_nancymaae,(Aotus_azarae,Aotus_trivirgatus)))),(((Eulemur_rubriventer,(Eulemur_macaco,Eulemur_fulvus)),Tarsius_bancanus),((((Nycticebus_pygmaeus,((Hapalemur_griseus,(Varecia_variegata,(Varecia_rubra,Cheirogaleus_medius))),Lemur_catta)),Prolemur_simus),(((Eulemur_mongoz,Eulemur_rufus),((Palaeopropithecus_ingens,((Megaladapis_edwardsi,Daubentonia_madagascariensis),((Perodicticus_potto,Perodicticus_potto_edwarsi),(((Propithecus_verreauxi,(Loris_tardigradus,Loris_lydekkerianus)),(Nycticebus_coucang,Nycticebus_bengalensis)),(Galago_moholi,(((Otolemur_garnettii,Galago_senegalensis),Otolemur_crassicaudatus),Galagoides_demidoff)))))),Propithecus_coquereli)),(((Lepilemur_ruficaudatus,Lepilemur_hubbardorum),Indri_indri),Avahi_laniger))),(((Tarsius_dentatus,Tarsius_lariang),Tarsius_wallacei),Tarsius_syrichta)))))),Gorilla_gorilla))))),(Pan_paniscus,(Pan_troglodytes,Pan_troglodytes_troglodytes)),Homo_sapiens); +((((((((((Hylobates_moloch,Hylobates_lar),Hylobates_agilis),(Nomascus_leucogenys,Symphalangus_syndactylus)),(Pongo_pygmaeus,Pongo_abelii)),(((((Presbytis_melalophos,(((Colobus_guereza,Colobus_satanas),(Piliocolobus_badius,Procolobus_verus)),((Trachypithecus_pileatus,(Trachypithecus_cristatus,(Trachypithecus_obscurus,(Semnopithecus_entellus,Trachypithecus_francoisi)))),Trachypithecus_johnii))),Rhinopithecus_avunculus),(((Rhinopithecus_brelichi,Rhinopithecus_bieti_2_RL2012),Rhinopithecus_roxellana),((Pygathrix_nigripes,Pygathrix_nemaeus),(Simias_concolor,Nasalis_larvatus)))),(Miopithecus_ogouensis,(((((Cercopithecus_roloway,(((((Macaca_arctoides,(Macaca_mulatta,Macaca_fuscata)),Macaca_nemestrina),(((((((Cercocebus_atys,Mandrillus_sphinx),Cercocebus_torquatus),(Cercocebus_agilis,(Mandrillus_leucophaeus,Cercocebus_chrysogaster))),(((Rungwecebus_kipunji,(Lophocebus_albigena,Lophocebus_aterrimus)),Theropithecus_gelada),((Papio_papio,(Papio_cynocephalus,Papio_kindae)),(Papio_hamadryas,(Papio_anubis,Papio_ursinus))))),Macaca_fascicularis),(Macaca_silenus,Macaca_tonkeana)),(Macaca_thibetana,Macaca_assamensis))),Macaca_nigra),((Allenopithecus_nigroviridis,Erythrocebus_patas),Macaca_sylvanus))),(Cercopithecus_lhoesti,(Cercopithecus_preussi_preussi,Cercopithecus_preussi_insularis))),(Cercopithecus_albogularis,((((Cercopithecus_albogularis_monoides,((((((Cercopithecus_wolfi_elegans,Cercopithecus_wolfi_pyrogaster),Cercopithecus_nictitans_martini),((Cercopithecus_pogonias,Cercopithecus_pogonias_nigripes),Cercopithecus_pogonias_schwarzianus)),Cercopithecus_pogonias_grayi),(Cercopithecus_campbelli,Cercopithecus_mona)),(Cercopithecus_diana,Cercopithecus_cephus_cephus))),((Cercopithecus_cephus_ngottoensis,((Cercopithecus_neglectus,(Cercopithecus_cephus,Cercopithecus_ascanius_schmidti)),Cercopithecus_ascanius_whitesidei)),(Cercopithecus_ascanius_katangae,(((Cercopithecus_erythrogaster,Cercopithecus_erythrogaster_pococki),(Cercopithecus_petaurista_petaurista,Cercopithecus_petaurista_buettikoferi)),Cercopithecus_petaurista)))),Cercopithecus_erythrotis_camerunensis),((((Cercopithecus_mitis_mitis,Cercopithecus_mitis_opisthostictus),(Cercopithecus_nictitans_nictitans,(Cercopithecus_albogularis_kolbi,Cercopithecus_nictitans))),(Cercopithecus_mitis,((Cercopithecus_kandti,Cercopithecus_mitis_stuhlmanni),((Cercopithecus_mitis_heymansi,Cercopithecus_albogularis_francescae),Cercopithecus_doggetti)))),(((Cercopithecus_albogularis_moloneyi,Cercopithecus_albogularis_albotorquatus),(Cercopithecus_mitis_boutourlinii,Cercopithecus_albogularis_labiatus)),Cercopithecus_albogularis_erythrarchus))))),(Cercopithecus_dryas,((Chlorocebus_sabaeus,Cercopithecus_aethiops),(Cercopithecus_solatus,((Cercopithecus_hamlyni,Chlorocebus_aethiops),(Chlorocebus_tantalus,(Chlorocebus_cynosuros,Chlorocebus_pygerythrus))))))),Miopithecus_talapoin))),(((((Sapajus_xanthosternos,(Cebus_albifrons,Cebus_apella)),((Aotus_azarae,(((Alouatta_caraya,(Leontopithecus_rosalia,(Saguinus_oedipus,(Callithrix_pygmaea,Aotus_nancymaae)))),Aotus_lemurinus),Aotus_azarai)),(Pithecia_pithecia,((Lagothrix_lagotricha,Aotus_azarae_azarai),(((Callicebus_donacophilus,(Ateles_belzebuth,(((Brachyteles_arachnoides,Ateles_paniscus),Ateles_geoffroyi),Callithrix_jacchus))),Callicebus_cupreus),Callicebus_lugens))))),(((Aotus_trivirgatus,Chiropotes_albinasus),Chiropotes_israelita),(Cacajao_calvus,((((Saimiri_oerstedii,Saimiri_sciureus),Saimiri_boliviensis),Saimiri_sciureus_macrodon),Saimiri_oerstedii_citrinellus)))),Callimico_goeldii),(((((Tarsius_bancanus,Lemur_catta),(Eulemur_fulvus,Eulemur_mongoz)),Eulemur_rubriventer),((((Varecia_rubra,Varecia_variegata),Nycticebus_pygmaeus),(Tarsius_lariang,(Tarsius_wallacei,Tarsius_dentatus))),Tarsius_syrichta)),(Eulemur_macaco,(((((Perodicticus_potto,Perodicticus_potto_edwarsi),(Otolemur_crassicaudatus,Otolemur_garnettii)),(((Nycticebus_coucang,Nycticebus_bengalensis),((Galagoides_demidoff,Loris_tardigradus),Loris_lydekkerianus)),Galago_moholi)),(Galago_senegalensis,Propithecus_verreauxi)),(((Hapalemur_griseus,Cheirogaleus_medius),Prolemur_simus),(Eulemur_rufus,((((Daubentonia_madagascariensis,Avahi_laniger),Megaladapis_edwardsi),Propithecus_coquereli),(Palaeopropithecus_ingens,((Lepilemur_ruficaudatus,Lepilemur_hubbardorum),Indri_indri))))))))))),(Gorilla_gorilla_gorilla,Gorilla_gorilla)),Homo_heidelbergensis),Homo_sapiens_ssp_Denisova),(Pan_troglodytes_troglodytes,Pan_troglodytes_ellioti)),(Pan_paniscus,Pan_troglodytes),Homo_sapiens); +((((Pongo_abelii,(Homo_heidelbergensis,(Pongo_pygmaeus,((Homo_sapiens_ssp_Denisova,(((((Trachypithecus_johnii,Procolobus_verus),(((Trachypithecus_pileatus,(((((Rhinopithecus_bieti_2_RL2012,Pygathrix_nemaeus),Pygathrix_nigripes),((Nasalis_larvatus,Rhinopithecus_roxellana),(Simias_concolor,Rhinopithecus_brelichi))),(Trachypithecus_cristatus,Trachypithecus_obscurus)),Trachypithecus_francoisi)),((Semnopithecus_entellus,Presbytis_melalophos),Rhinopithecus_avunculus)),((Colobus_guereza,Colobus_satanas),Piliocolobus_badius))),(Miopithecus_ogouensis,(((Chlorocebus_aethiops,((Chlorocebus_pygerythrus,(Allenopithecus_nigroviridis,((((Cercocebus_chrysogaster,Cercocebus_agilis),(Mandrillus_leucophaeus,(Mandrillus_sphinx,(Cercocebus_torquatus,Cercocebus_atys)))),((((Rungwecebus_kipunji,Papio_anubis),(Papio_hamadryas,((Lophocebus_albigena,Lophocebus_aterrimus),Papio_ursinus))),Theropithecus_gelada),(Papio_kindae,(Papio_papio,Papio_cynocephalus)))),((Macaca_fascicularis,Macaca_silenus),(((Macaca_thibetana,Macaca_assamensis),(Macaca_nemestrina,(Macaca_arctoides,((Macaca_sylvanus,Macaca_fuscata),Macaca_nigra)))),(Macaca_mulatta,Macaca_tonkeana)))))),(((Miopithecus_talapoin,((Chlorocebus_tantalus,(((Cercopithecus_albogularis_francescae,(((Cercopithecus_nictitans_nictitans,(((Cercopithecus_pogonias_nigripes,(Cercopithecus_pogonias_grayi,((Cercopithecus_wolfi_elegans,Cercopithecus_wolfi_pyrogaster),Cercopithecus_pogonias_schwarzianus))),((Cercopithecus_cephus_cephus,(Cercopithecus_campbelli,Cercopithecus_mona)),Cercopithecus_nictitans_martini)),Cercopithecus_pogonias)),(((Cercopithecus_lhoesti,(Cercopithecus_preussi_preussi,Cercopithecus_preussi_insularis)),(Cercopithecus_ascanius_schmidti,(((Cercopithecus_erythrotis_camerunensis,((Cercopithecus_petaurista_buettikoferi,Cercopithecus_erythrogaster_pococki),(Cercopithecus_petaurista,(Cercopithecus_erythrogaster,Cercopithecus_petaurista_petaurista)))),Cercopithecus_ascanius_whitesidei),Cercopithecus_ascanius_katangae))),(Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis))),Cercopithecus_aethiops)),((Cercopithecus_dryas,Chlorocebus_sabaeus),(Cercopithecus_neglectus,Cercopithecus_solatus))),((Cercopithecus_mitis_mitis,(((Cercopithecus_albogularis_monoides,Cercopithecus_albogularis),((Cercopithecus_mitis_boutourlinii,Cercopithecus_albogularis_erythrarchus),(Cercopithecus_albogularis_albotorquatus,Cercopithecus_albogularis_labiatus))),(Cercopithecus_albogularis_kolbi,(Cercopithecus_mitis_opisthostictus,((Cercopithecus_albogularis_moloneyi,((Cercopithecus_doggetti,Cercopithecus_mitis_stuhlmanni),Cercopithecus_mitis)),Cercopithecus_kandti))))),Cercopithecus_mitis_heymansi))),Cercopithecus_roloway)),(Cercopithecus_nictitans,Cercopithecus_hamlyni)),Chlorocebus_cynosuros))),Cercopithecus_diana),Erythrocebus_patas))),((((Tarsius_lariang,(Tarsius_wallacei,Tarsius_dentatus)),((Varecia_rubra,Varecia_variegata),Nycticebus_pygmaeus)),Tarsius_syrichta),((((Lepilemur_ruficaudatus,Cheirogaleus_medius),((Eulemur_rufus,(((((Propithecus_coquereli,((Megaladapis_edwardsi,Avahi_laniger),Daubentonia_madagascariensis)),Propithecus_verreauxi),Palaeopropithecus_ingens),Lepilemur_hubbardorum),Indri_indri)),(Prolemur_simus,Hapalemur_griseus))),(((Perodicticus_potto,Perodicticus_potto_edwarsi),((Otolemur_garnettii,(Otolemur_crassicaudatus,Galago_senegalensis)),((Nycticebus_coucang,Nycticebus_bengalensis),((Loris_tardigradus,Loris_lydekkerianus),Galagoides_demidoff)))),Galago_moholi)),((Eulemur_rubriventer,Eulemur_macaco),((Tarsius_bancanus,(Eulemur_mongoz,Eulemur_fulvus)),Lemur_catta))))),(((Saguinus_oedipus,Callithrix_pygmaea),(((((Aotus_azarae,(Aotus_trivirgatus,((Aotus_azarai,Aotus_lemurinus),Aotus_azarae_azarai))),((((Saimiri_oerstedii,Saimiri_boliviensis),Saimiri_sciureus),Saimiri_sciureus_macrodon),Saimiri_oerstedii_citrinellus)),(((Chiropotes_israelita,Chiropotes_albinasus),Cacajao_calvus),(Pithecia_pithecia,Lagothrix_lagotricha))),(Sapajus_xanthosternos,(Cebus_albifrons,Cebus_apella))),((Aotus_nancymaae,Leontopithecus_rosalia),(((((Callithrix_jacchus,(Callimico_goeldii,(Ateles_geoffroyi,Ateles_belzebuth))),Ateles_paniscus),(Callicebus_donacophilus,Brachyteles_arachnoides)),Callicebus_cupreus),Callicebus_lugens)))),Alouatta_caraya))),(Gorilla_gorilla_gorilla,Gorilla_gorilla))))),(Hylobates_moloch,Nomascus_leucogenys)),(Pan_troglodytes,((Hylobates_lar,(Pan_paniscus,Symphalangus_syndactylus)),Hylobates_agilis))),(Pan_troglodytes_troglodytes,Pan_troglodytes_ellioti),Homo_sapiens); +((((Homo_heidelbergensis,(((((Hylobates_agilis,((Hylobates_moloch,Nomascus_leucogenys),Symphalangus_syndactylus)),Hylobates_lar),(Pongo_pygmaeus,Pongo_abelii)),((((((Saguinus_oedipus,Callithrix_pygmaea),(((((((Ateles_belzebuth,((Callithrix_jacchus,((Callimico_goeldii,Callicebus_cupreus),Ateles_paniscus)),Ateles_geoffroyi)),Callicebus_donacophilus),Callicebus_lugens),Pithecia_pithecia),((Sapajus_xanthosternos,Cebus_apella),Cebus_albifrons)),(Lagothrix_lagotricha,((Chiropotes_israelita,Chiropotes_albinasus),Cacajao_calvus))),(((((Aotus_lemurinus,Aotus_azarai),Aotus_azarae),Aotus_trivirgatus),Aotus_azarae_azarai),((Saimiri_oerstedii_citrinellus,(Saimiri_sciureus_macrodon,((Saimiri_sciureus,Saimiri_oerstedii),Saimiri_boliviensis))),(Aotus_nancymaae,Leontopithecus_rosalia))))),(Brachyteles_arachnoides,Alouatta_caraya)),(((Tarsius_dentatus,(Tarsius_lariang,Tarsius_wallacei)),Tarsius_syrichta),(Propithecus_coquereli,((Daubentonia_madagascariensis,(((Palaeopropithecus_ingens,((Eulemur_rufus,((Cheirogaleus_medius,Hapalemur_griseus),Prolemur_simus)),((Lepilemur_ruficaudatus,Lepilemur_hubbardorum),Indri_indri))),Megaladapis_edwardsi),((Avahi_laniger,Galago_senegalensis),(((Eulemur_rubriventer,((Eulemur_mongoz,Eulemur_macaco),Eulemur_fulvus)),(Lemur_catta,((Varecia_rubra,Varecia_variegata),Tarsius_bancanus))),Propithecus_verreauxi)))),((((Otolemur_crassicaudatus,(Otolemur_garnettii,Nycticebus_coucang)),Nycticebus_bengalensis),(Nycticebus_pygmaeus,((Loris_tardigradus,Loris_lydekkerianus),Galagoides_demidoff))),((Perodicticus_potto,Perodicticus_potto_edwarsi),Galago_moholi)))))),(Miopithecus_ogouensis,(((Procolobus_verus,((((Semnopithecus_entellus,Rhinopithecus_avunculus),Presbytis_melalophos),((Rhinopithecus_bieti_2_RL2012,((((Pygathrix_nigripes,Pygathrix_nemaeus),(Simias_concolor,Nasalis_larvatus)),Rhinopithecus_brelichi),Rhinopithecus_roxellana)),((Trachypithecus_pileatus,(Trachypithecus_francoisi,Trachypithecus_obscurus)),Trachypithecus_cristatus))),((Colobus_guereza,Colobus_satanas),Piliocolobus_badius))),Trachypithecus_johnii),((Cercopithecus_diana,Erythrocebus_patas),((((Cercocebus_chrysogaster,((Mandrillus_leucophaeus,(Mandrillus_sphinx,(Cercocebus_torquatus,Cercocebus_atys))),Cercocebus_agilis)),((((Papio_ursinus,(Papio_papio,(Papio_anubis,Papio_hamadryas))),(Papio_kindae,Papio_cynocephalus)),(Lophocebus_albigena,Lophocebus_aterrimus)),(Theropithecus_gelada,Rungwecebus_kipunji))),((Macaca_fuscata,((Macaca_nigra,(Macaca_fascicularis,((Macaca_silenus,(Macaca_thibetana,Macaca_assamensis)),Macaca_tonkeana))),(Macaca_nemestrina,Macaca_sylvanus))),(Macaca_arctoides,Macaca_mulatta))),((((((Cercopithecus_albogularis_kolbi,(((Cercopithecus_albogularis_monoides,Cercopithecus_albogularis),((Cercopithecus_mitis_boutourlinii,Cercopithecus_albogularis_erythrarchus),(Cercopithecus_albogularis_labiatus,Cercopithecus_albogularis_albotorquatus))),((Cercopithecus_mitis_opisthostictus,Cercopithecus_mitis_mitis),Cercopithecus_mitis_heymansi))),((Cercopithecus_roloway,((Cercopithecus_nictitans_nictitans,Cercopithecus_nictitans),Cercopithecus_mitis)),(Cercopithecus_doggetti,Cercopithecus_mitis_stuhlmanni))),(Cercopithecus_albogularis_moloneyi,((((((((Cercopithecus_pogonias,((Cercopithecus_pogonias_schwarzianus,Cercopithecus_pogonias_nigripes),Cercopithecus_pogonias_grayi)),Cercopithecus_nictitans_martini),(Cercopithecus_wolfi_elegans,Cercopithecus_wolfi_pyrogaster)),(Cercopithecus_campbelli,Cercopithecus_mona)),(Cercopithecus_ascanius_schmidti,Cercopithecus_albogularis_francescae)),Cercopithecus_cephus_ngottoensis),(((((((Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi),Cercopithecus_lhoesti),Cercopithecus_cephus),Cercopithecus_neglectus),((Cercopithecus_cephus_cephus,(Cercopithecus_solatus,Miopithecus_talapoin)),((Cercopithecus_erythrotis_camerunensis,Cercopithecus_ascanius_katangae),(((Cercopithecus_erythrogaster_pococki,(Cercopithecus_petaurista_buettikoferi,Cercopithecus_petaurista_petaurista)),Cercopithecus_erythrogaster),Cercopithecus_petaurista)))),Cercopithecus_ascanius_whitesidei),Cercopithecus_dryas)),(Cercopithecus_aethiops,Chlorocebus_sabaeus)))),Cercopithecus_kandti),((((Chlorocebus_aethiops,Cercopithecus_hamlyni),Chlorocebus_tantalus),Chlorocebus_pygerythrus),Chlorocebus_cynosuros)),Allenopithecus_nigroviridis)))))),(Gorilla_gorilla_gorilla,Gorilla_gorilla))),Homo_sapiens_ssp_Denisova)),Pan_troglodytes_ellioti),Pan_troglodytes_troglodytes),(Pan_troglodytes,Pan_paniscus),Homo_sapiens); +((((Homo_heidelbergensis,((Gorilla_gorilla_gorilla,Gorilla_gorilla),(((((((((Nasalis_larvatus,((Pygathrix_nigripes,Trachypithecus_francoisi),Semnopithecus_entellus)),Pygathrix_nemaeus),Rhinopithecus_brelichi),((Presbytis_melalophos,((Rhinopithecus_avunculus,(Rhinopithecus_bieti_2_RL2012,(Trachypithecus_obscurus,(Trachypithecus_pileatus,Rhinopithecus_roxellana)))),Simias_concolor)),Trachypithecus_cristatus)),(Trachypithecus_johnii,((Colobus_guereza,Colobus_satanas),Piliocolobus_badius))),Procolobus_verus),((Cercopithecus_diana,(((((Papio_ursinus,(Papio_cynocephalus,(Rungwecebus_kipunji,(Papio_kindae,(Papio_papio,(Papio_anubis,Papio_hamadryas)))))),(Theropithecus_gelada,(Lophocebus_albigena,Lophocebus_aterrimus))),Cercocebus_atys),(((((Macaca_mulatta,((Macaca_sylvanus,Macaca_fuscata),Macaca_nigra)),Macaca_nemestrina),Macaca_fascicularis),(Macaca_tonkeana,Macaca_arctoides)),(Macaca_silenus,(Macaca_thibetana,Macaca_assamensis)))),(((Cercopithecus_hamlyni,((((Chlorocebus_aethiops,Chlorocebus_tantalus),Chlorocebus_pygerythrus),Chlorocebus_cynosuros),(Allenopithecus_nigroviridis,(Cercopithecus_doggetti,((Cercopithecus_nictitans_nictitans,(Cercopithecus_kandti,((Cercopithecus_albogularis_moloneyi,((((Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi),Cercopithecus_lhoesti),(((Cercopithecus_cephus_cephus,(((Cercopithecus_petaurista_buettikoferi,Cercopithecus_petaurista_petaurista),(Cercopithecus_erythrogaster,Cercopithecus_erythrogaster_pococki)),Cercopithecus_petaurista)),(Cercopithecus_erythrotis_camerunensis,Cercopithecus_ascanius_katangae)),(Cercopithecus_ascanius_whitesidei,Cercopithecus_ascanius_schmidti))),(Cercopithecus_cephus_ngottoensis,(((Cercopithecus_roloway,Miopithecus_talapoin),(Cercopithecus_dryas,((Cercopithecus_aethiops,Cercopithecus_solatus),Chlorocebus_sabaeus))),((((((Cercopithecus_nictitans_martini,((Cercopithecus_pogonias_nigripes,((Cercopithecus_wolfi_elegans,Cercopithecus_wolfi_pyrogaster),Cercopithecus_pogonias_grayi)),Cercopithecus_pogonias_schwarzianus)),Cercopithecus_pogonias),(Cercopithecus_campbelli,Cercopithecus_mona)),Cercopithecus_albogularis_francescae),Cercopithecus_neglectus),Cercopithecus_cephus))))),((((Cercopithecus_albogularis_labiatus,(Cercopithecus_albogularis_erythrarchus,(Cercopithecus_mitis_boutourlinii,Cercopithecus_albogularis_albotorquatus))),(Cercopithecus_albogularis_monoides,Cercopithecus_albogularis)),((Cercopithecus_mitis_mitis,Cercopithecus_mitis_opisthostictus),(Cercopithecus_mitis_heymansi,Cercopithecus_albogularis_kolbi))),Cercopithecus_mitis)))),Cercopithecus_mitis_stuhlmanni))))),Cercopithecus_nictitans),(Erythrocebus_patas,(Mandrillus_sphinx,(((Cercocebus_chrysogaster,Cercocebus_torquatus),Mandrillus_leucophaeus),Cercocebus_agilis)))))),Miopithecus_ogouensis)),(((Saguinus_oedipus,(Callithrix_pygmaea,(Lagothrix_lagotricha,(Pithecia_pithecia,(Aotus_azarae,((Leontopithecus_rosalia,(Aotus_nancymaae,((Aotus_azarae_azarai,(Chiropotes_israelita,((Brachyteles_arachnoides,Chiropotes_albinasus),Cacajao_calvus))),Cebus_apella))),((((Aotus_lemurinus,Aotus_azarai),((((Saimiri_oerstedii,Saimiri_sciureus),Saimiri_boliviensis),Saimiri_sciureus_macrodon),Saimiri_oerstedii_citrinellus)),Aotus_trivirgatus),(((((((Callithrix_jacchus,(Ateles_paniscus,Ateles_belzebuth)),Callimico_goeldii),Ateles_geoffroyi),Callicebus_donacophilus),Callicebus_cupreus),Callicebus_lugens),(Sapajus_xanthosternos,Cebus_albifrons))))))))),Alouatta_caraya),((Tarsius_syrichta,((Tarsius_dentatus,Tarsius_lariang),Tarsius_wallacei)),((((Perodicticus_potto,(((Galago_moholi,Otolemur_crassicaudatus),Galagoides_demidoff),Otolemur_garnettii)),((Nycticebus_pygmaeus,(Nycticebus_bengalensis,Nycticebus_coucang)),(Loris_tardigradus,Loris_lydekkerianus))),Perodicticus_potto_edwarsi),((((Eulemur_rufus,(Propithecus_coquereli,(Indri_indri,Palaeopropithecus_ingens))),Propithecus_verreauxi),(((Lepilemur_ruficaudatus,Lepilemur_hubbardorum),Prolemur_simus),(Hapalemur_griseus,Cheirogaleus_medius))),(((Megaladapis_edwardsi,Avahi_laniger),Daubentonia_madagascariensis),(Galago_senegalensis,((Tarsius_bancanus,((Eulemur_fulvus,Eulemur_mongoz),Eulemur_macaco)),((Lemur_catta,(Varecia_rubra,Varecia_variegata)),Eulemur_rubriventer))))))))),(((Symphalangus_syndactylus,(Hylobates_agilis,Hylobates_lar)),(Hylobates_moloch,Nomascus_leucogenys)),(Pongo_pygmaeus,Pongo_abelii))))),Homo_sapiens_ssp_Denisova),Pan_troglodytes_ellioti),((Pan_paniscus,Pan_troglodytes_troglodytes),Pan_troglodytes),Homo_sapiens); +((Homo_sapiens_ssp_Denisova,((((Nomascus_leucogenys,(Hylobates_agilis,((Hylobates_lar,Hylobates_moloch),Symphalangus_syndactylus))),(Pongo_pygmaeus,Pongo_abelii)),(Gorilla_gorilla_gorilla,(Gorilla_gorilla,(((((((Rhinopithecus_avunculus,Presbytis_melalophos),(((Trachypithecus_francoisi,Trachypithecus_cristatus),(Trachypithecus_pileatus,Trachypithecus_obscurus)),(((Rhinopithecus_brelichi,Rhinopithecus_roxellana),Rhinopithecus_bieti_2_RL2012),((Pygathrix_nemaeus,Pygathrix_nigripes),((Semnopithecus_entellus,Simias_concolor),Nasalis_larvatus))))),Trachypithecus_johnii),((Colobus_guereza,Colobus_satanas),Piliocolobus_badius)),Procolobus_verus),(((Cercopithecus_diana,((((Chlorocebus_pygerythrus,(((Cercopithecus_hamlyni,Chlorocebus_tantalus),Chlorocebus_cynosuros),Chlorocebus_aethiops)),((Cercopithecus_albogularis_moloneyi,((((Cercopithecus_erythrotis_camerunensis,((((((Cercopithecus_erythrogaster_pococki,Cercopithecus_petaurista_buettikoferi),Cercopithecus_petaurista_petaurista),Cercopithecus_erythrogaster),Cercopithecus_petaurista),Cercopithecus_cephus_cephus),Cercopithecus_ascanius_katangae)),Cercopithecus_ascanius_whitesidei),((Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi),Cercopithecus_lhoesti)),((((Cercopithecus_neglectus,(Cercopithecus_dryas,((Cercopithecus_aethiops,Cercopithecus_solatus),Chlorocebus_sabaeus))),(((Cercopithecus_pogonias_schwarzianus,Cercopithecus_pogonias_grayi),Cercopithecus_pogonias_nigripes),(((Cercopithecus_wolfi_elegans,Cercopithecus_wolfi_pyrogaster),Cercopithecus_nictitans_martini),((Cercopithecus_campbelli,Cercopithecus_mona),Cercopithecus_pogonias)))),Cercopithecus_nictitans_nictitans),(Cercopithecus_ascanius_schmidti,(Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis))))),((((Cercopithecus_kandti,Cercopithecus_mitis),(Cercopithecus_mitis_heymansi,Cercopithecus_albogularis_kolbi)),((Cercopithecus_albogularis_francescae,Cercopithecus_doggetti),Cercopithecus_mitis_stuhlmanni)),((Cercopithecus_mitis_opisthostictus,((Cercopithecus_albogularis_monoides,Cercopithecus_albogularis),((Cercopithecus_albogularis_albotorquatus,(Cercopithecus_albogularis_erythrarchus,Cercopithecus_mitis_boutourlinii)),Cercopithecus_albogularis_labiatus))),Cercopithecus_mitis_mitis)))),Cercopithecus_nictitans),((((Cercocebus_agilis,(Mandrillus_leucophaeus,(Cercocebus_torquatus,((Mandrillus_sphinx,Cercocebus_atys),Cercocebus_chrysogaster)))),(((Papio_ursinus,(Papio_kindae,(Papio_papio,((Papio_hamadryas,Papio_anubis),Papio_cynocephalus)))),Rungwecebus_kipunji),(Theropithecus_gelada,(Lophocebus_albigena,Lophocebus_aterrimus)))),((((Macaca_thibetana,Macaca_assamensis),(Macaca_arctoides,((((Macaca_sylvanus,Macaca_fuscata),Macaca_nigra),Macaca_nemestrina),Macaca_mulatta))),Macaca_fascicularis),(Macaca_silenus,Macaca_tonkeana))),(Erythrocebus_patas,Allenopithecus_nigroviridis)))),(Cercopithecus_roloway,Miopithecus_talapoin)),Miopithecus_ogouensis)),(((Callithrix_pygmaea,(Saguinus_oedipus,(((Aotus_azarae,(Leontopithecus_rosalia,(((Aotus_azarae_azarai,Lagothrix_lagotricha),(((Callimico_goeldii,(Callithrix_jacchus,((Ateles_paniscus,Ateles_geoffroyi),Ateles_belzebuth))),(Callicebus_donacophilus,Callicebus_cupreus)),Callicebus_lugens)),((((((Aotus_trivirgatus,Chiropotes_israelita),(Brachyteles_arachnoides,Chiropotes_albinasus)),Cacajao_calvus),((Saimiri_sciureus_macrodon,((Saimiri_oerstedii,Saimiri_sciureus),Saimiri_boliviensis)),Saimiri_oerstedii_citrinellus)),Pithecia_pithecia),(Cebus_albifrons,(Cebus_apella,Sapajus_xanthosternos)))))),(Aotus_lemurinus,Aotus_azarai)),Aotus_nancymaae))),Alouatta_caraya),((Tarsius_syrichta,(Tarsius_lariang,(Tarsius_wallacei,Tarsius_dentatus))),(((((Otolemur_garnettii,Otolemur_crassicaudatus),Galagoides_demidoff),Galago_moholi),((Nycticebus_bengalensis,((Perodicticus_potto,Perodicticus_potto_edwarsi),Nycticebus_coucang)),(Propithecus_verreauxi,(Loris_tardigradus,Loris_lydekkerianus)))),(((Nycticebus_pygmaeus,((Palaeopropithecus_ingens,(Eulemur_rufus,(Prolemur_simus,(((Lepilemur_ruficaudatus,Lepilemur_hubbardorum),Cheirogaleus_medius),Hapalemur_griseus)))),Indri_indri)),Propithecus_coquereli),(((Avahi_laniger,((Tarsius_bancanus,((Eulemur_rubriventer,(Eulemur_macaco,(Eulemur_mongoz,Eulemur_fulvus))),((Lemur_catta,Varecia_rubra),Varecia_variegata))),Galago_senegalensis)),Megaladapis_edwardsi),Daubentonia_madagascariensis))))))))),Homo_heidelbergensis)),(Pan_troglodytes_ellioti,(Pan_troglodytes_troglodytes,(Pan_paniscus,Pan_troglodytes))),Homo_sapiens); +((Pan_troglodytes_ellioti,(Pan_paniscus,(Pan_troglodytes_troglodytes,Pan_troglodytes))),((((((Pongo_pygmaeus,Pongo_abelii),(((Miopithecus_ogouensis,((((((Macaca_mulatta,Macaca_fuscata),((((Macaca_nemestrina,Macaca_sylvanus),Macaca_nigra),(Erythrocebus_patas,(((Macaca_fascicularis,Cercopithecus_diana),(Macaca_silenus,Macaca_tonkeana)),(Macaca_thibetana,Macaca_assamensis)))),Macaca_arctoides)),(((Chlorocebus_tantalus,((Chlorocebus_pygerythrus,(Cercopithecus_hamlyni,Chlorocebus_aethiops)),Chlorocebus_cynosuros)),(Cercopithecus_roloway,((((Cercopithecus_albogularis_monoides,(Cercopithecus_albogularis_labiatus,Cercopithecus_albogularis_albotorquatus)),(Cercopithecus_albogularis_erythrarchus,Cercopithecus_mitis_boutourlinii)),Cercopithecus_albogularis),((((Cercopithecus_mitis_mitis,((((Cercopithecus_neglectus,(Cercopithecus_dryas,((Cercopithecus_aethiops,Cercopithecus_solatus),Chlorocebus_sabaeus))),(((Cercopithecus_campbelli,Cercopithecus_mona),(((Cercopithecus_wolfi_elegans,(Cercopithecus_pogonias,Cercopithecus_nictitans_martini)),((Cercopithecus_wolfi_pyrogaster,Cercopithecus_pogonias_schwarzianus),Cercopithecus_pogonias_nigripes)),Cercopithecus_pogonias_grayi)),Cercopithecus_nictitans_nictitans)),(Cercopithecus_cephus_ngottoensis,Cercopithecus_albogularis_francescae)),((((Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi),Cercopithecus_lhoesti),((Cercopithecus_ascanius_schmidti,Cercopithecus_ascanius_whitesidei),(Cercopithecus_cephus_cephus,(Cercopithecus_ascanius_katangae,(Cercopithecus_petaurista,((Cercopithecus_petaurista_buettikoferi,Cercopithecus_petaurista_petaurista),((Cercopithecus_erythrogaster_pococki,Cercopithecus_erythrogaster),Cercopithecus_erythrotis_camerunensis))))))),Cercopithecus_cephus))),(Cercopithecus_mitis_opisthostictus,((Cercopithecus_mitis_stuhlmanni,(Cercopithecus_mitis_heymansi,Cercopithecus_mitis)),(Cercopithecus_nictitans,Cercopithecus_albogularis_kolbi)))),Cercopithecus_albogularis_moloneyi),(Cercopithecus_kandti,Cercopithecus_doggetti))))),Allenopithecus_nigroviridis)),(Miopithecus_talapoin,(((Presbytis_melalophos,((Rhinopithecus_bieti_2_RL2012,((((Pygathrix_nemaeus,Pygathrix_nigripes),((Simias_concolor,Semnopithecus_entellus),Nasalis_larvatus)),((Trachypithecus_cristatus,(Trachypithecus_francoisi,Trachypithecus_obscurus)),Trachypithecus_pileatus)),Trachypithecus_johnii)),(Rhinopithecus_brelichi,Rhinopithecus_avunculus))),Rhinopithecus_roxellana),(Procolobus_verus,((Colobus_guereza,Colobus_satanas),Piliocolobus_badius))))),(((Cercocebus_torquatus,(Mandrillus_leucophaeus,(Cercocebus_agilis,(Mandrillus_sphinx,Cercocebus_atys)))),Cercocebus_chrysogaster),Lophocebus_albigena)),((Papio_kindae,(Papio_ursinus,(Papio_papio,((Papio_hamadryas,Papio_anubis),Papio_cynocephalus)))),((Lophocebus_aterrimus,Rungwecebus_kipunji),Theropithecus_gelada)))),((((Callimico_goeldii,Leontopithecus_rosalia),((((Sapajus_xanthosternos,(Cebus_albifrons,Cebus_apella)),((((Pithecia_pithecia,Cacajao_calvus),(Chiropotes_israelita,Chiropotes_albinasus)),(((Saimiri_boliviensis,Saimiri_oerstedii),(Saimiri_sciureus_macrodon,Saimiri_sciureus)),Saimiri_oerstedii_citrinellus)),Aotus_azarae_azarai)),(Aotus_azarae,((Callicebus_cupreus,((Callithrix_jacchus,(Ateles_paniscus,(Ateles_belzebuth,Ateles_geoffroyi))),Callicebus_donacophilus)),Callicebus_lugens))),(((Brachyteles_arachnoides,Saguinus_oedipus),(Callithrix_pygmaea,Aotus_nancymaae)),((Lagothrix_lagotricha,(Aotus_azarai,Aotus_trivirgatus)),Aotus_lemurinus)))),Alouatta_caraya),(((Tarsius_wallacei,(Tarsius_lariang,Tarsius_dentatus)),((Daubentonia_madagascariensis,((Indri_indri,((((Lepilemur_ruficaudatus,Lepilemur_hubbardorum),Cheirogaleus_medius),(Prolemur_simus,Hapalemur_griseus)),(Palaeopropithecus_ingens,Eulemur_rufus))),((Propithecus_verreauxi,((Propithecus_coquereli,(Galago_senegalensis,(((Eulemur_macaco,((Eulemur_mongoz,Eulemur_rubriventer),Eulemur_fulvus)),((Varecia_variegata,Varecia_rubra),Lemur_catta)),Tarsius_bancanus))),Avahi_laniger)),Megaladapis_edwardsi))),((((Otolemur_crassicaudatus,Galago_moholi),Otolemur_garnettii),Galagoides_demidoff),((Nycticebus_bengalensis,((Perodicticus_potto,Perodicticus_potto_edwarsi),Nycticebus_coucang)),(Nycticebus_pygmaeus,(Loris_tardigradus,Loris_lydekkerianus)))))),Tarsius_syrichta))),((Hylobates_moloch,Nomascus_leucogenys),(Hylobates_lar,(Symphalangus_syndactylus,Hylobates_agilis))))),Gorilla_gorilla),Gorilla_gorilla_gorilla),Homo_heidelbergensis),Homo_sapiens_ssp_Denisova),Homo_sapiens); +((Pan_troglodytes_ellioti,Homo_heidelbergensis),((((((Miopithecus_ogouensis,((((((((Colobus_guereza,Colobus_satanas),(Piliocolobus_badius,Procolobus_verus)),((Trachypithecus_johnii,Rhinopithecus_avunculus),Presbytis_melalophos)),((((Rhinopithecus_bieti_2_RL2012,Rhinopithecus_brelichi),((Simias_concolor,Nasalis_larvatus),(Pygathrix_nemaeus,Pygathrix_nigripes))),Rhinopithecus_roxellana),(Trachypithecus_pileatus,((Trachypithecus_cristatus,Trachypithecus_obscurus),Trachypithecus_francoisi)))),Semnopithecus_entellus),((((Cercopithecus_campbelli,Cercopithecus_diana),(((((Cercopithecus_albogularis,Cercopithecus_albogularis_monoides),(Cercopithecus_albogularis_albotorquatus,(Cercopithecus_mitis_boutourlinii,(Cercopithecus_albogularis_erythrarchus,Cercopithecus_albogularis_labiatus)))),((Cercopithecus_albogularis_moloneyi,((((((((Cercopithecus_petaurista,(((Cercopithecus_petaurista_buettikoferi,Cercopithecus_petaurista_petaurista),Cercopithecus_erythrogaster_pococki),Cercopithecus_erythrogaster)),Cercopithecus_ascanius_whitesidei),Cercopithecus_neglectus),Cercopithecus_cephus_cephus),((((Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi),Cercopithecus_lhoesti),Cercopithecus_erythrotis_camerunensis),Cercopithecus_ascanius_katangae)),(Cercopithecus_ascanius_schmidti,((Cercopithecus_dryas,Cercopithecus_solatus),(Cercopithecus_aethiops,Chlorocebus_sabaeus)))),Cercopithecus_cephus_ngottoensis),Cercopithecus_cephus)),(((Cercopithecus_mitis_mitis,Cercopithecus_mitis_opisthostictus),(Cercopithecus_nictitans_nictitans,((((Cercopithecus_mitis_heymansi,Cercopithecus_albogularis_kolbi),(Cercopithecus_kandti,Cercopithecus_mitis_stuhlmanni)),(Cercopithecus_doggetti,Cercopithecus_albogularis_francescae)),Cercopithecus_mitis))),Cercopithecus_nictitans))),((Macaca_silenus,Macaca_tonkeana),((((Macaca_nemestrina,(Macaca_thibetana,Macaca_assamensis)),(Macaca_fascicularis,(Macaca_arctoides,(Macaca_mulatta,Macaca_fuscata)))),(Macaca_sylvanus,Erythrocebus_patas)),Macaca_nigra))),Cercopithecus_roloway)),Cercopithecus_mona),(((Cercopithecus_pogonias_nigripes,((Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans),Cercopithecus_pogonias_grayi)),Cercopithecus_pogonias_schwarzianus),Cercopithecus_pogonias))),((((((Mandrillus_sphinx,(Cercocebus_torquatus,Cercocebus_atys)),Cercocebus_agilis),Mandrillus_leucophaeus),Cercocebus_chrysogaster),(Allenopithecus_nigroviridis,((Theropithecus_gelada,(Rungwecebus_kipunji,((Papio_ursinus,(Papio_cynocephalus,Papio_kindae)),(Papio_papio,(Papio_hamadryas,Papio_anubis))))),(Lophocebus_albigena,Lophocebus_aterrimus)))),(((Chlorocebus_cynosuros,Cercopithecus_hamlyni),(Chlorocebus_aethiops,Chlorocebus_tantalus)),Chlorocebus_pygerythrus))),(Miopithecus_talapoin,Cercopithecus_nictitans_martini))),((((((((Aotus_lemurinus,Aotus_azarai),((Aotus_azarae_azarai,(Aotus_azarae,Aotus_trivirgatus)),((((Saimiri_sciureus_macrodon,Saimiri_boliviensis),(Saimiri_sciureus,Saimiri_oerstedii)),Saimiri_oerstedii_citrinellus),(Aotus_nancymaae,Leontopithecus_rosalia)))),((Pithecia_pithecia,(Callithrix_jacchus,Callithrix_pygmaea)),((((Callicebus_donacophilus,((Ateles_paniscus,Callicebus_cupreus),Callicebus_lugens)),(Cebus_albifrons,(Cebus_apella,Sapajus_xanthosternos))),(Cacajao_calvus,(Lagothrix_lagotricha,(Chiropotes_israelita,Chiropotes_albinasus)))),(Alouatta_caraya,Callimico_goeldii)))),Ateles_geoffroyi),Ateles_belzebuth),Saguinus_oedipus),Brachyteles_arachnoides),((((Otolemur_garnettii,((((((((((Indri_indri,(Lepilemur_ruficaudatus,Lepilemur_hubbardorum)),(Propithecus_coquereli,Palaeopropithecus_ingens)),Eulemur_rufus),Cheirogaleus_medius),Hapalemur_griseus),Prolemur_simus),Avahi_laniger),Propithecus_verreauxi),Megaladapis_edwardsi),((Galago_moholi,((((Perodicticus_potto,Perodicticus_potto_edwarsi),Nycticebus_coucang),Nycticebus_bengalensis),(Loris_lydekkerianus,(Galagoides_demidoff,(Loris_tardigradus,Nycticebus_pygmaeus))))),Daubentonia_madagascariensis))),(Galago_senegalensis,(Tarsius_bancanus,(((Eulemur_rubriventer,Eulemur_fulvus),(Eulemur_macaco,(Varecia_variegata,Varecia_rubra))),(Eulemur_mongoz,Lemur_catta))))),Otolemur_crassicaudatus),((Tarsius_wallacei,(Tarsius_lariang,Tarsius_dentatus)),Tarsius_syrichta)))),(Gorilla_gorilla_gorilla,Gorilla_gorilla)),((((Pongo_pygmaeus,Pongo_abelii),Hylobates_lar),(Hylobates_moloch,Hylobates_agilis)),(Nomascus_leucogenys,Symphalangus_syndactylus))),((Pan_paniscus,Pan_troglodytes_troglodytes),Pan_troglodytes)),Homo_sapiens_ssp_Denisova),Homo_sapiens); +((Pan_troglodytes_troglodytes,(Pan_troglodytes,Pan_paniscus)),(Pan_troglodytes_ellioti,(Homo_heidelbergensis,(((Gorilla_gorilla_gorilla,(Homo_sapiens_ssp_Denisova,(((((Colobus_guereza,Colobus_satanas),(Piliocolobus_badius,Procolobus_verus)),(Rhinopithecus_avunculus,((Presbytis_melalophos,((Trachypithecus_pileatus,((Trachypithecus_francoisi,Trachypithecus_obscurus),Trachypithecus_cristatus)),Trachypithecus_johnii)),((((Semnopithecus_entellus,(Simias_concolor,Nasalis_larvatus)),(Pygathrix_nemaeus,Pygathrix_nigripes)),(Rhinopithecus_bieti_2_RL2012,Rhinopithecus_brelichi)),Rhinopithecus_roxellana)))),(((Miopithecus_ogouensis,Miopithecus_talapoin),(Cercopithecus_diana,((Cercopithecus_roloway,((Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi),Cercopithecus_lhoesti)),((((((Macaca_thibetana,Macaca_assamensis),(Macaca_fascicularis,(Macaca_silenus,Macaca_tonkeana))),(((Macaca_mulatta,Macaca_fuscata),Macaca_nigra),(Macaca_sylvanus,Macaca_nemestrina))),Macaca_arctoides),((((((Papio_ursinus,(Papio_papio,(Papio_cynocephalus,Papio_kindae))),(Papio_hamadryas,Papio_anubis)),((Lophocebus_albigena,Lophocebus_aterrimus),Rungwecebus_kipunji)),Theropithecus_gelada),((Mandrillus_leucophaeus,(Cercocebus_agilis,(Mandrillus_sphinx,(Cercocebus_torquatus,Cercocebus_atys)))),Cercocebus_chrysogaster)),Allenopithecus_nigroviridis)),Erythrocebus_patas)))),((((((Cercopithecus_cephus_cephus,(Cercopithecus_petaurista,((Cercopithecus_erythrotis_camerunensis,Cercopithecus_ascanius_katangae),(Cercopithecus_erythrogaster,(Cercopithecus_petaurista_petaurista,(Cercopithecus_petaurista_buettikoferi,Cercopithecus_erythrogaster_pococki)))))),Cercopithecus_ascanius_whitesidei),(Cercopithecus_ascanius_schmidti,(Cercopithecus_cephus_ngottoensis,Cercopithecus_cephus))),((((Cercopithecus_mitis_mitis,Cercopithecus_mitis_opisthostictus),((Cercopithecus_nictitans,Cercopithecus_nictitans_nictitans),(Cercopithecus_mitis,(((Cercopithecus_albogularis_francescae,(Cercopithecus_albogularis_kolbi,Cercopithecus_mitis_heymansi)),Cercopithecus_doggetti),(Cercopithecus_mitis_stuhlmanni,Cercopithecus_kandti))))),((Cercopithecus_albogularis,(Cercopithecus_albogularis_labiatus,(Cercopithecus_albogularis_monoides,(Cercopithecus_mitis_boutourlinii,Cercopithecus_albogularis_erythrarchus)))),Cercopithecus_albogularis_albotorquatus)),Cercopithecus_albogularis_moloneyi)),Cercopithecus_neglectus),((((((Cercopithecus_pogonias_grayi,Cercopithecus_pogonias_nigripes),(Cercopithecus_wolfi_elegans,Cercopithecus_pogonias_schwarzianus)),(Cercopithecus_wolfi_pyrogaster,Cercopithecus_pogonias)),Cercopithecus_nictitans_martini),(Cercopithecus_mona,Cercopithecus_campbelli)),((((Chlorocebus_pygerythrus,(Chlorocebus_cynosuros,Cercopithecus_hamlyni)),(Chlorocebus_aethiops,Chlorocebus_tantalus)),((Cercopithecus_aethiops,Cercopithecus_solatus),Chlorocebus_sabaeus)),Cercopithecus_dryas))))),(((((Callimico_goeldii,(Ateles_paniscus,(Saguinus_oedipus,(Callithrix_jacchus,(Lagothrix_lagotricha,Callithrix_pygmaea))))),(Pithecia_pithecia,(((Cacajao_calvus,(Chiropotes_israelita,Chiropotes_albinasus)),((((((Saimiri_sciureus,Saimiri_oerstedii),Saimiri_boliviensis),Saimiri_sciureus_macrodon),Saimiri_oerstedii_citrinellus),(((Aotus_nancymaae,(Aotus_lemurinus,Aotus_azarai)),(Aotus_azarae_azarai,Aotus_azarae)),Aotus_trivirgatus)),Leontopithecus_rosalia)),((((Callicebus_donacophilus,Callicebus_cupreus),(Ateles_belzebuth,Ateles_geoffroyi)),Callicebus_lugens),(Sapajus_xanthosternos,(Cebus_albifrons,Cebus_apella)))))),Brachyteles_arachnoides),Alouatta_caraya),((((Varecia_variegata,((Eulemur_macaco,Eulemur_rubriventer),Lemur_catta)),((Eulemur_mongoz,Varecia_rubra),Eulemur_fulvus)),Tarsius_bancanus),(((Tarsius_wallacei,(Tarsius_lariang,Tarsius_dentatus)),Tarsius_syrichta),(((((Galago_moholi,Galago_senegalensis),(Galagoides_demidoff,(Otolemur_crassicaudatus,Otolemur_garnettii))),(Loris_lydekkerianus,((Perodicticus_potto,(Perodicticus_potto_edwarsi,Nycticebus_coucang)),Nycticebus_bengalensis))),((Propithecus_verreauxi,Daubentonia_madagascariensis),Avahi_laniger)),(Nycticebus_pygmaeus,(Megaladapis_edwardsi,((((Palaeopropithecus_ingens,(Loris_tardigradus,(((Lepilemur_ruficaudatus,Lepilemur_hubbardorum),Indri_indri),Propithecus_coquereli))),Eulemur_rufus),(Cheirogaleus_medius,Hapalemur_griseus)),Prolemur_simus)))))))))),((Hylobates_moloch,(Nomascus_leucogenys,((Hylobates_lar,Symphalangus_syndactylus),Hylobates_agilis))),(Pongo_pygmaeus,Pongo_abelii))),Gorilla_gorilla))),Homo_sapiens); +(((((Hylobates_agilis,Symphalangus_syndactylus),Nomascus_leucogenys),Hylobates_lar),((((((Cercopithecus_mona,Cercopithecus_campbelli),Cercopithecus_pogonias),((Cercopithecus_nictitans_martini,((Cercopithecus_pogonias_nigripes,((Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans),Cercopithecus_pogonias_schwarzianus)),Cercopithecus_pogonias_grayi)),(Cercopithecus_neglectus,((((((Chlorocebus_pygerythrus,Chlorocebus_cynosuros),(Chlorocebus_aethiops,Chlorocebus_tantalus)),Cercopithecus_hamlyni),((Cercopithecus_aethiops,Cercopithecus_solatus),Chlorocebus_sabaeus)),Cercopithecus_dryas),((((((Cercopithecus_ascanius_schmidti,(Cercopithecus_erythrotis_camerunensis,(Cercopithecus_ascanius_katangae,(((Cercopithecus_petaurista,(Cercopithecus_petaurista_buettikoferi,Cercopithecus_petaurista_petaurista)),(Cercopithecus_erythrogaster_pococki,Cercopithecus_erythrogaster)),Cercopithecus_cephus_cephus)))),Cercopithecus_ascanius_whitesidei),((Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi),Cercopithecus_lhoesti)),(Cercopithecus_cephus_ngottoensis,Cercopithecus_cephus)),(((Cercopithecus_nictitans,((Cercopithecus_mitis_stuhlmanni,(Cercopithecus_doggetti,(Cercopithecus_kandti,((Cercopithecus_nictitans_nictitans,Cercopithecus_albogularis_francescae),(((Cercopithecus_mitis_mitis,Cercopithecus_mitis_opisthostictus),Cercopithecus_mitis_heymansi),Cercopithecus_albogularis_kolbi))))),Cercopithecus_mitis)),(((Cercopithecus_albogularis,Cercopithecus_albogularis_monoides),Cercopithecus_mitis_boutourlinii),((Cercopithecus_albogularis_erythrarchus,Cercopithecus_albogularis_albotorquatus),Cercopithecus_albogularis_labiatus))),Cercopithecus_albogularis_moloneyi)),((((((Macaca_thibetana,Macaca_assamensis),((Cercocebus_atys,(Macaca_fascicularis,Macaca_mulatta)),(Macaca_tonkeana,Macaca_silenus))),((Macaca_fuscata,Macaca_nigra),Macaca_nemestrina)),Macaca_arctoides),(((((((Colobus_guereza,Colobus_satanas),Piliocolobus_badius),(((((((Trachypithecus_obscurus,(Trachypithecus_francoisi,Trachypithecus_cristatus)),Trachypithecus_pileatus),((Trachypithecus_johnii,((Simias_concolor,Semnopithecus_entellus),Nasalis_larvatus)),(Pygathrix_nemaeus,Pygathrix_nigripes))),Rhinopithecus_roxellana),Rhinopithecus_avunculus),Presbytis_melalophos),(Rhinopithecus_brelichi,Rhinopithecus_bieti_2_RL2012))),Procolobus_verus),Cercopithecus_diana),Miopithecus_talapoin),((Macaca_sylvanus,((((((Papio_anubis,Papio_cynocephalus),Papio_papio),Papio_ursinus),(Papio_kindae,Papio_hamadryas)),(Theropithecus_gelada,((Lophocebus_albigena,Lophocebus_aterrimus),Rungwecebus_kipunji))),(Cercocebus_chrysogaster,(((Mandrillus_leucophaeus,Cercocebus_torquatus),Mandrillus_sphinx),Cercocebus_agilis)))),(Erythrocebus_patas,Allenopithecus_nigroviridis)))),Cercopithecus_roloway)))))),Miopithecus_ogouensis),(((((Aotus_lemurinus,Aotus_azarai),((Aotus_nancymaae,Callithrix_pygmaea),((Alouatta_caraya,Leontopithecus_rosalia),(Aotus_azarae_azarai,((Pithecia_pithecia,(Lagothrix_lagotricha,(((Callicebus_cupreus,(Ateles_geoffroyi,Ateles_belzebuth)),Callicebus_donacophilus),Callicebus_lugens))),((Cebus_albifrons,(Cebus_apella,Sapajus_xanthosternos)),((Saimiri_oerstedii_citrinellus,(Saimiri_sciureus_macrodon,((Saimiri_oerstedii,Saimiri_sciureus),Saimiri_boliviensis))),(Aotus_trivirgatus,((Cacajao_calvus,Aotus_azarae),(Chiropotes_israelita,Chiropotes_albinasus)))))))))),(Ateles_paniscus,((Callithrix_jacchus,Callimico_goeldii),Saguinus_oedipus))),Brachyteles_arachnoides),((((Tarsius_dentatus,Tarsius_wallacei),Tarsius_lariang),Tarsius_syrichta),(((Perodicticus_potto_edwarsi,((Loris_tardigradus,Loris_lydekkerianus),(Nycticebus_bengalensis,Nycticebus_coucang))),(((Otolemur_crassicaudatus,(Otolemur_garnettii,Galago_moholi)),(Galago_senegalensis,Galagoides_demidoff)),Perodicticus_potto)),(Daubentonia_madagascariensis,((((Eulemur_rufus,(Lepilemur_ruficaudatus,(Indri_indri,(Palaeopropithecus_ingens,Propithecus_verreauxi)))),(((Lepilemur_hubbardorum,Cheirogaleus_medius),(Nycticebus_pygmaeus,Hapalemur_griseus)),(Prolemur_simus,Propithecus_coquereli))),(Megaladapis_edwardsi,Avahi_laniger)),(Tarsius_bancanus,(((Eulemur_mongoz,Eulemur_macaco),(Lemur_catta,(Varecia_variegata,Varecia_rubra))),(Eulemur_fulvus,Eulemur_rubriventer))))))))),Hylobates_moloch)),(((Pan_troglodytes,(Pan_troglodytes_troglodytes,Pan_paniscus)),Pan_troglodytes_ellioti),((((Gorilla_gorilla,Homo_heidelbergensis),(Pongo_pygmaeus,Pongo_abelii)),Homo_sapiens_ssp_Denisova),Gorilla_gorilla_gorilla)),Homo_sapiens); +(((((Gorilla_gorilla_gorilla,(((Semnopithecus_entellus,(Trachypithecus_johnii,(Presbytis_melalophos,((((Piliocolobus_badius,Procolobus_verus),(Colobus_guereza,Colobus_satanas)),(((Trachypithecus_cristatus,Trachypithecus_francoisi),(Trachypithecus_obscurus,Trachypithecus_pileatus)),((Rhinopithecus_brelichi,((Pygathrix_nemaeus,((Simias_concolor,Nasalis_larvatus),Pygathrix_nigripes)),Rhinopithecus_bieti_2_RL2012)),Rhinopithecus_roxellana))),Rhinopithecus_avunculus)))),((Cercopithecus_diana,(Miopithecus_talapoin,Miopithecus_ogouensis)),(((((Cercocebus_agilis,((Rungwecebus_kipunji,(Papio_kindae,(Papio_papio,(((Papio_ursinus,Papio_cynocephalus),Papio_anubis),Papio_hamadryas)))),((Lophocebus_albigena,Lophocebus_aterrimus),Theropithecus_gelada))),((Cercocebus_chrysogaster,(Cercocebus_atys,Cercocebus_torquatus)),Mandrillus_leucophaeus)),((Macaca_arctoides,((Macaca_fascicularis,(((Macaca_assamensis,Macaca_thibetana),Macaca_silenus),Macaca_tonkeana)),((Macaca_sylvanus,((Macaca_mulatta,Macaca_fuscata),Macaca_nigra)),Macaca_nemestrina))),((Allenopithecus_nigroviridis,((((Cercopithecus_albogularis,(Cercopithecus_albogularis_labiatus,((Cercopithecus_albogularis_erythrarchus,Cercopithecus_mitis_boutourlinii),(Cercopithecus_mitis_opisthostictus,Cercopithecus_albogularis_albotorquatus)))),Cercopithecus_mitis_mitis),((((((((Cercopithecus_mitis,Cercopithecus_doggetti),Cercopithecus_kandti),(Cercopithecus_albogularis_francescae,Cercopithecus_mitis_heymansi)),(Cercopithecus_albogularis_monoides,(Cercopithecus_nictitans_nictitans,(((Cercopithecus_mona,Cercopithecus_nictitans),Cercopithecus_campbelli),((((Cercopithecus_pogonias_schwarzianus,Cercopithecus_pogonias),Cercopithecus_pogonias_nigripes),((Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans),Cercopithecus_nictitans_martini)),Cercopithecus_pogonias_grayi))))),((Cercopithecus_neglectus,Cercopithecus_ascanius_whitesidei),(Cercopithecus_erythrotis_camerunensis,((Cercopithecus_ascanius_katangae,(Cercopithecus_cephus_cephus,(Cercopithecus_solatus,(Cercopithecus_mitis_stuhlmanni,Cercopithecus_albogularis_kolbi)))),(Cercopithecus_petaurista,((Cercopithecus_petaurista_petaurista,Cercopithecus_petaurista_buettikoferi),(Cercopithecus_erythrogaster,Cercopithecus_erythrogaster_pococki))))))),Cercopithecus_albogularis_moloneyi),(Cercopithecus_cephus_ngottoensis,Cercopithecus_cephus)),((((((Cercopithecus_hamlyni,Chlorocebus_aethiops),((Chlorocebus_tantalus,Cercopithecus_dryas),Chlorocebus_cynosuros)),Chlorocebus_pygerythrus),Chlorocebus_sabaeus),Cercopithecus_aethiops),Cercopithecus_ascanius_schmidti))),Cercopithecus_roloway)),(Cercopithecus_lhoesti,(Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi))))),Erythrocebus_patas),Mandrillus_sphinx))),((Alouatta_caraya,((Callimico_goeldii,Leontopithecus_rosalia),((Callicebus_donacophilus,(Ateles_paniscus,(Ateles_geoffroyi,(Callithrix_jacchus,(Lagothrix_lagotricha,((((Aotus_trivirgatus,(Aotus_azarae,Aotus_azarae_azarai)),(Aotus_azarai,Aotus_lemurinus)),(Callithrix_pygmaea,Saguinus_oedipus)),Pithecia_pithecia)))))),((((Cacajao_calvus,(Aotus_nancymaae,((Saimiri_sciureus_macrodon,(Saimiri_sciureus,(Saimiri_oerstedii,Saimiri_boliviensis))),Saimiri_oerstedii_citrinellus))),(Chiropotes_israelita,(Brachyteles_arachnoides,Chiropotes_albinasus))),Ateles_belzebuth),((Callicebus_lugens,Callicebus_cupreus),(Cebus_albifrons,(Sapajus_xanthosternos,Cebus_apella))))))),(Tarsius_bancanus,(Loris_tardigradus,(((Megaladapis_edwardsi,((((Propithecus_verreauxi,((Eulemur_rubriventer,(Eulemur_rufus,((((Lemur_catta,Hapalemur_griseus),((Lepilemur_hubbardorum,Lepilemur_ruficaudatus),Cheirogaleus_medius)),((Eulemur_macaco,Eulemur_mongoz),Prolemur_simus)),Eulemur_fulvus))),Palaeopropithecus_ingens)),Propithecus_coquereli),((Galago_moholi,((Perodicticus_potto,Perodicticus_potto_edwarsi),((Nycticebus_pygmaeus,(Loris_lydekkerianus,(Varecia_rubra,Varecia_variegata))),(Nycticebus_bengalensis,Nycticebus_coucang)))),(Avahi_laniger,Indri_indri))),Daubentonia_madagascariensis)),((Tarsius_wallacei,(Tarsius_dentatus,Tarsius_lariang)),Tarsius_syrichta)),((Galagoides_demidoff,(Otolemur_garnettii,Otolemur_crassicaudatus)),Galago_senegalensis))))))),Gorilla_gorilla),((Hylobates_moloch,(Symphalangus_syndactylus,Hylobates_agilis)),(Nomascus_leucogenys,((Pongo_abelii,Pongo_pygmaeus),Hylobates_lar)))),(Pan_paniscus,(Pan_troglodytes,Pan_troglodytes_troglodytes))),((Pan_troglodytes_ellioti,Homo_heidelbergensis),Homo_sapiens_ssp_Denisova),Homo_sapiens); +((((Homo_sapiens_ssp_Denisova,((Gorilla_gorilla_gorilla,((((Semnopithecus_entellus,(((Piliocolobus_badius,Procolobus_verus),(Colobus_guereza,Colobus_satanas)),(((Trachypithecus_pileatus,(((Trachypithecus_cristatus,(Rhinopithecus_roxellana,((Simias_concolor,Nasalis_larvatus),(Trachypithecus_obscurus,(Rhinopithecus_bieti_2_RL2012,Trachypithecus_francoisi))))),(Pygathrix_nemaeus,(Rhinopithecus_brelichi,Pygathrix_nigripes))),Trachypithecus_johnii)),Rhinopithecus_avunculus),Presbytis_melalophos))),((Miopithecus_talapoin,(Cercopithecus_diana,((((((((Papio_kindae,((Papio_papio,(Papio_hamadryas,Papio_anubis)),((Papio_cynocephalus,Papio_ursinus),Rungwecebus_kipunji))),((Lophocebus_albigena,Lophocebus_aterrimus),Theropithecus_gelada)),(Macaca_assamensis,Macaca_thibetana)),Macaca_silenus),((Macaca_fascicularis,(((Macaca_nemestrina,Macaca_nigra),(Macaca_arctoides,(Macaca_mulatta,Macaca_fuscata))),Macaca_sylvanus)),Macaca_tonkeana)),((Cercocebus_torquatus,Cercocebus_chrysogaster),((Cercocebus_agilis,Mandrillus_leucophaeus),(Mandrillus_sphinx,Cercocebus_atys)))),(((Allenopithecus_nigroviridis,Cercopithecus_roloway),(((Cercopithecus_albogularis,(Cercopithecus_albogularis_albotorquatus,(Cercopithecus_mitis_boutourlinii,(Cercopithecus_albogularis_erythrarchus,Cercopithecus_albogularis_labiatus)))),((((Cercopithecus_nictitans,Cercopithecus_nictitans_nictitans),(((Cercopithecus_albogularis_monoides,Cercopithecus_mitis_heymansi),Cercopithecus_mitis_mitis),Cercopithecus_mitis_opisthostictus)),((Cercopithecus_kandti,Cercopithecus_doggetti),Cercopithecus_mitis)),(Cercopithecus_albogularis_moloneyi,((((Cercopithecus_aethiops,((((Chlorocebus_cynosuros,Chlorocebus_pygerythrus),(Chlorocebus_tantalus,(Cercopithecus_hamlyni,Chlorocebus_aethiops))),Cercopithecus_dryas),Chlorocebus_sabaeus)),Cercopithecus_albogularis_francescae),(Cercopithecus_ascanius_schmidti,((Cercopithecus_neglectus,Cercopithecus_ascanius_whitesidei),(((((Cercopithecus_erythrogaster,Cercopithecus_petaurista),(Cercopithecus_petaurista_petaurista,(Cercopithecus_petaurista_buettikoferi,Cercopithecus_erythrogaster_pococki))),Cercopithecus_cephus_cephus),(Cercopithecus_erythrotis_camerunensis,Cercopithecus_ascanius_katangae)),((Cercopithecus_mitis_stuhlmanni,Cercopithecus_albogularis_kolbi),Cercopithecus_solatus))))),(Cercopithecus_cephus_ngottoensis,Cercopithecus_cephus))))),(Cercopithecus_lhoesti,(Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi)))),((Cercopithecus_mona,Cercopithecus_campbelli),((Cercopithecus_pogonias_schwarzianus,((Cercopithecus_nictitans_martini,(Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans)),(Cercopithecus_pogonias_nigripes,Cercopithecus_pogonias))),Cercopithecus_pogonias_grayi)))),Erythrocebus_patas))),Miopithecus_ogouensis)),((Alouatta_caraya,(((Callimico_goeldii,Leontopithecus_rosalia),(((Aotus_azarae,(Aotus_lemurinus,(Aotus_azarai,(Aotus_trivirgatus,((((Chiropotes_israelita,(Brachyteles_arachnoides,Chiropotes_albinasus)),(Callicebus_donacophilus,((((Ateles_paniscus,Callithrix_jacchus),Ateles_belzebuth),Callicebus_cupreus),Ateles_geoffroyi))),(Aotus_azarae_azarai,(((Aotus_nancymaae,((Saimiri_sciureus_macrodon,(Saimiri_boliviensis,(Saimiri_oerstedii,Saimiri_sciureus))),Saimiri_oerstedii_citrinellus)),Cacajao_calvus),(Cebus_albifrons,(Sapajus_xanthosternos,Cebus_apella))))),Callicebus_lugens))))),Lagothrix_lagotricha),Pithecia_pithecia)),(Callithrix_pygmaea,Saguinus_oedipus))),(Tarsius_bancanus,(((Galagoides_demidoff,(Otolemur_garnettii,Otolemur_crassicaudatus)),((((Eulemur_fulvus,Eulemur_rubriventer),(((((((Eulemur_mongoz,(Prolemur_simus,((Cheirogaleus_medius,(Lepilemur_hubbardorum,Lepilemur_ruficaudatus)),(Lemur_catta,Hapalemur_griseus)))),(Eulemur_rufus,Propithecus_verreauxi)),Palaeopropithecus_ingens),Indri_indri),Eulemur_macaco),(Avahi_laniger,Megaladapis_edwardsi)),Propithecus_coquereli)),(((Galago_moholi,((Perodicticus_potto,Perodicticus_potto_edwarsi),((Loris_lydekkerianus,(Varecia_rubra,Varecia_variegata)),(Nycticebus_bengalensis,(Nycticebus_pygmaeus,Nycticebus_coucang))))),((Tarsius_lariang,(Tarsius_wallacei,Tarsius_dentatus)),Tarsius_syrichta)),Daubentonia_madagascariensis)),Loris_tardigradus)),Galago_senegalensis)))),((((Nomascus_leucogenys,Hylobates_moloch),(Hylobates_agilis,Symphalangus_syndactylus)),Hylobates_lar),(Pongo_abelii,Pongo_pygmaeus)))),Gorilla_gorilla)),Homo_heidelbergensis),Pan_troglodytes_ellioti),(Pan_troglodytes_troglodytes,(Pan_paniscus,Pan_troglodytes)),Homo_sapiens); +(((Pan_troglodytes_ellioti,(Homo_heidelbergensis,(((Hylobates_moloch,((Hylobates_lar,(Pongo_abelii,(Symphalangus_syndactylus,Pongo_pygmaeus))),Hylobates_agilis)),Nomascus_leucogenys),(Gorilla_gorilla_gorilla,(Gorilla_gorilla,((((Rhinopithecus_avunculus,((Presbytis_melalophos,Piliocolobus_badius),Procolobus_verus)),(((Rhinopithecus_bieti_2_RL2012,(Rhinopithecus_brelichi,Rhinopithecus_roxellana)),(Colobus_guereza,Colobus_satanas)),(((((Trachypithecus_francoisi,Trachypithecus_cristatus),Trachypithecus_johnii),Trachypithecus_obscurus),Trachypithecus_pileatus),(Semnopithecus_entellus,((Pygathrix_nigripes,Pygathrix_nemaeus),(Simias_concolor,Nasalis_larvatus)))))),((Miopithecus_ogouensis,(Miopithecus_talapoin,(((Cercopithecus_mitis_stuhlmanni,Cercopithecus_albogularis_kolbi),(Cercopithecus_diana,((((Cercopithecus_nictitans_martini,((((((((Cercopithecus_mitis_boutourlinii,(Cercopithecus_albogularis_albotorquatus,Cercopithecus_albogularis_erythrarchus)),Cercopithecus_albogularis_labiatus),(Cercopithecus_albogularis,Cercopithecus_albogularis_monoides)),((Cercopithecus_mitis_mitis,Cercopithecus_mitis_opisthostictus),Cercopithecus_mitis_heymansi)),((Cercopithecus_albogularis_francescae,(Cercopithecus_doggetti,Cercopithecus_kandti)),Cercopithecus_mitis)),Cercopithecus_nictitans_nictitans),Cercopithecus_cephus_ngottoensis),Cercopithecus_neglectus)),Cercopithecus_albogularis_moloneyi),(Cercopithecus_nictitans,((((Chlorocebus_aethiops,Chlorocebus_cynosuros),(((Chlorocebus_tantalus,(Cercopithecus_aethiops,Cercopithecus_hamlyni)),Chlorocebus_pygerythrus),Chlorocebus_sabaeus)),Cercopithecus_dryas),Cercopithecus_cephus))),((((Cercopithecus_ascanius_schmidti,Cercopithecus_ascanius_whitesidei),Cercopithecus_ascanius_katangae),Cercopithecus_cephus_cephus),(Cercopithecus_erythrotis_camerunensis,(Cercopithecus_erythrogaster_pococki,((Cercopithecus_petaurista_buettikoferi,(Cercopithecus_petaurista,Cercopithecus_erythrogaster)),Cercopithecus_petaurista_petaurista))))))),Cercopithecus_solatus))),(((Erythrocebus_patas,Mandrillus_sphinx),(Cercopithecus_roloway,((Cercopithecus_lhoesti,(Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi)),(((((Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans),Cercopithecus_pogonias_grayi),Cercopithecus_pogonias_schwarzianus),Cercopithecus_pogonias_nigripes),(Cercopithecus_pogonias,(Cercopithecus_mona,Cercopithecus_campbelli)))))),(((((Cercocebus_torquatus,Cercocebus_atys),Cercocebus_agilis),Cercocebus_chrysogaster),Mandrillus_leucophaeus),((Allenopithecus_nigroviridis,((((Papio_ursinus,(Papio_hamadryas,Papio_anubis)),(Papio_kindae,(Papio_cynocephalus,Papio_papio))),Rungwecebus_kipunji),((Lophocebus_albigena,Lophocebus_aterrimus),Theropithecus_gelada))),(((Macaca_mulatta,(((Macaca_tonkeana,(Macaca_nigra,(Macaca_fascicularis,Macaca_silenus))),(Macaca_assamensis,Macaca_thibetana)),Macaca_nemestrina)),Macaca_arctoides),(Macaca_sylvanus,Macaca_fuscata))))))),((Alouatta_caraya,((((((((Brachyteles_arachnoides,Chiropotes_albinasus),(((Aotus_azarai,Aotus_lemurinus),Aotus_azarae),((Saimiri_sciureus_macrodon,(Saimiri_boliviensis,(Saimiri_oerstedii,Saimiri_sciureus))),Saimiri_oerstedii_citrinellus))),((Pithecia_pithecia,Ateles_geoffroyi),((Callicebus_donacophilus,(Ateles_belzebuth,(Lagothrix_lagotricha,((Aotus_nancymaae,((Chiropotes_israelita,Aotus_trivirgatus),(Callicebus_cupreus,Callicebus_lugens))),Ateles_paniscus)))),Callithrix_jacchus))),Cacajao_calvus),(Callimico_goeldii,Leontopithecus_rosalia)),(Cebus_albifrons,(Sapajus_xanthosternos,Cebus_apella))),Aotus_azarae_azarai),(Saguinus_oedipus,Callithrix_pygmaea))),((((Loris_tardigradus,Tarsius_bancanus),(Propithecus_coquereli,(Avahi_laniger,(((Eulemur_fulvus,Eulemur_rubriventer),Megaladapis_edwardsi),Eulemur_macaco)))),(Daubentonia_madagascariensis,((Perodicticus_potto,Perodicticus_potto_edwarsi),(((((Tarsius_dentatus,(Tarsius_lariang,Tarsius_syrichta)),Tarsius_wallacei),Galago_moholi),(((Lepilemur_hubbardorum,Lepilemur_ruficaudatus),(Palaeopropithecus_ingens,(((Varecia_rubra,Varecia_variegata),(Eulemur_rufus,Eulemur_mongoz)),(Lemur_catta,(Cheirogaleus_medius,(Prolemur_simus,Hapalemur_griseus)))))),(Propithecus_verreauxi,Indri_indri))),((Nycticebus_pygmaeus,(Nycticebus_coucang,Nycticebus_bengalensis)),Loris_lydekkerianus))))),((Galagoides_demidoff,(Galago_senegalensis,Otolemur_crassicaudatus)),Otolemur_garnettii))))))))),(Pan_troglodytes_troglodytes,Homo_sapiens_ssp_Denisova)),(Pan_troglodytes,Pan_paniscus),Homo_sapiens); +(Homo_sapiens_ssp_Denisova,((Homo_heidelbergensis,(((Pan_troglodytes,Pan_troglodytes_troglodytes),Pan_paniscus),Pan_troglodytes_ellioti)),(((((Pongo_pygmaeus,Pongo_abelii),Hylobates_lar),(Hylobates_moloch,Nomascus_leucogenys)),(Symphalangus_syndactylus,Hylobates_agilis)),((Gorilla_gorilla,((((((((Rhinopithecus_bieti_2_RL2012,(((Simias_concolor,Nasalis_larvatus),(Pygathrix_nigripes,Pygathrix_nemaeus)),(Rhinopithecus_brelichi,Rhinopithecus_roxellana))),((Trachypithecus_pileatus,Trachypithecus_cristatus),(Trachypithecus_francoisi,Trachypithecus_obscurus))),((Semnopithecus_entellus,Rhinopithecus_avunculus),Presbytis_melalophos)),((Colobus_guereza,Colobus_satanas),Piliocolobus_badius)),Procolobus_verus),Trachypithecus_johnii),((((Cercopithecus_roloway,(Cercopithecus_lhoesti,((Cercopithecus_ascanius_schmidti,(((Cercopithecus_pogonias,(((Cercopithecus_pogonias_grayi,Cercopithecus_pogonias_schwarzianus),Cercopithecus_pogonias_nigripes),(Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans))),(Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis)),(((Cercopithecus_ascanius_whitesidei,((Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi),(((Cercopithecus_erythrotis_camerunensis,((Cercopithecus_erythrogaster,Cercopithecus_erythrogaster_pococki),((Cercopithecus_petaurista_petaurista,Cercopithecus_petaurista_buettikoferi),Cercopithecus_petaurista))),Cercopithecus_ascanius_katangae),Cercopithecus_cephus_cephus))),Cercopithecus_neglectus),(((Cercopithecus_mitis_mitis,(Cercopithecus_mitis_opisthostictus,(((Cercopithecus_kandti,Cercopithecus_mitis),Cercopithecus_doggetti),(Cercopithecus_mitis_heymansi,Cercopithecus_albogularis_francescae)))),((Cercopithecus_mitis_stuhlmanni,Cercopithecus_albogularis_kolbi),(Cercopithecus_nictitans_nictitans,(Cercopithecus_nictitans,Cercopithecus_nictitans_martini)))),(Cercopithecus_albogularis_moloneyi,((Cercopithecus_albogularis,Cercopithecus_albogularis_monoides),(Cercopithecus_albogularis_labiatus,(Cercopithecus_albogularis_erythrarchus,(Cercopithecus_mitis_boutourlinii,Cercopithecus_albogularis_albotorquatus))))))))),(Cercopithecus_mona,Cercopithecus_campbelli)))),((((Cercocebus_agilis,((Cercocebus_chrysogaster,(Cercocebus_torquatus,(Cercocebus_atys,Mandrillus_sphinx))),Mandrillus_leucophaeus)),((Lophocebus_albigena,((Papio_ursinus,(((Papio_papio,Papio_cynocephalus),Papio_kindae),(Papio_hamadryas,Papio_anubis))),Rungwecebus_kipunji)),(Theropithecus_gelada,Lophocebus_aterrimus))),(Macaca_sylvanus,(Erythrocebus_patas,Allenopithecus_nigroviridis))),((((((Macaca_silenus,(Macaca_assamensis,Macaca_thibetana)),(Macaca_fascicularis,Macaca_tonkeana)),(Macaca_nigra,Macaca_nemestrina)),Macaca_arctoides),Macaca_mulatta),Macaca_fuscata))),Miopithecus_talapoin),(((Cercopithecus_aethiops,(Chlorocebus_tantalus,((Chlorocebus_pygerythrus,((Chlorocebus_aethiops,Cercopithecus_hamlyni),Cercopithecus_dryas)),(Chlorocebus_sabaeus,Chlorocebus_cynosuros)))),Cercopithecus_solatus),(Miopithecus_ogouensis,Cercopithecus_diana)))),((Alouatta_caraya,((((((Pithecia_pithecia,(Callimico_goeldii,Leontopithecus_rosalia)),((Callicebus_donacophilus,Cacajao_calvus),(Chiropotes_albinasus,(Brachyteles_arachnoides,Chiropotes_israelita)))),Ateles_paniscus),Ateles_belzebuth),((((((Aotus_trivirgatus,((Aotus_azarae_azarai,(Aotus_azarai,Aotus_lemurinus)),Aotus_nancymaae)),Aotus_azarae),(((Saimiri_boliviensis,(Saimiri_oerstedii,Saimiri_sciureus)),Saimiri_sciureus_macrodon),Saimiri_oerstedii_citrinellus)),((Cebus_albifrons,(Sapajus_xanthosternos,Cebus_apella)),(Callicebus_cupreus,Callicebus_lugens))),Lagothrix_lagotricha),Ateles_geoffroyi)),(Saguinus_oedipus,(Callithrix_jacchus,Callithrix_pygmaea)))),(((Galago_senegalensis,(((Galagoides_demidoff,Otolemur_crassicaudatus),Otolemur_garnettii),Loris_tardigradus)),Tarsius_bancanus),((((((Eulemur_mongoz,Megaladapis_edwardsi),(Eulemur_rubriventer,(Eulemur_macaco,(Eulemur_fulvus,(Cheirogaleus_medius,(Prolemur_simus,((Lemur_catta,(Varecia_rubra,Varecia_variegata)),Hapalemur_griseus))))))),(Eulemur_rufus,Palaeopropithecus_ingens)),((Propithecus_verreauxi,((Lepilemur_hubbardorum,Lepilemur_ruficaudatus),(Propithecus_coquereli,Indri_indri))),Avahi_laniger)),(((Perodicticus_potto,Perodicticus_potto_edwarsi),((Nycticebus_pygmaeus,(Nycticebus_coucang,Nycticebus_bengalensis)),Loris_lydekkerianus)),((((Tarsius_dentatus,Tarsius_lariang),Tarsius_wallacei),Tarsius_syrichta),Galago_moholi))),Daubentonia_madagascariensis))))),Gorilla_gorilla_gorilla))),Homo_sapiens); +((Pan_troglodytes_ellioti,((Homo_sapiens_ssp_Denisova,((((((Presbytis_melalophos,((Rhinopithecus_avunculus,(Trachypithecus_johnii,((Trachypithecus_cristatus,Trachypithecus_pileatus),(Trachypithecus_francoisi,Trachypithecus_obscurus)))),(Rhinopithecus_roxellana,((Rhinopithecus_brelichi,Rhinopithecus_bieti_2_RL2012),((Semnopithecus_entellus,(Simias_concolor,Nasalis_larvatus)),(Pygathrix_nigripes,Pygathrix_nemaeus)))))),Piliocolobus_badius),(Colobus_guereza,Colobus_satanas)),Procolobus_verus),(Miopithecus_ogouensis,(((Cercopithecus_diana,(Cercopithecus_roloway,(((((Cercopithecus_cephus,((Cercopithecus_albogularis_moloneyi,Cercopithecus_albogularis_albotorquatus),(((((((Cercopithecus_mitis_heymansi,Cercopithecus_albogularis_francescae),(Cercopithecus_mitis_stuhlmanni,Cercopithecus_albogularis_kolbi)),Cercopithecus_doggetti),Cercopithecus_kandti),Cercopithecus_mitis),(((Cercopithecus_nictitans_nictitans,Cercopithecus_nictitans),Cercopithecus_mitis_mitis),Cercopithecus_mitis_opisthostictus)),((Cercopithecus_mitis_boutourlinii,Cercopithecus_albogularis_erythrarchus),(Cercopithecus_albogularis_monoides,Cercopithecus_albogularis_labiatus))))),(Cercopithecus_cephus_ngottoensis,(Cercopithecus_neglectus,((((Cercopithecus_erythrotis_camerunensis,Cercopithecus_ascanius_katangae),((Cercopithecus_erythrogaster_pococki,Cercopithecus_erythrogaster),(Cercopithecus_petaurista_petaurista,Cercopithecus_petaurista_buettikoferi))),(Cercopithecus_petaurista,Cercopithecus_cephus_cephus)),(Cercopithecus_ascanius_schmidti,Cercopithecus_ascanius_whitesidei))))),Cercopithecus_albogularis),(Cercopithecus_lhoesti,(Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi))),(((((Cercopithecus_pogonias_schwarzianus,((Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans),Cercopithecus_pogonias_nigripes)),Cercopithecus_pogonias_grayi),Cercopithecus_pogonias),Cercopithecus_nictitans_martini),(Cercopithecus_mona,Cercopithecus_campbelli))))),((((Macaca_silenus,(Macaca_assamensis,Macaca_thibetana)),((Macaca_fuscata,Macaca_nigra),Macaca_nemestrina)),((Macaca_fascicularis,Macaca_tonkeana),Macaca_arctoides)),(Macaca_mulatta,((Erythrocebus_patas,(Macaca_sylvanus,Allenopithecus_nigroviridis)),(((Cercocebus_chrysogaster,(Mandrillus_leucophaeus,(Cercocebus_torquatus,(Cercocebus_atys,Mandrillus_sphinx)))),Cercocebus_agilis),(((Papio_ursinus,((Papio_cynocephalus,Papio_kindae),(Papio_papio,(Papio_hamadryas,Papio_anubis)))),Rungwecebus_kipunji),(Lophocebus_albigena,(Theropithecus_gelada,Lophocebus_aterrimus)))))))),(Miopithecus_talapoin,((Chlorocebus_tantalus,(((Chlorocebus_aethiops,(Chlorocebus_cynosuros,Cercopithecus_hamlyni)),Cercopithecus_dryas),((Cercopithecus_aethiops,Chlorocebus_sabaeus),Chlorocebus_pygerythrus))),Cercopithecus_solatus))))),(((Alouatta_caraya,(((Aotus_trivirgatus,((Ateles_belzebuth,(((Callimico_goeldii,Leontopithecus_rosalia),(Lagothrix_lagotricha,((Callicebus_cupreus,Callicebus_lugens),(((Aotus_nancymaae,((Saimiri_sciureus_macrodon,(Saimiri_boliviensis,(Saimiri_oerstedii,Saimiri_sciureus))),Saimiri_oerstedii_citrinellus)),(Cacajao_calvus,((((Brachyteles_arachnoides,Chiropotes_israelita),Callicebus_donacophilus),Chiropotes_albinasus),Ateles_geoffroyi))),(Cebus_albifrons,(Sapajus_xanthosternos,Cebus_apella)))))),(((Aotus_azarai,Aotus_lemurinus),Aotus_azarae),Aotus_azarae_azarai))),Pithecia_pithecia)),Ateles_paniscus),(Callithrix_jacchus,Callithrix_pygmaea))),Saguinus_oedipus),(((((((Propithecus_coquereli,Propithecus_verreauxi),(Indri_indri,Avahi_laniger)),((Megaladapis_edwardsi,(Eulemur_rufus,(((((Lemur_catta,(Varecia_rubra,Varecia_variegata)),Hapalemur_griseus),(Eulemur_macaco,(((Eulemur_rubriventer,(Lepilemur_hubbardorum,Lepilemur_ruficaudatus)),Cheirogaleus_medius),Eulemur_mongoz))),Prolemur_simus),Eulemur_fulvus))),Palaeopropithecus_ingens)),Daubentonia_madagascariensis),((Perodicticus_potto,Perodicticus_potto_edwarsi),(((Nycticebus_pygmaeus,(Nycticebus_coucang,Nycticebus_bengalensis)),Loris_lydekkerianus),(Galago_senegalensis,Galago_moholi)))),((Tarsius_lariang,(Tarsius_wallacei,Tarsius_dentatus)),Tarsius_syrichta)),(((Galagoides_demidoff,(Otolemur_crassicaudatus,Otolemur_garnettii)),Loris_tardigradus),Tarsius_bancanus))))),Gorilla_gorilla_gorilla)),((Gorilla_gorilla,((((((Symphalangus_syndactylus,Hylobates_lar),Hylobates_agilis),(Pongo_pygmaeus,Pongo_abelii)),(Hylobates_moloch,Nomascus_leucogenys)),(Pan_paniscus,Homo_heidelbergensis)),Pan_troglodytes)),Pan_troglodytes_troglodytes),Homo_sapiens); +(((Pongo_pygmaeus,Pongo_abelii),(((Symphalangus_syndactylus,(Hylobates_lar,Hylobates_moloch)),Nomascus_leucogenys),Hylobates_agilis)),(((Homo_sapiens_ssp_Denisova,((((Presbytis_melalophos,(Procolobus_verus,(Rhinopithecus_avunculus,(((Trachypithecus_johnii,(Rhinopithecus_brelichi,((Pygathrix_nemaeus,Trachypithecus_pileatus),(Trachypithecus_cristatus,(Nasalis_larvatus,(Simias_concolor,(((Rhinopithecus_bieti_2_RL2012,Trachypithecus_obscurus),(Rhinopithecus_roxellana,Trachypithecus_francoisi)),Pygathrix_nigripes))))))),(Colobus_guereza,Colobus_satanas)),Piliocolobus_badius)))),Semnopithecus_entellus),(Miopithecus_ogouensis,((Miopithecus_talapoin,((((Cercopithecus_albogularis_albotorquatus,(Cercopithecus_albogularis,(Cercopithecus_albogularis_monoides,((Cercopithecus_albogularis_erythrarchus,Cercopithecus_mitis_boutourlinii),Cercopithecus_albogularis_labiatus)))),((((((Cercopithecus_aethiops,Cercopithecus_solatus),Chlorocebus_sabaeus),Cercopithecus_dryas),((Chlorocebus_tantalus,Chlorocebus_pygerythrus),Chlorocebus_aethiops)),(Chlorocebus_cynosuros,Cercopithecus_hamlyni)),((((Cercopithecus_kandti,Cercopithecus_doggetti),((Cercopithecus_nictitans_nictitans,Cercopithecus_albogularis_francescae),((Cercopithecus_mitis_heymansi,(Cercopithecus_mitis_mitis,Cercopithecus_mitis_opisthostictus)),(Cercopithecus_mitis_stuhlmanni,Cercopithecus_albogularis_kolbi)))),Cercopithecus_mitis),Cercopithecus_nictitans))),Cercopithecus_albogularis_moloneyi),((Cercopithecus_cephus,(((Cercopithecus_erythrotis_camerunensis,Cercopithecus_ascanius_katangae),((Cercopithecus_cephus_cephus,Cercopithecus_petaurista),((Cercopithecus_erythrogaster_pococki,Cercopithecus_erythrogaster),(Cercopithecus_petaurista_petaurista,Cercopithecus_petaurista_buettikoferi)))),(Cercopithecus_neglectus,(Cercopithecus_ascanius_whitesidei,((Cercopithecus_lhoesti,Cercopithecus_preussi_preussi),Cercopithecus_preussi_insularis))))),((Cercopithecus_ascanius_schmidti,Cercopithecus_cephus_ngottoensis),(Cercopithecus_nictitans_martini,(((Cercopithecus_wolfi_pyrogaster,(Cercopithecus_wolfi_elegans,(Cercopithecus_pogonias_nigripes,(Cercopithecus_pogonias_grayi,Cercopithecus_pogonias_schwarzianus)))),Cercopithecus_pogonias),(Cercopithecus_mona,Cercopithecus_campbelli))))))),((Cercopithecus_roloway,(((((Macaca_nemestrina,Macaca_mulatta),((Macaca_nigra,((Macaca_silenus,Macaca_tonkeana),Macaca_fascicularis)),(Macaca_sylvanus,(Macaca_assamensis,Macaca_thibetana)))),Macaca_arctoides),Macaca_fuscata),(((((Lophocebus_albigena,Lophocebus_aterrimus),Theropithecus_gelada),((((Papio_cynocephalus,Papio_kindae),Rungwecebus_kipunji),Papio_ursinus),(Papio_papio,(Papio_hamadryas,Papio_anubis)))),Erythrocebus_patas),((((Cercocebus_torquatus,(Cercocebus_atys,Mandrillus_sphinx)),(Cercocebus_agilis,Cercocebus_chrysogaster)),Mandrillus_leucophaeus),Allenopithecus_nigroviridis)))),Cercopithecus_diana)))),((((Aotus_trivirgatus,(Aotus_nancymaae,(Aotus_azarae_azarai,(Aotus_lemurinus,Aotus_azarai)))),Aotus_azarae),(((Cebus_apella,Callithrix_pygmaea),((Saguinus_oedipus,(Brachyteles_arachnoides,((Ateles_paniscus,Ateles_geoffroyi),Ateles_belzebuth))),(Callicebus_donacophilus,Callithrix_jacchus))),((((Callicebus_cupreus,Callicebus_lugens),(((Saimiri_oerstedii_citrinellus,((Saimiri_sciureus,Saimiri_sciureus_macrodon),(Saimiri_boliviensis,Saimiri_oerstedii))),Lagothrix_lagotricha),((Cacajao_calvus,(Chiropotes_israelita,Chiropotes_albinasus)),(Cebus_albifrons,Sapajus_xanthosternos)))),(Alouatta_caraya,(Callimico_goeldii,Leontopithecus_rosalia))),Pithecia_pithecia))),((((((((Propithecus_coquereli,(Indri_indri,(Eulemur_rufus,((Prolemur_simus,((((Lemur_catta,(Varecia_rubra,Varecia_variegata)),(Nycticebus_pygmaeus,Hapalemur_griseus)),((Eulemur_fulvus,Eulemur_rubriventer),Cheirogaleus_medius)),Eulemur_macaco)),Eulemur_mongoz)))),(Lepilemur_hubbardorum,Lepilemur_ruficaudatus)),(Palaeopropithecus_ingens,Propithecus_verreauxi)),(Megaladapis_edwardsi,Avahi_laniger)),Daubentonia_madagascariensis),(((Nycticebus_coucang,Nycticebus_bengalensis),Loris_lydekkerianus),(Perodicticus_potto_edwarsi,((Galago_senegalensis,Galago_moholi),Perodicticus_potto)))),((Tarsius_lariang,(Tarsius_wallacei,Tarsius_dentatus)),Tarsius_syrichta)),(Tarsius_bancanus,((Galagoides_demidoff,(Otolemur_crassicaudatus,Otolemur_garnettii)),Loris_tardigradus)))))),((Gorilla_gorilla,Homo_heidelbergensis),Gorilla_gorilla_gorilla)),(Pan_troglodytes_troglodytes,(Pan_troglodytes_ellioti,(Pan_troglodytes,Pan_paniscus)))),Homo_sapiens); +(Homo_sapiens_ssp_Denisova,(((Homo_heidelbergensis,((((((Piliocolobus_badius,(Colobus_guereza,Colobus_satanas)),Procolobus_verus),(Semnopithecus_entellus,(((Rhinopithecus_roxellana,((((Pygathrix_nemaeus,Pygathrix_nigripes),(Simias_concolor,Nasalis_larvatus)),Rhinopithecus_bieti_2_RL2012),Rhinopithecus_brelichi)),(((Trachypithecus_francoisi,Trachypithecus_obscurus),Trachypithecus_cristatus),Trachypithecus_pileatus)),(Trachypithecus_johnii,(Rhinopithecus_avunculus,Presbytis_melalophos))))),(((((((((Lophocebus_albigena,Lophocebus_aterrimus),((Theropithecus_gelada,Rungwecebus_kipunji),((((Papio_papio,Papio_hamadryas),(Papio_cynocephalus,Papio_ursinus)),Papio_kindae),Papio_anubis))),Cercocebus_torquatus),((Cercocebus_agilis,(Cercocebus_atys,(Cercocebus_chrysogaster,Mandrillus_leucophaeus))),(Macaca_fascicularis,(((Macaca_assamensis,Macaca_thibetana),(Macaca_arctoides,(Macaca_nemestrina,((Macaca_mulatta,Macaca_fuscata),(Macaca_sylvanus,Macaca_nigra))))),(Macaca_silenus,Macaca_tonkeana))))),Allenopithecus_nigroviridis),(Erythrocebus_patas,Mandrillus_sphinx)),((Cercopithecus_neglectus,Cercopithecus_aethiops),(Chlorocebus_sabaeus,((((Chlorocebus_cynosuros,(Chlorocebus_aethiops,Cercopithecus_dryas)),(Chlorocebus_tantalus,Chlorocebus_pygerythrus)),Cercopithecus_roloway),((((Cercopithecus_campbelli,((Cercopithecus_nictitans,Cercopithecus_mona),(((((Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans),Cercopithecus_nictitans_martini),Cercopithecus_pogonias_nigripes),(Cercopithecus_pogonias_grayi,(Cercopithecus_hamlyni,Cercopithecus_pogonias_schwarzianus))),Cercopithecus_pogonias))),Cercopithecus_diana),(Cercopithecus_nictitans_nictitans,Miopithecus_ogouensis)),(((Cercopithecus_ascanius_schmidti,((Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis),(((((Cercopithecus_albogularis_monoides,Cercopithecus_albogularis),(Cercopithecus_albogularis_albotorquatus,((Cercopithecus_mitis_boutourlinii,Cercopithecus_albogularis_erythrarchus),Cercopithecus_albogularis_labiatus))),((((Cercopithecus_mitis_stuhlmanni,Cercopithecus_albogularis_francescae),(Cercopithecus_doggetti,Cercopithecus_kandti)),Cercopithecus_mitis),(Cercopithecus_albogularis_kolbi,Cercopithecus_mitis_heymansi))),Cercopithecus_mitis_mitis),Cercopithecus_mitis_opisthostictus))),(((Cercopithecus_lhoesti,(Cercopithecus_preussi_preussi,Cercopithecus_preussi_insularis)),(Cercopithecus_erythrotis_camerunensis,(Cercopithecus_ascanius_katangae,(((Cercopithecus_petaurista_petaurista,(Cercopithecus_erythrogaster_pococki,Cercopithecus_petaurista_buettikoferi)),(Cercopithecus_petaurista,Cercopithecus_erythrogaster)),Cercopithecus_cephus_cephus)))),Cercopithecus_ascanius_whitesidei)),Cercopithecus_albogularis_moloneyi)))))),Miopithecus_talapoin),Cercopithecus_solatus)),(((Callimico_goeldii,(((Pithecia_pithecia,((Aotus_nancymaae,Leontopithecus_rosalia),(Callithrix_pygmaea,Saguinus_oedipus))),((((Chiropotes_israelita,(Brachyteles_arachnoides,Chiropotes_albinasus)),(Cacajao_calvus,Ateles_belzebuth)),Ateles_paniscus),((Ateles_geoffroyi,(Callicebus_donacophilus,((Cebus_albifrons,(Sapajus_xanthosternos,Cebus_apella)),(((((Saimiri_boliviensis,(Saimiri_sciureus,Saimiri_oerstedii)),Saimiri_sciureus_macrodon),Saimiri_oerstedii_citrinellus),(Aotus_trivirgatus,(Aotus_azarae,(Aotus_azarae_azarai,(Aotus_lemurinus,Aotus_azarai))))),(Callicebus_cupreus,Callicebus_lugens))))),Lagothrix_lagotricha))),Callithrix_jacchus)),Alouatta_caraya),((Tarsius_bancanus,((Loris_tardigradus,Galagoides_demidoff),(Otolemur_garnettii,Otolemur_crassicaudatus))),(((Tarsius_dentatus,(Tarsius_lariang,Tarsius_wallacei)),Tarsius_syrichta),(((Eulemur_rubriventer,Daubentonia_madagascariensis),((Perodicticus_potto_edwarsi,((Perodicticus_potto,(Nycticebus_coucang,Nycticebus_bengalensis)),(Propithecus_verreauxi,Loris_lydekkerianus))),Galago_moholi)),(Eulemur_macaco,((Eulemur_fulvus,(((Galago_senegalensis,(Megaladapis_edwardsi,Avahi_laniger)),(Eulemur_mongoz,(((Nycticebus_pygmaeus,(Varecia_rubra,Varecia_variegata)),(Cheirogaleus_medius,(Lepilemur_hubbardorum,Lepilemur_ruficaudatus))),((Eulemur_rufus,((Hapalemur_griseus,Prolemur_simus),Lemur_catta)),Indri_indri)))),Propithecus_coquereli)),Palaeopropithecus_ingens))))))),(Gorilla_gorilla_gorilla,(Gorilla_gorilla,(((Pongo_abelii,((Nomascus_leucogenys,(Hylobates_moloch,Symphalangus_syndactylus)),Hylobates_agilis)),Hylobates_lar),Pongo_pygmaeus))))),Pan_troglodytes_ellioti),((Pan_troglodytes,Pan_paniscus),Pan_troglodytes_troglodytes)),Homo_sapiens); +((Homo_heidelbergensis,((((Pongo_abelii,Pongo_pygmaeus),((((((Piliocolobus_badius,(Colobus_guereza,Colobus_satanas)),Procolobus_verus),(((Semnopithecus_entellus,Presbytis_melalophos),Rhinopithecus_avunculus),((((Pygathrix_nemaeus,Pygathrix_nigripes),(Simias_concolor,Nasalis_larvatus)),((Rhinopithecus_brelichi,Rhinopithecus_bieti_2_RL2012),Rhinopithecus_roxellana)),(((Trachypithecus_cristatus,(Trachypithecus_johnii,Trachypithecus_francoisi)),Trachypithecus_obscurus),Trachypithecus_pileatus)))),((((((Lophocebus_albigena,Lophocebus_aterrimus),Theropithecus_gelada),((((Papio_anubis,Papio_hamadryas),Papio_ursinus),((Papio_cynocephalus,Papio_papio),Papio_kindae)),Rungwecebus_kipunji)),((((Mandrillus_leucophaeus,Cercocebus_chrysogaster),Cercocebus_agilis),(Mandrillus_sphinx,(Cercocebus_torquatus,Cercocebus_atys))),(Macaca_fascicularis,(((Macaca_assamensis,Macaca_thibetana),(Macaca_arctoides,((Macaca_nemestrina,((Macaca_mulatta,Macaca_fuscata),Macaca_nigra)),Macaca_sylvanus))),(Macaca_silenus,Macaca_tonkeana))))),Allenopithecus_nigroviridis),((Cercopithecus_solatus,((Cercopithecus_aethiops,((Cercopithecus_dryas,(Chlorocebus_pygerythrus,(Chlorocebus_aethiops,(Chlorocebus_tantalus,Chlorocebus_cynosuros)))),Chlorocebus_sabaeus)),(((((Cercopithecus_nictitans_nictitans,(Cercopithecus_albogularis_moloneyi,(((((Cercopithecus_albogularis_francescae,((Cercopithecus_mitis_stuhlmanni,Cercopithecus_kandti),Cercopithecus_doggetti)),Cercopithecus_mitis),(Cercopithecus_albogularis_kolbi,Cercopithecus_mitis_heymansi)),((Cercopithecus_albogularis_albotorquatus,((Cercopithecus_mitis_boutourlinii,Cercopithecus_albogularis_labiatus),Cercopithecus_albogularis_erythrarchus)),(Cercopithecus_albogularis_monoides,Cercopithecus_albogularis))),(Cercopithecus_mitis_mitis,Cercopithecus_mitis_opisthostictus)))),((Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis),((Cercopithecus_lhoesti,(Cercopithecus_preussi_preussi,Cercopithecus_preussi_insularis)),(Cercopithecus_ascanius_whitesidei,((Cercopithecus_cephus_cephus,Cercopithecus_ascanius_katangae),(((Cercopithecus_erythrogaster_pococki,Cercopithecus_petaurista_buettikoferi),((Cercopithecus_erythrogaster,Cercopithecus_petaurista_petaurista),Cercopithecus_petaurista)),Cercopithecus_erythrotis_camerunensis)))))),Cercopithecus_ascanius_schmidti),Cercopithecus_neglectus),(((Cercopithecus_campbelli,(Cercopithecus_mona,(Miopithecus_ogouensis,(Cercopithecus_pogonias,((Cercopithecus_nictitans_martini,(Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans)),((Cercopithecus_pogonias_nigripes,Cercopithecus_pogonias_grayi),(Cercopithecus_hamlyni,Cercopithecus_pogonias_schwarzianus))))))),(Cercopithecus_nictitans,(Erythrocebus_patas,Cercopithecus_diana))),Cercopithecus_roloway)))),Miopithecus_talapoin))),((((((((Saimiri_oerstedii_citrinellus,((Saimiri_sciureus,(Saimiri_oerstedii,Saimiri_boliviensis)),Saimiri_sciureus_macrodon)),(Lagothrix_lagotricha,(Cacajao_calvus,(Pithecia_pithecia,(Chiropotes_israelita,Chiropotes_albinasus))))),((Callicebus_lugens,((Callithrix_jacchus,((Ateles_belzebuth,Ateles_geoffroyi),Ateles_paniscus)),(Callicebus_cupreus,(Brachyteles_arachnoides,Callicebus_donacophilus)))),(Cebus_albifrons,(Sapajus_xanthosternos,Cebus_apella)))),(Aotus_azarai,((Aotus_nancymaae,((Aotus_azarae_azarai,Aotus_trivirgatus),Aotus_azarae)),Aotus_lemurinus))),(Alouatta_caraya,(Callimico_goeldii,Leontopithecus_rosalia))),Callithrix_pygmaea),Saguinus_oedipus),(((((Propithecus_coquereli,(Avahi_laniger,((Lepilemur_hubbardorum,Lepilemur_ruficaudatus),Indri_indri))),Propithecus_verreauxi),(Palaeopropithecus_ingens,(((Megaladapis_edwardsi,(Varecia_rubra,((Eulemur_fulvus,((Eulemur_macaco,(Cheirogaleus_medius,Eulemur_rubriventer)),Eulemur_mongoz)),Varecia_variegata))),(Prolemur_simus,((Hapalemur_griseus,Nycticebus_pygmaeus),Eulemur_rufus))),Lemur_catta))),((Tarsius_wallacei,(Tarsius_dentatus,Tarsius_lariang)),Tarsius_syrichta)),(((((Perodicticus_potto,Perodicticus_potto_edwarsi),Loris_lydekkerianus),(Nycticebus_coucang,Nycticebus_bengalensis)),Galago_moholi),(Galago_senegalensis,((((Galagoides_demidoff,(Otolemur_crassicaudatus,Otolemur_garnettii)),Loris_tardigradus),Tarsius_bancanus),Daubentonia_madagascariensis)))))),(Gorilla_gorilla,Gorilla_gorilla_gorilla))),((Symphalangus_syndactylus,Hylobates_agilis),((Hylobates_lar,Hylobates_moloch),Nomascus_leucogenys))),Homo_sapiens_ssp_Denisova)),(Pan_troglodytes_ellioti,(Pan_troglodytes,(Pan_troglodytes_troglodytes,Pan_paniscus))),Homo_sapiens); +(((((((Piliocolobus_badius,(Colobus_guereza,Colobus_satanas)),Procolobus_verus),(((((((Rhinopithecus_avunculus,(((Rhinopithecus_brelichi,(((Rhinopithecus_bieti_2_RL2012,Pygathrix_nemaeus),Simias_concolor),Pygathrix_nigripes)),(Nasalis_larvatus,Rhinopithecus_roxellana)),Trachypithecus_francoisi)),Presbytis_melalophos),Semnopithecus_entellus),Trachypithecus_obscurus),Trachypithecus_cristatus),Trachypithecus_johnii),Trachypithecus_pileatus)),(((((Miopithecus_ogouensis,((Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans),(Cercopithecus_pogonias,((Cercopithecus_pogonias_grayi,Cercopithecus_pogonias_schwarzianus),Cercopithecus_pogonias_nigripes)))),Cercopithecus_nictitans_martini),((((Cercopithecus_ascanius_schmidti,(((Cercopithecus_lhoesti,(Cercopithecus_preussi_preussi,Cercopithecus_preussi_insularis)),(Cercopithecus_ascanius_katangae,Cercopithecus_neglectus)),((Cercopithecus_erythrotis_camerunensis,(Cercopithecus_ascanius_whitesidei,(Cercopithecus_petaurista,(Cercopithecus_erythrogaster,((Cercopithecus_erythrogaster_pococki,Cercopithecus_petaurista_buettikoferi),Cercopithecus_petaurista_petaurista))))),Cercopithecus_cephus_cephus))),((Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis),(Cercopithecus_albogularis_moloneyi,((((Cercopithecus_albogularis_monoides,Cercopithecus_albogularis),(((Cercopithecus_albogularis_albotorquatus,Cercopithecus_albogularis_labiatus),Cercopithecus_albogularis_erythrarchus),Cercopithecus_mitis_boutourlinii)),((Cercopithecus_mitis_opisthostictus,Cercopithecus_mitis_mitis),((Cercopithecus_mitis,((Cercopithecus_kandti,Cercopithecus_mitis_stuhlmanni),(Cercopithecus_doggetti,Cercopithecus_albogularis_francescae))),(Cercopithecus_albogularis_kolbi,Cercopithecus_mitis_heymansi)))),(Cercopithecus_nictitans,Cercopithecus_nictitans_nictitans))))),Cercopithecus_roloway),((Cercopithecus_campbelli,Cercopithecus_mona),(Erythrocebus_patas,Cercopithecus_diana)))),((((((Papio_anubis,((((Lophocebus_albigena,Lophocebus_aterrimus),(Papio_papio,(Papio_kindae,Papio_cynocephalus))),Papio_ursinus),Theropithecus_gelada)),Rungwecebus_kipunji),Papio_hamadryas),((((Mandrillus_leucophaeus,Cercocebus_chrysogaster),Cercocebus_agilis),((Mandrillus_sphinx,Cercocebus_atys),Cercocebus_torquatus)),((Macaca_fascicularis,(((Macaca_assamensis,Macaca_thibetana),(Macaca_nemestrina,(Macaca_sylvanus,Macaca_nigra))),(Macaca_silenus,Macaca_tonkeana))),((Macaca_mulatta,Macaca_fuscata),Macaca_arctoides)))),Allenopithecus_nigroviridis),(((((Cercopithecus_hamlyni,Chlorocebus_aethiops),Chlorocebus_pygerythrus),((Chlorocebus_tantalus,Cercopithecus_solatus),Chlorocebus_cynosuros)),(Chlorocebus_sabaeus,Cercopithecus_aethiops)),Cercopithecus_dryas))),Miopithecus_talapoin)),((((((((((Aotus_azarai,Aotus_lemurinus),((((Saimiri_oerstedii,Saimiri_boliviensis),Saimiri_sciureus),Saimiri_sciureus_macrodon),Saimiri_oerstedii_citrinellus)),Ateles_belzebuth),Aotus_trivirgatus),Aotus_azarae),(((Callimico_goeldii,Leontopithecus_rosalia),((Callicebus_donacophilus,(Callicebus_cupreus,Callicebus_lugens)),Pithecia_pithecia)),((Sapajus_xanthosternos,Cebus_apella),Cebus_albifrons))),((Ateles_geoffroyi,(Callithrix_jacchus,((Lagothrix_lagotricha,Cacajao_calvus),((Chiropotes_israelita,Aotus_azarae_azarai),(Brachyteles_arachnoides,Chiropotes_albinasus))))),Ateles_paniscus)),((Aotus_nancymaae,Callithrix_pygmaea),Saguinus_oedipus)),Alouatta_caraya),(Tarsius_bancanus,((Tarsius_syrichta,(Tarsius_wallacei,(Tarsius_dentatus,Tarsius_lariang))),((((((Otolemur_garnettii,Otolemur_crassicaudatus),((Nycticebus_coucang,Nycticebus_bengalensis),(Loris_lydekkerianus,(Loris_tardigradus,Galagoides_demidoff)))),(Perodicticus_potto,Perodicticus_potto_edwarsi)),Galago_moholi),((Propithecus_coquereli,(((Avahi_laniger,((Lepilemur_hubbardorum,Lepilemur_ruficaudatus),Indri_indri)),(Eulemur_rufus,Palaeopropithecus_ingens)),Propithecus_verreauxi)),(Prolemur_simus,((((Hapalemur_griseus,Nycticebus_pygmaeus),(Varecia_rubra,Varecia_variegata)),Lemur_catta),(((Eulemur_macaco,(Eulemur_rubriventer,Cheirogaleus_medius)),Eulemur_mongoz),Eulemur_fulvus))))),(Megaladapis_edwardsi,(Galago_senegalensis,Daubentonia_madagascariensis))))))),(((Hylobates_agilis,(Symphalangus_syndactylus,Nomascus_leucogenys)),Hylobates_moloch),(Pongo_pygmaeus,(Pongo_abelii,Hylobates_lar)))),(((Pan_troglodytes_troglodytes,(Pan_paniscus,((Homo_sapiens_ssp_Denisova,(Pan_troglodytes_ellioti,Homo_heidelbergensis)),Pan_troglodytes))),Gorilla_gorilla),Gorilla_gorilla_gorilla),Homo_sapiens); +((Pan_troglodytes_ellioti,((Pan_paniscus,Pan_troglodytes_troglodytes),Pan_troglodytes)),(((((((Symphalangus_syndactylus,Hylobates_agilis),Nomascus_leucogenys),(Hylobates_moloch,Hylobates_lar)),(Pongo_pygmaeus,Pongo_abelii)),(Gorilla_gorilla_gorilla,(((((Piliocolobus_badius,(Colobus_guereza,Colobus_satanas)),Procolobus_verus),(Trachypithecus_johnii,((((Trachypithecus_cristatus,(Trachypithecus_obscurus,(Semnopithecus_entellus,Trachypithecus_francoisi))),Trachypithecus_pileatus),((((((Simias_concolor,Nasalis_larvatus),Pygathrix_nigripes),Pygathrix_nemaeus),Rhinopithecus_brelichi),Rhinopithecus_bieti_2_RL2012),Rhinopithecus_roxellana)),(Rhinopithecus_avunculus,Presbytis_melalophos)))),((((Cercopithecus_pogonias,((((Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans),Cercopithecus_nictitans_martini),Cercopithecus_pogonias_schwarzianus),(Cercopithecus_pogonias_grayi,Cercopithecus_pogonias_nigripes))),((((((((Cercopithecus_lhoesti,(Cercopithecus_preussi_preussi,Cercopithecus_preussi_insularis)),(Cercopithecus_ascanius_katangae,Cercopithecus_erythrotis_camerunensis)),(Cercopithecus_petaurista,(Cercopithecus_erythrogaster,((Cercopithecus_erythrogaster_pococki,Cercopithecus_petaurista_buettikoferi),Cercopithecus_petaurista_petaurista)))),Cercopithecus_cephus_cephus),(((Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis),Cercopithecus_neglectus),(Cercopithecus_ascanius_schmidti,Cercopithecus_ascanius_whitesidei))),(((((Erythrocebus_patas,Cercopithecus_diana),(Cercopithecus_campbelli,Cercopithecus_mona)),Cercopithecus_roloway),(((Cercopithecus_mitis_stuhlmanni,(((Cercopithecus_doggetti,Cercopithecus_albogularis_francescae),Cercopithecus_mitis),Cercopithecus_kandti)),(((Cercopithecus_mitis_mitis,(Cercopithecus_albogularis_kolbi,Cercopithecus_mitis_heymansi)),Cercopithecus_mitis_opisthostictus),((Cercopithecus_albogularis_monoides,Cercopithecus_albogularis),(Cercopithecus_albogularis_labiatus,(Cercopithecus_mitis_boutourlinii,Cercopithecus_albogularis_erythrarchus))))),(Cercopithecus_nictitans,Cercopithecus_nictitans_nictitans))),(Cercopithecus_albogularis_moloneyi,Cercopithecus_albogularis_albotorquatus))),(Chlorocebus_sabaeus,Cercopithecus_aethiops)),((Chlorocebus_tantalus,(Chlorocebus_aethiops,(Chlorocebus_pygerythrus,(Cercopithecus_dryas,Cercopithecus_solatus)))),(((((((((Papio_papio,(Papio_anubis,Papio_hamadryas)),(Papio_kindae,(Papio_ursinus,Papio_cynocephalus))),Rungwecebus_kipunji),(((((Cercocebus_atys,Cercocebus_torquatus),Mandrillus_sphinx),Cercocebus_agilis),Mandrillus_leucophaeus),Cercocebus_chrysogaster)),Theropithecus_gelada),(Lophocebus_albigena,Lophocebus_aterrimus)),((Macaca_fascicularis,(((Macaca_silenus,(Macaca_assamensis,Macaca_thibetana)),(Macaca_nemestrina,(Macaca_sylvanus,Macaca_nigra))),Macaca_tonkeana)),((Macaca_mulatta,Macaca_fuscata),Macaca_arctoides))),Allenopithecus_nigroviridis),(Cercopithecus_hamlyni,Chlorocebus_cynosuros))))),Miopithecus_talapoin),Miopithecus_ogouensis)),((((((Saimiri_sciureus_macrodon,Saimiri_oerstedii_citrinellus),((Saimiri_oerstedii,Saimiri_boliviensis),Saimiri_sciureus)),((Leontopithecus_rosalia,((Aotus_nancymaae,Callithrix_pygmaea),Saguinus_oedipus)),((Lagothrix_lagotricha,(((((Sapajus_xanthosternos,Cebus_apella),Cebus_albifrons),((Pithecia_pithecia,((Callicebus_cupreus,((Callimico_goeldii,Callicebus_donacophilus),((Ateles_geoffroyi,Ateles_paniscus),(Ateles_belzebuth,Callithrix_jacchus)))),Callicebus_lugens)),(Aotus_azarai,Aotus_lemurinus))),Aotus_azarae),Aotus_azarae_azarai)),(Chiropotes_israelita,(Cacajao_calvus,Aotus_trivirgatus))))),(Brachyteles_arachnoides,Chiropotes_albinasus)),Alouatta_caraya),(Tarsius_bancanus,((Perodicticus_potto_edwarsi,((Daubentonia_madagascariensis,(Perodicticus_potto,(((Nycticebus_coucang,Nycticebus_bengalensis),(Loris_lydekkerianus,Loris_tardigradus)),((((Galago_senegalensis,Otolemur_garnettii),Otolemur_crassicaudatus),Galagoides_demidoff),Galago_moholi)))),((Eulemur_rufus,(((Eulemur_macaco,(((Propithecus_coquereli,(Megaladapis_edwardsi,Cheirogaleus_medius)),Eulemur_rubriventer),(((Varecia_rubra,Varecia_variegata),(Lemur_catta,Prolemur_simus)),(Hapalemur_griseus,Nycticebus_pygmaeus)))),Eulemur_mongoz),Eulemur_fulvus)),(Propithecus_verreauxi,((Avahi_laniger,((Lepilemur_hubbardorum,Lepilemur_ruficaudatus),Indri_indri)),Palaeopropithecus_ingens))))),((Tarsius_lariang,(Tarsius_wallacei,Tarsius_dentatus)),Tarsius_syrichta))))))),Gorilla_gorilla),(Homo_sapiens_ssp_Denisova,Homo_heidelbergensis)),Homo_sapiens); +((Pan_troglodytes_ellioti,Homo_heidelbergensis),(((Pan_troglodytes_troglodytes,Pan_troglodytes),Pan_paniscus),(Homo_sapiens_ssp_Denisova,((Gorilla_gorilla,Gorilla_gorilla_gorilla),((Hylobates_moloch,(Hylobates_lar,((((Aotus_trivirgatus,Aotus_azarae_azarai),(Aotus_lemurinus,(Aotus_azarai,((((((Callicebus_donacophilus,(Ateles_paniscus,(((Lagothrix_lagotricha,((Callithrix_jacchus,Ateles_belzebuth),(Brachyteles_arachnoides,Chiropotes_israelita))),Chiropotes_albinasus),Cacajao_calvus))),(Cebus_albifrons,(Cebus_apella,Sapajus_xanthosternos))),Ateles_geoffroyi),((Callithrix_pygmaea,Saguinus_oedipus),(Aotus_nancymaae,((Saimiri_sciureus_macrodon,(Saimiri_boliviensis,(Saimiri_sciureus,Saimiri_oerstedii))),Saimiri_oerstedii_citrinellus)))),((Alouatta_caraya,(Callimico_goeldii,Leontopithecus_rosalia)),((Callicebus_lugens,Callicebus_cupreus),Pithecia_pithecia))),Aotus_azarae)))),((((Propithecus_verreauxi,(Eulemur_mongoz,Eulemur_rubriventer)),((Lepilemur_hubbardorum,Lepilemur_ruficaudatus),Nycticebus_pygmaeus)),Propithecus_coquereli),(Tarsius_bancanus,(((Tarsius_wallacei,(Tarsius_lariang,Tarsius_dentatus)),Tarsius_syrichta),((((Indri_indri,Avahi_laniger),(((((((((Varecia_variegata,Varecia_rubra),Eulemur_rufus),Prolemur_simus),Hapalemur_griseus),Cheirogaleus_medius),Eulemur_macaco),Eulemur_fulvus),Megaladapis_edwardsi),(Lemur_catta,Palaeopropithecus_ingens))),Daubentonia_madagascariensis),(((Otolemur_crassicaudatus,(Galago_moholi,Galago_senegalensis)),Otolemur_garnettii),((Perodicticus_potto,Perodicticus_potto_edwarsi),((Galagoides_demidoff,(Loris_tardigradus,Loris_lydekkerianus)),(Nycticebus_bengalensis,Nycticebus_coucang))))))))),(((((Mandrillus_sphinx,(Cercocebus_atys,Cercocebus_torquatus)),(((Cercocebus_agilis,Mandrillus_leucophaeus),(((Theropithecus_gelada,Lophocebus_aterrimus),(Rungwecebus_kipunji,((Papio_papio,(Papio_kindae,Papio_cynocephalus)),((Papio_hamadryas,Papio_anubis),Papio_ursinus)))),Lophocebus_albigena)),Cercocebus_chrysogaster)),((Macaca_fascicularis,(((Macaca_nemestrina,(Macaca_nigra,((Macaca_arctoides,(Macaca_mulatta,Macaca_fuscata)),Macaca_sylvanus))),(Macaca_assamensis,Macaca_thibetana)),(Macaca_silenus,Macaca_tonkeana))),(((Cercopithecus_nictitans_martini,Miopithecus_ogouensis),(Cercopithecus_neglectus,(Miopithecus_talapoin,(Chlorocebus_cynosuros,((Cercopithecus_dryas,(Chlorocebus_pygerythrus,((Chlorocebus_sabaeus,Cercopithecus_aethiops),(Cercopithecus_hamlyni,Chlorocebus_aethiops)))),(Chlorocebus_tantalus,Cercopithecus_solatus)))))),((Cercopithecus_diana,(((((Erythrocebus_patas,Cercopithecus_nictitans),Cercopithecus_nictitans_nictitans),((Cercopithecus_mitis,(Cercopithecus_mitis_stuhlmanni,((Cercopithecus_albogularis_francescae,Cercopithecus_mitis_heymansi),(Cercopithecus_doggetti,Cercopithecus_kandti)))),Cercopithecus_albogularis_kolbi)),(Cercopithecus_albogularis_monoides,((((((Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis),Cercopithecus_ascanius_schmidti),(Cercopithecus_albogularis_moloneyi,Cercopithecus_albogularis_albotorquatus)),(Cercopithecus_erythrogaster,((((Cercopithecus_petaurista_petaurista,(Cercopithecus_erythrogaster_pococki,Cercopithecus_petaurista_buettikoferi)),Cercopithecus_cephus_cephus),(Cercopithecus_preussi_insularis,((Cercopithecus_lhoesti,(Cercopithecus_ascanius_katangae,(Cercopithecus_preussi_preussi,Cercopithecus_erythrotis_camerunensis))),Cercopithecus_ascanius_whitesidei))),Cercopithecus_petaurista))),((Cercopithecus_mitis_boutourlinii,Cercopithecus_albogularis_erythrarchus),(Cercopithecus_albogularis_labiatus,(Allenopithecus_nigroviridis,(Cercopithecus_mitis_mitis,Cercopithecus_mitis_opisthostictus))))),(Cercopithecus_roloway,Cercopithecus_albogularis)))),((Cercopithecus_pogonias_nigripes,(Cercopithecus_wolfi_elegans,(Cercopithecus_wolfi_pyrogaster,Cercopithecus_pogonias))),Cercopithecus_pogonias_grayi))),(Cercopithecus_campbelli,Cercopithecus_mona))))),Cercopithecus_pogonias_schwarzianus),(((Colobus_satanas,Colobus_guereza),(Piliocolobus_badius,Procolobus_verus)),((((((Rhinopithecus_brelichi,Rhinopithecus_bieti_2_RL2012),((Pygathrix_nemaeus,Trachypithecus_pileatus),(Trachypithecus_cristatus,((Trachypithecus_obscurus,Trachypithecus_francoisi),(Pygathrix_nigripes,(Nasalis_larvatus,Simias_concolor)))))),Rhinopithecus_roxellana),Trachypithecus_johnii),Rhinopithecus_avunculus),(Semnopithecus_entellus,Presbytis_melalophos))))))),(Hylobates_agilis,(((Pongo_abelii,Pongo_pygmaeus),Nomascus_leucogenys),Symphalangus_syndactylus)))))),Homo_sapiens); +((((Gorilla_gorilla,Gorilla_gorilla_gorilla),((Hylobates_moloch,(((Alouatta_caraya,((((Ateles_geoffroyi,(Callimico_goeldii,((Cacajao_calvus,(Brachyteles_arachnoides,Chiropotes_albinasus)),(Callicebus_donacophilus,(Ateles_paniscus,((Lagothrix_lagotricha,Chiropotes_israelita),Ateles_belzebuth)))))),(((Pithecia_pithecia,(Callicebus_cupreus,Callicebus_lugens)),Callithrix_jacchus),(((Aotus_azarae_azarai,(Aotus_trivirgatus,Aotus_azarae)),(Aotus_azarai,Aotus_lemurinus)),(Callithrix_pygmaea,Saguinus_oedipus)))),((Aotus_nancymaae,Leontopithecus_rosalia),((Saimiri_sciureus_macrodon,((Saimiri_sciureus,Saimiri_oerstedii),Saimiri_boliviensis)),Saimiri_oerstedii_citrinellus))),(Cebus_albifrons,(Cebus_apella,Sapajus_xanthosternos)))),((Tarsius_bancanus,(((((Perodicticus_potto,(((Galagoides_demidoff,(Loris_tardigradus,Loris_lydekkerianus)),(Nycticebus_bengalensis,Nycticebus_coucang)),Perodicticus_potto_edwarsi)),((Otolemur_crassicaudatus,Otolemur_garnettii),(Galago_senegalensis,Galago_moholi))),Daubentonia_madagascariensis),((Indri_indri,Avahi_laniger),(((Megaladapis_edwardsi,(Eulemur_macaco,(Prolemur_simus,(Cheirogaleus_medius,(Lemur_catta,((Varecia_variegata,Varecia_rubra),Hapalemur_griseus)))))),(Eulemur_fulvus,Eulemur_rufus)),Palaeopropithecus_ingens))),((Tarsius_lariang,(Tarsius_dentatus,Tarsius_wallacei)),Tarsius_syrichta))),((Propithecus_verreauxi,(Propithecus_coquereli,((Lepilemur_hubbardorum,Lepilemur_ruficaudatus),Nycticebus_pygmaeus))),(Eulemur_mongoz,Eulemur_rubriventer)))),((Miopithecus_ogouensis,(((((Mandrillus_sphinx,Cercocebus_torquatus),((Cercocebus_agilis,Mandrillus_leucophaeus),Cercocebus_chrysogaster)),(Cercocebus_atys,((((Theropithecus_gelada,(Papio_ursinus,(Rungwecebus_kipunji,(Papio_papio,(Papio_hamadryas,Papio_anubis))))),(Lophocebus_aterrimus,Lophocebus_albigena)),(Papio_kindae,Papio_cynocephalus)),(Macaca_fascicularis,((((Macaca_nemestrina,(Macaca_arctoides,(Macaca_mulatta,Macaca_fuscata))),((Macaca_assamensis,Macaca_thibetana),Macaca_sylvanus)),Macaca_nigra),(Macaca_silenus,Macaca_tonkeana)))))),((Cercopithecus_pogonias_nigripes,(((Cercopithecus_wolfi_elegans,Cercopithecus_wolfi_pyrogaster),Cercopithecus_nictitans_martini),(Cercopithecus_pogonias_schwarzianus,Cercopithecus_pogonias))),(Cercopithecus_pogonias_grayi,((((Allenopithecus_nigroviridis,(Cercopithecus_roloway,Cercopithecus_albogularis)),((Cercopithecus_nictitans_nictitans,(((Cercopithecus_kandti,Cercopithecus_mitis_stuhlmanni),(Cercopithecus_doggetti,((Cercopithecus_mitis_heymansi,Cercopithecus_albogularis_kolbi),Cercopithecus_albogularis_francescae))),Cercopithecus_mitis)),(Cercopithecus_mitis_mitis,(Cercopithecus_mitis_opisthostictus,((Cercopithecus_albogularis_labiatus,(Cercopithecus_mitis_boutourlinii,Cercopithecus_albogularis_erythrarchus)),Cercopithecus_albogularis_monoides))))),(Cercopithecus_diana,(Cercopithecus_nictitans,Erythrocebus_patas))),(Cercopithecus_campbelli,Cercopithecus_mona))))),((((Cercopithecus_neglectus,(Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis)),((Cercopithecus_ascanius_schmidti,((((Cercopithecus_ascanius_katangae,Cercopithecus_erythrotis_camerunensis),(Cercopithecus_lhoesti,(Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi))),Cercopithecus_ascanius_whitesidei),(Cercopithecus_cephus_cephus,(Cercopithecus_petaurista,((Cercopithecus_petaurista_petaurista,Cercopithecus_petaurista_buettikoferi),(Cercopithecus_erythrogaster_pococki,Cercopithecus_erythrogaster)))))),(Cercopithecus_albogularis_moloneyi,Cercopithecus_albogularis_albotorquatus))),(Miopithecus_talapoin,Cercopithecus_dryas)),((((Cercopithecus_hamlyni,Chlorocebus_cynosuros),Chlorocebus_aethiops),((Chlorocebus_sabaeus,Cercopithecus_aethiops),Chlorocebus_pygerythrus)),(Cercopithecus_solatus,Chlorocebus_tantalus))))),(((((Trachypithecus_cristatus,(Trachypithecus_johnii,(Trachypithecus_francoisi,Trachypithecus_obscurus))),((((Rhinopithecus_bieti_2_RL2012,Rhinopithecus_brelichi),(Simias_concolor,Pygathrix_nigripes)),(Rhinopithecus_roxellana,Nasalis_larvatus)),(Pygathrix_nemaeus,Trachypithecus_pileatus))),(Presbytis_melalophos,Rhinopithecus_avunculus)),((Colobus_satanas,Colobus_guereza),(Piliocolobus_badius,Procolobus_verus))),Semnopithecus_entellus)))),(((((Pongo_abelii,Pongo_pygmaeus),Hylobates_lar),Symphalangus_syndactylus),Hylobates_agilis),Nomascus_leucogenys))),Homo_sapiens_ssp_Denisova),(Homo_heidelbergensis,(((Pan_troglodytes,Pan_paniscus),Pan_troglodytes_troglodytes),Pan_troglodytes_ellioti)),Homo_sapiens); +((((Pongo_pygmaeus,((Hylobates_agilis,(Pongo_abelii,Symphalangus_syndactylus)),Hylobates_lar)),(Nomascus_leucogenys,Hylobates_moloch)),((Gorilla_gorilla,Gorilla_gorilla_gorilla),(((Alouatta_caraya,((Callithrix_pygmaea,Saguinus_oedipus),(((Callimico_goeldii,Leontopithecus_rosalia),(Cacajao_calvus,((Ateles_geoffroyi,((Ateles_belzebuth,Lagothrix_lagotricha),(Brachyteles_arachnoides,Chiropotes_israelita))),Chiropotes_albinasus))),(Ateles_paniscus,((Callicebus_lugens,(Pithecia_pithecia,(Callicebus_donacophilus,(Callithrix_jacchus,Callicebus_cupreus)))),((Sapajus_xanthosternos,(Cebus_albifrons,Cebus_apella)),(((((Saimiri_oerstedii,Saimiri_sciureus),Saimiri_boliviensis),Saimiri_sciureus_macrodon),Saimiri_oerstedii_citrinellus),(Aotus_trivirgatus,((Aotus_azarae,((Aotus_lemurinus,Aotus_azarai),Aotus_nancymaae)),Aotus_azarae_azarai))))))))),(((((Eulemur_mongoz,Eulemur_rubriventer),Propithecus_coquereli),(Propithecus_verreauxi,Nycticebus_pygmaeus)),(Lepilemur_hubbardorum,Lepilemur_ruficaudatus)),(((Tarsius_syrichta,(Tarsius_wallacei,(Tarsius_lariang,Tarsius_dentatus))),(((((Perodicticus_potto_edwarsi,Perodicticus_potto),(((Otolemur_crassicaudatus,Otolemur_garnettii),Galagoides_demidoff),(Galago_senegalensis,Galago_moholi))),((Nycticebus_bengalensis,Nycticebus_coucang),(Loris_tardigradus,Loris_lydekkerianus))),Daubentonia_madagascariensis),((Indri_indri,((Prolemur_simus,(((Hapalemur_griseus,((Megaladapis_edwardsi,Cheirogaleus_medius),Varecia_variegata)),((Eulemur_macaco,(Eulemur_fulvus,Eulemur_rufus)),Varecia_rubra)),Lemur_catta)),Palaeopropithecus_ingens)),Avahi_laniger))),Tarsius_bancanus))),((Miopithecus_ogouensis,(Miopithecus_talapoin,(((Cercopithecus_solatus,Erythrocebus_patas),(Mandrillus_sphinx,(((Mandrillus_leucophaeus,Cercocebus_chrysogaster),Cercocebus_agilis),((Cercocebus_torquatus,Cercocebus_atys),(((((Theropithecus_gelada,Rungwecebus_kipunji),(((Papio_ursinus,(Lophocebus_aterrimus,Lophocebus_albigena)),Papio_anubis),Papio_hamadryas)),Papio_papio),(Papio_kindae,Papio_cynocephalus)),(Macaca_fascicularis,((((Macaca_silenus,Macaca_tonkeana),Macaca_nigra),((Macaca_nemestrina,Macaca_sylvanus),(Macaca_assamensis,Macaca_thibetana))),(Macaca_arctoides,(Macaca_mulatta,Macaca_fuscata))))))))),(Cercopithecus_diana,((((Cercopithecus_pogonias_nigripes,(((Cercopithecus_campbelli,Cercopithecus_mona),(Cercopithecus_wolfi_elegans,Cercopithecus_wolfi_pyrogaster)),Cercopithecus_pogonias_grayi)),Cercopithecus_pogonias_schwarzianus),Cercopithecus_pogonias),(Cercopithecus_nictitans_martini,((Allenopithecus_nigroviridis,(((Chlorocebus_sabaeus,Cercopithecus_aethiops),((Chlorocebus_aethiops,(Chlorocebus_cynosuros,(Chlorocebus_tantalus,Cercopithecus_hamlyni))),Cercopithecus_dryas)),Chlorocebus_pygerythrus)),(((Cercopithecus_ascanius_schmidti,((Cercopithecus_neglectus,(Cercopithecus_ascanius_whitesidei,(Cercopithecus_cephus_cephus,(((Cercopithecus_petaurista,(((Cercopithecus_petaurista_petaurista,Cercopithecus_petaurista_buettikoferi),Cercopithecus_erythrogaster_pococki),Cercopithecus_erythrogaster)),Cercopithecus_erythrotis_camerunensis),Cercopithecus_ascanius_katangae)))),(Cercopithecus_lhoesti,(Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi)))),((Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis),(Cercopithecus_albogularis,(((((Cercopithecus_mitis_opisthostictus,(Cercopithecus_mitis_mitis,Cercopithecus_kandti)),Cercopithecus_albogularis_francescae),(Cercopithecus_doggetti,(Cercopithecus_mitis_heymansi,((Cercopithecus_nictitans,Cercopithecus_nictitans_nictitans),(Cercopithecus_albogularis_kolbi,Cercopithecus_mitis_stuhlmanni))))),Cercopithecus_mitis),(Cercopithecus_albogularis_moloneyi,(((Cercopithecus_albogularis_labiatus,Cercopithecus_albogularis_albotorquatus),Cercopithecus_albogularis_monoides),(Cercopithecus_mitis_boutourlinii,Cercopithecus_albogularis_erythrarchus))))))),Cercopithecus_roloway)))))))),(Trachypithecus_pileatus,(((Rhinopithecus_avunculus,(Trachypithecus_obscurus,((Presbytis_melalophos,(Trachypithecus_francoisi,(((Pygathrix_nemaeus,(Rhinopithecus_bieti_2_RL2012,Pygathrix_nigripes)),(Simias_concolor,Rhinopithecus_brelichi)),(Nasalis_larvatus,Rhinopithecus_roxellana)))),Semnopithecus_entellus))),((Colobus_satanas,Colobus_guereza),(Piliocolobus_badius,Procolobus_verus))),(Trachypithecus_johnii,Trachypithecus_cristatus))))))),((Pan_troglodytes,(Pan_paniscus,Pan_troglodytes_troglodytes)),((Homo_heidelbergensis,Pan_troglodytes_ellioti),Homo_sapiens_ssp_Denisova)),Homo_sapiens); +((Homo_sapiens_ssp_Denisova,((Pan_troglodytes_troglodytes,Pan_troglodytes),Pan_paniscus)),(Pan_troglodytes_ellioti,(((Hylobates_agilis,((Hylobates_lar,(Gorilla_gorilla,(Nomascus_leucogenys,Hylobates_moloch))),(Pongo_pygmaeus,Pongo_abelii))),(Gorilla_gorilla_gorilla,(Symphalangus_syndactylus,(((Alouatta_caraya,((Chiropotes_albinasus,((Chiropotes_israelita,Cacajao_calvus),((((Pithecia_pithecia,((Callithrix_jacchus,Ateles_belzebuth),Ateles_paniscus)),Ateles_geoffroyi),Lagothrix_lagotricha),(((Callicebus_donacophilus,(Callicebus_cupreus,Callicebus_lugens)),(((((Saimiri_oerstedii,Saimiri_sciureus),Saimiri_boliviensis),Saimiri_sciureus_macrodon),Saimiri_oerstedii_citrinellus),(((((Aotus_azarai,(Aotus_azarae_azarai,(Aotus_trivirgatus,Aotus_azarae))),Aotus_lemurinus),(Callithrix_pygmaea,Saguinus_oedipus)),(Callimico_goeldii,Leontopithecus_rosalia)),Aotus_nancymaae))),(Cebus_albifrons,(Cebus_apella,Sapajus_xanthosternos)))))),Brachyteles_arachnoides)),(((((((((Eulemur_macaco,Eulemur_rufus),Palaeopropithecus_ingens),Megaladapis_edwardsi),((Cheirogaleus_medius,Hapalemur_griseus),Lemur_catta)),(Eulemur_fulvus,(Indri_indri,Avahi_laniger))),(Prolemur_simus,(Varecia_variegata,Varecia_rubra))),((((Loris_tardigradus,Loris_lydekkerianus),(Galagoides_demidoff,((Otolemur_crassicaudatus,(Galago_senegalensis,Otolemur_garnettii)),Galago_moholi))),((Perodicticus_potto_edwarsi,Perodicticus_potto),(Nycticebus_bengalensis,Nycticebus_coucang))),Daubentonia_madagascariensis)),(((Tarsius_wallacei,Tarsius_dentatus),Tarsius_lariang),Tarsius_syrichta)),(Tarsius_bancanus,(((Lepilemur_hubbardorum,Lepilemur_ruficaudatus),(Eulemur_mongoz,Nycticebus_pygmaeus)),(Propithecus_coquereli,(Eulemur_rubriventer,Propithecus_verreauxi)))))),((Miopithecus_ogouensis,(((Erythrocebus_patas,(Mandrillus_sphinx,(((Cercocebus_torquatus,Cercocebus_atys),(((Theropithecus_gelada,(Lophocebus_aterrimus,Lophocebus_albigena)),(Papio_kindae,((Rungwecebus_kipunji,Papio_ursinus),(((Papio_hamadryas,Papio_anubis),Papio_papio),Papio_cynocephalus)))),((Macaca_sylvanus,Macaca_fascicularis),((Macaca_silenus,Macaca_tonkeana),((Macaca_arctoides,(Macaca_nemestrina,(Macaca_nigra,(Macaca_mulatta,Macaca_fuscata)))),(Macaca_assamensis,Macaca_thibetana)))))),((Mandrillus_leucophaeus,Cercocebus_chrysogaster),Cercocebus_agilis)))),Cercopithecus_solatus),(Cercopithecus_diana,(Miopithecus_talapoin,(Cercopithecus_neglectus,(((Cercopithecus_dryas,((Cercopithecus_aethiops,Chlorocebus_pygerythrus),((Chlorocebus_sabaeus,((Chlorocebus_aethiops,Cercopithecus_hamlyni),Chlorocebus_cynosuros)),Chlorocebus_tantalus))),(Cercopithecus_roloway,((Cercopithecus_pogonias,((((Cercopithecus_wolfi_elegans,Cercopithecus_wolfi_pyrogaster),Cercopithecus_pogonias_schwarzianus),Cercopithecus_pogonias_grayi),Cercopithecus_pogonias_nigripes)),(Cercopithecus_campbelli,Cercopithecus_mona)))),((Cercopithecus_ascanius_schmidti,((Cercopithecus_cephus_cephus,(((Cercopithecus_erythrogaster,((Cercopithecus_petaurista_buettikoferi,Cercopithecus_erythrogaster_pococki),Cercopithecus_petaurista)),Cercopithecus_petaurista_petaurista),Cercopithecus_ascanius_katangae)),(Cercopithecus_ascanius_whitesidei,((Cercopithecus_erythrotis_camerunensis,(Allenopithecus_nigroviridis,(Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi))),Cercopithecus_lhoesti)))),((Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis),(((Cercopithecus_mitis,(((Cercopithecus_nictitans_nictitans,(Cercopithecus_nictitans_martini,Cercopithecus_nictitans)),Cercopithecus_doggetti),(Cercopithecus_kandti,((Cercopithecus_albogularis_kolbi,Cercopithecus_mitis_stuhlmanni),(Cercopithecus_mitis_heymansi,(Cercopithecus_mitis_mitis,Cercopithecus_mitis_opisthostictus)))))),Cercopithecus_albogularis_francescae),(Cercopithecus_albogularis_moloneyi,(((Cercopithecus_mitis_boutourlinii,(Cercopithecus_albogularis_erythrarchus,Cercopithecus_albogularis_labiatus)),(Cercopithecus_albogularis,Cercopithecus_albogularis_monoides)),Cercopithecus_albogularis_albotorquatus))))))))))),(((((((Trachypithecus_francoisi,Trachypithecus_cristatus),Trachypithecus_johnii),Trachypithecus_obscurus),((Rhinopithecus_roxellana,Nasalis_larvatus),((Rhinopithecus_bieti_2_RL2012,Pygathrix_nemaeus),(Pygathrix_nigripes,(Rhinopithecus_brelichi,Simias_concolor))))),Trachypithecus_pileatus),((Presbytis_melalophos,Semnopithecus_entellus),Rhinopithecus_avunculus)),((Colobus_satanas,Colobus_guereza),(Piliocolobus_badius,Procolobus_verus)))))))),Homo_heidelbergensis)),Homo_sapiens); +(((Gorilla_gorilla,((((Hylobates_agilis,(Pongo_pygmaeus,((Pongo_abelii,(Hylobates_lar,Nomascus_leucogenys)),Hylobates_moloch))),Symphalangus_syndactylus),(((Alouatta_caraya,(Callicebus_cupreus,((((((Aotus_azarai,Aotus_lemurinus),(Aotus_azarae_azarai,(Aotus_azarae,Aotus_trivirgatus))),(Leontopithecus_rosalia,(Aotus_nancymaae,(Saimiri_sciureus_macrodon,((Saimiri_sciureus,(Saimiri_oerstedii,Saimiri_boliviensis)),Saimiri_oerstedii_citrinellus))))),(Callithrix_pygmaea,Saguinus_oedipus)),(((Pithecia_pithecia,(Callimico_goeldii,(Ateles_geoffroyi,(Ateles_belzebuth,(((((Chiropotes_israelita,(Brachyteles_arachnoides,Chiropotes_albinasus)),Cacajao_calvus),Lagothrix_lagotricha),Callithrix_jacchus),Ateles_paniscus))))),Callicebus_lugens),(Cebus_albifrons,(Cebus_apella,Sapajus_xanthosternos)))),Callicebus_donacophilus))),((((Propithecus_coquereli,(Eulemur_mongoz,Eulemur_rubriventer)),(Lepilemur_hubbardorum,Lepilemur_ruficaudatus)),Tarsius_bancanus),(Perodicticus_potto,(((Propithecus_verreauxi,((Daubentonia_madagascariensis,((Galago_moholi,(Perodicticus_potto_edwarsi,((Galago_senegalensis,(Otolemur_garnettii,((Nycticebus_coucang,Nycticebus_bengalensis),Otolemur_crassicaudatus))),(Nycticebus_pygmaeus,(Loris_lydekkerianus,(Loris_tardigradus,Galagoides_demidoff)))))),(((Eulemur_rufus,(Eulemur_macaco,((Prolemur_simus,(Eulemur_fulvus,(Cheirogaleus_medius,Megaladapis_edwardsi))),((Varecia_variegata,Varecia_rubra),Hapalemur_griseus)))),Palaeopropithecus_ingens),Indri_indri))),Avahi_laniger)),((Tarsius_dentatus,(Tarsius_lariang,Tarsius_wallacei)),Tarsius_syrichta)),Lemur_catta)))),((Cercopithecus_roloway,((((Miopithecus_ogouensis,(Cercopithecus_campbelli,Cercopithecus_mona)),Cercopithecus_pogonias),((Miopithecus_talapoin,(((Rhinopithecus_avunculus,(Presbytis_melalophos,(Trachypithecus_johnii,(((Trachypithecus_obscurus,(Trachypithecus_francoisi,Trachypithecus_cristatus)),((Simias_concolor,(Rhinopithecus_bieti_2_RL2012,(Rhinopithecus_brelichi,Pygathrix_nigripes))),(Rhinopithecus_roxellana,Nasalis_larvatus))),(Pygathrix_nemaeus,Trachypithecus_pileatus))))),((Colobus_satanas,Colobus_guereza),(Piliocolobus_badius,Procolobus_verus))),Semnopithecus_entellus)),((Erythrocebus_patas,(((Macaca_sylvanus,((Theropithecus_gelada,(Lophocebus_aterrimus,Lophocebus_albigena)),(((Papio_cynocephalus,Papio_papio),Papio_kindae),((Papio_hamadryas,Papio_anubis),(Rungwecebus_kipunji,Papio_ursinus))))),(Macaca_fascicularis,((Macaca_silenus,Macaca_tonkeana),((Macaca_arctoides,(Macaca_nemestrina,(Macaca_nigra,(Macaca_mulatta,Macaca_fuscata)))),(Macaca_assamensis,Macaca_thibetana))))),((Cercocebus_torquatus,((Cercocebus_agilis,Mandrillus_leucophaeus),Cercocebus_chrysogaster)),(Cercocebus_atys,Mandrillus_sphinx)))),(Cercopithecus_dryas,(((Chlorocebus_tantalus,(Cercopithecus_solatus,Cercopithecus_aethiops)),((Chlorocebus_pygerythrus,(Chlorocebus_aethiops,Cercopithecus_hamlyni)),Chlorocebus_sabaeus)),Chlorocebus_cynosuros))))),Cercopithecus_diana)),((Cercopithecus_nictitans_martini,(Cercopithecus_albogularis,((((Cercopithecus_neglectus,((((((Cercopithecus_erythrogaster,(Cercopithecus_petaurista_petaurista,(Cercopithecus_petaurista_buettikoferi,Cercopithecus_erythrogaster_pococki))),Cercopithecus_erythrotis_camerunensis),Cercopithecus_ascanius_whitesidei),Cercopithecus_cephus_cephus),Cercopithecus_ascanius_katangae),(Cercopithecus_lhoesti,(Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi)))),(Cercopithecus_pogonias_schwarzianus,((Cercopithecus_pogonias_nigripes,(Cercopithecus_wolfi_elegans,(Cercopithecus_wolfi_pyrogaster,Cercopithecus_petaurista))),Cercopithecus_pogonias_grayi))),(((((Cercopithecus_albogularis_kolbi,(Allenopithecus_nigroviridis,Cercopithecus_kandti)),(Cercopithecus_mitis_stuhlmanni,((Cercopithecus_mitis_heymansi,Cercopithecus_albogularis_francescae),Cercopithecus_doggetti))),Cercopithecus_mitis),(Cercopithecus_nictitans,(Cercopithecus_nictitans_nictitans,(Cercopithecus_mitis_mitis,Cercopithecus_mitis_opisthostictus)))),(Cercopithecus_albogularis_moloneyi,(Cercopithecus_albogularis_monoides,((Cercopithecus_albogularis_erythrarchus,Cercopithecus_albogularis_albotorquatus),(Cercopithecus_mitis_boutourlinii,Cercopithecus_albogularis_labiatus)))))),(Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis)))),Cercopithecus_ascanius_schmidti)))),Gorilla_gorilla_gorilla)),Pan_troglodytes_troglodytes),(((Homo_sapiens_ssp_Denisova,(Homo_heidelbergensis,Pan_troglodytes_ellioti)),Pan_troglodytes),Pan_paniscus),Homo_sapiens); +(((Pan_paniscus,(Pan_troglodytes_troglodytes,Pan_troglodytes)),Pan_troglodytes_ellioti),(Homo_sapiens_ssp_Denisova,(Homo_heidelbergensis,(Gorilla_gorilla_gorilla,(Gorilla_gorilla,((((Hylobates_agilis,(Hylobates_moloch,(Nomascus_leucogenys,Symphalangus_syndactylus))),Hylobates_lar),(Pongo_pygmaeus,Pongo_abelii)),(((Alouatta_caraya,((Callithrix_pygmaea,Saguinus_oedipus),(Lagothrix_lagotricha,(((Pithecia_pithecia,(Callicebus_lugens,(((Callicebus_donacophilus,(Ateles_belzebuth,Brachyteles_arachnoides)),(Callithrix_jacchus,(Ateles_paniscus,(Ateles_geoffroyi,Callimico_goeldii)))),Callicebus_cupreus))),((Aotus_trivirgatus,((Aotus_nancymaae,((Aotus_lemurinus,(((Saimiri_sciureus_macrodon,Saimiri_oerstedii_citrinellus),(Saimiri_boliviensis,(Saimiri_sciureus,Saimiri_oerstedii))),Aotus_azarai)),Aotus_azarae_azarai)),Aotus_azarae)),Leontopithecus_rosalia)),((Sapajus_xanthosternos,(Cebus_albifrons,Cebus_apella)),((Chiropotes_israelita,Chiropotes_albinasus),Cacajao_calvus)))))),(((Lepilemur_hubbardorum,Lepilemur_ruficaudatus),(Eulemur_rubriventer,Eulemur_mongoz)),(((Perodicticus_potto,Lemur_catta),(Tarsius_syrichta,(Tarsius_lariang,(Tarsius_wallacei,Tarsius_dentatus)))),(Propithecus_verreauxi,(Galago_senegalensis,((((Daubentonia_madagascariensis,Propithecus_coquereli),(Galago_moholi,(Perodicticus_potto_edwarsi,((Nycticebus_bengalensis,Loris_lydekkerianus),((Galagoides_demidoff,(Nycticebus_coucang,Otolemur_crassicaudatus)),Otolemur_garnettii))))),((((Eulemur_rufus,(((((Varecia_rubra,Varecia_variegata),Hapalemur_griseus),(Eulemur_macaco,(Eulemur_fulvus,Cheirogaleus_medius))),Prolemur_simus),Megaladapis_edwardsi)),Palaeopropithecus_ingens),Nycticebus_pygmaeus),(Loris_tardigradus,(Indri_indri,Avahi_laniger)))),Tarsius_bancanus)))))),((((Colobus_satanas,Colobus_guereza),(Piliocolobus_badius,Procolobus_verus)),(Rhinopithecus_avunculus,((Presbytis_melalophos,(((Trachypithecus_pileatus,(Trachypithecus_cristatus,(Trachypithecus_francoisi,Trachypithecus_obscurus))),((Rhinopithecus_bieti_2_RL2012,Rhinopithecus_brelichi),(Rhinopithecus_roxellana,((Pygathrix_nemaeus,Pygathrix_nigripes),(Simias_concolor,Nasalis_larvatus))))),Trachypithecus_johnii)),Semnopithecus_entellus))),(((((Cercopithecus_cephus_cephus,((Cercopithecus_ascanius_katangae,((Cercopithecus_neglectus,((((Cercopithecus_albogularis_erythrarchus,(((Cercopithecus_roloway,(Cercopithecus_lhoesti,(Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi))),((((((Cercopithecus_mitis_heymansi,Cercopithecus_albogularis_francescae),(Cercopithecus_albogularis_kolbi,Cercopithecus_mitis_stuhlmanni)),((Allenopithecus_nigroviridis,Cercopithecus_kandti),Cercopithecus_doggetti)),Cercopithecus_mitis),((Cercopithecus_nictitans_nictitans,Cercopithecus_nictitans),(Cercopithecus_mitis_opisthostictus,Cercopithecus_mitis_mitis))),(Cercopithecus_albogularis,Cercopithecus_albogularis_monoides))),Cercopithecus_mitis_boutourlinii)),(Cercopithecus_erythrotis_camerunensis,(((((Cercopithecus_wolfi_elegans,Cercopithecus_wolfi_pyrogaster),Cercopithecus_nictitans_martini),(Cercopithecus_pogonias_schwarzianus,Cercopithecus_pogonias_nigripes)),Cercopithecus_pogonias_grayi),Cercopithecus_albogularis_labiatus))),(Cercopithecus_albogularis_moloneyi,Cercopithecus_albogularis_albotorquatus)),Cercopithecus_ascanius_whitesidei)),(Cercopithecus_cephus_ngottoensis,(Cercopithecus_ascanius_schmidti,Cercopithecus_cephus)))),(Cercopithecus_petaurista,((Cercopithecus_erythrogaster,Cercopithecus_erythrogaster_pococki),(Cercopithecus_petaurista_petaurista,Cercopithecus_petaurista_buettikoferi))))),(Cercopithecus_diana,((Macaca_fascicularis,((Macaca_silenus,Macaca_tonkeana),((Macaca_nemestrina,((Macaca_mulatta,Macaca_fuscata),Macaca_arctoides)),(Macaca_assamensis,Macaca_thibetana)))),Macaca_nigra))),Miopithecus_talapoin),(Miopithecus_ogouensis,(Cercopithecus_pogonias,(Cercopithecus_campbelli,Cercopithecus_mona)))),((((((Cercopithecus_aethiops,Chlorocebus_sabaeus),Cercopithecus_dryas),((Chlorocebus_tantalus,(Chlorocebus_pygerythrus,(Chlorocebus_aethiops,Cercopithecus_hamlyni))),Chlorocebus_cynosuros)),Cercopithecus_solatus),(Mandrillus_sphinx,((Cercocebus_torquatus,((((Macaca_sylvanus,((((Papio_papio,Papio_cynocephalus),Papio_kindae),((Papio_hamadryas,Papio_anubis),Papio_ursinus)),(Theropithecus_gelada,(Rungwecebus_kipunji,Lophocebus_aterrimus)))),(Cercocebus_agilis,Mandrillus_leucophaeus)),Lophocebus_albigena),Cercocebus_chrysogaster)),Cercocebus_atys))),Erythrocebus_patas))))))))),Homo_sapiens); +(((((((((Alouatta_caraya,(((Lagothrix_lagotricha,((Callithrix_jacchus,Callithrix_pygmaea),Pithecia_pithecia)),(((Cebus_albifrons,(Cebus_apella,Sapajus_xanthosternos)),(Chiropotes_israelita,(Chiropotes_albinasus,Cacajao_calvus))),(Callicebus_lugens,(Callicebus_cupreus,(((Callicebus_donacophilus,Brachyteles_arachnoides),Ateles_belzebuth),(Callimico_goeldii,(Ateles_paniscus,Ateles_geoffroyi))))))),(((((Aotus_azarai,Aotus_lemurinus),Aotus_trivirgatus),Aotus_azarae),Aotus_azarae_azarai),((((Saimiri_sciureus_macrodon,(Saimiri_boliviensis,Saimiri_oerstedii)),Saimiri_sciureus),Saimiri_oerstedii_citrinellus),(Leontopithecus_rosalia,Aotus_nancymaae))))),Saguinus_oedipus),(((((Lepilemur_hubbardorum,Lepilemur_ruficaudatus),Tarsius_bancanus),(Perodicticus_potto,Lemur_catta)),(((Eulemur_mongoz,Eulemur_rubriventer),((Tarsius_wallacei,(Tarsius_dentatus,Tarsius_lariang)),Tarsius_syrichta)),((Daubentonia_madagascariensis,(Galago_moholi,((Perodicticus_potto_edwarsi,(((Propithecus_verreauxi,(Nycticebus_coucang,Nycticebus_bengalensis)),(Galagoides_demidoff,(Loris_lydekkerianus,Loris_tardigradus))),Otolemur_garnettii)),Otolemur_crassicaudatus))),((Indri_indri,(((Eulemur_rufus,(Cheirogaleus_medius,((Nycticebus_pygmaeus,Hapalemur_griseus),Prolemur_simus))),Eulemur_fulvus),Palaeopropithecus_ingens)),((((Varecia_rubra,Varecia_variegata),(Propithecus_coquereli,Avahi_laniger)),Eulemur_macaco),Megaladapis_edwardsi))))),Galago_senegalensis)),((((((Colobus_satanas,Colobus_guereza),Piliocolobus_badius),(((((Trachypithecus_pileatus,(Trachypithecus_cristatus,(Trachypithecus_francoisi,Trachypithecus_obscurus))),(((Pygathrix_nemaeus,Pygathrix_nigripes),(Semnopithecus_entellus,(Simias_concolor,Nasalis_larvatus))),((Rhinopithecus_bieti_2_RL2012,Rhinopithecus_brelichi),Rhinopithecus_roxellana))),Presbytis_melalophos),Rhinopithecus_avunculus),Trachypithecus_johnii)),Procolobus_verus),(((Cercopithecus_campbelli,Cercopithecus_mona),((Cercopithecus_pogonias,((Cercopithecus_wolfi_elegans,Cercopithecus_wolfi_pyrogaster),((Cercopithecus_pogonias_nigripes,Cercopithecus_pogonias_grayi),Cercopithecus_pogonias_schwarzianus))),Cercopithecus_nictitans_martini)),((Miopithecus_talapoin,(Cercopithecus_diana,(((Macaca_nigra,(Macaca_mulatta,Macaca_fuscata)),(Macaca_arctoides,(((Macaca_silenus,(Macaca_assamensis,Macaca_thibetana)),(Macaca_tonkeana,Macaca_fascicularis)),Macaca_nemestrina))),(Cercopithecus_roloway,((Cercopithecus_ascanius_schmidti,(Cercopithecus_lhoesti,(Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi))),((((Cercopithecus_cephus,((Cercopithecus_ascanius_whitesidei,((Cercopithecus_cephus_cephus,(Cercopithecus_petaurista,(((Cercopithecus_erythrotis_camerunensis,Cercopithecus_erythrogaster_pococki),(Cercopithecus_petaurista_petaurista,Cercopithecus_petaurista_buettikoferi)),Cercopithecus_erythrogaster))),Cercopithecus_ascanius_katangae)),Cercopithecus_neglectus)),Cercopithecus_cephus_ngottoensis),(((Cercopithecus_mitis_opisthostictus,((Cercopithecus_nictitans_nictitans,Cercopithecus_nictitans),Allenopithecus_nigroviridis)),(Cercopithecus_mitis_mitis,(((Cercopithecus_mitis_heymansi,Cercopithecus_albogularis_francescae),(((Cercopithecus_albogularis_kolbi,Cercopithecus_mitis_stuhlmanni),Cercopithecus_doggetti),Cercopithecus_kandti)),Cercopithecus_mitis))),(Cercopithecus_albogularis_moloneyi,(Cercopithecus_albogularis_monoides,(Cercopithecus_albogularis_albotorquatus,((Cercopithecus_albogularis_erythrarchus,Cercopithecus_mitis_boutourlinii),Cercopithecus_albogularis_labiatus)))))),Cercopithecus_albogularis)))))),(((((Cercopithecus_aethiops,Chlorocebus_sabaeus),Cercopithecus_dryas),(((Chlorocebus_cynosuros,(Chlorocebus_aethiops,Cercopithecus_hamlyni)),Chlorocebus_tantalus),Chlorocebus_pygerythrus)),Cercopithecus_solatus),((Mandrillus_sphinx,Erythrocebus_patas),(Macaca_sylvanus,((Cercocebus_chrysogaster,(((Cercocebus_atys,((Lophocebus_aterrimus,Theropithecus_gelada),((Rungwecebus_kipunji,((Papio_hamadryas,((Papio_anubis,Papio_cynocephalus),Papio_ursinus)),(Papio_kindae,Papio_papio))),Lophocebus_albigena))),Cercocebus_torquatus),Mandrillus_leucophaeus)),Cercocebus_agilis))))))),Miopithecus_ogouensis)),(Gorilla_gorilla,((((((Symphalangus_syndactylus,Hylobates_lar),Hylobates_agilis),Nomascus_leucogenys),Hylobates_moloch),(Pongo_pygmaeus,Pongo_abelii)),Gorilla_gorilla_gorilla))),Homo_heidelbergensis),Homo_sapiens_ssp_Denisova),(Pan_troglodytes_ellioti,Pan_troglodytes_troglodytes)),(Pan_paniscus,Pan_troglodytes),Homo_sapiens); +((Homo_sapiens_ssp_Denisova,((((((((Pongo_pygmaeus,Pongo_abelii),(Hylobates_lar,Symphalangus_syndactylus)),Hylobates_agilis),Nomascus_leucogenys),Hylobates_moloch),((Gorilla_gorilla_gorilla,Gorilla_gorilla),(((((Saguinus_oedipus,(Callithrix_jacchus,Callithrix_pygmaea)),(((((Saimiri_boliviensis,(Saimiri_sciureus,Saimiri_oerstedii)),(Saimiri_sciureus_macrodon,Saimiri_oerstedii_citrinellus)),((Aotus_nancymaae,(Aotus_trivirgatus,(Aotus_azarae,(Aotus_azarai,Aotus_lemurinus)))),Aotus_azarae_azarai)),Leontopithecus_rosalia),(Pithecia_pithecia,(Lagothrix_lagotricha,((Callicebus_lugens,Callicebus_cupreus),((Sapajus_xanthosternos,(Cebus_albifrons,Cebus_apella)),(Callicebus_donacophilus,((Ateles_paniscus,(Ateles_geoffroyi,(Ateles_belzebuth,((Brachyteles_arachnoides,Chiropotes_albinasus),(Callimico_goeldii,Chiropotes_israelita))))),Cacajao_calvus)))))))),Alouatta_caraya),((Perodicticus_potto,Lemur_catta),(((((Daubentonia_madagascariensis,(Galago_moholi,((Otolemur_garnettii,(Loris_tardigradus,((Galagoides_demidoff,((Propithecus_verreauxi,(Nycticebus_coucang,Nycticebus_bengalensis)),Perodicticus_potto_edwarsi)),Otolemur_crassicaudatus))),Loris_lydekkerianus))),((Eulemur_fulvus,(Avahi_laniger,(Varecia_variegata,Megaladapis_edwardsi))),(((Eulemur_rufus,(Eulemur_macaco,(Cheirogaleus_medius,(Prolemur_simus,(Nycticebus_pygmaeus,Hapalemur_griseus))))),(Palaeopropithecus_ingens,(Propithecus_coquereli,Indri_indri))),Varecia_rubra))),((Tarsius_dentatus,(Tarsius_lariang,Tarsius_wallacei)),Tarsius_syrichta)),(Eulemur_mongoz,Eulemur_rubriventer)),((Tarsius_bancanus,(Lepilemur_hubbardorum,Lepilemur_ruficaudatus)),Galago_senegalensis)))),((((Cercopithecus_campbelli,Cercopithecus_mona),((Cercopithecus_neglectus,(((Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis),(Cercopithecus_ascanius_schmidti,(((Cercopithecus_cephus_cephus,((Cercopithecus_erythrogaster,Cercopithecus_petaurista),(Cercopithecus_petaurista_petaurista,Cercopithecus_petaurista_buettikoferi))),((Cercopithecus_ascanius_katangae,Cercopithecus_erythrotis_camerunensis),Cercopithecus_erythrogaster_pococki)),Cercopithecus_ascanius_whitesidei))),(Cercopithecus_albogularis_moloneyi,(((Cercopithecus_albogularis_labiatus,Cercopithecus_albogularis),((Cercopithecus_mitis_boutourlinii,(Cercopithecus_albogularis_monoides,Cercopithecus_albogularis_erythrarchus)),Cercopithecus_albogularis_albotorquatus)),(((Cercopithecus_doggetti,((Cercopithecus_kandti,Allenopithecus_nigroviridis),Cercopithecus_nictitans_nictitans)),((Cercopithecus_nictitans,(Cercopithecus_albogularis_francescae,Cercopithecus_mitis_heymansi)),((Cercopithecus_albogularis_kolbi,Cercopithecus_mitis_stuhlmanni),(Cercopithecus_mitis_mitis,Cercopithecus_mitis_opisthostictus)))),Cercopithecus_mitis))))),((Cercopithecus_pogonias,((Cercopithecus_pogonias_nigripes,Cercopithecus_pogonias_grayi),(Cercopithecus_pogonias_schwarzianus,(Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans)))),Cercopithecus_nictitans_martini))),((Cercopithecus_diana,((Macaca_silenus,(((((Macaca_assamensis,Macaca_thibetana),(Macaca_nemestrina,Macaca_arctoides)),(Macaca_nigra,(Macaca_mulatta,Macaca_fuscata))),Macaca_tonkeana),Macaca_fascicularis)),(Cercopithecus_roloway,(Cercopithecus_lhoesti,(Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi))))),((((Cercopithecus_solatus,((Mandrillus_sphinx,Erythrocebus_patas),((Mandrillus_leucophaeus,(Macaca_sylvanus,((Papio_kindae,Papio_cynocephalus),(((Rungwecebus_kipunji,((Lophocebus_aterrimus,Lophocebus_albigena),Papio_ursinus)),Theropithecus_gelada),(Papio_papio,(Papio_anubis,Papio_hamadryas)))))),(((Cercocebus_atys,Cercocebus_torquatus),Cercocebus_chrysogaster),Cercocebus_agilis)))),(((Chlorocebus_pygerythrus,Cercopithecus_dryas),(((Cercopithecus_aethiops,Chlorocebus_sabaeus),(Chlorocebus_aethiops,Cercopithecus_hamlyni)),Chlorocebus_cynosuros)),Chlorocebus_tantalus)),(((Procolobus_verus,Piliocolobus_badius),(Colobus_satanas,Colobus_guereza)),((Trachypithecus_cristatus,((Trachypithecus_obscurus,((Semnopithecus_entellus,((((Nasalis_larvatus,(Rhinopithecus_bieti_2_RL2012,(Pygathrix_nigripes,((Rhinopithecus_brelichi,Simias_concolor),Pygathrix_nemaeus)))),Rhinopithecus_roxellana),Trachypithecus_francoisi),Presbytis_melalophos)),Trachypithecus_johnii)),Trachypithecus_pileatus)),Rhinopithecus_avunculus))),Miopithecus_talapoin))),Miopithecus_ogouensis)))),Homo_heidelbergensis),(Pan_troglodytes_troglodytes,Pan_troglodytes_ellioti))),(Pan_paniscus,Pan_troglodytes),Homo_sapiens); +(((Homo_heidelbergensis,((((Gorilla_gorilla,(((Hylobates_agilis,(Symphalangus_syndactylus,(Hylobates_lar,Hylobates_moloch))),Nomascus_leucogenys),(Pongo_pygmaeus,Pongo_abelii))),Gorilla_gorilla_gorilla),Homo_sapiens_ssp_Denisova),((((((((Aotus_nancymaae,Lagothrix_lagotricha),((((((Saimiri_sciureus,(Saimiri_boliviensis,Saimiri_oerstedii)),Saimiri_sciureus_macrodon),Saimiri_oerstedii_citrinellus),Aotus_azarai),(Cebus_albifrons,(Cebus_apella,Sapajus_xanthosternos))),(Callicebus_lugens,(((Callicebus_donacophilus,Brachyteles_arachnoides),Callicebus_cupreus),(Callimico_goeldii,(Ateles_paniscus,(Ateles_geoffroyi,Ateles_belzebuth))))))),Pithecia_pithecia),(((Aotus_trivirgatus,(Chiropotes_albinasus,Chiropotes_israelita)),Leontopithecus_rosalia),(Cacajao_calvus,Aotus_azarae_azarai))),(Aotus_lemurinus,(Saguinus_oedipus,(Aotus_azarae,(Callithrix_jacchus,Callithrix_pygmaea))))),Alouatta_caraya),((((Tarsius_lariang,(Tarsius_wallacei,Tarsius_dentatus)),Tarsius_syrichta),((((((Propithecus_verreauxi,Loris_tardigradus),Loris_lydekkerianus),(Nycticebus_coucang,Nycticebus_bengalensis)),((((Otolemur_garnettii,Otolemur_crassicaudatus),Galagoides_demidoff),Galago_moholi),Perodicticus_potto_edwarsi)),Daubentonia_madagascariensis),(Eulemur_macaco,((Avahi_laniger,Megaladapis_edwardsi),((Palaeopropithecus_ingens,(Eulemur_rufus,(Indri_indri,((((Varecia_variegata,Varecia_rubra),Hapalemur_griseus),((Prolemur_simus,Nycticebus_pygmaeus),Propithecus_coquereli)),Cheirogaleus_medius)))),Eulemur_fulvus))))),(Lemur_catta,(((Lepilemur_hubbardorum,Lepilemur_ruficaudatus),(Eulemur_rubriventer,Eulemur_mongoz)),((Galago_senegalensis,Perodicticus_potto),Tarsius_bancanus))))),((((Procolobus_verus,Piliocolobus_badius),(Colobus_satanas,Colobus_guereza)),((Rhinopithecus_avunculus,(((((Rhinopithecus_brelichi,Rhinopithecus_bieti_2_RL2012),Rhinopithecus_roxellana),((Simias_concolor,Nasalis_larvatus),(Pygathrix_nigripes,Pygathrix_nemaeus))),(Trachypithecus_pileatus,((Trachypithecus_obscurus,Trachypithecus_francoisi),Trachypithecus_cristatus))),(Trachypithecus_johnii,Semnopithecus_entellus))),Presbytis_melalophos)),(((((Cercopithecus_albogularis_moloneyi,(((((Cercopithecus_albogularis_labiatus,Cercopithecus_albogularis_erythrarchus),((Cercopithecus_nictitans,Cercopithecus_nictitans_nictitans),((Allenopithecus_nigroviridis,Cercopithecus_mitis_mitis),(Cercopithecus_mitis_opisthostictus,((Cercopithecus_doggetti,(Cercopithecus_kandti,((Cercopithecus_mitis_stuhlmanni,Cercopithecus_albogularis_kolbi),Cercopithecus_mitis))),(Cercopithecus_albogularis_francescae,Cercopithecus_mitis_heymansi)))))),Cercopithecus_mitis_boutourlinii),(Cercopithecus_albogularis,Cercopithecus_albogularis_monoides)),Cercopithecus_albogularis_albotorquatus)),(((Cercopithecus_cephus_cephus,(((Cercopithecus_lhoesti,(Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi)),(Cercopithecus_ascanius_katangae,Cercopithecus_erythrotis_camerunensis)),((Cercopithecus_petaurista,(Cercopithecus_petaurista_petaurista,(Cercopithecus_petaurista_buettikoferi,Cercopithecus_erythrogaster_pococki))),Cercopithecus_erythrogaster))),(Cercopithecus_ascanius_whitesidei,Cercopithecus_neglectus)),(Cercopithecus_ascanius_schmidti,(Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis)))),((((Cercopithecus_campbelli,Cercopithecus_mona),(Cercopithecus_pogonias,((Cercopithecus_nictitans_martini,(Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans)),(Cercopithecus_pogonias_schwarzianus,(Cercopithecus_pogonias_grayi,Cercopithecus_pogonias_nigripes))))),Cercopithecus_roloway),(Cercopithecus_diana,(Erythrocebus_patas,((Macaca_arctoides,(((Macaca_silenus,(Macaca_tonkeana,Macaca_fascicularis)),(Macaca_assamensis,Macaca_thibetana)),(Macaca_nemestrina,Macaca_nigra))),(Macaca_mulatta,Macaca_fuscata)))))),(((((Chlorocebus_aethiops,(Cercopithecus_hamlyni,Chlorocebus_cynosuros)),(Chlorocebus_tantalus,((Cercopithecus_dryas,(Cercopithecus_aethiops,Chlorocebus_sabaeus)),Chlorocebus_pygerythrus))),Cercopithecus_solatus),(Mandrillus_sphinx,((Mandrillus_leucophaeus,(Cercocebus_agilis,((((Theropithecus_gelada,(((Papio_ursinus,(Papio_cynocephalus,Papio_kindae)),(Papio_papio,(Papio_anubis,Papio_hamadryas))),Lophocebus_aterrimus)),Lophocebus_albigena),Rungwecebus_kipunji),(Cercocebus_atys,Macaca_sylvanus)))),(Cercocebus_torquatus,Cercocebus_chrysogaster)))),Miopithecus_talapoin)),Miopithecus_ogouensis))))),Pan_troglodytes_ellioti),((Pan_paniscus,Pan_troglodytes),Pan_troglodytes_troglodytes),Homo_sapiens); +((Homo_sapiens_ssp_Denisova,(((Hylobates_agilis,(((Pongo_pygmaeus,Pongo_abelii),Symphalangus_syndactylus),Hylobates_lar)),(Nomascus_leucogenys,Hylobates_moloch)),((((((Tarsius_bancanus,Lemur_catta),((Lepilemur_hubbardorum,Lepilemur_ruficaudatus),(Galago_senegalensis,((Eulemur_mongoz,Eulemur_rubriventer),Perodicticus_potto)))),(((((Loris_lydekkerianus,(Galagoides_demidoff,((Nycticebus_pygmaeus,(Varecia_variegata,Varecia_rubra)),Loris_tardigradus))),(Nycticebus_bengalensis,(Propithecus_verreauxi,Nycticebus_coucang))),(((Otolemur_garnettii,Otolemur_crassicaudatus),Galago_moholi),Perodicticus_potto_edwarsi)),(((Eulemur_rufus,(Eulemur_fulvus,(Eulemur_macaco,((Hapalemur_griseus,Cheirogaleus_medius),((Indri_indri,(Propithecus_coquereli,Avahi_laniger)),Prolemur_simus))))),Palaeopropithecus_ingens),(Daubentonia_madagascariensis,Megaladapis_edwardsi))),(((Tarsius_dentatus,Tarsius_lariang),Tarsius_wallacei),Tarsius_syrichta))),((((Cacajao_calvus,((Brachyteles_arachnoides,Chiropotes_albinasus),Chiropotes_israelita)),(((Sapajus_xanthosternos,(Cebus_albifrons,Cebus_apella)),((Callicebus_cupreus,Callicebus_lugens),(Ateles_geoffroyi,(((((Ateles_paniscus,Ateles_belzebuth),((Aotus_azarai,(Aotus_azarae,Aotus_lemurinus)),(Callithrix_jacchus,(Callithrix_pygmaea,Saguinus_oedipus)))),Callimico_goeldii),Lagothrix_lagotricha),Pithecia_pithecia)))),Callicebus_donacophilus)),(((((Saimiri_boliviensis,(Saimiri_oerstedii,Saimiri_sciureus)),Saimiri_sciureus_macrodon),Saimiri_oerstedii_citrinellus),(Leontopithecus_rosalia,Aotus_nancymaae)),(Aotus_trivirgatus,Aotus_azarae_azarai))),Alouatta_caraya)),(((Piliocolobus_badius,(Colobus_satanas,Colobus_guereza)),((Rhinopithecus_roxellana,(Presbytis_melalophos,(Rhinopithecus_brelichi,Rhinopithecus_avunculus))),(Rhinopithecus_bieti_2_RL2012,(Trachypithecus_johnii,(Trachypithecus_pileatus,((((Nasalis_larvatus,(Semnopithecus_entellus,Simias_concolor)),(Pygathrix_nigripes,Pygathrix_nemaeus)),(Trachypithecus_obscurus,Trachypithecus_francoisi)),Trachypithecus_cristatus)))))),(Procolobus_verus,((Miopithecus_ogouensis,(Cercopithecus_diana,(((Cercocebus_atys,Mandrillus_sphinx),Cercocebus_torquatus),(((Mandrillus_leucophaeus,Cercocebus_chrysogaster),Cercocebus_agilis),((((((Papio_ursinus,Papio_cynocephalus),Papio_kindae),(Papio_papio,(Papio_anubis,Papio_hamadryas))),((Macaca_assamensis,Macaca_thibetana),Macaca_silenus)),(Macaca_tonkeana,Macaca_fascicularis)),((Theropithecus_gelada,((Lophocebus_albigena,Lophocebus_aterrimus),Rungwecebus_kipunji)),(((Macaca_mulatta,Macaca_fuscata),((Macaca_nemestrina,(Erythrocebus_patas,Macaca_nigra)),Macaca_sylvanus)),Macaca_arctoides))))))),((((((((Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis),Cercopithecus_albogularis_moloneyi),((Cercopithecus_aethiops,Cercopithecus_ascanius_schmidti),((((Cercopithecus_petaurista,(Cercopithecus_petaurista_petaurista,(Cercopithecus_petaurista_buettikoferi,Cercopithecus_erythrogaster_pococki))),Cercopithecus_erythrogaster),Cercopithecus_cephus_cephus),((Cercopithecus_ascanius_katangae,Cercopithecus_erythrotis_camerunensis),(Cercopithecus_ascanius_whitesidei,(Cercopithecus_lhoesti,(Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi))))))),Cercopithecus_albogularis_albotorquatus),((Cercopithecus_nictitans_nictitans,Cercopithecus_nictitans),(((Cercopithecus_mitis,((Cercopithecus_kandti,(Cercopithecus_mitis_stuhlmanni,Cercopithecus_albogularis_kolbi)),Cercopithecus_doggetti)),(Cercopithecus_albogularis_francescae,Cercopithecus_mitis_heymansi)),(((((Cercopithecus_mitis_opisthostictus,Cercopithecus_albogularis_erythrarchus),Cercopithecus_mitis_boutourlinii),Cercopithecus_albogularis_labiatus),(Cercopithecus_albogularis,Cercopithecus_albogularis_monoides)),Cercopithecus_mitis_mitis)))),(Cercopithecus_neglectus,Chlorocebus_sabaeus)),((((Allenopithecus_nigroviridis,Cercopithecus_roloway),((((Cercopithecus_campbelli,Cercopithecus_mona),((Cercopithecus_pogonias_schwarzianus,((Cercopithecus_nictitans_martini,(Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans)),(Cercopithecus_pogonias_grayi,Cercopithecus_pogonias_nigripes))),Cercopithecus_pogonias)),Cercopithecus_hamlyni),Chlorocebus_cynosuros)),((Chlorocebus_pygerythrus,Chlorocebus_aethiops),Chlorocebus_tantalus)),Cercopithecus_dryas)),(Miopithecus_talapoin,Cercopithecus_solatus)))))),(Gorilla_gorilla,Gorilla_gorilla_gorilla)))),((Pan_troglodytes_ellioti,Homo_heidelbergensis),((Pan_troglodytes_troglodytes,Pan_troglodytes),Pan_paniscus)),Homo_sapiens); +(((Homo_heidelbergensis,Homo_sapiens_ssp_Denisova),(((((((((((Pithecia_pithecia,((Aotus_nancymaae,(Lagothrix_lagotricha,((((Callicebus_cupreus,((Callimico_goeldii,(Ateles_paniscus,(Ateles_geoffroyi,Ateles_belzebuth))),Callithrix_jacchus)),(Callicebus_donacophilus,(Brachyteles_arachnoides,Saguinus_oedipus))),Callicebus_lugens),Aotus_azarai))),Aotus_trivirgatus)),Aotus_azarae),(Leontopithecus_rosalia,((Callithrix_pygmaea,Alouatta_caraya),(Chiropotes_albinasus,(Aotus_azarae_azarai,Chiropotes_israelita))))),(Cebus_albifrons,(Sapajus_xanthosternos,Cebus_apella))),(Aotus_lemurinus,Cacajao_calvus)),((Saimiri_boliviensis,(Saimiri_oerstedii,Saimiri_sciureus)),(Saimiri_oerstedii_citrinellus,Saimiri_sciureus_macrodon))),((Tarsius_bancanus,((Lepilemur_ruficaudatus,Lepilemur_hubbardorum),(((((Varecia_variegata,Varecia_rubra),Propithecus_verreauxi),Eulemur_fulvus),Eulemur_macaco),(Eulemur_mongoz,Eulemur_rubriventer)))),((((((Perodicticus_potto,Perodicticus_potto_edwarsi),(((Galago_senegalensis,(Galago_moholi,Galagoides_demidoff)),Otolemur_crassicaudatus),Otolemur_garnettii)),((Loris_tardigradus,Loris_lydekkerianus),(Nycticebus_pygmaeus,(Nycticebus_bengalensis,Nycticebus_coucang)))),((((Prolemur_simus,(Lemur_catta,Hapalemur_griseus)),Eulemur_rufus),(Palaeopropithecus_ingens,(Megaladapis_edwardsi,Cheirogaleus_medius))),((Indri_indri,Propithecus_coquereli),Avahi_laniger))),Daubentonia_madagascariensis),(Tarsius_syrichta,(Tarsius_lariang,(Tarsius_dentatus,Tarsius_wallacei)))))),(((((Semnopithecus_entellus,((Presbytis_melalophos,((((((((Pygathrix_nemaeus,Simias_concolor),Pygathrix_nigripes),(Rhinopithecus_brelichi,Rhinopithecus_bieti_2_RL2012)),Rhinopithecus_roxellana),Nasalis_larvatus),(Trachypithecus_obscurus,((Trachypithecus_francoisi,Trachypithecus_cristatus),Trachypithecus_johnii))),Trachypithecus_pileatus),((Procolobus_verus,Piliocolobus_badius),(Colobus_guereza,Colobus_satanas)))),Rhinopithecus_avunculus)),((Allenopithecus_nigroviridis,(Cercopithecus_roloway,(((Cercopithecus_nictitans_martini,(Cercopithecus_pogonias,((Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans),((Cercopithecus_pogonias_nigripes,Cercopithecus_pogonias_grayi),Cercopithecus_pogonias_schwarzianus)))),(Cercopithecus_campbelli,Cercopithecus_mona)),(Cercopithecus_neglectus,((Cercopithecus_dryas,(((Cercopithecus_hamlyni,(Chlorocebus_pygerythrus,((Chlorocebus_cynosuros,Chlorocebus_aethiops),Chlorocebus_tantalus))),(Cercopithecus_aethiops,Cercopithecus_solatus)),Chlorocebus_sabaeus)),(Cercopithecus_lhoesti,(((Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi),(((Cercopithecus_albogularis_francescae,((((Cercopithecus_mitis_opisthostictus,Cercopithecus_mitis_mitis),Cercopithecus_nictitans),(((Cercopithecus_albogularis,Cercopithecus_albogularis_monoides),(((Cercopithecus_albogularis_labiatus,Cercopithecus_albogularis_erythrarchus),(Cercopithecus_albogularis_moloneyi,Cercopithecus_albogularis_albotorquatus)),Cercopithecus_mitis_boutourlinii)),(Cercopithecus_mitis,((Cercopithecus_doggetti,((Cercopithecus_mitis_stuhlmanni,Cercopithecus_albogularis_kolbi),Cercopithecus_mitis_heymansi)),Cercopithecus_kandti)))),Cercopithecus_nictitans_nictitans)),Cercopithecus_ascanius_whitesidei),((Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis),(((Cercopithecus_cephus_cephus,(Cercopithecus_petaurista,((Cercopithecus_petaurista_petaurista,(Cercopithecus_erythrogaster_pococki,Cercopithecus_petaurista_buettikoferi)),Cercopithecus_erythrogaster))),Cercopithecus_ascanius_katangae),Cercopithecus_erythrotis_camerunensis)))),Cercopithecus_ascanius_schmidti))))))),(((((((Papio_ursinus,(((Papio_anubis,(Papio_hamadryas,(Papio_papio,Papio_kindae))),Rungwecebus_kipunji),Papio_cynocephalus)),Cercocebus_atys),((Macaca_fascicularis,(Macaca_tonkeana,Macaca_silenus)),((((Macaca_nemestrina,((Macaca_fuscata,Macaca_mulatta),Macaca_nigra)),Macaca_sylvanus),Macaca_arctoides),(Macaca_assamensis,Macaca_thibetana)))),(Theropithecus_gelada,Lophocebus_aterrimus)),(Cercocebus_agilis,(Mandrillus_sphinx,((Mandrillus_leucophaeus,Cercocebus_chrysogaster),Cercocebus_torquatus)))),Erythrocebus_patas),Lophocebus_albigena))),Cercopithecus_diana),Miopithecus_talapoin),Miopithecus_ogouensis)),(((Nomascus_leucogenys,(Symphalangus_syndactylus,(Hylobates_agilis,Hylobates_lar))),Hylobates_moloch),(Pongo_pygmaeus,Pongo_abelii))),Gorilla_gorilla),Gorilla_gorilla_gorilla)),(Pan_troglodytes_ellioti,(Pan_paniscus,(Pan_troglodytes_troglodytes,Pan_troglodytes))),Homo_sapiens); +((((((((Pithecia_pithecia,Cacajao_calvus),((((Callicebus_donacophilus,(((Callithrix_jacchus,Ateles_belzebuth),(Callicebus_cupreus,Callicebus_lugens)),(((Aotus_azarai,(Aotus_azarae_azarai,((Aotus_trivirgatus,Aotus_azarae),Aotus_nancymaae))),Aotus_lemurinus),(Callithrix_pygmaea,Saguinus_oedipus)))),((Sapajus_xanthosternos,Cebus_apella),Cebus_albifrons)),(((Alouatta_caraya,Brachyteles_arachnoides),Chiropotes_albinasus),Chiropotes_israelita)),((Callimico_goeldii,Leontopithecus_rosalia),((Ateles_geoffroyi,Ateles_paniscus),Lagothrix_lagotricha)))),(((Saimiri_sciureus,(Saimiri_boliviensis,Saimiri_oerstedii)),Saimiri_sciureus_macrodon),Saimiri_oerstedii_citrinellus)),((Tarsius_bancanus,((((Eulemur_rubriventer,(Eulemur_fulvus,(Varecia_variegata,Varecia_rubra))),Eulemur_macaco),Eulemur_mongoz),(Propithecus_verreauxi,(Lepilemur_ruficaudatus,Lepilemur_hubbardorum)))),((Tarsius_syrichta,(Tarsius_wallacei,(Tarsius_lariang,Tarsius_dentatus))),(((((Avahi_laniger,(Propithecus_coquereli,Indri_indri)),((((Megaladapis_edwardsi,Cheirogaleus_medius),(Prolemur_simus,(Lemur_catta,Hapalemur_griseus))),Eulemur_rufus),Palaeopropithecus_ingens)),Daubentonia_madagascariensis),Galago_senegalensis),((Galago_moholi,(Otolemur_crassicaudatus,(Perodicticus_potto,(Otolemur_garnettii,((Loris_lydekkerianus,(Galagoides_demidoff,Loris_tardigradus)),(Nycticebus_pygmaeus,(Nycticebus_bengalensis,Nycticebus_coucang))))))),Perodicticus_potto_edwarsi))))),(((((((Trachypithecus_obscurus,(Trachypithecus_johnii,Trachypithecus_pileatus)),(Trachypithecus_francoisi,Trachypithecus_cristatus)),(Rhinopithecus_roxellana,((((Pygathrix_nemaeus,Pygathrix_nigripes),(Simias_concolor,Nasalis_larvatus)),Rhinopithecus_brelichi),Rhinopithecus_bieti_2_RL2012))),Rhinopithecus_avunculus),(Presbytis_melalophos,Semnopithecus_entellus)),((Procolobus_verus,Piliocolobus_badius),(Colobus_guereza,Colobus_satanas))),(Miopithecus_ogouensis,(Miopithecus_talapoin,((((((Cercopithecus_dryas,((((Cercopithecus_aethiops,Cercopithecus_solatus),Chlorocebus_tantalus),((Chlorocebus_sabaeus,Chlorocebus_aethiops),Chlorocebus_pygerythrus)),(Chlorocebus_cynosuros,Cercopithecus_hamlyni))),Cercopithecus_roloway),((((Cercopithecus_albogularis_moloneyi,(Cercopithecus_albogularis_albotorquatus,(Cercopithecus_albogularis,((Cercopithecus_mitis_boutourlinii,Cercopithecus_albogularis_erythrarchus),(Cercopithecus_albogularis_labiatus,((((Cercopithecus_nictitans,Cercopithecus_nictitans_nictitans),(((Cercopithecus_kandti,(Cercopithecus_mitis_stuhlmanni,Cercopithecus_albogularis_kolbi)),((Cercopithecus_albogularis_francescae,Cercopithecus_mitis_heymansi),Cercopithecus_doggetti)),Cercopithecus_mitis)),(Cercopithecus_mitis_opisthostictus,Cercopithecus_mitis_mitis)),Cercopithecus_albogularis_monoides)))))),Cercopithecus_cephus),Cercopithecus_cephus_ngottoensis),(((Cercopithecus_lhoesti,(Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi)),(Cercopithecus_ascanius_whitesidei,((Cercopithecus_erythrotis_camerunensis,Cercopithecus_ascanius_katangae),((Cercopithecus_erythrogaster,Cercopithecus_erythrogaster_pococki),((Cercopithecus_cephus_cephus,Cercopithecus_petaurista),(Cercopithecus_petaurista_petaurista,Cercopithecus_petaurista_buettikoferi)))))),Cercopithecus_ascanius_schmidti))),Cercopithecus_neglectus),((((Cercopithecus_pogonias_grayi,(Cercopithecus_pogonias_schwarzianus,Cercopithecus_pogonias_nigripes)),Cercopithecus_wolfi_elegans),((Cercopithecus_nictitans_martini,Cercopithecus_pogonias),Cercopithecus_wolfi_pyrogaster)),(Cercopithecus_campbelli,Cercopithecus_mona))),(Cercopithecus_diana,(((Macaca_fuscata,Macaca_mulatta),(Macaca_nigra,((Macaca_nemestrina,((Macaca_silenus,(Macaca_assamensis,Macaca_thibetana)),(Macaca_tonkeana,Macaca_fascicularis))),Macaca_arctoides))),(((Erythrocebus_patas,(Macaca_sylvanus,Allenopithecus_nigroviridis)),(((Lophocebus_albigena,Lophocebus_aterrimus),(Rungwecebus_kipunji,Theropithecus_gelada)),((Papio_cynocephalus,Papio_kindae),((Papio_papio,(Papio_anubis,Papio_hamadryas)),Papio_ursinus)))),(((((Mandrillus_sphinx,Cercocebus_atys),Cercocebus_torquatus),Cercocebus_agilis),Mandrillus_leucophaeus),Cercocebus_chrysogaster))))))))),((Nomascus_leucogenys,(Hylobates_moloch,(Pongo_pygmaeus,Pongo_abelii))),((Hylobates_lar,Symphalangus_syndactylus),Hylobates_agilis))),Gorilla_gorilla_gorilla),(Pan_paniscus,((((Pan_troglodytes_troglodytes,(Pan_troglodytes_ellioti,Homo_heidelbergensis)),Homo_sapiens_ssp_Denisova),Pan_troglodytes),Gorilla_gorilla)),Homo_sapiens); +(((((Pongo_pygmaeus,Pongo_abelii),((Hylobates_moloch,Nomascus_leucogenys),Hylobates_lar)),(Hylobates_agilis,((((Callimico_goeldii,(Alouatta_caraya,((((Aotus_azarai,Aotus_lemurinus),(Aotus_nancymaae,((Callithrix_jacchus,Callithrix_pygmaea),Saguinus_oedipus))),((((Ateles_paniscus,(Callicebus_donacophilus,(Ateles_belzebuth,(Brachyteles_arachnoides,Callicebus_cupreus)))),Ateles_geoffroyi),Callicebus_lugens),((((Aotus_azarae,(Aotus_azarae_azarai,(Cacajao_calvus,(Aotus_trivirgatus,(Pithecia_pithecia,(Chiropotes_albinasus,Chiropotes_israelita)))))),Lagothrix_lagotricha),(((Saimiri_sciureus,(Saimiri_boliviensis,Saimiri_oerstedii)),Saimiri_sciureus_macrodon),Saimiri_oerstedii_citrinellus)),(Sapajus_xanthosternos,(Cebus_apella,Cebus_albifrons))))),Leontopithecus_rosalia))),(((((Eulemur_rubriventer,(Varecia_variegata,Varecia_rubra)),(Eulemur_macaco,(Eulemur_mongoz,(Eulemur_fulvus,Propithecus_verreauxi)))),(Lepilemur_ruficaudatus,Lepilemur_hubbardorum)),Tarsius_bancanus),((((Lemur_catta,(Propithecus_coquereli,Daubentonia_madagascariensis)),((((Prolemur_simus,(Hapalemur_griseus,Cheirogaleus_medius)),Eulemur_rufus),(Megaladapis_edwardsi,Palaeopropithecus_ingens)),(Indri_indri,Avahi_laniger))),(Nycticebus_pygmaeus,((((Otolemur_crassicaudatus,Otolemur_garnettii),((Galago_senegalensis,Galago_moholi),Galagoides_demidoff)),(Loris_lydekkerianus,Loris_tardigradus)),((Perodicticus_potto,Perodicticus_potto_edwarsi),(Nycticebus_bengalensis,Nycticebus_coucang))))),(Tarsius_syrichta,(Tarsius_lariang,(Tarsius_dentatus,Tarsius_wallacei)))))),(((((Rhinopithecus_brelichi,(Rhinopithecus_avunculus,Rhinopithecus_bieti_2_RL2012)),Presbytis_melalophos),((((Trachypithecus_pileatus,Trachypithecus_cristatus),((Trachypithecus_johnii,Trachypithecus_francoisi),Trachypithecus_obscurus)),((Pygathrix_nemaeus,Pygathrix_nigripes),((Simias_concolor,Semnopithecus_entellus),Nasalis_larvatus))),Rhinopithecus_roxellana)),(((Colobus_guereza,Colobus_satanas),Piliocolobus_badius),Procolobus_verus)),((((((((Cercopithecus_nictitans_martini,((Miopithecus_ogouensis,(Cercopithecus_campbelli,Cercopithecus_mona)),(((Cercopithecus_aethiops,(((Cercopithecus_dryas,Cercopithecus_solatus),Chlorocebus_sabaeus),(Chlorocebus_pygerythrus,(Chlorocebus_aethiops,((Chlorocebus_cynosuros,Cercopithecus_hamlyni),Chlorocebus_tantalus))))),Cercopithecus_neglectus),(((Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis),((Cercopithecus_erythrogaster,(Cercopithecus_petaurista,(((Cercopithecus_petaurista_buettikoferi,Cercopithecus_erythrogaster_pococki),((Cercopithecus_cephus_cephus,Cercopithecus_ascanius_schmidti),Cercopithecus_petaurista_petaurista)),(Cercopithecus_ascanius_whitesidei,((Cercopithecus_lhoesti,(Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi)),(Cercopithecus_erythrotis_camerunensis,Cercopithecus_ascanius_katangae)))))),(Cercopithecus_albogularis_moloneyi,((((Cercopithecus_mitis_stuhlmanni,(((Cercopithecus_mitis_mitis,(Cercopithecus_nictitans_nictitans,(Cercopithecus_nictitans,Cercopithecus_albogularis_kolbi))),Cercopithecus_mitis_heymansi),((Cercopithecus_mitis_opisthostictus,Cercopithecus_kandti),Cercopithecus_doggetti))),Cercopithecus_mitis),Cercopithecus_albogularis_francescae),(((Cercopithecus_mitis_boutourlinii,((Cercopithecus_albogularis_labiatus,Cercopithecus_albogularis_monoides),Cercopithecus_albogularis_erythrarchus)),Cercopithecus_albogularis),Cercopithecus_albogularis_albotorquatus))))),((Cercopithecus_diana,((Allenopithecus_nigroviridis,(Erythrocebus_patas,(Macaca_sylvanus,((((((Macaca_fascicularis,(((Macaca_fuscata,(Macaca_nemestrina,Macaca_nigra)),Macaca_arctoides),(Macaca_assamensis,Macaca_thibetana))),(Macaca_tonkeana,Macaca_silenus)),(((Papio_papio,(Papio_anubis,Papio_hamadryas)),(Papio_cynocephalus,Papio_ursinus)),Papio_kindae)),(Theropithecus_gelada,Lophocebus_aterrimus)),Rungwecebus_kipunji),((Mandrillus_leucophaeus,(Mandrillus_sphinx,(Cercocebus_agilis,(Cercocebus_torquatus,Cercocebus_atys)))),Cercocebus_chrysogaster))))),(Cercopithecus_roloway,Macaca_mulatta))),Miopithecus_talapoin))))),Cercopithecus_wolfi_elegans),Cercopithecus_pogonias_nigripes),Cercopithecus_wolfi_pyrogaster),Cercopithecus_pogonias_grayi),Cercopithecus_pogonias),Lophocebus_albigena),Cercopithecus_pogonias_schwarzianus))),Symphalangus_syndactylus))),((Gorilla_gorilla_gorilla,(Homo_sapiens_ssp_Denisova,Homo_heidelbergensis)),Gorilla_gorilla)),(((Pan_paniscus,Pan_troglodytes_troglodytes),Pan_troglodytes),Pan_troglodytes_ellioti),Homo_sapiens); +((Homo_sapiens_ssp_Denisova,((Gorilla_gorilla,((((Alouatta_caraya,(((((Aotus_nancymaae,Leontopithecus_rosalia),(Aotus_azarae_azarai,Aotus_azarae)),(Aotus_lemurinus,(Aotus_trivirgatus,((((Saimiri_boliviensis,(Saimiri_oerstedii,Saimiri_sciureus)),Saimiri_sciureus_macrodon),Saimiri_oerstedii_citrinellus),Aotus_azarai)))),((Callimico_goeldii,((Ateles_geoffroyi,(Callicebus_donacophilus,(Pithecia_pithecia,(Callicebus_cupreus,Callicebus_lugens)))),Lagothrix_lagotricha)),((Ateles_belzebuth,(Cacajao_calvus,(Ateles_paniscus,((Brachyteles_arachnoides,Chiropotes_albinasus),Chiropotes_israelita)))),(Cebus_albifrons,(Sapajus_xanthosternos,Cebus_apella))))),((Callithrix_jacchus,Callithrix_pygmaea),Saguinus_oedipus))),((((((((Galagoides_demidoff,(Otolemur_garnettii,Otolemur_crassicaudatus)),(Galago_senegalensis,Galago_moholi)),(Perodicticus_potto,((Nycticebus_bengalensis,(Nycticebus_pygmaeus,Nycticebus_coucang)),(Loris_lydekkerianus,Loris_tardigradus)))),Perodicticus_potto_edwarsi),Daubentonia_madagascariensis),((Propithecus_coquereli,(Avahi_laniger,Indri_indri)),((((Megaladapis_edwardsi,Cheirogaleus_medius),((Prolemur_simus,Hapalemur_griseus),Eulemur_rufus)),Lemur_catta),Palaeopropithecus_ingens))),(Tarsius_syrichta,(Tarsius_lariang,(Tarsius_dentatus,Tarsius_wallacei)))),(((Lepilemur_ruficaudatus,Lepilemur_hubbardorum),(Propithecus_verreauxi,((Eulemur_fulvus,(Varecia_rubra,Varecia_variegata)),((Eulemur_rubriventer,Eulemur_mongoz),Eulemur_macaco)))),Tarsius_bancanus))),((Lophocebus_albigena,((((Semnopithecus_entellus,Presbytis_melalophos),Rhinopithecus_avunculus),((Trachypithecus_cristatus,Trachypithecus_pileatus),((Trachypithecus_francoisi,(Pygathrix_nemaeus,(((Pygathrix_nigripes,Rhinopithecus_bieti_2_RL2012),Rhinopithecus_brelichi),(Rhinopithecus_roxellana,(Nasalis_larvatus,Simias_concolor))))),(Trachypithecus_johnii,Trachypithecus_obscurus)))),((Piliocolobus_badius,(Colobus_guereza,Colobus_satanas)),Procolobus_verus))),(Miopithecus_ogouensis,(Miopithecus_talapoin,(((Cercopithecus_aethiops,(Chlorocebus_sabaeus,(((Chlorocebus_tantalus,((Cercopithecus_dryas,Chlorocebus_pygerythrus),Chlorocebus_cynosuros)),Cercopithecus_solatus),(Cercopithecus_hamlyni,Chlorocebus_aethiops)))),Cercopithecus_neglectus),(((((Cercopithecus_pogonias_grayi,(((Cercopithecus_pogonias,Cercopithecus_pogonias_schwarzianus),(Cercopithecus_nictitans_martini,(Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans))),Cercopithecus_pogonias_nigripes)),(Cercopithecus_campbelli,Cercopithecus_mona)),(Erythrocebus_patas,Cercopithecus_diana)),((Allenopithecus_nigroviridis,(Macaca_sylvanus,((Cercocebus_agilis,(Mandrillus_leucophaeus,((Mandrillus_sphinx,Cercocebus_torquatus),Cercocebus_chrysogaster))),((Theropithecus_gelada,(((Macaca_arctoides,(Macaca_mulatta,Macaca_fuscata)),((((Macaca_assamensis,Macaca_thibetana),(Macaca_tonkeana,Macaca_silenus)),(Macaca_nemestrina,Macaca_nigra)),Macaca_fascicularis)),(((Rungwecebus_kipunji,Papio_ursinus),(Papio_cynocephalus,Papio_kindae)),((Cercocebus_atys,Papio_papio),(Papio_anubis,Papio_hamadryas))))),Lophocebus_aterrimus)))),((Cercopithecus_lhoesti,(Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi)),Cercopithecus_roloway))),((((Cercopithecus_albogularis_moloneyi,(((Cercopithecus_mitis_mitis,Cercopithecus_mitis_opisthostictus),(Cercopithecus_nictitans_nictitans,Cercopithecus_nictitans)),(Cercopithecus_mitis,((Cercopithecus_mitis_heymansi,Cercopithecus_albogularis_francescae),(((Cercopithecus_albogularis_kolbi,Cercopithecus_mitis_stuhlmanni),Cercopithecus_doggetti),Cercopithecus_kandti))))),(((Cercopithecus_albogularis,Cercopithecus_albogularis_monoides),(Cercopithecus_albogularis_labiatus,(Cercopithecus_albogularis_erythrarchus,Cercopithecus_mitis_boutourlinii))),Cercopithecus_albogularis_albotorquatus)),(((((Cercopithecus_erythrogaster_pococki,(((Cercopithecus_petaurista_buettikoferi,Cercopithecus_petaurista_petaurista),Cercopithecus_petaurista),Cercopithecus_erythrogaster)),Cercopithecus_cephus_cephus),(Cercopithecus_erythrotis_camerunensis,Cercopithecus_ascanius_katangae)),Cercopithecus_ascanius_whitesidei),(Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis))),Cercopithecus_ascanius_schmidti))))))),Gorilla_gorilla_gorilla)),(Hylobates_moloch,(Nomascus_leucogenys,(((Symphalangus_syndactylus,Hylobates_agilis),(Pongo_pygmaeus,Pongo_abelii)),Hylobates_lar))))),((Pan_troglodytes_ellioti,Homo_heidelbergensis),(Pan_paniscus,(Pan_troglodytes_troglodytes,Pan_troglodytes))),Homo_sapiens); +(((Pan_paniscus,(Pan_troglodytes_troglodytes,Pan_troglodytes)),(Homo_sapiens_ssp_Denisova,(Homo_heidelbergensis,(Gorilla_gorilla_gorilla,((((((Nomascus_leucogenys,((Hylobates_lar,Symphalangus_syndactylus),Hylobates_agilis)),Hylobates_moloch),Pongo_abelii),(((Alouatta_caraya,(((Saguinus_oedipus,Callithrix_pygmaea),Aotus_nancymaae),((((((Saimiri_sciureus,(Saimiri_oerstedii,Saimiri_boliviensis)),Saimiri_sciureus_macrodon),Saimiri_oerstedii_citrinellus),(Aotus_azarai,Aotus_lemurinus)),((Aotus_trivirgatus,(Leontopithecus_rosalia,(Pithecia_pithecia,((Aotus_azarae,Aotus_azarae_azarai),((Cacajao_calvus,Chiropotes_albinasus),Chiropotes_israelita))))),(Sapajus_xanthosternos,(Cebus_apella,Cebus_albifrons)))),((((((Callithrix_jacchus,Brachyteles_arachnoides),Callicebus_donacophilus),(Callimico_goeldii,(Ateles_paniscus,(Ateles_geoffroyi,Ateles_belzebuth)))),Callicebus_cupreus),Callicebus_lugens),Lagothrix_lagotricha)))),((((((((Propithecus_coquereli,(Avahi_laniger,Indri_indri)),((Prolemur_simus,(Cheirogaleus_medius,(Lemur_catta,Hapalemur_griseus))),(Eulemur_rufus,Palaeopropithecus_ingens))),(((((Galagoides_demidoff,Otolemur_garnettii),(Galago_senegalensis,Otolemur_crassicaudatus)),Galago_moholi),(((Nycticebus_pygmaeus,Nycticebus_coucang),Nycticebus_bengalensis),(Loris_lydekkerianus,Loris_tardigradus))),(Perodicticus_potto,Perodicticus_potto_edwarsi))),Daubentonia_madagascariensis),Megaladapis_edwardsi),Tarsius_bancanus),(Tarsius_syrichta,(Tarsius_lariang,(Tarsius_dentatus,Tarsius_wallacei)))),((Eulemur_macaco,(Propithecus_verreauxi,Eulemur_fulvus)),(((Eulemur_mongoz,Eulemur_rubriventer),(Varecia_rubra,Varecia_variegata)),(Lepilemur_ruficaudatus,Lepilemur_hubbardorum))))),((Lophocebus_albigena,((((Rhinopithecus_bieti_2_RL2012,Rhinopithecus_brelichi),(Rhinopithecus_roxellana,(Trachypithecus_cristatus,((((((Semnopithecus_entellus,(Nasalis_larvatus,Simias_concolor)),(Pygathrix_nemaeus,Pygathrix_nigripes)),Trachypithecus_francoisi),Trachypithecus_obscurus),Trachypithecus_johnii),Trachypithecus_pileatus)))),((Colobus_guereza,Colobus_satanas),(Procolobus_verus,Piliocolobus_badius))),(Presbytis_melalophos,Rhinopithecus_avunculus))),(Miopithecus_ogouensis,(Miopithecus_talapoin,(((Erythrocebus_patas,(((Cercocebus_torquatus,Cercocebus_chrysogaster),(((Cercocebus_atys,Mandrillus_sphinx),Cercocebus_agilis),Mandrillus_leucophaeus)),(((Macaca_silenus,(Macaca_sylvanus,(Macaca_assamensis,Macaca_thibetana))),(((Macaca_tonkeana,Macaca_arctoides),Macaca_fascicularis),(Macaca_nemestrina,((Macaca_mulatta,Macaca_fuscata),Macaca_nigra)))),(((((Papio_papio,Papio_kindae),((Papio_anubis,(Papio_ursinus,Papio_cynocephalus)),Papio_hamadryas)),Theropithecus_gelada),Lophocebus_aterrimus),Rungwecebus_kipunji)))),(((((Cercopithecus_albogularis_moloneyi,(((Cercopithecus_albogularis_francescae,(((Cercopithecus_mitis_heymansi,(Cercopithecus_albogularis_kolbi,Cercopithecus_mitis_stuhlmanni)),Cercopithecus_kandti),Cercopithecus_doggetti)),Cercopithecus_mitis),(Cercopithecus_nictitans,((Cercopithecus_mitis_mitis,Cercopithecus_mitis_opisthostictus),Cercopithecus_nictitans_nictitans)))),(((Cercopithecus_albogularis_albotorquatus,(Cercopithecus_albogularis,Cercopithecus_albogularis_monoides)),(Cercopithecus_albogularis_erythrarchus,Cercopithecus_mitis_boutourlinii)),Cercopithecus_albogularis_labiatus)),((((((Cercopithecus_hamlyni,Chlorocebus_aethiops),(Chlorocebus_tantalus,Chlorocebus_cynosuros)),Chlorocebus_pygerythrus),((Chlorocebus_sabaeus,Cercopithecus_aethiops),Cercopithecus_solatus)),Cercopithecus_dryas),((((Cercopithecus_neglectus,Cercopithecus_cephus),Cercopithecus_cephus_ngottoensis),((Cercopithecus_nictitans_martini,((((Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans),Cercopithecus_pogonias_grayi),Cercopithecus_pogonias_schwarzianus),(Cercopithecus_pogonias,Cercopithecus_pogonias_nigripes))),(Cercopithecus_campbelli,Cercopithecus_mona))),(Cercopithecus_ascanius_schmidti,((Cercopithecus_erythrotis_camerunensis,(Cercopithecus_lhoesti,(Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi))),((((Cercopithecus_petaurista_petaurista,(Cercopithecus_petaurista_buettikoferi,Cercopithecus_erythrogaster_pococki)),(Cercopithecus_petaurista,Cercopithecus_erythrogaster)),(Cercopithecus_ascanius_katangae,Cercopithecus_cephus_cephus)),Cercopithecus_ascanius_whitesidei)))))),Cercopithecus_roloway),Allenopithecus_nigroviridis)),Cercopithecus_diana)))))),Gorilla_gorilla),Pongo_pygmaeus))))),Pan_troglodytes_ellioti,Homo_sapiens); +((Homo_sapiens_ssp_Denisova,((((Hylobates_moloch,((Alouatta_caraya,(((Saguinus_oedipus,Callithrix_pygmaea),(((((Cacajao_calvus,Chiropotes_albinasus),Chiropotes_israelita),(Leontopithecus_rosalia,Callimico_goeldii)),((((Aotus_nancymaae,((Saimiri_sciureus_macrodon,((Saimiri_boliviensis,Saimiri_oerstedii),Saimiri_sciureus)),Saimiri_oerstedii_citrinellus)),(Aotus_azarae,(Aotus_trivirgatus,((Aotus_lemurinus,Aotus_azarai),Aotus_azarae_azarai)))),Ateles_belzebuth),(((((((Callicebus_lugens,Callicebus_cupreus),Lagothrix_lagotricha),Callicebus_donacophilus),Ateles_geoffroyi),Pithecia_pithecia),Callithrix_jacchus),(Cebus_albifrons,(Sapajus_xanthosternos,Cebus_apella))))),Ateles_paniscus)),Brachyteles_arachnoides)),((((Presbytis_melalophos,((((Procolobus_verus,Piliocolobus_badius),(((((Lophocebus_albigena,Rhinopithecus_bieti_2_RL2012),(Colobus_guereza,Colobus_satanas)),(((Pygathrix_nemaeus,Pygathrix_nigripes),(Simias_concolor,Nasalis_larvatus)),Rhinopithecus_roxellana)),Rhinopithecus_brelichi),((Trachypithecus_obscurus,(Trachypithecus_francoisi,Trachypithecus_cristatus)),Trachypithecus_pileatus))),Rhinopithecus_avunculus),Semnopithecus_entellus)),Trachypithecus_johnii),(((((Erythrocebus_patas,(((Cercopithecus_roloway,(Cercopithecus_albogularis,((Cercopithecus_mitis,(((Cercopithecus_doggetti,(Cercopithecus_albogularis_moloneyi,Cercopithecus_albogularis_francescae)),(((Cercopithecus_albogularis_kolbi,Cercopithecus_mitis_heymansi),((Cercopithecus_mitis_opisthostictus,(Cercopithecus_albogularis_albotorquatus,(((Cercopithecus_albogularis_labiatus,Cercopithecus_albogularis_monoides),Cercopithecus_mitis_boutourlinii),Cercopithecus_albogularis_erythrarchus))),Cercopithecus_mitis_mitis)),Cercopithecus_kandti)),Cercopithecus_mitis_stuhlmanni)),Cercopithecus_nictitans_nictitans))),Cercopithecus_diana),Cercopithecus_nictitans)),Cercopithecus_nictitans_martini),(Allenopithecus_nigroviridis,(((Cercocebus_agilis,(Mandrillus_leucophaeus,Cercocebus_torquatus)),Cercocebus_chrysogaster),((Cercocebus_atys,((Macaca_fascicularis,((Macaca_sylvanus,(Macaca_assamensis,Macaca_thibetana)),((((Macaca_mulatta,Macaca_fuscata),Macaca_nigra),Macaca_arctoides),Macaca_nemestrina))),(Macaca_silenus,Macaca_tonkeana))),(((Rungwecebus_kipunji,(((((Papio_anubis,Papio_hamadryas),Papio_papio),Papio_cynocephalus),Papio_kindae),Papio_ursinus)),Theropithecus_gelada),Lophocebus_aterrimus))))),(((Cercopithecus_ascanius_schmidti,((((Cercopithecus_lhoesti,(Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi)),(Cercopithecus_ascanius_katangae,Cercopithecus_erythrotis_camerunensis)),Cercopithecus_ascanius_whitesidei),(((Cercopithecus_erythrogaster,(Mandrillus_sphinx,Cercopithecus_erythrogaster_pococki)),((Cercopithecus_petaurista_petaurista,Cercopithecus_petaurista_buettikoferi),Cercopithecus_neglectus)),Cercopithecus_cephus_cephus))),((Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis),((Cercopithecus_pogonias_grayi,((Cercopithecus_pogonias,Cercopithecus_wolfi_pyrogaster),Cercopithecus_pogonias_schwarzianus)),(Cercopithecus_pogonias_nigripes,Cercopithecus_wolfi_elegans)))),((Cercopithecus_campbelli,Cercopithecus_mona),Miopithecus_ogouensis))),((Cercopithecus_petaurista,((((Chlorocebus_tantalus,(Chlorocebus_pygerythrus,(Chlorocebus_aethiops,Chlorocebus_sabaeus))),(Cercopithecus_solatus,Cercopithecus_aethiops)),(Chlorocebus_cynosuros,Cercopithecus_hamlyni)),Cercopithecus_dryas)),Miopithecus_talapoin))),(((((Daubentonia_madagascariensis,(Avahi_laniger,((Propithecus_coquereli,Indri_indri),((Cheirogaleus_medius,((Lemur_catta,Hapalemur_griseus),(Prolemur_simus,Eulemur_rufus))),(Megaladapis_edwardsi,Palaeopropithecus_ingens))))),((((Galago_moholi,Galago_senegalensis),(Galagoides_demidoff,(Otolemur_crassicaudatus,Otolemur_garnettii))),(((Nycticebus_pygmaeus,Nycticebus_coucang),Nycticebus_bengalensis),(Loris_lydekkerianus,Loris_tardigradus))),(Perodicticus_potto,Perodicticus_potto_edwarsi))),(Tarsius_syrichta,(Tarsius_lariang,(Tarsius_dentatus,Tarsius_wallacei)))),Tarsius_bancanus),(((Lepilemur_ruficaudatus,Lepilemur_hubbardorum),((Eulemur_macaco,(Eulemur_mongoz,(Eulemur_fulvus,(Varecia_rubra,Varecia_variegata)))),Eulemur_rubriventer)),Propithecus_verreauxi))))),(((Hylobates_agilis,((Pongo_pygmaeus,Pongo_abelii),Nomascus_leucogenys)),Symphalangus_syndactylus),Hylobates_lar)),Gorilla_gorilla_gorilla),(Pan_paniscus,(Pan_troglodytes_troglodytes,Gorilla_gorilla)))),((Homo_heidelbergensis,Pan_troglodytes_ellioti),Pan_troglodytes),Homo_sapiens); +(((Pan_paniscus,((Pan_troglodytes_troglodytes,Pan_troglodytes),Lophocebus_albigena)),(Homo_heidelbergensis,Pan_troglodytes_ellioti)),(Homo_sapiens_ssp_Denisova,((Hylobates_lar,(Gorilla_gorilla,(Gorilla_gorilla_gorilla,((Cercopithecus_petaurista,(((Miopithecus_ogouensis,(Cercopithecus_diana,((((((Cercocebus_atys,Cercocebus_torquatus),Mandrillus_leucophaeus),Cercocebus_agilis),Cercocebus_chrysogaster),((((Macaca_assamensis,Macaca_thibetana),((Macaca_fuscata,Macaca_nigra),((Macaca_sylvanus,(Macaca_mulatta,Macaca_nemestrina)),Macaca_arctoides))),(Macaca_fascicularis,(Macaca_silenus,Macaca_tonkeana))),((Papio_kindae,(Papio_papio,Papio_cynocephalus)),(Theropithecus_gelada,(Rungwecebus_kipunji,((Papio_ursinus,Lophocebus_aterrimus),(Papio_hamadryas,Papio_anubis))))))),Erythrocebus_patas))),(((((Chlorocebus_cynosuros,Chlorocebus_sabaeus),Chlorocebus_tantalus),(Cercopithecus_aethiops,Chlorocebus_pygerythrus)),((((((((Cercopithecus_mitis_opisthostictus,Cercopithecus_albogularis_moloneyi),(Cercopithecus_mitis_mitis,(((Cercopithecus_nictitans,Cercopithecus_nictitans_nictitans),Cercopithecus_albogularis_monoides),((Cercopithecus_mitis_boutourlinii,Cercopithecus_albogularis_albotorquatus),(Cercopithecus_albogularis_erythrarchus,Cercopithecus_albogularis_labiatus))))),(((Cercopithecus_doggetti,(Cercopithecus_albogularis_kolbi,Cercopithecus_mitis_stuhlmanni)),((Cercopithecus_mitis_heymansi,Cercopithecus_albogularis_francescae),Cercopithecus_kandti)),Cercopithecus_mitis)),((Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis),((Cercopithecus_lhoesti,(Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi)),((((Mandrillus_sphinx,Cercopithecus_cephus_cephus),Cercopithecus_ascanius_katangae),(((Cercopithecus_petaurista_petaurista,(Cercopithecus_petaurista_buettikoferi,Cercopithecus_erythrogaster_pococki)),Cercopithecus_erythrogaster),Cercopithecus_erythrotis_camerunensis)),(Cercopithecus_neglectus,Cercopithecus_ascanius_whitesidei))))),Cercopithecus_albogularis),((Cercopithecus_dryas,(((Cercopithecus_wolfi_elegans,(Cercopithecus_pogonias_nigripes,(Cercopithecus_wolfi_pyrogaster,(Cercopithecus_pogonias_schwarzianus,Cercopithecus_pogonias_grayi)))),Cercopithecus_nictitans_martini),((Cercopithecus_campbelli,Cercopithecus_mona),Cercopithecus_pogonias))),(Cercopithecus_roloway,Allenopithecus_nigroviridis))),Cercopithecus_ascanius_schmidti),(Chlorocebus_aethiops,Cercopithecus_hamlyni))),Cercopithecus_solatus)),Miopithecus_talapoin)),(Procolobus_verus,(((Rhinopithecus_avunculus,Presbytis_melalophos),Semnopithecus_entellus),(((((((((Otolemur_garnettii,(Galagoides_demidoff,(Otolemur_crassicaudatus,(Perodicticus_potto,(((Nycticebus_pygmaeus,Nycticebus_coucang),Nycticebus_bengalensis),Loris_lydekkerianus))))),Perodicticus_potto_edwarsi),Galago_moholi),(Galago_senegalensis,(Daubentonia_madagascariensis,Tarsius_bancanus))),((Propithecus_verreauxi,(Avahi_laniger,Loris_tardigradus)),(Propithecus_coquereli,(Indri_indri,(((Eulemur_rufus,((Lepilemur_ruficaudatus,Lepilemur_hubbardorum),Palaeopropithecus_ingens)),Megaladapis_edwardsi),(((((Lemur_catta,Varecia_variegata),Varecia_rubra),Hapalemur_griseus),Prolemur_simus),(Eulemur_rubriventer,(Eulemur_mongoz,((Eulemur_macaco,Cheirogaleus_medius),Eulemur_fulvus))))))))),(Tarsius_syrichta,(Tarsius_lariang,(Tarsius_dentatus,Tarsius_wallacei)))),(Alouatta_caraya,((((Callicebus_donacophilus,((((Sapajus_xanthosternos,(Pithecia_pithecia,(Cebus_apella,Cebus_albifrons))),((Ateles_belzebuth,(Ateles_paniscus,(Cacajao_calvus,(((Brachyteles_arachnoides,Chiropotes_israelita),Chiropotes_albinasus),Ateles_geoffroyi)))),Callimico_goeldii)),(Leontopithecus_rosalia,(Saimiri_oerstedii_citrinellus,((Saimiri_oerstedii,(Saimiri_sciureus,(Aotus_trivirgatus,(Aotus_azarae_azarai,((Aotus_azarae,((Aotus_lemurinus,Aotus_azarai),Saimiri_sciureus_macrodon)),Saimiri_boliviensis))))),Aotus_nancymaae)))),(Callicebus_lugens,Callicebus_cupreus))),Lagothrix_lagotricha),Callithrix_jacchus),(Saguinus_oedipus,Callithrix_pygmaea)))),(((Colobus_guereza,Colobus_satanas),(((((Trachypithecus_obscurus,Trachypithecus_francoisi),Trachypithecus_cristatus),Trachypithecus_pileatus),(Rhinopithecus_roxellana,(Nasalis_larvatus,(Simias_concolor,Pygathrix_nemaeus)))),((Pygathrix_nigripes,Rhinopithecus_brelichi),Rhinopithecus_bieti_2_RL2012))),Trachypithecus_johnii)),Piliocolobus_badius))))))),(Pongo_pygmaeus,((Pongo_abelii,(Hylobates_agilis,(Symphalangus_syndactylus,Nomascus_leucogenys))),Hylobates_moloch)))),Homo_sapiens); +(((Homo_sapiens_ssp_Denisova,(Homo_heidelbergensis,(((Gorilla_gorilla_gorilla,(((Alouatta_caraya,(Saguinus_oedipus,((((((((((Ateles_geoffroyi,Ateles_paniscus),Callimico_goeldii),Callithrix_jacchus),(Callicebus_donacophilus,Ateles_belzebuth)),(Chiropotes_albinasus,Brachyteles_arachnoides)),(Cacajao_calvus,(Pithecia_pithecia,(Chiropotes_israelita,Lagothrix_lagotricha)))),(Callicebus_cupreus,Callicebus_lugens)),((Cebus_apella,Sapajus_xanthosternos),Cebus_albifrons)),(Leontopithecus_rosalia,(((((Saimiri_boliviensis,(Saimiri_sciureus,Saimiri_oerstedii)),Saimiri_sciureus_macrodon),Saimiri_oerstedii_citrinellus),(Aotus_azarae,((Aotus_azarai,Aotus_lemurinus),(Aotus_azarae_azarai,Aotus_trivirgatus)))),Aotus_nancymaae))),Callithrix_pygmaea))),((((((Propithecus_verreauxi,(Indri_indri,Propithecus_coquereli)),(Avahi_laniger,Loris_tardigradus)),((((Hapalemur_griseus,Lemur_catta),(Eulemur_rufus,(Eulemur_fulvus,(Eulemur_rubriventer,(Eulemur_macaco,(Eulemur_mongoz,(Megaladapis_edwardsi,(Varecia_variegata,Varecia_rubra)))))))),Prolemur_simus),(Palaeopropithecus_ingens,((Lepilemur_ruficaudatus,Lepilemur_hubbardorum),Cheirogaleus_medius)))),(Daubentonia_madagascariensis,((((Perodicticus_potto,Perodicticus_potto_edwarsi),(Nycticebus_coucang,Nycticebus_bengalensis)),(Nycticebus_pygmaeus,(Galagoides_demidoff,Loris_lydekkerianus))),(Galago_senegalensis,(Otolemur_crassicaudatus,(Otolemur_garnettii,Galago_moholi)))))),Tarsius_bancanus),(Tarsius_syrichta,(Tarsius_wallacei,(Tarsius_lariang,Tarsius_dentatus))))),(((((((Trachypithecus_francoisi,(Trachypithecus_obscurus,Trachypithecus_johnii)),Trachypithecus_cristatus),Trachypithecus_pileatus),(((Rhinopithecus_bieti_2_RL2012,Rhinopithecus_brelichi),Rhinopithecus_roxellana),((Pygathrix_nemaeus,Pygathrix_nigripes),(Nasalis_larvatus,Simias_concolor)))),(Semnopithecus_entellus,(Rhinopithecus_avunculus,Presbytis_melalophos))),((Procolobus_verus,Lophocebus_albigena),(Piliocolobus_badius,(Colobus_guereza,Colobus_satanas)))),(((((Papio_ursinus,Papio_anubis),Papio_hamadryas),(Papio_kindae,(Papio_papio,Papio_cynocephalus))),Rungwecebus_kipunji),((((((Miopithecus_talapoin,(((Cercopithecus_roloway,(((((Chlorocebus_sabaeus,(Cercopithecus_dryas,Cercopithecus_aethiops)),Chlorocebus_pygerythrus),Chlorocebus_cynosuros),Chlorocebus_aethiops),Chlorocebus_tantalus)),(Cercopithecus_neglectus,(Cercopithecus_hamlyni,(((Cercopithecus_nictitans_martini,Cercopithecus_mona),(((Cercopithecus_pogonias_grayi,(Cercopithecus_pogonias_nigripes,(Cercopithecus_wolfi_elegans,Cercopithecus_pogonias_schwarzianus))),Cercopithecus_wolfi_pyrogaster),Cercopithecus_pogonias)),Cercopithecus_campbelli)))),((((((Cercopithecus_mitis_heymansi,Cercopithecus_albogularis_kolbi),Cercopithecus_mitis_mitis),Cercopithecus_mitis_opisthostictus),((Cercopithecus_albogularis_albotorquatus,(((Cercopithecus_albogularis_monoides,Cercopithecus_albogularis_erythrarchus),Cercopithecus_mitis_boutourlinii),Cercopithecus_albogularis_labiatus)),Cercopithecus_albogularis)),(Cercopithecus_kandti,((Cercopithecus_nictitans,Cercopithecus_nictitans_nictitans),((((Cercopithecus_ascanius_schmidti,Cercopithecus_albogularis_francescae),(Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis)),((Cercopithecus_lhoesti,(Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi)),(((Mandrillus_sphinx,Cercopithecus_cephus_cephus),(Cercopithecus_ascanius_katangae,((Cercopithecus_erythrogaster,(Cercopithecus_petaurista_petaurista,(Cercopithecus_petaurista_buettikoferi,Cercopithecus_erythrogaster_pococki))),Cercopithecus_erythrotis_camerunensis))),Cercopithecus_ascanius_whitesidei))),(Cercopithecus_doggetti,((Cercopithecus_mitis,Cercopithecus_albogularis_moloneyi),Cercopithecus_mitis_stuhlmanni)))))),Allenopithecus_nigroviridis))),(Cercopithecus_solatus,Cercopithecus_petaurista)),(Miopithecus_ogouensis,Cercopithecus_diana)),Erythrocebus_patas),((((Macaca_assamensis,Macaca_thibetana),((((Macaca_mulatta,Macaca_fuscata),Macaca_nigra),(Macaca_sylvanus,Macaca_nemestrina)),Macaca_arctoides)),(Macaca_fascicularis,(Macaca_silenus,Macaca_tonkeana))),((((Cercocebus_atys,Cercocebus_torquatus),Cercocebus_chrysogaster),Cercocebus_agilis),Mandrillus_leucophaeus))),(Theropithecus_gelada,Lophocebus_aterrimus)))))),Gorilla_gorilla),((((Hylobates_agilis,Hylobates_lar),(Symphalangus_syndactylus,Hylobates_moloch)),Nomascus_leucogenys),(Pongo_pygmaeus,Pongo_abelii))))),Pan_troglodytes_ellioti),(Pan_paniscus,(Pan_troglodytes_troglodytes,Pan_troglodytes)),Homo_sapiens); +(Symphalangus_syndactylus,(((Pan_troglodytes,(Pan_paniscus,(((Hylobates_agilis,(((((((Saimiri_sciureus_macrodon,(Saimiri_sciureus,(Saimiri_boliviensis,Saimiri_oerstedii))),Saimiri_oerstedii_citrinellus),(((((((((Aotus_azarae,Aotus_trivirgatus),Aotus_azarae_azarai),Aotus_nancymaae),(Aotus_azarai,Aotus_lemurinus)),(Saguinus_oedipus,Callithrix_pygmaea)),((Cebus_apella,Sapajus_xanthosternos),Cebus_albifrons)),Lagothrix_lagotricha),(((Alouatta_caraya,((Callicebus_donacophilus,(Ateles_geoffroyi,((Callithrix_jacchus,Ateles_belzebuth),Ateles_paniscus))),Callicebus_cupreus)),Callicebus_lugens),(Callimico_goeldii,Leontopithecus_rosalia))),(Pithecia_pithecia,((Chiropotes_israelita,(Chiropotes_albinasus,Brachyteles_arachnoides)),Cacajao_calvus)))),(((Tarsius_syrichta,(Tarsius_dentatus,(Tarsius_wallacei,Tarsius_lariang))),((((((Otolemur_garnettii,(Galago_senegalensis,Galago_moholi)),Galagoides_demidoff),Otolemur_crassicaudatus),(((Loris_tardigradus,Loris_lydekkerianus),(Nycticebus_pygmaeus,(Nycticebus_bengalensis,Nycticebus_coucang))),(Perodicticus_potto,Perodicticus_potto_edwarsi))),Daubentonia_madagascariensis),(Megaladapis_edwardsi,((Propithecus_coquereli,((((Lemur_catta,(((Eulemur_rubriventer,(((Varecia_variegata,(Varecia_rubra,(Cheirogaleus_medius,Hapalemur_griseus))),Eulemur_fulvus),Eulemur_macaco)),Eulemur_mongoz),Eulemur_rufus)),Prolemur_simus),((Indri_indri,(Lepilemur_ruficaudatus,Lepilemur_hubbardorum)),Avahi_laniger)),Palaeopropithecus_ingens)),Propithecus_verreauxi)))),Tarsius_bancanus)),(((((Rhinopithecus_bieti_2_RL2012,(Pygathrix_nigripes,((Nasalis_larvatus,Rhinopithecus_roxellana),((Trachypithecus_pileatus,((Trachypithecus_cristatus,Trachypithecus_francoisi),Trachypithecus_obscurus)),(Trachypithecus_johnii,((Rhinopithecus_avunculus,(Presbytis_melalophos,Semnopithecus_entellus)),(Procolobus_verus,(Piliocolobus_badius,(Colobus_guereza,Colobus_satanas))))))))),Rhinopithecus_brelichi),Simias_concolor),Pygathrix_nemaeus),(((Macaca_fascicularis,((Macaca_silenus,Macaca_tonkeana),((Macaca_assamensis,Macaca_thibetana),(((Macaca_mulatta,Macaca_fuscata),Macaca_nigra),(Macaca_sylvanus,Macaca_nemestrina))))),Macaca_arctoides),((((Erythrocebus_patas,(Cercopithecus_roloway,(((Cercopithecus_petaurista,(Cercopithecus_neglectus,((((Cercopithecus_nictitans_martini,(Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans)),(Cercopithecus_pogonias_schwarzianus,(Cercopithecus_pogonias,Cercopithecus_pogonias_nigripes))),Cercopithecus_pogonias_grayi),(Cercopithecus_campbelli,Cercopithecus_mona)))),(((((((Cercopithecus_albogularis,Cercopithecus_albogularis_monoides),(Cercopithecus_albogularis_erythrarchus,(Cercopithecus_mitis_boutourlinii,(Cercopithecus_albogularis_labiatus,Cercopithecus_albogularis_albotorquatus)))),(((Cercopithecus_mitis_opisthostictus,Cercopithecus_mitis_mitis),Cercopithecus_albogularis_kolbi),Cercopithecus_mitis_heymansi)),((((Cercopithecus_nictitans,Cercopithecus_nictitans_nictitans),(Cercopithecus_doggetti,Cercopithecus_mitis)),Cercopithecus_kandti),Cercopithecus_mitis_stuhlmanni)),(Cercopithecus_albogularis_moloneyi,((Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis),((((Mandrillus_sphinx,Cercopithecus_cephus_cephus),(Cercopithecus_erythrogaster_pococki,(Cercopithecus_erythrogaster,(Cercopithecus_petaurista_petaurista,Cercopithecus_petaurista_buettikoferi)))),(Cercopithecus_erythrotis_camerunensis,Cercopithecus_ascanius_katangae)),(Cercopithecus_ascanius_whitesidei,(Cercopithecus_ascanius_schmidti,(Cercopithecus_lhoesti,(Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi)))))))),Cercopithecus_albogularis_francescae),(((Cercopithecus_solatus,(Miopithecus_ogouensis,Miopithecus_talapoin)),(((Chlorocebus_tantalus,((Cercopithecus_hamlyni,Chlorocebus_aethiops),Chlorocebus_cynosuros)),Chlorocebus_pygerythrus),Cercopithecus_dryas)),(Chlorocebus_sabaeus,Cercopithecus_aethiops)))),Cercopithecus_diana))),Allenopithecus_nigroviridis),(Cercocebus_agilis,(Mandrillus_leucophaeus,(Cercocebus_chrysogaster,(Cercocebus_atys,Cercocebus_torquatus))))),((((Papio_kindae,Papio_cynocephalus),(Rungwecebus_kipunji,(Papio_papio,(Papio_anubis,Papio_hamadryas)))),Papio_ursinus),((Lophocebus_albigena,Lophocebus_aterrimus),Theropithecus_gelada)))))),((Gorilla_gorilla_gorilla,(Homo_sapiens_ssp_Denisova,(Gorilla_gorilla,Homo_heidelbergensis))),(Pongo_pygmaeus,Pongo_abelii))),Pan_troglodytes_ellioti)),Hylobates_lar),Pan_troglodytes_troglodytes))),Nomascus_leucogenys),Hylobates_moloch),Homo_sapiens); +((Pan_troglodytes_ellioti,(Pan_troglodytes,(Pan_troglodytes_troglodytes,Pan_paniscus))),Homo_sapiens,((Homo_sapiens_ssp_Denisova,(((((((((Saimiri_sciureus_macrodon,((Saimiri_boliviensis,Saimiri_oerstedii),Saimiri_sciureus)),Saimiri_oerstedii_citrinellus),((Aotus_trivirgatus,(((Cebus_apella,Sapajus_xanthosternos),Cebus_albifrons),((Aotus_azarae,(((Aotus_azarai,Aotus_lemurinus),((Saguinus_oedipus,Aotus_nancymaae),Callithrix_pygmaea)),(Alouatta_caraya,Leontopithecus_rosalia))),(Pithecia_pithecia,((Callicebus_cupreus,((Callicebus_donacophilus,((Callithrix_jacchus,(Ateles_geoffroyi,Ateles_paniscus)),Brachyteles_arachnoides)),Ateles_belzebuth)),Callicebus_lugens))))),Aotus_azarae_azarai)),((Chiropotes_israelita,(Chiropotes_albinasus,Cacajao_calvus)),Lagothrix_lagotricha)),Callimico_goeldii),((((Avahi_laniger,(Propithecus_coquereli,((Palaeopropithecus_ingens,((Megaladapis_edwardsi,(((Cheirogaleus_medius,Hapalemur_griseus),(Lemur_catta,Prolemur_simus)),(((Eulemur_mongoz,Eulemur_fulvus),Eulemur_rubriventer),Eulemur_macaco))),(Eulemur_rufus,(Varecia_variegata,Varecia_rubra)))),(Indri_indri,(Lepilemur_ruficaudatus,Lepilemur_hubbardorum))))),Propithecus_verreauxi),((Tarsius_syrichta,(Tarsius_lariang,(Tarsius_dentatus,Tarsius_wallacei))),((((((((Galago_moholi,Otolemur_crassicaudatus),Galago_senegalensis),Otolemur_garnettii),Galagoides_demidoff),(Loris_tardigradus,Loris_lydekkerianus)),(Nycticebus_pygmaeus,(Nycticebus_bengalensis,Nycticebus_coucang))),(Perodicticus_potto,Perodicticus_potto_edwarsi)),Daubentonia_madagascariensis))),Tarsius_bancanus)),(((((Pygathrix_nemaeus,Pygathrix_nigripes),(Simias_concolor,Nasalis_larvatus)),(Rhinopithecus_roxellana,((Rhinopithecus_brelichi,(Colobus_guereza,Colobus_satanas)),Rhinopithecus_bieti_2_RL2012))),((((Trachypithecus_johnii,Trachypithecus_pileatus),Trachypithecus_cristatus),(Trachypithecus_obscurus,(Semnopithecus_entellus,Trachypithecus_francoisi))),(((Piliocolobus_badius,Procolobus_verus),Rhinopithecus_avunculus),Presbytis_melalophos))),(((((Cercopithecus_campbelli,Cercopithecus_mona),Erythrocebus_patas),(Cercopithecus_diana,((((((Cercopithecus_kandti,Cercopithecus_mitis_stuhlmanni),(((((Cercopithecus_nictitans_nictitans,(Cercopithecus_nictitans,Cercopithecus_albogularis_kolbi)),(Cercopithecus_cephus_ngottoensis,((Cercopithecus_cephus_cephus,((Cercopithecus_ascanius_whitesidei,(((Cercopithecus_petaurista_petaurista,Cercopithecus_petaurista_buettikoferi),(Cercopithecus_erythrogaster,Cercopithecus_erythrogaster_pococki)),Cercopithecus_erythrotis_camerunensis)),(Cercopithecus_cephus,((Mandrillus_sphinx,Cercopithecus_lhoesti),(Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi))))),(Cercopithecus_ascanius_schmidti,Cercopithecus_ascanius_katangae)))),Cercopithecus_mitis_mitis),(((Cercopithecus_albogularis_labiatus,Cercopithecus_albogularis_erythrarchus),((Cercopithecus_mitis_boutourlinii,Cercopithecus_albogularis_albotorquatus),(Cercopithecus_albogularis,Cercopithecus_albogularis_monoides))),Cercopithecus_mitis)),((Cercopithecus_mitis_opisthostictus,Cercopithecus_albogularis_moloneyi),Cercopithecus_doggetti))),Cercopithecus_mitis_heymansi),Cercopithecus_albogularis_francescae),Cercopithecus_roloway),((Cercopithecus_neglectus,(Cercopithecus_aethiops,(((Cercopithecus_solatus,(Cercopithecus_dryas,(Miopithecus_ogouensis,Miopithecus_talapoin))),(Chlorocebus_pygerythrus,(((Cercopithecus_hamlyni,Chlorocebus_aethiops),Chlorocebus_tantalus),Chlorocebus_cynosuros))),Chlorocebus_sabaeus))),Cercopithecus_petaurista)))),(Cercopithecus_nictitans_martini,(Cercopithecus_pogonias,((Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans),((Cercopithecus_pogonias_schwarzianus,Cercopithecus_pogonias_nigripes),Cercopithecus_pogonias_grayi))))),((((Theropithecus_gelada,Lophocebus_aterrimus),(((((Papio_hamadryas,Papio_anubis),((Papio_cynocephalus,Papio_papio),Papio_kindae)),Papio_ursinus),Rungwecebus_kipunji),Lophocebus_albigena)),((((Cercocebus_atys,Cercocebus_torquatus),Cercocebus_chrysogaster),Cercocebus_agilis),Mandrillus_leucophaeus)),(Allenopithecus_nigroviridis,(Macaca_fascicularis,(((Macaca_silenus,Macaca_tonkeana),((Macaca_assamensis,Macaca_thibetana),((Macaca_fuscata,Macaca_nigra),(Macaca_sylvanus,Macaca_nemestrina)))),(Macaca_arctoides,Macaca_mulatta)))))))),((Gorilla_gorilla,(Pongo_pygmaeus,Pongo_abelii)),(Nomascus_leucogenys,(Hylobates_lar,(Hylobates_moloch,(Hylobates_agilis,Symphalangus_syndactylus)))))),Gorilla_gorilla_gorilla)),Homo_heidelbergensis)); +((Pan_paniscus,(Pan_troglodytes,Pan_troglodytes_troglodytes)),(Pan_troglodytes_ellioti,(((((((((Ateles_paniscus,Ateles_belzebuth),Callithrix_pygmaea),(Callimico_goeldii,Saguinus_oedipus)),((((Aotus_nancymaae,(Aotus_azarai,Aotus_lemurinus)),Aotus_azarae_azarai),Aotus_azarae),Aotus_trivirgatus)),((Saimiri_oerstedii_citrinellus,(Saimiri_sciureus_macrodon,((Saimiri_boliviensis,Saimiri_oerstedii),Saimiri_sciureus))),(((Sapajus_xanthosternos,(Cebus_albifrons,Cebus_apella)),(Callicebus_lugens,Callicebus_cupreus)),(Callicebus_donacophilus,(((Cacajao_calvus,Pithecia_pithecia),((Ateles_geoffroyi,(Lagothrix_lagotricha,(Brachyteles_arachnoides,Chiropotes_israelita))),Chiropotes_albinasus)),Callithrix_jacchus))))),(Alouatta_caraya,Leontopithecus_rosalia)),(((Procolobus_verus,((Piliocolobus_badius,(Colobus_satanas,Colobus_guereza)),((Rhinopithecus_avunculus,(Presbytis_melalophos,(Trachypithecus_johnii,Semnopithecus_entellus))),(((Pygathrix_nigripes,(Nasalis_larvatus,Simias_concolor)),(Rhinopithecus_roxellana,(Rhinopithecus_bieti_2_RL2012,Rhinopithecus_brelichi))),(((Pygathrix_nemaeus,Trachypithecus_pileatus),Trachypithecus_cristatus),(Trachypithecus_obscurus,Trachypithecus_francoisi)))))),(((Miopithecus_ogouensis,((Cercopithecus_mona,Cercopithecus_campbelli),(Cercopithecus_pogonias,((((Cercopithecus_wolfi_elegans,Cercopithecus_wolfi_pyrogaster),Cercopithecus_nictitans_martini),Cercopithecus_pogonias_schwarzianus),(Cercopithecus_pogonias_nigripes,Cercopithecus_pogonias_grayi))))),Miopithecus_talapoin),(((Cercopithecus_hamlyni,Chlorocebus_cynosuros),((((Cercocebus_chrysogaster,(Mandrillus_leucophaeus,(((Cercocebus_atys,Mandrillus_sphinx),Cercocebus_torquatus),Cercocebus_agilis))),((((Macaca_fuscata,Macaca_mulatta),((Macaca_nemestrina,((Macaca_assamensis,Macaca_thibetana),Macaca_sylvanus)),(((Macaca_silenus,Macaca_tonkeana),Macaca_fascicularis),Macaca_nigra))),Macaca_arctoides),(Lophocebus_albigena,((((Papio_anubis,Papio_hamadryas),Papio_ursinus),(Papio_papio,(Papio_cynocephalus,Papio_kindae))),(Theropithecus_gelada,(Lophocebus_aterrimus,Rungwecebus_kipunji)))))),Allenopithecus_nigroviridis),((Cercopithecus_roloway,(((Cercopithecus_diana,(Cercopithecus_mitis_boutourlinii,(Cercopithecus_albogularis_erythrarchus,((((((Cercopithecus_neglectus,(Cercopithecus_cephus_cephus,(Cercopithecus_petaurista,((Cercopithecus_petaurista_buettikoferi,Cercopithecus_petaurista_petaurista),(Cercopithecus_erythrogaster_pococki,Cercopithecus_erythrogaster))))),Cercopithecus_ascanius_schmidti),(Cercopithecus_cephus_ngottoensis,Cercopithecus_cephus)),(Cercopithecus_albogularis_francescae,(Cercopithecus_albogularis_albotorquatus,Cercopithecus_albogularis_moloneyi))),((((((Cercopithecus_mitis_opisthostictus,(Cercopithecus_mitis,Cercopithecus_mitis_heymansi)),Cercopithecus_doggetti),Cercopithecus_mitis_stuhlmanni),Cercopithecus_mitis_mitis),Cercopithecus_kandti),(Cercopithecus_nictitans_nictitans,(Cercopithecus_nictitans,Cercopithecus_albogularis_kolbi)))),Cercopithecus_albogularis_labiatus)))),(Cercopithecus_albogularis,Cercopithecus_albogularis_monoides)),((Cercopithecus_ascanius_katangae,(Cercopithecus_erythrotis_camerunensis,Cercopithecus_ascanius_whitesidei)),((Cercopithecus_preussi_preussi,Cercopithecus_preussi_insularis),Cercopithecus_lhoesti)))),Erythrocebus_patas))),((((Chlorocebus_tantalus,Cercopithecus_solatus),Chlorocebus_pygerythrus),Cercopithecus_dryas),(Chlorocebus_aethiops,(Chlorocebus_sabaeus,Cercopithecus_aethiops)))))),(Lemur_catta,(((Galago_senegalensis,(Galagoides_demidoff,(Otolemur_crassicaudatus,Otolemur_garnettii))),(((Daubentonia_madagascariensis,Propithecus_coquereli),((Loris_tardigradus,((((Perodicticus_potto_edwarsi,Perodicticus_potto),(Galago_moholi,((Nycticebus_bengalensis,Nycticebus_coucang),Loris_lydekkerianus))),(((Lepilemur_ruficaudatus,Lepilemur_hubbardorum),Indri_indri),((Megaladapis_edwardsi,(((((Eulemur_mongoz,Eulemur_fulvus),Eulemur_rufus),Eulemur_rubriventer),Eulemur_macaco),((Prolemur_simus,((Varecia_variegata,Varecia_rubra),Hapalemur_griseus)),Cheirogaleus_medius))),Palaeopropithecus_ingens))),Propithecus_verreauxi)),Avahi_laniger)),(Nycticebus_pygmaeus,((Tarsius_lariang,(Tarsius_dentatus,Tarsius_wallacei)),Tarsius_syrichta)))),Tarsius_bancanus)))),Homo_sapiens_ssp_Denisova),(Homo_heidelbergensis,((Gorilla_gorilla,(Nomascus_leucogenys,((((Pongo_pygmaeus,Pongo_abelii),(Hylobates_lar,Symphalangus_syndactylus)),Hylobates_agilis),Hylobates_moloch))),Gorilla_gorilla_gorilla)))),Homo_sapiens); +(((Pan_troglodytes,(Pan_troglodytes_troglodytes,Pan_paniscus)),Pan_troglodytes_ellioti),(((Gorilla_gorilla,((((((((((Rhinopithecus_roxellana,Rhinopithecus_bieti_2_RL2012),Rhinopithecus_brelichi),((((Semnopithecus_entellus,(Nasalis_larvatus,Simias_concolor)),(((Trachypithecus_francoisi,Trachypithecus_cristatus),Trachypithecus_obscurus),Trachypithecus_pileatus)),(Pygathrix_nemaeus,Pygathrix_nigripes)),Trachypithecus_johnii)),(Presbytis_melalophos,Rhinopithecus_avunculus)),(Procolobus_verus,(Piliocolobus_badius,(Colobus_satanas,Colobus_guereza)))),(((((Mandrillus_leucophaeus,((Cercocebus_atys,Mandrillus_sphinx),Cercocebus_torquatus)),Cercocebus_agilis),Cercocebus_chrysogaster),((((Macaca_assamensis,Macaca_thibetana),Macaca_silenus),((Macaca_tonkeana,(Macaca_arctoides,(Macaca_nemestrina,(((Macaca_mulatta,Macaca_fuscata),Macaca_nigra),Macaca_sylvanus)))),Macaca_fascicularis)),((((Papio_papio,(Papio_hamadryas,(Papio_anubis,(Papio_cynocephalus,Papio_ursinus)))),Papio_kindae),Rungwecebus_kipunji),(Theropithecus_gelada,(Lophocebus_aterrimus,Lophocebus_albigena))))),(((Miopithecus_ogouensis,((Miopithecus_talapoin,(((Cercopithecus_albogularis_moloneyi,((((((Cercopithecus_ascanius_whitesidei,(Cercopithecus_petaurista_petaurista,((((Cercopithecus_petaurista_buettikoferi,Cercopithecus_erythrogaster_pococki),Cercopithecus_erythrogaster),Cercopithecus_erythrotis_camerunensis),(Cercopithecus_neglectus,Cercopithecus_petaurista)))),Cercopithecus_ascanius_katangae),((Cercopithecus_preussi_preussi,Cercopithecus_preussi_insularis),Cercopithecus_lhoesti)),Cercopithecus_ascanius_schmidti),(Cercopithecus_cephus_ngottoensis,Cercopithecus_cephus)),(Cercopithecus_albogularis_monoides,((Cercopithecus_cephus_cephus,Cercopithecus_nictitans_nictitans),Cercopithecus_nictitans)))),((Cercopithecus_mitis,(Cercopithecus_mitis_stuhlmanni,((((Cercopithecus_albogularis_francescae,Cercopithecus_mitis_heymansi),Cercopithecus_albogularis_kolbi),Cercopithecus_doggetti),Cercopithecus_kandti))),(Cercopithecus_albogularis,((Cercopithecus_mitis_mitis,Cercopithecus_albogularis_albotorquatus),((Cercopithecus_mitis_boutourlinii,(Cercopithecus_albogularis_labiatus,Cercopithecus_albogularis_erythrarchus)),Cercopithecus_mitis_opisthostictus))))),(((((Chlorocebus_cynosuros,Chlorocebus_tantalus),Chlorocebus_pygerythrus),(Cercopithecus_hamlyni,Chlorocebus_aethiops)),(Chlorocebus_sabaeus,(Cercopithecus_solatus,Cercopithecus_aethiops))),Cercopithecus_dryas))),(Cercopithecus_roloway,(Erythrocebus_patas,Allenopithecus_nigroviridis)))),Cercopithecus_diana),((((Cercopithecus_pogonias,Cercopithecus_wolfi_pyrogaster),((Cercopithecus_pogonias_schwarzianus,Cercopithecus_wolfi_elegans),(Cercopithecus_pogonias_nigripes,Cercopithecus_pogonias_grayi))),Cercopithecus_nictitans_martini),(Cercopithecus_mona,Cercopithecus_campbelli))))),(Lemur_catta,((((Galagoides_demidoff,Otolemur_crassicaudatus),(Galago_senegalensis,Otolemur_garnettii)),((((Tarsius_dentatus,Tarsius_wallacei),Tarsius_lariang),Tarsius_syrichta),(((Megaladapis_edwardsi,(Galago_moholi,(((Loris_tardigradus,Propithecus_verreauxi),Loris_lydekkerianus),(Nycticebus_bengalensis,((Perodicticus_potto_edwarsi,Perodicticus_potto),Nycticebus_coucang))))),(Propithecus_coquereli,(Palaeopropithecus_ingens,((Eulemur_macaco,((Nycticebus_pygmaeus,(Eulemur_fulvus,((((Lepilemur_ruficaudatus,Lepilemur_hubbardorum),Cheirogaleus_medius),((Varecia_rubra,Varecia_variegata),Hapalemur_griseus)),Eulemur_mongoz))),Prolemur_simus)),((Eulemur_rufus,Eulemur_rubriventer),(Avahi_laniger,Indri_indri)))))),Daubentonia_madagascariensis))),Tarsius_bancanus))),(((Aotus_nancymaae,(Aotus_azarae_azarai,(Aotus_azarae,(Aotus_trivirgatus,(((((Callicebus_lugens,((((Ateles_paniscus,Ateles_belzebuth),Callithrix_jacchus),Ateles_geoffroyi),((Callicebus_donacophilus,Callicebus_cupreus),Brachyteles_arachnoides))),Alouatta_caraya),((Cacajao_calvus,(Chiropotes_israelita,Chiropotes_albinasus)),((Cebus_albifrons,(Cebus_apella,Sapajus_xanthosternos)),Lagothrix_lagotricha))),(Pithecia_pithecia,((Callithrix_pygmaea,Saguinus_oedipus),Callimico_goeldii))),(Aotus_azarai,Aotus_lemurinus)))))),Leontopithecus_rosalia),(Saimiri_sciureus_macrodon,(Saimiri_oerstedii_citrinellus,(Saimiri_boliviensis,(Saimiri_sciureus,Saimiri_oerstedii)))))),((Pongo_pygmaeus,Pongo_abelii),((Hylobates_lar,((Symphalangus_syndactylus,Hylobates_moloch),Nomascus_leucogenys)),Hylobates_agilis))),Gorilla_gorilla_gorilla)),Homo_sapiens_ssp_Denisova),Homo_heidelbergensis),Homo_sapiens); +((Pan_troglodytes_ellioti,(((((Gorilla_gorilla,((Alouatta_caraya,((Callithrix_pygmaea,(Aotus_nancymaae,Saguinus_oedipus)),((((((Saimiri_sciureus,Saimiri_oerstedii),(Saimiri_sciureus_macrodon,Saimiri_boliviensis)),Saimiri_oerstedii_citrinellus),((Lagothrix_lagotricha,Pithecia_pithecia),(Aotus_azarai,Aotus_lemurinus))),(((Cebus_albifrons,(Cebus_apella,Sapajus_xanthosternos)),((Aotus_azarae_azarai,Aotus_trivirgatus),((Chiropotes_israelita,Chiropotes_albinasus),Cacajao_calvus))),(Aotus_azarae,(Callicebus_lugens,(Callicebus_cupreus,(Callicebus_donacophilus,((((Callithrix_jacchus,(Ateles_geoffroyi,Ateles_paniscus)),Callimico_goeldii),Brachyteles_arachnoides),Ateles_belzebuth))))))),Leontopithecus_rosalia))),(((((((Rhinopithecus_bieti_2_RL2012,((((Trachypithecus_johnii,((Trachypithecus_francoisi,Trachypithecus_cristatus),(Trachypithecus_obscurus,Trachypithecus_pileatus))),((Pygathrix_nemaeus,Pygathrix_nigripes),((Simias_concolor,Semnopithecus_entellus),Nasalis_larvatus))),(Procolobus_verus,(Piliocolobus_badius,(Colobus_satanas,Colobus_guereza)))),Rhinopithecus_roxellana)),Rhinopithecus_brelichi),Presbytis_melalophos),Rhinopithecus_avunculus),((((((Cercocebus_atys,Mandrillus_sphinx),Cercocebus_torquatus),Mandrillus_leucophaeus),Cercocebus_chrysogaster),Cercocebus_agilis),(((((((((Cercopithecus_nictitans_nictitans,Cercopithecus_nictitans),((Cercopithecus_albogularis_kolbi,Cercopithecus_mitis_heymansi),((Cercopithecus_kandti,(Cercopithecus_doggetti,Cercopithecus_mitis_stuhlmanni)),Cercopithecus_mitis))),(Cercopithecus_albogularis_labiatus,(((Cercopithecus_mitis_boutourlinii,Cercopithecus_mitis_mitis),Cercopithecus_albogularis_erythrarchus),Cercopithecus_mitis_opisthostictus))),Cercopithecus_albogularis_monoides),Cercopithecus_albogularis),Cercopithecus_roloway),((Erythrocebus_patas,Allenopithecus_nigroviridis),(((((Macaca_fascicularis,Macaca_tonkeana),(((Macaca_sylvanus,((Macaca_mulatta,Macaca_fuscata),Macaca_nigra)),Macaca_arctoides),Macaca_nemestrina)),((Macaca_assamensis,Macaca_thibetana),Macaca_silenus)),(((((Papio_cynocephalus,Papio_kindae),Papio_ursinus),((Papio_papio,Papio_hamadryas),Papio_anubis)),Rungwecebus_kipunji),(Theropithecus_gelada,(Lophocebus_aterrimus,Lophocebus_albigena)))),Cercopithecus_diana))),((Cercopithecus_albogularis_albotorquatus,Cercopithecus_albogularis_moloneyi),((Cercopithecus_albogularis_francescae,((Cercopithecus_pogonias_grayi,(((Cercopithecus_pogonias_nigripes,Cercopithecus_pogonias),Cercopithecus_pogonias_schwarzianus),(Cercopithecus_nictitans_martini,(Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans)))),(Cercopithecus_mona,Cercopithecus_campbelli))),((((((Cercopithecus_petaurista,((Cercopithecus_petaurista_petaurista,(Cercopithecus_petaurista_buettikoferi,Cercopithecus_erythrogaster_pococki)),Cercopithecus_erythrogaster)),Cercopithecus_neglectus),Cercopithecus_cephus_cephus),(Cercopithecus_ascanius_whitesidei,(((Cercopithecus_preussi_preussi,Cercopithecus_preussi_insularis),Cercopithecus_lhoesti),(Cercopithecus_ascanius_katangae,Cercopithecus_erythrotis_camerunensis)))),Cercopithecus_ascanius_schmidti),(Cercopithecus_cephus_ngottoensis,Cercopithecus_cephus))))),(Miopithecus_talapoin,((((Cercopithecus_dryas,Cercopithecus_solatus),(Chlorocebus_sabaeus,Cercopithecus_aethiops)),(Chlorocebus_pygerythrus,((Cercopithecus_hamlyni,Chlorocebus_cynosuros),Chlorocebus_aethiops))),Chlorocebus_tantalus))))),Miopithecus_ogouensis),((Tarsius_syrichta,((Tarsius_lariang,Tarsius_dentatus),Tarsius_wallacei)),((Lemur_catta,Tarsius_bancanus),(((Eulemur_fulvus,((Megaladapis_edwardsi,((((Eulemur_rufus,(Palaeopropithecus_ingens,(Eulemur_macaco,Indri_indri))),Eulemur_mongoz),Eulemur_rubriventer),(((((Varecia_rubra,Varecia_variegata),Hapalemur_griseus),Nycticebus_pygmaeus),((Lepilemur_ruficaudatus,Lepilemur_hubbardorum),Cheirogaleus_medius)),Prolemur_simus))),Avahi_laniger)),(Propithecus_coquereli,Daubentonia_madagascariensis)),((Perodicticus_potto_edwarsi,((Perodicticus_potto,(Nycticebus_coucang,Nycticebus_bengalensis)),(Propithecus_verreauxi,(Loris_tardigradus,Loris_lydekkerianus)))),(((Galagoides_demidoff,(Otolemur_crassicaudatus,Otolemur_garnettii)),Galago_moholi),Galago_senegalensis)))))))),Gorilla_gorilla_gorilla),((Pongo_pygmaeus,Pongo_abelii),(((Hylobates_agilis,(Hylobates_lar,Symphalangus_syndactylus)),Hylobates_moloch),Nomascus_leucogenys))),Homo_sapiens_ssp_Denisova),Homo_heidelbergensis)),(Pan_paniscus,(Pan_troglodytes,Pan_troglodytes_troglodytes)),Homo_sapiens); +(Gorilla_gorilla_gorilla,(((((Pan_troglodytes,((Homo_heidelbergensis,Pan_troglodytes_ellioti),Pan_troglodytes_troglodytes)),Gorilla_gorilla),((Nomascus_leucogenys,Hylobates_moloch),(Hylobates_agilis,(Hylobates_lar,(Symphalangus_syndactylus,(Pongo_pygmaeus,Pongo_abelii)))))),Pan_paniscus),(Homo_sapiens_ssp_Denisova,(((((Rhinopithecus_avunculus,(((((Trachypithecus_francoisi,(Trachypithecus_obscurus,Trachypithecus_johnii)),Trachypithecus_cristatus),Trachypithecus_pileatus),(((Rhinopithecus_roxellana,Rhinopithecus_brelichi),((Pygathrix_nemaeus,Pygathrix_nigripes),(Simias_concolor,Nasalis_larvatus))),Rhinopithecus_bieti_2_RL2012)),Presbytis_melalophos)),((Colobus_satanas,Colobus_guereza),(Procolobus_verus,Piliocolobus_badius))),Semnopithecus_entellus),((((((((((((Cercopithecus_albogularis_monoides,((Cercopithecus_mitis_boutourlinii,Cercopithecus_albogularis_erythrarchus),Cercopithecus_albogularis_labiatus)),Cercopithecus_mitis_opisthostictus),Cercopithecus_mitis_mitis),Cercopithecus_albogularis_kolbi),(Cercopithecus_albogularis,Cercopithecus_mitis_heymansi)),((Cercopithecus_nictitans_nictitans,(Cercopithecus_mitis,(Cercopithecus_doggetti,(Cercopithecus_mitis_stuhlmanni,Cercopithecus_kandti)))),Cercopithecus_nictitans)),Cercopithecus_roloway),(((Macaca_fascicularis,(Macaca_silenus,Macaca_tonkeana)),((Macaca_sylvanus,(Macaca_assamensis,Macaca_thibetana)),(((Macaca_arctoides,((((((Papio_papio,(Papio_cynocephalus,Papio_kindae)),Papio_ursinus),(Papio_hamadryas,Papio_anubis)),Rungwecebus_kipunji),(Theropithecus_gelada,(Lophocebus_aterrimus,Lophocebus_albigena))),(Macaca_mulatta,Macaca_fuscata))),Macaca_nigra),Macaca_nemestrina))),Erythrocebus_patas)),Cercopithecus_diana),((((Cercopithecus_aethiops,(((Cercopithecus_cephus_ngottoensis,Cercopithecus_cephus),(((Cercopithecus_pogonias_nigripes,((Cercopithecus_pogonias_schwarzianus,(Cercopithecus_pogonias,Cercopithecus_wolfi_pyrogaster)),Cercopithecus_wolfi_elegans)),Cercopithecus_pogonias_grayi),((Cercopithecus_neglectus,((Cercopithecus_ascanius_whitesidei,((Cercopithecus_preussi_preussi,Cercopithecus_preussi_insularis),Cercopithecus_lhoesti)),(((Cercopithecus_petaurista_petaurista,(Cercopithecus_petaurista_buettikoferi,Cercopithecus_erythrogaster_pococki)),Cercopithecus_erythrogaster),((Cercopithecus_erythrotis_camerunensis,Cercopithecus_ascanius_katangae),Cercopithecus_cephus_cephus)))),Cercopithecus_ascanius_schmidti))),(Cercopithecus_albogularis_albotorquatus,Cercopithecus_albogularis_moloneyi))),Chlorocebus_sabaeus),((Cercopithecus_mona,Cercopithecus_campbelli),Cercopithecus_albogularis_francescae)),Cercopithecus_petaurista)),(((Miopithecus_talapoin,Cercopithecus_solatus),((((Cercopithecus_hamlyni,Chlorocebus_cynosuros),Cercopithecus_nictitans_martini),(Allenopithecus_nigroviridis,Chlorocebus_pygerythrus)),((Chlorocebus_tantalus,Cercopithecus_dryas),Chlorocebus_aethiops))),(((Cercocebus_agilis,Mandrillus_leucophaeus),Cercocebus_chrysogaster),((Cercocebus_atys,Mandrillus_sphinx),Cercocebus_torquatus)))),Miopithecus_ogouensis)),(((((Saimiri_sciureus,Saimiri_oerstedii),(Saimiri_sciureus_macrodon,Saimiri_boliviensis)),Saimiri_oerstedii_citrinellus),((((((((Ateles_paniscus,(Callithrix_jacchus,(Ateles_geoffroyi,Ateles_belzebuth))),Pithecia_pithecia),Callicebus_cupreus),Callicebus_lugens),(Cebus_albifrons,(Cebus_apella,Sapajus_xanthosternos))),(Lagothrix_lagotricha,(Callicebus_donacophilus,((Chiropotes_albinasus,(Callimico_goeldii,Chiropotes_israelita)),Cacajao_calvus)))),(((Leontopithecus_rosalia,((Aotus_nancymaae,(Callithrix_pygmaea,Saguinus_oedipus)),(Aotus_azarae_azarai,(Aotus_azarai,Aotus_lemurinus)))),Aotus_azarae),Aotus_trivirgatus)),(Brachyteles_arachnoides,Alouatta_caraya))),(Tarsius_bancanus,(((((((Perodicticus_potto,Perodicticus_potto_edwarsi),((Nycticebus_coucang,Nycticebus_bengalensis),(Loris_tardigradus,Loris_lydekkerianus))),((((Galago_senegalensis,Galago_moholi),Galagoides_demidoff),Otolemur_crassicaudatus),Otolemur_garnettii)),(Propithecus_verreauxi,(Palaeopropithecus_ingens,(Propithecus_coquereli,((Eulemur_rufus,((Eulemur_fulvus,(((Cheirogaleus_medius,(((Varecia_rubra,Varecia_variegata),(Hapalemur_griseus,Nycticebus_pygmaeus)),Prolemur_simus)),Eulemur_rubriventer),Eulemur_mongoz)),Eulemur_macaco)),((Lepilemur_ruficaudatus,Lepilemur_hubbardorum),Indri_indri)))))),(Daubentonia_madagascariensis,(Megaladapis_edwardsi,Avahi_laniger))),((Tarsius_lariang,(Tarsius_dentatus,Tarsius_wallacei)),Tarsius_syrichta)),Lemur_catta)))))),Homo_sapiens); +(((Homo_heidelbergensis,((Gorilla_gorilla_gorilla,(Homo_sapiens_ssp_Denisova,(((((Saimiri_sciureus_macrodon,Saimiri_oerstedii_citrinellus),(Saimiri_boliviensis,(Saimiri_sciureus,Saimiri_oerstedii))),((Chiropotes_albinasus,(Chiropotes_israelita,((((Cebus_albifrons,(Cebus_apella,Sapajus_xanthosternos)),(Lagothrix_lagotricha,(((Callicebus_cupreus,(Callicebus_donacophilus,(Brachyteles_arachnoides,Ateles_geoffroyi))),(((Ateles_paniscus,Ateles_belzebuth),Callimico_goeldii),Callithrix_jacchus)),Callicebus_lugens))),(Leontopithecus_rosalia,(((Aotus_trivirgatus,Aotus_azarae),(((Aotus_azarai,Aotus_lemurinus),Aotus_nancymaae),Aotus_azarae_azarai)),(Callithrix_pygmaea,Saguinus_oedipus)))),(Pithecia_pithecia,Cacajao_calvus)))),Alouatta_caraya)),((Lemur_catta,(((Daubentonia_madagascariensis,(Avahi_laniger,Megaladapis_edwardsi)),((Perodicticus_potto_edwarsi,((Perodicticus_potto,((Nycticebus_coucang,Nycticebus_bengalensis),(Loris_tardigradus,Loris_lydekkerianus))),((Galago_moholi,Galago_senegalensis),(Galagoides_demidoff,(Otolemur_crassicaudatus,Otolemur_garnettii))))),((((Propithecus_verreauxi,Propithecus_coquereli),Indri_indri),(Lepilemur_ruficaudatus,Lepilemur_hubbardorum)),(Palaeopropithecus_ingens,(((Cheirogaleus_medius,((Varecia_rubra,Varecia_variegata),(Hapalemur_griseus,Nycticebus_pygmaeus))),((Eulemur_mongoz,(Eulemur_rubriventer,(Eulemur_fulvus,Eulemur_rufus))),Eulemur_macaco)),Prolemur_simus))))),(((Tarsius_dentatus,Tarsius_wallacei),Tarsius_lariang),Tarsius_syrichta))),Tarsius_bancanus)),(Miopithecus_ogouensis,(((((((Procolobus_verus,(Piliocolobus_badius,(Colobus_satanas,Colobus_guereza))),Rhinopithecus_avunculus),Trachypithecus_johnii),Presbytis_melalophos),((Rhinopithecus_bieti_2_RL2012,(Rhinopithecus_brelichi,(((Trachypithecus_cristatus,(Nasalis_larvatus,(Rhinopithecus_roxellana,(Simias_concolor,Trachypithecus_francoisi)))),Trachypithecus_obscurus),Pygathrix_nigripes))),(Pygathrix_nemaeus,Trachypithecus_pileatus))),Semnopithecus_entellus),((Cercopithecus_roloway,((((Cercopithecus_nictitans,(Cercopithecus_hamlyni,((Chlorocebus_cynosuros,Allenopithecus_nigroviridis),((((Cercocebus_agilis,Mandrillus_leucophaeus),Cercocebus_chrysogaster),((Cercocebus_atys,Mandrillus_sphinx),Cercocebus_torquatus)),(((((((Cercopithecus_cephus,Cercopithecus_neglectus),Cercopithecus_petaurista),(((((Cercopithecus_albogularis_albotorquatus,Cercopithecus_albogularis_moloneyi),Cercopithecus_cephus_ngottoensis),((((Cercopithecus_preussi_preussi,Cercopithecus_preussi_insularis),Cercopithecus_lhoesti),(Cercopithecus_erythrotis_camerunensis,Cercopithecus_ascanius_katangae)),Cercopithecus_ascanius_whitesidei)),(Cercopithecus_ascanius_schmidti,((Cercopithecus_erythrogaster,Cercopithecus_erythrogaster_pococki),(Cercopithecus_petaurista_petaurista,Cercopithecus_petaurista_buettikoferi)))),((((Cercopithecus_mona,Cercopithecus_campbelli),(Cercopithecus_pogonias,(((Cercopithecus_wolfi_elegans,Cercopithecus_wolfi_pyrogaster),(Cercopithecus_pogonias_grayi,Cercopithecus_pogonias_schwarzianus)),Cercopithecus_pogonias_nigripes))),Cercopithecus_nictitans_martini),Cercopithecus_cephus_cephus))),Cercopithecus_albogularis_francescae),Cercopithecus_dryas),((Cercopithecus_solatus,Cercopithecus_aethiops),Chlorocebus_sabaeus)),((Chlorocebus_pygerythrus,Chlorocebus_tantalus),Chlorocebus_aethiops)))))),((((((((Cercopithecus_mitis_mitis,(Cercopithecus_mitis_boutourlinii,(((Cercopithecus_albogularis,Cercopithecus_albogularis_labiatus),Cercopithecus_albogularis_monoides),Cercopithecus_albogularis_erythrarchus))),Cercopithecus_mitis_opisthostictus),(Cercopithecus_albogularis_kolbi,Cercopithecus_mitis_heymansi)),((Cercopithecus_mitis_stuhlmanni,Cercopithecus_doggetti),Cercopithecus_mitis)),Cercopithecus_kandti),Cercopithecus_nictitans_nictitans),(((Lophocebus_aterrimus,Lophocebus_albigena),((Rungwecebus_kipunji,((((Papio_papio,Papio_hamadryas),Papio_anubis),(Papio_cynocephalus,Papio_kindae)),Papio_ursinus)),Macaca_sylvanus)),Theropithecus_gelada)),Erythrocebus_patas)),((((Macaca_fuscata,(Macaca_arctoides,Macaca_nemestrina)),Macaca_nigra),(Macaca_fascicularis,(Macaca_mulatta,Macaca_tonkeana))),(Macaca_silenus,(Macaca_assamensis,Macaca_thibetana)))),Cercopithecus_diana)),Miopithecus_talapoin)))))),Gorilla_gorilla)),(((Pan_troglodytes,Pan_paniscus),Pan_troglodytes_troglodytes),(Hylobates_moloch,(Nomascus_leucogenys,(((Hylobates_lar,Hylobates_agilis),(Pongo_pygmaeus,Pongo_abelii)),Symphalangus_syndactylus))))),Pan_troglodytes_ellioti,Homo_sapiens); +((Pan_troglodytes,(((((Saimiri_sciureus_macrodon,(Saimiri_boliviensis,(Saimiri_oerstedii,Saimiri_sciureus))),Saimiri_oerstedii_citrinellus),(((((Cacajao_calvus,(Callicebus_donacophilus,Chiropotes_israelita)),Chiropotes_albinasus),Brachyteles_arachnoides),((Sapajus_xanthosternos,(Cebus_albifrons,Cebus_apella)),(((((((Aotus_azarae_azarai,Aotus_azarae),(Aotus_azarai,Aotus_lemurinus)),Aotus_trivirgatus),Aotus_nancymaae),Leontopithecus_rosalia),(Callithrix_pygmaea,Saguinus_oedipus)),(Callimico_goeldii,(Ateles_paniscus,((Callithrix_jacchus,Pithecia_pithecia),((Ateles_geoffroyi,(Lagothrix_lagotricha,(Callicebus_lugens,Callicebus_cupreus))),Ateles_belzebuth))))))),Alouatta_caraya)),((((((Eulemur_fulvus,(Otolemur_crassicaudatus,(((Palaeopropithecus_ingens,Megaladapis_edwardsi),(Prolemur_simus,((((Nycticebus_pygmaeus,(Varecia_rubra,Varecia_variegata)),Hapalemur_griseus),Cheirogaleus_medius),Eulemur_rufus))),((((Eulemur_mongoz,((Galago_moholi,((Nycticebus_coucang,Nycticebus_bengalensis),(Propithecus_verreauxi,(Loris_tardigradus,Loris_lydekkerianus)))),Daubentonia_madagascariensis)),(Eulemur_rubriventer,(Tarsius_syrichta,(Galagoides_demidoff,((Tarsius_dentatus,Tarsius_wallacei),Tarsius_lariang))))),Propithecus_coquereli),((Perodicticus_potto,Perodicticus_potto_edwarsi),(Indri_indri,(Lepilemur_ruficaudatus,Lepilemur_hubbardorum))))))),Avahi_laniger),(Eulemur_macaco,Otolemur_garnettii)),Galago_senegalensis),Lemur_catta),Tarsius_bancanus)),(Miopithecus_ogouensis,(((Cercopithecus_diana,((((((Allenopithecus_nigroviridis,Chlorocebus_pygerythrus),(Chlorocebus_aethiops,((Chlorocebus_tantalus,Cercopithecus_solatus),(Cercopithecus_dryas,Chlorocebus_cynosuros)))),Chlorocebus_sabaeus),(Cercopithecus_aethiops,((((((Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis),(Cercopithecus_erythrogaster,(Cercopithecus_albogularis_albotorquatus,Cercopithecus_albogularis_moloneyi))),Cercopithecus_ascanius_schmidti),((((((Cercopithecus_preussi_preussi,Cercopithecus_preussi_insularis),Cercopithecus_lhoesti),Cercopithecus_erythrotis_camerunensis),(Cercopithecus_ascanius_katangae,Cercopithecus_ascanius_whitesidei)),((Cercopithecus_neglectus,((Cercopithecus_mona,Cercopithecus_campbelli),((((((Cercopithecus_pogonias_nigripes,(Cercopithecus_wolfi_elegans,Cercopithecus_pogonias_schwarzianus)),Cercopithecus_pogonias_grayi),Cercopithecus_pogonias),Cercopithecus_nictitans_martini),Cercopithecus_wolfi_pyrogaster),Cercopithecus_cephus_cephus))),Cercopithecus_petaurista)),(Cercopithecus_petaurista_petaurista,Cercopithecus_petaurista_buettikoferi))),Cercopithecus_erythrogaster_pococki),Cercopithecus_albogularis_francescae))),Cercopithecus_nictitans),(((((((Cercopithecus_mitis_opisthostictus,(Cercopithecus_albogularis,(Cercopithecus_albogularis_labiatus,((Cercopithecus_mitis_boutourlinii,Cercopithecus_albogularis_erythrarchus),Cercopithecus_albogularis_monoides)))),Cercopithecus_mitis_mitis),Cercopithecus_mitis_heymansi),((Cercopithecus_doggetti,Cercopithecus_mitis_stuhlmanni),(Cercopithecus_kandti,Cercopithecus_mitis))),Cercopithecus_albogularis_kolbi),Cercopithecus_nictitans_nictitans),((Cercopithecus_hamlyni,((((Mandrillus_leucophaeus,((Macaca_sylvanus,(Mandrillus_sphinx,Cercocebus_atys)),Cercocebus_chrysogaster)),Cercocebus_torquatus),Cercocebus_agilis),((Papio_kindae,(((Papio_anubis,Papio_hamadryas),(Papio_ursinus,Papio_cynocephalus)),Papio_papio)),(Rungwecebus_kipunji,(Theropithecus_gelada,(Lophocebus_aterrimus,Lophocebus_albigena)))))),Erythrocebus_patas)))),(((((Macaca_nigra,(Macaca_mulatta,Macaca_fuscata)),Macaca_nemestrina),Macaca_arctoides),(Macaca_fascicularis,Macaca_tonkeana)),(Macaca_silenus,(Macaca_assamensis,Macaca_thibetana)))),((Miopithecus_talapoin,(((Piliocolobus_badius,(Colobus_satanas,Colobus_guereza)),((((Trachypithecus_pileatus,(Trachypithecus_cristatus,(Trachypithecus_francoisi,Trachypithecus_obscurus))),(Rhinopithecus_bieti_2_RL2012,(((Pygathrix_nemaeus,Pygathrix_nigripes),(Simias_concolor,Nasalis_larvatus)),(Rhinopithecus_brelichi,Rhinopithecus_roxellana)))),(Presbytis_melalophos,(Semnopithecus_entellus,Rhinopithecus_avunculus))),Trachypithecus_johnii)),Procolobus_verus)),Cercopithecus_roloway))))),(((Hylobates_agilis,((Hylobates_moloch,(Nomascus_leucogenys,Symphalangus_syndactylus)),((Pongo_abelii,Pongo_pygmaeus),Hylobates_lar))),(Homo_sapiens_ssp_Denisova,(((Pan_paniscus,Pan_troglodytes_troglodytes),Gorilla_gorilla),(Pan_troglodytes_ellioti,Homo_heidelbergensis)))),Gorilla_gorilla_gorilla),Homo_sapiens); +(((((Gorilla_gorilla_gorilla,((((((Saimiri_sciureus_macrodon,((Saimiri_oerstedii,Saimiri_sciureus),Saimiri_boliviensis)),Saimiri_oerstedii_citrinellus),(Cacajao_calvus,((((((((((Ateles_belzebuth,((Callicebus_donacophilus,(Ateles_geoffroyi,Callimico_goeldii)),Callicebus_cupreus)),Ateles_paniscus),Callicebus_lugens),(Aotus_azarae,(Lagothrix_lagotricha,(((Aotus_lemurinus,Aotus_azarai),((Callithrix_jacchus,Callithrix_pygmaea),Saguinus_oedipus)),Aotus_azarae_azarai)))),(Cebus_albifrons,(Cebus_apella,Sapajus_xanthosternos))),Leontopithecus_rosalia),(Alouatta_caraya,Aotus_nancymaae)),Aotus_trivirgatus),Pithecia_pithecia),(Chiropotes_israelita,(Chiropotes_albinasus,Brachyteles_arachnoides))))),(((((Avahi_laniger,(Propithecus_coquereli,((Propithecus_verreauxi,((Eulemur_macaco,((((Eulemur_rubriventer,Eulemur_mongoz),(Palaeopropithecus_ingens,Varecia_variegata)),Eulemur_rufus),(Megaladapis_edwardsi,(Varecia_rubra,(((Nycticebus_pygmaeus,Hapalemur_griseus),Prolemur_simus),Cheirogaleus_medius))))),Eulemur_fulvus)),(Indri_indri,(Lepilemur_ruficaudatus,Lepilemur_hubbardorum))))),(Daubentonia_madagascariensis,((Perodicticus_potto,Perodicticus_potto_edwarsi),((Otolemur_crassicaudatus,(Galago_senegalensis,(Otolemur_garnettii,(Galagoides_demidoff,Galago_moholi)))),((Nycticebus_coucang,Nycticebus_bengalensis),(Loris_tardigradus,Loris_lydekkerianus)))))),(Tarsius_syrichta,(Tarsius_lariang,(Tarsius_wallacei,Tarsius_dentatus)))),Tarsius_bancanus),Lemur_catta)),((((((Trachypithecus_johnii,Rhinopithecus_avunculus),(Presbytis_melalophos,Semnopithecus_entellus)),((Trachypithecus_cristatus,(Trachypithecus_francoisi,(Trachypithecus_obscurus,Trachypithecus_pileatus))),(((((Pygathrix_nemaeus,Pygathrix_nigripes),(Simias_concolor,Nasalis_larvatus)),Rhinopithecus_bieti_2_RL2012),Rhinopithecus_brelichi),Rhinopithecus_roxellana))),(Piliocolobus_badius,(Colobus_satanas,Colobus_guereza))),Procolobus_verus),((Miopithecus_ogouensis,(((Cercopithecus_roloway,(((((Macaca_nigra,(Macaca_mulatta,Macaca_fuscata)),Macaca_nemestrina),Macaca_arctoides),(Macaca_assamensis,Macaca_thibetana)),(Macaca_tonkeana,(Macaca_fascicularis,Macaca_silenus)))),((Cercopithecus_nictitans,(((Cercopithecus_hamlyni,((Cercocebus_chrysogaster,(Mandrillus_sphinx,(((Cercocebus_torquatus,Cercocebus_atys),Mandrillus_leucophaeus),Cercocebus_agilis))),((Theropithecus_gelada,(Lophocebus_aterrimus,Lophocebus_albigena)),((((Papio_kindae,Papio_ursinus),Papio_cynocephalus),(Papio_papio,(Papio_anubis,Papio_hamadryas))),Rungwecebus_kipunji)))),Macaca_sylvanus),Erythrocebus_patas)),((((Chlorocebus_sabaeus,Cercopithecus_aethiops),(Cercopithecus_dryas,(Cercopithecus_solatus,((Chlorocebus_tantalus,(Chlorocebus_aethiops,Chlorocebus_cynosuros)),(Allenopithecus_nigroviridis,Chlorocebus_pygerythrus))))),(((((Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis),(Cercopithecus_albogularis_albotorquatus,Cercopithecus_albogularis_moloneyi)),(Cercopithecus_ascanius_schmidti,(((Cercopithecus_petaurista,(Cercopithecus_erythrogaster,(Cercopithecus_petaurista_petaurista,Cercopithecus_petaurista_buettikoferi))),(Cercopithecus_ascanius_whitesidei,(Cercopithecus_erythrotis_camerunensis,(Cercopithecus_ascanius_katangae,((Cercopithecus_preussi_preussi,Cercopithecus_preussi_insularis),Cercopithecus_lhoesti))))),(Cercopithecus_neglectus,((Cercopithecus_mona,Cercopithecus_campbelli),(((((Cercopithecus_pogonias,(Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans)),Cercopithecus_nictitans_martini),Cercopithecus_pogonias_schwarzianus),(Cercopithecus_pogonias_grayi,Cercopithecus_pogonias_nigripes)),Cercopithecus_cephus_cephus)))))),Cercopithecus_erythrogaster_pococki),Cercopithecus_albogularis_francescae)),((((Cercopithecus_mitis_stuhlmanni,(Cercopithecus_kandti,Cercopithecus_doggetti)),(Cercopithecus_mitis,(((Cercopithecus_mitis_opisthostictus,((Cercopithecus_albogularis,Cercopithecus_albogularis_monoides),(Cercopithecus_albogularis_labiatus,(Cercopithecus_mitis_boutourlinii,Cercopithecus_albogularis_erythrarchus)))),Cercopithecus_mitis_mitis),Cercopithecus_mitis_heymansi))),Cercopithecus_albogularis_kolbi),Cercopithecus_nictitans_nictitans)))),Cercopithecus_diana)),Miopithecus_talapoin))),((((Hylobates_agilis,Nomascus_leucogenys),Hylobates_moloch),(Hylobates_lar,Symphalangus_syndactylus)),(Pongo_abelii,Pongo_pygmaeus)))),Gorilla_gorilla),Homo_sapiens_ssp_Denisova),Homo_heidelbergensis),(Pan_troglodytes_ellioti,((Pan_troglodytes,Pan_paniscus),Pan_troglodytes_troglodytes)),Homo_sapiens); +(((((Hylobates_moloch,(((((((Saimiri_oerstedii,Saimiri_sciureus),Saimiri_boliviensis),Saimiri_sciureus_macrodon),Saimiri_oerstedii_citrinellus),((Aotus_lemurinus,Aotus_azarai),(Ateles_geoffroyi,(Aotus_trivirgatus,((((Callicebus_lugens,((Alouatta_caraya,Callicebus_cupreus),((Saguinus_oedipus,(Callithrix_pygmaea,Aotus_nancymaae)),(((Aotus_azarae,((((Chiropotes_albinasus,Brachyteles_arachnoides),Chiropotes_israelita),((Aotus_azarae_azarai,(Pithecia_pithecia,Cacajao_calvus)),Ateles_paniscus)),Lagothrix_lagotricha)),(Callimico_goeldii,Leontopithecus_rosalia)),Callithrix_jacchus)))),(Sapajus_xanthosternos,(Cebus_albifrons,Cebus_apella))),Callicebus_donacophilus),Ateles_belzebuth))))),(Lemur_catta,((((((Eulemur_rubriventer,(Megaladapis_edwardsi,Avahi_laniger)),(Propithecus_coquereli,(((Eulemur_rufus,((Eulemur_mongoz,(Eulemur_fulvus,(Propithecus_verreauxi,(((Varecia_variegata,Varecia_rubra),(Nycticebus_pygmaeus,Hapalemur_griseus)),(Prolemur_simus,Cheirogaleus_medius))))),Palaeopropithecus_ingens)),Eulemur_macaco),Indri_indri))),(((Lepilemur_ruficaudatus,Lepilemur_hubbardorum),Perodicticus_potto),Daubentonia_madagascariensis)),(Tarsius_syrichta,((Tarsius_wallacei,Tarsius_dentatus),Tarsius_lariang))),(Perodicticus_potto_edwarsi,((Nycticebus_coucang,Nycticebus_bengalensis),((Otolemur_garnettii,(Galago_senegalensis,(Otolemur_crassicaudatus,Galago_moholi))),(Galagoides_demidoff,(Loris_tardigradus,Loris_lydekkerianus)))))),Tarsius_bancanus))),(((Rhinopithecus_avunculus,((Presbytis_melalophos,Semnopithecus_entellus),((Trachypithecus_cristatus,((Trachypithecus_francoisi,Trachypithecus_obscurus),Trachypithecus_johnii)),(Trachypithecus_pileatus,(((Pygathrix_nemaeus,Simias_concolor),((Rhinopithecus_bieti_2_RL2012,Rhinopithecus_brelichi),Pygathrix_nigripes)),(Rhinopithecus_roxellana,Nasalis_larvatus)))))),(Procolobus_verus,((Colobus_satanas,Colobus_guereza),Piliocolobus_badius))),(Miopithecus_talapoin,(Cercopithecus_roloway,(Miopithecus_ogouensis,((((((Macaca_nigra,(Macaca_mulatta,Macaca_fuscata)),Macaca_nemestrina),Macaca_arctoides),(Macaca_assamensis,Macaca_thibetana)),(Macaca_fascicularis,(Macaca_silenus,Macaca_tonkeana))),(((((Papio_kindae,(((Rungwecebus_kipunji,(((Lophocebus_aterrimus,Lophocebus_albigena),((Cercocebus_atys,Papio_papio),(Papio_anubis,Papio_hamadryas))),Papio_cynocephalus)),Theropithecus_gelada),Papio_ursinus)),(((Cercocebus_torquatus,Mandrillus_sphinx),(Cercocebus_agilis,Mandrillus_leucophaeus)),Cercocebus_chrysogaster)),(Erythrocebus_patas,(((((Cercopithecus_doggetti,(((Macaca_sylvanus,Cercopithecus_mitis_stuhlmanni),Allenopithecus_nigroviridis),Cercopithecus_kandti)),((Cercopithecus_albogularis_francescae,(((Chlorocebus_aethiops,((Chlorocebus_sabaeus,Chlorocebus_pygerythrus),Chlorocebus_cynosuros)),((Chlorocebus_tantalus,Cercopithecus_aethiops),Cercopithecus_solatus)),Cercopithecus_dryas)),(Cercopithecus_erythrogaster_pococki,((((((Cercopithecus_petaurista,(Cercopithecus_erythrogaster,(Cercopithecus_petaurista_petaurista,Cercopithecus_petaurista_buettikoferi))),Cercopithecus_ascanius_whitesidei),(((Cercopithecus_preussi_preussi,Cercopithecus_preussi_insularis),Cercopithecus_lhoesti),(Cercopithecus_ascanius_katangae,Cercopithecus_erythrotis_camerunensis))),Cercopithecus_ascanius_schmidti),((Cercopithecus_neglectus,((Cercopithecus_nictitans_martini,((Cercopithecus_mona,Cercopithecus_campbelli),(((Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans),((Cercopithecus_pogonias_grayi,Cercopithecus_pogonias_nigripes),Cercopithecus_pogonias_schwarzianus)),Cercopithecus_pogonias))),Cercopithecus_cephus_cephus)),Cercopithecus_cephus)),((Cercopithecus_cephus_ngottoensis,Cercopithecus_albogularis_moloneyi),Cercopithecus_albogularis_albotorquatus))))),(Cercopithecus_mitis,((Cercopithecus_mitis_heymansi,(Cercopithecus_mitis_opisthostictus,Cercopithecus_mitis_mitis)),((Cercopithecus_albogularis,Cercopithecus_albogularis_monoides),(Cercopithecus_mitis_boutourlinii,(Cercopithecus_albogularis_erythrarchus,Cercopithecus_albogularis_labiatus)))))),(Cercopithecus_nictitans,Cercopithecus_nictitans_nictitans)),Cercopithecus_albogularis_kolbi))),Cercopithecus_hamlyni),Cercopithecus_diana)))))))),(((Pongo_abelii,Pongo_pygmaeus),Nomascus_leucogenys),(Hylobates_agilis,(Hylobates_lar,Symphalangus_syndactylus)))),Gorilla_gorilla_gorilla),Gorilla_gorilla),(((Pan_troglodytes_ellioti,Homo_heidelbergensis),(Pan_troglodytes,(Pan_paniscus,Pan_troglodytes_troglodytes))),Homo_sapiens_ssp_Denisova),Homo_sapiens); +(((((Gorilla_gorilla_gorilla,(((((((((Cacajao_calvus,(Aotus_azarae_azarai,(Pithecia_pithecia,(Chiropotes_albinasus,(Chiropotes_israelita,(Callicebus_donacophilus,((Callithrix_jacchus,((Ateles_paniscus,(Ateles_belzebuth,Ateles_geoffroyi)),Callimico_goeldii)),Brachyteles_arachnoides))))))),Aotus_azarae),(Cebus_albifrons,(Cebus_apella,Sapajus_xanthosternos))),(((Callicebus_cupreus,Callicebus_lugens),Aotus_trivirgatus),Lagothrix_lagotricha)),((Leontopithecus_rosalia,((Aotus_lemurinus,Aotus_azarai),((Aotus_nancymaae,Callithrix_pygmaea),Saguinus_oedipus))),((Saimiri_sciureus_macrodon,((Saimiri_oerstedii,Saimiri_sciureus),Saimiri_boliviensis)),Saimiri_oerstedii_citrinellus))),Alouatta_caraya),(((Tarsius_bancanus,((Tarsius_wallacei,(Tarsius_dentatus,Tarsius_lariang)),Tarsius_syrichta)),(Daubentonia_madagascariensis,(Megaladapis_edwardsi,(Avahi_laniger,(Propithecus_coquereli,(((((Eulemur_rufus,((((Eulemur_mongoz,(Eulemur_fulvus,(((Nycticebus_pygmaeus,(Varecia_rubra,Varecia_variegata)),Hapalemur_griseus),Cheirogaleus_medius))),Eulemur_rubriventer),Prolemur_simus),Eulemur_macaco)),Palaeopropithecus_ingens),((Lepilemur_ruficaudatus,Lepilemur_hubbardorum),Indri_indri)),((Perodicticus_potto_edwarsi,Perodicticus_potto),(((Nycticebus_coucang,Nycticebus_bengalensis),(Loris_lydekkerianus,Loris_tardigradus)),((((Otolemur_crassicaudatus,Galago_senegalensis),Galagoides_demidoff),Galago_moholi),Otolemur_garnettii)))),Propithecus_verreauxi)))))),Lemur_catta)),((((((Cercopithecus_roloway,(((((Cercocebus_atys,((((Theropithecus_gelada,(Rungwecebus_kipunji,Lophocebus_aterrimus)),((Papio_papio,(Papio_anubis,Papio_hamadryas)),((Papio_cynocephalus,Papio_kindae),Papio_ursinus))),Lophocebus_albigena),(Macaca_fascicularis,((Macaca_silenus,Macaca_tonkeana),(((Macaca_sylvanus,((Macaca_nigra,Macaca_fuscata),Macaca_nemestrina)),(Macaca_mulatta,Macaca_arctoides)),(Macaca_assamensis,Macaca_thibetana)))))),((Cercocebus_agilis,(Mandrillus_leucophaeus,Cercocebus_chrysogaster)),Cercocebus_torquatus)),Cercopithecus_hamlyni),Mandrillus_sphinx),Erythrocebus_patas)),(((Cercopithecus_cephus_ngottoensis,(Cercopithecus_ascanius_schmidti,((((Cercopithecus_cephus_cephus,(Cercopithecus_petaurista,(((Cercopithecus_nictitans_martini,(Cercopithecus_pogonias,((((Cercopithecus_mona,Cercopithecus_campbelli),Cercopithecus_pogonias_grayi),(Cercopithecus_pogonias_schwarzianus,Cercopithecus_pogonias_nigripes)),Cercopithecus_wolfi_elegans))),Cercopithecus_wolfi_pyrogaster),Cercopithecus_neglectus))),(Cercopithecus_petaurista_petaurista,Cercopithecus_petaurista_buettikoferi)),((Cercopithecus_erythrogaster_pococki,Cercopithecus_erythrogaster),(Cercopithecus_ascanius_whitesidei,(Cercopithecus_ascanius_katangae,(((Cercopithecus_preussi_preussi,Cercopithecus_preussi_insularis),Cercopithecus_lhoesti),Cercopithecus_erythrotis_camerunensis))))),Cercopithecus_cephus))),Cercopithecus_albogularis),(((Cercopithecus_mitis_opisthostictus,(Cercopithecus_nictitans,Cercopithecus_nictitans_nictitans)),(Cercopithecus_mitis_mitis,(Cercopithecus_mitis,((((Cercopithecus_albogularis_francescae,Cercopithecus_mitis_stuhlmanni),Cercopithecus_albogularis_kolbi),Cercopithecus_doggetti),(Cercopithecus_mitis_heymansi,Cercopithecus_kandti))))),(Cercopithecus_mitis_boutourlinii,(Cercopithecus_albogularis_erythrarchus,((Cercopithecus_albogularis_moloneyi,Cercopithecus_albogularis_albotorquatus),(Cercopithecus_albogularis_labiatus,Cercopithecus_albogularis_monoides))))))),Cercopithecus_diana),(Miopithecus_ogouensis,Miopithecus_talapoin)),(((Chlorocebus_tantalus,((Chlorocebus_pygerythrus,Allenopithecus_nigroviridis),((Chlorocebus_sabaeus,Cercopithecus_aethiops),(Cercopithecus_dryas,Cercopithecus_solatus)))),Chlorocebus_cynosuros),Chlorocebus_aethiops)),(Procolobus_verus,((((Presbytis_melalophos,Rhinopithecus_avunculus),(Trachypithecus_pileatus,(Trachypithecus_johnii,(Trachypithecus_obscurus,((Trachypithecus_francoisi,Semnopithecus_entellus),Trachypithecus_cristatus))))),(((Rhinopithecus_roxellana,(((Simias_concolor,Nasalis_larvatus),(Pygathrix_nemaeus,Pygathrix_nigripes)),Rhinopithecus_bieti_2_RL2012)),Rhinopithecus_brelichi),(Colobus_satanas,Colobus_guereza))),Piliocolobus_badius)))),((Nomascus_leucogenys,((Hylobates_lar,(Hylobates_agilis,Symphalangus_syndactylus)),Hylobates_moloch)),(Pongo_abelii,Pongo_pygmaeus)))),Gorilla_gorilla),Homo_sapiens_ssp_Denisova),Homo_heidelbergensis),(((Pan_paniscus,Pan_troglodytes_troglodytes),Pan_troglodytes),Pan_troglodytes_ellioti),Homo_sapiens); +(((Homo_heidelbergensis,Homo_sapiens_ssp_Denisova),(((((((Saguinus_oedipus,((((Aotus_azarae_azarai,Aotus_trivirgatus),(Aotus_lemurinus,Aotus_azarai)),((Aotus_azarae,((((Cebus_albifrons,Sapajus_xanthosternos),Lagothrix_lagotricha),(Cacajao_calvus,((Brachyteles_arachnoides,Chiropotes_albinasus),Chiropotes_israelita))),(Cebus_apella,(Pithecia_pithecia,(((Callicebus_donacophilus,(Callithrix_jacchus,(Callimico_goeldii,(Ateles_geoffroyi,(Ateles_paniscus,Ateles_belzebuth))))),Callicebus_cupreus),Callicebus_lugens))))),(Leontopithecus_rosalia,(Aotus_nancymaae,((((Saimiri_oerstedii,Saimiri_sciureus),Saimiri_boliviensis),Saimiri_sciureus_macrodon),Saimiri_oerstedii_citrinellus))))),Callithrix_pygmaea)),Alouatta_caraya),(Tarsius_bancanus,(Lemur_catta,((((Otolemur_garnettii,((Galago_moholi,((Nycticebus_coucang,Nycticebus_bengalensis),(Galagoides_demidoff,(Loris_lydekkerianus,Loris_tardigradus)))),(Perodicticus_potto_edwarsi,Perodicticus_potto))),((Otolemur_crassicaudatus,Daubentonia_madagascariensis),((((((Propithecus_coquereli,((Varecia_rubra,Varecia_variegata),(Propithecus_verreauxi,Avahi_laniger))),((Lepilemur_ruficaudatus,Lepilemur_hubbardorum),Indri_indri)),Eulemur_macaco),((((Eulemur_rufus,(Prolemur_simus,((Hapalemur_griseus,Nycticebus_pygmaeus),Cheirogaleus_medius))),Eulemur_rubriventer),Eulemur_mongoz),Eulemur_fulvus)),Palaeopropithecus_ingens),Megaladapis_edwardsi))),((Tarsius_lariang,(Tarsius_wallacei,Tarsius_dentatus)),Tarsius_syrichta)),Galago_senegalensis)))),(((Chlorocebus_tantalus,(Chlorocebus_aethiops,(((Chlorocebus_sabaeus,Cercopithecus_aethiops),(Cercopithecus_dryas,Cercopithecus_solatus)),(Chlorocebus_cynosuros,Chlorocebus_pygerythrus)))),(Miopithecus_talapoin,(((Cercopithecus_diana,(((Cercopithecus_neglectus,(Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis)),((((Cercopithecus_ascanius_katangae,(((Cercopithecus_erythrogaster,((Cercopithecus_petaurista_petaurista,Cercopithecus_petaurista_buettikoferi),Cercopithecus_erythrogaster_pococki)),Cercopithecus_ascanius_schmidti),Cercopithecus_erythrotis_camerunensis)),Cercopithecus_ascanius_whitesidei),(((Cercopithecus_mona,Cercopithecus_campbelli),Cercopithecus_cephus_cephus),(((Cercopithecus_pogonias_schwarzianus,(((Cercopithecus_pogonias_grayi,Cercopithecus_wolfi_pyrogaster),Cercopithecus_pogonias_nigripes),Cercopithecus_wolfi_elegans)),Cercopithecus_pogonias),Cercopithecus_nictitans_martini))),Cercopithecus_petaurista)),((Cercopithecus_albogularis_moloneyi,((Cercopithecus_nictitans,Cercopithecus_nictitans_nictitans),(Cercopithecus_mitis,((Cercopithecus_kandti,(Cercopithecus_doggetti,Cercopithecus_mitis_stuhlmanni)),(Cercopithecus_albogularis_francescae,(((Cercopithecus_mitis_mitis,Cercopithecus_mitis_opisthostictus),Cercopithecus_mitis_heymansi),Cercopithecus_albogularis_kolbi)))))),(((Cercopithecus_albogularis_monoides,Cercopithecus_albogularis_labiatus),((Cercopithecus_albogularis_erythrarchus,Cercopithecus_albogularis_albotorquatus),Cercopithecus_mitis_boutourlinii)),Cercopithecus_albogularis)))),((((((Macaca_fascicularis,((Macaca_silenus,Macaca_tonkeana),(((Macaca_sylvanus,((Macaca_nigra,(Macaca_mulatta,Macaca_fuscata)),Macaca_nemestrina)),Macaca_arctoides),(Macaca_assamensis,Macaca_thibetana)))),((Cercocebus_torquatus,Cercocebus_atys),(Papio_kindae,(((Papio_hamadryas,Theropithecus_gelada),((Lophocebus_aterrimus,Lophocebus_albigena),Papio_ursinus)),((Rungwecebus_kipunji,(Papio_anubis,Papio_cynocephalus)),Papio_papio))))),(Mandrillus_leucophaeus,(Cercocebus_chrysogaster,Cercocebus_agilis))),(Cercopithecus_hamlyni,Mandrillus_sphinx)),(Allenopithecus_nigroviridis,Erythrocebus_patas)),(Cercopithecus_roloway,((Cercopithecus_preussi_preussi,Cercopithecus_preussi_insularis),Cercopithecus_lhoesti)))),Miopithecus_ogouensis))),(Procolobus_verus,((Piliocolobus_badius,(Colobus_satanas,Colobus_guereza)),(Trachypithecus_johnii,((((Trachypithecus_pileatus,((Nasalis_larvatus,((Simias_concolor,((Pygathrix_nemaeus,Rhinopithecus_brelichi),Rhinopithecus_bieti_2_RL2012)),Pygathrix_nigripes)),Rhinopithecus_roxellana)),Trachypithecus_obscurus),(Trachypithecus_francoisi,Trachypithecus_cristatus)),((Semnopithecus_entellus,Presbytis_melalophos),Rhinopithecus_avunculus))))))),((Hylobates_moloch,(Nomascus_leucogenys,(Hylobates_agilis,(Hylobates_lar,Symphalangus_syndactylus)))),(Pongo_abelii,Pongo_pygmaeus))),Gorilla_gorilla_gorilla),Gorilla_gorilla)),(Pan_troglodytes_ellioti,(Pan_troglodytes,(Pan_troglodytes_troglodytes,Pan_paniscus))),Homo_sapiens); +((((Pan_troglodytes,Pan_troglodytes_troglodytes),Pan_troglodytes_ellioti),((((Pongo_pygmaeus,Pongo_abelii),Gorilla_gorilla),(Homo_heidelbergensis,Homo_sapiens_ssp_Denisova)),((Symphalangus_syndactylus,(Gorilla_gorilla_gorilla,(((Alouatta_caraya,(((Saimiri_sciureus_macrodon,(Saimiri_boliviensis,(Saimiri_oerstedii,Saimiri_sciureus))),Saimiri_oerstedii_citrinellus),(((((Callicebus_lugens,Lagothrix_lagotricha),Pithecia_pithecia),(((((Aotus_trivirgatus,(Aotus_azarae,Aotus_azarai)),Aotus_azarae_azarai),Aotus_lemurinus),(Leontopithecus_rosalia,Aotus_nancymaae)),(Saguinus_oedipus,Callithrix_pygmaea))),(((Callicebus_donacophilus,Ateles_belzebuth),(Brachyteles_arachnoides,Callimico_goeldii)),(((Callithrix_jacchus,Ateles_paniscus),Ateles_geoffroyi),Callicebus_cupreus))),(((Chiropotes_israelita,Chiropotes_albinasus),Cacajao_calvus),(Cebus_albifrons,(Sapajus_xanthosternos,Cebus_apella)))))),((((((Avahi_laniger,Megaladapis_edwardsi),(Indri_indri,(Lepilemur_ruficaudatus,Lepilemur_hubbardorum))),(Propithecus_coquereli,((Eulemur_mongoz,((Eulemur_macaco,Cheirogaleus_medius),((Propithecus_verreauxi,(Eulemur_rubriventer,Eulemur_rufus)),((Lemur_catta,((Varecia_variegata,Varecia_rubra),(Nycticebus_pygmaeus,Hapalemur_griseus))),Prolemur_simus)))),Eulemur_fulvus))),Palaeopropithecus_ingens),(Daubentonia_madagascariensis,(((((Galagoides_demidoff,(Loris_tardigradus,Loris_lydekkerianus)),(Nycticebus_bengalensis,Nycticebus_coucang)),(Perodicticus_potto,(Otolemur_crassicaudatus,Otolemur_garnettii))),Perodicticus_potto_edwarsi),((Tarsius_syrichta,(Tarsius_lariang,(Tarsius_wallacei,Tarsius_dentatus))),Galago_moholi)))),(Galago_senegalensis,Tarsius_bancanus))),((((Procolobus_verus,Piliocolobus_badius),(Colobus_guereza,Colobus_satanas)),(Trachypithecus_obscurus,(((Semnopithecus_entellus,((((Pygathrix_nigripes,((Rhinopithecus_bieti_2_RL2012,Rhinopithecus_brelichi),(Pygathrix_nemaeus,Simias_concolor))),Rhinopithecus_roxellana),Nasalis_larvatus),Trachypithecus_pileatus)),((Presbytis_melalophos,(Rhinopithecus_avunculus,Trachypithecus_francoisi)),Trachypithecus_cristatus)),Trachypithecus_johnii))),((Miopithecus_ogouensis,Miopithecus_talapoin),(Cercopithecus_diana,((((((Cercocebus_torquatus,((Cercocebus_chrysogaster,Cercocebus_agilis),Mandrillus_leucophaeus)),(Cercocebus_atys,Mandrillus_sphinx)),((Lophocebus_albigena,Lophocebus_aterrimus),((Papio_kindae,(Papio_papio,(Papio_cynocephalus,(Rungwecebus_kipunji,((Papio_anubis,Papio_ursinus),Papio_hamadryas))))),Theropithecus_gelada))),(Macaca_silenus,((Macaca_sylvanus,(Macaca_assamensis,Macaca_thibetana)),((Macaca_nemestrina,((Macaca_mulatta,Macaca_fuscata),Macaca_nigra)),(Macaca_tonkeana,(Macaca_fascicularis,Macaca_arctoides)))))),((((Cercopithecus_mona,Cercopithecus_campbelli),(((Cercopithecus_pogonias,(((Cercopithecus_pogonias_nigripes,Cercopithecus_pogonias_grayi),(Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans)),Cercopithecus_pogonias_schwarzianus)),Cercopithecus_nictitans_martini),Cercopithecus_neglectus)),((Allenopithecus_nigroviridis,((((Chlorocebus_aethiops,Cercopithecus_hamlyni),Chlorocebus_pygerythrus),(Chlorocebus_cynosuros,Chlorocebus_tantalus)),(Cercopithecus_dryas,((Cercopithecus_aethiops,Cercopithecus_solatus),Chlorocebus_sabaeus)))),(((((Cercopithecus_albogularis_erythrarchus,(Cercopithecus_albogularis_labiatus,(Cercopithecus_albogularis_monoides,Cercopithecus_albogularis_albotorquatus))),Cercopithecus_mitis_boutourlinii),Cercopithecus_albogularis),(Cercopithecus_albogularis_moloneyi,((Cercopithecus_nictitans_nictitans,Cercopithecus_albogularis_francescae),(Cercopithecus_nictitans,(Cercopithecus_mitis,(((Cercopithecus_albogularis_kolbi,Cercopithecus_mitis_stuhlmanni),((Cercopithecus_mitis_mitis,Cercopithecus_mitis_opisthostictus),Cercopithecus_mitis_heymansi)),(Cercopithecus_doggetti,Cercopithecus_kandti))))))),(((Cercopithecus_petaurista,((Cercopithecus_erythrotis_camerunensis,((Cercopithecus_petaurista_buettikoferi,Cercopithecus_petaurista_petaurista),(Cercopithecus_erythrogaster,Cercopithecus_erythrogaster_pococki))),(Cercopithecus_cephus_cephus,Cercopithecus_ascanius_katangae))),((Cercopithecus_ascanius_schmidti,(Cercopithecus_lhoesti,(Cercopithecus_preussi_preussi,Cercopithecus_preussi_insularis))),Cercopithecus_ascanius_whitesidei)),(Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis))))),Cercopithecus_roloway)),Erythrocebus_patas))))))),((Hylobates_agilis,Hylobates_lar),(Hylobates_moloch,Nomascus_leucogenys))))),Pan_paniscus,Homo_sapiens); +(Pan_troglodytes_ellioti,(((Homo_heidelbergensis,(((((Callimico_goeldii,Alouatta_caraya),(((((Chiropotes_albinasus,(Lagothrix_lagotricha,Chiropotes_israelita)),Cacajao_calvus),Pithecia_pithecia),((((Saguinus_oedipus,(Callithrix_jacchus,Callithrix_pygmaea)),(Leontopithecus_rosalia,(((Aotus_trivirgatus,(Aotus_azarae_azarai,Aotus_azarae)),Aotus_nancymaae),((Aotus_azarai,Aotus_lemurinus),(((Saimiri_sciureus,Saimiri_boliviensis),(Saimiri_oerstedii_citrinellus,Saimiri_sciureus_macrodon)),Saimiri_oerstedii))))),Callicebus_lugens),(Callicebus_cupreus,(Callicebus_donacophilus,(Ateles_belzebuth,((Ateles_geoffroyi,Ateles_paniscus),Brachyteles_arachnoides)))))),(Cebus_albifrons,(Sapajus_xanthosternos,Cebus_apella)))),((((((((Loris_tardigradus,Loris_lydekkerianus),(Nycticebus_bengalensis,Nycticebus_coucang)),(Perodicticus_potto,Perodicticus_potto_edwarsi)),((Galago_moholi,Galago_senegalensis),(Galagoides_demidoff,(Otolemur_crassicaudatus,Otolemur_garnettii)))),Daubentonia_madagascariensis),(Avahi_laniger,(((Palaeopropithecus_ingens,(Megaladapis_edwardsi,((((Eulemur_rubriventer,(Eulemur_macaco,(Eulemur_mongoz,(Eulemur_fulvus,((Lepilemur_ruficaudatus,Lepilemur_hubbardorum),Cheirogaleus_medius))))),((Lemur_catta,(Varecia_variegata,Varecia_rubra)),(Nycticebus_pygmaeus,Hapalemur_griseus))),Prolemur_simus),Eulemur_rufus))),(Propithecus_coquereli,Indri_indri)),Propithecus_verreauxi))),((Tarsius_wallacei,(Tarsius_dentatus,Tarsius_lariang)),Tarsius_syrichta)),Tarsius_bancanus)),((((((((Trachypithecus_cristatus,(Trachypithecus_johnii,Trachypithecus_francoisi)),Trachypithecus_obscurus),Trachypithecus_pileatus),(Rhinopithecus_bieti_2_RL2012,((Rhinopithecus_brelichi,Rhinopithecus_roxellana),(((Simias_concolor,Nasalis_larvatus),Pygathrix_nigripes),Pygathrix_nemaeus)))),Rhinopithecus_avunculus),(Presbytis_melalophos,Semnopithecus_entellus)),((Procolobus_verus,Piliocolobus_badius),(Colobus_guereza,Colobus_satanas))),(Miopithecus_ogouensis,((((((Cercopithecus_albogularis,Cercopithecus_albogularis_monoides),((((Cercopithecus_mona,Cercopithecus_campbelli),(((Cercopithecus_pogonias_nigripes,(Cercopithecus_pogonias_grayi,Cercopithecus_pogonias_schwarzianus)),((Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans),Cercopithecus_nictitans_martini)),Cercopithecus_pogonias)),Cercopithecus_albogularis_labiatus),(Cercopithecus_mitis_boutourlinii,Cercopithecus_albogularis_erythrarchus))),(Cercopithecus_roloway,((((((Cercopithecus_nictitans,Cercopithecus_nictitans_nictitans),Cercopithecus_hamlyni),Allenopithecus_nigroviridis),((Chlorocebus_cynosuros,(Chlorocebus_pygerythrus,(Chlorocebus_aethiops,(Chlorocebus_tantalus,(((Cercopithecus_aethiops,Cercopithecus_solatus),Cercopithecus_dryas),Chlorocebus_sabaeus))))),Cercopithecus_mitis_opisthostictus)),((((Cercopithecus_kandti,(Cercopithecus_albogularis_kolbi,Cercopithecus_mitis_stuhlmanni)),(Cercopithecus_mitis_heymansi,Cercopithecus_albogularis_francescae)),Cercopithecus_doggetti),Cercopithecus_mitis)),Cercopithecus_mitis_mitis))),((((((Cercopithecus_lhoesti,(Cercopithecus_preussi_preussi,Cercopithecus_preussi_insularis)),((((Cercopithecus_ascanius_katangae,Cercopithecus_erythrotis_camerunensis),(Cercopithecus_petaurista,(Cercopithecus_erythrogaster,((Cercopithecus_petaurista_buettikoferi,Cercopithecus_erythrogaster_pococki),Cercopithecus_petaurista_petaurista)))),Cercopithecus_cephus_cephus),(Cercopithecus_ascanius_whitesidei,Cercopithecus_neglectus))),(Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis)),Cercopithecus_ascanius_schmidti),Cercopithecus_albogularis_albotorquatus),Cercopithecus_albogularis_moloneyi)),Miopithecus_talapoin),(Cercopithecus_diana,((Erythrocebus_patas,(((Cercocebus_torquatus,(Cercocebus_chrysogaster,(Cercocebus_agilis,Mandrillus_leucophaeus))),(Cercocebus_atys,Mandrillus_sphinx)),(((((Papio_cynocephalus,Papio_kindae),((Papio_papio,(Papio_anubis,Papio_hamadryas)),Papio_ursinus)),Rungwecebus_kipunji),Lophocebus_albigena),(Theropithecus_gelada,Lophocebus_aterrimus)))),((Macaca_fascicularis,(Macaca_silenus,Macaca_tonkeana)),((Macaca_assamensis,Macaca_thibetana),(((Macaca_nemestrina,((Macaca_mulatta,Macaca_fuscata),Macaca_nigra)),Macaca_sylvanus),Macaca_arctoides))))))))),Homo_sapiens_ssp_Denisova)),((Gorilla_gorilla_gorilla,Gorilla_gorilla),((((Pongo_pygmaeus,Pongo_abelii),Hylobates_agilis),(Symphalangus_syndactylus,Hylobates_moloch)),Nomascus_leucogenys))),((Hylobates_lar,(Pan_paniscus,Pan_troglodytes)),Pan_troglodytes_troglodytes)),Homo_sapiens); +(((Homo_heidelbergensis,((Pongo_pygmaeus,(((Pongo_abelii,(Hylobates_moloch,(Nomascus_leucogenys,(Hylobates_agilis,(Hylobates_lar,Symphalangus_syndactylus))))),((((Aotus_azarae_azarai,(Cacajao_calvus,(Chiropotes_israelita,Chiropotes_albinasus))),(Aotus_azarae,(Pithecia_pithecia,(Aotus_trivirgatus,(((((((Saimiri_oerstedii,Saimiri_boliviensis),Saimiri_sciureus),Saimiri_oerstedii_citrinellus),Saimiri_sciureus_macrodon),(Leontopithecus_rosalia,((Saguinus_oedipus,(Aotus_nancymaae,Callithrix_pygmaea)),(Aotus_azarai,Aotus_lemurinus)))),(((Callicebus_lugens,((Callicebus_cupreus,((Ateles_belzebuth,(Callicebus_donacophilus,Brachyteles_arachnoides)),((Ateles_geoffroyi,Callimico_goeldii),Callithrix_jacchus))),Ateles_paniscus)),Lagothrix_lagotricha),(Cebus_albifrons,(Sapajus_xanthosternos,Cebus_apella)))),Alouatta_caraya))))),(Tarsius_bancanus,((Galago_senegalensis,((Avahi_laniger,Daubentonia_madagascariensis),(((Perodicticus_potto,Perodicticus_potto_edwarsi),(((Otolemur_crassicaudatus,((Loris_lydekkerianus,(Galagoides_demidoff,Loris_tardigradus)),(Nycticebus_bengalensis,Nycticebus_coucang))),Otolemur_garnettii),Galago_moholi)),(((((Palaeopropithecus_ingens,((Eulemur_macaco,((Megaladapis_edwardsi,(((Nycticebus_pygmaeus,Hapalemur_griseus),((Varecia_variegata,Varecia_rubra),(((Lemur_catta,Cheirogaleus_medius),Eulemur_rubriventer),(Lepilemur_ruficaudatus,Lepilemur_hubbardorum)))),Prolemur_simus)),Eulemur_rufus)),Eulemur_mongoz)),Propithecus_verreauxi),Indri_indri),Eulemur_fulvus),Propithecus_coquereli)))),(Tarsius_syrichta,(Tarsius_lariang,(Tarsius_wallacei,Tarsius_dentatus)))))),((((((Trachypithecus_cristatus,(Trachypithecus_obscurus,Trachypithecus_francoisi)),(Trachypithecus_johnii,Trachypithecus_pileatus)),(Presbytis_melalophos,(((Rhinopithecus_brelichi,(((((Semnopithecus_entellus,Simias_concolor),Nasalis_larvatus),Pygathrix_nigripes),Pygathrix_nemaeus),Rhinopithecus_bieti_2_RL2012)),Rhinopithecus_roxellana),Rhinopithecus_avunculus))),((Procolobus_verus,Piliocolobus_badius),(Colobus_guereza,Colobus_satanas))),(((((((((((Cercopithecus_albogularis_francescae,(Cercopithecus_mitis_heymansi,((Cercopithecus_albogularis_kolbi,Cercopithecus_mitis_stuhlmanni),Cercopithecus_doggetti))),Cercopithecus_kandti),Cercopithecus_mitis),(((((Chlorocebus_aethiops,(Chlorocebus_cynosuros,Chlorocebus_tantalus)),(Cercopithecus_hamlyni,(Allenopithecus_nigroviridis,Chlorocebus_pygerythrus))),(((Chlorocebus_sabaeus,Cercopithecus_aethiops),Cercopithecus_solatus),Cercopithecus_dryas)),(Cercopithecus_nictitans,Cercopithecus_nictitans_nictitans)),(Cercopithecus_mitis_mitis,Cercopithecus_mitis_opisthostictus))),((Cercopithecus_albogularis,Cercopithecus_albogularis_monoides),((Cercopithecus_albogularis_labiatus,(Cercopithecus_albogularis_erythrarchus,Cercopithecus_mitis_boutourlinii)),Cercopithecus_albogularis_albotorquatus))),Cercopithecus_albogularis_moloneyi),(Cercopithecus_cephus_ngottoensis,((((((((Cercopithecus_petaurista,(Cercopithecus_erythrogaster,((Cercopithecus_petaurista_buettikoferi,Cercopithecus_petaurista_petaurista),Cercopithecus_erythrogaster_pococki))),(Cercopithecus_ascanius_katangae,Cercopithecus_cephus_cephus)),Cercopithecus_erythrotis_camerunensis),Cercopithecus_ascanius_whitesidei),(Cercopithecus_lhoesti,(Cercopithecus_preussi_preussi,Cercopithecus_preussi_insularis))),Cercopithecus_neglectus),Cercopithecus_cephus),Cercopithecus_ascanius_schmidti))),Cercopithecus_roloway),((Cercopithecus_mona,Cercopithecus_campbelli),(((Cercopithecus_pogonias,((Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans),Cercopithecus_nictitans_martini)),(Cercopithecus_pogonias_schwarzianus,Cercopithecus_pogonias_nigripes)),Cercopithecus_pogonias_grayi))),Miopithecus_talapoin),(Cercopithecus_diana,((Erythrocebus_patas,(((Lophocebus_albigena,Mandrillus_sphinx),((Cercocebus_torquatus,(Cercocebus_agilis,(Cercocebus_atys,Cercocebus_chrysogaster))),Mandrillus_leucophaeus)),(((((((Papio_anubis,Papio_ursinus),Papio_cynocephalus),Papio_hamadryas),Papio_papio),Papio_kindae),Rungwecebus_kipunji),(Lophocebus_aterrimus,Theropithecus_gelada)))),((Macaca_tonkeana,((Macaca_assamensis,Macaca_thibetana),(((Macaca_nemestrina,(Macaca_nigra,(Macaca_mulatta,Macaca_fuscata))),Macaca_sylvanus),Macaca_arctoides))),(Macaca_fascicularis,Macaca_silenus)))))),Miopithecus_ogouensis))),Gorilla_gorilla)),Gorilla_gorilla_gorilla)),Homo_sapiens_ssp_Denisova),(((Pan_paniscus,Pan_troglodytes),Pan_troglodytes_troglodytes),Pan_troglodytes_ellioti),Homo_sapiens); +((((((Pongo_pygmaeus,((Pongo_abelii,(((Hylobates_agilis,(Hylobates_lar,Symphalangus_syndactylus)),Nomascus_leucogenys),Hylobates_moloch)),Gorilla_gorilla_gorilla)),(((((Procolobus_verus,Trachypithecus_johnii),((((Trachypithecus_cristatus,((Trachypithecus_obscurus,Trachypithecus_francoisi),(((Pygathrix_nigripes,((Simias_concolor,Pygathrix_nemaeus),Rhinopithecus_brelichi)),Rhinopithecus_bieti_2_RL2012),(Nasalis_larvatus,Rhinopithecus_roxellana)))),Trachypithecus_pileatus),(Rhinopithecus_avunculus,(Presbytis_melalophos,Semnopithecus_entellus))),(Piliocolobus_badius,(Colobus_guereza,Colobus_satanas)))),(Miopithecus_ogouensis,((((Cercopithecus_albogularis,Cercopithecus_roloway),((((((((Cercopithecus_kandti,(Cercopithecus_albogularis_kolbi,Cercopithecus_mitis_stuhlmanni)),((Cercopithecus_albogularis_francescae,Cercopithecus_mitis_heymansi),Cercopithecus_doggetti)),Cercopithecus_mitis),(Cercopithecus_mitis_opisthostictus,Cercopithecus_mitis_mitis)),((Cercopithecus_hamlyni,(((Allenopithecus_nigroviridis,Chlorocebus_pygerythrus),((((Chlorocebus_sabaeus,Cercopithecus_aethiops),Cercopithecus_solatus),Cercopithecus_dryas),(Chlorocebus_cynosuros,Chlorocebus_aethiops))),Chlorocebus_tantalus)),(Cercopithecus_nictitans,Cercopithecus_nictitans_nictitans))),(((Cercopithecus_albogularis_monoides,Cercopithecus_albogularis_erythrarchus),Cercopithecus_mitis_boutourlinii),(Cercopithecus_albogularis_albotorquatus,Cercopithecus_albogularis_labiatus))),Cercopithecus_albogularis_moloneyi),(((Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis),(((((((Cercopithecus_petaurista,(Cercopithecus_erythrogaster,((Cercopithecus_petaurista_buettikoferi,Cercopithecus_petaurista_petaurista),Cercopithecus_erythrogaster_pococki))),Cercopithecus_cephus_cephus),Cercopithecus_ascanius_katangae),Cercopithecus_ascanius_whitesidei),((Cercopithecus_erythrotis_camerunensis,Cercopithecus_preussi_preussi),Cercopithecus_preussi_insularis)),Cercopithecus_neglectus),Cercopithecus_lhoesti)),(((Cercopithecus_mona,Cercopithecus_campbelli),(Cercopithecus_pogonias_grayi,((Cercopithecus_pogonias,Cercopithecus_pogonias_schwarzianus),(Cercopithecus_pogonias_nigripes,((Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans),Cercopithecus_nictitans_martini))))),Cercopithecus_ascanius_schmidti)))),Miopithecus_talapoin),(Cercopithecus_diana,(Mandrillus_sphinx,(Erythrocebus_patas,((((Cercocebus_atys,(((((Papio_hamadryas,Theropithecus_gelada),((Lophocebus_aterrimus,(Papio_anubis,Rungwecebus_kipunji)),(Papio_ursinus,Lophocebus_albigena))),Papio_papio),Papio_cynocephalus),Papio_kindae)),(((Macaca_tonkeana,((Macaca_assamensis,Macaca_thibetana),((Macaca_nemestrina,((Macaca_mulatta,Macaca_fuscata),Macaca_arctoides)),Macaca_nigra))),(Macaca_fascicularis,Macaca_silenus)),Macaca_sylvanus)),Cercocebus_torquatus),(Cercocebus_chrysogaster,(Cercocebus_agilis,Mandrillus_leucophaeus))))))))),((((Saguinus_oedipus,Callithrix_pygmaea),(((((Aotus_trivirgatus,Aotus_azarae),((Aotus_azarai,Aotus_lemurinus),Aotus_azarae_azarai)),(Aotus_nancymaae,((Saimiri_sciureus_macrodon,Saimiri_oerstedii_citrinellus),((Saimiri_oerstedii,Saimiri_sciureus),Saimiri_boliviensis)))),Leontopithecus_rosalia),(((Callicebus_lugens,(Callicebus_cupreus,((Callicebus_donacophilus,Brachyteles_arachnoides),(Callithrix_jacchus,((Ateles_paniscus,(Callimico_goeldii,Ateles_belzebuth)),Ateles_geoffroyi))))),(Sapajus_xanthosternos,(Cebus_apella,Cebus_albifrons))),(Pithecia_pithecia,(Cacajao_calvus,((Lagothrix_lagotricha,Chiropotes_israelita),Chiropotes_albinasus)))))),Alouatta_caraya),(Tarsius_bancanus,(((((Propithecus_coquereli,(((((Eulemur_mongoz,Megaladapis_edwardsi),(((Lemur_catta,((Nycticebus_pygmaeus,(Varecia_variegata,Varecia_rubra)),Hapalemur_griseus)),(Cheirogaleus_medius,(Lepilemur_ruficaudatus,Lepilemur_hubbardorum))),Prolemur_simus)),Eulemur_rubriventer),((Eulemur_fulvus,Eulemur_macaco),(Palaeopropithecus_ingens,Eulemur_rufus))),(Indri_indri,(Perodicticus_potto,Avahi_laniger)))),Propithecus_verreauxi),((Perodicticus_potto_edwarsi,((Otolemur_garnettii,(Galago_moholi,Galagoides_demidoff)),(Galago_senegalensis,Otolemur_crassicaudatus))),((Loris_lydekkerianus,Loris_tardigradus),(Nycticebus_bengalensis,Nycticebus_coucang)))),Daubentonia_madagascariensis),(Tarsius_syrichta,(Tarsius_lariang,(Tarsius_dentatus,Tarsius_wallacei))))))),Gorilla_gorilla)),Homo_heidelbergensis),Homo_sapiens_ssp_Denisova),Pan_troglodytes_ellioti),((Pan_paniscus,Pan_troglodytes),Pan_troglodytes_troglodytes),Homo_sapiens); +((Homo_heidelbergensis,((((Pongo_pygmaeus,Pongo_abelii),((Hylobates_lar,(Hylobates_agilis,Symphalangus_syndactylus)),(Nomascus_leucogenys,Hylobates_moloch))),((Homo_sapiens_ssp_Denisova,(((Miopithecus_ogouensis,((((Cercopithecus_diana,Erythrocebus_patas),(((Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans),Cercopithecus_nictitans_martini),((Cercopithecus_pogonias,(Cercopithecus_mona,Cercopithecus_campbelli)),(Cercopithecus_pogonias_grayi,(Cercopithecus_pogonias_schwarzianus,Cercopithecus_pogonias_nigripes))))),(((Mandrillus_sphinx,Cercocebus_atys),(((Cercocebus_agilis,Mandrillus_leucophaeus),Cercocebus_chrysogaster),Cercocebus_torquatus)),((((((Macaca_assamensis,Macaca_thibetana),(((Macaca_nemestrina,Macaca_sylvanus),(Macaca_fuscata,Macaca_nigra)),Macaca_arctoides)),(Macaca_silenus,Macaca_tonkeana)),Macaca_fascicularis),Macaca_mulatta),((((Papio_papio,((Papio_ursinus,Papio_anubis),Papio_hamadryas)),Papio_cynocephalus),Papio_kindae),((Theropithecus_gelada,(Lophocebus_albigena,Lophocebus_aterrimus)),Rungwecebus_kipunji))))),(((((Cercopithecus_albogularis_moloneyi,Cercopithecus_albogularis_francescae),(Cercopithecus_mitis,((Cercopithecus_kandti,(Cercopithecus_doggetti,((Cercopithecus_nictitans_nictitans,(Cercopithecus_nictitans,Cercopithecus_albogularis_kolbi)),Cercopithecus_mitis_stuhlmanni))),((Cercopithecus_mitis_heymansi,(Cercopithecus_mitis_opisthostictus,Cercopithecus_mitis_mitis)),(((Cercopithecus_albogularis_labiatus,Cercopithecus_mitis_boutourlinii),Cercopithecus_albogularis_albotorquatus),(Cercopithecus_albogularis_erythrarchus,(Cercopithecus_albogularis,Cercopithecus_albogularis_monoides))))))),((Cercopithecus_ascanius_schmidti,(Cercopithecus_cephus,((((Cercopithecus_petaurista,((Cercopithecus_petaurista_buettikoferi,Cercopithecus_petaurista_petaurista),(Cercopithecus_erythrogaster_pococki,Cercopithecus_erythrogaster))),Cercopithecus_cephus_cephus),((Cercopithecus_lhoesti,((Cercopithecus_erythrotis_camerunensis,(Cercopithecus_preussi_preussi,Cercopithecus_preussi_insularis)),Cercopithecus_ascanius_katangae)),Cercopithecus_ascanius_whitesidei)),Cercopithecus_neglectus))),Cercopithecus_cephus_ngottoensis)),Cercopithecus_roloway),(((Chlorocebus_tantalus,(((((Chlorocebus_sabaeus,Cercopithecus_aethiops),Cercopithecus_solatus),Cercopithecus_dryas),Chlorocebus_pygerythrus),(Chlorocebus_aethiops,(Chlorocebus_cynosuros,Cercopithecus_hamlyni)))),Allenopithecus_nigroviridis),Miopithecus_talapoin)))),(Procolobus_verus,(((Colobus_guereza,Colobus_satanas),Piliocolobus_badius),(((Presbytis_melalophos,Semnopithecus_entellus),(Rhinopithecus_avunculus,Trachypithecus_johnii)),(((Trachypithecus_cristatus,(Trachypithecus_obscurus,Trachypithecus_francoisi)),Trachypithecus_pileatus),(((Pygathrix_nigripes,Pygathrix_nemaeus),(Simias_concolor,Nasalis_larvatus)),(Rhinopithecus_roxellana,(Rhinopithecus_bieti_2_RL2012,Rhinopithecus_brelichi)))))))),(((Saguinus_oedipus,((Callithrix_jacchus,Callithrix_pygmaea),(Lagothrix_lagotricha,(Aotus_nancymaae,(((((Aotus_azarae_azarai,((Aotus_trivirgatus,(Callicebus_lugens,((((Ateles_belzebuth,Callicebus_cupreus),Ateles_geoffroyi),Ateles_paniscus),Callicebus_donacophilus))),((((Saimiri_oerstedii,Saimiri_sciureus_macrodon),(Saimiri_boliviensis,Saimiri_sciureus)),Saimiri_oerstedii_citrinellus),((Cebus_albifrons,(Sapajus_xanthosternos,Cebus_apella)),(Cacajao_calvus,(Chiropotes_israelita,(Brachyteles_arachnoides,Chiropotes_albinasus))))))),Aotus_azarae),(Callimico_goeldii,Leontopithecus_rosalia)),(Aotus_azarai,Aotus_lemurinus)),Pithecia_pithecia))))),Alouatta_caraya),(Tarsius_bancanus,(((((Propithecus_verreauxi,(Avahi_laniger,Propithecus_coquereli)),((Lepilemur_ruficaudatus,Lepilemur_hubbardorum),Indri_indri)),((((Megaladapis_edwardsi,Eulemur_rubriventer),Cheirogaleus_medius),(Eulemur_fulvus,((Eulemur_macaco,(Prolemur_simus,(Eulemur_rufus,((Lemur_catta,(Varecia_variegata,Varecia_rubra)),(Hapalemur_griseus,Nycticebus_pygmaeus))))),Eulemur_mongoz))),Palaeopropithecus_ingens)),(((Galago_moholi,(Galagoides_demidoff,(Otolemur_crassicaudatus,(Galago_senegalensis,Otolemur_garnettii)))),((Perodicticus_potto,((Loris_lydekkerianus,Loris_tardigradus),(Nycticebus_bengalensis,Nycticebus_coucang))),Perodicticus_potto_edwarsi)),Daubentonia_madagascariensis)),(Tarsius_syrichta,(Tarsius_lariang,(Tarsius_wallacei,Tarsius_dentatus)))))))),Gorilla_gorilla_gorilla)),Gorilla_gorilla)),((Pan_troglodytes_troglodytes,(Pan_paniscus,Pan_troglodytes)),Pan_troglodytes_ellioti),Homo_sapiens); +(((Homo_sapiens_ssp_Denisova,((((((((Callithrix_pygmaea,Saguinus_oedipus),(((((Ateles_paniscus,(Callithrix_jacchus,(Ateles_belzebuth,Ateles_geoffroyi))),Callimico_goeldii),Lagothrix_lagotricha),((((Callicebus_lugens,(Callicebus_cupreus,Callicebus_donacophilus)),(Sapajus_xanthosternos,(Cebus_apella,Cebus_albifrons))),((((((Saimiri_oerstedii,Saimiri_boliviensis),Saimiri_sciureus),Saimiri_sciureus_macrodon),Saimiri_oerstedii_citrinellus),Cacajao_calvus),(Chiropotes_israelita,(Brachyteles_arachnoides,Chiropotes_albinasus)))),((Aotus_nancymaae,Leontopithecus_rosalia),(Aotus_trivirgatus,(((Aotus_azarae,Aotus_azarae_azarai),Aotus_lemurinus),Aotus_azarai))))),Pithecia_pithecia)),Alouatta_caraya),(((Megaladapis_edwardsi,Avahi_laniger),((Palaeopropithecus_ingens,(Propithecus_coquereli,((Eulemur_rufus,((Eulemur_rubriventer,(Eulemur_fulvus,(Eulemur_mongoz,Eulemur_macaco))),((Cheirogaleus_medius,((Nycticebus_pygmaeus,(Varecia_variegata,Varecia_rubra)),(Hapalemur_griseus,Lemur_catta))),Prolemur_simus))),Indri_indri))),(Daubentonia_madagascariensis,((((Otolemur_crassicaudatus,((Galago_senegalensis,Galago_moholi),Galagoides_demidoff)),Otolemur_garnettii),((Perodicticus_potto,Perodicticus_potto_edwarsi),((Propithecus_verreauxi,(Loris_lydekkerianus,Loris_tardigradus)),(Nycticebus_bengalensis,Nycticebus_coucang)))),((Lepilemur_ruficaudatus,Lepilemur_hubbardorum),(Tarsius_syrichta,((Tarsius_dentatus,Tarsius_lariang),Tarsius_wallacei))))))),Tarsius_bancanus)),((Miopithecus_ogouensis,(((((((((Cercopithecus_erythrotis_camerunensis,Cercopithecus_ascanius_katangae),((Cercopithecus_petaurista,((Cercopithecus_petaurista_buettikoferi,Cercopithecus_petaurista_petaurista),(Cercopithecus_erythrogaster_pococki,Cercopithecus_erythrogaster))),Cercopithecus_cephus_cephus)),(Cercopithecus_ascanius_whitesidei,Cercopithecus_ascanius_schmidti)),(Cercopithecus_lhoesti,(Cercopithecus_preussi_preussi,Cercopithecus_preussi_insularis))),(((((Cercopithecus_pogonias_schwarzianus,((Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans),Cercopithecus_nictitans_martini)),(Cercopithecus_pogonias_nigripes,Cercopithecus_pogonias_grayi)),Cercopithecus_pogonias),(Cercopithecus_mona,Cercopithecus_campbelli)),(Cercopithecus_neglectus,(Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis)))),Cercopithecus_roloway),((Chlorocebus_pygerythrus,((((Cercopithecus_aethiops,Cercopithecus_solatus),Chlorocebus_sabaeus),(Cercopithecus_albogularis_francescae,(((Cercopithecus_kandti,(((Cercopithecus_albogularis_kolbi,Cercopithecus_mitis_stuhlmanni),Cercopithecus_mitis),Cercopithecus_doggetti)),(Cercopithecus_nictitans_nictitans,Cercopithecus_nictitans)),(Cercopithecus_mitis_heymansi,(Cercopithecus_mitis_mitis,(Cercopithecus_mitis_opisthostictus,((Cercopithecus_albogularis,Cercopithecus_albogularis_monoides),((Cercopithecus_mitis_boutourlinii,((Cercopithecus_albogularis_moloneyi,Cercopithecus_albogularis_albotorquatus),Cercopithecus_albogularis_labiatus)),Cercopithecus_albogularis_erythrarchus)))))))),Cercopithecus_dryas)),(Chlorocebus_aethiops,(((Chlorocebus_cynosuros,Allenopithecus_nigroviridis),Cercopithecus_hamlyni),Chlorocebus_tantalus)))),Miopithecus_talapoin),((Cercopithecus_diana,Erythrocebus_patas),(((((((((((Lophocebus_albigena,Lophocebus_aterrimus),Papio_ursinus),Rungwecebus_kipunji),(Papio_anubis,Papio_hamadryas)),Theropithecus_gelada),((Papio_cynocephalus,Papio_papio),Papio_kindae)),Macaca_silenus),(Macaca_assamensis,Macaca_thibetana)),(((((Macaca_mulatta,Macaca_fuscata),Macaca_nigra),Macaca_nemestrina),Macaca_sylvanus),(Macaca_tonkeana,Macaca_arctoides))),Macaca_fascicularis),((Mandrillus_sphinx,Cercocebus_atys),((Cercocebus_chrysogaster,(Cercocebus_agilis,Mandrillus_leucophaeus)),Cercocebus_torquatus)))))),((Procolobus_verus,((Colobus_guereza,Colobus_satanas),Piliocolobus_badius)),((((Pygathrix_nemaeus,Trachypithecus_pileatus),(Nasalis_larvatus,(Rhinopithecus_roxellana,(Trachypithecus_obscurus,((Trachypithecus_cristatus,(((Rhinopithecus_brelichi,Rhinopithecus_bieti_2_RL2012),Pygathrix_nigripes),Trachypithecus_francoisi)),Simias_concolor))))),Trachypithecus_johnii),((Presbytis_melalophos,Semnopithecus_entellus),Rhinopithecus_avunculus))))),((Pongo_pygmaeus,Pongo_abelii),(((Hylobates_agilis,(Hylobates_lar,Symphalangus_syndactylus)),Nomascus_leucogenys),Hylobates_moloch))),Gorilla_gorilla),Gorilla_gorilla_gorilla)),Homo_heidelbergensis),(Pan_troglodytes_ellioti,(Pan_troglodytes_troglodytes,(Pan_paniscus,Pan_troglodytes))),Homo_sapiens); +((Homo_heidelbergensis,((Homo_sapiens_ssp_Denisova,((Gorilla_gorilla_gorilla,Pongo_pygmaeus),((Pongo_abelii,((Nomascus_leucogenys,(Hylobates_moloch,Hylobates_lar)),(Symphalangus_syndactylus,Hylobates_agilis))),((((((Saimiri_sciureus_macrodon,((Saimiri_oerstedii,Saimiri_boliviensis),Saimiri_sciureus)),Saimiri_oerstedii_citrinellus),((Chiropotes_israelita,(((((((Cebus_albifrons,(Sapajus_xanthosternos,Cebus_apella)),(Pithecia_pithecia,(Callicebus_lugens,((Callimico_goeldii,(Ateles_paniscus,(Ateles_belzebuth,Ateles_geoffroyi))),(Callicebus_cupreus,Callicebus_donacophilus))))),((Aotus_lemurinus,((Callithrix_jacchus,Callithrix_pygmaea),(Aotus_nancymaae,Saguinus_oedipus))),Aotus_azarai)),((Aotus_azarae_azarai,Cacajao_calvus),Aotus_trivirgatus)),Leontopithecus_rosalia),Aotus_azarae),Lagothrix_lagotricha)),(Brachyteles_arachnoides,Chiropotes_albinasus))),Alouatta_caraya),(Tarsius_bancanus,((Galago_senegalensis,(((Palaeopropithecus_ingens,(Eulemur_mongoz,(Eulemur_rufus,(((Eulemur_fulvus,((((Nycticebus_pygmaeus,(Varecia_variegata,Varecia_rubra)),(Hapalemur_griseus,Lemur_catta)),Prolemur_simus),Cheirogaleus_medius)),Eulemur_macaco),Eulemur_rubriventer)))),Indri_indri),(Propithecus_verreauxi,(((Daubentonia_madagascariensis,(Galago_moholi,((Otolemur_crassicaudatus,((Galagoides_demidoff,(Loris_lydekkerianus,Loris_tardigradus)),(Nycticebus_bengalensis,((Nycticebus_coucang,Otolemur_garnettii),Perodicticus_potto)))),Perodicticus_potto_edwarsi))),((Lepilemur_ruficaudatus,Lepilemur_hubbardorum),(Tarsius_syrichta,((Tarsius_wallacei,Tarsius_dentatus),Tarsius_lariang)))),Propithecus_coquereli)))),(Megaladapis_edwardsi,Avahi_laniger)))),((Miopithecus_ogouensis,(((((Cercocebus_atys,((((((Theropithecus_gelada,(Lophocebus_albigena,Lophocebus_aterrimus)),(Rungwecebus_kipunji,(Papio_kindae,(Papio_papio,(((Papio_anubis,Papio_cynocephalus),Papio_ursinus),Papio_hamadryas))))),Macaca_silenus),(Macaca_assamensis,Macaca_thibetana)),(Macaca_tonkeana,(Macaca_arctoides,((Macaca_sylvanus,((Macaca_mulatta,Macaca_fuscata),Macaca_nigra)),Macaca_nemestrina)))),Macaca_fascicularis)),((Cercocebus_agilis,Mandrillus_leucophaeus),(Cercocebus_chrysogaster,Cercocebus_torquatus))),(((((((((((Cercopithecus_pogonias_grayi,Cercopithecus_pogonias_nigripes),Cercopithecus_pogonias_schwarzianus),((Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans),Cercopithecus_nictitans_martini)),Cercopithecus_pogonias),(Cercopithecus_mona,Cercopithecus_campbelli)),((((Cercopithecus_lhoesti,(Cercopithecus_preussi_preussi,Cercopithecus_preussi_insularis)),(Cercopithecus_ascanius_schmidti,(Cercopithecus_ascanius_whitesidei,(Cercopithecus_cephus_cephus,(((Cercopithecus_petaurista,((Cercopithecus_petaurista_buettikoferi,Cercopithecus_petaurista_petaurista),(Cercopithecus_erythrogaster,Cercopithecus_erythrogaster_pococki))),Cercopithecus_erythrotis_camerunensis),Cercopithecus_ascanius_katangae))))),Allenopithecus_nigroviridis),Cercopithecus_cephus)),(Cercopithecus_cephus_ngottoensis,Cercopithecus_neglectus)),(((Cercopithecus_albogularis_moloneyi,((((Cercopithecus_doggetti,(Cercopithecus_mitis,Cercopithecus_kandti)),Cercopithecus_albogularis_francescae),Cercopithecus_mitis_stuhlmanni),(Cercopithecus_albogularis_kolbi,(Cercopithecus_mitis_heymansi,((Cercopithecus_albogularis,Cercopithecus_albogularis_monoides),(((Cercopithecus_albogularis_erythrarchus,(Cercopithecus_albogularis_labiatus,Cercopithecus_albogularis_albotorquatus)),Cercopithecus_mitis_boutourlinii),(Cercopithecus_mitis_mitis,Cercopithecus_mitis_opisthostictus))))))),(Cercopithecus_nictitans_nictitans,Cercopithecus_nictitans)),Cercopithecus_roloway)),(((((Chlorocebus_pygerythrus,Chlorocebus_aethiops),Chlorocebus_cynosuros),((Chlorocebus_sabaeus,Cercopithecus_aethiops),Cercopithecus_dryas)),Chlorocebus_tantalus),Cercopithecus_hamlyni)),Cercopithecus_solatus),Miopithecus_talapoin)),Mandrillus_sphinx),(Cercopithecus_diana,Erythrocebus_patas))),(((Trachypithecus_johnii,(Piliocolobus_badius,(Colobus_guereza,Colobus_satanas))),(Rhinopithecus_avunculus,(Presbytis_melalophos,(((Rhinopithecus_roxellana,((Semnopithecus_entellus,(Simias_concolor,Nasalis_larvatus)),(Pygathrix_nemaeus,Pygathrix_nigripes))),(Rhinopithecus_brelichi,Rhinopithecus_bieti_2_RL2012)),(Trachypithecus_francoisi,((Trachypithecus_obscurus,Trachypithecus_pileatus),Trachypithecus_cristatus)))))),Procolobus_verus)))))),Gorilla_gorilla)),((Pan_troglodytes,(Pan_troglodytes_troglodytes,Pan_paniscus)),Pan_troglodytes_ellioti),Homo_sapiens); +(((((Symphalangus_syndactylus,Nomascus_leucogenys),Hylobates_moloch),Hylobates_agilis),Hylobates_lar),(((Pan_troglodytes_troglodytes,((((((((((Chiropotes_albinasus,(((Cacajao_calvus,(((Saimiri_sciureus_macrodon,(Saimiri_boliviensis,(Saimiri_oerstedii,Saimiri_sciureus))),Saimiri_oerstedii_citrinellus),Aotus_azarae)),Chiropotes_israelita),((Callimico_goeldii,Leontopithecus_rosalia),(Pithecia_pithecia,(((Callicebus_lugens,((Ateles_geoffroyi,(Ateles_belzebuth,(Callicebus_donacophilus,(Ateles_paniscus,(Callithrix_jacchus,Brachyteles_arachnoides))))),Callicebus_cupreus)),(((Aotus_azarai,Aotus_lemurinus),((Aotus_nancymaae,Aotus_trivirgatus),Aotus_azarae_azarai)),((Lagothrix_lagotricha,Callithrix_pygmaea),Saguinus_oedipus))),(Sapajus_xanthosternos,(Cebus_apella,Cebus_albifrons))))))),Alouatta_caraya),(((((((((Propithecus_verreauxi,(Nycticebus_pygmaeus,(Palaeopropithecus_ingens,(Eulemur_rufus,((Eulemur_rubriventer,(Eulemur_mongoz,(((Prolemur_simus,((Hapalemur_griseus,((Lemur_catta,Varecia_variegata),Varecia_rubra)),Cheirogaleus_medius)),Eulemur_fulvus),(((Tarsius_lariang,(Tarsius_wallacei,Tarsius_dentatus)),Tarsius_syrichta),(Lepilemur_ruficaudatus,Lepilemur_hubbardorum))))),Eulemur_macaco))))),Indri_indri),((Perodicticus_potto,Perodicticus_potto_edwarsi),((((Galago_senegalensis,Galago_moholi),(Galagoides_demidoff,(Otolemur_garnettii,Otolemur_crassicaudatus))),Loris_lydekkerianus),(Nycticebus_bengalensis,Nycticebus_coucang)))),Megaladapis_edwardsi),Daubentonia_madagascariensis),Propithecus_coquereli),Loris_tardigradus),Avahi_laniger),Tarsius_bancanus)),(Miopithecus_ogouensis,(((((((Colobus_guereza,Colobus_satanas),Piliocolobus_badius),Procolobus_verus),((Trachypithecus_johnii,((Trachypithecus_pileatus,Trachypithecus_cristatus),(((Pygathrix_nemaeus,(Nasalis_larvatus,Simias_concolor)),(Pygathrix_nigripes,(Rhinopithecus_roxellana,(Rhinopithecus_brelichi,Rhinopithecus_bieti_2_RL2012)))),(Trachypithecus_obscurus,Trachypithecus_francoisi)))),(Rhinopithecus_avunculus,(Semnopithecus_entellus,Presbytis_melalophos)))),((((((Papio_papio,(Papio_anubis,Papio_hamadryas)),((Rungwecebus_kipunji,Theropithecus_gelada),((Lophocebus_albigena,Lophocebus_aterrimus),Papio_ursinus))),(Papio_cynocephalus,Papio_kindae)),((Macaca_silenus,Macaca_tonkeana),(((((Macaca_arctoides,(Macaca_mulatta,Macaca_fuscata)),Macaca_nigra),Macaca_nemestrina),Macaca_sylvanus),(Macaca_assamensis,Macaca_thibetana)))),Macaca_fascicularis),(((Cercocebus_atys,Mandrillus_sphinx),Cercocebus_torquatus),((Mandrillus_leucophaeus,Cercocebus_chrysogaster),Cercocebus_agilis)))),(((((Cercopithecus_albogularis_francescae,(((Cercopithecus_doggetti,Cercopithecus_mitis),Cercopithecus_kandti),((Cercopithecus_mitis_stuhlmanni,Cercopithecus_albogularis_kolbi),(Cercopithecus_mitis_heymansi,(((Cercopithecus_mitis_mitis,Cercopithecus_mitis_opisthostictus),(Cercopithecus_nictitans_nictitans,Cercopithecus_nictitans)),(((Cercopithecus_albogularis_albotorquatus,(Cercopithecus_mitis_boutourlinii,Cercopithecus_albogularis_monoides)),Cercopithecus_albogularis),(Cercopithecus_albogularis_erythrarchus,Cercopithecus_albogularis_labiatus))))))),Cercopithecus_albogularis_moloneyi),(Allenopithecus_nigroviridis,Cercopithecus_roloway)),(((((Cercopithecus_cephus_ngottoensis,(Cercopithecus_ascanius_schmidti,Cercopithecus_ascanius_whitesidei)),((((Cercopithecus_erythrotis_camerunensis,((Cercopithecus_preussi_preussi,Cercopithecus_preussi_insularis),Cercopithecus_lhoesti)),Cercopithecus_ascanius_katangae),((Cercopithecus_petaurista_buettikoferi,Cercopithecus_petaurista_petaurista),(Cercopithecus_erythrogaster,Cercopithecus_erythrogaster_pococki))),Cercopithecus_petaurista)),Cercopithecus_cephus),(Cercopithecus_neglectus,(Cercopithecus_cephus_cephus,(((Cercopithecus_pogonias,((Cercopithecus_pogonias_grayi,(Cercopithecus_pogonias_nigripes,Cercopithecus_pogonias_schwarzianus)),(Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans))),Cercopithecus_nictitans_martini),(Cercopithecus_mona,Cercopithecus_campbelli))))),(Cercopithecus_dryas,(((Chlorocebus_sabaeus,Cercopithecus_aethiops),Cercopithecus_solatus),(((Chlorocebus_aethiops,Chlorocebus_tantalus),Chlorocebus_pygerythrus),(Chlorocebus_cynosuros,Cercopithecus_hamlyni)))))),Miopithecus_talapoin)),(Cercopithecus_diana,Erythrocebus_patas)))),Homo_sapiens_ssp_Denisova),Gorilla_gorilla_gorilla),(Pongo_pygmaeus,Pongo_abelii)),Gorilla_gorilla),Homo_heidelbergensis),Pan_troglodytes_ellioti)),Pan_paniscus),Pan_troglodytes),Homo_sapiens); +((Pan_paniscus,(Pan_troglodytes,Pan_troglodytes_troglodytes)),(((((((Hylobates_agilis,(Pongo_pygmaeus,Pongo_abelii)),Hylobates_moloch),Symphalangus_syndactylus),Nomascus_leucogenys),Hylobates_lar),(((Homo_sapiens_ssp_Denisova,(((((((Sapajus_xanthosternos,Cebus_apella),Cebus_albifrons),(Aotus_trivirgatus,((Lagothrix_lagotricha,Aotus_nancymaae),((Callicebus_lugens,((((((Callicebus_cupreus,Callimico_goeldii),Ateles_geoffroyi),Ateles_belzebuth),Callicebus_donacophilus),Callithrix_jacchus),Ateles_paniscus)),((Aotus_azarai,Aotus_lemurinus),(Callithrix_pygmaea,Saguinus_oedipus)))))),(Pithecia_pithecia,(Aotus_azarae_azarai,(Aotus_azarae,((Alouatta_caraya,((Saimiri_sciureus_macrodon,((Saimiri_oerstedii,Saimiri_sciureus),Saimiri_boliviensis)),Saimiri_oerstedii_citrinellus)),(Cacajao_calvus,((Brachyteles_arachnoides,Chiropotes_albinasus),Chiropotes_israelita))))))),Leontopithecus_rosalia),(((Daubentonia_madagascariensis,((((Propithecus_verreauxi,(Indri_indri,Propithecus_coquereli)),(((((Eulemur_macaco,Eulemur_rufus),Eulemur_mongoz),Varecia_variegata),(Eulemur_rubriventer,((((Tarsius_lariang,(Tarsius_wallacei,Tarsius_dentatus)),Tarsius_syrichta),(Lepilemur_ruficaudatus,Lepilemur_hubbardorum)),((Prolemur_simus,((Varecia_rubra,(Lemur_catta,Cheirogaleus_medius)),Hapalemur_griseus)),Eulemur_fulvus)))),Palaeopropithecus_ingens)),((Perodicticus_potto,Perodicticus_potto_edwarsi),(Galago_moholi,(((Galagoides_demidoff,Otolemur_crassicaudatus),(Otolemur_garnettii,Galago_senegalensis)),((Loris_tardigradus,Loris_lydekkerianus),(Nycticebus_bengalensis,(Nycticebus_pygmaeus,Nycticebus_coucang))))))),Megaladapis_edwardsi)),Avahi_laniger),Tarsius_bancanus)),((Miopithecus_ogouensis,(((Miopithecus_talapoin,((((((Cercopithecus_pogonias,(Cercopithecus_pogonias_schwarzianus,(Cercopithecus_pogonias_nigripes,((Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans),Cercopithecus_pogonias_grayi)))),(Cercopithecus_mona,Cercopithecus_campbelli)),Cercopithecus_nictitans_martini),Cercopithecus_cephus_cephus),Cercopithecus_neglectus),((Cercopithecus_albogularis_francescae,((Cercopithecus_albogularis_albotorquatus,(((Cercopithecus_mitis_opisthostictus,Cercopithecus_mitis_mitis),((Cercopithecus_mitis_heymansi,((Cercopithecus_kandti,((Cercopithecus_mitis_stuhlmanni,(Cercopithecus_nictitans_nictitans,Cercopithecus_nictitans)),Cercopithecus_doggetti)),Cercopithecus_mitis)),Cercopithecus_albogularis_kolbi)),((Cercopithecus_albogularis,Cercopithecus_albogularis_monoides),(Cercopithecus_albogularis_labiatus,(Cercopithecus_albogularis_erythrarchus,Cercopithecus_mitis_boutourlinii))))),Cercopithecus_albogularis_moloneyi)),(((Cercopithecus_erythrotis_camerunensis,Cercopithecus_ascanius_katangae),((Cercopithecus_preussi_preussi,Cercopithecus_preussi_insularis),Cercopithecus_lhoesti)),(((Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis),(Cercopithecus_ascanius_whitesidei,((Cercopithecus_erythrogaster_pococki,Cercopithecus_petaurista_buettikoferi),(Cercopithecus_petaurista_petaurista,(Cercopithecus_petaurista,Cercopithecus_erythrogaster))))),Cercopithecus_ascanius_schmidti))))),((Cercopithecus_dryas,((((Chlorocebus_aethiops,Cercopithecus_hamlyni),(Chlorocebus_tantalus,Chlorocebus_cynosuros)),Chlorocebus_pygerythrus),((Cercopithecus_solatus,Cercopithecus_aethiops),Chlorocebus_sabaeus))),((((((Papio_ursinus,(Papio_papio,(Papio_anubis,Papio_hamadryas))),(Rungwecebus_kipunji,(Theropithecus_gelada,(Lophocebus_albigena,Lophocebus_aterrimus)))),(Papio_cynocephalus,Papio_kindae)),((((Macaca_tonkeana,Macaca_silenus),Macaca_fascicularis),((Macaca_arctoides,(Macaca_nemestrina,((Macaca_sylvanus,Macaca_fuscata),Macaca_nigra))),(Macaca_mulatta,(Macaca_assamensis,Macaca_thibetana)))),Cercocebus_atys)),(Cercocebus_torquatus,(Cercocebus_chrysogaster,(Cercocebus_agilis,Mandrillus_leucophaeus)))),Mandrillus_sphinx))),(Cercopithecus_diana,((Erythrocebus_patas,Allenopithecus_nigroviridis),Cercopithecus_roloway)))),((Piliocolobus_badius,((Presbytis_melalophos,(Rhinopithecus_avunculus,(Trachypithecus_johnii,((Trachypithecus_cristatus,(Semnopithecus_entellus,(Trachypithecus_obscurus,Trachypithecus_francoisi))),Trachypithecus_pileatus)))),((Colobus_guereza,Colobus_satanas),(Rhinopithecus_roxellana,((Rhinopithecus_bieti_2_RL2012,Rhinopithecus_brelichi),(((Nasalis_larvatus,Simias_concolor),Pygathrix_nemaeus),Pygathrix_nigripes)))))),Procolobus_verus)))),(Gorilla_gorilla_gorilla,Gorilla_gorilla)),Homo_heidelbergensis)),Pan_troglodytes_ellioti),Homo_sapiens); +(((((Gorilla_gorilla,(Gorilla_gorilla_gorilla,(((((Saimiri_sciureus_macrodon,((Saimiri_boliviensis,Saimiri_oerstedii),Saimiri_sciureus)),Saimiri_oerstedii_citrinellus),(((((Sapajus_xanthosternos,Cebus_apella),Cebus_albifrons),(((Leontopithecus_rosalia,((((Brachyteles_arachnoides,Chiropotes_albinasus),Chiropotes_israelita),Aotus_azarae_azarai),Cacajao_calvus)),Lagothrix_lagotricha),Aotus_nancymaae)),(Pithecia_pithecia,((Callicebus_lugens,(Callicebus_cupreus,(((Callimico_goeldii,Ateles_paniscus),(Callithrix_jacchus,Ateles_geoffroyi)),(Ateles_belzebuth,Callicebus_donacophilus)))),((Aotus_azarae,((Aotus_azarai,Aotus_lemurinus),(Saguinus_oedipus,Callithrix_pygmaea))),Aotus_trivirgatus)))),Alouatta_caraya)),((((Daubentonia_madagascariensis,(((((Eulemur_fulvus,(Perodicticus_potto,(Perodicticus_potto_edwarsi,((Propithecus_verreauxi,(Loris_tardigradus,Loris_lydekkerianus)),(Nycticebus_bengalensis,Nycticebus_coucang))))),(((Otolemur_garnettii,Otolemur_crassicaudatus),Galagoides_demidoff),(Galago_senegalensis,Galago_moholi))),(((Eulemur_mongoz,((((Cheirogaleus_medius,Prolemur_simus),(Varecia_rubra,(Lemur_catta,(Varecia_variegata,Hapalemur_griseus)))),Eulemur_rubriventer),(Eulemur_rufus,Palaeopropithecus_ingens))),Nycticebus_pygmaeus),Indri_indri)),Eulemur_macaco),Propithecus_coquereli)),(Avahi_laniger,Megaladapis_edwardsi)),((((Tarsius_wallacei,Tarsius_dentatus),Tarsius_lariang),Tarsius_syrichta),(Lepilemur_ruficaudatus,Lepilemur_hubbardorum))),Tarsius_bancanus)),(((((Cercocebus_agilis,((Cercocebus_chrysogaster,(Mandrillus_sphinx,Cercocebus_atys)),Mandrillus_leucophaeus)),Cercocebus_torquatus),(((Macaca_fascicularis,((Macaca_silenus,(Macaca_assamensis,Macaca_thibetana)),(((Macaca_nigra,(Macaca_mulatta,Macaca_fuscata)),(Macaca_sylvanus,Macaca_nemestrina)),Macaca_tonkeana))),Macaca_arctoides),((((Rhinopithecus_avunculus,((((Rhinopithecus_bieti_2_RL2012,Rhinopithecus_brelichi),Trachypithecus_johnii),(Rhinopithecus_roxellana,((((Nasalis_larvatus,Simias_concolor),Pygathrix_nemaeus),Pygathrix_nigripes),(Trachypithecus_francoisi,((Trachypithecus_obscurus,Trachypithecus_cristatus),Trachypithecus_pileatus))))),((Piliocolobus_badius,(Colobus_guereza,Colobus_satanas)),Procolobus_verus))),Presbytis_melalophos),Semnopithecus_entellus),((Theropithecus_gelada,(Lophocebus_albigena,Lophocebus_aterrimus)),(((((Papio_anubis,(Papio_cynocephalus,Papio_ursinus)),Papio_hamadryas),Papio_papio),Papio_kindae),Rungwecebus_kipunji))))),(((Miopithecus_talapoin,Cercopithecus_solatus),(Chlorocebus_pygerythrus,(((Chlorocebus_cynosuros,((Cercopithecus_roloway,((((Cercopithecus_mitis_heymansi,Cercopithecus_albogularis_kolbi),(((Cercopithecus_albogularis_albotorquatus,(Cercopithecus_albogularis_labiatus,Cercopithecus_mitis_boutourlinii)),Cercopithecus_albogularis_erythrarchus),(Cercopithecus_albogularis,Cercopithecus_albogularis_monoides))),(Cercopithecus_mitis_opisthostictus,Cercopithecus_mitis_mitis)),((((((((((Cercopithecus_erythrogaster,Cercopithecus_erythrogaster_pococki),((Cercopithecus_petaurista_buettikoferi,Cercopithecus_petaurista_petaurista),Cercopithecus_petaurista)),(Cercopithecus_cephus_cephus,Cercopithecus_ascanius_katangae)),(((Cercopithecus_dryas,(Chlorocebus_sabaeus,Cercopithecus_neglectus)),Cercopithecus_aethiops),Cercopithecus_cephus)),(((Cercopithecus_preussi_preussi,Cercopithecus_preussi_insularis),Cercopithecus_lhoesti),Cercopithecus_ascanius_schmidti)),(Cercopithecus_cephus_ngottoensis,(Cercopithecus_albogularis_francescae,(Cercopithecus_ascanius_whitesidei,((((((Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans),Cercopithecus_nictitans_martini),Cercopithecus_pogonias_grayi),(Cercopithecus_pogonias_schwarzianus,Cercopithecus_pogonias_nigripes)),Cercopithecus_pogonias),(Cercopithecus_mona,Cercopithecus_campbelli)))))),Cercopithecus_nictitans_nictitans),Cercopithecus_nictitans),(((Cercopithecus_erythrotis_camerunensis,(Cercopithecus_albogularis_moloneyi,Cercopithecus_mitis)),Cercopithecus_doggetti),Cercopithecus_kandti)),Cercopithecus_mitis_stuhlmanni))),Chlorocebus_tantalus)),Allenopithecus_nigroviridis),(Chlorocebus_aethiops,Cercopithecus_hamlyni)))),(Erythrocebus_patas,Cercopithecus_diana))),Miopithecus_ogouensis)))),(Homo_heidelbergensis,Homo_sapiens_ssp_Denisova)),Pan_troglodytes_ellioti),((((Hylobates_moloch,Symphalangus_syndactylus),Nomascus_leucogenys),Hylobates_agilis),((Pongo_pygmaeus,Pongo_abelii),Hylobates_lar))),(Pan_paniscus,(Pan_troglodytes,Pan_troglodytes_troglodytes)),Homo_sapiens); +(((Pan_paniscus,Pan_troglodytes),(((((Homo_sapiens_ssp_Denisova,Homo_heidelbergensis),((((Nomascus_leucogenys,Hylobates_lar),Hylobates_agilis),Hylobates_moloch),(Pongo_pygmaeus,Pongo_abelii))),Gorilla_gorilla_gorilla),Gorilla_gorilla),(((Alouatta_caraya,((Saimiri_oerstedii_citrinellus,(Saimiri_sciureus_macrodon,((Saimiri_oerstedii,Saimiri_boliviensis),Saimiri_sciureus))),((Aotus_azarai,Aotus_lemurinus),(((((Cacajao_calvus,(Aotus_azarae,((Pithecia_pithecia,(Aotus_trivirgatus,Chiropotes_israelita)),(Brachyteles_arachnoides,Chiropotes_albinasus)))),Aotus_azarae_azarai),Lagothrix_lagotricha),((Callicebus_lugens,((Callicebus_donacophilus,Callicebus_cupreus),((Callithrix_jacchus,((Ateles_paniscus,Ateles_belzebuth),Callimico_goeldii)),Ateles_geoffroyi))),((Saguinus_oedipus,(Aotus_nancymaae,Callithrix_pygmaea)),Leontopithecus_rosalia))),(Cebus_albifrons,(Cebus_apella,Sapajus_xanthosternos)))))),((((Eulemur_mongoz,((Eulemur_rubriventer,Eulemur_rufus),Palaeopropithecus_ingens)),(((Eulemur_fulvus,(Eulemur_macaco,((Prolemur_simus,(((Perodicticus_potto,Perodicticus_potto_edwarsi),(Nycticebus_pygmaeus,(Nycticebus_coucang,Nycticebus_bengalensis))),((Galagoides_demidoff,((Galago_senegalensis,Galago_moholi),(Otolemur_garnettii,Otolemur_crassicaudatus))),(Loris_tardigradus,Loris_lydekkerianus)))),(((Varecia_variegata,Varecia_rubra),(Lemur_catta,Hapalemur_griseus)),Cheirogaleus_medius)))),((Propithecus_verreauxi,(Propithecus_coquereli,Avahi_laniger)),((Lepilemur_ruficaudatus,Lepilemur_hubbardorum),Indri_indri))),Megaladapis_edwardsi)),Daubentonia_madagascariensis),((((Tarsius_wallacei,Tarsius_dentatus),Tarsius_lariang),Tarsius_syrichta),Tarsius_bancanus))),(Symphalangus_syndactylus,(((Colobus_satanas,Colobus_guereza),(Piliocolobus_badius,((((((Trachypithecus_johnii,((Trachypithecus_cristatus,(Rhinopithecus_avunculus,Trachypithecus_francoisi)),Trachypithecus_obscurus)),(((Nasalis_larvatus,Simias_concolor),Rhinopithecus_roxellana),((Rhinopithecus_brelichi,Pygathrix_nigripes),(Rhinopithecus_bieti_2_RL2012,Pygathrix_nemaeus)))),Presbytis_melalophos),Semnopithecus_entellus),Trachypithecus_pileatus),Procolobus_verus))),(((((Lophocebus_albigena,Lophocebus_aterrimus),Cercocebus_chrysogaster),(Cercocebus_atys,Mandrillus_sphinx)),((Cercocebus_agilis,((Theropithecus_gelada,Mandrillus_leucophaeus),(((Macaca_mulatta,Macaca_fuscata),((Macaca_sylvanus,((Macaca_nigra,((Macaca_fascicularis,(Macaca_silenus,Macaca_tonkeana)),(Macaca_thibetana,Macaca_assamensis))),Macaca_nemestrina)),Macaca_arctoides)),(((Allenopithecus_nigroviridis,Cercopithecus_hamlyni),((Miopithecus_talapoin,Miopithecus_ogouensis),(Cercopithecus_diana,(((Cercopithecus_campbelli,Cercopithecus_mona),(((((Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans),(Cercopithecus_pogonias_grayi,Cercopithecus_pogonias_nigripes)),Cercopithecus_pogonias),Cercopithecus_pogonias_schwarzianus),Cercopithecus_nictitans_martini)),(((((Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis),(((((Cercopithecus_ascanius_katangae,(((Cercopithecus_erythrogaster,((Cercopithecus_petaurista_buettikoferi,Cercopithecus_erythrogaster_pococki),Cercopithecus_petaurista_petaurista)),Cercopithecus_petaurista),Cercopithecus_cephus_cephus)),Cercopithecus_erythrotis_camerunensis),Cercopithecus_ascanius_whitesidei),(Cercopithecus_ascanius_schmidti,(Cercopithecus_lhoesti,(Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi)))),(((((Cercopithecus_albogularis_albotorquatus,Cercopithecus_albogularis_labiatus),(Cercopithecus_mitis_boutourlinii,Cercopithecus_albogularis_erythrarchus)),Cercopithecus_albogularis_monoides),Cercopithecus_albogularis),((Cercopithecus_albogularis_francescae,((((Cercopithecus_mitis_mitis,(Cercopithecus_mitis_opisthostictus,Cercopithecus_mitis_heymansi)),((Cercopithecus_mitis,(Cercopithecus_nictitans_nictitans,(Cercopithecus_nictitans,Cercopithecus_albogularis_kolbi))),Cercopithecus_doggetti)),Cercopithecus_mitis_stuhlmanni),Cercopithecus_kandti)),Cercopithecus_albogularis_moloneyi)))),(Cercopithecus_aethiops,(((Cercopithecus_dryas,Cercopithecus_solatus),((Chlorocebus_tantalus,(Chlorocebus_aethiops,Chlorocebus_cynosuros)),Chlorocebus_pygerythrus)),Chlorocebus_sabaeus))),Cercopithecus_neglectus),Cercopithecus_roloway))))),Erythrocebus_patas)))),Cercocebus_torquatus)),((Papio_cynocephalus,((Papio_hamadryas,Papio_papio),((Rungwecebus_kipunji,Papio_anubis),Papio_ursinus))),Papio_kindae))))))),(Pan_troglodytes_ellioti,Pan_troglodytes_troglodytes),Homo_sapiens); +((Homo_sapiens_ssp_Denisova,(((Gorilla_gorilla_gorilla,((Miopithecus_ogouensis,(((Miopithecus_talapoin,(((((Cercopithecus_roloway,((((((((Cercopithecus_albogularis_kolbi,Cercopithecus_mitis_stuhlmanni),(Cercopithecus_nictitans_nictitans,Cercopithecus_nictitans)),(Cercopithecus_mitis_heymansi,(Cercopithecus_albogularis_francescae,Cercopithecus_aethiops))),Cercopithecus_mitis_mitis),(Cercopithecus_kandti,(Cercopithecus_mitis_opisthostictus,Cercopithecus_doggetti))),Cercopithecus_mitis),(Cercopithecus_albogularis_moloneyi,(((Cercopithecus_albogularis_labiatus,Cercopithecus_albogularis_monoides),Cercopithecus_albogularis_erythrarchus),(Cercopithecus_mitis_boutourlinii,Cercopithecus_albogularis_albotorquatus)))),((Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis),(((Cercopithecus_ascanius_schmidti,(Cercopithecus_erythrotis_camerunensis,(((Cercopithecus_erythrogaster_pococki,Cercopithecus_erythrogaster),(Cercopithecus_petaurista_buettikoferi,Cercopithecus_petaurista_petaurista)),(Cercopithecus_ascanius_katangae,(Cercopithecus_cephus_cephus,Cercopithecus_petaurista))))),Cercopithecus_ascanius_whitesidei),(Cercopithecus_lhoesti,(Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi)))))),Cercopithecus_albogularis),Cercopithecus_neglectus),((((Chlorocebus_cynosuros,Chlorocebus_sabaeus),(Chlorocebus_aethiops,(Cercopithecus_dryas,Chlorocebus_pygerythrus))),Chlorocebus_tantalus),Cercopithecus_hamlyni)),((Cercopithecus_campbelli,Cercopithecus_mona),(Cercopithecus_nictitans_martini,(Cercopithecus_pogonias,((((Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans),Cercopithecus_pogonias_nigripes),Cercopithecus_pogonias_grayi),Cercopithecus_pogonias_schwarzianus)))))),(((Erythrocebus_patas,Cercopithecus_solatus),(Allenopithecus_nigroviridis,(((Cercocebus_agilis,Mandrillus_leucophaeus),(Cercocebus_chrysogaster,Cercocebus_atys)),((Cercocebus_torquatus,(((Macaca_nigra,(Macaca_mulatta,Macaca_fuscata)),((((Macaca_fascicularis,(Macaca_silenus,Macaca_tonkeana)),(Macaca_thibetana,Macaca_assamensis)),Macaca_nemestrina),Macaca_arctoides)),Macaca_sylvanus)),(((((((Papio_hamadryas,(Papio_cynocephalus,(Papio_ursinus,Papio_anubis))),Papio_papio),Papio_kindae),Rungwecebus_kipunji),((((((Procolobus_verus,((Colobus_satanas,Colobus_guereza),Piliocolobus_badius)),((Trachypithecus_cristatus,(Semnopithecus_entellus,(Trachypithecus_pileatus,Trachypithecus_johnii))),(Trachypithecus_francoisi,Trachypithecus_obscurus))),Presbytis_melalophos),Rhinopithecus_avunculus),((Rhinopithecus_roxellana,Rhinopithecus_bieti_2_RL2012),((Pygathrix_nigripes,Pygathrix_nemaeus),(Nasalis_larvatus,Simias_concolor)))),Rhinopithecus_brelichi)),Lophocebus_albigena),(Theropithecus_gelada,Lophocebus_aterrimus)))))),Mandrillus_sphinx)),Cercopithecus_diana)),((((Ateles_geoffroyi,Alouatta_caraya),((((Cacajao_calvus,(Chiropotes_albinasus,Pithecia_pithecia)),Chiropotes_israelita),((Ateles_paniscus,(Callicebus_donacophilus,(((Callicebus_cupreus,Callicebus_lugens),Brachyteles_arachnoides),Ateles_belzebuth))),(Cebus_albifrons,(Cebus_apella,Sapajus_xanthosternos)))),((Saguinus_oedipus,(Callithrix_jacchus,Callithrix_pygmaea)),((((Saimiri_sciureus_macrodon,((Saimiri_oerstedii,Saimiri_sciureus),Saimiri_boliviensis)),Saimiri_oerstedii_citrinellus),(((Aotus_azarae,Aotus_trivirgatus),Aotus_azarae_azarai),(Aotus_azarai,Aotus_lemurinus))),(Aotus_nancymaae,Leontopithecus_rosalia))))),(Callimico_goeldii,Lagothrix_lagotricha)),(Tarsius_bancanus,(Galago_senegalensis,((((Avahi_laniger,((Eulemur_mongoz,Indri_indri),Propithecus_coquereli)),(Lepilemur_ruficaudatus,Lepilemur_hubbardorum)),(((Palaeopropithecus_ingens,((Megaladapis_edwardsi,Eulemur_fulvus),Eulemur_macaco)),(Eulemur_rufus,(Propithecus_verreauxi,(Prolemur_simus,(Cheirogaleus_medius,((Varecia_variegata,Varecia_rubra),(Lemur_catta,Hapalemur_griseus))))))),Eulemur_rubriventer)),(Daubentonia_madagascariensis,((((Perodicticus_potto_edwarsi,(Otolemur_crassicaudatus,(Otolemur_garnettii,(Perodicticus_potto,((Galagoides_demidoff,(Loris_tardigradus,Loris_lydekkerianus)),(Nycticebus_pygmaeus,(Nycticebus_coucang,Nycticebus_bengalensis))))))),Galago_moholi),((Tarsius_dentatus,Tarsius_wallacei),Tarsius_lariang)),Tarsius_syrichta)))))))),((Nomascus_leucogenys,((Hylobates_moloch,Pongo_pygmaeus),Gorilla_gorilla)),(Hylobates_lar,((Pongo_abelii,Symphalangus_syndactylus),Hylobates_agilis)))),Homo_heidelbergensis)),(Pan_troglodytes_ellioti,(Pan_paniscus,(Pan_troglodytes_troglodytes,Pan_troglodytes))),Homo_sapiens); +((Pan_troglodytes,((((Miopithecus_ogouensis,(Cercopithecus_diana,((((Miopithecus_talapoin,(((Cercopithecus_ascanius_katangae,Cercopithecus_cephus_cephus),(Cercopithecus_petaurista,((Cercopithecus_erythrogaster_pococki,Cercopithecus_erythrogaster),(Cercopithecus_petaurista_buettikoferi,Cercopithecus_petaurista_petaurista)))),(Cercopithecus_erythrotis_camerunensis,((((Cercopithecus_lhoesti,(Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi)),Cercopithecus_neglectus),Cercopithecus_ascanius_whitesidei),(Cercopithecus_ascanius_schmidti,(((((Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis),((((Cercopithecus_albogularis_kolbi,(Cercopithecus_nictitans_nictitans,Cercopithecus_nictitans)),Cercopithecus_albogularis_monoides),((Cercopithecus_campbelli,Cercopithecus_mona),(Cercopithecus_pogonias,((Cercopithecus_nictitans_martini,(Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans)),(Cercopithecus_pogonias_nigripes,(Cercopithecus_pogonias_schwarzianus,Cercopithecus_pogonias_grayi)))))),Cercopithecus_roloway)),Cercopithecus_albogularis_moloneyi),((((((Cercopithecus_aethiops,(((Chlorocebus_cynosuros,(Chlorocebus_pygerythrus,(Cercopithecus_dryas,(Chlorocebus_aethiops,Cercopithecus_hamlyni)))),Chlorocebus_tantalus),Chlorocebus_sabaeus)),Cercopithecus_doggetti),Cercopithecus_mitis_heymansi),((Cercopithecus_mitis_mitis,(Cercopithecus_kandti,Cercopithecus_mitis_stuhlmanni)),Cercopithecus_albogularis_francescae)),Cercopithecus_mitis_opisthostictus),Cercopithecus_mitis)),(Cercopithecus_albogularis,((Cercopithecus_mitis_boutourlinii,(Cercopithecus_albogularis_erythrarchus,Cercopithecus_albogularis_albotorquatus)),Cercopithecus_albogularis_labiatus)))))))),Allenopithecus_nigroviridis),Cercopithecus_solatus),(Erythrocebus_patas,(((((Cercocebus_agilis,Mandrillus_leucophaeus),Cercocebus_chrysogaster),(Mandrillus_sphinx,(Cercocebus_torquatus,Cercocebus_atys))),(Macaca_fascicularis,((Macaca_silenus,Macaca_tonkeana),((Macaca_thibetana,Macaca_assamensis),(Macaca_nemestrina,((Macaca_arctoides,Macaca_sylvanus),(Macaca_nigra,(Macaca_mulatta,Macaca_fuscata)))))))),((((Papio_hamadryas,(Rungwecebus_kipunji,((Lophocebus_albigena,(Papio_ursinus,Lophocebus_aterrimus)),Papio_anubis))),Theropithecus_gelada),((Papio_papio,Papio_cynocephalus),Papio_kindae)),((Procolobus_verus,((Colobus_satanas,Colobus_guereza),Piliocolobus_badius)),(((Trachypithecus_johnii,(((((Pygathrix_nigripes,(((Trachypithecus_cristatus,(Simias_concolor,Trachypithecus_francoisi)),Rhinopithecus_brelichi),Rhinopithecus_roxellana)),Rhinopithecus_bieti_2_RL2012),Nasalis_larvatus),Trachypithecus_obscurus),(Pygathrix_nemaeus,Trachypithecus_pileatus))),(Presbytis_melalophos,Rhinopithecus_avunculus)),Semnopithecus_entellus)))))))),(((Alouatta_caraya,(((((Ateles_belzebuth,(((Callicebus_donacophilus,Cacajao_calvus),Chiropotes_albinasus),(Brachyteles_arachnoides,Chiropotes_israelita))),Ateles_paniscus),Ateles_geoffroyi),((Sapajus_xanthosternos,(Cebus_albifrons,Cebus_apella)),(Lagothrix_lagotricha,(Pithecia_pithecia,(Callicebus_cupreus,Callicebus_lugens))))),((Saguinus_oedipus,(Callithrix_jacchus,Callithrix_pygmaea)),((Leontopithecus_rosalia,Aotus_nancymaae),(((((Saimiri_oerstedii,Saimiri_oerstedii_citrinellus),Saimiri_sciureus),Saimiri_boliviensis),Saimiri_sciureus_macrodon),((Aotus_trivirgatus,((Aotus_azarai,Aotus_lemurinus),Aotus_azarae_azarai)),Aotus_azarae)))))),Callimico_goeldii),(Galago_senegalensis,(Tarsius_bancanus,((((((Galago_moholi,((Otolemur_garnettii,Otolemur_crassicaudatus),Galagoides_demidoff)),((Loris_tardigradus,Loris_lydekkerianus),(Nycticebus_pygmaeus,(Nycticebus_coucang,Nycticebus_bengalensis)))),(Perodicticus_potto,Perodicticus_potto_edwarsi)),Daubentonia_madagascariensis),(((Avahi_laniger,Megaladapis_edwardsi),(((Indri_indri,(Lepilemur_ruficaudatus,Lepilemur_hubbardorum)),((((Eulemur_mongoz,Eulemur_fulvus),Eulemur_macaco),Eulemur_rubriventer),(((Varecia_variegata,Varecia_rubra),Eulemur_rufus),(Prolemur_simus,(Cheirogaleus_medius,Hapalemur_griseus))))),(Propithecus_coquereli,(Palaeopropithecus_ingens,Propithecus_verreauxi)))),Lemur_catta)),(Tarsius_syrichta,((Tarsius_dentatus,Tarsius_wallacei),Tarsius_lariang))))))),Gorilla_gorilla_gorilla),((Hylobates_moloch,Nomascus_leucogenys),(Pongo_pygmaeus,((Gorilla_gorilla,((Pongo_abelii,Symphalangus_syndactylus),Hylobates_agilis)),Hylobates_lar))))),((Homo_sapiens_ssp_Denisova,((Pan_troglodytes_ellioti,Homo_heidelbergensis),Pan_troglodytes_troglodytes)),Pan_paniscus),Homo_sapiens); +(((Homo_sapiens_ssp_Denisova,((Gorilla_gorilla_gorilla,((((Semnopithecus_entellus,(((((Colobus_satanas,Colobus_guereza),(Piliocolobus_badius,Procolobus_verus)),((((Trachypithecus_johnii,(Trachypithecus_francoisi,Trachypithecus_obscurus)),(Pygathrix_nigripes,(((Rhinopithecus_brelichi,Rhinopithecus_bieti_2_RL2012),Pygathrix_nemaeus),((Nasalis_larvatus,Simias_concolor),Rhinopithecus_roxellana)))),Trachypithecus_cristatus),Trachypithecus_pileatus)),((((Rungwecebus_kipunji,Papio_anubis),Papio_hamadryas),Papio_ursinus),(((Papio_papio,Papio_cynocephalus),Papio_kindae),(Theropithecus_gelada,(Lophocebus_aterrimus,Lophocebus_albigena))))),(Rhinopithecus_avunculus,Presbytis_melalophos))),((Cercopithecus_diana,((((Cercopithecus_lhoesti,(Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi)),((Cercopithecus_neglectus,Cercopithecus_ascanius_whitesidei),((((Cercopithecus_albogularis,Cercopithecus_roloway),((((Cercopithecus_doggetti,Cercopithecus_kandti),(Cercopithecus_nictitans,((((((((Chlorocebus_aethiops,Cercopithecus_hamlyni),(Chlorocebus_cynosuros,(Chlorocebus_tantalus,Chlorocebus_pygerythrus))),Cercopithecus_dryas),Chlorocebus_sabaeus),Cercopithecus_aethiops),Cercopithecus_albogularis_francescae),Cercopithecus_nictitans_nictitans),((Cercopithecus_albogularis_kolbi,Cercopithecus_mitis_stuhlmanni),(Cercopithecus_mitis_heymansi,(Cercopithecus_mitis_mitis,Cercopithecus_mitis_opisthostictus)))))),Cercopithecus_mitis),(Cercopithecus_albogularis_moloneyi,(((Cercopithecus_albogularis_labiatus,Cercopithecus_albogularis_monoides),Cercopithecus_albogularis_albotorquatus),(Cercopithecus_albogularis_erythrarchus,Cercopithecus_mitis_boutourlinii))))),((Cercopithecus_ascanius_schmidti,(Cercopithecus_cephus,((Cercopithecus_campbelli,Cercopithecus_mona),((Cercopithecus_wolfi_elegans,((Cercopithecus_pogonias_schwarzianus,Cercopithecus_pogonias_grayi),Cercopithecus_pogonias_nigripes)),(Cercopithecus_nictitans_martini,(Cercopithecus_wolfi_pyrogaster,Cercopithecus_pogonias)))))),Cercopithecus_cephus_ngottoensis)),Cercopithecus_erythrotis_camerunensis))),(((((Cercopithecus_petaurista_buettikoferi,Cercopithecus_petaurista_petaurista),Cercopithecus_erythrogaster),Cercopithecus_erythrogaster_pococki),Cercopithecus_ascanius_katangae),Cercopithecus_cephus_cephus)),Cercopithecus_petaurista)),(Miopithecus_talapoin,((Cercopithecus_solatus,((Cercocebus_chrysogaster,((Erythrocebus_patas,(Cercocebus_agilis,Allenopithecus_nigroviridis)),Mandrillus_leucophaeus)),((Cercocebus_torquatus,Cercocebus_atys),(((Macaca_fascicularis,((Macaca_silenus,Macaca_tonkeana),((Macaca_nemestrina,Macaca_sylvanus),(Macaca_thibetana,Macaca_assamensis)))),Macaca_arctoides),(Macaca_nigra,(Macaca_mulatta,Macaca_fuscata)))))),Mandrillus_sphinx)))),Miopithecus_ogouensis),((((Perodicticus_potto_edwarsi,(((Perodicticus_potto,(Otolemur_garnettii,Galago_senegalensis)),Otolemur_crassicaudatus),((Daubentonia_madagascariensis,((Megaladapis_edwardsi,Avahi_laniger),(((Palaeopropithecus_ingens,Propithecus_coquereli),Propithecus_verreauxi),((Indri_indri,(Lepilemur_ruficaudatus,Lepilemur_hubbardorum)),((((Eulemur_mongoz,(Eulemur_fulvus,(Lemur_catta,((((Varecia_variegata,Varecia_rubra),Cheirogaleus_medius),Hapalemur_griseus),Prolemur_simus)))),Eulemur_macaco),Eulemur_rubriventer),Eulemur_rufus))))),(((Tarsius_lariang,Tarsius_dentatus),Tarsius_wallacei),Tarsius_syrichta)))),Tarsius_bancanus),(Galago_moholi,((Galagoides_demidoff,(Loris_tardigradus,Loris_lydekkerianus)),(Nycticebus_pygmaeus,(Nycticebus_coucang,Nycticebus_bengalensis))))),(((Cebus_albifrons,(Cebus_apella,Sapajus_xanthosternos)),(((Saguinus_oedipus,Callithrix_pygmaea),(((Aotus_trivirgatus,Aotus_azarae),((Aotus_lemurinus,Aotus_azarai),Aotus_azarae_azarai)),((Leontopithecus_rosalia,Aotus_nancymaae),((Saimiri_sciureus_macrodon,(Saimiri_boliviensis,Saimiri_oerstedii_citrinellus)),(Saimiri_oerstedii,Saimiri_sciureus))))),(((Alouatta_caraya,(Ateles_paniscus,((((Callithrix_jacchus,(Ateles_geoffroyi,Ateles_belzebuth)),Callicebus_cupreus),Callimico_goeldii),Callicebus_donacophilus))),Pithecia_pithecia),Callicebus_lugens))),(Lagothrix_lagotricha,(((Chiropotes_albinasus,Brachyteles_arachnoides),Chiropotes_israelita),Cacajao_calvus)))))),((Hylobates_agilis,(((Hylobates_lar,Hylobates_moloch),Nomascus_leucogenys),Symphalangus_syndactylus)),(Gorilla_gorilla,(Pongo_pygmaeus,Pongo_abelii))))),Homo_heidelbergensis),(((Pan_troglodytes_troglodytes,Pan_troglodytes),Pan_paniscus),Pan_troglodytes_ellioti),Homo_sapiens); +((Pan_troglodytes_ellioti,((((Gorilla_gorilla_gorilla,(Homo_sapiens_ssp_Denisova,((((((Cercopithecus_ascanius_whitesidei,Cercopithecus_ascanius_schmidti),((Cercopithecus_neglectus,((Cercopithecus_campbelli,(Cercopithecus_mona,Cercopithecus_pogonias)),(Cercopithecus_pogonias_grayi,(((Cercopithecus_pogonias_nigripes,Cercopithecus_wolfi_elegans),Cercopithecus_pogonias_schwarzianus),Cercopithecus_wolfi_pyrogaster)))),(((((((((((Chlorocebus_cynosuros,Cercopithecus_hamlyni),Chlorocebus_pygerythrus),(Chlorocebus_tantalus,Chlorocebus_aethiops)),Cercopithecus_solatus),Chlorocebus_sabaeus),Cercopithecus_aethiops),Cercopithecus_dryas),Cercopithecus_albogularis_francescae),(((Cercopithecus_nictitans,(Cercopithecus_nictitans_martini,Cercopithecus_nictitans_nictitans)),((Cercopithecus_kandti,(Cercopithecus_mitis_stuhlmanni,(((Cercopithecus_mitis_heymansi,Cercopithecus_mitis_opisthostictus),Cercopithecus_mitis_mitis),Cercopithecus_albogularis_kolbi))),Cercopithecus_doggetti)),Cercopithecus_mitis)),(((Cercopithecus_albogularis,(Cercopithecus_albogularis_labiatus,(Cercopithecus_albogularis_erythrarchus,(Cercopithecus_mitis_boutourlinii,Cercopithecus_albogularis_monoides)))),Cercopithecus_albogularis_albotorquatus),Cercopithecus_albogularis_moloneyi)),(Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis)))),(((((Cercopithecus_roloway,(Cercopithecus_lhoesti,(Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi))),Cercopithecus_erythrotis_camerunensis),Cercopithecus_ascanius_katangae),((Cercopithecus_petaurista_buettikoferi,Cercopithecus_erythrogaster_pococki),(Cercopithecus_petaurista_petaurista,Cercopithecus_erythrogaster))),Cercopithecus_petaurista)),Cercopithecus_cephus_cephus),((Miopithecus_talapoin,(Miopithecus_ogouensis,(Cercopithecus_diana,(((Erythrocebus_patas,((Cercocebus_torquatus,(Cercocebus_chrysogaster,(Cercocebus_agilis,Mandrillus_leucophaeus))),Mandrillus_sphinx)),(Allenopithecus_nigroviridis,((((Papio_papio,Papio_cynocephalus),Papio_kindae),((Papio_anubis,Papio_hamadryas),Papio_ursinus)),((Rungwecebus_kipunji,Theropithecus_gelada),(Lophocebus_aterrimus,Lophocebus_albigena))))),((Macaca_silenus,Macaca_tonkeana),(((((Macaca_sylvanus,Macaca_arctoides),Macaca_nemestrina),((Macaca_mulatta,Macaca_fuscata),(Macaca_thibetana,Macaca_assamensis))),Macaca_nigra),(Macaca_fascicularis,Cercocebus_atys))))))),(Rhinopithecus_avunculus,((((Colobus_satanas,Colobus_guereza),(Piliocolobus_badius,Procolobus_verus)),(((Trachypithecus_johnii,((Pygathrix_nemaeus,Trachypithecus_pileatus),Trachypithecus_cristatus)),(Trachypithecus_obscurus,Trachypithecus_francoisi)),((Pygathrix_nigripes,(Semnopithecus_entellus,(Nasalis_larvatus,Simias_concolor))),((Rhinopithecus_bieti_2_RL2012,Rhinopithecus_brelichi),Rhinopithecus_roxellana)))),Presbytis_melalophos)))),((((Chiropotes_albinasus,Brachyteles_arachnoides),(Chiropotes_israelita,(((((((Sapajus_xanthosternos,(Cebus_albifrons,Cebus_apella)),(Callicebus_lugens,((Callimico_goeldii,Leontopithecus_rosalia),(((Ateles_geoffroyi,((Ateles_belzebuth,Callicebus_cupreus),Callicebus_donacophilus)),Ateles_paniscus),(((Lagothrix_lagotricha,Callithrix_jacchus),Callithrix_pygmaea),Saguinus_oedipus))))),(Pithecia_pithecia,(Aotus_azarae_azarai,((Aotus_lemurinus,Aotus_azarai),((((Saimiri_oerstedii,Saimiri_sciureus),Saimiri_boliviensis),Saimiri_sciureus_macrodon),Saimiri_oerstedii_citrinellus))))),Aotus_trivirgatus),Aotus_azarae),Cacajao_calvus),Aotus_nancymaae))),Alouatta_caraya),((Galago_moholi,((Galagoides_demidoff,(Nycticebus_pygmaeus,(Nycticebus_coucang,Nycticebus_bengalensis))),(Loris_tardigradus,Loris_lydekkerianus))),((Perodicticus_potto,(Otolemur_crassicaudatus,Otolemur_garnettii)),((Tarsius_syrichta,(Tarsius_lariang,(Tarsius_dentatus,Tarsius_wallacei))),(((((Palaeopropithecus_ingens,(Eulemur_rufus,((Megaladapis_edwardsi,(Eulemur_rubriventer,(((((Varecia_variegata,Varecia_rubra),Cheirogaleus_medius),(Prolemur_simus,Hapalemur_griseus)),Eulemur_fulvus),Eulemur_mongoz))),Eulemur_macaco))),Indri_indri),Avahi_laniger),(Perodicticus_potto_edwarsi,Daubentonia_madagascariensis)),((Galago_senegalensis,Tarsius_bancanus),(((Lemur_catta,Propithecus_verreauxi),Propithecus_coquereli),(Lepilemur_ruficaudatus,Lepilemur_hubbardorum))))))))))),Gorilla_gorilla),(((Hylobates_moloch,(Hylobates_lar,(Hylobates_agilis,Symphalangus_syndactylus))),Nomascus_leucogenys),(Pongo_pygmaeus,Pongo_abelii))),Homo_heidelbergensis)),(Pan_paniscus,(Pan_troglodytes,Pan_troglodytes_troglodytes)),Homo_sapiens); +(((((Gorilla_gorilla,((Homo_sapiens_ssp_Denisova,(Gorilla_gorilla_gorilla,((((((Mandrillus_leucophaeus,((((Erythrocebus_patas,Mandrillus_sphinx),(Macaca_sylvanus,Allenopithecus_nigroviridis)),Cercocebus_torquatus),Cercocebus_agilis)),Cercocebus_chrysogaster),((((Macaca_silenus,Macaca_tonkeana),(((Macaca_thibetana,Macaca_assamensis),((Macaca_arctoides,Macaca_nemestrina),((Macaca_fuscata,Macaca_mulatta),Macaca_nigra))),Macaca_fascicularis)),Cercocebus_atys),((((Colobus_satanas,Colobus_guereza),(Piliocolobus_badius,Procolobus_verus)),(Rhinopithecus_avunculus,(Semnopithecus_entellus,(Presbytis_melalophos,(((((((Pygathrix_nemaeus,Simias_concolor),((Rhinopithecus_brelichi,Rhinopithecus_bieti_2_RL2012),Pygathrix_nigripes)),(Nasalis_larvatus,Rhinopithecus_roxellana)),(Trachypithecus_francoisi,Trachypithecus_cristatus)),Trachypithecus_obscurus),Trachypithecus_pileatus),Trachypithecus_johnii))))),((((((Papio_cynocephalus,((Papio_kindae,Papio_hamadryas),Theropithecus_gelada)),Rungwecebus_kipunji),Papio_papio),Papio_anubis),Papio_ursinus),(Lophocebus_aterrimus,Lophocebus_albigena))))),((((Cercopithecus_erythrotis_camerunensis,((((Cercopithecus_roloway,(Cercopithecus_lhoesti,(Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi))),(((Cercopithecus_mitis,(((Cercopithecus_albogularis_albotorquatus,((Cercopithecus_albogularis_erythrarchus,Cercopithecus_albogularis_labiatus),Cercopithecus_mitis_boutourlinii)),(Cercopithecus_albogularis,Cercopithecus_albogularis_monoides)),((Cercopithecus_mitis_opisthostictus,Cercopithecus_mitis_mitis),Cercopithecus_mitis_heymansi))),((((Cercopithecus_nictitans,(Cercopithecus_nictitans_martini,Cercopithecus_nictitans_nictitans)),(((Cercopithecus_albogularis_kolbi,Cercopithecus_solatus),Cercopithecus_mitis_stuhlmanni),((((((Chlorocebus_sabaeus,(Cercopithecus_dryas,Cercopithecus_aethiops)),(Chlorocebus_aethiops,Cercopithecus_hamlyni)),Chlorocebus_pygerythrus),Chlorocebus_cynosuros),Chlorocebus_tantalus),Cercopithecus_albogularis_francescae))),Cercopithecus_doggetti),Cercopithecus_kandti)),Cercopithecus_albogularis_moloneyi)),(Cercopithecus_cephus_ngottoensis,((Cercopithecus_cephus,((Cercopithecus_wolfi_elegans,Cercopithecus_wolfi_pyrogaster),(((Cercopithecus_pogonias_schwarzianus,Cercopithecus_pogonias_nigripes),((Cercopithecus_campbelli,Cercopithecus_mona),Cercopithecus_pogonias)),Cercopithecus_pogonias_grayi))),Cercopithecus_ascanius_schmidti))),(Cercopithecus_ascanius_whitesidei,Cercopithecus_neglectus))),((Cercopithecus_petaurista,(Cercopithecus_petaurista_buettikoferi,((Cercopithecus_erythrogaster,Cercopithecus_erythrogaster_pococki),Cercopithecus_petaurista_petaurista))),Cercopithecus_ascanius_katangae)),Cercopithecus_cephus_cephus),Miopithecus_ogouensis)),(Miopithecus_talapoin,Cercopithecus_diana)),(((((Saimiri_sciureus,(Saimiri_oerstedii,Saimiri_boliviensis)),Saimiri_sciureus_macrodon),Saimiri_oerstedii_citrinellus),((((((Ateles_belzebuth,(Saguinus_oedipus,Ateles_geoffroyi)),Callicebus_donacophilus),Callithrix_jacchus),Ateles_paniscus),(((Callicebus_cupreus,Callicebus_lugens),(Pithecia_pithecia,((Callimico_goeldii,Leontopithecus_rosalia),Alouatta_caraya))),(((Cebus_albifrons,(Cebus_apella,Sapajus_xanthosternos)),((Chiropotes_albinasus,Brachyteles_arachnoides),(Cacajao_calvus,(Lagothrix_lagotricha,Chiropotes_israelita)))),Callithrix_pygmaea))),((((Aotus_azarae_azarai,(Aotus_lemurinus,Aotus_azarai)),Aotus_nancymaae),Aotus_azarae),Aotus_trivirgatus))),(((Galago_moholi,(((Loris_tardigradus,(Nycticebus_coucang,Nycticebus_bengalensis)),Galagoides_demidoff),Loris_lydekkerianus)),Nycticebus_pygmaeus),(((Varecia_rubra,((Eulemur_mongoz,(Propithecus_verreauxi,(Galago_senegalensis,((Lepilemur_ruficaudatus,Lepilemur_hubbardorum),Lemur_catta)))),Eulemur_fulvus)),((Propithecus_coquereli,Daubentonia_madagascariensis),(((Eulemur_macaco,(Megaladapis_edwardsi,(((Otolemur_garnettii,(Perodicticus_potto_edwarsi,Perodicticus_potto)),Otolemur_crassicaudatus),Avahi_laniger))),Eulemur_rubriventer),(Palaeopropithecus_ingens,(Indri_indri,(Eulemur_rufus,(Tarsius_bancanus,((Cheirogaleus_medius,(Varecia_variegata,Hapalemur_griseus)),Prolemur_simus)))))))),(Tarsius_syrichta,((Tarsius_lariang,Tarsius_dentatus),Tarsius_wallacei)))))))),Pongo_pygmaeus)),((Nomascus_leucogenys,((((Hylobates_lar,Pan_troglodytes),Hylobates_agilis),Hylobates_moloch),Symphalangus_syndactylus)),Pongo_abelii)),Homo_heidelbergensis),(Pan_troglodytes_ellioti,Pan_troglodytes_troglodytes)),Pan_paniscus,Homo_sapiens); +(((Pan_troglodytes_troglodytes,Pan_paniscus),(Homo_heidelbergensis,((((((Hylobates_agilis,Symphalangus_syndactylus),Pan_troglodytes),(Hylobates_moloch,Nomascus_leucogenys)),Hylobates_lar),(Pongo_pygmaeus,Pongo_abelii)),(Gorilla_gorilla,((Homo_sapiens_ssp_Denisova,((((((Presbytis_melalophos,(((Trachypithecus_cristatus,(Trachypithecus_johnii,(((Nasalis_larvatus,((((Pygathrix_nemaeus,Simias_concolor),Rhinopithecus_bieti_2_RL2012),Rhinopithecus_brelichi),Pygathrix_nigripes)),Rhinopithecus_roxellana),Trachypithecus_francoisi))),Trachypithecus_pileatus),Rhinopithecus_avunculus)),Trachypithecus_obscurus),((Colobus_satanas,Colobus_guereza),(Piliocolobus_badius,Procolobus_verus))),Semnopithecus_entellus),((((Chlorocebus_pygerythrus,(Chlorocebus_tantalus,((Chlorocebus_cynosuros,((Cercopithecus_dryas,(Cercopithecus_aethiops,Chlorocebus_sabaeus)),Cercopithecus_hamlyni)),Chlorocebus_aethiops))),(((((Cercocebus_agilis,(Mandrillus_leucophaeus,(Cercocebus_chrysogaster,(Cercocebus_atys,Mandrillus_sphinx)))),Cercocebus_torquatus),((Theropithecus_gelada,((((Papio_anubis,((Papio_cynocephalus,Papio_kindae),Rungwecebus_kipunji)),Papio_hamadryas),Papio_papio),Papio_ursinus)),(Lophocebus_aterrimus,Lophocebus_albigena))),(Macaca_sylvanus,(((Macaca_fuscata,Macaca_mulatta),((Macaca_silenus,Macaca_fascicularis),((Macaca_nemestrina,Macaca_nigra),(Macaca_tonkeana,(Macaca_thibetana,Macaca_assamensis))))),Macaca_arctoides))),Allenopithecus_nigroviridis)),(((((((Cercopithecus_albogularis_labiatus,Cercopithecus_albogularis_albotorquatus),(Cercopithecus_albogularis_erythrarchus,Cercopithecus_mitis_boutourlinii)),(Cercopithecus_albogularis,Cercopithecus_albogularis_monoides)),((Cercopithecus_mitis_heymansi,Cercopithecus_albogularis_kolbi),(Cercopithecus_mitis_opisthostictus,Cercopithecus_mitis_mitis))),(((Cercopithecus_kandti,((Cercopithecus_albogularis_francescae,(Cercopithecus_nictitans_nictitans,(Cercopithecus_nictitans_martini,Cercopithecus_solatus))),Cercopithecus_mitis)),Cercopithecus_doggetti),Cercopithecus_mitis_stuhlmanni)),Cercopithecus_nictitans),Erythrocebus_patas)),(Miopithecus_talapoin,(((Cercopithecus_diana,(((Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis),(((((Cercopithecus_wolfi_elegans,Cercopithecus_wolfi_pyrogaster),(Cercopithecus_pogonias,(Cercopithecus_pogonias_nigripes,Cercopithecus_pogonias_schwarzianus))),Cercopithecus_pogonias_grayi),(Cercopithecus_campbelli,Cercopithecus_mona)),(Cercopithecus_ascanius_schmidti,((Cercopithecus_neglectus,(Cercopithecus_lhoesti,(Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi))),((Cercopithecus_cephus_cephus,((((Cercopithecus_petaurista,(Cercopithecus_erythrogaster,Cercopithecus_erythrogaster_pococki)),(Cercopithecus_petaurista_petaurista,Cercopithecus_petaurista_buettikoferi)),Cercopithecus_ascanius_whitesidei),Cercopithecus_erythrotis_camerunensis)),Cercopithecus_ascanius_katangae))))),Cercopithecus_roloway)),Cercopithecus_albogularis_moloneyi),Miopithecus_ogouensis)))),((((Saimiri_sciureus_macrodon,(Saimiri_sciureus,(Saimiri_oerstedii,Saimiri_boliviensis))),Saimiri_oerstedii_citrinellus),((Aotus_nancymaae,(((Aotus_lemurinus,Aotus_azarai),Aotus_azarae),Aotus_trivirgatus)),(((Saguinus_oedipus,(((Callithrix_jacchus,Ateles_geoffroyi),Ateles_paniscus),(Callicebus_donacophilus,Ateles_belzebuth))),((((((Chiropotes_israelita,(Chiropotes_albinasus,Brachyteles_arachnoides)),(Cacajao_calvus,Pithecia_pithecia)),Lagothrix_lagotricha),(Cebus_albifrons,(Cebus_apella,Sapajus_xanthosternos))),((Callicebus_lugens,Callicebus_cupreus),((Callimico_goeldii,Leontopithecus_rosalia),Alouatta_caraya))),Callithrix_pygmaea)),Aotus_azarae_azarai))),(((Varecia_rubra,Propithecus_coquereli),(((Daubentonia_madagascariensis,(Eulemur_rubriventer,(((((Tarsius_lariang,(Tarsius_wallacei,Tarsius_dentatus)),Tarsius_syrichta),(Galago_moholi,((Nycticebus_coucang,Nycticebus_bengalensis),(Galagoides_demidoff,(Loris_lydekkerianus,Loris_tardigradus))))),(((Indri_indri,(Eulemur_rufus,(Cheirogaleus_medius,((Tarsius_bancanus,Prolemur_simus),(Varecia_variegata,Hapalemur_griseus))))),Palaeopropithecus_ingens),Megaladapis_edwardsi)),Avahi_laniger))),(Eulemur_mongoz,Eulemur_fulvus)),((((Otolemur_garnettii,(Perodicticus_potto_edwarsi,Perodicticus_potto)),Otolemur_crassicaudatus),Eulemur_macaco),(Propithecus_verreauxi,((Lemur_catta,(Lepilemur_hubbardorum,Lepilemur_ruficaudatus)),Galago_senegalensis))))),Nycticebus_pygmaeus)))),Gorilla_gorilla_gorilla))))),Pan_troglodytes_ellioti,Homo_sapiens); +((((Pan_troglodytes_ellioti,Homo_heidelbergensis),Pan_paniscus),Hylobates_lar),(((Gorilla_gorilla_gorilla,(Pan_troglodytes_troglodytes,(((Pongo_pygmaeus,Pongo_abelii),(Alouatta_caraya,(((((Callithrix_jacchus,((Callimico_goeldii,(((Cebus_albifrons,(Cebus_apella,Sapajus_xanthosternos)),(Ateles_geoffroyi,(((Chiropotes_albinasus,(Callicebus_donacophilus,(Brachyteles_arachnoides,Chiropotes_israelita))),Cacajao_calvus),((Saimiri_sciureus_macrodon,((Saimiri_oerstedii,Saimiri_sciureus),Saimiri_boliviensis)),Saimiri_oerstedii_citrinellus)))),(Pithecia_pithecia,(Ateles_belzebuth,(Callicebus_cupreus,Callicebus_lugens))))),(Leontopithecus_rosalia,(Aotus_azarae_azarai,(((Aotus_trivirgatus,(Aotus_lemurinus,Aotus_azarai)),Aotus_azarae),Aotus_nancymaae))))),Lagothrix_lagotricha),Ateles_paniscus),Callithrix_pygmaea),Saguinus_oedipus))),(((((Presbytis_melalophos,Semnopithecus_entellus),((Rhinopithecus_avunculus,Trachypithecus_johnii),((((((Pygathrix_nigripes,Pygathrix_nemaeus),Trachypithecus_pileatus),Trachypithecus_cristatus),(Trachypithecus_obscurus,(Trachypithecus_francoisi,(Simias_concolor,Nasalis_larvatus)))),((Rhinopithecus_roxellana,Rhinopithecus_brelichi),Rhinopithecus_bieti_2_RL2012)),((Colobus_satanas,Colobus_guereza),(Piliocolobus_badius,Procolobus_verus))))),((Miopithecus_ogouensis,((((Cercocebus_agilis,Lophocebus_albigena),Mandrillus_leucophaeus),Cercocebus_chrysogaster),((Cercocebus_torquatus,Cercocebus_atys),Mandrillus_sphinx))),((Miopithecus_talapoin,Cercopithecus_dryas),((Chlorocebus_aethiops,((Cercopithecus_aethiops,Chlorocebus_sabaeus),(Chlorocebus_tantalus,Chlorocebus_pygerythrus))),((((((Cercopithecus_preussi_insularis,(((Cercopithecus_erythrogaster,Cercopithecus_petaurista),Cercopithecus_petaurista_petaurista),(Cercopithecus_petaurista_buettikoferi,Cercopithecus_erythrogaster_pococki))),(Cercopithecus_cephus_cephus,(((Cercopithecus_lhoesti,(Cercopithecus_preussi_preussi,Cercopithecus_erythrotis_camerunensis)),Cercopithecus_ascanius_katangae),Cercopithecus_ascanius_whitesidei))),Cercopithecus_neglectus),(Cercopithecus_albogularis_moloneyi,Cercopithecus_albogularis_albotorquatus)),((Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis),Cercopithecus_ascanius_schmidti)),(((((((Cercopithecus_mitis,(Cercopithecus_albogularis_kolbi,(((Cercopithecus_doggetti,Cercopithecus_kandti),((Cercopithecus_albogularis_francescae,(Cercopithecus_solatus,Cercopithecus_nictitans_martini)),Cercopithecus_mitis_heymansi)),Cercopithecus_mitis_stuhlmanni))),(Cercopithecus_mitis_mitis,((Cercopithecus_mitis_opisthostictus,Cercopithecus_mitis_boutourlinii),(Cercopithecus_albogularis_erythrarchus,((Cercopithecus_albogularis_monoides,Cercopithecus_nictitans_nictitans),Cercopithecus_albogularis_labiatus))))),(((((((Cercopithecus_pogonias,Cercopithecus_pogonias_nigripes),Cercopithecus_pogonias_grayi),Cercopithecus_pogonias_schwarzianus),(Cercopithecus_wolfi_elegans,Cercopithecus_wolfi_pyrogaster)),(Cercopithecus_campbelli,Cercopithecus_mona)),Cercopithecus_diana),Cercopithecus_albogularis)),Cercopithecus_roloway),(Cercopithecus_hamlyni,Chlorocebus_cynosuros)),((Cercopithecus_nictitans,Erythrocebus_patas),Allenopithecus_nigroviridis)),((((((((Papio_hamadryas,Papio_anubis),Papio_papio),(Papio_cynocephalus,Papio_kindae)),Papio_ursinus),Rungwecebus_kipunji),(Theropithecus_gelada,Lophocebus_aterrimus)),((Macaca_sylvanus,(Macaca_silenus,Macaca_fascicularis)),Macaca_tonkeana)),((Macaca_thibetana,Macaca_assamensis),((Macaca_nemestrina,(Macaca_nigra,(Macaca_fuscata,Macaca_mulatta))),Macaca_arctoides))))))))),Homo_sapiens_ssp_Denisova),((Nycticebus_pygmaeus,((((((Megaladapis_edwardsi,(((Prolemur_simus,((Varecia_variegata,Cheirogaleus_medius),Hapalemur_griseus)),(Eulemur_rufus,(Indri_indri,Palaeopropithecus_ingens))),Eulemur_rubriventer)),Tarsius_bancanus),(((((Nycticebus_coucang,Nycticebus_bengalensis),(Loris_lydekkerianus,Loris_tardigradus)),Galagoides_demidoff),Galago_moholi),(Tarsius_syrichta,(Tarsius_lariang,(Tarsius_wallacei,Tarsius_dentatus))))),Avahi_laniger),Daubentonia_madagascariensis),(Eulemur_macaco,((((((Perodicticus_potto_edwarsi,Perodicticus_potto),Otolemur_crassicaudatus),Otolemur_garnettii),Galago_senegalensis),((Lemur_catta,(Lepilemur_hubbardorum,Lepilemur_ruficaudatus)),(Eulemur_mongoz,Eulemur_fulvus))),Propithecus_verreauxi)))),(Propithecus_coquereli,Varecia_rubra)))))),(Pan_troglodytes,(Hylobates_agilis,((Hylobates_moloch,Nomascus_leucogenys),Symphalangus_syndactylus)))),Gorilla_gorilla),Homo_sapiens); +((((((((Lagothrix_lagotricha,((((Cebus_albifrons,(Cebus_apella,Sapajus_xanthosternos)),(((Aotus_azarae_azarai,((Chiropotes_albinasus,(Aotus_trivirgatus,(((Ateles_paniscus,Ateles_geoffroyi),((Brachyteles_arachnoides,Ateles_belzebuth),Callicebus_donacophilus)),Chiropotes_israelita))),Cacajao_calvus)),Aotus_nancymaae),(((Saimiri_oerstedii,Saimiri_sciureus),(Saimiri_sciureus_macrodon,Saimiri_oerstedii_citrinellus)),Saimiri_boliviensis))),(((Callimico_goeldii,Leontopithecus_rosalia),Alouatta_caraya),(Callicebus_cupreus,Callicebus_lugens))),((Aotus_lemurinus,Aotus_azarai),Aotus_azarae))),((Callithrix_pygmaea,Callithrix_jacchus),Pithecia_pithecia)),Saguinus_oedipus),(((((Eulemur_mongoz,Eulemur_fulvus),(Propithecus_verreauxi,(((Otolemur_crassicaudatus,(Otolemur_garnettii,Galago_senegalensis)),(Perodicticus_potto,Perodicticus_potto_edwarsi)),Lemur_catta))),(Lepilemur_hubbardorum,Lepilemur_ruficaudatus)),Eulemur_macaco),((Tarsius_bancanus,((Tarsius_syrichta,(Tarsius_lariang,(Tarsius_wallacei,Tarsius_dentatus))),(((Loris_tardigradus,(((Nycticebus_coucang,Nycticebus_bengalensis),Loris_lydekkerianus),(Galagoides_demidoff,Galago_moholi))),Daubentonia_madagascariensis),(Megaladapis_edwardsi,((((Prolemur_simus,(((Varecia_rubra,Varecia_variegata),Hapalemur_griseus),Cheirogaleus_medius)),Eulemur_rufus),((Eulemur_rubriventer,(Propithecus_coquereli,Indri_indri)),Avahi_laniger)),Palaeopropithecus_ingens))))),Nycticebus_pygmaeus))),(((((Colobus_satanas,Colobus_guereza),(Piliocolobus_badius,Procolobus_verus)),(Presbytis_melalophos,((((((((Rhinopithecus_bieti_2_RL2012,Pygathrix_nigripes),(Simias_concolor,Rhinopithecus_brelichi)),Pygathrix_nemaeus),(Rhinopithecus_roxellana,Nasalis_larvatus)),(Trachypithecus_cristatus,Trachypithecus_johnii)),Trachypithecus_francoisi),(Trachypithecus_obscurus,Trachypithecus_pileatus)),Rhinopithecus_avunculus))),Semnopithecus_entellus),(Miopithecus_ogouensis,(((Mandrillus_sphinx,(((Cercocebus_torquatus,(Cercocebus_agilis,Mandrillus_leucophaeus)),Cercocebus_chrysogaster),Cercocebus_atys)),((Cercopithecus_diana,(Cercopithecus_ascanius_katangae,((((Macaca_thibetana,Macaca_assamensis),(Macaca_fascicularis,(((Macaca_nigra,(Macaca_fuscata,Macaca_mulatta)),(Macaca_sylvanus,((Papio_ursinus,((Papio_cynocephalus,Rungwecebus_kipunji),(((Lophocebus_albigena,Papio_papio),(Papio_hamadryas,Papio_anubis)),Papio_kindae))),(Theropithecus_gelada,Lophocebus_aterrimus)))),Macaca_nemestrina))),(Macaca_silenus,Macaca_tonkeana)),Macaca_arctoides))),((Cercopithecus_albogularis_francescae,((Cercopithecus_aethiops,Chlorocebus_sabaeus),(((Chlorocebus_tantalus,Chlorocebus_aethiops),Chlorocebus_pygerythrus),Cercopithecus_dryas))),(((Cercopithecus_albogularis_moloneyi,((((((Cercopithecus_pogonias_nigripes,Cercopithecus_pogonias_grayi),(Cercopithecus_pogonias,((Cercopithecus_wolfi_elegans,Cercopithecus_wolfi_pyrogaster),Cercopithecus_nictitans_martini))),Cercopithecus_pogonias_schwarzianus),(Cercopithecus_campbelli,Cercopithecus_mona)),((((Cercopithecus_petaurista,Cercopithecus_petaurista_petaurista),((Cercopithecus_petaurista_buettikoferi,Cercopithecus_erythrogaster_pococki),Cercopithecus_erythrogaster)),Cercopithecus_solatus),Cercopithecus_cephus_cephus)),((Cercopithecus_ascanius_schmidti,((Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis),Cercopithecus_neglectus)),Cercopithecus_ascanius_whitesidei))),Cercopithecus_albogularis_albotorquatus),((((Cercopithecus_lhoesti,(Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi)),(Cercopithecus_roloway,Cercopithecus_erythrotis_camerunensis)),((Cercopithecus_hamlyni,Chlorocebus_cynosuros),((Allenopithecus_nigroviridis,(((Cercopithecus_mitis,(((Cercopithecus_mitis_opisthostictus,Cercopithecus_kandti),Cercopithecus_mitis_mitis),Cercopithecus_nictitans)),((Cercopithecus_albogularis_erythrarchus,(Cercopithecus_albogularis_labiatus,Cercopithecus_albogularis_monoides)),Cercopithecus_mitis_boutourlinii)),(Cercopithecus_doggetti,((Cercopithecus_albogularis_kolbi,(Erythrocebus_patas,Cercopithecus_mitis_stuhlmanni)),Cercopithecus_nictitans_nictitans)))),Cercopithecus_mitis_heymansi))),Cercopithecus_albogularis))))),Miopithecus_talapoin)))),((Pongo_pygmaeus,Pongo_abelii),((((Hylobates_moloch,Hylobates_agilis),Hylobates_lar),Symphalangus_syndactylus),Nomascus_leucogenys))),(Gorilla_gorilla,(Homo_sapiens_ssp_Denisova,(Gorilla_gorilla_gorilla,Homo_heidelbergensis)))),((Pan_paniscus,(Pan_troglodytes,Pan_troglodytes_troglodytes)),Pan_troglodytes_ellioti),Homo_sapiens); +((Homo_sapiens_ssp_Denisova,(((Gorilla_gorilla_gorilla,(((((((((Saimiri_sciureus,Saimiri_sciureus_macrodon),(Saimiri_boliviensis,Saimiri_oerstedii)),Saimiri_oerstedii_citrinellus),(((((Lagothrix_lagotricha,((Callicebus_cupreus,(((Callimico_goeldii,Leontopithecus_rosalia),Alouatta_caraya),Pithecia_pithecia)),Callicebus_lugens)),((Cebus_albifrons,(Cebus_apella,Sapajus_xanthosternos)),((Ateles_geoffroyi,((((Brachyteles_arachnoides,Chiropotes_albinasus),(Chiropotes_israelita,Ateles_belzebuth)),Cacajao_calvus),Callicebus_donacophilus)),Ateles_paniscus))),(Callithrix_jacchus,(Callithrix_pygmaea,Saguinus_oedipus))),((((Aotus_lemurinus,Aotus_azarai),Aotus_trivirgatus),Aotus_azarae),Aotus_azarae_azarai)),Aotus_nancymaae)),((((Eulemur_mongoz,Eulemur_fulvus),((Lepilemur_hubbardorum,Lepilemur_ruficaudatus),((Lemur_catta,((Perodicticus_potto,Perodicticus_potto_edwarsi),((Galago_senegalensis,Otolemur_garnettii),Otolemur_crassicaudatus))),Propithecus_verreauxi))),Eulemur_macaco),((((((Nycticebus_coucang,Nycticebus_bengalensis),(Nycticebus_pygmaeus,(Loris_tardigradus,((Galagoides_demidoff,Galago_moholi),Loris_lydekkerianus)))),(((Indri_indri,Avahi_laniger),(((Megaladapis_edwardsi,Cheirogaleus_medius),((Eulemur_rubriventer,(Hapalemur_griseus,(Varecia_rubra,Varecia_variegata))),Eulemur_rufus)),Prolemur_simus)),Palaeopropithecus_ingens)),Daubentonia_madagascariensis),Propithecus_coquereli),((Tarsius_lariang,(Tarsius_wallacei,Tarsius_dentatus)),(Tarsius_bancanus,Tarsius_syrichta))))),(Miopithecus_ogouensis,(((((Rhinopithecus_bieti_2_RL2012,((((((Trachypithecus_johnii,Procolobus_verus),Piliocolobus_badius),Rhinopithecus_avunculus),(((Trachypithecus_cristatus,Trachypithecus_pileatus),(Semnopithecus_entellus,(Trachypithecus_francoisi,Trachypithecus_obscurus))),Presbytis_melalophos)),(((Pygathrix_nigripes,Pygathrix_nemaeus),(Simias_concolor,Nasalis_larvatus)),(Colobus_satanas,Colobus_guereza))),(Rhinopithecus_brelichi,Rhinopithecus_roxellana))),(((Cercocebus_agilis,(((Cercocebus_torquatus,Cercocebus_atys),Cercocebus_chrysogaster),Mandrillus_leucophaeus)),(((Lophocebus_albigena,Lophocebus_aterrimus),Theropithecus_gelada),(Rungwecebus_kipunji,(Papio_ursinus,(Papio_anubis,(Papio_hamadryas,((Papio_papio,Papio_cynocephalus),Papio_kindae))))))),(((Macaca_sylvanus,((Macaca_nigra,(Macaca_arctoides,(Macaca_fuscata,Macaca_mulatta))),Macaca_nemestrina)),(Macaca_thibetana,Macaca_assamensis)),(Macaca_fascicularis,(Macaca_silenus,Macaca_tonkeana))))),Miopithecus_talapoin),(Mandrillus_sphinx,((((Cercopithecus_dryas,((Cercopithecus_hamlyni,Chlorocebus_aethiops),((Chlorocebus_tantalus,((Cercopithecus_aethiops,Chlorocebus_sabaeus),Cercopithecus_solatus)),(Chlorocebus_cynosuros,Chlorocebus_pygerythrus)))),((Cercopithecus_campbelli,Cercopithecus_mona),((Cercopithecus_roloway,Cercopithecus_neglectus),((((Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis),(((((Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi),Cercopithecus_lhoesti),((Cercopithecus_erythrotis_camerunensis,(Cercopithecus_ascanius_katangae,(((((Cercopithecus_petaurista_buettikoferi,Cercopithecus_petaurista_petaurista),Cercopithecus_erythrogaster),Cercopithecus_petaurista),Cercopithecus_erythrogaster_pococki),Cercopithecus_cephus_cephus))),Cercopithecus_ascanius_whitesidei)),Cercopithecus_ascanius_schmidti),Cercopithecus_albogularis_moloneyi)),(Cercopithecus_albogularis_albotorquatus,Cercopithecus_albogularis)),((Cercopithecus_mitis,(((Cercopithecus_nictitans,((Cercopithecus_albogularis_kolbi,(Erythrocebus_patas,Cercopithecus_mitis_stuhlmanni)),Cercopithecus_nictitans_nictitans)),((Cercopithecus_albogularis_monoides,((Cercopithecus_mitis_boutourlinii,Cercopithecus_albogularis_labiatus),Cercopithecus_albogularis_erythrarchus)),(Cercopithecus_mitis_mitis,(Cercopithecus_mitis_opisthostictus,Cercopithecus_mitis_heymansi)))),((Allenopithecus_nigroviridis,Cercopithecus_kandti),Cercopithecus_doggetti))),Cercopithecus_albogularis_francescae))))),(Cercopithecus_nictitans_martini,Cercopithecus_pogonias)),(((Cercopithecus_pogonias_grayi,Cercopithecus_pogonias_schwarzianus),(Cercopithecus_wolfi_elegans,Cercopithecus_wolfi_pyrogaster)),Cercopithecus_pogonias_nigripes)))),Cercopithecus_diana))),Symphalangus_syndactylus),Pongo_pygmaeus),(Hylobates_agilis,(Hylobates_lar,(Pongo_abelii,(Hylobates_moloch,Nomascus_leucogenys)))))),Gorilla_gorilla),((Pan_troglodytes,Pan_troglodytes_troglodytes),Pan_paniscus))),(Pan_troglodytes_ellioti,Homo_heidelbergensis),Homo_sapiens); +((((Homo_heidelbergensis,((Gorilla_gorilla_gorilla,((((((Trachypithecus_johnii,((Trachypithecus_cristatus,(Trachypithecus_pileatus,(Trachypithecus_francoisi,Trachypithecus_obscurus))),(Rhinopithecus_bieti_2_RL2012,((Rhinopithecus_brelichi,((Nasalis_larvatus,Simias_concolor),(Pygathrix_nigripes,Pygathrix_nemaeus))),Rhinopithecus_roxellana)))),((Semnopithecus_entellus,Rhinopithecus_avunculus),Presbytis_melalophos)),(Procolobus_verus,(Piliocolobus_badius,(Colobus_satanas,Colobus_guereza)))),(Miopithecus_ogouensis,((((((Cercocebus_atys,Mandrillus_sphinx),Cercocebus_torquatus),(((Allenopithecus_nigroviridis,((((Lophocebus_albigena,Lophocebus_aterrimus),Rungwecebus_kipunji),(((Papio_ursinus,Papio_anubis),Papio_hamadryas),(Papio_kindae,(Papio_papio,Papio_cynocephalus)))),Theropithecus_gelada)),(Mandrillus_leucophaeus,Cercocebus_agilis)),Cercocebus_chrysogaster)),(Macaca_fascicularis,((Macaca_tonkeana,Macaca_silenus),(Erythrocebus_patas,((Macaca_nemestrina,(((Macaca_mulatta,Macaca_fuscata),Macaca_arctoides),((Macaca_assamensis,Macaca_thibetana),Macaca_sylvanus))),Macaca_nigra))))),Miopithecus_talapoin),(((((Cercopithecus_nictitans_martini,(Cercopithecus_pogonias,Cercopithecus_wolfi_pyrogaster)),(Cercopithecus_pogonias_grayi,(Cercopithecus_pogonias_schwarzianus,Cercopithecus_wolfi_elegans))),Cercopithecus_pogonias_nigripes),Cercopithecus_hamlyni),((Cercopithecus_nictitans,Cercopithecus_diana),(Cercopithecus_roloway,(((Cercopithecus_neglectus,((Chlorocebus_sabaeus,Cercopithecus_aethiops),(((Chlorocebus_pygerythrus,(Chlorocebus_tantalus,(Chlorocebus_cynosuros,Chlorocebus_aethiops))),Cercopithecus_dryas),Cercopithecus_solatus))),(Cercopithecus_campbelli,Cercopithecus_mona)),(((((Cercopithecus_ascanius_schmidti,(((Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi),Cercopithecus_lhoesti),(Cercopithecus_ascanius_whitesidei,(((Cercopithecus_ascanius_katangae,((Cercopithecus_petaurista_petaurista,Cercopithecus_petaurista_buettikoferi),Cercopithecus_petaurista)),((Cercopithecus_erythrogaster_pococki,Cercopithecus_erythrogaster),Cercopithecus_cephus_cephus)),Cercopithecus_erythrotis_camerunensis)))),Cercopithecus_cephus),Cercopithecus_albogularis_francescae),(((Cercopithecus_albogularis,(((Cercopithecus_albogularis_labiatus,Cercopithecus_albogularis_monoides),Cercopithecus_albogularis_erythrarchus),(Cercopithecus_albogularis_albotorquatus,Cercopithecus_mitis_boutourlinii))),((Cercopithecus_albogularis_kolbi,Cercopithecus_mitis_heymansi),(Cercopithecus_mitis_opisthostictus,Cercopithecus_mitis_mitis))),(Cercopithecus_albogularis_moloneyi,(((Cercopithecus_mitis_stuhlmanni,Cercopithecus_kandti),Cercopithecus_mitis),Cercopithecus_doggetti)))),(Cercopithecus_cephus_ngottoensis,Cercopithecus_nictitans_nictitans))))))))),((Alouatta_caraya,((((Saimiri_boliviensis,(Saimiri_sciureus,Saimiri_oerstedii)),Saimiri_sciureus_macrodon),Saimiri_oerstedii_citrinellus),(Brachyteles_arachnoides,((Cacajao_calvus,(Chiropotes_israelita,Chiropotes_albinasus)),(((Callicebus_cupreus,Callicebus_lugens),((Aotus_trivirgatus,(Lagothrix_lagotricha,(Aotus_azarae_azarai,((Leontopithecus_rosalia,(((((Saguinus_oedipus,(Callithrix_jacchus,Callithrix_pygmaea)),Ateles_belzebuth),Callicebus_donacophilus),((Ateles_paniscus,Ateles_geoffroyi),Callimico_goeldii)),(Aotus_azarae,(Aotus_lemurinus,Aotus_azarai)))),Pithecia_pithecia)))),Aotus_nancymaae)),(Sapajus_xanthosternos,(Cebus_albifrons,Cebus_apella))))))),(((((Tarsius_lariang,(Tarsius_wallacei,Tarsius_dentatus)),Tarsius_syrichta),(((Perodicticus_potto,Perodicticus_potto_edwarsi),((Galago_senegalensis,((Otolemur_crassicaudatus,(Galagoides_demidoff,Galago_moholi)),Otolemur_garnettii)),((Loris_lydekkerianus,(Nycticebus_bengalensis,Nycticebus_coucang)),Nycticebus_pygmaeus))),((Propithecus_verreauxi,((((Lepilemur_hubbardorum,Lepilemur_ruficaudatus),Indri_indri),Avahi_laniger),((((((((Lemur_catta,Varecia_rubra),Varecia_variegata),Hapalemur_griseus),(Prolemur_simus,Cheirogaleus_medius)),((Eulemur_rufus,Eulemur_fulvus),Eulemur_macaco)),(Eulemur_mongoz,Eulemur_rubriventer)),Megaladapis_edwardsi),Palaeopropithecus_ingens))),(Propithecus_coquereli,Daubentonia_madagascariensis)))),Loris_tardigradus),Tarsius_bancanus))),Homo_sapiens_ssp_Denisova)),(((((Symphalangus_syndactylus,Hylobates_lar),Hylobates_agilis),Nomascus_leucogenys),Hylobates_moloch),(Pongo_pygmaeus,Pongo_abelii)))),Gorilla_gorilla),Pan_troglodytes_ellioti),(Pan_troglodytes_troglodytes,(Pan_paniscus,Pan_troglodytes)),Homo_sapiens); +((((Gorilla_gorilla,(((Nomascus_leucogenys,(Hylobates_moloch,((Symphalangus_syndactylus,Hylobates_agilis),Hylobates_lar))),(Pongo_pygmaeus,Pongo_abelii)),Homo_heidelbergensis)),(Gorilla_gorilla_gorilla,((((Trachypithecus_pileatus,(((Presbytis_melalophos,((Procolobus_verus,(Piliocolobus_badius,(Colobus_satanas,Colobus_guereza))),Rhinopithecus_avunculus)),(Rhinopithecus_roxellana,((((Semnopithecus_entellus,(Nasalis_larvatus,Simias_concolor)),(Pygathrix_nemaeus,Pygathrix_nigripes)),Rhinopithecus_bieti_2_RL2012),Rhinopithecus_brelichi))),(Trachypithecus_cristatus,(Trachypithecus_francoisi,(Trachypithecus_obscurus,Trachypithecus_johnii))))),(((((Cercocebus_atys,Mandrillus_sphinx),Cercocebus_torquatus),(((Theropithecus_gelada,(Lophocebus_albigena,Lophocebus_aterrimus)),(Rungwecebus_kipunji,((Papio_ursinus,(Papio_hamadryas,Papio_anubis)),((Papio_papio,Papio_cynocephalus),Papio_kindae)))),(Mandrillus_leucophaeus,(Cercocebus_chrysogaster,Cercocebus_agilis)))),(Macaca_silenus,(Macaca_tonkeana,(((Macaca_nemestrina,(((Macaca_mulatta,Macaca_fuscata),Macaca_arctoides),((Macaca_assamensis,Macaca_thibetana),Macaca_sylvanus))),Macaca_nigra),Macaca_fascicularis)))),(Miopithecus_ogouensis,(Cercopithecus_diana,(Miopithecus_talapoin,((((((Cercopithecus_nictitans,Erythrocebus_patas),Cercopithecus_hamlyni),Allenopithecus_nigroviridis),(((((Cercopithecus_albogularis_albotorquatus,Cercopithecus_albogularis_monoides),(Cercopithecus_albogularis_erythrarchus,Cercopithecus_albogularis_labiatus)),Cercopithecus_mitis_boutourlinii),(Cercopithecus_albogularis_moloneyi,((Cercopithecus_doggetti,((((Cercopithecus_albogularis_kolbi,Cercopithecus_mitis_heymansi),(Cercopithecus_mitis_opisthostictus,Cercopithecus_mitis_mitis)),Cercopithecus_mitis_stuhlmanni),Cercopithecus_kandti)),Cercopithecus_mitis))),Cercopithecus_albogularis)),Cercopithecus_roloway),((Cercopithecus_nictitans_martini,(((Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans),(Cercopithecus_pogonias_nigripes,Cercopithecus_pogonias_grayi)),Cercopithecus_pogonias_schwarzianus)),((((Cercopithecus_cephus_ngottoensis,Cercopithecus_cephus),Cercopithecus_neglectus),((((Cercopithecus_ascanius_whitesidei,Cercopithecus_ascanius_schmidti),(Cercopithecus_pogonias,(Cercopithecus_campbelli,Cercopithecus_mona))),(Cercopithecus_erythrotis_camerunensis,(Cercopithecus_cephus_cephus,(((Cercopithecus_petaurista,((Cercopithecus_petaurista_buettikoferi,Cercopithecus_erythrogaster_pococki),Cercopithecus_erythrogaster)),Cercopithecus_petaurista_petaurista),Cercopithecus_ascanius_katangae)))),((Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi),Cercopithecus_lhoesti))),((((Chlorocebus_sabaeus,(Cercopithecus_aethiops,Cercopithecus_solatus)),((Chlorocebus_aethiops,(Chlorocebus_cynosuros,Chlorocebus_tantalus)),Chlorocebus_pygerythrus)),Cercopithecus_dryas),(Cercopithecus_nictitans_nictitans,Cercopithecus_albogularis_francescae)))))))))),((((Saimiri_oerstedii_citrinellus,(Saimiri_sciureus,(Saimiri_boliviensis,Saimiri_oerstedii))),Saimiri_sciureus_macrodon),(Chiropotes_albinasus,(((Pithecia_pithecia,Cacajao_calvus),(Lagothrix_lagotricha,(((Alouatta_caraya,((Aotus_nancymaae,Leontopithecus_rosalia),((Saguinus_oedipus,Callithrix_pygmaea),(Aotus_azarae,(Aotus_azarae_azarai,((Aotus_lemurinus,Aotus_azarai),Aotus_trivirgatus)))))),((Callicebus_cupreus,((((Ateles_paniscus,Brachyteles_arachnoides),(Ateles_geoffroyi,(Callithrix_jacchus,Callimico_goeldii))),Callicebus_donacophilus),Ateles_belzebuth)),Callicebus_lugens)),(Cebus_albifrons,(Cebus_apella,Sapajus_xanthosternos))))),Chiropotes_israelita))),(((((Daubentonia_madagascariensis,((((Eulemur_mongoz,(Eulemur_fulvus,(Eulemur_rubriventer,(Eulemur_macaco,((Prolemur_simus,(Cheirogaleus_medius,((Varecia_rubra,Varecia_variegata),(Lemur_catta,Hapalemur_griseus)))),Eulemur_rufus))))),Megaladapis_edwardsi),Palaeopropithecus_ingens),((Lepilemur_hubbardorum,Lepilemur_ruficaudatus),(Propithecus_verreauxi,(Avahi_laniger,(Propithecus_coquereli,Indri_indri)))))),(((((Otolemur_crassicaudatus,(Galago_senegalensis,Otolemur_garnettii)),Galago_moholi),Galagoides_demidoff),Loris_lydekkerianus),(Nycticebus_pygmaeus,(Nycticebus_bengalensis,Nycticebus_coucang)))),(Perodicticus_potto,Perodicticus_potto_edwarsi)),((Tarsius_wallacei,(Tarsius_dentatus,Tarsius_lariang)),Tarsius_syrichta)),(Tarsius_bancanus,Loris_tardigradus)))),Homo_sapiens_ssp_Denisova))),(Pan_troglodytes_ellioti,Pan_troglodytes_troglodytes)),(Pan_paniscus,Pan_troglodytes),Homo_sapiens); +(((Pan_troglodytes,(Pan_troglodytes_troglodytes,Pan_paniscus)),(Homo_sapiens_ssp_Denisova,((((((Hylobates_lar,Symphalangus_syndactylus),Hylobates_agilis),(Hylobates_moloch,Nomascus_leucogenys)),(Pongo_pygmaeus,Pongo_abelii)),((((((Rhinopithecus_avunculus,((Semnopithecus_entellus,Trachypithecus_johnii),Presbytis_melalophos)),((((Rhinopithecus_roxellana,Rhinopithecus_bieti_2_RL2012),((Simias_concolor,Nasalis_larvatus),(Pygathrix_nemaeus,Pygathrix_nigripes))),Rhinopithecus_brelichi),(Trachypithecus_pileatus,((Trachypithecus_cristatus,Trachypithecus_francoisi),Trachypithecus_obscurus)))),(Procolobus_verus,(Piliocolobus_badius,(Colobus_satanas,Colobus_guereza)))),((((((((((Cercopithecus_nictitans_nictitans,Cercopithecus_albogularis_francescae),(((Cercopithecus_nictitans,Erythrocebus_patas),Cercopithecus_hamlyni),Allenopithecus_nigroviridis)),((Chlorocebus_sabaeus,Cercopithecus_aethiops),(Cercopithecus_dryas,(Cercopithecus_solatus,((Chlorocebus_aethiops,(Chlorocebus_tantalus,Chlorocebus_cynosuros)),Chlorocebus_pygerythrus))))),Cercopithecus_neglectus),((Cercopithecus_cephus_ngottoensis,Cercopithecus_cephus),(((((Cercopithecus_albogularis_moloneyi,((Cercopithecus_doggetti,((Cercopithecus_kandti,Cercopithecus_mitis_stuhlmanni),(((Cercopithecus_mitis_mitis,Cercopithecus_mitis_opisthostictus),Cercopithecus_mitis_heymansi),Cercopithecus_albogularis_kolbi))),Cercopithecus_mitis)),(Cercopithecus_mitis_boutourlinii,(Cercopithecus_albogularis_erythrarchus,(Cercopithecus_albogularis_albotorquatus,Cercopithecus_albogularis_labiatus)))),Cercopithecus_albogularis_monoides),Cercopithecus_albogularis),(((Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi),(((Cercopithecus_erythrotis_camerunensis,(Cercopithecus_ascanius_whitesidei,(Cercopithecus_petaurista,((Cercopithecus_erythrogaster,Cercopithecus_erythrogaster_pococki),(Cercopithecus_petaurista_buettikoferi,Cercopithecus_petaurista_petaurista))))),Cercopithecus_ascanius_katangae),Cercopithecus_ascanius_schmidti)),Cercopithecus_lhoesti)))),Cercopithecus_roloway),Miopithecus_talapoin),Miopithecus_ogouensis),(Cercopithecus_diana,((Cercopithecus_cephus_cephus,(Cercopithecus_campbelli,Cercopithecus_mona)),(((Cercopithecus_pogonias_nigripes,(Cercopithecus_pogonias_grayi,((Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans),Cercopithecus_pogonias_schwarzianus))),Cercopithecus_nictitans_martini),Cercopithecus_pogonias)))),(((Mandrillus_sphinx,Cercocebus_torquatus),(((Cercocebus_agilis,Mandrillus_leucophaeus),(((Lophocebus_albigena,Lophocebus_aterrimus),(Theropithecus_gelada,((Papio_papio,(Papio_cynocephalus,Papio_kindae)),(Papio_hamadryas,(Papio_ursinus,Papio_anubis))))),Rungwecebus_kipunji)),Cercocebus_chrysogaster)),(Cercocebus_atys,((((Macaca_assamensis,Macaca_thibetana),Macaca_silenus),(Macaca_tonkeana,(Macaca_arctoides,((Macaca_sylvanus,Macaca_nemestrina),((Macaca_mulatta,Macaca_fuscata),Macaca_nigra))))),Macaca_fascicularis))))),((Alouatta_caraya,((((((Sapajus_xanthosternos,(Cebus_albifrons,Cebus_apella)),(Aotus_trivirgatus,((Cacajao_calvus,((Chiropotes_israelita,Lagothrix_lagotricha),Aotus_azarae)),Chiropotes_albinasus))),((Aotus_azarae_azarai,(((((Brachyteles_arachnoides,(Callicebus_cupreus,Callimico_goeldii)),Callicebus_donacophilus),(Ateles_belzebuth,Ateles_paniscus)),Ateles_geoffroyi),Callicebus_lugens)),Pithecia_pithecia)),((Saguinus_oedipus,Aotus_nancymaae),(Leontopithecus_rosalia,(Callithrix_jacchus,Callithrix_pygmaea)))),(Aotus_lemurinus,Aotus_azarai)),(((Saimiri_sciureus_macrodon,(Saimiri_boliviensis,Saimiri_oerstedii)),Saimiri_sciureus),Saimiri_oerstedii_citrinellus))),((Otolemur_garnettii,Tarsius_bancanus),((((Perodicticus_potto,Perodicticus_potto_edwarsi),((((Galago_moholi,((Nycticebus_bengalensis,(Nycticebus_pygmaeus,Nycticebus_coucang)),(Galagoides_demidoff,(Loris_tardigradus,Loris_lydekkerianus)))),Otolemur_crassicaudatus),(((((((((Varecia_rubra,Varecia_variegata),(Lemur_catta,Hapalemur_griseus)),Prolemur_simus),((((Cheirogaleus_medius,Megaladapis_edwardsi),Eulemur_fulvus),Eulemur_macaco),Eulemur_rubriventer)),Eulemur_mongoz),Eulemur_rufus),Palaeopropithecus_ingens),((Indri_indri,(Lepilemur_hubbardorum,Lepilemur_ruficaudatus)),Avahi_laniger)),(Propithecus_verreauxi,Propithecus_coquereli))),Galago_senegalensis)),Daubentonia_madagascariensis),(Tarsius_syrichta,(Tarsius_wallacei,(Tarsius_dentatus,Tarsius_lariang))))))),(Gorilla_gorilla_gorilla,Gorilla_gorilla))),Homo_heidelbergensis))),Pan_troglodytes_ellioti,Homo_sapiens); +((Pan_troglodytes_ellioti,Homo_heidelbergensis),(Gorilla_gorilla,(Pan_paniscus,(((Gorilla_gorilla_gorilla,((Hylobates_moloch,(((Nomascus_leucogenys,Hylobates_agilis),Symphalangus_syndactylus),(Pongo_pygmaeus,(Hylobates_lar,Pongo_abelii)))),(((Semnopithecus_entellus,(((((((((Simias_concolor,Nasalis_larvatus),(Pygathrix_nemaeus,Pygathrix_nigripes)),Rhinopithecus_bieti_2_RL2012),Rhinopithecus_brelichi),Rhinopithecus_roxellana),(Trachypithecus_johnii,(((Trachypithecus_obscurus,Trachypithecus_francoisi),Trachypithecus_cristatus),Trachypithecus_pileatus))),((Colobus_satanas,Colobus_guereza),(Procolobus_verus,Piliocolobus_badius))),Rhinopithecus_avunculus),Presbytis_melalophos)),(((((((Papio_ursinus,Papio_anubis),Papio_hamadryas),(Papio_kindae,(Papio_papio,Papio_cynocephalus))),(Theropithecus_gelada,(Rungwecebus_kipunji,Lophocebus_aterrimus))),((Cercocebus_agilis,(Mandrillus_leucophaeus,(((Cercocebus_torquatus,Cercocebus_atys),Mandrillus_sphinx),Cercocebus_chrysogaster))),Lophocebus_albigena)),(((Macaca_tonkeana,(Macaca_silenus,Macaca_fascicularis)),((Macaca_sylvanus,(Macaca_assamensis,Macaca_thibetana)),(Macaca_nemestrina,((Macaca_mulatta,Macaca_fuscata),Macaca_nigra)))),Macaca_arctoides)),(((Miopithecus_talapoin,Miopithecus_ogouensis),(((((Cercopithecus_campbelli,Cercopithecus_mona),Cercopithecus_roloway),((Chlorocebus_sabaeus,Cercopithecus_aethiops),((Cercopithecus_cephus_cephus,Cercopithecus_diana),Erythrocebus_patas))),(Cercopithecus_neglectus,(Cercopithecus_nictitans,((((((Cercopithecus_ascanius_whitesidei,((Cercopithecus_ascanius_katangae,((Cercopithecus_erythrogaster,Cercopithecus_petaurista),((Cercopithecus_erythrogaster_pococki,Cercopithecus_petaurista_buettikoferi),Cercopithecus_petaurista_petaurista))),Cercopithecus_erythrotis_camerunensis)),((Cercopithecus_preussi_preussi,Cercopithecus_preussi_insularis),Cercopithecus_lhoesti)),(Cercopithecus_doggetti,((((((Cercopithecus_albogularis_kolbi,Cercopithecus_mitis_stuhlmanni),Cercopithecus_albogularis_albotorquatus),((Cercopithecus_mitis_mitis,(Cercopithecus_cephus_ngottoensis,Cercopithecus_cephus)),Cercopithecus_kandti)),((Cercopithecus_albogularis_moloneyi,(Cercopithecus_albogularis_labiatus,Cercopithecus_albogularis_erythrarchus)),Cercopithecus_nictitans_nictitans)),Cercopithecus_mitis_opisthostictus),Cercopithecus_mitis_boutourlinii))),Cercopithecus_mitis),Cercopithecus_ascanius_schmidti),(((Cercopithecus_albogularis_monoides,Cercopithecus_albogularis),Cercopithecus_mitis_heymansi),Cercopithecus_albogularis_francescae))))),(((Cercopithecus_pogonias,((Cercopithecus_pogonias_grayi,(Cercopithecus_pogonias_nigripes,Cercopithecus_pogonias_schwarzianus)),(Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans))),Cercopithecus_dryas),(Cercopithecus_nictitans_martini,((Cercopithecus_hamlyni,Chlorocebus_aethiops),(Chlorocebus_cynosuros,(Chlorocebus_tantalus,(Allenopithecus_nigroviridis,Chlorocebus_pygerythrus)))))))),Cercopithecus_solatus))),(Homo_sapiens_ssp_Denisova,((((Aotus_lemurinus,Aotus_azarai),(Aotus_trivirgatus,Aotus_azarae)),(((Cebus_albifrons,(Cebus_apella,Sapajus_xanthosternos)),(Callicebus_lugens,Callicebus_cupreus)),((Ateles_paniscus,((Callicebus_donacophilus,((((Leontopithecus_rosalia,Alouatta_caraya),Callimico_goeldii),(((Ateles_belzebuth,((Brachyteles_arachnoides,Chiropotes_israelita),Pithecia_pithecia)),Chiropotes_albinasus),(((Aotus_nancymaae,Aotus_azarae_azarai),((((Saimiri_sciureus,Saimiri_oerstedii),Saimiri_boliviensis),Saimiri_sciureus_macrodon),Saimiri_oerstedii_citrinellus)),Cacajao_calvus))),(Saguinus_oedipus,(Callithrix_pygmaea,Callithrix_jacchus)))),Ateles_geoffroyi)),Lagothrix_lagotricha))),(((((Tarsius_lariang,(Tarsius_wallacei,Tarsius_dentatus)),Tarsius_syrichta),((Avahi_laniger,Daubentonia_madagascariensis),((((((((((Varecia_rubra,(Eulemur_mongoz,Eulemur_rufus)),Nycticebus_pygmaeus),Eulemur_rubriventer),Eulemur_macaco),Varecia_variegata),((Eulemur_fulvus,((Prolemur_simus,Hapalemur_griseus),(Cheirogaleus_medius,Megaladapis_edwardsi))),Lemur_catta)),Palaeopropithecus_ingens),((Lepilemur_hubbardorum,Indri_indri),Lepilemur_ruficaudatus)),(((Otolemur_crassicaudatus,Galagoides_demidoff),(Galago_senegalensis,Galago_moholi)),((((Propithecus_verreauxi,Loris_tardigradus),Loris_lydekkerianus),(Nycticebus_bengalensis,Nycticebus_coucang)),(Perodicticus_potto,Perodicticus_potto_edwarsi)))),Propithecus_coquereli))),Otolemur_garnettii),Tarsius_bancanus)))))),Pan_troglodytes_troglodytes),Pan_troglodytes))),Homo_sapiens); +(((Homo_sapiens_ssp_Denisova,(Homo_heidelbergensis,((Gorilla_gorilla_gorilla,Gorilla_gorilla),((((((Symphalangus_syndactylus,Hylobates_lar),Hylobates_agilis),Hylobates_moloch),Nomascus_leucogenys),(Pongo_pygmaeus,Pongo_abelii)),(((Rhinopithecus_bieti_2_RL2012,(Rhinopithecus_roxellana,(((Pygathrix_nemaeus,Pygathrix_nigripes),(Simias_concolor,Nasalis_larvatus)),(Rhinopithecus_brelichi,((((Colobus_satanas,Colobus_guereza),(Procolobus_verus,Piliocolobus_badius)),(Rhinopithecus_avunculus,((((Semnopithecus_entellus,Trachypithecus_francoisi),Trachypithecus_obscurus),Trachypithecus_johnii),(Trachypithecus_pileatus,Trachypithecus_cristatus)))),Presbytis_melalophos))))),((((((Cercocebus_torquatus,Cercocebus_atys),Mandrillus_sphinx),Cercocebus_chrysogaster),Mandrillus_leucophaeus),Cercocebus_agilis),(((((Lophocebus_albigena,Lophocebus_aterrimus),Theropithecus_gelada),(Rungwecebus_kipunji,((Papio_anubis,Papio_hamadryas),(Papio_ursinus,((Papio_papio,Papio_cynocephalus),Papio_kindae))))),((Macaca_fascicularis,(Macaca_tonkeana,Macaca_silenus)),((Macaca_arctoides,(Macaca_assamensis,Macaca_thibetana)),(((Macaca_sylvanus,Macaca_nemestrina),Macaca_nigra),(Macaca_mulatta,Macaca_fuscata))))),((((Miopithecus_talapoin,((Cercopithecus_roloway,(Chlorocebus_cynosuros,Cercopithecus_diana)),Chlorocebus_tantalus)),((Cercopithecus_hamlyni,Chlorocebus_aethiops),Miopithecus_ogouensis)),((Cercopithecus_dryas,((Cercopithecus_nictitans_martini,((Cercopithecus_neglectus,(Cercopithecus_solatus,(((Cercopithecus_pogonias_nigripes,(((Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans),Cercopithecus_pogonias_schwarzianus),(Cercopithecus_pogonias,(Erythrocebus_patas,Cercopithecus_mona)))),Cercopithecus_pogonias_grayi),Cercopithecus_campbelli))),Cercopithecus_cephus_cephus)),Chlorocebus_sabaeus)),(Cercopithecus_aethiops,((((Cercopithecus_albogularis_francescae,((Cercopithecus_ascanius_katangae,(((Cercopithecus_preussi_preussi,Cercopithecus_preussi_insularis),Cercopithecus_lhoesti),Cercopithecus_ascanius_whitesidei)),(Cercopithecus_nictitans_nictitans,((((Cercopithecus_kandti,Cercopithecus_mitis_stuhlmanni),(Cercopithecus_mitis,Cercopithecus_doggetti)),Cercopithecus_nictitans),((((Cercopithecus_albogularis_monoides,Cercopithecus_albogularis),(Cercopithecus_albogularis_albotorquatus,(Cercopithecus_mitis_mitis,((Cercopithecus_albogularis_erythrarchus,((Cercopithecus_mitis_opisthostictus,Cercopithecus_mitis_boutourlinii),Cercopithecus_albogularis_labiatus)),(Cercopithecus_mitis_heymansi,Cercopithecus_albogularis_kolbi))))),Cercopithecus_erythrotis_camerunensis),Cercopithecus_albogularis_moloneyi))))),(Cercopithecus_cephus_ngottoensis,Cercopithecus_cephus)),Cercopithecus_ascanius_schmidti),((Cercopithecus_erythrogaster,((Cercopithecus_erythrogaster_pococki,Cercopithecus_petaurista_buettikoferi),Cercopithecus_petaurista_petaurista)),Cercopithecus_petaurista))))),(Allenopithecus_nigroviridis,Chlorocebus_pygerythrus))))),((((Aotus_azarae_azarai,((Lagothrix_lagotricha,(((((((Cacajao_calvus,Chiropotes_israelita),(Chiropotes_albinasus,(Saimiri_oerstedii_citrinellus,((Saimiri_boliviensis,Saimiri_oerstedii),(Saimiri_sciureus,Saimiri_sciureus_macrodon))))),(((Leontopithecus_rosalia,Alouatta_caraya),Callimico_goeldii),(Callicebus_lugens,Callicebus_cupreus))),(Cebus_albifrons,(Cebus_apella,Sapajus_xanthosternos))),((((((Ateles_paniscus,Ateles_geoffroyi),Callithrix_jacchus),Brachyteles_arachnoides),Ateles_belzebuth),Callicebus_donacophilus),Saguinus_oedipus)),(Aotus_nancymaae,Callithrix_pygmaea)),Pithecia_pithecia)),Aotus_azarae)),Aotus_trivirgatus),(Aotus_lemurinus,Aotus_azarai)),(((((Tarsius_lariang,(Tarsius_dentatus,Tarsius_wallacei)),Tarsius_syrichta),((Daubentonia_madagascariensis,(((Perodicticus_potto,Perodicticus_potto_edwarsi),Galago_moholi),((Galagoides_demidoff,(Loris_tardigradus,Loris_lydekkerianus)),(Nycticebus_bengalensis,Nycticebus_coucang)))),(((Propithecus_verreauxi,((Palaeopropithecus_ingens,(Propithecus_coquereli,((((Varecia_variegata,Varecia_rubra),((Prolemur_simus,(Nycticebus_pygmaeus,Hapalemur_griseus)),(Eulemur_fulvus,Cheirogaleus_medius))),(((Eulemur_rufus,Eulemur_rubriventer),Eulemur_mongoz),Eulemur_macaco)),(Lemur_catta,(Avahi_laniger,Indri_indri))))),(Lepilemur_hubbardorum,Lepilemur_ruficaudatus))),Megaladapis_edwardsi),Galago_senegalensis))),(Otolemur_garnettii,Otolemur_crassicaudatus)),Tarsius_bancanus))))))),(Pan_troglodytes_troglodytes,Pan_troglodytes_ellioti)),(Pan_paniscus,Pan_troglodytes),Homo_sapiens); +((((Symphalangus_syndactylus,Nomascus_leucogenys),(Hylobates_moloch,Hylobates_lar)),Hylobates_agilis),(Pan_paniscus,(Pan_troglodytes,(Pan_troglodytes_troglodytes,(Pan_troglodytes_ellioti,(Homo_heidelbergensis,((Gorilla_gorilla,(Homo_sapiens_ssp_Denisova,((Pongo_pygmaeus,Pongo_abelii),((((((Trachypithecus_pileatus,(((Trachypithecus_obscurus,Trachypithecus_francoisi),Trachypithecus_johnii),Trachypithecus_cristatus)),(Rhinopithecus_roxellana,((((Pygathrix_nemaeus,Pygathrix_nigripes),(Simias_concolor,Nasalis_larvatus)),Rhinopithecus_brelichi),Rhinopithecus_bieti_2_RL2012))),(Presbytis_melalophos,(Semnopithecus_entellus,Rhinopithecus_avunculus))),((Colobus_satanas,Colobus_guereza),(Procolobus_verus,Piliocolobus_badius))),(((Rungwecebus_kipunji,Lophocebus_albigena),(((Papio_papio,Papio_cynocephalus),Papio_kindae),(Papio_hamadryas,(Papio_anubis,Papio_ursinus)))),((Theropithecus_gelada,Lophocebus_aterrimus),(((((Macaca_nigra,(Macaca_fascicularis,(Macaca_tonkeana,Macaca_silenus))),((Macaca_assamensis,Macaca_thibetana),((Macaca_mulatta,Macaca_fuscata),Macaca_nemestrina))),Macaca_arctoides),Macaca_sylvanus),((((Cercocebus_atys,Mandrillus_sphinx),((((((Erythrocebus_patas,Cercopithecus_roloway),Cercopithecus_diana),((Cercopithecus_cephus,(((((Cercopithecus_ascanius_schmidti,((Cercopithecus_preussi_preussi,Cercopithecus_preussi_insularis),Cercopithecus_lhoesti)),(Cercopithecus_cephus_ngottoensis,(Cercopithecus_ascanius_whitesidei,((((Cercopithecus_petaurista_buettikoferi,Cercopithecus_petaurista_petaurista),(Cercopithecus_erythrogaster_pococki,Cercopithecus_erythrogaster)),Cercopithecus_petaurista),Cercopithecus_erythrotis_camerunensis)))),Cercopithecus_ascanius_katangae),((Cercopithecus_nictitans_nictitans,Cercopithecus_albogularis_francescae),((((Cercopithecus_albogularis_albotorquatus,(Cercopithecus_albogularis_erythrarchus,((Cercopithecus_mitis_boutourlinii,Cercopithecus_albogularis_moloneyi),Cercopithecus_albogularis_labiatus))),(Cercopithecus_albogularis_monoides,Cercopithecus_albogularis)),((Cercopithecus_albogularis_kolbi,(((((Cercopithecus_mitis_heymansi,Cercopithecus_mitis),Cercopithecus_nictitans),Cercopithecus_doggetti),Cercopithecus_mitis_mitis),Cercopithecus_mitis_opisthostictus)),Cercopithecus_mitis_stuhlmanni)),Cercopithecus_kandti))),Cercopithecus_cephus_cephus)),((Cercopithecus_neglectus,(((Cercopithecus_pogonias,(Cercopithecus_nictitans_martini,(Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans))),(Cercopithecus_pogonias_schwarzianus,Cercopithecus_pogonias_nigripes)),Cercopithecus_pogonias_grayi)),(Cercopithecus_mona,Cercopithecus_campbelli)))),(Miopithecus_talapoin,Miopithecus_ogouensis)),((((Chlorocebus_tantalus,(Cercopithecus_hamlyni,Chlorocebus_aethiops)),Chlorocebus_cynosuros),(((Chlorocebus_sabaeus,Cercopithecus_aethiops),Cercopithecus_solatus),Cercopithecus_dryas)),Chlorocebus_pygerythrus)),Cercocebus_torquatus)),(Cercocebus_agilis,(Cercocebus_chrysogaster,Mandrillus_leucophaeus))),Allenopithecus_nigroviridis))))),((Alouatta_caraya,(((Aotus_azarae,(Aotus_azarae_azarai,((((Aotus_trivirgatus,((Cacajao_calvus,(Chiropotes_albinasus,(Lagothrix_lagotricha,Chiropotes_israelita))),((((Saimiri_oerstedii,Saimiri_sciureus),Saimiri_sciureus_macrodon),Saimiri_boliviensis),Saimiri_oerstedii_citrinellus))),(Cebus_albifrons,(Cebus_apella,Sapajus_xanthosternos))),(Callicebus_lugens,((Callicebus_donacophilus,(((((Callimico_goeldii,Ateles_belzebuth),Ateles_geoffroyi),Ateles_paniscus),Callithrix_jacchus),Brachyteles_arachnoides)),Callicebus_cupreus))),Pithecia_pithecia))),(Leontopithecus_rosalia,((Saguinus_oedipus,Callithrix_pygmaea),Aotus_nancymaae))),(Aotus_lemurinus,Aotus_azarai))),(((Otolemur_crassicaudatus,Otolemur_garnettii),Tarsius_bancanus),((Daubentonia_madagascariensis,(((((Eulemur_rufus,((((Varecia_variegata,Varecia_rubra),(Lemur_catta,(Nycticebus_pygmaeus,Hapalemur_griseus))),(Eulemur_fulvus,((((Megaladapis_edwardsi,Cheirogaleus_medius),Eulemur_rubriventer),Eulemur_macaco),Eulemur_mongoz))),Prolemur_simus)),Palaeopropithecus_ingens),(Avahi_laniger,(Indri_indri,(Lepilemur_hubbardorum,Lepilemur_ruficaudatus)))),(Propithecus_coquereli,Propithecus_verreauxi)),((Galago_senegalensis,Galago_moholi),(Perodicticus_potto,(((Nycticebus_bengalensis,Nycticebus_coucang),(Galagoides_demidoff,(Loris_tardigradus,Loris_lydekkerianus))),Perodicticus_potto_edwarsi))))),(Tarsius_syrichta,(Tarsius_wallacei,(Tarsius_dentatus,Tarsius_lariang)))))))))),Gorilla_gorilla_gorilla)))))),Homo_sapiens); +((Pan_troglodytes_ellioti,((Pan_paniscus,Pan_troglodytes_troglodytes),Pan_troglodytes)),(((Hylobates_moloch,(Hylobates_lar,((Hylobates_agilis,Symphalangus_syndactylus),((Pongo_abelii,Pongo_pygmaeus),(((Rhinopithecus_roxellana,((((Pygathrix_nemaeus,Pygathrix_nigripes),(Simias_concolor,Nasalis_larvatus)),(((Trachypithecus_pileatus,(((Trachypithecus_johnii,(Trachypithecus_francoisi,Trachypithecus_obscurus)),Semnopithecus_entellus),Trachypithecus_cristatus)),((Procolobus_verus,Piliocolobus_badius),(Rhinopithecus_avunculus,Presbytis_melalophos))),(Rhinopithecus_brelichi,(Colobus_satanas,Colobus_guereza)))),Rhinopithecus_bieti_2_RL2012)),(((((Papio_hamadryas,(Papio_ursinus,Papio_anubis)),((Papio_papio,Papio_cynocephalus),Papio_kindae)),Lophocebus_aterrimus),((Theropithecus_gelada,Lophocebus_albigena),Rungwecebus_kipunji)),(((((Macaca_silenus,(Macaca_assamensis,Macaca_thibetana)),((Macaca_nigra,(Macaca_mulatta,Macaca_fuscata)),Macaca_nemestrina)),((Macaca_tonkeana,Macaca_fascicularis),Macaca_arctoides)),Macaca_sylvanus),(((Cercocebus_chrysogaster,Mandrillus_leucophaeus),Cercocebus_agilis),((Mandrillus_sphinx,(((Cercopithecus_albogularis_kolbi,((Miopithecus_ogouensis,(Miopithecus_talapoin,Cercopithecus_diana)),Cercopithecus_mitis_stuhlmanni)),((((((Cercopithecus_kandti,(Cercopithecus_mitis_opisthostictus,(Cercopithecus_mitis,Cercopithecus_nictitans))),(((((((Allenopithecus_nigroviridis,Chlorocebus_pygerythrus),(Cercopithecus_dryas,((Cercopithecus_aethiops,Cercopithecus_solatus),Chlorocebus_sabaeus))),Cercopithecus_hamlyni),Chlorocebus_cynosuros),Chlorocebus_aethiops),Chlorocebus_tantalus),Cercopithecus_doggetti)),Cercopithecus_mitis_heymansi),Cercopithecus_mitis_mitis),(Cercopithecus_nictitans_nictitans,Cercopithecus_albogularis_francescae)),(Cercopithecus_albogularis,(((Cercopithecus_albogularis_moloneyi,Cercopithecus_mitis_boutourlinii),(Cercopithecus_albogularis_erythrarchus,Cercopithecus_albogularis_monoides)),(((((((((Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans),Cercopithecus_pogonias_nigripes),Cercopithecus_pogonias_grayi),(Cercopithecus_neglectus,Cercopithecus_pogonias_schwarzianus)),(Cercopithecus_pogonias,(Cercopithecus_nictitans_martini,(((Cercopithecus_ascanius_schmidti,((((((Cercopithecus_petaurista_petaurista,(Cercopithecus_petaurista_buettikoferi,Cercopithecus_erythrogaster_pococki)),Cercopithecus_erythrogaster),Cercopithecus_ascanius_katangae),(Cercopithecus_petaurista,Cercopithecus_cephus_cephus)),Cercopithecus_erythrotis_camerunensis),((Cercopithecus_preussi_preussi,Cercopithecus_preussi_insularis),Cercopithecus_lhoesti))),Cercopithecus_ascanius_whitesidei),(Cercopithecus_mona,Cercopithecus_campbelli))))),Cercopithecus_albogularis_labiatus),(Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis)),Cercopithecus_albogularis_albotorquatus),Cercopithecus_roloway))))),Erythrocebus_patas)),(Cercocebus_torquatus,Cercocebus_atys)))))),((((((Saguinus_oedipus,(Callithrix_pygmaea,Aotus_nancymaae)),(Aotus_lemurinus,Aotus_azarai)),(((((((Saimiri_oerstedii_citrinellus,(Saimiri_sciureus_macrodon,(Saimiri_sciureus,(Saimiri_boliviensis,Saimiri_oerstedii)))),Pithecia_pithecia),(Cacajao_calvus,(Aotus_azarae_azarai,(Chiropotes_albinasus,(Aotus_azarae,Chiropotes_israelita))))),(Sapajus_xanthosternos,(Cebus_albifrons,Cebus_apella))),(Callicebus_lugens,((((Brachyteles_arachnoides,((Callithrix_jacchus,Ateles_geoffroyi),(Ateles_paniscus,Callimico_goeldii))),Callicebus_donacophilus),Callicebus_cupreus),Ateles_belzebuth))),Lagothrix_lagotricha),Aotus_trivirgatus)),Leontopithecus_rosalia),Alouatta_caraya),(Tarsius_bancanus,((((((Perodicticus_potto_edwarsi,Perodicticus_potto),(((Otolemur_garnettii,((Galago_senegalensis,Galago_moholi),Galagoides_demidoff)),Otolemur_crassicaudatus),(Loris_tardigradus,Loris_lydekkerianus))),(Nycticebus_bengalensis,Nycticebus_coucang)),(((Eulemur_rubriventer,Eulemur_macaco),Megaladapis_edwardsi),((((Prolemur_simus,Cheirogaleus_medius),((Eulemur_fulvus,(Eulemur_rufus,((Avahi_laniger,((Propithecus_coquereli,Indri_indri),Lemur_catta)),(Propithecus_verreauxi,((Lepilemur_hubbardorum,Lepilemur_ruficaudatus),Palaeopropithecus_ingens))))),Eulemur_mongoz)),(Nycticebus_pygmaeus,Hapalemur_griseus)),(Varecia_variegata,Varecia_rubra)))),Daubentonia_madagascariensis),(Tarsius_syrichta,(Tarsius_wallacei,(Tarsius_dentatus,Tarsius_lariang))))))))))),Nomascus_leucogenys),((Gorilla_gorilla,(Homo_sapiens_ssp_Denisova,Homo_heidelbergensis)),Gorilla_gorilla_gorilla)),Homo_sapiens); +((Pan_troglodytes_ellioti,Pan_troglodytes_troglodytes),(((Nomascus_leucogenys,((Pan_troglodytes,(Symphalangus_syndactylus,Hylobates_agilis)),(Hylobates_moloch,Pan_paniscus))),Hylobates_lar),(((Homo_heidelbergensis,Gorilla_gorilla),Homo_sapiens_ssp_Denisova),(Gorilla_gorilla_gorilla,((Pongo_abelii,Pongo_pygmaeus),((((((Trachypithecus_pileatus,(Trachypithecus_obscurus,(((((Presbytis_melalophos,((Piliocolobus_badius,Semnopithecus_entellus),Trachypithecus_francoisi)),Trachypithecus_cristatus),Procolobus_verus),Trachypithecus_johnii),Rhinopithecus_avunculus))),(Colobus_satanas,Colobus_guereza)),(Rhinopithecus_roxellana,Nasalis_larvatus)),(Rhinopithecus_bieti_2_RL2012,(((Simias_concolor,Pygathrix_nigripes),Pygathrix_nemaeus),Rhinopithecus_brelichi))),(((((Cercocebus_torquatus,Cercocebus_atys),(((((((Macaca_nigra,Macaca_mulatta),Macaca_fuscata),Macaca_nemestrina),(Macaca_assamensis,Macaca_thibetana)),(Macaca_sylvanus,(Macaca_fascicularis,Macaca_silenus))),(Macaca_tonkeana,Macaca_arctoides)),((Papio_cynocephalus,Papio_kindae),(((Theropithecus_gelada,Rungwecebus_kipunji),(Lophocebus_aterrimus,(Lophocebus_albigena,Papio_ursinus))),(Papio_papio,(Papio_hamadryas,Papio_anubis)))))),(Cercocebus_chrysogaster,Mandrillus_leucophaeus)),Cercocebus_agilis),(((Erythrocebus_patas,Cercopithecus_diana),((Cercopithecus_mitis_stuhlmanni,Cercopithecus_albogularis_kolbi),(Cercopithecus_albogularis,(((Allenopithecus_nigroviridis,Cercopithecus_roloway),((((Chlorocebus_aethiops,Cercopithecus_hamlyni),(Chlorocebus_sabaeus,((Cercopithecus_aethiops,Cercopithecus_solatus),Cercopithecus_dryas))),(Chlorocebus_pygerythrus,Chlorocebus_tantalus)),Chlorocebus_cynosuros)),((((Cercopithecus_mitis_boutourlinii,Cercopithecus_nictitans_nictitans),(Cercopithecus_mitis_mitis,(Cercopithecus_mitis_opisthostictus,(Cercopithecus_albogularis_erythrarchus,Cercopithecus_albogularis_labiatus)))),((Cercopithecus_nictitans,Cercopithecus_albogularis_monoides),((Cercopithecus_albogularis_moloneyi,Cercopithecus_albogularis_albotorquatus),((Cercopithecus_ascanius_schmidti,(Cercopithecus_ascanius_whitesidei,(Cercopithecus_nictitans_martini,(Cercopithecus_lhoesti,((Cercopithecus_erythrotis_camerunensis,(Cercopithecus_ascanius_katangae,(Cercopithecus_erythrogaster_pococki,((((Cercopithecus_petaurista_buettikoferi,Cercopithecus_petaurista_petaurista),Cercopithecus_erythrogaster),Cercopithecus_petaurista),Cercopithecus_cephus_cephus)))),(Cercopithecus_preussi_preussi,((Cercopithecus_mona,Cercopithecus_campbelli),Cercopithecus_preussi_insularis))))))),((Cercopithecus_neglectus,(Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis)),((Cercopithecus_pogonias_schwarzianus,(((Cercopithecus_wolfi_elegans,Cercopithecus_pogonias_nigripes),Cercopithecus_wolfi_pyrogaster),Cercopithecus_pogonias_grayi)),Cercopithecus_pogonias)))))),(((Cercopithecus_kandti,Cercopithecus_doggetti),(Cercopithecus_mitis_heymansi,Cercopithecus_albogularis_francescae)),Cercopithecus_mitis)))))),(Miopithecus_talapoin,(Miopithecus_ogouensis,Mandrillus_sphinx))))),(((((Callicebus_lugens,((Callicebus_donacophilus,(Brachyteles_arachnoides,((((Ateles_belzebuth,Callithrix_jacchus),Ateles_geoffroyi),Callimico_goeldii),Ateles_paniscus))),Callicebus_cupreus)),(((Saguinus_oedipus,Callithrix_pygmaea),((Aotus_azarae,(Aotus_lemurinus,Aotus_azarai)),Aotus_azarae_azarai)),(Cebus_albifrons,(Sapajus_xanthosternos,((Cacajao_calvus,(Pithecia_pithecia,((Cebus_apella,Chiropotes_israelita),Chiropotes_albinasus))),(Lagothrix_lagotricha,(Saimiri_oerstedii_citrinellus,(Saimiri_sciureus_macrodon,((Saimiri_sciureus,Saimiri_oerstedii),Saimiri_boliviensis))))))))),(Aotus_trivirgatus,(Aotus_nancymaae,Leontopithecus_rosalia))),Alouatta_caraya),((((((Perodicticus_potto_edwarsi,Perodicticus_potto),((Otolemur_garnettii,(((Galago_senegalensis,Otolemur_crassicaudatus),Galago_moholi),Galagoides_demidoff)),((Nycticebus_bengalensis,Nycticebus_coucang),(Loris_tardigradus,Loris_lydekkerianus)))),((Lemur_catta,Megaladapis_edwardsi),((Prolemur_simus,((Eulemur_mongoz,Eulemur_rufus),(Nycticebus_pygmaeus,Hapalemur_griseus))),(Eulemur_fulvus,(Eulemur_macaco,((Varecia_variegata,Varecia_rubra),((Cheirogaleus_medius,(Palaeopropithecus_ingens,(Avahi_laniger,(((Propithecus_coquereli,Indri_indri),Propithecus_verreauxi),(Lepilemur_hubbardorum,Lepilemur_ruficaudatus))))),Eulemur_rubriventer))))))),Daubentonia_madagascariensis),(Tarsius_syrichta,(Tarsius_lariang,(Tarsius_wallacei,Tarsius_dentatus)))),Tarsius_bancanus))))))),Homo_sapiens); +((Pan_troglodytes_troglodytes,((Pan_paniscus,(((((((Pygathrix_nemaeus,Trachypithecus_pileatus),((((Rhinopithecus_brelichi,((Nasalis_larvatus,((Trachypithecus_obscurus,(Rhinopithecus_bieti_2_RL2012,Trachypithecus_francoisi)),Trachypithecus_johnii)),Simias_concolor)),Rhinopithecus_roxellana),Trachypithecus_cristatus),Pygathrix_nigripes)),(Semnopithecus_entellus,(Rhinopithecus_avunculus,Presbytis_melalophos))),((Procolobus_verus,(Colobus_satanas,Colobus_guereza)),Piliocolobus_badius)),((((((Mandrillus_sphinx,(Cercocebus_torquatus,Cercocebus_atys)),((Theropithecus_gelada,(Rungwecebus_kipunji,((Papio_anubis,(Papio_ursinus,(Lophocebus_albigena,Lophocebus_aterrimus))),Papio_hamadryas))),(Papio_kindae,(Papio_papio,Papio_cynocephalus)))),(((Macaca_arctoides,((Macaca_nigra,Macaca_fuscata),Macaca_nemestrina)),(Macaca_assamensis,Macaca_thibetana)),(Macaca_sylvanus,(Macaca_fascicularis,(Macaca_tonkeana,Macaca_silenus))))),Macaca_mulatta),(Cercocebus_agilis,(Cercocebus_chrysogaster,Mandrillus_leucophaeus))),((((((((Cercopithecus_cephus_ngottoensis,((((Cercopithecus_cephus_cephus,(Cercopithecus_ascanius_katangae,((Cercopithecus_preussi_insularis,(Cercopithecus_preussi_preussi,Cercopithecus_lhoesti)),((((Cercopithecus_erythrogaster_pococki,(Cercopithecus_petaurista,Cercopithecus_erythrogaster)),(Cercopithecus_petaurista_buettikoferi,Cercopithecus_petaurista_petaurista)),Cercopithecus_ascanius_whitesidei),Cercopithecus_erythrotis_camerunensis)))),Cercopithecus_neglectus),Cercopithecus_ascanius_schmidti),(Allenopithecus_nigroviridis,(((Cercopithecus_pogonias_schwarzianus,Cercopithecus_pogonias_nigripes),(Cercopithecus_pogonias,((Cercopithecus_wolfi_elegans,Cercopithecus_wolfi_pyrogaster),Cercopithecus_nictitans_martini))),Cercopithecus_pogonias_grayi)))),(((Cercopithecus_mona,Cercopithecus_campbelli),Cercopithecus_nictitans),Cercopithecus_diana)),(Erythrocebus_patas,Cercopithecus_roloway)),Cercopithecus_albogularis),((Cercopithecus_mitis,(Cercopithecus_kandti,((Cercopithecus_mitis_stuhlmanni,Cercopithecus_albogularis_kolbi),(((Cercopithecus_nictitans_nictitans,((Cercopithecus_albogularis_albotorquatus,(((Cercopithecus_mitis_opisthostictus,Cercopithecus_albogularis_monoides),Cercopithecus_albogularis_erythrarchus),Cercopithecus_mitis_boutourlinii)),(Cercopithecus_albogularis_labiatus,Cercopithecus_mitis_mitis))),Cercopithecus_albogularis_moloneyi),Cercopithecus_doggetti)))),(Cercopithecus_mitis_heymansi,Cercopithecus_albogularis_francescae))),Cercopithecus_cephus),((((Chlorocebus_sabaeus,Cercopithecus_aethiops),(Chlorocebus_pygerythrus,((Chlorocebus_tantalus,Cercopithecus_solatus),(Chlorocebus_cynosuros,Chlorocebus_aethiops)))),Cercopithecus_dryas),Miopithecus_talapoin)),(Cercopithecus_hamlyni,Miopithecus_ogouensis)))),((Homo_sapiens_ssp_Denisova,((Brachyteles_arachnoides,(((((Callicebus_donacophilus,((((Aotus_nancymaae,(Callimico_goeldii,Leontopithecus_rosalia)),((((Saimiri_oerstedii,Saimiri_sciureus),Saimiri_boliviensis),Saimiri_sciureus_macrodon),Saimiri_oerstedii_citrinellus)),((Ateles_geoffroyi,(Callicebus_cupreus,Callicebus_lugens)),((((((((Aotus_azarae_azarai,(Aotus_lemurinus,Aotus_azarai)),Aotus_azarae),Aotus_trivirgatus),Ateles_paniscus),Saguinus_oedipus),(Callithrix_pygmaea,Callithrix_jacchus)),Pithecia_pithecia),Lagothrix_lagotricha))),(Cebus_albifrons,(Cebus_apella,Sapajus_xanthosternos)))),Cacajao_calvus),Ateles_belzebuth),Chiropotes_israelita),Chiropotes_albinasus)),Alouatta_caraya)),(Tarsius_bancanus,((((((Otolemur_crassicaudatus,(Galago_senegalensis,Otolemur_garnettii)),Galago_moholi),(((Perodicticus_potto_edwarsi,Perodicticus_potto),(Nycticebus_pygmaeus,(Nycticebus_bengalensis,Nycticebus_coucang))),(Galagoides_demidoff,(Loris_tardigradus,Loris_lydekkerianus)))),(((Propithecus_verreauxi,Propithecus_coquereli),(((Eulemur_rubriventer,Megaladapis_edwardsi),(Eulemur_rufus,((Varecia_variegata,Varecia_rubra),(((Eulemur_macaco,(Eulemur_mongoz,(Eulemur_fulvus,(Cheirogaleus_medius,Hapalemur_griseus)))),Lemur_catta),Prolemur_simus)))),Palaeopropithecus_ingens)),(Avahi_laniger,(Indri_indri,(Lepilemur_hubbardorum,Lepilemur_ruficaudatus))))),Daubentonia_madagascariensis),(Tarsius_syrichta,((Tarsius_wallacei,Tarsius_dentatus),Tarsius_lariang)))))),(((Hylobates_agilis,(Nomascus_leucogenys,Hylobates_moloch)),Symphalangus_syndactylus),((Pongo_pygmaeus,Hylobates_lar),Pongo_abelii)))),Gorilla_gorilla_gorilla)),(((Pan_troglodytes_ellioti,Homo_heidelbergensis),Pan_troglodytes),Gorilla_gorilla),Homo_sapiens); +(((((((Hylobates_moloch,Nomascus_leucogenys),((((Pongo_abelii,Symphalangus_syndactylus),(Homo_sapiens_ssp_Denisova,Hylobates_agilis)),Hylobates_lar),Pongo_pygmaeus)),(((((((Saguinus_oedipus,Callithrix_pygmaea),((Aotus_nancymaae,Leontopithecus_rosalia),(Saimiri_oerstedii_citrinellus,((Saimiri_sciureus,(Saimiri_oerstedii,Saimiri_boliviensis)),Saimiri_sciureus_macrodon)))),((((((Ateles_belzebuth,Callicebus_cupreus),Callicebus_lugens),((Aotus_azarae,(Aotus_lemurinus,Aotus_azarai)),Ateles_geoffroyi)),Callicebus_donacophilus),Ateles_paniscus),Cebus_apella)),((Aotus_trivirgatus,(Pithecia_pithecia,(((Lagothrix_lagotricha,((Cacajao_calvus,(Chiropotes_albinasus,Brachyteles_arachnoides)),Chiropotes_israelita)),Callimico_goeldii),Aotus_azarae_azarai))),Callithrix_jacchus)),(Cebus_albifrons,Sapajus_xanthosternos)),Alouatta_caraya),((((Colobus_guereza,((Procolobus_verus,(Pygathrix_nigripes,(Rhinopithecus_bieti_2_RL2012,((Rhinopithecus_brelichi,((Colobus_satanas,(Pygathrix_nemaeus,((Trachypithecus_cristatus,(Rhinopithecus_avunculus,(Nasalis_larvatus,((Trachypithecus_obscurus,Trachypithecus_francoisi),Simias_concolor)))),Rhinopithecus_roxellana))),Trachypithecus_pileatus)),Trachypithecus_johnii)))),Presbytis_melalophos)),Piliocolobus_badius),(Semnopithecus_entellus,(((((Macaca_silenus,Macaca_tonkeana),((Macaca_sylvanus,Macaca_fascicularis),(((Macaca_nigra,Macaca_nemestrina),(Macaca_fuscata,Macaca_arctoides)),(Macaca_assamensis,Macaca_thibetana)))),Macaca_mulatta),(((((Papio_papio,Rungwecebus_kipunji),((Papio_anubis,Papio_cynocephalus),Papio_ursinus)),Papio_hamadryas),Papio_kindae),((((Cercocebus_agilis,(Mandrillus_sphinx,(Cercocebus_chrysogaster,(Cercocebus_torquatus,Cercocebus_atys)))),Mandrillus_leucophaeus),(Lophocebus_albigena,Lophocebus_aterrimus)),Theropithecus_gelada))),(((((((((((Cercopithecus_neglectus,Cercopithecus_wolfi_pyrogaster),Cercopithecus_pogonias_schwarzianus),((Cercopithecus_wolfi_elegans,Cercopithecus_pogonias_grayi),Cercopithecus_pogonias_nigripes)),(Miopithecus_ogouensis,(Cercopithecus_mona,Cercopithecus_campbelli))),Cercopithecus_pogonias),(Cercopithecus_nictitans,(((Chlorocebus_tantalus,(Cercopithecus_solatus,(Cercopithecus_hamlyni,Cercopithecus_aethiops))),(((Chlorocebus_sabaeus,Chlorocebus_cynosuros),Chlorocebus_pygerythrus),Chlorocebus_aethiops)),Cercopithecus_dryas))),Miopithecus_talapoin),Cercopithecus_diana),(Cercopithecus_roloway,(Erythrocebus_patas,Allenopithecus_nigroviridis))),((Cercopithecus_nictitans_martini,((Cercopithecus_erythrogaster,(((Cercopithecus_lhoesti,(Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi)),(((Cercopithecus_ascanius_whitesidei,Cercopithecus_cephus_cephus),Cercopithecus_ascanius_katangae),((Cercopithecus_petaurista_petaurista,(Cercopithecus_petaurista_buettikoferi,Cercopithecus_erythrogaster_pococki)),Cercopithecus_erythrotis_camerunensis))),Cercopithecus_ascanius_schmidti)),(((Cercopithecus_nictitans_nictitans,(Cercopithecus_mitis,(Cercopithecus_doggetti,((Cercopithecus_albogularis_francescae,Cercopithecus_kandti),(((Cercopithecus_mitis_heymansi,Cercopithecus_albogularis_kolbi),(Cercopithecus_mitis_mitis,((Cercopithecus_albogularis_labiatus,(Cercopithecus_albogularis_monoides,((Cercopithecus_mitis_boutourlinii,Cercopithecus_albogularis_erythrarchus),Cercopithecus_albogularis_albotorquatus))),Cercopithecus_mitis_opisthostictus))),Cercopithecus_mitis_stuhlmanni))))),Cercopithecus_albogularis),Cercopithecus_albogularis_moloneyi))),Cercopithecus_petaurista)),(Cercopithecus_cephus_ngottoensis,Cercopithecus_cephus))))),(((((Avahi_laniger,((Propithecus_coquereli,(Indri_indri,Eulemur_macaco)),Eulemur_fulvus)),((Propithecus_verreauxi,((Eulemur_rubriventer,((Varecia_variegata,Varecia_rubra),((Lepilemur_hubbardorum,Lepilemur_ruficaudatus),Eulemur_rufus))),Palaeopropithecus_ingens)),((Hapalemur_griseus,(Eulemur_mongoz,Prolemur_simus)),(Lemur_catta,(Cheirogaleus_medius,Megaladapis_edwardsi))))),(Daubentonia_madagascariensis,(Galago_moholi,(Perodicticus_potto_edwarsi,((Otolemur_crassicaudatus,((Otolemur_garnettii,((Loris_lydekkerianus,(Galagoides_demidoff,Loris_tardigradus)),(Nycticebus_pygmaeus,(Nycticebus_bengalensis,Nycticebus_coucang)))),Galago_senegalensis)),Perodicticus_potto))))),(Tarsius_syrichta,((Tarsius_wallacei,Tarsius_dentatus),Tarsius_lariang))),Tarsius_bancanus)))),Gorilla_gorilla),Gorilla_gorilla_gorilla),Homo_heidelbergensis),(((Pan_troglodytes,Pan_troglodytes_troglodytes),Pan_paniscus),Pan_troglodytes_ellioti),Homo_sapiens); +((Pan_troglodytes_ellioti,((Homo_heidelbergensis,((Pongo_pygmaeus,Pongo_abelii),(((Hylobates_agilis,Symphalangus_syndactylus),Nomascus_leucogenys),(Hylobates_moloch,Hylobates_lar)))),(((Gorilla_gorilla_gorilla,((((((Piliocolobus_badius,(Procolobus_verus,Rhinopithecus_avunculus)),((Colobus_guereza,Colobus_satanas),(((Trachypithecus_pileatus,(Trachypithecus_cristatus,(Trachypithecus_francoisi,Trachypithecus_obscurus))),Trachypithecus_johnii),(((Pygathrix_nigripes,Pygathrix_nemaeus),(Nasalis_larvatus,Simias_concolor)),((Rhinopithecus_bieti_2_RL2012,Rhinopithecus_brelichi),Rhinopithecus_roxellana))))),Presbytis_melalophos),Semnopithecus_entellus),(Miopithecus_ogouensis,((Miopithecus_talapoin,(Cercopithecus_diana,(Cercopithecus_roloway,(((((Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi),Cercopithecus_lhoesti),((Cercopithecus_ascanius_schmidti,Cercopithecus_ascanius_whitesidei),(Cercopithecus_erythrotis_camerunensis,((Cercopithecus_erythrogaster,(Cercopithecus_petaurista,((Cercopithecus_petaurista_buettikoferi,Cercopithecus_erythrogaster_pococki),Cercopithecus_petaurista_petaurista))),(Cercopithecus_cephus_cephus,Cercopithecus_ascanius_katangae))))),((Cercopithecus_cephus_ngottoensis,Cercopithecus_cephus),((Cercopithecus_nictitans_nictitans,Cercopithecus_albogularis_francescae),((Cercopithecus_campbelli,Cercopithecus_mona),(Cercopithecus_neglectus,(((Cercopithecus_nictitans_martini,(Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans)),(Cercopithecus_pogonias_nigripes,(Cercopithecus_pogonias_schwarzianus,Cercopithecus_pogonias))),Cercopithecus_pogonias_grayi)))))),((((Cercopithecus_albogularis_monoides,Cercopithecus_albogularis),(((Cercopithecus_albogularis_erythrarchus,Cercopithecus_albogularis_labiatus),Cercopithecus_albogularis_albotorquatus),Cercopithecus_mitis_boutourlinii)),Cercopithecus_albogularis_moloneyi),(((Cercopithecus_nictitans,((Allenopithecus_nigroviridis,Erythrocebus_patas),(((Chlorocebus_aethiops,Cercopithecus_hamlyni),((Chlorocebus_pygerythrus,((Cercopithecus_aethiops,Chlorocebus_sabaeus),(Cercopithecus_dryas,Cercopithecus_solatus))),Chlorocebus_cynosuros)),Chlorocebus_tantalus))),(Cercopithecus_mitis_mitis,Cercopithecus_mitis_opisthostictus)),(Cercopithecus_mitis,((Cercopithecus_mitis_heymansi,(Cercopithecus_mitis_stuhlmanni,Cercopithecus_albogularis_kolbi)),(Cercopithecus_doggetti,Cercopithecus_kandti))))))))),((((Macaca_mulatta,Macaca_fascicularis),((((Macaca_nigra,Macaca_fuscata),Macaca_nemestrina),Macaca_tonkeana),((Macaca_assamensis,Macaca_thibetana),Macaca_silenus))),Macaca_arctoides),(((((Cercocebus_torquatus,(Macaca_sylvanus,(Cercocebus_atys,Cercocebus_chrysogaster))),Mandrillus_leucophaeus),Cercocebus_agilis),Mandrillus_sphinx),(((Lophocebus_albigena,Lophocebus_aterrimus),Theropithecus_gelada),((Papio_kindae,(Papio_papio,(((Papio_cynocephalus,Papio_ursinus),Papio_anubis),Papio_hamadryas))),Rungwecebus_kipunji))))))),((Alouatta_caraya,((Saguinus_oedipus,Callithrix_pygmaea),(((Cebus_albifrons,(Sapajus_xanthosternos,Cebus_apella)),(((Chiropotes_albinasus,Chiropotes_israelita),Cacajao_calvus),(((Callicebus_lugens,(Callicebus_cupreus,((Callicebus_donacophilus,((Ateles_paniscus,((Ateles_geoffroyi,Callimico_goeldii),Ateles_belzebuth)),Callithrix_jacchus)),Brachyteles_arachnoides))),Lagothrix_lagotricha),Pithecia_pithecia))),(((Saimiri_oerstedii_citrinellus,((Saimiri_sciureus,(Saimiri_oerstedii,Saimiri_boliviensis)),Saimiri_sciureus_macrodon)),(Leontopithecus_rosalia,Aotus_nancymaae)),(((Aotus_trivirgatus,Aotus_azarae_azarai),(Aotus_azarai,Aotus_lemurinus)),Aotus_azarae))))),((((Eulemur_rubriventer,(Eulemur_mongoz,Eulemur_fulvus)),Eulemur_macaco),(((Galagoides_demidoff,(Otolemur_garnettii,Galago_senegalensis)),Otolemur_crassicaudatus),((Propithecus_verreauxi,(Lepilemur_ruficaudatus,Lepilemur_hubbardorum)),Loris_tardigradus))),(Tarsius_bancanus,((((Palaeopropithecus_ingens,(Indri_indri,(((Lemur_catta,(Cheirogaleus_medius,(Prolemur_simus,(Nycticebus_pygmaeus,Hapalemur_griseus)))),(Varecia_variegata,Varecia_rubra)),Eulemur_rufus))),((Galago_moholi,(Perodicticus_potto_edwarsi,(Perodicticus_potto,(Loris_lydekkerianus,(Nycticebus_coucang,Nycticebus_bengalensis))))),((Tarsius_dentatus,Tarsius_wallacei),(Tarsius_lariang,Tarsius_syrichta)))),(Avahi_laniger,(Propithecus_coquereli,Megaladapis_edwardsi))),Daubentonia_madagascariensis)))))),Gorilla_gorilla),Homo_sapiens_ssp_Denisova))),(Pan_troglodytes_troglodytes,(Pan_troglodytes,Pan_paniscus)),Homo_sapiens); +(((((((((Pygathrix_nemaeus,(Trachypithecus_pileatus,((((((((Rhinopithecus_bieti_2_RL2012,(Nasalis_larvatus,((Semnopithecus_entellus,Trachypithecus_francoisi),Trachypithecus_cristatus))),Trachypithecus_johnii),(Pygathrix_nigripes,Rhinopithecus_roxellana)),Trachypithecus_obscurus),Rhinopithecus_brelichi),Presbytis_melalophos),(Simias_concolor,Rhinopithecus_avunculus)),((Piliocolobus_badius,(Colobus_guereza,Procolobus_verus)),Colobus_satanas)))),(Miopithecus_ogouensis,((Miopithecus_talapoin,(Cercopithecus_diana,((Cercopithecus_albogularis,(((((Cercopithecus_neglectus,Cercopithecus_cephus),Cercopithecus_cephus_ngottoensis),(Cercopithecus_ascanius_katangae,((Cercopithecus_cephus_cephus,Cercopithecus_ascanius_schmidti),(((Cercopithecus_petaurista,((Cercopithecus_petaurista_buettikoferi,Cercopithecus_petaurista_petaurista),Cercopithecus_erythrogaster)),Cercopithecus_erythrotis_camerunensis),Cercopithecus_ascanius_whitesidei)))),(((Cercopithecus_pogonias_grayi,(((Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans),Cercopithecus_nictitans_martini),((Cercopithecus_pogonias,Cercopithecus_pogonias_schwarzianus),Cercopithecus_pogonias_nigripes))),(Cercopithecus_campbelli,Cercopithecus_mona)),Cercopithecus_albogularis_labiatus)),((((Cercopithecus_doggetti,(((Erythrocebus_patas,Cercopithecus_mitis_stuhlmanni),(Cercopithecus_kandti,(Cercopithecus_erythrogaster_pococki,Cercopithecus_nictitans_nictitans))),(Cercopithecus_nictitans,((Cercopithecus_mitis_heymansi,(Allenopithecus_nigroviridis,((((Chlorocebus_aethiops,(Chlorocebus_pygerythrus,((Cercopithecus_solatus,Cercopithecus_dryas),(Chlorocebus_sabaeus,Cercopithecus_aethiops)))),Chlorocebus_cynosuros),Chlorocebus_tantalus),Cercopithecus_hamlyni))),Cercopithecus_albogularis_francescae)))),((Cercopithecus_mitis_opisthostictus,Cercopithecus_albogularis_kolbi),Cercopithecus_mitis_mitis)),Cercopithecus_mitis),(Cercopithecus_albogularis_monoides,(Cercopithecus_albogularis_erythrarchus,(Cercopithecus_albogularis_albotorquatus,(Cercopithecus_albogularis_moloneyi,Cercopithecus_mitis_boutourlinii))))))),(((Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi),Cercopithecus_lhoesti),Cercopithecus_roloway)))),((((((Macaca_assamensis,Macaca_thibetana),((Macaca_nigra,(Macaca_mulatta,Macaca_fuscata)),Macaca_nemestrina)),Macaca_tonkeana),(Macaca_silenus,Macaca_fascicularis)),Macaca_arctoides),(((((Papio_papio,Papio_cynocephalus),Papio_kindae),(((Papio_hamadryas,(Papio_anubis,Rungwecebus_kipunji)),Papio_ursinus),Lophocebus_albigena)),(Lophocebus_aterrimus,Theropithecus_gelada)),(((Cercocebus_torquatus,Cercocebus_atys),Mandrillus_sphinx),(Macaca_sylvanus,((Cercocebus_agilis,Cercocebus_chrysogaster),Mandrillus_leucophaeus)))))))),((Alouatta_caraya,((Saguinus_oedipus,Callithrix_pygmaea),((((Callicebus_lugens,(((Callicebus_donacophilus,Brachyteles_arachnoides),(((Ateles_paniscus,(Ateles_geoffroyi,Ateles_belzebuth)),Callithrix_jacchus),Callimico_goeldii)),Callicebus_cupreus)),(((Aotus_azarae,(((Aotus_lemurinus,Aotus_azarai),Aotus_azarae_azarai),Aotus_trivirgatus)),(Saimiri_sciureus_macrodon,(Saimiri_oerstedii_citrinellus,(Saimiri_boliviensis,(Saimiri_oerstedii,Saimiri_sciureus))))),(Aotus_nancymaae,Leontopithecus_rosalia))),(Cebus_albifrons,(Sapajus_xanthosternos,Cebus_apella))),((Lagothrix_lagotricha,(Pithecia_pithecia,(Chiropotes_israelita,Chiropotes_albinasus))),Cacajao_calvus)))),(Otolemur_crassicaudatus,((Otolemur_garnettii,((Loris_tardigradus,Galagoides_demidoff),(Galago_senegalensis,(Propithecus_verreauxi,(Lepilemur_ruficaudatus,Lepilemur_hubbardorum))))),(((((Eulemur_rubriventer,Eulemur_macaco),(Eulemur_mongoz,Eulemur_fulvus)),(Tarsius_syrichta,(Tarsius_lariang,(Tarsius_wallacei,Tarsius_dentatus)))),Tarsius_bancanus),(((((Palaeopropithecus_ingens,((Megaladapis_edwardsi,(Lemur_catta,(Prolemur_simus,((Cheirogaleus_medius,(Varecia_variegata,Varecia_rubra)),Hapalemur_griseus)))),Eulemur_rufus)),(Indri_indri,Propithecus_coquereli)),(Galago_moholi,((Loris_lydekkerianus,(Nycticebus_pygmaeus,(Nycticebus_coucang,Nycticebus_bengalensis))),(Perodicticus_potto_edwarsi,Perodicticus_potto)))),Daubentonia_madagascariensis),Avahi_laniger)))))),Gorilla_gorilla),Gorilla_gorilla_gorilla),((Pongo_pygmaeus,Pongo_abelii),((Nomascus_leucogenys,(Hylobates_agilis,(Hylobates_lar,Symphalangus_syndactylus))),Hylobates_moloch))),Homo_heidelbergensis),Homo_sapiens_ssp_Denisova),((Pan_troglodytes_ellioti,(Pan_paniscus,Pan_troglodytes)),Pan_troglodytes_troglodytes),Homo_sapiens); +((((((((Cacajao_calvus,((Callicebus_donacophilus,(Ateles_paniscus,(Brachyteles_arachnoides,Chiropotes_israelita))),Chiropotes_albinasus)),(((Cebus_albifrons,(Sapajus_xanthosternos,Cebus_apella)),((((Callimico_goeldii,Alouatta_caraya),((Saguinus_oedipus,Callithrix_pygmaea),Callithrix_jacchus)),((((Aotus_azarae,(Aotus_azarai,Aotus_lemurinus)),Aotus_trivirgatus),Aotus_azarae_azarai),(((Saimiri_sciureus_macrodon,(Saimiri_oerstedii_citrinellus,Saimiri_boliviensis)),(Saimiri_sciureus,Saimiri_oerstedii)),(Aotus_nancymaae,Leontopithecus_rosalia)))),(Ateles_geoffroyi,(Lagothrix_lagotricha,((Ateles_belzebuth,Callicebus_cupreus),Callicebus_lugens))))),Pithecia_pithecia)),((((Presbytis_melalophos,Rhinopithecus_avunculus),((((Trachypithecus_cristatus,Trachypithecus_francoisi),(Trachypithecus_pileatus,Trachypithecus_obscurus)),(((Rhinopithecus_bieti_2_RL2012,Rhinopithecus_brelichi),Rhinopithecus_roxellana),((Pygathrix_nigripes,Pygathrix_nemaeus),((Trachypithecus_johnii,Semnopithecus_entellus),(Simias_concolor,Nasalis_larvatus))))),((Colobus_guereza,Colobus_satanas),(Piliocolobus_badius,Procolobus_verus)))),(((((Cercopithecus_diana,(((Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi),Cercopithecus_lhoesti),Cercopithecus_roloway)),((((((((Cercopithecus_albogularis,Cercopithecus_albogularis_monoides),(Cercopithecus_albogularis_erythrarchus,(Cercopithecus_mitis_boutourlinii,Cercopithecus_albogularis_albotorquatus))),((Cercopithecus_mitis,((Cercopithecus_kandti,Cercopithecus_mitis_stuhlmanni),((((Cercopithecus_mitis_heymansi,((((Chlorocebus_cynosuros,(Cercopithecus_solatus,Chlorocebus_tantalus)),((Chlorocebus_aethiops,Cercopithecus_hamlyni),Chlorocebus_pygerythrus)),(Chlorocebus_sabaeus,Cercopithecus_aethiops)),Cercopithecus_dryas)),Cercopithecus_albogularis_francescae),Cercopithecus_doggetti),Cercopithecus_albogularis_kolbi))),(((Cercopithecus_nictitans,(Erythrocebus_patas,Allenopithecus_nigroviridis)),(Cercopithecus_erythrogaster_pococki,Cercopithecus_mitis_mitis)),(Cercopithecus_nictitans_nictitans,Cercopithecus_mitis_opisthostictus)))),Cercopithecus_albogularis_moloneyi),(Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis)),((Cercopithecus_campbelli,Cercopithecus_mona),((Cercopithecus_pogonias_grayi,((Cercopithecus_nictitans_martini,(Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans)),(Cercopithecus_pogonias_schwarzianus,(Cercopithecus_pogonias,Cercopithecus_pogonias_nigripes)))),Cercopithecus_albogularis_labiatus))),((Cercopithecus_cephus_cephus,(Cercopithecus_erythrotis_camerunensis,Cercopithecus_ascanius_schmidti)),(Cercopithecus_ascanius_katangae,(((Cercopithecus_petaurista,Cercopithecus_erythrogaster),(Cercopithecus_petaurista_buettikoferi,Cercopithecus_petaurista_petaurista)),Cercopithecus_ascanius_whitesidei)))),Cercopithecus_neglectus)),(((((((Macaca_sylvanus,(Macaca_assamensis,Macaca_thibetana)),(Macaca_nigra,Macaca_nemestrina)),(Macaca_silenus,Macaca_tonkeana)),Macaca_fascicularis),Macaca_arctoides),(Macaca_mulatta,Macaca_fuscata)),((Theropithecus_gelada,((((((Papio_hamadryas,(Papio_anubis,Papio_cynocephalus)),Papio_ursinus),(Papio_kindae,Papio_papio)),Rungwecebus_kipunji),Lophocebus_albigena),Lophocebus_aterrimus)),((Cercocebus_chrysogaster,(Cercocebus_torquatus,(Cercocebus_atys,Mandrillus_sphinx))),(Mandrillus_leucophaeus,Cercocebus_agilis))))),Miopithecus_ogouensis),Miopithecus_talapoin)),(((((Galago_senegalensis,Otolemur_garnettii),(Loris_tardigradus,Galagoides_demidoff)),((((Galago_moholi,(((Nycticebus_pygmaeus,(Nycticebus_coucang,Nycticebus_bengalensis)),Loris_lydekkerianus),(Perodicticus_potto_edwarsi,Perodicticus_potto))),((((Hapalemur_griseus,(Lemur_catta,(Varecia_variegata,Varecia_rubra))),(Cheirogaleus_medius,Prolemur_simus)),(Eulemur_rufus,Palaeopropithecus_ingens)),(Indri_indri,Propithecus_coquereli))),(Daubentonia_madagascariensis,((((Eulemur_rubriventer,Eulemur_macaco),(Eulemur_mongoz,Eulemur_fulvus)),Megaladapis_edwardsi),Avahi_laniger))),(Tarsius_bancanus,(Tarsius_syrichta,(Tarsius_wallacei,(Tarsius_dentatus,Tarsius_lariang)))))),((Lepilemur_ruficaudatus,Lepilemur_hubbardorum),Propithecus_verreauxi)),Otolemur_crassicaudatus))),Gorilla_gorilla),Gorilla_gorilla_gorilla),(Nomascus_leucogenys,(Hylobates_moloch,((((Hylobates_lar,Pongo_abelii),Symphalangus_syndactylus),Hylobates_agilis),Pongo_pygmaeus)))),Homo_heidelbergensis),((Pan_troglodytes_ellioti,((Pan_paniscus,Pan_troglodytes),Pan_troglodytes_troglodytes)),Homo_sapiens_ssp_Denisova),Homo_sapiens); +(((((Gorilla_gorilla,(Homo_sapiens_ssp_Denisova,((((((((Cercocebus_chrysogaster,(Mandrillus_leucophaeus,((Macaca_sylvanus,Cercocebus_agilis),(((((Papio_kindae,Papio_cynocephalus),Papio_papio),(Papio_hamadryas,(Papio_ursinus,Papio_anubis))),Theropithecus_gelada),((Lophocebus_aterrimus,Lophocebus_albigena),Rungwecebus_kipunji))))),(Cercocebus_torquatus,(Cercocebus_atys,Mandrillus_sphinx))),(((Cercopithecus_roloway,(((((Cercopithecus_albogularis,Cercopithecus_albogularis_monoides),(Cercopithecus_albogularis_labiatus,((Cercopithecus_mitis_boutourlinii,Cercopithecus_albogularis_albotorquatus),Cercopithecus_albogularis_erythrarchus))),((((Cercopithecus_mitis_stuhlmanni,((Cercopithecus_mitis_heymansi,Cercopithecus_albogularis_kolbi),(Cercopithecus_doggetti,(Cercopithecus_kandti,Cercopithecus_albogularis_francescae)))),Cercopithecus_mitis),((Cercopithecus_aethiops,(Chlorocebus_sabaeus,((((Chlorocebus_cynosuros,Chlorocebus_tantalus),Chlorocebus_pygerythrus),(Chlorocebus_aethiops,Cercopithecus_hamlyni)),(Cercopithecus_dryas,Cercopithecus_solatus)))),Cercopithecus_erythrogaster_pococki)),((Cercopithecus_mitis_mitis,Cercopithecus_mitis_opisthostictus),((Erythrocebus_patas,Allenopithecus_nigroviridis),(Cercopithecus_nictitans_nictitans,Cercopithecus_nictitans))))),((Cercopithecus_cephus,((((Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi),Cercopithecus_lhoesti),(Cercopithecus_ascanius_katangae,(Cercopithecus_cephus_cephus,((((Cercopithecus_erythrogaster,(Cercopithecus_petaurista_buettikoferi,Cercopithecus_petaurista_petaurista)),Cercopithecus_petaurista),Cercopithecus_ascanius_whitesidei),Cercopithecus_erythrotis_camerunensis)))),Cercopithecus_ascanius_schmidti)),((Cercopithecus_neglectus,((Cercopithecus_campbelli,Cercopithecus_mona),((((Cercopithecus_pogonias_schwarzianus,Cercopithecus_pogonias_grayi),Cercopithecus_pogonias_nigripes),((Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans),Cercopithecus_nictitans_martini)),Cercopithecus_pogonias))),Cercopithecus_cephus_ngottoensis))),Cercopithecus_albogularis_moloneyi)),(((Macaca_fuscata,(Macaca_nigra,Macaca_nemestrina)),(Macaca_assamensis,Macaca_thibetana)),Macaca_arctoides)),(Cercopithecus_diana,(Macaca_silenus,Macaca_tonkeana)))),Macaca_mulatta),Macaca_fascicularis),(Miopithecus_talapoin,((Procolobus_verus,((Colobus_guereza,Colobus_satanas),Piliocolobus_badius)),(((((((Trachypithecus_pileatus,Trachypithecus_johnii),Trachypithecus_cristatus),(((Pygathrix_nigripes,Pygathrix_nemaeus),(Simias_concolor,Nasalis_larvatus)),(Trachypithecus_obscurus,Trachypithecus_francoisi))),Rhinopithecus_roxellana),Rhinopithecus_bieti_2_RL2012),Rhinopithecus_brelichi),(Presbytis_melalophos,(Rhinopithecus_avunculus,Semnopithecus_entellus)))))),Miopithecus_ogouensis),((Otolemur_crassicaudatus,((((Galagoides_demidoff,Otolemur_garnettii),Galago_senegalensis),(((Lepilemur_ruficaudatus,Lepilemur_hubbardorum),Propithecus_verreauxi),Loris_tardigradus)),(((((((Megaladapis_edwardsi,Palaeopropithecus_ingens),((Avahi_laniger,Indri_indri),(((Hapalemur_griseus,(Lemur_catta,(Varecia_variegata,Varecia_rubra))),(Cheirogaleus_medius,Prolemur_simus)),(((Eulemur_macaco,(Eulemur_rufus,Eulemur_rubriventer)),Eulemur_mongoz),Eulemur_fulvus)))),Propithecus_coquereli),(Galago_moholi,(((Nycticebus_pygmaeus,(Nycticebus_coucang,Nycticebus_bengalensis)),Loris_lydekkerianus),(Perodicticus_potto_edwarsi,Perodicticus_potto)))),Daubentonia_madagascariensis),((Tarsius_lariang,(Tarsius_wallacei,Tarsius_dentatus)),Tarsius_syrichta)),Tarsius_bancanus))),((Brachyteles_arachnoides,Chiropotes_albinasus),(((((Saguinus_oedipus,Callithrix_pygmaea),Callithrix_jacchus),(Sapajus_xanthosternos,(Cebus_apella,Cebus_albifrons))),((((Aotus_azarae,((Aotus_azarai,Aotus_lemurinus),Aotus_azarae_azarai)),Aotus_trivirgatus),(((Saimiri_boliviensis,(Saimiri_sciureus_macrodon,(Saimiri_sciureus,Saimiri_oerstedii))),Saimiri_oerstedii_citrinellus),(Aotus_nancymaae,Leontopithecus_rosalia))),(Lagothrix_lagotricha,((Alouatta_caraya,(Callicebus_cupreus,Callicebus_lugens)),Pithecia_pithecia)))),((((Callicebus_donacophilus,Ateles_belzebuth),(Ateles_geoffroyi,(Ateles_paniscus,Callimico_goeldii))),Chiropotes_israelita),Cacajao_calvus))))))),Gorilla_gorilla_gorilla),((Pongo_pygmaeus,Pongo_abelii),((((Symphalangus_syndactylus,Hylobates_agilis),Hylobates_lar),Hylobates_moloch),Nomascus_leucogenys))),Homo_heidelbergensis),((Pan_paniscus,(Pan_troglodytes,Pan_troglodytes_troglodytes)),Pan_troglodytes_ellioti),Homo_sapiens); +(((((((((Callithrix_jacchus,Callithrix_pygmaea),(Ateles_paniscus,Saguinus_oedipus)),((Aotus_azarai,Aotus_lemurinus),(((Callimico_goeldii,Leontopithecus_rosalia),(((((Ateles_belzebuth,Lagothrix_lagotricha),Aotus_trivirgatus),Pithecia_pithecia),((Callicebus_lugens,(Aotus_nancymaae,Callicebus_cupreus)),(((Cacajao_calvus,(Chiropotes_israelita,(Brachyteles_arachnoides,Chiropotes_albinasus))),(Cebus_albifrons,(Sapajus_xanthosternos,Cebus_apella))),(Saimiri_oerstedii_citrinellus,(Saimiri_sciureus_macrodon,((Saimiri_boliviensis,Saimiri_oerstedii),Saimiri_sciureus)))))),((Ateles_geoffroyi,Callicebus_donacophilus),Aotus_azarae_azarai))),Aotus_azarae))),Alouatta_caraya),((((((Colobus_guereza,Colobus_satanas),(Piliocolobus_badius,Procolobus_verus)),((Rhinopithecus_bieti_2_RL2012,((Rhinopithecus_brelichi,((Trachypithecus_cristatus,(((Pygathrix_nigripes,Pygathrix_nemaeus),Trachypithecus_pileatus),(Trachypithecus_obscurus,(Trachypithecus_francoisi,Trachypithecus_johnii)))),(Semnopithecus_entellus,(Simias_concolor,Nasalis_larvatus)))),Rhinopithecus_roxellana)),Rhinopithecus_avunculus)),Presbytis_melalophos),(Miopithecus_ogouensis,((((((Cercopithecus_campbelli,Cercopithecus_mona),(Cercopithecus_wolfi_elegans,(((Cercopithecus_pogonias_grayi,(Cercopithecus_wolfi_pyrogaster,Cercopithecus_pogonias)),Cercopithecus_pogonias_schwarzianus),Cercopithecus_pogonias_nigripes))),(Cercopithecus_roloway,Cercopithecus_diana)),((((Cercopithecus_petaurista,Cercopithecus_neglectus),((((((Cercopithecus_ascanius_katangae,(Cercopithecus_ascanius_whitesidei,Cercopithecus_erythrotis_camerunensis)),((Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi),Cercopithecus_lhoesti)),Cercopithecus_cephus_cephus),((Cercopithecus_erythrogaster_pococki,Cercopithecus_erythrogaster),(Cercopithecus_petaurista_buettikoferi,Cercopithecus_petaurista_petaurista))),Cercopithecus_ascanius_schmidti),Cercopithecus_cephus)),Cercopithecus_cephus_ngottoensis),((((Allenopithecus_nigroviridis,Cercopithecus_kandti),((((Cercopithecus_mitis_heymansi,Erythrocebus_patas),(Cercopithecus_albogularis_francescae,(Cercopithecus_aethiops,((((Chlorocebus_cynosuros,Cercopithecus_hamlyni),Chlorocebus_pygerythrus),(((Cercopithecus_solatus,Chlorocebus_tantalus),Chlorocebus_aethiops),Cercopithecus_dryas)),Chlorocebus_sabaeus)))),Cercopithecus_nictitans),(Cercopithecus_doggetti,(Cercopithecus_mitis_stuhlmanni,((Cercopithecus_mitis,(((Cercopithecus_albogularis_monoides,(Cercopithecus_mitis_boutourlinii,(Cercopithecus_albogularis_erythrarchus,Cercopithecus_albogularis_labiatus))),Cercopithecus_albogularis),(Cercopithecus_albogularis_kolbi,(Cercopithecus_mitis_mitis,Cercopithecus_mitis_opisthostictus)))),Cercopithecus_nictitans_nictitans))))),(((Macaca_tonkeana,Macaca_silenus),Macaca_fascicularis),(((Macaca_sylvanus,(Macaca_assamensis,Macaca_thibetana)),(Macaca_nemestrina,(Macaca_arctoides,(Macaca_fuscata,Macaca_mulatta)))),Macaca_nigra))),(Cercopithecus_albogularis_moloneyi,Cercopithecus_albogularis_albotorquatus)))),(Cercopithecus_nictitans_martini,(((((((Rungwecebus_kipunji,(((Papio_papio,(Papio_hamadryas,Papio_anubis)),Papio_ursinus),(Papio_kindae,Papio_cynocephalus))),Theropithecus_gelada),(Lophocebus_aterrimus,Lophocebus_albigena)),Cercocebus_agilis),Mandrillus_leucophaeus),Cercocebus_chrysogaster),(Cercocebus_torquatus,(Cercocebus_atys,Mandrillus_sphinx))))),Miopithecus_talapoin))),((((Lepilemur_ruficaudatus,Lepilemur_hubbardorum),(((Galagoides_demidoff,Otolemur_garnettii),Galago_senegalensis),(Propithecus_verreauxi,Loris_tardigradus))),(Tarsius_bancanus,((((Galago_moholi,((Loris_lydekkerianus,(Nycticebus_pygmaeus,(Nycticebus_coucang,Nycticebus_bengalensis))),(Perodicticus_potto_edwarsi,Perodicticus_potto))),((((Palaeopropithecus_ingens,(((Cheirogaleus_medius,(((Hapalemur_griseus,Varecia_variegata),Lemur_catta),Varecia_rubra)),Prolemur_simus),((Eulemur_macaco,Eulemur_fulvus),Eulemur_rufus))),Indri_indri),Propithecus_coquereli),(((Eulemur_rubriventer,Eulemur_mongoz),Megaladapis_edwardsi),Avahi_laniger))),Daubentonia_madagascariensis),(((Tarsius_wallacei,Tarsius_dentatus),Tarsius_lariang),Tarsius_syrichta)))),Otolemur_crassicaudatus))),(Gorilla_gorilla_gorilla,Gorilla_gorilla)),(((Hylobates_agilis,(Symphalangus_syndactylus,Hylobates_lar)),(Pongo_pygmaeus,Pongo_abelii)),(Nomascus_leucogenys,Hylobates_moloch))),Homo_sapiens_ssp_Denisova),(((Homo_heidelbergensis,Pan_troglodytes_ellioti),(Pan_paniscus,Pan_troglodytes)),Pan_troglodytes_troglodytes),Homo_sapiens); +(((Homo_heidelbergensis,((((((Piliocolobus_badius,(Rhinopithecus_avunculus,(Presbytis_melalophos,(Semnopithecus_entellus,((Colobus_guereza,Colobus_satanas),((Rhinopithecus_roxellana,(Rhinopithecus_bieti_2_RL2012,Rhinopithecus_brelichi)),((((Trachypithecus_johnii,(Trachypithecus_obscurus,Trachypithecus_francoisi)),Trachypithecus_cristatus),Trachypithecus_pileatus),((Pygathrix_nigripes,Pygathrix_nemaeus),(Simias_concolor,Nasalis_larvatus))))))))),Procolobus_verus),((Cercopithecus_roloway,((((Cercopithecus_campbelli,Cercopithecus_mona),((Cercopithecus_wolfi_elegans,((Cercopithecus_pogonias_grayi,Cercopithecus_pogonias_schwarzianus),Cercopithecus_pogonias_nigripes)),(Cercopithecus_pogonias,Cercopithecus_wolfi_pyrogaster))),(((((Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi),Cercopithecus_lhoesti),((Cercopithecus_erythrotis_camerunensis,((Cercopithecus_ascanius_katangae,((Cercopithecus_petaurista,(Cercopithecus_petaurista_buettikoferi,Cercopithecus_petaurista_petaurista)),(Cercopithecus_erythrogaster_pococki,Cercopithecus_erythrogaster))),Cercopithecus_cephus_cephus)),(Cercopithecus_ascanius_whitesidei,Cercopithecus_neglectus))),Cercopithecus_ascanius_schmidti),(Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis))),(((((Macaca_assamensis,Macaca_thibetana),((Macaca_tonkeana,Macaca_silenus),Macaca_fascicularis)),((((Macaca_sylvanus,Macaca_fuscata),Macaca_nigra),Macaca_nemestrina),Macaca_mulatta)),Macaca_arctoides),((((Cercopithecus_mitis_mitis,Cercopithecus_mitis_opisthostictus),((Cercopithecus_nictitans_martini,Cercopithecus_nictitans_nictitans),(Cercopithecus_mitis,(((Cercopithecus_albogularis_kolbi,Cercopithecus_mitis_stuhlmanni),(Cercopithecus_kandti,(Cercopithecus_mitis_heymansi,(Cercopithecus_albogularis_francescae,(((Chlorocebus_cynosuros,Chlorocebus_tantalus),((((Cercopithecus_aethiops,Cercopithecus_solatus),Cercopithecus_dryas),Chlorocebus_sabaeus),(Allenopithecus_nigroviridis,Chlorocebus_pygerythrus))),((Cercopithecus_nictitans,(Chlorocebus_aethiops,Cercopithecus_hamlyni)),Erythrocebus_patas)))))),Cercopithecus_doggetti)))),((((Cercopithecus_albogularis_albotorquatus,Cercopithecus_mitis_boutourlinii),Cercopithecus_albogularis_monoides),Cercopithecus_albogularis_erythrarchus),(Cercopithecus_albogularis_labiatus,Cercopithecus_albogularis))),Cercopithecus_albogularis_moloneyi)))),((Cercopithecus_diana,(Miopithecus_ogouensis,((Cercocebus_chrysogaster,(Cercocebus_agilis,(Mandrillus_leucophaeus,((((Rungwecebus_kipunji,((Papio_papio,(Papio_kindae,Papio_cynocephalus)),((Papio_hamadryas,Papio_anubis),Papio_ursinus))),Theropithecus_gelada),(Lophocebus_aterrimus,Lophocebus_albigena)),(Cercocebus_torquatus,Cercocebus_atys))))),Mandrillus_sphinx))),Miopithecus_talapoin))),((((Loris_tardigradus,((Galagoides_demidoff,(Otolemur_garnettii,Galago_senegalensis)),(Propithecus_verreauxi,(Lepilemur_ruficaudatus,Lepilemur_hubbardorum)))),(Tarsius_bancanus,((((((Palaeopropithecus_ingens,(Propithecus_coquereli,((Eulemur_rufus,(Prolemur_simus,(((Cheirogaleus_medius,(Eulemur_rubriventer,(Eulemur_macaco,Eulemur_fulvus))),Eulemur_mongoz),(Hapalemur_griseus,(Lemur_catta,(Varecia_variegata,Varecia_rubra)))))),(Avahi_laniger,Indri_indri)))),Megaladapis_edwardsi),Daubentonia_madagascariensis),(Perodicticus_potto_edwarsi,Perodicticus_potto)),((Loris_lydekkerianus,(Nycticebus_pygmaeus,(Nycticebus_coucang,Nycticebus_bengalensis))),Galago_moholi)),((Tarsius_dentatus,Tarsius_wallacei),(Tarsius_lariang,Tarsius_syrichta))))),Otolemur_crassicaudatus),((Saimiri_oerstedii_citrinellus,(Saimiri_sciureus_macrodon,((Saimiri_sciureus,Saimiri_oerstedii),Saimiri_boliviensis))),((((Cebus_albifrons,(Sapajus_xanthosternos,Cebus_apella)),(((Saguinus_oedipus,(Lagothrix_lagotricha,Callithrix_pygmaea)),(Aotus_azarae_azarai,(Aotus_azarae,(Aotus_azarai,Aotus_lemurinus)))),(Aotus_nancymaae,((Alouatta_caraya,(Callimico_goeldii,Leontopithecus_rosalia)),(Callicebus_lugens,(((Callithrix_jacchus,(Ateles_paniscus,(Ateles_belzebuth,Ateles_geoffroyi))),Callicebus_donacophilus),Callicebus_cupreus)))))),Aotus_trivirgatus),(Pithecia_pithecia,((Chiropotes_israelita,(Brachyteles_arachnoides,Chiropotes_albinasus)),Cacajao_calvus)))))),(((Gorilla_gorilla_gorilla,((((Hylobates_moloch,Hylobates_lar),Nomascus_leucogenys),(Symphalangus_syndactylus,Hylobates_agilis)),Pongo_abelii)),Pongo_pygmaeus),Gorilla_gorilla)),Homo_sapiens_ssp_Denisova)),Pan_troglodytes_ellioti),((Pan_paniscus,Pan_troglodytes_troglodytes),Pan_troglodytes),Homo_sapiens); +((((Hylobates_moloch,(((Symphalangus_syndactylus,Gorilla_gorilla),((Pongo_abelii,Pongo_pygmaeus),(Hylobates_agilis,Hylobates_lar))),Nomascus_leucogenys)),(((((((((((Cercopithecus_albogularis,(Cercopithecus_nictitans_martini,Cercopithecus_albogularis_monoides)),((Cercopithecus_albogularis_labiatus,((Cercopithecus_albogularis_erythrarchus,Cercopithecus_mitis_boutourlinii),Cercopithecus_albogularis_moloneyi)),(Cercopithecus_albogularis_albotorquatus,((Cercopithecus_mitis_mitis,Cercopithecus_mitis_opisthostictus),((((Cercopithecus_mitis_stuhlmanni,(Cercopithecus_albogularis_kolbi,Cercopithecus_nictitans_nictitans)),(Cercopithecus_kandti,(((((Cercopithecus_nictitans,Cercopithecus_hamlyni),Erythrocebus_patas),((((Allenopithecus_nigroviridis,Chlorocebus_pygerythrus),(Chlorocebus_cynosuros,(Chlorocebus_aethiops,(Cercopithecus_dryas,(Chlorocebus_tantalus,Cercopithecus_solatus))))),Chlorocebus_sabaeus),Cercopithecus_aethiops)),Cercopithecus_albogularis_francescae),Cercopithecus_mitis_heymansi))),Cercopithecus_doggetti),Cercopithecus_mitis))))),((((Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi),Cercopithecus_lhoesti),(((((Cercopithecus_petaurista_buettikoferi,Cercopithecus_petaurista_petaurista),(Cercopithecus_erythrogaster_pococki,(Cercopithecus_erythrotis_camerunensis,Cercopithecus_erythrogaster))),Cercopithecus_petaurista),(Cercopithecus_ascanius_katangae,Cercopithecus_cephus_cephus)),Cercopithecus_ascanius_whitesidei)),Cercopithecus_ascanius_schmidti)),(Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis)),(Cercopithecus_neglectus,Cercopithecus_roloway)),((((Cercopithecus_campbelli,Cercopithecus_mona),(Cercopithecus_pogonias,((Cercopithecus_pogonias_nigripes,(Cercopithecus_pogonias_schwarzianus,Cercopithecus_pogonias_grayi)),(Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans)))),((((((Lophocebus_albigena,(Rungwecebus_kipunji,(((Papio_ursinus,Papio_anubis),(Papio_papio,(Papio_kindae,Papio_cynocephalus))),Papio_hamadryas))),(Lophocebus_aterrimus,Theropithecus_gelada)),(Cercocebus_agilis,Mandrillus_leucophaeus)),Cercocebus_chrysogaster),(Cercocebus_torquatus,Cercocebus_atys)),Mandrillus_sphinx)),(Cercopithecus_diana,Miopithecus_ogouensis))),Miopithecus_talapoin),(((Macaca_nemestrina,(((Macaca_assamensis,Macaca_thibetana),((Macaca_tonkeana,Macaca_silenus),Macaca_fascicularis)),Macaca_sylvanus)),Macaca_arctoides),((Macaca_mulatta,Macaca_fuscata),Macaca_nigra))),((Piliocolobus_badius,((Colobus_guereza,Colobus_satanas),(((Trachypithecus_pileatus,(Trachypithecus_cristatus,((Semnopithecus_entellus,Trachypithecus_francoisi),(Trachypithecus_obscurus,Trachypithecus_johnii)))),(Rhinopithecus_avunculus,Presbytis_melalophos)),((Rhinopithecus_bieti_2_RL2012,Rhinopithecus_brelichi),(Rhinopithecus_roxellana,((Pygathrix_nigripes,Pygathrix_nemaeus),(Simias_concolor,Nasalis_larvatus))))))),Procolobus_verus)),(((Loris_tardigradus,((((Galago_senegalensis,Galagoides_demidoff),Otolemur_garnettii),(Propithecus_verreauxi,(Lepilemur_ruficaudatus,Lepilemur_hubbardorum))),(Tarsius_bancanus,((((Loris_lydekkerianus,(Nycticebus_pygmaeus,(Nycticebus_coucang,Nycticebus_bengalensis))),((Perodicticus_potto_edwarsi,Perodicticus_potto),((Propithecus_coquereli,Avahi_laniger),(Indri_indri,(Palaeopropithecus_ingens,((Cheirogaleus_medius,Megaladapis_edwardsi),((Eulemur_macaco,((((Eulemur_rufus,Eulemur_mongoz),Prolemur_simus),(Hapalemur_griseus,(Lemur_catta,(Varecia_variegata,Varecia_rubra)))),Eulemur_rubriventer)),Eulemur_fulvus))))))),Daubentonia_madagascariensis),(Galago_moholi,((Tarsius_lariang,(Tarsius_dentatus,Tarsius_wallacei)),Tarsius_syrichta)))))),Otolemur_crassicaudatus),((Aotus_nancymaae,((Saimiri_sciureus_macrodon,(Saimiri_sciureus,(Saimiri_oerstedii,Saimiri_boliviensis))),Saimiri_oerstedii_citrinellus)),((Aotus_azarae,(Aotus_azarae_azarai,(Aotus_azarai,Aotus_lemurinus))),(Aotus_trivirgatus,(((Cebus_albifrons,(Pithecia_pithecia,(Sapajus_xanthosternos,Cebus_apella))),(Lagothrix_lagotricha,(Callicebus_cupreus,Callicebus_lugens))),(((Saguinus_oedipus,Callithrix_pygmaea),((((Alouatta_caraya,(Callimico_goeldii,Leontopithecus_rosalia)),(((Brachyteles_arachnoides,Chiropotes_israelita),Chiropotes_albinasus),(Callicebus_donacophilus,Cacajao_calvus))),Ateles_paniscus),Ateles_geoffroyi)),(Ateles_belzebuth,Callithrix_jacchus)))))))),Gorilla_gorilla_gorilla)),(((Pan_troglodytes_ellioti,Pan_troglodytes_troglodytes),(Pan_troglodytes,Pan_paniscus)),Homo_heidelbergensis)),Homo_sapiens_ssp_Denisova,Homo_sapiens); +((Homo_sapiens_ssp_Denisova,(Homo_heidelbergensis,(((Nomascus_leucogenys,(Hylobates_moloch,((Hylobates_agilis,Symphalangus_syndactylus),Hylobates_lar))),(Pongo_abelii,Pongo_pygmaeus)),(Gorilla_gorilla_gorilla,(Gorilla_gorilla,((((Saimiri_sciureus_macrodon,((Saimiri_oerstedii,Saimiri_boliviensis),Saimiri_sciureus)),Saimiri_oerstedii_citrinellus),(((Aotus_trivirgatus,(((((Cebus_albifrons,(Sapajus_xanthosternos,Cebus_apella)),(Chiropotes_albinasus,((Pithecia_pithecia,Chiropotes_israelita),Cacajao_calvus))),(((Brachyteles_arachnoides,Alouatta_caraya),(Callimico_goeldii,Saguinus_oedipus)),(Callithrix_jacchus,Callithrix_pygmaea))),(Lagothrix_lagotricha,(((Callicebus_cupreus,Callicebus_donacophilus),((Ateles_paniscus,Ateles_belzebuth),Ateles_geoffroyi)),Callicebus_lugens))),Leontopithecus_rosalia)),Aotus_azarae),(Aotus_nancymaae,((Aotus_azarai,Aotus_lemurinus),Aotus_azarae_azarai)))),((((Miopithecus_talapoin,((Miopithecus_ogouensis,(Cercopithecus_diana,(Cercopithecus_roloway,(Macaca_silenus,((Macaca_tonkeana,((((Macaca_nemestrina,((Macaca_mulatta,Macaca_fuscata),Macaca_nigra)),Macaca_sylvanus),Macaca_arctoides),(Macaca_assamensis,Macaca_thibetana))),Macaca_fascicularis))))),((((Mandrillus_leucophaeus,Cercocebus_agilis),((Theropithecus_gelada,(Lophocebus_aterrimus,Lophocebus_albigena)),((((Papio_papio,(Papio_anubis,Papio_hamadryas)),Papio_ursinus),Rungwecebus_kipunji),(Papio_kindae,Papio_cynocephalus)))),Cercocebus_chrysogaster),(Cercocebus_torquatus,(Mandrillus_sphinx,Cercocebus_atys))))),((((((Cercopithecus_albogularis_francescae,(((((Cercopithecus_erythrotis_camerunensis,Cercopithecus_ascanius_katangae),((Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi),Cercopithecus_lhoesti)),((((Cercopithecus_petaurista_buettikoferi,Cercopithecus_petaurista_petaurista),(Cercopithecus_erythrogaster_pococki,Cercopithecus_erythrogaster)),Cercopithecus_petaurista),Cercopithecus_cephus_cephus)),Cercopithecus_ascanius_whitesidei),Cercopithecus_ascanius_schmidti)),(Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis)),(Cercopithecus_albogularis_moloneyi,((((((Cercopithecus_mitis_mitis,Cercopithecus_mitis_opisthostictus),((((Allenopithecus_nigroviridis,Cercopithecus_kandti),Cercopithecus_mitis),Cercopithecus_doggetti),((Cercopithecus_mitis_stuhlmanni,(Cercopithecus_albogularis_kolbi,Erythrocebus_patas)),Cercopithecus_nictitans_nictitans))),Cercopithecus_mitis_heymansi),((Cercopithecus_albogularis,Cercopithecus_albogularis_monoides),Cercopithecus_albogularis_labiatus)),(Cercopithecus_mitis_boutourlinii,Cercopithecus_albogularis_erythrarchus)),Cercopithecus_albogularis_albotorquatus))),Cercopithecus_neglectus),((Cercopithecus_campbelli,Cercopithecus_mona),(Cercopithecus_nictitans_martini,((Cercopithecus_pogonias_schwarzianus,((Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans),(Cercopithecus_pogonias_grayi,Cercopithecus_pogonias_nigripes))),Cercopithecus_pogonias)))),((Cercopithecus_aethiops,(((Chlorocebus_cynosuros,(Cercopithecus_hamlyni,Cercopithecus_nictitans)),((Chlorocebus_pygerythrus,Chlorocebus_aethiops),Chlorocebus_tantalus)),(Cercopithecus_dryas,Cercopithecus_solatus))),Chlorocebus_sabaeus))),(Procolobus_verus,((((Pygathrix_nemaeus,Trachypithecus_pileatus),(Rhinopithecus_bieti_2_RL2012,((Pygathrix_nigripes,((((Simias_concolor,(Trachypithecus_cristatus,(Trachypithecus_obscurus,Trachypithecus_francoisi))),Rhinopithecus_brelichi),Nasalis_larvatus),Rhinopithecus_roxellana)),Trachypithecus_johnii))),(Semnopithecus_entellus,(Rhinopithecus_avunculus,Presbytis_melalophos))),((Colobus_guereza,Colobus_satanas),Piliocolobus_badius)))),((Loris_tardigradus,(Otolemur_garnettii,(Galago_senegalensis,((Propithecus_verreauxi,(Lepilemur_ruficaudatus,Lepilemur_hubbardorum)),(Galagoides_demidoff,(Tarsius_bancanus,((((((Eulemur_rubriventer,(((Cheirogaleus_medius,((Hapalemur_griseus,((Varecia_variegata,Lemur_catta),Varecia_rubra)),Prolemur_simus)),Eulemur_fulvus),(Eulemur_rufus,Palaeopropithecus_ingens))),Megaladapis_edwardsi),Eulemur_macaco),Eulemur_mongoz),(((Galago_moholi,(Loris_lydekkerianus,(Nycticebus_pygmaeus,(Nycticebus_coucang,Nycticebus_bengalensis)))),(Perodicticus_potto_edwarsi,Perodicticus_potto)),(Daubentonia_madagascariensis,((Propithecus_coquereli,Avahi_laniger),Indri_indri)))),(Tarsius_syrichta,(Tarsius_wallacei,(Tarsius_lariang,Tarsius_dentatus)))))))))),Otolemur_crassicaudatus)))))))),(((Pan_troglodytes,Pan_paniscus),Pan_troglodytes_troglodytes),Pan_troglodytes_ellioti),Homo_sapiens); +((Pan_troglodytes_troglodytes,Pan_paniscus),((Pan_troglodytes_ellioti,Pan_troglodytes),(Homo_heidelbergensis,(Homo_sapiens_ssp_Denisova,((Gorilla_gorilla_gorilla,(((Miopithecus_ogouensis,(((Miopithecus_talapoin,(((Cercopithecus_pogonias_schwarzianus,((Cercopithecus_pogonias_nigripes,Cercopithecus_pogonias_grayi),Cercopithecus_pogonias)),((Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans),Cercopithecus_nictitans_martini)),(((((Macaca_silenus,(((Macaca_nemestrina,((Macaca_mulatta,Macaca_fuscata),Macaca_nigra)),Macaca_sylvanus),(Macaca_assamensis,Macaca_thibetana))),(Macaca_tonkeana,(Macaca_fascicularis,Macaca_arctoides))),((Erythrocebus_patas,Allenopithecus_nigroviridis),Cercopithecus_diana)),((((((Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis),(((((Cercopithecus_erythrotis_camerunensis,Cercopithecus_ascanius_katangae),((((Cercopithecus_petaurista_buettikoferi,Cercopithecus_petaurista_petaurista),(Cercopithecus_erythrogaster_pococki,Cercopithecus_erythrogaster)),Cercopithecus_petaurista),Cercopithecus_cephus_cephus)),Cercopithecus_ascanius_whitesidei),((Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi),Cercopithecus_lhoesti)),Cercopithecus_ascanius_schmidti)),(((Cercopithecus_albogularis_moloneyi,((Cercopithecus_mitis_boutourlinii,((Cercopithecus_albogularis_erythrarchus,Cercopithecus_albogularis_labiatus),Cercopithecus_albogularis_monoides)),Cercopithecus_albogularis_albotorquatus)),(Cercopithecus_albogularis_francescae,((((((Cercopithecus_mitis_stuhlmanni,Cercopithecus_albogularis_kolbi),Cercopithecus_mitis_mitis),((Cercopithecus_nictitans_nictitans,Cercopithecus_nictitans),Cercopithecus_kandti)),(Cercopithecus_mitis_opisthostictus,Cercopithecus_doggetti)),Cercopithecus_mitis),Cercopithecus_mitis_heymansi))),Cercopithecus_albogularis)),Cercopithecus_neglectus),(Cercopithecus_aethiops,(((((Chlorocebus_pygerythrus,Chlorocebus_tantalus),Chlorocebus_cynosuros),(Chlorocebus_aethiops,Cercopithecus_hamlyni)),(Cercopithecus_dryas,Cercopithecus_solatus)),Chlorocebus_sabaeus))),Cercopithecus_roloway)),(Cercopithecus_campbelli,Cercopithecus_mona)))),((Cercocebus_chrysogaster,((Mandrillus_leucophaeus,((Cercocebus_torquatus,Cercocebus_atys),((Lophocebus_aterrimus,Theropithecus_gelada),(Lophocebus_albigena,(((Papio_kindae,Papio_cynocephalus),((Papio_papio,(Papio_anubis,Papio_hamadryas)),Papio_ursinus)),Rungwecebus_kipunji))))),Cercocebus_agilis)),Mandrillus_sphinx)),(Semnopithecus_entellus,(Rhinopithecus_avunculus,(Presbytis_melalophos,((Procolobus_verus,((Colobus_guereza,Colobus_satanas),Piliocolobus_badius)),((((Pygathrix_nemaeus,Pygathrix_nigripes),(Simias_concolor,Nasalis_larvatus)),((Rhinopithecus_brelichi,Rhinopithecus_roxellana),Rhinopithecus_bieti_2_RL2012)),(Trachypithecus_pileatus,((Trachypithecus_cristatus,(Trachypithecus_obscurus,Trachypithecus_johnii)),Trachypithecus_francoisi))))))))),((Leontopithecus_rosalia,(((((Chiropotes_israelita,Chiropotes_albinasus),(Lagothrix_lagotricha,(Pithecia_pithecia,((Cebus_albifrons,(Sapajus_xanthosternos,Cebus_apella)),Cacajao_calvus)))),((((Ateles_paniscus,Callicebus_donacophilus),(Ateles_belzebuth,((Ateles_geoffroyi,Callithrix_jacchus),Brachyteles_arachnoides))),Callicebus_cupreus),Callicebus_lugens)),((Saguinus_oedipus,(Callimico_goeldii,Alouatta_caraya)),Callithrix_pygmaea)),(((Aotus_lemurinus,((((Saimiri_sciureus_macrodon,(Saimiri_sciureus,(Saimiri_oerstedii,Saimiri_boliviensis))),Saimiri_oerstedii_citrinellus),Aotus_azarai),Aotus_nancymaae)),Aotus_azarae_azarai),(Aotus_trivirgatus,Aotus_azarae)))),((Galago_senegalensis,Loris_tardigradus),((((Otolemur_garnettii,Otolemur_crassicaudatus),Galagoides_demidoff),(Lepilemur_ruficaudatus,Lepilemur_hubbardorum)),(Propithecus_verreauxi,(Tarsius_bancanus,((((((Perodicticus_potto_edwarsi,Perodicticus_potto),(Nycticebus_coucang,Nycticebus_bengalensis)),(Loris_lydekkerianus,Galago_moholi)),(((Avahi_laniger,Indri_indri),((((Eulemur_macaco,(Eulemur_rufus,Varecia_variegata)),((Eulemur_mongoz,((Prolemur_simus,((Nycticebus_pygmaeus,Hapalemur_griseus),Cheirogaleus_medius)),Eulemur_fulvus)),Eulemur_rubriventer)),Megaladapis_edwardsi),Palaeopropithecus_ingens)),Propithecus_coquereli)),Daubentonia_madagascariensis),((((Tarsius_lariang,Tarsius_dentatus),Tarsius_wallacei),Tarsius_syrichta),(Lemur_catta,Varecia_rubra))))))))),(((Hylobates_lar,(Symphalangus_syndactylus,Hylobates_agilis)),Hylobates_moloch),Nomascus_leucogenys))),((Pongo_abelii,Pongo_pygmaeus),Gorilla_gorilla))))),Homo_sapiens); +(((((Gorilla_gorilla_gorilla,(((((((((Papio_kindae,Papio_cynocephalus),((Papio_papio,(Papio_anubis,Papio_hamadryas)),Papio_ursinus)),Rungwecebus_kipunji),(Theropithecus_gelada,Lophocebus_aterrimus)),Lophocebus_albigena),((Mandrillus_leucophaeus,(Cercocebus_agilis,(Cercocebus_torquatus,(Mandrillus_sphinx,Cercocebus_atys)))),Cercocebus_chrysogaster)),(Miopithecus_ogouensis,(Miopithecus_talapoin,(((((((Macaca_nemestrina,((Macaca_nigra,(Macaca_arctoides,(Macaca_mulatta,Macaca_fuscata))),Macaca_sylvanus)),(Macaca_assamensis,Macaca_thibetana)),((Macaca_silenus,Macaca_tonkeana),Macaca_fascicularis)),(Erythrocebus_patas,Cercopithecus_diana)),Cercopithecus_roloway),((((Cercopithecus_ascanius_schmidti,(((((((Cercopithecus_petaurista_buettikoferi,Cercopithecus_petaurista_petaurista),(Cercopithecus_erythrogaster_pococki,Cercopithecus_erythrogaster)),Cercopithecus_petaurista),Cercopithecus_cephus_cephus),((((Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi),(Cercopithecus_lhoesti,Cercopithecus_ascanius_whitesidei)),Cercopithecus_erythrotis_camerunensis),Cercopithecus_ascanius_katangae)),(Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis)),((Cercopithecus_albogularis_moloneyi,(Cercopithecus_albogularis_francescae,((Cercopithecus_mitis_opisthostictus,(((Cercopithecus_nictitans_nictitans,Cercopithecus_nictitans),((Cercopithecus_albogularis_erythrarchus,(Cercopithecus_albogularis,Cercopithecus_albogularis_monoides)),(Cercopithecus_mitis_boutourlinii,Cercopithecus_albogularis_labiatus))),Cercopithecus_mitis_mitis)),(Cercopithecus_mitis,((Cercopithecus_mitis_heymansi,(Cercopithecus_doggetti,(Cercopithecus_mitis_stuhlmanni,Cercopithecus_albogularis_kolbi))),Cercopithecus_kandti))))),Cercopithecus_albogularis_albotorquatus))),Cercopithecus_neglectus),(((((Chlorocebus_cynosuros,Cercopithecus_hamlyni),((Chlorocebus_aethiops,Chlorocebus_tantalus),Chlorocebus_pygerythrus)),(Cercopithecus_dryas,Cercopithecus_solatus)),Chlorocebus_sabaeus),Cercopithecus_aethiops)),(((Cercopithecus_pogonias_grayi,((Cercopithecus_pogonias,(Cercopithecus_nictitans_martini,(Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans))),Cercopithecus_pogonias_nigripes)),Cercopithecus_pogonias_schwarzianus),(Cercopithecus_campbelli,Cercopithecus_mona)))),Allenopithecus_nigroviridis)))),((Procolobus_verus,((Colobus_guereza,Colobus_satanas),Piliocolobus_badius)),(((((Pygathrix_nemaeus,Trachypithecus_pileatus),(((Trachypithecus_johnii,(Trachypithecus_francoisi,Trachypithecus_obscurus)),Trachypithecus_cristatus),(Pygathrix_nigripes,(Simias_concolor,Nasalis_larvatus)))),(Rhinopithecus_roxellana,Rhinopithecus_bieti_2_RL2012)),Rhinopithecus_brelichi),(Presbytis_melalophos,(Rhinopithecus_avunculus,Semnopithecus_entellus))))),(((((Aotus_nancymaae,Leontopithecus_rosalia),((Saimiri_sciureus_macrodon,(Saimiri_boliviensis,(Saimiri_oerstedii,Saimiri_sciureus))),Saimiri_oerstedii_citrinellus)),((Aotus_azarae,(Aotus_trivirgatus,(Aotus_azarai,Aotus_lemurinus))),Aotus_azarae_azarai)),(((Callithrix_pygmaea,Saguinus_oedipus),Alouatta_caraya),((Cebus_albifrons,(Sapajus_xanthosternos,Cebus_apella)),(((((Callimico_goeldii,(Ateles_belzebuth,Ateles_geoffroyi)),Callicebus_cupreus),((Callicebus_donacophilus,Ateles_paniscus),(Brachyteles_arachnoides,Callithrix_jacchus))),Callicebus_lugens),((Cacajao_calvus,(Chiropotes_albinasus,(Pithecia_pithecia,Chiropotes_israelita))),Lagothrix_lagotricha))))),((((Tarsius_bancanus,(((Otolemur_garnettii,Otolemur_crassicaudatus),Galagoides_demidoff),(Lepilemur_ruficaudatus,Lepilemur_hubbardorum))),((((((Indri_indri,(((Eulemur_fulvus,(((Eulemur_rufus,Eulemur_mongoz),Eulemur_macaco),Eulemur_rubriventer)),(((Varecia_variegata,(Nycticebus_pygmaeus,Hapalemur_griseus)),Cheirogaleus_medius),Prolemur_simus)),Palaeopropithecus_ingens)),Avahi_laniger),((Lemur_catta,Varecia_rubra),Megaladapis_edwardsi)),Propithecus_coquereli),(Daubentonia_madagascariensis,(Galago_moholi,((Perodicticus_potto_edwarsi,Perodicticus_potto),(Loris_lydekkerianus,(Nycticebus_coucang,Nycticebus_bengalensis)))))),(Tarsius_syrichta,((Tarsius_dentatus,Tarsius_wallacei),Tarsius_lariang)))),(Galago_senegalensis,Loris_tardigradus)),Propithecus_verreauxi)))),(Gorilla_gorilla,(Pongo_abelii,Pongo_pygmaeus))),((Hylobates_agilis,(Nomascus_leucogenys,Symphalangus_syndactylus)),(Hylobates_moloch,Hylobates_lar))),(Homo_sapiens_ssp_Denisova,Homo_heidelbergensis)),((Pan_paniscus,(Pan_troglodytes,Pan_troglodytes_troglodytes)),Pan_troglodytes_ellioti),Homo_sapiens); +(((((Pongo_abelii,Pongo_pygmaeus),Nomascus_leucogenys),(Gorilla_gorilla,((Hylobates_agilis,(Hylobates_lar,Symphalangus_syndactylus)),((Hylobates_moloch,(((((Rhinopithecus_avunculus,(Presbytis_melalophos,Semnopithecus_entellus)),(Trachypithecus_johnii,(((((Pygathrix_nigripes,Pygathrix_nemaeus),(Nasalis_larvatus,Simias_concolor)),((Trachypithecus_cristatus,Trachypithecus_pileatus),(Trachypithecus_francoisi,Trachypithecus_obscurus))),(Rhinopithecus_brelichi,Rhinopithecus_roxellana)),Rhinopithecus_bieti_2_RL2012))),((Piliocolobus_badius,(Colobus_guereza,Colobus_satanas)),Procolobus_verus)),(((((((Chlorocebus_pygerythrus,(Miopithecus_talapoin,(Chlorocebus_aethiops,(Cercopithecus_dryas,(Chlorocebus_tantalus,Cercopithecus_solatus))))),Chlorocebus_cynosuros),(Chlorocebus_sabaeus,(((Cercopithecus_cephus_ngottoensis,Cercopithecus_cephus),(((Cercopithecus_aethiops,Cercopithecus_albogularis_francescae),Cercopithecus_albogularis_moloneyi),((Cercopithecus_mitis,(Cercopithecus_kandti,((Cercopithecus_nictitans,Cercopithecus_nictitans_nictitans),(Cercopithecus_doggetti,Cercopithecus_mitis_stuhlmanni)))),((Cercopithecus_mitis_mitis,((Cercopithecus_albogularis_kolbi,Cercopithecus_mitis_heymansi),Cercopithecus_mitis_opisthostictus)),(Cercopithecus_albogularis,((Cercopithecus_albogularis_albotorquatus,Cercopithecus_albogularis_monoides),(Cercopithecus_mitis_boutourlinii,(Cercopithecus_albogularis_erythrarchus,Cercopithecus_albogularis_labiatus)))))))),(Cercopithecus_ascanius_schmidti,((Cercopithecus_ascanius_whitesidei,((Cercopithecus_erythrotis_camerunensis,(Cercopithecus_lhoesti,(Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi))),Cercopithecus_ascanius_katangae)),(((Cercopithecus_neglectus,Cercopithecus_petaurista),Cercopithecus_cephus_cephus),((Cercopithecus_petaurista_buettikoferi,Cercopithecus_petaurista_petaurista),(Cercopithecus_erythrogaster_pococki,Cercopithecus_erythrogaster)))))))),((Cercopithecus_mona,Cercopithecus_campbelli),(((Cercopithecus_pogonias_grayi,Cercopithecus_pogonias_schwarzianus),(Cercopithecus_pogonias_nigripes,Cercopithecus_wolfi_elegans)),(Cercopithecus_pogonias,Cercopithecus_wolfi_pyrogaster)))),Cercopithecus_nictitans_martini),(((Cercocebus_chrysogaster,(Cercocebus_torquatus,(Mandrillus_sphinx,(Cercocebus_atys,Mandrillus_leucophaeus)))),Cercocebus_agilis),(((((Macaca_tonkeana,(Macaca_fascicularis,Macaca_silenus)),((((Macaca_nemestrina,Macaca_sylvanus),((Macaca_mulatta,Macaca_fuscata),Macaca_nigra)),Macaca_arctoides),(Macaca_thibetana,Macaca_assamensis))),((((Papio_papio,(Papio_anubis,Papio_hamadryas)),(Papio_ursinus,Papio_cynocephalus)),Papio_kindae),(((Lophocebus_albigena,Lophocebus_aterrimus),Rungwecebus_kipunji),Theropithecus_gelada))),Cercopithecus_hamlyni),(((Erythrocebus_patas,Allenopithecus_nigroviridis),Cercopithecus_roloway),Cercopithecus_diana)))),Miopithecus_ogouensis)),((Alouatta_caraya,((((Ateles_paniscus,(Callimico_goeldii,(Ateles_geoffroyi,(Lagothrix_lagotricha,Ateles_belzebuth)))),((Callithrix_jacchus,(Pithecia_pithecia,(Callicebus_cupreus,Callicebus_lugens))),((Callicebus_donacophilus,(Cacajao_calvus,(Chiropotes_israelita,(Brachyteles_arachnoides,Chiropotes_albinasus)))),(Cebus_albifrons,(Sapajus_xanthosternos,Cebus_apella))))),((Leontopithecus_rosalia,(Aotus_nancymaae,(Saimiri_oerstedii_citrinellus,(((Saimiri_boliviensis,Saimiri_oerstedii),Saimiri_sciureus),Saimiri_sciureus_macrodon)))),(Aotus_trivirgatus,((Aotus_lemurinus,Aotus_azarai),(Aotus_azarae,Aotus_azarae_azarai))))),(Callithrix_pygmaea,Saguinus_oedipus))),(((((Megaladapis_edwardsi,Avahi_laniger),((Eulemur_fulvus,((Eulemur_rubriventer,(((Lepilemur_hubbardorum,Lepilemur_ruficaudatus),Indri_indri),(Eulemur_rufus,((Eulemur_mongoz,(Prolemur_simus,((Propithecus_verreauxi,Cheirogaleus_medius),(Nycticebus_pygmaeus,Hapalemur_griseus)))),Propithecus_coquereli)))),Palaeopropithecus_ingens)),Eulemur_macaco)),(Daubentonia_madagascariensis,((((((Perodicticus_potto_edwarsi,Perodicticus_potto),(Nycticebus_bengalensis,Nycticebus_coucang)),Otolemur_crassicaudatus),Otolemur_garnettii),(Galagoides_demidoff,(Loris_tardigradus,Loris_lydekkerianus))),Galago_moholi))),(Tarsius_syrichta,(Tarsius_lariang,(Tarsius_wallacei,Tarsius_dentatus)))),(Galago_senegalensis,(((Varecia_variegata,Varecia_rubra),Lemur_catta),Tarsius_bancanus)))))),Gorilla_gorilla_gorilla)))),Pan_troglodytes_troglodytes),((((Pan_troglodytes_ellioti,Homo_heidelbergensis),Pan_paniscus),Pan_troglodytes),Homo_sapiens_ssp_Denisova),Homo_sapiens); +((((((((Pongo_pygmaeus,(Pongo_abelii,Hylobates_lar)),(Hylobates_agilis,Symphalangus_syndactylus)),Hylobates_moloch),Nomascus_leucogenys),(((((((Nasalis_larvatus,((((Colobus_satanas,((Colobus_guereza,Rhinopithecus_bieti_2_RL2012),Pygathrix_nemaeus)),Simias_concolor),Rhinopithecus_brelichi),Pygathrix_nigripes)),Rhinopithecus_roxellana),((Rhinopithecus_avunculus,((Piliocolobus_badius,((Trachypithecus_pileatus,((Trachypithecus_johnii,Trachypithecus_cristatus),Trachypithecus_francoisi)),Procolobus_verus)),Trachypithecus_obscurus)),Presbytis_melalophos)),Semnopithecus_entellus),(((Cercopithecus_diana,(((((((Cercopithecus_albogularis_francescae,Cercopithecus_mitis_heymansi),(((Cercopithecus_albogularis,(Cercopithecus_albogularis_labiatus,((Cercopithecus_albogularis_albotorquatus,(Cercopithecus_albogularis_erythrarchus,Cercopithecus_albogularis_monoides)),Cercopithecus_mitis_boutourlinii))),(((((Cercopithecus_erythrotis_camerunensis,(((Cercopithecus_petaurista,(Cercopithecus_petaurista_buettikoferi,Cercopithecus_petaurista_petaurista)),(Cercopithecus_cephus_cephus,Cercopithecus_ascanius_katangae)),(Cercopithecus_erythrogaster_pococki,Cercopithecus_erythrogaster))),(Cercopithecus_ascanius_whitesidei,Cercopithecus_ascanius_schmidti)),(Cercopithecus_lhoesti,(Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi))),Cercopithecus_cephus),(Cercopithecus_cephus_ngottoensis,Cercopithecus_albogularis_moloneyi))),(((((((Cercopithecus_nictitans_nictitans,Cercopithecus_mitis),Cercopithecus_nictitans),Cercopithecus_doggetti),Cercopithecus_mitis_mitis),Cercopithecus_mitis_opisthostictus),(Cercopithecus_mitis_stuhlmanni,Cercopithecus_albogularis_kolbi)),Cercopithecus_kandti))),Cercopithecus_aethiops),(((Cercopithecus_mona,Cercopithecus_campbelli),((((Cercopithecus_pogonias_grayi,(Cercopithecus_wolfi_pyrogaster,(Cercopithecus_pogonias_nigripes,Cercopithecus_pogonias_schwarzianus))),Cercopithecus_wolfi_elegans),Cercopithecus_pogonias),Cercopithecus_neglectus)),Chlorocebus_sabaeus)),Chlorocebus_pygerythrus),((Chlorocebus_cynosuros,(Cercopithecus_dryas,Chlorocebus_tantalus)),((Cercopithecus_hamlyni,Chlorocebus_aethiops),Cercopithecus_nictitans_martini))),(Cercopithecus_solatus,((Erythrocebus_patas,((((Cercocebus_chrysogaster,((Mandrillus_leucophaeus,((Lophocebus_albigena,Lophocebus_aterrimus),Cercocebus_agilis)),Theropithecus_gelada)),(Cercocebus_torquatus,Cercocebus_atys)),(Allenopithecus_nigroviridis,((((Cercopithecus_roloway,Macaca_tonkeana),(((Macaca_nemestrina,((Macaca_mulatta,Macaca_fuscata),Macaca_nigra)),Macaca_arctoides),(Macaca_sylvanus,(Macaca_thibetana,Macaca_assamensis)))),Macaca_silenus),Macaca_fascicularis))),(((Papio_kindae,((Papio_hamadryas,(Papio_anubis,Rungwecebus_kipunji)),Papio_ursinus)),Papio_papio),Papio_cynocephalus))),Mandrillus_sphinx)))),Miopithecus_talapoin),Miopithecus_ogouensis)),(((Alouatta_caraya,((((Ateles_belzebuth,(Callicebus_cupreus,Callicebus_lugens)),(((((Cebus_apella,Sapajus_xanthosternos),((Aotus_nancymaae,((Saimiri_sciureus_macrodon,((Saimiri_boliviensis,Saimiri_oerstedii),Saimiri_sciureus)),Saimiri_oerstedii_citrinellus)),(Cacajao_calvus,(Chiropotes_albinasus,Chiropotes_israelita)))),((Ateles_geoffroyi,Ateles_paniscus),Cebus_albifrons)),(Callicebus_donacophilus,Brachyteles_arachnoides)),Lagothrix_lagotricha)),(Leontopithecus_rosalia,(((Aotus_azarae,Aotus_azarae_azarai),(Aotus_lemurinus,Aotus_azarai)),Aotus_trivirgatus))),((Callithrix_jacchus,(Callithrix_pygmaea,Saguinus_oedipus)),Pithecia_pithecia))),Callimico_goeldii),((Galago_senegalensis,(Tarsius_bancanus,((Varecia_variegata,Varecia_rubra),Lemur_catta))),((((Tarsius_dentatus,Tarsius_lariang),Tarsius_wallacei),Tarsius_syrichta),(((Megaladapis_edwardsi,((Eulemur_rufus,(((Lepilemur_hubbardorum,Lepilemur_ruficaudatus),Indri_indri),Palaeopropithecus_ingens)),(((Eulemur_fulvus,(Eulemur_rubriventer,(Prolemur_simus,(Cheirogaleus_medius,(Nycticebus_pygmaeus,Hapalemur_griseus))))),Eulemur_mongoz),Eulemur_macaco))),(Propithecus_verreauxi,(Propithecus_coquereli,Avahi_laniger))),(Daubentonia_madagascariensis,(((Otolemur_garnettii,((((Loris_tardigradus,Galagoides_demidoff),Loris_lydekkerianus),(Nycticebus_bengalensis,Nycticebus_coucang)),Galago_moholi)),(Perodicticus_potto_edwarsi,Perodicticus_potto)),Otolemur_crassicaudatus))))))),(Gorilla_gorilla,Gorilla_gorilla_gorilla))),Homo_sapiens_ssp_Denisova),Pan_troglodytes_ellioti),(((Pan_troglodytes_troglodytes,Pan_paniscus),Pan_troglodytes),Homo_heidelbergensis),Homo_sapiens); +((Pan_troglodytes,(Pan_troglodytes_troglodytes,Pan_paniscus)),((Homo_heidelbergensis,((Gorilla_gorilla_gorilla,((((((Symphalangus_syndactylus,Hylobates_lar),Hylobates_agilis),Nomascus_leucogenys),Hylobates_moloch),(Pongo_pygmaeus,Pongo_abelii)),(Homo_sapiens_ssp_Denisova,(((((((Pygathrix_nemaeus,Trachypithecus_pileatus),((Trachypithecus_johnii,Trachypithecus_cristatus),(Rhinopithecus_bieti_2_RL2012,((((((Trachypithecus_francoisi,Nasalis_larvatus),Rhinopithecus_brelichi),Simias_concolor),Trachypithecus_obscurus),Rhinopithecus_roxellana),Pygathrix_nigripes)))),(Presbytis_melalophos,Semnopithecus_entellus)),Rhinopithecus_avunculus),(Procolobus_verus,(Colobus_satanas,(Piliocolobus_badius,Colobus_guereza)))),((Miopithecus_talapoin,((Cercopithecus_neglectus,((((Cercopithecus_dryas,((Chlorocebus_cynosuros,((Cercopithecus_hamlyni,Chlorocebus_aethiops),Chlorocebus_tantalus)),Chlorocebus_pygerythrus)),Cercopithecus_solatus),Chlorocebus_sabaeus),Cercopithecus_aethiops)),(Cercopithecus_albogularis_francescae,((Cercopithecus_albogularis,Cercopithecus_mitis_heymansi),((Cercopithecus_kandti,(((((Cercopithecus_cephus_ngottoensis,(((Cercopithecus_petaurista,((((Cercopithecus_ascanius_whitesidei,Cercopithecus_cephus_cephus),((Cercopithecus_erythrotis_camerunensis,((Cercopithecus_petaurista_buettikoferi,Cercopithecus_petaurista_petaurista),Cercopithecus_erythrogaster_pococki)),Cercopithecus_erythrogaster)),Cercopithecus_ascanius_katangae),(Cercopithecus_lhoesti,(Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi)))),Cercopithecus_cephus),Cercopithecus_ascanius_schmidti)),(((Cercopithecus_albogularis_albotorquatus,Cercopithecus_albogularis_monoides),((Cercopithecus_albogularis_labiatus,Cercopithecus_albogularis_erythrarchus),Cercopithecus_mitis_boutourlinii)),(Cercopithecus_mitis_mitis,Cercopithecus_mitis_opisthostictus))),(Cercopithecus_albogularis_moloneyi,((Cercopithecus_nictitans_nictitans,Cercopithecus_nictitans),Cercopithecus_albogularis_kolbi))),Cercopithecus_mitis_stuhlmanni),Cercopithecus_doggetti)),Cercopithecus_mitis))))),((Cercopithecus_diana,((Miopithecus_ogouensis,(Cercopithecus_mona,Cercopithecus_campbelli)),(Cercopithecus_pogonias,(((Cercopithecus_pogonias_grayi,(Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans)),(Cercopithecus_pogonias_schwarzianus,Cercopithecus_pogonias_nigripes)),Cercopithecus_nictitans_martini)))),(((((Cercocebus_atys,Cercocebus_torquatus),Mandrillus_sphinx),(Cercocebus_chrysogaster,(((Theropithecus_gelada,(Lophocebus_albigena,Lophocebus_aterrimus)),Cercocebus_agilis),Mandrillus_leucophaeus))),((Erythrocebus_patas,(Macaca_silenus,(((((((((Macaca_mulatta,Macaca_fuscata),Macaca_arctoides),Allenopithecus_nigroviridis),Macaca_sylvanus),Macaca_nemestrina),Macaca_nigra),(Macaca_thibetana,Macaca_assamensis)),Macaca_fascicularis),Macaca_tonkeana))),Cercopithecus_roloway)),(Papio_kindae,(Papio_papio,(Papio_cynocephalus,(Rungwecebus_kipunji,((Papio_anubis,Papio_ursinus),Papio_hamadryas))))))))),((Alouatta_caraya,(((((((Aotus_trivirgatus,(((Aotus_lemurinus,Aotus_azarai),(Aotus_nancymaae,Aotus_azarae)),Aotus_azarae_azarai)),(((Saimiri_boliviensis,(Saimiri_oerstedii,Saimiri_sciureus)),Saimiri_sciureus_macrodon),Saimiri_oerstedii_citrinellus)),(Leontopithecus_rosalia,((((Ateles_belzebuth,Callimico_goeldii),Ateles_geoffroyi),((Callicebus_donacophilus,Ateles_paniscus),Callicebus_cupreus)),Callicebus_lugens))),((Lagothrix_lagotricha,(Cacajao_calvus,((Brachyteles_arachnoides,Chiropotes_albinasus),Chiropotes_israelita))),(Sapajus_xanthosternos,(Cebus_apella,Cebus_albifrons)))),Pithecia_pithecia),(Callithrix_jacchus,Callithrix_pygmaea)),Saguinus_oedipus)),(Propithecus_coquereli,((((((Lepilemur_hubbardorum,Lepilemur_ruficaudatus),Indri_indri),(Palaeopropithecus_ingens,(Eulemur_rufus,(((Eulemur_macaco,(Eulemur_rubriventer,(Prolemur_simus,(Hapalemur_griseus,(Eulemur_fulvus,Cheirogaleus_medius))))),Eulemur_mongoz),Nycticebus_pygmaeus)))),(((Galagoides_demidoff,(Otolemur_crassicaudatus,(Propithecus_verreauxi,((Loris_tardigradus,Loris_lydekkerianus),Galago_moholi)))),Nycticebus_bengalensis),(((Perodicticus_potto_edwarsi,Perodicticus_potto),Nycticebus_coucang),Otolemur_garnettii))),(Daubentonia_madagascariensis,(Galago_senegalensis,((Varecia_rubra,(Varecia_variegata,Lemur_catta)),Tarsius_bancanus)))),(Avahi_laniger,(Megaladapis_edwardsi,((Tarsius_dentatus,(Tarsius_lariang,Tarsius_wallacei)),Tarsius_syrichta)))))))))),Gorilla_gorilla)),Pan_troglodytes_ellioti),Homo_sapiens); +((((((((Miopithecus_ogouensis,((((Procolobus_verus,((Colobus_satanas,Colobus_guereza),Piliocolobus_badius)),(((Rhinopithecus_avunculus,Trachypithecus_johnii),(Presbytis_melalophos,Semnopithecus_entellus)),((Trachypithecus_pileatus,((Trachypithecus_obscurus,Trachypithecus_francoisi),Trachypithecus_cristatus)),(((Rhinopithecus_brelichi,Rhinopithecus_bieti_2_RL2012),Rhinopithecus_roxellana),(Pygathrix_nemaeus,((Simias_concolor,Nasalis_larvatus),Pygathrix_nigripes)))))),Miopithecus_talapoin),((((((Cercopithecus_albogularis_francescae,((Cercopithecus_albogularis,Cercopithecus_mitis_heymansi),((Cercopithecus_mitis_opisthostictus,Cercopithecus_mitis_mitis),((((Cercopithecus_mitis_stuhlmanni,(Cercopithecus_albogularis_moloneyi,((Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis),(((Cercopithecus_lhoesti,(Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi)),(((Cercopithecus_erythrotis_camerunensis,Cercopithecus_ascanius_katangae),(Cercopithecus_cephus_cephus,(Cercopithecus_petaurista,(((Cercopithecus_petaurista_buettikoferi,Cercopithecus_petaurista_petaurista),Cercopithecus_erythrogaster_pococki),Cercopithecus_erythrogaster)))),Cercopithecus_ascanius_whitesidei)),Cercopithecus_ascanius_schmidti)))),(((Cercopithecus_nictitans_nictitans,Cercopithecus_nictitans),Cercopithecus_albogularis_kolbi),Cercopithecus_kandti)),(Cercopithecus_mitis,Cercopithecus_doggetti)),(Cercopithecus_albogularis_monoides,(Cercopithecus_albogularis_labiatus,((Cercopithecus_albogularis_erythrarchus,Cercopithecus_albogularis_albotorquatus),Cercopithecus_mitis_boutourlinii))))))),((((Cercopithecus_dryas,(((Chlorocebus_pygerythrus,Chlorocebus_tantalus),Chlorocebus_cynosuros),(Cercopithecus_hamlyni,Chlorocebus_aethiops))),Cercopithecus_solatus),Chlorocebus_sabaeus),Cercopithecus_aethiops)),Cercopithecus_neglectus),Cercopithecus_roloway),((Cercopithecus_mona,Cercopithecus_campbelli),(((Cercopithecus_pogonias_grayi,Cercopithecus_pogonias_schwarzianus),(((Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans),Cercopithecus_nictitans_martini),Cercopithecus_pogonias_nigripes)),Cercopithecus_pogonias))),(Cercopithecus_diana,(Erythrocebus_patas,(((((((((Macaca_mulatta,Macaca_fuscata),Macaca_arctoides),Allenopithecus_nigroviridis),(Macaca_nemestrina,Macaca_nigra)),Macaca_sylvanus),(Macaca_thibetana,Macaca_assamensis)),Macaca_fascicularis),(Macaca_tonkeana,Macaca_silenus)),(((((Papio_ursinus,(Papio_cynocephalus,Papio_kindae)),(Papio_papio,(Papio_anubis,Papio_hamadryas))),Rungwecebus_kipunji),((Lophocebus_albigena,Lophocebus_aterrimus),Theropithecus_gelada)),(Cercocebus_chrysogaster,(((Cercocebus_torquatus,(Mandrillus_sphinx,Cercocebus_atys)),Mandrillus_leucophaeus),Cercocebus_agilis))))))))),((((Saimiri_sciureus_macrodon,(Saimiri_sciureus,(Saimiri_oerstedii,Saimiri_boliviensis))),Saimiri_oerstedii_citrinellus),(((Aotus_nancymaae,((Aotus_azarae_azarai,Aotus_trivirgatus),Aotus_azarae)),(Aotus_lemurinus,Aotus_azarai)),(((Cebus_albifrons,(Sapajus_xanthosternos,Cebus_apella)),(((Callicebus_cupreus,(Ateles_belzebuth,Callicebus_donacophilus)),Brachyteles_arachnoides),Callicebus_lugens)),(((Alouatta_caraya,(Callimico_goeldii,Leontopithecus_rosalia)),((Lagothrix_lagotricha,Pithecia_pithecia),((Saguinus_oedipus,((Callithrix_jacchus,Ateles_geoffroyi),Ateles_paniscus)),Callithrix_pygmaea))),(Cacajao_calvus,(Chiropotes_albinasus,Chiropotes_israelita)))))),((((Tarsius_lariang,(Tarsius_wallacei,Tarsius_dentatus)),Tarsius_syrichta),((((Nycticebus_pygmaeus,(Indri_indri,(Lepilemur_hubbardorum,Lepilemur_ruficaudatus))),((((Hapalemur_griseus,(((Megaladapis_edwardsi,Cheirogaleus_medius),Eulemur_macaco),Eulemur_rubriventer)),(((Eulemur_fulvus,Eulemur_rufus),Eulemur_mongoz),Perodicticus_potto)),(Palaeopropithecus_ingens,Prolemur_simus)),(Propithecus_coquereli,(Perodicticus_potto_edwarsi,((Galago_senegalensis,(Otolemur_crassicaudatus,((Galagoides_demidoff,Otolemur_garnettii),Galago_moholi))),(Propithecus_verreauxi,((Nycticebus_bengalensis,Nycticebus_coucang),(Loris_tardigradus,Loris_lydekkerianus)))))))),Avahi_laniger),Daubentonia_madagascariensis)),(Tarsius_bancanus,(Lemur_catta,(Varecia_rubra,Varecia_variegata)))))),(((((Nomascus_leucogenys,((Symphalangus_syndactylus,Hylobates_agilis),Hylobates_moloch)),Hylobates_lar),(Pongo_pygmaeus,Pongo_abelii)),Gorilla_gorilla_gorilla),Gorilla_gorilla)),Homo_heidelbergensis),Homo_sapiens_ssp_Denisova),Pan_troglodytes_ellioti),Pan_troglodytes_troglodytes),(Pan_paniscus,Pan_troglodytes),Homo_sapiens); +((((Pan_paniscus,Pan_troglodytes_troglodytes),Pan_troglodytes),((Homo_sapiens_ssp_Denisova,(((Miopithecus_ogouensis,((((Procolobus_verus,(Trachypithecus_johnii,((Colobus_satanas,Colobus_guereza),Piliocolobus_badius))),((((Trachypithecus_obscurus,Trachypithecus_francoisi),(Trachypithecus_cristatus,Trachypithecus_pileatus)),(((Pygathrix_nemaeus,((Simias_concolor,Nasalis_larvatus),Pygathrix_nigripes)),(Rhinopithecus_roxellana,Rhinopithecus_bieti_2_RL2012)),Rhinopithecus_brelichi)),((Semnopithecus_entellus,Presbytis_melalophos),Rhinopithecus_avunculus))),Miopithecus_talapoin),((((Cercopithecus_aethiops,(Cercopithecus_albogularis_francescae,(Cercopithecus_mitis_heymansi,(((Cercopithecus_kandti,((Cercopithecus_nictitans_nictitans,(Cercopithecus_nictitans,Cercopithecus_albogularis_kolbi)),Cercopithecus_mitis_stuhlmanni)),((Cercopithecus_doggetti,Cercopithecus_mitis_mitis),Cercopithecus_mitis_opisthostictus)),(((Cercopithecus_albogularis_albotorquatus,((Cercopithecus_albogularis_labiatus,(Cercopithecus_mitis_boutourlinii,Cercopithecus_albogularis_erythrarchus)),(Cercopithecus_albogularis,Cercopithecus_albogularis_monoides))),(Cercopithecus_albogularis_moloneyi,((Cercopithecus_ascanius_schmidti,Cercopithecus_cephus_ngottoensis),(Cercopithecus_cephus,(Cercopithecus_cephus_cephus,((((Cercopithecus_erythrogaster_pococki,Cercopithecus_erythrogaster),Cercopithecus_petaurista),(Cercopithecus_petaurista_buettikoferi,Cercopithecus_petaurista_petaurista)),(((Cercopithecus_lhoesti,(Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi)),(Cercopithecus_erythrotis_camerunensis,Cercopithecus_ascanius_katangae)),Cercopithecus_ascanius_whitesidei))))))),Cercopithecus_mitis))))),(((((Chlorocebus_tantalus,(Cercopithecus_hamlyni,Chlorocebus_aethiops)),Chlorocebus_cynosuros),Chlorocebus_pygerythrus),(Cercopithecus_solatus,Cercopithecus_dryas)),Chlorocebus_sabaeus)),Cercopithecus_neglectus),(Cercopithecus_roloway,(((((((Papio_papio,(Papio_anubis,Papio_hamadryas)),(Papio_ursinus,Papio_cynocephalus)),Papio_kindae),(((Lophocebus_aterrimus,Lophocebus_albigena),Rungwecebus_kipunji),Theropithecus_gelada)),((((Cercocebus_agilis,(Mandrillus_sphinx,Cercocebus_atys)),Mandrillus_leucophaeus),Cercocebus_chrysogaster),Cercocebus_torquatus)),(((Macaca_thibetana,Macaca_assamensis),(Macaca_tonkeana,((((Macaca_fascicularis,Macaca_fuscata),((Macaca_sylvanus,Allenopithecus_nigroviridis),Macaca_mulatta)),Macaca_arctoides),(Macaca_nemestrina,Macaca_nigra)))),Macaca_silenus)),((Cercopithecus_diana,((Cercopithecus_mona,Cercopithecus_campbelli),(((Cercopithecus_nictitans_martini,(Cercopithecus_wolfi_pyrogaster,Cercopithecus_wolfi_elegans)),((Cercopithecus_pogonias_grayi,Cercopithecus_pogonias_schwarzianus),Cercopithecus_pogonias_nigripes)),Cercopithecus_pogonias))),Erythrocebus_patas)))))),((((Saimiri_sciureus,(Saimiri_sciureus_macrodon,(Saimiri_oerstedii,Saimiri_boliviensis))),Saimiri_oerstedii_citrinellus),((Aotus_nancymaae,((((Alouatta_caraya,(Callimico_goeldii,((Ateles_geoffroyi,Saguinus_oedipus),(Callithrix_pygmaea,Callithrix_jacchus)))),((Sapajus_xanthosternos,(Cebus_apella,Cebus_albifrons)),((((Lagothrix_lagotricha,Chiropotes_israelita),Chiropotes_albinasus),Cacajao_calvus),(Pithecia_pithecia,((Callicebus_cupreus,(Ateles_paniscus,(Callicebus_donacophilus,(Ateles_belzebuth,Brachyteles_arachnoides)))),Callicebus_lugens))))),Leontopithecus_rosalia),Aotus_azarae_azarai)),((Aotus_trivirgatus,Aotus_azarae),(Aotus_lemurinus,Aotus_azarai)))),((((((Lepilemur_ruficaudatus,(Indri_indri,Lepilemur_hubbardorum)),(Propithecus_coquereli,(Eulemur_mongoz,(Eulemur_rubriventer,Avahi_laniger)))),(Eulemur_fulvus,((((Hapalemur_griseus,Nycticebus_pygmaeus),(Megaladapis_edwardsi,Cheirogaleus_medius)),((Propithecus_verreauxi,(Eulemur_macaco,Eulemur_rufus)),Palaeopropithecus_ingens)),(Prolemur_simus,(((Nycticebus_bengalensis,Nycticebus_coucang),(Loris_tardigradus,Loris_lydekkerianus)),(Perodicticus_potto_edwarsi,((Otolemur_crassicaudatus,((Galago_senegalensis,Galago_moholi),Otolemur_garnettii)),Galagoides_demidoff))))))),(Perodicticus_potto,Daubentonia_madagascariensis)),(Tarsius_syrichta,((Tarsius_dentatus,Tarsius_wallacei),Tarsius_lariang))),(Tarsius_bancanus,(Lemur_catta,(Varecia_rubra,Varecia_variegata)))))),((((Hylobates_agilis,((Hylobates_moloch,(Nomascus_leucogenys,Symphalangus_syndactylus)),Hylobates_lar)),(Pongo_pygmaeus,Pongo_abelii)),Gorilla_gorilla_gorilla),Gorilla_gorilla))),Homo_heidelbergensis)),Pan_troglodytes_ellioti,Homo_sapiens); +(((((((((Hylobates_moloch,Symphalangus_syndactylus),Hylobates_lar),Nomascus_leucogenys),Hylobates_agilis),(Pongo_pygmaeus,Pongo_abelii)),((((Miopithecus_ogouensis,(((((Rhinopithecus_avunculus,Presbytis_melalophos),Semnopithecus_entellus),((((Trachypithecus_johnii,(Trachypithecus_cristatus,Trachypithecus_francoisi)),Trachypithecus_pileatus),Trachypithecus_obscurus),((Pygathrix_nemaeus,((Simias_concolor,Nasalis_larvatus),Pygathrix_nigripes)),(Rhinopithecus_roxellana,(Rhinopithecus_brelichi,Rhinopithecus_bieti_2_RL2012))))),(Procolobus_verus,((Colobus_satanas,Colobus_guereza),Piliocolobus_badius))),(Miopithecus_talapoin,(((((Cercopithecus_aethiops,(Cercopithecus_albogularis_francescae,(Cercopithecus_mitis_heymansi,((((((Cercopithecus_albogularis_monoides,((Cercopithecus_mitis_boutourlinii,Cercopithecus_albogularis_labiatus),Cercopithecus_albogularis_erythrarchus)),Cercopithecus_albogularis),((Cercopithecus_albogularis_moloneyi,((Cercopithecus_ascanius_schmidti,Cercopithecus_cephus_ngottoensis),(Cercopithecus_cephus,((((Cercopithecus_erythrotis_camerunensis,Cercopithecus_ascanius_katangae),((((Cercopithecus_petaurista_buettikoferi,Cercopithecus_petaurista_petaurista),Cercopithecus_erythrogaster_pococki),Cercopithecus_erythrogaster),Cercopithecus_cephus_cephus)),Cercopithecus_petaurista),((Cercopithecus_lhoesti,(Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi)),Cercopithecus_ascanius_whitesidei))))),Cercopithecus_albogularis_albotorquatus)),((Cercopithecus_mitis_mitis,Cercopithecus_mitis_opisthostictus),(Cercopithecus_nictitans_nictitans,Cercopithecus_nictitans))),(Cercopithecus_mitis,(Cercopithecus_albogularis_kolbi,Cercopithecus_mitis_stuhlmanni))),(Cercopithecus_kandti,Cercopithecus_doggetti))))),(((Chlorocebus_tantalus,(((Cercopithecus_hamlyni,Chlorocebus_aethiops),Chlorocebus_pygerythrus),Chlorocebus_cynosuros)),Cercopithecus_dryas),Chlorocebus_sabaeus)),Cercopithecus_solatus),Cercopithecus_neglectus),(Cercopithecus_roloway,(((Cercopithecus_mona,Cercopithecus_campbelli),(Cercopithecus_pogonias_grayi,(Cercopithecus_pogonias_schwarzianus,((Cercopithecus_wolfi_elegans,(Cercopithecus_pogonias,(Cercopithecus_wolfi_pyrogaster,Cercopithecus_nictitans_martini))),Cercopithecus_pogonias_nigripes)))),(((Erythrocebus_patas,(((Rungwecebus_kipunji,(Papio_kindae,((Papio_papio,(Papio_anubis,Papio_hamadryas)),(Papio_cynocephalus,Papio_ursinus)))),(Theropithecus_gelada,Lophocebus_aterrimus)),(Cercocebus_chrysogaster,(Cercocebus_torquatus,((((Lophocebus_albigena,Mandrillus_sphinx),Cercocebus_atys),Mandrillus_leucophaeus),Cercocebus_agilis))))),(((Macaca_thibetana,Macaca_assamensis),((Macaca_fascicularis,(Macaca_arctoides,((Macaca_nemestrina,((Macaca_mulatta,Macaca_fuscata),Macaca_nigra)),(Macaca_sylvanus,Allenopithecus_nigroviridis)))),Macaca_tonkeana)),Macaca_silenus)),Cercopithecus_diana))))))),((Alouatta_caraya,(((((((Lagothrix_lagotricha,(((Brachyteles_arachnoides,(Callicebus_donacophilus,((Ateles_geoffroyi,(Callithrix_jacchus,Ateles_belzebuth)),Ateles_paniscus))),Callicebus_cupreus),Callicebus_lugens)),(Cebus_albifrons,(Sapajus_xanthosternos,Cebus_apella))),(Pithecia_pithecia,Chiropotes_israelita)),(Chiropotes_albinasus,Cacajao_calvus)),((Aotus_nancymaae,Leontopithecus_rosalia),((((Aotus_lemurinus,Aotus_azarai),(Aotus_azarae_azarai,Aotus_trivirgatus)),Aotus_azarae),((Saimiri_sciureus_macrodon,(Saimiri_sciureus,(Saimiri_oerstedii,Saimiri_boliviensis))),Saimiri_oerstedii_citrinellus)))),Callimico_goeldii),(Callithrix_pygmaea,Saguinus_oedipus))),(((((Nycticebus_pygmaeus,((((Otolemur_garnettii,(((Nycticebus_coucang,Perodicticus_potto),Perodicticus_potto_edwarsi),Otolemur_crassicaudatus)),Nycticebus_bengalensis),(Loris_lydekkerianus,(Galagoides_demidoff,Loris_tardigradus))),Galago_moholi)),(Propithecus_verreauxi,(((Megaladapis_edwardsi,(Daubentonia_madagascariensis,((Eulemur_rubriventer,Avahi_laniger),((Lepilemur_ruficaudatus,Lepilemur_hubbardorum),Indri_indri)))),(Eulemur_macaco,(Palaeopropithecus_ingens,(Eulemur_mongoz,Eulemur_rufus)))),((Galago_senegalensis,Prolemur_simus),(Cheirogaleus_medius,Hapalemur_griseus))))),(Propithecus_coquereli,(Tarsius_syrichta,((Tarsius_dentatus,Tarsius_wallacei),Tarsius_lariang)))),Eulemur_fulvus),(((Varecia_variegata,Varecia_rubra),Tarsius_bancanus),Lemur_catta)))),Gorilla_gorilla_gorilla),Homo_sapiens_ssp_Denisova)),Gorilla_gorilla),Homo_heidelbergensis),(((Pan_paniscus,Pan_troglodytes_troglodytes),Pan_troglodytes),Pan_troglodytes_ellioti),Homo_sapiens); +((Gorilla_gorilla_gorilla,(Gorilla_gorilla,(((Hylobates_agilis,((Pongo_pygmaeus,Pongo_abelii),(Symphalangus_syndactylus,Hylobates_lar))),(Hylobates_moloch,Nomascus_leucogenys)),((((Rhinopithecus_avunculus,(((Trachypithecus_pileatus,((Rhinopithecus_bieti_2_RL2012,((Trachypithecus_johnii,((Pygathrix_nigripes,((Simias_concolor,(Trachypithecus_cristatus,(Pygathrix_nemaeus,Trachypithecus_francoisi))),Rhinopithecus_brelichi)),Rhinopithecus_roxellana)),Nasalis_larvatus)),Trachypithecus_obscurus)),Presbytis_melalophos),((Colobus_satanas,Colobus_guereza),(Piliocolobus_badius,Procolobus_verus)))),Semnopithecus_entellus),(Miopithecus_ogouensis,((((Erythrocebus_patas,(((Cercopithecus_dryas,(((Chlorocebus_aethiops,(Chlorocebus_tantalus,Chlorocebus_pygerythrus)),(Chlorocebus_cynosuros,Cercopithecus_hamlyni)),((Cercopithecus_aethiops,Cercopithecus_solatus),Chlorocebus_sabaeus))),(Allenopithecus_nigroviridis,((((Cercopithecus_albogularis_francescae,(Cercopithecus_mitis,Cercopithecus_doggetti)),((Cercopithecus_albogularis_kolbi,Cercopithecus_mitis_stuhlmanni),Cercopithecus_mitis_heymansi)),Cercopithecus_kandti),((Cercopithecus_nictitans,Cercopithecus_nictitans_nictitans),(((((((Cercopithecus_albogularis_moloneyi,(Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis)),(Cercopithecus_ascanius_schmidti,(((((Cercopithecus_erythrogaster_pococki,Cercopithecus_erythrogaster),Cercopithecus_cephus_cephus),((Cercopithecus_petaurista_buettikoferi,Cercopithecus_petaurista_petaurista),Cercopithecus_petaurista)),(Cercopithecus_erythrotis_camerunensis,Cercopithecus_ascanius_katangae)),((Cercopithecus_lhoesti,(Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi)),Cercopithecus_ascanius_whitesidei)))),Cercopithecus_albogularis_albotorquatus),Cercopithecus_albogularis_monoides),(Cercopithecus_mitis_boutourlinii,(Cercopithecus_albogularis_labiatus,Cercopithecus_albogularis_erythrarchus))),Cercopithecus_albogularis),(Cercopithecus_mitis_mitis,Cercopithecus_mitis_opisthostictus)))))),(Cercopithecus_roloway,(((Cercopithecus_mona,Cercopithecus_campbelli),(Cercopithecus_pogonias_grayi,((Cercopithecus_pogonias,(Cercopithecus_nictitans_martini,Cercopithecus_wolfi_pyrogaster)),((Cercopithecus_pogonias_schwarzianus,Cercopithecus_wolfi_elegans),Cercopithecus_pogonias_nigripes)))),Cercopithecus_neglectus)))),(((Lophocebus_albigena,((Papio_kindae,((Papio_papio,(Papio_anubis,Papio_hamadryas)),((Rungwecebus_kipunji,Papio_cynocephalus),Papio_ursinus))),(Theropithecus_gelada,Lophocebus_aterrimus))),((Cercocebus_chrysogaster,(Mandrillus_leucophaeus,((Mandrillus_sphinx,Cercocebus_atys),Cercocebus_agilis))),Cercocebus_torquatus)),((Macaca_fascicularis,(Macaca_arctoides,((Macaca_sylvanus,(Macaca_thibetana,Macaca_assamensis)),(Macaca_nemestrina,((Macaca_mulatta,Macaca_fuscata),Macaca_nigra))))),(Macaca_silenus,Macaca_tonkeana)))),Cercopithecus_diana),Miopithecus_talapoin))),(((Ateles_geoffroyi,(Callithrix_pygmaea,Saguinus_oedipus)),((Callimico_goeldii,Alouatta_caraya),(Callithrix_jacchus,((((Lagothrix_lagotricha,(((Chiropotes_israelita,(Brachyteles_arachnoides,Chiropotes_albinasus)),(Ateles_belzebuth,((Cacajao_calvus,Pithecia_pithecia),Callicebus_donacophilus))),Ateles_paniscus)),(Cebus_albifrons,(Sapajus_xanthosternos,Cebus_apella))),(Callicebus_lugens,Callicebus_cupreus)),((Aotus_trivirgatus,((Aotus_azarae_azarai,Aotus_lemurinus),Aotus_azarai)),(Aotus_azarae,(Aotus_nancymaae,(Leontopithecus_rosalia,((Saimiri_sciureus_macrodon,((Saimiri_oerstedii,Saimiri_sciureus),Saimiri_boliviensis)),Saimiri_oerstedii_citrinellus))))))))),(((Tarsius_bancanus,((Varecia_rubra,Varecia_variegata),Lemur_catta)),Eulemur_fulvus),((((Perodicticus_potto_edwarsi,(((Eulemur_macaco,((Nycticebus_pygmaeus,(Galagoides_demidoff,(Loris_lydekkerianus,Loris_tardigradus))),(Nycticebus_bengalensis,Nycticebus_coucang))),Otolemur_crassicaudatus),(Perodicticus_potto,Galago_moholi))),((Galago_senegalensis,(((((Indri_indri,(Lepilemur_ruficaudatus,Lepilemur_hubbardorum)),Avahi_laniger),((Megaladapis_edwardsi,(Eulemur_rufus,(Prolemur_simus,(Hapalemur_griseus,((Propithecus_verreauxi,Cheirogaleus_medius),Eulemur_mongoz))))),Palaeopropithecus_ingens)),Propithecus_coquereli),Daubentonia_madagascariensis)),Eulemur_rubriventer)),Otolemur_garnettii),(Tarsius_syrichta,((Tarsius_wallacei,Tarsius_dentatus),Tarsius_lariang))))))))),((Homo_sapiens_ssp_Denisova,(Pan_troglodytes_ellioti,(Pan_troglodytes_troglodytes,(Pan_paniscus,Pan_troglodytes)))),Homo_heidelbergensis),Homo_sapiens); +((Homo_heidelbergensis,((Gorilla_gorilla,((((Pongo_pygmaeus,Pongo_abelii),((Hylobates_lar,(Hylobates_agilis,Symphalangus_syndactylus)),(Hylobates_moloch,Nomascus_leucogenys))),(((((Presbytis_melalophos,(((Colobus_satanas,Colobus_guereza),((((Simias_concolor,Nasalis_larvatus),(Pygathrix_nemaeus,Pygathrix_nigripes)),Rhinopithecus_roxellana),(Rhinopithecus_bieti_2_RL2012,Rhinopithecus_brelichi))),((Trachypithecus_cristatus,(Trachypithecus_obscurus,Trachypithecus_francoisi)),Trachypithecus_pileatus))),Rhinopithecus_avunculus),(Trachypithecus_johnii,Semnopithecus_entellus)),(Procolobus_verus,Piliocolobus_badius)),(((((Allenopithecus_nigroviridis,(((Cercocebus_chrysogaster,((Cercocebus_torquatus,(Mandrillus_sphinx,Cercocebus_atys)),Mandrillus_leucophaeus)),Cercocebus_agilis),((((Macaca_arctoides,(Macaca_sylvanus,(Macaca_thibetana,Macaca_assamensis))),(Macaca_nemestrina,((Macaca_mulatta,Macaca_fuscata),Macaca_nigra))),((Macaca_fascicularis,Macaca_silenus),Macaca_tonkeana)),(((Theropithecus_gelada,Rungwecebus_kipunji),(((Papio_papio,Papio_cynocephalus),Papio_kindae),((Papio_ursinus,Papio_anubis),Papio_hamadryas))),(Lophocebus_aterrimus,Lophocebus_albigena))))),Erythrocebus_patas),(((Cercopithecus_dryas,(((Cercopithecus_aethiops,Chlorocebus_sabaeus),((((Cercopithecus_hamlyni,Chlorocebus_aethiops),Chlorocebus_tantalus),Chlorocebus_cynosuros),Chlorocebus_pygerythrus)),Cercopithecus_solatus)),((((Cercopithecus_doggetti,(Cercopithecus_mitis_stuhlmanni,Cercopithecus_kandti)),((Cercopithecus_nictitans,(Cercopithecus_nictitans_martini,Cercopithecus_nictitans_nictitans)),((Cercopithecus_mitis_mitis,Cercopithecus_mitis_opisthostictus),(((((Cercopithecus_ascanius_schmidti,((Cercopithecus_ascanius_katangae,((Cercopithecus_cephus_cephus,((Cercopithecus_petaurista_petaurista,(Cercopithecus_erythrogaster_pococki,Cercopithecus_erythrogaster)),(Cercopithecus_petaurista_buettikoferi,Cercopithecus_petaurista))),Cercopithecus_erythrotis_camerunensis)),((Cercopithecus_lhoesti,(Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi)),Cercopithecus_ascanius_whitesidei))),(Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis)),Cercopithecus_albogularis_moloneyi),((Cercopithecus_mitis_boutourlinii,Cercopithecus_albogularis_albotorquatus),(Cercopithecus_albogularis_erythrarchus,(Cercopithecus_albogularis_labiatus,Cercopithecus_albogularis_monoides)))),Cercopithecus_albogularis_kolbi)))),Cercopithecus_mitis),(Cercopithecus_mitis_heymansi,Cercopithecus_albogularis_francescae))),(Cercopithecus_albogularis,(Cercopithecus_roloway,((Cercopithecus_mona,Cercopithecus_campbelli),(((Cercopithecus_pogonias_schwarzianus,((Cercopithecus_neglectus,Cercopithecus_wolfi_pyrogaster),Cercopithecus_wolfi_elegans)),(Cercopithecus_pogonias_nigripes,Cercopithecus_pogonias_grayi)),Cercopithecus_pogonias)))))),((Cercopithecus_diana,Miopithecus_ogouensis),Miopithecus_talapoin)),((((((Aotus_azarae,((((Aotus_trivirgatus,((Callicebus_lugens,Callicebus_cupreus),Aotus_azarae_azarai)),((Chiropotes_israelita,(Brachyteles_arachnoides,Chiropotes_albinasus)),Cacajao_calvus)),(((Pithecia_pithecia,Sapajus_xanthosternos),Cebus_apella),Cebus_albifrons)),((((Saimiri_sciureus,Saimiri_oerstedii),Saimiri_boliviensis),Saimiri_sciureus_macrodon),Saimiri_oerstedii_citrinellus))),Aotus_nancymaae),Leontopithecus_rosalia),(Lagothrix_lagotricha,((Aotus_lemurinus,Aotus_azarai),((Callithrix_pygmaea,Callithrix_jacchus),((((Ateles_paniscus,Callimico_goeldii),Ateles_geoffroyi),(Ateles_belzebuth,Callicebus_donacophilus)),Saguinus_oedipus))))),Alouatta_caraya),((((((Megaladapis_edwardsi,Avahi_laniger),(Perodicticus_potto,Daubentonia_madagascariensis)),(((Nycticebus_pygmaeus,((Eulemur_mongoz,Eulemur_rufus),Eulemur_macaco)),(Prolemur_simus,((((Lepilemur_ruficaudatus,Lepilemur_hubbardorum),Cheirogaleus_medius),Hapalemur_griseus),Eulemur_rubriventer))),(Propithecus_coquereli,(Indri_indri,Palaeopropithecus_ingens)))),(Perodicticus_potto_edwarsi,(((Propithecus_verreauxi,(Loris_lydekkerianus,Loris_tardigradus)),(Nycticebus_bengalensis,Nycticebus_coucang)),(Otolemur_garnettii,(Otolemur_crassicaudatus,((Galago_senegalensis,Galagoides_demidoff),Galago_moholi)))))),(Tarsius_syrichta,((Tarsius_wallacei,Tarsius_dentatus),Tarsius_lariang))),((Eulemur_fulvus,(Varecia_rubra,Varecia_variegata)),(Lemur_catta,Tarsius_bancanus))))))),Gorilla_gorilla_gorilla)),Homo_sapiens_ssp_Denisova)),(Pan_troglodytes_ellioti,((Pan_paniscus,Pan_troglodytes),Pan_troglodytes_troglodytes)),Homo_sapiens); +(((Homo_heidelbergensis,(((((Nomascus_leucogenys,(Hylobates_agilis,Symphalangus_syndactylus)),(Hylobates_lar,Hylobates_moloch)),((Pongo_abelii,Pongo_pygmaeus),((((((Presbytis_melalophos,Rhinopithecus_avunculus),Semnopithecus_entellus),(((Pygathrix_nigripes,(Simias_concolor,(Trachypithecus_johnii,(Nasalis_larvatus,((Trachypithecus_francoisi,((Rhinopithecus_bieti_2_RL2012,Rhinopithecus_brelichi),Trachypithecus_obscurus)),Rhinopithecus_roxellana))))),Trachypithecus_cristatus),(Pygathrix_nemaeus,Trachypithecus_pileatus))),((Colobus_guereza,(Colobus_satanas,Piliocolobus_badius)),Procolobus_verus)),((Miopithecus_talapoin,Miopithecus_ogouensis),(((Cercopithecus_roloway,(((Cercopithecus_mona,Cercopithecus_campbelli),((Cercopithecus_pogonias_schwarzianus,((Cercopithecus_pogonias_nigripes,Cercopithecus_wolfi_elegans),(Cercopithecus_nictitans_martini,(Cercopithecus_pogonias,Cercopithecus_wolfi_pyrogaster)))),Cercopithecus_pogonias_grayi)),Cercopithecus_neglectus)),Cercopithecus_diana),((((((Macaca_arctoides,(Macaca_mulatta,Macaca_fuscata)),(Macaca_nigra,(((Macaca_fascicularis,(Macaca_silenus,Macaca_tonkeana)),(Macaca_thibetana,Macaca_assamensis)),Macaca_nemestrina))),Macaca_sylvanus),(((Theropithecus_gelada,(Lophocebus_aterrimus,Lophocebus_albigena)),((Rungwecebus_kipunji,((Papio_papio,Papio_cynocephalus),Papio_kindae)),((Papio_anubis,Papio_ursinus),Papio_hamadryas))),(((Mandrillus_leucophaeus,Cercocebus_chrysogaster),Cercocebus_agilis),(Cercocebus_torquatus,(Mandrillus_sphinx,Cercocebus_atys))))),Erythrocebus_patas),(((Cercopithecus_aethiops,Chlorocebus_sabaeus),((Cercopithecus_solatus,Cercopithecus_dryas),(((Chlorocebus_tantalus,Chlorocebus_pygerythrus),Chlorocebus_cynosuros),(Cercopithecus_hamlyni,Chlorocebus_aethiops)))),(((((Allenopithecus_nigroviridis,Cercopithecus_kandti),Cercopithecus_doggetti),(Cercopithecus_mitis_stuhlmanni,(((Cercopithecus_mitis_opisthostictus,(Cercopithecus_albogularis_kolbi,Cercopithecus_mitis_mitis)),((Cercopithecus_albogularis_monoides,(Cercopithecus_mitis_boutourlinii,Cercopithecus_albogularis_labiatus)),(Cercopithecus_albogularis_erythrarchus,Cercopithecus_albogularis_albotorquatus))),((((Cercopithecus_ascanius_schmidti,((Cercopithecus_erythrotis_camerunensis,(((Cercopithecus_erythrogaster,((Cercopithecus_erythrogaster_pococki,Cercopithecus_petaurista_buettikoferi),Cercopithecus_petaurista_petaurista)),(Cercopithecus_ascanius_katangae,Cercopithecus_petaurista)),Cercopithecus_cephus_cephus)),((Cercopithecus_lhoesti,(Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi)),Cercopithecus_ascanius_whitesidei))),(Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis)),Cercopithecus_albogularis_moloneyi),Cercopithecus_mitis)))),(Cercopithecus_nictitans,Cercopithecus_nictitans_nictitans)),((Cercopithecus_albogularis,Cercopithecus_mitis_heymansi),Cercopithecus_albogularis_francescae))))))),((((Saimiri_sciureus_macrodon,((Saimiri_oerstedii,Saimiri_sciureus),Saimiri_boliviensis)),Saimiri_oerstedii_citrinellus),((((Saguinus_oedipus,(Callithrix_pygmaea,Callithrix_jacchus)),((Callimico_goeldii,((Ateles_geoffroyi,Ateles_belzebuth),Ateles_paniscus)),Callicebus_donacophilus)),((((Lagothrix_lagotricha,((Cacajao_calvus,(Pithecia_pithecia,Chiropotes_israelita)),(Brachyteles_arachnoides,Chiropotes_albinasus))),((Sapajus_xanthosternos,Cebus_apella),Cebus_albifrons)),(Callicebus_lugens,Callicebus_cupreus)),((Leontopithecus_rosalia,Aotus_nancymaae),((((Aotus_lemurinus,Aotus_azarai),Aotus_azarae_azarai),Aotus_trivirgatus),Aotus_azarae)))),Alouatta_caraya)),(((Galago_senegalensis,((((Otolemur_garnettii,Otolemur_crassicaudatus),(Tarsius_bancanus,Eulemur_fulvus)),(Propithecus_verreauxi,(Avahi_laniger,((((Megaladapis_edwardsi,(((Tarsius_lariang,Tarsius_dentatus),Tarsius_wallacei),Tarsius_syrichta)),Eulemur_rubriventer),((Eulemur_mongoz,(Prolemur_simus,(Cheirogaleus_medius,Hapalemur_griseus))),((Palaeopropithecus_ingens,Eulemur_rufus),Eulemur_macaco))),(Propithecus_coquereli,((Lepilemur_ruficaudatus,Lepilemur_hubbardorum),Indri_indri)))))),((Varecia_rubra,Varecia_variegata),Lemur_catta))),Daubentonia_madagascariensis),((Loris_lydekkerianus,(Loris_tardigradus,Galagoides_demidoff)),(Galago_moholi,((Nycticebus_bengalensis,(Nycticebus_pygmaeus,Nycticebus_coucang)),(Perodicticus_potto,Perodicticus_potto_edwarsi))))))))),Gorilla_gorilla_gorilla),Gorilla_gorilla)),Homo_sapiens_ssp_Denisova),(Pan_troglodytes_ellioti,((Pan_paniscus,Pan_troglodytes),Pan_troglodytes_troglodytes)),Homo_sapiens); +(Pan_troglodytes_ellioti,((Pan_paniscus,(Pan_troglodytes_troglodytes,Pan_troglodytes)),(Gorilla_gorilla,((Homo_sapiens_ssp_Denisova,((((Nomascus_leucogenys,Hylobates_moloch),(Hylobates_lar,(Hylobates_agilis,Symphalangus_syndactylus))),((Pongo_abelii,Pongo_pygmaeus),(((((Callicebus_cupreus,Callicebus_lugens),((((Aotus_trivirgatus,(Aotus_azarae,((Cacajao_calvus,((Pithecia_pithecia,(Chiropotes_israelita,(((Alouatta_caraya,Chiropotes_albinasus),Brachyteles_arachnoides),((Saimiri_sciureus_macrodon,((Saimiri_oerstedii,Saimiri_boliviensis),Saimiri_sciureus)),Saimiri_oerstedii_citrinellus)))),((Sapajus_xanthosternos,Cebus_apella),Cebus_albifrons))),(((Callithrix_pygmaea,Callithrix_jacchus),((Saguinus_oedipus,(Ateles_paniscus,(Callimico_goeldii,Ateles_geoffroyi))),(Callicebus_donacophilus,Ateles_belzebuth))),(Aotus_lemurinus,Aotus_azarai))))),Aotus_azarae_azarai),Aotus_nancymaae),Lagothrix_lagotricha)),Leontopithecus_rosalia),(((Galago_senegalensis,((Tarsius_bancanus,Eulemur_fulvus),(Otolemur_crassicaudatus,Otolemur_garnettii))),((Varecia_rubra,Varecia_variegata),Lemur_catta)),((((((Galagoides_demidoff,(Loris_lydekkerianus,Galago_moholi)),((Nycticebus_coucang,Nycticebus_pygmaeus),Nycticebus_bengalensis)),(Perodicticus_potto,Perodicticus_potto_edwarsi)),((Avahi_laniger,((Propithecus_coquereli,Indri_indri),Propithecus_verreauxi)),((Megaladapis_edwardsi,(Eulemur_mongoz,((Prolemur_simus,(((Lepilemur_ruficaudatus,Lepilemur_hubbardorum),Cheirogaleus_medius),Hapalemur_griseus)),(Eulemur_macaco,(Eulemur_rufus,Eulemur_rubriventer))))),Palaeopropithecus_ingens))),Daubentonia_madagascariensis),((Tarsius_syrichta,(Tarsius_lariang,(Tarsius_wallacei,Tarsius_dentatus))),Loris_tardigradus)))),((((((Semnopithecus_entellus,((Trachypithecus_pileatus,((Trachypithecus_francoisi,Trachypithecus_obscurus),Trachypithecus_cristatus)),((Simias_concolor,(((Rhinopithecus_brelichi,Rhinopithecus_bieti_2_RL2012),Rhinopithecus_roxellana),(Pygathrix_nemaeus,Pygathrix_nigripes))),Nasalis_larvatus))),Trachypithecus_johnii),Rhinopithecus_avunculus),Presbytis_melalophos),((Colobus_guereza,Colobus_satanas),(Piliocolobus_badius,Procolobus_verus))),(Miopithecus_ogouensis,((Cercopithecus_diana,((Cercopithecus_roloway,(((((Macaca_fascicularis,Macaca_tonkeana),(Macaca_silenus,(Macaca_sylvanus,(Macaca_thibetana,Macaca_assamensis)))),(Macaca_nemestrina,(Macaca_nigra,(Macaca_mulatta,Macaca_fuscata)))),Macaca_arctoides),(((Theropithecus_gelada,(Lophocebus_aterrimus,Lophocebus_albigena)),(Rungwecebus_kipunji,(((Papio_papio,(Papio_anubis,Papio_hamadryas)),Papio_ursinus),(Papio_cynocephalus,Papio_kindae)))),((Mandrillus_leucophaeus,(Cercocebus_agilis,Cercocebus_chrysogaster)),(Cercocebus_torquatus,(Mandrillus_sphinx,Cercocebus_atys)))))),Erythrocebus_patas)),(Miopithecus_talapoin,((((Cercopithecus_neglectus,((Cercopithecus_mona,(Cercopithecus_pogonias,Cercopithecus_campbelli)),((Cercopithecus_pogonias_grayi,((Cercopithecus_wolfi_elegans,Cercopithecus_pogonias_nigripes),Cercopithecus_pogonias_schwarzianus)),Cercopithecus_wolfi_pyrogaster))),Cercopithecus_dryas),((((Cercopithecus_cephus,Cercopithecus_cephus_ngottoensis),(Cercopithecus_ascanius_schmidti,(((((Cercopithecus_ascanius_katangae,Cercopithecus_erythrotis_camerunensis),(Cercopithecus_lhoesti,(Cercopithecus_preussi_insularis,Cercopithecus_preussi_preussi))),Cercopithecus_cephus_cephus),((((Cercopithecus_erythrogaster_pococki,Cercopithecus_petaurista_buettikoferi),Cercopithecus_petaurista_petaurista),Cercopithecus_erythrogaster),Cercopithecus_petaurista)),Cercopithecus_ascanius_whitesidei))),Cercopithecus_albogularis_moloneyi),(Cercopithecus_albogularis_francescae,((Cercopithecus_mitis,(Cercopithecus_doggetti,(((Cercopithecus_nictitans_nictitans,(Cercopithecus_nictitans,((Cercopithecus_mitis_opisthostictus,Cercopithecus_mitis_mitis),(Cercopithecus_albogularis_albotorquatus,((Cercopithecus_albogularis_labiatus,Cercopithecus_albogularis_monoides),(Cercopithecus_albogularis_erythrarchus,Cercopithecus_mitis_boutourlinii)))))),(Allenopithecus_nigroviridis,Cercopithecus_kandti)),(Cercopithecus_albogularis_kolbi,Cercopithecus_mitis_stuhlmanni)))),(Cercopithecus_albogularis,Cercopithecus_mitis_heymansi))))),(((Cercopithecus_aethiops,Cercopithecus_solatus),(Chlorocebus_sabaeus,(Chlorocebus_pygerythrus,((Chlorocebus_cynosuros,Cercopithecus_hamlyni),(Chlorocebus_tantalus,Chlorocebus_aethiops))))),Cercopithecus_nictitans_martini))))))))),Gorilla_gorilla_gorilla)),Homo_heidelbergensis))),Homo_sapiens); \ No newline at end of file diff --git a/inst/test-data/takazawa/primates_reference.nw b/inst/test-data/takazawa/primates_reference.nw new file mode 100644 index 000000000..21b01c877 --- /dev/null +++ b/inst/test-data/takazawa/primates_reference.nw @@ -0,0 +1 @@ +(((Pan_paniscus:0.00000100000050002909,(Pan_troglodytes_troglodytes:0.008976049170366509,Pan_troglodytes:0.00000100000050002909):0.00000100000050002909):0.0031865870836808507,Pan_troglodytes_ellioti:0.00000100000050002909):0.00000100000050002909,(Homo_heidelbergensis:0.00000100000050002909,((((Pongo_pygmaeus:0.00000100000050002909,Pongo_abelii:0.00000100000050002909):0.037170568292935524,((Nomascus_leucogenys:0.00000100000050002909,((Hylobates_lar:0.016591681006965456,Symphalangus_syndactylus:0.007920743188016216):0.00013621035770507584,Hylobates_agilis:0.02307658643885727):0.00249652792057071):0.00000100000050002909,Hylobates_moloch:0.02097195861946949):0.013516754887845275):0.031233822728521824,((Gorilla_gorilla:0.016433209463986846,(((((Procolobus_verus:0.011924334650199899,Piliocolobus_badius:0.00000100000050002909):0.00000100000050002909,(Colobus_guereza:0.013206585225886247,Colobus_satanas:0.014399914471687876):0.04020622046115531):0.015824648228866568,((Rhinopithecus_avunculus:0.011914184194655661,(Semnopithecus_entellus:0.023374905093694436,Presbytis_melalophos:0.00000100000050002909):0.00000100000050002909):0.00000100000050002909,(Trachypithecus_johnii:0.00000100000050002909,((Trachypithecus_pileatus:0.01302102410200909,(Trachypithecus_cristatus:0.0224675891245084,(Trachypithecus_francoisi:0.019642168131320983,Trachypithecus_obscurus:0.00000100000050002909):0.0025836401200199366):0.005110138441729096):0.010134298869341783,(((Nasalis_larvatus:0.00000100000050002909,Simias_concolor:0.00000100000050002909):0.009064510594372877,(Pygathrix_nigripes:0.01172923870803262,Pygathrix_nemaeus:0.02431688383686996):0.0025518243129543064):0.009336104449957808,((Rhinopithecus_bieti_2_RL2012:0.011514051810021882,Rhinopithecus_brelichi:0.00000100000050002909):0.00000100000050002909,Rhinopithecus_roxellana:0.00000100000050002909):0.00000100000050002909):0.010145278520955467):0.008944015666117253):0.00122858505403819):0.005792848763342661):0.06741824257854372,(Miopithecus_ogouensis:0.025554805037506935,((Cercopithecus_diana:0.019743863368161807,(Erythrocebus_patas:0.08377115747814227,(Allenopithecus_nigroviridis:0.06206028540332841,((Cercocebus_chrysogaster:0.00000100000050002909,(Mandrillus_leucophaeus:0.00000100000050002909,((Cercocebus_torquatus:0.01487559524013635,(Cercocebus_atys:0.00000100000050002909,Mandrillus_sphinx:0.016348105201563542):0.027040308748291844):0.027580853364101734,Cercocebus_agilis:0.00000100000050002909):0.00000100000050002909):0.00000100000050002909):0.036855047419667025,(((Rungwecebus_kipunji:0.00000100000050002909,((Papio_kindae:0.00000100000050002909,Papio_cynocephalus:0.00000100000050002909):0.01260828466550571,((Papio_papio:0.029361734354413974,(Papio_anubis:0.00000100000050002909,Papio_hamadryas:0.00000100000050002909):0.00000100000050002909):0.014419782818365182,Papio_ursinus:0.032148595252729985):0.00000100000050002909):0.01264862182790029):0.012411570224006241,((Lophocebus_aterrimus:0.00000100000050002909,Lophocebus_albigena:0.00000100000050002909):0.015905598712139434,Theropithecus_gelada:0.00000100000050002909):0.00000100000050002909):0.025062346274824936,(((Macaca_fascicularis:0.02521513112810832,(Macaca_silenus:0.03917377563642444,Macaca_tonkeana:0.018522743652970172):0.008551699636751158):0.0046316103201124136,((Macaca_arctoides:0.030401652724779963,(((Macaca_mulatta:0.04558985519551955,Macaca_fuscata:0.00000100000050002909):0.025317902183488533,Macaca_nigra:0.013435467273634864):0.00990524774787567,Macaca_nemestrina:0.008637961721894205):0.0044515308023778295):0.004152302824399529,(Macaca_thibetana:0.005147506037503612,Macaca_assamensis:0.00000100000050002909):0.030844091204435722):0.004809619633564048):0.010507349465855348,Macaca_sylvanus:0.05755699717134828):0.021246557250359132):0.006565561289905758):0.005863930509962941):0.011492121298005009):0.01187673267381836):0.006202828597494256,(((((Chlorocebus_aethiops:0.00000100000050002909,Cercopithecus_hamlyni:0.04137894286443595):0.010047454124514988,(Chlorocebus_cynosuros:0.010095840253939711,(Chlorocebus_pygerythrus:0.010845331403960936,(Cercopithecus_dryas:0.010259654525275382,(Chlorocebus_sabaeus:0.00000100000050002909,(Cercopithecus_aethiops:0.00000100000050002909,Cercopithecus_solatus:0.02382389166563658):0.00000100000050002909):0.0103372383698078):0.010054556614973028):0.00000100000050002909):0.00000100000050002909):0.00000100000050002909,Chlorocebus_tantalus:0.00000100000050002909):0.03053537832039837,((Cercopithecus_roloway:0.030802473839941502,(Cercopithecus_neglectus:0.011689231680001522,((Cercopithecus_campbelli:0.02255418148870602,Cercopithecus_mona:0.010343368947580072):0.030545602961454477,(Cercopithecus_pogonias:0.00000100000050002909,(((Cercopithecus_wolfi_pyrogaster:0.010419229511498344,Cercopithecus_wolfi_elegans:0.00000100000050002909):0.010013995679670274,Cercopithecus_nictitans_martini:0.00000100000050002909):0.00024196767577298875,((Cercopithecus_pogonias_schwarzianus:0.01016997347488147,Cercopithecus_pogonias_grayi:0.00000100000050002909):0.00000100000050002909,Cercopithecus_pogonias_nigripes:0.00000100000050002909):0.00000100000050002909):0.00000100000050002909):0.03077748873254212):0.02804098676500692):0.01266512887016918):0.00000100000050002909,(((Cercopithecus_ascanius_schmidti:0.00000100000050002909,(((Cercopithecus_cephus_cephus:0.012615248958788038,(Cercopithecus_ascanius_katangae:0.00000100000050002909,Cercopithecus_erythrotis_camerunensis:0.00000100000050002909):0.010225292208221215):0.00000100000050002909,(Cercopithecus_petaurista:0.014488560390855375,((Cercopithecus_petaurista_petaurista:0.00000100000050002909,Cercopithecus_petaurista_buettikoferi:0.015317672734583376):0.02117555385193525,(Cercopithecus_erythrogaster_pococki:0.021269698398455203,Cercopithecus_erythrogaster:0.015433123877817903):0.009458121720997885):0.010573987270574734):0.010305006523791604):0.01016640889975888,(((Cercopithecus_preussi_insularis:0.014539441786618599,Cercopithecus_preussi_preussi:0.00000100000050002909):0.033736232269526115,Cercopithecus_lhoesti:0.021603243402544124):0.041207052195376556,Cercopithecus_ascanius_whitesidei:0.00000100000050002909):0.00000100000050002909):0.010041388177677132):0.010090012122896347,(Cercopithecus_cephus:0.00000100000050002909,Cercopithecus_cephus_ngottoensis:0.00000100000050002909):0.010445388672408212):0.009705036579031089,((Cercopithecus_albogularis_albotorquatus:0.010089928886590912,((((((Cercopithecus_nictitans_nictitans:0.020300832445412694,Cercopithecus_nictitans:0.00000100000050002909):0.010131850635491366,(((Cercopithecus_doggetti:0.010253542784914613,(Cercopithecus_mitis_heymansi:0.01012294812967128,Cercopithecus_albogularis_francescae:0.030753923094548188):0.010123279589556514):0.00000100000050002909,(Cercopithecus_kandti:0.0101300385214338,(Cercopithecus_albogularis_kolbi:0.030445961961834352,Cercopithecus_mitis_stuhlmanni:0.020251760212913826):0.010147577349575396):0.00000100000050002909):0.00000100000050002909,Cercopithecus_mitis:0.00000100000050002909):0.00637880991921787):0.006358501560168369,Cercopithecus_mitis_opisthostictus:0.00000100000050002909):0.00000100000050002909,Cercopithecus_mitis_mitis:0.010115730002854):0.012762501178720053,((Cercopithecus_albogularis_labiatus:0.020234732659114078,Cercopithecus_albogularis_erythrarchus:0.00000100000050002909):0.00000100000050002909,Cercopithecus_mitis_boutourlinii:0.00000100000050002909):0.00000100000050002909):0.00000100000050002909,(Cercopithecus_albogularis_monoides:0.020535016131014324,Cercopithecus_albogularis:0.024654905752324832):0.006158760905159727):0.008016372099012417):0.015946834992090302,Cercopithecus_albogularis_moloneyi:0.00000100000050002909):0.008179034070495781):0.016058278522374934):0.008022220222153048):0.008082127200378344,Miopithecus_talapoin:0.00000100000050002909):0.007901864520128763):0.00946263167685457):0.052620474539527874):0.0428968180246764,((Alouatta_caraya:0.0245907600058461,((Saguinus_oedipus:0.03626557989745813,Callithrix_pygmaea:0.00859197051103864):0.009946419296389607,((((Cebus_albifrons:0.018480964433179058,(Sapajus_xanthosternos:0.01676470952031067,Cebus_apella:0.00000100000050002909):0.005530682819534275):0.027790701108350344,(((Callimico_goeldii:0.06086254588555785,(Callithrix_jacchus:0.014692665817586376,(Ateles_geoffroyi:0.00000100000050002909,(Ateles_belzebuth:0.007895888124255172,Ateles_paniscus:0.00000100000050002909):0.00000100000050002909):0.00000100000050002909):0.00000100000050002909):0.0024546855762566967,(Callicebus_donacophilus:0.00000100000050002909,Callicebus_cupreus:0.01098523063083413):0.00000100000050002909):0.01097708624405508,Callicebus_lugens:0.00000100000050002909):0.013202815567803039):0.00000100000050002909,((Chiropotes_israelita:0.01797936193141944,(Brachyteles_arachnoides:0.011616731680488782,Chiropotes_albinasus:0.00000100000050002909):0.004664792385690107):0.005893263302783158,(Lagothrix_lagotricha:0.00000100000050002909,(Pithecia_pithecia:0.00000100000050002909,Cacajao_calvus:0.0035633933601977477):0.00000100000050002909):0.0006017283501354095):0.017809427339528897):0.0042743520984313554,((Leontopithecus_rosalia:0.0413981032127957,(Aotus_nancymaae:0.00000100000050002909,((Saimiri_sciureus_macrodon:0.01187611308178513,(Saimiri_boliviensis:0.00000100000050002909,(Saimiri_sciureus:0.00000100000050002909,Saimiri_oerstedii:0.00000100000050002909):0.00000100000050002909):0.00000100000050002909):0.00000100000050002909,Saimiri_oerstedii_citrinellus:0.00000100000050002909):0.05862120061529083):0.00000100000050002909):0.006132130278253935,(Aotus_trivirgatus:0.00000100000050002909,((Aotus_azarai:0.00000100000050002909,Aotus_lemurinus:0.00000100000050002909):0.0076470673958283835,(Aotus_azarae:0.00000100000050002909,Aotus_azarae_azarai:0.00000100000050002909):0.00000100000050002909):0.00000100000050002909):0.00485397804997873):0.005778230469574646):0.009244286040677445):0.022619288272433962):0.06783352181969797,(((((((Otolemur_crassicaudatus:0.00000100000050002909,(Galagoides_demidoff:0.01450344195497542,(Galago_moholi:0.01837933976526092,Galago_senegalensis:0.00000100000050002909):0.0024719471989097107):0.00000100000050002909):0.00000100000050002909,Otolemur_garnettii:0.00000100000050002909):0.021004977534786737,(((Nycticebus_pygmaeus:0.10262073360482739,Nycticebus_coucang:0.003819093912751541):0.0006158586912025192,Nycticebus_bengalensis:0.00000100000050002909):0.01762008004304771,(Loris_tardigradus:0.00000100000050002909,Loris_lydekkerianus:0.00000100000050002909):0.014499295154702517):0.013114239634419923):0.00000100000050002909,(Perodicticus_potto:0.02904664140677436,Perodicticus_potto_edwarsi:0.00000100000050002909):0.010173486433362237):0.023035671942876746,(Daubentonia_madagascariensis:0.020754924396180336,((((((Prolemur_simus:0.013585326801090359,((((Varecia_rubra:0.00000100000050002909,Varecia_variegata:0.00000100000050002909):0.03350665025809169,Lemur_catta:0.04206579524916367):0.00000100000050002909,Hapalemur_griseus:0.011269396867223112):0.011158056852287988,Cheirogaleus_medius:0.032183973021800004):0.00000100000050002909):0.008051593962934442,Eulemur_rubriventer:0.00000100000050002909):0.0013066730478064703,(((Eulemur_fulvus:0.00000100000050002909,Eulemur_rufus:0.00784640241721738):0.00000867646777168683,Eulemur_macaco:0.00000100000050002909):0.00000100000050002909,Eulemur_mongoz:0.00000100000050002909):0.0012527168522641927):0.006666877282016884,Megaladapis_edwardsi:0.04265811398717199):0.006743880841239195,Palaeopropithecus_ingens:0.0047328600876847095):0.0047600274480326,(Propithecus_verreauxi:0.01759904078751576,(Propithecus_coquereli:0.00000100000050002909,(((Lepilemur_ruficaudatus:0.00000100000050002909,Lepilemur_hubbardorum:0.00000100000050002909):0.03529953832723479,Indri_indri:0.00000100000050002909):0.020063352678940237,Avahi_laniger:0.05836788474965459):0.011742961964976992):0.00000100000050002909):0.00000100000050002909):0.01860907492658325):0.0046018991422998):0.013822151807450356,(Tarsius_syrichta:0.022939345793413907,(Tarsius_lariang:0.00000100000050002909,(Tarsius_wallacei:0.004525585954244411,Tarsius_dentatus:0.00000100000050002909):0.004506816622482449):0.025214249160400937):0.045668942972468186):0.014407193936605854,Tarsius_bancanus:0.06222744724598934):0.07753058811220054):0.03124403276267376):0.07884456905752942):0.00000100000050002909,Gorilla_gorilla_gorilla:0.00000100000050002909):0.0063244513418949195):0.019478512772403807,Homo_sapiens_ssp_Denisova:0.023256597940732395):0.00000100000050002909):0.011121159652767216,Homo_sapiens:0.00000100000050002909); diff --git a/man/InfoConsensus.Rd b/man/InfoConsensus.Rd new file mode 100644 index 000000000..993f332d1 --- /dev/null +++ b/man/InfoConsensus.Rd @@ -0,0 +1,167 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/InfoConsensus.R +\name{InfoConsensus} +\alias{InfoConsensus} +\title{Information-theoretic consensus tree} +\usage{ +InfoConsensus( + trees, + maxReplicates = 5L, + targetHits = 2L, + maxSeconds = 0, + nThreads = getOption("mc.cores", 1L), + treeSample = "auto", + collapse = TRUE, + neverDrop = FALSE, + maxDrop = min(5L, ceiling(NTip(trees[[1]])/10)), + control = SearchControl(), + screeningK = 7, + screeningTolerance = 0, + screeningTopK = 1L, + method = c("mci", "spic"), + verbosity = 1L +) + +} +\arguments{ +\item{trees}{An object of class \code{multiPhylo}: the input trees. +All trees must share the same tip labels.} + +\item{maxReplicates}{Integer: maximum number of independent search +replicates. Each replicate starts from a different random Wagner tree.} + +\item{targetHits}{Integer: stop after finding the best score this many +times independently.} + +\item{maxSeconds}{Numeric: timeout in seconds (0 = no timeout).} + +\item{nThreads}{Integer: number of threads for inter-replicate parallelism. +Defaults to \code{getOption("mc.cores", 1L)}.} + +\item{treeSample}{Controls how many input trees are used during Phase 1 +(driven search). CID verification cost scales linearly with the number +of input trees, so with large tree sets, using a representative subsample +for the search phase and verifying against the full set afterwards can be +faster without sacrificing quality. + +\code{"auto"} (default): automatically selects a subsample size based on +the number of tips. An integer uses exactly that many trees (sampled +without replacement). \code{Inf} or \code{NULL} use all trees. + +Subsampling applies only to Phase 1. Phases 2 and 3 always score +against the \strong{full} input tree set, and the returned \code{score} +attribute reflects the full-set MCI.} + +\item{collapse}{Logical: if \code{TRUE} (default), run a collapse/resolve +refinement phase after the binary search. This can produce a +non-binary result when collapsing a split improves the mean MCI.} + +\item{neverDrop}{Controls rogue taxon dropping (Phase 3). +\code{TRUE} disables dropping entirely. +\code{FALSE} (default) allows all taxa to be dropped if doing so improves +the consensus. +A character or integer vector specifies tips that must never be dropped; +all others are candidates.} + +\item{maxDrop}{Integer: maximum number of tips that may be dropped during +rogue screening. Default \code{min(5L, ceiling(nTip / 10))}.} + +\item{control}{A \code{\link[=SearchControl]{SearchControl()}} object for expert tuning of the +driven search strategy.} + +\item{screeningK}{Numeric: implied-weights concavity constant for MRP +character screening during TBR. The search uses MRP (Matrix +Representation with Parsimony) characters as a fast proxy for MCI +scoring; \code{screeningK} controls how these characters are weighted. +Default \code{7} (IW with \code{k = 7}), which empirically maximizes rank +correlation with MCI scores. Use \code{Inf} for equal-weight screening.} + +\item{screeningTolerance}{Numeric (>= 0): controls how generously +candidate moves are sent to full MCI evaluation. A value of \code{0} +(default) only evaluates the single best MRP-screened candidate per +clip. Values > 0 relax the screening threshold, allowing candidates +whose MRP score exceeds the current best by up to this fraction (e.g., +\code{0.02} = $2\%$ tolerance). Higher values improve search quality at the +cost of more MCI evaluations per step.} + +\item{screeningTopK}{Integer: number of top MRP-screened candidates to +evaluate via full MCI scoring per TBR clip. Default \code{1} uses the +single best MRP candidate. Values > 1 score the top-k MRP candidates +and accept the one with the best MCI, catching moves where MRP and MCI +rankings disagree. Cost scales linearly with \code{screeningTopK}.} + +\item{method}{Character: the scoring method for consensus optimization. +\code{"mci"} (default): Mutual Clustering Information. +\code{"spic"}: Splitwise Phylogenetic Information Content (Smith 2022). +Faster than MCI because scoring is split-additive.} + +\item{verbosity}{Integer controlling console output (0 = silent).} +} +\value{ +A tree of class \code{phylo} with attributes: +\itemize{ +\item \code{"score"}: mean MCI between the consensus and the input trees +(higher is better). +\item \code{"hits"}: the number of times this score was found. +\item \code{"droppedTips"}: character vector of dropped taxa (if any), or \code{NULL}. +} +} +\description{ +Find a consensus tree that maximizes the mean Mutual Clustering +Information (MCI) with a set of input trees, using a driven search with +TBR, ratchet, drift, sectorial search, and tree fusing. +} +\details{ +Unlike the majority-rule consensus, which minimizes Robinson-Foulds +distance and can be highly unresolved when phylogenetic signal is low, +\code{InfoConsensus()} finds a more resolved tree that maximizes a finer-grained +information-theoretic measure of agreement with the input trees. + +The search uses MRP (Matrix Representation with Parsimony) characters +for fast incremental screening during TBR, with MCI verification for +move acceptance. This provides the full power of the driven search +pipeline (ratchet, drift, sectorial search, tree fusing, multi-replicate +parallelism) with MCI scoring. + +The search proceeds in up to three phases: +\enumerate{ +\item \strong{Driven search} using the C++ engine with MCI scoring. +\item \strong{Collapse/resolve refinement} (when \code{collapse = TRUE}): greedily +collapse internal edges whose removal improves the score, then try +resolving remaining polytomies. +\item \strong{Rogue taxon dropping} (when \code{neverDrop != TRUE}): iteratively +identify and remove taxa whose absence improves consensus quality, +then attempt to restore previously dropped taxa. +} +} +\examples{ +library(TreeTools) +# Generate some trees +trees <- as.phylo(1:30, nTip = 12) + +# Quick search +result <- InfoConsensus(trees, maxReplicates = 3L, targetHits = 2L, + neverDrop = TRUE, verbosity = 0) +plot(result) +attr(result, "score") + +# Compare with majority-rule consensus +mr <- Consensus(trees, p = 0.5) +mean(TreeDist::ClusteringInfoDistance(mr, trees)) +mean(TreeDist::ClusteringInfoDistance(result, trees)) + +} +\references{ +\insertRef{Smith2020}{TreeSearch} +} +\seealso{ +\code{\link[=MaximizeParsimony]{MaximizeParsimony()}} uses the same driven search engine for +parsimony. + +Other custom search functions: +\code{\link{EdgeListSearch}()}, +\code{\link{Jackknife}()}, +\code{\link{MorphyBootstrap}()}, +\code{\link{SuccessiveApproximations}()} +} +\concept{custom search functions} diff --git a/man/Jackknife.Rd b/man/Jackknife.Rd index c2ebfd523..269ad2008 100644 --- a/man/Jackknife.Rd +++ b/man/Jackknife.Rd @@ -86,6 +86,7 @@ Other split support functions: Other custom search functions: \code{\link{EdgeListSearch}()}, +\code{\link{InfoConsensus}()}, \code{\link{MorphyBootstrap}()}, \code{\link{SuccessiveApproximations}()} } diff --git a/man/Ratchet.Rd b/man/Ratchet.Rd index 84e496fdf..9f4ff5f93 100644 --- a/man/Ratchet.Rd +++ b/man/Ratchet.Rd @@ -178,7 +178,7 @@ sampling of the original characters. \code{MultiRatchet()} returns a list of optimal trees produced by \code{nSearch} \code{Ratchet()} searches, from which a consensus tree can -be generated using \code{\link[ape:consensus]{ape::consensus()}} or \code{\link[TreeTools:ConsensusWithout]{TreeTools::ConsensusWithout()}}. +be generated using \code{\link[TreeTools:Consensus]{Consensus()}} or \code{\link[TreeTools:ConsensusWithout]{TreeTools::ConsensusWithout()}}. } \description{ \code{Ratchet()} uses the parsimony ratchet \insertCite{Nixon1999}{TreeSearch} @@ -217,6 +217,7 @@ par(oldPar) Other custom search functions: \code{\link{EdgeListSearch}()}, +\code{\link{InfoConsensus}()}, \code{\link{Jackknife}()}, \code{\link{SuccessiveApproximations}()} } diff --git a/man/SearchControl.Rd b/man/SearchControl.Rd index 491d13fbb..c359559a7 100644 --- a/man/SearchControl.Rd +++ b/man/SearchControl.Rd @@ -40,6 +40,8 @@ SearchControl( poolSuboptimal = 0, consensusStableReps = 0L, perturbStopFactor = 2L, + scoreTol = 0, + plateauReps = 0L, adaptiveLevel = FALSE, consensusConstrain = FALSE, pruneReinsertCycles = 0L, @@ -186,6 +188,18 @@ Inspired by IQ-TREE's unsuccessful-perturbation stopping rule \insertCite{Nguyen2015}{TreeSearch}; adapted from per-perturbation to per-replicate granularity.} +\item{scoreTol}{Numeric; minimum score improvement to count as meaningful +for convergence detection. Default 0 (any strict improvement counts). +When positive, improvements smaller than \code{scoreTol} do not reset the +unsuccessful-replicate counter, allowing \code{perturbStopFactor} and +\code{plateauReps} to detect convergence in continuous-score modes (e.g.\ CID).} + +\item{plateauReps}{Integer; stop after this many consecutive replicates +without meaningful improvement (as determined by \code{scoreTol}). +0 disables this criterion (default). +Unlike \code{perturbStopFactor} (which scales with tree size), this is an +absolute count suitable for small replicate budgets.} + \item{adaptiveLevel}{Logical; dynamically scale ratchet and drift effort based on the observed hit rate? When \code{TRUE}, easy landscapes (high hit rate) trigger reduced effort per replicate, while hard diff --git a/man/SuccessiveApproximations.Rd b/man/SuccessiveApproximations.Rd index dd2efcfd6..e34f24c8e 100644 --- a/man/SuccessiveApproximations.Rd +++ b/man/SuccessiveApproximations.Rd @@ -111,6 +111,7 @@ criterion \insertCite{Farris1969}{TreeSearch}. \seealso{ Other custom search functions: \code{\link{EdgeListSearch}()}, +\code{\link{InfoConsensus}()}, \code{\link{Jackknife}()}, \code{\link{MorphyBootstrap}()} } diff --git a/man/TreeSearch.Rd b/man/TreeSearch.Rd index 60cee4f8f..13a4c52fe 100644 --- a/man/TreeSearch.Rd +++ b/man/TreeSearch.Rd @@ -141,6 +141,7 @@ optima. } Other custom search functions: +\code{\link{InfoConsensus}()}, \code{\link{Jackknife}()}, \code{\link{MorphyBootstrap}()}, \code{\link{SuccessiveApproximations}()} diff --git a/src/RcppExports.cpp b/src/RcppExports.cpp index 8967bf315..e3b3edacc 100644 --- a/src/RcppExports.cpp +++ b/src/RcppExports.cpp @@ -804,3 +804,104 @@ BEGIN_RCPP return rcpp_result_gen; END_RCPP } +// ts_cid_consensus +List ts_cid_consensus(List splitMatrices, IntegerVector nTip, LogicalVector normalize, int maxReplicates, int targetHits, int tbrMaxHits, int ratchetCycles, double ratchetPerturbProb, int ratchetPerturbMode, bool ratchetAdaptive, int driftCycles, int driftAfdLimit, double driftRfdLimit, int xssRounds, int xssPartitions, int rssRounds, int cssRounds, int cssPartitions, int sectorMinSize, int sectorMaxSize, int fuseInterval, bool fuseAcceptEqual, int poolMaxSize, double poolSuboptimal, double maxSeconds, int verbosity, int tabuSize, int wagnerStarts, int nThreads, double screeningK, double screeningTolerance, int screeningTopK, double scoreTol, int plateauReps, Nullable startEdge, Nullable progressCallback, int scoringMethod); +RcppExport SEXP _TreeSearch_ts_cid_consensus(SEXP splitMatricesSEXP, SEXP nTipSEXP, SEXP normalizeSEXP, SEXP maxReplicatesSEXP, SEXP targetHitsSEXP, SEXP tbrMaxHitsSEXP, SEXP ratchetCyclesSEXP, SEXP ratchetPerturbProbSEXP, SEXP ratchetPerturbModeSEXP, SEXP ratchetAdaptiveSEXP, SEXP driftCyclesSEXP, SEXP driftAfdLimitSEXP, SEXP driftRfdLimitSEXP, SEXP xssRoundsSEXP, SEXP xssPartitionsSEXP, SEXP rssRoundsSEXP, SEXP cssRoundsSEXP, SEXP cssPartitionsSEXP, SEXP sectorMinSizeSEXP, SEXP sectorMaxSizeSEXP, SEXP fuseIntervalSEXP, SEXP fuseAcceptEqualSEXP, SEXP poolMaxSizeSEXP, SEXP poolSuboptimalSEXP, SEXP maxSecondsSEXP, SEXP verbositySEXP, SEXP tabuSizeSEXP, SEXP wagnerStartsSEXP, SEXP nThreadsSEXP, SEXP screeningKSEXP, SEXP screeningToleranceSEXP, SEXP screeningTopKSEXP, SEXP scoreTolSEXP, SEXP plateauRepsSEXP, SEXP startEdgeSEXP, SEXP progressCallbackSEXP, SEXP scoringMethodSEXP) { +BEGIN_RCPP + Rcpp::RObject rcpp_result_gen; + Rcpp::RNGScope rcpp_rngScope_gen; + Rcpp::traits::input_parameter< List >::type splitMatrices(splitMatricesSEXP); + Rcpp::traits::input_parameter< IntegerVector >::type nTip(nTipSEXP); + Rcpp::traits::input_parameter< LogicalVector >::type normalize(normalizeSEXP); + Rcpp::traits::input_parameter< int >::type maxReplicates(maxReplicatesSEXP); + Rcpp::traits::input_parameter< int >::type targetHits(targetHitsSEXP); + Rcpp::traits::input_parameter< int >::type tbrMaxHits(tbrMaxHitsSEXP); + Rcpp::traits::input_parameter< int >::type ratchetCycles(ratchetCyclesSEXP); + Rcpp::traits::input_parameter< double >::type ratchetPerturbProb(ratchetPerturbProbSEXP); + Rcpp::traits::input_parameter< int >::type ratchetPerturbMode(ratchetPerturbModeSEXP); + Rcpp::traits::input_parameter< bool >::type ratchetAdaptive(ratchetAdaptiveSEXP); + Rcpp::traits::input_parameter< int >::type driftCycles(driftCyclesSEXP); + Rcpp::traits::input_parameter< int >::type driftAfdLimit(driftAfdLimitSEXP); + Rcpp::traits::input_parameter< double >::type driftRfdLimit(driftRfdLimitSEXP); + Rcpp::traits::input_parameter< int >::type xssRounds(xssRoundsSEXP); + Rcpp::traits::input_parameter< int >::type xssPartitions(xssPartitionsSEXP); + Rcpp::traits::input_parameter< int >::type rssRounds(rssRoundsSEXP); + Rcpp::traits::input_parameter< int >::type cssRounds(cssRoundsSEXP); + Rcpp::traits::input_parameter< int >::type cssPartitions(cssPartitionsSEXP); + Rcpp::traits::input_parameter< int >::type sectorMinSize(sectorMinSizeSEXP); + Rcpp::traits::input_parameter< int >::type sectorMaxSize(sectorMaxSizeSEXP); + Rcpp::traits::input_parameter< int >::type fuseInterval(fuseIntervalSEXP); + Rcpp::traits::input_parameter< bool >::type fuseAcceptEqual(fuseAcceptEqualSEXP); + Rcpp::traits::input_parameter< int >::type poolMaxSize(poolMaxSizeSEXP); + Rcpp::traits::input_parameter< double >::type poolSuboptimal(poolSuboptimalSEXP); + Rcpp::traits::input_parameter< double >::type maxSeconds(maxSecondsSEXP); + Rcpp::traits::input_parameter< int >::type verbosity(verbositySEXP); + Rcpp::traits::input_parameter< int >::type tabuSize(tabuSizeSEXP); + Rcpp::traits::input_parameter< int >::type wagnerStarts(wagnerStartsSEXP); + Rcpp::traits::input_parameter< int >::type nThreads(nThreadsSEXP); + Rcpp::traits::input_parameter< double >::type screeningK(screeningKSEXP); + Rcpp::traits::input_parameter< double >::type screeningTolerance(screeningToleranceSEXP); + Rcpp::traits::input_parameter< int >::type screeningTopK(screeningTopKSEXP); + Rcpp::traits::input_parameter< double >::type scoreTol(scoreTolSEXP); + Rcpp::traits::input_parameter< int >::type plateauReps(plateauRepsSEXP); + Rcpp::traits::input_parameter< Nullable >::type startEdge(startEdgeSEXP); + Rcpp::traits::input_parameter< Nullable >::type progressCallback(progressCallbackSEXP); + Rcpp::traits::input_parameter< int >::type scoringMethod(scoringMethodSEXP); + rcpp_result_gen = Rcpp::wrap(ts_cid_consensus(splitMatrices, nTip, normalize, maxReplicates, targetHits, tbrMaxHits, ratchetCycles, ratchetPerturbProb, ratchetPerturbMode, ratchetAdaptive, driftCycles, driftAfdLimit, driftRfdLimit, xssRounds, xssPartitions, rssRounds, cssRounds, cssPartitions, sectorMinSize, sectorMaxSize, fuseInterval, fuseAcceptEqual, poolMaxSize, poolSuboptimal, maxSeconds, verbosity, tabuSize, wagnerStarts, nThreads, screeningK, screeningTolerance, screeningTopK, scoreTol, plateauReps, startEdge, progressCallback, scoringMethod)); + return rcpp_result_gen; +END_RCPP +} +// ts_cid_score_trees +NumericVector ts_cid_score_trees(List splitMatrices, int nTip, List candidateEdges); +RcppExport SEXP _TreeSearch_ts_cid_score_trees(SEXP splitMatricesSEXP, SEXP nTipSEXP, SEXP candidateEdgesSEXP) { +BEGIN_RCPP + Rcpp::RObject rcpp_result_gen; + Rcpp::RNGScope rcpp_rngScope_gen; + Rcpp::traits::input_parameter< List >::type splitMatrices(splitMatricesSEXP); + Rcpp::traits::input_parameter< int >::type nTip(nTipSEXP); + Rcpp::traits::input_parameter< List >::type candidateEdges(candidateEdgesSEXP); + rcpp_result_gen = Rcpp::wrap(ts_cid_score_trees(splitMatrices, nTip, candidateEdges)); + return rcpp_result_gen; +END_RCPP +} +// ts_cid_prescreen_rogue +NumericVector ts_cid_prescreen_rogue(List splitMatrices, int nTip, IntegerMatrix candidateEdge, IntegerVector droppableTips); +RcppExport SEXP _TreeSearch_ts_cid_prescreen_rogue(SEXP splitMatricesSEXP, SEXP nTipSEXP, SEXP candidateEdgeSEXP, SEXP droppableTipsSEXP) { +BEGIN_RCPP + Rcpp::RObject rcpp_result_gen; + Rcpp::RNGScope rcpp_rngScope_gen; + Rcpp::traits::input_parameter< List >::type splitMatrices(splitMatricesSEXP); + Rcpp::traits::input_parameter< int >::type nTip(nTipSEXP); + Rcpp::traits::input_parameter< IntegerMatrix >::type candidateEdge(candidateEdgeSEXP); + Rcpp::traits::input_parameter< IntegerVector >::type droppableTips(droppableTipsSEXP); + rcpp_result_gen = Rcpp::wrap(ts_cid_prescreen_rogue(splitMatrices, nTip, candidateEdge, droppableTips)); + return rcpp_result_gen; +END_RCPP +} +// ts_spic_score_trees +NumericVector ts_spic_score_trees(List splitMatrices, int nTip, List candidateEdges); +RcppExport SEXP _TreeSearch_ts_spic_score_trees(SEXP splitMatricesSEXP, SEXP nTipSEXP, SEXP candidateEdgesSEXP) { +BEGIN_RCPP + Rcpp::RObject rcpp_result_gen; + Rcpp::RNGScope rcpp_rngScope_gen; + Rcpp::traits::input_parameter< List >::type splitMatrices(splitMatricesSEXP); + Rcpp::traits::input_parameter< int >::type nTip(nTipSEXP); + Rcpp::traits::input_parameter< List >::type candidateEdges(candidateEdgesSEXP); + rcpp_result_gen = Rcpp::wrap(ts_spic_score_trees(splitMatrices, nTip, candidateEdges)); + return rcpp_result_gen; +END_RCPP +} +// ts_spic_prescreen_rogue +NumericVector ts_spic_prescreen_rogue(List splitMatrices, int nTip, IntegerMatrix candidateEdge, IntegerVector droppableTips); +RcppExport SEXP _TreeSearch_ts_spic_prescreen_rogue(SEXP splitMatricesSEXP, SEXP nTipSEXP, SEXP candidateEdgeSEXP, SEXP droppableTipsSEXP) { +BEGIN_RCPP + Rcpp::RObject rcpp_result_gen; + Rcpp::RNGScope rcpp_rngScope_gen; + Rcpp::traits::input_parameter< List >::type splitMatrices(splitMatricesSEXP); + Rcpp::traits::input_parameter< int >::type nTip(nTipSEXP); + Rcpp::traits::input_parameter< IntegerMatrix >::type candidateEdge(candidateEdgeSEXP); + Rcpp::traits::input_parameter< IntegerVector >::type droppableTips(droppableTipsSEXP); + rcpp_result_gen = Rcpp::wrap(ts_spic_prescreen_rogue(splitMatrices, nTip, candidateEdge, droppableTips)); + return rcpp_result_gen; +END_RCPP +} diff --git a/src/TreeSearch-init.c b/src/TreeSearch-init.c index 5a0976ad2..0fc308b90 100644 --- a/src/TreeSearch-init.c +++ b/src/TreeSearch-init.c @@ -58,6 +58,11 @@ extern SEXP _TreeSearch_MaddisonSlatkin(SEXP, SEXP); extern SEXP _TreeSearch_MaddisonSlatkin_clear_cache(); extern SEXP _TreeSearch_ts_hsj_score(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); extern SEXP _TreeSearch_ts_sankoff_test(SEXP, SEXP, SEXP, SEXP, SEXP); +extern SEXP _TreeSearch_ts_cid_consensus(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); +extern SEXP _TreeSearch_ts_cid_score_trees(SEXP, SEXP, SEXP); +extern SEXP _TreeSearch_ts_cid_prescreen_rogue(SEXP, SEXP, SEXP, SEXP); +extern SEXP _TreeSearch_ts_spic_score_trees(SEXP, SEXP, SEXP); +extern SEXP _TreeSearch_ts_spic_prescreen_rogue(SEXP, SEXP, SEXP, SEXP); extern SEXP _TreeSearch_mc_fitch_scores(SEXP, SEXP); extern SEXP _TreeSearch_ts_wagner_bias_bench(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); /* ts_stochastic_tbr and ts_parallel_temper removed — on feature/parallel-temper */ @@ -133,6 +138,11 @@ static const R_CallMethodDef callMethods[] = { {"_TreeSearch_MaddisonSlatkin_clear_cache", (DL_FUNC) &_TreeSearch_MaddisonSlatkin_clear_cache, 0}, {"_TreeSearch_ts_hsj_score", (DL_FUNC) &_TreeSearch_ts_hsj_score, 9}, {"_TreeSearch_ts_sankoff_test", (DL_FUNC) &_TreeSearch_ts_sankoff_test, 5}, + {"_TreeSearch_ts_cid_consensus", (DL_FUNC) &_TreeSearch_ts_cid_consensus, 37}, + {"_TreeSearch_ts_cid_score_trees", (DL_FUNC) &_TreeSearch_ts_cid_score_trees, 3}, + {"_TreeSearch_ts_cid_prescreen_rogue", (DL_FUNC) &_TreeSearch_ts_cid_prescreen_rogue, 4}, + {"_TreeSearch_ts_spic_score_trees", (DL_FUNC) &_TreeSearch_ts_spic_score_trees, 3}, + {"_TreeSearch_ts_spic_prescreen_rogue", (DL_FUNC) &_TreeSearch_ts_spic_prescreen_rogue, 4}, {"_TreeSearch_ts_wagner_bias_bench", (DL_FUNC) &_TreeSearch_ts_wagner_bias_bench, 10}, /* ts_stochastic_tbr (9) and ts_parallel_temper (10) removed */ diff --git a/src/ts_cid.cpp b/src/ts_cid.cpp new file mode 100644 index 000000000..bc8f52623 --- /dev/null +++ b/src/ts_cid.cpp @@ -0,0 +1,743 @@ +// CID (Clustering Information Distance) scoring for the driven search. +// +// Contains: +// - LAP solver (Jonker-Volgenant, adapted from TreeDist) +// - Mutual clustering information computation +// - Clustering entropy computation +// - cid_score(): scores a candidate tree against input trees +// - build_mrp_dataset(): constructs MRP characters for Fitch screening +// - prepare_cid_data(): one-time initialization of hash indices and logs +// +// When TreeDist exposes LinkingTo headers, the LAP solver and MCI +// computation should be replaced with the TreeDist implementations. + +#include "ts_cid.h" +#include "ts_data.h" +#include +#include +#include +#include + +namespace ts { + +// ========================================================================== +// LAP solver (Jonker-Volgenant shortest augmenting path algorithm) +// Adapted from TreeDist's lap.cpp (Smith 2020, after Volgenant 1996) +// ========================================================================== + +lap_cost lap_solve(int dim, LapMatrix& cost, + int* rowsol, int* colsol, LapScratch& scratch) { + if (dim <= 0) return 0; + if (dim == 1) { + rowsol[0] = 0; + colsol[0] = 0; + return cost(0, 0); + } + + scratch.ensure(dim); + lap_cost* v = scratch.v.data(); + int* matches = scratch.matches.data(); + int* free_rows = scratch.free_rows.data(); + int* col_list = scratch.col_list.data(); + lap_cost* d = scratch.d.data(); + int* pred = scratch.pred.data(); + + std::fill(matches, matches + dim, 0); + std::fill(rowsol, rowsol + dim, -1); + std::fill(colsol, colsol + dim, -1); + + for (int j = dim; j--; ) { + lap_cost min_val = cost(0, j); + int min_row = 0; + for (int i = 1; i < dim; ++i) { + if (cost(i, j) < min_val) { min_val = cost(i, j); min_row = i; } + } + v[j] = min_val; + matches[min_row]++; + if (matches[min_row] == 1) { rowsol[min_row] = j; colsol[j] = min_row; } + else { colsol[j] = -1; } + } + + int n_free = 0; + for (int i = 0; i < dim; ++i) { + if (matches[i] == 0) { + free_rows[n_free++] = i; + } else if (matches[i] == 1) { + int j1 = rowsol[i]; + lap_cost min2 = LAP_BIG; + for (int j = 0; j < dim; ++j) { + if (j != j1) { + lap_cost reduced = cost(i, j) - v[j]; + if (reduced < min2) min2 = reduced; + } + } + v[j1] -= min2; + } + } + + for (int pass = 0; pass < 2; ++pass) { + int k = 0; int prev_free = n_free; n_free = 0; + while (k < prev_free) { + int i = free_rows[k++]; + lap_cost u1 = cost(i, 0) - v[0]; int j1 = 0; lap_cost u2 = LAP_BIG; + for (int j = 1; j < dim; ++j) { + lap_cost reduced = cost(i, j) - v[j]; + if (reduced < u2) { + if (reduced >= u1) { u2 = reduced; } + else { u2 = u1; u1 = reduced; j1 = j; } + } + } + int i0 = colsol[j1]; + if (u1 < u2) { v[j1] += u1 - u2; } + else if (i0 >= 0) { + int j2 = -1; lap_cost u2_find = LAP_BIG; + for (int j = 0; j < dim; ++j) { + if (j != j1) { lap_cost r2 = cost(i, j) - v[j]; if (r2 < u2_find) { u2_find = r2; j2 = j; } } + } + if (j2 >= 0) { j1 = j2; i0 = colsol[j1]; } + } + rowsol[i] = j1; colsol[j1] = i; + if (i0 >= 0) { if (u1 < u2) free_rows[--k] = i0; else free_rows[n_free++] = i0; } + } + } + + for (int f = 0; f < n_free; ++f) { + int i1 = free_rows[f]; int j1 = -1; + for (int j = 0; j < dim; ++j) { d[j] = cost(i1, j) - v[j]; pred[j] = i1; col_list[j] = j; } + int low = 0, up = 0; + while (true) { + if (up == low) { + lap_cost last_min = LAP_BIG; + for (int k = up; k < dim; ++k) { + int j = col_list[k]; + if (d[j] <= last_min) { if (d[j] < last_min) { last_min = d[j]; up = low; } col_list[k] = col_list[up]; col_list[up] = j; ++up; } + } + for (int k = low; k < up; ++k) { if (colsol[col_list[k]] < 0) { j1 = col_list[k]; goto augment; } } + } + int j_scan = col_list[low++]; int i_scan = colsol[j_scan]; + lap_cost scan_cost = cost(i_scan, j_scan) - v[j_scan] - d[j_scan]; + for (int k = up; k < dim; ++k) { + int j = col_list[k]; lap_cost new_d = cost(i_scan, j) - v[j] - scan_cost; + if (new_d < d[j]) { d[j] = new_d; pred[j] = i_scan; + if (new_d == d[col_list[low]]) { if (colsol[j] < 0) { j1 = j; goto augment; } col_list[k] = col_list[up]; col_list[up++] = j; } + } + } + } + augment: + for (int k = 0; k < low; ++k) { int j = col_list[k]; v[j] += d[j] - d[j1]; } + while (true) { int i_aug = pred[j1]; colsol[j1] = i_aug; int j_prev = rowsol[i_aug]; rowsol[i_aug] = j1; j1 = j_prev; if (i_aug == i1) break; } + } + + lap_cost total = 0; + for (int i = 0; i < dim; ++i) total += cost(i, rowsol[i]); + return total; +} + + +// ========================================================================== +// Clustering entropy +// ========================================================================== + +double clustering_entropy(const CidSplitSet& ss, int n_tips) { + if (n_tips <= 1 || ss.n_splits == 0) return 0.0; + double lg2n = std::log2(static_cast(n_tips)); + double ce = 0.0; + for (int i = 0; i < ss.n_splits; ++i) { + int a = ss.in_split[i]; + int b = n_tips - a; + if (a > 1 && b > 1) { + ce += (a * std::log2(static_cast(a)) + + b * std::log2(static_cast(b))) + / n_tips - lg2n; + } + } + return -ce; +} + +double clustering_entropy_fast(const CidSplitSet& ss, int n_tips, + double lg2_n) { + if (n_tips <= 1 || ss.n_splits == 0) return 0.0; + double ce = 0.0; + for (int i = 0; i < ss.n_splits; ++i) { + int a = ss.in_split[i]; + int b = n_tips - a; + if (a > 1 && b > 1) { + ce += (a * ss.lg2_in[i] + b * ss.lg2_out[i]) / n_tips - lg2_n; + } + } + return -ce; +} + + +// hash_split_key() now in ts_cid.h (inline, shared with ts_spic.cpp) + + +// ========================================================================== +// Mutual clustering information (adapted from TreeDist) +// ========================================================================== + +double mutual_clustering_info(const CidSplitSet& a, const CidSplitSet& b, + int n_tips, LapScratch& scratch) { + int a_n = a.n_splits; + int b_n = b.n_splits; + int n_bins = a.n_bins; + + if (a_n == 0 || b_n == 0 || n_tips == 0) return 0.0; + + double n_recip = 1.0 / n_tips; + double lg2_n = std::log2(static_cast(n_tips)); + bool a_has_logs = (static_cast(a.lg2_in.size()) == a_n); + bool b_has_logs = (static_cast(b.lg2_in.size()) == b_n); + + // Phase 1: find exact matches + double exact_score = 0.0; + int n_exact = 0; + std::vector a_matched(a_n, false); + std::vector b_matched(b_n, false); + + if (!b.hash_index.empty()) { + // Hash-based O(n) exact match + for (int ai = 0; ai < a_n; ++ai) { + uint64_t h = hash_split_key(a.split(ai), n_bins); + auto it = b.hash_index.find(h); + if (it != b.hash_index.end()) { + int bi = it->second; + if (!b_matched[bi] && + std::memcmp(a.split(ai), b.split(bi), + sizeof(uint64_t) * n_bins) == 0) { + int na = a.in_split[ai]; + int nb_val = n_tips - na; + if (a_has_logs) { + exact_score += n_tips * lg2_n - na * a.lg2_in[ai] + - nb_val * a.lg2_out[ai]; + } else { + exact_score += n_tips * lg2_n + - na * std::log2(static_cast(na)) + - nb_val * std::log2(static_cast(nb_val)); + } + a_matched[ai] = true; + b_matched[bi] = true; + ++n_exact; + } + } + } + } else { + // Fallback: O(n^2) scan with complement check + int unset = (n_tips % 64) ? 64 - (n_tips % 64) : 0; + uint64_t last_mask = unset ? (~uint64_t(0)) >> unset : ~uint64_t(0); + for (int ai = 0; ai < a_n; ++ai) { + const uint64_t* a_row = a.split(ai); + for (int bi = 0; bi < b_n; ++bi) { + if (b_matched[bi]) continue; + const uint64_t* b_row = b.split(bi); + bool match = true; + for (int bin = 0; bin < n_bins; ++bin) { + if (a_row[bin] != b_row[bin]) { match = false; break; } + } + if (!match) { + match = true; + for (int bin = 0; bin < n_bins - 1; ++bin) { + if (a_row[bin] != ~b_row[bin]) { match = false; break; } + } + if (match && n_bins > 0) { + match = (a_row[n_bins - 1] == (b_row[n_bins - 1] ^ last_mask)); + } + } + if (match) { + int na = a.in_split[ai]; + int nb_val = n_tips - na; + if (a_has_logs) { + exact_score += n_tips * lg2_n - na * a.lg2_in[ai] + - nb_val * a.lg2_out[ai]; + } else { + exact_score += n_tips * lg2_n + - na * std::log2(static_cast(na)) + - nb_val * std::log2(static_cast(nb_val)); + } + a_matched[ai] = true; + b_matched[bi] = true; + ++n_exact; + break; + } + } + } + } + + if (n_exact == a_n || n_exact == b_n) { + return exact_score * n_recip; + } + + // Phase 2: LAP for remaining unmatched splits + int a_unmatched = a_n - n_exact; + int b_unmatched = b_n - n_exact; + int lap_dim = std::max(a_unmatched, b_unmatched); + + scratch.ensure(lap_dim); + scratch.score_pool.resize(lap_dim); + LapMatrix& score = scratch.score_pool; + + constexpr lap_cost max_score = LAP_BIG / 4096; + double max_over_tips = static_cast(max_score) * n_recip; + + int a_pos = 0; + for (int ai = 0; ai < a_n; ++ai) { + if (a_matched[ai]) continue; + const uint64_t* a_row = a.split(ai); + int na = a.in_split[ai]; + int nA = n_tips - na; + double offset_a = a_has_logs + ? (lg2_n - a.lg2_in[ai]) + : (lg2_n - std::log2(static_cast(na))); + double offset_A = a_has_logs + ? (lg2_n - a.lg2_out[ai]) + : (lg2_n - std::log2(static_cast(nA))); + + int b_pos = 0; + for (int bi = 0; bi < b_n; ++bi) { + if (b_matched[bi]) continue; + const uint64_t* b_row = b.split(bi); + int nb = b.in_split[bi]; + int nB = n_tips - nb; + + int a_and_b = 0; + for (int bin = 0; bin < n_bins; ++bin) { + a_and_b += popcount64(a_row[bin] & b_row[bin]); + } + int a_and_B = na - a_and_b; + int A_and_b = nb - a_and_b; + int A_and_B = nA - A_and_b; + + if (a_and_b == A_and_b && a_and_b == a_and_B && a_and_b == A_and_B) { + score(a_pos, b_pos) = max_score; + } else { + double lg2_nb = b_has_logs ? b.lg2_in[bi] + : ((nb > 0) ? std::log2(static_cast(nb)) : 0); + double lg2_nB = b_has_logs ? b.lg2_out[bi] + : ((nB > 0) ? std::log2(static_cast(nB)) : 0); + double ic_sum = 0.0; + if (a_and_b > 0) + ic_sum += a_and_b * (std::log2(static_cast(a_and_b)) + + offset_a - lg2_nb); + if (a_and_B > 0) + ic_sum += a_and_B * (std::log2(static_cast(a_and_B)) + + offset_a - lg2_nB); + if (A_and_b > 0) + ic_sum += A_and_b * (std::log2(static_cast(A_and_b)) + + offset_A - lg2_nb); + if (A_and_B > 0) + ic_sum += A_and_B * (std::log2(static_cast(A_and_B)) + + offset_A - lg2_nB); + score(a_pos, b_pos) = max_score - + static_cast(ic_sum * max_over_tips); + } + ++b_pos; + } + for (int j = b_unmatched; j < lap_dim; ++j) score(a_pos, j) = max_score; + ++a_pos; + } + for (int i = a_unmatched; i < lap_dim; ++i) { + for (int j = 0; j < lap_dim; ++j) score(i, j) = max_score; + } + + scratch.ensure(lap_dim); + lap_cost lap_total = lap_solve(lap_dim, score, + scratch.rowsol.data(), + scratch.colsol.data(), scratch); + + double lap_score = static_cast( + static_cast(max_score) * lap_dim - lap_total) + / static_cast(max_score); + + return exact_score * n_recip + lap_score; +} + + +// ========================================================================== +// Convert ts::SplitSet to CidSplitSet +// ========================================================================== + +CidSplitSet splitset_to_cid(const SplitSet& ss, int n_tips) { + CidSplitSet cs; + cs.n_splits = ss.n_splits; + cs.n_bins = ss.words_per_split; + cs.data.assign(ss.splits.begin(), ss.splits.end()); + cs.in_split.resize(ss.n_splits); + for (int i = 0; i < ss.n_splits; ++i) { + int cnt = 0; + const uint64_t* sp = ss.split(i); + for (int w = 0; w < ss.words_per_split; ++w) { + cnt += popcount64(sp[w]); + } + cs.in_split[i] = cnt; + } + return cs; +} + + +// ========================================================================== +// Compute splits directly into a preallocated CidSplitSet +// ========================================================================== + +void compute_splits_cid(const TreeState& tree, + std::vector& tip_bits_work, + CidSplitSet& out) { + int n_tip = tree.n_tip; + int wps = (n_tip + 63) / 64; + + size_t total = static_cast(tree.n_node) * wps; + if (tip_bits_work.size() < total) tip_bits_work.resize(total); + std::fill(tip_bits_work.begin(), tip_bits_work.begin() + total, 0); + + for (int t = 0; t < n_tip; ++t) { + tip_bits_work[static_cast(t) * wps + t / 64] = 1ULL << (t % 64); + } + + for (int pi = 0; pi < static_cast(tree.postorder.size()); ++pi) { + int node = tree.postorder[pi]; + int ni = node - n_tip; + int lc = tree.left[ni]; + int rc = tree.right[ni]; + uint64_t* dst = &tip_bits_work[static_cast(node) * wps]; + const uint64_t* lbits = &tip_bits_work[static_cast(lc) * wps]; + const uint64_t* rbits = &tip_bits_work[static_cast(rc) * wps]; + for (int w = 0; w < wps; ++w) dst[w] = lbits[w] | rbits[w]; + } + + int root = n_tip; + int root_right = tree.right[0]; + int trailing = n_tip % 64; + uint64_t trail_mask = (trailing != 0) ? ((1ULL << trailing) - 1) : ~0ULL; + + int n_splits = 0; + for (int pi = 0; pi < static_cast(tree.postorder.size()); ++pi) { + int node = tree.postorder[pi]; + if (node == root || node == root_right) continue; + const uint64_t* bits = &tip_bits_work[static_cast(node) * wps]; + int count = 0; + for (int w = 0; w < wps; ++w) count += popcount64(bits[w]); + if (count <= 1 || count >= n_tip - 1) continue; + ++n_splits; + } + + out.n_splits = n_splits; + out.n_bins = wps; + size_t data_size = static_cast(n_splits) * wps; + if (out.data.size() < data_size) out.data.resize(data_size); + if (static_cast(out.in_split.size()) < n_splits) + out.in_split.resize(n_splits); + if (static_cast(out.lg2_in.size()) < n_splits) + out.lg2_in.resize(n_splits); + if (static_cast(out.lg2_out.size()) < n_splits) + out.lg2_out.resize(n_splits); + + int idx = 0; + for (int pi = 0; pi < static_cast(tree.postorder.size()); ++pi) { + int node = tree.postorder[pi]; + if (node == root || node == root_right) continue; + const uint64_t* bits = &tip_bits_work[static_cast(node) * wps]; + int count = 0; + for (int w = 0; w < wps; ++w) count += popcount64(bits[w]); + if (count <= 1 || count >= n_tip - 1) continue; + + uint64_t* dst = &out.data[static_cast(idx) * wps]; + std::memcpy(dst, bits, sizeof(uint64_t) * wps); + if (dst[0] & 1ULL) { + for (int w = 0; w < wps; ++w) dst[w] = ~dst[w]; + if (trailing != 0) dst[wps - 1] &= trail_mask; + count = n_tip - count; + } + out.in_split[idx] = count; + out.lg2_in[idx] = (count > 0) + ? std::log2(static_cast(count)) : 0.0; + out.lg2_out[idx] = (n_tip - count > 0) + ? std::log2(static_cast(n_tip - count)) : 0.0; + ++idx; + } +} + + +// ========================================================================== +// prepare_cid_data: one-time initialization +// ========================================================================== + +void prepare_cid_data(CidData& cd) { + cd.lg2_n = std::log2(static_cast(cd.n_tips)); + cd.max_splits = 0; + + for (int t = 0; t < cd.n_trees; ++t) { + CidSplitSet& ss = cd.tree_splits[t]; + ss.lg2_in.resize(ss.n_splits); + ss.lg2_out.resize(ss.n_splits); + for (int i = 0; i < ss.n_splits; ++i) { + int a = ss.in_split[i]; + int b = cd.n_tips - a; + ss.lg2_in[i] = (a > 0) ? std::log2(static_cast(a)) : 0.0; + ss.lg2_out[i] = (b > 0) ? std::log2(static_cast(b)) : 0.0; + } + ss.hash_index.clear(); + ss.hash_index.reserve(ss.n_splits); + for (int i = 0; i < ss.n_splits; ++i) { + uint64_t h = hash_split_key(ss.split(i), ss.n_bins); + ss.hash_index.emplace(h, i); + } + if (ss.n_splits > cd.max_splits) cd.max_splits = ss.n_splits; + } + + if (cd.max_splits > 0) { + cd.lap_scratch.ensure(cd.max_splits); + cd.lap_scratch.score_pool.resize(cd.max_splits); + } + + int n_node = 2 * cd.n_tips - 1; + cd.cand_tip_bits.resize(static_cast(n_node) * cd.n_bins, 0); +} + + +// ========================================================================== +// cid_score: score candidate tree against all input trees. +// Returns negated weighted mean MCI (lower = better consensus). +// ========================================================================== + +double cid_score(TreeState& tree, const CidData& cd) { + compute_splits_cid(tree, cd.cand_tip_bits, cd.cand_buf); + CidSplitSet& cand = cd.cand_buf; + double budget = cd.score_budget; + + // Upper bound on per-tree MCI (used for early termination) + double cand_ce = (budget < HUGE_VAL) + ? clustering_entropy_fast(cand, cd.n_tips, cd.lg2_n) + : 0.0; + + double mci_sum = 0.0; + double weight_done = 0.0; + for (int i = 0; i < cd.n_trees; ++i) { + if (cd.tree_weights[i] <= 0.0) continue; + double mci = mutual_clustering_info(cand, cd.tree_splits[i], + cd.n_tips, cd.lap_scratch); + mci_sum += cd.tree_weights[i] * mci; + weight_done += cd.tree_weights[i]; + // Early termination: even with perfect MCI for remaining trees, + // the negated mean can't beat budget + if (budget < HUGE_VAL) { + double remaining = cd.weight_sum - weight_done; + double best_possible = -(mci_sum + remaining * cand_ce) / cd.weight_sum; + if (best_possible > budget) return best_possible; + } + } + return -mci_sum / cd.weight_sum; +} + + +// ========================================================================== +// build_mrp_dataset: construct MRP binary characters for Fitch screening +// +// Deduplicates splits across input trees: each unique bipartition becomes +// one MRP character with pattern_freq = number of trees containing it. +// Splits are already canonicalized (tip 0 in partition 0) by both +// compute_splits_cid() and the R->C++ bridge. +// ========================================================================== + +DataSet build_mrp_dataset(CidData& cd) { + int n_tips = cd.n_tips; + int n_bins = cd.n_bins; + + // --- Phase 1: collect unique splits with deduplication --- + + struct UniqueSplitInfo { + int freq = 0; + std::vector trees; + }; + + // Contiguous storage: unique_split_data[idx * n_bins .. (idx+1) * n_bins) + std::vector unique_split_data; + std::vector unique_info; + std::unordered_multimap hash_to_idx; + + cd.mrp_tree_n_splits.assign(cd.n_trees, 0); + + for (int t = 0; t < cd.n_trees; ++t) { + const CidSplitSet& ss = cd.tree_splits[t]; + cd.mrp_tree_n_splits[t] = ss.n_splits; + + for (int s = 0; s < ss.n_splits; ++s) { + const uint64_t* sp = ss.split(s); + uint64_t h = hash_split_key(sp, n_bins); + + // Check existing entries with this hash + int found = -1; + auto range = hash_to_idx.equal_range(h); + for (auto it = range.first; it != range.second; ++it) { + int idx = it->second; + const uint64_t* existing = &unique_split_data[ + static_cast(idx) * n_bins]; + if (std::memcmp(sp, existing, + sizeof(uint64_t) * n_bins) == 0) { + found = idx; + break; + } + } + + if (found >= 0) { + unique_info[found].freq++; + unique_info[found].trees.push_back(t); + } else { + int new_idx = static_cast(unique_info.size()); + unique_split_data.insert(unique_split_data.end(), + sp, sp + n_bins); + unique_info.push_back({1, {t}}); + hash_to_idx.emplace(h, new_idx); + } + } + } + + int total_chars = static_cast(unique_info.size()); + + // --- Phase 2: build CharBlocks from unique splits --- + + DataSet ds; + ds.n_tips = n_tips; + ds.scoring_mode = ScoringMode::CID; + ds.cid_data = &cd; + ds.concavity = cd.mrp_concavity; + + static constexpr int N_STATES = 2; + + ds.blocks.clear(); + + for (int c = 0; c < total_chars; ++c) { + if (c % MAX_CHARS_PER_BLOCK == 0) { + CharBlock blk; + blk.n_chars = 0; + blk.n_states = N_STATES; + blk.weight = 1; + blk.has_inapplicable = false; + blk.active_mask = 0; + blk.upweight_mask = 0; + std::memset(blk.pattern_index, 0, sizeof(blk.pattern_index)); + ds.blocks.push_back(blk); + } + int local_idx = c % MAX_CHARS_PER_BLOCK; + ds.blocks.back().n_chars = local_idx + 1; + ds.blocks.back().active_mask |= (uint64_t(1) << local_idx); + ds.blocks.back().pattern_index[local_idx] = c; + } + if (ds.blocks.empty()) { + // Edge case: no splits at all + CharBlock blk; + blk.n_chars = 0; + blk.n_states = N_STATES; + blk.weight = 1; + blk.has_inapplicable = false; + blk.active_mask = 0; + blk.upweight_mask = 0; + std::memset(blk.pattern_index, 0, sizeof(blk.pattern_index)); + ds.blocks.push_back(blk); + } + + ds.n_blocks = static_cast(ds.blocks.size()); + ds.total_words = ds.n_blocks * N_STATES; + ds.block_word_offset.resize(ds.n_blocks); + for (int b = 0; b < ds.n_blocks; ++b) { + ds.block_word_offset[b] = b * N_STATES; + } + + // --- Phase 3: build tip_states from unique splits --- + + size_t tip_state_size = static_cast(n_tips) * ds.total_words; + ds.tip_states.assign(tip_state_size, 0); + + int blk_i = 0; + for (int c = 0; c < total_chars; ++c) { + int local_idx = c % MAX_CHARS_PER_BLOCK; + uint64_t bit = uint64_t(1) << local_idx; + if (local_idx == 0 && c > 0) ++blk_i; + int word_off = ds.block_word_offset[blk_i]; + + const uint64_t* split_data = &unique_split_data[ + static_cast(c) * n_bins]; + + for (int tip = 0; tip < n_tips; ++tip) { + size_t base = static_cast(tip) * ds.total_words + word_off; + int word_in_split = tip / 64; + int bit_in_word = tip % 64; + bool in_split = (word_in_split < n_bins) && + ((split_data[word_in_split] >> bit_in_word) & 1); + if (in_split) { + ds.tip_states[base + 1] |= bit; + } else { + ds.tip_states[base + 0] |= bit; + } + } + } + + // --- Phase 4: metadata --- + + ds.n_patterns = total_chars; + ds.ew_offset = 0; + ds.precomputed_steps.assign(total_chars, 0); + ds.min_steps.assign(total_chars, 1); + + // pattern_freq = number of input trees containing each unique split + ds.pattern_freq.resize(total_chars); + for (int c = 0; c < total_chars; ++c) { + ds.pattern_freq[c] = unique_info[c].freq; + } + + // IW weight arrays: binary MRP characters have min_steps = 1. + double k = std::isfinite(ds.concavity) ? ds.concavity : 0.0; + ds.eff_k.assign(total_chars, k); + ds.phi.assign(total_chars, 1.0); + + // --- Phase 5: populate CidData reverse index --- + + cd.mrp_split_trees.resize(total_chars); + for (int c = 0; c < total_chars; ++c) { + cd.mrp_split_trees[c] = std::move(unique_info[c].trees); + } + + return ds; +} + + +// ========================================================================== +// CID weight management for ratchet +// ========================================================================== + +void save_cid_weights(CidData& cd) { + cd.saved_tree_weights = cd.tree_weights; + cd.saved_weight_sum = cd.weight_sum; +} + +void restore_cid_weights(CidData& cd) { + cd.tree_weights = cd.saved_tree_weights; + cd.weight_sum = cd.saved_weight_sum; +} + +void sync_cid_weights_from_mrp(CidData& cd, const DataSet& ds) { + // Map MRP perturbation (active/upweight masks) back to per-tree CID + // weights using the dedup reverse index. + std::fill(cd.tree_weights.begin(), cd.tree_weights.end(), 0.0); + + for (int p = 0; p < ds.n_patterns; ++p) { + int blk = p / MAX_CHARS_PER_BLOCK; + int bit = p % MAX_CHARS_PER_BLOCK; + bool active = ds.blocks[blk].active_mask & (uint64_t(1) << bit); + bool upweighted = ds.blocks[blk].upweight_mask & (uint64_t(1) << bit); + double contrib = (active ? 1.0 : 0.0) + (upweighted ? 1.0 : 0.0); + if (contrib > 0.0) { + for (int t : cd.mrp_split_trees[p]) { + cd.tree_weights[t] += contrib; + } + } + } + + cd.weight_sum = 0.0; + for (int t = 0; t < cd.n_trees; ++t) { + if (cd.mrp_tree_n_splits[t] > 0) { + cd.tree_weights[t] /= cd.mrp_tree_n_splits[t]; + } + cd.weight_sum += cd.tree_weights[t]; + } +} + +} // namespace ts diff --git a/src/ts_cid.h b/src/ts_cid.h new file mode 100644 index 000000000..cc20de633 --- /dev/null +++ b/src/ts_cid.h @@ -0,0 +1,244 @@ +#ifndef TS_CID_H +#define TS_CID_H + +// CID (Clustering Information Distance) scoring for the driven search. +// +// Scores a candidate tree against a set of precomputed input tree splits +// using mutual clustering information (MCI) with a LAP solver. +// +// MRP (Matrix Representation with Parsimony) characters provide fast +// incremental screening for TBR candidate selection; CID is computed +// via score_tree() for verification only. +// +// The MCI algorithm is adapted from TreeDist (Smith 2020). +// When TreeDist exposes LinkingTo headers, this local copy should be +// replaced with #include . + +#include "ts_data.h" +#include "ts_tree.h" +#include "ts_splits.h" +#include +#include +#include +#include +#include + +namespace ts { + +// -------------------------------------------------------------------------- +// CID split set: precomputed splits for one tree +// -------------------------------------------------------------------------- +struct CidSplitSet { + int n_splits = 0; + int n_bins = 0; // ceil(n_tips / 64) + std::vector data; // n_splits * n_bins, contiguous + std::vector in_split; // popcount per split + + // Precomputed log2 values per split (populated by prepare_cid_data) + std::vector lg2_in; // log2(in_split[i]) + std::vector lg2_out; // log2(n_tips - in_split[i]) + + // Hash index for O(1) exact-match lookup (populated by prepare_cid_data). + // Maps split hash -> split index. Only built for input tree split sets. + std::unordered_map hash_index; + + const uint64_t* split(int i) const { + return &data[static_cast(i) * n_bins]; + } +}; + +// -------------------------------------------------------------------------- +// LAP cost matrix (simplified from TreeDist's CostMatrix) +// -------------------------------------------------------------------------- +// Integer cost matrix for the Jonker-Volgenant LAP solver. +// Row-major: element (i,j) at data_[i * dim_padded_ + j]. +using lap_cost = int_fast64_t; +static constexpr lap_cost LAP_BIG = + std::numeric_limits::max() / 4096; +static constexpr size_t LAP_BLOCK = 16; + +struct LapMatrix { + int dim_ = 0; + int dim_padded_ = 0; + std::vector data_; + + LapMatrix() = default; + + void resize(int dim) { + dim_ = dim; + dim_padded_ = static_cast( + ((static_cast(dim) + LAP_BLOCK - 1) / LAP_BLOCK) * LAP_BLOCK); + size_t needed = static_cast(dim_padded_) * dim_padded_; + if (data_.size() < needed) data_.resize(needed, 0); + } + + lap_cost& operator()(int r, int c) { + return data_[static_cast(r) * dim_padded_ + c]; + } + const lap_cost& operator()(int r, int c) const { + return data_[static_cast(r) * dim_padded_ + c]; + } + lap_cost* row(int r) { + return &data_[static_cast(r) * dim_padded_]; + } + const lap_cost* row(int r) const { + return &data_[static_cast(r) * dim_padded_]; + } + + void pad_row_after(int r, int start_col, lap_cost val) { + size_t off = static_cast(r) * dim_padded_; + std::fill(data_.begin() + off + start_col, + data_.begin() + off + dim_, val); + } + void pad_after_row(int start_row, lap_cost val) { + size_t off = static_cast(start_row) * dim_padded_; + std::fill(data_.begin() + off, + data_.begin() + static_cast(dim_) * dim_padded_, val); + } +}; + +// Reusable scratch for LAP solver +struct LapScratch { + std::vector v; + std::vector matches; + std::vector free_rows; + std::vector col_list; + std::vector d; + std::vector pred; + std::vector rowsol; + std::vector colsol; + LapMatrix score_pool; // reusable cost matrix + + void ensure(int dim) { + int padded = static_cast( + ((static_cast(dim) + LAP_BLOCK - 1) / LAP_BLOCK) * LAP_BLOCK); + if (static_cast(v.size()) < padded) v.resize(padded); + if (static_cast(matches.size()) < dim) matches.resize(dim); + if (static_cast(free_rows.size()) < dim) free_rows.resize(dim); + if (static_cast(col_list.size()) < dim) col_list.resize(dim); + if (static_cast(d.size()) < dim) d.resize(dim); + if (static_cast(pred.size()) < dim) pred.resize(dim); + if (static_cast(rowsol.size()) < dim) rowsol.resize(dim); + if (static_cast(colsol.size()) < dim) colsol.resize(dim); + } +}; + +// -------------------------------------------------------------------------- +// CidData: all precomputed data for CID scoring +// -------------------------------------------------------------------------- +struct CidData { + int n_trees; + int n_tips; + int n_bins; // ceil(n_tips / 64) + + // Precomputed input tree splits + std::vector tree_splits; + + // Precomputed per-tree clustering entropies + std::vector tree_ce; + double mean_tree_ce; + + // Per-tree weights (1.0 normally; modified during ratchet) + std::vector tree_weights; + double weight_sum; + + // Saved weights for ratchet restore + std::vector saved_tree_weights; + double saved_weight_sum; + + // Vestigial; no longer used by cid_score() (was normalized scoring mode). + bool normalize; + + // MRP screening parameters. + double mrp_concavity = 7.0; + double screening_tolerance = 0.0; + // Number of top MRP candidates to CID-score per TBR clip. + // 1 = current single-best behaviour; >1 enables batch CID evaluation + // of the top-k MRP candidates, allowing the search to find moves + // where CID and MRP rankings disagree. + int cid_top_k = 1; + + // --- MRP dedup reverse index (populated by build_mrp_dataset) --- + // mrp_split_trees[i] = list of input tree indices containing unique + // MRP character i. Used by sync_cid_weights_from_mrp() to map + // ratchet perturbations back to per-tree CID weights. + std::vector> mrp_split_trees; + // mrp_tree_n_splits[t] = total original splits in input tree t + // (denominator for per-tree weight normalization). + std::vector mrp_tree_n_splits; + + // --- Precomputed constants (populated by prepare_cid_data) --- + double lg2_n = 0.0; // log2(n_tips) + int max_splits = 0; // max n_splits across all input trees + + // --- Persistent candidate buffers (reused across cid_score calls) --- + mutable std::vector cand_tip_bits; + mutable CidSplitSet cand_buf; + mutable std::vector match_a, match_b; + + // Score budget for early termination. Set < HUGE_VAL to enable. + mutable double score_budget = HUGE_VAL; + + // LAP scratch (reused across cid_score calls) + mutable LapScratch lap_scratch; +}; + +// -------------------------------------------------------------------------- +// Public API +// -------------------------------------------------------------------------- + +// Score a candidate tree against input trees. +// Returns negated weighted mean MCI (lower = better consensus). +double cid_score(TreeState& tree, const CidData& cd); + +// Build an MRP DataSet from CidData. +DataSet build_mrp_dataset(CidData& cd); + +// Prepare CidData after tree_splits are populated: build hash indices, +// precompute log2 values, presize scratch buffers. +void prepare_cid_data(CidData& cd); + +// Convert a SplitSet (from ts_splits.h) to a CidSplitSet. +CidSplitSet splitset_to_cid(const SplitSet& ss, int n_tips); + +// Compute splits directly into a preallocated CidSplitSet. +void compute_splits_cid(const TreeState& tree, + std::vector& tip_bits_work, + CidSplitSet& out); + +// Compute clustering entropy of a split set. +double clustering_entropy(const CidSplitSet& ss, int n_tips); + +// Compute clustering entropy using precomputed log2 values. +double clustering_entropy_fast(const CidSplitSet& ss, int n_tips, + double lg2_n); + +// Compute mutual clustering information between two split sets. +double mutual_clustering_info(const CidSplitSet& a, const CidSplitSet& b, + int n_tips, LapScratch& scratch); + +// Jonker-Volgenant LAP solver. +lap_cost lap_solve(int dim, LapMatrix& cost, + int* rowsol, int* colsol, LapScratch& scratch); + +// Save / restore CidData tree weights for ratchet perturbation. +void save_cid_weights(CidData& cd); +void restore_cid_weights(CidData& cd); + +// Synchronize CidData tree weights with MRP block perturbation. +void sync_cid_weights_from_mrp(CidData& cd, const DataSet& ds); + +// FNV-1a hash for split data (used for O(1) lookup in frequency tables). +inline uint64_t hash_split_key(const uint64_t* data, int n_bins) { + if (n_bins == 1) return data[0]; + uint64_t h = 14695981039346656037ULL; + for (int i = 0; i < n_bins; ++i) { + h ^= data[i]; + h *= 1099511628211ULL; + } + return h; +} + +} // namespace ts + +#endif // TS_CID_H diff --git a/src/ts_data.h b/src/ts_data.h index e99d80a8b..ebe726406 100644 --- a/src/ts_data.h +++ b/src/ts_data.h @@ -59,7 +59,20 @@ inline int ctz64(uint64_t x) { static constexpr int MAX_CHARS_PER_BLOCK = 64; static constexpr int MAX_STATES = 32; // practical limit for morphological data -enum class ScoringMode { EW, IW, XPIWE, PROFILE, HSJ, XFORM }; +enum class ScoringMode { EW, IW, XPIWE, PROFILE, HSJ, XFORM, CID, SPIC }; + +// CID and SPIC both use MRP-based Fitch screening with a separate +// information-theoretic objective. All search modules that special-case +// CID mode must also cover SPIC. +inline bool is_cid_like(ScoringMode m) { + return m == ScoringMode::CID || m == ScoringMode::SPIC; +} + +// Forward declaration for CID scoring data (defined in ts_cid.h). +struct CidData; + +// Forward declaration for SPIC scoring data (defined in ts_spic.h). +struct SpicData; // A hierarchy block describes one controlling primary + its secondaries // (Hopkins & St. John 2021). Used by HSJ scoring. @@ -175,6 +188,14 @@ struct DataSet { // where stride = n_chars * max_states. // 0.0 = state allowed, INF = state disallowed. std::vector sankoff_tip_costs; + + // CID scoring data (populated when scoring_mode == CID). + // Owned by the caller; DataSet holds a non-owning pointer. + CidData* cid_data = nullptr; + + // SPIC scoring data (populated when scoring_mode == SPIC). + // Owned by the caller; DataSet holds a non-owning pointer. + SpicData* spic_data = nullptr; }; // Build a DataSet from R-side data. diff --git a/src/ts_drift.cpp b/src/ts_drift.cpp index f47129c47..25e40ccef 100644 --- a/src/ts_drift.cpp +++ b/src/ts_drift.cpp @@ -1,4 +1,5 @@ #include "ts_drift.h" +#include "ts_cid.h" #include "ts_collapsed.h" #include "ts_constraint.h" #include "ts_fitch.h" @@ -20,7 +21,37 @@ namespace ts { static double drift_full_rescore(TreeState& tree, const DataSet& ds) { tree.reset_states(ds); - return score_tree(tree, ds); + double s = score_tree(tree, ds); + if (is_cid_like(ds.scoring_mode)) { + fitch_score(tree, ds); + } + return s; +} + +// Compute MRP screening score from already-populated Fitch state arrays. +static double drift_mrp_score(const TreeState& tree, const DataSet& ds, + std::vector& char_steps) { + std::fill(char_steps.begin(), char_steps.end(), 0); + for (int node : tree.postorder) { + for (int b = 0; b < ds.n_blocks; ++b) { + const CharBlock& blk = ds.blocks[b]; + uint64_t mask = + tree.local_cost[static_cast(node) * tree.n_blocks + b]; + while (mask) { + int c = ts::ctz64(mask); + char_steps[blk.pattern_index[c]] += 1; + mask &= mask - 1; + } + } + } + if (std::isfinite(ds.concavity)) { + return compute_weighted_score(ds, char_steps); + } + int total = 0; + for (int p = 0; p < ds.n_patterns; ++p) { + total += char_steps[p] * ds.pattern_freq[p]; + } + return static_cast(total) + ds.ew_offset; } static void drift_collect_main_edges( @@ -325,8 +356,17 @@ static int drift_phase(TreeState& tree, const DataSet& ds, double score = drift_full_rescore(tree, ds); int n_accepted = 0; const bool use_iw = std::isfinite(ds.concavity); + const bool is_cid = is_cid_like(ds.scoring_mode); const double eps = use_iw ? 1e-10 : 0.0; + // CID mode: track MRP screening score separately from CID score. + std::vector mrp_steps_buf; + double mrp_score_val = score; + if (is_cid) { + mrp_steps_buf.resize(ds.n_patterns, 0); + mrp_score_val = drift_mrp_score(tree, ds, mrp_steps_buf); + } + bool has_na = false; for (int b = 0; b < ds.n_blocks; ++b) { if (ds.blocks[b].has_inapplicable) { has_na = true; break; } @@ -435,7 +475,7 @@ static int drift_phase(TreeState& tree, const DataSet& ds, if (ds.blocks[b].upweight_mask) nu += popcount64(lc & ds.blocks[b].upweight_mask); nx_cost += ds.blocks[b].weight * nu; } - divided_length = score + delta - nx_cost; + divided_length = mrp_score_val + delta - nx_cost; } // Weighted scoring (IW or profile): precompute base score and deltas @@ -573,7 +613,8 @@ static int drift_phase(TreeState& tree, const DataSet& ds, if (best_candidate >= HUGE_VAL || best_above < 0) continue; - double delta_score = best_candidate - score; + // AFD check: use MRP screening score (not CID) for delta + double delta_score = best_candidate - mrp_score_val; if (delta_score > afd_limit + eps) { continue; @@ -590,6 +631,7 @@ static int drift_phase(TreeState& tree, const DataSet& ds, drift_restore_topology(tree, snap); tree.build_postorder(); drift_full_rescore(tree, ds); + if (is_cid) mrp_score_val = drift_mrp_score(tree, ds, mrp_steps_buf); continue; } @@ -620,12 +662,16 @@ static int drift_phase(TreeState& tree, const DataSet& ds, // Improvement: always accept tree.build_postorder(); score = drift_full_rescore(tree, ds); + if (is_cid) mrp_score_val = drift_mrp_score(tree, ds, mrp_steps_buf); + else mrp_score_val = score; ++n_accepted; if (constrained) update_constraint(tree, *cd); } else if (std::fabs(delta_score) <= eps) { // Equal: always accept tree.build_postorder(); score = drift_full_rescore(tree, ds); + if (is_cid) mrp_score_val = drift_mrp_score(tree, ds, mrp_steps_buf); + else mrp_score_val = score; ++n_accepted; if (constrained) update_constraint(tree, *cd); } else { @@ -633,20 +679,22 @@ static int drift_phase(TreeState& tree, const DataSet& ds, tree.build_postorder(); double new_score = drift_full_rescore(tree, ds); - if (use_iw) { - // Under IW, use score-based RFD: (worsening - improving) / worsening - // Simplify to score delta ratio - double rfd = (new_score > score && score > 0.0) - ? (new_score - score) / new_score : 0.0; + if (use_iw || is_cid) { + // Under IW (or CID with IW screening), use score-based RFD + double new_mrp = is_cid ? drift_mrp_score(tree, ds, mrp_steps_buf) : new_score; + double rfd = (new_mrp > mrp_score_val && mrp_score_val > 0.0) + ? (new_mrp - mrp_score_val) / new_mrp : 0.0; if (rfd <= rfd_limit) { score = new_score; + mrp_score_val = new_mrp; ++n_accepted; if (constrained) update_constraint(tree, *cd); } else { drift_restore_topology(tree, snap); tree.build_postorder(); score = drift_full_rescore(tree, ds); + if (is_cid) mrp_score_val = drift_mrp_score(tree, ds, mrp_steps_buf); } } else { // EW: original local_cost-based RFD diff --git a/src/ts_driven.cpp b/src/ts_driven.cpp index 099c458fa..a157e9c04 100644 --- a/src/ts_driven.cpp +++ b/src/ts_driven.cpp @@ -77,8 +77,10 @@ ReplicateResult run_single_replicate( }; // NNI warmup per Wagner start is skipped when constraints are active - // because nni_search() does not enforce topological constraints. - bool nni_wagner = params.nni_first && (!cd || !cd->active); + // (nni_search() does not enforce constraints) and for CID mode + // (nni_search() lacks dual MRP/CID score tracking). + bool nni_wagner = params.nni_first && (!cd || !cd->active) + && !is_cid_like(ds.scoring_mode); // 1. Starting tree: dispatch on StartStrategy. // @@ -151,7 +153,7 @@ ReplicateResult run_single_replicate( } else { Rprintf(" %s%s tree score: %.5g [%.0f ms]%s\n", strategy_name(strategy), - params.nni_first ? "+NNI" : "", + nni_wagner ? "+NNI" : "", best_wag, result.timings.wagner_ms, params.wagner_starts > 1 ? " (best of multiple starts)" : ""); } @@ -854,7 +856,7 @@ DrivenResult driven_search(TreePool& pool, DataSet& ds, // Add to pool with collapsed-topology dedup double prev_best = pool.best_score(); pool.add_collapsed(rep_result.tree, rep_result.score, rep_collapsed); - bool score_improved = pool.best_score() < prev_best; + bool score_improved = pool.best_score() < prev_best - params.score_tol; if (score_improved) { result.last_improved_rep = rep1; unsuccessful_reps = 0; @@ -977,6 +979,20 @@ DrivenResult driven_search(TreePool& pool, DataSet& ds, break; } + // Plateau stopping (absolute count, for continuous-score modes like CID) + if (params.plateau_reps > 0 && + unsuccessful_reps >= params.plateau_reps) { + if (params.verbosity >= 1) { + if (!has_callback) { + Rprintf("Stopped: %d consecutive replicates without meaningful " + "improvement (plateau_reps %d, score_tol %.4g)\n", + unsuccessful_reps, params.plateau_reps, params.score_tol); + } + } + result.plateau_stop = true; + break; + } + if (ts::check_interrupt() || check_timeout()) { result.timed_out = true; goto finish; diff --git a/src/ts_driven.h b/src/ts_driven.h index 35102ea74..40b0c7678 100644 --- a/src/ts_driven.h +++ b/src/ts_driven.h @@ -182,6 +182,20 @@ struct DrivenParams { // replicates that fail to improve the best score. Resets on // every improvement. int perturb_stop_factor = 0; + + // Minimum score improvement to count as meaningful (for convergence + // detection). Default 0.0 = any strict improvement counts. When > 0, + // improvements smaller than score_tol do not reset the unsuccessful- + // replicate counter. Useful for continuous-score modes like CID where + // trivially small improvements can prevent convergence detection. + double score_tol = 0.0; + + // Plateau stopping: stop after this many consecutive replicates without + // meaningful improvement. 0 = disabled. Unlike perturb_stop_factor + // (which scales as nTip * factor), this is an absolute count suitable + // for small replicate budgets. + int plateau_reps = 0; + // Adaptive search level. // When true, dynamically scale ratchet_cycles and drift_cycles based // on the hit rate (fraction of replicates that find the current best @@ -272,6 +286,7 @@ struct DrivenResult { int last_improved_rep; // 1-based replicate that last improved score (0 = not tracked) bool timed_out; // true if search ended due to timeout bool consensus_stable; // true if stopped by consensus stability + bool plateau_stop; // true if stopped by plateau_reps PhaseTimings timings; // cumulative across all replicates // Per-strategy diagnostics (populated when adaptive_start is true) diff --git a/src/ts_fitch.cpp b/src/ts_fitch.cpp index 4223c0382..6a700761a 100644 --- a/src/ts_fitch.cpp +++ b/src/ts_fitch.cpp @@ -1,6 +1,8 @@ #include "ts_fitch.h" #include "ts_hsj.h" #include "ts_sankoff.h" +#include "ts_cid.h" +#include "ts_spic.h" #include #include @@ -791,6 +793,13 @@ double fitch_score_ew(TreeState& tree, const DataSet& ds) { } double score_tree(TreeState& tree, const DataSet& ds) { + if (ds.scoring_mode == ScoringMode::CID) { + return cid_score(tree, *ds.cid_data); + } + if (ds.scoring_mode == ScoringMode::SPIC) { + return spic_score(tree, *ds.spic_data); + } + if (ds.scoring_mode == ScoringMode::HSJ) { // HSJ: Fitch on non-hierarchy chars + HSJ DP on hierarchy blocks. // hsj_score() calls fitch_score_ew() internally, avoiding recursion. diff --git a/src/ts_parallel.cpp b/src/ts_parallel.cpp index bbe2d98e9..2da53b4bd 100644 --- a/src/ts_parallel.cpp +++ b/src/ts_parallel.cpp @@ -5,6 +5,8 @@ #include "ts_fitch.h" #include "ts_fuse.h" #include "ts_tbr.h" +#include "ts_cid.h" +#include "ts_spic.h" #include #include @@ -107,6 +109,21 @@ void worker_thread(WorkerContext ctx) { // Make thread-local copies of mutable data DataSet ds_local = *ctx.ds_prototype; + // Deep-copy CidData so each thread has its own mutable scratch + // buffers (lap_scratch, cand_tip_bits, cand_buf, score_budget). + CidData cid_local; + if (ds_local.cid_data) { + cid_local = *ds_local.cid_data; + ds_local.cid_data = &cid_local; + } + + // Deep-copy SpicData for thread-local scratch buffers. + SpicData spic_local; + if (ds_local.spic_data) { + spic_local = *ds_local.spic_data; + ds_local.spic_data = &spic_local; + } + ConstraintData cd_local; ConstraintData* cd_ptr = nullptr; if (ctx.cd_prototype && ctx.cd_prototype->active) { @@ -373,7 +390,7 @@ DrivenResult parallel_driven_search( if (perturb_stop_limit > 0) { int done = replicates_done.load(std::memory_order_relaxed); double cur_best = shared_pool.best_score(); - if (cur_best < last_known_best) { + if (cur_best < last_known_best - params.score_tol) { last_known_best = cur_best; reps_at_last_improvement = done; } @@ -388,6 +405,32 @@ DrivenResult parallel_driven_search( break; } } + + // Plateau stopping (absolute count, parallel path) + if (params.plateau_reps > 0) { + int done = replicates_done.load(std::memory_order_relaxed); + double cur_best = shared_pool.best_score(); + // Reuse last_known_best tracking from perturbation stop above; + // if perturb_stop_limit == 0, we need our own tracking. + if (perturb_stop_limit == 0) { + if (cur_best < last_known_best - params.score_tol) { + last_known_best = cur_best; + reps_at_last_improvement = done; + } + } + if (done - reps_at_last_improvement >= params.plateau_reps) { + stop_flag.store(true, std::memory_order_relaxed); + if (params.verbosity >= 1) { + Rprintf("Stopped: %d consecutive replicates without meaningful " + "improvement (plateau_reps %d, score_tol %.4g)\n", + done - reps_at_last_improvement, params.plateau_reps, + params.score_tol); + } + result.plateau_stop = true; + break; + } + } + // Progress reporting if (params.verbosity >= 1) { auto st = shared_pool.status(); diff --git a/src/ts_ratchet.cpp b/src/ts_ratchet.cpp index b2e6e0845..b2359ccaf 100644 --- a/src/ts_ratchet.cpp +++ b/src/ts_ratchet.cpp @@ -1,6 +1,7 @@ #include "ts_ratchet.h" #include "ts_tbr.h" #include "ts_fitch.h" +#include "ts_cid.h" #include "ts_rng.h" #include @@ -28,6 +29,7 @@ void save_perturb_state(const DataSet& ds, PerturbSnapshot& snap) { snap.upweight_masks[b] = ds.blocks[b].upweight_mask; } snap.pattern_freq = ds.pattern_freq; + if (ds.cid_data) save_cid_weights(*ds.cid_data); } void restore_perturb_state(DataSet& ds, const PerturbSnapshot& snap) { @@ -36,6 +38,7 @@ void restore_perturb_state(DataSet& ds, const PerturbSnapshot& snap) { ds.blocks[b].upweight_mask = snap.upweight_masks[b]; } ds.pattern_freq = snap.pattern_freq; + if (ds.cid_data) restore_cid_weights(*ds.cid_data); } // --- Perturbation modes --- @@ -185,6 +188,9 @@ RatchetResult ratchet_search(TreeState& tree, DataSet& ds, break; } + // Synchronize CID tree weights with perturbed MRP blocks + if (ds.cid_data) sync_cid_weights_from_mrp(*ds.cid_data, ds); + // 2. Short TBR on perturbed landscape TBRResult perturb_result = tbr_search(tree, ds, perturb_params, cd, nullptr, nullptr, check_timeout); diff --git a/src/ts_rcpp.cpp b/src/ts_rcpp.cpp index 062ad1469..0c73fa4b1 100644 --- a/src/ts_rcpp.cpp +++ b/src/ts_rcpp.cpp @@ -22,6 +22,8 @@ #include "ts_hsj.h" // ts_temper.h removed — parallel tempering lives on feature/parallel-temper #include "ts_strategy.h" +#include "ts_cid.h" +#include "ts_spic.h" using namespace Rcpp; @@ -1243,6 +1245,12 @@ static void unpack_search_control(List ctrl, ts::DrivenParams& params) { params.adaptive_start = as(ctrl["adaptiveStart"]); params.enum_time_fraction = as(ctrl["enumTimeFraction"]); + // Convergence tolerance (CID / continuous-score modes) + if (ctrl.containsElementNamed("scoreTol")) + params.score_tol = as(ctrl["scoreTol"]); + if (ctrl.containsElementNamed("plateauReps")) + params.plateau_reps = as(ctrl["plateauReps"]); + // Taxon pruning-reinsertion (T-266) params.prune_reinsert_cycles = as(ctrl["pruneReinsertCycles"]); params.prune_reinsert_drop = as(ctrl["pruneReinsertDrop"]); @@ -2645,3 +2653,682 @@ List ts_test_strategy_tracker(int seed, int n_draws) { ); } +// [[Rcpp::export]] +List ts_cid_consensus( + List splitMatrices, + IntegerVector nTip, + LogicalVector normalize, + int maxReplicates = 100, + int targetHits = 10, + int tbrMaxHits = 1, + int ratchetCycles = 10, + double ratchetPerturbProb = 0.04, + int ratchetPerturbMode = 0, + bool ratchetAdaptive = false, + int driftCycles = 6, + int driftAfdLimit = 3, + double driftRfdLimit = 0.1, + int xssRounds = 0, + int xssPartitions = 4, + int rssRounds = 0, + int cssRounds = 0, + int cssPartitions = 4, + int sectorMinSize = 6, + int sectorMaxSize = 50, + int fuseInterval = 3, + bool fuseAcceptEqual = false, + int poolMaxSize = 100, + double poolSuboptimal = 0.0, + double maxSeconds = 0.0, + int verbosity = 0, + int tabuSize = 100, + int wagnerStarts = 1, + int nThreads = 1, + double screeningK = 7.0, + double screeningTolerance = 0.0, + int screeningTopK = 1, + double scoreTol = 0.0, + int plateauReps = 0, + Nullable startEdge = R_NilValue, + Nullable progressCallback = R_NilValue, + int scoringMethod = 0) +{ + // scoringMethod: 0 = MCI (default), 1 = SPIC + int n_tip = nTip[0]; + bool norm = normalize[0]; + int n_trees = splitMatrices.size(); + + if (n_trees == 0) { + Rcpp::stop("No input trees provided."); + } + + // --- Build CidData from R split matrices --- + int n_bins = (n_tip + 63) / 64; + + ts::CidData cid_data; + cid_data.n_trees = n_trees; + cid_data.n_tips = n_tip; + cid_data.n_bins = n_bins; + cid_data.normalize = norm; + cid_data.mrp_concavity = (screeningK <= 0.0 || !R_finite(screeningK)) + ? HUGE_VAL : screeningK; + cid_data.screening_tolerance = std::max(0.0, screeningTolerance); + cid_data.cid_top_k = std::max(1, screeningTopK); + cid_data.tree_splits.resize(n_trees); + cid_data.tree_ce.resize(n_trees); + cid_data.tree_weights.assign(n_trees, 1.0); + cid_data.weight_sum = static_cast(n_trees); + + // Unset-tips mask for canonical split orientation + int unset = (n_tip % 64) ? 64 - (n_tip % 64) : 0; + uint64_t last_mask = unset ? (~uint64_t(0)) >> unset : ~uint64_t(0); + + for (int t = 0; t < n_trees; ++t) { + RawMatrix rm = as(splitMatrices[t]); + int n_splits = rm.nrow(); + int n_r_cols = rm.ncol(); // R raw columns (8 bits each) + int n_bins_from_r = (n_r_cols + 7) / 8; // 8 raw bytes per 64-bit word + if (n_bins_from_r > n_bins) n_bins_from_r = n_bins; + + ts::CidSplitSet& ss = cid_data.tree_splits[t]; + ss.n_splits = n_splits; + ss.n_bins = n_bins; + ss.data.assign(static_cast(n_splits) * n_bins, 0); + ss.in_split.resize(n_splits, 0); + + for (int s = 0; s < n_splits; ++s) { + uint64_t* sp = &ss.data[static_cast(s) * n_bins]; + + // Unpack R's raw matrix (column-major, 8 bits per column) + for (int col = 0; col < n_r_cols; ++col) { + int word = col / 8; + int byte_pos = col % 8; + if (word < n_bins) { + sp[word] |= static_cast( + static_cast(rm(s, col))) << (byte_pos * 8); + } + } + + // Ensure canonical form: tip 0 in partition 0 + if (sp[0] & 1) { + for (int w = 0; w < n_bins - 1; ++w) sp[w] = ~sp[w]; + if (n_bins > 0) sp[n_bins - 1] ^= last_mask; + } + + // Popcount + int cnt = 0; + for (int w = 0; w < n_bins; ++w) cnt += ts::popcount64(sp[w]); + ss.in_split[s] = cnt; + } + + cid_data.tree_ce[t] = ts::clustering_entropy(ss, n_tip); + } + cid_data.mean_tree_ce = 0.0; + for (int t = 0; t < n_trees; ++t) { + cid_data.mean_tree_ce += cid_data.tree_ce[t]; + } + cid_data.mean_tree_ce /= n_trees; + + // --- Prepare CID data (hash indices, log2 values, scratch presizing) --- + ts::prepare_cid_data(cid_data); + + // --- Build SPIC data if needed --- + ts::SpicData spic_data; + if (scoringMethod == 1) { + spic_data = ts::build_spic_data(cid_data); + } + + // --- Build MRP DataSet --- + ts::DataSet ds = ts::build_mrp_dataset(cid_data); + + // Override scoring mode if SPIC requested + if (scoringMethod == 1) { + ds.scoring_mode = ts::ScoringMode::SPIC; + ds.spic_data = &spic_data; + } + + // --- Populate DrivenParams --- + ts::DrivenParams params; + params.max_replicates = maxReplicates; + params.target_hits = targetHits; + params.tbr_max_hits = tbrMaxHits; + params.ratchet_cycles = ratchetCycles; + params.ratchet_perturb_prob = ratchetPerturbProb; + params.ratchet_perturb_mode = ratchetPerturbMode; + params.ratchet_adaptive = ratchetAdaptive; + params.drift_cycles = driftCycles; + params.drift_afd_limit = driftAfdLimit; + params.drift_rfd_limit = driftRfdLimit; + params.xss_rounds = xssRounds; + params.xss_partitions = xssPartitions; + params.rss_rounds = rssRounds; + params.css_rounds = cssRounds; + params.css_partitions = cssPartitions; + params.sector_min_size = sectorMinSize; + params.sector_max_size = sectorMaxSize; + params.fuse_interval = fuseInterval; + params.fuse_accept_equal = fuseAcceptEqual; + params.pool_max_size = poolMaxSize; + params.pool_suboptimal = poolSuboptimal; + params.max_seconds = maxSeconds; + params.verbosity = verbosity; + params.tabu_size = tabuSize; + params.wagner_starts = wagnerStarts; + params.score_tol = scoreTol; + params.plateau_reps = plateauReps; + + // Starting tree edge matrix (optional) + if (startEdge.isNotNull()) { + IntegerMatrix se(startEdge.get()); + int n_edge = se.nrow(); + params.start_n_edge = n_edge; + params.start_edge.resize(2 * n_edge); + for (int i = 0; i < n_edge; ++i) { + params.start_edge[i] = se(i, 0); + params.start_edge[n_edge + i] = se(i, 1); + } + } + + // Progress callback + if (progressCallback.isNotNull()) { + Rcpp::Function r_cb(progressCallback.get()); + params.progress_callback = [r_cb](const ts::ProgressInfo& pi) { + r_cb(Rcpp::List::create( + Rcpp::Named("replicate") = pi.replicate, + Rcpp::Named("max_replicates") = pi.max_replicates, + Rcpp::Named("best_score") = pi.best_score, + Rcpp::Named("hits_to_best") = pi.hits_to_best, + Rcpp::Named("target_hits") = pi.target_hits, + Rcpp::Named("pool_size") = pi.pool_size, + Rcpp::Named("phase") = std::string(pi.phase), + Rcpp::Named("elapsed") = pi.elapsed_seconds, + Rcpp::Named("phase_score") = pi.phase_score + )); + }; + } + + // --- Run driven search --- + ts::TreePool pool(params.pool_max_size, params.pool_suboptimal); + ts::DrivenResult result; + if (nThreads > 1) { + result = ts::parallel_driven_search(pool, ds, params, nullptr, nThreads); + } else { + result = ts::driven_search(pool, ds, params, nullptr); + } + + // --- Return results --- + if (result.pool_size == 0) { + return List::create( + Named("trees") = List::create(), + Named("scores") = NumericVector::create(), + Named("best_score") = result.best_score, + Named("replicates") = result.replicates_completed, + Named("hits_to_best") = result.hits_to_best, + Named("pool_size") = 0, + Named("timed_out") = result.timed_out + ); + } + + const auto& entries = pool.all(); + List tree_list(entries.size()); + NumericVector score_vec(entries.size()); + for (size_t i = 0; i < entries.size(); ++i) { + tree_list[i] = tree_to_edge(entries[i].tree); + score_vec[i] = entries[i].score; + } + + return List::create( + Named("trees") = tree_list, + Named("scores") = score_vec, + Named("best_score") = result.best_score, + Named("replicates") = result.replicates_completed, + Named("hits_to_best") = result.hits_to_best, + Named("pool_size") = result.pool_size, + Named("timed_out") = result.timed_out + ); +} +// --------------------------------------------------------------------------- +// ts_cid_score_trees: batch CID scoring of candidate trees. +// +// Given a set of input trees (same format as ts_cid_consensus) and a list +// of candidate tree edge matrices, scores each candidate and returns a +// NumericVector of negated mean MCI values (lower = better consensus), +// consistent with the C++ cid_score() convention. +// +// CidData is built once and reused across all candidates — amortising the +// prepare_cid_data() hash-index and log2 precomputation across the batch. +// This is the primary entry point for R-side scoring in phases 2 and 3 of +// InfoConsensus() (collapse/resolve refinement, rogue prescreening, and +// tip insertion). +// --------------------------------------------------------------------------- + +// Topology-only TreeState from a 1-based R edge matrix (two int vectors). +// Sets up parent/left/right/postorder; leaves Fitch state arrays empty. +// Sufficient for cid_score()/spic_score(), which only access topology fields. +// +// Handles polytomous trees (e.g. ape's trifurcating-root unrooted +// representation) by resolving multifurcations into arbitrary binary +// splits. The resolved topology doesn't change the split set (the +// inserted zero-length edges create trivial 1|n-1 splits that +// compute_splits_cid() filters out). +static ts::TreeState cid_tree_from_edge(const int* ep, const int* ec, + int n_edge, int n_tip) +{ + // --- Phase 1: build adjacency list (children per node) --- + int max_node_1idx = 0; + for (int i = 0; i < n_edge; ++i) { + if (ep[i] > max_node_1idx) max_node_1idx = ep[i]; + if (ec[i] > max_node_1idx) max_node_1idx = ec[i]; + } + int max_node = max_node_1idx; // 1-indexed max + // children[node_0indexed] = list of child node indices (0-indexed) + std::vector> children(max_node, std::vector()); + std::vector par_raw(max_node, -1); + + for (int i = 0; i < n_edge; ++i) { + int p = ep[i] - 1; + int c = ec[i] - 1; + children[p].push_back(c); + par_raw[c] = p; + } + + // Find root (internal node with no parent) + int root = -1; + for (int i = n_tip; i < max_node; ++i) { + if (par_raw[i] == -1) { root = i; break; } + } + if (root < 0) root = n_tip; // fallback + + // --- Phase 2: resolve polytomies --- + // Insert virtual nodes for any node with >2 children. + // next_id tracks the next available node index. + int next_id = max_node; + // Resolve in a queue to handle cascading insertions. + std::vector queue; + for (int i = n_tip; i < max_node; ++i) { + if (static_cast(children[i].size()) > 2) queue.push_back(i); + } + for (size_t qi = 0; qi < queue.size(); ++qi) { + int node = queue[qi]; + while (static_cast(children[node].size()) > 2) { + // Peel off the last two children into a new virtual node + int c_last = children[node].back(); children[node].pop_back(); + int c_prev = children[node].back(); children[node].pop_back(); + int virt = next_id++; + // Extend storage + if (virt >= static_cast(children.size())) { + children.resize(virt + 1); + par_raw.resize(virt + 1, -1); + } + children[virt] = {c_prev, c_last}; + par_raw[c_prev] = virt; + par_raw[c_last] = virt; + par_raw[virt] = node; + children[node].push_back(virt); + } + } + + // --- Phase 3: build TreeState --- + int n_internal = next_id - n_tip; + int n_node = next_id; + + ts::TreeState tree; + tree.n_tip = n_tip; + tree.n_internal = n_internal; + tree.n_node = n_node; + tree.total_words = 0; + tree.n_blocks = 0; + + tree.parent.assign(n_node, -1); + tree.left.assign(n_internal, -1); + tree.right.assign(n_internal, -1); + + for (int i = n_tip; i < n_node; ++i) { + int pi = i - n_tip; + if (static_cast(children[i].size()) >= 1) tree.left[pi] = children[i][0]; + if (static_cast(children[i].size()) >= 2) tree.right[pi] = children[i][1]; + } + for (int c = 0; c < n_node; ++c) { + if (c == root) { + tree.parent[c] = c; + } else { + tree.parent[c] = par_raw[c]; + } + } + tree.build_postorder(); + return tree; +} + +// Build CidData from a list of R raw split matrices. +// Extracted as a helper shared by ts_cid_score_trees and ts_cid_consensus. +static ts::CidData cid_data_from_splits(const Rcpp::List& splitMatrices, + int n_tip) +{ + int n_trees = splitMatrices.size(); + int n_bins = (n_tip + 63) / 64; + int unset = (n_tip % 64) ? 64 - (n_tip % 64) : 0; + uint64_t last_mask = unset ? (~uint64_t(0)) >> unset : ~uint64_t(0); + + ts::CidData cd; + cd.n_trees = n_trees; + cd.n_tips = n_tip; + cd.n_bins = n_bins; + cd.normalize = false; + cd.mrp_concavity = HUGE_VAL; + cd.screening_tolerance = 0.0; + cd.tree_splits.resize(n_trees); + cd.tree_ce.resize(n_trees); + cd.tree_weights.assign(n_trees, 1.0); + cd.weight_sum = static_cast(n_trees); + + for (int t = 0; t < n_trees; ++t) { + RawMatrix rm = Rcpp::as(splitMatrices[t]); + int n_splits = rm.nrow(); + int n_r_cols = rm.ncol(); + ts::CidSplitSet& ss = cd.tree_splits[t]; + ss.n_splits = n_splits; + ss.n_bins = n_bins; + ss.data.assign(static_cast(n_splits) * n_bins, 0); + ss.in_split.resize(n_splits, 0); + + for (int s = 0; s < n_splits; ++s) { + uint64_t* sp = &ss.data[static_cast(s) * n_bins]; + for (int col = 0; col < n_r_cols; ++col) { + int word = col / 8; + int byte_pos = col % 8; + if (word < n_bins) { + sp[word] |= static_cast( + static_cast(rm(s, col))) << (byte_pos * 8); + } + } + // Canonical form: ensure tip 0 is in partition 0 + if (sp[0] & 1) { + for (int w = 0; w < n_bins - 1; ++w) sp[w] = ~sp[w]; + if (n_bins > 0) sp[n_bins - 1] ^= last_mask; + } + int cnt = 0; + for (int w = 0; w < n_bins; ++w) cnt += ts::popcount64(sp[w]); + ss.in_split[s] = cnt; + } + cd.tree_ce[t] = ts::clustering_entropy(ss, n_tip); + } + cd.mean_tree_ce = 0.0; + for (int t = 0; t < n_trees; ++t) cd.mean_tree_ce += cd.tree_ce[t]; + if (n_trees > 0) cd.mean_tree_ce /= n_trees; + + ts::prepare_cid_data(cd); + return cd; +} + +// [[Rcpp::export]] +NumericVector ts_cid_score_trees( + List splitMatrices, + int nTip, + List candidateEdges) +{ + if (splitMatrices.size() == 0) + Rcpp::stop("ts_cid_score_trees: no input trees provided."); + + ts::CidData cd = cid_data_from_splits(splitMatrices, nTip); + + int n_cand = candidateEdges.size(); + NumericVector result(n_cand, R_PosInf); + + for (int i = 0; i < n_cand; ++i) { + IntegerMatrix edge = Rcpp::as(candidateEdges[i]); + int n_edge = edge.nrow(); + // Copy columns into contiguous vectors for cid_tree_from_edge + std::vector ep(n_edge), ec(n_edge); + for (int j = 0; j < n_edge; ++j) { + ep[j] = edge(j, 0); + ec[j] = edge(j, 1); + } + ts::TreeState tree = cid_tree_from_edge(ep.data(), ec.data(), n_edge, nTip); + result[i] = ts::cid_score(tree, cd); + } + return result; +} + +// --------------------------------------------------------------------------- +// ts_cid_prescreen_rogue: batch CID prescreen for rogue taxon detection. +// +// For each tip in droppableTips, computes the CID score of the candidate +// tree (with that tip masked out) against the input trees (with that tip +// masked out). All masking is done via bit operations on pre-built split +// data, avoiding R-level DropTip/as.Splits overhead. +// +// Returns a NumericVector of negated mean MCI values (lower = better). +// --------------------------------------------------------------------------- + +// Mask a split set by clearing one tip's bit and removing resulting trivial +// splits. Writes into `dst` (which is cleared first). Does NOT build +// hash_index or lg2 vectors -- the O(n^2) fallback in mutual_clustering_info +// handles complement matching. `n_tip` is the original (pre-mask) tip count. +static void mask_splits(const ts::CidSplitSet& src, int drop_word, + uint64_t drop_mask, int drop_bit_in_word, + int n_tip, ts::CidSplitSet& dst) { + int wps = src.n_bins; + dst.n_bins = wps; + dst.data.clear(); + dst.in_split.clear(); + dst.lg2_in.clear(); + dst.lg2_out.clear(); + dst.hash_index.clear(); + + int reduced = n_tip - 1; + for (int s = 0; s < src.n_splits; ++s) { + const uint64_t* sp = src.split(s); + int count = src.in_split[s]; + + bool tip_in = (sp[drop_word] >> drop_bit_in_word) & 1; + int new_count = tip_in ? count - 1 : count; + int complement = reduced - new_count; + + if (new_count <= 1 || complement <= 1) continue; + + size_t off = dst.data.size(); + dst.data.resize(off + wps); + uint64_t* dp = &dst.data[off]; + std::memcpy(dp, sp, sizeof(uint64_t) * wps); + dp[drop_word] &= drop_mask; + dst.in_split.push_back(new_count); + } + dst.n_splits = static_cast(dst.in_split.size()); +} + +// [[Rcpp::export]] +NumericVector ts_cid_prescreen_rogue( + List splitMatrices, + int nTip, + IntegerMatrix candidateEdge, + IntegerVector droppableTips) +{ + if (splitMatrices.size() == 0) + Rcpp::stop("ts_cid_prescreen_rogue: no input trees provided."); + if (droppableTips.size() == 0) + return NumericVector(0); + + // Build CidData from full input trees (once) + ts::CidData cd = cid_data_from_splits(splitMatrices, nTip); + + // Build candidate tree and compute its splits + int n_edge = candidateEdge.nrow(); + std::vector ep(n_edge), ec(n_edge); + for (int j = 0; j < n_edge; ++j) { + ep[j] = candidateEdge(j, 0); + ec[j] = candidateEdge(j, 1); + } + ts::TreeState cand_tree = cid_tree_from_edge( + ep.data(), ec.data(), n_edge, nTip); + ts::CidSplitSet full_cand; + std::vector tip_bits_work; + ts::compute_splits_cid(cand_tree, tip_bits_work, full_cand); + + int n_drop = droppableTips.size(); + int n_trees = cd.n_trees; + int reduced = nTip - 1; + NumericVector result(n_drop); + + ts::LapScratch lap_scratch; + ts::CidSplitSet masked_cand; + ts::CidSplitSet masked_input; + + for (int d = 0; d < n_drop; ++d) { + int drop_tip_0 = droppableTips[d] - 1; // R 1-indexed -> C++ 0-indexed + int drop_word = drop_tip_0 / 64; + int drop_bit_in_word = drop_tip_0 % 64; + uint64_t drop_mask = ~(1ULL << drop_bit_in_word); + + mask_splits(full_cand, drop_word, drop_mask, drop_bit_in_word, + nTip, masked_cand); + + double mci_sum = 0.0; + for (int t = 0; t < n_trees; ++t) { + mask_splits(cd.tree_splits[t], drop_word, drop_mask, drop_bit_in_word, + nTip, masked_input); + mci_sum += ts::mutual_clustering_info( + masked_cand, masked_input, reduced, lap_scratch); + } + result[d] = -mci_sum / n_trees; + } + return result; +} + + +// --------------------------------------------------------------------------- +// ts_spic_score_trees: batch SPIC scoring of candidate trees. +// +// Analogous to ts_cid_score_trees but uses SPIC (Splitwise Phylogenetic +// Information Content) instead of MCI. Builds SpicData once and reuses +// across all candidates. Returns negated SPIC sums (lower = better). +// --------------------------------------------------------------------------- + +// [[Rcpp::export]] +NumericVector ts_spic_score_trees( + List splitMatrices, + int nTip, + List candidateEdges) +{ + if (splitMatrices.size() == 0) + Rcpp::stop("ts_spic_score_trees: no input trees provided."); + + // Build CidData first (to get the split sets), then SpicData + ts::CidData cd = cid_data_from_splits(splitMatrices, nTip); + ts::SpicData sd = ts::build_spic_data(cd); + + int n_cand = candidateEdges.size(); + NumericVector result(n_cand, R_PosInf); + + for (int i = 0; i < n_cand; ++i) { + IntegerMatrix edge = Rcpp::as(candidateEdges[i]); + int n_edge = edge.nrow(); + std::vector ep(n_edge), ec(n_edge); + for (int j = 0; j < n_edge; ++j) { + ep[j] = edge(j, 0); + ec[j] = edge(j, 1); + } + ts::TreeState tree = cid_tree_from_edge(ep.data(), ec.data(), n_edge, nTip); + result[i] = ts::spic_score(tree, sd); + } + return result; +} + + +// --------------------------------------------------------------------------- +// ts_spic_prescreen_rogue: batch SPIC prescreen for rogue taxon detection. +// +// For each tip in droppableTips, masks out the tip from the candidate tree +// and input tree split data, then computes the SPIC score of the reduced +// candidate against the reduced inputs. All masking via bit operations. +// --------------------------------------------------------------------------- + +// Mask a split set for SPIC rogue prescreen: clear one tip's bit. +// Removes trivial splits and builds result in dst. +// Reuse the same mask_splits() already defined for CID prescreen. + +// [[Rcpp::export]] +NumericVector ts_spic_prescreen_rogue( + List splitMatrices, + int nTip, + IntegerMatrix candidateEdge, + IntegerVector droppableTips) +{ + if (splitMatrices.size() == 0) + Rcpp::stop("ts_spic_prescreen_rogue: no input trees provided."); + if (droppableTips.size() == 0) + return NumericVector(0); + + // Build CidData to get split sets, then SpicData + ts::CidData cd = cid_data_from_splits(splitMatrices, nTip); + + // Build candidate tree and compute its splits + int n_edge = candidateEdge.nrow(); + std::vector ep(n_edge), ec(n_edge); + for (int j = 0; j < n_edge; ++j) { + ep[j] = candidateEdge(j, 0); + ec[j] = candidateEdge(j, 1); + } + ts::TreeState cand_tree = cid_tree_from_edge( + ep.data(), ec.data(), n_edge, nTip); + ts::CidSplitSet full_cand; + std::vector tip_bits_work; + ts::compute_splits_cid(cand_tree, tip_bits_work, full_cand); + + int n_drop = droppableTips.size(); + int n_trees = cd.n_trees; + int reduced = nTip - 1; + NumericVector result(n_drop); + + ts::CidSplitSet masked_cand; + ts::CidSplitSet masked_input; + + for (int d = 0; d < n_drop; ++d) { + int drop_tip_0 = droppableTips[d] - 1; + int drop_word = drop_tip_0 / 64; + int drop_bit_in_word = drop_tip_0 % 64; + uint64_t drop_mask = ~(1ULL << drop_bit_in_word); + + // Mask candidate splits + mask_splits(full_cand, drop_word, drop_mask, drop_bit_in_word, + nTip, masked_cand); + + // Build reduced SpicData from masked input splits. + // IC tables use 'reduced' for correct combinatorics, but n_bins + // must match the original bit-width (masked data retains original + // word count even when nTip crosses a 64-boundary). + std::vector masked_inputs(n_trees); + for (int t = 0; t < n_trees; ++t) { + mask_splits(cd.tree_splits[t], drop_word, drop_mask, drop_bit_in_word, + nTip, masked_inputs[t]); + } + ts::SpicData sd = ts::build_spic_data_from_splits( + masked_inputs, reduced, n_trees, cd.n_bins); + int orig_n_bins = cd.n_bins; + + // Score the masked candidate against the masked inputs + double total_ic = 0.0; + for (int s = 0; s < masked_cand.n_splits; ++s) { + const uint64_t* sp = masked_cand.split(s); + int a = masked_cand.in_split[s]; + int b = reduced - a; + if (a < 2 || b < 2) continue; + + uint64_t h = ts::hash_split_key(sp, orig_n_bins); + int count = 0; + auto range = sd.freq_table.equal_range(h); + for (auto it = range.first; it != range.second; ++it) { + if (it->second.in_split == a && + std::memcmp(sp, it->second.data.data(), + sizeof(uint64_t) * orig_n_bins) == 0) { + count = it->second.count; + break; + } + } + double freq = static_cast(count) / n_trees; + total_ic += ts::split_ic(a, reduced, freq, sd); + } + result[d] = -total_ic; + } + return result; +} + diff --git a/src/ts_search.cpp b/src/ts_search.cpp index 8fa3a2e9a..3cf8b654a 100644 --- a/src/ts_search.cpp +++ b/src/ts_search.cpp @@ -1,4 +1,5 @@ #include "ts_search.h" +#include "ts_cid.h" #include "ts_fitch.h" #include "ts_collapsed.h" #include "ts_rng.h" @@ -19,7 +20,36 @@ namespace ts { static double full_rescore(TreeState& tree, const DataSet& ds) { tree.reset_states(ds); - return score_tree(tree, ds); + double s = score_tree(tree, ds); + if (is_cid_like(ds.scoring_mode)) { + fitch_score(tree, ds); + } + return s; +} + +static double spr_mrp_score(const TreeState& tree, const DataSet& ds, + std::vector& char_steps) { + std::fill(char_steps.begin(), char_steps.end(), 0); + for (int node : tree.postorder) { + for (int b = 0; b < ds.n_blocks; ++b) { + const CharBlock& blk = ds.blocks[b]; + uint64_t mask = + tree.local_cost[static_cast(node) * tree.n_blocks + b]; + while (mask) { + int c = ts::ctz64(mask); + char_steps[blk.pattern_index[c]] += 1; + mask &= mask - 1; + } + } + } + if (std::isfinite(ds.concavity)) { + return compute_weighted_score(ds, char_steps); + } + int total = 0; + for (int p = 0; p < ds.n_patterns; ++p) { + total += char_steps[p] * ds.pattern_freq[p]; + } + return static_cast(total) + ds.ew_offset; } // Compute the number of tips in the subtree below each node. @@ -176,6 +206,7 @@ SearchResult spr_search(TreeState& tree, const DataSet& ds, int maxHits, int hits = 1; const bool use_iw = std::isfinite(ds.concavity); + const bool is_cid = is_cid_like(ds.scoring_mode); const double eps = use_iw ? 1e-10 : 0.0; // Detect inapplicable characters @@ -208,6 +239,14 @@ SearchResult spr_search(TreeState& tree, const DataSet& ds, int maxHits, iw_del.resize(ds.n_patterns, 0.0); } + // CID mode: track MRP screening score separately + std::vector mrp_steps_buf; + double mrp_baseline = best_score; + if (is_cid) { + mrp_steps_buf.resize(ds.n_patterns, 0); + mrp_baseline = spr_mrp_score(tree, ds, mrp_steps_buf); + } + // Subtree sizes for smaller-subtree filtering std::vector subtree_sizes; @@ -275,7 +314,7 @@ SearchResult spr_search(TreeState& tree, const DataSet& ds, int maxHits, if (ds.blocks[b].upweight_mask) nu += popcount64(lc & ds.blocks[b].upweight_mask); nx_cost += ds.blocks[b].weight * nu; } - divided_length = best_score + delta - nx_cost; + divided_length = mrp_baseline + delta - nx_cost; } const uint64_t* clip_prelim = @@ -348,25 +387,49 @@ SearchResult spr_search(TreeState& tree, const DataSet& ds, int maxHits, } // --- Verify best candidate with full rescore --- - bool dominated = (best_candidate > best_score + eps) || - (best_candidate > best_score - eps - && hits > maxHits); + bool dominated; + if (is_cid) { + double threshold = mrp_baseline; + if (ds.cid_data && ds.cid_data->screening_tolerance > 0.0) { + threshold *= (1.0 + ds.cid_data->screening_tolerance); + } + dominated = (best_candidate > threshold + eps); + } else { + dominated = (best_candidate > best_score + eps) || + (best_candidate > best_score - eps + && hits > maxHits); + } bool accepted = false; if (!dominated && best_above >= 0) { tree.spr_regraft(best_above, best_below); tree.build_postorder(); + // CID early termination + if (is_cid && ds.cid_data) { + ds.cid_data->score_budget = best_score + eps; + } double actual = full_rescore(tree, ds); + if (is_cid && ds.cid_data) { + ds.cid_data->score_budget = HUGE_VAL; + } if (actual < best_score - eps) { best_score = actual; + if (is_cid) { + mrp_baseline = spr_mrp_score(tree, ds, mrp_steps_buf); + } else { + mrp_baseline = actual; + } ++n_moves; hits = 1; accepted = true; keep_going = true; } else if (std::fabs(actual - best_score) <= eps && hits <= maxHits) { + if (is_cid) { + mrp_baseline = spr_mrp_score(tree, ds, mrp_steps_buf); + } ++hits; ++n_moves; accepted = true; diff --git a/src/ts_sector.cpp b/src/ts_sector.cpp index 1fea4120e..4bcf06a99 100644 --- a/src/ts_sector.cpp +++ b/src/ts_sector.cpp @@ -266,6 +266,16 @@ static void collect_clade_nodes(const TreeState& tree, int node, } } +// In CID mode, score_tree() calls cid_score() which doesn't run Fitch, +// so prelim/final_ state arrays may be stale. build_reduced_dataset() +// needs valid final_ to construct the HTU pseudo-tip. This helper runs +// a full Fitch scoring on the MRP characters when needed. +static void prepare_cid_states(TreeState& tree, const DataSet& ds) { + if (is_cid_like(ds.scoring_mode)) { + fitch_score(tree, ds); + } +} + // ---- Reduced dataset construction ---- ReducedDataset build_reduced_dataset(const TreeState& tree, @@ -433,8 +443,15 @@ ReducedDataset build_reduced_dataset(const TreeState& tree, rd.data.eff_k = ds.eff_k; rd.data.phi = ds.phi; - // Copy scoring mode and simplification metadata + // Copy scoring mode and simplification metadata. + // CID mode: sector-internal search uses Fitch on MRP characters; + // full CID is verified on the complete tree after reinsertion. rd.data.scoring_mode = ds.scoring_mode; + if (is_cid_like(rd.data.scoring_mode)) { + rd.data.scoring_mode = ScoringMode::EW; + rd.data.cid_data = nullptr; + rd.data.spic_data = nullptr; + } rd.data.ew_offset = ds.ew_offset; rd.data.precomputed_steps = ds.precomputed_steps; rd.data.info_amounts = ds.info_amounts; @@ -638,7 +655,9 @@ SectorResult rss_search(TreeState& tree, DataSet& ds, // Seed RNG (from R in serial mode, from thread-local in parallel mode) std::mt19937 rng = ts::make_rng(); - // Ensure full tree has current state sets + // Ensure full tree has current state sets. + // For CID mode, also run Fitch to populate final_ for HTU construction. + prepare_cid_states(tree, ds); double current_score = score_tree(tree, ds); SectorResult result; @@ -747,6 +766,7 @@ SectorResult rss_search(TreeState& tree, DataSet& ds, restore_clade(tree, snap); tree.build_postorder(); score_tree(tree, ds); + prepare_cid_states(tree, ds); continue; } @@ -771,6 +791,8 @@ SectorResult rss_search(TreeState& tree, DataSet& ds, eligible.push_back(node); } } + // Refresh Fitch states for next sector extraction + prepare_cid_states(tree, ds); if (eligible.empty()) break; // Recompute conflict weights for new topology @@ -784,11 +806,13 @@ SectorResult rss_search(TreeState& tree, DataSet& ds, } } else if (new_score == result.best_score && params.accept_equal) { // Equal score accepted — topology changed but score didn't + prepare_cid_states(tree, ds); } else { // HTU approximation caused full-tree score to worsen; revert restore_clade(tree, snap); tree.build_postorder(); score_tree(tree, ds); + prepare_cid_states(tree, ds); } } @@ -818,6 +842,8 @@ SectorResult xss_search(TreeState& tree, DataSet& ds, // Seed RNG (from R in serial mode, from thread-local in parallel mode) std::mt19937 rng = ts::make_rng(); + // For CID mode, run Fitch to populate final_ for HTU construction. + prepare_cid_states(tree, ds); double current_score = score_tree(tree, ds); SectorResult result; @@ -848,10 +874,6 @@ SectorResult xss_search(TreeState& tree, DataSet& ds, int sz = count_clade_tips(tree, sector_root); if (sz < 4) continue; // too small to be useful - // State arrays are guaranteed valid: either from the initial - // score_tree above, or from the previous sector's acceptance/ - // rejection (both paths call score_tree before continuing). - ReducedDataset rd = build_reduced_dataset(tree, ds, sector_root); double sector_current = score_tree(rd.subtree, rd.data); @@ -877,6 +899,7 @@ SectorResult xss_search(TreeState& tree, DataSet& ds, restore_clade(tree, snap); tree.build_postorder(); score_tree(tree, ds); + prepare_cid_states(tree, ds); continue; } @@ -885,13 +908,16 @@ SectorResult xss_search(TreeState& tree, DataSet& ds, static_cast(result.best_score - new_score); result.best_score = new_score; ++result.n_sectors_improved; + prepare_cid_states(tree, ds); } else if (new_score == result.best_score && params.accept_equal) { // Equal score accepted + prepare_cid_states(tree, ds); } else { // HTU approximation caused full-tree score to worsen; revert restore_clade(tree, snap); tree.build_postorder(); score_tree(tree, ds); + prepare_cid_states(tree, ds); } } diff --git a/src/ts_spic.cpp b/src/ts_spic.cpp new file mode 100644 index 000000000..4d8254a3c --- /dev/null +++ b/src/ts_spic.cpp @@ -0,0 +1,212 @@ +// SPIC (Splitwise Phylogenetic Information Content) scoring. +// +// See ts_spic.h for overview and API. + +#include "ts_spic.h" +#include // memcmp + +namespace ts { + +// ========================================================================== +// Precomputed log2 tables +// ========================================================================== + +// Log2Rooted(k) = log2((2k-3)!!) = sum(log2(2i-1), i=1..k-1) for k >= 2. +// Log2Rooted(0) = Log2Rooted(1) = 0. +static std::vector build_log2_rooted(int n) { + std::vector tbl(n + 1, 0.0); + for (int k = 2; k <= n; ++k) { + tbl[k] = tbl[k - 1] + std::log2(static_cast(2 * k - 3)); + } + return tbl; +} + +// Log2Unrooted(n) = log2((2n-5)!!) for n >= 3. +// = Log2Rooted(n) - log2(2n - 3). +static double compute_log2_unrooted(int n, const std::vector& log2_rooted) { + if (n < 3) return 0.0; + return log2_rooted[n] - std::log2(static_cast(2 * n - 3)); +} + + +// ========================================================================== +// build_spic_data +// ========================================================================== + +SpicData build_spic_data_from_splits(const std::vector& tree_splits, + int n_tips, int n_trees, + int n_bins_override) { + SpicData sd; + sd.n_tips = n_tips; + sd.n_bins = (n_bins_override > 0) ? n_bins_override : (n_tips + 63) / 64; + sd.n_trees = n_trees; + + // Build log2 tables + sd.log2_rooted = build_log2_rooted(n_tips); + sd.log2_unrooted_n = compute_log2_unrooted(n_tips, sd.log2_rooted); + + // Precompute P_consistent and P_inconsistent for each partition size a + sd.log2_p_consistent.resize(n_tips + 1, 0.0); + sd.log2_p_inconsistent.resize(n_tips + 1, 0.0); + for (int a = 1; a <= n_tips; ++a) { + int b = n_tips - a; + if (a < 2 || b < 2) { + // Trivial split (1|n-1 or 0|n): present in all trees + sd.log2_p_consistent[a] = 0.0; // log2(1) = 0 + sd.log2_p_inconsistent[a] = -std::numeric_limits::infinity(); + } else { + double l2_n_consistent = sd.log2_rooted[a] + sd.log2_rooted[b]; + sd.log2_p_consistent[a] = l2_n_consistent - sd.log2_unrooted_n; + double p_consistent = std::exp2(sd.log2_p_consistent[a]); + if (p_consistent >= 1.0) { + sd.log2_p_inconsistent[a] = -std::numeric_limits::infinity(); + } else { + sd.log2_p_inconsistent[a] = std::log2(1.0 - p_consistent); + } + } + } + + // Build split frequency table from all input tree splits + int n_bins = sd.n_bins; + for (int t = 0; t < n_trees; ++t) { + const CidSplitSet& ss = tree_splits[t]; + for (int s = 0; s < ss.n_splits; ++s) { + const uint64_t* sp = ss.split(s); + uint64_t h = hash_split_key(sp, n_bins); + + // Check for existing entry with same hash and same data + bool found = false; + auto range = sd.freq_table.equal_range(h); + for (auto it = range.first; it != range.second; ++it) { + if (it->second.in_split == ss.in_split[s] && + std::memcmp(sp, it->second.data.data(), + sizeof(uint64_t) * n_bins) == 0) { + it->second.count++; + found = true; + break; + } + } + if (!found) { + SpicData::SplitEntry entry; + entry.count = 1; + entry.in_split = ss.in_split[s]; + entry.data.assign(sp, sp + n_bins); + sd.freq_table.emplace(h, std::move(entry)); + } + } + } + + // Allocate candidate buffers + sd.cand_tip_bits.resize(static_cast(n_tips) * n_bins, 0); + sd.cand_buf.n_bins = n_bins; + + return sd; +} + + +SpicData build_spic_data(const CidData& cd) { + return build_spic_data_from_splits(cd.tree_splits, cd.n_tips, cd.n_trees); +} + + +// ========================================================================== +// split_ic: information content of one split +// ========================================================================== +// +// Per-split IC formula (from SplitwiseInfo with probability weighting): +// +// IC = log2(N_unrooted) + p*(log2(p) - log2(N_consistent)) +// + (1-p)*(log2(1-p) - log2(N_inconsistent)) +// +// where: +// p = split frequency in input trees +// N_consistent = TreesMatchingSplit(a, b) = Rooted(a) * Rooted(b) +// N_inconsistent = N_unrooted - N_consistent +// log2(N_consistent) = Log2Rooted(a) + Log2Rooted(b) +// log2(N_inconsistent) = log2(P_inconsistent) + log2(N_unrooted) +// +// Rewritten using precomputed tables: +// IC = l2n + p*(log2(p) - l2n - l2pC) + q*(log2(q) - l2n - l2pI) +// = l2n * (1 - p - q) + p*(log2(p) - l2pC) + q*(log2(q) - l2pI) +// But 1-p-q = 0, so: +// IC = p*(log2(p) - log2(N_consistent)) + q*(log2(q) - log2(N_inconsistent)) +// Wait, the formula uses l2n + p*(log2(p) - l2nConsistent): +// l2nConsistent = log2(N_consistent) = Log2Rooted(a) + Log2Rooted(b) +// l2nInconsistent = log2(N_inconsistent) = log2(P_inconsistent) + l2n +// IC = l2n + p*(log2(p) - l2nConsistent) + q*(log2(q) - l2nInconsistent) + +double split_ic(int a, int n, double freq, const SpicData& sd) { + int b = n - a; + // Canonical: ensure a <= b for partition size + if (a > b) { int tmp = a; a = b; b = tmp; } + + // Trivial splits (1|n-1 or smaller): always present, IC = 0 + if (a < 2) return 0.0; + + double p = freq; + double q = 1.0 - p; + + double l2n = sd.log2_unrooted_n; + double l2n_consistent = sd.log2_rooted[a] + sd.log2_rooted[b]; + double l2p_inconsistent = sd.log2_p_inconsistent[a]; + double l2n_inconsistent = l2p_inconsistent + l2n; + + double ic = l2n; + + // p * (log2(p) - log2(N_consistent)) + if (p > 0.0) { + ic += p * (std::log2(p) - l2n_consistent); + } + // q * (log2(q) - log2(N_inconsistent)) + if (q > 0.0 && std::isfinite(l2n_inconsistent)) { + ic += q * (std::log2(q) - l2n_inconsistent); + } + + return ic; +} + + +// ========================================================================== +// spic_score: score candidate tree using SPIC +// ========================================================================== + +double spic_score(TreeState& tree, const SpicData& sd) { + // Extract candidate tree splits + compute_splits_cid(tree, sd.cand_tip_bits, sd.cand_buf); + const CidSplitSet& cand = sd.cand_buf; + + double total_ic = 0.0; + int n_bins = sd.n_bins; + + for (int s = 0; s < cand.n_splits; ++s) { + const uint64_t* sp = cand.split(s); + int a = cand.in_split[s]; + int b = sd.n_tips - a; + + // Skip trivial splits + if (a < 2 || b < 2) continue; + + // Look up frequency in input tree set + uint64_t h = hash_split_key(sp, n_bins); + int count = 0; + + auto range = sd.freq_table.equal_range(h); + for (auto it = range.first; it != range.second; ++it) { + if (it->second.in_split == a && + std::memcmp(sp, it->second.data.data(), + sizeof(uint64_t) * n_bins) == 0) { + count = it->second.count; + break; + } + } + + double freq = static_cast(count) / sd.n_trees; + total_ic += split_ic(a, sd.n_tips, freq, sd); + } + + // Return negated (lower = better consensus), consistent with cid_score() + return -total_ic; +} + + +} // namespace ts diff --git a/src/ts_spic.h b/src/ts_spic.h new file mode 100644 index 000000000..2f69dd14e --- /dev/null +++ b/src/ts_spic.h @@ -0,0 +1,96 @@ +#ifndef TS_SPIC_H +#define TS_SPIC_H + +// SPIC (Splitwise Phylogenetic Information Content) scoring for consensus search. +// +// Scores a candidate tree by summing the phylogenetic information content of +// each split, weighted by its frequency in the input tree set (interpreted as +// the probability that the split is correct). +// +// Reference: Smith (2022) Systematic Biology syab099. +// +// Key advantage over MCI (Mutual Clustering Information): +// O(splits * n_bins) per evaluation vs O(splits^2) for MCI (no LAP solver). +// Split-additive: each split contributes independently to the total score. + +#include "ts_data.h" +#include "ts_tree.h" +#include "ts_cid.h" // reuse CidSplitSet, compute_splits_cid +#include +#include +#include +#include + +namespace ts { + +// -------------------------------------------------------------------------- +// SpicData: precomputed data for SPIC scoring +// -------------------------------------------------------------------------- +struct SpicData { + int n_tips; + int n_bins; // ceil(n_tips / 64) + int n_trees; // number of input trees + + // Split frequency table: maps FNV-1a hash of split data to + // (count, in_split) for O(1) lookup per candidate split. + // Collisions handled by storing a list of entries per hash bucket. + struct SplitEntry { + int count; // number of input trees containing this split + int in_split; // popcount (partition size a) + // For collision resolution, store the split data + std::vector data; // n_bins words + }; + std::unordered_multimap freq_table; + + // Precomputed log2 tables for the IC formula. + // log2_rooted[k] = Log2Rooted(k) = log2((2k-3)!!) for k >= 2; 0 for k <= 1. + // Indexed from 0..n_tips. + std::vector log2_rooted; + + // log2_unrooted_n = Log2Unrooted(n_tips) + double log2_unrooted_n; + + // Precomputed log2(P_consistent(a)) for each possible partition size a. + // = Log2Rooted(a) + Log2Rooted(n-a) - Log2Unrooted(n) + // Indexed from 0..n_tips. + std::vector log2_p_consistent; + + // Precomputed log2(1 - P_consistent(a)) for each possible partition size a. + // Indexed from 0..n_tips. May be -Inf for trivial splits where P = 1. + std::vector log2_p_inconsistent; + + // Persistent candidate buffers (reused across spic_score calls) + mutable std::vector cand_tip_bits; + mutable CidSplitSet cand_buf; +}; + +// -------------------------------------------------------------------------- +// Public API +// -------------------------------------------------------------------------- + +// Build SpicData from input tree split sets (already stored in CidData). +// Builds the frequency table and precomputes log2 tables. +SpicData build_spic_data(const CidData& cd); + +// Build SpicData directly from a list of CidSplitSets. +// When n_bins_override > 0, use that for the bit-width of split data +// instead of computing from n_tips. This is needed when the split data +// was produced by bit-masking (e.g. rogue prescreen) and retains the +// original wider representation. +SpicData build_spic_data_from_splits(const std::vector& tree_splits, + int n_tips, int n_trees, + int n_bins_override = 0); + +// Score a candidate tree using SPIC. +// Returns negated SPIC sum (lower = better consensus), consistent with +// the cid_score() sign convention. +double spic_score(TreeState& tree, const SpicData& sd); + +// Per-split IC contribution (for debugging / diagnostics). +// Returns the IC of a split with partition size `a` (b = n - a), +// support frequency `freq` (in [0, 1]), using precomputed tables. +double split_ic(int a, int n, double freq, const SpicData& sd); + +} // namespace ts + +#endif // TS_SPIC_H diff --git a/src/ts_tbr.cpp b/src/ts_tbr.cpp index fcf37edf7..3f0c146b8 100644 --- a/src/ts_tbr.cpp +++ b/src/ts_tbr.cpp @@ -1,4 +1,5 @@ #include "ts_tbr.h" +#include "ts_cid.h" #include "ts_fitch.h" #include "ts_collapsed.h" #include "ts_rng.h" @@ -18,6 +19,41 @@ namespace ts { +// --- Top-k candidate buffer for batch CID scoring --- +struct CidCandidate { + int above, below; + int reroot_parent, reroot_child; + double mrp_score; +}; + +// Insert candidate into bounded top-k buffer (sorted ascending by mrp_score). +// If buffer is full and candidate is worse than the worst (back), skip. +static void topk_insert(std::vector& buf, int k, + double score, int above, int below, + int rp, int rc) { + if (static_cast(buf.size()) < k) { + buf.push_back({above, below, rp, rc, score}); + // Keep sorted: insert in position + for (int i = static_cast(buf.size()) - 1; i > 0; --i) { + if (buf[i].mrp_score < buf[i - 1].mrp_score) { + std::swap(buf[i], buf[i - 1]); + } else { + break; + } + } + } else if (score < buf.back().mrp_score) { + buf.back() = {above, below, rp, rc, score}; + // Re-sort: bubble down from back + for (int i = static_cast(buf.size()) - 1; i > 0; --i) { + if (buf[i].mrp_score < buf[i - 1].mrp_score) { + std::swap(buf[i], buf[i - 1]); + } else { + break; + } + } + } +} + // --- Fast hash for virtual_prelim deduplication (Phase 3A) --- // Word-at-a-time multiply-xor hash (faster than byte-by-byte FNV-1a). @@ -34,7 +70,40 @@ static uint64_t fast_hash(const uint64_t* data, int n_words) { static double full_rescore(TreeState& tree, const DataSet& ds) { tree.reset_states(ds); - return score_tree(tree, ds); + double s = score_tree(tree, ds); + // CID mode: score_tree() returns CID (doesn't run Fitch), but + // subsequent incremental screening needs populated Fitch state arrays. + if (is_cid_like(ds.scoring_mode)) { + fitch_score(tree, ds); + } + return s; +} + +// Compute the MRP screening score from already-populated Fitch states. +// For IW: per-character weighted fit. For EW: total steps + offset. +static double mrp_screening_score(const TreeState& tree, const DataSet& ds, + std::vector& char_steps) { + std::fill(char_steps.begin(), char_steps.end(), 0); + for (int node : tree.postorder) { + for (int b = 0; b < ds.n_blocks; ++b) { + const CharBlock& blk = ds.blocks[b]; + uint64_t mask = + tree.local_cost[static_cast(node) * tree.n_blocks + b]; + while (mask) { + int c = ts::ctz64(mask); + char_steps[blk.pattern_index[c]] += 1; + mask &= mask - 1; + } + } + } + if (std::isfinite(ds.concavity)) { + return compute_weighted_score(ds, char_steps); + } + int total = 0; + for (int p = 0; p < ds.n_patterns; ++p) { + total += char_steps[p] * ds.pattern_freq[p]; + } + return static_cast(total) + ds.ew_offset; } // Collect (parent, child) edge pairs reachable from root of main tree. @@ -472,6 +541,7 @@ TBRResult tbr_search(TreeState& tree, const DataSet& ds, int n_zero_skipped = 0; int hits = 1; const bool use_iw = std::isfinite(ds.concavity); + const bool is_cid = is_cid_like(ds.scoring_mode); // Floating-point tolerance for score equality const double eps = use_iw ? 1e-10 : 0.0; @@ -521,6 +591,23 @@ TBRResult tbr_search(TreeState& tree, const DataSet& ds, iw_delta.resize(ds.n_patterns, 0.0); } + // CID mode: track MRP screening score separately from CID score. + // MRP score is used for divided_length and the dominated check; + // CID score (best_score) is used for acceptance decisions. + std::vector mrp_steps_buf; + double mrp_baseline = best_score; // For non-CID, same as best_score + if (is_cid) { + mrp_steps_buf.resize(ds.n_patterns, 0); + mrp_baseline = mrp_screening_score(tree, ds, mrp_steps_buf); + } + + // CID top-k: number of best MRP candidates to CID-score per clip + const int cid_top_k = (is_cid && ds.cid_data) + ? std::max(1, ds.cid_data->cid_top_k) : 1; + const bool use_topk = (cid_top_k > 1); + std::vector topk_buf; + if (use_topk) topk_buf.reserve(cid_top_k); + // Subtree sizes for smaller-subtree filtering std::vector subtree_sizes(tree.n_node, 0); @@ -647,7 +734,7 @@ TBRResult tbr_search(TreeState& tree, const DataSet& ds, if (ds.blocks[b].upweight_mask) nu += popcount64(lc & ds.blocks[b].upweight_mask); nx_cost += ds.blocks[b].weight * nu; } - divided_length = best_score + delta - nx_cost; + divided_length = mrp_baseline + delta - nx_cost; } // For weighted scoring (IW or profile): precompute base score and deltas @@ -683,6 +770,7 @@ TBRResult tbr_search(TreeState& tree, const DataSet& ds, double best_candidate = HUGE_VAL; int best_above = -1, best_below = -1; int best_reroot_parent = -1, best_reroot_child = -1; + if (use_topk) topk_buf.clear(); // SPR candidates — with early termination (optimization #1) size_t clip_base = static_cast(clip_node) * tree.total_words; @@ -731,6 +819,10 @@ TBRResult tbr_search(TreeState& tree, const DataSet& ds, candidate = divided_length + extra; } ++n_evaluated; + if (use_topk) { + topk_insert(topk_buf, cid_top_k, candidate, + above, below, -1, -1); + } if (candidate < best_candidate) { best_candidate = candidate; best_above = above; @@ -863,6 +955,10 @@ TBRResult tbr_search(TreeState& tree, const DataSet& ds, candidate = divided_length + extra; } ++n_evaluated; + if (use_topk) { + topk_insert(topk_buf, cid_top_k, candidate, + above, below, sp, sc); + } if (candidate < best_candidate) { best_candidate = candidate; best_above = above; @@ -881,97 +977,229 @@ TBRResult tbr_search(TreeState& tree, const DataSet& ds, // Restore saved postorder (topology identical to pre-clip state) tree.postorder.assign(saved_postorder.begin(), saved_postorder.end()); - bool dominated = (best_candidate > best_score + eps) || - (best_candidate > best_score - eps && !params.accept_equal); - + // --- Phase 2b: Batch CID scoring of top-k candidates --- + // When cid_top_k > 1, evaluate the best k MRP candidates via full + // CID scoring and accept the best CID result. This catches moves + // where MRP and CID rankings disagree. bool accepted = false; - if (!dominated && best_above >= 0) { - // Topology and state snapshot already saved at the top of the - // while loop (optimization #7). No per-candidate save needed. + if (use_topk && !topk_buf.empty()) { + double mrp_threshold = mrp_baseline; + if (ds.cid_data->screening_tolerance > 0.0) { + mrp_threshold *= (1.0 + ds.cid_data->screening_tolerance); + } - bool ok = apply_tbr_move(tree, clip_node, - best_reroot_parent, best_reroot_child, - best_above, best_below); + double best_cid = HUGE_VAL; + int best_cid_idx = -1; - if (!ok || !validate_topology(tree)) { - restore_topology(tree, snap); - state_snap.restore(tree); - continue; - } + for (int ki = 0; ki < static_cast(topk_buf.size()); ++ki) { + auto& cand = topk_buf[ki]; + // Dominated check (same threshold as single-candidate path) + if (cand.mrp_score > mrp_threshold + eps) continue; + + save_topology(tree, snap); + state_snap.save(tree); + states_valid = true; + + bool ok = apply_tbr_move(tree, clip_node, + cand.reroot_parent, cand.reroot_child, + cand.above, cand.below); + if (!ok || !validate_topology(tree)) { + restore_topology(tree, snap); + state_snap.restore(tree); + continue; + } - tree.build_postorder_prealloc(work_stack); - double actual = full_rescore(tree, ds); + tree.build_postorder_prealloc(work_stack); + // Tighten budget as we find better CID scores in the batch + ds.cid_data->score_budget = std::min(best_score + eps, best_cid); + double actual = full_rescore(tree, ds); + ds.cid_data->score_budget = HUGE_VAL; - // Post-hoc constraint validation: TBR rerooting can break - // splits that were classified as UNCONSTRAINED during the - // clip phase (the rerooting changes which constraint tips - // end up on which side of the attachment edge). Reject - // any move that introduces a constraint violation. - if (constrained) { - map_constraint_nodes(tree, *cd); + // Post-hoc constraint validation bool violation = false; - for (int _s = 0; _s < cd->n_splits; ++_s) { - if (cd->constraint_node[_s] < 0) { - violation = true; - break; + if (constrained) { + map_constraint_nodes(tree, *cd); + for (int _s = 0; _s < cd->n_splits; ++_s) { + if (cd->constraint_node[_s] < 0) { + violation = true; + break; + } } } - if (violation) { - restore_topology(tree, snap); - state_snap.restore(tree); + + if (!violation && actual < best_cid) { + best_cid = actual; + best_cid_idx = ki; + } + + // Restore for next candidate (or for final acceptance) + restore_topology(tree, snap); + state_snap.restore(tree); + if (constrained && violation) { map_constraint_nodes(tree, *cd); compute_dfs_timestamps(tree, *cd); - continue; } } - // Compute topology hash for tabu checking - uint64_t tree_hash = 0; - if (tabu.active()) { - tree_hash = hash_tree(tree); + // Accept the best CID candidate if it improves or equals + if (best_cid_idx >= 0) { + auto& winner = topk_buf[best_cid_idx]; + + if (best_cid < best_score - eps) { + // Strict improvement: apply permanently + save_topology(tree, snap); + state_snap.save(tree); + apply_tbr_move(tree, clip_node, winner.reroot_parent, + winner.reroot_child, winner.above, winner.below); + tree.build_postorder_prealloc(work_stack); + full_rescore(tree, ds); // repopulate Fitch states + + if (tabu.active()) tabu.insert(hash_tree(tree)); + best_score = best_cid; + mrp_baseline = mrp_screening_score(tree, ds, mrp_steps_buf); + ++n_accepted; + hits = 1; + accepted = true; + keep_going = true; + states_valid = true; + if (constrained) compute_dfs_timestamps(tree, *cd); + if (collect_pool) collect_pool->add(tree, best_cid); + + } else if (std::fabs(best_cid - best_score) <= eps + && params.accept_equal + && hits <= params.max_hits) { + // Equal-score: apply, check tabu + save_topology(tree, snap); + state_snap.save(tree); + apply_tbr_move(tree, clip_node, winner.reroot_parent, + winner.reroot_child, winner.above, winner.below); + tree.build_postorder_prealloc(work_stack); + full_rescore(tree, ds); + + uint64_t tree_hash = tabu.active() ? hash_tree(tree) : 0; + if (tabu.active() && tabu.contains(tree_hash)) { + restore_topology(tree, snap); + state_snap.restore(tree); + // fall through to !accepted path + } else { + if (tabu.active()) tabu.insert(tree_hash); + mrp_baseline = mrp_screening_score(tree, ds, mrp_steps_buf); + ++hits; + ++n_accepted; + accepted = true; + keep_going = true; + states_valid = true; + if (constrained) compute_dfs_timestamps(tree, *cd); + if (collect_pool) collect_pool->add(tree, best_cid); + } + } } - - if (actual < best_score - eps) { - // Always accept strict improvements (but record in tabu) - if (tabu.active()) tabu.insert(tree_hash); - best_score = actual; - ++n_accepted; - hits = 1; - accepted = true; - keep_going = true; - states_valid = true; - if (constrained) { - compute_dfs_timestamps(tree, *cd); + // (if !accepted, tree is already in its original state) + } else { + // --- Original single-candidate path (non-CID or cid_top_k == 1) --- + + // In CID mode, best_candidate is an MRP screening score on a + // different scale from best_score (CID). Compare against the MRP + // baseline instead, with optional tolerance. + bool dominated; + if (is_cid) { + double threshold = mrp_baseline; + if (ds.cid_data && ds.cid_data->screening_tolerance > 0.0) { + threshold *= (1.0 + ds.cid_data->screening_tolerance); } - if (collect_pool) collect_pool->add(tree, actual); - } else if (std::fabs(actual - best_score) <= eps - && params.accept_equal - && hits <= params.max_hits) { - // Equal-score move: reject if tabu - if (tabu.active() && tabu.contains(tree_hash)) { - // Topology already visited — restore and skip + dominated = (best_candidate > threshold + eps); + } else { + dominated = (best_candidate > best_score + eps) || + (best_candidate > best_score - eps && !params.accept_equal); + } + + if (!dominated && best_above >= 0) { + // Topology and state snapshot already saved at the top of the + // while loop (optimization #7). No per-candidate save needed. + + bool ok = apply_tbr_move(tree, clip_node, + best_reroot_parent, best_reroot_child, + best_above, best_below); + + if (!ok || !validate_topology(tree)) { restore_topology(tree, snap); state_snap.restore(tree); continue; } - if (tabu.active()) tabu.insert(tree_hash); - ++hits; - ++n_accepted; - accepted = true; - keep_going = true; - states_valid = true; + + tree.build_postorder_prealloc(work_stack); + if (is_cid && ds.cid_data) { + ds.cid_data->score_budget = best_score + eps; + } + double actual = full_rescore(tree, ds); + if (is_cid && ds.cid_data) { + ds.cid_data->score_budget = HUGE_VAL; + } + if (constrained) { - compute_dfs_timestamps(tree, *cd); + map_constraint_nodes(tree, *cd); + bool violation = false; + for (int _s = 0; _s < cd->n_splits; ++_s) { + if (cd->constraint_node[_s] < 0) { + violation = true; + break; + } + } + if (violation) { + restore_topology(tree, snap); + state_snap.restore(tree); + map_constraint_nodes(tree, *cd); + compute_dfs_timestamps(tree, *cd); + continue; + } } - if (collect_pool) collect_pool->add(tree, actual); - } - if (!accepted) { - // Optimization #3: restore topology + states without full_rescore - restore_topology(tree, snap); - state_snap.restore(tree); - // state_snap.restore() already restored postorder via memcpy + uint64_t tree_hash = 0; + if (tabu.active()) { + tree_hash = hash_tree(tree); + } + + if (actual < best_score - eps) { + if (tabu.active()) tabu.insert(tree_hash); + best_score = actual; + if (is_cid) { + mrp_baseline = mrp_screening_score(tree, ds, mrp_steps_buf); + } else { + mrp_baseline = actual; + } + ++n_accepted; + hits = 1; + accepted = true; + keep_going = true; + states_valid = true; + if (constrained) compute_dfs_timestamps(tree, *cd); + if (collect_pool) collect_pool->add(tree, actual); + } else if (std::fabs(actual - best_score) <= eps + && params.accept_equal + && hits <= params.max_hits) { + if (tabu.active() && tabu.contains(tree_hash)) { + restore_topology(tree, snap); + state_snap.restore(tree); + continue; + } + if (tabu.active()) tabu.insert(tree_hash); + if (is_cid) { + mrp_baseline = mrp_screening_score(tree, ds, mrp_steps_buf); + } + ++hits; + ++n_accepted; + accepted = true; + keep_going = true; + states_valid = true; + if (constrained) compute_dfs_timestamps(tree, *cd); + if (collect_pool) collect_pool->add(tree, actual); + } + + if (!accepted) { + restore_topology(tree, snap); + state_snap.restore(tree); + } } } diff --git a/tests/testthat/_problems/test-Morphy-50.R b/tests/testthat/_problems/test-Morphy-50.R index 565ea24cb..0cd005643 100644 --- a/tests/testthat/_problems/test-Morphy-50.R +++ b/tests/testthat/_problems/test-Morphy-50.R @@ -37,5 +37,5 @@ dataset <- MatrixToPhyDat(matrix(c(0, 0, 1, 1, 1, 1, 1, constraint <- MatrixToPhyDat(matrix(c(0, 0, 1, "?", 1, 1, 1, 1, 1, 1, 0, 0), ncol = 2, dimnames = list(letters[1:6], NULL))) -cons <- consensus(Morphy(dataset, constraint = constraint), +cons <- Consensus(Morphy(dataset, constraint = constraint), rooted = TRUE) diff --git a/tests/testthat/_problems/test-Morphy-53.R b/tests/testthat/_problems/test-Morphy-53.R index 9a977a663..8836af501 100644 --- a/tests/testthat/_problems/test-Morphy-53.R +++ b/tests/testthat/_problems/test-Morphy-53.R @@ -42,7 +42,7 @@ dataset <- MatrixToPhyDat(matrix(c(0, 0, 1, 1, 1, 1, 1, constraint <- MatrixToPhyDat(matrix(c(0, 0, 1, "?", 1, 1, 1, 1, 1, 1, 0, 0), ncol = 2, dimnames = list(letters[1:6], NULL))) -cons <- consensus(Morphy(dataset, constraint = constraint), +cons <- Consensus(Morphy(dataset, constraint = constraint), rooted = TRUE) expect_true(as.Splits(as.logical(c(0, 0, 1, 1, 1)), letters[c(1:3, 5:6)]) %in% as.Splits(DropTip(cons, c("d", "g")))) diff --git a/tests/testthat/_problems/test-rearrange.cpp-12.R b/tests/testthat/_problems/test-rearrange.cpp-12.R index 7db47b01f..0a96ac233 100644 --- a/tests/testthat/_problems/test-rearrange.cpp-12.R +++ b/tests/testthat/_problems/test-rearrange.cpp-12.R @@ -4,5 +4,5 @@ library("TreeTools") # test ------------------------------------------------------------------------- -tr <- Preorder(root(TreeTools::BalancedTree(7), 't1', resolve.root = TRUE)) +tr <- Preorder(RootTree(TreeTools::BalancedTree(7), "t1")) expect_equal(0, length(expect_warning(all_spr(tr$edge, -1)))) diff --git a/tests/testthat/_problems/test-rearrange.cpp-21.R b/tests/testthat/_problems/test-rearrange.cpp-21.R index a1879f43f..6cca178e2 100644 --- a/tests/testthat/_problems/test-rearrange.cpp-21.R +++ b/tests/testthat/_problems/test-rearrange.cpp-21.R @@ -4,5 +4,5 @@ library("TreeTools") # test ------------------------------------------------------------------------- -tr <- Preorder(root(TreeTools::BalancedTree(7), 't1', resolve.root = TRUE)) +tr <- Preorder(RootTree(TreeTools::BalancedTree(7), "t1")) expect_equal(8, length(x <- all_tbr(tr$edge, 12))) diff --git a/tests/testthat/_problems/test-rearrange.cpp-5.R b/tests/testthat/_problems/test-rearrange.cpp-5.R index 94fd50329..ff634e718 100644 --- a/tests/testthat/_problems/test-rearrange.cpp-5.R +++ b/tests/testthat/_problems/test-rearrange.cpp-5.R @@ -4,5 +4,5 @@ library("TreeTools") # test ------------------------------------------------------------------------- -tr <- Preorder(root(TreeTools::BalancedTree(7), 't1', resolve.root = TRUE)) +tr <- Preorder(RootTree(TreeTools::BalancedTree(7), "t1")) expect_equal(0, length(expect_warning(all_tbr(tr$edge, -1)))) diff --git a/tests/testthat/_problems/test-zzz-tree-rearrange-61.R b/tests/testthat/_problems/test-zzz-tree-rearrange-61.R index 1547a06cc..03149904e 100644 --- a/tests/testthat/_problems/test-zzz-tree-rearrange-61.R +++ b/tests/testthat/_problems/test-zzz-tree-rearrange-61.R @@ -12,6 +12,6 @@ tree11 <- read.tree(text = "((((a, b), (c, d)), e), ((f, (g, (h, i))), (j, k))); attr(tree5a, 'order') <- attr(tree5b, 'order') <- attr(tree8, 'order') <- attr(tree11, 'order') <- 'preorder' # test ------------------------------------------------------------------------- -testTree <- Preorder(root(BalancedTree(7), 1, resolve.root = TRUE)) +testTree <- Preorder(RootTree(BalancedTree(7), 1)) edge <- testTree[["edge"]] expect_equal(spr(edge, 66), cSPR(testTree, 66)$edge) diff --git a/tests/testthat/test-InfoConsensus.R b/tests/testthat/test-InfoConsensus.R new file mode 100644 index 000000000..d0f484d95 --- /dev/null +++ b/tests/testthat/test-InfoConsensus.R @@ -0,0 +1,498 @@ +# Tier 2: skipped on CRAN; see tests/testing-strategy.md +skip_on_cran() + +library("TreeTools") +library("TreeDist") + +# Helpers ------------------------------------------------------------------- + +.CIDScorer <- TreeSearch:::.CIDScorer +.MakeCIDData <- TreeSearch:::.MakeCIDData +.CIDBootstrap <- TreeSearch:::.CIDBootstrap +.EdgeListToPhylo <- TreeSearch:::.EdgeListToPhylo +.CollapseEdge <- TreeSearch:::.CollapseEdge +.ResolveNode <- TreeSearch:::.ResolveNode +.RenumberNodes <- TreeSearch:::.RenumberNodes +.CollapseSwap <- TreeSearch:::.CollapseSwap +.ResolveSwap <- TreeSearch:::.ResolveSwap +.CollapseRefine <- TreeSearch:::.CollapseRefine +.CollapseSpecificEdge <- TreeSearch:::.CollapseSpecificEdge +.ResolveSpecificPair <- TreeSearch:::.ResolveSpecificPair +.ScoreTree <- TreeSearch:::.ScoreTree +.TopologySearch <- TreeSearch:::.TopologySearch +.RogueRefine <- TreeSearch:::.RogueRefine +.PrescreenMarginalNID <- TreeSearch:::.PrescreenMarginalNID +.PruneTrees <- TreeSearch:::.PruneTrees +.BestInsertion <- TreeSearch:::.BestInsertion +.InsertTipAtEdge <- TreeSearch:::.InsertTipAtEdge + +# Small reproducible tree set +set.seed(4817) +smallTrees <- as.phylo(sample.int(100, 20), nTip = 12) + + +# .EdgeListToPhylo ---------------------------------------------------------- + +test_that(".EdgeListToPhylo returns valid phylo", { + tr <- as.phylo(1, 10) + edge <- tr$edge + result <- .EdgeListToPhylo(edge[, 1], edge[, 2], tr$tip.label) + expect_s3_class(result, "phylo") + expect_equal(NTip(result), 10L) + expect_equal(result$Nnode, tr$Nnode) +}) + + +# .MakeCIDData --------------------------------------------------------------- + +test_that(".MakeCIDData creates correct environment", { + cidData <- .MakeCIDData(smallTrees, smallTrees[[1]]$tip.label) + expect_true(is.environment(cidData)) + expect_equal(length(cidData$trees), 20L) + expect_equal(cidData$nTip, 12L) +}) + + +# .CIDScorer ---------------------------------------------------------------- + +test_that(".CIDScorer returns negated mean MCI", { + cidData <- .MakeCIDData(smallTrees, smallTrees[[1]]$tip.label) + tr <- smallTrees[[1]] + edge <- tr$edge + + score <- .CIDScorer(edge[, 1], edge[, 2], cidData) + expected <- -mean(MutualClusteringInfo(tr, smallTrees)) + + expect_equal(score, expected, tolerance = 1e-6) +}) + +test_that(".CIDScorer returns negated mean MCI (MutualClusteringInfo check)", { + cidData <- .MakeCIDData(smallTrees, smallTrees[[1]]$tip.label) + tr <- smallTrees[[1]] + edge <- tr$edge + + score <- .CIDScorer(edge[, 1], edge[, 2], cidData) + expected <- -mean(MutualClusteringInfo(tr, smallTrees)) + expect_equal(score, expected, tolerance = 1e-6) +}) + + +# .CIDBootstrap ------------------------------------------------------------- + +test_that(".CIDBootstrap returns valid edgeList", { + cidData <- .MakeCIDData(smallTrees, smallTrees[[1]]$tip.label) + tr <- smallTrees[[1]] + edge <- tr$edge + edgeList <- TreeTools::RenumberEdges(edge[, 1], edge[, 2]) + + set.seed(7321) + result <- .CIDBootstrap(edgeList, cidData, + EdgeSwapper = RootedNNISwap, + maxIter = 5, maxHits = 3, + verbosity = 0L) + + expect_length(result, 2L) + expect_true(is.integer(result[[1]])) + expect_true(is.integer(result[[2]])) + expect_equal(length(result[[1]]), length(result[[2]])) +}) + +test_that(".CIDBootstrap restores original trees", { + cidData <- .MakeCIDData(smallTrees, smallTrees[[1]]$tip.label) + origTrees <- cidData$trees + tr <- smallTrees[[1]] + edgeList <- TreeTools::RenumberEdges(tr$edge[, 1], tr$edge[, 2]) + + set.seed(2199) + .CIDBootstrap(edgeList, cidData, + EdgeSwapper = RootedNNISwap, + maxIter = 3, maxHits = 2, + verbosity = 0L) + + expect_identical(cidData$trees, origTrees) +}) + + +# InfoConsensus — core tests ------------------------------------------------ + +test_that("InfoConsensus rejects non-multiPhylo input", { + expect_error(InfoConsensus(as.phylo(1, 10)), + "multiPhylo") +}) + +test_that("InfoConsensus rejects single tree", { + expect_error(InfoConsensus(c(as.phylo(1, 10))), + "at least 2") +}) + +test_that("InfoConsensus runs and returns valid result", { + set.seed(5103) + result <- InfoConsensus(smallTrees, + maxReplicates = 3L, targetHits = 2L, + neverDrop = TRUE, collapse = FALSE, + verbosity = 0L) + + expect_s3_class(result, "phylo") + expect_equal(NTip(result), 12L) + resultScore <- attr(result, "score") + expect_true(is.numeric(resultScore)) + expect_true(resultScore >= 0) +}) + +test_that("InfoConsensus score attribute is set", { + set.seed(9241) + result <- InfoConsensus(smallTrees, + maxReplicates = 2L, targetHits = 1L, + neverDrop = TRUE, collapse = FALSE, + verbosity = 0L) + + expect_true(!is.null(attr(result, "score"))) + expect_true(is.numeric(attr(result, "score"))) + expect_true(attr(result, "score") >= 0) +}) + +test_that("InfoConsensus rogue-dropping does not crash", { + # This exercises the neverDrop = FALSE path (rogue taxon screening). + # Previously crashed with SIGSEGV due to uninitialised phi/eff_k in MRP DataSet. + set.seed(6317) + result <- InfoConsensus(smallTrees, + maxReplicates = 2L, targetHits = 1L, + neverDrop = FALSE, maxDrop = 2L, + collapse = FALSE, verbosity = 0L) + + expect_s3_class(result, "phylo") + expect_true(NTip(result) >= 10L) # at most 2 tips dropped + expect_true(NTip(result) <= 12L) + expect_true(is.numeric(attr(result, "score"))) + expect_true(attr(result, "score") >= 0) +}) + + +# .CollapseEdge -------------------------------------------------------------- + +test_that(".CollapseEdge produces valid non-binary tree", { + tr <- as.phylo(1, 10) + edge <- tr$edge + nTip <- NTip(tr) + + set.seed(1234) + result <- .CollapseEdge(edge[, 1], edge[, 2], nTip) + + expect_length(result, 2L) + newParent <- result[[1]] + newChild <- result[[2]] + + # One fewer edge + expect_equal(length(newParent), nrow(edge) - 1L) + + # Still a valid tree: tips 1..nTip all present as children + expect_true(all(seq_len(nTip) %in% newChild)) + + # At least one polytomy (degree > 2) + expect_true(any(tabulate(newParent) > 2L)) +}) + +test_that(".CollapseEdge handles star tree gracefully", { + nTip <- 5L + parent <- rep(nTip + 1L, nTip) + child <- seq_len(nTip) + + result <- .CollapseEdge(parent, child, nTip) + expect_equal(result[[1]], parent) + expect_equal(result[[2]], child) +}) + + +# .ResolveNode ---------------------------------------------------------------- + +test_that(".ResolveNode resolves a polytomy", { + nTip <- 5L + parent <- c(6L, 6L, 7L, 7L, 7L, 6L) + child <- c(1L, 7L, 2L, 3L, 4L, 5L) + + set.seed(5555) + result <- .ResolveNode(parent, child, nTip) + newParent <- result[[1]] + newChild <- result[[2]] + + # One more edge than original + expect_equal(length(newParent), length(parent) + 1L) + + # All tips still present + expect_true(all(seq_len(nTip) %in% newChild)) +}) + +test_that(".ResolveNode returns unchanged on binary tree", { + tr <- as.phylo(1, 8) + edge <- tr$edge + nTip <- NTip(tr) + + result <- .ResolveNode(edge[, 1], edge[, 2], nTip) + expect_equal(result[[1]], edge[, 1]) + expect_equal(result[[2]], edge[, 2]) +}) + + +# .RenumberNodes --------------------------------------------------------------- + +test_that(".RenumberNodes fills gaps in node numbering", { + nTip <- 4L + parent <- c(5L, 5L, 7L, 7L, 5L) + child <- c(1L, 7L, 2L, 3L, 4L) + + result <- .RenumberNodes(parent, child, nTip) + newParent <- result[[1]] + newChild <- result[[2]] + + internalNew <- sort(unique(c(newParent, newChild))) + internalNew <- internalNew[internalNew > nTip] + + # Should be contiguous from nTip+1 + expect_equal(internalNew, seq(nTip + 1L, nTip + length(internalNew))) +}) + + +# Collapse then resolve roundtrip ------------------------------------------- + +test_that("Collapse then resolve preserves tip set", { + tr <- as.phylo(1, 10) + edge <- tr$edge + nTip <- NTip(tr) + origEdges <- nrow(edge) + + set.seed(7777) + collapsed <- .CollapseEdge(edge[, 1], edge[, 2], nTip) + expect_equal(length(collapsed[[1]]), origEdges - 1L) + + resolved <- .ResolveNode(collapsed[[1]], collapsed[[2]], nTip) + expect_equal(length(resolved[[1]]), origEdges) + + # All tips present + expect_true(all(seq_len(nTip) %in% resolved[[2]])) +}) + + +# .CollapseSwap and .ResolveSwap interface ----------------------------------- + +test_that(".CollapseSwap follows EdgeSwapper interface", { + tr <- as.phylo(1, 10) + edge <- tr$edge + set.seed(4444) + result <- .CollapseSwap(edge[, 1], edge[, 2]) + expect_length(result, 2L) + expect_true(is.integer(result[[1]]) || is.numeric(result[[1]])) +}) + +test_that(".ResolveSwap follows EdgeSwapper interface", { + nTip <- 5L + parent <- c(6L, 6L, 7L, 7L, 7L, 6L) + child <- c(1L, 7L, 2L, 3L, 4L, 5L) + set.seed(6666) + result <- .ResolveSwap(parent, child) + expect_length(result, 2L) +}) + + +# .CollapseSpecificEdge ------------------------------------------------------- + +test_that(".CollapseSpecificEdge collapses the targeted edge", { + tr <- as.phylo(1, 8) + edge <- tr$edge + nTip <- NTip(tr) + internalEdges <- which(edge[, 2] > nTip) + + result <- .CollapseSpecificEdge(edge[, 1], edge[, 2], internalEdges[1], nTip) + expect_equal(length(result[[1]]), nrow(edge) - 1L) + expect_true(all(seq_len(nTip) %in% result[[2]])) +}) + + +# .ResolveSpecificPair ------------------------------------------------------- + +test_that(".ResolveSpecificPair creates a new binary split", { + nTip <- 5L + parent <- c(6L, 6L, 6L, 6L, 6L) + child <- c(1L, 2L, 3L, 4L, 5L) + moveEdges <- c(1L, 2L) + + result <- .ResolveSpecificPair(parent, child, 6L, moveEdges, nTip) + newParent <- result[[1]] + newChild <- result[[2]] + + # One more edge + expect_equal(length(newParent), length(parent) + 1L) + # Tips 1 and 2 now share a new parent + expect_equal(newParent[1], newParent[2]) + expect_true(newParent[1] != 6L) +}) + + +# .CollapseRefine --------------------------------------------------------------- + +test_that(".CollapseRefine can collapse edges to improve score", { + set.seed(3210) + goodTree <- as.phylo(1, 10) + inputTrees <- c(rep(list(goodTree), 19), + list(as.phylo(99, 10))) + class(inputTrees) <- "multiPhylo" + + cidData <- .MakeCIDData(inputTrees, goodTree$tip.label) + + badTree <- as.phylo(50, 10) + badScore <- .ScoreTree(badTree, cidData) # internal negated MCI + + result <- .CollapseRefine(badTree, cidData, verbosity = 0L) + resultScore <- attr(result, "score") # internal negated MCI + + # Lower negated MCI = higher MCI = better; should be no worse + expect_true(resultScore <= badScore + sqrt(.Machine$double.eps)) +}) + +test_that(".CollapseRefine returns valid phylo", { + cidData <- .MakeCIDData(smallTrees, smallTrees[[1]]$tip.label) + startTree <- smallTrees[[1]] + + result <- .CollapseRefine(startTree, cidData, verbosity = 0L) + expect_s3_class(result, "phylo") + expect_true(!is.null(attr(result, "score"))) + expect_equal(length(result$tip.label), 12L) +}) + + +# InfoConsensus with collapse ------------------------------------------------- + +test_that("InfoConsensus collapse=TRUE produces equal-or-better score", { + set.seed(7799) + resultNoCollapse <- InfoConsensus(smallTrees, + maxReplicates = 2L, targetHits = 1L, + neverDrop = TRUE, collapse = FALSE, + verbosity = 0L) + set.seed(7799) + resultCollapse <- InfoConsensus(smallTrees, + maxReplicates = 2L, targetHits = 1L, + neverDrop = TRUE, collapse = TRUE, + verbosity = 0L) + + # Higher MCI = better; collapse should improve or equal + expect_true(attr(resultCollapse, "score") >= + attr(resultNoCollapse, "score") - sqrt(.Machine$double.eps)) +}) + + +# --- MCI scoring (.CIDScoreFast) ------------------------------------------- + +test_that("Internal MCI score is negative (negated mean MCI)", { + cidData <- .MakeCIDData(smallTrees, smallTrees[[1]]$tip.label) + tr <- smallTrees[[1]] + edge <- tr$edge + score <- .CIDScorer(edge[, 1], edge[, 2], cidData) + expect_true(score <= 0) + # Negated MCI should match -mean(MCI) + r_mci <- mean(MutualClusteringInfo(tr, smallTrees)) + expect_equal(-score, r_mci, tolerance = 1e-6) +}) + + +# --- .InsertTipAtEdge ------------------------------------------------------- + +test_that(".InsertTipAtEdge produces valid phylo", { + tr <- as.phylo(1, 8) + for (i in 1:nrow(tr$edge)) { + inserted <- .InsertTipAtEdge(tr, "new_tip", i) + expect_s3_class(inserted, "phylo") + expect_equal(NTip(inserted), 9L) + expect_true("new_tip" %in% inserted$tip.label) + expect_equal(inserted$Nnode, tr$Nnode + 1L) + } +}) + + +# --- .PruneTrees ------------------------------------------------------------ + +test_that(".PruneTrees drops tips from all trees", { + pruned <- .PruneTrees(smallTrees, "t1") + expect_equal(length(pruned), length(smallTrees)) + expect_equal(NTip(pruned[[1]]), NTip(smallTrees[[1]]) - 1L) + expect_false("t1" %in% pruned[[1]]$tip.label) +}) + +test_that(".PruneTrees returns unchanged on empty drop set", { + result <- .PruneTrees(smallTrees, character(0)) + expect_identical(result, smallTrees) +}) + + +# --- .ScoreTree ------------------------------------------------------------- + +test_that(".ScoreTree matches .CIDScorer on edge vectors", { + cidData <- .MakeCIDData(smallTrees, smallTrees[[1]]$tip.label) + tr <- smallTrees[[1]] + edge <- tr$edge + expect_equal(.ScoreTree(tr, cidData), + .CIDScorer(edge[, 1], edge[, 2], cidData)) +}) + + +# --- Rogue dropping (toy example) ------------------------------------------ + +test_that("Rogue taxon correctly identified in toy example", { + base <- ape::read.tree(text = "((a,b),(c,(d,e)));") + set.seed(2891) + rogue_trees <- lapply(sample.int(nrow(base$edge), 5), function(i) + .InsertTipAtEdge(base, "r", i)) + class(rogue_trees) <- "multiPhylo" + + set.seed(2891) + result <- InfoConsensus(rogue_trees, + maxReplicates = 3L, targetHits = 2L, + neverDrop = FALSE, + verbosity = 0L) + expect_equal(attr(result, "droppedTips"), "r") + expect_false("r" %in% result$tip.label) +}) + + +# --- neverDrop parameter ---------------------------------------------------- + +test_that("neverDrop = TRUE prevents rogue dropping", { + set.seed(4817) + result <- InfoConsensus(smallTrees, + maxReplicates = 2L, targetHits = 1L, + neverDrop = TRUE, + verbosity = 0L) + expect_null(attr(result, "droppedTips")) + expect_equal(NTip(result), 12L) +}) + +test_that("neverDrop protects specified tips", { + base <- ape::read.tree(text = "((a,b),(c,(d,e)));") + set.seed(2891) + rogue_trees <- lapply(sample.int(nrow(base$edge), 5), function(i) + .InsertTipAtEdge(base, "r", i)) + class(rogue_trees) <- "multiPhylo" + + set.seed(2891) + result <- InfoConsensus(rogue_trees, + maxReplicates = 3L, targetHits = 2L, + neverDrop = c("r", "a"), + verbosity = 0L) + expect_true("r" %in% result$tip.label) + expect_true("a" %in% result$tip.label) +}) + + +# --- maxDrop parameter ------------------------------------------------------- + +test_that("maxDrop limits the number of dropped tips", { + set.seed(4817) + result <- InfoConsensus(smallTrees, + maxReplicates = 2L, targetHits = 1L, + neverDrop = FALSE, + maxDrop = 1L, + verbosity = 0L) + nDropped <- length(attr(result, "droppedTips")) + expect_true(nDropped <= 1L) +}) + + + diff --git a/tests/testthat/test-NNI.R b/tests/testthat/test-NNI.R index 09bab3d60..099b4b557 100644 --- a/tests/testthat/test-NNI.R +++ b/tests/testthat/test-NNI.R @@ -3,7 +3,7 @@ test_that("Errors fail gracefully", { }) test_that("cNNI()", { - tr <- Preorder(root(TreeTools::BalancedTree(letters[1:7]), "a", resolve.root = TRUE)) + tr <- Preorder(RootTree(TreeTools::BalancedTree(letters[1:7]), "a")) expect_equal(ape::read.tree(text="(a,(b,((c,d),((e,g),f))));"), cNNI(tr, 0, 1)) # Edge "9" expect_equal(ape::read.tree(text="(a,(b,((c,d),((f,g),e))));"), diff --git a/tests/testthat/test-rearrange.cpp.R b/tests/testthat/test-rearrange.cpp.R index a3956d4eb..f9d72aae4 100644 --- a/tests/testthat/test-rearrange.cpp.R +++ b/tests/testthat/test-rearrange.cpp.R @@ -1,21 +1,21 @@ library("TreeTools") test_that("TBR errors", { - tr <- Preorder(root(TreeTools::BalancedTree(7), 't1', resolve.root = TRUE)) + tr <- Preorder(RootTree(TreeTools::BalancedTree(7), "t1")) expect_equal(0, length(expect_warning(TreeSearch:::all_tbr(tr$edge, -1)))) expect_equal(0, length(expect_warning(TreeSearch:::all_tbr(tr$edge, 1)))) expect_equal(0, length(expect_warning(TreeSearch:::all_tbr(tr$edge, 111)))) }) test_that("SPR errors", { - tr <- Preorder(root(TreeTools::BalancedTree(7), 't1', resolve.root = TRUE)) + tr <- Preorder(RootTree(TreeTools::BalancedTree(7), "t1")) expect_equal(0, length(expect_warning(TreeSearch:::all_spr(tr$edge, -1)))) expect_equal(0, length(expect_warning(TreeSearch:::all_spr(tr$edge, 1)))) expect_equal(0, length(expect_warning(TreeSearch:::all_spr(tr$edge, 111)))) }) test_that("TBR working", { - tr <- Preorder(root(TreeTools::BalancedTree(7), 't1', resolve.root = TRUE)) + tr <- Preorder(RootTree(TreeTools::BalancedTree(7), "t1")) # Move single tip expect_equal(8, length(x <- TreeSearch:::all_tbr(tr$edge, 12))) @@ -39,7 +39,7 @@ test_that("TBR working", { expect_equal(58, length(unique(x <- TreeSearch:::all_tbr(tr$edge, integer(0))))) # 58 not formally calculated expect_equal(58, length(TBRMoves(tr))) - tr <- Preorder(root(TreeTools::BalancedTree(14), 't1', resolve.root = TRUE)) + tr <- Preorder(RootTree(TreeTools::BalancedTree(14), "t1")) desc <- TreeTools::CladeSizes(tr) external <- c(3, 6, 7, 11, 12, 13, 17, 18, 20, 21, 24:26) @@ -68,7 +68,7 @@ test_that("SPR works", { t2 <- as.phylo(518, 7) # (t1, ((t2, t3), ((t4, t5), (t6, t7)))) expect_equal(8, length(TreeSearch:::all_spr(t2$edge, 2))) - tr <- Preorder(root(TreeTools::BalancedTree(7), 't1', resolve.root = TRUE)) + tr <- Preorder(RootTree(TreeTools::BalancedTree(7), "t1")) # Move single tip expect_equal(8, length(TreeSearch:::all_spr(tr$edge, 12))) @@ -95,7 +95,7 @@ test_that("SPR works", { uniqueMoves) expect_equal(uniqueMoves, length(SPRMoves(tr))) - tr <- Preorder(root(TreeTools::BalancedTree(14), 't1', resolve.root = TRUE)) + tr <- Preorder(RootTree(TreeTools::BalancedTree(14), "t1")) tr$edge desc <- TreeTools::CladeSizes(tr) @@ -121,7 +121,7 @@ test_that("SPR works", { }) if (FALSE) test_that("SPR works", { - testTree <- Preorder(root(TreeTools::BalancedTree(7), 't1', resolve.root = TRUE)) + testTree <- Preorder(RootTree(TreeTools::BalancedTree(7), "t1")) plot(testTree); nodelabels(); edgelabels() edge <- testTree$edge @@ -136,7 +136,7 @@ if (FALSE) test_that("SPR works", { test.tr$edge <- spr(edge, m) plot(test.tr) - oldWay <- SortTree(root(SPR(testTree, p1, r1), 't1', resolve.root = TRUE)) + oldWay <- SortTree(RootTree(SPR(testTree, p1, r1), "t1")) expect_equal(oldWay, SortTree(test.tr)) } Test(0, 1, 5) diff --git a/tests/testthat/test-ts-cid.R b/tests/testthat/test-ts-cid.R new file mode 100644 index 000000000..0fe69c49f --- /dev/null +++ b/tests/testthat/test-ts-cid.R @@ -0,0 +1,364 @@ +# Tier 2: skipped on CRAN; see tests/testing-strategy.md +skip_on_cran() + +library(TreeTools) +library(TreeDist) + +# Helpers +.CIDScorer <- TreeSearch:::.CIDScorer +.MakeCIDData <- TreeSearch:::.MakeCIDData +.ScoreTree <- TreeSearch:::.ScoreTree +.EdgeListToPhylo <- TreeSearch:::.EdgeListToPhylo +ts_cid_consensus <- TreeSearch:::ts_cid_consensus + +set.seed(6183) +smallTrees <- as.phylo(sample.int(100, 20), nTip = 12) +tipLabels <- smallTrees[[1]]$tip.label + + +# --- ts_cid_consensus basic smoke test ---------------------------------------- + +test_that("ts_cid_consensus returns valid result", { + splitMats <- lapply(smallTrees, function(tr) { + unclass(as.Splits(tr, tipLabels)) + }) + + set.seed(8472) + result <- ts_cid_consensus( + splitMatrices = splitMats, + nTip = 12L, + normalize = FALSE, + maxReplicates = 3L, + targetHits = 2L, + verbosity = 0L, + nThreads = 1L + ) + + expect_type(result, "list") + expect_true(result$pool_size > 0L) + expect_true(is.numeric(result$best_score)) + # Score is negated MCI: should be <= 0 + expect_true(result$best_score <= 0) + + # Tree is a valid edge matrix + bestEdge <- result$trees[[1]] + expect_equal(ncol(bestEdge), 2L) + nTip <- 12L + expect_true(all(seq_len(nTip) %in% bestEdge[, 2])) +}) + + +# --- Negated MCI matches R-level MCI ----------------------------------------- + +test_that("C++ negated MCI matches R-level mean(MCI)", { + splitMats <- lapply(smallTrees, function(tr) { + unclass(as.Splits(tr, tipLabels)) + }) + + set.seed(3719) + result <- ts_cid_consensus( + splitMatrices = splitMats, + nTip = 12L, + normalize = FALSE, + maxReplicates = 2L, + targetHits = 1L, + verbosity = 0L, + nThreads = 1L + ) + + bestEdge <- result$trees[[1]] + bestTree <- .EdgeListToPhylo(bestEdge[, 1], bestEdge[, 2], tipLabels) + + # R-level mean MCI + r_mci <- mean(MutualClusteringInfo(bestTree, smallTrees)) + + # C++ returns negated MCI + expect_equal(-result$best_score, r_mci, tolerance = 1e-6) +}) + + +# --- Search improves over majority-rule consensus ---------------------------- + +test_that("C++ search improves over majority-rule consensus", { + mr <- Consensus(smallTrees, p = 0.5) + mr_binary <- MakeTreeBinary(mr) + + splitMats <- lapply(smallTrees, function(tr) { + unclass(as.Splits(tr, tipLabels)) + }) + + set.seed(5902) + result <- ts_cid_consensus( + splitMatrices = splitMats, + nTip = 12L, + normalize = FALSE, + maxReplicates = 5L, + targetHits = 3L, + verbosity = 0L, + nThreads = 1L + ) + + expect_true(result$pool_size > 0L) + expect_true(is.finite(result$best_score)) +}) + + +# --- InfoConsensus R wrapper --------------------------------------------------- + +test_that("InfoConsensus runs end-to-end", { + set.seed(4291) + result <- InfoConsensus(smallTrees, + maxReplicates = 2L, targetHits = 1L, + neverDrop = TRUE, collapse = FALSE, + verbosity = 0L) + + expect_s3_class(result, "phylo") + expect_true(!is.null(attr(result, "score"))) + expect_true(is.numeric(attr(result, "score"))) + # User-facing score is positive MCI + expect_true(attr(result, "score") >= 0) + expect_equal(NTip(result), 12L) +}) + +test_that("InfoConsensus score matches mean(MutualClusteringInfo)", { + set.seed(4291) + result <- InfoConsensus(smallTrees, + maxReplicates = 2L, targetHits = 1L, + neverDrop = TRUE, collapse = FALSE, + verbosity = 0L) + + r_mci <- mean(MutualClusteringInfo(result, smallTrees)) + expect_equal(attr(result, "score"), r_mci, tolerance = 1e-6) +}) + +test_that("InfoConsensus with collapse improves or equals binary", { + set.seed(4291) + noColl <- InfoConsensus(smallTrees, + maxReplicates = 2L, targetHits = 1L, + neverDrop = TRUE, collapse = FALSE, + verbosity = 0L) + set.seed(4291) + coll <- InfoConsensus(smallTrees, + maxReplicates = 2L, targetHits = 1L, + neverDrop = TRUE, collapse = TRUE, + verbosity = 0L) + + # Higher MCI = better; collapse should improve or equal + expect_true(attr(coll, "score") >= + attr(noColl, "score") - sqrt(.Machine$double.eps)) +}) + +test_that("InfoConsensus rejects bad input", { + expect_error(InfoConsensus(as.phylo(1, 10)), "multiPhylo") + expect_error(InfoConsensus(c(as.phylo(1, 10))), "at least 2") +}) + + +# --- Sectorial search with CID -------------------------------------------------- + +test_that("CID search with sectors enabled produces valid results", { + # Use 20-tip trees so sectors can activate (>= 2 * sectorMinSize) + set.seed(7341) + trees20 <- as.phylo(sample.int(200, 30), nTip = 20) + tl <- trees20[[1]]$tip.label + splitMats <- lapply(trees20, function(tr) unclass(as.Splits(tr, tl))) + + set.seed(2519) + result <- ts_cid_consensus( + splitMatrices = splitMats, + nTip = 20L, + normalize = FALSE, + maxReplicates = 3L, + targetHits = 2L, + xssRounds = 2L, + rssRounds = 2L, + cssRounds = 1L, + sectorMinSize = 6L, + sectorMaxSize = 15L, + verbosity = 0L, + nThreads = 1L + ) + + expect_true(result$pool_size > 0L) + expect_true(is.finite(result$best_score)) + bestEdge <- result$trees[[1]] + expect_true(all(seq_len(20L) %in% bestEdge[, 2])) +}) + +test_that("Sectors-enabled score <= sectors-disabled score", { + set.seed(7341) + trees20 <- as.phylo(sample.int(200, 30), nTip = 20) + tl <- trees20[[1]]$tip.label + splitMats <- lapply(trees20, function(tr) unclass(as.Splits(tr, tl))) + + set.seed(9156) + no_sectors <- ts_cid_consensus( + splitMatrices = splitMats, + nTip = 20L, + normalize = FALSE, + maxReplicates = 5L, + targetHits = 3L, + xssRounds = 0L, + rssRounds = 0L, + cssRounds = 0L, + verbosity = 0L, + nThreads = 1L + ) + + set.seed(9156) + with_sectors <- ts_cid_consensus( + splitMatrices = splitMats, + nTip = 20L, + normalize = FALSE, + maxReplicates = 5L, + targetHits = 3L, + xssRounds = 3L, + rssRounds = 3L, + cssRounds = 2L, + sectorMinSize = 6L, + sectorMaxSize = 15L, + verbosity = 0L, + nThreads = 1L + ) + + # Negated MCI: lower = better; sectors should help or not hurt + expect_true(with_sectors$best_score <= + no_sectors$best_score + sqrt(.Machine$double.eps)) +}) + +test_that("Small tree gracefully skips sectors", { + splitMats <- lapply(smallTrees, function(tr) { + unclass(as.Splits(tr, tipLabels)) + }) + + # 12-tip tree with sectorMinSize = 8 → 2*8=16 > 12, sectors skipped + set.seed(4018) + result <- ts_cid_consensus( + splitMatrices = splitMats, + nTip = 12L, + normalize = FALSE, + maxReplicates = 2L, + targetHits = 1L, + xssRounds = 3L, + rssRounds = 3L, + cssRounds = 2L, + sectorMinSize = 8L, + verbosity = 0L, + nThreads = 1L + ) + + expect_true(result$pool_size > 0L) + expect_true(is.finite(result$best_score)) +}) + +# --- MRP split deduplication --------------------------------------------------- + +test_that("MRP dedup: identical trees produce correct consensus", { + ref <- as.phylo(42, nTip = 12) + identicalTrees <- rep(list(ref), 50) + class(identicalTrees) <- "multiPhylo" + + set.seed(5891) + result <- InfoConsensus(identicalTrees, + maxReplicates = 2L, targetHits = 1L, + neverDrop = TRUE, collapse = FALSE, + verbosity = 0L) + + expect_s3_class(result, "phylo") + # R score is positive (higher = better); should be > 0 for matching trees + expect_true(attr(result, "score") > 0) + + # Verify result is topologically correct using CID + resultCID <- ClusteringInfoDistance(result, ref) + expect_equal(resultCID, 0, tolerance = 1e-6) +}) + +test_that("MRP dedup: duplicated trees give same result as unique", { + set.seed(4027) + baseTrees <- as.phylo(sample.int(200, 10), nTip = 15) + + # Duplicate each tree 5x + dupTrees <- rep(baseTrees, each = 5) + class(dupTrees) <- "multiPhylo" + + set.seed(9134) + resultDup <- InfoConsensus(dupTrees, + maxReplicates = 3L, targetHits = 2L, + neverDrop = TRUE, collapse = FALSE, + verbosity = 0L) + + set.seed(9134) + resultOrig <- InfoConsensus(baseTrees, + maxReplicates = 3L, targetHits = 2L, + neverDrop = TRUE, collapse = FALSE, + verbosity = 0L) + + # Scores should be identical (same mean MCI — duplicates don't change the mean) + expect_equal(attr(resultDup, "score"), attr(resultOrig, "score"), + tolerance = 1e-6) +}) + +test_that("InfoConsensus R wrapper with sectors enabled", { + set.seed(7341) + trees20 <- as.phylo(sample.int(200, 30), nTip = 20) + + set.seed(6612) + result <- InfoConsensus(trees20, + maxReplicates = 3L, targetHits = 2L, + neverDrop = TRUE, collapse = FALSE, + verbosity = 0L) + + expect_s3_class(result, "phylo") + expect_true(is.finite(attr(result, "score"))) + expect_equal(NTip(result), 20L) +}) + +# --- Plateau stopping for CID ------------------------------------------------ + +test_that("Plateau stopping exits early on identical trees", { + # With identical input trees, CID = 0 for the optimal tree. Every replicate + + # converges to the same score, so no replicate improves on the previous best. + # plateauReps = 2 should trigger after 2 consecutive non-improving replicates, + # well before maxReplicates = 10. + set.seed(4297) + tree <- RandomTree(15) + identicalTrees <- rep(list(tree), 10) + class(identicalTrees) <- "multiPhylo" + tipLabels <- tree$tip.label + splitMats <- lapply(identicalTrees, function(tr) { + unclass(as.Splits(tr, tipLabels)) + }) + + result <- ts_cid_consensus( + splitMatrices = splitMats, + nTip = 15L, + normalize = FALSE, + maxReplicates = 10L, + targetHits = 100L, # disable hit-count stopping + tbrMaxHits = 1L, + ratchetCycles = 0L, + driftCycles = 0L, + xssRounds = 0L, + rssRounds = 0L, + cssRounds = 0L, + fuseInterval = 0L, + poolMaxSize = 100L, + poolSuboptimal = 0.0, + maxSeconds = 60.0, + verbosity = 0L, + tabuSize = 100L, + wagnerStarts = 1L, + nThreads = 1L, + screeningK = 7.0, + screeningTolerance = 0.0, + scoreTol = 0.001, + plateauReps = 2L + ) + + # Should exit well before 10 replicates + expect_lt(result[["replicates"]], 10L) + # First replicate sets the baseline; replicates 2 and 3 don't improve + # → plateau fires after rep 3 at latest + expect_lte(result[["replicates"]], 4L) +}) diff --git a/tests/testthat/test-zzz-tree-rearrange.R b/tests/testthat/test-zzz-tree-rearrange.R index 0117f7103..1d109247c 100644 --- a/tests/testthat/test-zzz-tree-rearrange.R +++ b/tests/testthat/test-zzz-tree-rearrange.R @@ -58,7 +58,7 @@ test_that("NNI works", { test_that("SPR works", { - testTree <- Preorder(root(BalancedTree(7), 1, resolve.root = TRUE)) + testTree <- Preorder(RootTree(BalancedTree(7), 1)) edge <- testTree[["edge"]] expect_equal(TreeSearch:::spr(edge, 66), cSPR(testTree, 66)$edge) @@ -66,7 +66,7 @@ test_that("SPR works", { test.tr <- testTree test.tr$edge <- TreeSearch:::spr(edge, m) - oldWay <- SortTree(root(SPR(testTree, p1, r1), "t1", resolve.root = TRUE)) + oldWay <- SortTree(RootTree(SPR(testTree, p1, r1), "t1")) expect_equal(oldWay, SortTree(test.tr)) } Test(0, 1, 5) @@ -225,7 +225,7 @@ test_that("RootedSPR fails", { test_that("SPR is special case of TBR", { expect_equal(SPR(tree11, 3, 9), TBR(tree11, 3, c(3, 9))) expect_equal(SPR(tree11, 12, 9), TBR(tree11, 12, c(12, 9))) - expect_equal(root(SPR(tree11, 1, 14), letters[1:5], resolve.root=TRUE), TBR(tree11, 1, c(1, 14))) + expect_equal(RootTree(SPR(tree11, 1, 14), letters[1:5]), TBR(tree11, 1, c(1, 14))) expect_error(SPR(tree11, 1, 6)) }) diff --git a/vignettes/profile.Rmd b/vignettes/profile.Rmd index 4f416542d..ef8ccf1d9 100644 --- a/vignettes/profile.Rmd +++ b/vignettes/profile.Rmd @@ -92,7 +92,7 @@ Let's see the resultant tree, and its score: ```{r ratchet-search-results} TreeLength(betterTrees[[1]], myMatrix, "profile") par(mar = rep(0.25, 4), cex = 0.75) # make plot easier to read -plot(ape::consensus(betterTrees)) +plot(TreeTools::Consensus(betterTrees)) ``` Type `?MaximizeParsimony` to view all search parameters, including strategy @@ -120,7 +120,7 @@ typically more reliable, summary of the signal with the phylogenetic dataset ```{r plot-suboptimal-consensus} par(mar = rep(0.25, 4), cex = 0.75) table(signif(TreeLength(suboptimals, myMatrix, "profile"))) -plot(ape::consensus(suboptimals)) +plot(TreeTools::Consensus(suboptimals)) ``` diff --git a/vignettes/tree-search.Rmd b/vignettes/tree-search.Rmd index aeb47154e..4d62776b1 100644 --- a/vignettes/tree-search.Rmd +++ b/vignettes/tree-search.Rmd @@ -104,7 +104,7 @@ We can plot the best tree(s) that we've found, and check its parsimony score ```{r plot-tree} par(mar = rep(0.25, 4), cex = 0.75) # make plot easier to read -plot(ape::consensus(bestTrees)) +plot(TreeTools::Consensus(bestTrees)) TreeLength(bestTrees[[1]], vinther) ``` @@ -115,7 +115,7 @@ sampled most-parsimonious trees: ```{r plot-label-nodes} par(mar = rep(0.25, 4), cex = 0.75) # make plot easier to read -majCons <- ape::consensus(bestTrees, p = 0.5) +majCons <- TreeTools::Consensus(bestTrees, p = 0.5) splitFreqs <- TreeTools::SplitFrequency(majCons, bestTrees) / length(bestTrees) plot(majCons) TreeTools::LabelSplits(majCons, round(splitFreqs * 100), unit = "%", @@ -157,7 +157,7 @@ nReplicates <- 10 jackTrees <- Resample(vinther, bestTrees, nReplicates = nReplicates, verbosity = 0) -strict <- ape::consensus(bestTrees, p = 1) +strict <- TreeTools::Consensus(bestTrees, p = 1) par(mar = rep(0, 4), cex = 0.8) # Take the strict consensus of all trees for each replicate @@ -218,7 +218,7 @@ The most informative single summary tree is thus provided by: ```{r cons-without-halk} par(mar = rep(0, 4), cex = 0.8) noWiwaxia <- lapply(bestTrees, TreeTools::DropTip, "Wiwaxia") -plot(ape::consensus(noWiwaxia), tip.color = Rogue::ColByStability(noWiwaxia)) +plot(TreeTools::Consensus(noWiwaxia), tip.color = Rogue::ColByStability(noWiwaxia)) ``` This reveals that all trees agree that _Halkieria_ and _Orthrozanclus_ are @@ -311,7 +311,7 @@ constant, _k_: ```{r iw-search, message = FALSE} iwTrees <- MaximizeParsimony(vinther, concavity = 10) par(mar = rep(0.25, 4), cex = 0.75) # make plot easier to read -plot(ape::consensus(iwTrees)) +plot(TreeTools::Consensus(iwTrees)) ``` Note that we recommend a default value of 10, somewhat higher than the default