forked from enviPath/enviPy
[Fix] Simplify Depth adjustment (#386)
Co-authored-by: Tim Lorsbach <tim@lorsba.ch> Reviewed-on: enviPath/enviPy#386
This commit is contained in:
@ -2179,18 +2179,20 @@ class Pathway(EnviPathModel, AliasMixin, ScenarioMixin, AdditionalInformationMix
|
|||||||
return Edge.create(self, start_nodes, end_nodes, rule, name=name, description=description)
|
return Edge.create(self, start_nodes, end_nodes, rule, name=name, description=description)
|
||||||
|
|
||||||
def update_depths(self):
|
def update_depths(self):
|
||||||
|
# Collect number of in and out links per node
|
||||||
in_count = defaultdict(lambda: 0)
|
in_count = defaultdict(lambda: 0)
|
||||||
out_count = defaultdict(lambda: 0)
|
out_count = defaultdict(lambda: 0)
|
||||||
|
|
||||||
for e in self.edges:
|
for e in self.edges:
|
||||||
# TODO check if this will remain
|
|
||||||
for react in e.start_nodes.all():
|
for react in e.start_nodes.all():
|
||||||
out_count[str(react.uuid)] += 1
|
out_count[str(react.uuid)] += 1
|
||||||
|
|
||||||
for prod in e.end_nodes.all():
|
for prod in e.end_nodes.all():
|
||||||
in_count[str(prod.uuid)] += 1
|
in_count[str(prod.uuid)] += 1
|
||||||
|
|
||||||
root_nodes = []
|
depth_map = {}
|
||||||
|
depth_map[0] = list()
|
||||||
|
|
||||||
for n in self.nodes:
|
for n in self.nodes:
|
||||||
num_parents = in_count[str(n.uuid)]
|
num_parents = in_count[str(n.uuid)]
|
||||||
if num_parents == 0:
|
if num_parents == 0:
|
||||||
@ -2201,28 +2203,30 @@ class Pathway(EnviPathModel, AliasMixin, ScenarioMixin, AdditionalInformationMix
|
|||||||
|
|
||||||
# Only root node may have children
|
# Only root node may have children
|
||||||
if out_count[str(n.uuid)] > 0:
|
if out_count[str(n.uuid)] > 0:
|
||||||
root_nodes.append(n)
|
depth_map[0].append(n)
|
||||||
|
|
||||||
levels = [root_nodes]
|
# At most depth len(nodes) is possible
|
||||||
seen = set()
|
for i in range(self.nodes.count()):
|
||||||
# Do a bfs to determine depths starting with level 0 a.k.a. root nodes
|
level_nodes = depth_map.get(i, [])
|
||||||
for i, level_nodes in enumerate(levels):
|
|
||||||
new_level = []
|
if len(level_nodes) == 0:
|
||||||
|
break
|
||||||
|
|
||||||
|
unique_next_level = set()
|
||||||
for n in level_nodes:
|
for n in level_nodes:
|
||||||
for e in n.out_edges.all():
|
for e in self.edges:
|
||||||
for prod in e.end_nodes.all():
|
if n in e.start_nodes.all():
|
||||||
if str(prod.uuid) not in seen:
|
for p in e.end_nodes.all():
|
||||||
old_depth = prod.depth
|
unique_next_level.add(p)
|
||||||
if old_depth != i + 1:
|
|
||||||
prod.depth = i + 1
|
|
||||||
prod.save()
|
|
||||||
|
|
||||||
new_level.append(prod)
|
if len(unique_next_level) > 0:
|
||||||
|
depth_map[i + 1] = list(unique_next_level)
|
||||||
|
|
||||||
seen.add(str(n.uuid))
|
for depth, nodes in depth_map.items():
|
||||||
|
for n in nodes:
|
||||||
if new_level:
|
if n.depth != depth:
|
||||||
levels.append(new_level)
|
n.depth = depth
|
||||||
|
n.save()
|
||||||
|
|
||||||
|
|
||||||
class Node(EnviPathModel, AliasMixin, ScenarioMixin, AdditionalInformationMixin):
|
class Node(EnviPathModel, AliasMixin, ScenarioMixin, AdditionalInformationMixin):
|
||||||
|
|||||||
Reference in New Issue
Block a user