Skip to content

Commit

Permalink
fix: add parameter use_cached to BlackholeGraph._get_blackhole_plasmi…
Browse files Browse the repository at this point in the history
…ds(), solving the slowdown introduced in releases v0.3.3 and v0.3.4

use_cached allows us to get the blackhole plasmids already computed in a previous call to this method, instead of always recomputing them from scratch.
  • Loading branch information
leoisl committed Dec 19, 2023
1 parent 0918b4d commit fc7685e
Showing 1 changed file with 36 additions and 29 deletions.
65 changes: 36 additions & 29 deletions plasnet/blackhole_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,44 +23,51 @@ def __init__(
self._edge_density = edge_density

def _get_node_shape(self, node: str) -> str:
if node in self._get_blackhole_plasmids():
if node in self._get_blackhole_plasmids(use_cached=True):
return "star"
return "circle"

def _add_special_node_attributes(self, node: str, attrs: dict[str, Any]) -> None:
if node in self._get_blackhole_plasmids():
attrs["is_blackhole"] = True
else:
attrs["is_blackhole"] = False
attrs["is_blackhole"] = node in self._get_blackhole_plasmids(use_cached=True)

def _get_blackhole_plasmids(self) -> list[str]:
blackhole_plasmids_in_graph = []
for node in self.nodes:
if self.degree(node) >= self._blackhole_connectivity_threshold:
neighbors = list(self.neighbors(node))
subgraph = nx.induced_subgraph(self, neighbors)
nb_of_edges_between_neighbours = subgraph.number_of_edges()
max_nb_of_edges_between_neighbours = (len(neighbors) * (len(neighbors) - 1)) // 2
edge_rate = nb_of_edges_between_neighbours / max_nb_of_edges_between_neighbours
if edge_rate <= self._edge_density:
blackhole_plasmids_in_graph.append(node)
logging.debug(f"{node} is a blackhole plasmid")
else:
logging.debug(
f"{node} is highly connected but does not connect "
f"unrelated plasmids, not a blackhole plasmid"
)
return blackhole_plasmids_in_graph
def _get_blackhole_plasmids(self, use_cached: bool = False) -> list[str]:
need_to_compute_the_blackhole_plasmids = not use_cached or not hasattr(
self, "_blackhole_plasmids"
)
if need_to_compute_the_blackhole_plasmids:
blackhole_plasmids_in_graph = []
for node in self.nodes:
if self.degree(node) >= self._blackhole_connectivity_threshold:
neighbors = list(self.neighbors(node))
subgraph = nx.induced_subgraph(self, neighbors)
nb_of_edges_between_neighbours = subgraph.number_of_edges()
max_nb_of_edges_between_neighbours = (
len(neighbors) * (len(neighbors) - 1)
) // 2
edge_rate = nb_of_edges_between_neighbours / max_nb_of_edges_between_neighbours
if edge_rate <= self._edge_density:
blackhole_plasmids_in_graph.append(node)
logging.debug(f"{node} is a blackhole plasmid")
else:
logging.debug(
f"{node} is highly connected but does not connect "
f"unrelated plasmids, not a blackhole plasmid"
)
self._blackhole_plasmids = blackhole_plasmids_in_graph

def get_nb_of_blackhole_plasmids(self) -> int:
return len(self._get_blackhole_plasmids())
return self._blackhole_plasmids

def remove_blackhole_plasmids(self) -> None:
while self.get_nb_of_blackhole_plasmids() > 0:
self.remove_nodes_from(self._get_blackhole_plasmids())
while True:
blackhole_plasmids = self._get_blackhole_plasmids()
there_are_still_blackhole_plasmids = len(blackhole_plasmids) > 0
if there_are_still_blackhole_plasmids:
self.remove_nodes_from(blackhole_plasmids)
else:
break

def _get_filters_HTML(self) -> str:
nb_of_black_holes = len(self._get_blackhole_plasmids())
nb_of_black_holes = len(self._get_blackhole_plasmids(use_cached=True))
return (
f'<label for="hide_blackholes">'
f"Hide blackhole plasmids ({nb_of_black_holes} present)"
Expand All @@ -74,7 +81,7 @@ def _get_custom_buttons_HTML(self) -> str:
@property
def description(self) -> str:
description = super().description
blackholes_detected = self.get_nb_of_blackhole_plasmids() > 0
blackholes_detected = len(self._get_blackhole_plasmids(use_cached=True)) > 0
if blackholes_detected:
description += " - WARNING: BLACKHOLE SPOTTED!"
return description

0 comments on commit fc7685e

Please sign in to comment.