Ejemplo n.º 1
0
    def test_load_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)
Ejemplo n.º 2
0
    def test_save_frame_csv(self):
        # Test the save_frame_csv() method.

        w, h = 2, 3
        time = [1, 2, 3]
        b = myokit.DataBlock2d(w, h, time)
        x = np.array([  # Each 3 by 2 array is a point in time
            [[0, 1], [2, 3], [4, 5]],
            [[5, 4], [3, 2], [1, 0]],
            [[0, 0], [0, 0], [0, 0]],
        ])
        b.set2d('x', x)

        with TemporaryDirectory() as d:
            path = d.path('test.csv')
            b.save_frame_csv(path, 'x', 0)
            with open(path, 'r') as f:
                lines = [str(x) for x in f.readlines()]
            self.assertEqual(lines[0], '"x","y","value"\n')
            self.assertEqual(lines[1], '0,0,0\n')
            self.assertEqual(lines[2], '1,0,1\n')
            self.assertEqual(lines[3], '0,1,2\n')
            self.assertEqual(lines[4], '1,1,3\n')
            self.assertEqual(lines[5], '0,2,4\n')
            self.assertEqual(lines[6], '1,2,5')
Ejemplo n.º 3
0
    def test_load_save_selection(self):
        # Tests the load_selection method
        import myokit._sim.opencl
        org_name = myokit._sim.opencl.SETTINGS_FILE
        try:
            with TemporaryDirectory() as d:
                fname = d.path('opencl-temp.ini')
                myokit._sim.opencl.SETTINGS_FILE = fname

                # Save None and None
                myokit.OpenCL.save_selection(None, None)
                platform, device = myokit.OpenCL.load_selection()
                self.assertIsNone(platform)
                self.assertIsNone(device)

                myokit.OpenCL.save_selection(None, 'bert')
                platform, device = myokit.OpenCL.load_selection()
                self.assertIsNone(platform)
                self.assertEqual(device, 'bert')

                myokit.OpenCL.save_selection('ernie', None)
                platform, device = myokit.OpenCL.load_selection()
                self.assertEqual(platform, 'ernie')
                self.assertIsNone(device)

                myokit.OpenCL.save_selection('ernie', 'bert')
                platform, device = myokit.OpenCL.load_selection()
                self.assertEqual(platform, 'ernie')
                self.assertEqual(device, 'bert')

        finally:
            myokit._sim.opencl.SETTINGS_FILE = org_name
Ejemplo n.º 4
0
    def test_stan_exporter(self):
        # Basic test
        self._test(myokit.formats.exporter('stan'))

        # Test with parameters and output variable specified

        # Load model
        m = myokit.load_model('example')

        # Guess parameters
        parameters = []
        for v in m.get('ina').variables(const=True):
            if v.name()[:1] == 'p':
                parameters.append(v)
        parameters.sort(key=lambda v: myokit.tools.natural_sort_key(v.name()))

        # Set output
        output = 'ina.INa'

        # Export to stan
        e = myokit.formats.stan.StanExporter()
        with TemporaryDirectory() as d:
            dpath = d.path('out')
            ret = e.runnable(dpath, m, parameters=parameters, output=output)
            self.assertIsNone(ret)
            self.assertTrue(os.path.isdir(dpath))
            self.assertTrue(len(os.listdir(dpath)) > 0)
Ejemplo n.º 5
0
    def test_export_reused_variable(self):
        # Tests exporting when an `inf` or other special variable is used twice

        # Create model re-using tau and inf
        m = myokit.parse_model("""
            [[model]]
            m.V = -80
            c.x = 0.1
            c.y = 0.1

            [m]
            time = 0 bind time
            i_ion = c.I
            dot(V) = -i_ion

            [c]
            inf = 0.5
            tau = 3
            dot(x) = (inf - x) / tau
            dot(y) = (inf - y) / tau
            I = x * y * (m.V - 50)
            """)

        # Export, and read back in
        e = myokit.formats.easyml.EasyMLExporter()
        with TemporaryDirectory() as d:
            path = d.path('easy.model')
            e.model(path, m)
            with open(path, 'r') as f:
                x = f.read()

        self.assertIn('x_inf =', x)
        self.assertIn('y_inf =', x)
        self.assertIn('tau_x =', x)
        self.assertIn('tau_y =', x)
Ejemplo n.º 6
0
    def test_easyml_exporter(self):
        # Tests exporting a model

        model = myokit.load_model('example')
        with TemporaryDirectory() as d:
            path = d.path('easy.model')

            # Test with simple model
            e = myokit.formats.easyml.EasyMLExporter()
            e.model(path, model)

            # Test with extra bound variables
            model.get('membrane.C').set_binding('hello')
            e.model(path, model)

            # Test without V being a state variable
            v = model.get('membrane.V')
            v.demote()
            v.set_rhs(3)
            e.model(path, model)

            # Test with invalid model
            v.set_rhs('2 * V')
            self.assertRaisesRegex(myokit.ExportError, 'valid model', e.model,
                                   path, model)
Ejemplo n.º 7
0
 def parse_in_file(self, xml):
     """
     Inserts the given ``xml`` into a <model> element, writes it to a
     temporary file, parses it, and returns the result.
     """
     with TemporaryDirectory() as d:
         path = d.path('test.cellml')
         with open(path, 'w') as f:
             f.write(self.wrap(xml))
         return v1.parse_file(path)
Ejemplo n.º 8
0
    def test_write_file(self):
        # Tests write_file

        m1 = cellml.Model('ernie')
        with TemporaryDirectory() as d:
            path = d.path('test.cellml')
            cellml.write_file(path, m1)
            m2 = cellml.parse_file(path)

        self.assertEqual(m2.name(), 'ernie')
        self.assertEqual(len(m2), 0)
Ejemplo n.º 9
0
    def test_accessors(self):
        # Test various accessor methods of :class:`AtfFile`.

        with TemporaryDirectory() as d:
            # Create data log
            log = myokit.DataLog()
            log.set_time_key('time')
            log['time'] = np.arange(10)
            log['sint'] = np.sin(log['time'])
            log['cost'] = np.cos(log['time'])

            # Write atf file
            path = d.path('test.atf')
            axon.save_atf(log, path)

            # Read atf file
            atf = myokit.formats.axon.AtfFile(path)

            # Test filename()
            self.assertEqual(atf.filename(), path)

            # Test iter and getitem
            self.assertEqual(len(list(iter(atf))), 3)
            self.assertTrue(np.all(atf['time'] == log['time']))
            self.assertTrue(np.all(atf['sint'] == log['sint']))
            self.assertTrue(np.all(atf['cost'] == log['cost']))

            # Test items()
            items = list(atf.items())
            self.assertEqual(items[0][0], 'time')
            self.assertEqual(items[1][0], 'sint')
            self.assertEqual(items[2][0], 'cost')
            self.assertTrue(np.all(items[0][1] == log['time']))
            self.assertTrue(np.all(items[1][1] == log['sint']))
            self.assertTrue(np.all(items[2][1] == log['cost']))

            # Test keys()
            self.assertEqual(list(atf.keys()), ['time', 'sint', 'cost'])

            # Test values()
            values = list(atf.values())
            self.assertTrue(np.all(values[0] == log['time']))
            self.assertTrue(np.all(values[1] == log['sint']))
            self.assertTrue(np.all(values[2] == log['cost']))

            # Test len
            self.assertEqual(len(atf), 3)

            # Test info
            self.assertIn('myokit', atf.info())

            # Test version
            self.assertEqual(atf.version(), '1.0')
Ejemplo n.º 10
0
    def test_load_save_state_bin(self):
        # Test loading/saving state in binary format.
        m, p, x = myokit.load('example')
        with TemporaryDirectory() as d:

            # Test save and load with double precision
            f = d.path('state.bin')
            myokit.save_state_bin(f, m.state())
            self.assertEqual(myokit.load_state_bin(f), m.state())

            # Test save and load with single precision
            f = d.path('state.bin')
            myokit.save_state_bin(f, m.state(), myokit.SINGLE_PRECISION)
            d = np.array(myokit.load_state_bin(f)) - np.array(m.state())
            self.assertTrue(np.all(np.abs(d) < 1e-5))  # Not very precise!
Ejemplo n.º 11
0
    def test_unit_conversion(self):
        # Tests exporting a model that requires unit conversion

        # Export model
        m = myokit.parse_model(units_model)
        e = myokit.formats.easyml.EasyMLExporter()
        with TemporaryDirectory() as d:
            path = d.path('easy.model')
            e.model(path, m)
            with open(path, 'r') as f:
                observed = f.read().strip().splitlines()

        # Get expected output
        expected = units_output.strip().splitlines()

        # Compare (line by line, for readable output)
        for ob, ex in zip(observed, expected):
            self.assertEqual(ob, ex)
        self.assertEqual(len(observed), len(expected))

        # Test warnings are raised if conversion fails
        m.get('membrane.V').set_rhs('hh.I1 + mm.I2')
        m.get('membrane').remove_variable(m.get('membrane.C'))
        with TemporaryDirectory() as d:
            path = d.path('easy.model')
            with WarningCollector() as c:
                e.model(path, m)
            self.assertIn('Unable to convert hh.I1', c.text())
            self.assertIn('Unable to convert mm.I2', c.text())

        m.get('engine.time').set_unit(myokit.units.cm)
        with TemporaryDirectory() as d:
            path = d.path('easy.model')
            with WarningCollector() as c:
                e.model(path, m)
            self.assertIn('Unable to convert time units [cm]', c.text())
Ejemplo n.º 12
0
    def test_create(self):
        # Test if the `_create` method works.

        # Import hidden _config module
        path = sys.path
        try:
            sys.path.append(myokit.DIR_MYOKIT)
            import _config as config
        finally:
            sys.path = path

        # Test _create
        with TemporaryDirectory() as d:
            filename = d.path('test.ini')
            config._create(filename)
            self.assertTrue(os.path.isfile(filename))
        self.assertFalse(os.path.isfile(filename))
Ejemplo n.º 13
0
    def test_writable_dir(self):
        # Test :meth:`_test_writable_dir` for existing paths.

        m, p, x = myokit.load('example')
        e = myokit.formats.exporter('ansic')
        with TemporaryDirectory() as d:

            # Create in new dir
            path = d.path('new-dir')
            e.runnable(path, m, p)

            # Create again, in same dir (should be ok)
            e.runnable(path, m, p)

            # Create at location of file: not allowed!
            path = d.path('file')
            with open(path, 'w') as f:
                f.write('Hello')
            self.assertRaisesRegex(myokit.ExportError, 'file exists',
                                   e.runnable, path, m, p)
Ejemplo n.º 14
0
 def e(self, template, args, expected_error=None):
     """
     Runs a template, if an error is expected it checks if it's the right
     one.
     """
     with TemporaryDirectory() as d:
         path = d.path('template')
         with open(path, 'w') as f:
             f.write(template)
         e = myokit.pype.TemplateEngine()
         if expected_error is None:
             e.process(path, args)
         else:
             try:
                 e.process(path, args)
             except myokit.pype.PypeError:
                 # Check expected message in error details
                 self.assertIn(expected_error, e.error_details())
                 return
             raise RuntimeError('PypeError not raised.')
Ejemplo n.º 15
0
    def test_easyml_exporter_static(self):
        # Tests exporting a model (with HH and markov states) and compares
        # against reference output.

        # Export model
        m = myokit.load_model(os.path.join(DIR_DATA, 'decker-2009.mmt'))
        e = myokit.formats.easyml.EasyMLExporter()
        with TemporaryDirectory() as d:
            path = d.path('decker.model')
            e.model(path, m)
            with open(path, 'r') as f:
                observed = f.readlines()

        # Load expected output
        with open(os.path.join(DIR_DATA, 'decker.model'), 'r') as f:
            expected = f.readlines()

        # Compare (line by line, for readable output)
        for ob, ex in zip(observed, expected):
            self.assertEqual(ob, ex)
        self.assertEqual(len(observed), len(expected))
Ejemplo n.º 16
0
    def test_load_save_state(self):
        # Test loading/saving state.
        m, p, x = myokit.load('example')
        with TemporaryDirectory() as d:
            # Test save and load without model
            f = d.path('state.txt')
            myokit.save_state(f, m.state())
            self.assertEqual(myokit.load_state(f), m.state())

            # Test save and load with model argument
            myokit.save_state(f, m.state(), m)
            self.assertEqual(myokit.load_state(f, m), m.state())

            # Save without, load with model
            myokit.save_state(f, m.state())
            self.assertEqual(myokit.load_state(f, m), m.state())

            # Save with model, load without
            # Loaded version is dict!
            myokit.save_state(f, m.state(), m)
            dct = dict(zip([v.qname() for v in m.states()], m.state()))
            self.assertEqual(myokit.load_state(f), dct)
Ejemplo n.º 17
0
    def test_save_protocol(self):
        # Test if the correct parts are saved/loaded from disk using the
        # ``save_protocol()`` method.

        ipath = os.path.join(DIR_DATA, 'lr-1991.mmt')
        # Test example loading
        p = myokit.load_protocol('example')
        self.assertIsInstance(p, myokit.Protocol)
        # Test file loading
        p = myokit.load_protocol(ipath)
        self.assertIsInstance(p, myokit.Protocol)
        with TemporaryDirectory() as d:
            opath = d.path('test.mmt')
            myokit.save_protocol(opath, p)
            # Test no other parts were written
            with open(opath, 'r') as f:
                text = f.read()
            self.assertFalse('[[model]]' in text)
            self.assertTrue('[[protocol]]' in text)
            self.assertFalse('[[script]]' in text)
            # Test reloading
            pp = myokit.load_protocol(opath)
            self.assertIsInstance(pp, myokit.Protocol)
            self.assertEqual(pp.code(), p.code())
Ejemplo n.º 18
0
    def test_save_script(self):
        # Test if the correct parts are saved/loaded from disk using the
        # ``save_script()`` method.

        ipath = os.path.join(DIR_DATA, 'lr-1991.mmt')
        # Test example loading
        x = myokit.load_script('example')
        self.assertTrue(isinstance(x, basestring))
        # Test file loading
        x = myokit.load_script(ipath)
        self.assertTrue(isinstance(x, basestring))
        with TemporaryDirectory() as d:
            opath = d.path('test.mmt')
            myokit.save_script(opath, x)
            # Test no other parts were written
            with open(opath, 'r') as f:
                text = f.read()
            self.assertFalse('[[model]]' in text)
            self.assertFalse('[[protocol]]' in text)
            self.assertTrue('[[script]]' in text)
            # Test reloading
            xx = myokit.load_script(opath)
            self.assertTrue(isinstance(xx, basestring))
            self.assertEqual(x, xx)
Ejemplo n.º 19
0
    def test_load_read(self):
        # Test if the `_load` method works, when a config file exists.

        # Import hidden _config module
        path = sys.path
        try:
            sys.path.append(myokit.DIR_MYOKIT)
            import _config as config
        finally:
            sys.path = path

        # Back-up current settings
        date_format = myokit.DATE_FORMAT
        time_format = myokit.TIME_FORMAT
        force_pyside = myokit.FORCE_PYSIDE
        force_pyside2 = myokit.FORCE_PYSIDE2
        force_pyqt4 = myokit.FORCE_PYQT4
        force_pyqt5 = myokit.FORCE_PYQT5
        sundials_lib = myokit.SUNDIALS_LIB
        sundials_inc = myokit.SUNDIALS_INC
        opencl_lib = myokit.OPENCL_LIB
        opencl_inc = myokit.OPENCL_INC

        # Change myokit config dir temporarily
        path = myokit.DIR_USER
        try:
            with TemporaryDirectory() as d:
                myokit.DIR_USER = d.path()

                # Simple test
                with open(d.path('myokit.ini'), 'w') as f:
                    f.write(config1)
                config._load()

                # Full values, PySide gui
                myokit.SUNDIALS_LIB = []
                myokit.SUNDIALS_INC = []
                myokit.OPENCL_LIB = []
                myokit.OPENCL_INC = []
                myokit.FORCE_PYSIDE = myokit.FORCE_PYSIDE2 = False
                myokit.FORCE_PYQT4 = myokit.FORCE_PYQT5 = False
                with open(d.path('myokit.ini'), 'w') as f:
                    f.write(config2)
                config._load()
                self.assertEqual(myokit.DATE_FORMAT, 'TEST_DATE_FORMAT')
                self.assertEqual(myokit.TIME_FORMAT, 'TEST_TIME_FORMAT')
                self.assertFalse(myokit.FORCE_PYSIDE)
                self.assertFalse(myokit.FORCE_PYSIDE2)
                self.assertFalse(myokit.FORCE_PYQT4)
                self.assertFalse(myokit.FORCE_PYQT5)
                self.assertEqual(myokit.SUNDIALS_LIB, ['one', 'two'])
                self.assertEqual(myokit.SUNDIALS_INC, ['three', 'four'])
                self.assertEqual(myokit.OPENCL_LIB, ['five', 'six'])
                self.assertEqual(myokit.OPENCL_INC, ['three', 'eight'])

                # Lists of paths should be filtered for empty values and
                # trimmed
                myokit.SUNDIALS_LIB = []
                myokit.SUNDIALS_INC = []
                myokit.OPENCL_LIB = []
                myokit.OPENCL_INC = []
                with open(d.path('myokit.ini'), 'w') as f:
                    f.write(config_empties_1)
                config._load()
                self.assertEqual(myokit.SUNDIALS_LIB, ['five'])
                self.assertEqual(myokit.SUNDIALS_INC, ['three', 'four'])
                self.assertEqual(myokit.OPENCL_LIB,
                                 ['one', 'two point five', 'three'])
                self.assertEqual(myokit.OPENCL_INC, [])

                # Even if the list contains " ;", which Python 2's config
                # parser treats as a comment
                myokit.SUNDIALS_LIB = []
                myokit.SUNDIALS_INC = []
                myokit.OPENCL_LIB = []
                myokit.OPENCL_INC = []
                with open(d.path('myokit.ini'), 'w') as f:
                    f.write(config_empties_2)
                if sys.hexversion < 0x03020000:
                    self.assertRaises(ImportError, config._load)
                else:
                    config._load()
                    self.assertEqual(myokit.SUNDIALS_LIB, ['five', 'six'])
                    self.assertEqual(myokit.SUNDIALS_INC, ['three', 'four'])
                    self.assertEqual(myokit.OPENCL_LIB,
                                     ['one', 'two point five', 'three'])
                    self.assertEqual(myokit.OPENCL_INC, [])

                # Qt gui options
                with open(d.path('myokit.ini'), 'w') as f:
                    f.write(config_pyqt4)
                config._load()
                self.assertFalse(myokit.FORCE_PYSIDE)
                self.assertFalse(myokit.FORCE_PYSIDE2)
                self.assertTrue(myokit.FORCE_PYQT4)
                self.assertFalse(myokit.FORCE_PYQT5)

                with open(d.path('myokit.ini'), 'w') as f:
                    f.write(config_pyqt5)
                config._load()
                self.assertFalse(myokit.FORCE_PYSIDE)
                self.assertFalse(myokit.FORCE_PYSIDE2)
                self.assertFalse(myokit.FORCE_PYQT4)
                self.assertTrue(myokit.FORCE_PYQT5)

                with open(d.path('myokit.ini'), 'w') as f:
                    f.write(config_pyside)
                config._load()
                self.assertTrue(myokit.FORCE_PYSIDE)
                self.assertFalse(myokit.FORCE_PYSIDE2)
                self.assertFalse(myokit.FORCE_PYQT4)
                self.assertFalse(myokit.FORCE_PYQT5)

                with open(d.path('myokit.ini'), 'w') as f:
                    f.write(config_pyside2)
                config._load()
                self.assertFalse(myokit.FORCE_PYSIDE)
                self.assertTrue(myokit.FORCE_PYSIDE2)
                self.assertFalse(myokit.FORCE_PYQT4)
                self.assertFalse(myokit.FORCE_PYQT5)

                # Odd ini file
                with open(d.path('myokit.ini'), 'w') as f:
                    f.write(config3)
                config._load()

                # No ini file (calls _create())
                os.remove(d.path('myokit.ini'))
                config._load()

        finally:
            # Reset path
            myokit.DIR_USER = path

            # Reset data and time
            myokit.DATE_FORMAT = date_format
            myokit.TIME_FORMAT = time_format
            myokit.FORCE_PYSIDE = force_pyside
            myokit.FORCE_PYSIDE2 = force_pyside2
            myokit.FORCE_PYQT4 = force_pyqt4
            myokit.FORCE_PYQT5 = force_pyqt5
            myokit.SUNDIALS_LIB = sundials_lib
            myokit.SUNDIALS_INC = sundials_inc
            myokit.OPENCL_LIB = opencl_lib
            myokit.OPENCL_INC = opencl_inc

            # Reload local settings
            config._load()

            # Sanity check
            self.assertNotEqual(myokit.DATE_FORMAT, 'TEST_DATE_FORMAT')
            self.assertNotEqual(myokit.TIME_FORMAT, 'TEST_TIME_FORMAT')
            self.assertEqual(myokit.FORCE_PYSIDE, force_pyside)
            self.assertEqual(myokit.FORCE_PYSIDE2, force_pyside2)
            self.assertEqual(myokit.FORCE_PYQT4, force_pyqt4)
            self.assertEqual(myokit.FORCE_PYQT5, force_pyqt5)
            self.assertNotEqual(myokit.SUNDIALS_LIB, ['one', 'two'])
            self.assertNotEqual(myokit.SUNDIALS_INC, ['three', 'four'])
            self.assertNotEqual(myokit.OPENCL_LIB, ['five', 'six'])
            self.assertNotEqual(myokit.OPENCL_INC, ['three', 'eight'])
Ejemplo n.º 20
0
    def test_combined(self):
        # Runs a combined test of:
        #
        # - DataLog to Block conversion
        # - Access to fields in block
        # - Saving block to binary file
        # - Loading block from binary file
        #

        # Create simulation log with 1d data
        log = myokit.DataLog()
        log.set_time_key('time')
        t = np.linspace(0, 1, 20)
        log['time'] = t
        log['0.x'] = np.sin(t)
        log['1.x'] = np.cos(t)
        log['2.x'] = np.tan(t)

        # Convert to datablock
        b = log.block1d()

        # Check block contents
        self.assertTrue(np.all(b.time() == t))
        self.assertFalse(b.time() is t)
        self.assertEqual(b.len0d(), 0)
        self.assertEqual(b.len1d(), 1)
        x = b.get1d('x')
        self.assertTrue(np.all(x[:, 0] == log['0.x']))
        self.assertTrue(np.all(x[:, 1] == log['1.x']))
        self.assertTrue(np.all(x[:, 2] == log['2.x']))

        # Make bigger log, try again
        log['pace'] = np.ones(t.shape) + t**2
        log['0.y'] = np.sqrt(t)
        log['1.y'] = 1 + np.sqrt(t)
        log['2.y'] = 2 + np.sqrt(t)

        # Convert to datablock
        b = log.block1d()

        # Check block contents
        self.assertTrue(np.all(b.time() == t))
        self.assertFalse(b.time() is t)
        self.assertEqual(b.len0d(), 1)
        self.assertEqual(b.len1d(), 2)
        self.assertTrue(np.all(b.get0d('pace') == log['pace']))
        self.assertFalse(b.get0d('pace') is log['pace'])
        x = b.get1d('x')
        self.assertTrue(np.all(x[:, 0] == log['0.x']))
        self.assertTrue(np.all(x[:, 1] == log['1.x']))
        self.assertTrue(np.all(x[:, 2] == log['2.x']))
        y = b.get1d('y')
        self.assertTrue(np.all(y[:, 0] == log['0.y']))
        self.assertTrue(np.all(y[:, 1] == log['1.y']))
        self.assertTrue(np.all(y[:, 2] == log['2.y']))

        # Test reading and writing
        with TemporaryDirectory() as d:
            fname = d.path('block1d.zip')
            b.save(fname)
            c = myokit.DataBlock1d.load(fname)
            # Test block contents
            self.assertTrue(np.all(b.time() == c.time()))
            self.assertFalse(b.time() is c.time())
            self.assertEqual(c.len0d(), 1)
            self.assertEqual(c.len1d(), 2)
            self.assertTrue(np.all(b.get0d('pace') == c.get0d('pace')))
            self.assertFalse(b.get0d('pace') is c.get0d('pace'))
            xb = b.get1d('x')
            xc = c.get1d('x')
            self.assertTrue(np.all(xb == xc))
            self.assertFalse(xb is xc)
            yb = b.get1d('y')
            yc = c.get1d('y')
            self.assertTrue(np.all(yb == yc))
            self.assertFalse(yb is yc)
Ejemplo n.º 21
0
    def test_write_read(self):
        # Test writing and reading an ATF file.

        with TemporaryDirectory() as d:
            # Create data log
            log = myokit.DataLog()
            log.set_time_key('time')
            log['time'] = np.arange(100)
            log['sint'] = np.sin(log['time'])
            log['cost'] = np.cos(log['time'])

            # Write atf file
            path = d.path('test.atf')
            axon.save_atf(log, path)

            # Read atf file
            log2 = axon.load_atf(path)
            self.assertEqual(len(log), len(log2))
            self.assertEqual(set(log.keys()), set(log2.keys()))
            for k, v in log.items():
                self.assertTrue(np.all(v == log2[k]))

            # Write selected fields
            axon.save_atf(log, path, fields=['time', 'sint'])
            log2 = axon.load_atf(path)
            self.assertEqual(set(log2.keys()), set(['time', 'sint']))

            # Time must be regularly spaced
            log['time'][-1] *= 2
            self.assertRaisesRegex(ValueError, 'regularly spaced',
                                   axon.save_atf, log, path)

            # Field names can't contain quotes
            log['time'] = np.arange(100)
            log['si"nt'] = log['sint']
            self.assertRaisesRegex(ValueError, 'double quotes', axon.save_atf,
                                   log, path)

            # Field names can't have newlines
            del (log['si"nt'])
            log['si\nnt'] = log['sint']
            self.assertRaisesRegex(ValueError, 'newlines', axon.save_atf, log,
                                   path)

            # Fields in `fields` must exist
            del (log['si\nnt'])
            self.assertRaisesRegex(ValueError,
                                   'not found',
                                   axon.save_atf,
                                   log,
                                   path,
                                   fields=['time', 'sint', 'hi'])

            # Try using on other formats
            log.save_csv(path)
            self.assertRaisesRegex(Exception, 'file type', axon.load_atf, path)

            # Try reading raw meta data (no key-value pairs)
            with open(path, 'w') as f:
                f.write('ATF\t1.0\n')
                f.write('1\t3\n')
                f.write('"Hello! This is raw meta data"\n')
                f.write('"time"\t"sint"\t"cost"\n')
                f.write('0\t0.0\t1.0\n')
                f.write('1\t10\t20\n')
                f.write('2\t30\t40\n')
            log2 = axon.load_atf(path)

            # Test invalid header detection
            with open(path, 'w') as f:
                f.write('ATF\t1.0\n')
                f.write('1\t3\n')
                f.write('Hello! This is raw meta data\n')
                f.write('"time"\t"sint"\t"cost"\n')
                f.write('0\t0.0\t1.0\n')
                f.write('1\t10\t20\n')
                f.write('2\t30\t40\n')
            self.assertRaisesRegex(Exception, 'double quotation',
                                   axon.load_atf, path)

            # Bad column headers
            with open(path, 'w') as f:
                f.write('ATF\t1.0\n')
                f.write('1\t3\n')
                f.write('"Hello! This is raw meta data"\n')
                f.write('Bonjou\t"time"\t"sint"\t"cost"\n')
                f.write('0\t0.0\t1.0\n')
                f.write('1\t10\t20\n')
                f.write('2\t30\t40\n')
            self.assertRaisesRegex(Exception, 'column headers', axon.load_atf,
                                   path)

            # Bad column headers
            with open(path, 'w') as f:
                f.write('ATF\t1.0\n')
                f.write('1\t3\n')
                f.write('"Hello! This is raw meta data"\n')
                f.write('time"\t"sint"\t"cost"\n')
                f.write('0\t0.0\t1.0\n')
                f.write('1\t10\t20\n')
                f.write('2\t30\t40\n')
            self.assertRaisesRegex(Exception, 'column headers', axon.load_atf,
                                   path)

            # Too many headers
            with open(path, 'w') as f:
                f.write('ATF\t1.0\n')
                f.write('1\t3\n')
                f.write('"Hello! This is raw meta data"\n')
                f.write('"Bonjour"\t"time"\t"sint"\t"cost"\n')
                f.write('0\t0.0\t1.0\n')
                f.write('1\t10\t20\n')
                f.write('2\t30\t40\n')
            self.assertRaisesRegex(Exception, 'found 4', axon.load_atf, path)

            # Commas as delimiter are ok
            with open(path, 'w') as f:
                f.write('ATF\t1.0\n')
                f.write('1\t3\n')
                f.write('"Hello! This is raw meta data"\n')
                f.write('"time","sint","cost"\n')
                f.write('0,0.0,1.0\n')
                f.write('1,10,20\n')
                f.write('2,30,40\n')
            axon.load_atf(path)

            # But can't mix them
            with open(path, 'w') as f:
                f.write('ATF\t1.0\n')
                f.write('1\t3\n')
                f.write('"Hello! This is raw meta data"\n')
                f.write('"time"\t"sint","cost"\n')
                f.write('0,0.0,1.0\n')
                f.write('1,10,20\n')
                f.write('2,30,40\n')
            self.assertRaisesRegex(Exception, 'Mixed delimiters',
                                   axon.load_atf, path)

            # Too many columns
            with open(path, 'w') as f:
                f.write('ATF\t1.0\n')
                f.write('1\t3\n')
                f.write('"Hello! This is raw meta data"\n')
                f.write('"time"\t"sint"\t"cost"\n')
                f.write('0\t0.0\t1.0\n')
                f.write('1\t10\t20\t100\n')
                f.write('2\t30\t40\n')
            self.assertRaisesRegex(Exception, 'Invalid data', axon.load_atf,
                                   path)
Ejemplo n.º 22
0
    def test_format_parse_error(self):
        # Test format_parse_error.

        # Test basic formatting, with and without source
        bad = '    5 + / 2'
        try:
            myokit.parse_expression(bad)
        except myokit.ParseError as e:

            # No source
            self.assertEqual(
                myokit.format_parse_error(e),
                '\n'.join([
                    'Syntax error',
                    '  Unexpected token SLASH "/" expecting expression',
                    'On line 1 character 8',
                ])
            )

            # List-of-strings source
            self.assertEqual(
                myokit.format_parse_error(e, source=[bad]),
                '\n'.join([
                    'Syntax error',
                    '  Unexpected token SLASH "/" expecting expression',
                    'On line 1 character 8',
                    '  5 + / 2',
                    '      ^'
                ])
            )

            # File source
            with TemporaryDirectory() as d:
                path = d.path('mmt')
                with open(path, 'w') as f:
                    f.write(bad + '\n')
                myokit.format_parse_error(e, source=path),
                '\n'.join([
                    'Syntax error',
                    '  Unexpected token SLASH "/" expecting expression',
                    'On line 1 character 8',
                    '  5 + / 2',
                    '      ^'
                ])

            # Line doesn't exist in source
            self.assertEqual(
                myokit.format_parse_error(e, source=[]),
                '\n'.join([
                    'Syntax error',
                    '  Unexpected token SLASH "/" expecting expression',
                    'On line 1 character 8',
                ])
            )

            # Char doesn't exist in source
            self.assertEqual(
                myokit.format_parse_error(e, source=['x']),
                '\n'.join([
                    'Syntax error',
                    '  Unexpected token SLASH "/" expecting expression',
                    'On line 1 character 8',
                ])
            )

        # Very long lines
        bad = '    1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 100 + 1000 + 11'
        bad += ' + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22'
        bad += ' + 23 + 24 + 25 + 26 + 27 + 28 + 29 + 30 + 31'

        # Error near start
        error = '\n'.join([
            'Syntax error',
            '  Unexpected token SLASH "/" expecting expression',
            'On line 1 character 12',
            '  1 + 2 + / 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 100 + 1000 + ..',
            '          ^',
        ])
        b = bad[:12] + '/ ' + bad[12:]
        try:
            myokit.parse_expression(b)
        except myokit.ParseError as e:
            self.assertEqual(myokit.format_parse_error(e, source=[b]), error)

        error = '\n'.join([
            'Syntax error',
            '  Unexpected token SLASH "/" expecting expression',
            'On line 1 character 83',
            '  ..+ 12 + 13 + 14 + 15 + / 16 + 17 + 18 + 19 + 20 + 21 + 22..',
            '                          ^',
        ])
        b = bad[:83] + '/ ' + bad[83:]
        try:
            myokit.parse_expression(b)
        except myokit.ParseError as e:
            self.assertEqual(myokit.format_parse_error(e, source=[b]), error)

        error = '\n'.join([
            'Syntax error',
            '  Unexpected token SLASH "/" expecting expression',
            'On line 1 character 133',
            '  ..+ 21 + 22 + 23 + 24 + 25 + / 26 + 27 + 28 + 29 + 30 + 31',
            '                               ^',
        ])
        b = bad[:133] + '/ ' + bad[133:]
        try:
            myokit.parse_expression(b)
        except myokit.ParseError as e:
            self.assertEqual(myokit.format_parse_error(e, source=[b]), error)
Ejemplo n.º 23
0
    def test_combined(self):
        # Test loading, saving, conversion from data log.

        # Create simulation log with 1d data
        log = myokit.DataLog()
        log.set_time_key('time')
        t = np.linspace(0, 1, 20)
        log['time'] = t
        log['0.0.x'] = np.sin(t)
        log['0.1.x'] = np.cos(t)
        log['0.2.x'] = np.tan(t)
        log['1.0.x'] = np.sin(2 * t)
        log['1.1.x'] = np.cos(2 * t)
        log['1.2.x'] = np.tan(2 * t)

        # Convert to datablock
        b = log.block2d()

        # Check block contents
        self.assertTrue(np.all(b.time() == t))
        self.assertFalse(b.time() is t)
        self.assertEqual(b.len0d(), 0)
        self.assertEqual(b.len2d(), 1)
        x = b.get2d('x')
        for xx in range(2):
            for yy in range(3):
                self.assertTrue(np.all(x[:, yy, xx] == log['x', xx, yy]))

        # Make bigger log, try again
        log['pace'] = np.ones(t.shape) + t**2
        log['0.0.y'] = np.sqrt(t)
        log['0.1.y'] = 1 + np.sqrt(t)
        log['0.2.y'] = 2 + np.sqrt(t)
        log['1.0.y'] = np.sqrt(t * 2)
        log['1.1.y'] = 1 + np.sqrt(t * 2)
        log['1.2.y'] = 2 + np.sqrt(t * 3)

        # Convert to datablock
        b = log.block2d()

        # Check block contents
        self.assertTrue(np.all(b.time() == t))
        self.assertFalse(b.time() is t)
        self.assertEqual(b.len0d(), 1)
        self.assertEqual(b.len2d(), 2)
        self.assertTrue(np.all(b.get0d('pace') == log['pace']))
        self.assertFalse(b.get0d('pace') is log['pace'])
        x = b.get2d('x')
        y = b.get2d('y')
        for xx in range(2):
            for yy in range(3):
                self.assertTrue(np.all(x[:, yy, xx] == log['x', xx, yy]))
                self.assertTrue(np.all(y[:, yy, xx] == log['y', xx, yy]))

        # Test reading and writing
        with TemporaryDirectory() as td:
            fname = td.path('block2d.zip')
            b.save(fname)
            c = myokit.DataBlock2d.load(fname)

            # Test block contents
            self.assertTrue(np.all(b.time() == c.time()))
            self.assertFalse(b.time() is c.time())
            self.assertEqual(c.len0d(), 1)
            self.assertEqual(c.len2d(), 2)
            self.assertTrue(np.all(b.get0d('pace') == c.get0d('pace')))
            self.assertFalse(b.get0d('pace') is c.get0d('pace'))
            xb = b.get2d('x')
            xc = c.get2d('x')
            self.assertTrue(np.all(xb == xc))
            self.assertFalse(xb is xc)
            yb = b.get2d('y')
            yc = c.get2d('y')
            self.assertTrue(np.all(yb == yc))
            self.assertFalse(yb is yc)
Ejemplo n.º 24
0
    def test_save(self):
        # Test if the correct parts are saved/loaded from disk using the
        # ``save()`` method.

        # Test example loading
        m, p, x = myokit.load('example')
        self.assertIsInstance(m, myokit.Model)
        self.assertIsInstance(p, myokit.Protocol)
        self.assertTrue(isinstance(x, basestring))

        # Save all three and reload
        with TemporaryDirectory() as d:
            opath = d.path('test.mmt')
            myokit.save(opath, m, p, x)
            mm, pp, xx = myokit.load(opath)
            self.assertEqual(m.code(), mm.code())
            self.assertEqual(p.code(), pp.code())
            self.assertEqual(x, xx)

        # Save only model
        with TemporaryDirectory() as d:
            opath = d.path('test.mmt')
            myokit.save(opath, model=m)
            with open(opath, 'r') as f:
                text = f.read()
            self.assertTrue('[[model]]' in text)
            self.assertFalse('[[protocol]]' in text)
            self.assertFalse('[[script]]' in text)
            mm, pp, xx = myokit.load(opath)
            self.assertEqual(mm.code(), m.code())
            self.assertEqual(pp, None)
            self.assertEqual(xx, None)

        # Save only protocol
        with TemporaryDirectory() as d:
            opath = d.path('test.mmt')
            myokit.save(opath, protocol=p)
            with open(opath, 'r') as f:
                text = f.read()
            self.assertFalse('[[model]]' in text)
            self.assertTrue('[[protocol]]' in text)
            self.assertFalse('[[script]]' in text)
            mm, pp, xx = myokit.load(opath)
            self.assertEqual(mm, None)
            self.assertEqual(pp.code(), p.code())
            self.assertEqual(xx, None)

        # Save only script
        with TemporaryDirectory() as d:
            opath = d.path('test.mmt')
            myokit.save(opath, script=x)
            with open(opath, 'r') as f:
                text = f.read()
            self.assertFalse('[[model]]' in text)
            self.assertFalse('[[protocol]]' in text)
            self.assertTrue('[[script]]' in text)
            mm, pp, xx = myokit.load(opath)
            self.assertEqual(mm, None)
            self.assertEqual(pp, None)
            self.assertEqual(xx, x)

        # Save all but model
        with TemporaryDirectory() as d:
            opath = d.path('test.mmt')
            myokit.save(opath, protocol=p, script=x)
            with open(opath, 'r') as f:
                text = f.read()
            self.assertFalse('[[model]]' in text)
            self.assertTrue('[[protocol]]' in text)
            self.assertTrue('[[script]]' in text)
            mm, pp, xx = myokit.load(opath)
            self.assertEqual(mm, None)
            self.assertEqual(pp.code(), p.code())
            self.assertEqual(xx, x)

        # Save all but protocol
        with TemporaryDirectory() as d:
            opath = d.path('test.mmt')
            myokit.save(opath, model=m, script=x)
            with open(opath, 'r') as f:
                text = f.read()
            self.assertTrue('[[model]]' in text)
            self.assertFalse('[[protocol]]' in text)
            self.assertTrue('[[script]]' in text)
            mm, pp, xx = myokit.load(opath)
            self.assertEqual(mm.code(), m.code())
            self.assertEqual(pp, None)
            self.assertEqual(xx, x)

        # Save all but script
        with TemporaryDirectory() as d:
            opath = d.path('test.mmt')
            myokit.save(opath, model=m, protocol=p)
            with open(opath, 'r') as f:
                text = f.read()
            self.assertTrue('[[model]]' in text)
            self.assertTrue('[[protocol]]' in text)
            self.assertFalse('[[script]]' in text)
            mm, pp, xx = myokit.load(opath)
            self.assertEqual(mm.code(), m.code())
            self.assertEqual(pp.code(), p.code())
            self.assertEqual(xx, None)

        # Save all as strings
        with TemporaryDirectory() as d:
            opath = d.path('test.mmt')
            myokit.save(opath, m, p, x)
            with open(opath, 'r') as f:
                text1 = f.read()
            myokit.save(opath, m.code(), p.code(), x)
            with open(opath, 'r') as f:
                text2 = f.read()
            self.assertEqual(text1, text2)

        # Save all as strings without [[model]] or [[protocol]] tage
        with TemporaryDirectory() as d:
            opath = d.path('test.mmt')
            myokit.save(opath, m, p, x)
            with open(opath, 'r') as f:
                text1 = f.read()
            mcode = '\n'.join(m.code().splitlines()[1:])
            pcode = '\n'.join(p.code().splitlines()[1:])
            myokit.save(opath, mcode, pcode, x)
            with open(opath, 'r') as f:
                text2 = f.read()
            self.assertEqual(text1, text2)

        # Save all, compare with string generated version
        with TemporaryDirectory() as d:
            opath = d.path('test.mmt')
            myokit.save(opath, model=m, protocol=p, script=x)
            with open(opath, 'r') as f:
                text = f.read()
            self.assertEqual(text, myokit.save(model=m, protocol=p, script=x))
Ejemplo n.º 25
0
    def _test(self, e, model=None, protocol=None):
        """ Test a given exporter `e`. """

        # Test info method.
        self.assertIsInstance(e.post_export_info(), basestring)

        # Load model, protocol
        m, p = model, protocol
        if m is None:
            m = myokit.load_model('example')
        if p is None:
            p = myokit.load_protocol('example')

        with TemporaryDirectory() as d:
            path = d.path()

            # Try exports
            exports = 0

            # Try model export
            if e.supports_model():
                exports += 1

                # Basic export
                fpath = os.path.join(path, 'model.txt')
                ret = e.model(fpath, m)
                self.assertIsNone(ret)
                self.assertTrue(os.path.isfile(fpath))

                # Unnamed model
                name = m.name()
                try:
                    m.set_name(None)
                    ret = e.model(fpath, m)
                    self.assertIsNone(ret)
                    self.assertTrue(os.path.isfile(fpath))
                finally:
                    m.set_name(name)

            else:
                self.assertRaises(NotImplementedError, e.model, path, m)

            # Try runnable export
            if e.supports_runnable():
                exports += 1

                # Check without protocol
                dpath = os.path.join(path, 'runnable1')
                ret = e.runnable(dpath, m)
                self.assertIsNone(ret)
                self.assertTrue(os.path.isdir(dpath))
                self.assertTrue(len(os.listdir(dpath)) > 0)

                # Check with protocol
                dpath = os.path.join(path, 'runnable2')
                ret = e.runnable(dpath, m, p)
                self.assertIsNone(ret)
                self.assertTrue(os.path.isdir(dpath))
                self.assertTrue(len(os.listdir(dpath)) > 0)

                # Write to complex path
                dpath = os.path.join(path, 'runnable3', 'nest', 'test')
                ret = e.runnable(dpath, m, p)
                self.assertIsNone(ret)
                self.assertTrue(os.path.isdir(dpath))
                self.assertTrue(len(os.listdir(dpath)) > 0)

            else:

                self.assertRaises(NotImplementedError, e.runnable, path, m, p)

            # Test if any exports were available
            if exports == 0:
                raise Exception('No types of export supported by: ' + exporter)
Ejemplo n.º 26
0
    def test_runnable_exporter_shared(self):
        # Test shared functionality of the TemplatedRunnableExporters.

        e = myokit.formats.exporter('ansic')

        # Load model, protocol
        m, p, x = myokit.load('example')

        # Create empty output directory as subdirectory of DIR_OUT
        with TemporaryDirectory() as d:
            path = d.path()

            # Simple export
            dpath = os.path.join(path, 'runnable1')
            ret = e.runnable(dpath, m)
            self.assertIsNone(ret)
            self.assertTrue(os.path.isdir(dpath))
            self.assertTrue(len(os.listdir(dpath)) > 0)

            # Write to complex path
            dpath = os.path.join(path, 'runnable2', 'nest', 'test')
            ret = e.runnable(dpath, m, p)
            self.assertIsNone(ret)
            self.assertTrue(os.path.isdir(dpath))
            self.assertTrue(len(os.listdir(dpath)) > 0)

            # Overwrite existing path
            ret = e.runnable(dpath, m, p)
            self.assertIsNone(ret)
            self.assertTrue(os.path.isdir(dpath))
            self.assertTrue(len(os.listdir(dpath)) > 0)

            # Path pointing to file
            dpath = os.path.join(path, 'file')
            with open(dpath, 'w') as f:
                f.write('contents\n')
            self.assertRaisesRegex(myokit.ExportError, 'file exists',
                                   e.runnable, dpath, m, p)

            # Directory exists where we're trying to write a file
            dpath = os.path.join(path, 'runnable3')
            fname = os.path.join(dpath, 'sim.c')
            os.makedirs(fname)
            self.assertRaisesRegex(myokit.ExportError, 'Directory exists',
                                   e.runnable, dpath, m, p)

            # Directory embedded in the output file path
            def embedded():
                return {'sim.c': 'nested/sim.c'}

            # 1. Normal operation
            e._dict = embedded
            dpath = os.path.join(path, 'runnable4')
            ret = e.runnable(dpath, m, p)
            self.assertIsNone(ret)
            self.assertTrue(os.path.isdir(dpath))
            self.assertTrue(len(os.listdir(dpath)) > 0)

            # 2. Try to create directory where file exists
            def embedded():
                return {'sim.c': 'nested/sim.c/som.c'}

            e._dict = embedded
            dpath = os.path.join(path, 'runnable4')
            self.assertRaisesRegex(myokit.ExportError, 'file or link',
                                   e.runnable, dpath, m, p)