125def merge_histograms(old, new, merge_error=True):
126 new_binning = []
127 new_values = []
128 new_errors = []
129 UNDERFLOW = 0
130 OVERFLOW = new.GetNbinsX() + 1
131
132 for iold in range(1, old.GetNbinsX()):
133 low = old.GetBinLowEdge(iold)
134 r = low + old.GetBinWidth(iold)
135
136 il_new = new.FindFixBin(low)
137 ir_new = new.FindFixBin(r)
138 remainer = None
139
140 if il_new == UNDERFLOW and ir_new == UNDERFLOW:
141 new_binning.append((low, r))
142 new_values.append(old.GetBinContent(iold))
143 new_errors.append(old.GetBinError(iold))
144
145 elif il_new == UNDERFLOW and ir_new > UNDERFLOW and ir_new < OVERFLOW:
146 if abs(new.GetBinLowEdge(1) - low) < 1E-100:
147 continue
148 new_binning.append((low, new.GetBinLowEdge(1)))
149 new_values.append(old.GetBinContent(iold))
150 new_errors.append(old.GetBinError(iold))
151 if ir_new == OVERFLOW:
152 remainer = iold
153 break
154 last_old = iold
155
156 for inew in range(1, new.GetNbinsX() + 1):
157 low = new.GetBinLowEdge(inew)
158 r = low + new.GetBinWidth(inew)
159 new_binning.append((low, r))
160 new_values.append(new.GetBinContent(inew))
161 new_errors.append(new.GetBinError(inew))
162
163 if remainer is not None:
164 new_binning.append((new.GetBinLowEdge(new.GetNbinsX()),
165 old.GetBinLowEdge(remainer)
166 + old.GetBinWidth(remainer)))
167 new_values.append(old.GetBinContent(remainer))
168 new_errors.append(old.GetBinError(remainer))
169
170 for iold in range(last_old, old.GetNbinsX() + 1):
171 low = old.GetBinLowEdge(iold)
172 r = low + old.GetBinWidth(iold)
173
174 il_new = new.FindFixBin(low)
175 ir_new = new.FindFixBin(r)
176
177 if il_new == OVERFLOW and ir_new == OVERFLOW:
178 new_binning.append((low, r))
179 new_values.append(old.GetBinContent(iold))
180 new_errors.append(old.GetBinError(iold))
181 elif il_new < OVERFLOW and ir_new == OVERFLOW:
182 if abs(new.GetBinLowEdge(new.GetNbinsX() + 1) - r) < 1E-100:
183 continue
184 new_binning.append((new.GetBinLowEdge(new.GetNbinsX() + 1), r))
185 new_values.append(old.GetBinContent(iold))
186 new_errors.append(old.GetBinError(iold))
187
188 new_edges =
array(
'f', [x[0]
for x
in new_binning] + [new_binning[-1][1]])
189 histo_type =
type(new)
190 result = histo_type(new.GetName(), new.GetTitle(),
191 len(new_edges) - 1, new_edges)
192 for i, (v, e) in enumerate(zip(new_values, new_errors), 1):
193 result.SetBinContent(i, v)
194 if merge_error:
195 result.SetBinError(i, e)
196 return result
197
198