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 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_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 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_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 process(self): """Deterministically merge inputs from a set of channels. Note that this only removes events from those channels that result in an output event. Events at the head of other channels are left untouched, and will be checked again the next time the process runs.""" logging.debug("Merge: running") # Block on each channel in sequence. We can't make a decision # on the merge until we have events (and thus tags) on every channel. events = [] termination_count = 0 oldest_tag = infinity for input in self.inputs: event = input.head() if event.last: termination_count += 1 else: oldest_tag = min(oldest_tag, event.tag) events.append((input, event)) # We are finished iff all the input channels have a LastEvent at the head if termination_count == self.num_inputs: logging.info("Merge: finished merging all events") # Clear all input channels for input in self.inputs: input.drop() # Terminate this process and pass on termination signal self.stop = True self.output_channel.put(LastEvent()) return elif termination_count > 0: # If we received at least one termination event then we should # begin to pass on termination signals # Clear non-terminating inputs for input in self.inputs: if not input.head().last: input.drop() # Terminate self.output_channel.put(LastEvent()) else: # Otherwise there are still events to process. Send out those events # corresponding to the oldest tag. for input, event in events: if event.tag == oldest_tag: self.output_channel.put(event) # Remove the head from each channel that has produced an output input.drop()
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_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 process(self): """Wait for data from both input channels""" logging.debug("Running pass-through, blocking on both channels") # this is blocking on each channel in sequence bool_in = self.bool_input.get(True) logging.debug("Got a boolean value, waiting for data point") data_in = self.data_input.get(True) if self.has_else_clause: else_data_in = self.else_data_input.get(True) # We are finished iff all the input objects are None if bool_in.last and data_in.last: logging.info("We have finished PassingThrough the data") self.stop = True self.output_channel.put(LastEvent(bool_in.tag)) return logging.debug("Received a boolean and a data point. Tags = (%e,%e)" % (bool_in.tag, data_in.tag)) # For now we require the signals are in sync assert bool_in.tag == data_in.tag if bool_in.value is True: logging.debug("The input was positive, passing data through") self.output_channel.put(data_in) else: if self.has_else_clause: self.output_channel.put(else_data_in) else: logging.debug("Discarding data.")
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_plotting(self): bundler = Bundle(self.q_in, self.q_out) bundlingPlotter = BundlePlotter(self.q_out, self.title) [block.start() for block in [bundler, bundlingPlotter]] [self.q_in.put(i) for i in self.input + [LastEvent()]] [block.join() for block in [bundler, bundlingPlotter]] self.assertTrue(os.path.exists(self.url))
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 test_unbundle(self): '''Test the unbundler and the bundler''' bundler = Bundle(self.q_in, self.q_out) unbundler = Unbundle(self.q_out, self.q_out2) [block.start() for block in [bundler, unbundler]] [self.q_in.put(i) for i in self.input + [LastEvent()]] [block.join() for block in [bundler, unbundler]] [self.assertEquals(self.q_out2.get(), i) for i in self.input] self.assertTrue(self.q_out2.get().last)
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 test_text_writer(self): tfile = tempfile.NamedTemporaryFile() filename = tfile.name output = Channel() writer = TextWriter(output, filename) [output.put(e) for e in [Event(value=i ** 3, tag=i) for i in xrange(100)] + [LastEvent()]] writer.start() writer.join() for i, line in enumerate(tfile): self.assertEquals('%s, %s' % (str(i), str(i**3)), line.strip())
def test_simple_merge(self): '''Test merging two channels of complete pairs together''' q_in_1 = Channel() q_in_2 = Channel() q_out = Channel() input1 = [Event(value=1, tag=i) for i in xrange(100)] + [LastEvent()] input2 = [Event(value=2, tag=i) 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(100): self.assertEquals(q_out.get().value, 1) self.assertEquals(q_out.get().value, 2) self.assertTrue(q_out.get().last)
def process(self): """Create the numbers...""" logging.debug("Running ramp process") tags = linspace(0, self.simulation_time, self.simulation_time * self.resolution, endpoint=self.endpoint) # for now just compute 2 minutes of values [self.output_channel.put(Event(tag, self.value)) for tag in tags] #time.sleep(random.random() * 0.001) # Adding a delay so we can see the async logging.debug("Const process finished adding all data to its output channel") self.stop = True self.output_channel.put(LastEvent(self.simulation_time))
def test_all_points(self): '''Test that it passes through every point when given True control signal''' every_point = [True] * 100 [ self.bool_in.put(Event(tag=i, value=every_point[i])) for i in self.data ] self.bool_in.put(LastEvent()) self.block.start() self.block.join() [self.assertEquals(self.output.get().tag, i) for i in self.data] self.assertTrue(self.output.get().last)
def test_basic_summer(self): '''Test adding two channels of complete pairs together''' 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) for i in xrange(100)] 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() for i in xrange(100): self.assertEquals(q_out.get()['value'], 3) self.assertTrue(q_out.get().last)
def test_signed_summer(self): '''Test subtracting one channel from another''' 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) for i in xrange(100)] 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() for i in xrange(100): self.assertEquals(q_out.get()['value'], -1) self.assertTrue(q_out.get().last)
def test_sink(self): '''Test that sink runs. ''' inp = [Event(i, i) for i in xrange(0, 100, 1)] try: sink = Sink(self.q_in) sink.start() [self.q_in.put(val) for val in inp] self.q_in.put(LastEvent()) sink.join() except: self.fail("Sink failed to run without exception.")
def test_getting_bundle_data(self): '''Test bundling a signal and getting the data back''' block = Bundle(self.q_in, self.q_out) block.start() [self.q_in.put(i) for i in self.input + [LastEvent()]] block.join() bundled_data = self.q_out.get() self.assertEqual(len(bundled_data), 100) self.assertEqual(type(bundled_data), numpy.ndarray) values = bundled_data["Value"] self.assertTrue(all(values == 1)) tags = bundled_data["Tag"] [self.assertEquals(tags[i], i) for i in xrange(100)]
def test_delayed_summer3(self): ''' Test adding two channels where one is delayed by ONE time step difference Summer is set up to SUM incomplete sets ''' 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)] # First tag is 0, last tag is 99. input2 = [Event(value=2, tag=i + 1) for i in xrange(100)] # First tag is 1, last tag is 100. summer = DTSummer([q_in_1, q_in_2], q_out, False) 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() # First value should be 1, next 99 should be 3, last should be 2. data = q_out.get() self.assertEquals(data['value'], 1) self.assertEquals(data['tag'], 0) for i in xrange(1, 100): data = q_out.get() self.assertEquals(data['value'], 3) self.assertEquals(data['tag'], i) data = q_out.get() # lastly the channel should contain a terminal event self.assertTrue(q_out.get().last)
def process(self): """Create the numbers...""" logging.debug("Running step process") tags = arange(0, self.simulation_time, self.timestep) for tag in tags: value = 0 if (tag < self.switch_time) else 1 self.output_channel.put(Event(tag, value)) #time.sleep(random.random() * 0.001) # Adding a delay so we can see the async logging.debug("Step process finished adding all data to channel") self.stop = True self.output_channel.put(LastEvent(self.simulation_time))
def test_bundle_full_signal(self): '''Test sending a basic integer tagged signal all at once''' bundle_size = 1000 #expected_output = [Event(value=1, tag=i + delay) for i in xrange(100)] block = Bundle(self.q_in, self.q_out, bundle_size) block.start() [self.q_in.put(i) for i in self.input + [LastEvent()]] block.join() actual_output = self.q_out.get() self.assertEqual(actual_output.size, 100) self.assertTrue(self.q_out.get().last)
def test_every_second_point(self): '''Test every second point is passed through and that the rest is discarded ''' [ self.bool_in.put(Event(tag=i, value=self.every_second_point[i])) for i in self.data ] self.bool_in.put(LastEvent()) self.block.start() self.block.join() [ self.assertEquals(self.output.get().tag, i) for i in self.data if i % 2 == 0 ] self.assertTrue(self.output.get().last)
def test_backward_euler(self): '''Test backward Euler integration of a simple positive integer signal. ''' inp = [Event(value=i, tag=i) for i in xrange(0, 10, 1)] expected_output_values = [sum(range(i)) for i in xrange(1, 11)] block = DTIntegratorBackwardEuler(self.q_in, self.q_out) block.start() [self.q_in.put(val) for val in inp] self.q_in.put(LastEvent()) block.join() for expected_output in expected_output_values: out = self.q_out.get() self.assertEquals(out.value, expected_output) self.assertTrue(self.q_out.get().last)
def test_positive_integers(self): '''Test a simple positive integer signal. ''' inp = [Event(value=i, tag=i) for i in xrange(0, 100, 1)] expected_outputs = inp[:] abs = Abs(self.q_in, self.q_out) abs.start() [self.q_in.put(val) for val in inp] self.q_in.put(LastEvent()) abs.join() for expected_output in expected_outputs: out = self.q_out.get() self.assertEquals(out.value, expected_output.value) self.assertEquals(out.tag, expected_output.tag) self.assertTrue(self.q_out.get().last)
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)