Belle II Software  release-08-01-10
quantity_extract.py
1 #!/usr/bin/env python3
2 
3 
10 
11 
12 """
13 Functionality to extract quantities from various ROOT objects (TH1).
14 """
15 
16 
17 def 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 supression
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 quntaties 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.extractorextractor = extractor
97 
98  if self.extractorextractor is None:
99  # use default
100  self.extractorextractor = 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.extractorextractor:
115  self.extractorextractor[class_type].append(extractor)
116  else:
117  self.extractorextractor[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.extractorextractor:
128  ext_list = self.extractorextractor[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)