<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 <CENTER>
    <a href="http
Step1:  In order to activate the interactive visualisation of the histogram that is later created we can use the JSROOT magic
Step2:  Next we have to open the data that we want to analyze. As described above the data is stored in a *.root file.
Step3:  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.
Step4:  The next step is to define a tree named t to get the data out of the .root file.
Step5:  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.
Step6:  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.
Step7:  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.
<ASSISTANT_TASK:>
Python Code:
import ROOT
Explanation: <CENTER>
    <a href="http://opendata.atlas.cern" class="icons"><img src="http://opendata.atlas.cern/DataAndTools/pictures/opendata-top-transblack.png" style="width:40%"></a>
</CENTER>
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).
<CENTER><img src="Z_ElectronPositron.png" style="width:40%"></CENTER>
First of all - like we did it in the first notebook - ROOT is imported to read the files in the .root data format.
End of explanation
%jsroot on
Explanation: In order to activate the interactive visualisation of the histogram that is later created we can use the JSROOT magic:
End of explanation
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")
Explanation: Next we have to open the data that we want to analyze. As described above the data is stored in a *.root file.
End of explanation
canvas = ROOT.TCanvas("Canvas","c",800,600)
Explanation: 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.
End of explanation
tree = f.Get("mini")
Explanation: The next step is to define a tree named t to get the data out of the .root file.
End of explanation
hist = ROOT.TH1F("variable","Mass of the Z boson; mass [GeV]; events",30,40,140)
Explanation: 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.
End of explanation
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())
Explanation: 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.
End of explanation
hist.Draw()
canvas.Draw()
Explanation: 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.
End of explanation
<END_TASK>