LineageTree 2.0.1__tar.gz → 2.0.3__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.
- {lineagetree-2.0.1/src/LineageTree.egg-info → lineagetree-2.0.3}/PKG-INFO +14 -36
- {lineagetree-2.0.1 → lineagetree-2.0.3}/README.md +13 -35
- {lineagetree-2.0.1 → lineagetree-2.0.3}/pyproject.toml +2 -2
- {lineagetree-2.0.1 → lineagetree-2.0.3}/src/LineageTree/__init__.py +1 -1
- {lineagetree-2.0.1 → lineagetree-2.0.3}/src/LineageTree/lineageTree.py +37 -11
- {lineagetree-2.0.1 → lineagetree-2.0.3}/src/LineageTree/lineageTreeManager.py +32 -23
- {lineagetree-2.0.1 → lineagetree-2.0.3}/src/LineageTree/loaders.py +10 -10
- {lineagetree-2.0.1 → lineagetree-2.0.3/src/LineageTree.egg-info}/PKG-INFO +14 -36
- {lineagetree-2.0.1 → lineagetree-2.0.3}/src/LineageTree.egg-info/SOURCES.txt +10 -1
- {lineagetree-2.0.1 → lineagetree-2.0.3}/LICENSE +0 -0
- {lineagetree-2.0.1 → lineagetree-2.0.3}/setup.cfg +0 -0
- {lineagetree-2.0.1 → lineagetree-2.0.3}/src/LineageTree/legacy/export_csv.py +0 -0
- {lineagetree-2.0.1 → lineagetree-2.0.3}/src/LineageTree/legacy/to_lineajea.py +0 -0
- {lineagetree-2.0.1 → lineagetree-2.0.3}/src/LineageTree/legacy/to_motile.py +0 -0
- {lineagetree-2.0.1 → lineagetree-2.0.3}/src/LineageTree/test/test_lineageTree.py +0 -0
- {lineagetree-2.0.1 → lineagetree-2.0.3}/src/LineageTree/test/test_uted.py +0 -0
- {lineagetree-2.0.1 → lineagetree-2.0.3}/src/LineageTree/tree_approximation.py +0 -0
- {lineagetree-2.0.1 → lineagetree-2.0.3}/src/LineageTree/utils.py +0 -0
- {lineagetree-2.0.1 → lineagetree-2.0.3}/src/LineageTree.egg-info/dependency_links.txt +0 -0
- {lineagetree-2.0.1 → lineagetree-2.0.3}/src/LineageTree.egg-info/requires.txt +0 -0
- {lineagetree-2.0.1 → lineagetree-2.0.3}/src/LineageTree.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: LineageTree
|
3
|
-
Version: 2.0.
|
3
|
+
Version: 2.0.3
|
4
4
|
Summary: Structure for Lineage Trees
|
5
5
|
Author: Giannis Liaskas, Christopher Mazzerbo
|
6
6
|
Author-email: Léo Guignard <leo.guignard@univ-amu.fr>
|
@@ -50,7 +50,7 @@ Dynamic: license-file
|
|
50
50
|
This library allows to import and work with cell (but not limited to cells) lineage trees.
|
51
51
|
With LineageTree you can read from:
|
52
52
|
|
53
|
-
- TGMM algorithm outputs described in [
|
53
|
+
- TGMM algorithm outputs described in [Amat et al. 2014](https://www.nature.com/articles/nmeth.3036)
|
54
54
|
- TrackMate files described in [Tinevez et al. 2017](https://doi.org/10.1016/j.ymeth.2016.09.016)
|
55
55
|
- MaMuT files described in [Wolff et al. 2018](https://doi.org/10.7554/eLife.34410)
|
56
56
|
- SVF algorithm outputs described in [McDole, Guignard et al. 2018](https://doi.org/10.1016/j.cell.2018.09.031)
|
@@ -71,66 +71,44 @@ and one can then load lineage trees the following way:
|
|
71
71
|
For `.lT` files:
|
72
72
|
|
73
73
|
```python
|
74
|
-
lT = lineageTree('path/to/file.lT')
|
74
|
+
lT = lineageTree.load('path/to/file.lT')
|
75
75
|
```
|
76
76
|
|
77
77
|
For ASTEC data:
|
78
78
|
|
79
79
|
```python
|
80
|
-
|
80
|
+
from LineageTree import read_from_ASTEC
|
81
|
+
lT = read_from_ASTEC('path/to/ASTEC.pkl')
|
81
82
|
```
|
82
83
|
|
83
|
-
or
|
84
|
+
For MaMuT or TrackMate:
|
84
85
|
|
85
86
|
```python
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
For SVF:
|
90
|
-
|
91
|
-
```python
|
92
|
-
lT = lineageTree('path/to/SVF.bin')
|
93
|
-
```
|
94
|
-
|
95
|
-
For MaMuT:
|
96
|
-
|
97
|
-
```python
|
98
|
-
lT = lineageTree('path/to/MaMuT.xml', file_type='MaMuT')
|
99
|
-
```
|
100
|
-
|
101
|
-
For TrackMate:
|
102
|
-
|
103
|
-
```python
|
104
|
-
lT = lineageTree('path/to/MaMuT.xml', file_type='TrackMate')
|
87
|
+
from LineageTree import read_from_mamut_xml
|
88
|
+
lT = read_from_mamut_xml('path/to/MaMuT.xml')
|
105
89
|
```
|
106
90
|
|
107
91
|
For TGMM:
|
108
92
|
|
109
93
|
```python
|
110
|
-
|
94
|
+
from LineageTree import read_from_tgmm_xml
|
95
|
+
lT = read_from_tgmm_xml('path/to/single_time_file{t:04d}.xml', tb=0, te=500)
|
111
96
|
```
|
112
97
|
|
113
98
|
For Mastodon:
|
114
99
|
|
115
100
|
```python
|
116
|
-
|
101
|
+
from LineageTree import read_from_mastodon
|
102
|
+
lT = read_from_mastodon('path/to/Mastodon.mastodon')
|
117
103
|
```
|
118
104
|
|
119
105
|
or, for Mastodon csv file:
|
120
106
|
|
121
107
|
```python
|
122
|
-
|
108
|
+
from LineageTree import read_from_mastodon_csv
|
109
|
+
lT = read_from_mastodon_csv(['path/to/nodes.csv', 'path/to/links.csv'])
|
123
110
|
```
|
124
111
|
|
125
|
-
## Dependencies
|
126
|
-
|
127
|
-
Some dependecies are requiered:
|
128
|
-
|
129
|
-
- general python dependecies:
|
130
|
-
- numpy, scipy
|
131
|
-
- specific dependency:
|
132
|
-
- svgwrite if svg output is needed
|
133
|
-
|
134
112
|
## Quick install
|
135
113
|
|
136
114
|
To quickly install the library together with its dependencies one can run:
|
@@ -3,7 +3,7 @@
|
|
3
3
|
This library allows to import and work with cell (but not limited to cells) lineage trees.
|
4
4
|
With LineageTree you can read from:
|
5
5
|
|
6
|
-
- TGMM algorithm outputs described in [
|
6
|
+
- TGMM algorithm outputs described in [Amat et al. 2014](https://www.nature.com/articles/nmeth.3036)
|
7
7
|
- TrackMate files described in [Tinevez et al. 2017](https://doi.org/10.1016/j.ymeth.2016.09.016)
|
8
8
|
- MaMuT files described in [Wolff et al. 2018](https://doi.org/10.7554/eLife.34410)
|
9
9
|
- SVF algorithm outputs described in [McDole, Guignard et al. 2018](https://doi.org/10.1016/j.cell.2018.09.031)
|
@@ -24,66 +24,44 @@ and one can then load lineage trees the following way:
|
|
24
24
|
For `.lT` files:
|
25
25
|
|
26
26
|
```python
|
27
|
-
lT = lineageTree('path/to/file.lT')
|
27
|
+
lT = lineageTree.load('path/to/file.lT')
|
28
28
|
```
|
29
29
|
|
30
30
|
For ASTEC data:
|
31
31
|
|
32
32
|
```python
|
33
|
-
|
33
|
+
from LineageTree import read_from_ASTEC
|
34
|
+
lT = read_from_ASTEC('path/to/ASTEC.pkl')
|
34
35
|
```
|
35
36
|
|
36
|
-
or
|
37
|
+
For MaMuT or TrackMate:
|
37
38
|
|
38
39
|
```python
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
For SVF:
|
43
|
-
|
44
|
-
```python
|
45
|
-
lT = lineageTree('path/to/SVF.bin')
|
46
|
-
```
|
47
|
-
|
48
|
-
For MaMuT:
|
49
|
-
|
50
|
-
```python
|
51
|
-
lT = lineageTree('path/to/MaMuT.xml', file_type='MaMuT')
|
52
|
-
```
|
53
|
-
|
54
|
-
For TrackMate:
|
55
|
-
|
56
|
-
```python
|
57
|
-
lT = lineageTree('path/to/MaMuT.xml', file_type='TrackMate')
|
40
|
+
from LineageTree import read_from_mamut_xml
|
41
|
+
lT = read_from_mamut_xml('path/to/MaMuT.xml')
|
58
42
|
```
|
59
43
|
|
60
44
|
For TGMM:
|
61
45
|
|
62
46
|
```python
|
63
|
-
|
47
|
+
from LineageTree import read_from_tgmm_xml
|
48
|
+
lT = read_from_tgmm_xml('path/to/single_time_file{t:04d}.xml', tb=0, te=500)
|
64
49
|
```
|
65
50
|
|
66
51
|
For Mastodon:
|
67
52
|
|
68
53
|
```python
|
69
|
-
|
54
|
+
from LineageTree import read_from_mastodon
|
55
|
+
lT = read_from_mastodon('path/to/Mastodon.mastodon')
|
70
56
|
```
|
71
57
|
|
72
58
|
or, for Mastodon csv file:
|
73
59
|
|
74
60
|
```python
|
75
|
-
|
61
|
+
from LineageTree import read_from_mastodon_csv
|
62
|
+
lT = read_from_mastodon_csv(['path/to/nodes.csv', 'path/to/links.csv'])
|
76
63
|
```
|
77
64
|
|
78
|
-
## Dependencies
|
79
|
-
|
80
|
-
Some dependecies are requiered:
|
81
|
-
|
82
|
-
- general python dependecies:
|
83
|
-
- numpy, scipy
|
84
|
-
- specific dependency:
|
85
|
-
- svgwrite if svg output is needed
|
86
|
-
|
87
65
|
## Quick install
|
88
66
|
|
89
67
|
To quickly install the library together with its dependencies one can run:
|
@@ -16,7 +16,7 @@ maintainers = [
|
|
16
16
|
]
|
17
17
|
name = "LineageTree"
|
18
18
|
description = "Structure for Lineage Trees"
|
19
|
-
version = "2.0.
|
19
|
+
version = "2.0.3"
|
20
20
|
license = "MIT"
|
21
21
|
license-files = [ "LICENSE" ]
|
22
22
|
readme = {file = "README.md", content-type = "text/markdown"}
|
@@ -76,7 +76,7 @@ profile = "black"
|
|
76
76
|
line_length = 79
|
77
77
|
|
78
78
|
[tool.bumpver]
|
79
|
-
current_version = "2.0.
|
79
|
+
current_version = "2.0.3"
|
80
80
|
version_pattern = "MAJOR.MINOR.PATCH[-TAG]"
|
81
81
|
commit_message = "bump version {old_version} -> {new_version}"
|
82
82
|
commit = true
|
@@ -29,6 +29,7 @@ from scipy.interpolate import InterpolatedUnivariateSpline
|
|
29
29
|
from scipy.sparse import dok_array
|
30
30
|
from scipy.spatial import Delaunay, KDTree, distance
|
31
31
|
|
32
|
+
from . import __version__
|
32
33
|
from .tree_approximation import TreeApproximationTemplate, tree_style
|
33
34
|
from .utils import (
|
34
35
|
convert_style_to_number,
|
@@ -306,7 +307,6 @@ class lineageTree:
|
|
306
307
|
"predecessor",
|
307
308
|
"_successor",
|
308
309
|
"_predecessor",
|
309
|
-
"_time",
|
310
310
|
]:
|
311
311
|
attr_value.pop(node, ())
|
312
312
|
if self._predecessor.get(node):
|
@@ -356,6 +356,10 @@ class lineageTree:
|
|
356
356
|
"""Nodes of the tree"""
|
357
357
|
return frozenset(self._successor.keys())
|
358
358
|
|
359
|
+
@dynamic_property
|
360
|
+
def number_of_nodes(self) -> int:
|
361
|
+
return len(self.nodes)
|
362
|
+
|
359
363
|
@dynamic_property
|
360
364
|
def depth(self) -> dict[int, int]:
|
361
365
|
"""The depth of each node in the tree."""
|
@@ -966,7 +970,7 @@ class lineageTree:
|
|
966
970
|
fname : str
|
967
971
|
path to and name of the file to save
|
968
972
|
"""
|
969
|
-
if os.path.splitext(fname)[-1] != ".
|
973
|
+
if os.path.splitext(fname)[-1].upper() != ".LT":
|
970
974
|
fname = os.path.extsep.join((fname, "lT"))
|
971
975
|
if hasattr(self, "_protected_predecessor"):
|
972
976
|
del self._protected_predecessor
|
@@ -1001,7 +1005,7 @@ class lineageTree:
|
|
1001
1005
|
properties = {
|
1002
1006
|
prop_name: prop
|
1003
1007
|
for prop_name, prop in lT.__dict__.items()
|
1004
|
-
if isinstance(prop, dict)
|
1008
|
+
if (isinstance(prop, dict) or prop_name == "_time_resolution")
|
1005
1009
|
and prop_name
|
1006
1010
|
not in [
|
1007
1011
|
"successor",
|
@@ -1016,7 +1020,6 @@ class lineageTree:
|
|
1016
1020
|
+ lineageTree._dynamic_properties
|
1017
1021
|
+ lineageTree._protected_dynamic_properties
|
1018
1022
|
}
|
1019
|
-
print("_comparisons" in properties)
|
1020
1023
|
lT = lineageTree(
|
1021
1024
|
successor=lT._successor,
|
1022
1025
|
time=lT._time,
|
@@ -2670,7 +2673,7 @@ class lineageTree:
|
|
2670
2673
|
self,
|
2671
2674
|
t: int,
|
2672
2675
|
r: int | Iterable[int] | None = None,
|
2673
|
-
) -> list:
|
2676
|
+
) -> list[int]:
|
2674
2677
|
"""
|
2675
2678
|
Returns the list of nodes at time `t` that are spawn by the node(s) `r`.
|
2676
2679
|
|
@@ -2683,8 +2686,8 @@ class lineageTree:
|
|
2683
2686
|
|
2684
2687
|
Returns
|
2685
2688
|
-------
|
2686
|
-
list
|
2687
|
-
list of nodes at time `t` spawned by `r`
|
2689
|
+
list of int
|
2690
|
+
list of ids of the nodes at time `t` spawned by `r`
|
2688
2691
|
"""
|
2689
2692
|
if not r and r != 0:
|
2690
2693
|
r = {root for root in self.roots if self.time[root] <= t}
|
@@ -3351,6 +3354,25 @@ class lineageTree:
|
|
3351
3354
|
|
3352
3355
|
return distance, fig
|
3353
3356
|
|
3357
|
+
def get_subtree(self, node_list: set[int]) -> lineageTree:
|
3358
|
+
new_successors = {
|
3359
|
+
n: tuple(vi for vi in self.successor[n] if vi in node_list)
|
3360
|
+
for n in node_list
|
3361
|
+
}
|
3362
|
+
return lineageTree(
|
3363
|
+
successor=new_successors,
|
3364
|
+
time=self._time,
|
3365
|
+
pos=self.pos,
|
3366
|
+
name=self.name,
|
3367
|
+
root_leaf_value=[
|
3368
|
+
(),
|
3369
|
+
],
|
3370
|
+
**{
|
3371
|
+
name: self.__dict__[name]
|
3372
|
+
for name in self._custom_property_list
|
3373
|
+
},
|
3374
|
+
)
|
3375
|
+
|
3354
3376
|
def __init__(
|
3355
3377
|
self,
|
3356
3378
|
*,
|
@@ -3388,7 +3410,7 @@ class lineageTree:
|
|
3388
3410
|
Supported keyword arguments are dictionaries assigning nodes to any custom property.
|
3389
3411
|
The property must be specified for every node, and named differently from lineageTree's own attributes.
|
3390
3412
|
"""
|
3391
|
-
self.__version__ =
|
3413
|
+
self.__version__ = __version__
|
3392
3414
|
self.name = str(name) if name is not None else None
|
3393
3415
|
if successor is not None and predecessor is not None:
|
3394
3416
|
raise ValueError(
|
@@ -3457,7 +3479,7 @@ class lineageTree:
|
|
3457
3479
|
"Cycles were found in the tree, there should not be any."
|
3458
3480
|
)
|
3459
3481
|
|
3460
|
-
if pos is None:
|
3482
|
+
if pos is None or len(pos) == 0:
|
3461
3483
|
self.pos = {}
|
3462
3484
|
else:
|
3463
3485
|
if self.nodes.difference(pos) != set():
|
@@ -3465,7 +3487,9 @@ class lineageTree:
|
|
3465
3487
|
self.pos = {
|
3466
3488
|
node: np.array(position) for node, position in pos.items()
|
3467
3489
|
}
|
3468
|
-
|
3490
|
+
if "labels" in kwargs:
|
3491
|
+
self._labels = kwargs["labels"]
|
3492
|
+
kwargs.pop("labels")
|
3469
3493
|
if time is None:
|
3470
3494
|
if starting_time is None:
|
3471
3495
|
starting_time = 0
|
@@ -3474,7 +3498,7 @@ class lineageTree:
|
|
3474
3498
|
f"Attribute `starting_time` was a `{type(starting_time)}`, has been casted as an `int`.",
|
3475
3499
|
stacklevel=2,
|
3476
3500
|
)
|
3477
|
-
self._time =
|
3501
|
+
self._time = dict.fromkeys(self.roots, starting_time)
|
3478
3502
|
queue = list(self.roots)
|
3479
3503
|
for node in queue:
|
3480
3504
|
for succ in self._successor[node]:
|
@@ -3513,6 +3537,7 @@ class lineageTree:
|
|
3513
3537
|
"Provided times are not strictly increasing. Setting times to default."
|
3514
3538
|
)
|
3515
3539
|
# custom properties
|
3540
|
+
self._custom_property_list = []
|
3516
3541
|
for name, d in kwargs.items():
|
3517
3542
|
if name in self.__dict__:
|
3518
3543
|
warnings.warn(
|
@@ -3520,5 +3545,6 @@ class lineageTree:
|
|
3520
3545
|
)
|
3521
3546
|
continue
|
3522
3547
|
setattr(self, name, d)
|
3548
|
+
self._custom_property_list.append(name)
|
3523
3549
|
if not hasattr(self, "_comparisons"):
|
3524
3550
|
self._comparisons = {}
|
@@ -3,7 +3,7 @@ from __future__ import annotations
|
|
3
3
|
import os
|
4
4
|
import pickle as pkl
|
5
5
|
import warnings
|
6
|
-
from collections.abc import Callable
|
6
|
+
from collections.abc import Callable, Generator, Iterable
|
7
7
|
from functools import partial
|
8
8
|
from typing import TYPE_CHECKING, Literal
|
9
9
|
|
@@ -35,17 +35,26 @@ if TYPE_CHECKING:
|
|
35
35
|
class lineageTreeManager:
|
36
36
|
norm_dict = {"max": max, "sum": sum, None: lambda x: 1}
|
37
37
|
|
38
|
-
def __init__(self):
|
39
|
-
|
40
|
-
|
41
|
-
self.registered = {}
|
42
|
-
self._comparisons = {}
|
38
|
+
def __init__(self, lineagetree_list: Iterable[lineageTree] = ()):
|
39
|
+
"""Creates a lineageTreeManager
|
40
|
+
:TODO: write the docstring
|
43
41
|
|
44
|
-
|
42
|
+
Parameters
|
43
|
+
----------
|
44
|
+
lineagetree_list: Iterable of lineageTree
|
45
|
+
List of lineage trees to be in the lineageTreeManager
|
46
|
+
"""
|
47
|
+
self.lineagetrees: dict[str, lineageTree] = {}
|
48
|
+
self.lineageTree_counter: int = 0
|
49
|
+
self._comparisons: dict = {}
|
50
|
+
for lT in lineagetree_list:
|
51
|
+
self.add(lT)
|
52
|
+
|
53
|
+
def __next__(self) -> int:
|
45
54
|
self.lineageTree_counter += 1
|
46
55
|
return self.lineageTree_counter - 1
|
47
56
|
|
48
|
-
def __len__(self):
|
57
|
+
def __len__(self) -> int:
|
49
58
|
"""Returns how many lineagetrees are in the manager.
|
50
59
|
|
51
60
|
Returns
|
@@ -55,12 +64,10 @@ class lineageTreeManager:
|
|
55
64
|
"""
|
56
65
|
return len(self.lineagetrees)
|
57
66
|
|
58
|
-
def __iter__(
|
59
|
-
self,
|
60
|
-
):
|
67
|
+
def __iter__(self) -> Generator[tuple[str, lineageTree]]:
|
61
68
|
yield from self.lineagetrees.items()
|
62
69
|
|
63
|
-
def __getitem__(self, key):
|
70
|
+
def __getitem__(self, key: str) -> lineageTree:
|
64
71
|
if key in self.lineagetrees:
|
65
72
|
return self.lineagetrees[key]
|
66
73
|
else:
|
@@ -122,7 +129,7 @@ class lineageTreeManager:
|
|
122
129
|
"Please add a LineageTree object or add time resolution to the LineageTree added."
|
123
130
|
)
|
124
131
|
|
125
|
-
def __add__(self, other):
|
132
|
+
def __add__(self, other: lineageTree):
|
126
133
|
self.add(other)
|
127
134
|
|
128
135
|
def write(self, fname: str):
|
@@ -133,13 +140,20 @@ class lineageTreeManager:
|
|
133
140
|
fname : str
|
134
141
|
The path and name of the file that is to be saved.
|
135
142
|
"""
|
136
|
-
if os.path.splitext(fname)[-1] != ".
|
137
|
-
fname = os.path.extsep.join((fname, "
|
143
|
+
if os.path.splitext(fname)[-1].upper() != ".LTM":
|
144
|
+
fname = os.path.extsep.join((fname, "lTM"))
|
145
|
+
for _, lT in self:
|
146
|
+
if hasattr(lT, "_protected_predecessor"):
|
147
|
+
del lT._protected_predecessor
|
148
|
+
if hasattr(lT, "_protected_successor"):
|
149
|
+
del lT._protected_successor
|
150
|
+
if hasattr(lT, "_protected_time"):
|
151
|
+
del lT._protected_time
|
138
152
|
with open(fname, "bw") as f:
|
139
153
|
pkl.dump(self, f)
|
140
154
|
f.close()
|
141
155
|
|
142
|
-
def remove_embryo(self, key):
|
156
|
+
def remove_embryo(self, key: str):
|
143
157
|
"""Removes the embryo from the manager.
|
144
158
|
|
145
159
|
Parameters
|
@@ -414,14 +428,9 @@ class lineageTreeManager:
|
|
414
428
|
-------
|
415
429
|
Alignment
|
416
430
|
The alignment between the nodes by the subtrees spawned by the nodes n1,n2 and the normalization function.`
|
417
|
-
|
418
|
-
ΟΡ
|
419
|
-
--
|
420
|
-
|
421
|
-
Alignment
|
422
|
-
The alignment between the nodes by the subtrees spawned by the nodes n1,n2 and the normalization function.`
|
423
|
-
tuple(tree,tree)
|
431
|
+
tuple(tree,tree), optional
|
424
432
|
The two trees that have been mapped to each other.
|
433
|
+
Returned if `return_norms` is `True`
|
425
434
|
"""
|
426
435
|
|
427
436
|
parameters = (
|
@@ -146,14 +146,14 @@ def read_from_csv(
|
|
146
146
|
id_, t, z, y, x, *_ = line
|
147
147
|
pred = None
|
148
148
|
t = int(t)
|
149
|
-
|
149
|
+
positions = np.array([x, y, z])
|
150
150
|
C = unique_id
|
151
151
|
corres[id_] = C
|
152
|
-
|
152
|
+
positions[-1] = positions[-1] * z_mult
|
153
153
|
if pred in corres:
|
154
154
|
M = corres[pred]
|
155
155
|
successor.setdefault(M, []).append(C)
|
156
|
-
pos[C] =
|
156
|
+
pos[C] = positions
|
157
157
|
time[C] = t
|
158
158
|
if not name:
|
159
159
|
tmp_name = Path(file_path).stem
|
@@ -393,7 +393,7 @@ def read_from_binary(fname: str, name: None | str = None) -> lineageTree:
|
|
393
393
|
)
|
394
394
|
)
|
395
395
|
)
|
396
|
-
is_root =
|
396
|
+
is_root = dict.fromkeys(tmp, True)
|
397
397
|
done = True
|
398
398
|
while (
|
399
399
|
i < len(number_sequence) and not done
|
@@ -635,7 +635,7 @@ def read_from_txt_for_celegans_BAO(
|
|
635
635
|
ids = list(range(unique_id, unique_id + len(lc)))
|
636
636
|
successor.update({ids[i]: [ids[i + 1]] for i in range(len(ids) - 1)})
|
637
637
|
properties["expression"].update(dict(zip(ids, lc, strict=True)))
|
638
|
-
properties["_labels"].update(
|
638
|
+
properties["_labels"].update(dict.fromkeys(ids, c))
|
639
639
|
to_link[c] = (unique_id, unique_id + len(lc) - 1)
|
640
640
|
unique_id += len(lc)
|
641
641
|
|
@@ -706,7 +706,7 @@ def read_from_tgmm_xml(
|
|
706
706
|
root = tree.getroot()
|
707
707
|
for unique_id, it in enumerate(root):
|
708
708
|
if "-1.#IND" not in it.attrib["m"] and "nan" not in it.attrib["m"]:
|
709
|
-
M_id,
|
709
|
+
M_id, positions, cell_id, svIdx, lin_id = (
|
710
710
|
int(it.attrib["parent"]),
|
711
711
|
[float(v) for v in it.attrib["m"].split(" ") if v != ""],
|
712
712
|
int(it.attrib["id"]),
|
@@ -729,13 +729,13 @@ def read_from_tgmm_xml(
|
|
729
729
|
float(it.attrib["nu"]),
|
730
730
|
float(it.attrib["alphaPrior"]),
|
731
731
|
)
|
732
|
-
|
732
|
+
positions = np.array(positions)
|
733
733
|
C = unique_id
|
734
|
-
|
734
|
+
positions[-1] = positions[-1] * z_mult
|
735
735
|
if (t - 1, M_id) in time_id:
|
736
736
|
M = time_id[(t - 1, M_id)]
|
737
737
|
successor.setdefault(M, []).append(C)
|
738
|
-
pos[C] =
|
738
|
+
pos[C] = positions
|
739
739
|
time_id[(t, cell_id)] = C
|
740
740
|
time[C] = t
|
741
741
|
properties["svIdx"][C] = svIdx
|
@@ -745,7 +745,7 @@ def read_from_tgmm_xml(
|
|
745
745
|
tmp = list(np.array(W) * nu)
|
746
746
|
W[C] = np.array(W).reshape(3, 3)
|
747
747
|
properties["coeffs"][C] = (
|
748
|
-
tmp[:3] + tmp[4:6] + tmp[8:9] + list(
|
748
|
+
tmp[:3] + tmp[4:6] + tmp[8:9] + list(positions)
|
749
749
|
)
|
750
750
|
if not name:
|
751
751
|
tmp_name = Path(file_format).stem
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: LineageTree
|
3
|
-
Version: 2.0.
|
3
|
+
Version: 2.0.3
|
4
4
|
Summary: Structure for Lineage Trees
|
5
5
|
Author: Giannis Liaskas, Christopher Mazzerbo
|
6
6
|
Author-email: Léo Guignard <leo.guignard@univ-amu.fr>
|
@@ -50,7 +50,7 @@ Dynamic: license-file
|
|
50
50
|
This library allows to import and work with cell (but not limited to cells) lineage trees.
|
51
51
|
With LineageTree you can read from:
|
52
52
|
|
53
|
-
- TGMM algorithm outputs described in [
|
53
|
+
- TGMM algorithm outputs described in [Amat et al. 2014](https://www.nature.com/articles/nmeth.3036)
|
54
54
|
- TrackMate files described in [Tinevez et al. 2017](https://doi.org/10.1016/j.ymeth.2016.09.016)
|
55
55
|
- MaMuT files described in [Wolff et al. 2018](https://doi.org/10.7554/eLife.34410)
|
56
56
|
- SVF algorithm outputs described in [McDole, Guignard et al. 2018](https://doi.org/10.1016/j.cell.2018.09.031)
|
@@ -71,66 +71,44 @@ and one can then load lineage trees the following way:
|
|
71
71
|
For `.lT` files:
|
72
72
|
|
73
73
|
```python
|
74
|
-
lT = lineageTree('path/to/file.lT')
|
74
|
+
lT = lineageTree.load('path/to/file.lT')
|
75
75
|
```
|
76
76
|
|
77
77
|
For ASTEC data:
|
78
78
|
|
79
79
|
```python
|
80
|
-
|
80
|
+
from LineageTree import read_from_ASTEC
|
81
|
+
lT = read_from_ASTEC('path/to/ASTEC.pkl')
|
81
82
|
```
|
82
83
|
|
83
|
-
or
|
84
|
+
For MaMuT or TrackMate:
|
84
85
|
|
85
86
|
```python
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
For SVF:
|
90
|
-
|
91
|
-
```python
|
92
|
-
lT = lineageTree('path/to/SVF.bin')
|
93
|
-
```
|
94
|
-
|
95
|
-
For MaMuT:
|
96
|
-
|
97
|
-
```python
|
98
|
-
lT = lineageTree('path/to/MaMuT.xml', file_type='MaMuT')
|
99
|
-
```
|
100
|
-
|
101
|
-
For TrackMate:
|
102
|
-
|
103
|
-
```python
|
104
|
-
lT = lineageTree('path/to/MaMuT.xml', file_type='TrackMate')
|
87
|
+
from LineageTree import read_from_mamut_xml
|
88
|
+
lT = read_from_mamut_xml('path/to/MaMuT.xml')
|
105
89
|
```
|
106
90
|
|
107
91
|
For TGMM:
|
108
92
|
|
109
93
|
```python
|
110
|
-
|
94
|
+
from LineageTree import read_from_tgmm_xml
|
95
|
+
lT = read_from_tgmm_xml('path/to/single_time_file{t:04d}.xml', tb=0, te=500)
|
111
96
|
```
|
112
97
|
|
113
98
|
For Mastodon:
|
114
99
|
|
115
100
|
```python
|
116
|
-
|
101
|
+
from LineageTree import read_from_mastodon
|
102
|
+
lT = read_from_mastodon('path/to/Mastodon.mastodon')
|
117
103
|
```
|
118
104
|
|
119
105
|
or, for Mastodon csv file:
|
120
106
|
|
121
107
|
```python
|
122
|
-
|
108
|
+
from LineageTree import read_from_mastodon_csv
|
109
|
+
lT = read_from_mastodon_csv(['path/to/nodes.csv', 'path/to/links.csv'])
|
123
110
|
```
|
124
111
|
|
125
|
-
## Dependencies
|
126
|
-
|
127
|
-
Some dependecies are requiered:
|
128
|
-
|
129
|
-
- general python dependecies:
|
130
|
-
- numpy, scipy
|
131
|
-
- specific dependency:
|
132
|
-
- svgwrite if svg output is needed
|
133
|
-
|
134
112
|
## Quick install
|
135
113
|
|
136
114
|
To quickly install the library together with its dependencies one can run:
|
@@ -16,4 +16,13 @@ src/LineageTree/legacy/export_csv.py
|
|
16
16
|
src/LineageTree/legacy/to_lineajea.py
|
17
17
|
src/LineageTree/legacy/to_motile.py
|
18
18
|
src/LineageTree/test/test_lineageTree.py
|
19
|
-
src/LineageTree/test/test_uted.py
|
19
|
+
src/LineageTree/test/test_uted.py
|
20
|
+
src/lineagetree/__init__.py
|
21
|
+
src/lineagetree/tree_approximation.py
|
22
|
+
src/lineagetree.egg-info/PKG-INFO
|
23
|
+
src/lineagetree.egg-info/SOURCES.txt
|
24
|
+
src/lineagetree.egg-info/dependency_links.txt
|
25
|
+
src/lineagetree.egg-info/requires.txt
|
26
|
+
src/lineagetree.egg-info/top_level.txt
|
27
|
+
src/lineagetree/test/test_lineageTree.py
|
28
|
+
src/lineagetree/test/test_uted.py
|
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
|