Return an `atom list` from elements and/or atom ids and coordinates.

    An `atom list` is a special object that some pywindowfunctions uses.
    It is a nested list of lists with each individual list containing:

        1. [[element, coordinates (x, y, z)], ...]

        2. [[element, atom key, coordinates (x, y, z)], ...]

    They work better for molecular re-building than two separate arrays for
    elements and coordinates do.

    Parameters
    ----------
    elements : :class:`numpy.ndarray`
        An array of all elements (type: str) in a molecule.

    coordinates : :class:`numpy.ndarray`
        An array containing molecule's coordinates.

    atom_ids : :class:`numpy.ndarray`, optional
        An array of all forcfield dependent atom keys (type:str) in a molecule.


    Returns
    -------
    list
        Version 1 or version 2 atom list depending on input parameters.

    Raises
    ------
    _FunctionError : :class:`Exception`
        Raised when wrong number of parameters is passed to the function.

def compose_atom_list(*args):
    """
    Return an `atom list` from elements and/or atom ids and coordinates.

    An `atom list` is a special object that some pywindowfunctions uses.
    It is a nested list of lists with each individual list containing:

        1. [[element, coordinates (x, y, z)], ...]

        2. [[element, atom key, coordinates (x, y, z)], ...]

    They work better for molecular re-building than two separate arrays for
    elements and coordinates do.

    Parameters
    ----------
    elements : :class:`numpy.ndarray`
        An array of all elements (type: str) in a molecule.

    coordinates : :class:`numpy.ndarray`
        An array containing molecule's coordinates.

    atom_ids : :class:`numpy.ndarray`, optional
        An array of all forcfield dependent atom keys (type:str) in a molecule.


    Returns
    -------
    list
        Version 1 or version 2 atom list depending on input parameters.

    Raises
    ------
    _FunctionError : :class:`Exception`
        Raised when wrong number of parameters is passed to the function.

    """
    if len(args) == 2:
        atom_list = [[
            i[0],
            round(float(i[1]), 8),
            round(float(i[2]), 8),
            round(float(i[3]), 8),
        ] for i in np.concatenate(
            (args[0].reshape(-1, 1), args[1]), axis=1)]
    elif len(args) == 3:
        atom_list = [
            [
                i[0],
                i[1],
                round(float(i[2]), 8),
                round(float(i[3]), 8),
                round(float(i[4]), 8),
            ]
            for i in np.concatenate(
                (np.concatenate(
                    (args[0].reshape(-1, 1), args[1].reshape(-1, 1)
                     ), axis=1), args[2]),
                axis=1)
        ]
    else:
        raise _FunctionError(
            "The compose_atom_list() function accepts only 2 or 3 arguments.")
    return atom_list