Replies: 4 comments 6 replies
-
This is something that'll come up when I present. There is at least one use case for not remapping nodes. |
Beta Was this translation helpful? Give feedback.
-
Here's a hack: def simplify_keeping_all_nodes(ts):
"""
Run the Hudson algorithm to convert from an implicit to an explicit edge encoding,
but keep all the nodes (like simplify(filter_nodes=False) if that existed)
"""
# get the edges to keep
ts2, node_map = ts.simplify(keep_unary=True, map_nodes=True)
val, inverted_map = np.unique(node_map, return_index=True)
inverted_map = inverted_map[val != tskit.NULL]
# only use the edges in the simplified one, but keep the nodes from the original
tables = ts.dump_tables()
tables.edges.clear()
for edge in ts2.tables.edges:
tables.edges.append(
edge.replace(
child=inverted_map[edge.child], parent=inverted_map[edge.parent]
)
)
tables.sort()
return tables.tree_sequence() |
Beta Was this translation helpful? Give feedback.
-
Here's some code I've put together to remove the edges above local roots, but leave the nodes untouched. it's pretty intricate though. def remove_edges_above_local_roots(ts):
# use simplify() to find the roots
ts_simp, node_map = ts.simplify(map_nodes=True)
inverted_node_map = {n: i for i, n in enumerate(node_map)}
edges_to_prune = {}
for intvl, orig_tree, tree in ts.coiterate(ts_simp):
for root in tree.roots:
orig_node = inverted_node_map[root]
if orig_tree.parent(orig_node) != tskit.NULL:
edge_above = orig_tree.edge(orig_node)
if edge_above in edges_to_prune:
intervals = edges_to_prune[edge_above]
if intervals[-1].right == intvl.left:
intervals[-1] = tskit.Interval(intervals[-1].left, intvl.right)
else:
intervals.append(intvl)
else:
edges_to_prune[edge_above] = [intvl]
# Now split the edges to prune by their intervals
tables = ts.dump_tables()
edges = tables.edges
for edge_id, intervals in edges_to_prune.items():
deleted_edge = tables.edges[edge_id]
if deleted_edge.left < intervals[0].left:
edges.append(deleted_edge.replace(right=intervals[0].left))
for i in range(len(intervals)):
try:
edges.append(deleted_edge.replace(
left=intervals[i].right, right=intervals[i+1].left))
except IndexError:
# last interval to delete
if deleted_edge.right > intervals[i].right:
edges.append(deleted_edge.replace(left=intervals[i].right))
keep = np.ones(edges.num_rows, dtype=bool)
keep[list(edges_to_prune.keys())] = False
tables.edges.replace_with(edges[keep])
tables.sort()
return tables.tree_sequence() |
Beta Was this translation helpful? Give feedback.
-
Actually implementing |
Beta Was this translation helpful? Give feedback.
-
Is there a simple way to identify (and then remove/adjust) the edges above local roots in the tree, while keeping all the nodes in the node table?
In fact, is there a way to simplify edges without touching the node table? Should there be?
Beta Was this translation helpful? Give feedback.
All reactions