How to discover new particles

Learning goals

  • Relativistic kinematics.
  • Standard model particles.

Background

If you know the mass of a particle, most of the time you know what that particle is. However, there is no way to just build a single detector that gives you the mass. You need to be clever and make use of Special relativity, specifically relativistic kinematics.

To determine the mass ($m$) of a particle you need to know the 4-momenta of the particles ($\mathbf{P}$) that are detected after the collision: the energy ($E$), the momentum in the x direction ($p_x$), the momentum in the y direction ($p_y$), the momentum in the z direction ($p_z$).

$$\mathbf{P} = (E,p_x,p_y,p_z)$$\begin{equation*} m = \sqrt{E^2-(p_x^2+p_y^2 + p_z^2)} \end{equation*}

Let's code!

Here is some sample code that reads in data from a Monte Carlo simulation file from the CMS experiment. It loops over data from many different proton-proton collisions.

For each collision, you can get the 4-momenta of the jets, muons, electrons, and photons produced in these collisions.


In [1]:
inFile = open("data/mc_dy_1000collisions.dat", "r")
import cms_tools
print "Reading in the data...."
collisions = cms_tools.get_collisions(inFile)
    
print len(collisions)

count = 0
for collision in collisions:
    
    jets,muons,electrons,photons,met = collision
    
    count += 1
    
    # To access the information about the particles.

    for jet in jets:
        energy,px,py,pz,btag = jet
        
    for muon in muons:
        energy,px,py,pz,charge = muon

    for electron in electrons:
        energy,px,py,pz,charge = electron
         
    for photon in photons:
        energy,px,py,pz = photon
     # For this exercise we will not work with MET (Missing Energy in the Transverse plane)


Reading in the data....
1000

Challenge!

Copy this sample code and use it to calculate the mass of the muons. Make a histogram of this quantity.

Hint!

Make sure you do this for all the muons! Each collision can produce differing numbers of muons, so take care when you code this up.

Your histogram should look something like the following sketch. The value of the peak, should be the mass of the muon. Check your answer!


In [3]:
from IPython.display import Image
Image(filename='images/muons_sketch.jpeg')


Out[3]:

In [17]:
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

inFile = open("data/mc_dy_1000collisions.dat", "r")
import cms_tools
print "Reading in the data...."
collisions = cms_tools.get_collisions(inFile)
    
print len(collisions)

count = 0
for collision in collisions:
    
    jets,muons,electrons,photons,met = collision
    
    count += 1
    
    # To access the information about the particles.
    mass=[]
    for muon in muons:
        energy,px,py,pz,charge = muon
        mass.append(np.sqrt(np.abs(energy**2-(px**2+py**2+pz**2))))
        print mass
        plt.hist(mass,bins=50)


Reading in the data....
1000
[0.081652066732851261]
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-17-2644e30e8973> in <module>()
     23         mass.append(np.sqrt(np.abs(energy**2-(px**2+py**2+pz**2))))
     24         print mass
---> 25         plt.hist(mass,bins=50)
     26 

C:\Users\Ronnie\Anaconda\lib\site-packages\matplotlib\pyplot.pyc in hist(x, bins, range, normed, weights, cumulative, bottom, histtype, align, orientation, rwidth, log, color, label, stacked, hold, **kwargs)
   2888                       histtype=histtype, align=align, orientation=orientation,
   2889                       rwidth=rwidth, log=log, color=color, label=label,
-> 2890                       stacked=stacked, **kwargs)
   2891         draw_if_interactive()
   2892     finally:

C:\Users\Ronnie\Anaconda\lib\site-packages\matplotlib\axes\_axes.pyc in hist(self, x, bins, range, normed, weights, cumulative, bottom, histtype, align, orientation, rwidth, log, color, label, stacked, **kwargs)
   5556         elif len(flat) == 1 and not binsgiven:
   5557             raise ValueError(
-> 5558                 "x has only one data point. bins or range kwarg must be given")
   5559 
   5560         # Massage 'x' for processing.

ValueError: x has only one data point. bins or range kwarg must be given

Background

Some particles are very unstable and decay (turn into) to two or more other particles. In fact, they can decay so quickly, that they never interact with your detector! Yikes!

However, we can reconstruct the parent particle (sometimes referred to as the initial state particle) and its 4-momentum by adding the 4-momenta of the child particles (sometimes referred to as the decay products).

$$\mathbf{P_{\rm parent}} = \mathbf{P_{\rm child 0}} + \mathbf{P_{\rm child 1}} + \mathbf{P_{\rm child 2}} + ...$$

which breaks down into...

$$E_{\rm parent} = E_{\rm child 0} + E_{\rm child 1} + E_{\rm child 2} + ...$$$$p_{\rm x parent} = p_{\rm x child 0} + p_{\rm x child 1} + p_{\rm x child 2} + ...$$$$p_{\rm y parent} = p_{\rm y child 0} + p_{\rm y child 1} + p_{\rm y child 2} + ...$$$$p_{\rm z parent} = p_{\rm z child 0} + p_{\rm y child 1} + p_{\rm z child 2} + ...$$

Challenge!

Again, starting with the same sample code, add the 4-vectors of the muons and determine the mass and type of the parent particle. Make a histogram of the mass.

Hint!

Some collisions produce more than one muon. You need to add the 4-vectors of the muons from each collision to determine the mass.


In [4]:
inFile = open("data/mc_dy_1000collisions.dat", "r")
import cms_tools
print "Reading in the data...."
collisions = cms_tools.get_collisions(inFile)
    
print len(collisions)

count = 0
for collision in collisions:
    
    jets,muons,electrons,photons,met = collision
    
    count += 1
    
# To find the mass of a muon
    
    for muon in muons:
        energy,px,py,pz,charge = muon
         
# To find the 3 combinations of jets and the mass of the paricle that these jets came from
    
    numjets = []
    number = len(jets)
    numjets.append(number)
    
    for i in range (0,number):
        for j in range (i+1,number):
            for k in range (j+1, number):
                
                energy0,px0,py0,pz0,btag0 = jets[i]
                energy1,px1,py1,pz1,btag1 = jets[j]
                energy2,px2,py2,pz2,btag2 = jets[k]


Reading in the data....
1000

Your histogram should look something like the following sketch. The value of the peak, should be the mass of the parent particle. Check out the standard model to help you decide what the parent particle is. Check your answer!


In [5]:
from IPython.display import Image
Image(filename='images/discovering_sketch_A.jpeg')


Out[5]:

In [2]:
#Your code here

Background

When a parent particle decays, it sometimes produces a spray of jets. Jets are a cone of hadrons that are produced from a collision. You can add together the 4-momenta of the jets to find the mass of the parent particle.

$$\mathbf{P_{\rm parent}} = \mathbf{P_{\rm jet 0}} + \mathbf{P_{\rm jet 1}} + \mathbf{P_{\rm jet 2}} + ...$$

Challenge!

Using the same sample code, add the 4-vectors of the jets and determine the mass and type of the parent particle. Make a histogram of the mass.

Hint!

Make sure you do this for all the combinations of jets! Each collision can produce differing numbers of jets, find all the three combinations of jets to find the parent particle.


In [6]:
inFile = open("data/mc_dy_1000collisions.dat", "r")
import cms_tools
print "Reading in the data...."
collisions = cms_tools.get_collisions(inFile)
    
print len(collisions)

count = 0
for collision in collisions:
    
    jets,muons,electrons,photons,met = collision
    
    count += 1
    
# To find the mass of a muon
    
    for muon in muons:
        energy,px,py,pz,charge = muon
         
# To find the 3 combinations of jets and the mass of the paricle that these jets came from
    
    numjets = []
    number = len(jets)
    numjets.append(number)
    
    for i in range (0,number):
        for j in range (i+1,number):
            for k in range (j+1, number):
                
                energy0,px0,py0,pz0,btag0 = jets[i]
                energy1,px1,py1,pz1,btag1 = jets[j]
                energy2,px2,py2,pz2,btag2 = jets[k]


Reading in the data....
1000

Your histogram should look something like the following sketch. The value of the peak should be the mass of the parent particle. Check your answer!


In [7]:
from IPython.display import Image
Image(filename='images/discovering_sketch_B.jpeg')


Out[7]:

In [3]:
#your code here