Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: switching terminology from blackhole to hub #51

Merged
merged 1 commit into from
Dec 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,11 @@ Usage: plasnet split [OPTIONS] PLASMIDS DISTANCES OUTPUT_DIR
Options:
-d, --distance-threshold FLOAT Distance threshold
-b, --bh-connectivity INTEGER Minimum number of connections a plasmid need
to be considered a blackhole plasmid
to be considered a hub plasmid
-e, --bh-neighbours-edge-density FLOAT
Maximum number of edge density between
blackhole plasmid neighbours to label the
plasmid as blackhole
Maximum number of edge density between hub
plasmid neighbours to label the plasmid as
hub
-p, --output-plasmid-graph Also outputs the full, unsplit, plasmid
graph
--plasmids-metadata PATH Plasmids metadata text file.
Expand Down
13 changes: 0 additions & 13 deletions plasnet/base_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,6 @@ class BaseGraph(nx.Graph): # type: ignore
between the different types of graphs.
"""

# def fix_node_to_subcommunity_attributes(self, node_to_subcommunity, blackhole_plasmids):
# for node, attrs in self.nodes.items():
# if node in node_to_subcommunity:
# attrs["color"] = ColorPicker.get_color_given_index(node_to_subcommunity[node])
# else:
# attrs["color"] = ColorPicker.get_default_color()
#
# if node in blackhole_plasmids:
# attrs["shape"] = "star"
# attrs["is_blackhole"] = True
# else:
# attrs["is_blackhole"] = False

def __init__(self, graph: Optional[nx.Graph] = None, label: str = "") -> None:
super().__init__(graph)
self._label = label
Expand Down
87 changes: 0 additions & 87 deletions plasnet/blackhole_graph.py

This file was deleted.

10 changes: 5 additions & 5 deletions plasnet/community_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,22 @@

import networkx as nx

from plasnet.blackhole_graph import BlackholeGraph
from plasnet.ColorPicker import ColorPicker
from plasnet.hub_graph import HubGraph
from plasnet.subcommunities import Subcommunities
from plasnet.subcommunity_graph import SubcommunityGraph
from plasnet.utils import DistanceDict, DistanceTags


class CommunityGraph(BlackholeGraph):
class CommunityGraph(HubGraph):
def __init__(
self,
graph: Optional[nx.Graph] = None,
blackhole_connectivity_threshold: int = 0,
hub_connectivity_threshold: int = 0,
edge_density: float = 0.0,
label: str = "",
):
super().__init__(graph, blackhole_connectivity_threshold, edge_density, label)
super().__init__(graph, hub_connectivity_threshold, edge_density, label)
self._node_to_colour: dict[str, str] = {}

def _get_node_color(self, node: str) -> str:
Expand Down Expand Up @@ -87,7 +87,7 @@ def split_graph_into_subcommunities(

subcommunity = SubcommunityGraph(
self.subgraph(subcommunity_nodes),
self._blackhole_connectivity_threshold,
self._hub_connectivity_threshold,
self._edge_density,
label=f"{self.label}_subcommunity_{subcommunity_index}",
colour=colour,
Expand Down
18 changes: 9 additions & 9 deletions plasnet/ext/templates/visualisation_template.html
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@
'width': 'data(size)',
'height': 'data(size)',
'shape': 'data(shape)',
'is_blackhole': 'data(is_blackhole)'
'is_hub': 'data(is_hub)'
},
},
{
Expand All @@ -235,13 +235,13 @@

<samples_selectors>

// hides blackholes
hide_blackholes = $("#hide_blackholes").is(":checked")
if (hide_blackholes) {
blackholes = cy.elements(`node[is_blackhole > 0]`)
console.log("Removing the following blackholes:")
console.log(blackholes)
cy.remove(blackholes)
// hides hubs
hide_hubs = $("#hide_hubs").is(":checked")
if (hide_hubs) {
hubs = cy.elements(`node[is_hub > 0]`)
console.log("Removing the following hubs:")
console.log(hubs)
cy.remove(hubs)
}

// lays out the graph
Expand Down Expand Up @@ -279,7 +279,7 @@
<p>But hopefully they won't be connected, so we can infer they are still different communities.</p>
<p>Node shapes:</p>
<p>&#9679; Normal plasmids</p>
<p>&#9733; Blackhole plasmids</p>
<p>&#9733; Hub plasmids</p>
</div>
<div>
<br/><br/>
Expand Down
85 changes: 85 additions & 0 deletions plasnet/hub_graph.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import logging
from typing import Any, Optional

import networkx as nx

from plasnet.base_graph import BaseGraph


class HubGraph(BaseGraph):
"""
This is a class that recognises and labels hub plasmids.
"""

def __init__(
self,
graph: Optional[nx.Graph] = None,
hub_connectivity_threshold: int = 0,
edge_density: float = 0.0,
label: str = "",
):
super().__init__(graph, label)
self._hub_connectivity_threshold = hub_connectivity_threshold
self._edge_density = edge_density

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

def _add_special_node_attributes(self, node: str, attrs: dict[str, Any]) -> None:
attrs["is_hub"] = node in self._get_hub_plasmids(use_cached=True)

def _get_hub_plasmids(self, use_cached: bool = False) -> list[str]:
need_to_compute_the_hub_plasmids = not use_cached or not hasattr(self, "_hub_plasmids")
if need_to_compute_the_hub_plasmids:
hub_plasmids_in_graph = []
for node in self.nodes:
if self.degree(node) >= self._hub_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:
hub_plasmids_in_graph.append(node)
logging.debug(f"{node} is a hub plasmid")
else:
logging.debug(
f"{node} is highly connected but does not connect "
f"unrelated plasmids, not a hub plasmid"
)
self._hub_plasmids = hub_plasmids_in_graph

return self._hub_plasmids

def remove_hub_plasmids(self) -> None:
while True:
hub_plasmids = self._get_hub_plasmids()
there_are_still_hub_plasmids = len(hub_plasmids) > 0
if there_are_still_hub_plasmids:
self.remove_nodes_from(hub_plasmids)
else:
break

def _get_filters_HTML(self) -> str:
nb_of_hubs = len(self._get_hub_plasmids(use_cached=True))
return (
f'<label for="hide_hubs">'
f"Hide hub plasmids ({nb_of_hubs} present)"
f"</label>"
f'<input type="checkbox" id="hide_hubs" name="hide_hubs"><br/>'
)

def _get_custom_buttons_HTML(self) -> str:
return '<div><input type="submit" value="Redraw" onclick="redraw()"></div>'

@property
def description(self) -> str:
description = super().description
hubs_detected = len(self._get_hub_plasmids(use_cached=True)) > 0
if hubs_detected:
description += " - WARNING: HUB PLASMID SPOTTED!"
return description
6 changes: 3 additions & 3 deletions plasnet/output_producer.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
from pathlib import Path

from plasnet.base_graph import BaseGraph
from plasnet.blackhole_graph import BlackholeGraph
from plasnet.communities import Communities
from plasnet.hub_graph import HubGraph
from plasnet.list_of_graphs import ListOfGraphs
from plasnet.Templates import Templates
from plasnet.utils import get_libs_dir
Expand All @@ -27,7 +27,7 @@ def produce_communities_visualisation(communities: Communities, outdir: Path) ->

@staticmethod
def produce_subcommunities_visualisation(
subcommunities: ListOfGraphs[BlackholeGraph], outdir: Path
subcommunities: ListOfGraphs[HubGraph], outdir: Path
) -> None:
OutputProducer._write_html_for_all_subgraphs(subcommunities, outdir)
OutputProducer._produce_index_file(outdir, subcommunities, "subcommunity")
Expand All @@ -48,7 +48,7 @@ def _write_html_for_all_subgraphs(

@staticmethod
def _produce_index_file(
outdir: Path, graphs: ListOfGraphs[BlackholeGraph], objects_description: str
outdir: Path, graphs: ListOfGraphs[HubGraph], objects_description: str
) -> None:
sorted_graphs = graphs.get_graphs_sorted_by_size()
index_src = Templates.read_template("index_template")
Expand Down
8 changes: 4 additions & 4 deletions plasnet/plasnet_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,15 @@ def cli() -> None:
"-b",
type=int,
default=10,
help="Minimum number of connections a plasmid need to be considered a blackhole plasmid",
help="Minimum number of connections a plasmid need to be considered a hub plasmid",
)
@click.option(
"--bh-neighbours-edge-density",
"-e",
type=float,
default=0.2,
help="Maximum number of edge density between blackhole plasmid neighbours to "
"label the plasmid as blackhole",
help="Maximum number of edge density between hub plasmid neighbours to "
"label the plasmid as hub",
)
@click.option(
"--output-plasmid-graph",
Expand Down Expand Up @@ -206,7 +206,7 @@ def type(
logging.info("Typing communities (i.e. splitting them into subcommunities)")
all_subcommunities = Subcommunities()
for community in communities:
community.remove_blackhole_plasmids()
community.remove_hub_plasmids()
subcommunities = community.split_graph_into_subcommunities(
small_subcommunity_size_threshold
)
Expand Down
6 changes: 3 additions & 3 deletions plasnet/sample_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ class SampleGraph(SubcommunityGraph):
def __init__(
self,
graph: Optional[nx.Graph] = None,
blackhole_connectivity_threshold: int = 0,
hub_connectivity_threshold: int = 0,
edge_density: float = 0.0,
label: str = "",
colour: str = ColorPicker.get_default_color(),
sample_plasmid: Optional[pd.DataFrame] = None,
):
super().__init__(graph, blackhole_connectivity_threshold, edge_density, label, colour)
super().__init__(graph, hub_connectivity_threshold, edge_density, label, colour)
if sample_plasmid is not None:
self._sample_to_plasmids = (
sample_plasmid.groupby("sample")["plasmid"].apply(list).to_dict()
Expand All @@ -29,7 +29,7 @@ def from_subcommunity_graph(
) -> "SampleGraph":
return cls(
subcommunity_graph,
subcommunity_graph._blackhole_connectivity_threshold,
subcommunity_graph._hub_connectivity_threshold,
subcommunity_graph._edge_density,
subcommunity_graph.label,
subcommunity_graph._colour,
Expand Down
8 changes: 4 additions & 4 deletions plasnet/subcommunity_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,20 @@

import networkx as nx

from plasnet.blackhole_graph import BlackholeGraph
from plasnet.ColorPicker import ColorPicker
from plasnet.hub_graph import HubGraph


class SubcommunityGraph(BlackholeGraph):
class SubcommunityGraph(HubGraph):
def __init__(
self,
graph: Optional[nx.Graph] = None,
blackhole_connectivity_threshold: int = 0,
hub_connectivity_threshold: int = 0,
edge_density: float = 0.0,
label: str = "",
colour: str = ColorPicker.get_default_color(),
):
super().__init__(graph, blackhole_connectivity_threshold, edge_density, label)
super().__init__(graph, hub_connectivity_threshold, edge_density, label)
self._colour = colour

def _get_libs_relative_path(self) -> str:
Expand Down
Loading