{ "cells": [ { "cell_type": "markdown", "id": "baaac12f-ffa3-41a6-88b4-7dda42bb1b84", "metadata": {}, "source": [ "## Produce plots comparing weighted distributions with ROOT\n", "\n", "Running CutLang provides ```histoOut-.root``` files which contain histograms available for each analysis region.\n", "This notebook provides code based on ```PyROOT``` to make plots comparing distributions between two files.\n", "\n", "The code will plot histograms after applying event weights that will normalize them to cross section times luminosity.\n", "\n", "The code only requires the following input\n", " * Addresses of the two files to compare\n", " * A list of regions and histograms you would like to draw." ] }, { "cell_type": "code", "execution_count": null, "id": "acc368aa-61c5-4f10-8dc0-a483b15c8232", "metadata": {}, "outputs": [], "source": [ "# Let's start with importing the needed modules\n", "from ROOT import gStyle, TFile, TH1, TH1D, TH2D, TCanvas, TLegend, TColor, TLatex, SetOwnership\n", "import random\n", "# Now let's set some ROOT styling parameters:\n", "# You do not need to know what they mean, but can directly use these settings\n", "\n", "gStyle.SetOptStat(0)\n", "gStyle.SetPalette(1)\n", "\n", "gStyle.SetTextFont(42)\n", "\n", "gStyle.SetTitleStyle(0000)\n", "gStyle.SetTitleBorderSize(0)\n", "gStyle.SetTitleFont(42)\n", "gStyle.SetTitleFontSize(0.055)\n", "\n", "gStyle.SetTitleFont(42, \"xyz\")\n", "gStyle.SetTitleSize(0.5, \"xyz\")\n", "gStyle.SetLabelFont(42, \"xyz\")\n", "gStyle.SetLabelSize(0.45, \"xyz\")\n", "\n", "# A function to apply a fix to the cutflow histograms from CutLang. \n", "# It takes out the redundant bins showing histogramming.\n", "def fixcutflow(h):\n", " nbins = 0\n", " for i in range(1, h.GetXaxis().GetNbins()+1):\n", " if not (\"Histo\" in h.GetXaxis().GetBinLabel(i) or \"ALL\" in h.GetXaxis().GetBinLabel(i)):\n", " nbins = nbins + 1\n", " hnew = TH1D(h.GetName()+str(random.random()), h.GetTitle(), nbins, 0, nbins)\n", " ibin = 0\n", " for i in range(1, h.GetXaxis().GetNbins()+1):\n", " label = h.GetXaxis().GetBinLabel(i)\n", " if not (\"Histo\" in label or \"ALL\" in label):\n", " ibin = ibin + 1\n", " hnew.GetXaxis().SetBinLabel(ibin, label)\n", " hnew.SetBinContent(ibin, h.GetBinContent(i))\n", " h = hnew\n", " SetOwnership(h, False)\n", " return h\n" ] }, { "cell_type": "code", "execution_count": null, "id": "acde226f-2c0e-4374-a382-25dcd8679c73", "metadata": {}, "outputs": [], "source": [ "# Let's open two histoOut files produced by CutLang, whose histograms we will compare. \n", "# These could, for example. be a signal file and a background file\n", "fs = TFile(\"../../src/histoOut-ttbartovlq_TT800.root\")\n", "fb = TFile(\"../../src/histoOut-ttbartovlq_SMttbar.root\")" ] }, { "cell_type": "code", "execution_count": null, "id": "e12dc78a-7095-40a6-a0c2-10441f0a975a", "metadata": { "tags": [] }, "outputs": [], "source": [ "# Let's also define some variables necessary for weight calculation\n", "# Cross section\n", "lumi = 2.26\n", "# BG masses : [cross section, all events, total skimmed events]\n", "bgxsec = 831760\n", "bgallevents = 97994442\n", "bgskimevents = 20620375\n", "\n", "# Signal masses : [cross section, all events, total skimmed events]\n", "massxsec = {'700' : [455, 805000, 256942],\n", " '800' : [196, 788200, 252828],\n", " '1200' : [11.8, 817800, 253993],\n", " }\n", "mass = '800'\n", "sgxsec = massxsec[mass][0]\n", "sgallevents = massxsec[mass][1]\n", "sgskimevents = massxsec[mass][2]" ] }, { "cell_type": "code", "execution_count": null, "id": "22ec1fac-5a78-4a1a-8313-1b1b43759a67", "metadata": {}, "outputs": [], "source": [ "# Now let's draw some histograms. \n", "# We will compare distributions for different variables.\n", "# You can try this with different histograms in different regions.\n", "# Provide the region and histo names in the following list:\n", "histoinfos = [\n", "# [\"\", \"\"]\n", " [\"fourjetoneb\", \"cutflow\"],\n", " [\"fourjetoneb\", \"hmtop1b\"],\n", " [\"fourjetoneb\", \"h2mtop1b\"],\n", " [\"fourjettwob\", \"cutflow\"],\n", " [\"fourjettwob\", \"hmtop\"],\n", " [\"fourjettwob\", \"h2mtop\"],\n", "# [\"fourjettwob\", \"hpttop\"],\n", "# [\"fourjettwob\", \"h2pttop\"],\n", "# [\"fourjettwob\", \"hnjets\"],\n", "# [\"fourjettwob\", \"hj1pT\"],\n", "# [\"fourjettwob\", \"hj2pT\"],\n", "# [\"fourjettwob\", \"hj3pT\"],\n", "# [\"fourjettwob\", \"hmet\"],\n", "# [\"fourjettwob\", \"hST\"],\n", "# [\"fourjettwob\", \"hnak8\"],\n", "# [\"optforvlqreint\", \"cutflow\"],\n", "# [\"optforvlqreint\", \"hak8j1pT\"],\n", "# [\"optforvlqreint\", \"h2ak8j1pT\"],\n", "# [\"optforvlqreint\", \"hak8j1m\"],\n", "# [\"optforvlqreint\", \"h2ak8j1m\"],\n", "# [\"optforvlqreint\", \"h2mtop2\"],\n", "# [\"optforvlqreint\", \"h2pttop2\"],\n", "# [\"optforvlqreint\", \"hmet2\"],\n", "# [\"optforvlqreint\", \"hST2\"],\n", "# [\"optforvlqreint\", \"h2ak8j1pT2\"],\n", "# [\"optforvlqreint\", \"h2ak8j1m2\"],\n", "]\n" ] }, { "cell_type": "code", "execution_count": null, "id": "0e32e46f-3eb7-4475-8166-c11ab07ab9b5", "metadata": {}, "outputs": [], "source": [ "# Make lists for convases and legends. This is just a fix for jupyter root!!!\n", "canvases = []\n", "texts = []\n", "legends = []\n", "\n", "# Loop over the histograms and prepare the plots:\n", "for hinfo in histoinfos:\n", " # In which region would you like to draw? You can change the region name. \n", " region = hinfo[0]\n", " # Which histogram would you like to plot?\n", " hname = hinfo[1]\n", " # Get the histograms from the file:\n", " hsg = fs.Get(region+\"/\"+hname)\n", " hbg = fb.Get(region+\"/\"+hname)\n", "\n", " if hname == \"cutflow\":\n", " hsg = fixcutflow(hsg)\n", " hbg = fixcutflow(hbg) \n", " \n", " hsg.SetName(hsg.GetName()+str(random.random()))\n", " hbg.SetName(hbg.GetName()+str(random.random()))\n", " \n", " # Calculate event weights\n", " sgw = sgxsec * lumi * (sgskimevents / fs.Get(region+\"/cutflow\").GetBinContent(1)) / sgallevents\n", " bgw = bgxsec * lumi * (bgskimevents / fb.Get(region+\"/cutflow\").GetBinContent(1)) / bgallevents\n", " # Scale the histograms with weights\n", " hsg.Scale(sgw)\n", " hbg.Scale(bgw) \n", "\n", " if hsg.GetMaximum() > hbg.GetMaximum(): \n", " hbg.SetMaximum(hsg.GetMaximum()*1.1)\n", " hbg.SetMinimum(0)\n", " \n", " # Format the histograms: scaling, lines, colors, axes titles, etc.. \n", " # You do not need to learn the commands here unless you are really curious.\n", " # Otherwise just execute the cell.\n", " \n", " # Histogram style settings:\n", " hsg.SetLineWidth(2)\n", " hbg.SetLineWidth(2)\n", "\n", " # Set the colors:\n", " # Color numbers can be retrived from https://root.cern.ch/doc/master/classTColor.html\n", " # (check for color wheel)\n", " hbg.SetFillColor(400-7) # kYellow - 7\n", " hsg.SetLineColor(600) # kBlue\n", " hbg.SetLineColor(400+2) # kYellow + 2\n", "\n", " # Titles, labels.\n", " # It is enough to set such variables ONLY FOR THE FIRST HISTOGRAM YOU WILL DRAW\n", " # i.e., the one you will call by .Draw(). The rest you will draw by .Draw(\"same\") will only \n", " # contribute with the historam curve.\n", " hbg.SetTitle(\"\")\n", " hbg.GetXaxis().SetTitle(hsg.GetTitle())\n", " hbg.GetXaxis().SetTitleOffset(1.25)\n", " hbg.GetXaxis().SetTitleSize(0.05)\n", " hbg.GetXaxis().SetLabelSize(0.045)\n", " hbg.GetXaxis().SetNdivisions(8, 5, 0)\n", " hbg.GetYaxis().SetTitle(\"number of events\")\n", " #hbg.GetYaxis().SetTitleOffset(1.4)\n", " hbg.GetYaxis().SetTitleSize(0.05)\n", " hbg.GetYaxis().SetLabelSize(0.045)\n", " \n", " # Write the region name on the histogram\n", " t = TLatex(0.60, 0.85, region)\n", " t.SetTextSize(0.042)\n", " t.SetTextFont(42)\n", " t.SetNDC()\n", " texts.append(t)\n", "\n", " # Make a plot legend\n", " # Change the entry names to reflect processes you are plotting!\n", " l = TLegend(0.55, 0.70, 0.88, 0.82)\n", " l.SetBorderSize(0)\n", " l.SetFillStyle(0000)\n", " l.AddEntry(hsg,\"TT m=800\", \"l\")\n", " l.AddEntry(hbg,\"tt+jets\", \"f\")\n", " legends.append(l)\n", " \n", " # Now we make a canvas and draw our histograms\n", " cxwidth = 650\n", " if hname == \"cutflow\": cxwidth = 1000\n", " c = TCanvas(\"c_\"+region+\"_\"+hname, \"c_\"+region+\"_\"+hname, cxwidth, 500)\n", " c.SetBottomMargin(0.15)\n", " c.SetLeftMargin(0.15)\n", " c.SetRightMargin(0.15)\n", " c.SetLogy(1)\n", " logy = 1\n", " if logy == 1:\n", " hbg.SetMaximum(hbg.GetMaximum()*10)\n", " hbg.SetMinimum(0.5)\n", " c.SetLogy(logy)\n", " hbg.Draw(\"hist\")\n", " hsg.Draw(\"hist same\")\n", " c.Draw()\n", " l.Draw(\"same\")\n", " t.Draw(\"same\")\n", " canvases.append(c)\n", " \n", "# Draw the canvases:\n", "for c in canvases:\n", " c.Draw()\n" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.6" } }, "nbformat": 4, "nbformat_minor": 5 }