示例#1
0
def main(opts):

    # Apply TDR style
    style = tdrstyle.TDRStyle()
    style.setOptStat(True)
    style.setGridX(True)
    style.setGridY(True)

    # 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("")
        optModes = optList
    else:
        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()

        # Get the PSets:
        if 0:
            datasetsMgr.printSelections()
            #PrintPSet("BJetSelection", datasetsMgr, depth=150)

        # ZJets and DYJets overlap!
        if "ZJetsToQQ_HT600toInf" in datasetsMgr.getAllDatasetNames(
        ) and "DYJetsToQQ_HT180" in datasetsMgr.getAllDatasetNames():
            Print(
                "Cannot use both ZJetsToQQ and DYJetsToQQ due to duplicate events? Investigate. Removing ZJetsToQQ datasets for now ..",
                True)
            datasetsMgr.remove(
                filter(lambda name: "ZJetsToQQ" in name,
                       datasetsMgr.getAllDatasetNames()))

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

        # Get luminosity if a value is not specified
        if opts.intLumi < 0:
            opts.intLumi = datasetsMgr.getDataset("Data").getLuminosity()

        # Remove datasets
        removeList = ["QCD-b", "Charged"]
        if not opts.useMC:
            removeList.append("QCD")
        for i, d in enumerate(removeList, 0):
            msg = "Removing dataset %s" % d
            Verbose(
                ShellStyles.WarningLabel() + msg + ShellStyles.NormalStyle(),
                i == 0)
            datasetsMgr.remove(
                filter(lambda name: d in name,
                       datasetsMgr.getAllDatasetNames()))

        # Print summary of datasets to be used
        if 0:
            datasetsMgr.PrintInfo()

        # Merge EWK samples
        datasetsMgr.merge("EWK", aux.GetListOfEwkDatasets())

        # Print dataset information
        datasetsMgr.PrintInfo()

        # List of TDirectoryFile (_CRone, _CRtwo, _VR, _SR)
        tdirs = [
            "LdgTrijetPt_", "LdgTrijetMass_", "LdgTrijetBJetBdisc_",
            "TetrajetBJetPt_", "TetrajetBJetEta_", "TetrajetBJetBdisc_",
            "LdgTetrajetPt_", "LdgTetrajetMass_"
        ]
        region = ["CRone", "CRtwo"]
        hList = []
        for d in tdirs:
            for r in region:
                hList.append(d + r)

        # Get the folders with the binned histograms
        folderList_ = datasetsMgr.getDataset(
            datasetsMgr.getAllDatasetNames()[0]).getDirectoryContent(
                opts.folder)
        folderList = [h for h in folderList_ if h in hList]

        # For-loop: All folders
        histoPaths = []
        for f in folderList:
            folderPath = os.path.join(opts.folder, f)
            histoList = datasetsMgr.getDataset(
                datasetsMgr.getAllDatasetNames()[0]).getDirectoryContent(
                    folderPath)
            pathList = [os.path.join(folderPath, h) for h in histoList]
            histoPaths.extend(pathList)

        # Get all the bin labels
        binLabels = GetBinLabels("CRone", histoPaths)

        for i, t in enumerate(tdirs, 1):
            myList = []
            for p in histoPaths:
                if t in p:
                    myList.append(p)
            msg = "{:<9} {:>3} {:<1} {:<3} {:<50}".format(
                "Histogram", "%i" % i, "/", "%s:" % (len(tdirs)),
                t.replace("_", ""))
            Print(ShellStyles.SuccessStyle() + msg + ShellStyles.NormalStyle(),
                  i == 1)

            PlotHistograms(datasetsMgr, myList, binLabels, opts)

    # Save the plots
    Print(
        "All plots saved under directory %s" %
        (ShellStyles.NoteStyle() + aux.convertToURL(opts.saveDir, opts.url) +
         ShellStyles.NormalStyle()), True)
    return
示例#2
0
def main(opts):

    # Apply TDR style
    style = tdrstyle.TDRStyle()
    style.setGridX(opts.gridx)
    style.setGridY(opts.gridy)
    style.setLogX(opts.logx)
    style.setLogY(opts.logy)

    # Create legend and set style
    histograms.createLegend.moveDefaults(dx=-0.1, dh=-0.15)
    histograms.uncertaintyMode.set(histograms.Uncertainty.StatOnly)
    styles.ratioLineStyle.append(styles.StyleLine(lineColor=13))

    # Define some variables
    nameList = []
    allShapeNuisances = []
    signalTable = {}
    myDatacardPattern = ""
    myRootfilePattern = ""

    # Find out the mass points
    if opts.cardPattern == None:
        mySettings = limitTools.GeneralSettings(".", [])
        myDatacardPattern = mySettings.getDatacardPattern(
            limitTools.LimitProcessType.TAUJETS)
        myRootfilePattern = mySettings.getRootfilePattern(
            limitTools.LimitProcessType.TAUJETS)
    else:
        myDatacardPattern = opts.cardPattern.replace("MMM", "M%s").replace(
            "MM", "%s")
        myRootfilePattern = opts.rootfilePattern.replace("MMM", "M%s").replace(
            "MM", "%s")

    # Get mass points to consider
    massPoints = DatacardReader.getMassPointsForDatacardPattern(
        ".", myDatacardPattern)
    Print(
        "The following masses will be considered: %s" %
        (ShellStyles.HighlightAltStyle() + ", ".join(massPoints) +
         ShellStyles.NormalStyle()), True)

    # For-loop: All mass points
    for i, m in enumerate(massPoints, 1):

        # Obtain luminosity from the datacard
        myLuminosity = float(
            limitTools.readLuminosityFromDatacard(".", myDatacardPattern % m))

        # Do the plots
        doPlot(opts, int(m), nameList, allShapeNuisances, myLuminosity,
               myDatacardPattern, myRootfilePattern, signalTable)

    # Print signal table
    Print("Max contracted uncertainty for signal:", True)
    table = []
    align = "{:>30} {:>15} {:>15}"
    hLine = "=" * 60
    table.append(hLine)
    table.append(align.format("Systematic", "Minimum", "Maximum"))
    table.append(hLine)
    # For-loop: All signal
    for i, k in enumerate(signalTable.keys(), 1):
        # Print("Key = %s" % (k), False)
        minVal = "%.3f" % (signalTable[k]["min"])
        maxVal = "%.3f" % (signalTable[k]["max"])
        msg = align.format(k, minVal, maxVal)
        table.append(msg)
    table.append(hLine)
    for row in table:
        Print(row, False)

    msg = "All results under directory %s" % (
        ShellStyles.SuccessStyle() + opts.dirName + ShellStyles.NormalStyle())
    Print(msg, True)

    return
示例#3
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
示例#4
0
    def drawAllInOne(self, myAllShapeNuisances, luminosity):
        myMaxSize = len(myAllShapeNuisances)
        # Create pads
        canvasHeight = _cHeaderHeight + _cBodyHeight * myMaxSize + _cFooterHeight
        c = ROOT.TCanvas("", "", 600, canvasHeight)
        c.Divide(1, myMaxSize)
        myHeightBefore = canvasHeight
        myHeightAfter = canvasHeight
        for i in range(0, myMaxSize):
            myHeightBefore = myHeightAfter
            p = c.cd(i + 1)
            myTopMargin = 0.0
            myBottomMargin = 0.0
            if i == 0:
                # Top histogram with header
                myHeightAfter -= _cHeaderHeight + _cBodyHeight
                myTopMargin = float(_cHeaderHeight) / float(_cHeaderHeight +
                                                            _cBodyHeight)
            elif i == myMaxSize - 1:
                # Bottom histogram with x axis label and title
                myHeightAfter -= _cFooterHeight + _cBodyHeight
                myBottomMargin = float(_cFooterHeight) / float(_cFooterHeight +
                                                               _cBodyHeight)
            else:
                # Middle histogram, only body
                myHeightAfter -= _cBodyHeight
            (xlow, ylow, xup, yup) = [ROOT.Double(x) for x in [0.0] * 4]
            p.GetPadPar(xlow, ylow, xup, yup)
            p.SetPad(xlow,
                     float(myHeightAfter) / float(canvasHeight), xup,
                     float(myHeightBefore) / float(canvasHeight))
            p.SetBorderMode(0)
            p.SetFillStyle(4000)
            p.SetTopMargin(myTopMargin)
            p.SetBottomMargin(myBottomMargin)

        # Draw plots
        if len(self._ratioPlotList) == 0:
            self.Verbose("No ratioplots in list. Cannot draw all-in-one plot!",
                         False)
            return

        o = self._ratioPlotList[0].getFrame2()
        myEmptyPlot = aux.Clone(
            o)  # Keep the clone if it is needed to draw the x axis

        # For-loop: All nuisances
        for i in range(0, myMaxSize):
            p = c.cd(i + 1)

            # Find plot
            myPlotIndex = None
            for j in range(0, len(self._systNameList)):
                if myAllShapeNuisances[i] == self._systNameList[j]:
                    myPlotIndex = j
            plot = None
            if myPlotIndex != None:
                plot = self._ratioPlotList[myPlotIndex].getFrame2()
            else:
                if i == myMaxSize - 1:
                    plot = myEmptyPlot  # Use this to draw the x axis
                else:
                    plot = self._ratioPlotList[0].getFrame2(
                    )  # Only the empty frame matters

            # Draw plot
            if i == myMaxSize - 1:
                # Bottom histogram
                plot.GetXaxis().SetTitleOffset(0.6 * myMaxSize +
                                               0.6)  # 6.6/10, 3.6/5
            else:
                plot.GetXaxis().SetTitleSize(0)
                plot.GetXaxis().SetLabelSize(0)
            plot.GetYaxis().SetLabelSize(26)
            plot.GetYaxis().SetTitleOffset(0.34 * myMaxSize +
                                           0.1)  # 3.5/10, 1.8/5
            plot.SetMinimum(0.601)  # 0.001
            plot.SetMaximum(1.399)  # 1.999

            # Plot frame for every nuisance
            plot.Draw()

            # Plot content only if affected
            if myPlotIndex != None:
                self._ratioPlotList[myPlotIndex].ratioHistoMgr.draw()
            self._ratioPlotList[0].ratioLine.Draw("L")
            p.RedrawAxis()

            # Labels for shape nuisance and dataset
            myHeight = 0.82
            if i == 0:
                myHeight = myHeight * float(_cBodyHeight) / float(
                    _cHeaderHeight + _cBodyHeight)
            elif i == myMaxSize - 1:
                myHeight = (myHeight * float(_cBodyHeight) +
                            float(_cFooterHeight)) / float(_cFooterHeight +
                                                           _cBodyHeight)
            histograms.addText(x=0.18,
                               y=myHeight,
                               text=myAllShapeNuisances[i],
                               size=30)

            myHeight = 0.08
            if i == 0:
                myHeight = myHeight * float(_cBodyHeight) / float(
                    _cHeaderHeight + _cBodyHeight)
            elif i == myMaxSize - 1:
                myHeight = (myHeight * float(_cBodyHeight) +
                            float(_cFooterHeight)) / float(_cFooterHeight +
                                                           _cBodyHeight)
            histograms.addText(x=0.93,
                               y=myHeight,
                               text=self._dsetName,
                               size=30,
                               align="right")

            # Header labels
            if i == 0:
                histograms.addStandardTexts(lumi=luminosity,
                                            cmsTextPosition="outframe")

            # Labels for non-existing nuisances
            if myPlotIndex == None:
                myHeight = 0.44
                if i == 0:
                    myHeight = myHeight * float(_cBodyHeight) / float(
                        _cHeaderHeight + _cBodyHeight)
                elif i == myMaxSize - 1:
                    myHeight = (myHeight * float(_cBodyHeight) +
                                float(_cFooterHeight)) / float(_cFooterHeight +
                                                               _cBodyHeight)
                histograms.addText(x=0.555,
                                   y=myHeight,
                                   text="Not affected",
                                   size=30,
                                   align="center")

        # Save plot
        plotName = "shapeSystRatioOnlyAll_%s" % (self._dsetName)
        saveName = os.path.join(opts.dirName, plotName)
        backup = ROOT.gErrorIgnoreLevel
        ROOT.gErrorIgnoreLevel = ROOT.kError
        # For-loop: All formats to save
        for i, ext in enumerate([".png", ".C", ".eps"], 1):
            fName = saveName + ext
            c.Print(fName)
            msg = "Created file %s" % (ShellStyles.SuccessStyle() + fName +
                                       ShellStyles.NormalStyle())
            self.Verbose(msg, i == 1)
        ROOT.gErrorIgnoreLevel = backup
        return
示例#5
0
def doPlot(opts, mass, nameList, allShapeNuisances, luminosity,
           myDatacardPattern, rootFilePattern, signalTable):
    fName = rootFilePattern % mass
    f = ROOT.TFile.Open(fName)

    content = f.GetListOfKeys()
    # Suppress the warning message of missing dictionary for some iterator
    backup = ROOT.gErrorIgnoreLevel
    ROOT.gErrorIgnoreLevel = ROOT.kError
    diriter = content.MakeIterator()
    ROOT.gErrorIgnoreLevel = backup

    # Find the datacard and nuisance names
    myCardReader = DatacardReader.DataCardReader(".", mass, myDatacardPattern,
                                                 rootFilePattern)
    myDatasetNames = myCardReader.getDatasetNames()

    # Find the name stem and the name of the uncertainties
    datasets = []
    shapes = []
    for d in myDatasetNames:
        myLabel = d
        myStatus = not d in nameList
        if d == myDatasetNames[0]:
            myStatus = True
            if not str(mass) in d:
                myLabel = "%sm%d" % (d, mass)

        myShapeNuisanceNames = myCardReader.getShapeNuisanceNames(d)
        myFilteredShapeNuisances = []
        for n in myShapeNuisanceNames:
            if not "statBin" in n and not n.endswith(
                    "_statUp") and not n.endswith("_statDown"):
                myFilteredShapeNuisances.append(n)
        if myStatus:
            myDataset = DatasetContainer(column=d,
                                         label=myLabel,
                                         nuisances=myFilteredShapeNuisances,
                                         cardReader=myCardReader,
                                         verbose=opts.verbose)
            datasets.append(myDataset)
            nameList.append(d)
        for n in myFilteredShapeNuisances:
            if not n in shapes:
                shapes.append(n)

    rebinList = None
    if opts.h2tb:
        rebinList = systematics._dataDrivenCtrlPlotBinning[
            "LdgTetrajetMass_AfterAllSelections"]

    ## Do the actual plots
    myDsets = ["Hp%s" % (mass), "FakeB", "TT_GenuineB", "SingleTop_GenuineB"]
    for i, d in enumerate(datasets, 1):
        if d.GetName() not in myDsets:
            msg = "Skipping dataset %s" % (d.GetName())
            Print(ShellStyles.WarningStyle() + msg + ShellStyles.NormalStyle(),
                  False)
            continue
        if opts.verbose:
            d.debug()
        msg = "{:>10}, {:<20}".format("m = %d GeV" % (mass), d.GetName())
        if i < len(datasets):
            Print(
                ShellStyles.HighlightAltStyle() + msg +
                ShellStyles.NormalStyle(), False)
        else:
            Print(ShellStyles.SuccessStyle() + msg + ShellStyles.NormalStyle(),
                  False)

        d.doPlot(opts, shapes, f, mass, luminosity, signalTable, rebinList)
    Verbose("Closing ROOT file %s" % (fName), True)
    f.Close()
示例#6
0
    for counter, d in enumerate(myDirs, 1):
        msg = "{:<9} {:>3} {:<1} {:<3} {:<50}".format("Directory",
                                                      "%i" % counter, "/",
                                                      "%i:" % len(myDirs),
                                                      "%s" % d)
        Print(
            ShellStyles.HighlightAltStyle() + msg + ShellStyles.NormalStyle(),
            counter == 1)
        myResults.append(Result(opts, d))

        # Inform user of success
        msg = "{:<9} {:>3} {:<1} {:<3} {:<50}".format("Directory",
                                                      "%i" % counter, "/",
                                                      "%i:" % len(myDirs),
                                                      "Success")
        Print(ShellStyles.SuccessStyle() + msg + ShellStyles.NormalStyle(),
              True)

    Verbose("The results are stored in the following directories:",
            counter == 1)
    for i, r in enumerate(myResults, 1):
        msg = str(i) + ") " + r.getBaseDir()
        Verbose(msg, False)

    if 0:
        Print("Printing results for all directories:", True)
        for r in myResults:
            r.printResultsAlt()
    else:
        Verbose("Printing results for all directories:", True)
        r.printResults(unblindedStatus=opts.unblinded, nDigits=opts.precision)
os.chdir(output_directory_name)
for filename in filenames:
    if "datacard" in filename and ".txt" in filename:
        datacard_names.append(filename)
if len(datacard_names) == 0:
    Print("No datacards found in input directory", True)
    sys.exit(1)

# remove old Combine output and limits from copied directory
#os.system("rm -rf CombineResults*")

Verbose("Looping over datacards:", True)
# For-loop: All  datacards (replace bin-by-bin uncertainties with Barlow-Beeston command)
for i, dcard_name in enumerate(datacard_names, 1):
    Print("Processing %s" % dcard_name, i == 1)
    f_in = file("../" + input_path + "/" + dcard_name)

    with open(dcard_name, "w") as f:
        # For-loop: All lines in open file
        for line in f_in:
            if "kmax" in line:
                f.write("kmax     *     number of parameters\n")
            elif not "statBin" in line:
                f.write(line)
        f.write("\n\n* autoMCStats 0")
        f.truncate()

dirName = ShellStyles.SuccessStyle(
) + output_directory_name + ShellStyles.NormalStyle()
Print("Barlow-Beeston datacards stored in directory %s" % (dirName), True)
示例#8
0
def main(opts):

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

    # 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]

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

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

        if 0:
            datasetsMgr.printSelections()

        # Print PSets used for FakeBMeasurement
        if 0:
            datasetsMgr.printSelections()
            PrintPSet("BJetSelection", datasetsMgr)
            PrintPSet("TopSelectionBDT", datasetsMgr)
            PrintPSet("FakeBMeasurement", datasetsMgr)
            sys.exit()

        # Set/Overwrite cross-sections
        for d in datasetsMgr.getAllDatasets():
            if "ChargedHiggs" in d.getName():
                datasetsMgr.getDataset(d.getName()).setCrossSection(1.0)

        if opts.verbose:
            datasetsMgr.PrintCrossSections()
            datasetsMgr.PrintLuminosities()
            datasetsMgr.PrintInfo()

        # Filter the datasets
        datasetsMgr.remove(
            filter(lambda name: "Charged" in name,
                   datasetsMgr.getAllDatasetNames()))
        # datasetsMgr.remove(filter(lambda name: "Charged" in name and not "M_500" in name, datasetsMgr.getAllDatasetNames()))

        # ZJets and DYJets overlap!
        if "ZJetsToQQ_HT600toInf" in datasetsMgr.getAllDatasetNames(
        ) and "DYJetsToQQ_HT180" in datasetsMgr.getAllDatasetNames():
            Print(
                "Cannot use both ZJetsToQQ and DYJetsToQQ due to duplicate events? Investigate. Removing ZJetsToQQ datasets for now ..",
                True)
            datasetsMgr.remove(
                filter(lambda name: "ZJetsToQQ" in name,
                       datasetsMgr.getAllDatasetNames()))

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

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

        # Re-order datasets (different for inverted than default=baseline)
        if 0:
            newOrder = ["Data"]
            newOrder.extend(aux.GetListOfEwkDatasets())
            datasetsMgr.selectAndReorder(newOrder)

        # Print post-merged data dataset summary
        datasetsMgr.PrintInfo()

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

        # Print post EWK-merge dataset summary
        datasetsMgr.PrintInfo()

        # Get all histograms from the  in the selected folder inside the ROOT files
        allHistos = datasetsMgr.getAllDatasets()[0].getDirectoryContent(
            opts.folder)
        hList = [
            h for h in allHistos if "CRSelections" in h and "_Vs" not in h
        ]
        hList.extend(
            [h for h in allHistos if "AllSelections" in h and "_Vs" not in h])
        # hList.extend([h for h in allHistos if "StandardSelections" in h and "_Vs" not in h])

        # Create a list with strings included in the histogram names you want to plot
        myHistos = [
            "LdgTrijetPt", "LdgTrijetMass", "TetrajetBJetPt",
            "TetrajetBJetEta", "LdgTetrajetPt", "LdgTetrajetMass", "MVAmax2",
            "MVAmax1", "HT", "MET"
        ]
        #myHistos = ["LdgTrijetPt", "LdgTrijetMass", "LdgTetrajetMass", "MVAmax2", "MVAmax1", "Njets", "NBjets",
        #            "Bjet3Bdisc", "Bjet2Bdisc", "Bjet1Bdisc", "Bjet3Pt", "Bjet2Pt", "Bjet1Pt"]

        # For-loop: All histos
        for i, h in enumerate(myHistos, 1):
            hGraphList = []
            for b in ["Baseline_", "Inverted_"]:
                #for r in ["_AfterAllSelections", "_AfterCRSelections"]:
                for r in ["_AfterCRSelections", "_AfterAllSelections"]:
                    histoName = b + h + r
                    hgQCD, kwargs = GetPurityHistoGraph(
                        datasetsMgr, opts.folder, histoName)

                    # Do not draw SR in multigraph plot!
                    if GetControlRegionLabel(histoName) != "SR":
                        hGraphList.append(hgQCD)

                    # Plot individual purity graphs?
                    if 0:
                        PlotHistoGraph(hgQCD, kwargs)

            msg = "{:<9} {:>3} {:<1} {:<3} {:<50}".format(
                "Histogram", "%i" % i, "/", "%s:" % (len(myHistos)), h)
            Print(ShellStyles.SuccessStyle() + msg + ShellStyles.NormalStyle(),
                  i == 1)
            PlotHistoGraphs(hGraphList, kwargs)

    Print(
        "All plots saved under directory %s" %
        (ShellStyles.NoteStyle() + aux.convertToURL(opts.saveDir, opts.url) +
         ShellStyles.NormalStyle()), True)
    return
def main(opts):

    # Apply TDR style
    style = tdrstyle.TDRStyle()
    style.setOptStat(False)
    style.setGridX(True)  #opts.gridX)
    style.setGridY(True)  #opts.gridY)
    style.setLogX(False)  #opts.logX)
    style.setLogY(False)  #opts.logY)

    # 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]

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

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

        if 0:
            datasetsMgr.printSelections()

        # Set/Overwrite cross-sections
        for d in datasetsMgr.getAllDatasets():
            if "ChargedHiggs" in d.getName():
                datasetsMgr.getDataset(d.getName()).setCrossSection(1.0)

        if opts.verbose:
            datasetsMgr.PrintCrossSections()
            datasetsMgr.PrintLuminosities()

        # Custom Filtering of datasets
        if 0:
            datasetsMgr.remove(
                filter(lambda name: "Charged" in name and not "M_500" in name,
                       datasetsMgr.getAllDatasetNames()))

        # ZJets and DYJets overlap!
        if "ZJetsToQQ_HT600toInf" in datasetsMgr.getAllDatasetNames(
        ) and "DYJetsToQQ_HT180" in datasetsMgr.getAllDatasetNames():
            Print(
                "Cannot use both ZJetsToQQ and DYJetsToQQ due to duplicate events? Investigate. Removing ZJetsToQQ datasets for now ..",
                True)
            datasetsMgr.remove(
                filter(lambda name: "ZJetsToQQ" in name,
                       datasetsMgr.getAllDatasetNames()))

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

        # Get Luminosity
        if opts.intLumi < 0.0:
            if "Data" in datasetsMgr.getAllDatasetNames():
                opts.intLumi = datasetsMgr.getDataset("Data").getLuminosity()
            else:
                opts.intLumi = 1.0

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

        # Print dataset information
        datasetsMgr.PrintInfo()

        # Get all histogram names in the given ROOT folder
        histoNames = datasetsMgr.getAllDatasets()[0].getDirectoryContent(
            opts.folder)
        histoList = [
            os.path.join(opts.folder, h) for h in histoNames if "_SR" in h
        ]

        # For-loop: All histos in SR
        nHistos = len(histoList)
        for i, h in enumerate(histoList, 1):

            msg = "{:<9} {:>3} {:<1} {:<3} {:<50}".format(
                "Histogram", "%i" % i, "/", "%s:" % (nHistos), h)
            Print(ShellStyles.SuccessStyle() + msg + ShellStyles.NormalStyle(),
                  i == 1)
            PlotHistograms(datasetsMgr, h)

    # Inform user where the plots where saved
    Print(
        "All plots saved under directory %s" %
        (ShellStyles.NoteStyle() + aux.convertToURL(opts.saveDir, opts.url) +
         ShellStyles.NormalStyle()), True)
    return
import ROOT
ROOT.gROOT.SetBatch(True)
ROOT.PyConfig.IgnoreCommandLineOptions = True

import HiggsAnalysis.NtupleAnalysis.tools.dataset as dataset
import HiggsAnalysis.NtupleAnalysis.tools.plots as plots
import HiggsAnalysis.NtupleAnalysis.tools.aux as aux
import HiggsAnalysis.NtupleAnalysis.tools.analysisModuleSelector as analysisModuleSelector
import HiggsAnalysis.NtupleAnalysis.tools.ShellStyles as ShellStyles
import HiggsAnalysis.NtupleAnalysis.tools.pseudoMultiCrabCreator as pseudoMultiCrabCreator

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


#================================================================================================
# Class Definition
#================================================================================================
class NewShape:
    '''
    Container class for information of data and MC at certain point of the selection flow
    '''
    def __init__(self,
                 dsetMgr,