docs: def tree2array(tree,
                 branches=None,
                 selection=None,
                 object_selection=None,
                 start=None,
                 stop=None,
                 step=None,
                 include_weight=False,
                 weight_name='weight',
                 cache_size=-1):
      """Convert a tree into a numpy structured array.
  
      Convert branches of strings and basic types such as bool, int, float,
      double, etc. as well as variable-length and fixed-length multidimensional
      arrays and 1D or 2D vectors of basic types and strings. ``tree2array`` can
      also create columns in the output array that are expressions involving the
      TTree branches (i.e. ``'vect.Pt() / 1000'``) similar to ``TTree::Draw()``.
      See the notes below for important details.
  
      Parameters
      ----------
      tree : ROOT TTree instance
          The ROOT TTree to convert into an array.
      branches : list of strings and tuples or a string or tuple, optional (default=None)
          List of branches and expressions to include as columns of the array or
          a single branch or expression in which case a nonstructured array is
          returned. If None then include all branches that can be converted.
          Branches or expressions that result in variable-length subarrays can be
          truncated at a fixed length by using the tuple ``(branch_or_expression,
          fill_value, length)`` or converted into a single value with
          ``(branch_or_expression, fill_value)`` where ``length==1`` is implied.
          ``fill_value`` is used when the original array is shorter than
          ``length``. This truncation is after any object selection performed
          with the ``object_selection`` argument.
      selection : str, optional (default=None)
          Only include entries fulfilling this condition. If the condition
          evaluates to multiple values per tree entry (e.g. conditions on array
          branches) then an entry will be included if the condition evaluates to
          true for at least one array element.
      object_selection : dict, optional (default=None)
          A dictionary mapping selection strings to branch names or lists of
          branch names. Only array elements passing the selection strings will be
          included in the output array per entry in the tree. The branches
          specified must be variable-length array-type branches and the length of
          the selection and branches it acts on must match for each tree entry.
          For example ``object_selection={'a > 0': ['a', 'b']}`` will include all
          elements of 'a' and corresponding elements of 'b' where 'a > 0' for
          each tree entry. 'a' and 'b' must have the same length in every tree
          entry.
      start, stop, step: int, optional (default=None)
          The meaning of the ``start``, ``stop`` and ``step`` parameters is the
          same as for Python slices. If a range is supplied (by setting some of
          the ``start``, ``stop`` or ``step`` parameters), only the entries in
          that range and fulfilling the ``selection`` condition (if defined) are
          used.
      include_weight : bool, optional (default=False)
          Include a column containing the tree weight ``TTree::GetWeight()``.
          Note that this will be the same value for all entries unless the tree
          is actually a TChain containing multiple trees with different weights.
      weight_name : str, optional (default='weight')
          The field name for the weight column if ``include_weight=True``.
      cache_size : int, optional (default=-1)
          Set the size (in bytes) of the TTreeCache used while reading a TTree. A
          value of -1 uses ROOT's default cache size. A value of 0 disables the
          cache.
  
      Notes
      -----
      Types are converted according to the following table:
  
      .. _conversion_table:
  
      ========================  ===============================
      ROOT                      NumPy
      ========================  ===============================
      ``Bool_t``                ``np.bool``
      ``Char_t``                ``np.int8``
      ``UChar_t``               ``np.uint8``
      ``Short_t``               ``np.int16``
      ``UShort_t``              ``np.uint16``
      ``Int_t``                 ``np.int32``
      ``UInt_t``                ``np.uint32``
      ``Float_t``               ``np.float32``
      ``Double_t``              ``np.float64``
      ``Long64_t``              ``np.int64``
      ``ULong64_t``             ``np.uint64``
      ``<type>[2][3]...``       ``(<nptype>, (2, 3, ...))``
      ``<type>[nx][2]...``      ``np.object``
      ``string``                ``np.object``
      ``vector<t>``             ``np.object``
      ``vector<vector<t> >``    ``np.object``
      ========================  ===============================
  
      * Variable-length arrays (such as ``x[nx][2]``) and vectors (such as
        ``vector<int>``) are converted to NumPy arrays of the corresponding
        types.
  
      * Fixed-length arrays are converted to fixed-length NumPy array fields.
  
      **Branches with different lengths:**
  
      Note that when converting trees that have branches of different lengths
      into numpy arrays, the shorter branches will be extended to match the
      length of the longest branch by repeating their last values. If all
      requested branches are shorter than the longest branch in the tree, this
      will result in a "read failure" since beyond the end of the longest
      requested branch no additional bytes will be read from the file and
      root_numpy is unable to distinguish this from other ROOT errors that result
      in no bytes being read. In this case, explicitly set the ``stop`` argument
      to the length of the longest requested branch.
  
  
      See Also
      --------
      root2array
      array2root
      array2tree
  
      """
      import ROOT
      if not isinstance(tree, ROOT.TTree):
          raise TypeError("tree must be a ROOT.TTree")
      cobj = ROOT.AsCObject(tree)
  
      if isinstance(branches, string_types):
          # single branch selected
          flatten = branches
          branches = [branches]
      elif isinstance(branches, tuple):
          if len(branches) not in (2, 3):
              raise ValueError(
                  "invalid branch tuple: {0}. "
                  "A branch tuple must contain two elements "
                  "(branch_name, fill_value) or three elements "
                  "(branch_name, fill_value, length) "
                  "to yield a single value or truncate, respectively".format(branches))
          flatten = branches[0]
          branches = [branches]
      else:
          flatten = False
  
      arr = _librootnumpy.root2array_fromtree(
          cobj, branches, selection, object_selection,
          start, stop, step,
          include_weight,
          weight_name,
          cache_size)
  
      if flatten:
          # select single column
          return arr[flatten]
      return arr