Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 134 additions & 1 deletion bmtk/simulator/bionet/bionetwork.py
Original file line number Diff line number Diff line change
Expand Up @@ -387,4 +387,137 @@ def add_spike_trains(self, spike_trains, node_set, spikes_generator=None, sim=No
elif edge_pop.mixed_connections:
raise NotImplementedError()

self.io.barrier()
self.io.barrier()

INTFIRE_ATTRS = ['tau', 'refrac', 'm', 'taum', 'taus', 'ib', 'i', 'I', 'taue', 'taui1', 'taui2', 'i1', 'i2']

def inspect_cells(self, format='json', output_path=None, filter=None):
import pandas as pd
import json
from pathlib import Path
from pprint import pprint

cell_mechs = {
'population': [],
'node_id': [],
'model_type': [],
'node_type_id': [],
'sec_name': [],
'attr_name': [],
'mech_name': [],
'attr_val': [],
'type': []
}

sect_counts = {
'population': [],
'node_id': [],
'nsections': [],
'nsegments': []
}


filtered_gids = set()
filter = filter or 'all'
for a in self.get_node_set(filter).fetch_nodes():
filtered_gids.add((a.node_id, a.population_name))

for _, cell in self.get_local_cells().items():
if (cell.node_id, cell.population_name) not in filtered_gids:
continue

if cell['model_type'] == 'biophysical':
sect_counts['population'].append(cell.population_name)
sect_counts['node_id'].append(cell.node_id)
sect_counts['nsections'].append(sum(1 for _ in cell.hobj.all))
sect_counts['nsegments'].append(sum(sec.nseg for sec in cell.hobj.all))

for sec in cell.hobj.all:
sec_name = sec.name().split('.')[-1].split('[')[0]
if hasattr(sec, 'Ra'):
cell_mechs['population'].append(cell.population_name)
cell_mechs['node_id'].append(cell.node_id)
cell_mechs['node_type_id'].append(cell['node_type_id'])
cell_mechs['model_type'].append(cell['model_type'])
cell_mechs['sec_name'].append(sec_name)
cell_mechs['mech_name'].append(None)
cell_mechs['attr_name'].append('Ra')
cell_mechs['attr_val'].append(sec.Ra)
cell_mechs['type'].append(None)

for mech_name, mech_props in sec.psection()['density_mechs'].items():
for attr_name, attr_val in mech_props.items():
cell_mechs['population'].append(cell.population_name)
cell_mechs['node_id'].append(cell.node_id)
cell_mechs['node_type_id'].append(cell['node_type_id'])
cell_mechs['model_type'].append(cell['model_type'])
cell_mechs['sec_name'].append(sec_name)
cell_mechs['mech_name'].append(mech_name)
cell_mechs['attr_name'].append(attr_name)
cell_mechs['attr_val'].append(np.mean(attr_val))
cell_mechs['type'].append('mechanism')

for ion_name, ion_props in sec.psection()['ions'].items():
for attr_name, attr_val in ion_props.items():
cell_mechs['population'].append(cell.population_name)
cell_mechs['node_id'].append(cell.node_id)
cell_mechs['node_type_id'].append(cell['node_type_id'])
cell_mechs['model_type'].append(cell['model_type'])
cell_mechs['sec_name'].append(sec_name)
cell_mechs['mech_name'].append(ion_name)
cell_mechs['attr_name'].append(attr_name)
cell_mechs['attr_val'].append(np.mean(attr_val))
cell_mechs['type'].append('ion')

elif cell['model_type'] in ['point_neuron', 'point', 'point_process']:
process_name = sec.name().split('.')[-1].split('[')[0]
for attr_name in dir(cell.hobj):
if attr_name.startswith('__') or attr_name not in self.INTFIRE_ATTRS:
continue

cell_mechs['population'].append(cell.population_name)
cell_mechs['node_id'].append(cell.node_id)
cell_mechs['node_type_id'].append(cell['node_type_id'])
cell_mechs['model_type'].append(cell['model_type'])
cell_mechs['sec_name'].append('NA')
cell_mechs['mech_name'].append(process_name)
cell_mechs['attr_name'].append(attr_name)
cell_mechs['attr_val'].append(getattr(cell.hobj, attr_name))
cell_mechs['type'].append('ARTIFICIAL_CELL')

agg_mech = pd.DataFrame(cell_mechs).groupby(['population', 'node_id', 'node_type_id', 'model_type', 'sec_name', 'mech_name', 'attr_name', 'type']).agg('mean')
mechs_df = agg_mech.reset_index()
mechs_df['attr_name'] = mechs_df.apply(lambda r: f'{r["attr_name"]}_{r["mech_name"]}' if r['type'] == 'mechanism' else r['attr_name'], axis=1)

sect_lu = pd.DataFrame(sect_counts).set_index(['population', 'node_id'])

if format == 'csv':
if output_path:
Path(output_path).parent.mkdir(parents=True, exist_ok=True)
mechs_df.to_csv(output_path, index=False)
else:
csv_str = mechs_df.to_csv(index=False)
print(csv_str)

else:
mechs_dict = {}
for pop, pop_df in mechs_df.groupby('population'):
mechs_dict[pop] = {}
for node_id, node_df in pop_df.groupby('node_id'):
mechs_dict[pop][node_id] = {
'node_type_id': int(node_df['node_type_id'].iloc[0]),
'model_type': node_df['model_type'].iloc[0],
'nsections': int(sect_lu.loc[(pop, node_id)]['nsections']),
'nsegments': int(sect_lu.loc[(pop, node_id)]['nsegments'])
}
for sec, sec_df in node_df.groupby('sec_name'):
mechs_dict[pop][node_id][sec] = {}
for _, r in sec_df.iterrows():
mechs_dict[pop][node_id][sec][r['attr_name']] = {'default_value': float(r['attr_val']), 'mechanism': r['mech_name'], 'type': r['type']}

if output_path:
Path(output_path).parent.mkdir(parents=True, exist_ok=True)
with open(output_path, 'w') as f:
json.dump(mechs_dict, f, indent=2)
else:
pprint(mechs_dict)
1 change: 1 addition & 0 deletions bmtk/simulator/bionet/cell.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class Cell(object):
def __init__(self, node, population_name, network=None):
self._node = node
self._network = network
self.population_name = population_name

self._gid = network.gid_pool.get_gid(name=population_name, node_id=node.node_id)
self._node_id = node.node_id
Expand Down
102 changes: 102 additions & 0 deletions bmtk/simulator/pointnet/pointnetwork.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
import os
import json
import functools
import pandas as pd
import nest
from pathlib import Path

from six import string_types
import numpy as np
Expand Down Expand Up @@ -254,3 +256,103 @@ def _nest_connect(self, nest_srcs, nest_trgs, conn_spec='one_to_one', syn_spec=N
# Record exception to log file.
self.io.log_error(str(e))
raise

skip_attrs = [
'archiver_length',
'element_type',
'frozen',
'global_id',
'local',
'model',
'model_id',
'node_uses_wfr',
'post_trace',
'recordables',
'refractory_input',
'synaptic_elements',
'thread',
'thread_local_id'
]

def inspect(self, format='json', output_path=None, filter=None):
from pprint import pprint

filter = filter or {'model_type': 'point_neuron'}
node_set = self.get_node_set(filter)
# print(self._node_sets)
# exit()
# for n in list(node_set.fetch_nodes()):
# print(n.node_id, n.population_name, n.node_type_id)
# print(node_set.population_names())
# exit()
nodes = list(node_set.fetch_nodes())
nest_ids = list(node_set.gids())
# populations = node_set.population_names()
# populations = populations*len(node_ids) if len(populations) < len(node_ids) else populations

attrs_table = {
'population': [],
'node_id': [],
'nest_id': [],
# 'model_type': [],
'model_template': [],
'node_type_id': [],
'attr_name': [],
'attr_val': [],
'type': []
}

nest_attrs = nest.GetStatus(nest.NodeCollection(nest_ids))
for nest_id, cell_attr, node in zip(nest_ids, nest_attrs, nodes):
model_template = cell_attr['model']
for key, val in cell_attr.items():
if key in self.skip_attrs:
continue
else:
attrs_table['population'].append(node.population_name)
attrs_table['node_id'].append(node.node_id)
attrs_table['node_type_id'].append(node.node_type_id)
attrs_table['nest_id'].append(nest_id)
attrs_table['model_template'].append(model_template)
attrs_table['attr_name'].append(key)
attrs_table['attr_val'].append(val)
if key in cell_attr.get('recordables', {}):
attrs_table['type'].append('recordable')
else:
attrs_table['type'].append('attribute')

attrs_table_df = pd.DataFrame(attrs_table)
attrs_table_df['model_type'] = 'point_neuron'

if format == 'csv':
if output_path:
Path(output_path).parent.mkdir(parents=True, exist_ok=True)
attrs_table_df.to_csv(output_path, index=False)
else:
csv_str = attrs_table_df.to_csv(index=False)
print(csv_str)
else:
attrs_dict = {}
for pop, pop_df in attrs_table_df.groupby('population'):
attrs_dict[pop] = {}
for node_id, node_df in pop_df.groupby('node_id'):
attrs_dict[pop][node_id] = {
'model_type': node_df['model_type'].iloc[0],
'nest_id': int(node_df['nest_id'].iloc[0]),
'node_type_id': int(node_df['node_type_id'].iloc[0]),
'model_template': node_df['model_template'].iloc[0],
}
attrs_dict[pop][node_id]['attributes'] = []
for _, row in node_df.iterrows():
attrs_dict[pop][node_id]['attributes'].append({
'name': row['attr_name'],
'value': row['attr_val'],
'type': row['type']
})

if output_path:
Path(output_path).parent.mkdir(parents=True, exist_ok=True)
with open(output_path, 'w') as f:
json.dump(attrs_dict, f, indent=2)
else:
pprint(attrs_dict)
Empty file.
78 changes: 78 additions & 0 deletions bmtk/utils/inspector/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import logging
import re
from argparse import ArgumentParser

from bmtk.simulator.core.simulation_config import SimulationConfig


def inspect_bionet(config_path, format='json', output_path=None, filter=None):
from bmtk.simulator import bionet

conf = bionet.Config.from_json(config_path)
conf.output['log_to_console'] = False
conf.build_env()

network = bionet.BioNetwork.from_config(conf)
network.build_nodes()
network.inspect_cells(
format=format,
output_path=output_path,
filter=filter
)

bionet.nrn.quit_execution()


def inspect_pointnet(config_path, format='json', output_path=None, filter=None):
from bmtk.simulator import pointnet

conf = pointnet.Config.from_json(config_path)
conf.output['log_to_console'] = False
conf.build_env()

network = pointnet.PointNetwork.from_config(conf)
pointnet.PointSimulator.from_config(conf, network)
network.inspect(
format=format,
output_path=output_path,
filter=filter
)


if __name__ == '__main__':
parser = ArgumentParser()
parser.add_argument('--to-json', action='store_true')
parser.add_argument('--to-csv', action='store_true')
parser.add_argument('--output-path', type=str)
parser.add_argument('-p', '--population', type=str, required=False)
parser.add_argument('--node-ids', type=str, required=False)
parser.add_argument('config', type=str)
args = parser.parse_args()

config_path = args.config
config_dict = SimulationConfig.load(config_path)
target_sim = config_dict.target_simulator.upper()

output_path = args.output_path
format = 'json'
if args.to_json and args.to_csv:
raise ValueError('Both --to-csv and --to-json specified. Please specify a single output format!')
elif args.to_csv:
format = 'csv'

filter_dict = {}
if args.population:
filter_dict['population'] = re.split(r'[,;\s]+', args.population)

if args.node_ids:
print(args.node_ids)
node_ids = re.split(r'[,;\s]+', args.node_ids)
node_ids = list(map(int, node_ids))
filter_dict['node_id'] = node_ids

if target_sim in ['BIONET', 'NEURON', 'NRN']:
inspect_bionet(config_path=config_path, format=format, output_path=output_path, filter=filter_dict)
elif target_sim in ['POINTNET', 'NEST']:
inspect_pointnet(config_path=config_path, format=format, output_path=output_path, filter=filter_dict)
elif target_sim in ['FILTERNET', 'LGN']:
raise NotImplementedError
Loading