def test_network(): """Test network object.""" params = read_params(params_fname) # add rhythmic inputs (i.e., a type of common input) params.update({ 'input_dist_A_weight_L2Pyr_ampa': 1.4e-5, 'input_dist_A_weight_L5Pyr_ampa': 2.4e-5, 't0_input_dist': 50, 'input_prox_A_weight_L2Pyr_ampa': 3.4e-5, 'input_prox_A_weight_L5Pyr_ampa': 4.4e-5, 't0_input_prox': 50 }) net = jones_2009_model(deepcopy(params), add_drives_from_params=True) # instantiate drive events for NetworkBuilder net._instantiate_drives(tstop=params['tstop'], n_trials=params['N_trials']) network_builder = NetworkBuilder(net) # needed to instantiate cells # Assert that params are conserved across Network initialization for p in params: assert params[p] == net._params[p] assert len(params) == len(net._params) print(network_builder) print(network_builder._cells[:2]) # Assert that proper number/types of gids are created for Network drives dns_from_gids = [ name for name in net.gid_ranges.keys() if name not in net.cell_types ] assert sorted(dns_from_gids) == sorted(net.external_drives.keys()) for dn in dns_from_gids: n_drive_cells = net.external_drives[dn]['n_drive_cells'] assert len(net.gid_ranges[dn]) == n_drive_cells # Check drive dict structure for each external drive for drive in net.external_drives.values(): # Check that connectivity sources correspond to gid_ranges conn_idxs = pick_connection(net, src_gids=drive['name']) this_src_gids = set([ gid for conn_idx in conn_idxs for gid in net.connectivity[conn_idx]['src_gids'] ]) # NB set: globals assert sorted(this_src_gids) == list(net.gid_ranges[drive['name']]) # Check type-specific dynamics and events n_drive_cells = drive['n_drive_cells'] assert len(drive['events']) == 1 # single trial simulated if drive['type'] == 'evoked': for kw in ['mu', 'sigma', 'numspikes']: assert kw in drive['dynamics'].keys() assert len(drive['events'][0]) == n_drive_cells # this also implicitly tests that events are always a list assert len(drive['events'][0][0]) == drive['dynamics']['numspikes'] elif drive['type'] == 'gaussian': for kw in ['mu', 'sigma', 'numspikes']: assert kw in drive['dynamics'].keys() assert len(drive['events'][0]) == n_drive_cells elif drive['type'] == 'poisson': for kw in ['tstart', 'tstop', 'rate_constant']: assert kw in drive['dynamics'].keys() assert len(drive['events'][0]) == n_drive_cells elif drive['type'] == 'bursty': for kw in [ 'tstart', 'tstart_std', 'tstop', 'burst_rate', 'burst_std', 'numspikes' ]: assert kw in drive['dynamics'].keys() assert len(drive['events'][0]) == n_drive_cells n_events = ( drive['dynamics']['numspikes'] * # 2 (1 + (drive['dynamics']['tstop'] - drive['dynamics']['tstart'] - 1) // (1000. / drive['dynamics']['burst_rate']))) assert len(drive['events'][0][0]) == n_events # 4 # make sure the PRNGs are consistent. target_times = { 'evdist1': [66.30498327062551, 61.54362532343694], 'evprox1': [23.80641637082997, 30.857310915553647], 'evprox2': [141.76252038319825, 137.73942375578602] } for drive_name in target_times: for idx in [0, -1]: # first and last assert_allclose(net.external_drives[drive_name]['events'][0][idx], target_times[drive_name][idx], rtol=1e-12) # check select AMPA weights target_weights = { 'evdist1': { 'L2_basket': 0.006562, 'L5_pyramidal': 0.142300 }, 'evprox1': { 'L2_basket': 0.08831, 'L5_pyramidal': 0.00865 }, 'evprox2': { 'L2_basket': 0.000003, 'L5_pyramidal': 0.684013 }, 'bursty1': { 'L2_pyramidal': 0.000034, 'L5_pyramidal': 0.000044 }, 'bursty2': { 'L2_pyramidal': 0.000014, 'L5_pyramidal': 0.000024 } } for drive_name in target_weights: for target_type in target_weights[drive_name]: conn_idxs = pick_connection(net, src_gids=drive_name, target_gids=target_type, receptor='ampa') for conn_idx in conn_idxs: drive_conn = net.connectivity[conn_idx] assert_allclose(drive_conn['nc_dict']['A_weight'], target_weights[drive_name][target_type], rtol=1e-12) # check select synaptic delays target_delays = { 'evdist1': { 'L2_basket': 0.1, 'L5_pyramidal': 0.1 }, 'evprox1': { 'L2_basket': 0.1, 'L5_pyramidal': 1. }, 'evprox2': { 'L2_basket': 0.1, 'L5_pyramidal': 1. } } for drive_name in target_delays: for target_type in target_delays[drive_name]: conn_idxs = pick_connection(net, src_gids=drive_name, target_gids=target_type, receptor='ampa') for conn_idx in conn_idxs: drive_conn = net.connectivity[conn_idx] assert_allclose(drive_conn['nc_dict']['A_delay'], target_delays[drive_name][target_type], rtol=1e-12) # array of simulation times is created in Network.__init__, but passed # to CellResponse-constructor for storage (Network is agnostic of time) with pytest.raises(TypeError, match="'times' is an np.ndarray of simulation times"): _ = CellResponse(times='blah') # Assert that all external drives are initialized # Assumes legacy mode where cell-specific drives create artificial cells # for all network cells regardless of connectivity n_evoked_sources = 3 * net._n_cells n_pois_sources = net._n_cells n_gaus_sources = net._n_cells n_bursty_sources = (net.external_drives['bursty1']['n_drive_cells'] + net.external_drives['bursty2']['n_drive_cells']) # test that expected number of external driving events are created assert len( network_builder._drive_cells) == (n_evoked_sources + n_pois_sources + n_gaus_sources + n_bursty_sources) assert len(network_builder._gid_list) ==\ len(network_builder._drive_cells) + net._n_cells # first 'evoked drive' comes after real cells and bursty drive cells assert network_builder._drive_cells[n_bursty_sources].gid ==\ net._n_cells + n_bursty_sources # Assert that netcons are created properly n_pyr = len(net.gid_ranges['L2_pyramidal']) n_basket = len(net.gid_ranges['L2_basket']) # Check basket-basket connection where allow_autapses=False assert 'L2Pyr_L2Pyr_nmda' in network_builder.ncs n_connections = 3 * (n_pyr**2 - n_pyr) # 3 synapses / cell assert len(network_builder.ncs['L2Pyr_L2Pyr_nmda']) == n_connections nc = network_builder.ncs['L2Pyr_L2Pyr_nmda'][0] assert nc.threshold == params['threshold'] # Check bursty drives which use cell_specific=False assert 'bursty1_L2Pyr_ampa' in network_builder.ncs n_bursty1_sources = net.external_drives['bursty1']['n_drive_cells'] n_connections = n_bursty1_sources * 3 * n_pyr # 3 synapses / cell assert len(network_builder.ncs['bursty1_L2Pyr_ampa']) == n_connections nc = network_builder.ncs['bursty1_L2Pyr_ampa'][0] assert nc.threshold == params['threshold'] # Check basket-basket connection where allow_autapses=True assert 'L2Basket_L2Basket_gabaa' in network_builder.ncs n_connections = n_basket**2 # 1 synapse / cell assert len(network_builder.ncs['L2Basket_L2Basket_gabaa']) == n_connections nc = network_builder.ncs['L2Basket_L2Basket_gabaa'][0] assert nc.threshold == params['threshold'] # Check evoked drives which use cell_specific=True assert 'evdist1_L2Basket_nmda' in network_builder.ncs n_connections = n_basket # 1 synapse / cell assert len(network_builder.ncs['evdist1_L2Basket_nmda']) == n_connections nc = network_builder.ncs['evdist1_L2Basket_nmda'][0] assert nc.threshold == params['threshold'] # Test inputs for connectivity API net = jones_2009_model(deepcopy(params), add_drives_from_params=True) # instantiate drive events for NetworkBuilder net._instantiate_drives(tstop=params['tstop'], n_trials=params['N_trials']) n_conn = len(network_builder.ncs['L2Basket_L2Pyr_gabaa']) kwargs_default = dict(src_gids=[0, 1], target_gids=[35, 36], loc='soma', receptor='gabaa', weight=5e-4, delay=1.0, lamtha=1e9, probability=1.0) net.add_connection(**kwargs_default) # smoke test network_builder = NetworkBuilder(net) assert len(network_builder.ncs['L2Basket_L2Pyr_gabaa']) == n_conn + 4 nc = network_builder.ncs['L2Basket_L2Pyr_gabaa'][-1] assert_allclose(nc.weight[0], kwargs_default['weight']) kwargs_good = [('src_gids', 0), ('src_gids', 'L2_pyramidal'), ('src_gids', range(2)), ('target_gids', 35), ('target_gids', range(2)), ('target_gids', 'L2_pyramidal'), ('target_gids', [[35, 36], [37, 38]]), ('probability', 0.5)] for arg, item in kwargs_good: kwargs = kwargs_default.copy() kwargs[arg] = item net.add_connection(**kwargs) kwargs_bad = [('src_gids', 0.0), ('src_gids', [0.0]), ('target_gids', 35.0), ('target_gids', [35.0]), ('target_gids', [[35], [36.0]]), ('loc', 1.0), ('receptor', 1.0), ('weight', '1.0'), ('delay', '1.0'), ('lamtha', '1.0'), ('probability', '0.5')] for arg, item in kwargs_bad: match = ('must be an instance of') with pytest.raises(TypeError, match=match): kwargs = kwargs_default.copy() kwargs[arg] = item net.add_connection(**kwargs) kwargs_bad = [('src_gids', -1), ('src_gids', [-1]), ('target_gids', -1), ('target_gids', [-1]), ('target_gids', [[35], [-1]]), ('target_gids', [[35]]), ('src_gids', [0, 100]), ('target_gids', [0, 100])] for arg, item in kwargs_bad: with pytest.raises(AssertionError): kwargs = kwargs_default.copy() kwargs[arg] = item net.add_connection(**kwargs) for arg in ['src_gids', 'target_gids', 'loc', 'receptor']: string_arg = 'invalid_string' match = f"Invalid value for the '{arg}' parameter" with pytest.raises(ValueError, match=match): kwargs = kwargs_default.copy() kwargs[arg] = string_arg net.add_connection(**kwargs) # Check probability=0.5 produces half as many connections as default net.add_connection(**kwargs_default) kwargs = kwargs_default.copy() kwargs['probability'] = 0.5 net.add_connection(**kwargs) n_connections = np.sum( [len(t_gids) for t_gids in net.connectivity[-2]['gid_pairs'].values()]) n_connections_new = np.sum( [len(t_gids) for t_gids in net.connectivity[-1]['gid_pairs'].values()]) assert n_connections_new == np.round(n_connections * 0.5).astype(int) assert net.connectivity[-1]['probability'] == 0.5 with pytest.raises(ValueError, match='probability must be'): kwargs = kwargs_default.copy() kwargs['probability'] = -1.0 net.add_connection(**kwargs) # Test net.pick_connection() kwargs_default = dict(net=net, src_gids=None, target_gids=None, loc=None, receptor=None) kwargs_good = [('src_gids', 0), ('src_gids', 'L2_pyramidal'), ('src_gids', range(2)), ('src_gids', None), ('target_gids', 35), ('target_gids', range(2)), ('target_gids', 'L2_pyramidal'), ('target_gids', None), ('loc', 'soma'), ('loc', None), ('receptor', 'gabaa'), ('receptor', None)] for arg, item in kwargs_good: kwargs = kwargs_default.copy() kwargs[arg] = item indices = pick_connection(**kwargs) for conn_idx in indices: if (arg == 'src_gids' or arg == 'target_gids') and \ isinstance(item, str): assert np.all( np.in1d(net.connectivity[conn_idx][arg], net.gid_ranges[item])) elif item is None: pass else: assert np.any(np.in1d([item], net.connectivity[conn_idx][arg])) # Check that a given gid isn't present in any connection profile that # pick_connection can't identify conn_idxs = pick_connection(net, src_gids=0) for conn_idx in range(len(net.connectivity)): if conn_idx not in conn_idxs: assert 0 not in net.connectivity[conn_idx]['src_gids'] # Check that pick_connection returns empty lists when searching for # a drive targetting the wrong location conn_idxs = pick_connection(net, src_gids='evdist1', loc='proximal') assert len(conn_idxs) == 0 assert not pick_connection(net, src_gids='evprox1', loc='distal') # Check condition where not connections match assert pick_connection(net, loc='distal', receptor='gabab') == list() kwargs_bad = [('src_gids', 0.0), ('src_gids', [0.0]), ('target_gids', 35.0), ('target_gids', [35.0]), ('target_gids', [35, [36.0]]), ('loc', 1.0), ('receptor', 1.0)] for arg, item in kwargs_bad: match = ('must be an instance of') with pytest.raises(TypeError, match=match): kwargs = kwargs_default.copy() kwargs[arg] = item pick_connection(**kwargs) kwargs_bad = [('src_gids', -1), ('src_gids', [-1]), ('target_gids', -1), ('target_gids', [-1]), ('src_gids', [35, -1]), ('target_gids', [35, -1])] for arg, item in kwargs_bad: with pytest.raises(AssertionError): kwargs = kwargs_default.copy() kwargs[arg] = item pick_connection(**kwargs) for arg in ['src_gids', 'target_gids', 'loc', 'receptor']: string_arg = 'invalid_string' match = f"Invalid value for the '{arg}' parameter" with pytest.raises(ValueError, match=match): kwargs = kwargs_default.copy() kwargs[arg] = string_arg pick_connection(**kwargs) # Test removing connections from net.connectivity # Needs to be updated if number of drives change in preceeding tests net.clear_connectivity() assert len(net.connectivity) == 50 net.clear_drives() assert len(net.connectivity) == 0
# Instantiating the network comes with a predefined set of connections that # reflect the canonical neocortical microcircuit. ``net.connectivity`` # is a list of dictionaries which detail every cell-cell, and drive-cell # connection. The weights of these connections can be visualized with # :func:`~hnn_core.viz.plot_connectivity_weights` as well as # :func:`~hnn_core.viz.plot_cell_connectivity`. We can search for specific # connections using ``pick_connection`` which returns the indices # of ``net.connectivity`` that match the provided parameters. from hnn_core.viz import plot_connectivity_matrix, plot_cell_connectivity from hnn_core.network import pick_connection print(len(net_erp.connectivity)) conn_indices = pick_connection(net=net_erp, src_gids='L5_basket', target_gids='L5_pyramidal', loc='soma', receptor='gabaa') conn_idx = conn_indices[0] print(net_erp.connectivity[conn_idx]) plot_connectivity_matrix(net_erp, conn_idx) gid_idx = 11 src_gid = net_erp.connectivity[conn_idx]['src_gids'][gid_idx] fig = plot_cell_connectivity(net_erp, conn_idx, src_gid) ############################################################################### # Data recorded during simulations are stored under # :class:`~hnn_core.Cell_Response`. Spiking activity can be visualized after # a simulation is using :meth:`~hnn_core.Cell_Response.plot_spikes_raster` dpl_erp = simulate_dipole(net_erp, tstop=170., n_trials=1)
def test_add_drives(): """Test methods for adding drives to a Network.""" hnn_core_root = op.dirname(hnn_core.__file__) params_fname = op.join(hnn_core_root, 'param', 'default.json') params = read_params(params_fname) net = Network(params, legacy_mode=False) # Ensure weights and delays are updated weights_ampa = {'L2_basket': 1.0, 'L2_pyramidal': 3.0, 'L5_pyramidal': 4.0} syn_delays = {'L2_basket': 1.0, 'L2_pyramidal': 2.0, 'L5_pyramidal': 4.0} n_drive_cells = 10 cell_specific = False # default for bursty drive net.add_bursty_drive( 'bursty', location='distal', burst_rate=10, weights_ampa=weights_ampa, synaptic_delays=syn_delays, n_drive_cells=n_drive_cells) assert net.external_drives['bursty']['n_drive_cells'] == n_drive_cells assert net.external_drives['bursty']['cell_specific'] == cell_specific conn_idxs = pick_connection(net, src_gids='bursty') for conn_idx in conn_idxs: drive_conn = net.connectivity[conn_idx] target_type = drive_conn['target_type'] assert drive_conn['nc_dict']['A_weight'] == weights_ampa[target_type] assert drive_conn['nc_dict']['A_delay'] == syn_delays[target_type] n_drive_cells = 'n_cells' # default for evoked drive cell_specific = True net.add_evoked_drive( 'evoked_dist', mu=1.0, sigma=1.0, numspikes=1.0, weights_ampa=weights_ampa, location='distal', synaptic_delays=syn_delays, cell_specific=True) n_dist_targets = 235 # 270 with legacy mode assert (net.external_drives['evoked_dist'] ['n_drive_cells'] == n_dist_targets) assert net.external_drives['evoked_dist']['cell_specific'] == cell_specific conn_idxs = pick_connection(net, src_gids='evoked_dist') for conn_idx in conn_idxs: drive_conn = net.connectivity[conn_idx] target_type = drive_conn['target_type'] assert drive_conn['nc_dict']['A_weight'] == weights_ampa[target_type] assert drive_conn['nc_dict']['A_delay'] == syn_delays[target_type] n_drive_cells = 'n_cells' # default for poisson drive cell_specific = True net.add_poisson_drive( 'poisson', rate_constant=1.0, weights_ampa=weights_ampa, location='distal', synaptic_delays=syn_delays, cell_specific=cell_specific) n_dist_targets = 235 # 270 with non-legacy mode assert (net.external_drives['poisson'] ['n_drive_cells'] == n_dist_targets) assert net.external_drives['poisson']['cell_specific'] == cell_specific conn_idxs = pick_connection(net, src_gids='poisson') for conn_idx in conn_idxs: drive_conn = net.connectivity[conn_idx] target_type = drive_conn['target_type'] assert drive_conn['nc_dict']['A_weight'] == weights_ampa[target_type] assert drive_conn['nc_dict']['A_delay'] == syn_delays[target_type] # evoked with pytest.raises(ValueError, match='Standard deviation cannot be negative'): net.add_evoked_drive('evdist1', mu=10, sigma=-1, numspikes=1, location='distal') with pytest.raises(ValueError, match='Number of spikes must be greater than zero'): net.add_evoked_drive('evdist1', mu=10, sigma=1, numspikes=0, location='distal') # Test Network._attach_drive() with pytest.raises(ValueError, match=r'Allowed drive target locations are'): net.add_evoked_drive('evdist1', mu=10, sigma=1, numspikes=1, location='bogus_location') with pytest.raises(ValueError, match='Drive evoked_dist already defined'): net.add_evoked_drive('evoked_dist', mu=10, sigma=1, numspikes=1, location='distal') with pytest.raises(ValueError, match='No target cell types have been given a synaptic ' 'weight'): net.add_evoked_drive('evdist1', mu=10, sigma=1, numspikes=1, location='distal') with pytest.raises(ValueError, match='When adding a distal drive, synaptic weight ' 'cannot be defined for the L5_basket cell type'): net.add_evoked_drive('evdist1', mu=10, sigma=1, numspikes=1, location='distal', weights_ampa={'L5_basket': 1.}, synaptic_delays={'L5_basket': .1}) with pytest.raises(ValueError, match='If cell_specific is True, n_drive_cells'): net.add_evoked_drive('evdist1', mu=10, sigma=1, numspikes=1, location='distal', n_drive_cells=10, cell_specific=True, weights_ampa=weights_ampa, synaptic_delays=syn_delays) with pytest.raises(ValueError, match='If cell_specific is False, n_drive_cells'): net.add_evoked_drive('evdist1', mu=10, sigma=1, numspikes=1, location='distal', n_drive_cells='n_cells', cell_specific=False, weights_ampa=weights_ampa, synaptic_delays=syn_delays) with pytest.raises(ValueError, match='Number of drive cells must be greater than 0'): net.add_evoked_drive('evdist1', mu=10, sigma=1, numspikes=1, location='distal', n_drive_cells=0, cell_specific=False, weights_ampa=weights_ampa, synaptic_delays=syn_delays) # Poisson with pytest.raises(ValueError, match='End time of Poisson drive cannot be negative'): net.add_poisson_drive('poisson1', tstart=0, tstop=-1, location='distal', rate_constant=10.) with pytest.raises(ValueError, match='Start time of Poisson drive cannot be negative'): net.add_poisson_drive('poisson1', tstart=-1, location='distal', rate_constant=10.) with pytest.raises(ValueError, match='Duration of Poisson drive cannot be negative'): net.add_poisson_drive('poisson1', tstart=10, tstop=1, location='distal', rate_constant=10.) with pytest.raises(ValueError, match='Rate constant must be positive'): net.add_poisson_drive('poisson1', location='distal', rate_constant=0., weights_ampa=weights_ampa, synaptic_delays=syn_delays) with pytest.raises(ValueError, match='Rate constants not provided for all target'): net.add_poisson_drive('poisson1', location='distal', rate_constant={'L2_pyramidal': 10.}, weights_ampa=weights_ampa, synaptic_delays=syn_delays) with pytest.raises(ValueError, match='Rate constant provided for unknown target cell'): net.add_poisson_drive('poisson1', location='distal', rate_constant={'L2_pyramidal': 10., 'bogus_celltype': 20.}, weights_ampa={'L2_pyramidal': .01, 'bogus_celltype': .01}, synaptic_delays=0.1) with pytest.raises(ValueError, match='Drives specific to cell types are only ' 'possible with cell_specific=True'): net.add_poisson_drive('poisson1', location='distal', rate_constant={'L2_basket': 10., 'L2_pyramidal': 11., 'L5_basket': 12., 'L5_pyramidal': 13.}, n_drive_cells=1, cell_specific=False, weights_ampa=weights_ampa, synaptic_delays=syn_delays) # bursty with pytest.raises(ValueError, match='End time of bursty drive cannot be negative'): net.add_bursty_drive('bursty_drive', tstop=-1, location='distal', burst_rate=10) with pytest.raises(ValueError, match='Start time of bursty drive cannot be negative'): net.add_bursty_drive('bursty_drive', tstart=-1, location='distal', burst_rate=10) with pytest.raises(ValueError, match='Duration of bursty drive cannot be negative'): net.add_bursty_drive('bursty_drive', tstart=10, tstop=1, location='distal', burst_rate=10) msg = (r'Burst duration (?s).* cannot be greater than ' 'burst period') with pytest.raises(ValueError, match=msg): net.add_bursty_drive('bursty_drive', location='distal', burst_rate=10, burst_std=20., numspikes=4, spike_isi=50) # attaching drives with pytest.raises(ValueError, match='Drive evoked_dist already defined'): net.add_poisson_drive('evoked_dist', location='distal', rate_constant=10., weights_ampa=weights_ampa, synaptic_delays=syn_delays) with pytest.raises(ValueError, match='Allowed drive target locations are:'): net.add_poisson_drive('weird_poisson', location='inbetween', rate_constant=10., weights_ampa=weights_ampa, synaptic_delays=syn_delays) with pytest.raises(ValueError, match='Allowed drive target cell types are:'): net.add_poisson_drive('cell_unknown', location='proximal', rate_constant=10., weights_ampa={'CA1_pyramidal': 1.}, synaptic_delays=.01) with pytest.raises(ValueError, match='synaptic_delays is either a common float or ' 'needs to be specified as a dict for each of the cell'): net.add_poisson_drive('cell_unknown', location='proximal', rate_constant=10., weights_ampa={'L2_pyramidal': 1.}, synaptic_delays={'L5_pyramidal': 1.})
def test_add_drives(): """Test methods for adding drives to a Network.""" hnn_core_root = op.dirname(hnn_core.__file__) params_fname = op.join(hnn_core_root, 'param', 'default.json') params = read_params(params_fname) net = Network(params, legacy_mode=False) # Ensure weights and delays are updated weights_ampa = {'L2_basket': 1.0, 'L2_pyramidal': 3.0, 'L5_pyramidal': 4.0} syn_delays = {'L2_basket': 1.0, 'L2_pyramidal': 2.0, 'L5_pyramidal': 4.0} n_drive_cells = 10 cell_specific = False # default for bursty drive net.add_bursty_drive('bursty', location='distal', burst_rate=10, weights_ampa=weights_ampa, synaptic_delays=syn_delays, n_drive_cells=n_drive_cells) assert net.external_drives['bursty']['n_drive_cells'] == n_drive_cells assert net.external_drives['bursty']['cell_specific'] == cell_specific conn_idxs = pick_connection(net, src_gids='bursty') for conn_idx in conn_idxs: drive_conn = net.connectivity[conn_idx] target_type = drive_conn['target_type'] assert drive_conn['nc_dict']['A_weight'] == weights_ampa[target_type] assert drive_conn['nc_dict']['A_delay'] == syn_delays[target_type] n_drive_cells = 'n_cells' # default for evoked drive cell_specific = True net.add_evoked_drive('evoked_dist', mu=1.0, sigma=1.0, numspikes=1.0, weights_ampa=weights_ampa, location='distal', synaptic_delays=syn_delays, cell_specific=True) n_dist_targets = 235 # 270 with legacy mode assert ( net.external_drives['evoked_dist']['n_drive_cells'] == n_dist_targets) assert net.external_drives['evoked_dist']['cell_specific'] == cell_specific conn_idxs = pick_connection(net, src_gids='evoked_dist') for conn_idx in conn_idxs: drive_conn = net.connectivity[conn_idx] target_type = drive_conn['target_type'] assert drive_conn['nc_dict']['A_weight'] == weights_ampa[target_type] assert drive_conn['nc_dict']['A_delay'] == syn_delays[target_type] n_drive_cells = 'n_cells' # default for poisson drive cell_specific = True net.add_poisson_drive('poisson', rate_constant=1.0, weights_ampa=weights_ampa, location='distal', synaptic_delays=syn_delays, cell_specific=cell_specific) n_dist_targets = 235 # 270 with non-legacy mode assert (net.external_drives['poisson']['n_drive_cells'] == n_dist_targets) assert net.external_drives['poisson']['cell_specific'] == cell_specific conn_idxs = pick_connection(net, src_gids='poisson') for conn_idx in conn_idxs: drive_conn = net.connectivity[conn_idx] target_type = drive_conn['target_type'] assert drive_conn['nc_dict']['A_weight'] == weights_ampa[target_type] assert drive_conn['nc_dict']['A_delay'] == syn_delays[target_type] # Test probabalistic drive connections. # drive with cell_specific=False n_drive_cells = 10 probability = 0.5 # test that only half of possible connections are made weights_nmda = {'L2_basket': 1.0, 'L2_pyramidal': 3.0, 'L5_pyramidal': 4.0} net.add_bursty_drive('bursty_prob', location='distal', burst_rate=10, weights_ampa=weights_ampa, weights_nmda=weights_nmda, synaptic_delays=syn_delays, n_drive_cells=n_drive_cells, probability=probability) for cell_type in weights_ampa.keys(): conn_idxs = pick_connection(net, src_gids='bursty_prob', target_gids=cell_type) gid_pairs_comparison = net.connectivity[conn_idxs[0]]['gid_pairs'] for conn_idx in conn_idxs: conn = net.connectivity[conn_idx] num_connections = np.sum( [len(gids) for gids in conn['gid_pairs'].values()]) # Ensures that AMPA and NMDA connections target the same gids. # Necessary when weights of both are non-zero. assert gid_pairs_comparison == conn['gid_pairs'] assert num_connections == \ np.around(len(net.gid_ranges[cell_type]) * n_drive_cells * probability).astype(int) # drives with cell_specific=True probability = {'L2_basket': 0.1, 'L2_pyramidal': 0.25, 'L5_pyramidal': 0.5} net.add_evoked_drive('evoked_prob', mu=1.0, sigma=1.0, numspikes=1.0, weights_ampa=weights_ampa, weights_nmda=weights_nmda, location='distal', synaptic_delays=syn_delays, cell_specific=True, probability=probability) for cell_type in weights_ampa.keys(): conn_idxs = pick_connection(net, src_gids='evoked_prob', target_gids=cell_type) gid_pairs_comparison = net.connectivity[conn_idxs[0]]['gid_pairs'] for conn_idx in conn_idxs: conn = net.connectivity[conn_idx] num_connections = np.sum( [len(gids) for gids in conn['gid_pairs'].values()]) assert gid_pairs_comparison == conn['gid_pairs'] assert num_connections == \ np.around(len(net.gid_ranges[cell_type]) * probability[cell_type]).astype(int) # evoked with pytest.raises(ValueError, match='Standard deviation cannot be negative'): net.add_evoked_drive('evdist1', mu=10, sigma=-1, numspikes=1, location='distal') with pytest.raises(ValueError, match='Number of spikes must be greater than zero'): net.add_evoked_drive('evdist1', mu=10, sigma=1, numspikes=0, location='distal') # Test Network._attach_drive() with pytest.raises(ValueError, match=r'Allowed drive target locations are'): net.add_evoked_drive('evdist1', mu=10, sigma=1, numspikes=1, location='bogus_location') with pytest.raises(ValueError, match='Drive evoked_dist already defined'): net.add_evoked_drive('evoked_dist', mu=10, sigma=1, numspikes=1, location='distal') with pytest.raises(ValueError, match='No target cell types have been given a synaptic ' 'weight'): net.add_evoked_drive('evdist1', mu=10, sigma=1, numspikes=1, location='distal') with pytest.raises(ValueError, match='When adding a distal drive, synaptic weight ' 'cannot be defined for the L5_basket cell type'): net.add_evoked_drive('evdist1', mu=10, sigma=1, numspikes=1, location='distal', weights_ampa={'L5_basket': 1.}, synaptic_delays={'L5_basket': .1}) with pytest.raises(ValueError, match='If cell_specific is True, n_drive_cells'): net.add_evoked_drive('evdist1', mu=10, sigma=1, numspikes=1, location='distal', n_drive_cells=10, cell_specific=True, weights_ampa=weights_ampa, synaptic_delays=syn_delays) with pytest.raises(ValueError, match='If cell_specific is False, n_drive_cells'): net.add_evoked_drive('evdist1', mu=10, sigma=1, numspikes=1, location='distal', n_drive_cells='n_cells', cell_specific=False, weights_ampa=weights_ampa, synaptic_delays=syn_delays) with pytest.raises(ValueError, match='Number of drive cells must be greater than 0'): net.add_evoked_drive('evdist1', mu=10, sigma=1, numspikes=1, location='distal', n_drive_cells=0, cell_specific=False, weights_ampa=weights_ampa, synaptic_delays=syn_delays) # Poisson with pytest.raises(ValueError, match='End time of Poisson drive cannot be negative'): net.add_poisson_drive('poisson1', tstart=0, tstop=-1, location='distal', rate_constant=10.) with pytest.raises(ValueError, match='Start time of Poisson drive cannot be negative'): net.add_poisson_drive('poisson1', tstart=-1, location='distal', rate_constant=10.) with pytest.raises(ValueError, match='Duration of Poisson drive cannot be negative'): net.add_poisson_drive('poisson1', tstart=10, tstop=1, location='distal', rate_constant=10.) with pytest.raises(ValueError, match='Rate constant must be positive'): net.add_poisson_drive('poisson1', location='distal', rate_constant=0., weights_ampa=weights_ampa, synaptic_delays=syn_delays) with pytest.raises(ValueError, match='Rate constants not provided for all target'): net.add_poisson_drive('poisson1', location='distal', rate_constant={'L2_pyramidal': 10.}, weights_ampa=weights_ampa, synaptic_delays=syn_delays) with pytest.raises(ValueError, match='Rate constant provided for unknown target cell'): net.add_poisson_drive('poisson1', location='distal', rate_constant={ 'L2_pyramidal': 10., 'bogus_celltype': 20. }, weights_ampa={ 'L2_pyramidal': .01, 'bogus_celltype': .01 }, synaptic_delays=0.1) with pytest.raises(ValueError, match='Drives specific to cell types are only ' 'possible with cell_specific=True'): net.add_poisson_drive('poisson1', location='distal', rate_constant={ 'L2_basket': 10., 'L2_pyramidal': 11., 'L5_basket': 12., 'L5_pyramidal': 13. }, n_drive_cells=1, cell_specific=False, weights_ampa=weights_ampa, synaptic_delays=syn_delays) # bursty with pytest.raises(ValueError, match='End time of bursty drive cannot be negative'): net.add_bursty_drive('bursty_drive', tstop=-1, location='distal', burst_rate=10) with pytest.raises(ValueError, match='Start time of bursty drive cannot be negative'): net.add_bursty_drive('bursty_drive', tstart=-1, location='distal', burst_rate=10) with pytest.raises(ValueError, match='Duration of bursty drive cannot be negative'): net.add_bursty_drive('bursty_drive', tstart=10, tstop=1, location='distal', burst_rate=10) msg = (r'Burst duration (?s).* cannot be greater than ' 'burst period') with pytest.raises(ValueError, match=msg): net.add_bursty_drive('bursty_drive', location='distal', burst_rate=10, burst_std=20., numspikes=4, spike_isi=50) # attaching drives with pytest.raises(ValueError, match='Drive evoked_dist already defined'): net.add_poisson_drive('evoked_dist', location='distal', rate_constant=10., weights_ampa=weights_ampa, synaptic_delays=syn_delays) with pytest.raises(ValueError, match='Allowed drive target locations are:'): net.add_poisson_drive('weird_poisson', location='inbetween', rate_constant=10., weights_ampa=weights_ampa, synaptic_delays=syn_delays) with pytest.raises(ValueError, match='Allowed drive target cell types are:'): net.add_poisson_drive('cell_unknown', location='proximal', rate_constant=10., weights_ampa={'CA1_pyramidal': 1.}, synaptic_delays=.01) with pytest.raises(ValueError, match='synaptic_delays is either a common float or ' 'needs to be specified as a dict for each of the cell'): net.add_poisson_drive('cell_unknown', location='proximal', rate_constant=10., weights_ampa={'L2_pyramidal': 1.}, synaptic_delays={'L5_pyramidal': 1.}) with pytest.raises(ValueError, match=r'probability must be in the range \(0\,1\)'): net.add_bursty_drive('cell_unknown', location='distal', burst_rate=10, weights_ampa={'L2_pyramidal': 1.}, synaptic_delays={'L2_pyramidal': 1.}, probability=2.0) with pytest.raises(TypeError, match="probability must be an instance of " r"float or dict, got \<class 'str'\> instead"): net.add_bursty_drive('cell_unknown2', location='distal', burst_rate=10, weights_ampa={'L2_pyramidal': 1.}, synaptic_delays={'L2_pyramidal': 1.}, probability='1.0') with pytest.raises(ValueError, match='probability is either a common ' 'float or needs to be specified as a dict for ' 'each of the cell'): net.add_bursty_drive('cell_unknown2', location='distal', burst_rate=10, weights_ampa={'L2_pyramidal': 1.}, synaptic_delays={'L2_pyramidal': 1.}, probability={'L5_pyramidal': 1.}) with pytest.raises(TypeError, match="probability must be an instance of " r"float, got \<class 'str'\> instead"): net.add_bursty_drive('cell_unknown2', location='distal', burst_rate=10, weights_ampa={'L2_pyramidal': 1.}, synaptic_delays={'L2_pyramidal': 1.}, probability={'L2_pyramidal': '1.0'}) with pytest.raises(ValueError, match=r'probability must be in the range \(0\,1\)'): net.add_bursty_drive('cell_unknown3', location='distal', burst_rate=10, weights_ampa={'L2_pyramidal': 1.}, synaptic_delays={'L2_pyramidal': 1.}, probability={'L2_pyramidal': 2.0})