Example #1
0
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
Example #2
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)
Example #3
0
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.})
Example #4
0
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})