6 from array
import array
10 This is an utility to merge histograms. The common case is when you have
11 old scale factors for the whole calorimeter and new scale factor only for
15 ROOT.PyConfig.IgnoreCommandLineOptions =
True
16 logging.basicConfig(level=logging.INFO)
20 print(
"old binning: " +
", ".
join((
"%.3f" % old.GetBinLowEdge(ibin))
21 for ibin
in range(1, old.GetNbinsX()
23 print(
"new binning: " +
", ".
join((
"%.3f" % new.GetBinLowEdge(ibin))
24 for ibin
in range(1, new.GetNbinsX()
31 OVERFLOW = new.GetNbinsX() + 1
33 for iold
in range(1, old.GetNbinsX()):
34 low = old.GetBinLowEdge(iold)
35 r = low + old.GetBinWidth(iold)
37 il_new = new.FindFixBin(low)
38 ir_new = new.FindFixBin(r)
41 if il_new == UNDERFLOW
and ir_new == UNDERFLOW:
42 print(
"1. adding %.3f - %.3f from old" % (low, r))
43 new_binning.append((low, r))
44 new_values.append(old.GetBinContent(iold))
45 new_errors.append(old.GetBinError(iold))
47 elif il_new == UNDERFLOW
and ir_new > UNDERFLOW:
48 if abs(new.GetBinLowEdge(1) - low) < 1E-100:
50 new_binning.append((low, new.GetBinLowEdge(1)))
51 new_values.append(old.GetBinContent(iold))
52 new_errors.append(old.GetBinError(iold))
53 if ir_new == OVERFLOW:
59 for inew
in range(1, new.GetNbinsX() + 1):
60 low = new.GetBinLowEdge(inew)
61 r = low + new.GetBinWidth(inew)
62 print(
"2. adding %.3f - %.3f from new" % (low, r))
63 new_binning.append((low, r))
64 new_values.append(new.GetBinContent(inew))
65 new_errors.append(new.GetBinError(inew))
67 for iold
in range(last_old, old.GetNbinsX() + 1):
68 low = old.GetBinLowEdge(iold)
69 r = low + old.GetBinWidth(iold)
71 il_new = new.FindFixBin(low)
72 ir_new = new.FindFixBin(r)
74 if il_new == OVERFLOW
and ir_new == OVERFLOW:
75 print(
"4. adding %.3f - %.3f from old" % (low, r))
76 new_binning.append((low, r))
77 new_values.append(old.GetBinContent(iold))
78 new_errors.append(old.GetBinError(iold))
79 elif il_new < OVERFLOW
and ir_new == OVERFLOW:
80 if abs(new.GetBinLowEdge(new.GetNbinsX() + 1) - r) < 1E-100:
82 new_binning.append((new.GetBinLowEdge(new.GetNbinsX() + 1), r))
83 new_values.append(old.GetBinContent(iold))
84 new_errors.append(old.GetBinError(iold))
87 new_edges =
array(
'f', [x[0]
for x
in new_binning] + [new_binning[-1][1]])
88 histo_type =
type(new)
89 result = histo_type(new.GetName(), new.GetTitle(),
90 len(new_edges) - 1, new_edges)
91 for i, (v, e)
in enumerate(zip(new_values, new_errors), 1):
92 result.SetBinContent(i, v)
94 result.SetBinError(i, e)
96 print(
"merged binning: " +
", ".
join((
"%.3f" % result.GetBinLowEdge(ibin))
97 for ibin
in range(1, result.GetNbinsX()
103 if __name__ ==
"__main__":
105 ROOT.gROOT.ProcessLine(
".x ~/atlasstyle/AtlasStyle.C")
107 except AttributeError:
112 parser = argparse.ArgumentParser(description=doc,
113 formatter_class=argparse.RawTextHelpFormatter)
114 parser.add_argument(
'histo_old')
115 parser.add_argument(
'histo_new')
116 parser.add_argument(
'--title', help=
'title of the new histogram')
117 parser.add_argument(
'--name', help=
'name of the new histogram')
119 '--recreate', help=
'create a new file', action=
'store_true')
120 parser.add_argument(
'--output-filename', default=
'output.root')
122 args = parser.parse_args()
124 file_old = ROOT.TFile.Open(args.histo_old.split(
":")[0])
125 file_new = ROOT.TFile.Open(args.histo_new.split(
":")[0])
127 histo_old = file_old.Get(args.histo_old.split(
":")[1])
128 histo_new = file_new.Get(args.histo_new.split(
":")[1])
131 raise IOError(
"cannot find histogram %s" % args.histo_old)
133 raise IOError(
"cannot find histogram %s" % args.histo_new)
135 logging.info(
"going to merge %s with %s",
136 histo_old.GetName(), histo_new.GetName())
139 canvas = ROOT.TCanvas()
140 histo_merged.SetFillColor(ROOT.kBlue)
141 histo_old.SetMarkerColor(ROOT.kRed)
142 histo_new.SetMarkerColor(ROOT.kGreen)
143 for histo
in histo_old, histo_new:
144 histo.SetMarkerStyle(20)
145 histo.SetMarkerSize(1)
146 histo_merged.Draw(
"histo")
147 histo_old.Draw(
"Psame")
148 histo_new.Draw(
"Psame")
150 legend = ROOT.TLegend(0.6, 0.7, 0.9, 0.9)
151 legend.AddEntry(histo_old,
"old")
152 legend.AddEntry(histo_new,
"new")
153 legend.SetBorderSize(0)
156 fout = ROOT.TFile.Open(args.output_filename,
157 "recreate" if args.recreate
else "update")
158 if args.title
is not None:
159 histo_merged.SetTitle(args.title)
160 name = args.name
or histo_old.GetName()
161 histo_merged.SetName(name)