Skip to main content
`Ctrl`+`K`

# ULM files

Simple and efficient pythonic file-format

Stores ndarrays as binary data and Python’s built-in datatypes (bool, int, float, complex, str, dict, list, tuple, None) as json.

ase.io.ulm.open(filename, mode='r', index=None, tag=None)

  Open ulm-file.

  filename: str

    Filename.

  mode: str

    Mode. Must be ‘r’ for reading, ‘w’ for writing to a new file (overwriting an existing one) or ‘a’ for appending to an existing file.

  index: int

    Index of item to read. Defaults to 0.

  tag: str

    Magic ID string.

  Returns a `Reader` or a `Writer` object. May raise `InvalidULMFileError`.

exception ase.io.ulm.InvalidULMFileError

## File layout

When there is only a single item:

    0: "- of Ulm" (magic prefix, ascii)
    8: "                " (tag, ascii)
    24: version (int64)
    32: nitems (int64)
    40: 48 (position of offsets, int64)
    48: p0 (offset to json data, int64)
    56: array1, array2, ... (8-byte aligned ndarrays)
    p0: n (length of json data, int64)
    p0+8: json data
    p0+8+n: EOF

Examples

Writing:

    >>> import numpy as np
    >>> import ase.io.ulm as ulm
    >>> with ulm.open('x.ulm', 'w') as w:
    ...     w.write(a=np.ones(7), b=42, c='abc')
    ...     w.write(d=3.14)

Reading:

    >>> r = ulm.open('x.ulm')
    >>> print(r.c)
    abc
    >>> r.close()

To see what’s inside ‘x.ulm’ do this:

    $ ase ulm x.ulm
    x.ulm  (tag: "", 1 item)
    item #0:
    {
        a: <ndarray shape=(7,) dtype=float64>,
        b: 42,
        c: abc,
        d: 3.14}

class ase.io.ulm.Writer(fd, mode='w', tag='', data=None)

  Create writer object.

  fd: str

    Filename.

  mode: str

    Mode. Must be ‘w’ for writing to a new file (overwriting an existing one) and ‘a’ for appending to an existing file.

  tag: str

    Magic ID string.

  add_array(name, shape, dtype=<class 'float'>)

    Add ndarray object.

    Set name, shape and dtype for array and fill in the data in chunks later with the fill() method.

  child(name)

    Create child-writer object.

  close()

    Close file.

  fill(a)

    Fill in ndarray chunks for array currently being written.

  sync()

    Write data dictionary.

    Write bool, int, float, complex and str data, shapes and dtypes for ndarrays.

  write(*args, **kwargs)

    Write data.

    Examples:

        writer.write('n', 7)
        writer.write(n=7)
        writer.write(n=7, s='abc', a=np.zeros(3), abc=obj)

    If obj is not one of the supported data types (bool, int, float, complex, tupl, list, dict, None or ndarray) then it must have a obj.write(childwriter) method.

class ase.io.ulm.Reader(fd, index=0, data=None, _little_endian=None)

  Create reader.

  asdict()

    Read everything now and convert to dict.

  get(attr, value=None)

    Get attr or value if no such attr.

  get_tag()

    Return special tag string.

  keys()

    Return list of keys.

## More examples

In the following we append to the ulm-file from above and demonstrae how to write a big array in chunks:

    >>> w = ulm.open('x.ulm', 'a')
    >>> w.add_array('bigarray', (10, 1000), float)
    >>> for i in range(10):
    ...     w.fill(np.ones(1000))
    ...
    >>> w.close()

Now read first and second items:

    >>> with ulm.open('x.ulm') as r:
    ...     print(r.keys())
    dict_keys(['a', 'b', 'c', 'd'])
    >>> with ulm.open('x.ulm', index=1) as r:
    ...     print(r.keys())
    dict_keys(['bigarray'])

To get all the data, it is possible to iterate over the items in the file.

    >>> for i, r in enumerate(ulm.Reader('x.ulm')):
    ...     for k in r.keys():
    ...         print(i, k)
    0 a
    0 b
    0 c
    0 d
    1 bigarray
    >>> r.close()

The different parts (items) of the file are numbered by the index argument:

    >>> r = ulm.Reader('x.ulm')
    >>> r[1].bigarray.shape
    (10, 1000)
    >>> r.close()

## Versions

1. Initial version.

2. Added support for big endian machines. Json data may now have _little_endian=False item.

3. Changed magic string from “AFFormat” to “- of Ulm”.