KAHIBARO
Discord Login Register

13.1. Introduction to TTrees

Events

In ROOT, a TTree is designed to store event based data. An event is one logical instance of your measurement or simulation. What counts as an event depends on your experiment or dataset. In a particle physics experiment, one event is usually everything that happened in one beam crossing or trigger, including all detector hits and reconstructed particles. In a nuclear physics experiment, an event might be one detector trigger from a radioactive decay. In other fields, an event could be one image, one time sample, or one complete measurement record.

The important point is that an event groups together many related quantities that you want to keep as a unit. All the variables that belong to the same physical or logical event are stored together in the same row of the TTree. When you process the TTree, you usually write an event loop. In each iteration of this loop, you read one event, use all the data from that event at once, and then move to the next event.

TTrees are optimized for this pattern. Instead of storing your data in a simple table that you always read in full, a TTree lets you read one event at a time from disk and skip quickly to any event you want. This is very efficient when you have millions or billions of events and you want to process them sequentially or with selection cuts.

Each event can contain simple values such as numbers and also more complex data such as arrays or C++ vectors. For example, in one event you might store the total energy, the number of tracks, and a vector with the momentum of each track. These are still considered part of a single event. The structure that describes which quantities are stored per event is defined by the branches of the TTree. The event itself is the combination of all branch values at a given position in the tree.

When analyzing data with ROOT, it is useful to think conceptually in terms of events first. You ask: what is one event, what variables do I need for each event, and how will I loop over those events. The TTree interface follows this logic closely, which makes it a central tool for event based analyses.

Entries

In ROOT terminology, the number of events stored in a TTree is called the number of entries. Each entry corresponds to one event, and the words “event” and “entry” are often used almost interchangeably in everyday ROOT usage.

A TTree is therefore a collection of entries, each identified by an index that starts at zero. If a tree has $N$ entries, the valid entry indices go from $0$ to $N-1$. When you write an event loop, you typically loop over entry indices, tell the TTree to load that entry into memory, and then read or compute what you need.

From a technical perspective, an entry is a synchronized set of values across all branches of the TTree. If the tree has several branches, entry $i$ contains the value in branch 1 at index $i$, the value in branch 2 at index $i$, and so on. ROOT ensures that these values stay aligned. This lets you access all the event information consistently when you request a specific entry.

You often inspect the number of entries in a TTree to get a feeling for the dataset size or to control your analysis loops. For example, you might decide to process only the first fraction of the entries while developing your code, and later run over all entries for the full analysis. When you draw histograms from a TTree or use higher level interfaces such as RDataFrame, behind the scenes ROOT is still working entry by entry.

The concept of entries also matters when combining multiple TTrees, for example with TChain, where you effectively create a virtual sequence of entries that span several ROOT files. In all these cases, the basic idea remains the same. An entry index labels one full event worth of stored data.

Branches

Branches define the structure of a TTree. Conceptually, a branch is one column of data across all events. Each branch holds a particular variable or group of variables, and for every entry of the tree, the branch can store the corresponding value. If you think of a TTree as a very large table, then each branch is one column and each entry is one row.

Branches can store many types of information. A simple branch might contain a single floating point variable, such as the energy measured in a detector. Another branch might contain an integer, such as the event number. More complex branches can hold C arrays, C++ std::vector objects, or even user defined C++ classes. This allows you to represent complex event structures, such as variable numbers of particles per event, while keeping a clear organization.

One of the main advantages of branches is that they can be read independently. You do not always need every branch for every analysis. TTrees are designed so that you can choose to read only the branches you care about. This reduces memory usage and disk access, which is critical for large datasets. In practice, this means you can disable unneeded branches before looping, or rely on higher level tools that only touch required branches.

The layout of branches is defined when you create the TTree. At that point you decide which physical or logical variables will be stored, and how they are grouped. You might create one branch per simple variable or group several related variables in one branch. The choice affects both convenience and performance. For example, grouping rarely used variables into a separate branch can make most analyses faster, since ROOT will not need to read that branch by default.

Branches can be arranged hierarchically. A top level branch can contain sub branches if you store complex objects such as classes with several data members. In listings or the ROOT browser you might see paths like branch.subbranch, which reflect this internal structure. Even in that case, each sub branch is still analogous to one column, with a value per entry.

Branches are the main interface between your in memory C++ variables and the persistent data stored in the tree. When filling a TTree, you usually connect your variables to branches, then update the variables for each event, and call the TTree fill method. When reading, you connect variables or pointers to branches and ask the tree to load the desired entry, which fills your variables with the stored values for that event.

Leaves

Leaves are the lowest level representation of stored values inside a TTree. Historically, branches were built as collections of leaves, where each leaf corresponds to a single primitive data item, such as one integer, one floating point number, or one element in an array. While modern ROOT code usually works directly with branches, understanding leaves can clarify how data is organized.

If you think in terms of a table analogy, a branch is a logical column, while leaves are the fundamental stored pieces that make up that column, especially when the column is composite. For example, a branch that stores a 3 component vector (x, y, z) might contain three leaves, one for each component. Each leaf then holds one simple value per entry.

In tools that inspect TTrees, such as Print or the interactive TTree viewer, you often see both branches and leaves listed. The tree structure might show a branch name, followed by one or more leaves with slightly different names. The leaf names usually indicate the actual stored variables, for example by appending suffixes or indices.

From the user perspective, especially in modern analyses, you usually interact with branches to define what to read or write. ROOT manages the mapping between branches and leaves internally. However, leaves still appear in certain commands and can matter when you work with very old trees or low level features. For instance, some older macros refer directly to leaf names when drawing variables from a tree.

In summary, branches describe how your data is grouped and accessed, while leaves correspond to the individual primitive values that are stored for each entry. Most of the time, as a beginner, you can think in terms of events and branches only, and treat leaves as an implementation detail that explains why some ROOT output shows both levels.

Views: 12

Comments

Please login to add a comment.

Don't have an account? Register now!