460 def __call__(self, root_file):
461 ROOT.TH1.AddDirectory(False)
462 hist = find_histo(root_file, self.input_hist)
463 if not hist:
464 if crash_on_error:
465 raise RuntimeError(f"Histogram '{self.input_hist}' not found.")
466 else:
467 logging.error(f"Histogram '{self.input_hist}' not found.")
468 return
469
470 path_parts = self.new_path.
strip(
"/").
split(
"/")
471 *dir_path, new_name = path_parts
472 directory_path = "/".join(dir_path)
473 ensure_directory_exists(root_file, directory_path)
474 root_file.cd(directory_path)
475
476 if self.xlow is None or self.xhigh is None:
477 h_out = hist.Clone(new_name)
478 else:
479 ax = hist.GetXaxis()
480 bin_low =
max(1,
min(ax.FindBin(self.xlow), ax.GetNbins()))
481 bin_high =
max(1,
min(ax.FindBin(self.xhigh), ax.GetNbins()))
482 nbins = bin_high - bin_low
483 h_out = ROOT.TH1D(new_name, hist.GetTitle(), nbins, float(self.xlow), float(self.xhigh))
484 for i in range(nbins + 1):
485 h_out.SetBinContent(i + 1, hist.GetBinContent(i + bin_low))
486 h_out.SetBinError(i + 1, hist.GetBinError(i + bin_low))
487
488 h_out.SetEntries(hist.GetEntries())
489
490 if self.x_label:
491 h_out.GetXaxis().SetTitle(self.x_label)
492 if self.y_label:
493 h_out.GetYaxis().SetTitle(self.y_label)
494 h_out.Write(new_name, ROOT.TObject.kOverwrite)
495 logging.info(f"Renamed and updated histogram '{self.input_hist}' → '{self.new_path}' in '{directory_path}' | X-axis: '{self.x_label}' | Y-axis: '{self.y_label}' | Range: ({self.xlow}, {self.xhigh})")
496
std::vector< std::string > split(const std::string &s, const std::string &t=":")