示例#1
0
def parse_expressions(renderer, evaluator, numvalues=10):
    exprs = [([m for m in get_identifiers(l) if len(m)==1], [], l.strip())
             for l in TEST_EXPRESSIONS.split('\n') if l.strip()]
    i, imod = 1, 33
    for varids, funcids, expr in exprs:
        pexpr = renderer.render_expr(expr)
        n = 0
        for _ in xrange(numvalues):
            # assign some random values
            ns = {}
            for v in varids:
                if v in ['n', 'm']:  # integer values
                    ns[v] = i
                else:
                    ns[v] = float(i)/imod
                i = i%imod+1
            r1 = eval(expr.replace('&', ' and ').replace('|', ' or '), ns)
            n += 1
            r2 = evaluator(pexpr, ns)
            try:
                # Use all close because we can introduce small numerical
                # difference through sympy's rearrangements
                assert_allclose(r1, r2, atol=10)
            except AssertionError as e:
                raise AssertionError("In expression " + str(expr) +
                                     " translated to " + str(pexpr) +
                                     " " + str(e))
示例#2
0
def test_function_dependencies_numpy():
    if prefs.codegen.target != 'numpy':
        raise SkipTest('numpy-only test')

    @implementation('cpp', '''
    float foo(float x)
    {
        return 42*0.001;
    }''')
    @check_units(x=volt, result=volt)
    def foo(x):
        return 42*mV

    # Second function with an independent implementation for C++ and an
    # implementation for numpy that makes use of the previous function.

    # Note that we don't need to use the explicit dependencies mechanism for
    # numpy, since the Python function stores a reference to the referenced
    # function directly

    @implementation('cpp', '''
    float bar(float x)
    {
        return 84*0.001;
    }''')
    @check_units(x=volt, result=volt)
    def bar(x):
        return 2*foo(x)

    G = NeuronGroup(5, 'v : volt')
    G.run_regularly('v = bar(v)')
    net = Network(G)
    net.run(defaultclock.dt)

    assert_allclose(G.v_[:], 84*0.001)
示例#3
0
def test_state_monitor_indexing():
    # Check indexing semantics
    G = NeuronGroup(10, 'v:volt')
    G.v = np.arange(10) * volt
    mon = StateMonitor(G, 'v', record=[5, 6, 7])

    run(2 * defaultclock.dt)

    assert_array_equal(mon.v, np.array([[5, 5],
                                  [6, 6],
                                  [7, 7]]) * volt)
    assert_array_equal(mon.v_, np.array([[5, 5],
                                   [6, 6],
                                   [7, 7]]))
    assert_array_equal(mon[5].v, mon.v[0])
    assert_array_equal(mon[7].v, mon.v[2])
    assert_array_equal(mon[[5, 7]].v, mon.v[[0, 2]])
    assert_array_equal(mon[np.array([5, 7])].v, mon.v[[0, 2]])

    assert_allclose(mon.t[1:], Quantity([defaultclock.dt]))

    assert_raises(IndexError, lambda: mon[8])
    assert_raises(TypeError, lambda: mon['string'])
    assert_raises(TypeError, lambda: mon[5.0])
    assert_raises(TypeError, lambda: mon[[5.0, 6.0]])
示例#4
0
def test_function_dependencies_cython():
    if prefs.codegen.target != 'cython':
        raise SkipTest('cython-only test')

    @implementation('cython', '''
    cdef float foo(float x):
        return 42*0.001
    ''')
    @check_units(x=volt, result=volt)
    def foo(x):
        return 42*mV

    # Second function with an independent implementation for numpy and an
    # implementation for C++ that makes use of the previous function.

    @implementation('cython', '''
    cdef float bar(float x):
        return 2*foo(x)
    ''', dependencies={'foo': foo})
    @check_units(x=volt, result=volt)
    def bar(x):
        return 84*mV

    G = NeuronGroup(5, 'v : volt')
    G.run_regularly('v = bar(v)')
    net = Network(G)
    net.run(defaultclock.dt)

    assert_allclose(G.v_[:], 84*0.001)
示例#5
0
def test_inplace_on_scalars():
    # We want "copy semantics" for in-place operations on scalar quantities
    # in the same way as for Python scalars
    for scalar in [3*mV, 3*mV/mV]:
        scalar_reference = scalar
        scalar_copy = Quantity(scalar, copy=True)
        scalar += scalar_copy
        assert_equal(scalar_copy, scalar_reference)
        scalar *= 1.5
        assert_equal(scalar_copy, scalar_reference)
        scalar /= 2
        assert_equal(scalar_copy, scalar_reference)

        # also check that it worked correctly for the scalar itself
        assert_allclose(scalar, (scalar_copy + scalar_copy)*1.5/2)

    # For arrays, it should use reference semantics
    for vector in [[3]*mV, [3]*mV/mV]:
        vector_reference = vector
        vector_copy = Quantity(vector, copy=True)
        vector += vector_copy
        assert_equal(vector, vector_reference)
        vector *= 1.5
        assert_equal(vector, vector_reference)
        vector /= 2
        assert_equal(vector, vector_reference)

        # also check that it worked correctly for the vector itself
        assert_allclose(vector, (vector_copy + vector_copy)*1.5/2)
示例#6
0
def test_math_functions():
    '''
    Test that math functions give the same result, regardless of whether used
    directly or in generated Python or C++ code.
    '''
    default_dt = defaultclock.dt
    test_array = np.array([-1, -0.5, 0, 0.5, 1])
    def int_(x):
        return array(x, dtype=int)
    int_.__name__ = 'int'

    with catch_logs() as _:  # Let's suppress warnings about illegal values
        # Functions with a single argument
        for func in [cos, tan, sinh, cosh, tanh,
                     arcsin, arccos, arctan,
                     log, log10,
                     exp, np.sqrt,
                     np.ceil, np.floor, np.sign, int_]:

            # Calculate the result directly
            numpy_result = func(test_array)

            # Calculate the result in a somewhat complicated way by using a
            # subexpression in a NeuronGroup
            if func.__name__ == 'absolute':
                # we want to use the name abs instead of absolute
                func_name = 'abs'
            else:
                func_name = func.__name__
            G = NeuronGroup(len(test_array),
                            '''func = {func}(variable) : 1
                               variable : 1'''.format(func=func_name))
            G.variable = test_array
            mon = StateMonitor(G, 'func', record=True)
            net = Network(G, mon)
            net.run(default_dt)

            assert_allclose(numpy_result, mon.func_.flatten(),
                            err_msg='Function %s did not return the correct values' % func.__name__)

        # Functions/operators
        scalar = 3
        for func, operator in [(np.power, '**'), (np.mod, '%')]:

            # Calculate the result directly
            numpy_result = func(test_array, scalar)

            # Calculate the result in a somewhat complicated way by using a
            # subexpression in a NeuronGroup
            G = NeuronGroup(len(test_array),
                            '''func = variable {op} scalar : 1
                               variable : 1'''.format(op=operator))
            G.variable = test_array
            mon = StateMonitor(G, 'func', record=True)
            net = Network(G, mon)
            net.run(default_dt)

            assert_allclose(numpy_result, mon.func_.flatten(),
                            err_msg='Function %s did not return the correct values' % func.__name__)
示例#7
0
def test_rate_monitor_2():
    G = NeuronGroup(10, 'v : 1', threshold='v>1') # no reset
    G.v['i<5'] = 1.1  # Half of the neurons fire every time step
    rate_mon = PopulationRateMonitor(G)
    net = Network(G, rate_mon)
    net.run(10*defaultclock.dt)
    assert_allclose(rate_mon.rate, 0.5 * np.ones(10) / defaultclock.dt)
    assert_allclose(rate_mon.rate_, 0.5 *np.asarray(np.ones(10) / defaultclock.dt_))
示例#8
0
def test_timedarray_no_upsampling():
    # Test a TimedArray where no upsampling is necessary because the monitor's
    # dt is bigger than the TimedArray's
    ta = TimedArray(np.arange(10), dt=0.01*ms)
    G = NeuronGroup(1, 'value = ta(t): 1', dt=0.1*ms)
    mon = StateMonitor(G, 'value', record=True, dt=1*ms)
    run(2.1*ms)
    assert_allclose(mon[0].value, [0, 9, 9])
示例#9
0
def assert_quantity(q, values, unit):
    assert isinstance(q, Quantity) or (have_same_dimensions(unit, 1) and
                                       (values.shape == () or
                                        isinstance(q, np.ndarray))), q
    assert_allclose(np.asarray(q), values)
    assert have_same_dimensions(q, unit), ('Dimension mismatch: (%s) (%s)' %
                                           (get_dimensions(q),
                                            get_dimensions(unit)))
示例#10
0
def test_timedarray_semantics():
    # Make sure that timed arrays are interpreted as specifying the values
    # between t and t+dt (not between t-dt/2 and t+dt/2 as in Brian1)
    ta = TimedArray(array([0, 1]), dt=0.4*ms)
    G = NeuronGroup(1, 'value = ta(t) : 1', dt=0.1*ms)
    mon = StateMonitor(G, 'value', record=0)
    run(0.8*ms)
    assert_allclose(mon[0].value, [0, 0, 0, 0, 1, 1, 1, 1])
    assert_allclose(mon[0].value, ta(mon.t))
示例#11
0
def test_rallpack1():
    '''
    Rallpack 1
    '''
    if prefs.core.default_float_dtype is np.float32:
        raise SkipTest('Need double precision for this test')
    defaultclock.dt = 0.05*ms

    # Morphology
    diameter = 1*um
    length = 1*mm
    Cm = 1 * uF / cm ** 2
    Ri = 100 * ohm * cm
    N = 1000
    morpho = Cylinder(diameter=diameter, length=length, n=N)

    # Passive channels
    gL = 1./(40000*ohm*cm**2)
    EL = -65*mV
    eqs = '''
    Im = gL*(EL - v) : amp/meter**2
    I : amp (point current, constant)
    '''
    neuron = SpatialNeuron(morphology=morpho, model=eqs, Cm=Cm, Ri=Ri)
    neuron.v = EL

    neuron.I[0] = 0.1*nA  # injecting at the left end

    #Record at the two ends
    mon = StateMonitor(neuron, 'v', record=[0, 999], when='start', dt=0.05*ms)

    run(250*ms + defaultclock.dt)

    # Load the theoretical results
    basedir = os.path.join(os.path.abspath(os.path.dirname(__file__)),
                           'rallpack_data')
    data_0 = np.loadtxt(os.path.join(basedir, 'ref_cable.0'))
    data_x = np.loadtxt(os.path.join(basedir, 'ref_cable.x'))

    scale_0 = max(data_0[:, 1]*volt) - min(data_0[:, 1]*volt)
    scale_x = max(data_x[:, 1]*volt) - min(data_x[:, 1]*volt)
    squared_diff_0 = (data_0[:, 1] * volt - mon[0].v)**2
    squared_diff_x = (data_x[:, 1] * volt - mon[999].v)**2
    rel_RMS_0 = sqrt(mean(squared_diff_0))/scale_0
    rel_RMS_x = sqrt(mean(squared_diff_x))/scale_x
    max_rel_0 = sqrt(max(squared_diff_0))/scale_0
    max_rel_x = sqrt(max(squared_diff_x))/scale_x

    # sanity check: times are the same
    assert_allclose(mon.t/second, data_0[:, 0])
    assert_allclose(mon.t/second, data_x[:, 0])

    # RMS error should be < 0.1%, maximum error along the curve should be < 0.5%
    assert 100*rel_RMS_0 < 0.1
    assert 100*rel_RMS_x < 0.1
    assert 100*max_rel_0 < 0.5
    assert 100*max_rel_x < 0.5
示例#12
0
def test_constants_values():
    '''
    Make sure that symbolic constants use the correct values in code
    '''
    G = NeuronGroup(3, 'v : 1')
    G.v[0] = 'pi'
    G.v[1] = 'e'
    G.v[2] = 'inf'
    run(0*ms)
    assert_allclose(G.v[:], [np.pi, np.e, np.inf])
示例#13
0
def test_poissoninput_refractory():
    eqs = '''
    dv/dt = 0/second : 1 (unless refractory)
    '''
    G = NeuronGroup(10, eqs, reset='v=0', threshold='v>4.5', refractory=5*defaultclock.dt)
    # Will increase the value by 1.0 at each time step
    P = PoissonInput(G, 'v', 1, 1/defaultclock.dt, weight=1.0)
    mon = StateMonitor(G, 'v', record=5)
    run(10*defaultclock.dt)
    expected = np.arange(10, dtype=np.float)
    expected[6-int(schedule_propagation_offset()/defaultclock.dt):] = 0
    assert_allclose(mon[5].v[:], expected)
示例#14
0
def test_active_flag():
    G = NeuronGroup(1, 'dv/dt = 1/ms : 1')
    mon = StateMonitor(G, 'v', record=0)
    mon.active = False
    run(1*ms)
    mon.active = True
    G.active = False
    run(1*ms)
    device.build(direct_call=False, **device.build_options)
    # Monitor should start recording at 1ms
    # Neurongroup should not integrate after 1ms (but should have integrated before)
    assert_allclose(mon[0].t[0], 1*ms)
    assert_allclose(mon[0].v, 1.0)
示例#15
0
def test_str_repr():
    '''
    Test that str representations do not raise any errors and that repr
    fullfills eval(repr(x)) == x.
    '''
    from numpy import array # necessary for evaluating repr    
    
    units_which_should_exist = [metre, meter, kilogram, kilogramme, second, amp, kelvin, mole, candle,
                                radian, steradian, hertz, newton, pascal, joule, watt,
                                coulomb, volt, farad, ohm, siemens, weber, tesla, henry,
                                lumen, lux, becquerel, gray, sievert, katal,
                                gram, gramme, molar, liter, litre]
    
    # scaled versions of all these units should exist (we just check farad as an example)
    some_scaled_units = [Yfarad, Zfarad, Efarad, Pfarad, Tfarad, Gfarad, Mfarad, kfarad,
                         hfarad, dafarad, dfarad, cfarad, mfarad, ufarad, nfarad, pfarad,
                         ffarad, afarad, zfarad, yfarad]
    
    # some powered units
    powered_units = [cmetre2, Yfarad3]
    
    # Combined units
    complex_units = [(kgram * metre2)/(amp * second3),
                     5 * (kgram * metre2)/(amp * second3),
                     metre * second**-1, 10 * metre * second**-1,
                     array([1, 2, 3]) * kmetre / second,
                     np.ones(3) * nS / cm**2,
                     Unit(1, dim=get_or_create_dimension(length=5, time=2)),
                     8000*umetre**3, [0.0001, 10000] * umetre**3,
                     1/metre, 1/(coulomb*metre**2), Unit(1)/second,
                     3.*mM, 5*mole/liter, 7*liter/meter3]
    
    unitless = [second/second, 5 * second/second, Unit(1)]
    
    for u in itertools.chain(units_which_should_exist, some_scaled_units,
                              powered_units, complex_units, unitless):
        assert(len(str(u)) > 0)
        assert_allclose(eval(repr(u)), u)

    # test the `DIMENSIONLESS` object
    assert str(DIMENSIONLESS) == '1'
    assert repr(DIMENSIONLESS) == 'Dimension()'
    
    # test DimensionMismatchError (only that it works without raising an error
    for error in [DimensionMismatchError('A description'),
                  DimensionMismatchError('A description', DIMENSIONLESS),
                  DimensionMismatchError('A description', DIMENSIONLESS,
                                         second.dim)]:
        assert len(str(error))
        assert len(repr(error))
示例#16
0
def test_state_monitor_record_single_timestep():
    G = NeuronGroup(1, 'dv/dt = -v/(5*ms) : 1')
    G.v = 1
    mon = StateMonitor(G, 'v', record=True)
    # Recording before a run should not work
    assert_raises(TypeError, lambda: mon.record_single_timestep())
    run(0.5*ms)
    mon.record_single_timestep()
    device.build(direct_call=False, **device.build_options)
    assert mon.t[0] == 0*ms
    assert mon[0].v[0] == 1
    assert_allclose(mon.t[-1], 0.5*ms)
    assert len(mon.t) == 6
    assert mon[0].v[-1] == G.v
示例#17
0
def test_spikegenerator_period():
    '''
    Basic test for `SpikeGeneratorGroup`.
    '''
    indices = np.array([3, 2, 1, 1, 2, 3, 3, 2, 1])
    times   = np.array([1, 4, 4, 3, 2, 4, 2, 3, 2]) * ms
    SG = SpikeGeneratorGroup(5, indices, times, period=5*ms)

    s_mon = SpikeMonitor(SG)
    run(10*ms)
    for idx in xrange(5):
        generator_spikes = sorted([(idx, time) for time in times[indices==idx]] + [(idx, time+5*ms) for time in times[indices==idx]])
        recorded_spikes = sorted([(idx, time) for time in s_mon.t[s_mon.i==idx]])
        assert_allclose(generator_spikes, recorded_spikes)
示例#18
0
def test_spikegenerator_extreme_period():
    '''
    Basic test for `SpikeGeneratorGroup`.
    '''
    indices = np.array([0, 1, 2])
    times   = np.array([0, 1, 2]) * ms
    SG = SpikeGeneratorGroup(5, indices, times, period=1e6*second)
    s_mon = SpikeMonitor(SG)
    with catch_logs() as l:
        run(10*ms)

    assert_equal(s_mon.i, np.array([0, 1, 2]))
    assert_allclose(s_mon.t, [0, 1, 2]*ms)
    assert len(l) == 1 and l[0][1].endswith('spikegenerator_long_period')
示例#19
0
def test_long_timedarray():
    '''
    Use a very long timedarray (with a big dt), where the upsampling can lead
    to integer overflow.
    '''
    ta = TimedArray(np.arange(16385), dt=1*second)
    G = NeuronGroup(1, 'value = ta(t) : 1')
    mon = StateMonitor(G, 'value', record=True)
    net = Network(G, mon)
    # We'll start the simulation close to the critical boundary
    # FIXME: setting the time like this does not work for standalone
    net.t_ = float(16384*second - 5*ms)
    net.run(10*ms)
    assert_allclose(mon[0].value[mon.t < 16384*second], 16383)
    assert_allclose(mon[0].value[mon.t >= 16384*second], 16384)
示例#20
0
def test_state_variables_string_indices():
    '''
    Test accessing subgroups with string indices.
    '''
    G = NeuronGroup(10, 'v : volt')
    SG = G[4:9]
    assert len(SG.v['i>3']) == 1

    G.v = np.arange(10) * mV
    assert len(SG.v['v>7.5*mV']) == 1

    # Combined string indexing and assignment
    SG.v['i > 3'] = 'i*10*mV'

    assert_allclose(G.v[:], [0, 1, 2, 3, 4, 5, 6, 7, 40, 9] * mV)
示例#21
0
def test_rate_monitor_1():
    G = NeuronGroup(5, 'v : 1', threshold='v>1') # no reset
    G.v = 1.1 # All neurons spike every time step
    rate_mon = PopulationRateMonitor(G)
    run(10*defaultclock.dt)

    assert_allclose(rate_mon.t, np.arange(10) * defaultclock.dt)
    assert_allclose(rate_mon.t_, np.arange(10) * defaultclock.dt_)
    assert_allclose(rate_mon.rate, np.ones(10) / defaultclock.dt)
    assert_allclose(rate_mon.rate_, np.asarray(np.ones(10) / defaultclock.dt_))
示例#22
0
def test_timedarray_direct_use():
    ta = TimedArray(np.linspace(0, 10, 11), 1*ms)
    assert ta(-1*ms) == 0
    assert ta(5*ms) == 5
    assert ta(10*ms) == 10
    assert ta(15*ms) == 10
    ta = TimedArray(np.linspace(0, 10, 11)*amp, 1*ms)
    assert ta(-1*ms) == 0*amp
    assert ta(5*ms) == 5*amp
    assert ta(10*ms) == 10*amp
    assert ta(15*ms) == 10*amp
    ta2d = TimedArray((np.linspace(0, 11, 12)*amp).reshape(4, 3), 1*ms)
    assert ta2d(-1*ms, 0) == 0*amp
    assert ta2d(0*ms, 0) == 0*amp
    assert ta2d(0*ms, 1) == 1*amp
    assert ta2d(1*ms, 1) == 4*amp
    assert_allclose(ta2d(1*ms, [0, 1, 2]), [3, 4, 5]*amp)
    assert_allclose(ta2d(15*ms, [0, 1, 2]), [9, 10, 11]*amp)
示例#23
0
def test_synapses_state_monitor():
    G = NeuronGroup(2, '')
    S = Synapses(G, G, 'w: siemens')
    S.connect(True)
    S.w = 'j*nS'

    # record from a Synapses object (all synapses connecting to neuron 1)
    synapse_mon = StateMonitor(S, 'w', record=S[:, 1])
    synapse_mon2 = StateMonitor(S, 'w', record=S['j==1'])

    net = Network(G, S, synapse_mon, synapse_mon2)
    net.run(10*ms)
    # Synaptic variables
    assert_allclose(synapse_mon[S[0, 1]].w, 1*nS)
    assert_allclose(synapse_mon.w[1], 1*nS)
    assert_allclose(synapse_mon2[S[0, 1]].w, 1*nS)
    assert_allclose(synapse_mon2[S['i==0 and j==1']].w, 1*nS)
    assert_allclose(synapse_mon2.w[1], 1*nS)
示例#24
0
def test_custom_events():
    # Set (could be moved in a setup)
    EL = -65*mV
    gL = 0.0003*siemens/cm**2
    ev = '''
    Im = gL * (EL - v) : amp/meter**2
    event_time1 : second
    '''
    # Create a three compartments morphology
    morpho = Soma(diameter=10*um)
    morpho.dend1 = Cylinder(n=1, diameter=1*um, length=10*um )
    morpho.dend2 = Cylinder(n=1, diameter=1*um, length=10*um )
    G = SpatialNeuron(morphology=morpho,
                      model=ev,
                      events={'event1': 't>=i*ms and t<i*ms+dt'})
    G.run_on_event('event1', 'event_time1 = 0.1*ms')
    run(0.2*ms)
    # Event has size three now because there are three compartments
    assert_allclose(G.event_time1[:], [0.1, 0, 0]*ms)
示例#25
0
def test_constants():
    import brian2.units.constants as constants
    # Check that the expected names exist and have the correct dimensions
    assert constants.avogadro_constant.dim == (1/mole).dim
    assert constants.boltzmann_constant.dim == (joule/kelvin).dim
    assert constants.electric_constant.dim == (farad/meter).dim
    assert constants.electron_mass.dim == kilogram.dim
    assert constants.elementary_charge.dim == coulomb.dim
    assert constants.faraday_constant.dim == (coulomb/mole).dim
    assert constants.gas_constant.dim == (joule/mole/kelvin).dim
    assert constants.magnetic_constant.dim == (newton/amp2).dim
    assert constants.molar_mass_constant.dim == (kilogram/mole).dim
    assert constants.zero_celsius.dim == kelvin.dim

    # Check the consistency between a few constants
    assert_allclose(constants.gas_constant,
                    constants.avogadro_constant*constants.boltzmann_constant)
    assert_allclose(constants.faraday_constant,
                    constants.avogadro_constant*constants.elementary_charge)
示例#26
0
def test_rate_monitor_subgroups_2():
    G = NeuronGroup(6, '''do_spike : boolean''', threshold='do_spike')
    G.do_spike = [True, False, False, False, True, True]
    rate_all = PopulationRateMonitor(G)
    rate_1 = PopulationRateMonitor(G[:2])
    rate_2 = PopulationRateMonitor(G[2:4])
    rate_3 = PopulationRateMonitor(G[4:])
    run(2*defaultclock.dt)
    assert_allclose(rate_all.rate, 0.5 / defaultclock.dt)
    assert_allclose(rate_1.rate, 0.5 / defaultclock.dt)
    assert_allclose(rate_2.rate, 0*Hz)
    assert_allclose(rate_3.rate, 1 / defaultclock.dt)
示例#27
0
def test_spatialneuron_capacitive_currents():
    if prefs.core.default_float_dtype is np.float32:
        raise SkipTest('Need double precision for this test')
    defaultclock.dt = 0.1*ms
    morpho = Cylinder(x=[0, 10]*cm, diameter=2*238*um, n=200, type='axon')

    El = 10.613* mV
    ENa = 115*mV
    EK = -12*mV
    gl = 0.3*msiemens/cm**2
    gNa0 = 120*msiemens/cm**2
    gK = 36*msiemens/cm**2

    # Typical equations
    eqs = '''
    # The same equations for the whole neuron, but possibly different parameter values
    # distributed transmembrane current
    Im = gl * (El-v) + gNa * m**3 * h * (ENa-v) + gK * n**4 * (EK-v) : amp/meter**2
    I : amp (point current) # applied current
    dm/dt = alpham * (1-m) - betam * m : 1
    dn/dt = alphan * (1-n) - betan * n : 1
    dh/dt = alphah * (1-h) - betah * h : 1
    alpham = (0.1/mV) * (-v+25*mV) / (exp((-v+25*mV) / (10*mV)) - 1)/ms : Hz
    betam = 4 * exp(-v/(18*mV))/ms : Hz
    alphah = 0.07 * exp(-v/(20*mV))/ms : Hz
    betah = 1/(exp((-v+30*mV) / (10*mV)) + 1)/ms : Hz
    alphan = (0.01/mV) * (-v+10*mV) / (exp((-v+10*mV) / (10*mV)) - 1)/ms : Hz
    betan = 0.125*exp(-v/(80*mV))/ms : Hz
    gNa : siemens/meter**2
    '''

    neuron = SpatialNeuron(morphology=morpho, model=eqs, Cm=1*uF/cm**2,
                           Ri=35.4*ohm*cm, method="exponential_euler")
    mon = StateMonitor(neuron, ['Im', 'Ic'], record=True, when='end')
    run(10*ms)
    neuron.I[0] = 1*uA  # current injection at one end
    run(3*ms)
    neuron.I = 0*amp
    run(10*ms)
    device.build(direct_call=False, **device.build_options)
    assert_allclose((mon.Im-mon.Ic).sum(axis=0)/(mA/cm**2), np.zeros(230),
                    atol=1e6)
示例#28
0
def test_infinitecable():
    '''
    Test simulation of an infinite cable vs. theory for current pulse (Green function)
    '''
    BrianLogger.suppress_name('resolution_conflict')

    defaultclock.dt = 0.001*ms

    # Morphology
    diameter = 1*um
    Cm = 1 * uF / cm ** 2
    Ri = 100 * ohm * cm
    N = 500
    morpho=Cylinder(diameter=diameter,length=3*mm,n=N)

    # Passive channels
    gL=1e-4*siemens/cm**2
    eqs='''
    Im=-gL*v : amp/meter**2
    I : amp (point current)
    '''

    neuron = SpatialNeuron(morphology=morpho, model=eqs, Cm=Cm, Ri=Ri)

    # Monitors
    mon=StateMonitor(neuron,'v',record=N/2-20)

    neuron.I[len(neuron)//2]=1*nA # injecting in the middle
    run(0.02*ms)
    neuron.I=0*amp
    run(3*ms)
    t = mon.t
    v = mon[N//2-20].v
    # Theory (incorrect near cable ends)
    x = 20*morpho.length[0]
    la = neuron.space_constant[0]
    taum = Cm/gL # membrane time constant
    theory = 1./(la*Cm*pi*diameter)*sqrt(taum/(4*pi*(t+defaultclock.dt)))*\
                 exp(-(t+defaultclock.dt)/taum-taum/(4*(t+defaultclock.dt))*(x/la)**2)
    theory = theory*1*nA*0.02*ms
    assert_allclose(v[t>0.5*ms],theory[t>0.5*ms], rtol=1e14, atol=1e10) # high error tolerance (not exact because not infinite cable)
示例#29
0
def test_finitecable():
    '''
    Test simulation of short cylinder vs. theory for constant current.
    '''
    if prefs.core.default_float_dtype is np.float32:
        raise SkipTest('Need double precision for this test')
    BrianLogger.suppress_name('resolution_conflict')

    defaultclock.dt = 0.01*ms

    # Morphology
    diameter = 1*um
    length = 300*um
    Cm = 1 * uF / cm ** 2
    Ri = 150 * ohm * cm
    N = 200
    morpho=Cylinder(diameter=diameter,length=length,n=N)

    # Passive channels
    gL=1e-4*siemens/cm**2
    EL=-70*mV
    eqs='''
    Im=gL*(EL-v) : amp/meter**2
    I : amp (point current)
    '''

    neuron = SpatialNeuron(morphology=morpho, model=eqs, Cm=Cm, Ri=Ri)
    neuron.v = EL

    neuron.I[0]=0.02*nA # injecting at the left end

    run(100*ms)

    # Theory
    x = neuron.distance
    v = neuron.v
    la = neuron.space_constant[0]
    ra = la*4*Ri/(pi*diameter**2)
    theory = EL+ra*neuron.I[0]*cosh((length-x)/la)/sinh(length/la)
    assert_allclose(v-EL, theory-EL, rtol=1e12, atol=1e8)
示例#30
0
def test_clip():
    G = NeuronGroup(4, '''
                       clipexpr1 = clip(integer_var1, 0, 1) : integer
                       clipexpr2 = clip(integer_var2, -0.5, 1.5) : integer
                       clipexpr3 = clip(float_var1, 0, 1) : 1
                       clipexpr4 = clip(float_var2, -0.5, 1.5) : 1
                       integer_var1 : integer
                       integer_var2 : integer
                       float_var1 : 1
                       float_var2 : 1
                       ''')
    G.integer_var1 = [0, 1, -1, 2]
    G.integer_var2 = [0, 1, -1, 2]
    G.float_var1 = [0., 1., -1., 2.]
    G.float_var2 = [0., 1., -1., 2.]
    s_mon = StateMonitor(G, ['clipexpr1', 'clipexpr2',
                             'clipexpr3', 'clipexpr4'], record=True)
    run(defaultclock.dt)
    assert_equal(s_mon.clipexpr1.flatten(), [0, 1, 0, 1])
    assert_equal(s_mon.clipexpr2.flatten(), [0, 1, 0, 1])
    assert_allclose(s_mon.clipexpr3.flatten(), [0, 1, 0, 1])
    assert_allclose(s_mon.clipexpr4.flatten(), [0, 1, -0.5, 1.5])
示例#31
0
def test_conditional_write_automatic_and_manual():
    source = NeuronGroup(1, '', threshold='True')  # spiking all the time
    target = NeuronGroup(
        2,
        '''dv/dt = 0/ms : 1 (unless refractory)
                               dw/dt = 0/ms : 1''',
        threshold='t == 0*ms',
        refractory='False')  # only refractory for the first time step
    # Cell is spiking/refractory only in the first time step
    syn = Synapses(source,
                   target,
                   on_pre='''v += 1
                                             w += 1 * int(not_refractory_post)'''
                   )
    syn.connect()
    mon = StateMonitor(target, ['v', 'w'], record=True, when='end')
    run(2 * defaultclock.dt)

    # Synapse should not have been effective in the first time step
    assert_allclose(mon.v[:, 0], 0)
    assert_allclose(mon.v[:, 1], 1)
    assert_allclose(mon.w[:, 0], 0)
    assert_allclose(mon.w[:, 1], 1)
示例#32
0
def test_rate_monitor_subgroups():
    old_dt = defaultclock.dt
    defaultclock.dt = 0.01 * ms
    G = NeuronGroup(4,
                    '''dv/dt = rate : 1
                          rate : Hz''',
                    threshold='v>0.999',
                    reset='v=0')
    G.rate = [100, 200, 400, 800] * Hz
    rate_all = PopulationRateMonitor(G)
    rate_1 = PopulationRateMonitor(G[:2])
    rate_2 = PopulationRateMonitor(G[2:])
    run(1 * second)
    assert_allclose(mean(G.rate_[:]), mean(rate_all.rate_[:]))
    assert_allclose(mean(G.rate_[:2]), mean(rate_1.rate_[:]))
    assert_allclose(mean(G.rate_[2:]), mean(rate_2.rate_[:]))

    defaultclock.dt = old_dt
示例#33
0
def test_refractoriness_variables():
    # Try a string evaluating to a quantity an an explicit boolean
    # condition -- all should do the same thing
    for ref_time in ['5*ms', '(t-lastspike + 1e-3*dt) < 5*ms',
                     'time_since_spike + 1e-3*dt < 5*ms', 'ref_subexpression',
                     '(t-lastspike + 1e-3*dt) <= ref', 'ref', 'ref_no_unit*ms']:
        reinit_and_delete()
        G = NeuronGroup(1, '''
                        dv/dt = 99.999*Hz : 1 (unless refractory)
                        dw/dt = 99.999*Hz : 1
                        ref : second
                        ref_no_unit : 1
                        time_since_spike = (t - lastspike) +1e-3*dt : second
                        ref_subexpression = (t - lastspike + 1e-3*dt) < ref : boolean
                        ''',
                        threshold='v>1', reset='v=0;w=0',
                        refractory=ref_time,
                        dtype={'ref': defaultclock.variables['t'].dtype,
                               'ref_no_unit': defaultclock.variables['t'].dtype,
                               'lastspike': defaultclock.variables['t'].dtype,
                               'time_since_spike': defaultclock.variables['t'].dtype})
        G.ref = 5*ms
        G.ref_no_unit = 5
        # It should take 10ms to reach the threshold, then v should stay at 0
        # for 5ms, while w continues to increase
        mon = StateMonitor(G, ['v', 'w'], record=True, when='end')
        run(20*ms)
        try:
            # No difference before the spike
            assert_allclose(mon[0].v[:timestep(10*ms, defaultclock.dt)],
                            mon[0].w[:timestep(10*ms, defaultclock.dt)])
            # v is not updated during refractoriness
            in_refractoriness = mon[0].v[timestep(10*ms, defaultclock.dt):timestep(15*ms, defaultclock.dt)]
            assert_allclose(in_refractoriness, np.zeros_like(in_refractoriness))
            # w should evolve as before
            assert_allclose(mon[0].w[:timestep(5*ms, defaultclock.dt)],
                         mon[0].w[timestep(10*ms, defaultclock.dt)+1:timestep(15*ms, defaultclock.dt)+1])
            assert np.all(mon[0].w[timestep(10*ms, defaultclock.dt)+1:timestep(15*ms, defaultclock.dt)+1] > 0)
            # After refractoriness, v should increase again
            assert np.all(mon[0].v[timestep(15*ms, defaultclock.dt):timestep(20*ms, defaultclock.dt)] > 0)
        except AssertionError as ex:
            raise
            raise AssertionError('Assertion failed when using %r as refractory argument:\n%s' % (ref_time, ex))
示例#34
0
def test_timedarray_no_units():
    ta = TimedArray(np.arange(10), dt=0.1 * ms)
    G = NeuronGroup(1, 'value = ta(t) + 1: 1', dt=0.1 * ms)
    mon = StateMonitor(G, 'value', record=True, dt=0.1 * ms)
    run(1.1 * ms)
    assert_allclose(mon[0].value_, np.clip(np.arange(len(mon[0].t)), 0, 9) + 1)
def test_CudaSpikeQueue_push_outer_loop2():

    # This test was testing a special case scenario in an old version of
    # CudaSpikeQueue::push(). It is now left here as a sanity check for spike
    # propagation.

    # This test creates a situation where one pre neuron is connected to 2048
    # post neurons, where all synapses have different delays except of the the
    # two synapses with ids 1023 and 1024 (last thread of first loop cycle and
    # first thread of last loop cycle in CudaSpikeQueue::push()), which have
    # the same delay. Additionaly all delay queues have different size when the
    # pre neuron spikes one time. The different delay queue sizes is just a
    # leftover of another test and does not have any effect on this test, but
    # I'll leave it as an example.

    num_blocks = 1
    prefs['devices.cuda_standalone.parallel_blocks'] = num_blocks
    # make sure we don't use less then 1024 threads due to register usage
    prefs['devices.cuda_standalone.cuda_backend.extra_compile_args_nvcc'] += [
        '-maxrregcount=64'
    ]

    threads_per_block = 1024
    neurons_per_block = 2 * threads_per_block
    N = neurons_per_block * num_blocks  # each block gets 2048 synapses to push

    default_dt = defaultclock.dt
    # for the first connection each thread has a different delay per block of
    # postsynatpic neurons
    delays_one_block = arange(neurons_per_block) * default_dt
    delays0 = tile(delays_one_block, num_blocks)
    # for the second connection we want to trigger situation (a), so per block the
    # last thread of first loop and first thread of last loop have the same delay
    delays_one_block[threads_per_block] = delays_one_block[threads_per_block -
                                                           1]
    delays = tile(delays_one_block, num_blocks)

    # inp neuron 0 fires the first (2*threads_per_block) time steps, s.t. all queues
    # have different size after that (first 2048, last 0)
    # inp neuron 1 fires once after that
    indices = zeros(neurons_per_block + 1)
    indices[-1] = 1
    times = arange(neurons_per_block + 1) * default_dt
    inp = SpikeGeneratorGroup(2, indices, times)
    G = NeuronGroup(N, 'v:1', threshold='v>1', reset='v=0')

    S = Synapses(inp, G, 'w:1', on_pre='v+=w')
    S.connect()
    # inp neuron 0 has no effect on target neurons (weight 0)
    S.w['i == 0'] = 0
    # inp neuron 1 makes G neurons spike
    S.w['i == 1'] = 1.1
    # delays from inp neuron 0 are equal to post neuron number j
    S.delay[
        'i == 0'] = '(j % neurons_per_block) * default_dt'  # arange(2048) per block
    # delays from inp neuron 0 are the same except of the delay for the synapse
    # of the thread of the second loop in the spikequeue.push(), which is the
    # same as the previous synapse
    S.delay[
        'i == 1'] = '(j % neurons_per_block) * default_dt'  # arange(2048), but [..., 1023, 1023, 1025, ...]
    S.delay[
        'i == 1 and j % neurons_per_block == threads_per_block'] = '(threads_per_block - 1) * default_dt'

    mon = SpikeMonitor(G)

    # first neurons_per_block time steps we resize queues
    # at time step neurons_per_block + 1 we send a spike that triggeres
    # postsynaptic spikes with delays = arange(neurons_per_block), but [..., 1023, 1023, 1035, ...]
    # then it takes neurons_per_block - 1 time steps for all effects to be applied
    time_steps = 2 * neurons_per_block + 2
    run(time_steps * default_dt)

    assert_allclose(S.delay[0, :], delays0)
    assert_allclose(S.delay[1, :], delays)

    assert_equal(len(mon), N)

    unique_mon_t = unique(mon.t)
    for n in range(time_steps):
        t = n * default_dt
        if n <= neurons_per_block or n == time_steps - 1:
            # no spikes
            assert t not in unique_mon_t
        else:
            try:
                mon_idx = sort(mon.i[mon.t == t])
                # first neuron (idx 0) spikes at time step neurons_per_block + 1
                spiking_neuron_idx = n - (neurons_per_block + 1)
                # neuron indices increment over blocks, get idx starting at 0 per block
                mon_idx_per_block = mod(mon_idx, neurons_per_block)
                assert_array_equal(sort(mon_idx), mon_idx)
                if spiking_neuron_idx == threads_per_block - 1:  # 1023
                    # [1023, 1024, 1023, 1024, ...]
                    expected_indices = tile(
                        [spiking_neuron_idx, spiking_neuron_idx + 1],
                        num_blocks)
                elif spiking_neuron_idx == threads_per_block:  # 1024
                    # []
                    expected_indices = array([])
                else:
                    # [spiking_neuron_idx, spiking_neuron_idx, ...]
                    expected_indices = tile([spiking_neuron_idx], num_blocks)
                assert_equal(mon_idx_per_block, expected_indices)
            except AssertionError:
                print('n =', n)
                print(mon_idx)
                raise
示例#36
0
def test_spatialneuron_morphology_assignment():
    sec = Cylinder(length=50 * um, diameter=10 * um, n=2)
    sec.sec1 = Cylinder(length=50 * um, diameter=10 * um, n=2)
    sec.sec1.sec11 = Cylinder(length=50 * um, diameter=10 * um, n=2)
    sec.sec1.sec12 = Cylinder(length=50 * um, diameter=10 * um, n=2)
    sec.sec2 = Cylinder(length=50 * um, diameter=10 * um, n=2)
    sec.sec2.sec21 = Cylinder(length=50 * um, diameter=10 * um, n=2)
    neuron = SpatialNeuron(sec, 'Im = 0*amp/meter**2 : amp/meter**2')

    neuron.v[sec.sec1.sec11] = 1 * volt
    assert_allclose(neuron.sec1.sec11.v[:], np.ones(2) * volt)
    assert_allclose(neuron.sec1.sec12.v[:], np.zeros(2) * volt)
    assert_allclose(neuron.sec1.main.v[:], np.zeros(2) * volt)
    assert_allclose(neuron.main.v[:], np.zeros(2) * volt)
    assert_allclose(neuron.sec2.v[:], np.zeros(4) * volt)

    neuron.v[sec.sec2[25 * um:]] = 2 * volt
    neuron.v[sec.sec1[:25 * um]] = 3 * volt
    assert_allclose(neuron.main.v[:], np.zeros(2) * volt)
    assert_allclose(neuron.sec2.main.v[:], [0, 2] * volt)
    assert_allclose(neuron.sec2.sec21.v[:], np.zeros(2) * volt)
    assert_allclose(neuron.sec1.main.v[:], [3, 0] * volt)
    assert_allclose(neuron.sec1.sec11.v[:], np.ones(2) * volt)
    assert_allclose(neuron.sec1.sec12.v[:], np.zeros(2) * volt)
示例#37
0
def test_construction_coordinates():
    # Same as test_construction, but uses coordinates instead of lengths to
    # set up everything
    # Note that all coordinates here are relative to the origin of the
    # respective cylinder
    BrianLogger.suppress_name('resolution_conflict')
    morpho = Soma(diameter=30 * um)
    morpho.L = Cylinder(x=[0, 10] * um, diameter=1 * um, n=10)
    morpho.LL = Cylinder(y=[0, 5] * um, diameter=2 * um, n=5)
    morpho.LR = Cylinder(z=[0, 5] * um, diameter=2 * um, n=10)
    morpho.right = Cylinder(x=[0, sqrt(2) * 1.5] * um,
                            y=[0, sqrt(2) * 1.5] * um,
                            diameter=1 * um,
                            n=7)
    morpho.right.nextone = Cylinder(y=[0, sqrt(2)] * um,
                                    z=[0, sqrt(2)] * um,
                                    diameter=1 * um,
                                    n=3)
    gL = 1e-4 * siemens / cm**2
    EL = -70 * mV
    eqs = '''
    Im=gL*(EL-v) : amp/meter**2
    I : meter (point current)
    '''

    # Check units of currents
    with pytest.raises(DimensionMismatchError):
        SpatialNeuron(morphology=morpho, model=eqs)

    eqs = '''
    Im=gL*(EL-v) : amp/meter**2
    '''
    neuron = SpatialNeuron(morphology=morpho,
                           model=eqs,
                           Cm=1 * uF / cm**2,
                           Ri=100 * ohm * cm)

    # Test initialization of values
    neuron.LL.v = EL
    assert_allclose(neuron.L.main.v, 0 * mV)
    assert_allclose(neuron.LL.v, EL)
    neuron.LL[1 * um:3 * um].v = 0 * mV
    assert_allclose(neuron.LL.v, Quantity([EL, 0 * mV, 0 * mV, EL, EL]))
    assert_allclose(neuron.Cm, 1 * uF / cm**2)

    # Test morphological variables
    assert_allclose(neuron.L.main.x, morpho.L.x)
    assert_allclose(neuron.LL.main.x, morpho.LL.x)
    assert_allclose(neuron.right.main.x, morpho.right.x)
    assert_allclose(neuron.L.main.distance, morpho.L.distance)
    # assert_allclose(neuron.L.main.diameter, morpho.L.diameter)
    assert_allclose(neuron.L.main.area, morpho.L.area)
    assert_allclose(neuron.L.main.length, morpho.L.length)

    # Check basic consistency of the flattened representation
    assert all(neuron.diffusion_state_updater._ends[:].flat >=
               neuron.diffusion_state_updater._starts[:].flat)

    # Check that length and distances make sense
    assert_allclose(sum(morpho.L.length), 10 * um)
    assert_allclose(morpho.L.distance, (0.5 + np.arange(10)) * um)
    assert_allclose(sum(morpho.LL.length), 5 * um)
    assert_allclose(morpho.LL.distance, (10 + .5 + np.arange(5)) * um)
    assert_allclose(sum(morpho.LR.length), 5 * um)
    assert_allclose(morpho.LR.distance, (10 + 0.25 + np.arange(10) * 0.5) * um)
    assert_allclose(sum(morpho.right.length), 3 * um)
    assert_allclose(morpho.right.distance, (0.5 + np.arange(7)) * 3. / 7. * um)
    assert_allclose(sum(morpho.right.nextone.length), 2 * um)
    assert_allclose(morpho.right.nextone.distance,
                    3 * um + (0.5 + np.arange(3)) * 2. / 3. * um)
示例#38
0
def test_rall():
    '''
    Test simulation of a cylinder plus two branches, with diameters according to Rall's formula
    '''
    if prefs.core.default_float_dtype is np.float32:
        pytest.skip('Need double precision for this test')
    BrianLogger.suppress_name('resolution_conflict')

    defaultclock.dt = 0.01 * ms

    # Passive channels
    gL = 1e-4 * siemens / cm**2
    EL = -70 * mV

    # Morphology
    diameter = 1 * um
    length = 300 * um
    Cm = 1 * uF / cm**2
    Ri = 150 * ohm * cm
    N = 500
    rm = 1 / (gL * pi * diameter)  # membrane resistance per unit length
    ra = (4 * Ri) / (pi * diameter**2)  # axial resistance per unit length
    la = sqrt(rm / ra)  # space length
    morpho = Cylinder(diameter=diameter, length=length, n=N)
    d1 = 0.5 * um
    L1 = 200 * um
    rm = 1 / (gL * pi * d1)  # membrane resistance per unit length
    ra = (4 * Ri) / (pi * d1**2)  # axial resistance per unit length
    l1 = sqrt(rm / ra)  # space length
    morpho.L = Cylinder(diameter=d1, length=L1, n=N)
    d2 = (diameter**1.5 - d1**1.5)**(1. / 1.5)
    rm = 1 / (gL * pi * d2)  # membrane resistance per unit length
    ra = (4 * Ri) / (pi * d2**2)  # axial resistance per unit length
    l2 = sqrt(rm / ra)  # space length
    L2 = (L1 / l1) * l2
    morpho.R = Cylinder(diameter=d2, length=L2, n=N)

    eqs = '''
    Im=gL*(EL-v) : amp/meter**2
    I : amp (point current)
    '''

    neuron = SpatialNeuron(morphology=morpho, model=eqs, Cm=Cm, Ri=Ri)
    neuron.v = EL

    neuron.I[0] = 0.02 * nA  # injecting at the left end
    run(100 * ms)

    # Check space constant calculation
    assert_allclose(la, neuron.space_constant[0])
    assert_allclose(l1, neuron.L.space_constant[0])
    assert_allclose(l2, neuron.R.space_constant[0])

    # Theory
    x = neuron.main.distance
    ra = la * 4 * Ri / (pi * diameter**2)
    l = length / la + L1 / l1
    theory = EL + ra * neuron.I[0] * cosh(l - x / la) / sinh(l)
    v = neuron.main.v
    assert_allclose(v - EL, theory - EL, rtol=1e12, atol=1e8)
    x = neuron.L.distance
    theory = EL + ra * neuron.I[0] * cosh(l - neuron.main.distance[-1] / la -
                                          (x - neuron.main.distance[-1]) /
                                          l1) / sinh(l)
    v = neuron.L.v
    assert_allclose(v - EL, theory - EL, rtol=1e12, atol=1e8)
    x = neuron.R.distance
    theory = EL + ra * neuron.I[0] * cosh(l - neuron.main.distance[-1] / la -
                                          (x - neuron.main.distance[-1]) /
                                          l2) / sinh(l)
    v = neuron.R.v
    assert_allclose(v - EL, theory - EL, rtol=1e12, atol=1e8)
示例#39
0
def test_spatialneuron_subtree_assignment():
    sec = Cylinder(length=50 * um, diameter=10 * um, n=2)
    sec.sec1 = Cylinder(length=50 * um, diameter=10 * um, n=2)
    sec.sec1.sec11 = Cylinder(length=50 * um, diameter=10 * um, n=2)
    sec.sec1.sec12 = Cylinder(length=50 * um, diameter=10 * um, n=2)
    sec.sec2 = Cylinder(length=50 * um, diameter=10 * um, n=2)
    sec.sec2.sec21 = Cylinder(length=50 * um, diameter=10 * um, n=2)
    neuron = SpatialNeuron(sec, 'Im = 0*amp/meter**2 : amp/meter**2')

    neuron.v = 1 * volt
    assert_allclose(neuron.v[:], np.ones(12) * volt)
    neuron.sec1.v += 1 * volt
    assert_allclose(neuron.main.v[:], np.ones(2) * volt)
    assert_allclose(neuron.sec1.v[:], np.ones(6) * 2 * volt)
    assert_allclose(neuron.sec1.main.v[:], np.ones(2) * 2 * volt)
    assert_allclose(neuron.sec1.sec11.v[:], np.ones(2) * 2 * volt)
    assert_allclose(neuron.sec1.sec12.v[:], np.ones(2) * 2 * volt)
    assert_allclose(neuron.sec2.v[:], np.ones(4) * volt)
    neuron.sec2.v = 5 * volt
    assert_allclose(neuron.sec2.v[:], np.ones(4) * 5 * volt)
    assert_allclose(neuron.sec2.main.v[:], np.ones(2) * 5 * volt)
    assert_allclose(neuron.sec2.sec21.v[:], np.ones(2) * 5 * volt)
示例#40
0
def test_rallpack2():
    '''
    Rallpack 2
    '''
    if prefs.core.default_float_dtype is np.float32:
        pytest.skip('Need double precision for this test')
    defaultclock.dt = 0.1 * ms

    # Morphology
    diameter = 32 * um
    length = 16 * um
    Cm = 1 * uF / cm**2
    Ri = 100 * ohm * cm

    # Construct binary tree according to Rall's formula
    morpho = Cylinder(n=1, diameter=diameter, y=[0, float(length)] * meter)
    endpoints = {morpho}
    for depth in range(1, 10):
        diameter /= 2.**(1. / 3.)
        length /= 2.**(2. / 3.)
        new_endpoints = set()
        for endpoint in endpoints:
            new_L = Cylinder(n=1, diameter=diameter, length=length)
            new_R = Cylinder(n=1, diameter=diameter, length=length)
            new_endpoints.add(new_L)
            new_endpoints.add(new_R)
            endpoint.L = new_L
            endpoint.R = new_R
        endpoints = new_endpoints

    # Passive channels
    gL = 1. / (40000 * ohm * cm**2)
    EL = -65 * mV
    eqs = '''
    Im = gL*(EL - v) : amp/meter**2
    I : amp (point current, constant)
    '''
    neuron = SpatialNeuron(morphology=morpho,
                           model=eqs,
                           Cm=Cm,
                           Ri=Ri,
                           method='rk4')
    neuron.v = EL

    neuron.I[0] = 0.1 * nA  # injecting at the origin

    endpoint_indices = [endpoint.indices[0] for endpoint in endpoints]
    mon = StateMonitor(neuron,
                       'v',
                       record=[0] + endpoint_indices,
                       when='start',
                       dt=0.1 * ms)

    run(250 * ms + defaultclock.dt)

    # Load the theoretical results
    basedir = os.path.join(os.path.abspath(os.path.dirname(__file__)),
                           'rallpack_data')
    # Only use very second time step, since we run with 0.1ms instead of 0.05ms
    data_0 = np.loadtxt(os.path.join(basedir, 'ref_branch.0'))[::2]
    data_x = np.loadtxt(os.path.join(basedir, 'ref_branch.x'))[::2]

    # sanity check: times are the same
    assert_allclose(mon.t / second, data_0[:, 0])
    assert_allclose(mon.t / second, data_x[:, 0])

    # Check that all endpoints are the same:
    for endpoint in endpoints:
        assert_allclose(mon[endpoint].v, mon[endpoint[0]].v)

    scale_0 = max(data_0[:, 1] * volt) - min(data_0[:, 1] * volt)
    scale_x = max(data_x[:, 1] * volt) - min(data_x[:, 1] * volt)
    squared_diff_0 = (data_0[:, 1] * volt - mon[0].v)**2

    # One endpoint
    squared_diff_x = (data_x[:, 1] * volt - mon[endpoint_indices[0]].v)**2
    rel_RMS_0 = sqrt(mean(squared_diff_0)) / scale_0
    rel_RMS_x = sqrt(mean(squared_diff_x)) / scale_x
    max_rel_0 = sqrt(max(squared_diff_0)) / scale_0
    max_rel_x = sqrt(max(squared_diff_x)) / scale_x

    # RMS error should be < 0.25%, maximum error along the curve should be < 0.5%
    assert 100 * rel_RMS_0 < 0.25
    assert 100 * rel_RMS_x < 0.25
    assert 100 * max_rel_0 < 0.5
    assert 100 * max_rel_x < 0.5
示例#41
0
def test_rallpack3():
    '''
    Rallpack 3
    '''
    if prefs.core.default_float_dtype is np.float32:
        pytest.skip('Need double precision for this test')
    defaultclock.dt = 1 * usecond

    # Morphology
    diameter = 1 * um
    length = 1 * mm
    N = 1000
    morpho = Cylinder(diameter=diameter, length=length, n=N)
    # Passive properties
    gl = 1. / (40000 * ohm * cm**2)
    El = -65 * mV
    Cm = 1 * uF / cm**2
    Ri = 100 * ohm * cm
    # Active properties
    ENa = 50 * mV
    EK = -77 * mV
    gNa = 120 * msiemens / cm**2
    gK = 36 * msiemens / cm**2
    eqs = '''
    Im = gl * (El-v) + gNa * m**3 * h * (ENa-v) + gK * n**4 * (EK-v) : amp/meter**2
    dm/dt = alpham * (1-m) - betam * m : 1
    dn/dt = alphan * (1-n) - betan * n : 1
    dh/dt = alphah * (1-h) - betah * h : 1
    v_shifted = v - El : volt
    alpham = (0.1/mV) * (-v_shifted+25*mV) / (exp((-v_shifted+25*mV) / (10*mV)) - 1)/ms : Hz
    betam = 4 * exp(-v_shifted/(18*mV))/ms : Hz
    alphah = 0.07 * exp(-v_shifted/(20*mV))/ms : Hz
    betah = 1/(exp((-v_shifted+30*mV) / (10*mV)) + 1)/ms : Hz
    alphan = (0.01/mV) * (-v_shifted+10*mV) / (exp((-v_shifted+10*mV) / (10*mV)) - 1)/ms : Hz
    betan = 0.125*exp(-v_shifted/(80*mV))/ms : Hz
    I : amp (point current, constant)
    '''
    axon = SpatialNeuron(morphology=morpho,
                         model=eqs,
                         Cm=Cm,
                         Ri=Ri,
                         method='exponential_euler')
    axon.v = El
    # Pre-calculated equilibrium values at v = El
    axon.m = 0.0529324852572
    axon.n = 0.317676914061
    axon.h = 0.596120753508
    axon.I[0] = 0.1 * nA  # injecting at the left end

    #Record at the two ends
    mon = StateMonitor(axon, 'v', record=[0, 999], when='start', dt=0.05 * ms)

    run(250 * ms + defaultclock.dt)

    # Load the theoretical results
    basedir = os.path.join(os.path.abspath(os.path.dirname(__file__)),
                           'rallpack_data')
    data_0 = np.loadtxt(os.path.join(basedir, 'ref_axon.0.neuron'))
    data_x = np.loadtxt(os.path.join(basedir, 'ref_axon.x.neuron'))

    # sanity check: times are the same
    assert_allclose(mon.t / second, data_0[:, 0])
    assert_allclose(mon.t / second, data_x[:, 0])

    scale_0 = max(data_0[:, 1] * volt) - min(data_0[:, 1] * volt)
    scale_x = max(data_x[:, 1] * volt) - min(data_x[:, 1] * volt)
    squared_diff_0 = (data_0[:, 1] * volt - mon[0].v)**2
    squared_diff_x = (data_x[:, 1] * volt - mon[999].v)**2

    rel_RMS_0 = sqrt(mean(squared_diff_0)) / scale_0
    rel_RMS_x = sqrt(mean(squared_diff_x)) / scale_x
    max_rel_0 = sqrt(max(squared_diff_0)) / scale_0
    max_rel_x = sqrt(max(squared_diff_x)) / scale_x

    # RMS error should be < 0.1%, maximum error along the curve should be < 0.5%
    # Note that this is much stricter than the original Rallpack evaluation, but
    # with the 1us time step, the voltage traces are extremely similar
    assert 100 * rel_RMS_0 < 0.1
    assert 100 * rel_RMS_x < 0.1
    assert 100 * max_rel_0 < 0.5
    assert 100 * max_rel_x < 0.5
示例#42
0
def test_scale():
    # Check that unit scaling is implemented correctly
    from brian2.core.namespace import DEFAULT_UNITS
    siprefixes = {
        "y": 1e-24,
        "z": 1e-21,
        "a": 1e-18,
        "f": 1e-15,
        "p": 1e-12,
        "n": 1e-9,
        "u": 1e-6,
        "m": 1e-3,
        "": 1.0,
        "k": 1e3,
        "M": 1e6,
        "G": 1e9,
        "T": 1e12,
        "P": 1e15,
        "E": 1e18,
        "Z": 1e21,
        "Y": 1e24
    }
    for prefix in siprefixes:
        if prefix in ['c', 'd', 'da', 'h']:
            continue
        scaled_unit = DEFAULT_UNITS[prefix + 'meter']
        assert_allclose(float(scaled_unit), siprefixes[prefix])
        assert_allclose(5 * scaled_unit / meter, 5 * siprefixes[prefix])
        scaled_unit = DEFAULT_UNITS[prefix + 'meter2']
        assert_allclose(float(scaled_unit), siprefixes[prefix]**2)
        assert_allclose(5 * scaled_unit / meter2, 5 * siprefixes[prefix]**2)
        scaled_unit = DEFAULT_UNITS[prefix + 'meter3']
        assert_allclose(float(scaled_unit), siprefixes[prefix]**3)
        assert_allclose(5 * scaled_unit / meter3, 5 * siprefixes[prefix]**3)
        # liter, gram, and molar are special, they are not base units with a
        # value of one, even though they do not have any prefix
        for unit, factor in [('liter', 1e-3), ('litre', 1e-3), ('gram', 1e-3),
                             ('gramme', 1e-3), ('molar', 1e3)]:
            base_unit = DEFAULT_UNITS[unit]
            scaled_unit = DEFAULT_UNITS[prefix + unit]
            assert_allclose(float(scaled_unit), siprefixes[prefix] * factor)
            assert_allclose(5 * scaled_unit / base_unit,
                            5 * siprefixes[prefix])
示例#43
0
def test_array_cache():
    # Check that variables are only accessible from Python when they should be
    set_device('cpp_standalone', build_on_run=False)
    G = NeuronGroup(10,
                    '''dv/dt = -v / (10*ms) : 1
                           w : 1
                           x : 1
                           y : 1
                           z : 1 (shared)''',
                    threshold='v>1')
    S = Synapses(G, G, 'weight: 1', on_pre='w += weight')
    S.connect(p=0.2)
    S.weight = 7
    # All neurongroup values should be known
    assert_allclose(G.v, 0)
    assert_allclose(G.w, 0)
    assert_allclose(G.x, 0)
    assert_allclose(G.y, 0)
    assert_allclose(G.z, 0)
    assert_allclose(G.i, np.arange(10))

    # But the synaptic variable is not -- we don't know the number of synapses
    with pytest.raises(NotImplementedError):
        S.weight[:]

    # Setting variables with explicit values should not change anything
    G.v = np.arange(10) + 1
    G.w = 2
    G.y = 5
    G.z = 7
    assert_allclose(G.v, np.arange(10) + 1)
    assert_allclose(G.w, 2)
    assert_allclose(G.y, 5)
    assert_allclose(G.z, 7)

    # But setting with code should invalidate them
    G.x = 'i*2'
    with pytest.raises(NotImplementedError):
        G.x[:]

    # Make sure that the array cache does not allow to use incorrectly sized
    # values to pass
    with pytest.raises(ValueError):
        setattr(G, 'w', [0, 2])
    with pytest.raises(ValueError):
        G.w.__setitem__(slice(0, 4), [0, 2])

    run(10 * ms)
    # v is now no longer known without running the network
    with pytest.raises(NotImplementedError):
        G.v[:]
    # Neither is w, it is updated in the synapse
    with pytest.raises(NotImplementedError):
        G.w[:]
    # However, no code touches y or z
    assert_allclose(G.y, 5)
    assert_allclose(G.z, 7)
    # i is read-only anyway
    assert_allclose(G.i, np.arange(10))

    # After actually running the network, everything should be accessible
    device.build(directory=None, with_output=False)
    assert all(G.v > 0)
    assert all(G.w > 0)
    assert_allclose(G.x, np.arange(10) * 2)
    assert_allclose(G.y, 5)
    assert_allclose(G.z, 7)
    assert_allclose(G.i, np.arange(10))
    assert_allclose(S.weight, 7)
示例#44
0
def test_math_functions():
    '''
    Test that math functions give the same result, regardless of whether used
    directly or in generated Python or C++ code.
    '''
    default_dt = defaultclock.dt
    test_array = np.array([-1, -0.5, 0, 0.5, 1])

    def int_(x):
        return array(x, dtype=int)

    int_.__name__ = 'int'

    with catch_logs() as _:  # Let's suppress warnings about illegal values
        # Functions with a single argument
        for func in [
                cos, tan, sinh, cosh, tanh, arcsin, arccos, arctan, log, log10,
                exp, np.sqrt, np.ceil, np.floor, np.sign, int_
        ]:

            # Calculate the result directly
            numpy_result = func(test_array)

            # Calculate the result in a somewhat complicated way by using a
            # subexpression in a NeuronGroup
            if func.__name__ == 'absolute':
                # we want to use the name abs instead of absolute
                func_name = 'abs'
            else:
                func_name = func.__name__
            G = NeuronGroup(
                len(test_array), '''func = {func}(variable) : 1
                               variable : 1'''.format(func=func_name))
            G.variable = test_array
            mon = StateMonitor(G, 'func', record=True)
            net = Network(G, mon)
            net.run(default_dt)

            assert_allclose(
                numpy_result,
                mon.func_.flatten(),
                err_msg='Function %s did not return the correct values' %
                func.__name__)

        # Functions/operators
        scalar = 3
        for func, operator in [(np.power, '**'), (np.mod, '%')]:

            # Calculate the result directly
            numpy_result = func(test_array, scalar)

            # Calculate the result in a somewhat complicated way by using a
            # subexpression in a NeuronGroup
            G = NeuronGroup(
                len(test_array), '''func = variable {op} scalar : 1
                               variable : 1'''.format(op=operator))
            G.variable = test_array
            mon = StateMonitor(G, 'func', record=True)
            net = Network(G, mon)
            net.run(default_dt)

            assert_allclose(
                numpy_result,
                mon.func_.flatten(),
                err_msg='Function %s did not return the correct values' %
                func.__name__)
示例#45
0
def test_rate_monitor_1():
    G = NeuronGroup(5, 'v : 1', threshold='v>1')  # no reset
    G.v = 1.1  # All neurons spike every time step
    rate_mon = PopulationRateMonitor(G)
    run(10 * defaultclock.dt)

    assert_allclose(rate_mon.t, np.arange(10) * defaultclock.dt)
    assert_allclose(rate_mon.t_, np.arange(10) * defaultclock.dt_)
    assert_allclose(rate_mon.t, np.arange(10) * defaultclock.dt)
    assert_allclose(rate_mon.rate, np.ones(10) / defaultclock.dt)
    assert_allclose(rate_mon.rate_, np.asarray(np.ones(10) / defaultclock.dt_))
    # Check that indexing into the VariableView works (this fails if we do not
    # update the N variable correctly)
    assert_allclose(rate_mon.t[:5], np.arange(5) * defaultclock.dt)
示例#46
0
def test_construction():
    BrianLogger.suppress_name('resolution_conflict')
    morpho = Soma(diameter=30*um)
    morpho.L = Cylinder(length=10*um, diameter=1*um, n=10)
    morpho.LL = Cylinder(length=5*um, diameter=2*um, n=5)
    morpho.LR = Cylinder(length=5*um, diameter=2*um, n=10)
    morpho.right = Cylinder(length=3*um, diameter=1*um, n=7)
    morpho.right.nextone = Cylinder(length=2*um, diameter=1*um, n=3)
    gL=1e-4*siemens/cm**2
    EL=-70*mV
    eqs="""
    Im=gL*(EL-v) : amp/meter**2
    I : meter (point current)
    """

    # Check units of currents
    with pytest.raises(DimensionMismatchError):
        SpatialNeuron(morphology=morpho, model=eqs)

    eqs="""
    Im=gL*(EL-v) : amp/meter**2
    """
    neuron = SpatialNeuron(morphology=morpho, model=eqs, Cm=1 * uF / cm ** 2, Ri=100 * ohm * cm)
    # Test initialization of values
    neuron.LL.v = EL
    assert_allclose(neuron.L.main.v, 0*mV)
    assert_allclose(neuron.LL.v, EL)
    neuron.LL[1*um:3*um].v = 0*mV
    assert_allclose(neuron.LL.v, Quantity([EL, 0*mV, 0*mV, EL, EL]))
    assert_allclose(neuron.Cm, 1 * uF / cm ** 2)

    # Test morphological variables
    assert_allclose(neuron.L.main.distance, morpho.L.distance)
    assert_allclose(neuron.L.main.area, morpho.L.area)
    assert_allclose(neuron.L.main.length, morpho.L.length)

    # Check basic consistency of the flattened representation
    assert all(neuron.diffusion_state_updater._ends[:].flat >=
               neuron.diffusion_state_updater._starts[:].flat)

    # Check that length and distances make sense
    assert_allclose(sum(morpho.L.length), 10*um)
    assert_allclose(morpho.L.distance, (0.5 + np.arange(10))*um)
    assert_allclose(sum(morpho.LL.length), 5*um)
    assert_allclose(morpho.LL.distance, (10 + .5 + np.arange(5))*um)
    assert_allclose(sum(morpho.LR.length), 5*um)
    assert_allclose(morpho.LR.distance, (10 + 0.25 + np.arange(10)*0.5)*um)
    assert_allclose(sum(morpho.right.length), 3*um)
    assert_allclose(morpho.right.distance, (0.5 + np.arange(7))*3./7.*um)
    assert_allclose(sum(morpho.right.nextone.length), 2*um)
    assert_allclose(morpho.right.nextone.distance, 3*um + (0.5 + np.arange(3))*2./3.*um)
示例#47
0
def test_atomics_parallelisation():
    # Adapted from brian2.test_synapses:test_ufunc_at_vectorisation()
    for n, code in enumerate(permutation_analysis_good_examples):
        should_be_able_to_use_ufunc_at = not 'NOT_UFUNC_AT_VECTORISABLE' in code
        if should_be_able_to_use_ufunc_at:
            use_ufunc_at_list = [False, True]
        else:
            use_ufunc_at_list = [True]
        code = deindent(code)
        vars = get_identifiers(code)
        vars_src = []
        vars_tgt = []
        vars_syn = []
        vars_shared = []
        vars_const = {}
        for var in vars:
            if var.endswith('_pre'):
                vars_src.append(var[:-4])
            elif var.endswith('_post'):
                vars_tgt.append(var[:-5])
            elif var.endswith('_syn'):
                vars_syn.append(var[:-4])
            elif var.endswith('_shared'):
                vars_shared.append(var[:-7])
            elif var.endswith('_const'):
                vars_const[var[:-6]] = 42
        eqs_src = '\n'.join(var + ':1' for var in vars_src)
        eqs_tgt = '\n'.join(var + ':1' for var in vars_tgt)
        eqs_syn = '\n'.join(var + ':1' for var in vars_syn)
        eqs_syn += '\n' + '\n'.join(var + ':1 (shared)' for var in vars_shared)
        origvals = {}
        endvals = {}
        group_size = 1000
        syn_size = group_size**2
        try:
            BrianLogger._log_messages.clear()
            with catch_logs(log_level=logging.INFO) as caught_logs:
                for use_ufunc_at in use_ufunc_at_list:
                    set_device('cuda_standalone',
                               directory=None,
                               compile=True,
                               run=True,
                               debug=False)
                    CUDACodeGenerator._use_atomics = use_ufunc_at
                    src = NeuronGroup(group_size,
                                      eqs_src,
                                      threshold='True',
                                      name='src')
                    tgt = NeuronGroup(group_size, eqs_tgt, name='tgt')
                    syn = Synapses(src,
                                   tgt,
                                   eqs_syn,
                                   on_pre=code.replace('_syn', '').replace(
                                       '_const', '').replace('_shared', ''),
                                   name='syn',
                                   namespace=vars_const)
                    syn.connect()
                    for G, vars in [(src, vars_src), (tgt, vars_tgt),
                                    (syn, vars_syn)]:
                        for var in vars:
                            fullvar = var + G.name
                            if fullvar in origvals:
                                G.state(var)[:] = origvals[fullvar]
                            else:
                                if isinstance(G, Synapses):
                                    val = rand(syn_size)
                                else:
                                    val = rand(len(G))
                                G.state(var)[:] = val
                                origvals[fullvar] = val.copy()
                    Network(src, tgt, syn).run(5 * defaultclock.dt)
                    for G, vars in [(src, vars_src), (tgt, vars_tgt),
                                    (syn, vars_syn)]:
                        for var in vars:
                            fullvar = var + G.name
                            val = G.state(var)[:].copy()
                            if fullvar in endvals:
                                assert_allclose(val,
                                                endvals[fullvar],
                                                err_msg='%d: %s' % (n, code),
                                                rtol=1e-5)
                            else:
                                endvals[fullvar] = val
                    device.reinit()
                    device.activate()
                cuda_generator_messages = [
                    l for l in caught_logs
                    if l[1] == 'brian2.codegen.generators.cuda_generator'
                ]
                if should_be_able_to_use_ufunc_at:
                    assert len(
                        cuda_generator_messages) == 0, cuda_generator_messages
                else:
                    assert len(
                        cuda_generator_messages) == 1, cuda_generator_messages
                    log_lev, log_mod, log_msg = cuda_generator_messages[0]
                    assert log_msg.startswith(
                        'Failed to parallelise code'), log_msg
        finally:
            CUDACodeGenerator._use_atomics = False  #restore it
            device.reinit()
            device.activate()
示例#48
0
def test_default_function_implementations():
    ''' Test that all default functions work as expected '''
    # NeuronGroup variables are set in device code
    # Synapses are generated in host code
    # int function arguments use the template code
    # double arguments use the overloaded function

    ### sin
    # Promotes int to float in template device code
    G = NeuronGroup(1, 'v: 1')
    G.v = 'sin(i)'

    # Uses int overloaded C++ function in template host code
    S = Synapses(G, G, 'w: 1')
    S.connect(condition='sin(i)==0')

    # Uses double overloaded func (device code)
    G1 = NeuronGroup(1, 'v: 1')
    G1.v = 'sin(i*1.0)'

    # Uses double overloaded func (host code)
    S1 = Synapses(G, G, 'w: 1')
    S1.connect(condition='sin(i*1.0)==0')

    ### cos
    G2 = NeuronGroup(1, 'v: 1')
    G2.v = 'cos(i)'

    S2 = Synapses(G, G, 'w: 1')
    S2.connect(condition='cos(i)==1')

    G3 = NeuronGroup(1, 'v: 1')
    G3.v = 'cos(i*1.0)'

    S3 = Synapses(G, G, 'w: 1')
    S3.connect(condition='cos(i*1.0)==1')

    ### tan
    G4 = NeuronGroup(1, 'v: 1')
    G4.v = 'tan(i)'

    S4 = Synapses(G, G, 'w: 1')
    S4.connect(condition='tan(i)==0')

    G5 = NeuronGroup(1, 'v: 1')
    G5.v = 'tan(i*1.0)'

    S5 = Synapses(G, G, 'w: 1')
    S5.connect(condition='tan(i*1.0)==0')

    ### sinh
    G6 = NeuronGroup(1, 'v: 1')
    G6.v = 'sinh(i)'

    S6 = Synapses(G, G, 'w: 1')
    S6.connect(condition='sinh(i)==0')

    G7 = NeuronGroup(1, 'v: 1')
    G7.v = 'sinh(i*1.0)'

    S7 = Synapses(G, G, 'w: 1')
    S7.connect(condition='sinh(i*1.0)==0')

    ### cosh
    G8 = NeuronGroup(1, 'v: 1')
    G8.v = 'cosh(i)'

    S8 = Synapses(G, G, 'w: 1')
    S8.connect(condition='cosh(i)==1')

    G9 = NeuronGroup(1, 'v: 1')
    G9.v = 'cosh(i*1.0)'

    S9 = Synapses(G, G, 'w: 1')
    S9.connect(condition='cosh(i*1.0)==1')

    ### tanh
    G10 = NeuronGroup(1, 'v: 1')
    G10.v = 'tanh(i)'

    S10 = Synapses(G, G, 'w: 1')
    S10.connect(condition='tanh(i)==0')

    G11 = NeuronGroup(1, 'v: 1')
    G11.v = 'tanh(i*1.0)'

    S11 = Synapses(G, G, 'w: 1')
    S11.connect(condition='tanh(i*1.0)==0')

    ### exp
    G12 = NeuronGroup(1, 'v: 1')
    G12.v = 'exp(i)'

    S12 = Synapses(G, G, 'w: 1')
    S12.connect(condition='exp(i)==1')

    G13 = NeuronGroup(1, 'v: 1')
    G13.v = 'exp(i*1.0)'

    S13 = Synapses(G, G, 'w: 1')
    S13.connect(condition='exp(i*1.0)==1')

    ### log
    G14 = NeuronGroup(1, 'v: 1')
    G14.v = 'log(i+1)'

    S14 = Synapses(G, G, 'w: 1')
    S14.connect(condition='log(i+1)==0')

    G15 = NeuronGroup(1, 'v: 1')
    G15.v = 'log(i+1.0)'

    S15 = Synapses(G, G, 'w: 1')
    S15.connect(condition='log(i+1.0)==0')

    ### log10
    G16 = NeuronGroup(1, 'v: 1')
    G16.v = 'log10(i+1)'

    S16 = Synapses(G, G, 'w: 1')
    S16.connect(condition='log10(i+1)==0')

    G17 = NeuronGroup(1, 'v: 1')
    G17.v = 'log10(i+1.0)'

    S17 = Synapses(G, G, 'w: 1')
    S17.connect(condition='log10(i+1.0)==0')

    ### sqrt
    G18 = NeuronGroup(1, 'v: 1')
    G18.v = 'sqrt(i)'

    S18 = Synapses(G, G, 'w: 1')
    S18.connect(condition='sqrt(i)==0')

    G19 = NeuronGroup(1, 'v: 1')
    G19.v = 'sqrt(i*1.0)'

    S19 = Synapses(G, G, 'w: 1')
    S19.connect(condition='sqrt(i*1.0)==0')

    ### ceil
    G20 = NeuronGroup(1, 'v: 1')
    G20.v = 'ceil(i)'

    S20 = Synapses(G, G, 'w: 1')
    S20.connect(condition='ceil(i)==0')

    G21 = NeuronGroup(1, 'v: 1')
    G21.v = 'ceil(i*1.0)'

    S21 = Synapses(G, G, 'w: 1')
    S21.connect(condition='ceil(i*1.0)==0')

    ### floor
    G22 = NeuronGroup(1, 'v: 1')
    G22.v = 'floor(i)'

    S22 = Synapses(G, G, 'w: 1')
    S22.connect(condition='floor(i)==0')

    G23 = NeuronGroup(1, 'v: 1')
    G23.v = 'floor(i*1.0)'

    S23 = Synapses(G, G, 'w: 1')
    S23.connect(condition='floor(i*1.0)==0')

    ### arcsin
    G24 = NeuronGroup(1, 'v: 1')
    G24.v = 'arcsin(i)'

    S24 = Synapses(G, G, 'w: 1')
    S24.connect(condition='arcsin(i)==0')

    G25 = NeuronGroup(1, 'v: 1')
    G25.v = 'arcsin(i*1.0)'

    S25 = Synapses(G, G, 'w: 1')
    S25.connect(condition='arcsin(i*1.0)==0')

    ### arccos
    G26 = NeuronGroup(1, 'v: 1')
    G26.v = 'arccos(i+1)'

    S26 = Synapses(G, G, 'w: 1')
    S26.connect(condition='arccos(i+1)==0')

    G27 = NeuronGroup(1, 'v: 1')
    G27.v = 'arccos(i+1.0)'

    S27 = Synapses(G, G, 'w: 1')
    S27.connect(condition='arccos(i+1.0)==0')

    ### arctan
    G28 = NeuronGroup(1, 'v: 1')
    G28.v = 'arctan(i)'

    S28 = Synapses(G, G, 'w: 1')
    S28.connect(condition='arctan(i)==0')

    G29 = NeuronGroup(1, 'v: 1')
    G29.v = 'arctan(i*1.0)'

    S29 = Synapses(G, G, 'w: 1')
    S29.connect(condition='arctan(i*1.0)==0')

    ### abs
    G30 = NeuronGroup(1, 'v: 1')
    G30.v = 'abs(i-1)'

    S30 = Synapses(G, G, 'w: 1')
    S30.connect(condition='abs(i-1)==1')

    G31 = NeuronGroup(1, 'v: 1')
    G31.v = 'abs(i-1.0)'

    S31 = Synapses(G, G, 'w: 1')
    S31.connect(condition='abs(i-1.0)==1')

    ### int
    G32 = NeuronGroup(1, 'v: 1')
    G32.v = 'int(i>0)'

    S32 = Synapses(G, G, 'w: 1')
    S32.connect(condition='int(i>0)==0')

    G33 = NeuronGroup(1, 'v: 1')
    G33.v = 'int(i+0.1)'

    S33 = Synapses(G, G, 'w: 1')
    S33.connect(condition='int(i+0.1)==0')

    ### clip
    G34 = NeuronGroup(1, 'v: 1')
    G34.v = 'clip(i+1,-1,0)'

    S34 = Synapses(G, G, 'w: 1')
    S34.connect(condition='clip(i+1,-1,0)==0')

    G35 = NeuronGroup(1, 'v: 1')
    G35.v = 'clip(i+1,-1.0,0.0)'

    S35 = Synapses(G, G, 'w: 1')
    S35.connect(condition='clip(i+1,-1.0,0.0)==0')

    ### sign
    G36 = NeuronGroup(1, 'v: 1')
    G36.v = 'sign(i+1)'

    S36 = Synapses(G, G, 'w: 1')
    S36.connect(condition='sign(i+1)==1')

    ### timestep
    G38 = NeuronGroup(1, 'v: 1')
    G38.v = 'timestep(0.1*ms, 0.001*ms)'

    S38 = Synapses(G, G, 'w: 1')
    S38.connect(condition='timestep(0.1*ms, 0.001*ms) == 100')

    run(0 * ms)

    assert_allclose([G38.v[0]], [100])
    assert_allclose([S38.N[:]], [1])

    assert_allclose([G36.v[0]], [1])
    assert_allclose([S36.N[:]], [1])

    assert_allclose([G34.v[0], G35.v[0]], [0, 0])
    assert_allclose([S34.N[:], S35.N[:]], [1, 1])

    assert_allclose([G32.v[0], G33.v[0]], [0, 0])
    assert_allclose([S32.N[:], S33.N[:]], [1, 1])

    assert_allclose([G30.v[0], G31.v[0]], [1, 1])
    assert_allclose([S30.N[:], S31.N[:]], [1, 1])

    assert_allclose([G28.v[0], G29.v[0]], [0, 0])
    assert_allclose([S28.N[:], S29.N[:]], [1, 1])

    assert_allclose([G26.v[0], G27.v[0]], [0, 0])
    assert_allclose([S26.N[:], S27.N[:]], [1, 1])

    assert_allclose([G24.v[0], G25.v[0]], [0, 0])
    assert_allclose([S24.N[:], S25.N[:]], [1, 1])

    assert_allclose([G22.v[0], G23.v[0]], [0, 0])
    assert_allclose([S22.N[:], S23.N[:]], [1, 1])

    assert_allclose([G20.v[0], G21.v[0]], [0, 0])
    assert_allclose([S20.N[:], S21.N[:]], [1, 1])

    assert_allclose([G18.v[0], G19.v[0]], [0, 0])
    assert_allclose([S18.N[:], S19.N[:]], [1, 1])

    assert_allclose([G16.v[0], G17.v[0]], [0, 0])
    assert_allclose([S16.N[:], S17.N[:]], [1, 1])

    assert_allclose([G14.v[0], G15.v[0]], [0, 0])
    assert_allclose([S14.N[:], S15.N[:]], [1, 1])

    assert_allclose([G12.v[0], G13.v[0]], [1, 1])
    assert_allclose([S12.N[:], S13.N[:]], [1, 1])

    assert_allclose([G10.v[0], G11.v[0]], [0, 0])
    assert_allclose([S10.N[:], S11.N[:]], [1, 1])

    assert_allclose([G8.v[0], G9.v[0]], [1, 1])
    assert_allclose([S8.N[:], S9.N[:]], [1, 1])

    assert_allclose([G6.v[0], G7.v[0]], [0, 0])
    assert_allclose([S6.N[:], S7.N[:]], [1, 1])

    assert_allclose([G4.v[0], G5.v[0]], [0, 0])
    assert_allclose([S4.N[:], S5.N[:]], [1, 1])

    assert_allclose([G2.v[0], G3.v[0]], [1, 1])
    assert_allclose([S2.N[:], S3.N[:]], [1, 1])

    assert_allclose([G.v[0], G1.v[0]], [0, 0])
    assert_allclose([S.N[:], S1.N[:]], [1, 1])
示例#49
0
def test_binomial_values():

    if prefs.core.default_float_dtype is np.float32:
        # TODO: Make test single-precision compatible, see #262
        pytest.skip('Need double precision for this test')

    # On Denis' local computer this test blows up all available RAM + SWAP when
    # compiling with all threads in parallel. Use half the threads instead.
    import socket
    if socket.gethostname() == 'selene':
        prefs.devices.cpp_standalone.extra_make_args_unix = ['-j4']

    my_f_approximated = BinomialFunction(100, 0.1, approximate=True)
    my_f = BinomialFunction(100, 0.1, approximate=False)

    # Test neurongroup every tick objects
    G = NeuronGroup(10,
                    '''dx/dt = my_f_approximated()/ms: 1
                          dy/dt = my_f()/ms: 1''',
                    threshold='True')
    G.run_regularly('''x = my_f_approximated()
                       y = my_f()''')

    # Test synapses every tick objects (where N is not known at compile time)
    syn = Synapses(
        G,
        G,
        model='''
                         dw/dt = my_f()/ms: 1
                         dv/dt = my_f_approximated()/ms: 1
                         ''',
        on_pre='''
                          x += w
                          y += v
                          '''

        # TODO: fails when having binomial here, why?
        #on_pre='''
        #       x += w * my_f()
        #       y += v * my_f_approximated()
        #       '''
    )
    # Test synapses generation, which needs host side binomial
    syn.connect(condition='my_f_approximated() < 100')

    mon = StateMonitor(G, ['x', 'y'], record=True)
    w_mon = StateMonitor(syn, ['w', 'v'], record=np.arange(100))

    def init_group_variables(my_f, my_f_approximated):
        # Test codeobjects run only once outside the network,
        # G.x uses group_variable_set_conditional, G.x[:5] uses group_variable_set
        # Synapse objects (N not known at compile time)
        syn.w = 'my_f()'
        syn.w['i < j'] = 'my_f_approximated()'
        syn.v = 'my_f_approximated()'
        syn.v['i < j'] = 'my_f()'
        # Neurongroup object
        G.x = 'my_f_approximated()'
        G.x[:5] = 'my_f()'
        G.y = 'my_f()'
        G.y[:5] = 'my_f_approximated()'

    # first run
    init_group_variables(my_f, my_f_approximated)
    run(2 * defaultclock.dt)

    # second run
    seed(11400)
    init_group_variables(my_f, my_f_approximated)
    run(2 * defaultclock.dt)

    # third run
    seed()
    init_group_variables(my_f, my_f_approximated)
    run(2 * defaultclock.dt)

    # forth run
    seed(11400)
    init_group_variables(my_f, my_f_approximated)
    run(2 * defaultclock.dt)

    device.build(direct_call=False, **device.build_options)

    run_values_1 = np.vstack([
        mon.x[:, [0, 1]], mon.y[:, [0, 1]], w_mon.w[:, [0, 1]], w_mon.v[:,
                                                                        [0, 1]]
    ])
    run_values_2 = np.vstack([
        mon.x[:, [2, 3]], mon.y[:, [2, 3]], w_mon.w[:, [2, 3]], w_mon.v[:,
                                                                        [2, 3]]
    ])
    run_values_3 = np.vstack([
        mon.x[:, [4, 5]], mon.y[:, [4, 5]], w_mon.w[:, [4, 5]], w_mon.v[:,
                                                                        [4, 5]]
    ])
    run_values_4 = np.vstack([
        mon.x[:, [6, 7]], mon.y[:, [6, 7]], w_mon.w[:, [6, 7]], w_mon.v[:,
                                                                        [6, 7]]
    ])

    # Two calls to binomial functions should return different numbers in all runs
    for n, values in enumerate(
        [run_values_1, run_values_2, run_values_3, run_values_4]):
        with pytest.raises(AssertionError):
            assert_allclose(values[:, 0], values[:, 1])

    # 2. and 4. run set the same seed
    assert_allclose(run_values_2, run_values_4)
    # all other combinations should be different
    with pytest.raises(AssertionError):
        assert_allclose(run_values_1, run_values_2)
    with pytest.raises(AssertionError):
        assert_allclose(run_values_1, run_values_3)
    with pytest.raises(AssertionError):
        assert_allclose(run_values_2, run_values_3)
示例#50
0
def test_rallpack1():
    '''
    Rallpack 1
    '''
    if prefs.core.default_float_dtype is np.float32:
        pytest.skip('Need double precision for this test')
    defaultclock.dt = 0.05 * ms

    # Morphology
    diameter = 1 * um
    length = 1 * mm
    Cm = 1 * uF / cm**2
    Ri = 100 * ohm * cm
    N = 1000
    morpho = Cylinder(diameter=diameter, length=length, n=N)

    # Passive channels
    gL = 1. / (40000 * ohm * cm**2)
    EL = -65 * mV
    eqs = '''
    Im = gL*(EL - v) : amp/meter**2
    I : amp (point current, constant)
    '''
    neuron = SpatialNeuron(morphology=morpho, model=eqs, Cm=Cm, Ri=Ri)
    neuron.v = EL

    neuron.I[0] = 0.1 * nA  # injecting at the left end

    #Record at the two ends
    mon = StateMonitor(neuron,
                       'v',
                       record=[0, 999],
                       when='start',
                       dt=0.05 * ms)

    run(250 * ms + defaultclock.dt)

    # Load the theoretical results
    basedir = os.path.join(os.path.abspath(os.path.dirname(__file__)),
                           'rallpack_data')
    data_0 = np.loadtxt(os.path.join(basedir, 'ref_cable.0'))
    data_x = np.loadtxt(os.path.join(basedir, 'ref_cable.x'))

    scale_0 = max(data_0[:, 1] * volt) - min(data_0[:, 1] * volt)
    scale_x = max(data_x[:, 1] * volt) - min(data_x[:, 1] * volt)
    squared_diff_0 = (data_0[:, 1] * volt - mon[0].v)**2
    squared_diff_x = (data_x[:, 1] * volt - mon[999].v)**2
    rel_RMS_0 = sqrt(mean(squared_diff_0)) / scale_0
    rel_RMS_x = sqrt(mean(squared_diff_x)) / scale_x
    max_rel_0 = sqrt(max(squared_diff_0)) / scale_0
    max_rel_x = sqrt(max(squared_diff_x)) / scale_x

    # sanity check: times are the same
    assert_allclose(mon.t / second, data_0[:, 0])
    assert_allclose(mon.t / second, data_x[:, 0])

    # RMS error should be < 0.1%, maximum error along the curve should be < 0.5%
    assert 100 * rel_RMS_0 < 0.1
    assert 100 * rel_RMS_x < 0.1
    assert 100 * max_rel_0 < 0.5
    assert 100 * max_rel_x < 0.5
示例#51
0
def test_spike_monitor():
    G = NeuronGroup(3,
                    '''dv/dt = rate : 1
                          rate: Hz''',
                    threshold='v>1',
                    reset='v=0')
    # We don't use 100 and 1000Hz, because then the membrane potential would
    # be exactly at 1 after 10 resp. 100 timesteps. Due to floating point
    # issues this will not be exact,
    G.rate = [101, 0, 1001] * Hz

    mon = SpikeMonitor(G)

    with pytest.raises(ValueError):
        SpikeMonitor(G, order=1)  # need to specify 'when' as well
    # Creating a SpikeMonitor for a Synapses object should not work
    S = Synapses(G, G, on_pre='v += 0')
    S.connect()
    with pytest.raises(TypeError):
        SpikeMonitor(S)

    run(10 * ms)

    spike_trains = mon.spike_trains()

    assert_allclose(mon.t[mon.i == 0], [9.9] * ms)
    assert len(mon.t[mon.i == 1]) == 0
    assert_allclose(mon.t[mon.i == 2], np.arange(10) * ms + 0.9 * ms)
    assert_allclose(mon.t_[mon.i == 0], np.array([9.9 * float(ms)]))
    assert len(mon.t_[mon.i == 1]) == 0
    assert_allclose(mon.t_[mon.i == 2], (np.arange(10) + 0.9) * float(ms))
    assert_allclose(spike_trains[0], [9.9] * ms)
    assert len(spike_trains[1]) == 0
    assert_allclose(spike_trains[2], np.arange(10) * ms + 0.9 * ms)
    assert_array_equal(mon.count, np.array([1, 0, 10]))

    i, t = mon.it
    i_, t_ = mon.it_
    assert_array_equal(i, mon.i)
    assert_array_equal(i, i_)
    assert_array_equal(t, mon.t)
    assert_array_equal(t_, mon.t_)

    with pytest.raises(KeyError):
        spike_trains[3]
    with pytest.raises(KeyError):
        spike_trains[-1]
    with pytest.raises(KeyError):
        spike_trains['string']

    # Check that indexing into the VariableView works (this fails if we do not
    # update the N variable correctly)
    assert_allclose(mon.t[:5], [0.9, 1.9, 2.9, 3.9, 4.9] * ms)
示例#52
0
def test_openmp_consistency():
    previous_device = get_device()
    n_cells = 100
    n_recorded = 10
    numpy.random.seed(42)
    taum = 20 * ms
    taus = 5 * ms
    Vt = -50 * mV
    Vr = -60 * mV
    El = -49 * mV
    fac = (60 * 0.27 / 10)
    gmax = 20 * fac
    dApre = .01
    taupre = 20 * ms
    taupost = taupre
    dApost = -dApre * taupre / taupost * 1.05
    dApost *= 0.1 * gmax
    dApre *= 0.1 * gmax

    connectivity = numpy.random.randn(n_cells, n_cells)
    sources = numpy.random.randint(0, n_cells - 1, 10 * n_cells)
    # Only use one spike per time step (to rule out that a single source neuron
    # has more than one spike in a time step)
    times = numpy.random.choice(
        numpy.arange(10 * n_cells), 10 * n_cells, replace=False) * ms
    v_init = Vr + numpy.random.rand(n_cells) * (Vt - Vr)

    eqs = Equations('''
    dv/dt = (g-(v-El))/taum : volt
    dg/dt = -g/taus         : volt
    ''')

    results = {}

    for (n_threads,
         devicename) in [(0, 'runtime'), (0, 'cpp_standalone'),
                         (1, 'cpp_standalone'), (2, 'cpp_standalone'),
                         (3, 'cpp_standalone'), (4, 'cpp_standalone')]:
        set_device(devicename, build_on_run=False, with_output=False)
        Synapses.__instances__().clear()
        if devicename == 'cpp_standalone':
            reinit_and_delete()
        prefs.devices.cpp_standalone.openmp_threads = n_threads
        P = NeuronGroup(n_cells,
                        model=eqs,
                        threshold='v>Vt',
                        reset='v=Vr',
                        refractory=5 * ms)
        Q = SpikeGeneratorGroup(n_cells, sources, times)
        P.v = v_init
        P.g = 0 * mV
        S = Synapses(P,
                     P,
                     model='''dApre/dt=-Apre/taupre    : 1 (event-driven)    
                                       dApost/dt=-Apost/taupost : 1 (event-driven)
                                       w                        : 1''',
                     pre='''g     += w*mV
                                     Apre  += dApre
                                     w      = w + Apost''',
                     post='''Apost += dApost
                                      w      = w + Apre''')
        S.connect()

        S.w = fac * connectivity.flatten()

        T = Synapses(Q, P, model="w : 1", on_pre="g += w*mV")
        T.connect(j='i')
        T.w = 10 * fac

        spike_mon = SpikeMonitor(P)
        rate_mon = PopulationRateMonitor(P)
        state_mon = StateMonitor(S,
                                 'w',
                                 record=np.arange(n_recorded),
                                 dt=0.1 * second)
        v_mon = StateMonitor(P, 'v', record=np.arange(n_recorded))

        run(0.2 * second, report='text')

        if devicename == 'cpp_standalone':
            device.build(directory=None, with_output=False)

        results[n_threads, devicename] = {}
        results[n_threads, devicename]['w'] = state_mon.w
        results[n_threads, devicename]['v'] = v_mon.v
        results[n_threads, devicename]['s'] = spike_mon.num_spikes
        results[n_threads, devicename]['r'] = rate_mon.rate[:]

    for key1, key2 in [((0, 'runtime'), (0, 'cpp_standalone')),
                       ((1, 'cpp_standalone'), (0, 'cpp_standalone')),
                       ((2, 'cpp_standalone'), (0, 'cpp_standalone')),
                       ((3, 'cpp_standalone'), (0, 'cpp_standalone')),
                       ((4, 'cpp_standalone'), (0, 'cpp_standalone'))]:
        assert_allclose(results[key1]['w'], results[key2]['w'])
        assert_allclose(results[key1]['v'], results[key2]['v'])
        assert_allclose(results[key1]['r'], results[key2]['r'])
        assert_allclose(results[key1]['s'], results[key2]['s'])
    reset_device(previous_device)
示例#53
0
def test_state_variables():
    '''
    Test the setting and accessing of state variables in subgroups.
    '''
    G = NeuronGroup(10, 'v : volt')
    SG = G[4:9]
    with pytest.raises(DimensionMismatchError):
        SG.__setattr__('v', -70)
    SG.v_ = float(-80 * mV)
    assert_allclose(G.v,
                    np.array([0, 0, 0, 0, -80, -80, -80, -80, -80, 0]) * mV)
    assert_allclose(SG.v, np.array([-80, -80, -80, -80, -80]) * mV)
    assert_allclose(
        G.v_,
        np.array([0, 0, 0, 0, -80, -80, -80, -80, -80, 0]) * float(mV))
    assert_allclose(SG.v_, np.array([-80, -80, -80, -80, -80]) * float(mV))
    # You should also be able to set variables with a string
    SG.v = 'v + i*mV'
    assert_allclose(SG.v[0], -80 * mV)
    assert_allclose(SG.v[4], -76 * mV)
    assert_allclose(G.v[4:9], -80 * mV + np.arange(5) * mV)

    # Calculating with state variables should work too
    assert all(G.v[4:9] - SG.v == 0)

    # And in-place modification should work as well
    SG.v += 10 * mV
    assert_allclose(G.v[4:9], -70 * mV + np.arange(5) * mV)
    SG.v *= 2
    assert_allclose(G.v[4:9], 2 * (-70 * mV + np.arange(5) * mV))
    # with unit checking
    with pytest.raises(DimensionMismatchError):
        SG.v.__iadd__(3 * second)
    with pytest.raises(DimensionMismatchError):
        SG.v.__iadd__(3)
    with pytest.raises(DimensionMismatchError):
        SG.v.__imul__(3 * second)

    # Indexing with subgroups
    assert_equal(G.v[SG], SG.v[:])
示例#54
0
def test_spike_monitor_subgroups():
    G = NeuronGroup(6, '''do_spike : boolean''', threshold='do_spike')
    G.do_spike = [True, False, False, False, True, True]
    spikes_all = SpikeMonitor(G)
    spikes_1 = SpikeMonitor(G[:2])
    spikes_2 = SpikeMonitor(G[2:4])
    spikes_3 = SpikeMonitor(G[4:])
    run(defaultclock.dt)
    assert_allclose(spikes_all.i, [0, 4, 5])
    assert_allclose(spikes_all.t, [0, 0, 0] * ms)
    assert_allclose(spikes_1.i, [0])
    assert_allclose(spikes_1.t, [0] * ms)
    assert len(spikes_2.i) == 0
    assert len(spikes_2.t) == 0
    assert_allclose(spikes_3.i, [0, 1])  # recorded spike indices are relative
    assert_allclose(spikes_3.t, [0, 0] * ms)
示例#55
0
def test_time_after_run():
    set_device('cpp_standalone', build_on_run=False)
    # Check that the clock and network time after a run is correct, even if we
    # have not actually run the code yet (via build)
    G = NeuronGroup(10, 'dv/dt = -v/(10*ms) : 1')
    net = Network(G)
    assert_allclose(defaultclock.dt, 0.1 * ms)
    assert_allclose(defaultclock.t, 0. * ms)
    assert_allclose(G.t, 0. * ms)
    assert_allclose(net.t, 0. * ms)
    net.run(10 * ms)
    assert_allclose(defaultclock.t, 10. * ms)
    assert_allclose(G.t, 10. * ms)
    assert_allclose(net.t, 10. * ms)
    net.run(10 * ms)
    assert_allclose(defaultclock.t, 20. * ms)
    assert_allclose(G.t, 20. * ms)
    assert_allclose(net.t, 20. * ms)
    device.build(directory=None, with_output=False)
    # Everything should of course still be accessible
    assert_allclose(defaultclock.t, 20. * ms)
    assert_allclose(G.t, 20. * ms)
    assert_allclose(net.t, 20. * ms)

    reset_device()
示例#56
0
def test_event_monitor():
    G = NeuronGroup(3,
                    '''dv/dt = rate : 1
                          rate: Hz''',
                    events={'my_event': 'v>1'})
    G.run_on_event('my_event', 'v=0')
    # We don't use 100 and 1000Hz, because then the membrane potential would
    # be exactly at 1 after 10 resp. 100 timesteps. Due to floating point
    # issues this will not be exact,
    G.rate = [101, 0, 1001] * Hz

    mon = EventMonitor(G, 'my_event')
    net = Network(G, mon)
    net.run(10 * ms)

    event_trains = mon.event_trains()

    assert_allclose(mon.t[mon.i == 0], [9.9] * ms)
    assert len(mon.t[mon.i == 1]) == 0
    assert_allclose(mon.t[mon.i == 2], np.arange(10) * ms + 0.9 * ms)
    assert_allclose(mon.t_[mon.i == 0], np.array([9.9 * float(ms)]))
    assert len(mon.t_[mon.i == 1]) == 0
    assert_allclose(mon.t_[mon.i == 2], (np.arange(10) + 0.9) * float(ms))
    assert_allclose(event_trains[0], [9.9] * ms)
    assert len(event_trains[1]) == 0
    assert_allclose(event_trains[2], np.arange(10) * ms + 0.9 * ms)
    assert_array_equal(mon.count, np.array([1, 0, 10]))

    i, t = mon.it
    i_, t_ = mon.it_
    assert_array_equal(i, mon.i)
    assert_array_equal(i, i_)
    assert_array_equal(t, mon.t)
    assert_array_equal(t_, mon.t_)

    with pytest.raises(KeyError):
        event_trains[3]
    with pytest.raises(KeyError):
        event_trains[-1]
    with pytest.raises(KeyError):
        event_trains['string']
示例#57
0
def test_storing_loading():
    set_device('cpp_standalone', build_on_run=False)
    G = NeuronGroup(
        10, '''v : volt
                           x : 1
                           n : integer
                           b : boolean''')
    v = np.arange(10) * volt
    x = np.arange(10, 20)
    n = np.arange(20, 30)
    b = np.array([True, False]).repeat(5)
    G.v = v
    G.x = x
    G.n = n
    G.b = b
    S = Synapses(
        G, G, '''v_syn : volt
                          x_syn : 1
                          n_syn : integer
                          b_syn : boolean''')
    S.connect(j='i')
    S.v_syn = v
    S.x_syn = x
    S.n_syn = n
    S.b_syn = b
    run(0 * ms)
    device.build(directory=None, with_output=False)
    assert_allclose(G.v[:], v)
    assert_allclose(S.v_syn[:], v)
    assert_allclose(G.x[:], x)
    assert_allclose(S.x_syn[:], x)
    assert_allclose(G.n[:], n)
    assert_allclose(S.n_syn[:], n)
    assert_allclose(G.b[:], b)
    assert_allclose(S.b_syn[:], b)
    reset_device()
示例#58
0
def test_state_monitor():
    # Unique name to get the warning even for repeated runs of the test
    unique_name = 'neurongroup_' + str(uuid.uuid4()).replace('-', '_')
    # Check that all kinds of variables can be recorded
    G = NeuronGroup(2,
                    '''dv/dt = -v / (10*ms) : 1
                          f = clip(v, 0.1, 0.9) : 1
                          rate: Hz''',
                    threshold='v>1',
                    reset='v=0',
                    refractory=2 * ms,
                    name=unique_name)
    G.rate = [100, 1000] * Hz
    G.v = 1

    S = Synapses(G, G, 'w: siemens')
    S.connect(True)
    S.w = 'j*nS'

    # A bit peculiar, but in principle one should be allowed to record
    # nothing except for the time
    nothing_mon = StateMonitor(G, [], record=True)
    no_record = StateMonitor(G, 'v', record=False)

    # Use a single StateMonitor
    v_mon = StateMonitor(G, 'v', record=True)
    v_mon1 = StateMonitor(G, 'v', record=[1])

    # Use a StateMonitor for specified variables
    multi_mon = StateMonitor(G, ['v', 'f', 'rate'], record=True)
    multi_mon1 = StateMonitor(G, ['v', 'f', 'rate'], record=[1])

    # Use a StateMonitor recording everything
    all_mon = StateMonitor(G, True, record=True)

    # Record synapses with explicit indices (the only way allowed in standalone)
    synapse_mon = StateMonitor(S, 'w', record=np.arange(len(G)**2))

    run(10 * ms)

    # Check time recordings
    assert_array_equal(nothing_mon.t, v_mon.t)
    assert_array_equal(nothing_mon.t_, np.asarray(nothing_mon.t))
    assert_array_equal(nothing_mon.t_, v_mon.t_)
    assert_allclose(nothing_mon.t,
                    np.arange(len(nothing_mon.t)) * defaultclock.dt)
    assert_array_equal(no_record.t, v_mon.t)

    # Check v recording
    assert_allclose(v_mon.v.T, np.exp(np.tile(-v_mon.t, (2, 1)).T / (10 * ms)))
    assert_allclose(v_mon.v_.T,
                    np.exp(np.tile(-v_mon.t_, (2, 1)).T / float(10 * ms)))
    assert_array_equal(v_mon.v, multi_mon.v)
    assert_array_equal(v_mon.v_, multi_mon.v_)
    assert_array_equal(v_mon.v, all_mon.v)
    assert_array_equal(v_mon.v[1:2], v_mon1.v)
    assert_array_equal(multi_mon.v[1:2], multi_mon1.v)
    assert len(no_record.v) == 0

    # Other variables
    assert_array_equal(
        multi_mon.rate_.T,
        np.tile(np.atleast_2d(G.rate_), (multi_mon.rate.shape[1], 1)))
    assert_array_equal(multi_mon.rate[1:2], multi_mon1.rate)
    assert_allclose(np.clip(multi_mon.v, 0.1, 0.9), multi_mon.f)
    assert_allclose(np.clip(multi_mon1.v, 0.1, 0.9), multi_mon1.f)

    assert all(all_mon[0].not_refractory[:] == True), (
        'not_refractory should '
        'be True, but got'
        '(not_refractory, v):'
        '%s ' % str((all_mon.not_refractory, all_mon.v)))

    # Synapses
    assert_allclose(synapse_mon.w[:],
                    np.tile(S.j[:] * nS, (synapse_mon.w[:].shape[1], 1)).T)