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)
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))