def test_linear_interpolation_ct(self): '''Test linear interpolation of a simple CT signal. ''' inp = [Event(value = i, tag = i) for i in xrange(-10, 11, 2)] expected_outputs = [Event(tag = t, value = t ) for t in xrange(-10, 11, 1)] block = InterpolatorLinear(self.q_in, self.q_out) SisoTestHelper(self, block, inp, expected_outputs)
def test_delayed_summer2(self): ''' Test adding two channels where one is delayed by an arbitrary time step difference. Summer is set up to discard incomplete sets ''' DELAY = 2 q_in_1 = Channel('DT') q_in_2 = Channel('DT') q_out = Channel('DT') input1 = [Event(value=1, tag=i) for i in xrange(100)] input2 = [Event(value=2, tag=i + DELAY) for i in xrange(100)] summer = DTSummer([q_in_1, q_in_2], q_out, True) summer.start() for val in input1: q_in_1.put(val) for val in input2: q_in_2.put(val) q_in_1.put(LastEvent()) q_in_2.put(LastEvent()) summer.join() for i in xrange(DELAY, 100): self.assertEquals(q_out.get()['value'], 3) self.assertTrue(q_out.get().last)
def test_complex_delay(self): '''Test delaying a CT signal''' delay = 11.5 # Delay by this amount simulation_time = 120 # seconds to simulate resolution = 10.0 # samples per second (10hz) tags = linspace(0, simulation_time, simulation_time / resolution) values = arange(len(tags)) data_in = [ Event(value=values[i], tag=tags[i]) for i in xrange(len(tags)) ] expected_output = [ Event(value=values[i], tag=tags[i] + delay) for i in xrange(len(tags)) ] block = Delay(self.q_in, self.q_out, delay) block.start() [self.q_in.put(i) for i in data_in + [LastEvent()]] block.join() actual_output = [self.q_out.get() for i in xrange(len(tags))] [ self.assertEquals(actual_output[i], expected_output[i]) for i in xrange(len(tags)) ] self.assertTrue(self.q_out.get().last)
def test_multi_delayed_summer(self): ''' Test adding multiple (50) input signals where one signal is delayed. ''' DELAY = 20 num_input_channels, num_data_points = 50, 100 input_channels = [Channel('DT') for i in xrange(num_input_channels)] output_channel = Channel('DT') # Fill each channel with num_data_points of its own index # So channel 5 will be full of the value 4, then a terminal event for i, input_channel in enumerate(input_channels): [ input_channel.put(Event(value=i, tag=j)) for j in xrange(num_data_points) if i is not 0 ] [ input_channels[0].put(Event(value=0, tag=j + DELAY)) for j in xrange(num_data_points) ] [input_channel.put(LastEvent()) for input_channel in input_channels] summer = Summer(input_channels, output_channel) summer.start() summer.join() s = sum(xrange(num_input_channels)) for i in xrange(num_data_points - DELAY): self.assertEquals(output_channel.get()['value'], s) self.assertTrue(output_channel.get().last)
def test_ct_summer_with_different_rates(self): ''' Test adding two channels where one is operates at a different rate than the other. The sum should appear at the fastest rate, with values that assume constant-interpolation between events in the slower channel. ''' DELAY = 2 q_in_1 = Channel('CT') q_in_2 = Channel('CT') q_out = Channel('CT') input1 = [Event(value=i, tag=i) for i in xrange(1, 100)] input2 = [Event(value=2 * i, tag=2 * i) for i in xrange(1, 50)] summer = Summer([q_in_1, q_in_2], q_out) summer.start() for val in input1: q_in_1.put(val) for val in input2: q_in_2.put(val) q_in_1.put(LastEvent()) q_in_2.put(LastEvent()) summer.join() self.assertEquals(q_out.get()['value'], 1.0) for i in xrange(2, 98, 2): self.assertEquals(q_out.get()['value'], i + i) self.assertEquals(q_out.get()['value'], i + i + 1) self.assertEquals(q_out.get()['value'], 196) self.assertTrue(q_out.get().last)
def setUp(self): '''General set up that will be used in all tests''' self.data_in = Channel() self.alt_data_in = Channel() self.bool_in = Channel() self.output = Channel() # Some fake boolean data self.every_second_point = [True, False] * 50 # some fake pass through data, and add it to the channel self.data = range(100) self.data_alt = 10 * self.data [ self.alt_data_in.put(Event(tag=i, value=self.data_alt[i])) for i in range(100) ] [self.data_in.put(Event(tag=i, value=i)) for i in range(100)] self.data_in.put(LastEvent()) self.alt_data_in.put(LastEvent()) # create the block self.block = PassThrough(self.bool_in, self.data_in, self.output, else_data_input=self.alt_data_in)
def test_alternating_merge(self): ''' Test merging two channels with out-of-sync tags. ''' q_in_1 = Channel() q_in_2 = Channel() q_out = Channel() input1 = [Event(value=1, tag=2.0*i) for i in xrange(100)] + [LastEvent()] input2 = [Event(value=2, tag=2.0*i + 1.0) for i in xrange(100)] + [LastEvent()] merge = Merge([q_in_1, q_in_2], q_out) merge.start() for val in input1: q_in_1.put(val) for val in input2: q_in_2.put(val) merge.join() for i in xrange(99): self.assertEquals(q_out.get().value, 1) self.assertEquals(q_out.get().value, 2) # The termination event from channel 1 will cause the # last value event from channel 2 to be lost self.assertEquals(q_out.get().value, 1) self.assertTrue(q_out.get().last) self.assertTrue(q_out.get().last)
def test_different_rate(self): '''Test that integration of a simple positive constant signal doesn't change with samplerate. ''' from scipy import arange inp_1 = [Event(value = 10, tag = i) for i in arange(0, 10, 1)] inp_2 = [Event(value = 10, tag = i) for i in arange(0, 10, 0.1)] expected_output_values_1 = [10 * i for i in arange(0, 10, 1)] expected_output_values_2 = [10 * i for i in arange(0, 10, 0.1)] for Block in [CTIntegratorForwardEuler]: q_in1, q_out1, q_in2, q_out2 = Channel(), Channel(), Channel(), Channel() block1 = Block(q_in1, q_out1) block2 = Block(q_in2, q_out2) block1.start(); block2.start() [q_in1.put(val) for val in inp_1] [q_in2.put(val) for val in inp_2] q_in1.put(LastEvent()); q_in2.put(LastEvent()) block1.join(); block2.join() out = [] for expected_output in expected_output_values_1: out.append(q_out1.get()) out = [item.value for item in out] self.assertEquals(len(out), len(expected_output_values_1)) #[self.assertEquals(out[i], expected_output[i]) for i, _ in enumerate(expected_output_values_1)] self.assertTrue(q_out1.get().last) for expected_output in expected_output_values_2: out = q_out2.get() self.assertAlmostEquals(out.value, expected_output) self.assertTrue(q_out2.get().last)
def test_compatible_signals(self): '''Test reducing the frequency of a more complicated signal. Create a signal of 120 seconds, with 10 samples per second. (10hz) Down-sample this to a 2hz signal. ''' simulation_time = 120 # seconds to simulate resolution = 10.0 # samples per second (10hz) desired_resolution = 2 # what we want out - (2hz) # Create tags for a signal from 0 to 120 seconds. # length = number of seconds * ( samples per second + 1) freq = simulation_time * resolution tags = linspace(0, simulation_time, (freq) + 1) # Create 120 seconds of a discrete time signal with a 10hz frequency inp = [Event(value=1, tag=i) for i in tags] step = resolution / desired_resolution expected_output = [Event(value=1, tag=i) for i in tags[::step]] down_sampler = Sampler(self.q_in, self.q_out, desired_resolution) down_sampler.start() [self.q_in.put(val) for val in inp] self.q_in.put(LastEvent()) down_sampler.join() for expected_output_element in expected_output: out = self.q_out.get() self.assertEquals(out.value, expected_output_element.value) self.assertEquals(out.tag, expected_output_element.tag) self.assertTrue(self.q_out.get().last)
def test_step_interpolation_ct(self): '''Test step interpolation of a simple CT signal. ''' inp = [Event(value = i, tag = i) for i in xrange(-10, 11, 2)] expected_outputs = [Event(tag = t, value = t if not (t % 2) else t - 1 ) for t in xrange(-10, 11, 1)] block = InterpolatorStep(self.q_in, self.q_out) SisoTestHelper(self, block, inp, expected_outputs)
def test_boolean_output(self): '''Test thresholding a signal into a binary signal''' inp = [Event(value=i, tag=i) for i in xrange(0, 100, 1)] expected_outputs = [ Event(value=True if i.value >= 50 else False, tag=i.tag) for i in inp ] block = GreaterThan(self.q_in, self.q_out, 50, True) SisoTestHelper(self, block, inp, expected_outputs)
def siso_process(self, event): '''Carry out the comparison using the compare method.''' if self.compare(event): if self.bool_out: self.output_channel.put(Event(event.tag, True)) else: self.output_channel.put(event) elif self.bool_out: self.output_channel.put(Event(event.tag, False))
def test_linear_interpolation_dt(self): '''Test linear interpolation of a simple DT signal. ''' inp = [Event(value = i, tag = i) for i in xrange(-10, 11, 1)] expected_outputs = [Event(tag = t, value = (t / 2.0 - 5.0) ) for t in xrange(-10, 31, 1)] self.q_in = Channel('DT') self.q_out = Channel('DT') block = InterpolatorLinear(self.q_in, self.q_out) SisoTestHelper(self, block, inp, expected_outputs)
def process(self): for i, line in enumerate(self.file): if self.send_as_words: [ self.output_channel.put(Event(tag=i, value=word.strip())) for j, word in enumerate(line.split()) ] else: self.output_channel.put(Event(tag=i, value=line.strip())) self.output_channel.put(LastEvent) self.stop = True
def siso_process(self, event): logging.debug("Quantizer received (tag: %2.e, value: %2.e )" % (event.tag, event.value)) quantized_value = self.delta * floor(event.value / self.delta) self.output_channel.put(Event(event.tag, quantized_value)) return
def test_incompatible_signals(self): '''Test reducing the frequency by non integer factor. First create a signal of 120 seconds, with 10 samples per second. Down-sample this to a 8hz signal. ''' simulation_time = 120 # seconds to simulate resolution = 10.0 # samples per second (10hz) desired_resolution = 8 # what we want out - (8hz) # Create tags for a signal from 0 to 120 seconds. # length = number of seconds * ( samples per second + 1) freq = simulation_time * resolution tags = linspace(0, simulation_time, (freq) + 1) # Create 120 seconds of a discrete time signal with a 10hz frequency inp = [Event(value=1, tag=i) for i in tags] down_sampler = Sampler(self.q_in, self.q_out, desired_resolution) down_sampler.start() [self.q_in.put(val) for val in inp] self.q_in.put(LastEvent()) down_sampler.join() out = self.q_out.get() # @todo: NEED TO WORK OUT HOW WE WANT TO DO THIS... #self.assertEquals(type(out), InvalidSimulationInput) self.assertTrue(self.q_out.get().last)
def integrate(self, event): ''' y[n] = y[n-1] + x[n-1] ''' self.y = self.y_old self.y_old += event.value # Generate output event out_event = Event(event.tag, self.y) return out_event
def test_greater_than_positive_integers(self): '''Test a simple positive integer signal. ''' inp = [Event(value=i, tag=i) for i in xrange(0, 100, 1)] expected_outputs = [i for i in inp if i.value >= 50] greater_than_block = GreaterThan(self.q_in, self.q_out, 50) SisoTestHelper(self, greater_than_block, inp, expected_outputs)
def process(self): x = self.input_channel.get(True) if not hasattr(x, 'last'): # Hack for bundles [self.output_channel.put(Event(tag, value)) for (tag, value) in x] else: self.output_channel.put(x) self.stop = True
def test_interleaving_merge(self): ''' Test merging two channels that have different numbers of events, and don't simply alternate their tags. ''' q_in_1 = Channel() q_in_2 = Channel() q_out = Channel() input1 = [Event(value=1, tag=2.0*i) for i in xrange(3)] + [LastEvent()] input2 = [Event(value=2, tag=0.5*i) for i in xrange(11)] + [LastEvent()] merge = Merge([q_in_1, q_in_2], q_out) merge.start() for val in input1: q_in_1.put(val) for val in input2: q_in_2.put(val) merge.join() self.assertEquals(q_out.head().tag, 0.0) self.assertEquals(q_out.get().value, 1) # 0 self.assertEquals(q_out.head().tag, 0.0) self.assertEquals(q_out.get().value, 2) # 0 self.assertEquals(q_out.head().tag, 0.5) self.assertEquals(q_out.get().value, 2) # 0.5 self.assertEquals(q_out.head().tag, 1.0) self.assertEquals(q_out.get().value, 2) # 1.0 self.assertEquals(q_out.head().tag, 1.5) self.assertEquals(q_out.get().value, 2) # 1.5 self.assertEquals(q_out.head().tag, 2.0) self.assertEquals(q_out.get().value, 1) self.assertEquals(q_out.head().tag, 2.0) self.assertEquals(q_out.get().value, 2) self.assertEquals(q_out.head().tag, 2.5) self.assertEquals(q_out.get().value, 2) self.assertEquals(q_out.head().tag, 3.0) self.assertEquals(q_out.get().value, 2) self.assertEquals(q_out.head().tag, 3.5) self.assertEquals(q_out.get().value, 2) self.assertEquals(q_out.head().tag, 4.0) self.assertEquals(q_out.get().value, 1) self.assertEquals(q_out.head().tag, 4.0) self.assertEquals(q_out.get().value, 2) self.assertTrue(q_out.get().last) self.assertTrue(q_out.get().last)
def setUp(self): self.q_in = Channel() self.q_out = Channel() self.q_out2 = Channel() self.input = [Event(value=1, tag=i) for i in xrange(100)] self.title = "test plot" self.url = os.path.join(os.getcwd(), self.title) + ".png"
def integrate(self, event): ''' y[n] = y[n-1] + 0.5*(x[n] + x[n-1]) ''' self.y = self.y_old + 0.5 * (event.value + self.x_old) self.x_old = event.value self.y_old = self.y # Generate output event out_event = Event(event.tag, self.y) return out_event
def siso_process(self, event): """The Sin trig function.""" logging.debug("Running sin process") tag = event.tag value = self.amplitude * sin(2 * pi * self.frequency * tag + self.phase) return Event(tag, value)
def test_ramp_event_detection(self): ''' Test event detection on a simple ramp signal. ''' inp = [Event(i/3, i/3) for i in xrange(-60, 63, 1)] ef = EventFilter(self.q_in, self.q_out, 2) expected_outputs = [Event(i, i) for i in xrange(-20, 21, 2)] ef.start() [self.q_in.put(val) for val in inp] self.q_in.put(LastEvent()) ef.join() for expected_output in expected_outputs: out = self.q_out.get() self.assertEquals(out.tag, expected_output.tag) self.assertEquals(out.value, expected_output.value) self.assertTrue(self.q_out.get().last)
def test_basic_delay(self): '''Test delaying a basic integer tagged signal by 1''' delay = 2 input1 = [Event(value=1, tag=i) for i in xrange(100)] expected_output = [Event(value=1, tag=i + delay) for i in xrange(100)] block = Delay(self.q_in, self.q_out, delay) block.start() [self.q_in.put(i) for i in input1 + [LastEvent()]] block.join() actual_output = [self.q_out.get() for i in xrange(100)] [ self.assertEquals(actual_output[i], expected_output[i]) for i in xrange(100) ] self.assertTrue(self.q_out.get().last)
def integrate(self, event): ''' y[n] = y[n-1] + x[n]*(t[n]-t[n-1])''' self.y = self.y_old self.y_old += event.value * (event.tag - self.t_old) self.t_old = event.tag # Generate output event return Event(event.tag, self.y_old)
def test_simple_ramp(self): '''Convert a simple ramp signal''' inp = [Event(value=i, tag=i / 10.0) for i in xrange(0, 100, 1)] expected_outputs = [ Event(value=i * 2, tag=i) for i in xrange(0, 50, 1) ] sampler = Ct2Dt(self.q_in, self.q_out, 5) sampler.start() [self.q_in.put(val) for val in inp] self.q_in.put(LastEvent()) sampler.join() for expected_output in expected_outputs: out = self.q_out.get() self.assertAlmostEquals(out.value, expected_output.value) self.assertEquals(out.tag, expected_output.tag)
def test_simple_integration(self): ''' Test a simple integration of xdot = -x. ''' # Note that here instead of actually closing the loop around the # integrator we're simply feeding in a sequence of values corresponding # to the function f(x) = -x, and then later checking that the outputs we # get match the inputs we fed in. This allows the testing to be done # without relying on other actors. intags = [ 0.0, 0.0500000000000000, 0.1611111111111, 0.28611111111111, 0.42896825396825566, 0.59563492063492, 0.79563492063492, 1.04563492063492, 1.37896825396825, 1.878968253968261, 2.878968253968262 ] invals = [ -1, -0.9, -0.8, -0.7, -0.6, -0.5, -0.4, -0.3, -0.2, -0.1, 0.0 ] inputs = [ Event(value=val, tag=tag) for (val, tag) in zip(invals, intags) ] expected_output_tags = [ 0.0, 0.0500000000000000, 0.1611111111111, 0.28611111111111, 0.42896825396825566, 0.59563492063492, 0.79563492063492, 1.04563492063492, 1.37896825396825, 1.878968253968261, 2.878968253968262, 10.0 ] expected_output_values = [ 1, 0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1, 0.0, 0.1 ] expected_outputs = [ Event(value=val, tag=tag) for (val, tag) in zip(expected_output_values, expected_output_tags) ] # k has been set to make maxstep 10.0 block = CTIntegratorQS1(self.q_in, self.q_out, init=1.0, delta=0.1, maxstep=10.0, algebraic_loop=True) SisoCTTestHelper(self, block, inputs, expected_outputs)
def test_no_points(self): '''Test that no points get passed through for an all False signal''' [ self.bool_in.put(Event(tag=i, value=self.no_points[i])) for i in self.data ] self.bool_in.put(LastEvent()) self.block.start() self.block.join() self.assertTrue(self.output.get().last)
def siso_process(self, event): out_event = None if self.next_time is None: # the first data point out_event = Event(self.out_tag, event.value) self.next_time = event.tag + self.output_period elif self.next_time <= event.tag: # the next data point for given frequency dt = (event.tag - self.last_event.tag) dv = (event.value - self.last_event.value) out_value = self.last_event.value + (dv / dt) * ( self.next_time - self.last_event.tag) out_event = Event(self.out_tag, out_value) self.next_time += self.output_period self.last_event = event if out_event is not None: self.out_tag += 1 self.output_channel.put(out_event)