Пример #1
0
def main(args, variable, category):
    # Config
    linear = True
    bkg_processes = [
        'qcd', 'vvt', 'vvl', 'vvj', 'w', 'ttt', 'ttl', 'ttj', 'zj', 'zl', 'ztt'
    ]
    name = '{}_{}'.format(variable, category)

    # Read histograms
    hists = {}
    reader = Reader([
        os.path.join(args.workdir, f)
        for f in ['shapes_main.root', 'shapes_qcd.root']
    ])
    total_bkg = None
    for process in bkg_processes:
        h = reader.get(process, 'Nominal', name)
        hists[process] = h
        if not total_bkg:
            total_bkg = h.Clone()
        else:
            total_bkg.Add(h)

    hists['data'] = reader.get('data', 'Nominal', name)
    hists['ggh'] = reader.get('ggh', 'Nominal', name)
    hists['qqh'] = reader.get('qqh', 'Nominal', name)

    # Blinding
    is_blinded = False
    if args.blinding and category != 'inclusive':
        hists['data'] = hists[bkg_processes[0]].Clone()
        for process in bkg_processes[1:] + ['ggh', 'qqh']:
            hists['data'].Add(hists[process])
        is_blinded = True

    # Set backgrounds
    plot = dd.Plot([0.3 if linear else 0.5, [0.3, 0.28]],
                   'ModTDR',
                   r=0.04,
                   l=0.14,
                   width=600)

    for process in bkg_processes:
        plot.add_hist(hists[process], process, 'bkg')
        plot.setGraphStyle(process,
                           'hist',
                           fillcolor=styles.color_dict[process.upper()])

    plot.add_hist(total_bkg, 'total_bkg')
    plot.setGraphStyle('total_bkg',
                       'e2',
                       markersize=0,
                       fillcolor=styles.color_dict['unc'],
                       linecolor=0)

    # Set data
    plot.add_hist(hists['data'], 'data_obs')
    data_norm = plot.subplot(0).get_hist('data_obs').Integral()
    plot.subplot(0).get_hist('data_obs').GetXaxis().SetMaxDigits(4)
    for i in [0, 2]:
        plot.subplot(i).setGraphStyle('data_obs', 'e0')

    # Set signals
    for i in [0, 2] if linear else [1, 2]:
        ggH = hists['ggh'].Clone()
        qqH = hists['qqh'].Clone()
        if ggH.Integral() > 0:
            ggH_scale = 0.5 * data_norm / ggH.Integral()
        else:
            ggH_scale = 0.0
        if qqH.Integral() > 0:
            qqH_scale = 0.5 * data_norm / qqH.Integral()
        else:
            qqH_scale = 0.0
        if i in [0, 1]:
            ggH.Scale(ggH_scale)
            qqH.Scale(qqH_scale)
        plot.subplot(i).add_hist(ggH, 'ggH')
        plot.subplot(i).add_hist(ggH, 'ggH_top')
        plot.subplot(i).add_hist(qqH, 'qqH')
        plot.subplot(i).add_hist(qqH, 'qqH_top')

    plot.subplot(0 if linear else 1).setGraphStyle(
        'ggH', 'hist', linecolor=styles.color_dict['ggH'], linewidth=3)
    plot.subplot(0 if linear else 1).setGraphStyle('ggH_top',
                                                   'hist',
                                                   linecolor=0)
    plot.subplot(0 if linear else 1).setGraphStyle(
        'qqH', 'hist', linecolor=styles.color_dict['qqH'], linewidth=3)
    plot.subplot(0 if linear else 1).setGraphStyle('qqH_top',
                                                   'hist',
                                                   linecolor=0)

    # Make ratio
    bkg_ggH = plot.subplot(2).get_hist('ggH')
    bkg_qqH = plot.subplot(2).get_hist('qqH')
    bkg_ggH.Add(plot.subplot(2).get_hist('total_bkg'))
    bkg_qqH.Add(plot.subplot(2).get_hist('total_bkg'))
    plot.subplot(2).add_hist(bkg_ggH, 'bkg_ggH')
    plot.subplot(2).add_hist(bkg_ggH, 'bkg_ggH_top')
    plot.subplot(2).add_hist(bkg_qqH, 'bkg_qqH')
    plot.subplot(2).add_hist(bkg_qqH, 'bkg_qqH_top')
    plot.subplot(2).setGraphStyle('bkg_ggH',
                                  'hist',
                                  linecolor=styles.color_dict['ggH'],
                                  linewidth=3)
    plot.subplot(2).setGraphStyle('bkg_ggH_top', 'hist', linecolor=0)
    plot.subplot(2).setGraphStyle('bkg_qqH',
                                  'hist',
                                  linecolor=styles.color_dict['qqH'],
                                  linewidth=3)
    plot.subplot(2).setGraphStyle('bkg_qqH_top', 'hist', linecolor=0)
    plot.subplot(2).normalize([
        'total_bkg', 'bkg_ggH', 'bkg_ggH_top', 'bkg_qqH', 'bkg_qqH_top',
        'data_obs'
    ], 'total_bkg')

    # Stack background processes
    plot.create_stack(bkg_processes, 'stack')

    # Set axes limits and labels
    plot.subplot(0).setYlims(
        0, 1.8 * plot.subplot(0).get_hist('data_obs').GetMaximum())
    plot.subplot(2).setYlims(0.75, 1.35)

    if not linear:
        plot.subplot(1).setYlims(0.1, 0)
        plot.subplot(1).setYlabel('')
    if variable in styles.x_label_dict['mt']:
        x_label = styles.x_label_dict['mt'][variable]
    else:
        x_label = variable
    plot.subplot(2).setXlabel(x_label)
    plot.subplot(0).setYlabel('N_{events}')

    plot.subplot(2).setYlabel('')

    plot.scaleYLabelSize(0.8)
    plot.scaleYTitleOffset(1.1)

    # Wraw subplots
    # Argument contains names of objects to be drawn in corresponding order
    plot.subplot(0).Draw(
        ['stack', 'total_bkg', 'ggH', 'ggH_top', 'qqH', 'qqH_top', 'data_obs'])
    if not linear:
        plot.subplot(1).Draw(['stack', 'total_bkg', 'data_obs'])
    plot.subplot(2).Draw([
        'total_bkg', 'bkg_ggH', 'bkg_ggH_top', 'bkg_qqH', 'bkg_qqH_top',
        'data_obs'
    ])

    # Create legends
    suffix = ['', '_top']
    for i in range(2):
        plot.add_legend(width=0.6, height=0.15)
        for process in reversed(bkg_processes):
            plot.legend(i).add_entry(
                0, process, styles.legend_label_dict[process.upper().replace(
                    'TTL', 'TT').replace('VVL', 'VV')], 'f')
        plot.legend(i).add_entry(0, 'total_bkg', 'Bkg. stat. unc.', 'f')
        plot.legend(i).add_entry(
            0 if linear else 1, 'ggH%s' % suffix[i],
            '%s #times gg#rightarrowH' % str(int(ggH_scale)), 'l')
        plot.legend(i).add_entry(
            0 if linear else 1, 'qqH%s' % suffix[i],
            '%s #times qq#rightarrowH' % str(int(qqH_scale)), 'l')
        plot.legend(i).add_entry(0, 'data_obs', 'Data', 'PE')
        plot.legend(i).setNColumns(3)
    plot.legend(0).Draw()
    plot.legend(1).setAlpha(0.0)
    plot.legend(1).Draw()

    for i in range(2):
        plot.add_legend(reference_subplot=2, pos=1, width=0.5, height=0.03)
        plot.legend(i + 2).add_entry(0, 'data_obs', 'Data', 'PE')
        plot.legend(i + 2).add_entry(0 if linear else 1, 'ggH%s' % suffix[i],
                                     'ggH+bkg.', 'l')
        plot.legend(i + 2).add_entry(0 if linear else 1, 'qqH%s' % suffix[i],
                                     'qqH+bkg.', 'l')
        plot.legend(i + 2).add_entry(0, 'total_bkg', 'Bkg. stat. unc.', 'f')
        plot.legend(i + 2).setNColumns(4)
    plot.legend(2).Draw()
    plot.legend(3).setAlpha(0.0)
    plot.legend(3).Draw()

    # Draw additional labels
    plot.DrawLumi('59.7 fb^{-1} (2018, 13 TeV)')
    tag = category.replace('_cat',
                           '') + ' (blinded)' if is_blinded else category
    plot.DrawChannelCategoryLabel('%s, %s' % ('#mu#tau_{h}', tag),
                                  begin_left=None)

    plot.save(
        os.path.join(args.workdir, '%s_%s.%s' % (variable, category, 'png')))
    plot.save(
        os.path.join(args.workdir, '%s_%s.%s' % (variable, category, 'pdf')))
Пример #2
0
def main(info):
    args = info["args"]
    variable = info["variable"]
    channel = info["channel"]
    channel_dict = {
        "ee": "#font[42]{#scale[0.85]{ee}}",
        "em": "#scale[0.85]{e}#mu",
        "et": "#font[42]{#scale[0.85]{e}}#tau_{#font[42]{h}}",
        "mm": "#mu#mu",
        "mt": "#mu#tau_{#font[42]{h}}",
        "tt": "#tau_{#font[42]{h}}#tau_{#font[42]{h}}"
    }
    if args.linear == True:
        split_value = 0.1
    else:
        if args.normalize_by_bin_width:
            split_value = 10001
        else:
            split_value = 101

    split_dict = {c: split_value for c in ["et", "mt", "tt", "em", "mm"]}

    bkg_processes = [
        "VVL", "TTL", "ZL", "jetFakesEMB", "EMB"
    ]
    if not args.fake_factor and args.embedding:
        bkg_processes = [
            "QCDEMB", "VVL", "VVJ", "W", "TTL", "TTJ", "ZJ", "ZL", "EMB"
        ]
    if not args.embedding and args.fake_factor:
        bkg_processes = [
            "VVT", "VVL", "TTT", "TTL", "ZL", "jetFakes", "ZTT"
        ]
    if not args.embedding and not args.fake_factor:
        bkg_processes = [
            "QCD", "VVT", "VVL", "VVJ", "W", "TTT", "TTL", "TTJ", "ZJ", "ZL", "ZTT"
        ]
    if args.draw_jet_fake_variation is not None:
        bkg_processes = [
            "VVL", "TTL", "ZL", "EMB"
        ]
        if not args.fake_factor and args.embedding:
            bkg_processes = [
                "VVL", "VVJ", "W", "TTL", "TTJ", "ZJ", "ZL", "EMB"
            ]
        if not args.embedding and args.fake_factor:
            bkg_processes = [
                "VVT", "VVL", "TTT", "TTL", "ZL", "ZTT"
            ]
        if not args.embedding and not args.fake_factor:
            bkg_processes = [
                "VVT", "VVL", "VVJ", "W", "TTT", "TTL", "TTJ", "ZJ", "ZL", "ZTT"
            ]
    all_bkg_processes = [b for b in bkg_processes]
    legend_bkg_processes = copy.deepcopy(bkg_processes)
    legend_bkg_processes.reverse()

    if "2016" in args.era:
        era = "Run2016"
    elif "2017" in args.era:
        era = "Run2017"
    elif "2018" in args.era:
        era = "Run2018"
    else:
        logger.critical("Era {} is not implemented.".format(args.era))
        raise Exception

    # category = "_".join([channel, variable])
    # if args.category_postfix is not None:
    #     category += "_%s"%args.category_postfix
    rootfile = rootfile_parser.Rootfile_parser(args.input, variable)
    bkg_processes = [b for b in all_bkg_processes]
    if "em" in channel:
        if not args.embedding:
            bkg_processes = [
                "QCD", "VVT", "VVL", "W", "TTT", "TTL", "ZL", "ZTT"
            ]
        if args.embedding:
            bkg_processes = [
                "QCDEMB", "VVL", "W", "TTL", "ZL", "EMB"
            ]
        if args.draw_jet_fake_variation is not None:
            if not args.embedding:
                bkg_processes = [
                    "VVT", "VVL", "W", "TTT", "TTL", "ZL", "ZTT"
                ]
            if args.embedding:
                bkg_processes = [
                    "VVL", "W", "TTL", "ZL", "EMB"
                ]

    if "mm" in channel:
        bkg_processes = [
            "QCD", "VVT", "VVL", "W", "TTT", "TTL", "ZTT", "ZL"
        ]

    legend_bkg_processes = copy.deepcopy(bkg_processes)
    legend_bkg_processes.reverse()

    # create plot
    width = 600
    if args.linear == True:
        plot = dd.Plot(
            [0.3, [0.3, 0.28]], "ModTDR", r=0.04, l=0.14, width=width)
    else:
        plot = dd.Plot(
            [0.5, [0.3, 0.28]], "ModTDR", r=0.04, l=0.14, width=width)

    # get background histograms
    total_bkg = None
    if args.draw_jet_fake_variation is None:
        stype = "Nominal"
    else:
        stype = args.draw_jet_fake_variation
    for index,process in enumerate(bkg_processes):
        if index == 0:
            total_bkg = rootfile.get(channel, process, shape_type=stype).Clone()
        else:
            total_bkg.Add(rootfile.get(channel, process, shape_type=stype))
        if process in ["jetFakesEMB", "jetFakes"] and channel == "tt":
            total_bkg.Add(rootfile.get(channel, "wFakes", shape_type=stype))
            jetfakes_hist = rootfile.get(channel, process, shape_type=stype)
            jetfakes_hist.Add(
                rootfile.get(channel, "wFakes", shape_type=stype))
            plot.add_hist(
                jetfakes_hist, process, "bkg")
        else:
            plot.add_hist(
                rootfile.get(channel, process, shape_type=stype), process, "bkg")
        plot.setGraphStyle(
            process, "hist", fillcolor=styles.color_dict[process])


    # if "mm" not in channel:
    #     # add VH, ttH & HWW to total bkg histogram
    #     total_bkg.Add(rootfile.get(channel, "VH125"))
    #     total_bkg.Add(rootfile.get(channel, "ttH125"))
    #     total_bkg.Add(rootfile.get(channel, "HWW"))

    plot.add_hist(total_bkg, "total_bkg")
    plot.setGraphStyle(
        "total_bkg",
        "e2",
        markersize=0,
        fillcolor=styles.color_dict["unc"],
        linecolor=0)

    plot.add_hist(rootfile.get(channel, "data", shape_type=stype), "data_obs")
    data_norm = plot.subplot(0).get_hist("data_obs").Integral()
    plot.subplot(0).get_hist("data_obs").GetXaxis().SetMaxDigits(4)
    plot.subplot(0).setGraphStyle("data_obs", "e0")
    plot.subplot(0).setGraphStyle("data_obs", "e0")
    if args.linear:
        pass
    else:
        plot.subplot(1).setGraphStyle("data_obs", "e0")

    if "mm" not in channel:
        # get signal histograms
        plot_idx_to_add_signal = [0,2] if args.linear else [1,2]
        for i in plot_idx_to_add_signal:
            ggH = rootfile.get(channel, "ggH125").Clone()
            qqH = rootfile.get(channel, "qqH125").Clone()
            # VH = rootfile.get(channel, "VH125").Clone()
            # ttH = rootfile.get(channel, "ttH125").Clone()
            # HWW = rootfile.get(channel, "HWW").Clone()
            if ggH.Integral() > 0:
                ggH_scale = 10
            else:
                ggH_scale = 0.0
            if qqH.Integral() > 0:
                qqH_scale = 10
            else:
                qqH_scale = 0.0
            # if VH.Integral() > 0:
            #     VH_scale = 10
            # else:
            #     VH_scale = 0.0
            # if ttH.Integral() > 0:
            #     ttH_scale = 10
            # else:
            #     ttH_scale = 0.0
            # if HWW.Integral() > 0:
            #     HWW_scale = 10
            # else:
            #     HWW_scale = 0

            if i in [0,1]:
                ggH.Scale(ggH_scale)
                qqH.Scale(qqH_scale)
                # VH.Scale(VH_scale)
                # ttH.Scale(ttH_scale)
                # HWW.Scale(HWW_scale)
            plot.subplot(i).add_hist(ggH, "ggH")
            plot.subplot(i).add_hist(ggH, "ggH_top")
            plot.subplot(i).add_hist(qqH, "qqH")
            plot.subplot(i).add_hist(qqH, "qqH_top")
            # plot.subplot(i).add_hist(VH, "VH")
            # plot.subplot(i).add_hist(VH, "VH_top")
            # plot.subplot(i).add_hist(ttH, "ttH")
            # plot.subplot(i).add_hist(ttH, "ttH_top")
            # plot.subplot(i).add_hist(HWW, "HWW")
            # plot.subplot(i).add_hist(HWW, "HWW_top")

    if "mm" not in channel:
        plot.subplot(0 if args.linear else 1).setGraphStyle(
            "ggH", "hist", linecolor=styles.color_dict["ggH"], linewidth=3)
        plot.subplot(0 if args.linear else 1).setGraphStyle("ggH_top", "hist", linecolor=0)
        plot.subplot(0 if args.linear else 1).setGraphStyle(
            "qqH", "hist", linecolor=styles.color_dict["qqH"], linewidth=3)
        plot.subplot(0 if args.linear else 1).setGraphStyle("qqH_top", "hist", linecolor=0)
        # plot.subplot(0 if args.linear else 1).setGraphStyle(
        #     "VH", "hist", linecolor=styles.color_dict["VH"], linewidth=3)
        # plot.subplot(0 if args.linear else 1).setGraphStyle("VH_top", "hist", linecolor=0)
        # plot.subplot(0 if args.linear else 1).setGraphStyle(
        #     "ttH", "hist", linecolor=styles.color_dict["ttH"], linewidth=3)
        # plot.subplot(0 if args.linear else 1).setGraphStyle("ttH_top", "hist", linecolor=0)
        # plot.subplot(0 if args.linear else 1).setGraphStyle(
        #     "HWW", "hist", linecolor=styles.color_dict["HWW"], linewidth=3)
        # plot.subplot(0 if args.linear else 1).setGraphStyle("HWW_top", "hist", linecolor=0)


    # assemble ratio
    if "mm" not in channel:
        bkg_ggH = plot.subplot(2).get_hist("ggH")
        bkg_qqH = plot.subplot(2).get_hist("qqH")
        bkg_ggH.Add(plot.subplot(2).get_hist("total_bkg"))
        bkg_qqH.Add(plot.subplot(2).get_hist("total_bkg"))
        plot.subplot(2).add_hist(bkg_ggH, "bkg_ggH")
        plot.subplot(2).add_hist(bkg_ggH, "bkg_ggH_top")
        plot.subplot(2).add_hist(bkg_qqH, "bkg_qqH")
        plot.subplot(2).add_hist(bkg_qqH, "bkg_qqH_top")
        plot.subplot(2).setGraphStyle(
            "bkg_ggH",
            "hist",
            linecolor=styles.color_dict["ggH"],
            linewidth=3)
        plot.subplot(2).setGraphStyle("bkg_ggH_top", "hist", linecolor=0)
        plot.subplot(2).setGraphStyle(
            "bkg_qqH",
            "hist",
            linecolor=styles.color_dict["qqH"],
            linewidth=3)
        plot.subplot(2).setGraphStyle("bkg_qqH_top", "hist", linecolor=0)

        plot.subplot(2).normalize([
            "total_bkg", "bkg_ggH", "bkg_ggH_top", "bkg_qqH",
            "bkg_qqH_top", "data_obs"
        ], "total_bkg")
    else:
        plot.subplot(2).normalize(["total_bkg", "data_obs"], "total_bkg")

    # stack background processes
    plot.create_stack(bkg_processes, "stack")

    # normalize stacks by bin-width
    if args.normalize_by_bin_width:
        plot.subplot(0).normalizeByBinWidth()
        plot.subplot(1).normalizeByBinWidth()

    # set axes limits and labels
    plot.subplot(0).setYlims(
        split_dict[channel],
        max(1.6 * plot.subplot(0).get_hist("data_obs").GetMaximum(),
            split_dict[channel] * 2))

    log_quantities = ["ME_ggh", "ME_vbf", "ME_z2j_1", "ME_z2j_2", "ME_q2v1", "ME_q2v2", "ME_vbf_vs_ggh", "ME_ggh_vs_Z"]
    if variable in log_quantities:
        plot.subplot(0).setLogY()
        plot.subplot(0).setYlims(
            1.0,
            1000 * plot.subplot(0).get_hist("data_obs").GetMaximum())

    plot.subplot(2).setYlims(0.75, 1.45)
    if channel == "mm":
        plot.subplot(0).setLogY()
        plot.subplot(0).setYlims(1, 10**10)

    if args.linear != True:
        plot.subplot(1).setYlims(0.1, split_dict[channel])
        plot.subplot(1).setYlabel(
            "")  # otherwise number labels are not drawn on axis
        plot.subplot(1).setLogY()
    # Check if variables should be plotted with log x axis
    log_x_variables = ["puppimet"]
    if variable in log_x_variables:
        plot.subplot(0).setLogX()
        plot.subplot(1).setLogX()
        plot.subplot(2).setLogX()
    if variable != None:
        if variable in styles.x_label_dict[channel]:
            x_label = styles.x_label_dict[channel][
                variable]
        else:
            x_label = variable
        plot.subplot(2).setXlabel(x_label)
    else:
        plot.subplot(2).setXlabel("NN output")
    if args.normalize_by_bin_width:
        plot.subplot(0).setYlabel("dN/d(NN output)")
    else:
        plot.subplot(0).setYlabel("N_{events}")

    plot.subplot(2).setYlabel("")
    plot.subplot(2).setGrid()
    plot.scaleYLabelSize(0.8)
    plot.scaleYTitleOffset(1.1)

    category = ""
    if not channel == "tt" and category in ["11", "12", "13", "14", "15", "16"]:
        plot.subplot(2).changeXLabels(["0.2", "0.4", "0.6", "0.8", "1.0"])

    # draw subplots. Argument contains names of objects to be drawn in corresponding order.
    if "mm" not in channel:
        # procs_to_draw = ["stack", "total_bkg", "ggH", "ggH_top", "qqH", "qqH_top", "VH", "VH_top", "ttH", "ttH_top", "data_obs"] if args.linear else ["stack", "total_bkg", "data_obs"]
        procs_to_draw = ["stack", "total_bkg", "ggH", "ggH_top", "qqH", "qqH_top", "data_obs"] if args.linear else ["stack", "total_bkg", "data_obs"]
        if args.draw_jet_fake_variation is not None:
            procs_to_draw = ["stack", "total_bkg", "data_obs"]
        plot.subplot(0).Draw(procs_to_draw)
        if args.linear != True:
            # plot.subplot(1).Draw([
            #     "stack", "total_bkg", "ggH", "ggH_top", "qqH", "qqH_top",
            #     "VH", "VH_top", "ttH", "ttH_top", "HWW", "HWW_top", "data_obs"
            # ])
            plot.subplot(1).Draw([
                "stack", "total_bkg", "ggH", "ggH_top", "qqH", "qqH_top",
                "data_obs"
            ])
        if args.draw_jet_fake_variation is None:
            plot.subplot(2).Draw([
                "total_bkg", "bkg_ggH", "bkg_ggH_top", "bkg_qqH",
                "bkg_qqH_top", "data_obs"
            ])
        else:
            plot.subplot(2).Draw([
                "total_bkg", "data_obs"
            ])
    else:
        procs_to_draw = ["stack", "total_bkg", "data_obs"] if args.linear else ["stack", "total_bkg", "data_obs"]
        plot.subplot(0).Draw(procs_to_draw)
        if args.linear != True:
            plot.subplot(1).Draw([
                "stack", "total_bkg", "data_obs"
            ])
        plot.subplot(2).Draw([
            "total_bkg", "data_obs"
        ])


    # create legends
    suffix = ["", "_top"]
    for i in range(2):

        plot.add_legend(width=0.6, height=0.15)
        for process in legend_bkg_processes:
            plot.legend(i).add_entry(
                0, process, styles.legend_label_dict[process.replace("TTL", "TT").replace("VVL", "VV").replace("NLO","")], 'f')
        plot.legend(i).add_entry(0, "total_bkg", "Bkg. stat. unc.", 'f')
        if "mm" not in channel and args.draw_jet_fake_variation is None:
            plot.legend(i).add_entry(0 if args.linear else 1, "ggH%s" % suffix[i], "%s #times gg#rightarrowH"%str(int(ggH_scale)), 'l')
            plot.legend(i).add_entry(0 if args.linear else 1, "qqH%s" % suffix[i], "%s #times qq#rightarrowH"%str(int(qqH_scale)), 'l')
            # plot.legend(i).add_entry(0 if args.linear else 1, "VH%s" % suffix[i], "%s #times V(lep)H"%str(int(VH_scale)), 'l')
            # plot.legend(i).add_entry(0 if args.linear else 1, "ttH%s" % suffix[i], "%s #times ttH"%str(int(ttH_scale)), 'l')
            # # plot.legend(i).add_entry(0 if args.linear else 1, "HWW%s" % suffix[i], "%s #times H#rightarrowWW"%str(int(HWW_scale)), 'l')
        plot.legend(i).add_entry(0, "data_obs", "Observed", 'PE2L')
        plot.legend(i).setNColumns(3)
    plot.legend(0).Draw()
    plot.legend(1).setAlpha(0.0)
    plot.legend(1).Draw()

    for i in range(2):
        plot.add_legend(
            reference_subplot=2, pos=1, width=0.6, height=0.03)
        plot.legend(i + 2).add_entry(0, "data_obs", "Observed", 'PE2L')
        if "mm" not in channel and args.draw_jet_fake_variation is None:
            plot.legend(i + 2).add_entry(0 if args.linear else 1, "ggH%s" % suffix[i],
                                         "ggH+bkg.", 'l')
            plot.legend(i + 2).add_entry(0 if args.linear else 1, "qqH%s" % suffix[i],
                                         "qqH+bkg.", 'l')
        plot.legend(i + 2).add_entry(0, "total_bkg", "Bkg. stat. unc.", 'f')
        plot.legend(i + 2).setNColumns(4)
    plot.legend(2).Draw()
    plot.legend(3).setAlpha(0.0)
    plot.legend(3).Draw()

    # draw additional labels
    plot.DrawCMS()
    if "2016" in args.era:
        plot.DrawLumi("35.9 fb^{-1} (2016, 13 TeV)")
    elif "2017" in args.era:
        plot.DrawLumi("41.5 fb^{-1} (2017, 13 TeV)")
    elif "2018" in args.era:
        plot.DrawLumi("59.7 fb^{-1} (2018, 13 TeV)")
    else:
        logger.critical("Era {} is not implemented.".format(args.era))
        raise Exception

    posChannelCategoryLabelLeft = None
    plot.DrawChannelCategoryLabel(
        "%s, %s" % (channel_dict[channel], "inclusive"),
        begin_left=posChannelCategoryLabelLeft)

    # save plot
    if not args.embedding and not args.fake_factor:
        postfix = "fully_classic"
    if args.embedding and not args.fake_factor:
        postfix = "emb_classic"
    if not args.embedding and args.fake_factor:
        postfix = "classic_ff"
    if args.embedding and args.fake_factor:
        postfix = "emb_ff"
    if args.draw_jet_fake_variation is not None:
        postfix = postfix + "_" + args.draw_jet_fake_variation

    if not os.path.exists("%s_plots_%s"%(args.era,postfix)):
        os.mkdir("%s_plots_%s"%(args.era,postfix))
    if not os.path.exists("%s_plots_%s/%s"%(args.era,postfix,channel)):
        os.mkdir("%s_plots_%s/%s"%(args.era,postfix,channel))
    print "Trying to save the created plot"
    plot.save("%s_plots_%s/%s/%s_%s_%s.%s" % (args.era, postfix, channel, args.era, channel, variable, "pdf"))
    plot.save("%s_plots_%s/%s/%s_%s_%s.%s" % (args.era, postfix, channel, args.era, channel, variable, "png"))
Пример #3
0
def main(args):
    if args.gof_variable != None:
        channel_categories = {c: [args.gof_variable] for c in args.channels}
    else:
        channel_categories = {
            #"et": ["ztt", "zll", "w", "tt", "ss", "misc"],
            "et": ["12", "15", "11", "13", "14", "16"],
            #"mt": ["ztt", "zll", "w", "tt", "ss", "misc"],
            "mt": ["12", "15", "11", "13", "14", "16"],
            #"tt": ["ztt", "noniso", "misc"]
            "tt": ["12", "17", "16"]
        }
        if args.stxs_categories == 0:
            for channel in ["et", "mt", "tt"]:
                channel_categories[channel] += ["1", "2"]
        elif args.stxs_categories == 1:
            for channel in ["et", "mt", "tt"]:
                channel_categories[channel] += ["1", "2"]
        else:
            logger.critical("Selected unkown STXS categorization {}",
                            args.stxs_categories)
            raise Exception
    channel_dict = {
        "ee": "ee",
        "em": "e#mu",
        "et": "e#tau_{h}",
        "mm": "#mu#mu",
        "mt": "#mu#tau_{h}",
        "tt": "#tau_{h}#tau_{h}"
    }
    if args.gof_variable != None:
        category_dict = {args.gof_variable: "inclusive"}
    else:
        category_dict = {
            "1": "ggH",
            "2": "VBF",
            "3": "ggH, unrolled",
            "4": "VBF, unrolled",
            "12": "Z#rightarrow#tau#tau",
            "15": "Z#rightarrowll",
            "11": "W+jets",
            "13": "t#bar{t}",
            "14": "same sign",
            "16": "misc",
            "17": "noniso"
        }
    if args.linear == True:
        split_value = 0
    else:
        if args.normalize_by_bin_width:
            split_value = 10001
        else:
            split_value = 101

    split_dict = {c: split_value for c in ["et", "mt", "tt"]}

    bkg_processes = [
        "EWKZ", "QCD", "VVT", "VVJ", "W", "TTT", "TTJ", "ZJ", "ZL", "ZTT"
    ]
    if args.fake_factor:
        bkg_processes = [
            b for b in bkg_processes if b not in ["QCD", "VVJ", "TTJ", "W", "ZJ"]
        ] + ["jetFakes"]
    if args.embedding:
        bkg_processes = [b for b in bkg_processes
                         if b not in ["ZTT", "TTT"]] + ["TTL", "EMB"]
    else: #keep ordering consistent
        bkg_processes.remove("ZTT")
        bkg_processes.remove("TTT")
        bkg_processes.append("TTT")
        bkg_processes.append("ZTT")
    all_bkg_processes = [b for b in bkg_processes]
    legend_bkg_processes = copy.deepcopy(bkg_processes)
    legend_bkg_processes.reverse()

    rootfile = rootfile_parser.Rootfile_parser(args.input)

    plots = []
    for channel in args.channels:
        if channel == "tt":
            if args.embedding:
                bkg_processes = [
                    b for b in all_bkg_processes if b is not "TTL"
                ]
            else:
                bkg_processes = [b for b in all_bkg_processes]
        else:
            bkg_processes = [b for b in all_bkg_processes]
        legend_bkg_processes = copy.deepcopy(bkg_processes)
        legend_bkg_processes.reverse()

        for category in channel_categories[channel]:
            # create plot
            width = 600
            if args.stxs_categories == 1:
                if category in ["1", "2"]:
                    width = 1200
            if args.linear == True:
                plot = dd.Plot(
                    [0.3, [0.3, 0.28]], "ModTDR", r=0.04, l=0.14, width=width)
            else:
                plot = dd.Plot(
                    [0.5, [0.3, 0.28]], "ModTDR", r=0.04, l=0.14, width=width)

            # get background histograms
            for process in bkg_processes:
                plot.add_hist(
                    rootfile.get(channel, category, process), process, "bkg")
                plot.setGraphStyle(
                    process, "hist", fillcolor=styles.color_dict[process])

            # get signal histograms
            for i in range(2):
                plot.subplot(i + 1).add_hist(
                    rootfile.get(channel, category, "ggH"), "ggH")
                plot.subplot(i + 1).add_hist(
                    rootfile.get(channel, category, "ggH"), "ggH_top")
                plot.subplot(i + 1).add_hist(
                    rootfile.get(channel, category, "qqH"), "qqH")
                plot.subplot(i + 1).add_hist(
                    rootfile.get(channel, category, "qqH"), "qqH_top")

            # get observed data and total background histograms
            plot.add_hist(
                rootfile.get(channel, category, "data_obs"), "data_obs")
            plot.add_hist(
                rootfile.get(channel, category, "TotalBkg"), "total_bkg")

            plot.subplot(0).setGraphStyle("data_obs", "e0")
            plot.subplot(1).setGraphStyle(
                "ggH", "hist", linecolor=styles.color_dict["ggH"], linewidth=3)
            plot.subplot(1).setGraphStyle("ggH_top", "hist", linecolor=0)
            plot.subplot(1).setGraphStyle(
                "qqH", "hist", linecolor=styles.color_dict["qqH"], linewidth=3)
            plot.subplot(1).setGraphStyle("qqH_top", "hist", linecolor=0)
            plot.setGraphStyle(
                "total_bkg",
                "e2",
                markersize=0,
                fillcolor=styles.color_dict["unc"],
                linecolor=0)

            # assemble ratio
            bkg_ggH = plot.subplot(2).get_hist("ggH")
            bkg_qqH = plot.subplot(2).get_hist("qqH")
            bkg_ggH.Add(plot.subplot(2).get_hist("total_bkg"))
            bkg_qqH.Add(plot.subplot(2).get_hist("total_bkg"))
            plot.subplot(2).add_hist(bkg_ggH, "bkg_ggH")
            plot.subplot(2).add_hist(bkg_ggH, "bkg_ggH_top")
            plot.subplot(2).add_hist(bkg_qqH, "bkg_qqH")
            plot.subplot(2).add_hist(bkg_qqH, "bkg_qqH_top")
            plot.subplot(2).setGraphStyle(
                "bkg_ggH",
                "hist",
                linecolor=styles.color_dict["ggH"],
                linewidth=3)
            plot.subplot(2).setGraphStyle("bkg_ggH_top", "hist", linecolor=0)
            plot.subplot(2).setGraphStyle(
                "bkg_qqH",
                "hist",
                linecolor=styles.color_dict["qqH"],
                linewidth=3)
            plot.subplot(2).setGraphStyle("bkg_qqH_top", "hist", linecolor=0)

            plot.subplot(2).normalize([
                "total_bkg", "bkg_ggH", "bkg_ggH_top", "bkg_qqH",
                "bkg_qqH_top", "data_obs"
            ], "total_bkg")

            # stack background processes
            plot.create_stack(bkg_processes, "stack")

            # normalize stacks by bin-width
            if args.normalize_by_bin_width:
                plot.subplot(0).normalizeByBinWidth()
                plot.subplot(1).normalizeByBinWidth()

            # set axes limits and labels
            plot.subplot(0).setYlims(
                split_dict[channel],
                max(2 * plot.subplot(0).get_hist("total_bkg").GetMaximum(),
                    split_dict[channel] * 2))

            plot.subplot(2).setYlims(0.75, 1.45)
            if int(category) < 10:
                plot.subplot(2).setYlims(0.55, 2.05)
            if args.linear != True:
                plot.subplot(1).setYlims(0.1, split_dict[channel])
                plot.subplot(1).setLogY()
                plot.subplot(1).setYlabel(
                    "")  # otherwise number labels are not drawn on axis
            if args.gof_variable != None:
                if args.gof_variable in styles.x_label_dict[args.channels[0]]:
                    x_label = styles.x_label_dict[args.channels[0]][
                        args.gof_variable]
                else:
                    x_label = args.gof_variable
                plot.subplot(2).setXlabel(x_label)
            else:
                plot.subplot(2).setXlabel("NN score")
            if args.normalize_by_bin_width:
                plot.subplot(0).setYlabel("N_{events}/bin width")
            else:
                plot.subplot(0).setYlabel("N_{events}")

            plot.subplot(2).setYlabel("Ratio to Bkg.")

            #plot.scaleXTitleSize(0.8)
            #plot.scaleXLabelSize(0.8)
            #plot.scaleYTitleSize(0.8)
            plot.scaleYLabelSize(0.8)
            #plot.scaleXLabelOffset(2.0)
            plot.scaleYTitleOffset(1.1)

            #plot.subplot(2).setNYdivisions(3, 5)

            # draw subplots. Argument contains names of objects to be drawn in corresponding order.
            plot.subplot(0).Draw(["stack", "total_bkg", "data_obs"])
            if args.linear != True:
                plot.subplot(1).Draw([
                    "stack", "total_bkg", "ggH", "ggH_top", "qqH", "qqH_top",
                    "data_obs"
                ])
            plot.subplot(2).Draw([
                "total_bkg", "bkg_ggH", "bkg_ggH_top", "bkg_qqH",
                "bkg_qqH_top", "data_obs"
            ])

            # create legends
            suffix = ["", "_top"]
            for i in range(2):

                plot.add_legend(width=0.6, height=0.15)
                for process in legend_bkg_processes:
                    plot.legend(i).add_entry(
                        0, process, styles.legend_label_dict[process], 'f')
                plot.legend(i).add_entry(0, "total_bkg", "Bkg. unc.", 'f')
                plot.legend(i).add_entry(1, "ggH%s" % suffix[i], "ggH", 'l')
                plot.legend(i).add_entry(1, "qqH%s" % suffix[i], "qqH", 'l')
                plot.legend(i).add_entry(0, "data_obs", "Data", 'PE')
                plot.legend(i).setNColumns(3)
            plot.legend(0).Draw()
            plot.legend(1).setAlpha(0.0)
            plot.legend(1).Draw()

            if args.chi2test:
                import ROOT as r
                f = r.TFile(args.input, "read")
                background = f.Get("htt_{}_{}_13TeV_{}/TotalBkg".format(
                    channel, category, "prefit"
                    if "prefit" in args.input else "postfit"))
                data = f.Get("htt_{}_{}_13TeV_{}/data_obs".format(
                    channel, category, "prefit"
                    if "prefit" in args.input else "postfit"))
                chi2 = data.Chi2Test(background, "UW CHI2/NDF")
                plot.DrawText(0.7, 0.3,
                              "\chi^{2}/ndf = " + str(round(chi2, 3)))

            for i in range(2):
                plot.add_legend(
                    reference_subplot=2, pos=1, width=0.5, height=0.03)
                plot.legend(i + 2).add_entry(0, "data_obs", "Data", 'PE')
                plot.legend(i + 2).add_entry(1, "ggH%s" % suffix[i],
                                             "ggH+bkg.", 'l')
                plot.legend(i + 2).add_entry(1, "qqH%s" % suffix[i],
                                             "qqH+bkg.", 'l')
                plot.legend(i + 2).add_entry(0, "total_bkg", "Bkg. unc.", 'f')
                plot.legend(i + 2).setNColumns(4)
            plot.legend(2).Draw()
            plot.legend(3).setAlpha(0.0)
            plot.legend(3).Draw()

            # draw additional labels
            plot.DrawCMS()
            if "2016" in args.era:
                plot.DrawLumi("35.9 fb^{-1} (13 TeV)")
            elif "2017" in args.era:
                plot.DrawLumi("41.3 fb^{-1} (13 TeV)")
            else:
                logger.critical("Era {} is not implemented.".format(args.era))
                raise Exception

            posChannelCategoryLabelLeft = None
            if args.stxs_categories == 1:
                if category in ["1", "2"]:
                    posChannelCategoryLabelLeft = 0.075
            plot.DrawChannelCategoryLabel(
                "%s, %s" % (channel_dict[channel], category_dict[category]),
                begin_left=posChannelCategoryLabelLeft)

            # save plot
            postfix = "prefit" if "prefit" in args.input else "postfit" if "postfit" in args.input else "undefined"
            plot.save("plots/%s_%s_%s_%s.%s" % (args.era, channel, category,
                                                postfix, "png"
                                                if args.png else "pdf"))
            plots.append(
                plot
            )  # work around to have clean up seg faults only at the end of the script
logger = logging.getLogger("")
logger.setLevel(logging.DEBUG)
formatter = logging.Formatter("%(name)s - %(levelname)s - %(message)s")
handler = logging.StreamHandler()
handler.setFormatter(formatter)
logger.addHandler(handler)

# Open file
era = 2016
channel = "tt"

category = "{}_m_sv".format(channel)
rootfile = rootfile_parser.Rootfile_parser("2016_shapes.root", "smhtt", "Run2016", "m_sv", 125)

# Make plot
plot = dd.Plot([], "ModTDR", r=0.04, l=0.15)

# Add backgrounds
bkg_processes = ["ZTT", "W", "ZL", "ZJ", "TTT", "TTL", "TTJ", "VVT", "VVL", "VVJ"]
for process in bkg_processes:
    plot.add_hist(rootfile.get(channel, category, process), process, "bkg")
    plot.setGraphStyle(process, "hist", fillcolor=styles.color_dict[process])
plot.create_stack(bkg_processes, "stack")

# Add data
plot.add_hist(rootfile.get(channel, category, "data_obs"), "data_obs", "data_obs")
plot.setGraphStyle(
    "data_obs",
    "e0",
    markersize=1,
    fillcolor=styles.color_dict["unc"],
Пример #5
0
def main():
    shifter = QuantileShifter("splines.root", "source", "target", True)
    backshifter = QuantileShifter("splines.root", "target", "source", True)
    hist1 = ROOT.TH1F("source", "source", 100, 0., 100.)
    hist2 = ROOT.TH1F("shifted", "shifted", 100, 0., 100.)
    hist3 = ROOT.TH1F("backshift", "backshift", 100, 0., 100.)
    hist4 = ROOT.TH1F("target", "target", 100, 0., 100.)
    for i in range(100000):
        number = random.gauss(40., 10.)
        hist1.Fill(number)
        hist2.Fill(shifter.shift(number))
        hist3.Fill(backshifter.shift(shifter.shift(number)))
        hist4.Fill(50. + (number - 40.) * 3. / 2.)  #random.gauss(50., 15.))
    plot = dd.Plot([[0.54, 0.52], [0.27, 0.25]], "ModTDR", r=0.04, l=0.14)
    plot.add_hist(hist1, "source")
    plot.add_hist(hist1, "source_err")
    plot.add_hist(hist2, "shifted")
    plot.add_hist(hist3, "backshift")
    plot.add_hist(hist4, "target")
    plot.add_hist(hist4, "target_err")
    plot.setGraphStyle('source', 'hist', linecolor=2, linewidth=3)
    plot.setGraphStyle('shifted', 'hist', linecolor=4, linewidth=1)
    plot.setGraphStyle('backshift', 'hist', linecolor=8, linewidth=3)
    plot.setGraphStyle('target', 'hist', linecolor=6, linewidth=1)
    plot.setGraphStyle('source_err',
                       'e2',
                       fillcolor=2,
                       fillstyle=3001,
                       linecolor=0)
    plot.setGraphStyle('target_err',
                       'e2',
                       fillcolor=6,
                       fillstyle=3001,
                       linecolor=0)

    plot.subplot(0).setYlabel("N_{events}")
    plot.subplot(1).setYlabel("shifted/tar.")
    plot.subplot(2).setYlabel("bck.sh./orig.")
    plot.subplot(1).setYlims(0.55, 1.45)
    plot.subplot(2).setYlims(0.55, 1.45)
    plot.subplot(1).setNYdivisions(6, 10)
    plot.subplot(2).setNYdivisions(6, 10)
    plot.subplot(2).setXlabel("variable (arb.units)")
    plot.scaleYTitleOffset(2.0)

    plot.subplot(2).normalize(["source_err", "backshift"], "source")
    plot.subplot(1).normalize(["shifted", "target_err"], "target")
    plot.subplot(0).Draw([
        "source_err", "target_err", "source", "target", "shifted", "backshift"
    ])
    plot.subplot(1).Draw(["target_err", "shifted"])
    plot.subplot(2).Draw(["source_err", "backshift"])
    plot.add_legend(width=0.25, height=0.2)
    plot.legend(0).add_entry(0, "source", "original", 'l')
    plot.legend(0).add_entry(0, "source_err", "original Poisson err.", 'f')
    plot.legend(0).add_entry(0, "target", "target", 'l')
    plot.legend(0).add_entry(0, "target_err", "target Poisson err.", 'f')
    plot.legend(0).add_entry(0, "shifted", "shifted", 'l')
    plot.legend(0).add_entry(0, "backshift", "shifted back", 'l')
    plot.legend(0).Draw()
    plot.save("applied_quantile_method.pdf")
Пример #6
0
def main(args):
    channel_categories = {
        "mt": ["0"],
    }
    channel_dict = {
        "ee": "ee",
        "em": "e#mu",
        "et": "e#tau_{h}",
        "mm": "#mu#mu",
        "mt": "#mu#tau_{h}",
        "tt": "#tau_{h}#tau_{h}"
    }
    category_dict = {"0": "nll"}

    bkg_processes = [
        "QCD",
        "VVT",
        "VVL",
        "VVJ",
        "W",
        "TTT",
        "TTL",
        "TTJ",
        "ZJ",
        "ZL",
        "ZTT"]
    all_bkg_processes = [b for b in bkg_processes]
    legend_bkg_processes = copy.deepcopy(bkg_processes)
    legend_bkg_processes.reverse()

    era = 2018
    plots = []
    channel = "mt"
    for category in channel_categories[channel]:
        linear = False if category == "0" else True
        normalize_by_bin_width = False
        if linear:
            split_value = 0
        else:
            split_value = 101

        rootfile = rootfile_parser.Rootfile_parser(os.path.join(args.workdir, "shapes_{}.root".format(args.fittype)))
        bkg_processes = [b for b in all_bkg_processes]
        legend_bkg_processes = copy.deepcopy(bkg_processes)
        legend_bkg_processes.reverse()
        # create plot
        width = 600
        if linear:
            plot = dd.Plot(
                [0.3, [0.3, 0.28]], "ModTDR", r=0.04, l=0.14, width=width)
        else:
            plot = dd.Plot(
                [0.5, [0.3, 0.28]], "ModTDR", r=0.04, l=0.14, width=width)

        # get background histograms
        for process in bkg_processes:
            try:
                plot.add_hist(
                    rootfile.get(
                        era,
                        channel,
                        category,
                        process),
                    process,
                    "bkg")
                plot.setGraphStyle(
                    process, "hist", fillcolor=styles.color_dict[process])
            except BaseException:
                pass

        # get signal histograms
        plot_idx_to_add_signal = [0, 2] if linear else [1, 2]
        for i in plot_idx_to_add_signal:
            plot.subplot(i).add_hist(
                rootfile.get(era, channel, category, "ggH"), "ggH")
            plot.subplot(i).add_hist(
                rootfile.get(era, channel, category, "ggH"), "ggH_top")
            plot.subplot(i).add_hist(
                rootfile.get(era, channel, category, "qqH"), "qqH")
            plot.subplot(i).add_hist(
                rootfile.get(era, channel, category, "qqH"), "qqH_top")

        # get observed data and total background histograms
        # NOTE: With CMSSW_8_1_0 the TotalBkg definition has changed.
        plot.add_hist(
            rootfile.get(era, channel, category, "data_obs"), "data_obs")
        total_bkg = rootfile.get(era, channel, category, "TotalBkg")
        #ggHHist = rootfile.get(era, channel, category, "ggH")
        #qqHHist = rootfile.get(era, channel, category, "qqH")
        #total_bkg.Add(ggHHist, -1)
        # if qqHHist:
        #     total_bkg.Add(qqHHist, -1)
        plot.add_hist(total_bkg, "total_bkg")

        plot.subplot(0).setGraphStyle("data_obs", "e0")
        plot.subplot(0 if linear else 1).setGraphStyle(
            "ggH", "hist", linecolor=styles.color_dict["ggH"], linewidth=3)
        plot.subplot(
            0 if linear else 1).setGraphStyle(
            "ggH_top", "hist", linecolor=0)
        plot.subplot(0 if linear else 1).setGraphStyle(
            "qqH", "hist", linecolor=styles.color_dict["qqH"], linewidth=3)
        plot.subplot(
            0 if linear else 1).setGraphStyle(
            "qqH_top", "hist", linecolor=0)
        plot.subplot(0 if linear else 1).setGraphStyle(
            "VH", "hist", linecolor=styles.color_dict["VH"], linewidth=3)
        plot.subplot(
            0 if linear else 1).setGraphStyle(
            "VH_top", "hist", linecolor=0)
        plot.subplot(0 if linear else 1).setGraphStyle(
            "ttH", "hist", linecolor=styles.color_dict["ttH"], linewidth=3)
        plot.subplot(
            0 if linear else 1).setGraphStyle(
            "ttH_top", "hist", linecolor=0)
        plot.subplot(0 if linear else 1).setGraphStyle(
            "HWW", "hist", linecolor=styles.color_dict["HWW"], linewidth=3)
        plot.subplot(
            0 if linear else 1).setGraphStyle(
            "HWW_top", "hist", linecolor=0)
        plot.setGraphStyle(
            "total_bkg",
            "e2",
            markersize=0,
            fillcolor=styles.color_dict["unc"],
            linecolor=0)

        # assemble ratio
        bkg_ggH = plot.subplot(2).get_hist("ggH")
        bkg_qqH = plot.subplot(2).get_hist("qqH")
        bkg_ggH.Add(plot.subplot(2).get_hist("total_bkg"))
        if bkg_qqH:
            bkg_qqH.Add(plot.subplot(2).get_hist("total_bkg"))
        plot.subplot(2).add_hist(bkg_ggH, "bkg_ggH")
        plot.subplot(2).add_hist(bkg_ggH, "bkg_ggH_top")
        plot.subplot(2).add_hist(bkg_qqH, "bkg_qqH")
        plot.subplot(2).add_hist(bkg_qqH, "bkg_qqH_top")
        plot.subplot(2).setGraphStyle(
            "bkg_ggH",
            "hist",
            linecolor=styles.color_dict["ggH"],
            linewidth=3)
        plot.subplot(2).setGraphStyle("bkg_ggH_top", "hist", linecolor=0)
        plot.subplot(2).setGraphStyle(
            "bkg_qqH",
            "hist",
            linecolor=styles.color_dict["qqH"],
            linewidth=3)
        plot.subplot(2).setGraphStyle("bkg_qqH_top", "hist", linecolor=0)

        plot.subplot(2).normalize([
            "total_bkg", "bkg_ggH", "bkg_ggH_top", "bkg_qqH",
            "bkg_qqH_top", "data_obs"
        ], "total_bkg")

        # stack background processes
        plot.create_stack(bkg_processes, "stack")

        # normalize stacks by bin-width
        if normalize_by_bin_width:
            plot.subplot(0).normalizeByBinWidth()
            plot.subplot(1).normalizeByBinWidth()

        # set axes limits and labels
        plot.subplot(0).setYlims(
            split_value,
            max(2 * plot.subplot(0).get_hist("total_bkg").GetMaximum(),
                split_value * 2))

        plot.subplot(2).setYlims(0.75, 1.35)
        if not linear:
            plot.subplot(1).setYlims(0.1, split_value)
            plot.subplot(1).setLogY()
            plot.subplot(1).setYlabel(
                "")  # otherwise number labels are not drawn on axis
        plot.subplot(2).setXlabel(styles.x_label_dict[channel][cfg.analysis_variable])
        if normalize_by_bin_width:
            plot.subplot(0).setYlabel("dN/d(NN output)")
        else:
            plot.subplot(0).setYlabel("N_{events}")

        plot.subplot(2).setYlabel("")

        # plot.scaleXTitleSize(0.8)
        # plot.scaleXLabelSize(0.8)
        # plot.scaleYTitleSize(0.8)
        plot.scaleYLabelSize(0.8)
        # plot.scaleXLabelOffset(2.0)
        plot.scaleYTitleOffset(1.1)

        #plot.subplot(2).setNYdivisions(3, 5)

        # if not channel == "tt" and category in ["11", "12", "13", "14", "15", "16"]:
        #    plot.subplot(2).changeXLabels(["0.2", "0.4", "0.6", "0.8", "1.0"])

        # draw subplots. Argument contains names of objects to be drawn in
        # corresponding order.
        procs_to_draw = [
            "stack",
            "total_bkg",
            "ggH",
            "ggH_top",
            "qqH",
            "qqH_top",
            "data_obs"] if linear else [
            "stack",
            "total_bkg",
            "data_obs"]
        plot.subplot(0).Draw(procs_to_draw)
        if not linear:
            plot.subplot(1).Draw(
                ["stack", "total_bkg", "ggH", "ggH_top", "qqH", "qqH_top",
                 "data_obs"])
        plot.subplot(2).Draw([
            "total_bkg", "bkg_ggH", "bkg_ggH_top", "bkg_qqH",
            "bkg_qqH_top", "data_obs"
        ])

        # create legends
        suffix = ["", "_top"]
        for i in range(2):

            plot.add_legend(width=0.6, height=0.15)
            for process in legend_bkg_processes:
                try:
                    plot.legend(i).add_entry(
                        0, process, styles.legend_label_dict
                        [process.replace("TTL", "TT").replace(
                            "VVL", "VV")],
                        'f')
                except BaseException:
                    pass
            plot.legend(i).add_entry(0, "total_bkg", "Bkg. unc.", 'f')
            plot.legend(i).add_entry(
                0 if linear else 1, "ggH%s" %
                suffix[i], "gg#rightarrowH", 'l')
            plot.legend(i).add_entry(
                0 if linear else 1, "qqH%s" %
                suffix[i], "qq#rightarrowH", 'l')
            plot.legend(i).add_entry(0, "data_obs", "Data", 'PE')
            plot.legend(i).setNColumns(3)
        plot.legend(0).Draw()
        plot.legend(1).setAlpha(0.0)
        plot.legend(1).Draw()

        for i in range(2):
            plot.add_legend(
                reference_subplot=2, pos=1, width=0.5, height=0.03)
            plot.legend(i + 2).add_entry(0, "data_obs", "Data", 'PE')
            plot.legend(
                i +
                2).add_entry(
                0 if linear else 1,
                "ggH%s" %
                suffix[i],
                "ggH+bkg.",
                'l')
            plot.legend(
                i +
                2).add_entry(
                0 if linear else 1,
                "qqH%s" %
                suffix[i],
                "qqH+bkg.",
                'l')
            plot.legend(i + 2).add_entry(0, "total_bkg", "Bkg. unc.", 'f')
            plot.legend(i + 2).setNColumns(4)
        plot.legend(2).Draw()
        plot.legend(3).setAlpha(0.0)
        plot.legend(3).Draw()

        # draw additional labels
        #plot.DrawCMS()
        plot.DrawLumi("59.7 fb^{-1} (2018, 13 TeV)")

        plot.DrawChannelCategoryLabel(
            "%s, %s" % (channel_dict[channel], category_dict[category]),
            begin_left=None)

        # save plot
        for filetype in ["png", "pdf"]:
            plot.save(
                "%s/%s_%s_%s_%s.%s" %
                (args.workdir,
                 "2018",
                 channel,
                 category,
                 args.fittype,
                 filetype))
        # work around to have clean up seg faults only at the end of the
        # script
        plots.append(plot)
Пример #7
0
def main(args):
    if args.gof_variable != None:
        channel_categories = {
            "et": ["100"],
            "mt": ["100"],
            "tt": ["100"],
            "em": ["100"],
            "mm": ["100"],
        }
    channel_categories = {
        "mt": [args.bin],
        "mm": ["100"],
    }
    channel_dict = {
        "ee": "ee",
        "em": "e#mu",
        "et": "e#tau_{h}",
        "mm": "#mu#mu",
        "mt": "#mu#tau_{h}",
        "tt": "#tau_{h}#tau_{h}"
    }
    if args.gof_variable != None:
        category_dict = {"100": "inclusive"}
    elif args.categories == "inclusive":
        category_dict = {
            "1": "inclusive",
            "100": "cr",
        }
    elif args.categories == "pt_binned":
        category_dict = {
            "1": "[20,25]",
            "2": "[25,30]",
            "3": "[30,35]",
            "4": "[35,40]",
            "5": "[40,50]",
            "6": "[50,70]",
            "7": "[70,]",
            "100": "cr",
        }
    elif args.categories == "dm_binned":
        category_dict = {
            "1": "DM0",
            "2": "DM1",
            "3": "DM10",
            "4": "DM11",
            "100": "cr",
        }
    elif args.categories == "ptdm_binned":
        category_dict = {
            "1": "[20,25], DM0",
            "2": "[20,25], DM1",
            "3": "[20,25], DM10",
            "4": "[25,30], DM0",
            "5": "[25,30], DM1",
            "6": "[25,30], DM10",
            "7": "[30,35], DM0",
            "8": "[30,35], DM1",
            "9": "[30,35], DM10",
            "10": "[35,40], DM0",
            "11": "[35,40], DM1",
            "12": "[35,40], DM10",
            "13": "[40,50], DM0",
            "14": "[40,50], DM1",
            "15": "[40,50], DM10",
            "16": "[50,70], DM0",
            "17": "[50,70], DM1",
            "18": "[50,70], DM10",
            "19": "[70,], DM0",
            "20": "[70,], DM1",
            "21": "[70,], DM10",
            "100": "cr",
        }
    else:
        logger.fatal(
            "Neither gof variable nor valid categorisation specified.")
        raise Exception

    if args.linear == True:
        split_value = 0
    else:
        if args.normalize_by_bin_width:
            split_value = 10001
        else:
            split_value = 101

    split_dict = {c: split_value for c in ["et", "mt", "tt", "em", "mm"]}

    bkg_processes = {
        "mt": ["VVL", "TTL", "ZL", "jetFakes", "EMB"],
        "mm": ["VV", "TT", "jetFakes", "EMB"]
    }
    if not args.fake_factor and args.embedding:
        bkg_processes = {
            "mt":
            ["QCDEMB", "VVJ", "VVL", "W", "TTJ", "TTL", "ZJ", "ZL", "EMB"],
            "mm": ["QCDEMB", "W", "MMEMB"]
        }
    if not args.embedding and args.fake_factor:
        bkg_processes = {
            "mt": ["VVT", "VVJ", "TTT", "TTJ", "ZJ", "ZL", "jetFakes", "ZTT"],
            "mm": ["VV", "TT", "jetFakes", "ZLL"]
        }
    if not args.embedding and not args.fake_factor:
        bkg_processes = {
            "mt": [
                "QCD", "VVT", "VVL", "VVJ", "W", "TTT", "TTL", "TTJ", "ZJ",
                "ZL", "ZTT"
            ],
            "mm": ["VV", "W", "TT", "ZLL"]
        }

    legend_bkg_processes = copy.deepcopy(bkg_processes)
    for chn_bkg_processes in legend_bkg_processes.itervalues():
        chn_bkg_processes.reverse()

    if "2016" in args.era:
        era = "Run2016"
    elif "2017" in args.era:
        era = "Run2017"
    elif "2018" in args.era:
        era = "Run2018"
    else:
        logger.critical("Era {} is not implemented.".format(args.era))
        raise Exception

    plots = []
    for channel in args.channels:
        for category in channel_categories[channel]:
            rootfile = rootfile_parser.Rootfile_parser(args.input)
            tranche = None
            if "_" in category:
                tranche = category.split("_")[1]
                category = category.split("_")[0]
            # create plot
            width = 600
            if args.linear == True:
                plot = dd.Plot([0.3, [0.3, 0.28]],
                               "ModTDR",
                               r=0.04,
                               l=0.14,
                               width=width)
            else:
                plot = dd.Plot([0.5, [0.3, 0.28]],
                               "ModTDR",
                               r=0.04,
                               l=0.14,
                               width=width)

            # get background histograms
            for process in bkg_processes[channel]:
                plot.add_hist(rootfile.get(era, channel, category, process),
                              process, "bkg")
                plot.setGraphStyle(process,
                                   "hist",
                                   fillcolor=styles.color_dict[process])

            # get observed data and total background histograms
            # NOTE: With CMSSW_8_1_0 the TotalBkg definition has changed.
            plot.add_hist(rootfile.get(era, channel, category, "data_obs"),
                          "data_obs")
            total_bkg = rootfile.get(era, channel, category, "TotalBkg")
            if args.embedding:
                total_bkg.Add(rootfile.get(era, channel, category, "EMB"))
            else:
                total_bkg.Add(rootfile.get(era, channel, category, "ZTT"))
            plot.add_hist(total_bkg, "total_bkg")

            plot.subplot(0).setGraphStyle("data_obs", "e0")
            plot.setGraphStyle("total_bkg",
                               "e2",
                               markersize=0,
                               fillcolor=styles.color_dict["unc"],
                               linecolor=0)

            plot.subplot(2).normalize(["total_bkg", "data_obs"], "total_bkg")

            # stack background processes
            plot.create_stack(bkg_processes[channel], "stack")

            # normalize stacks by bin-width
            if args.normalize_by_bin_width:
                plot.subplot(0).normalizeByBinWidth()
                plot.subplot(1).normalizeByBinWidth()

            # # set axes limits and labels
            plot.subplot(0).setYlims(
                split_dict[channel],
                max(2 * plot.subplot(0).get_hist("total_bkg").GetMaximum(),
                    split_dict[channel] * 2))

            plot.subplot(2).setYlims(0.5, 1.5)

            if args.linear != True:
                plot.subplot(1).setYlims(0.1, split_dict[channel])
                plot.subplot(1).setLogY()
                plot.subplot(1).setYlabel(
                    "")  # otherwise number labels are not drawn on axis
            if args.gof_variable != None:
                if args.gof_variable in styles.x_label_dict[args.channels[0]]:
                    x_label = styles.x_label_dict[args.channels[0]][
                        args.gof_variable]
                else:
                    x_label = args.gof_variable
                plot.subplot(2).setXlabel(x_label)
            else:
                plot.subplot(2).setXlabel("m_{vis} / GeV")
            if args.normalize_by_bin_width:
                plot.subplot(0).setYlabel("dN/d(NN output)")
            else:
                plot.subplot(0).setYlabel("N_{events}")

            plot.subplot(2).setYlabel("")

            #plot.scaleXTitleSize(0.8)
            #plot.scaleXLabelSize(0.8)
            #plot.scaleYTitleSize(0.8)
            plot.scaleYLabelSize(0.8)
            #plot.scaleXLabelOffset(2.0)
            plot.scaleYTitleOffset(1.1)

            #plot.subplot(2).setNYdivisions(3, 5)

            # draw subplots. Argument contains names of objects to be drawn in corresponding order.
            procs_to_draw = ["stack", "data_obs"
                             ] if args.linear else ["stack", "data_obs"]
            plot.subplot(0).Draw(procs_to_draw)
            if args.linear != True:
                plot.subplot(1).Draw(["stack", "data_obs"])
            plot.subplot(2).Draw(["total_bkg", "data_obs"])

            # create legends
            suffix = ["", "_top"]
            for i in range(2):
                plot.add_legend(width=0.6, height=0.2)
                for process in legend_bkg_processes[channel]:
                    plot.legend(i).add_entry(
                        0, process, styles.legend_label_dict[process.replace(
                            "TTL", "TT").replace("VVL", "VV")], 'f')
                plot.legend(i).add_entry(0, "data_obs", "Data", 'PE')
                plot.legend(i).setNColumns(3)
            plot.legend(0).Draw()
            plot.legend(1).setAlpha(0.0)
            plot.legend(1).Draw()

            if args.chi2test:
                import ROOT as r
                f = r.TFile(args.input, "read")
                background = f.Get("htt_{}_{}_Run{}_{}/TotalBkg".format(
                    channel, category, args.era,
                    "prefit" if "prefit" in args.input else "postfit"))
                data = f.Get("htt_{}_{}_Run{}_{}/data_obs".format(
                    channel, category, args.era,
                    "prefit" if "prefit" in args.input else "postfit"))
                chi2 = data.Chi2Test(background, "UW CHI2/NDF")
                plot.DrawText(0.7, 0.3,
                              "\chi^{2}/ndf = " + str(round(chi2, 3)))

            for i in range(2):
                plot.add_legend(reference_subplot=2,
                                pos=1,
                                width=0.5,
                                height=0.03)
                plot.legend(i + 2).add_entry(0, "data_obs", "Data", 'PE')
                plot.legend(i + 2).setNColumns(4)
            plot.legend(2).Draw()
            plot.legend(3).setAlpha(0.0)
            plot.legend(3).Draw()

            # draw additional labels
            plot.DrawCMS()
            if "2016" in args.era:
                plot.DrawLumi("35.9 fb^{-1} (2016, 13 TeV)")
            elif "2017" in args.era:
                plot.DrawLumi("41.5 fb^{-1} (2017, 13 TeV)")
            elif "2018" in args.era:
                plot.DrawLumi("57.9 fb^{-1} (2018, 13 TeV)")
            else:
                logger.critical("Era {} is not implemented.".format(args.era))
                raise Exception

            posChannelCategoryLabelLeft = None
            plot.DrawChannelCategoryLabel(
                "%s, %s" % (channel_dict[channel], category_dict[category]),
                begin_left=posChannelCategoryLabelLeft)

            # save plot
            postfix = "prefit" if "prefit" in args.input else "postfit" if "postfit" in args.input else "undefined"
            plot.save("%s_plots/%s_%s_%s_%s.%s" %
                      (args.era, args.era, channel, args.gof_variable
                       if args.gof_variable is not None else category
                       if tranche == None else "_".join([category, tranche]),
                       postfix, "png" if args.png else "pdf"))
            plots.append(
                plot
            )  # work around to have clean up seg faults only at the end of the script
Пример #8
0
}

for ch in channel_dict:
    if not os.path.exists("cutscans/%s" % ch):
        os.mkdir("cutscans/%s" % ch)
    for sig in signals:
        if not os.path.exists("cutscans/%s/%s" % (ch, sig)):
            os.mkdir("cutscans/%s/%s" % (ch, sig))

for sig in signals:
    for var in soverb_dict[sig]:
        channel = var.split("_")[0]
        variable_name = var.replace(channel + "_", "", 1)
        print channel, variable_name
        width = 600
        plot = dd.Plot([], "ModTDR", r=0.04, l=0.14, width=width)
        cuts_less = r.TGraph(len(cutvalues[var]), np.array(cutvalues[var]),
                             np.array(soverb_dict[sig][var]["less"]))
        cuts_greater = r.TGraph(len(cutvalues[var]), np.array(cutvalues[var]),
                                np.array(soverb_dict[sig][var]["greater"]))
        plot.add_graph(cuts_less, "cuts_less")
        plot.add_graph(cuts_greater, "cuts_greater")
        plot.setGraphStyle("cuts_less",
                           "L",
                           linecolor=r.kBlue,
                           linewidth=3,
                           markersize=0)
        plot.setGraphStyle("cuts_greater",
                           "L",
                           linecolor=r.kRed,
                           linewidth=3,
Пример #9
0
def main(args):
    hack = []
    roc = {}
    shapes = {}
    for channel in args.channels:
        roc[channel] = {}
        shapes[channel] = {}
        for category in args.categories:
            roc[channel][category] = {}
            shapes[channel][category] = {}
    for variable in args.variables:
        for channel in args.channels:
            for category in args.categories:
                rootfile = rootfile_parser.Rootfile_parser(
                    "2016_shapes.root", "smhtt", "Run2016", variable, 125)
                #print rootfile.list_contents()
                name = "_".join([channel, category])
                out_name = "_".join([channel, category, variable])
                print name

                # create canvas:
                #   First argument defines subplot structure: List of splits from top to bottom (max. 1.0 to min. 0.0). A split can be a single position or a pair resulting in gap.
                #   Further arguments set general style.
                plot = dd.Plot([0.05], "ModTDR", r=0.04, l=0.14)

                #bkg_processes = ["EWK", "QCD", "VV", "W", "TTT", "TTJ", "ZJ", "ZL", "ZTT"]
                bkg_processes = [
                    "EWK", "QCD", "VV", "W", "TTT", "TTJ", "ZL", "ZJ", "ZTT"
                ]
                if channel == 'tt':
                    bkg_processes = [
                        "QCD", "VVT", "VVJ", "W", "TTT", "TTJ", "ZL", "ZJ",
                        "ZTT"
                    ]

                # register histograms in the subplots (can be done globally or for specific subplots). regustered histograms are not necessarily plotted later.
                for process in bkg_processes:
                    plot.add_hist(
                        rootfile.get(channel, name, process), process, "bkg"
                    )  # get(channel, category, process) and assign specific name and group name to histogram. The group name is optional.
                    plot.setGraphStyle(process,
                                       "hist",
                                       fillcolor=styles.color_dict[process])

#				for i in range(1):
#					plot.add_hist(
#						rootfile.get(channel, name, "ggh"), "ggh"
#						)  # signal histograms are used twice in order to realize a two color line style
#					plot.add_hist(
#						rootfile.get(channel, name, "ggh"), "ggh_top")
#					plot.add_hist(rootfile.get(channel, name, "qqH"), "qqH")
#					plot.add_hist(
#						rootfile.get(channel, name, "qqH"), "qqH_top")
                plot.add_hist(rootfile.get(channel, name, "data_obs"),
                              "data_obs", "data_obs")
                # set some graph styles
                #				plot.setGraphStyle(
                #					"ggh", "hist", linecolor=styles.color_dict["ggh"], linewidth=3)
                #				plot.setGraphStyle("ggh_top", "hist", linecolor=0)
                #				plot.setGraphStyle(
                #					"qqH", "hist", linecolor=styles.color_dict["qqH"], linewidth=3)

                #				plot.setGraphStyle("qqH_top", "hist", linecolor=0)
                plot.setGraphStyle("data_obs",
                                   "e0",
                                   markersize=1,
                                   fillcolor=styles.color_dict["unc"],
                                   linecolor=1)
                plot.create_stack(bkg_processes, "stack")
                #				plot.subplot(1).normalize(["data_obs"], bkg_processes) # would also work but add up the single bkg histograms in the background
                if channel == 'tt':
                    plot.subplot(0).setYlims(1, 1e5)
                    plot.DrawChannelCategoryLabel("#tau_{h}#tau_{h}")
                elif channel == 'mt':
                    plot.subplot(0).setYlims(1, 1e7)
                    plot.DrawChannelCategoryLabel("#mu#tau_{h}")
                elif channel == 'et':
                    plot.subplot(0).setYlims(0.1, 1e7)
                    plot.DrawChannelCategoryLabel("e#tau_{h}")

    #			plot.subplot(0).setXlims(-200, 200)
    #			plot.subplot(1).setXlims(-200, )
                plot.subplot(1).setYlims(0, 2)
                plot.subplot(0).setLogY()
                plot.subplot(0).setXlabel(variable)
                plot.subplot(0).setYlabel("N_{events}")
                plot.subplot(1).setYlabel("ratio to bkg")

                plot.scaleXTitleSize(0.8)
                plot.scaleXLabelSize(0.8)
                plot.scaleYTitleSize(0.8)
                plot.scaleYLabelSize(0.8)
                plot.scaleXLabelOffset(2.0)
                plot.scaleYTitleOffset(1.1)
                plot.subplot(0).Draw([
                    'stack',
                    "data_obs",
                    "ggh",
                    "qqH",
                    "ggh_top",
                    "qqH_top",
                ])
                #			plot.subplot(1).add_hist(R.TF1("line", "1", 0, 1000), "line")
                #				plot.subplot(1).Draw(["data_obs", "line"])

                # create legends
                bkg_processes.reverse()
                suffix = ["", "_top"]
                for i in range(2):
                    plot.add_legend(width=0.5, height=0.08)
                    for process in bkg_processes:
                        plot.legend(i).add_entry(
                            0, process, styles.legend_label_dict[process], 'f')
                    #plot.legend(i).add_entry(1, "ggh%s" % suffix[i], "ggh", 'l')
                    #plot.legend(i).add_entry(1, "qqH%s" % suffix[i], "qqH", 'l')


#					plot.legend(i).add_entry(0, "data_obs", "Data", 'PE')
                    plot.legend(i).setNColumns(3)
                plot.legend(0).Draw()
                plot.subplot(1)._pad.SetGrid()

                # draw additional labels
                plot.DrawCMS()
                plot.DrawLumi("35.9 fb^{-1} (13 TeV)")

                # save plot
                plot.save(out_name + ".png")
                plot.save(out_name + ".pdf")
                hack.append(plot)
Пример #10
0
def main(args):
    channel_categories = {
        "et": ["ggh", "qqh", "ztt", "zll", "w", "tt", "ss", "misc"],
        "mt": ["ggh", "qqh", "ztt", "zll", "w", "tt", "ss", "misc"],
        "tt": ["ggh", "qqh", "ztt", "noniso", "misc"]
    }
    channel_dict = {
        "ee": "ee",
        "em": "e#mu",
        "et": "e#tau_{h}",
        "mm": "#mu#mu",
        "mt": "#mu#tau_{h}",
        "tt": "#tau_{h}#tau_{h}"
    }
    category_dict = {
        "ggh": "ggH",
        "qqh": "VBF",
        "ztt": "Z#rightarrow#tau#tau",
        "zll": "Z#rightarrowll",
        "w": "W+jets",
        "tt": "t#bar{t}",
        "ss": "same sign",
        "misc": "misc",
        "noniso": "noniso"
    }
    split_dict = {"et": 50, "mt": 200, "tt": 20}

    bkg_processes = ["EWK", "QCD", "VV", "W", "TTT", "TTJ", "ZJ", "ZL", "ZTT"]
    legend_bkg_processes = copy.deepcopy(bkg_processes)
    legend_bkg_processes.reverse()

    rootfile_unc = rootfile_parser.Rootfile_parser(args.input)
    rootfile_prefit = rootfile_parser.Rootfile_parser(
        args.input.replace(".root", "_prefit.root"))
    #for process in bkg_processes:
    #    if rootfile.get('mt', 'ztt', process, 'CMS_htt_dyShapeUp') != None:
    #        print process

    plots = []
    for channel in args.channels:
        for category in channel_categories[channel]:
            plot = dd.Plot([[0.4, 0.38]], "ModTDR", r=0.04, l=0.14)
            for process in bkg_processes:
                plot.add_hist(rootfile_prefit.get(channel, category, process),
                              process, "bkg")
                plot.setGraphStyle(process,
                                   "hist",
                                   fillcolor=styles.color_dict[process])
            plot.add_hist(rootfile_prefit.get(channel, category, "ggH"), "ggH",
                          "signal")
            plot.add_hist(rootfile_prefit.get(channel, category, "ggH"),
                          "ggH_top")
            plot.add_hist(rootfile_prefit.get(channel, category, "qqH"), "qqH",
                          "signal")
            plot.add_hist(rootfile_prefit.get(channel, category, "qqH"),
                          "qqH_top")
            plot.add_hist(rootfile_prefit.get(channel, category, "data_obs"),
                          "data_obs")
            plot.add_hist(rootfile_prefit.get(channel, category, "TotalBkg"),
                          "total_bkg")
            for index, uncertainty in enumerate(args.uncertainties):
                for shift in ["Up", "Down"]:
                    for process in bkg_processes + ["ggH125", "qqH125"]:
                        hist = rootfile_unc.get(channel, category, process,
                                                uncertainty + shift)
                        if hist != None:
                            plot.subplot(0).add_hist(
                                hist, process + uncertainty + shift,
                                uncertainty + shift)
                        else:
                            plot.subplot(0).add_hist(
                                rootfile_unc.get(channel, category, process),
                                process + uncertainty + shift,
                                uncertainty + shift)
                    sighist = plot.subplot(0).get_hist("signal")
                    sighist.Scale(-1)
                    plot.subplot(0).add_hist(sighist,
                                             "signal" + uncertainty + shift,
                                             uncertainty + shift)
                    plot.add_hist(
                        plot.subplot(0).get_hist(uncertainty + shift),
                        "total_" + uncertainty + shift, "uncertainties")
                    plot.setGraphStyle("total_" + uncertainty + shift,
                                       "hist",
                                       linecolor=4 + index,
                                       linewidth=3)

            plot.subplot(0).setGraphStyle("ggH",
                                          "hist",
                                          linecolor=styles.color_dict["ggH"],
                                          linewidth=3)
            plot.subplot(0).setGraphStyle("ggH_top", "hist", linecolor=0)
            plot.subplot(0).setGraphStyle("qqH",
                                          "hist",
                                          linecolor=styles.color_dict["qqH"],
                                          linewidth=3)
            plot.subplot(0).setGraphStyle("qqH_top", "hist", linecolor=0)
            plot.setGraphStyle("total_bkg",
                               "e2",
                               markersize=0,
                               fillcolor=styles.color_dict["unc"],
                               linecolor=0,
                               fillstyle=3001 if args.png else 1001)

            bkg_ggH = plot.subplot(1).get_hist("ggH")
            bkg_qqH = plot.subplot(1).get_hist("qqH")
            bkg_ggH.Add(plot.subplot(1).get_hist("total_bkg"))
            bkg_qqH.Add(plot.subplot(1).get_hist("total_bkg"))
            plot.subplot(1).add_hist(bkg_ggH, "bkg_ggH")
            plot.subplot(1).add_hist(bkg_ggH, "bkg_ggH_top")
            plot.subplot(1).add_hist(bkg_qqH, "bkg_qqH")
            plot.subplot(1).add_hist(bkg_qqH, "bkg_qqH_top")
            plot.subplot(1).setGraphStyle("bkg_ggH",
                                          "hist",
                                          linecolor=styles.color_dict["ggH"],
                                          linewidth=3)
            plot.subplot(1).setGraphStyle("bkg_ggH_top", "hist", linecolor=0)
            plot.subplot(1).setGraphStyle("bkg_qqH",
                                          "hist",
                                          linecolor=styles.color_dict["qqH"],
                                          linewidth=3)
            plot.subplot(1).setGraphStyle("bkg_qqH_top", "hist", linecolor=0)

            plot.subplot(1).normalize([
                "total_bkg", "bkg_ggH", "bkg_ggH_top", "bkg_qqH",
                "bkg_qqH_top", "data_obs", "uncertainties"
            ], "total_bkg")

            plot.create_stack(bkg_processes, "stack")

            plot.subplot(0).setYlims(
                0, 1.7 * plot.subplot(0).get_hist("total_bkg").GetMaximum())
            plot.subplot(1).setYlims(0.85, 1.35)
            if channel == "tt" and category == "qqh":
                plot.subplot(1).setYlims(0.75, 2.15)
            plot.subplot(1).setXlabel(args.x_label)
            plot.subplot(0).setYlabel("N_{events}")
            plot.subplot(1).setYlabel("Ratio to Bkg.")

            #plot.scaleXTitleSize(0.8)
            #plot.scaleXLabelSize(0.8)
            #plot.scaleYTitleSize(0.8)
            plot.scaleYLabelSize(0.8)
            #plot.scaleXLabelOffset(2.0)
            plot.scaleYTitleOffset(1.1)

            #plot.subplot(1).setNYdivisions(3, 5)

            # draw subplots. Argument contains names of objects to be drawn in corresponding order.
            plot.subplot(0).Draw([
                "stack", "total_bkg", "uncertainties", "ggH", "ggH_top", "qqH",
                "qqH_top", "data_obs"
            ])
            plot.subplot(1).Draw([
                "total_bkg", "uncertainties", "bkg_ggH", "bkg_ggH_top",
                "bkg_qqH", "bkg_qqH_top", "data_obs"
            ])

            # create legends
            suffix = ["", "_top"]
            for i in range(2):
                plot.add_legend(width=0.48, height=0.15)
                for process in legend_bkg_processes:
                    plot.legend(i).add_entry(
                        0, process,
                        styles.label_dict[process.replace("EWK", "EWKZ")], 'f')
                plot.legend(i).add_entry(0, "total_bkg", "Bkg. unc.", 'f')
                plot.legend(i).add_entry(0, "ggH%s" % suffix[i], "ggH", 'l')
                plot.legend(i).add_entry(0, "qqH%s" % suffix[i], "qqH", 'l')
                plot.legend(i).add_entry(0, "data_obs", "Data", 'PE')
                for uncertainty in args.uncertainties:
                    plot.legend(i).add_entry(
                        1, "total_" + uncertainty + "Up",
                        uncertainty.replace("CMS_htt_", ""), 'l')
                plot.legend(i).setNColumns(3)
            plot.legend(0).Draw()
            plot.legend(1).setAlpha(0.0)
            plot.legend(1).Draw()

            for i in range(2):
                plot.add_legend(reference_subplot=1,
                                pos=1,
                                width=0.5,
                                height=0.06)
                plot.legend(i + 2).add_entry(0, "data_obs", "Data", 'PE')
                plot.legend(i + 2).add_entry(0, "ggH%s" % suffix[i],
                                             "ggH+bkg.", 'l')
                plot.legend(i + 2).add_entry(0, "qqH%s" % suffix[i],
                                             "qqH+bkg.", 'l')
                plot.legend(i + 2).add_entry(0, "total_bkg", "Bkg. unc.", 'f')
                for uncertainty in args.uncertainties:
                    plot.legend(i + 2).add_entry(
                        1, "total_" + uncertainty + "Up",
                        uncertainty.replace("CMS_htt_", ""), 'l')
                plot.legend(i + 2).setNColumns(4)
            plot.legend(2).Draw()
            plot.legend(3).setAlpha(0.0)
            plot.legend(3).Draw()

            # draw additional labels
            plot.DrawCMS()
            plot.DrawLumi("35.9 fb^{-1} (13 TeV)")
            plot.DrawChannelCategoryLabel(
                "%s, %s" % (channel_dict[channel], category_dict[category]))

            # save plot
            plot.save("plots/unc_%s_%s.%s" %
                      (channel, category, 'png' if args.png else 'pdf'))
            plots.append(
                plot
            )  # work around to have clean up seg faults only at the end of the script
Пример #11
0
def main(args):
    channel_categories = {
        "et": ["0jet", "boosted", "vbf"],
        "mt": ["0jet", "boosted", "vbf"],
        "tt": ["0jet", "boosted", "vbf"]
    }
    channel_dict = {
        "ee": "ee",
        "em": "e#mu",
        "et": "e#tau_{h}",
        "mm": "#mu#mu",
        "mt": "#mu#tau_{h}",
        "tt": "#tau_{h}#tau_{h}"
    }
    category_dict = {"0jet": "0 Jet", "boosted": "Boosted", "vbf": "VBF"}

    bkg_processes = ["EWK", "QCD", "VV", "W", "TTT", "TTJ", "ZJ", "ZL", "ZTT"]
    sig_processes = ["ggH", "qqH"]
    legend_bkg_processes = copy.deepcopy(bkg_processes)
    legend_bkg_processes.reverse()

    rootfile = rootfile_parser.Rootfile_parser(args.input)

    plots = []

    for channel in args.channels:
        for category in channel_categories[channel]:
            plot = dd.Plot([],
                           "ModTDR",
                           r=0.04,
                           l=0.14,
                           width=1200,
                           height=600)

            for process in bkg_processes:
                plot.add_hist(rootfile.get(channel, category, process),
                              process)
                plot.setGraphStyle(process,
                                   "hist",
                                   fillcolor=styles.color_dict[process])

            for process in sig_processes:
                plot.add_hist(rootfile.get(channel, category, process),
                              process)
                plot.setGraphStyle(process,
                                   "hist",
                                   fillcolor=styles.color_dict[process])
                plot.add_hist(rootfile.get(channel, category, process),
                              process + "_line")
                plot.setGraphStyle(process + "_line",
                                   "hist",
                                   linecolor=styles.color_dict[process],
                                   linewidth=3)

            plot.add_hist(rootfile.get(channel, category, "data_obs"),
                          "data_obs")
            plot.setGraphStyle("data_obs", "e0")

            plot.add_hist(rootfile.get(channel, category, "TotalBkg"),
                          "total_bkg")
            plot.setGraphStyle("total_bkg",
                               "e2",
                               markersize=0,
                               fillcolor=styles.color_dict["unc"],
                               linecolor=0,
                               fillstyle=3001 if args.png else 1001)

            plot.create_stack(bkg_processes + sig_processes, "stack")

            plot.subplot(0).setYlims(
                0.1, 10 * plot.subplot(0).get_hist("total_bkg").GetMaximum())
            plot.subplot(0).setXlabel(args.x_label)
            plot.subplot(0).setYlabel("N_{events}")
            plot.subplot(0).setLogY()
            plot.subplot(0).Draw(
                ["stack", "qqH_line", "ggH_line", "total_bkg", "data_obs"])

            plot.DrawCMS()
            plot.DrawLumi("35.9 fb^{-1} (13 TeV)")
            plot.DrawChannelCategoryLabel(
                "%s, %s" % (channel_dict[channel], category_dict[category]))

            prefix = "prefit" if "prefit" in args.input else "postfit" if "postfit" in args.input else "undefined"
            plot.save(
                "plots/%s_%s_%s.%s" %
                (prefix, channel, category, 'png' if args.png else 'pdf'))
            plots.append(
                plot
            )  # work around to have clean up seg faults only at the end of the script
def main(args):
    if args.control_variable is None:
        channel_categories = {
            #"et": ["nobtag_tight", "btag_tight", "nobtag_loosemt", "nobtag_tight"]
            "et": ["10", "11", "12", "13", "14", "15", "16", "17", "18", "32", "33",  "35", "36"],
            #"mt": ["nobtag_tight", "btag_tight", "nobtag_loosemt", "nobtag_tight"]
            "mt": ["10", "11", "12", "13", "14", "15", "16", "17", "18", "32", "33",  "35", "36"],
            #"tt": ["nobtag", "btag"]
            "tt": ["10", "11", "12", "13", "14", "15", "16", "17", "32", "35"],
            "em": ["2", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "32", "33", "34", "35", "36", "37"]
        }
        if args.model_independent:
            channel_categories = {
                #"et": ["nobtag_tight", "btag_tight", "nobtag_loosemt", "nobtag_tight"]
                "et": ["32", "33",  "35", "36"],
                #"mt": ["nobtag_tight", "btag_tight", "nobtag_loosemt", "nobtag_tight"]
                "mt": ["32", "33",  "35", "36"],
                #"tt": ["nobtag", "btag"]
                "tt": ["32", "35"],
                "em": ["2","32", "33", "34", "35", "36", "37"]
            }
            channel_categories = {
                "et": ["32", "35"],
                "mt": ["32", "35"],
                "tt": ["32", "35"],
                # "em": ["32", "33", "35", "36"],
                "em": ["33", "36"],
                "lt": ["32", "35"],
            }
    else:
        channel_categories = {
            "et": ["100"],
            "mt": ["100"],
            "tt": ["100"],
            "em": ["100"]
        }
    channel_dict = {
        "ee": "ee",
        "em": "e#mu",
        "et": "e#tau_{h}",
        "mm": "#mu#mu",
        "mt": "#mu#tau_{h}",
        "lt": "#mu_{}#tau_{h}+e_{}#tau_{h}",
        # "lt": "#ell#tau_{h}",
        "tt": "#tau_{h}#tau_{h}"
    }
    if args.control_variable != None:
        category_dict = {"100": "inclusive"}
    else:
        category_dict = {
            "et": {
                "1": "2D ggH/qqH category",
                "13": "tt",
                "15": "zll",
                "16": "misc",
                "20": "Genuine #tau",
                "21": "Jet #rightarrow #tau_{h}",
                "32": "No b tag Tight-m_{T}",
                "33": "No b tag Loose-m_{T}",
                "35": "b tag Tight-m_{T}",
                "36": "b tag Loose-m_{T}",
                },
            "mt": {
                "1": "2D ggH/qqH category",
                "13": "tt",
                "15": "zll",
                "16": "misc",
                "20": "Genuine #tau",
                "21": "Jet #rightarrow #tau_{h}",
                "32": "No b tag Tight-m_{T}",
                "33": "No b tag Loose-m_{T}",
                "35": "b tag Tight-m_{T}",
                "36": "b tag Loose-m_{T}",
                },
            "lt": {
                "1": "2D ggH/qqH category",
                "13": "tt",
                "15": "zll",
                "16": "misc",
                "20": "Genuine #tau",
                "21": "Jet #rightarrow #tau_{h}",
                "32": "No b tag Tight-m_{T}",
                "33": "No b tag Loose-m_{T}",
                "35": "b tag Tight-m_{T}",
                "36": "b tag Loose-m_{T}",
                },
            "tt": {
                "1": "2D ggH/qqH category",
                "16": "misc",
                "20": "Genuine #tau",
                "21": "Jet #rightarrow #tau_{h}",
                "32": "No b tag",
                "35": "b tag",
                },
            "em": {
                "1": "2D ggH/qqH category",
                "2": "D_{#lower[-0.2]{#zeta}} < -35 GeV",
                "13": "tt",
                "14": "qcd",
                "16": "misc",
                "19": "diboson",
                "20": "Genuine #tau",
                "32": "No b tag, High-D_{#lower[-0.2]{#zeta}}",
                "33": "No b tag, Medium-D_{#lower[-0.2]{#zeta}}",
                "34": "No b tag, Low-D_{#lower[-0.2]{#zeta}}",
                "35": "b tag, High-D_{#lower[-0.2]{#zeta}}",
                "36": "b tag, Medium-D_{#lower[-0.2]{#zeta}}",
                "37": "b tag, Low-D_{#lower[-0.2]{#zeta}}",
                },

        }
    if args.linear == True:
        split_value = 0
    else:
        if args.normalize_by_bin_width:
            split_value = 1
        else:
            split_value = 101

    split_dict = {c: split_value for c in ["et", "mt", "tt", "em", "lt"]}

    bkg_processes = [
        "HSM", "VVL", "TTL", "ZL", "jetFakes", "EMB"
    ]
    if args.combine_backgrounds:
        bkg_processes = [
            "other", "TTL", "jetFakes", "EMB"
        ]
    if not args.fake_factor and args.embedding:
        bkg_processes = [
            "QCD", "VVJ", "VVL", "W", "TTJ", "TTL", "ZJ", "ZL", "EMB"
        ]
    if not args.embedding and args.fake_factor:
        bkg_processes = [
            "VVT", "VVJ", "TTT", "TTJ", "ZJ", "ZL", "jetFakes", "ZTT"
        ]
    if not args.embedding and not args.fake_factor:
        bkg_processes = [
            "QCD", "W", "VVJ", "VVL", "VVT", "TTJ", "TTL", "TTT", "ZJ", "ZL", "ZTT"
#            "QCD", "VVT", "VVJ", "W", "TTT", "TTJ", "ZJ", "ZL", "ZTT"
        ]
    all_bkg_processes = [b for b in bkg_processes]
    legend_bkg_processes = copy.deepcopy(bkg_processes)
    legend_bkg_processes.reverse()

    if "2016" in args.era:
        era = "_2016"
    elif "2017" in args.era:
        era = "_2017"
    elif "2018" in args.era:
        era = "_2018"
    elif "combined" in args.era:
        era = ""
    else:
        logger.critical("Era {} is not implemented.".format(args.era))
        raise Exception

    plots = []
    for channel in args.channels:
        if "em" in channel:
            if not args.embedding:
                bkg_processes = [
                    "HSM", "QCDMC", "VVT", "VVL", "W", "TTT", "TTL", "ZL", "ZTT"
                ]
            else:
                bkg_processes = [
                    "HSM", "QCD", "EWK", "TTL", "ZL", "EMB"
                ]
                if args.combine_backgrounds:
                    bkg_processes = [
                        "other", "QCD", "TTL", "EMB"
                    ]

        for category in channel_categories[channel]:
            # Set split value to 101 for no b-tag categories to make
            # transition between scales smoother
            if int(category) < 35 and int(category) > 10:
                split_dict[channel] += 100
            if args.control_region and category != "2":
                continue
            rootfile = rootfile_parser.Rootfile_parser(args.input, mode="CombineHarvesterMerged")
            legend_bkg_processes = copy.deepcopy(bkg_processes)
            legend_bkg_processes.reverse()
            # create plot
            if args.linear == True:
                plot = dd.Plot(
                    [0.3, [0.3, 0.28]], "ModTDR", r=0.04, l=0.14, width=600)
            else:
                plot = dd.Plot(
                    [0.55, [0.3, 0.28]], style="ModTDR", invert_pad_creation=True, r=0.04, l=0.14, width=600)

            # get background histograms
            for process in bkg_processes:
                if process in ["jetFakes", "jetFakesEMB"] and channel == "tt":
                    jetfakes_hist = rebin_hist_for_logX(rootfile.get(era, channel, category, process).Clone(), xlow=30.)
                    jetfakes_hist.Add(rebin_hist_for_logX(rootfile.get(era, channel, category, "wFakes"), xlow=30.))
                    plot.add_hist(jetfakes_hist, process, "bkg")
                elif process in ["HSM"]:
                    if channel == "em":
                        hsm_hist = rebin_hist_for_logX(rootfile.get(era, channel, category, "ggH125").Clone(), xlow=30.)
                        hsm_hist.Add(rebin_hist_for_logX(rootfile.get(era, channel, category, "qqH125"), xlow=30.))
                        hsm_hist.Add(rebin_hist_for_logX(rootfile.get(era, channel, category, "bbH125"), xlow=30.))
                        hsm_hist.Add(rebin_hist_for_logX(rootfile.get(era, channel, category, "ggHWW125"), xlow=30.))
                        hsm_hist.Add(rebin_hist_for_logX(rootfile.get(era, channel, category, "qqHWW125"), xlow=30.))
                        hsm_hist.Add(rebin_hist_for_logX(rootfile.get(era, channel, category, "ZHWW125"), xlow=30.))
                        hsm_hist.Add(rebin_hist_for_logX(rootfile.get(era, channel, category, "WHWW125"), xlow=30.))
                        plot.add_hist(hsm_hist, process, "bkg")
                    else:
                        hsm_hist = rebin_hist_for_logX(rootfile.get(era, channel, category, "ggH125").Clone(), xlow=30.)
                        hsm_hist.Add(rebin_hist_for_logX(rootfile.get(era, channel, category, "qqH125"), xlow=30.))
                        hsm_hist.Add(rebin_hist_for_logX(rootfile.get(era, channel, category, "bbH125"), xlow=30.))
                        plot.add_hist(hsm_hist, process, "bkg")
                elif process == "EWK" and channel == "em":
                    ewk_hist = rebin_hist_for_logX(rootfile.get(era, channel, category, "W").Clone(), xlow=30.)
                    ewk_hist.Add(rebin_hist_for_logX(rootfile.get(era, channel, category, "VVL"), xlow=30.))
                    plot.add_hist(ewk_hist, process, "bkg")
                elif process in ["HWW"]:
                    hww_hist = rebin_hist_for_logX(rootfile.get(era, channel, category, "ggHWW125").Clone(), xlow=30.)
                    hww_hist.Add(rebin_hist_for_logX(rootfile.get(era, channel, category, "qqHWW125"), xlow=30.))
                    hww_hist.Add(rebin_hist_for_logX(rootfile.get(era, channel, category, "ZHWW125"), xlow=30.))
                    hww_hist.Add(rebin_hist_for_logX(rootfile.get(era, channel, category, "WHWW125"), xlow=30.))
                    plot.add_hist(hww_hist, process, "bkg")
                elif process == "other":
                    if channel == "em":
                        other_hist = rebin_hist_for_logX(rootfile.get(era, channel, category, "W").Clone(), xlow=30.)
                        other_hist.Add(rebin_hist_for_logX(rootfile.get(era, channel, category, "VVL"), xlow=30.))
                        other_hist.Add(rebin_hist_for_logX(rootfile.get(era, channel, category, "ZL"), xlow=30.))
                        other_hist.Add(rebin_hist_for_logX(rootfile.get(era, channel, category, "ggH125"), xlow=30.))
                        other_hist.Add(rebin_hist_for_logX(rootfile.get(era, channel, category, "qqH125"), xlow=30.))
                        other_hist.Add(rebin_hist_for_logX(rootfile.get(era, channel, category, "bbH125"), xlow=30.))
                        other_hist.Add(rebin_hist_for_logX(rootfile.get(era, channel, category, "ggHWW125"), xlow=30.))
                        other_hist.Add(rebin_hist_for_logX(rootfile.get(era, channel, category, "qqHWW125"), xlow=30.))
                        other_hist.Add(rebin_hist_for_logX(rootfile.get(era, channel, category, "ZHWW125"), xlow=30.))
                        other_hist.Add(rebin_hist_for_logX(rootfile.get(era, channel, category, "WHWW125"), xlow=30.))
                        plot.add_hist(other_hist, process, "bkg")
                    elif channel in ["et", "mt", "lt", "tt"]:
                        other_hist = rebin_hist_for_logX(rootfile.get(era, channel, category, "VVL").Clone(), xlow=30.)
                        other_hist.Add(rebin_hist_for_logX(rootfile.get(era, channel, category, "ZL"), xlow=30.))
                        other_hist.Add(rebin_hist_for_logX(rootfile.get(era, channel, category, "ggH125"), xlow=30.))
                        other_hist.Add(rebin_hist_for_logX(rootfile.get(era, channel, category, "qqH125"), xlow=30.))
                        other_hist.Add(rebin_hist_for_logX(rootfile.get(era, channel, category, "bbH125"), xlow=30.))
                        plot.add_hist(other_hist, process, "bkg")
                else:
                    #print era, channel, category, process
                    plot.add_hist(
                        rebin_hist_for_logX(rootfile.get(era, channel, category, process), xlow=30.), process, "bkg")
                plot.setGraphStyle(
                    process, "hist", fillcolor=styles.color_dict[process])

            # get signal histograms
            if int(category) > 30:
                plot_idx_to_add_signal = [0,2] if args.linear else [1,2]
                for i in plot_idx_to_add_signal:
                    if args.model_independent:
                        ggH_hist = rebin_hist_for_logX(rootfile.get(era, channel, category, "ggh_t"), xlow=30.).Clone()
                        ggH_hist.Add(rebin_hist_for_logX(rootfile.get(era, channel, category, "ggh_i"), xlow=30.))
                        ggH_hist.Add(rebin_hist_for_logX(rootfile.get(era, channel, category, "ggh_b"), xlow=30.))
                        plot.subplot(i).add_hist(ggH_hist, "ggH")
                        # bbH signal
                        bbH_hist = rebin_hist_for_logX(rootfile.get(era, channel, category, "bbh"), xlow=30.)
                        # if args.cross_section_bbh != args.cross_section_ggh:
                        #     print("Scaling bbH by {}".format(float(args.cross_section_bbh)/float(args.cross_section_ggh)))
                        #     bbH_hist.Scale(float(args.cross_section_bbh)/float(args.cross_section_ggh))
                        if args.cross_section_bbh != args.cross_section_ggh:
                            print("Scaling bbH by {}".format(float(args.cross_section_bbh)/0.0030584))
                            bbH_hist.Scale(float(args.cross_section_bbh)/0.0030584)
                        plot.subplot(i).add_hist(bbH_hist, "bbH")
                        # vector leptoquark signal
                        VLQ_hist = rebin_hist_for_logX(rootfile.get(era, channel, category, "VLQ_s"), xlow=30.).Clone()
                        VLQ_hist.Add(rebin_hist_for_logX(rootfile.get(era, channel, category, "VLQ_i"), xlow=30.))
                        plot.subplot(i).add_hist(
                            VLQ_hist, "VLQ")
                    else:
                        plot.subplot(i).add_hist(
                            rebin_hist_for_logX(rootfile.get(era, channel, category, "TotalSig"), xlow=30.), "mssm_sig")

            # get observed data and total background histograms
            plot.add_hist(
                rebin_hist_for_logX(rootfile.get(era, channel, category, "data_obs"), xlow=30.), "data_obs")
            plot.add_hist(
                rebin_hist_for_logX(rootfile.get(era, channel, category, "TotalBkg"), xlow=30.), "total_bkg")

            plot.subplot(0).setGraphStyle("data_obs", "e0")
            if args.model_independent:
                if int(category) > 30:
                    plot.subplot(0 if args.linear else 1).setGraphStyle(
                        "ggH", "hist", linecolor=styles.color_dict["ggH"], linewidth=2)
                    plot.subplot(0 if args.linear else 1).setGraphStyle(
                        "bbH", "hist", linecolor=styles.color_dict["bbH"], linewidth=2)
                    plot.subplot(0 if args.linear else 1).setGraphStyle(
                        "VLQ", "hist", linecolor=styles.color_dict["VLQ"], linewidth=2)
            else:
                plot.subplot(0 if args.linear else 1).setGraphStyle(
                    "mssm_sig", "hist", linecolor=styles.color_dict["bbH"], linewidth=2)
            plot.setGraphStyle(
                "total_bkg",
                "e2",
                markersize=0,
                fillcolor=styles.color_dict["unc"],
                linecolor=0)

            # assemble ratio
            if args.model_independent:
                if args.b_only_fit is not None:
                    rootfile_b_only = rootfile_parser.Rootfile_parser(args.b_only_fit, mode="CombineHarvesterMerged")
                    plot.subplot(2).add_hist(
                        rebin_hist_for_logX(rootfile_b_only.get(era, channel, category, "TotalBkg"), xlow=30.), "total_bkg_b_only")
                    plot.subplot(2).setGraphStyle(
                        "total_bkg_b_only", "hist", linecolor=ROOT.kBlue,
                        linewidth=2, linestyle=2)
                if int(category) > 30:
                    bkg_ggH = plot.subplot(2).get_hist("ggH")
                    bkg_bbH = plot.subplot(2).get_hist("bbH")
                    bkg_VLQ = plot.subplot(2).get_hist("VLQ")
                    bkg_ggH.Add(plot.subplot(2).get_hist("total_bkg"))
                    bkg_bbH.Add(plot.subplot(2).get_hist("total_bkg"))
                    bkg_VLQ.Add(plot.subplot(2).get_hist("total_bkg"))
                    plot.subplot(2).add_hist(bkg_ggH, "bkg_ggH")
                    plot.subplot(2).add_hist(bkg_bbH, "bkg_bbH")
                    plot.subplot(2).add_hist(bkg_VLQ, "bkg_VLQ")
                    plot.subplot(2).setGraphStyle(
                        "bkg_ggH",
                        "hist",
                        linecolor=styles.color_dict["ggH"],
                        linewidth=2)
                    plot.subplot(2).setGraphStyle(
                        "bkg_bbH",
                        "hist",
                        linecolor=styles.color_dict["bbH"],
                        linewidth=2)
                    plot.subplot(2).setGraphStyle(
                        "bkg_VLQ",
                        "hist",
                        linecolor=styles.color_dict["VLQ"],
                        linewidth=2)
                    to_normalize = ["total_bkg", "bkg_ggH", "bkg_bbH", "bkg_VLQ",
                        "data_obs"
                    ]
                    if args.b_only_fit is not None:
                        to_normalize.append("total_bkg_b_only")
                    plot.subplot(2).normalize(to_normalize, "total_bkg")
                else:
                    to_normalize = ["total_bkg", "data_obs" ]
                    if args.b_only_fit is not None:
                        to_normalize.append("total_bkg_b_only")
                    plot.subplot(2).normalize(to_normalize, "total_bkg")
            else:
                bkg_sig = plot.subplot(2).get_hist("mssm_sig")
                bkg_sig.Add(plot.subplot(2).get_hist("total_bkg"))
                plot.subplot(2).add_hist(bkg_sig, "bkg_mssm_sig")
                plot.subplot(2).add_hist(bkg_sig, "bkg_mssm_sig_top")
                plot.subplot(2).setGraphStyle(
                    "bkg_mssm_sig",
                    "hist",
                    linecolor=styles.color_dict["bbH"],
                    linewidth=3)
                plot.subplot(2).setGraphStyle(
                    "bkg_mssm_sig_top",
                    "hist",
                    linecolor=0)
                plot.subplot(2).normalize([
                    "total_bkg", "bkg_mssm_sig", "bkg_mssm_sig_top",
                    "data_obs"
                ], "total_bkg")

            # stack background processes
            plot.create_stack(bkg_processes, "stack")

            # Use binning from data histogram to get bin widths for the normalization.
            hist_for_rebinning = rootfile.get(era, channel, category, "data_obs")
            widths = []
            for i in range(hist_for_rebinning.GetNbinsX()):
                widths.append(hist_for_rebinning.GetBinWidth(i+1))
            # normalize stacks by bin-width
            if args.normalize_by_bin_width:
                plot.subplot(0).normalizeByBinWidth(widths=widths)
                plot.subplot(1).normalizeByBinWidth(widths=widths)

            if args.x_range is not None:
                for i in range(3):
                    plot.subplot(i).setXlims(*args.x_range)

            # set axes limits and labels
            if args.x_range is not None:
                range_hist = plot.subplot(0).get_hist("data_obs").Clone()
                range_hist.GetXaxis().SetRangeUser(*args.x_range)
                plot.subplot(0).setYlims(
                    split_dict[channel],
                    max(1.8 * range_hist.GetMaximum(),
                        split_dict[channel] * 2))
                    # max(1,
                    #     split_dict[channel] * 2))
            else:
                plot.subplot(0).setYlims(
                    split_dict[channel],
                    max(1.4 * plot.subplot(0).get_hist("data_obs").GetMaximum(),
                        split_dict[channel] * 2))

            if channel == "em":
                if int(category) == 36:
                    plot.subplot(2).setYlims(0.2, 2.5)
                else:
                    plot.subplot(2).setYlims(0.5, 2.0)
            elif channel == "tt":
                plot.subplot(2).setYlims(0.7, 2.5)
            else:
                if int(category) == 35:
                    plot.subplot(2).setYlims(0.5, 2.2)
                else:
                    plot.subplot(2).setYlims(0.7, 2.2)

            ROOT.TGaxis.SetMaxDigits(4)

            if args.linear != True:
                # plot.subplot(1).setYlims(1.e-4, split_dict[channel])
                plot.subplot(1).setYlims(min(1.e-3, plot.subplot(1).get_hist("data_obs").GetMinimum()/10., plot.subplot(1).get_hist("total_bkg").GetMinimum()/10.), split_dict[channel])
                plot.subplot(1).setLogY()
                if int(category) > 30 or int(category) == 2:
                    plot.subplot(1).setLogX()
                plot.subplot(1).setYlabel(
                    "")  # otherwise number labels are not drawn on axis
            if args.control_variable != None:
                if args.control_variable in styles.x_label_dict[args.channels[0]]:
                    x_label = styles.x_label_dict[args.channels[0]][
                        args.control_variable]
                else:
                    x_label = args.control_variable
                plot.subplot(2).setXlabel(x_label)
            else:
                if int(category) > 30 or int(category) == 2:
                    plot.subplot(2).setXlabel("m_{T}^{tot} (GeV)")
                else:
                    plot.subplot(2).setXlabel("SVFit m_{#tau#tau} (GeV)")
            if args.normalize_by_bin_width:
                if int(category) > 30 or int(category) == 2:
                    plot.subplot(0).setYlabel("dN/dm_{T}^{tot} (1/GeV)")
                    # plot.subplot(0).setYlabel("< Events / GeV >")
                else:
                    plot.subplot(0).setYlabel("dN/dm_{#tau#tau} (1/GeV)")
            else:
                plot.subplot(0).setYlabel("Events / {} GeV".format(plot.subplot(0).get_hist("total_bkg").GetBinWidth(1)))

            plot.subplot(2).setYlabel("Obs./Exp.")


            if (int(category) > 30 or int(category) == 2) and args.x_range is None:
                plot.subplot(0).setLogX()
                plot.subplot(2).setLogX()

            #plot.scaleXTitleSize(0.8)
            #plot.scaleXLabelSize(0.8)
            #plot.scaleYTitleSize(0.8)
            plot.scaleYLabelSize(0.8)
            #plot.scaleXLabelOffset(2.0)

            plot.scaleYTitleOffset(1.05)

            if channel == "em":
                if category == "32":
                    plot.subplot(0).setNYdivisions(3, 5)
                elif category == "33":
                    plot.subplot(0).setNYdivisions(4, 5)
            if int(category) < 35 and int(category) > 10:
                plot.subplot(1).setNYdivisions(3, 5)
            plot.subplot(2).setNYdivisions(3, 5)

            # draw subplots. Argument contains names of objects to be drawn in corresponding order.
            # procs_to_draw = ["stack", "total_bkg", "ggH", "ggH_top", "bbH", "bbH_top", "data_obs"] if args.linear else ["stack", "total_bkg", "data_obs"]
            if category == "2":
                procs_to_draw = ["stack", "total_bkg", "data_obs"] if args.linear else ["stack", "total_bkg", "data_obs"]
            else:
                if args.model_independent:
                    procs_to_draw = ["stack", "total_bkg", "ggH", "bbH", "data_obs"] if args.linear else ["stack", "total_bkg", "data_obs"]
                else:
                    procs_to_draw = ["stack", "total_bkg", "mssm_sig", "data_obs"] if args.linear else ["stack", "total_bkg", "data_obs"]
                if args.blinded:
                    procs_to_draw.remove("data_obs")
            plot.subplot(0).Draw(procs_to_draw)
            if not args.linear:
                # plot.subplot(1).Draw([
                #     "stack", "total_bkg", "ggH", "bbH",
                #     "ggH_top", "bbH_top",
                #     "data_obs"
                # ])
                if category == "2":
                    plot.subplot(1).Draw([
                        "stack", "total_bkg",
                        "data_obs"
                    ])
                else:
                    if args.model_independent:
                        procs_to_draw = ["stack", "total_bkg", "ggH", "bbH", "VLQ", "data_obs"]
                    else:
                        procs_to_draw = ["stack", "total_bkg", "mssm_sig", "data_obs"]
                    if args.blinded:
                        procs_to_draw.remove("data_obs")
                    plot.subplot(1).Draw(procs_to_draw)

                plot.subplot(0).remove_lower_x_ticks()
                plot.subplot(1)._pad.SetTickx(0)
                plot.add_line(0, 30, split_dict[channel], 6000, split_dict[channel], linestyle=1, color=ROOT.kGray+2)
                for line in plot._lines:
                    line.Draw()
                label2 = ROOT.TLatex()
                label2.SetNDC()
                label2.SetTextAngle(270)
                label2.SetTextColor(ROOT.kGray+2)
                label2.SetTextSize(0.030)
                label2.DrawLatex(0.97, 0.54, "log scale")
                label2.DrawLatex(0.97, 0.75, "linear scale")
                # Redraw upper x axis to have good looking plot
                plot.subplot(0)._pad.cd()
                y_max = 1.4 * plot.subplot(0).get_hist("data_obs").GetMaximum()
                axis = ROOT.TGaxis(30., y_max, 5000., y_max, 30., 5000., 510, "GBSU-")
                axis.SetTickLength(0.02)
                axis.SetTickSize(0.02)
                axis.Draw()

            # Draw upper panel after lower panel of split to ensure full
            # display of the data points
            if category == "2":
                plot.subplot(2).Draw([
                    "total_bkg",
                    "data_obs"
                ])
            else:
                if args.model_independent:
                    if args.b_only_fit is not None:
                        if int(category) > 30:
                            procs_to_draw = ["total_bkg_b_only", "total_bkg", "bkg_ggH", "bkg_bbH", "bkg_VLQ", "data_obs"]
                        else:
                            procs_to_draw = ["total_bkg_b_only", "total_bkg", "data_obs"]
                    else:
                        if int(category) > 30:
                            procs_to_draw = ["total_bkg", "bkg_ggH", "bkg_bbH", "bkg_VLQ", "data_obs"]
                        else:
                            procs_to_draw = ["total_bkg", "data_obs"]
                else:
                    procs_to_draw = ["total_bkg", "bkg_mssm_sig", "data_obs"]
                if args.blinded:
                    procs_to_draw.remove("data_obs")
                plot.subplot(2).Draw(procs_to_draw)

            # create legends
            if int(category) < 30 and int(category) > 2:
                plot.add_legend(width=0.38, height=0.30)
            else:
                # plot.add_legend(width=0.60, height=0.20, pos=1)
                plot.add_legend(width=0.40, height=0.33, pos=3)
            # plot.add_legend(width=0.6, height=0.15)
            for process in legend_bkg_processes:
                if process == "HSM" and channel == "em":
                    plot.legend(0).add_entry(
                        0, process, "H(125 GeV)", "f")
                else:
                    plot.legend(0).add_entry(
                        0, process, styles.legend_label_dict[process.replace("TTL", "TT").replace("VVL", "VV")], 'f')
            if not args.blinded:
                plot.legend(0).add_entry(0, "data_obs", "Observed", 'PE')
            plot.legend(0).add_entry(0, "total_bkg", "Bkg. unc.", 'f')
            if args.control_region and category == "2":
                pass
            else:
                if args.model_independent:
                    if int(category) > 30:
                        mass_str = "%s GeV" % args.mass if float(args.mass) < 1000 else "{:.1f} TeV".format(float(args.mass) / 1000)
                        ggH_xs_str = "%s pb" % args.cross_section_ggh if float(args.cross_section_ggh) > 1e-2 else "{} fb".format(float(args.cross_section_ggh) * 1000)
                        bbH_xs_str = "%s pb" % args.cross_section_bbh if float(args.cross_section_bbh) > 1e-2 else "{} fb".format(float(args.cross_section_bbh) * 1000)
                        plot.legend(0).add_entry(0 if args.linear else 1, "ggH", "#splitline{gg#phi @ %s}{(m_{#phi} = %s)}" % (ggH_xs_str, mass_str), 'l')
                        plot.legend(0).add_entry(0 if args.linear else 1, "bbH", "#splitline{bb#phi @ %s}{(m_{#phi} = %s)}" % (bbH_xs_str, mass_str), 'l')
                        plot.legend(0).add_entry(0 if args.linear else 1, "", "", '')
                        plot.legend(0).add_entry(0 if args.linear else 1, "VLQ", "#splitline{VLQ, g_{U} = %s}{(m_{U} = %s TeV)}" % (1.2, 1), 'l')
                else:
                    plot.legend(0).add_entry(0 if args.linear else 1, "mssm_sig", "#splitline{H #rightarrow #tau#tau}{#splitline{(m_{A}= %s GeV,}{ tan #beta = %s)}}" %(args.mass, args.tanbeta), 'l')
            plot.legend(0).setNColumns(2)
            # plot.legend(0).scaleTextSize(1.05)
            plot.legend(0).Draw()


            # FIXME: Legend for ratio plot temporarily disabled.
            if channel != "em":
                plot.add_legend(
                    reference_subplot=2, pos=1, width=0.45, height=0.10)
            else:
                plot.add_legend(
                    reference_subplot=2, pos=1, width=0.75, height=0.05)
                if not args.blinded:
                    plot.legend(1).add_entry(0, "data_obs", "Observed", 'PE')
                plot.legend(1).add_entry(0, "total_bkg", "Bkg. unc.", 'f')
                if args.b_only_fit:
                    plot.legend(1).add_entry(2, "total_bkg_b_only", "Bkg. only fit", "l")
            if args.control_region and category == "2":
                pass
            else:
                if args.model_independent:
                    if int(category) > 30:
                        plot.legend(1).add_entry(0 if args.linear else 1, "ggH",
                                             "gg#phi", 'l')
                        plot.legend(1).add_entry(0 if args.linear else 1, "bbH",
                                             "bb#phi", 'l')
                        plot.legend(1).add_entry(0 if args.linear else 1, "VLQ",
                                             "VLQ", 'l')
                else:
                    plot.legend(1).add_entry(0 if args.linear else 1, "mssm_sig",
                                                 "H+bkg.", 'l')
            if channel != "em":
                if not args.blinded:
                    plot.legend(1).add_entry(0, "data_obs", "Observed", 'PE')
                plot.legend(1).add_entry(0, "total_bkg", "Bkg. unc.", 'f')
                if args.b_only_fit is not None:
                    plot.legend(1).add_entry(2, "total_bkg_b_only", "Bkg. only fit", "l")
                plot.legend(1).setNColumns(3)
            else:
                plot.legend(1).setNColumns(5)
                if args.b_only_fit is not None:
                    plot.legend(1).setNColumns(6)
            # plot.legend(1).scaleTextSize(1.05)
            plot.legend(1).Draw()

            # draw additional labels
            plot.DrawCMS(cms_sub="")
            if "2016" in args.era:
                plot.DrawLumi("36.3 fb^{-1} (2016, 13 TeV)")
            elif "2017" in args.era:
                plot.DrawLumi("41.5 fb^{-1} (2017, 13 TeV)")
            elif "2018" in args.era:
                plot.DrawLumi("59.7 fb^{-1} (2018, 13 TeV)")
            elif "combined" in args.era:
                plot.DrawLumi("138 fb^{-1} (13 TeV)")
            else:
                logger.critical("Era {} is not implemented.".format(args.era))
                raise Exception

            posChannelCategoryLabelLeft = None
            plot.DrawChannelCategoryLabel(
                "#font[42]{%s, %s}" % (channel_dict[channel], category_dict[channel][category]),
                begin_left=posChannelCategoryLabelLeft)

            # save plot
            if not os.path.exists(args.output_dir):
                os.makedirs(args.output_dir)
            postfix = "prefit" if "prefit" in args.input else "postfit" if "postfit" in args.input else "undefined"
            plot.save("%s/%s_%s_%s_%s.%s" % (args.output_dir, args.era, channel, args.control_variable if args.control_variable is not None else category,
                                                postfix, "png"
                                                if args.png else "pdf"))
            # Undo switch of split value
            if int(category) < 35 and int(category) > 10:
                split_dict[channel] -= 100
            plots.append(
                plot
            )  # work around to have clean up seg faults only at the end of the script
Пример #13
0
def main(args):
    channel_dict = {
        "em": "e#mu",
        "et": "e#tau_{h}",
        "mt": "#mu#tau_{h}",
        "tt": "#tau_{h}#tau_{h}"
    }
    signal_categories = {
        "2": "#leq 1 jet p_{T}^{H} [200,#infty)",
        "3": "0 jet p_{T}^{H} [0,200)",
        "4": "1 jet p_{T}^{H} [0,120)",
        "5": "1 jet p_{T}^{H} [120,200)",
        "6": "#geq 2 jet m_{jj} [0,350)",
        "7": "#geq 2 jet m_{jj} [350,#infty) p_{T}^{H} [0,200)",
        "8": "#geq 2 jet m_{jj} [350,#infty) p_{T}^{H} [200,#infty)",
    }
    category_dict = {
        "em": signal_categories.copy(),
        "et": signal_categories.copy(),
        "mt": signal_categories.copy(),
        "tt": signal_categories.copy(),
    }
    category_dict["em"].update({"1" : "t#bar{t} control"})
    category_dict["et"].update({"1" : "W + jets control"})
    category_dict["mt"].update({"1" : "W + jets control"})

    bkg_processes = ["VVL", "TTL", "ZL", "jetFakes", "EMB"]
    bkg_processes_em = ["VVL", "TTL", "ZL", "W", "QCD", "EMB"]

    if "2016" in args.era:
        era = "Run2016"
    elif "2017" in args.era:
        era = "Run2017"
    elif "2018" in args.era:
        era = "Run2018"
    else:
        logger.critical("Era {} is not implemented.".format(args.era))
        raise Exception

    plots = []
    for channel in sorted(channel_dict):
        for category in sorted(category_dict[channel]):
            print "channel, category",channel,category

            rootfile = rootfile_parser.Rootfile_parser(args.input)
            rootfile._type = args.shape_type
            if channel == "em":
                bkgs = bkg_processes_em
            else:
                bkgs = bkg_processes
            legend_bkg_processes = copy.deepcopy(bkgs)
            legend_bkg_processes.reverse()

            # create plot
            width = 600
            plot = dd.Plot([0.3, [0.3, 0.28]], "ModTDR", r=0.04, l=0.14, width=width)
            print "plot created"

            # get background histograms
            for process in bkgs:
                try:
                    bg = rootfile.get(era, channel, category, process)
                    if isinstance(bg,ROOT.TH1):
                        plot.add_hist(bg, process, "bkg")
                        plot.setGraphStyle(process, "hist", fillcolor=styles.color_dict[process])
                except:
                    pass
            print "got bgs"

            # get signal histograms
            plot_idx_to_add_signal = [0,2]
            for i in plot_idx_to_add_signal:
                try:
                    plot.subplot(i).add_hist(rootfile.get(era, channel, category, "ggH125"), "ggH")
                    plot.subplot(i).add_hist(rootfile.get(era, channel, category, "ggH125"), "ggH_top")
                    plot.subplot(i).add_hist(rootfile.get(era, channel, category, "qqH125"), "qqH")
                    plot.subplot(i).add_hist(rootfile.get(era, channel, category, "qqH125"), "qqH_top")
                    if isinstance(rootfile.get(era, channel, category, "ZH125"), ROOT.TH1):
                        VHhist = rootfile.get(era, channel, category, "ZH125").Clone("VH")
                    WHhist = rootfile.get(era, channel, category, "WH125")
                    if isinstance(WHhist,ROOT.TH1) and VHhist:
                        VHhist.Add(WHhist)
                    elif WHhist:
                        VHhist = WHhist
                    plot.subplot(i).add_hist(VHhist, "VH")
                    plot.subplot(i).add_hist(VHhist, "VH_top")

                    if isinstance(rootfile.get(era, channel, category, "ttH125"), ROOT.TH1):
                        plot.subplot(i).add_hist(rootfile.get(era, channel, category, "ttH125"), "ttH")
                        plot.subplot(i).add_hist(rootfile.get(era, channel, category, "ttH125"), "ttH_top")

                    ggHWWhist = rootfile.get(era, channel, category, "ggHWW125")
                    qqHWWhist = rootfile.get(era, channel, category, "qqHWW125")
                    if isinstance(ggHWWhist, ROOT.TH1):
                        HWWhist = rootfile.get(era, channel, category, "ggHWW125").Clone("ggHWW125")
                    if isinstance(qqHWWhist,ROOT.TH1) and isinstance(HWWhist,ROOT.TH1):
                        HWWhist.Add(qqHWWhist)
                    elif isinstance(qqHWWhist,ROOT.TH1):
                        HWWhist = qqHWWhist
                    if isinstance(HWWhist,ROOT.TH1):
                        plot.subplot(i).add_hist(HWWhist, "HWW")
                        plot.subplot(i).add_hist(HWWhist, "HWW_top")
                except:
                    pass
            print "got signals"

            # get observed data and total background histograms
            plot.add_hist(rootfile.get(era, channel, category, "data_obs"), "data_obs")
            total_bkg = rootfile.get(era, channel, category, "TotalBkg")
            ggHHist = rootfile.get(era, channel, category, "ggH125")
            qqHHist = rootfile.get(era, channel, category, "qqH125")
            plot.add_hist(total_bkg, "total_bkg")

            plot.subplot(0).setGraphStyle("data_obs", "e0")
            plot.subplot(0).setGraphStyle("ggH", "hist", linecolor=styles.color_dict["ggH"], linewidth=3)
            plot.subplot(0).setGraphStyle("ggH_top", "hist", linecolor=0)
            plot.subplot(0).setGraphStyle("qqH", "hist", linecolor=styles.color_dict["qqH"], linewidth=3)
            plot.subplot(0).setGraphStyle("qqH_top", "hist", linecolor=0)
            plot.subplot(0).setGraphStyle("VH", "hist", linecolor=styles.color_dict["VH"], linewidth=3)
            plot.subplot(0).setGraphStyle("VH_top", "hist", linecolor=0)
            plot.subplot(0).setGraphStyle("ttH", "hist", linecolor=styles.color_dict["ttH"], linewidth=3)
            plot.subplot(0).setGraphStyle("ttH_top", "hist", linecolor=0)
            plot.subplot(0).setGraphStyle("HWW", "hist", linecolor=styles.color_dict["HWW"], linewidth=3)
            plot.subplot(0).setGraphStyle("HWW_top", "hist", linecolor=0)
            plot.setGraphStyle("total_bkg", "e2", markersize=0, fillcolor=styles.color_dict["unc"], linecolor=0)
            print "data + signal bg"

            # assemble ratio
            bkg_ggH = plot.subplot(2).get_hist("ggH")
            bkg_qqH = plot.subplot(2).get_hist("qqH")
            bkg_ggH.Add(plot.subplot(2).get_hist("total_bkg"))
            if bkg_qqH:
                bkg_qqH.Add(plot.subplot(2).get_hist("total_bkg"))
            plot.subplot(2).add_hist(bkg_ggH, "bkg_ggH")
            plot.subplot(2).add_hist(bkg_ggH, "bkg_ggH_top")
            plot.subplot(2).add_hist(bkg_qqH, "bkg_qqH")
            plot.subplot(2).add_hist(bkg_qqH, "bkg_qqH_top")
            plot.subplot(2).setGraphStyle("bkg_ggH", "hist", linecolor=styles.color_dict["ggH"], linewidth=3)
            plot.subplot(2).setGraphStyle("bkg_ggH_top", "hist", linecolor=0)
            plot.subplot(2).setGraphStyle("bkg_qqH", "hist", linecolor=styles.color_dict["qqH"], linewidth=3)
            plot.subplot(2).setGraphStyle("bkg_qqH_top", "hist", linecolor=0)
            plot.subplot(2).normalize([ "total_bkg", "bkg_ggH", "bkg_ggH_top", "bkg_qqH", "bkg_qqH_top", "data_obs"], "total_bkg")
            print "made ratio"

            # stack background processes
            plot.create_stack(bkgs, "stack")
            print "created stack"

            # normalize stacks by bin-width
            if args.normalize_by_bin_width:
                plot.subplot(0).normalizeByBinWidth()
                plot.subplot(1).normalizeByBinWidth()
            print "normalized by bin width"

            # set axes limits and labels
            plot.subplot(0).setYlims(0.0, 2 * plot.subplot(0).get_hist("total_bkg").GetMaximum())
            plot.subplot(2).setYlims(0.45, 2.05)
            plot.subplot(2).setXlabel(styles.x_label_dict[channel][args.variable])
            if args.normalize_by_bin_width:
                plot.subplot(0).setYlabel("dN/d(%s)"%styles.x_label_dict[channel][args.variable])
            else:
                plot.subplot(0).setYlabel("N_{events}")

            plot.subplot(2).setYlabel("")
            plot.scaleYLabelSize(0.8)
            plot.scaleYTitleOffset(1.1)
            print "labels & limits"

            # draw subplots. Argument contains names of objects to be drawn in corresponding order.
            procs_to_draw = ["stack", "total_bkg", "ggH", "ggH_top", "qqH", "qqH_top", "VH", "VH_top", "ttH", "ttH_top", "HWW", "HWW_top", "data_obs"]
            plot.subplot(0).Draw(procs_to_draw)
            plot.subplot(2).Draw(["total_bkg", "bkg_ggH", "bkg_ggH_top", "bkg_qqH", "bkg_qqH_top", "data_obs"])
            print "hists drawn"

            # create legends
            suffix = ["", "_top"]
            for i in range(2):

                plot.add_legend(width=0.6, height=0.15)
                for process in legend_bkg_processes:
                    try:
                        plot.legend(i).add_entry(0, process, styles.legend_label_dict[process.replace("TTL", "TT").replace("VVL", "VV")], 'f')
                    except:
                        pass
                plot.legend(i).add_entry(0, "total_bkg", "Bkg. unc.", 'f')
                plot.legend(i).add_entry(0, "ggH%s" % suffix[i], "gg#rightarrowH", 'l')
                plot.legend(i).add_entry(0, "qqH%s" % suffix[i], "qq#rightarrowH", 'l')
                plot.legend(i).add_entry(0, "VH%s" % suffix[i], "qq#rightarrowVH", 'l')
                try:
                    plot.legend(i).add_entry(0, "ttH%s" % suffix[i], "ttH", 'l')
                    plot.legend(i).add_entry(0, "HWW%s" % suffix[i], "H#rightarrowWW", 'l')
                except:
                    pass
                plot.legend(i).add_entry(0, "data_obs", "Data", 'PE')
                plot.legend(i).setNColumns(3)
            plot.legend(0).Draw()
            plot.legend(1).setAlpha(0.0)
            plot.legend(1).Draw()

            for i in range(2):
                plot.add_legend(
                    reference_subplot=2, pos=1, width=0.5, height=0.03)
                plot.legend(i + 2).add_entry(0, "data_obs", "Data", 'PE')
                plot.legend(i + 2).add_entry(0, "ggH%s" % suffix[i], "ggH+bkg.", 'l')
                plot.legend(i + 2).add_entry(0, "qqH%s" % suffix[i], "qqH+bkg.", 'l')
                plot.legend(i + 2).add_entry(0, "total_bkg", "Bkg. unc.", 'f')
                plot.legend(i + 2).setNColumns(4)
            plot.legend(2).Draw()
            plot.legend(3).setAlpha(0.0)
            plot.legend(3).Draw()
            print "legends created"

            # draw additional labels
            plot.DrawCMS()
            if "2016" in args.era:
                plot.DrawLumi("35.9 fb^{-1} (2016, 13 TeV)")
            elif "2017" in args.era:
                plot.DrawLumi("41.5 fb^{-1} (2017, 13 TeV)")
            elif "2018" in args.era:
                plot.DrawLumi("59.7 fb^{-1} (2018, 13 TeV)")
            else:
                logger.critical("Era {} is not implemented.".format(args.era))
                raise Exception

            plot.DrawChannelCategoryLabel("%s, %s" % (channel_dict[channel], category_dict[channel][category]), begin_left=None)
            print "additional labes drawn"

            # save plot
            postfix = args.shape_type
            plot.save("%s_plots_cutbased/%s_%s_%s_%s.%s" % (args.era, args.era, channel, category, postfix, "pdf"))
            plot.save("%s_plots_cutbased/%s_%s_%s_%s.%s" % (args.era, args.era, channel, category, postfix, "png"))
            plots.append(plot)  # work around to have clean up seg faults only at the end of the script
def main(args):
    if args.control_variable is None:
        channel_categories = {
            #"et": ["nobtag_tight", "btag_tight", "nobtag_loosemt", "nobtag_tight"]
            "et": ["10", "11", "12", "13", "14", "15", "16", "17", "18", "32", "33",  "35", "36"],
            #"mt": ["nobtag_tight", "btag_tight", "nobtag_loosemt", "nobtag_tight"]
            "mt": ["10", "11", "12", "13", "14", "15", "16", "17", "18", "32", "33",  "35", "36"],
            #"tt": ["nobtag", "btag"]
            "tt": ["10", "11", "12", "13", "14", "15", "16", "17", "32", "35"],
            "em": ["2", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "32", "33", "34", "35", "36", "37"]
        }
        if args.model_independent:
            channel_categories = {
                #"et": ["nobtag_tight", "btag_tight", "nobtag_loosemt", "nobtag_tight"]
                "et": ["32", "33",  "35", "36"],
                #"mt": ["nobtag_tight", "btag_tight", "nobtag_loosemt", "nobtag_tight"]
                "mt": ["32", "33",  "35", "36"],
                #"tt": ["nobtag", "btag"]
                "tt": ["32", "35"],
                "em": ["2", "32", "33", "34", "35", "36", "37"]
            }
    else:
        channel_categories = {
            "et": ["100"],
            "mt": ["100"],
            "tt": ["100"],
            "em": ["100"]
        }
    channel_dict = {
        "ee": "ee",
        "em": "e#mu",
        "et": "e#tau_{h}",
        "mm": "#mu#mu",
        "mt": "#mu#tau_{h}",
        "tt": "#tau_{h}#tau_{h}"
    }
    if args.control_variable != None:
        category_dict = {"100": "inclusive"}
    else:
        category_dict = {
            "et": {
                "10": "N_{jets} = 0, m_{T} (e) < 40 GeV",
                "11": "N_{jets} = 0, 40 GeV < m_{T} (e) < 70 GeV",
                "12": "N_{jets} = 0, #Delta R #geq 2.5",
                "13": "n_{jets} = 1, p_{T}(H) < 120 GeV",
                "14": "n_{jets} = 1, 120 GeV < p_{T}(H) < 200 GeV",
                "15": "n_{jets} = 1, p_{T}(H) > 200 GeV",
                "16": "N_{jets} #geq 2, m_{jj} < 350 GeV",
                "17": "N_{jets} #geq 2, 350 GeV < m_{jj} < 1000 GeV",
                "18": "N_{jets} #geq 2, m_{jj} > 1000 GeV",
                "32": "No B-tag Tight-m_{T}",
                "33": "No B-tag Loose-m_{T}",
                "35": "B-tag Tight-m_{T}",
                "36": "B-tag Loose-m_{T}",
                },
            "mt": {
                "10": "N_{jets} = 0, m_{T} (e) < 40 GeV",
                "11": "N_{jets} = 0, 40 GeV < m_{T} (e) < 70 GeV",
                "12": "N_{jets} = 0, #Delta R #geq 2.5",
                "13": "n_{jets} = 1, p_{T}(H) < 120 GeV",
                "14": "n_{jets} = 1, 120 GeV < p_{T}(H) < 200 GeV",
                "15": "n_{jets} = 1, p_{T}(H) > 200 GeV",
                "16": "N_{jets} #geq 2, m_{jj} < 350 GeV",
                "17": "N_{jets} #geq 2, 350 GeV < m_{jj} < 1000 GeV",
                "18": "N_{jets} #geq 2, m_{jj} > 1000 GeV",
                "32": "No B-tag Tight-m_{T}",
                "33": "No B-tag Loose-m_{T}",
                "35": "B-tag Tight-m_{T}",
                "36": "B-tag Loose-m_{T}",
                },
            "tt": {
                "10": "10",
                "11": "11",
                "12": "12",
                "13": "13",
                "14": "14",
                "15": "15",
                "16": "16",
                "17": "17",
                "32": "No B-tag",
                "35": "B-tag",
                },
            "em": {
                "2": "d_{#zeta} < -35 GeV",
                "10": "10",
                "11": "11",
                "12": "12",
                "13": "13",
                "14": "14",
                "15": "15",
                "16": "16",
                "17": "17",
                "18": "18",
                "19": "19",
                "32": "No B-tag, high d_{#zeta}",
                "33": "No B-tag, medium d_{#zeta}",
                "34": "No B-tag, low d_{#zeta}",
                "35": "B-tag, high d_{#zeta}",
                "36": "B-tag, medium d_{#zeta}",
                "37": "B-tag, low d_{#zeta}",
                },

        }
    if args.linear == True:
        split_value = 0
    else:
        if args.normalize_by_bin_width:
            split_value = 1
        else:
            split_value = 101

    split_dict = {c: split_value for c in ["et", "mt", "tt", "em"]}

    bkg_processes = [
        "VVL", "TTL", "ZL", "jetFakes", "EMB"
    ]
    if not args.fake_factor and args.embedding:
        bkg_processes = [
            "QCD", "VVJ", "VVL", "W", "TTJ", "TTL", "ZJ", "ZL", "EMB"
        ]
    if not args.embedding and args.fake_factor:
        bkg_processes = [
            "VVT", "VVJ", "TTT", "TTJ", "ZJ", "ZL", "jetFakes", "ZTT"
        ]
    if not args.embedding and not args.fake_factor:
        bkg_processes = [
            "QCD", "W", "VVJ", "VVL", "VVT", "TTJ", "TTL", "TTT", "ZJ", "ZL", "ZTT"
#            "QCD", "VVT", "VVJ", "W", "TTT", "TTJ", "ZJ", "ZL", "ZTT"
        ]
    all_bkg_processes = [b for b in bkg_processes]
    legend_bkg_processes = copy.deepcopy(bkg_processes)
    legend_bkg_processes.reverse()

    if "2016" in args.era:
        era = "2016"
    elif "2017" in args.era:
        era = "2017"
    elif "2018" in args.era:
        era = "2018"
    else:
        logger.critical("Era {} is not implemented.".format(args.era))
        raise Exception

    plots = []
    for channel in args.channels:
        if "em" in channel:
            if not args.embedding:
                bkg_processes = [
                    "QCDMC", "VVT", "VVL", "W", "TTT", "TTL", "ZL", "ZTT"
                ]
            if args.embedding:
                bkg_processes = [
                    "QCD", "VVL", "W", "TTL", "ZL", "EMB"
                ]

        for category in channel_categories[channel]:
            if args.control_region and category != "2":
                continue
            rootfile = rootfile_parser.Rootfile_parser(args.input)
            legend_bkg_processes = copy.deepcopy(bkg_processes)
            legend_bkg_processes.reverse()
            # create plot
            if args.linear == True:
                plot = dd.Plot(
                    [0.3, [0.3, 0.28]], "ModTDR", r=0.04, l=0.14, width=600)
            else:
                plot = dd.Plot(
                    [0.5, [0.3, 0.28]], "ModTDR", r=0.04, l=0.14, width=600)

            # get background histograms
            for process in bkg_processes:
                if process in ["jetFakes", "jetFakesEMB"] and channel == "tt":
                    jetfakes_hist = rootfile.get(era, channel, category, process)
                    jetfakes_hist.Add(rootfile.get(era, channel, category, "wFakes"))
                    plot.add_hist(jetfakes_hist, process, "bkg")
                else:
                    plot.add_hist(
                        rootfile.get(era, channel, category, process), process, "bkg")
                plot.setGraphStyle(
                    process, "hist", fillcolor=styles.color_dict[process])

            # get signal histograms
            plot_idx_to_add_signal = [0,2] if args.linear else [1,2]
            for i in plot_idx_to_add_signal:
                if args.model_independent:
                    ggH_hist = rootfile.get(era, channel, category, "ggh_t").Clone()
                    ggH_hist.Add(rootfile.get(era, channel, category, "ggh_i"))
                    ggH_hist.Add(rootfile.get(era, channel, category, "ggh_b"))
                    plot.subplot(i).add_hist(
                        ggH_hist, "ggH")
                    plot.subplot(i).add_hist(
                        ggH_hist, "ggH_top")
                    plot.subplot(i).add_hist(
                        rootfile.get(era, channel, category, "bbh"), "bbH")
                    plot.subplot(i).add_hist(
                        rootfile.get(era, channel, category, "bbh"), "bbH_top")
                else:
                    plot.subplot(i).add_hist(
                        rootfile.get(era, channel, category, "TotalSig"), "mssm_sig")
                    plot.subplot(i).add_hist(
                        rootfile.get(era, channel, category, "TotalSig"), "mssm_sig_top")

            # get observed data and total background histograms
            plot.add_hist(
                rootfile.get(era, channel, category, "data_obs"), "data_obs")
            plot.add_hist(
                rootfile.get(era, channel, category, "TotalBkg"), "total_bkg")

            plot.subplot(0).setGraphStyle("data_obs", "e0")
            if args.model_independent:
                plot.subplot(0 if args.linear else 1).setGraphStyle(
                    "ggH", "hist", linecolor=styles.color_dict["ggH"], linewidth=3)
                plot.subplot(0 if args.linear else 1).setGraphStyle(
                    "ggH_top", "hist", linecolor=0)
                plot.subplot(0 if args.linear else 1).setGraphStyle(
                    "bbH", "hist", linecolor=styles.color_dict["bbH"], linewidth=3)
                plot.subplot(0 if args.linear else 1).setGraphStyle(
                    "bbH_top", "hist", linecolor=0)
            else:
                plot.subplot(0 if args.linear else 1).setGraphStyle(
                    "mssm_sig", "hist", linecolor=styles.color_dict["bbH"], linewidth=3)
                plot.subplot(0 if args.linear else 1).setGraphStyle(
                    "mssm_sig_top", "hist", linecolor=0)
            plot.setGraphStyle(
                "total_bkg",
                "e2",
                markersize=0,
                fillcolor=styles.color_dict["unc"],
                linecolor=0)

            # assemble ratio
            if args.model_independent:
                bkg_ggH = plot.subplot(2).get_hist("ggH")
                bkg_bbH = plot.subplot(2).get_hist("bbH")
                bkg_ggH.Add(plot.subplot(2).get_hist("total_bkg"))
                bkg_bbH.Add(plot.subplot(2).get_hist("total_bkg"))
                plot.subplot(2).add_hist(bkg_ggH, "bkg_ggH")
                plot.subplot(2).add_hist(bkg_ggH, "bkg_ggH_top")
                plot.subplot(2).add_hist(bkg_bbH, "bkg_bbH")
                plot.subplot(2).add_hist(bkg_bbH, "bkg_bbH_top")
                plot.subplot(2).setGraphStyle(
                    "bkg_ggH",
                    "hist",
                    linecolor=styles.color_dict["ggH"],
                    linewidth=3)
                plot.subplot(2).setGraphStyle(
                    "bkg_ggH_top",
                    "hist",
                    linecolor=0)
                plot.subplot(2).setGraphStyle(
                    "bkg_bbH",
                    "hist",
                    linecolor=styles.color_dict["bbH"],
                    linewidth=3)
                plot.subplot(2).setGraphStyle(
                    "bkg_bbH_top",
                    "hist",
                    linecolor=0)
                plot.subplot(2).normalize([
                    "total_bkg", "bkg_ggH", "bkg_ggH_top", "bkg_bbH",
                    "bkg_bbH_top", "data_obs"
                ], "total_bkg")
            else:
                bkg_sig = plot.subplot(2).get_hist("mssm_sig")
                bkg_sig.Add(plot.subplot(2).get_hist("total_bkg"))
                plot.subplot(2).add_hist(bkg_sig, "bkg_mssm_sig")
                plot.subplot(2).add_hist(bkg_sig, "bkg_mssm_sig_top")
                plot.subplot(2).setGraphStyle(
                    "bkg_mssm_sig",
                    "hist",
                    linecolor=styles.color_dict["bbH"],
                    linewidth=3)
                plot.subplot(2).setGraphStyle(
                    "bkg_mssm_sig_top",
                    "hist",
                    linecolor=0)
                plot.subplot(2).normalize([
                    "total_bkg", "bkg_mssm_sig", "bkg_mssm_sig_top",
                    "data_obs"
                ], "total_bkg")

            # stack background processes
            plot.create_stack(bkg_processes, "stack")

            # normalize stacks by bin-width
            if args.normalize_by_bin_width:
                plot.subplot(0).normalizeByBinWidth()
                plot.subplot(1).normalizeByBinWidth()

            # set axes limits and labels
            plot.subplot(0).setYlims(
                split_dict[channel],
                # max(2 * plot.subplot(0).get_hist("total_bkg").GetMaximum(),
                #     split_dict[channel] * 2))
                max(1.3 * plot.subplot(0).get_hist("total_bkg").GetMaximum(),
                    split_dict[channel] * 2))

            plot.subplot(2).setYlims(0.75, 1.8)

            if args.linear != True:
                # plot.subplot(1).setYlims(1.e-4, split_dict[channel])
                plot.subplot(1).setYlims(1.e-3, split_dict[channel])
                plot.subplot(1).setLogY()
                if int(category) > 30 or int(category) == 1:
                    plot.subplot(1).setLogX()
                plot.subplot(1).setYlabel(
                    "")  # otherwise number labels are not drawn on axis
            if args.control_variable != None:
                if args.control_variable in styles.x_label_dict[args.channels[0]]:
                    x_label = styles.x_label_dict[args.channels[0]][
                        args.control_variable]
                else:
                    x_label = args.control_variable
                plot.subplot(2).setXlabel(x_label)
            else:
                if int(category) > 30 or int(category) == 1:
                    plot.subplot(2).setXlabel("m_{T}^{tot} (Puppi) [GeV]")
                else:
                    plot.subplot(2).setXlabel("SVFit m_{#tau#tau} (Puppi) [GeV]")
            if args.normalize_by_bin_width:
                if int(category) > 30 or int(category) == 1:
                    plot.subplot(0).setYlabel("dN/dm_{T}^{tot} [1/GeV]")
                else:
                    plot.subplot(0).setYlabel("dN/dm_{#tau#tau} [1/GeV]")
            else:
                plot.subplot(0).setYlabel("N_{events}")

            plot.subplot(2).setYlabel("")


            if int(category) > 30 or int(category) == 1:
                low_edge = max(10, rootfile.get(era, channel, category, "TotalSig").GetBinLowEdge(2))
                plot.setXlims(low_edge, 3890)
                plot.subplot(0).setLogX()
                plot.subplot(2).setLogX()

            #plot.scaleXTitleSize(0.8)
            #plot.scaleXLabelSize(0.8)
            #plot.scaleYTitleSize(0.8)
            plot.scaleYLabelSize(0.8)
            #plot.scaleXLabelOffset(2.0)
            plot.scaleYTitleOffset(1.05)


            #plot.subplot(2).setNYdivisions(3, 5)

            # draw subplots. Argument contains names of objects to be drawn in corresponding order.
            # procs_to_draw = ["stack", "total_bkg", "ggH", "ggH_top", "bbH", "bbH_top", "data_obs"] if args.linear else ["stack", "total_bkg", "data_obs"]
            if category == "1" and args.control_region:
                procs_to_draw = ["stack", "total_bkg", "data_obs"] if args.linear else ["stack", "total_bkg", "data_obs"]
            else:
                if args.model_independent:
                    procs_to_draw = ["stack", "total_bkg", "ggH", "ggH_top", "bbH", "bbH_top", "data_obs"] if args.linear else ["stack", "total_bkg", "data_obs"]
                else:
                    procs_to_draw = ["stack", "total_bkg", "mssm_sig", "mssm_sig_top", "data_obs"] if args.linear else ["stack", "total_bkg", "data_obs"]
                if args.blinded:
                    procs_to_draw.remove("data_obs")
            plot.subplot(0).Draw(procs_to_draw)
            if args.linear != True:
                # plot.subplot(1).Draw([
                #     "stack", "total_bkg", "ggH", "bbH",
                #     "ggH_top", "bbH_top",
                #     "data_obs"
                # ])
                if category == "1" and args.control_region:
                    plot.subplot(1).Draw([
                        "stack", "total_bkg",
                        "data_obs"
                    ])
                else:
                    if args.model_independent:
                        procs_to_draw = ["stack", "total_bkg", "ggH", "bbH", "ggH_top", "bbH_top", "data_obs"]
                    else:
                        procs_to_draw = ["stack", "total_bkg", "mssm_sig", "mssm_sig_top", "data_obs"]
                    if args.blinded:
                        procs_to_draw.remove("data_obs")
                    plot.subplot(1).Draw(procs_to_draw)
            if category == "1" and args.control_region:
                plot.subplot(2).Draw([
                    "total_bkg",
                    "data_obs"
                ])
            else:
                if args.model_independent:
                    procs_to_draw = ["total_bkg", "bkg_ggH", "bkg_bbH", "bkg_ggH_top", "bkg_bbH_top", "data_obs"]
                else:
                    procs_to_draw = ["total_bkg", "bkg_mssm_sig", "bkg_mssm_sig_top", "data_obs"]
                if args.blinded:
                    procs_to_draw.remove("data_obs")
                plot.subplot(2).Draw(procs_to_draw)

            # create legends
            suffix = ["", "_top"]
            for i in range(2):

                if int(category) < 30 and int(category) > 1:
                    plot.add_legend(width=0.38, height=0.30)
                else:
                    plot.add_legend(width=0.40, height=0.30)
                # plot.add_legend(width=0.6, height=0.15)
                for process in legend_bkg_processes:
                    plot.legend(i).add_entry(
                        0, process, styles.legend_label_dict[process.replace("TTL", "TT").replace("VVL", "VV")], 'f')
                plot.legend(i).add_entry(0, "total_bkg", "Bkg. unc.", 'f')
                if args.control_region and category == "1":
                    # plot.legend(i).add_entry(0 if args.linear else 1, "mssm_sig%s" % suffix[i], "#splitline{H #rightarrow #tau#tau}{(m_{H}=1200 GeV)}", 'l')
                    pass
                else:
                    if args.model_independent:
                        plot.legend(i).add_entry(0 if args.linear else 1, "ggH%s" % suffix[i], "#splitline{ggH}{(m_{H} = 2600 GeV)}", 'l')
                        plot.legend(i).add_entry(0 if args.linear else 1, "bbH%s" % suffix[i], "#splitline{bbH}{(m_{H} = 2600 GeV)}", 'l')
                    else:
                        plot.legend(i).add_entry(0 if args.linear else 1, "mssm_sig%s" % suffix[i], "#splitline{H #rightarrow #tau#tau}{#splitline{(m_{A}=1200 GeV,}{ tan #beta = 10)}}", 'l')
                if not args.blinded:
                    plot.legend(i).add_entry(0, "data_obs", "Data", 'PE')
                plot.legend(i).setNColumns(2)
            plot.legend(0).Draw()
            plot.legend(1).setAlpha(0.0)
            plot.legend(1).Draw()

            if args.chi2test:
                import ROOT as r
                f = r.TFile(args.input, "read")
                background = f.Get("htt_{}_{}_Run{}_{}/TotalBkg".format(
                    channel, category, args.era, "prefit"
                    if "prefit" in args.input else "postfit"))
                data = f.Get("htt_{}_{}_Run{}_{}/data_obs".format(
                    channel, category, args.era, "prefit"
                    if "prefit" in args.input else "postfit"))
                chi2 = data.Chi2Test(background, "UW CHI2/NDF")
                plot.DrawText(0.7, 0.3,
                              "\chi^{2}/ndf = " + str(round(chi2, 3)))

            for i in range(2):
                plot.add_legend(
                    reference_subplot=2, pos=1, width=0.5, height=0.06)
                if not args.blinded:
                    plot.legend(i + 2).add_entry(0, "data_obs", "Data", 'PE')
                if args.control_region and category == "1":
                    pass
                else:
                    if args.model_independent:
                        plot.legend(i + 2).add_entry(0 if args.linear else 1, "ggH%s" % suffix[i],
                                             "ggH+bkg.", 'l')
                        plot.legend(i + 2).add_entry(0 if args.linear else 1, "bbH%s" % suffix[i],
                                             "bbH+bkg.", 'l')
                    else:
                        plot.legend(i + 2).add_entry(0 if args.linear else 1, "mssm_sig%s" % suffix[i],
                                                     "H+bkg.", 'l')
                plot.legend(i + 2).add_entry(0, "total_bkg", "Bkg. unc.", 'f')
                plot.legend(i + 2).setNColumns(3)
            plot.legend(2).Draw()
            plot.legend(3).setAlpha(0.0)
            plot.legend(3).Draw()

            # draw additional labels
            # plot.DrawCMS()
            if "2016" in args.era:
                plot.DrawLumi("35.9 fb^{-1} (2016, 13 TeV)")
            elif "2017" in args.era:
                plot.DrawLumi("41.5 fb^{-1} (2017, 13 TeV)")
            elif "2018" in args.era:
                plot.DrawLumi("59.7 fb^{-1} (2018, 13 TeV)")
            else:
                logger.critical("Era {} is not implemented.".format(args.era))
                raise Exception

            posChannelCategoryLabelLeft = None
            plot.DrawChannelCategoryLabel(
                "%s, %s" % (channel_dict[channel], category_dict[channel][category]),
                begin_left=posChannelCategoryLabelLeft)

            # save plot
            postfix = "prefit" if "prefit" in args.input else "postfit" if "postfit" in args.input else "undefined"
            plot.save("%s/%s_%s_%s_%s.%s" % (args.output_dir, args.era, channel, args.control_variable if args.control_variable is not None else category,
                                                postfix, "png"
                                                if args.png else "pdf"))
            plots.append(
                plot
            )  # work around to have clean up seg faults only at the end of the script
Пример #15
0
def main(args):
    channel_categories = {
        #"et": ["ztt", "zll", "w", "tt", "ss", "misc"],
        "et": ["12", "15", "11", "13", "14", "16"],
        #"mt": ["ztt", "zll", "w", "tt", "ss", "misc"],
        "mt": ["12", "15", "11", "13", "14", "16"],
        #"tt": ["ztt", "noniso", "misc"]
        "tt": ["12", "17", "16"]
    }

    if args.categories == "stxs_stage0":
        for channel in ["et", "mt", "tt"]:
            channel_categories[channel] += ["1", "2"]
    elif args.categories == "stxs_stage1":
        for channel in ["et", "mt", "tt"]:
            channel_categories[channel] += ["1", "2"]
    else:
        logger.critical("Selected unkown STXS categorization {}",
                        args.categories)
        raise Exception

    if args.stxs_signals == "stxs_stage0":
        signals = ["ggH", "qqH"]
        signal_linestlyes = [1, 1]
    elif args.stxs_signals == "stxs_stage1":
        signals = [
            "qqH_VBFTOPO_JET3VETO", "qqH_VBFTOPO_JET3", "qqH_REST",
            "qqH_PTJET1_GT200", "qqH_VH2JET", "ggH_0J", "ggH_1J_PTH_0_60",
            "ggH_1J_PTH_60_120", "ggH_1J_PTH_120_200", "ggH_1J_PTH_GT200",
            "ggH_GE2J_PTH_0_60", "ggH_GE2J_PTH_60_120", "ggH_GE2J_PTH_120_200",
            "ggH_GE2J_PTH_GT200", "ggH_VBFTOPO_JET3VETO", "ggH_VBFTOPO_JET3"
        ]
        signal_linestlyes = [1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
    else:
        logger.critical("Selected unkown STXS signals {}", args.stxs_signals)
        raise Exception
    signal_names = [signal.replace("125", "") for signal in signals]

    channel_dict = {
        "ee": "ee",
        "em": "e#mu",
        "et": "e#tau_{h}",
        "mm": "#mu#mu",
        "mt": "#mu#tau_{h}",
        "tt": "#tau_{h}#tau_{h}"
    }

    category_dict = {
        "1": "ggH",
        "2": "VBF",
        "12": "Z#rightarrow#tau#tau",
        "15": "Z#rightarrowll",
        "11": "W+jets",
        "13": "t#bar{t}",
        "14": "same sign",
        "16": "misc",
        "17": "noniso"
    }

    rootfile = rootfile_parser.Rootfile_parser(args.input)

    plots = []
    for channel in args.channels:
        for category in channel_categories[channel]:
            # Create plot
            width = 600
            if args.categories == "stxs_stage1":
                if category in ["1", "2"]:
                    width = 1200
            plot = dd.Plot([], "ModTDR", r=0.04, l=0.14, width=width)

            # Plot signals
            for i, (signal, name) in enumerate(zip(signals, signal_names)):
                plot.subplot(0).add_hist(
                    rootfile.get(channel, category, signal), name)
                plot.subplot(0).setGraphStyle(
                    name,
                    "hist",
                    linecolor=styles.color_dict[name.split("_")[0]],
                    linewidth=5)
                plot.subplot(0).get_hist(name).SetLineStyle(
                    signal_linestlyes[i])

            # Normalize by bin-width
            if args.normalize_by_bin_width:
                plot.subplot(0).normalizeByBinWidth()

            # Define axes
            plot.subplot(0).setXlabel("NN score")
            if args.normalize_by_bin_width:
                plot.subplot(0).setYlabel("N_{events}/bin width")
            else:
                plot.subplot(0).setYlabel("N_{events}")

            # Draw signals
            plot.subplot(0).setLogY()
            plot.subplot(0).setYlims(1e-3, 1e5)
            plot.subplot(0).Draw(signal_names)

            # Draw additional labels
            plot.DrawCMS()
            if "2016" in args.era:
                plot.DrawLumi("35.9 fb^{-1} (2016, 13 TeV)")
            elif "2017" in args.era:
                plot.DrawLumi("41.5 fb^{-1} (2017, 13 TeV)")
            else:
                logger.critical("Era {} is not implemented.".format(args.era))
                raise Exception

            posChannelCategoryLabelLeft = None
            if args.categories == "stxs_stage1":
                if category in ["1", "2"]:
                    posChannelCategoryLabelLeft = 0.075
            plot.DrawChannelCategoryLabel(
                "%s, %s" % (channel_dict[channel], category_dict[category]),
                begin_left=posChannelCategoryLabelLeft)

            # Create legends
            plot.add_legend(width=0.40, height=0.30)
            plot.legend(0).setNColumns(1)
            for i, name in enumerate(signal_names):
                plot.legend(0).add_entry(0, name, name, 'l')
            plot.legend(0).Draw()

            # Save plot
            postfix = "signals_{}".format(args.stxs_signals)
            plot.save("plots/%s_%s_%s_%s.%s" %
                      (args.era, channel, category, postfix,
                       "png" if args.png else "pdf"))

            plots.append(
                plot
            )  # work around to have clean up seg faults only at the end of the script
Пример #16
0
def main(args):
    if args.gof_variable != None:
        channel_categories = {c: [args.gof_variable] for c in args.channels}
    else:
        channel_categories = {
            "et": ["ggh", "qqh", "ztt", "zll", "w", "tt", "ss", "misc"],
            "mt": ["ggh", "qqh", "ztt", "zll", "w", "tt", "ss", "misc"],
            "tt": ["ggh", "qqh", "ztt", "noniso", "misc"]
        }
    channel_dict = {
        "ee": "ee",
        "em": "e#mu",
        "et": "e#tau_{h}",
        "mm": "#mu#mu",
        "mt": "#mu#tau_{h}",
        "tt": "#tau_{h}#tau_{h}"
    }
    if args.gof_variable != None:
        category_dict = {args.gof_variable: "inclusive"}
    else:
        category_dict = {
            "ggh": "ggH",
            "qqh": "VBF",
            "ztt": "Z#rightarrow#tau#tau",
            "zll": "Z#rightarrowll",
            "w": "W+jets",
            "tt": "t#bar{t}",
            "ss": "same sign",
            "misc": "misc",
            "noniso": "noniso"
        }
    if args.linear == True:
        split_value = 0
    else:
        if args.normalize_by_bin_width:
            split_value = 10001
        else:
            split_value = 101

    split_dict = {c: split_value for c in ["et", "mt", "tt"]}
    bkg_processes = ["EWK", "QCD", "VV", "W", "TTT", "TTJ", "ZJ", "ZL", "ZTT"]
    legend_bkg_processes = copy.deepcopy(bkg_processes)
    legend_bkg_processes.reverse()

    rootfile = rootfile_parser.Rootfile_parser(args.input)

    plots = []
    for channel in args.channels:
        for category in channel_categories[channel]:
            # create plot
            if args.linear == True:
                plot = plot = dd.Plot([0.3, [0.3, 0.28]],
                                      "ModTDR",
                                      r=0.04,
                                      l=0.14)
            else:
                plot = dd.Plot([0.5, [0.3, 0.28]], "ModTDR", r=0.04, l=0.14)

            # get background histograms
            for process in bkg_processes:
                plot.add_hist(rootfile.get(channel, category, process),
                              process, "bkg")
                plot.setGraphStyle(process,
                                   "hist",
                                   fillcolor=styles.color_dict[process])

            # get signal histograms
            for i in range(2):
                plot.subplot(i + 1).add_hist(
                    rootfile.get(channel, category, "ggH"), "ggH")
                plot.subplot(i + 1).add_hist(
                    rootfile.get(channel, category, "ggH"), "ggH_top")
                plot.subplot(i + 1).add_hist(
                    rootfile.get(channel, category, "qqH"), "qqH")
                plot.subplot(i + 1).add_hist(
                    rootfile.get(channel, category, "qqH"), "qqH_top")

            # get observed data and total background histograms
            plot.add_hist(rootfile.get(channel, category, "data_obs"),
                          "data_obs")
            plot.add_hist(rootfile.get(channel, category, "TotalBkg"),
                          "total_bkg")

            plot.subplot(0).setGraphStyle("data_obs", "e0")
            plot.subplot(1).setGraphStyle("ggH",
                                          "hist",
                                          linecolor=styles.color_dict["ggH"],
                                          linewidth=3)
            plot.subplot(1).setGraphStyle("ggH_top", "hist", linecolor=0)
            plot.subplot(1).setGraphStyle("qqH",
                                          "hist",
                                          linecolor=styles.color_dict["qqH"],
                                          linewidth=3)
            plot.subplot(1).setGraphStyle("qqH_top", "hist", linecolor=0)
            plot.setGraphStyle("total_bkg",
                               "e2",
                               markersize=0,
                               fillcolor=styles.color_dict["unc"],
                               linecolor=0)

            # assemble ratio
            bkg_ggH = plot.subplot(2).get_hist("ggH")
            bkg_qqH = plot.subplot(2).get_hist("qqH")
            bkg_ggH.Add(plot.subplot(2).get_hist("total_bkg"))
            bkg_qqH.Add(plot.subplot(2).get_hist("total_bkg"))
            plot.subplot(2).add_hist(bkg_ggH, "bkg_ggH")
            plot.subplot(2).add_hist(bkg_ggH, "bkg_ggH_top")
            plot.subplot(2).add_hist(bkg_qqH, "bkg_qqH")
            plot.subplot(2).add_hist(bkg_qqH, "bkg_qqH_top")
            plot.subplot(2).setGraphStyle("bkg_ggH",
                                          "hist",
                                          linecolor=styles.color_dict["ggH"],
                                          linewidth=3)
            plot.subplot(2).setGraphStyle("bkg_ggH_top", "hist", linecolor=0)
            plot.subplot(2).setGraphStyle("bkg_qqH",
                                          "hist",
                                          linecolor=styles.color_dict["qqH"],
                                          linewidth=3)
            plot.subplot(2).setGraphStyle("bkg_qqH_top", "hist", linecolor=0)

            plot.subplot(2).normalize([
                "total_bkg", "bkg_ggH", "bkg_ggH_top", "bkg_qqH",
                "bkg_qqH_top", "data_obs"
            ], "total_bkg")

            # stack background processes
            plot.create_stack(bkg_processes, "stack")

            # normalize stacks by bin-width
            if args.normalize_by_bin_width:
                plot.subplot(0).normalizeByBinWidth()
                plot.subplot(1).normalizeByBinWidth()

            # set axes limits and labels
            plot.subplot(0).setYlims(
                split_dict[channel],
                max(2 * plot.subplot(0).get_hist("total_bkg").GetMaximum(),
                    split_dict[channel] * 2))

            plot.subplot(2).setYlims(0.75, 1.45)
            if channel == "tt" and category == "qqh":
                plot.subplot(2).setYlims(0.75, 2.65)
            if args.linear != True:
                plot.subplot(1).setYlims(0.1, split_dict[channel])
                plot.subplot(1).setLogY()
                plot.subplot(1).setYlabel(
                    "")  # otherwise number labels are not drawn on axis
            if args.gof_variable != None:
                plot.subplot(2).setXlabel(
                    styles.x_label_dict[args.channels[0]][args.gof_variable])
            else:
                plot.subplot(2).setXlabel("NN score")
            if args.normalize_by_bin_width:
                plot.subplot(0).setYlabel("N_{events}/bin width")
            else:
                plot.subplot(0).setYlabel("N_{events}")

            plot.subplot(2).setYlabel("Ratio to Bkg.")

            #plot.scaleXTitleSize(0.8)
            #plot.scaleXLabelSize(0.8)
            #plot.scaleYTitleSize(0.8)
            plot.scaleYLabelSize(0.8)
            #plot.scaleXLabelOffset(2.0)
            plot.scaleYTitleOffset(1.1)

            #plot.subplot(2).setNYdivisions(3, 5)

            # draw subplots. Argument contains names of objects to be drawn in corresponding order.
            plot.subplot(0).Draw(["stack", "total_bkg", "data_obs"])
            if args.linear != True:
                plot.subplot(1).Draw([
                    "stack", "total_bkg", "ggH", "ggH_top", "qqH", "qqH_top",
                    "data_obs"
                ])
            plot.subplot(2).Draw([
                "total_bkg", "bkg_ggH", "bkg_ggH_top", "bkg_qqH",
                "bkg_qqH_top", "data_obs"
            ])

            # create legends
            suffix = ["", "_top"]
            for i in range(2):
                plot.add_legend(width=0.48, height=0.15)
                for process in legend_bkg_processes:
                    plot.legend(i).add_entry(
                        0, process, styles.legend_label_dict[process.replace(
                            "EWK", "EWKZ")], 'f')
                plot.legend(i).add_entry(0, "total_bkg", "Bkg. unc.", 'f')
                plot.legend(i).add_entry(1, "ggH%s" % suffix[i], "ggH", 'l')
                plot.legend(i).add_entry(1, "qqH%s" % suffix[i], "qqH", 'l')
                plot.legend(i).add_entry(0, "data_obs", "Data", 'PE')
                plot.legend(i).setNColumns(3)
            plot.legend(0).Draw()
            plot.legend(1).setAlpha(0.0)
            plot.legend(1).Draw()

            for i in range(2):
                plot.add_legend(reference_subplot=2,
                                pos=1,
                                width=0.5,
                                height=0.03)
                plot.legend(i + 2).add_entry(0, "data_obs", "Data", 'PE')
                plot.legend(i + 2).add_entry(1, "ggH%s" % suffix[i],
                                             "ggH+bkg.", 'l')
                plot.legend(i + 2).add_entry(1, "qqH%s" % suffix[i],
                                             "qqH+bkg.", 'l')
                plot.legend(i + 2).add_entry(0, "total_bkg", "Bkg. unc.", 'f')
                plot.legend(i + 2).setNColumns(4)
            plot.legend(2).Draw()
            plot.legend(3).setAlpha(0.0)
            plot.legend(3).Draw()

            # draw additional labels
            plot.DrawCMS()
            plot.DrawLumi("35.9 fb^{-1} (13 TeV)")
            plot.DrawChannelCategoryLabel(
                "%s, %s" % (channel_dict[channel], category_dict[category]))

            # save plot
            postfix = "prefit" if "prefit" in args.input else "postfit" if "postfit" in args.input else "undefined"
            plot.save(
                "plots/%s_%s_%s.%s" %
                (channel, category, postfix, "png" if args.png else "pdf"))
            plots.append(
                plot
            )  # work around to have clean up seg faults only at the end of the script
Пример #17
0
def main():
    rootfile = rootfile_parser.Rootfile_parser("datacard_shapes_prefit.root")

    # create canvas:
    #   First argument defines subplot structure: List of splits from top to bottom (max. 1.0 to min. 0.0). A split can be a single position or a pair resulting in gap.
    #   Further arguments set general style.
    plot = dd.Plot([0.65, [0.47, 0.45], [0.22, 0.20]],
                   "ModTDR",
                   r=0.04,
                   l=0.14)

    bkg_processes = ["EWK", "QCD", "VV", "W", "TTT", "TTJ", "ZJ", "ZL", "ZTT"]

    # register histograms in the subplots (can be done globally or for specific subplots). regustered histograms are not necessarily plotted later.
    for process in bkg_processes:
        plot.add_hist(
            rootfile.get("mt", "qqh", process), process, "bkg"
        )  # get(channel, category, process) and assign specific name and group name to histogram. The group name is optional.
        plot.setGraphStyle(process,
                           "hist",
                           fillcolor=styles.color_dict[process])
    for i in range(2):
        plot.subplot(i + 1).add_hist(
            rootfile.get("mt", "qqh", "ggH"), "ggH"
        )  # signal histograms are used twice in order to realize a two color line style
        plot.subplot(i + 1).add_hist(rootfile.get("mt", "qqh", "ggH"),
                                     "ggH_top")
        plot.subplot(i + 1).add_hist(rootfile.get("mt", "qqh", "qqH"), "qqH")
        plot.subplot(i + 1).add_hist(rootfile.get("mt", "qqh", "qqH"),
                                     "qqH_top")
    plot.add_hist(rootfile.get("mt", "qqh", "data_obs"), "data_obs")
    plot.add_hist(rootfile.get("mt", "qqh", "TotalBkg"), "unc_band")

    # set some graph styles
    plot.subplot(1).setGraphStyle("ggH",
                                  "hist",
                                  linecolor=styles.color_dict["ggH"],
                                  linewidth=3)
    plot.subplot(1).setGraphStyle("ggH_top", "hist", linecolor=0)
    plot.subplot(1).setGraphStyle("qqH",
                                  "hist",
                                  linecolor=styles.color_dict["qqH"],
                                  linewidth=3)
    plot.subplot(1).setGraphStyle("qqH_top", "hist", linecolor=0)
    plot.setGraphStyle("unc_band",
                       "e2",
                       markersize=0,
                       fillcolor=styles.color_dict["unc"],
                       linecolor=0)

    # in order to show S+B in the ratio plot, add total background to signal hists (get_hist returns a copy) and register the results
    bkg_ggH = plot.subplot(2).get_hist("ggH")
    bkg_qqH = plot.subplot(2).get_hist("qqH")
    bkg_ggH.Add(plot.subplot(2).get_hist("unc_band"))
    bkg_qqH.Add(plot.subplot(2).get_hist("unc_band"))
    plot.subplot(2).add_hist(bkg_ggH, "bkg_ggH")
    plot.subplot(2).add_hist(bkg_ggH, "bkg_ggH_top")
    plot.subplot(2).add_hist(bkg_qqH, "bkg_qqH")
    plot.subplot(2).add_hist(bkg_qqH, "bkg_qqH_top")
    plot.subplot(2).setGraphStyle("bkg_ggH",
                                  "hist",
                                  linecolor=styles.color_dict["ggH"],
                                  linewidth=3)
    plot.subplot(2).setGraphStyle("bkg_ggH_top", "hist", linecolor=0)
    plot.subplot(2).setGraphStyle("bkg_qqH",
                                  "hist",
                                  linecolor=styles.color_dict["qqH"],
                                  linewidth=3)
    plot.subplot(2).setGraphStyle("bkg_qqH_top", "hist", linecolor=0)

    # apply normalizations for the ratio and the background fractions plot:
    # First argument: Name of a single histogram or list of names / group names that shall be normalized
    # Second argument: Name of a single histogram or list of names / group names that shall be contained in the denominator
    plot.subplot(2).normalize([
        "unc_band", "bkg_ggH", "bkg_ggH_top", "bkg_qqH", "bkg_qqH_top",
        "data_obs"
    ], "unc_band")
    #plot.subplot(2).normalize(["unc_band", "bkg_ggH", "bkg_ggH_top", "bkg_qqH", "bkg_qqH_top", "data_obs"], "bkg") # would also work but add up the single bkg histograms in the background
    plot.subplot(3).normalize("bkg", "bkg")

    # stack background histograms for all subplots and assign a name
    plot.create_stack(bkg_processes, "stack")

    # set some axis options
    plot.subplot(0).setYlims(100, 2000)
    plot.subplot(1).setYlims(0.1, 100)
    plot.subplot(2).setYlims(0.81, 1.39)
    plot.subplot(3).setYlims(0.0, 1.0)
    plot.subplot(1).setLogY()
    plot.subplot(3).setXlabel("NN score")
    plot.subplot(0).setYlabel("N_{events}")
    plot.subplot(1).setYlabel(
        "")  # otherwise number labels are not drawn on axis
    plot.subplot(2).setYlabel("ratio to bkg")
    plot.subplot(3).setYlabel("bkg frac.")

    plot.scaleXTitleSize(0.8)
    plot.scaleXLabelSize(0.8)
    plot.scaleYTitleSize(0.8)
    plot.scaleYLabelSize(0.8)
    plot.scaleXLabelOffset(2.0)
    plot.scaleYTitleOffset(1.1)

    plot.subplot(2).setNYdivisions(3, 5)

    # draw subplots. Argument contains names of objects to be drawn in corresponding order.
    plot.subplot(0).Draw(["stack", "unc_band", "data_obs"])
    plot.subplot(1).Draw(
        ["stack", "unc_band", "ggH", "ggH_top", "qqH", "qqH_top", "data_obs"])
    plot.subplot(2).Draw([
        "unc_band", "bkg_ggH", "bkg_ggH_top", "bkg_qqH", "bkg_qqH_top",
        "data_obs"
    ])
    plot.subplot(3).Draw("stack")

    # create legends
    bkg_processes.reverse()
    suffix = ["", "_top"]
    for i in range(2):
        plot.add_legend(width=0.48, height=0.15)
        for process in bkg_processes:
            plot.legend(i).add_entry(
                0, process, styles.label_dict[process.replace("EWK", "EWKZ")],
                'f')
        plot.legend(i).add_entry(0, "unc_band", "Bkg. unc.", 'f')
        plot.legend(i).add_entry(1, "ggH%s" % suffix[i], "ggH", 'l')
        plot.legend(i).add_entry(1, "qqH%s" % suffix[i], "qqH", 'l')
        plot.legend(i).add_entry(0, "data_obs", "Data", 'PE')
        plot.legend(i).setNColumns(3)
    plot.legend(0).Draw()
    plot.legend(1).setAlpha(0.0)
    plot.legend(1).Draw()

    for i in range(2):
        plot.add_legend(reference_subplot=2, pos=1, width=0.4, height=0.03)
        plot.legend(i + 2).add_entry(0, "data_obs", "Data", 'PE')
        plot.legend(i + 2).add_entry(1, "ggH%s" % suffix[i], "ggH+bkg.", 'l')
        plot.legend(i + 2).add_entry(1, "qqH%s" % suffix[i], "qqH+bkg.", 'l')
        plot.legend(i + 2).setNColumns(3)
    plot.legend(2).Draw()
    plot.legend(3).setAlpha(0.0)
    plot.legend(3).Draw()

    # draw additional labels
    plot.DrawCMS()
    plot.DrawLumi("35.9 fb^{-1} (13 TeV)")
    plot.DrawChannelCategoryLabel("#mu#tau_{h}, VBF")

    # save plot
    plot.save("testoutput.pdf")
Пример #18
0
def main(args):
    channel_dict = {
        "mm": "#mu#mu",
    }
    category_dict = {
        "mm_0jet": "0-jet",
        "mm_1jet": "1-jet",
        "mm_ge2jet": "#geq 2-jet",
    }
    processes = [
        "QCD", "VVT", "VVL", "W", "TTT", "TTL", "ZTT", "ZL"
    ]
    legend_processes = copy.deepcopy(processes)
    legend_processes.reverse()

    if "2016" in args.era:
        era = "Run2016"
    elif "2017" in args.era:
        era = "Run2017"
    elif "2018" in args.era:
        era = "Run2018"
    else:
        logger.critical("Era {} is not implemented.".format(args.era))
        raise Exception

    plots = []
    for plottype in ["prefit", "postfit"]:
        for category in category_dict:
            filename = args.input_dir+ "/" + category + "/postfit_shapes.root"
            rootfile = rootfile_parser.Rootfile_parser(filename)
            rootfile._hist_hash = "{category}{plottype}/{process}"
            rootfile._type = plottype

            # create plot
            width = 600
            plot = dd.Plot(
                [0.3, [0.3, 0.28]], "ModTDR", r=0.04, l=0.14, width=width)

            # get background histograms
            print "Getting shapes"
            for process in processes:
                plot.add_hist(
                    rootfile.get(era, "mm", category, process), process, "procs")
                plot.setGraphStyle(
                    process, "hist", fillcolor=styles.color_dict[process])
            print "Finished getting shapes"


            # get observed data and total processes histograms
            plot.add_hist(rootfile.get(era, "mm", category, "data_obs"), "data_obs")
            plot.add_hist(rootfile.get(era, "mm", category, "TotalProcs"), "total_procs")

            plot.subplot(0).setGraphStyle("data_obs", "e0")
            plot.setGraphStyle(
                "total_procs",
                "e2",
                markersize=0,
                fillcolor=styles.color_dict["unc"],
                linecolor=0)

            # assemble ratio
            plot.subplot(2).normalize(["data_obs", "total_procs"], "total_procs")

            # stack background processes
            plot.create_stack(processes, "stack")

            # set axes limits and labels
            plot.subplot(0).setYlims(1.0, float(10**10))
            plot.subplot(2).setYlims(0.45, 2.05)
            plot.subplot(0).setLogY()
            plot.subplot(2).setXlabel("MET #parallel Z")
            plot.subplot(0).setYlabel("N_{events}")
            plot.subplot(2).setYlabel("")
            #plot.scaleXTitleSize(0.8)
            #plot.scaleXLabelSize(0.8)
            #plot.scaleYTitleSize(0.8)
            plot.scaleYLabelSize(0.8)
            #plot.scaleXLabelOffset(2.0)
            plot.scaleYTitleOffset(1.1)

            # draw subplots. Argument contains names of objects to be drawn in corresponding order.
            procs_to_draw = ["stack", "total_procs", "data_obs"]
            plot.subplot(0).Draw(procs_to_draw)
            plot.subplot(2).Draw(["total_procs", "data_obs"])

            # create legends
            for i in range(2):
                plot.add_legend(width=0.6, height=0.15)
                for process in legend_processes:
                    plot.legend(i).add_entry(
                        0, process, styles.legend_label_dict[process.replace("TTL", "TT").replace("VVL", "VV")], 'f')
                plot.legend(i).add_entry(0, "data_obs", "Data", 'PE')
                plot.legend(i).add_entry(0, "total_procs", "Total unc.", 'f')
                plot.legend(i).setNColumns(3)
            plot.legend(0).Draw()
            plot.legend(1).setAlpha(0.0)
            plot.legend(1).Draw()
            for i in range(2):
                plot.add_legend(reference_subplot=2, pos=1, width=0.5, height=0.03)
                plot.legend(i + 2).add_entry(0, "data_obs", "Data", 'PE')
                plot.legend(i + 2).add_entry(0, "total_procs", "Total unc.", 'f')
                plot.legend(i + 2).setNColumns(4)
            plot.legend(2).Draw()
            plot.legend(3).setAlpha(0.0)
            plot.legend(3).Draw()

            # draw additional labels
            plot.DrawCMS()
            if "2016" in args.era:
                plot.DrawLumi("35.9 fb^{-1} (2016, 13 TeV)")
            elif "2017" in args.era:
                plot.DrawLumi("41.5 fb^{-1} (2017, 13 TeV)")
            elif "2018" in args.era:
                plot.DrawLumi("59.7 fb^{-1} (2018, 13 TeV)")
            else:
                logger.critical("Era {} is not implemented.".format(args.era))
                raise Exception

            plot.DrawChannelCategoryLabel(
                "%s, %s" % (channel_dict["mm"], category_dict[category]),
                begin_left=None)

            # save plot
            plot.save("%s_plots_metrecoilfit/%s_%s_%s_%s.%s" % (args.era, args.variable, "mm", category, plottype, "png"))
            plot.save("%s_plots_metrecoilfit/%s_%s_%s_%s.%s" % (args.era, args.variable, "mm", category, plottype, "pdf"))
            plots.append(plot)  # work around to have clean up seg faults only at the end of the script
Пример #19
0
def build_plot(folder, variable, era, type, etabin, plotoptions):

    plot = dd.Plot([[0.25, 0.20]], "ModTDR", r=0.04, l=0.14)

    processes = ["Data", "DY", "Embedding"]
    # iterate over the three rootfiles of the sf fit and load the efficiency curves
    for k, process in enumerate(processes):
        rootfile = rootfile_parser.ScaleFactor_Rootfile_parser(
            "{folder}/{type}_TP_{process}_{era}_Fits_{variable}.root".format(
                folder=folder,
                type=type,
                era=era,
                variable=variable,
                process=process))
        plot.add_hist(rootfile.get(variable, etabin + 1), process)
        plot.setGraphStyle(process,
                           "LE",
                           markersize=0.8,
                           linewidth=2,
                           markershape=21,
                           markercolor=sf_color(process),
                           linecolor=sf_color(process))
        # add subplot(1) for the ratio, and add data twice for 2 ratios
        if 'Data' in process:
            for label in ["Data_Embedding_ratio", "Data_DY_ratio"]:
                plot.subplot(1).add_hist(rootfile.get(variable, etabin + 1),
                                         label)
                plot.subplot(1).setGraphStyle(
                    label,
                    "LE",
                    markersize=0.8,
                    linewidth=2,
                    markershape=21,
                    markercolor=sf_color(label.split("_")[1]),
                    linecolor=sf_color(label.split("_")[1]))
        else:
            plot.subplot(1).add_hist(rootfile.get(variable, etabin + 1),
                                     "{}_ratio".format(process))
            plot.subplot(1).setGraphStyle("{}_ratio".format(process),
                                          "LE",
                                          markersize=0.8,
                                          linewidth=2,
                                          markershape=21,
                                          markercolor=sf_color(process),
                                          linecolor=sf_color(process))
        del (rootfile)
    # normalize the two ratios so they represent the sf: Data/Emb and Data/MC
    plot.subplot(1).normalize("Data_Embedding_ratio", "Embedding_ratio")
    plot.subplot(1).normalize("Data_DY_ratio", "DY_ratio")
    logger.debug("y Range: {} - {}".format(plotoptions['y_range'][0],
                                           plotoptions['y_range'][1]))
    logger.debug("y Subrange: {} - {}".format(plotoptions['ratio_y_range'][0],
                                              plotoptions['ratio_y_range'][1]))
    logger.debug("pT Range: {} - {}".format(plotoptions['ptrange'][0],
                                            int(plotoptions['ptrange'][1])))
    # take ranges from the .yaml settings file
    plot.subplot(0).setYlims(plotoptions['y_range'][0],
                             plotoptions['y_range'][1])
    plot.subplot(1).setYlims(plotoptions['ratio_y_range'][0],
                             plotoptions['ratio_y_range'][1])
    plot.subplot(0).setXlims(plotoptions['ptrange'][0],
                             int(plotoptions['ptrange'][1]))
    plot.subplot(1).setXlims(plotoptions['ptrange'][0],
                             int(plotoptions['ptrange'][1]))
    plot.subplot(0).setLogX()
    plot.subplot(1).setLogX()
    if "muon" in type:
        plot.subplot(1).setXlabel("p_{T}^{#mu} (GeV)")
    elif "electron" in type:
        plot.subplot(1).setXlabel("p_{T}^{e} (GeV)")
    plot.subplot(0).setYlabel("Efficiency")
    plot.subplot(1).setYlabel("Scalefactor")

    plot.scaleXTitleSize(0.8)
    plot.scaleXLabelSize(0.8)
    plot.scaleYTitleSize(0.8)
    plot.scaleYLabelSize(0.8)
    plot.scaleXLabelOffset(2.0)
    plot.scaleYTitleOffset(1.1)
    logger.debug("plotting {} - #eta [{}]".format(
        plotoptions["TITLE"], plotoptions["etarange"].replace("-", ",")))
    # draw subplots. Argument contains names of objects to be drawn in corresponding order.
    plot.subplot(0).Draw(["Data", "Embedding", "DY"])
    plot.subplot(1).Draw(["Data_Embedding_ratio", "Data_DY_ratio"])

    for i in range(2):
        plot.add_legend(width=0.3, height=0.15, pos=6)
        for process in processes:
            plot.legend(i).add_entry(i, process, sf_label(type, process),
                                     'PLE')
        plot.legend(i).setNColumns(1)
    plot.legend(0).Draw()
    plot.legend(1).setAlpha(0.0)
    plot.legend(1).Draw()

    # plot.DrawCMS()
    if "2016" in era:
        plot.DrawLumi("35.9 fb^{-1} (2016, 13 TeV)")
    elif "2017" in era:
        plot.DrawLumi("41.5 fb^{-1} (2017, 13 TeV)")
    elif "2018" in era:
        plot.DrawLumi("59.7 fb^{-1} (2018, 13 TeV)")

    # take plot label from the .yaml settings file
    plot.DrawChannelCategoryLabel("{} - #eta [{}]".format(
        plotoptions["TITLE"], plotoptions["etarange"].replace("-", ",")),
                                  textsize=0.03)
    # save plot

    logger.debug("Saving Plot")
    plot.save(
        "{folder}/{variable}_{type}_{era}_{etarange}_scalefactor.pdf".format(
            folder=plotoptions["outputdir"],
            variable=variable,
            type=type,
            era=era,
            etarange=plotoptions["etarange"]))
    plot.save(
        "{folder}/{variable}_{type}_{era}_{etarange}_scalefactor.png".format(
            folder=plotoptions["outputdir"],
            variable=variable,
            type=type,
            era=era,
            etarange=plotoptions["etarange"]))
Пример #20
0
def main(args):
    if args.gof_variable != None:
        channel_categories = {
            "et": ["100"],
            "mt": ["100"],
            "tt": ["100"],
            "em": ["100"]
        }
    else:
        channel_categories = {
            #"et": ["ztt", "zll", "w", "tt", "ss", "misc"],
            "et": ["12", "15", "11", "13", "14", "16"],
            #"mt": ["ztt", "zll", "w", "tt", "ss", "misc"],
            "mt": ["12", "15", "11", "13", "14", "16"],
            #"tt": ["ztt", "noniso", "misc"]
            "tt": ["12", "17", "16"],
            "em": ["12", "13", "14", "16", "18", "19"]
        }
        if args.categories == "stxs_stage0":
            for channel in ["et", "mt", "tt", "em"]:
                channel_categories[channel] += [
                    "1_A", "1_B", "1_C", "2_A", "2_B"
                ]
        elif args.categories == "stxs_stage1":
            for channel in ["et", "mt", "tt", "em"]:
                channel_categories[channel] += [
                    "1_A", "1_B", "1_C", "2_A", "2_B"
                ]
        else:
            logger.critical("Selected unkown STXS categorization {}",
                            args.categories)
            raise Exception
    channel_dict = {
        "ee": "ee",
        "em": "e#mu",
        "et": "e#tau_{h}",
        "mm": "#mu#mu",
        "mt": "#mu#tau_{h}",
        "tt": "#tau_{h}#tau_{h}"
    }
    if args.gof_variable != None:
        category_dict = {"100": "inclusive"}
    else:
        category_dict = {
            "1": "ggH",
            "2": "qqH",
            "3": "ggH, unrolled",
            "4": "qqH, unrolled",
            "12": "ztt",
            "15": "zll",
            "11": "wjets",
            "13": "tt",
            "14": "qcd",
            "16": "misc",
            "17": "qcd",
            "18": "single top",
            "19": "diboson"
        }
    if args.linear == True:
        split_value = 0
    else:
        if args.normalize_by_bin_width:
            split_value = 10001
        else:
            split_value = 101

    split_dict = {c: split_value for c in ["et", "mt", "tt", "em"]}

    bkg_processes = ["VVL", "TTL", "ZL", "jetFakes", "EMB"]
    if not args.fake_factor and args.embedding:
        bkg_processes = ["QCD", "VVJ", "W", "TTJ", "ZJ", "ZL", "EMB"]
    if not args.embedding and args.fake_factor:
        bkg_processes = [
            "VVT", "VVJ", "TTT", "TTJ", "ZJ", "ZL", "jetFakes", "ZTT"
        ]
    if not args.embedding and not args.fake_factor:
        bkg_processes = [
            "QCD", "VVT", "VVL", "VVJ", "W", "TTT", "TTL", "TTJ", "ZJ", "ZL",
            "ZTT"
        ]
    all_bkg_processes = [b for b in bkg_processes]
    legend_bkg_processes = copy.deepcopy(bkg_processes)
    legend_bkg_processes.reverse()

    if "2016" in args.era:
        era = "Run2016"
    elif "2017" in args.era:
        era = "Run2017"
    else:
        logger.critical("Era {} is not implemented.".format(args.era))
        raise Exception

    plots = []
    for channel in args.channels:
        for category in channel_categories[channel]:
            rootfile = rootfile_parser.Rootfile_parser(args.input)
            tranche = None
            if "_" in category:
                tranche = category.split("_")[1]
                category = category.split("_")[0]
            if channel == "tt" and category == "2":
                bkg_processes = [b for b in all_bkg_processes]
            elif channel == "em" and args.embedding:
                bkg_processes = ["ST", "VV", "W", "TT", "ZL", "QCD", "EMB"]
            elif channel == "em" and not args.embedding:
                bkg_processes = ["ST", "VV", "W", "TT", "ZL", "QCD", "ZTT"]
            else:
                bkg_processes = [b for b in all_bkg_processes]
            legend_bkg_processes = copy.deepcopy(bkg_processes)
            legend_bkg_processes.reverse()
            # create plot
            width = 600
            if args.categories == "stxs_stage1":
                if category == "2" or (category == "1" and tranche != "A"):
                    width = 1200
            if args.linear == True:
                plot = dd.Plot([0.3, [0.3, 0.28]],
                               "ModTDR",
                               r=0.04,
                               l=0.14,
                               width=width)
            else:
                plot = dd.Plot([0.5, [0.3, 0.28]],
                               "ModTDR",
                               r=0.04,
                               l=0.14,
                               width=width)

            # get background histograms
            for process in bkg_processes:
                plot.add_hist(rootfile.get(era, channel, category, process),
                              process, "bkg")
                plot.setGraphStyle(process,
                                   "hist",
                                   fillcolor=styles.color_dict[process])

            # get signal histograms
            plot_idx_to_add_signal = [0, 2] if args.linear else [1, 2]
            for i in plot_idx_to_add_signal:
                plot.subplot(i).add_hist(
                    rootfile.get(era, channel, category, "ggH"), "ggH")
                plot.subplot(i).add_hist(
                    rootfile.get(era, channel, category, "ggH"), "ggH_top")
                plot.subplot(i).add_hist(
                    rootfile.get(era, channel, category, "qqH"), "qqH")
                plot.subplot(i).add_hist(
                    rootfile.get(era, channel, category, "qqH"), "qqH_top")
                VHhist = rootfile.get(era, channel, category,
                                      "ZH125").Clone("VH")
                VHhist.Add(rootfile.get(era, channel, category, "WH125"))
                plot.subplot(i).add_hist(VHhist, "VH")
                plot.subplot(i).add_hist(VHhist, "VH_top")

            # get observed data and total background histograms
            # NOTE: With CMSSW_8_1_0 the TotalBkg definition has changed.
            plot.add_hist(rootfile.get(era, channel, category, "data_obs"),
                          "data_obs")
            total_bkg = rootfile.get(era, channel, category, "TotalBkg")
            ggHHist = rootfile.get(era, channel, category, "ggH")
            qqHHist = rootfile.get(era, channel, category, "qqH")
            total_bkg.Add(ggHHist, -1)
            total_bkg.Add(qqHHist, -1)
            plot.add_hist(total_bkg, "total_bkg")

            plot.subplot(0).setGraphStyle("data_obs", "e0")
            plot.subplot(0 if args.linear else 1).setGraphStyle(
                "ggH", "hist", linecolor=styles.color_dict["ggH"], linewidth=3)
            plot.subplot(0 if args.linear else 1).setGraphStyle("ggH_top",
                                                                "hist",
                                                                linecolor=0)
            plot.subplot(0 if args.linear else 1).setGraphStyle(
                "qqH", "hist", linecolor=styles.color_dict["qqH"], linewidth=3)
            plot.subplot(0 if args.linear else 1).setGraphStyle("qqH_top",
                                                                "hist",
                                                                linecolor=0)
            plot.subplot(0 if args.linear else 1).setGraphStyle(
                "VH", "hist", linecolor=styles.color_dict["VH"], linewidth=3)
            plot.subplot(0 if args.linear else 1).setGraphStyle("VH_top",
                                                                "hist",
                                                                linecolor=0)
            plot.setGraphStyle("total_bkg",
                               "e2",
                               markersize=0,
                               fillcolor=styles.color_dict["unc"],
                               linecolor=0)

            # assemble ratio
            bkg_ggH = plot.subplot(2).get_hist("ggH")
            bkg_qqH = plot.subplot(2).get_hist("qqH")
            bkg_VH = plot.subplot(2).get_hist("VH")
            bkg_ggH.Add(plot.subplot(2).get_hist("total_bkg"))
            bkg_qqH.Add(plot.subplot(2).get_hist("total_bkg"))
            bkg_VH.Add(plot.subplot(2).get_hist("total_bkg"))
            plot.subplot(2).add_hist(bkg_ggH, "bkg_ggH")
            plot.subplot(2).add_hist(bkg_ggH, "bkg_ggH_top")
            plot.subplot(2).add_hist(bkg_qqH, "bkg_qqH")
            plot.subplot(2).add_hist(bkg_qqH, "bkg_qqH_top")
            plot.subplot(2).add_hist(bkg_VH, "bkg_VH")
            plot.subplot(2).add_hist(bkg_VH, "bkg_VH_top")
            plot.subplot(2).setGraphStyle("bkg_ggH",
                                          "hist",
                                          linecolor=styles.color_dict["ggH"],
                                          linewidth=3)
            plot.subplot(2).setGraphStyle("bkg_ggH_top", "hist", linecolor=0)
            plot.subplot(2).setGraphStyle("bkg_qqH",
                                          "hist",
                                          linecolor=styles.color_dict["qqH"],
                                          linewidth=3)
            plot.subplot(2).setGraphStyle("bkg_qqH_top", "hist", linecolor=0)
            plot.subplot(2).setGraphStyle("bkg_VH",
                                          "hist",
                                          linecolor=styles.color_dict["VH"],
                                          linewidth=3)
            plot.subplot(2).setGraphStyle("bkg_VH_top", "hist", linecolor=0)

            plot.subplot(2).normalize([
                "total_bkg", "bkg_ggH", "bkg_ggH_top", "bkg_qqH",
                "bkg_qqH_top", "bkg_VH", "bkg_VH_top", "data_obs"
            ], "total_bkg")

            # stack background processes
            plot.create_stack(bkg_processes, "stack")

            # normalize stacks by bin-width
            if args.normalize_by_bin_width:
                plot.subplot(0).normalizeByBinWidth()
                plot.subplot(1).normalizeByBinWidth()

            # set axes limits and labels
            plot.subplot(0).setYlims(
                split_dict[channel],
                max(2 * plot.subplot(0).get_hist("total_bkg").GetMaximum(),
                    split_dict[channel] * 2))

            plot.subplot(2).setYlims(0.75, 1.45)
            if category in ["2"]:
                plot.subplot(2).setYlims(0.55, 2.05)
            if category in ["1", "2"]:
                plot.subplot(0).setLogY()
                plot.subplot(0).setYlims(
                    0.1, 15000000 if channel in ["et", "mt"]
                    and category == "1" and tranche == "A" else 150000)
                if channel == "em":
                    plot.subplot(0).setYlims(1, 15000000)

            if args.linear != True:
                plot.subplot(1).setYlims(0.1, split_dict[channel])
                plot.subplot(1).setLogY()
                plot.subplot(1).setYlabel(
                    "")  # otherwise number labels are not drawn on axis
            if args.gof_variable != None:
                if args.gof_variable in styles.x_label_dict[args.channels[0]]:
                    x_label = styles.x_label_dict[args.channels[0]][
                        args.gof_variable]
                else:
                    x_label = args.gof_variable
                plot.subplot(2).setXlabel(x_label)
            else:
                plot.subplot(2).setXlabel("NN output")
            if args.normalize_by_bin_width:
                plot.subplot(0).setYlabel("dN/d(NN output)")
            else:
                plot.subplot(0).setYlabel("N_{events}")

            plot.subplot(2).setYlabel("")

            #plot.scaleXTitleSize(0.8)
            #plot.scaleXLabelSize(0.8)
            #plot.scaleYTitleSize(0.8)
            plot.scaleYLabelSize(0.8)
            #plot.scaleXLabelOffset(2.0)
            plot.scaleYTitleOffset(1.1)

            #plot.subplot(2).setNYdivisions(3, 5)

            if args.categories == "stxs_stage1":
                if not channel == "tt":
                    plot.subplot(2).changeXLabels(
                        [" ", "0.25", " ", "0.50", " ", "0.75", " ", " "])
                if category in ["1"]:
                    selection = None
                    if tranche == "A":
                        selection = [0]
                    elif tranche == "B":
                        selection = [1, 2, 3, 4]
                    elif tranche == "C":
                        selection = [5, 6, 7, 8]
                    if not channel == "tt":
                        plot.setNXdivisions(7, 0, 4, False)
                    #else:
                    #    plot.setNXdivisions(4, 0, 0, False)
                    #plot.scaleXLabelSize(0.5)
                    plot.unroll([
                        "0J", "1J_PTH_0_60", "1J_PTH_60_120", "1J_PTH_120_200",
                        "1J_PTH_GT200", "GE2J_PTH_0_60", "GE2J_PTH_60_120",
                        "GE2J_PTH_120_200", "GE2J_PTH_GT200"
                    ],
                                ur_label_size=0.5,
                                pads_to_print_labels=[],
                                selection=selection)
                if category in ["2"]:
                    selection = None
                    if tranche == "A":
                        selection = [0, 1]
                    elif tranche == "B":
                        selection = [2, 3, 4]
                    if not channel == "tt":
                        plot.setNXdivisions(7, 0, 4, False)
                    plot.unroll([
                        "VBFTOPO_JET3VETO", "VBFTOPO_JET3", "VH2JET", "REST",
                        "PTJET1_GT200"
                    ],
                                ur_label_size=0.9,
                                pads_to_print_labels=[],
                                selection=selection)
            if not channel == "tt" and category in [
                    "11", "12", "13", "14", "15", "16"
            ]:
                plot.subplot(2).changeXLabels(
                    ["0.2", "0.4", "0.6", "0.8", "1.0"])

            # draw subplots. Argument contains names of objects to be drawn in corresponding order.
            procs_to_draw = [
                "stack", "total_bkg", "ggH", "ggH_top", "qqH", "qqH_top", "VH",
                "VH_top", "data_obs"
            ] if args.linear else ["stack", "total_bkg", "data_obs"]
            plot.subplot(0).Draw(procs_to_draw)
            if args.linear != True:
                plot.subplot(1).Draw([
                    "stack", "total_bkg", "ggH", "ggH_top", "qqH", "qqH_top",
                    "VH", "VH_top", "data_obs"
                ])
            plot.subplot(2).Draw([
                "total_bkg", "bkg_ggH", "bkg_ggH_top", "bkg_qqH",
                "bkg_qqH_top", "data_obs"
            ])

            # create legends
            suffix = ["", "_top"]
            for i in range(2):

                plot.add_legend(
                    width=0.3 if args.categories == "stxs_stage1" and
                    (category == "2" or
                     (category == "1" and tranche != "A")) else 0.6,
                    height=0.15)
                for process in legend_bkg_processes:
                    plot.legend(i).add_entry(
                        0, process, styles.legend_label_dict[process.replace(
                            "TTL", "TT").replace("VVL", "VV")], 'f')
                plot.legend(i).add_entry(0, "total_bkg", "Bkg. unc.", 'f')
                plot.legend(i).add_entry(0 if args.linear else 1,
                                         "ggH%s" % suffix[i], "gg#rightarrowH",
                                         'l')
                plot.legend(i).add_entry(0 if args.linear else 1,
                                         "qqH%s" % suffix[i], "qq#rightarrowH",
                                         'l')
                plot.legend(i).add_entry(0 if args.linear else 1,
                                         "VH%s" % suffix[i], "qq#rightarrowVH",
                                         'l')
                plot.legend(i).add_entry(0, "data_obs", "Data", 'PE')
                plot.legend(i).setNColumns(3)
            plot.legend(0).Draw()
            plot.legend(1).setAlpha(0.0)
            plot.legend(1).Draw()

            if args.chi2test:
                import ROOT as r
                f = r.TFile(args.input, "read")
                background = f.Get("htt_{}_{}_Run{}_{}/TotalBkg".format(
                    channel, category, args.era,
                    "prefit" if "prefit" in args.input else "postfit"))
                data = f.Get("htt_{}_{}_Run{}_{}/data_obs".format(
                    channel, category, args.era,
                    "prefit" if "prefit" in args.input else "postfit"))
                chi2 = data.Chi2Test(background, "UW CHI2/NDF")
                plot.DrawText(0.7, 0.3,
                              "\chi^{2}/ndf = " + str(round(chi2, 3)))

            for i in range(2):
                plot.add_legend(reference_subplot=2,
                                pos=1,
                                width=0.5,
                                height=0.03)
                plot.legend(i + 2).add_entry(0, "data_obs", "Data", 'PE')
                plot.legend(i + 2).add_entry(0 if args.linear else 1,
                                             "ggH%s" % suffix[i], "ggH+bkg.",
                                             'l')
                plot.legend(i + 2).add_entry(0 if args.linear else 1,
                                             "qqH%s" % suffix[i], "qqH+bkg.",
                                             'l')
                plot.legend(i + 2).add_entry(0, "total_bkg", "Bkg. unc.", 'f')
                plot.legend(i + 2).setNColumns(4)
            plot.legend(2).Draw()
            plot.legend(3).setAlpha(0.0)
            plot.legend(3).Draw()

            # draw additional labels
            plot.DrawCMS()
            if "2016" in args.era:
                plot.DrawLumi("35.9 fb^{-1} (2016, 13 TeV)")
            elif "2017" in args.era:
                plot.DrawLumi("41.5 fb^{-1} (2017, 13 TeV)")
            else:
                logger.critical("Era {} is not implemented.".format(args.era))
                raise Exception

            posChannelCategoryLabelLeft = None
            if args.categories == "stxs_stage1":
                if category in ["1", "2"]:
                    posChannelCategoryLabelLeft = 0.075
            plot.DrawChannelCategoryLabel(
                "%s, %s" % (channel_dict[channel], category_dict[category]),
                begin_left=posChannelCategoryLabelLeft)

            # save plot
            postfix = "prefit" if "prefit" in args.input else "postfit" if "postfit" in args.input else "undefined"
            plot.save("%s_plots/%s_%s_%s_%s.%s" %
                      (args.era, args.era, channel, args.gof_variable
                       if args.gof_variable is not None else category
                       if tranche == None else "_".join([category, tranche]),
                       postfix, "png" if args.png else "pdf"))
            plots.append(
                plot
            )  # work around to have clean up seg faults only at the end of the script
def main(args):
    #### plot signals
    if args.background_only:
        stxs_stage1p1_cats = []
    else:
        stxs_stage1p1_cats = [str(100 + i) for i in range(5)
                              ] + [str(200 + i) for i in range(4)]
    print(args)
    if args.gof_variable != None:
        channel_categories = {
            "et": ["300"],
            "mt": ["300"],
            "tt": ["300"],
            "em": ["300"]
        }
    else:
        channel_categories = {
            #"et": ["ztt", "zll", "w", "tt", "ss", "misc"],
            "et": ["12", "15", "11", "13", "14", "16"],
            #"mt": ["ztt", "zll", "w", "tt", "ss", "misc"],
            "mt": ["12", "15", "11", "13", "14", "16"],
            #"tt": ["ztt", "noniso", "misc"]
            "tt": ["12", "17", "16"],
            #"em": ["ztt", "tt", "ss", "misc", "db"]
            "em": ["12", "13", "14", "16", "19"]
        }
        if args.train_emb:  #swap ztt for embedding
            for chn in ["em", "mt", "et", "tt"]:
                channel_categories[chn].remove("12")
                channel_categories[chn].append("20")
        if args.train_ff:
            for chn in ["mt", "et", "tt"]:  # no change for em
                if chn == "tt":
                    channel_categories[chn].remove("17")
                else:
                    channel_categories[chn].remove("11")
                    channel_categories[chn].remove("14")
                channel_categories[chn].append("21")  # add ff
        if args.categories == "stxs_stage0":
            for channel in ["et", "mt", "tt", "em"]:
                channel_categories[channel] += ["1", "2"]
        elif args.categories == "stxs_stage1p1":
            for channel in ["et", "mt", "tt", "em"]:
                channel_categories[channel] += stxs_stage1p1_cats
        elif args.categories == "backgrounds":
            pass
        else:
            logger.critical("Selected unkown STXS categorization {}",
                            args.categories)
            raise Exception
    channel_dict = {
        "ee": "ee",
        "em": "e#mu",
        "et": "e#tau_{h}",
        "mm": "#mu#mu",
        "mt": "#mu#tau_{h}",
        "tt": "#tau_{h}#tau_{h}"
    }
    if args.gof_variable != None:
        category_dict = {"300": "inclusive"}
    else:
        category_dict = {
            "1": "ggh",
            "100": "ggh 0-jet",
            "101": "ggh 1-jet p_{T}^{H} [0,120]",
            "102": "ggh 1-jet p_{T}^{H} [120,200]",
            "103": "ggh #geq 2-jet",
            "104": "ggh p_{T}^{H}>200",
            "2": "qqh",
            "200": "qqh 2J low mjj",
            "201": "qqh p_{T}^{H}>200",
            "202": "qqh vbftopo mjj>700",
            "203": "qqh vbftopo mjj [350,700]",
            "12": "ztt",
            "15": "zll",
            "11": "wjets",
            "13": "tt",
            "14": "qcd",
            "16": "misc",
            "17": "qcd",
            "19": "diboson",
            "20": "Genuine #tau",
            "21": "Jet #rightarrow #tau_{h}"
        }
    if args.linear == True:
        split_value = 0
    else:
        if args.normalize_by_bin_width:
            split_value = 10001
        else:
            split_value = 101

    split_dict = {c: split_value for c in ["et", "mt", "tt", "em"]}

    bkg_processes = ["VVL", "TTL", "ZL", "jetFakes", "EMB"]
    if not args.fake_factor and args.embedding:
        bkg_processes = ["QCD", "VVJ", "W", "TTJ", "ZJ", "ZL", "EMB"]
    if not args.embedding and args.fake_factor:
        bkg_processes = ["VVT", "VVL", "TTT", "TTL", "ZL", "jetFakes", "ZTT"]
    if not args.embedding and not args.fake_factor:
        bkg_processes = [
            "QCD", "VVT", "VVL", "VVJ", "W", "TTT", "TTL", "TTJ", "ZJ", "ZL",
            "ZTT"
        ]
    all_bkg_processes = [b for b in bkg_processes]
    legend_bkg_processes = copy.deepcopy(bkg_processes)
    legend_bkg_processes.reverse()

    if "2016" in args.era:
        era = "2016"
    elif "2017" in args.era:
        era = "2017"
    elif "2018" in args.era:
        era = "2018"
    else:
        logger.critical("Era {} is not implemented.".format(args.era))
        raise Exception
    print(channel_categories)
    plots = []
    for channel in args.channels:
        for category in channel_categories[channel]:
            print "Plot for category: ", category
            rootfile = rootfile_parser.Rootfile_parser(args.input)
            if channel == "em" and args.embedding:
                bkg_processes = ["VVL", "W", "TTL", "ZL", "QCD", "EMB"]
            elif channel == "em" and not args.embedding:
                bkg_processes = ["VVL", "W", "TTL", "ZL", "QCD", "ZTT"]
            else:
                bkg_processes = [b for b in all_bkg_processes]
            legend_bkg_processes = copy.deepcopy(bkg_processes)
            legend_bkg_processes.reverse()
            # create plot
            width = 600
            if args.linear == True:
                plot = dd.Plot([0.3, [0.3, 0.28]],
                               "ModTDR",
                               r=0.04,
                               l=0.14,
                               width=width)
            else:
                plot = dd.Plot([0.5, [0.3, 0.28]],
                               "ModTDR",
                               r=0.04,
                               l=0.14,
                               width=width)

            # get background histograms
            for process in bkg_processes:
                try:
                    if channel == "tt" and process == "jetFakes":
                        jetfakes = rootfile.get(era, channel, category,
                                                process).Clone()
                        jetfakes.Add(
                            rootfile.get(era, channel, category, "wFakes"))
                        plot.add_hist(jetfakes, process, "bkg")
                    else:
                        plot.add_hist(
                            rootfile.get(era, channel, category, process),
                            process, "bkg")
                    plot.setGraphStyle(process,
                                       "hist",
                                       fillcolor=styles.color_dict[process])
                except:
                    pass

            # get signal histograms
            plot_idx_to_add_signal = [0, 2] if args.linear else [1, 2]
            for i in plot_idx_to_add_signal:
                try:
                    plot.subplot(i).add_hist(
                        check_for_zero_bins(
                            rootfile.get(era, channel, category, "ggH125")),
                        "ggH")
                    plot.subplot(i).add_hist(
                        check_for_zero_bins(
                            rootfile.get(era, channel, category, "ggH125")),
                        "ggH_top")
                    plot.subplot(i).add_hist(
                        check_for_zero_bins(
                            rootfile.get(era, channel, category, "qqH125")),
                        "qqH")
                    plot.subplot(i).add_hist(
                        check_for_zero_bins(
                            rootfile.get(era, channel, category, "qqH125")),
                        "qqH_top")
                    if not args.plot_restricted_signals:
                        if isinstance(
                                rootfile.get(era, channel, category, "ZH125"),
                                ROOT.TH1):
                            VHhist = rootfile.get(era, channel, category,
                                                  "ZH125").Clone("VH")
                        WHhist = rootfile.get(era, channel, category, "WH125")
                        if isinstance(WHhist, ROOT.TH1) and VHhist:
                            VHhist.Add(WHhist)
                        elif WHhist:
                            VHhist = WHhist
                        plot.subplot(i).add_hist(VHhist, "VH")
                        plot.subplot(i).add_hist(VHhist, "VH_top")

                        if isinstance(
                                rootfile.get(era, channel, category, "ttH125"),
                                ROOT.TH1):
                            plot.subplot(i).add_hist(
                                rootfile.get(era, channel, category, "ttH125"),
                                "ttH")
                            plot.subplot(i).add_hist(
                                rootfile.get(era, channel, category, "ttH125"),
                                "ttH_top")

                        HWWhist = rootfile.get(era, channel, category,
                                               "ggHWW125")
                        if isinstance(
                                rootfile.get(era, channel, category,
                                             "ggHWW125"), ROOT.TH1):
                            HWWhist = rootfile.get(
                                era, channel, category,
                                "ggHWW125").Clone("ggHWW125")
                        qqHWWhist = rootfile.get(era, channel, category,
                                                 "qqHWW125")
                        if isinstance(qqHWWhist, ROOT.TH1) and HWWhist:
                            HWWhist.Add(qqHWWhist)
                        elif qqHWWhist:
                            HWWhist = qqHWWhist
                        plot.subplot(i).add_hist(HWWhist, "HWW")
                        plot.subplot(i).add_hist(HWWhist, "HWW_top")
                except:
                    pass

            # get observed data and total background histograms
            # NOTE: With CMSSW_8_1_0 the TotalBkg definition has changed.
            print("plot.add_hist(rootfile.get(" + era + ", " + channel + ", " +
                  category + ', "data_obs")')
            plot.add_hist(rootfile.get(era, channel, category, "data_obs"),
                          "data_obs")
            total_bkg = check_for_zero_bins(
                rootfile.get(era, channel, category, "TotalBkg"))
            #ggHHist = rootfile.get(era, channel, category, "ggH")
            #qqHHist = rootfile.get(era, channel, category, "qqH")
            #total_bkg.Add(ggHHist, -1)
            #if qqHHist:
            #     total_bkg.Add(qqHHist, -1)
            plot.add_hist(total_bkg, "total_bkg")

            plot.subplot(0).setGraphStyle("data_obs", "e0")
            plot.subplot(0 if args.linear else 1).setGraphStyle(
                "ggH", "hist", linecolor=styles.color_dict["ggH"], linewidth=3)
            plot.subplot(0 if args.linear else 1).setGraphStyle("ggH_top",
                                                                "hist",
                                                                linecolor=0)
            plot.subplot(0 if args.linear else 1).setGraphStyle(
                "qqH", "hist", linecolor=styles.color_dict["qqH"], linewidth=3)
            plot.subplot(0 if args.linear else 1).setGraphStyle("qqH_top",
                                                                "hist",
                                                                linecolor=0)
            if not args.plot_restricted_signals:
                plot.subplot(0 if args.linear else 1).setGraphStyle(
                    "VH",
                    "hist",
                    linecolor=styles.color_dict["VH"],
                    linewidth=3)
                plot.subplot(0 if args.linear else 1).setGraphStyle(
                    "VH_top", "hist", linecolor=0)
                plot.subplot(0 if args.linear else 1).setGraphStyle(
                    "ttH",
                    "hist",
                    linecolor=styles.color_dict["ttH"],
                    linewidth=3)
                plot.subplot(0 if args.linear else 1).setGraphStyle(
                    "ttH_top", "hist", linecolor=0)
                plot.subplot(0 if args.linear else 1).setGraphStyle(
                    "HWW",
                    "hist",
                    linecolor=styles.color_dict["HWW"],
                    linewidth=3)
                plot.subplot(0 if args.linear else 1).setGraphStyle(
                    "HWW_top", "hist", linecolor=0)
            plot.setGraphStyle("total_bkg",
                               "e2",
                               markersize=0,
                               fillcolor=styles.color_dict["unc"],
                               linecolor=0)

            # assemble ratio
            bkg_ggH = plot.subplot(2).get_hist("ggH")
            bkg_qqH = plot.subplot(2).get_hist("qqH")
            bkg_ggH.Add(plot.subplot(2).get_hist("total_bkg"))
            if bkg_qqH:
                bkg_qqH.Add(plot.subplot(2).get_hist("total_bkg"))
            plot.subplot(2).add_hist(bkg_ggH, "bkg_ggH")
            plot.subplot(2).add_hist(bkg_ggH, "bkg_ggH_top")
            plot.subplot(2).add_hist(bkg_qqH, "bkg_qqH")
            plot.subplot(2).add_hist(bkg_qqH, "bkg_qqH_top")
            plot.subplot(2).setGraphStyle("bkg_ggH",
                                          "hist",
                                          linecolor=styles.color_dict["ggH"],
                                          linewidth=3)
            plot.subplot(2).setGraphStyle("bkg_ggH_top", "hist", linecolor=0)
            plot.subplot(2).setGraphStyle("bkg_qqH",
                                          "hist",
                                          linecolor=styles.color_dict["qqH"],
                                          linewidth=3)
            plot.subplot(2).setGraphStyle("bkg_qqH_top", "hist", linecolor=0)

            plot.subplot(2).normalize([
                "total_bkg", "bkg_ggH", "bkg_ggH_top", "bkg_qqH",
                "bkg_qqH_top", "data_obs"
            ], "total_bkg")

            # stack background processes
            plot.create_stack(bkg_processes, "stack")

            # normalize stacks by bin-width
            if args.normalize_by_bin_width:
                plot.subplot(0).normalizeByBinWidth()
                plot.subplot(1).normalizeByBinWidth()

            # set axes limits and labels
            plot.subplot(0).setYlims(
                split_dict[channel],
                max(2 * plot.subplot(0).get_hist("data_obs").GetMaximum(),
                    split_dict[channel] * 2))

            if args.gof_variable is None:
                plot.subplot(2).setYlims(0.45, 2.05)
            else:
                plot.subplot(2).setYlims(0.85, 1.25)
            if category in ["1", "2"] + stxs_stage1p1_cats:
                plot.subplot(0).setLogY()
                plot.subplot(0).setYlims(0.1, 150000000)
                if channel == "em":
                    plot.subplot(0).setYlims(1, 150000000)

            if not args.linear:
                plot.subplot(1).setYlims(0.1, split_dict[channel])
                plot.subplot(1).setLogY()
                plot.subplot(1).setYlabel(
                    "")  # otherwise number labels are not drawn on axis
            if args.gof_variable != None:
                gof_log_vars = []
                if args.gof_variable in gof_log_vars:
                    plot.subplot(0).setLogX()
                    plot.subplot(1).setLogX()
                    plot.subplot(2).setLogX()
                elif args.gof_variable in ["njets_red", "nbtag_red"]:
                    bins = plot.subplot(2).get_hist("data_obs").GetNbinsX()
                    bin_labels = map(str, range(bins - 1))
                    bin_labels.append("#geq%i" % (bins - 1))
                    plot.subplot(2).setNXdivisions(bins, 0, 2)
                    plot.subplot(2).changeXLabels(bin_labels)
                if args.gof_variable in styles.x_label_dict[args.channels[0]]:
                    x_label = styles.x_label_dict[args.channels[0]][
                        args.gof_variable]
                else:
                    x_label = args.gof_variable
                plot.subplot(2).setXlabel(x_label)
            elif args.gof_variable != None and args.linear:
                if args.gof_variable in styles.x_label_dict[args.channels[0]]:
                    x_label = styles.x_label_dict[args.channels[0]][
                        args.gof_variable]
                else:
                    x_label = args.gof_variable
                plot.subplot(2).setXlabel(x_label)
            else:
                plot.subplot(2).setXlabel("NN output")
            if args.normalize_by_bin_width:
                plot.subplot(0).setYlabel("dN/d(%s)" % args.gof_variable)
            else:
                plot.subplot(0).setYlabel("N_{events}")

            plot.subplot(2).setYlabel("")

            #plot.scaleXTitleSize(0.8)
            #plot.scaleXLabelSize(0.8)
            #plot.scaleYTitleSize(0.8)
            plot.scaleYLabelSize(0.8)
            #plot.scaleXLabelOffset(2.0)
            plot.scaleYTitleOffset(1.1)

            #plot.subplot(2).setNYdivisions(3, 5)

            #if not channel == "tt" and category in ["11", "12", "13", "14", "15", "16"]:
            #    plot.subplot(2).changeXLabels(["0.2", "0.4", "0.6", "0.8", "1.0"])

            # draw subplots. Argument contains names of objects to be drawn in corresponding order.
            if args.plot_restricted_signals:
                procs_to_draw = [
                    "stack", "total_bkg", "ggH", "ggH_top", "qqH", "qqH_top",
                    "data_obs"
                ] if args.linear else ["stack", "total_bkg", "data_obs"]
            else:
                procs_to_draw = [
                    "stack", "total_bkg", "ggH", "ggH_top", "qqH", "qqH_top",
                    "VH", "VH_top", "ttH", "ttH_top", "HWW", "HWW_top",
                    "data_obs"
                ] if args.linear else ["stack", "total_bkg", "data_obs"]
            plot.subplot(0).Draw(procs_to_draw)
            if args.linear != True:
                if args.plot_restricted_signals:
                    plot.subplot(1).Draw([
                        "stack", "total_bkg", "ggH", "ggH_top", "qqH",
                        "qqH_top", "data_obs"
                    ])
                else:
                    plot.subplot(1).Draw([
                        "stack", "total_bkg", "ggH", "ggH_top", "qqH",
                        "qqH_top", "VH", "VH_top", "ttH", "ttH_top", "HWW",
                        "HWW_top", "data_obs"
                    ])
            plot.subplot(2).Draw([
                "total_bkg", "bkg_ggH", "bkg_ggH_top", "bkg_qqH",
                "bkg_qqH_top", "data_obs"
            ])

            # create legends
            suffix = ["", "_top"]
            for i in range(2):

                plot.add_legend(width=0.6, height=0.15)
                for process in legend_bkg_processes:
                    try:
                        plot.legend(i).add_entry(
                            0, process,
                            styles.legend_label_dict[process.replace(
                                "TTL", "TT").replace("VVL", "VV")], 'f')
                    except:
                        pass
                plot.legend(i).add_entry(0, "total_bkg", "Bkg. unc.", 'f')
                plot.legend(i).add_entry(0 if args.linear else 1,
                                         "ggH%s" % suffix[i], "gg#rightarrowH",
                                         'l')
                plot.legend(i).add_entry(0 if args.linear else 1,
                                         "qqH%s" % suffix[i], "qq#rightarrowH",
                                         'l')
                if not args.plot_restricted_signals:
                    plot.legend(i).add_entry(0 if args.linear else 1,
                                             "VH%s" % suffix[i],
                                             "qq#rightarrowVH", 'l')
                    try:
                        plot.legend(i).add_entry(0 if args.linear else 1,
                                                 "ttH%s" % suffix[i], "ttH",
                                                 'l')
                        plot.legend(i).add_entry(0 if args.linear else 1,
                                                 "HWW%s" % suffix[i],
                                                 "H#rightarrowWW", 'l')
                    except:
                        pass
                plot.legend(i).add_entry(0, "data_obs", "Data", 'PE')
                plot.legend(i).setNColumns(3)
            plot.legend(0).Draw()
            plot.legend(1).setAlpha(0.0)
            plot.legend(1).Draw()

            if args.chi2test:
                import ROOT as r
                f = r.TFile(args.input, "read")
                background = f.Get("htt_{}_{}_Run{}_{}/TotalBkg".format(
                    channel, category, args.era,
                    "prefit" if "prefit" in args.input else "postfit"))
                data = f.Get("htt_{}_{}_Run{}_{}/data_obs".format(
                    channel, category, args.era,
                    "prefit" if "prefit" in args.input else "postfit"))
                chi2 = data.Chi2Test(background, "UW CHI2/NDF")
                plot.DrawText(0.7, 0.3,
                              "\chi^{2}/ndf = " + str(round(chi2, 3)))

            for i in range(2):
                plot.add_legend(reference_subplot=2,
                                pos=1,
                                width=0.5,
                                height=0.03)
                plot.legend(i + 2).add_entry(0, "data_obs", "Data", 'PE')
                plot.legend(i + 2).add_entry(0 if args.linear else 1,
                                             "ggH%s" % suffix[i], "ggH+bkg.",
                                             'l')
                plot.legend(i + 2).add_entry(0 if args.linear else 1,
                                             "qqH%s" % suffix[i], "qqH+bkg.",
                                             'l')
                plot.legend(i + 2).add_entry(0, "total_bkg", "Bkg. unc.", 'f')
                plot.legend(i + 2).setNColumns(4)
            plot.legend(2).Draw()
            plot.legend(3).setAlpha(0.0)
            plot.legend(3).Draw()

            # draw additional labels
            plot.DrawCMS()
            if "2016" in args.era:
                plot.DrawLumi("35.9 fb^{-1} (2016, 13 TeV)")
            elif "2017" in args.era:
                plot.DrawLumi("41.5 fb^{-1} (2017, 13 TeV)")
            elif "2018" in args.era:
                plot.DrawLumi("59.7 fb^{-1} (2018, 13 TeV)")
            else:
                logger.critical("Era {} is not implemented.".format(args.era))
                raise Exception

            plot.DrawChannelCategoryLabel(
                "%s, %s" % (channel_dict[channel], category_dict[category]),
                begin_left=None)

            # save plot
            postfix = "prefit" if "prefit" in args.input else "postfit" if "postfit" in args.input else "undefined"
            plot.save("%s/%s_%s_%s_%s.%s" %
                      (args.outputfolder, args.era, channel, args.gof_variable
                       if args.gof_variable is not None else category, postfix,
                       "png" if args.png else "pdf"))
            plots.append(
                plot
            )  # work around to have clean up seg faults only at the end of the script
Пример #22
0
def main(args):
    channel_categories = {
        "ee": ["m_vis", "d0_e", "dZ_e", "DCA0_e", "DCAZ_e"],
        "mm": ["m_vis", "d0_m", "dZ_m", "DCA0_m", "DCAZ_m"],
        "em": [
            "d0_em_te", "dZ_em_te", "d0_em_tm", "dZ_em_tm"
        ],  #["m_vis_te", "m_vis_tm"],#, "d0_te", "dZ_te", "DCA0_te", "DCAZ_te", "d0_tm", "dZ_tm", "DCA0_tm", "DCAZ_tm"],
        "et": ["d0_te",
               "dZ_te"],  #["m_vis", "d0_te", "dZ_te"],#, "d0_t", "dZ_t"],
        "mt": [
            "d0_tm", "dZ_tm"
        ],  #["m_vis", "d0_tm", "dZ_tm"],#, "d0_t", "dZ_t", "d0_f", "dZ_f", "d0_tt", "dZ_tt"],
        "tt": ["d0_t2", "dZ_t2"]
    }
    channel_dict = {
        "ee": "ee",
        "em": "e#mu",
        "et": "e#tau_{h}",
        "mm": "#mu#mu",
        "mt": "#mu#tau_{h}",
        "tt": "#tau_{h}#tau_{h}"
    }
    category_dict = {
        "d0_e": "#rightarrowe",
        "dZ_e": "#rightarrowe",
        "DCA0_e": "#rightarrowe",
        "DCAZ_e": "#rightarrowe",
        "d0_m": "#rightarrowm",
        "dZ_m": "#rightarrowm",
        "DCA0_m": "#rightarrowm",
        "DCAZ_m": "#rightarrowm",
        "d0_te": "#rightarrow#tau#rightarrowe",
        "dZ_te": "#rightarrow#tau#rightarrowe",
        "DCA0_te": "#rightarrow#tau#rightarrowe",
        "DCAZ_te": "#rightarrow#tau#rightarrowe",
        "d0_tm": "#rightarrow#tau#rightarrowm",
        "dZ_tm": "#rightarrow#tau#rightarrowm",
        "DCA0_tm": "#rightarrow#tau#rightarrowm",
        "DCAZ_tm": "#rightarrow#tau#rightarrowm",
        "d0_em_te": "#rightarrow#tau#rightarrowe",
        "dZ_em_te": "#rightarrow#tau#rightarrowe",
        "DCA0_em_te": "#rightarrow#tau#rightarrowe",
        "DCAZ_em_te": "#rightarrow#tau#rightarrowe",
        "d0_em_tm": "#rightarrow#tau#rightarrowm",
        "dZ_em_tm": "#rightarrow#tau#rightarrowm",
        "DCA0_em_tm": "#rightarrow#tau#rightarrowm",
        "DCAZ_em_tm": "#rightarrow#tau#rightarrowm",
        "d0_t": "#rightarrow#tau#rightarrow#tau_{h}",
        "dZ_t": "#rightarrow#tau#rightarrow#tau_{h}",
        "d0_t2": "#rightarrow#tau#rightarrow#tau_{h}",
        "dZ_t2": "#rightarrow#tau#rightarrow#tau_{h}",
        "d0_f": "fake#rightarrow#tau_{h}",
        "dZ_f": "fake#rightarrow#tau_{h}",
        "d0_tt": "fake#rightarrow#tau_{h}",
        "dZ_tt": "fake#rightarrow#tau_{h}",
        "m_vis": "inclusive",
        "m_vis_te": "muon antiiso",
        "m_vis_tm": "ele antiiso"
    }
    variable_dict = {
        "d0_e": "d0_1_calib_all",
        "dZ_e": "dZ_1_calib_all",
        "DCA0_e": "DCA0_1",
        "DCAZ_e": "DCAZ_1",
        "d0_m": "d0_1_calib_all",
        "dZ_m": "dZ_1_calib_all",
        "DCA0_m": "DCA0_1",
        "DCAZ_m": "DCAZ_1",
        "d0_te": "d0_1_calib",
        "dZ_te": "dZ_1_calib",
        "DCA0_te": "d0_1",
        "DCAZ_te": "dZ_1",
        "d0_tm": "d0_1_calib",
        "dZ_tm": "dZ_1_calib",
        "DCA0_tm": "d0_1",
        "DCAZ_tm": "dZ_1",
        "d0_em_te": "d0_1_calib_all",
        "dZ_em_te": "dZ_1_calib_all",
        "DCA0_em_te": "d0_1",
        "DCAZ_em_te": "dZ_1",
        "d0_em_tm": "d0_2_calib_all",
        "dZ_em_tm": "dZ_2_calib_all",
        "DCA0_em_tm": "d0_2",
        "DCAZ_em_tm": "dZ_2",
        "d0_t": "d0_2",
        "dZ_t": "dZ_2",
        "d0_t2": "d0_2",
        "dZ_t2": "dZ_2",
        "d0_f": "d0_2",
        "dZ_f": "dZ_2",
        "d0_tt": "d0_2",
        "dZ_tt": "dZ_2",
        "m_vis": "m_vis",
        "m_vis_te": "m_vis",
        "m_vis_tm": "m_vis"
    }
    split_dict = {
        "ee": 10000000,
        "em": 10000,
        "et": 1000000,
        "mm": 100000000,
        "mt": 1000000,
        "tt": 10
    }

    MC_processes = {
        "ee": ["HTT", "EWK", "QCD", "VV", "W", "TT", "ZJ", "ZTT", "ZL"],
        "em": ["HTT", "EWK", "QCD", "VV", "W", "TT", "ZJ", "ZTT", "ZL"],
        "et": [
            "HTT", "EWK", "QCD", "VV", "TTT", "TTJ", "ZJ", "WL", "WT", "ZTT",
            "ZL"
        ],
        "mm": ["HTT", "EWK", "QCD", "VV", "W", "TT", "ZJ", "ZTT", "ZL"],
        "mt": [
            "HTT", "EWK", "QCD", "VV", "TTT", "TTJ", "ZJ", "WL", "WT", "ZTT",
            "ZL"
        ],
        "tt":
        ["HTT", "EWK", "QCD", "VV", "W", "TTT", "TTJ", "ZJ", "ZTT", "ZL"]
    }
    legend_MC_processes = {}
    for channel in args.channels:
        legend_MC_processes[channel] = copy.deepcopy(MC_processes[channel])
        legend_MC_processes[channel].reverse()

    rootfile = ROOT.TFile(args.input, "READ")

    plots = []

    for channel in args.channels:
        for category in channel_categories[channel]:
            plot = dd.Plot([0.5, [0.35, 0.33]], "ModTDR", r=0.04, l=0.14)
            for process in MC_processes[channel]:
                #print "#{channel}#{channel}_{category}#{process}#smhtt#Run2016#{var}#125#".format(channel=channel, category=category, process=process, var=variable_dict[category])
                plot.add_hist(
                    rootfile.Get(
                        "#{channel}#{channel}_{category}#{process}#smhtt#Run2016#{var}#125#"
                        .format(channel=channel,
                                category=category,
                                process=process,
                                var=variable_dict[category])), process,
                    "MC_single")
                plot.setGraphStyle(
                    process,
                    "hist",
                    fillcolor=styles.color_dict["ggH" if process ==
                                                "HTT" else process])
            plot.add_hist(
                rootfile.Get(
                    "#{channel}#{channel}_{category}#data_obs#smhtt#Run2016#{var}#125#"
                    .format(channel=channel,
                            category=category,
                            var=variable_dict[category])), "data_obs")
            plot.add_hist(
                rootfile.Get(
                    "#{channel}#{channel}_{category}#MC#smhtt#Run2016#{var}#125#"
                    .format(channel=channel,
                            category=category,
                            var=variable_dict[category])), "MC")
            plot.setGraphStyle("MC", "hist", linecolor=1, linewidth=3)
            plot.setGraphStyle("data_obs", "e0")

            scalefactor = plot.subplot(2).get_hist("data_obs").GetSumOfWeights(
            ) / plot.subplot(1).get_hist("MC").GetSumOfWeights()
            print scalefactor
            plot.subplot(2)._hists["MC"][0].Scale(scalefactor)

            plot.subplot(2).normalize(["MC", "data_obs"], "data_obs")
            plot.subplot(0).normalizeByBinWidth()
            plot.subplot(1).normalizeByBinWidth()

            plot.create_stack(MC_processes[channel], "stack")

            plot.subplot(0).setYlims(
                split_dict[channel] /
                1000 if "DCA" in category else split_dict[channel],
                2 * plot.subplot(0).get_hist("MC").GetMaximum())
            #plot.subplot(0).setYlims(10, 10000000)
            plot.subplot(1).setYlims(
                0.1 if "DCA" in category else
                100.0 if "t" in channel else 100.0, split_dict[channel] /
                1000 if "DCA" in category else split_dict[channel])
            #plot.subplot(2).setYlims(0.95, 1.05)
            plot.subplot(2).setYlims(0.8, 1.2)
            #plot.subplot(2).setYlims(0.6, 1.4)
            plot.subplot(2).setXlabel(variable_dict[category])
            plot.subplot(0).setYlabel("N_{events} / bin width")
            plot.subplot(1).setYlabel("")
            plot.subplot(2).setYlabel("Ratio to data")

            #plot.scaleXTitleSize(0.8)
            #plot.scaleXLabelSize(0.8)
            plot.scaleYTitleSize(0.9)
            #plot.scaleYLabelSize(0.8)
            #plot.scaleXLabelOffset(2.0)
            plot.scaleYTitleOffset(1.25)
            #plot.setXlims(-0.02, 0.02)
            plot.subplot(1).setLogY()

            #plot.subplot(2).setNYdivisions(3, 5)

            # draw subplots. Argument contains names of objects to be drawn in corresponding order.
            plot.subplot(1).Draw(["stack", "data_obs"])
            plot.subplot(0).Draw(["stack", "data_obs"])
            plot.subplot(2).Draw(["MC", "data_obs"])

            # create legends
            suffix = ["", "_top"]
            plot.add_legend(width=0.48, height=0.15)

            label_dict = styles.label_dict
            label_dict["EWK"] = "EWKZ"
            label_dict["ZL"] = label_dict["ZL"].replace(
                " (l#rightarrow#tau_{h})", "")
            label_dict["ZJ"] = label_dict["ZJ"].replace("#tau_{h}", "l")
            for process in legend_MC_processes[channel]:
                plot.legend(0).add_entry(
                    0, process,
                    styles.label_dict[process.replace("EWK", "EWKZ")], 'f')
            plot.legend(0).add_entry(0, "MC", "MC", 'l')
            plot.legend(0).add_entry(0, "data_obs", "Data", 'PE')
            plot.legend(0).setNColumns(3)
            plot.legend(0).Draw()

            # draw additional labels
            plot.DrawCMS()
            plot.DrawLumi("35.9 fb^{-1} (13 TeV)")
            plot.DrawChannelCategoryLabel(
                "%s, %s" % (channel_dict[channel], category_dict[category]))

            # save plot
            prefix = "prefit" if "prefit" in args.input else "postfit" if "postfit" in args.input else "undefined"
            plot.save("quantile-method/%s_%s.%s" %
                      (channel, category, 'png' if args.png else 'pdf'))

            # plot zoomed version
            lim = 0.01 * 600 if "DCA" in category else 0.01
            plot.setXlims(-lim, lim)
            plot.scaleYTitleSize(1.0)
            plot.scaleYTitleOffset(1.0)
            plot.subplot(1).Draw(["stack", "data_obs"])
            plot.subplot(0).Draw(["stack", "data_obs"])
            plot.subplot(2).Draw(["MC", "data_obs"])
            plot.legend(0).Draw()
            plot.DrawCMS()
            plot.DrawLumi("35.9 fb^{-1} (13 TeV)")
            plot.DrawChannelCategoryLabel(
                "%s, %s" % (channel_dict[channel], category_dict[category]))
            plot.save("quantile-method/zoom_%s_%s.%s" %
                      (channel, category, 'png' if args.png else 'pdf'))

            plots.append(
                plot
            )  # work around to have clean up seg faults only at the end of the script
def main(args):
    #### plot signals
    print(args)
    if args.gof_variable != None:
        channel_categories = {
            "et": ["300"],
            "mt": ["301", "302"],
            "tt": ["300"],
            "em": ["301", "302"],
        }
        if args.era == "combined":
            if "prefit" in args.input:
                channel_categories = {
                    "et": ["300"],
                    "mt": ["300", "301", "302"],
                    "tt": ["300"],
                    "em": ["300", "301", "302"],
                }
            else:
                if "301" in args.input:
                    channel_categories["mt"] = ["301"]
                    channel_categories["em"] = ["301"]
                elif "302" in args.input:
                    channel_categories["mt"] = ["302"]
                    channel_categories["em"] = ["302"]
                else:
                    channel_categories = {
                        "et": ["300"],
                        "mt": ["300"],
                        "tt": ["300"],
                        "em": ["300"],
                    }
    else:
        channel_categories = {
            #"et": ["ztt", "zll", "w", "tt", "ss", "misc"],
            "et": ["12", "15", "11", "13", "14", "16"],
            #"mt": ["ztt", "zll", "w", "tt", "ss", "misc"],
            "mt": ["12", "15", "11", "13", "14", "16"],
            #"tt": ["ztt", "noniso", "misc"]
            "tt": ["12", "17", "16"],
            #"em": ["ztt", "tt", "ss", "misc", "db"]
            "em": ["12", "13", "14", "16", "19"]
        }

    channel_dict = {
        "ee": "ee",
        "em": "e#mu",
        "et": "e#tau_{h}",
        "mm": "#mu#mu",
        "mt": "#mu#tau_{h}",
        "tt": "#tau_{h}#tau_{h}"
    }
    if args.gof_variable != None:
        category_dict = {
            "300": "inclusive",
            "301": "No b tag",
            "302": "b tag",
        }
    else:
        category_dict = {
            "1": "ggh",
            "100": "ggh 0-jet",
            "101": "ggh 1-jet p_{T}^{H} [0,120]",
            "102": "ggh 1-jet p_{T}^{H} [120,200]",
            "103": "ggh #geq 2-jet",
            "104": "ggh p_{T}^{H}>200",
            "2": "qqh",
            "200": "qqh 2J low mjj",
            "201": "qqh p_{T}^{H}>200",
            "202": "qqh vbftopo mjj>700",
            "203": "qqh vbftopo mjj [350,700]",
            "12": "ztt",
            "15": "zll",
            "11": "wjets",
            "13": "tt",
            "14": "qcd",
            "16": "misc",
            "17": "qcd",
            "19": "diboson",
            "20": "Genuine #tau",
            "21": "Jet #rightarrow #tau_{h}"
        }
    if args.linear == True:
        split_value = 0
    else:
        if args.normalize_by_bin_width:
            split_value = 10001
        else:
            split_value = 101

    split_dict = {c: split_value for c in ["et", "mt", "tt", "em"]}

    bkg_processes = ["EWK", "ZL", "TTL", "jetFakes", "EMB"]
    if not args.fake_factor and args.embedding:
        bkg_processes = ["QCD", "VVJ", "W", "TTJ", "ZJ", "ZL", "EMB"]
    if not args.embedding and args.fake_factor:
        bkg_processes = ["VVT", "VVL", "TTT", "TTL", "ZL", "jetFakes", "ZTT"]
    if not args.embedding and not args.fake_factor:
        bkg_processes = [
            "QCD", "VVT", "VVL", "VVJ", "W", "TTT", "TTL", "TTJ", "ZJ", "ZL",
            "ZTT"
        ]
    all_bkg_processes = [b for b in bkg_processes]
    legend_bkg_processes = copy.deepcopy(bkg_processes)
    legend_bkg_processes.reverse()

    if "2016" in args.era:
        era = "2016"
    elif "2017" in args.era:
        era = "2017"
    elif "2018" in args.era:
        era = "2018"
    elif "combined" in args.era:
        era = "combined"
    else:
        logger.critical("Era {} is not implemented.".format(args.era))
        raise Exception
    print(channel_categories)
    plots = []
    for channel in args.channels:
        for category in channel_categories[channel]:
            print "Plot for category: ", category
            rootfile = rootfile_parser.Rootfile_parser(args.input)
            if channel == "em" and args.embedding:
                bkg_processes = ["EWK", "ZL", "TTL", "QCD", "EMB"]
            elif channel == "em" and not args.embedding:
                bkg_processes = ["VVL", "W", "TTL", "ZL", "QCD", "ZTT"]
            else:
                bkg_processes = [b for b in all_bkg_processes]
            legend_bkg_processes = copy.deepcopy(bkg_processes)
            legend_bkg_processes.reverse()
            # create plot
            width = 600
            if args.linear == True:
                plot = dd.Plot([0.25, [0.25, 0.23]],
                               "ModTDR",
                               r=0.04,
                               l=0.14,
                               width=width)
            else:
                plot = dd.Plot([0.5, [0.3, 0.28]],
                               "ModTDR",
                               r=0.04,
                               l=0.14,
                               width=width)

            # get background histograms
            for process in bkg_processes:
                try:
                    plot.add_hist(
                        get_histogram(rootfile, era, channel, category,
                                      process), process, "bkg")
                    plot.setGraphStyle(process,
                                       "hist",
                                       fillcolor=styles.color_dict[process])
                except:
                    pass

            # get observed data and total background histograms
            # NOTE: With CMSSW_8_1_0 the TotalBkg definition has changed.
            print("plot.add_hist(rootfile.get(" + era + ", " + channel + ", " +
                  category + ', "data_obs")')
            plot.add_hist(
                get_histogram(rootfile, era, channel, category, "data_obs"),
                "data_obs")
            total_bkg = check_for_zero_bins(
                get_histogram(rootfile, era, channel, category, "TotalBkg"))
            #ggHHist = rootfile.get(era, channel, category, "ggH")
            #qqHHist = rootfile.get(era, channel, category, "qqH")
            #total_bkg.Add(ggHHist, -1)
            #if qqHHist:
            #     total_bkg.Add(qqHHist, -1)
            plot.add_hist(total_bkg, "total_bkg")

            plot.subplot(0).setGraphStyle("data_obs", "e0")
            plot.setGraphStyle("total_bkg",
                               "e2",
                               markersize=0,
                               fillcolor=styles.color_dict["unc"],
                               linecolor=0)

            plot.subplot(2).normalize(["total_bkg", "data_obs"], "total_bkg")

            # stack background processes
            plot.create_stack(bkg_processes, "stack")

            # normalize stacks by bin-width
            if args.normalize_by_bin_width:
                plot.subplot(0).normalizeByBinWidth()
                plot.subplot(1).normalizeByBinWidth()

            # set axes limits and labels
            if channel == "em":
                # plot.setXlims(-200.,150.)
                if category in ["300", "301"]:
                    plot.setXlims(-70., 100.)
                    plot.subplot(0).setYlims(
                        split_dict[channel],
                        max(
                            1.40 *
                            plot.subplot(0).get_hist("data_obs").GetMaximum(),
                            split_dict[channel] * 2))
                elif category == "302":
                    plot.setXlims(-140., 140)
                    plot.subplot(0).setYlims(
                        split_dict[channel],
                        max(
                            1.40 *
                            plot.subplot(0).get_hist("data_obs").GetMaximum(),
                            split_dict[channel] * 2))
            elif channel in ["et", "mt"]:
                if category in ["300", "301"]:
                    plot.subplot(0).setYlims(
                        split_dict[channel],
                        max(
                            1.25 *
                            plot.subplot(0).get_hist("data_obs").GetMaximum(),
                            split_dict[channel] * 2))
                elif category in ["302"]:
                    plot.subplot(0).setYlims(
                        split_dict[channel],
                        max(
                            2.00 *
                            plot.subplot(0).get_hist("data_obs").GetMaximum(),
                            split_dict[channel] * 2))

            if args.gof_variable is None:
                plot.subplot(2).setYlims(0.45, 2.05)
            else:
                plot.subplot(2).setYlims(0.85, 1.15)

            if not args.linear:
                plot.subplot(1).setYlims(0.1, split_dict[channel])
                plot.subplot(1).setLogY()
                plot.subplot(1).setYlabel(
                    "")  # otherwise number labels are not drawn on axis
            if args.gof_variable != None:
                gof_log_vars = []
                if args.gof_variable in gof_log_vars:
                    plot.subplot(0).setLogX()
                    plot.subplot(1).setLogX()
                    plot.subplot(2).setLogX()
                elif args.gof_variable in ["njets_red", "nbtag_red"]:
                    bins = plot.subplot(2).get_hist("data_obs").GetNbinsX()
                    bin_labels = map(str, range(bins - 1))
                    bin_labels.append("#geq%i" % (bins - 1))
                    plot.subplot(2).setNXdivisions(bins, 0, 2)
                    plot.subplot(2).changeXLabels(bin_labels)
                if args.gof_variable in styles.x_label_dict[args.channels[0]]:
                    x_label = styles.x_label_dict[args.channels[0]][
                        args.gof_variable]
                else:
                    x_label = args.gof_variable
                plot.subplot(2).setXlabel(x_label)
            elif args.gof_variable != None and args.linear:
                if args.gof_variable in styles.x_label_dict[args.channels[0]]:
                    x_label = styles.x_label_dict[args.channels[0]][
                        args.gof_variable]
                else:
                    x_label = args.gof_variable
                plot.subplot(2).setXlabel(x_label)
            else:
                plot.subplot(2).setXlabel("NN output")
            if args.normalize_by_bin_width:
                plot.subplot(0).setYlabel("dN/d(%s)" % args.gof_variable)
            else:
                if channel == "em":
                    plot.subplot(0).setYlabel("Events / 5 GeV")
                else:
                    plot.subplot(0).setYlabel("Events / 5 GeV")

            plot.subplot(2).setYlabel("Obs./Exp.")
            plot.subplot(2).setGrid()

            #plot.scaleXTitleSize(0.8)
            #plot.scaleXLabelSize(0.8)
            #plot.scaleYTitleSize(0.8)
            plot.scaleYLabelSize(0.8)
            #plot.scaleXLabelOffset(2.0)
            plot.scaleYTitleOffset(1.1)

            plot.subplot(2).setNYdivisions(3, 0)

            #if not channel == "tt" and category in ["11", "12", "13", "14", "15", "16"]:
            #    plot.subplot(2).changeXLabels(["0.2", "0.4", "0.6", "0.8", "1.0"])

            # draw subplots. Argument contains names of objects to be drawn in corresponding order.
            procs_to_draw = [
                "stack", "total_bkg", "data_obs"
            ] if args.linear else ["stack", "total_bkg", "data_obs"]
            plot.subplot(0).Draw(procs_to_draw)
            if args.linear != True:
                plot.subplot(1).Draw(["stack", "total_bkg", "data_obs"])
            plot.subplot(2).Draw(["total_bkg", "data_obs"])

            # create legends
            if channel == "mt" and category in ["302"]:
                plot.add_legend(width=0.5, height=0.20)
                plot.legend(0).setNColumns(2)
            elif channel == "em" and category in ["302"]:
                plot.add_legend(width=0.25, height=0.35)
                plot.legend(0).setNColumns(1)
            else:
                plot.add_legend(width=0.25, height=0.35)
                plot.legend(0).setNColumns(1)
            plot.legend(0).add_entry(0, "data_obs", "Observed", 'PE')
            for process in legend_bkg_processes:
                try:
                    plot.legend(0).add_entry(
                        0, process, styles.legend_label_dict[process.replace(
                            "TTL",
                            "TT").replace("VVL",
                                          "VV").replace("EMB", "EMBFull")],
                        'f')
                except:
                    pass
            plot.legend(0).add_entry(0, "total_bkg", "Bkg. unc.", 'f')
            # plot.legend(0).add_entry(0, "total_bkg", "Background uncertainty", 'f')

            plot.legend(0).scaleTextSize(1.175)
            plot.legend(0).Draw()

            if channel == "em":
                if category in ["300", "301"]:
                    _ymax_low = max(
                        1.05 *
                        plot.subplot(0).get_hist("data_obs").GetMaximum(),
                        split_dict[channel] * 2)
                    _ymax_high = max(
                        0.6 *
                        plot.subplot(0).get_hist("data_obs").GetMaximum(),
                        split_dict[channel] * 2)
                    plot.add_line(xmin=-35,
                                  xmax=-35,
                                  ymin=0,
                                  ymax=_ymax_low,
                                  linestyle=7,
                                  color=ROOT.kBlack)
                    plot.add_line(xmin=-10,
                                  xmax=-10,
                                  ymin=0,
                                  ymax=_ymax_low,
                                  linestyle=7,
                                  color=ROOT.kBlack)
                    plot.add_line(xmin=30,
                                  xmax=30,
                                  ymin=0,
                                  ymax=_ymax_low,
                                  linestyle=7,
                                  color=ROOT.kBlack)
                    # plot.DrawText(0.335, 0.80, "Low-D_{#zeta}", textsize=0.030)
                    # plot.DrawText(0.465, 0.80, "Medium-D_{#zeta}", textsize=0.025)
                    label2 = ROOT.TLatex()
                    plot.subplot(0)._pad.cd()
                    label2.SetNDC(False)
                    label2.SetTextAngle(0)
                    label2.SetTextAlign(22)
                    label2.SetTextColor(ROOT.kBlack)
                    label2.SetTextSize(0.030)
                    if category in ["301"]:
                        label2.DrawLatex(-22.5, 105000, "Low-D_{#zeta}")
                        label2.DrawLatex(10, 105000, "Medium-D_{#zeta}")
                        plot.DrawText(0.75,
                                      0.5,
                                      "High-D_{#zeta}",
                                      textsize=0.030)
                    else:
                        label2.DrawLatex(-22.5, 125000, "Low-D_{#zeta}")
                        label2.DrawLatex(10, 125000, "Medium-D_{#zeta}")
                        plot.DrawText(0.75,
                                      0.5,
                                      "High-D_{#zeta}",
                                      textsize=0.030)
                elif category in ["302"]:
                    _ymax_low = max(
                        1.05 *
                        plot.subplot(0).get_hist("data_obs").GetMaximum(),
                        split_dict[channel] * 2)
                    _ymax_high = max(
                        0.6 *
                        plot.subplot(0).get_hist("data_obs").GetMaximum(),
                        split_dict[channel] * 2)
                    plot.add_line(xmin=-35,
                                  xmax=-35,
                                  ymin=0,
                                  ymax=_ymax_low,
                                  linestyle=7,
                                  color=ROOT.kBlack)
                    plot.add_line(xmin=-10,
                                  xmax=-10,
                                  ymin=0,
                                  ymax=_ymax_low,
                                  linestyle=7,
                                  color=ROOT.kBlack)
                    plot.add_line(xmin=30,
                                  xmax=30,
                                  ymin=0,
                                  ymax=_ymax_low,
                                  linestyle=7,
                                  color=ROOT.kBlack)
                    plot.DrawText(0.450, 0.8, "Low-D_{#zeta}", textsize=0.025)
                    plot.DrawText(0.525,
                                  0.8,
                                  "Medium-D_{#zeta}",
                                  textsize=0.025)
                    plot.DrawText(0.75, 0.45, "High-D_{#zeta}", textsize=0.025)
                    plot.DrawText(0.305, 0.8, "t#bar{t} CR", textsize=0.025)
            elif channel in ["et", "mt"]:
                if category in ["300", "301"]:
                    _ymax = max(
                        0.8 *
                        plot.subplot(0).get_hist("data_obs").GetMaximum(),
                        split_dict[channel] * 2)
                    plot.add_line(xmin=40,
                                  xmax=40,
                                  ymin=0,
                                  ymax=_ymax,
                                  linestyle=7,
                                  color=ROOT.kBlack)
                    _ymax = max(
                        0.5 *
                        plot.subplot(0).get_hist("data_obs").GetMaximum(),
                        split_dict[channel] * 2)
                    plot.add_line(xmin=70,
                                  xmax=70,
                                  ymin=0,
                                  ymax=_ymax,
                                  linestyle=7,
                                  color=ROOT.kBlack)
                    plot.DrawText(0.24, 0.68, "Tight-m_{T}", textsize=0.030)
                    plot.DrawText(0.40, 0.55, "Loose-m_{T}", textsize=0.030)
                elif category in ["302"]:
                    _ymax = max(
                        1.3 *
                        plot.subplot(0).get_hist("data_obs").GetMaximum(),
                        split_dict[channel] * 2)
                    plot.add_line(xmin=40,
                                  xmax=40,
                                  ymin=0,
                                  ymax=_ymax,
                                  linestyle=7,
                                  color=ROOT.kBlack)
                    _ymax = max(
                        1.3 *
                        plot.subplot(0).get_hist("data_obs").GetMaximum(),
                        split_dict[channel] * 2)
                    plot.add_line(xmin=70,
                                  xmax=70,
                                  ymin=0,
                                  ymax=_ymax,
                                  linestyle=7,
                                  color=ROOT.kBlack)
                    plot.DrawText(0.18, 0.67, "Tight-m_{T}", textsize=0.030)
                    plot.DrawText(0.40, 0.67, "Loose-m_{T}", textsize=0.030)

            for line in plot._lines:
                line.Draw()

            if args.chi2test:
                import ROOT as r
                f = r.TFile(args.input, "read")
                background = f.Get("htt_{}_{}_Run{}_{}/TotalBkg".format(
                    channel, category, args.era,
                    "prefit" if "prefit" in args.input else "postfit"))
                data = f.Get("htt_{}_{}_Run{}_{}/data_obs".format(
                    channel, category, args.era,
                    "prefit" if "prefit" in args.input else "postfit"))
                chi2 = data.Chi2Test(background, "UW CHI2/NDF")
                plot.DrawText(0.7, 0.3,
                              "\chi^{2}/ndf = " + str(round(chi2, 3)))

            # plot.add_legend(
            #     reference_subplot=2, pos=1, width=0.5, height=0.03)
            # plot.legend(1).add_entry(0, "data_obs", "Data", 'PE')
            # plot.legend(1).add_entry(0, "total_bkg", "Bkg. unc.", 'f')
            # plot.legend(1).setNColumns(4)
            # plot.legend(1).Draw()

            # draw additional labels
            plot.DrawCMS(cms_sub="")
            if "2016" in args.era:
                plot.DrawLumi("36.3 fb^{-1} (2016, 13 TeV)")
            elif "2017" in args.era:
                plot.DrawLumi("41.5 fb^{-1} (2017, 13 TeV)")
            elif "2018" in args.era:
                plot.DrawLumi("59.7 fb^{-1} (2018, 13 TeV)")
            elif "combined" in args.era:
                plot.DrawLumi("138 fb^{-1} (13 TeV)")
            else:
                logger.critical("Era {} is not implemented.".format(args.era))
                raise Exception

            plot.DrawChannelCategoryLabel(
                "#font[42]{%s, %s}" %
                (channel_dict[channel], category_dict[category])
                if category != "300" else "%s" % channel_dict[channel],
                begin_left=None)

            # save plot
            postfix = "prefit" if "prefit" in args.input else "postfit" if "postfit" in args.input else "undefined"
            plot.save("%s/%s_%s_%s_%s.%s" %
                      (args.outputfolder, args.era, channel, category, postfix,
                       "png" if args.png else "pdf"))
            plots.append(
                plot
            )  # work around to have clean up seg faults only at the end of the script