ATLAS Offline Software
Loading...
Searching...
No Matches
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 ROOT import TGraphErrors,TGraph, TGraphAsymmErrors, Double, TCanvas, gPad
7#import numpy
8from math import fabs, sqrt
9
10
11
12
13def getPlotRatio (plotNum, plotDen, doAverage) :
14
15 DataPointsForAverage=[]
16 ErrorsForAverage=[]
17 averageDelta = 0
18 maxDelta = 0
19 nPointsNum = plotNum.GetN()
20 nPointsDen = plotDen.GetN()
21
22 if nPointsNum!=nPointsDen :
23 print "Plots don't have the same number of points!"
24 return(0,0,0)
25
26 plotRatio = TGraphErrors()
27
28 plotRatio.SetName(plotNum.GetName())
29
30 x1=Double(0)
31 y1=Double(0)
32 x2=Double(0)
33 y2=Double(0)
34 dx1=Double(0)
35 dx2=Double(0)
36 dy1=Double(0)
37 dy2=Double(0)
38 iv=int(0)
39 dx=Double(0)
40 for pointNum in xrange(0,nPointsNum) :
41 pointNum = int(pointNum)
42 matchcount = 0
43 for pointDen in xrange(0,nPointsDen) :
44 pointDen = int(pointDen)
45 plotNum.GetPoint(pointNum, x1, y1)
46 plotDen.GetPoint(pointDen, x2, y2)
47 dx1 = plotNum.GetErrorX(pointNum)
48 dx2 = plotNum.GetErrorX(pointDen)
49 emean = (dx1+dx2)/2.
50 if fabs(x1-x2)>=emean and fabs(x1-x2)>dx :
51 pass
52 #print "no idea what's going on here"
53 else :
54 matchcount=matchcount+1
55 dx1 = plotNum.GetErrorX(pointNum)
56 if y1 != 0 : dy1 = plotNum.GetErrorY(pointNum)/y1
57 if y2 != 0 : dy2 = plotNum.GetErrorY(pointDen)/y2
58
59 if y2 != 0 :
60 plotRatio.SetPoint(iv, x1, y1/y2)
61 if doAverage : DataPointsForAverage.append(y1/y2)
62
63 else :
64 plotRatio.SetPoint(iv, x1, y2)
65 if doAverage : DataPointsForAverage.append(y2)
66
67 e = Double(0)
68
69 if y1 != 0 and y2 != 0 : e=sqrt(dy1*dy1+dy2*dy2)*(y1/y2)
70 plotRatio.SetPointError(iv, dx1, e)
71 if doAverage : ErrorsForAverage.append(e)
72
73 iv = iv+1
74
75 if (matchcount>1) :
76 print "too many x points matched!"
77 return(0)
78
79 if doAverage :
80
81 averageDelta = getAverageDelta(DataPointsForAverage, ErrorsForAverage)
82 maxDelta = getMaxDelta(DataPointsForAverage, ErrorsForAverage)
83
84
85 return plotRatio, averageDelta-1, maxDelta
86
87
88def getAverageDelta (DataPoints, ErrorsOnDataPoints) :
89 if len(DataPoints) != len(ErrorsOnDataPoints) :
90 "Data points and errors do not match"
91 return 0
92
93 average = 0
94 skippedDataPoints = 0
95
96 for datapoint,error in zip(DataPoints, ErrorsOnDataPoints) :
97 #don't care about the data point if the error is 0
98 if error<0.00000001 or error>0.03 :
99 skippedDataPoints = skippedDataPoints+1
100 pass
101
102 else :
103 average += datapoint
104
105 average = average/(len(DataPoints)-skippedDataPoints)
106 return average
107
108def getMaxDelta (DataPoints, ErrorsOnDataPoints) :
109 if len(DataPoints) != len(ErrorsOnDataPoints) :
110 "Data points and errors do not match"
111 return 0
112
113 maxDelta = 0
114
115 for datapoint,error in zip(DataPoints, ErrorsOnDataPoints) :
116 #don't care about the data point if the error is 0
117 if error<0.00000001 :
118 pass
119 #or if the error is > 3% (most likely due to a bad fit)
120 elif error>0.03 :
121 pass
122 else :
123 if fabs(datapoint-1) > fabs(maxDelta) : maxDelta = datapoint-1
124
125 return maxDelta
126
127
129 #pick up point by point pl
130
131 #loop on all data points
132 nPoints = graph.GetN()
133
134 newGraph=TGraphAsymmErrors(nPoints)
135
136 #x=array('f')
137 #y=array('f')
138 #ey=array('f')
139
140 for iPoint in xrange(0,nPoints) :
141 #get info on data point
142 dataPointX = Double(0)
143 dataPointY = Double(0)
144 graph.GetPoint(iPoint,dataPointX,dataPointY)
145 dataErrorX = graph.GetErrorX(iPoint)
146 dataErrorY = graph.GetErrorY(iPoint)
147
148 #numerical-invert the X
149 newDataPointX = dataPointX * dataPointY
150
151 newErrorXLeft = fabs(newDataPointX - (dataPointX-dataErrorX))
152 newErrorXRight = fabs(newDataPointX - (dataPointX+dataErrorX))
153
154 #setting the new graph (with asymm errors this time)
155 newGraph.SetPoint(iPoint, newDataPointX, dataPointY)
156 newGraph.SetPointEXhigh(iPoint, newErrorXRight)
157 newGraph.SetPointEXlow(iPoint, newErrorXLeft)
158 newGraph.SetPointEYhigh(iPoint, dataErrorY)
159 newGraph.SetPointEYlow(iPoint, dataErrorY)
160
161 print dataPointY, newDataPointX
162 #check that the numerical-inverted X is still in the previous bin - otherwise, ERROR!
163 binRangeLow = dataPointX-dataErrorX
164 binRangeHigh = dataPointX+dataErrorX
165 if newDataPointX<binRangeLow or newDataPointX>binRangeHigh :
166 print "Warning! Data point should not be here!"
167 print "Old data point: ", dataPointX
168 print "New NI data point:" , newDataPointX
169 print "XLow: ", binRangeLow
170 print "XHigh: ", binRangeHigh
171 newGraph.SetPoint(iPoint, dataPointX, 0.0000000000001)
172 newGraph.SetPointEXhigh(iPoint, dataErrorX)
173 newGraph.SetPointEXlow(iPoint, dataErrorX)
174 newGraph.SetPointEYhigh(iPoint, dataErrorY)
175 newGraph.SetPointEYlow(iPoint, dataErrorY)
176
177 return newGraph
void xrange(TH1 *h, bool symmetric)
getAverageDelta(DataPoints, ErrorsOnDataPoints)
Definition RatioUtils.py:88
numericalInvertPlot(graph)
getPlotRatio(plotNum, plotDen, doAverage)
Division function############.
Definition RatioUtils.py:13
getMaxDelta(DataPoints, ErrorsOnDataPoints)