LineageTree 1.4.2__tar.gz → 1.4.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-1.4.2/src/LineageTree.egg-info → LineageTree-1.4.3}/PKG-INFO +8 -3
- {LineageTree-1.4.2 → LineageTree-1.4.3}/README.md +6 -0
- {LineageTree-1.4.2 → LineageTree-1.4.3}/pyproject.toml +1 -1
- {LineageTree-1.4.2 → LineageTree-1.4.3}/setup.cfg +1 -2
- {LineageTree-1.4.2 → LineageTree-1.4.3}/src/LineageTree/__init__.py +1 -1
- {LineageTree-1.4.2 → LineageTree-1.4.3}/src/LineageTree/lineageTree.py +70 -13
- {LineageTree-1.4.2 → LineageTree-1.4.3/src/LineageTree.egg-info}/PKG-INFO +8 -3
- {LineageTree-1.4.2 → LineageTree-1.4.3}/src/LineageTree.egg-info/requires.txt +1 -3
- {LineageTree-1.4.2 → LineageTree-1.4.3}/test/test_lineageTree.py +5 -0
- {LineageTree-1.4.2 → LineageTree-1.4.3}/LICENSE +0 -0
- {LineageTree-1.4.2 → LineageTree-1.4.3}/src/LineageTree.egg-info/SOURCES.txt +0 -0
- {LineageTree-1.4.2 → LineageTree-1.4.3}/src/LineageTree.egg-info/dependency_links.txt +0 -0
- {LineageTree-1.4.2 → LineageTree-1.4.3}/src/LineageTree.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: LineageTree
|
3
|
-
Version: 1.4.
|
3
|
+
Version: 1.4.3
|
4
4
|
Summary: Lineage tree structure
|
5
5
|
Home-page: https://github.com/leoguignard/LineageTree
|
6
6
|
Author: Léo Guignard
|
@@ -35,10 +35,9 @@ Requires-Dist: matplotlib; extra == "test"
|
|
35
35
|
Requires-Dist: tox; extra == "test"
|
36
36
|
Requires-Dist: pytest; extra == "test"
|
37
37
|
Requires-Dist: pytest-cov; extra == "test"
|
38
|
+
Requires-Dist: mastodon-reader; extra == "test"
|
38
39
|
Provides-Extra: treeedit
|
39
40
|
Requires-Dist: edist; extra == "treeedit"
|
40
|
-
Provides-Extra: mastodon
|
41
|
-
Requires-Dist: mastodon-reader; extra == "mastodon"
|
42
41
|
Provides-Extra: all
|
43
42
|
Requires-Dist: svgwrite; extra == "all"
|
44
43
|
Requires-Dist: matplotlib; extra == "all"
|
@@ -77,6 +76,12 @@ from LineageTree import lineageTree
|
|
77
76
|
|
78
77
|
and one can then load lineage trees the following way:
|
79
78
|
|
79
|
+
For `.lT` files:
|
80
|
+
|
81
|
+
```python
|
82
|
+
lT = lineageTree('path/to/file.lT')
|
83
|
+
```
|
84
|
+
|
80
85
|
For ASTEC data:
|
81
86
|
|
82
87
|
```python
|
@@ -70,6 +70,21 @@ class lineageTree:
|
|
70
70
|
self.time[C_next] = t
|
71
71
|
return C_next
|
72
72
|
|
73
|
+
def remove_track(self, track: list):
|
74
|
+
self.nodes.difference_update(track)
|
75
|
+
times = {self.time[n] for n in track}
|
76
|
+
for t in times:
|
77
|
+
self.time_nodes[t] = list(
|
78
|
+
set(self.time_nodes[t]).difference(track)
|
79
|
+
)
|
80
|
+
for i, c in enumerate(track):
|
81
|
+
self.pos.pop(c)
|
82
|
+
if i != 0:
|
83
|
+
self.predecessor.pop(c)
|
84
|
+
if i < len(track) - 1:
|
85
|
+
self.successor.pop(c)
|
86
|
+
self.time.pop(c)
|
87
|
+
|
73
88
|
def remove_node(self, c: int) -> tuple:
|
74
89
|
"""Removes a node and update the lineageTree accordingly
|
75
90
|
|
@@ -139,6 +154,10 @@ class lineageTree:
|
|
139
154
|
self._roots = set(self.successor).difference(self.predecessor)
|
140
155
|
return self._roots
|
141
156
|
|
157
|
+
@property
|
158
|
+
def leaves(self):
|
159
|
+
return set(self.predecessor).difference(self.successor)
|
160
|
+
|
142
161
|
def _write_header_am(self, f: TextIO, nb_points: int, length: int):
|
143
162
|
"""Header for Amira .am files"""
|
144
163
|
f.write("# AmiraMesh 3D ASCII 2.0\n")
|
@@ -729,7 +748,7 @@ class lineageTree:
|
|
729
748
|
|
730
749
|
if node_properties:
|
731
750
|
for p_name, (p_dict, default) in node_properties.items():
|
732
|
-
if
|
751
|
+
if isinstance(list(p_dict.values())[0], str):
|
733
752
|
f.write('(property 0 string "%s"\n' % p_name)
|
734
753
|
f.write(f"\t(default {default} {default})\n")
|
735
754
|
elif isinstance(list(p_dict.values())[0], Number):
|
@@ -1837,22 +1856,28 @@ class lineageTree:
|
|
1837
1856
|
x, depth_succ
|
1838
1857
|
)
|
1839
1858
|
|
1840
|
-
|
1859
|
+
@property
|
1860
|
+
def all_tracks(self):
|
1861
|
+
if not hasattr(self, "_all_tracks"):
|
1862
|
+
self._all_tracks = self.get_all_tracks()
|
1863
|
+
return self._all_tracks
|
1864
|
+
|
1865
|
+
def get_all_tracks(self, force_recompute: bool = False) -> list:
|
1841
1866
|
"""Computes all the tracks of a given lineage tree,
|
1842
1867
|
stores it in `self.all_tracks` and returns it.
|
1843
1868
|
|
1844
1869
|
Returns:
|
1845
1870
|
([[int, ...], ...]): list of lists containing track cell ids
|
1846
1871
|
"""
|
1847
|
-
if not hasattr(self, "
|
1848
|
-
self.
|
1872
|
+
if not hasattr(self, "_all_tracks"):
|
1873
|
+
self._all_tracks = []
|
1849
1874
|
to_do = set(self.nodes)
|
1850
1875
|
while len(to_do) != 0:
|
1851
1876
|
current = to_do.pop()
|
1852
1877
|
track = self.get_cycle(current)
|
1853
|
-
self.
|
1878
|
+
self._all_tracks += [track]
|
1854
1879
|
to_do -= set(track)
|
1855
|
-
return self.
|
1880
|
+
return self._all_tracks
|
1856
1881
|
|
1857
1882
|
def get_sub_tree(self, x: int, preorder: bool = False) -> list:
|
1858
1883
|
"""Computes the list of cells from the subtree spawned by *x*
|
@@ -1946,7 +1971,7 @@ class lineageTree:
|
|
1946
1971
|
)
|
1947
1972
|
return self.th_edges
|
1948
1973
|
|
1949
|
-
def get_ancestor_at_t(self, n: int, time: int=None):
|
1974
|
+
def get_ancestor_at_t(self, n: int, time: int = None):
|
1950
1975
|
"""
|
1951
1976
|
Find the id of the ancestor of a give node `n`
|
1952
1977
|
at a given time `time`.
|
@@ -1958,18 +1983,17 @@ class lineageTree:
|
|
1958
1983
|
time (int): time at which the ancestor has to be found.
|
1959
1984
|
If `None` the ancestor at the first time point
|
1960
1985
|
will be found (default `None`)
|
1961
|
-
|
1986
|
+
|
1962
1987
|
Returns:
|
1963
1988
|
(int): the id of the ancestor at time `time`,
|
1964
1989
|
`-1` if it does not exist
|
1965
1990
|
"""
|
1966
|
-
if not
|
1991
|
+
if n not in self.nodes:
|
1967
1992
|
return
|
1968
1993
|
if time is None:
|
1969
1994
|
time = self.t_b
|
1970
|
-
t = self.time[n]
|
1971
1995
|
ancestor = n
|
1972
|
-
while time<self.time.get(ancestor, -1):
|
1996
|
+
while time < self.time.get(ancestor, -1):
|
1973
1997
|
ancestor = self.predecessor.get(ancestor, [-1])[0]
|
1974
1998
|
return ancestor
|
1975
1999
|
|
@@ -2169,8 +2193,40 @@ class lineageTree:
|
|
2169
2193
|
def __getitem__(self, item):
|
2170
2194
|
if isinstance(item, str):
|
2171
2195
|
return self.__dict__[item]
|
2172
|
-
elif
|
2173
|
-
return self.successor[
|
2196
|
+
elif np.issubdtype(type(item), np.integer):
|
2197
|
+
return self.successor.get(item, [])
|
2198
|
+
else:
|
2199
|
+
raise KeyError(
|
2200
|
+
"Only integer or string are valid key for lineageTree"
|
2201
|
+
)
|
2202
|
+
|
2203
|
+
def get_cells_at_t_from_root(self, r: [int, list], t: int = None) -> list:
|
2204
|
+
"""
|
2205
|
+
Returns the list of cells at time `t` that are spawn by the node(s) `r`.
|
2206
|
+
|
2207
|
+
Args:
|
2208
|
+
r (int | list): id or list of ids of the spawning node
|
2209
|
+
t (int): target time, if None goes as far as possible
|
2210
|
+
(default None)
|
2211
|
+
|
2212
|
+
Returns:
|
2213
|
+
(list) list of nodes at time `t` spawned by `r`
|
2214
|
+
"""
|
2215
|
+
if not isinstance(r, list):
|
2216
|
+
r = [r]
|
2217
|
+
to_do = list(r)
|
2218
|
+
final_nodes = []
|
2219
|
+
while len(to_do) > 0:
|
2220
|
+
curr = to_do.pop()
|
2221
|
+
for _next in self[curr]:
|
2222
|
+
if self.time[_next] < t:
|
2223
|
+
to_do.append(_next)
|
2224
|
+
elif self.time[_next] == t:
|
2225
|
+
final_nodes.append(_next)
|
2226
|
+
return final_nodes
|
2227
|
+
|
2228
|
+
def first_labelling(self):
|
2229
|
+
self.labels = {i:"Enter_Label" for i in self.time_nodes[0]}
|
2174
2230
|
|
2175
2231
|
def __init__(
|
2176
2232
|
self,
|
@@ -2217,6 +2273,7 @@ class lineageTree:
|
|
2217
2273
|
self.kdtrees = {}
|
2218
2274
|
self.spatial_density = {}
|
2219
2275
|
self.progeny = {}
|
2276
|
+
self.labels = {}
|
2220
2277
|
if xml_attributes is None:
|
2221
2278
|
self.xml_attributes = []
|
2222
2279
|
else:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: LineageTree
|
3
|
-
Version: 1.4.
|
3
|
+
Version: 1.4.3
|
4
4
|
Summary: Lineage tree structure
|
5
5
|
Home-page: https://github.com/leoguignard/LineageTree
|
6
6
|
Author: Léo Guignard
|
@@ -35,10 +35,9 @@ Requires-Dist: matplotlib; extra == "test"
|
|
35
35
|
Requires-Dist: tox; extra == "test"
|
36
36
|
Requires-Dist: pytest; extra == "test"
|
37
37
|
Requires-Dist: pytest-cov; extra == "test"
|
38
|
+
Requires-Dist: mastodon-reader; extra == "test"
|
38
39
|
Provides-Extra: treeedit
|
39
40
|
Requires-Dist: edist; extra == "treeedit"
|
40
|
-
Provides-Extra: mastodon
|
41
|
-
Requires-Dist: mastodon-reader; extra == "mastodon"
|
42
41
|
Provides-Extra: all
|
43
42
|
Requires-Dist: svgwrite; extra == "all"
|
44
43
|
Requires-Dist: matplotlib; extra == "all"
|
@@ -77,6 +76,12 @@ from LineageTree import lineageTree
|
|
77
76
|
|
78
77
|
and one can then load lineage trees the following way:
|
79
78
|
|
79
|
+
For `.lT` files:
|
80
|
+
|
81
|
+
```python
|
82
|
+
lT = lineageTree('path/to/file.lT')
|
83
|
+
```
|
84
|
+
|
80
85
|
For ASTEC data:
|
81
86
|
|
82
87
|
```python
|
@@ -14,3 +14,8 @@ def test_writting_svg():
|
|
14
14
|
lT = lineageTree("test/data/test-mamut.xml", file_type="MaMuT")
|
15
15
|
lT = lineageTree("test/data/test.mastodon", file_type="mastodon")
|
16
16
|
lT.write_to_svg("test/test.svg")
|
17
|
+
|
18
|
+
|
19
|
+
def test_all_tracks():
|
20
|
+
lT = lineageTree("test/data/test-mamut.xml", file_type="MaMuT")
|
21
|
+
assert len(lT.all_tracks) == 18
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|