Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 9 additions & 14 deletions models/multimeter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,39 +129,34 @@ nest::multimeter::Parameters_::set( const DictionaryDatum& d, const Buffers_& b,
"to nodes." );
}

double v;
if ( updateValueParam< double >( d, names::interval, v, node ) )
double interval_ms;
if ( updateValueParam< double >( d, names::interval, interval_ms, node ) )
{
if ( Time( Time::ms( v ) ) < Time::get_resolution() )
interval_ = Time( Time::ms( interval_ms ) );
if ( interval_ < Time::get_resolution() )
{
throw BadProperty(
"The sampling interval must be at least as long "
"as the simulation resolution." );
throw BadProperty( "The sampling interval must be at least as long as the simulation resolution." );
}

// see if we can represent interval as multiple of step
interval_ = Time::step( Time( Time::ms( v ) ).get_steps() );
if ( not interval_.is_multiple_of( Time::get_resolution() ) )
{
throw BadProperty(
"The sampling interval must be a multiple of "
"the simulation resolution" );
throw BadProperty( "The sampling interval must be a multiple of the simulation resolution." );
}
}

if ( updateValueParam< double >( d, names::offset, v, node ) )
if ( updateValueParam< double >( d, names::offset, interval_ms, node ) )
{
// if offset is different from the default value (0), it must be at least
// as large as the resolution
if ( v != 0 and Time( Time::ms( v ) ) < Time::get_resolution() )
if ( interval_ms != 0 and Time( Time::ms( interval_ms ) ) < Time::get_resolution() )
{
throw BadProperty(
"The offset for the sampling interval must be at least as long as the "
"simulation resolution." );
}

// see if we can represent offset as multiple of step
offset_ = Time::step( Time( Time::ms( v ) ).get_steps() );
offset_ = Time::step( Time( Time::ms( interval_ms ) ).get_steps() );
if ( not offset_.is_multiple_of( Time::get_resolution() ) )
{
throw BadProperty(
Expand Down
6 changes: 4 additions & 2 deletions models/multimeter.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,12 @@ recordables to have them sampled during simulation.
The sampling interval for recordings (given in ms) can be controlled
using the ``multimeter`` parameter ``interval``. The default value of
1.0 ms can be changed by supplying a new value either in the call to
``Create`` or by using ``SetStatus`` on the model instance.
``Create`` or by using ``SetStatus`` on the model instance. To sample
values at every simulation time step, use

::

nest.SetStatus(mm, {'interval': 0.1})
nest.SetStatus(mm, {'interval': nest.resolution})

The recording interval must be greater than or equal to the
:ref:`simulation resolution <simulation_resolution>`, which defaults
Expand Down Expand Up @@ -121,6 +122,7 @@ record_from
interval
A float (default: 1.0) specifying the interval in ms, at which
data is collected from the nodes, the multimeter is connected to.
Must be a multiple of the resolution.

See also
++++++++
Expand Down
10 changes: 10 additions & 0 deletions testsuite/pytests/test_multimeter.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,13 @@ def test_identical_recording_from_multiple_multimeters(model):

for recordable in recordables:
nptest.assert_array_equal(mm1.events[recordable], mm2.events[recordable])


@pytest.mark.parametrize("interval", [0, 0.05, 0.15])
def test_bad_intervals_detected(interval):
"""
Test that NEST raises BadProperty if interval cannot be represented as multiple of resolution.
"""

with pytest.raises(nest.kernel.NESTError, match="BadProperty"):
nest.Create("multimeter", params={"interval": interval})
Loading