Reads data from an HDF5 file (high level).

    High level function to read one or more pieces of data from an HDF5
    file located at the paths specified in `paths` into Python
    types. Each path is specified as a POSIX style path where the data
    to read is located.

    There are various options that can be used to influence how the data
    is read. They can be passed as an already constructed ``Options``
    into `options` or as additional keywords that will be used to make
    one by ``options = Options(**keywords)``.

    Paths are POSIX style and can either be given directly as ``str`` or
    ``bytes``, or the separated path can be given as an iterable of
    ``str`` and ``bytes``. Each part of a separated path is escaped
    using ``utilities.escape_path``. Otherwise, the path is assumed to
    be already escaped. Escaping is done so that targets with a part
    that starts with one or more periods, contain slashes, and/or
    contain nulls can be used without causing the wrong Group to be
    looked in or the wrong target to be looked at. It essentially allows
    one to make a Dataset named ``'..'`` or ``'a/a'`` instead of moving
    around in the Dataset hierarchy.

    Parameters
    ----------
    paths : iterable of paths
        An iterable of paths to read data from. Each must be a POSIX
        style path where the directory name is the Group to put it in
        and the basename is the name to write it to. The format of
        paths is described in the paragraph above.
    filename : str, optional
        The name of the HDF5 file to read data from.
    options : Options, optional
        The options to use when reading. Is mutually exclusive with any
        additional keyword arguments given (set to ``None`` or don't
        provide to use them).
    **keywords :
        If `options` was not provided or was ``None``, these are used as
        arguments to make a ``Options``.

    Returns
    -------
    datas : iterable
        An iterable holding the piece of data for each path in `paths`
        in the same order.

    Raises
    ------
    exceptions.CantReadError
        If reading the data can't be done.

    See Also
    --------
    utilities.process_path
    utilities.escape_path
    read : Reads just a single piece of data
    writes
    write
    Options
    utilities.read_data : Low level version.

def reads(paths, filename='data.h5', options=None, **keywords):
    """ Reads data from an HDF5 file (high level).

    High level function to read one or more pieces of data from an HDF5
    file located at the paths specified in `paths` into Python
    types. Each path is specified as a POSIX style path where the data
    to read is located.

    There are various options that can be used to influence how the data
    is read. They can be passed as an already constructed ``Options``
    into `options` or as additional keywords that will be used to make
    one by ``options = Options(**keywords)``.

    Paths are POSIX style and can either be given directly as ``str`` or
    ``bytes``, or the separated path can be given as an iterable of
    ``str`` and ``bytes``. Each part of a separated path is escaped
    using ``utilities.escape_path``. Otherwise, the path is assumed to
    be already escaped. Escaping is done so that targets with a part
    that starts with one or more periods, contain slashes, and/or
    contain nulls can be used without causing the wrong Group to be
    looked in or the wrong target to be looked at. It essentially allows
    one to make a Dataset named ``'..'`` or ``'a/a'`` instead of moving
    around in the Dataset hierarchy.

    Parameters
    ----------
    paths : iterable of paths
        An iterable of paths to read data from. Each must be a POSIX
        style path where the directory name is the Group to put it in
        and the basename is the name to write it to. The format of
        paths is described in the paragraph above.
    filename : str, optional
        The name of the HDF5 file to read data from.
    options : Options, optional
        The options to use when reading. Is mutually exclusive with any
        additional keyword arguments given (set to ``None`` or don't
        provide to use them).
    **keywords :
        If `options` was not provided or was ``None``, these are used as
        arguments to make a ``Options``.

    Returns
    -------
    datas : iterable
        An iterable holding the piece of data for each path in `paths`
        in the same order.

    Raises
    ------
    exceptions.CantReadError
        If reading the data can't be done.

    See Also
    --------
    utilities.process_path
    utilities.escape_path
    read : Reads just a single piece of data
    writes
    write
    Options
    utilities.read_data : Low level version.

    """
    # Pack the different options into an Options class if an Options was
    # not given. By default, the matlab_compatible option is set to
    # False. So, if it wasn't passed in the keywords, this needs to be
    # added to override the default value (True) for a new Options.
    if not isinstance(options, Options):
        kw = copy.deepcopy(keywords)
        if 'matlab_compatible' not in kw:
            kw['matlab_compatible'] = False
        options = Options(**kw)

    # Process the paths and stuff the group names and target names as
    # tuples into toread.
    toread = []
    for p in paths:
        groupname, targetname = utilities.process_path(p)

        # Pack them into toread
        toread.append((groupname, targetname))

    # Open the hdf5 file and start reading the data. This is all wrapped
    # in a try block, so that the file can be closed if any errors
    # happen (the error is re-raised).
    try:
        f = None
        f = h5py.File(filename, mode='r')

        # Read the data item by item
        datas = []
        for groupname, targetname in toread:
            # Check that the containing group is in f and is indeed a
            # group. If it isn't an error needs to be thrown.
            if groupname not in f \
                    or not isinstance(f[groupname], h5py.Group):
                raise exceptions.CantReadError( \
                    'Could not find containing Group ' \
                    + groupname + '.')

            # Hand off everything to the low level reader.
            datas.append(utilities.read_data(f, f[groupname],
                                             targetname, options))
    except:
        raise
    finally:
        if f is not None:
            f.close()

    return datas