ATLAS Offline Software
CorrelationMatrixHelpers.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 from math import fabs,exp,log,sqrt
6 import sys
7 import re
8 import os
9 import AtlasStyleMacro
10 
11 from PlotHelpers import *
12 
13 # Script is Steven's
14 # Structural modifications by Kate, Dec 2016
15 
16 
21 
22 class CorrMat4D:
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 
411 def 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 
499 def 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 
573 def 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 
602 def 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 
653 def 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 
670 def 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 
696 def 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 
732 def 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 
745 def 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 
757 def 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 
769 def 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 
781 def 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 
CorrelationMatrixHelpers.buildAndFillHists4DFromDifferenceHists
def buildAndFillHists4DFromDifferenceHists(hists, relativeMetric=False)
Definition: CorrelationMatrixHelpers.py:732
replace
std::string replace(std::string s, const std::string &s2, const std::string &s3)
Definition: hcg.cxx:307
PlotHelpers.SetAxisRange
def SetAxisRange(histo, oneSided=True, lowBound=-1e10, highBound=1e10)
Definition: PlotHelpers.py:101
CorrelationMatrixHelpers.DrawLabels
def DrawLabels(hist, jetDefString, scenarioString, drawATLASLabel, labelName)
Definition: CorrelationMatrixHelpers.py:411
CorrelationMatrixHelpers.buildAndFillHist4DFromMinOfSet
def buildAndFillHist4DFromMinOfSet(hists, relativeMetric=False)
Definition: CorrelationMatrixHelpers.py:745
vtune_athena.format
format
Definition: vtune_athena.py:14
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
CorrelationMatrixHelpers.CorrMat4D.cloneHist4D
def cloneHist4D(self, toClone)
Definition: CorrelationMatrixHelpers.py:50
CorrelationMatrixHelpers.CorrMat4D.DrawATLASLabel
DrawATLASLabel
Definition: CorrelationMatrixHelpers.py:36
CorrelationMatrixHelpers.CorrMat4D.fillHist4DFromMinOfSet
def fillHist4DFromMinOfSet(self, hists)
4D histogram from minimum value of a 4D set #
Definition: CorrelationMatrixHelpers.py:203
CorrelationMatrixHelpers.CorrMat4D.fillHist4DFromDifference
def fillHist4DFromDifference(self, hist1, hist2)
4D histograms from differences of 4D hist sets #
Definition: CorrelationMatrixHelpers.py:175
CorrelationMatrixHelpers.saveHists4D
def saveHists4D(canvas, plotFileName, hist, oneSidedAxis, fixedX, fixedY, fixedStr, scenarioLabel="", drawATLASLabel=True, additionalString="")
Definition: CorrelationMatrixHelpers.py:499
PlotHelpers.SetAxisLabels
def SetAxisLabels(histo, xValues, yValues, labelString)
Definition: PlotHelpers.py:203
CorrelationMatrixHelpers.buildAndFillHist4DFromMaxOfSet
def buildAndFillHist4DFromMaxOfSet(hists, relativeMetric=False)
Definition: CorrelationMatrixHelpers.py:757
CorrelationMatrixHelpers.CorrMat4D.histName
histName
Definition: CorrelationMatrixHelpers.py:139
CorrelationMatrixHelpers.CorrMat4D.setInfoCopy
def setInfoCopy(self, toCopy, plotType="")
Definition: CorrelationMatrixHelpers.py:45
CorrelationMatrixHelpers.getFixedValuesFromFiles
def getFixedValuesFromFiles(inFiles, jetDef)
Definition: CorrelationMatrixHelpers.py:602
CorrelationMatrixHelpers.CorrMat4D.fillHist4DFromMaxOfSet
def fillHist4DFromMaxOfSet(self, hists)
4D histogram from maximum value of a 4D set #
Definition: CorrelationMatrixHelpers.py:253
CorrelationMatrixHelpers.CorrMat4D.jetDef
jetDef
Definition: CorrelationMatrixHelpers.py:26
CorrelationMatrixHelpers.getFixedValuesFromFile
def getFixedValuesFromFile(inFile, jetDef)
Definition: CorrelationMatrixHelpers.py:573
PlotHelpers.DetermineStatValues
def DetermineStatValues(histo, xValues, yValues, lowBound=-1e10, highBound=1e10, percent=True)
Definition: PlotHelpers.py:256
CorrelationMatrixHelpers.CorrMat4D.fillHist4DFromCoverageOfSet
def fillHist4DFromCoverageOfSet(self, minDiffFromNominal, maxDiffBetweenScenarios, plotStyle, nominalHist=None)
4D histogram from coverage of a 4D set #
Definition: CorrelationMatrixHelpers.py:340
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
CorrelationMatrixHelpers.buildAndFillHists4DFromEnvelopeOfSet
def buildAndFillHists4DFromEnvelopeOfSet(hists, relativeMetric=False)
Definition: CorrelationMatrixHelpers.py:769
CorrelationMatrixHelpers.DrawLabelsGuessScenario
def DrawLabelsGuessScenario(histo)
Definition: CorrelationMatrixHelpers.py:449
CorrelationMatrixHelpers.CorrMat4D.relativeMetric
relativeMetric
Definition: CorrelationMatrixHelpers.py:32
TH2D
Definition: rootspy.cxx:430
CorrelationMatrixHelpers.CorrMat4D.iEPS
iEPS
Definition: CorrelationMatrixHelpers.py:37
CorrelationMatrixHelpers.CorrMat4D.OOBT
OOBT
Definition: CorrelationMatrixHelpers.py:30
CorrelationMatrixHelpers.CorrMat4D.applyAbsValue
def applyAbsValue(self)
Definition: CorrelationMatrixHelpers.py:57
AtlasStyleMacro.ATLASLabel
def ATLASLabel(x, y, text="", color=kBlack)
Definition: AtlasStyleMacro.py:108
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.
CxxUtils::set
constexpr std::enable_if_t< is_bitmask_v< E >, E & > set(E &lhs, E rhs)
Convenience function to set bits in a class enum bitmask.
Definition: bitmask.h:224
CorrelationMatrixHelpers.buildAndFillHist4DFromCoverageOfSet
def buildAndFillHist4DFromCoverageOfSet(minDiffFromNominal, maxDiffBetweenScenarios, plotStyle, nominalHist=None, relativeMetric=False)
Definition: CorrelationMatrixHelpers.py:781
CorrelationMatrixHelpers.CorrMat4D.OOB
OOB
Definition: CorrelationMatrixHelpers.py:29
CorrelationMatrixHelpers.CorrMat4D.setInfo
def setInfo(self, jetDef, varType, plotType)
Definition: CorrelationMatrixHelpers.py:40
CorrelationMatrixHelpers.CorrMat4D.plotType
plotType
Definition: CorrelationMatrixHelpers.py:28
CorrelationMatrixHelpers.CorrMat4D.__init__
def __init__(self, relMet=False)
Definition: CorrelationMatrixHelpers.py:24
CorrelationMatrixHelpers.buildAndFillHists4DFromFiles
def buildAndFillHists4DFromFiles(inFiles, jetDef, varString, fixedString, fixedX, fixedY, filterStartString="", granularityFactor=1, relativeMetric=False)
Definition: CorrelationMatrixHelpers.py:670
CorrelationMatrixHelpers.CorrMat4D.varType
varType
Definition: CorrelationMatrixHelpers.py:27
CorrelationMatrixHelpers.buildAndFillHists4DFromFile
def buildAndFillHists4DFromFile(inFile, jetDef, varString, fixedString, fixedX, fixedY, excludeStartString="", granularityFactor=1, relativeMetric=False)
Definition: CorrelationMatrixHelpers.py:696
CorrelationMatrixHelpers.CorrMat4D.hist4D
hist4D
Definition: CorrelationMatrixHelpers.py:25
CorrelationMatrixHelpers.CorrMat4D.ATLASLabelName
ATLASLabelName
Definition: CorrelationMatrixHelpers.py:35
CorrelationMatrixHelpers.CorrMat4D.fillHist4DFromEnvelopeOfSet
def fillHist4DFromEnvelopeOfSet(self, hists)
4D histogram from envelope of a 4D set #
Definition: CorrelationMatrixHelpers.py:298
CorrelationMatrixHelpers.CorrMat4D.fillHist4DFromFile
def fillHist4DFromFile(self, inFile, fixedString, fixedX, fixedY, filterStartString="", granularityFactor=1)
4D histogram building from 2D histograms #
Definition: CorrelationMatrixHelpers.py:70
CorrelationMatrixHelpers.getFixedValuesFromName
def getFixedValuesFromName(histName)
Definition: CorrelationMatrixHelpers.py:550
readCCLHist.float
float
Definition: readCCLHist.py:83
PlotHelpers.doDrawText
def doDrawText(xPos, yPos, text)
Definition: PlotHelpers.py:89
CorrelationMatrixHelpers.relativeMetric
def relativeMetric(numerator, denominator)
Definition: CorrelationMatrixHelpers.py:653
PlotHelpers.DrawGrid
def DrawGrid(histo, xValues, yValues)
Definition: PlotHelpers.py:219
CorrelationMatrixHelpers.CorrMat4D
Definition: CorrelationMatrixHelpers.py:22