LineageTree 1.8.0__py3-none-any.whl → 2.0.3__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]
@@ -0,0 +1,130 @@
1
+ Metadata-Version: 2.4
2
+ Name: LineageTree
3
+ Version: 2.0.3
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
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3 :: Only
19
+ Classifier: Programming Language :: Python :: 3.10
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
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE
26
+ Requires-Dist: scipy>=1.9
27
+ Requires-Dist: numpy>=1.23
28
+ Requires-Dist: mastodon-reader
29
+ Requires-Dist: matplotlib
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"
43
+ Provides-Extra: test
44
+ Requires-Dist: pytest; extra == "test"
45
+ Requires-Dist: pytest-cov; extra == "test"
46
+ Dynamic: license-file
47
+
48
+ # LineageTree
49
+
50
+ This library allows to import and work with cell (but not limited to cells) lineage trees.
51
+ With LineageTree you can read from:
52
+
53
+ - TGMM algorithm outputs described in [Amat et al. 2014](https://www.nature.com/articles/nmeth.3036)
54
+ - TrackMate files described in [Tinevez et al. 2017](https://doi.org/10.1016/j.ymeth.2016.09.016)
55
+ - MaMuT files described in [Wolff et al. 2018](https://doi.org/10.7554/eLife.34410)
56
+ - SVF algorithm outputs described in [McDole, Guignard et al. 2018](https://doi.org/10.1016/j.cell.2018.09.031)
57
+ - ASTEC algorithm outputs described in [Guignard, Fiuza et al. 2020](https://doi.org/10.1126/science.aar5663)
58
+ - Data from the [Digital development Database](http://digital-development.org/index.html) described in [Du et al. 2014](https://www.cell.com/fulltext/S0092-8674(13)01542-0) and [Du et al. 2015](https://www.sciencedirect.com/science/article/pii/S1534580715004876?via%3Dihub)
59
+ - and few others
60
+
61
+ ## Basic usage
62
+
63
+ Once installed the library can be called the following way (as an example):
64
+
65
+ ```python
66
+ from LineageTree import lineageTree
67
+ ```
68
+
69
+ and one can then load lineage trees the following way:
70
+
71
+ For `.lT` files:
72
+
73
+ ```python
74
+ lT = lineageTree.load('path/to/file.lT')
75
+ ```
76
+
77
+ For ASTEC data:
78
+
79
+ ```python
80
+ from LineageTree import read_from_ASTEC
81
+ lT = read_from_ASTEC('path/to/ASTEC.pkl')
82
+ ```
83
+
84
+ For MaMuT or TrackMate:
85
+
86
+ ```python
87
+ from LineageTree import read_from_mamut_xml
88
+ lT = read_from_mamut_xml('path/to/MaMuT.xml')
89
+ ```
90
+
91
+ For TGMM:
92
+
93
+ ```python
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)
96
+ ```
97
+
98
+ For Mastodon:
99
+
100
+ ```python
101
+ from LineageTree import read_from_mastodon
102
+ lT = read_from_mastodon('path/to/Mastodon.mastodon')
103
+ ```
104
+
105
+ or, for Mastodon csv file:
106
+
107
+ ```python
108
+ from LineageTree import read_from_mastodon_csv
109
+ lT = read_from_mastodon_csv(['path/to/nodes.csv', 'path/to/links.csv'])
110
+ ```
111
+
112
+ ## Quick install
113
+
114
+ To quickly install the library together with its dependencies one can run:
115
+
116
+ ```shell
117
+ pip install LineageTree
118
+ ```
119
+
120
+ or, for the latest version if you have cloned the directory:
121
+
122
+ ```shell
123
+ pip install .
124
+ ```
125
+
126
+ or for the latest version wihtout cloning the directory
127
+
128
+ ```shell
129
+ pip install git+https://github.com/leoguignard/LineageTree
130
+ ```
@@ -0,0 +1,16 @@
1
+ LineageTree/__init__.py,sha256=DBw4aJTm7ttYYm6FuL9b_Q1108W9YU_dox0oIoDiLUU,749
2
+ LineageTree/lineageTree.py,sha256=3es3wPN9O0Eaqw-YC-uMq4tukpQPkW7DbTl9ujvZkXs,125993
3
+ LineageTree/lineageTreeManager.py,sha256=kyHeoQ3EKMNnlSJG-v0K67j8RHECNIk-dUzdP0za3as,32406
4
+ LineageTree/loaders.py,sha256=lcLEvLGA4Jn0QwBId__kHpQ3i4axDT5VEyACGnDNrBg,30255
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.3.dist-info/licenses/LICENSE,sha256=IKncNCNpq93Kq7Ywg1V4I9Bu_99VMK-mX1EJyjTKLyc,1068
13
+ lineagetree-2.0.3.dist-info/METADATA,sha256=GOrhmJPx3qWTCqszjsjHQ2vS-43DZ0gDurjfpUZ8US8,4081
14
+ lineagetree-2.0.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
15
+ lineagetree-2.0.3.dist-info/top_level.txt,sha256=CCqPCTX76zPTEUagUgTWbLaZun8752n59iOOwfUlvxs,12
16
+ lineagetree-2.0.3.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