Ejemplo n.º 1
0
    def test_block_comments(self):
        """ Test block comments in model. """
        from myokit._parsing import parse_model_from_stream
        from myokit._parsing import Tokenizer

        def p(code):
            return parse_model_from_stream(Tokenizer(iter(code)))

        # Block comments
        c1 = (
            '[[model]]',
            '[c]',
            't = 0 bind time',
        )
        m1 = p(c1)
        c2 = (
            '[[model]]',
            '"""This is a comment"""',
            '[c]',
            't = 0 bind time',
        )
        m2 = p(c2)
        c3 = (
            '[[model]]',
            '"""'
            'This is a long',
            'long',
            'long',
            'comment',
            '"""',
            '[c]',
            't = 0 bind time',
        )
        m3 = p(c3)
        self.assertEqual(m1.code(), m2.code(), m3.code())
Ejemplo n.º 2
0
    def test_parse_variable(self):
        """
        Tests parse_variable(), uses parse_expression()
        """
        from myokit._parser import parse_variable
        from myokit._parser import Tokenizer
        m = myokit.Model('test_model')
        c = m.add_component('test_component')

        def p(s, name=None):
            parse_variable(Tokenizer(s), None, c, convert_proto_rhs=True)
            if name:
                return c.var(name)

        s = """
            x1 = 5
            """
        v = p(s, 'x1')
        self.assertIsInstance(v, myokit.Variable)
        self.assertTrue(v.is_constant())
        self.assertTrue(v.is_literal())
        self.assertFalse(v.is_state())
        self.assertFalse(v.is_intermediary())
        self.assertEqual(v.unit(), None)
        self.assertEqual(v.rhs().unit(), None)
        s = """
            x2 = 5 [mV]
            """
        v = p(s, 'x2')
        self.assertIsInstance(v, myokit.Variable)
        self.assertTrue(v.is_constant())
        self.assertTrue(v.is_literal())
        self.assertFalse(v.is_state())
        self.assertFalse(v.is_intermediary())
        self.assertEqual(v.unit(), None)
        self.assertEqual(v.rhs().unit(), myokit.parse_unit('mV'))
        s = """
            x3 = 5
                in [mV]
            """
        v = p(s, 'x3')
        self.assertIsInstance(v, myokit.Variable)
        self.assertTrue(v.is_constant())
        self.assertTrue(v.is_literal())
        self.assertFalse(v.is_state())
        self.assertFalse(v.is_intermediary())
        self.assertEqual(v.unit(), myokit.parse_unit('mV'))
        self.assertEqual(v.rhs().unit(), None)
        s = """
            x4 = 5 [V] : This is x4
            """
        v = p(s, 'x4')
        self.assertIsInstance(v, myokit.Variable)
        self.assertTrue(v.is_constant())
        self.assertTrue(v.is_literal())
        self.assertFalse(v.is_state())
        self.assertFalse(v.is_intermediary())
        self.assertEqual(v.unit(), None)
        self.assertEqual(v.rhs().unit(), myokit.units.V)
        self.assertEqual(v.meta['desc'], 'This is x4')
Ejemplo n.º 3
0
    def test_parse_user_function(self):
        """ Test :meth:`parse_user_function()`. """
        from myokit._parsing import parse_model as p

        # Test basics
        code = (
            '[[model]]',
            'michael(x) = 1 + sin(x)',
            '[c]',
            't = 0 bind time',
            'x = michael(12)',
        )
        p(code)

        code = (
            '[[model]]',
            'michael(x, y, z) = x + y / z',
            '[c]',
            't = 0 bind time',
            'x = michael(1,2,3)',
        )
        p(code)

        # Duplicate name
        code = (
            '[[model]]',
            'michael(x, y, z) = x + y / z',
            'michael(x, y, z) = x - y - z',
            '[c]',
            't = 0 bind time',
            'x = michael(1,2,3)',
        )
        self.assertRaisesRegex(myokit.ParseError, 'already defined', p, code)
Ejemplo n.º 4
0
    def test_parse_component(self):
        """
        Test parse_component(), uses parse_variable
        """
        from myokit._parser import parse_component as pc
        from myokit._parser import ParseInfo
        from myokit._parser import Tokenizer
        info = ParseInfo()
        info.model = m = myokit.Model('test_model')

        def p(s, name=None):
            pc(Tokenizer(s), info)
            if name:
                return m[name]

        s = """
            [test_component]
            x = 5 + b
                b = 13
                in [mV]
            desc: \"""
            This is a test component.
            \"""
            """
        c = p(s, 'test_component')
        self.assertEqual(len(c), 1)
        self.assertIn('desc', c.meta)
        self.assertEqual(c.meta['desc'], 'This is a test component.')
        pass
Ejemplo n.º 5
0
    def test_parse_alias(self):
        """ Test :meth:`parse_alias()`. """
        from myokit._parsing import parse_model as p

        # Test basics
        code = (
            '[[model]]',
            '[a]',
            't = 10',
            '    bind time',
            '[b]',
            'use a.t as time',
            'b = time',
            '\"""',
        )
        m = p(code)
        self.assertEqual(m.get('b.b').eval(), 10)

        # Test bad variable name
        code = (
            '[[model]]',
            '[a]',
            't = 10',
            '    bind time',
            '[b]',
            'use t as time',
            'b = time',
            '\"""',
        )
        self.assertRaisesRegex(myokit.ParseError, 'fully qualified', p, code)

        # Test bad alias name
        code = (
            '[[model]]',
            '[a]',
            't = 10',
            '    bind time',
            '[b]',
            'use a.t as _flbt12',
            'b = time',
            '\"""',
        )
        self.assertRaisesRegex(myokit.ParseError, 'invalid token', p, code)

        # Unknown variable
        code = (
            '[[model]]',
            '[a]',
            't = 10',
            '    bind time',
            '[b]',
            'use a.x as time',
            'b = time',
            '\"""',
        )
        self.assertRaisesRegex(myokit.ParseError, 'Variable not found', p,
                               code)
Ejemplo n.º 6
0
    def test_parse_model_from_stream_error(self):
        """ Quick error testing for :meth:`parse_model_from_stream`. """
        from myokit._parsing import parse_model_from_stream
        from myokit._parsing import Tokenizer

        def p(code):
            return parse_model_from_stream(Tokenizer(iter(code)))

        code = (
            '[[model]]',
            '[c]',
            't = 0 bind time',
        )
        model = p(code)
        self.assertIsInstance(model, myokit.Model)

        # Not a model
        code = (
            '[[muddle]]',
            '[c]',
            't = 0 bind time',
        )
        self.assertRaisesRegex(myokit.ParseError, r'Expecting \[\[model]]', p,
                               code)

        # Double meta-data value
        code = (
            '[[model]]',
            'ax: 1',
            'ax: 1',
        )
        self.assertRaisesRegex(myokit.ParseError, 'Duplicate meta-data key', p,
                               code)

        # Double initial values
        code = (
            '[[model]]',
            'a.x = 1',
            'a.x = 1',
        )
        self.assertRaisesRegex(myokit.ParseError, 'Duplicate initial value', p,
                               code)

        # Unused initial values
        code = (
            '[[model]]',
            'a.x = 1',
            '[c]',
            't = 0 bind time',
        )
        self.assertRaisesRegex(myokit.ParseError, 'Unused initial value', p,
                               code)
Ejemplo n.º 7
0
    def test_parse_component(self):
        """
        Test parse_component(), uses parse_variable
        """
        from myokit._parsing import parse_model as p

        # Test basics
        code = (
            '[[model]]',
            '[test]',
            't = 0',
            '    bind time',
            'x = 5 + b',
            '    b = 13',
            '    in [mV]',
            'desc: \"""',
            'This is a test component.',
            '\"""',
        )
        m = p(code)
        self.assertIn('test', m)
        self.assertEqual(
            m.get('test').meta['desc'], 'This is a test component.')

        # Test duplicate name
        code = (
            '[[model]]',
            '[test]',
            't = 0',
            '    bind time',
            '[test]',
            'x = 2',
        )
        self.assertRaisesRegex(myokit.ParseError, 'Duplicate component name',
                               p, code)

        # Test invalid name --> Handled by tokenizer

        # Test duplicate meta data key
        code = (
            '[[model]]',
            '[test]',
            'yes: no',
            't = 0',
            '    bind time',
            'yes: yes',
            '[test]',
            'x = 2',
        )
        self.assertRaisesRegex(myokit.ParseError, 'Duplicate meta-data key', p,
                               code)
Ejemplo n.º 8
0
 def test_parse_expression(self):
     """
     Test parse_expression()
     """
     from myokit import parse_expression as p
     from myokit import Number
     e = p('5')
     self.assertIsInstance(e, Number)
     self.assertEqual(e.eval(), 5.0)
     self.assertEqual(float(e), 5.0)
     e = p('5[m]')
     self.assertIsInstance(e, Number)
     self.assertEqual(e.eval(), 5.0)
     self.assertEqual(float(e), 5.0)
     self.assertEqual(e.unit(), myokit.units.m)
     e = p('5 [m/s]')
     self.assertIsInstance(e, Number)
     self.assertEqual(e.eval(), 5.0)
     self.assertEqual(float(e), 5.0)
     self.assertEqual(e.unit(), myokit.parse_unit('m/s'))
     self.assertEqual(e.unit(), myokit.units.m / myokit.units.s)
     e = p('+5')
     self.assertIsInstance(e, myokit.PrefixPlus)
     self.assertEqual(e.eval(), 5.0)
     e = p('++5')
     self.assertIsInstance(e, myokit.PrefixPlus)
     self.assertEqual(e.eval(), 5.0)
     e = p('-5')
     self.assertIsInstance(e, myokit.PrefixMinus)
     self.assertEqual(e.eval(), -5.0)
     e = p('--5')
     self.assertIsInstance(e, myokit.PrefixMinus)
     self.assertEqual(e.eval(), 5.0)
     e = p('5 + 2')
     self.assertIsInstance(e, myokit.Plus)
     self.assertEqual(e.eval(), 7)
     e = p('5 + 1 + 1')
     self.assertIsInstance(e, myokit.Plus)
     self.assertEqual(e.eval(), 7)
     e = p('5 - 2')
     self.assertIsInstance(e, myokit.Minus)
     self.assertEqual(e.eval(), 3)
     e = p('5 -- 2')
     self.assertIsInstance(e, myokit.Minus)
     self.assertEqual(e.eval(), 7)
     e = p('5 --+ 2')
     self.assertIsInstance(e, myokit.Minus)
     self.assertEqual(e.eval(), 7)
     e = p('5 --- 2')
     self.assertIsInstance(e, myokit.Minus)
     self.assertEqual(e.eval(), 3)
Ejemplo n.º 9
0
    def test_parse_unit(self):
        """ Test :meth:`parse_unit` and :meth:`parse_unit_string`. """
        from myokit._parsing import parse_unit_string as p

        # Test dimensionless
        self.assertEqual(p('1'), myokit.units.dimensionless)

        # Test bare unit
        self.assertEqual(p('V'), myokit.units.Volt)

        # Test unit with quantifier
        self.assertEqual(p('mV'), myokit.units.Volt / 1000)

        # Test multiplied units
        self.assertEqual(p('V*A'), myokit.units.Volt * myokit.units.Ampere)
        self.assertEqual(p('J/s'), myokit.units.Watt)
        self.assertEqual(p('1/s'), 1 / myokit.units.second)

        # Test units with exponents (first unit)
        self.assertEqual(p('m^2'), myokit.units.meter**2)
        self.assertEqual(p('m^-1'), 1 / myokit.units.meter)
        # Exponents on remaining units
        self.assertEqual(p('s*m^2'),
                         myokit.units.second * myokit.units.meter**2)
        self.assertEqual(p('s*m^-1'), myokit.units.second / myokit.units.meter)

        # Test units with multipliers
        self.assertEqual(p('m (123)'), myokit.units.meter * 123)

        # Test bad unit
        self.assertRaisesRegex(myokit.ParseError, 'Unit not recognized', p,
                               'michael')
        self.assertRaisesRegex(myokit.ParseError, 'Unit not recognized', p,
                               'kg/michael')
        self.assertRaisesRegex(myokit.ParseError, 'Unexpected token', p, '*2')
        self.assertRaisesRegex(myokit.ParseError, 'Invalid unit specification',
                               p, '2')
        self.assertRaisesRegex(myokit.ParseError, 'Invalid unit multiplier', p,
                               'm (x)')
Ejemplo n.º 10
0
    def test_parse_variable(self):
        """
        Test parse_variable(), uses parse_expression()
        """
        from myokit._parsing import parse_model as p

        # Test basics
        s = (
            '[[model]]',
            '[x]',
            't = 0 bind time',
        )
        t = p(s).get('x.t')
        self.assertEqual(t.name(), 't')
        self.assertEqual(t.qname(), 'x.t')
        self.assertEqual(t.unit(), None)
        self.assertEqual(t.binding(), 'time')

        s = (
            '[[model]]',
            '[x]',
            't = 0',
            '    bind time',
        )
        t = p(s).get('x.t')
        self.assertEqual(t.name(), 't')
        self.assertEqual(t.qname(), 'x.t')
        self.assertEqual(t.unit(), None)
        self.assertEqual(t.binding(), 'time')

        s = ('[[model]]', '[x]', 't = 0 bind time', 'x1 = 5')
        v = p(s).get('x.x1')
        self.assertIsInstance(v, myokit.Variable)
        self.assertTrue(v.is_constant())
        self.assertTrue(v.is_literal())
        self.assertFalse(v.is_state())
        self.assertFalse(v.is_intermediary())
        self.assertEqual(v.unit(), None)
        self.assertEqual(v.rhs().unit(), None)

        s = ('[[model]]', '[x]', 't = 0 bind time', 'x2 = 5 [mV]')
        v = p(s).get('x.x2')
        self.assertIsInstance(v, myokit.Variable)
        self.assertTrue(v.is_constant())
        self.assertTrue(v.is_literal())
        self.assertFalse(v.is_state())
        self.assertFalse(v.is_intermediary())
        self.assertEqual(v.unit(), None)
        self.assertEqual(v.rhs().unit(), myokit.parse_unit('mV'))

        s = (
            '[[model]]',
            '[x]',
            't = 0 bind time',
            'x3 = 5',
            '    in [mV]',
        )
        v = p(s).get('x.x3')
        self.assertIsInstance(v, myokit.Variable)
        self.assertTrue(v.is_constant())
        self.assertTrue(v.is_literal())
        self.assertFalse(v.is_state())
        self.assertFalse(v.is_intermediary())
        self.assertEqual(v.unit(), myokit.parse_unit('mV'))
        self.assertEqual(v.rhs().unit(), None)

        s = (
            '[[model]]',
            '[x]',
            't = 0 bind time',
            'x3 = 5 in [mV]',
        )
        v = p(s).get('x.x3')
        self.assertIsInstance(v, myokit.Variable)
        self.assertTrue(v.is_constant())
        self.assertTrue(v.is_literal())
        self.assertFalse(v.is_state())
        self.assertFalse(v.is_intermediary())
        self.assertEqual(v.unit(), myokit.parse_unit('mV'))
        self.assertEqual(v.rhs().unit(), None)

        s = (
            '[[model]]',
            '[x]',
            't = 0 bind time',
            'x4 = 5 [V] : This is x4',
        )
        v = p(s).get('x.x4')
        self.assertIsInstance(v, myokit.Variable)
        self.assertTrue(v.is_constant())
        self.assertTrue(v.is_literal())
        self.assertFalse(v.is_state())
        self.assertFalse(v.is_intermediary())
        self.assertEqual(v.unit(), None)
        self.assertEqual(v.rhs().unit(), myokit.units.V)
        self.assertEqual(v.meta['desc'], 'This is x4')

        code = (
            '[[model]]',
            '[x]',
            't = 0 bind time',
            'x = 5 label vvv',
        )
        x = p(code).get('x.x')
        self.assertIsInstance(x, myokit.Variable)
        self.assertEqual(x.label(), 'vvv')

        s = (
            '[[model]]',
            '[x]',
            't = 0 bind time',
            'x = 5',
            '    label vvv',
        )
        x = p(code).get('x.x')
        self.assertIsInstance(x, myokit.Variable)
        self.assertEqual(x.label(), 'vvv')

        # Illegal lhs
        code = (
            '[[model]]',
            '[x]',
            't = 0 bind time',
            'sin(x) = 5',
        )
        self.assertRaisesRegex(myokit.ParseError, 'variable names or the dot',
                               p, code)

        # Duplicate name
        code = (
            '[[model]]',
            '[x]',
            't = 0 bind time',
            'x = 5',
            'x = 5',
        )
        self.assertRaisesRegex(myokit.ParseError, 'Duplicate var', p, code)

        # Missing initial value
        code = (
            '[[model]]',
            '[x]',
            't = 0 bind time',
            'dot(x) = 5',
        )
        self.assertRaisesRegex(myokit.ParseError, 'Missing initial', p, code)

        # Duplicate meta
        code = (
            '[[model]]',
            '[x]',
            't = 0 bind time',
            '    yes: really',
            '    yes: no',
        )
        self.assertRaisesRegex(myokit.ParseError, 'Duplicate meta-data key', p,
                               code)

        # Duplicate unit
        code = (
            '[[model]]',
            '[x]',
            't = 0 bind time',
            '    in [s]',
            '    in [s]',
        )
        self.assertRaisesRegex(myokit.ParseError, 'Duplicate variable unit', p,
                               code)
Ejemplo n.º 11
0
    def test_parse_expression(self):
        # Test parse_expression()
        from myokit import parse_expression as p
        from myokit import Number
        e = p('5')
        self.assertIsInstance(e, Number)
        self.assertEqual(e.eval(), 5.0)
        self.assertEqual(float(e), 5.0)
        e = p('5[m]')
        self.assertIsInstance(e, Number)
        self.assertEqual(e.eval(), 5.0)
        self.assertEqual(float(e), 5.0)
        self.assertEqual(e.unit(), myokit.units.m)
        e = p('5 [m/s]')
        self.assertIsInstance(e, Number)
        self.assertEqual(e.eval(), 5.0)
        self.assertEqual(float(e), 5.0)
        self.assertEqual(e.unit(), myokit.parse_unit('m/s'))
        self.assertEqual(e.unit(), myokit.units.m / myokit.units.s)
        e = p('+5')
        self.assertIsInstance(e, myokit.PrefixPlus)
        self.assertEqual(e.eval(), 5.0)
        e = p('++5')
        self.assertIsInstance(e, myokit.PrefixPlus)
        self.assertEqual(e.eval(), 5.0)
        e = p('-5')
        self.assertIsInstance(e, myokit.PrefixMinus)
        self.assertEqual(e.eval(), -5.0)
        e = p('--5')
        self.assertIsInstance(e, myokit.PrefixMinus)
        self.assertEqual(e.eval(), 5.0)
        e = p('5 + 2')
        self.assertIsInstance(e, myokit.Plus)
        self.assertEqual(e.eval(), 7)
        e = p('5 + 1 + 1')
        self.assertIsInstance(e, myokit.Plus)
        self.assertEqual(e.eval(), 7)
        e = p('5 - 2')
        self.assertIsInstance(e, myokit.Minus)
        self.assertEqual(e.eval(), 3)
        e = p('5 -- 2')
        self.assertIsInstance(e, myokit.Minus)
        self.assertEqual(e.eval(), 7)
        e = p('5 --+ 2')
        self.assertIsInstance(e, myokit.Minus)
        self.assertEqual(e.eval(), 7)
        e = p('5 --- 2')
        self.assertIsInstance(e, myokit.Minus)
        self.assertEqual(e.eval(), 3)
        # Etc etc etc

        # Test bad value
        self.assertRaises(myokit.ParseError, p, '5 beans')