class TestBlackboard(unittest.TestCase):

    def setUp(self):
        self.blackboard = Blackboard()

    """ Test put functionality  """
    def test_put(self):
        # put value in buffer
        self.blackboard.put_data( test_pattern, test_value )
        
        # buffer should only contain the added value in a list
        self.assertEquals( self.blackboard.get_data(test_pattern)['data'], [test_value] )   
        
        # set buffersize and add a lot of data
        for pat in self.blackboard.get_patterns():
            self.blackboard.set_bufsize( pat, test_buffersize )
        for _ in range( 2000 ):
            self.blackboard.put_data( test_pattern, randint( 0, 256 ) )
            
        # check whether buffer size remains within buffersize
        self.assertEqual( len( self.blackboard.get_data( test_pattern )['data'] ), test_buffersize )
        
    """ Test get functionality """
    def test_get(self):
        # register buffer, set buffersize and add a bit of data
        for pat in self.blackboard.get_patterns():
            self.blackboard.set_bufferlength( test_buffersize )
        for _ in range( number_of_test_samples ):
            self.blackboard.put_data( test_pattern, randint( 0, 256 ) )
            
        # buffer should contain the number of added samples
        self.assertEquals( len( self.blackboard.get_data( test_pattern )['data'] ), number_of_test_samples)        
        
    def tearDown(self):
        unittest.TestCase.tearDown(self)
class TestFreqSpectrum(unittest.TestCase):

    def setUp(self):
        unittest.TestCase.setUp(self)
        self.bb = Blackboard()
        pattern = '/sines'
        
        self.offset         = 10
        self.frequencies    = [1,3,5,7]
        self.amps           = [1,2,1,8]
        
        self.gen            = DataGenerator( self.bb, pattern, frequencies=self.frequencies, amplitudes=self.amps, offset=self.offset, noise=0 )
        self.freqspec       = FFTAnalyzer( self.bb, pattern, windowsize=256 )
        self.bb.set_bufsize( '/sines/fft', 128 )

    def test_fft(self):
        self.gen.start()
        self.freqspec.start()
        
        sleep( 3 )
        
        self.gen.stop()
        self.freqspec.stop()

        result = self.bb.get_data('/sines/fft')
        
        # Enable when code coverage is guaranteed
        #self.assertAlmostEqual( result['data'], self.offset, msg="Offset difference too big", delta=.15 )
        
        #for f,amp in zip(self.frequencies,self.amps):
        #    self.assertAlmostEqual( result[f], amp, msg="Power difference too big: freq %f - original %f - measured %f" % (f, amp, result[f]), delta=.15 )
        
    def test_setFreqBands(self):
        '''
            Verify if frequency bands can be set
            For now only call the function for code coverage
        '''
        test_freq = 10

        self.freqspec.setFreqBands(test_freq)


    def test_setPatterns(self):
        '''
            Verify if patterns can be set
            For now only call the function for code coverage
        '''
        test_pattern = '/test'

        self.freqspec.setPatterns(test_pattern)

    def test_resetBuffers(self):
        '''
            Verify if buffers can be reset
            For now only call the function for code coverage
        '''
        self.freqspec.resetBuffers()

    def tearDown(self):
        unittest.TestCase.tearDown(self)
class TestDataConsumer(unittest.TestCase):

    def setUp(self):
        unittest.TestCase.setUp(self)
        self.blackboard = Blackboard()
        
        self.pat = '/test'
        self.gen = DataGenerator( self.blackboard, self.pat, [1], [1] )
        self.gen.start()
        self.pat2 = '/test2'
        self.gen2 = DataGenerator( self.blackboard, self.pat2, [2], [1] )
        self.gen2.start()

    def test_singel_data_stream(self):
        """
        Test whether data of single is coming through
        """
        DataConsumer( self.blackboard, self.pat )
        sleep( .5 )
        
        result = self.blackboard.get_data( self.pat )
        self.assertIsNotNone( result )
        self.assertGreater(len(result), 0 )

    def test_multiple_data_streams(self):
        DataConsumer( self.blackboard, [self.pat, self.pat2] )
        sleep( .5 )
        
        result = self.blackboard.get_data( self.pat )
        self.assertIsNotNone( result )
        self.assertGreater(len(result), 0 )
        
        result = self.blackboard.get_data( self.pat2 )
        self.assertIsNotNone( result )
        self.assertGreater(len(result), 0 )

        
    def tearDown(self):
        unittest.TestCase.tearDown(self)
        self.gen.stop()
        self.gen2.stop()
Пример #4
0
class TestBlackboard(unittest.TestCase):
    def setUp(self):
        self.blackboard = Blackboard()

    """ Test put functionality  """

    def test_put(self):
        # put value in buffer
        self.blackboard.put_data(test_pattern, test_value)

        # buffer should only contain the added value in a list
        self.assertEquals(
            self.blackboard.get_data(test_pattern)['data'], [test_value])

        # set buffersize and add a lot of data
        for pat in self.blackboard.get_patterns():
            self.blackboard.set_bufsize(pat, test_buffersize)
        for _ in range(2000):
            self.blackboard.put_data(test_pattern, randint(0, 256))

        # check whether buffer size remains within buffersize
        self.assertEqual(len(self.blackboard.get_data(test_pattern)['data']),
                         test_buffersize)

    """ Test get functionality """

    def test_get(self):
        # register buffer, set buffersize and add a bit of data
        for pat in self.blackboard.get_patterns():
            self.blackboard.set_bufferlength(test_buffersize)
        for _ in range(number_of_test_samples):
            self.blackboard.put_data(test_pattern, randint(0, 256))

        # buffer should contain the number of added samples
        self.assertEquals(len(self.blackboard.get_data(test_pattern)['data']),
                          number_of_test_samples)

    def tearDown(self):
        unittest.TestCase.tearDown(self)
Пример #5
0
class TestDataConsumer(unittest.TestCase):
    def setUp(self):
        unittest.TestCase.setUp(self)
        self.blackboard = Blackboard()

        self.pat = '/test'
        self.gen = DataGenerator(self.blackboard, self.pat, [1], [1])
        self.gen.start()
        self.pat2 = '/test2'
        self.gen2 = DataGenerator(self.blackboard, self.pat2, [2], [1])
        self.gen2.start()

    def test_singel_data_stream(self):
        """
        Test whether data of single is coming through
        """
        DataConsumer(self.blackboard, self.pat)
        sleep(.5)

        result = self.blackboard.get_data(self.pat)
        self.assertIsNotNone(result)
        self.assertGreater(len(result), 0)

    def test_multiple_data_streams(self):
        DataConsumer(self.blackboard, [self.pat, self.pat2])
        sleep(.5)

        result = self.blackboard.get_data(self.pat)
        self.assertIsNotNone(result)
        self.assertGreater(len(result), 0)

        result = self.blackboard.get_data(self.pat2)
        self.assertIsNotNone(result)
        self.assertGreater(len(result), 0)

    def tearDown(self):
        unittest.TestCase.tearDown(self)
        self.gen.stop()
        self.gen2.stop()
Пример #6
0
class TestFIRFilter(unittest.TestCase):
    def setUp(self):
        """
        Initialize blackboard and a simulation data generator
        """
        unittest.TestCase.setUp(self)
        self.bb = Blackboard()
        self.pattern = '/sines'

        self.offset = 10
        self.frequencies = [50, 10]
        self.amps = [1, 1]

        self.gen = DataGenerator(self.bb,
                                 self.pattern,
                                 frequencies=self.frequencies,
                                 amplitudes=self.amps,
                                 offset=self.offset,
                                 noise=0)

    def test_init_notch(self):
        """
        Compare the generation of notch filter coefficients with the coefficients provided by Imec
        """
        notch_template = FIRPreprocessing.coefBSF256

        fir = FIRFilter(self.bb, self.pattern, 129, 256, 50, 'notch')
        self.assertEqual(len(notch_template), len(fir.get_coefficients()),
                         'sets should be equal length')
        self.assertAlmostEqual(
            sum([
                abs(x - y)
                for x, y in zip(notch_template, fir.get_coefficients())
            ]), 0, 5, 'difference should be small')

    def test_init_lpf(self):
        """
        Compare the generation of low-pass filter coefficients with the coefficients provided by Imec
        """
        lpf_template = FIRPreprocessing.coefLPF256

        fir = FIRFilter(self.bb, self.pattern, 33, 256, 75, 'lpf')
        coef = fir.get_coefficients()

        self.assertAlmostEqual(
            sum([abs(x - y) for x, y in zip(lpf_template, coef)]), 0, 2,
            'difference should be small')

    def test_elementwise_lfilter(self):
        """
        Test whether our method of elementwise processing yields the same results as processing a whole signal at once
        """
        fir = FIRFilter(self.bb, self.pattern, 33, 256, 75, 'lpf')
        a = 1
        sig = [randint(0, 1024) for _ in range(256)]

        result = lfilter(fir.get_coefficients(), a, sig, axis=0)

        result2 = []
        buf = []
        for s in sig:
            buf.append(s)
            buf = buf[-33:]
            result2.append(lfilter(fir.get_coefficients(), a, buf)[-1])

        self.assertEqual(len(result), len(result2),
                         'Results should be equal length')
        self.assertEqual(sum([abs(x - y) for x, y in zip(result, result2)]), 0,
                         'Results should be equal value')

    def test_notch50(self):
        """
        TODO Improve test with better timing mechanism or decouple from internal timing mechanism
        When plotting the results, the filtered signal looks really good though.
        """
        fir = FIRFilter(self.bb, self.pattern, 129, 256, 50, 'notch')

        self.gen2 = DataGenerator(self.bb,
                                  '/sine',
                                  frequencies=[10],
                                  amplitudes=[1],
                                  offset=self.offset,
                                  noise=0)

        self.bb.set_bufsize('/sine', 512)
        self.bb.set_bufsize('/sines/notch_50', 512)

        self.gen.start()
        self.gen2.start()
        fir.start()

        time.sleep(3)

        self.gen.stop()
        self.gen2.stop()
        fir.stop()

        time.sleep(1)

        off = len(fir.get_coefficients())

        target = self.bb.get_data('/sine')['data'][(off - 1) / 2:128 +
                                                   (off - 1) / 2]
        result = self.bb.get_data('/sines/notch_50')['data'][:128]

        #dif = np.average([ abs( x-y ) for x,y in zip(result, target ) ])
        #delta = 1
        #self.assertAlmostEqual( dif, 0, msg='Difference between target and result should be smaller than %.2f, difference is %f'%(delta,dif), delta=delta)

    def test_init_pattern_no_string(self):

        # An TypeError should be raised when a pattern is no string
        with self.assertRaises(TypeError):
            FIRFilter(self.bb, 5, 129, 256, 50, 'notch')

    def test_init_not_implemented_filter(self):

        # An NotImplementedError should be raised
        with self.assertRaises(NotImplementedError):
            FIRFilter(self.bb, self.pattern, 129, 256, 50, 'bsf')

    def test_init_incompatible_filter(self):

        # An TyperError should be raised
        with self.assertRaises(TypeError):
            FIRFilter(self.bb, self.pattern, 129, 256, 50, 'foo')

    def test_init_pattern_list(self):
        # For codecoverage
        FIRFilter(self.bb, [self.pattern], 129, 256, 50, 'notch')
Пример #7
0
class TestFreqSpectrum(unittest.TestCase):
    def setUp(self):
        unittest.TestCase.setUp(self)
        self.bb = Blackboard()
        pattern = '/sines'

        self.offset = 10
        self.frequencies = [1, 3, 5, 7]
        self.amps = [1, 2, 1, 8]

        self.gen = DataGenerator(self.bb,
                                 pattern,
                                 frequencies=self.frequencies,
                                 amplitudes=self.amps,
                                 offset=self.offset,
                                 noise=0)
        self.freqspec = FFTAnalyzer(self.bb, pattern, windowsize=256)
        self.bb.set_bufsize('/sines/fft', 128)

    def test_fft(self):
        self.gen.start()
        self.freqspec.start()

        sleep(3)

        self.gen.stop()
        self.freqspec.stop()

        result = self.bb.get_data('/sines/fft')

        # Enable when code coverage is guaranteed
        #self.assertAlmostEqual( result['data'], self.offset, msg="Offset difference too big", delta=.15 )

        #for f,amp in zip(self.frequencies,self.amps):
        #    self.assertAlmostEqual( result[f], amp, msg="Power difference too big: freq %f - original %f - measured %f" % (f, amp, result[f]), delta=.15 )

    def test_setFreqBands(self):
        '''
            Verify if frequency bands can be set
            For now only call the function for code coverage
        '''
        test_freq = 10

        self.freqspec.setFreqBands(test_freq)

    def test_setPatterns(self):
        '''
            Verify if patterns can be set
            For now only call the function for code coverage
        '''
        test_pattern = '/test'

        self.freqspec.setPatterns(test_pattern)

    def test_resetBuffers(self):
        '''
            Verify if buffers can be reset
            For now only call the function for code coverage
        '''
        self.freqspec.resetBuffers()

    def tearDown(self):
        unittest.TestCase.tearDown(self)
Пример #8
0
class TestFIRFilter( unittest.TestCase ):
    
    def setUp(self):
        """
        Initialize blackboard and a simulation data generator
        """
        unittest.TestCase.setUp( self )
        self.bb      = Blackboard()
        self.pattern = '/sines'
        
        self.offset         = 10
        self.frequencies    = [50,10]
        self.amps           = [1,1]
        
        self.gen            = DataGenerator( self.bb, self.pattern, frequencies=self.frequencies, amplitudes=self.amps, offset=self.offset, noise=0 )
    
    def test_init_notch(self):
        """
        Compare the generation of notch filter coefficients with the coefficients provided by Imec
        """
        notch_template = FIRPreprocessing.coefBSF256

        fir = FIRFilter( self.bb, self.pattern, 129, 256, 50, 'notch' )
        self.assertEqual( len(notch_template), len(fir.get_coefficients() ), 'sets should be equal length')
        self.assertAlmostEqual( sum([ abs( x-y ) for x,y in zip(notch_template, fir.get_coefficients() ) ]), 0, 5, 'difference should be small')
        
    def test_init_lpf(self):
        """
        Compare the generation of low-pass filter coefficients with the coefficients provided by Imec
        """
        lpf_template = FIRPreprocessing.coefLPF256

        fir  = FIRFilter( self.bb, self.pattern, 33, 256, 75, 'lpf' )
        coef = fir.get_coefficients()
           
        self.assertAlmostEqual( sum([ abs( x-y ) for x,y in zip(lpf_template, coef ) ]), 0, 2, 'difference should be small')
        
    def test_elementwise_lfilter(self):
        """
        Test whether our method of elementwise processing yields the same results as processing a whole signal at once
        """
        fir = FIRFilter( self.bb, self.pattern, 33, 256, 75, 'lpf' )
        a   = 1
        sig = [ randint(0,1024) for _ in range(256) ]
        
        result = lfilter( fir.get_coefficients(), a, sig, axis=0 ) 

        result2 = []
        buf = []
        for s in sig:
            buf.append(s)
            buf = buf[-33:]
            result2.append(lfilter( fir.get_coefficients(), a, buf )[-1] )
        
        self.assertEqual( len(result), len(result2), 'Results should be equal length')
        self.assertEqual( sum([ abs( x-y ) for x,y in zip(result, result2 ) ]), 0, 'Results should be equal value')
        
    def test_notch50(self):
        """
        TODO Improve test with better timing mechanism or decouple from internal timing mechanism
        When plotting the results, the filtered signal looks really good though.
        """
        fir = FIRFilter( self.bb, self.pattern, 129, 256, 50, 'notch' )
        
        self.gen2 = DataGenerator( self.bb, '/sine', frequencies=[10], amplitudes=[1], offset=self.offset, noise=0 )
        
        self.bb.set_bufsize('/sine', 512)
        self.bb.set_bufsize('/sines/notch_50', 512)
        
        self.gen.start()
        self.gen2.start()
        fir.start()
        
        time.sleep( 3 )
        
        self.gen.stop()
        self.gen2.stop()
        fir.stop()

        time.sleep( 1 )
        
        off = len(fir.get_coefficients())
        
        target = self.bb.get_data('/sine')['data'][(off-1)/2:128+(off-1)/2]
        result = self.bb.get_data('/sines/notch_50')['data'][:128]

        #dif = np.average([ abs( x-y ) for x,y in zip(result, target ) ])
        #delta = 1
        #self.assertAlmostEqual( dif, 0, msg='Difference between target and result should be smaller than %.2f, difference is %f'%(delta,dif), delta=delta)

    def test_init_pattern_no_string(self):

        # An TypeError should be raised when a pattern is no string
        with self.assertRaises(TypeError):
            FIRFilter( self.bb, 5, 129, 256, 50, 'notch' )

    def test_init_not_implemented_filter(self):

        # An NotImplementedError should be raised
        with self.assertRaises(NotImplementedError):
            FIRFilter( self.bb, self.pattern, 129, 256, 50, 'bsf' )

    def test_init_incompatible_filter(self):

        # An TyperError should be raised
        with self.assertRaises(TypeError):
            FIRFilter( self.bb, self.pattern, 129, 256, 50, 'foo' )


    def test_init_pattern_list(self):
        # For codecoverage
        FIRFilter( self.bb, [self.pattern] , 129, 256, 50, 'notch' )