ATLAS Offline Software
ICHEP2016/ProviderHistoHelpers.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
2 
3 from ROOT import *
4 from array import array
5 import glob
6 import re
7 import math
8 
9 
10 def GetDefaultPtBins(numBins=100,lowVal=15.0,highVal=2500.0):
11  dx = (math.log(highVal)-math.log(lowVal))/numBins
12  bins = []
13  for iBin in range(0,numBins+1):
14  bins.append(math.exp(math.log(lowVal)+iBin*dx))
15 
16  return bins
17 
18 def GetDefaultEtaBins():
19  etaValuesAsym = [0,0.15,0.3,0.8,1.0,1.2,1.65,2.1,2.45,2.8,3.0,3.2,3.6,4.5]
20  etaValuesSym = []
21  for aVal in etaValuesAsym:
22  etaValuesSym.append(aVal)
23  if math.fabs(aVal) > 1.e-4: # Don't double-count zero
24  etaValuesSym.append(-aVal)
25 
26  return sorted(etaValuesSym)
27 
28 def GetCentredBins(values):
29  if len(values) == 1:
30  return [values[0]*0.5,values[0]*1.5]
31 
32  binList = []
33  for iVal in range(0,len(values)-1):
34  binList.append(values[iVal]+(values[iVal+1]-values[iVal])/2.0)
35  binList.insert(0,values[0]-(values[1]-values[0])/2.0)
36  binList.append(values[-1]+(values[-1]-values[-2])/2.0)
37 
38  return binList
39 
40 def MakeProviderHisto(histoName,ptBins=GetDefaultPtBins(),etaBins=GetDefaultEtaBins()):
41  return TH2D(histoName,histoName,len(ptBins)-1,array('d',ptBins),len(etaBins)-1,array('d',etaBins))
42 
43 
44 def ConvertPtHistoToProviderHisto(histo1D,histoName):
45  histo2D = MakeProviderHisto(histoName,etaBins=[min(GetDefaultEtaBins()),0,max(GetDefaultEtaBins())])
46 
47  oldMinPt = histo1D.GetXaxis().GetBinLowEdge(1)
48  oldMaxPt = histo1D.GetXaxis().GetBinLowEdge(histo1D.GetNbinsX()+1)
49  tolerance = 1.0e-4
50  for ptBin in range(1,histo2D.GetNbinsX()+1):
51  pt = histo2D.GetXaxis().GetBinCenter(ptBin)
52  unc = 0.0
53  if pt <= oldMinPt:
54  unc = histo1D.Interpolate(oldMinPt+tolerance)
55  elif pt >= oldMaxPt:
56  unc = histo1D.Interpolate(oldMaxPt+tolerance)
57  else:
58  unc = histo1D.Interpolate(pt)
59 
60  for etaBin in range(1,histo2D.GetNbinsY()+1):
61  histo2D.SetBinContent(ptBin,etaBin,unc)
62 
63  return histo2D
64 
65 def ConvertTGraphToProviderHisto(graph,histoName):
66  pointsX = []
67  pointsY = []
68  for iPoint in range(0,graph.GetN()):
69  px = Double(0)
70  py = Double(0)
71  graph.GetPoint(iPoint,px,py)
72  pointsX.append(px)
73  pointsY.append(py)
74 
75  # Make bins with the points as the centre where possible
76  bins = GetCentredBins(pointsX)
77 
78  # Extend the range to cover [15,2500] if necessary
79  if bins[0] > 15:
80  bins.insert(0,15.)
81  pointsX.inset(0,(bins[0]+bins[1])/2.0)
82  pointsY.insert(0,pointsY[0])
83 
84  if bins[-1] < 2500:
85  bins.append(2500.)
86  pointsX.append((bins[-1]+bins[-2])/2.0)
87  pointsY.append(pointsY[-1])
88 
89  # Make the histo and fill it
90  histo = MakeProviderHisto(histoName,ptBins=bins,etaBins=[min(GetDefaultEtaBins()),0,max(GetDefaultEtaBins())])
91  for ptBin in range(1,histo.GetNbinsX()+1):
92  for etaBin in range(1,histo.GetNbinsY()+1):
93  histo.SetBinContent(ptBin,etaBin,pointsY[ptBin-1])
94 
95  return histo
96 
97 def ExtendPtRangeOfHisto(histo,histoName):
98  # Get the current bins
99  ptBins = []
100  for xBin in range(1,histo.GetNbinsX()+2):
101  ptBins.append(histo.GetXaxis().GetBinLowEdge(xBin))
102 
103  # Extend only if necessary
104  if math.fabs(ptBins[-1] - 2500) < 1.e-4:
105  print "Histo already went to 2500 GeV, doing nothing"
106  return histo
107  elif ptBins[-1] > 2500:
108  print "Histo beyond range, cannot extend"
109  return None
110  ptBins.append(2500.)
111 
112  # Get eta bins
113  etaBins = []
114  for yBin in range(1,histo.GetNbinsY()+2):
115  etaBins.append(histo.GetYaxis().GetBinLowEdge(yBin))
116 
117  # Make and fill
118  newHisto = MakeProviderHisto(histoName,ptBins=ptBins,etaBins=etaBins)
119  for xBin in range(1,histo.GetNbinsX()+1):
120  for yBin in range(1,histo.GetNbinsY()+1):
121  newHisto.SetBinContent(xBin,yBin,histo.GetBinContent(xBin,yBin))
122  for yBin in range(1,histo.GetNbinsY()+1):
123  newHisto.SetBinContent(histo.GetNbinsX()+1,yBin,histo.GetBinContent(histo.GetNbinsX(),yBin))
124 
125  return newHisto
126 
127 def SymmetrizeHistoInEta(histo,histoName):
128  # Get the current eta bins and symmetrize
129  etaBins = []
130  for yBin in range(1,histo.GetNbinsY()+2):
131  etaVal = histo.GetYaxis().GetBinLowEdge(yBin)
132  if math.fabs(etaVal) > 1.e-4:
133  etaBins.append(-etaVal)
134  etaBins.append(etaVal)
135  etaBins = sorted(etaBins)
136 
137  # Get the current pT bins
138  ptBins = []
139  for xBin in range(1,histo.GetNbinsX()+2):
140  ptBins.append(histo.GetXaxis().GetBinLowEdge(xBin))
141 
142  # Make and fill
143  newHisto = MakeProviderHisto(histoName,ptBins=ptBins,etaBins=etaBins)
144  for xBin in range(1,histo.GetNbinsX()+1):
145  xVal = histo.GetXaxis().GetBinCenter(xBin)
146  for yBin in range(1,histo.GetNbinsY()+1):
147  yVal = histo.GetYaxis().GetBinCenter(yBin)
148  newHisto.SetBinContent(newHisto.GetXaxis().FindBin(xVal),newHisto.GetYaxis().FindBin(-yVal),histo.GetBinContent(xBin,yBin))
149  newHisto.SetBinContent(newHisto.GetXaxis().FindBin(xVal),newHisto.GetYaxis().FindBin(yVal),histo.GetBinContent(xBin,yBin))
150 
151  return newHisto
152 
153 def QuadratureSumHisto(histoName,histos):
154  # If it's one histo, just return it
155  if len(histos) == 1:
156  return histos[0]
157 
158  # Ensure that the binning is the same
159  tolerance = 1.e-4
160  for aHisto in histos[1:]:
161  if aHisto.GetNbinsX() != histos[0].GetNbinsX():
162  print "Input histograms have different number of x bins - can't do quadrature sum safely"
163  return None
164  elif aHisto.GetNbinsY() != histos[0].GetNbinsY():
165  print "Input histograms have different number of y bins - can't do quadrature sum safely"
166  return None
167  for xBin in range(1,histos[0].GetNbinsX()+2):
168  edge = None
169  for aHisto in histos:
170  if edge is None:
171  edge = aHisto.GetXaxis().GetBinLowEdge(xBin)
172  elif math.fabs(edge-aHisto.GetXaxis().GetBinLowEdge(xBin)) > tolerance:
173  print "Input histograms have different x binning - can't do quadrature sum safely"
174  return None
175  for yBin in range(1,histos[0].GetNbinsY()+2):
176  edge = None
177  for aHisto in histos:
178  if edge is None:
179  edge = aHisto.GetYaxis().GetBinLowEdge(yBin)
180  elif math.fabs(edge-aHisto.GetYaxis().GetBinLowEdge(yBin)) > tolerance:
181  print "Input histograms have different y binning - can't do quadrature sum safely"
182  return None
183 
184  # Same binning - good, we can continue
185  # Clone the first histo for the binning
186  quadSumHisto = histos[0].Clone()
187  for xBin in range(1,quadSumHisto.GetNbinsX()+1):
188  for yBin in range(1,quadSumHisto.GetNbinsY()+1):
189  quadSum = 0
190  for aHisto in histos:
191  quadSum += pow(aHisto.GetBinContent(xBin,yBin),2)
192  quadSumHisto.SetBinContent(xBin,yBin,sqrt(quadSum))
193 
194  return quadSumHisto
195 
196 
197 
198 
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
RootHelpers::FindBin
Int_t FindBin(const TAxis *axis, const double x)
Definition: RootHelpers.cxx:14
ProviderHistoHelpers.GetDefaultEtaBins
def GetDefaultEtaBins()
Definition: Final2012/ProviderHistoHelpers.py:18
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
ProviderHistoHelpers.MakeProviderHisto
def MakeProviderHisto(histoName, ptBins=GetDefaultPtBins(), etaBins=GetDefaultEtaBins())
Definition: Final2012/ProviderHistoHelpers.py:40
ProviderHistoHelpers.GetCentredBins
def GetCentredBins(values)
Definition: Final2012/ProviderHistoHelpers.py:28
ProviderHistoHelpers.ConvertPtHistoToProviderHisto
def ConvertPtHistoToProviderHisto(histo1D, histoName)
Definition: Final2012/ProviderHistoHelpers.py:44
ProviderHistoHelpers.ConvertTGraphToProviderHisto
def ConvertTGraphToProviderHisto(graph, histoName)
Definition: Final2012/ProviderHistoHelpers.py:65
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
ProviderHistoHelpers.QuadratureSumHisto
def QuadratureSumHisto(histoName, histos)
Definition: Final2012/ProviderHistoHelpers.py:153
ProviderHistoHelpers.SymmetrizeHistoInEta
def SymmetrizeHistoInEta(histo, histoName)
Definition: Final2012/ProviderHistoHelpers.py:127
DerivationFramework::TriggerMatchingUtils::sorted
std::vector< typename T::value_type > sorted(T begin, T end)
Helper function to create a sorted vector from an unsorted one.
ProviderHistoHelpers.ExtendPtRangeOfHisto
def ExtendPtRangeOfHisto(histo, histoName)
Definition: Final2012/ProviderHistoHelpers.py:97
array
ProviderHistoHelpers.GetDefaultPtBins
def GetDefaultPtBins(numBins=100, lowVal=15.0, highVal=2500.0)
Definition: Final2012/ProviderHistoHelpers.py:10
pow
constexpr int pow(int base, int exp) noexcept
Definition: ap_fixedTest.cxx:15