Skip to content

Commit

Permalink
added bmplot examples and other small fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
GregGlickert committed Nov 13, 2024
1 parent 9ef9c08 commit e94398a
Show file tree
Hide file tree
Showing 356 changed files with 682 additions and 92,996 deletions.
398 changes: 28 additions & 370 deletions README.md

Large diffs are not rendered by default.

69 changes: 36 additions & 33 deletions bmtool/bmplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ def divergence_connection_matrix(config=None,title=None,sources=None, targets=No
plot_connection_info(syn_info,data,source_labels,target_labels,title, save_file=save_file)
return

def gap_junction_matrix(config=None,title=None,sources=None, targets=None, sids=None,tids=None, no_prepend_pop=False,save_file=None,type='convergence'):
def gap_junction_matrix(config=None,title=None,sources=None, targets=None, sids=None,tids=None, no_prepend_pop=False,save_file=None,method='convergence'):
"""
Generates connection plot displaying gap junction data.
config: A BMTK simulation config
Expand All @@ -290,7 +290,7 @@ def gap_junction_matrix(config=None,title=None,sources=None, targets=None, sids=
raise Exception("config not defined")
if not sources or not targets:
raise Exception("Sources or targets not defined")
if type !='convergence' and type!='percent':
if method !='convergence' and method!='percent':
raise Exception("type must be 'convergence' or 'percent'")
sources = sources.split(",")
targets = targets.split(",")
Expand All @@ -302,7 +302,7 @@ def gap_junction_matrix(config=None,title=None,sources=None, targets=None, sids=
tids = tids.split(",")
else:
tids = []
syn_info, data, source_labels, target_labels = util.gap_junction_connections(config=config,nodes=None,edges=None,sources=sources,targets=targets,sids=sids,tids=tids,prepend_pop=not no_prepend_pop,type=type)
syn_info, data, source_labels, target_labels = util.gap_junction_connections(config=config,nodes=None,edges=None,sources=sources,targets=targets,sids=sids,tids=tids,prepend_pop=not no_prepend_pop,method=method)


def filter_rows(syn_info, data, source_labels, target_labels):
Expand Down Expand Up @@ -350,7 +350,7 @@ def filter_rows_and_columns(syn_info,data,source_labels,target_labels):
plot_connection_info(syn_info,data,source_labels,target_labels,title, save_file=save_file)
return

def connection_histogram(config=None,nodes=None,edges=None,sources=[],targets=[],sids=[],tids=[],prepend_pop=True,synaptic_info='0',
def connection_histogram(config=None,nodes=None,edges=None,sources=[],targets=[],sids=[],tids=[],no_prepend_pop=True,synaptic_info='0',
source_cell = None,target_cell = None,include_gap=True):
"""
Generates histogram of number of connections individual cells in a population receieve from another population
Expand Down Expand Up @@ -379,15 +379,15 @@ def connection_pair_histogram(**kwargs):
conn_mean = statistics.mean(node_pairs.values)
conn_std = statistics.stdev(node_pairs.values)
conn_median = statistics.median(node_pairs.values)
label = "mean {:.2f} std ({:.2f}) median {:.2f}".format(conn_mean,conn_std,conn_median)
label = "mean {:.2f} std {:.2f} median {:.2f}".format(conn_mean,conn_std,conn_median)
except: # lazy fix for std not calculated with 1 node
conn_mean = statistics.mean(node_pairs.values)
conn_median = statistics.median(node_pairs.values)
label = "mean {:.2f} median {:.2f}".format(conn_mean,conn_median)
plt.hist(node_pairs.values,density=True,bins='auto',stacked=True,label=label)
plt.hist(node_pairs.values,density=False,bins='auto',stacked=True,label=label)
plt.legend()
plt.xlabel("# of conns from {} to {}".format(source_cell,target_cell))
plt.ylabel("Density")
plt.ylabel("# of cells")
plt.show()
else: # dont care about other cell pairs so pass
pass
Expand All @@ -406,10 +406,10 @@ def connection_pair_histogram(**kwargs):
tids = tids.split(",")
else:
tids = []
util.relation_matrix(config,nodes,edges,sources,targets,sids,tids,prepend_pop,relation_func=connection_pair_histogram,synaptic_info=synaptic_info)
util.relation_matrix(config,nodes,edges,sources,targets,sids,tids,not no_prepend_pop,relation_func=connection_pair_histogram,synaptic_info=synaptic_info)

def connection_distance(config: str,source: str,target: str,
source_cell_id: int,target_id_type: str) -> None:
def connection_distance(config: str,sources: str,targets: str,
source_cell_id: int,target_id_type: str,ignore_z:bool=False) -> None:
"""
Plots the 3D spatial distribution of target nodes relative to a source node
and a histogram of distances from the source node to each target node.
Expand All @@ -421,20 +421,21 @@ def connection_distance(config: str,source: str,target: str,
targets: (str) network name(s) to plot
source_cell_id : (int) ID of the source cell for calculating distances to target nodes.
target_id_type : (str) A string to filter target nodes based off the target_query.
ignore_z : (bool) A bool to ignore_z axis or not for when calculating distance default is False
"""
if not config:
raise Exception("config not defined")
if not source or not target:
if not sources or not targets:
raise Exception("Sources or targets not defined")
#if source != target:
#raise Exception("Code is setup for source and target to be the same! Look at source code for function to add feature")

# Load nodes and edges based on config file
nodes, edges = util.load_nodes_edges_from_config(config)

edge_network = source + "_to_" + target
node_network = source
edge_network = sources + "_to_" + targets
node_network = sources

# Filter edges to obtain connections originating from the source node
edge = edges[edge_network]
Expand All @@ -450,16 +451,25 @@ def connection_distance(config: str,source: str,target: str,
source_node = node.loc[node.index == source_cell_id]

# Calculate distances between source node and each target node
target_positions = target_nodes[['pos_x', 'pos_y', 'pos_z']].values
source_position = np.array([source_node['pos_x'], source_node['pos_y'], source_node['pos_z']]).ravel() # Ensure 1D shape
if ignore_z:
target_positions = target_nodes[['pos_x', 'pos_y']].values
source_position = np.array([source_node['pos_x'], source_node['pos_y']]).ravel() # Ensure 1D shape
else:
target_positions = target_nodes[['pos_x', 'pos_y', 'pos_z']].values
source_position = np.array([source_node['pos_x'], source_node['pos_y'], source_node['pos_z']]).ravel() # Ensure 1D shape
distances = np.linalg.norm(target_positions - source_position, axis=1)

# Plot positions of source and target nodes in 3D space
fig = plt.figure(figsize=(8, 6))
ax = fig.add_subplot(111, projection='3d')

ax.scatter(target_nodes['pos_x'], target_nodes['pos_y'], target_nodes['pos_z'], c='blue', label="target cells")
ax.scatter(source_node['pos_x'], source_node['pos_y'], source_node['pos_z'], c='red', label="source cell")
# Plot positions of source and target nodes in 3D space or 2D
if ignore_z:
fig = plt.figure(figsize=(8, 6))
ax = fig.add_subplot(111)
ax.scatter(target_nodes['pos_x'], target_nodes['pos_y'], c='blue', label="target cells")
ax.scatter(source_node['pos_x'], source_node['pos_y'], c='red', label="source cell")
else:
fig = plt.figure(figsize=(8, 6))
ax = fig.add_subplot(111, projection='3d')
ax.scatter(target_nodes['pos_x'], target_nodes['pos_y'], target_nodes['pos_z'], c='blue', label="target cells")
ax.scatter(source_node['pos_x'], source_node['pos_y'], source_node['pos_z'], c='red', label="source cell")

# Optional: Add text annotations for distances
# for i, distance in enumerate(distances):
Expand All @@ -474,7 +484,7 @@ def connection_distance(config: str,source: str,target: str,
plt.hist(distances, bins=20, color='blue', edgecolor='black')
plt.xlabel("Distance")
plt.ylabel("Count")
plt.title("Distance from Source Node to Each Target Node")
plt.title(f"Distance from Source Node to Each Target Node")
plt.grid(True)
plt.show()

Expand Down Expand Up @@ -914,7 +924,7 @@ def plot_3d_positions(config=None, populations_list=None, group_by=None, title=N

return

def cell_rotation_3d(config=None, populations_list=None, group_by=None, title=None, save_file=None, quiver_length=None, arrow_length_ratio=None, group=None, max_cells=1000000):
def plot_3d_cell_rotation(config=None, populations_list=None, group_by=None, title=None, save_file=None, quiver_length=None, arrow_length_ratio=None, group=None, subset=None):
from scipy.spatial.transform import Rotation as R
if not config:
raise Exception("config not defined")
Expand Down Expand Up @@ -957,23 +967,16 @@ def cell_rotation_3d(config=None, populations_list=None, group_by=None, title=No
groupings = [(None, nodes_df)]
color_map = ['blue']

cells_plotted = 0
for color, (group_name, group_df) in zip(color_map, groupings):
if subset is not None:
group_df = group_df.iloc[::subset]

if group and group_name not in group.split(","):
continue

if "pos_x" not in group_df or "rotation_angle_xaxis" not in group_df:
continue

if cells_plotted >= max_cells:
continue

if len(group_df) + cells_plotted > max_cells:
total_remaining = max_cells - cells_plotted
group_df = group_df[:total_remaining]

cells_plotted += len(group_df)

X = group_df["pos_x"]
Y = group_df["pos_y"]
Z = group_df["pos_z"]
Expand Down
4 changes: 2 additions & 2 deletions bmtool/connectors.py
Original file line number Diff line number Diff line change
Expand Up @@ -1272,8 +1272,8 @@ class GapJunction(UnidirectionConnector):
Similar to `UnidirectionConnector`.
"""

def __init__(self, p=1., p_arg=None, verbose=True,report_name=None):
super().__init__(p=p, p_arg=p_arg, verbose=verbose,report_name=None)
def __init__(self, p=1., p_arg=None, verbose=True,save_report=True,report_name=None):
super().__init__(p=p, p_arg=p_arg, verbose=verbose,save_report=save_report,report_name=None)


def setup_nodes(self, source=None, target=None):
Expand Down
18 changes: 6 additions & 12 deletions bmtool/util/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -736,8 +736,7 @@ def total_connection_relationship(**kwargs):

return relation_matrix(config,nodes,edges,sources,targets,sids,tids,prepend_pop,relation_func=total_connection_relationship)

def gap_junction_connections(config=None,nodes=None,edges=None,sources=[],targets=[],sids=[],tids=[],prepend_pop=True,type='convergence'):
import pandas as pd
def gap_junction_connections(config=None,nodes=None,edges=None,sources=[],targets=[],sids=[],tids=[],prepend_pop=True,method='convergence'):


def total_connection_relationship(**kwargs): #reduced version of original function; only gets mean+std
Expand All @@ -751,7 +750,7 @@ def total_connection_relationship(**kwargs): #reduced version of original functi
#print(cons)

try:
cons = cons[cons['is_gap_junction'] != True]
cons = cons[cons['is_gap_junction'] == True]
except:
raise Exception("no gap junctions found to drop from connections")
mean = cons['target_node_id'].value_counts().mean()
Expand All @@ -770,7 +769,7 @@ def precent_func(**kwargs): #barely different than original function; only gets
cons = edges[(edges[source_id_type] == source_id) & (edges[target_id_type]==target_id)]
#add functionality that shows only the one's with gap_junctions
try:
cons = cons[cons['is_gap_junction'] != True]
cons = cons[cons['is_gap_junction'] == True]
except:
raise Exception("no gap junctions found to drop from connections")

Expand All @@ -780,20 +779,15 @@ def precent_func(**kwargs): #barely different than original function; only gets
num_targets = t_list[target_id_type].value_counts().sort_index().loc[target_id]


total = round(total_cons / (num_sources*num_targets) * 100,2)
total = round(total_cons / (num_sources*num_targets) * 100,2) * 2 #not sure why but the percent is off by roughly 2 times ill make khuram fix it
return total

if type == 'convergence':
if method == 'convergence':
return relation_matrix(config,nodes,edges,sources,targets,sids,tids,prepend_pop,relation_func=total_connection_relationship)
elif type == 'percent':
elif method == 'percent':
return relation_matrix(config,nodes,edges,sources,targets,sids,tids,prepend_pop,relation_func=precent_func)


def gap_junction_percent_connections(config=None,nodes=None,edges=None,sources=[],targets=[],sids=[],tids=[],prepend_pop=True,method=None):
import pandas as pd



def connection_probabilities(config=None,nodes=None,edges=None,sources=[],
targets=[],sids=[],tids=[],prepend_pop=True,dist_X=True,dist_Y=True,dist_Z=True,num_bins=10,include_gap=True):

Expand Down
597 changes: 589 additions & 8 deletions examples/bmplot/bmplot.ipynb

Large diffs are not rendered by default.

198 changes: 0 additions & 198 deletions examples/bmplot/build_network.ipynb

This file was deleted.

28 changes: 16 additions & 12 deletions examples/bmplot/circuit_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,20 @@
"$COMPONENTS_DIR": "$BASE_DIR/components"
},
"components": {
"mechanisms_dir": "$COMPONENTS_DIR/mechanisms",
"__pycache___dir": "$COMPONENTS_DIR/__pycache__",
"biophysical_neuron_models_dir": "$COMPONENTS_DIR/biophysical_neuron_models",
"filter_models_dir": "$COMPONENTS_DIR/filter_models",
"mechanisms_dir": "$COMPONENTS_DIR/mechanisms",
"morphologies_dir": "$COMPONENTS_DIR/morphologies",
"__pycache___dir": "$COMPONENTS_DIR/__pycache__",
"point_neuron_models_dir": "$COMPONENTS_DIR/point_neuron_models",
"synaptic_models_dir": "$COMPONENTS_DIR/synaptic_models",
"biophysical_neuron_models_dir": "$COMPONENTS_DIR/biophysical_neuron_models",
"templates_dir": "$COMPONENTS_DIR/templates",
"point_neuron_models_dir": "$COMPONENTS_DIR/point_neuron_models"
"templates_dir": "$COMPONENTS_DIR/templates"
},
"networks": {
"nodes": [
{
"node_types_file": "$NETWORK_DIR/example_net_node_types.csv",
"nodes_file": "$NETWORK_DIR/example_net_nodes.h5"
"nodes_file": "$NETWORK_DIR/bio_net_nodes.h5",
"node_types_file": "$NETWORK_DIR/bio_net_node_types.csv"
},
{
"nodes_file": "$NETWORK_DIR/background_nodes.h5",
Expand All @@ -27,14 +27,18 @@
],
"edges": [
{
"edges_file": "$NETWORK_DIR/background_example_net_edges.h5",
"edge_types_file": "$NETWORK_DIR/background_example_net_edge_types.csv"
"edge_types_file": "$NETWORK_DIR/bio_net_bio_net_edge_types.csv",
"edges_file": "$NETWORK_DIR/bio_net_bio_net_edges.h5"
},
{
"edge_types_file": "$NETWORK_DIR/example_net_example_net_edge_types.csv",
"edges_file": "$NETWORK_DIR/example_net_example_net_edges.h5"
"edge_types_file": "$NETWORK_DIR/background_bio_net_edge_types.csv",
"edges_file": "$NETWORK_DIR/background_bio_net_edges.h5"
}
],
"gap_juncs": []
"gap_juncs": [
{
"gap_juncs_file": "/home/gjgpb9/cortex_modeling/bmtool/examples/bmplot/network/bio_net_gap_juncs.h5"
}
]
}
}
105 changes: 0 additions & 105 deletions examples/bmplot/components/Cell_A.hoc

This file was deleted.

Loading

0 comments on commit e94398a

Please sign in to comment.