def _get_report(report_path=None, config=None, report_name=None): if report_path is not None: return report_path, CompartmentReport.load(report=report_path) elif config is not None: selected_reports = [] sim_reports = simulation_reports.from_config(config) for report in sim_reports: if report.module in ['membrane_report', 'multimeter_report']: rname = report.report_name rfile = report.params['file_name'] # TODO: Full path should be determined by config/simulation_reports module rpath = rfile if os.path.isabs(rfile) else os.path.join(report.params['tmp_dir'], rfile) if report_name is not None and report_name == rname: selected_reports.append((rname, CompartmentReport.load(rpath))) elif report_name is None: selected_reports.append((rname, CompartmentReport.load(rpath))) if len(selected_reports) == 0: msg = 'Could not find a report ' msg += '' if report_name is None else 'with report_name "{}"'.format(report_name) msg += ' from configuration file. . Use "report_path" parameter instead.' raise ValueError(msg) elif len(selected_reports) > 1: avail_reports = ', '.join(s[0] for s in selected_reports) raise ValueError('Configuration file contained multiple "membrane_reports", use "report_name" or' '"report_path" to pick which one to plot. Option values: {}'.format(avail_reports)) else: return selected_reports[0] else: raise AttributeError('Could not find a compartment report SONATA file. Please user "config_file" or ' '"report_path" options.')
def _get_ecp_path(ecp_path=None, config=None, report_name=None): if ecp_path is not None: return ecp_path elif config is not None: possible_paths = [] sim_reports = simulation_reports.from_config(config) for report in sim_reports: if report.module in ['extracellular', 'ecp']: rname = report.report_name rfile = report.params['file_name'] rpath = rfile if os.path.isabs(rfile) else os.path.join( report.params['tmp_dir'], rfile) if report_name is not None and report_name == rname: possible_paths.append((rname, rpath)) elif report_name is None: possible_paths.append((rname, rpath)) if len(possible_paths) == 0: msg = 'Could not find a ECP report ' msg += '' if report_name is None else 'with report_name "{}"'.format( report_name) msg += ' from configuration file. . Use "report_path" parameter instead.' raise ValueError(msg) elif len(possible_paths) > 1: avail_reports = ', '.join(s[0] for s in possible_paths) raise ValueError( 'Configuration file contained multiple "extracelluar", use "report_name" or' '"report_path" to pick which one to plot. Option values: {}'. format(avail_reports)) else: return possible_paths[0] else: raise AttributeError( 'Could not find a compartment report SONATA file. Please user "config_file" or ' '"report_path" options.')
def from_config(cls, config, network, set_recordings=True): # TODO: convert from json to sonata config if necessary sim = cls(network=network, dt=config.dt, tstop=config.tstop, v_init=config.v_init, celsius=config.celsius, cao0=config.cao0, optocell=config.optocell, nsteps_block=config.block_step) network.io.log_info('Building cells.') network.build_nodes() network.io.log_info('Building recurrent connections') network.build_recurrent_edges() # TODO: Need to create a gid selector for sim_input in inputs.from_config(config): node_set = network.get_node_set(sim_input.node_set) if sim_input.input_type == 'spikes': spikes = spike_trains.SpikesInput.load( name=sim_input.name, module=sim_input.module, input_type=sim_input.input_type, params=sim_input.params) io.log_info('Build virtual cell stimulations for {}'.format( sim_input.name)) network.add_spike_trains(spikes, node_set) elif sim_input.module == 'IClamp': # TODO: Parse from csv file amplitude = sim_input.params['amp'] delay = sim_input.params['delay'] duration = sim_input.params['duration'] gids = sim_input.params['node_set'] sim.attach_current_clamp(amplitude, delay, duration, node_set) elif sim_input.module == 'xstim': sim.add_mod(mods.XStimMod(**sim_input.params)) else: io.log_exception('Can not parse input format {}'.format( sim_input.name)) if config.calc_ecp: for gid, cell in network.cell_type_maps('biophysical').items(): cell.setup_ecp() sim.h.cvode.use_fast_imem(1) # Parse the "reports" section of the config and load an associated output module for each report sim_reports = reports.from_config(config) for report in sim_reports: if isinstance(report, reports.SpikesReport): mod = mods.SpikesMod(**report.params) elif isinstance(report, reports.SectionReport): mod = mods.SectionReport(**report.params) elif isinstance(report, reports.MembraneReport): if report.params['sections'] == 'soma': mod = mods.SomaReport(**report.params) else: mod = mods.MembraneReport(**report.params) elif isinstance(report, reports.ECPReport): assert config.calc_ecp mod = mods.EcpMod(**report.params) # Set up the ability for ecp on all relevant cells # TODO: According to spec we need to allow a different subset other than only biophysical cells # for gid, cell in network.cell_type_maps('biophysical').items(): # cell.setup_ecp() elif report.module == 'save_synapses': mod = mods.SaveSynapses(**report.params) else: # TODO: Allow users to register customized modules using pymodules io.log_warning('Unrecognized module {}, skipping.'.format( report.module)) continue sim.add_mod(mod) return sim
def from_config(cls, config, network, set_recordings=True): # TODO: convert from json to sonata config if necessary #The network must be built before initializing the simulator because #gap junctions must be set up before the simulation is initialized. network.io.log_info('Building cells.') network.build_nodes() network.io.log_info('Building recurrent connections') network.build_recurrent_edges() sim = cls(network=network, dt=config.dt, tstop=config.tstop, v_init=config.v_init, celsius=config.celsius, nsteps_block=config.block_step) # TODO: Need to create a gid selector for sim_input in inputs.from_config(config): try: network.get_node_set(sim_input.node_set) except: print( "Parameter node_set must be given in inputs module of simulation_config file. If unsure of what node_set should be, set it to 'all'." ) node_set = network.get_node_set(sim_input.node_set) if sim_input.input_type == 'spikes': io.log_info('Building virtual cell stimulations for {}'.format( sim_input.name)) path = sim_input.params['input_file'] spikes = SpikeTrains.load(path=path, file_type=sim_input.module, **sim_input.params) network.add_spike_trains(spikes, node_set) elif sim_input.module == "FileIClamp": sim.attach_file_current_clamp(sim_input.params["input_file"]) elif sim_input.module == 'IClamp': # TODO: Parse from csv file try: len(sim_input.params['amp']) except: sim_input.params['amp'] = [float(sim_input.params['amp'])] if len(sim_input.params['amp']) > 1: sim_input.params['amp'] = [ float(i) for i in sim_input.params['amp'] ] try: len(sim_input.params['delay']) except: sim_input.params['delay'] = [ float(sim_input.params['delay']) ] if len(sim_input.params['delay']) > 1: sim_input.params['delay'] = [ float(i) for i in sim_input.params['delay'] ] try: len(sim_input.params['duration']) except: sim_input.params['duration'] = [ float(sim_input.params['duration']) ] if len(sim_input.params['duration']) > 1: sim_input.params['duration'] = [ float(i) for i in sim_input.params['duration'] ] amplitude = sim_input.params['amp'] delay = sim_input.params['delay'] duration = sim_input.params['duration'] try: sim_input.params['gids'] except: sim_input.params['gids'] = None if sim_input.params['gids'] is not None: gids = sim_input.params['gids'] else: gids = list(node_set.gids()) sim.attach_current_clamp(amplitude, delay, duration, gids) elif sim_input.module == "SEClamp": try: len(sim_input.params['amps']) except: sim_input.params['amps'] = [ float(sim_input.params['amps']) ] try: len(sim_input.params['durations']) except: sim_input.params['durations'] = [ float(sim_input.params['durations']) ] amplitudes = sim_input.params['amps'] durations = sim_input.params['durations'] rs = None if "rs" in sim_input.params.keys(): try: len(sim_input.params['rs']) except: sim_input.params['rs'] = [ float(sim_input.params['rs']) ] if len(sim_input.params['rs']) > 1: sim_input.params['rs'] = [ float(i) for i in sim_input.params['rs'] ] rs = sim_input.params["rs"] try: sim_input.params['gids'] except: sim_input.params['gids'] = None if sim_input.params['gids'] is not None: gids = sim_input.params['gids'] else: gids = list(node_set.gids()) sim.attach_se_voltage_clamp(amplitudes, durations, gids, rs) elif sim_input.module == 'xstim': sim.add_mod(mods.XStimMod(**sim_input.params)) else: io.log_exception('Can not parse input format {}'.format( sim_input.name)) # Parse the "reports" section of the config and load an associated output module for each report sim_reports = reports.from_config(config) for report in sim_reports: if isinstance(report, reports.SpikesReport): mod = mods.SpikesMod(**report.params) elif report.module == 'netcon_report': mod = mods.NetconReport(**report.params) elif isinstance(report, reports.MembraneReport): if report.params['sections'] == 'soma': mod = mods.SomaReport(**report.params) else: mod = mods.MembraneReport(**report.params) elif isinstance(report, reports.ClampReport): mod = mods.ClampReport(**report.params) elif isinstance(report, reports.ECPReport): mod = mods.EcpMod(**report.params) # Set up the ability for ecp on all relevant cells # TODO: According to spec we need to allow a different subset other than only biophysical cells for gid, cell in network.cell_type_maps('biophysical').items(): cell.setup_ecp() elif report.module == 'save_synapses': mod = mods.SaveSynapses(**report.params) else: # TODO: Allow users to register customized modules using pymodules io.log_warning('Unrecognized module {}, skipping.'.format( report.module)) continue sim.add_mod(mod) return sim
def from_config(cls, config, network, set_recordings=True): simulation_inputs = inputs.from_config(config) # Special case for setting synapses to spontaneously (for a given set of pre-synaptic cell-types). Using this # input will change the way the network builds cells/connections and thus needs to be set first. for sim_input in simulation_inputs: if sim_input.input_type == 'syn_activity': network.set_spont_syn_activity( precell_filter=sim_input.params['precell_filter'], timestamps=sim_input.params['timestamps'] ) # The network must be built before initializing the simulator because # gap junctions must be set up before the simulation is initialized. network.io.log_info('Building cells.') network.build_nodes() network.io.log_info('Building recurrent connections') network.build_recurrent_edges() sim = cls(network=network, dt=config.dt, tstop=config.tstop, v_init=config.v_init, celsius=config.celsius, nsteps_block=config.block_step) # TODO: Need to create a gid selector for sim_input in inputs.from_config(config): try: network.get_node_set(sim_input.node_set) except: print("Parameter node_set must be given in inputs module of simulation_config file. If unsure of what node_set should be, set it to 'all'.") node_set = network.get_node_set(sim_input.node_set) if sim_input.input_type == 'spikes': io.log_info('Building virtual cell stimulations for {}'.format(sim_input.name)) path = sim_input.params['input_file'] spikes = SpikeTrains.load(path=path, file_type=sim_input.module, **sim_input.params) network.add_spike_trains(spikes, node_set) elif sim_input.module == "FileIClamp": sim.attach_file_current_clamp(sim_input.params["input_file"]) elif sim_input.module == 'IClamp': # TODO: Parse from csv file try: len(sim_input.params['amp']) except: sim_input.params['amp']=[float(sim_input.params['amp'])] if len(sim_input.params['amp'])>1: sim_input.params['amp']=[float(i) for i in sim_input.params['amp']] try: len(sim_input.params['delay']) except: sim_input.params['delay']=[float(sim_input.params['delay'])] if len(sim_input.params['delay'])>1: sim_input.params['delay']=[float(i) for i in sim_input.params['delay']] try: len(sim_input.params['duration']) except: sim_input.params['duration']=[float(sim_input.params['duration'])] if len(sim_input.params['duration'])>1: sim_input.params['duration']=[float(i) for i in sim_input.params['duration']] amplitude = sim_input.params['amp'] delay = sim_input.params['delay'] duration = sim_input.params['duration'] # specificed for location to place iclamp hobj.<section_name>[<section_index>](<section_dist>). The # default is hobj.soma[0](0.5), the center of the soma section_name = sim_input.params.get('section_name', 'soma') section_index = sim_input.params.get('section_index', 0) section_dist = sim_input.params.get('section_dist', 0.5) # section_name = section_name if isinstance(section_name, (list, tuple)) else [section_name] # section_index = section_index if isinstance(section_index, (list, tuple)) else [section_index] # section_dist = section_dist if isinstance(section_dist, (list, tuple)) else [section_dist] try: sim_input.params['gids'] except: sim_input.params['gids'] = None if sim_input.params['gids'] is not None: gids = sim_input.params['gids'] else: gids = list(node_set.gids()) sim.attach_current_clamp(amplitude, delay, duration, gids, section_name, section_index, section_dist) elif sim_input.module == "SEClamp": try: len(sim_input.params['amps']) except: sim_input.params['amps']=[float(sim_input.params['amps'])] try: len(sim_input.params['durations']) except: sim_input.params['durations']=[float(sim_input.params['durations'])] amplitudes = sim_input.params['amps'] durations = sim_input.params['durations'] rs = None if "rs" in sim_input.params.keys(): try: len(sim_input.params['rs']) except: sim_input.params['rs']=[float(sim_input.params['rs'])] if len(sim_input.params['rs'])>1: sim_input.params['rs']=[float(i) for i in sim_input.params['rs']] rs = sim_input.params["rs"] try: sim_input.params['gids'] except: sim_input.params['gids'] = None if sim_input.params['gids'] is not None: gids = sim_input.params['gids'] else: gids = list(node_set.gids()) sim.attach_se_voltage_clamp(amplitudes, durations, gids, rs) elif sim_input.module == 'xstim': sim.add_mod(mods.XStimMod(**sim_input.params)) elif sim_input.module == 'syn_activity': pass else: io.log_exception('Can not parse input format {}'.format(sim_input.name)) # Parse the "reports" section of the config and load an associated output module for each report sim_reports = reports.from_config(config) for report in sim_reports: if isinstance(report, reports.SpikesReport): mod = mods.SpikesMod(**report.params) elif report.module == 'netcon_report': mod = mods.NetconReport(**report.params) elif isinstance(report, reports.MembraneReport): if report.params['sections'] == 'soma': mod = mods.SomaReport(**report.params) else: mod = mods.MembraneReport(**report.params) elif isinstance(report, reports.ClampReport): mod = mods.ClampReport(**report.params) elif isinstance(report, reports.ECPReport): mod = mods.EcpMod(**report.params) # Set up the ability for ecp on all relevant cells # TODO: According to spec we need to allow a different subset other than only biophysical cells for gid, cell in network.cell_type_maps('biophysical').items(): cell.setup_ecp() elif report.module == 'save_synapses': mod = mods.SaveSynapses(**report.params) else: # TODO: Allow users to register customized modules using pymodules io.log_warning('Unrecognized module {}, skipping.'.format(report.module)) continue sim.add_mod(mod) return sim
def _find_spikes(spikes_file=None, config_file=None, population=None): candidate_spikes = [] # Get spikes file(s) if spikes_file: # User has explicity set the location of the spike files candidate_spikes.append(spikes_file) elif config_file is not None: # Otherwise search the config.json for all possible output spikes_files. We can use the simulation_reports # module to find any spikes output file specified in config's "output" or "reports" section. config = SonataConfig.from_json(config_file) sim_reports = simulation_reports.from_config(config) for report in sim_reports: if report.module == 'spikes_report': # BMTK can end up output the same spikes file in SONATA, CSV, and NWB format. Try fetching the SONATA # version first, then CSV, and finally NWB if it exists. spikes_sonata = report.params.get('spikes_file', None) spikes_csv = report.params.get('spikes_file_csv', None) spikes_nwb = report.params.get('spikes_file_nwb', None) if spikes_sonata is not None: candidate_spikes.append(spikes_sonata) elif spikes_csv is not None: candidate_spikes.append(spikes_csv) elif spikes_csv is not None: candidate_spikes.append(spikes_nwb) # TODO: Should we also look in the "inputs" for displaying input spike statistics? if not candidate_spikes: raise ValueError( 'Could not find an output spikes-file. Use "spikes_file" parameter option.' ) # Find file that contains spikes for the specified "population" of nodes. If "population" parameter is not # specified try to guess that spikes that the user wants to visualize. if population is not None: spikes_obj = None for spikes_f in candidate_spikes: st = SpikeTrains.load(spikes_f) if population in st.populations: if spikes_obj is None: spikes_obj = st else: spikes_obj.merge(st) if spikes_obj is None: raise ValueError( 'Could not fine spikes file with node population "{}".'.format( population)) else: return population, spikes_obj else: if len(candidate_spikes) > 1: raise ValueError('Found more than one spike-trains file') spikes_f = candidate_spikes[0] if not os.path.exists(spikes_f): raise ValueError( 'Did not find spike-trains file {}. Make sure the simulation has completed.' .format(spikes_f)) spikes_obj = SpikeTrains.load(spikes_f) if len(spikes_obj.populations) > 1: raise ValueError( 'Spikes file {} contains more than one node population.'. format(spikes_f)) else: return spikes_obj.populations[0], spikes_obj
def test_from_config(): config = { 'reports': { "membrane_potential": { "cells": 'some', "variable_name": "v", "module": "membrane_report", "sections": "soma", "enabled": True }, "syn_report": { "cells": [0, 1], "variable_name": "tau1", "module": "netcon_report", "sections": "soma", "syn_type": "Exp2Syn" }, "ecp": { "cells": 'all', "variable_name": "v", "module": "extracellular", "electrode_positions": "linear_electrode.csv", "file_name": "ecp.h5", "electrode_channels": "all", "contributions_dir": "ecp_contributions" }, "spikes": { 'cells': 'all', 'module': 'spikes_report', 'spikes_file': 'my_spikes.h5', 'cache_to_disk': False } } } config_dict = SonataConfig.from_dict(config) reports = from_config(config_dict) assert (len(reports) == 4) assert ({r.report_name for r in reports } == {'spikes', 'ecp', 'membrane_potential', 'syn_report'}) for report in reports: if report.report_name == 'spikes': assert (isinstance(report, SpikesReport)) assert (report.params == { 'cells': 'all', 'spikes_file': 'my_spikes.h5', 'cache_to_disk': False }) elif report.report_name == 'ecp': assert (isinstance(report, ECPReport)) assert (report.params == { 'cells': 'all', 'variable_name': 'v', 'electrode_positions': 'linear_electrode.csv', 'file_name': 'ecp.h5', 'electrode_channels': 'all', 'contributions_dir': 'ecp_contributions', 'tmp_dir': '.' }) elif report.report_name == 'membrane_potential': assert (isinstance(report, MembraneReport)) assert (report.params == { 'cells': 'some', 'variable_name': ['v'], 'sections': 'soma', 'tmp_dir': '.', 'file_name': 'membrane_potential.h5', 'transform': {}, 'buffer_data': True }) elif report.report_name == 'syn_report': assert (isinstance(report, MembraneReport)) assert (report.params == { 'cells': [0, 1], 'variable_name': ['tau1'], 'sections': 'soma', 'syn_type': 'Exp2Syn', 'tmp_dir': '.', 'file_name': 'syn_report.h5', 'transform': {}, 'buffer_data': True })
def from_config(cls, configure, graph): # load the json file or object if isinstance(configure, string_types): config = Config.from_json(configure, validate=True) elif isinstance(configure, dict): config = configure else: raise Exception('Could not convert {} (type "{}") to json.'.format( configure, type(configure))) if 'run' not in config: raise Exception( 'Json file is missing "run" entry. Unable to build Bionetwork.' ) run_dict = config['run'] # Get network parameters # step time (dt) is set in the kernel and should be passed overwrite = run_dict[ 'overwrite_output_dir'] if 'overwrite_output_dir' in run_dict else True print_time = run_dict[ 'print_time'] if 'print_time' in run_dict else False dt = run_dict['dt'] # TODO: make sure dt exists network = cls(graph, dt=dt, overwrite=overwrite) if 'output_dir' in config['output']: network.output_dir = config['output']['output_dir'] if 'block_run' in run_dict and run_dict['block_run']: if 'block_size' not in run_dict: raise Exception( '"block_run" is set to True but "block_size" not found.') network._block_size = run_dict['block_size'] if 'duration' in run_dict: network.tstop = run_dict['duration'] elif 'tstop' in run_dict: network.tstop = run_dict['tstop'] if 'precise_times' in run_dict: network.set_spike_generator_params( precise_times=run_dict['precise_times']) if run_dict.get('allow_offgrid_spikes', False): network.set_spike_generator_params(allow_offgrid_spikes=True) # Create the output-directory, or delete existing files if it already exists graph.io.log_info('Setting up output directory') if not os.path.exists(config['output']['output_dir']): os.mkdir(config['output']['output_dir']) elif overwrite: for gfile in glob.glob( os.path.join(config['output']['output_dir'], '*.gdf')): os.remove(gfile) graph.io.log_info('Building cells.') graph.build_nodes() graph.io.log_info('Building recurrent connections') graph.build_recurrent_edges() for sim_input in inputs.from_config(config): node_set = graph.get_node_set(sim_input.node_set) if sim_input.input_type == 'spikes': io.log_info('Build virtual cell stimulations for {}'.format( sim_input.name)) path = sim_input.params['input_file'] spikes = SpikeTrains.load(path=path, file_type=sim_input.module, **sim_input.params) #spikes = spike_trains.SpikesInput.load(name=sim_input.name, module=sim_input.module, # input_type=sim_input.input_type, params=sim_input.params) graph.add_spike_trains(spikes, node_set, network.get_spike_generator_params()) elif sim_input.input_type == 'current_clamp': # TODO: Need to make this more robust amp_times = sim_input.params.get('amplitude_times', []) amp_values = sim_input.params.get('amplitude_values', []) if 'delay' in sim_input.params: amp_times.append(sim_input.params['delay']) amp_values.append(sim_input.params['amp']) if 'duration' in sim_input.params: amp_times.append(sim_input.params['delay'] + sim_input.params['duration']) amp_values.append(0.0) network.add_step_currents(amp_times, amp_values, node_set, sim_input.name) else: graph.io.log_warning('Unknown input type {}'.format( sim_input.input_type)) sim_reports = reports.from_config(config) for report in sim_reports: if report.module == 'spikes_report': mod = mods.SpikesMod(**report.params) elif isinstance(report, reports.MembraneReport): # For convience and for compliance with SONATA format. "membrane_report" and "multimeter_report is the # same in pointnet. mod = mods.MultimeterMod(**report.params) else: graph.io.log_exception('Unknown report type {}'.format( report.module)) network.add_mod(mod) io.log_info('Network created.') return network
def from_config(cls, configure, graph): # load the json file or object if isinstance(configure, basestring): config = Config.from_json(configure, validate=True) elif isinstance(configure, dict): config = configure else: raise Exception('Could not convert {} (type "{}") to json.'.format( configure, type(configure))) if 'run' not in config: raise Exception( 'Json file is missing "run" entry. Unable to build Bionetwork.' ) run_dict = config['run'] # Get network parameters # step time (dt) is set in the kernel and should be passed overwrite = run_dict[ 'overwrite_output_dir'] if 'overwrite_output_dir' in run_dict else True print_time = run_dict[ 'print_time'] if 'print_time' in run_dict else False dt = run_dict['dt'] # TODO: make sure dt exists network = cls(graph, dt=dt, overwrite=overwrite) if 'output_dir' in config['output']: network.output_dir = config['output']['output_dir'] if 'block_run' in run_dict and run_dict['block_run']: if 'block_size' not in run_dict: raise Exception( '"block_run" is set to True but "block_size" not found.') network._block_size = run_dict['block_size'] if 'duration' in run_dict: network.duration = run_dict['duration'] elif 'tstop' in run_dict: network.duration = run_dict['tstop'] # Create the output-directory, or delete existing files if it already exists graph.io.log_info('Setting up output directory') if not os.path.exists(config['output']['output_dir']): os.mkdir(config['output']['output_dir']) elif overwrite: for gfile in glob.glob( os.path.join(config['output']['output_dir'], '*.gdf')): os.remove(gfile) graph.io.log_info('Building cells.') graph.build_nodes() graph.io.log_info('Building recurrent connections') graph.build_recurrent_edges() for sim_input in inputs.from_config(config): node_set = graph.get_node_set(sim_input.node_set) if sim_input.input_type == 'spikes': spikes = spike_trains.SpikesInput.load( name=sim_input.name, module=sim_input.module, input_type=sim_input.input_type, params=sim_input.params) io.log_info('Build virtual cell stimulations for {}'.format( sim_input.name)) graph.add_spike_trains(spikes, node_set) sim_reports = reports.from_config(config) for report in sim_reports: if report.module == 'spikes_report': mod = mods.SpikesMod(**report.params) else: graph.io.log_exception('Unknown report type {}'.format( report.module)) network.add_mod(mod) io.log_info('Network created.') return network