bmtool 0.5.9.6__py3-none-any.whl → 0.5.9.8__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.py +117 -101
- bmtool/connectors.py +2 -2
- bmtool/synapses.py +1 -1
- bmtool/util/util.py +6 -12
- {bmtool-0.5.9.6.dist-info → bmtool-0.5.9.8.dist-info}/METADATA +36 -371
- {bmtool-0.5.9.6.dist-info → bmtool-0.5.9.8.dist-info}/RECORD +10 -10
- {bmtool-0.5.9.6.dist-info → bmtool-0.5.9.8.dist-info}/WHEEL +1 -1
- {bmtool-0.5.9.6.dist-info → bmtool-0.5.9.8.dist-info}/LICENSE +0 -0
- {bmtool-0.5.9.6.dist-info → bmtool-0.5.9.8.dist-info}/entry_points.txt +0 -0
- {bmtool-0.5.9.6.dist-info → bmtool-0.5.9.8.dist-info}/top_level.txt +0 -0
bmtool/bmplot.py
CHANGED
@@ -12,6 +12,7 @@ import matplotlib.cm as cmx
|
|
12
12
|
import matplotlib.colors as colors
|
13
13
|
import matplotlib.gridspec as gridspec
|
14
14
|
from mpl_toolkits.mplot3d import Axes3D
|
15
|
+
from matplotlib.axes import Axes
|
15
16
|
from IPython import get_ipython
|
16
17
|
from IPython.display import display, HTML
|
17
18
|
import statistics
|
@@ -19,8 +20,10 @@ import pandas as pd
|
|
19
20
|
import os
|
20
21
|
import sys
|
21
22
|
import re
|
23
|
+
from typing import Optional, Dict
|
24
|
+
from .analysis.spikes import load_spikes_to_df
|
22
25
|
|
23
|
-
from .util.util import CellVarsFile #, missing_units
|
26
|
+
from .util.util import CellVarsFile,load_nodes_from_config #, missing_units
|
24
27
|
from bmtk.analyzer.utils import listify
|
25
28
|
|
26
29
|
use_description = """
|
@@ -271,7 +274,7 @@ def divergence_connection_matrix(config=None,title=None,sources=None, targets=No
|
|
271
274
|
plot_connection_info(syn_info,data,source_labels,target_labels,title, save_file=save_file)
|
272
275
|
return
|
273
276
|
|
274
|
-
def gap_junction_matrix(config=None,title=None,sources=None, targets=None, sids=None,tids=None, no_prepend_pop=False,save_file=None,
|
277
|
+
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'):
|
275
278
|
"""
|
276
279
|
Generates connection plot displaying gap junction data.
|
277
280
|
config: A BMTK simulation config
|
@@ -287,7 +290,7 @@ def gap_junction_matrix(config=None,title=None,sources=None, targets=None, sids=
|
|
287
290
|
raise Exception("config not defined")
|
288
291
|
if not sources or not targets:
|
289
292
|
raise Exception("Sources or targets not defined")
|
290
|
-
if
|
293
|
+
if method !='convergence' and method!='percent':
|
291
294
|
raise Exception("type must be 'convergence' or 'percent'")
|
292
295
|
sources = sources.split(",")
|
293
296
|
targets = targets.split(",")
|
@@ -299,7 +302,7 @@ def gap_junction_matrix(config=None,title=None,sources=None, targets=None, sids=
|
|
299
302
|
tids = tids.split(",")
|
300
303
|
else:
|
301
304
|
tids = []
|
302
|
-
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,
|
305
|
+
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)
|
303
306
|
|
304
307
|
|
305
308
|
def filter_rows(syn_info, data, source_labels, target_labels):
|
@@ -347,7 +350,7 @@ def gap_junction_matrix(config=None,title=None,sources=None, targets=None, sids=
|
|
347
350
|
plot_connection_info(syn_info,data,source_labels,target_labels,title, save_file=save_file)
|
348
351
|
return
|
349
352
|
|
350
|
-
def connection_histogram(config=None,nodes=None,edges=None,sources=[],targets=[],sids=[],tids=[],
|
353
|
+
def connection_histogram(config=None,nodes=None,edges=None,sources=[],targets=[],sids=[],tids=[],no_prepend_pop=True,synaptic_info='0',
|
351
354
|
source_cell = None,target_cell = None,include_gap=True):
|
352
355
|
"""
|
353
356
|
Generates histogram of number of connections individual cells in a population receieve from another population
|
@@ -376,15 +379,15 @@ def connection_histogram(config=None,nodes=None,edges=None,sources=[],targets=[]
|
|
376
379
|
conn_mean = statistics.mean(node_pairs.values)
|
377
380
|
conn_std = statistics.stdev(node_pairs.values)
|
378
381
|
conn_median = statistics.median(node_pairs.values)
|
379
|
-
label = "mean {:.2f} std
|
382
|
+
label = "mean {:.2f} std {:.2f} median {:.2f}".format(conn_mean,conn_std,conn_median)
|
380
383
|
except: # lazy fix for std not calculated with 1 node
|
381
384
|
conn_mean = statistics.mean(node_pairs.values)
|
382
385
|
conn_median = statistics.median(node_pairs.values)
|
383
386
|
label = "mean {:.2f} median {:.2f}".format(conn_mean,conn_median)
|
384
|
-
plt.hist(node_pairs.values,density=
|
387
|
+
plt.hist(node_pairs.values,density=False,bins='auto',stacked=True,label=label)
|
385
388
|
plt.legend()
|
386
389
|
plt.xlabel("# of conns from {} to {}".format(source_cell,target_cell))
|
387
|
-
plt.ylabel("
|
390
|
+
plt.ylabel("# of cells")
|
388
391
|
plt.show()
|
389
392
|
else: # dont care about other cell pairs so pass
|
390
393
|
pass
|
@@ -403,10 +406,10 @@ def connection_histogram(config=None,nodes=None,edges=None,sources=[],targets=[]
|
|
403
406
|
tids = tids.split(",")
|
404
407
|
else:
|
405
408
|
tids = []
|
406
|
-
util.relation_matrix(config,nodes,edges,sources,targets,sids,tids,
|
409
|
+
util.relation_matrix(config,nodes,edges,sources,targets,sids,tids,not no_prepend_pop,relation_func=connection_pair_histogram,synaptic_info=synaptic_info)
|
407
410
|
|
408
|
-
def connection_distance(config: str,
|
409
|
-
source_cell_id: int,target_id_type: str) -> None:
|
411
|
+
def connection_distance(config: str,sources: str,targets: str,
|
412
|
+
source_cell_id: int,target_id_type: str,ignore_z:bool=False) -> None:
|
410
413
|
"""
|
411
414
|
Plots the 3D spatial distribution of target nodes relative to a source node
|
412
415
|
and a histogram of distances from the source node to each target node.
|
@@ -418,11 +421,12 @@ def connection_distance(config: str,source: str,target: str,
|
|
418
421
|
targets: (str) network name(s) to plot
|
419
422
|
source_cell_id : (int) ID of the source cell for calculating distances to target nodes.
|
420
423
|
target_id_type : (str) A string to filter target nodes based off the target_query.
|
424
|
+
ignore_z : (bool) A bool to ignore_z axis or not for when calculating distance default is False
|
421
425
|
|
422
426
|
"""
|
423
427
|
if not config:
|
424
428
|
raise Exception("config not defined")
|
425
|
-
if not
|
429
|
+
if not sources or not targets:
|
426
430
|
raise Exception("Sources or targets not defined")
|
427
431
|
#if source != target:
|
428
432
|
#raise Exception("Code is setup for source and target to be the same! Look at source code for function to add feature")
|
@@ -430,8 +434,8 @@ def connection_distance(config: str,source: str,target: str,
|
|
430
434
|
# Load nodes and edges based on config file
|
431
435
|
nodes, edges = util.load_nodes_edges_from_config(config)
|
432
436
|
|
433
|
-
edge_network =
|
434
|
-
node_network =
|
437
|
+
edge_network = sources + "_to_" + targets
|
438
|
+
node_network = sources
|
435
439
|
|
436
440
|
# Filter edges to obtain connections originating from the source node
|
437
441
|
edge = edges[edge_network]
|
@@ -447,16 +451,25 @@ def connection_distance(config: str,source: str,target: str,
|
|
447
451
|
source_node = node.loc[node.index == source_cell_id]
|
448
452
|
|
449
453
|
# Calculate distances between source node and each target node
|
450
|
-
|
451
|
-
|
454
|
+
if ignore_z:
|
455
|
+
target_positions = target_nodes[['pos_x', 'pos_y']].values
|
456
|
+
source_position = np.array([source_node['pos_x'], source_node['pos_y']]).ravel() # Ensure 1D shape
|
457
|
+
else:
|
458
|
+
target_positions = target_nodes[['pos_x', 'pos_y', 'pos_z']].values
|
459
|
+
source_position = np.array([source_node['pos_x'], source_node['pos_y'], source_node['pos_z']]).ravel() # Ensure 1D shape
|
452
460
|
distances = np.linalg.norm(target_positions - source_position, axis=1)
|
453
461
|
|
454
|
-
# Plot positions of source and target nodes in 3D space
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
462
|
+
# Plot positions of source and target nodes in 3D space or 2D
|
463
|
+
if ignore_z:
|
464
|
+
fig = plt.figure(figsize=(8, 6))
|
465
|
+
ax = fig.add_subplot(111)
|
466
|
+
ax.scatter(target_nodes['pos_x'], target_nodes['pos_y'], c='blue', label="target cells")
|
467
|
+
ax.scatter(source_node['pos_x'], source_node['pos_y'], c='red', label="source cell")
|
468
|
+
else:
|
469
|
+
fig = plt.figure(figsize=(8, 6))
|
470
|
+
ax = fig.add_subplot(111, projection='3d')
|
471
|
+
ax.scatter(target_nodes['pos_x'], target_nodes['pos_y'], target_nodes['pos_z'], c='blue', label="target cells")
|
472
|
+
ax.scatter(source_node['pos_x'], source_node['pos_y'], source_node['pos_z'], c='red', label="source cell")
|
460
473
|
|
461
474
|
# Optional: Add text annotations for distances
|
462
475
|
# for i, distance in enumerate(distances):
|
@@ -471,7 +484,7 @@ def connection_distance(config: str,source: str,target: str,
|
|
471
484
|
plt.hist(distances, bins=20, color='blue', edgecolor='black')
|
472
485
|
plt.xlabel("Distance")
|
473
486
|
plt.ylabel("Count")
|
474
|
-
plt.title("Distance from Source Node to Each Target Node")
|
487
|
+
plt.title(f"Distance from Source Node to Each Target Node")
|
475
488
|
plt.grid(True)
|
476
489
|
plt.show()
|
477
490
|
|
@@ -725,82 +738,92 @@ def connector_percent_matrix(csv_path: str = None, exclude_shell: bool = True,
|
|
725
738
|
plt.tight_layout()
|
726
739
|
plt.show()
|
727
740
|
|
728
|
-
def
|
729
|
-
|
730
|
-
|
731
|
-
"""
|
732
|
-
conf = util.load_config(config)
|
733
|
-
spikes_path = os.path.join(conf["output"]["output_dir"],conf["output"]["spikes_file"])
|
734
|
-
nodes = util.load_nodes_from_config(config)
|
735
|
-
plot_spikes(nodes,spikes_path)
|
736
|
-
return
|
737
|
-
|
738
|
-
def raster(config=None,title=None,population=None,group_key='pop_name'):
|
739
|
-
"""
|
740
|
-
old function probs dep or more to new spike module?
|
741
|
+
def raster(spikes_df: Optional[pd.DataFrame] = None, config: Optional[str] = None, network_name: Optional[str] = None,
|
742
|
+
ax: Optional[Axes] = None,tstart: Optional[float] = None,tstop: Optional[float] = None,
|
743
|
+
color_map: Optional[Dict[str, str]] = None) -> Axes:
|
741
744
|
"""
|
742
|
-
|
745
|
+
Plots a raster plot of neural spikes, with different colors for each population.
|
743
746
|
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
747
|
+
Parameters:
|
748
|
+
----------
|
749
|
+
spikes_df : pd.DataFrame, optional
|
750
|
+
DataFrame containing spike data with columns 'timestamps', 'node_ids', and optional 'pop_name'.
|
751
|
+
config : str, optional
|
752
|
+
Path to the configuration file used to load node data.
|
753
|
+
network_name : str, optional
|
754
|
+
Specific network name to select from the configuration; if not provided, uses the first network.
|
755
|
+
ax : matplotlib.axes.Axes, optional
|
756
|
+
Axes on which to plot the raster; if None, a new figure and axes are created.
|
757
|
+
tstart : float, optional
|
758
|
+
Start time for filtering spikes; only spikes with timestamps greater than `tstart` will be plotted.
|
759
|
+
tstop : float, optional
|
760
|
+
Stop time for filtering spikes; only spikes with timestamps less than `tstop` will be plotted.
|
761
|
+
color_map : dict, optional
|
762
|
+
Dictionary specifying colors for each population. Keys should be population names, and values should be color values.
|
763
|
+
|
764
|
+
Returns:
|
765
|
+
-------
|
766
|
+
matplotlib.axes.Axes
|
767
|
+
Axes with the raster plot.
|
768
|
+
|
769
|
+
Notes:
|
770
|
+
-----
|
771
|
+
- If `config` is provided, the function merges population names from the node data with `spikes_df`.
|
772
|
+
- Each unique population (`pop_name`) in `spikes_df` will be represented by a different color if `color_map` is not specified.
|
773
|
+
- If `color_map` is provided, it should contain colors for all unique `pop_name` values in `spikes_df`.
|
755
774
|
"""
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
775
|
+
# Initialize axes if none provided
|
776
|
+
if ax is None:
|
777
|
+
_, ax = plt.subplots(1, 1)
|
778
|
+
|
779
|
+
# Filter spikes by time range if specified
|
780
|
+
if tstart is not None:
|
781
|
+
spikes_df = spikes_df[spikes_df['timestamps'] > tstart]
|
782
|
+
if tstop is not None:
|
783
|
+
spikes_df = spikes_df[spikes_df['timestamps'] < tstop]
|
784
|
+
|
785
|
+
# Load and merge node population data if config is provided
|
786
|
+
if config:
|
787
|
+
nodes = load_nodes_from_config(config)
|
788
|
+
if network_name:
|
789
|
+
nodes = nodes.get(network_name, {})
|
790
|
+
else:
|
791
|
+
nodes = list(nodes.values())[0] if nodes else {}
|
792
|
+
print("Grabbing first network; specify a network name to ensure correct node population is selected.")
|
761
793
|
|
762
|
-
|
794
|
+
# Find common columns, but exclude the join key from the list
|
795
|
+
common_columns = spikes_df.columns.intersection(nodes.columns).tolist()
|
796
|
+
common_columns = [col for col in common_columns if col != 'node_ids'] # Remove our join key from the common list
|
763
797
|
|
764
|
-
|
798
|
+
# Drop all intersecting columns except the join key column from df2
|
799
|
+
spikes_df = spikes_df.drop(columns=common_columns)
|
800
|
+
# merge nodes and spikes df
|
801
|
+
spikes_df = spikes_df.merge(nodes['pop_name'], left_on='node_ids', right_index=True, how='left')
|
765
802
|
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
"""
|
770
|
-
|
771
|
-
cell_types = ['EC','CA3e','CA3o','CA3b','DGg','DGh','DGb']
|
772
|
-
cell_nums = [30,63,8,8,384,32,32]
|
773
|
-
d = [[] for _ in range(sum(cell_nums))]
|
774
|
-
|
775
|
-
color_picker=['red','orange','yellow','green','blue','purple','black']
|
776
|
-
colors = []
|
777
|
-
offset=0
|
778
|
-
|
779
|
-
for i, row in enumerate(spikes):
|
780
|
-
d[int(row[0])+offset].append(row[1])
|
781
|
-
|
782
|
-
for i, n in enumerate(cell_nums):
|
783
|
-
for _ in range(n):
|
784
|
-
colors.append(color_picker[i])
|
785
|
-
|
786
|
-
fig, axs = plt.subplots(1,1)
|
787
|
-
axs.eventplot(d,colors=colors)
|
788
|
-
axs.set_title('Hipp BMTK')
|
789
|
-
axs.set_ylabel('Cell Number')
|
790
|
-
axs.set_xlabel('Time (ms)')
|
791
|
-
axs.legend(cell_types[::-1])
|
792
|
-
|
793
|
-
leg = axs.get_legend()
|
794
|
-
for i,c in enumerate(color_picker):
|
795
|
-
leg.legendHandles[-i-1].set_color(c)
|
803
|
+
|
804
|
+
# Get unique population names
|
805
|
+
unique_pop_names = spikes_df['pop_name'].unique()
|
796
806
|
|
797
|
-
#
|
798
|
-
if
|
799
|
-
plt.
|
807
|
+
# Generate colors if no color_map is provided
|
808
|
+
if color_map is None:
|
809
|
+
cmap = plt.get_cmap('tab10') # Default colormap
|
810
|
+
color_map = {pop_name: cmap(i / len(unique_pop_names)) for i, pop_name in enumerate(unique_pop_names)}
|
811
|
+
else:
|
812
|
+
# Ensure color_map contains all population names
|
813
|
+
missing_colors = [pop for pop in unique_pop_names if pop not in color_map]
|
814
|
+
if missing_colors:
|
815
|
+
raise ValueError(f"color_map is missing colors for populations: {missing_colors}")
|
800
816
|
|
801
|
-
|
817
|
+
# Plot each population with its specified or generated color
|
818
|
+
for pop_name, group in spikes_df.groupby('pop_name'):
|
819
|
+
ax.scatter(group['timestamps'], group['node_ids'], label=pop_name, color=color_map[pop_name], s=0.5)
|
820
|
+
|
821
|
+
# Label axes
|
822
|
+
ax.set_xlabel("Time")
|
823
|
+
ax.set_ylabel("Node ID")
|
824
|
+
ax.legend(title="Population", loc='upper right', framealpha=0.9, markerfirst=False)
|
802
825
|
|
803
|
-
return
|
826
|
+
return ax
|
804
827
|
|
805
828
|
def plot_3d_positions(config=None, populations_list=None, group_by=None, title=None, save_file=None, subset=None):
|
806
829
|
"""
|
@@ -901,7 +924,7 @@ def plot_3d_positions(config=None, populations_list=None, group_by=None, title=N
|
|
901
924
|
|
902
925
|
return
|
903
926
|
|
904
|
-
def
|
927
|
+
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):
|
905
928
|
from scipy.spatial.transform import Rotation as R
|
906
929
|
if not config:
|
907
930
|
raise Exception("config not defined")
|
@@ -944,23 +967,16 @@ def cell_rotation_3d(config=None, populations_list=None, group_by=None, title=No
|
|
944
967
|
groupings = [(None, nodes_df)]
|
945
968
|
color_map = ['blue']
|
946
969
|
|
947
|
-
cells_plotted = 0
|
948
970
|
for color, (group_name, group_df) in zip(color_map, groupings):
|
971
|
+
if subset is not None:
|
972
|
+
group_df = group_df.iloc[::subset]
|
973
|
+
|
949
974
|
if group and group_name not in group.split(","):
|
950
975
|
continue
|
951
976
|
|
952
977
|
if "pos_x" not in group_df or "rotation_angle_xaxis" not in group_df:
|
953
978
|
continue
|
954
979
|
|
955
|
-
if cells_plotted >= max_cells:
|
956
|
-
continue
|
957
|
-
|
958
|
-
if len(group_df) + cells_plotted > max_cells:
|
959
|
-
total_remaining = max_cells - cells_plotted
|
960
|
-
group_df = group_df[:total_remaining]
|
961
|
-
|
962
|
-
cells_plotted += len(group_df)
|
963
|
-
|
964
980
|
X = group_df["pos_x"]
|
965
981
|
Y = group_df["pos_y"]
|
966
982
|
Z = group_df["pos_z"]
|
bmtool/connectors.py
CHANGED
@@ -1272,8 +1272,8 @@ class GapJunction(UnidirectionConnector):
|
|
1272
1272
|
Similar to `UnidirectionConnector`.
|
1273
1273
|
"""
|
1274
1274
|
|
1275
|
-
def __init__(self, p=1., p_arg=None, verbose=True,report_name=None):
|
1276
|
-
super().__init__(p=p, p_arg=p_arg, verbose=verbose,report_name=None)
|
1275
|
+
def __init__(self, p=1., p_arg=None, verbose=True,save_report=True,report_name=None):
|
1276
|
+
super().__init__(p=p, p_arg=p_arg, verbose=verbose,save_report=save_report,report_name=None)
|
1277
1277
|
|
1278
1278
|
|
1279
1279
|
def setup_nodes(self, source=None, target=None):
|
bmtool/synapses.py
CHANGED
@@ -115,7 +115,7 @@ class SynapseTuner:
|
|
115
115
|
- `set_up_cell()` should be called before setting up the synapse.
|
116
116
|
- Synapse location, type, and properties are specified within `spec_syn_param` and `spec_settings`.
|
117
117
|
"""
|
118
|
-
self.syn = getattr(h, self.conn['
|
118
|
+
self.syn = getattr(h, self.conn['spec_settings']['level_of_detail'])(list(self.cell.all)[self.conn['spec_settings']['sec_id']](self.conn['spec_settings']['sec_x']))
|
119
119
|
for key, value in self.conn['spec_syn_param'].items():
|
120
120
|
if isinstance(value, (int, float)): # Only create sliders for numeric values
|
121
121
|
if hasattr(self.syn, key):
|
bmtool/util/util.py
CHANGED
@@ -736,8 +736,7 @@ def connection_divergence(config=None,nodes=None,edges=None,sources=[],targets=[
|
|
736
736
|
|
737
737
|
return relation_matrix(config,nodes,edges,sources,targets,sids,tids,prepend_pop,relation_func=total_connection_relationship)
|
738
738
|
|
739
|
-
def gap_junction_connections(config=None,nodes=None,edges=None,sources=[],targets=[],sids=[],tids=[],prepend_pop=True,
|
740
|
-
import pandas as pd
|
739
|
+
def gap_junction_connections(config=None,nodes=None,edges=None,sources=[],targets=[],sids=[],tids=[],prepend_pop=True,method='convergence'):
|
741
740
|
|
742
741
|
|
743
742
|
def total_connection_relationship(**kwargs): #reduced version of original function; only gets mean+std
|
@@ -751,7 +750,7 @@ def gap_junction_connections(config=None,nodes=None,edges=None,sources=[],target
|
|
751
750
|
#print(cons)
|
752
751
|
|
753
752
|
try:
|
754
|
-
cons = cons[cons['is_gap_junction']
|
753
|
+
cons = cons[cons['is_gap_junction'] == True]
|
755
754
|
except:
|
756
755
|
raise Exception("no gap junctions found to drop from connections")
|
757
756
|
mean = cons['target_node_id'].value_counts().mean()
|
@@ -770,7 +769,7 @@ def gap_junction_connections(config=None,nodes=None,edges=None,sources=[],target
|
|
770
769
|
cons = edges[(edges[source_id_type] == source_id) & (edges[target_id_type]==target_id)]
|
771
770
|
#add functionality that shows only the one's with gap_junctions
|
772
771
|
try:
|
773
|
-
cons = cons[cons['is_gap_junction']
|
772
|
+
cons = cons[cons['is_gap_junction'] == True]
|
774
773
|
except:
|
775
774
|
raise Exception("no gap junctions found to drop from connections")
|
776
775
|
|
@@ -780,20 +779,15 @@ def gap_junction_connections(config=None,nodes=None,edges=None,sources=[],target
|
|
780
779
|
num_targets = t_list[target_id_type].value_counts().sort_index().loc[target_id]
|
781
780
|
|
782
781
|
|
783
|
-
total = round(total_cons / (num_sources*num_targets) * 100,2)
|
782
|
+
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
|
784
783
|
return total
|
785
784
|
|
786
|
-
if
|
785
|
+
if method == 'convergence':
|
787
786
|
return relation_matrix(config,nodes,edges,sources,targets,sids,tids,prepend_pop,relation_func=total_connection_relationship)
|
788
|
-
elif
|
787
|
+
elif method == 'percent':
|
789
788
|
return relation_matrix(config,nodes,edges,sources,targets,sids,tids,prepend_pop,relation_func=precent_func)
|
790
789
|
|
791
790
|
|
792
|
-
def gap_junction_percent_connections(config=None,nodes=None,edges=None,sources=[],targets=[],sids=[],tids=[],prepend_pop=True,method=None):
|
793
|
-
import pandas as pd
|
794
|
-
|
795
|
-
|
796
|
-
|
797
791
|
def connection_probabilities(config=None,nodes=None,edges=None,sources=[],
|
798
792
|
targets=[],sids=[],tids=[],prepend_pop=True,dist_X=True,dist_Y=True,dist_Z=True,num_bins=10,include_gap=True):
|
799
793
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: bmtool
|
3
|
-
Version: 0.5.9.
|
3
|
+
Version: 0.5.9.8
|
4
4
|
Summary: BMTool
|
5
5
|
Home-page: https://github.com/cyneuro/bmtool
|
6
6
|
Download-URL:
|
@@ -38,11 +38,12 @@ A collection of modules to make developing [Neuron](https://www.neuron.yale.edu/
|
|
38
38
|
[](https://github.com/cyneuro/bmtool/blob/master/LICENSE)
|
39
39
|
|
40
40
|
## Table of Contents
|
41
|
-
- [Getting Started](#
|
42
|
-
- [CLI](#
|
43
|
-
- [Single Cell](#
|
44
|
-
- [
|
45
|
-
- [
|
41
|
+
- [Getting Started](#getting-started)
|
42
|
+
- [CLI](#cli)
|
43
|
+
- [Single Cell](#single-cell-module)
|
44
|
+
- [Synapses](#synapses-module)
|
45
|
+
- [Connectors](#connectors-module)
|
46
|
+
- [Bmplot](#bmplot-module)
|
46
47
|
- [Graphs](#graphs-module)
|
47
48
|
|
48
49
|
## Getting Started
|
@@ -335,6 +336,12 @@ bmtool util cell --hoc segmented_template.hoc vhsegbuild
|
|
335
336
|
```
|
336
337
|
ex: [https://github.com/tjbanks/two-cell-hco](https://github.com/tjbanks/two-cell-hco)
|
337
338
|
|
339
|
+
### Synapses Module
|
340
|
+
-[SynapticTuner](#synaptictuner)
|
341
|
+
|
342
|
+
#### SynapticTuner - Aids in the tuning of synapses by printing out synaptic properties and giving the user sliders in a Jupyter notebook to tune the synapse. For more info view the example [here](examples/synapses/synaptic_tuner.ipynb)
|
343
|
+
|
344
|
+
|
338
345
|
### Connectors Module
|
339
346
|
- [UnidirectionConnector](#unidirectional-connector---unidirectional-connections-in-bmtk-network-model-with-given-probability-within-a-single-population-or-between-two-populations)
|
340
347
|
- [ReciprocalConnector](#recipical-connector---buiilding-connections-in-bmtk-network-model-with-reciprocal-probability-within-a-single-population-or-between-two-populations)
|
@@ -390,148 +397,53 @@ connector.setup_nodes(target=net.nodes(pop_name = 'PopB'))
|
|
390
397
|
net.add_edges(**connector.edge_params())
|
391
398
|
```
|
392
399
|
|
393
|
-
## Bmplot Module
|
394
|
-
|
395
|
-
- [
|
396
|
-
- [
|
397
|
-
- [
|
398
|
-
- [
|
399
|
-
- [
|
400
|
-
- [
|
401
|
-
- [
|
402
|
-
- [
|
403
|
-
- [
|
404
|
-
|
405
|
-
### Total connection plot
|
406
|
-
#### Generates a table of total number of connections each neuron population recieves
|
407
|
-
|
408
|
-
|
409
|
-
```python
|
410
|
-
from bmtool import bmplot
|
411
|
-
bmplot.total_connection_matrix(config='config.json',sources='LA',targets='LA',tids='pop_name',sids='pop_name',no_prepend_pop=True,include_gap=False)
|
412
|
-
```
|
400
|
+
## Bmplot Module
|
401
|
+
### for a demo please see the notebook [here](examples/bmplot/bmplot.ipynb)
|
402
|
+
- [total_connection_matrix](#total_connection_matrix)
|
403
|
+
- [percent_connection_matrix](#percent_connection_matrix)
|
404
|
+
- [convergence_connection_matrix](#convergence_connection_matrix)
|
405
|
+
- [divergence_connection_matrix](#divergence_connection_matrix)
|
406
|
+
- [gap_junction_matrix](#gap_junction_matrix)
|
407
|
+
- [connection_distance](#connection_distance)
|
408
|
+
- [connection_histogram](#connection_histogram)
|
409
|
+
- [plot_3d_positions](#plot_3d_positions)
|
410
|
+
- [plot_3d_cell_rotation](#plot_3d_cell_rotation)
|
413
411
|
|
412
|
+
### total_connection_matrix
|
413
|
+
#### Generates a table of total number of connections each neuron population recieves
|
414
414
|
|
415
415
|
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
### Percent connection plot
|
416
|
+
### percent_connection_matrix
|
421
417
|
#### Generates a table of the percent connectivity of neuron populations.Method can change if you want the table to be total percent connectivity, only unidirectional connectivity or only bi directional connectvity
|
422
418
|
|
423
419
|
|
424
|
-
|
425
|
-
bmplot.percent_connection_matrix(config='config.json',sources='LA',targets='LA',tids='pop_name',sids='pop_name',no_prepend_pop=True,method='total',include_gap=False)
|
426
|
-
```
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-

|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
### Convergence plot
|
420
|
+
### convergence_connection_matrix
|
435
421
|
#### Generates a table of the mean convergence of neuron populations. Method can be changed to show max, min, mean, or std for convergence a cell recieves
|
436
422
|
|
437
|
-
|
438
|
-
```python
|
439
|
-
bmplot.convergence_connection_matrix(config='config.json',sources='LA',targets='LA',tids='pop_name',sids='pop_name',no_prepend_pop=True,include_gap=False,method='mean+std')
|
440
|
-
```
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-

|
445
423
|
|
446
|
-
|
447
|
-
|
448
|
-
### Divergence plot
|
424
|
+
### divergence_connection_matrix
|
449
425
|
#### Generates a table of the mean divergence of neuron populations. Method can be changed to show max, min, mean or std divergence a cell recieves.
|
450
426
|
|
451
|
-
|
452
|
-
```python
|
453
|
-
bmplot.divergence_connection_matrix(config='config.json',sources='LA',targets='LA',tids='pop_name',sids='pop_name',no_prepend_pop=True,include_gap=False,method='mean+std')
|
454
|
-
```
|
455
|
-
|
456
|
-
|
457
427
|
|
458
|
-
|
459
|
-
|
460
|
-
### Gap Junction plot
|
461
|
-
#### While gap junctions can be include in the above plots, you can use this function to only view gap junctions.Type can be either 'convergence' or 'percent' connections to generate different plots
|
462
|
-
|
463
|
-
|
464
|
-
```python
|
465
|
-
bmplot.gap_junction_matrix(config='config.json',sources='LA',targets='LA',sids='pop_name',tids='pop_name',no_prepend_pop=True,type='percent')
|
466
|
-
```
|
428
|
+
### gap_junction_matrix
|
429
|
+
#### While gap junctions can be include in the above plots, you can use this function to only view gap junctions. Method can be either 'convergence' or 'percent' connections to generate different plots
|
467
430
|
|
468
431
|
|
469
|
-
|
470
|
-
|
471
|
-
|
432
|
+
### connection_distance
|
433
|
+
#### Generates a 3d plot with the source and target cells location along with a histogram showing connection distance
|
472
434
|
|
473
|
-
###
|
435
|
+
### connection_histogram
|
474
436
|
#### Generates a histogram of the distribution of connections a population of cells give to individual cells of another population
|
475
437
|
|
476
438
|
|
477
|
-
|
478
|
-
bmplot.connection_histogram(config='config.json',sources='LA',targets='LA',tids='pop_name',sids='pop_name',source_cell='PV',target_cell='PV',include_gap=False)
|
479
|
-
```
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-

|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
### probability of connection plot
|
488
|
-
#### this function needs some work
|
489
|
-
|
490
|
-
|
491
|
-
```python
|
492
|
-
bmplot.probability_connection_matrix(config='config.json',sources='LA',targets='LA',tids='pop_name',sids='pop_name',no_prepend_pop=True,line_plot=True)
|
493
|
-
```
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-

|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-

|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
### 3D position plot
|
439
|
+
### plot_3d_positions
|
508
440
|
#### Generates a plot of cells positions in 3D space
|
509
441
|
|
510
442
|
|
511
|
-
|
512
|
-
bmplot.plot_3d_positions(config='config.json',populations_list='LA',group_by='pop_name',save_file=False)
|
513
|
-
```
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-

|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
### cell rotations
|
443
|
+
### plot_3d_cell_rotation
|
522
444
|
#### Generates a plot of cells location in 3D plot and also the cells rotation
|
523
445
|
|
524
446
|
|
525
|
-
```python
|
526
|
-
bmplot.cell_rotation_3d(config='config2.json',populations_list='all',group_by='pop_name',save_file=False,quiver_length=20,arrow_length_ratio=0.25,max_cells=100)
|
527
|
-
```
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-

|
532
|
-
|
533
|
-
|
534
|
-
|
535
447
|
### Plot Connection Diagram
|
536
448
|
|
537
449
|
|
@@ -546,252 +458,6 @@ bmplot.plot_network_graph(config='config.json',sources='LA',targets='LA',tids='p
|
|
546
458
|
|
547
459
|
|
548
460
|
|
549
|
-
|
550
|
-
|
551
|
-
```python
|
552
|
-
from bmtool import bmplot
|
553
|
-
bmplot.plot_basic_cell_info(config_file='config.json')
|
554
|
-
```
|
555
|
-
|
556
|
-
Network and node info:
|
557
|
-
LA:
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
<table border="1" class="dataframe">
|
562
|
-
<thead>
|
563
|
-
<tr style="text-align: right;">
|
564
|
-
<th></th>
|
565
|
-
<th>node_type</th>
|
566
|
-
<th>pop_name</th>
|
567
|
-
<th>model_type</th>
|
568
|
-
<th>model_template</th>
|
569
|
-
<th>morphology</th>
|
570
|
-
<th>count</th>
|
571
|
-
</tr>
|
572
|
-
</thead>
|
573
|
-
<tbody>
|
574
|
-
<tr>
|
575
|
-
<th>0</th>
|
576
|
-
<td>100</td>
|
577
|
-
<td>PNa</td>
|
578
|
-
<td>biophysical</td>
|
579
|
-
<td>hoc:Cell_Af</td>
|
580
|
-
<td>blank.swc</td>
|
581
|
-
<td>800</td>
|
582
|
-
</tr>
|
583
|
-
<tr>
|
584
|
-
<th>1</th>
|
585
|
-
<td>101</td>
|
586
|
-
<td>PNc</td>
|
587
|
-
<td>biophysical</td>
|
588
|
-
<td>hoc:Cell_Cf</td>
|
589
|
-
<td>blank.swc</td>
|
590
|
-
<td>800</td>
|
591
|
-
</tr>
|
592
|
-
<tr>
|
593
|
-
<th>2</th>
|
594
|
-
<td>102</td>
|
595
|
-
<td>PV</td>
|
596
|
-
<td>biophysical</td>
|
597
|
-
<td>hoc:InterneuronCellf</td>
|
598
|
-
<td>blank.swc</td>
|
599
|
-
<td>240</td>
|
600
|
-
</tr>
|
601
|
-
<tr>
|
602
|
-
<th>3</th>
|
603
|
-
<td>103</td>
|
604
|
-
<td>SOM</td>
|
605
|
-
<td>biophysical</td>
|
606
|
-
<td>hoc:LTS_Cell</td>
|
607
|
-
<td>blank.swc</td>
|
608
|
-
<td>160</td>
|
609
|
-
</tr>
|
610
|
-
</tbody>
|
611
|
-
</table>
|
612
|
-
|
613
|
-
|
614
|
-
thalamus_pyr:
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
<table border="1" class="dataframe">
|
619
|
-
<thead>
|
620
|
-
<tr style="text-align: right;">
|
621
|
-
<th></th>
|
622
|
-
<th>node_type</th>
|
623
|
-
<th>pop_name</th>
|
624
|
-
<th>model_type</th>
|
625
|
-
<th>count</th>
|
626
|
-
</tr>
|
627
|
-
</thead>
|
628
|
-
<tbody>
|
629
|
-
<tr>
|
630
|
-
<th>0</th>
|
631
|
-
<td>100</td>
|
632
|
-
<td>pyr_inp</td>
|
633
|
-
<td>virtual</td>
|
634
|
-
<td>1600</td>
|
635
|
-
</tr>
|
636
|
-
</tbody>
|
637
|
-
</table>
|
638
|
-
|
639
|
-
|
640
|
-
thalamus_pv:
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
<table border="1" class="dataframe">
|
645
|
-
<thead>
|
646
|
-
<tr style="text-align: right;">
|
647
|
-
<th></th>
|
648
|
-
<th>node_type</th>
|
649
|
-
<th>pop_name</th>
|
650
|
-
<th>model_type</th>
|
651
|
-
<th>count</th>
|
652
|
-
</tr>
|
653
|
-
</thead>
|
654
|
-
<tbody>
|
655
|
-
<tr>
|
656
|
-
<th>0</th>
|
657
|
-
<td>100</td>
|
658
|
-
<td>pv_inp</td>
|
659
|
-
<td>virtual</td>
|
660
|
-
<td>240</td>
|
661
|
-
</tr>
|
662
|
-
</tbody>
|
663
|
-
</table>
|
664
|
-
|
665
|
-
|
666
|
-
thalamus_som:
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
<table border="1" class="dataframe">
|
671
|
-
<thead>
|
672
|
-
<tr style="text-align: right;">
|
673
|
-
<th></th>
|
674
|
-
<th>node_type</th>
|
675
|
-
<th>pop_name</th>
|
676
|
-
<th>model_type</th>
|
677
|
-
<th>count</th>
|
678
|
-
</tr>
|
679
|
-
</thead>
|
680
|
-
<tbody>
|
681
|
-
<tr>
|
682
|
-
<th>0</th>
|
683
|
-
<td>100</td>
|
684
|
-
<td>som_inp</td>
|
685
|
-
<td>virtual</td>
|
686
|
-
<td>160</td>
|
687
|
-
</tr>
|
688
|
-
</tbody>
|
689
|
-
</table>
|
690
|
-
|
691
|
-
|
692
|
-
tone:
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
<table border="1" class="dataframe">
|
697
|
-
<thead>
|
698
|
-
<tr style="text-align: right;">
|
699
|
-
<th></th>
|
700
|
-
<th>node_type</th>
|
701
|
-
<th>pop_name</th>
|
702
|
-
<th>model_type</th>
|
703
|
-
<th>count</th>
|
704
|
-
</tr>
|
705
|
-
</thead>
|
706
|
-
<tbody>
|
707
|
-
<tr>
|
708
|
-
<th>0</th>
|
709
|
-
<td>100</td>
|
710
|
-
<td>tone</td>
|
711
|
-
<td>virtual</td>
|
712
|
-
<td>1840</td>
|
713
|
-
</tr>
|
714
|
-
</tbody>
|
715
|
-
</table>
|
716
|
-
|
717
|
-
|
718
|
-
shock:
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
<table border="1" class="dataframe">
|
723
|
-
<thead>
|
724
|
-
<tr style="text-align: right;">
|
725
|
-
<th></th>
|
726
|
-
<th>node_type</th>
|
727
|
-
<th>pop_name</th>
|
728
|
-
<th>model_type</th>
|
729
|
-
<th>count</th>
|
730
|
-
</tr>
|
731
|
-
</thead>
|
732
|
-
<tbody>
|
733
|
-
<tr>
|
734
|
-
<th>0</th>
|
735
|
-
<td>100</td>
|
736
|
-
<td>shock</td>
|
737
|
-
<td>virtual</td>
|
738
|
-
<td>400</td>
|
739
|
-
</tr>
|
740
|
-
</tbody>
|
741
|
-
</table>
|
742
|
-
|
743
|
-
|
744
|
-
shell:
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
<table border="1" class="dataframe">
|
749
|
-
<thead>
|
750
|
-
<tr style="text-align: right;">
|
751
|
-
<th></th>
|
752
|
-
<th>node_type</th>
|
753
|
-
<th>pop_name</th>
|
754
|
-
<th>model_type</th>
|
755
|
-
<th>count</th>
|
756
|
-
</tr>
|
757
|
-
</thead>
|
758
|
-
<tbody>
|
759
|
-
<tr>
|
760
|
-
<th>0</th>
|
761
|
-
<td>100</td>
|
762
|
-
<td>PNa</td>
|
763
|
-
<td>virtual</td>
|
764
|
-
<td>3975</td>
|
765
|
-
</tr>
|
766
|
-
<tr>
|
767
|
-
<th>1</th>
|
768
|
-
<td>101</td>
|
769
|
-
<td>PNc</td>
|
770
|
-
<td>virtual</td>
|
771
|
-
<td>3975</td>
|
772
|
-
</tr>
|
773
|
-
<tr>
|
774
|
-
<th>2</th>
|
775
|
-
<td>102</td>
|
776
|
-
<td>PV</td>
|
777
|
-
<td>virtual</td>
|
778
|
-
<td>1680</td>
|
779
|
-
</tr>
|
780
|
-
<tr>
|
781
|
-
<th>3</th>
|
782
|
-
<td>103</td>
|
783
|
-
<td>SOM</td>
|
784
|
-
<td>virtual</td>
|
785
|
-
<td>1120</td>
|
786
|
-
</tr>
|
787
|
-
</tbody>
|
788
|
-
</table>
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
'LA'
|
795
461
|
## Graphs Module
|
796
462
|
- [Generate graph](#generate-graph)
|
797
463
|
- [Plot Graph](#plot-graph)
|
@@ -799,7 +465,6 @@ bmplot.plot_basic_cell_info(config_file='config.json')
|
|
799
465
|
|
800
466
|
### Generate Graph
|
801
467
|
|
802
|
-
|
803
468
|
```python
|
804
469
|
from bmtool import graphs
|
805
470
|
import networkx as nx
|
@@ -1,24 +1,24 @@
|
|
1
1
|
bmtool/SLURM.py,sha256=AX5MKV7dD-XwS8SROnW1IyesZ3jDwMf0txO6mHxTbuw,13694
|
2
2
|
bmtool/__init__.py,sha256=ZStTNkAJHJxG7Pwiy5UgCzC4KlhMS5pUNPtUJZVwL_Y,136
|
3
3
|
bmtool/__main__.py,sha256=TmFkmDxjZ6250nYD4cgGhn-tbJeEm0u-EMz2ajAN9vE,650
|
4
|
-
bmtool/bmplot.py,sha256=
|
5
|
-
bmtool/connectors.py,sha256=
|
4
|
+
bmtool/bmplot.py,sha256=VoX-oXqu6dRb3JEUgGxWiX23JxUy9PeemE7z4f6hVbY,53177
|
5
|
+
bmtool/connectors.py,sha256=QEaBGc6mEoQc-H3ltjvjn5-XWyYgnrhcfNRblVOUE2A,72228
|
6
6
|
bmtool/graphs.py,sha256=K8BiughRUeXFVvAgo8UzrwpSClIVg7UfmIcvtEsEsk0,6020
|
7
7
|
bmtool/manage.py,sha256=_lCU0qBQZ4jSxjzAJUd09JEetb--cud7KZgxQFbLGSY,657
|
8
8
|
bmtool/plot_commands.py,sha256=Tqujyf0c0u8olhiHOMwgUSJXIIE1hgjv6otb25G9cA0,12298
|
9
9
|
bmtool/singlecell.py,sha256=Q4poQvG9fw0jlyMmHFzbRPrpcEkPz5MKS8Guuo73Bzs,26849
|
10
|
-
bmtool/synapses.py,sha256=
|
10
|
+
bmtool/synapses.py,sha256=CA4mPeLCnyaqhDYphcKz-1s7C2JVknCRW_NoTfHS9MM,27500
|
11
11
|
bmtool/debug/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
12
12
|
bmtool/debug/commands.py,sha256=AwtcR7BUUheM0NxvU1Nu234zCdpobhJv5noX8x5K2vY,583
|
13
13
|
bmtool/debug/debug.py,sha256=xqnkzLiH3s-tS26Y5lZZL62qR2evJdi46Gud-HzxEN4,207
|
14
14
|
bmtool/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
15
15
|
bmtool/util/commands.py,sha256=zJF-fiLk0b8LyzHDfvewUyS7iumOxVnj33IkJDzux4M,64396
|
16
|
-
bmtool/util/util.py,sha256=
|
16
|
+
bmtool/util/util.py,sha256=00vOAwTVIifCqouBoFoT0lBashl4fCalrk8fhg_Uq4c,56654
|
17
17
|
bmtool/util/neuron/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
18
18
|
bmtool/util/neuron/celltuner.py,sha256=xSRpRN6DhPFz4q5buq_W8UmsD7BbUrkzYBEbKVloYss,87194
|
19
|
-
bmtool-0.5.9.
|
20
|
-
bmtool-0.5.9.
|
21
|
-
bmtool-0.5.9.
|
22
|
-
bmtool-0.5.9.
|
23
|
-
bmtool-0.5.9.
|
24
|
-
bmtool-0.5.9.
|
19
|
+
bmtool-0.5.9.8.dist-info/LICENSE,sha256=qrXg2jj6kz5d0EnN11hllcQt2fcWVNumx0xNbV05nyM,1068
|
20
|
+
bmtool-0.5.9.8.dist-info/METADATA,sha256=rrR39yoM5X0WSk15L0KZV3KoRFqwt5KAmwMXW-apI_c,18823
|
21
|
+
bmtool-0.5.9.8.dist-info/WHEEL,sha256=R06PA3UVYHThwHvxuRWMqaGcr-PuniXahwjmQRFMEkY,91
|
22
|
+
bmtool-0.5.9.8.dist-info/entry_points.txt,sha256=0-BHZ6nUnh0twWw9SXNTiRmKjDnb1VO2DfG_-oprhAc,45
|
23
|
+
bmtool-0.5.9.8.dist-info/top_level.txt,sha256=gpd2Sj-L9tWbuJEd5E8C8S8XkNm5yUE76klUYcM-eWM,7
|
24
|
+
bmtool-0.5.9.8.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|