Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-11-26 02:34:39

0001 #! /usr/bin/env python3
0002 
0003 from builtins import range
0004 import FWCore.ParameterSet.Config as cms
0005 import sys
0006 import os
0007 import math
0008 import re
0009 import Validation.RecoTau.RecoTauValidation_cfi as validation
0010 from optparse import OptionParser
0011 from ROOT import gStyle, TDirectory, TDirectoryFile, TLatex, TH1F, TLegend, TPaveText, TPad
0012 
0013 __author__  = "Mauro Verzetti (mauro.verzetti@cern.ch) and Lucia Perrini (lucia.perrini@cern.ch)"
0014 __doc__ = """Script to plot the content of a Validation .root file and compare it to a different file:\n\n
0015 Usage: MultipleCompare.py -T testFile -R refFile [options] [search strings that you want to apply '*' is supported as special character]"""
0016 
0017 def LoadCommandlineOptions(argv):
0018   sys.argv = argv
0019   parser = OptionParser(description=__doc__)
0020   parser.add_option('--myhelp',metavar='', action="store_true",help='prints this output message',dest='help',default = False)
0021   parser.add_option('--TestFile','-T',metavar='testFile', type=str,help='Sets the test file',dest='test',default = '')
0022   parser.add_option('--RefFile','-R',metavar='refFile', type=str,help='Sets the reference file',dest='ref',default = None)
0023   parser.add_option('--output','-o',metavar='outputFile', type=str,help='Sets the output file',dest='out',default = 'MultipleCompare.png')
0024   parser.add_option('--logScaleY',action="store_true", dest="logScaleY", default=False, help="Sets the log scale in the plot (Y axis)")
0025   parser.add_option('--logScaleX',action="store_true", dest="logScaleX", default=False, help="Sets the log scale in the plot (X axis)")
0026   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)")
0027   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)
0028   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)
0029   parser.add_option('--sampleLabel','-s',metavar='sampleLabel', type=str,help='Sets the label to indicate the sample used',dest='sampleLabel',default = None)
0030   parser.add_option('--maxLogX',metavar='number', type=float,help='Sets the maximum of the scale in log scale both in the main and in the sub pad (requires --logScale or -f to work)',dest='maxLogX',default = 100)
0031   parser.add_option('--minLogX',metavar='number', type=float,help='Sets the minimum of the scale in log scale (requires --logScale or -f to work)',dest='minLogX',default = 0.001)
0032   parser.add_option('--minLogY',metavar='number', type=float,help='Sets the minimum of the scale in log scale (requires --logScale or -f to work)',dest='minLogY',default = 0.0001)
0033   parser.add_option('--maxLogY',metavar='number', type=float,help='Sets the maximum of the scale in log scale (requires --logScale or -f to work)',dest='maxLogY',default = 3)
0034   parser.add_option('--minYR',metavar='number', type=float,help='Sets the minimum of the scale in sub pad',dest='minYR',default = 0)
0035   parser.add_option('--maxYR',metavar='number', type=float,help='Sets the maximum of the scale in sub pad',dest='maxYR',default = 1.2)
0036 #  parser.add_option('--minDivY',metavar='number', type=float,help='Sets the minimum of the scale in the ratio pad',dest='minDivY',default = 0.)
0037 #  parser.add_option('--maxDivY',metavar='number', type=float,help='Sets the maximum of the scale in the ratio pad',dest='maxDivY',default = 2)
0038 #  parser.add_option('--minDivX',metavar='number', type=float,help='Sets the minimum of the scale in the ratio pad',dest='minDivX',default = 0.)
0039 #  parser.add_option('--maxDivX',metavar='number', type=float,help='Sets the maximum of the scale in the ratio pad',dest='maxDivX',default = 2)
0040   parser.add_option('--logDiv',action="store_true", dest="logDiv", default=False, help="Sets the log scale in the plot")
0041   parser.add_option('--normalize',action="store_true", dest="normalize", default=False, help="plot normalized")
0042   parser.add_option('--maxRange',metavar='number',type=float, dest="maxRange", default=1.6, help="Sets the maximum range in linear plots")
0043   parser.add_option('--maxXaxis',metavar='number',type=float, dest="maxXaxis", default=800, help="Sets the maximum range on x axis in the main pad")
0044   parser.add_option('--minXaxis',metavar='number',type=float,help="Sets the minimum range on x axis in the main pad",dest="minXaxis", default=-3)
0045   parser.add_option('--maxYaxis',metavar='number',type=float, dest="maxYaxis", default=2, help="Sets the maximum range on Y axis in the main pad")
0046   parser.add_option('--minYaxis',metavar='number',type=float, dest="minYaxis", default=0, help="Sets the minimum range on Y axis in the main pad")
0047   parser.add_option('--rebin', dest="rebin", type=int, default=-1, help="Sets the rebinning scale")
0048   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)
0049   #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 python3 to use all the strings before a new option, thus moving this from option to argument (but may be empty)
0050 
0051   (options,toPlot) = parser.parse_args()
0052   if options.help:
0053     parser.print_help()
0054     sys.exit(0)
0055   return [options, toPlot]
0056 
0057 def GetContent(dir):
0058     tempList = dir.GetListOfKeys()
0059     retList = []
0060     for it in range(0,tempList.GetSize()):
0061        retList.append(tempList.At(it).ReadObj())
0062     return retList
0063 
0064 def MapDirStructure( directory, dirName, objectList ):
0065     dirContent = GetContent(directory)
0066     for entry in dirContent:
0067         if isinstance(entry, TDirectory) or isinstance(entry, TDirectoryFile):
0068             subdirName = os.path.join(dirName,entry.GetName())
0069             MapDirStructure(entry, subdirName,objectList)
0070         else:
0071             pathname = os.path.join(dirName,entry.GetName())
0072             objectList.append(pathname)
0073 
0074 def Match(required, got):
0075     for part in required.split('*'):
0076         if got.find(part) == -1:
0077             return False
0078     return True
0079 
0080 def Divide(hNum,hDen):
0081     ret = hNum.Clone('Division')
0082     ret.GetYaxis().SetTitle('Ratio')
0083     for binI in range(hNum.GetNbinsX()+1):
0084         denVal = hDen.GetBinContent(binI)
0085         denErr = hDen.GetBinError(binI)
0086         numErr = hNum.GetBinError(binI)
0087         numVal = hNum.GetBinContent(binI)
0088         if denVal == 0:
0089             ret.SetBinContent(binI,0)
0090             ret.SetBinError(binI,0)
0091         else:
0092             ret.SetBinContent(binI,numVal/denVal)
0093             if numVal==0:
0094                 ret.SetBinError(binI,1)
0095             else:
0096                 ret.SetBinError(binI,(numVal/denVal)*math.sqrt(math.pow(numErr/numVal,2) + math.pow(denErr/denVal,2) ) )
0097     return ret
0098 
0099 def DetermineHistType(name):
0100   #automatically derive all plot types in the future?
0101   type = ''
0102   label = ''
0103   prefix = ''
0104   #assuming plots name like: tauType_plotType_xAxis or tauType_plotType_selection
0105   matches = re.match(r'.*/(.*)_(.*)_(.*)', name)
0106   if matches:
0107     prefix = matches.group(1)
0108     label = matches.group(3)
0109     knowntypes = (['pTRatio','SumPt','Size'])
0110     for knowntype in knowntypes:
0111       if matches.group(2) == knowntype:
0112         type = knowntype
0113     if not type:  #there are plots labelled ..._vs_...
0114       type = 'Eff'
0115   else:
0116     type = 'Eff'
0117 
0118   prefixParts = prefix.partition('Discrimination')
0119   if prefixParts[2] != '':
0120     prefix = prefixParts[2]
0121     prefixParts = prefix.partition('By')
0122     if prefixParts[2] != '':
0123       prefix = prefixParts[2]
0124 
0125   #print 'type is ' + type
0126   return [type, label, prefix]
0127 
0128 def DrawTitle(text):
0129     title = TLatex()
0130     title.SetNDC()
0131     title.SetTextAlign(12)#3*10=right,3*1=top
0132     title.SetTextSize(.035) 
0133     leftMargin = gStyle.GetPadLeftMargin()
0134     topMargin = 1 - 0.5*gStyle.GetPadTopMargin()
0135     title.DrawLatex(leftMargin, topMargin, text)
0136 
0137 def DrawBranding(options, label=''):
0138   if options.branding != None or label != '':
0139     text = TLatex()
0140     text.SetNDC();
0141     text.SetTextAlign(11)#3*10=right,3*1=top
0142     text.SetTextSize(.025)
0143     text.SetTextColor(13)
0144     if options.out.find(".eps")!=-1:
0145       text.SetTextAngle(-91.0)#eps BUG
0146     else:
0147       text.SetTextAngle(-90.0)
0148     rightMargin = 1 - gStyle.GetPadRightMargin()
0149     topMargin = 1 - gStyle.GetPadTopMargin()
0150     if label!='':
0151       label += ': '
0152     text.DrawLatex(rightMargin+.01, topMargin+0.025, label+options.branding);
0153 
0154 
0155 def FindParents(histoPath):
0156     root = histoPath[:histoPath.find('_')]
0157     par = histoPath[histoPath.find('Eff')+3:]
0158     validationPlots = validation.proc.efficiencies.plots._Parameterizable__parameterNames
0159     found =0
0160     num = ''
0161     den = ''
0162     for efficiency in validationPlots:
0163         effpset = getattr(validation.proc.efficiencies.plots,efficiency)
0164         effName = effpset.efficiency.value()
0165         effNameCut = effName[effName.find('_'):effName.find('#')]
0166         if effNameCut in histoPath:
0167             if found == 1:
0168                 print('More than one pair of parents found for ' + histopath + ':')
0169                 assert(False)
0170             num = root + effpset.numerator.value()[effName.find('_'):].replace('#PAR#',par)
0171             den = root + effpset.denominator.value()[effName.find('_'):].replace('#PAR#',par)
0172             found += 1
0173     return [num,den]
0174 
0175 def Rebin(tfile, histoPath, rebinVal):
0176     parents = FindParents(histoPath)
0177     num = tfile.Get(parents[0])
0178     if not isinstance(num, TH1F):
0179         print('Looking for ' + num)
0180         print('Plot now found! What the hell are you doing? Exiting...')
0181         sys.exit()
0182     denSingle = tfile.Get(parents[1])
0183     if not isinstance(denSingle, TH1F):
0184         print('Looking for '+denSingle)
0185         print('Plot now found! What the hell are you doing? Exiting...')
0186         sys.exit()
0187     num.Rebin(rebinVal)
0188     den = denSingle.Rebin(rebinVal,'denClone')
0189     retVal = num.Clone(histoPath+'Rebin%s'%rebinVal)
0190     #print 'Num : ' + parents[0]
0191     #print 'Den : ' +parents[1]
0192     #print "NumBins: %s DenBins: %s" % (num.GetNbinsX(), den.GetNbinsX() )
0193     retVal.Divide(num,den,1,1,'B')
0194     return retVal
0195 
0196 def findRange(hists, min0=-1, max0=-1):
0197   if len(hists) < 1:
0198     return
0199   #auto ranges if no user value provided
0200   min = min0
0201   max = max0
0202   if min0 == -1 or max0 == -1:
0203     for hist in hists:
0204       if min0 == -1:
0205         #Divide() sets bin to zero if division not possible. Ignore these bins.
0206         minTmp = getMinimumIncludingErrors(hist)
0207         if minTmp < min or min == -1:
0208           min = minTmp
0209       if max0 == -1:
0210         maxTmp = getMaximumIncludingErrors(hist)
0211         if maxTmp > max or max == -1:
0212           max = maxTmp
0213   return [min, max]
0214 
0215 def optimizeRangeMainPad(argv, pad, hists, maxLogX_, minX_, maxX_, maxLogY_, minY_, maxY_):
0216   pad.Update()
0217   if pad.GetLogy():
0218     if maxLogY_ > 0:
0219       maxLogY = maxLogY_
0220     else:
0221       maxLogY = -1
0222     minY, maxY = findRange(hists, -1, maxLogY)
0223   else:
0224     minY, maxY = findRange(hists, minY_, maxY_)
0225 
0226   if pad.GetLogy():
0227     if minY == 0:
0228       minY = 0.001
0229   else:
0230     if minY < 0.7:
0231       minY = minY #start from zero if possible
0232     if maxY <= 1.1 and maxY > 0.7:
0233       maxY = 1.2 #prefere fixed range for easy comparison
0234   hists[0].SetAxisRange(minY, maxY, "Y")
0235 
0236   if pad.GetLogx():
0237     if maxLogX_ > 0:
0238       maxLogX = maxLogX_
0239     else:
0240       maxLogX = -1
0241     minX, maxX = findRange(hists, -1, maxLogX)
0242   else:
0243     minX, maxX = findRange(hists, minX_, maxX_)
0244 
0245   if pad.GetLogx():
0246     if minX == 0:
0247       minX = 0.001
0248   else:
0249     if minX < 0.7:
0250       minX = minX #start from zero if possible
0251     if maxX <= 1.1 and maxX > 0.7:
0252       maxX = 1.2 #prefere fixed range for easy comparison
0253   hists[0].SetAxisRange(minX, maxX, "X")
0254 
0255 def optimizeRangeSubPad(argv, pad, hists, maxLogX_, minX_, maxX_, minYRatio_, maxYRatio_):
0256   pad.Update()
0257   if pad.GetLogx():
0258     if maxLogX_ > 0:
0259       maxLogX = maxLogX_
0260     else:
0261       maxLogX = -1
0262     minX, maxX = findRange(hists, -1, maxLogX)
0263   else:
0264     minX, maxX = findRange(hists, minX_, maxX_)
0265   if pad.GetLogx():
0266     if minX == 0:
0267       minX = 0.001
0268   else:
0269     if minX < 0.7:
0270       minX = minX #start from zero if possible
0271     if maxX <= 1.1 and maxX > 0.7:
0272       maxX = 1.2 #prefere fixed range for easy comparison
0273   hists[0].SetAxisRange(minX, maxX, "X")
0274 
0275   min = -1
0276   max = -1
0277   if minYRatio_ > 0:
0278     min = minYRatio_
0279   if maxYRatio_ > 0:
0280     max = maxYRatio_
0281   min, max = findRange(hists, min, max)
0282   if max > 2:
0283     max = 2 #maximal bound
0284   hists[0].SetAxisRange(min, max, "Y")
0285 
0286 def getMaximumIncludingErrors(hist):
0287 #find maximum considering also the errors
0288   distance = 1.
0289   max = -1
0290   pos = 0
0291   for i in range(1, hist.GetNbinsX()):
0292     if hist.GetBinContent(i) > max:#ignore errors here
0293       max = hist.GetBinContent(i)
0294       pos = i
0295   return max + distance*hist.GetBinError(pos)
0296 
0297 def getMinimumIncludingErrors(hist):
0298   #find minimum considering also the errors
0299   #ignoring zero bins
0300   distance = 1.
0301   min = -1
0302   pos = 0
0303   for i in range(1, hist.GetNbinsX()):
0304     if hist.GetBinContent(i)<=0.:#ignore errors here
0305       continue
0306     if hist.GetBinContent(i) < min or min==-1:
0307       min = hist.GetBinContent(i)
0308       pos = i
0309       if min < 0:
0310         min = 0
0311   return min - distance*hist.GetBinError(pos)
0312 
0313 
0314 def main(argv=None):
0315   if argv is None:
0316     argv = sys.argv
0317 
0318   options, toPlot = LoadCommandlineOptions(argv)
0319 
0320   gROOT.SetStyle('Plain')
0321   gROOT.SetBatch()
0322   gStyle.SetPalette(1)
0323   gStyle.SetOptStat(0)
0324   gStyle.SetPadGridX(True)
0325   gStyle.SetPadGridY(True)
0326   gStyle.SetOptTitle(0)
0327   gStyle.SetPadTopMargin(0.1)
0328   gStyle.SetPadBottomMargin(0.1)
0329   gStyle.SetPadLeftMargin(0.13)
0330   gStyle.SetPadRightMargin(0.07)
0331 
0332 
0333   testFile = TFile(options.test)
0334   refFile = None
0335   if options.ref != None:
0336     refFile = TFile(options.ref)
0337 
0338   #Takes the position of all plots that were produced
0339   plotList = []
0340   MapDirStructure( testFile,'',plotList)
0341 
0342   histoList = []
0343   for plot in toPlot:
0344     for path in plotList:
0345         if Match(plot.lower(),path.lower()):
0346             histoList.append(path)
0347 
0348 #  print "options: ",options
0349 #  print "toPlot: ",toPlot
0350   print(histoList)
0351 
0352   if len(histoList)<1:
0353     print('\tError: Please specify at least one histogram.')
0354     if len(toPlot)>0:
0355       print('Check your plot list:', toPlot)
0356     sys.exit()
0357 
0358 
0359   #WARNING: For now the hist type is assumed to be constant over all histos.
0360   histType, label, prefix = DetermineHistType(histoList[0])
0361   #decide whether or not to scale to an integral of 1
0362   #should usually not be used most plot types. they are already normalized.
0363   scaleToIntegral = False
0364   if options.normalize:
0365     scaleToIntegral = True
0366 
0367   ylabel = 'Efficiency'
0368 
0369   if options.fakeRate:
0370     ylabel = 'Fake rate'
0371 
0372   drawStats = False
0373   if histType=='pTRatio' and len(histoList)<3:
0374     drawStats = True
0375 
0376   #legend = TLegend(0.50,0.73,0.50+0.37,1)
0377   x1 = 0.33
0378   x2 = 1-gStyle.GetPadRightMargin()
0379   y2 = 1-gStyle.GetPadTopMargin()
0380   lineHeight = .055
0381   if len(histoList) == 1:
0382     lineHeight = .05
0383   y1 = y2 - lineHeight*len(histoList)
0384   legend = TLegend(x1,y1,x2,y2)
0385   legend.SetHeader(label)
0386   legend.SetFillColor(0)
0387   legend.SetTextSize(0.032)
0388   if drawStats:
0389     y2 = y1
0390     y1 = y2 - .07*len(histoList)
0391     statsBox = TPaveText(x1,y1,x2,y2,"NDC")
0392     statsBox.SetFillColor(0)
0393     statsBox.SetTextAlign(12)#3*10=right,3*1=top
0394     statsBox.SetMargin(0.05)
0395     statsBox.SetBorderSize(1)
0396 
0397 
0398   canvas = TCanvas('MultiPlot','MultiPlot',validation.standardDrawingStuff.canvasSizeX.value(),832)
0399   effPad = TPad('effPad','effPad',0.01,0.35,0.99,0.99)#0,0.25,1.,1.,0,0)
0400   effPad.SetBottomMargin(0.0)#0.1)
0401   #effPad.SetTopMargin(0.1)
0402   #effPad.SetLeftMargin(0.13)
0403   #effPad.SetRightMargin(0.07)
0404   effPad.Draw()
0405   header = ''
0406   if options.sampleLabel != None:
0407     header += 'Sample: '+options.sampleLabel
0408   if options.testLabel != None:
0409     header += ' Dots: '+options.testLabel
0410   if options.refLabel != None:
0411     header += ' Line: '+options.refLabel
0412   DrawTitle(header)
0413   DrawBranding(options)
0414   diffPad = TPad('diffPad','diffPad',0.01,0.01,0.99,0.32)#0.,0.,1,.25,0,0)
0415   diffPad.SetTopMargin(0.00);
0416   diffPad.SetBottomMargin(0.30);
0417   diffPad.Draw()
0418   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]
0419   first = True
0420   divHistos = []
0421   statTemplate = '%s Mean: %.3f RMS: %.3f'
0422   testHs = []
0423   refHs = []
0424   for histoPath,color in zip(histoList,colors):
0425     if(options.rebin == -1):
0426       testH = testFile.Get(histoPath)
0427     else:
0428         testH = Rebin(testFile,histoPath,options.rebin)
0429     if not isinstance(testH, TH1F):
0430         print('Looking for '+histoPath)
0431         print('Test plot now found! What the hell are you doing? Exiting...')
0432         sys.exit()
0433     testHs.append(testH)
0434     xAx = histoPath[histoPath.find('Eff')+len('Eff'):]
0435     effPad.cd()
0436     if not testH.GetXaxis().GetTitle():  #only overwrite label if none already existing
0437       if hasattr(validation.standardDrawingStuff.xAxes,xAx):
0438         testH.GetXaxis().SetTitle( getattr(validation.standardDrawingStuff.xAxes,xAx).xAxisTitle.value())
0439     if not testH.GetYaxis().GetTitle():  #only overwrite label if none already existing
0440       testH.GetYaxis().SetTitle(ylabel)
0441     if label!='':
0442       testH.GetXaxis().SetTitle(label+': '+testH.GetXaxis().GetTitle())
0443     testH.GetXaxis().SetTitleOffset(1.1)
0444     testH.GetXaxis().SetRangeUser(options.minXaxis,options.maxXaxis)
0445     testH.GetYaxis().SetTitleOffset(1.1)
0446     #testH.GetYaxis().SetTitleSize(0.08)
0447     #testH.GetYaxis().CenterTitle()
0448     testH.SetMarkerSize(1)
0449     testH.SetMarkerStyle(20)
0450     testH.SetMarkerColor(color)
0451     if histType == 'Eff':
0452       legend.AddEntry(testH,histoPath[histoPath.rfind('/')+1:histoPath.find(histType)],'p')
0453     else:
0454       legend.AddEntry(testH,DetermineHistType(histoPath)[2],'p')
0455     if drawStats:
0456         text = statsBox.AddText(statTemplate % ('Dots',testH.GetMean(), testH.GetRMS()) )
0457         text.SetTextColor(color)
0458     if first:
0459         first = False
0460         if options.logScaleY:
0461             effPad.SetLogy()
0462         if options.logScaleX:
0463             effPad.SetLogx()
0464             diffPad.SetLogx()
0465         if scaleToIntegral:
0466           if testH.GetEntries() > 0:
0467             if not testH.GetSumw2N():
0468               testH.Sumw2()
0469               testH.DrawNormalized('ex0 P')
0470             else:
0471               print("--> Warning! You tried to normalize a histogram which seems to be already scaled properly. Draw it unscaled.")
0472               scaleToIntegral = False
0473               testH.Draw('ex0')
0474         else:
0475           testH.Draw('ex0')
0476     else:
0477         if scaleToIntegral:
0478           if testH.GetEntries() > 0:
0479             testH.DrawNormalized('same p')
0480         else:
0481             testH.Draw('same ex0 l')
0482     if refFile == None:
0483         continue
0484     if(options.rebin == -1):
0485         refH = refFile.Get(histoPath)
0486     else:
0487         refH = Rebin(refFile,histoPath,options.rebin)
0488     if not isinstance(refH, TH1F):
0489         continue
0490     refHs.append(refH)
0491     refH.SetLineColor(color)
0492     refH.SetLineWidth(1)
0493     if scaleToIntegral:
0494       if testH.GetEntries() > 0:
0495         refH.DrawNormalized('same hist')
0496     else:
0497         refH.DrawCopy('same hist')
0498     if drawStats:
0499       text = statsBox.AddText(statTemplate % ('Line',refH.GetMean(), refH.GetRMS()) )
0500       text.SetTextColor(color)
0501     #refH.SetFillColor(color)
0502     #refH.SetFillStyle(3001)
0503     if scaleToIntegral:
0504         entries = testH.GetEntries()
0505         if entries > 0:
0506           testH.Scale(1./entries)
0507         entries = refH.GetEntries()
0508         refH.Sumw2()
0509         if entries > 0:
0510           refH.Scale(1./entries)
0511     refH.Draw('same hist')
0512     divHistos.append(Divide(testH,refH))
0513 
0514     if options.maxLogY > 0:
0515        maxlY=options.maxLogY
0516     if options.maxLogX > 0:
0517        maxlX=options.maxLogX
0518 
0519   tmpHists = []
0520   tmpHists.extend(testHs)
0521   tmpHists.extend(refHs)
0522   optimizeRangeMainPad(argv, effPad, tmpHists, maxlX, options.minXaxis, options.maxXaxis, maxlY, options.minYaxis, options.maxYaxis)
0523 
0524   firstD = True
0525   if refFile != None:
0526     for histo,color in zip(divHistos,colors):
0527       diffPad.cd()
0528       histo.SetMarkerSize(1)
0529       histo.SetMarkerStyle(20)
0530       histo.SetMarkerColor(color)
0531       histo.GetYaxis().SetLabelSize(0.07)
0532       histo.GetYaxis().SetTitleOffset(0.75)
0533       histo.GetYaxis().SetTitleSize(0.08)
0534       histo.GetXaxis().SetLabelSize(0.08)
0535       histo.GetXaxis().SetTitleSize(0.08)
0536       #histo.GetYaxis().CenterTitle()
0537 
0538 
0539       if firstD:
0540         histo.Draw('ex0')
0541         firstD = False
0542       else:
0543         histo.Draw('same ex0')
0544         diffPad.Update()
0545 
0546     if options.maxLogX > 0:
0547       maxlX=options.maxLogX
0548     optimizeRangeSubPad(argv, diffPad, divHistos, maxlX, options.minXaxis, options.maxXaxis, options.minYR, options.maxYR)
0549 
0550   effPad.cd()
0551   legend.Draw()
0552 
0553   if drawStats:
0554     statsBox.Draw()
0555 
0556   canvas.Print(options.out)
0557 
0558 
0559 if __name__ == '__main__':
0560   sys.exit(main())