NTuple
The NTuple
class serves as a simple gateway to access information from single or multiple .root
Ntuples located in the specified input path. It represents an interface to build Event
instances
directly from the TTree event entries automatically. This class is capable of preprocessing, filtering and building Event
instances according to the preprocessors, and selectors passed.
A preprocessor refers to a function that takes an Event
instance as input and applies
any necessary modifications or additions. A selector refers to a function that returns a
boolean based on the information of an Event
passed as input.
The NTuple
class is designed to be generic and handle many types of NTuple formats since Event
creation can be
controlled through a configuration YAML
file. Internally, the NTuple
class just loads
the ROOT TTrees in a TChain (accessible through the attribute tree
), and generates Event
instances
on the fly by demand (accessible through the attribute events
), applying the preprocessors
and selectors methods before returning to perform any necessary processing and selecting steps.
The preprocessing feature was implemented in that way to allow creating selectors based on properties that by default do not come directly from the input NTuples, but can be computed with extra preprocessing functions steps before applying the selection methods.
The NTuple
class admits specifying the following maps into the configuration file:
ntuple-tree-name
: The name of the TTree to be used. It is supposed to be the same for all the files in the input folder.ntuple_preprocessors
: A map containing the preprocessors to be used in the NTuple.ntuple_selectors
: A map containing the selectors to be used in the NTuple.
Both, preprocessors and selectors maps should contains a src
key that specifies the path to the function
to be used, and optionally, a kwargs
map for additional parameters of the preprocessor.
example
#...
ntuple_tree_name: '/dtNtupleProducer/DTTREE'
ntuple_preprocessors:
prepocessor_name: # Any name, not relevant to the codes
src: 'path.to.preprocessor'
kwargs: # optional arguments to be passed to the preprocessor
arg1: value1
#...
ntuple_selectors:
selector_name: # Any name, not relevant to the codes
src: 'path.to.selector'
kwargs: # optional arguments to be passed to the selector
arg1: value1
#...
The following example shows how to use the NTuple
class to read DT Ntuples and access events.
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)
# input_file could be the path to the DT Ntuple, or to a folder with several files
ntuple = NTuple(input_file) # It also admits passing a list of selectors and preprocessors when instantiating
# you can access events by index or slice such as a list
print(ntuple.events[9])
print(ntuple.events[3:5]) # slicing return a generator
# you can also loop over the events
for iev, ev in enumerate(ntuple.events):
print(ev)
break
# or simply, you can still use the TTree (It is a ROOT.TChain)
for i, ev in enumerate(ntuple.tree):
print(f"Event orbit number: {ev.event_orbitNumber}")
break
Output
+ Opening input file /root/DTPatternRecognition/test/ntuples/DTDPGNtuple_12_4_2_Phase2Concentrator_thr6_Simulation_99.root
>> ------ Event 39954 info ------
+ Index: 9
+ Digis
* Number of digis: 167
+ Segments
* Number of segments: 21
* AM-Seg matches:
--> Segment 1 info -->
- Wh: -2, Sc: 5, St: 1, Phi: 2.2211668491363525, Eta: -0.9381515979766846
--> Segment 2 info -->
- Wh: -2, Sc: 5, St: 1, Phi: 2.2211666107177734, Eta: -0.9440188407897949
--> Segment 8 info -->
- Wh: -2, Sc: 5, St: 2, Phi: 2.221505880355835, Eta: -0.9430407881736755
--> Segment 9 info -->
- Wh: -2, Sc: 5, St: 2, Phi: 2.2215068340301514, Eta: -0.9163724184036255
--> Segment 10 info -->
- Wh: -2, Sc: 12, St: 2, Phi: -0.6958962082862854, Eta: -0.8441917300224304
+ Tps
* Number of tps: 32
+ Genmuons
* Number of genmuons: 2
* GenMuon 1 info -->
--> Pt: 548.1250610351562, Eta: -0.8365859985351562, Phi: -0.6915670037269592, Charge: 1, Matched_segments_stations: [(2, 12, -2), (3, 12, -2), (3, 12, -2), (3, 12, -2), (3, 12, -2), (3, 12, -2), (3, 12, -2), (3, 12, -2), (3, 12, -2), (3, 12, -2), (1, 5, -2), (1, 5, -2), (2, 5, -2), (2, 5, -2)], Showered: True
* GenMuon 0 info -->
--> Pt: 511.7483215332031, Eta: -0.9357022643089294, Phi: 2.2167818546295166, Charge: -1, Matched_segments_stations: [(2, 12, -2), (3, 12, -2), (3, 12, -2), (3, 12, -2), (3, 12, -2), (3, 12, -2), (3, 12, -2), (3, 12, -2), (3, 12, -2), (3, 12, -2), (1, 5, -2), (1, 5, -2), (2, 5, -2), (2, 5, -2)], Showered: True
+ Emushowers
* Number of emushowers: 1
+ Simhits
* Number of simhits: 188
+ Realshowers
* Number of realshowers: 3
<generator object EventList.__getitem__.<locals>.<genexpr> at 0x7ff5a640a740>
>> ------ Event 39956 info ------
+ Index: 0
+ Digis
* Number of digis: 81
+ Segments
* Number of segments: 8
* AM-Seg matches:
--> Segment 5 info -->
- Wh: 0, Sc: 8, St: 1, Phi: -2.5716519355773926, Eta: -0.2304154634475708
--> Segment 7 info -->
- Wh: -1, Sc: 8, St: 4, Phi: -2.5743513107299805, Eta: -0.36347508430480957
+ 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: [(2, 12, -2), (3, 12, -2), (3, 12, -2), (3, 12, -2), (3, 12, -2), (3, 12, -2), (3, 12, -2), (3, 12, -2), (3, 12, -2), (3, 12, -2), (1, 5, -2), (1, 5, -2), (2, 5, -2), (2, 5, -2), (1, 8, 0), (4, 8, -1)], Showered: True
* GenMuon 1 info -->
--> Pt: 190.72511291503906, Eta: -0.2504693865776062, Phi: -2.558511257171631, Charge: 1, Matched_segments_stations: [(2, 12, -2), (3, 12, -2), (3, 12, -2), (3, 12, -2), (3, 12, -2), (3, 12, -2), (3, 12, -2), (3, 12, -2), (3, 12, -2), (3, 12, -2), (1, 5, -2), (1, 5, -2), (2, 5, -2), (2, 5, -2), (1, 8, 0), (4, 8, -1)], Showered: True
+ Emushowers
* Number of emushowers: 0
+ Simhits
* Number of simhits: 50
+ Realshowers
* Number of realshowers: 0
Event orbit number: -1
Important
The NTuple.events
attribute is not a simple list, but an instance of the EventList class.
This design prevents loading all events into memory simultaneously. Instead, it allows iteration and access by index and slice,
while internally iterating over the root tree entries to create the required event on the fly.