Particle Hunter

Particle decay width and lifetime

Background

I’m currently working on a physics analysis that involves a unique signature of an LLP (Long Lived Particle) that decay into two particles with a distinct angle (kinked). Anyway trying to work on this and produce MC (Monte-Carlo) data using Gauss (LHCb simulation framework) is proving challenging. One of the interesting things I needed to do and invistigate later because it was puzzling was the adding these new particles so that Geant4 inside Gauss would be able to simulate them. The important thing in adding a new particle to Geant4 is to define the G4ParticleTable which contains the information about the particle properties. This is done by adding a new entry to the G4ParticleTable which is a G4ParticleDefinition object. This object contains the following information about the particle:

name        mass          width           charge
2*spin      parity        C-conjugation
2*Isospin   2*Isospin3    G-parity
type        lepton number baryon number   PDG encoding
stable      lifetime      decay table
shortlived  subType       anti_encoding

For example the case of the Gravitino (a hypothetical particle that is the superpartner of the graviton) is defined as:

name,    3.6e-19*CLHEP::GeV,       0*CLHEP::GeV,         0.0, 
+3/2,              +1,             0,          
0,               0,             0,             
"supersymmetric",               0,             0,          1000039,
true,             0.0,          NULL,
false,            "Gravitino"

But I needed to understand more about the relation between the decay width and lifetime of a particle. I will give some discussion about this and how to calculate them.

What is particle decay width and lifetime?

In the realm of quantum mechanics, the decay of unstable particles is an intriguing phenomenon. Unstable particles are those that have a finite lifetime, and they naturally transition into other particles over time. This transformation, known as particle decay, is a random process that follows certain probabilistic rules. Two key quantities are associated with the decay process: the decay width (often denoted as Γ) and the lifetime (τ) of the particle. The uncertainty principle establishes a connection between these two quantities, which can be used to calculate and understand the behavior of decaying particles.

The decay width of a particle is a measure of the rate of its decay. Mathematically, it is defined as the probability of decay per unit time. The larger the decay width, the higher the probability that the particle will decay within a given time interval. Decay width is closely related to the concept of resonance in quantum mechanics, and it provides insight into the stability of a particle. On the other hand, the lifetime of a particle is the average time that a particle exists before it decays. It is an important quantity in determining the stability of particles, as particles with longer lifetimes are more stable. The lifetime is the inverse of the decay rate and can be expressed in terms of the decay width. The relationship between decay width and lifetime is given by the equation:

ΔxΔp2

The Uncertainty Principle comes into play

The Heisenberg uncertainty principle is a fundamental principle in quantum mechanics that establishes a limit on the precision with which certain pairs of physical quantities can be simultaneously known. The most famous example of the uncertainty principle is the trade-off between the uncertainty in position (Δx) and the uncertainty in momentum (Δp), which is given by the equation:

ΔxΔp2where ℏ is the reduced Planck constant.

The uncertainty principle also applies to energy and time, and it is this relationship that is particularly relevant to the study of particle decay. The uncertainty in energy (ΔE) and the uncertainty in time (Δt) are related by the equation:

ΔEΔt2In the context of particle decay as we are discussing here, the uncertainty in energy is associated with the decay width (Γ), and the uncertainty in time is associated with the lifetime (τ) of the particle. Substituting these quantities into the uncertainty principle, we get:

Γτ2Rearranging the equation, we find the expression for the lifetime of the particle in terms of the decay width:

τ2Γ

This equation shows that there is an inverse relationship between the decay width and the lifetime of the particle, which is in accordance with the earlier statement that the lifetime is the inverse of the decay rate. The uncertainty principle provides a theoretical lower limit on the lifetime of a particle based on its decay width.

Now we usually report the lifetime in unit of seconds and width in the unit of inverse seconds. But in HEP we usually use natural units where things start to be more flexible. In natural units, the Planck constant is set to 1, and the speed of light is set to 1. This means that the width can have units of GeV (Giga electron volts) and the lifetime can have units of seconds. Now if we go back to Geant4, it does expect the lifetime in seconds and the width in GeV (at least Gauss). So we need to convert the units. I get confused for sometime at this and was worried about implications of this. But I think I have a better understanding now. We agree now that the width and lifetime of a particle are related through the uncertainty principle. The relation between the two is given again by:

Γ=τ

Converting between the width and lifetime

In Geant4, the width and lifetime should be consistent with this relation. You can either set both width and lifetime manually according to your knowledge of the particle or set one of them and calculate the other using the uncertainty principle.

For example, if you know the width and want to calculate the lifetime:

G4double stauWidth = 1.0*CLHEP::MeV; // Example width value
G4double stauLifetime = CLHEP::hbar_Planck / stauWidth;

Or if you know the lifetime and want to calculate the width:

G4double stauLifetime = 1.0e-9*CLHEP::s; // Example lifetime value
G4double stauWidth = CLHEP::hbar_Planck / stauLifetime;

I decided to write a simple c++ program to do the calculations and conversion between the width (in different units) and lifetime. The name stau_calculator is just a placeholder. You can use it for any particle (Actually any name). This happen to be the particle I am working with.

Here is the code:

// stau_calculator.cpp
// Author: Mohamed Elashri <mail@elashri.com>
// Date: 2023-04-13
// Compile: g++ -o stau_calculator stau_calculator.cpp
// Usage: ./stau_calculator <lifetime_in_ns>
// i.e:
// ./stau_calculator width 1GeV
// ./stau_calculator width 1MeV
// ./stau_calculator lifetime 1s
// ./stau_calculator lifetime 1ns

#include <iostream>
#include <cstdlib>
#include <iomanip>
#include <stdexcept>
#include <string>
#include <regex>

// Physical constants
const double hbar_Planck = 6.582119569e-16; // eV s, reduced Planck constant
const double MeV = 1.0e6;                  // eV, 1 MeV in eV
const double GeV = 1.0e9;                  // eV, 1 GeV in eV
const double s = 1.0;                      // s, 1 second in s
const double ns = 1.0e-9;                  // s, 1 nanosecond in s

void calculateWidthAndLifetime(double inputWidth, double inputLifetime_s, double inputLifetime_ns, double& outputWidth, double& outputLifetime_s, double& outputLifetime_ns) {
    if (inputWidth > 0) {
        outputWidth = inputWidth;
        outputLifetime_s = hbar_Planck / inputWidth;
        outputLifetime_ns = outputLifetime_s / ns; // Convert output lifetime to ns
    } else if (inputLifetime_s > 0) {
        outputLifetime_s = inputLifetime_s;
        outputWidth = hbar_Planck / inputLifetime_s;
        outputLifetime_ns = outputLifetime_s / ns; // Convert output lifetime to ns
    } else if (inputLifetime_ns > 0) {
        outputLifetime_ns = inputLifetime_ns;
        outputLifetime_s = inputLifetime_ns * ns;
        outputWidth = hbar_Planck / outputLifetime_s;
    } else {
        outputWidth = -1;
        outputLifetime_s = -1;
        outputLifetime_ns = -1;
    }
}

int main(int argc, char* argv[]) {
    if (argc < 3) {
        std::cerr << "Usage: " << argv[0] << " <type: width | lifetime> <value_with_unit>" << std::endl;
        return 1;
    }

    std::string inputType(argv[1]);
    std::string inputValueWithUnit(argv[2]);

    std::regex valueRegex("(\\d+(\\.\\d+)?)([a-zA-Z]+)");
    std::smatch match;

    if (!std::regex_match(inputValueWithUnit, match, valueRegex)) {
        std::cerr << "Error: invalid input value format" << std::endl;
        return 1;
    }

    double inputValue = std::stod(match[1]);
    std::string unit = match[3];

    double inputWidth = -1;
    double inputLifetime_s = -1;
    double inputLifetime_ns = -1;

        if (inputType == "width") {
            if (unit == "GeV") {
                inputWidth = inputValue * GeV;
            } else if (unit == "MeV") {
                inputWidth = inputValue * MeV;
            } else {
                std::cerr << "Error: invalid width unit" << std::endl;
                return 1;
        }
        } 
        
        else if (inputType == "lifetime") {
        if (unit == "s") {
            inputLifetime_s = inputValue;
        } else if (unit == "ns") {
            inputLifetime_ns = inputValue;
        } else {
            std::cerr << "Error: invalid lifetime unit" << std::endl;
            return 1;
        }
        } 
    
        else {
            std::cerr << "Error: invalid input type" << std::endl;
            return 1;
        }

    double outputWidth, outputLifetime_s, outputLifetime_ns;

    calculateWidthAndLifetime(inputWidth, inputLifetime_s, inputLifetime_ns, outputWidth, outputLifetime_s, outputLifetime_ns);

    std::cout << "Stau width in MeV: " << outputWidth / MeV << " MeV" << std::endl;
    std::cout << "Stau width in GeV: " << outputWidth / GeV << " GeV" << std::endl;
    std::cout << "Stau lifetime in s: " << outputLifetime_s << " s" << std::endl;
    std::cout << "Stau lifetime in ns: " << outputLifetime_ns << " ns" << std::endl;

    return 0;
}

The program takes command-line arguments to specify the input type (width or lifetime) and the corresponding value with the unit. Based on the input, it calculates the stau width and lifetime and prints the results in various units. To use the program, compile it with a C++ compiler:

g++ -o stau_calculator stau_calculator.cpp

Then, run the compiled program with the input type and value. The input type can be either width or lifetime, and the value should be followed by the unit. For width input, the program accepts GeV and MeV units. For lifetime input, the program accepts s (seconds) and ns (nanoseconds) units.

Examples

  1. Example I

stau properties for a given width in MeV

./stau_calculator width 1GeV

stau properties for a given width in MeV Which gives the following output:

Stau width in MeV: 1000 MeV
Stau width in GeV: 1 GeV
Stau lifetime in s: 6.58212e-25 s
Stau lifetime in ns: 0.000658212 ns
  1. Example II

stau properties for a given lifetime in seconds

./stau_calculator lifetime 1s

which gives the following output:

Stau width in MeV: 9.52517e-22 MeV
Stau width in GeV: 9.52517e-25 GeV
Stau lifetime in s: 1 s
Stau lifetime in ns: 1e+09 ns
  1. Example III

stau properties for a given lifetime in nanoseconds

./stau_calculator lifetime 1ns

which gives the following output:

Stau width in MeV: 9.52517e-13 MeV
Stau width in GeV: 9.52517e-16 GeV
Stau lifetime in s: 1e-09 s
Stau lifetime in ns: 1 ns

With this simple C++ program, you can easily calculate the width and lifetime of a stau particle for a given input. This might be trivial but for my surprise it took some time for me to deal with these things. So i hope this will be useful for someone else struggling in silence like a typical PhD student.

#LHCb #HEP #C++