if args.nonInfoSignal: rate[region]['signal'] += ttZISRSample.weightInfo.get_weight_yield( nonInfo_coeffList, **params ) for i_region, region in enumerate(regions): totalUncertainty = 0 for i, s in enumerate( [ttXSample] + bg ): hists[s.shortname].SetBinContent(i_region+1, rate[region][s.shortname]) hists[s.shortname].SetBinError(i_region+1,0) hists[s.shortname].legendText = s.shortname.replace('gamma', '#gamma') # hists[s.shortname].style = styles.fillStyle( s.color, lineColor=s.color if i!=0 else ROOT.kBlack, errors=False, width=0 if i!=0 else 2 ) hists[s.shortname].style = styles.fillStyle( s.color, lineColor=ROOT.kBlack, errors=False, width=1 if i!=0 else 2 ) if args.addUncertainties and s.name != ttXSample.name: for unc in uncertainties: totalUncertainty += (abs(getUncertaintyValue( 'TTXPhenoCardFile.txt', i_region, '_'.join(s.name.split('_')[1:3]), unc ) - 1) * rate[region][s.shortname])**2 if args.nonInfoSignal: hists['nonInfo'].SetBinContent(i_region+1, rate[region]['nonInfo']) hists['nonInfo'].SetBinError(i_region+1,0) hists['nonInfo'].legendText = ttXSample.shortname.replace('gamma', '#gamma') + ' (non-info)' hists['nonInfo'].style = styles.fillStyle( colors['nonInfo'], lineColor=ROOT.kBlack, errors=False, width=1, fillStyle=3345, hatchesWidth=1, hatchesSpacing=None ) # hists['nonInfo'].style = styles.fillStyle( colors['nonInfo'], lineColor=colors['nonInfo'], errors=False ) # hists['nonInfo'].SetFillStyle(3345) # hists['nonInfo'].SetFillStyle(3005) # hists['nonInfo'].SetFillStyle(3544) # hists['nonInfo'].SetFillColor(ROOT.kWhite) # hists['nonInfo'].SetLineWidth(1) # hists['nonInfo'].SetLineColor(ROOT.kBlack) # ROOT.gStyle.SetHatchesLineWidth(2) # ROOT.gStyle.SetHatchesSpacing(1.1)
totalUncertainty = 0 for i_s, s in enumerate([ttXSample] + bg): hists[s.shortname].SetBinContent(i_region + 1, rate[region][s.shortname]) hists[s.shortname].SetBinError(i_region + 1, 0) hists[s.shortname].legendText = s.shortname.replace('gamma', '#gamma') hists[s.shortname].style = styles.fillStyle(s.color, lineColor=ROOT.kBlack, errors=False, width=1 if i_s != 0 else 3) if args.addUncertainties and s.name != ttXSample.name: for unc in uncertainties: totalUncertainty += (abs( getUncertaintyValue(args.cardFile, i_region, '_'.join( s.name.split('_')[1:3]), unc) - 1) * rate[region][s.shortname])**2 if args.nonInfoSignal: hists['nonInfo'].SetBinContent(i_region + 1, rate[region]['nonInfo']) hists['nonInfo'].SetBinError(i_region + 1, 0) hists['nonInfo'].legendText = ttXSample.shortname.replace( 'gamma', '#gamma') + ' (non-info)' hists['nonInfo'].style = styles.fillStyle(colors['nonInfo'], lineColor=ROOT.kBlack, errors=False, width=1, fillStyle=3645, hatchesWidth=1, hatchesSpacing=None) # hists['nonInfo'].style = styles.fillStyle( colors['nonInfo'], lineColor=ROOT.kBlack, errors=False, width=1 )
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
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)