def mc_amount(cut, weight, lumi=12210, ref=None): histsD = dict() for samp in samples: histsD[samp.name] = samp.drawHistogram("mu_pt", str(cut), dtype="float", weight=weight, plot_range=[100, 0, 100000000]) for name, hist in histsD.items(): hist.normalize_lumi(lumi) for name, hist in histsD.items(): histsD[name] = hist.hist merge_cmd = dict() merge_cmd["t-channel incl"] = ["T_t", "Tbar_t"] merge_cmd["t-channel excl"] = ["T_t_ToLeptons", "Tbar_t_ToLeptons"] merge_cmd["t#bar{t} excl"] = ["TTJets_FullLept", "TTJets_SemiLept"] merge_cmd["QCD (MC)"] = ["QCDMu"] merge_cmd["t#bar{t} incl"] = ["TTJets_MassiveBinDECAY"] merge_cmd["WJets incl"] = ["WJets_inclusive"] merge_cmd["WJets excl"] = [ "W1Jets_exclusive", "W2Jets_exclusive", "W3Jets_exclusive", "W4Jets_exclusive" ] merged_hists = merge_hists(histsD, merge_cmd) normd = dict() for hn, h in merged_hists.items(): normd[hn] = get_hist_int_err(h) return merged_hists, normd
def compare_plot(plot_def): """ Draws a comparison plot based on a plot definition dictionary, which has the following arguments: *mandatory* var: a string with the TTree branch name / TFormula expression to plot plot_range: the plot range definition for Sample.drawHistogram items: a list of tuples, containing the plots to be drawn in the following format [ (name_of_plot, pathname_of_file, filename, cut_object, weight_object) ] *optional* lumi: the luminosity to normalize to in /pb merge_cmds: a merge command for the merge_hists method, which merges the histograms according to the names in the items list hist_callback: a method that is called on each of the histograms after merging, having the form: def f(hist_name, hist): dostuff return hist x_label: a string the the label for the x axis *returns* a tuple (canvas, final_histogram_dict) """ proc_cuts = plot_def['items'] var = plot_def.get('var') plot_range = plot_def.get('range') lumi = plot_def.get('lumi', 20000) merge_cmds = plot_def.get('merge_cmds', None) hist_callback = plot_def.get('hist_callback', None) x_label = plot_def.get('xlab', 'xlab') hists = {} for name, path, fname, cut, weight in proc_cuts: fname = join(path, fname) sample = Sample.fromFile(fname) hists[name] = sample.drawHistogram(var, str(cut), weight=str(weight), plot_range=plot_range) hists[name].SetName(name) hists[name] = copy.deepcopy(hists[name]) hists[name].Scale(sample.lumiScaleFactor(lumi)) if merge_cmds: hists_merged = merge_hists(hists, merge_cmds) hists = hists_merged if hist_callback: for hn, h in hists.items(): hists[hn] = hist_callback(hn, h) canv = plot_hists_dict(hists, x_label=x_label) return canv, hists
def mc_amount(cut, weight, lumi=12210, ref=None): histsD = dict() for samp in samples: histsD[samp.name] = samp.drawHistogram("mu_pt", str(cut), dtype="float", weight=weight, plot_range=[100, 0, 100000000]) histsD[samp.name].Scale(samp.lumiScaleFactor(lumi)) merge_cmd = dict() merge_cmd["t-channel incl"] = ["T_t", "Tbar_t"] merge_cmd["t-channel excl"] = ["T_t_ToLeptons", "Tbar_t_ToLeptons"] merge_cmd["t#bar{t} excl"] = ["TTJets_FullLept", "TTJets_SemiLept"] merge_cmd["QCD (MC)"] = ["QCDMu"] merge_cmd["t#bar{t} incl"] = ["TTJets_MassiveBinDECAY"] merge_cmd["WJets incl"] = ["WJets_inclusive"] merge_cmd["WJets excl"] = ["W1Jets_exclusive", "W2Jets_exclusive", "W3Jets_exclusive", "W4Jets_exclusive"] merged_hists = merge_hists(histsD, merge_cmd) normd = dict() for hn, h in merged_hists.items(): normd[hn] = get_hist_int_err(h) return merged_hists, normd
} recreate = True if recreate: for sn in sampnames: sample = Sample.fromFile(path + "/" + sn + ".root") for wn, w in weights: hi = sample.drawHistogram(var, str(cut), weight=w, plot_range=plot_range) hi.Scale(sample.lumiScaleFactor(lumi)) hists[wn][sample.name] = hi merged = dict() for wn, w in weights: merged[wn] = merge_hists(hists[wn], merge_cmds) hc = HistCollection(merged[wn], name="bweight_%s" % wn) hc.save(".") colls = dict() for wn, w in weights: hc = HistCollection.load("./bweight_%s.root" % wn) colls[wn] = hc for proc in merge_cmds.keys(): hists = OrderedDict([(wn, colls[wn].hists[proc]) for wn, w in weights]) for hn, h in hists.items(): h.SetTitle(pretty_names_weights[hn]) hists_normed = copy.deepcopy(hists)
def combine_templates(templates, patterns, conf): """ Args: """ hists = {} hsources = [] for k in ["data", "mc_nom", "mc_varsamp", "mc_varproc"]: items = templates[patterns[k]] if len(items)==0: raise MatchingException("Nothing matched to %s:%s" % (k, patterns[k])) hsources += items if len(hsources)==0: raise ValueError("No histograms matched") hqcd = NestedDict() hqcd["nominal"][None] = [] for syst in ["yield", "iso"]: for sdir in ["up", "down"]: hqcd[syst][sdir] = [] templates_qcd = templates[patterns["data_antiiso"]] if len(templates_qcd)==0: raise MatchingException("Nothing matched to %s:%s" % ("data_antiiso", patterns["data_antiiso"])) for keys, hist in templates[patterns["data_antiiso"]]: if keys[1].startswith("antiiso"): #We have isolation variations isodir = keys[1].split("_")[1] if isodir=="nominal": hqcd["nominal"][None].append(hist) hup = hist.Clone() hdown = hist.Clone() hup.Scale(qcd_yield_variations[0]) hdown.Scale(qcd_yield_variations[1]) hqcd["yield"]["up"].append(hup) hqcd["yield"]["down"].append(hdown) elif isodir in ["up", "down"]: hqcd["iso"][isodir].append(hist) else: raise ValueError("Undefined isolation variation direction: %s" % isodir) #We only have the nominal QCD shape elif keys[1]=="weight__unweighted": hqcd["nominal"][None].append(hist) hup = hist.Clone() hdown = hist.Clone() hup.Scale(qcd_yield_variations[0]) hdown.Scale(qcd_yield_variations[1]) hqcd["yield"]["up"].append(hup) hqcd["yield"]["down"].append(hdown) #Placeholders for the isolation variation for isodir in ["up", "down"]: h = hist.Clone() hqcd["iso"][isodir].append(h) else: raise Exception("Couldn't parse the QCD pattern: %s" % str(keys)) def map_leaves(di, f, equate=True): for k, v in di.items(): if isinstance(v, dict): map_leaves(v, f) else: if equate: di[k] = f(v) else: f(v) return di #Sum the anti-iso data subsamples map_leaves(hqcd, lambda li: reduce(lambda x,y: x+y, li)) #Normalize the isolation variations to the nominal map_leaves(hqcd["iso"], lambda hi: hi.Scale(hqcd["nominal"][None].Integral() / hi.Integral()) if hi.Integral()>0 else 0, equate=False ) #Add the variated data-driven QCD templates hsources += [ (("data", "qcd", "weight__unweighted"), hqcd["nominal"][None]), (("data", "qcd", "weight__qcd_yield_up"), hqcd["yield"]["up"]), (("data", "qcd", "weight__qcd_yield_down"), hqcd["yield"]["down"]), (("data", "qcd", "weight__qcd_iso_up"), hqcd["iso"]["up"]), (("data", "qcd", "weight__qcd_iso_down"), hqcd["iso"]["down"]), ] #f = open('temp.pickle','wb') #pickle.dump(hsources, f) #f.close() #load the histos from the temporary pickle #f = open('temp.pickle','rb') #hsources = pickle.load(f) syst_scenarios = NestedDict() for (sample_var, sample, weight_var), hist in hsources: make_hist(hist) # if "__ele" in weight_var: # continue if ".root" in sample: sample = sample[:sample.index(".root")] if "__" in weight_var: spl = weight_var.split("__") wn = spl[1] else: wn = weight_var sample_var = sample_var.lower() wtype = None wdir = None stype = None sdir = None syst = None #Nominal weight, look for variated samples if wn=="nominal": syst = sample_var elif wn=="unweighted": syst="unweighted" else: #Variated weight, use only nominal sample or data in case of data-driven shapes if not (sample_var=="nominal" or sample_var=="data"): continue syst = wn if wn==conf.get_nominal_weight() and sample_var=="nominal": logger.info("Using %s:%s as nominal sample for %s" % (wn, sample_var, sample)) syst_scenarios[sample]["nominal"][None] = hist #A systematic scenario which has a separate systematic sample elif sample_var == "syst": try: r = get_syst_from_sample_name(sample) except Exception as e: logger.warning("Unhandled systematic: %s" % str(e)) r = None if not r: continue sample, systname, d = r #sample = map_syst_sample_to_nominal(sample) syst_scenarios[sample][systname][d] = hist else: logger.debug("Systematically variated weight: %s:%s %s" % (wn, sample_var, sample)) systname, d = get_updown(syst) syst_scenarios[sample][systname][d] = hist logger.info("histogram W3Jets_exclusive nominal: " + "%f %d" % ( syst_scenarios["W3Jets_exclusive"]["nominal"][None].Integral(), syst_scenarios["W3Jets_exclusive"]["nominal"][None].GetEntries()) ) ###################################### ### Save systematics, fill missing ### ###################################### ######### # tchan # ######### #T_t_ToLeptons mass_up is missing, take the mass down and flip the difference with the nominal mnomt = syst_scenarios["T_t_ToLeptons"]["nominal"][None].Clone() mdownt = syst_scenarios["T_t_ToLeptons"]["mass"]["down"].Clone() mupt = (mnomt+mnomt-mdownt) syst_scenarios["T_t_ToLeptons"]["mass"]["up"] = mupt ######### # TTBar # ######### #TTbar variations are provided for the inclusive only, fill them for the exclusive nom_ttbar = syst_scenarios["TTJets_FullLept"]["nominal"][None] + syst_scenarios["TTJets_SemiLept"]["nominal"][None] for syst in ["mass", "ttbar_scale", "ttbar_matching"]: for sample in ["TTJets_FullLept", "TTJets_SemiLept"]: for sd in ["up", "down"]: syst_scenarios[sample][syst][sd] = syst_scenarios[sample]["nominal"][None] * syst_scenarios["TTJets"][syst][sd] / nom_ttbar syst_scenarios.pop("TTJets") syst_scenarios = syst_scenarios.as_dict() #Create the output file p = os.path.dirname(conf.get_outfile_unmerged()) if not os.path.exists(p): os.makedirs(p) of = ROOT.TFile(conf.get_outfile_unmerged() , "RECREATE") of.cd() #Get the list of all possible systematic scenarios that we have available allsysts = get_all_systs(syst_scenarios) for sampn, h1 in syst_scenarios.items(): #Consider all the possible systematic scenarios for systname in allsysts: #If we have it available, fine, use it if systname in h1.keys(): h2 = h1[systname] #If not, in case of MC and a non-trivial variation elif not sampn.startswith("Single") and systname not in ["unweighted", "nominal"]: #Try to get the unvariated template as a placeholder h = h1.get("nominal", None) if not h: h = h1.get("unweighted", None) if not h: raise Exception("Could not get the nominal template for %s:%s" % (sampn, systname)) #Our convention is that even the unvariated template is a dict with a single #key for the direction of variation, which is 'None' h = h[None] #Add placeholder templates for systdir in ["up", "down"]: h = h.Clone(hname_encode(conf.varname, sampn, systname, systdir)) set_missing_hist(h) #Save to file h.SetDirectory(of) h.Write() continue else: continue for systdir, h in h2.items(): if systdir==None and systname=="nominal" or not sample_types.is_mc(sampn): h = h.Clone(hname_encode(conf.varname, sampn)) elif systdir==None and systname=="unweighted": h = h.Clone(hname_encode(conf.varname, sampn, "unweighted")) else: h = h.Clone(hname_encode(conf.varname, sampn, systname, systdir)) h.SetDirectory(of) h.Write() nkeys = len(of.GetListOfKeys()) logger.info("Saved %d histograms to file %s" % (nkeys, of.GetPath())) # of.Close() ######################## ### Load systematics ### ######################## # of_unmerged = File(conf.get_outfile_unmerged()) hists = dict() # ROOT.gROOT.cd() for k in of.GetListOfKeys(): hists[k.GetName()] = of.Get(k.GetName()) h = hists[k.GetName()] #hists[k.GetName()].Rebin(2) logger.info("Loaded %d histograms from file %s" % (len(hists), of.GetPath())) #of_unmerged.Close() ######################## ### Merge ### ######################## from plots.common.utils import merge_hists, PhysicsProcess merge_cmds = PhysicsProcess.get_merge_dict( PhysicsProcess.get_proc_dict(conf.channel) ) hsysts = NestedDict() for k, v in hists.items(): spl = split_name(k) hsysts[spl["type"]][spl["dir"]][spl["sample"]] = v hsysts = hsysts.as_dict() p = os.path.dirname(conf.get_outfile_merged()) if not os.path.exists(p): os.makedirs(p) of = ROOT.TFile(conf.get_outfile_merged(), "RECREATE") of.cd() for syst, h1 in hsysts.items(): if syst in skipped_systs: continue for sdir, h2 in h1.items(): hmc = merge_hists(h2, merge_cmds) for hn, h in hmc.items(): if syst=="nominal" or syst=="unweighted": h.SetName("__".join([spl["var"], hn])) else: h.SetName("__".join([spl["var"], hn, syst, sdir])) h.SetDirectory(of) h.Write() nkeys = len(of.GetListOfKeys()) logger.info("Saved %d histograms to file %s" % (nkeys, of.GetPath())) of.Close() hists = load_theta_format(conf.get_outfile_merged()) processes = [] systs = [] for (variable, sample, syst, systdir), v in hists.items_flat(): processes.append(sample) systs.append(syst) processes = set(processes) systs = set(systs) logger.info("Processes: %s" % processes) if not processes == set(['diboson', 'schan', 'tWchan', 'TTJets', 'tchan', 'WJets', 'qcd', 'DYJets', 'data']): raise Exception("Combined file did not contain the necessary processes: %s" % str(processes)) logger.info("Systematic scenarios: %s" % systs)
for k, v in histsA["cos_theta"][N_jets][N_tags]["unweighted"].items(): if re.match("W.*Jets.*", k): for flavour, hist in v.items(): wjets_hists[flavour][k] = hist wjets_hists = wjets_hists.as_dict() merged_wjets = NestedDict() wjets_merges = OrderedDict() wjets_merges["sherpa"] = ["WJets_sherpa"] wjets_merges["madgraph"] = ["W[1-4]Jets_exclusive"] hists_ratio = NestedDict() logger.info("Merging histograms by flavour") for flavour, hists in wjets_hists.items(): logger.debug("Merging flavour %s: %s" % (flavour, str(hists))) merged_wjets[flavour] = merge_hists(hists, wjets_merges, order=wjets_merges.keys()) madgraph_rew_hists = dict( filter(lambda x: make_pattern( N_jets=N_jets, N_tags=N_tags, weight="weighted_wjets_mg_flavour_nominal", var="cos_theta", flavour=flavour, extra="/sample__W[1-4]Jets_exclusive" ).match(x[0]), histsB.items() ) ).values() madgraph_rew = sum(madgraph_rew_hists) cloned = dc(merged_wjets[flavour]) logger.debug("Merge output %s" % str(cloned)) norm(cloned["sherpa"]) norm(cloned["madgraph"])
def data_mc_plot(samples, plot_def, name, lepton_channel, lumi, weight, physics_processes, use_antiiso=False): logger.info('Plot in progress %s' % name) merge_cmds = PhysicsProcess.get_merge_dict(physics_processes) #The actual merge dictionary var = plot_def['var'] #Id var is a list/tuple, assume if not isinstance(var, basestring): try: if lepton_channel == 'ele': var = var[0] elif lepton_channel == 'mu': var = var[1] except Exception as e: logger.error("Plot variable 'var' specification incorrect for multi-variable plot: %s" % str(var)) raise e cut = None if lepton_channel == 'ele': cut = plot_def['elecut'] elif lepton_channel == 'mu': cut = plot_def['mucut'] cut_str = str(cut) plot_range = plot_def['range'] do_norm = False if 'normalize' in plot_def.keys() and plot_def['normalize']: do_norm = True hists_mc = dict() hists_data = dict() for name, sample in samples.items(): logger.debug("Starting to plot %s" % name) if sample.isMC: hist = sample.drawHistogram(var, cut_str, weight=str(weight), plot_range=plot_range) hist.Scale(sample.lumiScaleFactor(lumi)) hists_mc[sample.name] = hist if do_norm: Styling.mc_style_nostack(hists_mc[sample.name], sample.name) else: Styling.mc_style(hists_mc[sample.name], sample.name) if "fitpars" in plot_def.keys(): rescale_to_fit(sample.name, hist, plot_def["fitpars"][lepton_channel]) elif "antiiso" in name and plot_def['estQcd'] and not use_antiiso: # Make loose template #Y U NO LOOP :) -JP region = '2j1t' if '2j0t' in plot_def['estQcd']: region='2j0t' if '3j0t' in plot_def['estQcd']: region='3j0t' if '3j1t' in plot_def['estQcd']: region='3j1t' if '3j2t' in plot_def['estQcd']: region='3j2t' qcd_extra_cut = Cuts.deltaR(0.3)*Cuts.antiiso(lepton_channel) #Take the loose template with a good shape from the N-jet, M-tag, post lepton selection region with high statistics qcd_loose_cut = cutlist[region]*cutlist['presel_'+lepton_channel]*qcd_extra_cut #Take the template which can be correctly normalized from the actual region with inverted isolation cuts qcd_cut = cut*qcd_extra_cut hist_qcd_loose = sample.drawHistogram(var, str(qcd_loose_cut), weight="1.0", plot_range=plot_range) hist_qcd = sample.drawHistogram(var, str(qcd_cut), weight="1.0", plot_range=plot_range) logger.debug("Using the QCD scale factor %s: %.2f" % (plot_def['estQcd'], qcdScale[lepton_channel][plot_def['estQcd']])) hist_qcd.Scale(qcdScale[lepton_channel][plot_def['estQcd']]) hist_qcd_loose.Scale(hist_qcd.Integral()/hist_qcd_loose.Integral()) if var=='cos_theta': hist_qcd=hist_qcd_loose sampn = "QCD"+sample.name #Rescale the QCD histogram to the eta_lj fit if "fitpars" in plot_def.keys(): rescale_to_fit(sampn, hist_qcd, plot_def["fitpars"][lepton_channel]) hists_mc[sampn] = hist_qcd hists_mc[sampn].SetTitle('QCD') if do_norm: Styling.mc_style_nostack(hists_mc[sampn], 'QCD') else: Styling.mc_style(hists_mc[sampn], 'QCD') #Real ordinary data in the isolated region elif not "antiiso" in name or use_antiiso: hist_data = sample.drawHistogram(var, cut_str, weight="1.0", plot_range=plot_range) hist_data.SetTitle('Data') Styling.data_style(hist_data) hists_data[name] = hist_data if len(hists_data.values())==0: raise Exception("Couldn't draw the data histogram") #Combine the subsamples to physical processes hist_data = sum(hists_data.values()) merge_cmds['QCD']=["QCD"+merge_cmds['data'][0]] order=['QCD']+PhysicsProcess.desired_plot_order if plot_def['log']: order = PhysicsProcess.desired_plot_order_log+['QCD'] merged_hists = merge_hists(hists_mc, merge_cmds, order=order) if hist_data.Integral()<=0: logger.error(hists_data) logger.error("hist_data.entries = %d" % hist_data.GetEntries()) logger.error("hist_data.integral = %d" % hist_data.Integral()) raise Exception("Histogram for data was empty. Something went wrong, please check.") if do_norm: for k,v in merged_hists.items(): v.Scale(1./v.Integral()) hist_data.Scale(1./hist_data.Integral()) htot = sum(merged_hists.values()) chi2 = hist_data.Chi2Test(htot, "UW CHI2/NDF") if chi2>20:#FIXME: uglyness logger.error("The chi2 between data and MC is large (%s, chi2=%.2f). You may have errors with your samples!" % (name, chi2) ) logger.info("MC : %s" % " ".join(map(lambda x: "%.1f" % x, list(htot.y())))) logger.info("DATA: %s" % " ".join(map(lambda x: "%.1f" % x, list(hist_data.y())))) logger.info("diff: %s" % str( " ".join(map(lambda x: "%.1f" % x, numpy.abs(numpy.array(list(htot.y())) - numpy.array(list(hist_data.y()))))) )) merged_hists_l = merged_hists.values() PhysicsProcess.name_histograms(physics_processes, merged_hists) leg_style = ['p','f'] if do_norm: leg_style=['p','l'] leg = legend([hist_data] + list(reversed(merged_hists_l)), legend_pos=plot_def['labloc'], styles=leg_style) canv = ROOT.TCanvas() #Make the stacks stacks_d = OrderedDict() stacks_d["mc"] = merged_hists_l stacks_d["data"] = [hist_data] #label xlab = plot_def['xlab'] if not isinstance(xlab, basestring): if lepton_channel == 'ele': xlab = xlab[0] else: xlab = xlab[1] ylab = 'N / '+str((1.*(plot_range[2]-plot_range[1])/plot_range[0])) if plot_def['gev']: ylab+=' GeV' fact = 1.5 if plot_def['log']: fact = 10 plow=0.3 if do_norm: plow=0 #Make a separate pad for the stack plot p1 = ROOT.TPad("p1", "p1", 0, plow, 1, 1) p1.Draw() p1.SetTicks(1, 1); p1.SetGrid(); p1.SetFillStyle(0); p1.cd() stacks = plot_hists_stacked(p1, stacks_d, x_label=xlab, y_label=ylab, max_bin_mult = fact, do_log_y = plot_def['log'], stack = (not do_norm)) #Put the the lumi box where the legend is not boxloc = 'top-right' if plot_def['labloc'] == 'top-right': boxloc = 'top-left' chan = 'Electron' if lepton_channel == "mu": chan = 'Muon' additional_comments = "" if 'cutname' in plot_def.keys(): additional_comments += ", " + plot_def['cutname'][lepton_channel] lbox = lumi_textbox(lumi, boxloc, 'preliminary', chan + ' channel' + additional_comments ) #Draw everything lbox.Draw() leg.Draw() canv.Draw() #Keep the handles just in case canv.PAD1 = p1 canv.STACKS = stacks canv.LEGEND = legend canv.LUMIBOX = lbox return canv, merged_hists, htot, hist_data
if sample.isMC: hist = sample.drawHistogram(var, cut_str, weight=weight_str, plot_range=plot_range) hist.Scale(sample.lumiScaleFactor(lumi)*mc_sf) hists_mc[sample.name] = hist.hist Styling.mc_style(hists_mc[sample.name], sample.name) elif name == "SingleMu": hist_data = sample.drawHistogram(var, cut_str, weight="1.0", plot_range=plot_range) Styling.data_style(hist_data) elif name == "SingleMu_aiso": hist_qcd = sample.drawHistogram(var, cut_str, weight="1.0", plot_range=plot_range) #hist_qcd. pass #Combine the subsamples to physical processes merged_hists = merge_hists(hists_mc, merge_cmds).values() #Some printout for h in merged_hists + [hist_data]: print h.GetName(), h.GetTitle(), h.Integral() canv = ROOT.TCanvas() stacks_d = OrderedDict() stacks_d["mc"] = merged_hists stacks_d["data"] = [hist_data] stacks = plot_hists_stacked(canv, stacks_d) canv.Draw() #Create the dir if it doesn't exits try:
def plot_sherpa_vs_madgraph(var, cut_name, cut, samples, out_dir, recreate=False, **kwargs): hname = var["varname"] out_dir = out_dir + "/" + cut_name if recreate and os.path.exists(out_dir): logger.info("Output directory %s exists, removing" % out_dir) shutil.rmtree(out_dir) mkdir_p(out_dir) logger.info("Using output directory %s" % out_dir) logger.info("Using output directory %s" % out_dir) coll = data_mc(var["var"], cut_name, cut, Weights.total()*Weights.mu, samples, out_dir, recreate, LUMI_TOTAL, reweight_madgraph=True, flavour_split=True, plot_range=var["range"], **kwargs) logging.debug(str(coll.hists)) for hn, hist in coll.hists.items(): sample_name = coll.metadata[hn].sample_name process_name = coll.metadata[hn].process_name match = re.match(".*/cut__flavour__(W_[Hl][Hl])/.*", hn) if match: flavour_scenario = match.group(1) else: flavour_scenario = None try: if sample_types.is_mc(sample_name): Styling.mc_style(hist, process_name) else: Styling.data_style(hist) except KeyError as e: logger.warning("Couldn't style histogram %s" % hn) if flavour_scenario: logger.debug("Matched flavour split histogram %s, %s" % (hn, flavour_scenario)) #Styling.mc_style(hist, process_name) if re.match("W_H[lH]", flavour_scenario): logger.debug("Changing colour of %s" % (hn)) hist.SetFillColor(hist.GetFillColor()+1) hist.SetLineColor(hist.GetLineColor()+1) logger.debug("pre merge: %s" % str([ (hn, coll.hists[hn].GetLineColor()) for hn in coll.hists.keys() if "sherpa" in hn])) merges = dict() merge_cmds = get_merge_cmds() merge_cmds.pop("WJets") merges["madgraph/unweighted"] = merge_cmds.copy() merges["madgraph/weighted"] = merge_cmds.copy() merges["sherpa/unweighted"] = merge_cmds.copy() merges["sherpa/weighted"] = merge_cmds.copy() merges["sherpa/unweighted"]["WJets_hf"] = ["weight__nominal/cut__flavour__W_heavy/WJets_sherpa_nominal"] merges["sherpa/unweighted"]["WJets_lf"] = ["weight__nominal/cut__flavour__W_light/WJets_sherpa_nominal"] merges["sherpa/weighted"]["WJets_hf"] = ["weight__sherpa_flavour/cut__flavour__W_heavy/WJets_sherpa_nominal"] merges["sherpa/weighted"]["WJets_lf"] = ["weight__sherpa_flavour/cut__flavour__W_light/WJets_sherpa_nominal"] merges["madgraph/unweighted"]["WJets_hf"] = ["weight__nominal/cut__flavour__W_heavy/W[1-4]Jets_exclusive"] merges["madgraph/unweighted"]["WJets_lf"] = ["weight__nominal/cut__flavour__W_light/W[1-4]Jets_exclusive"] merges["madgraph/weighted"]["WJets_hf"] = ["weight__reweight_madgraph/cut__flavour__W_heavy/W[1-4]Jets_exclusive"] merges["madgraph/weighted"]["WJets_lf"] = ["weight__reweight_madgraph/cut__flavour__W_light/W[1-4]Jets_exclusive"] hmerged = dict() for k in merges.keys(): hmerged[k] = merge_hists(copy.deepcopy(coll.hists), merges[k]) logger.debug("post merge: %s" % str([ (hn, hmerged["sherpa/weighted"][hn].GetLineColor()) for hn in hmerged["sherpa/weighted"].keys()])) #w_mg_sh = 1.0416259307303726 #sherpa to madgraph ratio w_mg_sh = 1.0821535639376414 hmerged["sherpa/weighted"]["WJets_hf"].Scale(w_mg_sh) hmerged["sherpa/weighted"]["WJets_lf"].Scale(w_mg_sh) logger.info("Drawing madgraph unweighted plot") canv = ROOT.TCanvas("c2", "c2") suffix = "__%s__%s" % (var["var"], cut_name) suffix = escape(suffix) plot(canv, "madgraph_unw"+suffix, hmerged["madgraph/unweighted"], out_dir, **kwargs) kwargs = dict({"x_label": var["varname"]}, **kwargs) for k, v in hmerged.items(): logger.debug("Group %s" % k) for hn, h in v.items(): logger.debug("Sample %s = %.2f" % (hn, h.Integral())) logger.info("%s data=%.2f" % (k, v["data"].Integral())) logger.info("%s MC=%.2f" % (k, sum([h.Integral() for k, h in v.items() if k!="data"]))) hists_flavours_merged = dict() hists_flavours_merged["madgraph/weighted"] = merge_hists(hmerged["madgraph/weighted"], {"WJets": ["WJets_hf", "WJets_lf"]}) hists_flavours_merged["madgraph/unweighted"] = merge_hists(hmerged["madgraph/unweighted"], {"WJets": ["WJets_hf", "WJets_lf"]}) hists_flavours_merged["sherpa/unweighted"] = merge_hists(hmerged["sherpa/unweighted"], {"WJets": ["WJets_hf", "WJets_lf"]}) hists_flavours_merged["sherpa/weighted"] = merge_hists(hmerged["sherpa/weighted"], {"WJets": ["WJets_hf", "WJets_lf"]}) logger.info("Drawing sherpa weighted plot") canv = ROOT.TCanvas("c1", "c1") plot(canv, "sherpa_rew"+suffix, hmerged["sherpa/weighted"], out_dir, **kwargs) logger.info("Drawing sherpa unweighted plot") canv = ROOT.TCanvas("c1", "c1") plot(canv, "sherpa_unw"+suffix, hmerged["sherpa/unweighted"], out_dir, **kwargs) logger.info("Drawing madgraph plot") canv = ROOT.TCanvas("c2", "c2") plot(canv, "madgraph_rew"+suffix, hmerged["madgraph/weighted"], out_dir, **kwargs) total_madgraph = copy.deepcopy(hmerged["madgraph/unweighted"]) merged_colls = dict() for k, v in hmerged.items(): merged_colls[k] = HistCollection(copy.deepcopy(v), name=k) logger.info("Drawing sherpa vs. madgraph shape comparison plots") hists = [ ("sherpa unw hf", hmerged["sherpa/unweighted"]["WJets_hf"]), ("sherpa rew hf", hmerged["sherpa/weighted"]["WJets_hf"]), ("madgraph unw hf", hmerged["madgraph/unweighted"]["WJets_hf"]), ("madgraph rew hf", hmerged["madgraph/weighted"]["WJets_hf"]), ] hists = copy.deepcopy(hists) for hn, h in hists: h.SetTitle(hn + " %.2f" % h.Integral()) h.Scale(1.0/h.Integral()) hists = [h[1] for h in hists] ColorStyleGen.style_hists(hists) canv = plot_hists(hists, x_label=var["varname"], do_chi2=True) leg = legend(hists, styles=["f", "f"], **kwargs) canv.SaveAs(out_dir + "/weighted_flavour_hf_%s.png" % hname) canv.Close() hists = [ ("data", hmerged["madgraph/unweighted"]["data"]), ("sherpa", hists_flavours_merged["sherpa/unweighted"]["WJets"]), ("madgraph", hists_flavours_merged["madgraph/unweighted"]["WJets"]), ] hists = copy.deepcopy(hists) for hn, h in hists: h.SetTitle(hn + " %.2f" % h.Integral()) h.Scale(1.0/h.Integral()) hists = [h[1] for h in hists] ColorStyleGen.style_hists(hists) canv = plot_hists(hists, x_label=var["varname"], do_chi2=True) leg = legend(hists, styles=["f", "f"], **kwargs) canv.SaveAs(out_dir + "/unweighted_sherpa_mg_%s.png" % hname) canv.Close() hists = [ ("data", hmerged["madgraph/unweighted"]["data"]), ("sherpa", hists_flavours_merged["sherpa/weighted"]["WJets"]), ("madgraph", hists_flavours_merged["madgraph/weighted"]["WJets"]), ] hists = copy.deepcopy(hists) for hn, h in hists: h.SetTitle(hn + " %.2f" % h.Integral()) h.Scale(1.0/h.Integral()) hists = [h[1] for h in hists] ColorStyleGen.style_hists(hists) canv = plot_hists(hists, x_label=var["varname"], do_chi2=True) leg = legend(hists, styles=["f", "f"], **kwargs) canv.SaveAs(out_dir + "/weighted_sherpa_mg_%s.png" % hname) canv.Close() hists = [ ("sherpa unw lf", hmerged["sherpa/unweighted"]["WJets_lf"]), ("sherpa rew lf", hmerged["sherpa/weighted"]["WJets_lf"]), ("madgraph unw lf", hmerged["madgraph/unweighted"]["WJets_lf"]), ("madgraph rew lf", hmerged["madgraph/weighted"]["WJets_lf"]), ] hists = copy.deepcopy(hists) for hn, h in hists: h.SetTitle(hn + " %.2f" % h.Integral()) h.Scale(1.0/h.Integral()) hists = [h[1] for h in hists] ColorStyleGen.style_hists(hists) canv = plot_hists(hists, x_label=var["varname"], do_chi2=True) leg = legend(hists, styles=["f", "f"], **kwargs) canv.SaveAs(out_dir + "/weighted_flavour_lf_%s.png" % hname) canv.Close() hists = [ ("data", hmerged["madgraph/unweighted"]["data"]), ("madgraph unw", hists_flavours_merged["madgraph/unweighted"]["WJets"]), ("madgraph rew", hists_flavours_merged["madgraph/weighted"]["WJets"]), ("sherpa unw", hists_flavours_merged["sherpa/unweighted"]["WJets"]), ("sherpa rew", hists_flavours_merged["sherpa/weighted"]["WJets"]), ] hists = copy.deepcopy(hists) for hn, h in hists: h.SetTitle(hn + " %.2f" % h.Integral()) h.Scale(1.0/h.Integral()) hists = [h[1] for h in hists] ColorStyleGen.style_hists(hists) canv = plot_hists(hists, x_label=var["varname"], do_chi2=True) leg = legend(hists, styles=["f", "f"], **kwargs) hists[0].SetTitle("") canv.Update() canv.SaveAs(out_dir + "/shapes_%s.png" % hname) canv.Close() # hists = [ # ("sherpa hf", hmerged["sherpa"]["WJets_hf"]), # ("madgraph unw hf", hmerged["madgraph/unweighted"]["WJets_hf"]), # ("madgraph rew hf", hmerged["madgraph/weighted"]["WJets_hf"]), # ] # hists = copy.deepcopy(hists) # for hn, h in hists: # h.SetTitle(hn + " %.2f" % h.Integral()) # h.Scale(1.0/h.Integral()) # hists = [h[1] for h in hists] # ColorStyleGen.style_hists(hists) # canv = plot_hists(hists, x_label=var["varname"], do_chi2=True) # leg = legend(hists, styles=["f", "f"], **kwargs) # hists[0].SetTitle("madgraph sherpa rew hf") # canv.SaveAs(out_dir + "/shapes_hf_%s.png" % hname) # canv.Close() return coll, merged_colls
def plot_ratios(cut_name, cut, samples, out_dir, recreate, flavour_scenario=flavour_scenarios[0]): out_dir += "/" + cut_name mkdir_p(out_dir) colls = dict() samples_WJets = filter(lambda x: sample_types.is_wjets(x.name), samples) for sc in flavour_scenario: logger.info("Drawing ratio with cut %s" % sc) cut_ = cut*getattr(Cuts, sc) colls[sc] = data_mc(costheta["var"], cut_name + "__" + sc, cut_, Weights.total()*Weights.mu, samples_WJets, out_dir, recreate, LUMI_TOTAL, plot_range=costheta["range"]) logger.debug(colls[flavour_scenario[0]].hists["weight__nominal/cut__all/WJets_sherpa_nominal"].Integral()) logger.debug(colls[flavour_scenario[1]].hists["weight__nominal/cut__all/WJets_sherpa_nominal"].Integral()) coll = dict() for k, c in colls.items(): for hn, h in c.hists.items(): coll[hn + "/" + k] = h for k, h in coll.items(): logger.debug("%s = %s" % (k, str([y for y in h.y()]))) logger.debug(coll) #coll = HistCollection(coll, name=cut_name) merges = {} for sc in flavour_scenario: merges["madgraph/%s" % sc] = ["weight__nominal/cut__all/W[1-4]Jets_exclusive/%s" % sc] merges["sherpa/unweighted/%s" % sc] = ["weight__nominal/cut__all/WJets_sherpa_nominal/%s" % sc] merges["sherpa/weighted/%s" % sc] = ["weight__sherpa_flavour/cut__all/WJets_sherpa_nominal/%s" % sc] merged = merge_hists(coll, merges) for k, h in merged.items(): logger.debug("%s = %s" % (k, str([y for y in h.y()]))) hists_flavour = dict() hists_flavour["madgraph"] = ROOT.TH1F("madgraph", "madgraph", len(flavour_scenario), 0, len(flavour_scenario)-1) hists_flavour["sherpa/unweighted"] = ROOT.TH1F("sherpa_unw", "sherpa unweighted", len(flavour_scenario), 0, len(flavour_scenario)-1) hists_flavour["sherpa/weighted"] = ROOT.TH1F("sherpa_rew", "sherpa weighted", len(flavour_scenario), 0, len(flavour_scenario)-1) for i, sc in zip(range(1,len(flavour_scenario)+1), flavour_scenario): sh1_int, sh1_err = calc_int_err(merged["sherpa/unweighted/%s" % sc]) sh2_int, sh2_err = calc_int_err(merged["sherpa/weighted/%s" % sc]) mg_int, mg_err = calc_int_err(merged["madgraph/%s" % sc]) logger.debug("%.2f %.2f" % (sh1_int, sh1_err)) logger.debug("%.2f %.2f" % (sh2_int, sh2_err)) logger.debug("%.2f %.2f" % (mg_int, mg_err)) hists_flavour["madgraph"].SetBinContent(i, mg_int) hists_flavour["madgraph"].SetBinError(i, mg_err) hists_flavour["sherpa/unweighted"].SetBinContent(i, sh1_int) hists_flavour["sherpa/unweighted"].SetBinError(i, sh1_err) hists_flavour["sherpa/weighted"].SetBinContent(i, sh2_int) hists_flavour["sherpa/weighted"].SetBinError(i, sh2_err) hists_flavour["madgraph"].GetXaxis().SetBinLabel(i, sc) hists_flavour["sherpa/unweighted"].GetXaxis().SetBinLabel(i, sc) hists_flavour["sherpa/weighted"].GetXaxis().SetBinLabel(i, sc) hists_flavour["sherpa/weighted"].Sumw2() hists_flavour["sherpa/unweighted"].Sumw2() hists_flavour["madgraph"].Sumw2() hists_flavour["ratio/unweighted"] = hists_flavour["madgraph"].Clone("ratio_unw") hists_flavour["ratio/unweighted"].Divide(hists_flavour["sherpa/unweighted"]) hists_flavour["ratio/weighted"] = hists_flavour["madgraph"].Clone("ratio_rew") hists_flavour["ratio/weighted"].Divide(hists_flavour["sherpa/weighted"]) for i, sc in zip(range(1,len(flavour_scenario)+1), flavour_scenario): logger.info("weights[%s] = %.6f; //error=%.6f [%d]" % (sc, hists_flavour["ratio/unweighted"].GetBinContent(i), hists_flavour["ratio/unweighted"].GetBinError(i), i)) flavour_ratio_coll = HistCollection(hists_flavour, name="hists__flavour_ratios") flavour_ratio_coll.save(out_dir) for sc in flavour_scenario: hists = [merged["madgraph/%s" % sc], merged["sherpa/unweighted/%s" % sc], merged["sherpa/weighted/%s" % sc]] for hist in hists: norm(hist) #hist.SetName(sc) #hist.SetTitle(sc) ColorStyleGen.style_hists(hists) canv = plot_hists(hists, x_label=costheta["varname"]) leg = legend(hists, styles=["f", "f"], nudge_x=-0.2) chi2 = hists[0].Chi2Test(hists[1], "WW CHI2/NDF") hists[0].SetTitle("madgraph to sherpa comparison #chi^{2}/ndf=%.2f" % chi2) canv.Update() canv.SaveAs(out_dir + "/flavours__%s.png" % (sc)) md_merged = dict() for sc in flavour_scenario: logger.info("Calculating ratio for %s" % sc) hi = merged["sherpa/unweighted/%s" % sc].Clone("ratio__%s" % sc) hi.Divide(merged["madgraph/%s" % sc]) merged[hi.GetName()] = hi hc_merged = HistCollection(merged, md_merged, "hists__costheta_flavours_merged") hc_merged.save(out_dir) logger.info("Saved merged histogram collection")
hists = {} for fn in fnames: files[re.match(".*__(.*).root", fn).group(1)] = File(fn) logging.info("files = %s" % str(files)) for sn, fi in files.items(): hi = fi.Get("flavour_counts") hi.SetName(sn) pn = sn Styling.mc_style(hi, pn) hists[sn] = hi merges = OrderedDict() merges["W (madgraph)"] = ["W1Jets_exclusive", "W2Jets_exclusive", "W3Jets_exclusive", "W4Jets_exclusive"] merges["W (sherpa)"] = ["WJets_sherpa"] hists_merged = merge_hists(hists, merges) hists = hists_merged.values() ColorStyleGen.style_hists(hists) for h in hists: logging.info(list(h.y())) h.SetFillColor(ROOT.kWhite) h.Scale(1.0 / h.Integral()) c = plot_hists(hists, x_label="flavour(j,j)", y_label="", draw_cmd="HIST E1") leg = legend(hists, styles=len(hists) * ["f"], nudge_x=-0.1) hists[0].SetTitle("Jet flavour fraction n %s" % cut_name) # hists[0].SetFillColor(ROOT.kGreen+2) hists[0].SetMinimum(10 ** -3) hists[0].SetMaximum(10) # hists[0].SetLineColor(ROOT.kGreen+2) c.SetLogy()