Beispiel #1
0
    def test_unique_names_1(self):
        # Test Model.create_unique_names().

        # Heavily disputed variable names
        m = myokit.Model()
        a = m.add_component('a')
        ax = a.add_variable('x')
        b = m.add_component('b')
        bx = b.add_variable('x')
        x = m.add_component('x')
        xx = x.add_variable('x')
        m.create_unique_names()
        self.assertEqual(a.uname(), 'a')
        self.assertEqual(ax.uname(), 'a_x')
        self.assertEqual(b.uname(), 'b')
        self.assertEqual(bx.uname(), 'b_x')
        self.assertEqual(x.uname(), 'x_1')
        self.assertEqual(xx.uname(), 'x_x')

        # Disputed variable name --> Generated name already exists
        m = myokit.Model()
        a = m.add_component('a')
        ax = a.add_variable('x')
        abx = a.add_variable('b_x')
        aax = a.add_variable('a_x')
        ax11 = a.add_variable('x_1_1')
        b = m.add_component('b')
        bx = b.add_variable('x')
        bx11 = b.add_variable('x_1_1')
        m.create_unique_names()
        self.assertEqual(a.uname(), 'a')
        self.assertEqual(ax.uname(), 'a_x_1')
        self.assertEqual(abx.uname(), 'b_x')
        self.assertEqual(aax.uname(), 'a_x')
        self.assertEqual(ax11.uname(), 'a_x_1_1')
        self.assertEqual(b.uname(), 'b')
        self.assertEqual(bx.uname(), 'b_x_1')
        self.assertEqual(bx11.uname(), 'b_x_1_1')

        # Disputed component name
        m = myokit.Model()
        a = m.add_component('a')
        a.add_variable('x')
        m.add_component('x')
        m.create_unique_names()
        self.assertEqual(m.get('a').uname(), 'a')
        self.assertEqual(m.get('a.x').uname(), 'a_x')
        self.assertEqual(m.get('x').uname(), 'x_1')

        # Disputed component name --> Generated name already exists
        m = myokit.Model()
        a = m.add_component('a')
        a.add_variable('x')
        m.add_component('x')
        m.add_component('x_1')
        m.create_unique_names()
        self.assertEqual(m.get('a').uname(), 'a')
        self.assertEqual(m.get('a.x').uname(), 'a_x')
        self.assertEqual(m.get('x').uname(), 'x_2')
        self.assertEqual(m.get('x_1').uname(), 'x_1')
    def create_myokit_model(self):
        if self.pk_model is None:
            pk_model = myokit.Model()
        else:
            pk_model = self.create_myokit_dosed_pk_model()
        if self.pd_model is None:
            pd_model = myokit.Model()
        else:
            pd_model = self.pd_model.create_myokit_model()
        have_both_models = (self.pk_model is not None
                            and self.pd_model is not None)
        have_no_models = (self.pk_model is None and self.pd_model is None)

        # use pk model as the base and import the pd model
        pkpd_model = pk_model

        # default model is one with just time
        if have_no_models:
            pkpd_model = myokit.parse_model('''
            [[model]]
            [myokit]
            time = 0 [s] bind time
                in [s]
        ''')

        # remove time binding if
        if have_both_models:
            time_var = pd_model.get('myokit.time')
            time_var.set_binding(None)

        pd_components = list(pd_model.components())
        pd_names = [c.name().replace('myokit', 'PD') for c in pd_components]

        if pd_components:
            pkpd_model.import_component(
                pd_components,
                new_name=pd_names,
            )

        # remove imported time var
        if have_both_models:
            imported_pd_component = pkpd_model.get('PD')
            imported_time = imported_pd_component.get('time')
            imported_pd_component.remove_variable(imported_time)

        # do mappings
        for mapping in self.mappings.all():
            pd_var = pkpd_model.get(
                mapping.pd_variable.qname.replace('myokit', 'PD'))
            pk_var = pkpd_model.get(mapping.pk_variable.qname)

            unit_conversion_multiplier = myokit.Unit.conversion_factor(
                pk_var.unit(), pd_var.unit())
            pd_var.set_rhs(
                myokit.Multiply(myokit.Number(unit_conversion_multiplier),
                                myokit.Name(pk_var)))

        pkpd_model.validate()
        return pkpd_model
Beispiel #3
0
    def test_promote_demote(self):
        # Test variable promotion and demotion.

        m = myokit.Model()
        c = m.add_component('c')
        v = c.add_variable('v')
        v.set_rhs(3)

        self.assertTrue(v.is_literal())
        self.assertTrue(v.is_constant())
        self.assertFalse(v.is_intermediary())
        self.assertFalse(v.is_state())
        self.assertEqual(v.lhs(), myokit.Name(v))
        self.assertRaises(Exception, v.demote)
        self.assertRaises(Exception, v.indice)
        self.assertRaises(Exception, v.state_value)

        v.promote(3)
        self.assertFalse(v.is_literal())
        self.assertFalse(v.is_constant())
        self.assertFalse(v.is_intermediary())
        self.assertTrue(v.is_state())
        self.assertEqual(v.lhs(), myokit.Derivative(myokit.Name(v)))
        self.assertEqual(v.indice(), 0)
        self.assertEqual(v.state_value(), 3)

        v.demote()
        self.assertTrue(v.is_literal())
        self.assertTrue(v.is_constant())
        self.assertFalse(v.is_intermediary())
        self.assertFalse(v.is_state())
        self.assertEqual(v.lhs(), myokit.Name(v))
        self.assertRaises(Exception, v.demote)
        self.assertRaises(Exception, v.indice)
        self.assertRaises(Exception, v.state_value)

        # Test errors
        v.promote(3)
        self.assertRaisesRegex(Exception, 'already', v.promote, 4)
        v.demote()
        v.set_binding('time')
        self.assertRaisesRegex(Exception, 'cannot be bound', v.promote, 4)
        w = v.add_variable('w')
        self.assertRaisesRegex(
            Exception, 'only be added to Components', w.promote, 4)

        # Test we can't demote a variable with references to its derivative
        m = myokit.Model()
        c = m.add_component('c')
        x = c.add_variable('x')
        x.set_rhs(3)
        x.promote()
        y = c.add_variable('y')
        y.set_rhs('1 + dot(x)')
        self.assertRaisesRegex(
            Exception, 'references to its derivative', x.demote)
        y.set_rhs('1 + x')
        x.demote()
Beispiel #4
0
 def test_multiline_string_indent(self):
     """
     Test what happens when you load save a string that gets auto-indented.
     """
     # Create model with multi-line meta-data property
     d1 = 'First line\n\nSecond line'
     m1 = myokit.Model()
     m1.meta['desc'] = d1
     e = m1.add_component('engine')
     v = e.add_variable('time')
     v.set_binding('time')
     v.set_rhs(0)
     # Store to disk
     with TemporaryDirectory() as d:
         opath = d.path('multiline.mmt')
         myokit.save_model(opath, m1)
         # Load and compare the meta-data string
         m2 = myokit.load_model(opath)
         d2 = m2.meta['desc']
         self.assertEqual(d1, d2)
     # Create model with indented multi-line meta-data property
     d1 = '  First line\n\n  Second line'
     dr = 'First line\n\nSecond line'
     m1 = myokit.Model()
     m1.meta['desc'] = d1
     e = m1.add_component('engine')
     v = e.add_variable('time')
     v.set_binding('time')
     v.set_rhs(0)
     # Store to disk
     with TemporaryDirectory() as d:
         opath = d.path('multiline.mmt')
         myokit.save_model(opath, m1)
         # Load and compare the meta-data string
         m2 = myokit.load_model(opath)
         d2 = m2.meta['desc']
         self.assertEqual(d2, dr)
     # Create model with strangely indented multi-line meta-data property
     d1 = '  First line\n\n   Second line'
     dr = 'First line\n\n Second line'
     m1 = myokit.Model()
     m1.meta['desc'] = d1
     e = m1.add_component('engine')
     v = e.add_variable('time')
     v.set_binding('time')
     v.set_rhs(0)
     # Store to disk
     with TemporaryDirectory() as d:
         opath = d.path('multiline.mmt')
         myokit.save_model(opath, m1)
         # Load and compare the meta-data string
         m2 = myokit.load_model(opath)
         d2 = m2.meta['desc']
         self.assertEqual(d2, dr)
    def test_version_selection(self):
        # Test choosing between CellML versions

        e = formats.exporter('cellml')
        model = myokit.Model('hello')
        t = model.add_component('env').add_variable('time')
        t.set_binding('time')
        t.set_rhs(0)

        # Write to 1.0 model
        with TemporaryDirectory() as d:
            path = d.path('test.cellml')
            e.model(path, model, version='1.0')
            with open(path, 'r') as f:
                self.assertIn('cellml/1.0#', f.read())

        # Write to 1.1 model
        with TemporaryDirectory() as d:
            path = d.path('test.cellml')
            e.model(path, model, version='1.1')
            with open(path, 'r') as f:
                self.assertIn('cellml/1.1#', f.read())

        # Write to 2.0 model
        with TemporaryDirectory() as d:
            path = d.path('test.cellml')
            e.model(path, model, version='2.0')
            with open(path, 'r') as f:
                self.assertIn('cellml/2.0#', f.read())
Beispiel #6
0
    def test_basic(self):
        """
        Test the basic meta-data functionality
        """
        # Test assignment with simple and namespaced names
        m = myokit.Model()
        m.meta['bert'] = 'ernie'
        m.meta['bert:ernie'] = 'banaan'

        def f():
            m.meta['bert.ernie'] = 'banaan'

        self.assertRaises(myokit.InvalidMetaDataNameError, f)

        def f():
            m.meta['bert '] = 'banaan'

        self.assertRaises(myokit.InvalidMetaDataNameError, f)

        # Test retrieval
        self.assertEqual(m.meta['bert'], 'ernie')
        self.assertEqual(m.meta['bert:ernie'], 'banaan')

        def f():
            return m.meta['bert.ernie']

        self.assertRaises(myokit.InvalidMetaDataNameError, f)

        # Test overwriting
        m.meta['bert'] = 'verrekijker'
        self.assertEqual(m.meta['bert'], 'verrekijker')

        # Test deletion
        del (m.meta['bert'])
        self.assertRaises(KeyError, lambda: m.meta['bert'])
    def test_creation(self):
        # Test Benchmarker creation.
        # Create test model
        m = myokit.Model('test')
        c = m.add_component('c')
        t = c.add_variable('time')
        t.set_rhs('0')
        t.set_binding('time')
        v = c.add_variable('V')
        v.set_rhs('0')
        v.promote(-80.1)
        x = c.add_variable('x')
        x.set_rhs('exp(V)')
        y = c.add_variable('y')
        y.set_rhs(3)
        m.validate()

        # Create benchmarker without variables
        myokit.RhsBenchmarker(m)

        # Create with objects
        myokit.RhsBenchmarker(m, [x])

        # Create with strings
        myokit.RhsBenchmarker(m, ['c.x'])

        # Cannot create with constants
        self.assertRaisesRegex(ValueError, 'constant', myokit.RhsBenchmarker,
                               m, [y])

        # Cannot create with bound variables
        self.assertRaisesRegex(ValueError, 'bound', myokit.RhsBenchmarker, m,
                               [t])
    def test_simple(self):
        # Test basic functionality.

        # Create test model
        m = myokit.Model('test')
        c = m.add_component('c')
        t = c.add_variable('time')
        t.set_rhs('0')
        t.set_binding('time')
        v = c.add_variable('V')
        v.set_rhs('0')
        v.promote(-80.1)
        x = c.add_variable('x')
        x.set_rhs('exp(V)')
        m.validate()

        # Create simulation log
        log = myokit.DataLog()
        log['c.time'] = np.zeros(10)
        log['c.V'] = np.linspace(-80.0, 50.0, 10)

        # Number of repeats
        repeats = 10

        # Run
        x.set_rhs('1 / (7 * exp((V + 12) / 35) + 9 * exp(-(V + 77) / 6))')
        b = myokit.RhsBenchmarker(m, [x])
        t = b.bench_full(log, repeats)
        t = b.bench_part(log, repeats)
        # No errors = pass

        # Get mean and std after outlier removal
        mean = b.mean(t)
        mean, std = b.mean_std(t)
Beispiel #9
0
    def test_add_alias_errors(self):
        # Test error handling in :meth:`Component.add_alias()`.
        m = myokit.Model()
        c = m.add_component('c')
        x = c.add_variable('x')
        d = m.add_component('d')
        y = d.add_variable('y')
        z = y.add_variable('z')

        # Duplicate name
        d.add_alias('great_name', x)
        self.assertRaises(myokit.DuplicateName, d.add_alias, 'y', x)

        # Alias for a nested variable
        c.add_alias('not_a_problem', y)
        self.assertRaisesRegex(myokit.IllegalAliasError, 'whose parent',
                               c.add_alias, 'xyz', z)

        # Alias for a variable in the same component
        self.assertRaisesRegex(myokit.IllegalAliasError, 'same component',
                               c.add_alias, 'zz', x)

        # Alias for a component
        self.assertRaisesRegex(myokit.IllegalAliasError, 'for variables',
                               c.add_alias, 'zz', c)
Beispiel #10
0
    def test_alias_methods(self):
        # Test various methods to do with aliases.

        # Proper use of add_alias
        m = myokit.Model()
        c1 = m.add_component('c1')
        a = c1.add_variable('a')
        a.set_rhs(2)
        c2 = m.add_component('c2')
        c2.add_alias('bert', a)
        b = c2.add_variable('b')
        b.set_rhs('3 * bert')
        self.assertEqual(b.eval(), 6)

        # Test alias() and alias_for(), remove_alias()
        self.assertTrue(c2.has_alias('bert'))
        self.assertTrue(c2.has_alias_for(a))
        self.assertEqual(c2.alias('bert'), a)
        self.assertEqual(c2.alias_for(a), 'bert')
        c2.remove_alias('bert')
        self.assertFalse(c2.has_alias('bert'))
        self.assertFalse(c2.has_alias_for(a))
        self.assertRaises(KeyError, c2.alias, 'bert')
        self.assertRaises(KeyError, c2.alias_for, a)
        c2.add_alias('bert', a)
        c2.add_alias('ernie', a)
        c2.add_alias('hello', a)
        self.assertTrue(c2.has_alias_for(a))
        c2.remove_alias('bert')
        self.assertTrue(c2.has_alias_for(a))
        c2.remove_aliases_for(a)
        self.assertFalse(c2.has_alias_for(a))
Beispiel #11
0
    def test_default_protocol(self):
        # Test default_protocol()

        # Test default version
        protocol = myokit.default_protocol()
        self.assertTrue(isinstance(protocol, myokit.Protocol))
        self.assertEqual(protocol.head().period(), 1000)

        # Test adapting the time unit
        model = myokit.Model()
        t = model.add_component('c').add_variable('t')
        t.set_rhs(0)
        protocol = myokit.default_protocol(model)
        self.assertTrue(isinstance(protocol, myokit.Protocol))
        self.assertEqual(protocol.head().period(), 1000)

        t.set_binding('time')
        protocol = myokit.default_protocol(model)
        self.assertTrue(isinstance(protocol, myokit.Protocol))
        self.assertEqual(protocol.head().period(), 1000)

        t.set_unit('s')
        protocol = myokit.default_protocol(model)
        self.assertTrue(isinstance(protocol, myokit.Protocol))
        self.assertEqual(protocol.head().period(), 1)

        t.set_unit('ms')
        protocol = myokit.default_protocol(model)
        self.assertTrue(isinstance(protocol, myokit.Protocol))
        self.assertEqual(protocol.head().period(), 1000)
Beispiel #12
0
 def __init__(self, name=None):
     self._model = myokit.Model()
     self._roa_set = False  # Route of administration
     self._dose_comp = None
     self._depot_comp = None
     self._dose_rate = None
     self._regimen = None
Beispiel #13
0
    def test_read_write(self):
        # Test using the read() and write() methods
        try:
            import sympy as sp
        except ImportError:
            print('Sympy not found, skipping test.')
            return

        # Test writing and reading with a model
        a = self._a
        ca = sp.Symbol('c.a')
        self.assertEqual(mypy.write(a), ca)
        self.assertEqual(mypy.read(ca, self._model), a)

        # Test doing it again, with a different model
        m = myokit.Model()
        a = m.add_component('cc').add_variable('aa')
        a = myokit.Name(a)
        ca = sp.Symbol('cc.aa')
        self.assertEqual(mypy.write(a), ca)
        self.assertEqual(mypy.read(ca, m), a)

        # Test reading without a model
        b = myokit.Number('12')
        cb = sp.Float(12)
        self.assertEqual(mypy.write(b), cb)
        self.assertEqual(mypy.read(cb), b)
Beispiel #14
0
    def test_set_state_value(self):
        # Test :meth:`Variable.set_state_value()`.

        m = myokit.Model()
        c = m.add_component('c')
        v = c.add_variable('v')
        w = c.add_variable('w')

        # Test basic functionality
        v.promote(10)
        self.assertEqual(v.state_value(), 10)
        v.set_state_value(12)
        self.assertEqual(v.state_value(), 12)

        # Only states have this option
        v.demote()
        self.assertRaisesRegex(
            Exception, 'Only state variables', v.set_state_value, 3)
        self.assertRaisesRegex(
            Exception, 'Only state variables', w.set_state_value, 3)

        # State values must be literals
        v.promote(3)
        self.assertRaises(
            myokit.NonLiteralValueError, v.set_state_value, w.lhs())
Beispiel #15
0
    def test_is_referenced(self):
        # Test :meth:`Variable.is_referenced().

        m = myokit.Model()
        c = m.add_component('c')
        v = c.add_variable('v')
        v.set_rhs(3)
        w = c.add_variable('w')
        w.set_rhs(4)

        self.assertFalse(v.is_referenced())
        self.assertFalse(w.is_referenced())
        v.set_rhs('3 * w')
        self.assertFalse(v.is_referenced())
        self.assertTrue(w.is_referenced())
        w.set_rhs('2 * v')
        self.assertTrue(v.is_referenced())
        self.assertTrue(w.is_referenced())

        z = c.add_variable('z')
        z.set_rhs('3 * v')
        self.assertFalse(z.is_referenced())
        self.assertTrue(v.is_referenced())
        w.set_rhs(1)
        self.assertTrue(v.is_referenced())
        z.set_rhs(2)
        self.assertFalse(v.is_referenced())
Beispiel #16
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
Beispiel #17
0
    def test_varowner_get(self):
        # Test VarOwner.get().

        # Test basics
        m = myokit.Model('test')
        c = m.add_component('c')
        x = c.add_variable('x')
        self.assertIs(m.get('c'), c)
        self.assertIs(m.get('c.x'), x)
        self.assertIs(c.get('x'), x)

        # Test asking for object
        self.assertIs(m.get(c), c)
        self.assertIs(m.get(x), x)
        self.assertIs(c.get(x), x)
        self.assertIs(x.get(c), c)

        # Test not founds
        self.assertRaises(KeyError, m.get, 'y')
        self.assertRaises(KeyError, m.get, 'c.y')
        self.assertRaises(KeyError, c.get, 'y')

        # Test class filter
        self.assertIs(m.get('c', myokit.Component), c)
        self.assertRaises(KeyError, m.get, 'c', myokit.Variable)
        self.assertIs(m.get('c.x', myokit.Variable), x)
        self.assertIs(c.get('x', myokit.Variable), x)
        self.assertRaises(KeyError, m.get, 'c.x', myokit.Component)
        self.assertRaises(KeyError, c.get, 'x', myokit.Component)
Beispiel #18
0
    def test_binding(self):
        # Tests setting and getting of bindings

        # Note that set_binding() is part of Variable, so not tested here
        m = myokit.Model()
        c = m.add_component('c')
        x = c.add_variable('x')
        x.set_binding('hello')
        y = c.add_variable('y')
        y.set_binding('goodbye')
        z = c.add_variable('z')
        z.set_binding('x')

        # Test binding()
        self.assertEqual(m.binding('goodbye'), y)
        self.assertEqual(m.binding('hello'), x)
        self.assertEqual(m.binding('x'), z)
        self.assertEqual(m.binding('y'), None)

        # Test bindings()
        bindings = dict(m.bindings())
        self.assertEqual(bindings['goodbye'], y)
        self.assertEqual(bindings['hello'], x)
        self.assertEqual(bindings['x'], z)
        self.assertFalse('y' in bindings)

        # Test bindingx()
        self.assertEqual(m.bindingx('goodbye'), y)
        self.assertEqual(m.bindingx('hello'), x)
        self.assertEqual(m.bindingx('x'), z)
        self.assertRaisesRegex(myokit.IncompatibleModelError,
                               'No variable found with binding "y"',
                               m.bindingx, 'y')
Beispiel #19
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')
Beispiel #20
0
    def test_labels(self):
        # Test setting labels and :meth:`Model.labels()`.

        # Test set_label() and labels()
        m = myokit.Model()
        c = m.add_component('c')
        t = c.add_variable('time')
        t.set_binding('time')
        t.set_rhs(0)
        v = c.add_variable('v')
        v.set_rhs('3 - v')
        v.set_label('membrane_potential')
        w = c.add_variable('w')
        w.set_rhs(1)
        x = c.add_variable('x')
        x.set_rhs(1)
        labels = list(m.labels())
        self.assertEqual(len(labels), 1)
        self.assertEqual(labels[0][0], 'membrane_potential')
        self.assertEqual(labels[0][1], v)

        # Can't have two labels
        self.assertRaisesRegex(myokit.InvalidLabelError, 'already has a label',
                               v.set_label, 'bert')

        # No two variables can have the same label
        self.assertRaisesRegex(myokit.InvalidLabelError, 'already in use',
                               w.set_label, 'membrane_potential')

        # Labels can't overlap with bindings
        self.assertRaisesRegex(myokit.InvalidLabelError, 'in use as a binding',
                               w.set_label, 'time')
Beispiel #21
0
    def test_eval_state_derivatives(self):
        # Test Model.eval_state_derivatives().
        model = myokit.Model('m')
        component = model.add_component('comp1')
        t = component.add_variable('time')
        t.set_binding('time')
        t.set_rhs(1)
        a = component.add_variable('a')
        b = component.add_variable('b')
        c = component.add_variable('c')
        a.promote(1)
        a.set_rhs('1')
        b.promote(2)
        b.set_rhs('2 * b')
        c.promote(3)
        c.set_rhs('b + c')
        model.validate()
        self.assertEqual(model.eval_state_derivatives(), [1, 4, 5])
        self.assertEqual(model.eval_state_derivatives(state=[1, 1, 2]),
                         [1, 2, 3])
        c.set_rhs('b + c + time')
        self.assertEqual(model.eval_state_derivatives(), [1, 4, 6])
        self.assertEqual(
            model.eval_state_derivatives(state=[1, 1, 2], inputs={'time': 0}),
            [1, 2, 3])

        # Errors
        c.set_rhs('(b + c) / 0')
        self.assertRaises(myokit.NumericalError, model.eval_state_derivatives)
        nan = model.eval_state_derivatives(ignore_errors=True)[2]
        self.assertNotEqual(nan, nan)  # x != x is a nan test...
Beispiel #22
0
    def test_add_function(self):
        # Test the ``Model.add_function`` method.

        m = myokit.Model('m')
        c = m.add_component('c')
        x = c.add_variable('x')

        # Test basics
        m.add_function('f', ('a', 'b', 'c'), 'a + b + c')
        x.set_rhs('f(1, 2, 3)')
        self.assertEqual(x.eval(), 6)

        # Test duplicate name
        # Different number of arguments is allowed:
        m.add_function('f', ('a', 'b'), 'a + b')
        self.assertRaisesRegex(myokit.DuplicateFunctionName, 'already defined',
                               m.add_function, 'f', ('a', 'b'), 'a - b')

        # Test duplicate argument name
        self.assertRaisesRegex(myokit.DuplicateFunctionArgument,
                               'already in use', m.add_function, 'g',
                               ('a', 'a'), 'a + a')

        # Dot operator is not allowed
        self.assertRaisesRegex(myokit.InvalidFunction, r'dot\(\) operator',
                               m.add_function, 'fdot', ('a', ), 'dot(a)')

        # Unused argument
        self.assertRaisesRegex(myokit.InvalidFunction, 'never used',
                               m.add_function, 'fun', ('a', 'b'), 'a')

        # Unspecified variable
        self.assertRaisesRegex(myokit.InvalidFunction, 'never declared',
                               m.add_function, 'fun', ('a', ), 'a + b')
Beispiel #23
0
    def test_validate_and_remove_unused_variables(self):
        # Test :class:`Model.validate` with ``remove_unused_variables=True``.

        m = myokit.Model()
        c = m.add_component('c')
        t = c.add_variable('time')
        t.set_binding('time')
        t.set_rhs(0)
        x = c.add_variable('x')
        y = c.add_variable('y')
        z = c.add_variable('z')
        z1 = z.add_variable('z1')
        x.set_rhs('(10 - x) / y')
        x.promote(0)
        y.set_rhs(1)
        z.set_rhs('2 + z1')
        z1.set_rhs(3)

        # Two unused variables: z and z1
        m.validate()
        self.assertEqual(len(m.warnings()), 2)

        # Remove unused variables
        m.validate(remove_unused_variables=True)
        self.assertEqual(len(m.warnings()), 2)  # 2 removal warnings
        m.validate()
        self.assertEqual(len(m.warnings()), 0)  # issue fixed!
Beispiel #24
0
    def test_warnings(self):
        # Test Model.has_warnings(), model.warnings() and
        # Model.format_warnings().

        # Test model without warnings
        m = myokit.Model()
        c = m.add_component('c')
        t = c.add_variable('time')
        t.set_binding('time')
        t.set_rhs(0)
        v = c.add_variable('v')
        v.set_rhs('3 - v')
        v.promote(0.1)
        m.validate()

        self.assertFalse(m.has_warnings())
        self.assertIn('0 validation warning', m.format_warnings())
        self.assertEqual(m.warnings(), [])

        # Test model with warnings
        v.validate()
        v.demote()
        v.validate()
        v.set_rhs(3)
        m.validate()

        self.assertTrue(m.has_warnings())
        self.assertIn('1 validation warning', m.format_warnings())
        self.assertIn('Unused variable', str(m.warnings()[0]))
Beispiel #25
0
    def test_suggest(self):
        # Test :meth:`Model.suggest(variable_name)`.

        m = myokit.Model()
        c1 = m.add_component('c1')
        t = c1.add_variable('time')
        t.set_binding('time')
        t.set_rhs(0)
        c2 = m.add_component('c2')
        v = c2.add_variable('v')
        v.set_rhs('3')

        # Test with correct name
        found, suggested, msg = m.suggest_variable('c1.time')
        self.assertEqual(found, t)
        self.assertIsNone(suggested)
        self.assertIsNone(msg)

        # Test with wrong name
        found, suggested, msg = m.suggest_variable('c1.tim')
        self.assertIsNone(found)
        self.assertEqual(suggested, t)
        self.assertIn('Unknown', msg)

        # Test with case mismatch
        found, suggested, msg = m.suggest_variable('c1.timE')
        self.assertIsNone(found)
        self.assertEqual(suggested, t)
        self.assertIn('Case mismatch', msg)

        # Test without component
        found, suggested, msg = m.suggest_variable('time')
        self.assertIsNone(found)
        self.assertEqual(suggested, t)
        self.assertIn('No component', msg)
Beispiel #26
0
    def test_bindings(self):
        # Test setting bindings and :meth:`Model.bindings()`.

        # Test set_binding() and bindings()
        m = myokit.Model()
        c = m.add_component('c')
        t = c.add_variable('time')
        t.set_binding('time')
        t.set_rhs(0)
        v = c.add_variable('v')
        v.set_rhs('3 - v')
        w = c.add_variable('w')
        w.set_rhs(0)
        bindings = list(m.bindings())
        self.assertEqual(len(bindings), 1)
        self.assertEqual(bindings[0][0], 'time')
        self.assertEqual(bindings[0][1], t)

        # Can't have two labels
        self.assertRaisesRegex(myokit.InvalidBindingError, 'already bound to',
                               t.set_binding, 'bert')

        # No two variables can have the same label
        self.assertRaisesRegex(myokit.InvalidBindingError, 'Duplicate binding',
                               v.set_binding, 'time')

        # Binding can't overlap with label
        v.set_label('membrane_potential')
        self.assertRaisesRegex(myokit.InvalidBindingError, 'in use as a label',
                               w.set_binding, 'membrane_potential')

        # State variables can't be bound
        v.promote(0)
        self.assertRaisesRegex(myokit.InvalidBindingError, 'State variables',
                               v.set_binding, 'x')
Beispiel #27
0
    def test_reorder_state(self):
        # Test :meth:`Model.reorder_state()`.

        m = myokit.Model()
        c = m.add_component('c')
        t = c.add_variable('time')
        t.set_binding('time')
        t.set_rhs(0)
        v = c.add_variable('v')
        v.set_rhs('3 - v')
        v.promote(0)
        w = c.add_variable('w')
        w.set_rhs(1)
        w.promote(0)
        self.assertEqual(list(m.states()), [v, w])
        m.reorder_state([w, v])
        self.assertEqual(list(m.states()), [w, v])
        m.reorder_state([w, v])
        self.assertEqual(list(m.states()), [w, v])
        m.reorder_state([v, w])
        self.assertEqual(list(m.states()), [v, w])

        # Wrong number of states
        self.assertRaisesRegex(ValueError, 'number of entries',
                               m.reorder_state, [v])
        self.assertRaisesRegex(ValueError, 'number of entries',
                               m.reorder_state, [v, w, v])

        # Duplicate entries
        self.assertRaisesRegex(ValueError, 'Duplicate', m.reorder_state,
                               [v, v])

        # Not a state
        self.assertRaisesRegex(ValueError, 'must all be', m.reorder_state,
                               [v, t])
Beispiel #28
0
    def test_no_time_variable(self):
        # Test an exception is raised if nothing is bound to time.

        m = myokit.Model('LotkaVolterra')
        c0 = m.add_component('c0')
        t = c0.add_variable('time')
        t.set_rhs(myokit.Number(0))
        self.assertRaises(myokit.MissingTimeVariableError, m.validate)
Beispiel #29
0
    def test_value(self):
        # Test :meth:`Variable.value()`.

        m = myokit.Model()
        c = m.add_component('c')
        v = c.add_variable('v')
        v.set_rhs('1 + 2 + 3 + 4')
        self.assertEqual(v.value(), 10)
Beispiel #30
0
    def test_pacing_values_at_event_transitions(self):
        # Tests the value of the pacing signal at event transitions

        # Create a simple model
        m = myokit.Model()
        c = m.add_component('c')
        t = c.add_variable('t')
        t.set_rhs(0)
        t.set_binding('time')
        v = c.add_variable('v')
        v.set_rhs('0')
        v.set_binding('pace')
        x = c.add_variable('x')
        x.set_rhs(0.1)
        x.promote(0)

        # Create step protocol
        p = myokit.Protocol()
        p.schedule(0, 0, 2)
        p.schedule(1, 2, 2)
        p.schedule(2, 4, 4)
        p.schedule(3, 8, 2)

        # Simulate with dynamic logging
        s = myokit.LegacySimulation(m, p)
        d = s.run(p.characteristic_time())
        time = list(d.time())
        value = list(d['c.v'])

        if False:
            for i, t in enumerate(d.time()):
                t = str(np.round(t, 5))
                print(t + ' ' * (10 - len(t)) + str(d['c.v'][i]))

        # Values should be
        #   t   0   1   2   3   4   5   6   7   8   9   10
        #   p   0   0   1   1   2   2   2   2   3   3   0
        self.assertEqual(value[time.index(0.0)], 0)
        self.assertEqual(value[time.index(0.0) + 1], 0)
        self.assertEqual(value[time.index(2.0) - 1], 0)
        self.assertEqual(value[time.index(2.0)], 1)
        self.assertEqual(value[time.index(2.0) + 1], 1)
        self.assertEqual(value[time.index(4.0) - 1], 1)
        self.assertEqual(value[time.index(4.0)], 2)
        self.assertEqual(value[time.index(4.0) + 1], 2)
        self.assertEqual(value[time.index(8.0) - 1], 2)
        self.assertEqual(value[time.index(8.0)], 3)
        self.assertEqual(value[time.index(8.0) + 1], 3)
        self.assertEqual(value[time.index(10.0) - 1], 3)
        self.assertEqual(value[time.index(10.0)], 0)

        # Simulate with fixed logging
        s.reset()
        d = s.run(p.characteristic_time() + 1, log_times=d.time())
        time2 = list(d.time())
        value2 = list(d['c.v'])
        self.assertEqual(time, time2)
        self.assertEqual(value, value2)