CMS 3D CMS Logo

Functions | Variables

MultipleCompare Namespace Reference

Functions

def DetermineHistType
def Divide
def DrawBranding
def DrawTitle
def FindParents
def findRange
def GetContent
def getMaximumIncludingErrors
def getMinimumIncludingErrors
def LoadCommandlineOptions
def main
def MapDirStructure
def Match
def optimizeRangeMainPad
def optimizeRangeSubPad
def Rebin

Variables

string __author__ = "Mauro Verzetti (mauro.verzetti@cern.ch)"
string __doc__

Function Documentation

def MultipleCompare::DetermineHistType (   name)

Definition at line 85 of file MultipleCompare.py.

00086                            :
00087   #automatically derive all plot types in the future?
00088   type = ''
00089   label = ''
00090   prefix = ''
00091   #assuming plots name like: tauType_plotType_xAxis or tauType_plotType_selection
00092   matches = re.match(r'.*/(.*)_(.*)_(.*)', name)
00093   if matches:
00094     prefix = matches.group(1) 
00095     label = matches.group(3)
00096     knowntypes = (['pTRatio','SumPt','Size'])
00097     for knowntype in knowntypes:
00098       if matches.group(2) == knowntype:
00099         type = knowntype
00100     if not type:  #there are plots labelled ..._vs_...
00101       type = 'Eff'
00102   else:
00103     type = 'Eff'
00104 
00105   prefixParts = prefix.partition('Discrimination')
00106   if prefixParts[2] != '':
00107     prefix = prefixParts[2]
00108     prefixParts = prefix.partition('By')
00109     if prefixParts[2] != '':
00110       prefix = prefixParts[2]
00111 
00112   #print 'type is ' + type
00113   return [type, label, prefix]

def MultipleCompare::Divide (   hNum,
  hDen 
)

Definition at line 66 of file MultipleCompare.py.

Referenced by FlavourHistograms2D< T, G >::divide(), and FlavourHistograms< T >::divide().

00067                      :
00068     ret = hNum.Clone('Division')
00069     ret.GetYaxis().SetTitle('Ratio')
00070     for binI in range(hNum.GetNbinsX()):
00071         denVal = hDen.GetBinContent(binI)
00072         denErr = hDen.GetBinError(binI)
00073         numErr = hNum.GetBinError(binI)
00074         numVal = hNum.GetBinContent(binI)
00075         if denVal == 0:
00076             ret.SetBinContent(binI,0)
00077             ret.SetBinError(binI,0)
00078         else:
00079             ret.SetBinContent(binI,numVal/denVal)
00080             if numVal==0:
00081                 ret.SetBinError(binI,1)
00082             else:
00083                 ret.SetBinError(binI,(numVal/denVal)*math.sqrt(math.pow(numErr/numVal,2) + math.pow(denErr/denVal,2) ) )
00084     return ret

def MultipleCompare::DrawBranding (   options,
  label = '' 
)

Definition at line 123 of file MultipleCompare.py.

00124                                    :
00125   if options.branding != None or label != '':
00126     text = TLatex()
00127     text.SetNDC();
00128     text.SetTextAlign(11)#3*10=right,3*1=top
00129     text.SetTextSize(.025)
00130     text.SetTextColor(13)
00131     if options.out.find(".eps")!=-1:
00132       text.SetTextAngle(-91.0)#eps BUG
00133     else:
00134       text.SetTextAngle(-90.0)
00135     rightMargin = 1 - gStyle.GetPadRightMargin()
00136     topMargin = 1 - gStyle.GetPadTopMargin()
00137     if label!='':
00138       label += ': '
00139     text.DrawLatex(rightMargin+.01, topMargin+0.025, label+options.branding);
00140 

def MultipleCompare::DrawTitle (   text)

Definition at line 114 of file MultipleCompare.py.

00115                    :
00116         title = TLatex()
00117         title.SetNDC()
00118         title.SetTextAlign(12)#3*10=right,3*1=top
00119         title.SetTextSize(.035) 
00120         leftMargin = gStyle.GetPadLeftMargin()
00121         topMargin = 1 - 0.5*gStyle.GetPadTopMargin()
00122         title.DrawLatex(leftMargin, topMargin, text)

def MultipleCompare::FindParents (   histoPath)

Definition at line 141 of file MultipleCompare.py.

00142                           :
00143     root = histoPath[:histoPath.find('_')]
00144     par = histoPath[histoPath.find('Eff')+3:]
00145     validationPlots = validation.proc.efficiencies.plots._Parameterizable__parameterNames
00146     found =0
00147     num = ''
00148     den = ''
00149     for efficiency in validationPlots:
00150         effpset = getattr(validation.proc.efficiencies.plots,efficiency)
00151         effName = effpset.efficiency.value()
00152         effNameCut = effName[effName.find('_'):effName.find('#')]
00153         if effNameCut in histoPath:
00154             if found == 1:
00155                 print 'More than one pair of parents found for ' + histopath + ':'
00156                 assert(False)
00157             num = root + effpset.numerator.value()[effName.find('_'):].replace('#PAR#',par)
00158             den = root + effpset.denominator.value()[effName.find('_'):].replace('#PAR#',par)
00159             found += 1
00160     return [num,den]

def MultipleCompare::findRange (   hists,
  min0 = -1,
  max0 = -1 
)

Definition at line 182 of file MultipleCompare.py.

00183                                       :
00184   if len(hists) < 1:
00185     return
00186   #auto ranges if no user value provided
00187   min = min0
00188   max = max0
00189   if min0 == -1 or max0 == -1:
00190     for hist in hists:
00191       if min0 == -1:
00192         #Divide() sets bin to zero if division not possible. Ignore these bins.
00193         minTmp = getMinimumIncludingErrors(hist)
00194         if minTmp < min or min == -1:
00195           min = minTmp
00196       if max0 == -1:
00197         maxTmp = getMaximumIncludingErrors(hist)
00198         if maxTmp > max or max == -1:
00199           max = maxTmp
00200   return [min, max]

def MultipleCompare::GetContent (   dir)

Definition at line 43 of file MultipleCompare.py.

00044                    :
00045     tempList = dir.GetListOfKeys()
00046     retList = []
00047     for it in range(0,tempList.GetSize()):
00048        retList.append(tempList.At(it).ReadObj())
00049     return retList

def MultipleCompare::getMaximumIncludingErrors (   hist)

Definition at line 233 of file MultipleCompare.py.

00234                                    :
00235 #find maximum considering also the errors
00236   distance = 1.
00237   max = -1
00238   pos = 0
00239   for i in range(1, hist.GetNbinsX()):
00240     if hist.GetBinContent(i) > max:#ignore errors here
00241       max = hist.GetBinContent(i)
00242       pos = i
00243   return max + distance*hist.GetBinError(pos)

def MultipleCompare::getMinimumIncludingErrors (   hist)

Definition at line 244 of file MultipleCompare.py.

00245                                    :
00246   #find minimum considering also the errors
00247   #ignoring zero bins
00248   distance = 1.
00249   min = -1
00250   pos = 0
00251   for i in range(1, hist.GetNbinsX()):
00252     if hist.GetBinContent(i)<=0.:#ignore errors here
00253       continue
00254     if hist.GetBinContent(i) < min or min==-1:
00255       min = hist.GetBinContent(i)
00256       pos = i
00257       if min < 0:
00258         min = 0  
00259   return min - distance*hist.GetBinError(pos)
00260 

def MultipleCompare::LoadCommandlineOptions (   argv)

Definition at line 16 of file MultipleCompare.py.

00017                                 :
00018   sys.argv = argv
00019   parser = OptionParser(description=__doc__)
00020   parser.add_option('--myhelp',metavar='', action="store_true",help='prints this output message',dest='help',default = False)
00021   parser.add_option('--TestFile','-T',metavar='testFile', type=str,help='Sets the test file',dest='test',default = '')
00022   parser.add_option('--RefFile','-R',metavar='refFile', type=str,help='Sets the reference file',dest='ref',default = None)
00023   parser.add_option('--output','-o',metavar='outputFile', type=str,help='Sets the output file',dest='out',default = 'MultipleCompare.png')
00024   parser.add_option('--logScale',action="store_true", dest="logScale", default=False, help="Sets the log scale in the plot")
00025   parser.add_option('--fakeRate','-f',action="store_true", dest="fakeRate", default=False, help="Sets the fake rate options and put the correct label (implies --logScale)")
00026   parser.add_option('--testLabel','-t',metavar='testLabel', type=str,help='Sets the label to put in the plots for test file',dest='testLabel',default = None)
00027   parser.add_option('--refLabel','-r',metavar='refLabel', type=str,help='Sets the label to put in the plots for ref file',dest='refLabel',default = None)
00028   parser.add_option('--maxLog',metavar='number', type=float,help='Sets the maximum of the scale in log scale (requires --logScale or -f to work)',dest='maxLog',default = 3)
00029   parser.add_option('--minDiv',metavar='number', type=float,help='Sets the minimum of the scale in the ratio pad',dest='minDiv',default = 0.001)
00030   parser.add_option('--maxDiv',metavar='number', type=float,help='Sets the maximum of the scale in the ratio pad',dest='maxDiv',default = 2)
00031   parser.add_option('--logDiv',action="store_true", dest="logDiv", default=False, help="Sets the log scale in the plot")
00032   parser.add_option('--normalize',action="store_true", dest="normalize", default=False, help="plot normalized")
00033   parser.add_option('--maxRange',metavar='number',type=float, dest="maxRange", default=1.6, help="Sets the maximum range in linear plots")
00034   parser.add_option('--rebin', dest="rebin", type=int, default=-1, help="Sets the rebinning scale")
00035   parser.add_option('--branding','-b',metavar='branding', type=str,help='Define a branding to label the plots (in the top right corner)',dest='branding',default = None)
00036   #parser.add_option('--search,-s',metavar='searchStrings', type=str,help='Sets the label to put in the plots for ref file',dest='testLabel',default = None) No idea on how to tell python to use all the strings before a new option, thus moving this from option to argument (but may be empty)  
00037   
00038   (options,toPlot) = parser.parse_args()
00039   if options.help:
00040     parser.print_help()
00041     sys.exit(0)
00042   return [options, toPlot]

def MultipleCompare::main (   argv = None)

Definition at line 261 of file MultipleCompare.py.

00262                    :
00263   if argv is None:
00264     argv = sys.argv
00265 
00266   options, toPlot = LoadCommandlineOptions(argv)
00267 
00268   gROOT.SetStyle('Plain')
00269   gROOT.SetBatch()
00270   gStyle.SetPalette(1)
00271   gStyle.SetOptStat(0)
00272   gStyle.SetPadGridX(True)
00273   gStyle.SetPadGridY(True)
00274   gStyle.SetOptTitle(0)
00275   gStyle.SetPadTopMargin(0.1)
00276   gStyle.SetPadBottomMargin(0.1)
00277   gStyle.SetPadLeftMargin(0.13)
00278   gStyle.SetPadRightMargin(0.07)
00279 
00280 
00281   testFile = TFile(options.test)
00282   refFile = None
00283   if options.ref != None:
00284     refFile = TFile(options.ref)
00285 
00286   #Takes the position of all plots that were produced
00287   plotList = []
00288   MapDirStructure( testFile,'',plotList)
00289 
00290   histoList = []
00291   for plot in toPlot:
00292     for path in plotList:
00293         if Match(plot.lower(),path.lower()):
00294             histoList.append(path)
00295 
00296 #  print "options: ",options
00297 #  print "toPlot: ",toPlot
00298   print histoList
00299 
00300   if len(histoList)<1:
00301     print '\tError: Please specify at least one histogram.'
00302     if len(toPlot)>0:
00303       print 'Check your plot list:', toPlot
00304     sys.exit()
00305 
00306 
00307   #WARNING: For now the hist type is assumed to be constant over all histos.
00308   histType, label, prefix = DetermineHistType(histoList[0])
00309   #decide whether or not to scale to an integral of 1
00310   #should usually not be used most plot types. they are already normalized.
00311   scaleToIntegral = False
00312   if options.normalize:
00313     scaleToIntegral = True
00314 
00315   ylabel = 'Efficiency'
00316 
00317   if options.fakeRate:
00318     ylabel = 'Fake rate'
00319 
00320   drawStats = False
00321   if histType=='pTRatio' and len(histoList)<3:
00322     drawStats = True
00323 
00324   #legend = TLegend(0.6,0.83,0.6+0.39,0.83+0.17)
00325   x1 = 0.55
00326   x2 = 1-gStyle.GetPadRightMargin()
00327   y2 = 1-gStyle.GetPadTopMargin()
00328   lineHeight = .025
00329   if len(histoList) == 1:
00330     lineHeight = .05
00331   y1 = y2 - lineHeight*len(histoList)
00332   legend = TLegend(x1,y1,x2,y2)
00333   #legend.SetHeader(label)
00334   legend.SetFillColor(0)
00335   if drawStats:
00336     y2 = y1
00337     y1 = y2 - .07*len(histoList)
00338     statsBox = TPaveText(x1,y1,x2,y2,"NDC")
00339     statsBox.SetFillColor(0)
00340     statsBox.SetTextAlign(12)#3*10=right,3*1=top
00341     statsBox.SetMargin(0.05)
00342     statsBox.SetBorderSize(1)
00343 
00344     
00345   canvas = TCanvas('MultiPlot','MultiPlot',validation.standardDrawingStuff.canvasSizeX.value(),832)
00346   effPad = TPad('effPad','effPad',0,0.25,1.,1.,0,0)
00347   effPad.SetBottomMargin(0.1);
00348   effPad.SetTopMargin(0.1);
00349   effPad.SetLeftMargin(0.13);
00350   effPad.SetRightMargin(0.07);
00351   effPad.Draw()
00352   header = ''
00353   if options.testLabel != None:
00354     header += 'Dots: '+options.testLabel
00355   if options.refLabel != None:
00356     header += ' Line: '+options.refLabel
00357   DrawTitle(header)
00358   DrawBranding(options)
00359   diffPad = TPad('diffPad','diffPad',0.,0.,1,.25,0,0)
00360   diffPad.Draw()
00361   colors = [2,3,4,6,5,7,28,1,2,3,4,6,5,7,28,1,2,3,4,6,5,7,28,1,2,3,4,6,5,7,28,1,2,3,4,6,5,7,28,1]
00362   first = True
00363   divHistos = []
00364   statTemplate = '%s Mean: %.3f RMS: %.3f'
00365   testHs = []
00366   refHs = []
00367   for histoPath,color in zip(histoList,colors):
00368     if(options.rebin == -1):
00369       testH = testFile.Get(histoPath)
00370     else:
00371         testH = Rebin(testFile,histoPath,options.rebin)
00372     if type(testH) != TH1F:
00373         print 'Looking for '+histoPath
00374         print 'Test plot now found! What the hell are you doing? Exiting...'
00375         sys.exit()
00376     testHs.append(testH)
00377     xAx = histoPath[histoPath.find('Eff')+len('Eff'):]
00378     effPad.cd()
00379     if not testH.GetXaxis().GetTitle():  #only overwrite label if none already existing
00380       if hasattr(validation.standardDrawingStuff.xAxes,xAx):
00381         testH.GetXaxis().SetTitle( getattr(validation.standardDrawingStuff.xAxes,xAx).xAxisTitle.value())
00382     if not testH.GetYaxis().GetTitle():  #only overwrite label if none already existing
00383       testH.GetYaxis().SetTitle(ylabel)
00384     if label!='':
00385       testH.GetXaxis().SetTitle(label+': '+testH.GetXaxis().GetTitle())
00386     testH.GetXaxis().SetTitleOffset(1.1)
00387     testH.GetYaxis().SetTitleOffset(1.5)
00388     testH.SetMarkerSize(1)
00389     testH.SetMarkerStyle(20)
00390     testH.SetMarkerColor(color)
00391     if histType == 'Eff':
00392       legend.AddEntry(testH,histoPath[histoPath.rfind('/')+1:histoPath.find(histType)],'p')
00393     else:
00394       legend.AddEntry(testH,DetermineHistType(histoPath)[2],'p')
00395     if drawStats:
00396         text = statsBox.AddText(statTemplate % ('Dots',testH.GetMean(), testH.GetRMS()) )
00397         text.SetTextColor(color)
00398     if first:
00399         first = False
00400         if options.logScale:
00401             effPad.SetLogy()
00402         if scaleToIntegral:
00403           if testH.GetEntries() > 0:
00404             if not testH.GetSumw2N():
00405               testH.Sumw2()
00406               testH.DrawNormalized('ex0 P')
00407             else:
00408               print "--> Warning! You tried to normalize a histogram which seems to be already scaled properly. Draw it unscaled."
00409               scaleToIntegral = False
00410               testH.Draw('ex0')
00411         else:
00412           testH.Draw('ex0')
00413     else:
00414         if scaleToIntegral:
00415           if testH.GetEntries() > 0:
00416             testH.DrawNormalized('same p')
00417         else:
00418             testH.Draw('same ex0 l')
00419     if refFile == None:
00420         continue
00421     if(options.rebin == -1):
00422         refH = refFile.Get(histoPath)
00423     else:
00424         refH = Rebin(refFile,histoPath,options.rebin)
00425     if type(refH) != TH1F:
00426         continue
00427     refHs.append(refH)
00428     refH.SetLineColor(color)
00429     refH.SetLineWidth(1)
00430     if scaleToIntegral:
00431       if testH.GetEntries() > 0:
00432         refH.DrawNormalized('same hist')
00433     else:
00434         refH.DrawCopy('same hist')
00435     if drawStats:
00436       text = statsBox.AddText(statTemplate % ('Line',refH.GetMean(), refH.GetRMS()) )
00437       text.SetTextColor(color)
00438     refH.SetFillColor(color)
00439     refH.SetFillStyle(3001)
00440     if scaleToIntegral:
00441         entries = testH.GetEntries()
00442         if entries > 0:
00443           testH.Scale(1./entries)
00444         entries = refH.GetEntries()
00445         refH.Sumw2()
00446         if entries > 0:
00447           refH.Scale(1./entries)
00448     refH.Draw('same e3')
00449     divHistos.append(Divide(testH,refH))
00450 
00451   tmpHists = []
00452   tmpHists.extend(testHs)
00453   tmpHists.extend(refHs)
00454   optimizeRangeMainPad(argv, effPad, tmpHists)
00455   
00456   firstD = True
00457   if refFile != None:
00458     for histo,color in zip(divHistos,colors):
00459         diffPad.cd()
00460         histo.SetMarkerSize(1)
00461         histo.SetMarkerStyle(20)
00462         histo.SetMarkerColor(color)
00463         histo.GetYaxis().SetLabelSize(0.08)
00464         histo.GetYaxis().SetTitleOffset(0.6)
00465         histo.GetYaxis().SetTitleSize(0.08)
00466         histo.GetXaxis().SetLabelSize(0.)
00467         histo.GetXaxis().SetTitleSize(0.)
00468         if firstD:
00469             if options.logDiv:
00470                 diffPad.SetLogy()
00471             histo.Draw('ex0')
00472             firstD = False
00473         else:
00474             histo.Draw('same ex0')
00475             diffPad.Update()
00476     optimizeRangeSubPad(argv, divHistos)
00477 
00478     effPad.cd()
00479   legend.Draw()
00480   if drawStats:
00481     statsBox.Draw()
00482   canvas.Print(options.out)
00483 

def MultipleCompare::MapDirStructure (   directory,
  dirName,
  objectList 
)

Definition at line 50 of file MultipleCompare.py.

00051                                                      :
00052     dirContent = GetContent(directory)
00053     for entry in dirContent:
00054         if type(entry) is TDirectory or type(entry) is TDirectoryFile:
00055             subdirName = os.path.join(dirName,entry.GetName())
00056             MapDirStructure(entry, subdirName,objectList)
00057         else:
00058             pathname = os.path.join(dirName,entry.GetName())
00059             objectList.append(pathname)

def MultipleCompare::Match (   required,
  got 
)

Definition at line 60 of file MultipleCompare.py.

Referenced by FWGeometryTableManager::loadGeometry(), lhef::JetMatchingMLM::match(), lhef::Matching< Delta >::match(), btag::Matching< Delta >::match(), and MatchJet::matchCollections().

00061                         :
00062     for part in required.split('*'):
00063         if got.find(part) == -1:
00064             return False
00065     return True

def MultipleCompare::optimizeRangeMainPad (   argv,
  pad,
  hists 
)

Definition at line 201 of file MultipleCompare.py.

00202                                           :
00203   pad.Update()
00204   if pad.GetLogy() and argv.count('maxLog') > 0:
00205     maxLog = options.maxLog
00206   else:
00207     maxLog = -1
00208   min, max = findRange(hists, -1, maxLog)
00209   if pad.GetLogy():
00210     if min == 0:
00211       min = 0.001
00212     if max < 2:
00213       max = 2. #prefere fixed range for easy comparison
00214   else:
00215     if min < 0.7:
00216       min = 0. #start from zero if possible
00217     if max <= 1.1 and max > 0.7:
00218       max = 1.2 #prefere fixed range for easy comparison
00219   hists[0].SetAxisRange(min, max, "Y")

def MultipleCompare::optimizeRangeSubPad (   argv,
  hists 
)

Definition at line 220 of file MultipleCompare.py.

00221                                     :
00222   min = -1
00223   max = -1
00224   if argv.count('minDiv') > 0:
00225     min = options.minDiv
00226   if argv.count('maxDiv') > 0:
00227     max = options.maxDiv
00228   min, max = findRange(hists, min, max)
00229   if max > 2:
00230     max = 2 #maximal bound
00231   hists[0].SetAxisRange(min, max, "Y")
00232 

def MultipleCompare::Rebin (   tfile,
  histoPath,
  rebinVal 
)

Definition at line 161 of file MultipleCompare.py.

00162                                      :
00163     parents = FindParents(histoPath)
00164     num = tfile.Get(parents[0])
00165     if type(num) != TH1F:
00166         print 'Looking for '+num
00167         print 'Plot now found! What the hell are you doing? Exiting...'
00168         sys.exit()
00169     denSingle = tfile.Get(parents[1])
00170     if type(denSingle) != TH1F:
00171         print 'Looking for '+denSingle
00172         print 'Plot now found! What the hell are you doing? Exiting...'
00173         sys.exit()
00174     num.Rebin(rebinVal)
00175     den = denSingle.Rebin(rebinVal,'denClone')
00176     retVal = num.Clone(histoPath+'Rebin%s'%rebinVal)
00177     #print 'Num : ' + parents[0]
00178     #print 'Den : ' +parents[1]
00179     #print "NumBins: %s DenBins: %s" % (num.GetNbinsX(), den.GetNbinsX() )
00180     retVal.Divide(num,den,1,1,'B')
00181     return retVal


Variable Documentation

string MultipleCompare::__author__ = "Mauro Verzetti (mauro.verzetti@cern.ch)"

Definition at line 12 of file MultipleCompare.py.

Initial value:
00001 """Script to plot the content of a Validation .root file and compare it to a different file:\n\n
00002 Usage: MultipleCompare.py -T testFile -R refFile [options] [search strings that you want to apply '*' is supported as special character]"""

Definition at line 13 of file MultipleCompare.py.