Esempio n. 1
0
def wrapper(s):
    
    logger.info("Now working on %s", s.name)
    xSecScale = 1
    c = cardFileWriter.cardFileWriter()
    c.releaseLocation = combineReleaseLocation

    for coup in nonZeroCouplings:
        try:
            modification_dict[coup] = getCouplingFromName(s.name, coup)
            logger.info("The following coupling is set to non-zero value: %s: %s", coup, modification_dict[coup])
        except ValueError:
            logger.info("The following coupling is kept at zero: %s: %s", coup, modification_dict[coup])
            continue
    try:
        p = Process(process = "ttZ_ll", nEvents = 5000, config = config, xsec_cache=xsecDB)
        xsec = p.xsecDB.get(modification_dict)
    except IndexError:
        logger.info("Looking into backup DB for x-sec")
        p = Process(process = "ttZ_ll", nEvents = 5000, config = config, xsec_cache=xsecDB_Backup)
        xsec = p.xsecDB.get(modification_dict)
    if not xsec:
        try:
            p = Process(process = "ttZ_ll", nEvents = 5000, config = config, xsec_cache=xsecDB_Backup)
            xsec = p.xsecDB.get(modification_dict)
        except IndexError:
            logger.info("No x-sec found.")
    logger.info("Found modified x-sec of %s", xsec)
    
    cardFileName = os.path.join(limitDir, s.name+'.txt')
    if not os.path.exists(cardFileName) or overWrite:
        counter=0
        c.reset()
        c.setPrecision(3)
        postfix = '_%s'%args.year
        c.addUncertainty('PU',                  'lnN') # correlated
        c.addUncertainty('JEC'+postfix,         'lnN') # uncorrelated, for now!
        c.addUncertainty('btag_heavy'+postfix,  'lnN') # uncorrelated, wait for offical recommendation
        c.addUncertainty('btag_light'+postfix,  'lnN') # uncorrelated, wait for offical recommendation
        c.addUncertainty('trigger'+postfix,     'lnN') # uncorrelated, statistics dominated
        c.addUncertainty('leptonSF',            'lnN') # correlated
        c.addUncertainty('scale',               'lnN') # correlated.
        c.addUncertainty('scale_sig',           'lnN') # correlated.
        c.addUncertainty('PDF',                 'lnN') # correlated.
        c.addUncertainty('PartonShower',        'lnN') # correlated.
        c.addUncertainty('nonprompt',           'lnN') # correlated?!
        c.addUncertainty('WZ_xsec',             'lnN') # correlated.
        c.addUncertainty('WZ_bb',               'lnN') # correlated
        c.addUncertainty('WZ_powheg',           'lnN') # correlated
        c.addUncertainty('ZZ_xsec',             'lnN') # correlated.
        c.addUncertainty('ZG_xsec',             'lnN') # correlated.
        c.addUncertainty('rare',                'lnN') # correlated.
        c.addUncertainty('ttX',                 'lnN') # correlated.
        c.addUncertainty('Lumi'+postfix, 'lnN')

        uncList = ['PU', 'JEC', 'btag_heavy', 'btag_light', 'leptonSF', 'trigger']
        for unc in uncList:
            uncertainties[unc] = []
        
        ## use rate parameters??
        #c.addRateParameter('WZ', 1, '[0,2]')
        #c.addRateParameter('ZZ', 1, '[0,2]')

        for setupPair in setups:
            
            # extract the nominal and nonprompt setup from the pair
            setup, setupNP = setupPair
            
            signal      = MCBasedEstimate(name="TTZ", sample=setup.samples["TTZ"], cacheDir=setup.defaultCacheDir())
            #nonprompt   = FakeEstimate(name="nonPromptDD", sample=setup.samples["Data"], setup=setupNP, cacheDir=setup.defaultCacheDir())
            if args.unblind or (setup == setup3l_CR) or (setup == setup4l_CR):
                observation = DataObservation(name="Data", sample=setup.samples["Data"], cacheDir=setup.defaultCacheDir())
                logger.info("Using data!")
            else:
                observation = MCBasedEstimate(name="observation", sample=setup.samples["pseudoData"], cacheDir=setup.defaultCacheDir())
                logger.info("Using pseudo-data!")
            for e in setup.estimators: e.initCache(setup.defaultCacheDir())

            for r in setup.regions:
                totalBackground = u_float(0)
                for channel in setup.channels:
                    niceName = ' '.join([channel.name, r.__str__()])
                    binname = 'Bin'+str(counter)
                    logger.info("Working on %s", binname)
                    counter += 1
                    c.addBin(binname, [e.name.split('-')[0] for e in setup.estimators]+["nonPromptDD"], niceName)
                    #c.addBin(binname, 'nonPromptDD', niceName)

                    for e in setup.estimators:
                        name = e.name.split('-')[0]
                        if name.count('WZ'):
                            logger.info("Using reweighting to powheg for WZ sample")
                            wzReweighting = WZReweighting( cacheDir = reweightCacheWZ )
                            f = wzReweighting.cachedReweightingFunc( setup.WZselection )
                            powhegExpected = e.reweight1D(r, channel, setup, f)
                            expected = e.cachedEstimate(r, channel, setup)
                            print expected
                            WZ_powheg_unc = (powhegExpected-expected)/expected
                        else:
                            expected = e.cachedEstimate(r, channel, setup)
                        logger.info("Adding expectation %s for process %s", expected.val, name)
                        c.specifyExpectation(binname, name, expected.val if expected.val > 0.01 else 0.01)

                        totalBackground += expected

                        if not args.statOnly:
                            # uncertainties
                            pu          = 1 + e.PUSystematic( r, channel, setup).val            if expected.val>0.01 else 1.1
                            jec         = 1 + e.JECSystematic( r, channel, setup).val           if expected.val>0.01 else 1.1
                            btag_heavy  = 1 + e.btaggingSFbSystematic(r, channel, setup).val    if expected.val>0.01 else 1.1
                            btag_light  = 1 + e.btaggingSFlSystematic(r, channel, setup).val    if expected.val>0.01 else 1.1
                            trigger     = 1 + e.triggerSystematic(r, channel, setup).val        if expected.val>0.01 else 1.1
                            leptonSF    = 1 + e.leptonSFSystematic(r, channel, setup).val       if expected.val>0.01 else 1.1
                            if name.count('WZ'):
                                WZ_powheg   = 1 + WZ_powheg_unc.val                                 if expected.val>0.01 else 1.1

                            c.specifyUncertainty('PU',          binname, name, 1 + e.PUSystematic( r, channel, setup).val)
                            if not name.count('nonprompt'):
                                c.specifyUncertainty('JEC'+postfix,         binname, name, jec)
                                c.specifyUncertainty('btag_heavy'+postfix,  binname, name, btag_heavy)
                                c.specifyUncertainty('btag_light'+postfix,  binname, name, btag_light)
                                c.specifyUncertainty('trigger'+postfix,     binname, name, trigger)
                                c.specifyUncertainty('leptonSF',    binname, name, leptonSF)
                                c.specifyUncertainty('scale',       binname, name, 1.01) 
                                c.specifyUncertainty('PDF',         binname, name, 1.01)
                                c.specifyUncertainty('Lumi'+postfix, binname, name, 1.025 )

                            if name.count('ZZ'):    c.specifyUncertainty('ZZ_xsec',     binname, name, 1.10)
                            if name.count('ZG'):    c.specifyUncertainty('ZG_xsec',     binname, name, 1.20)
                            if name.count('WZ'):
                                c.specifyUncertainty('WZ_xsec',     binname, name, 1.10)
                                if setup == setup3l:
                                    c.specifyUncertainty('WZ_bb',     binname, name, 1.08)
                                c.specifyUncertainty('WZ_powheg',     binname, name, WZ_powheg)
                            
                            if name.count('nonprompt'):    c.specifyUncertainty('nonprompt',   binname, name, 1.30)
                            if name.count('rare'):    c.specifyUncertainty('rare',        binname, name, 1.50)
                            if name.count('TTX'):     c.specifyUncertainty('ttX',         binname, name, 1.11)


                        #MC bkg stat (some condition to neglect the smaller ones?)
                        uname = 'Stat_'+binname+'_'+name+postfix
                        c.addUncertainty(uname, 'lnN')
                        if expected.val > 0:
                            c.specifyUncertainty(uname, binname, name, 1 + expected.sigma/expected.val )
                        else:
                            c.specifyUncertainty(uname, binname, name, 1.01 )
                    
                    uname = 'Stat_'+binname+'_nonprompt'+postfix
                    c.addUncertainty(uname, 'lnN')
                    
                    if setup.nLeptons == 3 and setupNP:
                        nonprompt   = FakeEstimate(name="nonPromptDD", sample=setup.samples["Data"], setup=setupNP, cacheDir=setup.defaultCacheDir())
                        np = nonprompt.cachedEstimate(r, channel, setupNP)
                        if np.val < 0.01:
                            np = u_float(0.01,0.)
                        c.specifyExpectation(binname, 'nonPromptDD', np.val ) 
                        c.specifyUncertainty(uname,   binname, "nonPromptDD", 1 + np.sigma/np.val )
                        c.specifyUncertainty('nonprompt',   binname, "nonPromptDD", 1.30)
                    else:
                        np = u_float(0)
                        c.specifyExpectation(binname, 'nonPromptDD', np.val)
                    
                    if args.expected:
                        sig = signal.cachedEstimate(r, channel, setup)
                        obs = totalBackground + sig + np
                    elif args.unblind or (setup == setup3l_CR) or (setup == setup4l_CR):
                        obs = observation.cachedObservation(r, channel, setup)
                    else:
                        obs = observation.cachedEstimate(r, channel, setup)
                    c.specifyObservation(binname, int(round(obs.val,0)) )


                    if args.useShape:
                        logger.info("Using 2D reweighting method for shapes")
                        if args.model == "dim6top_LO":
                            source_gen = dim6top_central
                        elif args.model == "ewkDM":
                            source_gen = ewkDM_central

                        signalReweighting = SignalReweighting( source_sample = source_gen, target_sample = s, cacheDir = reweightCache)
                        f = signalReweighting.cachedReweightingFunc( setup.genSelection )
                        sig = signal.reweight2D(r, channel, setup, f)
                    else:
                        sig = signal.cachedEstimate(r, channel, setup)

                    xSecMod = 1
                    if args.useXSec:
                        xSecMod = xsec.val/xsec_central.val
                    
                    logger.info("x-sec is multiplied by %s",xSecMod)
                    
                    c.specifyExpectation(binname, 'signal', sig.val * xSecScale * xSecMod )
                    logger.info('Adding signal %s'%(sig.val * xSecScale * xSecMod))
                    
                    if sig.val>0:
                        c.specifyUncertainty('Lumi'+postfix, binname, 'signal', 1.025 )
                        if not args.statOnly:
                            # uncertainties
                            pu          = 1 + e.PUSystematic( r, channel, setup).val
                            jec         = 1 + e.JECSystematic( r, channel, setup).val
                            btag_heavy  = 1 + e.btaggingSFbSystematic(r, channel, setup).val
                            btag_light  = 1 + e.btaggingSFlSystematic(r, channel, setup).val
                            trigger     = 1 + e.triggerSystematic(r, channel, setup).val
                            leptonSF    = 1 + e.leptonSFSystematic(r, channel, setup).val

                            if sig.sigma/sig.val < 0.05:
                                uncertainties['PU']         += [pu]
                                uncertainties['JEC']        += [jec]
                                uncertainties['btag_heavy'] += [btag_heavy]
                                uncertainties['btag_light'] += [btag_light]
                                uncertainties['trigger']    += [trigger]
                                uncertainties['leptonSF']   += [leptonSF]

                            c.specifyUncertainty('PU',                  binname, "signal", pu)
                            c.specifyUncertainty('JEC'+postfix,         binname, "signal", jec)
                            c.specifyUncertainty('btag_heavy'+postfix,  binname, "signal", btag_heavy)
                            c.specifyUncertainty('btag_light'+postfix,  binname, "signal", btag_light)
                            c.specifyUncertainty('trigger'+postfix,     binname, "signal", trigger)
                            c.specifyUncertainty('leptonSF',            binname, "signal", leptonSF)
                            # This doesn't get the right uncertainty in CRs. However, signal doesn't matter there anyway.
                            if setup in [setup3l, setup4l]:
                                c.specifyUncertainty('scale_sig',   binname, "signal", 1 + scale_cache.get({"region":r, "channel":channel.name, "PDFset":"scale"}).val)
                                c.specifyUncertainty('PDF',         binname, "signal", 1 + PDF_cache.get({"region":r, "channel":channel.name, "PDFset":PDFset}).val)
                                c.specifyUncertainty('PartonShower',binname, "signal", PS_cache.get({"region":r, "channel":channel.name, "PDFset":"PSscale"}).val) #something wrong here?
                            #c.specifyUncertainty('scale_sig',   binname, "signal", 1.05) #1.30
                            #c.specifyUncertainty('PDF',         binname, "signal", 1.04) #1.15

                        uname = 'Stat_'+binname+'_signal'+postfix
                        c.addUncertainty(uname, 'lnN')
                        c.specifyUncertainty(uname, binname, 'signal', 1 + sig.sigma/sig.val )
                    else:
                        uname = 'Stat_'+binname+'_signal'+postfix
                        c.addUncertainty(uname, 'lnN')
                        c.specifyUncertainty(uname, binname, 'signal', 1 )

                    
        #c.addUncertainty('Lumi'+postfix, 'lnN')
        #c.specifyFlatUncertainty('Lumi'+postfix, 1.026)
        cardFileName = c.writeToFile(cardFileName)
    else:
        logger.info("File %s found. Reusing.",cardFileName)
    
    res = {}
    
    if not os.path.isdir(limitDir):
        os.makedirs(limitDir)
    resDB = resultsDB(limitDir+'/results.sq', "results", setup.resultsColumns)
    res = {"signal":s.name}
    if not overWrite and res.DB.contains(key):
        res = resDB.getDicts(key)[0]
        logger.info("Found result for %s, reusing", s.name)
    else:
        # We don't calculate limits here, but just in case we find a way how to do it, put placeholders here
        res.update({"exp":0, "obs":0, "exp1up":0, "exp2up":0, "exp1down":0, "exp2down":0})
        # Don't extract all the nuisances by default
        signalRegions = range(15,30) ## shouldn't be hardcoded
        masks = ['mask_ch1_Bin'+str(i)+'=1' for i in signalRegions]
        masks = ','.join(masks)

        if args.calcNuisances:
            c.calcNuisances(cardFileName, masks=masks)
        # extract the NLL
        #nll = c.calcNLL(cardFileName, options="")
        nll = c.physicsModel(cardFileName, options="", normList=["WZ_norm","ZZ_norm"], masks=masks) # fastScan turns of profiling
        if nll["nll0"] > 0:
            res.update({"dNLL_postfit_r1":nll["nll"], "dNLL_bestfit":nll["bestfit"], "NLL_prefit":nll["nll0"]})
        else:
            res.update({"dNLL_postfit_r1":-999, "dNLL_bestfit":-999, "NLL_prefit":-999})
            logger.info("Fits failed, adding values -999 as results")
        logger.info("Adding results to database")
        resDB.add(res, nll['nll_abs'], overwrite=True)

    print
    print "NLL results:"
    print "{:>15}{:>15}{:>15}".format("Pre-fit", "Post-fit r=1", "Best fit")
    print "{:15.2f}{:15.2f}{:15.2f}".format(float(res["NLL_prefit"]), float(res["NLL_prefit"])+float(res["dNLL_postfit_r1"]), float(res["NLL_prefit"])+float(res["dNLL_bestfit"]))
    
    print 'PU', min(uncertainties['PU']), max(uncertainties['PU'])
    print 'JEC', min(uncertainties['JEC']), max(uncertainties['JEC'])
    print 'btag_heavy', min(uncertainties['btag_heavy']), max(uncertainties['btag_heavy'])
    print 'btag_light', min(uncertainties['btag_light']), max(uncertainties['btag_light'])
    print 'trigger', min(uncertainties['trigger']), max(uncertainties['trigger'])
    print 'leptonSF', min(uncertainties['leptonSF']), max(uncertainties['leptonSF'])
Esempio n. 2
0
def wrapper(s):
    
    logger.info("Now working on %s", s.name)
    xSecScale = 1
    c = cardFileWriter.cardFileWriter()
    c.releaseLocation = combineReleaseLocation

    for coup in nonZeroCouplings:
        modification_dict[coup] = getCouplingFromName(s.name, coup)
        logger.info("The following coupling is set to non-zero value: %s: %s", coup, modification_dict[coup])
    
    xsec = p.xsecDB.get(modification_dict)
    logger.info("Found modified x-sec of %s", xsec)
    
    cardFileName = os.path.join(limitDir, s.name+'.txt')
    if not os.path.exists(cardFileName) or overWrite:
        counter=0
        c.reset()
        c.addUncertainty('PU',          'lnN')
        c.addUncertainty('JEC',         'lnN')
        c.addUncertainty('btag',        'lnN')
        c.addUncertainty('trigger',     'lnN')
        c.addUncertainty('leptonSF',    'lnN')
        c.addUncertainty('scale',       'lnN')
        c.addUncertainty('scale_sig',   'lnN')
        c.addUncertainty('PDF',         'lnN')
        c.addUncertainty('nonprompt',   'lnN')
        c.addUncertainty('WZ_xsec',     'lnN')
        c.addUncertainty('ZZ_xsec',     'lnN')
        c.addUncertainty('rare',        'lnN')
        c.addUncertainty('ttX',         'lnN')
        c.addUncertainty('tZq',         'lnN')


        for setup in setups:
            signal      = MCBasedEstimate(name="TTZ", sample=setup.samples["TTZ"], cacheDir=setup.defaultCacheDir())
            observation = MCBasedEstimate(name="observation", sample=setup.samples["pseudoData"], cacheDir=setup.defaultCacheDir())
            #observation = DataObservation(name='Data', sample=setup.sample['pseudoData'], cacheDir=setup.defaultCacheDir())
            for e in setup.estimators: e.initCache(setup.defaultCacheDir())

            for r in setup.regions:
                for channel in setup.channels:
                    niceName = ' '.join([channel, r.__str__()])
                    binname = 'Bin'+str(counter)
                    counter += 1
                    c.addBin(binname, [e.name.split('-')[0] for e in setup.estimators], niceName)

                    for e in setup.estimators:
                        name = e.name.split('-')[0]
                        expected = e.cachedEstimate(r, channel, setup)
                        c.specifyExpectation(binname, name, round(expected.val,3) if expected.val > 0 else 0.01)

                        if expected.val>0:
                            if not args.statOnly:
                                c.specifyUncertainty('PU',          binname, name, 1.01) 
                                c.specifyUncertainty('JEC',         binname, name, 1.03) #1.05
                                c.specifyUncertainty('btag',        binname, name, 1.03) #1.05
                                c.specifyUncertainty('trigger',     binname, name, 1.03) #1.04
                                c.specifyUncertainty('leptonSF',    binname, name, 1.05) #1.07
                                c.specifyUncertainty('scale',       binname, name, 1.01) 
                                c.specifyUncertainty('PDF',         binname, name, 1.01) 

                                if name.count('ZZ'):      c.specifyUncertainty('ZZ_xsec',     binname, name, 1.20) #1.20
                                if name.count('WZ'):      c.specifyUncertainty('WZ_xsec',     binname, name, 1.10) #1.20
                                if name.count('nonprompt'):    c.specifyUncertainty('nonprompt',   binname, name, 1.30)
                                if name.count('rare'):    c.specifyUncertainty('rare',        binname, name, 1.50)
                                if name.count('TTX'):     c.specifyUncertainty('ttX',         binname, name, 1.10) #1.15
                                if name.count('TZQ'):     c.specifyUncertainty('tZq',         binname, name, 1.10) #1.15


                            #MC bkg stat (some condition to neglect the smaller ones?)
                            uname = 'Stat_'+binname+'_'+name
                            c.addUncertainty(uname, 'lnN')
                            c.specifyUncertainty(uname, binname, name, round(1+expected.sigma/expected.val,3) )

                    obs = observation.cachedEstimate(r, channel, setup)
                    c.specifyObservation(binname, int(round(obs.val,0)))

                    if args.useShape:
                        logger.info("Using 2D reweighting method for shapes")
                        if args.model == "dim6top_LO":
                            source_gen = dim6top_LO_ttZ_ll_ctZ_0p00_ctZI_0p00
                        elif args.model == "ewkDM":
                            source_gen = ewkDM_central
                        target_gen = s

                        signalReweighting = SignalReweighting( source_sample = source_gen, target_sample = s, cacheDir = reweightCache)
                        f = signalReweighting.cachedReweightingFunc( setup.genSelection )
                        sig = signal.reweight2D(r, channel, setup, f)
                    else:
                        sig = signal.cachedEstimate(r, channel, setup)

                    xSecMod = 1
                    if args.useXSec:
                        xSecMod = xsec.val/xsec_central.val
                    
                    logger.info("x-sec is multiplied by %s",xSecMod)
                    
                    c.specifyExpectation(binname, 'signal', round(sig.val*xSecScale * xSecMod, 3) )
                    
                    if sig.val>0:
                        if not args.statOnly:
                            c.specifyUncertainty('PU',          binname, "signal", 1.01)
                            c.specifyUncertainty('JEC',         binname, "signal", 1.03) #1.05
                            c.specifyUncertainty('btag',        binname, "signal", 1.03) #1.05
                            c.specifyUncertainty('trigger',     binname, "signal", 1.03) #1.04
                            c.specifyUncertainty('leptonSF',    binname, "signal", 1.05) #1.07
                            c.specifyUncertainty('scale_sig',   binname, "signal", 1.10) #1.30
                            c.specifyUncertainty('PDF',         binname, "signal", 1.05) #1.15

                        uname = 'Stat_'+binname+'_signal'
                        c.addUncertainty(uname, 'lnN')
                        c.specifyUncertainty(uname, binname, 'signal', round(1 + sig.sigma/sig.val,3) )
                    else:
                        uname = 'Stat_'+binname+'_signal'
                        c.addUncertainty(uname, 'lnN')
                        c.specifyUncertainty(uname, binname, 'signal', 1 )

                    
        c.addUncertainty('Lumi', 'lnN')
        c.specifyFlatUncertainty('Lumi', 1.026)
        cardFileName = c.writeToFile(cardFileName)
    else:
        logger.info("File %s found. Reusing.",cardFileName)
    
    res = {}
    
    if getResult(s) and not overWrite:
        res = getResult(s)
        logger.info("Found result for %s, reusing", s.name)
    else:
        # calculate the limit
        #limit = c.calcLimit(cardFileName)#, options="--run blind")
        #res.update({"exp":limit['0.500'], "obs":limit['-1.000'], "exp1up":limit['0.840'], "exp2up":limit['0.975'], "exp1down":limit['0.160'], "exp2down":limit['0.025']})
        res.update({"exp":0, "obs":0, "exp1up":0, "exp2up":0, "exp1down":0, "exp2down":0})
        # run the checks
        c.calcNuisances(cardFileName)
        # extract the NLL
        nll = c.calcNLL(cardFileName, options="--fastScan")
        if nll["nll0"] > 0:
            res.update({"dNLL_postfit_r1":nll["nll"], "dNLL_bestfit":nll["bestfit"], "NLL_prefit":nll["nll0"]})
        else:
            res.update({"dNLL_postfit_r1":-999, "dNLL_bestfit":-999, "NLL_prefit":-999})
            logger.info("Fits failed, adding values -999 as results")
        logger.info("Adding results to database")
        addResult(s, res, nll['nll_abs'], overwrite=True)
        
    print
    print "NLL results:"
    print "{:>15}{:>15}{:>15}".format("Pre-fit", "Post-fit r=1", "Best fit")
    print "{:15.2f}{:15.2f}{:15.2f}".format(float(res["NLL_prefit"]), float(res["NLL_prefit"])+float(res["dNLL_postfit_r1"]), float(res["NLL_prefit"])+float(res["dNLL_bestfit"]))
    
    if xSecScale != 1:
        for k in res:
            res[k] *= xSecScale
Esempio n. 3
0
def wrapper(s):

    logger.info("Now working on %s", s.name)

    c = cardFileWriter.cardFileWriter()
    c.releaseLocation = combineReleaseLocation
    cards = {}
    
    # get the seperated cards
    for year in [2016,2017]:
        
        subDir = ''
        cardDir = "regionsE_%s"%(year)
        if args.useXSec: cardDir += "_xsec"
        if args.useShape: cardDir += "_shape"
        exp = "_expected" if args.expected else ''
        cardDir += "_lowUnc%s"%exp
        if args.includeCR: cardDir += "_SRandCR"


        baseDir = os.path.join(analysis_results)
        limitDir    = os.path.join(baseDir, 'cardFiles', cardDir, subDir, '_'.join([args.model, args.signal]))
        #resDB = resultsDB(limitDir+'/results.sq', "results", setup.resultsColumns)
        
        cardFileName = os.path.join(limitDir, s.name+'.txt')

        if not os.path.isfile(cardFileName):
            raise IOError("File %s doesn't exist!"%cardFileName)

        cards[year] = cardFileName
    
    limitDir = limitDir.replace('2017','COMBINED')
    
    # run combine and store results in sqlite database
    if not os.path.isdir(limitDir):
        os.makedirs(limitDir)
    resDB = resultsDB(limitDir+'/results.sq', "results", setup.resultsColumns)
    res = {"signal":s.name}

    overWrite = True

    if not overWrite and res.DB.contains(key):
        res = resDB.getDicts(key)[0]
        logger.info("Found result for %s, reusing", s.name)

    else:
        signalRegions = range(15,30)
        masks_2016 = ['mask_ch1_dc_2016_Bin'+str(i)+'=1' for i in signalRegions]
        masks_2017 = ['mask_ch1_dc_2017_Bin'+str(i)+'=1' for i in signalRegions]
    
        masks = ','.join(masks_2016+masks_2017)
        
        combinedCard = c.combineCards( cards )
        
        # We don't calculate limits here, but just in case we find a way how to do it, put placeholders here
        res.update({"exp":0, "obs":0, "exp1up":0, "exp2up":0, "exp1down":0, "exp2down":0})
        # Don't extract all the nuisances by default

        if args.calcNuisances:
            c.calcNuisances(combinedCard, masks=masks)

        #nll = c.physicsModel(combinedCard, options="", normList=["WZ_norm","ZZ_norm"], masks=masks) # fastScan turns of profiling
        nll = c.calcNLL(combinedCard)

        if nll["nll0"] > 0:
            res.update({"dNLL_postfit_r1":nll["nll"], "dNLL_bestfit":nll["bestfit"], "NLL_prefit":nll["nll0"]})
        else:
            res.update({"dNLL_postfit_r1":-999, "dNLL_bestfit":-999, "NLL_prefit":-999})
            logger.info("Fits failed, adding values -999 as results")
        logger.info("Adding results to database")
        resDB.add(res, nll['nll_abs'], overwrite=True)


    logger.info("Results stored in %s", limitDir)
Esempio n. 4
0
def wrapper(s):
    xSecScale = 1
    c = cardFileWriter.cardFileWriter()
    c.releaseLocation = combineReleaseLocation

    cardFileName = os.path.join(limitDir, s.name + '.txt')
    if not os.path.exists(cardFileName) or overWrite:
        counter = 0
        c.reset()
        c.addUncertainty('PU', 'lnN')
        c.addUncertainty('JEC', 'lnN')
        c.addUncertainty('btag', 'lnN')
        c.addUncertainty('trigger', 'lnN')
        c.addUncertainty('leptonSF', 'lnN')
        c.addUncertainty('scale', 'lnN')
        c.addUncertainty('scale_sig', 'lnN')
        c.addUncertainty('PDF', 'lnN')
        c.addUncertainty('nonprompt', 'lnN')
        c.addUncertainty('WZ_xsec', 'lnN')
        c.addUncertainty('ZZ_xsec', 'lnN')
        c.addUncertainty('rare', 'lnN')
        c.addUncertainty('ttX', 'lnN')
        c.addUncertainty('tZq', 'lnN')

        for setup in setups:
            for r in setup.regions:
                for channel in setup.channels:
                    niceName = ' '.join([channel, r.__str__()])
                    binname = 'Bin' + str(counter)
                    counter += 1
                    c.addBin(binname, [p.name for p in processes], niceName)

                    for p in processes:
                        name = p.name
                        expected = getEstimate(
                            p, r, channel
                        )  #{"process":nam, "region":r, "lumi":35.9, "presel":"nLep==3&&isTTZ&&nJetGodd>2&&nBTag>0", "weightString":"weight", "channel":channel})
                        c.specifyExpectation(binname, name, expected.val)

                        if expected.val > 0:
                            c.specifyUncertainty('PU', binname, name, 1.01)
                            c.specifyUncertainty('JEC', binname, name, 1.05)
                            c.specifyUncertainty('btag', binname, name, 1.05)
                            c.specifyUncertainty('trigger', binname, name,
                                                 1.04)
                            c.specifyUncertainty('leptonSF', binname, name,
                                                 1.07)
                            c.specifyUncertainty('scale', binname, name, 1.01)
                            c.specifyUncertainty('PDF', binname, name, 1.01)

                            if name.count('ZZ'):
                                c.specifyUncertainty('ZZ_xsec', binname, name,
                                                     1.20)
                            if name.count('WZ'):
                                c.specifyUncertainty('WZ_xsec', binname, name,
                                                     1.20)
                            if name.count('nonprompt'):
                                c.specifyUncertainty('nonprompt', binname,
                                                     name, 1.30)
                            if name.count('rare'):
                                c.specifyUncertainty('rare', binname, name,
                                                     1.50)
                            if name.count('TTX'):
                                c.specifyUncertainty('ttX', binname, name,
                                                     1.15)
                            if name.count('TZQ'):
                                c.specifyUncertainty('tZq', binname, name,
                                                     1.15)

                            #MC bkg stat (some condition to neglect the smaller ones?)
                            uname = 'Stat_' + binname + '_' + name
                            c.addUncertainty(uname, 'lnN')
                            c.specifyUncertainty(
                                uname, binname, name,
                                1 + expected.sigma / expected.val)

                    c.specifyObservation(
                        binname,
                        int(round((getEstimate(
                            pseudoData, r,
                            channel).val))))  #can also be pseudoDataPriv

                    #signalSetup = setup.systematicClone()
                    signal = getEstimate(
                        s, r, channel
                    )  #resultsCache.get({"process":s.name, "region":r, "lumi":35.9, "presel":"nLep==3&&isTTZ&&nJetGodd>2&&nBTag>0", "weightString":"weight", "channel":channel})
                    c.specifyExpectation(binname, 'signal',
                                         signal.val * xSecScale)

                    if signal.val > 0:
                        c.specifyUncertainty('PU', binname, "signal", 1.01)
                        c.specifyUncertainty('JEC', binname, "signal", 1.05)
                        c.specifyUncertainty('btag', binname, "signal", 1.05)
                        c.specifyUncertainty('trigger', binname, "signal",
                                             1.04)
                        c.specifyUncertainty('leptonSF', binname, "signal",
                                             1.07)
                        c.specifyUncertainty('scale_sig', binname, "signal",
                                             1.30)
                        c.specifyUncertainty('PDF', binname, "signal", 1.15)

                        uname = 'Stat_' + binname + '_signal'
                        c.addUncertainty(uname, 'lnN')
                        c.specifyUncertainty(uname, binname, 'signal',
                                             1 + signal.sigma / signal.val)
                    else:
                        uname = 'Stat_' + binname + '_signal'
                        c.addUncertainty(uname, 'lnN')
                        c.specifyUncertainty(uname, binname, 'signal', 1)

                    ## alternative signal model
                    #signal_ALT = getEstimate(s, r, channel)
                    #c.specifyExpectation(binname, 'signal_ALT', signal_ALT.val*xSecScale )
                    #
                    #if signal_ALT.val>0:
                    #    c.specifyUncertainty('PU',          binname, "signal_ALT", 1.01)
                    #    c.specifyUncertainty('JEC',         binname, "signal_ALT", 1.05)
                    #    c.specifyUncertainty('btag',        binname, "signal_ALT", 1.05)
                    #    c.specifyUncertainty('trigger',     binname, "signal_ALT", 1.04)
                    #    c.specifyUncertainty('leptonSF',    binname, "signal_ALT", 1.07)
                    #    c.specifyUncertainty('scale_sig',   binname, "signal_ALT", 1.30)
                    #    c.specifyUncertainty('PDF',         binname, "signal_ALT", 1.15)

                    #    uname = 'Stat_'+binname+'_signal_ALT'
                    #    c.addUncertainty(uname, 'lnN')
                    #    c.specifyUncertainty(uname, binname, 'signal_ALT', 1 + signal_ALT.sigma/signal_ALT.val )
                    #else:
                    #    uname = 'Stat_'+binname+'_signal_ALT'
                    #    c.addUncertainty(uname, 'lnN')
                    #    c.specifyUncertainty(uname, binname, 'signal_ALT', 1 )

        c.addUncertainty('Lumi', 'lnN')
        c.specifyFlatUncertainty('Lumi', 1.026)
        cardFileName = c.writeToFile(cardFileName)
    else:
        print "File %s found. Reusing." % cardFileName

    res = {}

    if getResult(s) and not overWrite:
        res = getResult(s)
        print "Found result for %s, reusing" % s.name
    else:
        # calculate the limit
        limit = c.calcLimit(cardFileName)  #, options="--run blind")
        res.update({
            "exp": limit['0.500'],
            "obs": limit['-1.000'],
            "exp1up": limit['0.840'],
            "exp2up": limit['0.975'],
            "exp1down": limit['0.160'],
            "exp2down": limit['0.025']
        })
        # run the checks
        c.calcNuisances(cardFileName)
        # extract the NLL
        nll = c.calcNLL(cardFileName)
        res.update({
            "dNLL_postfit_r1": nll["nll"],
            "dNLL_bestfit": nll["bestfit"],
            "NLL_prefit": nll["nll0"]
        })
        addResult(s, res, nll['nll_abs'], overwrite=True)

    print "NLL results:"
    print "{:>15}{:>15}{:>15}".format("Pre-fit", "Post-fit r=1", "Best fit")
    print "{:15.2f}{:15.2f}{:15.2f}".format(
        float(res["NLL_prefit"]),
        float(res["NLL_prefit"]) + float(res["dNLL_postfit_r1"]),
        float(res["NLL_prefit"]) + float(res["dNLL_bestfit"]))

    if xSecScale != 1:
        for k in res:
            res[k] *= xSecScale
Esempio n. 5
0
    histo.Add(histos[i_histo + 1])
    histos[i_histo + 1].Scale(-1)

# compute differences
h_signal, h_backgrounds = histos[0], histos[1:]

logger.info("Total signal %s %f", h_signal.GetName(), h_signal.Integral())
for i_h, h in enumerate(h_backgrounds):
    logger.info("Total bkg %i %s: %f", i_h, h.GetName(), h.Integral())

result = {}

lumi_factor = 136. / 300.
signal_strengths = [0, 0.25, 0.5, 0.75, 1., 1.5, 2, 2.2]
for signal_strength in signal_strengths:
    c = cardFileWriter.cardFileWriter()

    bkg_sys = 1.1
    bkg_shape_sys = 1.1

    for i in range(len(h_backgrounds)):
        c.addUncertainty('bkg_sys_%i' % i, 'lnN')
        c.addUncertainty('bkg_shape_sys_%i' % i, 'lnN')

    c.addUncertainty('sig_sys', 'lnN')
    sig_sys = 1.25

    for i_bin in range(1, 1 + h_signal.GetNbinsX()):
        c.addBin('Bin' + str(i_bin), [h.GetName() for h in h_backgrounds],
                 'Bin' + str(i_bin))
        y_signal = h_signal.GetBinContent(i_bin)