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
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 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
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)