bmtool 0.7.5.1__py3-none-any.whl → 0.7.7__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.
- bmtool/bmplot/connections.py +11 -5
- bmtool/connectors.py +386 -0
- bmtool/singlecell.py +429 -31
- bmtool/synapses.py +369 -45
- bmtool/util/util.py +69 -17
- {bmtool-0.7.5.1.dist-info → bmtool-0.7.7.dist-info}/METADATA +1 -1
- {bmtool-0.7.5.1.dist-info → bmtool-0.7.7.dist-info}/RECORD +11 -11
- {bmtool-0.7.5.1.dist-info → bmtool-0.7.7.dist-info}/WHEEL +0 -0
- {bmtool-0.7.5.1.dist-info → bmtool-0.7.7.dist-info}/entry_points.txt +0 -0
- {bmtool-0.7.5.1.dist-info → bmtool-0.7.7.dist-info}/licenses/LICENSE +0 -0
- {bmtool-0.7.5.1.dist-info → bmtool-0.7.7.dist-info}/top_level.txt +0 -0
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
|
-
|
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
|
-
|
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")
|
@@ -1159,9 +1163,43 @@ def percent_connections(
|
|
1159
1163
|
num_sources = s_list[source_id_type].value_counts().sort_index().loc[source_id]
|
1160
1164
|
num_targets = t_list[target_id_type].value_counts().sort_index().loc[target_id]
|
1161
1165
|
|
1162
|
-
|
1163
|
-
|
1164
|
-
|
1166
|
+
# Check if this is a recurrent network (same source and target population)
|
1167
|
+
# For recurrent networks (e.g., FSI->FSI), we need special handling because:
|
1168
|
+
# - Each pair can have at most 2 directed connections (bidirectional)
|
1169
|
+
# - We want to count unique pairs, not directed connections
|
1170
|
+
# - The denominator should be n*(n-1)/2, not n*n
|
1171
|
+
is_recurrent = source_id == target_id
|
1172
|
+
|
1173
|
+
if is_recurrent:
|
1174
|
+
# For recurrent networks, calculate connectivity based on unique undirected pairs
|
1175
|
+
# This avoids double-counting reciprocal connections and uses correct denominator
|
1176
|
+
pair_counts = {}
|
1177
|
+
for _, row in cons.iterrows():
|
1178
|
+
sid = row['source_node_id']
|
1179
|
+
tid = row['target_node_id']
|
1180
|
+
if sid != tid: # Exclude self-connections
|
1181
|
+
# Use symmetric pair key to count connections per unique pair
|
1182
|
+
pair_key = (min(sid, tid), max(sid, tid))
|
1183
|
+
if pair_key not in pair_counts:
|
1184
|
+
pair_counts[pair_key] = 0
|
1185
|
+
pair_counts[pair_key] += 1
|
1186
|
+
|
1187
|
+
# Count pairs with exactly 1 connection (unidirectional) vs 2 connections (bidirectional)
|
1188
|
+
num_uni = sum(1 for count in pair_counts.values() if count == 1)
|
1189
|
+
num_bi = sum(1 for count in pair_counts.values() if count == 2)
|
1190
|
+
|
1191
|
+
# Total possible unique pairs (excluding self-connections)
|
1192
|
+
total_possible = num_sources * (num_sources - 1) / 2
|
1193
|
+
total = round((num_uni + num_bi) / total_possible * 100, 2)
|
1194
|
+
uni = round(num_uni / total_possible * 100, 2)
|
1195
|
+
bi = round(num_bi / total_possible * 100, 2)
|
1196
|
+
else:
|
1197
|
+
# For non-recurrent networks, use the original calculation
|
1198
|
+
# Each connection is unique (no double-counting issues)
|
1199
|
+
total = round(total_cons / (num_sources * num_targets) * 100, 2)
|
1200
|
+
uni = round(num_uni / (num_sources * num_targets) * 100, 2)
|
1201
|
+
bi = round(num_bi / (num_sources * num_targets) * 100, 2)
|
1202
|
+
|
1165
1203
|
if method == "total":
|
1166
1204
|
return total
|
1167
1205
|
if method == "uni":
|
@@ -1200,9 +1238,17 @@ def connection_divergence(
|
|
1200
1238
|
cons = edges[(edges[source_id_type] == source_id) & (edges[target_id_type] == target_id)]
|
1201
1239
|
if not include_gap:
|
1202
1240
|
try:
|
1203
|
-
|
1241
|
+
# Handle mixed types and NaN values in is_gap_junction column
|
1242
|
+
gap_col = cons["is_gap_junction"].fillna(False).astype(bool)
|
1243
|
+
cons = cons[~gap_col]
|
1204
1244
|
except:
|
1205
|
-
raise Exception("
|
1245
|
+
raise Exception("error")
|
1246
|
+
|
1247
|
+
if cons.empty:
|
1248
|
+
if method == "mean+std":
|
1249
|
+
return (0, 0)
|
1250
|
+
else:
|
1251
|
+
return 0
|
1206
1252
|
|
1207
1253
|
if convergence:
|
1208
1254
|
if method == "min":
|
@@ -1213,15 +1259,16 @@ def connection_divergence(
|
|
1213
1259
|
return round(count, 2)
|
1214
1260
|
elif method == "std":
|
1215
1261
|
std = cons["target_node_id"].value_counts().std()
|
1216
|
-
return round(std, 2)
|
1262
|
+
return round(std, 2) if not np.isnan(std) else 0
|
1217
1263
|
elif method == "mean":
|
1218
1264
|
mean = cons["target_node_id"].value_counts().mean()
|
1219
|
-
return round(mean, 2)
|
1265
|
+
return round(mean, 2) if not np.isnan(mean) else 0
|
1220
1266
|
elif method == "mean+std": # default is mean + std
|
1221
1267
|
mean = cons["target_node_id"].value_counts().mean()
|
1222
1268
|
std = cons["target_node_id"].value_counts().std()
|
1223
|
-
|
1224
|
-
|
1269
|
+
mean = round(mean, 2) if not np.isnan(mean) else 0
|
1270
|
+
std = round(std, 2) if not np.isnan(std) else 0
|
1271
|
+
return (mean, std)
|
1225
1272
|
else: # divergence
|
1226
1273
|
if method == "min":
|
1227
1274
|
count = cons["source_node_id"].value_counts().min()
|
@@ -1231,14 +1278,16 @@ def connection_divergence(
|
|
1231
1278
|
return round(count, 2)
|
1232
1279
|
elif method == "std":
|
1233
1280
|
std = cons["source_node_id"].value_counts().std()
|
1234
|
-
return round(std, 2)
|
1281
|
+
return round(std, 2) if not np.isnan(std) else 0
|
1235
1282
|
elif method == "mean":
|
1236
1283
|
mean = cons["source_node_id"].value_counts().mean()
|
1237
|
-
return round(mean, 2)
|
1284
|
+
return round(mean, 2) if not np.isnan(mean) else 0
|
1238
1285
|
elif method == "mean+std": # default is mean + std
|
1239
1286
|
mean = cons["source_node_id"].value_counts().mean()
|
1240
1287
|
std = cons["source_node_id"].value_counts().std()
|
1241
|
-
|
1288
|
+
mean = round(mean, 2) if not np.isnan(mean) else 0
|
1289
|
+
std = round(std, 2) if not np.isnan(std) else 0
|
1290
|
+
return (mean, std)
|
1242
1291
|
|
1243
1292
|
return relation_matrix(
|
1244
1293
|
config,
|
@@ -1294,9 +1343,10 @@ def gap_junction_connections(
|
|
1294
1343
|
s_list = kwargs["source_nodes"]
|
1295
1344
|
|
1296
1345
|
cons = edges[(edges[source_id_type] == source_id) & (edges[target_id_type] == target_id)]
|
1297
|
-
#
|
1346
|
+
# print(cons)
|
1347
|
+
|
1298
1348
|
try:
|
1299
|
-
cons = cons[cons["is_gap_junction"]]
|
1349
|
+
cons = cons[cons["is_gap_junction"]==True]
|
1300
1350
|
except:
|
1301
1351
|
raise Exception("no gap junctions found to drop from connections")
|
1302
1352
|
|
@@ -1442,7 +1492,9 @@ def connection_probabilities(
|
|
1442
1492
|
]
|
1443
1493
|
if not include_gap:
|
1444
1494
|
try:
|
1445
|
-
|
1495
|
+
# Handle mixed types and NaN values in is_gap_junction column
|
1496
|
+
gap_col = relevant_edges["is_gap_junction"].fillna(False).astype(bool)
|
1497
|
+
relevant_edges = relevant_edges[~gap_col]
|
1446
1498
|
except:
|
1447
1499
|
raise Exception("no gap junctions found to drop from connections")
|
1448
1500
|
connected_distances = eudist(relevant_edges, dist_X, dist_Y, dist_Z).values.tolist()
|
@@ -1,19 +1,19 @@
|
|
1
1
|
bmtool/SLURM.py,sha256=UBfITY1MtYo95nyKglgGSqAC9Ds8PBvlHczsiNMFxvc,20573
|
2
2
|
bmtool/__init__.py,sha256=r_8fXc-2uj1DndCdhB4jME51r1pn6ESTD5zRc355BrU,134
|
3
3
|
bmtool/__main__.py,sha256=uCEqPwRxIuNRUASKhsvh4S8Nkp4dqnvfXTMUv-wWWRU,665
|
4
|
-
bmtool/connectors.py,sha256=
|
4
|
+
bmtool/connectors.py,sha256=tkCh9oVsIgaV5zzBzTFTG2Y6YVAoIHv2Pm-qxZAbca8,93124
|
5
5
|
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
|
-
bmtool/singlecell.py,sha256=
|
9
|
-
bmtool/synapses.py,sha256=
|
8
|
+
bmtool/singlecell.py,sha256=qcciWdn8RjJCp7z8G2dCdPTLS9Brho3lPFSIsYMw8Ls,65348
|
9
|
+
bmtool/synapses.py,sha256=2M0dUBXfdYrJA3FWLbqsZGqAkO0sS2gQ-zq6GHYaVE4,121393
|
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=
|
16
|
+
bmtool/bmplot/connections.py,sha256=xn9QaNN7fTTVNaalS8QHIp2TVo7nXgiT-nO4nKXOo6w,59612
|
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=
|
26
|
+
bmtool/util/util.py,sha256=oXrY-Cc4wxPvgJVg2TqaAPua_gAl1Kj1nqrLgsqsXS8,77815
|
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.
|
30
|
-
bmtool-0.7.
|
31
|
-
bmtool-0.7.
|
32
|
-
bmtool-0.7.
|
33
|
-
bmtool-0.7.
|
34
|
-
bmtool-0.7.
|
29
|
+
bmtool-0.7.7.dist-info/licenses/LICENSE,sha256=qrXg2jj6kz5d0EnN11hllcQt2fcWVNumx0xNbV05nyM,1068
|
30
|
+
bmtool-0.7.7.dist-info/METADATA,sha256=uHViQaXG-O6O_GqENKn1vOkXp6g_yN94M9jSRilSnJU,3595
|
31
|
+
bmtool-0.7.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
32
|
+
bmtool-0.7.7.dist-info/entry_points.txt,sha256=0-BHZ6nUnh0twWw9SXNTiRmKjDnb1VO2DfG_-oprhAc,45
|
33
|
+
bmtool-0.7.7.dist-info/top_level.txt,sha256=gpd2Sj-L9tWbuJEd5E8C8S8XkNm5yUE76klUYcM-eWM,7
|
34
|
+
bmtool-0.7.7.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|