188 def __call__(self, root_file):
189 num = find_histo(root_file, self.numerator)
190 den = find_histo(root_file, self.denominator)
191 if not num or not den:
192 if crash_on_error:
193 raise RuntimeError(f"Missing histogram: {self.numerator} or {self.denominator}")
194 else:
195 logging.error(f"Missing histogram: {self.numerator} or {self.denominator}")
196 return
197
198 if not ROOT.TEfficiency.CheckConsistency(num, den):
199 logging.warning("Inconsistency detected between numerator and denominator histograms.")
200 logging.info("Attempting to fix...")
201 for i in range(1, num.GetNbinsX() + 1):
202 num_val = num.GetBinContent(i)
203 den_val = den.GetBinContent(i)
204 if den_val == 0:
205 den.SetBinContent(i, 1e-6)
206 den_val = 1e-6
207 logging.info(f"Setting denominator to a smaller value for bin {i} as it is zero. Any other options?")
208 if num_val > den_val:
209 logging.info(f"For Bin {i}: Num ({num_val}) > Den ({den_val})! Adjusting by setting Den to Num. Any other options?")
210 den.SetBinContent(i, num_val)
211 if not ROOT.TEfficiency.CheckConsistency(num, den):
212 logging.error("Unable to fix histogram inconsistencies. Aborting efficiency calculation.")
213 return
214
215 eff = ROOT.TEfficiency(num, den)
216 path_parts = self.output.
strip(
"/").
split(
"/")
217 *dir_path, obj_name = path_parts
218 directory_path = "/".join(dir_path)
219 eff.SetName(obj_name)
220 eff.SetTitle(f"{self.numerator}/{self.denominator};{num.GetXaxis().GetTitle()};Efficiency")
221 ensure_directory_exists(root_file, directory_path)
222 root_file.cd(directory_path)
223 eff.Write()
224 logging.info(f"Saved efficiency '{obj_name}' in '{directory_path}'.")
225
std::vector< std::string > split(const std::string &s, const std::string &t=":")