phylogenie 1.0.3__tar.gz → 1.0.5__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.
- {phylogenie-1.0.3 → phylogenie-1.0.5}/PKG-INFO +1 -1
- {phylogenie-1.0.3 → phylogenie-1.0.5}/phylogenie/core/configs.py +1 -4
- {phylogenie-1.0.3 → phylogenie-1.0.5}/phylogenie/core/context/configs.py +4 -14
- {phylogenie-1.0.3 → phylogenie-1.0.5}/phylogenie/core/context/distributions.py +3 -3
- phylogenie-1.0.5/phylogenie/core/context/factories.py +54 -0
- {phylogenie-1.0.3 → phylogenie-1.0.5}/phylogenie/core/factories.py +22 -64
- phylogenie-1.0.5/phylogenie/core/msas/base.py +34 -0
- {phylogenie-1.0.3 → phylogenie-1.0.5}/phylogenie/core/trees/remaster/generator.py +0 -3
- {phylogenie-1.0.3 → phylogenie-1.0.5}/phylogenie/core/trees/treesimulator.py +4 -8
- {phylogenie-1.0.3 → phylogenie-1.0.5}/phylogenie/core/typeguards.py +12 -7
- {phylogenie-1.0.3 → phylogenie-1.0.5}/phylogenie/skyline/matrix.py +52 -30
- {phylogenie-1.0.3 → phylogenie-1.0.5}/phylogenie/skyline/parameter.py +26 -12
- {phylogenie-1.0.3 → phylogenie-1.0.5}/phylogenie/skyline/vector.py +35 -13
- {phylogenie-1.0.3 → phylogenie-1.0.5}/phylogenie/typings.py +1 -0
- {phylogenie-1.0.3 → phylogenie-1.0.5}/pyproject.toml +1 -1
- phylogenie-1.0.3/phylogenie/core/context/factories.py +0 -41
- phylogenie-1.0.3/phylogenie/core/msas/base.py +0 -51
- {phylogenie-1.0.3 → phylogenie-1.0.5}/LICENSE.txt +0 -0
- {phylogenie-1.0.3 → phylogenie-1.0.5}/README.md +0 -0
- {phylogenie-1.0.3 → phylogenie-1.0.5}/phylogenie/__init__.py +0 -0
- {phylogenie-1.0.3 → phylogenie-1.0.5}/phylogenie/backend/__init__.py +0 -0
- {phylogenie-1.0.3 → phylogenie-1.0.5}/phylogenie/backend/remaster/__init__.py +0 -0
- {phylogenie-1.0.3 → phylogenie-1.0.5}/phylogenie/backend/remaster/generate.py +0 -0
- {phylogenie-1.0.3 → phylogenie-1.0.5}/phylogenie/backend/remaster/reactions.py +0 -0
- {phylogenie-1.0.3 → phylogenie-1.0.5}/phylogenie/backend/treesimulator.py +0 -0
- {phylogenie-1.0.3 → phylogenie-1.0.5}/phylogenie/configs.py +0 -0
- {phylogenie-1.0.3 → phylogenie-1.0.5}/phylogenie/core/__init__.py +0 -0
- {phylogenie-1.0.3 → phylogenie-1.0.5}/phylogenie/core/context/__init__.py +0 -0
- {phylogenie-1.0.3 → phylogenie-1.0.5}/phylogenie/core/dataset.py +0 -0
- {phylogenie-1.0.3 → phylogenie-1.0.5}/phylogenie/core/msas/__init__.py +0 -0
- {phylogenie-1.0.3 → phylogenie-1.0.5}/phylogenie/core/msas/alisim.py +0 -0
- {phylogenie-1.0.3 → phylogenie-1.0.5}/phylogenie/core/trees/__init__.py +0 -0
- {phylogenie-1.0.3 → phylogenie-1.0.5}/phylogenie/core/trees/base.py +0 -0
- {phylogenie-1.0.3 → phylogenie-1.0.5}/phylogenie/core/trees/remaster/__init__.py +0 -0
- {phylogenie-1.0.3 → phylogenie-1.0.5}/phylogenie/core/trees/remaster/configs.py +0 -0
- {phylogenie-1.0.3 → phylogenie-1.0.5}/phylogenie/core/trees/remaster/factories.py +0 -0
- {phylogenie-1.0.3 → phylogenie-1.0.5}/phylogenie/main.py +0 -0
- {phylogenie-1.0.3 → phylogenie-1.0.5}/phylogenie/py.typed +0 -0
- {phylogenie-1.0.3 → phylogenie-1.0.5}/phylogenie/skyline/__init__.py +0 -0
- {phylogenie-1.0.3 → phylogenie-1.0.5}/phylogenie/typeguards.py +0 -0
|
@@ -25,9 +25,6 @@ class SkylineVectorValueModel(StrictBaseModel):
|
|
|
25
25
|
SkylineVectorCoercibleConfig = (
|
|
26
26
|
str | pgt.Scalar | list[SkylineParameterLikeConfig] | SkylineVectorValueModel
|
|
27
27
|
)
|
|
28
|
-
SkylineVectorLikeConfig = (
|
|
29
|
-
str | list[SkylineParameterLikeConfig] | SkylineVectorValueModel
|
|
30
|
-
)
|
|
31
28
|
|
|
32
29
|
|
|
33
30
|
class SkylineMatrixValueModel(StrictBaseModel):
|
|
@@ -36,5 +33,5 @@ class SkylineMatrixValueModel(StrictBaseModel):
|
|
|
36
33
|
|
|
37
34
|
|
|
38
35
|
SkylineMatrixCoercibleConfig = (
|
|
39
|
-
str | pgt.Scalar | list[
|
|
36
|
+
str | pgt.Scalar | list[SkylineVectorCoercibleConfig] | SkylineMatrixValueModel
|
|
40
37
|
)
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
from typing import Annotated, Literal
|
|
2
|
-
|
|
3
|
-
from pydantic import Field
|
|
4
|
-
|
|
5
1
|
from phylogenie.configs import StrictBaseModel
|
|
6
2
|
from phylogenie.core.context.distributions import (
|
|
7
3
|
DistributionConfig,
|
|
@@ -11,28 +7,22 @@ from phylogenie.core.context.distributions import (
|
|
|
11
7
|
|
|
12
8
|
class VectorModel(StrictBaseModel):
|
|
13
9
|
x: ScalarDistributionConfig
|
|
14
|
-
N: int
|
|
15
10
|
|
|
16
11
|
|
|
17
12
|
class Vector1DModel(VectorModel):
|
|
18
|
-
|
|
13
|
+
size: int
|
|
19
14
|
|
|
20
15
|
|
|
21
16
|
class Vector2DModel(VectorModel):
|
|
22
|
-
|
|
17
|
+
size: tuple[int, int]
|
|
23
18
|
zero_diagonal: bool = False
|
|
24
19
|
|
|
25
20
|
|
|
26
21
|
class Vector3DModel(VectorModel):
|
|
27
|
-
|
|
28
|
-
T: int
|
|
22
|
+
size: tuple[int, int, int]
|
|
29
23
|
zero_diagonal: bool = False
|
|
30
24
|
|
|
31
25
|
|
|
32
26
|
ContextConfig = dict[
|
|
33
|
-
str,
|
|
34
|
-
DistributionConfig
|
|
35
|
-
| Annotated[
|
|
36
|
-
Vector1DModel | Vector2DModel | Vector3DModel, Field(discriminator="n_dim")
|
|
37
|
-
],
|
|
27
|
+
str, DistributionConfig | Vector1DModel | Vector2DModel | Vector3DModel
|
|
38
28
|
]
|
|
@@ -77,7 +77,7 @@ class Exponential(Scalar):
|
|
|
77
77
|
scale: float
|
|
78
78
|
|
|
79
79
|
def _sample(self, rng: Generator) -> float:
|
|
80
|
-
return rng.exponential(
|
|
80
|
+
return rng.exponential(self.scale)
|
|
81
81
|
|
|
82
82
|
|
|
83
83
|
class Gamma(Scalar):
|
|
@@ -86,7 +86,7 @@ class Gamma(Scalar):
|
|
|
86
86
|
shape: float
|
|
87
87
|
|
|
88
88
|
def _sample(self, rng: Generator) -> float:
|
|
89
|
-
return rng.gamma(
|
|
89
|
+
return rng.gamma(self.shape, self.scale)
|
|
90
90
|
|
|
91
91
|
|
|
92
92
|
class Beta(Scalar):
|
|
@@ -95,7 +95,7 @@ class Beta(Scalar):
|
|
|
95
95
|
beta: float
|
|
96
96
|
|
|
97
97
|
def _sample(self, rng: Generator) -> float:
|
|
98
|
-
return rng.beta(
|
|
98
|
+
return rng.beta(self.alpha, self.beta)
|
|
99
99
|
|
|
100
100
|
|
|
101
101
|
class IntUniform(Scalar):
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
from numpy.random import Generator
|
|
2
|
+
|
|
3
|
+
import phylogenie.core.context.configs as cfg
|
|
4
|
+
import phylogenie.typings as pgt
|
|
5
|
+
from phylogenie.core.context import distributions
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def _sample_vector1D(x: distributions.Scalar, N: int, rng: Generator) -> pgt.Vector1D:
|
|
9
|
+
return [x.sample(rng) for _ in range(N)]
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _sample_vector2D(
|
|
13
|
+
x: distributions.Scalar,
|
|
14
|
+
size: tuple[int, int],
|
|
15
|
+
zero_diagonal: bool,
|
|
16
|
+
rng: Generator,
|
|
17
|
+
) -> pgt.Vector2D:
|
|
18
|
+
n_rows, n_cols = size
|
|
19
|
+
v = [_sample_vector1D(x, n_cols, rng) for _ in range(n_rows)]
|
|
20
|
+
if zero_diagonal:
|
|
21
|
+
if n_rows != n_cols:
|
|
22
|
+
raise ValueError(
|
|
23
|
+
f"It is impossible to initialize a non-square matrix with zero the diagonal (got x={x}, size={size} and zero_diagonal=True)"
|
|
24
|
+
)
|
|
25
|
+
for i in range(n_rows):
|
|
26
|
+
v[i][i] = 0
|
|
27
|
+
return v
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def _sample_vector3D(
|
|
31
|
+
x: distributions.Scalar,
|
|
32
|
+
size: tuple[int, int, int],
|
|
33
|
+
zero_diagonal: bool,
|
|
34
|
+
rng: Generator,
|
|
35
|
+
) -> pgt.Vector3D:
|
|
36
|
+
n_matrices, n_rows, n_cols = size
|
|
37
|
+
return [
|
|
38
|
+
_sample_vector2D(x, (n_rows, n_cols), zero_diagonal, rng)
|
|
39
|
+
for _ in range(n_matrices)
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def context_factory(x: cfg.ContextConfig, rng: Generator) -> pgt.Data:
|
|
44
|
+
data: pgt.Data = {}
|
|
45
|
+
for key, value in x.items():
|
|
46
|
+
if isinstance(value, distributions.Distribution):
|
|
47
|
+
data[key] = value.sample(rng)
|
|
48
|
+
elif isinstance(value, cfg.Vector1DModel):
|
|
49
|
+
data[key] = _sample_vector1D(value.x, value.size, rng)
|
|
50
|
+
elif isinstance(value, cfg.Vector2DModel):
|
|
51
|
+
data[key] = _sample_vector2D(value.x, value.size, value.zero_diagonal, rng)
|
|
52
|
+
else:
|
|
53
|
+
data[key] = _sample_vector3D(value.x, value.size, value.zero_diagonal, rng)
|
|
54
|
+
return data
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import Any
|
|
1
|
+
from typing import Any
|
|
2
2
|
|
|
3
3
|
import numpy as np
|
|
4
4
|
|
|
@@ -13,7 +13,6 @@ from phylogenie.skyline import (
|
|
|
13
13
|
SkylineParameterLike,
|
|
14
14
|
SkylineVector,
|
|
15
15
|
SkylineVectorCoercible,
|
|
16
|
-
SkylineVectorLike,
|
|
17
16
|
)
|
|
18
17
|
|
|
19
18
|
|
|
@@ -100,17 +99,23 @@ def skyline_parameter_like_factory(
|
|
|
100
99
|
)
|
|
101
100
|
|
|
102
101
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
x: cfg.SkylineVectorValueModel, data: pgt.Data, coercible: Literal[True]
|
|
106
|
-
) -> SkylineVectorCoercible: ...
|
|
107
|
-
@overload
|
|
108
|
-
def _parse_skyline_vector_value_model(
|
|
109
|
-
x: cfg.SkylineVectorValueModel, data: pgt.Data, coercible: Literal[False]
|
|
110
|
-
) -> SkylineVectorLike: ...
|
|
111
|
-
def _parse_skyline_vector_value_model(
|
|
112
|
-
x: cfg.SkylineVectorValueModel, data: pgt.Data, coercible: bool
|
|
102
|
+
def skyline_vector_coercible_factory(
|
|
103
|
+
x: cfg.SkylineVectorCoercibleConfig, data: pgt.Data
|
|
113
104
|
) -> SkylineVectorCoercible:
|
|
105
|
+
if isinstance(x, str):
|
|
106
|
+
e = _eval_expression(x, data)
|
|
107
|
+
if tg.is_one_or_many_scalars(e):
|
|
108
|
+
return e
|
|
109
|
+
raise ValueError(
|
|
110
|
+
f"Expression '{x}' evaluated to {e} of type {type(e)}, expected a SkylineVectorCoercible object (e.g., a scalar or a sequence of them)."
|
|
111
|
+
)
|
|
112
|
+
if isinstance(x, pgt.Scalar):
|
|
113
|
+
return x
|
|
114
|
+
if ctg.is_list_of_skyline_parameter_like_configs(x):
|
|
115
|
+
return [skyline_parameter_like_factory(p, data) for p in x]
|
|
116
|
+
|
|
117
|
+
assert isinstance(x, cfg.SkylineVectorValueModel)
|
|
118
|
+
|
|
114
119
|
change_times = many_scalars_factory(x.change_times, data)
|
|
115
120
|
if isinstance(x.value, str):
|
|
116
121
|
e = _eval_expression(x.value, data)
|
|
@@ -124,12 +129,7 @@ def _parse_skyline_vector_value_model(
|
|
|
124
129
|
value = [one_or_many_scalars_factory(v, data) for v in x.value]
|
|
125
130
|
|
|
126
131
|
if tg.is_many_scalars(value):
|
|
127
|
-
|
|
128
|
-
return SkylineParameter(value=value, change_times=change_times)
|
|
129
|
-
else:
|
|
130
|
-
raise ValueError(
|
|
131
|
-
f"Parsing SkylineVector config {x.value} yielded a sequence of scalars {value} when a nested (2D) sequence of scalars was expected."
|
|
132
|
-
)
|
|
132
|
+
return SkylineParameter(value=value, change_times=change_times)
|
|
133
133
|
|
|
134
134
|
Ns = {len(elem) for elem in value if tg.is_many(elem)}
|
|
135
135
|
if len(Ns) > 1:
|
|
@@ -139,46 +139,7 @@ def _parse_skyline_vector_value_model(
|
|
|
139
139
|
(N,) = Ns
|
|
140
140
|
value = [[p] * N if isinstance(p, pgt.Scalar) else p for p in value]
|
|
141
141
|
|
|
142
|
-
return SkylineVector(
|
|
143
|
-
value=value,
|
|
144
|
-
change_times=change_times,
|
|
145
|
-
)
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
def skyline_vector_coercible_factory(
|
|
149
|
-
x: cfg.SkylineVectorCoercibleConfig, data: pgt.Data
|
|
150
|
-
) -> SkylineVectorCoercible:
|
|
151
|
-
if isinstance(x, str):
|
|
152
|
-
e = _eval_expression(x, data)
|
|
153
|
-
if tg.is_one_or_many_scalars(e):
|
|
154
|
-
return e
|
|
155
|
-
raise ValueError(
|
|
156
|
-
f"Expression '{x}' evaluated to {e} of type {type(e)}, expected a SkylineVectorCoercible object (e.g., a scalar or a sequence of them)."
|
|
157
|
-
)
|
|
158
|
-
if isinstance(x, pgt.Scalar):
|
|
159
|
-
return x
|
|
160
|
-
if ctg.is_list_of_skyline_parameter_like_configs(x):
|
|
161
|
-
return [skyline_parameter_like_factory(p, data) for p in x]
|
|
162
|
-
|
|
163
|
-
assert isinstance(x, cfg.SkylineVectorValueModel)
|
|
164
|
-
return _parse_skyline_vector_value_model(x, data, coercible=True)
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
def skyline_vector_like_factory(
|
|
168
|
-
x: cfg.SkylineVectorLikeConfig, data: pgt.Data
|
|
169
|
-
) -> SkylineVectorLike:
|
|
170
|
-
if isinstance(x, str):
|
|
171
|
-
e = _eval_expression(x, data)
|
|
172
|
-
if tg.is_many_scalars(e):
|
|
173
|
-
return e
|
|
174
|
-
raise ValueError(
|
|
175
|
-
f"Expression '{x}' evaluated to {e} of type {type(e)}, expected a SkylineVectorLike object (e.g., a sequence of scalars)."
|
|
176
|
-
)
|
|
177
|
-
if ctg.is_list_of_skyline_parameter_like_configs(x):
|
|
178
|
-
return [skyline_parameter_like_factory(p, data) for p in x]
|
|
179
|
-
|
|
180
|
-
assert isinstance(x, cfg.SkylineVectorValueModel)
|
|
181
|
-
return _parse_skyline_vector_value_model(x, data, coercible=False)
|
|
142
|
+
return SkylineVector(value=value, change_times=change_times)
|
|
182
143
|
|
|
183
144
|
|
|
184
145
|
def one_or_many_2D_scalars_factory(
|
|
@@ -208,8 +169,8 @@ def skyline_matrix_coercible_factory(
|
|
|
208
169
|
)
|
|
209
170
|
if isinstance(x, pgt.Scalar):
|
|
210
171
|
return x
|
|
211
|
-
if ctg.
|
|
212
|
-
return [
|
|
172
|
+
if ctg.is_list_of_skyline_vector_coercible_configs(x):
|
|
173
|
+
return [skyline_vector_coercible_factory(v, data) for v in x]
|
|
213
174
|
|
|
214
175
|
assert isinstance(x, cfg.SkylineMatrixValueModel)
|
|
215
176
|
|
|
@@ -245,7 +206,4 @@ def skyline_matrix_coercible_factory(
|
|
|
245
206
|
(N,) = Ns
|
|
246
207
|
value = [[[p] * N] * N if isinstance(p, pgt.Scalar) else p for p in value]
|
|
247
208
|
|
|
248
|
-
return SkylineMatrix(
|
|
249
|
-
value=value,
|
|
250
|
-
change_times=change_times,
|
|
251
|
-
)
|
|
209
|
+
return SkylineMatrix(value=value, change_times=change_times)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from abc import abstractmethod
|
|
3
|
+
from enum import Enum
|
|
4
|
+
from typing import Literal
|
|
5
|
+
|
|
6
|
+
from numpy.random import Generator
|
|
7
|
+
|
|
8
|
+
import phylogenie.typings as pgt
|
|
9
|
+
from phylogenie.core.dataset import DatasetGenerator, DataType
|
|
10
|
+
from phylogenie.core.trees import TreesGeneratorConfig
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class BackendType(str, Enum):
|
|
14
|
+
ALISIM = "alisim"
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class MSAsGenerator(DatasetGenerator):
|
|
18
|
+
data_type: Literal[DataType.MSAS] = DataType.MSAS
|
|
19
|
+
trees: TreesGeneratorConfig
|
|
20
|
+
|
|
21
|
+
@abstractmethod
|
|
22
|
+
def _generate_one_from_tree(
|
|
23
|
+
self, filename: str, tree_file: str, rng: Generator, data: pgt.Data
|
|
24
|
+
) -> None: ...
|
|
25
|
+
|
|
26
|
+
def _generate_one(self, filename: str, rng: Generator, data: pgt.Data) -> None:
|
|
27
|
+
tree_filename = f"{filename}.temp-tree"
|
|
28
|
+
self.trees.generate_one(
|
|
29
|
+
filename=tree_filename, data=data, seed=int(rng.integers(0, 2**32 - 1))
|
|
30
|
+
)
|
|
31
|
+
self._generate_one_from_tree(
|
|
32
|
+
filename=filename, tree_file=f"{tree_filename}.nwk", rng=rng, data=data
|
|
33
|
+
)
|
|
34
|
+
os.remove(f"{tree_filename}.nwk")
|
|
@@ -67,9 +67,6 @@ class ReMASTERGenerator(TreesGenerator):
|
|
|
67
67
|
beast_path=self.beast_path,
|
|
68
68
|
)
|
|
69
69
|
|
|
70
|
-
def _generate_one(self, filename: str, rng: Generator, data: pgt.Data) -> None:
|
|
71
|
-
self._generate_one_from_extra_reactions(filename, rng, data, reactions=[])
|
|
72
|
-
|
|
73
70
|
|
|
74
71
|
class CanonicalReMASTERGenerator(ReMASTERGenerator):
|
|
75
72
|
parameterization: Literal[ParameterizationType.CANONICAL] = (
|
|
@@ -25,7 +25,7 @@ from phylogenie.core.trees.base import BackendType, TreesGenerator
|
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
class ParameterizationType(str, Enum):
|
|
28
|
-
|
|
28
|
+
MTBD = "MTBD"
|
|
29
29
|
BD = "BD"
|
|
30
30
|
BDEI = "BDEI"
|
|
31
31
|
|
|
@@ -70,10 +70,8 @@ class TreeSimulatorGenerator(TreesGenerator):
|
|
|
70
70
|
)
|
|
71
71
|
|
|
72
72
|
|
|
73
|
-
class
|
|
74
|
-
parameterization: Literal[ParameterizationType.
|
|
75
|
-
ParameterizationType.CANONICAL
|
|
76
|
-
)
|
|
73
|
+
class MTBDTreeSimulatorGenerator(TreeSimulatorGenerator):
|
|
74
|
+
parameterization: Literal[ParameterizationType.MTBD] = ParameterizationType.MTBD
|
|
77
75
|
populations: str | list[str] = DEFAULT_POPULATION
|
|
78
76
|
transition_rates: cfg.SkylineMatrixCoercibleConfig = 0
|
|
79
77
|
transmission_rates: cfg.SkylineMatrixCoercibleConfig = 0
|
|
@@ -158,8 +156,6 @@ class BDEITreeSimulatorGenerator(TreeSimulatorGenerator):
|
|
|
158
156
|
|
|
159
157
|
|
|
160
158
|
TreeSimulatorGeneratorConfig = Annotated[
|
|
161
|
-
|
|
162
|
-
| BDTreeSimulatorGenerator
|
|
163
|
-
| BDEITreeSimulatorGenerator,
|
|
159
|
+
MTBDTreeSimulatorGenerator | BDTreeSimulatorGenerator | BDEITreeSimulatorGenerator,
|
|
164
160
|
Field(discriminator="parameterization"),
|
|
165
161
|
]
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from typing import TypeGuard
|
|
2
2
|
|
|
3
3
|
import phylogenie.core.configs as cfg
|
|
4
|
+
import phylogenie.typings as pgt
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
def is_list(x: object) -> TypeGuard[list[object]]:
|
|
@@ -17,11 +18,15 @@ def is_list_of_skyline_parameter_like_configs(
|
|
|
17
18
|
return is_list(x) and all(isinstance(v, cfg.SkylineParameterLikeConfig) for v in x)
|
|
18
19
|
|
|
19
20
|
|
|
20
|
-
def
|
|
21
|
+
def is_skyline_vector_coercible_config(
|
|
21
22
|
x: object,
|
|
22
|
-
) -> TypeGuard[
|
|
23
|
-
return
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
) -> TypeGuard[cfg.SkylineVectorCoercibleConfig]:
|
|
24
|
+
return isinstance(
|
|
25
|
+
x, str | pgt.Scalar | cfg.SkylineVectorValueModel
|
|
26
|
+
) or is_list_of_skyline_parameter_like_configs(x)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def is_list_of_skyline_vector_coercible_configs(
|
|
30
|
+
x: object,
|
|
31
|
+
) -> TypeGuard[list[cfg.SkylineVectorCoercibleConfig]]:
|
|
32
|
+
return is_list(x) and all(is_skyline_vector_coercible_config(v) for v in x)
|
|
@@ -1,28 +1,24 @@
|
|
|
1
1
|
from collections.abc import Callable, Iterator
|
|
2
|
-
from typing import TypeGuard, Union
|
|
2
|
+
from typing import TypeGuard, Union, overload
|
|
3
3
|
|
|
4
4
|
import phylogenie.typeguards as tg
|
|
5
5
|
import phylogenie.typings as pgt
|
|
6
|
-
from phylogenie.skyline.parameter import
|
|
7
|
-
SkylineParameter,
|
|
8
|
-
SkylineParameterLike,
|
|
9
|
-
is_skyline_parameter_like,
|
|
10
|
-
skyline_parameter,
|
|
11
|
-
)
|
|
6
|
+
from phylogenie.skyline.parameter import SkylineParameter, is_skyline_parameter_like
|
|
12
7
|
from phylogenie.skyline.vector import (
|
|
13
8
|
SkylineVector,
|
|
9
|
+
SkylineVectorCoercible,
|
|
14
10
|
SkylineVectorLike,
|
|
15
11
|
SkylineVectorOperand,
|
|
12
|
+
is_many_skyline_vectors_coercible,
|
|
16
13
|
is_many_skyline_vectors_like,
|
|
14
|
+
is_skyline_vector_coercible,
|
|
17
15
|
is_skyline_vector_like,
|
|
18
16
|
is_skyline_vector_operand,
|
|
19
17
|
skyline_vector,
|
|
20
18
|
)
|
|
21
19
|
|
|
22
20
|
SkylineMatrixOperand = Union[SkylineVectorOperand, "SkylineMatrix"]
|
|
23
|
-
SkylineMatrixCoercible = Union[
|
|
24
|
-
SkylineParameterLike, pgt.Many[SkylineVectorLike], "SkylineMatrix"
|
|
25
|
-
]
|
|
21
|
+
SkylineMatrixCoercible = Union[pgt.OneOrMany[SkylineVectorCoercible], "SkylineMatrix"]
|
|
26
22
|
|
|
27
23
|
|
|
28
24
|
def is_skyline_matrix_operand(x: object) -> TypeGuard[SkylineMatrixOperand]:
|
|
@@ -43,7 +39,7 @@ class SkylineMatrix:
|
|
|
43
39
|
raise TypeError(
|
|
44
40
|
f"It is impossible to create a SkylineMatrix from `params` {params} of type {type(params)}. Please provide a sequence composed of SkylineVectorLike objects (a SkylineVectorLike object can either be a SkylineVector or a sequence of scalars and/or SkylineParameters)."
|
|
45
41
|
)
|
|
46
|
-
elif value is not None and change_times is not None:
|
|
42
|
+
elif params is None and value is not None and change_times is not None:
|
|
47
43
|
if tg.is_many_3D_scalars(value):
|
|
48
44
|
matrix_lengths = {len(matrix) for matrix in value}
|
|
49
45
|
if any(ml != len(value[0]) for ml in matrix_lengths):
|
|
@@ -80,45 +76,49 @@ class SkylineMatrix:
|
|
|
80
76
|
def get_value_at_time(self, time: pgt.Scalar) -> pgt.Vector2D:
|
|
81
77
|
return [param.get_value_at_time(time) for param in self.params]
|
|
82
78
|
|
|
83
|
-
def
|
|
79
|
+
def _operate(
|
|
84
80
|
self,
|
|
85
81
|
other: SkylineMatrixOperand,
|
|
86
82
|
func: Callable[
|
|
87
83
|
[SkylineVector, SkylineVector | SkylineParameter], SkylineVector
|
|
88
84
|
],
|
|
89
85
|
) -> "SkylineMatrix":
|
|
90
|
-
if not is_skyline_matrix_operand(other):
|
|
91
|
-
return NotImplemented
|
|
92
86
|
if is_skyline_vector_operand(other):
|
|
93
87
|
other = skyline_vector(other, N=self.N)
|
|
94
|
-
|
|
88
|
+
elif isinstance(other, SkylineMatrix):
|
|
89
|
+
if other.N != self.N:
|
|
90
|
+
raise ValueError(
|
|
91
|
+
f"Expected a SkylineMatrix with the same size as self (N={self.N}), but got {other} with N={other.N}."
|
|
92
|
+
)
|
|
93
|
+
else:
|
|
94
|
+
return NotImplemented
|
|
95
95
|
return SkylineMatrix(
|
|
96
96
|
[func(p1, p2) for p1, p2 in zip(self.params, other.params)]
|
|
97
97
|
)
|
|
98
98
|
|
|
99
99
|
def __add__(self, operand: SkylineMatrixOperand) -> "SkylineMatrix":
|
|
100
|
-
return self.
|
|
100
|
+
return self._operate(operand, lambda x, y: x + y)
|
|
101
101
|
|
|
102
102
|
def __radd__(self, operand: SkylineVectorOperand) -> "SkylineMatrix":
|
|
103
|
-
return self.
|
|
103
|
+
return self._operate(operand, lambda x, y: y + x)
|
|
104
104
|
|
|
105
105
|
def __sub__(self, operand: SkylineMatrixOperand) -> "SkylineMatrix":
|
|
106
|
-
return self.
|
|
106
|
+
return self._operate(operand, lambda x, y: x - y)
|
|
107
107
|
|
|
108
108
|
def __rsub__(self, operand: SkylineVectorOperand) -> "SkylineMatrix":
|
|
109
|
-
return self.
|
|
109
|
+
return self._operate(operand, lambda x, y: y - x)
|
|
110
110
|
|
|
111
111
|
def __mul__(self, operand: SkylineMatrixOperand) -> "SkylineMatrix":
|
|
112
|
-
return self.
|
|
112
|
+
return self._operate(operand, lambda x, y: x * y)
|
|
113
113
|
|
|
114
114
|
def __rmul__(self, operand: SkylineVectorOperand) -> "SkylineMatrix":
|
|
115
|
-
return self.
|
|
115
|
+
return self._operate(operand, lambda x, y: y * x)
|
|
116
116
|
|
|
117
117
|
def __truediv__(self, operand: SkylineMatrixOperand) -> "SkylineMatrix":
|
|
118
|
-
return self.
|
|
118
|
+
return self._operate(operand, lambda x, y: x / y)
|
|
119
119
|
|
|
120
120
|
def __rtruediv__(self, operand: SkylineVectorOperand) -> "SkylineMatrix":
|
|
121
|
-
return self.
|
|
121
|
+
return self._operate(operand, lambda x, y: y / x)
|
|
122
122
|
|
|
123
123
|
@property
|
|
124
124
|
def T(self) -> "SkylineMatrix":
|
|
@@ -139,7 +139,13 @@ class SkylineMatrix:
|
|
|
139
139
|
def __len__(self) -> int:
|
|
140
140
|
return self.N
|
|
141
141
|
|
|
142
|
-
|
|
142
|
+
@overload
|
|
143
|
+
def __getitem__(self, item: int) -> SkylineVector: ...
|
|
144
|
+
@overload
|
|
145
|
+
def __getitem__(self, item: slice) -> list[SkylineVector]: ...
|
|
146
|
+
def __getitem__(
|
|
147
|
+
self, item: int | slice
|
|
148
|
+
) -> Union[SkylineVector, list[SkylineVector]]:
|
|
143
149
|
return self.params[item]
|
|
144
150
|
|
|
145
151
|
def __setitem__(self, item: int, value: SkylineVectorLike) -> None:
|
|
@@ -153,20 +159,36 @@ class SkylineMatrix:
|
|
|
153
159
|
def skyline_matrix(
|
|
154
160
|
x: SkylineMatrixCoercible, N: int, zero_diagonal: bool = False
|
|
155
161
|
) -> SkylineMatrix:
|
|
156
|
-
if
|
|
157
|
-
|
|
162
|
+
if N <= 0:
|
|
163
|
+
raise ValueError(
|
|
164
|
+
f"N must be a positive integer for SkylineMatrix construction (got N={N})."
|
|
165
|
+
)
|
|
166
|
+
if is_skyline_vector_coercible(x):
|
|
167
|
+
x = SkylineMatrix([[p] * N for p in skyline_vector(x, N)])
|
|
158
168
|
if zero_diagonal:
|
|
159
169
|
for i in range(N):
|
|
160
170
|
x[i][i] = 0
|
|
161
171
|
return x
|
|
162
|
-
elif
|
|
163
|
-
x = SkylineMatrix(
|
|
172
|
+
elif is_many_skyline_vectors_coercible(x):
|
|
173
|
+
x = SkylineMatrix(
|
|
174
|
+
[
|
|
175
|
+
[
|
|
176
|
+
(
|
|
177
|
+
0
|
|
178
|
+
if i == j and is_skyline_parameter_like(v) and zero_diagonal
|
|
179
|
+
else p
|
|
180
|
+
)
|
|
181
|
+
for j, p in enumerate(skyline_vector(v, N))
|
|
182
|
+
]
|
|
183
|
+
for i, v in enumerate(x)
|
|
184
|
+
]
|
|
185
|
+
)
|
|
164
186
|
if not isinstance(x, SkylineMatrix):
|
|
165
187
|
raise TypeError(
|
|
166
188
|
f"It is impossible to coerce {x} of type {type(x)} into a SkylineMatrix. Please provide either:\n"
|
|
167
189
|
"- a SkylineMatrix,\n"
|
|
168
|
-
"- a
|
|
169
|
-
"- a sequence of
|
|
190
|
+
"- a SkylineVectorCoercible object (i.e., a scalar, a SkylineParameter, a SkylineVector, or a sequence of scalars and/or SkylineParameters),\n"
|
|
191
|
+
"- a sequence of SkylineVectorCoercible objects."
|
|
170
192
|
)
|
|
171
193
|
|
|
172
194
|
if x.N != N:
|
|
@@ -23,7 +23,7 @@ class SkylineParameter:
|
|
|
23
23
|
self,
|
|
24
24
|
value: pgt.OneOrManyScalars,
|
|
25
25
|
change_times: pgt.ManyScalars | None = None,
|
|
26
|
-
)
|
|
26
|
+
):
|
|
27
27
|
if isinstance(value, pgt.Scalar):
|
|
28
28
|
value = [value]
|
|
29
29
|
elif not tg.is_many_scalars(value):
|
|
@@ -42,23 +42,37 @@ class SkylineParameter:
|
|
|
42
42
|
raise ValueError(
|
|
43
43
|
f"`value` must have exactly one more element than `change_times` (got value={value} of length {len(value)} and change_times={change_times} of length {len(change_times)})."
|
|
44
44
|
)
|
|
45
|
+
if any(t1 >= t2 for t1, t2 in zip(change_times, change_times[1:])):
|
|
46
|
+
raise ValueError(
|
|
47
|
+
f"`change_times` must be sorted in strictly increasing order "
|
|
48
|
+
f"(got change_times={change_times})."
|
|
49
|
+
)
|
|
50
|
+
if any(t < 0 for t in change_times):
|
|
51
|
+
raise ValueError(
|
|
52
|
+
f"`change_times` must be non-negative (got change_times={change_times})."
|
|
53
|
+
)
|
|
45
54
|
|
|
46
55
|
self.value = [value[0]]
|
|
47
56
|
self.change_times: list[pgt.Scalar] = []
|
|
48
57
|
for i in range(1, len(value)):
|
|
49
58
|
if value[i] != value[i - 1]:
|
|
50
59
|
self.value.append(value[i])
|
|
51
|
-
self.
|
|
60
|
+
self.change_times.append(change_times[i - 1])
|
|
52
61
|
|
|
53
62
|
def get_value_at_time(self, t: pgt.Scalar) -> pgt.Scalar:
|
|
63
|
+
if t < 0:
|
|
64
|
+
raise ValueError(f"Time cannot be negative (got t={t}).")
|
|
54
65
|
return self.value[bisect_right(self.change_times, t)]
|
|
55
66
|
|
|
56
|
-
def
|
|
67
|
+
def _operate(
|
|
57
68
|
self,
|
|
58
69
|
other: SkylineParameterLike,
|
|
59
70
|
f: Callable[[pgt.Scalar, pgt.Scalar], pgt.Scalar],
|
|
60
71
|
) -> "SkylineParameter":
|
|
61
|
-
|
|
72
|
+
if is_skyline_parameter_like(other):
|
|
73
|
+
other = skyline_parameter(other)
|
|
74
|
+
else:
|
|
75
|
+
return NotImplemented
|
|
62
76
|
change_times = sorted(set(self.change_times + other.change_times))
|
|
63
77
|
value = [
|
|
64
78
|
f(self.get_value_at_time(t), other.get_value_at_time(t))
|
|
@@ -67,28 +81,28 @@ class SkylineParameter:
|
|
|
67
81
|
return SkylineParameter(value, change_times)
|
|
68
82
|
|
|
69
83
|
def __add__(self, other: SkylineParameterLike) -> "SkylineParameter":
|
|
70
|
-
return self.
|
|
84
|
+
return self._operate(other, lambda x, y: x + y)
|
|
71
85
|
|
|
72
86
|
def __radd__(self, other: pgt.Scalar) -> "SkylineParameter":
|
|
73
|
-
return self.
|
|
87
|
+
return self._operate(other, lambda x, y: y + x)
|
|
74
88
|
|
|
75
89
|
def __sub__(self, other: SkylineParameterLike) -> "SkylineParameter":
|
|
76
|
-
return self.
|
|
90
|
+
return self._operate(other, lambda x, y: x - y)
|
|
77
91
|
|
|
78
92
|
def __rsub__(self, other: pgt.Scalar) -> "SkylineParameter":
|
|
79
|
-
return self.
|
|
93
|
+
return self._operate(other, lambda x, y: y - x)
|
|
80
94
|
|
|
81
95
|
def __mul__(self, other: SkylineParameterLike) -> "SkylineParameter":
|
|
82
|
-
return self.
|
|
96
|
+
return self._operate(other, lambda x, y: x * y)
|
|
83
97
|
|
|
84
98
|
def __rmul__(self, other: pgt.Scalar) -> "SkylineParameter":
|
|
85
|
-
return self.
|
|
99
|
+
return self._operate(other, lambda x, y: y * x)
|
|
86
100
|
|
|
87
101
|
def __truediv__(self, other: SkylineParameterLike) -> "SkylineParameter":
|
|
88
|
-
return self.
|
|
102
|
+
return self._operate(other, lambda x, y: x / y)
|
|
89
103
|
|
|
90
104
|
def __rtruediv__(self, other: pgt.Scalar) -> "SkylineParameter":
|
|
91
|
-
return self.
|
|
105
|
+
return self._operate(other, lambda x, y: y / x)
|
|
92
106
|
|
|
93
107
|
def __bool__(self) -> bool:
|
|
94
108
|
return any(self.value)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from collections.abc import Callable, Iterator
|
|
2
|
-
from typing import TypeGuard, Union
|
|
2
|
+
from typing import TypeGuard, Union, overload
|
|
3
3
|
|
|
4
4
|
import phylogenie.typeguards as tg
|
|
5
5
|
import phylogenie.typings as pgt
|
|
@@ -24,17 +24,29 @@ def is_skyline_vector_like(x: object) -> TypeGuard[SkylineVectorLike]:
|
|
|
24
24
|
return isinstance(x, SkylineVector) or is_many_skyline_parameters_like(x)
|
|
25
25
|
|
|
26
26
|
|
|
27
|
+
def is_skyline_vector_coercible(
|
|
28
|
+
x: object,
|
|
29
|
+
) -> TypeGuard[SkylineVectorCoercible]:
|
|
30
|
+
return is_skyline_parameter_like(x) or is_skyline_vector_like(x)
|
|
31
|
+
|
|
32
|
+
|
|
27
33
|
def is_many_skyline_vectors_like(x: object) -> TypeGuard[pgt.Many[SkylineVectorLike]]:
|
|
28
34
|
return tg.is_many(x) and all(is_skyline_vector_like(v) for v in x)
|
|
29
35
|
|
|
30
36
|
|
|
37
|
+
def is_many_skyline_vectors_coercible(
|
|
38
|
+
x: object,
|
|
39
|
+
) -> TypeGuard[pgt.Many[SkylineVectorCoercible]]:
|
|
40
|
+
return tg.is_many(x) and all(is_skyline_vector_coercible(v) for v in x)
|
|
41
|
+
|
|
42
|
+
|
|
31
43
|
class SkylineVector:
|
|
32
44
|
def __init__(
|
|
33
45
|
self,
|
|
34
46
|
params: pgt.Many[SkylineParameterLike] | None = None,
|
|
35
47
|
value: pgt.Many2DScalars | None = None,
|
|
36
48
|
change_times: pgt.ManyScalars | None = None,
|
|
37
|
-
)
|
|
49
|
+
):
|
|
38
50
|
if params is not None and value is None and change_times is None:
|
|
39
51
|
if is_many_skyline_parameters_like(params):
|
|
40
52
|
self.params = [skyline_parameter(param) for param in params]
|
|
@@ -42,7 +54,7 @@ class SkylineVector:
|
|
|
42
54
|
raise TypeError(
|
|
43
55
|
f"It is impossible to create a SkylineVector from `params` {params} of type {type(params)}. Please provide a sequence of SkylineParameterLike objects (a SkylineParameterLike object can either be a SkylineParameter or a scalar)."
|
|
44
56
|
)
|
|
45
|
-
elif value is not None and change_times is not None:
|
|
57
|
+
elif params is None and value is not None and change_times is not None:
|
|
46
58
|
if tg.is_many_2D_scalars(value):
|
|
47
59
|
vector_lengths = {len(vector) for vector in value}
|
|
48
60
|
if any(vl != len(value[0]) for vl in vector_lengths):
|
|
@@ -77,7 +89,7 @@ class SkylineVector:
|
|
|
77
89
|
def get_value_at_time(self, t: pgt.Scalar) -> pgt.Vector1D:
|
|
78
90
|
return [param.get_value_at_time(t) for param in self.params]
|
|
79
91
|
|
|
80
|
-
def
|
|
92
|
+
def _operate(
|
|
81
93
|
self,
|
|
82
94
|
other: SkylineVectorOperand,
|
|
83
95
|
func: Callable[[SkylineParameter, SkylineParameter], SkylineParameter],
|
|
@@ -90,28 +102,28 @@ class SkylineVector:
|
|
|
90
102
|
)
|
|
91
103
|
|
|
92
104
|
def __add__(self, operand: SkylineVectorOperand) -> "SkylineVector":
|
|
93
|
-
return self.
|
|
105
|
+
return self._operate(operand, lambda x, y: x + y)
|
|
94
106
|
|
|
95
107
|
def __radd__(self, operand: SkylineParameterLike) -> "SkylineVector":
|
|
96
|
-
return self.
|
|
108
|
+
return self._operate(operand, lambda x, y: y + x)
|
|
97
109
|
|
|
98
110
|
def __sub__(self, operand: SkylineVectorOperand) -> "SkylineVector":
|
|
99
|
-
return self.
|
|
111
|
+
return self._operate(operand, lambda x, y: x - y)
|
|
100
112
|
|
|
101
113
|
def __rsub__(self, operand: SkylineParameterLike) -> "SkylineVector":
|
|
102
|
-
return self.
|
|
114
|
+
return self._operate(operand, lambda x, y: y - x)
|
|
103
115
|
|
|
104
116
|
def __mul__(self, operand: SkylineVectorOperand) -> "SkylineVector":
|
|
105
|
-
return self.
|
|
117
|
+
return self._operate(operand, lambda x, y: x * y)
|
|
106
118
|
|
|
107
119
|
def __rmul__(self, operand: SkylineParameterLike) -> "SkylineVector":
|
|
108
|
-
return self.
|
|
120
|
+
return self._operate(operand, lambda x, y: y * x)
|
|
109
121
|
|
|
110
122
|
def __truediv__(self, operand: SkylineVectorOperand) -> "SkylineVector":
|
|
111
|
-
return self.
|
|
123
|
+
return self._operate(operand, lambda x, y: x / y)
|
|
112
124
|
|
|
113
125
|
def __rtruediv__(self, operand: SkylineParameterLike) -> "SkylineVector":
|
|
114
|
-
return self.
|
|
126
|
+
return self._operate(operand, lambda x, y: y / x)
|
|
115
127
|
|
|
116
128
|
def __len__(self) -> int:
|
|
117
129
|
return self.N
|
|
@@ -128,7 +140,13 @@ class SkylineVector:
|
|
|
128
140
|
def __iter__(self) -> Iterator[SkylineParameter]:
|
|
129
141
|
return iter(self.params)
|
|
130
142
|
|
|
131
|
-
|
|
143
|
+
@overload
|
|
144
|
+
def __getitem__(self, item: int) -> SkylineParameter: ...
|
|
145
|
+
@overload
|
|
146
|
+
def __getitem__(self, item: slice) -> list[SkylineParameter]: ...
|
|
147
|
+
def __getitem__(
|
|
148
|
+
self, item: int | slice
|
|
149
|
+
) -> Union[SkylineParameter, list[SkylineParameter]]:
|
|
132
150
|
return self.params[item]
|
|
133
151
|
|
|
134
152
|
def __setitem__(self, item: int, value: SkylineParameterLike) -> None:
|
|
@@ -140,6 +158,10 @@ class SkylineVector:
|
|
|
140
158
|
|
|
141
159
|
|
|
142
160
|
def skyline_vector(x: SkylineVectorCoercible, N: int) -> SkylineVector:
|
|
161
|
+
if N <= 0:
|
|
162
|
+
raise ValueError(
|
|
163
|
+
f"N must be a positive integer for SkylineVector construction (got N={N})."
|
|
164
|
+
)
|
|
143
165
|
if is_skyline_parameter_like(x):
|
|
144
166
|
return SkylineVector([skyline_parameter(x)] * N)
|
|
145
167
|
elif is_many_skyline_parameters_like(x):
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
from numpy.random import Generator
|
|
2
|
-
|
|
3
|
-
import phylogenie.core.context.configs as cfg
|
|
4
|
-
import phylogenie.typings as pgt
|
|
5
|
-
from phylogenie.core.context import distributions
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
def _sample_vector1D(x: distributions.Scalar, N: int, rng: Generator) -> pgt.Vector1D:
|
|
9
|
-
return [x.sample(rng) for _ in range(N)]
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
def _sample_vector2D(
|
|
13
|
-
x: distributions.Scalar, N: int, zero_diagonal: bool, rng: Generator
|
|
14
|
-
) -> pgt.Vector2D:
|
|
15
|
-
v = [_sample_vector1D(x, N, rng) for _ in range(N)]
|
|
16
|
-
if zero_diagonal:
|
|
17
|
-
for i in range(N):
|
|
18
|
-
v[i][i] = 0
|
|
19
|
-
return v
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
def _sample_vector3D(
|
|
23
|
-
x: distributions.Scalar, N: int, T: int, zero_diagonal: bool, rng: Generator
|
|
24
|
-
) -> pgt.Vector3D:
|
|
25
|
-
return [_sample_vector2D(x, N, zero_diagonal, rng) for _ in range(T)]
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
def context_factory(x: cfg.ContextConfig, rng: Generator) -> pgt.Data:
|
|
29
|
-
data: pgt.Data = {}
|
|
30
|
-
for key, value in x.items():
|
|
31
|
-
if isinstance(value, distributions.Distribution):
|
|
32
|
-
data[key] = value.sample(rng)
|
|
33
|
-
elif isinstance(value, cfg.Vector1DModel):
|
|
34
|
-
data[key] = _sample_vector1D(value.x, value.N, rng)
|
|
35
|
-
elif isinstance(value, cfg.Vector2DModel):
|
|
36
|
-
data[key] = _sample_vector2D(value.x, value.N, value.zero_diagonal, rng)
|
|
37
|
-
else:
|
|
38
|
-
data[key] = _sample_vector3D(
|
|
39
|
-
value.x, value.N, value.T, value.zero_diagonal, rng
|
|
40
|
-
)
|
|
41
|
-
return data
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
from abc import abstractmethod
|
|
3
|
-
from enum import Enum
|
|
4
|
-
from pathlib import Path
|
|
5
|
-
from typing import Literal
|
|
6
|
-
|
|
7
|
-
from numpy.random import Generator
|
|
8
|
-
|
|
9
|
-
import phylogenie.typings as pgt
|
|
10
|
-
from phylogenie.core.dataset import DatasetGenerator, DataType
|
|
11
|
-
from phylogenie.core.trees import TreesGeneratorConfig
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class BackendType(str, Enum):
|
|
15
|
-
ALISIM = "alisim"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
class MSAsGenerator(DatasetGenerator):
|
|
19
|
-
data_type: Literal[DataType.MSAS] = DataType.MSAS
|
|
20
|
-
trees: str | TreesGeneratorConfig
|
|
21
|
-
output_trees_dir: str | None = None
|
|
22
|
-
|
|
23
|
-
@abstractmethod
|
|
24
|
-
def _generate_one_from_tree(
|
|
25
|
-
self, filename: str, tree_file: str, rng: Generator, data: pgt.Data
|
|
26
|
-
) -> None: ...
|
|
27
|
-
|
|
28
|
-
def _generate_one(self, filename: str, rng: Generator, data: pgt.Data) -> None:
|
|
29
|
-
if isinstance(self.trees, str):
|
|
30
|
-
tree_files = os.listdir(self.trees)
|
|
31
|
-
tree_file = os.path.join(self.trees, str(rng.choice(tree_files)))
|
|
32
|
-
self._generate_one_from_tree(
|
|
33
|
-
filename=filename, tree_file=tree_file, rng=rng, data=data
|
|
34
|
-
)
|
|
35
|
-
elif isinstance(self.output_trees_dir, str):
|
|
36
|
-
os.makedirs(self.output_trees_dir, exist_ok=True)
|
|
37
|
-
self._generate_one_from_tree(
|
|
38
|
-
filename=filename,
|
|
39
|
-
tree_file=os.path.join(self.output_trees_dir, f"{Path(filename).stem}"),
|
|
40
|
-
rng=rng,
|
|
41
|
-
data=data,
|
|
42
|
-
)
|
|
43
|
-
else:
|
|
44
|
-
tree_filename = f"{filename}.temp-tree"
|
|
45
|
-
self.trees.generate_one(
|
|
46
|
-
filename=tree_filename, data=data, seed=int(rng.integers(0, 2**32 - 1))
|
|
47
|
-
)
|
|
48
|
-
self._generate_one_from_tree(
|
|
49
|
-
filename=filename, tree_file=f"{tree_filename}.nwk", rng=rng, data=data
|
|
50
|
-
)
|
|
51
|
-
os.remove(f"{tree_filename}.nwk")
|
|
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
|