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