{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"<div style=\"padding:20px; \n            color:#150d0a;\n            margin:10px;\n            font-size:220%;\n            text-align:center;\n            display:fill;\n            border-radius:20px;\n            border-width: 5px;\n            border-style: solid;\n            border-color: #150d0a;\n            background-color:#eca912;\n            overflow:hidden;\n            font-weight:500\">Ice cube Neutriono Direction prediction challenge</div>\n\n# 1. The objective\n\nThe goal of the project is predict the direction of the neutrino events given their interaction in the detector. \n\nIn other simple words we have a distrubution of points in 3D space (or 4D space)\nFirst, the data looks as follows","metadata":{}},{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport timeit\nimport numpy as np # linear algebra\nfrom numpy import cos, sin\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport pyarrow.parquet as pq\nimport plotly.graph_objects as go\nimport plotly.express as px\nimport plotly\nfrom plotly.subplots import make_subplots\n\nplotly.offline.init_notebook_mode (connected = True)\nplotly.io.templates.default = \"seaborn\"\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\n\ninput_dir = \"/kaggle/input/icecube-neutrinos-in-deep-ice\"\n\noutput_dir = os.path.join(os.getcwd(), \"Ice-Cube-Challenge\")\nif(not os.path.exists(output_dir)):\n    os.mkdir(output_dir)\n","metadata":{"execution":{"iopub.status.busy":"2023-02-24T15:22:28.607807Z","iopub.execute_input":"2023-02-24T15:22:28.608243Z","iopub.status.idle":"2023-02-24T15:22:28.645379Z","shell.execute_reply.started":"2023-02-24T15:22:28.608202Z","shell.execute_reply":"2023-02-24T15:22:28.644484Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"BATCH = 341\nMODE = \"testing\"","metadata":{"execution":{"iopub.status.busy":"2023-02-24T17:20:02.802360Z","iopub.execute_input":"2023-02-24T17:20:02.803104Z","iopub.status.idle":"2023-02-24T17:20:02.807795Z","shell.execute_reply.started":"2023-02-24T17:20:02.803067Z","shell.execute_reply":"2023-02-24T17:20:02.806626Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_meta = pq.ParquetDataset(input_dir + \"/train_meta.parquet\", \n                               use_legacy_dataset=False,\n                               filters = [('batch_id', \"=\", BATCH)]\n                              ).read().to_pandas()\ntrain_meta[\"pulse_length\"] = train_meta[\"last_pulse_index\"] - train_meta[\"first_pulse_index\"]\ntrain_meta = train_meta[train_meta[\"pulse_length\"] <= 1000]\n","metadata":{"execution":{"iopub.status.busy":"2023-02-24T17:20:02.931428Z","iopub.execute_input":"2023-02-24T17:20:02.932050Z","iopub.status.idle":"2023-02-24T17:20:11.325933Z","shell.execute_reply.started":"2023-02-24T17:20:02.932006Z","shell.execute_reply":"2023-02-24T17:20:11.324951Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_meta","metadata":{"execution":{"iopub.status.busy":"2023-02-24T17:23:56.029696Z","iopub.execute_input":"2023-02-24T17:23:56.030918Z","iopub.status.idle":"2023-02-24T17:23:56.048400Z","shell.execute_reply.started":"2023-02-24T17:23:56.030877Z","shell.execute_reply":"2023-02-24T17:23:56.047073Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_batch = pq.ParquetDataset(input_dir + f\"/train/batch_{BATCH}.parquet\", \n                               use_legacy_dataset=False\n                              ).read().to_pandas()","metadata":{"execution":{"iopub.status.busy":"2023-02-24T17:20:11.328102Z","iopub.execute_input":"2023-02-24T17:20:11.328565Z","iopub.status.idle":"2023-02-24T17:20:13.060565Z","shell.execute_reply.started":"2023-02-24T17:20:11.328524Z","shell.execute_reply":"2023-02-24T17:20:13.059217Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_batch.head(20)","metadata":{"execution":{"iopub.status.busy":"2023-02-24T17:20:13.065056Z","iopub.execute_input":"2023-02-24T17:20:13.065408Z","iopub.status.idle":"2023-02-24T17:20:13.081868Z","shell.execute_reply.started":"2023-02-24T17:20:13.065363Z","shell.execute_reply":"2023-02-24T17:20:13.080591Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sensor_dict_aux = {i: [] for i in pd.read_csv(input_dir + \"/sensor_geometry.csv\")['sensor_id']}\nsensor_dict_nonaux = {i: [] for i in pd.read_csv(input_dir + \"/sensor_geometry.csv\")['sensor_id']}\nfor index, (_, row) in enumerate(train_meta.iterrows()):\n    start = row.first_pulse_index\n    end = row.last_pulse_index\n    tempdf = train_batch.iloc[start:end]\n    valuecounts_aux = tempdf[tempdf.auxiliary == True].sensor_id.value_counts()\n    valuecounts_nonaux = tempdf[tempdf.auxiliary == False].sensor_id.value_counts()\n    for key, val in valuecounts_aux.items():\n        sensor_dict_aux[key].append(val)\n    for key, val in valuecounts_nonaux.items():\n        sensor_dict_nonaux[key].append(val)","metadata":{"execution":{"iopub.status.busy":"2023-02-24T18:20:31.819741Z","iopub.execute_input":"2023-02-24T18:20:31.820221Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x_aux = []\ny_aux = []\nfor key, val in sensor_dict_aux.items():\n    x_aux.append(key)\n    y_aux.append(np.array(val).mean())\nx_nonaux = []\ny_nonaux = []\nfor key, val in sensor_dict_nonaux.items():\n    x_nonaux.append(key)\n    y_nonaux.append(np.array(val).mean())\ntrace1 = go.Scatter(x = x_aux, y = y_aux, mode = \"markers\", name = \"Aux = True\")\ntrace2 = go.Scatter(x = x_nonaux, y = y_nonaux, mode = \"markers\", name = \"Aux = False\")\nfig = go.Figure(data = [trace1, trace2])\nfig.update_yaxes(range = [0, 8])\nfig.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def getSensorMapToXYZ():\n    \"\"\"\n    A utility function that maps the sensor_id to its corresponding X, Y, Z position\n    returns a dictionary with sensor_id as the key and the respective positions as its value\n    \"\"\"\n    geom_df = pd.read_csv(input_dir + \"/sensor_geometry.csv\")\n    sensor_id_dict = dict()\n    for _, row in geom_df.iterrows():\n        sensor_id_dict[row.sensor_id] = (row.x, row.y, row.z)\n    return sensor_id_dict\n\ndef getEventDF(eventID):\n    \"\"\"\n    A utility function that returns event Info along with zenith and azimuth\n    \"\"\"\n    temp_meta = train_meta[train_meta.event_id == eventID]\n    temp_batch = train_batch.iloc[temp_meta.first_pulse_index.values[0]:temp_meta.last_pulse_index.values[0]]\n    return temp_meta.zenith.values[0], temp_meta.azimuth.values[0], temp_batch\n\ndef getCoords(sensor_id_dict, df):\n    x = np.array([0.]*len(df))\n    y = np.array([0.]*len(df))\n    z = np.array([0.]*len(df))\n    time = np.array([0.]*len(df))\n    charge = np.array([0.]*len(df))\n    auxtype = np.array([0]*len(df), dtype = bool)\n    for index, (_, rows) in enumerate(df.iterrows()):\n        _x, _y, _z = sensor_id_dict[rows.sensor_id]\n        x[index] = _x\n        y[index] = _y        \n        z[index] = _z\n        time[index] = rows.time\n        charge[index] = rows.charge\n        auxtype[index] = rows.auxiliary\n    return x, y, z, time, charge, auxtype\nsensor_dict = getSensorMapToXYZ()\n\n","metadata":{"execution":{"iopub.status.busy":"2023-02-24T16:44:30.333310Z","iopub.execute_input":"2023-02-24T16:44:30.333781Z","iopub.status.idle":"2023-02-24T16:44:30.745223Z","shell.execute_reply.started":"2023-02-24T16:44:30.333743Z","shell.execute_reply":"2023-02-24T16:44:30.744069Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"zen, azi, eventDF = getEventDF(train_meta.event_id[15])\nx, y, z, time, charge, auxtype = getCoords(sensor_dict, eventDF)","metadata":{"execution":{"iopub.status.busy":"2023-02-24T16:47:37.031466Z","iopub.execute_input":"2023-02-24T16:47:37.031940Z","iopub.status.idle":"2023-02-24T16:47:37.045241Z","shell.execute_reply.started":"2023-02-24T16:47:37.031907Z","shell.execute_reply":"2023-02-24T16:47:37.043707Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig = px.scatter_matrix(pd.DataFrame({'x' : x, 'y' : y, 'z' : z, 'charge' : charge, 'auxtype' : auxtype}), \n                        dimensions=[\"x\", \"y\", \"z\"], size = 'charge',\n                        color = 'auxtype', color_discrete_sequence=px.colors.qualitative.Antique)\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2023-02-24T16:47:37.467346Z","iopub.execute_input":"2023-02-24T16:47:37.467770Z","iopub.status.idle":"2023-02-24T16:47:37.543498Z","shell.execute_reply.started":"2023-02-24T16:47:37.467732Z","shell.execute_reply":"2023-02-24T16:47:37.541941Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"r = np.linspace(-100, 100, 100)\nx = r*np.cos(azi) * np.sin(zen)\ny = r*np.sin(azi) * np.sin(zen)\nz = r*np.cos(zen)\n\nline1 = go.Scatter3d(x = x - np.mean(x), y = y - np.mean(y), z = z - np.mean(z), mode = \"markers\", name = \"Shifted\")\nline2 = go.Scatter3d(x = x, y = y, z = z, mode = \"markers\", name = \"Original\")\nfig = go.Figure(data = [line1, line2])\nfig.update_layout(scene = {'xaxis' : {'range' : [-500, 500]},\n                                                'yaxis' : {'range' : [-500, 500]},\n                                                'zaxis' : {'range' : [-500, 500]}\n                                               })\nfig.show()\n#x-y fitting y = mx + c\n","metadata":{"execution":{"iopub.status.busy":"2023-02-24T16:44:33.067522Z","iopub.execute_input":"2023-02-24T16:44:33.067922Z","iopub.status.idle":"2023-02-24T16:44:33.092684Z","shell.execute_reply.started":"2023-02-24T16:44:33.067890Z","shell.execute_reply":"2023-02-24T16:44:33.091326Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def FitSimpleLeastSquare(x, y, z):\n    \"\"\"\n    Simple Least square fitting. Not considering charge time or aux\n    \"\"\"\n    # y vs x fitting\n    X = np.vstack([x, np.ones(len(x))]).T\n    m_xy, c_xy = np.linalg.lstsq(X, y, rcond=None)[0]\n    \n    # z vs xy fitting","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x = x - np.mean(x)\ny = y - np.mean(y)\nz = z - np.mean(z)\n# Fitting in 2D xy, yz, xz -> alpha, beta and gamma Euler Angles -> Theta and Phi","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"px.scatter_3d(x = '')","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig = px.density_heatmap(train_meta, x=\"zenith\", \n                         y=\"azimuth\", nbinsx=180, nbinsy=360,\n                         marginal_x=\"histogram\", marginal_y=\"histogram\",\n                         histnorm = 'percent'\n                        )\nfig.update_layout(height = 600, width = 1000, \n                 title = {'text' : \"Distribution of angles\", \n                          'xanchor' : \"center\",\n                          'yanchor' : 'top',\n                          'font' : {'size' : 20},\n                          'x' : 0.5,\n                          'y' : 0.99\n                         },\n                  xaxis_title = r\"$\\text{theta} [ \\theta ] \\text{in rad}$\",\n                  yaxis_title = r\"$\\text{azimuth} [ \\phi ] \\text{in rad}$\"\n                 )\nfig.update_xaxes(title_font_size = 20)\nfig.update_yaxes(title_font_size = 20)\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2023-02-24T16:46:34.741240Z","iopub.execute_input":"2023-02-24T16:46:34.741677Z","iopub.status.idle":"2023-02-24T16:46:36.456634Z","shell.execute_reply.started":"2023-02-24T16:46:34.741644Z","shell.execute_reply":"2023-02-24T16:46:36.455051Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig = px.histogram(train_meta, x=\"pulse_length\", histnorm = 'percent')\nfig.update_layout(height = 600, width = 1000, \n                 title = {'text' : \"Histogram of Pulse length\", \n                          'xanchor' : \"center\",\n                          'yanchor' : 'top',\n                          'font' : {'size' : 20},\n                          'x' : 0.5,\n                          'y' : 0.99\n                         },\n                  xaxis_title = r\"Pulse Length [no units]\",\n                  yaxis_title = r\"Normalized counts\"\n                 )\nfig.update_xaxes(title_font_size = 25)\nfig.update_yaxes(title_font_size = 25)\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2023-02-13T18:00:20.015473Z","iopub.execute_input":"2023-02-13T18:00:20.015855Z","iopub.status.idle":"2023-02-13T18:00:20.174335Z","shell.execute_reply.started":"2023-02-13T18:00:20.015822Z","shell.execute_reply":"2023-02-13T18:00:20.173161Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df = pd.read_parquet(input_dir + f\"/train/batch_{BATCH}.parquet\")\ntrain_df.head(10)","metadata":{"execution":{"iopub.status.busy":"2023-02-08T19:02:05.688103Z","iopub.status.idle":"2023-02-08T19:02:05.690340Z","shell.execute_reply.started":"2023-02-08T19:02:05.689097Z","shell.execute_reply":"2023-02-08T19:02:05.689206Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def getSensorMapToXYZ():\n    \"\"\"\n    A utility function that maps the sensor_id to its corresponding X, Y, Z position\n    returns a dictionary with sensor_id as the key and the respective positions as its value\n    \"\"\"\n    geom_df = pd.read_csv(input_dir + \"/sensor_geometry.csv\")\n    sensor_id_dict = dict()\n    for _, row in geom_df.iterrows():\n        sensor_id_dict[row.sensor_id] = (row.x, row.y, row.z)\n    return sensor_id_dict\n\ndef getGeomMap(sensor_id_dict):\n    sensor_id = []\n    posX = [] \n    posY = []\n    posZ = []\n    for s_id, (x, y, z) in sensor_id_dict.items():\n        sensor_id.append(sensor_id)\n        posX.append(x)\n        posY.append(y)\n        posZ.append(z)\n    return sensor_id, posX, posY, posZ\n\ndef ConvertToPolar(x, y, z):\n    \"\"\"\n    x = cos(azimuth) * sin(zenith)\n    y = sin(azimuth) * sin(zenith)\n    z = cos(zenith)\n    \"\"\"\n    r = np.sqrt(x**2 + y**2 + z**2)\n    zenith = np.arccos(z/r)\n    azimuth = np.arccos(x/(r*np.sin(zenith)))\n    \n    return (r, zenith, azimuth)\n\ndef ConvertToCyl(x, y, z):\n    r = np.sqrt(x**2 + y**2)\n    th = np.arctan(y/x)\n    return r, th, z\n\ndef getSensorMapToCyl():\n    geom_df = pd.read_csv(input_dir + \"/sensor_geometry.csv\")\n    sensor_id_dict = dict()\n    for _, row in geom_df.iterrows():\n        sensor_id_dict[row.sensor_id] = ConvertToCyl(row.x, row.y, row.z)\n    return sensor_id_dict\n\ndef getSensorMapToPolar():\n    \"\"\"\n    A utility function that maps the sensor_id to its corresponding X, Y, Z position\n    returns a dictionary with sensor_id as the key and the respective positions as its value\n    \"\"\"\n    geom_df = pd.read_csv(input_dir + \"/sensor_geometry.csv\")\n    sensor_id_dict = dict()\n    for _, row in geom_df.iterrows():\n        sensor_id_dict[row.sensor_id] = ConvertToPolar(row.x, row.y, row.z)\n    return sensor_id_dict\n\n\ndef getXYZTrack(azimuth, zenith, r = 1, makePlot = False) -> np.float32:\n    \"\"\"\n    Function that generates a track for a given azimuth and zenith angle.\n    If radius is given is provided it moves the track radially to that location.\n    input : azimuth, zenith\n    optional params : r \n    output : a float32 of numpy array of x, y, z \n            if makePlot then a plotly 3d plot\n    \"\"\"\n    n = np.linspace(-500, 500, 50)\n    x = r*n*np.cos(azimuth)*np.sin(zenith)\n    y = r*n*np.sin(azimuth)*np.sin(zenith)\n    z = r*n*cos(zenith)\n    \n    geomPlot = None\n    \n    if(makePlot):\n        geomPlot = go.Scatter3d(x = x, y = y, z = z, mode = \"lines\", \n                                marker = {'size' : 3, 'opacity' : 1.0, 'color' : 'red'}\n                               )\n    return x, y, z, geomPlot\n\ndef PlotGeom():\n    \"\"\"\n    A utility function that plots the geometry\n    \"\"\"\n    geom_df = pd.read_csv(input_dir + \"/sensor_geometry.csv\")\n    fig = px.scatter_3d(geom_df, x='x', y='y', z='z', size = [5]*len(geom_df), size_max = 5, opacity = 0.25, symbol = [\"+\"]*len(geom_df))\n    return geom_df\n\ndef GetCoords(sensor_id_dict, df):\n    x = []\n    y = []\n    z = []\n    time = []\n    charge = []\n    for _, rows in df.iterrows():\n        _x, _y, _z = sensor_id_dict[rows.sensor_id]\n        x.append(_x)\n        y.append(_y)\n        z.append(_z)\n        time.append(rows.time)\n        charge.append(rows.charge)\n    return x, y, z, time, charge","metadata":{"execution":{"iopub.status.busy":"2023-02-16T17:33:09.547375Z","iopub.execute_input":"2023-02-16T17:33:09.549245Z","iopub.status.idle":"2023-02-16T17:33:09.578908Z","shell.execute_reply.started":"2023-02-16T17:33:09.549172Z","shell.execute_reply":"2023-02-16T17:33:09.577713Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sensor_id, x, y, z = getGeomMap(getSensorMapToXYZ())\nfig = px.scatter_3d(x = x, y = y, z = z, size = [0.1]*len(x))\nfig.update_layout(width = 800, height = 800)\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2023-02-16T17:33:10.655038Z","iopub.execute_input":"2023-02-16T17:33:10.655492Z","iopub.status.idle":"2023-02-16T17:33:11.553556Z","shell.execute_reply.started":"2023-02-16T17:33:10.655450Z","shell.execute_reply":"2023-02-16T17:33:11.552384Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def PlotEvent(event_id, df, train_meta):\n    \n    sensor_id_dict = getSensorMapToXYZ()\n    sensor_id_dict_pol = getSensorMapToPolar()\n    geom = PlotGeom()\n    \n    with_aux_df = df[(df.index == event_id) & (df.auxiliary == True)]\n    without_aux_df = df[(df.index == event_id) & (df.auxiliary == False)]\n    \n    r, zen, azi, time, charge = GetCoords(sensor_id_dict_pol, with_aux_df)\n    wo_r, wo_zen, wo_azi, wo_time, wo_charge = GetCoords(sensor_id_dict_pol, without_aux_df)\n    \n    test_w_aux = go.Scatter(x = zen, y = azi, \n                            mode = \"markers\",\n                            marker = {'color' : time, 'colorscale' : 'Viridis'}\n                            )\n    test_wo_aux = go.Scatter(x = wo_zen, y = wo_azi, \n                             mode = \"markers\",\n                             marker = {'color' : time}\n                            )\n    \n    figa = go.Figure()\n    #figa.add_trace(test_w_aux)\n    figa.add_trace(test_wo_aux)\n    figa.show()\n    \n    \n    x, y, z, time, charge = GetCoords(sensor_id_dict, with_aux_df)\n    wo_x, wo_y, wo_z, wo_time, wo_charge = GetCoords(sensor_id_dict, without_aux_df)\n    \n    meta_df = train_meta[(train_meta.event_id == event_id)]\n    \n    geom = go.Scatter3d(x = geom.x, y = geom.y, z = geom.z, \n                                 mode = \"markers\", \n                                 marker = {'size' : 1, 'opacity' : 0.4, 'color' : 'green'}\n                       )\n    with_aux_scatter = go.Scatter3d(x = x, y = y, z = z, \n                          mode = \"markers\",\n                          marker = {'size' : [i*10. for i in charge], 'color' : time, 'opacity' : 0.8, 'colorscale' : 'inferno'}\n                                   )\n    \n    without_aux_scatter = go.Scatter3d(x = wo_x, y = wo_y, z = wo_z, \n                          mode = \"markers\",\n                          marker = {'size' : [i*10. for i in wo_charge], 'color' : wo_time, 'opacity' : 0.8, 'colorscale' : 'inferno'}\n                                      )\n    azi = meta_df.azimuth.values[0]\n    zen = meta_df.zenith.values[0]\n    (*_, track) = getXYZTrack(azi, zen, 1, 1)\n    \n    fig = make_subplots(rows=1, cols=2,\n                        specs = [\n                            [{'type' : 'surface'}, {'type' : 'surface'}]\n                        ],\n                        subplot_titles = (\"With Auxiliary hits\", \"Without Auxiliary hits\")\n                       )\n    \n    fig.append_trace(with_aux_scatter, row = 1, col = 1)\n    fig.append_trace(geom, row = 1, col = 1)\n    fig.append_trace(track, row = 1, col = 1)\n    \n    fig.append_trace(without_aux_scatter, row = 1, col = 2)\n    fig.append_trace(geom, row = 1, col = 2)\n    fig.append_trace(track, row = 1, col = 2)\n    \n    title = {'text' : f'Event Display (event_id = {event_id})' + f\"<br>azimuth = {azi:.2f} and zenith = {zen:.2f} in rad\",\n             'x' : 0.5,\n             'y' : 0.95,\n             'xanchor' : 'center',\n             'yanchor' : 'top',\n             'font' : {'size' : 20}\n            }\n    \n    fig.update_traces(showlegend=False)\n    fig.update_layout(title = title, \n                      coloraxis = {'colorscale' : 'inferno',\n                                   'colorbar' : {\n                                       'x' : 0.5,\n                                       'y' : 0.5\n                                   }\n                                  }, \n                      template = \"plotly_dark\",\n                      width = 800, height = 600\n                     )\n    #fig.update(layout_coloraxis_showscale=False)\n    fig.show()\n","metadata":{"execution":{"iopub.status.busy":"2023-02-16T17:33:18.393152Z","iopub.execute_input":"2023-02-16T17:33:18.393554Z","iopub.status.idle":"2023-02-16T17:33:18.413286Z","shell.execute_reply.started":"2023-02-16T17:33:18.393524Z","shell.execute_reply":"2023-02-16T17:33:18.411381Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from IPython.display import display\nimport ipywidgets as widgets\nfrom IPython.display import clear_output\n\nlayout = widgets.Layout(width='300px', height='50px', background=\"red\", fontsize = \"50\") #set width and height\n\nbutton = widgets.Button(\n    description='Next Event Click Me',\n    disabled=False,\n    button_style = \"info\",\n    display='info',\n    flex_flow='column',\n    align_items='stretch', \n    layout = layout\n)        \nbutton.style.button_color = '#90ee90'\n\noutput = widgets.Output()\nevent_ids = iter(train_meta.event_id.to_list())\ndisplay(button, output)\n\ndef on_button_clicked(b):\n    with output:\n        clear_output(True)\n        PlotEvent(next(event_ids), train_batch, train_meta)\n\nbutton.on_click(on_button_clicked)","metadata":{"execution":{"iopub.status.busy":"2023-02-16T17:33:19.160195Z","iopub.execute_input":"2023-02-16T17:33:19.160652Z","iopub.status.idle":"2023-02-16T17:33:19.360299Z","shell.execute_reply.started":"2023-02-16T17:33:19.160617Z","shell.execute_reply":"2023-02-16T17:33:19.358997Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"TimeLength = []\nfor _, row in train_meta.iterrows():\n    TimeLength.append(train_df.iloc[row.last_pulse_index].time - train_df.iloc[row.first_pulse_index].time)","metadata":{"execution":{"iopub.status.busy":"2023-02-16T17:33:20.467655Z","iopub.execute_input":"2023-02-16T17:33:20.468083Z","iopub.status.idle":"2023-02-16T17:33:20.687131Z","shell.execute_reply.started":"2023-02-16T17:33:20.468050Z","shell.execute_reply":"2023-02-16T17:33:20.685441Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig = px.histogram(x = TimeLength)\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2023-02-08T19:02:05.724082Z","iopub.status.idle":"2023-02-08T19:02:05.725913Z","shell.execute_reply.started":"2023-02-08T19:02:05.724869Z","shell.execute_reply":"2023-02-08T19:02:05.724895Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df.iloc[int(train_meta.iloc[2].last_pulse_index)].time","metadata":{"execution":{"iopub.status.busy":"2023-02-08T19:02:05.731388Z","iopub.status.idle":"2023-02-08T19:02:05.733215Z","shell.execute_reply.started":"2023-02-08T19:02:05.732196Z","shell.execute_reply":"2023-02-08T19:02:05.732303Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Trying out to plot event level plots\n\ndef getDirection(coords : tuple):\n    x, y, z = tuple(np.array(i) for i in coords)\n    r = np.sqrt(x**2 + y**2 + z**2)\n    zenith = np.arccos(z/r)\n    azimuth = np.arccos(x/(r*np.sin(zenith)))\n    return r, zenith, azimuth\n\ndef ComputeDirection(df):\n    sensor_id_dict = getSensorMap()\n    x, y, z, time, charge = GetXYZ(sensor_id_dict, df[df.auxiliary == False])\n    r, zen, azi = getDirection((x, y, z))\n    mean_zen = zen.mean()\n    mean_azi = azi.mean()\n    return mean_zen, mean_azi\n\npred_zen = np.array([0.]*len(train_meta))\npred_azi = np.array([0.]*len(train_meta))\ntrue_zen = np.array([0.]*len(train_meta))\ntrue_azi = np.array([0.]*len(train_meta))\nfor i, row in train_meta.iterrows():\n    ev = row.event_id\n    pred_zen[i], pred_azi[i] = ComputeDirection(train_df[train_df.index == ev])\n    true_zen[i] = row.zenith\n    true_azi[i] = row.azimuth\n    print (i)\n    if(i == 1):\n        break\n    ","metadata":{"execution":{"iopub.status.busy":"2023-02-16T17:33:26.731973Z","iopub.execute_input":"2023-02-16T17:33:26.733200Z","iopub.status.idle":"2023-02-16T17:33:26.886365Z","shell.execute_reply.started":"2023-02-16T17:33:26.733146Z","shell.execute_reply":"2023-02-16T17:33:26.884224Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df = pd.read_parquet(input_dir + \"/test/batch_661.parquet\")\ntest_df.head(5)","metadata":{"execution":{"iopub.status.busy":"2023-02-16T17:33:37.901439Z","iopub.execute_input":"2023-02-16T17:33:37.902077Z","iopub.status.idle":"2023-02-16T17:33:37.937657Z","shell.execute_reply.started":"2023-02-16T17:33:37.902048Z","shell.execute_reply":"2023-02-16T17:33:37.936652Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df.size","metadata":{"execution":{"iopub.status.busy":"2023-02-16T17:33:38.369087Z","iopub.execute_input":"2023-02-16T17:33:38.369574Z","iopub.status.idle":"2023-02-16T17:33:38.378016Z","shell.execute_reply.started":"2023-02-16T17:33:38.369536Z","shell.execute_reply":"2023-02-16T17:33:38.376658Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_events = test_df.index.unique()\npred_zen = [0.]*len(test_events)\npred_azi = [0.]*len(test_events)\nevents = [0.]*len(test_events)\nfor i, ev in enumerate(test_events):\n    events[i] = ev\n    pred_zen[i], pred_azi[i] = ComputeDirection(test_df[test_df.index == ev])","metadata":{"execution":{"iopub.status.busy":"2023-02-16T17:33:39.452975Z","iopub.execute_input":"2023-02-16T17:33:39.453388Z","iopub.status.idle":"2023-02-16T17:33:39.496125Z","shell.execute_reply.started":"2023-02-16T17:33:39.453359Z","shell.execute_reply":"2023-02-16T17:33:39.494066Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_events","metadata":{"execution":{"iopub.status.busy":"2023-02-08T19:02:05.779365Z","iopub.status.idle":"2023-02-08T19:02:05.781331Z","shell.execute_reply.started":"2023-02-08T19:02:05.780333Z","shell.execute_reply":"2023-02-08T19:02:05.780413Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pd.DataFrame(\n    {\"event_id\" : events, \"azimuth\" : pred_azi, \"zenith\" : pred_zen}\n).to_csv(\"submission.csv\")","metadata":{"execution":{"iopub.status.busy":"2023-02-08T19:02:05.788865Z","iopub.status.idle":"2023-02-08T19:02:05.790487Z","shell.execute_reply.started":"2023-02-08T19:02:05.789472Z","shell.execute_reply":"2023-02-08T19:02:05.789546Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"val = 100\nfig = make_subplots(rows=1, cols=2, \n                    subplot_titles = (\"Zenith Prediction\", \"Azimuth Prediction\")\n                   )\nfig.append_trace(go.Histogram(x = (true_zen[:val] - pred_zen[:val])/true_zen[:val], nbinsx = 100), row = 1, col = 1)\nfig.append_trace(go.Histogram(x = (true_azi[:val] - pred_azi[:val])/true_azi[:val], nbinsx = 100), row = 1, col = 2)\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2023-02-08T19:02:05.796333Z","iopub.status.idle":"2023-02-08T19:02:05.798868Z","shell.execute_reply.started":"2023-02-08T19:02:05.798206Z","shell.execute_reply":"2023-02-08T19:02:05.798324Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Geometry:\n    def __init__(self):\n        self.DF = pd.read_csv(input_dir + \"/sensor_geometry.csv\", sep = \",\") # assuming that the file is a csv\n        self.nSensors = self.DF.sensor_id.size\n        self.SensorCoords = {i.sensor_id : (i.x, i.y, i.z) for _, i in self.DF.iterrows()}\n        self.scatter3d = go.Scatter3d(x = self.DF.x, y = self.DF.y, z = self.DF.z, \n                                      mode = \"markers\", \n                                      marker = {'size' : 1, 'opacity' : 0.4, 'color' : 'white'}\n                                     )\n    def getSensorXYZ(self, sensor_id : int) -> tuple:\n        return self.SensorCoords.get(sensor_id)\n\nclass EventInfo:\n    \n    def __init__(self, batch_id : int, event_id : int, event_info : 'dataframe', hit_info : 'dataframe'):\n        self.geom = Geometry()\n        self.batch_id = batch_id\n        self.event_id = event_id\n        self.event_info = event_info\n        self.zenith = zenith\n        self.theta = theta\n        self.hit_info = hit_info\n            \n    \n    def makePlot(self):\n        geom_trace = self.geom.scatter3d\n        event_trace = go.Scatter3d(x = hit_info.x, y = hit_info.y, z = hit_info.z, \n                          mode = \"markers\",\n                          marker = {'size' : [i*10. for i in hit_info.charge], 'color' : hit_info.time, 'opacity' : 0.8, 'colorscale' : 'hot'})\n        fig = go.Figure(data = [event_trace, geom_trace])\n        fig.update_traces(showlegend=False)\n        fig.update_layout(title = title,\n                          coloraxis = {'colorscale' : 'hot'}, \n                          template = \"plotly_dark\",\n                          width = 1000, height = 600\n                         )\n        return fig\n\nclass BatchInfo:\n    \n    def __init__(self, batch_id : int, batch_filename : str, train_filename : str):\n        self.batch_id = batch_id\n        self.batch_filename = batch_filename\n        self.train_filename = train_filename\n        self.batch_df = self.__modify_batch_df__()\n        self.train_df = pq.ParquetDataset(self.train_df, \n                                          use_legacy_dataset=False, \n                                          filters = [('batch_id', \"=\", self.batch_id)]\n                                         ).read().to_pandas()\n    def __modify_batch_df__(self):\n        geom = Geometry()\n        df = pd.read_parquet(self.batch_filename)\n        xyz = {'x' : [0.0]*df.shape[0], 'y' : []*df.shape[0], 'z' : []*df.shape[0]}\n        for i, row in df.iterrows():\n            _x, _y, _z = geom.getSensorXYZ(row.sensor_id)\n            xyz['x'][i] = _x\n            xyz['y'][i] = _y\n            xyz['z'][i] = _z\n        return df.append(pd.DataFrame(xyz))\n        \n            \n    def getEventInfo(self, event_id):\n        hit_info = self.batch_df[self.batch_df.event_id == event_id]\n        return EventInfo(self.batch_id, self)\n","metadata":{"execution":{"iopub.status.busy":"2023-02-08T19:02:05.804376Z","iopub.status.idle":"2023-02-08T19:02:05.805956Z","shell.execute_reply.started":"2023-02-08T19:02:05.805336Z","shell.execute_reply":"2023-02-08T19:02:05.805370Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Drawing the sensor in polar coordinates\nradius = []\nzenith = []\nazimuth = []\nsensor_id = []\n\nfor s_id, (r, th, az) in getSensorMapToPolar().items():\n    sensor_id.append(s_id)\n    radius.append(r)\n    zenith.append(th*180./np.pi)\n    azimuth.append(az*180./np.pi)\n\nsensor_df = pd.DataFrame({\"sensor_id\" : sensor_id, \"radius\" : radius, \"zenith\" : zenith, \"azimuth\" : azimuth})\nsensor_geom = go.Scatter3d(x = radius, y = zenith, z = azimuth, marker = {'size' : 1, 'color' : 'blue'}, mode = \"markers\")\n\nfig = go.Figure(data = [sensor_geom])\nfig.update_layout(scene = dict(xaxis_title = \"radius\", yaxis_title = \"zenith\", zaxis_title = \"azimuth\"))\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2023-02-08T19:58:25.527217Z","iopub.execute_input":"2023-02-08T19:58:25.527656Z","iopub.status.idle":"2023-02-08T19:58:26.197913Z","shell.execute_reply.started":"2023-02-08T19:58:25.527622Z","shell.execute_reply":"2023-02-08T19:58:26.196948Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Drawing the sensor in polar coordinates\nradius = []\nzenith = []\nz = []\nsensor_id = []\n\nfor s_id, (r, th, az) in getSensorMapToCyl().items():\n    sensor_id.append(s_id)\n    radius.append(r)\n    zenith.append(th*180./np.pi)\n    z.append(az)\n\nsensor_df = pd.DataFrame({\"sensor_id\" : sensor_id, \"radius\" : radius, \"zenith\" : zenith, \"z\" : z})\nsensor_geom = go.Scatter3d(x = radius, y = zenith, z = azimuth, marker = {'size' : 5, 'color' : sensor_id}, mode = \"markers\")\n\nfig = go.Figure(data = [sensor_geom])\nfig.update_layout(scene = dict(xaxis_title = \"radius\", yaxis_title = \"zenith\", zaxis_title = \"z\"))\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2023-02-08T20:04:55.461834Z","iopub.execute_input":"2023-02-08T20:04:55.462247Z","iopub.status.idle":"2023-02-08T20:04:56.235738Z","shell.execute_reply.started":"2023-02-08T20:04:55.462212Z","shell.execute_reply":"2023-02-08T20:04:56.234799Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Coordinates testing\nn = np.linspace(-100, 100, 10)\ntheta = 45.0*np.pi/180.\nphi = 60.0*np.pi/180.\nradius = 500.\nx1 = n*np.cos(phi)*np.sin(theta)\ny1 = n*np.sin(phi)*np.sin(theta)\nz1 = n*np.cos(theta)\nline1 = go.Scatter3d(x = x1, y = y1, z = z1, mode = \"lines\", marker = {'size' : 5, 'color' : 'red'})\nx2 = x1 + 50.\ny2 = y1 - 30.\nz2 = z1 + 190.\nline2 = go.Scatter3d(x = x2, y = y2, z = z2, mode = \"lines\", marker = {'size' : 5, 'color' : 'blue'})\nfig = go.Figure(data = [line1, line2])\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2023-02-08T20:29:15.971331Z","iopub.execute_input":"2023-02-08T20:29:15.971948Z","iopub.status.idle":"2023-02-08T20:29:16.015807Z","shell.execute_reply.started":"2023-02-08T20:29:15.971895Z","shell.execute_reply":"2023-02-08T20:29:16.014506Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x = y = np.linspace(-100, 100, 100)\n\na = 5.\nb = -1.\nc = 3.\nz = a*x + b*y + c\nline = go.Scatter3d(x = x, y = y, z = z, mode = \"lines\")\nfig = go.Figure(data = [line])\nfig.show()\n\n","metadata":{"execution":{"iopub.status.busy":"2023-02-08T21:41:13.917706Z","iopub.execute_input":"2023-02-08T21:41:13.918071Z","iopub.status.idle":"2023-02-08T21:41:13.935742Z","shell.execute_reply.started":"2023-02-08T21:41:13.918041Z","shell.execute_reply":"2023-02-08T21:41:13.934897Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"PlotGeom()","metadata":{"execution":{"iopub.status.busy":"2023-02-09T01:45:52.872347Z","iopub.execute_input":"2023-02-09T01:45:52.872784Z","iopub.status.idle":"2023-02-09T01:45:53.155251Z","shell.execute_reply.started":"2023-02-09T01:45:52.872742Z","shell.execute_reply":"2023-02-09T01:45:53.154230Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}