phylogenie 1.0.7__py3-none-any.whl → 2.0.0__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.
Files changed (47) hide show
  1. phylogenie/generators/__init__.py +14 -0
  2. phylogenie/generators/alisim.py +71 -0
  3. phylogenie/generators/configs.py +41 -0
  4. phylogenie/{core → generators}/dataset.py +25 -23
  5. phylogenie/{core → generators}/factories.py +42 -52
  6. phylogenie/generators/trees.py +220 -0
  7. phylogenie/generators/typeguards.py +32 -0
  8. phylogenie/io.py +92 -0
  9. phylogenie/main.py +2 -2
  10. phylogenie/msa.py +72 -0
  11. phylogenie/skyline/matrix.py +62 -45
  12. phylogenie/skyline/vector.py +8 -6
  13. phylogenie/tree.py +53 -0
  14. phylogenie/treesimulator/__init__.py +21 -0
  15. phylogenie/treesimulator/events.py +256 -0
  16. phylogenie/treesimulator/gillespie.py +66 -0
  17. phylogenie/treesimulator/model.py +100 -0
  18. phylogenie/typings.py +0 -2
  19. {phylogenie-1.0.7.dist-info → phylogenie-2.0.0.dist-info}/METADATA +6 -18
  20. phylogenie-2.0.0.dist-info/RECORD +28 -0
  21. phylogenie/backend/__init__.py +0 -0
  22. phylogenie/backend/remaster/__init__.py +0 -21
  23. phylogenie/backend/remaster/generate.py +0 -187
  24. phylogenie/backend/remaster/reactions.py +0 -165
  25. phylogenie/backend/treesimulator.py +0 -163
  26. phylogenie/configs.py +0 -5
  27. phylogenie/core/__init__.py +0 -14
  28. phylogenie/core/configs.py +0 -37
  29. phylogenie/core/context/__init__.py +0 -4
  30. phylogenie/core/context/configs.py +0 -28
  31. phylogenie/core/context/distributions.py +0 -125
  32. phylogenie/core/context/factories.py +0 -54
  33. phylogenie/core/msas/__init__.py +0 -10
  34. phylogenie/core/msas/alisim.py +0 -35
  35. phylogenie/core/msas/base.py +0 -51
  36. phylogenie/core/trees/__init__.py +0 -11
  37. phylogenie/core/trees/base.py +0 -13
  38. phylogenie/core/trees/remaster/__init__.py +0 -3
  39. phylogenie/core/trees/remaster/configs.py +0 -14
  40. phylogenie/core/trees/remaster/factories.py +0 -26
  41. phylogenie/core/trees/remaster/generator.py +0 -177
  42. phylogenie/core/trees/treesimulator.py +0 -199
  43. phylogenie/core/typeguards.py +0 -32
  44. phylogenie-1.0.7.dist-info/RECORD +0 -39
  45. {phylogenie-1.0.7.dist-info → phylogenie-2.0.0.dist-info}/LICENSE.txt +0 -0
  46. {phylogenie-1.0.7.dist-info → phylogenie-2.0.0.dist-info}/WHEEL +0 -0
  47. {phylogenie-1.0.7.dist-info → phylogenie-2.0.0.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,256 @@
1
+ from abc import ABC, abstractmethod
2
+
3
+ from numpy.random import Generator
4
+
5
+ from phylogenie.skyline import (
6
+ SkylineMatrixCoercible,
7
+ SkylineParameterLike,
8
+ SkylineVectorCoercible,
9
+ skyline_matrix,
10
+ skyline_parameter,
11
+ skyline_vector,
12
+ )
13
+ from phylogenie.treesimulator.model import Model
14
+
15
+ INFECTIOUS_STATE = "I"
16
+ EXPOSED_STATE = "E"
17
+ SUPERSPREADER_STATE = "S"
18
+
19
+
20
+ class Event(ABC):
21
+ def __init__(
22
+ self,
23
+ rate: SkylineParameterLike,
24
+ state: str | None = None,
25
+ ):
26
+ self.rate = skyline_parameter(rate)
27
+ self.state = state
28
+
29
+ def get_propensity(self, model: Model, time: float) -> float:
30
+ return self.rate.get_value_at_time(time) * model.count_leaves(self.state)
31
+
32
+ @abstractmethod
33
+ def apply(self, rng: Generator, model: Model, time: float) -> None: ...
34
+
35
+
36
+ class BirthEvent(Event):
37
+ def __init__(
38
+ self,
39
+ rate: SkylineParameterLike,
40
+ state: str | None = None,
41
+ child_state: str | None = None,
42
+ ):
43
+ super().__init__(rate, state)
44
+ self.child_state = child_state
45
+
46
+ def apply(self, rng: Generator, model: Model, time: float) -> None:
47
+ node = model.get_random_leaf(self.state, rng)
48
+ model.add_child(node, time, True, self.child_state)
49
+
50
+
51
+ class DeathEvent(Event):
52
+ def apply(self, rng: Generator, model: Model, time: float) -> None:
53
+ node = model.get_random_leaf(self.state, rng)
54
+ model.remove(node)
55
+
56
+
57
+ class MigrationEvent(Event):
58
+ def __init__(self, state: str, target_state: str, rate: SkylineParameterLike):
59
+ super().__init__(rate, state)
60
+ self.target_state = target_state
61
+
62
+ def apply(self, rng: Generator, model: Model, time: float) -> None:
63
+ node = model.get_random_leaf(self.state, rng)
64
+ model.add_child(node, time, False, self.target_state)
65
+
66
+
67
+ class SamplingEvent(Event):
68
+ def __init__(
69
+ self,
70
+ rate: SkylineParameterLike,
71
+ removal_probability: SkylineParameterLike,
72
+ state: str | None = None,
73
+ ):
74
+ super().__init__(rate, state)
75
+ self.removal_probability = skyline_parameter(removal_probability)
76
+
77
+ def apply(self, rng: Generator, model: Model, time: float) -> None:
78
+ node = model.get_random_leaf(self.state, rng)
79
+ remove = rng.random() < self.removal_probability.get_value_at_time(time)
80
+ model.sample(node, time, remove)
81
+
82
+
83
+ def get_canonical_events(
84
+ sampling_rates: SkylineVectorCoercible,
85
+ birth_rates: SkylineVectorCoercible = 0,
86
+ death_rates: SkylineVectorCoercible = 0,
87
+ removal_probabilities: SkylineVectorCoercible = 0,
88
+ migration_rates: SkylineMatrixCoercible = 0,
89
+ birth_rates_among_states: SkylineMatrixCoercible = 0,
90
+ states: list[str] | None = None,
91
+ ) -> list[Event]:
92
+ N = 1 if states is None else len(states)
93
+
94
+ birth_rates = skyline_vector(birth_rates, N)
95
+ death_rates = skyline_vector(death_rates, N)
96
+ sampling_rates = skyline_vector(sampling_rates, N)
97
+ removal_probabilities = skyline_vector(removal_probabilities, N)
98
+ if migration_rates and N == 1:
99
+ raise ValueError(f"Migration rates require multiple states (got {states}).")
100
+ if birth_rates_among_states and N == 1:
101
+ raise ValueError(
102
+ f"Birth rates among states require multiple states (got {states})."
103
+ )
104
+
105
+ events: list[Event] = []
106
+ for i in range(N):
107
+ state = None if states is None else states[i]
108
+ events.append(BirthEvent(birth_rates[i], state, state))
109
+ events.append(DeathEvent(death_rates[i], state))
110
+ events.append(SamplingEvent(sampling_rates[i], removal_probabilities[i], state))
111
+ if N > 1:
112
+ migration_rates = skyline_matrix(migration_rates, N, N - 1)
113
+ birth_rates_among_states = skyline_matrix(
114
+ birth_rates_among_states, N, N - 1
115
+ )
116
+ assert states is not None
117
+ assert state is not None
118
+ for j, other_state in enumerate([s for s in states if s != state]):
119
+ events.append(MigrationEvent(state, other_state, migration_rates[i][j]))
120
+ events.append(
121
+ BirthEvent(birth_rates_among_states[i][j], state, other_state)
122
+ )
123
+ return [event for event in events if event.rate]
124
+
125
+
126
+ def get_epidemiological_events(
127
+ sampling_proportions: SkylineVectorCoercible = 1,
128
+ reproduction_numbers: SkylineVectorCoercible = 0,
129
+ become_uninfectious_rates: SkylineVectorCoercible = 0,
130
+ removal_probabilities: SkylineVectorCoercible = 1,
131
+ migration_rates: SkylineMatrixCoercible = 0,
132
+ reproduction_numbers_among_states: SkylineMatrixCoercible = 0,
133
+ states: list[str] | None = None,
134
+ ) -> list[Event]:
135
+ N = 1 if states is None else len(states)
136
+
137
+ reproduction_numbers = skyline_vector(reproduction_numbers, N)
138
+ become_uninfectious_rates = skyline_vector(become_uninfectious_rates, N)
139
+ sampling_proportions = skyline_vector(sampling_proportions, N)
140
+ removal_probabilities = skyline_vector(removal_probabilities, N)
141
+ if N == 1 and reproduction_numbers_among_states:
142
+ raise ValueError(
143
+ f"Reproduction numbers among states require multiple states (got {states})."
144
+ )
145
+ reproduction_numbers_among_states = (
146
+ skyline_matrix(reproduction_numbers_among_states, N, N - 1) if N > 1 else 0
147
+ )
148
+
149
+ birth_rates = reproduction_numbers * become_uninfectious_rates
150
+ sampling_rates = become_uninfectious_rates * sampling_proportions
151
+ birth_rates_among_states = (
152
+ reproduction_numbers_among_states * become_uninfectious_rates
153
+ )
154
+ death_rates = become_uninfectious_rates - removal_probabilities * sampling_rates
155
+
156
+ return get_canonical_events(
157
+ states=states,
158
+ birth_rates=birth_rates,
159
+ death_rates=death_rates,
160
+ sampling_rates=sampling_rates,
161
+ removal_probabilities=removal_probabilities,
162
+ migration_rates=migration_rates,
163
+ birth_rates_among_states=birth_rates_among_states,
164
+ )
165
+
166
+
167
+ def get_FBD_events(
168
+ diversification: SkylineVectorCoercible = 0,
169
+ turnover: SkylineVectorCoercible = 0,
170
+ sampling_proportions: SkylineVectorCoercible = 1,
171
+ removal_probabilities: SkylineVectorCoercible = 0,
172
+ migration_rates: SkylineMatrixCoercible = 0,
173
+ diversification_between_types: SkylineMatrixCoercible = 0,
174
+ states: list[str] | None = None,
175
+ ):
176
+ N = 1 if states is None else len(states)
177
+
178
+ diversification = skyline_vector(diversification, N)
179
+ turnover = skyline_vector(turnover, N)
180
+ sampling_proportions = skyline_vector(sampling_proportions, N)
181
+ removal_probabilities = skyline_vector(removal_probabilities, N)
182
+ if N == 1 and diversification_between_types:
183
+ raise ValueError(
184
+ f"Diversification rates among states require multiple states (got {states})."
185
+ )
186
+ diversification_between_types = (
187
+ skyline_matrix(diversification_between_types, N, N - 1) if N > 1 else 0
188
+ )
189
+
190
+ birth_rates = diversification / (1 - turnover)
191
+ death_rates = turnover * birth_rates
192
+ sampling_rates = (
193
+ sampling_proportions
194
+ * death_rates
195
+ / (1 - removal_probabilities * sampling_proportions)
196
+ )
197
+ birth_rates_among_states = diversification_between_types + death_rates
198
+
199
+ return get_canonical_events(
200
+ states=states,
201
+ birth_rates=birth_rates,
202
+ death_rates=death_rates,
203
+ sampling_rates=sampling_rates,
204
+ removal_probabilities=removal_probabilities,
205
+ migration_rates=migration_rates,
206
+ birth_rates_among_states=birth_rates_among_states,
207
+ )
208
+
209
+
210
+ def get_BD_events(
211
+ reproduction_number: SkylineParameterLike,
212
+ infectious_period: SkylineParameterLike,
213
+ sampling_proportion: SkylineParameterLike = 1,
214
+ ) -> list[Event]:
215
+ return get_epidemiological_events(
216
+ reproduction_numbers=reproduction_number,
217
+ become_uninfectious_rates=1 / infectious_period,
218
+ sampling_proportions=sampling_proportion,
219
+ )
220
+
221
+
222
+ def get_BDEI_events(
223
+ reproduction_number: SkylineParameterLike,
224
+ infectious_period: SkylineParameterLike,
225
+ incubation_period: SkylineParameterLike,
226
+ sampling_proportion: SkylineParameterLike = 1,
227
+ ) -> list[Event]:
228
+ return get_epidemiological_events(
229
+ states=[EXPOSED_STATE, INFECTIOUS_STATE],
230
+ sampling_proportions=[0, sampling_proportion],
231
+ become_uninfectious_rates=[0, 1 / infectious_period],
232
+ reproduction_numbers_among_states=[[0], [reproduction_number]],
233
+ migration_rates=[[1 / incubation_period], [0]],
234
+ )
235
+
236
+
237
+ def get_BDSS_events(
238
+ reproduction_number: SkylineParameterLike,
239
+ infectious_period: SkylineParameterLike,
240
+ superspreading_ratio: SkylineParameterLike,
241
+ superspreaders_proportion: SkylineParameterLike,
242
+ sampling_proportion: SkylineParameterLike = 1,
243
+ ) -> list[Event]:
244
+ f_SS = superspreaders_proportion
245
+ r_SS = superspreading_ratio
246
+ R_0_IS = reproduction_number * f_SS / (1 + r_SS * f_SS - f_SS)
247
+ R_0_SI = (reproduction_number - r_SS * R_0_IS) * r_SS
248
+ R_0_S = r_SS * R_0_IS
249
+ R_0_I = R_0_SI / r_SS
250
+ return get_epidemiological_events(
251
+ states=[INFECTIOUS_STATE, SUPERSPREADER_STATE],
252
+ reproduction_numbers=[R_0_I, R_0_S],
253
+ reproduction_numbers_among_states=[[R_0_IS], [R_0_SI]],
254
+ become_uninfectious_rates=1 / infectious_period,
255
+ sampling_proportions=sampling_proportion,
256
+ )
@@ -0,0 +1,66 @@
1
+ from collections.abc import Sequence
2
+
3
+ import numpy as np
4
+ from numpy.random import default_rng
5
+
6
+ from phylogenie.tree import Tree
7
+ from phylogenie.treesimulator.events import Event
8
+ from phylogenie.treesimulator.model import Model
9
+
10
+
11
+ def simulate_tree(
12
+ events: Sequence[Event],
13
+ min_tips: int = 1,
14
+ max_tips: int | None = None,
15
+ max_time: float = np.inf,
16
+ init_state: str | None = None,
17
+ sampling_probability_at_present: float = 0.0,
18
+ max_tries: int | None = None,
19
+ seed: int | None = None,
20
+ ) -> Tree | None:
21
+ rng = default_rng(seed)
22
+
23
+ if max_tips is None and max_time == np.inf:
24
+ raise ValueError("Either max_tips or max_time must be specified.")
25
+
26
+ n_tries = 0
27
+ states = [e.state for e in events if e.state is not None]
28
+ init_state = (
29
+ init_state
30
+ if init_state is not None
31
+ else str(rng.choice(states)) if states else None
32
+ )
33
+ while max_tries is None or n_tries < max_tries:
34
+ model = Model(init_state)
35
+ current_time = 0.0
36
+ change_times = sorted(set(t for e in events for t in e.rate.change_times))
37
+ next_change_time = change_times.pop(0) if change_times else np.inf
38
+ n_tips = None if max_tips is None else rng.integers(min_tips, max_tips + 1)
39
+
40
+ while current_time < max_time and (n_tips is None or model.n_sampled < n_tips):
41
+ rates = [e.get_propensity(model, current_time) for e in events]
42
+ if not any(rates):
43
+ break
44
+
45
+ current_time += rng.exponential(1 / sum(rates))
46
+ if current_time >= max_time:
47
+ break
48
+
49
+ if current_time >= next_change_time:
50
+ current_time = next_change_time
51
+ next_change_time = change_times.pop(0) if change_times else np.inf
52
+ continue
53
+
54
+ event_idx = np.searchsorted(np.cumsum(rates) / sum(rates), rng.random())
55
+ events[int(event_idx)].apply(rng, model, current_time)
56
+
57
+ for leaf in model.get_leaves():
58
+ if rng.random() < sampling_probability_at_present:
59
+ model.sample(leaf, current_time, True)
60
+
61
+ if model.n_sampled >= min_tips and (
62
+ max_tips is None or model.n_sampled <= max_tips
63
+ ):
64
+ return model.get_sampled_tree()
65
+
66
+ n_tries += 1
@@ -0,0 +1,100 @@
1
+ from collections import defaultdict
2
+
3
+ from numpy.random import Generator, default_rng
4
+
5
+ from phylogenie.tree import Tree
6
+
7
+
8
+ class Model:
9
+ def __init__(self, init_state: str | None = None):
10
+ self._next_id = 0
11
+ self._n_sampled = 0
12
+ self._leaves: dict[str, Tree] = {}
13
+ self._leaf2state: dict[str, str | None] = {}
14
+ self._state2leaves: dict[str | None, set[str]] = defaultdict(set)
15
+ self._tree = self._get_new_node(init_state, None)
16
+
17
+ @property
18
+ def next_id(self) -> int:
19
+ self._next_id += 1
20
+ return self._next_id
21
+
22
+ @property
23
+ def n_sampled(self) -> int:
24
+ return self._n_sampled
25
+
26
+ def _get_new_node(self, state: str | None, branch_length: float | None) -> Tree:
27
+ id = str(self.next_id) if state is None else f"{self.next_id}|{state}"
28
+ node = Tree(id, branch_length)
29
+ if branch_length is None:
30
+ self._leaves[id] = node
31
+ self._leaf2state[id] = state
32
+ self._state2leaves[state].add(id)
33
+ return node
34
+
35
+ def remove(self, node_id: str) -> None:
36
+ self._state2leaves[self._leaf2state[node_id]].remove(node_id)
37
+ self._leaf2state.pop(node_id, None)
38
+ self._leaves.pop(node_id)
39
+
40
+ def add_child(
41
+ self,
42
+ node_id: str,
43
+ time: float,
44
+ stem: bool,
45
+ state: str | None,
46
+ branch_length: float | None = None,
47
+ ) -> None:
48
+ node = self._leaves[node_id]
49
+ if node.branch_length is not None:
50
+ raise ValueError("Cannot add a child to a node with a set branch length.")
51
+ node.add_child(self._get_new_node(state, branch_length))
52
+ if stem:
53
+ node.add_child(self._get_new_node(self._leaf2state[node.id], None))
54
+ node.branch_length = (
55
+ time if node.parent is None else time - node.parent.get_time()
56
+ )
57
+ self.remove(node_id)
58
+
59
+ def sample(self, node_id: str, time: float, remove: bool) -> None:
60
+ self.add_child(node_id, time, not remove, self._leaf2state[node_id], 0.0)
61
+ self._n_sampled += 1
62
+
63
+ def get_sampled_tree(self) -> Tree:
64
+ tree = self._tree.copy()
65
+ for node in list(tree.postorder_traversal()):
66
+ if node.branch_length is None or (
67
+ node.branch_length > 0 and not node.children
68
+ ):
69
+ if node.parent is None:
70
+ raise ValueError("No samples in the tree.")
71
+ else:
72
+ node.parent.children.remove(node)
73
+ elif len(node.children) == 1:
74
+ (child,) = node.children
75
+ child.parent = node.parent
76
+ assert child.branch_length is not None
77
+ assert node.branch_length is not None
78
+ child.branch_length += node.branch_length
79
+ if node.parent is None:
80
+ return child
81
+ else:
82
+ node.parent.children.append(child)
83
+ node.parent.children.remove(node)
84
+ return tree
85
+
86
+ def get_random_leaf(
87
+ self, state: str | None = None, rng: int | Generator | None = None
88
+ ) -> str:
89
+ rng = rng if isinstance(rng, Generator) else default_rng(rng)
90
+ if state is None:
91
+ return rng.choice(list(self._leaves))
92
+ return rng.choice(list(self._state2leaves[state]))
93
+
94
+ def get_leaves(self) -> list[str]:
95
+ return list(self._leaves)
96
+
97
+ def count_leaves(self, state: str | None = None) -> int:
98
+ if state is None:
99
+ return len(self._leaves)
100
+ return len(self._state2leaves[state])
phylogenie/typings.py CHANGED
@@ -19,5 +19,3 @@ Vector1D = list[Scalar]
19
19
  IntVector1D = list[int]
20
20
  Vector2D = list[Vector1D]
21
21
  Vector3D = list[Vector2D]
22
-
23
- Data = dict[str, str | Scalar | Vector1D | Vector2D | Vector3D]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: phylogenie
3
- Version: 1.0.7
3
+ Version: 2.0.0
4
4
  Summary: Generate phylogenetic datasets with minimal setup effort
5
5
  Author: Gabriele Marino
6
6
  Author-email: gabmarino.8601@gmail.com
@@ -23,9 +23,9 @@ Description-Content-Type: text/markdown
23
23
 
24
24
  ---
25
25
 
26
- [![TreeSimulator](https://img.shields.io/badge/Powered%20by-TreeSimulator-green?style=flat-square)](https://github.com/evolbioinfo/treesimulator)
27
- [![Remaster](https://img.shields.io/badge/Powered%20by-Remaster-blue?style=flat-square)](https://tgvaughan.github.io/remaster/)
28
26
  [![AliSim](https://img.shields.io/badge/Powered%20by-AliSim-orange?style=flat-square)](https://iqtree.github.io/doc/AliSim)
27
+ [![PyPI package](https://badge.fury.io/py/phylogenie.svg)](https://pypi.org/project/phylogenie/)
28
+ [![PyPI downloads](https://shields.io/pypi/dm/phylogenie)](https://pypi.org/project/phylogenie/)
29
29
 
30
30
  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!
31
31
 
@@ -46,7 +46,7 @@ Phylogenie comes packed with useful features, including:
46
46
  Simply specify the number of cores to use, and Phylogenie handles multiprocessing automatically.
47
47
 
48
48
  - **Pre-implemented parameterizations** 🎯
49
- Include canonical, fossilized birth-death, epidemiological, birth-death with exposed-infectious (BDEI), birth-death with superspreading (BDSS), contact-tracing (CT), and more.
49
+ Include canonical, fossilized birth-death, epidemiological, birth-death with exposed-infectious (BDEI), birth-death with superspreading (BDSS), and more.
50
50
 
51
51
  - **Skyline parameter support** 🪜
52
52
  Support for piece-wise constant parameters.
@@ -54,9 +54,6 @@ Phylogenie comes packed with useful features, including:
54
54
  - **Arithmetic operations on parameters** 🧮
55
55
  Perform flexible arithmetic operations between parameters directly within the config file.
56
56
 
57
- - **Support for common phylogenetic simulation tools** 🛠️
58
- Compatible backends include ReMASTER, TreeSimulator, and AliSim.
59
-
60
57
  - **Modular and extendible architecture** 🧩
61
58
  Easily add new simulation backends as needed.
62
59
 
@@ -76,18 +73,9 @@ cd phylogenie
76
73
  pip install .
77
74
  ```
78
75
 
79
- ## 🛠 Backend dependencies
80
-
81
- Phylogenie works with the following simulation backends:
82
-
83
- - **[TreeSimulator](https://github.com/evolbioinfo/treesimulator)**
84
- A [Python](https://www.python.org/) package for simulating phylogenetic trees. It is automatically installed with Phylogenie, so you can use it right away.
85
-
86
- - **[ReMASTER](https://tgvaughan.github.io/remaster/)**
87
- A [BEAST2](https://www.beast2.org/) package designed for tree simulation. To use ReMASTER as a backend, you need to install it separately.
76
+ ## 🛠 Backend dependency
88
77
 
89
- - **[AliSim](https://iqtree.github.io/doc/AliSim)**
90
- A tool for simulating multiple sequence alignments (MSAs). It is distributed with [IQ-TREE](https://iqtree.github.io/) and also requires separate installation if you wish to use it as a backend.
78
+ Phylogenie relies on [AliSim](https://iqtree.github.io/doc/AliSim) for simulating multiple sequence alignments (MSAs). AliSim is a powerful MSAs simulation tool distributed with [IQ-TREE](https://iqtree.github.io/), and requires separate installation to use it as a simulation backend.
91
79
 
92
80
  ## 🚀 Quick Start
93
81
 
@@ -0,0 +1,28 @@
1
+ phylogenie/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ phylogenie/generators/__init__.py,sha256=kHDCQUSCl2O-wtPxcYEc1d4NTh5wjt-Oci9bYVNbhIY,440
3
+ phylogenie/generators/alisim.py,sha256=Psh_fAHHrJBCd1kqVtz_BdoVVmNvieHJRMmapQncJhM,2288
4
+ phylogenie/generators/configs.py,sha256=2NctdpKhOK7uuTrau18QCG1OqAAmmTl_c6QYwFnRSU0,1108
5
+ phylogenie/generators/dataset.py,sha256=Q8GsO6b4792VACvwle26QAsbeiyOGUqID2Q3-_urVS4,2543
6
+ phylogenie/generators/factories.py,sha256=AxLNuvZKnrSSUltr--kJ1zr-JjObD-KIip31ETSN0wk,6952
7
+ phylogenie/generators/trees.py,sha256=CXFXeYLYjgJe7tDwCaYrtHBVLl8Wn83in_pDM_2oH6M,8717
8
+ phylogenie/generators/typeguards.py,sha256=6WIQIy6huHok4vYqA9ym6g2kvyyXPggBONWwbiHtDiY,925
9
+ phylogenie/io.py,sha256=lDLWz-7fsw85HCpVjtpGpw2oWxf5Aurd3_jTx2Gt_pU,2865
10
+ phylogenie/main.py,sha256=vtvSpQxBNlYABoFQ25czl-l3fIr4QRo3svWVd-jcArw,1170
11
+ phylogenie/msa.py,sha256=JDGyZUsAq6-m-SQjoCDjAkAZIxfgyl_PDIhdYn5HOow,2064
12
+ phylogenie/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
+ phylogenie/skyline/__init__.py,sha256=7pF4CUb4ZCLzNYJNhOjpuTOLTRhlK7L6ugfccNqjIGo,620
14
+ phylogenie/skyline/matrix.py,sha256=S9CTsiK8hh4hXEnbsnPFnIXVNUFL9Oe3MMBKWRNEsSE,8951
15
+ phylogenie/skyline/parameter.py,sha256=CJ5OEyRQG2Tg1WJWQ1IpfX-6hjJv80Zj8lMoRke5nnQ,4648
16
+ phylogenie/skyline/vector.py,sha256=becZlWLeT12mvpDC5MLGXZPKlgmbkY-DEcuhdQpnsSc,7135
17
+ phylogenie/tree.py,sha256=nNUQrTtUqgc-Z6CHflqROZ8W2ZL1YWGG7xeWmcKwZUU,1684
18
+ phylogenie/treesimulator/__init__.py,sha256=koyVZxKUeMtY1S2WUgqbeIthoGbdUmx9vP4svFi4a6U,459
19
+ phylogenie/treesimulator/events.py,sha256=4TJpf9v9Cx-8g886Ilw2fbjSCuSkIoQ_xfOkm_a4ex8,9356
20
+ phylogenie/treesimulator/gillespie.py,sha256=p2bjwc6iyaf4mMI-xregJwOnXkjT2tIhxXbcGncQ5b0,2293
21
+ phylogenie/treesimulator/model.py,sha256=pPl4JYnBIHjWeSgpIypaDOes11tA4bFAGuMRArXbsVo,3577
22
+ phylogenie/typeguards.py,sha256=WBOSJSaOC8VDtrYoA2w_AYEXTpyKdCfmsM29KaKXl3A,1350
23
+ phylogenie/typings.py,sha256=O1X6lGKTjJ2YJz3ApQ-rYb_tEJNUIcHdUIeYlSM4s5o,500
24
+ phylogenie-2.0.0.dist-info/LICENSE.txt,sha256=NUrDqElK-eD3I0WqC004CJsy6cs0JgsAoebDv_42-pw,1071
25
+ phylogenie-2.0.0.dist-info/METADATA,sha256=n2Rf9bfLtz_ctQrAZaXc-nQCe1Z3xqoUbiNrpwLOD94,5602
26
+ phylogenie-2.0.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
27
+ phylogenie-2.0.0.dist-info/entry_points.txt,sha256=Rt6_usN0FkBX1ZfiqCirjMN9FKOgFLG8rydcQ8kugeE,51
28
+ phylogenie-2.0.0.dist-info/RECORD,,
File without changes
@@ -1,21 +0,0 @@
1
- from phylogenie.backend.remaster.generate import generate_trees
2
- from phylogenie.backend.remaster.reactions import (
3
- DEFAULT_POPULATION,
4
- SAMPLE_POPULATION,
5
- PunctualReaction,
6
- Reaction,
7
- get_canonical_reactions,
8
- get_epidemiological_reactions,
9
- get_FBD_reactions,
10
- )
11
-
12
- __all__ = [
13
- "DEFAULT_POPULATION",
14
- "SAMPLE_POPULATION",
15
- "PunctualReaction",
16
- "Reaction",
17
- "get_canonical_reactions",
18
- "get_epidemiological_reactions",
19
- "get_FBD_reactions",
20
- "generate_trees",
21
- ]