From 5a588db38b4326e68d444d673a410e50becc0e9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Guignard?= Date: Fri, 27 Jun 2025 10:02:04 +0200 Subject: [PATCH 1/6] adding function get_subtree --- src/LineageTree/lineageTree.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/LineageTree/lineageTree.py b/src/LineageTree/lineageTree.py index 9b71970..311dd31 100644 --- a/src/LineageTree/lineageTree.py +++ b/src/LineageTree/lineageTree.py @@ -3349,6 +3349,23 @@ def plot_dtw_trajectory( return distance, fig + def get_subtree(self, node_list: set[int]) -> lineageTree: + new_successors = { + n: (vi for vi in self.successor[n] if vi in node_list) + for n in node_list + } + return lineageTree( + successor=new_successors, + time=self._time, + pos=self.pos, + name=self.name, + root_leaf_value=(()), + **{ + name: self.__dict__[name] + for name in self._custom_property_list + }, + ) + def __init__( self, *, @@ -3511,6 +3528,7 @@ def __init__( "Provided times are not strictly increasing. Setting times to default." ) # custom properties + self._custom_property_list = [] for name, d in kwargs.items(): if name in self.__dict__: warnings.warn( @@ -3518,5 +3536,6 @@ def __init__( ) continue setattr(self, name, d) + self._custom_property_list.append(name) if not hasattr(self, "_comparisons"): self._comparisons = {} From 99b31beebbff2dabc80a4f7fff33c9ae3510aa74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Guignard?= Date: Fri, 27 Jun 2025 10:08:27 +0200 Subject: [PATCH 2/6] fix for root_leaves_values --- src/LineageTree/lineageTree.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/LineageTree/lineageTree.py b/src/LineageTree/lineageTree.py index 311dd31..2ebe860 100644 --- a/src/LineageTree/lineageTree.py +++ b/src/LineageTree/lineageTree.py @@ -3359,7 +3359,9 @@ def get_subtree(self, node_list: set[int]) -> lineageTree: time=self._time, pos=self.pos, name=self.name, - root_leaf_value=(()), + root_leaf_value=[ + (), + ], **{ name: self.__dict__[name] for name in self._custom_property_list From 24029e2383de4aebe06a8b9ce554048c90e8a87d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Guignard?= Date: Fri, 27 Jun 2025 10:20:30 +0200 Subject: [PATCH 3/6] fix where tuple not generator is needed --- src/LineageTree/lineageTree.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/LineageTree/lineageTree.py b/src/LineageTree/lineageTree.py index 2ebe860..379373c 100644 --- a/src/LineageTree/lineageTree.py +++ b/src/LineageTree/lineageTree.py @@ -3351,7 +3351,7 @@ def plot_dtw_trajectory( def get_subtree(self, node_list: set[int]) -> lineageTree: new_successors = { - n: (vi for vi in self.successor[n] if vi in node_list) + n: tuple(vi for vi in self.successor[n] if vi in node_list) for n in node_list } return lineageTree( From 959dc432581ca709683d7c36dd0d0ffdd3cbc819 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Guignard?= Date: Fri, 27 Jun 2025 10:36:04 +0200 Subject: [PATCH 4/6] adding possibility to give empty dictionnary for positiongs --- src/LineageTree/lineageTree.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/LineageTree/lineageTree.py b/src/LineageTree/lineageTree.py index 379373c..409cc6a 100644 --- a/src/LineageTree/lineageTree.py +++ b/src/LineageTree/lineageTree.py @@ -3474,7 +3474,7 @@ def __init__( "Cycles were found in the tree, there should not be any." ) - if pos is None: + if pos is None or len(pos) == 0: self.pos = {} else: if self.nodes.difference(pos) != set(): From 14c5e36e15762d1e3386a9acfe67d223334b825f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Guignard?= Date: Fri, 27 Jun 2025 10:43:05 +0200 Subject: [PATCH 5/6] adding possibility to give lineages at lt manager creation --- src/LineageTree/lineageTreeManager.py | 50 +++++++++++++-------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/src/LineageTree/lineageTreeManager.py b/src/LineageTree/lineageTreeManager.py index 0f1564d..e7bc749 100644 --- a/src/LineageTree/lineageTreeManager.py +++ b/src/LineageTree/lineageTreeManager.py @@ -3,7 +3,7 @@ import os import pickle as pkl import warnings -from collections.abc import Callable +from collections.abc import Callable, Iterable from functools import partial from typing import TYPE_CHECKING, Literal @@ -35,11 +35,13 @@ class lineageTreeManager: norm_dict = {"max": max, "sum": sum, None: lambda x: 1} - def __init__(self): + def __init__(self, lineagetree_list: Iterable[lineageTree] = ()): self.lineagetrees = {} self.lineageTree_counter = 0 self.registered = {} self._comparisons = {} + for lT in lineagetree_list: + self.add(lT) def __next__(self): self.lineageTree_counter += 1 @@ -55,9 +57,7 @@ def __len__(self): """ return len(self.lineagetrees) - def __iter__( - self, - ): + def __iter__(self): yield from self.lineagetrees.items() def __getitem__(self, key): @@ -657,28 +657,28 @@ def plot_tree_distance_graphs( matched_right.append(node_2) l_node_2 = tree2.lT.get_chain_of_node(node_2)[-1] matched_right.append(l_node_2) - colors1[ - node_1 - ] = self.__calculate_distance_of_sub_tree( - node_1, - tree1.lT, - node_2, - tree2.lT, - btrc, - corres1, - corres2, - delta_tmp, - self.norm_dict[norm], - tree1.get_norm(node_1), - tree2.get_norm(node_2), + colors1[node_1] = ( + self.__calculate_distance_of_sub_tree( + node_1, + tree1.lT, + node_2, + tree2.lT, + btrc, + corres1, + corres2, + delta_tmp, + self.norm_dict[norm], + tree1.get_norm(node_1), + tree2.get_norm(node_2), + ) ) colors2[node_2] = colors1[node_1] - colors1[ - tree1.lT.get_chain_of_node(node_1)[-1] - ] = colors1[node_1] - colors2[ - tree2.lT.get_chain_of_node(node_2)[-1] - ] = colors2[node_2] + colors1[tree1.lT.get_chain_of_node(node_1)[-1]] = ( + colors1[node_1] + ) + colors2[tree2.lT.get_chain_of_node(node_2)[-1]] = ( + colors2[node_2] + ) if tree1.lT.get_chain_of_node(node_1)[-1] != node_1: matched_left.append( From a9bbe102d1ee8ec7ea65bd99a99cc18924301e7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Guignard?= Date: Fri, 27 Jun 2025 10:44:48 +0200 Subject: [PATCH 6/6] add quick docstring and TODO for ltmanager --- src/LineageTree/lineageTreeManager.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/LineageTree/lineageTreeManager.py b/src/LineageTree/lineageTreeManager.py index e7bc749..df3014d 100644 --- a/src/LineageTree/lineageTreeManager.py +++ b/src/LineageTree/lineageTreeManager.py @@ -36,6 +36,14 @@ class lineageTreeManager: norm_dict = {"max": max, "sum": sum, None: lambda x: 1} def __init__(self, lineagetree_list: Iterable[lineageTree] = ()): + """Creates a lineageTreeManager + :TODO: write the docstring + + Parameters + ---------- + lineagetree_list: Iterable of lineageTree + List of lineage trees to be in the lineageTreeManager + """ self.lineagetrees = {} self.lineageTree_counter = 0 self.registered = {}