115 def __call__(self, root_file):
116 num = find_histo(root_file, self.numerator)
117 den = find_histo(root_file, self.denominator)
118 if not num or not den:
119 if crash_on_error:
120 raise RuntimeError(f"Missing histogram: {self.numerator} or {self.denominator}")
121 else:
122 logging.error(f"Missing histogram: {self.numerator} or {self.denominator}")
123 return
124
125 if not ROOT.TEfficiency.CheckConsistency(num, den):
126 logging.warning("Inconsistency detected between numerator and denominator histograms.")
127 logging.info("Attempting to fix...")
128 for i in range(1, num.GetNbinsX() + 1):
129 num_val = num.GetBinContent(i)
130 den_val = den.GetBinContent(i)
131 if den_val == 0:
132 den.SetBinContent(i, 1e-6)
133 den_val = 1e-6
134 logging.info(f"Setting denominator to a smaller value for bin {i} as it is zero. Any other options?")
135 if num_val > den_val:
136 logging.info(f"For Bin {i}: Num ({num_val}) > Den ({den_val})! Adjusting by setting Den to Num. Any other options?")
137 den.SetBinContent(i, num_val)
138 if not ROOT.TEfficiency.CheckConsistency(num, den):
139 logging.error("Unable to fix histogram inconsistencies. Aborting efficiency calculation.")
140 return
141
142 eff = ROOT.TEfficiency(num, den)
143 path_parts = self.output.
strip(
"/").
split(
"/")
144 *dir_path, obj_name = path_parts
145 directory_path = "/".join(dir_path)
146 eff.SetName(obj_name)
147 eff.SetTitle(f"{self.numerator}/{self.denominator};{num.GetXaxis().GetTitle()};Efficiency")
148 ensure_directory_exists(root_file, directory_path)
149 root_file.cd(directory_path)
150 eff.Write()
151 logging.info(f"Saved efficiency '{obj_name}' in '{directory_path}'.")
152
std::vector< std::string > split(const std::string &s, const std::string &t=":")