Skip to content

Commit

Permalink
Refactor calculate tasks (#29)
Browse files Browse the repository at this point in the history
* Update convert to network task to take single dataframe

* Simplify calculate measures tasks to take single network

* Clean up calculate measures tasks

* Remove calculate cluster tasks

* Fix README capitalization
  • Loading branch information
jessicasyu authored Aug 30, 2023
1 parent 40ff0bc commit 9bf0695
Show file tree
Hide file tree
Showing 8 changed files with 56 additions and 204 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[![Build Status](https://allen-cell-animated.github.io/abm-colony-collection/_badges/build.svg)](https://github.com/allen-cell-animated/abm-colony-collection/actions?query=workflow%3Abuild)
[![Lint Status](https://allen-cell-animated.github.io/abm-colony-collection/_badges/lint.svg)](https://github.com/allen-cell-animated/abm-colony-collection/actions?query=workflow%3Alint)
[![Build status](https://allen-cell-animated.github.io/abm-colony-collection/_badges/build.svg)](https://github.com/allen-cell-animated/abm-colony-collection/actions?query=workflow%3Abuild)
[![Lint status](https://allen-cell-animated.github.io/abm-colony-collection/_badges/lint.svg)](https://github.com/allen-cell-animated/abm-colony-collection/actions?query=workflow%3Alint)
[![Documentation](https://allen-cell-animated.github.io/abm-colony-collection/_badges/documentation.svg)](https://allen-cell-animated.github.io/abm-colony-collection/)
[![Coverage](https://allen-cell-animated.github.io/abm-colony-collection/_badges/coverage.svg)](https://allen-cell-animated.github.io/abm-colony-collection/_coverage/)
[![Code style](https://allen-cell-animated.github.io/abm-colony-collection/_badges/style.svg)](https://github.com/psf/black)
Expand Down
6 changes: 1 addition & 5 deletions src/abm_colony_collection/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
"""Tasks for analyzing colony dynamics including clustering and graph measures."""
"""Tasks for analyzing colony dynamics including neighbors and graph measures."""

from prefect import task

from .calculate_centrality_measures import calculate_centrality_measures
from .calculate_cluster_distances import calculate_cluster_distances
from .calculate_cluster_sizes import calculate_cluster_sizes
from .calculate_degree_measures import calculate_degree_measures
from .calculate_distance_measures import calculate_distance_measures
from .convert_to_network import convert_to_network
Expand All @@ -13,8 +11,6 @@
from .make_voxels_array import make_voxels_array

calculate_centrality_measures = task(calculate_centrality_measures)
calculate_cluster_distances = task(calculate_cluster_distances)
calculate_cluster_sizes = task(calculate_cluster_sizes)
calculate_degree_measures = task(calculate_degree_measures)
calculate_distance_measures = task(calculate_distance_measures)
convert_to_network = task(convert_to_network)
Expand Down
51 changes: 18 additions & 33 deletions src/abm_colony_collection/calculate_centrality_measures.py
Original file line number Diff line number Diff line change
@@ -1,37 +1,22 @@
import networkx as nx
import numpy as np
import pandas as pd


def calculate_centrality_measures(networks: dict) -> pd.DataFrame:
all_measures = []

for (seed, tick), network in networks.items():
degree_centralities = list(nx.degree_centrality(network).values())
closeness_centralities = list(nx.closeness_centrality(network).values())
betweenness_centralities = list(nx.betweenness_centrality(network).values())

degree_centrality_mean = np.mean(degree_centralities)
closeness_centrality_mean = np.mean(closeness_centralities)
betweenness_centrality_mean = np.mean(betweenness_centralities)

degree_centrality_std = np.std(degree_centralities, ddof=1)
closeness_centrality_std = np.std(closeness_centralities, ddof=1)
betweenness_centrality_std = np.std(betweenness_centralities, ddof=1)

all_measures.append(
{
"SEED": seed,
"TICK": tick,
"DEGREE_CENTRALITY_MEAN": degree_centrality_mean,
"CLOSENESS_CENTRALITY_MEAN": closeness_centrality_mean,
"BETWEENNESS_CENTRALITY_MEAN": betweenness_centrality_mean,
"DEGREE_CENTRALITY_STD": degree_centrality_std,
"CLOSENESS_CENTRALITY_STD": closeness_centrality_std,
"BETWEENNESS_CENTRALITY_STD": betweenness_centrality_std,
}
)

all_measures_df = pd.DataFrame(all_measures)

return all_measures_df
def calculate_centrality_measures(network: nx.Graph) -> pd.DataFrame:
# Calculate different centrality measures for network.
degree_centralities = nx.degree_centrality(network)
closeness_centralities = nx.closeness_centrality(network)
betweenness_centralities = nx.betweenness_centrality(network)

# Extract centrality measures for each node in network.
measures = [
{
"ID": node,
"DEGREE_CENTRALITY": degree_centralities[node],
"CLOSENESS_CENTRALITY": closeness_centralities[node],
"BETWEENNESS_CENTRALITY": betweenness_centralities[node],
}
for node in network.nodes
]

return pd.DataFrame(measures)
64 changes: 0 additions & 64 deletions src/abm_colony_collection/calculate_cluster_distances.py

This file was deleted.

26 changes: 0 additions & 26 deletions src/abm_colony_collection/calculate_cluster_sizes.py

This file was deleted.

32 changes: 11 additions & 21 deletions src/abm_colony_collection/calculate_degree_measures.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,15 @@
import numpy as np
import networkx as nx
import pandas as pd


def calculate_degree_measures(networks: dict) -> pd.DataFrame:
all_measures = []
def calculate_degree_measures(network: nx.Graph) -> pd.DataFrame:
# Extract degree for each node in network.
measures = [
{
"ID": node,
"DEGREE": degree,
}
for node, degree in network.degree()
]

for (seed, tick), network in networks.items():
degrees = sorted([d for n, d in network.degree()], reverse=True)
degree_mean = np.mean(degrees)
degree_std = np.std(degrees, ddof=1)

all_measures.append(
{
"SEED": seed,
"TICK": tick,
"DEGREES": degrees,
"DEGREE_MEAN": degree_mean,
"DEGREE_STD": degree_std,
}
)

all_measures_df = pd.DataFrame(all_measures)

return all_measures_df
return pd.DataFrame(measures)
52 changes: 14 additions & 38 deletions src/abm_colony_collection/calculate_distance_measures.py
Original file line number Diff line number Diff line change
@@ -1,47 +1,23 @@
from typing import Union

import networkx as nx
import numpy as np
import pandas as pd


def calculate_distance_measures(networks: dict) -> pd.DataFrame:
all_measures = []

for (seed, tick), network in networks.items():
if not nx.is_connected(network):
subnetworks = [
network.subgraph(component) for component in nx.connected_components(network)
]

radius = np.mean([nx.radius(subnetwork) for subnetwork in subnetworks])
diameter = np.mean([nx.diameter(subnetwork) for subnetwork in subnetworks])

eccentricities = [nx.eccentricity(subnetwork) for subnetwork in subnetworks]
eccentricity = np.mean([np.mean(list(ecc.values())) for ecc in eccentricities])
def calculate_distance_measures(network: nx.Graph) -> pd.DataFrame:
measures: list[dict[str, Union[int, float]]] = []

shortest_paths = [
nx.average_shortest_path_length(subnetwork) for subnetwork in subnetworks
]
shortest_path = np.mean(shortest_paths)
else:
radius = nx.radius(network)
diameter = nx.diameter(network)
for component in nx.connected_components(network):
# Calculate eccentricity for connected subnetwork.
eccentricity = nx.eccentricity(network.subgraph(component))

ecc = nx.eccentricity(network)
eccentricity = np.mean(list(ecc.values()))

shortest_path = nx.average_shortest_path_length(network)

all_measures.append(
# Extract distance measures for each node in subnetwork.
measures = measures + [
{
"SEED": seed,
"TICK": tick,
"RADIUS": radius,
"DIAMETER": diameter,
"ECCENTRICITY": eccentricity,
"SHORTEST_PATH": shortest_path,
"ID": node,
"ECCENTRICITY": eccentricity[node],
}
)

all_measures_df = pd.DataFrame(all_measures)
for node in component
]

return all_measures_df
return pd.DataFrame(measures)
25 changes: 10 additions & 15 deletions src/abm_colony_collection/convert_to_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,15 @@


def convert_to_network(neighbors: pd.DataFrame) -> nx.Graph:
networks = {}
nodes = list(neighbors["ID"].values)
edges = [
(node_id, neighbor_id)
for node_id, neighbor_ids in zip(neighbors["ID"], neighbors["NEIGHBORS"])
for neighbor_id in neighbor_ids
]

for tick, group in neighbors.groupby("TICK"):
nodes = list(group["ID"].values)
edges = [
(node_id, neighbor_id)
for node_id, neighbor_ids in zip(group["ID"], group["NEIGHBORS"])
for neighbor_id in neighbor_ids
]
network = nx.Graph()
network.add_nodes_from(nodes)
network.add_edges_from(edges)

network = nx.Graph()
network.add_nodes_from(nodes)
network.add_edges_from(edges)

networks[tick] = network

return networks
return network

0 comments on commit 9bf0695

Please sign in to comment.