uproot.WritableTree

Defined in uproot.writing.writable on line 1558.

class uproot.writing.writable.WritableTree(path, file, cascading)
Parameters:
  • path (tuple of str) – Path of directory names to this TTree.

  • file (uproot.WritableFile) – Handle to the file in which this TTree can be found.

  • cascading (uproot.writing._cascadetree.Tree) – The low-level directory object.

Represents a writable TTree from a ROOT file.

This object would normally be created by assigning a TTree-like data to a uproot.WritableDirectory. For instance:

my_directory["tree1"] = {"branch1": np.array(...), "branch2": ak.Array(...)}
my_directory["tree2"] = numpy_structured_array
my_directory["tree3"] = awkward_record_array
my_directory["tree4"] = pandas_dataframe

Recognized data types:

  • dict of NumPy arrays (flat, multidimensional, and/or structured), Awkward Arrays containing one level of variable-length lists and/or one level of records, or a Pandas DataFrame with a numeric index

  • a single NumPy structured array (one level deep)

  • a single Awkward Array containing one level of variable-length lists and/or one level of records

  • a single Pandas DataFrame with a numeric index

The arrays may have different types, but their lengths must be identical, at least in the first dimension (i.e. number of entries).

If the Awkward Array contains variable-length lists (i.e. it is “jagged”), a counter TBranch will be created along with the data TBranch. ROOT needs the counter TBranch to quantify the size of the variable-size arrays. Combining Awkward Arrays with the same number of nested items using ak.zip prevents a proliferation of counter TBranches:

my_directory["tree5"] = ak.zip({"branch1": array1, "branch2": array2, "branch3": array3})

would produce only one counter TBranch.

Assigning TTree-like data to a directory creates the TTree object with all of its metadata and fills it with the contents of the arrays in one step. To separate the process of creating the TTree metadata from filling the first TBasket, use the uproot.writing.writable.WritableDirectory.mktree method:

my_directory.mktree("tree6", {"branch1": numpy_dtype, "branch2": awkward_type})

The uproot.writing.writable.WritableDirectory.mktree method can also control the title of the TTree and the rules used to name counter TBranches and nested field TBranches.

The numpy_dtype is any data that NumPy recognizes as a np.dtype, and the awkward_type is an ak.types.Type from ak.type or a string in that form, such as "var * float64" for variable-length doubles.

TBaskets can be added to each TBranch using the extend method:

my_directory["tree6"].extend({"branch1": another_numpy_array,
                              "branch2": another_awkward_array})

Be sure to make these extensions as large as is feasible within memory constraints, because a ROOT file full of small TBaskets is bloated (larger than it needs to be) and slow to read (especially for Uproot, but also for ROOT).

For instance, if you want to write a million events and have enough memory available to do that 100 thousand events at a time (total of 10 TBaskets), then do so. Filling the TTree a hundred events at a time (total of 10000 TBaskets) would be considerably slower for writing and reading, and the file would be much larger than it could otherwise be, even with compression.

path

WritableTree.path

Path of directory names to this TTree as a tuple of strings.

object_path

WritableTree.object_path

Path of directory names to this TTree as a single string, delimited by slashes.

file_path

WritableTree.file_path

Filesystem path of the open file, or None if using a file-like object.

file

WritableTree.file

Handle to the uproot.WritableDirectory in which this directory can be found.

close

WritableTree.close()

Explicitly close the file.

(Files can also be closed with the Python with statement, as context managers.)

After closing, objects cannot be read from or written to the file.

closed

WritableTree.closed

True if the file has been closed; False otherwise.

The file may have been closed explicitly with close or implicitly in the Python with statement, as a context manager.

After closing, objects cannot be read from or written to the file.

compression

WritableTree.compression

Compression algorithm and level (uproot.compression.Compression or None) for new TBaskets added to the TTree.

This property can be changed and doesn’t have to be the same as the compression of the file, which allows you to write different objects with different compression settings.

The following are equivalent:

my_directory["tree"]["branch1"].compression = uproot.ZLIB(1)
my_directory["tree"]["branch2"].compression = uproot.LZMA(9)

and

my_directory["tree"].compression = {"branch1": uproot.ZLIB(1),
                                    "branch2": uproot.LZMA(9)}

num_entries

WritableTree.num_entries

The number of entries accumulated so far.

num_baskets

WritableTree.num_baskets

The number of TBaskets accumulated so far.

extend

WritableTree.extend(data)
Parameters:

data (dict of str → arrays) – More array data to add to the TTree.

This method adds data to an existing TTree, whether it was created through assignment or uproot.writing.writable.WritableDirectory.mktree.

The arrays must be a dict, but the values of the dict can be any of the array/DataFrame types described in uproot.WritableTree. However, these types must be compatible with the established TBranch types, the dict must contain a key for every TBranch, and the arrays must have the same lengths (in their first dimension).

For example,

my_directory.mktree("tree6", {"branch1": numpy_dtype, "branch2": awkward_type})

my_directory["tree6"].extend({"branch1": another_numpy_array,
                              "branch2": another_awkward_array})

Warning

As a word of warning, be sure that each call to extend includes at least 100 kB per branch/array. (NumPy and Awkward Arrays have an nbytes property; you want at least 100000 per array.) If you ask Uproot to write very small TBaskets, it will spend more time working on TBasket overhead than actually writing data. The absolute worst case is one-entry-per-extend. See #428 (comment).

show

WritableTree.show(*, filter_name=<function no_filter>, filter_typename=<function no_filter>, filter_branch=<function no_filter>, recursive=True, full_paths=True, name_width=20, typename_width=24, interpretation_width=30, stream=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>)

Opens the TTree for reading and calls uproot.behaviors.TBranch.HasBranches.show on it (follow link for documentation of this method).