phylogenie 3.1.8__py3-none-any.whl → 3.1.10__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/draw.py CHANGED
@@ -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
- ys: dict[Tree, float] = {node: i for i, node in enumerate(tree.get_leaves())}
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
- ys[node] = sum(ys[child] for child in node.children) / len(node.children)
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(y=ys[tree], xmin=xmin, xmax=xs[tree], color=colors[tree]) # pyright: ignore
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()
@@ -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(tree=tree, ax=ax, colors=colors, backward_time=backward_time)
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, calibration_nodes=calibration_nodes, ax=ax, colors=colors
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
- show_hist: Literal[True],
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, ax=ax, colors=colors, backward_time=backward_time
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(tree=tree, ax=ax, colors=colors, backward_time=backward_time)
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, extract_time_from_id: Callable[[str], float] | None = None
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(id.split("|")[-1])
24
+ time = float(last_metadata)
22
25
  except ValueError:
23
- pass
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.8
3
+ Version: 3.1.10
4
4
  Summary: Generate phylogenetic datasets with minimal setup effort
5
5
  Requires-Python: >=3.10
6
6
  Description-Content-Type: text/markdown
@@ -1,8 +1,8 @@
1
1
  phylogenie/__init__.py,sha256=redo-SdvWwQPlyqOfdSW0TkkZf-aP98kLRCUIg4pB8c,3304
2
- phylogenie/draw.py,sha256=J_ijON8O848f-r2VnOu8MbSR_vAcvO8zPq5u5Vq5J_U,23323
2
+ phylogenie/draw.py,sha256=ZZvOQrmW_X9wUiOl5h2nvNBVX7BFH014EJ7evEI2orA,26840
3
3
  phylogenie/main.py,sha256=ry3B3HiwibZG3_qB58T5UhWy5dp6neYUtSqzL9LrSkA,1698
4
4
  phylogenie/mixins.py,sha256=wMwqP6zkqME9eMyzx5FS6-p9X8yW09jIC8jge8pHlkk,907
5
- phylogenie/msa.py,sha256=JDGyZUsAq6-m-SQjoCDjAkAZIxfgyl_PDIhdYn5HOow,2064
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=kx9uVATLpzpXdhhNNMvMpB5Vdwh9CTWepTGachvEwV4,1154
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.8.dist-info/licenses/LICENSE.txt,sha256=NUrDqElK-eD3I0WqC004CJsy6cs0JgsAoebDv_42-pw,1071
37
- phylogenie-3.1.8.dist-info/METADATA,sha256=0lQMRPORgVWh0cp4OYt1RjCkYtCdy2P3ugiBmqB2oHQ,5194
38
- phylogenie-3.1.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
39
- phylogenie-3.1.8.dist-info/entry_points.txt,sha256=BBH8LoReHnNFnvq4sROEsVFegfkKJ6c_oHZ7bgK7Jl4,52
40
- phylogenie-3.1.8.dist-info/top_level.txt,sha256=1YGZJhKA9tN9qI0Hcj6Cn_sOoDpba0HQlNcgQTjMD-8,11
41
- phylogenie-3.1.8.dist-info/RECORD,,
36
+ phylogenie-3.1.10.dist-info/licenses/LICENSE.txt,sha256=NUrDqElK-eD3I0WqC004CJsy6cs0JgsAoebDv_42-pw,1071
37
+ phylogenie-3.1.10.dist-info/METADATA,sha256=sdHbD8Gx14dS0TkKkN9dpmZkTKgt0ib__qtTX2noIo0,5195
38
+ phylogenie-3.1.10.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
39
+ phylogenie-3.1.10.dist-info/entry_points.txt,sha256=BBH8LoReHnNFnvq4sROEsVFegfkKJ6c_oHZ7bgK7Jl4,52
40
+ phylogenie-3.1.10.dist-info/top_level.txt,sha256=1YGZJhKA9tN9qI0Hcj6Cn_sOoDpba0HQlNcgQTjMD-8,11
41
+ phylogenie-3.1.10.dist-info/RECORD,,