This is an exercise showing a simple analysis exploring the ZZ -> 4 lepton final state, focusing on the e+e-μ+μ- channel. The analysis aims to explore the kinematics of ZZ --> e+e-μ+μ- events.
The analysis is performed based on CMS open data MC ntuples.
The analysis consists of two parts:
!wget --progress=dot:giga https://www.dropbox.com/s/hak5sqxamgkrfa2/ZZTo2e2mu.root
# Get the ROOT file containing the ZZ -> eemumu background events
Please import the requirements by running the cell below to avoid error
import ROOT
%jsroot on
Writing the analysis with ADL: In the following cell, part of the analysis is written using the ADL syntax. However there are some parts missing. Please follow the instructions in the comments to complete the missing parts. If you feel adventurous, you could modify the object or event selections, add new variables or new histograms.
Running the analysis with CutLang: Executing the cell will run the analysis on both the signal (SMHiggsToZZTo4L.root) and background (ZZTo2e2mu.root) events. The run parameters are given in the first line of the cell:
NOTE: When running jupyter/binder via direct link, if your run does not complete due to memory issues, please reduce the number of events via the "events" parameter.
Analysis output: Running the analysis will produce two outputs:
%%cutlang file=ZZTo2e2mu.root filetype=CMSODR2 adlfile=ZZ4L events=100000 verbose=20000
# ADL file for ZZ->eemumu analysis
# Object selection
# Take input electrons, labeled "ele" and obtain a set of selected electrons "elesel"
object elesel
take ele
select pT(ele) > 20
select abs(eta(ele)) < 2.5
# Take input muons, labeled "muo" and obtain a set of selected muons "muosel"
object muosel
take muo
select pT(muo) > 20
select abs(eta(muo)) < 2.4
# Event selection
# Select all events and make histograms of lepton multiplicities
region overview
select ALL # to count all events
histo hneinp, "number of input electrons", 10, 0, 10, size(ele)
histo hnesel, "number of selected electrons", 10, 0, 10, size(elesel)
histo hnminp, "number of input muons", 10, 0, 10, size(muo)
histo hnmsel, "number of selected muons", 10, 0, 10, size(muosel)
histo hnenminp, "number of input electrons vs muons", 10, 0, 10, 10, 0, 10, size(ele), size(muo)
histo hnenmsel, "number of selected electrons vs muons", 10, 0, 10, 10, 0, 10, size(elesel), size(muosel)
# Selection requiring 1 Z->ee in the event using input electrons
region rZeeinp
select ALL
select size(ele) == 2
select q(ele[0]) + q(ele[1]) == 0
histo hZeeinp, "Z(->ee,inp) candidate mass (GeV)", 50, 50, 150, m(ele[0] ele[1])
# Selection requiring 1 Z->mumu in the event using selected electrons
region rZeesel
select ALL
select size(elesel) == 2
select q(elesel[0]) + q(elesel[1]) == 0
histo hZeesel, "Z(->ee,sel) candidate mass (GeV)", 50, 50, 150, m(elesel[0] elesel[1])
# Can you write here the 2 regions requiring 1 Z->mumu in the event?
region rZmminp
select ALL
# Please complete the rest
region rZmmsel
select ALL
# Please complete the rest
# Now let's apply a selection with 2Zs, Z->ee and Z->mumu
region rZeemminp
select ALL
select size(ele) == 2 and size(muo) == 2
select q(ele[0]) + q(ele[1]) == 0
select q(muo[0]) + q(muo[1]) == 0
histo hZeeinp, "Z(->ee,inp) candidate mass (GeV)", 50, 50, 150, m(ele[0] ele[1])
histo hZmminp, "Z(->mm,inp) candidate mass (GeV)", 50, 50, 150, m(muo[0] muo[1])
# Can you make a 2D histogram plotting m(ee) vs m(mumu) ?
# histo hZeemminp,
# Can you write the same region using the selected electrons and muons?
region rZeemmsel
select ALL
# Please complete the rest
Now let's make some plots using the ROOT package in python (which is widely used at CERN). Instructions are shown within comments in the following cells.
What to do:
# Let's start with importing the needed modules
from ROOT import gStyle, TFile, TH1, TH1D, TH2D, TCanvas, TLegend, TColor
# Now let's set some ROOT styling parameters:
# You do not need to know what they mean, but can directly use these settings
gStyle.SetOptStat(0)
gStyle.SetPalette(1)
gStyle.SetTextFont(42)
gStyle.SetTitleStyle(0000)
gStyle.SetTitleBorderSize(0)
gStyle.SetTitleFont(42)
gStyle.SetTitleFontSize(0.055)
gStyle.SetTitleFont(42, "xyz")
gStyle.SetTitleSize(0.5, "xyz")
gStyle.SetLabelFont(42, "xyz")
gStyle.SetLabelSize(0.45, "xyz")
# Let's open the output file produced by CutLang:
# (If you changed the adlfile option when running cutlang, you will need to change the file names)
f = TFile("histoOut-ZZ4L-ZZTo2e2mu.root")
# We can see what is inside the signal file:
f.ls()
# There should be a directory (TDirectoryFile) per selection region.
# Let's check out what is inside "baseline":
f.cd("rZeeinp")
f.ls()
# Get the histograms
# Overview region:
hneinp = f.Get("overview/hneinp")
hnminp = f.Get("overview/hnminp")
hnesel = f.Get("overview/hnesel")
hnmsel = f.Get("overview/hnmsel")
hnenminp = f.Get("overview/hnenminp")
hnenmsel = f.Get("overview/hnenmsel")
# Zeeinp region
hZeeinp = f.Get("rZeeinp/hZeeinp")
# Zeesel region
hZeesel = f.Get("rZeesel/hZeesel")
# Zmminp region
hZmminp = f.Get("rZmminp/hZmminp")
# Zmmsel region
hZmmsel = f.Get("rZmmsel/hZmmsel")
# Zeemminp region
hZeeinp2 = f.Get("rZeemminp/hZeeinp")
hZmminp2 = f.Get("rZeemminp/hZmminp")
hZeemminp = f.Get("rZeemminp/hZeemminp")
# Zeemmsel region
hZeesel2 = f.Get("rZeemmsel/hZeesel")
hZmmsel2 = f.Get("rZeemmsel/hZmmsel")
hZeemmsel = f.Get("rZeemmsel/hZeemmsel")
# In order to be able to make many plots, let's define two generic histogrms to which we can
# assign any of the histograms above:
h1 = hneinp
h2 = hnminp
# Now we format the histograms: lines, colors, axes titles, etc..
# You do not need to learn the commands here unless you are really curious.
# Otherwise just execute the cell.
# Color numbers can be retrived from https://root.cern.ch/doc/master/classTColor.html
# (check for color wheel)
h1.SetLineColor(600) # kBlue
h2.SetLineColor(416+2) # kGreen + 2
# Titles, labels.
# It is enough to set these variables ONLY FOR THE FIRST HISTOGRAM YOU WILL DRAW
# i.e., the one you will call by .Draw(). The rest you will draw by .Draw("same") will only
# contribute with the historam curve.
# Make the x-axis title:
rawtitle = h1.GetTitle()
if ("electron" in rawtitle):
title = rawtitle.replace("electron", "lepton")
elif ("muon" in rawtitle):
title = rawtitle.replace("muon", "lepton")
elif ("ee" in rawtitle):
title = rawtitle.replace("ee", "ll")
elif ("mm" in rawtitle):
title = rawtitle.replace("mm", "ll")
print(title)
h1.SetTitle("")
h1.GetXaxis().SetTitle(title)
h1.GetXaxis().SetTitleOffset(1.25)
h1.GetXaxis().SetTitleSize(0.05)
h1.GetXaxis().SetLabelSize(0.045)
h1.GetXaxis().SetNdivisions(8, 5, 0)
h1.GetYaxis().SetTitle("number of events")
h1.GetYaxis().SetTitleOffset(1.4)
h1.GetYaxis().SetTitleSize(0.05)
h1.GetYaxis().SetLabelSize(0.045)
# Set the maximum of the y axis:
if (h2.GetMaximum()>h1.GetMaximum()):
h1.SetMaximum(h2.GetMaximum()*1.1)
# Make a generically usable legend
l = TLegend(0.65, 0.75, 0.88, 0.87)
l.SetBorderSize(0)
l.SetFillStyle(0000)
# You can change the legend titles from here based on what you are plotting
l.AddEntry(h1,h1.GetName(), "l")
l.AddEntry(h2,h2.GetName(), "l")
# Now we make a canvas and draw our histograms
c = TCanvas("c", "c", 620, 500)
c.SetBottomMargin(0.15)
c.SetLeftMargin(0.15)
c.SetRightMargin(0.15)
h1.Draw()
h2.Draw("same")
l.Draw("same")
c.Draw()
# Don't worry about the error that appears below!
c2 = TCanvas("c2", "c2", 620, 500)
c2.SetBottomMargin(0.15)
c2.SetLeftMargin(0.15)
c2.SetRightMargin(0.15)
hZeemmsel.Draw("colz")
c2.Draw()
# Don't worry about the error that appears below!