def array2tree(arr, name='tree', tree=None):
    """Convert a numpy structured array into a ROOT TTree.

    Fields of basic types, strings, and fixed-size subarrays of basic types are
    supported. ``np.object`` and ``np.float16`` are currently not supported.

    Parameters
    ----------
    arr : array
        A numpy structured array
    name : str (optional, default='tree')
        Name of the created ROOT TTree if ``tree`` is None.
    tree : ROOT TTree (optional, default=None)
        An existing ROOT TTree to be extended by the numpy array. Any branch
        with the same name as a field in the numpy array will be extended as
        long as the types are compatible, otherwise a TypeError is raised. New
        branches will be created and filled for all new fields.

    Returns
    -------
    root_tree : a ROOT TTree

    Notes
    -----
    When using the ``tree`` argument to extend and/or add new branches to an
    existing tree, note that it is possible to create branches of different
    lengths. This will result in a warning from ROOT when root_numpy calls the
    tree's ``SetEntries()`` method. Beyond that, the tree should still be
    usable. While it might not be generally recommended to create branches with
    differing lengths, this behaviour could be required in certain situations.
    root_numpy makes no attempt to prevent such behaviour as this would be more
    strict than ROOT itself. Also see the note about converting trees that have
    branches of different lengths into numpy arrays in the documentation of
    :func:`tree2array`.

    See Also
    --------
    array2root
    root2array
    tree2array

    Examples
    --------

    Convert a numpy array into a tree:

    >>> from root_numpy import array2tree
    >>> import numpy as np
    >>>
    >>> a = np.array([(1, 2.5, 3.4),
    ...               (4, 5, 6.8)],
    ...              dtype=[('a', np.int32),
    ...                     ('b', np.float32),
    ...                     ('c', np.float64)])
    >>> tree = array2tree(a)
    >>> tree.Scan()
    ************************************************
    *    Row   *         a *         b *         c *
    ************************************************
    *        0 *         1 *       2.5 *       3.4 *
    *        1 *         4 *         5 *       6.8 *
    ************************************************

    Add new branches to an existing tree (continuing from the example above):

    >>> b = np.array([(4, 10),
    ...               (3, 5)],
    ...              dtype=[('d', np.int32),
    ...                     ('e', np.int32)])
    >>> array2tree(b, tree=tree)
    <ROOT.TTree object ("tree") at 0x1449970>
    >>> tree.Scan()
    ************************************************************************
    *    Row   *         a *         b *         c *         d *         e *
    ************************************************************************
    *        0 *         1 *       2.5 *       3.4 *         4 *        10 *
    *        1 *         4 *         5 *       6.8 *         3 *         5 *
    ************************************************************************

    """
    import ROOT
    if tree is not None:
        if not isinstance(tree, ROOT.TTree):
            raise TypeError("tree must be a ROOT.TTree")
        incobj = ROOT.AsCObject(tree)
    else:
        incobj = None
    cobj = _librootnumpy.array2tree_toCObj(arr, name=name, tree=incobj)
    return ROOT.BindObject(cobj, 'TTree')
Convert a numpy structured array into a ROOT TTree.

    Fields of basic types, strings, and fixed-size subarrays of basic types are
    supported. ``np.object`` and ``np.float16`` are currently not supported.

    Parameters
    ----------
    arr : array
        A numpy structured array
    name : str (optional, default='tree')
        Name of the created ROOT TTree if ``tree`` is None.
    tree : ROOT TTree (optional, default=None)
        An existing ROOT TTree to be extended by the numpy array. Any branch
        with the same name as a field in the numpy array will be extended as
        long as the types are compatible, otherwise a TypeError is raised. New
        branches will be created and filled for all new fields.

    Returns
    -------
    root_tree : a ROOT TTree

    Notes
    -----
    When using the ``tree`` argument to extend and/or add new branches to an
    existing tree, note that it is possible to create branches of different
    lengths. This will result in a warning from ROOT when root_numpy calls the
    tree's ``SetEntries()`` method. Beyond that, the tree should still be
    usable. While it might not be generally recommended to create branches with
    differing lengths, this behaviour could be required in certain situations.
    root_numpy makes no attempt to prevent such behaviour as this would be more
    strict than ROOT itself. Also see the note about converting trees that have
    branches of different lengths into numpy arrays in the documentation of
    :func:`tree2array`.

    See Also
    --------
    array2root
    root2array
    tree2array

    Examples
    --------

    Convert a numpy array into a tree:

    >>> from root_numpy import array2tree
    >>> import numpy as np
    >>>
    >>> a = np.array([(1, 2.5, 3.4),
    ...               (4, 5, 6.8)],
    ...              dtype=[('a', np.int32),
    ...                     ('b', np.float32),
    ...                     ('c', np.float64)])
    >>> tree = array2tree(a)
    >>> tree.Scan()
    ************************************************
    *    Row   *         a *         b *         c *
    ************************************************
    *        0 *         1 *       2.5 *       3.4 *
    *        1 *         4 *         5 *       6.8 *
    ************************************************

    Add new branches to an existing tree (continuing from the example above):

    >>> b = np.array([(4, 10),
    ...               (3, 5)],
    ...              dtype=[('d', np.int32),
    ...                     ('e', np.int32)])
    >>> array2tree(b, tree=tree)
    <ROOT.TTree object ("tree") at 0x1449970>
    >>> tree.Scan()
    ************************************************************************
    *    Row   *         a *         b *         c *         d *         e *
    ************************************************************************
    *        0 *         1 *       2.5 *       3.4 *         4 *        10 *
    *        1 *         4 *         5 *       6.8 *         3 *         5 *
    ************************************************************************