예제 #1
0
    def test_version(self):
        # Test the version() method.

        # Raw version
        raw = myokit.version(raw=True)
        self.assertIsInstance(raw, basestring)
        parts = raw.split('.')
        self.assertTrue(len(parts) in [3, 4])

        # Formatted version
        v = myokit.version()
        v = v.splitlines()
        self.assertEqual(len(v), 3)
예제 #2
0
def system(live_printing=False):
    """
    Returns a (long) string with system information.

    If ``live_printing`` is set to ``True``, no string is returned but the
    results are printed to screen as they come in.
    """

    # Print directly to screen or store in array
    if not live_printing:
        out = []
    else:
        # Create fake list interface that just prints
        class Out(object):
            def append(self, x):
                print(x)

            def extend(self, xs):
                print('\n'.join(xs))

        out = Out()

    # Basic system information
    out.append('== System information ==')
    out.append('Myokit: ' + myokit.version(raw=True))
    ver = iter(sys.version.splitlines())
    out.append('Python: ' + next(ver))
    out.extend([' ' * 8 + v for v in ver])
    out.append(
        'OS: ' + platform.system()
        + ' (' + sys.platform + ', ' + os.name + ')')
    out.append('')

    # Python requirements
    out.append('== Python requirements ==')
    out.append('NumPy: ' + _module_version('numpy'))
    out.append('SciPy: ' + _module_version('scipy'))
    out.append('Matplotlib: ' + _module_version('matplotlib'))
    out.append('ConfigParser: ' + _module_version('configparser'))
    out.append('Setuptools: ' + _module_version('setuptools'))
    out.append('')

    # Python extras
    out.append('== Python extras ==')
    out.append('SymPy: ' + _module_version('sympy'))
    ver = _module_version('cma')
    try:
        ver = ver[:ver.index('$')].strip()
    except ValueError:  # pragma: no cover
        pass
    out.append('CMAES: ' + ver)
    out.append('MoviePy: ' + _module_version('moviepy'))
    out.append('')

    # GUI toolkits
    out.append('== GUI ==')

    try:    # pragma: no cover
        from PyQt5.QtCore import QT_VERSION_STR
        out.append('PyQt5: ' + QT_VERSION_STR)
        out.append('  Sip: ' + _module_version('sip'))
        del(QT_VERSION_STR)
    except ImportError:
        out.append('PyQt5: Not found')

    try:    # pragma: no cover
        from PyQt4.QtCore import QT_VERSION_STR
        out.append('PyQt4: ' + QT_VERSION_STR)
        out.append('  Sip: ' + _module_version('sip'))
        del(QT_VERSION_STR)
    except ImportError:
        out.append('PyQt4: Not found')
    except RuntimeError:    # pragma: no cover
        # Happens if PyQt5 was also found
        out.append('PyQt4: OK')

    out.append('PySide: ' + _module_version('PySide'))
    out.append('PySide2: ' + _module_version('PySide2'))
    out.append('')

    # Development tools
    out.append('== Development tools ==')
    out.append('Sphinx: ' + _module_version('sphinx'))
    out.append('Flake8: ' + _module_version('flake8'))
    out.append('')

    # Simulation tools / compilation
    out.append('== Simulation tools ==')
    compiler = myokit.Compiler.info()
    if compiler is None:    # pragma: no cover
        out.append('Compiler: NOT FOUND')
        out.append('Sundials: Compiler not found')
        out.append('OpenCL: Compiler not found')
    else:
        out.append('Compiler: ' + compiler)
        out.append('Sundials: ' + (myokit.Sundials.version() or 'Not found'))

        opencl = myokit.OpenCL()
        if not opencl.supported():  # pragma: no cover
            out.append('OpenCL: No OpenCL support detected.')
        else:   # pragma: no cover
            devices = []
            for p in opencl.info().platforms:
                for d in p.devices:
                    devices.append(d.name + ' on ' + p.name)
            out.append('OpenCL: ' + str(len(devices)) + ' device(s) found')
            for d in devices:
                out.append('  ' + d)
            out.append('  Use `python -m myokit opencl` for more information.')

    if not live_printing:
        return '\n'.join(out)
def save_atf(log, filename, fields=None):
    """
    Saves the :class:`myokit.DataLog` ``log`` to ``filename`` in ATF format.

    ATF requires that the times in the log be regularly spaced.

    The first column in an ATF file should always be time. Remaining fields
    will be written in a random order. To indicate an order or make a selection
    of fields, pass in a sequence ``fields`` containing the field names.
    """
    log.validate()
    import myokit

    # Check filename
    filename = os.path.expanduser(filename)

    # Delimiters
    # Dos-style EOL: Open file in 'wb' mode to stop windows writing \r\r\n
    eol = '\r\n'
    delim = '\t'

    # Create data and keys lists
    data = [iter(log.time())]
    time = log.time_key()
    keys = [time]

    # Check fields
    if fields:
        for field in fields:
            field = str(field)
            if field == time:
                continue
            keys.append(field)
            try:
                data.append(iter(log[field]))
            except KeyError:
                raise ValueError('Variable <' + field + '> not found in log.')
    else:
        for k, v in log.items():
            if k != time:
                keys.append(k)
                data.append(iter(v))

    for k in keys:
        if '"' in k:
            raise ValueError('Column names must not contain double quotes.')
        if '\r' in k or '\n' in k:
            raise ValueError(
                'Column names must not contain newlines or carriage returns.')

    # Check if time is equally spaced
    t = np.asarray(log.time())
    dt = t[1:] - t[:-1]
    dt_ref = dt[0]
    dt_err = dt_ref * 1e-6
    if np.any(np.abs(dt - dt_ref) > dt_err):
        raise ValueError('The time variable must be regularly spaced.')

    # Create header
    header = []
    header.append(('myokit-version', 'Myokit ' + myokit.version(raw=True)))
    header.append(('date-created', myokit.date()))
    header.append(('sampling-interval', dt_ref))

    # Get sizes
    nh = len(header)
    nf = len(keys)
    nd = log.length()

    # Write file
    with open(filename, 'wb') as f:
        # Write version number
        f.write(('ATF 1.0' + eol).encode(_ENC))

        # Write number of header lines, number of fields
        f.write((str(nh) + delim + str(nf) + eol).encode(_ENC))
        for k, v in header:
            f.write(('"' + str(k) + '=' + str(v) + '"' + eol).encode(_ENC))

        # Write field names
        f.write((delim.join(['"' + k + '"' for k in keys]) + eol).encode(_ENC))

        # Write data
        for i in range(nd):
            f.write((
                delim.join([myokit.strfloat(next(d)) for d in data]) + eol
            ).encode(_ENC))
def version(raw=False):
    import myokit
    print(myokit.version(raw))