示例#1
0
    def plot_data_mc(hists_mc, hist_data, name):
        canv = ROOT.TCanvas()
        p1 = ROOT.TPad("p1", "p1", 0, 0.3, 1, 1)
        p1.Draw()
        p1.SetTicks(1, 1);
        p1.SetGrid();
        p1.SetFillStyle(0);
        p1.cd()

        stacks_d = OrderedDict()
        print "MC",hists_mc
        print "VAL",hists_mc.values()
        stacks_d["mc"] = hists_mc.values()
        stacks_d["data"] = [hist_data]
        stacks = plot_hists_stacked(
            p1,
            stacks_d,
            x_label=var,
            y_label="",
            do_log_y=True
        )
        leg = legend([hist_data] + list(reversed(hists_mc.values())), styles=["p", "f"])
        print canv, hist_data
        print get_stack_total_hist(stacks["mc"])
        ratio_pad, hratio = plot_data_mc_ratio(canv, get_stack_total_hist(stacks["mc"]), hist_data)

        plot_info = PlotMetaInfo(
            name,
            "CUT",
            "WEIGHT",
            [infile],
            subdir=fit.name,
            comments=str(result[SIGNAL])
        )
        of.savePlot(canv, plot_info)
        canv.Close()
示例#2
0
                hists_tot_mc_syst[name] = tuple(tots)

            #Draw the ratio plot with the systematics
            do_norm = plot_def.get("normalize", False)
            if not do_norm and len(hists_tot_mc_syst.items())>0:
                syst_hists = total_syst(htot_mc, hists_tot_mc_syst)

                for h in list(syst_hists):
                    try:
                        logger.info("Chi2 = %.2f" % (htot_mc.Chi2Test(h, "WW CHI2/NDF")))
                    except rootpy.ROOTError as e:
                        logger.error("Couldn't calculate the chi2: %s" % str(e))
            else:
                syst_hists = None

            ratio_pad, hratio = plot_data_mc_ratio(canv, htot_data, htot_mc, syst_hists=syst_hists)

            #This is adopted in the AN
            if lepton_channel=="ele":
                _lepton_channel = "el"
            else:
                _lepton_channel = "mu"

            if use_antiiso:
                _lepton_channel+='_aiso'

            subpath = ""
            if "dir" in plot_def.keys():
                subpath = plot_def["dir"]

            #Set the plot metadata
示例#3
0
def data_mc_plot(pd):
    hists = load_theta_format(pd.infile, styles)

    for (variable, sample, systtype, systdir), hist in hists.items_flat():

        #Scale all MC samples except QCD to the luminosity
        if sample_types.is_mc(sample) and not sample=="qcd":
            hist.Scale(pd.lumi)
        if hasattr(pd, "rebin"):
            hist.Rebin(pd.rebin)
        if sample=="qcd" and hasattr(pd, "qcd_yield"):
            hist.Scale(pd.qcd_yield / hist.Integral())

        rescale_to_fit(sample, hist, pd.process_scale_factor)
        hist.SetTitle(sample)
        hist.SetName(sample)


    #Assuming we only have 1 variable
    hists = hists[pd.var]

    hists_nominal = hists.pop("nominal")[None]
    hists_nom_data = hists_nominal.pop('data')
    hists_nom_mc = hists_nominal.values()
    hists_syst = hists

    hists_nom_data.SetTitle('data')

    #A list of all the systematic up, down variation templates as 2-tuples
    all_systs = [
    ]

    all_systs = hists_syst.keys()
    systs_to_consider = []

    #See which systematics where asked to switch on
    for syst in all_systs:
        for sm in pd.systematics:
            if re.match(sm, syst):
                systs_to_consider.append(syst)

    #The total nominal MC histogram
    nom = sum(hists_nom_mc)

    if pd.normalize:
        ratio = hists_nom_data.Integral() / nom.Integral()
        hists_nom_data.Scale(1.0/ratio)

    #Get all the variated up/down total templates
    #A list with all the up/down total templates
    all_systs = []

    sumsqs = []
    logger.info("Considering systematics %s" % str(systs_to_consider))
    for syst in systs_to_consider:

        #A list with the up/down variated template for a particular systematic
        totupdown = []

        sumsq = []
        for systdir in ["up", "down"]:

            #Get all the templates corresponding to a systematic scenario and a variation
            _hists = hists_syst[syst][systdir]


            for k, h in _hists.items():

                """
                Consider only the shape variation of the systematic,
                hence the variated template is normalized to the corresponding
                unvariated template.
                """
                if pd.systematics_shapeonly:
                    if h.Integral()>0:
                        h.Scale(hists_nominal[k].Integral() / h.Integral())

            #For the missing variated templates, use the nominal ones, but warn the user
            present = set(_hists.keys())
            all_mc = set(hists_nominal.keys())
            missing = list(all_mc.difference(present))
            for m in missing:
                logger.warning("Missing systematic template for %s:%s" % (syst, systdir))

            #Calculate the total variated template
            tot = sum(_hists.values()) + sum([hists_nominal[m] for m in missing])
            totupdown.append(tot)

            sumsq.append(
                math.sqrt(numpy.sum(numpy.power(numpy.array(list(nom.y())) - numpy.array(list(tot.y())), 2)))
            )
        logger.debug("Systematic %s: sumsq=%.2Eu, %.2Ed" % (syst, sumsq[0], sumsq[1]))
        sumsqs.append((syst, max(sumsq)))
        all_systs.append(
            (syst, tuple(totupdown))
        )

    sumsqs = sorted(sumsqs, key=lambda x: x[1], reverse=True)
    for syst, sumsq in sumsqs[0:7]:
        logger.info("Systematic %s, %.4f" % (syst, sumsq))

    #Calculate the total up/down variated templates by summing in quadrature
    syst_stat_up, syst_stat_down = total_syst(
        nom, all_systs,
    )

    for k, v in hists_nominal.items():
        if hasattr(PhysicsProcess, k):
            pp = getattr(PhysicsProcess, k)
            v.SetTitle(pp.pretty_name)
        else:
            logger.warning("Not setting pretty name for %s" % k)


    #If QCD is high-stats, put it in the bottom
    plotorder = copy.copy(PhysicsProcess.desired_plot_order_mc)
    if hists_nominal["qcd"].GetEntries()>100:
        plotorder.pop(plotorder.index("qcd"))
        plotorder.insert(0, "qcd")

    stacks_d = OrderedDict()
    stacks_d['mc'] = reorder(hists_nominal, plotorder)
    stacks_d['data'] = [hists_nom_data]

    #Systematic style
    for s in [syst_stat_up, syst_stat_down]:
        s.SetFillStyle(0)
        s.SetLineWidth(3)
        s.SetMarkerSize(0)
        s.SetLineColor(ROOT.kBlue+2)
        s.SetLineStyle('dashed')
        s.SetTitle("stat. + syst.")

    #c = ROOT.TCanvas("c", "c", 1000, 1000)
    c = ROOT.TCanvas("c", "c")
    p1 = ROOT.TPad("p1", "p1", 0, 0.3, 1, 1)
    p1.Draw()
    p1.SetTicks(1, 1);
    p1.SetGrid();
    p1.SetFillStyle(0);
    p1.cd()

    stacks = plot_hists_stacked(
        p1, stacks_d,
        x_label=pd.get_x_label(), max_bin_mult=pd.get_max_bin_mult(),
        min_bin=pd.get_min_bin()
    )
    p1.SetLogy(pd.log)

    syst_stat_up.Draw("SAME hist")
    syst_stat_down.Draw("SAME hist")

    ratio_pad, hratio = plot_data_mc_ratio(
        c, hists_nom_data,
        nom, syst_hists=(syst_stat_down, syst_stat_up), min_max=pd.get_ratio_minmax()
    )



    p1.cd()
    leg = legend(
        stacks_d['data'] +
        list(reversed(stacks_d['mc'])) +
        [syst_stat_up],
        nudge_x=pd.legend_nudge_x,
        nudge_y=pd.legend_nudge_y,
        **pd.__dict__
    )
    lb = lumi_textbox(pd.lumi,
        line2=pd.get_lumibox_comments(channel=pd.channel_pretty),
        pos=pd.get_lumi_pos()
    )
    c.children = [p1, ratio_pad, stacks, leg, lb]

    tot = 0
    for k, v in hists_nominal.items():
        print k, v.Integral(), v.GetEntries()
        tot += v.Integral()
    tot_data = hists_nom_data.Integral()
    print "MC: %.2f Data: %.2f" % (tot, tot_data)
    #import pdb; pdb.set_trace()
    return c, (hists_nominal, hists_nom_data)