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
void xrange(TH1 *h, bool symmetric)
getDeltaVarGraph(graph)
Calculate point by point |1-graph| and put it into a TGraph.
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).
getMaxVariationGraph(graph1, graph2)
Get maximum variation out of two plots.
divideGraphs(numeratorGraph, denominatorGraph, warn)
Do the ratio of two TGraphs.