def test_units(self): # Test writing of units u1 = myokit.parse_unit('kg*m^2/mole^3 (0.123)') u2 = myokit.parse_unit('1 (4.56)') m1 = cellml.Model('mmm') m1.add_units('flibbit', u1) m1.add_units('special_volt', myokit.units.Volt) c = m1.add_component('ccc') c.add_units('flibbit', u2) p = c.add_variable('p', 'flibbit') p.set_rhs(myokit.Number(1, u2)) d = m1.add_component('ddd') q = d.add_variable('q', 'flibbit') q.set_rhs(myokit.Number(2, u1)) xml = cellml.write_string(m1) m2 = cellml.parse_string(xml) p, q = m2['ccc']['p'], m2['ddd']['q'] self.assertEqual(p.units().name(), 'flibbit') self.assertEqual(q.units().name(), 'flibbit') self.assertEqual(p.units().myokit_unit(), u2) self.assertEqual(q.units().myokit_unit(), u1) self.assertEqual( m2.find_units('special_volt').myokit_unit(), myokit.units.volt)
def test_versions(self): # Tests writing different CellML versions # CellML 1.0 units = { myokit.parse_unit('pF'): 'picofarad', } w = cellml.CellMLExpressionWriter('1.0') w.set_unit_function(lambda x: units[x]) xml = w.ex(myokit.Number(1, myokit.units.pF)) self.assertIn(cellml.NS_CELLML_1_0, xml) # CellML 1.1 w = cellml.CellMLExpressionWriter('1.1') w.set_unit_function(lambda x: units[x]) xml = w.ex(myokit.Number(1, myokit.units.pF)) self.assertIn(cellml.NS_CELLML_1_1, xml) # CellML 1.2 self.assertRaisesRegex(ValueError, 'Unknown CellML version', cellml.CellMLExpressionWriter, '1.2') # CellML 2.0 w = cellml.CellMLExpressionWriter('2.0') w.set_unit_function(lambda x: units[x]) xml = w.ex(myokit.Number(1, myokit.units.pF)) self.assertIn(cellml.NS_CELLML_2_0, xml)
def ifif(self): """ Test of If class """ true = myokit.Number(1) false = myokit.Number(0) two = myokit.Number(2) three = myokit.Number(3) x = myokit.If(true, two, three) self.assertEqual(x.eval(), 2) self.assertEqual(x.condition(), true) x = myokit.If(true, three, two) self.assertEqual(x.eval(), 3) x = myokit.If(false, two, three) self.assertEqual(x.eval(), 3) self.assertEqual(x.condition(), false) x = myokit.If(false, three, two) self.assertEqual(x.eval(), 2) # Conversion to piecewise x = myokit.If(true, two, three).piecewise() self.assertIsInstance(x, myokit.Piecewise) self.assertEqual(x.eval(), 2) x = myokit.If(true, three, two).piecewise() self.assertIsInstance(x, myokit.Piecewise) self.assertEqual(x.eval(), 3) x = myokit.If(false, two, three).piecewise() self.assertIsInstance(x, myokit.Piecewise) self.assertEqual(x.eval(), 3) x = myokit.If(false, three, two).piecewise() self.assertIsInstance(x, myokit.Piecewise) self.assertEqual(x.eval(), 2)
def _ex_piecewise(self, e): from sympy.logic.boolalg import BooleanTrue, BooleanFalse args = [] n = len(e.args) - 1 for k, pair in enumerate(e.args): expr, cond = pair expr = self.ex(expr) cond_is_true = False if type(cond) == BooleanTrue: cond_is_true = True cond = myokit.Equal(myokit.Number(1), myokit.Number(1)) elif type(cond) == BooleanFalse: # pragma: no cover # Cover pragma: SymPy currently optimises out BooleanFalse cond = myokit.Equal(myokit.Number(0), myokit.Number(1)) else: cond = self.ex(cond) if k < n: args.append(cond) args.append(expr) if cond_is_true: args.append(expr) else: args.append(cond) args.append(expr) args.append(myokit.Number(0)) return myokit.Piecewise(*args)
def test_conditionals(self): # Tests if and piecewise writing a = myokit.Name('a') b = myokit.Number(1) c = myokit.Number(1) cond1 = myokit.parse_expression('5 > 3') cond2 = myokit.parse_expression('2 < 1') ca = '<mi>a</mi>' cb = '<mn>1.0</mn>' cc = '<mn>1.0</mn>' c1 = '<mrow><mn>5.0</mn><mo>></mo><mn>3.0</mn></mrow>' c2 = '<mrow><mn>2.0</mn><mo><</mo><mn>1.0</mn></mrow>' # If x = myokit.If(cond1, a, b) self.assertWrite( x, '<piecewise>' '<piece>' + ca + c1 + '</piece>' '<otherwise>' + cb + '</otherwise>' '</piecewise>') # Piecewise x = myokit.Piecewise(cond1, a, cond2, b, c) self.assertWrite( x, '<piecewise>' '<piece>' + ca + c1 + '</piece>' '<piece>' + cb + c2 + '</piece>' '<otherwise>' + cc + '</otherwise>' '</piecewise>')
def test_conditionals(self): # Tests if and piecewise writing a = myokit.Name('a') b = myokit.Number(1) cond1 = myokit.parse_expression('5 > 3') cond2 = myokit.parse_expression('2 < 1') c1 = '<apply><gt/><cn>5.0</cn><cn>3.0</cn></apply>' c2 = '<apply><lt/><cn>2.0</cn><cn>1.0</cn></apply>' # If e = myokit.If(cond1, a, b) x = ( '<piecewise>' '<piece><ci>a</ci>' + c1 + '</piece>' '<otherwise><cn>1.0</cn></otherwise>' '</piecewise>' ) self.assertWrite(e, x) # Piecewise e = myokit.Piecewise(cond1, a, cond2, b, myokit.Number(100)) x = ( '<piecewise>' '<piece><ci>a</ci>' + c1 + '</piece>' '<piece><cn>1.0</cn>' + c2 + '</piece>' '<otherwise><cn>100.0</cn></otherwise>' '</piecewise>' ) self.assertWrite(e, x)
def equal(self): """ Test of __eq__ operators """ a1 = myokit.Number(4) a2 = myokit.Number(5) self.assertEqual(a1, a1) self.assertEqual(a1, myokit.Number(4)) self.assertEqual(a1, myokit.Number(4.0)) self.assertNotEqual(a1, a2) b1 = myokit.Name('test') b2 = myokit.Name('tost') self.assertEqual(b1, b1) self.assertNotEqual(b1, b2) c1 = myokit.PrefixPlus(a1) c2 = myokit.PrefixPlus(a1) self.assertEqual(c1, c1) self.assertEqual(c1, c2) c2 = myokit.PrefixPlus(a2) self.assertNotEqual(c1, c2) d1 = myokit.Plus(a1, a2) d2 = myokit.Plus(a1, a2) self.assertEqual(d1, d1) self.assertEqual(d1, d2) d2 = myokit.Plus(a2, a1) self.assertNotEqual(d2, d1) e1 = myokit.Sqrt(a1) e2 = myokit.Sqrt(a1) self.assertEqual(e1, e1) self.assertEqual(e1, e2) e2 = myokit.Sqrt(a2) self.assertNotEqual(e1, e2)
def polynomial(self): """ Test of Polynomial class """ x = myokit.Name('x') c = [ myokit.Number(5), myokit.Number(4), myokit.Number(3), myokit.Number(2) ] p = myokit.Polynomial(x, *c) self.assertEqual(p.eval(subst={x: 0}), 5) self.assertEqual(p.eval(subst={x: 1}), 14) self.assertEqual(p.eval(subst={x: 2}), 41) self.assertEqual(p.eval(subst={x: -1}), 2) self.assertEqual(p.eval(subst={x: 0.5}), 8) q = p.tree() self.assertNotEqual(p, q) for i in [-1, 0, 0.5, 1, 2]: s = {x: i} self.assertEqual(p.eval(subst=s), q.eval(subst=s)) q = p.tree(horner=False) self.assertNotEqual(p, q) for i in [-1, 0, 0.5, 1, 2]: s = {x: i} self.assertEqual(p.eval(subst=s), q.eval(subst=s))
def number_factory(value, element): # Numbers not connected to a cn if element is None: return myokit.Number(value, myokit.units.dimensionless) # Get units attribute try: units = element.attrib[attr] except KeyError: raise CellMLParsingError( 'Numbers inside MathML must define a cellml:units' ' attribute (4.4.3.1).', element) # Find units in component try: units = component.find_units(units) units = units.myokit_unit() except myokit.formats.cellml.v1.UnitsError as e: warnings.warn( 'The units "' + str(units) + '" (referenced inside a' ' MathML equation) are not supported and have been' ' replaced by `dimensionless`. (' + str(e) + ')') units = myokit.units.dimensionless except myokit.formats.cellml.v1.CellMLError: raise CellMLParsingError( 'Unknown unit "' + str(units) + '" referenced inside a' ' MathML equation (4.4.3.2).', element) # Create and return return myokit.Number(value, units)
def test_name_and_numbers(self): # Test name and number writing self.assertWrite(myokit.Name('a'), '<ci>a</ci>') # Number without unit self.assertWrite(myokit.Number(1), '<cn>1.0</cn>') # Number with unit # Unit isn't exported by default! self.assertWrite(myokit.Number('12', 'pF'), '<cn>12.0</cn>')
def test_arithmetic_unary(self): # Tests writing prefix operators # Prefix plus m = myokit.PrefixPlus(myokit.Number(1)) x = '<apply><plus/><cn>1.0</cn></apply>' self.assertWrite(m, x) # Prefix minus m = myokit.PrefixMinus(myokit.Number(1)) x = '<apply><minus/><cn>1.0</cn></apply>' self.assertWrite(m, x)
def test_arithmetic_unary(self): # Tests parsing basic arithmetic operators # Prefix plus e = myokit.PrefixPlus(myokit.Number(1)) x = '<apply><plus/><cn>1.0</cn></apply>' self.assertEqual(self.p(x), e) # Prefix minus e = myokit.PrefixMinus(myokit.Number(1)) x = '<apply><minus/><cn>1.0</cn></apply>' self.assertEqual(self.p(x), e)
def parse_mathml_number(node, logger=None): """ Parses a mathml <cn> tag to a :class:`myokit.Number`. The attribute ``node`` must be a DOM node representing a <cn> tag using the ``xml.dom.Node`` interface. If the argument ``logger`` is given this will be used to log messages to, assuming the :class:`myokit.TextLogger` interface. """ kind = node.getAttribute('type') if kind == '': # Default type kind = 'real' if kind == 'real': # Float, specified as 123.123 (no exponent!) # May be in a different base than 10 base = node.getAttribute('base') if base: raise MathMLError('BASE conversion for reals is not supported') return myokit.Number(str(node.firstChild.data).strip()) elif kind == 'integer': # Integer in any given base base = node.getAttribute('base') numb = str(node.firstChild.data).strip() if base: v = int(numb, base) if logger: logger.log('Converted from ' + str(numb) + ' to ' + str(v)) numb = v return myokit.Number(numb) elif kind == 'double': # Floating point (positive, negative, exponents, etc) return myokit.Number(numb) elif kind == 'e-notation': # 1<sep />3 = 1e3 sig = str(node.firstChild.data.strip()) exp = str(node.firstChild.nextSibling.nextSibling.data).strip() numb = sig + 'e' + exp if logger: logger.log('Converted ' + sig + 'e' + str(exp) + '.') return myokit.Number(numb) elif kind == 'rational': # 1<sep />3 = 1 / 3 num = str(node.firstChild.data.strip()) den = str(node.firstChild.nextSibling.nextSibling.data).strip() numb = str(float(num) / float(den)) if logger: logger.log('Converted ' + num + ' / ' + den + ' to ' + numb) return myokit.Number(numb) else: raise MathMLError('Unsupported <cn> type: ' + kind)
def _test_maths(self, version): # Test maths is written (in selected ``version``) # Create model m1 = cellml.Model('m', version) c1 = m1.add_component('c') p1 = c1.add_variable('p', 'mole') p1.set_initial_value(2) q1 = c1.add_variable('q', 'dimensionless') r1 = c1.add_variable('r', 'second') r1.set_initial_value(0.1) t1 = c1.add_variable('t', 'second') m1.set_variable_of_integration(t1) # Add component without maths d1 = m1.add_component('d') s1 = d1.add_variable('s', 'volt') s1.set_initial_value(1.23) # Add two equations # Note: Numbers without units become dimensionless in CellML eq1 = myokit.Equation( myokit.Name(q1), myokit.Plus(myokit.Number(3, myokit.units.mole), myokit.Name(p1))) er1 = myokit.Equation(myokit.Derivative(myokit.Name(r1)), myokit.Power(myokit.Name(q1), myokit.Number(2))) q1.set_equation(eq1) r1.set_equation(er1) # Write and read xml = cellml.write_string(m1) m2 = cellml.parse_string(xml) # Check results p2, q2, r2, s2 = m2['c']['p'], m2['c']['q'], m2['c']['r'], m2['d']['s'] subst = { myokit.Name(p1): myokit.Name(p2), myokit.Name(q1): myokit.Name(q2), myokit.Name(r1): myokit.Name(r2), } eq2 = eq1.clone(subst) er2 = er1.clone(subst) self.assertEqual(q2.equation(), eq2) self.assertEqual(r2.equation(), er2) self.assertEqual(s2.initial_value(), myokit.Number(1.23, myokit.units.volt)) self.assertFalse(p2.is_state()) self.assertFalse(q2.is_state()) self.assertTrue(r2.is_state()) self.assertFalse(s2.is_state()) self.assertIs(m2.variable_of_integration(), m2['c']['t'])
def test_name_and_numbers(self): # Test name and number writing self.assertWrite(myokit.Name('a'), '<ci>a</ci>') # Number without unit self.assertWrite(myokit.Number(0), '<cn>0.0</cn>') self.assertWrite(myokit.Number(1), '<cn>1.0</cn>') # Number with unit # Unit isn't exported by default! self.assertWrite(myokit.Number('-12', 'pF'), '<cn>-12.0</cn>') # Number with e notation (note that Python will turn e.g. 1e3 into # 1000, so must pick tests carefully) self.assertWrite(myokit.Number(1e3), '<cn>1000.0</cn>') self.assertWrite(myokit.Number(1e-3), '<cn>0.001</cn>') self.assertWrite( myokit.Number(1e-6), '<cn type="e-notation">1<sep/>-6</cn>') self.assertWrite( myokit.Number(2.3e24), '<cn type="e-notation">2.3<sep/>24</cn>') # myokit.float.str(1.23456789) = 1.23456788999999989e+00 self.assertWrite( myokit.Number(1.23456789), '<cn>1.23456788999999989</cn>')
def test_name_and_numbers(self): # Test name and number writing # Name self.assertWrite(myokit.Name(self.avar), '<mi>c.a</mi>') # Number with unit self.assertWrite(myokit.Number(12, 'pF'), '<mn>12.0</mn>') # Number without unit self.assertWrite(myokit.Number(1), '<mn>1.0</mn>') # E-notation is allowed in presentation MathML self.assertWrite(myokit.Number(1e-6), '<mn>1e-06</mn>') self.assertWrite(myokit.Number(1e24), '<mn>1e+24</mn>')
def test_remove_component(self): # Test the removal of a component. # Create model m = myokit.Model('LotkaVolterra') # Simplest case X = m.add_component('X') self.assertEqual(m.count_components(), 1) m.remove_component(X) self.assertEqual(m.count_components(), 0) self.assertRaises(KeyError, m.remove_component, X) # Test if orphaned self.assertIsNone(X.parent()) # Re-adding self.assertEqual(m.count_components(), 0) X = m.add_component('X') self.assertEqual(m.count_components(), 1) # With internal variables and string name a = X.add_variable('a') a.set_rhs(myokit.Number(4)) b = X.add_variable('b') b.set_rhs(myokit.Name(a)) m.remove_component('X') self.assertEqual(m.count_components(), 0) # With dependencies from another component X = m.add_component('X') a = X.add_variable('a') a.set_rhs(myokit.Number(45)) b = X.add_variable('b') b.set_rhs(myokit.Name(b)) Y = m.add_component('Y') c = Y.add_variable('c') c.set_rhs(myokit.Name(a)) d = Y.add_variable('d') d.set_rhs(myokit.Name(c)) self.assertEqual(m.count_components(), 2) self.assertRaises(myokit.IntegrityError, m.remove_component, X) self.assertEqual(m.count_components(), 2) # In the right order... m.remove_component(Y) self.assertEqual(m.count_components(), 1) m.remove_component(X) self.assertEqual(m.count_components(), 0)
def TT_HF_Lu(cell_type = None): m = myokit.load_model('tentusscher-2006.mmt') # INa: -40% ina = m.get('ina.INa') ina.set_rhs(myokit.Multiply(myokit.Number(0.6), ina.rhs())) # Ito: -36% (not -64% like other papers misquote) ito = m.get('ito.ITo') ito.set_rhs(myokit.Multiply(myokit.Number(0.64), ito.rhs())) # IK1: -20% ik1 = m.get('ik1.IK1') ik1.set_rhs(myokit.Multiply(myokit.Number(0.8), ik1.rhs())) # INaK: -42% inak = m.get('inak.INaK') inak.set_rhs(myokit.Multiply(myokit.Number(0.58), inak.rhs())) # ICab: +53% icab = m.get('icab.ICaB') icab.set_rhs(myokit.Multiply(myokit.Number(1.53), icab.rhs())) # INCX: +65% incx = m.get('inaca.INaCa') incx.set_rhs(myokit.Multiply(myokit.Number(1.65), incx.rhs())) # SR calcium pump current : -45% iup = m.get('calcium.i_up') iup.set_rhs(myokit.Multiply(myokit.Number(0.55), iup.rhs())) ## Can I call this serca? # ILeak: 0% ileak = m.get('calcium.i_leak') ileak.set_rhs(myokit.Multiply(myokit.Number(1.0), ileak.rhs())) #Jrel ??: -23% jrel = m.get('calcium.i_rel') # Not sure this is the right parameter jrel.set_rhs(myokit.Multiply(myokit.Number(0.77), jrel.rhs())) #Iks: -50% iks = m.get('iks.IKs') iks.set_rhs(myokit.Multiply(myokit.Number(0.5), iks.rhs())) return(m)
def simulate_aps(scales, model_file, beats=2, cl=1000, prepace=100, stimulate=True): """ Generate APs using the given scalings. """ # Load model model = myokit.load_model(model_file) # Apply scalings for var in scales: scale = scales[var] v = model.get(var) v.set_rhs(myokit.Multiply(myokit.Number(scale), v.rhs())) # Simulate with modified model sim = myokit.Simulation(model) # Add stimulus if stimulate: protocol = myokit.pacing.blocktrain(period=cl, duration=1, offset=50) sim.set_protocol(protocol) # Pre-pace for some beats sim.pre(prepace * cl) # Log some beats and return log = ['engine.time', 'membrane.V'] log = ['environment.time', 'membrane.V'] log = ['membrane.V'] return sim.run(beats * cl, log=log, log_interval=DT).npview()
def test_parse_mathml_string(self): # Test :meth:`mathml.parse_mathml_string()`. self.assertEqual( mathml.parse_mathml_string('<apply><cn>1.0</cn></apply>'), myokit.Number(1) )
def test_trig_basic(self): # Test writing basic trig functions b = myokit.Number('12', 'pF') cb = '<mn>12.0</mn>' # Sin x = myokit.Sin(b) self.assertWrite( x, '<mrow><mi>sin</mi><mfenced>' + cb + '</mfenced></mrow>') # Cos x = myokit.Cos(b) self.assertWrite( x, '<mrow><mi>cos</mi><mfenced>' + cb + '</mfenced></mrow>') # Tan x = myokit.Tan(b) self.assertWrite( x, '<mrow><mi>tan</mi><mfenced>' + cb + '</mfenced></mrow>') # ASin x = myokit.ASin(b) self.assertWrite( x, '<mrow><mi>arcsin</mi><mfenced>' + cb + '</mfenced></mrow>') # ACos x = myokit.ACos(b) self.assertWrite( x, '<mrow><mi>arccos</mi><mfenced>' + cb + '</mfenced></mrow>') # ATan x = myokit.ATan(b) self.assertWrite( x, '<mrow><mi>arctan</mi><mfenced>' + cb + '</mfenced></mrow>')
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)
def test_inequalities(self): # Test writing (in)equalities a = myokit.Name(self.avar) b = myokit.Number('12', 'pF') ca = '<mi>c.a</mi>' cb = '<mn>12.0</mn>' # Equal x = myokit.Equal(a, b) self.assertWrite(x, '<mrow>' + ca + '<mo>==</mo>' + cb + '</mrow>') # NotEqual x = myokit.NotEqual(a, b) self.assertWrite(x, '<mrow>' + ca + '<mo>!=</mo>' + cb + '</mrow>') # More x = myokit.More(a, b) self.assertWrite(x, '<mrow>' + ca + '<mo>></mo>' + cb + '</mrow>') # Less x = myokit.Less(a, b) self.assertWrite(x, '<mrow>' + ca + '<mo><</mo>' + cb + '</mrow>') # MoreEqual # Named version ≥ is not output, shows decimal code instead x = myokit.MoreEqual(a, b) self.assertWrite(x, '<mrow>' + ca + '<mo>≥</mo>' + cb + '</mrow>') # LessEqual # Named version ≤ is not output, shows decimal code instead x = myokit.LessEqual(a, b) self.assertWrite(x, '<mrow>' + ca + '<mo>≤</mo>' + cb + '</mrow>')
def test_functions(self): # Test printing functions a = myokit.Name(self.avar) b = myokit.Number('12', 'pF') ca = '<ci>a</ci>' cb = ('<cn cellml:units="picofarad">12.0</cn>') # Power x = myokit.Power(a, b) self.assertWrite(x, '<apply><power/>' + ca + cb + '</apply>') # Sqrt x = myokit.Sqrt(b) self.assertWrite(x, '<apply><root/>' + cb + '</apply>') # Exp x = myokit.Exp(a) self.assertWrite(x, '<apply><exp/>' + ca + '</apply>') # Floor x = myokit.Floor(b) self.assertWrite(x, '<apply><floor/>' + cb + '</apply>') # Ceil x = myokit.Ceil(b) self.assertWrite(x, '<apply><ceiling/>' + cb + '</apply>') # Abs x = myokit.Abs(b) self.assertWrite(x, '<apply><abs/>' + cb + '</apply>')
def test_inequalities(self): # Tests printing inequalities a = myokit.Name(self.avar) b = myokit.Number('12', 'pF') ca = '<ci>a</ci>' cb = ('<cn cellml:units="picofarad">12.0</cn>') # Equal x = myokit.Equal(a, b) self.assertWrite(x, '<apply><eq/>' + ca + cb + '</apply>') # NotEqual x = myokit.NotEqual(a, b) self.assertWrite(x, '<apply><neq/>' + ca + cb + '</apply>') # More x = myokit.More(a, b) self.assertWrite(x, '<apply><gt/>' + ca + cb + '</apply>') # Less x = myokit.Less(a, b) self.assertWrite(x, '<apply><lt/>' + ca + cb + '</apply>') # MoreEqual x = myokit.MoreEqual(a, b) self.assertWrite(x, '<apply><geq/>' + ca + cb + '</apply>') # LessEqual x = myokit.LessEqual(a, b) self.assertWrite(x, '<apply><leq/>' + ca + cb + '</apply>')
def test_arithmetic(self): # Test basic arithmetic a = myokit.Name(self.avar) b = myokit.Number('12', 'pF') ca = '<ci>a</ci>' cb = ('<cn cellml:units="picofarad">12.0</cn>') # Prefix plus x = myokit.PrefixPlus(b) self.assertWrite(x, '<apply><plus/>' + cb + '</apply>') # Prefix minus x = myokit.PrefixMinus(b) self.assertWrite(x, '<apply><minus/>' + cb + '</apply>') # Plus x = myokit.Plus(a, b) self.assertWrite(x, '<apply><plus/>' + ca + cb + '</apply>') # Minus x = myokit.Minus(a, b) self.assertWrite(x, '<apply><minus/>' + ca + cb + '</apply>') # Multiply x = myokit.Multiply(a, b) self.assertWrite(x, '<apply><times/>' + ca + cb + '</apply>') # Divide x = myokit.Divide(a, b) self.assertWrite(x, '<apply><divide/>' + ca + cb + '</apply>')
def test_overdefined(self): # Tests for overdefined variables # Initial value and equation for state x = ('<component name="a">' ' <variable name="time" units="dimensionless" />' ' <variable name="x" units="dimensionless" initial_value="2" />' ' <math xmlns="http://www.w3.org/1998/Math/MathML">') a = (' <apply>' ' <eq />' ' <apply>' ' <diff/>' ' <bvar>' ' <ci>time</ci>' ' </bvar>' ' <ci>x</ci>' ' </apply>' ' <cn cellml:units="dimensionless">3</cn>' ' </apply>') z = (' </math>' '</component>') m = self.parse(x + a + z) v = m['a']['x'] self.assertEqual(v.rhs(), myokit.Number(3)) self.assertEqual(v.initial_value(), 2) # Initial value and equation for a non-state b = (' <apply>' ' <eq /><ci>x</ci><cn cellml:units="dimensionless">2</cn>' ' </apply>') self.assertBad(x + b + z, 'Initial value and a defining equation') # Two equations self.assertBad(x + a + a + z, 'Two defining equations')
def test_variable(self): # Tests writing of variables m1 = cellml.Model('m') c = m1.add_component('c') p = c.add_variable('p', 'mole') q = c.add_variable('q', 'kelvin', interface='public') r = c.add_variable('r', 'ampere', interface='private') p.set_initial_value(1) with WarningCollector(): xml = cellml.write_string(m1) m2 = cellml.parse_string(xml) p, q, r = m2['c']['p'], m2['c']['q'], m2['c']['r'] self.assertEqual(p.units().name(), 'mole') self.assertEqual(q.units().name(), 'kelvin') self.assertEqual(r.units().name(), 'ampere') self.assertEqual(p.interface(), 'none') self.assertEqual(q.interface(), 'public') self.assertEqual(r.interface(), 'private') self.assertEqual(p.initial_value(), myokit.Number(1, myokit.units.mole)) self.assertEqual(q.initial_value(), None) self.assertEqual(r.initial_value(), None)
def test_units(self): # Test writing of units u1 = myokit.parse_unit('kg*m^2/mole^3 (0.123)') m1 = cellml.Model('mmm') m1.add_units('flibbit', u1) m1.add_units('special_volt', myokit.units.Volt) d = m1.add_component('ddd') q = d.add_variable('q', 'flibbit') q.set_equation(myokit.Equation(myokit.Name(q), myokit.Number(2, u1))) xml = cellml.write_string(m1) m2 = cellml.parse_string(xml) q = m2['ddd']['q'] self.assertEqual(q.units().name(), 'flibbit') self.assertEqual(q.units().myokit_unit(), u1) self.assertEqual( m2.find_units('special_volt').myokit_unit(), myokit.units.volt) # Dimensionless units with a multiplier u1 = myokit.parse_unit('1 (0.123)') m1 = cellml.Model('mmm') m1.add_units('flibbit', u1) xml = cellml.write_string(m1) m2 = cellml.parse_string(xml) u2 = m2.find_units('flibbit') u2 = u2.myokit_unit() self.assertEqual(u1, u2)
def test_oxmeta_annotations(self): # Tests if oxmeta annotations are written # Create mini model m = cellml.Model('m') c = m.add_component('c') v = c.add_variable('v', 'volt') v.set_rhs(myokit.Number(0, myokit.units.volt)) # Test no RDF is written without oxmeta or cmeta xml = cellml.write_string(m) self.assertNotIn(b'rdf:RDF', xml) v.meta['oxmeta'] = 'membrane_voltage' xml = cellml.write_string(m) self.assertNotIn(b'rdf:RDF', xml) del (v.meta['oxmeta']) v.set_cmeta_id('vvv') xml = cellml.write_string(m) self.assertNotIn(b'rdf:RDF', xml) # Test it is written if both are set v.meta['oxmeta'] = 'membrane_voltage' xml = cellml.write_string(m) self.assertIn(b'rdf:RDF', xml) # Test reading it again with the parser m2 = cellml.parse_string(xml) v2 = m2['c']['v'] self.assertEqual(v2.cmeta_id(), 'vvv') self.assertIn('oxmeta', v2.meta) self.assertEqual(v2.meta['oxmeta'], 'membrane_voltage')