145 """Calculate the ratios for a list of histograms""" 147 def _divideOrZero(numerator, denominator):
150 return numerator/denominator
153 if a == 0.
and b == 0.:
157 def findBins(wrap, bins_xvalues):
159 currBin = wrap.begin()
161 while i < len(bins_xvalues)
and currBin < wrap.end():
162 (xcenter, xlow, xhigh) = bins_xvalues[i]
163 xlowEdge = xcenter-xlow
164 xupEdge = xcenter+xhigh
166 (curr_center, curr_low, curr_high) = wrap.xvalues(currBin)
167 curr_lowEdge = curr_center-curr_low
168 curr_upEdge = curr_center+curr_high
170 if equal(xlowEdge, curr_lowEdge)
and equal(xupEdge, curr_upEdge):
174 elif curr_upEdge <= xlowEdge:
176 elif curr_lowEdge >= xupEdge:
183 if len(ret) != len(bins_xvalues):
184 ret.extend([
None]*( len(bins_xvalues) - len(ret) ))
190 def __init__(self, th1, uncertainty):
192 self._uncertainty = uncertainty
194 xaxis = th1.GetXaxis()
195 xaxis_arr = xaxis.GetXbins()
196 if xaxis_arr.GetSize() > 0:
197 lst = [xaxis_arr[i]
for i
in xrange(0, xaxis_arr.GetSize())]
198 arr = array.array(
"d", lst)
199 self._ratio = ROOT.TH1F(
"foo",
"foo", xaxis.GetNbins(), arr)
201 self._ratio = ROOT.TH1F(
"foo",
"foo", xaxis.GetNbins(), xaxis.GetXmin(), xaxis.GetXmax())
203 self._ratio.SetStats(0)
204 self._ratio.SetLineColor(ROOT.kBlack)
205 self._ratio.SetLineWidth(1)
206 def draw(self, style=None):
209 if self._uncertainty:
213 self._ratio.Draw(
"same "+st)
217 return self._th1.GetNbinsX()+1
218 def xvalues(self, bin):
219 xval = self._th1.GetBinCenter(bin)
220 xlow = xval-self._th1.GetXaxis().GetBinLowEdge(bin)
221 xhigh = self._th1.GetXaxis().GetBinUpEdge(bin)-xval
222 return (xval, xlow, xhigh)
223 def yvalues(self, bin):
224 yval = self._th1.GetBinContent(bin)
225 yerr = self._th1.GetBinError(bin)
226 return (yval, yerr, yerr)
228 return self._th1.GetBinContent(bin)
229 def divide(self, bin, scale):
230 self._ratio.SetBinContent(bin, _divideOrZero(self._th1.GetBinContent(bin), scale))
231 self._ratio.SetBinError(bin, _divideOrZero(self._th1.GetBinError(bin), scale))
238 def __init__(self, gr, uncertainty):
240 self._uncertainty = uncertainty
247 def draw(self, style=None):
248 if self._ratio
is None:
252 if self._uncertainty:
256 self._ratio.Draw(
"same "+st)
260 return self._gr.GetN()
261 def xvalues(self, bin):
262 return (self._gr.GetX()[bin], self._gr.GetErrorXlow(bin), self._gr.GetErrorXhigh(bin))
263 def yvalues(self, bin):
264 return (self._gr.GetY()[bin], self._gr.GetErrorYlow(bin), self._gr.GetErrorYhigh(bin))
266 return self._gr.GetY()[bin]
267 def divide(self, bin, scale):
272 if bin >= self._gr.GetN():
275 xvals = self.xvalues(bin)
278 self._xvalues.append(xval)
279 self._xerrslow.append(xvals[1])
280 self._xerrshigh.append(xvals[2])
281 yvals = self.yvalues(bin)
282 self._yvalues.append(yvals[0] / scale)
283 if self._uncertainty:
284 self._yerrslow.append(yvals[1] / scale)
285 self._yerrshigh.append(yvals[2] / scale)
287 self._yerrslow.append(0)
288 self._yerrshigh.append(0)
290 if len(self._xvalues) == 0:
293 self._ratio = ROOT.TGraphAsymmErrors(len(self._xvalues), array.array(
"d", self._xvalues), array.array(
"d", self._yvalues),
294 array.array(
"d", self._xerrslow), array.array(
"d", self._xerrshigh),
295 array.array(
"d", self._yerrslow), array.array(
"d", self._yerrshigh))
299 class WrapTGraph2D(WrapTGraph):
300 def __init__(self, gr, uncertainty):
301 WrapTGraph.__init__(self, gr, uncertainty)
302 def xvalues(self, bin):
303 return (self._gr.GetX()[bin], self._gr.GetErrorX(bin), self._gr.GetErrorX(bin))
304 def yvalues(self, bin):
305 return (self._gr.GetY()[bin], self._gr.GetErrorY(bin), self._gr.GetErrorY(bin))
308 if isinstance(o, ROOT.TH1):
309 return WrapTH1(o, ratioUncertainty)
310 elif isinstance(o, ROOT.TGraph):
311 return WrapTGraph(o, ratioUncertainty)
312 elif isinstance(o, ROOT.TGraph2D):
313 return WrapTGraph2D(o, ratioUncertainty)
315 wrappers = [
wrap(h)
for h
in histos]
319 ref_bins = [ref.xvalues(b)
for b
in xrange(ref.begin(), ref.end())]
321 wrappers_bins.append(findBins(w, ref_bins))
323 for i, bin
in enumerate(xrange(ref.begin(), ref.end())):
324 (scale, ylow, yhigh) = ref.yvalues(bin)
325 for w, bins
in zip(wrappers, wrappers_bins):
328 w.divide(bins[i], scale)
def divide(outfile, dest, numer, denom)
bool equal(const T &first, const T &second)
def _calculateRatios(histos, ratioUncertainty=False)
OutputIterator zip(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp)
Abs< T >::type abs(const T &t)
auto wrap(F iFunc) -> decltype(iFunc())