ATLAS Offline Software
Loading...
Searching...
No Matches
CorrelationMatrixHelpers.py
Go to the documentation of this file.
1# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
2
3from ROOT import *
4from array import array
5from math import fabs,exp,log,sqrt
6import sys
7import re
8import os
9import AtlasStyleMacro
10
11from PlotHelpers import *
12
13# Script is Steven's
14# Structural modifications by Kate, Dec 2016
15
16
21
23
24 def __init__(self,relMet=False):
25 self.hist4D = None
26 self.jetDef = None
27 self.varType = None
28 self.plotType = None
29 self.OOB = -1234 # out of bounds value
30 self.OOBT = -1000 # out of bounds threshold
31 # Whether to use (nominal-reduced) or (1-nominal)/(1-reduced)
32 self.relativeMetric = relMet
33
34 # For the plotting functions
35 self.ATLASLabelName = "Internal"
36 self.DrawATLASLabel = True
37 self.iEPS = 0
38
39
40 def setInfo(self,jetDef,varType,plotType):
41 self.jetDef = jetDef
42 self.varType = varType
43 self.plotType = plotType
44
45 def setInfoCopy(self,toCopy,plotType = ""):
46 self.jetDef = toCopy.jetDef
47 self.varType = toCopy.varType
48 self.plotType = plotType if plotType != "" else toCopy.plotType
49
50 def cloneHist4D(self,toClone):
51 try:
52 self.hist4D = toClone.Clone()
53 except AttributeError:
54 self.hist4D = toClone.hist4D.Clone()
55 self.hist4D.SetName("4D_var%s_%s_%s"%(self.varType,self.jetDef,self.plotType))
56
57 def applyAbsValue(self):
58 if not self.hist4D:
59 print "Cannot apply absolute value when the histogram hasn't been created"
60 return False
61
62 for binX in range(1,self.hist4D.GetNbinsX()+1):
63 for binY in range(1,self.hist4D.GetNbinsY()+1):
64 if self.hist4D.GetBinContent(binX,binY) > self.OOBT:
65 self.hist4D.SetBinContent(binX,binY,fabs(self.hist4D.GetBinContent(binX,binY)))
66 return True
67
68
70 def fillHist4DFromFile(self,inFile,fixedString,fixedX,fixedY,filterStartString="",granularityFactor=1):
71 # Ensure the histogram wasn't already filled
72 if self.hist4D:
73 print "Blocking re-filling of existing CorrMat4D histogram of name ",self.hist4D.GetName()
74 return False
75
76 # Begin by checking the size of the 2D matrices
77 numBins = -1
78 for histName in inFile.GetKeyNames():
79 if filterStartString != "" and not histName.startswith(filterStartString):
80 continue
81 if self.jetDef not in histName:
82 continue
83 if "_%s"%(fixedString) in histName:
84 hist = inFile.Get(histName)
85 numBins = hist.GetNbinsX()
86 break
87 if numBins < 0:
88 print "Failed to find histogram matching criteria:"
89 print "jetDef = \"%s\""%(self.jetDef)
90 print "filterStartString = \"%s\""%(filterStartString)
91 return False
92
93 # Granularity scaling if requested
94 localNumBins = int(numBins / granularityFactor) if granularityFactor > 1 else numBins
95 if granularityFactor > 1:
96 # Ensure the granularity fits
97 if numBins % granularityFactor != 0:
98 print "Cannot apply granularity factor: %d bins can't be divided by %d"%(numBins,granularityFactor)
99 return False
100
101 # Now build the empty 4D matrix
102 histName4D = "4D_var%s_%s_%s"%(self.varType,self.jetDef,inFile.GetNameNoDir())
103 self.hist4D = TH2D(histName4D,"",len(fixedX)*localNumBins,0.,len(fixedX)*localNumBins,len(fixedY)*localNumBins,0.,len(fixedY)*localNumBins)
104
105 # Fill with the out-of-bounds value
106 for binX in range(1,self.hist4D.GetNbinsX()+1):
107 for binY in range(1,self.hist4D.GetNbinsY()+1):
108 self.hist4D.SetBinContent(binX,binY,self.OOB)
109
110 # Fill the histogram
111 for histName in inFile.GetKeyNames():
112 if filterStartString != "" and not histName.startswith(filterStartString):
113 continue
114 if self.jetDef not in histName:
115 continue
116
117 # Get the fixed values for this 2D histogram
118 # Sanity checks were already done before, so we just need to retrieve them
119 fixed1,fixed2 = getFixedValuesFromName(histName)
120 if not fixed1.startswith(fixedString): continue
121 fixed1 = float(fixed1.replace(fixedString,"",1))
122 fixed2 = float(fixed2.replace(fixedString,"",1))
123
124 # We have the fixed values, now determine the respective indices
125 index1 = -1
126 index2 = -1
127 for aIndex in range(0,len(fixedX)):
128 aValue = fixedX[aIndex]
129 if fabs(aValue - fixed1) < 1.e-4:
130 index1 = aIndex
131 break
132 for aIndex in range(0,len(fixedY)):
133 aValue = fixedY[aIndex]
134 if fabs(aValue - fixed2) < 1.e-4:
135 index2 = aIndex
136 break
137 if index1 < 0 or index2 < 0:
138 print "Failed to find index1 (%d) or index2 (%d) for histogram (%s)"%(index1,index2,histName)
139 self.histName = None
140 return False
141
142 # We now have the indices
143 # Get the 2D histogram and use it to fill the relevant portion of the 4D histogram
144 # Watch for granularity factors
145 hist2D = inFile.Get(histName)
146 offsetX = int((self.hist4D.GetNbinsX()/len(fixedX))*index1)
147 offsetY = int((self.hist4D.GetNbinsY()/len(fixedY))*index2)
148 if localNumBins == numBins:
149 for binX in range(1,hist2D.GetNbinsX()+1):
150 for binY in range(1,hist2D.GetNbinsY()+1):
151 self.hist4D.SetBinContent(binX+offsetX,binY+offsetY,hist2D.GetBinContent(binX,binY))
152 else:
153 # Split into pieces by the granularity factor
154 # Watch for the root indexing from 1, which has to be in the sub-bin indices
155 # Also have to be careful about bins which are on the edge of the kinematic limit
156 for binX in range(0,hist2D.GetNbinsX()/granularityFactor):
157 for binY in range(0,hist2D.GetNbinsY()/granularityFactor):
158 subVal = 0
159 numVal = 0
160 for subBinX in range(1,granularityFactor+1):
161 for subBinY in range(1,granularityFactor+1):
162 binContent = hist2D.GetBinContent(binX*granularityFactor+subBinX,binY*granularityFactor+subBinY)
163 if binContent > self.OOBT:
164 subVal += binContent
165 numVal += 1
166 self.hist4D.SetBinContent(binX+1+offsetX,binY+1+offsetY,subVal/numVal if numVal > 0 else self.OOB)
167
168 # Done with this 2D histogram
169 # Done with this 4D histogram
170 return True
171
172
174
175 def fillHist4DFromDifference(self,hist1,hist2):
176 # Ensure the histogram wasn't already filled
177 if self.hist4D:
178 print "Blocking re-filling of existing CorrMat4D histogram of name ",self.hist4D.GetName()
179 return False
180
181 # Ensure the histograms exist
182 if not hist1 or not hist2:
183 print "Argument(s) are None: ",hist1,hist2
184 return False
185
186 # Copy the first histogram and subtract the second
187 self.cloneHist4D(hist1)
188
189 # Manually do the difference so that we can watch for out-of-bounds
190 for binX in range(1,hist1.hist4D.GetNbinsX()+1):
191 for binY in range(1,hist2.hist4D.GetNbinsX()+1):
192 if hist1.hist4D.GetBinContent(binX,binY) > self.OOBT and hist2.hist4D.GetBinContent(binX,binY) > self.OOBT:
193 if not hist1.relativeMetric:
194 self.hist4D.SetBinContent(binX,binY,hist1.hist4D.GetBinContent(binX,binY) - hist2.hist4D.GetBinContent(binX,binY))
195 else:
196 self.hist4D.SetBinContent(binX,binY,relativeMetric(hist1.hist4D.GetBinContent(binX,binY),hist2.hist4D.GetBinContent(binX,binY)))
197
198 return True
199
200
202
203 def fillHist4DFromMinOfSet(self,hists):
204 # Ensure the histogram wasn't already filled
205 if self.hist4D:
206 print "Blocking re-filling of existing CorrMat4D histogram of name ",self.hist4D.GetName()
207 return False
208
209 # Ensure the histogram(s) exist
210 if not hists or len(hists) == 0:
211 print "Argument is None or empty list: ",hists
212 return False
213
214 # Copy the first histogram for formatting purposes
215 self.cloneHist4D(hists[0])
216
217 # The values from the first histogram are already set from cloning
218 # Now just check if any other hists have smaller values
219 # Note that smaller may be relative to 1, not zero (for the relative metric)
220 # Watch for out-of-bounds
221 for aHist in hists[1:]:
222 for binX in range(1,aHist.hist4D.GetNbinsX()+1):
223 for binY in range(1,aHist.hist4D.GetNbinsY()+1):
224 if aHist.hist4D.GetBinContent(binX,binY) > aHist.OOBT:
225 if not aHist.relativeMetric:
226 if fabs(aHist.hist4D.GetBinContent(binX,binY)) < fabs(self.hist4D.GetBinContent(binX,binY)):
227 self.hist4D.SetBinContent(binX,binY,aHist.hist4D.GetBinContent(binX,binY))
228 else:
229 currVal = self.hist4D.GetBinContent(binX,binY)
230 newVal = aHist.hist4D.GetBinContent(binX,binY)
231 # If the values bracket one, we're safe
232 if currVal <= 1 and newVal >= 1:
233 self.hist4D.SetBinContent(binX,binY,1)
234 elif currVal >= 1 and newVal <= 1:
235 self.hist4D.SetBinContent(binX,binY,1)
236 elif currVal < 1 and newVal < 1:
237 if newVal > currVal:
238 self.hist4D.SetBinContent(binX,binY,newVal)
239 #elif currVal < 1 and newVal > 1:
240 # if newVal < 1/currVal:
241 # self.hist4D.SetBinContent(binX,binY,newVal)
242 #elif currVal > 1 and newVal < 1:
243 # if newVal > 1/currVal:
244 # self.hist4D.SetBinContent(binX,binY,newVal)
245 elif currVal > 1 and newVal > 1:
246 if newVal < currVal:
247 self.hist4D.SetBinContent(binX,binY,newVal)
248 return True
249
250
252
253 def fillHist4DFromMaxOfSet(self,hists):
254 # Ensure the histogram wasn't already filled
255 if self.hist4D:
256 print "Blocking re-filling of existing CorrMat4D histogram of name ",self.hist4D.GetName()
257 return False
258
259 # Ensure the histogram(s) exist
260 if not hists or len(hists) == 0:
261 print "Argument is None or empty list: ",hists
262 return False
263
264 # Copy the first histogram for formatting purposes
265 self.cloneHist4D(hists[0])
266
267 # The values from the first histogram are already set from cloning
268 # Now just check if any other hists have smaller values
269 # Note that this may be values with respect to 1 if relative metric
270 # Watch for out-of-bounds
271 for aHist in hists[1:]:
272 for binX in range(1,aHist.hist4D.GetNbinsX()+1):
273 for binY in range(1,aHist.hist4D.GetNbinsY()+1):
274 if aHist.hist4D.GetBinContent(binX,binY) > aHist.OOBT and aHist.hist4D.GetBinContent(binX,binY) < -aHist.OOBT:
275 if not aHist.relativeMetric:
276 if fabs(aHist.hist4D.GetBinContent(binX,binY)) > fabs(self.hist4D.GetBinContent(binX,binY)):
277 self.hist4D.SetBinContent(binX,binY,aHist.hist4D.GetBinContent(binX,binY))
278 else:
279 currVal = self.hist4D.GetBinContent(binX,binY)
280 newVal = aHist.hist4D.GetBinContent(binX,binY)
281 if currVal < 1 and newVal < 1:
282 if newVal < currVal:
283 self.hist4D.SetBinContent(binX,binY,newVal)
284 elif currVal < 1 and newVal > 1:
285 if newVal > 1/currVal:
286 self.hist4D.SetBinContent(binX,binY,newVal)
287 elif currVal > 1 and newVal < 1:
288 if newVal < 1/currVal:
289 self.hist4D.SetBinContent(binX,binY,newVal)
290 elif currVal > 1 and newVal > 1:
291 if newVal > currVal:
292 self.hist4D.SetBinContent(binX,binY,newVal)
293 return True
294
295
297
299 # Ensure the histogram wasn't already filled
300 if self.hist4D:
301 print "Blocking re-filling of existing CorrMat4D histogram of name ",self.hist4D.GetName()
302 return False
303
304 # Ensure the histogram(s) exist
305 if not hists or len(hists) < 2:
306 print "Argument is None or contains less than two histograms: ",hists
307 return False
308
309 # Copy the first histogram for formatting purposes
310 self.cloneHist4D(hists[0])
311
312 # The values of the first histogram were copied from cloning
313 # We need to set these back to 0 (excluding out-of-bounds values)
314 for binX in range(1,self.hist4D.GetNbinsX()+1):
315 for binY in range(1,self.hist4D.GetNbinsY()+1):
316 if self.hist4D.GetBinContent(binX,binY) > self.OOBT:
317 self.hist4D.SetBinContent(binX,binY,0)
318
319 # Now construct the envelope
320 # Fill with the maximum |difference| from zero when subtracting config X from config Y for all combinations of X,Y
321 for iHist1 in range(0,len(hists)):
322 hist1 = hists[iHist1]
323 for iHist2 in range(iHist1+1,len(hists)):
324 hist2 = hists[iHist2]
325 for binX in range(self.hist4D.GetNbinsX()+1):
326 for binY in range(self.hist4D.GetNbinsY()+1):
327 if self.hist4D.GetBinContent(binX,binY) > self.OOBT:
328 if aHist.relativeMetric:
329 diff = relativeMetric(1-hist1.hist4D.GetBinContent(binX,binY),1-hist2.hist4D.GetBinContent(binX,binY))
330 else:
331 diff = fabs(hist2.hist4D.GetBinContent(binX,binY) - hist1.hist4D.GetBinContent(binX,binY))
332 if diff > self.hist4D.GetBinContent(binX,binY):
333 self.hist4D.SetBinContent(binX,binY,diff)
334
335 return True
336
337
339
340 def fillHist4DFromCoverageOfSet(self,minDiffFromNominal,maxDiffBetweenScenarios,plotStyle,nominalHist=None):
341 # Ensure the histogram wasn't already filled
342 if self.hist4D:
343 print "Blocking re-filling of existing CorrMat4D histogram of name ",self.hist4D.GetName()
344 return False
345
346 # Ensure the histogram(s) exist
347 if not minDiffFromNominal or not maxDiffBetweenScenarios:
348 print "Argument is None or empty list: ",minDiffFromNominal,maxDiffBetweenScenarios
349 return False
350 if plotStyle==2 and not nominalHist:
351 print "NominalHist is None for style which requires it"
352 return False
353
354 # Copy the minDiff histogram for formatting purposes
355 self.cloneHist4D(minDiffFromNominal)
356
357 # Now fill with the value controlled by plotStyle
358 # 0: 0 if max(scenarioDiff) > min(nominalDiff) else min(nominalDiff)
359 # 1: 0 if max(scenarioDiff) > min(nominalDiff) else min(nominalDiff) - max(scenarioDiff)
360 # 2: 0 if max(scenarioDiff) > min(nominalDiff) else nominalValue
361
362 for binX in range(1,self.hist4D.GetNbinsX()+1):
363 for binY in range(1,self.hist4D.GetNbinsY()+1):
364 if self.hist4D.GetBinContent(binX,binY) > self.OOBT:
365 minDiff = fabs(minDiffFromNominal.hist4D.GetBinContent(binX,binY))
366 maxDiff = fabs(maxDiffBetweenScenarios.hist4D.GetBinContent(binX,binY))
367
368 if not self.relativeMetric:
369 if minDiff <= maxDiff:
370 self.hist4D.SetBinContent(binX,binY,0)
371 elif plotStyle == 0:
372 self.hist4D.SetBinContent(binX,binY,minDiffFromNominal.hist4D.GetBinContent(binX,binY))
373 elif plotStyle == 1:
374 self.hist4D.SetBinContent(binX,binY,maxDiff-minDiff)
375 elif plotStyle == 2:
376 self.hist4D.SetBinContent(binX,binY,nominalHist.hist4D.GetBinContent(binX,binY))
377 else:
378 print "Unrecognized plotStyle of ",plotStyle
379 return False
380 else:
381 # The min difference from 1 (nominal vs reduced) should be smaller
382 # than the max difference from 1 (reduced vs reduced) as a relative comparison
383 if (minDiff <= 1 and maxDiff <= 1) and (minDiff >= maxDiff):
384 self.hist4D.SetBinContent(binX,binY,1)
385 elif (minDiff >= 1 and maxDiff >= 1) and (minDiff <= maxDiff):
386 self.hist4D.SetBinContent(binX,binY,1)
387 elif (minDiff >= 1 and maxDiff <= 1) and (minDiff <= 1/maxDiff):
388 self.hist4D.SetBinContent(binX,binY,1)
389 elif (minDiff <= 1 and maxDiff >= 1) and (minDiff >= 1/maxDiff):
390 self.hist4D.SetBinContent(binX,binY,1)
391 else:
392 if plotStyle == 0:
393 self.hist4D.SetBinContent(binX,binY,minDiffFromNominal.hist4D.GetBinContent(binX,binY))
394 elif plotStyle == 1:
395 if (minDiff <= 1 and maxDiff <= 1) or (minDiff >= 1 and maxDiff >= 1):
396 self.hist4D.SetBinContent(binX,binY,minDiff/maxDiff)
397 else:
398 self.hist4D.SetBinContent(binX,binY,minDiff*maxDiff)
399 elif plotStyle == 2:
400 self.hist4D.SetBinContent(binX,binY,nominalHist.hist4D.GetBinContent(binX,binY))
401 else:
402 print "Unrecognized plotStyle of ",plotStyle
403 return False
404
405 return True
406
407
408
410
411def DrawLabels(hist,jetDefString,scenarioString,drawATLASLabel,labelName):
412 if scenarioString != "":
413 if drawATLASLabel:
414 AtlasStyleMacro.ATLASLabel(0.10,0.845,labelName)
415 jetDefLabel = ""
416
417 if jetDefString.startswith("AntiKt4"):
418 jetDefLabel += "anti-k_{t} #it{R} = 0.4, "
419 elif jetDefString.startswith("AntiKt6"):
420 jetDefLabel += "anti-k_{t} #it{R} = 0.6, "
421
422 if jetDefString.endswith("LCTopo") or jetDefString.endswith("TopoLC"):
423 jetDefLabel += "LCW+JES"
424 elif jetDefString.endswith("EMTopo") or jetDefString.endswith("TopoEM"):
425 jetDefLabel += "EM+JES"
426
427 scenarioString = "{0}".format(scenarioString)
428 doDrawText(0.10,0.900,jetDefLabel+" 2016")
429 doDrawText(0.10,0.955,scenarioString)
430 else:
431 if drawATLASLabel:
432 AtlasStyleMacro.ATLASLabel(0.09,0.955,labelName)
433 jetDefLabel = ""
434
435 if jetDefString.startswith("AntiKt4"):
436 jetDefLabel += "anti-#it{k}_{t} #it{R} = 0.4, "
437 elif jetDefString.startswith("AntiKt6"):
438 jetDefLabel += "anti-#it{k}_{t} #it{R} = 0.6, "
439
440 if jetDefString.endswith("LCTopo") or jetDefString.endswith("TopoLC"):
441 jetDefLabel += "LCW+JES + #it{in situ}"
442 elif jetDefString.endswith("EMTopo") or jetDefString.endswith("TopoEM"):
443 jetDefLabel += "EM+JES + #it{in situ}"
444
445 scenarioString = "{0}".format(scenarioString)
446 doDrawText(0.50,0.955,jetDefLabel)
447 doDrawText(0.09,0.900,"Data 2015, #sqrt{s} = 13 TeV")
448
450 jetDefString = histo.jetDef
451 scenarioLabel = histo.hist4D.GetName().replace("4D_varpt_%s_"%(jetDefString),"").replace("4D_vareta_%s_"%(jetDefString),"").replace(".root","")
452 plotType = histo.plotType
453 if "_" in scenarioLabel:
454 if scenarioLabel.startswith("diff_"):
455 scenarioLabel = re.sub("diff_","",scenarioLabel)
456 scenarioLabel = re.sub("_"," - ",scenarioLabel)
457 scenarioLabel = "Correlation differences, "+scenarioLabel
458 elif scenarioLabel.startswith("minDiff_"):
459 scenarioLabel = re.sub("minDiff_","",scenarioLabel)
460 scenarioLabel = re.sub("_",", ",scenarioLabel)
461 #scenarioLabel = "Correlation differences, min[" + scenarioLabel + "]"
462 scenarioLabel = "Metric 1 (minimum correlation differences)" if not histo.relativeMetric else "Metric 1' (minimum correlation differences)"
463 elif scenarioLabel.startswith("maxDiff_"):
464 scenarioLabel = re.sub("maxDiff_","",scenarioLabel)
465 scenarioLabel = re.sub("_",", ",scenarioLabel)
466 scenarioLabel = "Correlation differences, max[" + scenarioLabel + "]"
467 elif scenarioLabel.startswith("coverageRaw_"):
468 scenarioLabel = re.sub("coverageRaw_","",scenarioLabel)
469 scenarioLabel = re.sub("_",", ",scenarioLabel)
470 #scenarioLabel = "Correlation loss coverage, [" + scenarioLabel + "]"
471 scenarioLabel = "Metric 2 (raw)"
472 elif scenarioLabel.startswith("coverageRes_") or plotType == "Metric2" or plotType == "Metric 2":
473 scenarioLabel = re.sub("coverageRes_","",scenarioLabel)
474 scenarioLabel = re.sub("_",", ",scenarioLabel)
475 #scenarioLabel = "Correlation loss remaining, [" + scenarioLabel + "]"
476 scenarioLabel = "Metric 2 (uncovered correlation differences)" if not histo.relativeMetric else "Metric 2' (uncovered correlation differences)"
477 elif scenarioLabel.startswith("uncertaintyRaw_coverageRaw"):
478 #scenarioLabel = "Remaining loss not covered by correlation uncertainties"
479 scenarioLabel = "Metric 3 (raw)"
480 elif scenarioLabel.startswith("uncertaintyRes_coverageRes") or plotType == "Metric3" or plotType == "Metric 3":
481 #scenarioLabel = "Remaining loss beyond correlation uncertainties"
482 scenarioLabel = "Metric 3 (uncovered corr. diff. including uncertainties)" if not histo.relativeMetric else "Metric 3' (uncovered corr. diff. including uncertainties)"
483 elif scenarioLabel=="uncenvelope":
484 scenarioLabel = "Correlation uncertainties"
485 else:
486 scenarioNum = re.sub("JER","",re.sub("4NP","",re.sub("3NP","",scenarioLabel)))
487 if len(scenarioNum) == 1:
488 scenarioLabel = "Correlation difference, Rep_{full}^{JES} - Rep_{str.red}^{%s,JES}"%(scenarioNum if not (scenarioNum == "3" and "JER" in scenarioLabel) else "evdm")
489 else:
490 scenarioNum = "Correlation difference, full - %s"%(scenarioLabel)
491
492 DrawLabels(histo.hist4D,jetDefString,"",histo.DrawATLASLabel,histo.ATLASLabelName)
493 #DrawLabels(histo.hist4D,jetDefString,scenarioLabel,histo.DrawATLASLabel,histo.ATLASLabelName)
494
495 sanitizedLabel= "Uncovered correlation loss" if "Metric 2" in scenarioLabel else (scenarioLabel if "Metric" not in scenarioLabel else re.sub("\‍)","",re.sub(".*\‍(","",scenarioLabel)))
496 histo.hist4D.GetZaxis().SetTitle(sanitizedLabel)
497 histo.hist4D.GetZaxis().SetTitleOffset(1.8)
498
499def saveHists4D(canvas,plotFileName,hist,oneSidedAxis,fixedX,fixedY,fixedStr,scenarioLabel="",drawATLASLabel=True,additionalString = ""):
500
501 # Check for empty inputs
502 if not hist:
503 pass
504 elif isinstance(hist,list):
505 # A list, iterate on the entries
506 for aHist in hist:
507 saveHists4D(canvas,plotFileName,aHist,oneSidedAxis,fixedX,fixedY,fixedStr,drawATLASLabel=drawATLASLabel,additionalString = "{0}.{1}".format(additionalString,hist.index(aHist)))
508 else:
509 # Not a list, save the output
510 hist.DrawATLASLabel = drawATLASLabel
511 SetAxisRange(hist.hist4D,oneSidedAxis,hist.OOBT,1e10)
512 SetAxisLabels(hist.hist4D,fixedX,fixedY,fixedStr)
513
514 if canvas.GetLogx():
515 hist.hist4D.GetXaxis().SetMoreLogLabels()
516 if canvas.GetLogy():
517 hist.hist4D.GetYaxis().SetMoreLogLabels()
518 if canvas.GetLogz():
519 hist.hist4D.GetZaxis().SetMoreLogLabels()
520 hist.hist4D.GetZaxis().SetLabelOffset(0.0010)
521
522 if hist.relativeMetric:
523 for binX in range(1,hist.hist4D.GetNbinsX()+1):
524 for binY in range(1,hist.hist4D.GetNbinsY()+1):
525 if hist.hist4D.GetBinContent(binX,binY) < hist.OOBT:
526 hist.hist4D.SetBinContent(binX,binY,1.e-10)
527 hist.hist4D.Draw("colz")
528 DrawGrid(hist.hist4D,fixedX,fixedY)
529 thisMaxAll,thisMaxAvg = DetermineStatValues(hist.hist4D,fixedX,fixedY,hist.OOBT if not hist.relativeMetric else 1.e-9,1e10,not hist.relativeMetric)
530 if scenarioLabel != "": DrawLabels(hist.hist4D,hist.jetDef,scenarioLabel,hist.DrawATLASLabel,hist.ATLASLabelName)
531 else: DrawLabelsGuessScenario(hist)
532
533 if not (plotFileName.endswith(".eps") or plotFileName.endswith(".png")):
534 canvas.Print(plotFileName)
535 else:
536 mynewname = plotFileName.replace(".png","-{0}-maxAll{1}-maxAvg{2}.png".format(additionalString,int(fabs(thisMaxAll*100)),int(fabs(thisMaxAvg*100))))
537 mynewname = mynewname.replace(".eps","-{0}-maxAll{1}-maxAvg{2}.eps".format(additionalString, int(fabs(thisMaxAll*100)),int(fabs(thisMaxAvg*100))))
538 canvas.Print(mynewname)
539 hist.iEPS += 1
540 #canvas.Print(getPlotFileName(plotFileName))
541
542
543
548
549
551 # Parse the histogram name
552 tokens = histName.split("_")
553 fixed1 = ""
554 fixed2 = ""
555 for aToken in tokens:
556 keep = False
557 if aToken.startswith("pt"):
558 keep = True
559 elif aToken.startswith("eta"):
560 keep = True
561
562 if keep:
563 if fixed1 == "":
564 fixed1 = aToken
565 elif fixed2 == "":
566 fixed2 = aToken
567 else:
568 print "ERROR: More than two fixed values appear in name:",histName
569 sys.exit(-1)
570 return fixed1,fixed2
571
572
573def getFixedValuesFromFile(inFile,jetDef):
574 newfixedPt = []
575 newfixedEta = []
576 for histName in inFile.GetKeyNames():
577 # Ensure this histogram is for the collection we want
578 if not jetDef in histName:
579 continue
580 # Ensure this is a difference histogram
581 if not histName.startswith("diff_"):
582 continue
583
584 fixed1,fixed2 = getFixedValuesFromName(histName)
585
586 if fixed1 != "" and fixed2 != "":
587 if fixed1.startswith("pt") and fixed2.startswith("pt"):
588 newfixedPt.append([float(fixed1.replace("pt","",1)),float(fixed2.replace("pt","",1))])
589 elif fixed1.startswith("eta") and fixed2.startswith("eta"):
590 newfixedEta.append([float(fixed1.replace("eta","",1)),float(fixed2.replace("eta","",1))])
591 else:
592 print "ERROR: Unexpected mixture of fixed variables for histogram:",histName
593 sys.exit(-1)
594 else:
595 print "ERROR: Failed to parse histogram name for fixed values:",histName
596 sys.exit(-2)
597
598
599 return newfixedPt,newfixedEta
600
601
602def getFixedValuesFromFiles(inFiles,jetDef):
603 # Get fixed pt and/or eta values from the first file
604 newfixedPt,newfixedEta = getFixedValuesFromFile(inFiles[0],jetDef)
605 newfixedPt.sort()
606 newfixedEta.sort()
607
608 # Ensure that subsequent file(s) match the fixed pt/eta values
609 for aFile in inFiles[1:]:
610 localFixedPt,localFixedEta = getFixedValuesFromFile(aFile,jetDef)
611 localFixedPt.sort()
612 localFixedEta.sort()
613
614 # Check for equality
615 # Note that these are floating point equalities, so be careful
616 if len(localFixedPt) != len(newfixedPt):
617 print "ERROR: File %s has %d fixed pt values, while %s has %d values"%(aFile.GetNameNoDir(),len(localFixedPt),inFiles[0],len(newfixedPt))
618 sys.exit(3)
619 elif len(localFixedEta) != len(newfixedEta):
620 print "ERROR: File %s has %d fixed eta values, while %s has %d values"%(aFile.GetNameNoDir(),len(localFixedEta),inFiles[0],len(newfixedEta))
621 sys.exit(4)
622 for localVal,globalVal in zip(localFixedPt,newfixedPt):
623 if fabs(localVal[0]-globalVal[0]) > 1.e-4 or fabs(localVal[1]-globalVal[1]) > 1.e-4:
624 print "ERROR: File %s and %s have different fixed pt values, was comparing %f and %f"%(aFile.GetNameNoDir(),inFiles[0],localVal,globalVal)
625 sys.exit(5)
626 for localVal,globalVal in zip(localFixedEta,newfixedEta):
627 if fabs(localVal[0]-globalVal[0]) > 1.e-4 or fabs(localVal[1]-globalVal[1]) > 1.e-4:
628 print "ERROR: File %s and %s have different fixed eta values, was comparing %f and %f"%(aFile.GetNameNoDir(),inFiles[0],localVal,globalVal)
629 sys.exit(6)
630
631 # Files have now been confirmed to match in fixed values, assuming multiple files were specified
632 # Determine the actual pT and eta values available now (not just pairs)
633 newfixedPtX = set([])
634 newfixedPtY = set([])
635 for newfixedPtSet in newfixedPt:
636 newfixedPtX.add(newfixedPtSet[0])
637 newfixedPtY.add(newfixedPtSet[1])
638 newfixedPtX = sorted(newfixedPtX)
639 newfixedPtY = sorted(newfixedPtY)
640
641 newfixedEtaX = set([])
642 newfixedEtaY = set([])
643 for newfixedEtaSet in newfixedEta:
644 newfixedEtaX.add(newfixedEtaSet[0])
645 newfixedEtaY.add(newfixedEtaSet[1])
646 newfixedEtaX = sorted(newfixedEtaX)
647 newfixedEtaY = sorted(newfixedEtaY)
648
649 # Done, return the sorted lists of fixed values
650 return newfixedPtX,newfixedPtY,newfixedEtaX,newfixedEtaY
651
652
653def relativeMetric(numerator,denominator):
654 if fabs(denominator) < 1.e-3:
655 if fabs(numerator) < 1.e-3:
656 return 1
657 else:
658 return globalOOB
659 if numerator/denominator < 0:
660 print "NUM/DEN = %f/%f"%(numerator,denominator)
661 return sqrt(numerator/denominator)
662
663
668
669
670def buildAndFillHists4DFromFiles(inFiles,jetDef,varString,fixedString,fixedX,fixedY,filterStartString="",granularityFactor=1,relativeMetric=False):
671 try:
672 iterator = iter(inFiles)
673 except TypeError:
674 # Not iterable
675 # Probably a single item
676 inFiles = [inFiles]
677 else:
678 # Iterable
679 # Probably a list of files, but watch for strings
680 if isinstance(inFiles,str):
681 inFiles = [TFile.Open(inFiles,"READ")]
682 else:
683 for iFile in range(0,len(inFiles)):
684 if isinstance(inFiles[iFile],str):
685 inFiles[iFile] = TFile.Open(inFiles[iFile],"READ")
686
687 hists4D = [CorrMat4D(relativeMetric) for aFile in inFiles]
688 for aFile,aHist in zip(inFiles,hists4D):
689 aHist.setInfo(jetDef,varString,"raw" if filterStartString == "" else "raw_"+ re.sub("_","",filterStartString))
690 if not aHist.fillHist4DFromFile(aFile,fixedString,fixedX,fixedY,filterStartString,granularityFactor):
691 return None
692
693 return hists4D
694
695
696def buildAndFillHists4DFromFile(inFile,jetDef,varString,fixedString,fixedX,fixedY,excludeStartString="",granularityFactor=1,relativeMetric=False):
697 try:
698 iterator = iter(inFile)
699 except TypeError:
700 # Not iterable
701 # Probably a single item
702 # Nothing to do in this case
703 pass
704 else:
705 # Iterable
706 # Probably a list of files, but watch for a single string
707 if isinstance(inFile,str):
708 inFile = TFile.Open(inFile,"READ")
709 else:
710 print "Expected a string, but did not receive one: ",inFile
711 print "This method is for building a set of histograms from a single file"
712 return None
713
714 # Get the list of starts (the string before _var*)
715 startStrings = set()
716 for histName in inFile.GetKeyNames():
717 if excludeStartString != "" and histName.startswith(excludeStartString):
718 continue
719 # Find the _var and get what's in front of it
720 startStrings.add(histName[:histName.find("_var")])
721
722 # Now run over the scenarios
723 hists4D = [CorrMat4D(relativeMetric) for aString in startStrings]
724 for aString,aHist in zip(startStrings,hists4D):
725 aHist.setInfo(jetDef,varString,"raw_"+aString)
726 if not aHist.fillHist4DFromFile(inFile,fixedString,fixedX,fixedY,aString,granularityFactor):
727 return None
728
729 return hists4D
730
731
732def buildAndFillHists4DFromDifferenceHists(hists,relativeMetric=False) :
733
734 # Must do all possible comparisons
735 diffHists = []
736 for iHist1 in range(0,len(hists)):
737 for iHist2 in range(iHist1+1,len(hists)):
738 hist4D = CorrMat4D(relativeMetric)
739 hist4D.setInfoCopy(hists[iHist1],"diff_%s_%s"%(hists[iHist1].plotType,hists[iHist2].plotType))
740 if not hist4D.fillHist4DFromDifference(hists[iHist1],hists[iHist2]):
741 return None
742 diffHists.append(hist4D)
743 return diffHists
744
745def buildAndFillHist4DFromMinOfSet(hists,relativeMetric=False):
746 # Ensure the histogram(s) exist
747 if not hists or len(hists) == 0:
748 print "Argument is None or empty list: ",hists
749 return None
750
751 minHist = CorrMat4D(relativeMetric)
752 minHist.setInfoCopy(hists[0],"minDiff_%dinputs"%(len(hists)))
753 if not minHist.fillHist4DFromMinOfSet(hists):
754 return None
755 return minHist
756
757def buildAndFillHist4DFromMaxOfSet(hists,relativeMetric=False):
758 # Ensure the histogram(s) exist
759 if not hists or len(hists) == 0:
760 print "Argument is None or empty list: ",hists
761 return None
762
763 maxHist = CorrMat4D(relativeMetric)
764 maxHist.setInfoCopy(hists[0],"maxDiff_%dinputs"%(len(hists)))
765 if not maxHist.fillHist4DFromMaxOfSet(hists):
766 return None
767 return maxHist
768
769def buildAndFillHists4DFromEnvelopeOfSet(hists,relativeMetric=False):
770 # Ensure the histogram(s) exist
771 if not hists or len(hists) < 2:
772 print "Argument is None or contains less than two histograms: ",hists
773 return None
774
775 envelopeHist = CorrMat4D(relativeMetric)
776 envelopeHist.setInfoCopy(hists[0],"envelope_%dinputs"%(len(hists)))
777 if not envelopeHist.fillHist4DFromEnvelopeOfSet(hists):
778 return None
779 return envelopeHist
780
781def buildAndFillHist4DFromCoverageOfSet(minDiffFromNominal,maxDiffBetweenScenarios,plotStyle,nominalHist=None,relativeMetric=False):
782 coverageHist = CorrMat4D(relativeMetric)
783 coverageHist.setInfoCopy(minDiffFromNominal,"coverage_type%d"%(plotStyle))
784
785 if not coverageHist.fillHist4DFromCoverageOfSet(minDiffFromNominal,maxDiffBetweenScenarios,plotStyle,nominalHist):
786 return None
787 return coverageHist
788
789
fillHist4DFromCoverageOfSet(self, minDiffFromNominal, maxDiffBetweenScenarios, plotStyle, nominalHist=None)
4D histogram from coverage of a 4D set #
setInfo(self, jetDef, varType, plotType)
fillHist4DFromMaxOfSet(self, hists)
4D histogram from maximum value of a 4D set #
fillHist4DFromMinOfSet(self, hists)
4D histogram from minimum value of a 4D set #
fillHist4DFromFile(self, inFile, fixedString, fixedX, fixedY, filterStartString="", granularityFactor=1)
4D histogram building from 2D histograms #
fillHist4DFromEnvelopeOfSet(self, hists)
4D histogram from envelope of a 4D set #
fillHist4DFromDifference(self, hist1, hist2)
4D histograms from differences of 4D hist sets #
STL class.
std::string replace(std::string s, const std::string &s2, const std::string &s3)
Definition hcg.cxx:310
ATLASLabel(x, y, text="", color=kBlack)
buildAndFillHists4DFromEnvelopeOfSet(hists, relativeMetric=False)
buildAndFillHists4DFromDifferenceHists(hists, relativeMetric=False)
buildAndFillHist4DFromMinOfSet(hists, relativeMetric=False)
buildAndFillHists4DFromFile(inFile, jetDef, varString, fixedString, fixedX, fixedY, excludeStartString="", granularityFactor=1, relativeMetric=False)
buildAndFillHist4DFromMaxOfSet(hists, relativeMetric=False)
saveHists4D(canvas, plotFileName, hist, oneSidedAxis, fixedX, fixedY, fixedStr, scenarioLabel="", drawATLASLabel=True, additionalString="")
DrawLabels(hist, jetDefString, scenarioString, drawATLASLabel, labelName)
buildAndFillHist4DFromCoverageOfSet(minDiffFromNominal, maxDiffBetweenScenarios, plotStyle, nominalHist=None, relativeMetric=False)
buildAndFillHists4DFromFiles(inFiles, jetDef, varString, fixedString, fixedX, fixedY, filterStartString="", granularityFactor=1, relativeMetric=False)
relativeMetric(numerator, denominator)
SetAxisRange(histo, oneSided=True, lowBound=-1e10, highBound=1e10)
SetAxisLabels(histo, xValues, yValues, labelString)
DrawGrid(histo, xValues, yValues)
DetermineStatValues(histo, xValues, yValues, lowBound=-1e10, highBound=1e10, percent=True)
doDrawText(xPos, yPos, text)