Пример #1
0
def GetBinText(bin):
    #if bin == "Inclusive":
    #    return "combined"
    #else:
    #    return "bin-" + str(bin)
    if bin == "0":
        return "p_{T} < 80 GeV/c, |#eta| < 0.8"
    elif bin == "1":
        return "p_{T} = 80-200 GeV/c, |#eta| < 0.8"
    elif bin == "2":
        return "p_{T} > 200 GeV/c, |#eta| < 0.8"
    elif bin == "3":
        return "p_{T} < 80 GeV/c, |#eta| = 0.8-1.6"
    elif bin == "4":
        return "p_{T} = 80-200 GeV/c, |#eta| = 0.8-1.6"
    elif bin == "5":
        return "p_{T} > 200 GeV/c, |#eta| = 0.8-1.6"
    elif bin == "6":
        return "p_{T} < 80 GeV/c, |#eta| > 1.6"
    elif bin == "7":
        return "p_{T} = 80-200 GeV/c, |#eta| > 1.6"
    elif bin == "8":
        return "p_{T} > 200 GeV/c, |#eta| > 1.6"
    elif bin == "Inclusive":
        return "combined"
    else:
        raise Exception(ShellStyles.ErrorStyle() + "Unexpected bin %s" %
                        (bin) + ShellStyles.NormalStyle())
def getNormFactorFileList(dirName, fileBaseName):
    scriptList = []

    # For-loop: All items (files/dir) in directory
    for item in os.listdir(dirName):
        fullPath = os.path.join(dirName, item)

        # Skip directories
        if os.path.isdir(fullPath):
            continue

        # Find files matching the script "Base" name (without moduleInfoStrings)
        if item.startswith((fileBaseName).replace("%s.py", "")):
            if item.endswith(".py"):
                scriptList.append(item)

    if len(scriptList) < 1:
        msg = "ERROR! Found no normalization info files under dir %s. Did you generate them?" % dirName
        raise Exception(ShellStyles.ErrorStyle() + msg +
                        ShellStyles.NormalStyle())
    else:
        msg = "Found %s norm-factor file(s):\n\t%s" % (
            len(scriptList), "\n\t".join(
                os.path.join([os.path.join(dirName, s) for s in scriptList])))
        Verbose(ShellStyles.NoteLabel() + msg, True)
    return scriptList
    def getDataDrivenQCDHistoForSplittedBin(self, binIndex):
        '''
        Return the sum of data-ewk in a given phase space split bin
        
        at bin-index 0 you have the inclusive histogram!
        '''
        if binIndex >= len(self._dataList):
            # FIXME: New addition to fix "optionUseInclusiveNorm" functionality (24-Mar-2018). Should not affect binned result!
            if self._optionUseInclusiveNorm:  #new
                h = aux.Clone(self._dataList[0])  #new
                newName = h.GetName() + "_DataDriven"  #new
                h.SetName(newName)  #new
                return h  #new
            msg = "Requested bin index %d out of range (0-%d)!" % (
                binIndex, len(self._dataList))
            raise Exception(ShellStyles.ErrorStyle() + msg,
                            ShellStyles.NormalStyle())

        # Clone the Data histos
        h = aux.Clone(self._dataList[binIndex])
        newName = h.GetName() + "_DataDriven"
        h.SetName(newName)
        self.Verbose(
            "Cloned histo %s from histo %s" %
            (h.GetName(), self._dataList[0].GetName()), True)

        # Subtract the EWK histos
        self.Verbose(
            "Subtracting histo %s from histo %s (bin=%i)" %
            (self._ewkList[binIndex].GetName(), h.GetName(), binIndex), False)
        h.Add(self._ewkList[binIndex], -1.0)
        return h
Пример #4
0
def IsTH1(h, raiseExcept=False):
    if not isinstance(h, ROOT.TH1):
        msg = "Expected object of type ROOT.TH1, got \"%s\" instead" % (type(h))
        if raiseExcept:
            raise Exception(ShellStyles.ErrorStyle() + msg + ShellStyles.NormalStyle())
        return False
    else:
        return True
Пример #5
0
 def _getAnalysisType(self, analysis):
     myAnalyses = ["HToTauNu", "HToTB"]
     if analysis not in myAnalyses:
         msg = "Unsupported analysis \"%s\". Please select one of the following: %s" % (analysis, ", ".join(myAnalyses))
         raise Exception(ShellStyles.ErrorStyle() + msg + ShellStyles.NormalStyle() )
     else:
         self.Print("Analysis type set to %s" % (sh_Note + analysis + sh_Normal), True)
         return analysis
    def writeModuleToRootFile(self, rootfile):

        # Create module directory
        rootfile.cd("/")
        myModuleDir = rootfile.mkdir(self._moduleName)
        # Save shape information
        for h in self._shapes:
            h.SetDirectory(myModuleDir)
        # Save data-driven control plots
        myDDPlotsDirName = "ForDataDrivenCtrlPlots"
        myDDPlotsDir = myModuleDir.mkdir(myDDPlotsDirName)
        for h in self._dataDrivenControlPlots:
            h.SetDirectory(myDDPlotsDir)

        # Save counter histogram
        myCounterDir = myModuleDir.mkdir("counters")
        myWeightedCounterDir = myCounterDir.mkdir("weighted")
        self._hCounters = ROOT.TH1F("counter", "counter", len(self._counters),
                                    0, len(self._counters))
        i = 1
        for key in self._counters.keys():
            self._hCounters.GetXaxis().SetBinLabel(i, key)
            i += 1
            self._hCounters.SetBinContent(i, self._counters[key])
            self._hCounters.SetBinError(i, self._counterUncertainties[key])
        self._hCounters.SetDirectory(myWeightedCounterDir)

        # Save splittedBinInfo
        hType = str(type(self._hSplittedBinInfo)).lower()
        if "none" not in hType:
            self._hSplittedBinInfo.SetDirectory(myModuleDir)
        else:
            msg = "WARNING! Unexpected problem with splitted bin info histogram. Type is %s" % (
                hType)
            self.Print(
                ShellStyles.ErrorStyle() + msg + ShellStyles.NormalStyle(),
                True)

        # Save parameter set, code version and data version
        #myModuleDir.Add(self._psetInfo)

        # Create config info for the module
        myConfigInfoDir = myModuleDir.mkdir("configInfo")
        self._hConfigInfo = ROOT.TH1F(
            "configinfo", "configinfo", 2, 0, 2
        )  # Have to store the histogram to keep it alive for writing        self._hConfigInfo.GetXaxis().SetBinLabel(1,"control")
        self._hConfigInfo.GetXaxis().SetBinLabel(1, "control")
        self._hConfigInfo.SetBinContent(1, 1)
        #self._hConfigInfo.GetXaxis().SetBinLabel(2,"energy")
        #self._hConfigInfo.SetBinContent(2, self._energy)
        self._hConfigInfo.GetXaxis().SetBinLabel(2, "luminosity")
        self._hConfigInfo.SetBinContent(2, self._luminosity)
        self._hConfigInfo.SetDirectory(myConfigInfoDir)
        myConfigInfoDir.Add(self._dataVersion)
        #myConfigInfoDir.Add(self._codeVersion)
        #.SetDirectory(rootfile)
        #self._codeVersion.SetDirectory(rootfile)
        return
Пример #7
0
 def _getAnalysisType(self, analysis):
     myAnalyses = ["HToTauNu", "HToTB", "HToHW", "HToHW_background"]
     if analysis not in myAnalyses:
         msg = "Unsupported analysis \"%s\". Please select one of the following: %s" % (
             analysis, ", ".join(myAnalyses))
         raise Exception(ShellStyles.ErrorStyle() + msg +
                         ShellStyles.NormalStyle())
     else:
         return analysis
Пример #8
0
    def __init__(self, dataPath, ewkPath, dsetMgr, luminosity, moduleInfoString, normFactors,
                 optionDoFakeBNormalisationSyst=True, normDataSrc=None, normEWKSrc=None,
                 optionUseInclusiveNorm=False, keyList=[], verbose=False):
        self._verbose = verbose
        self._shapePlots = []
        self._shapePlotLabels = []
        self._QCDNormalizationSystPlots = []
        self._QCDNormalizationSystPlotLabels = []
        self._moduleInfoString = moduleInfoString
        self._useInclusiveNorm = optionUseInclusiveNorm
        if len(normFactors.keys()) == 1 and normFactors.keys()[0] == "Inclusive":
            self._useInclusiveNorm = True
        self._histoPathsData= self._GetHistoPaths(dsetMgr, "Data", dataPath, keyList)
        if ewkPath == dataPath:
            self._histoPathsEWK = self._histoPathsData
        else:
            self._histoPathsEWK  = self._GetHistoPaths(dsetMgr, "EWK" , ewkPath , keyList)
        
        # Sanity check
        if len(self._histoPathsEWK) != len(self._histoPathsData):
            msg = "List of histograms for EWK does not match in size that of Data"
            raise Exception(ShellStyles.ErrorLabel() + msg + ShellStyles.NormalStyle())
            
        # For-Loop: All plots to consider
        for i, plotName in enumerate(self._histoPathsData, 1):

            # Inform user of progress
            msg = "{:<9} {:>3} {:<1} {:<3} {:<80}".format("Histogram", "%i" % i, "/", "%s:" % (len(self._histoPathsData)), os.path.join(dataPath, plotName) )
            self.PrintFlushed(ShellStyles.SuccessStyle() + msg + ShellStyles.NormalStyle(), False)

            if "JetEtaPhi_AfterAllSelections" in plotName:
                continue 

            # Ensure that histograms exist && pass other sanity checks
            dataOk = self._sanityChecks(dsetMgr, dataPath, plotName) 
            ewkOk  = self._sanityChecks(dsetMgr, ewkPath , plotName)

            if dataOk*ewkOk == False:
                self.Print(ShellStyles.ErrorStyle() + msg + ShellStyles.NormalStyle(), i==1)
                continue
            
            self.Verbose("Obtaining shape plots (the returned object is not owned)", True)
            myShapeHisto = self._obtainShapeHistograms(i, dataPath, ewkPath, dsetMgr, plotName, luminosity, normFactors)

            # Obtain plots for systematics coming from invariant mass shape difference
            if optionDoFakeBNormalisationSyst:
                if isinstance(myShapeHisto, ROOT.TH2):
                    msg = "Skipping invariant mass shape uncertainty because histogram has more than 1 dimensions!"
                    self.Print(ShellStyles.WarningLabel() + msg, True)
                else:
                    self._obtainQCDNormalizationSystHistograms(myShapeHisto, dsetMgr, plotName, luminosity, normDataSrc, normEWKSrc) #iro: fixme (missing plots)
            
        msg = "Obtaining final shape from data path %s" % (ShellStyles.NoteStyle() + dataPath + ShellStyles.NormalStyle())
        self.Verbose(msg, True)
        return
def getTransferFactorsSrcFilename(dirName, fileName):
    src = os.path.join(dirName, fileName)
    if not os.path.exists(src):
        msg = "Normalisation factors ('%s') not found!\nRun script \"./getABCD_TF.py\" to auto-generate the transfer factors (TFs) file." % src
        raise Exception(ShellStyles.ErrorStyle() + msg +
                        ShellStyles.NormalStyle())
    else:
        Print(
            "Importing transfer factors (TFs) from file %s" %
            (ShellStyles.NoteStyle() + os.path.basename(src) +
             ShellStyles.NormalStyle()), True)
    return src
Пример #10
0
 def getListOfSystematics(self):
     if self._analysisType == "HToTauNu":
         return self.getSystematicsForHToTauNu()
     elif self._analysisType == "HToTB":
         return self.getSystematicsForHToTB()
     elif self._analysisType == "HToHW":
         return self.getSystematicsForHToHW()
     elif self._analysisType == "HToHW_background":
         return self.getSystematicsForHToHW_background()
     else:
         raise Exception(ShellStyles.ErrorStyle() +
                         "This should never be reached" +
                         ShellStyles.NormalStyle())
Пример #11
0
 def getListOfSystematics(self):
     systList = None
     if self._analysisType == "HToTauNu":
         systList =  self.getSystematicsForHToTauNu()
     elif  self._analysisType == "HToTB":
         systList = self.getSystematicsForHToTB()
     else:
         raise Exception(ShellStyles.ErrorStyle() + "This should never be reached" + ShellStyles.NormalStyle() )
     if len(systList) < 1:
         self.Print("Disabled systematics", False)
     else:
         self.Print("Enabled %d systematics (%s)" % (len(systList), sh_Note + ", ".join(systList) + sh_Normal), False)
     return systList
Пример #12
0
def ApplyBlinding(myObject, blindedRange = []):
    '''
    myObject must be an instance of:
    h=histograms.Histo(rootHisto, "Label")
    and the rooHistos is an instance of:
    rootHisto = p.histoMgr.getHisto("HistoName").getRootHisto()
    '''

    if len(blindedRange) != 2:
        msg = "Blinded range list requires exactly 2 values (got %s)" % len(blindedRange) 
        raise Exception(ShellStyles.ErrorStyle() + msg + ShellStyles.NormalStyle())

    # Definitions
    myMin = None
    myMax = None
    myHisto = myObject.getRootHisto()

    # For-loop: All histogram bins
    for i in range (1, myHisto.GetNbinsX()+1):
        myUpEdge  = myHisto.GetXaxis().GetBinUpEdge(i)
        myLowEdge = myHisto.GetXaxis().GetBinLowEdge(i)
        
        # Define conditions
        c1 = (myLowEdge >= blindedRange[0] and myLowEdge <= blindedRange[1]) 
        c2 = (myUpEdge  >= blindedRange[0] and myUpEdge  <= blindedRange[1])
        c3 = (myLowEdge <= blindedRange[0] and myUpEdge  >= blindedRange[1])

        # Blind if any edge of the current bin is inside the blinded range or if bin spans over the blinded range
        if ( c1 or c2 or c3):
            if myMin == None or myLowEdge < myMin:
                myMin = myLowEdge
            if myMax == None or myUpEdge > myMax:
                myMax = myUpEdge
            #  Blind data by setting bin content to -1.0
            myHisto.SetBinContent(i, -1.0)
            myHisto.SetBinError(i, 0.0)

    if myMin == None:
        return None
    
    # Prepare blinding string for printing on canvas
    myMinFormat = "%" + "d"
    myMaxFormat = "%" + "d"
    if abs(myMin) < 1.0 and abs(myMin) > 0.00000001:
        myMinFormat = "%%.%df" % (abs(int(log10(myMin)))+1)
    if abs(myMax) < 1.0  and abs(myMax) > 0.00000001:
        myMaxFormat = "%%.%df" % (abs(int(log10(myMax)))+1)
    bString = myMinFormat%myMin+"-"+myMaxFormat%myMax
    return bString
Пример #13
0
def getBinningForTetrajetMass(binLevel=0, endValue=4000):
    '''
    Currenty in Combine:
    myBins = [0,50,100,120,140,160,180,200,220,240,260,280,300,320,340,360,380,400,420,440,460,480,500,520,540,560,580,600,620,640,660,680,700,720,740,
              760,780,800,820,840,860,880,900,920,940,960,980,1000,1020,1040,1060,1080,1100,1150,1200,1250,1300,1350,1400,1450,1500,1750,2000,2250,2500,
              2750,3000,3250,3500,3750,4000]
    '''
    myBins = []
    if binLevel == -1:
        myBins = [0.0, 4000.0]
    elif binLevel == 0: #default binning
        for i in range(0, 1000, 50):
            myBins.append(i)
        for i in range(1000, 2000, 100):
            myBins.append(i)
        for i in range(2000, 3000, 500):
            myBins.append(i)
        for i in range(3000, endValue+1000, 1000):
            myBins.append(i)
    elif binLevel == 1: #finer binning
        for i in range(0, 1000, 25):
            myBins.append(i)
        for i in range(1000, 2000, 50):
            myBins.append(i)
        for i in range(2000, endValue+250, 250):
            myBins.append(i)
    elif binLevel == 2:
        for i in range(0, 1000, 20):
            myBins.append(i)
        for i in range(1000, 2000, 40):
            myBins.append(i)
        for i in range(2000, endValue+200, 200):
            myBins.append(i)
    elif binLevel == 3:
        for i in range(0, 1000, 10):
            myBins.append(i)
        for i in range(1000, 2000, 20):
            myBins.append(i)
        for i in range(2000, endValue+50, 50):
            myBins.append(i)
    else:
        raise Exception(ShellStyles.ErrorStyle() + "Please choose bin-level from -1 to 3" + ShellStyles.NormalStyle())

    return myBins
Пример #14
0
def GetBinText(bin):
    return "bin-" + str(bin)  #tmp
    if bin == "0":
        return "|#eta| < 0.4"
    elif bin == "1":
        return "0.4 < |#eta| < 0.8"
    elif bin == "2":
        return "0.8 < |#eta| < 1.6"
    elif bin == "3":
        return "1.6 < |#eta| < 1.8"
    elif bin == "4":
        return "1.8 < |#eta| < 2.0"
    elif bin == "5":
        return "2.0 < |#eta| < 2.2"
    elif bin == "6":
        return "|#eta| > 2.2"
    elif bin == "Inclusive":
        return bin
    else:
        raise Exception(ShellStyles.ErrorStyle() + "Unexpected bin %s" %
                        (bin) + ShellStyles.NormalStyle())
Пример #15
0
    def _generateDQMPlot(self):
        '''
        Create a Data Quality Monitor (DQM) style plot
        to easily check the error for each transfer factor
        and whether it is within an acceptable relative error
        '''
        # Define error warning/tolerance on relative errors
        okay = 1.0 / (len(self._BinLabelMap.keys()))
        warn = 0.5 * okay
        NEvts = []
        # Check the uncertainties on the normalization factors
        for k in self._BinLabelMap:
            relErrorUp = abs(self._TF_Up[k]) / (self._TF[k])
            relErrorDown = abs(self._TF_Down[k]) / (self._TF[k])
            relError = self._TF_Error[k] / self._TF[k]
            if 0:
                print "bin = %s , relErrorUp = %s, relErrorDown = %s " % (
                    k, relErrorUp, relErrorDown)

            # Add DQM entries
            NCR1 = 0
            NCR2 = 0
            NCR3 = 0
            NCR4 = 0
            for j in self._NEvtsCR1:
                NCR1 += self._NEvtsCR1[j]
                NEvts.append(self._NEvtsCR1[j])
            for j in self._NEvtsCR2:
                NCR2 += self._NEvtsCR2[j]
                NEvts.append(self._NEvtsCR2[j])
            for j in self._NEvtsCR3:
                NCR3 += self._NEvtsCR3[j]
                NEvts.append(self._NEvtsCR3[j])
            for j in self._NEvtsCR4:
                NCR4 += self._NEvtsCR4[j]
                NEvts.append(self._NEvtsCR4[j])

            if 0:
                print "NCR1[%s] = %0.1f, NCR2[%s] = %0.1f, k = %s" % (
                    k, self._NEvtsCR1[k], k, self._NEvtsCR2[k], k)
                print "NCR1 = %s, NCR2 = %s, k = %s" % (NCR1, NCR2, k)
                print "error/NCR1[%s] = %0.2f, error/NCR2[%s] = %0.2f" % (
                    k, self._NEvtsCR1_Error[k] / self._NEvtsCR1[k], k,
                    self._NEvtsCR2_Error[k] / self._NEvtsCR2[k])

            # Add DQM plot entries
            self._addDqmEntry(self._BinLabelMap[k], "N_{CR1}",
                              self._NEvtsCR1[k], NCR1 * okay, NCR1 * warn)
            self._addDqmEntry(self._BinLabelMap[k], "N_{CR2}",
                              self._NEvtsCR2[k], NCR2 * okay, NCR2 * warn)
            self._addDqmEntry(self._BinLabelMap[k], "N_{CR3}",
                              self._NEvtsCR3[k], NCR3 * okay, NCR3 * warn)
            self._addDqmEntry(self._BinLabelMap[k], "N_{CR4}",
                              self._NEvtsCR4[k], NCR4 * okay, NCR4 * warn)
            # self._addDqmEntry(self._BinLabelMap[k], "#frac{#sigma_{CR1}}{N_{CR1}}", self._NEvtsCR1_Error[k]/NCR1, 0.05, 0.15)
            # self._addDqmEntry(self._BinLabelMap[k], "#frac{#sigma_{CR2}}{N_{CR2}}", self._NEvtsCR2_Error[k]/NCR2, 0.05, 0.15)

        # Construct the DQM histogram
        nBinsX = len(self._dqmKeys[self._dqmKeys.keys()[0]].keys())
        nBinsY = len(self._dqmKeys.keys())
        h = ROOT.TH2F("FakeB DQM", "FakeB DQM", nBinsX, 0, nBinsX, nBinsY, 0,
                      nBinsY)

        # Customise axes
        h.GetXaxis().SetLabelSize(15)
        h.GetYaxis().SetLabelSize(10)

        # Set Min and Max of z-axis
        if 0:  # red, yellow, green for DQM
            h.SetMinimum(0)
            h.SetMaximum(3)
        else:  # pure entries instead of red, yellow, green
            h.SetMinimum(min(NEvts) * 0.25)
            h.SetMaximum(round(max(NCR1, NCR2, NCR3, NCR4)))
            h.SetContour(10)
            #h.SetContour(3)
        if 0:
            h.GetXaxis().LabelsOption("v")
            h.GetYaxis().LabelsOption("v")

        nWarnings = 0
        nErrors = 0
        # For-loop: All x-axis bins
        for i in range(h.GetNbinsX()):
            # For-loop: All y-axis bins
            for j in range(h.GetNbinsY()):
                ykey = self._dqmKeys.keys()[j]
                xkey = self._dqmKeys[ykey].keys()[i]

                # Set the bin content
                h.SetBinContent(i + 1, j + 1, self._dqmKeys[ykey][xkey])
                h.GetXaxis().SetBinLabel(i + 1, xkey)
                h.GetYaxis().SetBinLabel(j + 1, ykey)
                if self._dqmKeys[ykey][xkey] > 2:
                    nErrors += 1
                elif self._dqmKeys[ykey][xkey] > 1:
                    nWarnings += 1

        # Apply TDR style
        style = tdrstyle.TDRStyle()
        style.setOptStat(False)
        style.setGridX(False)
        style.setGridY(False)
        style.setWide(True, 0.15)

        # Set the colour styling (red, yellow, green)
        if 0:
            palette = array.array("i",
                                  [ROOT.kGreen + 1, ROOT.kYellow, ROOT.kRed])
            ROOT.gStyle.SetPalette(3, palette)
        else:
            # https://root.cern.ch/doc/master/classTColor.html
            ROOT.gStyle.SetPalette(ROOT.kLightTemperature)
            # ROOT.gStyle.SetPalette(ROOT.kColorPrintableOnGrey)
            #tdrstyle.setRainBowPalette()
            #tdrstyle.setDeepSeaPalette()

        # Create canvas
        c = ROOT.TCanvas()
        c.SetLogx(False)
        c.SetLogy(False)
        c.SetLogz(True)
        c.SetGridx()
        c.SetGridy()
        h.Draw("COLZ")  #"COLZ TEXT"

        # Add CMS text and text with colour keys
        histograms.addStandardTexts(cmsTextPosition="outframe")
        if 0:
            histograms.addText(0.55,
                               0.80,
                               "green < %.0f %%" % (okay * 100),
                               size=20)
            histograms.addText(0.55,
                               0.84,
                               "yellow < %.0f %%" % (warn * 100),
                               size=20)
            histograms.addText(0.55,
                               0.88,
                               "red > %.0f %%" % (warn * 100),
                               size=20)

        # Save the canvas to a file
        backup = ROOT.gErrorIgnoreLevel
        ROOT.gErrorIgnoreLevel = ROOT.kWarning
        plotName = os.path.join(self._plotDirName, "FakeBNormalisationDQM")
        # For-loop: Save formats
        for ext in ["png", "C", "pdf"]:
            saveName = "%s.%s" % (plotName, ext)
            c.Print(saveName)
        ROOT.gErrorIgnoreLevel = backup
        ROOT.gStyle.SetPalette(1)

        msg = "Obtained %d warnings and %d errors for the normalisation" % (
            nWarnings, nErrors)
        self.Verbose(msg)
        if nWarnings > 0:
            msg = "DQM has %d warnings and %d errors! Please have a look at %s.png." % (
                nWarnings, nErrors, os.path.basename(plotName))
            self.Verbose(
                ShellStyles.ErrorStyle() + msg + ShellStyles.NormalStyle(),
                True)

        #if nWarnings > 0 or nErrors > 0:
        if nErrors > 0:
            msg = "DQM has %d warnings and %d errors! Please have a look at %s.png." % (
                nWarnings, nErrors, os.path.basename(plotName))
            self.Verbose(
                ShellStyles.ErrorStyle() + msg + ShellStyles.NormalStyle(),
                True)
        return
Пример #16
0
import ROOT
ROOT.gROOT.SetBatch(True)
ROOT.PyConfig.IgnoreCommandLineOptions = True

import HiggsAnalysis.NtupleAnalysis.tools.histograms as histograms
import HiggsAnalysis.NtupleAnalysis.tools.tdrstyle as tdrstyle
import HiggsAnalysis.NtupleAnalysis.tools.plots as plots
import HiggsAnalysis.NtupleAnalysis.tools.styles as styles
import HiggsAnalysis.Keras_ANN.results as _results
import HiggsAnalysis.NtupleAnalysis.tools.ShellStyles as ShellStyles
import HiggsAnalysis.NtupleAnalysis.tools.aux as aux

#================================================================================================
# Shell Types
#================================================================================================
sh_e = ShellStyles.ErrorStyle()
sh_s = ShellStyles.SuccessStyle()
sh_h = ShellStyles.HighlightStyle()
sh_a = ShellStyles.HighlightAltStyle()
sh_t = ShellStyles.NoteStyle()
sh_n = ShellStyles.NormalStyle()
sh_w = ShellStyles.WarningStyle()


#================================================================================================
# Function definition
#================================================================================================
def Verbose(msg, printHeader=False):
    '''
    Calls Print() only if verbose options is set to true.
    '''
Пример #17
0
    def plot(self):
        style = tdrstyle.TDRStyle()
        ROOT.gStyle.SetErrorX(
            0.5
        )  #required for x-axis error bars! (must be called AFTER tdrstyle.TDRStyle())

        histolist = []
        #styles.dataStyle.apply(self.h_data)
        hhd = histograms.Histo(self.h_data,
                               "Data",
                               legendStyle="PL",
                               drawStyle="E1P")
        hhd.setIsDataMC(isData=True, isMC=False)
        histolist.append(hhd)
        if 0:
            aux.PrintTH1Info(hhd.getRootHisto())

        # For-loop: All signal histo
        for i, hsignal in enumerate(self.h_signal, 1):
            mass = hsignal.GetName().replace("Hp", "")
            Verbose("Customing signal histogram for Mass = \"%s\"" % (mass),
                    i == 1)
            hhs = histograms.Histo(hsignal,
                                   hsignal.GetTitle(),
                                   legendStyle="L",
                                   drawStyle="HIST")
            hhs.setIsDataMC(isData=False, isMC=True)
            signalStyle = styles.getSignalStyleHToTB_M(mass)
            signalStyle.apply(hhs.getRootHisto())
            histolist.append(hhs)

        # For-loop: All bkg histos
        for i, hname in enumerate(self.histonames, 1):
            # Safety net for empty histos
            if hname in opts.empty:
                msg = "Skipping %s. Not a histogram!" % (hname)
                Print(
                    ShellStyles.ErrorStyle() + msg + ShellStyles.NormalStyle(),
                    True)
                continue
            else:
                #print hname
                pass

            myLabel = self.labels[hname]
            myHisto = self.histograms[hname]
            Verbose(
                "Creating histogram \"%s\" from ROOT file \"%s\" (Integral = %.1f)"
                % (hname, myHisto.GetName(), myHisto.Integral()), i == 1)
            hhp = histograms.Histo(myHisto,
                                   hname,
                                   legendStyle="F",
                                   drawStyle="HIST",
                                   legendLabel=myLabel)
            hhp.setIsDataMC(isData=False, isMC=True)
            histolist.append(hhp)
            if 0:
                aux.PrintTH1Info(hhp.getRootHisto())

        # Sanity check
        for i, h in enumerate(histolist, 1):
            hName = h.getRootHisto().GetName()
            Verbose(hName, i == 1)

        # Do the plot
        p = plots.DataMCPlot2(histolist)
        p.setDefaultStyles()
        p.stackMCHistograms()
        p.setLuminosity(opts.lumi)

        if opts.fitUncert:
            p.addMCUncertainty(
                postfit=not opts.prefit)  # boolean changes only the legend

        if opts.prefit:
            p.setLegendHeader("Pre-Fit")
        else:
            p.setLegendHeader("Post-Fit")

        # Customise histogram
        units = "GeV"  #(GeV/c^{2})
        myParams = {}
        myParams["xlabel"] = "m_{jjbb} (%s)" % (units)
        myParams["ylabel"] = "< Events / " + units + " >"
        myParams["ratio"] = True
        myParams["ratioYlabel"] = "Data/Bkg. "
        myParams["logx"] = self.gOpts.logX
        myParams["log"] = self.gOpts.logY
        myParams["ratioType"] = "errorScale"
        myParams["ratioErrorOptions"] = {
            "numeratorStatSyst": False,
            "denominatorStatSyst": True
        }
        myParams["opts"] = self.opts
        myParams["optsLogx"] = self.optsLogx
        myParams["opts2"] = self.opts2
        myParams[
            "divideByBinWidth"] = True  #not opts.fitUncert # Error when used for "TGraphAsymmErrors" (uncert.)
        myParams["errorBarsX"] = True
        myParams["xlabelsize"] = 25
        myParams["ylabelsize"] = 25
        myParams["addMCUncertainty"] = True
        myParams["addLuminosityText"] = True
        myParams["moveLegend"] = self.moveLegend
        #myParams["saveFormats"]       = []

        # Draw the plot
        if not os.path.exists(opts.saveDir):
            os.makedirs(opts.saveDir)
        plots.drawPlot(p, os.path.join(opts.saveDir, self.gOpts.saveName),
                       **myParams)

        # Save the plot (not needed - drawPlot saves the canvas already)
        SavePlot(p,
                 self.gOpts.saveName,
                 opts.saveDir,
                 saveFormats=[".png", ".pdf", ".C"])

        return
def main(opts):

    # Obtain dsetMgrCreator and register it to module selector
    dsetMgrCreator = dataset.readFromMulticrabCfg(directory=opts.mcrab)
    
    # Get list of eras, modes, and optimisation modes
    erasList      = dsetMgrCreator.getDataEras()
    modesList     = dsetMgrCreator.getSearchModes()
    optList       = dsetMgrCreator.getOptimizationModes()
    sysVarList    = dsetMgrCreator.getSystematicVariations()
    sysVarSrcList = dsetMgrCreator.getSystematicVariationSources()

    # Apply TDR style
    style = tdrstyle.TDRStyle()
    style.setGridX(opts.gridX)
    style.setGridY(opts.gridY)
    style.setOptStat(False)

    # If user does not define optimisation mode do all of them
    if opts.optMode == None:
        optModes = optList
    else:
        optModes = [opts.optMode]

    # Define genuineB and fakeB datasets
    mergeMap = {"TT": "GenuineB",
                "QCD_HT50to100"   : "FakeB", #v. poor stats!
                "QCD_HT200to300"  : "FakeB", #v. poor stats!
                "QCD_HT100to200"  : "FakeB", #v. poor stats!
                "QCD_HT200to300"  : "FakeB", #v. poor stats!
                "QCD_HT300to500"  : "FakeB",
                "QCD_HT500to700"  : "FakeB", 
                "QCD_HT700to1000" : "FakeB",
                "QCD_HT1000to1500": "FakeB",
                "QCD_HT1500to2000": "FakeB", 
                "QCD_HT2000toInf" : "FakeB",
                "WJetsToQQ_HT_600ToInf": "FakeB"
                }
    # Definitions
    results  = []

    # For-loop: All optimisation modes
    for index, opt in enumerate(optModes, 1):
        opts.optMode = opt
        
        # Definitions
        genuineB = None
        fakeB    = None

        # Setup & configure the dataset manager
        datasetsMgr = GetDatasetsFromDir(opts)
        datasetsMgr.updateNAllEventsToPUWeighted()
        datasetsMgr.loadLuminosities() # from lumi.json   
        
        # Print datasets info ?
        if opts.verbose:
            datasetsMgr.PrintCrossSections()
            datasetsMgr.PrintLuminosities()

        # Remove unwanted datasets
        removeList = ["QCD_HT50to100", "QCD_HT100to200", "QCD_HT200to300", "QCD_HT200to300_ext1", "WJetsToQQ_HT_600ToInf"]
        for k, d in enumerate(datasetsMgr.getAllDatasets(), 1):
            if d.getName() in removeList:
                datasetsMgr.remove(d.getName())
                Verbose(ShellStyles.ErrorStyle() + "Removing dataset %s" % d.getName() + ShellStyles.NormalStyle(), k==1)
        if index == 1:
            datasetsMgr.PrintInfo()

        # Merge datasets into two groups: Genuine-B and Fake-B
        datasetsMgr.mergeMany(mergeMap, addition=False)
        for d in datasetsMgr.getAllDatasets():
            if d.getName() == "GenuineB":
                genuineB = d
            if d.getName() == "FakeB":
                fakeB = d

        # Merge histograms (see NtupleAnalysis/python/tools/plots.py)
        plots.mergeRenameReorderForDataMC(datasetsMgr)

        # Get integrated luminosity
        intLumi = datasetsMgr.getDataset("Data").getLuminosity()
        datasetsMgr.remove(filter(lambda name: "Data" in name, datasetsMgr.getAllDatasetNames()))
                    
        # Print dataset information
        if index == 1:
            datasetsMgr.PrintInfo()

        # Do the plot
        name = GetPlotName(opts)
        myResults = doPlot(name, genuineB, fakeB, opts.errorlevel, opts.optMode, intLumi) 
        
        # Save results and msgs
        results.extend(myResults)
        
        # For-loop: All points
        if opts.verbose:
            for item in results:
                print item
    
    # Print path of all saved plots
    msg = "All plots saved under directory %s" % (aux.convertToURL(opts.saveDir, opts.url))
    Print(ShellStyles.SuccessStyle() + msg + ShellStyles.NormalStyle(), True)

    # Write results to a json file
    with open(opts.json, 'w') as outfile:
        json.dump(results, outfile)
    msg = "Wrote results to \"%s\"" % (opts.json)
    Print(ShellStyles.SuccessStyle() + msg + ShellStyles.NormalStyle(), True)
    return
    def createSystHistograms(self,
                             hRate,
                             hSystUp,
                             hSystDown,
                             hSystUpFromVar,
                             hSystDownFromVar,
                             quietMode=True):
        '''
        Uses the histogram "hSystUpFromVar" and "hSystDownFromVar" to account the systematic uncertainties 
        related to the Transfer Factors (TF) from the Control (or Verification) 
        Region (VR) to the Signal Region (SR). This sys. uncertainty should have both a Rate + Shape impact
        on final invariant mass distribution. 

        The two aforementioned histograms correspond to the invariant massdistrubutions
        ("ForDataDrivenCtrlPlots/LdgTetrajetMass_AfterAllSelections") obtained by using applying
        the transfer factors (TF) of the FakeB measurement to shapes from the VR. Instead of the nominal TF 
        however, the TF+TF_Error and TF-TF_Error are used instead, where TF_Error is the statistical error of
        the TF, calculated by using error propagation:
        TF = CR1/CR2
        TF_Error = ErrorPropagationForDivision(TF) = sqrt((sigmaA/b)**2 + (a/(b**2)*sigmaB)**2)
        where:
        A = Integral of CR1 histogram  (from ROOT)
        sigmaA = Integral Error for CR1 histogram (from ROOT)
        These histograms should be already in place (and correctly normalised) for the FakeB pseudodataset, 
        after running the ./makePseudoMulticrab.py -m <FakeB-dir> script.

        The error is symmetric and it is basically defined as:
        hSystUp   = Rate + 1sigma
        hSystDown = Rate - 1sigma
        where the rate is obtained from the filled histogram provided ("hRate")
        and sigma is the TF_Error as discussed above (error propagation on the division of CR1 and CR2)

        In this function we don't need to calculate the error propagation. The function assumes that the histograms provided
        already have the final variations in place (i.e. up = rate+error, down = rate-error)
        '''
        # Get the (clean) histogram name
        fullName = hRate.GetName()
        cleanName = fullName.replace("_cloned", "")
        cleanName = cleanName.replace("_FakeBMeasurementTrijetMass", "")
        rebinX = systematics.getBinningForPlot(cleanName)

        # if hRate.GetNbinsX() != hSystUpFromVar.GetNbinsX():

        if rebinX != None:
            self.Verbose(
                "Rebinning histogram \"%s\" (\"%s\")" % (cleanName, fullName),
                True)
            hRate = hRate.Rebin(
                len(rebinX) - 1, hRate.GetName(), array.array("d", rebinX))
            hSystUpFromVar = hSystUpFromVar.Rebin(
                len(rebinX) - 1, hSystUpFromVar.GetName(),
                array.array("d", rebinX))
            hSystDownFromVar = hSystDownFromVar.Rebin(
                len(rebinX) - 1, hSystDownFromVar.GetName(),
                array.array("d", rebinX))
            ### hSystUp      = hSystUp.Rebin(len(rebinX)-1, hSystUp.GetName(), array.array("d", rebinX))     #don't !
            ### hSystDown    = hSystDown.Rebin(len(rebinX)-1, hSystDown.GetName(), array.array("d", rebinX)) #don't !

        # Constuct a summary table
        table = []
        align = "{:>7} {:>15} {:>10} {:>12} {:>12} {:>12} {:>10}"
        header = align.format("Bin #", "Bin Centre", "Rate (Nom)", "Rate (Up)",
                              "Rate (Down)", "% Up", "% Down")
        hLine = "=" * 85
        table.append("{:^85}".format(cleanName))
        table.append(hLine)
        table.append(header)
        table.append(hLine)

        # For-loop: All histogram bins for given data-driven control plot
        nBinsX = hRate.GetNbinsX()
        for i in range(1, nBinsX + 1):
            self.Verbose(
                "Calculating systematic for bin \"%d\" in histogram \"%s\"" %
                (i, hRate.GetName()), i == 1)

            # Calculate the systematics
            rateNominal = hRate.GetBinContent(i)
            rateSystUp = hSystUpFromVar.GetBinContent(i)
            rateSystDown = hSystDownFromVar.GetBinContent(i)
            binCentre = hRate.GetBinCenter(i)

            # Calculate percentage difference wrt nominal
            if rateNominal > 0.0:
                rateSystUpPerc = (rateSystUp -
                                  rateNominal) / (rateNominal) * 100
                rateSystDownPerc = (rateSystDown -
                                    rateNominal) / (rateNominal) * 100
            else:
                rateSystUpPerc = 0
                rateSystDownPerc = 0

            # Fill summary table for given bin
            row = align.format(i, binCentre, "%.1f" % rateNominal,
                               "%.1f" % rateSystUp, "%.1f" % rateSystDown,
                               "%.1f" % rateSystUpPerc,
                               "%.1f" % rateSystDownPerc)
            table.append(row)
            self.Verbose(
                ShellStyles.ErrorStyle() + row + ShellStyles.NormalStyle(),
                i == 1)

            # Fill the up/down systematics histograms
            self.Verbose(
                "Setting the systematics values in the histograms SystUp and SystDown",
                False)
            hSystUp.SetBinContent(i, rateSystUp)
            hSystDown.SetBinContent(i, rateSystDown)

        # Append total uncertainty info
        table.extend(
            self.GetTotalUncertainyTable(hRate, hSystUpFromVar,
                                         hSystDownFromVar, hLine, align))

        # Print summary table
        if quietMode == False or self._verbose == True:
            for i, row in enumerate(table, 1):
                self.Print(row, i == 1)
        return
Пример #20
0
    def fetchHistograms(self, fINdata, fINpost, fINsignal):

        histoName = "data_obs"
        histoData = fINdata.Get(histoName)
        Verbose(
            "Getting data histogram \"%s\" from ROOT file \"%s\" (Integral = %.1f)"
            % (histoName, fINdata.GetName(), histoData.Integral()), True)
        self.h_data = histoData.Clone("Data")

        # Inspect histogram contents?
        if opts.verbose:
            aux.PrintTH1Info(self.h_data)

        nbins = 0
        binning = []
        # For-loop: All bins
        for iBin in range(self.h_data.GetNbinsX() + 1):
            binLowEdge = self.h_data.GetBinLowEdge(iBin)
            if binLowEdge >= opts.xMinRebin and binLowEdge < opts.xMaxRebin:
                nbins += 1
                binning.append(binLowEdge)

        binning.append(min(self.optsLogx["xmax"], opts.xMaxRebin))
        n = len(binning) - 1
        self.h_data.SetBins(nbins, array.array("d", binning))

        # Inspect histogram contents?
        if opts.verbose:
            aux.PrintTH1Info(self.h_data)

        # Define signal histogram styles
        # if len(opts.masses) > 3:
        #     raise Exception("Cannot plot more than 3 signal mass points (got %s)." % (opts.masses) )
        # lineStyles  = [ROOT.kSolid, ROOT.kDashed, ROOT.kDotted]
        # lineColours = [ROOT.kRed, ROOT.kAzure+6, ROOT.kGreen]

        # Add signal
        self.h_signal = []
        for i, m in enumerate(opts.masses, 0):
            hName = "Hp%s" % m
            histo = fINsignal[m].Get(hName)
            Verbose(
                "Getting signal histogram \"%s\" from ROOT file \"%s\" (Integral = %.1f)"
                % (hName, fINsignal[m].GetName(), histo.Integral()), False)
            if 0:
                histo.SetLineColor(lineColours[i])
                histo.SetLineStyle(lineStyles[i])
                histo.SetLineWidth(3)
            histo.SetTitle("H^{#pm} (%s GeV)" % m)
            histo.SetBins(nbins, array.array("d", binning))
            self.h_signal.append(histo.Clone(hName))

        # Inspect histogram contents?
        if opts.verbose:
            aux.PrintTH1Info(self.h_signal)

        # For-loop: All histos
        for i, hname in enumerate(self.histonames, 1):
            Verbose(
                "Getting histogram \"%s\" from ROOT file \"%s\"" %
                (histoName, fINpost.GetName()), i == 1)

            template = self.h_data.Clone(hname)
            template.Reset()

            n = len(binning) - 1
            template.SetBins(n, array.array("d", binning))

            if opts.prefit:
                histoName = os.path.join("shapes_prefit", self.name, hname)
            else:
                histoName = os.path.join("shapes_fit_b", self.name, hname)

            # Get the histograms
            histo = fINpost.Get(histoName)

            # Safety net for empty histos (if datasset integral is zero corresponding histo will not exist)
            if "TH1" in str(type(histo)):
                # print "type(histo) = ", type(histo)
                pass
            else:
                # Histograms to ignore because dataset yield is zero (hack)
                msg = "Skipping %s. Not a histogram!" % (histoName)
                Print(
                    ShellStyles.ErrorStyle() + msg + ShellStyles.NormalStyle(),
                    True)
                opts.empty.append(histoName.split("/")[-1])
                continue

            Verbose(
                "Getting bkg histogram \"%s\" from ROOT file \"%s\" (Integral = %.1f)"
                % (histoName, fINpost.GetName(), histo.Integral()), i == 1)

            # For-loop: All bins
            for iBin in range(0, histo.GetNbinsX() + 1):
                template.SetBinContent(iBin, histo.GetBinContent(iBin))
                template.SetBinError(iBin, histo.GetBinError(iBin))

            if opts.verbose:
                aux.PrintTH1Info(histo)

            # Customise histogram
            template.SetFillColor(self.colors[hname])
            template.SetLineWidth(0)
            self.histograms[hname] = template
        return
Пример #21
0
def main(opts):

    optModes = [""]

    if opts.optMode != None:
        optModes = [opts.optMode]

    # Apply TDR style
    style = tdrstyle.TDRStyle()
    style.setOptStat(False)
    style.setGridX(opts.gridX)
    style.setGridY(opts.gridY)
    style.setLogX(opts.logX)
    style.setLogY(opts.logY)
    style.setLogZ(opts.logZ)
    style.setWide(True, 0.15)
    # style.setPadRightMargin()#0.13)

    # For-loop: All opt Mode
    for opt in optModes:
        opts.optMode = opt

        # Setup & configure the dataset manager
        datasetsMgr = GetDatasetsFromDir(opts)
        datasetsMgr.updateNAllEventsToPUWeighted()
        datasetsMgr.loadLuminosities()  # from lumi.json
        if opts.verbose:
            datasetsMgr.PrintCrossSections()
            datasetsMgr.PrintLuminosities()
            datasetsMgr.PrintInfo()

        # Merge histograms (see NtupleAnalysis/python/tools/plots.py)
        plots.mergeRenameReorderForDataMC(datasetsMgr)

        # Print merged datasets and MC samples
        if 0:
            datasetsMgr.PrintInfo()

        # Get Luminosity
        if opts.intLumi < 0:
            opts.intLumi = datasetsMgr.getDataset("Data").getLuminosity()

        # Merge EWK samples
        if opts.dataset == "EWK":
            datasetsMgr.merge("EWK", aux.GetListOfEwkDatasets())
            plots._plotStyles["EWK"] = styles.getAltEWKStyle()

        # Re-order datasets (different for inverted than default=baseline)
        newOrder = []
        for d in datasetsMgr.getAllDatasets():
            if d.getName() == opts.dataset:
                newOrder.append(d.getName())

        # Sanity check on selected dataset
        nDatasets = len(newOrder)
        if nDatasets < 1:
            msg = "Please select a valid dataset. Dataset \"%s\" does not exist!" % (
                opts.dataset)
            Print(ShellStyles.ErrorStyle() + msg + ShellStyles.NormalStyle(),
                  True)
            datasetsMgr.PrintInfo()
            sys.exit()
        if nDatasets > 1:
            msg = "Please select only 1 valid dataset. Requested %i datasets for plotting!" % (
                nDatasets)
            Print(ShellStyles.ErrorStyle() + msg + ShellStyles.NormalStyle(),
                  True)
            datasetsMgr.PrintInfo()
            sys.exit()

        # Select only given dataset
        datasetsMgr.selectAndReorder(newOrder)

        # Print dataset information
        msg = "Plotting for single dataset \"%s\". Integrated luminosity is %.2f 1/fb" % (
            opts.dataset, opts.intLumi)
        Print(ShellStyles.NoteStyle() + msg + ShellStyles.NormalStyle(), True)
        datasetsMgr.PrintInfo()

        # Get list of histogram paths
        folder = opts.folder
        histoList = datasetsMgr.getDataset(
            datasetsMgr.getAllDatasetNames()[0]).getDirectoryContent(folder)
        histoPaths = [os.path.join(folder, h) for h in histoList]

        # For-loop: All histograms
        for h in histoPaths:
            if "_vs_" not in h.lower():
                continue
            Plot2dHistograms(datasetsMgr, h)

    Print(
        "All plots saved under directory %s" %
        (ShellStyles.NoteStyle() + aux.convertToURL(opts.saveDir, opts.url) +
         ShellStyles.NormalStyle()), True)
    return
Пример #22
0
def GetHistoKwargs(h, opts):

    # Common bin settings
    myBins  = []
    vtxBins = []
    ptBins  = []
    yMax    = 1.04
    bWidth  = 2    
    for i in range(0, 40, bWidth):
        vtxBins.append(i)
    bWidth  = 10 #25
    for i in range(40, 100+bWidth, bWidth):
        vtxBins.append(i)
        
    _kwargs = {
        "ylabel"           : "Purity / %.0f ",
        #"rebinX"           : 1, # cannot rebin unless i divide new purity value by rebinX value!
        #"rebinY"           : None,
        "addMCUncertainty" : False, 
        "addLuminosityText": True,
        "addCmText"        : True,
        "cmsExtraText"     : "Preliminary",
        "opts"             : {"ymin": 0.0, "ymax": yMax},
        "log"              : False,
        "moveLegend"       : {"dx": -0.05, "dy": -0.15, "dh": -0.1},
        "cutBoxY"          : {"cutValue": 1.0, "fillColor": 16, "box": False, "line": True, "greaterThan": True, "mainCanvas": True, "ratioCanvas": False}
        }

    kwargs = copy.deepcopy(_kwargs)
    
    if "deltaphi" in h.lower():
        units            = "rads"
        kwargs["xlabel"] = "#Delta#phi (%s)" % units
        kwargs["ylabel"] = "Purity / %.2f " + units
    elif "deltaeta" in h.lower():
        units            = ""
        kwargs["xlabel"] = "#Delta#eta"
        kwargs["ylabel"] = "Purity / %.2f " + units
        kwargs["opts"]   = {"xmin": 0.0 ,"xmax": 5.0, "ymin": 0.0, "ymax": yMax}
    elif "deltar" in h.lower():
        units            = ""
        kwargs["xlabel"] = "#DeltaR"
        kwargs["ylabel"] = "Purity / %.2f " + units
        kwargs["opts"]   = {"xmin": 0.0 ,"xmax": 6.0, "ymin": 0.0, "ymax": yMax}
    elif "mvamax" in h.lower():
        units            = ""
        kwargs["xlabel"] = "top-tag discriminant"
        kwargs["ylabel"] = "Purity / %.2f " + units
        kwargs["cutBox"] = {"cutValue": 0.85, "fillColor": 16, "box": False, "line": True, "greaterThan": True}
        kwargs["opts"]   = {"xmin": 0.55 ,"xmax": 1.0, "ymin": 0.0, "ymax": yMax}
        if "max1" in h.lower():
            pass
        else:
            pass
    elif "bdisc" in h.lower():
        units            = ""
        kwargs["xlabel"] = "b-tag discriminant"
        kwargs["ylabel"] = "Purity / %.2f " + units
        kwargs["cutBox"] = {"cutValue": 0.8484, "fillColor": 16, "box": False, "line": True, "greaterThan": True}
        kwargs["opts"]   = {"xmin": 0.0 ,"xmax": 1.0, "ymin": 0.0, "ymax": yMax}
    elif "pt" in h.lower():
        ROOT.gStyle.SetNdivisions(8, "X")
        units            = "GeV/c"
        kwargs["xlabel"] = "p_{T} (%s)" % units
        kwargs["ylabel"]+= units
        # kwargs["cutBox"] = {"cutValue": 40.0, "fillColor": 16, "box": True, "line": True, "greaterThan": True}
        kwargs["opts"]   = {"xmin": 0.0 ,"xmax": 500.0, "ymin": 0.0, "ymax": yMax}
        if "tetrajet" in h.lower():
            kwargs["opts"]   = {"xmin": 0.0 ,"xmax": 800.0, "ymin": 0.0, "ymax": yMax}
    elif "mass" in h.lower() or "jetM" in h:
        units             = "GeV/c^{2}"
        kwargs["xlabel"]  = "m_{jjb}^{ldg} (%s)" % units
        kwargs["ylabel"] += units
        if "trijet" in h.lower():
            kwargs["opts"]   = {"xmin": 50.0 ,"xmax": 300.0, "ymin": 0.0, "ymax": yMax}
            kwargs["cutBox"] = {"cutValue": 173.21, "fillColor": 16, "box": False, "line": True, "greaterThan": True}
        if "tetrajet" in h.lower():
            kwargs["opts"]   = {"xmin": 0.0 ,"xmax": 3000.0, "ymin": 0.0, "ymax": yMax}
            kwargs["cutBox"] = {"cutValue": 173.21, "fillColor": 16, "box": False, "line": False, "greaterThan": True}
    elif "MET" in h:
        units             = "GeV"
        kwargs["xlabel"]  = "E_{T}^{miss} (%s)" % units
        kwargs["ylabel"] += units
    elif "Njets" in h:
        units             = ""
        kwargs["xlabel"]  = "jet multiplicity"
        #kwargs["ylabel"] += units
        kwargs["opts"]   = {"xmin": 6.0 ,"xmax": 18.0, "ymin": 0.0, "ymax": yMax}
        kwargs["cutBox"] = {"cutValue": 7.0, "fillColor": 16, "box": False, "line": True, "greaterThan": True}
    elif "HT" in h:
        units             = "GeV"
        kwargs["xlabel"]  = "H_{T} (%s)" % units
        kwargs["ylabel"]  = "Purity / %.0f " + units
        kwargs["cutBox"] = {"cutValue": 500.0, "fillColor": 16, "box": True, "line": True, "greaterThan": True}
        kwargs["opts"]["xmax"] = 3000.0
    elif "eta" in h.lower():
        units            = ""
        kwargs["xlabel"] = "#eta"
        kwargs["ylabel"]  = "Purity / %.2f " + units
        kwargs["cutBox"] = {"cutValue": 0.0, "fillColor": 16, "box": False, "line": True, "greaterThan": True}
        kwargs["opts"]   = {"xmin": -2.5 ,"xmax": 2.5, "ymin": 0.0, "ymax": yMax}
        if "trijet" in h.lower():
            pass
        if "bjet" in h.lower():
            pass        
    else:
        Print("Could not customise kwargs for %s" % (ShellStyles.ErrorStyle() + h + ShellStyles.NormalStyle()), True)
    return kwargs
Пример #23
0
def main(opts):
    
    # Suppress warnings about weight being re-applied
    ROOT.gErrorIgnoreLevel = ROOT.kError 

    # Obtain dsetMgrCreator and register it to module selector
    dsetMgrCreator = dataset.readFromMulticrabCfg(directory=opts.mcrab)

    # Get list of eras, modes, and optimisation modes
    erasList      = dsetMgrCreator.getDataEras()
    modesList     = dsetMgrCreator.getSearchModes()
    optList       = dsetMgrCreator.getOptimizationModes()
    sysVarList    = dsetMgrCreator.getSystematicVariations()
    sysVarSrcList = dsetMgrCreator.getSystematicVariationSources()
    
    # If user does not define optimisation mode do all of them
    if opts.optMode == None:
        if len(optList) < 1:
            optList.append("")
        else:
            pass
        optModes = optList
    else:
        optModes = [opts.optMode]

    opts.optMode = ""
    mcrabName    = opts.mcrab
    RunEra       = mcrabName.split("_")[1]

    # Setup ROOT and style
    ROOT.gROOT.SetBatch(opts.batchMode)
    style = tdrstyle.TDRStyle()
    style.setOptStat(True)
    style.setGridX(True)
    style.setGridY(True)
    
    # Setup & configure the dataset manager
    datasetsMgr = GetDatasetsFromDir(opts)

    # Remove some QCD samples (the cross sections of these samples are not calculated)
    if 0:
        msg = "Removing following samples:"
        Print(ShellStyles.ErrorStyle() + msg + ShellStyles.NormalStyle(), True)
        for d in getDatasetsToExclude():
            Print(d, False)
            datasetsMgr.remove(d)

    # Get run-range 
    minRunRange, maxRunRange, runRange = GetRunRange(datasetsMgr)

    # Get int lumi
    intLumi  = GetLumi(datasetsMgr)

    # Update to PU & load luminosities 
    datasetsMgr.updateNAllEventsToPUWeighted()
    datasetsMgr.loadLuminosities()
    #datasetsMgr.normalizeMCByLuminosity()

    # Print luminisoties and cross-sections
    datasetsMgr.PrintLuminosities()
    datasetsMgr.PrintCrossSections()

    # Default merging & ordering: "Data", "QCD", "SingleTop", "Diboson"
    plots.mergeRenameReorderForDataMC(datasetsMgr)
    
    # Get datasets
    datasetsMgr.mergeMC()
    dataset_Data = datasetsMgr.getDataDatasets()
    dataset_MC   = datasetsMgr.getMCDatasets()

    # Define lists of Triggers to be plotted and Variables 
    xVars   = ["pt6thJet", "eta6thJet", "phi6thJet", "Ht", "nBTagJets", "pu", "JetMulti", "BJetMulti"]
    trgList = ["1BTag", "2BTag", "OR", "OR_PFJet450"]
    if opts.fast:
        trgList = ["OR_PFJet450"]
        xVars   = ["pt6thJet", "Ht"]
    nPlots  = len(trgList)*len(xVars)
    counter =  0

    # For-loop: All signal triggers
    for i, trg in enumerate(trgList, 1):
        
        # For-loop: All x-variables
        for j, xVar in enumerate(xVars, 1):
            counter+=1
            msg = "{:<9} {:>3} {:<1} {:<3} {:<50}".format("Histogram", "%i" % counter, "/", "%s:" % (nPlots), "%s Vs %s" % (trg, xVar))
            Print(ShellStyles.SuccessStyle() + msg + ShellStyles.NormalStyle(), counter==1)


            # Define names
            hNumerator   = "hNum_%s_RefTrg_OfflineSel_Signal%s" % (xVar, trg)
            hDenominator = "hDen_%s_RefTrg_OfflineSel" % (xVar)
            plotName     = "Eff_%s_%s" % (xVar, trg)
            
            # Get Efficiency Plots
            _kwargs  = GetHistoKwargs(xVar, opts)
            eff_Data = GetEfficiency(datasetsMgr, dataset_Data, hNumerator, hDenominator , **_kwargs)
            eff_MC   = GetEfficiency(datasetsMgr, dataset_MC, hNumerator, hDenominator, **_kwargs) 
                       
            # Apply Styles
            styles.dataStyle.apply(eff_Data)
            styles.mcStyle.apply(eff_MC)
        
            # Create the plot
            p = plots.ComparisonPlot(histograms.HistoGraph(eff_Data, "eff_Data", "p", "P"),
                                     histograms.HistoGraph(eff_MC,   "eff_MC"  , "p", "P"),
                                     saveFormats=[])                  

            # Define the legend entries
            p.histoMgr.setHistoLegendLabelMany(
                {
                    "eff_Data": "Data", 
                    "eff_MC"  : "Simulation"
                    }
                )
            
            # Draw and save the plot
            p.setLuminosity(intLumi)
            plots.drawPlot(p, plotName, **_kwargs)
                                                   
            # Draw
            histograms.addText(0.65, 0.06, "Runs "+ runRange, 17)
            histograms.addText(0.65, 0.10, "2016", 17)

            # Save the canvas to a file
            SavePlot(p, plotName, os.path.join(opts.saveDir, opts.optMode), saveFormats=[".pdf", ".png", ".C"] )

    Print("All plots saved under directory %s" % (ShellStyles.NoteStyle() + aux.convertToURL(opts.saveDir, opts.url) + ShellStyles.NormalStyle()), True)
    return
Пример #24
0
ROOT.gROOT.SetBatch(True)
ROOT.PyConfig.IgnoreCommandLineOptions = True

import datasets as datasetsTest
import HiggsAnalysis.NtupleAnalysis.tools.dataset as dataset
import HiggsAnalysis.NtupleAnalysis.tools.aux as aux
import HiggsAnalysis.NtupleAnalysis.tools.git as git
import HiggsAnalysis.NtupleAnalysis.tools.ShellStyles as ShellStyles

#================================================================================================
# Global Definitions
#================================================================================================
_debugMode = False
_debugPUreweighting = False
_debugMemoryConsumption = False
sh_Error = ShellStyles.ErrorStyle()
sh_Success = ShellStyles.SuccessStyle()
sh_Note = ShellStyles.HighlightAltStyle()
sh_Normal = ShellStyles.NormalStyle()


#================================================================================================
# Function Definition
#================================================================================================
def Verbose(msg, printHeader=False):
    '''
    Calls Print() only if verbose options is set to true.
    '''
    if not _debugMode:
        return
    Print(msg, printHeader)
Пример #25
0
def main(opts):

    # Apply TDR style
    style = tdrstyle.TDRStyle()
    style.setOptStat(False)
    style.setGridX(opts.gridX)
    style.setGridY(opts.gridY)

    optModes = [""]

    if opts.optMode != None:
        optModes = [opts.optMode]
        
    # For-loop: All opt Mode
    for opt in optModes:
        opts.optMode = opt

        # Setup & configure the dataset manager 
        datasetsMgr = GetDatasetsFromDir(opts)
        datasetsMgr.updateNAllEventsToPUWeighted()
        #datasetsMgr.loadLuminosities() # from lumi.json

        if opts.verbose:
            datasetsMgr.PrintCrossSections()
            datasetsMgr.PrintLuminosities()
            
        if 1:
            datasetsMgr.printSelections()
            sys.exit()

        # Merge histograms (see NtupleAnalysis/python/tools/plots.py) 
        plots.mergeRenameReorderForDataMC(datasetsMgr) 

        # Get the luminosity
        if opts.intLumi < 0:
            opts.intLumi = 35.8 #fixme
            # opts.intLumi = datasetsMgr.getDataset("Data").getLuminosity()

        # Set/Overwrite cross-sections
        for i, d in enumerate(datasetsMgr.getAllDatasets(), 0):
            if "FakeB" not in d.getName():
                msg = "Removing dataset %s" % d.getName()
                Verbose(ShellStyles.NoteStyle() + msg + ShellStyles.NormalStyle(), i==0)
                datasetsMgr.remove(d.getName())

        # Re-order datasets (different for inverted than default=baseline)
        if 0:
            newOrder = ["FakeB"]
            datasetsMgr.selectAndReorder(newOrder)
        
        # Print dataset information
        datasetsMgr.PrintInfo()

        # Get histograms under given folder in ROOT file
        hList      = datasetsMgr.getDataset(opts.dataset).getDirectoryContent(opts.folder)
        hPaths1    = [os.path.join(opts.folder, h) for h in hList]
        hPaths2    = [h for h in hPaths1 if "Purity" in h]
        keepHistos = ["Njets", "MET", "MVAmax1", "MVAmax2", "LdgTetrajetPt", "LdgTetrajetMass", 
                      "TetrajetBJetPt", "TetrajetBJetEta", "TetrajetBJetBdisc", "DeltaEtaLdgTrijetBJetTetrajetBJet", "DeltaPhiLdgTrijetBJetTetrajetBJet", 
                      "DeltaRLdgTrijetBJetTetrajetBJet", "LdgTrijetPt", "LdgTrijetM", "LdgTrijetBJetBdisc"]
        allHistos  = ["NBjets", "Bjet1Pt", "Bjet2Pt", "Bjet3Pt", "Bjet1Eta", "Bjet2Eta", "Bjet3Eta", "Bjet1Bdisc", "Bjet2Bdisc", "Bjet3Bdisc", "Njets", 
                      "Jet1Pt", "Jet2Pt", "Jet3Pt", "Jet4Pt", "Jet5Pt", "Jet6Pt", "Jet7Pt", "Jet1Eta", "Jet2Eta", "Jet3Eta", "Jet4Eta", "Jet5Eta", "Jet6Eta", "Jet7Eta", 
                      "Jet1Bdisc", "Jet2Bdisc", "Jet3Bdisc", "Jet4Bdisc", "Jet5Bdisc", "Jet6Bdisc", "Jet7Bdisc", "MET", "MVAmax1", "MVAmax2", "LdgTetrajetPt", "LdgTetrajetMass", 
                     "TetrajetBJetPt", "TetrajetBJetEta", "TetrajetBJetBdisc", "DeltaEtaLdgTrijetBJetTetrajetBJet", "DeltaPhiLdgTrijetBJetTetrajetBJet", 
                      "DeltaRLdgTrijetBJetTetrajetBJet", "LdgTrijetPt", "LdgTrijetM", "LdgTrijetBJetBdisc", "SubLdgTrijetPt", "SubLdgTrijetM", "SubLdgTrijetBJetBdisc", "LdgDijetPt", 
                      "LdgDijetM", "SubLdgDijetPt", "SubLdgDijetM"]

        # For-loop: All histograms
        for i, h in enumerate(hPaths2, 1):
            hName = h.split("/")[1].replace("_AfterAllSelections_Purity", "")
            if hName not in keepHistos:
                Verbose("Skipping %s" % (ShellStyles.ErrorStyle() + h + ShellStyles.NormalStyle()), i==1)
                continue
            else:
                Verbose("Plotting %s" % (ShellStyles.NoteStyle() + h + ShellStyles.NormalStyle()), True)
            if opts.doHistos:
                PlotHistograms(datasetsMgr, h)
            else:
                PlotHistoGraphs(datasetsMgr, h, hideZeros=True)

    return
Пример #26
0
from subprocess import Popen, PIPE
import os
import sys
import datetime
from optparse import OptionParser

import HiggsAnalysis.NtupleAnalysis.tools.ShellStyles as ShellStyles

#================================================================================================
# Variable definition
#================================================================================================
ss = ShellStyles.SuccessStyle()
ns = ShellStyles.NormalStyle()
ts = ShellStyles.NoteStyle()
hs = ShellStyles.HighlightAltStyle()
es = ShellStyles.ErrorStyle()


#================================================================================================
# Function Definitions
#================================================================================================
def Verbose(msg, printHeader=False):
    if not VERBOSE:
        return
    if printHeader:
        print "=== submitCondor.py:"

    if msg != "":
        print "\t", msg
    return
Пример #27
0
def main():

    # Save start time (epoch seconds)
    tStart = time.time()
    Verbose("Started @ " + str(tStart), True)

    # Require at least two arguments (script-name, path to multicrab)
    if len(sys.argv) < 2:
        Print(
            "Not enough arguments passed to script execution. Printing docstring & EXIT."
        )
        print __doc__
        sys.exit(0)
    else:
        pass

    # ================================================================================================
    # Setup the process
    # ================================================================================================
    maxEvents = {}
    maxEvents["All"] = opts.nEvts
    # maxEvents["2016"] = 1
    # maxEvents["ZZTo4Q"] = -1
    # maxEvents["ZJetsToQQ_HT600toInf"] = 1
    # maxEvents["WZ_ext1"] = 1
    # maxEvents["WZ"] = 1
    # maxEvents["WWTo4Q"] = 1
    # maxEvents["WJetsToQQ_HT_600ToInf"] = 1
    # maxEvents["TTZToQQ"] = 1
    # maxEvents["TTWJetsToQQ"] = 1
    # maxEvents["TTTT"] = 1
    # maxEvents["TT"] = 1
    # maxEvents["ST_t_channel_top_4f_inclusiveDecays"] = 1
    # maxEvents["ST_t_channel_antitop_4f_inclusiveDecays"] = 1
    # maxEvents["ST_tW_top_5f_inclusiveDecays_ext1"] = 1
    # maxEvents["ST_tW_top_5f_inclusiveDecays"] = 1
    # maxEvents["ST_tW_antitop_5f_inclusiveDecays_ext1"] = 1
    # maxEvents["ST_tW_antitop_5f_inclusiveDecays"] = 1
    # maxEvents["ST_s_channel_4f_InclusiveDecays"] = 1
    # maxEvents["QCD_HT700to1000_ext1"] = 1
    # maxEvents["QCD_HT700to1000"] = 1
    # maxEvents["QCD_HT50to100"] = 1
    # maxEvents["QCD_HT500to700_ext1"] = 1
    # maxEvents["QCD_HT500to700"] = 1
    # maxEvents["QCD_HT300to500_ext1"] = 1
    # maxEvents["QCD_HT300to500"] = 1
    # maxEvents["QCD_HT200to300_ext1"] = 1
    # maxEvents["QCD_HT200to300"] = 1
    # maxEvents["QCD_HT2000toInf_ext1"] = 1
    # maxEvents["QCD_HT2000toInf"] = 1
    # maxEvents["QCD_HT1500to2000_ext1"] = 1
    # maxEvents["QCD_HT1500to2000"] = 1
    # maxEvents["QCD_HT100to200"] = 1
    # maxEvents["QCD_HT1000to1500_ext1"] = 1
    # maxEvents["QCD_HT1000to1500"] = 1
    # maxEvents["JetHT_Run2016H_03Feb2017_ver3_v1_284036_284044"] = 1
    # maxEvents["JetHT_Run2016H_03Feb2017_ver2_v1_281613_284035"] = 1
    # maxEvents["JetHT_Run2016G_03Feb2017_v1_278820_280385"] = 1
    # maxEvents["JetHT_Run2016F_03Feb2017_v1_278801_278808"] = 1
    # maxEvents["JetHT_Run2016F_03Feb2017_v1_277932_278800"] = 1
    # maxEvents["JetHT_Run2016E_03Feb2017_v1_276831_277420"] = 1
    # maxEvents["JetHT_Run2016D_03Feb2017_v1_276315_276811"] = 1
    # maxEvents["JetHT_Run2016C_03Feb2017_v1_275656_276283"] = 1
    # maxEvents["JetHT_Run2016B_03Feb2017_ver2_v2_273150_275376"] = 1
    # maxEvents["DYJetsToQQ_HT180"] = 1
    # maxEvents["ChargedHiggs_HplusTB_HplusToTB_M_500"] = 1
    process = Process(prefix, postfix, maxEvents)

    # ================================================================================================
    # Add the datasets (according to user options)
    # ================================================================================================
    if (opts.includeOnlyTasks):
        Verbose("Adding only dataset %s from multiCRAB directory %s" %
                (opts.includeOnlyTasks, opts.mcrab))
        process.addDatasetsFromMulticrab(
            opts.mcrab, includeOnlyTasks=opts.includeOnlyTasks)
    elif (opts.excludeTasks):
        Verbose("Adding all datasets except %s from multiCRAB directory %s" %
                (opts.excludeTasks, opts.mcrab))
        Print(
            "If collision data are present, then vertex reweighting is done according to the chosen data era (era=2015C, 2015D, 2015) etc..."
        )
        process.addDatasetsFromMulticrab(opts.mcrab,
                                         excludeTasks=opts.excludeTasks)
    else:
        myBlackList = [
            "M_180", "M_200", "M_220", "M_250", "M_300", "M_350", "M_400",
            "M_500", "M_650", "M_800", "M_1000", "M_1500", "M_2000", "M_2500",
            "M_3000", "M_5000", "M_7000", "M_10000", "QCD_b"
        ]
        Verbose("Adding all datasets from multiCRAB directory %s except %s" %
                (opts.mcrab, (",".join(myBlackList))))
        Verbose(
            "Vertex reweighting is done according to the chosen data era (%s)"
            % (",".join(dataEras)))
        # process.addDatasetsFromMulticrab(opts.mcrab, blacklist=myBlackList)
        if len(myBlackList) > 0:
            regex = "|".join(myBlackList)
            process.addDatasetsFromMulticrab(opts.mcrab, excludeTasks=regex)
        else:
            process.addDatasetsFromMulticrab(opts.mcrab)

    # ================================================================================================
    # Overwrite Default Settings
    # ================================================================================================
    from HiggsAnalysis.NtupleAnalysis.parameters.hplus2tbAnalysis import allSelections

    allSelections.verbose = opts.verbose
    allSelections.histogramAmbientLevel = opts.histoLevel

    # Set splitting of phase-space (first bin is below first edge value and last bin is above last edge value)
    allSelections.CommonPlots.histogramSplitting = [
        PSet(label="TetrajetBjetPt",
             binLowEdges=[60, 90, 160, 300],
             useAbsoluteValues=False),  # Final
        PSet(label="TetrajetBjetEta",
             binLowEdges=[0.8, 1.4, 2.0],
             useAbsoluteValues=True),  # Final
        #
        # PSet(label="TetrajsetBjetPt", binLowEdges=[60, 100, 150], useAbsoluteValues=False),
        # PSet(label="TetrajsetBjetPt", binLowEdges=[60, 150], useAbsoluteValues=False),
        # PSet(label="TetrajsetBjetPt", binLowEdges=[55, 110], useAbsoluteValues=False),
        # PSet(label="TetrajetBjetEta", binLowEdges=[0.8, 1.6], useAbsoluteValues=True),
        # PSet(label="TetrajetBjetEta", binLowEdges=[0.4, 0.8, 1.6, 2.0, 2.2], useAbsoluteValues=True),  #AN v4
    ]

    # Overwrite values
    # allSelections.TopSelectionBDT.CSV_bDiscCutDirection  = ">="
    allSelections.TopSelectionBDT.CSV_bDiscCutValue = 0.54  # allow CSVv2-L for inverted top

    # Testing
    if 0:
        msg = "WARNING! This is a simple testing of the FakeB measurement with only 1 CSVv2-M. Disable once done!"
        Print(ShellStyles.ErrorStyle() + msg + ShellStyles.NormalStyle(), True)
        allSelections.FakeBMeasurement.baselineBJetsCutValue = 0  #1
        allSelections.FakeBMeasurement.baselineBJetsCutDirection = "=="

    # ================================================================================================
    # Command Line Options
    # ================================================================================================
    # from HiggsAnalysis.NtupleAnalysis.parameters.signalAnalysisParameters import applyAnalysisCommandLineOptions
    # applyAnalysisCommandLineOptions(sys.argv, allSelections)

    # ================================================================================================
    # Build analysis modules
    # ================================================================================================
    PrintOptions(opts)
    builder = AnalysisBuilder(prefix,
                              dataEras,
                              searchModes,
                              usePUreweighting=opts.usePUreweighting,
                              useTopPtReweighting=opts.useTopPtReweighting,
                              doSystematicVariations=opts.doSystematics,
                              analysisType="HToTB",
                              verbose=opts.verbose)

    # Add variations (e.g. for optimisation)
    # builder.addVariation("BJetSelection.triggerMatchingApply", [True, False]) # At least 1 trg b-jet dR-matched to offline b-jets
    # builder.addVariation("FakeBMeasurement.prelimTopFitChiSqrCutValue", [100, 20])
    # builder.addVariation("FakeBMeasurement.prelimTopFitChiSqrCutDirection", ["<=", "==", ">="])
    # builder.addVariation("FakeBMeasurement.numberOfBJetsCutValue", [0, 1])
    # builder.addVariation("FakeBMeasurement.numberOfBJetsCutDirection", ["=="])
    # builder.addVariation("FakeBMeasurement.numberOfBJetsCutDirection", ["<=", "==", ">="])
    # builder.addVariation("FakeBMeasurement.numberOfInvertedBJetsCutValue", [0, 1])
    # builder.addVariation("FakeBMeasurement.numberOfInvertedBJetsCutDirection", [">="])
    # builder.addVariation("FakeBMeasurement.invertedBJetDiscr", "")
    # builder.addVariation("FakeBMeasurement.invertedBJetDiscrWorkingPoint", "Loose")
    # builder.addVariation("FakeBMeasurement.invertedBJetsSortType", ["Random", "DescendingBDiscriminator"])
    # builder.addVariation("FakeBMeasurement.invertedBJetsDiscrMaxCutValue", [0.82, 0.80, 0.75, 0.70])
    # builder.addVariation("TopSelection.ChiSqrCutValue", [100])
    # builder.addVariation("Trigger.triggerOR", [["HLT_PFHT450_SixJet40"], ["HLT_PFHT400_SixJet30"]])
    # builder.addVariation("TopologySelection.FoxWolframMomentCutValue", [0.5, 0.7])
    # builder.addVariation("Trigger.triggerOR", [["HLT_PFHT400_SixJet30_DoubleBTagCSV_p056"], ["HLT_PFHT450_SixJet40_BTagCSV_p056"]])
    # builder.addVariation("Trigger.triggerOR", [["HLT_PFHT400_SixJet30_DoubleBTagCSV_p056", "HLT_PFHT450_SixJet40_BTagCSV_p056"]])

    # Build the builder
    builder.build(process, allSelections)

    # ================================================================================================
    # Example of adding an analyzer whose configuration depends on dataVersion
    # ================================================================================================
    # def createAnalyzer(dataVersion):
    # a = Analyzer("ExampleAnalysis")
    # if dataVersion.isMC():
    # a.tauPtCut = 10
    # else:
    # a.tauPtCut = 20
    # return a
    # process.addAnalyzer("test2", createAnalyzer)

    # ================================================================================================
    # Pick events
    # ================================================================================================
    # process.addOptions(EventSaver = PSet(enabled = True,pickEvents = True))

    # ================================================================================================
    # Run the analysis
    # ================================================================================================
    # Run the analysis with PROOF? You can give proofWorkers=<N> as a parameter
    if opts.jCores:
        Print("Running process with PROOF (proofWorkes=%s)" %
              (str(opts.jCores)))
        process.run(proof=True, proofWorkers=opts.jCores)
    else:
        Print("Running process (no PROOF)")
        process.run()

    # Print total time elapsed
    tFinish = time.time()
    dt = int(tFinish) - int(tStart)
    days = divmod(dt, 86400)  # days
    hours = divmod(days[1], 3600)  # hours
    mins = divmod(hours[1], 60)  # minutes
    secs = mins[1]  # seconds
    Print(
        "Total elapsed time is %s days, %s hours, %s mins, %s secs" %
        (days[0], hours[0], mins[0], secs), True)
    return