Beispiel #1
0
    def test_get_expr_user_defined_function_memoized_clear_cache(self):

        # helper callable with call counter
        class FuncWithCounter:
            def __init__(self, func):
                self._f = func
                self.__name__ = func.__name__
                self._call_count = 0

            def __call__(self, *args):
                self._call_count += 1
                return self._f(*args)

        @FuncWithCounter
        def triple_memoized(tobject):
            return 3 * tobject

        # add the memoized function
        InputROOT.add_function(function=triple_memoized, memoize=True)

        # get expression multiple times, clearing the cache in-between
        for _i in range(7):
            _result_expr_memoized = self._ic.get_expr(
                'triple_memoized("test:h1")')
            InputROOT.clear_cache()

        # ensure memoized version has only been called once
        assert triple_memoized._call_count == 7

        # remove function to avoid side effects
        InputROOT.functions.pop('triple_memoized', None)
Beispiel #2
0
class TestInputROOTNoFile(unittest.TestCase):
    def setUp(self):
        self._ic = InputROOT()

    def test_request_objspec_raises(self):
        with self.assertRaises(ValueError):
            self._ic.request([dict(object_spec="file0:directory/object")])

    def test_request_filenick_objpath_raises(self):
        with self.assertRaises(ValueError):
            self._ic.request(
                [dict(file_nickname='file0', object_path="directory/object")])

    def test_get_raises(self):
        with self.assertRaises(ValueError):
            self._ic.get(object_spec="file0:directory/object")

    def test_get_expr_raises(self):
        with self.assertRaises(ValueError):
            self._ic.get_expr(
                '"file0:directory/object" + "file0:directory/object2"')

    def test_add_file(self):
        for nickname in (None, 'testfile'):
            with self.subTest():
                self._ic.add_file('ref/test.root', nickname=nickname)
                self.assertIn('ref/test.root', self._ic._file_nick_to_realpath)
                if nickname is not None:
                    self.assertIn('testfile', self._ic._file_nick_to_realpath)
                self.assertEqual(len(self._ic._input_controllers), 1)
                self.assertTrue(
                    list(self._ic._input_controllers)[0].endswith('test.root'))
Beispiel #3
0
    def test_add_function(self):
        @InputROOT.add_function
        def test_function(tobject):
            pass

        self.assertIn('test_function', InputROOT.functions)
        self.assertIs(InputROOT.get_function('test_function'), test_function)
Beispiel #4
0
    def test_add_function_alias(self):
        @InputROOT.add_function(name='aliased_function')
        def test_function(tobject):
            pass

        self.assertIn('aliased_function', InputROOT.functions)
        self.assertNotIn('test_function', InputROOT.functions)
        self.assertIs(InputROOT.get_function('aliased_function'),
                      test_function)
Beispiel #5
0
    def test_get_function_override(self):
        @InputROOT.add_function
        def test_function(tobject):
            pass

        @InputROOT.add_function(name='test_function', override=True)
        def test_function_2(tobject):
            pass

        self.assertIn('test_function', InputROOT.functions)
        self.assertNotIn('test_function_2', InputROOT.functions)
        self.assertIs(InputROOT.get_function('test_function'), test_function_2)
Beispiel #6
0
    def setUpClass(cls):
        # create root file controller
        cls._IC = InputROOT()

        # add file containing reference objects and retrieve them
        cls._IC.add_file(cls.INPUT_FILENAME, nickname='ref')
        cls._REF_OBJECTS = {
            'h1': cls._IC.get(object_spec="ref:h1"),
            'h2': cls._IC.get(object_spec="ref:h2")
        }

        # add "virtual" file that will contain the test outputs to compare
        cls._TEST_FILENAME = os.path.join(cls.OUTPUT_FOLDER,
                                          cls.OUTPUT_FILENAME)
        cls._IC.add_file(cls._TEST_FILENAME, nickname='test')
    def setUpClass(cls):
        # create root file controller
        cls._IC = InputROOT()

        # add file containing reference objects and retrieve them
        cls._IC.add_file(cls.INPUT_FILENAME, nickname='ref')
        cls._REF_OBJECTS = {
            'h1': cls._IC.get(object_spec="ref:h1"),
            'h2': cls._IC.get(object_spec="ref:h2"),
            'fa1': cls._IC.get(object_spec="ref:fa1")
        }

        # path to file(s) that will contain the test outputs to compare
        cls._TEST_FILENAME_FIG = os.path.join(cls.OUTPUT_FOLDER,
                                              cls.OUTPUT_FILENAME)
        cls._TEST_FILENAME_YML = '.'.join(
            cls._TEST_FILENAME_FIG.split('.')[:-1] + ['yml'])
Beispiel #8
0
    def test_get_expr_user_defined_function_memoized(self):

        # helper callable with call counter
        class FuncWithCounter:
            def __init__(self, func):
                self._f = func
                self.__name__ = func.__name__
                self._call_count = 0

            def __call__(self, *args):
                self._call_count += 1
                return self._f(*args)

        # define two equivalend call-counted functions
        @FuncWithCounter
        def triple(tobject):
            return 3 * tobject

        @FuncWithCounter
        def triple_memoized(tobject):
            return 3 * tobject

        # add a memoized and a non-memoized version
        InputROOT.add_function(function=triple_memoized, memoize=True)
        InputROOT.add_function(function=triple, memoize=False)

        # get expression multiple times
        _result_direct = 3 * self._ic.get_expr('"test:h1"')
        for _i in range(7):
            _result_expr_memoized = self._ic.get_expr(
                'triple_memoized("test:h1")')
            _result_expr = self._ic.get_expr('triple("test:h1")')

        # compare results with both functions to reference
        for _bin_1, _bin_2 in zip(_result_expr, _result_direct):
            self.assertEqual(_bin_1.value, _bin_2.value)
            self.assertEqual(_bin_1.error, _bin_2.error)
        for _bin_1, _bin_2 in zip(_result_expr_memoized, _result_direct):
            self.assertEqual(_bin_1.value, _bin_2.value)
            self.assertEqual(_bin_1.error, _bin_2.error)

        # ensure memoized version has only been called once
        assert triple._call_count == 7
        assert triple_memoized._call_count == 1

        # remove function and clear the cache to avoid side effects
        InputROOT.functions.pop('triple', None)
        InputROOT.functions.pop('triple_memoized', None)
        InputROOT.clear_cache()
Beispiel #9
0
 def setUp(self):
     self._ic = InputROOT()
Beispiel #10
0
    def setUp(self):

        self._ic = InputROOT()
        self._ic.add_file('ref/test.root', nickname='test')
Beispiel #11
0
class TestInputROOTWithFile(unittest.TestCase):
    def setUp(self):

        self._ic = InputROOT()
        self._ic.add_file('ref/test.root', nickname='test')

    def test_get_inexistent_raises(self):
        with self.assertRaises(DoesNotExist):
            self._ic.get(object_spec="test:this_does_not_exist")

    def test_get_expr_inexistent_raises(self):
        with self.assertRaises(DoesNotExist):
            self._ic.get_expr('"test:this_does_not_exist"')

    def test_get(self):
        self.assertIsInstance(self._ic.get(object_spec="test:h1"), _Hist)
        self.assertIsInstance(self._ic.get(object_spec="test:h2"), _Hist)

    def test_get_expr_simple(self):
        self.assertIsInstance(self._ic.get_expr('"test:h1"'), _Hist)
        self.assertIsInstance(self._ic.get_expr('"test:h2"'), _Hist)

    def test_get_expr_simple_string(self):
        self.assertEquals(self._ic.get_expr('str("test:h1")'), "test:h1")

    def test_get_expr_histogram_binary_op(self):
        for _symbol, _op in [('+', op.add), ('*', op.mul)]:
            with self.subTest(operation=_symbol):
                _result_expr = self._ic.get_expr(
                    '"test:h1" {} "test:h2"'.format(_symbol))
                _result_direct = _op(self._ic.get_expr('"test:h1"'),
                                     self._ic.get_expr('"test:h2"'))
                # bin-by-bin comparison
                for _bin_1, _bin_2 in zip(_result_expr, _result_direct):
                    self.assertEqual(_bin_1.value, _bin_2.value)
                    self.assertEqual(_bin_1.error, _bin_2.error)

    def test_get_expr_histogram_attribute(self):
        self.assertEquals(self._ic.get_expr('"test:h1".GetNbinsX()'),
                          self._ic.get_expr('"test:h1"').GetNbinsX())

    def test_get_expr_binary_op_noinput(self):
        self.assertEquals(
            self._ic.get_expr('no_input("test:h1"+"_"+"test:h2")'),
            "test:h1_test:h2")

    def test_get_expr_user_defined_function(self):

        # add a custom function: scale hist by a factor 3
        @InputROOT.add_function
        def triple(tobject):
            return 3 * tobject

        # evaluate expr and compute reference reult
        _result_expr = self._ic.get_expr('triple("test:h1")')
        _result_direct = 3 * self._ic.get_expr('"test:h1"')

        # bin-by-bin comparison
        for _bin_1, _bin_2 in zip(_result_expr, _result_direct):
            self.assertEqual(_bin_1.value, _bin_2.value)
            self.assertEqual(_bin_1.error, _bin_2.error)

        # remove function to avoid side effects
        InputROOT.functions.pop('triple', None)

    def test_get_expr_undefined_user_defined_function_raise(self):

        with self.assertRaises(KeyError) as _err:
            # evaluate expr and compute reference reult
            self._ic.get_expr('triple("test:h1")')

        self.assertIn("'triple'", _err.exception.args[0])

    def test_get_expr_user_defined_function_signatures(self):
        @InputROOT.add_function
        def divide(dividend, divisor=8):
            return dividend / divisor

        # subtests for correct application of signatures
        with self.subTest(test_label="kwarg_default"):
            self.assertEqual(self._ic.get_expr('divide(16)'), 2)
        with self.subTest(test_label="kwarg_explicit_as_positional"):
            self.assertEqual(self._ic.get_expr('divide(16, 2)'), 8)
        with self.subTest(test_label="kwarg_explicit"):
            self.assertEqual(self._ic.get_expr('divide(16, divisor=4)'), 4)
        with self.subTest(test_label="kwarg_and_positional_explicit"):
            self.assertEqual(
                self._ic.get_expr('divide(dividend=42, divisor=7)'), 6)
        with self.subTest(
                test_label="kwarg_and_positional_explicit_different_order"):
            self.assertEqual(
                self._ic.get_expr('divide(divisor=5, dividend=35)'), 7)

        # subtests for exceptions
        with self.subTest(test_label="too_few_args"):
            with self.assertRaises(TypeError) as _err:
                self._ic.get_expr('divide()')
        with self.subTest(test_label="too_many_args"):
            with self.assertRaises(TypeError) as _err:
                self._ic.get_expr('divide(1,2,3)')
        with self.subTest(test_label="multiple_values_for_kwarg"):
            with self.assertRaises(TypeError) as _err:
                self._ic.get_expr('divide(1,2,divisor=3)')
        with self.subTest(test_label="wrong_kwarg"):
            with self.assertRaises(TypeError) as _err:
                self._ic.get_expr('divide(42, bogus_kwarg=30)')

        # remove function to avoid side effects
        InputROOT.functions.pop('divide', None)

    def test_get_expr_user_defined_function_argtypes(self):
        @InputROOT.add_function
        def get_type(argument):
            return type(argument)

        # subtests for correct application of signatures
        with self.subTest(test_label="int"):
            self.assertTrue(self._ic.get_expr('get_type(16)') is int)
        with self.subTest(test_label="float"):
            self.assertTrue(self._ic.get_expr('get_type(13.4)') is float)
        with self.subTest(test_label="bool"):
            self.assertTrue(self._ic.get_expr('get_type(True)') is bool)
            self.assertTrue(self._ic.get_expr('get_type(False)') is bool)
        with self.subTest(test_label="none"):
            self.assertTrue(self._ic.get_expr('get_type(None)') is type(None))

        with self.subTest(test_label="unknown_identifier_raise"):
            with self.assertRaises(NameError) as _err:
                self._ic.get_expr('get_type(bogus_identifier)')

        # remove function to avoid side effects
        InputROOT.functions.pop('get_type', None)

    def test_get_expr_user_defined_function_varargs(self):
        @InputROOT.add_function
        def get_arg_structure(*args, **kwargs):
            return dict(args=args, kwargs=kwargs)

        # subtests for correct application of signatures
        with self.subTest(test_label="no_args"):
            self.assertEquals(self._ic.get_expr('get_arg_structure()'),
                              dict(args=tuple(), kwargs={}))
        with self.subTest(test_label="positional_args_only"):
            self.assertEquals(self._ic.get_expr('get_arg_structure(1, 6, 4)'),
                              dict(args=(1, 6, 4), kwargs={}))
        with self.subTest(test_label="kwargs_only"):
            self.assertEquals(
                self._ic.get_expr('get_arg_structure(key1=3, key2=77)'),
                dict(args=tuple(), kwargs=dict(key1=3, key2=77)))
        with self.subTest(test_label="positional_and_kwargs"):
            self.assertEquals(
                self._ic.get_expr('get_arg_structure(2, 44, key=92)'),
                dict(args=(2, 44), kwargs=dict(key=92)))

        with self.subTest(test_label="starred_args_in_expression"):
            self.assertEquals(self._ic.get_expr('get_arg_structure(*[3, 2])'),
                              dict(args=(3, 2), kwargs=dict()))

        with self.subTest(test_label="args_and_starred_args_in_expression"):
            self.assertEquals(
                self._ic.get_expr('get_arg_structure(1, *[2, 3])'),
                dict(args=(1, 2, 3), kwargs={}))

        with self.subTest(test_label="starred_kwargs_in_expression"):
            with self.assertRaises(NotImplementedError) as _err:
                self._ic.get_expr('get_arg_structure(**{"a": 3})')

        # remove function to avoid side effects
        InputROOT.functions.pop('get_arg_structure', None)

    def test_get_expr_user_defined_function_memoized(self):

        # helper callable with call counter
        class FuncWithCounter:
            def __init__(self, func):
                self._f = func
                self.__name__ = func.__name__
                self._call_count = 0

            def __call__(self, *args):
                self._call_count += 1
                return self._f(*args)

        # define two equivalend call-counted functions
        @FuncWithCounter
        def triple(tobject):
            return 3 * tobject

        @FuncWithCounter
        def triple_memoized(tobject):
            return 3 * tobject

        # add a memoized and a non-memoized version
        InputROOT.add_function(function=triple_memoized, memoize=True)
        InputROOT.add_function(function=triple, memoize=False)

        # get expression multiple times
        _result_direct = 3 * self._ic.get_expr('"test:h1"')
        for _i in range(7):
            _result_expr_memoized = self._ic.get_expr(
                'triple_memoized("test:h1")')
            _result_expr = self._ic.get_expr('triple("test:h1")')

        # compare results with both functions to reference
        for _bin_1, _bin_2 in zip(_result_expr, _result_direct):
            self.assertEqual(_bin_1.value, _bin_2.value)
            self.assertEqual(_bin_1.error, _bin_2.error)
        for _bin_1, _bin_2 in zip(_result_expr_memoized, _result_direct):
            self.assertEqual(_bin_1.value, _bin_2.value)
            self.assertEqual(_bin_1.error, _bin_2.error)

        # ensure memoized version has only been called once
        assert triple._call_count == 7
        assert triple_memoized._call_count == 1

        # remove function and clear the cache to avoid side effects
        InputROOT.functions.pop('triple', None)
        InputROOT.functions.pop('triple_memoized', None)
        InputROOT.clear_cache()

    def test_get_expr_user_defined_function_memoized_clear_cache(self):

        # helper callable with call counter
        class FuncWithCounter:
            def __init__(self, func):
                self._f = func
                self.__name__ = func.__name__
                self._call_count = 0

            def __call__(self, *args):
                self._call_count += 1
                return self._f(*args)

        @FuncWithCounter
        def triple_memoized(tobject):
            return 3 * tobject

        # add the memoized function
        InputROOT.add_function(function=triple_memoized, memoize=True)

        # get expression multiple times, clearing the cache in-between
        for _i in range(7):
            _result_expr_memoized = self._ic.get_expr(
                'triple_memoized("test:h1")')
            InputROOT.clear_cache()

        # ensure memoized version has only been called once
        assert triple_memoized._call_count == 7

        # remove function to avoid side effects
        InputROOT.functions.pop('triple_memoized', None)

    def test_get_expr_user_defined_function_memoized_iterable_arguments(self):

        # add a custom function: scale hist by a factor 3
        @InputROOT.add_function(memoize=True)
        def how_many(iterable_args):
            try:
                return len(iterable_args.keys())
            except AttributeError:
                return len(iterable_args)

        # evaluate expr and compute reference reult
        self.assertEqual(
            self._ic.get_expr('how_many(["test:h1", "test:h1", "test:h1"])'),
            3)
        self.assertEqual(
            self._ic.get_expr('how_many(("test:h1", "test:h1", "test:h1"))'),
            3)
        self.assertEqual(
            self._ic.get_expr(
                'how_many({"a": "test:h1", "b": "test:h1", "c": "test:h1"})'),
            3)

        # remove function to avoid side effects
        InputROOT.functions.pop('how_many', None)

    def test_get_expr_user_defined_function_memoized_variable_arguments(self):

        # add a custom function: scale hist by a factor 3
        @InputROOT.add_function(memoize=True)
        def how_many(*args, **kwargs):
            return len(kwargs) + len(args)

        # evaluate expr and compute reference reult
        self.assertEqual(
            self._ic.get_expr('how_many("test:h1", "test:h1", "test:h1")'), 3)
        self.assertEqual(
            self._ic.get_expr(
                'how_many(a="test:h1", b="test:h1", c="test:h1")'), 3)
        self.assertEqual(
            self._ic.get_expr('how_many("test:h1", "test:h1", c="test:h1")'),
            3)

        # remove function to avoid side effects
        InputROOT.functions.pop('how_many', None)

    def test_get_expr_local_variables(self):

        with self.subTest(test_label="call_local_variable"):
            self.assertEqual(
                self._ic.get_expr('my_local', locals={'my_local': 60}), 60)

        with self.subTest(test_label="call_local_variable_list"):
            self.assertEqual(
                self._ic.get_expr('my_local',
                                  locals={'my_local': [42, 60, 93]}),
                [42, 60, 93])
            self.assertEqual(
                self._ic.get_expr('my_local[2]',
                                  locals={'my_local': [42, 60, 93]}), 93)
            with self.assertRaises(IndexError) as _err:
                self._ic.get_expr('my_local[44]',
                                  locals={'my_local': [42, 60, 93]})

        with self.subTest(
                test_label="registered_local_variable_before_creation_raise"):
            with self.assertRaises(NameError) as _err:
                self._ic.get_expr('my_local')

        self._ic.register_local('my_local', 42)

        with self.subTest(test_label="registered_local_variable_value"):
            self.assertEqual(self._ic.get_expr('my_local'), 42)

        with self.subTest(
                test_label="registered_local_variable_value_overridden_in_call"
        ):
            self.assertEqual(self._ic.get_expr('my_local', {'my_local': 93}),
                             93)

        with self.subTest(test_label="disallow_local_variables_raise"):
            with self.assertRaises(NameError) as _err:
                self._ic.get_expr('my_local', locals=None)

        with self.subTest(test_label="inexistent_local_variable_raise"):
            with self.assertRaises(NameError) as _err:
                self._ic.get_expr('my_bogus_local')

        self._ic.clear_locals()

        with self.subTest(test_label="local_variable_after_deletion_raise"):
            with self.assertRaises(NameError) as _err:
                self._ic.get_expr('my_local')

    def test_get_expr_local_variables_self_referential(self):

        self._ic.register_local('selfref_direct', 'selfref_direct')
        self._ic.register_local(
            'selfref_list_direct',
            ['selfref_list_direct[0]', 'selfref_list_direct[1]'])
        self._ic.register_local(
            'selfref_list_cross',
            ['selfref_list_cross[1]', 'selfref_list_cross[0]'])
        self._ic.register_local('selfref_resolvable',
                                ['selfref_resolvable[1]', 42])

        with self.subTest(test_label="selfref_direct"):
            with self.assertRaises(NameError) as _err:
                self._ic.get_expr('selfref_direct')

        with self.subTest(test_label="selfref_list_direct"):
            with self.assertRaises(NameError) as _err:
                self._ic.get_expr('selfref_list_direct[0]')
                self._ic.get_expr('selfref_list_direct[1]')
        with self.subTest(test_label="selfref_list_cross"):
            with self.assertRaises(NameError) as _err:
                self._ic.get_expr('selfref_list_cross[0]')
                self._ic.get_expr('selfref_list_cross[1]')
Beispiel #12
0
class TestInputROOTWithFile(unittest.TestCase):
    def setUp(self):

        self._ic = InputROOT()
        self._ic.add_file('ref/test.root', nickname='test')

    def test_get_inexistent_raises(self):
        with self.assertRaises(DoesNotExist):
            self._ic.get(object_spec="test:this_does_not_exist")

    def test_get_expr_inexistent_raises(self):
        with self.assertRaises(DoesNotExist):
            self._ic.get_expr('"test:this_does_not_exist"')

    def test_get(self):
        self.assertIsInstance(self._ic.get(object_spec="test:h1"), _Hist)
        self.assertIsInstance(self._ic.get(object_spec="test:h2"), _Hist)

    def test_get_expr_simple(self):
        self.assertIsInstance(self._ic.get_expr('"test:h1"'), _Hist)
        self.assertIsInstance(self._ic.get_expr('"test:h2"'), _Hist)

    def test_get_expr_histogram_binary_op(self):
        for _symbol, _op in [('+', op.add), ('*', op.mul)]:
            with self.subTest(operation=_symbol):
                _result_expr = self._ic.get_expr(
                    '"test:h1" {} "test:h2"'.format(_symbol))
                _result_direct = _op(self._ic.get_expr('"test:h1"'),
                                     self._ic.get_expr('"test:h2"'))
                # bin-by-bin comparison
                for _bin_1, _bin_2 in zip(_result_expr, _result_direct):
                    self.assertEqual(_bin_1.value, _bin_2.value)
                    self.assertEqual(_bin_1.error, _bin_2.error)

    def test_get_expr_user_defined_function(self):

        # add a custom function: scale hist by a factor 3
        @InputROOT.add_function
        def triple(tobject):
            return 3 * tobject

        # evaluate expr and compute reference reult
        _result_expr = self._ic.get_expr('triple("test:h1")')
        _result_direct = 3 * self._ic.get_expr('"test:h1"')

        # bin-by-bin comparison
        for _bin_1, _bin_2 in zip(_result_expr, _result_direct):
            self.assertEqual(_bin_1.value, _bin_2.value)
            self.assertEqual(_bin_1.error, _bin_2.error)

        # remove function to avoid side effects
        InputROOT.functions.pop('triple', None)

    def test_get_expr_undefined_user_defined_function_raise(self):

        with self.assertRaises(KeyError) as _err:
            # evaluate expr and compute reference reult
            self._ic.get_expr('triple("test:h1")')

        self.assertEqual(_err.exception.args[0], 'triple')