Event

The Event class is designed to represent an event entry from a ROOT TTree, facilitating access to information by abstracting info into instances of Particle class. Each instance of the Event class allows to comfortably access those objects such as offline segments, generation-level muons, simulation digis, showers, and more.

Thanks to how Particle class was designed, the Event class can dynamically build particles based on specifications from a configuration file. This file should contain information about the types of particles and how to build them, allowing for flexible and customizable event processing.

To illustrate the dynamic particle-building feature, suppose we want to extract digi information from the TTree event’s entries when an event is instantiated. This requires specifying the following in a YAML configuration file under the particle_types map:

run_config.yaml

particle_types:
    # ...
    digis:
        amount: 'digi_nDigis'
        branches:
            wh: 'digi_wheel'
            sc: 'digi_sector'
            st: 'digi_station'
            sl: 'digi_superLayer'
            w: 'digi_wire'
            l: 'digi_layer'
            time: 'digi_time'
        attributes:
            BX:
                expr: 'time // 25 if time is not None else None'
        sorter:
            by: 'p.BX'
# ...

The Event class creates n instances of the Particle class, where n is determined by the amount key. Attributes are defined using the branches map, which maps directly from TTree branches, and the attributes map, which allows for computed values using expressions (expr) or callable methods (specified via src key). The callable methods must accept the particle instance as an argument, and the expression can access directly to the particle instance attribute to any computation.

Additionally, the particle_types map can manage also the following keys:

  • class: Specifies the class path to be used for the particle. If not specified, it defaults to the Particle class.

  • filter: Allows to filter particles based on boolean conditions. These conditions can use the particle instance (referred to as p) and the root event entry (referred to as ev).

  • sorter: Sorts particles using Python’s sorted(). The by key specifies the sorting expression (which can also use p and ev), and reverse key (default: False) can reverse the order.

For example, to iterate over a TTree and create event instances with particles specified in the configuration file, you can use the following code:

from ROOT import TFile
from dtpr.utils.config import RUN_CONFIG

# update the configuration file -> if it is not set, it will use the default one 'run_config.yaml'
RUN_CONFIG.change_config_file(config_path=cf_path)

# first, create a TFile object to read the dt ntuple (this is not necessary by using NTuple Class)
with TFile(input_file, "read") as ntuple:
    tree = ntuple["dtNtupleProducer/DTTREE;1"]

    for iev, ev in enumerate(tree):
        # use_config=True to use the configuration file to build the particles
        event = Event(index=iev, ev=ev, use_config=True)

        # Print the event summary
        print(event)

        break # break after the first event

Output

>> ------ Event 39956 info ------
+ Index: 0
+ Digis
    * Number of digis: 81
+ Segments
    * Number of segments: 8
+ Tps
    * Number of tps: 21
+ Genmuons
    * Number of genmuons: 2
    * GenMuon 0 info -->
    --> Pt: 258.0812683105469, Eta: -1.9664770364761353, Phi: 0.5708979964256287, Charge: -1, Matched_segments_stations: [], Showered: False
    * GenMuon 1 info -->
    --> Pt: 190.72511291503906, Eta: -0.2504693865776062, Phi: -2.558511257171631, Charge: 1, Matched_segments_stations: [], Showered: False
+ Emushowers
    * Number of emushowers: 0
+ Simhits
    * Number of simhits: 50

The Event class is highly flexible and not restricted to TTree data. As demonstrated above, you can define any type of attributes mapping in the configuration file or even create an empty event instance and then add attributes manually as needed.

event = Event(index=1) # initialize an empty event with index 1
print(event)

# It is possible to manually add particles or other attributes
from dtpr.base import Particle

showers = [Particle(index=i, wh=1, sc=1, st=1, name="Shower") for i in range(5)] # create 5 showers
event.showers = showers # add them to the event

print(event)
print(event.showers[-1])

Output

>> ------ Event 1 info ------
+ Index: 1
>> ------ Event 1 info ------
+ Index: 1
+ Showers
    * Number of showers: 5
>> Shower 4 info -->
+ Wh: 1, Sc: 1, St: 1