bmtool 0.7.5.1__py3-none-any.whl → 0.7.6__py3-none-any.whl

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.
@@ -661,7 +661,8 @@ def connection_histogram(
661
661
  (edges[source_id_type] == source_id) & (edges[target_id_type] == target_id)
662
662
  ]
663
663
  if not include_gap:
664
- temp = temp[~temp["is_gap_junction"]]
664
+ gap_col = temp["is_gap_junction"].fillna(False).astype(bool)
665
+ temp = temp[~gap_col]
665
666
  node_pairs = temp.groupby("target_node_id")["source_node_id"].count()
666
667
  try:
667
668
  conn_mean = statistics.mean(node_pairs.values)
@@ -1022,8 +1023,8 @@ def plot_synapse_location(config: str, source: str, target: str, sids: str, tids
1022
1023
  )
1023
1024
 
1024
1025
  # Fix the validation logic - it was using 'or' instead of 'and'
1025
- if syn_feature not in ["afferent_section_id", "afferent_section_pos"]:
1026
- raise ValueError("Currently only syn features supported are afferent_section_id or afferent_section_pos")
1026
+ #if syn_feature not in ["afferent_section_id", "afferent_section_pos"]:
1027
+ # raise ValueError("Currently only syn features supported are afferent_section_id or afferent_section_pos")
1027
1028
 
1028
1029
  try:
1029
1030
  # Load mechanisms and template
bmtool/synapses.py CHANGED
@@ -1175,7 +1175,9 @@ class SynapseTuner:
1175
1175
  amp = np.array(amp)
1176
1176
  amp = amp * 1000 # scale up
1177
1177
  amp = amp.reshape(-1, amp.shape[-1])
1178
- maxamp = amp.max(axis=1 if normalize_by_trial else None)
1178
+
1179
+ # Calculate 90th percentile amplitude for normalization
1180
+ percentile_90 = np.percentile(amp, 90)
1179
1181
 
1180
1182
  def format_array(arr):
1181
1183
  """Format an array to 2 significant figures for cleaner output."""
@@ -1187,49 +1189,42 @@ class SynapseTuner:
1187
1189
  f"Short Term Plasticity Results for {self.train_freq}Hz with {self.train_delay} Delay"
1188
1190
  )
1189
1191
  print("=" * 40)
1190
- print("PPR: Above 1 is facilitating, below 1 is depressing.")
1192
+ print("PPR: Above 0 is facilitating, below 0 is depressing.")
1191
1193
  print("Induction: Above 0 is facilitating, below 0 is depressing.")
1192
1194
  print("Recovery: A measure of how fast STP decays.\n")
1193
1195
 
1194
- # PPR Calculation
1195
- ppr = amp[:, 1:2] / amp[:, 0:1]
1196
+ # PPR Calculation: (Avg 2nd pulse - Avg 1st pulse) / 90th percentile amplitude
1197
+ ppr = (np.mean(amp[:, 1:2]) - np.mean(amp[:, 0:1])) / percentile_90
1196
1198
  print("Paired Pulse Response (PPR)")
1197
- print("Calculation: 2nd pulse / 1st pulse")
1199
+ print("Calculation: (Avg 2nd pulse - Avg 1st pulse) / 90th percentile amplitude")
1198
1200
  print(
1199
- f"Values: ({format_array(amp[:, 1:2])}) / ({format_array(amp[:, 0:1])}) = {format_array(ppr)}\n"
1201
+ f"Values: ({np.mean(amp[:, 1:2]):.3f} - {np.mean(amp[:, 0:1]):.3f}) / {percentile_90:.3f} = {ppr:.3f}\n"
1200
1202
  )
1201
1203
 
1202
- # Induction Calculation
1203
- induction = np.mean((amp[:, 5:8].mean(axis=1) - amp[:, :1].mean(axis=1)) / maxamp)
1204
+ # Induction Calculation: (Avg (6th, 7th, 8th pulses) - Avg 1st pulse) / 90th percentile amplitude
1205
+ induction = (np.mean(amp[:, 5:8]) - np.mean(amp[:, :1])) / percentile_90
1204
1206
  print("Induction")
1205
- print("Calculation: (avg(6th, 7th, 8th pulses) - 1st pulse) / max amps")
1206
- print(
1207
- f"Values: avg({format_array(amp[:, 5:8])}) - {format_array(amp[:, :1])} / {format_array(maxamp)}"
1208
- )
1207
+ print("Calculation: (Avg(6th, 7th, 8th pulses) - Avg 1st pulse) / 90th percentile amplitude")
1209
1208
  print(
1210
- f"({format_array(amp[:, 5:8].mean(axis=1))}) - ({format_array(amp[:, :1].mean(axis=1))}) / {format_array(maxamp)} = {induction:.3f}\n"
1209
+ f"Values: {np.mean(amp[:, 5:8]):.3f} - {np.mean(amp[:, :1]):.3f} / {percentile_90:.3f} = {induction:.3f}\n"
1211
1210
  )
1212
1211
 
1213
- # Recovery Calculation
1214
- recovery = np.mean((amp[:, 8:12].mean(axis=1) - amp[:, :4].mean(axis=1)) / maxamp)
1212
+ # Recovery Calculation: (Avg (9th, 10th, 11th, 12th pulses) - Avg (1st, 2nd, 3rd, 4th pulses)) / 90th percentile amplitude
1213
+ recovery = (np.mean(amp[:, 8:12]) - np.mean(amp[:, :4])) / percentile_90
1215
1214
  print("Recovery")
1216
1215
  print(
1217
- "Calculation: (avg(9th, 10th, 11th, 12th pulses) - avg(1st to 4th pulses)) / max amps"
1218
- )
1219
- print(
1220
- f"Values: avg({format_array(amp[:, 8:12])}) - avg({format_array(amp[:, :4])}) / {format_array(maxamp)}"
1216
+ "Calculation: (Avg(9th, 10th, 11th, 12th pulses) - Avg(1st to 4th pulses)) / 90th percentile amplitude"
1221
1217
  )
1222
1218
  print(
1223
- f"({format_array(amp[:, 8:12].mean(axis=1))}) - ({format_array(amp[:, :4].mean(axis=1))}) / {format_array(maxamp)} = {recovery:.3f}\n"
1219
+ f"Values: {np.mean(amp[:, 8:12]):.3f} - {np.mean(amp[:, :4]):.3f} / {percentile_90:.3f} = {recovery:.3f}\n"
1224
1220
  )
1225
1221
 
1226
1222
  print("=" * 40 + "\n")
1227
1223
 
1228
- recovery = np.mean((amp[:, 8:12].mean(axis=1) - amp[:, :4].mean(axis=1)) / maxamp)
1229
- induction = np.mean((amp[:, 5:8].mean(axis=1) - amp[:, :1].mean(axis=1)) / maxamp)
1230
- ppr = amp[:, 1:2] / amp[:, 0:1]
1231
- # maxamp = max(amp, key=lambda x: abs(x[0]))
1232
- maxamp = maxamp.max()
1224
+ # Calculate final metrics
1225
+ ppr = (np.mean(amp[:, 1:2]) - np.mean(amp[:, 0:1])) / percentile_90
1226
+ induction = (np.mean(amp[:, 5:8]) - np.mean(amp[:, :1])) / percentile_90
1227
+ recovery = (np.mean(amp[:, 8:12]) - np.mean(amp[:, :4])) / percentile_90
1233
1228
 
1234
1229
  return ppr, induction, recovery
1235
1230
 
bmtool/util/util.py CHANGED
@@ -1,4 +1,5 @@
1
1
  import argparse
2
+ from logging import raiseExceptions
2
3
  import math
3
4
  import os
4
5
  import smtplib
@@ -1081,7 +1082,9 @@ def connection_totals(
1081
1082
  total = edges[(edges[source_id_type] == source_id) & (edges[target_id_type] == target_id)]
1082
1083
  if not include_gap:
1083
1084
  try:
1084
- total = total[~total["is_gap_junction"]]
1085
+ # Handle mixed types and NaN values in is_gap_junction column
1086
+ gap_col = total["is_gap_junction"].fillna(False).astype(bool)
1087
+ total = total[~gap_col]
1085
1088
  except:
1086
1089
  # If there are no gap junctions, just continue
1087
1090
  pass
@@ -1129,7 +1132,8 @@ def percent_connections(
1129
1132
  cons = edges[(edges[source_id_type] == source_id) & (edges[target_id_type] == target_id)]
1130
1133
  if not include_gap:
1131
1134
  try:
1132
- gaps = cons["is_gap_junction"]==True
1135
+ # Handle mixed types and NaN values in is_gap_junction column
1136
+ gaps = cons["is_gap_junction"].fillna(False).astype(bool)
1133
1137
  cons = cons[~gaps]
1134
1138
  except:
1135
1139
  raise Exception("no gap junctions found to drop from connections")
@@ -1200,9 +1204,17 @@ def connection_divergence(
1200
1204
  cons = edges[(edges[source_id_type] == source_id) & (edges[target_id_type] == target_id)]
1201
1205
  if not include_gap:
1202
1206
  try:
1203
- cons = cons[~cons["is_gap_junction"]]
1207
+ # Handle mixed types and NaN values in is_gap_junction column
1208
+ gap_col = cons["is_gap_junction"].fillna(False).astype(bool)
1209
+ cons = cons[~gap_col]
1204
1210
  except:
1205
- raise Exception("no gap junctions found to drop from connections")
1211
+ raise Exception("error")
1212
+
1213
+ if cons.empty:
1214
+ if method == "mean+std":
1215
+ return (0, 0)
1216
+ else:
1217
+ return 0
1206
1218
 
1207
1219
  if convergence:
1208
1220
  if method == "min":
@@ -1213,15 +1225,16 @@ def connection_divergence(
1213
1225
  return round(count, 2)
1214
1226
  elif method == "std":
1215
1227
  std = cons["target_node_id"].value_counts().std()
1216
- return round(std, 2)
1228
+ return round(std, 2) if not np.isnan(std) else 0
1217
1229
  elif method == "mean":
1218
1230
  mean = cons["target_node_id"].value_counts().mean()
1219
- return round(mean, 2)
1231
+ return round(mean, 2) if not np.isnan(mean) else 0
1220
1232
  elif method == "mean+std": # default is mean + std
1221
1233
  mean = cons["target_node_id"].value_counts().mean()
1222
1234
  std = cons["target_node_id"].value_counts().std()
1223
- # std = cons.apply(pd.Series.value_counts).target_node_id.dropna().std() no longer a valid way
1224
- return (round(mean, 2)), (round(std, 2))
1235
+ mean = round(mean, 2) if not np.isnan(mean) else 0
1236
+ std = round(std, 2) if not np.isnan(std) else 0
1237
+ return (mean, std)
1225
1238
  else: # divergence
1226
1239
  if method == "min":
1227
1240
  count = cons["source_node_id"].value_counts().min()
@@ -1231,14 +1244,16 @@ def connection_divergence(
1231
1244
  return round(count, 2)
1232
1245
  elif method == "std":
1233
1246
  std = cons["source_node_id"].value_counts().std()
1234
- return round(std, 2)
1247
+ return round(std, 2) if not np.isnan(std) else 0
1235
1248
  elif method == "mean":
1236
1249
  mean = cons["source_node_id"].value_counts().mean()
1237
- return round(mean, 2)
1250
+ return round(mean, 2) if not np.isnan(mean) else 0
1238
1251
  elif method == "mean+std": # default is mean + std
1239
1252
  mean = cons["source_node_id"].value_counts().mean()
1240
1253
  std = cons["source_node_id"].value_counts().std()
1241
- return (round(mean, 2)), (round(std, 2))
1254
+ mean = round(mean, 2) if not np.isnan(mean) else 0
1255
+ std = round(std, 2) if not np.isnan(std) else 0
1256
+ return (mean, std)
1242
1257
 
1243
1258
  return relation_matrix(
1244
1259
  config,
@@ -1442,7 +1457,9 @@ def connection_probabilities(
1442
1457
  ]
1443
1458
  if not include_gap:
1444
1459
  try:
1445
- relevant_edges = relevant_edges[~relevant_edges["is_gap_junction"]]
1460
+ # Handle mixed types and NaN values in is_gap_junction column
1461
+ gap_col = relevant_edges["is_gap_junction"].fillna(False).astype(bool)
1462
+ relevant_edges = relevant_edges[~gap_col]
1446
1463
  except:
1447
1464
  raise Exception("no gap junctions found to drop from connections")
1448
1465
  connected_distances = eudist(relevant_edges, dist_X, dist_Y, dist_Z).values.tolist()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bmtool
3
- Version: 0.7.5.1
3
+ Version: 0.7.6
4
4
  Summary: BMTool
5
5
  Home-page: https://github.com/cyneuro/bmtool
6
6
  Download-URL:
@@ -6,14 +6,14 @@ bmtool/graphs.py,sha256=gBTzI6c2BBK49dWGcfWh9c56TAooyn-KaiEy0Im1HcI,6717
6
6
  bmtool/manage.py,sha256=lsgRejp02P-x6QpA7SXcyXdalPhRmypoviIA2uAitQs,608
7
7
  bmtool/plot_commands.py,sha256=Dxm_RaT4CtHnfsltTtUopJ4KVbfhxtktEB_b7bFEXII,12716
8
8
  bmtool/singlecell.py,sha256=xqdLM2TjjnL8YyTy-c3WR6mElTv3E4zkZgkfUh4S5X0,47161
9
- bmtool/synapses.py,sha256=k-xyZjElz2CHM2oGXqBnFOCd0NusoA6JASzPXHPCj5c,106068
9
+ bmtool/synapses.py,sha256=GbnPPdXotl7MTeju_QTBwZfFxYFNCq0fJijntzfttds,106071
10
10
  bmtool/analysis/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
11
  bmtool/analysis/entrainment.py,sha256=NQloQtVpEWjDzmkZwMWVcm3hSjErHBZfQl1mrBVoIE8,25321
12
12
  bmtool/analysis/lfp.py,sha256=S2JvxkjcK3-EH93wCrhqNSFY6cX7fOq74pz64ibHKrc,26556
13
13
  bmtool/analysis/netcon_reports.py,sha256=VnPZNKPaQA7oh1q9cIatsqQudm4cOtzNtbGPXoiDCD0,2909
14
14
  bmtool/analysis/spikes.py,sha256=3n-xmyEZ7w6CKEND7-aKOAvdDg0lwDuPI5sMdOuPwa0,24637
15
15
  bmtool/bmplot/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
- bmtool/bmplot/connections.py,sha256=DwnnMp5cUwZC3OqsJqvgTPr4lBzc0sNWYRPmwij0WRk,59337
16
+ bmtool/bmplot/connections.py,sha256=xACgnkLAZrEBpaxa9Ob9MX-B1DO782UAeMvih9DleDk,59400
17
17
  bmtool/bmplot/entrainment.py,sha256=BrBMerqyiG2YWAO_OEFv7OJf3yeFz3l9jUt4NamluLc,32837
18
18
  bmtool/bmplot/lfp.py,sha256=7JLozQQJ19ty0ZNyfhkuJAr_K8_pVP9C0flVJd_YXaY,2027
19
19
  bmtool/bmplot/netcon_reports.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -23,12 +23,12 @@ bmtool/debug/commands.py,sha256=VV00f6q5gzZI503vUPeG40ABLLen0bw_k4-EX-H5WZE,580
23
23
  bmtool/debug/debug.py,sha256=9yUFvA4_Bl-x9s29quIEG3pY-S8hNJF3RKBfRBHCl28,208
24
24
  bmtool/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
25
  bmtool/util/commands.py,sha256=Nn-R-4e9g8ZhSPZvTkr38xeKRPfEMANB9Lugppj82UI,68564
26
- bmtool/util/util.py,sha256=TAWdGd0tDuouS-JiusMs8WwP7kQpWHPr1nu0XG01TBQ,75056
26
+ bmtool/util/util.py,sha256=HbVgPpvDBSkvXv5gAz7ad1V5GKL26q_LyJGt6ehpGQE,75929
27
27
  bmtool/util/neuron/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
28
  bmtool/util/neuron/celltuner.py,sha256=lokRLUM1rsdSYBYrNbLBBo39j14mm8TBNVNRnSlhHCk,94868
29
- bmtool-0.7.5.1.dist-info/licenses/LICENSE,sha256=qrXg2jj6kz5d0EnN11hllcQt2fcWVNumx0xNbV05nyM,1068
30
- bmtool-0.7.5.1.dist-info/METADATA,sha256=H1XxiaHJuU-Bq_HTck5_z1fm08rTmSNxZYBA7hVcmNk,3597
31
- bmtool-0.7.5.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
32
- bmtool-0.7.5.1.dist-info/entry_points.txt,sha256=0-BHZ6nUnh0twWw9SXNTiRmKjDnb1VO2DfG_-oprhAc,45
33
- bmtool-0.7.5.1.dist-info/top_level.txt,sha256=gpd2Sj-L9tWbuJEd5E8C8S8XkNm5yUE76klUYcM-eWM,7
34
- bmtool-0.7.5.1.dist-info/RECORD,,
29
+ bmtool-0.7.6.dist-info/licenses/LICENSE,sha256=qrXg2jj6kz5d0EnN11hllcQt2fcWVNumx0xNbV05nyM,1068
30
+ bmtool-0.7.6.dist-info/METADATA,sha256=iSIT7erBJsvbZ6vJE1LKOlQPF1ne1BiluVL-81Z8l4U,3595
31
+ bmtool-0.7.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
32
+ bmtool-0.7.6.dist-info/entry_points.txt,sha256=0-BHZ6nUnh0twWw9SXNTiRmKjDnb1VO2DfG_-oprhAc,45
33
+ bmtool-0.7.6.dist-info/top_level.txt,sha256=gpd2Sj-L9tWbuJEd5E8C8S8XkNm5yUE76klUYcM-eWM,7
34
+ bmtool-0.7.6.dist-info/RECORD,,