background_fakerate_uncertainty[region][background.name] = min(
                [1 + 0.03 * (i_region + 1),
                 1.12])  #*(i_background+1) #change that
            background_jec_uncertainty[region][background.name] = max([
                1.05, min([1.12 - 0.01 * (i_region + 1), 1.12])
            ])  #1.2 - 0.02*(i_region+1) #*(i_background+1) #change that

        # Our expected observation :-)
        observation[region] = int(
            sum(background_rate[region].values()) + ttgamma1l_SM_rate[region] +
            ttgamma2l_SM_rate[region])

    # Write temporary card file
    from TTXPheno.Tools.cardFileWriter import cardFileWriter
    c = cardFileWriter.cardFileWriter()

    def cuBWtoctWZ(cuB, cuW):
        ''' transforms C_tZ and C_tW to C_uB and C_uW
            C_tZ = Re( -sW*C_uB + cW*C_uW )
            C_tW = Re( C_uW )
            arXiv: 1802.07237
        '''
        sW = 0.4715
        cW = 0.8819

        ctW = cuW
        ctZ = -sW * cuB + cW * cuW

        return ctZ, ctW
Exemple #2
0
    def calculation(variables):
        #def calculation( var1, var2 ):

        if args.variables[0] == 'cuB' and args.variables[1] == 'cuW':
            var1, var2 = variables  #cuB cuW
            ctZ, ctW = cuBWtoctWZ(var1, var2)
            kwargs = {'ctZ': ctZ, 'ctW': ctW}
        else:
            var1, var2 = variables
            kwargs = {args.variables[0]: var1, args.variables[1]: var2}

        nameList = args.sample.split(
            '_')[1:3] + args.variables + args.binning + [
                args.level, args.version, args.order, args.luminosity,
                "14TeV" if args.scale14TeV else "13TeV", args.selection,
                'small' if args.small else 'full', 'statOnly' if args.statOnly
                else 'fullUnc' if not args.noExpUnc else 'noExpUnc', var1, var2
            ]
        cardname = '%s_nll_card' % '_'.join(map(str, nameList))
        cardFilePath = os.path.join(cardfileLocation, cardname + '.txt')

        c = cardFileWriter.cardFileWriter()
        if args.useCombine:
            c.releaseLocation = combineReleaseLocation

        if not args.fitOnly:
            #            print 'run cardfile'

            # uncertainties
            c.reset()
            if not args.statOnly:
                if not args.noExpUnc:
                    c.addUncertainty('lumi', 'lnN')
                    c.addUncertainty('JES', 'lnN')
                    c.addUncertainty('btagging', 'lnN')
                    c.addUncertainty('mistagging', 'lnN')
                    c.addUncertainty('muonId', 'lnN')
                    c.addUncertainty('electronId', 'lnN')
                for unc in args.addUncertainties:
                    c.addUncertainty(unc, 'lnN')

            signal_rate = {}
            for i_region, region in enumerate(regions):

                signal_rate[region] = ttXSample.weightInfo.get_weight_yield(
                    ttX_coeffList[region], **kwargs)

                if not args.statOnly and not args.noExpUnc:
                    # signal uncertainties
                    # btagging
                    signal_rate_reweighted = ttXSample.weightInfo.get_weight_yield(
                        ttX_coeffList_reweighted_btagging[region], **kwargs)
                    signal_btagging_uncertainty[region] = 1 + (
                        (signal_rate_reweighted - signal_rate[region]) /
                        signal_rate[region]) if signal_rate[region] > 0 else 1.

                    # mistagging
                    signal_rate_reweighted = ttXSample.weightInfo.get_weight_yield(
                        ttX_coeffList_reweighted_mistagging[region], **kwargs)
                    signal_mistagging_uncertainty[region] = 1 + (
                        (signal_rate_reweighted - signal_rate[region]) /
                        signal_rate[region]) if signal_rate[region] > 0 else 1.

                    # muonId
                    signal_rate_reweighted = ttXSample.weightInfo.get_weight_yield(
                        ttX_coeffList_reweighted_muonId[region], **kwargs)
                    signal_muonId_uncertainty[region] = 1 + (
                        (signal_rate_reweighted - signal_rate[region]) /
                        signal_rate[region]) if signal_rate[region] > 0 else 1.

                    # electronId
                    signal_rate_reweighted = ttXSample.weightInfo.get_weight_yield(
                        ttX_coeffList_reweighted_electronId[region], **kwargs)
                    signal_electronId_uncertainty[region] = 1 + (
                        (signal_rate_reweighted - signal_rate[region]) /
                        signal_rate[region]) if signal_rate[region] > 0 else 1.

                    # JES
                    signal_rate_reweighted_JES_up = ttXSample.weightInfo.get_weight_yield(
                        ttX_coeffList_reweighted_jes_up[region], **kwargs)
                    signal_rate_reweighted_JES_down = ttXSample.weightInfo.get_weight_yield(
                        ttX_coeffList_reweighted_jes_down[region], **kwargs)
                    signal_jes_uncertainty[region] = 1 + (
                        (signal_rate_reweighted_JES_up -
                         signal_rate_reweighted_JES_down) /
                        (2 * signal_rate[region])
                    ) if signal_rate[region] > 0 else 1.

                bin_name = "Region_%i" % i_region
                nice_name = region.__str__()
                c.addBin(bin_name,
                         ['_'.join(s.name.split('_')[1:3])
                          for s in bg] + ['nonPrompt'] if args.addNonPrompt
                         else ['_'.join(s.name.split('_')[1:3])
                               for s in bg], nice_name)

                c.specifyObservation(bin_name, observation[region])

                c.specifyExpectation(bin_name, 'signal', signal_rate[region])

                if not args.statOnly:
                    if not args.noExpUnc:
                        c.specifyFlatUncertainty('lumi', 1.01)
                        c.specifyUncertainty('JES', bin_name, 'signal',
                                             signal_jes_uncertainty[region])
                        c.specifyUncertainty(
                            'btagging', bin_name, 'signal',
                            signal_btagging_uncertainty[region])
                        c.specifyUncertainty(
                            'mistagging', bin_name, 'signal',
                            signal_mistagging_uncertainty[region])
                        c.specifyUncertainty('muonId', bin_name, 'signal',
                                             signal_muonId_uncertainty[region])
                        c.specifyUncertainty(
                            'electronId', bin_name, 'signal',
                            signal_electronId_uncertainty[region])

                    for unc in args.addUncertainties:
                        c.specifyUncertainty(
                            unc, bin_name, 'signal', 1 + (getUncertaintyValue(
                                args.additionalCardFile, args.addBinNumberShift
                                + i_region, 'signal', unc) - 1) *
                            args.uncertaintyScale)

                if args.addNonPrompt:
                    # for nonpromt only nonpromt uncertainty is important
                    c.specifyExpectation(bin_name, 'nonPrompt',
                                         nonPromptObservation[region])
                    if not args.statOnly:
                        c.specifyUncertainty(
                            'nonprompt', bin_name, 'nonPrompt',
                            1 + (getUncertaintyValue(
                                args.additionalCardFile, args.addBinNumberShift
                                + i_region, 'nonPromptDD', 'nonprompt') - 1) *
                            args.uncertaintyScale)

                #c.specifyExpectation( bin_name, 'ttX_SM', ttX_SM_rate[region] )
                #c.specifyUncertainty( 'JES', bin_name, 'ttX_SM', ttX_SM_jes_uncertainty[region])
                #c.specifyUncertainty( 'btagging',bin_name, 'ttX_SM', ttX_SM_btagging_uncertainty[region])

                for background in bg:
                    c.specifyExpectation(
                        bin_name, '_'.join(background.name.split('_')[1:3]),
                        background_rate[region][background.name])
                    if not args.statOnly:
                        if not args.noExpUnc:
                            c.specifyUncertainty(
                                'JES', bin_name,
                                '_'.join(background.name.split('_')[1:3]),
                                background_jes_uncertainty[region][
                                    background.name])
                            c.specifyUncertainty(
                                'btagging', bin_name,
                                '_'.join(background.name.split('_')[1:3]),
                                background_btagging_uncertainty[region][
                                    background.name])
                            c.specifyUncertainty(
                                'mistagging', bin_name,
                                '_'.join(background.name.split('_')[1:3]),
                                background_mistagging_uncertainty[region][
                                    background.name])
                            c.specifyUncertainty(
                                'muonId', bin_name,
                                '_'.join(background.name.split('_')[1:3]),
                                background_muonId_uncertainty[region][
                                    background.name])
                            c.specifyUncertainty(
                                'electronId', bin_name,
                                '_'.join(background.name.split('_')[1:3]),
                                background_electronId_uncertainty[region][
                                    background.name])
                        for unc in args.addUncertainties:
                            if 'tZq' in background.name.split(
                                    '_') or 'ttgamma' in background.name.split(
                                        '_') or 'tWZ' in background.name.split(
                                            '_'):
                                proc = 'TTX'
                            elif 'WZ' in background.name.split('_'):
                                proc = 'WZ'
                            else:
                                raise ValueError('Background not found: %s' %
                                                 background.name)
                            c.specifyUncertainty(
                                unc, bin_name,
                                '_'.join(background.name.split('_')[1:3]),
                                1 + (getUncertaintyValue(
                                    args.additionalCardFile,
                                    args.addBinNumberShift + i_region, proc,
                                    unc) - 1) * args.uncertaintyScale)

            c.writeToFile(cardFilePath)

        else:
            logger.info("Running only NLL Fit with given CardFile %s" %
                        cardFilePath)

        if not os.path.isfile(cardFilePath):
            raise ValueError(
                'CardFiles not found! Run script without --fitOnly!')

        if args.useCombine:
            # use the official cms combine tool
            #                c.calcNuisances( cardFilePath, bestFit=args.bestFit )
            nll = c.calcNLL(cardFilePath, bestFit=args.bestFit)
            #            nll = nll['nll0'] #pre-fit
            nll = nll['nll_abs']  #post-fit

            if args.removeCardFiles:
                for file in os.listdir(cardfileLocation):
                    if file.startswith(cardname):
                        os.remove(os.path.join(cardfileLocation, file))

        else:
            if args.bestFit: r = (0.99, 1.01)
            else: r = (0., 2.)

            profiledLoglikelihoodFit = ProfiledLoglikelihoodFit(cardFilePath)
            profiledLoglikelihoodFit.make_workspace(rmin=r[0], rmax=r[1])
            nll = profiledLoglikelihoodFit.likelihoodTest()
            profiledLoglikelihoodFit.cleanup(removeFiles=args.removeCardFiles)
            del profiledLoglikelihoodFit

        logger.info("NLL: %f", nll)
        ROOT.gDirectory.Clear()

        # in very large WC regions, the fit fails, not relevant for the interesting regions
        if nll is None or abs(nll) > 10000 or abs(nll) < 1: nll = 999

        del c

        return var1, var2, nll
Exemple #3
0
    def calculation( c_var ):

        sigmaC = getHiggsWeight( c_var )

        nameList = [args.sample] + args.binning + [ args.selection, 'small' if args.small else 'full', c_var ]
        cardname = '%s_nll_card'%'_'.join( map( str, nameList ) )
        cardFilePath = os.path.join( cardfileLocation, cardname + '.txt' )

        c = cardFileWriter.cardFileWriter()

        if not args.fitOnly:
#            print 'run cardfile'

            # uncertainties
            c.reset()
            c.addUncertainty('Luminosity', 'lnN')
            c.addUncertainty('JER',             'lnN')
            c.addUncertainty('btagging',       'lnN')
            c.addUncertainty('mistagging',     'lnN')
            c.addUncertainty('LeptonID',       'lnN')

            signal_rate                  = {}
            for i_region, region in enumerate(regions):

                i_r = i_region % 4

                signal_rate[region]    = signalPP.getYieldFromDraw( selectionString=region.cutString(), weightString="%f"%(nloXSec*(1-c_var)**2/sigmaC) )['val']
                signal_rate[region]   += signalGH.getYieldFromDraw( selectionString=region.cutString(), weightString="%f"%(nloXSec*(1-c_var)*c_var/sigmaC) )['val']
                signal_rate[region]   += signalHG.getYieldFromDraw( selectionString=region.cutString(), weightString="%f"%(nloXSec*(1-c_var)*c_var/sigmaC) )['val']
                signal_rate[region]   += signalHH.getYieldFromDraw( selectionString=region.cutString(), weightString="%f"%(nloXSec*c_var**2/sigmaC) )['val']

                signal_btagging_uncertainty   [region] = 1 + .015/(i_r+1.)
                signal_mistagging_uncertainty [region] = 1 + .01/(i_r+1.)
                signal_leptonId_uncertainty   [region] = 1 + .01/(i_r+1.)
                signal_jes_uncertainty        [region] = 1 + .05/(i_r+1.)

                bin_name = "Region_%i" % i_region
                nice_name = region.__str__()
                c.addBin(bin_name, ['_'.join(s.name.split('_')[1:3]) for s in bg], nice_name)

                c.specifyObservation( bin_name, observation[region] )

                c.specifyExpectation( bin_name, 'signal', signal_rate[region]                                 )

                c.specifyFlatUncertainty( 'Luminosity', 1.026 )
                c.specifyUncertainty( 'JER',         bin_name, 'signal', signal_jes_uncertainty[region]        )
                c.specifyUncertainty( 'btagging',   bin_name, 'signal', signal_btagging_uncertainty[region]   )
                c.specifyUncertainty( 'mistagging', bin_name, 'signal', signal_mistagging_uncertainty[region] )
                c.specifyUncertainty( 'LeptonID',   bin_name, 'signal', signal_leptonId_uncertainty[region] )

                for background in bg:
                    c.specifyExpectation( bin_name, '_'.join( background.name.split('_')[1:3] ), background_rate[region][background.name] )
                    c.specifyUncertainty( 'JER',           bin_name, '_'.join( background.name.split('_')[1:3] ), background_jes_uncertainty[region][background.name])
                    c.specifyUncertainty( 'btagging',     bin_name, '_'.join( background.name.split('_')[1:3] ), background_btagging_uncertainty[region][background.name])
                    c.specifyUncertainty( 'mistagging',   bin_name, '_'.join( background.name.split('_')[1:3] ), background_mistagging_uncertainty[region][background.name])
                    c.specifyUncertainty( 'LeptonID',     bin_name, '_'.join( background.name.split('_')[1:3] ), background_leptonId_uncertainty[region][background.name])
                    
            c.writeToFile( cardFilePath )

        else:
            logger.info( "Running only NLL Fit with given CardFile %s"%cardFilePath)

        if not os.path.isfile( cardFilePath ):
            raise ValueError('CardFiles not found! Run script without --fitOnly!')

        if args.bestFit: r = (0.99, 1.01)
        else: r = (0., 2.)

        profiledLoglikelihoodFit = ProfiledLoglikelihoodFit( cardFilePath )
        profiledLoglikelihoodFit.make_workspace(rmin=r[0], rmax=r[1])
        nll = profiledLoglikelihoodFit.likelihoodTest()
        profiledLoglikelihoodFit.cleanup(removeFiles=args.removeCardFiles)
        del profiledLoglikelihoodFit

        logger.info( "NLL: %f", nll)
        ROOT.gDirectory.Clear()

        # in very large WC regions, the fit fails, not relevant for the interesting regions
        if nll is None or abs(nll) > 10000 or abs(nll) < 1: nll = 999

        del c

        return c_var, nll
Exemple #4
0
    def createCardfile():
        #def calculation( var1, var2 ):

        #            cardname = 'Cos_SM_cardfile'
        cardname = 'PTZ_SM_cardfile'
        cardFilePath = os.path.join(cardfileLocation, cardname + '.txt')
        kwargs = {}

        c = cardFileWriter.cardFileWriter()

        c.addUncertainty('lumi', 'lnN')
        c.addUncertainty('JES', 'lnN')
        c.addUncertainty('btagging', 'lnN')
        c.addUncertainty('mistagging', 'lnN')
        c.addUncertainty('muonId', 'lnN')
        c.addUncertainty('electronId', 'lnN')
        for unc in args.addUncertainties:
            c.addUncertainty(unc, 'lnN')

        signal_rate = {}
        for i_region, region in enumerate(regions):

            signal_rate[region] = ttXSample.weightInfo.get_weight_yield(
                ttX_coeffList[region], **kwargs)

            # signal uncertainties
            # btagging
            signal_rate_reweighted = ttXSample.weightInfo.get_weight_yield(
                ttX_coeffList_reweighted_btagging[region], **kwargs)
            signal_btagging_uncertainty[region] = 1 + (
                (signal_rate_reweighted - signal_rate[region]) /
                signal_rate[region]) if signal_rate[region] > 0 else 1.

            # mistagging
            signal_rate_reweighted = ttXSample.weightInfo.get_weight_yield(
                ttX_coeffList_reweighted_mistagging[region], **kwargs)
            signal_mistagging_uncertainty[region] = 1 + (
                (signal_rate_reweighted - signal_rate[region]) /
                signal_rate[region]) if signal_rate[region] > 0 else 1.

            # muonId
            signal_rate_reweighted = ttXSample.weightInfo.get_weight_yield(
                ttX_coeffList_reweighted_muonId[region], **kwargs)
            signal_muonId_uncertainty[region] = 1 + (
                (signal_rate_reweighted - signal_rate[region]) /
                signal_rate[region]) if signal_rate[region] > 0 else 1.

            # electronId
            signal_rate_reweighted = ttXSample.weightInfo.get_weight_yield(
                ttX_coeffList_reweighted_electronId[region], **kwargs)
            signal_electronId_uncertainty[region] = 1 + (
                (signal_rate_reweighted - signal_rate[region]) /
                signal_rate[region]) if signal_rate[region] > 0 else 1.

            # JES
            signal_rate_reweighted_JES_up = ttXSample.weightInfo.get_weight_yield(
                ttX_coeffList_reweighted_jes_up[region], **kwargs)
            signal_rate_reweighted_JES_down = ttXSample.weightInfo.get_weight_yield(
                ttX_coeffList_reweighted_jes_down[region], **kwargs)
            signal_jes_uncertainty[region] = 1 + (
                (signal_rate_reweighted_JES_up -
                 signal_rate_reweighted_JES_down) /
                (2 * signal_rate[region])) if signal_rate[region] > 0 else 1.

            bin_name = "Region_%i" % i_region
            nice_name = region.__str__()
            c.addBin(bin_name, ['_'.join(s.name.split('_')[1:3]) for s in bg],
                     nice_name)

            c.specifyObservation(bin_name, observation[region])

            c.specifyExpectation(bin_name, 'signal', signal_rate[region])

            c.specifyFlatUncertainty('lumi', 1.01)
            c.specifyUncertainty('JES', bin_name, 'signal',
                                 signal_jes_uncertainty[region])
            c.specifyUncertainty('btagging', bin_name, 'signal',
                                 signal_btagging_uncertainty[region])
            c.specifyUncertainty('mistagging', bin_name, 'signal',
                                 signal_mistagging_uncertainty[region])
            c.specifyUncertainty('muonId', bin_name, 'signal',
                                 signal_muonId_uncertainty[region])
            c.specifyUncertainty('electronId', bin_name, 'signal',
                                 signal_electronId_uncertainty[region])

            for unc in args.addUncertainties:
                c.specifyUncertainty(
                    unc, bin_name, 'signal', 1 + (getUncertaintyValue(
                        args.additionalCardFile, args.addBinNumberShift +
                        i_region, 'signal', unc) - 1) * args.uncertaintyScale)

            #c.specifyExpectation( bin_name, 'ttX_SM', ttX_SM_rate[region] )
            #c.specifyUncertainty( 'JES', bin_name, 'ttX_SM', ttX_SM_jes_uncertainty[region])
            #c.specifyUncertainty( 'btagging',bin_name, 'ttX_SM', ttX_SM_btagging_uncertainty[region])

            for background in bg:
                c.specifyExpectation(bin_name,
                                     '_'.join(background.name.split('_')[1:3]),
                                     background_rate[region][background.name])
                c.specifyUncertainty(
                    'JES', bin_name, '_'.join(background.name.split('_')[1:3]),
                    background_jes_uncertainty[region][background.name])
                c.specifyUncertainty(
                    'btagging', bin_name,
                    '_'.join(background.name.split('_')[1:3]),
                    background_btagging_uncertainty[region][background.name])
                c.specifyUncertainty(
                    'mistagging', bin_name,
                    '_'.join(background.name.split('_')[1:3]),
                    background_mistagging_uncertainty[region][background.name])
                c.specifyUncertainty(
                    'muonId', bin_name,
                    '_'.join(background.name.split('_')[1:3]),
                    background_muonId_uncertainty[region][background.name])
                c.specifyUncertainty(
                    'electronId', bin_name,
                    '_'.join(background.name.split('_')[1:3]),
                    background_electronId_uncertainty[region][background.name])
                for unc in args.addUncertainties:
                    if 'tZq' in background.name.split(
                            '_') or 'ttgamma' in background.name.split(
                                '_') or 'tWZ' in background.name.split('_'):
                        proc = 'TTX'
                    elif 'WZ' in background.name.split('_'):
                        proc = 'WZ'
                    else:
                        raise ValueError('Background not found: %s' %
                                         background.name)
                    c.specifyUncertainty(
                        unc, bin_name,
                        '_'.join(background.name.split('_')[1:3]),
                        1 + (getUncertaintyValue(
                            args.additionalCardFile, args.addBinNumberShift +
                            i_region, proc, unc) - 1) * args.uncertaintyScale)

        c.writeToFile(cardFilePath)