phylogenie 2.1.5__py3-none-any.whl → 2.1.7__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.
@@ -46,7 +46,7 @@ class ParameterizationType(str, Enum):
46
46
  class TreeDatasetGenerator(DatasetGenerator):
47
47
  data_type: Literal[DataType.TREES] = DataType.TREES
48
48
  min_tips: cfg.Integer = 1
49
- max_tips: cfg.Integer = 2**32
49
+ max_tips: cfg.Integer | None = None
50
50
  max_time: cfg.Scalar = np.inf
51
51
  init_state: str | None = None
52
52
  sampling_probability_at_present: cfg.Scalar = 0.0
@@ -64,7 +64,7 @@ class TreeDatasetGenerator(DatasetGenerator):
64
64
  return simulate_tree(
65
65
  events=self._get_events(data),
66
66
  min_tips=integer(self.min_tips, data),
67
- max_tips=integer(self.max_tips, data),
67
+ max_tips=None if self.max_tips is None else integer(self.max_tips, data),
68
68
  max_time=scalar(self.max_time, data),
69
69
  init_state=init_state,
70
70
  sampling_probability_at_present=scalar(
@@ -98,8 +98,8 @@ class CanonicalTreeDatasetGenerator(TreeDatasetGenerator):
98
98
  ParameterizationType.CANONICAL
99
99
  )
100
100
  states: list[str]
101
- sampling_rates: cfg.SkylineVector
102
- remove_after_sampling: bool
101
+ sampling_rates: cfg.SkylineVector = 0
102
+ remove_after_sampling: bool = False
103
103
  birth_rates: cfg.SkylineVector = 0
104
104
  death_rates: cfg.SkylineVector = 0
105
105
  migration_rates: cfg.SkylineMatrix = None
@@ -122,7 +122,7 @@ class CanonicalTreeDatasetGenerator(TreeDatasetGenerator):
122
122
  class FBDTreeDatasetGenerator(TreeDatasetGenerator):
123
123
  parameterization: Literal[ParameterizationType.FBD] = ParameterizationType.FBD
124
124
  states: list[str]
125
- sampling_proportions: cfg.SkylineVector
125
+ sampling_proportions: cfg.SkylineVector = 0
126
126
  diversification: cfg.SkylineVector = 0
127
127
  turnover: cfg.SkylineVector = 0
128
128
  migration_rates: cfg.SkylineMatrix = None
@@ -218,7 +218,7 @@ class BDTreeDatasetGenerator(TreeDatasetGeneratorForEpidemiology):
218
218
  parameterization: Literal[ParameterizationType.BD] = ParameterizationType.BD
219
219
  reproduction_number: cfg.SkylineParameter
220
220
  infectious_period: cfg.SkylineParameter
221
- sampling_proportion: cfg.SkylineParameter = 1
221
+ sampling_proportion: cfg.SkylineParameter
222
222
 
223
223
  def _get_base_events(self, data: dict[str, Any]) -> list[Event]:
224
224
  return get_BD_events(
@@ -233,7 +233,7 @@ class BDEITreeDatasetGenerator(TreeDatasetGeneratorForEpidemiology):
233
233
  reproduction_number: cfg.SkylineParameter
234
234
  infectious_period: cfg.SkylineParameter
235
235
  incubation_period: cfg.SkylineParameter
236
- sampling_proportion: cfg.SkylineParameter = 1
236
+ sampling_proportion: cfg.SkylineParameter
237
237
 
238
238
  def _get_base_events(self, data: dict[str, Any]) -> list[Event]:
239
239
  return get_BDEI_events(
@@ -250,7 +250,7 @@ class BDSSTreeDatasetGenerator(TreeDatasetGeneratorForEpidemiology):
250
250
  infectious_period: cfg.SkylineParameter
251
251
  superspreading_ratio: cfg.SkylineParameter
252
252
  superspreaders_proportion: cfg.SkylineParameter
253
- sampling_proportion: cfg.SkylineParameter = 1
253
+ sampling_proportion: cfg.SkylineParameter
254
254
 
255
255
  def _get_base_events(self, data: dict[str, Any]) -> list[Event]:
256
256
  return get_BDSS_events(
phylogenie/tree.py CHANGED
@@ -36,6 +36,15 @@ class Tree:
36
36
  if node is not None:
37
37
  node._children.append(self)
38
38
 
39
+ def inorder_traversal(self) -> Iterator["Tree"]:
40
+ if self.children and len(self.children) != 2:
41
+ raise ValueError("Inorder traversal is only defined for binary trees.")
42
+ if self.children:
43
+ yield from self.children[0].inorder_traversal()
44
+ yield self
45
+ if self.children:
46
+ yield from self.children[1].inorder_traversal()
47
+
39
48
  def preorder_traversal(self) -> Iterator["Tree"]:
40
49
  yield self
41
50
  for child in self.children:
@@ -64,8 +64,8 @@ class Sampling(Event):
64
64
 
65
65
  def get_canonical_events(
66
66
  states: list[str],
67
- sampling_rates: SkylineVectorCoercible,
68
- remove_after_sampling: bool,
67
+ sampling_rates: SkylineVectorCoercible = 0,
68
+ remove_after_sampling: bool = False,
69
69
  birth_rates: SkylineVectorCoercible = 0,
70
70
  death_rates: SkylineVectorCoercible = 0,
71
71
  migration_rates: SkylineMatrixCoercible | None = None,
@@ -100,7 +100,7 @@ def get_canonical_events(
100
100
 
101
101
  def get_FBD_events(
102
102
  states: list[str],
103
- sampling_proportions: SkylineVectorCoercible = 1,
103
+ sampling_proportions: SkylineVectorCoercible = 0,
104
104
  diversification: SkylineVectorCoercible = 0,
105
105
  turnover: SkylineVectorCoercible = 0,
106
106
  migration_rates: SkylineMatrixCoercible | None = None,
@@ -134,7 +134,7 @@ def get_FBD_events(
134
134
 
135
135
  def get_epidemiological_events(
136
136
  states: list[str],
137
- sampling_proportions: SkylineVectorCoercible = 1,
137
+ sampling_proportions: SkylineVectorCoercible,
138
138
  reproduction_numbers: SkylineVectorCoercible = 0,
139
139
  become_uninfectious_rates: SkylineVectorCoercible = 0,
140
140
  migration_rates: SkylineMatrixCoercible | None = None,
@@ -172,7 +172,7 @@ def get_epidemiological_events(
172
172
  def get_BD_events(
173
173
  reproduction_number: SkylineParameterLike,
174
174
  infectious_period: SkylineParameterLike,
175
- sampling_proportion: SkylineParameterLike = 1,
175
+ sampling_proportion: SkylineParameterLike,
176
176
  ) -> list[Event]:
177
177
  return get_epidemiological_events(
178
178
  states=[INFECTIOUS_STATE],
@@ -186,7 +186,7 @@ def get_BDEI_events(
186
186
  reproduction_number: SkylineParameterLike,
187
187
  infectious_period: SkylineParameterLike,
188
188
  incubation_period: SkylineParameterLike,
189
- sampling_proportion: SkylineParameterLike = 1,
189
+ sampling_proportion: SkylineParameterLike,
190
190
  ) -> list[Event]:
191
191
  return get_epidemiological_events(
192
192
  states=[EXPOSED_STATE, INFECTIOUS_STATE],
@@ -202,7 +202,7 @@ def get_BDSS_events(
202
202
  infectious_period: SkylineParameterLike,
203
203
  superspreading_ratio: SkylineParameterLike,
204
204
  superspreaders_proportion: SkylineParameterLike,
205
- sampling_proportion: SkylineParameterLike = 1,
205
+ sampling_proportion: SkylineParameterLike,
206
206
  ) -> list[Event]:
207
207
  f_SS = superspreaders_proportion
208
208
  r_SS = superspreading_ratio
@@ -11,20 +11,18 @@ from phylogenie.io import dump_newick
11
11
  from phylogenie.tree import Tree
12
12
  from phylogenie.treesimulator.model import Event, Model
13
13
 
14
- MAX_TIPS = 2**32
15
-
16
14
 
17
15
  def simulate_tree(
18
16
  events: Sequence[Event],
19
17
  min_tips: int = 1,
20
- max_tips: int = MAX_TIPS,
18
+ max_tips: int | None = None,
21
19
  max_time: float = np.inf,
22
20
  init_state: str | None = None,
23
21
  sampling_probability_at_present: float = 0.0,
24
22
  seed: int | None = None,
25
23
  timeout: float = np.inf,
26
24
  ) -> Tree:
27
- if max_time == np.inf and max_tips == MAX_TIPS:
25
+ if max_time == np.inf and max_tips is None:
28
26
  raise ValueError("Either max_time or max_tips must be specified.")
29
27
 
30
28
  if max_time == np.inf and sampling_probability_at_present:
@@ -49,9 +47,11 @@ def simulate_tree(
49
47
  current_time = 0.0
50
48
  change_times = sorted(set(t for e in events for t in e.rate.change_times))
51
49
  next_change_time = change_times.pop(0) if change_times else np.inf
52
- target_n_tips = (
53
- rng.integers(min_tips, max_tips + 1) if max_time == np.inf else None
54
- )
50
+ if max_time == np.inf:
51
+ assert max_tips is not None
52
+ target_n_tips = rng.integers(min_tips, max_tips + 1)
53
+ else:
54
+ target_n_tips = None
55
55
 
56
56
  while current_time < max_time:
57
57
  if time.perf_counter() - start_clock > timeout:
@@ -68,7 +68,8 @@ def simulate_tree(
68
68
 
69
69
  if (
70
70
  not any(rates)
71
- or model.n_sampled > max_tips
71
+ or max_tips is not None
72
+ and model.n_sampled > max_tips
72
73
  or target_n_tips is not None
73
74
  and model.n_sampled >= target_n_tips
74
75
  ):
@@ -91,7 +92,9 @@ def simulate_tree(
91
92
  if rng.random() < sampling_probability_at_present:
92
93
  model.sample(individual, current_time, True)
93
94
 
94
- if min_tips <= model.n_sampled <= max_tips:
95
+ if min_tips <= model.n_sampled and (
96
+ max_tips is None or model.n_sampled <= max_tips
97
+ ):
95
98
  return model.get_sampled_tree()
96
99
 
97
100
 
@@ -127,7 +130,7 @@ def generate_trees(
127
130
 
128
131
  if os.path.exists(output_dir):
129
132
  raise FileExistsError(f"Output directory {output_dir} already exists")
130
- os.makedirs(output_dir, exist_ok=True)
133
+ os.makedirs(output_dir)
131
134
 
132
135
  rng = default_rng(seed)
133
136
  jobs = joblib.Parallel(n_jobs=n_jobs, return_as="generator_unordered")(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: phylogenie
3
- Version: 2.1.5
3
+ Version: 2.1.7
4
4
  Summary: Generate phylogenetic datasets with minimal setup effort
5
5
  Author: Gabriele Marino
6
6
  Author-email: gabmarino.8601@gmail.com
@@ -24,6 +24,8 @@ Description-Content-Type: text/markdown
24
24
 
25
25
  [![AliSim](https://img.shields.io/badge/Powered%20by-AliSim-orange?style=flat-square)](https://iqtree.github.io/doc/AliSim)
26
26
  [![PyPI version](https://img.shields.io/pypi/v/phylogenie)](https://pypi.org/project/phylogenie/)
27
+ ![Downloads](https://img.shields.io/pypi/dm/phylogenie)
28
+
27
29
 
28
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!
29
31
 
@@ -4,7 +4,7 @@ phylogenie/generators/alisim.py,sha256=6IQEn8zNoVSLdHLRT1HBnrv1wfZzYaT-38SQNXE_M
4
4
  phylogenie/generators/configs.py,sha256=AiiFS6rpH9BPwDKCkT4SVrRzfLFFrwRCJM4CRj0Srdk,1072
5
5
  phylogenie/generators/dataset.py,sha256=loVKC_1G7gzkPDN9W3GF-Rj9od8AeOJgIC0aJJa-4KA,2110
6
6
  phylogenie/generators/factories.py,sha256=OKCNg9jwF2KahZCJKTdJVxhLTeLNBDMOqJs7XSVXTqY,7881
7
- phylogenie/generators/trees.py,sha256=q03WPG82M4ucp-jyjoKEBy7TKMBzD3RkKn8hS0G0-i0,10463
7
+ phylogenie/generators/trees.py,sha256=KEDvyrfMjUPWwyp1xnhWpatNnjmDLPhSSQl6Msx19Ms,10508
8
8
  phylogenie/generators/typeguards.py,sha256=yj4VkhOaUXJ2OrY-6zhOeY9C4yKIQxjZtk2d-vIxttQ,828
9
9
  phylogenie/io.py,sha256=y7nQIvLgCvqELsXFKfm1GgKJO_saoQ-7zQpE3Kvajzc,3509
10
10
  phylogenie/main.py,sha256=vtvSpQxBNlYABoFQ25czl-l3fIr4QRo3svWVd-jcArw,1170
@@ -14,19 +14,19 @@ phylogenie/skyline/__init__.py,sha256=7pF4CUb4ZCLzNYJNhOjpuTOLTRhlK7L6ugfccNqjIG
14
14
  phylogenie/skyline/matrix.py,sha256=Gl8OgKjtieG0NwPYiPimKI36gefV8fm_OeorjdXxPTs,9146
15
15
  phylogenie/skyline/parameter.py,sha256=EM9qlPt0JhMBy3TbztM0dj24BaGNEy8KWKdTObDKhbI,4644
16
16
  phylogenie/skyline/vector.py,sha256=bJP7_FNX_Klt6wXqsyfj0KX3VNj6-dIhzCKSJuQcOV0,7115
17
- phylogenie/tree.py,sha256=KTx3m_tJPdeBqA5i0SA3dwCIobxsFcJwZFunMfDmVBY,2791
17
+ phylogenie/tree.py,sha256=JM4ZccuIh0wesSZ5igK3Wi57dX1peJmj8N0KZdGov9Y,3174
18
18
  phylogenie/treesimulator/__init__.py,sha256=XG_xwETKWgDmCihqNUFCcMHtFg4WvZu5qbqWn9Dndt8,879
19
19
  phylogenie/treesimulator/events/__init__.py,sha256=UGfvXOVJ_ZAkk_8sBPihjmxciiaEnXZEPFIY53sttWI,940
20
20
  phylogenie/treesimulator/events/contact_tracing.py,sha256=_nJ85yhgGkeruQgMHvGpDYoyhheBf8M4LgZWiWdi5dY,4801
21
- phylogenie/treesimulator/events/core.py,sha256=JokGmieAv2xEX7KsjBWZr05jHN1jB-XZbpxe9gwdbDA,7953
21
+ phylogenie/treesimulator/events/core.py,sha256=RF7oHzAjkU675PnczaVc66d9gNrHBL-IhmVHtcy7MKE,7949
22
22
  phylogenie/treesimulator/events/mutations.py,sha256=xkXUIppbLIWZqKwVf-hi7d-_pS42TG2EPVfJA_grxBg,3443
23
- phylogenie/treesimulator/gillespie.py,sha256=xdfiiMAsdC4ybLwmT6njC6ZrbgCeEptpuNX23Gnf-Vc,4877
23
+ phylogenie/treesimulator/gillespie.py,sha256=EfEbuMBQSk9izamBPaQ9rNKA4NvtrI3XVm891G2iMeM,5014
24
24
  phylogenie/treesimulator/model.py,sha256=0Im6cFTlpMlJrSP4pTTKtvLT9qrQWV8MSTesAsBxT8g,5422
25
25
  phylogenie/typeguards.py,sha256=JtqmbEWJZBRHbWgCvcl6nrWm3VcBfzRbklbTBYHItn0,1325
26
26
  phylogenie/typings.py,sha256=GknvAFXyiaWeeYJ8Lk5d6E2VHT-xW6ONEojYbtJYiB8,476
27
27
  phylogenie/utils.py,sha256=pCg9ob0RpLUHwM49x4knKxL4FNPr3-EU_6zMXsvxtAg,370
28
- phylogenie-2.1.5.dist-info/LICENSE.txt,sha256=NUrDqElK-eD3I0WqC004CJsy6cs0JgsAoebDv_42-pw,1071
29
- phylogenie-2.1.5.dist-info/METADATA,sha256=BIpsttapT2FwTo_rFg7AALZigoBVms5w9Q_pFTSGSus,5375
30
- phylogenie-2.1.5.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
31
- phylogenie-2.1.5.dist-info/entry_points.txt,sha256=Rt6_usN0FkBX1ZfiqCirjMN9FKOgFLG8rydcQ8kugeE,51
32
- phylogenie-2.1.5.dist-info/RECORD,,
28
+ phylogenie-2.1.7.dist-info/LICENSE.txt,sha256=NUrDqElK-eD3I0WqC004CJsy6cs0JgsAoebDv_42-pw,1071
29
+ phylogenie-2.1.7.dist-info/METADATA,sha256=CZ_2VR75BnBKObxMlc0LZR1sIApDeZMw3IRCuUPT2zM,5432
30
+ phylogenie-2.1.7.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
31
+ phylogenie-2.1.7.dist-info/entry_points.txt,sha256=Rt6_usN0FkBX1ZfiqCirjMN9FKOgFLG8rydcQ8kugeE,51
32
+ phylogenie-2.1.7.dist-info/RECORD,,