示例#1
0
def createBinnedFitUncertaintyHistograms(hRate, hUp, hDown, applyFrom, opts):
    hupList = []
    hDownList = []
    # find bin
    myFirstBin = hRate.GetXaxis().FindBin(applyFrom + 0.0001)
    for i in range(myFirstBin, hRate.GetNbinsX() + 1):
        hup = aux.Clone(
            hRate,
            "%s_%s_fitBinByBin%dUp" % (hRate.GetTitle(), hRate.GetTitle(), i))
        hup.SetTitle(hup.GetName())
        hdown = aux.Clone(
            hRate, "%s_%s_fitBinByBin%dDown" %
            (hRate.GetTitle(), hRate.GetTitle(), i))
        hup.SetTitle(hdown.GetName())
        for j in range(1, hRate.GetNbinsX() + 1):
            hup.SetBinError(j, 0.0)
            hdown.SetBinError(j, 0.0)
        if opts.doubleFitUncert:
            hup.SetBinContent(
                i, (hUp.GetBinContent(i) - hRate.GetBinContent(i)) * 2.0 +
                hRate.GetBinContent(i))
            hdown.SetBinContent(
                i, (hDown.GetBinContent(i) - hRate.GetBinContent(i)) * 2.0 +
                hRate.GetBinContent(i))
        else:
            hup.SetBinContent(i, hUp.GetBinContent(i))
            hdown.SetBinContent(i, hDown.GetBinContent(i))
        if hDown.GetBinContent(i) < 0.0:
            hdown.SetBinContent(i, 0.0)
        hupList.append(hup)
        hDownList.append(hdown)
    # Return histogram lists
    return (hupList, hDownList)
    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
示例#3
0
 def calculateTotalVariationHistograms(self, hRate, hup, hdown):
     # Create empty histogram templates
     hFitUncertaintyUpTotal = aux.Clone(hup[0], self._label + "_TailFitUp")
     hFitUncertaintyDownTotal = aux.Clone(hup[0],
                                          self._label + "_TailFitDown")
     hFitUncertaintyUpTotal.Reset()  # clean bin contents and errors
     hFitUncertaintyDownTotal.Reset()  # clean bin contents and errors
     for i in range(1, hup[0].GetNbinsX() + 1):
         myPedestal = hRate.GetBinContent(i)
         myVarianceUp = 0.0
         myVarianceDown = 0.0
         for j in range(0, len(hup)):
             a = 0.0
             b = 0.0
             if hup[j].GetBinContent(i) > 0.0:
                 a = hup[j].GetBinContent(i) - myPedestal
             else:
                 a = -myPedestal
             if hdown[j].GetBinContent(i) > 0.0:
                 b = hdown[j].GetBinContent(i) - myPedestal
             else:
                 b = -myPedestal
             if abs(a) != float('Inf') and not math.isnan(
                     a) and abs(b) != float('Inf') and not math.isnan(b):
                 (varA,
                  varB) = aux.getProperAdditivesForVariationUncertainties(
                      a, b)  # essentially squaring a and b
                 myVarianceUp += varA
                 myVarianceDown += varB
         hFitUncertaintyUpTotal.SetBinContent(
             i, myPedestal + math.sqrt(myVarianceUp))
         hFitUncertaintyDownTotal.SetBinContent(
             i, myPedestal - math.sqrt(myVarianceDown))
     return (hFitUncertaintyUpTotal, hFitUncertaintyDownTotal)
示例#4
0
    def _obtainShapeHistograms(self, i, dataPath, ewkPath, dsetMgr, plotName, luminosity, normFactors):
        self.Verbose("_obtainShapeHistograms()", True)

        if self._verbose:
            self.PrintShapeInputSummary(dataPath, ewkPath, dsetMgr, plotName, luminosity, normFactors)

        self.Verbose("Obtain the (pre-normFactor) shape %s as \"DataDrivenQCDShape\" type object" % (plotName), True) 
        myShape = dataDrivenQCDCount.DataDrivenQCDShape(dsetMgr, "Data", "EWK", plotName, dataPath, ewkPath, luminosity, self._useInclusiveNorm, self._verbose)
        
        if self._verbose:
            msg = "Printing TH1s (before NormFactors) of \"Data\", \"Data-Driven QCD\", \"EWK\",  and \"Bin-by\Bin Purity\" and \"Integrated Purity\""
            self.Print(msg, True)
            PrintTH1Info(myShape.getIntegratedDataHisto())
            PrintTH1Info(myShape.getIntegratedDataDrivenQCDHisto()) #Data-EWK. NormFactor not applied
            PrintTH1Info(myShape.getIntegratedEwkHisto())
            PrintTH1Info(myShape.getPurityHisto())  # Splitted-bin (disabled for Inclusive mode)
            PrintTH1Info(myShape.getIntegratedPurityForShapeHisto())        
            self.PrintShapePuritySummary(myShape)
        
        self.Verbose("Obtain the (post-normFactor) shape %s as \"QCDInvertedShape\" type object (Takes \"DataDrivenQCDShape\" type object as argument)" % (plotName), True)
        moduleInfo = self._moduleInfoString + "_" + plotName
        myPlot= QCDInvertedShape(myShape, moduleInfo, normFactors, optionUseInclusiveNorm=self._useInclusiveNorm)
        myPlot.PrintSettings(printHistos=self._verbose, verbose=self._verbose)

        # Define histogram name as will be written in the ROOT file
        self.Verbose("%sDefining the name of histogram objects, as they will appear in the ROOT file%s" % (ShellStyles.WarningStyle(), ShellStyles.NormalStyle()), True)
        hName  = plotName + "%d" %i
        hTitle = plotName.replace("CRSelections", "AllSelections").replace("Baseline_", "").replace("Inverted_", "")#FIXME: not elegant!

        # DataDriven
        myShape.delete()
        myPlotHisto = aux.Clone(myPlot.getResultShape(), "ctrlPlotShapeInManager")
        myPlot.delete()
        myPlotHisto.SetName(hName)
        myPlotHisto.SetTitle(hTitle)
        self._shapePlots.append(myPlotHisto)
        self._shapePlotLabels.append(myPlotHisto.GetTitle())# this is the name the object will have in the ROOT file

        # MC EWK
        hName  = plotName + "%d_MCEWK" %i
        myPlotMCEWKHisto = aux.Clone(myPlot.getResultMCEWK(), "ctrlPlotMCEWKInManager")
        myPlotMCEWKHisto.SetName(hName) 
        myPlotMCEWKHisto.SetTitle(hTitle + "_MCEWK")
        self._shapePlots.append(myPlotMCEWKHisto)
        self._shapePlotLabels.append(myPlotMCEWKHisto.GetTitle())# this is the name the object will have in the ROOT file

        # Purity
        hName  = plotName + "%d_Purity" %i
        #self.Print("myPlot.getResultPurity().GetName() = %s" % myPlot.getResultPurity().GetName(), True)
        #self.Print("myPlot.getResultPurity().GetIntegral() = %s" % myPlot.getResultPurity().Integral(), True)

        myPlotPurityHisto = aux.Clone(myPlot.getResultPurity(), "ctrlPlotPurityInManager")
        myPlotPurityHisto.SetName(hName)
        myPlotPurityHisto.SetTitle(hTitle + "_Purity")
        self._shapePlots.append(myPlotPurityHisto)
        self._shapePlotLabels.append(myPlotPurityHisto.GetTitle())# this is the name the object will have in the ROOT file
        return myPlotHisto
示例#5
0
 def _createHistograms(self,data,expectedList):
     for e in expectedList:
         self._expectedList.append(aux.Clone(self._hFrame))
         self._expectedList[len(self._expectedList)-1].Reset()
         self._expectedListSystUp.append(aux.Clone(self._hFrame))
         self._expectedListSystUp[len(self._expectedListSystUp)-1].Reset()
         self._expectedListSystDown.append(aux.Clone(self._hFrame))
         self._expectedListSystDown[len(self._expectedListSystDown)-1].Reset()
         self._expectedLabelList.append(e.name)
     self._data = aux.Clone(self._hFrame)
     self._data.Reset()
 def _obtainQCDNormalizationSystHistograms(self, shapeHisto, dsetMgr,
                                           plotName, luminosity,
                                           normDataSrc, normEWKSrc):
     print ShellStyles.HighlightStyle(
     ) + "...Obtaining region transition systematics" + ShellStyles.NormalStyle(
     )
     myPlotSignalRegionShape = dataDrivenQCDCount.DataDrivenQCDShape(
         dsetMgr=dsetMgr,
         dsetLabelData="Data",
         dsetLabelEwk="EWK",
         histoName=plotName,
         dataPath=normDataSrc + "QCDNormalizationSignal",
         ewkPath=normEWKSrc + "QCDNormalizationSignal",
         luminosity=luminosity)
     myPlotControlRegionShape = dataDrivenQCDCount.DataDrivenQCDShape(
         dsetMgr=dsetMgr,
         dsetLabelData="Data",
         dsetLabelEwk="EWK",
         histoName=plotName,
         dataPath=normDataSrc + "QCDNormalizationControl",
         ewkPath=normEWKSrc + "QCDNormalizationControl",
         luminosity=luminosity)
     myPlotRegionTransitionSyst = metSyst.SystematicsForMetShapeDifference(
         myPlotSignalRegionShape,
         myPlotControlRegionShape,
         shapeHisto,
         moduleInfoString=self._moduleInfoString,
         quietMode=True)
     myPlotSignalRegionShape.delete()
     myPlotControlRegionShape.delete()
     # Store up and down variations
     #hUp = aux.Clone(myPlotRegionTransitionSyst.getUpHistogram(), "QCDfactMgrSystQCDSystUp%d"%i)
     #hUp.SetTitle(plotName+"systQCDUp")
     #self._QCDNormalizationSystPlots.append(hUp)
     #self._QCDNormalizationSystPlotLabels.append(hUp.GetTitle())
     #hDown = aux.Clone(myPlotRegionTransitionSyst.getDownHistogram(), "QCDfactMgrSystQCDSystDown%d"%i)
     #hDown.SetTitle(plotName+"systQCDDown")
     #self._QCDNormalizationSystPlots.append(hDown)
     #self._QCDNormalizationSystPlotLabels.append(hDown.GetTitle())
     # Store source histograms
     hNum = aux.Clone(
         myPlotRegionTransitionSyst.getCombinedSignalRegionHistogram(),
         "QCDfactMgrSystQCDSystNumerator")
     hNum.SetTitle(plotName + "systQCDNumerator")
     self._QCDNormalizationSystPlots.append(hNum)
     self._QCDNormalizationSystPlotLabels.append(hNum.GetTitle())
     hDenom = aux.Clone(
         myPlotRegionTransitionSyst.getCombinedCtrlRegionHistogram(),
         "QCDfactMgrSystQCDSystDenominator")
     hDenom.SetTitle(plotName + "systQCDDenominator")
     self._QCDNormalizationSystPlots.append(hDenom)
     self._QCDNormalizationSystPlotLabels.append(hDenom.GetTitle())
     # Free memory
     myPlotRegionTransitionSyst.delete()
示例#7
0
    def getIntegratedDataDrivenQCDHisto(self):
        '''
        Return the sum of data-ewk integrated over the phase space splitted bins
        '''

        # 1) Do the "Inclusive" histogram (here I assume that the first in the list is the inclusive)
        h = aux.Clone(self._dataList[0])
        histoName = "_".join(h.GetName().split(
            "_", 2)[:2]) + "_DataMinusEWK_Integrated"
        # histoName = h.GetName()+"Integrated" #original code
        h.SetName(histoName)
        # Subtract the EWK histo from Data histo (QCD=Data-EWK)
        h.Add(self._ewkList[0], -1.0)

        # 2) Do the bin-by-bin histograms
        # For-loop: All data histos
        for i in range(1,
                       len(self._dataList)):  # starts from bin #1 (not zero)
            # Bin-by-bin mode has not been validated by me yet
            print "FIXME " * 20

            h.Add(self._dataList[i])
            # Subtract the EWK histo from Data histo (QCD=Data-EWK)
            h.Add(self._ewkList[i], -1.0)
        return h
示例#8
0
 def getDataDrivenQCDHistoForSplittedBin(self, binIndex):
     if binIndex >= len(self._dataList):
         raise Exception(ShellStyles.ErrorLabel()+"DataDrivenQCDShape::getDataDrivenQCDForSplittedBin: requested bin index %d out of range (0-%d)!"%(binIndex,len(self._dataList)))
     h = aux.Clone(self._dataList[binIndex])
     h.SetName(h.GetName()+"dataDriven")
     h.Add(self._ewkList[binIndex], -1.0)
     return h
示例#9
0
 def _obtainShapeHistograms(self, i, dataPath, ewkPath, dsetMgr, plotName, luminosity, normFactors):
     myShape = dataDrivenQCDCount.DataDrivenQCDShape(dsetMgr=dsetMgr,
                                                     dsetLabelData="Data",
                                                     dsetLabelEwk="EWK",
                                                     histoName=plotName,
                                                     dataPath=dataPath,
                                                     ewkPath=ewkPath,
                                                     luminosity=luminosity)
     myPlot = QCDInvertedShape(myShape,
                               self._moduleInfoString+"_"+plotName,
                               normFactors,
                               optionUseInclusiveNorm=self._useInclusiveNorm)
     myShape.delete()
     myPlotHisto = aux.Clone(myPlot.getResultShape(), "ctrlPlotShapeInManager")
     myPlot.delete()
     myPlotHisto.SetName(plotName+"%d"%i)
     myPlotHisto.SetTitle(plotName)
     self._shapePlots.append(myPlotHisto)
     self._shapePlotLabels.append(plotName)
     # MC EWK and purity
     #myPlotMCEWKHisto = aux.Clone(myPlot.getResultMCEWK(), "ctrlPlotMCEWKInManager")
     #myPlotMCEWKHisto.SetName(plotName+"%d_MCEWK"%i)
     #myPlotMCEWKHisto.SetTitle(plotName+"_MCEWK")
     #self._shapePlots.append(myPlotMCEWKHisto)
     #self._shapePlotLabels.append(myPlotMCEWKHisto.GetTitle())
     #myPlotPurityHisto = aux.Clone(myPlot.getResultPurity(), "ctrlPlotPurityInManager")
     #myPlotPurityHisto.SetName(plotName+"%d_Purity"%i)
     #myPlotPurityHisto.SetTitle(plotName+"_Purity")
     #self._shapePlots.append(myPlotPurityHisto)
     #self._shapePlotLabels.append(myPlotPurityHisto.GetTitle())
     return myPlotHisto
    def getIntegratedDataDrivenQCDHisto(self):
        '''
        Return the sum of data-ewk integrated over the phase space splitted bins
        '''
        # Do the "Inclusive" histogram (here I assume that the first in the list is the inclusive)
        h = aux.Clone(self._dataList[0])
        histoName = "_".join(h.GetName().split(
            "_", 2)[:2]) + "_DataDriven_Integrated"
        h.SetName(histoName)
        self.Verbose(
            "Cloned histo %s from histo %s" %
            (h.GetName(), self._dataList[0].GetName()), True)

        # Subtract the EWK histo from Data histo (QCD=Data-EWK)
        self.Verbose(
            "Subtracting histo %s from histo %s" %
            (self._ewkList[0].GetName(), h.GetName()), False)
        h.Add(self._ewkList[0], -1.0)

        # For-loop: All data histos [N.B. Starts from bin 1 (not 0=inclusive) ]
        for i in range(1, len(self._dataList)):

            msg = "Splitted-bin mode has not been validated yet"
            #raise Exception(ShellStyles.ErrorStyle() + msg + ShellStyles.NormalStyle())

            # Accumulate given bin-histo from Data
            h.Add(self._dataList[i])

            # Subtract given bin-histo from EWK
            h.Add(self._ewkList[i], -1.0)
        return h
    def _obtainHistograms(self, i, dsetMgr, plotName, luminosity):
        self.Verbose(
            "Obtain histogram %s as \"NewShape\" type object" % (plotName),
            True)
        myShape = NewShape(dsetMgr, opts.newDsetName, opts.dsetsToMerge,
                           self._moduleInfoString, plotName, luminosity,
                           self._verbose)
        myPlot = myShape.getIntegratedNewDsetHisto(
        )  #myPlot = myShape.getIntegratedEwkHisto()
        if self._verbose:
            aux.PrintTH1Info(myPlot)

        self.Verbose(
            "Cloning histogram %s, settting name and title" % (plotName), True)
        saveName = "%s_%d" % (plotName, i)
        myPlotHisto = aux.Clone(myPlot)
        myPlotHisto.SetName(saveName)
        myPlotHisto.SetTitle(plotName)

        # Append the plot to the list. The plot title is the name the object will saved as in the ROOT file
        saveName = myPlotHisto.GetTitle()
        self.Verbose(
            "Saving histogram %s for dataset %s" %
            (saveName, opts.newDsetName), i == 1)
        if self._verbose:
            aux.PrintTH1Info(myPlotHisto)
        self._myPlots.append(myPlotHisto)
        self._myPlotLabels.append(saveName)

        # Delete objects from memory
        # myPlot.delete()
        myShape.delete()

        return myPlotHisto
    def _obtainShapeHistograms(self, i, dataPath, ewkPath, dsetMgr, plotName, luminosity, normFactors):
        Verbose("_obtainShapeHistograms()", True)

        if self._verbose:
            self.PrintShapeInputSummary(dataPath, ewkPath, dsetMgr, plotName, luminosity, normFactors)
        
        Verbose("Obtain the (pre-normFactor) shape %s as \"DataDrivenQCDShape\" type object" % (plotName), True) 
        myShape = dataDrivenQCDCount.DataDrivenQCDShape(dsetMgr, "Data", "EWK", plotName, dataPath, ewkPath, luminosity, self._useInclusiveNorm) #pre-normFactor

        if self._verbose:
            msg = "Printing TH1s (before NormFactors) of \"Data\", \"Data-Driven QCD\", \"EWK\",  and \"Bin-by\Bin Purity\" and \"Integrated Purity\""
            Print(msg, True)
            PrintTH1Info(myShape.getIntegratedDataHisto())
            PrintTH1Info(myShape.getIntegratedDataDrivenQCDHisto()) #Data-EWK. NormFactor not applied
            PrintTH1Info(myShape.getIntegratedEwkHisto())
            PrintTH1Info(myShape.getPurityHisto())
            PrintTH1Info(myShape.getIntegratedPurityForShapeHisto())

        if self._verbose:
            self.PrintShapePuritySummary(myShape)
        
        Verbose("Obtain the (post-normFactor) shape %s as \"QCDInvertedShape\" type object (Takes \"DataDrivenQCDShape\" type object as argument)" % (plotName), True)
        moduleInfo = self._moduleInfoString + "_" + plotName
        myPlot     = QCDInvertedShape(myShape, moduleInfo, normFactors, optionUseInclusiveNorm=self._useInclusiveNorm)
        myPlot.PrintSettings(printHistos=self._verbose, verbose=self._verbose)

        myShape.delete()
        myPlotHisto = aux.Clone(myPlot.getResultShape(), "ctrlPlotShapeInManager")
        myPlot.delete()
        myPlotHisto.SetName(plotName+"%d"%i)
        myPlotHisto.SetTitle(plotName)
        self._shapePlots.append(myPlotHisto)
        self._shapePlotLabels.append(plotName)

        # MC EWK and purity
        myPlotMCEWKHisto = aux.Clone(myPlot.getResultMCEWK(), "ctrlPlotMCEWKInManager")
        myPlotMCEWKHisto.SetName(plotName+"%d_MCEWK"%i)
        myPlotMCEWKHisto.SetTitle(plotName+"_MCEWK")
        self._shapePlots.append(myPlotMCEWKHisto)
        self._shapePlotLabels.append(myPlotMCEWKHisto.GetTitle())
        myPlotPurityHisto = aux.Clone(myPlot.getResultPurity(), "ctrlPlotPurityInManager")
        myPlotPurityHisto.SetName(plotName+"%d_Purity"%i)
        myPlotPurityHisto.SetTitle(plotName+"_Purity")
        self._shapePlots.append(myPlotPurityHisto)
        self._shapePlotLabels.append(myPlotPurityHisto.GetTitle())
        return myPlotHisto
示例#13
0
 def getIntegratedDataDrivenQCDHisto(self):
     h = aux.Clone(self._dataList[0])
     h.SetName(h.GetName()+"Integrated")
     h.Add(self._ewkList[0],-1.0)
     for i in range(1, len(self._dataList)):
         h.Add(self._dataList[i])
         h.Add(self._ewkList[i],-1.0)
     return h
 def getDataHistoForSplittedBin(self, binIndex):
     '''
     Return the data in a given phase space split bin
     '''
     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
             h.SetName(h.GetName() + "_")  #new
             return h  #new
         msg = "Requested bin index %d out of range (0-%d)!" % (
             binIndex, len(self._dataList))
         raise Exception(ShellStyles.ErrorLabel() + msg +
                         ShellStyles.NormalStyle())
     h = aux.Clone(self._dataList[binIndex])
     h.SetName(h.GetName() + "_")
     return h
 def getIntegratedEwkHisto(self):
     '''
     Return the sum of ewk integrated over the phase space splitted bins
     '''
     h = aux.Clone(self._histoList[0])
     h.SetName("_".join(h.GetName().split("_", 2)[:2]) + "_EWK_Integrated")
     for i in range(1, len(self._histoList)):
         h.Add(self._histoList[i])
     return h
 def getIntegratedDataHisto(self):
     '''
     Return the sum of data integrated over the phase space splitted bins
     '''
     h = aux.Clone(self._dataList[0])
     #h.SetName(h.GetName()+"Integrated") #original code
     h.SetName("_".join(h.GetName().split("_", 2)[:2]) + "_Data_Integrated")
     for i in range(1, len(self._dataList)):
         h.Add(self._dataList[i])
     return h
示例#17
0
 def getEwkHistoForSplittedBin(self, binIndex):
     '''
     Return the EWK MC in a given phase space split bin
     '''
     if binIndex >= len(self._dataList):
         raise Exception(
             ShellStyles.ErrorLabel() +
             "DataDrivenQCDShape::getEwkHistoForSplittedBin: requested bin index %d out of range (0-%d)!"
             % (binIndex, len(self._ewkList)))
     h = aux.Clone(self._ewkList[binIndex])
     h.SetName(h.GetName() + "_")
     return h
示例#18
0
 def calculateTotalVariationHistograms(self, hRate, hup, hdown):
     # Calculate total uncertainty (only for reference, note that can give also negative results)
     hFitUncertaintyUpTotal = aux.Clone(hup[0], self._label + "_TailFitUp")
     hFitUncertaintyUpTotal.Reset()
     hFitUncertaintyDownTotal = aux.Clone(hup[0],
                                          self._label + "_TailFitDown")
     hFitUncertaintyDownTotal.Reset()
     for i in range(1, hup[0].GetNbinsX() + 1):
         myPedestal = hRate.GetBinContent(i)
         myVarianceUp = 0.0
         myVarianceDown = 0.0
         for j in range(0, len(hup)):
             a = 0.0
             b = 0.0
             #if hup[j].GetBinContent(i) > 1e-10:
             #a = hup[j].GetBinContent(i) - myPedestal
             #if hdown[j].GetBinContent(i) > 1e-10:
             #b = hdown[j].GetBinContent(i) - myPedestal
             if hup[j].GetBinContent(i) > 0.0:
                 a = hup[j].GetBinContent(i) - myPedestal
             else:
                 a = -myPedestal
             if hdown[j].GetBinContent(i) > 0.0:
                 b = hdown[j].GetBinContent(i) - myPedestal
             else:
                 b = -myPedestal
             if abs(a) != float('Inf') and not math.isnan(
                     a) and abs(b) != float('Inf') and not math.isnan(b):
                 (varA,
                  varB) = aux.getProperAdditivesForVariationUncertainties(
                      a, b)
                 myVarianceUp += varA
                 myVarianceDown += varB
             #print j,hup[j].GetBinContent(i),hdown[j].GetBinContent(i),a,b,varA,varB
         #print self._hFitFineBinning.GetXaxis().GetBinLowEdge(i),":", myPedestal,math.sqrt(myVarianceUp), math.sqrt(myVarianceDown), myPedestal+math.sqrt(myVarianceUp), myPedestal-math.sqrt(myVarianceDown)
         hFitUncertaintyUpTotal.SetBinContent(
             i, myPedestal + math.sqrt(myVarianceUp))
         hFitUncertaintyDownTotal.SetBinContent(
             i, myPedestal - math.sqrt(myVarianceDown))
     return (hFitUncertaintyUpTotal, hFitUncertaintyDownTotal)
示例#19
0
    def __init__(self,
                 h,
                 label,
                 fitFuncName,
                 fitmin,
                 fitmax,
                 applyFitFrom,
                 doPlots=False,
                 luminosity=None):
        self._label = label
        self._fittedRate = None
        self._centralParams = None
        self._eigenVectors = None
        self._eigenValues = None
        self._fitmin = fitmin
        self._hRate = aux.Clone(h)
        self._luminosity = luminosity

        # Initialize style
        myStyle = tdrstyle.TDRStyle()
        myStyle.setOptStat(True)
        myStyle.tdrStyle.SetOptFit(True)

        # Find fit function class
        scaleFactor = h.Integral(h.FindBin(fitmin), h.GetNbinsX() + 1) * 1.01
        self._myFitFuncObject = self._findFitFunction(fitFuncName, scaleFactor)
        # Obtain bin list for fine binning (compatibility with fine binning)
        myBinList = []
        for i in range(1, h.GetNbinsX() + 1):
            myBinList.append(h.GetXaxis().GetBinLowEdge(i))
        myBinList.append(h.GetXaxis().GetBinUpEdge(h.GetNbinsX()))
        # Do fit
        myFitResult = self._doFit(h, myBinList, fitFuncName, fitmin, fitmax)
        # Calculate eigenvectors and values
        self._calculateEigenVectorsAndValues(myFitResult, printStatus=True)

        # Create histograms and control plots
        if doPlots:
            (hFitUncertaintyUp,
             hFitUncertaintyDown) = self.calculateVariationHistograms(
                 myBinList, applyFitFrom)
            self.makeVariationPlotDetailed("FineBinning", self._hRate,
                                           self._hFitFineBinning,
                                           hFitUncertaintyUp,
                                           hFitUncertaintyDown)
            (hupTotal, hdownTotal) = self.calculateTotalVariationHistograms(
                self._hFitFineBinning, hFitUncertaintyUp, hFitUncertaintyDown)
            self.makeVariationPlotSimple("FineBinning", self._hRate,
                                         self._hFitFineBinning, hupTotal,
                                         hdownTotal)
示例#20
0
def getAndRebinQCDShapeNuisanceHistos(columnName, rootFile, hRate,
                                      nuisanceInfo, binlist):
    if not "QCD" in columnName:
        return []
    myHistograms = []
    # Loop over nuisance info
    for n in nuisanceInfo:
        if n["distribution"] == "shape" and n[
                columnName] == "1" and "QCD_metshape" in n["name"]:
            # Obtain numerator and denominator
            myNumName = "%s_QCD_metshapeSource_Numerator" % (columnName)
            myDenomName = "%s_QCD_metshapeSource_Denominator" % (columnName)
            hNum = rootFile.Get(myNumName)
            if hNum == None:
                raise Exception(ErrorLabel() +
                                "Cannot find histogram '%s'!" % myNumName)
            hDenom = rootFile.Get(myDenomName)
            if hDenom == None:
                raise Exception(ErrorLabel() +
                                "Cannot find histogram '%s'!" % myDenomName)
            myArray = array.array("d", binlist)
            hDenomRebinned = hDenom.Rebin(len(myArray) - 1, "", myArray)
            hNumRebinned = hNum.Rebin(len(myArray) - 1, "", myArray)
            hDenom.Delete()
            hNum.Delete()
            # Create output histograms
            hUp = aux.Clone(hRate, "%s_QCD_metshapeUp" % columnName)
            hDown = aux.Clone(hRate, "%s_QCD_metshapeDown" % columnName)
            hUp.Reset()
            hDown.Reset()
            # Calculate
            systematicsForMetShapeDifference.createSystHistograms(
                hRate, hUp, hDown, hNumRebinned, hDenomRebinned)
            myHistograms.append(hUp)
            myHistograms.append(hDown)
    return myHistograms
    def getIntegratedPurityForShapeHisto(self):
        '''
        Return the QCD purity in bins of the final shape
        '''
        hData = self.getIntegratedDataHisto()
        hEwk = self.getIntegratedEwkHisto()
        # newName  =  ("_".join(hData.GetName().split("_", 2)[:2]) + "_IntegratedPurity_" + str(self._uniqueN) )
        newName = hData.GetName() + "_Purity"
        h = aux.Clone(hData, newName)
        nameList = self._dataList[0].GetName().split("_")
        newTitle = "PurityByFinalShapeBin_%s" % nameList[0][:len(nameList[0]) -
                                                            1]
        h.SetTitle(newTitle)
        self._uniqueN += 1

        # For-loop: All bins
        for i in range(1, h.GetNbinsX() + 1):
            myPurity = 0.0
            myUncert = 0.0
            nData = hData.GetBinContent(i)
            nEWK = hEwk.GetBinContent(i)

            # Calculate the purity
            if (nData > 0.0):

                myPurity = (nData - nEWK) / nData

                # Sanity check
                if myPurity < 0.0:
                    myPurity = 0.0
                    myUncert = 0.0
                else:
                    # Assume binomial error
                    myUncertSq = myPurity * (1.0 - myPurity) / nData
                    if myUncertSq >= 0.0:
                        myUncert = sqrt(myUncertSq)
                    else:
                        msg = "Purity is greater than 1 (%.4f) in bin %i of histogram %s" % (
                            myPurity, i, h.GetName())
                        self.Verbose(ShellStyles.WarningLabel() + msg, True)
                        myUncert = 0.0

            # Set the purity value for the given bin
            h.SetBinContent(i, myPurity)
            h.SetBinError(i, myUncert)
        return h
示例#22
0
 def getIntegratedPurityForShapeHisto(self):
     hData = self.getIntegratedDataHisto()
     hEwk = self.getIntegratedEwkHisto()
     h = aux.Clone(hData, "%s_purity_%d"%(hData,self._uniqueN))
     myNameList = self._dataList[0].GetName().split("_")
     h.SetTitle("PurityByFinalShapeBin_%s"%myNameList[0][:len(myNameList[0])-1])
     self._uniqueN += 1
     for i in range(1, h.GetNbinsX()+1):
         myPurity = 0.0
         myUncert = 0.0
         if (hData.GetBinContent(i) > 0.0):
             myPurity = (hData.GetBinContent(i) - hEwk.GetBinContent(i)) / hData.GetBinContent(i)
             if myPurity < 0.0:
                 myPurity = 0.0
                 myUncert = 0.0
             else:
                 myUncert = sqrt(myPurity * (1.0-myPurity) / hData.GetBinContent(i)) # Assume binomial error
         h.SetBinContent(i, myPurity)
         h.SetBinError(i, myUncert)
     return h
    def getIntegratedNewDsetHisto(self):
        '''
        Return the sum of all datasets to be merged over the entire phase space
        '''
        newName = "%s_%s" % (self._histoName, self._newDsetName)
        histo = aux.Clone(self._histoList[0], newName)
        histo.Reset()

        # For-loop: All histograms in list
        for i, h in enumerate(self._histoList, 0):
            self.Verbose(
                "self.histoList[%s] = %s " % (i, self._histoList[i].GetName()),
                True)
            histo.Add(self._histoList[i])
            self.Verbose("histo.Integral() += %.2f" % (histo.Integral()),
                         False)

        self.Verbose(
            "Integral of histogram %s is %.3f (Entries = %d)" %
            (histo.GetName(), histo.Integral(), histo.GetEntries()), True)
        return histo
示例#24
0
    def getIntegratedPurityForShapeHisto(self):
        '''
        Return the QCD purity in bins of the final shape
        '''
        hData = self.getIntegratedDataHisto()
        hEwk = self.getIntegratedEwkHisto()
        #cloneName =  "%s_purity_%d" % (hData, self._uniqueN) # original code
        cloneName = ("_".join(hData.GetName().split("_", 2)[:2]) +
                     "_IntegratedPurity_" + str(self._uniqueN))
        h = aux.Clone(hData, cloneName)
        nameList = self._dataList[0].GetName().split("_")
        h.SetTitle("PurityByFinalShapeBin_%s" %
                   nameList[0][:len(nameList[0]) - 1])
        self._uniqueN += 1

        # For-loop: All bins
        for i in range(1, h.GetNbinsX() + 1):
            myPurity = 0.0
            myUncert = 0.0
            if (hData.GetBinContent(i) > 0.0):
                myPurity = (hData.GetBinContent(i) -
                            hEwk.GetBinContent(i)) / hData.GetBinContent(i)
                if myPurity < 0.0:
                    myPurity = 0.0
                    myUncert = 0.0
                else:
                    # Assume binomial error
                    myUncertSq = myPurity * (1.0 -
                                             myPurity) / hData.GetBinContent(i)
                    if myUncertSq >= 0.0:
                        myUncert = sqrt(myUncertSq)
                    else:
                        msg = "Purity is greater than 1 (%.4f) in bin %i of histogram %s" % (
                            myPurity, i, h.GetName())
                        self.Verbose(ShellStyles.WarningLabel() + msg, True)
                        myUncert = 0.0
            h.SetBinContent(i, myPurity)
            h.SetBinError(i, myUncert)
        return h
示例#25
0
 def _obtainScaleFactor(self, h, fitmin, fitmax):
     raise Exception(
         "There is something fishy in this function, validate before using")
     minbin = h.GetXaxis().FindBin(fitmin)
     maxbin = h.GetXaxis().FindBin(fitmax)
     hh = aux.Clone(h)
     preFactor = hh.Integral(minbin, hh.GetNbinsX() + 1)
     hh.Scale(1.0 / preFactor)
     myFitFunc = FitFuncPreFitForIntegral(self._fitmin)
     myFittedRate = ROOT.TF1(self._label + "myFitForIntegral", myFitFunc,
                             fitmin, fitmax, myFitFunc.getNparam())
     myFitResult = hh.Fit(myFittedRate, _fitOptions)
     # Set fitted params to function
     for i in range(0, myFitFunc.getNparam()):
         myFittedRate.SetParameter(i, myFitResult.Parameter(i))
     # Calculate integral from fitmin to infinity and divide by bin width to normalize
     myBinWidth = (hh.GetXaxis().GetBinLowEdge(maxbin) -
                   hh.GetXaxis().GetBinLowEdge(minbin)) / (maxbin - minbin)
     myScaleFactor = myFittedRate.Integral(minbin,
                                           1e5) / myBinWidth * preFactor
     print "Scale factor calc cross-check: integral from histogram = %f, integral from fit = %f" % (
         preFactor, myScaleFactor)
     print myFittedRate.Integral(minbin, 1e5), myBinWidth, preFactor
     return myScaleFactor
 def _doCalculate(self, shape, moduleInfoString, normFactors,
                  optionPrintPurityByBins, optionDoNQCDByBinHistograms):
     # Calculate final shape in signal region (shape * w_QCD)
     nSplitBins = shape.getNumberOfPhaseSpaceSplitBins()
     # Initialize result containers
     self._resultShape = aux.Clone(
         shape.getDataDrivenQCDHistoForSplittedBin(0))
     self._resultShape.Reset()
     self._resultShape.SetTitle("NQCDFinal_Total_%s" % moduleInfoString)
     self._resultShape.SetName("NQCDFinal_Total_%s" % moduleInfoString)
     self._resultShapeEWK = aux.Clone(
         shape.getDataDrivenQCDHistoForSplittedBin(0))
     self._resultShapeEWK.Reset()
     self._resultShapeEWK.SetTitle("NQCDFinal_EWK_%s" % moduleInfoString)
     self._resultShapeEWK.SetName("NQCDFinal_EWK_%s" % moduleInfoString)
     self._resultShapePurity = aux.Clone(
         shape.getDataDrivenQCDHistoForSplittedBin(0))
     self._resultShapePurity.Reset()
     self._resultShapePurity.SetTitle("NQCDFinal_Purity_%s" %
                                      moduleInfoString)
     self._resultShapePurity.SetName("NQCDFinal_Purity_%s" %
                                     moduleInfoString)
     self._histogramsList = []
     myUncertaintyLabels = ["statData", "statEWK"]
     self._resultCountObject = extendedCount.ExtendedCount(
         0.0, [0.0, 0.0], myUncertaintyLabels)
     if optionDoNQCDByBinHistograms:
         for i in range(0, nSplitBins):
             hBin = aux.Clone(self._resultShape)
             hBin.SetTitle(
                 "NQCDFinal_%s_%s" %
                 (shape.getPhaseSpaceBinFileFriendlyTitle(i).replace(
                     " ", ""), moduleInfoString))
             hBin.SetName(
                 "NQCDFinal_%s_%s" %
                 (shape.getPhaseSpaceBinFileFriendlyTitle(i).replace(
                     " ", ""), moduleInfoString))
             self._histogramsList.append(hBin)
     if isinstance(self._resultShape, ROOT.TH2):
         self._doCalculate2D(nSplitBins, shape, normFactors,
                             optionPrintPurityByBins,
                             optionDoNQCDByBinHistograms,
                             myUncertaintyLabels)
         return
     # Intialize counters for purity calculation in final shape binning
     myShapeDataSum = []
     myShapeDataSumUncert = []
     myShapeEwkSum = []
     myShapeEwkSumUncert = []
     for j in range(1, self._resultShape.GetNbinsX() + 1):
         myShapeDataSum.append(0.0)
         myShapeDataSumUncert.append(0.0)
         myShapeEwkSum.append(0.0)
         myShapeEwkSumUncert.append(0.0)
     # Calculate results separately for each phase space bin and then combine
     for i in range(0, nSplitBins):
         # Get data-driven QCD, data, and MC EWK shape histogram for the phase space bin
         h = shape.getDataDrivenQCDHistoForSplittedBin(i)
         hData = shape.getDataHistoForSplittedBin(i)
         hEwk = shape.getEwkHistoForSplittedBin(i)
         # Get normalization factor
         wQCDLabel = shape.getPhaseSpaceBinFileFriendlyTitle(i)
         if self._optionUseInclusiveNorm:
             wQCDLabel = "Inclusive"
         wQCD = 0.0
         if not wQCDLabel in normFactors.keys():
             print ShellStyles.WarningLabel(
             ) + "No normalization factors available for bin '%s' when accessing histogram %s! Ignoring this bin..." % (
                 wQCDLabel, shape.getHistoName())
         else:
             wQCD = normFactors[wQCDLabel]
         # Loop over bins in the shape histogram
         for j in range(1, h.GetNbinsX() + 1):
             myResult = 0.0
             myStatDataUncert = 0.0
             myStatEwkUncert = 0.0
             if abs(h.GetBinContent(j)) > 0.00001:  # Ignore zero bins
                 # Calculate result
                 myResult = h.GetBinContent(j) * wQCD
                 # Calculate abs. stat. uncert. for data and for MC EWK
                 myStatDataUncert = hData.GetBinError(j) * wQCD
                 myStatEwkUncert = hEwk.GetBinError(j) * wQCD
                 #errorPropagation.errorPropagationForProduct(hLeg1.GetBinContent(j), hLeg1Data.GetBinError(j), myEffObject.value(), myEffObject.uncertainty("statData"))
                 # Do not calculate here MC EWK syst.
             myCountObject = extendedCount.ExtendedCount(
                 myResult, [myStatDataUncert, myStatEwkUncert],
                 myUncertaintyLabels)
             self._resultCountObject.add(myCountObject)
             if optionDoNQCDByBinHistograms:
                 self._histogramsList[i].SetBinContent(
                     j, myCountObject.value())
                 self._histogramsList[i].SetBinError(
                     j, myCountObject.statUncertainty())
             self._resultShape.SetBinContent(
                 j,
                 self._resultShape.GetBinContent(j) + myCountObject.value())
             self._resultShape.SetBinError(
                 j,
                 self._resultShape.GetBinError(j) +
                 myCountObject.statUncertainty()**2)  # Sum squared
             # Sum items for purity calculation
             myShapeDataSum[j - 1] += hData.GetBinContent(j) * wQCD
             myShapeDataSumUncert[j - 1] += (hData.GetBinError(j) * wQCD)**2
             myShapeEwkSum[j - 1] += hEwk.GetBinContent(j) * wQCD
             myShapeEwkSumUncert[j - 1] += (hEwk.GetBinError(j) * wQCD)**2
         h.Delete()
         hData.Delete()
         hEwk.Delete()
     # Take square root of uncertainties
     for j in range(1, self._resultShape.GetNbinsX() + 1):
         self._resultShape.SetBinError(
             j, math.sqrt(self._resultShape.GetBinError(j)))
     # Print result
     print "NQCD Integral(%s) = %s " % (
         shape.getHistoName(),
         self._resultCountObject.getResultStringFull("%.1f"))
     # Print purity as function of final shape bins
     if optionPrintPurityByBins:
         print "Purity of shape %s" % shape.getHistoName()
         print "shapeBin purity purityUncert"
     for j in range(1, self._resultShape.GetNbinsX() + 1):
         myPurity = 0.0
         myPurityUncert = 0.0
         if abs(myShapeDataSum[j - 1]) > 0.000001:
             myPurity = 1.0 - myShapeEwkSum[j - 1] / myShapeDataSum[j - 1]
             myPurityUncert = errorPropagation.errorPropagationForDivision(
                 myShapeEwkSum[j - 1],
                 math.sqrt(myShapeEwkSumUncert[j - 1]),
                 myShapeDataSum[j - 1],
                 math.sqrt(myShapeDataSumUncert[j - 1]))
         # Store MC EWK content
         self._resultShapeEWK.SetBinContent(j, myShapeEwkSum[j - 1])
         self._resultShapeEWK.SetBinError(
             j, math.sqrt(myShapeEwkSumUncert[j - 1]))
         self._resultShapePurity.SetBinContent(j, myPurity)
         self._resultShapePurity.SetBinError(j, myPurityUncert)
         # Print purity info of final shape
         if optionPrintPurityByBins:
             myString = ""
             if j < self._resultShape.GetNbinsX():
                 myString = "%d..%d" % (
                     self._resultShape.GetXaxis().GetBinLowEdge(j),
                     self._resultShape.GetXaxis().GetBinUpEdge(j))
             else:
                 myString = ">%d" % (
                     self._resultShape.GetXaxis().GetBinLowEdge(j))
             myString += " %.3f %.3f" % (myPurity, myPurityUncert)
             print myString
示例#27
0
 def getIntegratedEwkHisto(self):
     h = aux.Clone(self._ewkList[0])
     h.SetName(h.GetName()+"Integrated")
     for i in range(1, len(self._dataList)):
         h.Add(self._ewkList[i])
     return h
示例#28
0
def printSummaryInfo(columnNames, myNuisanceInfo, cachedHistos, hObs, m,
                     luminosity, opts):

    config = aux.load_module(opts.settings)

    def addOrReplace(dictionary, key, newItem):
        if not key in dictionary.keys():
            dictionary[key] = newItem.Clone()
        else:
            dictionary[key].Add(newItem)

    def getHisto(cachedHistos, name):
        for h in cachedHistos:
            if h.GetName() == name:
                return h
        raise Exception("Cannot find histogram '%s'!" % name)

    # Create for each column a root histo with uncertainties
    myDict = OrderedDict()
    myTotal = None

    # Loop over columns (datasets)
    for c in columnNames:

        # Bugfix to prevent crashing with blacklisted datasets
        if c in config.Blacklist:
            continue

        hRate = aux.Clone(getHisto(cachedHistos, c))
        myRHWU = RootHistoWithUncertainties(hRate)
        for n in myNuisanceInfo:
            # Add shape uncertainties
            if n["name"] != "observation" and n[
                    "distribution"] == "shape" and n[
                        c] == "1" and not "statBin" in n["name"]:
                hUp = aux.Clone(
                    getHisto(cachedHistos, "%s_%sUp" % (c, n["name"])))
                hDown = aux.Clone(
                    getHisto(cachedHistos, "%s_%sDown" % (c, n["name"])))
                myRHWU.addShapeUncertaintyFromVariation(n["name"], hUp, hDown)
            # Add constant uncertainties
            elif n["name"] != "observation" and n["name"] != "rate" and n[
                    "name"] != "process" and n[c] != "-" and n[
                        c] != "1" and not "statBin" in n[
                            "name"] and not "BinByBin" in n["name"]:
                diffUp = 0.0
                diffDown = 0.0
                if "/" in n[c]:
                    mySplit = n[c].split("/")
                    diffDown = float(mySplit[0]) - 1.0
                    diffUp = float(mySplit[1]) - 1.0
                else:
                    diffDown = float(n[c]) - 1.0
                    diffUp = float(n[c]) - 1.0
                myRHWU.addNormalizationUncertaintyRelative(
                    n["name"], diffUp, diffDown)
        # Store column info
        _myBr = 0.01
        myAddToTotalStatus = False
        if c.startswith("HH") or c.startswith("CMS_Hptntj_HH"):
            myRHWU.Scale(_myBr**2)
            addOrReplace(myDict, "Hp", myRHWU)
        elif c.startswith("HW") or c.startswith("CMS_Hptntj_HW"):
            myRHWU.Scale(2.0 * _myBr * (1.0 - _myBr))
            addOrReplace(myDict, "Hp", myRHWU)
        elif c.startswith("Hp") or c.startswith("CMS_Hptntj_Hp"):
            addOrReplace(myDict, "Hp", myRHWU)
        elif c == "EWK_Tau" or c.startswith("CMS_Hptntj_EWK_Tau"):
            addOrReplace(myDict, "EWKtau", myRHWU)
            myAddToTotalStatus = True
        elif c.endswith("genuinetau"):
            addOrReplace(myDict, c.replace("CMS_Hptntj_", ""), myRHWU)
            myAddToTotalStatus = True
        elif c.endswith("faketau"):
            addOrReplace(myDict, "EWKfakes", myRHWU)
            myAddToTotalStatus = True
        elif c.startswith("QCD") or c.startswith("CMS_Hptntj_QCD"):
            addOrReplace(myDict, "QCD", myRHWU)
            myAddToTotalStatus = True
        else:
            myDict[c] = myRHWU
            myAddToTotalStatus = True
        if myAddToTotalStatus:
            if myTotal == None:
                myTotal = myRHWU.Clone()
            else:
                myTotal.Add(myRHWU.Clone())

    myDict["Totalbkg"] = myTotal
    # Make table
    print "\nEvent yields:"
    myTotal = None
    for item in myDict.keys():
        if myDict[item] != None:
            myDict[item].makeFlowBinsVisible()
            rate = myDict[item].getRate()
            stat = myDict[item].getRateStatUncertainty()
            (systUp, systDown) = myDict[item].getRateSystUncertainty()
            #myDict[item].Debug()
            print "%11s: %.1f +- %.1f (stat.) + %.1f - %.1f (syst.)" % (
                item, rate, stat, systUp, systDown)
    print "Observation: %d\n\n" % hObs.Integral(0, hObs.GetNbinsX() + 2)

    def setTailFitUncToStat(rhwu):
        tailfitNames = filter(lambda n: "_TailFit_" in n,
                              rhwu.getShapeUncertaintyNames())
        rhwu.setShapeUncertaintiesAsStatistical(tailfitNames)
        #rhwu.printUncertainties()
        #print rhwu.getShapeUncertaintiesAsStatistical()
        return rhwu

    myLogList = [False, True]
    for l in myLogList:

        # Create post fit shape
        myStackList = []
        if "QCD" in myDict.keys():
            myHisto = histograms.Histo(
                setTailFitUncToStat(myDict["QCD"].Clone()),
                "QCD",
                legendLabel=ControlPlotMaker._legendLabelQCD)
            myHisto.setIsDataMC(isData=False, isMC=True)
            myStackList.append(myHisto)
        if "EWKtau" in myDict.keys():
            myHisto = histograms.Histo(
                setTailFitUncToStat(myDict["EWKtau"].Clone()),
                "Embedding",
                legendLabel=ControlPlotMaker._legendLabelEmbedding)
            myHisto.setIsDataMC(isData=False, isMC=True)
            myStackList.append(myHisto)
        for c in myDict.keys():
            if c.endswith("genuinetau"):
                histoID = c.replace("CMS_Hptntj_",
                                    "").replace("_genuinetau", "")
                lookupTable = {  # Map column name to style in plots.py
                    "tt": "TT",
                    "W": "WJets",
                    "t": "SingleTop",
                    "DY": "DYJetsToLL",
                    "VV": "Diboson",
                    "tt_and_singleTop": "TTandSingleTop",
                    "EWK": "EWK"
                }
                histoString = lookupTable[histoID]
                myHisto = histograms.Histo(
                    setTailFitUncToStat(myDict[c].Clone()),
                    histoString,
                    legendLabel=c.replace("CMS_Hptntj_", ""))
                myHisto.setIsDataMC(isData=False, isMC=True)
                myStackList.append(myHisto)
        if "EWKfakes" in myDict.keys() and myDict["EWKfakes"] != None:
            myHisto = histograms.Histo(
                myDict["EWKfakes"].Clone(),
                "EWKfakes",
                legendLabel=ControlPlotMaker._legendLabelEWKFakes)
            myHisto.setIsDataMC(isData=False, isMC=True)
            myStackList.append(myHisto)
        myBlindedStatus = not opts.unblinded
        myBlindingString = None
        hObsLocal = aux.Clone(hObs)
        if myBlindedStatus:
            myBlindingString = "%d-%d GeV" % (hObs.GetXaxis().GetBinLowEdge(1),
                                              hObs.GetXaxis().GetBinUpEdge(
                                                  hObs.GetNbinsX()))
            for i in range(0, hObs.GetNbinsX()):
                hObsLocal.SetBinContent(i, -1.0)
                hObsLocal.SetBinError(i, 0.0)
        # Add data
        myDataHisto = histograms.Histo(hObsLocal, "Data")
        myDataHisto.setIsDataMC(isData=True, isMC=False)
        myStackList.insert(0, myDataHisto)
        # Add signal
        mySignalLabel = "TTToHplus_M%d" % float(m)
        if float(m) > 179:
            mySignalLabel = "HplusTB_M%d" % float(m)
        myHisto = histograms.Histo(myDict["Hp"].Clone(), mySignalLabel)
        myHisto.setIsDataMC(isData=False, isMC=True)
        myStackList.insert(1, myHisto)

        # Make plot
        myStackPlot = plots.DataMCPlot2(myStackList)
        myStackPlot.setLuminosity(luminosity)
        #myStackPlot.setEnergy("%d"%self._config.OptionSqrtS)
        myStackPlot.setDefaultStyles()
        myParams = {}
        if myBlindedStatus:
            myParams["blindingRangeString"] = myBlindingString
        myParams["cmsTextPosition"] = "right"
        myParams["ratio"] = True
        myParams["ratioType"] = "errorScale"
        myParams["ratioYlabel"] = "Data/Bkg. "
        myParams["stackMCHistograms"] = True
        myParams["addMCUncertainty"] = True
        myParams["addLuminosityText"] = True
        myParams["moveLegend"] = {"dx": -0.14, "dy": -0.10}
        myParams["ratioErrorOptions"] = {"numeratorStatSyst": False}
        myParams["ratioCreateLegend"] = True
        #myParams["ratioMoveLegend"] = {"dx": -0.51, "dy": 0.03}
        myParams["ratioMoveLegend"] = {"dx": -0.06, "dy": -0.1}
        myParams["opts2"] = {"ymin": 0.0, "ymax": 2.5}
        myParams["xlabel"] = "m_{T} (GeV)"
        #if l:
        #    myParams["ylabel"] = "< Events / bin >"
        #else:
        myParams["ylabel"] = "Events / 20 GeV"
        a = hObsLocal.GetXaxis().GetBinWidth(1)
        b = hObsLocal.GetXaxis().GetBinWidth(hObsLocal.GetNbinsX())
        #if abs(a-b) < 0.0001:
        #myParams["ylabel"]  += "%d GeV"%a
        #else:
        #myParams["ylabel"]  += "%d-%d GeV"%(a,b)
        #myParams["divideByBinWidth"] = l
        myParams["log"] = l
        myPlotName = "PostTailFitShape_M%d" % float(m)
        if l:
            # scale ymin by 20 in order to compare the rebinned mT with same y-scale
            # ymax(factor) takes care of max automatically
            myParams["opts"] = {"ymin": 20 * 1e-5}
        else:
            myParams["opts"] = {"ymin": 0.0}
            myPlotName += "_Linear"
        plots.drawPlot(myStackPlot, myPlotName, **myParams)
示例#29
0
def updateNuisanceTail(opts,
                       hOriginalShape,
                       hFittedShape,
                       rootFile,
                       histoName,
                       skipNotFoundTest=False):
    myList = []
    myPostfixes = ["Up", "Down"]
    for postfix in myPostfixes:
        # Obtain original nuisance histogram
        hOriginalNuisance = rootFile.Get(histoName + postfix)
        hOriginalNuisance.Scale(opts.lumiProjection * opts.bkgxsecProjection)
        if hOriginalNuisance == None:
            if skipNotFoundTest:
                return []
            else:
                raise Exception(ErrorLabel() + "Cannot open histogram '%s'!" %
                                (histoName + postfix))
        # Sanity check
        if hOriginalShape.GetNbinsX() != hOriginalNuisance.GetNbinsX():
            raise Exception("This should not happen")
        # Prepare new histogram
        hNewNuisance = aux.Clone(hFittedShape, histoName + postfix)
        hNewNuisance.Reset()
        hNewNuisance.SetMarkerSize(0)
        # Loop over final histogram bins
        for i in range(1, hFittedShape.GetNbinsX() + 1):
            myOriginalBin = hOriginalShape.GetXaxis().FindBin(
                hFittedShape.GetXaxis().GetBinLowEdge(i) + 0.0001)
            myOriginalBinUpEdge = hOriginalShape.GetXaxis().FindBin(
                hFittedShape.GetXaxis().GetBinUpEdge(i) - 0.0001)
            if myOriginalBin != myOriginalBinUpEdge:
                raise Exception(
                    ErrorLabel() +
                    "final rebinning boundaries at %d-%d do not match to original histogram (needed for shape nuisance scaling)!"
                    % (hFittedShape.GetXaxis().GetBinLowEdge(i),
                       hFittedShape.GetXaxis().GetBinUpEdge(i)))
            # Original relative uncertainty (if ambiguous, leave as None, i.e. perform no scaling
            myOriginalDelta = None
            if abs(hOriginalNuisance.GetBinContent(myOriginalBin)) < 0.00001:
                myOriginalDelta = None
            elif abs(hOriginalShape.GetBinContent(myOriginalBin)) < 0.00001:
                myOriginalDelta = None
            else:
                myOriginalDelta = hOriginalNuisance.GetBinContent(
                    myOriginalBin) / hOriginalShape.GetBinContent(
                        myOriginalBin)
            #print i, myOriginalBin, myOriginalDelta, hOriginalNuisance.GetBinContent(myOriginalBin), hOriginalShape.GetBinContent(myOriginalBin)
            # Calculate new variation counts
            myNewVariation = None
            if myOriginalDelta == None:
                # scale by bin width difference
                myNewVariation = hOriginalNuisance.GetBinContent(
                    myOriginalBin) * hFittedShape.GetXaxis().GetBinWidth(
                        i) / hOriginalNuisance.GetXaxis().GetBinWidth(
                            myOriginalBin)
            else:
                myNewVariation = myOriginalDelta * hFittedShape.GetBinContent(
                    i)
            #print i, myNewVariation, hFittedShape.GetBinContent(i)
            # Store
            hNewNuisance.SetBinContent(i, myNewVariation)
            hNewNuisance.SetBinError(i,
                                     hOriginalShape.GetBinError(myOriginalBin))
        # Finalize
        hOriginalNuisance.Delete()
        hNewNuisance.SetTitle(histoName + postfix)
        myList.append(hNewNuisance)
    return myList
示例#30
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:
            print "No ratioplots in list! Cannot draw all-in-one plot!"
            return
        o = self._ratioPlotList[0].getFrame2()
        myEmptyPlot = aux.Clone(o) # Keep the clone if it is needed to draw the x axis
        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.001)
#            plot.SetMaximum(1.999)
            plot.SetMinimum(0.601)
            plot.SetMaximum(1.399)
            plot.Draw() # Plot frame for every nuisance
            if myPlotIndex != None:
                self._ratioPlotList[myPlotIndex].ratioHistoMgr.draw() # Plot content only if affected
            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
        myPlotName = "shapeSystRatioOnlyAll_%s"%(self._dsetName)
        backup = ROOT.gErrorIgnoreLevel
        ROOT.gErrorIgnoreLevel = ROOT.kError
        for suffix in [".png",".C",".eps"]:
            c.Print("%s/%s%s"%(_dirname,myPlotName,suffix))
        ROOT.gErrorIgnoreLevel = backup