{
"cells": [
{
"cell_type": "markdown",
"id": "f40b7065-5763-4abc-91ff-40437cf86517",
"metadata": {},
"source": [
"# Simple $e^+e^- \\to \\mu^+ \\mu^- $ Monte Carlo Event Generator example"
]
},
{
"cell_type": "markdown",
"id": "215df39b-69fc-4f74-b882-3c96f5526783",
"metadata": {},
"source": [
"Differential cross section:\n",
"$$\n",
"\\frac{d \\sigma}{ d \\Omega} = \\frac{\\alpha^2}{4 s } ( 1+ \\cos^2(\\theta))\n",
"$$"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "f7124c5f-9f86-4a0a-ac08-6e30cc55e01d",
"metadata": {},
"outputs": [],
"source": [
"import math\n",
"import random\n",
"\n",
"import hist\n",
"import numpy as np\n",
"\n",
"import pylhe"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "f2553a00-1d72-4d4b-ba6d-c552ca0a7b59",
"metadata": {},
"outputs": [],
"source": [
"alpha = 1 / 127.4 # alpha QED\n",
"aqcd = 0.1075 # alpha QCD\n",
"EB = 209\n",
"s = (2 * EB) ** 2\n",
"theta_min = 0\n",
"theta_max = math.pi\n",
"phi_min = 0\n",
"phi_max = 2 * math.pi"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "7242869e-7fbb-4eee-9d49-8a9d63724e35",
"metadata": {},
"outputs": [],
"source": [
"# https://equation-database.readthedocs.io/en/latest/_autosummary/equation_database.isbn_9780471887416.html#equation_database.isbn_9780471887416.equation_6_32\n",
"\n",
"\n",
"def dsigma(s, theta, _phi):\n",
" return (math.cos(theta) ** 2 + 1) / 4 * alpha**2 / s"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "147dfe17-a5d9-4b68-a07f-6f8d8aa390a1",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Estimated integral: 1.47792134606482e-09\n",
"Real integral: 1.477056777521761e-09\n"
]
}
],
"source": [
"# Monte Carlo integration\n",
"\n",
"\n",
"def monte_carlo_integration(\n",
" func, s, theta_min, theta_max, phi_min, phi_max, num_samples\n",
"):\n",
" theta_samples = [random.uniform(theta_min, theta_max) for _ in range(num_samples)]\n",
" phi_samples = [random.uniform(phi_min, phi_max) for _ in range(num_samples)]\n",
" func_values = [\n",
" (phi_max - phi_min)\n",
" * (theta_max - theta_min)\n",
" * func(s, theta, phi)\n",
" * math.sin(theta)\n",
" for theta, phi in zip(theta_samples, phi_samples)\n",
" ]\n",
" maximum = np.max(func_values)\n",
" integral = np.mean(func_values)\n",
" return integral, maximum\n",
"\n",
"\n",
"# Parameters\n",
"\n",
"num_samples = 1_000_000\n",
"\n",
"# Perform integration\n",
"result, maximum = monte_carlo_integration(\n",
" dsigma, s, theta_min, theta_max, phi_min, phi_max, num_samples\n",
")\n",
"print(f\"Estimated integral: {result}\")\n",
"\n",
"# https://equation-database.readthedocs.io/en/latest/_autosummary/equation_database.isbn_9780471887416.html#equation_database.isbn_9780471887416.equation_6_33\n",
"sigma = 4 * math.pi / 3 * alpha**2 / s\n",
"print(f\"Real integral: {sigma}\")"
]
},
{
"cell_type": "markdown",
"id": "692b7fad-a519-49b8-9dbc-d7d8c27eaba9",
"metadata": {},
"source": [
"## Weighted Events\n",
"\n",
"The information about the distribution is carried by the weights of the events."
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "5c26e5e3-8e1e-470f-96a6-376a6e294bf9",
"metadata": {},
"outputs": [],
"source": [
"num_samples = 1_000_000\n",
"integ = 0.0\n",
"lheevents = []\n",
"for _i in range(num_samples):\n",
" theta = random.uniform(theta_min, theta_max)\n",
" phi = random.uniform(phi_min, phi_max)\n",
" sig = (\n",
" (phi_max - phi_min)\n",
" * (theta_max - theta_min)\n",
" * dsigma(s, theta, phi)\n",
" * math.sin(theta)\n",
" / num_samples\n",
" )\n",
" integ += sig\n",
" # Fill the LHE event\n",
" e = pylhe.LHEEvent(\n",
" eventinfo=pylhe.LHEEventInfo(\n",
" nparticles=5,\n",
" pid=0,\n",
" weight=sig, # The individual weight per event\n",
" scale=s,\n",
" aqed=alpha,\n",
" aqcd=aqcd,\n",
" ),\n",
" particles=[\n",
" pylhe.LHEParticle(\n",
" id=11,\n",
" status=-1,\n",
" mother1=0,\n",
" mother2=0,\n",
" color1=0,\n",
" color2=0,\n",
" px=0.0,\n",
" py=0.0,\n",
" pz=EB,\n",
" e=EB,\n",
" m=0.0,\n",
" lifetime=0,\n",
" spin=9.0,\n",
" ),\n",
" pylhe.LHEParticle(\n",
" id=-11,\n",
" status=-1,\n",
" mother1=0,\n",
" mother2=0,\n",
" color1=0,\n",
" color2=0,\n",
" px=0.0,\n",
" py=0.0,\n",
" pz=-EB,\n",
" e=EB,\n",
" m=0.0,\n",
" lifetime=0,\n",
" spin=9.0,\n",
" ),\n",
" pylhe.LHEParticle(\n",
" id=22,\n",
" status=2,\n",
" mother1=1,\n",
" mother2=2,\n",
" color1=0,\n",
" color2=0,\n",
" px=0.0,\n",
" py=0.0,\n",
" pz=EB - EB,\n",
" e=EB + EB,\n",
" m=0.0,\n",
" lifetime=0,\n",
" spin=9.0,\n",
" ),\n",
" pylhe.LHEParticle(\n",
" id=13,\n",
" status=1,\n",
" mother1=3,\n",
" mother2=3,\n",
" color1=0,\n",
" color2=0,\n",
" px=EB * math.sin(theta) * math.cos(phi),\n",
" py=EB * math.sin(theta) * math.sin(phi),\n",
" pz=EB * math.cos(theta),\n",
" e=EB,\n",
" m=0,\n",
" lifetime=0,\n",
" spin=9.0,\n",
" ),\n",
" pylhe.LHEParticle(\n",
" id=-13,\n",
" status=1,\n",
" mother1=3,\n",
" mother2=3,\n",
" color1=0,\n",
" color2=0,\n",
" px=-EB * math.sin(theta) * math.cos(phi),\n",
" py=-EB * math.sin(theta) * math.sin(phi),\n",
" pz=-EB * math.cos(theta),\n",
" e=EB,\n",
" m=0,\n",
" lifetime=0,\n",
" spin=9.0,\n",
" ),\n",
" ],\n",
" )\n",
" lheevents.append(e)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "2fca49b0-2d93-476a-9b6b-835b72a24bb0",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"