ATLAS Offline Software
Loading...
Searching...
No Matches
JESUncertainty_RatioUtils.py
Go to the documentation of this file.
1#!/bin/python
2
3# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
4# -*- coding: utf-8 -*-
5
6from numpy import isnan
7from ROOT import Double, TGraphErrors
8from math import sqrt
9
10
13
14def divideGraphs (numeratorGraph, denominatorGraph, warn) :
15
16 #get number of points for the two graphs
17 nPointsNum = numeratorGraph.GetN()
18 nPointsDen = denominatorGraph.GetN()
19
20 if nPointsNum!=nPointsDen :
21 print "ERROR in JESUncertainty_RatioUtils:: graphs don't have the same number of points"
22 return None
23
24 #prepare the final graph
25 graphRatio = TGraphErrors()
26 graphRatio.SetName(numeratorGraph.GetName())
27
28 #loop on points of the graphs
29 for iPoint in xrange(0,nPointsNum) :
30
31 #retrieve the point
32 dataPointXNum = Double(0)
33 dataPointYNum = Double(0)
34 errorXNum = numeratorGraph.GetErrorX(iPoint)
35 errorYNum = numeratorGraph.GetErrorY(iPoint)
36 numeratorGraph.GetPoint(iPoint,dataPointXNum,dataPointYNum)
37
38 dataPointXDen = Double(0)
39 dataPointYDen = Double(0)
40 errorXDen = denominatorGraph.GetErrorX(iPoint)
41 errorYDen = denominatorGraph.GetErrorY(iPoint)
42 denominatorGraph.GetPoint(iPoint,dataPointXDen,dataPointYDen)
43
44 if abs(dataPointXNum-dataPointXDen) > 0.0001:
45 print "ERROR in JESUncertainty_RatioUtils::divideGraphs: x coordinates of data points do not match"
46 return None
47
48 #do the ratio
49 dataPointXRatio = dataPointXNum
50 dataPointYRatio = None
51 if dataPointYDen != 0 :
52 dataPointYRatio = dataPointYNum/dataPointYDen
53 else :
54 dataPointYRatio = 0
55 if warn == True :
56 print "WARNING in JESUncertainty_RatioUtils::divideGraphs: division by zero for x point: ", dataPointXNum
57 print "numerator graph:", numeratorGraph.GetName()
58 print "denominator graph:", denominatorGraph.GetName()
59
60 errorXRatio = errorXNum
61
62
63 #calculate the error (simple error propagation)
64 if errorYNum != 0 and errorYDen != 0 :
65
66 #no correlation:
67 errorYRatioNoCorr = sqrt(
68 pow(errorYNum,2)/pow(dataPointYDen,2)+
69 pow(errorYDen,2)*pow(dataPointYNum,2)/pow(dataPointYDen,4)
70 )
71
72 #with correlation:
73 #relativeErrorYRatioSquared = (pow((errorYNum/dataPointYNum),2)+
74 #pow((errorYDen/dataPointYDen),2)-
75 #2*(errorYNum*errorYDen)/(dataPointYNum*dataPointYDen))
76
77 #errorYRatioCorr = sqrt(relativeErrorYRatioSquared/(pow(dataPointYRatio,2)))
78
79 #go for no correlation:
80 errorYRatio = errorYRatioNoCorr
81
82 #case in which the numerator is zero (should not happen), zero the error as well
83 #this is not the best approach but it should be good enough for what we are doing (we always discard points with zero response)
84 elif dataPointYNum == 0 or dataPointYDen == 0 :
85 errorYRatio = 0
86
87 graphRatio.SetPoint(iPoint, dataPointXRatio, dataPointYRatio)
88 graphRatio.SetPointError(iPoint, errorXRatio, errorYRatio)
89
90 return graphRatio
91
92
93
96
97def getDeltaVarGraph (graph) :
98
99 #get number of points for the graph
100 nPoints = graph.GetN()
101
102 #prepare the final graph
103 deltaVarGraph = TGraphErrors()
104 deltaVarGraph.SetName(graph.GetName())
105
106 #loop on points of the graphs
107 for iPoint in xrange(0,nPoints) :
108
109 #retrieve the point
110 dataPointX = Double(0)
111 dataPointY = Double(0)
112 errorX = graph.GetErrorX(iPoint)
113 errorY = graph.GetErrorY(iPoint)
114 graph.GetPoint(iPoint,dataPointX,dataPointY)
115
116 #subtract unity and do the absolute value
117 dataPointXDeltaVar = dataPointX
118 dataPointYDeltaVar = abs(1-dataPointY)
119 errorXDeltaVar = errorX
120
121 deltaVarGraph.SetPoint(iPoint, dataPointXDeltaVar, dataPointYDeltaVar)
122
123 #being lazy (we will truncate the error if it goes below zero anyways)
124 errorYDeltaVar = errorY
125
126 #to calculate the error correctly
127 #if dataPointY != 0 and (dataPointY-1) > 0 :
128 #errorYDeltaVar = sqrt((dataPointY-1)/abs(dataPointY-1) * errorY) #this guarantees one does not go negative spitting an exception
129 #else
130 #one here would need to do a TGraphAsymmErrors with only the positive error in full
131
132 deltaVarGraph.SetPointError(iPoint, errorXDeltaVar, errorYDeltaVar)
133
134
135 return deltaVarGraph
136
137
140
141def getMaxVariationGraph (graph1, graph2) :
142
143 #get number of points for the two graphs
144 nPointsGraph1= graph1.GetN()
145 nPointsGraph2 = graph2.GetN()
146
147 if nPointsGraph1!=nPointsGraph2 :
148 print "ERROR in JESUncertainty_RatioUtils::getMaxVariationGraph: graphs don't have the same number of points"
149 return None
150
151 #prepare the final graph
152 maxVarGraph = graph1.Clone()
153 maxVarGraph.SetName(graph1.GetName()+"_Max")
154
155 #loop on points of the graphs
156 for iPoint in xrange(0,nPointsGraph1) :
157
158 #make the new point
159 maxPoint = Double(0)
160 maxPointError = Double(0)
161
162 #retrieve the point
163 dataPointXGraph1 = Double(0)
164 dataPointYGraph1 = Double(0)
165 errorXGraph1= graph1.GetErrorX(iPoint)
166 errorYGraph1 = graph1.GetErrorY(iPoint)
167 graph1.GetPoint(iPoint,dataPointXGraph1,dataPointYGraph1)
168
169 dataPointXGraph2 = Double(0)
170 dataPointYGraph2 = Double(0)
171 errorXGraph2 = graph2.GetErrorX(iPoint)
172 errorYGraph2 = graph2.GetErrorY(iPoint)
173 graph2.GetPoint(iPoint,dataPointXGraph2,dataPointYGraph2)
174
175 if abs(dataPointXGraph1-dataPointXGraph2) > 0.0001:
176 print "ERROR in JESUncertainty_RatioUtils::getMaxVariationGraph: x coordinates of data points do not match"
177 return None
178
179 #check for the largest (the convention of -999 for useless bins should work here)
180 if dataPointYGraph1 > dataPointYGraph2 :
181 maxPoint = dataPointYGraph1
182 maxPointError = errorYGraph1
183
184 else :
185 maxPoint = dataPointYGraph2
186 maxPointError = errorYGraph2
187 #print dataPointXGraph1, maxPoint, maxPointError
188 maxVarGraph.SetPoint(iPoint, dataPointXGraph1, maxPoint)
189 maxVarGraph.SetPointError(iPoint, errorXGraph1, maxPointError)
190
191 return maxVarGraph
192 #TODO: is there anything to do for the last good bin?
193
194
195#Debugging material to see if it actually works
196#c=TCanvas()
197#deadMaterialMaxVarGraph.Draw("AP")
198#deadMaterialMaxVarGraph.SetMarkerStyle(25)
199#deadMaterialMaxVarGraph.SetMarkerSize(2)
200#deadMaterialMaxVarGraph.SetMarkerColor(4)
201#deadMaterialMaxVarGraph.SetLineStyle(2)
202#deadMaterialMaxVarGraph.SetLineWidth(5)
203#deadMaterialMaxVarGraph.SetLineColor(4)
204#gPad.SetLogx()
205#deadMaterialGraphE.SetMarkerStyle(20)
206#deadMaterialGraphE.Draw("Psame")
207#deadMaterialGraphPt.SetMarkerStyle(22)
208#deadMaterialGraphPt.Draw("Psame")
209#c.SaveAs("max.png")
210
211
214
215def getQuadratureGraph (dummyGraph, listOfGraphs) :
216
217
218 for graphToSum in listOfGraphs :
219 #print graphToSum
220 nPointsDummyGraph = dummyGraph.GetN()
221 nPointsGraphToSum = graphToSum.GetN()
222
223 if nPointsDummyGraph!=nPointsGraphToSum :
224 print "ERROR in JESUncertainty_RatioUtils::getQuadratureGraph: graphs don't have the same number of points"
225 return None
226
227 #loop on points of the graphs
228 for iPoint in xrange(0,nPointsDummyGraph) :
229
230 #retrieve the point
231 dataPointXDummyGraph = Double(0)
232 dataPointYDummyGraph = Double(0)
233 dummyGraph.GetPoint(iPoint,dataPointXDummyGraph,dataPointYDummyGraph)
234
235 dataPointXGraphToSum = Double(0)
236 dataPointYGraphToSum = Double(0)
237 errorXGraphToSum = graphToSum.GetErrorX(iPoint)
238 errorYGraphToSum = graphToSum.GetErrorY(iPoint)
239 graphToSum.GetPoint(iPoint,dataPointXGraphToSum,dataPointYGraphToSum)
240
241 if abs(dataPointXDummyGraph-dataPointXGraphToSum) > 0.0001:
242 print "ERROR in JESUncertainty_RatioUtils::getQuadratureGraph: x coordinates of data points do not match"
243 return None
244
245 #end of preliminary checks
246
247 #prepare everything for the propagation of errors
248 #these are arrays that at the end of the loop on the graphs contain the points and errors
249 AllSquaredSums = []
250 AllErrors = []
251 #and this is the final graph that contains the quadrature of the others
252 quadratureGraph = dummyGraph.Clone()
253 quadratureGraph.SetName(listOfGraphs[0].GetName()+"_Quadrature")
254
255 for iPoint in xrange(0,nPointsDummyGraph) :
256
257 squaredSum = 0
258 error = 0
259 badPoint = False
260
261 for graphToSum in listOfGraphs :
262
263 dataPointXGraphToSum = Double(0)
264 dataPointYGraphToSum = Double(0)
265 errorXGraphToSum = graphToSum.GetErrorX(iPoint)
266 errorYGraphToSum = graphToSum.GetErrorY(iPoint)
267 graphToSum.GetPoint(iPoint,dataPointXGraphToSum,dataPointYGraphToSum)
268
269 #check for bad points
270 if dataPointYGraphToSum < -998 :
271 badPoint = True
272
273 #this will be the denominator of the error propagation as well
274 squaredSum += pow(dataPointYGraphToSum,2)
275
276 #if iPoint == 0:
277 #print "toSum: ", dataPointYGraphToSum
278 #print "toSumSquared: ", pow(dataPointYGraphToSum,2)
279 #this is the numerator of the error propagation
280 error += pow(dataPointYGraphToSum*errorYGraphToSum,2)
281 #print "addingToErrorNum: ", pow(dataPointYGraphToSum*errorYGraphToSum,2)
282
283 try :
284 sqrtSquaredSum = sqrt(squaredSum)
285 sqrtError = sqrt(error/squaredSum)
286 except :
287 sqrtSquaredSum = 0
288 sqrtError = 0
289
290 #propagate the bad points
291 if badPoint :
292 sqrtSquaredSum = -999
293 sqrtError = 0.000000001
294
295 #now append them (for debugging reasons only)
296 AllSquaredSums.append(sqrtSquaredSum)
297 AllErrors.append(sqrtError)
298
299 #put them into the final plot
300 quadratureGraph.SetPoint(iPoint, dataPointXGraphToSum, sqrtSquaredSum)
301 quadratureGraph.SetPointError(iPoint, errorXGraphToSum, sqrtError)
302
303 return quadratureGraph
304
305
308
309def getLinearSumGraph (dummyGraph, listOfGraphs) :
310
311
312 for graphToSum in listOfGraphs :
313 #print graphToSum
314 nPointsDummyGraph = dummyGraph.GetN()
315 nPointsGraphToSum = graphToSum.GetN()
316
317 if nPointsDummyGraph!=nPointsGraphToSum :
318 print "ERROR in JESUncertainty_RatioUtils::getQuadratureGraph: graphs don't have the same number of points"
319 return None
320
321 #loop on points of the graphs
322 for iPoint in xrange(0,nPointsDummyGraph) :
323
324 #retrieve the point
325 dataPointXDummyGraph = Double(0)
326 dataPointYDummyGraph = Double(0)
327 dummyGraph.GetPoint(iPoint,dataPointXDummyGraph,dataPointYDummyGraph)
328
329 dataPointXGraphToSum = Double(0)
330 dataPointYGraphToSum = Double(0)
331 errorXGraphToSum = graphToSum.GetErrorX(iPoint)
332 errorYGraphToSum = graphToSum.GetErrorY(iPoint)
333 graphToSum.GetPoint(iPoint,dataPointXGraphToSum,dataPointYGraphToSum)
334
335 if abs(dataPointXDummyGraph-dataPointXGraphToSum) > 0.0001:
336 print "ERROR in JESUncertainty_RatioUtils::getQuadratureGraph: x coordinates of data points do not match"
337 return None
338
339 #end of preliminary checks
340
341 #prepare everything for the propagation of errors
342 #these are arrays that at the end of the loop on the graphs contain the points and errors
343 AllSquaredSums = []
344 AllErrors = []
345
346 #this contains the errors for all data points for the propagation
347 ListOfErrors = []
348
349 #and this is the final graph that contains the quadrature of the others
350 linearGraph = dummyGraph.Clone()
351 linearGraph.SetName(listOfGraphs[0].GetName()+"_Quadrature")
352
353 for iPoint in xrange(0,nPointsDummyGraph) :
354
355 theSum = 0
356 uncorrError = 0
357 corrError = 0
358 badPoint = False
359
360 for graphToSum in listOfGraphs :
361
362 dataPointXGraphToSum = Double(0)
363 dataPointYGraphToSum = Double(0)
364 errorXGraphToSum = graphToSum.GetErrorX(iPoint)
365 errorYGraphToSum = graphToSum.GetErrorY(iPoint)
366 graphToSum.GetPoint(iPoint,dataPointXGraphToSum,dataPointYGraphToSum)
367
368 #check for bad points
369 if dataPointYGraphToSum < -998 :
370 badPoint = True
371
372 #this will be the denominator of the error propagation as well
373 theSum += dataPointYGraphToSum
374
375 #print "toSumSquared: ", pow(dataPointYGraphToSum,2)
376 #this is for the error propagation
377 uncorrError += pow(errorYGraphToSum,2)
378 ListOfErrors.append(errorYGraphToSum)
379 #print "addingToErrorNum: ", pow(dataPointYGraphToSum*errorYGraphToSum,2)
380
381 #need to do all combination of errors
382 while len(ListOfErrors) != 0 :
383 for iError, theError in enumerate(ListOfErrors) :
384 theError = ListOfErrors.pop(iError)
385 for jError, theOtherError in enumerate(ListOfErrors) :
386 corrError =+ theError * theOtherError
387
388 sqrtSum = theSum
389 sqrtError = sqrt(uncorrError + 2 * corrError)
390
391 #propagate the bad points
392 if badPoint :
393 sqrtSum = -999
394 sqrtError = 0.000000001
395
396 #now append them (for debugging reasons only)
397 AllSquaredSums.append(sqrtSum)
398 AllErrors.append(sqrtError)
399 #print AllSquaredSums
400 #print AllErrors
401
402 #put them into the final plot
403 linearGraph.SetPoint(iPoint, dataPointXGraphToSum, sqrtSum)
404 linearGraph.SetPointError(iPoint, errorXGraphToSum, sqrtError)
405
406 return linearGraph
constexpr int pow(int base, int exp) noexcept
void xrange(TH1 *h, bool symmetric)
getDeltaVarGraph(graph)
Calculate point by point |1-graph| and put it into a TGraph.
getMaxVariationGraph(graph1, graph2)
Get maximum variation out of two plots.
getQuadratureGraph(dummyGraph, listOfGraphs)
Get a graph that is the sum in quadrature of all others (they all have to look like dummygraph)
getLinearSumGraph(dummyGraph, listOfGraphs)
Get a graph that is the linear sum of all others (they all have to look like dummygraph)
divideGraphs(numeratorGraph, denominatorGraph, warn)
Do the ratio of two TGraphs.