Belle II Software development
quantity_extract.py
1#!/usr/bin/env python3
2
3
10
11
12"""
13Functionality to extract quantities from various ROOT objects (TH1).
14"""
15
16
17def default_extractor():
18 """
19 Returns a list of default extractors for the most common
20 ROOT Objects
21 """
22
23 def computeMean(profile_obj):
24 """
25 compute the mean values of the y dimension, also with
26 zero suppression
27 """
28 nbinsx = profile_obj.GetNbinsX()
29 sum = 0.0
30 sumZeroSuppressed = 0.0
31 countZeroSuppressed = 0
32 for i in range(nbinsx):
33 v = profile_obj.GetBinContent(i + 1)
34 sum = (
35 sum + v
36 ) # from first bin, ignored underflow (i=0) and overflow (i=nbinsx+1) bins
37 if v > 0.0:
38 sumZeroSuppressed = sumZeroSuppressed + v
39 countZeroSuppressed = countZeroSuppressed + 1
40 meanY = sum / nbinsx
41 meanYzeroSuppressed = sum / countZeroSuppressed
42
43 return (meanY, meanYzeroSuppressed)
44
45 def extractNtupleValues(ntuple_obj):
46 # only get the first entry for now
47 results = []
48 if ntuple_obj.GetEntries() > 0:
49 # ent0 = ntuple_obj.GetEntry(0)
50 for branch in ntuple_obj.GetListOfBranches():
51 branch_name = branch.GetName()
52 # create tuple with the branch name and value
53 results.append(
54 (
55 ntuple_obj.GetName() + "_" + branch_name,
56 float(getattr(ntuple_obj, branch_name)),
57 )
58 )
59 return results
60
61 th1_like = [
62 lambda x: [("mean_x", x.GetMean(1))],
63 lambda x: [("entries", x.GetEntries())],
64 lambda x: [("mean_y", computeMean(x)[0])],
65 lambda x: [("mean_y_zero_suppressed", computeMean(x)[1])],
66 ]
67
68 tprofile = [
69 lambda x: [("mean_y", computeMean(x)[0])],
70 lambda x: [("mean_y_zero_suppressed", computeMean(x)[1])],
71 ]
72
73 tntuple = [extractNtupleValues]
74
75 return {
76 "TH1D": th1_like,
77 "TH1F": th1_like,
78 "TH1": th1_like,
79 "TProfile": tprofile,
80 "TNtuple": tntuple,
81 }
82
83
85 """
86 Class to automatically extract quantities from ROOT Objects
87 """
88
89 def __init__(self, extractor=None):
90 """
91 Initialize the class with a set of quantity extractors
92 """
93
94
96 self.extractor = extractor
97
98 if self.extractor is None:
99 # use default
100 self.extractor = default_extractor()
101
102 def addExtractor(self, class_type, extractor):
103 """
104 Adds an extractor to this class
105
106 @param class_type: the string you get when
107 running <root_object>.IsA().GetName()
108 This is used to map the correct extractor to
109 this root object
110 """
111
112 # check if extractors for this type are already
113 # registered
114 if class_type in self.extractor:
115 self.extractor[class_type].append(extractor)
116 else:
117 self.extractor[class_type] = [extractor]
118
119 def extract(self, obj):
120 """
121 Extract quantities from a root object
122
123 @return: a dictionary of extracted quantities
124 """
125 this_class_type = obj.IsA().GetName()
126
127 if this_class_type in self.extractor:
128 ext_list = self.extractor[this_class_type]
129
130 # run list of extractors
131 # convert the returned tuple list to a dictionary
132 result = []
133 for x in ext_list:
134 # run the extractor
135 result_list = x(obj)
136 result += result_list
137 # convert the list of tuples into a dictionary
138 return dict(result)
139 else:
140 # no extractors available for this type
141 return {}
extractor
the dictionary used for data extraction, key is the ROOT type and value a list of extractors
def __init__(self, extractor=None)
def addExtractor(self, class_type, extractor)