phykit 2.1.32__tar.gz → 2.1.34__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {phykit-2.1.32 → phykit-2.1.34}/PKG-INFO +1 -1
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/discordance_asymmetry.py +96 -29
- phykit-2.1.34/phykit/version.py +1 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit.egg-info/PKG-INFO +1 -1
- phykit-2.1.32/phykit/version.py +0 -1
- {phykit-2.1.32 → phykit-2.1.34}/LICENSE.md +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/README.md +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/__init__.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/__main__.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/cli_registry.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/errors.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/helpers/__init__.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/helpers/boolean_argument_parsing.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/helpers/caching.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/helpers/files.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/helpers/json_output.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/helpers/parallel.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/helpers/stats_summary.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/helpers/streaming.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/phykit.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/service_factories.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/__init__.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/alignment/__init__.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/alignment/alignment_entropy.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/alignment/alignment_length.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/alignment/alignment_length_no_gaps.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/alignment/alignment_outlier_taxa.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/alignment/alignment_recoding.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/alignment/base.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/alignment/column_score.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/alignment/composition_per_taxon.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/alignment/compositional_bias_per_site.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/alignment/create_concatenation_matrix.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/alignment/dna_threader.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/alignment/evolutionary_rate_per_site.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/alignment/faidx.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/alignment/gc_content.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/alignment/mask_alignment.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/alignment/occupancy_per_taxon.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/alignment/pairwise_identity.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/alignment/parsimony_informative_sites.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/alignment/plot_alignment_qc.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/alignment/rcv.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/alignment/rcvt.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/alignment/rename_fasta_entries.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/alignment/sum_of_pairs_score.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/alignment/variable_sites.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/base.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/__init__.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/ancestral_reconstruction.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/base.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/bipartition_support_stats.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/branch_length_multiplier.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/collapse_branches.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/concordance_asr.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/consensus_network.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/consensus_tree.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/cont_map.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/cophylo.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/covarying_evolutionary_rates.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/density_map.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/dvmc.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/evo_tempo_map.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/evolutionary_rate.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/fit_continuous.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/hidden_paralogy_check.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/internal_branch_stats.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/internode_labeler.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/last_common_ancestor_subtree.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/lb_score.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/ltt.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/monophyly_check.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/nearest_neighbor_interchange.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/network_signal.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/ou_shift_detection.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/ouwie.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/patristic_distances.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/phenogram.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/phylogenetic_glm.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/phylogenetic_ordination.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/phylogenetic_regression.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/phylogenetic_signal.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/phylomorphospace.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/polytomy_test.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/print_tree.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/prune_tree.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/quartet_network.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/rate_heterogeneity.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/relative_rate_test.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/rename_tree_tips.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/rf_distance.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/root_tree.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/saturation.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/spurious_sequence.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/stochastic_character_map.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/terminal_branch_stats.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/threshold_model.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/tip_labels.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/tip_to_tip_distance.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/tip_to_tip_node_distance.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/total_tree_length.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/treeness.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/treeness_over_rcv.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit/services/tree/vcv_utils.py +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit.egg-info/SOURCES.txt +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit.egg-info/dependency_links.txt +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit.egg-info/entry_points.txt +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit.egg-info/requires.txt +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/phykit.egg-info/top_level.txt +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/setup.cfg +0 -0
- {phykit-2.1.32 → phykit-2.1.34}/setup.py +0 -0
|
@@ -32,7 +32,7 @@ class DiscordanceAsymmetry(Tree):
|
|
|
32
32
|
species_tree = self.read_tree_file()
|
|
33
33
|
gene_trees = self._parse_gene_trees(self.gene_trees_path)
|
|
34
34
|
|
|
35
|
-
topology_counts = self._count_topologies(species_tree, gene_trees)
|
|
35
|
+
topology_counts, shared_taxa = self._count_topologies(species_tree, gene_trees)
|
|
36
36
|
|
|
37
37
|
# Test each branch and collect results
|
|
38
38
|
branch_results = []
|
|
@@ -82,7 +82,8 @@ class DiscordanceAsymmetry(Tree):
|
|
|
82
82
|
self._output_text(branch_results, summary)
|
|
83
83
|
|
|
84
84
|
if self.plot_output:
|
|
85
|
-
self._plot(species_tree, branch_results, self.plot_output
|
|
85
|
+
self._plot(species_tree, branch_results, self.plot_output,
|
|
86
|
+
shared_taxa=shared_taxa)
|
|
86
87
|
|
|
87
88
|
# ------------------------------------------------------------------
|
|
88
89
|
# Output methods
|
|
@@ -162,7 +163,8 @@ class DiscordanceAsymmetry(Tree):
|
|
|
162
163
|
)
|
|
163
164
|
print_json(result)
|
|
164
165
|
|
|
165
|
-
def _plot(self, species_tree, branch_results, output_path
|
|
166
|
+
def _plot(self, species_tree, branch_results, output_path,
|
|
167
|
+
shared_taxa=None) -> None:
|
|
166
168
|
"""Phylogram colored by asymmetry ratio at each branch."""
|
|
167
169
|
import matplotlib
|
|
168
170
|
matplotlib.use("Agg")
|
|
@@ -178,7 +180,10 @@ class DiscordanceAsymmetry(Tree):
|
|
|
178
180
|
|
|
179
181
|
parent_map = self._build_parent_map(species_tree)
|
|
180
182
|
tips = list(species_tree.get_terminals())
|
|
181
|
-
|
|
183
|
+
# Use shared taxa (intersection with gene trees) for split label
|
|
184
|
+
# matching so labels are consistent with _count_topologies.
|
|
185
|
+
all_taxa_fs = (shared_taxa if shared_taxa is not None
|
|
186
|
+
else frozenset(t.name for t in tips))
|
|
182
187
|
|
|
183
188
|
# Compute node positions
|
|
184
189
|
node_x = {}
|
|
@@ -212,7 +217,7 @@ class DiscordanceAsymmetry(Tree):
|
|
|
212
217
|
for clade in species_tree.find_clades(order="preorder"):
|
|
213
218
|
if clade.is_terminal():
|
|
214
219
|
continue
|
|
215
|
-
node_tips = frozenset(t.name for t in clade.get_terminals())
|
|
220
|
+
node_tips = frozenset(t.name for t in clade.get_terminals()) & all_taxa_fs
|
|
216
221
|
split_label = (
|
|
217
222
|
sorted(node_tips)
|
|
218
223
|
if len(node_tips) <= len(all_taxa_fs) - len(node_tips)
|
|
@@ -361,6 +366,51 @@ class DiscordanceAsymmetry(Tree):
|
|
|
361
366
|
parent_map[id(child)] = clade
|
|
362
367
|
return parent_map
|
|
363
368
|
|
|
369
|
+
@staticmethod
|
|
370
|
+
def _collect_taxa(trees) -> set:
|
|
371
|
+
"""Collect the union of all tip names across a list of trees.
|
|
372
|
+
|
|
373
|
+
Uses a direct stack walk over .clades to avoid the overhead of
|
|
374
|
+
Bio.Phylo's find_clades / match_attrs dispatch layer.
|
|
375
|
+
"""
|
|
376
|
+
taxa = set()
|
|
377
|
+
for tree in trees:
|
|
378
|
+
stack = [tree.root]
|
|
379
|
+
while stack:
|
|
380
|
+
node = stack.pop()
|
|
381
|
+
if not node.clades:
|
|
382
|
+
taxa.add(node.name)
|
|
383
|
+
else:
|
|
384
|
+
stack.extend(node.clades)
|
|
385
|
+
return taxa
|
|
386
|
+
|
|
387
|
+
def _extract_splits(self, tree, all_taxa_fs) -> set:
|
|
388
|
+
"""Extract canonical bipartitions from a single tree.
|
|
389
|
+
|
|
390
|
+
Performs a single postorder traversal, building tip sets
|
|
391
|
+
bottom-up via .clades, and canonicalises each non-trivial split.
|
|
392
|
+
"""
|
|
393
|
+
splits = set()
|
|
394
|
+
tip_sets = {}
|
|
395
|
+
stack = [(tree.root, False)]
|
|
396
|
+
while stack:
|
|
397
|
+
node, children_done = stack[-1]
|
|
398
|
+
if not node.clades:
|
|
399
|
+
stack.pop()
|
|
400
|
+
name = node.name
|
|
401
|
+
tip_sets[id(node)] = frozenset((name,)) if name in all_taxa_fs else frozenset()
|
|
402
|
+
elif children_done:
|
|
403
|
+
stack.pop()
|
|
404
|
+
merged = frozenset().union(*(tip_sets[id(c)] for c in node.clades))
|
|
405
|
+
tip_sets[id(node)] = merged
|
|
406
|
+
if len(merged) > 1 and merged != all_taxa_fs:
|
|
407
|
+
splits.add(self._canonical_split(merged, all_taxa_fs))
|
|
408
|
+
else:
|
|
409
|
+
stack[-1] = (node, True)
|
|
410
|
+
for child in reversed(node.clades):
|
|
411
|
+
stack.append((child, False))
|
|
412
|
+
return splits
|
|
413
|
+
|
|
364
414
|
def _get_four_groups(self, tree, node, parent_map, all_taxa_fs):
|
|
365
415
|
"""Identify the four subtree groups around an internal branch.
|
|
366
416
|
|
|
@@ -376,26 +426,54 @@ class DiscordanceAsymmetry(Tree):
|
|
|
376
426
|
if node.is_terminal() or len(node.clades) < 2:
|
|
377
427
|
return None
|
|
378
428
|
|
|
379
|
-
C1 = frozenset(t.name for t in node.clades[0].get_terminals())
|
|
380
|
-
C2 = frozenset(t.name for t in node.clades[1].get_terminals())
|
|
429
|
+
C1 = frozenset(t.name for t in node.clades[0].get_terminals()) & all_taxa_fs
|
|
430
|
+
C2 = frozenset(t.name for t in node.clades[1].get_terminals()) & all_taxa_fs
|
|
381
431
|
# If node has >2 children (polytomy), merge extras into C2
|
|
382
432
|
for extra_child in node.clades[2:]:
|
|
383
|
-
C2 = C2 | frozenset(t.name for t in extra_child.get_terminals())
|
|
433
|
+
C2 = C2 | (frozenset(t.name for t in extra_child.get_terminals()) & all_taxa_fs)
|
|
384
434
|
|
|
385
435
|
parent = parent_map.get(id(node))
|
|
386
436
|
if parent is None:
|
|
387
437
|
# node is root — no branch above it
|
|
388
438
|
return None
|
|
389
439
|
|
|
390
|
-
# Get siblings of node under parent
|
|
440
|
+
# Get siblings of node under parent; pick the first sibling
|
|
441
|
+
# whose shared taxa are non-empty (avoids skipping valid branches
|
|
442
|
+
# when the first sibling's taxa are all absent from gene trees).
|
|
391
443
|
siblings = [c for c in parent.clades if id(c) != id(node)]
|
|
392
444
|
if not siblings:
|
|
393
445
|
return None
|
|
394
446
|
|
|
395
|
-
|
|
447
|
+
chosen_sib = None
|
|
448
|
+
S = frozenset()
|
|
449
|
+
for sib in siblings:
|
|
450
|
+
candidate = frozenset(t.name for t in sib.get_terminals()) & all_taxa_fs
|
|
451
|
+
if candidate:
|
|
452
|
+
S = candidate
|
|
453
|
+
chosen_sib = sib
|
|
454
|
+
break
|
|
455
|
+
|
|
456
|
+
if not S:
|
|
457
|
+
return None
|
|
458
|
+
|
|
396
459
|
# D = everything else (other siblings + above parent)
|
|
397
460
|
D = all_taxa_fs - C1 - C2 - S
|
|
398
461
|
|
|
462
|
+
# For the root branch (D empty), the sibling encompasses the
|
|
463
|
+
# entire other side of the tree. Decompose the sibling into its
|
|
464
|
+
# children to obtain proper 4-subtree NNI groups.
|
|
465
|
+
if not D:
|
|
466
|
+
if chosen_sib.is_terminal() or len(chosen_sib.clades) < 2:
|
|
467
|
+
return None
|
|
468
|
+
S = frozenset(t.name for t in chosen_sib.clades[0].get_terminals()) & all_taxa_fs
|
|
469
|
+
D = frozenset(t.name for t in chosen_sib.clades[1].get_terminals()) & all_taxa_fs
|
|
470
|
+
for extra in chosen_sib.clades[2:]:
|
|
471
|
+
D = D | (frozenset(t.name for t in extra.get_terminals()) & all_taxa_fs)
|
|
472
|
+
|
|
473
|
+
# Skip if any group is empty (branch is degenerate after taxon filtering)
|
|
474
|
+
if not C1 or not C2 or not S:
|
|
475
|
+
return None
|
|
476
|
+
|
|
399
477
|
return C1, C2, S, D
|
|
400
478
|
|
|
401
479
|
def _count_topologies(self, species_tree, gene_trees) -> Dict:
|
|
@@ -409,28 +487,17 @@ class DiscordanceAsymmetry(Tree):
|
|
|
409
487
|
n_alt1: int
|
|
410
488
|
n_alt2: int
|
|
411
489
|
"""
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
set(t.name for t in gt.get_terminals()) for gt in gene_trees
|
|
416
|
-
))
|
|
417
|
-
)
|
|
418
|
-
all_taxa_fs = frozenset(all_taxa)
|
|
490
|
+
species_taxa = set(t.name for t in species_tree.get_terminals())
|
|
491
|
+
gene_taxa = self._collect_taxa(gene_trees)
|
|
492
|
+
all_taxa_fs = frozenset(sorted(species_taxa & gene_taxa))
|
|
419
493
|
parent_map = self._build_parent_map(species_tree)
|
|
420
494
|
|
|
421
495
|
# Extract bipartitions from all gene trees (topology only, no lengths).
|
|
422
|
-
#
|
|
496
|
+
# Builds tip sets bottom-up in a single postorder pass per gene tree,
|
|
497
|
+
# avoiding repeated get_terminals() calls (O(n) vs O(n²) per tree).
|
|
423
498
|
gene_tree_splits = []
|
|
424
499
|
for gt in gene_trees:
|
|
425
|
-
splits =
|
|
426
|
-
for clade in gt.get_nonterminals():
|
|
427
|
-
tips = frozenset(
|
|
428
|
-
t.name for t in clade.get_terminals()
|
|
429
|
-
if t.name in all_taxa_fs
|
|
430
|
-
)
|
|
431
|
-
if len(tips) <= 1 or tips == all_taxa_fs:
|
|
432
|
-
continue
|
|
433
|
-
splits.add(self._canonical_split(tips, all_taxa_fs))
|
|
500
|
+
splits = self._extract_splits(gt, all_taxa_fs)
|
|
434
501
|
gene_tree_splits.append(splits)
|
|
435
502
|
|
|
436
503
|
result = {}
|
|
@@ -452,7 +519,7 @@ class DiscordanceAsymmetry(Tree):
|
|
|
452
519
|
n_alt1 = sum(1 for splits in gene_tree_splits if nni_alt1_bp in splits)
|
|
453
520
|
n_alt2 = sum(1 for splits in gene_tree_splits if nni_alt2_bp in splits)
|
|
454
521
|
|
|
455
|
-
node_tips = frozenset(t.name for t in clade.get_terminals())
|
|
522
|
+
node_tips = frozenset(t.name for t in clade.get_terminals()) & all_taxa_fs
|
|
456
523
|
split_label = (
|
|
457
524
|
sorted(node_tips)
|
|
458
525
|
if len(node_tips) <= len(all_taxa_fs) - len(node_tips)
|
|
@@ -465,7 +532,7 @@ class DiscordanceAsymmetry(Tree):
|
|
|
465
532
|
n_alt1=n_alt1,
|
|
466
533
|
n_alt2=n_alt2,
|
|
467
534
|
)
|
|
468
|
-
return result
|
|
535
|
+
return result, all_taxa_fs
|
|
469
536
|
|
|
470
537
|
# ------------------------------------------------------------------
|
|
471
538
|
# Statistical testing
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "2.1.34"
|
phykit-2.1.32/phykit/version.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "2.1.32"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|