LineageTree 1.8.0__py3-none-any.whl → 2.0.1__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.
LineageTree/utils.py CHANGED
@@ -1,122 +1,88 @@
1
- import csv
2
- import warnings
3
-
4
- from LineageTree import lineageTree
5
-
6
- try:
7
- import motile
8
- except ImportError:
9
- warnings.warn(
10
- "No motile installed therefore you will not be able to produce links with motile.",
11
- stacklevel=2,
12
- )
13
-
14
-
15
- def to_motile(
16
- lT: lineageTree, crop: int = None, max_dist=200, max_skip_frames=1
17
- ):
18
- try:
19
- import networkx as nx
20
- except ImportError:
21
- raise Warning("Please install networkx") # noqa: B904
22
-
23
- fmt = nx.DiGraph()
24
- if not crop:
25
- crop = lT.t_e
26
- for time in range(crop):
27
- for time_node in lT.time_nodes[time]:
28
- fmt.add_node(
29
- time_node,
30
- t=lT.time[time_node],
31
- pos=lT.pos[time_node],
32
- score=1,
33
- )
34
-
35
- motile.add_cand_edges(fmt, max_dist, max_skip_frames=max_skip_frames)
36
-
37
- return fmt
38
-
39
-
40
- def write_csv_from_lT_to_lineaja(
41
- lT, path_to, start: int = 0, finish: int = 300
42
- ):
43
- csv_dict = {}
44
- for time in range(start, finish):
45
- for node in lT.time_nodes[time]:
46
- csv_dict[node] = {"pos": lT.pos[node], "t": time}
47
- with open(path_to, "w", newline="\n") as file:
48
- fieldnames = [
49
- "time",
50
- "positions_x",
51
- "positions_y",
52
- "positions_z",
53
- "id",
54
- ]
55
- writer = csv.DictWriter(file, fieldnames=fieldnames)
56
- writer.writeheader()
57
- for node in csv_dict:
58
- writer.writerow(
59
- {
60
- "time": csv_dict[node]["t"],
61
- "positions_z": csv_dict[node]["pos"][0],
62
- "positions_y": csv_dict[node]["pos"][1],
63
- "positions_x": csv_dict[node]["pos"][2],
64
- "id": node,
65
- }
66
- )
67
-
68
-
69
- def create_links_and_cycles(lT: lineageTree, roots=None):
70
- """Generates a dictionary containing the links and the lengths of each branch.
71
- Similar to simple tree, mainly used for tree manip app.
72
-
73
- Args:
74
- roots (Union[list,set,int]): The roots from which the tree will be generated.
75
-
76
- Returns:
77
- dict: A dictionary with keys "links" and "times" which contains the connections all cells and their branch
78
- length.
1
+ from collections.abc import Iterable
2
+
3
+ from LineageTree import lineageTree, tree_approximation
4
+
5
+
6
+ def create_links_and_chains(
7
+ lT: lineageTree,
8
+ roots: int | Iterable | None = None,
9
+ end_time: int | None = None,
10
+ ) -> dict[str, dict]:
11
+ """Generates a dictionary containing all the edges (from start of lifetime to end not the intermediate timepoints)
12
+ of a subtree spawned by node/s and their duration
13
+
14
+
15
+ Parameters
16
+ ----------
17
+ lT : lineageTree
18
+ The lineagetree that the user is working on
19
+ roots : int or Iterable, optional
20
+ The root/s from which the tree/s will be generated, if 'None' all the roots will be selected.
21
+ end_time : int, optional
22
+ The last timepoint to be considered, if 'None' the last timepoint of the dataset (t_e) is considered, by default None.
23
+
24
+ Returns
25
+ -------
26
+ dict mapping str to set or dict mapping int to list or int
27
+ A dictionary that contains:
28
+ - "links": The dictionary that contains the hierarchy of the nodes (only start and end of each chain)
29
+ - "times": The time distance between the start and the end of a chain
30
+ - "roots": The roots used
79
31
  """
80
32
  if roots is None:
81
33
  to_do = set(lT.roots)
82
- elif isinstance(roots, list):
34
+ elif isinstance(roots, Iterable):
83
35
  to_do = set(roots)
84
36
  else:
85
37
  to_do = {int(roots)}
38
+ if end_time is None:
39
+ end_time = lT.t_e
86
40
  times = {}
87
41
  links = {}
88
42
  while to_do:
89
43
  curr = to_do.pop()
90
- cyc = lT.get_successors(curr)
91
- last = cyc[-1]
92
- times[curr] = len(cyc)
93
- if last != curr:
94
- links[curr] = [cyc[-1]]
95
- else:
96
- links[curr] = []
97
- succ = lT.successor.get(last)
98
- if succ:
99
- times[cyc[-1]] = 0
100
- to_do.update(succ)
44
+ cyc = lT.get_successors(curr, end_time=end_time)
45
+ if cyc[-1] != curr or lT.time[cyc[-1]] <= end_time:
46
+ last = cyc[-1]
47
+ times[curr] = len(cyc)
48
+ if last != curr:
49
+ links[curr] = [last]
50
+ else:
51
+ links[curr] = []
52
+ succ = lT._successor.get(last)
53
+ if succ:
54
+ times[cyc[-1]] = 0
55
+ to_do.update(succ)
101
56
  links[last] = succ
102
57
  return {"links": links, "times": times, "root": roots}
103
58
 
104
59
 
105
60
  def hierarchical_pos(
106
61
  lnks_tms: dict, root, width=1000, vert_gap=2, xcenter=0, ycenter=0
107
- ):
108
- """Calculates the position of each node on te tree graph.
109
-
110
- Args:
111
- lnks_tms (dict): a dictionary created by create_links_and_cycles.
112
- root (_type_): The id of the node, usually it exists inside lnks_tms dictionary, however you may use your own root.
113
- width (int, optional): Max width, will not change the graph but the interacting with the graph takes this distance into account. Defaults to 1000.
114
- vert_gap (int, optional): How far downwards each timepoint will go. Defaults to 2.
115
- xcenter (int, optional): Where the root will be placed on the x axis. Defaults to 0.
116
- ycenter (int, optional): Where the root will be placed on the y axis. Defaults to 0.
117
-
118
- Returns:
119
- _type_: _description_
62
+ ) -> dict[int, list[float]] | None:
63
+ """Calculates the position of each node on the tree graph.
64
+
65
+ Parameters
66
+ ----------
67
+ lnks_tms : dict
68
+ a dictionary created by create_links_and_chains.
69
+ root : _type_
70
+ The id of the node, usually it exists inside lnks_tms dictionary, however you may use your own root.
71
+ width : int, optional
72
+ Max width, will not change the graph but interacting with the graph takes this distance into account, by default 1000
73
+ vert_gap : int, optional
74
+ How far downwards each timepoint will go, by default 2
75
+ xcenter : int, optional
76
+ Where the root will be placed on the x axis, by default 0
77
+ ycenter : int, optional
78
+ Where the root will be placed on the y axis, by default 0
79
+
80
+ Returns
81
+ -------
82
+ dict mapping int to list of float
83
+ Provides a dictionary that contains the id of each node as keys and its 2-d position on the
84
+ tree graph as values.
85
+ If the root requested does not exists, None is then returned
120
86
  """
121
87
  to_do = [root]
122
88
  if root not in lnks_tms["times"]:
@@ -152,3 +118,37 @@ def hierarchical_pos(
152
118
  prev_width[curr] / 2,
153
119
  )
154
120
  return pos_node
121
+
122
+
123
+ def convert_style_to_number(
124
+ style: str | tree_approximation.TreeApproximationTemplate,
125
+ downsample: int | None,
126
+ ) -> int:
127
+ """Converts tree_style and downsampling to a single number.
128
+
129
+ Parameters
130
+ ----------
131
+ style : str
132
+ the tree style
133
+ downsample : int
134
+ the downsampling factor
135
+
136
+ Returns
137
+ -------
138
+ int
139
+ A number which serves as ID if the tree style and downsampling used.
140
+ """
141
+ style_dict = {
142
+ "full": 0,
143
+ "simple": -1,
144
+ "normalized_simple": -2,
145
+ "mini": -1000,
146
+ }
147
+ if style == "downsampled" and downsample is not None:
148
+ return downsample
149
+ elif not isinstance(style, str) and issubclass(
150
+ style, tree_approximation.TreeApproximationTemplate
151
+ ):
152
+ return hash(style.__name__)
153
+ else:
154
+ return style_dict[style]
@@ -1,53 +1,49 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: LineageTree
3
- Version: 1.8.0
4
- Summary: Lineage tree structure
5
- Home-page: https://github.com/leoguignard/LineageTree
6
- Author: Léo Guignard
7
- Author-email: leo.guignard@univ-amu.fr
8
- License: MIT
9
- Project-URL: Bug Tracker, https://github.com/leoguignard/LineageTree/issues
10
- Project-URL: Documentation, https://github.com/leoguignard/LineageTree#README.md
11
- Project-URL: Source Code, https://github.com/leoguignard/LineageTree
12
- Project-URL: User Support, https://github.com/leoguignard/LineageTree/issues
13
- Classifier: Development Status :: 2 - Pre-Alpha
3
+ Version: 2.0.1
4
+ Summary: Structure for Lineage Trees
5
+ Author: Giannis Liaskas, Christopher Mazzerbo
6
+ Author-email: Léo Guignard <leo.guignard@univ-amu.fr>
7
+ Maintainer-email: Léo Guignard <leo.guignard@univ-amu.fr>
8
+ License-Expression: MIT
9
+ Project-URL: Bug Tracker, https://github.com/GuignardLab/LineageTree/issues
10
+ Project-URL: Documentation, https://github.com/GuignardLab/LineageTree#README.md
11
+ Project-URL: Source Code, https://github.com/GuignardLab/LineageTree
12
+ Project-URL: User Support, https://github.com/GuignardLab/LineageTree/issues
13
+ Classifier: Development Status :: 4 - Beta
14
14
  Classifier: Intended Audience :: Developers
15
- Classifier: License :: OSI Approved :: MIT License
16
15
  Classifier: Operating System :: OS Independent
17
16
  Classifier: Programming Language :: Python
18
17
  Classifier: Programming Language :: Python :: 3
19
18
  Classifier: Programming Language :: Python :: 3 :: Only
20
- Classifier: Programming Language :: Python :: 3.8
21
- Classifier: Programming Language :: Python :: 3.9
22
19
  Classifier: Programming Language :: Python :: 3.10
23
- Classifier: Topic :: Scientific/Engineering :: Image Processing
24
- Requires-Python: >=3.8
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Programming Language :: Python :: 3.13
23
+ Requires-Python: >=3.10
25
24
  Description-Content-Type: text/markdown
26
25
  License-File: LICENSE
27
26
  Requires-Dist: scipy>=1.9
28
27
  Requires-Dist: numpy>=1.23
29
28
  Requires-Dist: mastodon-reader
30
29
  Requires-Dist: matplotlib
31
- Provides-Extra: svg
32
- Requires-Dist: svgwrite; extra == "svg"
33
- Requires-Dist: matplotlib; extra == "svg"
30
+ Requires-Dist: edist
31
+ Requires-Dist: svgwrite
32
+ Provides-Extra: dev
33
+ Requires-Dist: pytest; extra == "dev"
34
+ Requires-Dist: pytest-cov; extra == "dev"
35
+ Requires-Dist: tox; extra == "dev"
36
+ Requires-Dist: black; extra == "dev"
37
+ Requires-Dist: ruff; extra == "dev"
38
+ Requires-Dist: bumpver; extra == "dev"
39
+ Provides-Extra: doc
40
+ Requires-Dist: sphinx-rtd-theme; extra == "doc"
41
+ Requires-Dist: myst-parser; extra == "doc"
42
+ Requires-Dist: sphinx_book_theme; extra == "doc"
34
43
  Provides-Extra: test
35
- Requires-Dist: svgwrite; extra == "test"
36
- Requires-Dist: matplotlib; extra == "test"
37
- Requires-Dist: tox; extra == "test"
38
44
  Requires-Dist: pytest; extra == "test"
39
45
  Requires-Dist: pytest-cov; extra == "test"
40
- Requires-Dist: mastodon-reader; extra == "test"
41
- Provides-Extra: treeedit
42
- Requires-Dist: edist; extra == "treeedit"
43
- Provides-Extra: all
44
- Requires-Dist: svgwrite; extra == "all"
45
- Requires-Dist: matplotlib; extra == "all"
46
- Requires-Dist: tox; extra == "all"
47
- Requires-Dist: pytest; extra == "all"
48
- Requires-Dist: pytest-cov; extra == "all"
49
- Requires-Dist: edist; extra == "all"
50
- Requires-Dist: mastodon-reader; extra == "all"
46
+ Dynamic: license-file
51
47
 
52
48
  # LineageTree
53
49
 
@@ -0,0 +1,16 @@
1
+ LineageTree/__init__.py,sha256=Mkxh44uNuGueMMHEnOWpEchFefwMS6rht_EqHShIYew,749
2
+ LineageTree/lineageTree.py,sha256=dWpGuQ_h4JMvTzOBaMg_dC4mkPwIR2Rb3EvDKowcVxM,125146
3
+ LineageTree/lineageTreeManager.py,sha256=25QWNbj3Ep7itQKd6LrddICG457BEp1DlfKWgVHlx5I,31753
4
+ LineageTree/loaders.py,sha256=rjLHSaukBI23oxndkqrkK_6UBjmzU4LUkr_lgOaZqvM,30189
5
+ LineageTree/tree_approximation.py,sha256=61Omn0gUaRiNTDcIucDM4DUPBW5voXRxCZQ0uYGRDSg,16170
6
+ LineageTree/utils.py,sha256=EOH2MGlBH3cFs8DVOX-3fJRwoj0ZmiE_nPkAjzWXK48,5124
7
+ LineageTree/legacy/export_csv.py,sha256=cJ1R3GCGEy9Oey73jbFhoKRGTonNbqg229fVnGm_FuU,2009
8
+ LineageTree/legacy/to_lineajea.py,sha256=iZyZTsrvWYHkGJ8npf91lQPrXPgKouiy7Zrywx5Lkkw,926
9
+ LineageTree/legacy/to_motile.py,sha256=4AC9BmGa-hpqt8_x6HTR_XqCrTERlKo9WwYHUFtheM0,860
10
+ LineageTree/test/test_lineageTree.py,sha256=d5uucokzE7OWQirsW7XxaGEgeRszQ5KICbAYhriXEQo,16492
11
+ LineageTree/test/test_uted.py,sha256=Vl7uNGZp57XUD3v3SHRJtXhb0Lte8mDjpOtEKp_dxt0,6496
12
+ lineagetree-2.0.1.dist-info/licenses/LICENSE,sha256=IKncNCNpq93Kq7Ywg1V4I9Bu_99VMK-mX1EJyjTKLyc,1068
13
+ lineagetree-2.0.1.dist-info/METADATA,sha256=UwtX1LWAG-s-7aaGkss_UTpourt3InBk5ab5x-4W4i0,4300
14
+ lineagetree-2.0.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
15
+ lineagetree-2.0.1.dist-info/top_level.txt,sha256=CCqPCTX76zPTEUagUgTWbLaZun8752n59iOOwfUlvxs,12
16
+ lineagetree-2.0.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.8.0)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,334 +0,0 @@
1
- import warnings
2
- from abc import ABC, abstractmethod
3
- from enum import Enum
4
-
5
- import numpy as np
6
-
7
- from LineageTree import lineageTree
8
-
9
-
10
- class abstract_trees(ABC):
11
- """Template class to produce different techniques to comapare lineageTrees.
12
- To add a new technique you need to iherit this class or one of its children
13
- and add them to the tree_style enum.
14
- For a class to be valid you need a
15
- - tree constructor (get_tree) that produces one dictionary that contains
16
- arbitary unique labels and one dictionary that contains the duration of each node.
17
- - delta function: A function that handles the cost of comparing nodes to each other.
18
- - normalization function, a function that returns the length of the tree or any interger.
19
- """
20
-
21
- def __init__(
22
- self,
23
- lT: lineageTree,
24
- root: int,
25
- downsample: int,
26
- end_time: int = None,
27
- time_scale: int = 1,
28
- ):
29
- self.lT: lineageTree = lT
30
- self.root: int = root
31
- self.downsample: int = downsample
32
- self.end_time: int = end_time if end_time else self.lT.t_e
33
- self.time_scale: int = int(time_scale) if time_scale else 1
34
- if time_scale <= 0:
35
- raise Exception("Please used a valid time_scale (Larger than 0)")
36
- self.tree: tuple = self.get_tree()
37
- self.edist = self._edist_format(self.tree[0])
38
-
39
- @abstractmethod
40
- def get_tree(self):
41
- """
42
- Get a tree version of the tree spawned by the node `r`
43
-
44
- Args:
45
- r (int): root of the tree to spawn
46
- end_time (int): the last time point to consider
47
- time_resolution (float): the time between two consecutive time points
48
-
49
- Returns:
50
- (dict) {m (int): [d1 (int), d2 (int)]}: an adjacency dictionnary
51
- where the ids are the ids of the cells in the original tree
52
- at their first time point (except for the cell `r` if it was
53
- not the first time point).
54
- (dict) {m (int): duration (float)}: life time duration of the cell `m`
55
- """
56
-
57
- @abstractmethod
58
- def delta(self, x, y, corres1, corres2, times1, times2):
59
- """The distance of two nodes inside a tree. Behaves like a staticmethod.
60
- The corres1/2 and time1/2 should always be provided and will be handled accordingly by the specific
61
- delta of each tree style.
62
-
63
- Args:
64
- x (int): The first node to compare, takes the names provided by the edist.
65
- y (int): The second node to compare, takes the names provided by the edist
66
- corres1 (dict): Correspondance between node1 and its name in the real tree.
67
- corres2 (dict): Correspondance between node2 and its name in the real tree.
68
- times1 (dict): The dictionary of the branch lengths of the tree that n1 is spawned from.
69
- times2 (dict): The dictionary of the branch lengths of the tree that n2 is spawned from.
70
-
71
- Returns:
72
- (int|float): The diatance between these 2 nodes.
73
- """
74
- if x is None and y is None:
75
- return 0
76
- if x is None:
77
- return times2[corres2[y]]
78
- if y is None:
79
- return times1[corres1[x]]
80
- len_x = times1[corres1[x]]
81
- len_y = times2[corres2[y]]
82
- return np.abs(len_x - len_y)
83
-
84
- @abstractmethod
85
- def get_norm(self):
86
- """
87
- Returns the valid value for normalizing the edit distance.
88
- Returns:
89
- (int|float): The number of nodes of each tree according to each style.
90
- """
91
-
92
- def _edist_format(self, adj_dict: dict):
93
- """Formating the custom tree style to the format needed by edist.
94
- SHOULD NOT BE CHANGED.
95
-
96
- Args:
97
- adj_dict (dict): _description_
98
-
99
- Returns:
100
- _type_: _description_
101
- """
102
- inv_adj = {vi: k for k, v in adj_dict.items() for vi in v}
103
- roots = set(adj_dict).difference(inv_adj)
104
- nid2list = {}
105
- list2nid = {}
106
- nodes = []
107
- adj_list = []
108
- curr_id = 0
109
- for r in roots:
110
- to_do = [r]
111
- while to_do:
112
- curr = to_do.pop(0)
113
- nid2list[curr] = curr_id
114
- list2nid[curr_id] = curr
115
- nodes.append(curr_id)
116
- to_do = adj_dict.get(curr, []) + to_do
117
- curr_id += 1
118
- adj_list = [
119
- [nid2list[d] for d in adj_dict.get(list2nid[_id], [])]
120
- for _id in nodes
121
- ]
122
- return nodes, adj_list, list2nid
123
-
124
-
125
- class mini_tree(abstract_trees):
126
- """Each branch is converted to a node of length 1, it is useful for comparing synchronous developing cells, extremely fast.
127
- Mainly used for testing.
128
- """
129
-
130
- def __init__(self, **kwargs):
131
- super().__init__(**kwargs)
132
-
133
- def get_tree(self):
134
- if self.end_time is None:
135
- self.end_time = self.lT.t_e
136
- out_dict = {}
137
- self.times = {}
138
- to_do = [self.root]
139
- while to_do:
140
- current = to_do.pop()
141
- cycle = np.array(self.lT.get_successors(current))
142
- cycle_times = np.array([self.lT.time[c] for c in cycle])
143
- cycle = cycle[cycle_times <= self.end_time]
144
- if cycle.size:
145
- _next = self.lT[cycle[-1]]
146
- if 1 < len(_next):
147
- out_dict[current] = _next
148
- to_do.extend(_next)
149
- else:
150
- out_dict[current] = []
151
- self.length = len(out_dict)
152
- return out_dict, None
153
-
154
- def get_norm(self):
155
- return len(
156
- self.lT.get_all_branches_of_node(self.root, end_time=self.end_time)
157
- )
158
-
159
- def _edist_format(self, adj_dict: dict):
160
- return super()._edist_format(adj_dict)
161
-
162
- def delta(self, x, y, corres1, corres2, times1, times2):
163
- if x is None and y is None:
164
- return 0
165
- if x is None:
166
- return 1
167
- if y is None:
168
- return 1
169
- return 0
170
-
171
-
172
- class simple_tree(abstract_trees):
173
- """Each branch is converted to one node with length the same as the life cycle of the cell.
174
- This method is fast, but imprecise, especialy for small trees (recommended height of the trees should be 100 at least).
175
- Use with CAUTION.
176
- """
177
-
178
- def __init__(self, **kwargs):
179
- super().__init__(**kwargs)
180
-
181
- def get_tree(self):
182
- if self.end_time is None:
183
- self.end_time = self.lT.t_e
184
- out_dict = {}
185
- self.times = {}
186
- to_do = [self.root]
187
- while to_do:
188
- current = to_do.pop()
189
- cycle = np.array(self.lT.get_successors(current))
190
- cycle_times = np.array([self.lT.time[c] for c in cycle])
191
- cycle = cycle[cycle_times <= self.end_time]
192
- if cycle.size:
193
- _next = self.lT[cycle[-1]]
194
- if len(_next) > 1 and self.lT.time[cycle[-1]] < self.end_time:
195
- out_dict[current] = _next
196
- to_do.extend(_next)
197
- else:
198
- out_dict[current] = []
199
- self.times[current] = len(cycle) * self.time_scale
200
- return out_dict, self.times
201
-
202
- def delta(self, x, y, corres1, corres2, times1, times2):
203
- return super().delta(x, y, corres1, corres2, times1, times2)
204
-
205
- def get_norm(self):
206
- return (
207
- len(self.lT.get_sub_tree(self.root, end_time=self.end_time))
208
- * self.time_scale
209
- )
210
-
211
-
212
- class downsample_tree(abstract_trees):
213
- """Downsamples a tree so every n nodes are being used as one."""
214
-
215
- def __init__(self, **kwargs):
216
- super().__init__(**kwargs)
217
- if self.downsample == 0:
218
- raise Exception("Please use a valid downsampling rate")
219
- if self.downsample == 1:
220
- warnings.warn(
221
- "Downsampling rate of 1 is identical to the full tree.",
222
- stacklevel=1,
223
- )
224
-
225
- def get_tree(self):
226
- self.out_dict = {}
227
- self.times = {}
228
- to_do = [self.root]
229
- while to_do:
230
- current = to_do.pop()
231
- _next = self.lT.get_cells_at_t_from_root(
232
- current,
233
- self.lT.time[current] + (self.downsample / self.time_scale),
234
- )
235
- if _next == [current]:
236
- _next = None
237
- if _next and self.lT.time[_next[0]] <= self.end_time:
238
- self.out_dict[current] = _next
239
- to_do.extend(_next)
240
- else:
241
- self.out_dict[current] = []
242
- self.times[current] = 1 # self.downsample
243
- return self.out_dict, self.times
244
-
245
- def get_norm(self):
246
- return len(self.times.values()) * self.downsample / self.time_scale
247
-
248
- def delta(self, x, y, corres1, corres2, times1, times2):
249
- if x is None and y is None:
250
- return 0
251
- if x is None:
252
- return self.downsample
253
- if y is None:
254
- return self.downsample
255
- return 0
256
-
257
-
258
- class normalized_simple_tree(simple_tree):
259
- def __init__(self, **kwargs):
260
- super().__init__(**kwargs)
261
-
262
- def delta(self, x, y, corres1, corres2, times1, times2):
263
- if x is None and y is None:
264
- return 0
265
- if x is None:
266
- return 1
267
- if y is None:
268
- return 1
269
- return abs(times1[corres1[x]] - times2[corres2[y]]) / (
270
- times1[corres1[x]] + times2[corres2[y]]
271
- )
272
-
273
- def get_norm(self):
274
- return len(
275
- self.lT.get_all_branches_of_node(self.root, end_time=self.end_time)
276
- )
277
-
278
-
279
- class full_tree(abstract_trees):
280
- """No approximations the whole tree is used here. Perfect accuracy, but heavy on ram and speed.
281
- Not recommended to use on napari.
282
-
283
- """
284
-
285
- def __init__(self, **kwargs):
286
- super().__init__(**kwargs)
287
-
288
- def get_tree(self) -> dict:
289
- self.out_dict = {}
290
- self.times = {}
291
- to_do = [self.root]
292
- while to_do:
293
- current = to_do.pop()
294
- _next = self.lT.successor.get(current, [])
295
- if _next and self.lT.time[_next[0]] <= self.end_time:
296
- if self.time_scale > 1:
297
- for _ in range(self.time_scale - 1):
298
- next_id = self.lT.get_next_id()
299
- self.out_dict[current] = [next_id]
300
- current = next_id
301
- self.out_dict[current] = _next
302
- to_do.extend(_next)
303
- else:
304
- for _ in range(self.time_scale - 1):
305
- next_id = self.lT.get_next_id()
306
- self.out_dict[current] = [next_id]
307
- current = next_id
308
- self.out_dict[current] = []
309
- self.times[current] = 1
310
- return self.out_dict, self.times
311
-
312
- def get_norm(self):
313
- return len(self.times) * self.time_scale
314
-
315
- def delta(self, x, y, corres1, corres2, times1, times2):
316
- if x is None and y is None:
317
- return 0
318
- if x is None:
319
- return 1
320
- if y is None:
321
- return 1
322
- return 0
323
-
324
-
325
- class tree_style(Enum):
326
- mini = mini_tree
327
- simple = simple_tree
328
- normalized_simple = normalized_simple_tree
329
- downsampled = downsample_tree
330
- full = full_tree
331
-
332
- @classmethod
333
- def list_names(self):
334
- return [style.name for style in self]
@@ -1,11 +0,0 @@
1
- LineageTree/__init__.py,sha256=888vRBgs18oExOHp7Q87HSH1GL60m-YLLjkMWYnZcBI,155
2
- LineageTree/lineageTree.py,sha256=SoxLcYXhr5wzuX9ZXMDsK5fePd_6_Boq-y4HVJ6mBBI,102326
3
- LineageTree/lineageTreeManager.py,sha256=bBhJrCUmLa6D6cZ95jT4hTnNfG7q-l_FiqOf2oaBc2o,6458
4
- LineageTree/loaders.py,sha256=eStgVrqYeUlYQ-r7EByCZo2t5cgn-mXARTWBzLSN12Q,32778
5
- LineageTree/tree_styles.py,sha256=ZEj0HcoEaWk8zyObboXW-qoM3uzKAQgiNzX2-UUa0cg,11337
6
- LineageTree/utils.py,sha256=sFIj1eDid1EKP09g_jrSgqk4NLdNVf7KjC5UwN0Fihc,4878
7
- LineageTree-1.8.0.dist-info/LICENSE,sha256=IKncNCNpq93Kq7Ywg1V4I9Bu_99VMK-mX1EJyjTKLyc,1068
8
- LineageTree-1.8.0.dist-info/METADATA,sha256=X9UUm6EP44N_O3Uv0JN4Bu9wXU9kXAB9Nh-lHkjHoEs,4469
9
- LineageTree-1.8.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
10
- LineageTree-1.8.0.dist-info/top_level.txt,sha256=CCqPCTX76zPTEUagUgTWbLaZun8752n59iOOwfUlvxs,12
11
- LineageTree-1.8.0.dist-info/RECORD,,