"marker": 22, "color": ROOT.kGreen + 2 } } processes = ["ttZ", "ttH", "ttW"] SM_xsec = {} modified_couplings = {args.coupling: 0.0} for proc in processes: logger.info("Checking SM x-sec:") config = Configuration(model_name=model_name, modified_couplings=modified_couplings) p = Process(process=proc, nEvents=50000, config=config) SM_xsec[proc] = p.xsec() logger.info("SM x-sec for %s is %s", proc, SM_xsec[proc]) if SM_xsec[proc].val == 0.: SM_xsec[proc] = u_float(1) del config hists = [] fits = [] m = 0 if args.scale: scale = lambdaSqInv[args.coupling] else: scale = 1
if args.signal == "dipoles": nonZeroCouplings = ["DC2A","DC2V"] elif args.signal == "currents": nonZeroCouplings = ["DC1A", "DC1V"] # for safety, set all couplings to 0. modification_dict["DC1A"] = 0. modification_dict["DC1V"] = 0. modification_dict["DC2A"] = 0. modification_dict["DC2V"] = 0. logger.info("Using model %s in plane: %s", args.model, args.signal) logger.info("Will scan the following coupling values: %s and %s", nonZeroCouplings[0], nonZeroCouplings[1]) p = Process(process = "ttZ_ll", nEvents = 5000, config = config, xsec_cache=xsecDB) xsec_central = p.xsecDB.get(modification_dict) if year == 2016: PDFset = "NNPDF30" TTZ_sample = "TTZ_NLO" elif year == 2017: PDFset = "NNPDF30" TTZ_sample = "TTZ_NLO_17" elif year == 20167: PDFset = "NNPDF30" TTZ_sample = "TTZ_NLO" logger.info("Will use PDF and scale uncertainties based on 2016.") # always use PDF4LHC set for now, only included in Fall17
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'])
# Check that we have an even number of arguments if not len(args.couplings) % 2 == 0: logger.error( "Need an even number of coupling arguments of the format coupling1, value1, coupling2, value2, ... . Got %r", args.couplings) # Interpret coupling argument list coupling_names = args.couplings[::2] coupling_values = map(float, args.couplings[1::2]) modified_couplings = {c: v for c, v in zip(coupling_names, coupling_values)} # Let's not leave the user in the dark logger.info("Model: %s", args.model) logger.info("Process: %s", args.process) logger.info("Couplings: %s", ", ".join(["%s=%5.4f" % c for c in modified_couplings.items()])) # Create configuration class config = Configuration(model_name=args.model) #p = Process(process = args.process, nEvents = 1, config = config, modified_couplings = modified_couplings ) p = Process(process=args.process, nEvents=1, config=config) xsec_val = p.diagrams(plot_dir=plot_directory, modified_couplings=modified_couplings) config.cleanup() logger.info("Done! Calculated xsec: %s ", repr(xsec_val))
logger = logger.get_logger(args.logLevel, logFile=None) if len(args.couplings) % 2 == 0: param_points = args.couplings else: logger.error( "Need an even number of coupling arguments of the format coupling1, value1, coupling2, value2, ... . Got %r", args.couplings) raise ValueError # Create configuration class config = Configuration(model_name=args.model) if args.dbfile: p = Process(process=args.process, nEvents=args.nEvents, config=config, xsec_cache=args.dbfile) else: p = Process(process=args.process, nEvents=args.nEvents, config=config) names = param_points[::2] values = map(float, param_points[1::2]) print values modification_dict = {c: v for c, v in zip(names, values)} modification_dict["process"] = args.process modification_dict["nEvents"] = args.nEvents p.xsecDB.getTable(modification_dict)
len(param_points)) # Interpret coupling argument list names = param_point[::2] values = map(float, param_point[1::2]) modification_dict = {c: v for c, v in zip(names, values)} # Let's not leave the user in the dark logger.info("Model: %s", args.model) logger.info("Process: %s", args.process) logger.info("Couplings: %s", ", ".join(["%s=%5.4f" % c for c in modification_dict.items()])) # make process p = Process(process=args.process, nEvents=args.nEvents, config=config) # Make grid pack if args.makeGridpack: gridpack = p.makeGridpack(modified_couplings=modification_dict, overwrite=args.overwrite) # calculate x-sec if args.calcXSec: xsec = p.xsec(modified_couplings=modification_dict, overwrite=args.overwrite) logger.info("xsec: %s ", repr(xsec)) if not args.keepWorkspace: config.cleanup()
subDir = '' baseDir = os.path.join(analysis_results, subDir) limitDir = os.path.join(baseDir, 'cardFiles', setup.name, args.signal + args.extension) overWrite = (args.only is not None) or args.overwrite reweightCache = os.path.join( results_directory, 'SignalReweightingTemplate' ) from TopEFT.Generation.Configuration import Configuration from TopEFT.Generation.Process import Process from TopEFT.Tools.u_float import u_float config = Configuration( model_name = "dim6top_LO" ) p = Process(process = "ttZ_ll", nEvents = 5000, config = config) modification_dict = {"process":"ttZ_ll"} modification_dict["ctZ"] = 0. modification_dict["ctZi"] = 0. modification_dict["cpQM"] = 0. modification_dict["cpt"] = 0. xsec_central = p.xsecDB.get(modification_dict) def wrapper(s): logger.info("Now working on %s", s.name) xSecScale = 1 c = cardFileWriter.cardFileWriter() c.releaseLocation = combineReleaseLocation
hists = [] cans = [] pads = [] SM_xsec = {} latex1 = ROOT.TLatex() latex1.SetNDC() latex1.SetTextSize(0.04) latex1.SetTextAlign(11) logger.info("Model: %s", model_name) for proc in processes[:1]: logger.info("Starting with process %s", proc) config = Configuration(model_name=model_name) p = Process(process=proc, nEvents=50000, config=config) SM_xsec[proc] = p.xsec(modified_couplings={}) logger.info("SM x-sec: %s", SM_xsec[proc]) for comb in combinations: logger.info("Making 2D plots for %s", comb) fixedPoints = list(nonZeroCouplings) subDir = "{}_vs_{}".format(comb[0], comb[1]) if interpolate: subDir += "_interpolated" for c in comb: fixedPoints.remove(c) for v in points[fixedPoints[0]]: for w in points[fixedPoints[1]]: