uproot.writing.writable.WritableNTuple
Defined in uproot.writing.writable on line 2894.
- class uproot.writing.writable.WritableNTuple(path, file, cascading)
- Parameters:
path (tuple of str) – Path of directory names to this RNTuple.
file (uproot.WritableFile) – Handle to the file in which this RNTuple can be found.
cascading (uproot.writing._cascadentuple.NTuple) – The low-level directory object.
Represents a writable
RNTuplefrom a ROOT file.Assigning data to a directory creates an RNTuple object by default starting in Uproot v5.7.0. This creates the RNTuple 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 RNTuple metadata from filling the first cluster, use the uproot.writing.writable.WritableDirectory.mkrntuple method:
my_directory.mkrntuple("tuple6", {"branch1": numpy_dtype, "branch2": awkward_type})
The
numpy_dtypeis any data that NumPy recognizes as anp.dtype, and theawkward_typeis an ak.types.Type from ak.type or a string in that form, such as"var * float64"for variable-length doubles.RNTuple can be extended using extend method:
my_directory["tuple6"].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 clusters 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 clusters), then do so. Filling the RNTuple a hundred events at a time (total of 10000 clusters) would be considerably slower for writing and reading, and the file would be much larger than it could otherwise be, even with compression.
path
- WritableNTuple.path
Path of directory names to this RNTuple as a tuple of strings.
object_path
- WritableNTuple.object_path
Path of directory names to this RNTuple as a single string, delimited by slashes.
file_path
- WritableNTuple.file_path
Filesystem path of the open file, or None if using a file-like object.
file
- WritableNTuple.file
Handle to the uproot.WritableDirectory in which this directory can be found.
close
- WritableNTuple.close()
Explicitly close the file.
(Files can also be closed with the Python
withstatement, as context managers.)After closing, objects cannot be read from or written to the file.
closed
compression
- WritableNTuple.compression
Compression algorithm and level (uproot.compression.Compression or None) used when writing pages to this RNTuple.
RNTuple compression is file-wide and is taken from the file header; individual per-column compression is not yet supported.
num_entries
- WritableNTuple.num_entries
The number of entries accumulated so far.
extend
- WritableNTuple.extend(data, accept_new_fields=False)
- Parameters:
data (dict of str → arrays) – More array data to add to the RNTuple.
accept_new_fields (bool) – If False (default), raises ValueError if data contains fields not already in the RNTuple, forcing the user to call add_fields first. If True, new fields are automatically added back-filled with zeros for existing entries, then extended with the provided values for new entries.
This method adds data to an existing RNTuple, whether it was created through assignment or uproot.writing.writable.WritableDirectory.mkrntuple.
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,
with uproot.update("file.root") as f: f["mytuple"].extend({ "x": np.array([4, 5, 6]), "y": np.array([40, 50, 60]), }) # automatically add new field and extend with uproot.update("file.root") as f: f["mytuple"].extend({"x": np.array([7, 8]), "z": np.array([70, 80])}, accept_new_fields=True)
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
100000per 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).Note
Extending an RNTuple opened with uproot.writing.writable.WritableDirectory.update only works if every column uses an encoding Uproot itself writes. RNTuples written by ROOT commonly use column encodings (e.g. split encoding) that Uproot does not yet write, and are rejected with a
ValueErrorrather than risk writing an inconsistent file. In practice,extend/add_fieldsafter reopening a file only work reliably on RNTuples that Uproot itself wrote.
add_fields
- WritableNTuple.add_fields(new_fields)
- Parameters:
new_fields (dict of str -> numpy dtype) – New field names and types. Only scalar numeric types are accepted (e.g.
np.int32,np.float64). Variable-length or nested types are not supported.
Adds new fields to this RNTuple, back-filled with zeros for existing entries. Only top-level fields or subfields of existing untyped record fields are supported.
Note: when using
accept_new_fields=Trueinextend(), new fields must be flat (scalar) types. Jagged or nested new fields will fail the form compatibility check inextend.- Raises:
TypeError – if a field type is not a simple scalar numeric type.
ValueError – if a field already exists, if the subfield parent is not found or is a typed struct (C++ typename), if the file was opened without a file path (file-like objects are not supported), or if the RNTuple uses column encodings Uproot does not write (see the note below).
For example,
with uproot.update("file.root") as f: f["mytuple"].add_fields({"z": np.int32, "w": np.float32})
Note
Like extend, this only works on an RNTuple opened with uproot.writing.writable.WritableDirectory.update if every column uses an encoding Uproot itself writes. RNTuples written by ROOT commonly use column encodings (e.g. split encoding) that Uproot does not yet write, and are rejected with a
ValueError. In practice,add_fields/extendafter reopening a file only work reliably on RNTuples that Uproot itself wrote.