phylogenie 3.1.8__py3-none-any.whl → 3.1.11__py3-none-any.whl
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.
- phylogenie/__init__.py +0 -14
- phylogenie/draw.py +104 -20
- phylogenie/io/fasta.py +9 -3
- phylogenie/msa.py +4 -3
- {phylogenie-3.1.8.dist-info → phylogenie-3.1.11.dist-info}/METADATA +5 -6
- {phylogenie-3.1.8.dist-info → phylogenie-3.1.11.dist-info}/RECORD +10 -10
- {phylogenie-3.1.8.dist-info → phylogenie-3.1.11.dist-info}/WHEEL +0 -0
- {phylogenie-3.1.8.dist-info → phylogenie-3.1.11.dist-info}/entry_points.txt +0 -0
- {phylogenie-3.1.8.dist-info → phylogenie-3.1.11.dist-info}/licenses/LICENSE.txt +0 -0
- {phylogenie-3.1.8.dist-info → phylogenie-3.1.11.dist-info}/top_level.txt +0 -0
phylogenie/__init__.py
CHANGED
|
@@ -1,11 +1,3 @@
|
|
|
1
|
-
from phylogenie.draw import (
|
|
2
|
-
draw_colored_dated_tree_categorical,
|
|
3
|
-
draw_colored_dated_tree_continuous,
|
|
4
|
-
draw_colored_tree_categorical,
|
|
5
|
-
draw_colored_tree_continuous,
|
|
6
|
-
draw_dated_tree,
|
|
7
|
-
draw_tree,
|
|
8
|
-
)
|
|
9
1
|
from phylogenie.generators import (
|
|
10
2
|
AliSimDatasetGenerator,
|
|
11
3
|
BDEITreeDatasetGenerator,
|
|
@@ -71,12 +63,6 @@ from phylogenie.treesimulator import (
|
|
|
71
63
|
)
|
|
72
64
|
|
|
73
65
|
__all__ = [
|
|
74
|
-
"draw_colored_dated_tree_categorical",
|
|
75
|
-
"draw_colored_dated_tree_continuous",
|
|
76
|
-
"draw_colored_tree_categorical",
|
|
77
|
-
"draw_colored_tree_continuous",
|
|
78
|
-
"draw_dated_tree",
|
|
79
|
-
"draw_tree",
|
|
80
66
|
"AliSimDatasetGenerator",
|
|
81
67
|
"BDEITreeDatasetGenerator",
|
|
82
68
|
"BDSSTreeDatasetGenerator",
|
phylogenie/draw.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import datetime
|
|
1
2
|
from dataclasses import dataclass
|
|
2
|
-
from datetime import datetime
|
|
3
3
|
from typing import Any, Literal, overload
|
|
4
4
|
|
|
5
5
|
import matplotlib.colors as mcolors
|
|
@@ -21,7 +21,7 @@ from phylogenie.treesimulator import (
|
|
|
21
21
|
@dataclass
|
|
22
22
|
class CalibrationNode:
|
|
23
23
|
node: Tree
|
|
24
|
-
date: datetime
|
|
24
|
+
date: datetime.date
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
Color = str | tuple[float, float, float] | tuple[float, float, float, float]
|
|
@@ -32,6 +32,8 @@ def draw_tree(
|
|
|
32
32
|
ax: Axes | None = None,
|
|
33
33
|
colors: Color | dict[Tree, Color] = "black",
|
|
34
34
|
backward_time: bool = False,
|
|
35
|
+
branch_kwargs: dict[str, Any] | None = None,
|
|
36
|
+
sampled_ancestor_kwargs: dict[str, Any] | None = None,
|
|
35
37
|
) -> Axes:
|
|
36
38
|
"""
|
|
37
39
|
Draw a phylogenetic tree with colored branches.
|
|
@@ -46,6 +48,10 @@ def draw_tree(
|
|
|
46
48
|
A single color for all branches or a dictionary mapping each node to a color.
|
|
47
49
|
backward_time : bool, optional
|
|
48
50
|
If True, the x-axis is inverted to represent time going backward.
|
|
51
|
+
branch_kwargs : dict[str, Any] | None, optional
|
|
52
|
+
Additional keyword arguments to pass to the branch drawing functions.
|
|
53
|
+
sampled_ancestor_kwargs : dict[str, Any] | None, optional
|
|
54
|
+
Additional keyword arguments to highlight sampled ancestors.
|
|
49
55
|
|
|
50
56
|
Returns
|
|
51
57
|
-------
|
|
@@ -54,6 +60,12 @@ def draw_tree(
|
|
|
54
60
|
"""
|
|
55
61
|
if ax is None:
|
|
56
62
|
ax = plt.gca()
|
|
63
|
+
if branch_kwargs is None:
|
|
64
|
+
branch_kwargs = {}
|
|
65
|
+
if sampled_ancestor_kwargs is None:
|
|
66
|
+
sampled_ancestor_kwargs = {}
|
|
67
|
+
if "marker" not in sampled_ancestor_kwargs:
|
|
68
|
+
sampled_ancestor_kwargs["marker"] = "o"
|
|
57
69
|
|
|
58
70
|
if not isinstance(colors, dict):
|
|
59
71
|
colors = {node: colors for node in tree}
|
|
@@ -66,20 +78,33 @@ def draw_tree(
|
|
|
66
78
|
else get_node_depths(tree)
|
|
67
79
|
)
|
|
68
80
|
|
|
69
|
-
|
|
81
|
+
leaves = tree.get_leaves()
|
|
82
|
+
ys: dict[Tree, float] = {
|
|
83
|
+
node: i
|
|
84
|
+
for i, node in enumerate(leaves)
|
|
85
|
+
if node.parent is None or node.branch_length != 0
|
|
86
|
+
}
|
|
70
87
|
for node in tree.postorder_traversal():
|
|
71
88
|
if node.is_internal():
|
|
72
|
-
|
|
89
|
+
children = [child for child in node.children if child.branch_length != 0]
|
|
90
|
+
ys[node] = sum(ys[child] for child in children) / len(children)
|
|
91
|
+
for leaf in leaves:
|
|
92
|
+
if leaf.parent is not None and leaf.branch_length == 0:
|
|
93
|
+
ys[leaf] = ys[leaf.parent]
|
|
73
94
|
|
|
74
95
|
if tree.branch_length is not None:
|
|
75
96
|
xmin = xs[tree] + tree.branch_length if backward_time else 0
|
|
76
|
-
ax.hlines(
|
|
97
|
+
ax.hlines( # pyright: ignore
|
|
98
|
+
y=ys[tree], xmin=xmin, xmax=xs[tree], color=colors[tree], **branch_kwargs
|
|
99
|
+
)
|
|
77
100
|
for node in tree:
|
|
78
101
|
x1, y1 = xs[node], ys[node]
|
|
102
|
+
if node.parent is not None and node.branch_length == 0:
|
|
103
|
+
ax.plot(x1, y1, color=colors[node], **sampled_ancestor_kwargs) # pyright: ignore
|
|
79
104
|
for child in node.children:
|
|
80
105
|
x2, y2 = xs[child], ys[child]
|
|
81
|
-
ax.hlines(y=y2, xmin=x1, xmax=x2, color=colors[child]) # pyright: ignore
|
|
82
|
-
ax.vlines(x=x1, ymin=y1, ymax=y2, color=colors[child]) # pyright: ignore
|
|
106
|
+
ax.hlines(y=y2, xmin=x1, xmax=x2, color=colors[child], **branch_kwargs) # pyright: ignore
|
|
107
|
+
ax.vlines(x=x1, ymin=y1, ymax=y2, color=colors[child], **branch_kwargs) # pyright: ignore
|
|
83
108
|
|
|
84
109
|
if backward_time:
|
|
85
110
|
ax.invert_xaxis()
|
|
@@ -90,7 +115,7 @@ def draw_tree(
|
|
|
90
115
|
|
|
91
116
|
def _depth_to_date(
|
|
92
117
|
depth: float, calibration_nodes: tuple[CalibrationNode, CalibrationNode]
|
|
93
|
-
) -> datetime:
|
|
118
|
+
) -> datetime.date:
|
|
94
119
|
"""
|
|
95
120
|
Convert a depth value to a date using linear interpolation between two calibration nodes.
|
|
96
121
|
|
|
@@ -103,7 +128,7 @@ def _depth_to_date(
|
|
|
103
128
|
|
|
104
129
|
Returns
|
|
105
130
|
-------
|
|
106
|
-
datetime
|
|
131
|
+
datetime.date
|
|
107
132
|
The interpolated date corresponding to the given depth.
|
|
108
133
|
"""
|
|
109
134
|
node1, node2 = calibration_nodes
|
|
@@ -117,6 +142,7 @@ def draw_dated_tree(
|
|
|
117
142
|
calibration_nodes: tuple[CalibrationNode, CalibrationNode],
|
|
118
143
|
ax: Axes | None = None,
|
|
119
144
|
colors: Color | dict[Tree, Color] = "black",
|
|
145
|
+
branch_kwargs: dict[str, Any] | None = None,
|
|
120
146
|
) -> Axes:
|
|
121
147
|
"""
|
|
122
148
|
Draw a phylogenetic tree with branches positioned according to calibrated dates.
|
|
@@ -131,6 +157,8 @@ def draw_dated_tree(
|
|
|
131
157
|
The matplotlib Axes to draw on. If None, uses the current Axes.
|
|
132
158
|
colors : Color | dict[Tree, Color], optional
|
|
133
159
|
A single color for all branches or a dictionary mapping each node to a color.
|
|
160
|
+
branch_kwargs : dict[str, Any] | None, optional
|
|
161
|
+
Additional keyword arguments to pass to the branch drawing functions.
|
|
134
162
|
|
|
135
163
|
Returns
|
|
136
164
|
-------
|
|
@@ -139,6 +167,8 @@ def draw_dated_tree(
|
|
|
139
167
|
"""
|
|
140
168
|
if ax is None:
|
|
141
169
|
ax = plt.gca()
|
|
170
|
+
if branch_kwargs is None:
|
|
171
|
+
branch_kwargs = {}
|
|
142
172
|
|
|
143
173
|
if not isinstance(colors, dict):
|
|
144
174
|
colors = {node: colors for node in tree}
|
|
@@ -160,6 +190,7 @@ def draw_dated_tree(
|
|
|
160
190
|
xmin=mdates.date2num(origin_date), # pyright: ignore
|
|
161
191
|
xmax=mdates.date2num(xs[tree]), # pyright: ignore
|
|
162
192
|
color=colors[tree],
|
|
193
|
+
**branch_kwargs,
|
|
163
194
|
)
|
|
164
195
|
for node in tree:
|
|
165
196
|
x1, y1 = xs[node], ys[node]
|
|
@@ -170,8 +201,15 @@ def draw_dated_tree(
|
|
|
170
201
|
xmin=mdates.date2num(x1), # pyright: ignore
|
|
171
202
|
xmax=mdates.date2num(x2), # pyright: ignore
|
|
172
203
|
color=colors[child],
|
|
204
|
+
**branch_kwargs,
|
|
205
|
+
)
|
|
206
|
+
ax.vlines( # pyright: ignore
|
|
207
|
+
x=mdates.date2num(x1), # pyright: ignore
|
|
208
|
+
ymin=y1,
|
|
209
|
+
ymax=y2,
|
|
210
|
+
color=colors[child],
|
|
211
|
+
**branch_kwargs,
|
|
173
212
|
)
|
|
174
|
-
ax.vlines(x=mdates.date2num(x1), ymin=y1, ymax=y2, color=colors[child]) # pyright: ignore
|
|
175
213
|
|
|
176
214
|
ax.xaxis.set_major_locator(mdates.AutoDateLocator())
|
|
177
215
|
ax.xaxis.set_major_formatter(mdates.DateFormatter("%Y-%m-%d"))
|
|
@@ -260,6 +298,8 @@ def draw_colored_tree_categorical(
|
|
|
260
298
|
show_legend: bool = True,
|
|
261
299
|
labels: dict[Any, str] | None = None,
|
|
262
300
|
legend_kwargs: dict[str, Any] | None = None,
|
|
301
|
+
branch_kwargs: dict[str, Any] | None = None,
|
|
302
|
+
sampled_ancestor_kwargs: dict[str, Any] | None = None,
|
|
263
303
|
):
|
|
264
304
|
"""
|
|
265
305
|
Draw a phylogenetic tree with branches colored based on categorical metadata.
|
|
@@ -284,6 +324,10 @@ def draw_colored_tree_categorical(
|
|
|
284
324
|
A mapping from category values to labels for the legend.
|
|
285
325
|
legend_kwargs : dict[str, Any] | None, optional
|
|
286
326
|
Additional keyword arguments to pass to the legend.
|
|
327
|
+
branch_kwargs : dict[str, Any] | None, optional
|
|
328
|
+
Additional keyword arguments to pass to the branch drawing functions.
|
|
329
|
+
sampled_ancestor_kwargs : dict[str, Any] | None, optional
|
|
330
|
+
Additional keyword arguments to highlight sampled ancestors.
|
|
287
331
|
|
|
288
332
|
Returns
|
|
289
333
|
-------
|
|
@@ -300,7 +344,14 @@ def draw_colored_tree_categorical(
|
|
|
300
344
|
labels=labels,
|
|
301
345
|
legend_kwargs=legend_kwargs,
|
|
302
346
|
)
|
|
303
|
-
return draw_tree(
|
|
347
|
+
return draw_tree(
|
|
348
|
+
tree=tree,
|
|
349
|
+
ax=ax,
|
|
350
|
+
colors=colors,
|
|
351
|
+
backward_time=backward_time,
|
|
352
|
+
branch_kwargs=branch_kwargs,
|
|
353
|
+
sampled_ancestor_kwargs=sampled_ancestor_kwargs,
|
|
354
|
+
)
|
|
304
355
|
|
|
305
356
|
|
|
306
357
|
def draw_colored_dated_tree_categorical(
|
|
@@ -313,6 +364,7 @@ def draw_colored_dated_tree_categorical(
|
|
|
313
364
|
show_legend: bool = True,
|
|
314
365
|
labels: dict[Any, str] | None = None,
|
|
315
366
|
legend_kwargs: dict[str, Any] | None = None,
|
|
367
|
+
branch_kwargs: dict[str, Any] | None = None,
|
|
316
368
|
) -> Axes:
|
|
317
369
|
"""
|
|
318
370
|
Draw a dated phylogenetic tree with branches colored based on categorical metadata.
|
|
@@ -337,6 +389,8 @@ def draw_colored_dated_tree_categorical(
|
|
|
337
389
|
A mapping from category values to labels for the legend.
|
|
338
390
|
legend_kwargs : dict[str, Any] | None, optional
|
|
339
391
|
Additional keyword arguments to pass to the legend.
|
|
392
|
+
branch_kwargs : dict[str, Any] | None, optional
|
|
393
|
+
Additional keyword arguments to pass to the branch drawing functions.
|
|
340
394
|
|
|
341
395
|
Returns
|
|
342
396
|
-------
|
|
@@ -354,7 +408,11 @@ def draw_colored_dated_tree_categorical(
|
|
|
354
408
|
legend_kwargs=legend_kwargs,
|
|
355
409
|
)
|
|
356
410
|
return draw_dated_tree(
|
|
357
|
-
tree=tree,
|
|
411
|
+
tree=tree,
|
|
412
|
+
calibration_nodes=calibration_nodes,
|
|
413
|
+
ax=ax,
|
|
414
|
+
colors=colors,
|
|
415
|
+
branch_kwargs=branch_kwargs,
|
|
358
416
|
)
|
|
359
417
|
|
|
360
418
|
|
|
@@ -382,7 +440,7 @@ def _init_colored_tree_continuous(
|
|
|
382
440
|
vmin: float | None = ...,
|
|
383
441
|
vmax: float | None = ...,
|
|
384
442
|
*,
|
|
385
|
-
show_hist: Literal[True],
|
|
443
|
+
show_hist: Literal[True] = True,
|
|
386
444
|
hist_kwargs: dict[str, Any] | None = ...,
|
|
387
445
|
hist_axes_kwargs: dict[str, Any] | None = ...,
|
|
388
446
|
) -> tuple[Axes, dict[Tree, Color], Axes]: ...
|
|
@@ -394,7 +452,6 @@ def _init_colored_tree_continuous(
|
|
|
394
452
|
colormap: str | Colormap = "viridis",
|
|
395
453
|
vmin: float | None = None,
|
|
396
454
|
vmax: float | None = None,
|
|
397
|
-
*,
|
|
398
455
|
show_hist: bool = True,
|
|
399
456
|
hist_kwargs: dict[str, Any] | None = None,
|
|
400
457
|
hist_axes_kwargs: dict[str, Any] | None = None,
|
|
@@ -478,6 +535,8 @@ def draw_colored_tree_continuous(
|
|
|
478
535
|
colormap: str | Colormap = "viridis",
|
|
479
536
|
vmin: float | None = None,
|
|
480
537
|
vmax: float | None = None,
|
|
538
|
+
branch_kwargs: dict[str, Any] | None = None,
|
|
539
|
+
sampled_ancestor_kwargs: dict[str, Any] | None = None,
|
|
481
540
|
*,
|
|
482
541
|
show_hist: Literal[False],
|
|
483
542
|
hist_kwargs: dict[str, Any] | None = None,
|
|
@@ -493,8 +552,9 @@ def draw_colored_tree_continuous(
|
|
|
493
552
|
colormap: str | Colormap = "viridis",
|
|
494
553
|
vmin: float | None = None,
|
|
495
554
|
vmax: float | None = None,
|
|
496
|
-
|
|
497
|
-
|
|
555
|
+
branch_kwargs: dict[str, Any] | None = None,
|
|
556
|
+
sampled_ancestor_kwargs: dict[str, Any] | None = None,
|
|
557
|
+
show_hist: Literal[True] = True,
|
|
498
558
|
hist_kwargs: dict[str, Any] | None = None,
|
|
499
559
|
hist_axes_kwargs: dict[str, Any] | None = None,
|
|
500
560
|
) -> tuple[Axes, Axes]: ...
|
|
@@ -507,6 +567,8 @@ def draw_colored_tree_continuous(
|
|
|
507
567
|
colormap: str | Colormap = "viridis",
|
|
508
568
|
vmin: float | None = None,
|
|
509
569
|
vmax: float | None = None,
|
|
570
|
+
branch_kwargs: dict[str, Any] | None = None,
|
|
571
|
+
sampled_ancestor_kwargs: dict[str, Any] | None = None,
|
|
510
572
|
show_hist: bool = True,
|
|
511
573
|
hist_kwargs: dict[str, Any] | None = None,
|
|
512
574
|
hist_axes_kwargs: dict[str, Any] | None = None,
|
|
@@ -532,6 +594,10 @@ def draw_colored_tree_continuous(
|
|
|
532
594
|
The minimum value for normalization. If None, uses the minimum of the data.
|
|
533
595
|
vmax : float | None, optional
|
|
534
596
|
The maximum value for normalization. If None, uses the maximum of the data.
|
|
597
|
+
branch_kwargs : dict[str, Any] | None, optional
|
|
598
|
+
Additional keyword arguments to pass to the branch drawing functions.
|
|
599
|
+
sampled_ancestor_kwargs : dict[str, Any] | None, optional
|
|
600
|
+
Additional keyword arguments to highlight sampled ancestors.
|
|
535
601
|
show_hist : bool, optional
|
|
536
602
|
Whether to display a histogram of the continuous values.
|
|
537
603
|
hist_kwargs : dict[str, Any] | None, optional
|
|
@@ -559,7 +625,12 @@ def draw_colored_tree_continuous(
|
|
|
559
625
|
hist_axes_kwargs=hist_axes_kwargs,
|
|
560
626
|
)
|
|
561
627
|
return draw_tree(
|
|
562
|
-
tree=tree,
|
|
628
|
+
tree=tree,
|
|
629
|
+
ax=ax,
|
|
630
|
+
colors=colors,
|
|
631
|
+
backward_time=backward_time,
|
|
632
|
+
branch_kwargs=branch_kwargs,
|
|
633
|
+
sampled_ancestor_kwargs=sampled_ancestor_kwargs,
|
|
563
634
|
), hist_ax
|
|
564
635
|
|
|
565
636
|
ax, colors = _init_colored_tree_continuous(
|
|
@@ -574,7 +645,14 @@ def draw_colored_tree_continuous(
|
|
|
574
645
|
hist_kwargs=hist_kwargs,
|
|
575
646
|
hist_axes_kwargs=hist_axes_kwargs,
|
|
576
647
|
)
|
|
577
|
-
return draw_tree(
|
|
648
|
+
return draw_tree(
|
|
649
|
+
tree=tree,
|
|
650
|
+
ax=ax,
|
|
651
|
+
colors=colors,
|
|
652
|
+
backward_time=backward_time,
|
|
653
|
+
branch_kwargs=branch_kwargs,
|
|
654
|
+
sampled_ancestor_kwargs=sampled_ancestor_kwargs,
|
|
655
|
+
)
|
|
578
656
|
|
|
579
657
|
|
|
580
658
|
@overload
|
|
@@ -587,6 +665,7 @@ def draw_colored_dated_tree_continuous(
|
|
|
587
665
|
colormap: str | Colormap = "viridis",
|
|
588
666
|
vmin: float | None = None,
|
|
589
667
|
vmax: float | None = None,
|
|
668
|
+
branch_kwargs: dict[str, Any] | None = None,
|
|
590
669
|
*,
|
|
591
670
|
show_hist: Literal[False],
|
|
592
671
|
hist_kwargs: dict[str, Any] | None = None,
|
|
@@ -602,8 +681,8 @@ def draw_colored_dated_tree_continuous(
|
|
|
602
681
|
colormap: str | Colormap = "viridis",
|
|
603
682
|
vmin: float | None = None,
|
|
604
683
|
vmax: float | None = None,
|
|
605
|
-
|
|
606
|
-
show_hist: Literal[True],
|
|
684
|
+
branch_kwargs: dict[str, Any] | None = None,
|
|
685
|
+
show_hist: Literal[True] = True,
|
|
607
686
|
hist_kwargs: dict[str, Any] | None = None,
|
|
608
687
|
hist_axes_kwargs: dict[str, Any] | None = None,
|
|
609
688
|
) -> tuple[Axes, Axes]: ...
|
|
@@ -616,6 +695,7 @@ def draw_colored_dated_tree_continuous(
|
|
|
616
695
|
colormap: str | Colormap = "viridis",
|
|
617
696
|
vmin: float | None = None,
|
|
618
697
|
vmax: float | None = None,
|
|
698
|
+
branch_kwargs: dict[str, Any] | None = None,
|
|
619
699
|
show_hist: bool = True,
|
|
620
700
|
hist_kwargs: dict[str, Any] | None = None,
|
|
621
701
|
hist_axes_kwargs: dict[str, Any] | None = None,
|
|
@@ -641,6 +721,8 @@ def draw_colored_dated_tree_continuous(
|
|
|
641
721
|
The minimum value for normalization. If None, uses the minimum of the data.
|
|
642
722
|
vmax : float | None, optional
|
|
643
723
|
The maximum value for normalization. If None, uses the maximum of the data.
|
|
724
|
+
branch_kwargs : dict[str, Any] | None, optional
|
|
725
|
+
Additional keyword arguments to pass to the branch drawing functions.
|
|
644
726
|
show_hist : bool, optional
|
|
645
727
|
Whether to display a histogram of the continuous values.
|
|
646
728
|
hist_kwargs : dict[str, Any] | None, optional
|
|
@@ -672,6 +754,7 @@ def draw_colored_dated_tree_continuous(
|
|
|
672
754
|
calibration_nodes=calibration_nodes,
|
|
673
755
|
ax=ax,
|
|
674
756
|
colors=colors,
|
|
757
|
+
branch_kwargs=branch_kwargs,
|
|
675
758
|
), hist_ax
|
|
676
759
|
|
|
677
760
|
ax, colors = _init_colored_tree_continuous(
|
|
@@ -691,4 +774,5 @@ def draw_colored_dated_tree_continuous(
|
|
|
691
774
|
calibration_nodes=calibration_nodes,
|
|
692
775
|
ax=ax,
|
|
693
776
|
colors=colors,
|
|
777
|
+
branch_kwargs=branch_kwargs,
|
|
694
778
|
)
|
phylogenie/io/fasta.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from datetime import date
|
|
1
2
|
from pathlib import Path
|
|
2
3
|
from typing import Callable
|
|
3
4
|
|
|
@@ -5,7 +6,8 @@ from phylogenie.msa import MSA, Sequence
|
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
def load_fasta(
|
|
8
|
-
fasta_file: str | Path,
|
|
9
|
+
fasta_file: str | Path,
|
|
10
|
+
extract_time_from_id: Callable[[str], float | date] | None = None,
|
|
9
11
|
) -> MSA:
|
|
10
12
|
sequences: list[Sequence] = []
|
|
11
13
|
with open(fasta_file, "r") as f:
|
|
@@ -17,10 +19,14 @@ def load_fasta(
|
|
|
17
19
|
if extract_time_from_id is not None:
|
|
18
20
|
time = extract_time_from_id(id)
|
|
19
21
|
elif "|" in id:
|
|
22
|
+
last_metadata = id.split("|")[-1]
|
|
20
23
|
try:
|
|
21
|
-
time = float(
|
|
24
|
+
time = float(last_metadata)
|
|
22
25
|
except ValueError:
|
|
23
|
-
|
|
26
|
+
try:
|
|
27
|
+
time = date.fromisoformat(last_metadata)
|
|
28
|
+
except ValueError:
|
|
29
|
+
pass
|
|
24
30
|
chars = next(f).strip()
|
|
25
31
|
sequences.append(Sequence(id, chars, time))
|
|
26
32
|
return MSA(sequences)
|
phylogenie/msa.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from collections.abc import Iterator
|
|
2
2
|
from dataclasses import dataclass
|
|
3
|
+
from datetime import date
|
|
3
4
|
|
|
4
5
|
import numpy as np
|
|
5
6
|
|
|
@@ -8,7 +9,7 @@ import numpy as np
|
|
|
8
9
|
class Sequence:
|
|
9
10
|
id: str
|
|
10
11
|
chars: str
|
|
11
|
-
time: float | None = None
|
|
12
|
+
time: float | date | None = None
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
class MSA:
|
|
@@ -25,8 +26,8 @@ class MSA:
|
|
|
25
26
|
return [sequence.id for sequence in self.sequences]
|
|
26
27
|
|
|
27
28
|
@property
|
|
28
|
-
def times(self) -> list[float]:
|
|
29
|
-
times: list[float] = []
|
|
29
|
+
def times(self) -> list[float | date]:
|
|
30
|
+
times: list[float | date] = []
|
|
30
31
|
for sequence in self:
|
|
31
32
|
if sequence.time is None:
|
|
32
33
|
raise ValueError(f"Time is not set for sequence {sequence.id}.")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: phylogenie
|
|
3
|
-
Version: 3.1.
|
|
3
|
+
Version: 3.1.11
|
|
4
4
|
Summary: Generate phylogenetic datasets with minimal setup effort
|
|
5
5
|
Requires-Python: >=3.10
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
@@ -23,7 +23,6 @@ Dynamic: license-file
|
|
|
23
23
|
[](https://pypi.org/project/phylogenie/)
|
|
24
24
|

|
|
25
25
|
|
|
26
|
-
|
|
27
26
|
Phylogenie is a [Python](https://www.python.org/) package designed to easily simulate phylogenetic datasets—such as trees and multiple sequence alignments (MSAs)—with minimal setup effort. Simply specify the distributions from which your parameters should be sampled, and Phylogenie will handle the rest!
|
|
28
27
|
|
|
29
28
|
## ✨ Features
|
|
@@ -73,21 +72,21 @@ Phylogenie relies on [AliSim](https://iqtree.github.io/doc/AliSim) for simulatin
|
|
|
73
72
|
|
|
74
73
|
## 🚀 Quick Start
|
|
75
74
|
|
|
76
|
-
Once you have installed Phylogenie, check out the [
|
|
75
|
+
Once you have installed Phylogenie, check out the [tutorials](https://github.com/gabriele-marino/phylogenie/tree/main/tutorials) folder.
|
|
77
76
|
It includes a collection of thoroughly commented configuration files, organized as a step-by-step tutorial. These examples will help you understand how to use Phylogenie in practice and can be easily adapted to fit your own workflow.
|
|
78
77
|
|
|
79
78
|
For quick start, pick your favorite config file and run Phylogenie with:
|
|
80
79
|
```bash
|
|
81
|
-
phylogenie
|
|
80
|
+
phylogenie tutorials/config_file.yaml
|
|
82
81
|
```
|
|
83
82
|
This command will create the output dataset in the folder specified inside the configuration file, including data directories and metadata files for each dataset split defined in the config.
|
|
84
83
|
|
|
85
84
|
>❗ *Tip*: Can’t choose just one config file?
|
|
86
|
-
You can run them all at once by pointing Phylogenie to the folder! Just use: `phylogenie
|
|
85
|
+
You can run them all at once by pointing Phylogenie to the folder! Just use: `phylogenie tutorials`. In this mode, Phylogenie will automatically find all `.yaml` files in the folder you specified and run for each of them!
|
|
87
86
|
|
|
88
87
|
## 📖 Documentation
|
|
89
88
|
|
|
90
|
-
- The [
|
|
89
|
+
- The [tutorials](https://github.com/gabriele-marino/phylogenie/tree/main/tutorials) folder contains many ready-to-use, extensively commented configuration files that serve as a step-by-step tutorial to guide you through using Phylogenie. You can explore them to learn how it works or adapt them directly to your own workflows.
|
|
91
90
|
- A complete user guide and API reference are under development. In the meantime, feel free to [reach out](mailto:gabmarino.8601@email.com) if you have any questions about integrating Phylogenie into your workflows.
|
|
92
91
|
|
|
93
92
|
## 📄 License
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
phylogenie/__init__.py,sha256=
|
|
2
|
-
phylogenie/draw.py,sha256
|
|
1
|
+
phylogenie/__init__.py,sha256=RyH_mcEXcKtELTkl9HRzWcl2ANWN-G4K0BLigqR3_B4,2888
|
|
2
|
+
phylogenie/draw.py,sha256=-hyycRN4RyG0nzZrE4CC4bmg0PgxJOeK67rwlmFZiuc,26841
|
|
3
3
|
phylogenie/main.py,sha256=ry3B3HiwibZG3_qB58T5UhWy5dp6neYUtSqzL9LrSkA,1698
|
|
4
4
|
phylogenie/mixins.py,sha256=wMwqP6zkqME9eMyzx5FS6-p9X8yW09jIC8jge8pHlkk,907
|
|
5
|
-
phylogenie/msa.py,sha256=
|
|
5
|
+
phylogenie/msa.py,sha256=RGXxmo1WX9wi5NpEQTxMuH4zk8vM0f8A7Knm0YUJ9AI,2111
|
|
6
6
|
phylogenie/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
7
|
phylogenie/typeguards.py,sha256=JtqmbEWJZBRHbWgCvcl6nrWm3VcBfzRbklbTBYHItn0,1325
|
|
8
8
|
phylogenie/typings.py,sha256=p694PBe_tk25A6N8vGGWxuqoDtt3nHFUsIYJrwR_76Y,494
|
|
@@ -14,7 +14,7 @@ phylogenie/generators/factories.py,sha256=2mTFdFbbLyV3v79JaOEVtqLOmxQHaOUv1S-Y3v
|
|
|
14
14
|
phylogenie/generators/trees.py,sha256=8dO1CkU34E6mmMAHrYqiLV_VA8r54cSEOo-UzoHiN20,10467
|
|
15
15
|
phylogenie/generators/typeguards.py,sha256=yj4VkhOaUXJ2OrY-6zhOeY9C4yKIQxjZtk2d-vIxttQ,828
|
|
16
16
|
phylogenie/io/__init__.py,sha256=3v_bxv9RVeQ3KZzxNFeV9KLVxaC_Whf7rgWLnBKoEr0,95
|
|
17
|
-
phylogenie/io/fasta.py,sha256=
|
|
17
|
+
phylogenie/io/fasta.py,sha256=1Bjm_70fkqTA5rCsBY17iMW-lyW1smM-wjq3dl93sFc,1371
|
|
18
18
|
phylogenie/skyline/__init__.py,sha256=7pF4CUb4ZCLzNYJNhOjpuTOLTRhlK7L6ugfccNqjIGo,620
|
|
19
19
|
phylogenie/skyline/matrix.py,sha256=v4SitY7VbXprqlqQckjWTzW5hwRmCyIF595R6IJMxWw,9268
|
|
20
20
|
phylogenie/skyline/parameter.py,sha256=TVqkqirGXNN-VP8hnIJACPkOxUan6LkGa5o_JcPfwbY,4834
|
|
@@ -33,9 +33,9 @@ phylogenie/treesimulator/events/mutations.py,sha256=8Nqa2fg7fwaVNe5XSkGDSwp9pIKQ
|
|
|
33
33
|
phylogenie/treesimulator/io/__init__.py,sha256=rfP-zp8SP8baq5_4dPAr10WH0W6KfoMCxdTZDCSXtzE,185
|
|
34
34
|
phylogenie/treesimulator/io/newick.py,sha256=8Pr_jixByPOaVch18w-rFt62HYy0U97YMu0H-QSwIy0,3449
|
|
35
35
|
phylogenie/treesimulator/io/nexus.py,sha256=zqT9dzj413z_s0hqp3Cdq5NMO6lv-zuuaJlaqzaqaB8,1847
|
|
36
|
-
phylogenie-3.1.
|
|
37
|
-
phylogenie-3.1.
|
|
38
|
-
phylogenie-3.1.
|
|
39
|
-
phylogenie-3.1.
|
|
40
|
-
phylogenie-3.1.
|
|
41
|
-
phylogenie-3.1.
|
|
36
|
+
phylogenie-3.1.11.dist-info/licenses/LICENSE.txt,sha256=NUrDqElK-eD3I0WqC004CJsy6cs0JgsAoebDv_42-pw,1071
|
|
37
|
+
phylogenie-3.1.11.dist-info/METADATA,sha256=91J5lodQcF09WeD0Oq8ljaIVEWQzoYeXvb2VDbNtQ7U,5200
|
|
38
|
+
phylogenie-3.1.11.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
39
|
+
phylogenie-3.1.11.dist-info/entry_points.txt,sha256=BBH8LoReHnNFnvq4sROEsVFegfkKJ6c_oHZ7bgK7Jl4,52
|
|
40
|
+
phylogenie-3.1.11.dist-info/top_level.txt,sha256=1YGZJhKA9tN9qI0Hcj6Cn_sOoDpba0HQlNcgQTjMD-8,11
|
|
41
|
+
phylogenie-3.1.11.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|