bmtool 0.7.2__tar.gz → 0.7.2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. {bmtool-0.7.2 → bmtool-0.7.2.1}/PKG-INFO +1 -1
  2. {bmtool-0.7.2 → bmtool-0.7.2.1}/bmtool/bmplot/connections.py +139 -86
  3. {bmtool-0.7.2 → bmtool-0.7.2.1}/bmtool.egg-info/PKG-INFO +1 -1
  4. {bmtool-0.7.2 → bmtool-0.7.2.1}/setup.py +1 -1
  5. {bmtool-0.7.2 → bmtool-0.7.2.1}/LICENSE +0 -0
  6. {bmtool-0.7.2 → bmtool-0.7.2.1}/README.md +0 -0
  7. {bmtool-0.7.2 → bmtool-0.7.2.1}/bmtool/SLURM.py +0 -0
  8. {bmtool-0.7.2 → bmtool-0.7.2.1}/bmtool/__init__.py +0 -0
  9. {bmtool-0.7.2 → bmtool-0.7.2.1}/bmtool/__main__.py +0 -0
  10. {bmtool-0.7.2 → bmtool-0.7.2.1}/bmtool/analysis/__init__.py +0 -0
  11. {bmtool-0.7.2 → bmtool-0.7.2.1}/bmtool/analysis/entrainment.py +0 -0
  12. {bmtool-0.7.2 → bmtool-0.7.2.1}/bmtool/analysis/lfp.py +0 -0
  13. {bmtool-0.7.2 → bmtool-0.7.2.1}/bmtool/analysis/netcon_reports.py +0 -0
  14. {bmtool-0.7.2 → bmtool-0.7.2.1}/bmtool/analysis/spikes.py +0 -0
  15. {bmtool-0.7.2 → bmtool-0.7.2.1}/bmtool/bmplot/__init__.py +0 -0
  16. {bmtool-0.7.2 → bmtool-0.7.2.1}/bmtool/bmplot/entrainment.py +0 -0
  17. {bmtool-0.7.2 → bmtool-0.7.2.1}/bmtool/bmplot/lfp.py +0 -0
  18. {bmtool-0.7.2 → bmtool-0.7.2.1}/bmtool/bmplot/netcon_reports.py +0 -0
  19. {bmtool-0.7.2 → bmtool-0.7.2.1}/bmtool/bmplot/spikes.py +0 -0
  20. {bmtool-0.7.2 → bmtool-0.7.2.1}/bmtool/connectors.py +0 -0
  21. {bmtool-0.7.2 → bmtool-0.7.2.1}/bmtool/debug/__init__.py +0 -0
  22. {bmtool-0.7.2 → bmtool-0.7.2.1}/bmtool/debug/commands.py +0 -0
  23. {bmtool-0.7.2 → bmtool-0.7.2.1}/bmtool/debug/debug.py +0 -0
  24. {bmtool-0.7.2 → bmtool-0.7.2.1}/bmtool/graphs.py +0 -0
  25. {bmtool-0.7.2 → bmtool-0.7.2.1}/bmtool/manage.py +0 -0
  26. {bmtool-0.7.2 → bmtool-0.7.2.1}/bmtool/plot_commands.py +0 -0
  27. {bmtool-0.7.2 → bmtool-0.7.2.1}/bmtool/singlecell.py +0 -0
  28. {bmtool-0.7.2 → bmtool-0.7.2.1}/bmtool/synapses.py +0 -0
  29. {bmtool-0.7.2 → bmtool-0.7.2.1}/bmtool/util/__init__.py +0 -0
  30. {bmtool-0.7.2 → bmtool-0.7.2.1}/bmtool/util/commands.py +0 -0
  31. {bmtool-0.7.2 → bmtool-0.7.2.1}/bmtool/util/neuron/__init__.py +0 -0
  32. {bmtool-0.7.2 → bmtool-0.7.2.1}/bmtool/util/neuron/celltuner.py +0 -0
  33. {bmtool-0.7.2 → bmtool-0.7.2.1}/bmtool/util/util.py +0 -0
  34. {bmtool-0.7.2 → bmtool-0.7.2.1}/bmtool.egg-info/SOURCES.txt +0 -0
  35. {bmtool-0.7.2 → bmtool-0.7.2.1}/bmtool.egg-info/dependency_links.txt +0 -0
  36. {bmtool-0.7.2 → bmtool-0.7.2.1}/bmtool.egg-info/entry_points.txt +0 -0
  37. {bmtool-0.7.2 → bmtool-0.7.2.1}/bmtool.egg-info/requires.txt +0 -0
  38. {bmtool-0.7.2 → bmtool-0.7.2.1}/bmtool.egg-info/top_level.txt +0 -0
  39. {bmtool-0.7.2 → bmtool-0.7.2.1}/pyproject.toml +0 -0
  40. {bmtool-0.7.2 → bmtool-0.7.2.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bmtool
3
- Version: 0.7.2
3
+ Version: 0.7.2.1
4
4
  Summary: BMTool
5
5
  Home-page: https://github.com/cyneuro/bmtool
6
6
  Download-URL:
@@ -12,7 +12,6 @@ import matplotlib.pyplot as plt
12
12
  import numpy as np
13
13
  import pandas as pd
14
14
  from IPython import get_ipython
15
- from neuron import h
16
15
 
17
16
  from ..util import util
18
17
 
@@ -981,104 +980,158 @@ def distance_delay_plot(
981
980
  plt.show()
982
981
 
983
982
 
984
- def plot_synapse_location_histograms(config, target_model, source=None, target=None):
983
+ def plot_synapse_location(config: str, source: str, target: str, sids: str, tids: str) -> tuple:
985
984
  """
986
- generates a histogram of the positions of the synapses on a cell broken down by section
987
- config: a BMTK config
988
- target_model: the name of the model_template used when building the BMTK node
989
- source: The source BMTK network
990
- target: The target BMTK network
991
- """
992
- # Load mechanisms and template
993
-
994
- util.load_templates_from_config(config)
995
-
996
- # Load node and edge data
997
- nodes, edges = util.load_nodes_edges_from_config(config)
998
- nodes = nodes[source]
999
- edges = edges[f"{source}_to_{target}"]
1000
-
1001
- # Map target_node_id to model_template
1002
- edges["target_model_template"] = edges["target_node_id"].map(nodes["model_template"])
985
+ Generates a connectivity matrix showing synaptic distribution across different cell sections.
1003
986
 
1004
- # Map source_node_id to pop_name
1005
- edges["source_pop_name"] = edges["source_node_id"].map(nodes["pop_name"])
1006
-
1007
- edges = edges[edges["target_model_template"] == target_model]
1008
-
1009
- # Create the cell model from target model
1010
- cell = getattr(h, target_model.split(":")[1])()
1011
-
1012
- # Create a mapping from section index to section name
1013
- section_id_to_name = {}
1014
- for idx, sec in enumerate(cell.all):
1015
- section_id_to_name[idx] = sec.name()
1016
-
1017
- # Add a new column with section names based on afferent_section_id
1018
- edges["afferent_section_name"] = edges["afferent_section_id"].map(section_id_to_name)
1019
-
1020
- # Get unique sections and source populations
1021
- unique_pops = edges["source_pop_name"].unique()
1022
-
1023
- # Filter to only include sections with data
1024
- section_counts = edges["afferent_section_name"].value_counts()
1025
- sections_with_data = section_counts[section_counts > 0].index.tolist()
987
+ Parameters
988
+ ----------
989
+ config : str
990
+ Path to BMTK config file
991
+ source : str
992
+ The source BMTK network name
993
+ target : str
994
+ The target BMTK network name
995
+ sids : str
996
+ Column name in nodes file containing source population identifiers
997
+ tids : str
998
+ Column name in nodes file containing target population identifiers
999
+
1000
+ Returns
1001
+ -------
1002
+ tuple
1003
+ (matplotlib.figure.Figure, matplotlib.axes.Axes) containing the plot
1004
+
1005
+ Raises
1006
+ ------
1007
+ ValueError
1008
+ If required parameters are missing or invalid
1009
+ RuntimeError
1010
+ If template loading or cell instantiation fails
1011
+ """
1012
+ import matplotlib.pyplot as plt
1013
+ import numpy as np
1014
+ from neuron import h
1015
+
1016
+ # Validate inputs
1017
+ if not all([config, source, target, sids, tids]):
1018
+ raise ValueError(
1019
+ "Missing required parameters: config, source, target, sids, and tids must be provided"
1020
+ )
1026
1021
 
1027
- # Create a figure with subplots for each section
1028
- plt.figure(figsize=(8, 12))
1022
+ try:
1023
+ # Load mechanisms and template
1024
+ util.load_templates_from_config(config)
1025
+ except Exception as e:
1026
+ raise RuntimeError(f"Failed to load templates from config: {str(e)}")
1029
1027
 
1030
- # Color map for source populations
1031
- color_map = plt.cm.tab10(np.linspace(0, 1, len(unique_pops)))
1032
- pop_colors = {pop: color for pop, color in zip(unique_pops, color_map)}
1028
+ try:
1029
+ # Load node and edge data
1030
+ nodes, edges = util.load_nodes_edges_from_config(config)
1031
+ if source not in nodes or f"{source}_to_{target}" not in edges:
1032
+ raise ValueError(f"Source '{source}' or target '{target}' networks not found in data")
1033
1033
 
1034
- # Create a histogram for each section
1035
- for i, section in enumerate(sections_with_data):
1036
- ax = plt.subplot(len(sections_with_data), 1, i + 1)
1034
+ nodes = nodes[source]
1035
+ edges = edges[f"{source}_to_{target}"]
1036
+ except Exception as e:
1037
+ raise RuntimeError(f"Failed to load nodes and edges: {str(e)}")
1037
1038
 
1038
- # Get data for this section
1039
- section_data = edges[edges["afferent_section_name"] == section]
1039
+ # Map identifiers while checking for missing values
1040
+ edges["target_model_template"] = edges["target_node_id"].map(nodes["model_template"])
1041
+ edges["target_pop_name"] = edges["target_node_id"].map(nodes[tids])
1042
+ edges["source_pop_name"] = edges["source_node_id"].map(nodes[sids])
1043
+
1044
+ if edges["target_model_template"].isnull().any():
1045
+ print("Warning: Some target nodes missing model template")
1046
+ if edges["target_pop_name"].isnull().any():
1047
+ print("Warning: Some target nodes missing population name")
1048
+ if edges["source_pop_name"].isnull().any():
1049
+ print("Warning: Some source nodes missing population name")
1050
+
1051
+ # Get unique populations
1052
+ source_pops = edges["source_pop_name"].unique()
1053
+ target_pops = edges["target_pop_name"].unique()
1054
+
1055
+ # Initialize matrices
1056
+ num_connections = np.zeros((len(source_pops), len(target_pops)))
1057
+ text_data = np.empty((len(source_pops), len(target_pops)), dtype=object)
1058
+
1059
+ # Create mappings for indices
1060
+ source_pop_to_idx = {pop: idx for idx, pop in enumerate(source_pops)}
1061
+ target_pop_to_idx = {pop: idx for idx, pop in enumerate(target_pops)}
1062
+
1063
+ # Cache for section mappings to avoid recreating cells
1064
+ section_mappings = {}
1065
+
1066
+ # Calculate connectivity statistics
1067
+ for source_pop in source_pops:
1068
+ for target_pop in target_pops:
1069
+ # Filter edges for this source-target pair
1070
+ filtered_edges = edges[
1071
+ (edges["source_pop_name"] == source_pop) & (edges["target_pop_name"] == target_pop)
1072
+ ]
1040
1073
 
1041
- # Group by source population
1042
- for pop_name, pop_group in section_data.groupby("source_pop_name"):
1043
- if len(pop_group) > 0:
1044
- ax.hist(
1045
- pop_group["afferent_section_pos"],
1046
- bins=15,
1047
- alpha=0.7,
1048
- label=pop_name,
1049
- color=pop_colors[pop_name],
1050
- )
1074
+ source_idx = source_pop_to_idx[source_pop]
1075
+ target_idx = target_pop_to_idx[target_pop]
1051
1076
 
1052
- # Set title and labels
1053
- ax.set_title(f"{section}", fontsize=10)
1054
- ax.set_xlabel("Section Position", fontsize=8)
1055
- ax.set_ylabel("Frequency", fontsize=8)
1056
- ax.tick_params(labelsize=7)
1057
- ax.grid(True, alpha=0.3)
1077
+ if len(filtered_edges) == 0:
1078
+ num_connections[source_idx, target_idx] = 0
1079
+ text_data[source_idx, target_idx] = "No connections"
1080
+ continue
1058
1081
 
1059
- # Only add legend to the first plot
1060
- if i == 0:
1061
- ax.legend(fontsize=8)
1082
+ total_connections = len(filtered_edges)
1083
+ target_model_template = filtered_edges["target_model_template"].iloc[0]
1062
1084
 
1063
- plt.tight_layout()
1064
- plt.suptitle(
1065
- "Connection Distribution by Cell Section and Source Population", fontsize=16, y=1.02
1085
+ try:
1086
+ # Get or create section mapping for this model
1087
+ if target_model_template not in section_mappings:
1088
+ cell_class_name = (
1089
+ target_model_template.split(":")[1]
1090
+ if ":" in target_model_template
1091
+ else target_model_template
1092
+ )
1093
+ cell = getattr(h, cell_class_name)()
1094
+
1095
+ # Create section mapping
1096
+ section_mapping = {}
1097
+ for idx, sec in enumerate(cell.all):
1098
+ section_mapping[idx] = sec.name().split(".")[-1] # Clean name
1099
+ section_mappings[target_model_template] = section_mapping
1100
+
1101
+ section_mapping = section_mappings[target_model_template]
1102
+
1103
+ # Calculate section distribution
1104
+ section_counts = filtered_edges["afferent_section_id"].value_counts()
1105
+ section_percentages = (section_counts / total_connections * 100).round(1)
1106
+
1107
+ # Format section distribution text - show all sections
1108
+ section_display = []
1109
+ for section_id, percentage in section_percentages.items():
1110
+ section_name = section_mapping.get(section_id, f"sec_{section_id}")
1111
+ section_display.append(f"{section_name}:{percentage}%")
1112
+
1113
+ num_connections[source_idx, target_idx] = total_connections
1114
+ text_data[source_idx, target_idx] = "\n".join(section_display)
1115
+
1116
+ except Exception as e:
1117
+ print(f"Warning: Error processing {target_model_template}: {str(e)}")
1118
+ num_connections[source_idx, target_idx] = total_connections
1119
+ text_data[source_idx, target_idx] = "Section info N/A"
1120
+
1121
+ # Create the plot
1122
+ title = f"Synaptic Distribution by Section: {source} to {target}"
1123
+ fig, ax = plot_connection_info(
1124
+ text=text_data,
1125
+ num=num_connections,
1126
+ source_labels=list(source_pops),
1127
+ target_labels=list(target_pops),
1128
+ title=title,
1129
+ syn_info="1",
1066
1130
  )
1067
- if is_notebook:
1131
+ if is_notebook():
1068
1132
  plt.show()
1069
1133
  else:
1070
- pass
1071
-
1072
- # Create a summary table
1073
- print("Summary of connections by section and source population:")
1074
- pivot_table = edges.pivot_table(
1075
- values="afferent_section_id",
1076
- index="afferent_section_name",
1077
- columns="source_pop_name",
1078
- aggfunc="count",
1079
- fill_value=0,
1080
- )
1081
- print(pivot_table)
1134
+ return fig, ax
1082
1135
 
1083
1136
 
1084
1137
  def plot_connection_info(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bmtool
3
- Version: 0.7.2
3
+ Version: 0.7.2.1
4
4
  Summary: BMTool
5
5
  Home-page: https://github.com/cyneuro/bmtool
6
6
  Download-URL:
@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
5
5
 
6
6
  setup(
7
7
  name="bmtool",
8
- version="0.7.2",
8
+ version="0.7.2.1",
9
9
  author="Neural Engineering Laboratory at the University of Missouri",
10
10
  author_email="gregglickert@mail.missouri.edu",
11
11
  description="BMTool",
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes