docs: 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')