Пример #1
0
 def test_date(self):
     # Test date formatting method.
     import time
     for i in range(3):
         a = time.strftime(myokit.DATE_FORMAT)
         b = myokit.date()
         if a == b:
             break
     self.assertEqual(a, b)
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))