A more difficult notebook in python

In this notebook you can find a more difficult program that shows further high energy physics (HEP) analysis techniques.

The following analysis is searching for events where Z bosons decay to two leptons of same flavour and opposite charge (to be seen for example in the Feynman diagram).

First of all - like we did it in the first notebook - ROOT is imported to read the files in the .root data format.

In [1]:
import ROOT
Welcome to JupyROOT 6.08/04

In order to activate the interactive visualisation of the histogram that is later created we can use the JSROOT magic:

In [2]:
%jsroot on

Next we have to open the data that we want to analyze. As described above the data is stored in a *.root file.

In [3]:
f = ROOT.TFile.Open("mc_105986.ZZ.root")
#f = ROOT.TFile.Open("mc_147770.Zee.root")
#f = ROOT.TFile.Open("http://opendata.atlas.cern/release/samples/MC/mc_147770.Zee.root")

After the data is opened we create a canvas on which we can draw a histogram. If we do not have a canvas we cannot see our histogram at the end. Its name is Canvas and its header is c. The two following arguments define the width and the height of the canvas.

In [4]:
canvas = ROOT.TCanvas("Canvas","c",800,600)

The next step is to define a tree named t to get the data out of the .root file.

In [5]:
tree = f.Get("mini")

Now we define a histogram that will later be placed on this canvas. Its name is variable, the header of the histogram is Mass of the Z boson, the x axis is named mass [GeV] and the y axis is named events. The three following arguments indicate that this histogram contains 30 bins which have a range from 40 to 140.

In [6]:
hist = ROOT.TH1F("variable","Mass of the Z boson; mass [GeV]; events",30,40,140)

Time to fill our above defined histogram. At first we define some variables and then we loop over the data. We also make some cuts as you can see in the # comments.

In [7]:
leadLepton  = ROOT.TLorentzVector()
trailLepton = ROOT.TLorentzVector()

for event in tree:
    
    # Cut #1: At least 2 leptons
    if tree.lep_n == 2:
        
        # Cut #2: Leptons with opposite charge
        if (tree.lep_charge[0] != tree.lep_charge[1]):
            
            # Cut #3: Leptons of the same family (2 electrons or 2 muons)
            if (tree.lep_type[0] == tree.lep_type[1]):
                
                # Let's define one TLorentz vector for each, e.i. two vectors!
                leadLepton.SetPtEtaPhiE(tree.lep_pt[0]/1000., tree.lep_eta[0], tree.lep_phi[0], tree.lep_E[0]/1000.)
                trailLepton.SetPtEtaPhiE(tree.lep_pt[1]/1000., tree.lep_eta[1], tree.lep_phi[1], tree.lep_E[1]/1000.)
                # Next line: addition of two TLorentz vectors above --> ask mass very easy (devide by 1000 to get value in GeV)
                invmass = leadLepton + trailLepton
                
                hist.Fill(invmass.M())

After filling the histogram we want to see the results of the analysis. First we draw the histogram on the canvas and then the canvas on which the histogram lies.

In [8]:
hist.Draw()
In [9]:
canvas.Draw()