{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "(rawdata)=\n", "# Datos sin preprocesar\n", "Los dos conjuntos de datos utilizados en este trabajo, como se explica en la {numref}`datos`, poseen señales similares de nueva física, que se diferencian por las masas de las partículas BSM y las fracción de eventos de señal. En esta sección se realizará una breve exploración de los datos R&D y BB1 publicados para las LHCO 2020. \n", "\n", "```{figure} ./../../figuras/lhco-RnD.png\n", "---\n", "name: rawdata-senal\n", "figclass: margin\n", "---\n", "Diagrama de Feynmann para la señal.\n", "```\n", "Para esta sección, utilizamos los primeros 100,000 eventos de cada conjunto de datos por dos razones: utilizar todos los eventos no es posible porque requiere una gran cantidad de memoria y 100,000 eventos son suficientes para observar las distribuciones de los datos. Los datos utilizados representan el 9% y el 10% de los eventos del conjunto R&D y BB1, respectivamente, y poseen la misma proporción de señal y fondo que cada uno de los conjuntos en su totalidad." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "tags": [ "remove-cell" ] }, "outputs": [], "source": [ "# Importamos las librerías principales\n", "import pandas as pd\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "from myst_nb import glue\n", "from PIL import Image\n", "import os\n", "\n", "# Funciones de benchtools\n", "from benchtools.src.datatools import ascii_column\n", "from benchtools.src.plotools import bkg_sig_hist, create_png, image_grid\n", "\n", "# Definimos variables globales\n", "PATH_IMAGES = '../../figuras/'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "(rawdata-estruc)=\n", "## Estructura\n", "El conjunto de datos R&D y BB1 publicados para las olimpiadas posee un evento por fila, con la información de $pT$, $\\eta$ y $\\phi$ para cada hadrón del evento, como se muestra en {numref}`rawdata-rawdataframe`. La diferencia estructural entre ambos archivos es que el conjunto R&D tiene la etiqueta del evento en la última columna (señal o fondo), mientras que para el conjunto BB1 la etiqueta se encuentra en un archivo aparte.\n", "\n", "```{table} Estructura del conjunto de datos R&D. Cada fila es un evento y la última columna hace referencia a si el evento es fondo (0) o señal (1).\n", ":name: rawdata-rawdataframe\n", "|Evento |$pT$ | $\\eta$ | $\\phi$ | $pT$ | $\\eta$ | $\\phi$ | $\\cdots$| señal |\n", "|---------|---------|---------|---------|---------|---------|---------|---------|-------|\n", "| 1 | $\\cdots$| $\\cdots$| $\\cdots$| $\\cdots$| $\\cdots$| $\\cdots$| $\\cdots$| 1.0 |\n", "| 2 | $\\cdots$| $\\cdots$| $\\cdots$| $\\cdots$| $\\cdots$| $\\cdots$| $\\cdots$| 0.0 |\n", "| $\\vdots$| $\\cdots$| $\\cdots$| $\\cdots$| $\\cdots$| $\\cdots$| $\\cdots$| $\\cdots$| 0.0 |\n", "```\n", "El conjunto R&D posee 1,000,000 de eventos de fondo y 100,000 de señal (aproximadamente 9.09% de los eventos son señal). En este conjunto las partículas $Z'$, $X$ y $Y$ tienen masas de 3.5 TeV, 500 GeV y 100 GeV, respectivamente. En el conjunto BB1, las partículas $Z'$, $X$ y $Y$ tienen masas de 3,823 TeV, 732 GeV y 378 GeV, respectivamente, con un porcentaje menor de señal: de 1,000,000 de eventos, 834 son señal, es decir, el 0.08% es señal, como se discutió en la {numref}`datos`.\n", "\n", "La información de los primeros 5 eventos del conjunto R&D se puede observar en la {numref}`df-raw`." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "tags": [ "remove-cell" ] }, "outputs": [ { "data": { "application/papermill.record/text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
0123456789...2091209220932094209520962097209820992100
00.324101-0.3611582.7376690.409859-2.4299390.7298300.867922-2.267777-1.1613100.383031...0.00.00.00.00.00.00.00.00.00.0
10.646304-0.539460-1.3862580.471293-1.6365720.7516570.453769-1.099593-0.3934050.485929...0.00.00.00.00.00.00.00.00.00.0
20.325172-0.8339482.4048441.295058-2.089618-1.8733420.451272-0.1018772.2173480.461293...0.00.00.00.00.00.00.00.00.00.0
30.290918-2.2000631.6301320.565028-1.714345-2.6171030.951042-0.5327202.9414730.896248...0.00.00.00.00.00.00.00.00.00.0
40.526330-2.349110-1.7455320.542491-2.080352-3.0440450.390727-1.278563-2.1310582.530358...0.00.00.00.00.00.00.00.00.01.0
\n

5 rows × 2101 columns

\n
", "application/papermill.record/text/plain": " 0 1 2 3 4 5 6 \\\n0 0.324101 -0.361158 2.737669 0.409859 -2.429939 0.729830 0.867922 \n1 0.646304 -0.539460 -1.386258 0.471293 -1.636572 0.751657 0.453769 \n2 0.325172 -0.833948 2.404844 1.295058 -2.089618 -1.873342 0.451272 \n3 0.290918 -2.200063 1.630132 0.565028 -1.714345 -2.617103 0.951042 \n4 0.526330 -2.349110 -1.745532 0.542491 -2.080352 -3.044045 0.390727 \n\n 7 8 9 ... 2091 2092 2093 2094 2095 2096 \\\n0 -2.267777 -1.161310 0.383031 ... 0.0 0.0 0.0 0.0 0.0 0.0 \n1 -1.099593 -0.393405 0.485929 ... 0.0 0.0 0.0 0.0 0.0 0.0 \n2 -0.101877 2.217348 0.461293 ... 0.0 0.0 0.0 0.0 0.0 0.0 \n3 -0.532720 2.941473 0.896248 ... 0.0 0.0 0.0 0.0 0.0 0.0 \n4 -1.278563 -2.131058 2.530358 ... 0.0 0.0 0.0 0.0 0.0 0.0 \n\n 2097 2098 2099 2100 \n0 0.0 0.0 0.0 0.0 \n1 0.0 0.0 0.0 0.0 \n2 0.0 0.0 0.0 0.0 \n3 0.0 0.0 0.0 0.0 \n4 0.0 0.0 0.0 1.0 \n\n[5 rows x 2101 columns]" }, "metadata": { "scrapbook": { "mime_prefix": "application/papermill.record/", "name": "df-raw" } }, "output_type": "display_data" } ], "source": [ "# Cargamos 100,000 eventos\n", "path_data = \"../../../datos/events_anomalydetection.h5\"\n", "df_RnD = pd.read_hdf(path_data, stop=100000)\n", "glue(\"df-raw\", df_RnD.head(), display=False)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```{glue:figure} df-raw\n", ":figwidth: 600px\n", ":name: \"df-raw\"\n", "\n", "Primeros 5 eventos de los datos R&D. Cada fila representa un evento y cada columna representa una medida de la cinemática de un hadrón, como se muestra en la {numref}`rawdata-rawdataframe`. La columna 2100 representa la etiqueta del evento (señal o fondo).\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Cada evento tiene un número distinto de hadrones. Por ejemplo, los primeros eventos del conjunto R&D tienen:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "tags": [ "remove-input" ] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Evento 0: 109 hadrones\n", "Evento 1: 208 hadrones\n", "Evento 2: 196 hadrones\n", "Evento 3: 183 hadrones\n", "Evento 4: 169 hadrones\n" ] } ], "source": [ "# Eliminamos la señal para evitar contar los hadrónes\n", "ns_df_RnD = df_RnD.iloc[:,:-1] \n", "\n", "# Contamos los valores de pT distintos de cero\n", "df_RnD['n_hadrons'] = ns_df_RnD.iloc[:,::3].gt(0).sum(axis='columns')\n", "\n", "# Imprimimos para los primeros 5 eventos \n", "for event in range(5):\n", " print(\"Evento {}: {} hadrones\".format(event, df_RnD.loc[event,'n_hadrons']))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "(rawdata-dist)=\n", "## Distribuciones\n", "Para ambos conjuntos, las distribuciones de los datos son similares. La diferencia más evidente es la proporción de eventos de señal, que requiere de histogramas con menos contenedores para el conjunto con menor proporción de señal, es decir, para el conjunto BB1." ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "tags": [ "remove-cell" ] }, "outputs": [], "source": [ "# Cargamos 100,000 eventos de los datos BB1 \n", "df_BB1_nk = pd.read_hdf('../../../datos/events_LHCO2020_BlackBox1.h5', stop=100000)\n", "# Cargamos las estiquetas\n", "df_key = ascii_column('../../../datos/events_LHCO2020_BlackBox1.masterkey', column_name=2100)\n", "# Juntamos los dataframes\n", "df_BB1 = pd.concat([df_BB1_nk, df_key.iloc[:100000]], axis=1, sort=False)\n", "# Contamos el numero de hadrónes\n", "# Eliminamos la señal para evitar contar los hadrónes\n", "ns_df_BB1 = df_BB1.iloc[:,:-1] \n", "df_BB1['n_hadrons'] = ns_df_BB1.iloc[:,::3].gt(0).sum(axis='columns')" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "tags": [ "remove-cell" ] }, "outputs": [ { "data": { "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "for name, df in zip(['R&D', 'BB1'], [df_RnD,df_BB1]):\n", " # Graficamos utilizando benchtools\n", " fig = plt.figure(facecolor='white', figsize=(6,8));\n", " bkg_sig_hist(df, variable='n_hadrons', label=2100, xlabel='Nro. de hadrones', ylabel='Densidad de eventos' , n_bins=20); # label=2100 porque esa es la columna de señal\n", " plt.title('Nro. hadrones {}'.format(name))\n", " plt.savefig(os.path.join('../../figuras/','rawdata-{}-nhadrons.png'.format(name)), bbox_inches='tight', facecolor=fig.get_facecolor(),edgecolor='none')\n", " plt.clf()\n", "\n", "# Creamos un grid de las imagenes usando benchtools\n", "imagenes = ['./../../figuras/rawdata-R&D-nhadrons.png', './../../figuras/rawdata-BB1-nhadrons.png']\n", "image_grid(rows=1, columns=2, images=imagenes, name='rawdata-nhadrones', path=PATH_IMAGES, remove=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```{figure} ./../../figuras/rawdata-nhadrones.png\n", "---\n", "name: rawdata-nhadrones\n", "width: 80%\n", "---\n", "Distribución del número de hadrones para eventos de señal y fondo. A la izquierda el conjunto R&D y a la derecha el conjunto BB1.\n", "```" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "tags": [ "remove-cell" ] }, "outputs": [ { "data": { "application/papermill.record/text/plain": "139.69080472458327" }, "metadata": { "scrapbook": { "mime_prefix": "application/papermill.record/", "name": "mean_nhad_RnD_sig" } }, "output_type": "display_data" }, { "data": { "application/papermill.record/text/plain": "147.025" }, "metadata": { "scrapbook": { "mime_prefix": "application/papermill.record/", "name": "mean_nhad_BB1_sig" } }, "output_type": "display_data" }, { "data": { "application/papermill.record/text/plain": "171.3385711615223" }, "metadata": { "scrapbook": { "mime_prefix": "application/papermill.record/", "name": "mean_nhad_RnD_bkg" } }, "output_type": "display_data" }, { "data": { "application/papermill.record/text/plain": "173.6753903122498" }, "metadata": { "scrapbook": { "mime_prefix": "application/papermill.record/", "name": "mean_nhad_BB1_bkg" } }, "output_type": "display_data" } ], "source": [ "# En esta celda calculamos la media del numero de hadrónes de la figura anterior\n", "# Señal\n", "mean_nhad_RnD_sig = df_RnD.loc[df_RnD[2100]==1]['n_hadrons'].mean()\n", "mean_nhad_BB1_sig = df_BB1.loc[df_BB1[2100]==1]['n_hadrons'].mean()\n", "# Fondo\n", "mean_nhad_RnD_bkg = df_RnD.loc[df_RnD[2100]==0]['n_hadrons'].mean()\n", "mean_nhad_BB1_bkg = df_BB1.loc[df_BB1[2100]==0]['n_hadrons'].mean()\n", "\n", "glue(\"mean_nhad_RnD_sig\", mean_nhad_RnD_sig, display=False)\n", "glue(\"mean_nhad_BB1_sig\", mean_nhad_BB1_sig, display=False)\n", "glue(\"mean_nhad_RnD_bkg\", mean_nhad_RnD_bkg, display=False)\n", "glue(\"mean_nhad_BB1_bkg\", mean_nhad_BB1_bkg, display=False)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Como se puede ver en la {numref}`rawdata-nhadrones`, el conjunto R&D posee una media de {glue:text}`mean_nhad_RnD_sig:.0f` hadrones por evento para la señal, y de {glue:text}`mean_nhad_RnD_bkg:.0f` hadrones por evento para el fondo. El conjunto BB1 es similar, con una media de {glue:text}`mean_nhad_BB1_sig:.0f` y {glue:text}`mean_nhad_BB1_bkg:.0f` hadrones por evento para señal y fondo, respectivamente. En general, los eventos de señal producen menos hadrones. Esto está relacionado con la naturaleza de los eventos; los eventos de fondo poseen más hadrones por evento que los de señal, porque en general provienen de jets de gluones, que generan más radiación de partículas{cite}`Aad_2014`.\n", "\n", "Las distribuciones de la media de las variables $pT$, $\\eta$ y $\\phi$ por evento se pueden ver en las {numref}`rawdata-meanRnD` y {numref}`rawdata-meanBB1`, para el conjunto R&D y el conjunto BB1, respectivamente." ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "tags": [ "remove-cell" ] }, "outputs": [ { "data": { "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# En esta celda graficamos la distribución del valor medio de pT, eta y phi de cada evento.\n", "\n", "# Cada 3 valores es pT, cada 3 empezando por 1 es eta \n", "# y cada 3 empezando por 2 es phi.\n", "# Remplazamos los ceros con NaN para poder utilizar .mean()\n", "for name, ns_df, df, nbins in zip(['R&D', 'BB1'], [ns_df_RnD, ns_df_BB1], [df_RnD,df_BB1], [50,20]):\n", " pt_df = ns_df.iloc[:,::3].replace(0, np.NaN)\n", " eta_df = ns_df.iloc[:,1::3].replace(0, np.NaN)\n", " phi_df = ns_df.iloc[:,2::3].replace(0, np.NaN)\n", "\n", " # Calculamos la media de cada evento\n", " df['mean_pT'] = pt_df.mean(axis=1)\n", " df['mean_eta']= eta_df.mean(axis=1)\n", " df['mean_phi']= phi_df.mean(axis=1)\n", "\n", " # Graficamos cada variable\n", " variables = ['mean_pT', 'mean_eta', 'mean_phi']\n", " names = [r'$\\langle p_T\\rangle$ de las partículas',r'$\\langle\\eta\\rangle$ de las partículas', r'$\\langle\\phi\\rangle$ de las partículas']\n", " for variable, name_var in zip(variables,names):\n", " fig = plt.figure(facecolor='white')\n", " bkg_sig_hist(df, variable, label=2100, xlabel=name_var, ylabel='Densidad de eventos', n_bins=nbins)\n", " plt.title(r'{}: Distribución de '.format(name)+name_var)\n", " plt.savefig(os.path.join('../../figuras/','rawdata-{}-{}.png'.format(variable,name)), bbox_inches='tight', facecolor=fig.get_facecolor(),edgecolor='none')\n", " plt.clf()\n", "\n", "# Creamos un grid para RnD\n", "imagenes = ['./../../figuras/rawdata-mean_pT-R&D.png', \n", "'./../../figuras/rawdata-mean_eta-R&D.png',\n", "'./../../figuras/rawdata-mean_phi-R&D.png']\n", "image_grid(rows=1, columns=3, images=imagenes, name='rawdata-means-RnD', path=PATH_IMAGES, remove=True)\n", "\n", "# Creamos un grid para BB1\n", "imagenes = ['./../../figuras/rawdata-mean_pT-BB1.png', \n", "'./../../figuras/rawdata-mean_eta-BB1.png',\n", "'./../../figuras/rawdata-mean_phi-BB1.png']\n", "image_grid(rows=1, columns=3, images=imagenes, name='rawdata-means-BB1', path=PATH_IMAGES, remove=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```{figure} ./../../figuras/rawdata-means-RnD.png\n", "---\n", "name: rawdata-meanRnD\n", "width: 100%\n", "---\n", "Distribución de la media de $pT$, $\\eta$ y $\\phi$ para las partículas de los eventos del conjunto R&D.\n", "```\n", "\n", "```{figure} ./../../figuras/rawdata-means-BB1.png\n", "---\n", "name: rawdata-meanBB1\n", "width: 100%\n", "---\n", "Distribución de la media de $pT$, $\\eta$ y $\\phi$ para las partículas de los eventos del conjunto BB1.\n", "```" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "tags": [ "remove-cell" ] }, "outputs": [ { "data": { "application/papermill.record/text/plain": "25.247649677146946" }, "metadata": { "scrapbook": { "mime_prefix": "application/papermill.record/", "name": "meanpt_sig_RnD" } }, "output_type": "display_data" }, { "data": { "application/papermill.record/text/plain": "19.19757850577501" }, "metadata": { "scrapbook": { "mime_prefix": "application/papermill.record/", "name": "meanpt_bkg_RnD" } }, "output_type": "display_data" }, { "data": { "application/papermill.record/text/plain": "25.202933721950238" }, "metadata": { "scrapbook": { "mime_prefix": "application/papermill.record/", "name": "meanpt_sig_BB1" } }, "output_type": "display_data" }, { "data": { "application/papermill.record/text/plain": "19.942760435054584" }, "metadata": { "scrapbook": { "mime_prefix": "application/papermill.record/", "name": "meanpt_bkg_BB1" } }, "output_type": "display_data" } ], "source": [ "# En esta celda calculamos los valores medios de pT de las figuras anteriores\n", "meanpt_sig_RnD = df_RnD.loc[df_RnD.iloc[:,2100]==1]['mean_pT'].mean()\n", "meanpt_bkg_RnD = df_RnD.loc[df_RnD.iloc[:,2100]==0]['mean_pT'].mean()\n", "meanpt_sig_BB1 = df_BB1.loc[df_BB1.iloc[:,2100]==1]['mean_pT'].mean()\n", "meanpt_bkg_BB1 = df_BB1.loc[df_BB1.iloc[:,2100]==0]['mean_pT'].mean()\n", "\n", "glue(\"meanpt_sig_RnD\", meanpt_sig_RnD, display=False)\n", "glue(\"meanpt_bkg_RnD\", meanpt_bkg_RnD , display=False)\n", "glue(\"meanpt_sig_BB1\", meanpt_sig_BB1, display=False)\n", "glue(\"meanpt_bkg_BB1\", meanpt_bkg_BB1, display=False)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Las distribuciones de la señal son más claras en la {numref}`rawdata-meanRnD` que en la {numref}`rawdata-meanBB1`, debido a que hay mayor cantidad de eventos de señal. $\\phi$ y $\\eta$ no parecen diferir notablemente entre eventos de señal y fondo. Sin embargo, se observa que los valores de $pT$ difieren, siendo el $pT$ de los eventos de señal mayor que el $pT$ de los eventos de fondo, debido a que se requiere una mayor transferencia de momento para crear la partícula de nueva física.\n", "\n", "En el caso del conjunto R&D, se tiene una media de $pT$ de {glue:text}`meanpt_sig_RnD:.0f` y {glue:text}`meanpt_bkg_RnD:.0f` GeV para señal y fondo, respectivamente. Para el conjunto BB1 las medias son de {glue:text}`meanpt_sig_BB1:.0f` y {glue:text}`meanpt_bkg_BB1:.0f` GeV. En general, la media de $pT$ de los eventos de señal es mayor.\n", "\n", "Para poder entender los procesos físicos de los eventos, es necesario agrupar los datos en jets. Esto se hará en la siguiente sección." ] } ], "metadata": { "celltoolbar": "Tags", "interpreter": { "hash": "be244558907c567e73a32fad5ffef5514602d6da01bb2b6b51508d7e46fcc84d" }, "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.11" } }, "nbformat": 4, "nbformat_minor": 2 }